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