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_DMX_CONFIG_H 32#include <dmx-config.h> 33#endif 34 35#include "dmx.h" 36#include "dmxwindow.h" 37#include "dmxpixmap.h" 38#include "dmxfont.h" 39#include "dmxsync.h" 40 41#include "glxserver.h" 42#include <GL/glxtokens.h> 43#include "g_disptab.h" 44#include <pixmapstr.h> 45#include <windowstr.h> 46#include "glxutil.h" 47#include "glxext.h" 48#include "unpack.h" 49 50#include "GL/glxproto.h" 51#include "glxvendor.h" 52#include "glxvisuals.h" 53#include "glxswap.h" 54 55#include "glxcmds.h" 56 57#ifdef PANORAMIX 58#include "panoramiXsrv.h" 59#endif 60 61extern __GLXFBConfig **__glXFBConfigs; 62extern int __glXNumFBConfigs; 63 64extern __GLXFBConfig *glxLookupFBConfig( GLXFBConfigID id ); 65extern __GLXFBConfig *glxLookupFBConfigByVID( VisualID vid ); 66extern __GLXFBConfig *glxLookupBackEndFBConfig( GLXFBConfigID id, int screen ); 67extern int glxIsExtensionSupported( char *ext ); 68extern int __glXGetFBConfigsSGIX(__GLXclientState *cl, GLbyte *pc); 69 70#define BE_TO_CLIENT_ERROR(x) \ 71 ( (x) >= __glXerrorBase ? \ 72 (x) - dmxScreen->glxErrorBase + __glXerrorBase \ 73 : (x) ) 74 75Display *GetBackEndDisplay( __GLXclientState *cl, int s ) 76{ 77 if (! cl->be_displays[s] ) { 78 cl->be_displays[s] = XOpenDisplay( DisplayString(dmxScreens[s].beDisplay) ); 79 } 80 return cl->be_displays[s]; 81} 82 83/* 84** Create a GL context with the given properties. 85*/ 86static int CreateContext(__GLXclientState *cl, 87 GLXContextID gcId, 88 VisualID vid, GLXFBConfigID fbconfigId, 89 int screen, 90 GLXContextID shareList, 91 int isDirect ) 92{ 93 ClientPtr client = cl->client; 94 xGLXCreateContextReq *be_req; 95 xGLXCreateNewContextReq *be_new_req; 96 VisualPtr pVisual; 97 ScreenPtr pScreen; 98 __GLXcontext *glxc, *shareglxc; 99 __GLXvisualConfig *pGlxVisual; 100 __GLXscreenInfo *pGlxScreen; 101 VisualID visual = vid; 102 GLint i; 103 int from_screen = screen; 104 int to_screen = screen; 105 DMXScreenInfo *dmxScreen; 106 VisualID be_vid = 0; 107 GLXFBConfigID be_fbconfigId = 0; 108 int num_be_screens; 109 Display *dpy; 110 111 /* 112 ** Check if screen exists. 113 */ 114 if (screen >= screenInfo.numScreens) { 115 client->errorValue = screen; 116 return BadValue; 117 } 118 119 120#ifdef PANORAMIX 121 if (!noPanoramiXExtension) { 122 from_screen = 0; 123 to_screen = screenInfo.numScreens - 1; 124 } 125#endif 126 127 /* 128 ** Find the display list space that we want to share. 129 ** 130 */ 131 if (shareList == None) { 132 shareglxc = NULL; 133 } else { 134 dixLookupResourceByType((pointer*) &shareglxc, shareList, 135 __glXContextRes, NullClient, DixUnknownAccess); 136 if (!shareglxc) { 137 client->errorValue = shareList; 138 return __glXBadContext; 139 } 140 } 141 142 /* 143 ** Allocate memory for the new context 144 */ 145 glxc = calloc(1, sizeof(__GLXcontext)); 146 if (!glxc) { 147 return BadAlloc; 148 } 149 150 pScreen = screenInfo.screens[screen]; 151 pGlxScreen = &__glXActiveScreens[screen]; 152 153 if (fbconfigId != None) { 154 glxc->pFBConfig = glxLookupFBConfig( fbconfigId ); 155 if (!glxc->pFBConfig) { 156 client->errorValue = fbconfigId; 157 free( glxc ); 158 return BadValue; 159 } 160 visual = glxc->pFBConfig->associatedVisualId; 161 } 162 else { 163 glxc->pFBConfig = NULL; 164 } 165 166 if (visual != None) { 167 /* 168 ** Check if the visual ID is valid for this screen. 169 */ 170 pVisual = pScreen->visuals; 171 for (i = 0; i < pScreen->numVisuals; i++, pVisual++) { 172 if (pVisual->vid == visual) { 173 break; 174 } 175 } 176 if (i == pScreen->numVisuals) { 177 client->errorValue = visual; 178 free( glxc ); 179 return BadValue; 180 } 181 182 pGlxVisual = pGlxScreen->pGlxVisual; 183 for (i = 0; i < pGlxScreen->numVisuals; i++, pGlxVisual++) { 184 if (pGlxVisual->vid == visual) { 185 break; 186 } 187 } 188 if (i == pGlxScreen->numVisuals) { 189 /* 190 ** Visual not support on this screen by this OpenGL implementation. 191 */ 192 client->errorValue = visual; 193 free( glxc ); 194 return BadValue; 195 } 196 197 if ( glxc->pFBConfig == NULL ) { 198 glxc->pFBConfig = glxLookupFBConfigByVID( visual ); 199 200 if ( glxc->pFBConfig == NULL ) { 201 /* 202 * visual does not have an FBConfig ??? 203 client->errorValue = visual; 204 free( glxc ); 205 return BadValue; 206 */ 207 } 208 } 209 } 210 else { 211 pVisual = NULL; 212 pGlxVisual = NULL; 213 } 214 215 glxc->pScreen = pScreen; 216 glxc->pGlxScreen = pGlxScreen; 217 glxc->pVisual = pVisual; 218 glxc->pGlxVisual = pGlxVisual; 219 220 /* 221 * allocate memory for back-end servers info 222 */ 223 num_be_screens = to_screen - from_screen + 1; 224 glxc->real_ids = (XID *)malloc(sizeof(XID) * num_be_screens); 225 if (!glxc->real_ids) { 226 return BadAlloc; 227 } 228 glxc->real_vids = (XID *)malloc(sizeof(XID) * num_be_screens); 229 if (!glxc->real_vids) { 230 return BadAlloc; 231 } 232 233 for (screen = from_screen; screen <= to_screen; screen++) { 234 int sent = 0; 235 pScreen = screenInfo.screens[screen]; 236 pGlxScreen = &__glXActiveScreens[screen]; 237 dmxScreen = &dmxScreens[screen]; 238 239 if (glxc->pFBConfig) { 240 __GLXFBConfig *beFBConfig = glxLookupBackEndFBConfig( glxc->pFBConfig->id, 241 screen ); 242 be_fbconfigId = beFBConfig->id; 243 } 244 245 if (pGlxVisual) { 246 247 be_vid = glxMatchGLXVisualInConfigList( pGlxVisual, 248 dmxScreen->glxVisuals, 249 dmxScreen->numGlxVisuals ); 250 251 if (!be_vid) { 252 /* visual is not supported on the back-end server */ 253 free( glxc->real_ids ); 254 free( glxc->real_vids ); 255 free( glxc ); 256 return BadValue; 257 } 258 } 259 260 glxc->real_ids[screen-from_screen] = XAllocID(GetBackEndDisplay(cl,screen)); 261 262 /* send the create context request to the back-end server */ 263 dpy = GetBackEndDisplay(cl,screen); 264 if (glxc->pFBConfig) { 265 /*Since for a certain visual both RGB and COLOR INDEX 266 *can be on then the only parmeter to choose the renderType 267 * should be the class of the colormap since all 4 first 268 * classes does not support RGB mode only COLOR INDEX , 269 * and so TrueColor and DirectColor does not support COLOR INDEX*/ 270 int renderType = glxc->pFBConfig->renderType; 271 if ( pVisual ) { 272 switch ( pVisual->class ){ 273 case PseudoColor: 274 case StaticColor: 275 case GrayScale: 276 case StaticGray: 277 renderType = GLX_COLOR_INDEX_TYPE; 278 break; 279 case TrueColor: 280 case DirectColor: 281 default: 282 renderType = GLX_RGBA_TYPE; 283 break; 284 } 285 } 286 if ( __GLX_IS_VERSION_SUPPORTED(1,3) ) { 287 LockDisplay(dpy); 288 GetReq(GLXCreateNewContext,be_new_req); 289 be_new_req->reqType = dmxScreen->glxMajorOpcode; 290 be_new_req->glxCode = X_GLXCreateNewContext; 291 be_new_req->context = (unsigned int)glxc->real_ids[screen-from_screen]; 292 be_new_req->fbconfig = (unsigned int)be_fbconfigId; 293 be_new_req->screen = DefaultScreen(dpy); 294 be_new_req->renderType = renderType; 295 296 be_new_req->shareList = (shareglxc ? shareglxc->real_ids[screen-from_screen] : 0); 297 be_new_req->isDirect = 0; 298 UnlockDisplay(dpy); 299 glxc->real_vids[screen-from_screen] = be_fbconfigId; 300 sent = 1; 301 } 302 else if (glxIsExtensionSupported("GLX_SGIX_fbconfig")) { 303 304 xGLXCreateContextWithConfigSGIXReq *ext_req; 305 xGLXVendorPrivateReq *vpreq; 306 LockDisplay(dpy); 307 GetReqExtra(GLXVendorPrivate, 308 sz_xGLXCreateContextWithConfigSGIXReq - sz_xGLXVendorPrivateReq, 309 vpreq); 310 ext_req = (xGLXCreateContextWithConfigSGIXReq *)vpreq; 311 ext_req->reqType = dmxScreen->glxMajorOpcode; 312 ext_req->glxCode = X_GLXVendorPrivate; 313 ext_req->vendorCode = X_GLXvop_CreateContextWithConfigSGIX; 314 ext_req->context = (unsigned int)glxc->real_ids[screen-from_screen]; 315 ext_req->fbconfig = (unsigned int)be_fbconfigId; 316 ext_req->screen = DefaultScreen(dpy); 317 ext_req->renderType = renderType; 318 ext_req->shareList = (shareglxc ? shareglxc->real_ids[screen-from_screen] : 0); 319 ext_req->isDirect = 0; 320 UnlockDisplay(dpy); 321 glxc->real_vids[screen-from_screen] = be_fbconfigId; 322 sent = 1; 323 } 324 } 325 326 if (!sent) { 327 LockDisplay(dpy); 328 GetReq(GLXCreateContext,be_req); 329 be_req->reqType = dmxScreen->glxMajorOpcode; 330 be_req->glxCode = X_GLXCreateContext; 331 be_req->context = (unsigned int)glxc->real_ids[screen-from_screen]; 332 be_req->visual = (unsigned int)be_vid; 333 be_req->screen = DefaultScreen(dpy); 334 be_req->shareList = (shareglxc ? shareglxc->real_ids[screen-from_screen] : 0); 335 be_req->isDirect = 0; 336 UnlockDisplay(dpy); 337 glxc->real_vids[screen-from_screen] = be_vid; 338 } 339 SyncHandle(); 340 341 } 342 343 /* 344 ** Register this context as a resource. 345 */ 346 if (!AddResource(gcId, __glXContextRes, (pointer)glxc)) { 347 free( glxc->real_ids ); 348 free( glxc->real_vids ); 349 free( glxc ); 350 client->errorValue = gcId; 351 return BadAlloc; 352 } 353 354 /* 355 ** Finally, now that everything is working, setup the rest of the 356 ** context. 357 */ 358 glxc->id = gcId; 359 glxc->share_id = shareList; 360 glxc->idExists = GL_TRUE; 361 glxc->isCurrent = GL_FALSE; 362 363 return Success; 364} 365 366int __glXCreateContext(__GLXclientState *cl, GLbyte *pc) 367{ 368 xGLXCreateContextReq *req = (xGLXCreateContextReq *) pc; 369 370 return( CreateContext(cl, req->context,req->visual, None, 371 req->screen, req->shareList, req->isDirect) ); 372 373} 374 375int __glXCreateNewContext(__GLXclientState *cl, GLbyte *pc) 376{ 377 xGLXCreateNewContextReq *req = (xGLXCreateNewContextReq *) pc; 378 379 return( CreateContext(cl, req->context,None, req->fbconfig, 380 req->screen, req->shareList, req->isDirect) ); 381 382} 383 384int __glXCreateContextWithConfigSGIX(__GLXclientState *cl, GLbyte *pc) 385{ 386 xGLXCreateContextWithConfigSGIXReq *req = (xGLXCreateContextWithConfigSGIXReq *) pc; 387 388 return( CreateContext(cl, req->context, None, req->fbconfig, 389 req->screen, req->shareList, req->isDirect) ); 390 391} 392 393int __glXQueryMaxSwapBarriersSGIX(__GLXclientState *cl, GLbyte *pc) 394{ 395 ClientPtr client = cl->client; 396 xGLXQueryMaxSwapBarriersSGIXReq *req = 397 (xGLXQueryMaxSwapBarriersSGIXReq *)pc; 398 xGLXQueryMaxSwapBarriersSGIXReply reply; 399 400 reply.type = X_Reply; 401 reply.sequenceNumber = client->sequence; 402 reply.length = 0; 403 reply.max = QueryMaxSwapBarriersSGIX(req->screen); 404 405 if (client->swapped) { 406 __glXSwapQueryMaxSwapBarriersSGIXReply(client, &reply); 407 } else { 408 WriteToClient(client, sz_xGLXQueryMaxSwapBarriersSGIXReply, 409 (char *)&reply); 410 } 411 412 return Success; 413} 414 415int __glXBindSwapBarrierSGIX(__GLXclientState *cl, GLbyte *pc) 416{ 417 ClientPtr client = cl->client; 418 xGLXBindSwapBarrierSGIXReq *req = (xGLXBindSwapBarrierSGIXReq *)pc; 419 DrawablePtr pDraw; 420 __GLXpixmap *pGlxPixmap = NULL; 421 __glXWindow *pGlxWindow = NULL; 422 int rc; 423 424 rc = dixLookupDrawable(&pDraw, req->drawable, client, 0, DixGetAttrAccess); 425 if (rc != Success) { 426 dixLookupResourceByType((pointer*) &pGlxPixmap, req->drawable, 427 __glXPixmapRes, NullClient, DixUnknownAccess); 428 if (pGlxPixmap) pDraw = pGlxPixmap->pDraw; 429 } 430 431 if (!pDraw && __GLX_IS_VERSION_SUPPORTED(1,3) ) { 432 dixLookupResourceByType((pointer*) &pGlxWindow, req->drawable, 433 __glXWindowRes, NullClient, DixUnknownAccess); 434 if (pGlxWindow) pDraw = pGlxWindow->pDraw; 435 } 436 437 if (!pDraw) { 438 client->errorValue = req->drawable; 439 return __glXBadDrawable; 440 } 441 442 return BindSwapBarrierSGIX(pDraw, req->barrier); 443} 444 445int __glXJoinSwapGroupSGIX(__GLXclientState *cl, GLbyte *pc) 446{ 447 ClientPtr client = cl->client; 448 xGLXJoinSwapGroupSGIXReq *req = (xGLXJoinSwapGroupSGIXReq *)pc; 449 DrawablePtr pDraw, pMember = NULL; 450 __GLXpixmap *pGlxPixmap = NULL; 451 __glXWindow *pGlxWindow = NULL; 452 int rc; 453 454 rc = dixLookupDrawable(&pDraw, req->drawable, client, 0, DixManageAccess); 455 if (rc != Success) { 456 dixLookupResourceByType((pointer*) &pGlxPixmap, req->drawable, 457 __glXPixmapRes, NullClient, DixUnknownAccess); 458 if (pGlxPixmap) pDraw = pGlxPixmap->pDraw; 459 } 460 461 if (!pDraw && __GLX_IS_VERSION_SUPPORTED(1,3) ) { 462 dixLookupResourceByType((pointer*) &pGlxWindow, req->drawable, 463 __glXWindowRes, NullClient, DixUnknownAccess); 464 if (pGlxWindow) pDraw = pGlxWindow->pDraw; 465 } 466 467 if (!pDraw) { 468 client->errorValue = req->drawable; 469 return __glXBadDrawable; 470 } 471 472 if (req->member != None) { 473 rc = dixLookupDrawable(&pMember, req->member, client, 0, 474 DixGetAttrAccess); 475 if (rc != Success) { 476 dixLookupResourceByType((pointer*) &pGlxPixmap, req->member, 477 __glXPixmapRes, NullClient, 478 DixUnknownAccess); 479 if (pGlxPixmap) pMember = pGlxPixmap->pDraw; 480 } 481 482 if (!pMember && __GLX_IS_VERSION_SUPPORTED(1,3) ) { 483 dixLookupResourceByType((pointer*) &pGlxWindow, req->member, 484 __glXWindowRes, NullClient, 485 DixUnknownAccess); 486 if (pGlxWindow) pMember = pGlxWindow->pDraw; 487 } 488 489 if (!pMember) { 490 client->errorValue = req->member; 491 return __glXBadDrawable; 492 } 493 } 494 495 return JoinSwapGroupSGIX(pDraw, pMember); 496} 497 498 499/* 500** Destroy a GL context as an X resource. 501*/ 502int __glXDestroyContext(__GLXclientState *cl, GLbyte *pc) 503{ 504 ClientPtr client = cl->client; 505 xGLXDestroyContextReq *req = (xGLXDestroyContextReq *) pc; 506 xGLXDestroyContextReq *be_req; 507 GLXContextID gcId = req->context; 508 __GLXcontext *glxc; 509 int from_screen = 0; 510 int to_screen = 0; 511 int s; 512 513 dixLookupResourceByType((pointer*) &glxc, gcId, __glXContextRes, 514 NullClient, DixUnknownAccess); 515 if (glxc) { 516 /* 517 ** Just free the resource; don't actually destroy the context, 518 ** because it might be in use. The 519 ** destroy method will be called by the resource destruction routine 520 ** if necessary. 521 */ 522 FreeResourceByType(gcId, __glXContextRes, FALSE); 523 524 from_screen = to_screen = glxc->pScreen->myNum; 525 526 } else { 527 client->errorValue = gcId; 528 return __glXBadContext; 529 } 530 531#ifdef PANORAMIX 532 if (!noPanoramiXExtension) { 533 from_screen = 0; 534 to_screen = screenInfo.numScreens - 1; 535 } 536#endif 537 538 /* 539 * send DestroyContext request to all back-end servers 540 */ 541 for (s=from_screen; s<=to_screen; s++) { 542 DMXScreenInfo *dmxScreen = &dmxScreens[s]; 543 Display *dpy = GetBackEndDisplay(cl,s); 544 545 LockDisplay(dpy); 546 GetReq(GLXDestroyContext,be_req); 547 be_req->reqType = dmxScreen->glxMajorOpcode; 548 be_req->glxCode = X_GLXDestroyContext; 549 be_req->context = glxc->real_ids[s-from_screen]; 550 UnlockDisplay(dpy); 551 SyncHandle(); 552 } 553 554 return Success; 555} 556 557/*****************************************************************************/ 558 559/* 560** For each client, the server keeps a table of all the contexts that are 561** current for that client (each thread of a client may have its own current 562** context). These routines add, change, and lookup contexts in the table. 563*/ 564 565/* 566** Add a current context, and return the tag that will be used to refer to it. 567*/ 568static int AddCurrentContext(__GLXclientState *cl, __GLXcontext *glxc, DrawablePtr pDraw) 569{ 570 int i; 571 int num = cl->numCurrentContexts; 572 __GLXcontext **table = cl->currentContexts; 573 574 if (!glxc) return -1; 575 576 /* 577 ** Try to find an empty slot and use it. 578 */ 579 for (i=0; i < num; i++) { 580 if (!table[i]) { 581 table[i] = glxc; 582 return i+1; 583 } 584 } 585 /* 586 ** Didn't find a free slot, so we'll have to grow the table. 587 */ 588 if (!num) { 589 table = (__GLXcontext **) malloc(sizeof(__GLXcontext *)); 590 cl->currentDrawables = (DrawablePtr *) malloc(sizeof(DrawablePtr)); 591 cl->be_currentCTag = (GLXContextTag *) malloc(screenInfo.numScreens *sizeof(GLXContextTag)); 592 } else { 593 table = (__GLXcontext **) realloc(table, 594 (num+1)*sizeof(__GLXcontext *)); 595 cl->currentDrawables = (DrawablePtr *) realloc( 596 cl->currentDrawables , 597 (num+1)*sizeof(DrawablePtr)); 598 cl->be_currentCTag = (GLXContextTag *) realloc(cl->be_currentCTag, 599 (num+1)*screenInfo.numScreens*sizeof(GLXContextTag)); 600 } 601 table[num] = glxc; 602 cl->currentDrawables[num] = pDraw; 603 cl->currentContexts = table; 604 cl->numCurrentContexts++; 605 606 memset(cl->be_currentCTag + num*screenInfo.numScreens, 0, 607 screenInfo.numScreens * sizeof(GLXContextTag)); 608 609 return num+1; 610} 611 612/* 613** Given a tag, change the current context for the corresponding entry. 614*/ 615static void ChangeCurrentContext(__GLXclientState *cl, __GLXcontext *glxc, 616 GLXContextTag tag) 617{ 618 __GLXcontext **table = cl->currentContexts; 619 table[tag-1] = glxc; 620} 621 622/* 623** Given a tag, and back-end screen number, retrives the current back-end 624** tag. 625*/ 626int GetCurrentBackEndTag(__GLXclientState *cl, GLXContextTag tag, int s) 627{ 628 if (tag >0) { 629 return( cl->be_currentCTag[ (tag-1)*screenInfo.numScreens + s ] ); 630 } 631 else { 632 return 0; 633 } 634} 635 636/* 637** Given a tag, and back-end screen number, sets the current back-end 638** tag. 639*/ 640static void SetCurrentBackEndTag(__GLXclientState *cl, GLXContextTag tag, int s, GLXContextTag be_tag) 641{ 642 if (tag >0) { 643 cl->be_currentCTag[ (tag-1)*screenInfo.numScreens + s ] = be_tag; 644 } 645} 646 647/* 648** For this implementation we have chosen to simply use the index of the 649** context's entry in the table as the context tag. A tag must be greater 650** than 0. 651*/ 652__GLXcontext *__glXLookupContextByTag(__GLXclientState *cl, GLXContextTag tag) 653{ 654 int num = cl->numCurrentContexts; 655 656 if (tag < 1 || tag > num) { 657 return 0; 658 } else { 659 return cl->currentContexts[tag-1]; 660 } 661} 662 663DrawablePtr __glXLookupDrawableByTag(__GLXclientState *cl, GLXContextTag tag) 664{ 665 int num = cl->numCurrentContexts; 666 667 if (tag < 1 || tag > num) { 668 return 0; 669 } else { 670 return cl->currentDrawables[tag-1]; 671 } 672} 673 674/*****************************************************************************/ 675 676static void StopUsingContext(__GLXcontext *glxc) 677{ 678 if (glxc) { 679 if (glxc == __glXLastContext) { 680 /* Tell server GL library */ 681 __glXLastContext = 0; 682 } 683 glxc->isCurrent = GL_FALSE; 684 if (!glxc->idExists) { 685 __glXFreeContext(glxc); 686 } 687 } 688} 689 690static void StartUsingContext(__GLXclientState *cl, __GLXcontext *glxc) 691{ 692 glxc->isCurrent = GL_TRUE; 693} 694 695/*****************************************************************************/ 696/* 697** Make an OpenGL context and drawable current. 698*/ 699static int MakeCurrent(__GLXclientState *cl, 700 GLXDrawable drawable, 701 GLXDrawable readdrawable, 702 GLXContextID context, 703 GLXContextTag oldContextTag) 704{ 705 ClientPtr client = cl->client; 706 DrawablePtr pDraw = NULL; 707 DrawablePtr pReadDraw = NULL; 708 xGLXMakeCurrentReadSGIReply new_reply; 709 xGLXMakeCurrentReq *be_req; 710 xGLXMakeCurrentReply be_reply; 711 xGLXMakeContextCurrentReq *be_new_req; 712 xGLXMakeContextCurrentReply be_new_reply; 713 GLXDrawable drawId = drawable; 714 GLXDrawable readId = readdrawable; 715 GLXContextID contextId = context; 716 __GLXpixmap *pGlxPixmap = 0; 717 __GLXpixmap *pReadGlxPixmap = 0; 718 __GLXcontext *glxc, *prevglxc; 719 GLXContextTag tag = oldContextTag; 720 WindowPtr pWin = NULL; 721 WindowPtr pReadWin = NULL; 722 __glXWindow *pGlxWindow = NULL; 723 __glXWindow *pGlxReadWindow = NULL; 724 __glXPbuffer *pGlxPbuffer = NULL; 725 __glXPbuffer *pGlxReadPbuffer = NULL; 726#ifdef PANORAMIX 727 PanoramiXRes *pXinDraw = NULL; 728 PanoramiXRes *pXinReadDraw = NULL; 729#endif 730 int from_screen = 0; 731 int to_screen = 0; 732 int s, rc; 733 734 /* 735 ** If one is None and the other isn't, it's a bad match. 736 */ 737 if ((drawId == None && contextId != None) || 738 (drawId != None && contextId == None)) { 739 return BadMatch; 740 } 741 742 /* 743 ** Lookup old context. If we have one, it must be in a usable state. 744 */ 745 if (tag != 0) { 746 prevglxc = __glXLookupContextByTag(cl, tag); 747 if (!prevglxc) { 748 /* 749 ** Tag for previous context is invalid. 750 */ 751 return __glXBadContextTag; 752 } 753 } else { 754 prevglxc = 0; 755 } 756 757 /* 758 ** Lookup new context. It must not be current for someone else. 759 */ 760 if (contextId != None) { 761 dixLookupResourceByType((pointer*) &glxc, contextId, __glXContextRes, 762 NullClient, DixUnknownAccess); 763 if (!glxc) { 764 client->errorValue = contextId; 765 return __glXBadContext; 766 } 767 if ((glxc != prevglxc) && glxc->isCurrent) { 768 /* Context is current to somebody else */ 769 return BadAccess; 770 } 771 } else { 772 /* Switching to no context. Ignore new drawable. */ 773 glxc = 0; 774 } 775 776 if (drawId != None) { 777 rc = dixLookupDrawable(&pDraw, drawId, client, 0, DixWriteAccess); 778 if (rc == Success) { 779 if (pDraw->type == DRAWABLE_WINDOW) { 780 /* 781 ** Drawable is an X Window. 782 */ 783 VisualID vid; 784 pWin = (WindowPtr)pDraw; 785 vid = wVisual(pWin); 786 787 new_reply.writeVid = (glxc->pFBConfig ? glxc->pFBConfig->id : vid); 788 new_reply.writeType = GLX_WINDOW_TYPE; 789 790 /* 791 ** Check if window and context are similar. 792 */ 793 if ((vid != glxc->pVisual->vid) || 794 (pWin->drawable.pScreen != glxc->pScreen)) { 795 client->errorValue = drawId; 796 return BadMatch; 797 } 798 799 from_screen = to_screen = pWin->drawable.pScreen->myNum; 800 801 } else { 802 /* 803 ** An X Pixmap is not allowed as a parameter (a GLX Pixmap 804 ** is, but it must first be created with glxCreateGLXPixmap). 805 */ 806 client->errorValue = drawId; 807 return __glXBadDrawable; 808 } 809 } 810 811 if (!pDraw) { 812 dixLookupResourceByType((pointer*) &pGlxPixmap, drawId, 813 __glXPixmapRes, NullClient, 814 DixUnknownAccess); 815 if (pGlxPixmap) { 816 /* 817 ** Check if pixmap and context are similar. 818 */ 819 if (pGlxPixmap->pScreen != glxc->pScreen || 820 pGlxPixmap->pGlxVisual != glxc->pGlxVisual) { 821 client->errorValue = drawId; 822 return BadMatch; 823 } 824 pDraw = pGlxPixmap->pDraw; 825 826 new_reply.writeVid = (glxc->pFBConfig ? glxc->pFBConfig->id : 827 pGlxPixmap->pGlxVisual->vid); 828 829 new_reply.writeType = GLX_PIXMAP_TYPE; 830 831 from_screen = to_screen = pGlxPixmap->pScreen->myNum; 832 833 } 834 } 835 836 if (!pDraw && __GLX_IS_VERSION_SUPPORTED(1,3) ) { 837 dixLookupResourceByType((pointer*) &pGlxWindow, drawId, 838 __glXWindowRes, NullClient, 839 DixUnknownAccess); 840 if (pGlxWindow) { 841 /* 842 ** Drawable is a GLXWindow. 843 ** 844 ** Check if GLX window and context are similar. 845 */ 846 if (pGlxWindow->pScreen != glxc->pScreen || 847 pGlxWindow->pGlxFBConfig != glxc->pFBConfig) { 848 client->errorValue = drawId; 849 return BadMatch; 850 } 851 852 pDraw = pGlxWindow->pDraw; 853 new_reply.writeVid = pGlxWindow->pGlxFBConfig->id; 854 new_reply.writeType = GLX_GLXWINDOW_TYPE; 855 } 856 857 } 858 859 if (!pDraw && __GLX_IS_VERSION_SUPPORTED(1,3) ) { 860 dixLookupResourceByType((pointer*) &pGlxPbuffer, drawId, 861 __glXPbufferRes, NullClient, 862 DixUnknownAccess); 863 if (pGlxPbuffer) { 864 if (pGlxPbuffer->pScreen != glxc->pScreen || 865 pGlxPbuffer->pFBConfig != glxc->pFBConfig) { 866 client->errorValue = drawId; 867 return BadMatch; 868 } 869 870 pDraw = (DrawablePtr)pGlxPbuffer; 871 new_reply.writeVid = pGlxPbuffer->pFBConfig->id; 872 new_reply.writeType = GLX_PBUFFER_TYPE; 873 } 874 } 875 876 if (!pDraw) { 877 /* 878 ** Drawable is not a Window , GLXWindow or a GLXPixmap. 879 */ 880 client->errorValue = drawId; 881 return __glXBadDrawable; 882 } 883 884 } else { 885 pDraw = 0; 886 } 887 888 if (readId != None && readId != drawId ) { 889 rc = dixLookupDrawable(&pReadDraw, readId, client, 0, DixReadAccess); 890 if (rc == Success) { 891 if (pReadDraw->type == DRAWABLE_WINDOW) { 892 /* 893 ** Drawable is an X Window. 894 */ 895 VisualID vid; 896 pReadWin = (WindowPtr)pDraw; 897 vid = wVisual(pReadWin); 898 899 new_reply.readVid = (glxc->pFBConfig ? glxc->pFBConfig->id : vid); 900 new_reply.readType = GLX_WINDOW_TYPE; 901 902 /* 903 ** Check if window and context are similar. 904 */ 905 if ((vid != glxc->pVisual->vid) || 906 (pReadWin->drawable.pScreen != glxc->pScreen)) { 907 client->errorValue = readId; 908 return BadMatch; 909 } 910 911 } else { 912 913 /* 914 ** An X Pixmap is not allowed as a parameter (a GLX Pixmap 915 ** is, but it must first be created with glxCreateGLXPixmap). 916 */ 917 client->errorValue = readId; 918 return __glXBadDrawable; 919 } 920 } 921 922 if (!pReadDraw) { 923 dixLookupResourceByType((pointer*) &pReadGlxPixmap, readId, 924 __glXPixmapRes, NullClient, 925 DixUnknownAccess); 926 if (pReadGlxPixmap) { 927 /* 928 ** Check if pixmap and context are similar. 929 */ 930 if (pReadGlxPixmap->pScreen != glxc->pScreen || 931 pReadGlxPixmap->pGlxVisual != glxc->pGlxVisual) { 932 client->errorValue = readId; 933 return BadMatch; 934 } 935 pReadDraw = pReadGlxPixmap->pDraw; 936 937 new_reply.readVid = (glxc->pFBConfig ? glxc->pFBConfig->id : 938 pReadGlxPixmap->pGlxVisual->vid ); 939 new_reply.readType = GLX_PIXMAP_TYPE; 940 941 } 942 } 943 944 if (!pReadDraw && __GLX_IS_VERSION_SUPPORTED(1,3) ) { 945 dixLookupResourceByType((pointer*) &pGlxReadWindow, readId, 946 __glXWindowRes, NullClient, 947 DixUnknownAccess); 948 if (pGlxReadWindow) { 949 /* 950 ** Drawable is a GLXWindow. 951 ** 952 ** Check if GLX window and context are similar. 953 */ 954 if (pGlxReadWindow->pScreen != glxc->pScreen || 955 pGlxReadWindow->pGlxFBConfig != glxc->pFBConfig) { 956 client->errorValue = readId; 957 return BadMatch; 958 } 959 960 pReadDraw = pGlxReadWindow->pDraw; 961 new_reply.readVid = pGlxReadWindow->pGlxFBConfig->id; 962 new_reply.readType = GLX_GLXWINDOW_TYPE; 963 } 964 } 965 966 if (!pReadDraw && __GLX_IS_VERSION_SUPPORTED(1,3) ) { 967 dixLookupResourceByType((pointer*) &pGlxReadPbuffer, readId, 968 __glXPbufferRes, NullClient, 969 DixUnknownAccess); 970 if (pGlxReadPbuffer) { 971 if (pGlxReadPbuffer->pScreen != glxc->pScreen || 972 pGlxReadPbuffer->pFBConfig != glxc->pFBConfig) { 973 client->errorValue = drawId; 974 return BadMatch; 975 } 976 977 pReadDraw = (DrawablePtr)pGlxReadPbuffer; 978 new_reply.readVid = pGlxReadPbuffer->pFBConfig->id; 979 new_reply.readType = GLX_PBUFFER_TYPE; 980 } 981 } 982 983 if (!pReadDraw) { 984 /* 985 ** Drawable is neither a Window nor a GLXPixmap. 986 */ 987 client->errorValue = readId; 988 return __glXBadDrawable; 989 } 990 991 } else { 992 pReadDraw = pDraw; 993 pReadGlxPixmap = pGlxPixmap; 994 pReadWin = pWin; 995 new_reply.readVid = new_reply.writeVid; 996 new_reply.readType = new_reply.writeType; 997 } 998 999 if (prevglxc) { 1000 1001 if (prevglxc->pGlxPixmap) { 1002 /* 1003 ** The previous drawable was a glx pixmap, release it. 1004 */ 1005 prevglxc->pGlxPixmap->refcnt--; 1006 __glXFreeGLXPixmap( prevglxc->pGlxPixmap ); 1007 prevglxc->pGlxPixmap = 0; 1008 } 1009 1010 if (prevglxc->pGlxReadPixmap) { 1011 /* 1012 ** The previous drawable was a glx pixmap, release it. 1013 */ 1014 prevglxc->pGlxReadPixmap->refcnt--; 1015 __glXFreeGLXPixmap( prevglxc->pGlxReadPixmap ); 1016 prevglxc->pGlxReadPixmap = 0; 1017 } 1018 1019 if (prevglxc->pGlxWindow) { 1020 /* 1021 ** The previous drawable was a glx window, release it. 1022 */ 1023 prevglxc->pGlxWindow->refcnt--; 1024 __glXFreeGLXWindow( prevglxc->pGlxWindow ); 1025 prevglxc->pGlxWindow = 0; 1026 } 1027 1028 if (prevglxc->pGlxReadWindow) { 1029 /* 1030 ** The previous drawable was a glx window, release it. 1031 */ 1032 prevglxc->pGlxReadWindow->refcnt--; 1033 __glXFreeGLXWindow( prevglxc->pGlxReadWindow ); 1034 prevglxc->pGlxReadWindow = 0; 1035 } 1036 1037 if (prevglxc->pGlxPbuffer) { 1038 /* 1039 ** The previous drawable was a glx Pbuffer, release it. 1040 */ 1041 prevglxc->pGlxPbuffer->refcnt--; 1042 __glXFreeGLXPbuffer( prevglxc->pGlxPbuffer ); 1043 prevglxc->pGlxPbuffer = 0; 1044 } 1045 1046 if (prevglxc->pGlxReadPbuffer) { 1047 /* 1048 ** The previous drawable was a glx Pbuffer, release it. 1049 */ 1050 prevglxc->pGlxReadPbuffer->refcnt--; 1051 __glXFreeGLXPbuffer( prevglxc->pGlxReadPbuffer ); 1052 prevglxc->pGlxReadPbuffer = 0; 1053 } 1054 1055 ChangeCurrentContext(cl, glxc, tag); 1056 ChangeCurrentContext(cl, glxc, tag); 1057 StopUsingContext(prevglxc); 1058 } else { 1059 tag = AddCurrentContext(cl, glxc, pDraw); 1060 } 1061 if (glxc) { 1062 1063 glxc->pGlxPixmap = pGlxPixmap; 1064 glxc->pGlxReadPixmap = pReadGlxPixmap; 1065 glxc->pGlxWindow = pGlxWindow; 1066 glxc->pGlxReadWindow = pGlxReadWindow; 1067 glxc->pGlxPbuffer = pGlxPbuffer; 1068 glxc->pGlxReadPbuffer = pGlxReadPbuffer; 1069 1070 if (pGlxPixmap) { 1071 pGlxPixmap->refcnt++; 1072 } 1073 1074 if (pReadGlxPixmap) { 1075 pReadGlxPixmap->refcnt++; 1076 } 1077 1078 if (pGlxWindow) { 1079 pGlxWindow->refcnt++; 1080 } 1081 1082 if (pGlxReadWindow) { 1083 pGlxReadWindow->refcnt++; 1084 } 1085 1086 if (pGlxPbuffer) { 1087 pGlxPbuffer->refcnt++; 1088 } 1089 1090 if (pGlxReadPbuffer) { 1091 pGlxReadPbuffer->refcnt++; 1092 } 1093 1094 StartUsingContext(cl, glxc); 1095 new_reply.contextTag = tag; 1096 } else { 1097 new_reply.contextTag = 0; 1098 } 1099 new_reply.length = 0; 1100 new_reply.type = X_Reply; 1101 new_reply.sequenceNumber = client->sequence; 1102 1103#ifdef PANORAMIX 1104 if (!noPanoramiXExtension) { 1105 from_screen = 0; 1106 to_screen = screenInfo.numScreens - 1; 1107 1108 if (pDraw && new_reply.writeType != GLX_PBUFFER_TYPE) { 1109 dixLookupResourceByClass((pointer*) &pXinDraw, 1110 pDraw->id, XRC_DRAWABLE, 1111 client, DixReadAccess); 1112 } 1113 1114 if (pReadDraw && pReadDraw != pDraw && 1115 new_reply.readType != GLX_PBUFFER_TYPE) { 1116 dixLookupResourceByClass((pointer*) &pXinReadDraw, 1117 pReadDraw->id, XRC_DRAWABLE, 1118 client, DixReadAccess); 1119 } 1120 else { 1121 pXinReadDraw = pXinDraw; 1122 } 1123 } 1124#endif 1125 1126 1127 /* send the MakeCurrent request to all required 1128 * back-end servers. 1129 */ 1130 for (s = from_screen; s<=to_screen; s++) { 1131 DMXScreenInfo *dmxScreen = &dmxScreens[s]; 1132 Display *dpy = GetBackEndDisplay(cl,s); 1133 unsigned int be_draw = None; 1134 unsigned int be_read_draw = None; 1135 1136 if (pGlxPixmap) { 1137 be_draw = pGlxPixmap->be_xids[s]; 1138 } 1139 else if (pGlxPbuffer) { 1140 be_draw = pGlxPbuffer->be_xids[s]; 1141 } 1142#ifdef PANORAMIX 1143 else if (pXinDraw) { 1144 dixLookupWindow(&pWin, pXinDraw->info[s].id, client, DixReadAccess); 1145 } 1146#endif 1147 else if (pGlxWindow) { 1148 pWin = (WindowPtr)pGlxWindow->pDraw; 1149 } 1150 1151 if (pWin && be_draw == None) { 1152 be_draw = (unsigned int)(DMX_GET_WINDOW_PRIV(pWin))->window; 1153 if (!be_draw) { 1154 /* it might be that the window did not created yet on the */ 1155 /* back-end server (lazy window creation option), force */ 1156 /* creation of the window */ 1157 dmxCreateAndRealizeWindow( pWin, TRUE ); 1158 be_draw = (unsigned int)(DMX_GET_WINDOW_PRIV(pWin))->window; 1159 } 1160 } 1161 1162 /* 1163 * Before sending the MakeCurrent request - sync the 1164 * X11 connection to the back-end servers to make sure 1165 * that drawable is already created 1166 */ 1167 dmxSync( dmxScreen, 1 ); 1168 1169 if (drawId == readId) { 1170 LockDisplay(dpy); 1171 GetReq(GLXMakeCurrent, be_req); 1172 be_req->reqType = dmxScreen->glxMajorOpcode; 1173 be_req->glxCode = X_GLXMakeCurrent; 1174 be_req->drawable = be_draw; 1175 be_req->context = (unsigned int)(glxc ? glxc->real_ids[s-from_screen] : 0); 1176 be_req->oldContextTag = GetCurrentBackEndTag(cl, tag, s); 1177 if (!_XReply(dpy, (xReply *) &be_reply, 0, False)) { 1178 1179 /* The make current failed */ 1180 UnlockDisplay(dpy); 1181 SyncHandle(); 1182 return( BE_TO_CLIENT_ERROR(dmxLastErrorEvent.error_code) ); 1183 } 1184 1185 UnlockDisplay(dpy); 1186 SyncHandle(); 1187 1188 SetCurrentBackEndTag( cl, tag, s, be_reply.contextTag ); 1189 } 1190 else { 1191 1192 if (pReadGlxPixmap) { 1193 be_read_draw = pReadGlxPixmap->be_xids[s]; 1194 } 1195 else if (pGlxReadPbuffer) { 1196 be_read_draw = pGlxReadPbuffer->be_xids[s]; 1197 } 1198#ifdef PANORAMIX 1199 else if (pXinReadDraw) { 1200 dixLookupWindow(&pReadWin, pXinReadDraw->info[s].id, client, 1201 DixReadAccess); 1202 } 1203#endif 1204 else if (pGlxReadWindow) { 1205 pReadWin = (WindowPtr)pGlxReadWindow->pDraw; 1206 } 1207 1208 if (pReadWin && be_read_draw == None) { 1209 be_read_draw = (unsigned int)(DMX_GET_WINDOW_PRIV(pReadWin))->window; 1210 if (!be_read_draw) { 1211 /* it might be that the window did not created yet on the */ 1212 /* back-end server (lazy window creation option), force */ 1213 /* creation of the window */ 1214 dmxCreateAndRealizeWindow( pReadWin, TRUE ); 1215 be_read_draw = (unsigned int)(DMX_GET_WINDOW_PRIV(pReadWin))->window; 1216 dmxSync( dmxScreen, 1 ); 1217 } 1218 } 1219 1220 if ( __GLX_IS_VERSION_SUPPORTED(1,3) ) { 1221 LockDisplay(dpy); 1222 GetReq(GLXMakeContextCurrent, be_new_req); 1223 be_new_req->reqType = dmxScreen->glxMajorOpcode; 1224 be_new_req->glxCode = X_GLXMakeContextCurrent; 1225 be_new_req->drawable = be_draw; 1226 be_new_req->readdrawable = be_read_draw; 1227 be_new_req->context = (unsigned int)(glxc ? glxc->real_ids[s-from_screen] : 0); 1228 be_new_req->oldContextTag = GetCurrentBackEndTag(cl, tag, s); 1229 if (!_XReply(dpy, (xReply *) &be_new_reply, 0, False)) { 1230 1231 /* The make current failed */ 1232 UnlockDisplay(dpy); 1233 SyncHandle(); 1234 return( BE_TO_CLIENT_ERROR(dmxLastErrorEvent.error_code) ); 1235 } 1236 1237 UnlockDisplay(dpy); 1238 SyncHandle(); 1239 1240 SetCurrentBackEndTag( cl, tag, s, be_new_reply.contextTag ); 1241 } 1242 else if (glxIsExtensionSupported("GLX_SGI_make_current_read")) { 1243 xGLXMakeCurrentReadSGIReq *ext_req; 1244 xGLXVendorPrivateWithReplyReq *vpreq; 1245 xGLXMakeCurrentReadSGIReply ext_reply; 1246 1247 LockDisplay(dpy); 1248 GetReqExtra(GLXVendorPrivateWithReply, 1249 sz_xGLXMakeCurrentReadSGIReq - sz_xGLXVendorPrivateWithReplyReq, 1250 vpreq); 1251 ext_req = (xGLXMakeCurrentReadSGIReq *)vpreq; 1252 ext_req->reqType = dmxScreen->glxMajorOpcode; 1253 ext_req->glxCode = X_GLXVendorPrivateWithReply; 1254 ext_req->vendorCode = X_GLXvop_MakeCurrentReadSGI; 1255 ext_req->drawable = be_draw; 1256 ext_req->readable = be_read_draw; 1257 ext_req->context = (unsigned int)(glxc ? glxc->real_ids[s-from_screen] : 0); 1258 ext_req->oldContextTag = GetCurrentBackEndTag(cl, tag, s); 1259 if (!_XReply(dpy, (xReply *) &ext_reply, 0, False)) { 1260 1261 /* The make current failed */ 1262 UnlockDisplay(dpy); 1263 SyncHandle(); 1264 return( BE_TO_CLIENT_ERROR(dmxLastErrorEvent.error_code) ); 1265 } 1266 1267 UnlockDisplay(dpy); 1268 SyncHandle(); 1269 1270 SetCurrentBackEndTag( cl, tag, s, ext_reply.contextTag ); 1271 1272 } 1273 else { 1274 return BadMatch; 1275 } 1276 } 1277 1278 XFlush( dpy ); 1279 } 1280 1281 if (client->swapped) { 1282 __glXSwapMakeCurrentReply(client, &new_reply); 1283 } else { 1284 WriteToClient(client, sz_xGLXMakeContextCurrentReply, (char *)&new_reply); 1285 } 1286 1287 return Success; 1288} 1289 1290int __glXMakeCurrent(__GLXclientState *cl, GLbyte *pc) 1291{ 1292 xGLXMakeCurrentReq *req = (xGLXMakeCurrentReq *) pc; 1293 1294 return( MakeCurrent(cl, req->drawable, req->drawable, 1295 req->context, req->oldContextTag ) ); 1296} 1297 1298int __glXMakeContextCurrent(__GLXclientState *cl, GLbyte *pc) 1299{ 1300 xGLXMakeContextCurrentReq *req = (xGLXMakeContextCurrentReq *) pc; 1301 1302 return( MakeCurrent(cl, req->drawable, req->readdrawable, 1303 req->context, req->oldContextTag ) ); 1304} 1305 1306int __glXMakeCurrentReadSGI(__GLXclientState *cl, GLbyte *pc) 1307{ 1308 xGLXMakeCurrentReadSGIReq *req = (xGLXMakeCurrentReadSGIReq *) pc; 1309 1310 return( MakeCurrent(cl, req->drawable, req->readable, 1311 req->context, req->oldContextTag ) ); 1312} 1313 1314int __glXIsDirect(__GLXclientState *cl, GLbyte *pc) 1315{ 1316 ClientPtr client = cl->client; 1317 xGLXIsDirectReq *req = (xGLXIsDirectReq *) pc; 1318 xGLXIsDirectReply reply; 1319 __GLXcontext *glxc; 1320 1321 /* 1322 ** Find the GL context. 1323 */ 1324 dixLookupResourceByType((pointer*) &glxc, req->context, __glXContextRes, 1325 NullClient, DixUnknownAccess); 1326 if (!glxc) { 1327 client->errorValue = req->context; 1328 return __glXBadContext; 1329 } 1330 1331 reply.isDirect = 0; 1332 reply.length = 0; 1333 reply.type = X_Reply; 1334 reply.sequenceNumber = client->sequence; 1335 1336 if (client->swapped) { 1337 __glXSwapIsDirectReply(client, &reply); 1338 } else { 1339 WriteToClient(client, sz_xGLXIsDirectReply, (char *)&reply); 1340 } 1341 1342 return Success; 1343} 1344 1345int __glXQueryVersion(__GLXclientState *cl, GLbyte *pc) 1346{ 1347 ClientPtr client = cl->client; 1348/* xGLXQueryVersionReq *req = (xGLXQueryVersionReq *) pc; */ 1349 xGLXQueryVersionReply reply; 1350 1351 /* 1352 ** Server should take into consideration the version numbers sent by the 1353 ** client if it wants to work with older clients; however, in this 1354 ** implementation the server just returns its version number. 1355 */ 1356 reply.majorVersion = __glXVersionMajor; 1357 reply.minorVersion = __glXVersionMinor; 1358 reply.length = 0; 1359 reply.type = X_Reply; 1360 reply.sequenceNumber = client->sequence; 1361 1362 if (client->swapped) { 1363 __glXSwapQueryVersionReply(client, &reply); 1364 } else { 1365 WriteToClient(client, sz_xGLXQueryVersionReply, (char *)&reply); 1366 } 1367 return Success; 1368} 1369 1370int __glXWaitGL(__GLXclientState *cl, GLbyte *pc) 1371{ 1372 xGLXWaitGLReq *req = (xGLXWaitGLReq *)pc; 1373 xGLXWaitGLReq *be_req = (xGLXWaitGLReq *)pc; 1374 int from_screen = 0; 1375 int to_screen = 0; 1376 int s; 1377 __GLXcontext *glxc = NULL; 1378 1379 if (req->contextTag != 0) { 1380 glxc = __glXLookupContextByTag(cl, req->contextTag); 1381 if (glxc) { 1382 from_screen = to_screen = glxc->pScreen->myNum; 1383 } 1384 } 1385 1386#ifdef PANORAMIX 1387 if (!noPanoramiXExtension) { 1388 from_screen = 0; 1389 to_screen = screenInfo.numScreens - 1; 1390 } 1391#endif 1392 1393 for (s=from_screen; s<=to_screen; s++) { 1394 DMXScreenInfo *dmxScreen = &dmxScreens[s]; 1395 Display *dpy = GetBackEndDisplay(cl,s); 1396 1397 LockDisplay(dpy); 1398 GetReq(GLXWaitGL,be_req); 1399 be_req->reqType = dmxScreen->glxMajorOpcode; 1400 be_req->glxCode = X_GLXWaitGL; 1401 be_req->contextTag = (glxc ? GetCurrentBackEndTag(cl,req->contextTag,s) : 0); 1402 UnlockDisplay(dpy); 1403 SyncHandle(); 1404 1405 XSync(dpy, False); 1406 } 1407 1408 return Success; 1409} 1410 1411int __glXWaitX(__GLXclientState *cl, GLbyte *pc) 1412{ 1413 xGLXWaitXReq *req = (xGLXWaitXReq *)pc; 1414 xGLXWaitXReq *be_req; 1415 int from_screen = 0; 1416 int to_screen = 0; 1417 int s; 1418 __GLXcontext *glxc = NULL; 1419 1420 if (req->contextTag != 0) { 1421 glxc = __glXLookupContextByTag(cl, req->contextTag); 1422 if (glxc) { 1423 from_screen = to_screen = glxc->pScreen->myNum; 1424 } 1425 } 1426 1427#ifdef PANORAMIX 1428 if (!noPanoramiXExtension) { 1429 from_screen = 0; 1430 to_screen = screenInfo.numScreens - 1; 1431 } 1432#endif 1433 1434 for (s=from_screen; s<=to_screen; s++) { 1435 DMXScreenInfo *dmxScreen = &dmxScreens[s]; 1436 Display *dpy = GetBackEndDisplay(cl,s); 1437 1438 dmxSync( dmxScreen, 1 ); 1439 1440 LockDisplay(dpy); 1441 GetReq(GLXWaitX,be_req); 1442 be_req->reqType = dmxScreen->glxMajorOpcode; 1443 be_req->glxCode = X_GLXWaitX; 1444 be_req->contextTag = (glxc ? GetCurrentBackEndTag(cl,req->contextTag,s) : 0); 1445 UnlockDisplay(dpy); 1446 SyncHandle(); 1447 1448 XFlush( dpy ); 1449 } 1450 1451 return Success; 1452} 1453 1454int __glXCopyContext(__GLXclientState *cl, GLbyte *pc) 1455{ 1456 ClientPtr client = cl->client; 1457 xGLXCopyContextReq *be_req; 1458 xGLXCopyContextReq *req = (xGLXCopyContextReq *) pc; 1459 GLXContextID source = req->source; 1460 GLXContextID dest = req->dest; 1461 GLXContextTag tag = req->contextTag; 1462 unsigned long mask = req->mask; 1463 __GLXcontext *src, *dst; 1464 int s; 1465 int from_screen = 0; 1466 int to_screen = 0; 1467 1468 /* 1469 ** Check that each context exists. 1470 */ 1471 dixLookupResourceByType((pointer*) &src, source, __glXContextRes, 1472 NullClient, DixUnknownAccess); 1473 if (!src) { 1474 client->errorValue = source; 1475 return __glXBadContext; 1476 } 1477 dixLookupResourceByType((pointer*) &dst, dest, __glXContextRes, 1478 NullClient, DixUnknownAccess); 1479 if (!dst) { 1480 client->errorValue = dest; 1481 return __glXBadContext; 1482 } 1483 1484 /* 1485 ** They must be in the same address space, and same screen. 1486 */ 1487 if (src->pGlxScreen != dst->pGlxScreen) { 1488 client->errorValue = source; 1489 return BadMatch; 1490 } 1491 1492 /* 1493 ** The destination context must not be current for any client. 1494 */ 1495 if (dst->isCurrent) { 1496 client->errorValue = dest; 1497 return BadAccess; 1498 } 1499 1500 if (tag) { 1501 __GLXcontext *tagcx = __glXLookupContextByTag(cl, tag); 1502 1503 if (!tagcx) { 1504 return __glXBadContextTag; 1505 } 1506 if (tagcx != src) { 1507 /* 1508 ** This would be caused by a faulty implementation of the client 1509 ** library. 1510 */ 1511 return BadMatch; 1512 } 1513 } 1514 1515 from_screen = to_screen = src->pScreen->myNum; 1516 1517#ifdef PANORAMIX 1518 if (!noPanoramiXExtension) { 1519 from_screen = 0; 1520 to_screen = screenInfo.numScreens - 1; 1521 } 1522#endif 1523 1524 for (s=from_screen; s<=to_screen; s++) { 1525 DMXScreenInfo *dmxScreen = &dmxScreens[s]; 1526 Display *dpy = GetBackEndDisplay(cl,s); 1527 1528 LockDisplay(dpy); 1529 GetReq(GLXCopyContext,be_req); 1530 be_req->reqType = dmxScreen->glxMajorOpcode; 1531 be_req->glxCode = X_GLXCopyContext; 1532 be_req->source = (unsigned int)src->real_ids[s-from_screen]; 1533 be_req->dest = (unsigned int)dst->real_ids[s-from_screen]; 1534 be_req->mask = mask; 1535 be_req->contextTag = (tag ? GetCurrentBackEndTag(cl,req->contextTag,s) : 0); 1536 UnlockDisplay(dpy); 1537 SyncHandle(); 1538 } 1539 1540 return Success; 1541} 1542 1543int __glXGetVisualConfigs(__GLXclientState *cl, GLbyte *pc) 1544{ 1545 ClientPtr client = cl->client; 1546 xGLXGetVisualConfigsReq *req = (xGLXGetVisualConfigsReq *) pc; 1547 xGLXGetVisualConfigsReply reply; 1548 __GLXscreenInfo *pGlxScreen; 1549 __GLXvisualConfig *pGlxVisual; 1550 CARD32 buf[__GLX_TOTAL_CONFIG]; 1551 unsigned int screen; 1552 int i, p; 1553 1554 screen = req->screen; 1555 if (screen >= screenInfo.numScreens) { 1556 /* The client library must send a valid screen number. */ 1557 client->errorValue = screen; 1558 return BadValue; 1559 } 1560 pGlxScreen = &__glXActiveScreens[screen]; 1561 1562 reply.numVisuals = pGlxScreen->numGLXVisuals; 1563 reply.numProps = __GLX_TOTAL_CONFIG; 1564 reply.length = (pGlxScreen->numGLXVisuals * __GLX_SIZE_CARD32 * 1565 __GLX_TOTAL_CONFIG) >> 2; 1566 reply.type = X_Reply; 1567 reply.sequenceNumber = client->sequence; 1568 1569 WriteToClient(client, sz_xGLXGetVisualConfigsReply, (char *)&reply); 1570 1571 for (i=0; i < pGlxScreen->numVisuals; i++) { 1572 pGlxVisual = &pGlxScreen->pGlxVisual[i]; 1573 if (!pGlxScreen->isGLXvis[i] || pGlxVisual->vid == 0) { 1574 /* not a usable visual */ 1575 continue; 1576 } 1577 p = 0; 1578 buf[p++] = pGlxVisual->vid; 1579 buf[p++] = pGlxVisual->class; 1580 buf[p++] = pGlxVisual->rgba; 1581 1582 buf[p++] = pGlxVisual->redSize; 1583 buf[p++] = pGlxVisual->greenSize; 1584 buf[p++] = pGlxVisual->blueSize; 1585 buf[p++] = pGlxVisual->alphaSize; 1586 buf[p++] = pGlxVisual->accumRedSize; 1587 buf[p++] = pGlxVisual->accumGreenSize; 1588 buf[p++] = pGlxVisual->accumBlueSize; 1589 buf[p++] = pGlxVisual->accumAlphaSize; 1590 1591 buf[p++] = pGlxVisual->doubleBuffer; 1592 buf[p++] = pGlxVisual->stereo; 1593 1594 buf[p++] = pGlxVisual->bufferSize; 1595 buf[p++] = pGlxVisual->depthSize; 1596 buf[p++] = pGlxVisual->stencilSize; 1597 buf[p++] = pGlxVisual->auxBuffers; 1598 buf[p++] = pGlxVisual->level; 1599 /* 1600 ** Add token/value pairs for extensions. 1601 */ 1602 buf[p++] = GLX_VISUAL_CAVEAT_EXT; 1603 buf[p++] = pGlxVisual->visualRating; 1604 buf[p++] = GLX_TRANSPARENT_TYPE_EXT; 1605 buf[p++] = pGlxVisual->transparentPixel; 1606 buf[p++] = GLX_TRANSPARENT_RED_VALUE_EXT; 1607 buf[p++] = pGlxVisual->transparentRed; 1608 buf[p++] = GLX_TRANSPARENT_GREEN_VALUE_EXT; 1609 buf[p++] = pGlxVisual->transparentGreen; 1610 buf[p++] = GLX_TRANSPARENT_BLUE_VALUE_EXT; 1611 buf[p++] = pGlxVisual->transparentBlue; 1612 buf[p++] = GLX_TRANSPARENT_ALPHA_VALUE_EXT; 1613 buf[p++] = pGlxVisual->transparentAlpha; 1614 buf[p++] = GLX_TRANSPARENT_INDEX_VALUE_EXT; 1615 buf[p++] = pGlxVisual->transparentIndex; 1616 buf[p++] = GLX_SAMPLES_SGIS; 1617 buf[p++] = pGlxVisual->multiSampleSize; 1618 buf[p++] = GLX_SAMPLE_BUFFERS_SGIS; 1619 buf[p++] = pGlxVisual->nMultiSampleBuffers; 1620 buf[p++] = GLX_VISUAL_SELECT_GROUP_SGIX; 1621 buf[p++] = pGlxVisual->visualSelectGroup; 1622 1623 WriteToClient(client, __GLX_SIZE_CARD32 * __GLX_TOTAL_CONFIG, 1624 (char *)buf); 1625 } 1626 return Success; 1627} 1628 1629/* 1630** Create a GLX Pixmap from an X Pixmap. 1631*/ 1632static int CreateGLXPixmap(__GLXclientState *cl, 1633 VisualID visual, GLXFBConfigID fbconfigId, 1634 int screenNum, XID pixmapId, XID glxpixmapId ) 1635{ 1636 ClientPtr client = cl->client; 1637 xGLXCreateGLXPixmapReq *be_req; 1638 xGLXCreatePixmapReq *be_new_req; 1639 DrawablePtr pDraw; 1640 ScreenPtr pScreen; 1641 VisualPtr pVisual; 1642 __GLXpixmap *pGlxPixmap; 1643 __GLXscreenInfo *pGlxScreen; 1644 __GLXvisualConfig *pGlxVisual; 1645 __GLXFBConfig *pFBConfig; 1646 int i, s, rc; 1647 int from_screen, to_screen; 1648#ifdef PANORAMIX 1649 PanoramiXRes *pXinDraw = NULL; 1650#endif 1651 1652 rc = dixLookupDrawable(&pDraw, pixmapId, client, M_DRAWABLE_PIXMAP, 1653 DixAddAccess); 1654 if (rc != Success) 1655 return rc; 1656 1657 /* 1658 ** Check if screen of visual matches screen of pixmap. 1659 */ 1660 pScreen = pDraw->pScreen; 1661 if (screenNum != pScreen->myNum) { 1662 return BadMatch; 1663 } 1664 1665 if (fbconfigId == 0 && visual == 0) { 1666 return BadValue; 1667 } 1668 1669 if (fbconfigId != None) { 1670 pFBConfig = glxLookupFBConfig( fbconfigId ); 1671 if (!pFBConfig) { 1672 client->errorValue = fbconfigId; 1673 return BadValue; 1674 } 1675 visual = pFBConfig->associatedVisualId; 1676 } 1677 else { 1678 pFBConfig = NULL; 1679 } 1680 1681 if (visual != None) { 1682 /* 1683 ** Find the VisualRec for this visual. 1684 */ 1685 pVisual = pScreen->visuals; 1686 for (i=0; i < pScreen->numVisuals; i++, pVisual++) { 1687 if (pVisual->vid == visual) { 1688 break; 1689 } 1690 } 1691 if (i == pScreen->numVisuals) { 1692 client->errorValue = visual; 1693 return BadValue; 1694 } 1695 /* 1696 ** Check if depth of visual matches depth of pixmap. 1697 */ 1698 if (pVisual->nplanes != pDraw->depth) { 1699 client->errorValue = visual; 1700 return BadMatch; 1701 } 1702 1703 /* 1704 ** Get configuration of the visual. 1705 */ 1706 pGlxScreen = &__glXActiveScreens[screenNum]; 1707 pGlxVisual = pGlxScreen->pGlxVisual; 1708 for (i = 0; i < pGlxScreen->numVisuals; i++, pGlxVisual++) { 1709 if (pGlxVisual->vid == visual) { 1710 break; 1711 } 1712 } 1713 if (i == pGlxScreen->numVisuals) { 1714 /* 1715 ** Visual not support on this screen by this OpenGL implementation. 1716 */ 1717 client->errorValue = visual; 1718 return BadValue; 1719 } 1720 1721 1722 /* find the FBConfig for that visual (if any) */ 1723 if ( pFBConfig == NULL ) { 1724 pFBConfig = glxLookupFBConfigByVID( visual ); 1725 1726 if ( pFBConfig == NULL ) { 1727 /* 1728 * visual does not have an FBConfig ??? 1729 client->errorValue = visual; 1730 return BadValue; 1731 */ 1732 } 1733 } 1734 } 1735 else { 1736 pVisual = NULL; 1737 pGlxVisual = NULL; 1738 pGlxScreen = &__glXActiveScreens[pDraw->pScreen->myNum]; 1739 } 1740 1741 pGlxPixmap = (__GLXpixmap *) malloc(sizeof(__GLXpixmap)); 1742 if (!pGlxPixmap) { 1743 return BadAlloc; 1744 } 1745 pGlxPixmap->be_xids = (XID *) malloc(sizeof(XID) * screenInfo.numScreens); 1746 if (!pGlxPixmap->be_xids) { 1747 free( pGlxPixmap ); 1748 return BadAlloc; 1749 } 1750 1751 pGlxPixmap->pDraw = pDraw; 1752 pGlxPixmap->pGlxScreen = pGlxScreen; 1753 pGlxPixmap->pGlxVisual = pGlxVisual; 1754 pGlxPixmap->pFBConfig = pFBConfig; 1755 pGlxPixmap->pScreen = pScreen; 1756 pGlxPixmap->idExists = True; 1757 pGlxPixmap->refcnt = 0; 1758 1759 /* 1760 ** Bump the ref count on the X pixmap so it won't disappear. 1761 */ 1762 ((PixmapPtr) pDraw)->refcnt++; 1763 1764 /* 1765 * send the request to the back-end server(s) 1766 */ 1767 from_screen = to_screen = screenNum; 1768#ifdef PANORAMIX 1769 if (!noPanoramiXExtension) { 1770 from_screen = 0; 1771 to_screen = screenInfo.numScreens - 1; 1772 1773 dixLookupResourceByClass((pointer*) &pXinDraw, 1774 pDraw->id, XRC_DRAWABLE, 1775 client, DixReadAccess); 1776 } 1777#endif 1778 1779 for (s=from_screen; s<=to_screen; s++) { 1780 1781 DMXScreenInfo *dmxScreen = &dmxScreens[s]; 1782 Display *dpy = GetBackEndDisplay(cl,s); 1783 Pixmap be_pixmap; 1784 DrawablePtr pRealDraw = pDraw; 1785 1786#ifdef PANORAMIX 1787 if (pXinDraw) { 1788 dixLookupDrawable(&pRealDraw, pXinDraw->info[s].id, client, 0, 1789 DixAddAccess); 1790 } 1791#endif 1792 1793 be_pixmap = (DMX_GET_PIXMAP_PRIV((PixmapPtr)pRealDraw))->pixmap; 1794 1795 /* make sure pixmap already created on back-end */ 1796 dmxSync( dmxScreen, 1 ); 1797 1798 if ( pFBConfig && __GLX_IS_VERSION_SUPPORTED(1,3) ) { 1799 __GLXFBConfig *be_FBConfig = glxLookupBackEndFBConfig( pFBConfig->id, s ); 1800 1801 LockDisplay(dpy); 1802 pGlxPixmap->be_xids[s] = XAllocID(dpy); 1803 GetReq(GLXCreatePixmap,be_new_req); 1804 be_new_req->reqType = dmxScreen->glxMajorOpcode; 1805 be_new_req->glxCode = X_GLXCreatePixmap; 1806 be_new_req->screen = DefaultScreen(dpy); 1807 be_new_req->fbconfig = be_FBConfig->id; 1808 be_new_req->pixmap = (unsigned int)be_pixmap; 1809 be_new_req->glxpixmap = (unsigned int)pGlxPixmap->be_xids[s]; 1810 be_new_req->numAttribs = 0; 1811 UnlockDisplay(dpy); 1812 SyncHandle(); 1813 } 1814 else if (pFBConfig && glxIsExtensionSupported("GLX_SGIX_fbconfig")) { 1815 __GLXFBConfig *be_FBConfig = glxLookupBackEndFBConfig( pFBConfig->id, s ); 1816 xGLXCreateGLXPixmapWithConfigSGIXReq *ext_req; 1817 xGLXVendorPrivateReq *vpreq; 1818 1819 LockDisplay(dpy); 1820 pGlxPixmap->be_xids[s] = XAllocID(dpy); 1821 GetReqExtra(GLXVendorPrivate, 1822 sz_xGLXCreateGLXPixmapWithConfigSGIXReq-sz_xGLXVendorPrivateReq, 1823 vpreq); 1824 ext_req = (xGLXCreateGLXPixmapWithConfigSGIXReq *)vpreq; 1825 ext_req->reqType = dmxScreen->glxMajorOpcode; 1826 ext_req->glxCode = X_GLXVendorPrivate; 1827 ext_req->vendorCode = X_GLXvop_CreateGLXPixmapWithConfigSGIX; 1828 ext_req->screen = DefaultScreen(dpy); 1829 ext_req->fbconfig = be_FBConfig->id; 1830 ext_req->pixmap = (unsigned int)be_pixmap; 1831 ext_req->glxpixmap = (unsigned int)pGlxPixmap->be_xids[s]; 1832 UnlockDisplay(dpy); 1833 SyncHandle(); 1834 } 1835 else if (pGlxVisual) { 1836 LockDisplay(dpy); 1837 pGlxPixmap->be_xids[s] = XAllocID(dpy); 1838 GetReq(GLXCreateGLXPixmap,be_req); 1839 be_req->reqType = dmxScreen->glxMajorOpcode; 1840 be_req->glxCode = X_GLXCreateGLXPixmap; 1841 be_req->screen = DefaultScreen(dpy); 1842 be_req->visual = (unsigned int)glxMatchGLXVisualInConfigList( 1843 pGlxVisual, 1844 dmxScreen->glxVisuals, 1845 dmxScreen->numGlxVisuals ); 1846 be_req->pixmap = (unsigned int)be_pixmap; 1847 be_req->glxpixmap = (unsigned int)pGlxPixmap->be_xids[s]; 1848 UnlockDisplay(dpy); 1849 SyncHandle(); 1850 } 1851 else { 1852 client->errorValue = ( visual ? visual : fbconfigId ); 1853 free( pGlxPixmap ); 1854 return BadValue; 1855 } 1856 1857 XFlush( dpy ); 1858 } 1859 1860 if (!(AddResource(glxpixmapId, __glXPixmapRes, pGlxPixmap))) { 1861 free( pGlxPixmap ); 1862 return BadAlloc; 1863 } 1864 1865 return Success; 1866} 1867 1868int __glXCreateGLXPixmap(__GLXclientState *cl, GLbyte *pc) 1869{ 1870 xGLXCreateGLXPixmapReq *req = (xGLXCreateGLXPixmapReq *) pc; 1871 1872 return( CreateGLXPixmap(cl, req->visual, None, 1873 req->screen, req->pixmap, req->glxpixmap) ); 1874} 1875 1876int __glXCreatePixmap(__GLXclientState *cl, GLbyte *pc) 1877{ 1878 xGLXCreatePixmapReq *req = (xGLXCreatePixmapReq *) pc; 1879 1880 return( CreateGLXPixmap(cl, None, req->fbconfig, 1881 req->screen, req->pixmap, req->glxpixmap) ); 1882} 1883 1884int __glXDestroyGLXPixmap(__GLXclientState *cl, GLbyte *pc) 1885{ 1886 ClientPtr client = cl->client; 1887 xGLXDestroyGLXPixmapReq *req = (xGLXDestroyGLXPixmapReq *) pc; 1888 XID glxpixmap = req->glxpixmap; 1889 __GLXpixmap *pGlxPixmap; 1890 int s; 1891 int from_screen, to_screen; 1892 1893 /* 1894 ** Check if it's a valid GLX pixmap. 1895 */ 1896 dixLookupResourceByType((pointer*) &pGlxPixmap, glxpixmap, 1897 __glXPixmapRes, NullClient, DixUnknownAccess); 1898 if (!pGlxPixmap) { 1899 client->errorValue = glxpixmap; 1900 return __glXBadPixmap; 1901 } 1902 FreeResource(glxpixmap, FALSE); 1903 1904 /* 1905 * destroy the pixmap on the back-end server(s). 1906 */ 1907 from_screen = to_screen = pGlxPixmap->pDraw->pScreen->myNum; 1908#ifdef PANORAMIX 1909 if (!noPanoramiXExtension) { 1910 from_screen = 0; 1911 to_screen = screenInfo.numScreens - 1; 1912 } 1913#endif 1914 1915 for (s=from_screen; s<=to_screen; s++) { 1916 DMXScreenInfo *dmxScreen = &dmxScreens[s]; 1917 Display *dpy = GetBackEndDisplay(cl,s); 1918 1919 /* make sure pixmap exist in back-end */ 1920 dmxSync( dmxScreen, 1 ); 1921 1922 LockDisplay(dpy); 1923 GetReq(GLXDestroyGLXPixmap,req); 1924 req->reqType = dmxScreen->glxMajorOpcode; 1925 req->glxCode = X_GLXDestroyGLXPixmap; 1926 req->glxpixmap = (unsigned int)pGlxPixmap->be_xids[s]; 1927 UnlockDisplay(dpy); 1928 SyncHandle(); 1929 } 1930 1931 1932 return Success; 1933} 1934 1935/*****************************************************************************/ 1936 1937/* 1938** NOTE: There is no portable implementation for swap buffers as of 1939** this time that is of value. Consequently, this code must be 1940** implemented by somebody other than SGI. 1941*/ 1942int __glXDoSwapBuffers(__GLXclientState *cl, XID drawId, GLXContextTag tag) 1943{ 1944 ClientPtr client = cl->client; 1945 DrawablePtr pDraw; 1946 xGLXSwapBuffersReq *be_req; 1947 WindowPtr pWin = NULL; 1948 __GLXpixmap *pGlxPixmap = NULL; 1949 __GLXcontext *glxc = NULL; 1950#ifdef PANORAMIX 1951 PanoramiXRes *pXinDraw = NULL; 1952#endif 1953 __glXWindow *pGlxWindow = NULL; 1954 int from_screen = 0; 1955 int to_screen = 0; 1956 int s, rc; 1957 1958 /* 1959 ** Check that the GLX drawable is valid. 1960 */ 1961 rc = dixLookupDrawable(&pDraw, drawId, client, 0, DixWriteAccess); 1962 if (rc == Success) { 1963 from_screen = to_screen = pDraw->pScreen->myNum; 1964 1965 if (pDraw->type == DRAWABLE_WINDOW) { 1966 /* 1967 ** Drawable is an X window. 1968 */ 1969 pWin = (WindowPtr)pDraw; 1970 } else { 1971 /* 1972 ** Drawable is an X pixmap, which is not allowed. 1973 */ 1974 client->errorValue = drawId; 1975 return __glXBadDrawable; 1976 } 1977 } 1978 1979 if (!pDraw) { 1980 dixLookupResourceByType((pointer*) &pGlxPixmap, drawId, 1981 __glXPixmapRes, NullClient, DixUnknownAccess); 1982 if (pGlxPixmap) { 1983 /* 1984 ** Drawable is a GLX pixmap. 1985 */ 1986 pDraw = pGlxPixmap->pDraw; 1987 from_screen = to_screen = pGlxPixmap->pScreen->myNum; 1988 } 1989 } 1990 1991 if (!pDraw && __GLX_IS_VERSION_SUPPORTED(1,3) ) { 1992 dixLookupResourceByType((pointer*) &pGlxWindow, drawId, 1993 __glXWindowRes, NullClient, DixUnknownAccess); 1994 if (pGlxWindow) { 1995 /* 1996 ** Drawable is a GLXWindow. 1997 */ 1998 pDraw = pGlxWindow->pDraw; 1999 from_screen = to_screen = pGlxWindow->pScreen->myNum; 2000 } 2001 } 2002 2003 if (!pDraw) { 2004 /* 2005 ** Drawable is neither a X window nor a GLX pixmap. 2006 */ 2007 client->errorValue = drawId; 2008 return __glXBadDrawable; 2009 } 2010 2011 if (tag) { 2012 glxc = __glXLookupContextByTag(cl, tag); 2013 if (!glxc) { 2014 return __glXBadContextTag; 2015 } 2016 } 2017 2018#ifdef PANORAMIX 2019 if (!noPanoramiXExtension) { 2020 from_screen = 0; 2021 to_screen = screenInfo.numScreens - 1; 2022 dixLookupResourceByClass((pointer*) &pXinDraw, 2023 pDraw->id, XRC_DRAWABLE, 2024 client, DixReadAccess); 2025 } 2026#endif 2027 2028 /* If requested, send a glFinish to all back-end servers before swapping. */ 2029 if (dmxGLXFinishSwap) { 2030 for (s=from_screen; s<=to_screen; s++) { 2031 Display *dpy = GetBackEndDisplay(cl,s); 2032 DMXScreenInfo *dmxScreen = &dmxScreens[s]; 2033 xGLXSingleReq *finishReq; 2034 xGLXSingleReply reply; 2035 2036#define X_GLXSingle 0 /* needed by GetReq below */ 2037 2038 LockDisplay(dpy); 2039 GetReq(GLXSingle,finishReq); 2040 finishReq->reqType = dmxScreen->glxMajorOpcode; 2041 finishReq->glxCode = X_GLsop_Finish; 2042 finishReq->contextTag = (tag ? GetCurrentBackEndTag(cl,tag,s) : 0); 2043 (void) _XReply(dpy, (xReply*) &reply, 0, False); 2044 UnlockDisplay(dpy); 2045 SyncHandle(); 2046 } 2047 } 2048 2049 /* If requested, send an XSync to all back-end servers before swapping. */ 2050 if (dmxGLXSyncSwap) { 2051 for (s=from_screen; s<=to_screen; s++) 2052 XSync(GetBackEndDisplay(cl,s), False); 2053 } 2054 2055 2056 /* send the SwapBuffers request to all back-end servers */ 2057 2058 for (s=from_screen; s<=to_screen; s++) { 2059 DMXScreenInfo *dmxScreen = &dmxScreens[s]; 2060 Display *dpy = GetBackEndDisplay(cl,s); 2061 unsigned int be_draw = 0; 2062 2063 if (pGlxPixmap) { 2064 be_draw = (unsigned int)pGlxPixmap->be_xids[s]; 2065 } 2066#ifdef PANORAMIX 2067 else if (pXinDraw) { 2068 dixLookupWindow(&pWin, pXinDraw->info[s].id, client, DixReadAccess); 2069 } 2070#endif 2071 else if (pGlxWindow) { 2072 pWin = (WindowPtr)pGlxWindow->pDraw; 2073 } 2074 2075 if (pWin && !be_draw) { 2076 be_draw = (unsigned int)(DMX_GET_WINDOW_PRIV(pWin))->window; 2077 if (!be_draw) { 2078 /* it might be that the window did not created yet on the */ 2079 /* back-end server (lazy window creation option), force */ 2080 /* creation of the window */ 2081 dmxCreateAndRealizeWindow( pWin, TRUE ); 2082 be_draw = (unsigned int)(DMX_GET_WINDOW_PRIV(pWin))->window; 2083 } 2084 } 2085 2086 dmxSync( dmxScreen, 1 ); 2087 2088 LockDisplay(dpy); 2089 GetReq(GLXSwapBuffers,be_req); 2090 be_req->reqType = dmxScreen->glxMajorOpcode; 2091 be_req->glxCode = X_GLXSwapBuffers; 2092 be_req->drawable = be_draw; 2093 be_req->contextTag = ( tag ? GetCurrentBackEndTag(cl,tag,s) : 0 ); 2094 UnlockDisplay(dpy); 2095 SyncHandle(); 2096 XFlush(dpy); 2097 } 2098 2099 return Success; 2100} 2101 2102int __glXSwapBuffers(__GLXclientState *cl, GLbyte *pc) 2103{ 2104 ClientPtr client = cl->client; 2105 DrawablePtr pDraw; 2106 xGLXSwapBuffersReq *req = (xGLXSwapBuffersReq *) pc; 2107 GLXContextTag tag = req->contextTag; 2108 XID drawId = req->drawable; 2109 __GLXpixmap *pGlxPixmap = NULL; 2110 __GLXcontext *glxc = NULL; 2111 __glXWindow *pGlxWindow = NULL; 2112 int rc; 2113 2114 /* 2115 ** Check that the GLX drawable is valid. 2116 */ 2117 rc = dixLookupDrawable(&pDraw, drawId, client, 0, DixWriteAccess); 2118 if (rc == Success) { 2119 if (pDraw->type != DRAWABLE_WINDOW) { 2120 /* 2121 ** Drawable is an X pixmap, which is not allowed. 2122 */ 2123 client->errorValue = drawId; 2124 return __glXBadDrawable; 2125 } 2126 } 2127 2128 if (!pDraw) { 2129 dixLookupResourceByType((pointer*) &pGlxPixmap, drawId, 2130 __glXPixmapRes, NullClient, DixUnknownAccess); 2131 if (pGlxPixmap) { 2132 /* 2133 ** Drawable is a GLX pixmap. 2134 */ 2135 pDraw = pGlxPixmap->pDraw; 2136 } 2137 } 2138 2139 if (!pDraw && __GLX_IS_VERSION_SUPPORTED(1,3) ) { 2140 dixLookupResourceByType((pointer*) &pGlxWindow, drawId, 2141 __glXWindowRes, NullClient, DixUnknownAccess); 2142 if (pGlxWindow) { 2143 /* 2144 ** Drawable is a GLXWindow. 2145 */ 2146 pDraw = pGlxWindow->pDraw; 2147 } 2148 } 2149 2150 if (!pDraw) { 2151 /* 2152 ** Drawable is neither a X window nor a GLX pixmap. 2153 */ 2154 client->errorValue = drawId; 2155 return __glXBadDrawable; 2156 } 2157 2158 if (tag) { 2159 glxc = __glXLookupContextByTag(cl, tag); 2160 if (!glxc) { 2161 return __glXBadContextTag; 2162 } 2163 } 2164 2165 if (pDraw && 2166 pDraw->type == DRAWABLE_WINDOW && 2167 DMX_GET_WINDOW_PRIV((WindowPtr)pDraw)->swapGroup) { 2168 return SGSwapBuffers(cl, drawId, tag, pDraw); 2169 } 2170 2171 return __glXDoSwapBuffers(cl, drawId, tag); 2172} 2173 2174 2175/************************************************************************/ 2176 2177/* 2178** Render and Renderlarge are not in the GLX API. They are used by the GLX 2179** client library to send batches of GL rendering commands. 2180*/ 2181 2182/* 2183** Execute all the drawing commands in a request. 2184*/ 2185int __glXRender(__GLXclientState *cl, GLbyte *pc) 2186{ 2187 xGLXRenderReq *req; 2188 xGLXRenderReq *be_req; 2189 int size; 2190 __GLXcontext *glxc; 2191 int from_screen = 0; 2192 int to_screen = 0; 2193 int s; 2194 2195 /* 2196 ** NOTE: much of this code also appears in the byteswapping version of this 2197 ** routine, __glXSwapRender(). Any changes made here should also be 2198 ** duplicated there. 2199 */ 2200 2201 req = (xGLXRenderReq *) pc; 2202 2203 glxc = __glXLookupContextByTag(cl, req->contextTag); 2204 if (!glxc) { 2205 return 0; 2206 } 2207 from_screen = to_screen = glxc->pScreen->myNum; 2208 2209#ifdef PANORAMIX 2210 if (!noPanoramiXExtension) { 2211 from_screen = 0; 2212 to_screen = screenInfo.numScreens - 1; 2213 } 2214#endif 2215 2216 pc += sz_xGLXRenderReq; 2217 size = (req->length << 2) - sz_xGLXRenderReq; 2218 2219 /* 2220 * just forward the request to back-end server(s) 2221 */ 2222 for (s=from_screen; s<=to_screen; s++) { 2223 DMXScreenInfo *dmxScreen = &dmxScreens[s]; 2224 Display *dpy = GetBackEndDisplay(cl,s); 2225 2226 LockDisplay(dpy); 2227 GetReq(GLXRender,be_req); 2228 be_req->reqType = dmxScreen->glxMajorOpcode; 2229 be_req->glxCode = X_GLXRender; 2230 be_req->length = req->length; 2231 be_req->contextTag = GetCurrentBackEndTag(cl,req->contextTag,s); 2232 _XSend(dpy, (const char *)pc, size); 2233 UnlockDisplay(dpy); 2234 SyncHandle(); 2235 } 2236 2237 return Success; 2238} 2239 2240/* 2241** Execute a large rendering request (one that spans multiple X requests). 2242*/ 2243int __glXRenderLarge(__GLXclientState *cl, GLbyte *pc) 2244{ 2245 xGLXRenderLargeReq *req; 2246 xGLXRenderLargeReq *be_req; 2247 __GLXcontext *glxc; 2248 int from_screen = 0; 2249 int to_screen = 0; 2250 int s; 2251 2252 /* 2253 ** NOTE: much of this code also appears in the byteswapping version of this 2254 ** routine, __glXSwapRenderLarge(). Any changes made here should also be 2255 ** duplicated there. 2256 */ 2257 2258 req = (xGLXRenderLargeReq *) pc; 2259 glxc = __glXLookupContextByTag(cl, req->contextTag); 2260 if (!glxc) { 2261 return 0; 2262 } 2263 from_screen = to_screen = glxc->pScreen->myNum; 2264 2265#ifdef PANORAMIX 2266 if (!noPanoramiXExtension) { 2267 from_screen = 0; 2268 to_screen = screenInfo.numScreens - 1; 2269 } 2270#endif 2271 2272 pc += sz_xGLXRenderLargeReq; 2273 2274 /* 2275 * just forward the request to back-end server(s) 2276 */ 2277 for (s=from_screen; s<=to_screen; s++) { 2278 DMXScreenInfo *dmxScreen = &dmxScreens[s]; 2279 Display *dpy = GetBackEndDisplay(cl,s); 2280 2281 GetReq(GLXRenderLarge,be_req); 2282 be_req->reqType = dmxScreen->glxMajorOpcode; 2283 be_req->glxCode = X_GLXRenderLarge; 2284 be_req->contextTag = GetCurrentBackEndTag(cl,req->contextTag,s); 2285 be_req->length = req->length; 2286 be_req->requestNumber = req->requestNumber; 2287 be_req->requestTotal = req->requestTotal; 2288 be_req->dataBytes = req->dataBytes; 2289 Data(dpy, (const char *)pc, req->dataBytes); 2290 UnlockDisplay(dpy); 2291 SyncHandle(); 2292 2293 } 2294 2295 return Success; 2296} 2297 2298 2299/************************************************************************/ 2300 2301int __glXVendorPrivate(__GLXclientState *cl, GLbyte *pc) 2302{ 2303 xGLXVendorPrivateReq *req; 2304 2305 req = (xGLXVendorPrivateReq *) pc; 2306 2307 switch( req->vendorCode ) { 2308 2309 case X_GLvop_DeleteTexturesEXT: 2310 return __glXVForwardSingleReq( cl, pc ); 2311 break; 2312 2313 case X_GLXvop_SwapIntervalSGI: 2314 if (glxIsExtensionSupported("SGI_swap_control")) { 2315 return __glXVForwardSingleReq( cl, pc ); 2316 } 2317 else { 2318 return Success; 2319 } 2320 break; 2321 2322#if 0 /* glx 1.3 */ 2323 case X_GLXvop_CreateGLXVideoSourceSGIX: 2324 break; 2325 case X_GLXvop_DestroyGLXVideoSourceSGIX: 2326 break; 2327 case X_GLXvop_CreateGLXPixmapWithConfigSGIX: 2328 break; 2329 case X_GLXvop_DestroyGLXPbufferSGIX: 2330 break; 2331 case X_GLXvop_ChangeDrawableAttributesSGIX: 2332 break; 2333#endif 2334 2335 case X_GLXvop_BindSwapBarrierSGIX: 2336 return __glXBindSwapBarrierSGIX( cl, pc ); 2337 break; 2338 2339 case X_GLXvop_JoinSwapGroupSGIX: 2340 return __glXJoinSwapGroupSGIX( cl, pc ); 2341 break; 2342 2343 case X_GLXvop_CreateContextWithConfigSGIX: 2344 return __glXCreateContextWithConfigSGIX( cl, pc ); 2345 break; 2346 2347 default: 2348 /* 2349 ** unsupported private request 2350 */ 2351 cl->client->errorValue = req->vendorCode; 2352 return __glXUnsupportedPrivateRequest; 2353 } 2354 2355 cl->client->errorValue = req->vendorCode; 2356 return __glXUnsupportedPrivateRequest; 2357 2358} 2359 2360int __glXVendorPrivateWithReply(__GLXclientState *cl, GLbyte *pc) 2361{ 2362 xGLXVendorPrivateWithReplyReq *req; 2363 2364 req = (xGLXVendorPrivateWithReplyReq *) pc; 2365 2366 switch( req->vendorCode ) { 2367 2368 case X_GLvop_GetConvolutionFilterEXT: 2369 case X_GLvop_GetConvolutionParameterfvEXT: 2370 case X_GLvop_GetConvolutionParameterivEXT: 2371 case X_GLvop_GetSeparableFilterEXT: 2372 case X_GLvop_GetHistogramEXT: 2373 case X_GLvop_GetHistogramParameterivEXT: 2374 case X_GLvop_GetMinmaxEXT: 2375 case X_GLvop_GetMinmaxParameterfvEXT: 2376 case X_GLvop_GetMinmaxParameterivEXT: 2377 case X_GLvop_AreTexturesResidentEXT: 2378 case X_GLvop_IsTextureEXT: 2379 return( __glXVForwardPipe0WithReply(cl, pc) ); 2380 break; 2381 2382 case X_GLvop_GenTexturesEXT: 2383 return( __glXVForwardAllWithReply(cl, pc) ); 2384 break; 2385 2386 2387#if 0 /* glx1.3 */ 2388 case X_GLvop_GetDetailTexFuncSGIS: 2389 case X_GLvop_GetSharpenTexFuncSGIS: 2390 case X_GLvop_GetColorTableSGI: 2391 case X_GLvop_GetColorTableParameterfvSGI: 2392 case X_GLvop_GetColorTableParameterivSGI: 2393 case X_GLvop_GetTexFilterFuncSGIS: 2394 case X_GLvop_GetInstrumentsSGIX: 2395 case X_GLvop_InstrumentsBufferSGIX: 2396 case X_GLvop_PollInstrumentsSGIX: 2397 case X_GLvop_FlushRasterSGIX: 2398 case X_GLXvop_CreateGLXPbufferSGIX: 2399 case X_GLXvop_GetDrawableAttributesSGIX: 2400 case X_GLXvop_QueryHyperpipeNetworkSGIX: 2401 case X_GLXvop_QueryHyperpipeConfigSGIX: 2402 case X_GLXvop_HyperpipeConfigSGIX: 2403 case X_GLXvop_DestroyHyperpipeConfigSGIX: 2404#endif 2405 case X_GLXvop_QueryMaxSwapBarriersSGIX: 2406 return( __glXQueryMaxSwapBarriersSGIX(cl, pc) ); 2407 break; 2408 2409 case X_GLXvop_GetFBConfigsSGIX: 2410 return( __glXGetFBConfigsSGIX(cl, pc) ); 2411 break; 2412 2413 case X_GLXvop_MakeCurrentReadSGI: 2414 return( __glXMakeCurrentReadSGI(cl, pc) ); 2415 break; 2416 2417 case X_GLXvop_QueryContextInfoEXT: 2418 return( __glXQueryContextInfoEXT(cl,pc) ); 2419 break; 2420 2421 default: 2422 /* 2423 ** unsupported private request 2424 */ 2425 cl->client->errorValue = req->vendorCode; 2426 return __glXUnsupportedPrivateRequest; 2427 } 2428 2429} 2430 2431int __glXQueryExtensionsString(__GLXclientState *cl, GLbyte *pc) 2432{ 2433 ClientPtr client = cl->client; 2434 xGLXQueryExtensionsStringReq *req = (xGLXQueryExtensionsStringReq *) pc; 2435 xGLXQueryExtensionsStringReply reply; 2436 GLint screen; 2437 size_t length; 2438 int len, numbytes; 2439 char *be_buf; 2440 2441#ifdef FWD_QUERY_REQ 2442 xGLXQueryExtensionsStringReq *be_req; 2443 xGLXQueryExtensionsStringReply be_reply; 2444 DMXScreenInfo *dmxScreen; 2445 Display *dpy; 2446 int slop; 2447#endif 2448 2449 screen = req->screen; 2450 2451 /* 2452 ** Check if screen exists. 2453 */ 2454 if ((screen < 0) || (screen >= screenInfo.numScreens)) { 2455 client->errorValue = screen; 2456 return BadValue; 2457 } 2458 2459#ifdef FWD_QUERY_REQ 2460 dmxScreen = &dmxScreens[screen]; 2461 2462 /* Send the glXQueryServerString request */ 2463 dpy = GetBackEndDisplay(cl,screen); 2464 LockDisplay(dpy); 2465 GetReq(GLXQueryExtensionsString,be_req); 2466 be_req->reqType = dmxScreen->glxMajorOpcode; 2467 be_req->glxCode = X_GLXQueryServerString; 2468 be_req->screen = DefaultScreen(dpy); 2469 _XReply(dpy, (xReply*) &be_reply, 0, False); 2470 len = (int)be_reply.length; 2471 numbytes = (int)be_reply.n; 2472 slop = numbytes * __GLX_SIZE_INT8 & 3; 2473 be_buf = (char *)malloc(numbytes); 2474 if (!be_buf) { 2475 /* Throw data on the floor */ 2476 _XEatData(dpy, len); 2477 } else { 2478 _XRead(dpy, (char *)be_buf, numbytes); 2479 if (slop) _XEatData(dpy,4-slop); 2480 } 2481 UnlockDisplay(dpy); 2482 SyncHandle(); 2483 2484#else 2485 2486 be_buf = __glXGetServerString(GLX_EXTENSIONS); 2487 numbytes = strlen(be_buf) + 1; 2488 len = __GLX_PAD(numbytes) >> 2; 2489 2490#endif 2491 2492 length = len; 2493 reply.type = X_Reply; 2494 reply.sequenceNumber = client->sequence; 2495 reply.length = len; 2496 reply.n = numbytes; 2497 2498 if (client->swapped) { 2499 glxSwapQueryExtensionsStringReply(client, &reply, be_buf); 2500 } else { 2501 WriteToClient(client, sz_xGLXQueryExtensionsStringReply,(char *)&reply); 2502 WriteToClient(client, (int)(length << 2), (char *)be_buf); 2503 } 2504 2505 return Success; 2506} 2507 2508int __glXQueryServerString(__GLXclientState *cl, GLbyte *pc) 2509{ 2510 ClientPtr client = cl->client; 2511 xGLXQueryServerStringReq *req = (xGLXQueryServerStringReq *) pc; 2512 xGLXQueryServerStringReply reply; 2513 int name; 2514 GLint screen; 2515 size_t length; 2516 int len, numbytes; 2517 char *be_buf; 2518#ifdef FWD_QUERY_REQ 2519 xGLXQueryServerStringReq *be_req; 2520 xGLXQueryServerStringReply be_reply; 2521 DMXScreenInfo *dmxScreen; 2522 Display *dpy; 2523 int slop; 2524#endif 2525 2526 name = req->name; 2527 screen = req->screen; 2528 /* 2529 ** Check if screen exists. 2530 */ 2531 if ((screen < 0) || (screen >= screenInfo.numScreens)) { 2532 client->errorValue = screen; 2533 return BadValue; 2534 } 2535 2536#ifdef FWD_QUERY_REQ 2537 dmxScreen = &dmxScreens[screen]; 2538 2539 /* Send the glXQueryServerString request */ 2540 dpy = GetBackEndDisplay(cl,screen); 2541 LockDisplay(dpy); 2542 GetReq(GLXQueryServerString,be_req); 2543 be_req->reqType = dmxScreen->glxMajorOpcode; 2544 be_req->glxCode = X_GLXQueryServerString; 2545 be_req->screen = DefaultScreen(dpy); 2546 be_req->name = name; 2547 _XReply(dpy, (xReply*) &be_reply, 0, False); 2548 len = (int)be_reply.length; 2549 numbytes = (int)be_reply.n; 2550 slop = numbytes * __GLX_SIZE_INT8 & 3; 2551 be_buf = (char *)malloc(numbytes); 2552 if (!be_buf) { 2553 /* Throw data on the floor */ 2554 _XEatData(dpy, len); 2555 } else { 2556 _XRead(dpy, (char *)be_buf, numbytes); 2557 if (slop) _XEatData(dpy,4-slop); 2558 } 2559 UnlockDisplay(dpy); 2560 SyncHandle(); 2561 2562#else 2563 be_buf = __glXGetServerString(name); 2564 numbytes = strlen(be_buf) + 1; 2565 len = __GLX_PAD(numbytes) >> 2; 2566#endif 2567 2568 length = len; 2569 reply.type = X_Reply; 2570 reply.sequenceNumber = client->sequence; 2571 reply.length = length; 2572 reply.n = numbytes; 2573 2574 if (client->swapped) { 2575 glxSwapQueryServerStringReply(client, &reply, be_buf); 2576 } else { 2577 WriteToClient(client, sz_xGLXQueryServerStringReply, (char *)&reply); 2578 WriteToClient(client, (int)(length << 2), be_buf); 2579 } 2580 2581 return Success; 2582} 2583 2584int __glXClientInfo(__GLXclientState *cl, GLbyte *pc) 2585{ 2586 xGLXClientInfoReq *req = (xGLXClientInfoReq *) pc; 2587 xGLXClientInfoReq *be_req; 2588 const char *buf; 2589 int from_screen = 0; 2590 int to_screen = 0; 2591 int s; 2592 2593 cl->GLClientmajorVersion = req->major; 2594 cl->GLClientminorVersion = req->minor; 2595 free(cl->GLClientextensions); 2596 buf = (const char *)(req+1); 2597 cl->GLClientextensions = strdup(buf); 2598 2599 to_screen = screenInfo.numScreens - 1; 2600 2601 for (s=from_screen; s<=to_screen; s++) 2602 { 2603 DMXScreenInfo *dmxScreen = &dmxScreens[s]; 2604 Display *dpy = GetBackEndDisplay(cl,s); 2605 2606 LockDisplay(dpy); 2607 GetReq(GLXClientInfo,be_req); 2608 be_req->reqType = dmxScreen->glxMajorOpcode; 2609 be_req->glxCode = X_GLXClientInfo; 2610 be_req->major = req->major; 2611 be_req->minor = req->minor; 2612 be_req->length = req->length; 2613 be_req->numbytes = req->numbytes; 2614 Data(dpy, buf, req->numbytes); 2615 2616 UnlockDisplay(dpy); 2617 SyncHandle(); 2618 } 2619 2620 return Success; 2621} 2622 2623int __glXUseXFont(__GLXclientState *cl, GLbyte *pc) 2624{ 2625 ClientPtr client = cl->client; 2626 xGLXUseXFontReq *req; 2627 xGLXUseXFontReq *be_req; 2628 FontPtr pFont; 2629 __GLXcontext *glxc = NULL; 2630 int from_screen = 0; 2631 int to_screen = 0; 2632 int s; 2633 dmxFontPrivPtr pFontPriv; 2634 DMXScreenInfo *dmxScreen; 2635 Display *dpy; 2636 2637 req = (xGLXUseXFontReq *) pc; 2638 2639 if (req->contextTag != 0) { 2640 glxc = __glXLookupContextByTag(cl, req->contextTag); 2641 if (glxc) { 2642 from_screen = to_screen = glxc->pScreen->myNum; 2643 } 2644 } 2645 2646 /* 2647 ** Font can actually be either the ID of a font or the ID of a GC 2648 ** containing a font. 2649 */ 2650 dixLookupResourceByType((pointer*) &pFont, req->font, RT_FONT, 2651 NullClient, DixUnknownAccess); 2652 if (!pFont) { 2653 GC *pGC; 2654 dixLookupResourceByType((pointer*) &pGC, req->font, 2655 RT_GC, NullClient, 2656 DixUnknownAccess); 2657 if (!pGC) { 2658 client->errorValue = req->font; 2659 return BadFont; 2660 } 2661 pFont = pGC->font; 2662 } 2663 2664 pFontPriv = FontGetPrivate(pFont, dmxFontPrivateIndex); 2665 2666#ifdef PANORAMIX 2667 if (!noPanoramiXExtension) { 2668 from_screen = 0; 2669 to_screen = screenInfo.numScreens - 1; 2670 } 2671#endif 2672 2673 2674 for (s=from_screen; s<=to_screen; s++) { 2675 dmxScreen = &dmxScreens[s]; 2676 dpy = GetBackEndDisplay(cl,s); 2677 2678 dmxSync( dmxScreen, 1 ); 2679 2680 LockDisplay(dpy); 2681 GetReq(GLXUseXFont,be_req); 2682 be_req->reqType = dmxScreen->glxMajorOpcode; 2683 be_req->glxCode = X_GLXUseXFont; 2684 be_req->contextTag = (glxc ? GetCurrentBackEndTag(cl,req->contextTag,s) : 0); 2685 be_req->font = pFontPriv->font[s]->fid; 2686 be_req->first = req->first; 2687 be_req->count = req->count; 2688 be_req->listBase = req->listBase; 2689 UnlockDisplay(dpy); 2690 SyncHandle(); 2691 2692 XSync( dpy, False ); 2693 } 2694 2695 return Success; 2696} 2697 2698/* 2699 * start GLX 1.3 here 2700 */ 2701 2702int __glXGetFBConfigs(__GLXclientState *cl, GLbyte *pc) 2703{ 2704 ClientPtr client = cl->client; 2705 xGLXGetFBConfigsReq *req = (xGLXGetFBConfigsReq *) pc; 2706 xGLXGetFBConfigsReply reply; 2707 __GLXFBConfig *pFBConfig; 2708 CARD32 buf[2 * __GLX_TOTAL_FBCONFIG_PROPS]; 2709 int numAttribs = __GLX_TOTAL_FBCONFIG_PROPS; 2710 unsigned int screen = req->screen; 2711 int numFBConfigs, i, p; 2712 __GLXscreenInfo *pGlxScreen; 2713 2714 if (screen >= screenInfo.numScreens) { 2715 /* The client library must send a valid screen number. */ 2716 client->errorValue = screen; 2717 return BadValue; 2718 } 2719 2720 pGlxScreen = &__glXActiveScreens[screen]; 2721 numFBConfigs = __glXNumFBConfigs; 2722 2723 reply.numFBConfigs = numFBConfigs; 2724 reply.numAttribs = numAttribs; 2725 reply.length = (numFBConfigs * 2 * numAttribs * __GLX_SIZE_CARD32) >> 2; 2726 reply.type = X_Reply; 2727 reply.sequenceNumber = client->sequence; 2728 2729 if (client->swapped) { 2730 __GLX_DECLARE_SWAP_VARIABLES; 2731 __GLX_SWAP_SHORT(&reply.sequenceNumber); 2732 __GLX_SWAP_INT(&reply.length); 2733 __GLX_SWAP_INT(&reply.numFBConfigs); 2734 __GLX_SWAP_INT(&reply.numAttribs); 2735 } 2736 WriteToClient(client, sz_xGLXGetFBConfigsReply, (char *)&reply); 2737 2738 for (i=0; i < numFBConfigs; i++) { 2739 int associatedVisualId = 0; 2740 int drawableTypeIndex; 2741 pFBConfig = __glXFBConfigs[ i * (screenInfo.numScreens+1) ]; 2742 2743 p = 0; 2744 /* core attributes */ 2745 buf[p++] = GLX_FBCONFIG_ID; 2746 buf[p++] = pFBConfig->id; 2747 buf[p++] = GLX_BUFFER_SIZE; 2748 buf[p++] = pFBConfig->indexBits; 2749 buf[p++] = GLX_LEVEL; 2750 buf[p++] = pFBConfig->level; 2751 buf[p++] = GLX_DOUBLEBUFFER; 2752 buf[p++] = pFBConfig->doubleBufferMode; 2753 buf[p++] = GLX_STEREO; 2754 buf[p++] = pFBConfig->stereoMode; 2755 buf[p++] = GLX_AUX_BUFFERS; 2756 buf[p++] = pFBConfig->maxAuxBuffers; 2757 buf[p++] = GLX_RED_SIZE; 2758 buf[p++] = pFBConfig->redBits; 2759 buf[p++] = GLX_GREEN_SIZE; 2760 buf[p++] = pFBConfig->greenBits; 2761 buf[p++] = GLX_BLUE_SIZE; 2762 buf[p++] = pFBConfig->blueBits; 2763 buf[p++] = GLX_ALPHA_SIZE; 2764 buf[p++] = pFBConfig->alphaBits; 2765 buf[p++] = GLX_DEPTH_SIZE; 2766 buf[p++] = pFBConfig->depthBits; 2767 buf[p++] = GLX_STENCIL_SIZE; 2768 buf[p++] = pFBConfig->stencilBits; 2769 buf[p++] = GLX_ACCUM_RED_SIZE; 2770 buf[p++] = pFBConfig->accumRedBits; 2771 buf[p++] = GLX_ACCUM_GREEN_SIZE; 2772 buf[p++] = pFBConfig->accumGreenBits; 2773 buf[p++] = GLX_ACCUM_BLUE_SIZE; 2774 buf[p++] = pFBConfig->accumBlueBits; 2775 buf[p++] = GLX_ACCUM_ALPHA_SIZE; 2776 buf[p++] = pFBConfig->accumAlphaBits; 2777 buf[p++] = GLX_RENDER_TYPE; 2778 buf[p++] = pFBConfig->renderType; 2779 buf[p++] = GLX_DRAWABLE_TYPE; 2780 drawableTypeIndex = p; 2781 buf[p++] = pFBConfig->drawableType; 2782 buf[p++] = GLX_X_VISUAL_TYPE; 2783 buf[p++] = pFBConfig->visualType; 2784 buf[p++] = GLX_CONFIG_CAVEAT; 2785 buf[p++] = pFBConfig->visualCaveat; 2786 buf[p++] = GLX_TRANSPARENT_TYPE; 2787 buf[p++] = pFBConfig->transparentType; 2788 buf[p++] = GLX_TRANSPARENT_RED_VALUE; 2789 buf[p++] = pFBConfig->transparentRed; 2790 buf[p++] = GLX_TRANSPARENT_GREEN_VALUE; 2791 buf[p++] = pFBConfig->transparentGreen; 2792 buf[p++] = GLX_TRANSPARENT_BLUE_VALUE; 2793 buf[p++] = pFBConfig->transparentBlue; 2794 buf[p++] = GLX_TRANSPARENT_ALPHA_VALUE; 2795 buf[p++] = pFBConfig->transparentAlpha; 2796 buf[p++] = GLX_TRANSPARENT_INDEX_VALUE; 2797 buf[p++] = pFBConfig->transparentIndex; 2798 buf[p++] = GLX_MAX_PBUFFER_WIDTH; 2799 buf[p++] = pFBConfig->maxPbufferWidth; 2800 buf[p++] = GLX_MAX_PBUFFER_HEIGHT; 2801 buf[p++] = pFBConfig->maxPbufferHeight; 2802 buf[p++] = GLX_MAX_PBUFFER_PIXELS; 2803 buf[p++] = pFBConfig->maxPbufferPixels; 2804 2805 /* 2806 * find the visual of the back-end server and match a visual 2807 * on the proxy. 2808 * do only once - if a visual is not yet associated. 2809 */ 2810 if (pFBConfig->associatedVisualId == (unsigned int)-1) { 2811 DMXScreenInfo *dmxScreen = &dmxScreens[screen]; 2812 __GLXFBConfig *be_pFBConfig = __glXFBConfigs[ i * (screenInfo.numScreens+1)+screen+1 ]; 2813 __GLXvisualConfig *pGlxVisual = NULL; 2814 int v; 2815 int found = 0; 2816 for (v=0; v<dmxScreen->numGlxVisuals; v++) { 2817 if (dmxScreen->glxVisuals[v].vid == be_pFBConfig->associatedVisualId) { 2818 pGlxVisual = &dmxScreen->glxVisuals[v]; 2819 break; 2820 } 2821 } 2822 2823 if (pGlxVisual) { 2824 for (v=0; v<pGlxScreen->numVisuals; v++) { 2825 if (glxVisualsMatch(&pGlxScreen->pGlxVisual[v], pGlxVisual)) { 2826 associatedVisualId = pGlxScreen->pGlxVisual[v].vid; 2827 found = 1; 2828 break; 2829 } 2830 } 2831 } 2832 2833 if (!found) { 2834 associatedVisualId = 0; 2835 pFBConfig->drawableType &= ~(GLX_WINDOW_BIT); 2836 buf[drawableTypeIndex] = pFBConfig->drawableType; 2837 } 2838#ifdef PANORAMIX 2839 else if (!noPanoramiXExtension) { 2840 /* convert the associated visualId to the panoramix one */ 2841 pFBConfig->associatedVisualId = 2842 PanoramiXTranslateVisualID(screen, v); 2843 } 2844#endif 2845 } 2846 else { 2847 associatedVisualId = pFBConfig->associatedVisualId; 2848 } 2849 2850 buf[p++] = GLX_VISUAL_ID; 2851 buf[p++] = associatedVisualId; 2852 2853 /* SGIS_multisample attributes */ 2854 buf[p++] = GLX_SAMPLES_SGIS; 2855 buf[p++] = pFBConfig->multiSampleSize; 2856 buf[p++] = GLX_SAMPLE_BUFFERS_SGIS; 2857 buf[p++] = pFBConfig->nMultiSampleBuffers; 2858 2859 /* SGIX_pbuffer specific attributes */ 2860 buf[p++] = GLX_OPTIMAL_PBUFFER_WIDTH_SGIX; 2861 buf[p++] = pFBConfig->optimalPbufferWidth; 2862 buf[p++] = GLX_OPTIMAL_PBUFFER_HEIGHT_SGIX; 2863 buf[p++] = pFBConfig->optimalPbufferHeight; 2864 2865 buf[p++] = GLX_VISUAL_SELECT_GROUP_SGIX; 2866 buf[p++] = pFBConfig->visualSelectGroup; 2867 2868 if (client->swapped) { 2869 __GLX_DECLARE_SWAP_VARIABLES; 2870 __GLX_DECLARE_SWAP_ARRAY_VARIABLES; 2871 __GLX_SWAP_INT_ARRAY((int *)buf, 2*numAttribs); 2872 } 2873 WriteToClient(client, 2*numAttribs * __GLX_SIZE_CARD32, (char *)buf); 2874 } 2875 return Success; 2876} 2877 2878int __glXGetFBConfigsSGIX(__GLXclientState *cl, GLbyte *pc) 2879{ 2880 xGLXGetFBConfigsSGIXReq *req = (xGLXGetFBConfigsSGIXReq *)pc; 2881 xGLXGetFBConfigsReq new_req; 2882 2883 new_req.reqType = req->reqType; 2884 new_req.glxCode = req->glxCode; 2885 new_req.length = req->length; 2886 new_req.screen = req->screen; 2887 2888 return( __glXGetFBConfigs( cl, (GLbyte *)&new_req ) ); 2889} 2890 2891 2892int __glXCreateWindow(__GLXclientState *cl, GLbyte *pc) 2893{ 2894 ClientPtr client = cl->client; 2895 xGLXCreateWindowReq *req = (xGLXCreateWindowReq *) pc; 2896 int screen = req->screen; 2897 GLXFBConfigID fbconfigId = req->fbconfig; 2898 XID windowId = req->window; 2899 XID glxwindowId = req->glxwindow; 2900 DrawablePtr pDraw; 2901 ScreenPtr pScreen; 2902 __glXWindow *pGlxWindow; 2903 __GLXFBConfig *pGlxFBConfig = NULL; 2904 VisualPtr pVisual; 2905 VisualID visId; 2906 int i, rc; 2907 pointer val; 2908 2909 /* 2910 ** Check if windowId is valid 2911 */ 2912 rc = dixLookupDrawable(&pDraw, windowId, client, M_DRAWABLE_WINDOW, 2913 DixAddAccess); 2914 if (rc != Success) 2915 return rc; 2916 2917 /* 2918 ** Check if screen of window matches screen of fbconfig. 2919 */ 2920 pScreen = pDraw->pScreen; 2921 if (screen != pScreen->myNum) { 2922 return BadMatch; 2923 } 2924 2925 /* 2926 ** Find the FBConfigRec for this fbconfigid. 2927 */ 2928 if (!(pGlxFBConfig = glxLookupFBConfig(fbconfigId))) { 2929 client->errorValue = fbconfigId; 2930 return __glXBadFBConfig; 2931 } 2932 visId = pGlxFBConfig->associatedVisualId; 2933 2934 /* 2935 ** Check if the fbconfig supports rendering to windows 2936 */ 2937 if( !(pGlxFBConfig->drawableType & GLX_WINDOW_BIT) ) { 2938 return BadMatch; 2939 } 2940 2941 if (visId != None) { 2942 /* 2943 ** Check if the visual ID is valid for this screen. 2944 */ 2945 pVisual = pScreen->visuals; 2946 for (i = 0; i < pScreen->numVisuals; i++, pVisual++) { 2947 if (pVisual->vid == visId) { 2948 break; 2949 } 2950 } 2951 if (i == pScreen->numVisuals) { 2952 client->errorValue = visId; 2953 return BadValue; 2954 } 2955 2956 /* 2957 ** Check if color buffer depth of fbconfig matches depth 2958 ** of window. 2959 */ 2960 if (pVisual->nplanes != pDraw->depth) { 2961 return BadMatch; 2962 } 2963 } else 2964 /* 2965 ** The window was created with no visual that corresponds 2966 ** to fbconfig 2967 */ 2968 return BadMatch; 2969 2970 /* 2971 ** Check if there is already a fbconfig associated with this window 2972 */ 2973 if (Success == dixLookupResourceByType(&val, 2974 glxwindowId, __glXWindowRes, 2975 NullClient, DixUnknownAccess)) { 2976 client->errorValue = glxwindowId; 2977 return BadAlloc; 2978 } 2979 2980 pGlxWindow = (__glXWindow *) malloc(sizeof(__glXWindow)); 2981 if (!pGlxWindow) { 2982 return BadAlloc; 2983 } 2984 2985 /* 2986 ** Register this GLX window as a resource 2987 */ 2988 if (!(AddResource(glxwindowId, __glXWindowRes, pGlxWindow))) { 2989 return BadAlloc; 2990 } 2991 2992 pGlxWindow->pDraw = pDraw; 2993 pGlxWindow->type = GLX_GLXWINDOW_TYPE; 2994 pGlxWindow->idExists = True; 2995 pGlxWindow->refcnt = 0; 2996 pGlxWindow->pGlxFBConfig = pGlxFBConfig; 2997 pGlxWindow->pScreen = pScreen; 2998 2999 return Success; 3000} 3001 3002int __glXDestroyWindow(__GLXclientState *cl, GLbyte *pc) 3003{ 3004 ClientPtr client = cl->client; 3005 xGLXDestroyWindowReq *req = (xGLXDestroyWindowReq *) pc; 3006 XID glxwindow = req->glxwindow; 3007 pointer val; 3008 3009 /* 3010 ** Check if it's a valid GLX window. 3011 */ 3012 if (Success != dixLookupResourceByType(&val, 3013 glxwindow, __glXWindowRes, 3014 NullClient, DixUnknownAccess)) { 3015 client->errorValue = glxwindow; 3016 return __glXBadDrawable; 3017 } 3018 /* 3019 ** The glx window destructor will check whether it's current before 3020 ** freeing anything. 3021 */ 3022 FreeResource(glxwindow, RT_NONE); 3023 3024 return Success; 3025} 3026 3027int __glXQueryContext(__GLXclientState *cl, GLbyte *pc) 3028{ 3029 ClientPtr client = cl->client; 3030 __GLXcontext *ctx; 3031 xGLXQueryContextReq *req; 3032 xGLXQueryContextReply reply; 3033 int nProps; 3034 int *sendBuf, *pSendBuf; 3035 int nReplyBytes; 3036 3037 req = (xGLXQueryContextReq *)pc; 3038 dixLookupResourceByType((pointer*) &ctx, req->context, __glXContextRes, 3039 NullClient, DixUnknownAccess); 3040 if (!ctx) { 3041 client->errorValue = req->context; 3042 return __glXBadContext; 3043 } 3044 3045 nProps = 3; 3046 3047 reply.length = nProps << 1; 3048 reply.type = X_Reply; 3049 reply.sequenceNumber = client->sequence; 3050 reply.n = nProps; 3051 3052 nReplyBytes = reply.length << 2; 3053 sendBuf = (int *)malloc(nReplyBytes); 3054 pSendBuf = sendBuf; 3055 *pSendBuf++ = GLX_FBCONFIG_ID; 3056 *pSendBuf++ = (int)(ctx->pFBConfig->id); 3057 *pSendBuf++ = GLX_RENDER_TYPE; 3058 *pSendBuf++ = (int)(ctx->pFBConfig->renderType); 3059 *pSendBuf++ = GLX_SCREEN; 3060 *pSendBuf++ = (int)(ctx->pScreen->myNum); 3061 3062 if (client->swapped) { 3063 __glXSwapQueryContextReply(client, &reply, sendBuf); 3064 } else { 3065 WriteToClient(client, sz_xGLXQueryContextReply, (char *)&reply); 3066 WriteToClient(client, nReplyBytes, (char *)sendBuf); 3067 } 3068 free((char *)sendBuf); 3069 3070 return Success; 3071} 3072 3073int __glXQueryContextInfoEXT(__GLXclientState *cl, GLbyte *pc) 3074{ 3075 ClientPtr client = cl->client; 3076 __GLXcontext *ctx; 3077 xGLXQueryContextInfoEXTReq *req; 3078 xGLXQueryContextInfoEXTReply reply; 3079 int nProps; 3080 int *sendBuf, *pSendBuf; 3081 int nReplyBytes; 3082 3083 req = (xGLXQueryContextInfoEXTReq *)pc; 3084 dixLookupResourceByType((pointer*) &ctx, 3085 req->context, __glXContextRes, 3086 client, DixReadAccess); 3087 3088 if (!ctx) { 3089 client->errorValue = req->context; 3090 return __glXBadContext; 3091 } 3092 3093 nProps = 4; 3094 3095 reply.length = nProps << 1; 3096 reply.type = X_Reply; 3097 reply.sequenceNumber = client->sequence; 3098 reply.n = nProps; 3099 3100 nReplyBytes = reply.length << 2; 3101 sendBuf = (int *)malloc(nReplyBytes); 3102 pSendBuf = sendBuf; 3103 *pSendBuf++ = GLX_SHARE_CONTEXT_EXT; 3104 *pSendBuf++ = (int)(ctx->share_id); 3105 *pSendBuf++ = GLX_VISUAL_ID_EXT; 3106 *pSendBuf++ = (int)(ctx->pVisual ? ctx->pVisual->vid : 0); 3107 *pSendBuf++ = GLX_SCREEN_EXT; 3108 *pSendBuf++ = (int)(ctx->pScreen->myNum); 3109 *pSendBuf++ = GLX_FBCONFIG_ID; 3110 *pSendBuf++ = (int)(ctx->pFBConfig ? ctx->pFBConfig->id : 0); 3111 3112 if (client->swapped) { 3113 __glXSwapQueryContextInfoEXTReply(client, &reply, sendBuf); 3114 } else { 3115 WriteToClient(client, sz_xGLXQueryContextInfoEXTReply, (char *)&reply); 3116 WriteToClient(client, nReplyBytes, (char *)sendBuf); 3117 } 3118 free((char *)sendBuf); 3119 3120 return Success; 3121} 3122 3123int __glXCreatePbuffer(__GLXclientState *cl, GLbyte *pc) 3124{ 3125 ClientPtr client = cl->client; 3126 xGLXCreatePbufferReq *req = (xGLXCreatePbufferReq *)pc; 3127 xGLXCreatePbufferReq *be_req; 3128 int screen = req->screen; 3129 GLXFBConfigID fbconfigId = req->fbconfig; 3130 GLXPbuffer pbuffer = req->pbuffer; 3131 __glXPbuffer *pGlxPbuffer; 3132 int numAttribs = req->numAttribs; 3133 int *attr; 3134 ScreenPtr pScreen; 3135 __GLXFBConfig *pGlxFBConfig; 3136 __GLXFBConfig *be_pGlxFBConfig; 3137 XID be_xid; 3138 Display *dpy; 3139 DMXScreenInfo *dmxScreen; 3140 int s; 3141 int from_screen, to_screen; 3142 3143 /* 3144 ** Look up screen and FBConfig. 3145 */ 3146 if (screen >= screenInfo.numScreens) { 3147 /* The client library must send a valid screen number. */ 3148 client->errorValue = screen; 3149 return BadValue; 3150 } 3151 pScreen = screenInfo.screens[screen]; 3152 3153 /* 3154 ** Find the FBConfigRec for this fbconfigid. 3155 */ 3156 if (!(pGlxFBConfig = glxLookupFBConfig(fbconfigId))) { 3157 client->errorValue = fbconfigId; 3158 return __glXBadFBConfig; 3159 } 3160 3161 /* 3162 ** Create the GLX part of the Pbuffer. 3163 */ 3164 pGlxPbuffer = (__glXPbuffer *) malloc(sizeof(__glXPbuffer)); 3165 if (!pGlxPbuffer) { 3166 return BadAlloc; 3167 } 3168 3169 pGlxPbuffer->be_xids = (XID *) malloc( sizeof(XID) * screenInfo.numScreens ); 3170 if (!pGlxPbuffer->be_xids) { 3171 free(pGlxPbuffer); 3172 return BadAlloc; 3173 } 3174 3175 /* 3176 * Allocate an XID on the back-end server(s) and send him the request 3177 */ 3178 from_screen = to_screen = screen; 3179#ifdef PANORAMIX 3180 if (!noPanoramiXExtension) { 3181 from_screen = 0; 3182 to_screen = screenInfo.numScreens - 1; 3183 } 3184#endif 3185 3186 for (s=from_screen; s<=to_screen; s++) { 3187 dpy = GetBackEndDisplay(cl,s); 3188 be_xid = XAllocID(dpy); 3189 dmxScreen = &dmxScreens[s]; 3190 be_pGlxFBConfig = glxLookupBackEndFBConfig( pGlxFBConfig->id, s ); 3191 3192 attr = (int *)( req+1 ); 3193 3194 LockDisplay(dpy); 3195 GetReqExtra(GLXCreatePbuffer, 2 * numAttribs * __GLX_SIZE_CARD32, be_req); 3196 be_req->reqType = dmxScreen->glxMajorOpcode; 3197 be_req->glxCode = X_GLXCreatePbuffer; 3198 be_req->screen = be_pGlxFBConfig->screen; 3199 be_req->fbconfig = be_pGlxFBConfig->id; 3200 be_req->pbuffer = be_xid; 3201 be_req->numAttribs = numAttribs; 3202 3203 /* Send attributes */ 3204 if ( attr != NULL ) { 3205 CARD32 *pc = (CARD32 *)(be_req + 1); 3206 3207 while (numAttribs-- > 0) { 3208 *pc++ = *attr++; /* token */ 3209 *pc++ = *attr++; /* value */ 3210 } 3211 } 3212 3213 UnlockDisplay(dpy); 3214 SyncHandle(); 3215 3216 pGlxPbuffer->be_xids[s] = be_xid; 3217 } 3218 3219 3220 pGlxPbuffer->idExists = True; 3221 pGlxPbuffer->refcnt = 0; 3222 pGlxPbuffer->pFBConfig = pGlxFBConfig; 3223 pGlxPbuffer->pScreen = pScreen; 3224 3225 /* 3226 ** Register the resource. 3227 */ 3228 if (!(AddResource(pbuffer, __glXPbufferRes, pGlxPbuffer))) { 3229 return BadAlloc; 3230 } 3231 3232 return Success; 3233 3234} 3235 3236int __glXDestroyPbuffer(__GLXclientState *cl, GLbyte *pc) 3237{ 3238 ClientPtr client = cl->client; 3239 xGLXDestroyPbufferReq *req = (xGLXDestroyPbufferReq *) pc; 3240 xGLXDestroyPbufferReq *be_req; 3241 GLXPbuffer pbuffer = req->pbuffer; 3242 Display *dpy; 3243 int screen; 3244 DMXScreenInfo *dmxScreen; 3245 __glXPbuffer *pGlxPbuffer; 3246 int s; 3247 int from_screen, to_screen; 3248 3249 /* 3250 ** Check if it's a valid Pbuffer 3251 */ 3252 dixLookupResourceByType((pointer*) &pGlxPbuffer, pbuffer, 3253 __glXPbufferRes, NullClient, DixUnknownAccess); 3254 if (!pGlxPbuffer) { 3255 client->errorValue = pbuffer; 3256 return __glXBadPbuffer; 3257 } 3258 3259 screen = pGlxPbuffer->pScreen->myNum; 3260 3261 from_screen = to_screen = screen; 3262#ifdef PANORAMIX 3263 if (!noPanoramiXExtension) { 3264 from_screen = 0; 3265 to_screen = screenInfo.numScreens - 1; 3266 } 3267#endif 3268 3269 for (s=from_screen; s<=to_screen; s++) { 3270 dpy = GetBackEndDisplay(cl,s); 3271 dmxScreen = &dmxScreens[s]; 3272 3273 /* send the destroy request to the back-end server */ 3274 LockDisplay(dpy); 3275 GetReq(GLXDestroyPbuffer, be_req); 3276 be_req->reqType = dmxScreen->glxMajorOpcode; 3277 be_req->glxCode = X_GLXDestroyPbuffer; 3278 be_req->pbuffer = pGlxPbuffer->be_xids[s]; 3279 UnlockDisplay(dpy); 3280 SyncHandle(); 3281 } 3282 3283 FreeResource(pbuffer, RT_NONE); 3284 3285 return Success; 3286} 3287 3288int __glXGetDrawableAttributes(__GLXclientState *cl, GLbyte *pc) 3289{ 3290 xGLXGetDrawableAttributesReq *req = (xGLXGetDrawableAttributesReq *)pc; 3291 xGLXGetDrawableAttributesReq *be_req; 3292 xGLXGetDrawableAttributesReply reply; 3293 ClientPtr client = cl->client; 3294 GLXDrawable drawId = req->drawable; 3295 GLXDrawable be_drawable = 0; 3296 DrawablePtr pDraw = NULL; 3297 Display *dpy; 3298 int screen, rc; 3299 DMXScreenInfo *dmxScreen; 3300 CARD32 *attribs = NULL; 3301 int attribs_size = 0; 3302#ifdef PANORAMIX 3303 PanoramiXRes *pXinDraw = NULL; 3304#endif 3305 3306 if (drawId != None) { 3307 rc = dixLookupDrawable(&pDraw, drawId, client, 0, DixGetAttrAccess); 3308 if (rc == Success && pDraw->type == DRAWABLE_WINDOW) { 3309 WindowPtr pWin = (WindowPtr)pDraw; 3310 be_drawable = 0; 3311 screen = pWin->drawable.pScreen->myNum; 3312 } else { 3313 /* 3314 ** Drawable is not a Window , GLXWindow or a GLXPixmap. 3315 */ 3316 client->errorValue = drawId; 3317 return __glXBadDrawable; 3318 } 3319 3320 if (!pDraw) { 3321 __GLXpixmap *pGlxPixmap; 3322 dixLookupResourceByType((pointer*) &pGlxPixmap, 3323 drawId, __glXPixmapRes, 3324 NullClient, DixUnknownAccess); 3325 if (pGlxPixmap) { 3326 pDraw = pGlxPixmap->pDraw; 3327 screen = pGlxPixmap->pScreen->myNum; 3328 be_drawable = pGlxPixmap->be_xids[screen]; 3329 } 3330 } 3331 3332 if (!pDraw) { 3333 __glXWindow *pGlxWindow; 3334 dixLookupResourceByType((pointer*) &pGlxWindow, 3335 drawId, __glXWindowRes, 3336 NullClient, DixUnknownAccess); 3337 if (pGlxWindow) { 3338 pDraw = pGlxWindow->pDraw; 3339 screen = pGlxWindow->pScreen->myNum; 3340 be_drawable = 0; 3341 } 3342 } 3343 3344 if (!pDraw) { 3345 __glXPbuffer *pGlxPbuffer; 3346 dixLookupResourceByType((pointer*) &pGlxPbuffer, 3347 drawId, __glXPbufferRes, 3348 NullClient, DixUnknownAccess); 3349 if (pGlxPbuffer) { 3350 pDraw = (DrawablePtr)pGlxPbuffer; 3351 screen = pGlxPbuffer->pScreen->myNum; 3352 be_drawable = pGlxPbuffer->be_xids[screen]; 3353 } 3354 } 3355 } 3356 3357 if (!pDraw) { 3358 /* 3359 ** Drawable is not a Window , GLXWindow or a GLXPixmap. 3360 */ 3361 client->errorValue = drawId; 3362 return __glXBadDrawable; 3363 } 3364 3365 /* if the drawable is a window or GLXWindow - 3366 * we need to find the base id on the back-end server 3367 */ 3368 if (!be_drawable) { 3369 WindowPtr pWin = (WindowPtr)pDraw; 3370 3371#ifdef PANORAMIX 3372 if (!noPanoramiXExtension) { 3373 if (Success != dixLookupResourceByClass((pointer*) &pXinDraw, 3374 pDraw->id, XRC_DRAWABLE, 3375 client, DixReadAccess)) { 3376 client->errorValue = drawId; 3377 return __glXBadDrawable; 3378 } 3379 3380 dixLookupWindow(&pWin, pXinDraw->info[screen].id, client, 3381 DixReadAccess); 3382 } 3383#endif 3384 3385 if (pWin) { 3386 be_drawable = (unsigned int)(DMX_GET_WINDOW_PRIV(pWin))->window; 3387 if (!be_drawable) { 3388 /* it might be that the window did not created yet on the */ 3389 /* back-end server (lazy window creation option), force */ 3390 /* creation of the window */ 3391 dmxCreateAndRealizeWindow( pWin, TRUE ); 3392 be_drawable = (unsigned int)(DMX_GET_WINDOW_PRIV(pWin))->window; 3393 } 3394 } 3395 else { 3396 client->errorValue = drawId; 3397 return __glXBadDrawable; 3398 } 3399 } 3400 3401 3402 /* send the request to the back-end server */ 3403 dpy = GetBackEndDisplay(cl,screen); 3404 dmxScreen = &dmxScreens[screen]; 3405 3406 /* make sure drawable exists on back-end */ 3407 dmxSync( dmxScreen, 1 ); 3408 3409 LockDisplay(dpy); 3410 GetReq(GLXGetDrawableAttributes, be_req); 3411 be_req->reqType = dmxScreen->glxMajorOpcode; 3412 be_req->glxCode = X_GLXGetDrawableAttributes; 3413 be_req->drawable = be_drawable; 3414 be_req->length = req->length; 3415 if (!_XReply(dpy, (xReply *) &reply, 0, False)) { 3416 UnlockDisplay(dpy); 3417 SyncHandle(); 3418 return( BE_TO_CLIENT_ERROR(dmxLastErrorEvent.error_code) ); 3419 } 3420 3421 if (reply.numAttribs) { 3422 attribs_size = 2 * reply.numAttribs * __GLX_SIZE_CARD32; 3423 attribs = (CARD32 *) malloc(attribs_size); 3424 if (attribs == NULL) { 3425 UnlockDisplay(dpy); 3426 SyncHandle(); 3427 return BadAlloc; 3428 } 3429 3430 _XRead(dpy, (char *) attribs, attribs_size); 3431 } 3432 3433 UnlockDisplay(dpy); 3434 SyncHandle(); 3435 3436 3437 /* send the reply back to the client */ 3438 reply.sequenceNumber = client->sequence; 3439 if (client->swapped) { 3440 __glXSwapGetDrawableAttributesReply(client, &reply, (int *)attribs); 3441 } 3442 else { 3443 WriteToClient(client, sz_xGLXGetDrawableAttributesReply, (char *)&reply); 3444 WriteToClient(client, attribs_size, (char *)attribs); 3445 } 3446 3447 free(attribs); 3448 3449 return Success; 3450} 3451 3452int __glXChangeDrawableAttributes(__GLXclientState *cl, GLbyte *pc) 3453{ 3454 xGLXChangeDrawableAttributesReq *req = (xGLXChangeDrawableAttributesReq *)pc; 3455 xGLXChangeDrawableAttributesReq *be_req; 3456 ClientPtr client = cl->client; 3457 GLXDrawable drawId = req->drawable; 3458 GLXDrawable be_drawable = 0; 3459 DrawablePtr pDraw = NULL; 3460 Display *dpy; 3461 int screen, rc; 3462 DMXScreenInfo *dmxScreen; 3463 3464 if (drawId != None) { 3465 rc = dixLookupDrawable(&pDraw, drawId, client, 0, DixSetAttrAccess); 3466 if (rc == Success && pDraw->type == DRAWABLE_WINDOW) { 3467 be_drawable = 0; 3468 screen = pDraw->pScreen->myNum; 3469 } else { 3470 /* 3471 ** Drawable is not a Window , GLXWindow or a GLXPixmap. 3472 */ 3473 client->errorValue = drawId; 3474 return __glXBadDrawable; 3475 } 3476 3477 if (!pDraw) { 3478 __GLXpixmap *pGlxPixmap; 3479 dixLookupResourceByType((pointer*) &pGlxPixmap, 3480 drawId, __glXPixmapRes, 3481 NullClient, DixUnknownAccess); 3482 if (pGlxPixmap) { 3483 pDraw = pGlxPixmap->pDraw; 3484 screen = pGlxPixmap->pScreen->myNum; 3485 be_drawable = pGlxPixmap->be_xids[screen]; 3486 } 3487 } 3488 3489 if (!pDraw) { 3490 __glXWindow *pGlxWindow; 3491 dixLookupResourceByType((pointer*) &pGlxWindow, 3492 drawId, __glXWindowRes, 3493 NullClient, DixUnknownAccess); 3494 if (pGlxWindow) { 3495 pDraw = pGlxWindow->pDraw; 3496 screen = pGlxWindow->pScreen->myNum; 3497 be_drawable = 0; 3498 } 3499 } 3500 3501 if (!pDraw) { 3502 __glXPbuffer *pGlxPbuffer; 3503 dixLookupResourceByType((pointer*) &pGlxPbuffer, 3504 drawId, __glXPbufferRes, 3505 NullClient, DixUnknownAccess); 3506 if (pGlxPbuffer) { 3507 pDraw = (DrawablePtr)pGlxPbuffer; 3508 screen = pGlxPbuffer->pScreen->myNum; 3509 be_drawable = pGlxPbuffer->be_xids[screen]; 3510 } 3511 } 3512 } 3513 3514 if (!pDraw) { 3515 /* 3516 ** Drawable is not a Window , GLXWindow or a GLXPixmap. 3517 */ 3518 client->errorValue = drawId; 3519 return __glXBadDrawable; 3520 } 3521 3522 /* if the drawable is a window or GLXWindow - 3523 * we need to find the base id on the back-end server 3524 */ 3525 if (!be_drawable) { 3526 WindowPtr pWin = (WindowPtr)pDraw; 3527 3528#ifdef PANORAMIX 3529 if (!noPanoramiXExtension) { 3530 PanoramiXRes *pXinDraw; 3531 if (Success != dixLookupResourceByClass((pointer*) &pXinDraw, 3532 pDraw->id, XRC_DRAWABLE, 3533 client, DixReadAccess)) { 3534 client->errorValue = drawId; 3535 return __glXBadDrawable; 3536 } 3537 3538 dixLookupWindow(&pWin, pXinDraw->info[screen].id, client, 3539 DixReadAccess); 3540 } 3541#endif 3542 3543 if (pWin) { 3544 be_drawable = (unsigned int)(DMX_GET_WINDOW_PRIV(pWin))->window; 3545 if (!be_drawable) { 3546 /* it might be that the window did not created yet on the */ 3547 /* back-end server (lazy window creation option), force */ 3548 /* creation of the window */ 3549 dmxCreateAndRealizeWindow( pWin, TRUE ); 3550 be_drawable = (unsigned int)(DMX_GET_WINDOW_PRIV(pWin))->window; 3551 } 3552 } 3553 else { 3554 client->errorValue = drawId; 3555 return __glXBadDrawable; 3556 } 3557 } 3558 3559 3560 /* send the request to the back-end server */ 3561 dpy = GetBackEndDisplay(cl,screen); 3562 dmxScreen = &dmxScreens[screen]; 3563 3564 /* make sure drawable exists on back-end */ 3565 dmxSync( dmxScreen, 1 ); 3566 3567 LockDisplay(dpy); 3568 GetReqExtra(GLXChangeDrawableAttributes, 3569 2 * req->numAttribs * __GLX_SIZE_CARD32, be_req); 3570 be_req->reqType = dmxScreen->glxMajorOpcode; 3571 be_req->glxCode = X_GLXChangeDrawableAttributes; 3572 be_req->drawable = be_drawable; 3573 be_req->numAttribs = req->numAttribs; 3574 be_req->length = req->length; 3575 3576 UnlockDisplay(dpy); 3577 SyncHandle(); 3578 3579 return Success; 3580} 3581 3582int __glXSendLargeCommand(__GLXclientState *cl, GLXContextTag contextTag) 3583{ 3584 ClientPtr client = cl->client; 3585 xGLXRenderLargeReq *req; 3586 GLint maxSize, amount; 3587 GLint totalRequests, requestNumber; 3588 GLint dataLen; 3589 GLbyte *data; 3590 __GLXcontext *glxc; 3591 int s; 3592 int from_screen, to_screen; 3593 3594 maxSize = cl->largeCmdMaxReqDataSize - (GLint)sizeof(xGLXRenderLargeReq); 3595 dataLen = cl->largeCmdBytesTotal; 3596 totalRequests = (dataLen / maxSize); 3597 if (dataLen % maxSize) totalRequests++; 3598 3599 glxc = __glXLookupContextByTag(cl, contextTag); 3600 if (!glxc) { 3601 client->errorValue = contextTag; 3602 return __glXBadContext; 3603 } 3604 from_screen = to_screen = glxc->pScreen->myNum; 3605 3606#ifdef PANORAMIX 3607 if (!noPanoramiXExtension) { 3608 from_screen = 0; 3609 to_screen = screenInfo.numScreens - 1; 3610 } 3611#endif 3612 3613 /* 3614 ** Send enough requests until the whole array is sent. 3615 */ 3616 requestNumber = 1; 3617 data = cl->largeCmdBuf; 3618 while (dataLen > 0) { 3619 amount = dataLen; 3620 if (amount > maxSize) { 3621 amount = maxSize; 3622 } 3623 3624 for (s=from_screen; s<=to_screen; s++) { 3625 3626 Display *dpy = GetBackEndDisplay(cl,s); 3627 DMXScreenInfo *dmxScreen = &dmxScreens[s]; 3628 3629 LockDisplay(dpy); 3630 GetReq(GLXRenderLarge,req); 3631 req->reqType = dmxScreen->glxMajorOpcode; 3632 req->glxCode = X_GLXRenderLarge; 3633 req->contextTag = GetCurrentBackEndTag(cl,contextTag,s); 3634 req->length += (amount + 3) >> 2; 3635 req->requestNumber = requestNumber++; 3636 req->requestTotal = totalRequests; 3637 req->dataBytes = amount; 3638 Data(dpy, ((const char*)data), amount); 3639 dataLen -= amount; 3640 data = ((GLbyte *) data) + amount; 3641 UnlockDisplay(dpy); 3642 SyncHandle(); 3643 } 3644 } 3645 3646 return Success; 3647} 3648