xserver

xserver with xephyr scale patch
git clone https://git.neptards.moe/u3shit/xserver.git
Log | Files | Refs | README | LICENSE

render.c (97959B)


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