3315 lines
		
	
	
		
			95 KiB
		
	
	
	
		
			C
		
	
	
	
			
		
		
	
	
			3315 lines
		
	
	
		
			95 KiB
		
	
	
	
		
			C
		
	
	
	
| /*
 | |
|  *
 | |
|  * Copyright © 2000 SuSE, Inc.
 | |
|  *
 | |
|  * Permission to use, copy, modify, distribute, and sell this software and its
 | |
|  * documentation for any purpose is hereby granted without fee, provided that
 | |
|  * the above copyright notice appear in all copies and that both that
 | |
|  * copyright notice and this permission notice appear in supporting
 | |
|  * documentation, and that the name of SuSE not be used in advertising or
 | |
|  * publicity pertaining to distribution of the software without specific,
 | |
|  * written prior permission.  SuSE makes no representations about the
 | |
|  * suitability of this software for any purpose.  It is provided "as is"
 | |
|  * without express or implied warranty.
 | |
|  *
 | |
|  * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
 | |
|  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
 | |
|  * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 | |
|  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
 | |
|  * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN 
 | |
|  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 | |
|  *
 | |
|  * Author:  Keith Packard, SuSE, Inc.
 | |
|  */
 | |
| 
 | |
| #ifdef HAVE_DIX_CONFIG_H
 | |
| #include <dix-config.h>
 | |
| #endif
 | |
| 
 | |
| #include <X11/X.h>
 | |
| #include <X11/Xproto.h>
 | |
| #include "misc.h"
 | |
| #include "os.h"
 | |
| #include "dixstruct.h"
 | |
| #include "resource.h"
 | |
| #include "scrnintstr.h"
 | |
| #include "windowstr.h"
 | |
| #include "pixmapstr.h"
 | |
| #include "colormapst.h"
 | |
| #include "extnsionst.h"
 | |
| #include "servermd.h"
 | |
| #include <X11/extensions/render.h>
 | |
| #include <X11/extensions/renderproto.h>
 | |
| #include "picturestr.h"
 | |
| #include "glyphstr.h"
 | |
| #include <X11/Xfuncproto.h>
 | |
| #include "cursorstr.h"
 | |
| #include "xace.h"
 | |
| #include "protocol-versions.h"
 | |
| 
 | |
| #ifdef PANORAMIX
 | |
| #include "panoramiX.h"
 | |
| #include "panoramiXsrv.h"
 | |
| #endif
 | |
| 
 | |
| #include <stdint.h>
 | |
| 
 | |
| static int ProcRenderQueryVersion(ClientPtr pClient);
 | |
| static int ProcRenderQueryPictFormats(ClientPtr pClient);
 | |
| static int ProcRenderQueryPictIndexValues(ClientPtr pClient);
 | |
| static int ProcRenderQueryDithers(ClientPtr pClient);
 | |
| static int ProcRenderCreatePicture(ClientPtr pClient);
 | |
| static int ProcRenderChangePicture(ClientPtr pClient);
 | |
| static int ProcRenderSetPictureClipRectangles(ClientPtr pClient);
 | |
| static int ProcRenderFreePicture(ClientPtr pClient);
 | |
| static int ProcRenderComposite(ClientPtr pClient);
 | |
| static int ProcRenderScale(ClientPtr pClient);
 | |
| static int ProcRenderTrapezoids(ClientPtr pClient);
 | |
| static int ProcRenderTriangles(ClientPtr pClient);
 | |
| static int ProcRenderTriStrip(ClientPtr pClient);
 | |
| static int ProcRenderTriFan(ClientPtr pClient);
 | |
| static int ProcRenderColorTrapezoids(ClientPtr pClient);
 | |
| static int ProcRenderColorTriangles(ClientPtr pClient);
 | |
| static int ProcRenderTransform(ClientPtr pClient);
 | |
| static int ProcRenderCreateGlyphSet(ClientPtr pClient);
 | |
| static int ProcRenderReferenceGlyphSet(ClientPtr pClient);
 | |
| static int ProcRenderFreeGlyphSet(ClientPtr pClient);
 | |
| static int ProcRenderAddGlyphs(ClientPtr pClient);
 | |
| static int ProcRenderAddGlyphsFromPicture(ClientPtr pClient);
 | |
| static int ProcRenderFreeGlyphs(ClientPtr pClient);
 | |
| static int ProcRenderCompositeGlyphs(ClientPtr pClient);
 | |
| static int ProcRenderFillRectangles(ClientPtr pClient);
 | |
| static int ProcRenderCreateCursor(ClientPtr pClient);
 | |
| static int ProcRenderSetPictureTransform(ClientPtr pClient);
 | |
| static int ProcRenderQueryFilters(ClientPtr pClient);
 | |
| static int ProcRenderSetPictureFilter(ClientPtr pClient);
 | |
| static int ProcRenderCreateAnimCursor(ClientPtr pClient);
 | |
| static int ProcRenderAddTraps(ClientPtr pClient);
 | |
| static int ProcRenderCreateSolidFill(ClientPtr pClient);
 | |
| static int ProcRenderCreateLinearGradient(ClientPtr pClient);
 | |
| static int ProcRenderCreateRadialGradient(ClientPtr pClient);
 | |
| static int ProcRenderCreateConicalGradient(ClientPtr pClient);
 | |
| 
 | |
| static int ProcRenderDispatch(ClientPtr pClient);
 | |
| 
 | |
| static int SProcRenderQueryVersion(ClientPtr pClient);
 | |
| static int SProcRenderQueryPictFormats(ClientPtr pClient);
 | |
| static int SProcRenderQueryPictIndexValues(ClientPtr pClient);
 | |
| static int SProcRenderQueryDithers(ClientPtr pClient);
 | |
| static int SProcRenderCreatePicture(ClientPtr pClient);
 | |
| static int SProcRenderChangePicture(ClientPtr pClient);
 | |
| static int SProcRenderSetPictureClipRectangles(ClientPtr pClient);
 | |
| static int SProcRenderFreePicture(ClientPtr pClient);
 | |
| static int SProcRenderComposite(ClientPtr pClient);
 | |
| static int SProcRenderScale(ClientPtr pClient);
 | |
| static int SProcRenderTrapezoids(ClientPtr pClient);
 | |
| static int SProcRenderTriangles(ClientPtr pClient);
 | |
| static int SProcRenderTriStrip(ClientPtr pClient);
 | |
| static int SProcRenderTriFan(ClientPtr pClient);
 | |
| static int SProcRenderColorTrapezoids(ClientPtr pClient);
 | |
| static int SProcRenderColorTriangles(ClientPtr pClient);
 | |
| static int SProcRenderTransform(ClientPtr pClient);
 | |
| static int SProcRenderCreateGlyphSet(ClientPtr pClient);
 | |
| static int SProcRenderReferenceGlyphSet(ClientPtr pClient);
 | |
| static int SProcRenderFreeGlyphSet(ClientPtr pClient);
 | |
| static int SProcRenderAddGlyphs(ClientPtr pClient);
 | |
| static int SProcRenderAddGlyphsFromPicture(ClientPtr pClient);
 | |
| static int SProcRenderFreeGlyphs(ClientPtr pClient);
 | |
| static int SProcRenderCompositeGlyphs(ClientPtr pClient);
 | |
| static int SProcRenderFillRectangles(ClientPtr pClient);
 | |
| static int SProcRenderCreateCursor(ClientPtr pClient);
 | |
| static int SProcRenderSetPictureTransform(ClientPtr pClient);
 | |
| static int SProcRenderQueryFilters(ClientPtr pClient);
 | |
| static int SProcRenderSetPictureFilter(ClientPtr pClient);
 | |
| static int SProcRenderCreateAnimCursor(ClientPtr pClient);
 | |
| static int SProcRenderAddTraps(ClientPtr pClient);
 | |
| static int SProcRenderCreateSolidFill(ClientPtr pClient);
 | |
| static int SProcRenderCreateLinearGradient(ClientPtr pClient);
 | |
| static int SProcRenderCreateRadialGradient(ClientPtr pClient);
 | |
| static int SProcRenderCreateConicalGradient(ClientPtr pClient);
 | |
| 
 | |
| static int SProcRenderDispatch(ClientPtr pClient);
 | |
| 
 | |
| int (*ProcRenderVector[RenderNumberRequests]) (ClientPtr) = {
 | |
| ProcRenderQueryVersion,
 | |
|         ProcRenderQueryPictFormats,
 | |
|         ProcRenderQueryPictIndexValues,
 | |
|         ProcRenderQueryDithers,
 | |
|         ProcRenderCreatePicture,
 | |
|         ProcRenderChangePicture,
 | |
|         ProcRenderSetPictureClipRectangles,
 | |
|         ProcRenderFreePicture,
 | |
|         ProcRenderComposite,
 | |
|         ProcRenderScale,
 | |
|         ProcRenderTrapezoids,
 | |
|         ProcRenderTriangles,
 | |
|         ProcRenderTriStrip,
 | |
|         ProcRenderTriFan,
 | |
|         ProcRenderColorTrapezoids,
 | |
|         ProcRenderColorTriangles,
 | |
|         ProcRenderTransform,
 | |
|         ProcRenderCreateGlyphSet,
 | |
|         ProcRenderReferenceGlyphSet,
 | |
|         ProcRenderFreeGlyphSet,
 | |
|         ProcRenderAddGlyphs,
 | |
|         ProcRenderAddGlyphsFromPicture,
 | |
|         ProcRenderFreeGlyphs,
 | |
|         ProcRenderCompositeGlyphs,
 | |
|         ProcRenderCompositeGlyphs,
 | |
|         ProcRenderCompositeGlyphs,
 | |
|         ProcRenderFillRectangles,
 | |
|         ProcRenderCreateCursor,
 | |
|         ProcRenderSetPictureTransform,
 | |
|         ProcRenderQueryFilters,
 | |
|         ProcRenderSetPictureFilter,
 | |
|         ProcRenderCreateAnimCursor,
 | |
|         ProcRenderAddTraps,
 | |
|         ProcRenderCreateSolidFill,
 | |
|         ProcRenderCreateLinearGradient,
 | |
|         ProcRenderCreateRadialGradient, ProcRenderCreateConicalGradient};
 | |
| 
 | |
| int (*SProcRenderVector[RenderNumberRequests]) (ClientPtr) = {
 | |
| SProcRenderQueryVersion,
 | |
|         SProcRenderQueryPictFormats,
 | |
|         SProcRenderQueryPictIndexValues,
 | |
|         SProcRenderQueryDithers,
 | |
|         SProcRenderCreatePicture,
 | |
|         SProcRenderChangePicture,
 | |
|         SProcRenderSetPictureClipRectangles,
 | |
|         SProcRenderFreePicture,
 | |
|         SProcRenderComposite,
 | |
|         SProcRenderScale,
 | |
|         SProcRenderTrapezoids,
 | |
|         SProcRenderTriangles,
 | |
|         SProcRenderTriStrip,
 | |
|         SProcRenderTriFan,
 | |
|         SProcRenderColorTrapezoids,
 | |
|         SProcRenderColorTriangles,
 | |
|         SProcRenderTransform,
 | |
|         SProcRenderCreateGlyphSet,
 | |
|         SProcRenderReferenceGlyphSet,
 | |
|         SProcRenderFreeGlyphSet,
 | |
|         SProcRenderAddGlyphs,
 | |
|         SProcRenderAddGlyphsFromPicture,
 | |
|         SProcRenderFreeGlyphs,
 | |
|         SProcRenderCompositeGlyphs,
 | |
|         SProcRenderCompositeGlyphs,
 | |
|         SProcRenderCompositeGlyphs,
 | |
|         SProcRenderFillRectangles,
 | |
|         SProcRenderCreateCursor,
 | |
|         SProcRenderSetPictureTransform,
 | |
|         SProcRenderQueryFilters,
 | |
|         SProcRenderSetPictureFilter,
 | |
|         SProcRenderCreateAnimCursor,
 | |
|         SProcRenderAddTraps,
 | |
|         SProcRenderCreateSolidFill,
 | |
|         SProcRenderCreateLinearGradient,
 | |
|         SProcRenderCreateRadialGradient, SProcRenderCreateConicalGradient};
 | |
| 
 | |
| int RenderErrBase;
 | |
| static DevPrivateKeyRec RenderClientPrivateKeyRec;
 | |
| 
 | |
| #define RenderClientPrivateKey (&RenderClientPrivateKeyRec )
 | |
| 
 | |
| typedef struct _RenderClient {
 | |
|     int major_version;
 | |
|     int minor_version;
 | |
| } RenderClientRec, *RenderClientPtr;
 | |
| 
 | |
| #define GetRenderClient(pClient) ((RenderClientPtr)dixLookupPrivate(&(pClient)->devPrivates, RenderClientPrivateKey))
 | |
| 
 | |
| static void
 | |
| RenderClientCallback(CallbackListPtr *list, pointer closure, pointer data)
 | |
| {
 | |
|     NewClientInfoRec *clientinfo = (NewClientInfoRec *) data;
 | |
|     ClientPtr pClient = clientinfo->client;
 | |
|     RenderClientPtr pRenderClient = GetRenderClient(pClient);
 | |
| 
 | |
|     pRenderClient->major_version = 0;
 | |
|     pRenderClient->minor_version = 0;
 | |
| }
 | |
| 
 | |
| #ifdef PANORAMIX
 | |
| RESTYPE XRT_PICTURE;
 | |
| #endif
 | |
| 
 | |
| void
 | |
| RenderExtensionInit(void)
 | |
| {
 | |
|     ExtensionEntry *extEntry;
 | |
| 
 | |
|     if (!PictureType)
 | |
|         return;
 | |
|     if (!PictureFinishInit())
 | |
|         return;
 | |
|     if (!dixRegisterPrivateKey
 | |
|         (&RenderClientPrivateKeyRec, PRIVATE_CLIENT, sizeof(RenderClientRec)))
 | |
|         return;
 | |
|     if (!AddCallback(&ClientStateCallback, RenderClientCallback, 0))
 | |
|         return;
 | |
| 
 | |
|     extEntry = AddExtension(RENDER_NAME, 0, RenderNumberErrors,
 | |
|                             ProcRenderDispatch, SProcRenderDispatch,
 | |
|                             NULL, StandardMinorOpcode);
 | |
|     if (!extEntry)
 | |
|         return;
 | |
|     RenderErrBase = extEntry->errorBase;
 | |
| #ifdef PANORAMIX
 | |
|     if (XRT_PICTURE)
 | |
|         SetResourceTypeErrorValue(XRT_PICTURE, RenderErrBase + BadPicture);
 | |
| #endif
 | |
|     SetResourceTypeErrorValue(PictureType, RenderErrBase + BadPicture);
 | |
|     SetResourceTypeErrorValue(PictFormatType, RenderErrBase + BadPictFormat);
 | |
|     SetResourceTypeErrorValue(GlyphSetType, RenderErrBase + BadGlyphSet);
 | |
| }
 | |
| 
 | |
| static int
 | |
| ProcRenderQueryVersion(ClientPtr client)
 | |
| {
 | |
|     RenderClientPtr pRenderClient = GetRenderClient(client);
 | |
|     xRenderQueryVersionReply rep;
 | |
| 
 | |
|     REQUEST(xRenderQueryVersionReq);
 | |
| 
 | |
|     pRenderClient->major_version = stuff->majorVersion;
 | |
|     pRenderClient->minor_version = stuff->minorVersion;
 | |
| 
 | |
|     REQUEST_SIZE_MATCH(xRenderQueryVersionReq);
 | |
|     memset(&rep, 0, sizeof(xRenderQueryVersionReply));
 | |
|     rep.type = X_Reply;
 | |
|     rep.length = 0;
 | |
|     rep.sequenceNumber = client->sequence;
 | |
| 
 | |
|     if ((stuff->majorVersion * 1000 + stuff->minorVersion) <
 | |
|         (SERVER_RENDER_MAJOR_VERSION * 1000 + SERVER_RENDER_MINOR_VERSION)) {
 | |
|         rep.majorVersion = stuff->majorVersion;
 | |
|         rep.minorVersion = stuff->minorVersion;
 | |
|     }
 | |
|     else {
 | |
|         rep.majorVersion = SERVER_RENDER_MAJOR_VERSION;
 | |
|         rep.minorVersion = SERVER_RENDER_MINOR_VERSION;
 | |
|     }
 | |
| 
 | |
|     if (client->swapped) {
 | |
|         swaps(&rep.sequenceNumber);
 | |
|         swapl(&rep.length);
 | |
|         swapl(&rep.majorVersion);
 | |
|         swapl(&rep.minorVersion);
 | |
|     }
 | |
|     WriteToClient(client, sizeof(xRenderQueryVersionReply), (char *) &rep);
 | |
|     return Success;
 | |
| }
 | |
| 
 | |
| static VisualPtr
 | |
| findVisual(ScreenPtr pScreen, VisualID vid)
 | |
| {
 | |
|     VisualPtr pVisual;
 | |
|     int v;
 | |
| 
 | |
|     for (v = 0; v < pScreen->numVisuals; v++) {
 | |
|         pVisual = pScreen->visuals + v;
 | |
|         if (pVisual->vid == vid)
 | |
|             return pVisual;
 | |
|     }
 | |
|     return 0;
 | |
| }
 | |
| 
 | |
| static int
 | |
| ProcRenderQueryPictFormats(ClientPtr client)
 | |
