render.c revision 4e185dc0
1/* 2 * 3 * Copyright © 2000 SuSE, Inc. 4 * 5 * Permission to use, copy, modify, distribute, and sell this software and its 6 * documentation for any purpose is hereby granted without fee, provided that 7 * the above copyright notice appear in all copies and that both that 8 * copyright notice and this permission notice appear in supporting 9 * documentation, and that the name of SuSE not be used in advertising or 10 * publicity pertaining to distribution of the software without specific, 11 * written prior permission. SuSE makes no representations about the 12 * suitability of this software for any purpose. It is provided "as is" 13 * without express or implied warranty. 14 * 15 * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE 17 * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 18 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION 19 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN 20 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 21 * 22 * Author: Keith Packard, SuSE, Inc. 23 */ 24 25#ifdef HAVE_DIX_CONFIG_H 26#include <dix-config.h> 27#endif 28 29#include <X11/X.h> 30#include <X11/Xproto.h> 31#include "misc.h" 32#include "os.h" 33#include "dixstruct.h" 34#include "resource.h" 35#include "scrnintstr.h" 36#include "windowstr.h" 37#include "pixmapstr.h" 38#include "colormapst.h" 39#include "extnsionst.h" 40#include "extinit.h" 41#include "servermd.h" 42#include <X11/extensions/render.h> 43#include <X11/extensions/renderproto.h> 44#include "picturestr.h" 45#include "glyphstr.h" 46#include <X11/Xfuncproto.h> 47#include "cursorstr.h" 48#include "xace.h" 49#include "protocol-versions.h" 50 51#ifdef PANORAMIX 52#include "panoramiX.h" 53#include "panoramiXsrv.h" 54#endif 55 56#include <stdint.h> 57 58static int ProcRenderQueryVersion(ClientPtr pClient); 59static int ProcRenderQueryPictFormats(ClientPtr pClient); 60static int ProcRenderQueryPictIndexValues(ClientPtr pClient); 61static int ProcRenderQueryDithers(ClientPtr pClient); 62static int ProcRenderCreatePicture(ClientPtr pClient); 63static int ProcRenderChangePicture(ClientPtr pClient); 64static int ProcRenderSetPictureClipRectangles(ClientPtr pClient); 65static int ProcRenderFreePicture(ClientPtr pClient); 66static int ProcRenderComposite(ClientPtr pClient); 67static int ProcRenderScale(ClientPtr pClient); 68static int ProcRenderTrapezoids(ClientPtr pClient); 69static int ProcRenderTriangles(ClientPtr pClient); 70static int ProcRenderTriStrip(ClientPtr pClient); 71static int ProcRenderTriFan(ClientPtr pClient); 72static int ProcRenderColorTrapezoids(ClientPtr pClient); 73static int ProcRenderColorTriangles(ClientPtr pClient); 74static int ProcRenderTransform(ClientPtr pClient); 75static int ProcRenderCreateGlyphSet(ClientPtr pClient); 76static int ProcRenderReferenceGlyphSet(ClientPtr pClient); 77static int ProcRenderFreeGlyphSet(ClientPtr pClient); 78static int ProcRenderAddGlyphs(ClientPtr pClient); 79static int ProcRenderAddGlyphsFromPicture(ClientPtr pClient); 80static int ProcRenderFreeGlyphs(ClientPtr pClient); 81static int ProcRenderCompositeGlyphs(ClientPtr pClient); 82static int ProcRenderFillRectangles(ClientPtr pClient); 83static int ProcRenderCreateCursor(ClientPtr pClient); 84static int ProcRenderSetPictureTransform(ClientPtr pClient); 85static int ProcRenderQueryFilters(ClientPtr pClient); 86static int ProcRenderSetPictureFilter(ClientPtr pClient); 87static int ProcRenderCreateAnimCursor(ClientPtr pClient); 88static int ProcRenderAddTraps(ClientPtr pClient); 89static int ProcRenderCreateSolidFill(ClientPtr pClient); 90static int ProcRenderCreateLinearGradient(ClientPtr pClient); 91static int ProcRenderCreateRadialGradient(ClientPtr pClient); 92static int ProcRenderCreateConicalGradient(ClientPtr pClient); 93 94static int ProcRenderDispatch(ClientPtr pClient); 95 96static int SProcRenderQueryVersion(ClientPtr pClient); 97static int SProcRenderQueryPictFormats(ClientPtr pClient); 98static int SProcRenderQueryPictIndexValues(ClientPtr pClient); 99static int SProcRenderQueryDithers(ClientPtr pClient); 100static int SProcRenderCreatePicture(ClientPtr pClient); 101static int SProcRenderChangePicture(ClientPtr pClient); 102static int SProcRenderSetPictureClipRectangles(ClientPtr pClient); 103static int SProcRenderFreePicture(ClientPtr pClient); 104static int SProcRenderComposite(ClientPtr pClient); 105static int SProcRenderScale(ClientPtr pClient); 106static int SProcRenderTrapezoids(ClientPtr pClient); 107static int SProcRenderTriangles(ClientPtr pClient); 108static int SProcRenderTriStrip(ClientPtr pClient); 109static int SProcRenderTriFan(ClientPtr pClient); 110static int SProcRenderColorTrapezoids(ClientPtr pClient); 111static int SProcRenderColorTriangles(ClientPtr pClient); 112static int SProcRenderTransform(ClientPtr pClient); 113static int SProcRenderCreateGlyphSet(ClientPtr pClient); 114static int SProcRenderReferenceGlyphSet(ClientPtr pClient); 115static int SProcRenderFreeGlyphSet(ClientPtr pClient); 116static int SProcRenderAddGlyphs(ClientPtr pClient); 117static int SProcRenderAddGlyphsFromPicture(ClientPtr pClient); 118static int SProcRenderFreeGlyphs(ClientPtr pClient); 119static int SProcRenderCompositeGlyphs(ClientPtr pClient); 120static int SProcRenderFillRectangles(ClientPtr pClient); 121static int SProcRenderCreateCursor(ClientPtr pClient); 122static int SProcRenderSetPictureTransform(ClientPtr pClient); 123static int SProcRenderQueryFilters(ClientPtr pClient); 124static int SProcRenderSetPictureFilter(ClientPtr pClient); 125static int SProcRenderCreateAnimCursor(ClientPtr pClient); 126static int SProcRenderAddTraps(ClientPtr pClient); 127static int SProcRenderCreateSolidFill(ClientPtr pClient); 128static int SProcRenderCreateLinearGradient(ClientPtr pClient); 129static int SProcRenderCreateRadialGradient(ClientPtr pClient); 130static int SProcRenderCreateConicalGradient(ClientPtr pClient); 131 132static int SProcRenderDispatch(ClientPtr pClient); 133 134int (*ProcRenderVector[RenderNumberRequests]) (ClientPtr) = { 135ProcRenderQueryVersion, 136 ProcRenderQueryPictFormats, 137 ProcRenderQueryPictIndexValues, 138 ProcRenderQueryDithers, 139 ProcRenderCreatePicture, 140 ProcRenderChangePicture, 141 ProcRenderSetPictureClipRectangles, 142 ProcRenderFreePicture, 143 ProcRenderComposite, 144 ProcRenderScale, 145 ProcRenderTrapezoids, 146 ProcRenderTriangles, 147 ProcRenderTriStrip, 148 ProcRenderTriFan, 149 ProcRenderColorTrapezoids, 150 ProcRenderColorTriangles, 151 ProcRenderTransform, 152 ProcRenderCreateGlyphSet, 153 ProcRenderReferenceGlyphSet, 154 ProcRenderFreeGlyphSet, 155 ProcRenderAddGlyphs, 156 ProcRenderAddGlyphsFromPicture, 157 ProcRenderFreeGlyphs, 158 ProcRenderCompositeGlyphs, 159 ProcRenderCompositeGlyphs, 160 ProcRenderCompositeGlyphs, 161 ProcRenderFillRectangles, 162 ProcRenderCreateCursor, 163 ProcRenderSetPictureTransform, 164 ProcRenderQueryFilters, 165 ProcRenderSetPictureFilter, 166 ProcRenderCreateAnimCursor, 167 ProcRenderAddTraps, 168 ProcRenderCreateSolidFill, 169 ProcRenderCreateLinearGradient, 170 ProcRenderCreateRadialGradient, ProcRenderCreateConicalGradient}; 171 172int (*SProcRenderVector[RenderNumberRequests]) (ClientPtr) = { 173SProcRenderQueryVersion, 174 SProcRenderQueryPictFormats, 175 SProcRenderQueryPictIndexValues, 176 SProcRenderQueryDithers, 177 SProcRenderCreatePicture, 178 SProcRenderChangePicture, 179 SProcRenderSetPictureClipRectangles, 180 SProcRenderFreePicture, 181 SProcRenderComposite, 182 SProcRenderScale, 183 SProcRenderTrapezoids, 184 SProcRenderTriangles, 185 SProcRenderTriStrip, 186 SProcRenderTriFan, 187 SProcRenderColorTrapezoids, 188 SProcRenderColorTriangles, 189 SProcRenderTransform, 190 SProcRenderCreateGlyphSet, 191 SProcRenderReferenceGlyphSet, 192 SProcRenderFreeGlyphSet, 193 SProcRenderAddGlyphs, 194 SProcRenderAddGlyphsFromPicture, 195 SProcRenderFreeGlyphs, 196 SProcRenderCompositeGlyphs, 197 SProcRenderCompositeGlyphs, 198 SProcRenderCompositeGlyphs, 199 SProcRenderFillRectangles, 200 SProcRenderCreateCursor, 201 SProcRenderSetPictureTransform, 202 SProcRenderQueryFilters, 203 SProcRenderSetPictureFilter, 204 SProcRenderCreateAnimCursor, 205 SProcRenderAddTraps, 206 SProcRenderCreateSolidFill, 207 SProcRenderCreateLinearGradient, 208 SProcRenderCreateRadialGradient, SProcRenderCreateConicalGradient}; 209 210int RenderErrBase; 211static DevPrivateKeyRec RenderClientPrivateKeyRec; 212 213#define RenderClientPrivateKey (&RenderClientPrivateKeyRec ) 214 215typedef struct _RenderClient { 216 int major_version; 217 int minor_version; 218} RenderClientRec, *RenderClientPtr; 219 220#define GetRenderClient(pClient) ((RenderClientPtr)dixLookupPrivate(&(pClient)->devPrivates, RenderClientPrivateKey)) 221 222#ifdef PANORAMIX 223RESTYPE XRT_PICTURE; 224#endif 225 226void 227RenderExtensionInit(void) 228{ 229 ExtensionEntry *extEntry; 230 231 if (!PictureType) 232 return; 233 if (!PictureFinishInit()) 234 return; 235 if (!dixRegisterPrivateKey 236 (&RenderClientPrivateKeyRec, PRIVATE_CLIENT, sizeof(RenderClientRec))) 237 return; 238 239 extEntry = AddExtension(RENDER_NAME, 0, RenderNumberErrors, 240 ProcRenderDispatch, SProcRenderDispatch, 241 NULL, StandardMinorOpcode); 242 if (!extEntry) 243 return; 244 RenderErrBase = extEntry->errorBase; 245#ifdef PANORAMIX 246 if (XRT_PICTURE) 247 SetResourceTypeErrorValue(XRT_PICTURE, RenderErrBase + BadPicture); 248#endif 249 SetResourceTypeErrorValue(PictureType, RenderErrBase + BadPicture); 250 SetResourceTypeErrorValue(PictFormatType, RenderErrBase + BadPictFormat); 251 SetResourceTypeErrorValue(GlyphSetType, RenderErrBase + BadGlyphSet); 252} 253 254static int 255ProcRenderQueryVersion(ClientPtr client) 256{ 257 RenderClientPtr pRenderClient = GetRenderClient(client); 258 xRenderQueryVersionReply rep = { 259 .type = X_Reply, 260 .sequenceNumber = client->sequence, 261 .length = 0 262 }; 263 264 REQUEST(xRenderQueryVersionReq); 265 266 REQUEST_SIZE_MATCH(xRenderQueryVersionReq); 267 268 pRenderClient->major_version = stuff->majorVersion; 269 pRenderClient->minor_version = stuff->minorVersion; 270 271 if ((stuff->majorVersion * 1000 + stuff->minorVersion) < 272 (SERVER_RENDER_MAJOR_VERSION * 1000 + SERVER_RENDER_MINOR_VERSION)) { 273 rep.majorVersion = stuff->majorVersion; 274 rep.minorVersion = stuff->minorVersion; 275 } 276 else { 277 rep.majorVersion = SERVER_RENDER_MAJOR_VERSION; 278 rep.minorVersion = SERVER_RENDER_MINOR_VERSION; 279 } 280 281 if (client->swapped) { 282 swaps(&rep.sequenceNumber); 283 swapl(&rep.length); 284 swapl(&rep.majorVersion); 285 swapl(&rep.minorVersion); 286 } 287 WriteToClient(client, sizeof(xRenderQueryVersionReply), &rep); 288 return Success; 289} 290 291static VisualPtr 292findVisual(ScreenPtr pScreen, VisualID vid) 293{ 294 VisualPtr pVisual; 295 int v; 296 297 for (v = 0; v < pScreen->numVisuals; v++) { 298 pVisual = pScreen->visuals + v; 299 if (pVisual->vid == vid) 300 return pVisual; 301 } 302 return 0; 303} 304 305static int 306ProcRenderQueryPictFormats(ClientPtr client) 307{ 308 RenderClientPtr pRenderClient = GetRenderClient(client); 309 xRenderQueryPictFormatsReply *reply; 310 xPictScreen *pictScreen; 311 xPictDepth *pictDepth; 312 xPictVisual *pictVisual; 313 xPictFormInfo *pictForm; 314 CARD32 *pictSubpixel; 315 ScreenPtr pScreen; 316 VisualPtr pVisual; 317 DepthPtr pDepth; 318 int v, d; 319 PictureScreenPtr ps; 320 PictFormatPtr pFormat; 321 int nformat; 322 int ndepth; 323 int nvisual; 324 int rlength; 325 int s; 326 int numScreens; 327 int numSubpixel; 328 329/* REQUEST(xRenderQueryPictFormatsReq); */ 330 331 REQUEST_SIZE_MATCH(xRenderQueryPictFormatsReq); 332 333#ifdef PANORAMIX 334 if (noPanoramiXExtension) 335 numScreens = screenInfo.numScreens; 336 else 337 numScreens = ((xConnSetup *) ConnectionInfo)->numRoots; 338#else 339 numScreens = screenInfo.numScreens; 340#endif 341 ndepth = nformat = nvisual = 0; 342 for (s = 0; s < numScreens; s++) { 343 pScreen = screenInfo.screens[s]; 344 for (d = 0; d < pScreen->numDepths; d++) { 345 pDepth = pScreen->allowedDepths + d; 346 ++ndepth; 347 348 for (v = 0; v < pDepth->numVids; v++) { 349 pVisual = findVisual(pScreen, pDepth->vids[v]); 350 if (pVisual && 351 PictureMatchVisual(pScreen, pDepth->depth, pVisual)) 352 ++nvisual; 353 } 354 } 355 ps = GetPictureScreenIfSet(pScreen); 356 if (ps) 357 nformat += ps->nformats; 358 } 359 if (pRenderClient->major_version == 0 && pRenderClient->minor_version < 6) 360 numSubpixel = 0; 361 else 362 numSubpixel = numScreens; 363 364 rlength = (sizeof(xRenderQueryPictFormatsReply) + 365 nformat * sizeof(xPictFormInfo) + 366 numScreens * sizeof(xPictScreen) + 367 ndepth * sizeof(xPictDepth) + 368 nvisual * sizeof(xPictVisual) + numSubpixel * sizeof(CARD32)); 369 reply = (xRenderQueryPictFormatsReply *) calloc(1, rlength); 370 if (!reply) 371 return BadAlloc; 372 reply->type = X_Reply; 373 reply->sequenceNumber = client->sequence; 374 reply->length = bytes_to_int32(rlength - sizeof(xGenericReply)); 375 reply->numFormats = nformat; 376 reply->numScreens = numScreens; 377 reply->numDepths = ndepth; 378 reply->numVisuals = nvisual; 379 reply->numSubpixel = numSubpixel; 380 381 pictForm = (xPictFormInfo *) (reply + 1); 382 383 for (s = 0; s < numScreens; s++) { 384 pScreen = screenInfo.screens[s]; 385 ps = GetPictureScreenIfSet(pScreen); 386 if (ps) { 387 for (nformat = 0, pFormat = ps->formats; 388 nformat < ps->nformats; nformat++, pFormat++) { 389 pictForm->id = pFormat->id; 390 pictForm->type = pFormat->type; 391 pictForm->depth = pFormat->depth; 392 pictForm->direct.red = pFormat->direct.red; 393 pictForm->direct.redMask = pFormat->direct.redMask; 394 pictForm->direct.green = pFormat->direct.green; 395 pictForm->direct.greenMask = pFormat->direct.greenMask; 396 pictForm->direct.blue = pFormat->direct.blue; 397 pictForm->direct.blueMask = pFormat->direct.blueMask; 398 pictForm->direct.alpha = pFormat->direct.alpha; 399 pictForm->direct.alphaMask = pFormat->direct.alphaMask; 400 if (pFormat->type == PictTypeIndexed && 401 pFormat->index.pColormap) 402 pictForm->colormap = pFormat->index.pColormap->mid; 403 else 404 pictForm->colormap = None; 405 if (client->swapped) { 406 swapl(&pictForm->id); 407 swaps(&pictForm->direct.red); 408 swaps(&pictForm->direct.redMask); 409 swaps(&pictForm->direct.green); 410 swaps(&pictForm->direct.greenMask); 411 swaps(&pictForm->direct.blue); 412 swaps(&pictForm->direct.blueMask); 413 swaps(&pictForm->direct.alpha); 414 swaps(&pictForm->direct.alphaMask); 415 swapl(&pictForm->colormap); 416 } 417 pictForm++; 418 } 419 } 420 } 421 422 pictScreen = (xPictScreen *) pictForm; 423 for (s = 0; s < numScreens; s++) { 424 pScreen = screenInfo.screens[s]; 425 pictDepth = (xPictDepth *) (pictScreen + 1); 426 ndepth = 0; 427 for (d = 0; d < pScreen->numDepths; d++) { 428 pictVisual = (xPictVisual *) (pictDepth + 1); 429 pDepth = pScreen->allowedDepths + d; 430 431 nvisual = 0; 432 for (v = 0; v < pDepth->numVids; v++) { 433 pVisual = findVisual(pScreen, pDepth->vids[v]); 434 if (pVisual && (pFormat = PictureMatchVisual(pScreen, 435 pDepth->depth, 436 pVisual))) { 437 pictVisual->visual = pVisual->vid; 438 pictVisual->format = pFormat->id; 439 if (client->swapped) { 440 swapl(&pictVisual->visual); 441 swapl(&pictVisual->format); 442 } 443 pictVisual++; 444 nvisual++; 445 } 446 } 447 pictDepth->depth = pDepth->depth; 448 pictDepth->nPictVisuals = nvisual; 449 if (client->swapped) { 450 swaps(&pictDepth->nPictVisuals); 451 } 452 ndepth++; 453 pictDepth = (xPictDepth *) pictVisual; 454 } 455 pictScreen->nDepth = ndepth; 456 ps = GetPictureScreenIfSet(pScreen); 457 if (ps) 458 pictScreen->fallback = ps->fallback->id; 459 else 460 pictScreen->fallback = 0; 461 if (client->swapped) { 462 swapl(&pictScreen->nDepth); 463 swapl(&pictScreen->fallback); 464 } 465 pictScreen = (xPictScreen *) pictDepth; 466 } 467 pictSubpixel = (CARD32 *) pictScreen; 468 469 for (s = 0; s < numSubpixel; s++) { 470 pScreen = screenInfo.screens[s]; 471 ps = GetPictureScreenIfSet(pScreen); 472 if (ps) 473 *pictSubpixel = ps->subpixel; 474 else 475 *pictSubpixel = SubPixelUnknown; 476 if (client->swapped) { 477 swapl(pictSubpixel); 478 } 479 ++pictSubpixel; 480 } 481 482 if (client->swapped) { 483 swaps(&reply->sequenceNumber); 484 swapl(&reply->length); 485 swapl(&reply->numFormats); 486 swapl(&reply->numScreens); 487 swapl(&reply->numDepths); 488 swapl(&reply->numVisuals); 489 swapl(&reply->numSubpixel); 490 } 491 WriteToClient(client, rlength, reply); 492 free(reply); 493 return Success; 494} 495 496static int 497ProcRenderQueryPictIndexValues(ClientPtr client) 498{ 499 PictFormatPtr pFormat; 500 int rc, num; 501 int rlength; 502 int i; 503 504 REQUEST(xRenderQueryPictIndexValuesReq); 505 xRenderQueryPictIndexValuesReply *reply; 506 xIndexValue *values; 507 508 REQUEST_AT_LEAST_SIZE(xRenderQueryPictIndexValuesReq); 509 510 rc = dixLookupResourceByType((void **) &pFormat, stuff->format, 511 PictFormatType, client, DixReadAccess); 512 if (rc != Success) 513 return rc; 514 515 if (pFormat->type != PictTypeIndexed) { 516 client->errorValue = stuff->format; 517 return BadMatch; 518 } 519 num = pFormat->index.nvalues; 520 rlength = (sizeof(xRenderQueryPictIndexValuesReply) + 521 num * sizeof(xIndexValue)); 522 reply = (xRenderQueryPictIndexValuesReply *) calloc(1, rlength); 523 if (!reply) 524 return BadAlloc; 525 526 reply->type = X_Reply; 527 reply->sequenceNumber = client->sequence; 528 reply->length = bytes_to_int32(rlength - sizeof(xGenericReply)); 529 reply->numIndexValues = num; 530 531 values = (xIndexValue *) (reply + 1); 532 533 memcpy(reply + 1, pFormat->index.pValues, num * sizeof(xIndexValue)); 534 535 if (client->swapped) { 536 for (i = 0; i < num; i++) { 537 swapl(&values[i].pixel); 538 swaps(&values[i].red); 539 swaps(&values[i].green); 540 swaps(&values[i].blue); 541 swaps(&values[i].alpha); 542 } 543 swaps(&reply->sequenceNumber); 544 swapl(&reply->length); 545 swapl(&reply->numIndexValues); 546 } 547 548 WriteToClient(client, rlength, reply); 549 free(reply); 550 return Success; 551} 552 553static int 554ProcRenderQueryDithers(ClientPtr client) 555{ 556 return BadImplementation; 557} 558 559static int 560ProcRenderCreatePicture(ClientPtr client) 561{ 562 PicturePtr pPicture; 563 DrawablePtr pDrawable; 564 PictFormatPtr pFormat; 565 int len, error, rc; 566 567 REQUEST(xRenderCreatePictureReq); 568 569 REQUEST_AT_LEAST_SIZE(xRenderCreatePictureReq); 570 571 LEGAL_NEW_RESOURCE(stuff->pid, client); 572 rc = dixLookupDrawable(&pDrawable, stuff->drawable, client, 0, 573 DixReadAccess | DixAddAccess); 574 if (rc != Success) 575 return rc; 576 577 rc = dixLookupResourceByType((void **) &pFormat, stuff->format, 578 PictFormatType, client, DixReadAccess); 579 if (rc != Success) 580 return rc; 581 582 if (pFormat->depth != pDrawable->depth) 583 return BadMatch; 584 len = client->req_len - bytes_to_int32(sizeof(xRenderCreatePictureReq)); 585 if (Ones(stuff->mask) != len) 586 return BadLength; 587 588 pPicture = CreatePicture(stuff->pid, 589 pDrawable, 590 pFormat, 591 stuff->mask, (XID *) (stuff + 1), client, &error); 592 if (!pPicture) 593 return error; 594 if (!AddResource(stuff->pid, PictureType, (void *) pPicture)) 595 return BadAlloc; 596 return Success; 597} 598 599static int 600ProcRenderChangePicture(ClientPtr client) 601{ 602 PicturePtr pPicture; 603 604 REQUEST(xRenderChangePictureReq); 605 int len; 606 607 REQUEST_AT_LEAST_SIZE(xRenderChangePictureReq); 608 VERIFY_PICTURE(pPicture, stuff->picture, client, DixSetAttrAccess); 609 610 len = client->req_len - bytes_to_int32(sizeof(xRenderChangePictureReq)); 611 if (Ones(stuff->mask) != len) 612 return BadLength; 613 614 return ChangePicture(pPicture, stuff->mask, (XID *) (stuff + 1), 615 (DevUnion *) 0, client); 616} 617 618static int 619ProcRenderSetPictureClipRectangles(ClientPtr client) 620{ 621 REQUEST(xRenderSetPictureClipRectanglesReq); 622 PicturePtr pPicture; 623 int nr; 624 625 REQUEST_AT_LEAST_SIZE(xRenderSetPictureClipRectanglesReq); 626 VERIFY_PICTURE(pPicture, stuff->picture, client, DixSetAttrAccess); 627 if (!pPicture->pDrawable) 628 return RenderErrBase + BadPicture; 629 630 nr = (client->req_len << 2) - sizeof(xRenderSetPictureClipRectanglesReq); 631 if (nr & 4) 632 return BadLength; 633 nr >>= 3; 634 return SetPictureClipRects(pPicture, 635 stuff->xOrigin, stuff->yOrigin, 636 nr, (xRectangle *) &stuff[1]); 637} 638 639static int 640ProcRenderFreePicture(ClientPtr client) 641{ 642 PicturePtr pPicture; 643 644 REQUEST(xRenderFreePictureReq); 645 646 REQUEST_SIZE_MATCH(xRenderFreePictureReq); 647 648 VERIFY_PICTURE(pPicture, stuff->picture, client, DixDestroyAccess); 649 FreeResource(stuff->picture, RT_NONE); 650 return Success; 651} 652 653static Bool 654PictOpValid(CARD8 op) 655{ 656 if ( /*PictOpMinimum <= op && */ op <= PictOpMaximum) 657 return TRUE; 658 if (PictOpDisjointMinimum <= op && op <= PictOpDisjointMaximum) 659 return TRUE; 660 if (PictOpConjointMinimum <= op && op <= PictOpConjointMaximum) 661 return TRUE; 662 if (PictOpBlendMinimum <= op && op <= PictOpBlendMaximum) 663 return TRUE; 664 return FALSE; 665} 666 667static int 668ProcRenderComposite(ClientPtr client) 669{ 670 PicturePtr pSrc, pMask, pDst; 671 672 REQUEST(xRenderCompositeReq); 673 674 REQUEST_SIZE_MATCH(xRenderCompositeReq); 675 if (!PictOpValid(stuff->op)) { 676 client->errorValue = stuff->op; 677 return BadValue; 678 } 679 VERIFY_PICTURE(pDst, stuff->dst, client, DixWriteAccess); 680 if (!pDst->pDrawable) 681 return BadDrawable; 682 VERIFY_PICTURE(pSrc, stuff->src, client, DixReadAccess); 683 VERIFY_ALPHA(pMask, stuff->mask, client, DixReadAccess); 684 if ((pSrc->pDrawable && 685 pSrc->pDrawable->pScreen != pDst->pDrawable->pScreen) || (pMask && 686 pMask-> 687 pDrawable && 688 pDst-> 689 pDrawable-> 690 pScreen != 691 pMask-> 692 pDrawable-> 693 pScreen)) 694 return BadMatch; 695 CompositePicture(stuff->op, 696 pSrc, 697 pMask, 698 pDst, 699 stuff->xSrc, 700 stuff->ySrc, 701 stuff->xMask, 702 stuff->yMask, 703 stuff->xDst, stuff->yDst, stuff->width, stuff->height); 704 return Success; 705} 706 707static int 708ProcRenderScale(ClientPtr client) 709{ 710 return BadImplementation; 711} 712 713static int 714ProcRenderTrapezoids(ClientPtr client) 715{ 716 int rc, ntraps; 717 PicturePtr pSrc, pDst; 718 PictFormatPtr pFormat; 719 720 REQUEST(xRenderTrapezoidsReq); 721 722 REQUEST_AT_LEAST_SIZE(xRenderTrapezoidsReq); 723 if (!PictOpValid(stuff->op)) { 724 client->errorValue = stuff->op; 725 return BadValue; 726 } 727 VERIFY_PICTURE(pSrc, stuff->src, client, DixReadAccess); 728 VERIFY_PICTURE(pDst, stuff->dst, client, DixWriteAccess); 729 if (!pDst->pDrawable) 730 return BadDrawable; 731 if (pSrc->pDrawable && pSrc->pDrawable->pScreen != pDst->pDrawable->pScreen) 732 return BadMatch; 733 if (stuff->maskFormat) { 734 rc = dixLookupResourceByType((void **) &pFormat, stuff->maskFormat, 735 PictFormatType, client, DixReadAccess); 736 if (rc != Success) 737 return rc; 738 } 739 else 740 pFormat = 0; 741 ntraps = (client->req_len << 2) - sizeof(xRenderTrapezoidsReq); 742 if (ntraps % sizeof(xTrapezoid)) 743 return BadLength; 744 ntraps /= sizeof(xTrapezoid); 745 if (ntraps) 746 CompositeTrapezoids(stuff->op, pSrc, pDst, pFormat, 747 stuff->xSrc, stuff->ySrc, 748 ntraps, (xTrapezoid *) &stuff[1]); 749 return Success; 750} 751 752static int 753ProcRenderTriangles(ClientPtr client) 754{ 755 int rc, ntris; 756 PicturePtr pSrc, pDst; 757 PictFormatPtr pFormat; 758 759 REQUEST(xRenderTrianglesReq); 760 761 REQUEST_AT_LEAST_SIZE(xRenderTrianglesReq); 762 if (!PictOpValid(stuff->op)) { 763 client->errorValue = stuff->op; 764 return BadValue; 765 } 766 VERIFY_PICTURE(pSrc, stuff->src, client, DixReadAccess); 767 VERIFY_PICTURE(pDst, stuff->dst, client, DixWriteAccess); 768 if (!pDst->pDrawable) 769 return BadDrawable; 770 if (pSrc->pDrawable && pSrc->pDrawable->pScreen != pDst->pDrawable->pScreen) 771 return BadMatch; 772 if (stuff->maskFormat) { 773 rc = dixLookupResourceByType((void **) &pFormat, stuff->maskFormat, 774 PictFormatType, client, DixReadAccess); 775 if (rc != Success) 776 return rc; 777 } 778 else 779 pFormat = 0; 780 ntris = (client->req_len << 2) - sizeof(xRenderTrianglesReq); 781 if (ntris % sizeof(xTriangle)) 782 return BadLength; 783 ntris /= sizeof(xTriangle); 784 if (ntris) 785 CompositeTriangles(stuff->op, pSrc, pDst, pFormat, 786 stuff->xSrc, stuff->ySrc, 787 ntris, (xTriangle *) &stuff[1]); 788 return Success; 789} 790 791static int 792ProcRenderTriStrip(ClientPtr client) 793{ 794 int rc, npoints; 795 PicturePtr pSrc, pDst; 796 PictFormatPtr pFormat; 797 798 REQUEST(xRenderTrianglesReq); 799 800 REQUEST_AT_LEAST_SIZE(xRenderTrianglesReq); 801 if (!PictOpValid(stuff->op)) { 802 client->errorValue = stuff->op; 803 return BadValue; 804 } 805 VERIFY_PICTURE(pSrc, stuff->src, client, DixReadAccess); 806 VERIFY_PICTURE(pDst, stuff->dst, client, DixWriteAccess); 807 if (!pDst->pDrawable) 808 return BadDrawable; 809 if (pSrc->pDrawable && pSrc->pDrawable->pScreen != pDst->pDrawable->pScreen) 810 return BadMatch; 811 if (stuff->maskFormat) { 812 rc = dixLookupResourceByType((void **) &pFormat, stuff->maskFormat, 813 PictFormatType, client, DixReadAccess); 814 if (rc != Success) 815 return rc; 816 } 817 else 818 pFormat = 0; 819 npoints = ((client->req_len << 2) - sizeof(xRenderTriStripReq)); 820 if (npoints & 4) 821 return BadLength; 822 npoints >>= 3; 823 if (npoints >= 3) 824 CompositeTriStrip(stuff->op, pSrc, pDst, pFormat, 825 stuff->xSrc, stuff->ySrc, 826 npoints, (xPointFixed *) &stuff[1]); 827 return Success; 828} 829 830static int 831ProcRenderTriFan(ClientPtr client) 832{ 833 int rc, npoints; 834 PicturePtr pSrc, pDst; 835 PictFormatPtr pFormat; 836 837 REQUEST(xRenderTrianglesReq); 838 839 REQUEST_AT_LEAST_SIZE(xRenderTrianglesReq); 840 if (!PictOpValid(stuff->op)) { 841 client->errorValue = stuff->op; 842 return BadValue; 843 } 844 VERIFY_PICTURE(pSrc, stuff->src, client, DixReadAccess); 845 VERIFY_PICTURE(pDst, stuff->dst, client, DixWriteAccess); 846 if (!pDst->pDrawable) 847 return BadDrawable; 848 if (pSrc->pDrawable && pSrc->pDrawable->pScreen != pDst->pDrawable->pScreen) 849 return BadMatch; 850 if (stuff->maskFormat) { 851 rc = dixLookupResourceByType((void **) &pFormat, stuff->maskFormat, 852 PictFormatType, client, DixReadAccess); 853 if (rc != Success) 854 return rc; 855 } 856 else 857 pFormat = 0; 858 npoints = ((client->req_len << 2) - sizeof(xRenderTriStripReq)); 859 if (npoints & 4) 860 return BadLength; 861 npoints >>= 3; 862 if (npoints >= 3) 863 CompositeTriFan(stuff->op, pSrc, pDst, pFormat, 864 stuff->xSrc, stuff->ySrc, 865 npoints, (xPointFixed *) &stuff[1]); 866 return Success; 867} 868 869static int 870ProcRenderColorTrapezoids(ClientPtr client) 871{ 872 return BadImplementation; 873} 874 875static int 876ProcRenderColorTriangles(ClientPtr client) 877{ 878 return BadImplementation; 879} 880 881static int 882ProcRenderTransform(ClientPtr client) 883{ 884 return BadImplementation; 885} 886 887static int 888ProcRenderCreateGlyphSet(ClientPtr client) 889{ 890 GlyphSetPtr glyphSet; 891 PictFormatPtr format; 892 int rc, f; 893 894 REQUEST(xRenderCreateGlyphSetReq); 895 896 REQUEST_SIZE_MATCH(xRenderCreateGlyphSetReq); 897 898 LEGAL_NEW_RESOURCE(stuff->gsid, client); 899 rc = dixLookupResourceByType((void **) &format, stuff->format, 900 PictFormatType, client, DixReadAccess); 901 if (rc != Success) 902 return rc; 903 904 switch (format->depth) { 905 case 1: 906 f = GlyphFormat1; 907 break; 908 case 4: 909 f = GlyphFormat4; 910 break; 911 case 8: 912 f = GlyphFormat8; 913 break; 914 case 16: 915 f = GlyphFormat16; 916 break; 917 case 32: 918 f = GlyphFormat32; 919 break; 920 default: 921 return BadMatch; 922 } 923 if (format->type != PictTypeDirect) 924 return BadMatch; 925 glyphSet = AllocateGlyphSet(f, format); 926 if (!glyphSet) 927 return BadAlloc; 928 /* security creation/labeling check */ 929 rc = XaceHook(XACE_RESOURCE_ACCESS, client, stuff->gsid, GlyphSetType, 930 glyphSet, RT_NONE, NULL, DixCreateAccess); 931 if (rc != Success) 932 return rc; 933 if (!AddResource(stuff->gsid, GlyphSetType, (void *) glyphSet)) 934 return BadAlloc; 935 return Success; 936} 937 938static int 939ProcRenderReferenceGlyphSet(ClientPtr client) 940{ 941 GlyphSetPtr glyphSet; 942 int rc; 943 944 REQUEST(xRenderReferenceGlyphSetReq); 945 946 REQUEST_SIZE_MATCH(xRenderReferenceGlyphSetReq); 947 948 LEGAL_NEW_RESOURCE(stuff->gsid, client); 949 950 rc = dixLookupResourceByType((void **) &glyphSet, stuff->existing, 951 GlyphSetType, client, DixGetAttrAccess); 952 if (rc != Success) { 953 client->errorValue = stuff->existing; 954 return rc; 955 } 956 glyphSet->refcnt++; 957 if (!AddResource(stuff->gsid, GlyphSetType, (void *) glyphSet)) 958 return BadAlloc; 959 return Success; 960} 961 962#define NLOCALDELTA 64 963#define NLOCALGLYPH 256 964 965static int 966ProcRenderFreeGlyphSet(ClientPtr client) 967{ 968 GlyphSetPtr glyphSet; 969 int rc; 970 971 REQUEST(xRenderFreeGlyphSetReq); 972 973 REQUEST_SIZE_MATCH(xRenderFreeGlyphSetReq); 974 rc = dixLookupResourceByType((void **) &glyphSet, stuff->glyphset, 975 GlyphSetType, client, DixDestroyAccess); 976 if (rc != Success) { 977 client->errorValue = stuff->glyphset; 978 return rc; 979 } 980 FreeResource(stuff->glyphset, RT_NONE); 981 return Success; 982} 983 984typedef struct _GlyphNew { 985 Glyph id; 986 GlyphPtr glyph; 987 Bool found; 988 unsigned char sha1[20]; 989} GlyphNewRec, *GlyphNewPtr; 990 991#define NeedsComponent(f) (PICT_FORMAT_A(f) != 0 && PICT_FORMAT_RGB(f) != 0) 992 993static int 994ProcRenderAddGlyphs(ClientPtr client) 995{ 996 GlyphSetPtr glyphSet; 997 998 REQUEST(xRenderAddGlyphsReq); 999 GlyphNewRec glyphsLocal[NLOCALGLYPH]; 1000 GlyphNewPtr glyphsBase, glyphs, glyph_new; 1001 int remain, nglyphs; 1002 CARD32 *gids; 1003 xGlyphInfo *gi; 1004 CARD8 *bits; 1005 unsigned int size; 1006 int err; 1007 int i, screen; 1008 PicturePtr pSrc = NULL, pDst = NULL; 1009 PixmapPtr pSrcPix = NULL, pDstPix = NULL; 1010 CARD32 component_alpha; 1011 1012 REQUEST_AT_LEAST_SIZE(xRenderAddGlyphsReq); 1013 err = 1014 dixLookupResourceByType((void **) &glyphSet, stuff->glyphset, 1015 GlyphSetType, client, DixAddAccess); 1016 if (err != Success) { 1017 client->errorValue = stuff->glyphset; 1018 return err; 1019 } 1020 1021 err = BadAlloc; 1022 nglyphs = stuff->nglyphs; 1023 if (nglyphs > UINT32_MAX / sizeof(GlyphNewRec)) 1024 return BadAlloc; 1025 1026 component_alpha = NeedsComponent(glyphSet->format->format); 1027 1028 if (nglyphs <= NLOCALGLYPH) { 1029 memset(glyphsLocal, 0, sizeof(glyphsLocal)); 1030 glyphsBase = glyphsLocal; 1031 } 1032 else { 1033 glyphsBase = (GlyphNewPtr) calloc(nglyphs, sizeof(GlyphNewRec)); 1034 if (!glyphsBase) 1035 return BadAlloc; 1036 } 1037 1038 remain = (client->req_len << 2) - sizeof(xRenderAddGlyphsReq); 1039 1040 glyphs = glyphsBase; 1041 1042 gids = (CARD32 *) (stuff + 1); 1043 gi = (xGlyphInfo *) (gids + nglyphs); 1044 bits = (CARD8 *) (gi + nglyphs); 1045 remain -= (sizeof(CARD32) + sizeof(xGlyphInfo)) * nglyphs; 1046 1047 /* protect against bad nglyphs */ 1048 if (gi < ((xGlyphInfo *) stuff) || 1049 gi > ((xGlyphInfo *) ((CARD32 *) stuff + client->req_len)) || 1050 bits < ((CARD8 *) stuff) || 1051 bits > ((CARD8 *) ((CARD32 *) stuff + client->req_len))) { 1052 err = BadLength; 1053 goto bail; 1054 } 1055 1056 for (i = 0; i < nglyphs; i++) { 1057 size_t padded_width; 1058 1059 glyph_new = &glyphs[i]; 1060 1061 padded_width = PixmapBytePad(gi[i].width, glyphSet->format->depth); 1062 1063 if (gi[i].height && 1064 padded_width > (UINT32_MAX - sizeof(GlyphRec)) / gi[i].height) 1065 break; 1066 1067 size = gi[i].height * padded_width; 1068 if (remain < size) 1069 break; 1070 1071 err = HashGlyph(&gi[i], bits, size, glyph_new->sha1); 1072 if (err) 1073 goto bail; 1074 1075 glyph_new->glyph = FindGlyphByHash(glyph_new->sha1, glyphSet->fdepth); 1076 1077 if (glyph_new->glyph && glyph_new->glyph != DeletedGlyph) { 1078 glyph_new->found = TRUE; 1079 } 1080 else { 1081 GlyphPtr glyph; 1082 1083 glyph_new->found = FALSE; 1084 glyph_new->glyph = glyph = AllocateGlyph(&gi[i], glyphSet->fdepth); 1085 if (!glyph) { 1086 err = BadAlloc; 1087 goto bail; 1088 } 1089 1090 for (screen = 0; screen < screenInfo.numScreens; screen++) { 1091 int width = gi[i].width; 1092 int height = gi[i].height; 1093 int depth = glyphSet->format->depth; 1094 ScreenPtr pScreen; 1095 int error; 1096 1097 /* Skip work if it's invisibly small anyway */ 1098 if (!width || !height) 1099 break; 1100 1101 pScreen = screenInfo.screens[screen]; 1102 pSrcPix = GetScratchPixmapHeader(pScreen, 1103 width, height, 1104 depth, depth, -1, bits); 1105 if (!pSrcPix) { 1106 err = BadAlloc; 1107 goto bail; 1108 } 1109 1110 pSrc = CreatePicture(0, &pSrcPix->drawable, 1111 glyphSet->format, 0, NULL, 1112 serverClient, &error); 1113 if (!pSrc) { 1114 err = BadAlloc; 1115 goto bail; 1116 } 1117 1118 pDstPix = (pScreen->CreatePixmap) (pScreen, 1119 width, height, depth, 1120 CREATE_PIXMAP_USAGE_GLYPH_PICTURE); 1121 1122 if (!pDstPix) { 1123 err = BadAlloc; 1124 goto bail; 1125 } 1126 1127 pDst = CreatePicture(0, &pDstPix->drawable, 1128 glyphSet->format, 1129 CPComponentAlpha, &component_alpha, 1130 serverClient, &error); 1131 SetGlyphPicture(glyph, pScreen, pDst); 1132 1133 /* The picture takes a reference to the pixmap, so we 1134 drop ours. */ 1135 (pScreen->DestroyPixmap) (pDstPix); 1136 pDstPix = NULL; 1137 1138 if (!pDst) { 1139 err = BadAlloc; 1140 goto bail; 1141 } 1142 1143 CompositePicture(PictOpSrc, 1144 pSrc, 1145 None, pDst, 0, 0, 0, 0, 0, 0, width, height); 1146 1147 FreePicture((void *) pSrc, 0); 1148 pSrc = NULL; 1149 FreeScratchPixmapHeader(pSrcPix); 1150 pSrcPix = NULL; 1151 } 1152 1153 memcpy(glyph_new->glyph->sha1, glyph_new->sha1, 20); 1154 } 1155 1156 glyph_new->id = gids[i]; 1157 1158 if (size & 3) 1159 size += 4 - (size & 3); 1160 bits += size; 1161 remain -= size; 1162 } 1163 if (remain || i < nglyphs) { 1164 err = BadLength; 1165 goto bail; 1166 } 1167 if (!ResizeGlyphSet(glyphSet, nglyphs)) { 1168 err = BadAlloc; 1169 goto bail; 1170 } 1171 for (i = 0; i < nglyphs; i++) 1172 AddGlyph(glyphSet, glyphs[i].glyph, glyphs[i].id); 1173 1174 if (glyphsBase != glyphsLocal) 1175 free(glyphsBase); 1176 return Success; 1177 bail: 1178 if (pSrc) 1179 FreePicture((void *) pSrc, 0); 1180 if (pSrcPix) 1181 FreeScratchPixmapHeader(pSrcPix); 1182 for (i = 0; i < nglyphs; i++) 1183 if (glyphs[i].glyph && !glyphs[i].found) 1184 free(glyphs[i].glyph); 1185 if (glyphsBase != glyphsLocal) 1186 free(glyphsBase); 1187 return err; 1188} 1189 1190static int 1191ProcRenderAddGlyphsFromPicture(ClientPtr client) 1192{ 1193 return BadImplementation; 1194} 1195 1196static int 1197ProcRenderFreeGlyphs(ClientPtr client) 1198{ 1199 REQUEST(xRenderFreeGlyphsReq); 1200 GlyphSetPtr glyphSet; 1201 int rc, nglyph; 1202 CARD32 *gids; 1203 CARD32 glyph; 1204 1205 REQUEST_AT_LEAST_SIZE(xRenderFreeGlyphsReq); 1206 rc = dixLookupResourceByType((void **) &glyphSet, stuff->glyphset, 1207 GlyphSetType, client, DixRemoveAccess); 1208 if (rc != Success) { 1209 client->errorValue = stuff->glyphset; 1210 return rc; 1211 } 1212 nglyph = 1213 bytes_to_int32((client->req_len << 2) - sizeof(xRenderFreeGlyphsReq)); 1214 gids = (CARD32 *) (stuff + 1); 1215 while (nglyph-- > 0) { 1216 glyph = *gids++; 1217 if (!DeleteGlyph(glyphSet, glyph)) { 1218 client->errorValue = glyph; 1219 return RenderErrBase + BadGlyph; 1220 } 1221 } 1222 return Success; 1223} 1224 1225static int 1226ProcRenderCompositeGlyphs(ClientPtr client) 1227{ 1228 GlyphSetPtr glyphSet; 1229 GlyphSet gs; 1230 PicturePtr pSrc, pDst; 1231 PictFormatPtr pFormat; 1232 GlyphListRec listsLocal[NLOCALDELTA]; 1233 GlyphListPtr lists, listsBase; 1234 GlyphPtr glyphsLocal[NLOCALGLYPH]; 1235 Glyph glyph; 1236 GlyphPtr *glyphs, *glyphsBase; 1237 xGlyphElt *elt; 1238 CARD8 *buffer, *end; 1239 int nglyph; 1240 int nlist; 1241 int space; 1242 int size; 1243 int rc, n; 1244 1245 REQUEST(xRenderCompositeGlyphsReq); 1246 1247 REQUEST_AT_LEAST_SIZE(xRenderCompositeGlyphsReq); 1248 1249 switch (stuff->renderReqType) { 1250 default: 1251 size = 1; 1252 break; 1253 case X_RenderCompositeGlyphs16: 1254 size = 2; 1255 break; 1256 case X_RenderCompositeGlyphs32: 1257 size = 4; 1258 break; 1259 } 1260 1261 if (!PictOpValid(stuff->op)) { 1262 client->errorValue = stuff->op; 1263 return BadValue; 1264 } 1265 VERIFY_PICTURE(pSrc, stuff->src, client, DixReadAccess); 1266 VERIFY_PICTURE(pDst, stuff->dst, client, DixWriteAccess); 1267 if (!pDst->pDrawable) 1268 return BadDrawable; 1269 if (pSrc->pDrawable && pSrc->pDrawable->pScreen != pDst->pDrawable->pScreen) 1270 return BadMatch; 1271 if (stuff->maskFormat) { 1272 rc = dixLookupResourceByType((void **) &pFormat, stuff->maskFormat, 1273 PictFormatType, client, DixReadAccess); 1274 if (rc != Success) 1275 return rc; 1276 } 1277 else 1278 pFormat = 0; 1279 1280 rc = dixLookupResourceByType((void **) &glyphSet, stuff->glyphset, 1281 GlyphSetType, client, DixUseAccess); 1282 if (rc != Success) 1283 return rc; 1284 1285 buffer = (CARD8 *) (stuff + 1); 1286 end = (CARD8 *) stuff + (client->req_len << 2); 1287 nglyph = 0; 1288 nlist = 0; 1289 while (buffer + sizeof(xGlyphElt) < end) { 1290 elt = (xGlyphElt *) buffer; 1291 buffer += sizeof(xGlyphElt); 1292 1293 if (elt->len == 0xff) { 1294 buffer += 4; 1295 } 1296 else { 1297 nlist++; 1298 nglyph += elt->len; 1299 space = size * elt->len; 1300 if (space & 3) 1301 space += 4 - (space & 3); 1302 buffer += space; 1303 } 1304 } 1305 if (nglyph <= NLOCALGLYPH) 1306 glyphsBase = glyphsLocal; 1307 else { 1308 glyphsBase = xallocarray(nglyph, sizeof(GlyphPtr)); 1309 if (!glyphsBase) 1310 return BadAlloc; 1311 } 1312 if (nlist <= NLOCALDELTA) 1313 listsBase = listsLocal; 1314 else { 1315 listsBase = xallocarray(nlist, sizeof(GlyphListRec)); 1316 if (!listsBase) { 1317 rc = BadAlloc; 1318 goto bail; 1319 } 1320 } 1321 buffer = (CARD8 *) (stuff + 1); 1322 glyphs = glyphsBase; 1323 lists = listsBase; 1324 while (buffer + sizeof(xGlyphElt) < end) { 1325 elt = (xGlyphElt *) buffer; 1326 buffer += sizeof(xGlyphElt); 1327 1328 if (elt->len == 0xff) { 1329 if (buffer + sizeof(GlyphSet) < end) { 1330 memcpy(&gs, buffer, sizeof(GlyphSet)); 1331 rc = dixLookupResourceByType((void **) &glyphSet, gs, 1332 GlyphSetType, client, 1333 DixUseAccess); 1334 if (rc != Success) 1335 goto bail; 1336 } 1337 buffer += 4; 1338 } 1339 else { 1340 lists->xOff = elt->deltax; 1341 lists->yOff = elt->deltay; 1342 lists->format = glyphSet->format; 1343 lists->len = 0; 1344 n = elt->len; 1345 while (n--) { 1346 if (buffer + size <= end) { 1347 switch (size) { 1348 case 1: 1349 glyph = *((CARD8 *) buffer); 1350 break; 1351 case 2: 1352 glyph = *((CARD16 *) buffer); 1353 break; 1354 case 4: 1355 default: 1356 glyph = *((CARD32 *) buffer); 1357 break; 1358 } 1359 if ((*glyphs = FindGlyph(glyphSet, glyph))) { 1360 lists->len++; 1361 glyphs++; 1362 } 1363 } 1364 buffer += size; 1365 } 1366 space = size * elt->len; 1367 if (space & 3) 1368 buffer += 4 - (space & 3); 1369 lists++; 1370 } 1371 } 1372 if (buffer > end) { 1373 rc = BadLength; 1374 goto bail; 1375 } 1376 1377 CompositeGlyphs(stuff->op, 1378 pSrc, 1379 pDst, 1380 pFormat, 1381 stuff->xSrc, stuff->ySrc, nlist, listsBase, glyphsBase); 1382 rc = Success; 1383 1384 bail: 1385 if (glyphsBase != glyphsLocal) 1386 free(glyphsBase); 1387 if (listsBase != listsLocal) 1388 free(listsBase); 1389 return rc; 1390} 1391 1392static int 1393ProcRenderFillRectangles(ClientPtr client) 1394{ 1395 PicturePtr pDst; 1396 int things; 1397 1398 REQUEST(xRenderFillRectanglesReq); 1399 1400 REQUEST_AT_LEAST_SIZE(xRenderFillRectanglesReq); 1401 if (!PictOpValid(stuff->op)) { 1402 client->errorValue = stuff->op; 1403 return BadValue; 1404 } 1405 VERIFY_PICTURE(pDst, stuff->dst, client, DixWriteAccess); 1406 if (!pDst->pDrawable) 1407 return BadDrawable; 1408 1409 things = (client->req_len << 2) - sizeof(xRenderFillRectanglesReq); 1410 if (things & 4) 1411 return BadLength; 1412 things >>= 3; 1413 1414 CompositeRects(stuff->op, 1415 pDst, &stuff->color, things, (xRectangle *) &stuff[1]); 1416 1417 return Success; 1418} 1419 1420static void 1421RenderSetBit(unsigned char *line, int x, int bit) 1422{ 1423 unsigned char mask; 1424 1425 if (screenInfo.bitmapBitOrder == LSBFirst) 1426 mask = (1 << (x & 7)); 1427 else 1428 mask = (0x80 >> (x & 7)); 1429 /* XXX assumes byte order is host byte order */ 1430 line += (x >> 3); 1431 if (bit) 1432 *line |= mask; 1433 else 1434 *line &= ~mask; 1435} 1436 1437#define DITHER_DIM 2 1438 1439static CARD32 orderedDither[DITHER_DIM][DITHER_DIM] = { 1440 {1, 3,}, 1441 {4, 2,}, 1442}; 1443 1444#define DITHER_SIZE ((sizeof orderedDither / sizeof orderedDither[0][0]) + 1) 1445 1446static int 1447ProcRenderCreateCursor(ClientPtr client) 1448{ 1449 REQUEST(xRenderCreateCursorReq); 1450 PicturePtr pSrc; 1451 ScreenPtr pScreen; 1452 unsigned short width, height; 1453 CARD32 *argbbits, *argb; 1454 unsigned char *srcbits, *srcline; 1455 unsigned char *mskbits, *mskline; 1456 int stride; 1457 int x, y; 1458 int nbytes_mono; 1459 CursorMetricRec cm; 1460 CursorPtr pCursor; 1461 CARD32 twocolor[3]; 1462 int rc, ncolor; 1463 1464 REQUEST_SIZE_MATCH(xRenderCreateCursorReq); 1465 LEGAL_NEW_RESOURCE(stuff->cid, client); 1466 1467 VERIFY_PICTURE(pSrc, stuff->src, client, DixReadAccess); 1468 if (!pSrc->pDrawable) 1469 return BadDrawable; 1470 pScreen = pSrc->pDrawable->pScreen; 1471 width = pSrc->pDrawable->width; 1472 height = pSrc->pDrawable->height; 1473 if (height && width > UINT32_MAX / (height * sizeof(CARD32))) 1474 return BadAlloc; 1475 if (stuff->x > width || stuff->y > height) 1476 return BadMatch; 1477 argbbits = malloc(width * height * sizeof(CARD32)); 1478 if (!argbbits) 1479 return BadAlloc; 1480 1481 stride = BitmapBytePad(width); 1482 nbytes_mono = stride * height; 1483 srcbits = calloc(1, nbytes_mono); 1484 if (!srcbits) { 1485 free(argbbits); 1486 return BadAlloc; 1487 } 1488 mskbits = calloc(1, nbytes_mono); 1489 if (!mskbits) { 1490 free(argbbits); 1491 free(srcbits); 1492 return BadAlloc; 1493 } 1494 1495 /* what kind of maniac creates a cursor from a window picture though */ 1496 if (pSrc->pDrawable->type == DRAWABLE_WINDOW) 1497 pScreen->SourceValidate(pSrc->pDrawable, 0, 0, width, height, 1498 IncludeInferiors); 1499 1500 if (pSrc->format == PICT_a8r8g8b8) { 1501 (*pScreen->GetImage) (pSrc->pDrawable, 1502 0, 0, width, height, ZPixmap, 1503 0xffffffff, (void *) argbbits); 1504 } 1505 else { 1506 PixmapPtr pPixmap; 1507 PicturePtr pPicture; 1508 PictFormatPtr pFormat; 1509 int error; 1510 1511 pFormat = PictureMatchFormat(pScreen, 32, PICT_a8r8g8b8); 1512 if (!pFormat) { 1513 free(argbbits); 1514 free(srcbits); 1515 free(mskbits); 1516 return BadImplementation; 1517 } 1518 pPixmap = (*pScreen->CreatePixmap) (pScreen, width, height, 32, 1519 CREATE_PIXMAP_USAGE_SCRATCH); 1520 if (!pPixmap) { 1521 free(argbbits); 1522 free(srcbits); 1523 free(mskbits); 1524 return BadAlloc; 1525 } 1526 pPicture = CreatePicture(0, &pPixmap->drawable, pFormat, 0, 0, 1527 client, &error); 1528 if (!pPicture) { 1529 free(argbbits); 1530 free(srcbits); 1531 free(mskbits); 1532 return error; 1533 } 1534 (*pScreen->DestroyPixmap) (pPixmap); 1535 CompositePicture(PictOpSrc, 1536 pSrc, 0, pPicture, 0, 0, 0, 0, 0, 0, width, height); 1537 (*pScreen->GetImage) (pPicture->pDrawable, 1538 0, 0, width, height, ZPixmap, 1539 0xffffffff, (void *) argbbits); 1540 FreePicture(pPicture, 0); 1541 } 1542 /* 1543 * Check whether the cursor can be directly supported by 1544 * the core cursor code 1545 */ 1546 ncolor = 0; 1547 argb = argbbits; 1548 for (y = 0; ncolor <= 2 && y < height; y++) { 1549 for (x = 0; ncolor <= 2 && x < width; x++) { 1550 CARD32 p = *argb++; 1551 CARD32 a = (p >> 24); 1552 1553 if (a == 0) /* transparent */ 1554 continue; 1555 if (a == 0xff) { /* opaque */ 1556 int n; 1557 1558 for (n = 0; n < ncolor; n++) 1559 if (p == twocolor[n]) 1560 break; 1561 if (n == ncolor) 1562 twocolor[ncolor++] = p; 1563 } 1564 else 1565 ncolor = 3; 1566 } 1567 } 1568 1569 /* 1570 * Convert argb image to two plane cursor 1571 */ 1572 srcline = srcbits; 1573 mskline = mskbits; 1574 argb = argbbits; 1575 for (y = 0; y < height; y++) { 1576 for (x = 0; x < width; x++) { 1577 CARD32 p = *argb++; 1578 1579 if (ncolor <= 2) { 1580 CARD32 a = ((p >> 24)); 1581 1582 RenderSetBit(mskline, x, a != 0); 1583 RenderSetBit(srcline, x, a != 0 && p == twocolor[0]); 1584 } 1585 else { 1586 CARD32 a = ((p >> 24) * DITHER_SIZE + 127) / 255; 1587 CARD32 i = ((CvtR8G8B8toY15(p) >> 7) * DITHER_SIZE + 127) / 255; 1588 CARD32 d = 1589 orderedDither[y & (DITHER_DIM - 1)][x & (DITHER_DIM - 1)]; 1590 /* Set mask from dithered alpha value */ 1591 RenderSetBit(mskline, x, a > d); 1592 /* Set src from dithered intensity value */ 1593 RenderSetBit(srcline, x, a > d && i <= d); 1594 } 1595 } 1596 srcline += stride; 1597 mskline += stride; 1598 } 1599 /* 1600 * Dither to white and black if the cursor has more than two colors 1601 */ 1602 if (ncolor > 2) { 1603 twocolor[0] = 0xff000000; 1604 twocolor[1] = 0xffffffff; 1605 } 1606 else { 1607 free(argbbits); 1608 argbbits = 0; 1609 } 1610 1611#define GetByte(p,s) (((p) >> (s)) & 0xff) 1612#define GetColor(p,s) (GetByte(p,s) | (GetByte(p,s) << 8)) 1613 1614 cm.width = width; 1615 cm.height = height; 1616 cm.xhot = stuff->x; 1617 cm.yhot = stuff->y; 1618 rc = AllocARGBCursor(srcbits, mskbits, argbbits, &cm, 1619 GetColor(twocolor[0], 16), 1620 GetColor(twocolor[0], 8), 1621 GetColor(twocolor[0], 0), 1622 GetColor(twocolor[1], 16), 1623 GetColor(twocolor[1], 8), 1624 GetColor(twocolor[1], 0), 1625 &pCursor, client, stuff->cid); 1626 if (rc != Success) 1627 goto bail; 1628 if (!AddResource(stuff->cid, RT_CURSOR, (void *) pCursor)) { 1629 rc = BadAlloc; 1630 goto bail; 1631 } 1632 1633 return Success; 1634 bail: 1635 free(srcbits); 1636 free(mskbits); 1637 return rc; 1638} 1639 1640static int 1641ProcRenderSetPictureTransform(ClientPtr client) 1642{ 1643 REQUEST(xRenderSetPictureTransformReq); 1644 PicturePtr pPicture; 1645 1646 REQUEST_SIZE_MATCH(xRenderSetPictureTransformReq); 1647 VERIFY_PICTURE(pPicture, stuff->picture, client, DixSetAttrAccess); 1648 return SetPictureTransform(pPicture, (PictTransform *) &stuff->transform); 1649} 1650 1651static int 1652ProcRenderQueryFilters(ClientPtr client) 1653{ 1654 REQUEST(xRenderQueryFiltersReq); 1655 DrawablePtr pDrawable; 1656 xRenderQueryFiltersReply *reply; 1657 int nbytesName; 1658 int nnames; 1659 ScreenPtr pScreen; 1660 PictureScreenPtr ps; 1661 int i, j, len, total_bytes, rc; 1662 INT16 *aliases; 1663 char *names; 1664 1665 REQUEST_SIZE_MATCH(xRenderQueryFiltersReq); 1666 rc = dixLookupDrawable(&pDrawable, stuff->drawable, client, 0, 1667 DixGetAttrAccess); 1668 if (rc != Success) 1669 return rc; 1670 1671 pScreen = pDrawable->pScreen; 1672 nbytesName = 0; 1673 nnames = 0; 1674 ps = GetPictureScreenIfSet(pScreen); 1675 if (ps) { 1676 for (i = 0; i < ps->nfilters; i++) 1677 nbytesName += 1 + strlen(ps->filters[i].name); 1678 for (i = 0; i < ps->nfilterAliases; i++) 1679 nbytesName += 1 + strlen(ps->filterAliases[i].alias); 1680 nnames = ps->nfilters + ps->nfilterAliases; 1681 } 1682 len = ((nnames + 1) >> 1) + bytes_to_int32(nbytesName); 1683 total_bytes = sizeof(xRenderQueryFiltersReply) + (len << 2); 1684 reply = (xRenderQueryFiltersReply *) calloc(1, total_bytes); 1685 if (!reply) 1686 return BadAlloc; 1687 aliases = (INT16 *) (reply + 1); 1688 names = (char *) (aliases + ((nnames + 1) & ~1)); 1689 1690 reply->type = X_Reply; 1691 reply->sequenceNumber = client->sequence; 1692 reply->length = len; 1693 reply->numAliases = nnames; 1694 reply->numFilters = nnames; 1695 if (ps) { 1696 1697 /* fill in alias values */ 1698 for (i = 0; i < ps->nfilters; i++) 1699 aliases[i] = FilterAliasNone; 1700 for (i = 0; i < ps->nfilterAliases; i++) { 1701 for (j = 0; j < ps->nfilters; j++) 1702 if (ps->filterAliases[i].filter_id == ps->filters[j].id) 1703 break; 1704 if (j == ps->nfilters) { 1705 for (j = 0; j < ps->nfilterAliases; j++) 1706 if (ps->filterAliases[i].filter_id == 1707 ps->filterAliases[j].alias_id) { 1708 break; 1709 } 1710 if (j == ps->nfilterAliases) 1711 j = FilterAliasNone; 1712 else 1713 j = j + ps->nfilters; 1714 } 1715 aliases[i + ps->nfilters] = j; 1716 } 1717 1718 /* fill in filter names */ 1719 for (i = 0; i < ps->nfilters; i++) { 1720 j = strlen(ps->filters[i].name); 1721 *names++ = j; 1722 memcpy(names, ps->filters[i].name, j); 1723 names += j; 1724 } 1725 1726 /* fill in filter alias names */ 1727 for (i = 0; i < ps->nfilterAliases; i++) { 1728 j = strlen(ps->filterAliases[i].alias); 1729 *names++ = j; 1730 memcpy(names, ps->filterAliases[i].alias, j); 1731 names += j; 1732 } 1733 } 1734 1735 if (client->swapped) { 1736 for (i = 0; i < reply->numAliases; i++) { 1737 swaps(&aliases[i]); 1738 } 1739 swaps(&reply->sequenceNumber); 1740 swapl(&reply->length); 1741 swapl(&reply->numAliases); 1742 swapl(&reply->numFilters); 1743 } 1744 WriteToClient(client, total_bytes, reply); 1745 free(reply); 1746 1747 return Success; 1748} 1749 1750static int 1751ProcRenderSetPictureFilter(ClientPtr client) 1752{ 1753 REQUEST(xRenderSetPictureFilterReq); 1754 PicturePtr pPicture; 1755 int result; 1756 xFixed *params; 1757 int nparams; 1758 char *name; 1759 1760 REQUEST_AT_LEAST_SIZE(xRenderSetPictureFilterReq); 1761 VERIFY_PICTURE(pPicture, stuff->picture, client, DixSetAttrAccess); 1762 name = (char *) (stuff + 1); 1763 params = (xFixed *) (name + pad_to_int32(stuff->nbytes)); 1764 nparams = ((xFixed *) stuff + client->req_len) - params; 1765 if (nparams < 0) 1766 return BadLength; 1767 1768 result = SetPictureFilter(pPicture, name, stuff->nbytes, params, nparams); 1769 return result; 1770} 1771 1772static int 1773ProcRenderCreateAnimCursor(ClientPtr client) 1774{ 1775 REQUEST(xRenderCreateAnimCursorReq); 1776 CursorPtr *cursors; 1777 CARD32 *deltas; 1778 CursorPtr pCursor; 1779 int ncursor; 1780 xAnimCursorElt *elt; 1781 int i; 1782 int ret; 1783 1784 REQUEST_AT_LEAST_SIZE(xRenderCreateAnimCursorReq); 1785 LEGAL_NEW_RESOURCE(stuff->cid, client); 1786 if (client->req_len & 1) 1787 return BadLength; 1788 ncursor = 1789 (client->req_len - 1790 (bytes_to_int32(sizeof(xRenderCreateAnimCursorReq)))) >> 1; 1791 cursors = xallocarray(ncursor, sizeof(CursorPtr) + sizeof(CARD32)); 1792 if (!cursors) 1793 return BadAlloc; 1794 deltas = (CARD32 *) (cursors + ncursor); 1795 elt = (xAnimCursorElt *) (stuff + 1); 1796 for (i = 0; i < ncursor; i++) { 1797 ret = dixLookupResourceByType((void **) (cursors + i), elt->cursor, 1798 RT_CURSOR, client, DixReadAccess); 1799 if (ret != Success) { 1800 free(cursors); 1801 return ret; 1802 } 1803 deltas[i] = elt->delay; 1804 elt++; 1805 } 1806 ret = AnimCursorCreate(cursors, deltas, ncursor, &pCursor, client, 1807 stuff->cid); 1808 free(cursors); 1809 if (ret != Success) 1810 return ret; 1811 1812 if (AddResource(stuff->cid, RT_CURSOR, (void *) pCursor)) 1813 return Success; 1814 return BadAlloc; 1815} 1816 1817static int 1818ProcRenderAddTraps(ClientPtr client) 1819{ 1820 int ntraps; 1821 PicturePtr pPicture; 1822 1823 REQUEST(xRenderAddTrapsReq); 1824 1825 REQUEST_AT_LEAST_SIZE(xRenderAddTrapsReq); 1826 VERIFY_PICTURE(pPicture, stuff->picture, client, DixWriteAccess); 1827 if (!pPicture->pDrawable) 1828 return BadDrawable; 1829 ntraps = (client->req_len << 2) - sizeof(xRenderAddTrapsReq); 1830 if (ntraps % sizeof(xTrap)) 1831 return BadLength; 1832 ntraps /= sizeof(xTrap); 1833 if (ntraps) 1834 AddTraps(pPicture, 1835 stuff->xOff, stuff->yOff, ntraps, (xTrap *) &stuff[1]); 1836 return Success; 1837} 1838 1839static int 1840ProcRenderCreateSolidFill(ClientPtr client) 1841{ 1842 PicturePtr pPicture; 1843 int error = 0; 1844 1845 REQUEST(xRenderCreateSolidFillReq); 1846 1847 REQUEST_AT_LEAST_SIZE(xRenderCreateSolidFillReq); 1848 1849 LEGAL_NEW_RESOURCE(stuff->pid, client); 1850 1851 pPicture = CreateSolidPicture(stuff->pid, &stuff->color, &error); 1852 if (!pPicture) 1853 return error; 1854 /* security creation/labeling check */ 1855 error = XaceHook(XACE_RESOURCE_ACCESS, client, stuff->pid, PictureType, 1856 pPicture, RT_NONE, NULL, DixCreateAccess); 1857 if (error != Success) 1858 return error; 1859 if (!AddResource(stuff->pid, PictureType, (void *) pPicture)) 1860 return BadAlloc; 1861 return Success; 1862} 1863 1864static int 1865ProcRenderCreateLinearGradient(ClientPtr client) 1866{ 1867 PicturePtr pPicture; 1868 int len; 1869 int error = 0; 1870 xFixed *stops; 1871 xRenderColor *colors; 1872 1873 REQUEST(xRenderCreateLinearGradientReq); 1874 1875 REQUEST_AT_LEAST_SIZE(xRenderCreateLinearGradientReq); 1876 1877 LEGAL_NEW_RESOURCE(stuff->pid, client); 1878 1879 len = (client->req_len << 2) - sizeof(xRenderCreateLinearGradientReq); 1880 if (stuff->nStops > UINT32_MAX / (sizeof(xFixed) + sizeof(xRenderColor))) 1881 return BadLength; 1882 if (len != stuff->nStops * (sizeof(xFixed) + sizeof(xRenderColor))) 1883 return BadLength; 1884 1885 stops = (xFixed *) (stuff + 1); 1886 colors = (xRenderColor *) (stops + stuff->nStops); 1887 1888 pPicture = CreateLinearGradientPicture(stuff->pid, &stuff->p1, &stuff->p2, 1889 stuff->nStops, stops, colors, 1890 &error); 1891 if (!pPicture) 1892 return error; 1893 /* security creation/labeling check */ 1894 error = XaceHook(XACE_RESOURCE_ACCESS, client, stuff->pid, PictureType, 1895 pPicture, RT_NONE, NULL, DixCreateAccess); 1896 if (error != Success) 1897 return error; 1898 if (!AddResource(stuff->pid, PictureType, (void *) pPicture)) 1899 return BadAlloc; 1900 return Success; 1901} 1902 1903static int 1904ProcRenderCreateRadialGradient(ClientPtr client) 1905{ 1906 PicturePtr pPicture; 1907 int len; 1908 int error = 0; 1909 xFixed *stops; 1910 xRenderColor *colors; 1911 1912 REQUEST(xRenderCreateRadialGradientReq); 1913 1914 REQUEST_AT_LEAST_SIZE(xRenderCreateRadialGradientReq); 1915 1916 LEGAL_NEW_RESOURCE(stuff->pid, client); 1917 1918 len = (client->req_len << 2) - sizeof(xRenderCreateRadialGradientReq); 1919 if (stuff->nStops > UINT32_MAX / (sizeof(xFixed) + sizeof(xRenderColor))) 1920 return BadLength; 1921 if (len != stuff->nStops * (sizeof(xFixed) + sizeof(xRenderColor))) 1922 return BadLength; 1923 1924 stops = (xFixed *) (stuff + 1); 1925 colors = (xRenderColor *) (stops + stuff->nStops); 1926 1927 pPicture = 1928 CreateRadialGradientPicture(stuff->pid, &stuff->inner, &stuff->outer, 1929 stuff->inner_radius, stuff->outer_radius, 1930 stuff->nStops, stops, colors, &error); 1931 if (!pPicture) 1932 return error; 1933 /* security creation/labeling check */ 1934 error = XaceHook(XACE_RESOURCE_ACCESS, client, stuff->pid, PictureType, 1935 pPicture, RT_NONE, NULL, DixCreateAccess); 1936 if (error != Success) 1937 return error; 1938 if (!AddResource(stuff->pid, PictureType, (void *) pPicture)) 1939 return BadAlloc; 1940 return Success; 1941} 1942 1943static int 1944ProcRenderCreateConicalGradient(ClientPtr client) 1945{ 1946 PicturePtr pPicture; 1947 int len; 1948 int error = 0; 1949 xFixed *stops; 1950 xRenderColor *colors; 1951 1952 REQUEST(xRenderCreateConicalGradientReq); 1953 1954 REQUEST_AT_LEAST_SIZE(xRenderCreateConicalGradientReq); 1955 1956 LEGAL_NEW_RESOURCE(stuff->pid, client); 1957 1958 len = (client->req_len << 2) - sizeof(xRenderCreateConicalGradientReq); 1959 if (stuff->nStops > UINT32_MAX / (sizeof(xFixed) + sizeof(xRenderColor))) 1960 return BadLength; 1961 if (len != stuff->nStops * (sizeof(xFixed) + sizeof(xRenderColor))) 1962 return BadLength; 1963 1964 stops = (xFixed *) (stuff + 1); 1965 colors = (xRenderColor *) (stops + stuff->nStops); 1966 1967 pPicture = 1968 CreateConicalGradientPicture(stuff->pid, &stuff->center, stuff->angle, 1969 stuff->nStops, stops, colors, &error); 1970 if (!pPicture) 1971 return error; 1972 /* security creation/labeling check */ 1973 error = XaceHook(XACE_RESOURCE_ACCESS, client, stuff->pid, PictureType, 1974 pPicture, RT_NONE, NULL, DixCreateAccess); 1975 if (error != Success) 1976 return error; 1977 if (!AddResource(stuff->pid, PictureType, (void *) pPicture)) 1978 return BadAlloc; 1979 return Success; 1980} 1981 1982static int 1983ProcRenderDispatch(ClientPtr client) 1984{ 1985 REQUEST(xReq); 1986 1987 if (stuff->data < RenderNumberRequests) 1988 return (*ProcRenderVector[stuff->data]) (client); 1989 else 1990 return BadRequest; 1991} 1992 1993static int _X_COLD 1994SProcRenderQueryVersion(ClientPtr client) 1995{ 1996 REQUEST(xRenderQueryVersionReq); 1997 REQUEST_SIZE_MATCH(xRenderQueryVersionReq); 1998 swaps(&stuff->length); 1999 swapl(&stuff->majorVersion); 2000 swapl(&stuff->minorVersion); 2001 return (*ProcRenderVector[stuff->renderReqType]) (client); 2002} 2003 2004static int _X_COLD 2005SProcRenderQueryPictFormats(ClientPtr client) 2006{ 2007 REQUEST(xRenderQueryPictFormatsReq); 2008 REQUEST_SIZE_MATCH(xRenderQueryPictFormatsReq); 2009 swaps(&stuff->length); 2010 return (*ProcRenderVector[stuff->renderReqType]) (client); 2011} 2012 2013static int _X_COLD 2014SProcRenderQueryPictIndexValues(ClientPtr client) 2015{ 2016 REQUEST(xRenderQueryPictIndexValuesReq); 2017 REQUEST_AT_LEAST_SIZE(xRenderQueryPictIndexValuesReq); 2018 swaps(&stuff->length); 2019 swapl(&stuff->format); 2020 return (*ProcRenderVector[stuff->renderReqType]) (client); 2021} 2022 2023static int _X_COLD 2024SProcRenderQueryDithers(ClientPtr client) 2025{ 2026 return BadImplementation; 2027} 2028 2029static int _X_COLD 2030SProcRenderCreatePicture(ClientPtr client) 2031{ 2032 REQUEST(xRenderCreatePictureReq); 2033 REQUEST_AT_LEAST_SIZE(xRenderCreatePictureReq); 2034 swaps(&stuff->length); 2035 swapl(&stuff->pid); 2036 swapl(&stuff->drawable); 2037 swapl(&stuff->format); 2038 swapl(&stuff->mask); 2039 SwapRestL(stuff); 2040 return (*ProcRenderVector[stuff->renderReqType]) (client); 2041} 2042 2043static int _X_COLD 2044SProcRenderChangePicture(ClientPtr client) 2045{ 2046 REQUEST(xRenderChangePictureReq); 2047 REQUEST_AT_LEAST_SIZE(xRenderChangePictureReq); 2048 swaps(&stuff->length); 2049 swapl(&stuff->picture); 2050 swapl(&stuff->mask); 2051 SwapRestL(stuff); 2052 return (*ProcRenderVector[stuff->renderReqType]) (client); 2053} 2054 2055static int _X_COLD 2056SProcRenderSetPictureClipRectangles(ClientPtr client) 2057{ 2058 REQUEST(xRenderSetPictureClipRectanglesReq); 2059 REQUEST_AT_LEAST_SIZE(xRenderSetPictureClipRectanglesReq); 2060 swaps(&stuff->length); 2061 swapl(&stuff->picture); 2062 swaps(&stuff->xOrigin); 2063 swaps(&stuff->yOrigin); 2064 SwapRestS(stuff); 2065 return (*ProcRenderVector[stuff->renderReqType]) (client); 2066} 2067 2068static int _X_COLD 2069SProcRenderFreePicture(ClientPtr client) 2070{ 2071 REQUEST(xRenderFreePictureReq); 2072 REQUEST_SIZE_MATCH(xRenderFreePictureReq); 2073 swaps(&stuff->length); 2074 swapl(&stuff->picture); 2075 return (*ProcRenderVector[stuff->renderReqType]) (client); 2076} 2077 2078static int _X_COLD 2079SProcRenderComposite(ClientPtr client) 2080{ 2081 REQUEST(xRenderCompositeReq); 2082 REQUEST_SIZE_MATCH(xRenderCompositeReq); 2083 swaps(&stuff->length); 2084 swapl(&stuff->src); 2085 swapl(&stuff->mask); 2086 swapl(&stuff->dst); 2087 swaps(&stuff->xSrc); 2088 swaps(&stuff->ySrc); 2089 swaps(&stuff->xMask); 2090 swaps(&stuff->yMask); 2091 swaps(&stuff->xDst); 2092 swaps(&stuff->yDst); 2093 swaps(&stuff->width); 2094 swaps(&stuff->height); 2095 return (*ProcRenderVector[stuff->renderReqType]) (client); 2096} 2097 2098static int _X_COLD 2099SProcRenderScale(ClientPtr client) 2100{ 2101 return BadImplementation; 2102} 2103 2104static int _X_COLD 2105SProcRenderTrapezoids(ClientPtr client) 2106{ 2107 REQUEST(xRenderTrapezoidsReq); 2108 2109 REQUEST_AT_LEAST_SIZE(xRenderTrapezoidsReq); 2110 swaps(&stuff->length); 2111 swapl(&stuff->src); 2112 swapl(&stuff->dst); 2113 swapl(&stuff->maskFormat); 2114 swaps(&stuff->xSrc); 2115 swaps(&stuff->ySrc); 2116 SwapRestL(stuff); 2117 return (*ProcRenderVector[stuff->renderReqType]) (client); 2118} 2119 2120static int _X_COLD 2121SProcRenderTriangles(ClientPtr client) 2122{ 2123 REQUEST(xRenderTrianglesReq); 2124 2125 REQUEST_AT_LEAST_SIZE(xRenderTrianglesReq); 2126 swaps(&stuff->length); 2127 swapl(&stuff->src); 2128 swapl(&stuff->dst); 2129 swapl(&stuff->maskFormat); 2130 swaps(&stuff->xSrc); 2131 swaps(&stuff->ySrc); 2132 SwapRestL(stuff); 2133 return (*ProcRenderVector[stuff->renderReqType]) (client); 2134} 2135 2136static int _X_COLD 2137SProcRenderTriStrip(ClientPtr client) 2138{ 2139 REQUEST(xRenderTriStripReq); 2140 2141 REQUEST_AT_LEAST_SIZE(xRenderTriStripReq); 2142 swaps(&stuff->length); 2143 swapl(&stuff->src); 2144 swapl(&stuff->dst); 2145 swapl(&stuff->maskFormat); 2146 swaps(&stuff->xSrc); 2147 swaps(&stuff->ySrc); 2148 SwapRestL(stuff); 2149 return (*ProcRenderVector[stuff->renderReqType]) (client); 2150} 2151 2152static int _X_COLD 2153SProcRenderTriFan(ClientPtr client) 2154{ 2155 REQUEST(xRenderTriFanReq); 2156 2157 REQUEST_AT_LEAST_SIZE(xRenderTriFanReq); 2158 swaps(&stuff->length); 2159 swapl(&stuff->src); 2160 swapl(&stuff->dst); 2161 swapl(&stuff->maskFormat); 2162 swaps(&stuff->xSrc); 2163 swaps(&stuff->ySrc); 2164 SwapRestL(stuff); 2165 return (*ProcRenderVector[stuff->renderReqType]) (client); 2166} 2167 2168static int _X_COLD 2169SProcRenderColorTrapezoids(ClientPtr client) 2170{ 2171 return BadImplementation; 2172} 2173 2174static int _X_COLD 2175SProcRenderColorTriangles(ClientPtr client) 2176{ 2177 return BadImplementation; 2178} 2179 2180static int _X_COLD 2181SProcRenderTransform(ClientPtr client) 2182{ 2183 return BadImplementation; 2184} 2185 2186static int _X_COLD 2187SProcRenderCreateGlyphSet(ClientPtr client) 2188{ 2189 REQUEST(xRenderCreateGlyphSetReq); 2190 REQUEST_SIZE_MATCH(xRenderCreateGlyphSetReq); 2191 swaps(&stuff->length); 2192 swapl(&stuff->gsid); 2193 swapl(&stuff->format); 2194 return (*ProcRenderVector[stuff->renderReqType]) (client); 2195} 2196 2197static int _X_COLD 2198SProcRenderReferenceGlyphSet(ClientPtr client) 2199{ 2200 REQUEST(xRenderReferenceGlyphSetReq); 2201 REQUEST_SIZE_MATCH(xRenderReferenceGlyphSetReq); 2202 swaps(&stuff->length); 2203 swapl(&stuff->gsid); 2204 swapl(&stuff->existing); 2205 return (*ProcRenderVector[stuff->renderReqType]) (client); 2206} 2207 2208static int _X_COLD 2209SProcRenderFreeGlyphSet(ClientPtr client) 2210{ 2211 REQUEST(xRenderFreeGlyphSetReq); 2212 REQUEST_SIZE_MATCH(xRenderFreeGlyphSetReq); 2213 swaps(&stuff->length); 2214 swapl(&stuff->glyphset); 2215 return (*ProcRenderVector[stuff->renderReqType]) (client); 2216} 2217 2218static int _X_COLD 2219SProcRenderAddGlyphs(ClientPtr client) 2220{ 2221 register int i; 2222 CARD32 *gids; 2223 void *end; 2224 xGlyphInfo *gi; 2225 2226 REQUEST(xRenderAddGlyphsReq); 2227 REQUEST_AT_LEAST_SIZE(xRenderAddGlyphsReq); 2228 swaps(&stuff->length); 2229 swapl(&stuff->glyphset); 2230 swapl(&stuff->nglyphs); 2231 if (stuff->nglyphs & 0xe0000000) 2232 return BadLength; 2233 end = (CARD8 *) stuff + (client->req_len << 2); 2234 gids = (CARD32 *) (stuff + 1); 2235 gi = (xGlyphInfo *) (gids + stuff->nglyphs); 2236 if ((char *) end - (char *) (gids + stuff->nglyphs) < 0) 2237 return BadLength; 2238 if ((char *) end - (char *) (gi + stuff->nglyphs) < 0) 2239 return BadLength; 2240 for (i = 0; i < stuff->nglyphs; i++) { 2241 swapl(&gids[i]); 2242 swaps(&gi[i].width); 2243 swaps(&gi[i].height); 2244 swaps(&gi[i].x); 2245 swaps(&gi[i].y); 2246 swaps(&gi[i].xOff); 2247 swaps(&gi[i].yOff); 2248 } 2249 return (*ProcRenderVector[stuff->renderReqType]) (client); 2250} 2251 2252static int _X_COLD 2253SProcRenderAddGlyphsFromPicture(ClientPtr client) 2254{ 2255 return BadImplementation; 2256} 2257 2258static int _X_COLD 2259SProcRenderFreeGlyphs(ClientPtr client) 2260{ 2261 REQUEST(xRenderFreeGlyphsReq); 2262 REQUEST_AT_LEAST_SIZE(xRenderFreeGlyphsReq); 2263 swaps(&stuff->length); 2264 swapl(&stuff->glyphset); 2265 SwapRestL(stuff); 2266 return (*ProcRenderVector[stuff->renderReqType]) (client); 2267} 2268 2269static int _X_COLD 2270SProcRenderCompositeGlyphs(ClientPtr client) 2271{ 2272 xGlyphElt *elt; 2273 CARD8 *buffer; 2274 CARD8 *end; 2275 int space; 2276 int i; 2277 int size; 2278 2279 REQUEST(xRenderCompositeGlyphsReq); 2280 REQUEST_AT_LEAST_SIZE(xRenderCompositeGlyphsReq); 2281 2282 switch (stuff->renderReqType) { 2283 default: 2284 size = 1; 2285 break; 2286 case X_RenderCompositeGlyphs16: 2287 size = 2; 2288 break; 2289 case X_RenderCompositeGlyphs32: 2290 size = 4; 2291 break; 2292 } 2293 2294 swaps(&stuff->length); 2295 swapl(&stuff->src); 2296 swapl(&stuff->dst); 2297 swapl(&stuff->maskFormat); 2298 swapl(&stuff->glyphset); 2299 swaps(&stuff->xSrc); 2300 swaps(&stuff->ySrc); 2301 buffer = (CARD8 *) (stuff + 1); 2302 end = (CARD8 *) stuff + (client->req_len << 2); 2303 while (buffer + sizeof(xGlyphElt) < end) { 2304 elt = (xGlyphElt *) buffer; 2305 buffer += sizeof(xGlyphElt); 2306 2307 swaps(&elt->deltax); 2308 swaps(&elt->deltay); 2309 2310 i = elt->len; 2311 if (i == 0xff) { 2312 swapl((int *) buffer); 2313 buffer += 4; 2314 } 2315 else { 2316 space = size * i; 2317 switch (size) { 2318 case 1: 2319 buffer += i; 2320 break; 2321 case 2: 2322 while (i--) { 2323 swaps((short *) buffer); 2324 buffer += 2; 2325 } 2326 break; 2327 case 4: 2328 while (i--) { 2329 swapl((int *) buffer); 2330 buffer += 4; 2331 } 2332 break; 2333 } 2334 if (space & 3) 2335 buffer += 4 - (space & 3); 2336 } 2337 } 2338 return (*ProcRenderVector[stuff->renderReqType]) (client); 2339} 2340 2341static int _X_COLD 2342SProcRenderFillRectangles(ClientPtr client) 2343{ 2344 REQUEST(xRenderFillRectanglesReq); 2345 2346 REQUEST_AT_LEAST_SIZE(xRenderFillRectanglesReq); 2347 swaps(&stuff->length); 2348 swapl(&stuff->dst); 2349 swaps(&stuff->color.red); 2350 swaps(&stuff->color.green); 2351 swaps(&stuff->color.blue); 2352 swaps(&stuff->color.alpha); 2353 SwapRestS(stuff); 2354 return (*ProcRenderVector[stuff->renderReqType]) (client); 2355} 2356 2357static int _X_COLD 2358SProcRenderCreateCursor(ClientPtr client) 2359{ 2360 REQUEST(xRenderCreateCursorReq); 2361 REQUEST_SIZE_MATCH(xRenderCreateCursorReq); 2362 2363 swaps(&stuff->length); 2364 swapl(&stuff->cid); 2365 swapl(&stuff->src); 2366 swaps(&stuff->x); 2367 swaps(&stuff->y); 2368 return (*ProcRenderVector[stuff->renderReqType]) (client); 2369} 2370 2371static int _X_COLD 2372SProcRenderSetPictureTransform(ClientPtr client) 2373{ 2374 REQUEST(xRenderSetPictureTransformReq); 2375 REQUEST_SIZE_MATCH(xRenderSetPictureTransformReq); 2376 2377 swaps(&stuff->length); 2378 swapl(&stuff->picture); 2379 swapl(&stuff->transform.matrix11); 2380 swapl(&stuff->transform.matrix12); 2381 swapl(&stuff->transform.matrix13); 2382 swapl(&stuff->transform.matrix21); 2383 swapl(&stuff->transform.matrix22); 2384 swapl(&stuff->transform.matrix23); 2385 swapl(&stuff->transform.matrix31); 2386 swapl(&stuff->transform.matrix32); 2387 swapl(&stuff->transform.matrix33); 2388 return (*ProcRenderVector[stuff->renderReqType]) (client); 2389} 2390 2391static int _X_COLD 2392SProcRenderQueryFilters(ClientPtr client) 2393{ 2394 REQUEST(xRenderQueryFiltersReq); 2395 REQUEST_SIZE_MATCH(xRenderQueryFiltersReq); 2396 2397 swaps(&stuff->length); 2398 swapl(&stuff->drawable); 2399 return (*ProcRenderVector[stuff->renderReqType]) (client); 2400} 2401 2402static int _X_COLD 2403SProcRenderSetPictureFilter(ClientPtr client) 2404{ 2405 REQUEST(xRenderSetPictureFilterReq); 2406 REQUEST_AT_LEAST_SIZE(xRenderSetPictureFilterReq); 2407 2408 swaps(&stuff->length); 2409 swapl(&stuff->picture); 2410 swaps(&stuff->nbytes); 2411 return (*ProcRenderVector[stuff->renderReqType]) (client); 2412} 2413 2414static int _X_COLD 2415SProcRenderCreateAnimCursor(ClientPtr client) 2416{ 2417 REQUEST(xRenderCreateAnimCursorReq); 2418 REQUEST_AT_LEAST_SIZE(xRenderCreateAnimCursorReq); 2419 2420 swaps(&stuff->length); 2421 swapl(&stuff->cid); 2422 SwapRestL(stuff); 2423 return (*ProcRenderVector[stuff->renderReqType]) (client); 2424} 2425 2426static int _X_COLD 2427SProcRenderAddTraps(ClientPtr client) 2428{ 2429 REQUEST(xRenderAddTrapsReq); 2430 REQUEST_AT_LEAST_SIZE(xRenderAddTrapsReq); 2431 2432 swaps(&stuff->length); 2433 swapl(&stuff->picture); 2434 swaps(&stuff->xOff); 2435 swaps(&stuff->yOff); 2436 SwapRestL(stuff); 2437 return (*ProcRenderVector[stuff->renderReqType]) (client); 2438} 2439 2440static int _X_COLD 2441SProcRenderCreateSolidFill(ClientPtr client) 2442{ 2443 REQUEST(xRenderCreateSolidFillReq); 2444 REQUEST_AT_LEAST_SIZE(xRenderCreateSolidFillReq); 2445 2446 swaps(&stuff->length); 2447 swapl(&stuff->pid); 2448 swaps(&stuff->color.alpha); 2449 swaps(&stuff->color.red); 2450 swaps(&stuff->color.green); 2451 swaps(&stuff->color.blue); 2452 return (*ProcRenderVector[stuff->renderReqType]) (client); 2453} 2454 2455static void _X_COLD 2456swapStops(void *stuff, int num) 2457{ 2458 int i; 2459 CARD32 *stops; 2460 CARD16 *colors; 2461 2462 stops = (CARD32 *) (stuff); 2463 for (i = 0; i < num; ++i) { 2464 swapl(stops); 2465 ++stops; 2466 } 2467 colors = (CARD16 *) (stops); 2468 for (i = 0; i < 4 * num; ++i) { 2469 swaps(colors); 2470 ++colors; 2471 } 2472} 2473 2474static int _X_COLD 2475SProcRenderCreateLinearGradient(ClientPtr client) 2476{ 2477 int len; 2478 2479 REQUEST(xRenderCreateLinearGradientReq); 2480 REQUEST_AT_LEAST_SIZE(xRenderCreateLinearGradientReq); 2481 2482 swaps(&stuff->length); 2483 swapl(&stuff->pid); 2484 swapl(&stuff->p1.x); 2485 swapl(&stuff->p1.y); 2486 swapl(&stuff->p2.x); 2487 swapl(&stuff->p2.y); 2488 swapl(&stuff->nStops); 2489 2490 len = (client->req_len << 2) - sizeof(xRenderCreateLinearGradientReq); 2491 if (stuff->nStops > UINT32_MAX / (sizeof(xFixed) + sizeof(xRenderColor))) 2492 return BadLength; 2493 if (len != stuff->nStops * (sizeof(xFixed) + sizeof(xRenderColor))) 2494 return BadLength; 2495 2496 swapStops(stuff + 1, stuff->nStops); 2497 2498 return (*ProcRenderVector[stuff->renderReqType]) (client); 2499} 2500 2501static int _X_COLD 2502SProcRenderCreateRadialGradient(ClientPtr client) 2503{ 2504 int len; 2505 2506 REQUEST(xRenderCreateRadialGradientReq); 2507 REQUEST_AT_LEAST_SIZE(xRenderCreateRadialGradientReq); 2508 2509 swaps(&stuff->length); 2510 swapl(&stuff->pid); 2511 swapl(&stuff->inner.x); 2512 swapl(&stuff->inner.y); 2513 swapl(&stuff->outer.x); 2514 swapl(&stuff->outer.y); 2515 swapl(&stuff->inner_radius); 2516 swapl(&stuff->outer_radius); 2517 swapl(&stuff->nStops); 2518 2519 len = (client->req_len << 2) - sizeof(xRenderCreateRadialGradientReq); 2520 if (stuff->nStops > UINT32_MAX / (sizeof(xFixed) + sizeof(xRenderColor))) 2521 return BadLength; 2522 if (len != stuff->nStops * (sizeof(xFixed) + sizeof(xRenderColor))) 2523 return BadLength; 2524 2525 swapStops(stuff + 1, stuff->nStops); 2526 2527 return (*ProcRenderVector[stuff->renderReqType]) (client); 2528} 2529 2530static int _X_COLD 2531SProcRenderCreateConicalGradient(ClientPtr client) 2532{ 2533 int len; 2534 2535 REQUEST(xRenderCreateConicalGradientReq); 2536 REQUEST_AT_LEAST_SIZE(xRenderCreateConicalGradientReq); 2537 2538 swaps(&stuff->length); 2539 swapl(&stuff->pid); 2540 swapl(&stuff->center.x); 2541 swapl(&stuff->center.y); 2542 swapl(&stuff->angle); 2543 swapl(&stuff->nStops); 2544 2545 len = (client->req_len << 2) - sizeof(xRenderCreateConicalGradientReq); 2546 if (stuff->nStops > UINT32_MAX / (sizeof(xFixed) + sizeof(xRenderColor))) 2547 return BadLength; 2548 if (len != stuff->nStops * (sizeof(xFixed) + sizeof(xRenderColor))) 2549 return BadLength; 2550 2551 swapStops(stuff + 1, stuff->nStops); 2552 2553 return (*ProcRenderVector[stuff->renderReqType]) (client); 2554} 2555 2556static int _X_COLD 2557SProcRenderDispatch(ClientPtr client) 2558{ 2559 REQUEST(xReq); 2560 2561 if (stuff->data < RenderNumberRequests) 2562 return (*SProcRenderVector[stuff->data]) (client); 2563 else 2564 return BadRequest; 2565} 2566 2567#ifdef PANORAMIX 2568#define VERIFY_XIN_PICTURE(pPicture, pid, client, mode) {\ 2569 int rc = dixLookupResourceByType((void **)&(pPicture), pid,\ 2570 XRT_PICTURE, client, mode);\ 2571 if (rc != Success)\ 2572 return rc;\ 2573} 2574 2575#define VERIFY_XIN_ALPHA(pPicture, pid, client, mode) {\ 2576 if (pid == None) \ 2577 pPicture = 0; \ 2578 else { \ 2579 VERIFY_XIN_PICTURE(pPicture, pid, client, mode); \ 2580 } \ 2581} \ 2582 2583int (*PanoramiXSaveRenderVector[RenderNumberRequests]) (ClientPtr); 2584 2585static int 2586PanoramiXRenderCreatePicture(ClientPtr client) 2587{ 2588 REQUEST(xRenderCreatePictureReq); 2589 PanoramiXRes *refDraw, *newPict; 2590 int result, j; 2591 2592 REQUEST_AT_LEAST_SIZE(xRenderCreatePictureReq); 2593 result = dixLookupResourceByClass((void **) &refDraw, stuff->drawable, 2594 XRC_DRAWABLE, client, DixWriteAccess); 2595 if (result != Success) 2596 return (result == BadValue) ? BadDrawable : result; 2597 if (!(newPict = (PanoramiXRes *) malloc(sizeof(PanoramiXRes)))) 2598 return BadAlloc; 2599 newPict->type = XRT_PICTURE; 2600 panoramix_setup_ids(newPict, client, stuff->pid); 2601 2602 if (refDraw->type == XRT_WINDOW && 2603 stuff->drawable == screenInfo.screens[0]->root->drawable.id) { 2604 newPict->u.pict.root = TRUE; 2605 } 2606 else 2607 newPict->u.pict.root = FALSE; 2608 2609 FOR_NSCREENS_BACKWARD(j) { 2610 stuff->pid = newPict->info[j].id; 2611 stuff->drawable = refDraw->info[j].id; 2612 result = (*PanoramiXSaveRenderVector[X_RenderCreatePicture]) (client); 2613 if (result != Success) 2614 break; 2615 } 2616 2617 if (result == Success) 2618 AddResource(newPict->info[0].id, XRT_PICTURE, newPict); 2619 else 2620 free(newPict); 2621 2622 return result; 2623} 2624 2625static int 2626PanoramiXRenderChangePicture(ClientPtr client) 2627{ 2628 PanoramiXRes *pict; 2629 int result = Success, j; 2630 2631 REQUEST(xRenderChangePictureReq); 2632 2633 REQUEST_AT_LEAST_SIZE(xRenderChangePictureReq); 2634 2635 VERIFY_XIN_PICTURE(pict, stuff->picture, client, DixWriteAccess); 2636 2637 FOR_NSCREENS_BACKWARD(j) { 2638 stuff->picture = pict->info[j].id; 2639 result = (*PanoramiXSaveRenderVector[X_RenderChangePicture]) (client); 2640 if (result != Success) 2641 break; 2642 } 2643 2644 return result; 2645} 2646 2647static int 2648PanoramiXRenderSetPictureClipRectangles(ClientPtr client) 2649{ 2650 REQUEST(xRenderSetPictureClipRectanglesReq); 2651 int result = Success, j; 2652 PanoramiXRes *pict; 2653 2654 REQUEST_AT_LEAST_SIZE(xRenderSetPictureClipRectanglesReq); 2655 2656 VERIFY_XIN_PICTURE(pict, stuff->picture, client, DixWriteAccess); 2657 2658 FOR_NSCREENS_BACKWARD(j) { 2659 stuff->picture = pict->info[j].id; 2660 result = 2661 (*PanoramiXSaveRenderVector[X_RenderSetPictureClipRectangles]) 2662 (client); 2663 if (result != Success) 2664 break; 2665 } 2666 2667 return result; 2668} 2669 2670static int 2671PanoramiXRenderSetPictureTransform(ClientPtr client) 2672{ 2673 REQUEST(xRenderSetPictureTransformReq); 2674 int result = Success, j; 2675 PanoramiXRes *pict; 2676 2677 REQUEST_AT_LEAST_SIZE(xRenderSetPictureTransformReq); 2678 2679 VERIFY_XIN_PICTURE(pict, stuff->picture, client, DixWriteAccess); 2680 2681 FOR_NSCREENS_BACKWARD(j) { 2682 stuff->picture = pict->info[j].id; 2683 result = 2684 (*PanoramiXSaveRenderVector[X_RenderSetPictureTransform]) (client); 2685 if (result != Success) 2686 break; 2687 } 2688 2689 return result; 2690} 2691 2692static int 2693PanoramiXRenderSetPictureFilter(ClientPtr client) 2694{ 2695 REQUEST(xRenderSetPictureFilterReq); 2696 int result = Success, j; 2697 PanoramiXRes *pict; 2698 2699 REQUEST_AT_LEAST_SIZE(xRenderSetPictureFilterReq); 2700 2701 VERIFY_XIN_PICTURE(pict, stuff->picture, client, DixWriteAccess); 2702 2703 FOR_NSCREENS_BACKWARD(j) { 2704 stuff->picture = pict->info[j].id; 2705 result = 2706 (*PanoramiXSaveRenderVector[X_RenderSetPictureFilter]) (client); 2707 if (result != Success) 2708 break; 2709 } 2710 2711 return result; 2712} 2713 2714static int 2715PanoramiXRenderFreePicture(ClientPtr client) 2716{ 2717 PanoramiXRes *pict; 2718 int result = Success, j; 2719 2720 REQUEST(xRenderFreePictureReq); 2721 2722 REQUEST_SIZE_MATCH(xRenderFreePictureReq); 2723 2724 client->errorValue = stuff->picture; 2725 2726 VERIFY_XIN_PICTURE(pict, stuff->picture, client, DixDestroyAccess); 2727 2728 FOR_NSCREENS_BACKWARD(j) { 2729 stuff->picture = pict->info[j].id; 2730 result = (*PanoramiXSaveRenderVector[X_RenderFreePicture]) (client); 2731 if (result != Success) 2732 break; 2733 } 2734 2735 /* Since ProcRenderFreePicture is using FreeResource, it will free 2736 our resource for us on the last pass through the loop above */ 2737 2738 return result; 2739} 2740 2741static int 2742PanoramiXRenderComposite(ClientPtr client) 2743{ 2744 PanoramiXRes *src, *msk, *dst; 2745 int result = Success, j; 2746 xRenderCompositeReq orig; 2747 2748 REQUEST(xRenderCompositeReq); 2749 2750 REQUEST_SIZE_MATCH(xRenderCompositeReq); 2751 2752 VERIFY_XIN_PICTURE(src, stuff->src, client, DixReadAccess); 2753 VERIFY_XIN_ALPHA(msk, stuff->mask, client, DixReadAccess); 2754 VERIFY_XIN_PICTURE(dst, stuff->dst, client, DixWriteAccess); 2755 2756 orig = *stuff; 2757 2758 FOR_NSCREENS_FORWARD(j) { 2759 stuff->src = src->info[j].id; 2760 if (src->u.pict.root) { 2761 stuff->xSrc = orig.xSrc - screenInfo.screens[j]->x; 2762 stuff->ySrc = orig.ySrc - screenInfo.screens[j]->y; 2763 } 2764 stuff->dst = dst->info[j].id; 2765 if (dst->u.pict.root) { 2766 stuff->xDst = orig.xDst - screenInfo.screens[j]->x; 2767 stuff->yDst = orig.yDst - screenInfo.screens[j]->y; 2768 } 2769 if (msk) { 2770 stuff->mask = msk->info[j].id; 2771 if (msk->u.pict.root) { 2772 stuff->xMask = orig.xMask - screenInfo.screens[j]->x; 2773 stuff->yMask = orig.yMask - screenInfo.screens[j]->y; 2774 } 2775 } 2776 result = (*PanoramiXSaveRenderVector[X_RenderComposite]) (client); 2777 if (result != Success) 2778 break; 2779 } 2780 2781 return result; 2782} 2783 2784static int 2785PanoramiXRenderCompositeGlyphs(ClientPtr client) 2786{ 2787 PanoramiXRes *src, *dst; 2788 int result = Success, j; 2789 2790 REQUEST(xRenderCompositeGlyphsReq); 2791 xGlyphElt origElt, *elt; 2792 INT16 xSrc, ySrc; 2793 2794 REQUEST_AT_LEAST_SIZE(xRenderCompositeGlyphsReq); 2795 VERIFY_XIN_PICTURE(src, stuff->src, client, DixReadAccess); 2796 VERIFY_XIN_PICTURE(dst, stuff->dst, client, DixWriteAccess); 2797 2798 if (client->req_len << 2 >= (sizeof(xRenderCompositeGlyphsReq) + 2799 sizeof(xGlyphElt))) { 2800 elt = (xGlyphElt *) (stuff + 1); 2801 origElt = *elt; 2802 xSrc = stuff->xSrc; 2803 ySrc = stuff->ySrc; 2804 FOR_NSCREENS_FORWARD(j) { 2805 stuff->src = src->info[j].id; 2806 if (src->u.pict.root) { 2807 stuff->xSrc = xSrc - screenInfo.screens[j]->x; 2808 stuff->ySrc = ySrc - screenInfo.screens[j]->y; 2809 } 2810 stuff->dst = dst->info[j].id; 2811 if (dst->u.pict.root) { 2812 elt->deltax = origElt.deltax - screenInfo.screens[j]->x; 2813 elt->deltay = origElt.deltay - screenInfo.screens[j]->y; 2814 } 2815 result = 2816 (*PanoramiXSaveRenderVector[stuff->renderReqType]) (client); 2817 if (result != Success) 2818 break; 2819 } 2820 } 2821 2822 return result; 2823} 2824 2825static int 2826PanoramiXRenderFillRectangles(ClientPtr client) 2827{ 2828 PanoramiXRes *dst; 2829 int result = Success, j; 2830 2831 REQUEST(xRenderFillRectanglesReq); 2832 char *extra; 2833 int extra_len; 2834 2835 REQUEST_AT_LEAST_SIZE(xRenderFillRectanglesReq); 2836 VERIFY_XIN_PICTURE(dst, stuff->dst, client, DixWriteAccess); 2837 extra_len = (client->req_len << 2) - sizeof(xRenderFillRectanglesReq); 2838 if (extra_len && (extra = (char *) malloc(extra_len))) { 2839 memcpy(extra, stuff + 1, extra_len); 2840 FOR_NSCREENS_FORWARD(j) { 2841 if (j) 2842 memcpy(stuff + 1, extra, extra_len); 2843 if (dst->u.pict.root) { 2844 int x_off = screenInfo.screens[j]->x; 2845 int y_off = screenInfo.screens[j]->y; 2846 2847 if (x_off || y_off) { 2848 xRectangle *rects = (xRectangle *) (stuff + 1); 2849 int i = extra_len / sizeof(xRectangle); 2850 2851 while (i--) { 2852 rects->x -= x_off; 2853 rects->y -= y_off; 2854 rects++; 2855 } 2856 } 2857 } 2858 stuff->dst = dst->info[j].id; 2859 result = 2860 (*PanoramiXSaveRenderVector[X_RenderFillRectangles]) (client); 2861 if (result != Success) 2862 break; 2863 } 2864 free(extra); 2865 } 2866 2867 return result; 2868} 2869 2870static int 2871PanoramiXRenderTrapezoids(ClientPtr client) 2872{ 2873 PanoramiXRes *src, *dst; 2874 int result = Success, j; 2875 2876 REQUEST(xRenderTrapezoidsReq); 2877 char *extra; 2878 int extra_len; 2879 2880 REQUEST_AT_LEAST_SIZE(xRenderTrapezoidsReq); 2881 2882 VERIFY_XIN_PICTURE(src, stuff->src, client, DixReadAccess); 2883 VERIFY_XIN_PICTURE(dst, stuff->dst, client, DixWriteAccess); 2884 2885 extra_len = (client->req_len << 2) - sizeof(xRenderTrapezoidsReq); 2886 2887 if (extra_len && (extra = (char *) malloc(extra_len))) { 2888 memcpy(extra, stuff + 1, extra_len); 2889 2890 FOR_NSCREENS_FORWARD(j) { 2891 if (j) 2892 memcpy(stuff + 1, extra, extra_len); 2893 if (dst->u.pict.root) { 2894 int x_off = screenInfo.screens[j]->x; 2895 int y_off = screenInfo.screens[j]->y; 2896 2897 if (x_off || y_off) { 2898 xTrapezoid *trap = (xTrapezoid *) (stuff + 1); 2899 int i = extra_len / sizeof(xTrapezoid); 2900 2901 while (i--) { 2902 trap->top -= y_off; 2903 trap->bottom -= y_off; 2904 trap->left.p1.x -= x_off; 2905 trap->left.p1.y -= y_off; 2906 trap->left.p2.x -= x_off; 2907 trap->left.p2.y -= y_off; 2908 trap->right.p1.x -= x_off; 2909 trap->right.p1.y -= y_off; 2910 trap->right.p2.x -= x_off; 2911 trap->right.p2.y -= y_off; 2912 trap++; 2913 } 2914 } 2915 } 2916 2917 stuff->src = src->info[j].id; 2918 stuff->dst = dst->info[j].id; 2919 result = (*PanoramiXSaveRenderVector[X_RenderTrapezoids]) (client); 2920 2921 if (result != Success) 2922 break; 2923 } 2924 2925 free(extra); 2926 } 2927 2928 return result; 2929} 2930 2931static int 2932PanoramiXRenderTriangles(ClientPtr client) 2933{ 2934 PanoramiXRes *src, *dst; 2935 int result = Success, j; 2936 2937 REQUEST(xRenderTrianglesReq); 2938 char *extra; 2939 int extra_len; 2940 2941 REQUEST_AT_LEAST_SIZE(xRenderTrianglesReq); 2942 2943 VERIFY_XIN_PICTURE(src, stuff->src, client, DixReadAccess); 2944 VERIFY_XIN_PICTURE(dst, stuff->dst, client, DixWriteAccess); 2945 2946 extra_len = (client->req_len << 2) - sizeof(xRenderTrianglesReq); 2947 2948 if (extra_len && (extra = (char *) malloc(extra_len))) { 2949 memcpy(extra, stuff + 1, extra_len); 2950 2951 FOR_NSCREENS_FORWARD(j) { 2952 if (j) 2953 memcpy(stuff + 1, extra, extra_len); 2954 if (dst->u.pict.root) { 2955 int x_off = screenInfo.screens[j]->x; 2956 int y_off = screenInfo.screens[j]->y; 2957 2958 if (x_off || y_off) { 2959 xTriangle *tri = (xTriangle *) (stuff + 1); 2960 int i = extra_len / sizeof(xTriangle); 2961 2962 while (i--) { 2963 tri->p1.x -= x_off; 2964 tri->p1.y -= y_off; 2965 tri->p2.x -= x_off; 2966 tri->p2.y -= y_off; 2967 tri->p3.x -= x_off; 2968 tri->p3.y -= y_off; 2969 tri++; 2970 } 2971 } 2972 } 2973 2974 stuff->src = src->info[j].id; 2975 stuff->dst = dst->info[j].id; 2976 result = (*PanoramiXSaveRenderVector[X_RenderTriangles]) (client); 2977 2978 if (result != Success) 2979 break; 2980 } 2981 2982 free(extra); 2983 } 2984 2985 return result; 2986} 2987 2988static int 2989PanoramiXRenderTriStrip(ClientPtr client) 2990{ 2991 PanoramiXRes *src, *dst; 2992 int result = Success, j; 2993 2994 REQUEST(xRenderTriStripReq); 2995 char *extra; 2996 int extra_len; 2997 2998 REQUEST_AT_LEAST_SIZE(xRenderTriStripReq); 2999 3000 VERIFY_XIN_PICTURE(src, stuff->src, client, DixReadAccess); 3001 VERIFY_XIN_PICTURE(dst, stuff->dst, client, DixWriteAccess); 3002 3003 extra_len = (client->req_len << 2) - sizeof(xRenderTriStripReq); 3004 3005 if (extra_len && (extra = (char *) malloc(extra_len))) { 3006 memcpy(extra, stuff + 1, extra_len); 3007 3008 FOR_NSCREENS_FORWARD(j) { 3009 if (j) 3010 memcpy(stuff + 1, extra, extra_len); 3011 if (dst->u.pict.root) { 3012 int x_off = screenInfo.screens[j]->x; 3013 int y_off = screenInfo.screens[j]->y; 3014 3015 if (x_off || y_off) { 3016 xPointFixed *fixed = (xPointFixed *) (stuff + 1); 3017 int i = extra_len / sizeof(xPointFixed); 3018 3019 while (i--) { 3020 fixed->x -= x_off; 3021 fixed->y -= y_off; 3022 fixed++; 3023 } 3024 } 3025 } 3026 3027 stuff->src = src->info[j].id; 3028 stuff->dst = dst->info[j].id; 3029 result = (*PanoramiXSaveRenderVector[X_RenderTriStrip]) (client); 3030 3031 if (result != Success) 3032 break; 3033 } 3034 3035 free(extra); 3036 } 3037 3038 return result; 3039} 3040 3041static int 3042PanoramiXRenderTriFan(ClientPtr client) 3043{ 3044 PanoramiXRes *src, *dst; 3045 int result = Success, j; 3046 3047 REQUEST(xRenderTriFanReq); 3048 char *extra; 3049 int extra_len; 3050 3051 REQUEST_AT_LEAST_SIZE(xRenderTriFanReq); 3052 3053 VERIFY_XIN_PICTURE(src, stuff->src, client, DixReadAccess); 3054 VERIFY_XIN_PICTURE(dst, stuff->dst, client, DixWriteAccess); 3055 3056 extra_len = (client->req_len << 2) - sizeof(xRenderTriFanReq); 3057 3058 if (extra_len && (extra = (char *) malloc(extra_len))) { 3059 memcpy(extra, stuff + 1, extra_len); 3060 3061 FOR_NSCREENS_FORWARD(j) { 3062 if (j) 3063 memcpy(stuff + 1, extra, extra_len); 3064 if (dst->u.pict.root) { 3065 int x_off = screenInfo.screens[j]->x; 3066 int y_off = screenInfo.screens[j]->y; 3067 3068 if (x_off || y_off) { 3069 xPointFixed *fixed = (xPointFixed *) (stuff + 1); 3070 int i = extra_len / sizeof(xPointFixed); 3071 3072 while (i--) { 3073 fixed->x -= x_off; 3074 fixed->y -= y_off; 3075 fixed++; 3076 } 3077 } 3078 } 3079 3080 stuff->src = src->info[j].id; 3081 stuff->dst = dst->info[j].id; 3082 result = (*PanoramiXSaveRenderVector[X_RenderTriFan]) (client); 3083 3084 if (result != Success) 3085 break; 3086 } 3087 3088 free(extra); 3089 } 3090 3091 return result; 3092} 3093 3094static int 3095PanoramiXRenderAddTraps(ClientPtr client) 3096{ 3097 PanoramiXRes *picture; 3098 int result = Success, j; 3099 3100 REQUEST(xRenderAddTrapsReq); 3101 char *extra; 3102 int extra_len; 3103 INT16 x_off, y_off; 3104 3105 REQUEST_AT_LEAST_SIZE(xRenderAddTrapsReq); 3106 VERIFY_XIN_PICTURE(picture, stuff->picture, client, DixWriteAccess); 3107 extra_len = (client->req_len << 2) - sizeof(xRenderAddTrapsReq); 3108 if (extra_len && (extra = (char *) malloc(extra_len))) { 3109 memcpy(extra, stuff + 1, extra_len); 3110 x_off = stuff->xOff; 3111 y_off = stuff->yOff; 3112 FOR_NSCREENS_FORWARD(j) { 3113 if (j) 3114 memcpy(stuff + 1, extra, extra_len); 3115 stuff->picture = picture->info[j].id; 3116 3117 if (picture->u.pict.root) { 3118 stuff->xOff = x_off + screenInfo.screens[j]->x; 3119 stuff->yOff = y_off + screenInfo.screens[j]->y; 3120 } 3121 result = (*PanoramiXSaveRenderVector[X_RenderAddTraps]) (client); 3122 if (result != Success) 3123 break; 3124 } 3125 free(extra); 3126 } 3127 3128 return result; 3129} 3130 3131static int 3132PanoramiXRenderCreateSolidFill(ClientPtr client) 3133{ 3134 REQUEST(xRenderCreateSolidFillReq); 3135 PanoramiXRes *newPict; 3136 int result = Success, j; 3137 3138 REQUEST_AT_LEAST_SIZE(xRenderCreateSolidFillReq); 3139 3140 if (!(newPict = (PanoramiXRes *) malloc(sizeof(PanoramiXRes)))) 3141 return BadAlloc; 3142 3143 newPict->type = XRT_PICTURE; 3144 panoramix_setup_ids(newPict, client, stuff->pid); 3145 newPict->u.pict.root = FALSE; 3146 3147 FOR_NSCREENS_BACKWARD(j) { 3148 stuff->pid = newPict->info[j].id; 3149 result = (*PanoramiXSaveRenderVector[X_RenderCreateSolidFill]) (client); 3150 if (result != Success) 3151 break; 3152 } 3153 3154 if (result == Success) 3155 AddResource(newPict->info[0].id, XRT_PICTURE, newPict); 3156 else 3157 free(newPict); 3158 3159 return result; 3160} 3161 3162static int 3163PanoramiXRenderCreateLinearGradient(ClientPtr client) 3164{ 3165 REQUEST(xRenderCreateLinearGradientReq); 3166 PanoramiXRes *newPict; 3167 int result = Success, j; 3168 3169 REQUEST_AT_LEAST_SIZE(xRenderCreateLinearGradientReq); 3170 3171 if (!(newPict = (PanoramiXRes *) malloc(sizeof(PanoramiXRes)))) 3172 return BadAlloc; 3173 3174 newPict->type = XRT_PICTURE; 3175 panoramix_setup_ids(newPict, client, stuff->pid); 3176 newPict->u.pict.root = FALSE; 3177 3178 FOR_NSCREENS_BACKWARD(j) { 3179 stuff->pid = newPict->info[j].id; 3180 result = 3181 (*PanoramiXSaveRenderVector[X_RenderCreateLinearGradient]) (client); 3182 if (result != Success) 3183 break; 3184 } 3185 3186 if (result == Success) 3187 AddResource(newPict->info[0].id, XRT_PICTURE, newPict); 3188 else 3189 free(newPict); 3190 3191 return result; 3192} 3193 3194static int 3195PanoramiXRenderCreateRadialGradient(ClientPtr client) 3196{ 3197 REQUEST(xRenderCreateRadialGradientReq); 3198 PanoramiXRes *newPict; 3199 int result = Success, j; 3200 3201 REQUEST_AT_LEAST_SIZE(xRenderCreateRadialGradientReq); 3202 3203 if (!(newPict = (PanoramiXRes *) malloc(sizeof(PanoramiXRes)))) 3204 return BadAlloc; 3205 3206 newPict->type = XRT_PICTURE; 3207 panoramix_setup_ids(newPict, client, stuff->pid); 3208 newPict->u.pict.root = FALSE; 3209 3210 FOR_NSCREENS_BACKWARD(j) { 3211 stuff->pid = newPict->info[j].id; 3212 result = 3213 (*PanoramiXSaveRenderVector[X_RenderCreateRadialGradient]) (client); 3214 if (result != Success) 3215 break; 3216 } 3217 3218 if (result == Success) 3219 AddResource(newPict->info[0].id, XRT_PICTURE, newPict); 3220 else 3221 free(newPict); 3222 3223 return result; 3224} 3225 3226static int 3227PanoramiXRenderCreateConicalGradient(ClientPtr client) 3228{ 3229 REQUEST(xRenderCreateConicalGradientReq); 3230 PanoramiXRes *newPict; 3231 int result = Success, j; 3232 3233 REQUEST_AT_LEAST_SIZE(xRenderCreateConicalGradientReq); 3234 3235 if (!(newPict = (PanoramiXRes *) malloc(sizeof(PanoramiXRes)))) 3236 return BadAlloc; 3237 3238 newPict->type = XRT_PICTURE; 3239 panoramix_setup_ids(newPict, client, stuff->pid); 3240 newPict->u.pict.root = FALSE; 3241 3242 FOR_NSCREENS_BACKWARD(j) { 3243 stuff->pid = newPict->info[j].id; 3244 result = 3245 (*PanoramiXSaveRenderVector[X_RenderCreateConicalGradient]) 3246 (client); 3247 if (result != Success) 3248 break; 3249 } 3250 3251 if (result == Success) 3252 AddResource(newPict->info[0].id, XRT_PICTURE, newPict); 3253 else 3254 free(newPict); 3255 3256 return result; 3257} 3258 3259void 3260PanoramiXRenderInit(void) 3261{ 3262 int i; 3263 3264 XRT_PICTURE = CreateNewResourceType(XineramaDeleteResource, 3265 "XineramaPicture"); 3266 if (RenderErrBase) 3267 SetResourceTypeErrorValue(XRT_PICTURE, RenderErrBase + BadPicture); 3268 for (i = 0; i < RenderNumberRequests; i++) 3269 PanoramiXSaveRenderVector[i] = ProcRenderVector[i]; 3270 /* 3271 * Stuff in Xinerama aware request processing hooks 3272 */ 3273 ProcRenderVector[X_RenderCreatePicture] = PanoramiXRenderCreatePicture; 3274 ProcRenderVector[X_RenderChangePicture] = PanoramiXRenderChangePicture; 3275 ProcRenderVector[X_RenderSetPictureTransform] = 3276 PanoramiXRenderSetPictureTransform; 3277 ProcRenderVector[X_RenderSetPictureFilter] = 3278 PanoramiXRenderSetPictureFilter; 3279 ProcRenderVector[X_RenderSetPictureClipRectangles] = 3280 PanoramiXRenderSetPictureClipRectangles; 3281 ProcRenderVector[X_RenderFreePicture] = PanoramiXRenderFreePicture; 3282 ProcRenderVector[X_RenderComposite] = PanoramiXRenderComposite; 3283 ProcRenderVector[X_RenderCompositeGlyphs8] = PanoramiXRenderCompositeGlyphs; 3284 ProcRenderVector[X_RenderCompositeGlyphs16] = 3285 PanoramiXRenderCompositeGlyphs; 3286 ProcRenderVector[X_RenderCompositeGlyphs32] = 3287 PanoramiXRenderCompositeGlyphs; 3288 ProcRenderVector[X_RenderFillRectangles] = PanoramiXRenderFillRectangles; 3289 3290 ProcRenderVector[X_RenderTrapezoids] = PanoramiXRenderTrapezoids; 3291 ProcRenderVector[X_RenderTriangles] = PanoramiXRenderTriangles; 3292 ProcRenderVector[X_RenderTriStrip] = PanoramiXRenderTriStrip; 3293 ProcRenderVector[X_RenderTriFan] = PanoramiXRenderTriFan; 3294 ProcRenderVector[X_RenderAddTraps] = PanoramiXRenderAddTraps; 3295 3296 ProcRenderVector[X_RenderCreateSolidFill] = PanoramiXRenderCreateSolidFill; 3297 ProcRenderVector[X_RenderCreateLinearGradient] = 3298 PanoramiXRenderCreateLinearGradient; 3299 ProcRenderVector[X_RenderCreateRadialGradient] = 3300 PanoramiXRenderCreateRadialGradient; 3301 ProcRenderVector[X_RenderCreateConicalGradient] = 3302 PanoramiXRenderCreateConicalGradient; 3303} 3304 3305void 3306PanoramiXRenderReset(void) 3307{ 3308 int i; 3309 3310 for (i = 0; i < RenderNumberRequests; i++) 3311 ProcRenderVector[i] = PanoramiXSaveRenderVector[i]; 3312 RenderErrBase = 0; 3313} 3314 3315#endif /* PANORAMIX */ 3316