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