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