| {
 | |
|     RenderClientPtr pRenderClient = GetRenderClient(client);
 | |
|     xRenderQueryPictFormatsReply *reply;
 | |
|     xPictScreen *pictScreen;
 | |
|     xPictDepth *pictDepth;
 | |
|     xPictVisual *pictVisual;
 | |
|     xPictFormInfo *pictForm;
 | |
|     CARD32 *pictSubpixel;
 | |
|     ScreenPtr pScreen;
 | |
|     VisualPtr pVisual;
 | |
|     DepthPtr pDepth;
 | |
|     int v, d;
 | |
|     PictureScreenPtr ps;
 | |
|     PictFormatPtr pFormat;
 | |
|     int nformat;
 | |
|     int ndepth;
 | |
|     int nvisual;
 | |
|     int rlength;
 | |
|     int s;
 | |
|     int numScreens;
 | |
|     int numSubpixel;
 | |
| 
 | |
| /*    REQUEST(xRenderQueryPictFormatsReq); */
 | |
| 
 | |
|     REQUEST_SIZE_MATCH(xRenderQueryPictFormatsReq);
 | |
| 
 | |
| #ifdef PANORAMIX
 | |
|     if (noPanoramiXExtension)
 | |
|         numScreens = screenInfo.numScreens;
 | |
|     else
 | |
|         numScreens = ((xConnSetup *) ConnectionInfo)->numRoots;
 | |
| #else
 | |
|     numScreens = screenInfo.numScreens;
 | |
| #endif
 | |
|     ndepth = nformat = nvisual = 0;
 | |
|     for (s = 0; s < numScreens; s++) {
 | |
|         pScreen = screenInfo.screens[s];
 | |
|         for (d = 0; d < pScreen->numDepths; d++) {
 | |
|             pDepth = pScreen->allowedDepths + d;
 | |
|             ++ndepth;
 | |
| 
 | |
|             for (v = 0; v < pDepth->numVids; v++) {
 | |
|                 pVisual = findVisual(pScreen, pDepth->vids[v]);
 | |
|                 if (pVisual &&
 | |
|                     PictureMatchVisual(pScreen, pDepth->depth, pVisual))
 | |
|                     ++nvisual;
 | |
|             }
 | |
|         }
 | |
|         ps = GetPictureScreenIfSet(pScreen);
 | |
|         if (ps)
 | |
|             nformat += ps->nformats;
 | |
|     }
 | |
|     if (pRenderClient->major_version == 0 && pRenderClient->minor_version < 6)
 | |
|         numSubpixel = 0;
 | |
|     else
 | |
|         numSubpixel = numScreens;
 | |
| 
 | |
|     rlength = (sizeof(xRenderQueryPictFormatsReply) +
 | |
|                nformat * sizeof(xPictFormInfo) +
 | |
|                numScreens * sizeof(xPictScreen) +
 | |
|                ndepth * sizeof(xPictDepth) +
 | |
|                nvisual * sizeof(xPictVisual) + numSubpixel * sizeof(CARD32));
 | |
|     reply = (xRenderQueryPictFormatsReply *) calloc(1, rlength);
 | |
|     if (!reply)
 | |
|         return BadAlloc;
 | |
|     reply->type = X_Reply;
 | |
|     reply->sequenceNumber = client->sequence;
 | |
|     reply->length = bytes_to_int32(rlength - sizeof(xGenericReply));
 | |
|     reply->numFormats = nformat;
 | |
|     reply->numScreens = numScreens;
 | |
|     reply->numDepths = ndepth;
 | |
|     reply->numVisuals = nvisual;
 | |
|     reply->numSubpixel = numSubpixel;
 | |
| 
 | |
|     pictForm = (xPictFormInfo *) (reply + 1);
 | |
| 
 | |
|     for (s = 0; s < numScreens; s++) {
 | |
|         pScreen = screenInfo.screens[s];
 | |
|         ps = GetPictureScreenIfSet(pScreen);
 | |
|         if (ps) {
 | |
|             for (nformat = 0, pFormat = ps->formats;
 | |
|                  nformat < ps->nformats; nformat++, pFormat++) {
 | |
|                 pictForm->id = pFormat->id;
 | |
|                 pictForm->type = pFormat->type;
 | |
|                 pictForm->depth = pFormat->depth;
 | |
|                 pictForm->direct.red = pFormat->direct.red;
 | |
|                 pictForm->direct.redMask = pFormat->direct.redMask;
 | |
|                 pictForm->direct.green = pFormat->direct.green;
 | |
|                 pictForm->direct.greenMask = pFormat->direct.greenMask;
 | |
|                 pictForm->direct.blue = pFormat->direct.blue;
 | |
|                 pictForm->direct.blueMask = pFormat->direct.blueMask;
 | |
|                 pictForm->direct.alpha = pFormat->direct.alpha;
 | |
|                 pictForm->direct.alphaMask = pFormat->direct.alphaMask;
 | |
|                 if (pFormat->type == PictTypeIndexed &&
 | |
|                     pFormat->index.pColormap)
 | |
|                     pictForm->colormap = pFormat->index.pColormap->mid;
 | |
|                 else
 | |
|                     pictForm->colormap = None;
 | |
|                 if (client->swapped) {
 | |
|                     swapl(&pictForm->id);
 | |
|                     swaps(&pictForm->direct.red);
 | |
|                     swaps(&pictForm->direct.redMask);
 | |
|                     swaps(&pictForm->direct.green);
 | |
|                     swaps(&pictForm->direct.greenMask);
 | |
|                     swaps(&pictForm->direct.blue);
 | |
|                     swaps(&pictForm->direct.blueMask);
 | |
|                     swaps(&pictForm->direct.alpha);
 | |
|                     swaps(&pictForm->direct.alphaMask);
 | |
|                     swapl(&pictForm->colormap);
 | |
|                 }
 | |
|                 pictForm++;
 | |
|             }
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     pictScreen = (xPictScreen *) pictForm;
 | |
|     for (s = 0; s < numScreens; s++) {
 | |
|         pScreen = screenInfo.screens[s];
 | |
|         pictDepth = (xPictDepth *) (pictScreen + 1);
 | |
|         ndepth = 0;
 | |
|         for (d = 0; d < pScreen->numDepths; d++) {
 | |
|             pictVisual = (xPictVisual *) (pictDepth + 1);
 | |
|             pDepth = pScreen->allowedDepths + d;
 | |
| 
 | |
|             nvisual = 0;
 | |
|             for (v = 0; v < pDepth->numVids; v++) {
 | |
|                 pVisual = findVisual(pScreen, pDepth->vids[v]);
 | |
|                 if (pVisual && (pFormat = PictureMatchVisual(pScreen,
 | |
|                                                              pDepth->depth,
 | |
|                                                              pVisual))) {
 | |
|                     pictVisual->visual = pVisual->vid;
 | |
|                     pictVisual->format = pFormat->id;
 | |
|                     if (client->swapped) {
 | |
|                         swapl(&pictVisual->visual);
 | |
|                         swapl(&pictVisual->format);
 | |
|                     }
 | |
|                     pictVisual++;
 | |
|                     nvisual++;
 | |
|                 }
 | |
|             }
 | |
|             pictDepth->depth = pDepth->depth;
 | |
|             pictDepth->nPictVisuals = nvisual;
 | |
|             if (client->swapped) {
 | |
|                 swaps(&pictDepth->nPictVisuals);
 | |
|             }
 | |
|             ndepth++;
 | |
|             pictDepth = (xPictDepth *) pictVisual;
 | |
|         }
 | |
|         pictScreen->nDepth = ndepth;
 | |
|         ps = GetPictureScreenIfSet(pScreen);
 | |
|         if (ps)
 | |
|             pictScreen->fallback = ps->fallback->id;
 | |
|         else
 | |
|             pictScreen->fallback = 0;
 | |
|         if (client->swapped) {
 | |
|             swapl(&pictScreen->nDepth);
 | |
|             swapl(&pictScreen->fallback);
 | |
|         }
 | |
|         pictScreen = (xPictScreen *) pictDepth;
 | |
|     }
 | |
|     pictSubpixel = (CARD32 *) pictScreen;
 | |
| 
 | |
|     for (s = 0; s < numSubpixel; s++) {
 | |
|         pScreen = screenInfo.screens[s];
 | |
|         ps = GetPictureScreenIfSet(pScreen);
 | |
|         if (ps)
 | |
|             *pictSubpixel = ps->subpixel;
 | |
|         else
 | |
|             *pictSubpixel = SubPixelUnknown;
 | |
|         if (client->swapped) {
 | |
|             swapl(pictSubpixel);
 | |
|         }
 | |
|         ++pictSubpixel;
 | |
|     }
 | |
| 
 | |
|     if (client->swapped) {
 | |
|         swaps(&reply->sequenceNumber);
 | |
|         swapl(&reply->length);
 | |
|         swapl(&reply->numFormats);
 | |
|         swapl(&reply->numScreens);
 | |
|         swapl(&reply->numDepths);
 | |
|         swapl(&reply->numVisuals);
 | |
|         swapl(&reply->numSubpixel);
 | |
|     }
 | |
|     WriteToClient(client, rlength, (char *) reply);
 | |
|     free(reply);
 | |
|     return Success;
 | |
| }
 | |
| 
 | |
| static int
 | |
| ProcRenderQueryPictIndexValues(ClientPtr client)
 | |
| {
 | |
|     PictFormatPtr pFormat;
 | |
|     int rc, num;
 | |
|     int rlength;
 | |
|     int i;
 | |
| 
 | |
|     REQUEST(xRenderQueryPictIndexValuesReq);
 | |
|     xRenderQueryPictIndexValuesReply *reply;
 | |
|     xIndexValue *values;
 | |
| 
 | |
|     REQUEST_AT_LEAST_SIZE(xRenderQueryPictIndexValuesReq);
 | |
| 
 | |
|     rc = dixLookupResourceByType((pointer *) &pFormat, stuff->format,
 | |
|                                  PictFormatType, client, DixReadAccess);
 | |
|     if (rc != Success)
 | |
|         return rc;
 | |
| 
 | |
|     if (pFormat->type != PictTypeIndexed) {
 | |
|         client->errorValue = stuff->format;
 | |
|         return BadMatch;
 | |
|     }
 | |
|     num = pFormat->index.nvalues;
 | |
|     rlength = (sizeof(xRenderQueryPictIndexValuesReply) +
 | |
|                num * sizeof(xIndexValue));
 | |
|     reply = (xRenderQueryPictIndexValuesReply *) malloc(rlength);
 | |
|     if (!reply)
 | |
|         return BadAlloc;
 | |
| 
 | |
|     reply->type = X_Reply;
 | |
|     reply->sequenceNumber = client->sequence;
 | |
|     reply->length = bytes_to_int32(rlength - sizeof(xGenericReply));
 | |
|     reply->numIndexValues = num;
 | |
| 
 | |
|     values = (xIndexValue *) (reply + 1);
 | |
| 
 | |
|     memcpy(reply + 1, pFormat->index.pValues, num * sizeof(xIndexValue));
 | |
| 
 | |
|     if (client->swapped) {
 | |
|         for (i = 0; i < num; i++) {
 | |
|             swapl(&values[i].pixel);
 | |
|             swaps(&values[i].red);
 | |
|             swaps(&values[i].green);
 | |
|             swaps(&values[i].blue);
 | |
|             swaps(&values[i].alpha);
 | |
|         }
 | |
|         swaps(&reply->sequenceNumber);
 | |
|         swapl(&reply->length);
 | |
|         swapl(&reply->numIndexValues);
 | |
|     }
 | |
| 
 | |
|     WriteToClient(client, rlength, (char *) reply);
 | |
|     free(reply);
 | |
|     return Success;
 | |
| }
 | |
| 
 | |
| static int
 | |
| ProcRenderQueryDithers(ClientPtr client)
 | |
| {
 | |
|     return BadImplementation;
 | |
| }
 | |
| 
 | |
| static int
 | |
| ProcRenderCreatePicture(ClientPtr client)
 | |
| {
 | |
|     PicturePtr pPicture;
 | |
|     DrawablePtr pDrawable;
 | |
|     PictFormatPtr pFormat;
 | |
|     int len, error, rc;
 | |
| 
 | |
|     REQUEST(xRenderCreatePictureReq);
 | |
| 
 | |
|     REQUEST_AT_LEAST_SIZE(xRenderCreatePictureReq);
 | |
| 
 | |
|     LEGAL_NEW_RESOURCE(stuff->pid, client);
 | |
|     rc = dixLookupDrawable(&pDrawable, stuff->drawable, client, 0,
 | |
|                            DixReadAccess | DixAddAccess);
 | |
|     if (rc != Success)
 | |
|         return rc;
 | |
| 
 | |
|     rc = dixLookupResourceByType((pointer *) &pFormat, stuff->format,
 | |
|                                  PictFormatType, client, DixReadAccess);
 | |
|     if (rc != Success)
 | |
|         return rc;
 | |
| 
 | |
|     if (pFormat->depth != pDrawable->depth)
 | |
|         return BadMatch;
 | |
|     len = client->req_len - bytes_to_int32(sizeof(xRenderCreatePictureReq));
 | |
|     if (Ones(stuff->mask) != len)
 | |
|         return BadLength;
 | |
| 
 | |
|     pPicture = CreatePicture(stuff->pid,
 | |
|                              pDrawable,
 | |
|                              pFormat,
 | |
|                              stuff->mask, (XID *) (stuff + 1), client, &error);
 | |
|     if (!pPicture)
 | |
|         return error;
 | |
|     if (!AddResource(stuff->pid, PictureType, (pointer) pPicture))
 | |
|         return BadAlloc;
 | |
|     return Success;
 | |
| }
 | |
| 
 | |
| static int
 | |
| ProcRenderChangePicture(ClientPtr client)
 | |
| {
 | |
|     PicturePtr pPicture;
 | |
| 
 | |
|     REQUEST(xRenderChangePictureReq);
 | |
|     int len;
 | |
| 
 | |
|     REQUEST_AT_LEAST_SIZE(xRenderChangePictureReq);
 | |
|     VERIFY_PICTURE(pPicture, stuff->picture, client, DixSetAttrAccess);
 | |
| 
 | |
|     len = client->req_len - bytes_to_int32(sizeof(xRenderChangePictureReq));
 | |
|     if (Ones(stuff->mask) != len)
 | |
|         return BadLength;
 | |
| 
 | |
|     return ChangePicture(pPicture, stuff->mask, (XID *) (stuff + 1),
 | |
|                          (DevUnion *) 0, client);
 | |
| }
 | |
| 
 | |
| static int
 | |
| ProcRenderSetPictureClipRectangles(ClientPtr client)
 | |
| {
 | |
|     REQUEST(xRenderSetPictureClipRectanglesReq);
 | |
|     PicturePtr pPicture;
 | |
|     int nr;
 | |
| 
 | |
|     REQUEST_AT_LEAST_SIZE(xRenderSetPictureClipRectanglesReq);
 | |
|     VERIFY_PICTURE(pPicture, stuff->picture, client, DixSetAttrAccess);
 | |
|     if (!pPicture->pDrawable)
 | |
|         return BadDrawable;
 | |
| 
 | |
|     nr = (client->req_len << 2) - sizeof(xRenderSetPictureClipRectanglesReq);
 | |
|     if (nr & 4)
 | |
|         return BadLength;
 | |
|     nr >>= 3;
 | |
|     return SetPictureClipRects(pPicture,
 | |
|                                stuff->xOrigin, stuff->yOrigin,
 | |
|                                nr, (xRectangle *) &stuff[1]);
 | |
| }
 | |
| 
 | |
| static int
 | |
| ProcRenderFreePicture(ClientPtr client)
 | |
| {
 | |
|     PicturePtr pPicture;
 | |
| 
 | |
|     REQUEST(xRenderFreePictureReq);
 | |
| 
 | |
|     REQUEST_SIZE_MATCH(xRenderFreePictureReq);
 | |
| 
 | |
|     VERIFY_PICTURE(pPicture, stuff->picture, client, DixDestroyAccess);
 | |
|     FreeResource(stuff->picture, RT_NONE);
 | |
|     return Success;
 | |
| }
 | |
| 
 | |
| static Bool
 | |
| PictOpValid(CARD8 op)
 | |
| {
 | |
|     if ( /*PictOpMinimum <= op && */ op <= PictOpMaximum)
 | |
|         return TRUE;
 | |
|     if (PictOpDisjointMinimum <= op && op <= PictOpDisjointMaximum)
 | |
|         return TRUE;
 | |
|     if (PictOpConjointMinimum <= op && op <= PictOpConjointMaximum)
 | |
|         return TRUE;
 | |
|     if (PictOpBlendMinimum <= op && op <= PictOpBlendMaximum)
 | |
|         return TRUE;
 | |
|     return FALSE;
 | |
| }
 | |
| 
 | |
| static int
 | |
| ProcRenderComposite(ClientPtr client)
 | |
| {
 | |
|     PicturePtr pSrc, pMask, pDst;
 | |
| 
 | |
|     REQUEST(xRenderCompositeReq);
 | |
| 
 | |
|     REQUEST_SIZE_MATCH(xRenderCompositeReq);
 | |
|     if (!PictOpValid(stuff->op)) {
 | |
|         client->errorValue = stuff->op;
 | |
|         return BadValue;
 | |
|     }
 | |
|     VERIFY_PICTURE(pDst, stuff->dst, client, DixWriteAccess);
 | |
|     if (!pDst->pDrawable)
 | |
|         return BadDrawable;
 | |
|     VERIFY_PICTURE(pSrc, stuff->src, client, DixReadAccess);
 | |
|     VERIFY_ALPHA(pMask, stuff->mask, client, DixReadAccess);
 | |
|     if ((pSrc->pDrawable &&
 | |
|          pSrc->pDrawable->pScreen != pDst->pDrawable->pScreen) || (pMask &&
 | |
|                                                                    pMask->
 | |
|                                                                    pDrawable &&
 | |
|                                                                    pDst->
 | |
|                                                                    pDrawable->
 | |
|                                                                    pScreen !=
 | |
|                                                                    pMask->
 | |
|                                                                    pDrawable->
 | |
|                                                                    pScreen))
 | |
|         return BadMatch;
 | |
|     CompositePicture(stuff->op,
 | |
|                      pSrc,
 | |
|                      pMask,
 | |
|                      pDst,
 | |
|                      stuff->xSrc,
 | |
|                      stuff->ySrc,
 | |
|                      stuff->xMask,
 | |
|                      stuff->yMask,
 | |
|                      stuff->xDst, stuff->yDst, stuff->width, stuff->height);
 | |
|     return Success;
 | |
| }
 | |
| 
 | |
| static int
 | |
| ProcRenderScale(ClientPtr client)
 | |
| {
 | |
|     return BadImplementation;
 | |
| }
 | |
| 
 | |
| static int
 | |
| ProcRenderTrapezoids(ClientPtr client)
 | |
| {
 | |
|     int rc, ntraps;
 | |
|     PicturePtr pSrc, pDst;
 | |
|     PictFormatPtr pFormat;
 | |
| 
 | |
|     REQUEST(xRenderTrapezoidsReq);
 | |
| 
 | |
|     REQUEST_AT_LEAST_SIZE(xRenderTrapezoidsReq);
 | |
|     if (!PictOpValid(stuff->op)) {
 | |
|         client->errorValue = stuff->op;
 | |
|         return BadValue;
 | |
|     }
 | |
|     VERIFY_PICTURE(pSrc, stuff->src, client, DixReadAccess);
 | |
|     VERIFY_PICTURE(pDst, stuff->dst, client, DixWriteAccess);
 | |
|     if (!pDst->pDrawable)
 | |
|         return BadDrawable;
 | |
|     if (pSrc->pDrawable && pSrc->pDrawable->pScreen != pDst->pDrawable->pScreen)
 | |
|         return BadMatch;
 | |
|     if (stuff->maskFormat) {
 | |
|         rc = dixLookupResourceByType((pointer *) &pFormat, stuff->maskFormat,
 | |
|                                      PictFormatType, client, DixReadAccess);
 | |
|         if (rc != Success)
 | |
|             return rc;
 | |
|     }
 | |
|     else
 | |
|         pFormat = 0;
 | |
|     ntraps = (client->req_len << 2) - sizeof(xRenderTrapezoidsReq);
 | |
|     if (ntraps % sizeof(xTrapezoid))
 | |
|         return BadLength;
 | |
|     ntraps /= sizeof(xTrapezoid);
 | |
|     if (ntraps)
 | |
|         CompositeTrapezoids(stuff->op, pSrc, pDst, pFormat,
 | |
|                             stuff->xSrc, stuff->ySrc,
 | |
|                             ntraps, (xTrapezoid *) &stuff[1]);
 | |
|     return Success;
 | |
| }
 | |
| 
 | |
| static int
 | |
| ProcRenderTriangles(ClientPtr client)
 | |
| {
 | |
|     int rc, ntris;
 | |
|     PicturePtr pSrc, pDst;
 | |
|     PictFormatPtr pFormat;
 | |
| 
 | |
|     REQUEST(xRenderTrianglesReq);
 | |
| 
 | |
|     REQUEST_AT_LEAST_SIZE(xRenderTrianglesReq);
 | |
|     if (!PictOpValid(stuff->op)) {
 | |
|         client->errorValue = stuff->op;
 | |
|         return BadValue;
 | |
|     }
 | |
|     VERIFY_PICTURE(pSrc, stuff->src, client, DixReadAccess);
 | |
|     VERIFY_PICTURE(pDst, stuff->dst, client, DixWriteAccess);
 | |
|     if (!pDst->pDrawable)
 | |
|         return BadDrawable;
 | |
|     if (pSrc->pDrawable && pSrc->pDrawable->pScreen != pDst->pDrawable->pScreen)
 | |
|         return BadMatch;
 | |
|     if (stuff->maskFormat) {
 | |
|         rc = dixLookupResourceByType((pointer *) &pFormat, stuff->maskFormat,
 | |
|                                      PictFormatType, client, DixReadAccess);
 | |
|         if (rc != Success)
 | |
|             return rc;
 | |
|     }
 | |
|     else
 | |
|         pFormat = 0;
 | |
|     ntris = (client->req_len << 2) - sizeof(xRenderTrianglesReq);
 | |
|     if (ntris % sizeof(xTriangle))
 | |
|         return BadLength;
 | |
|     ntris /= sizeof(xTriangle);
 | |
|     if (ntris)
 | |
|         CompositeTriangles(stuff->op, pSrc, pDst, pFormat,
 | |
|                            stuff->xSrc, stuff->ySrc,
 | |
|                            ntris, (xTriangle *) &stuff[1]);
 | |
|     return Success;
 | |
| }
 | |
| 
 | |
| static int
 | |
| ProcRenderTriStrip(ClientPtr client)
 | |
| {
 | |
|     int rc, npoints;
 | |
|     PicturePtr pSrc, pDst;
 | |
|     PictFormatPtr pFormat;
 | |
| 
 | |
|     REQUEST(xRenderTrianglesReq);
 | |
| 
 | |
|     REQUEST_AT_LEAST_SIZE(xRenderTrianglesReq);
 | |
|     if (!PictOpValid(stuff->op)) {
 | |
|         client->errorValue = stuff->op;
 | |
|         return BadValue;
 | |
|     }
 | |
|     VERIFY_PICTURE(pSrc, stuff->src, client, DixReadAccess);
 | |
|     VERIFY_PICTURE(pDst, stuff->dst, client, DixWriteAccess);
 | |
|     if (!pDst->pDrawable)
 | |
|         return BadDrawable;
 | |
|     if (pSrc->pDrawable && pSrc->pDrawable->pScreen != pDst->pDrawable->pScreen)
 | |
|         return BadMatch;
 | |
|     if (stuff->maskFormat) {
 | |
|         rc = dixLookupResourceByType((pointer *) &pFormat, stuff->maskFormat,
 | |
|                                      PictFormatType, client, DixReadAccess);
 | |
|         if (rc != Success)
 | |
|             return rc;
 | |
|     }
 | |
|     else
 | |
|         pFormat = 0;
 | |
|     npoints = ((client->req_len << 2) - sizeof(xRenderTriStripReq));
 | |
|     if (npoints & 4)
 | |
|         return BadLength;
 | |
|     npoints >>= 3;
 | |
|     if (npoints >= 3)
 | |
|         CompositeTriStrip(stuff->op, pSrc, pDst, pFormat,
 | |
|                           stuff->xSrc, stuff->ySrc,
 | |
|                           npoints, (xPointFixed *) &stuff[1]);
 | |
|     return Success;
 | |
| }
 | |
| 
 | |
| static int
 | |
| ProcRenderTriFan(ClientPtr client)
 | |
| {
 | |
|     int rc, npoints;
 | |
|     PicturePtr pSrc, pDst;
 | |
|     PictFormatPtr pFormat;
 | |
| 
 | |
|     REQUEST(xRenderTrianglesReq);
 | |
| 
 | |
|     REQUEST_AT_LEAST_SIZE(xRenderTrianglesReq);
 | |
|     if (!PictOpValid(stuff->op)) {
 | |
|         client->errorValue = stuff->op;
 | |
|         return BadValue;
 | |
|     }
 | |
|     VERIFY_PICTURE(pSrc, stuff->src, client, DixReadAccess);
 | |
|     VERIFY_PICTURE(pDst, stuff->dst, client, DixWriteAccess);
 | |
|     if (!pDst->pDrawable)
 | |
|         return BadDrawable;
 | |
|     if (pSrc->pDrawable && pSrc->pDrawable->pScreen != pDst->pDrawable->pScreen)
 | |
|         return BadMatch;
 | |
|     if (stuff->maskFormat) {
 | |
|         rc = dixLookupResourceByType((pointer *) &pFormat, stuff->maskFormat,
 | |
|                                      PictFormatType, client, DixReadAccess);
 | |
|         if (rc != Success)
 | |
|             return rc;
 | |
|     }
 | |
|     else
 | |
|         pFormat = 0;
 | |
|     npoints = ((client->req_len << 2) - sizeof(xRenderTriStripReq));
 | |
|     if (npoints & 4)
 | |
|         return BadLength;
 | |
|     npoints >>= 3;
 | |
|     if (npoints >= 3)
 | |
|         CompositeTriFan(stuff->op, pSrc, pDst, pFormat,
 | |
|                         stuff->xSrc, stuff->ySrc,
 | |
|                         npoints, (xPointFixed *) &stuff[1]);
 | |
|     return Success;
 | |
| }
 | |
| 
 | |
| static int
 | |
| ProcRenderColorTrapezoids(ClientPtr client)
 | |
| {
 | |
|     return BadImplementation;
 | |
| }
 | |
| 
 | |
| static int
 | |
| ProcRenderColorTriangles(ClientPtr client)
 | |
| {
 | |
|     return BadImplementation;
 | |
| }
 | |
| 
 | |
| static int
 | |
| ProcRenderTransform(ClientPtr client)
 | |
| {
 | |
|     return BadImplementation;
 | |
| }
 | |
| 
 | |
| static int
 | |
| ProcRenderCreateGlyphSet(ClientPtr client)
 | |
| {
 | |
|     GlyphSetPtr glyphSet;
 | |
|     PictFormatPtr format;
 | |
|     int rc, f;
 | |
| 
 | |
|     REQUEST(xRenderCreateGlyphSetReq);
 | |
| 
 | |
|     REQUEST_SIZE_MATCH(xRenderCreateGlyphSetReq);
 | |
| 
 | |
|     LEGAL_NEW_RESOURCE(stuff->gsid, client);
 | |
|     rc = dixLookupResourceByType((pointer *) &format, stuff->format,
 | |
|                                  PictFormatType, client, DixReadAccess);
 | |
|     if (rc != Success)
 | |
|         return rc;
 | |
| 
 | |
|     switch (format->depth) {
 | |
|     case 1:
 | |
|         f = GlyphFormat1;
 | |
|         break;
 | |
|     case 4:
 | |
|         f = GlyphFormat4;
 | |
|         break;
 | |
|     case 8:
 | |
|         f = GlyphFormat8;
 | |
|         break;
 | |
|     case 16:
 | |
|         f = GlyphFormat16;
 | |
|         break;
 | |
|     case 32:
 | |
|         f = GlyphFormat32;
 | |
|         break;
 | |
|     default:
 | |
|         return BadMatch;
 | |
|     }
 | |
|     if (format->type != PictTypeDirect)
 | |
|         return BadMatch;
 | |
|     glyphSet = AllocateGlyphSet(f, format);
 | |
|     if (!glyphSet)
 | |
|         return BadAlloc;
 | |
|     /* security creation/labeling check */
 | |
|     rc = XaceHook(XACE_RESOURCE_ACCESS, client, stuff->gsid, GlyphSetType,
 | |
|                   glyphSet, RT_NONE, NULL, DixCreateAccess);
 | |
|     if (rc != Success)
 | |
|         return rc;
 | |
|     if (!AddResource(stuff->gsid, GlyphSetType, (pointer) glyphSet))
 | |
|         return BadAlloc;
 | |
|     return Success;
 | |
| }
 | |
| 
 | |
| static int
 | |
| ProcRenderReferenceGlyphSet(ClientPtr client)
 | |
| {
 | |
|     GlyphSetPtr glyphSet;
 | |
|     int rc;
 | |
| 
 | |
|     REQUEST(xRenderReferenceGlyphSetReq);
 | |
| 
 | |
|     REQUEST_SIZE_MATCH(xRenderReferenceGlyphSetReq);
 | |
| 
 | |
|     LEGAL_NEW_RESOURCE(stuff->gsid, client);
 | |
| 
 | |
|     rc = dixLookupResourceByType((pointer *) &glyphSet, stuff->existing,
 | |
|                                  GlyphSetType, client, DixGetAttrAccess);
 | |
|     if (rc != Success) {
 | |
|         client->errorValue = stuff->existing;
 | |
|         return rc;
 | |
|     }
 | |
|     glyphSet->refcnt++;
 | |
|     if (!AddResource(stuff->gsid, GlyphSetType, (pointer) glyphSet))
 | |
|         return BadAlloc;
 | |
|     return Success;
 | |
| }
 | |
| 
 | |
| #define NLOCALDELTA	64
 | |
| #define NLOCALGLYPH	256
 | |
| 
 | |
| static int
 | |
| ProcRenderFreeGlyphSet(ClientPtr client)
 | |
| {
 | |
|     GlyphSetPtr glyphSet;
 | |
|     int rc;
 | |
| 
 | |
|     REQUEST(xRenderFreeGlyphSetReq);
 | |
| 
 | |
|     REQUEST_SIZE_MATCH(xRenderFreeGlyphSetReq);
 | |
|     rc = dixLookupResourceByType((pointer *) &glyphSet, stuff->glyphset,
 | |
|                                  GlyphSetType, client, DixDestroyAccess);
 | |
|     if (rc != Success) {
 | |
|         client->errorValue = stuff->glyphset;
 | |
|         return rc;
 | |
|     }
 | |
|     FreeResource(stuff->glyphset, RT_NONE);
 | |
|     return Success;
 | |
| }
 | |
| 
 | |
| typedef struct _GlyphNew {
 | |
|     Glyph id;
 | |
|     GlyphPtr glyph;
 | |
|     Bool found;
 | |
|     unsigned char sha1[20];
 | |
| } GlyphNewRec, *GlyphNewPtr;
 | |
| 
 | |
| #define NeedsComponent(f) (PICT_FORMAT_A(f) != 0 && PICT_FORMAT_RGB(f) != 0)
 | |
| 
 | |
| static int
 | |
| ProcRenderAddGlyphs(ClientPtr client)
 | |
| {
 | |
|     GlyphSetPtr glyphSet;
 | |
| 
 | |
|     REQUEST(xRenderAddGlyphsReq);
 | |
|     GlyphNewRec glyphsLocal[NLOCALGLYPH];
 | |
|     GlyphNewPtr glyphsBase, glyphs, glyph_new;
 | |
|     int remain, nglyphs;
 | |
|     CARD32 *gids;
 | |
|     xGlyphInfo *gi;
 | |
|     CARD8 *bits;
 | |
|     unsigned int size;
 | |
|     int err;
 | |
|     int i, screen;
 | |
|     PicturePtr pSrc = NULL, pDst = NULL;
 | |
|     PixmapPtr pSrcPix = NULL, pDstPix = NULL;
 | |
|     CARD32 component_alpha;
 | |
| 
 | |
|     REQUEST_AT_LEAST_SIZE(xRenderAddGlyphsReq);
 | |
|     err =
 | |
|         dixLookupResourceByType((pointer *) &glyphSet, stuff->glyphset,
 | |
|                                 GlyphSetType, client, DixAddAccess);
 | |
|     if (err != Success) {
 | |
|         client->errorValue = stuff->glyphset;
 | |
|         return err;
 | |
|     }
 | |
| 
 | |
|     err = BadAlloc;
 | |
|     nglyphs = stuff->nglyphs;
 | |
|     if (nglyphs > UINT32_MAX / sizeof(GlyphNewRec))
 | |
|         return BadAlloc;
 | |
| 
 | |
|     component_alpha = NeedsComponent(glyphSet->format->format);
 | |
| 
 | |
|     if (nglyphs <= NLOCALGLYPH) {
 | |
|         memset(glyphsLocal, 0, sizeof(glyphsLocal));
 | |
|         glyphsBase = glyphsLocal;
 | |
|     }
 | |
|     else {
 | |
|         glyphsBase = (GlyphNewPtr) calloc(nglyphs, sizeof(GlyphNewRec));
 | |
|         if (!glyphsBase)
 | |
|             return BadAlloc;
 | |
|     }
 | |
| 
 | |
|     remain = (client->req_len << 2) - sizeof(xRenderAddGlyphsReq);
 | |
| 
 | |
|     glyphs = glyphsBase;
 | |
| 
 | |
|     gids = (CARD32 *) (stuff + 1);
 | |
|     gi = (xGlyphInfo *) (gids + nglyphs);
 | |
|     bits = (CARD8 *) (gi + nglyphs);
 | |
|     remain -= (sizeof(CARD32) + sizeof(xGlyphInfo)) * nglyphs;
 | |
| 
 | |
|     /* protect against bad nglyphs */
 | |
|     if (gi < ((xGlyphInfo *) stuff) ||
 | |
|         gi > ((xGlyphInfo *) ((CARD32 *) stuff + client->req_len)) ||
 | |
|         bits < ((CARD8 *) stuff) ||
 | |
|         bits > ((CARD8 *) ((CARD32 *) stuff + client->req_len))) {
 | |
|         err = BadLength;
 | |
|         goto bail;
 | |
|     }
 | |
| 
 | |
|     for (i = 0; i < nglyphs; i++) {
 | |
|         size_t padded_width;
 | |
| 
 | |
|         glyph_new = &glyphs[i];
 | |
| 
 | |
|         padded_width = PixmapBytePad(gi[i].width, glyphSet->format->depth);
 | |
| 
 | |
|         if (gi[i].height &&
 | |
|             padded_width > (UINT32_MAX - sizeof(GlyphRec)) / gi[i].height)
 | |
|             break;
 | |
| 
 | |
|         size = gi[i].height * padded_width;
 | |
|         if (remain < size)
 | |
|             break;
 | |
| 
 | |
|         err = HashGlyph(&gi[i], bits, size, glyph_new->sha1);
 | |
|         if (err)
 | |
|             goto bail;
 | |
| 
 | |
|         glyph_new->glyph = FindGlyphByHash(glyph_new->sha1, glyphSet->fdepth);
 | |
| 
 | |
|         if (glyph_new->glyph && glyph_new->glyph != DeletedGlyph) {
 | |
|             glyph_new->found = TRUE;
 | |
|         }
 | |
|         else {
 | |
|             GlyphPtr glyph;
 | |
| 
 | |
|             glyph_new->found = FALSE;
 | |
|             glyph_new->glyph = glyph = AllocateGlyph(&gi[i], glyphSet->fdepth);
 | |
|             if (!glyph) {
 | |
|                 err = BadAlloc;
 | |
|                 goto bail;
 | |
|             }
 | |
| 
 | |
|             for (screen = 0; screen < screenInfo.numScreens; screen++) {
 | |
|                 int width = gi[i].width;
 | |
|                 int height = gi[i].height;
 | |
|                 int depth = glyphSet->format->depth;
 | |
|                 ScreenPtr pScreen;
 | |
|                 int error;
 | |
| 
 | |
|                 /* Skip work if it's invisibly small anyway */
 | |
|                 if (!width || !height)
 | |
|                     break;
 | |
| 
 | |
|                 pScreen = screenInfo.screens[screen];
 | |
|                 pSrcPix = GetScratchPixmapHeader(pScreen,
 | |
|                                                  width, height,
 | |
|                                                  depth, depth, -1, bits);
 | |
|                 if (!pSrcPix) {
 | |
|                     err = BadAlloc;
 | |
|                     goto bail;
 | |
|                 }
 | |
| 
 | |
|                 pSrc = CreatePicture(0, &pSrcPix->drawable,
 | |
|                                      glyphSet->format, 0, NULL,
 | |
|                                      serverClient, &error);
 | |
|                 if (!pSrc) {
 | |
|                     err = BadAlloc;
 | |
|                     goto bail;
 | |
|                 }
 | |
| 
 | |
|                 pDstPix = (pScreen->CreatePixmap) (pScreen,
 | |
|                                                    width, height, depth,
 | |
|                                                    CREATE_PIXMAP_USAGE_GLYPH_PICTURE);
 | |
| 
 | |
|                 if (!pDstPix) {
 | |
|                     err = BadAlloc;
 | |
|                     goto bail;
 | |
|                 }
 | |
| 
 | |
|                 GlyphPicture(glyph)[screen] = pDst =
 | |
|                     CreatePicture(0, &pDstPix->drawable,
 | |
|                                   glyphSet->format,
 | |
|                                   CPComponentAlpha, &component_alpha,
 | |
|                                   serverClient, &error);
 | |
| 
 | |
|                 /* The picture takes a reference to the pixmap, so we
 | |
|                    drop ours. */
 | |
|                 (pScreen->DestroyPixmap) (pDstPix);
 | |
|                 pDstPix = NULL;
 | |
| 
 | |
|                 if (!pDst) {
 | |
|                     err = BadAlloc;
 | |
|                     goto bail;
 | |
|                 }
 | |
| 
 | |
|                 CompositePicture(PictOpSrc,
 | |
|                                  pSrc,
 | |
|                                  None, pDst, 0, 0, 0, 0, 0, 0, width, height);
 | |
| 
 | |
|                 FreePicture((pointer) pSrc, 0);
 | |
|                 pSrc = NULL;
 | |
|                 FreeScratchPixmapHeader(pSrcPix);
 | |
|                 pSrcPix = NULL;
 | |
|             }
 | |
| 
 | |
|             memcpy(glyph_new->glyph->sha1, glyph_new->sha1, 20);
 | |
|         }
 | |
| 
 | |
|         glyph_new->id = gids[i];
 | |
| 
 | |
|         if (size & 3)
 | |
|             size += 4 - (size & 3);
 | |
|         bits += size;
 | |
|         remain -= size;
 | |
|     }
 | |
|     if (remain || i < nglyphs) {
 | |
|         err = BadLength;
 | |
|         goto bail;
 | |
|     }
 | |
|     if (!ResizeGlyphSet(glyphSet, nglyphs)) {
 | |
|         err = BadAlloc;
 | |
|         goto bail;
 | |
|     }
 | |
|     for (i = 0; i < nglyphs; i++)
 | |
|         AddGlyph(glyphSet, glyphs[i].glyph, glyphs[i].id);
 | |
| 
 | |
|     if (glyphsBase != glyphsLocal)
 | |
|         free(glyphsBase);
 | |
|     return Success;
 | |
|  bail:
 | |
|     if (pSrc)
 | |
|         FreePicture((pointer) pSrc, 0);
 | |
|     if (pSrcPix)
 | |
|         FreeScratchPixmapHeader(pSrcPix);
 | |
|     for (i = 0; i < nglyphs; i++)
 | |
|         if (glyphs[i].glyph && !glyphs[i].found)
 | |
|             free(glyphs[i].glyph);
 | |
|     if (glyphsBase != glyphsLocal)
 | |
|         free(glyphsBase);
 | |
|     return err;
 | |
| }
 | |
| 
 | |
| static int
 | |
| ProcRenderAddGlyphsFromPicture(ClientPtr client)
 | |
| {
 | |
|     return BadImplementation;
 | |
| }
 | |
| 
 | |
| static int
 | |
| ProcRenderFreeGlyphs(ClientPtr client)
 | |
| {
 | |
|     REQUEST(xRenderFreeGlyphsReq);
 | |
|     GlyphSetPtr glyphSet;
 | |
|     int rc, nglyph;
 | |
|     CARD32 *gids;
 | |
|     CARD32 glyph;
 | |
| 
 | |
|     REQUEST_AT_LEAST_SIZE(xRenderFreeGlyphsReq);
 | |
|     rc = dixLookupResourceByType((pointer *) &glyphSet, stuff->glyphset,
 | |
|                                  GlyphSetType, client, DixRemoveAccess);
 | |
|     if (rc != Success) {
 | |
|         client->errorValue = stuff->glyphset;
 | |
|         return rc;
 | |
|     }
 | |
|     nglyph =
 | |
|         bytes_to_int32((client->req_len << 2) - sizeof(xRenderFreeGlyphsReq));
 | |
|     gids = (CARD32 *) (stuff + 1);
 | |
|     while (nglyph-- > 0) {
 | |
|         glyph = *gids++;
 | |
|         if (!DeleteGlyph(glyphSet, glyph)) {
 | |
|             client->errorValue = glyph;
 | |
|             return RenderErrBase + BadGlyph;
 | |
|         }
 | |
|     }
 | |
|     return Success;
 | |
| }
 | |
| 
 | |
| static int
 | |
| ProcRenderCompositeGlyphs(ClientPtr client)
 | |
| {
 | |
|     GlyphSetPtr glyphSet;
 | |
|     GlyphSet gs;
 | |
|     PicturePtr pSrc, pDst;
 | |
|     PictFormatPtr pFormat;
 | |
|     GlyphListRec listsLocal[NLOCALDELTA];
 | |
|     GlyphListPtr lists, listsBase;
 | |
|     GlyphPtr glyphsLocal[NLOCALGLYPH];
 | |
|     Glyph glyph;
 | |
|     GlyphPtr *glyphs, *glyphsBase;
 | |
|     xGlyphElt *elt;
 | |
|     CARD8 *buffer, *end;
 | |
|     int nglyph;
 | |
|     int nlist;
 | |
|     int space;
 | |
|     int size;
 | |
|     int rc, n;
 | |
| 
 | |
|     REQUEST(xRenderCompositeGlyphsReq);
 | |
| 
 | |
|     REQUEST_AT_LEAST_SIZE(xRenderCompositeGlyphsReq);
 | |
| 
 | |
|     switch (stuff->renderReqType) {
 | |
|     default:
 | |
|         size = 1;
 | |
|         break;
 | |
|     case X_RenderCompositeGlyphs16:
 | |
|         size = 2;
 | |
|         break;
 | |
|     case X_RenderCompositeGlyphs32:
 | |
|         size = 4;
 | |
|         break;
 | |
|     }
 | |
| 
 | |
|     if (!PictOpValid(stuff->op)) {
 | |
|         client->errorValue = stuff->op;
 | |
|         return BadValue;
 | |
|     }
 | |
|     VERIFY_PICTURE(pSrc, stuff->src, client, DixReadAccess);
 | |
|     VERIFY_PICTURE(pDst, stuff->dst, client, DixWriteAccess);
 | |
|     if (!pDst->pDrawable)
 | |
|         return BadDrawable;
 | |
|     if (pSrc->pDrawable && pSrc->pDrawable->pScreen != pDst->pDrawable->pScreen)
 | |
|         return BadMatch;
 | |
|     if (stuff->maskFormat) {
 | |
|         rc = dixLookupResourceByType((pointer *) &pFormat, stuff->maskFormat,
 | |
|                                      PictFormatType, client, DixReadAccess);
 | |
|         if (rc != Success)
 | |
|             return rc;
 | |
|     }
 | |
|     else
 | |
|         pFormat = 0;
 | |
| 
 | |
|     rc = dixLookupResourceByType((pointer *) &glyphSet, stuff->glyphset,
 | |
|                                  GlyphSetType, client, DixUseAccess);
 | |
|     if (rc != Success)
 | |
|         return rc;
 | |
| 
 | |
|     buffer = (CARD8 *) (stuff + 1);
 | |
|     end = (CARD8 *) stuff + (client->req_len << 2);
 | |
|     nglyph = 0;
 | |
|     nlist = 0;
 | |
|     while (buffer + sizeof(xGlyphElt) < end) {
 | |
|         elt = (xGlyphElt *) buffer;
 | |
|         buffer += sizeof(xGlyphElt);
 | |
| 
 | |
|         if (elt->len == 0xff) {
 | |
|             buffer += 4;
 | |
|         }
 | |
|         else {
 | |
|             nlist++;
 | |
|             nglyph += elt->len;
 | |
|             space = size * elt->len;
 | |
|             if (space & 3)
 | |
|                 space += 4 - (space & 3);
 | |
|             buffer += space;
 | |
|         }
 | |
|     }
 | |
|     if (nglyph <= NLOCALGLYPH)
 | |
|         glyphsBase = glyphsLocal;
 | |
|     else {
 | |
|         glyphsBase = (GlyphPtr *) malloc(nglyph * sizeof(GlyphPtr));
 | |
|         if (!glyphsBase)
 | |
|             return BadAlloc;
 | |
|     }
 | |
|     if (nlist <= NLOCALDELTA)
 | |
|         listsBase = listsLocal;
 | |
|     else {
 | |
|         listsBase = (GlyphListPtr) malloc(nlist * sizeof(GlyphListRec));
 | |
|         if (!listsBase) {
 | |
|             rc = BadAlloc;
 | |
|             goto bail;
 | |
|         }
 | |
|     }
 | |
|     buffer = (CARD8 *) (stuff + 1);
 | |
|     glyphs = glyphsBase;
 | |
|     lists = listsBase;
 | |
|     while (buffer + sizeof(xGlyphElt) < end) {
 | |
|         elt = (xGlyphElt *) buffer;
 | |
|         buffer += sizeof(xGlyphElt);
 | |
| 
 | |
|         if (elt->len == 0xff) {
 | |
|             if (buffer + sizeof(GlyphSet) < end) {
 | |
|                 memcpy(&gs, buffer, sizeof(GlyphSet));
 | |
|                 rc = dixLookupResourceByType((pointer *) &glyphSet, gs,
 | |
|                                              GlyphSetType, client,
 | |
|                                              DixUseAccess);
 | |
|                 if (rc != Success)
 | |
|                     goto bail;
 | |
|             }
 | |
|             buffer += 4;
 | |
|         }
 | |
|         else {
 | |
|             lists->xOff = elt->deltax;
 | |
|             lists->yOff = elt->deltay;
 | |
|             lists->format = glyphSet->format;
 | |
|             lists->len = 0;
 | |
|             n = elt->len;
 | |
|             while (n--) {
 | |
|                 if (buffer + size <= end) {
 | |
|                     switch (size) {
 | |
|                     case 1:
 | |
|                         glyph = *((CARD8 *) buffer);
 | |
|                         break;
 | |
|                     case 2:
 | |
|                         glyph = *((CARD16 *) buffer);
 | |
|                         break;
 | |
|                     case 4:
 | |
|                     default:
 | |
|                         glyph = *((CARD32 *) buffer);
 | |
|                         break;
 | |
|                     }
 | |
|                     if ((*glyphs = FindGlyph(glyphSet, glyph))) {
 | |
|                         lists->len++;
 | |
|                         glyphs++;
 | |
|                     }
 | |
|                 }
 | |
|                 buffer += size;
 | |
|             }
 | |
|             space = size * elt->len;
 | |
|             if (space & 3)
 | |
|                 buffer += 4 - (space & 3);
 | |
|             lists++;
 | |
|         }
 | |
|     }
 | |
|     if (buffer > end) {
 | |
|         rc = BadLength;
 | |
|         goto bail;
 | |
|     }
 | |
| 
 | |
|     CompositeGlyphs(stuff->op,
 | |
|                     pSrc,
 | |
|                     pDst,
 | |
|                     pFormat,
 | |
|                     stuff->xSrc, stuff->ySrc, nlist, listsBase, glyphsBase);
 | |
|     rc = Success;
 | |
| 
 | |
|  bail:
 | |
|     if (glyphsBase != glyphsLocal)
 | |
|         free(glyphsBase);
 | |
|     if (listsBase != listsLocal)
 | |
|         free(listsBase);
 | |
|     return rc;
 | |
| }
 | |
| 
 | |
| static int
 | |
| ProcRenderFillRectangles(ClientPtr client)
 | |
| {
 | |
|     PicturePtr pDst;
 | |
|     int things;
 | |
| 
 | |
|     REQUEST(xRenderFillRectanglesReq);
 | |
| 
 | |
|     REQUEST_AT_LEAST_SIZE(xRenderFillRectanglesReq);
 | |
|     if (!PictOpValid(stuff->op)) {
 | |
|         client->errorValue = stuff->op;
 | |
|         return BadValue;
 | |
|     }
 | |
|     VERIFY_PICTURE(pDst, stuff->dst, client, DixWriteAccess);
 | |
|     if (!pDst->pDrawable)
 | |
|         return BadDrawable;
 | |
| 
 | |
|     things = (client->req_len << 2) - sizeof(xRenderFillRectanglesReq);
 | |
|     if (things & 4)
 | |
|         return BadLength;
 | |
|     things >>= 3;
 | |
| 
 | |
|     CompositeRects(stuff->op,
 | |
|                    pDst, &stuff->color, things, (xRectangle *) &stuff[1]);
 | |
| 
 | |
|     return Success;
 | |
| }
 | |
| 
 | |
| static void
 | |
| RenderSetBit(unsigned char *line, int x, int bit)
 | |
| {
 | |
|     unsigned char mask;
 | |
| 
 | |
|     if (screenInfo.bitmapBitOrder == LSBFirst)
 | |
|         mask = (1 << (x & 7));
 | |
|     else
 | |
|         mask = (0x80 >> (x & 7));
 | |
|     /* XXX assumes byte order is host byte order */
 | |
|     line += (x >> 3);
 | |
|     if (bit)
 | |
|         *line |= mask;
 | |
|     else
 | |
|         *line &= ~mask;
 | |
| }
 | |
| 
 | |
| #define DITHER_DIM 2
 | |
| 
 | |
| static CARD32 orderedDither[DITHER_DIM][DITHER_DIM] = {
 | |
|     {1, 3,},
 | |
|     {4, 2,},
 | |
| };
 | |
| 
 | |
| #define DITHER_SIZE  ((sizeof orderedDither / sizeof orderedDither[0][0]) + 1)
 | |
| 
 | |
| static int
 | |
| ProcRenderCreateCursor(ClientPtr client)
 | |
| {
 | |
|     REQUEST(xRenderCreateCursorReq);
 | |
|     PicturePtr pSrc;
 | |
|     ScreenPtr pScreen;
 | |
|     unsigned short width, height;
 | |
|     CARD32 *argbbits, *argb;
 | |
|     unsigned char *srcbits, *srcline;
 | |
|     unsigned char *mskbits, *mskline;
 | |
|     int stride;
 | |
|     int x, y;
 | |
|     int nbytes_mono;
 | |
|     CursorMetricRec cm;
 | |
|     CursorPtr pCursor;
 | |
|     CARD32 twocolor[3];
 | |
|     int rc, ncolor;
 | |
| 
 | |
|     REQUEST_SIZE_MATCH(xRenderCreateCursorReq);
 | |
|     LEGAL_NEW_RESOURCE(stuff->cid, client);
 | |
| 
 | |
|     VERIFY_PICTURE(pSrc, stuff->src, client, DixReadAccess);
 | |
|     if (!pSrc->pDrawable)
 | |
|         return BadDrawable;
 | |
|     pScreen = pSrc->pDrawable->pScreen;
 | |
|     width = pSrc->pDrawable->width;
 | |
|     height = pSrc->pDrawable->height;
 | |
|     if (height && width > UINT32_MAX / (height * sizeof(CARD32)))
 | |
|         return BadAlloc;
 | |
|     if (stuff->x > width || stuff->y > height)
 | |
|         return BadMatch;
 | |
|     argbbits = malloc(width * height * sizeof(CARD32));
 | |
|     if (!argbbits)
 | |
|         return BadAlloc;
 | |
| 
 | |
|     stride = BitmapBytePad(width);
 | |
|     nbytes_mono = stride * height;
 | |
|     srcbits = calloc(1, nbytes_mono);
 | |
|     if (!srcbits) {
 | |
|         free(argbbits);
 | |
|         return BadAlloc;
 | |
|     }
 | |
|     mskbits = calloc(1, nbytes_mono);
 | |
|     if (!mskbits) {
 | |
|         free(argbbits);
 | |
|         free(srcbits);
 | |
|         return BadAlloc;
 | |
|     }
 | |
| 
 | |
|     if (pSrc->format == PICT_a8r8g8b8) {
 | |
|         (*pScreen->GetImage) (pSrc->pDrawable,
 | |
|                               0, 0, width, height, ZPixmap,
 | |
|                               0xffffffff, (pointer) argbbits);
 | |
|     }
 | |
|     else {
 | |
|         PixmapPtr pPixmap;
 | |
|         PicturePtr pPicture;
 | |
|         PictFormatPtr pFormat;
 | |
|         int error;
 | |
| 
 | |
|         pFormat = PictureMatchFormat(pScreen, 32, PICT_a8r8g8b8);
 | |
|         if (!pFormat) {
 | |
|             free(argbbits);
 | |
|             free(srcbits);
 | |
|             free(mskbits);
 | |
|             return BadImplementation;
 | |
|         }
 | |
|         pPixmap = (*pScreen->CreatePixmap) (pScreen, width, height, 32,
 | |
|                                             CREATE_PIXMAP_USAGE_SCRATCH);
 | |
|         if (!pPixmap) {
 | |
|             free(argbbits);
 | |
|             free(srcbits);
 | |
|             free(mskbits);
 | |
|             return BadAlloc;
 | |
|         }
 | |
|         pPicture = CreatePicture(0, &pPixmap->drawable, pFormat, 0, 0,
 | |
|                                  client, &error);
 | |
|         if (!pPicture) {
 | |
|             free(argbbits);
 | |
|             free(srcbits);
 | |
|             free(mskbits);
 | |
|             return error;
 | |
|         }
 | |
|         (*pScreen->DestroyPixmap) (pPixmap);
 | |
|         CompositePicture(PictOpSrc,
 | |
|                          pSrc, 0, pPicture, 0, 0, 0, 0, 0, 0, width, height);
 | |
|         (*pScreen->GetImage) (pPicture->pDrawable,
 | |
|                               0, 0, width, height, ZPixmap,
 | |
|                               0xffffffff, (pointer) argbbits);
 | |
|         FreePicture(pPicture, 0);
 | |
|     }
 | |
|     /*
 | |
|      * Check whether the cursor can be directly supported by 
 | |
|      * the core cursor code
 | |
|      */
 | |
|     ncolor = 0;
 | |
|     argb = argbbits;
 | |
|     for (y = 0; ncolor <= 2 && y < height; y++) {
 | |
|         for (x = 0; ncolor <= 2 && x < width; x++) {
 | |
|             CARD32 p = *argb++;
 | |
|             CARD32 a = (p >> 24);
 | |
| 
 | |
|             if (a == 0)         /* transparent */
 | |
|                 continue;
 | |
|             if (a == 0xff) {    /* opaque */
 | |
|                 int n;
 | |
| 
 | |
|                 for (n = 0; n < ncolor; n++)
 | |
|                     if (p == twocolor[n])
 | |
|                         break;
 | |
|                 if (n == ncolor)
 | |
|                     twocolor[ncolor++] = p;
 | |
|             }
 | |
|             else
 | |
|                 ncolor = 3;
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     /*
 | |
|      * Convert argb image to two plane cursor
 | |
|      */
 | |
|     srcline = srcbits;
 | |
|     mskline = mskbits;
 | |
|     argb = argbbits;
 | |
|     for (y = 0; y < height; y++) {
 | |
|         for (x = 0; x < width; x++) {
 | |
|             CARD32 p = *argb++;
 | |
| 
 | |
|             if (ncolor <= 2) {
 | |
|                 CARD32 a = ((p >> 24));
 | |
| 
 | |
|                 RenderSetBit(mskline, x, a != 0);
 | |
|                 RenderSetBit(srcline, x, a != 0 && p == twocolor[0]);
 | |
|             }
 | |
|             else {
 | |
|                 CARD32 a = ((p >> 24) * DITHER_SIZE + 127) / 255;
 | |
|                 CARD32 i = ((CvtR8G8B8toY15(p) >> 7) * DITHER_SIZE + 127) / 255;
 | |
|                 CARD32 d =
 | |
|                     orderedDither[y & (DITHER_DIM - 1)][x & (DITHER_DIM - 1)];
 | |
|                 /* Set mask from dithered alpha value */
 | |
|                 RenderSetBit(mskline, x, a > d);
 | |
|                 /* Set src from dithered intensity value */
 | |
|                 RenderSetBit(srcline, x, a > d && i <= d);
 | |
|             }
 | |
|         }
 | |
|         srcline += stride;
 | |
|         mskline += stride;
 | |
|     }
 | |
|     /*
 | |
|      * Dither to white and black if the cursor has more than two colors
 | |
|      */
 | |
|     if (ncolor > 2) {
 | |
|         twocolor[0] = 0xff000000;
 | |
|         twocolor[1] = 0xffffffff;
 | |
|     }
 | |
|     else {
 | |
|         free(argbbits);
 | |
|         argbbits = 0;
 | |
|     }
 | |
| 
 | |
| #define GetByte(p,s)	(((p) >> (s)) & 0xff)
 | |
| #define GetColor(p,s)	(GetByte(p,s) | (GetByte(p,s) << 8))
 | |
| 
 | |
|     cm.width = width;
 | |
|     cm.height = height;
 | |
|     cm.xhot = stuff->x;
 | |
|     cm.yhot = stuff->y;
 | |
|     rc = AllocARGBCursor(srcbits, mskbits, argbbits, &cm,
 | |
|                          GetColor(twocolor[0], 16),
 | |
|                          GetColor(twocolor[0], 8),
 | |
|                          GetColor(twocolor[0], 0),
 | |
|                          GetColor(twocolor[1], 16),
 | |
|                          GetColor(twocolor[1], 8),
 | |
|                          GetColor(twocolor[1], 0),
 | |
|                          &pCursor, client, stuff->cid);
 | |
|     if (rc != Success)
 | |
|         goto bail;
 | |
|     if (!AddResource(stuff->cid, RT_CURSOR, (pointer) pCursor)) {
 | |
|         rc = BadAlloc;
 | |
|         goto bail;
 | |
|     }
 | |
| 
 | |
|     return Success;
 | |
|  bail:
 | |
|     free(srcbits);
 | |
|     free(mskbits);
 | |
|     return rc;
 | |
| }
 | |
| 
 | |
| static int
 | |
| ProcRenderSetPictureTransform(ClientPtr client)
 | |
| {
 | |
|     REQUEST(xRenderSetPictureTransformReq);
 | |
|     PicturePtr pPicture;
 | |
| 
 | |
|     REQUEST_SIZE_MATCH(xRenderSetPictureTransformReq);
 | |
|     VERIFY_PICTURE(pPicture, stuff->picture, client, DixSetAttrAccess);
 | |
|     return SetPictureTransform(pPicture, (PictTransform *) &stuff->transform);
 | |
| }
 | |
| 
 | |
| static int
 | |
| ProcRenderQueryFilters(ClientPtr client)
 | |
| {
 | |
|     REQUEST(xRenderQueryFiltersReq);
 | |
|     DrawablePtr pDrawable;
 | |
|     xRenderQueryFiltersReply *reply;
 | |
|     int nbytesName;
 | |
|     int nnames;
 | |
|     ScreenPtr pScreen;
 | |
|     PictureScreenPtr ps;
 | |
|     int i, j, len, total_bytes, rc;
 | |
|     INT16 *aliases;
 | |
|     char *names;
 | |
| 
 | |
|     REQUEST_SIZE_MATCH(xRenderQueryFiltersReq);
 | |
|     rc = dixLookupDrawable(&pDrawable, stuff->drawable, client, 0,
 | |
|                            DixGetAttrAccess);
 | |
|     if (rc != Success)
 | |
|         return rc;
 | |
| 
 | |
|     pScreen = pDrawable->pScreen;
 | |
|     nbytesName = 0;
 | |
|     nnames = 0;
 | |
|     ps = GetPictureScreenIfSet(pScreen);
 | |
|     if (ps) {
 | |
|         for (i = 0; i < ps->nfilters; i++)
 | |
|             nbytesName += 1 + strlen(ps->filters[i].name);
 | |
|         for (i = 0; i < ps->nfilterAliases; i++)
 | |
|             nbytesName += 1 + strlen(ps->filterAliases[i].alias);
 | |
|         nnames = ps->nfilters + ps->nfilterAliases;
 | |
|     }
 | |
|     len = ((nnames + 1) >> 1) + bytes_to_int32(nbytesName);
 | |
|     total_bytes = sizeof(xRenderQueryFiltersReply) + (len << 2);
 | |
|     reply = (xRenderQueryFiltersReply *) malloc(total_bytes);
 | |
|     if (!reply)
 | |
|         return BadAlloc;
 | |
|     aliases = (INT16 *) (reply + 1);
 | |
|     names = (char *) (aliases + ((nnames + 1) & ~1));
 | |
| 
 | |
|     reply->type = X_Reply;
 | |
|     reply->sequenceNumber = client->sequence;
 | |
|     reply->length = len;
 | |
|     reply->numAliases = nnames;
 | |
|     reply->numFilters = nnames;
 | |
|     if (ps) {
 | |
| 
 | |
|         /* fill in alias values */
 | |
|         for (i = 0; i < ps->nfilters; i++)
 | |
|             aliases[i] = FilterAliasNone;
 | |
|         for (i = 0; i < ps->nfilterAliases; i++) {
 | |
|             for (j = 0; j < ps->nfilters; j++)
 | |
|                 if (ps->filterAliases[i].filter_id == ps->filters[j].id)
 | |
|                     break;
 | |
|             if (j == ps->nfilters) {
 | |
|                 for (j = 0; j < ps->nfilterAliases; j++)
 | |
|                     if (ps->filterAliases[i].filter_id ==
 | |
|                         ps->filterAliases[j].alias_id) {
 | |
|                         break;
 | |
|                     }
 | |
|                 if (j == ps->nfilterAliases)
 | |
|                     j = FilterAliasNone;
 | |
|                 else
 | |
|                     j = j + ps->nfilters;
 | |
|             }
 | |
|             aliases[i + ps->nfilters] = j;
 | |
|         }
 | |
| 
 | |
|         /* fill in filter names */
 | |
|         for (i = 0; i < ps->nfilters; i++) {
 | |
|             j = strlen(ps->filters[i].name);
 | |
|             *names++ = j;
 | |
|             memcpy(names, ps->filters[i].name, j);
 | |
|             names += j;
 | |
|         }
 | |
| 
 | |
|         /* fill in filter alias names */
 | |
|         for (i = 0; i < ps->nfilterAliases; i++) {
 | |
|             j = strlen(ps->filterAliases[i].alias);
 | |
|             *names++ = j;
 | |
|             memcpy(names, ps->filterAliases[i].alias, j);
 | |
|             names += j;
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     if (client->swapped) {
 | |
|         for (i = 0; i < reply->numAliases; i++) {
 | |
|             swaps(&aliases[i]);
 | |
|         }
 | |
|         swaps(&reply->sequenceNumber);
 | |
|         swapl(&reply->length);
 | |
|         swapl(&reply->numAliases);
 | |
|         swapl(&reply->numFilters);
 | |
|     }
 | |
|     WriteToClient(client, total_bytes, (char *) reply);
 | |
|     free(reply);
 | |
| 
 | |
|     return Success;
 | |
| }
 | |
| 
 | |
| static int
 | |
| ProcRenderSetPictureFilter(ClientPtr client)
 | |
| {
 | |
|     REQUEST(xRenderSetPictureFilterReq);
 | |
|     PicturePtr pPicture;
 | |
|     int result;
 | |
|     xFixed *params;
 | |
|     int nparams;
 | |
|     char *name;
 | |
| 
 | |
|     REQUEST_AT_LEAST_SIZE(xRenderSetPictureFilterReq);
 | |
|     VERIFY_PICTURE(pPicture, stuff->picture, client, DixSetAttrAccess);
 | |
|     name = (char *) (stuff + 1);
 | |
|     params = (xFixed *) (name + pad_to_int32(stuff->nbytes));
 | |
|     nparams = ((xFixed *) stuff + client->req_len) - params;
 | |
|     result = SetPictureFilter(pPicture, name, stuff->nbytes, params, nparams);
 | |
|     return result;
 | |
| }
 | |
| 
 | |
| static int
 | |
| ProcRenderCreateAnimCursor(ClientPtr client)
 | |
| {
 | |
|     REQUEST(xRenderCreateAnimCursorReq);
 | |
|     CursorPtr *cursors;
 | |
|     CARD32 *deltas;
 | |
|     CursorPtr pCursor;
 | |
|     int ncursor;
 | |
|     xAnimCursorElt *elt;
 | |
|     int i;
 | |
|     int ret;
 | |
| 
 | |
|     REQUEST_AT_LEAST_SIZE(xRenderCreateAnimCursorReq);
 | |
|     LEGAL_NEW_RESOURCE(stuff->cid, client);
 | |
|     if (client->req_len & 1)
 | |
|         return BadLength;
 | |
|     ncursor =
 | |
|         (client->req_len -
 | |
|          (bytes_to_int32(sizeof(xRenderCreateAnimCursorReq)))) >> 1;
 | |
|     cursors = malloc(ncursor * (sizeof(CursorPtr) + sizeof(CARD32)));
 | |
|     if (!cursors)
 | |
|         return BadAlloc;
 | |
|     deltas = (CARD32 *) (cursors + ncursor);
 | |
|     elt = (xAnimCursorElt *) (stuff + 1);
 | |
|     for (i = 0; i < ncursor; i++) {
 | |
|         ret = dixLookupResourceByType((pointer *) (cursors + i), elt->cursor,
 | |
|                                       RT_CURSOR, client, DixReadAccess);
 | |
|         if (ret != Success) {
 | |
|             free(cursors);
 | |
|             return ret;
 | |
|         }
 | |
|         deltas[i] = elt->delay;
 | |
|         elt++;
 | |
|     }
 | |
|     ret = AnimCursorCreate(cursors, deltas, ncursor, &pCursor, client,
 | |
|                            stuff->cid);
 | |
|     free(cursors);
 | |
|     if (ret != Success)
 | |
|         return ret;
 | |
| 
 | |
|     if (AddResource(stuff->cid, RT_CURSOR, (pointer) pCursor))
 | |
|         return Success;
 | |
|     return BadAlloc;
 | |
| }
 | |
| 
 | |
| static int
 | |
| ProcRenderAddTraps(ClientPtr client)
 | |
| {
 | |
|     int ntraps;
 | |
|     PicturePtr pPicture;
 | |
| 
 | |
|     REQUEST(xRenderAddTrapsReq);
 | |
| 
 | |
|     REQUEST_AT_LEAST_SIZE(xRenderAddTrapsReq);
 | |
|     VERIFY_PICTURE(pPicture, stuff->picture, client, DixWriteAccess);
 | |
|     if (!pPicture->pDrawable)
 | |
|         return BadDrawable;
 | |
|     ntraps = (client->req_len << 2) - sizeof(xRenderAddTrapsReq);
 | |
|     if (ntraps % sizeof(xTrap))
 | |
|         return BadLength;
 | |
|     ntraps /= sizeof(xTrap);
 | |
|     if (ntraps)
 | |
|         AddTraps(pPicture,
 | |
|                  stuff->xOff, stuff->yOff, ntraps, (xTrap *) &stuff[1]);
 | |
|     return Success;
 | |
| }
 | |
| 
 | |
| static int
 | |
| ProcRenderCreateSolidFill(ClientPtr client)
 | |
| {
 | |
|     PicturePtr pPicture;
 | |
|     int error = 0;
 | |
| 
 | |
|     REQUEST(xRenderCreateSolidFillReq);
 | |
| 
 | |
|     REQUEST_AT_LEAST_SIZE(xRenderCreateSolidFillReq);
 | |
| 
 | |
|     LEGAL_NEW_RESOURCE(stuff->pid, client);
 | |
| 
 | |
|     pPicture = CreateSolidPicture(stuff->pid, &stuff->color, &error);
 | |
|     if (!pPicture)
 | |
|         return error;
 | |
|     /* security creation/labeling check */
 | |
|     error = XaceHook(XACE_RESOURCE_ACCESS, client, stuff->pid, PictureType,
 | |
|                      pPicture, RT_NONE, NULL, DixCreateAccess);
 | |
|     if (error != Success)
 | |
|         return error;
 | |
|     if (!AddResource(stuff->pid, PictureType, (pointer) pPicture))
 | |
|         return BadAlloc;
 | |
|     return Success;
 | |
| }
 | |
| 
 | |
| static int
 | |
| ProcRenderCreateLinearGradient(ClientPtr client)
 | |
| {
 | |
|     PicturePtr pPicture;
 | |
|     int len;
 | |
|     int error = 0;
 | |
|     xFixed *stops;
 | |
|     xRenderColor *colors;
 | |
| 
 | |
|     REQUEST(xRenderCreateLinearGradientReq);
 | |
| 
 | |
|     REQUEST_AT_LEAST_SIZE(xRenderCreateLinearGradientReq);
 | |
| 
 | |
|     LEGAL_NEW_RESOURCE(stuff->pid, client);
 | |
| 
 | |
|     len = (client->req_len << 2) - sizeof(xRenderCreateLinearGradientReq);
 | |
|     if (stuff->nStops > UINT32_MAX / (sizeof(xFixed) + sizeof(xRenderColor)))
 | |
|         return BadLength;
 | |
|     if (len != stuff->nStops * (sizeof(xFixed) + sizeof(xRenderColor)))
 | |
|         return BadLength;
 | |
| 
 | |
|     stops = (xFixed *) (stuff + 1);
 | |
|     colors = (xRenderColor *) (stops + stuff->nStops);
 | |
| 
 | |
|     pPicture = CreateLinearGradientPicture(stuff->pid, &stuff->p1, &stuff->p2,
 | |
|                                            stuff->nStops, stops, colors,
 | |
|                                            &error);
 | |
|     if (!pPicture)
 | |
|         return error;
 | |
|     /* security creation/labeling check */
 | |
|     error = XaceHook(XACE_RESOURCE_ACCESS, client, stuff->pid, PictureType,
 | |
|                      pPicture, RT_NONE, NULL, DixCreateAccess);
 | |
|     if (error != Success)
 | |
|         return error;
 | |
|     if (!AddResource(stuff->pid, PictureType, (pointer) pPicture))
 | |
|         return BadAlloc;
 | |
|     return Success;
 | |
| }
 | |
| 
 | |
| static int
 | |
| ProcRenderCreateRadialGradient(ClientPtr client)
 | |
| {
 | |
|     PicturePtr pPicture;
 | |
|     int len;
 | |
|     int error = 0;
 | |
|     xFixed *stops;
 | |
|     xRenderColor *colors;
 | |
| 
 | |
|     REQUEST(xRenderCreateRadialGradientReq);
 | |
| 
 | |
|     REQUEST_AT_LEAST_SIZE(xRenderCreateRadialGradientReq);
 | |
| 
 | |
|     LEGAL_NEW_RESOURCE(stuff->pid, client);
 | |
| 
 | |
|     len = (client->req_len << 2) - sizeof(xRenderCreateRadialGradientReq);
 | |
|     if (len != stuff->nStops * (sizeof(xFixed) + sizeof(xRenderColor)))
 | |
|         return BadLength;
 | |
| 
 | |
|     stops = (xFixed *) (stuff + 1);
 | |
|     colors = (xRenderColor *) (stops + stuff->nStops);
 | |
| 
 | |
|     pPicture =
 | |
|         CreateRadialGradientPicture(stuff->pid, &stuff->inner, &stuff->outer,
 | |
|                                     stuff->inner_radius, stuff->outer_radius,
 | |
|                                     stuff->nStops, stops, colors, &error);
 | |
|     if (!pPicture)
 | |
|         return error;
 | |
|     /* security creation/labeling check */
 | |
|     error = XaceHook(XACE_RESOURCE_ACCESS, client, stuff->pid, PictureType,
 | |
|                      pPicture, RT_NONE, NULL, DixCreateAccess);
 | |
|     if (error != Success)
 | |
|         return error;
 | |
|     if (!AddResource(stuff->pid, PictureType, (pointer) pPicture))
 | |
|         return BadAlloc;
 | |
|     return Success;
 | |
| }
 | |
| 
 | |
| static int
 | |
| ProcRenderCreateConicalGradient(ClientPtr client)
 | |
| {
 | |
|     PicturePtr pPicture;
 | |
|     int len;
 | |
|     int error = 0;
 | |
|     xFixed *stops;
 | |
|     xRenderColor *colors;
 | |
| 
 | |
|     REQUEST(xRenderCreateConicalGradientReq);
 | |
| 
 | |
|     REQUEST_AT_LEAST_SIZE(xRenderCreateConicalGradientReq);
 | |
| 
 | |
|     LEGAL_NEW_RESOURCE(stuff->pid, client);
 | |
| 
 | |
|     len = (client->req_len << 2) - sizeof(xRenderCreateConicalGradientReq);
 | |
|     if (len != stuff->nStops * (sizeof(xFixed) + sizeof(xRenderColor)))
 | |
|         return BadLength;
 | |
| 
 | |
|     stops = (xFixed *) (stuff + 1);
 | |
|     colors = (xRenderColor *) (stops + stuff->nStops);
 | |
| 
 | |
|     pPicture =
 | |
|         CreateConicalGradientPicture(stuff->pid, &stuff->center, stuff->angle,
 | |
|                                      stuff->nStops, stops, colors, &error);
 | |
|     if (!pPicture)
 | |
|         return error;
 | |
|     /* security creation/labeling check */
 | |
|     error = XaceHook(XACE_RESOURCE_ACCESS, client, stuff->pid, PictureType,
 | |
|                      pPicture, RT_NONE, NULL, DixCreateAccess);
 | |
|     if (error != Success)
 | |
|         return error;
 | |
|     if (!AddResource(stuff->pid, PictureType, (pointer) pPicture))
 | |
|         return BadAlloc;
 | |
|     return Success;
 | |
| }
 | |
| 
 | |
| static int
 | |
| ProcRenderDispatch(ClientPtr client)
 | |
| {
 | |
|     REQUEST(xReq);
 | |
| 
 | |
|     if (stuff->data < RenderNumberRequests)
 | |
|         return (*ProcRenderVector[stuff->data]) (client);
 | |
|     else
 | |
|         return BadRequest;
 | |
| }
 | |
| 
 | |
| static int
 | |
| SProcRenderQueryVersion(ClientPtr client)
 | |
| {
 | |
|     REQUEST(xRenderQueryVersionReq);
 | |
| 
 | |
|     swaps(&stuff->length);
 | |
|     swapl(&stuff->majorVersion);
 | |
|     swapl(&stuff->minorVersion);
 | |
|     return (*ProcRenderVector[stuff->renderReqType]) (client);
 | |
| }
 | |
| 
 | |
| static int
 | |
| SProcRenderQueryPictFormats(ClientPtr client)
 | |
| {
 | |
|     REQUEST(xRenderQueryPictFormatsReq);
 | |
|     swaps(&stuff->length);
 | |
|     return (*ProcRenderVector[stuff->renderReqType]) (client);
 | |
| }
 | |
| 
 | |
| static int
 | |
| SProcRenderQueryPictIndexValues(ClientPtr client)
 | |
| {
 | |
|     REQUEST(xRenderQueryPictIndexValuesReq);
 | |
|     swaps(&stuff->length);
 | |
|     swapl(&stuff->format);
 | |
|     return (*ProcRenderVector[stuff->renderReqType]) (client);
 | |
| }
 | |
| 
 | |
| static int
 | |
| SProcRenderQueryDithers(ClientPtr client)
 | |
| {
 | |
|     return BadImplementation;
 | |
| }
 | |
| 
 | |
| static int
 | |
| SProcRenderCreatePicture(ClientPtr client)
 | |
| {
 | |
|     REQUEST(xRenderCreatePictureReq);
 | |
|     swaps(&stuff->length);
 | |
|     swapl(&stuff->pid);
 | |
|     swapl(&stuff->drawable);
 | |
|     swapl(&stuff->format);
 | |
|     swapl(&stuff->mask);
 | |
|     SwapRestL(stuff);
 | |
|     return (*ProcRenderVector[stuff->renderReqType]) (client);
 | |
| }
 | |
| 
 | |
| static int
 | |
| SProcRenderChangePicture(ClientPtr client)
 | |
| {
 | |
|     REQUEST(xRenderChangePictureReq);
 | |
|     swaps(&stuff->length);
 | |
|     swapl(&stuff->picture);
 | |
|     swapl(&stuff->mask);
 | |
|     SwapRestL(stuff);
 | |
|     return (*ProcRenderVector[stuff->renderReqType]) (client);
 | |
| }
 | |
| 
 | |
| static int
 | |
| SProcRenderSetPictureClipRectangles(ClientPtr client)
 | |
| {
 | |
|     REQUEST(xRenderSetPictureClipRectanglesReq);
 | |
|     swaps(&stuff->length);
 | |
|     swapl(&stuff->picture);
 | |
|     swaps(&stuff->xOrigin);
 | |
|     swaps(&stuff->yOrigin);
 | |
|     SwapRestS(stuff);
 | |
|     return (*ProcRenderVector[stuff->renderReqType]) (client);
 | |
| }
 | |
| 
 | |
| static int
 | |
| SProcRenderFreePicture(ClientPtr client)
 | |
| {
 | |
|     REQUEST(xRenderFreePictureReq);
 | |
|     swaps(&stuff->length);
 | |
|     swapl(&stuff->picture);
 | |
|     return (*ProcRenderVector[stuff->renderReqType]) (client);
 | |
| }
 | |
| 
 | |
| static int
 | |
| SProcRenderComposite(ClientPtr client)
 | |
| {
 | |
|     REQUEST(xRenderCompositeReq);
 | |
|     swaps(&stuff->length);
 | |
|     swapl(&stuff->src);
 | |
|     swapl(&stuff->mask);
 | |
|     swapl(&stuff->dst);
 | |
|     swaps(&stuff->xSrc);
 | |
|     swaps(&stuff->ySrc);
 | |
|     swaps(&stuff->xMask);
 | |
|     swaps(&stuff->yMask);
 | |
|     swaps(&stuff->xDst);
 | |
|     swaps(&stuff->yDst);
 | |
|     swaps(&stuff->width);
 | |
|     swaps(&stuff->height);
 | |
|     return (*ProcRenderVector[stuff->renderReqType]) (client);
 | |
| }
 | |
| 
 | |
| static int
 | |
| SProcRenderScale(ClientPtr client)
 | |
| {
 | |
|     REQUEST(xRenderScaleReq);
 | |
|     swaps(&stuff->length);
 | |
|     swapl(&stuff->src);
 | |
|     swapl(&stuff->dst);
 | |
|     swapl(&stuff->colorScale);
 | |
|     swapl(&stuff->alphaScale);
 | |
|     swaps(&stuff->xSrc);
 | |
|     swaps(&stuff->ySrc);
 | |
|     swaps(&stuff->xDst);
 | |
|     swaps(&stuff->yDst);
 | |
|     swaps(&stuff->width);
 | |
|     swaps(&stuff->height);
 | |
|     return (*ProcRenderVector[stuff->renderReqType]) (client);
 | |
| }
 | |
| 
 | |
| static int
 | |
| SProcRenderTrapezoids(ClientPtr client)
 | |
| {
 | |
|     REQUEST(xRenderTrapezoidsReq);
 | |
| 
 | |
|     REQUEST_AT_LEAST_SIZE(xRenderTrapezoidsReq);
 | |
|     swaps(&stuff->length);
 | |
|     swapl(&stuff->src);
 | |
|     swapl(&stuff->dst);
 | |
|     swapl(&stuff->maskFormat);
 | |
|     swaps(&stuff->xSrc);
 | |
|     swaps(&stuff->ySrc);
 | |
|     SwapRestL(stuff);
 | |
|     return (*ProcRenderVector[stuff->renderReqType]) (client);
 | |
| }
 | |
| 
 | |
| static int
 | |
| SProcRenderTriangles(ClientPtr client)
 | |
| {
 | |
|     REQUEST(xRenderTrianglesReq);
 | |
| 
 | |
|     REQUEST_AT_LEAST_SIZE(xRenderTrianglesReq);
 | |
|     swaps(&stuff->length);
 | |
|     swapl(&stuff->src);
 | |
|     swapl(&stuff->dst);
 | |
|     swapl(&stuff->maskFormat);
 | |
|     swaps(&stuff->xSrc);
 | |
|     swaps(&stuff->ySrc);
 | |
|     SwapRestL(stuff);
 | |
|     return (*ProcRenderVector[stuff->renderReqType]) (client);
 | |
| }
 | |
| 
 | |
| static int
 | |
| SProcRenderTriStrip(ClientPtr client)
 | |
| {
 | |
|     REQUEST(xRenderTriStripReq);
 | |
| 
 | |
|     REQUEST_AT_LEAST_SIZE(xRenderTriStripReq);
 | |
|     swaps(&stuff->length);
 | |
|     swapl(&stuff->src);
 | |
|     swapl(&stuff->dst);
 | |
|     swapl(&stuff->maskFormat);
 | |
|     swaps(&stuff->xSrc);
 | |
|     swaps(&stuff->ySrc);
 | |
|     SwapRestL(stuff);
 | |
|     return (*ProcRenderVector[stuff->renderReqType]) (client);
 | |
| }
 | |
| 
 | |
| static int
 | |
| SProcRenderTriFan(ClientPtr client)
 | |
| {
 | |
|     REQUEST(xRenderTriFanReq);
 | |
| 
 | |
|     REQUEST_AT_LEAST_SIZE(xRenderTriFanReq);
 | |
|     swaps(&stuff->length);
 | |
|     swapl(&stuff->src);
 | |
|     swapl(&stuff->dst);
 | |
|     swapl(&stuff->maskFormat);
 | |
|     swaps(&stuff->xSrc);
 | |
|     swaps(&stuff->ySrc);
 | |
|     SwapRestL(stuff);
 | |
|     return (*ProcRenderVector[stuff->renderReqType]) (client);
 | |
| }
 | |
| 
 | |
| static int
 | |
| SProcRenderColorTrapezoids(ClientPtr client)
 | |
| {
 | |
|     return BadImplementation;
 | |
| }
 | |
| 
 | |
| static int
 | |
| SProcRenderColorTriangles(ClientPtr client)
 | |
| {
 | |
|     return BadImplementation;
 | |
| }
 | |
| 
 | |
| static int
 | |
| SProcRenderTransform(ClientPtr client)
 | |
| {
 | |
|     return BadImplementation;
 | |
| }
 | |
| 
 | |
| static int
 | |
| SProcRenderCreateGlyphSet(ClientPtr client)
 | |
| {
 | |
|     REQUEST(xRenderCreateGlyphSetReq);
 | |
|     swaps(&stuff->length);
 | |
|     swapl(&stuff->gsid);
 | |
|     swapl(&stuff->format);
 | |
|     return (*ProcRenderVector[stuff->renderReqType]) (client);
 | |
| }
 | |
| 
 | |
| static int
 | |
| SProcRenderReferenceGlyphSet(ClientPtr client)
 | |
| {
 | |
|     REQUEST(xRenderReferenceGlyphSetReq);
 | |
|     swaps(&stuff->length);
 | |
|     swapl(&stuff->gsid);
 | |
|     swapl(&stuff->existing);
 | |
|     return (*ProcRenderVector[stuff->renderReqType]) (client);
 | |
| }
 | |
| 
 | |
| static int
 | |
| SProcRenderFreeGlyphSet(ClientPtr client)
 | |
| {
 | |
|     REQUEST(xRenderFreeGlyphSetReq);
 | |
|     swaps(&stuff->length);
 | |
|     swapl(&stuff->glyphset);
 | |
|     return (*ProcRenderVector[stuff->renderReqType]) (client);
 | |
| }
 | |
| 
 | |
| static int
 | |
| SProcRenderAddGlyphs(ClientPtr client)
 | |
| {
 | |
|     register int i;
 | |
|     CARD32 *gids;
 | |
|     void *end;
 | |
|     xGlyphInfo *gi;
 | |
| 
 | |
|     REQUEST(xRenderAddGlyphsReq);
 | |
|     swaps(&stuff->length);
 | |
|     swapl(&stuff->glyphset);
 | |
|     swapl(&stuff->nglyphs);
 | |
|     if (stuff->nglyphs & 0xe0000000)
 | |
|         return BadLength;
 | |
|     end = (CARD8 *) stuff + (client->req_len << 2);
 | |
|     gids = (CARD32 *) (stuff + 1);
 | |
|     gi = (xGlyphInfo *) (gids + stuff->nglyphs);
 | |
|     if ((char *) end - (char *) (gids + stuff->nglyphs) < 0)
 | |
|         return BadLength;
 | |
|     if ((char *) end - (char *) (gi + stuff->nglyphs) < 0)
 | |
|         return BadLength;
 | |
|     for (i = 0; i < stuff->nglyphs; i++) {
 | |
|         swapl(&gids[i]);
 | |
|         swaps(&gi[i].width);
 | |
|         swaps(&gi[i].height);
 | |
|         swaps(&gi[i].x);
 | |
|         swaps(&gi[i].y);
 | |
|         swaps(&gi[i].xOff);
 | |
|         swaps(&gi[i].yOff);
 | |
|     }
 | |
|     return (*ProcRenderVector[stuff->renderReqType]) (client);
 | |
| }
 | |
| 
 | |
| static int
 | |
| SProcRenderAddGlyphsFromPicture(ClientPtr client)
 | |
| {
 | |
|     return BadImplementation;
 | |
| }
 | |
| 
 | |
| static int
 | |
| SProcRenderFreeGlyphs(ClientPtr client)
 | |
| {
 | |
|     REQUEST(xRenderFreeGlyphsReq);
 | |
|     swaps(&stuff->length);
 | |
|     swapl(&stuff->glyphset);
 | |
|     SwapRestL(stuff);
 | |
|     return (*ProcRenderVector[stuff->renderReqType]) (client);
 | |
| }
 | |
| 
 | |
| static int
 | |
| SProcRenderCompositeGlyphs(ClientPtr client)
 | |
| {
 | |
|     xGlyphElt *elt;
 | |
|     CARD8 *buffer;
 | |
|     CARD8 *end;
 | |
|     int space;
 | |
|     int i;
 | |
|     int size;
 | |
| 
 | |
|     REQUEST(xRenderCompositeGlyphsReq);
 | |
| 
 | |
|     switch (stuff->renderReqType) {
 | |
|     default:
 | |
|         size = 1;
 | |
|         break;
 | |
|     case X_RenderCompositeGlyphs16:
 | |
|         size = 2;
 | |
|         break;
 | |
|     case X_RenderCompositeGlyphs32:
 | |
|         size = 4;
 | |
|         break;
 | |
|     }
 | |
| 
 | |
|     swaps(&stuff->length);
 | |
|     swapl(&stuff->src);
 | |
|     swapl(&stuff->dst);
 | |
|     swapl(&stuff->maskFormat);
 | |
|     swapl(&stuff->glyphset);
 | |
|     swaps(&stuff->xSrc);
 | |
|     swaps(&stuff->ySrc);
 | |
|     buffer = (CARD8 *) (stuff + 1);
 | |
|     end = (CARD8 *) stuff + (client->req_len << 2);
 | |
|     while (buffer + sizeof(xGlyphElt) < end) {
 | |
|         elt = (xGlyphElt *) buffer;
 | |
|         buffer += sizeof(xGlyphElt);
 | |
| 
 | |
|         swaps(&elt->deltax);
 | |
|         swaps(&elt->deltay);
 | |
| 
 | |
|         i = elt->len;
 | |
|         if (i == 0xff) {
 | |
|             swapl((int *) buffer);
 | |
|             buffer += 4;
 | |
|         }
 | |
|         else {
 | |
|             space = size * i;
 | |
|             switch (size) {
 | |
|             case 1:
 | |
|                 buffer += i;
 | |
|                 break;
 | |
|             case 2:
 | |
|                 while (i--) {
 | |
|                     swaps((short *) buffer);
 | |
|                     buffer += 2;
 | |
|                 }
 | |
|                 break;
 | |
|             case 4:
 | |
|                 while (i--) {
 | |
|                     swapl((int *) buffer);
 | |
|                     buffer += 4;
 | |
|                 }
 | |
|                 break;
 | |
|             }
 | |
|             if (space & 3)
 | |
|                 buffer += 4 - (space & 3);
 | |
|         }
 | |
|     }
 | |
|     return (*ProcRenderVector[stuff->renderReqType]) (client);
 | |
| }
 | |
| 
 | |
| static int
 | |
| SProcRenderFillRectangles(ClientPtr client)
 | |
| {
 | |
|     REQUEST(xRenderFillRectanglesReq);
 | |
| 
 | |
|     REQUEST_AT_LEAST_SIZE(xRenderFillRectanglesReq);
 | |
|     swaps(&stuff->length);
 | |
|     swapl(&stuff->dst);
 | |
|     swaps(&stuff->color.red);
 | |
|     swaps(&stuff->color.green);
 | |
|     swaps(&stuff->color.blue);
 | |
|     swaps(&stuff->color.alpha);
 | |
|     SwapRestS(stuff);
 | |
|     return (*ProcRenderVector[stuff->renderReqType]) (client);
 | |
| }
 | |
| 
 | |
| static int
 | |
| SProcRenderCreateCursor(ClientPtr client)
 | |
| {
 | |
|     REQUEST(xRenderCreateCursorReq);
 | |
|     REQUEST_SIZE_MATCH(xRenderCreateCursorReq);
 | |
| 
 | |
|     swaps(&stuff->length);
 | |
|     swapl(&stuff->cid);
 | |
|     swapl(&stuff->src);
 | |
|     swaps(&stuff->x);
 | |
|     swaps(&stuff->y);
 | |
|     return (*ProcRenderVector[stuff->renderReqType]) (client);
 | |
| }
 | |
| 
 | |
| static int
 | |
| SProcRenderSetPictureTransform(ClientPtr client)
 | |
| {
 | |
|     REQUEST(xRenderSetPictureTransformReq);
 | |
|     REQUEST_SIZE_MATCH(xRenderSetPictureTransformReq);
 | |
| 
 | |
|     swaps(&stuff->length);
 | |
|     swapl(&stuff->picture);
 | |
|     swapl(&stuff->transform.matrix11);
 | |
|     swapl(&stuff->transform.matrix12);
 | |
|     swapl(&stuff->transform.matrix13);
 | |
|     swapl(&stuff->transform.matrix21);
 | |
|     swapl(&stuff->transform.matrix22);
 | |
|     swapl(&stuff->transform.matrix23);
 | |
|     swapl(&stuff->transform.matrix31);
 | |
|     swapl(&stuff->transform.matrix32);
 | |
|     swapl(&stuff->transform.matrix33);
 | |
|     return (*ProcRenderVector[stuff->renderReqType]) (client);
 | |
| }
 | |
| 
 | |
| static int
 | |
| SProcRenderQueryFilters(ClientPtr client)
 | |
| {
 | |
|     REQUEST(xRenderQueryFiltersReq);
 | |
|     REQUEST_SIZE_MATCH(xRenderQueryFiltersReq);
 | |
| 
 | |
|     swaps(&stuff->length);
 | |
|     swapl(&stuff->drawable);
 | |
|     return (*ProcRenderVector[stuff->renderReqType]) (client);
 | |
| }
 | |
| 
 | |
| static int
 | |
| SProcRenderSetPictureFilter(ClientPtr client)
 | |
| {
 | |
|     REQUEST(xRenderSetPictureFilterReq);
 | |
|     REQUEST_AT_LEAST_SIZE(xRenderSetPictureFilterReq);
 | |
| 
 | |
|     swaps(&stuff->length);
 | |
|     swapl(&stuff->picture);
 | |
|     swaps(&stuff->nbytes);
 | |
|     return (*ProcRenderVector[stuff->renderReqType]) (client);
 | |
| }
 | |
| 
 | |
| static int
 | |
| SProcRenderCreateAnimCursor(ClientPtr client)
 | |
| {
 | |
|     REQUEST(xRenderCreateAnimCursorReq);
 | |
|     REQUEST_AT_LEAST_SIZE(xRenderCreateAnimCursorReq);
 | |
| 
 | |
|     swaps(&stuff->length);
 | |
|     swapl(&stuff->cid);
 | |
|     SwapRestL(stuff);
 | |
|     return (*ProcRenderVector[stuff->renderReqType]) (client);
 | |
| }
 | |
| 
 | |
| static int
 | |
| SProcRenderAddTraps(ClientPtr client)
 | |
| {
 | |
|     REQUEST(xRenderAddTrapsReq);
 | |
|     REQUEST_AT_LEAST_SIZE(xRenderAddTrapsReq);
 | |
| 
 | |
|     swaps(&stuff->length);
 | |
|     swapl(&stuff->picture);
 | |
|     swaps(&stuff->xOff);
 | |
|     swaps(&stuff->yOff);
 | |
|     SwapRestL(stuff);
 | |
|     return (*ProcRenderVector[stuff->renderReqType]) (client);
 | |
| }
 | |
| 
 | |
| static int
 | |
| SProcRenderCreateSolidFill(ClientPtr client)
 | |
| {
 | |
|     REQUEST(xRenderCreateSolidFillReq);
 | |
|     REQUEST_AT_LEAST_SIZE(xRenderCreateSolidFillReq);
 | |
| 
 | |
|     swaps(&stuff->length);
 | |
|     swapl(&stuff->pid);
 | |
|     swaps(&stuff->color.alpha);
 | |
|     swaps(&stuff->color.red);
 | |
|     swaps(&stuff->color.green);
 | |
|     swaps(&stuff->color.blue);
 | |
|     return (*ProcRenderVector[stuff->renderReqType]) (client);
 | |
| }
 | |
| 
 | |
| static void
 | |
| swapStops(void *stuff, int num)
 | |
| {
 | |
|     int i;
 | |
|     CARD32 *stops;
 | |
|     CARD16 *colors;
 | |
| 
 | |
|     stops = (CARD32 *) (stuff);
 | |
|     for (i = 0; i < num; ++i) {
 | |
|         swapl(stops);
 | |
|         ++stops;
 | |
|     }
 | |
|     colors = (CARD16 *) (stops);
 | |
|     for (i = 0; i < 4 * num; ++i) {
 | |
|         swaps(colors);
 | |
|         ++colors;
 | |
|     }
 | |
| }
 | |
| 
 | |
| static int
 | |
| SProcRenderCreateLinearGradient(ClientPtr client)
 | |
| {
 | |
|     int len;
 | |
| 
 | |
|     REQUEST(xRenderCreateLinearGradientReq);
 | |
|     REQUEST_AT_LEAST_SIZE(xRenderCreateLinearGradientReq);
 | |
| 
 | |
|     swaps(&stuff->length);
 | |
|     swapl(&stuff->pid);
 | |
|     swapl(&stuff->p1.x);
 | |
|     swapl(&stuff->p1.y);
 | |
|     swapl(&stuff->p2.x);
 | |
|     swapl(&stuff->p2.y);
 | |
|     swapl(&stuff->nStops);
 | |
| 
 | |
|     len = (client->req_len << 2) - sizeof(xRenderCreateLinearGradientReq);
 | |
|     if (stuff->nStops > UINT32_MAX / (sizeof(xFixed) + sizeof(xRenderColor)))
 | |
|         return BadLength;
 | |
|     if (len != stuff->nStops * (sizeof(xFixed) + sizeof(xRenderColor)))
 | |
|         return BadLength;
 | |
| 
 | |
|     swapStops(stuff + 1, stuff->nStops);
 | |
| 
 | |
|     return (*ProcRenderVector[stuff->renderReqType]) (client);
 | |
| }
 | |
| 
 | |
| static int
 | |
| SProcRenderCreateRadialGradient(ClientPtr client)
 | |
| {
 | |
|     int len;
 | |
| 
 | |
|     REQUEST(xRenderCreateRadialGradientReq);
 | |
|     REQUEST_AT_LEAST_SIZE(xRenderCreateRadialGradientReq);
 | |
| 
 | |
|     swaps(&stuff->length);
 | |
|     swapl(&stuff->pid);
 | |
|     swapl(&stuff->inner.x);
 | |
|     swapl(&stuff->inner.y);
 | |
|     swapl(&stuff->outer.x);
 | |
|     swapl(&stuff->outer.y);
 | |
|     swapl(&stuff->inner_radius);
 | |
|     swapl(&stuff->outer_radius);
 | |
|     swapl(&stuff->nStops);
 | |
| 
 | |
|     len = (client->req_len << 2) - sizeof(xRenderCreateRadialGradientReq);
 | |
|     if (stuff->nStops > UINT32_MAX / (sizeof(xFixed) + sizeof(xRenderColor)))
 | |
|         return BadLength;
 | |
|     if (len != stuff->nStops * (sizeof(xFixed) + sizeof(xRenderColor)))
 | |
|         return BadLength;
 | |
| 
 | |
|     swapStops(stuff + 1, stuff->nStops);
 | |
| 
 | |
|     return (*ProcRenderVector[stuff->renderReqType]) (client);
 | |
| }
 | |
| 
 | |
| static int
 | |
| SProcRenderCreateConicalGradient(ClientPtr client)
 | |
| {
 | |
|     int len;
 | |
| 
 | |
|     REQUEST(xRenderCreateConicalGradientReq);
 | |
|     REQUEST_AT_LEAST_SIZE(xRenderCreateConicalGradientReq);
 | |
| 
 | |
|     swaps(&stuff->length);
 | |
|     swapl(&stuff->pid);
 | |
|     swapl(&stuff->center.x);
 | |
|     swapl(&stuff->center.y);
 | |
|     swapl(&stuff->angle);
 | |
|     swapl(&stuff->nStops);
 | |
| 
 | |
|     len = (client->req_len << 2) - sizeof(xRenderCreateConicalGradientReq);
 | |
|     if (stuff->nStops > UINT32_MAX / (sizeof(xFixed) + sizeof(xRenderColor)))
 | |
|         return BadLength;
 | |
|     if (len != stuff->nStops * (sizeof(xFixed) + sizeof(xRenderColor)))
 | |
|         return BadLength;
 | |
| 
 | |
|     swapStops(stuff + 1, stuff->nStops);
 | |
| 
 | |
|     return (*ProcRenderVector[stuff->renderReqType]) (client);
 | |
| }
 | |
| 
 | |
| static int
 | |
| SProcRenderDispatch(ClientPtr client)
 | |
| {
 | |
|     REQUEST(xReq);
 | |
| 
 | |
|     if (stuff->data < RenderNumberRequests)
 | |
|         return (*SProcRenderVector[stuff->data]) (client);
 | |
|     else
 | |
|         return BadRequest;
 | |
| }
 | |
| 
 | |
| #ifdef PANORAMIX
 | |
| #define VERIFY_XIN_PICTURE(pPicture, pid, client, mode) {\
 | |
|     int rc = dixLookupResourceByType((pointer *)&(pPicture), pid,\
 | |
|                                      XRT_PICTURE, client, mode);\
 | |
|     if (rc != Success)\
 | |
| 	return rc;\
 | |
| }
 | |
| 
 | |
| #define VERIFY_XIN_ALPHA(pPicture, pid, client, mode) {\
 | |
|     if (pid == None) \
 | |
| 	pPicture = 0; \
 | |
|     else { \
 | |
| 	VERIFY_XIN_PICTURE(pPicture, pid, client, mode); \
 | |
|     } \
 | |
| } \
 | |
| 
 | |
| int (*PanoramiXSaveRenderVector[RenderNumberRequests]) (ClientPtr);
 | |
| 
 | |
| static int
 | |
| PanoramiXRenderCreatePicture(ClientPtr client)
 | |
| {
 | |
|     REQUEST(xRenderCreatePictureReq);
 | |
|     PanoramiXRes *refDraw, *newPict;
 | |
|     int result, j;
 | |
| 
 | |
|     REQUEST_AT_LEAST_SIZE(xRenderCreatePictureReq);
 | |
|     result = dixLookupResourceByClass((pointer *) &refDraw, stuff->drawable,
 | |
|                                       XRC_DRAWABLE, client, DixWriteAccess);
 | |
|     if (result != Success)
 | |
|         return (result == BadValue) ? BadDrawable : result;
 | |
|     if (!(newPict = (PanoramiXRes *) malloc(sizeof(PanoramiXRes))))
 | |
|         return BadAlloc;
 | |
|     newPict->type = XRT_PICTURE;
 | |
|     panoramix_setup_ids(newPict, client, stuff->pid);
 | |
| 
 | |
|     if (refDraw->type == XRT_WINDOW &&
 | |
|         stuff->drawable == screenInfo.screens[0]->root->drawable.id) {
 | |
|         newPict->u.pict.root = TRUE;
 | |
|     }
 | |
|     else
 | |
|         newPict->u.pict.root = FALSE;
 | |
| 
 | |
|     FOR_NSCREENS_BACKWARD(j) {
 | |
|         stuff->pid = newPict->info[j].id;
 | |
|         stuff->drawable = refDraw->info[j].id;
 | |
|         result = (*PanoramiXSaveRenderVector[X_RenderCreatePicture]) (client);
 | |
|         if (result != Success)
 | |
|             break;
 | |
|     }
 | |
| 
 | |
|     if (result == Success)
 | |
|         AddResource(newPict->info[0].id, XRT_PICTURE, newPict);
 | |
|     else
 | |
|         free(newPict);
 | |
| 
 | |
|     return result;
 | |
| }
 | |
| 
 | |
| static int
 | |
| PanoramiXRenderChangePicture(ClientPtr client)
 | |
| {
 | |
|     PanoramiXRes *pict;
 | |
|     int result = Success, j;
 | |
| 
 | |
|     REQUEST(xRenderChangePictureReq);
 | |
| 
 | |
|     REQUEST_AT_LEAST_SIZE(xRenderChangePictureReq);
 | |
| 
 | |
|     VERIFY_XIN_PICTURE(pict, stuff->picture, client, DixWriteAccess);
 | |
| 
 | |
|     FOR_NSCREENS_BACKWARD(j) {
 | |
|         stuff->picture = pict->info[j].id;
 | |
|         result = (*PanoramiXSaveRenderVector[X_RenderChangePicture]) (client);
 | |
|         if (result != Success)
 | |
|             break;
 | |
|     }
 | |
| 
 | |
|     return result;
 | |
| }
 | |
| 
 | |
| static int
 | |
| PanoramiXRenderSetPictureClipRectangles(ClientPtr client)
 | |
| {
 | |
|     REQUEST(xRenderSetPictureClipRectanglesReq);
 | |
|     int result = Success, j;
 | |
|     PanoramiXRes *pict;
 | |
| 
 | |
|     REQUEST_AT_LEAST_SIZE(xRenderSetPictureClipRectanglesReq);
 | |
| 
 | |
|     VERIFY_XIN_PICTURE(pict, stuff->picture, client, DixWriteAccess);
 | |
| 
 | |
|     FOR_NSCREENS_BACKWARD(j) {
 | |
|         stuff->picture = pict->info[j].id;
 | |
|         result =
 | |
|             (*PanoramiXSaveRenderVector[X_RenderSetPictureClipRectangles])
 | |
|             (client);
 | |
|         if (result != Success)
 | |
|             break;
 | |
|     }
 | |
| 
 | |
|     return result;
 | |
| }
 | |
| 
 | |
| static int
 | |
| PanoramiXRenderSetPictureTransform(ClientPtr client)
 | |
| {
 | |
|     REQUEST(xRenderSetPictureTransformReq);
 | |
|     int result = Success, j;
 | |
|     PanoramiXRes *pict;
 | |
| 
 | |
|     REQUEST_AT_LEAST_SIZE(xRenderSetPictureTransformReq);
 | |
| 
 | |
|     VERIFY_XIN_PICTURE(pict, stuff->picture, client, DixWriteAccess);
 | |
| 
 | |
|     FOR_NSCREENS_BACKWARD(j) {
 | |
|         stuff->picture = pict->info[j].id;
 | |
|         result =
 | |
|             (*PanoramiXSaveRenderVector[X_RenderSetPictureTransform]) (client);
 | |
|         if (result != Success)
 | |
|             break;
 | |
|     }
 | |
| 
 | |
|     return result;
 | |
| }
 | |
| 
 | |
| static int
 | |
| PanoramiXRenderSetPictureFilter(ClientPtr client)
 | |
| {
 | |
|     REQUEST(xRenderSetPictureFilterReq);
 | |
|     int result = Success, j;
 | |
|     PanoramiXRes *pict;
 | |
| 
 | |
|     REQUEST_AT_LEAST_SIZE(xRenderSetPictureFilterReq);
 | |
| 
 | |
|     VERIFY_XIN_PICTURE(pict, stuff->picture, client, DixWriteAccess);
 | |
| 
 | |
|     FOR_NSCREENS_BACKWARD(j) {
 | |
|         stuff->picture = pict->info[j].id;
 | |
|         result =
 | |
|             (*PanoramiXSaveRenderVector[X_RenderSetPictureFilter]) (client);
 | |
|         if (result != Success)
 | |
|             break;
 | |
|     }
 | |
| 
 | |
|     return result;
 | |
| }
 | |
| 
 | |
| static int
 | |
| PanoramiXRenderFreePicture(ClientPtr client)
 | |
| {
 | |
|     PanoramiXRes *pict;
 | |
|     int result = Success, j;
 | |
| 
 | |
|     REQUEST(xRenderFreePictureReq);
 | |
| 
 | |
|     REQUEST_SIZE_MATCH(xRenderFreePictureReq);
 | |
| 
 | |
|     client->errorValue = stuff->picture;
 | |
| 
 | |
|     VERIFY_XIN_PICTURE(pict, stuff->picture, client, DixDestroyAccess);
 | |
| 
 | |
|     FOR_NSCREENS_BACKWARD(j) {
 | |
|         stuff->picture = pict->info[j].id;
 | |
|         result = (*PanoramiXSaveRenderVector[X_RenderFreePicture]) (client);
 | |
|         if (result != Success)
 | |
|             break;
 | |
|     }
 | |
| 
 | |
|     /* Since ProcRenderFreePicture is using FreeResource, it will free
 | |
|        our resource for us on the last pass through the loop above */
 | |
| 
 | |
|     return result;
 | |
| }
 | |
| 
 | |
| static int
 | |
| PanoramiXRenderComposite(ClientPtr client)
 | |
| {
 | |
|     PanoramiXRes *src, *msk, *dst;
 | |
|     int result = Success, j;
 | |
|     xRenderCompositeReq orig;
 | |
| 
 | |
|     REQUEST(xRenderCompositeReq);
 | |
| 
 | |
|     REQUEST_SIZE_MATCH(xRenderCompositeReq);
 | |
| 
 | |
|     VERIFY_XIN_PICTURE(src, stuff->src, client, DixReadAccess);
 | |
|     VERIFY_XIN_ALPHA(msk, stuff->mask, client, DixReadAccess);
 | |
|     VERIFY_XIN_PICTURE(dst, stuff->dst, client, DixWriteAccess);
 | |
| 
 | |
|     orig = *stuff;
 | |
| 
 | |
|     FOR_NSCREENS_FORWARD(j) {
 | |
|         stuff->src = src->info[j].id;
 | |
|         if (src->u.pict.root) {
 | |
|             stuff->xSrc = orig.xSrc - screenInfo.screens[j]->x;
 | |
|             stuff->ySrc = orig.ySrc - screenInfo.screens[j]->y;
 | |
|         }
 | |
|         stuff->dst = dst->info[j].id;
 | |
|         if (dst->u.pict.root) {
 | |
|             stuff->xDst = orig.xDst - screenInfo.screens[j]->x;
 | |
|             stuff->yDst = orig.yDst - screenInfo.screens[j]->y;
 | |
|         }
 | |
|         if (msk) {
 | |
|             stuff->mask = msk->info[j].id;
 | |
|             if (msk->u.pict.root) {
 | |
|                 stuff->xMask = orig.xMask - screenInfo.screens[j]->x;
 | |
|                 stuff->yMask = orig.yMask - screenInfo.screens[j]->y;
 | |
|             }
 | |
|         }
 | |
|         result = (*PanoramiXSaveRenderVector[X_RenderComposite]) (client);
 | |
|         if (result != Success)
 | |
|             break;
 | |
|     }
 | |
| 
 | |
|     return result;
 | |
| }
 | |
| 
 | |
| static int
 | |
| PanoramiXRenderCompositeGlyphs(ClientPtr client)
 | |
| {
 | |
|     PanoramiXRes *src, *dst;
 | |
|     int result = Success, j;
 | |
| 
 | |
|     REQUEST(xRenderCompositeGlyphsReq);
 | |
|     xGlyphElt origElt, *elt;
 | |
|     INT16 xSrc, ySrc;
 | |
| 
 | |
|     REQUEST_AT_LEAST_SIZE(xRenderCompositeGlyphsReq);
 | |
|     VERIFY_XIN_PICTURE(src, stuff->src, client, DixReadAccess);
 | |
|     VERIFY_XIN_PICTURE(dst, stuff->dst, client, DixWriteAccess);
 | |
| 
 | |
|     if (client->req_len << 2 >= (sizeof(xRenderCompositeGlyphsReq) +
 | |
|                                  sizeof(xGlyphElt))) {
 | |
|         elt = (xGlyphElt *) (stuff + 1);
 | |
|         origElt = *elt;
 | |
|         xSrc = stuff->xSrc;
 | |
|         ySrc = stuff->ySrc;
 | |
|         FOR_NSCREENS_FORWARD(j) {
 | |
|             stuff->src = src->info[j].id;
 | |
|             if (src->u.pict.root) {
 | |
|                 stuff->xSrc = xSrc - screenInfo.screens[j]->x;
 | |
|                 stuff->ySrc = ySrc - screenInfo.screens[j]->y;
 | |
|             }
 | |
|             stuff->dst = dst->info[j].id;
 | |
|             if (dst->u.pict.root) {
 | |
|                 elt->deltax = origElt.deltax - screenInfo.screens[j]->x;
 | |
|                 elt->deltay = origElt.deltay - screenInfo.screens[j]->y;
 | |
|             }
 | |
|             result =
 | |
|                 (*PanoramiXSaveRenderVector[stuff->renderReqType]) (client);
 | |
|             if (result != Success)
 | |
|                 break;
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     return result;
 | |
| }
 | |
| 
 | |
| static int
 | |
| PanoramiXRenderFillRectangles(ClientPtr client)
 | |
| {
 | |
|     PanoramiXRes *dst;
 | |
|     int result = Success, j;
 | |
| 
 | |
|     REQUEST(xRenderFillRectanglesReq);
 | |
|     char *extra;
 | |
|     int extra_len;
 | |
| 
 | |
|     REQUEST_AT_LEAST_SIZE(xRenderFillRectanglesReq);
 | |
|     VERIFY_XIN_PICTURE(dst, stuff->dst, client, DixWriteAccess);
 | |
|     extra_len = (client->req_len << 2) - sizeof(xRenderFillRectanglesReq);
 | |
|     if (extra_len && (extra = (char *) malloc(extra_len))) {
 | |
|         memcpy(extra, stuff + 1, extra_len);
 | |
|         FOR_NSCREENS_FORWARD(j) {
 | |
|             if (j)
 | |
|                 memcpy(stuff + 1, extra, extra_len);
 | |
|             if (dst->u.pict.root) {
 | |
|                 int x_off = screenInfo.screens[j]->x;
 | |
|                 int y_off = screenInfo.screens[j]->y;
 | |
| 
 | |
|                 if (x_off || y_off) {
 | |
|                     xRectangle *rects = (xRectangle *) (stuff + 1);
 | |
|                     int i = extra_len / sizeof(xRectangle);
 | |
| 
 | |
|                     while (i--) {
 | |
|                         rects->x -= x_off;
 | |
|                         rects->y -= y_off;
 | |
|                         rects++;
 | |
|                     }
 | |
|                 }
 | |
|             }
 | |
|             stuff->dst = dst->info[j].id;
 | |
|             result =
 | |
|                 (*PanoramiXSaveRenderVector[X_RenderFillRectangles]) (client);
 | |
|             if (result != Success)
 | |
|                 break;
 | |
|         }
 | |
|         free(extra);
 | |
|     }
 | |
| 
 | |
|     return result;
 | |
| }
 | |
| 
 | |
| static int
 | |
| PanoramiXRenderTrapezoids(ClientPtr client)
 | |
| {
 | |
|     PanoramiXRes *src, *dst;
 | |
|     int result = Success, j;
 | |
| 
 | |
|     REQUEST(xRenderTrapezoidsReq);
 | |
|     char *extra;
 | |
|     int extra_len;
 | |
| 
 | |
|     REQUEST_AT_LEAST_SIZE(xRenderTrapezoidsReq);
 | |
| 
 | |
|     VERIFY_XIN_PICTURE(src, stuff->src, client, DixReadAccess);
 | |
|     VERIFY_XIN_PICTURE(dst, stuff->dst, client, DixWriteAccess);
 | |
| 
 | |
|     extra_len = (client->req_len << 2) - sizeof(xRenderTrapezoidsReq);
 | |
| 
 | |
|     if (extra_len && (extra = (char *) malloc(extra_len))) {
 | |
|         memcpy(extra, stuff + 1, extra_len);
 | |
| 
 | |
|         FOR_NSCREENS_FORWARD(j) {
 | |
|             if (j)
 | |
|                 memcpy(stuff + 1, extra, extra_len);
 | |
|             if (dst->u.pict.root) {
 | |
|                 int x_off = screenInfo.screens[j]->x;
 | |
|                 int y_off = screenInfo.screens[j]->y;
 | |
| 
 | |
|                 if (x_off || y_off) {
 | |
|                     xTrapezoid *trap = (xTrapezoid *) (stuff + 1);
 | |
|                     int i = extra_len / sizeof(xTrapezoid);
 | |
| 
 | |
|                     while (i--) {
 | |
|                         trap->top -= y_off;
 | |
|                         trap->bottom -= y_off;
 | |
|                         trap->left.p1.x -= x_off;
 | |
|                         trap->left.p1.y -= y_off;
 | |
|                         trap->left.p2.x -= x_off;
 | |
|                         trap->left.p2.y -= y_off;
 | |
|                         trap->right.p1.x -= x_off;
 | |
|                         trap->right.p1.y -= y_off;
 | |
|                         trap->right.p2.x -= x_off;
 | |
|                         trap->right.p2.y -= y_off;
 | |
|                         trap++;
 | |
|                     }
 | |
|                 }
 | |
|             }
 | |
| 
 | |
|             stuff->src = src->info[j].id;
 | |
|             stuff->dst = dst->info[j].id;
 | |
|             result = (*PanoramiXSaveRenderVector[X_RenderTrapezoids]) (client);
 | |
| 
 | |
|             if (result != Success)
 | |
|                 break;
 | |
|         }
 | |
| 
 | |
|         free(extra);
 | |
|     }
 | |
| 
 | |
|     return result;
 | |
| }
 | |
| 
 | |
| static int
 | |
| PanoramiXRenderTriangles(ClientPtr client)
 | |
| {
 | |
|     PanoramiXRes *src, *dst;
 | |
|     int result = Success, j;
 | |
| 
 | |
|     REQUEST(xRenderTrianglesReq);
 | |
|     char *extra;
 | |
|     int extra_len;
 | |
| 
 | |
|     REQUEST_AT_LEAST_SIZE(xRenderTrianglesReq);
 | |
| 
 | |
|     VERIFY_XIN_PICTURE(src, stuff->src, client, DixReadAccess);
 | |
|     VERIFY_XIN_PICTURE(dst, stuff->dst, client, DixWriteAccess);
 | |
| 
 | |
|     extra_len = (client->req_len << 2) - sizeof(xRenderTrianglesReq);
 | |
| 
 | |
|     if (extra_len && (extra = (char *) malloc(extra_len))) {
 | |
|         memcpy(extra, stuff + 1, extra_len);
 | |
| 
 | |
|         FOR_NSCREENS_FORWARD(j) {
 | |
|             if (j)
 | |
|                 memcpy(stuff + 1, extra, extra_len);
 | |
|             if (dst->u.pict.root) {
 | |
|                 int x_off = screenInfo.screens[j]->x;
 | |
|                 int y_off = screenInfo.screens[j]->y;
 | |
| 
 | |
|                 if (x_off || y_off) {
 | |
|                     xTriangle *tri = (xTriangle *) (stuff + 1);
 | |
|                     int i = extra_len / sizeof(xTriangle);
 | |
| 
 | |
|                     while (i--) {
 | |
|                         tri->p1.x -= x_off;
 | |
|                         tri->p1.y -= y_off;
 | |
|                         tri->p2.x -= x_off;
 | |
|                         tri->p2.y -= y_off;
 | |
|                         tri->p3.x -= x_off;
 | |
|                         tri->p3.y -= y_off;
 | |
|                         tri++;
 | |
|                     }
 | |
|                 }
 | |
|             }
 | |
| 
 | |
|             stuff->src = src->info[j].id;
 | |
|             stuff->dst = dst->info[j].id;
 | |
|             result = (*PanoramiXSaveRenderVector[X_RenderTriangles]) (client);
 | |
| 
 | |
|             if (result != Success)
 | |
|                 break;
 | |
|         }
 | |
| 
 | |
|         free(extra);
 | |
|     }
 | |
| 
 | |
|     return result;
 | |
| }
 | |
| 
 | |
| static int
 | |
| PanoramiXRenderTriStrip(ClientPtr client)
 | |
| {
 | |
|     PanoramiXRes *src, *dst;
 | |
|     int result = Success, j;
 | |
| 
 | |
|     REQUEST(xRenderTriStripReq);
 | |
|     char *extra;
 | |
|     int extra_len;
 | |
| 
 | |
|     REQUEST_AT_LEAST_SIZE(xRenderTriStripReq);
 | |
| 
 | |
|     VERIFY_XIN_PICTURE(src, stuff->src, client, DixReadAccess);
 | |
|     VERIFY_XIN_PICTURE(dst, stuff->dst, client, DixWriteAccess);
 | |
| 
 | |
|     extra_len = (client->req_len << 2) - sizeof(xRenderTriStripReq);
 | |
| 
 | |
|     if (extra_len && (extra = (char *) malloc(extra_len))) {
 | |
|         memcpy(extra, stuff + 1, extra_len);
 | |
| 
 | |
|         FOR_NSCREENS_FORWARD(j) {
 | |
|             if (j)
 | |
|                 memcpy(stuff + 1, extra, extra_len);
 | |
|             if (dst->u.pict.root) {
 | |
|                 int x_off = screenInfo.screens[j]->x;
 | |
|                 int y_off = screenInfo.screens[j]->y;
 | |
| 
 | |
|                 if (x_off || y_off) {
 | |
|                     xPointFixed *fixed = (xPointFixed *) (stuff + 1);
 | |
|                     int i = extra_len / sizeof(xPointFixed);
 | |
| 
 | |
|                     while (i--) {
 | |
|                         fixed->x -= x_off;
 | |
|                         fixed->y -= y_off;
 | |
|                         fixed++;
 | |
|                     }
 | |
|                 }
 | |
|             }
 | |
| 
 | |
|             stuff->src = src->info[j].id;
 | |
|             stuff->dst = dst->info[j].id;
 | |
|             result = (*PanoramiXSaveRenderVector[X_RenderTriStrip]) (client);
 | |
| 
 | |
|             if (result != Success)
 | |
|                 break;
 | |
|         }
 | |
| 
 | |
|         free(extra);
 | |
|     }
 | |
| 
 | |
|     return result;
 | |
| }
 | |
| 
 | |
| static int
 | |
| PanoramiXRenderTriFan(ClientPtr client)
 | |
| {
 | |
|     PanoramiXRes *src, *dst;
 | |
|     int result = Success, j;
 | |
| 
 | |
|     REQUEST(xRenderTriFanReq);
 | |
|     char *extra;
 | |
|     int extra_len;
 | |
| 
 | |
|     REQUEST_AT_LEAST_SIZE(xRenderTriFanReq);
 | |
| 
 | |
|     VERIFY_XIN_PICTURE(src, stuff->src, client, DixReadAccess);
 | |
|     VERIFY_XIN_PICTURE(dst, stuff->dst, client, DixWriteAccess);
 | |
| 
 | |
|     extra_len = (client->req_len << 2) - sizeof(xRenderTriFanReq);
 | |
| 
 | |
|     if (extra_len && (extra = (char *) malloc(extra_len))) {
 | |
|         memcpy(extra, stuff + 1, extra_len);
 | |
| 
 | |
|         FOR_NSCREENS_FORWARD(j) {
 | |
|             if (j)
 | |
|                 memcpy(stuff + 1, extra, extra_len);
 | |
|             if (dst->u.pict.root) {
 | |
|                 int x_off = screenInfo.screens[j]->x;
 | |
|                 int y_off = screenInfo.screens[j]->y;
 | |
| 
 | |
|                 if (x_off || y_off) {
 | |
|                     xPointFixed *fixed = (xPointFixed *) (stuff + 1);
 | |
|                     int i = extra_len / sizeof(xPointFixed);
 | |
| 
 | |
|                     while (i--) {
 | |
|                         fixed->x -= x_off;
 | |
|                         fixed->y -= y_off;
 | |
|                         fixed++;
 | |
|                     }
 | |
|                 }
 | |
|             }
 | |
| 
 | |
|             stuff->src = src->info[j].id;
 | |
|             stuff->dst = dst->info[j].id;
 | |
|             result = (*PanoramiXSaveRenderVector[X_RenderTriFan]) (client);
 | |
| 
 | |
|             if (result != Success)
 | |
|                 break;
 | |
|         }
 | |
| 
 | |
|         free(extra);
 | |
|     }
 | |
| 
 | |
|     return result;
 | |
| }
 | |
| 
 | |
| static int
 | |
| PanoramiXRenderAddTraps(ClientPtr client)
 | |
| {
 | |
|     PanoramiXRes *picture;
 | |
|     int result = Success, j;
 | |
| 
 | |
|     REQUEST(xRenderAddTrapsReq);
 | |
|     char *extra;
 | |
|     int extra_len;
 | |
|     INT16 x_off, y_off;
 | |
| 
 | |
|     REQUEST_AT_LEAST_SIZE(xRenderAddTrapsReq);
 | |
|     VERIFY_XIN_PICTURE(picture, stuff->picture, client, DixWriteAccess);
 | |
|     extra_len = (client->req_len << 2) - sizeof(xRenderAddTrapsReq);
 | |
|     if (extra_len && (extra = (char *) malloc(extra_len))) {
 | |
|         memcpy(extra, stuff + 1, extra_len);
 | |
|         x_off = stuff->xOff;
 | |
|         y_off = stuff->yOff;
 | |
|         FOR_NSCREENS_FORWARD(j) {
 | |
|             if (j)
 | |
|                 memcpy(stuff + 1, extra, extra_len);
 | |
|             stuff->picture = picture->info[j].id;
 | |
| 
 | |
|             if (picture->u.pict.root) {
 | |
|                 stuff->xOff = x_off + screenInfo.screens[j]->x;
 | |
|                 stuff->yOff = y_off + screenInfo.screens[j]->y;
 | |
|             }
 | |
|             result = (*PanoramiXSaveRenderVector[X_RenderAddTraps]) (client);
 | |
|             if (result != Success)
 | |
|                 break;
 | |
|         }
 | |
|         free(extra);
 | |
|     }
 | |
| 
 | |
|     return result;
 | |
| }
 | |
| 
 | |
| static int
 | |
| PanoramiXRenderCreateSolidFill(ClientPtr client)
 | |
| {
 | |
|     REQUEST(xRenderCreateSolidFillReq);
 | |
|     PanoramiXRes *newPict;
 | |
|     int result = Success, j;
 | |
| 
 | |
|     REQUEST_AT_LEAST_SIZE(xRenderCreateSolidFillReq);
 | |
| 
 | |
|     if (!(newPict = (PanoramiXRes *) malloc(sizeof(PanoramiXRes))))
 | |
|         return BadAlloc;
 | |
| 
 | |
|     newPict->type = XRT_PICTURE;
 | |
|     panoramix_setup_ids(newPict, client, stuff->pid);
 | |
|     newPict->u.pict.root = FALSE;
 | |
| 
 | |
|     FOR_NSCREENS_BACKWARD(j) {
 | |
|         stuff->pid = newPict->info[j].id;
 | |
|         result = (*PanoramiXSaveRenderVector[X_RenderCreateSolidFill]) (client);
 | |
|         if (result != Success)
 | |
|             break;
 | |
|     }
 | |
| 
 | |
|     if (result == Success)
 | |
|         AddResource(newPict->info[0].id, XRT_PICTURE, newPict);
 | |
|     else
 | |
|         free(newPict);
 | |
| 
 | |
|     return result;
 | |
| }
 | |
| 
 | |
| static int
 | |
| PanoramiXRenderCreateLinearGradient(ClientPtr client)
 | |
| {
 | |
|     REQUEST(xRenderCreateLinearGradientReq);
 | |
|     PanoramiXRes *newPict;
 | |
|     int result = Success, j;
 | |
| 
 | |
|     REQUEST_AT_LEAST_SIZE(xRenderCreateLinearGradientReq);
 | |
| 
 | |
|     if (!(newPict = (PanoramiXRes *) malloc(sizeof(PanoramiXRes))))
 | |
|         return BadAlloc;
 | |
| 
 | |
|     newPict->type = XRT_PICTURE;
 | |
|     panoramix_setup_ids(newPict, client, stuff->pid);
 | |
|     newPict->u.pict.root = FALSE;
 | |
| 
 | |
|     FOR_NSCREENS_BACKWARD(j) {
 | |
|         stuff->pid = newPict->info[j].id;
 | |
|         result =
 | |
|             (*PanoramiXSaveRenderVector[X_RenderCreateLinearGradient]) (client);
 | |
|         if (result != Success)
 | |
|             break;
 | |
|     }
 | |
| 
 | |
|     if (result == Success)
 | |
|         AddResource(newPict->info[0].id, XRT_PICTURE, newPict);
 | |
|     else
 | |
|         free(newPict);
 | |
| 
 | |
|     return result;
 | |
| }
 | |
| 
 | |
| static int
 | |
| PanoramiXRenderCreateRadialGradient(ClientPtr client)
 | |
| {
 | |
|     REQUEST(xRenderCreateRadialGradientReq);
 | |
|     PanoramiXRes *newPict;
 | |
|     int result = Success, j;
 | |
| 
 | |
|     REQUEST_AT_LEAST_SIZE(xRenderCreateRadialGradientReq);
 | |
| 
 | |
|     if (!(newPict = (PanoramiXRes *) malloc(sizeof(PanoramiXRes))))
 | |
|         return BadAlloc;
 | |
| 
 | |
|     newPict->type = XRT_PICTURE;
 | |
|     panoramix_setup_ids(newPict, client, stuff->pid);
 | |
|     newPict->u.pict.root = FALSE;
 | |
| 
 | |
|     FOR_NSCREENS_BACKWARD(j) {
 | |
|         stuff->pid = newPict->info[j].id;
 | |
|         result =
 | |
|             (*PanoramiXSaveRenderVector[X_RenderCreateRadialGradient]) (client);
 | |
|         if (result != Success)
 | |
|             break;
 | |
|     }
 | |
| 
 | |
|     if (result == Success)
 | |
|         AddResource(newPict->info[0].id, XRT_PICTURE, newPict);
 | |
|     else
 | |
|         free(newPict);
 | |
| 
 | |
|     return result;
 | |
| }
 | |
| 
 | |
| static int
 | |
| PanoramiXRenderCreateConicalGradient(ClientPtr client)
 | |
| {
 | |
|     REQUEST(xRenderCreateConicalGradientReq);
 | |
|     PanoramiXRes *newPict;
 | |
|     int result = Success, j;
 | |
| 
 | |
|     REQUEST_AT_LEAST_SIZE(xRenderCreateConicalGradientReq);
 | |
| 
 | |
|     if (!(newPict = (PanoramiXRes *) malloc(sizeof(PanoramiXRes))))
 | |
|         return BadAlloc;
 | |
| 
 | |
|     newPict->type = XRT_PICTURE;
 | |
|     panoramix_setup_ids(newPict, client, stuff->pid);
 | |
|     newPict->u.pict.root = FALSE;
 | |
| 
 | |
|     FOR_NSCREENS_BACKWARD(j) {
 | |
|         stuff->pid = newPict->info[j].id;
 | |
|         result =
 | |
|             (*PanoramiXSaveRenderVector[X_RenderCreateConicalGradient])
 | |
|             (client);
 | |
|         if (result != Success)
 | |
|             break;
 | |
|     }
 | |
| 
 | |
|     if (result == Success)
 | |
|         AddResource(newPict->info[0].id, XRT_PICTURE, newPict);
 | |
|     else
 | |
|         free(newPict);
 | |
| 
 | |
|     return result;
 | |
| }
 | |
| 
 | |
| void
 | |
| PanoramiXRenderInit(void)
 | |
| {
 | |
|     int i;
 | |
| 
 | |
|     XRT_PICTURE = CreateNewResourceType(XineramaDeleteResource,
 | |
|                                         "XineramaPicture");
 | |
|     if (RenderErrBase)
 | |
|         SetResourceTypeErrorValue(XRT_PICTURE, RenderErrBase + BadPicture);
 | |
|     for (i = 0; i < RenderNumberRequests; i++)
 | |
|         PanoramiXSaveRenderVector[i] = ProcRenderVector[i];
 | |
|     /*
 | |
|      * Stuff in Xinerama aware request processing hooks
 | |
|      */
 | |
|     ProcRenderVector[X_RenderCreatePicture] = PanoramiXRenderCreatePicture;
 | |
|     ProcRenderVector[X_RenderChangePicture] = PanoramiXRenderChangePicture;
 | |
|     ProcRenderVector[X_RenderSetPictureTransform] =
 | |
|         PanoramiXRenderSetPictureTransform;
 | |
|     ProcRenderVector[X_RenderSetPictureFilter] =
 | |
|         PanoramiXRenderSetPictureFilter;
 | |
|     ProcRenderVector[X_RenderSetPictureClipRectangles] =
 | |
|         PanoramiXRenderSetPictureClipRectangles;
 | |
|     ProcRenderVector[X_RenderFreePicture] = PanoramiXRenderFreePicture;
 | |
|     ProcRenderVector[X_RenderComposite] = PanoramiXRenderComposite;
 | |
|     ProcRenderVector[X_RenderCompositeGlyphs8] = PanoramiXRenderCompositeGlyphs;
 | |
|     ProcRenderVector[X_RenderCompositeGlyphs16] =
 | |
|         PanoramiXRenderCompositeGlyphs;
 | |
|     ProcRenderVector[X_RenderCompositeGlyphs32] =
 | |
|         PanoramiXRenderCompositeGlyphs;
 | |
|     ProcRenderVector[X_RenderFillRectangles] = PanoramiXRenderFillRectangles;
 | |
| 
 | |
|     ProcRenderVector[X_RenderTrapezoids] = PanoramiXRenderTrapezoids;
 | |
|     ProcRenderVector[X_RenderTriangles] = PanoramiXRenderTriangles;
 | |
|     ProcRenderVector[X_RenderTriStrip] = PanoramiXRenderTriStrip;
 | |
|     ProcRenderVector[X_RenderTriFan] = PanoramiXRenderTriFan;
 | |
|     ProcRenderVector[X_RenderAddTraps] = PanoramiXRenderAddTraps;
 | |
| 
 | |
|     ProcRenderVector[X_RenderCreateSolidFill] = PanoramiXRenderCreateSolidFill;
 | |
|     ProcRenderVector[X_RenderCreateLinearGradient] =
 | |
|         PanoramiXRenderCreateLinearGradient;
 | |
|     ProcRenderVector[X_RenderCreateRadialGradient] =
 | |
|         PanoramiXRenderCreateRadialGradient;
 | |
|     ProcRenderVector[X_RenderCreateConicalGradient] =
 | |
|         PanoramiXRenderCreateConicalGradient;
 | |
| }
 | |
| 
 | |
| void
 | |
| PanoramiXRenderReset(void)
 | |
| {
 | |
|     int i;
 | |
| 
 | |
|     for (i = 0; i < RenderNumberRequests; i++)
 | |
|         ProcRenderVector[i] = PanoramiXSaveRenderVector[i];
 | |
|     RenderErrBase = 0;
 | |
| }
 | |
| 
 | |
| #endif                          /* PANORAMIX */
 |