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