render.c (97959B)
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 58 static int ProcRenderQueryVersion(ClientPtr pClient); 59 static int ProcRenderQueryPictFormats(ClientPtr pClient); 60 static int ProcRenderQueryPictIndexValues(ClientPtr pClient); 61 static int ProcRenderQueryDithers(ClientPtr pClient); 62 static int ProcRenderCreatePicture(ClientPtr pClient); 63 static int ProcRenderChangePicture(ClientPtr pClient); 64 static int ProcRenderSetPictureClipRectangles(ClientPtr pClient); 65 static int ProcRenderFreePicture(ClientPtr pClient); 66 static int ProcRenderComposite(ClientPtr pClient); 67 static int ProcRenderScale(ClientPtr pClient); 68 static int ProcRenderTrapezoids(ClientPtr pClient); 69 static int ProcRenderTriangles(ClientPtr pClient); 70 static int ProcRenderTriStrip(ClientPtr pClient); 71 static int ProcRenderTriFan(ClientPtr pClient); 72 static int ProcRenderColorTrapezoids(ClientPtr pClient); 73 static int ProcRenderColorTriangles(ClientPtr pClient); 74 static int ProcRenderTransform(ClientPtr pClient); 75 static int ProcRenderCreateGlyphSet(ClientPtr pClient); 76 static int ProcRenderReferenceGlyphSet(ClientPtr pClient); 77 static int ProcRenderFreeGlyphSet(ClientPtr pClient); 78 static int ProcRenderAddGlyphs(ClientPtr pClient); 79 static int ProcRenderAddGlyphsFromPicture(ClientPtr pClient); 80 static int ProcRenderFreeGlyphs(ClientPtr pClient); 81 static int ProcRenderCompositeGlyphs(ClientPtr pClient); 82 static int ProcRenderFillRectangles(ClientPtr pClient); 83 static int ProcRenderCreateCursor(ClientPtr pClient); 84 static int ProcRenderSetPictureTransform(ClientPtr pClient); 85 static int ProcRenderQueryFilters(ClientPtr pClient); 86 static int ProcRenderSetPictureFilter(ClientPtr pClient); 87 static int ProcRenderCreateAnimCursor(ClientPtr pClient); 88 static int ProcRenderAddTraps(ClientPtr pClient); 89 static int ProcRenderCreateSolidFill(ClientPtr pClient); 90 static int ProcRenderCreateLinearGradient(ClientPtr pClient); 91 static int ProcRenderCreateRadialGradient(ClientPtr pClient); 92 static int ProcRenderCreateConicalGradient(ClientPtr pClient); 93 94 static int ProcRenderDispatch(ClientPtr pClient); 95 96 static int SProcRenderQueryVersion(ClientPtr pClient); 97 static int SProcRenderQueryPictFormats(ClientPtr pClient); 98 static int SProcRenderQueryPictIndexValues(ClientPtr pClient); 99 static int SProcRenderQueryDithers(ClientPtr pClient); 100 static int SProcRenderCreatePicture(ClientPtr pClient); 101 static int SProcRenderChangePicture(ClientPtr pClient); 102 static int SProcRenderSetPictureClipRectangles(ClientPtr pClient); 103 static int SProcRenderFreePicture(ClientPtr pClient); 104 static int SProcRenderComposite(ClientPtr pClient); 105 static int SProcRenderScale(ClientPtr pClient); 106 static int SProcRenderTrapezoids(ClientPtr pClient); 107 static int SProcRenderTriangles(ClientPtr pClient); 108 static int SProcRenderTriStrip(ClientPtr pClient); 109 static int SProcRenderTriFan(ClientPtr pClient); 110 static int SProcRenderColorTrapezoids(ClientPtr pClient); 111 static int SProcRenderColorTriangles(ClientPtr pClient); 112 static int SProcRenderTransform(ClientPtr pClient); 113 static int SProcRenderCreateGlyphSet(ClientPtr pClient); 114 static int SProcRenderReferenceGlyphSet(ClientPtr pClient); 115 static int SProcRenderFreeGlyphSet(ClientPtr pClient); 116 static int SProcRenderAddGlyphs(ClientPtr pClient); 117 static int SProcRenderAddGlyphsFromPicture(ClientPtr pClient); 118 static int SProcRenderFreeGlyphs(ClientPtr pClient); 119 static int SProcRenderCompositeGlyphs(ClientPtr pClient); 120 static int SProcRenderFillRectangles(ClientPtr pClient); 121 static int SProcRenderCreateCursor(ClientPtr pClient); 122 static int SProcRenderSetPictureTransform(ClientPtr pClient); 123 static int SProcRenderQueryFilters(ClientPtr pClient); 124 static int SProcRenderSetPictureFilter(ClientPtr pClient); 125 static int SProcRenderCreateAnimCursor(ClientPtr pClient); 126 static int SProcRenderAddTraps(ClientPtr pClient); 127 static int SProcRenderCreateSolidFill(ClientPtr pClient); 128 static int SProcRenderCreateLinearGradient(ClientPtr pClient); 129 static int SProcRenderCreateRadialGradient(ClientPtr pClient); 130 static int SProcRenderCreateConicalGradient(ClientPtr pClient); 131 132 static int SProcRenderDispatch(ClientPtr pClient); 133 134 int (*ProcRenderVector[RenderNumberRequests]) (ClientPtr) = { 135 ProcRenderQueryVersion, 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 172 int (*SProcRenderVector[RenderNumberRequests]) (ClientPtr) = { 173 SProcRenderQueryVersion, 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 210 int RenderErrBase; 211 static DevPrivateKeyRec RenderClientPrivateKeyRec; 212 213 #define RenderClientPrivateKey (&RenderClientPrivateKeyRec ) 214 215 typedef 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 223 RESTYPE XRT_PICTURE; 224 #endif 225 226 void 227 RenderExtensionInit(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 254 static int 255 ProcRenderQueryVersion(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 291 static VisualPtr 292 findVisual(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 305 static int 306 ProcRenderQueryPictFormats(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 496 static int 497 ProcRenderQueryPictIndexValues(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 553 static int 554 ProcRenderQueryDithers(ClientPtr client) 555 { 556 return BadImplementation; 557 } 558 559 static int 560 ProcRenderCreatePicture(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 599 static int 600 ProcRenderChangePicture(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 618 static int 619 ProcRenderSetPictureClipRectangles(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 639 static int 640 ProcRenderFreePicture(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 653 static Bool 654 PictOpValid(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 667 static int 668 ProcRenderComposite(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 707 static int 708 ProcRenderScale(ClientPtr client) 709 { 710 return BadImplementation; 711 } 712 713 static int 714 ProcRenderTrapezoids(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 752 static int 753 ProcRenderTriangles(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 791 static int 792 ProcRenderTriStrip(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 830 static int 831 ProcRenderTriFan(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 869 static int 870 ProcRenderColorTrapezoids(ClientPtr client) 871 { 872 return BadImplementation; 873 } 874 875 static int 876 ProcRenderColorTriangles(ClientPtr client) 877 { 878 return BadImplementation; 879 } 880 881 static int 882 ProcRenderTransform(ClientPtr client) 883 { 884 return BadImplementation; 885 } 886 887 static int 888 ProcRenderCreateGlyphSet(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 938 static int 939 ProcRenderReferenceGlyphSet(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 965 static int 966 ProcRenderFreeGlyphSet(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 984 typedef 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 993 static int 994 ProcRenderAddGlyphs(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 1190 static int 1191 ProcRenderAddGlyphsFromPicture(ClientPtr client) 1192 { 1193 return BadImplementation; 1194 } 1195 1196 static int 1197 ProcRenderFreeGlyphs(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 1225 static int 1226 ProcRenderCompositeGlyphs(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 1392 static int 1393 ProcRenderFillRectangles(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 1420 static void 1421 RenderSetBit(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 1439 static 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 1446 static int 1447 ProcRenderCreateCursor(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 1640 static int 1641 ProcRenderSetPictureTransform(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 1651 static int 1652 ProcRenderQueryFilters(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 1750 static int 1751 ProcRenderSetPictureFilter(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 1772 static int 1773 ProcRenderCreateAnimCursor(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 1817 static int 1818 ProcRenderAddTraps(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 1839 static int 1840 ProcRenderCreateSolidFill(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 1864 static int 1865 ProcRenderCreateLinearGradient(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 1903 static int 1904 ProcRenderCreateRadialGradient(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 1943 static int 1944 ProcRenderCreateConicalGradient(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 1982 static int 1983 ProcRenderDispatch(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 1993 static int _X_COLD 1994 SProcRenderQueryVersion(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 2004 static int _X_COLD 2005 SProcRenderQueryPictFormats(ClientPtr client) 2006 { 2007 REQUEST(xRenderQueryPictFormatsReq); 2008 REQUEST_SIZE_MATCH(xRenderQueryPictFormatsReq); 2009 swaps(&stuff->length); 2010 return (*ProcRenderVector[stuff->renderReqType]) (client); 2011 } 2012 2013 static int _X_COLD 2014 SProcRenderQueryPictIndexValues(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 2023 static int _X_COLD 2024 SProcRenderQueryDithers(ClientPtr client) 2025 { 2026 return BadImplementation; 2027 } 2028 2029 static int _X_COLD 2030 SProcRenderCreatePicture(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 2043 static int _X_COLD 2044 SProcRenderChangePicture(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 2055 static int _X_COLD 2056 SProcRenderSetPictureClipRectangles(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 2068 static int _X_COLD 2069 SProcRenderFreePicture(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 2078 static int _X_COLD 2079 SProcRenderComposite(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 2098 static int _X_COLD 2099 SProcRenderScale(ClientPtr client) 2100 { 2101 return BadImplementation; 2102 } 2103 2104 static int _X_COLD 2105 SProcRenderTrapezoids(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 2120 static int _X_COLD 2121 SProcRenderTriangles(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 2136 static int _X_COLD 2137 SProcRenderTriStrip(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 2152 static int _X_COLD 2153 SProcRenderTriFan(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 2168 static int _X_COLD 2169 SProcRenderColorTrapezoids(ClientPtr client) 2170 { 2171 return BadImplementation; 2172 } 2173 2174 static int _X_COLD 2175 SProcRenderColorTriangles(ClientPtr client) 2176 { 2177 return BadImplementation; 2178 } 2179 2180 static int _X_COLD 2181 SProcRenderTransform(ClientPtr client) 2182 { 2183 return BadImplementation; 2184 } 2185 2186 static int _X_COLD 2187 SProcRenderCreateGlyphSet(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 2197 static int _X_COLD 2198 SProcRenderReferenceGlyphSet(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 2208 static int _X_COLD 2209 SProcRenderFreeGlyphSet(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 2218 static int _X_COLD 2219 SProcRenderAddGlyphs(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 2252 static int _X_COLD 2253 SProcRenderAddGlyphsFromPicture(ClientPtr client) 2254 { 2255 return BadImplementation; 2256 } 2257 2258 static int _X_COLD 2259 SProcRenderFreeGlyphs(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 2269 static int _X_COLD 2270 SProcRenderCompositeGlyphs(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 if (buffer + 4 > end) { 2313 return BadLength; 2314 } 2315 swapl((int *) buffer); 2316 buffer += 4; 2317 } 2318 else { 2319 space = size * i; 2320 switch (size) { 2321 case 1: 2322 buffer += i; 2323 break; 2324 case 2: 2325 if (buffer + i * 2 > end) { 2326 return BadLength; 2327 } 2328 while (i--) { 2329 swaps((short *) buffer); 2330 buffer += 2; 2331 } 2332 break; 2333 case 4: 2334 if (buffer + i * 4 > end) { 2335 return BadLength; 2336 } 2337 while (i--) { 2338 swapl((int *) buffer); 2339 buffer += 4; 2340 } 2341 break; 2342 } 2343 if (space & 3) 2344 buffer += 4 - (space & 3); 2345 } 2346 } 2347 return (*ProcRenderVector[stuff->renderReqType]) (client); 2348 } 2349 2350 static int _X_COLD 2351 SProcRenderFillRectangles(ClientPtr client) 2352 { 2353 REQUEST(xRenderFillRectanglesReq); 2354 2355 REQUEST_AT_LEAST_SIZE(xRenderFillRectanglesReq); 2356 swaps(&stuff->length); 2357 swapl(&stuff->dst); 2358 swaps(&stuff->color.red); 2359 swaps(&stuff->color.green); 2360 swaps(&stuff->color.blue); 2361 swaps(&stuff->color.alpha); 2362 SwapRestS(stuff); 2363 return (*ProcRenderVector[stuff->renderReqType]) (client); 2364 } 2365 2366 static int _X_COLD 2367 SProcRenderCreateCursor(ClientPtr client) 2368 { 2369 REQUEST(xRenderCreateCursorReq); 2370 REQUEST_SIZE_MATCH(xRenderCreateCursorReq); 2371 2372 swaps(&stuff->length); 2373 swapl(&stuff->cid); 2374 swapl(&stuff->src); 2375 swaps(&stuff->x); 2376 swaps(&stuff->y); 2377 return (*ProcRenderVector[stuff->renderReqType]) (client); 2378 } 2379 2380 static int _X_COLD 2381 SProcRenderSetPictureTransform(ClientPtr client) 2382 { 2383 REQUEST(xRenderSetPictureTransformReq); 2384 REQUEST_SIZE_MATCH(xRenderSetPictureTransformReq); 2385 2386 swaps(&stuff->length); 2387 swapl(&stuff->picture); 2388 swapl(&stuff->transform.matrix11); 2389 swapl(&stuff->transform.matrix12); 2390 swapl(&stuff->transform.matrix13); 2391 swapl(&stuff->transform.matrix21); 2392 swapl(&stuff->transform.matrix22); 2393 swapl(&stuff->transform.matrix23); 2394 swapl(&stuff->transform.matrix31); 2395 swapl(&stuff->transform.matrix32); 2396 swapl(&stuff->transform.matrix33); 2397 return (*ProcRenderVector[stuff->renderReqType]) (client); 2398 } 2399 2400 static int _X_COLD 2401 SProcRenderQueryFilters(ClientPtr client) 2402 { 2403 REQUEST(xRenderQueryFiltersReq); 2404 REQUEST_SIZE_MATCH(xRenderQueryFiltersReq); 2405 2406 swaps(&stuff->length); 2407 swapl(&stuff->drawable); 2408 return (*ProcRenderVector[stuff->renderReqType]) (client); 2409 } 2410 2411 static int _X_COLD 2412 SProcRenderSetPictureFilter(ClientPtr client) 2413 { 2414 REQUEST(xRenderSetPictureFilterReq); 2415 REQUEST_AT_LEAST_SIZE(xRenderSetPictureFilterReq); 2416 2417 swaps(&stuff->length); 2418 swapl(&stuff->picture); 2419 swaps(&stuff->nbytes); 2420 return (*ProcRenderVector[stuff->renderReqType]) (client); 2421 } 2422 2423 static int _X_COLD 2424 SProcRenderCreateAnimCursor(ClientPtr client) 2425 { 2426 REQUEST(xRenderCreateAnimCursorReq); 2427 REQUEST_AT_LEAST_SIZE(xRenderCreateAnimCursorReq); 2428 2429 swaps(&stuff->length); 2430 swapl(&stuff->cid); 2431 SwapRestL(stuff); 2432 return (*ProcRenderVector[stuff->renderReqType]) (client); 2433 } 2434 2435 static int _X_COLD 2436 SProcRenderAddTraps(ClientPtr client) 2437 { 2438 REQUEST(xRenderAddTrapsReq); 2439 REQUEST_AT_LEAST_SIZE(xRenderAddTrapsReq); 2440 2441 swaps(&stuff->length); 2442 swapl(&stuff->picture); 2443 swaps(&stuff->xOff); 2444 swaps(&stuff->yOff); 2445 SwapRestL(stuff); 2446 return (*ProcRenderVector[stuff->renderReqType]) (client); 2447 } 2448 2449 static int _X_COLD 2450 SProcRenderCreateSolidFill(ClientPtr client) 2451 { 2452 REQUEST(xRenderCreateSolidFillReq); 2453 REQUEST_AT_LEAST_SIZE(xRenderCreateSolidFillReq); 2454 2455 swaps(&stuff->length); 2456 swapl(&stuff->pid); 2457 swaps(&stuff->color.alpha); 2458 swaps(&stuff->color.red); 2459 swaps(&stuff->color.green); 2460 swaps(&stuff->color.blue); 2461 return (*ProcRenderVector[stuff->renderReqType]) (client); 2462 } 2463 2464 static void _X_COLD 2465 swapStops(void *stuff, int num) 2466 { 2467 int i; 2468 CARD32 *stops; 2469 CARD16 *colors; 2470 2471 stops = (CARD32 *) (stuff); 2472 for (i = 0; i < num; ++i) { 2473 swapl(stops); 2474 ++stops; 2475 } 2476 colors = (CARD16 *) (stops); 2477 for (i = 0; i < 4 * num; ++i) { 2478 swaps(colors); 2479 ++colors; 2480 } 2481 } 2482 2483 static int _X_COLD 2484 SProcRenderCreateLinearGradient(ClientPtr client) 2485 { 2486 int len; 2487 2488 REQUEST(xRenderCreateLinearGradientReq); 2489 REQUEST_AT_LEAST_SIZE(xRenderCreateLinearGradientReq); 2490 2491 swaps(&stuff->length); 2492 swapl(&stuff->pid); 2493 swapl(&stuff->p1.x); 2494 swapl(&stuff->p1.y); 2495 swapl(&stuff->p2.x); 2496 swapl(&stuff->p2.y); 2497 swapl(&stuff->nStops); 2498 2499 len = (client->req_len << 2) - sizeof(xRenderCreateLinearGradientReq); 2500 if (stuff->nStops > UINT32_MAX / (sizeof(xFixed) + sizeof(xRenderColor))) 2501 return BadLength; 2502 if (len != stuff->nStops * (sizeof(xFixed) + sizeof(xRenderColor))) 2503 return BadLength; 2504 2505 swapStops(stuff + 1, stuff->nStops); 2506 2507 return (*ProcRenderVector[stuff->renderReqType]) (client); 2508 } 2509 2510 static int _X_COLD 2511 SProcRenderCreateRadialGradient(ClientPtr client) 2512 { 2513 int len; 2514 2515 REQUEST(xRenderCreateRadialGradientReq); 2516 REQUEST_AT_LEAST_SIZE(xRenderCreateRadialGradientReq); 2517 2518 swaps(&stuff->length); 2519 swapl(&stuff->pid); 2520 swapl(&stuff->inner.x); 2521 swapl(&stuff->inner.y); 2522 swapl(&stuff->outer.x); 2523 swapl(&stuff->outer.y); 2524 swapl(&stuff->inner_radius); 2525 swapl(&stuff->outer_radius); 2526 swapl(&stuff->nStops); 2527 2528 len = (client->req_len << 2) - sizeof(xRenderCreateRadialGradientReq); 2529 if (stuff->nStops > UINT32_MAX / (sizeof(xFixed) + sizeof(xRenderColor))) 2530 return BadLength; 2531 if (len != stuff->nStops * (sizeof(xFixed) + sizeof(xRenderColor))) 2532 return BadLength; 2533 2534 swapStops(stuff + 1, stuff->nStops); 2535 2536 return (*ProcRenderVector[stuff->renderReqType]) (client); 2537 } 2538 2539 static int _X_COLD 2540 SProcRenderCreateConicalGradient(ClientPtr client) 2541 { 2542 int len; 2543 2544 REQUEST(xRenderCreateConicalGradientReq); 2545 REQUEST_AT_LEAST_SIZE(xRenderCreateConicalGradientReq); 2546 2547 swaps(&stuff->length); 2548 swapl(&stuff->pid); 2549 swapl(&stuff->center.x); 2550 swapl(&stuff->center.y); 2551 swapl(&stuff->angle); 2552 swapl(&stuff->nStops); 2553 2554 len = (client->req_len << 2) - sizeof(xRenderCreateConicalGradientReq); 2555 if (stuff->nStops > UINT32_MAX / (sizeof(xFixed) + sizeof(xRenderColor))) 2556 return BadLength; 2557 if (len != stuff->nStops * (sizeof(xFixed) + sizeof(xRenderColor))) 2558 return BadLength; 2559 2560 swapStops(stuff + 1, stuff->nStops); 2561 2562 return (*ProcRenderVector[stuff->renderReqType]) (client); 2563 } 2564 2565 static int _X_COLD 2566 SProcRenderDispatch(ClientPtr client) 2567 { 2568 REQUEST(xReq); 2569 2570 if (stuff->data < RenderNumberRequests) 2571 return (*SProcRenderVector[stuff->data]) (client); 2572 else 2573 return BadRequest; 2574 } 2575 2576 #ifdef PANORAMIX 2577 #define VERIFY_XIN_PICTURE(pPicture, pid, client, mode) {\ 2578 int rc = dixLookupResourceByType((void **)&(pPicture), pid,\ 2579 XRT_PICTURE, client, mode);\ 2580 if (rc != Success)\ 2581 return rc;\ 2582 } 2583 2584 #define VERIFY_XIN_ALPHA(pPicture, pid, client, mode) {\ 2585 if (pid == None) \ 2586 pPicture = 0; \ 2587 else { \ 2588 VERIFY_XIN_PICTURE(pPicture, pid, client, mode); \ 2589 } \ 2590 } \ 2591 2592 int (*PanoramiXSaveRenderVector[RenderNumberRequests]) (ClientPtr); 2593 2594 static int 2595 PanoramiXRenderCreatePicture(ClientPtr client) 2596 { 2597 REQUEST(xRenderCreatePictureReq); 2598 PanoramiXRes *refDraw, *newPict; 2599 int result, j; 2600 2601 REQUEST_AT_LEAST_SIZE(xRenderCreatePictureReq); 2602 result = dixLookupResourceByClass((void **) &refDraw, stuff->drawable, 2603 XRC_DRAWABLE, client, DixWriteAccess); 2604 if (result != Success) 2605 return (result == BadValue) ? BadDrawable : result; 2606 if (!(newPict = (PanoramiXRes *) malloc(sizeof(PanoramiXRes)))) 2607 return BadAlloc; 2608 newPict->type = XRT_PICTURE; 2609 panoramix_setup_ids(newPict, client, stuff->pid); 2610 2611 if (refDraw->type == XRT_WINDOW && 2612 stuff->drawable == screenInfo.screens[0]->root->drawable.id) { 2613 newPict->u.pict.root = TRUE; 2614 } 2615 else 2616 newPict->u.pict.root = FALSE; 2617 2618 FOR_NSCREENS_BACKWARD(j) { 2619 stuff->pid = newPict->info[j].id; 2620 stuff->drawable = refDraw->info[j].id; 2621 result = (*PanoramiXSaveRenderVector[X_RenderCreatePicture]) (client); 2622 if (result != Success) 2623 break; 2624 } 2625 2626 if (result == Success) 2627 AddResource(newPict->info[0].id, XRT_PICTURE, newPict); 2628 else 2629 free(newPict); 2630 2631 return result; 2632 } 2633 2634 static int 2635 PanoramiXRenderChangePicture(ClientPtr client) 2636 { 2637 PanoramiXRes *pict; 2638 int result = Success, j; 2639 2640 REQUEST(xRenderChangePictureReq); 2641 2642 REQUEST_AT_LEAST_SIZE(xRenderChangePictureReq); 2643 2644 VERIFY_XIN_PICTURE(pict, stuff->picture, client, DixWriteAccess); 2645 2646 FOR_NSCREENS_BACKWARD(j) { 2647 stuff->picture = pict->info[j].id; 2648 result = (*PanoramiXSaveRenderVector[X_RenderChangePicture]) (client); 2649 if (result != Success) 2650 break; 2651 } 2652 2653 return result; 2654 } 2655 2656 static int 2657 PanoramiXRenderSetPictureClipRectangles(ClientPtr client) 2658 { 2659 REQUEST(xRenderSetPictureClipRectanglesReq); 2660 int result = Success, j; 2661 PanoramiXRes *pict; 2662 2663 REQUEST_AT_LEAST_SIZE(xRenderSetPictureClipRectanglesReq); 2664 2665 VERIFY_XIN_PICTURE(pict, stuff->picture, client, DixWriteAccess); 2666 2667 FOR_NSCREENS_BACKWARD(j) { 2668 stuff->picture = pict->info[j].id; 2669 result = 2670 (*PanoramiXSaveRenderVector[X_RenderSetPictureClipRectangles]) 2671 (client); 2672 if (result != Success) 2673 break; 2674 } 2675 2676 return result; 2677 } 2678 2679 static int 2680 PanoramiXRenderSetPictureTransform(ClientPtr client) 2681 { 2682 REQUEST(xRenderSetPictureTransformReq); 2683 int result = Success, j; 2684 PanoramiXRes *pict; 2685 2686 REQUEST_AT_LEAST_SIZE(xRenderSetPictureTransformReq); 2687 2688 VERIFY_XIN_PICTURE(pict, stuff->picture, client, DixWriteAccess); 2689 2690 FOR_NSCREENS_BACKWARD(j) { 2691 stuff->picture = pict->info[j].id; 2692 result = 2693 (*PanoramiXSaveRenderVector[X_RenderSetPictureTransform]) (client); 2694 if (result != Success) 2695 break; 2696 } 2697 2698 return result; 2699 } 2700 2701 static int 2702 PanoramiXRenderSetPictureFilter(ClientPtr client) 2703 { 2704 REQUEST(xRenderSetPictureFilterReq); 2705 int result = Success, j; 2706 PanoramiXRes *pict; 2707 2708 REQUEST_AT_LEAST_SIZE(xRenderSetPictureFilterReq); 2709 2710 VERIFY_XIN_PICTURE(pict, stuff->picture, client, DixWriteAccess); 2711 2712 FOR_NSCREENS_BACKWARD(j) { 2713 stuff->picture = pict->info[j].id; 2714 result = 2715 (*PanoramiXSaveRenderVector[X_RenderSetPictureFilter]) (client); 2716 if (result != Success) 2717 break; 2718 } 2719 2720 return result; 2721 } 2722 2723 static int 2724 PanoramiXRenderFreePicture(ClientPtr client) 2725 { 2726 PanoramiXRes *pict; 2727 int result = Success, j; 2728 2729 REQUEST(xRenderFreePictureReq); 2730 2731 REQUEST_SIZE_MATCH(xRenderFreePictureReq); 2732 2733 client->errorValue = stuff->picture; 2734 2735 VERIFY_XIN_PICTURE(pict, stuff->picture, client, DixDestroyAccess); 2736 2737 FOR_NSCREENS_BACKWARD(j) { 2738 stuff->picture = pict->info[j].id; 2739 result = (*PanoramiXSaveRenderVector[X_RenderFreePicture]) (client); 2740 if (result != Success) 2741 break; 2742 } 2743 2744 /* Since ProcRenderFreePicture is using FreeResource, it will free 2745 our resource for us on the last pass through the loop above */ 2746 2747 return result; 2748 } 2749 2750 static int 2751 PanoramiXRenderComposite(ClientPtr client) 2752 { 2753 PanoramiXRes *src, *msk, *dst; 2754 int result = Success, j; 2755 xRenderCompositeReq orig; 2756 2757 REQUEST(xRenderCompositeReq); 2758 2759 REQUEST_SIZE_MATCH(xRenderCompositeReq); 2760 2761 VERIFY_XIN_PICTURE(src, stuff->src, client, DixReadAccess); 2762 VERIFY_XIN_ALPHA(msk, stuff->mask, client, DixReadAccess); 2763 VERIFY_XIN_PICTURE(dst, stuff->dst, client, DixWriteAccess); 2764 2765 orig = *stuff; 2766 2767 FOR_NSCREENS_FORWARD(j) { 2768 stuff->src = src->info[j].id; 2769 if (src->u.pict.root) { 2770 stuff->xSrc = orig.xSrc - screenInfo.screens[j]->x; 2771 stuff->ySrc = orig.ySrc - screenInfo.screens[j]->y; 2772 } 2773 stuff->dst = dst->info[j].id; 2774 if (dst->u.pict.root) { 2775 stuff->xDst = orig.xDst - screenInfo.screens[j]->x; 2776 stuff->yDst = orig.yDst - screenInfo.screens[j]->y; 2777 } 2778 if (msk) { 2779 stuff->mask = msk->info[j].id; 2780 if (msk->u.pict.root) { 2781 stuff->xMask = orig.xMask - screenInfo.screens[j]->x; 2782 stuff->yMask = orig.yMask - screenInfo.screens[j]->y; 2783 } 2784 } 2785 result = (*PanoramiXSaveRenderVector[X_RenderComposite]) (client); 2786 if (result != Success) 2787 break; 2788 } 2789 2790 return result; 2791 } 2792 2793 static int 2794 PanoramiXRenderCompositeGlyphs(ClientPtr client) 2795 { 2796 PanoramiXRes *src, *dst; 2797 int result = Success, j; 2798 2799 REQUEST(xRenderCompositeGlyphsReq); 2800 xGlyphElt origElt, *elt; 2801 INT16 xSrc, ySrc; 2802 2803 REQUEST_AT_LEAST_SIZE(xRenderCompositeGlyphsReq); 2804 VERIFY_XIN_PICTURE(src, stuff->src, client, DixReadAccess); 2805 VERIFY_XIN_PICTURE(dst, stuff->dst, client, DixWriteAccess); 2806 2807 if (client->req_len << 2 >= (sizeof(xRenderCompositeGlyphsReq) + 2808 sizeof(xGlyphElt))) { 2809 elt = (xGlyphElt *) (stuff + 1); 2810 origElt = *elt; 2811 xSrc = stuff->xSrc; 2812 ySrc = stuff->ySrc; 2813 FOR_NSCREENS_FORWARD(j) { 2814 stuff->src = src->info[j].id; 2815 if (src->u.pict.root) { 2816 stuff->xSrc = xSrc - screenInfo.screens[j]->x; 2817 stuff->ySrc = ySrc - screenInfo.screens[j]->y; 2818 } 2819 stuff->dst = dst->info[j].id; 2820 if (dst->u.pict.root) { 2821 elt->deltax = origElt.deltax - screenInfo.screens[j]->x; 2822 elt->deltay = origElt.deltay - screenInfo.screens[j]->y; 2823 } 2824 result = 2825 (*PanoramiXSaveRenderVector[stuff->renderReqType]) (client); 2826 if (result != Success) 2827 break; 2828 } 2829 } 2830 2831 return result; 2832 } 2833 2834 static int 2835 PanoramiXRenderFillRectangles(ClientPtr client) 2836 { 2837 PanoramiXRes *dst; 2838 int result = Success, j; 2839 2840 REQUEST(xRenderFillRectanglesReq); 2841 char *extra; 2842 int extra_len; 2843 2844 REQUEST_AT_LEAST_SIZE(xRenderFillRectanglesReq); 2845 VERIFY_XIN_PICTURE(dst, stuff->dst, client, DixWriteAccess); 2846 extra_len = (client->req_len << 2) - sizeof(xRenderFillRectanglesReq); 2847 if (extra_len && (extra = (char *) malloc(extra_len))) { 2848 memcpy(extra, stuff + 1, extra_len); 2849 FOR_NSCREENS_FORWARD(j) { 2850 if (j) 2851 memcpy(stuff + 1, extra, extra_len); 2852 if (dst->u.pict.root) { 2853 int x_off = screenInfo.screens[j]->x; 2854 int y_off = screenInfo.screens[j]->y; 2855 2856 if (x_off || y_off) { 2857 xRectangle *rects = (xRectangle *) (stuff + 1); 2858 int i = extra_len / sizeof(xRectangle); 2859 2860 while (i--) { 2861 rects->x -= x_off; 2862 rects->y -= y_off; 2863 rects++; 2864 } 2865 } 2866 } 2867 stuff->dst = dst->info[j].id; 2868 result = 2869 (*PanoramiXSaveRenderVector[X_RenderFillRectangles]) (client); 2870 if (result != Success) 2871 break; 2872 } 2873 free(extra); 2874 } 2875 2876 return result; 2877 } 2878 2879 static int 2880 PanoramiXRenderTrapezoids(ClientPtr client) 2881 { 2882 PanoramiXRes *src, *dst; 2883 int result = Success, j; 2884 2885 REQUEST(xRenderTrapezoidsReq); 2886 char *extra; 2887 int extra_len; 2888 2889 REQUEST_AT_LEAST_SIZE(xRenderTrapezoidsReq); 2890 2891 VERIFY_XIN_PICTURE(src, stuff->src, client, DixReadAccess); 2892 VERIFY_XIN_PICTURE(dst, stuff->dst, client, DixWriteAccess); 2893 2894 extra_len = (client->req_len << 2) - sizeof(xRenderTrapezoidsReq); 2895 2896 if (extra_len && (extra = (char *) malloc(extra_len))) { 2897 memcpy(extra, stuff + 1, extra_len); 2898 2899 FOR_NSCREENS_FORWARD(j) { 2900 if (j) 2901 memcpy(stuff + 1, extra, extra_len); 2902 if (dst->u.pict.root) { 2903 int x_off = screenInfo.screens[j]->x; 2904 int y_off = screenInfo.screens[j]->y; 2905 2906 if (x_off || y_off) { 2907 xTrapezoid *trap = (xTrapezoid *) (stuff + 1); 2908 int i = extra_len / sizeof(xTrapezoid); 2909 2910 while (i--) { 2911 trap->top -= y_off; 2912 trap->bottom -= y_off; 2913 trap->left.p1.x -= x_off; 2914 trap->left.p1.y -= y_off; 2915 trap->left.p2.x -= x_off; 2916 trap->left.p2.y -= y_off; 2917 trap->right.p1.x -= x_off; 2918 trap->right.p1.y -= y_off; 2919 trap->right.p2.x -= x_off; 2920 trap->right.p2.y -= y_off; 2921 trap++; 2922 } 2923 } 2924 } 2925 2926 stuff->src = src->info[j].id; 2927 stuff->dst = dst->info[j].id; 2928 result = (*PanoramiXSaveRenderVector[X_RenderTrapezoids]) (client); 2929 2930 if (result != Success) 2931 break; 2932 } 2933 2934 free(extra); 2935 } 2936 2937 return result; 2938 } 2939 2940 static int 2941 PanoramiXRenderTriangles(ClientPtr client) 2942 { 2943 PanoramiXRes *src, *dst; 2944 int result = Success, j; 2945 2946 REQUEST(xRenderTrianglesReq); 2947 char *extra; 2948 int extra_len; 2949 2950 REQUEST_AT_LEAST_SIZE(xRenderTrianglesReq); 2951 2952 VERIFY_XIN_PICTURE(src, stuff->src, client, DixReadAccess); 2953 VERIFY_XIN_PICTURE(dst, stuff->dst, client, DixWriteAccess); 2954 2955 extra_len = (client->req_len << 2) - sizeof(xRenderTrianglesReq); 2956 2957 if (extra_len && (extra = (char *) malloc(extra_len))) { 2958 memcpy(extra, stuff + 1, extra_len); 2959 2960 FOR_NSCREENS_FORWARD(j) { 2961 if (j) 2962 memcpy(stuff + 1, extra, extra_len); 2963 if (dst->u.pict.root) { 2964 int x_off = screenInfo.screens[j]->x; 2965 int y_off = screenInfo.screens[j]->y; 2966 2967 if (x_off || y_off) { 2968 xTriangle *tri = (xTriangle *) (stuff + 1); 2969 int i = extra_len / sizeof(xTriangle); 2970 2971 while (i--) { 2972 tri->p1.x -= x_off; 2973 tri->p1.y -= y_off; 2974 tri->p2.x -= x_off; 2975 tri->p2.y -= y_off; 2976 tri->p3.x -= x_off; 2977 tri->p3.y -= y_off; 2978 tri++; 2979 } 2980 } 2981 } 2982 2983 stuff->src = src->info[j].id; 2984 stuff->dst = dst->info[j].id; 2985 result = (*PanoramiXSaveRenderVector[X_RenderTriangles]) (client); 2986 2987 if (result != Success) 2988 break; 2989 } 2990 2991 free(extra); 2992 } 2993 2994 return result; 2995 } 2996 2997 static int 2998 PanoramiXRenderTriStrip(ClientPtr client) 2999 { 3000 PanoramiXRes *src, *dst; 3001 int result = Success, j; 3002 3003 REQUEST(xRenderTriStripReq); 3004 char *extra; 3005 int extra_len; 3006 3007 REQUEST_AT_LEAST_SIZE(xRenderTriStripReq); 3008 3009 VERIFY_XIN_PICTURE(src, stuff->src, client, DixReadAccess); 3010 VERIFY_XIN_PICTURE(dst, stuff->dst, client, DixWriteAccess); 3011 3012 extra_len = (client->req_len << 2) - sizeof(xRenderTriStripReq); 3013 3014 if (extra_len && (extra = (char *) malloc(extra_len))) { 3015 memcpy(extra, stuff + 1, extra_len); 3016 3017 FOR_NSCREENS_FORWARD(j) { 3018 if (j) 3019 memcpy(stuff + 1, extra, extra_len); 3020 if (dst->u.pict.root) { 3021 int x_off = screenInfo.screens[j]->x; 3022 int y_off = screenInfo.screens[j]->y; 3023 3024 if (x_off || y_off) { 3025 xPointFixed *fixed = (xPointFixed *) (stuff + 1); 3026 int i = extra_len / sizeof(xPointFixed); 3027 3028 while (i--) { 3029 fixed->x -= x_off; 3030 fixed->y -= y_off; 3031 fixed++; 3032 } 3033 } 3034 } 3035 3036 stuff->src = src->info[j].id; 3037 stuff->dst = dst->info[j].id; 3038 result = (*PanoramiXSaveRenderVector[X_RenderTriStrip]) (client); 3039 3040 if (result != Success) 3041 break; 3042 } 3043 3044 free(extra); 3045 } 3046 3047 return result; 3048 } 3049 3050 static int 3051 PanoramiXRenderTriFan(ClientPtr client) 3052 { 3053 PanoramiXRes *src, *dst; 3054 int result = Success, j; 3055 3056 REQUEST(xRenderTriFanReq); 3057 char *extra; 3058 int extra_len; 3059 3060 REQUEST_AT_LEAST_SIZE(xRenderTriFanReq); 3061 3062 VERIFY_XIN_PICTURE(src, stuff->src, client, DixReadAccess); 3063 VERIFY_XIN_PICTURE(dst, stuff->dst, client, DixWriteAccess); 3064 3065 extra_len = (client->req_len << 2) - sizeof(xRenderTriFanReq); 3066 3067 if (extra_len && (extra = (char *) malloc(extra_len))) { 3068 memcpy(extra, stuff + 1, extra_len); 3069 3070 FOR_NSCREENS_FORWARD(j) { 3071 if (j) 3072 memcpy(stuff + 1, extra, extra_len); 3073 if (dst->u.pict.root) { 3074 int x_off = screenInfo.screens[j]->x; 3075 int y_off = screenInfo.screens[j]->y; 3076 3077 if (x_off || y_off) { 3078 xPointFixed *fixed = (xPointFixed *) (stuff + 1); 3079 int i = extra_len / sizeof(xPointFixed); 3080 3081 while (i--) { 3082 fixed->x -= x_off; 3083 fixed->y -= y_off; 3084 fixed++; 3085 } 3086 } 3087 } 3088 3089 stuff->src = src->info[j].id; 3090 stuff->dst = dst->info[j].id; 3091 result = (*PanoramiXSaveRenderVector[X_RenderTriFan]) (client); 3092 3093 if (result != Success) 3094 break; 3095 } 3096 3097 free(extra); 3098 } 3099 3100 return result; 3101 } 3102 3103 static int 3104 PanoramiXRenderAddTraps(ClientPtr client) 3105 { 3106 PanoramiXRes *picture; 3107 int result = Success, j; 3108 3109 REQUEST(xRenderAddTrapsReq); 3110 char *extra; 3111 int extra_len; 3112 INT16 x_off, y_off; 3113 3114 REQUEST_AT_LEAST_SIZE(xRenderAddTrapsReq); 3115 VERIFY_XIN_PICTURE(picture, stuff->picture, client, DixWriteAccess); 3116 extra_len = (client->req_len << 2) - sizeof(xRenderAddTrapsReq); 3117 if (extra_len && (extra = (char *) malloc(extra_len))) { 3118 memcpy(extra, stuff + 1, extra_len); 3119 x_off = stuff->xOff; 3120 y_off = stuff->yOff; 3121 FOR_NSCREENS_FORWARD(j) { 3122 if (j) 3123 memcpy(stuff + 1, extra, extra_len); 3124 stuff->picture = picture->info[j].id; 3125 3126 if (picture->u.pict.root) { 3127 stuff->xOff = x_off + screenInfo.screens[j]->x; 3128 stuff->yOff = y_off + screenInfo.screens[j]->y; 3129 } 3130 result = (*PanoramiXSaveRenderVector[X_RenderAddTraps]) (client); 3131 if (result != Success) 3132 break; 3133 } 3134 free(extra); 3135 } 3136 3137 return result; 3138 } 3139 3140 static int 3141 PanoramiXRenderCreateSolidFill(ClientPtr client) 3142 { 3143 REQUEST(xRenderCreateSolidFillReq); 3144 PanoramiXRes *newPict; 3145 int result = Success, j; 3146 3147 REQUEST_AT_LEAST_SIZE(xRenderCreateSolidFillReq); 3148 3149 if (!(newPict = (PanoramiXRes *) malloc(sizeof(PanoramiXRes)))) 3150 return BadAlloc; 3151 3152 newPict->type = XRT_PICTURE; 3153 panoramix_setup_ids(newPict, client, stuff->pid); 3154 newPict->u.pict.root = FALSE; 3155 3156 FOR_NSCREENS_BACKWARD(j) { 3157 stuff->pid = newPict->info[j].id; 3158 result = (*PanoramiXSaveRenderVector[X_RenderCreateSolidFill]) (client); 3159 if (result != Success) 3160 break; 3161 } 3162 3163 if (result == Success) 3164 AddResource(newPict->info[0].id, XRT_PICTURE, newPict); 3165 else 3166 free(newPict); 3167 3168 return result; 3169 } 3170 3171 static int 3172 PanoramiXRenderCreateLinearGradient(ClientPtr client) 3173 { 3174 REQUEST(xRenderCreateLinearGradientReq); 3175 PanoramiXRes *newPict; 3176 int result = Success, j; 3177 3178 REQUEST_AT_LEAST_SIZE(xRenderCreateLinearGradientReq); 3179 3180 if (!(newPict = (PanoramiXRes *) malloc(sizeof(PanoramiXRes)))) 3181 return BadAlloc; 3182 3183 newPict->type = XRT_PICTURE; 3184 panoramix_setup_ids(newPict, client, stuff->pid); 3185 newPict->u.pict.root = FALSE; 3186 3187 FOR_NSCREENS_BACKWARD(j) { 3188 stuff->pid = newPict->info[j].id; 3189 result = 3190 (*PanoramiXSaveRenderVector[X_RenderCreateLinearGradient]) (client); 3191 if (result != Success) 3192 break; 3193 } 3194 3195 if (result == Success) 3196 AddResource(newPict->info[0].id, XRT_PICTURE, newPict); 3197 else 3198 free(newPict); 3199 3200 return result; 3201 } 3202 3203 static int 3204 PanoramiXRenderCreateRadialGradient(ClientPtr client) 3205 { 3206 REQUEST(xRenderCreateRadialGradientReq); 3207 PanoramiXRes *newPict; 3208 int result = Success, j; 3209 3210 REQUEST_AT_LEAST_SIZE(xRenderCreateRadialGradientReq); 3211 3212 if (!(newPict = (PanoramiXRes *) malloc(sizeof(PanoramiXRes)))) 3213 return BadAlloc; 3214 3215 newPict->type = XRT_PICTURE; 3216 panoramix_setup_ids(newPict, client, stuff->pid); 3217 newPict->u.pict.root = FALSE; 3218 3219 FOR_NSCREENS_BACKWARD(j) { 3220 stuff->pid = newPict->info[j].id; 3221 result = 3222 (*PanoramiXSaveRenderVector[X_RenderCreateRadialGradient]) (client); 3223 if (result != Success) 3224 break; 3225 } 3226 3227 if (result == Success) 3228 AddResource(newPict->info[0].id, XRT_PICTURE, newPict); 3229 else 3230 free(newPict); 3231 3232 return result; 3233 } 3234 3235 static int 3236 PanoramiXRenderCreateConicalGradient(ClientPtr client) 3237 { 3238 REQUEST(xRenderCreateConicalGradientReq); 3239 PanoramiXRes *newPict; 3240 int result = Success, j; 3241 3242 REQUEST_AT_LEAST_SIZE(xRenderCreateConicalGradientReq); 3243 3244 if (!(newPict = (PanoramiXRes *) malloc(sizeof(PanoramiXRes)))) 3245 return BadAlloc; 3246 3247 newPict->type = XRT_PICTURE; 3248 panoramix_setup_ids(newPict, client, stuff->pid); 3249 newPict->u.pict.root = FALSE; 3250 3251 FOR_NSCREENS_BACKWARD(j) { 3252 stuff->pid = newPict->info[j].id; 3253 result = 3254 (*PanoramiXSaveRenderVector[X_RenderCreateConicalGradient]) 3255 (client); 3256 if (result != Success) 3257 break; 3258 } 3259 3260 if (result == Success) 3261 AddResource(newPict->info[0].id, XRT_PICTURE, newPict); 3262 else 3263 free(newPict); 3264 3265 return result; 3266 } 3267 3268 void 3269 PanoramiXRenderInit(void) 3270 { 3271 int i; 3272 3273 XRT_PICTURE = CreateNewResourceType(XineramaDeleteResource, 3274 "XineramaPicture"); 3275 if (RenderErrBase) 3276 SetResourceTypeErrorValue(XRT_PICTURE, RenderErrBase + BadPicture); 3277 for (i = 0; i < RenderNumberRequests; i++) 3278 PanoramiXSaveRenderVector[i] = ProcRenderVector[i]; 3279 /* 3280 * Stuff in Xinerama aware request processing hooks 3281 */ 3282 ProcRenderVector[X_RenderCreatePicture] = PanoramiXRenderCreatePicture; 3283 ProcRenderVector[X_RenderChangePicture] = PanoramiXRenderChangePicture; 3284 ProcRenderVector[X_RenderSetPictureTransform] = 3285 PanoramiXRenderSetPictureTransform; 3286 ProcRenderVector[X_RenderSetPictureFilter] = 3287 PanoramiXRenderSetPictureFilter; 3288 ProcRenderVector[X_RenderSetPictureClipRectangles] = 3289 PanoramiXRenderSetPictureClipRectangles; 3290 ProcRenderVector[X_RenderFreePicture] = PanoramiXRenderFreePicture; 3291 ProcRenderVector[X_RenderComposite] = PanoramiXRenderComposite; 3292 ProcRenderVector[X_RenderCompositeGlyphs8] = PanoramiXRenderCompositeGlyphs; 3293 ProcRenderVector[X_RenderCompositeGlyphs16] = 3294 PanoramiXRenderCompositeGlyphs; 3295 ProcRenderVector[X_RenderCompositeGlyphs32] = 3296 PanoramiXRenderCompositeGlyphs; 3297 ProcRenderVector[X_RenderFillRectangles] = PanoramiXRenderFillRectangles; 3298 3299 ProcRenderVector[X_RenderTrapezoids] = PanoramiXRenderTrapezoids; 3300 ProcRenderVector[X_RenderTriangles] = PanoramiXRenderTriangles; 3301 ProcRenderVector[X_RenderTriStrip] = PanoramiXRenderTriStrip; 3302 ProcRenderVector[X_RenderTriFan] = PanoramiXRenderTriFan; 3303 ProcRenderVector[X_RenderAddTraps] = PanoramiXRenderAddTraps; 3304 3305 ProcRenderVector[X_RenderCreateSolidFill] = PanoramiXRenderCreateSolidFill; 3306 ProcRenderVector[X_RenderCreateLinearGradient] = 3307 PanoramiXRenderCreateLinearGradient; 3308 ProcRenderVector[X_RenderCreateRadialGradient] = 3309 PanoramiXRenderCreateRadialGradient; 3310 ProcRenderVector[X_RenderCreateConicalGradient] = 3311 PanoramiXRenderCreateConicalGradient; 3312 } 3313 3314 void 3315 PanoramiXRenderReset(void) 3316 { 3317 int i; 3318 3319 for (i = 0; i < RenderNumberRequests; i++) 3320 ProcRenderVector[i] = PanoramiXSaveRenderVector[i]; 3321 RenderErrBase = 0; 3322 } 3323 3324 #endif /* PANORAMIX */