render.c revision 875c6e4f
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 cursors = xallocarray(ncursor, sizeof(CursorPtr) + sizeof(CARD32)); 1799 if (!cursors) 1800 return BadAlloc; 1801 deltas = (CARD32 *) (cursors + ncursor); 1802 elt = (xAnimCursorElt *) (stuff + 1); 1803 for (i = 0; i < ncursor; i++) { 1804 ret = dixLookupResourceByType((void **) (cursors + i), elt->cursor, 1805 RT_CURSOR, client, DixReadAccess); 1806 if (ret != Success) { 1807 free(cursors); 1808 return ret; 1809 } 1810 deltas[i] = elt->delay; 1811 elt++; 1812 } 1813 ret = AnimCursorCreate(cursors, deltas, ncursor, &pCursor, client, 1814 stuff->cid); 1815 free(cursors); 1816 if (ret != Success) 1817 return ret; 1818 1819 if (AddResource(stuff->cid, RT_CURSOR, (void *) pCursor)) 1820 return Success; 1821 return BadAlloc; 1822} 1823 1824static int 1825ProcRenderAddTraps(ClientPtr client) 1826{ 1827 int ntraps; 1828 PicturePtr pPicture; 1829 1830 REQUEST(xRenderAddTrapsReq); 1831 1832 REQUEST_AT_LEAST_SIZE(xRenderAddTrapsReq); 1833 VERIFY_PICTURE(pPicture, stuff->picture, client, DixWriteAccess); 1834 if (!pPicture->pDrawable) 1835 return BadDrawable; 1836 ntraps = (client->req_len << 2) - sizeof(xRenderAddTrapsReq); 1837 if (ntraps % sizeof(xTrap)) 1838 return BadLength; 1839 ntraps /= sizeof(xTrap); 1840 if (ntraps) 1841 AddTraps(pPicture, 1842 stuff->xOff, stuff->yOff, ntraps, (xTrap *) &stuff[1]); 1843 return Success; 1844} 1845 1846static int 1847ProcRenderCreateSolidFill(ClientPtr client) 1848{ 1849 PicturePtr pPicture; 1850 int error = 0; 1851 1852 REQUEST(xRenderCreateSolidFillReq); 1853 1854 REQUEST_AT_LEAST_SIZE(xRenderCreateSolidFillReq); 1855 1856 LEGAL_NEW_RESOURCE(stuff->pid, client); 1857 1858 pPicture = CreateSolidPicture(stuff->pid, &stuff->color, &error); 1859 if (!pPicture) 1860 return error; 1861 /* security creation/labeling check */ 1862 error = XaceHook(XACE_RESOURCE_ACCESS, client, stuff->pid, PictureType, 1863 pPicture, RT_NONE, NULL, DixCreateAccess); 1864 if (error != Success) 1865 return error; 1866 if (!AddResource(stuff->pid, PictureType, (void *) pPicture)) 1867 return BadAlloc; 1868 return Success; 1869} 1870 1871static int 1872ProcRenderCreateLinearGradient(ClientPtr client) 1873{ 1874 PicturePtr pPicture; 1875 int len; 1876 int error = 0; 1877 xFixed *stops; 1878 xRenderColor *colors; 1879 1880 REQUEST(xRenderCreateLinearGradientReq); 1881 1882 REQUEST_AT_LEAST_SIZE(xRenderCreateLinearGradientReq); 1883 1884 LEGAL_NEW_RESOURCE(stuff->pid, client); 1885 1886 len = (client->req_len << 2) - sizeof(xRenderCreateLinearGradientReq); 1887 if (stuff->nStops > UINT32_MAX / (sizeof(xFixed) + sizeof(xRenderColor))) 1888 return BadLength; 1889 if (len != stuff->nStops * (sizeof(xFixed) + sizeof(xRenderColor))) 1890 return BadLength; 1891 1892 stops = (xFixed *) (stuff + 1); 1893 colors = (xRenderColor *) (stops + stuff->nStops); 1894 1895 pPicture = CreateLinearGradientPicture(stuff->pid, &stuff->p1, &stuff->p2, 1896 stuff->nStops, stops, colors, 1897 &error); 1898 if (!pPicture) 1899 return error; 1900 /* security creation/labeling check */ 1901 error = XaceHook(XACE_RESOURCE_ACCESS, client, stuff->pid, PictureType, 1902 pPicture, RT_NONE, NULL, DixCreateAccess); 1903 if (error != Success) 1904 return error; 1905 if (!AddResource(stuff->pid, PictureType, (void *) pPicture)) 1906 return BadAlloc; 1907 return Success; 1908} 1909 1910static int 1911ProcRenderCreateRadialGradient(ClientPtr client) 1912{ 1913 PicturePtr pPicture; 1914 int len; 1915 int error = 0; 1916 xFixed *stops; 1917 xRenderColor *colors; 1918 1919 REQUEST(xRenderCreateRadialGradientReq); 1920 1921 REQUEST_AT_LEAST_SIZE(xRenderCreateRadialGradientReq); 1922 1923 LEGAL_NEW_RESOURCE(stuff->pid, client); 1924 1925 len = (client->req_len << 2) - sizeof(xRenderCreateRadialGradientReq); 1926 if (stuff->nStops > UINT32_MAX / (sizeof(xFixed) + sizeof(xRenderColor))) 1927 return BadLength; 1928 if (len != stuff->nStops * (sizeof(xFixed) + sizeof(xRenderColor))) 1929 return BadLength; 1930 1931 stops = (xFixed *) (stuff + 1); 1932 colors = (xRenderColor *) (stops + stuff->nStops); 1933 1934 pPicture = 1935 CreateRadialGradientPicture(stuff->pid, &stuff->inner, &stuff->outer, 1936 stuff->inner_radius, stuff->outer_radius, 1937 stuff->nStops, stops, colors, &error); 1938 if (!pPicture) 1939 return error; 1940 /* security creation/labeling check */ 1941 error = XaceHook(XACE_RESOURCE_ACCESS, client, stuff->pid, PictureType, 1942 pPicture, RT_NONE, NULL, DixCreateAccess); 1943 if (error != Success) 1944 return error; 1945 if (!AddResource(stuff->pid, PictureType, (void *) pPicture)) 1946 return BadAlloc; 1947 return Success; 1948} 1949 1950static int 1951ProcRenderCreateConicalGradient(ClientPtr client) 1952{ 1953 PicturePtr pPicture; 1954 int len; 1955 int error = 0; 1956 xFixed *stops; 1957 xRenderColor *colors; 1958 1959 REQUEST(xRenderCreateConicalGradientReq); 1960 1961 REQUEST_AT_LEAST_SIZE(xRenderCreateConicalGradientReq); 1962 1963 LEGAL_NEW_RESOURCE(stuff->pid, client); 1964 1965 len = (client->req_len << 2) - sizeof(xRenderCreateConicalGradientReq); 1966 if (stuff->nStops > UINT32_MAX / (sizeof(xFixed) + sizeof(xRenderColor))) 1967 return BadLength; 1968 if (len != stuff->nStops * (sizeof(xFixed) + sizeof(xRenderColor))) 1969 return BadLength; 1970 1971 stops = (xFixed *) (stuff + 1); 1972 colors = (xRenderColor *) (stops + stuff->nStops); 1973 1974 pPicture = 1975 CreateConicalGradientPicture(stuff->pid, &stuff->center, stuff->angle, 1976 stuff->nStops, stops, colors, &error); 1977 if (!pPicture) 1978 return error; 1979 /* security creation/labeling check */ 1980 error = XaceHook(XACE_RESOURCE_ACCESS, client, stuff->pid, PictureType, 1981 pPicture, RT_NONE, NULL, DixCreateAccess); 1982 if (error != Success) 1983 return error; 1984 if (!AddResource(stuff->pid, PictureType, (void *) pPicture)) 1985 return BadAlloc; 1986 return Success; 1987} 1988 1989static int 1990ProcRenderDispatch(ClientPtr client) 1991{ 1992 REQUEST(xReq); 1993 1994 if (stuff->data < RenderNumberRequests) 1995 return (*ProcRenderVector[stuff->data]) (client); 1996 else 1997 return BadRequest; 1998} 1999 2000static int _X_COLD 2001SProcRenderQueryVersion(ClientPtr client) 2002{ 2003 REQUEST(xRenderQueryVersionReq); 2004 REQUEST_SIZE_MATCH(xRenderQueryVersionReq); 2005 swaps(&stuff->length); 2006 swapl(&stuff->majorVersion); 2007 swapl(&stuff->minorVersion); 2008 return (*ProcRenderVector[stuff->renderReqType]) (client); 2009} 2010 2011static int _X_COLD 2012SProcRenderQueryPictFormats(ClientPtr client) 2013{ 2014 REQUEST(xRenderQueryPictFormatsReq); 2015 REQUEST_SIZE_MATCH(xRenderQueryPictFormatsReq); 2016 swaps(&stuff->length); 2017 return (*ProcRenderVector[stuff->renderReqType]) (client); 2018} 2019 2020static int _X_COLD 2021SProcRenderQueryPictIndexValues(ClientPtr client) 2022{ 2023 REQUEST(xRenderQueryPictIndexValuesReq); 2024 REQUEST_AT_LEAST_SIZE(xRenderQueryPictIndexValuesReq); 2025 swaps(&stuff->length); 2026 swapl(&stuff->format); 2027 return (*ProcRenderVector[stuff->renderReqType]) (client); 2028} 2029 2030static int _X_COLD 2031SProcRenderQueryDithers(ClientPtr client) 2032{ 2033 return BadImplementation; 2034} 2035 2036static int _X_COLD 2037SProcRenderCreatePicture(ClientPtr client) 2038{ 2039 REQUEST(xRenderCreatePictureReq); 2040 REQUEST_AT_LEAST_SIZE(xRenderCreatePictureReq); 2041 swaps(&stuff->length); 2042 swapl(&stuff->pid); 2043 swapl(&stuff->drawable); 2044 swapl(&stuff->format); 2045 swapl(&stuff->mask); 2046 SwapRestL(stuff); 2047 return (*ProcRenderVector[stuff->renderReqType]) (client); 2048} 2049 2050static int _X_COLD 2051SProcRenderChangePicture(ClientPtr client) 2052{ 2053 REQUEST(xRenderChangePictureReq); 2054 REQUEST_AT_LEAST_SIZE(xRenderChangePictureReq); 2055 swaps(&stuff->length); 2056 swapl(&stuff->picture); 2057 swapl(&stuff->mask); 2058 SwapRestL(stuff); 2059 return (*ProcRenderVector[stuff->renderReqType]) (client); 2060} 2061 2062static int _X_COLD 2063SProcRenderSetPictureClipRectangles(ClientPtr client) 2064{ 2065 REQUEST(xRenderSetPictureClipRectanglesReq); 2066 REQUEST_AT_LEAST_SIZE(xRenderSetPictureClipRectanglesReq); 2067 swaps(&stuff->length); 2068 swapl(&stuff->picture); 2069 swaps(&stuff->xOrigin); 2070 swaps(&stuff->yOrigin); 2071 SwapRestS(stuff); 2072 return (*ProcRenderVector[stuff->renderReqType]) (client); 2073} 2074 2075static int _X_COLD 2076SProcRenderFreePicture(ClientPtr client) 2077{ 2078 REQUEST(xRenderFreePictureReq); 2079 REQUEST_SIZE_MATCH(xRenderFreePictureReq); 2080 swaps(&stuff->length); 2081 swapl(&stuff->picture); 2082 return (*ProcRenderVector[stuff->renderReqType]) (client); 2083} 2084 2085static int _X_COLD 2086SProcRenderComposite(ClientPtr client) 2087{ 2088 REQUEST(xRenderCompositeReq); 2089 REQUEST_SIZE_MATCH(xRenderCompositeReq); 2090 swaps(&stuff->length); 2091 swapl(&stuff->src); 2092 swapl(&stuff->mask); 2093 swapl(&stuff->dst); 2094 swaps(&stuff->xSrc); 2095 swaps(&stuff->ySrc); 2096 swaps(&stuff->xMask); 2097 swaps(&stuff->yMask); 2098 swaps(&stuff->xDst); 2099 swaps(&stuff->yDst); 2100 swaps(&stuff->width); 2101 swaps(&stuff->height); 2102 return (*ProcRenderVector[stuff->renderReqType]) (client); 2103} 2104 2105static int _X_COLD 2106SProcRenderScale(ClientPtr client) 2107{ 2108 return BadImplementation; 2109} 2110 2111static int _X_COLD 2112SProcRenderTrapezoids(ClientPtr client) 2113{ 2114 REQUEST(xRenderTrapezoidsReq); 2115 2116 REQUEST_AT_LEAST_SIZE(xRenderTrapezoidsReq); 2117 swaps(&stuff->length); 2118 swapl(&stuff->src); 2119 swapl(&stuff->dst); 2120 swapl(&stuff->maskFormat); 2121 swaps(&stuff->xSrc); 2122 swaps(&stuff->ySrc); 2123 SwapRestL(stuff); 2124 return (*ProcRenderVector[stuff->renderReqType]) (client); 2125} 2126 2127static int _X_COLD 2128SProcRenderTriangles(ClientPtr client) 2129{ 2130 REQUEST(xRenderTrianglesReq); 2131 2132 REQUEST_AT_LEAST_SIZE(xRenderTrianglesReq); 2133 swaps(&stuff->length); 2134 swapl(&stuff->src); 2135 swapl(&stuff->dst); 2136 swapl(&stuff->maskFormat); 2137 swaps(&stuff->xSrc); 2138 swaps(&stuff->ySrc); 2139 SwapRestL(stuff); 2140 return (*ProcRenderVector[stuff->renderReqType]) (client); 2141} 2142 2143static int _X_COLD 2144SProcRenderTriStrip(ClientPtr client) 2145{ 2146 REQUEST(xRenderTriStripReq); 2147 2148 REQUEST_AT_LEAST_SIZE(xRenderTriStripReq); 2149 swaps(&stuff->length); 2150 swapl(&stuff->src); 2151 swapl(&stuff->dst); 2152 swapl(&stuff->maskFormat); 2153 swaps(&stuff->xSrc); 2154 swaps(&stuff->ySrc); 2155 SwapRestL(stuff); 2156 return (*ProcRenderVector[stuff->renderReqType]) (client); 2157} 2158 2159static int _X_COLD 2160SProcRenderTriFan(ClientPtr client) 2161{ 2162 REQUEST(xRenderTriFanReq); 2163 2164 REQUEST_AT_LEAST_SIZE(xRenderTriFanReq); 2165 swaps(&stuff->length); 2166 swapl(&stuff->src); 2167 swapl(&stuff->dst); 2168 swapl(&stuff->maskFormat); 2169 swaps(&stuff->xSrc); 2170 swaps(&stuff->ySrc); 2171 SwapRestL(stuff); 2172 return (*ProcRenderVector[stuff->renderReqType]) (client); 2173} 2174 2175static int _X_COLD 2176SProcRenderColorTrapezoids(ClientPtr client) 2177{ 2178 return BadImplementation; 2179} 2180 2181static int _X_COLD 2182SProcRenderColorTriangles(ClientPtr client) 2183{ 2184 return BadImplementation; 2185} 2186 2187static int _X_COLD 2188SProcRenderTransform(ClientPtr client) 2189{ 2190 return BadImplementation; 2191} 2192 2193static int _X_COLD 2194SProcRenderCreateGlyphSet(ClientPtr client) 2195{ 2196 REQUEST(xRenderCreateGlyphSetReq); 2197 REQUEST_SIZE_MATCH(xRenderCreateGlyphSetReq); 2198 swaps(&stuff->length); 2199 swapl(&stuff->gsid); 2200 swapl(&stuff->format); 2201 return (*ProcRenderVector[stuff->renderReqType]) (client); 2202} 2203 2204static int _X_COLD 2205SProcRenderReferenceGlyphSet(ClientPtr client) 2206{ 2207 REQUEST(xRenderReferenceGlyphSetReq); 2208 REQUEST_SIZE_MATCH(xRenderReferenceGlyphSetReq); 2209 swaps(&stuff->length); 2210 swapl(&stuff->gsid); 2211 swapl(&stuff->existing); 2212 return (*ProcRenderVector[stuff->renderReqType]) (client); 2213} 2214 2215static int _X_COLD 2216SProcRenderFreeGlyphSet(ClientPtr client) 2217{ 2218 REQUEST(xRenderFreeGlyphSetReq); 2219 REQUEST_SIZE_MATCH(xRenderFreeGlyphSetReq); 2220 swaps(&stuff->length); 2221 swapl(&stuff->glyphset); 2222 return (*ProcRenderVector[stuff->renderReqType]) (client); 2223} 2224 2225static int _X_COLD 2226SProcRenderAddGlyphs(ClientPtr client) 2227{ 2228 register int i; 2229 CARD32 *gids; 2230 void *end; 2231 xGlyphInfo *gi; 2232 2233 REQUEST(xRenderAddGlyphsReq); 2234 REQUEST_AT_LEAST_SIZE(xRenderAddGlyphsReq); 2235 swaps(&stuff->length); 2236 swapl(&stuff->glyphset); 2237 swapl(&stuff->nglyphs); 2238 if (stuff->nglyphs & 0xe0000000) 2239 return BadLength; 2240 end = (CARD8 *) stuff + (client->req_len << 2); 2241 gids = (CARD32 *) (stuff + 1); 2242 gi = (xGlyphInfo *) (gids + stuff->nglyphs); 2243 if ((char *) end - (char *) (gids + stuff->nglyphs) < 0) 2244 return BadLength; 2245 if ((char *) end - (char *) (gi + stuff->nglyphs) < 0) 2246 return BadLength; 2247 for (i = 0; i < stuff->nglyphs; i++) { 2248 swapl(&gids[i]); 2249 swaps(&gi[i].width); 2250 swaps(&gi[i].height); 2251 swaps(&gi[i].x); 2252 swaps(&gi[i].y); 2253 swaps(&gi[i].xOff); 2254 swaps(&gi[i].yOff); 2255 } 2256 return (*ProcRenderVector[stuff->renderReqType]) (client); 2257} 2258 2259static int _X_COLD 2260SProcRenderAddGlyphsFromPicture(ClientPtr client) 2261{ 2262 return BadImplementation; 2263} 2264 2265static int _X_COLD 2266SProcRenderFreeGlyphs(ClientPtr client) 2267{ 2268 REQUEST(xRenderFreeGlyphsReq); 2269 REQUEST_AT_LEAST_SIZE(xRenderFreeGlyphsReq); 2270 swaps(&stuff->length); 2271 swapl(&stuff->glyphset); 2272 SwapRestL(stuff); 2273 return (*ProcRenderVector[stuff->renderReqType]) (client); 2274} 2275 2276static int _X_COLD 2277SProcRenderCompositeGlyphs(ClientPtr client) 2278{ 2279 xGlyphElt *elt; 2280 CARD8 *buffer; 2281 CARD8 *end; 2282 int space; 2283 int i; 2284 int size; 2285 2286 REQUEST(xRenderCompositeGlyphsReq); 2287 REQUEST_AT_LEAST_SIZE(xRenderCompositeGlyphsReq); 2288 2289 switch (stuff->renderReqType) { 2290 default: 2291 size = 1; 2292 break; 2293 case X_RenderCompositeGlyphs16: 2294 size = 2; 2295 break; 2296 case X_RenderCompositeGlyphs32: 2297 size = 4; 2298 break; 2299 } 2300 2301 swaps(&stuff->length); 2302 swapl(&stuff->src); 2303 swapl(&stuff->dst); 2304 swapl(&stuff->maskFormat); 2305 swapl(&stuff->glyphset); 2306 swaps(&stuff->xSrc); 2307 swaps(&stuff->ySrc); 2308 buffer = (CARD8 *) (stuff + 1); 2309 end = (CARD8 *) stuff + (client->req_len << 2); 2310 while (buffer + sizeof(xGlyphElt) < end) { 2311 elt = (xGlyphElt *) buffer; 2312 buffer += sizeof(xGlyphElt); 2313 2314 swaps(&elt->deltax); 2315 swaps(&elt->deltay); 2316 2317 i = elt->len; 2318 if (i == 0xff) { 2319 if (buffer + 4 > end) { 2320 return BadLength; 2321 } 2322 swapl((int *) buffer); 2323 buffer += 4; 2324 } 2325 else { 2326 space = size * i; 2327 switch (size) { 2328 case 1: 2329 buffer += i; 2330 break; 2331 case 2: 2332 if (buffer + i * 2 > end) { 2333 return BadLength; 2334 } 2335 while (i--) { 2336 swaps((short *) buffer); 2337 buffer += 2; 2338 } 2339 break; 2340 case 4: 2341 if (buffer + i * 4 > end) { 2342 return BadLength; 2343 } 2344 while (i--) { 2345 swapl((int *) buffer); 2346 buffer += 4; 2347 } 2348 break; 2349 } 2350 if (space & 3) 2351 buffer += 4 - (space & 3); 2352 } 2353 } 2354 return (*ProcRenderVector[stuff->renderReqType]) (client); 2355} 2356 2357static int _X_COLD 2358SProcRenderFillRectangles(ClientPtr client) 2359{ 2360 REQUEST(xRenderFillRectanglesReq); 2361 2362 REQUEST_AT_LEAST_SIZE(xRenderFillRectanglesReq); 2363 swaps(&stuff->length); 2364 swapl(&stuff->dst); 2365 swaps(&stuff->color.red); 2366 swaps(&stuff->color.green); 2367 swaps(&stuff->color.blue); 2368 swaps(&stuff->color.alpha); 2369 SwapRestS(stuff); 2370 return (*ProcRenderVector[stuff->renderReqType]) (client); 2371} 2372 2373static int _X_COLD 2374SProcRenderCreateCursor(ClientPtr client) 2375{ 2376 REQUEST(xRenderCreateCursorReq); 2377 REQUEST_SIZE_MATCH(xRenderCreateCursorReq); 2378 2379 swaps(&stuff->length); 2380 swapl(&stuff->cid); 2381 swapl(&stuff->src); 2382 swaps(&stuff->x); 2383 swaps(&stuff->y); 2384 return (*ProcRenderVector[stuff->renderReqType]) (client); 2385} 2386 2387static int _X_COLD 2388SProcRenderSetPictureTransform(ClientPtr client) 2389{ 2390 REQUEST(xRenderSetPictureTransformReq); 2391 REQUEST_SIZE_MATCH(xRenderSetPictureTransformReq); 2392 2393 swaps(&stuff->length); 2394 swapl(&stuff->picture); 2395 swapl(&stuff->transform.matrix11); 2396 swapl(&stuff->transform.matrix12); 2397 swapl(&stuff->transform.matrix13); 2398 swapl(&stuff->transform.matrix21); 2399 swapl(&stuff->transform.matrix22); 2400 swapl(&stuff->transform.matrix23); 2401 swapl(&stuff->transform.matrix31); 2402 swapl(&stuff->transform.matrix32); 2403 swapl(&stuff->transform.matrix33); 2404 return (*ProcRenderVector[stuff->renderReqType]) (client); 2405} 2406 2407static int _X_COLD 2408SProcRenderQueryFilters(ClientPtr client) 2409{ 2410 REQUEST(xRenderQueryFiltersReq); 2411 REQUEST_SIZE_MATCH(xRenderQueryFiltersReq); 2412 2413 swaps(&stuff->length); 2414 swapl(&stuff->drawable); 2415 return (*ProcRenderVector[stuff->renderReqType]) (client); 2416} 2417 2418static int _X_COLD 2419SProcRenderSetPictureFilter(ClientPtr client) 2420{ 2421 REQUEST(xRenderSetPictureFilterReq); 2422 REQUEST_AT_LEAST_SIZE(xRenderSetPictureFilterReq); 2423 2424 swaps(&stuff->length); 2425 swapl(&stuff->picture); 2426 swaps(&stuff->nbytes); 2427 return (*ProcRenderVector[stuff->renderReqType]) (client); 2428} 2429 2430static int _X_COLD 2431SProcRenderCreateAnimCursor(ClientPtr client) 2432{ 2433 REQUEST(xRenderCreateAnimCursorReq); 2434 REQUEST_AT_LEAST_SIZE(xRenderCreateAnimCursorReq); 2435 2436 swaps(&stuff->length); 2437 swapl(&stuff->cid); 2438 SwapRestL(stuff); 2439 return (*ProcRenderVector[stuff->renderReqType]) (client); 2440} 2441 2442static int _X_COLD 2443SProcRenderAddTraps(ClientPtr client) 2444{ 2445 REQUEST(xRenderAddTrapsReq); 2446 REQUEST_AT_LEAST_SIZE(xRenderAddTrapsReq); 2447 2448 swaps(&stuff->length); 2449 swapl(&stuff->picture); 2450 swaps(&stuff->xOff); 2451 swaps(&stuff->yOff); 2452 SwapRestL(stuff); 2453 return (*ProcRenderVector[stuff->renderReqType]) (client); 2454} 2455 2456static int _X_COLD 2457SProcRenderCreateSolidFill(ClientPtr client) 2458{ 2459 REQUEST(xRenderCreateSolidFillReq); 2460 REQUEST_AT_LEAST_SIZE(xRenderCreateSolidFillReq); 2461 2462 swaps(&stuff->length); 2463 swapl(&stuff->pid); 2464 swaps(&stuff->color.alpha); 2465 swaps(&stuff->color.red); 2466 swaps(&stuff->color.green); 2467 swaps(&stuff->color.blue); 2468 return (*ProcRenderVector[stuff->renderReqType]) (client); 2469} 2470 2471static void _X_COLD 2472swapStops(void *stuff, int num) 2473{ 2474 int i; 2475 CARD32 *stops; 2476 CARD16 *colors; 2477 2478 stops = (CARD32 *) (stuff); 2479 for (i = 0; i < num; ++i) { 2480 swapl(stops); 2481 ++stops; 2482 } 2483 colors = (CARD16 *) (stops); 2484 for (i = 0; i < 4 * num; ++i) { 2485 swaps(colors); 2486 ++colors; 2487 } 2488} 2489 2490static int _X_COLD 2491SProcRenderCreateLinearGradient(ClientPtr client) 2492{ 2493 int len; 2494 2495 REQUEST(xRenderCreateLinearGradientReq); 2496 REQUEST_AT_LEAST_SIZE(xRenderCreateLinearGradientReq); 2497 2498 swaps(&stuff->length); 2499 swapl(&stuff->pid); 2500 swapl(&stuff->p1.x); 2501 swapl(&stuff->p1.y); 2502 swapl(&stuff->p2.x); 2503 swapl(&stuff->p2.y); 2504 swapl(&stuff->nStops); 2505 2506 len = (client->req_len << 2) - sizeof(xRenderCreateLinearGradientReq); 2507 if (stuff->nStops > UINT32_MAX / (sizeof(xFixed) + sizeof(xRenderColor))) 2508 return BadLength; 2509 if (len != stuff->nStops * (sizeof(xFixed) + sizeof(xRenderColor))) 2510 return BadLength; 2511 2512 swapStops(stuff + 1, stuff->nStops); 2513 2514 return (*ProcRenderVector[stuff->renderReqType]) (client); 2515} 2516 2517static int _X_COLD 2518SProcRenderCreateRadialGradient(ClientPtr client) 2519{ 2520 int len; 2521 2522 REQUEST(xRenderCreateRadialGradientReq); 2523 REQUEST_AT_LEAST_SIZE(xRenderCreateRadialGradientReq); 2524 2525 swaps(&stuff->length); 2526 swapl(&stuff->pid); 2527 swapl(&stuff->inner.x); 2528 swapl(&stuff->inner.y); 2529 swapl(&stuff->outer.x); 2530 swapl(&stuff->outer.y); 2531 swapl(&stuff->inner_radius); 2532 swapl(&stuff->outer_radius); 2533 swapl(&stuff->nStops); 2534 2535 len = (client->req_len << 2) - sizeof(xRenderCreateRadialGradientReq); 2536 if (stuff->nStops > UINT32_MAX / (sizeof(xFixed) + sizeof(xRenderColor))) 2537 return BadLength; 2538 if (len != stuff->nStops * (sizeof(xFixed) + sizeof(xRenderColor))) 2539 return BadLength; 2540 2541 swapStops(stuff + 1, stuff->nStops); 2542 2543 return (*ProcRenderVector[stuff->renderReqType]) (client); 2544} 2545 2546static int _X_COLD 2547SProcRenderCreateConicalGradient(ClientPtr client) 2548{ 2549 int len; 2550 2551 REQUEST(xRenderCreateConicalGradientReq); 2552 REQUEST_AT_LEAST_SIZE(xRenderCreateConicalGradientReq); 2553 2554 swaps(&stuff->length); 2555 swapl(&stuff->pid); 2556 swapl(&stuff->center.x); 2557 swapl(&stuff->center.y); 2558 swapl(&stuff->angle); 2559 swapl(&stuff->nStops); 2560 2561 len = (client->req_len << 2) - sizeof(xRenderCreateConicalGradientReq); 2562 if (stuff->nStops > UINT32_MAX / (sizeof(xFixed) + sizeof(xRenderColor))) 2563 return BadLength; 2564 if (len != stuff->nStops * (sizeof(xFixed) + sizeof(xRenderColor))) 2565 return BadLength; 2566 2567 swapStops(stuff + 1, stuff->nStops); 2568 2569 return (*ProcRenderVector[stuff->renderReqType]) (client); 2570} 2571 2572static int _X_COLD 2573SProcRenderDispatch(ClientPtr client) 2574{ 2575 REQUEST(xReq); 2576 2577 if (stuff->data < RenderNumberRequests) 2578 return (*SProcRenderVector[stuff->data]) (client); 2579 else 2580 return BadRequest; 2581} 2582 2583#ifdef PANORAMIX 2584#define VERIFY_XIN_PICTURE(pPicture, pid, client, mode) {\ 2585 int rc = dixLookupResourceByType((void **)&(pPicture), pid,\ 2586 XRT_PICTURE, client, mode);\ 2587 if (rc != Success)\ 2588 return rc;\ 2589} 2590 2591#define VERIFY_XIN_ALPHA(pPicture, pid, client, mode) {\ 2592 if (pid == None) \ 2593 pPicture = 0; \ 2594 else { \ 2595 VERIFY_XIN_PICTURE(pPicture, pid, client, mode); \ 2596 } \ 2597} \ 2598 2599int (*PanoramiXSaveRenderVector[RenderNumberRequests]) (ClientPtr); 2600 2601static int 2602PanoramiXRenderCreatePicture(ClientPtr client) 2603{ 2604 REQUEST(xRenderCreatePictureReq); 2605 PanoramiXRes *refDraw, *newPict; 2606 int result, j; 2607 2608 REQUEST_AT_LEAST_SIZE(xRenderCreatePictureReq); 2609 result = dixLookupResourceByClass((void **) &refDraw, stuff->drawable, 2610 XRC_DRAWABLE, client, DixWriteAccess); 2611 if (result != Success) 2612 return (result == BadValue) ? BadDrawable : result; 2613 if (!(newPict = (PanoramiXRes *) malloc(sizeof(PanoramiXRes)))) 2614 return BadAlloc; 2615 newPict->type = XRT_PICTURE; 2616 panoramix_setup_ids(newPict, client, stuff->pid); 2617 2618 if (refDraw->type == XRT_WINDOW && 2619 stuff->drawable == screenInfo.screens[0]->root->drawable.id) { 2620 newPict->u.pict.root = TRUE; 2621 } 2622 else 2623 newPict->u.pict.root = FALSE; 2624 2625 FOR_NSCREENS_BACKWARD(j) { 2626 stuff->pid = newPict->info[j].id; 2627 stuff->drawable = refDraw->info[j].id; 2628 result = (*PanoramiXSaveRenderVector[X_RenderCreatePicture]) (client); 2629 if (result != Success) 2630 break; 2631 } 2632 2633 if (result == Success) 2634 AddResource(newPict->info[0].id, XRT_PICTURE, newPict); 2635 else 2636 free(newPict); 2637 2638 return result; 2639} 2640 2641static int 2642PanoramiXRenderChangePicture(ClientPtr client) 2643{ 2644 PanoramiXRes *pict; 2645 int result = Success, j; 2646 2647 REQUEST(xRenderChangePictureReq); 2648 2649 REQUEST_AT_LEAST_SIZE(xRenderChangePictureReq); 2650 2651 VERIFY_XIN_PICTURE(pict, stuff->picture, client, DixWriteAccess); 2652 2653 FOR_NSCREENS_BACKWARD(j) { 2654 stuff->picture = pict->info[j].id; 2655 result = (*PanoramiXSaveRenderVector[X_RenderChangePicture]) (client); 2656 if (result != Success) 2657 break; 2658 } 2659 2660 return result; 2661} 2662 2663static int 2664PanoramiXRenderSetPictureClipRectangles(ClientPtr client) 2665{ 2666 REQUEST(xRenderSetPictureClipRectanglesReq); 2667 int result = Success, j; 2668 PanoramiXRes *pict; 2669 2670 REQUEST_AT_LEAST_SIZE(xRenderSetPictureClipRectanglesReq); 2671 2672 VERIFY_XIN_PICTURE(pict, stuff->picture, client, DixWriteAccess); 2673 2674 FOR_NSCREENS_BACKWARD(j) { 2675 stuff->picture = pict->info[j].id; 2676 result = 2677 (*PanoramiXSaveRenderVector[X_RenderSetPictureClipRectangles]) 2678 (client); 2679 if (result != Success) 2680 break; 2681 } 2682 2683 return result; 2684} 2685 2686static int 2687PanoramiXRenderSetPictureTransform(ClientPtr client) 2688{ 2689 REQUEST(xRenderSetPictureTransformReq); 2690 int result = Success, j; 2691 PanoramiXRes *pict; 2692 2693 REQUEST_AT_LEAST_SIZE(xRenderSetPictureTransformReq); 2694 2695 VERIFY_XIN_PICTURE(pict, stuff->picture, client, DixWriteAccess); 2696 2697 FOR_NSCREENS_BACKWARD(j) { 2698 stuff->picture = pict->info[j].id; 2699 result = 2700 (*PanoramiXSaveRenderVector[X_RenderSetPictureTransform]) (client); 2701 if (result != Success) 2702 break; 2703 } 2704 2705 return result; 2706} 2707 2708static int 2709PanoramiXRenderSetPictureFilter(ClientPtr client) 2710{ 2711 REQUEST(xRenderSetPictureFilterReq); 2712 int result = Success, j; 2713 PanoramiXRes *pict; 2714 2715 REQUEST_AT_LEAST_SIZE(xRenderSetPictureFilterReq); 2716 2717 VERIFY_XIN_PICTURE(pict, stuff->picture, client, DixWriteAccess); 2718 2719 FOR_NSCREENS_BACKWARD(j) { 2720 stuff->picture = pict->info[j].id; 2721 result = 2722 (*PanoramiXSaveRenderVector[X_RenderSetPictureFilter]) (client); 2723 if (result != Success) 2724 break; 2725 } 2726 2727 return result; 2728} 2729 2730static int 2731PanoramiXRenderFreePicture(ClientPtr client) 2732{ 2733 PanoramiXRes *pict; 2734 int result = Success, j; 2735 2736 REQUEST(xRenderFreePictureReq); 2737 2738 REQUEST_SIZE_MATCH(xRenderFreePictureReq); 2739 2740 client->errorValue = stuff->picture; 2741 2742 VERIFY_XIN_PICTURE(pict, stuff->picture, client, DixDestroyAccess); 2743 2744 FOR_NSCREENS_BACKWARD(j) { 2745 stuff->picture = pict->info[j].id; 2746 result = (*PanoramiXSaveRenderVector[X_RenderFreePicture]) (client); 2747 if (result != Success) 2748 break; 2749 } 2750 2751 /* Since ProcRenderFreePicture is using FreeResource, it will free 2752 our resource for us on the last pass through the loop above */ 2753 2754 return result; 2755} 2756 2757static int 2758PanoramiXRenderComposite(ClientPtr client) 2759{ 2760 PanoramiXRes *src, *msk, *dst; 2761 int result = Success, j; 2762 xRenderCompositeReq orig; 2763 2764 REQUEST(xRenderCompositeReq); 2765 2766 REQUEST_SIZE_MATCH(xRenderCompositeReq); 2767 2768 VERIFY_XIN_PICTURE(src, stuff->src, client, DixReadAccess); 2769 VERIFY_XIN_ALPHA(msk, stuff->mask, client, DixReadAccess); 2770 VERIFY_XIN_PICTURE(dst, stuff->dst, client, DixWriteAccess); 2771 2772 orig = *stuff; 2773 2774 FOR_NSCREENS_FORWARD(j) { 2775 stuff->src = src->info[j].id; 2776 if (src->u.pict.root) { 2777 stuff->xSrc = orig.xSrc - screenInfo.screens[j]->x; 2778 stuff->ySrc = orig.ySrc - screenInfo.screens[j]->y; 2779 } 2780 stuff->dst = dst->info[j].id; 2781 if (dst->u.pict.root) { 2782 stuff->xDst = orig.xDst - screenInfo.screens[j]->x; 2783 stuff->yDst = orig.yDst - screenInfo.screens[j]->y; 2784 } 2785 if (msk) { 2786 stuff->mask = msk->info[j].id; 2787 if (msk->u.pict.root) { 2788 stuff->xMask = orig.xMask - screenInfo.screens[j]->x; 2789 stuff->yMask = orig.yMask - screenInfo.screens[j]->y; 2790 } 2791 } 2792 result = (*PanoramiXSaveRenderVector[X_RenderComposite]) (client); 2793 if (result != Success) 2794 break; 2795 } 2796 2797 return result; 2798} 2799 2800static int 2801PanoramiXRenderCompositeGlyphs(ClientPtr client) 2802{ 2803 PanoramiXRes *src, *dst; 2804 int result = Success, j; 2805 2806 REQUEST(xRenderCompositeGlyphsReq); 2807 xGlyphElt origElt, *elt; 2808 INT16 xSrc, ySrc; 2809 2810 REQUEST_AT_LEAST_SIZE(xRenderCompositeGlyphsReq); 2811 VERIFY_XIN_PICTURE(src, stuff->src, client, DixReadAccess); 2812 VERIFY_XIN_PICTURE(dst, stuff->dst, client, DixWriteAccess); 2813 2814 if (client->req_len << 2 >= (sizeof(xRenderCompositeGlyphsReq) + 2815 sizeof(xGlyphElt))) { 2816 elt = (xGlyphElt *) (stuff + 1); 2817 origElt = *elt; 2818 xSrc = stuff->xSrc; 2819 ySrc = stuff->ySrc; 2820 FOR_NSCREENS_FORWARD(j) { 2821 stuff->src = src->info[j].id; 2822 if (src->u.pict.root) { 2823 stuff->xSrc = xSrc - screenInfo.screens[j]->x; 2824 stuff->ySrc = ySrc - screenInfo.screens[j]->y; 2825 } 2826 stuff->dst = dst->info[j].id; 2827 if (dst->u.pict.root) { 2828 elt->deltax = origElt.deltax - screenInfo.screens[j]->x; 2829 elt->deltay = origElt.deltay - screenInfo.screens[j]->y; 2830 } 2831 result = 2832 (*PanoramiXSaveRenderVector[stuff->renderReqType]) (client); 2833 if (result != Success) 2834 break; 2835 } 2836 } 2837 2838 return result; 2839} 2840 2841static int 2842PanoramiXRenderFillRectangles(ClientPtr client) 2843{ 2844 PanoramiXRes *dst; 2845 int result = Success, j; 2846 2847 REQUEST(xRenderFillRectanglesReq); 2848 char *extra; 2849 int extra_len; 2850 2851 REQUEST_AT_LEAST_SIZE(xRenderFillRectanglesReq); 2852 VERIFY_XIN_PICTURE(dst, stuff->dst, client, DixWriteAccess); 2853 extra_len = (client->req_len << 2) - sizeof(xRenderFillRectanglesReq); 2854 if (extra_len && (extra = (char *) malloc(extra_len))) { 2855 memcpy(extra, stuff + 1, extra_len); 2856 FOR_NSCREENS_FORWARD(j) { 2857 if (j) 2858 memcpy(stuff + 1, extra, extra_len); 2859 if (dst->u.pict.root) { 2860 int x_off = screenInfo.screens[j]->x; 2861 int y_off = screenInfo.screens[j]->y; 2862 2863 if (x_off || y_off) { 2864 xRectangle *rects = (xRectangle *) (stuff + 1); 2865 int i = extra_len / sizeof(xRectangle); 2866 2867 while (i--) { 2868 rects->x -= x_off; 2869 rects->y -= y_off; 2870 rects++; 2871 } 2872 } 2873 } 2874 stuff->dst = dst->info[j].id; 2875 result = 2876 (*PanoramiXSaveRenderVector[X_RenderFillRectangles]) (client); 2877 if (result != Success) 2878 break; 2879 } 2880 free(extra); 2881 } 2882 2883 return result; 2884} 2885 2886static int 2887PanoramiXRenderTrapezoids(ClientPtr client) 2888{ 2889 PanoramiXRes *src, *dst; 2890 int result = Success, j; 2891 2892 REQUEST(xRenderTrapezoidsReq); 2893 char *extra; 2894 int extra_len; 2895 2896 REQUEST_AT_LEAST_SIZE(xRenderTrapezoidsReq); 2897 2898 VERIFY_XIN_PICTURE(src, stuff->src, client, DixReadAccess); 2899 VERIFY_XIN_PICTURE(dst, stuff->dst, client, DixWriteAccess); 2900 2901 extra_len = (client->req_len << 2) - sizeof(xRenderTrapezoidsReq); 2902 2903 if (extra_len && (extra = (char *) malloc(extra_len))) { 2904 memcpy(extra, stuff + 1, extra_len); 2905 2906 FOR_NSCREENS_FORWARD(j) { 2907 if (j) 2908 memcpy(stuff + 1, extra, extra_len); 2909 if (dst->u.pict.root) { 2910 int x_off = screenInfo.screens[j]->x; 2911 int y_off = screenInfo.screens[j]->y; 2912 2913 if (x_off || y_off) { 2914 xTrapezoid *trap = (xTrapezoid *) (stuff + 1); 2915 int i = extra_len / sizeof(xTrapezoid); 2916 2917 while (i--) { 2918 trap->top -= y_off; 2919 trap->bottom -= y_off; 2920 trap->left.p1.x -= x_off; 2921 trap->left.p1.y -= y_off; 2922 trap->left.p2.x -= x_off; 2923 trap->left.p2.y -= y_off; 2924 trap->right.p1.x -= x_off; 2925 trap->right.p1.y -= y_off; 2926 trap->right.p2.x -= x_off; 2927 trap->right.p2.y -= y_off; 2928 trap++; 2929 } 2930 } 2931 } 2932 2933 stuff->src = src->info[j].id; 2934 stuff->dst = dst->info[j].id; 2935 result = (*PanoramiXSaveRenderVector[X_RenderTrapezoids]) (client); 2936 2937 if (result != Success) 2938 break; 2939 } 2940 2941 free(extra); 2942 } 2943 2944 return result; 2945} 2946 2947static int 2948PanoramiXRenderTriangles(ClientPtr client) 2949{ 2950 PanoramiXRes *src, *dst; 2951 int result = Success, j; 2952 2953 REQUEST(xRenderTrianglesReq); 2954 char *extra; 2955 int extra_len; 2956 2957 REQUEST_AT_LEAST_SIZE(xRenderTrianglesReq); 2958 2959 VERIFY_XIN_PICTURE(src, stuff->src, client, DixReadAccess); 2960 VERIFY_XIN_PICTURE(dst, stuff->dst, client, DixWriteAccess); 2961 2962 extra_len = (client->req_len << 2) - sizeof(xRenderTrianglesReq); 2963 2964 if (extra_len && (extra = (char *) malloc(extra_len))) { 2965 memcpy(extra, stuff + 1, extra_len); 2966 2967 FOR_NSCREENS_FORWARD(j) { 2968 if (j) 2969 memcpy(stuff + 1, extra, extra_len); 2970 if (dst->u.pict.root) { 2971 int x_off = screenInfo.screens[j]->x; 2972 int y_off = screenInfo.screens[j]->y; 2973 2974 if (x_off || y_off) { 2975 xTriangle *tri = (xTriangle *) (stuff + 1); 2976 int i = extra_len / sizeof(xTriangle); 2977 2978 while (i--) { 2979 tri->p1.x -= x_off; 2980 tri->p1.y -= y_off; 2981 tri->p2.x -= x_off; 2982 tri->p2.y -= y_off; 2983 tri->p3.x -= x_off; 2984 tri->p3.y -= y_off; 2985 tri++; 2986 } 2987 } 2988 } 2989 2990 stuff->src = src->info[j].id; 2991 stuff->dst = dst->info[j].id; 2992 result = (*PanoramiXSaveRenderVector[X_RenderTriangles]) (client); 2993 2994 if (result != Success) 2995 break; 2996 } 2997 2998 free(extra); 2999 } 3000 3001 return result; 3002} 3003 3004static int 3005PanoramiXRenderTriStrip(ClientPtr client) 3006{ 3007 PanoramiXRes *src, *dst; 3008 int result = Success, j; 3009 3010 REQUEST(xRenderTriStripReq); 3011 char *extra; 3012 int extra_len; 3013 3014 REQUEST_AT_LEAST_SIZE(xRenderTriStripReq); 3015 3016 VERIFY_XIN_PICTURE(src, stuff->src, client, DixReadAccess); 3017 VERIFY_XIN_PICTURE(dst, stuff->dst, client, DixWriteAccess); 3018 3019 extra_len = (client->req_len << 2) - sizeof(xRenderTriStripReq); 3020 3021 if (extra_len && (extra = (char *) malloc(extra_len))) { 3022 memcpy(extra, stuff + 1, extra_len); 3023 3024 FOR_NSCREENS_FORWARD(j) { 3025 if (j) 3026 memcpy(stuff + 1, extra, extra_len); 3027 if (dst->u.pict.root) { 3028 int x_off = screenInfo.screens[j]->x; 3029 int y_off = screenInfo.screens[j]->y; 3030 3031 if (x_off || y_off) { 3032 xPointFixed *fixed = (xPointFixed *) (stuff + 1); 3033 int i = extra_len / sizeof(xPointFixed); 3034 3035 while (i--) { 3036 fixed->x -= x_off; 3037 fixed->y -= y_off; 3038 fixed++; 3039 } 3040 } 3041 } 3042 3043 stuff->src = src->info[j].id; 3044 stuff->dst = dst->info[j].id; 3045 result = (*PanoramiXSaveRenderVector[X_RenderTriStrip]) (client); 3046 3047 if (result != Success) 3048 break; 3049 } 3050 3051 free(extra); 3052 } 3053 3054 return result; 3055} 3056 3057static int 3058PanoramiXRenderTriFan(ClientPtr client) 3059{ 3060 PanoramiXRes *src, *dst; 3061 int result = Success, j; 3062 3063 REQUEST(xRenderTriFanReq); 3064 char *extra; 3065 int extra_len; 3066 3067 REQUEST_AT_LEAST_SIZE(xRenderTriFanReq); 3068 3069 VERIFY_XIN_PICTURE(src, stuff->src, client, DixReadAccess); 3070 VERIFY_XIN_PICTURE(dst, stuff->dst, client, DixWriteAccess); 3071 3072 extra_len = (client->req_len << 2) - sizeof(xRenderTriFanReq); 3073 3074 if (extra_len && (extra = (char *) malloc(extra_len))) { 3075 memcpy(extra, stuff + 1, extra_len); 3076 3077 FOR_NSCREENS_FORWARD(j) { 3078 if (j) 3079 memcpy(stuff + 1, extra, extra_len); 3080 if (dst->u.pict.root) { 3081 int x_off = screenInfo.screens[j]->x; 3082 int y_off = screenInfo.screens[j]->y; 3083 3084 if (x_off || y_off) { 3085 xPointFixed *fixed = (xPointFixed *) (stuff + 1); 3086 int i = extra_len / sizeof(xPointFixed); 3087 3088 while (i--) { 3089 fixed->x -= x_off; 3090 fixed->y -= y_off; 3091 fixed++; 3092 } 3093 } 3094 } 3095 3096 stuff->src = src->info[j].id; 3097 stuff->dst = dst->info[j].id; 3098 result = (*PanoramiXSaveRenderVector[X_RenderTriFan]) (client); 3099 3100 if (result != Success) 3101 break; 3102 } 3103 3104 free(extra); 3105 } 3106 3107 return result; 3108} 3109 3110static int 3111PanoramiXRenderAddTraps(ClientPtr client) 3112{ 3113 PanoramiXRes *picture; 3114 int result = Success, j; 3115 3116 REQUEST(xRenderAddTrapsReq); 3117 char *extra; 3118 int extra_len; 3119 INT16 x_off, y_off; 3120 3121 REQUEST_AT_LEAST_SIZE(xRenderAddTrapsReq); 3122 VERIFY_XIN_PICTURE(picture, stuff->picture, client, DixWriteAccess); 3123 extra_len = (client->req_len << 2) - sizeof(xRenderAddTrapsReq); 3124 if (extra_len && (extra = (char *) malloc(extra_len))) { 3125 memcpy(extra, stuff + 1, extra_len); 3126 x_off = stuff->xOff; 3127 y_off = stuff->yOff; 3128 FOR_NSCREENS_FORWARD(j) { 3129 if (j) 3130 memcpy(stuff + 1, extra, extra_len); 3131 stuff->picture = picture->info[j].id; 3132 3133 if (picture->u.pict.root) { 3134 stuff->xOff = x_off + screenInfo.screens[j]->x; 3135 stuff->yOff = y_off + screenInfo.screens[j]->y; 3136 } 3137 result = (*PanoramiXSaveRenderVector[X_RenderAddTraps]) (client); 3138 if (result != Success) 3139 break; 3140 } 3141 free(extra); 3142 } 3143 3144 return result; 3145} 3146 3147static int 3148PanoramiXRenderCreateSolidFill(ClientPtr client) 3149{ 3150 REQUEST(xRenderCreateSolidFillReq); 3151 PanoramiXRes *newPict; 3152 int result = Success, j; 3153 3154 REQUEST_AT_LEAST_SIZE(xRenderCreateSolidFillReq); 3155 3156 if (!(newPict = (PanoramiXRes *) malloc(sizeof(PanoramiXRes)))) 3157 return BadAlloc; 3158 3159 newPict->type = XRT_PICTURE; 3160 panoramix_setup_ids(newPict, client, stuff->pid); 3161 newPict->u.pict.root = FALSE; 3162 3163 FOR_NSCREENS_BACKWARD(j) { 3164 stuff->pid = newPict->info[j].id; 3165 result = (*PanoramiXSaveRenderVector[X_RenderCreateSolidFill]) (client); 3166 if (result != Success) 3167 break; 3168 } 3169 3170 if (result == Success) 3171 AddResource(newPict->info[0].id, XRT_PICTURE, newPict); 3172 else 3173 free(newPict); 3174 3175 return result; 3176} 3177 3178static int 3179PanoramiXRenderCreateLinearGradient(ClientPtr client) 3180{ 3181 REQUEST(xRenderCreateLinearGradientReq); 3182 PanoramiXRes *newPict; 3183 int result = Success, j; 3184 3185 REQUEST_AT_LEAST_SIZE(xRenderCreateLinearGradientReq); 3186 3187 if (!(newPict = (PanoramiXRes *) malloc(sizeof(PanoramiXRes)))) 3188 return BadAlloc; 3189 3190 newPict->type = XRT_PICTURE; 3191 panoramix_setup_ids(newPict, client, stuff->pid); 3192 newPict->u.pict.root = FALSE; 3193 3194 FOR_NSCREENS_BACKWARD(j) { 3195 stuff->pid = newPict->info[j].id; 3196 result = 3197 (*PanoramiXSaveRenderVector[X_RenderCreateLinearGradient]) (client); 3198 if (result != Success) 3199 break; 3200 } 3201 3202 if (result == Success) 3203 AddResource(newPict->info[0].id, XRT_PICTURE, newPict); 3204 else 3205 free(newPict); 3206 3207 return result; 3208} 3209 3210static int 3211PanoramiXRenderCreateRadialGradient(ClientPtr client) 3212{ 3213 REQUEST(xRenderCreateRadialGradientReq); 3214 PanoramiXRes *newPict; 3215 int result = Success, j; 3216 3217 REQUEST_AT_LEAST_SIZE(xRenderCreateRadialGradientReq); 3218 3219 if (!(newPict = (PanoramiXRes *) malloc(sizeof(PanoramiXRes)))) 3220 return BadAlloc; 3221 3222 newPict->type = XRT_PICTURE; 3223 panoramix_setup_ids(newPict, client, stuff->pid); 3224 newPict->u.pict.root = FALSE; 3225 3226 FOR_NSCREENS_BACKWARD(j) { 3227 stuff->pid = newPict->info[j].id; 3228 result = 3229 (*PanoramiXSaveRenderVector[X_RenderCreateRadialGradient]) (client); 3230 if (result != Success) 3231 break; 3232 } 3233 3234 if (result == Success) 3235 AddResource(newPict->info[0].id, XRT_PICTURE, newPict); 3236 else 3237 free(newPict); 3238 3239 return result; 3240} 3241 3242static int 3243PanoramiXRenderCreateConicalGradient(ClientPtr client) 3244{ 3245 REQUEST(xRenderCreateConicalGradientReq); 3246 PanoramiXRes *newPict; 3247 int result = Success, j; 3248 3249 REQUEST_AT_LEAST_SIZE(xRenderCreateConicalGradientReq); 3250 3251 if (!(newPict = (PanoramiXRes *) malloc(sizeof(PanoramiXRes)))) 3252 return BadAlloc; 3253 3254 newPict->type = XRT_PICTURE; 3255 panoramix_setup_ids(newPict, client, stuff->pid); 3256 newPict->u.pict.root = FALSE; 3257 3258 FOR_NSCREENS_BACKWARD(j) { 3259 stuff->pid = newPict->info[j].id; 3260 result = 3261 (*PanoramiXSaveRenderVector[X_RenderCreateConicalGradient]) 3262 (client); 3263 if (result != Success) 3264 break; 3265 } 3266 3267 if (result == Success) 3268 AddResource(newPict->info[0].id, XRT_PICTURE, newPict); 3269 else 3270 free(newPict); 3271 3272 return result; 3273} 3274 3275void 3276PanoramiXRenderInit(void) 3277{ 3278 int i; 3279 3280 XRT_PICTURE = CreateNewResourceType(XineramaDeleteResource, 3281 "XineramaPicture"); 3282 if (RenderErrBase) 3283 SetResourceTypeErrorValue(XRT_PICTURE, RenderErrBase + BadPicture); 3284 for (i = 0; i < RenderNumberRequests; i++) 3285 PanoramiXSaveRenderVector[i] = ProcRenderVector[i]; 3286 /* 3287 * Stuff in Xinerama aware request processing hooks 3288 */ 3289 ProcRenderVector[X_RenderCreatePicture] = PanoramiXRenderCreatePicture; 3290 ProcRenderVector[X_RenderChangePicture] = PanoramiXRenderChangePicture; 3291 ProcRenderVector[X_RenderSetPictureTransform] = 3292 PanoramiXRenderSetPictureTransform; 3293 ProcRenderVector[X_RenderSetPictureFilter] = 3294 PanoramiXRenderSetPictureFilter; 3295 ProcRenderVector[X_RenderSetPictureClipRectangles] = 3296 PanoramiXRenderSetPictureClipRectangles; 3297 ProcRenderVector[X_RenderFreePicture] = PanoramiXRenderFreePicture; 3298 ProcRenderVector[X_RenderComposite] = PanoramiXRenderComposite; 3299 ProcRenderVector[X_RenderCompositeGlyphs8] = PanoramiXRenderCompositeGlyphs; 3300 ProcRenderVector[X_RenderCompositeGlyphs16] = 3301 PanoramiXRenderCompositeGlyphs; 3302 ProcRenderVector[X_RenderCompositeGlyphs32] = 3303 PanoramiXRenderCompositeGlyphs; 3304 ProcRenderVector[X_RenderFillRectangles] = PanoramiXRenderFillRectangles; 3305 3306 ProcRenderVector[X_RenderTrapezoids] = PanoramiXRenderTrapezoids; 3307 ProcRenderVector[X_RenderTriangles] = PanoramiXRenderTriangles; 3308 ProcRenderVector[X_RenderTriStrip] = PanoramiXRenderTriStrip; 3309 ProcRenderVector[X_RenderTriFan] = PanoramiXRenderTriFan; 3310 ProcRenderVector[X_RenderAddTraps] = PanoramiXRenderAddTraps; 3311 3312 ProcRenderVector[X_RenderCreateSolidFill] = PanoramiXRenderCreateSolidFill; 3313 ProcRenderVector[X_RenderCreateLinearGradient] = 3314 PanoramiXRenderCreateLinearGradient; 3315 ProcRenderVector[X_RenderCreateRadialGradient] = 3316 PanoramiXRenderCreateRadialGradient; 3317 ProcRenderVector[X_RenderCreateConicalGradient] = 3318 PanoramiXRenderCreateConicalGradient; 3319} 3320 3321void 3322PanoramiXRenderReset(void) 3323{ 3324 int i; 3325 3326 for (i = 0; i < RenderNumberRequests; i++) 3327 ProcRenderVector[i] = PanoramiXSaveRenderVector[i]; 3328 RenderErrBase = 0; 3329} 3330 3331#endif /* PANORAMIX */ 3332