render.c revision 706f2543
1706f2543Smrg/*
2706f2543Smrg *
3706f2543Smrg * Copyright © 2000 SuSE, Inc.
4706f2543Smrg *
5706f2543Smrg * Permission to use, copy, modify, distribute, and sell this software and its
6706f2543Smrg * documentation for any purpose is hereby granted without fee, provided that
7706f2543Smrg * the above copyright notice appear in all copies and that both that
8706f2543Smrg * copyright notice and this permission notice appear in supporting
9706f2543Smrg * documentation, and that the name of SuSE not be used in advertising or
10706f2543Smrg * publicity pertaining to distribution of the software without specific,
11706f2543Smrg * written prior permission.  SuSE makes no representations about the
12706f2543Smrg * suitability of this software for any purpose.  It is provided "as is"
13706f2543Smrg * without express or implied warranty.
14706f2543Smrg *
15706f2543Smrg * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
16706f2543Smrg * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
17706f2543Smrg * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
18706f2543Smrg * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
19706f2543Smrg * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
20706f2543Smrg * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
21706f2543Smrg *
22706f2543Smrg * Author:  Keith Packard, SuSE, Inc.
23706f2543Smrg */
24706f2543Smrg
25706f2543Smrg#ifdef HAVE_DIX_CONFIG_H
26706f2543Smrg#include <dix-config.h>
27706f2543Smrg#endif
28706f2543Smrg
29706f2543Smrg#include <X11/X.h>
30706f2543Smrg#include <X11/Xproto.h>
31706f2543Smrg#include "misc.h"
32706f2543Smrg#include "os.h"
33706f2543Smrg#include "dixstruct.h"
34706f2543Smrg#include "resource.h"
35706f2543Smrg#include "scrnintstr.h"
36706f2543Smrg#include "windowstr.h"
37706f2543Smrg#include "pixmapstr.h"
38706f2543Smrg#include "colormapst.h"
39706f2543Smrg#include "extnsionst.h"
40706f2543Smrg#include "servermd.h"
41706f2543Smrg#include <X11/extensions/render.h>
42706f2543Smrg#include <X11/extensions/renderproto.h>
43706f2543Smrg#include "picturestr.h"
44706f2543Smrg#include "glyphstr.h"
45706f2543Smrg#include <X11/Xfuncproto.h>
46706f2543Smrg#include "cursorstr.h"
47706f2543Smrg#include "xace.h"
48706f2543Smrg#include "protocol-versions.h"
49706f2543Smrg
50706f2543Smrg#ifdef PANORAMIX
51706f2543Smrg#include "panoramiX.h"
52706f2543Smrg#include "panoramiXsrv.h"
53706f2543Smrg#endif
54706f2543Smrg
55706f2543Smrg#if HAVE_STDINT_H
56706f2543Smrg#include <stdint.h>
57706f2543Smrg#elif !defined(UINT32_MAX)
58706f2543Smrg#define UINT32_MAX 0xffffffffU
59706f2543Smrg#endif
60706f2543Smrg
61706f2543Smrgstatic int ProcRenderQueryVersion (ClientPtr pClient);
62706f2543Smrgstatic int ProcRenderQueryPictFormats (ClientPtr pClient);
63706f2543Smrgstatic int ProcRenderQueryPictIndexValues (ClientPtr pClient);
64706f2543Smrgstatic int ProcRenderQueryDithers (ClientPtr pClient);
65706f2543Smrgstatic int ProcRenderCreatePicture (ClientPtr pClient);
66706f2543Smrgstatic int ProcRenderChangePicture (ClientPtr pClient);
67706f2543Smrgstatic int ProcRenderSetPictureClipRectangles (ClientPtr pClient);
68706f2543Smrgstatic int ProcRenderFreePicture (ClientPtr pClient);
69706f2543Smrgstatic int ProcRenderComposite (ClientPtr pClient);
70706f2543Smrgstatic int ProcRenderScale (ClientPtr pClient);
71706f2543Smrgstatic int ProcRenderTrapezoids (ClientPtr pClient);
72706f2543Smrgstatic int ProcRenderTriangles (ClientPtr pClient);
73706f2543Smrgstatic int ProcRenderTriStrip (ClientPtr pClient);
74706f2543Smrgstatic int ProcRenderTriFan (ClientPtr pClient);
75706f2543Smrgstatic int ProcRenderColorTrapezoids (ClientPtr pClient);
76706f2543Smrgstatic int ProcRenderColorTriangles (ClientPtr pClient);
77706f2543Smrgstatic int ProcRenderTransform (ClientPtr pClient);
78706f2543Smrgstatic int ProcRenderCreateGlyphSet (ClientPtr pClient);
79706f2543Smrgstatic int ProcRenderReferenceGlyphSet (ClientPtr pClient);
80706f2543Smrgstatic int ProcRenderFreeGlyphSet (ClientPtr pClient);
81706f2543Smrgstatic int ProcRenderAddGlyphs (ClientPtr pClient);
82706f2543Smrgstatic int ProcRenderAddGlyphsFromPicture (ClientPtr pClient);
83706f2543Smrgstatic int ProcRenderFreeGlyphs (ClientPtr pClient);
84706f2543Smrgstatic int ProcRenderCompositeGlyphs (ClientPtr pClient);
85706f2543Smrgstatic int ProcRenderFillRectangles (ClientPtr pClient);
86706f2543Smrgstatic int ProcRenderCreateCursor (ClientPtr pClient);
87706f2543Smrgstatic int ProcRenderSetPictureTransform (ClientPtr pClient);
88706f2543Smrgstatic int ProcRenderQueryFilters (ClientPtr pClient);
89706f2543Smrgstatic int ProcRenderSetPictureFilter (ClientPtr pClient);
90706f2543Smrgstatic int ProcRenderCreateAnimCursor (ClientPtr pClient);
91706f2543Smrgstatic int ProcRenderAddTraps (ClientPtr pClient);
92706f2543Smrgstatic int ProcRenderCreateSolidFill (ClientPtr pClient);
93706f2543Smrgstatic int ProcRenderCreateLinearGradient (ClientPtr pClient);
94706f2543Smrgstatic int ProcRenderCreateRadialGradient (ClientPtr pClient);
95706f2543Smrgstatic int ProcRenderCreateConicalGradient (ClientPtr pClient);
96706f2543Smrg
97706f2543Smrgstatic int ProcRenderDispatch (ClientPtr pClient);
98706f2543Smrg
99706f2543Smrgstatic int SProcRenderQueryVersion (ClientPtr pClient);
100706f2543Smrgstatic int SProcRenderQueryPictFormats (ClientPtr pClient);
101706f2543Smrgstatic int SProcRenderQueryPictIndexValues (ClientPtr pClient);
102706f2543Smrgstatic int SProcRenderQueryDithers (ClientPtr pClient);
103706f2543Smrgstatic int SProcRenderCreatePicture (ClientPtr pClient);
104706f2543Smrgstatic int SProcRenderChangePicture (ClientPtr pClient);
105706f2543Smrgstatic int SProcRenderSetPictureClipRectangles (ClientPtr pClient);
106706f2543Smrgstatic int SProcRenderFreePicture (ClientPtr pClient);
107706f2543Smrgstatic int SProcRenderComposite (ClientPtr pClient);
108706f2543Smrgstatic int SProcRenderScale (ClientPtr pClient);
109706f2543Smrgstatic int SProcRenderTrapezoids (ClientPtr pClient);
110706f2543Smrgstatic int SProcRenderTriangles (ClientPtr pClient);
111706f2543Smrgstatic int SProcRenderTriStrip (ClientPtr pClient);
112706f2543Smrgstatic int SProcRenderTriFan (ClientPtr pClient);
113706f2543Smrgstatic int SProcRenderColorTrapezoids (ClientPtr pClient);
114706f2543Smrgstatic int SProcRenderColorTriangles (ClientPtr pClient);
115706f2543Smrgstatic int SProcRenderTransform (ClientPtr pClient);
116706f2543Smrgstatic int SProcRenderCreateGlyphSet (ClientPtr pClient);
117706f2543Smrgstatic int SProcRenderReferenceGlyphSet (ClientPtr pClient);
118706f2543Smrgstatic int SProcRenderFreeGlyphSet (ClientPtr pClient);
119706f2543Smrgstatic int SProcRenderAddGlyphs (ClientPtr pClient);
120706f2543Smrgstatic int SProcRenderAddGlyphsFromPicture (ClientPtr pClient);
121706f2543Smrgstatic int SProcRenderFreeGlyphs (ClientPtr pClient);
122706f2543Smrgstatic int SProcRenderCompositeGlyphs (ClientPtr pClient);
123706f2543Smrgstatic int SProcRenderFillRectangles (ClientPtr pClient);
124706f2543Smrgstatic int SProcRenderCreateCursor (ClientPtr pClient);
125706f2543Smrgstatic int SProcRenderSetPictureTransform (ClientPtr pClient);
126706f2543Smrgstatic int SProcRenderQueryFilters (ClientPtr pClient);
127706f2543Smrgstatic int SProcRenderSetPictureFilter (ClientPtr pClient);
128706f2543Smrgstatic int SProcRenderCreateAnimCursor (ClientPtr pClient);
129706f2543Smrgstatic int SProcRenderAddTraps (ClientPtr pClient);
130706f2543Smrgstatic int SProcRenderCreateSolidFill (ClientPtr pClient);
131706f2543Smrgstatic int SProcRenderCreateLinearGradient (ClientPtr pClient);
132706f2543Smrgstatic int SProcRenderCreateRadialGradient (ClientPtr pClient);
133706f2543Smrgstatic int SProcRenderCreateConicalGradient (ClientPtr pClient);
134706f2543Smrg
135706f2543Smrgstatic int SProcRenderDispatch (ClientPtr pClient);
136706f2543Smrg
137706f2543Smrgint	(*ProcRenderVector[RenderNumberRequests])(ClientPtr) = {
138706f2543Smrg    ProcRenderQueryVersion,
139706f2543Smrg    ProcRenderQueryPictFormats,
140706f2543Smrg    ProcRenderQueryPictIndexValues,
141706f2543Smrg    ProcRenderQueryDithers,
142706f2543Smrg    ProcRenderCreatePicture,
143706f2543Smrg    ProcRenderChangePicture,
144706f2543Smrg    ProcRenderSetPictureClipRectangles,
145706f2543Smrg    ProcRenderFreePicture,
146706f2543Smrg    ProcRenderComposite,
147706f2543Smrg    ProcRenderScale,
148706f2543Smrg    ProcRenderTrapezoids,
149706f2543Smrg    ProcRenderTriangles,
150706f2543Smrg    ProcRenderTriStrip,
151706f2543Smrg    ProcRenderTriFan,
152706f2543Smrg    ProcRenderColorTrapezoids,
153706f2543Smrg    ProcRenderColorTriangles,
154706f2543Smrg    ProcRenderTransform,
155706f2543Smrg    ProcRenderCreateGlyphSet,
156706f2543Smrg    ProcRenderReferenceGlyphSet,
157706f2543Smrg    ProcRenderFreeGlyphSet,
158706f2543Smrg    ProcRenderAddGlyphs,
159706f2543Smrg    ProcRenderAddGlyphsFromPicture,
160706f2543Smrg    ProcRenderFreeGlyphs,
161706f2543Smrg    ProcRenderCompositeGlyphs,
162706f2543Smrg    ProcRenderCompositeGlyphs,
163706f2543Smrg    ProcRenderCompositeGlyphs,
164706f2543Smrg    ProcRenderFillRectangles,
165706f2543Smrg    ProcRenderCreateCursor,
166706f2543Smrg    ProcRenderSetPictureTransform,
167706f2543Smrg    ProcRenderQueryFilters,
168706f2543Smrg    ProcRenderSetPictureFilter,
169706f2543Smrg    ProcRenderCreateAnimCursor,
170706f2543Smrg    ProcRenderAddTraps,
171706f2543Smrg    ProcRenderCreateSolidFill,
172706f2543Smrg    ProcRenderCreateLinearGradient,
173706f2543Smrg    ProcRenderCreateRadialGradient,
174706f2543Smrg    ProcRenderCreateConicalGradient
175706f2543Smrg};
176706f2543Smrg
177706f2543Smrgint	(*SProcRenderVector[RenderNumberRequests])(ClientPtr) = {
178706f2543Smrg    SProcRenderQueryVersion,
179706f2543Smrg    SProcRenderQueryPictFormats,
180706f2543Smrg    SProcRenderQueryPictIndexValues,
181706f2543Smrg    SProcRenderQueryDithers,
182706f2543Smrg    SProcRenderCreatePicture,
183706f2543Smrg    SProcRenderChangePicture,
184706f2543Smrg    SProcRenderSetPictureClipRectangles,
185706f2543Smrg    SProcRenderFreePicture,
186706f2543Smrg    SProcRenderComposite,
187706f2543Smrg    SProcRenderScale,
188706f2543Smrg    SProcRenderTrapezoids,
189706f2543Smrg    SProcRenderTriangles,
190706f2543Smrg    SProcRenderTriStrip,
191706f2543Smrg    SProcRenderTriFan,
192706f2543Smrg    SProcRenderColorTrapezoids,
193706f2543Smrg    SProcRenderColorTriangles,
194706f2543Smrg    SProcRenderTransform,
195706f2543Smrg    SProcRenderCreateGlyphSet,
196706f2543Smrg    SProcRenderReferenceGlyphSet,
197706f2543Smrg    SProcRenderFreeGlyphSet,
198706f2543Smrg    SProcRenderAddGlyphs,
199706f2543Smrg    SProcRenderAddGlyphsFromPicture,
200706f2543Smrg    SProcRenderFreeGlyphs,
201706f2543Smrg    SProcRenderCompositeGlyphs,
202706f2543Smrg    SProcRenderCompositeGlyphs,
203706f2543Smrg    SProcRenderCompositeGlyphs,
204706f2543Smrg    SProcRenderFillRectangles,
205706f2543Smrg    SProcRenderCreateCursor,
206706f2543Smrg    SProcRenderSetPictureTransform,
207706f2543Smrg    SProcRenderQueryFilters,
208706f2543Smrg    SProcRenderSetPictureFilter,
209706f2543Smrg    SProcRenderCreateAnimCursor,
210706f2543Smrg    SProcRenderAddTraps,
211706f2543Smrg    SProcRenderCreateSolidFill,
212706f2543Smrg    SProcRenderCreateLinearGradient,
213706f2543Smrg    SProcRenderCreateRadialGradient,
214706f2543Smrg    SProcRenderCreateConicalGradient
215706f2543Smrg};
216706f2543Smrg
217706f2543Smrgint	RenderErrBase;
218706f2543Smrgstatic DevPrivateKeyRec RenderClientPrivateKeyRec;
219706f2543Smrg#define RenderClientPrivateKey (&RenderClientPrivateKeyRec )
220706f2543Smrg
221706f2543Smrgtypedef struct _RenderClient {
222706f2543Smrg    int	    major_version;
223706f2543Smrg    int	    minor_version;
224706f2543Smrg} RenderClientRec, *RenderClientPtr;
225706f2543Smrg
226706f2543Smrg#define GetRenderClient(pClient) ((RenderClientPtr)dixLookupPrivate(&(pClient)->devPrivates, RenderClientPrivateKey))
227706f2543Smrg
228706f2543Smrgstatic void
229706f2543SmrgRenderClientCallback (CallbackListPtr	*list,
230706f2543Smrg		      pointer		closure,
231706f2543Smrg		      pointer		data)
232706f2543Smrg{
233706f2543Smrg    NewClientInfoRec	*clientinfo = (NewClientInfoRec *) data;
234706f2543Smrg    ClientPtr		pClient = clientinfo->client;
235706f2543Smrg    RenderClientPtr	pRenderClient = GetRenderClient (pClient);
236706f2543Smrg
237706f2543Smrg    pRenderClient->major_version = 0;
238706f2543Smrg    pRenderClient->minor_version = 0;
239706f2543Smrg}
240706f2543Smrg
241706f2543Smrg#ifdef PANORAMIX
242706f2543Smrgunsigned long	XRT_PICTURE;
243706f2543Smrg#endif
244706f2543Smrg
245706f2543Smrgvoid
246706f2543SmrgRenderExtensionInit (void)
247706f2543Smrg{
248706f2543Smrg    ExtensionEntry *extEntry;
249706f2543Smrg
250706f2543Smrg    if (!PictureType)
251706f2543Smrg	return;
252706f2543Smrg    if (!PictureFinishInit ())
253706f2543Smrg	return;
254706f2543Smrg    if (!dixRegisterPrivateKey(&RenderClientPrivateKeyRec, PRIVATE_CLIENT, sizeof(RenderClientRec)))
255706f2543Smrg	return;
256706f2543Smrg    if (!AddCallback (&ClientStateCallback, RenderClientCallback, 0))
257706f2543Smrg	return;
258706f2543Smrg
259706f2543Smrg    extEntry = AddExtension (RENDER_NAME, 0, RenderNumberErrors,
260706f2543Smrg			     ProcRenderDispatch, SProcRenderDispatch,
261706f2543Smrg			     NULL, StandardMinorOpcode);
262706f2543Smrg    if (!extEntry)
263706f2543Smrg	return;
264706f2543Smrg    RenderErrBase = extEntry->errorBase;
265706f2543Smrg#ifdef PANORAMIX
266706f2543Smrg    if (XRT_PICTURE)
267706f2543Smrg	SetResourceTypeErrorValue(XRT_PICTURE, RenderErrBase + BadPicture);
268706f2543Smrg#endif
269706f2543Smrg    SetResourceTypeErrorValue(PictureType, RenderErrBase + BadPicture);
270706f2543Smrg    SetResourceTypeErrorValue(PictFormatType, RenderErrBase + BadPictFormat);
271706f2543Smrg    SetResourceTypeErrorValue(GlyphSetType, RenderErrBase + BadGlyphSet);
272706f2543Smrg}
273706f2543Smrg
274706f2543Smrgstatic int
275706f2543SmrgProcRenderQueryVersion (ClientPtr client)
276706f2543Smrg{
277706f2543Smrg    RenderClientPtr pRenderClient = GetRenderClient (client);
278706f2543Smrg    xRenderQueryVersionReply rep;
279706f2543Smrg    register int n;
280706f2543Smrg    REQUEST(xRenderQueryVersionReq);
281706f2543Smrg    REQUEST_SIZE_MATCH(xRenderQueryVersionReq);
282706f2543Smrg
283706f2543Smrg    pRenderClient->major_version = stuff->majorVersion;
284706f2543Smrg    pRenderClient->minor_version = stuff->minorVersion;
285706f2543Smrg
286706f2543Smrg    memset(&rep, 0, sizeof(xRenderQueryVersionReply));
287706f2543Smrg    rep.type = X_Reply;
288706f2543Smrg    rep.length = 0;
289706f2543Smrg    rep.sequenceNumber = client->sequence;
290706f2543Smrg
291706f2543Smrg    if ((stuff->majorVersion * 1000 + stuff->minorVersion) <
292706f2543Smrg        (SERVER_RENDER_MAJOR_VERSION * 1000 + SERVER_RENDER_MINOR_VERSION))
293706f2543Smrg    {
294706f2543Smrg	rep.majorVersion = stuff->majorVersion;
295706f2543Smrg	rep.minorVersion = stuff->minorVersion;
296706f2543Smrg    } else
297706f2543Smrg    {
298706f2543Smrg	rep.majorVersion = SERVER_RENDER_MAJOR_VERSION;
299706f2543Smrg	rep.minorVersion = SERVER_RENDER_MINOR_VERSION;
300706f2543Smrg    }
301706f2543Smrg
302706f2543Smrg    if (client->swapped) {
303706f2543Smrg    	swaps(&rep.sequenceNumber, n);
304706f2543Smrg    	swapl(&rep.length, n);
305706f2543Smrg	swapl(&rep.majorVersion, n);
306706f2543Smrg	swapl(&rep.minorVersion, n);
307706f2543Smrg    }
308706f2543Smrg    WriteToClient(client, sizeof(xRenderQueryVersionReply), (char *)&rep);
309706f2543Smrg    return Success;
310706f2543Smrg}
311706f2543Smrg
312706f2543Smrgstatic VisualPtr
313706f2543SmrgfindVisual (ScreenPtr pScreen, VisualID vid)
314706f2543Smrg{
315706f2543Smrg    VisualPtr	pVisual;
316706f2543Smrg    int		v;
317706f2543Smrg
318706f2543Smrg    for (v = 0; v < pScreen->numVisuals; v++)
319706f2543Smrg    {
320706f2543Smrg	pVisual = pScreen->visuals + v;
321706f2543Smrg	if (pVisual->vid == vid)
322706f2543Smrg	    return pVisual;
323706f2543Smrg    }
324706f2543Smrg    return 0;
325706f2543Smrg}
326706f2543Smrg
327706f2543Smrgstatic int
328706f2543SmrgProcRenderQueryPictFormats (ClientPtr client)
329706f2543Smrg{
330706f2543Smrg    RenderClientPtr		    pRenderClient = GetRenderClient (client);
331706f2543Smrg    xRenderQueryPictFormatsReply    *reply;
332706f2543Smrg    xPictScreen			    *pictScreen;
333706f2543Smrg    xPictDepth			    *pictDepth;
334706f2543Smrg    xPictVisual			    *pictVisual;
335706f2543Smrg    xPictFormInfo		    *pictForm;
336706f2543Smrg    CARD32			    *pictSubpixel;
337706f2543Smrg    ScreenPtr			    pScreen;
338706f2543Smrg    VisualPtr			    pVisual;
339706f2543Smrg    DepthPtr			    pDepth;
340706f2543Smrg    int				    v, d;
341706f2543Smrg    PictureScreenPtr		    ps;
342706f2543Smrg    PictFormatPtr		    pFormat;
343706f2543Smrg    int				    nformat;
344706f2543Smrg    int				    ndepth;
345706f2543Smrg    int				    nvisual;
346706f2543Smrg    int				    rlength;
347706f2543Smrg    int				    s;
348706f2543Smrg    int				    n;
349706f2543Smrg    int				    numScreens;
350706f2543Smrg    int				    numSubpixel;
351706f2543Smrg/*    REQUEST(xRenderQueryPictFormatsReq); */
352706f2543Smrg
353706f2543Smrg    REQUEST_SIZE_MATCH(xRenderQueryPictFormatsReq);
354706f2543Smrg
355706f2543Smrg#ifdef PANORAMIX
356706f2543Smrg    if (noPanoramiXExtension)
357706f2543Smrg	numScreens = screenInfo.numScreens;
358706f2543Smrg    else
359706f2543Smrg        numScreens = ((xConnSetup *)ConnectionInfo)->numRoots;
360706f2543Smrg#else
361706f2543Smrg    numScreens = screenInfo.numScreens;
362706f2543Smrg#endif
363706f2543Smrg    ndepth = nformat = nvisual = 0;
364706f2543Smrg    for (s = 0; s < numScreens; s++)
365706f2543Smrg    {
366706f2543Smrg	pScreen = screenInfo.screens[s];
367706f2543Smrg	for (d = 0; d < pScreen->numDepths; d++)
368706f2543Smrg	{
369706f2543Smrg	    pDepth = pScreen->allowedDepths + d;
370706f2543Smrg	    ++ndepth;
371706f2543Smrg
372706f2543Smrg	    for (v = 0; v < pDepth->numVids; v++)
373706f2543Smrg	    {
374706f2543Smrg		pVisual = findVisual (pScreen, pDepth->vids[v]);
375706f2543Smrg		if (pVisual && PictureMatchVisual (pScreen, pDepth->depth, pVisual))
376706f2543Smrg		    ++nvisual;
377706f2543Smrg	    }
378706f2543Smrg	}
379706f2543Smrg	ps = GetPictureScreenIfSet(pScreen);
380706f2543Smrg	if (ps)
381706f2543Smrg	    nformat += ps->nformats;
382706f2543Smrg    }
383706f2543Smrg    if (pRenderClient->major_version == 0 && pRenderClient->minor_version < 6)
384706f2543Smrg	numSubpixel = 0;
385706f2543Smrg    else
386706f2543Smrg	numSubpixel = numScreens;
387706f2543Smrg
388706f2543Smrg    rlength = (sizeof (xRenderQueryPictFormatsReply) +
389706f2543Smrg	       nformat * sizeof (xPictFormInfo) +
390706f2543Smrg	       numScreens * sizeof (xPictScreen) +
391706f2543Smrg	       ndepth * sizeof (xPictDepth) +
392706f2543Smrg	       nvisual * sizeof (xPictVisual) +
393706f2543Smrg	       numSubpixel * sizeof (CARD32));
394706f2543Smrg    reply = (xRenderQueryPictFormatsReply *) calloc(1, rlength);
395706f2543Smrg    if (!reply)
396706f2543Smrg	return BadAlloc;
397706f2543Smrg    reply->type = X_Reply;
398706f2543Smrg    reply->sequenceNumber = client->sequence;
399706f2543Smrg    reply->length = bytes_to_int32(rlength - sizeof(xGenericReply));
400706f2543Smrg    reply->numFormats = nformat;
401706f2543Smrg    reply->numScreens = numScreens;
402706f2543Smrg    reply->numDepths = ndepth;
403706f2543Smrg    reply->numVisuals = nvisual;
404706f2543Smrg    reply->numSubpixel = numSubpixel;
405706f2543Smrg
406706f2543Smrg    pictForm = (xPictFormInfo *) (reply + 1);
407706f2543Smrg
408706f2543Smrg    for (s = 0; s < numScreens; s++)
409706f2543Smrg    {
410706f2543Smrg	pScreen = screenInfo.screens[s];
411706f2543Smrg	ps = GetPictureScreenIfSet(pScreen);
412706f2543Smrg	if (ps)
413706f2543Smrg	{
414706f2543Smrg	    for (nformat = 0, pFormat = ps->formats;
415706f2543Smrg		 nformat < ps->nformats;
416706f2543Smrg		 nformat++, pFormat++)
417706f2543Smrg	    {
418706f2543Smrg		pictForm->id = pFormat->id;
419706f2543Smrg		pictForm->type = pFormat->type;
420706f2543Smrg		pictForm->depth = pFormat->depth;
421706f2543Smrg		pictForm->direct.red = pFormat->direct.red;
422706f2543Smrg		pictForm->direct.redMask = pFormat->direct.redMask;
423706f2543Smrg		pictForm->direct.green = pFormat->direct.green;
424706f2543Smrg		pictForm->direct.greenMask = pFormat->direct.greenMask;
425706f2543Smrg		pictForm->direct.blue = pFormat->direct.blue;
426706f2543Smrg		pictForm->direct.blueMask = pFormat->direct.blueMask;
427706f2543Smrg		pictForm->direct.alpha = pFormat->direct.alpha;
428706f2543Smrg		pictForm->direct.alphaMask = pFormat->direct.alphaMask;
429706f2543Smrg		if (pFormat->type == PictTypeIndexed && pFormat->index.pColormap)
430706f2543Smrg		    pictForm->colormap = pFormat->index.pColormap->mid;
431706f2543Smrg		else
432706f2543Smrg		    pictForm->colormap = None;
433706f2543Smrg		if (client->swapped)
434706f2543Smrg		{
435706f2543Smrg		    swapl (&pictForm->id, n);
436706f2543Smrg		    swaps (&pictForm->direct.red, n);
437706f2543Smrg		    swaps (&pictForm->direct.redMask, n);
438706f2543Smrg		    swaps (&pictForm->direct.green, n);
439706f2543Smrg		    swaps (&pictForm->direct.greenMask, n);
440706f2543Smrg		    swaps (&pictForm->direct.blue, n);
441706f2543Smrg		    swaps (&pictForm->direct.blueMask, n);
442706f2543Smrg		    swaps (&pictForm->direct.alpha, n);
443706f2543Smrg		    swaps (&pictForm->direct.alphaMask, n);
444706f2543Smrg		    swapl (&pictForm->colormap, n);
445706f2543Smrg		}
446706f2543Smrg		pictForm++;
447706f2543Smrg	    }
448706f2543Smrg	}
449706f2543Smrg    }
450706f2543Smrg
451706f2543Smrg    pictScreen = (xPictScreen *) pictForm;
452706f2543Smrg    for (s = 0; s < numScreens; s++)
453706f2543Smrg    {
454706f2543Smrg	pScreen = screenInfo.screens[s];
455706f2543Smrg	pictDepth = (xPictDepth *) (pictScreen + 1);
456706f2543Smrg	ndepth = 0;
457706f2543Smrg	for (d = 0; d < pScreen->numDepths; d++)
458706f2543Smrg	{
459706f2543Smrg	    pictVisual = (xPictVisual *) (pictDepth + 1);
460706f2543Smrg	    pDepth = pScreen->allowedDepths + d;
461706f2543Smrg
462706f2543Smrg	    nvisual = 0;
463706f2543Smrg	    for (v = 0; v < pDepth->numVids; v++)
464706f2543Smrg	    {
465706f2543Smrg		pVisual = findVisual (pScreen, pDepth->vids[v]);
466706f2543Smrg		if (pVisual && (pFormat = PictureMatchVisual (pScreen,
467706f2543Smrg							      pDepth->depth,
468706f2543Smrg							      pVisual)))
469706f2543Smrg		{
470706f2543Smrg		    pictVisual->visual = pVisual->vid;
471706f2543Smrg		    pictVisual->format = pFormat->id;
472706f2543Smrg		    if (client->swapped)
473706f2543Smrg		    {
474706f2543Smrg			swapl (&pictVisual->visual, n);
475706f2543Smrg			swapl (&pictVisual->format, n);
476706f2543Smrg		    }
477706f2543Smrg		    pictVisual++;
478706f2543Smrg		    nvisual++;
479706f2543Smrg		}
480706f2543Smrg	    }
481706f2543Smrg	    pictDepth->depth = pDepth->depth;
482706f2543Smrg	    pictDepth->nPictVisuals = nvisual;
483706f2543Smrg	    if (client->swapped)
484706f2543Smrg	    {
485706f2543Smrg		swaps (&pictDepth->nPictVisuals, n);
486706f2543Smrg	    }
487706f2543Smrg	    ndepth++;
488706f2543Smrg	    pictDepth = (xPictDepth *) pictVisual;
489706f2543Smrg	}
490706f2543Smrg	pictScreen->nDepth = ndepth;
491706f2543Smrg	ps = GetPictureScreenIfSet(pScreen);
492706f2543Smrg	if (ps)
493706f2543Smrg	    pictScreen->fallback = ps->fallback->id;
494706f2543Smrg	else
495706f2543Smrg	    pictScreen->fallback = 0;
496706f2543Smrg	if (client->swapped)
497706f2543Smrg	{
498706f2543Smrg	    swapl (&pictScreen->nDepth, n);
499706f2543Smrg	    swapl (&pictScreen->fallback, n);
500706f2543Smrg	}
501706f2543Smrg	pictScreen = (xPictScreen *) pictDepth;
502706f2543Smrg    }
503706f2543Smrg    pictSubpixel = (CARD32 *) pictScreen;
504706f2543Smrg
505706f2543Smrg    for (s = 0; s < numSubpixel; s++)
506706f2543Smrg    {
507706f2543Smrg	pScreen = screenInfo.screens[s];
508706f2543Smrg	ps = GetPictureScreenIfSet(pScreen);
509706f2543Smrg	if (ps)
510706f2543Smrg	    *pictSubpixel = ps->subpixel;
511706f2543Smrg	else
512706f2543Smrg	    *pictSubpixel = SubPixelUnknown;
513706f2543Smrg	if (client->swapped)
514706f2543Smrg	{
515706f2543Smrg	    swapl (pictSubpixel, n);
516706f2543Smrg	}
517706f2543Smrg	++pictSubpixel;
518706f2543Smrg    }
519706f2543Smrg
520706f2543Smrg    if (client->swapped)
521706f2543Smrg    {
522706f2543Smrg	swaps (&reply->sequenceNumber, n);
523706f2543Smrg	swapl (&reply->length, n);
524706f2543Smrg	swapl (&reply->numFormats, n);
525706f2543Smrg	swapl (&reply->numScreens, n);
526706f2543Smrg	swapl (&reply->numDepths, n);
527706f2543Smrg	swapl (&reply->numVisuals, n);
528706f2543Smrg	swapl (&reply->numSubpixel, n);
529706f2543Smrg    }
530706f2543Smrg    WriteToClient(client, rlength, (char *) reply);
531706f2543Smrg    free(reply);
532706f2543Smrg    return Success;
533706f2543Smrg}
534706f2543Smrg
535706f2543Smrgstatic int
536706f2543SmrgProcRenderQueryPictIndexValues (ClientPtr client)
537706f2543Smrg{
538706f2543Smrg    PictFormatPtr   pFormat;
539706f2543Smrg    int		    rc, num;
540706f2543Smrg    int		    rlength;
541706f2543Smrg    int		    i, n;
542706f2543Smrg    REQUEST(xRenderQueryPictIndexValuesReq);
543706f2543Smrg    xRenderQueryPictIndexValuesReply *reply;
544706f2543Smrg    xIndexValue	    *values;
545706f2543Smrg
546706f2543Smrg    REQUEST_AT_LEAST_SIZE(xRenderQueryPictIndexValuesReq);
547706f2543Smrg
548706f2543Smrg    rc = dixLookupResourceByType((pointer *)&pFormat, stuff->format,
549706f2543Smrg				 PictFormatType, client, DixReadAccess);
550706f2543Smrg    if (rc != Success)
551706f2543Smrg	return rc;
552706f2543Smrg
553706f2543Smrg    if (pFormat->type != PictTypeIndexed)
554706f2543Smrg    {
555706f2543Smrg	client->errorValue = stuff->format;
556706f2543Smrg	return BadMatch;
557706f2543Smrg    }
558706f2543Smrg    num = pFormat->index.nvalues;
559706f2543Smrg    rlength = (sizeof (xRenderQueryPictIndexValuesReply) +
560706f2543Smrg	       num * sizeof(xIndexValue));
561706f2543Smrg    reply = (xRenderQueryPictIndexValuesReply *) malloc(rlength);
562706f2543Smrg    if (!reply)
563706f2543Smrg	return BadAlloc;
564706f2543Smrg
565706f2543Smrg    reply->type = X_Reply;
566706f2543Smrg    reply->sequenceNumber = client->sequence;
567706f2543Smrg    reply->length = bytes_to_int32(rlength - sizeof(xGenericReply));
568706f2543Smrg    reply->numIndexValues = num;
569706f2543Smrg
570706f2543Smrg    values = (xIndexValue *) (reply + 1);
571706f2543Smrg
572706f2543Smrg    memcpy (reply + 1, pFormat->index.pValues, num * sizeof (xIndexValue));
573706f2543Smrg
574706f2543Smrg    if (client->swapped)
575706f2543Smrg    {
576706f2543Smrg	for (i = 0; i < num; i++)
577706f2543Smrg	{
578706f2543Smrg	    swapl (&values[i].pixel, n);
579706f2543Smrg	    swaps (&values[i].red, n);
580706f2543Smrg	    swaps (&values[i].green, n);
581706f2543Smrg	    swaps (&values[i].blue, n);
582706f2543Smrg	    swaps (&values[i].alpha, n);
583706f2543Smrg	}
584706f2543Smrg	swaps (&reply->sequenceNumber, n);
585706f2543Smrg	swapl (&reply->length, n);
586706f2543Smrg	swapl (&reply->numIndexValues, n);
587706f2543Smrg    }
588706f2543Smrg
589706f2543Smrg    WriteToClient(client, rlength, (char *) reply);
590706f2543Smrg    free(reply);
591706f2543Smrg    return Success;
592706f2543Smrg}
593706f2543Smrg
594706f2543Smrgstatic int
595706f2543SmrgProcRenderQueryDithers (ClientPtr client)
596706f2543Smrg{
597706f2543Smrg    return BadImplementation;
598706f2543Smrg}
599706f2543Smrg
600706f2543Smrgstatic int
601706f2543SmrgProcRenderCreatePicture (ClientPtr client)
602706f2543Smrg{
603706f2543Smrg    PicturePtr	    pPicture;
604706f2543Smrg    DrawablePtr	    pDrawable;
605706f2543Smrg    PictFormatPtr   pFormat;
606706f2543Smrg    int		    len, error, rc;
607706f2543Smrg    REQUEST(xRenderCreatePictureReq);
608706f2543Smrg
609706f2543Smrg    REQUEST_AT_LEAST_SIZE(xRenderCreatePictureReq);
610706f2543Smrg
611706f2543Smrg    LEGAL_NEW_RESOURCE(stuff->pid, client);
612706f2543Smrg    rc = dixLookupDrawable(&pDrawable, stuff->drawable, client, 0,
613706f2543Smrg			   DixReadAccess|DixAddAccess);
614706f2543Smrg    if (rc != Success)
615706f2543Smrg	return rc;
616706f2543Smrg
617706f2543Smrg    rc = dixLookupResourceByType((pointer *)&pFormat, stuff->format,
618706f2543Smrg				 PictFormatType, client, DixReadAccess);
619706f2543Smrg    if (rc != Success)
620706f2543Smrg	return rc;
621706f2543Smrg
622706f2543Smrg    if (pFormat->depth != pDrawable->depth)
623706f2543Smrg	return BadMatch;
624706f2543Smrg    len = client->req_len - bytes_to_int32(sizeof(xRenderCreatePictureReq));
625706f2543Smrg    if (Ones(stuff->mask) != len)
626706f2543Smrg	return BadLength;
627706f2543Smrg
628706f2543Smrg    pPicture = CreatePicture (stuff->pid,
629706f2543Smrg			      pDrawable,
630706f2543Smrg			      pFormat,
631706f2543Smrg			      stuff->mask,
632706f2543Smrg			      (XID *) (stuff + 1),
633706f2543Smrg			      client,
634706f2543Smrg			      &error);
635706f2543Smrg    if (!pPicture)
636706f2543Smrg	return error;
637706f2543Smrg    if (!AddResource (stuff->pid, PictureType, (pointer)pPicture))
638706f2543Smrg	return BadAlloc;
639706f2543Smrg    return Success;
640706f2543Smrg}
641706f2543Smrg
642706f2543Smrgstatic int
643706f2543SmrgProcRenderChangePicture (ClientPtr client)
644706f2543Smrg{
645706f2543Smrg    PicturePtr	    pPicture;
646706f2543Smrg    REQUEST(xRenderChangePictureReq);
647706f2543Smrg    int len;
648706f2543Smrg
649706f2543Smrg    REQUEST_AT_LEAST_SIZE(xRenderChangePictureReq);
650706f2543Smrg    VERIFY_PICTURE (pPicture, stuff->picture, client, DixSetAttrAccess);
651706f2543Smrg
652706f2543Smrg    len = client->req_len - bytes_to_int32(sizeof(xRenderChangePictureReq));
653706f2543Smrg    if (Ones(stuff->mask) != len)
654706f2543Smrg	return BadLength;
655706f2543Smrg
656706f2543Smrg    return ChangePicture (pPicture, stuff->mask, (XID *) (stuff + 1),
657706f2543Smrg			  (DevUnion *) 0, client);
658706f2543Smrg}
659706f2543Smrg
660706f2543Smrgstatic int
661706f2543SmrgProcRenderSetPictureClipRectangles (ClientPtr client)
662706f2543Smrg{
663706f2543Smrg    REQUEST(xRenderSetPictureClipRectanglesReq);
664706f2543Smrg    PicturePtr	    pPicture;
665706f2543Smrg    int		    nr;
666706f2543Smrg
667706f2543Smrg    REQUEST_AT_LEAST_SIZE(xRenderSetPictureClipRectanglesReq);
668706f2543Smrg    VERIFY_PICTURE (pPicture, stuff->picture, client, DixSetAttrAccess);
669706f2543Smrg    if (!pPicture->pDrawable)
670706f2543Smrg        return BadDrawable;
671706f2543Smrg
672706f2543Smrg    nr = (client->req_len << 2) - sizeof(xRenderSetPictureClipRectanglesReq);
673706f2543Smrg    if (nr & 4)
674706f2543Smrg	return BadLength;
675706f2543Smrg    nr >>= 3;
676706f2543Smrg    return SetPictureClipRects (pPicture,
677706f2543Smrg				  stuff->xOrigin, stuff->yOrigin,
678706f2543Smrg				  nr, (xRectangle *) &stuff[1]);
679706f2543Smrg}
680706f2543Smrg
681706f2543Smrgstatic int
682706f2543SmrgProcRenderFreePicture (ClientPtr client)
683706f2543Smrg{
684706f2543Smrg    PicturePtr	pPicture;
685706f2543Smrg    REQUEST(xRenderFreePictureReq);
686706f2543Smrg
687706f2543Smrg    REQUEST_SIZE_MATCH(xRenderFreePictureReq);
688706f2543Smrg
689706f2543Smrg    VERIFY_PICTURE (pPicture, stuff->picture, client, DixDestroyAccess);
690706f2543Smrg    FreeResource (stuff->picture, RT_NONE);
691706f2543Smrg    return Success;
692706f2543Smrg}
693706f2543Smrg
694706f2543Smrgstatic Bool
695706f2543SmrgPictOpValid (CARD8 op)
696706f2543Smrg{
697706f2543Smrg    if (/*PictOpMinimum <= op && */ op <= PictOpMaximum)
698706f2543Smrg	return TRUE;
699706f2543Smrg    if (PictOpDisjointMinimum <= op && op <= PictOpDisjointMaximum)
700706f2543Smrg	return TRUE;
701706f2543Smrg    if (PictOpConjointMinimum <= op && op <= PictOpConjointMaximum)
702706f2543Smrg	return TRUE;
703706f2543Smrg    if (PictOpBlendMinimum <= op && op <= PictOpBlendMaximum)
704706f2543Smrg	return TRUE;
705706f2543Smrg    return FALSE;
706706f2543Smrg}
707706f2543Smrg
708706f2543Smrgstatic int
709706f2543SmrgProcRenderComposite (ClientPtr client)
710706f2543Smrg{
711706f2543Smrg    PicturePtr	pSrc, pMask, pDst;
712706f2543Smrg    REQUEST(xRenderCompositeReq);
713706f2543Smrg
714706f2543Smrg    REQUEST_SIZE_MATCH(xRenderCompositeReq);
715706f2543Smrg    if (!PictOpValid (stuff->op))
716706f2543Smrg    {
717706f2543Smrg	client->errorValue = stuff->op;
718706f2543Smrg	return BadValue;
719706f2543Smrg    }
720706f2543Smrg    VERIFY_PICTURE (pDst, stuff->dst, client, DixWriteAccess);
721706f2543Smrg    if (!pDst->pDrawable)
722706f2543Smrg        return BadDrawable;
723706f2543Smrg    VERIFY_PICTURE (pSrc, stuff->src, client, DixReadAccess);
724706f2543Smrg    VERIFY_ALPHA (pMask, stuff->mask, client, DixReadAccess);
725706f2543Smrg    if ((pSrc->pDrawable && pSrc->pDrawable->pScreen != pDst->pDrawable->pScreen) ||
726706f2543Smrg	(pMask && pMask->pDrawable && pDst->pDrawable->pScreen != pMask->pDrawable->pScreen))
727706f2543Smrg	return BadMatch;
728706f2543Smrg    CompositePicture (stuff->op,
729706f2543Smrg		      pSrc,
730706f2543Smrg		      pMask,
731706f2543Smrg		      pDst,
732706f2543Smrg		      stuff->xSrc,
733706f2543Smrg		      stuff->ySrc,
734706f2543Smrg		      stuff->xMask,
735706f2543Smrg		      stuff->yMask,
736706f2543Smrg		      stuff->xDst,
737706f2543Smrg		      stuff->yDst,
738706f2543Smrg		      stuff->width,
739706f2543Smrg		      stuff->height);
740706f2543Smrg    return Success;
741706f2543Smrg}
742706f2543Smrg
743706f2543Smrgstatic int
744706f2543SmrgProcRenderScale (ClientPtr client)
745706f2543Smrg{
746706f2543Smrg    return BadImplementation;
747706f2543Smrg}
748706f2543Smrg
749706f2543Smrgstatic int
750706f2543SmrgProcRenderTrapezoids (ClientPtr client)
751706f2543Smrg{
752706f2543Smrg    int		rc, ntraps;
753706f2543Smrg    PicturePtr	pSrc, pDst;
754706f2543Smrg    PictFormatPtr   pFormat;
755706f2543Smrg    REQUEST(xRenderTrapezoidsReq);
756706f2543Smrg
757706f2543Smrg    REQUEST_AT_LEAST_SIZE(xRenderTrapezoidsReq);
758706f2543Smrg    if (!PictOpValid (stuff->op))
759706f2543Smrg    {
760706f2543Smrg	client->errorValue = stuff->op;
761706f2543Smrg	return BadValue;
762706f2543Smrg    }
763706f2543Smrg    VERIFY_PICTURE (pSrc, stuff->src, client, DixReadAccess);
764706f2543Smrg    VERIFY_PICTURE (pDst, stuff->dst, client, DixWriteAccess);
765706f2543Smrg    if (!pDst->pDrawable)
766706f2543Smrg        return BadDrawable;
767706f2543Smrg    if (pSrc->pDrawable && pSrc->pDrawable->pScreen != pDst->pDrawable->pScreen)
768706f2543Smrg	return BadMatch;
769706f2543Smrg    if (stuff->maskFormat)
770706f2543Smrg    {
771706f2543Smrg	rc = dixLookupResourceByType((pointer *)&pFormat, stuff->maskFormat,
772706f2543Smrg				     PictFormatType, client, DixReadAccess);
773706f2543Smrg	if (rc != Success)
774706f2543Smrg	    return rc;
775706f2543Smrg    }
776706f2543Smrg    else
777706f2543Smrg	pFormat = 0;
778706f2543Smrg    ntraps = (client->req_len << 2) - sizeof (xRenderTrapezoidsReq);
779706f2543Smrg    if (ntraps % sizeof (xTrapezoid))
780706f2543Smrg	return BadLength;
781706f2543Smrg    ntraps /= sizeof (xTrapezoid);
782706f2543Smrg    if (ntraps)
783706f2543Smrg	CompositeTrapezoids (stuff->op, pSrc, pDst, pFormat,
784706f2543Smrg			     stuff->xSrc, stuff->ySrc,
785706f2543Smrg			     ntraps, (xTrapezoid *) &stuff[1]);
786706f2543Smrg    return Success;
787706f2543Smrg}
788706f2543Smrg
789706f2543Smrgstatic int
790706f2543SmrgProcRenderTriangles (ClientPtr client)
791706f2543Smrg{
792706f2543Smrg    int		rc, ntris;
793706f2543Smrg    PicturePtr	pSrc, pDst;
794706f2543Smrg    PictFormatPtr   pFormat;
795706f2543Smrg    REQUEST(xRenderTrianglesReq);
796706f2543Smrg
797706f2543Smrg    REQUEST_AT_LEAST_SIZE(xRenderTrianglesReq);
798706f2543Smrg    if (!PictOpValid (stuff->op))
799706f2543Smrg    {
800706f2543Smrg	client->errorValue = stuff->op;
801706f2543Smrg	return BadValue;
802706f2543Smrg    }
803706f2543Smrg    VERIFY_PICTURE (pSrc, stuff->src, client, DixReadAccess);
804706f2543Smrg    VERIFY_PICTURE (pDst, stuff->dst, client, DixWriteAccess);
805706f2543Smrg    if (!pDst->pDrawable)
806706f2543Smrg        return BadDrawable;
807706f2543Smrg    if (pSrc->pDrawable && pSrc->pDrawable->pScreen != pDst->pDrawable->pScreen)
808706f2543Smrg	return BadMatch;
809706f2543Smrg    if (stuff->maskFormat)
810706f2543Smrg    {
811706f2543Smrg	rc = dixLookupResourceByType((pointer *)&pFormat, stuff->maskFormat,
812706f2543Smrg				     PictFormatType, client, DixReadAccess);
813706f2543Smrg	if (rc != Success)
814706f2543Smrg	    return rc;
815706f2543Smrg    }
816706f2543Smrg    else
817706f2543Smrg	pFormat = 0;
818706f2543Smrg    ntris = (client->req_len << 2) - sizeof (xRenderTrianglesReq);
819706f2543Smrg    if (ntris % sizeof (xTriangle))
820706f2543Smrg	return BadLength;
821706f2543Smrg    ntris /= sizeof (xTriangle);
822706f2543Smrg    if (ntris)
823706f2543Smrg	CompositeTriangles (stuff->op, pSrc, pDst, pFormat,
824706f2543Smrg			    stuff->xSrc, stuff->ySrc,
825706f2543Smrg			    ntris, (xTriangle *) &stuff[1]);
826706f2543Smrg    return Success;
827706f2543Smrg}
828706f2543Smrg
829706f2543Smrgstatic int
830706f2543SmrgProcRenderTriStrip (ClientPtr client)
831706f2543Smrg{
832706f2543Smrg    int		rc, npoints;
833706f2543Smrg    PicturePtr	pSrc, pDst;
834706f2543Smrg    PictFormatPtr   pFormat;
835706f2543Smrg    REQUEST(xRenderTrianglesReq);
836706f2543Smrg
837706f2543Smrg    REQUEST_AT_LEAST_SIZE(xRenderTrianglesReq);
838706f2543Smrg    if (!PictOpValid (stuff->op))
839706f2543Smrg    {
840706f2543Smrg	client->errorValue = stuff->op;
841706f2543Smrg	return BadValue;
842706f2543Smrg    }
843706f2543Smrg    VERIFY_PICTURE (pSrc, stuff->src, client, DixReadAccess);
844706f2543Smrg    VERIFY_PICTURE (pDst, stuff->dst, client, DixWriteAccess);
845706f2543Smrg    if (!pDst->pDrawable)
846706f2543Smrg        return BadDrawable;
847706f2543Smrg    if (pSrc->pDrawable && pSrc->pDrawable->pScreen != pDst->pDrawable->pScreen)
848706f2543Smrg	return BadMatch;
849706f2543Smrg    if (stuff->maskFormat)
850706f2543Smrg    {
851706f2543Smrg	rc = dixLookupResourceByType((pointer *)&pFormat, stuff->maskFormat,
852706f2543Smrg				     PictFormatType, client, DixReadAccess);
853706f2543Smrg	if (rc != Success)
854706f2543Smrg	    return rc;
855706f2543Smrg    }
856706f2543Smrg    else
857706f2543Smrg	pFormat = 0;
858706f2543Smrg    npoints = ((client->req_len << 2) - sizeof (xRenderTriStripReq));
859706f2543Smrg    if (npoints & 4)
860706f2543Smrg	return BadLength;
861706f2543Smrg    npoints >>= 3;
862706f2543Smrg    if (npoints >= 3)
863706f2543Smrg	CompositeTriStrip (stuff->op, pSrc, pDst, pFormat,
864706f2543Smrg			   stuff->xSrc, stuff->ySrc,
865706f2543Smrg			   npoints, (xPointFixed *) &stuff[1]);
866706f2543Smrg    return Success;
867706f2543Smrg}
868706f2543Smrg
869706f2543Smrgstatic int
870706f2543SmrgProcRenderTriFan (ClientPtr client)
871706f2543Smrg{
872706f2543Smrg    int		rc, npoints;
873706f2543Smrg    PicturePtr	pSrc, pDst;
874706f2543Smrg    PictFormatPtr   pFormat;
875706f2543Smrg    REQUEST(xRenderTrianglesReq);
876706f2543Smrg
877706f2543Smrg    REQUEST_AT_LEAST_SIZE(xRenderTrianglesReq);
878706f2543Smrg    if (!PictOpValid (stuff->op))
879706f2543Smrg    {
880706f2543Smrg	client->errorValue = stuff->op;
881706f2543Smrg	return BadValue;
882706f2543Smrg    }
883706f2543Smrg    VERIFY_PICTURE (pSrc, stuff->src, client, DixReadAccess);
884706f2543Smrg    VERIFY_PICTURE (pDst, stuff->dst, client, DixWriteAccess);
885706f2543Smrg    if (!pDst->pDrawable)
886706f2543Smrg        return BadDrawable;
887706f2543Smrg    if (pSrc->pDrawable && pSrc->pDrawable->pScreen != pDst->pDrawable->pScreen)
888706f2543Smrg	return BadMatch;
889706f2543Smrg    if (stuff->maskFormat)
890706f2543Smrg    {
891706f2543Smrg	rc = dixLookupResourceByType((pointer *)&pFormat, stuff->maskFormat,
892706f2543Smrg				     PictFormatType, client, DixReadAccess);
893706f2543Smrg	if (rc != Success)
894706f2543Smrg	    return rc;
895706f2543Smrg    }
896706f2543Smrg    else
897706f2543Smrg	pFormat = 0;
898706f2543Smrg    npoints = ((client->req_len << 2) - sizeof (xRenderTriStripReq));
899706f2543Smrg    if (npoints & 4)
900706f2543Smrg	return BadLength;
901706f2543Smrg    npoints >>= 3;
902706f2543Smrg    if (npoints >= 3)
903706f2543Smrg	CompositeTriFan (stuff->op, pSrc, pDst, pFormat,
904706f2543Smrg			 stuff->xSrc, stuff->ySrc,
905706f2543Smrg			 npoints, (xPointFixed *) &stuff[1]);
906706f2543Smrg    return Success;
907706f2543Smrg}
908706f2543Smrg
909706f2543Smrgstatic int
910706f2543SmrgProcRenderColorTrapezoids (ClientPtr client)
911706f2543Smrg{
912706f2543Smrg    return BadImplementation;
913706f2543Smrg}
914706f2543Smrg
915706f2543Smrgstatic int
916706f2543SmrgProcRenderColorTriangles (ClientPtr client)
917706f2543Smrg{
918706f2543Smrg    return BadImplementation;
919706f2543Smrg}
920706f2543Smrg
921706f2543Smrgstatic int
922706f2543SmrgProcRenderTransform (ClientPtr client)
923706f2543Smrg{
924706f2543Smrg    return BadImplementation;
925706f2543Smrg}
926706f2543Smrg
927706f2543Smrgstatic int
928706f2543SmrgProcRenderCreateGlyphSet (ClientPtr client)
929706f2543Smrg{
930706f2543Smrg    GlyphSetPtr	    glyphSet;
931706f2543Smrg    PictFormatPtr   format;
932706f2543Smrg    int		    rc, f;
933706f2543Smrg    REQUEST(xRenderCreateGlyphSetReq);
934706f2543Smrg
935706f2543Smrg    REQUEST_SIZE_MATCH(xRenderCreateGlyphSetReq);
936706f2543Smrg
937706f2543Smrg    LEGAL_NEW_RESOURCE(stuff->gsid, client);
938706f2543Smrg    rc = dixLookupResourceByType((pointer *)&format, stuff->format,
939706f2543Smrg				 PictFormatType, client, DixReadAccess);
940706f2543Smrg    if (rc != Success)
941706f2543Smrg	return rc;
942706f2543Smrg
943706f2543Smrg    switch (format->depth) {
944706f2543Smrg    case 1:
945706f2543Smrg	f = GlyphFormat1;
946706f2543Smrg	break;
947706f2543Smrg    case 4:
948706f2543Smrg	f = GlyphFormat4;
949706f2543Smrg	break;
950706f2543Smrg    case 8:
951706f2543Smrg	f = GlyphFormat8;
952706f2543Smrg	break;
953706f2543Smrg    case 16:
954706f2543Smrg	f = GlyphFormat16;
955706f2543Smrg	break;
956706f2543Smrg    case 32:
957706f2543Smrg	f = GlyphFormat32;
958706f2543Smrg	break;
959706f2543Smrg    default:
960706f2543Smrg	return BadMatch;
961706f2543Smrg    }
962706f2543Smrg    if (format->type != PictTypeDirect)
963706f2543Smrg	return BadMatch;
964706f2543Smrg    glyphSet = AllocateGlyphSet (f, format);
965706f2543Smrg    if (!glyphSet)
966706f2543Smrg	return BadAlloc;
967706f2543Smrg    /* security creation/labeling check */
968706f2543Smrg    rc = XaceHook(XACE_RESOURCE_ACCESS, client, stuff->gsid, GlyphSetType,
969706f2543Smrg		  glyphSet, RT_NONE, NULL, DixCreateAccess);
970706f2543Smrg    if (rc != Success)
971706f2543Smrg	return rc;
972706f2543Smrg    if (!AddResource (stuff->gsid, GlyphSetType, (pointer)glyphSet))
973706f2543Smrg	return BadAlloc;
974706f2543Smrg    return Success;
975706f2543Smrg}
976706f2543Smrg
977706f2543Smrgstatic int
978706f2543SmrgProcRenderReferenceGlyphSet (ClientPtr client)
979706f2543Smrg{
980706f2543Smrg    GlyphSetPtr     glyphSet;
981706f2543Smrg    int rc;
982706f2543Smrg    REQUEST(xRenderReferenceGlyphSetReq);
983706f2543Smrg
984706f2543Smrg    REQUEST_SIZE_MATCH(xRenderReferenceGlyphSetReq);
985706f2543Smrg
986706f2543Smrg    LEGAL_NEW_RESOURCE(stuff->gsid, client);
987706f2543Smrg
988706f2543Smrg    rc = dixLookupResourceByType((pointer *)&glyphSet, stuff->existing, GlyphSetType,
989706f2543Smrg			   client, DixGetAttrAccess);
990706f2543Smrg    if (rc != Success)
991706f2543Smrg    {
992706f2543Smrg	client->errorValue = stuff->existing;
993706f2543Smrg	return rc;
994706f2543Smrg    }
995706f2543Smrg    glyphSet->refcnt++;
996706f2543Smrg    if (!AddResource (stuff->gsid, GlyphSetType, (pointer)glyphSet))
997706f2543Smrg	return BadAlloc;
998706f2543Smrg    return Success;
999706f2543Smrg}
1000706f2543Smrg
1001706f2543Smrg#define NLOCALDELTA	64
1002706f2543Smrg#define NLOCALGLYPH	256
1003706f2543Smrg
1004706f2543Smrgstatic int
1005706f2543SmrgProcRenderFreeGlyphSet (ClientPtr client)
1006706f2543Smrg{
1007706f2543Smrg    GlyphSetPtr     glyphSet;
1008706f2543Smrg    int rc;
1009706f2543Smrg    REQUEST(xRenderFreeGlyphSetReq);
1010706f2543Smrg
1011706f2543Smrg    REQUEST_SIZE_MATCH(xRenderFreeGlyphSetReq);
1012706f2543Smrg    rc = dixLookupResourceByType((pointer *)&glyphSet, stuff->glyphset, GlyphSetType,
1013706f2543Smrg			   client, DixDestroyAccess);
1014706f2543Smrg    if (rc != Success)
1015706f2543Smrg    {
1016706f2543Smrg	client->errorValue = stuff->glyphset;
1017706f2543Smrg	return rc;
1018706f2543Smrg    }
1019706f2543Smrg    FreeResource (stuff->glyphset, RT_NONE);
1020706f2543Smrg    return Success;
1021706f2543Smrg}
1022706f2543Smrg
1023706f2543Smrgtypedef struct _GlyphNew {
1024706f2543Smrg    Glyph	    id;
1025706f2543Smrg    GlyphPtr        glyph;
1026706f2543Smrg    Bool	    found;
1027706f2543Smrg    unsigned char   sha1[20];
1028706f2543Smrg} GlyphNewRec, *GlyphNewPtr;
1029706f2543Smrg
1030706f2543Smrg#define NeedsComponent(f) (PICT_FORMAT_A(f) != 0 && PICT_FORMAT_RGB(f) != 0)
1031706f2543Smrg
1032706f2543Smrgstatic int
1033706f2543SmrgProcRenderAddGlyphs (ClientPtr client)
1034706f2543Smrg{
1035706f2543Smrg    GlyphSetPtr     glyphSet;
1036706f2543Smrg    REQUEST(xRenderAddGlyphsReq);
1037706f2543Smrg    GlyphNewRec	    glyphsLocal[NLOCALGLYPH];
1038706f2543Smrg    GlyphNewPtr	    glyphsBase, glyphs, glyph_new;
1039706f2543Smrg    int		    remain, nglyphs;
1040706f2543Smrg    CARD32	    *gids;
1041706f2543Smrg    xGlyphInfo	    *gi;
1042706f2543Smrg    CARD8	    *bits;
1043706f2543Smrg    unsigned int    size;
1044706f2543Smrg    int		    err;
1045706f2543Smrg    int		    i, screen;
1046706f2543Smrg    PicturePtr	    pSrc = NULL, pDst = NULL;
1047706f2543Smrg    PixmapPtr	    pSrcPix = NULL, pDstPix = NULL;
1048706f2543Smrg    CARD32	    component_alpha;
1049706f2543Smrg
1050706f2543Smrg    REQUEST_AT_LEAST_SIZE(xRenderAddGlyphsReq);
1051706f2543Smrg    err = dixLookupResourceByType((pointer *)&glyphSet, stuff->glyphset, GlyphSetType,
1052706f2543Smrg			    client, DixAddAccess);
1053706f2543Smrg    if (err != Success)
1054706f2543Smrg    {
1055706f2543Smrg	client->errorValue = stuff->glyphset;
1056706f2543Smrg	return err;
1057706f2543Smrg    }
1058706f2543Smrg
1059706f2543Smrg    err = BadAlloc;
1060706f2543Smrg    nglyphs = stuff->nglyphs;
1061706f2543Smrg    if (nglyphs > UINT32_MAX / sizeof(GlyphNewRec))
1062706f2543Smrg	    return BadAlloc;
1063706f2543Smrg
1064706f2543Smrg    component_alpha = NeedsComponent (glyphSet->format->format);
1065706f2543Smrg
1066706f2543Smrg    if (nglyphs <= NLOCALGLYPH) {
1067706f2543Smrg	memset (glyphsLocal, 0, sizeof (glyphsLocal));
1068706f2543Smrg	glyphsBase = glyphsLocal;
1069706f2543Smrg    }
1070706f2543Smrg    else
1071706f2543Smrg    {
1072706f2543Smrg	glyphsBase = (GlyphNewPtr)calloc(nglyphs, sizeof (GlyphNewRec));
1073706f2543Smrg	if (!glyphsBase)
1074706f2543Smrg	    return BadAlloc;
1075706f2543Smrg    }
1076706f2543Smrg
1077706f2543Smrg    remain = (client->req_len << 2) - sizeof (xRenderAddGlyphsReq);
1078706f2543Smrg
1079706f2543Smrg    glyphs = glyphsBase;
1080706f2543Smrg
1081706f2543Smrg    gids = (CARD32 *) (stuff + 1);
1082706f2543Smrg    gi = (xGlyphInfo *) (gids + nglyphs);
1083706f2543Smrg    bits = (CARD8 *) (gi + nglyphs);
1084706f2543Smrg    remain -= (sizeof (CARD32) + sizeof (xGlyphInfo)) * nglyphs;
1085706f2543Smrg
1086706f2543Smrg    /* protect against bad nglyphs */
1087706f2543Smrg    if (gi < ((xGlyphInfo *)stuff) ||
1088706f2543Smrg        gi > ((xGlyphInfo *)((CARD32 *)stuff + client->req_len)) ||
1089706f2543Smrg        bits < ((CARD8 *)stuff) ||
1090706f2543Smrg        bits > ((CARD8 *)((CARD32 *)stuff + client->req_len))) {
1091706f2543Smrg        err = BadLength;
1092706f2543Smrg        goto bail;
1093706f2543Smrg    }
1094706f2543Smrg
1095706f2543Smrg    for (i = 0; i < nglyphs; i++)
1096706f2543Smrg    {
1097706f2543Smrg	size_t padded_width;
1098706f2543Smrg	glyph_new = &glyphs[i];
1099706f2543Smrg
1100706f2543Smrg	padded_width = PixmapBytePad (gi[i].width,
1101706f2543Smrg				      glyphSet->format->depth);
1102706f2543Smrg
1103706f2543Smrg	if (gi[i].height && padded_width > (UINT32_MAX - sizeof(GlyphRec))/gi[i].height)
1104706f2543Smrg	    break;
1105706f2543Smrg
1106706f2543Smrg	size = gi[i].height * padded_width;
1107706f2543Smrg	if (remain < size)
1108706f2543Smrg	    break;
1109706f2543Smrg
1110706f2543Smrg	err = HashGlyph (&gi[i], bits, size, glyph_new->sha1);
1111706f2543Smrg	if (err)
1112706f2543Smrg	    goto bail;
1113706f2543Smrg
1114706f2543Smrg	glyph_new->glyph = FindGlyphByHash (glyph_new->sha1,
1115706f2543Smrg					    glyphSet->fdepth);
1116706f2543Smrg
1117706f2543Smrg	if (glyph_new->glyph && glyph_new->glyph != DeletedGlyph)
1118706f2543Smrg	{
1119706f2543Smrg	    glyph_new->found = TRUE;
1120706f2543Smrg	}
1121706f2543Smrg	else
1122706f2543Smrg	{
1123706f2543Smrg	    GlyphPtr glyph;
1124706f2543Smrg
1125706f2543Smrg	    glyph_new->found = FALSE;
1126706f2543Smrg	    glyph_new->glyph = glyph = AllocateGlyph (&gi[i], glyphSet->fdepth);
1127706f2543Smrg	    if (! glyph)
1128706f2543Smrg	    {
1129706f2543Smrg		err = BadAlloc;
1130706f2543Smrg		goto bail;
1131706f2543Smrg	    }
1132706f2543Smrg
1133706f2543Smrg	    for (screen = 0; screen < screenInfo.numScreens; screen++)
1134706f2543Smrg	    {
1135706f2543Smrg		int	    width = gi[i].width;
1136706f2543Smrg		int	    height = gi[i].height;
1137706f2543Smrg		int	    depth = glyphSet->format->depth;
1138706f2543Smrg		ScreenPtr   pScreen;
1139706f2543Smrg		int	    error;
1140706f2543Smrg
1141706f2543Smrg		/* Skip work if it's invisibly small anyway */
1142706f2543Smrg		if (!width || !height)
1143706f2543Smrg		    break;
1144706f2543Smrg
1145706f2543Smrg		pScreen = screenInfo.screens[screen];
1146706f2543Smrg		pSrcPix = GetScratchPixmapHeader (pScreen,
1147706f2543Smrg						  width, height,
1148706f2543Smrg						  depth, depth,
1149706f2543Smrg						  -1, bits);
1150706f2543Smrg		if (! pSrcPix)
1151706f2543Smrg		{
1152706f2543Smrg		    err = BadAlloc;
1153706f2543Smrg		    goto bail;
1154706f2543Smrg		}
1155706f2543Smrg
1156706f2543Smrg		pSrc = CreatePicture (0, &pSrcPix->drawable,
1157706f2543Smrg				      glyphSet->format, 0, NULL,
1158706f2543Smrg				      serverClient, &error);
1159706f2543Smrg		if (! pSrc)
1160706f2543Smrg		{
1161706f2543Smrg		    err = BadAlloc;
1162706f2543Smrg		    goto bail;
1163706f2543Smrg		}
1164706f2543Smrg
1165706f2543Smrg		pDstPix = (pScreen->CreatePixmap) (pScreen,
1166706f2543Smrg						   width, height, depth,
1167706f2543Smrg						   CREATE_PIXMAP_USAGE_GLYPH_PICTURE);
1168706f2543Smrg
1169706f2543Smrg		if (!pDstPix)
1170706f2543Smrg		{
1171706f2543Smrg		    err = BadAlloc;
1172706f2543Smrg		    goto bail;
1173706f2543Smrg		}
1174706f2543Smrg
1175706f2543Smrg		GlyphPicture (glyph)[screen] = pDst =
1176706f2543Smrg			CreatePicture (0, &pDstPix->drawable,
1177706f2543Smrg				       glyphSet->format,
1178706f2543Smrg				       CPComponentAlpha, &component_alpha,
1179706f2543Smrg				       serverClient, &error);
1180706f2543Smrg
1181706f2543Smrg		/* The picture takes a reference to the pixmap, so we
1182706f2543Smrg		   drop ours. */
1183706f2543Smrg		(pScreen->DestroyPixmap) (pDstPix);
1184706f2543Smrg		pDstPix = NULL;
1185706f2543Smrg
1186706f2543Smrg		if (! pDst)
1187706f2543Smrg		{
1188706f2543Smrg		    err = BadAlloc;
1189706f2543Smrg		    goto bail;
1190706f2543Smrg		}
1191706f2543Smrg
1192706f2543Smrg		CompositePicture (PictOpSrc,
1193706f2543Smrg				  pSrc,
1194706f2543Smrg				  None,
1195706f2543Smrg				  pDst,
1196706f2543Smrg				  0, 0,
1197706f2543Smrg				  0, 0,
1198706f2543Smrg				  0, 0,
1199706f2543Smrg				  width, height);
1200706f2543Smrg
1201706f2543Smrg		FreePicture ((pointer) pSrc, 0);
1202706f2543Smrg		pSrc = NULL;
1203706f2543Smrg		FreeScratchPixmapHeader (pSrcPix);
1204706f2543Smrg		pSrcPix = NULL;
1205706f2543Smrg	    }
1206706f2543Smrg
1207706f2543Smrg	    memcpy (glyph_new->glyph->sha1, glyph_new->sha1, 20);
1208706f2543Smrg	}
1209706f2543Smrg
1210706f2543Smrg	glyph_new->id = gids[i];
1211706f2543Smrg
1212706f2543Smrg	if (size & 3)
1213706f2543Smrg	    size += 4 - (size & 3);
1214706f2543Smrg	bits += size;
1215706f2543Smrg	remain -= size;
1216706f2543Smrg    }
1217706f2543Smrg    if (remain || i < nglyphs)
1218706f2543Smrg    {
1219706f2543Smrg	err = BadLength;
1220706f2543Smrg	goto bail;
1221706f2543Smrg    }
1222706f2543Smrg    if (!ResizeGlyphSet (glyphSet, nglyphs))
1223706f2543Smrg    {
1224706f2543Smrg	err = BadAlloc;
1225706f2543Smrg	goto bail;
1226706f2543Smrg    }
1227706f2543Smrg    for (i = 0; i < nglyphs; i++)
1228706f2543Smrg	AddGlyph (glyphSet, glyphs[i].glyph, glyphs[i].id);
1229706f2543Smrg
1230706f2543Smrg    if (glyphsBase != glyphsLocal)
1231706f2543Smrg	free(glyphsBase);
1232706f2543Smrg    return Success;
1233706f2543Smrgbail:
1234706f2543Smrg    if (pSrc)
1235706f2543Smrg	FreePicture ((pointer) pSrc, 0);
1236706f2543Smrg    if (pSrcPix)
1237706f2543Smrg	FreeScratchPixmapHeader (pSrcPix);
1238706f2543Smrg    for (i = 0; i < nglyphs; i++)
1239706f2543Smrg	if (glyphs[i].glyph && ! glyphs[i].found)
1240706f2543Smrg	    free(glyphs[i].glyph);
1241706f2543Smrg    if (glyphsBase != glyphsLocal)
1242706f2543Smrg	free(glyphsBase);
1243706f2543Smrg    return err;
1244706f2543Smrg}
1245706f2543Smrg
1246706f2543Smrgstatic int
1247706f2543SmrgProcRenderAddGlyphsFromPicture (ClientPtr client)
1248706f2543Smrg{
1249706f2543Smrg    return BadImplementation;
1250706f2543Smrg}
1251706f2543Smrg
1252706f2543Smrgstatic int
1253706f2543SmrgProcRenderFreeGlyphs (ClientPtr client)
1254706f2543Smrg{
1255706f2543Smrg    REQUEST(xRenderFreeGlyphsReq);
1256706f2543Smrg    GlyphSetPtr     glyphSet;
1257706f2543Smrg    int		    rc, nglyph;
1258706f2543Smrg    CARD32	    *gids;
1259706f2543Smrg    CARD32	    glyph;
1260706f2543Smrg
1261706f2543Smrg    REQUEST_AT_LEAST_SIZE(xRenderFreeGlyphsReq);
1262706f2543Smrg    rc = dixLookupResourceByType((pointer *)&glyphSet, stuff->glyphset, GlyphSetType,
1263706f2543Smrg			   client, DixRemoveAccess);
1264706f2543Smrg    if (rc != Success)
1265706f2543Smrg    {
1266706f2543Smrg	client->errorValue = stuff->glyphset;
1267706f2543Smrg	return rc;
1268706f2543Smrg    }
1269706f2543Smrg    nglyph = bytes_to_int32((client->req_len << 2) - sizeof (xRenderFreeGlyphsReq));
1270706f2543Smrg    gids = (CARD32 *) (stuff + 1);
1271706f2543Smrg    while (nglyph-- > 0)
1272706f2543Smrg    {
1273706f2543Smrg	glyph = *gids++;
1274706f2543Smrg	if (!DeleteGlyph (glyphSet, glyph))
1275706f2543Smrg	{
1276706f2543Smrg	    client->errorValue = glyph;
1277706f2543Smrg	    return RenderErrBase + BadGlyph;
1278706f2543Smrg	}
1279706f2543Smrg    }
1280706f2543Smrg    return Success;
1281706f2543Smrg}
1282706f2543Smrg
1283706f2543Smrgstatic int
1284706f2543SmrgProcRenderCompositeGlyphs (ClientPtr client)
1285706f2543Smrg{
1286706f2543Smrg    GlyphSetPtr     glyphSet;
1287706f2543Smrg    GlyphSet	    gs;
1288706f2543Smrg    PicturePtr      pSrc, pDst;
1289706f2543Smrg    PictFormatPtr   pFormat;
1290706f2543Smrg    GlyphListRec    listsLocal[NLOCALDELTA];
1291706f2543Smrg    GlyphListPtr    lists, listsBase;
1292706f2543Smrg    GlyphPtr	    glyphsLocal[NLOCALGLYPH];
1293706f2543Smrg    Glyph	    glyph;
1294706f2543Smrg    GlyphPtr	    *glyphs, *glyphsBase;
1295706f2543Smrg    xGlyphElt	    *elt;
1296706f2543Smrg    CARD8	    *buffer, *end;
1297706f2543Smrg    int		    nglyph;
1298706f2543Smrg    int		    nlist;
1299706f2543Smrg    int		    space;
1300706f2543Smrg    int		    size;
1301706f2543Smrg    int		    rc, n;
1302706f2543Smrg
1303706f2543Smrg    REQUEST(xRenderCompositeGlyphsReq);
1304706f2543Smrg
1305706f2543Smrg    REQUEST_AT_LEAST_SIZE(xRenderCompositeGlyphsReq);
1306706f2543Smrg
1307706f2543Smrg    switch (stuff->renderReqType) {
1308706f2543Smrg    default:			    size = 1; break;
1309706f2543Smrg    case X_RenderCompositeGlyphs16: size = 2; break;
1310706f2543Smrg    case X_RenderCompositeGlyphs32: size = 4; break;
1311706f2543Smrg    }
1312706f2543Smrg
1313706f2543Smrg    if (!PictOpValid (stuff->op))
1314706f2543Smrg    {
1315706f2543Smrg	client->errorValue = stuff->op;
1316706f2543Smrg	return BadValue;
1317706f2543Smrg    }
1318706f2543Smrg    VERIFY_PICTURE (pSrc, stuff->src, client, DixReadAccess);
1319706f2543Smrg    VERIFY_PICTURE (pDst, stuff->dst, client, DixWriteAccess);
1320706f2543Smrg    if (!pDst->pDrawable)
1321706f2543Smrg        return BadDrawable;
1322706f2543Smrg    if (pSrc->pDrawable && pSrc->pDrawable->pScreen != pDst->pDrawable->pScreen)
1323706f2543Smrg	return BadMatch;
1324706f2543Smrg    if (stuff->maskFormat)
1325706f2543Smrg    {
1326706f2543Smrg	rc = dixLookupResourceByType((pointer *)&pFormat, stuff->maskFormat,
1327706f2543Smrg				     PictFormatType, client, DixReadAccess);
1328706f2543Smrg	if (rc != Success)
1329706f2543Smrg	    return rc;
1330706f2543Smrg    }
1331706f2543Smrg    else
1332706f2543Smrg	pFormat = 0;
1333706f2543Smrg
1334706f2543Smrg    rc = dixLookupResourceByType((pointer *)&glyphSet, stuff->glyphset,
1335706f2543Smrg				 GlyphSetType, client, DixUseAccess);
1336706f2543Smrg    if (rc != Success)
1337706f2543Smrg	return rc;
1338706f2543Smrg
1339706f2543Smrg    buffer = (CARD8 *) (stuff + 1);
1340706f2543Smrg    end = (CARD8 *) stuff + (client->req_len << 2);
1341706f2543Smrg    nglyph = 0;
1342706f2543Smrg    nlist = 0;
1343706f2543Smrg    while (buffer + sizeof (xGlyphElt) < end)
1344706f2543Smrg    {
1345706f2543Smrg	elt = (xGlyphElt *) buffer;
1346706f2543Smrg	buffer += sizeof (xGlyphElt);
1347706f2543Smrg
1348706f2543Smrg	if (elt->len == 0xff)
1349706f2543Smrg	{
1350706f2543Smrg	    buffer += 4;
1351706f2543Smrg	}
1352706f2543Smrg	else
1353706f2543Smrg	{
1354706f2543Smrg	    nlist++;
1355706f2543Smrg	    nglyph += elt->len;
1356706f2543Smrg	    space = size * elt->len;
1357706f2543Smrg	    if (space & 3)
1358706f2543Smrg		space += 4 - (space & 3);
1359706f2543Smrg	    buffer += space;
1360706f2543Smrg	}
1361706f2543Smrg    }
1362706f2543Smrg    if (nglyph <= NLOCALGLYPH)
1363706f2543Smrg	glyphsBase = glyphsLocal;
1364706f2543Smrg    else
1365706f2543Smrg    {
1366706f2543Smrg	glyphsBase = (GlyphPtr *) malloc(nglyph * sizeof (GlyphPtr));
1367706f2543Smrg	if (!glyphsBase)
1368706f2543Smrg	    return BadAlloc;
1369706f2543Smrg    }
1370706f2543Smrg    if (nlist <= NLOCALDELTA)
1371706f2543Smrg	listsBase = listsLocal;
1372706f2543Smrg    else
1373706f2543Smrg    {
1374706f2543Smrg	listsBase = (GlyphListPtr) malloc(nlist * sizeof (GlyphListRec));
1375706f2543Smrg	if (!listsBase) {
1376706f2543Smrg	    rc = BadAlloc;
1377706f2543Smrg	    goto bail;
1378706f2543Smrg	}
1379706f2543Smrg    }
1380706f2543Smrg    buffer = (CARD8 *) (stuff + 1);
1381706f2543Smrg    glyphs = glyphsBase;
1382706f2543Smrg    lists = listsBase;
1383706f2543Smrg    while (buffer + sizeof (xGlyphElt) < end)
1384706f2543Smrg    {
1385706f2543Smrg	elt = (xGlyphElt *) buffer;
1386706f2543Smrg	buffer += sizeof (xGlyphElt);
1387706f2543Smrg
1388706f2543Smrg	if (elt->len == 0xff)
1389706f2543Smrg	{
1390706f2543Smrg	    if (buffer + sizeof (GlyphSet) < end)
1391706f2543Smrg	    {
1392706f2543Smrg                memcpy(&gs, buffer, sizeof(GlyphSet));
1393706f2543Smrg		rc = dixLookupResourceByType((pointer *)&glyphSet, gs,
1394706f2543Smrg					     GlyphSetType, client,
1395706f2543Smrg					     DixUseAccess);
1396706f2543Smrg		if (rc != Success)
1397706f2543Smrg		    goto bail;
1398706f2543Smrg	    }
1399706f2543Smrg	    buffer += 4;
1400706f2543Smrg	}
1401706f2543Smrg	else
1402706f2543Smrg	{
1403706f2543Smrg	    lists->xOff = elt->deltax;
1404706f2543Smrg	    lists->yOff = elt->deltay;
1405706f2543Smrg	    lists->format = glyphSet->format;
1406706f2543Smrg	    lists->len = 0;
1407706f2543Smrg	    n = elt->len;
1408706f2543Smrg	    while (n--)
1409706f2543Smrg	    {
1410706f2543Smrg		if (buffer + size <= end)
1411706f2543Smrg		{
1412706f2543Smrg		    switch (size) {
1413706f2543Smrg		    case 1:
1414706f2543Smrg			glyph = *((CARD8 *)buffer); break;
1415706f2543Smrg		    case 2:
1416706f2543Smrg			glyph = *((CARD16 *)buffer); break;
1417706f2543Smrg		    case 4:
1418706f2543Smrg		    default:
1419706f2543Smrg			glyph = *((CARD32 *)buffer); break;
1420706f2543Smrg		    }
1421706f2543Smrg		    if ((*glyphs = FindGlyph (glyphSet, glyph)))
1422706f2543Smrg		    {
1423706f2543Smrg			lists->len++;
1424706f2543Smrg			glyphs++;
1425706f2543Smrg		    }
1426706f2543Smrg		}
1427706f2543Smrg		buffer += size;
1428706f2543Smrg	    }
1429706f2543Smrg	    space = size * elt->len;
1430706f2543Smrg	    if (space & 3)
1431706f2543Smrg		buffer += 4 - (space & 3);
1432706f2543Smrg	    lists++;
1433706f2543Smrg	}
1434706f2543Smrg    }
1435706f2543Smrg    if (buffer > end) {
1436706f2543Smrg	rc = BadLength;
1437706f2543Smrg	goto bail;
1438706f2543Smrg    }
1439706f2543Smrg
1440706f2543Smrg    CompositeGlyphs (stuff->op,
1441706f2543Smrg		     pSrc,
1442706f2543Smrg		     pDst,
1443706f2543Smrg		     pFormat,
1444706f2543Smrg		     stuff->xSrc,
1445706f2543Smrg		     stuff->ySrc,
1446706f2543Smrg		     nlist,
1447706f2543Smrg		     listsBase,
1448706f2543Smrg		     glyphsBase);
1449706f2543Smrg    rc = Success;
1450706f2543Smrg
1451706f2543Smrgbail:
1452706f2543Smrg    if (glyphsBase != glyphsLocal)
1453706f2543Smrg	free(glyphsBase);
1454706f2543Smrg    if (listsBase != listsLocal)
1455706f2543Smrg	free(listsBase);
1456706f2543Smrg    return rc;
1457706f2543Smrg}
1458706f2543Smrg
1459706f2543Smrgstatic int
1460706f2543SmrgProcRenderFillRectangles (ClientPtr client)
1461706f2543Smrg{
1462706f2543Smrg    PicturePtr	    pDst;
1463706f2543Smrg    int             things;
1464706f2543Smrg    REQUEST(xRenderFillRectanglesReq);
1465706f2543Smrg
1466706f2543Smrg    REQUEST_AT_LEAST_SIZE (xRenderFillRectanglesReq);
1467706f2543Smrg    if (!PictOpValid (stuff->op))
1468706f2543Smrg    {
1469706f2543Smrg	client->errorValue = stuff->op;
1470706f2543Smrg	return BadValue;
1471706f2543Smrg    }
1472706f2543Smrg    VERIFY_PICTURE (pDst, stuff->dst, client, DixWriteAccess);
1473706f2543Smrg    if (!pDst->pDrawable)
1474706f2543Smrg        return BadDrawable;
1475706f2543Smrg
1476706f2543Smrg    things = (client->req_len << 2) - sizeof(xRenderFillRectanglesReq);
1477706f2543Smrg    if (things & 4)
1478706f2543Smrg	return BadLength;
1479706f2543Smrg    things >>= 3;
1480706f2543Smrg
1481706f2543Smrg    CompositeRects (stuff->op,
1482706f2543Smrg		    pDst,
1483706f2543Smrg		    &stuff->color,
1484706f2543Smrg		    things,
1485706f2543Smrg		    (xRectangle *) &stuff[1]);
1486706f2543Smrg
1487706f2543Smrg    return Success;
1488706f2543Smrg}
1489706f2543Smrg
1490706f2543Smrgstatic void
1491706f2543SmrgRenderSetBit (unsigned char *line, int x, int bit)
1492706f2543Smrg{
1493706f2543Smrg    unsigned char   mask;
1494706f2543Smrg
1495706f2543Smrg    if (screenInfo.bitmapBitOrder == LSBFirst)
1496706f2543Smrg	mask = (1 << (x & 7));
1497706f2543Smrg    else
1498706f2543Smrg	mask = (0x80 >> (x & 7));
1499706f2543Smrg    /* XXX assumes byte order is host byte order */
1500706f2543Smrg    line += (x >> 3);
1501706f2543Smrg    if (bit)
1502706f2543Smrg	*line |= mask;
1503706f2543Smrg    else
1504706f2543Smrg	*line &= ~mask;
1505706f2543Smrg}
1506706f2543Smrg
1507706f2543Smrg#define DITHER_DIM 2
1508706f2543Smrg
1509706f2543Smrgstatic CARD32 orderedDither[DITHER_DIM][DITHER_DIM] = {
1510706f2543Smrg    {  1,  3,  },
1511706f2543Smrg    {  4,  2,  },
1512706f2543Smrg};
1513706f2543Smrg
1514706f2543Smrg#define DITHER_SIZE  ((sizeof orderedDither / sizeof orderedDither[0][0]) + 1)
1515706f2543Smrg
1516706f2543Smrgstatic int
1517706f2543SmrgProcRenderCreateCursor (ClientPtr client)
1518706f2543Smrg{
1519706f2543Smrg    REQUEST(xRenderCreateCursorReq);
1520706f2543Smrg    PicturePtr	    pSrc;
1521706f2543Smrg    ScreenPtr	    pScreen;
1522706f2543Smrg    unsigned short  width, height;
1523706f2543Smrg    CARD32	    *argbbits, *argb;
1524706f2543Smrg    unsigned char   *srcbits, *srcline;
1525706f2543Smrg    unsigned char   *mskbits, *mskline;
1526706f2543Smrg    int		    stride;
1527706f2543Smrg    int		    x, y;
1528706f2543Smrg    int		    nbytes_mono;
1529706f2543Smrg    CursorMetricRec cm;
1530706f2543Smrg    CursorPtr	    pCursor;
1531706f2543Smrg    CARD32	    twocolor[3];
1532706f2543Smrg    int		    rc, ncolor;
1533706f2543Smrg
1534706f2543Smrg    REQUEST_SIZE_MATCH (xRenderCreateCursorReq);
1535706f2543Smrg    LEGAL_NEW_RESOURCE(stuff->cid, client);
1536706f2543Smrg
1537706f2543Smrg    VERIFY_PICTURE (pSrc, stuff->src, client, DixReadAccess);
1538706f2543Smrg    if (!pSrc->pDrawable)
1539706f2543Smrg        return BadDrawable;
1540706f2543Smrg    pScreen = pSrc->pDrawable->pScreen;
1541706f2543Smrg    width = pSrc->pDrawable->width;
1542706f2543Smrg    height = pSrc->pDrawable->height;
1543706f2543Smrg    if (height && width > UINT32_MAX/(height*sizeof(CARD32)))
1544706f2543Smrg	return BadAlloc;
1545706f2543Smrg    if ( stuff->x > width
1546706f2543Smrg      || stuff->y > height )
1547706f2543Smrg	return BadMatch;
1548706f2543Smrg    argbbits = malloc(width * height * sizeof (CARD32));
1549706f2543Smrg    if (!argbbits)
1550706f2543Smrg	return BadAlloc;
1551706f2543Smrg
1552706f2543Smrg    stride = BitmapBytePad(width);
1553706f2543Smrg    nbytes_mono = stride*height;
1554706f2543Smrg    srcbits = calloc(1, nbytes_mono);
1555706f2543Smrg    if (!srcbits)
1556706f2543Smrg    {
1557706f2543Smrg	free(argbbits);
1558706f2543Smrg	return BadAlloc;
1559706f2543Smrg    }
1560706f2543Smrg    mskbits = calloc(1, nbytes_mono);
1561706f2543Smrg    if (!mskbits)
1562706f2543Smrg    {
1563706f2543Smrg	free(argbbits);
1564706f2543Smrg	free(srcbits);
1565706f2543Smrg	return BadAlloc;
1566706f2543Smrg    }
1567706f2543Smrg
1568706f2543Smrg    if (pSrc->format == PICT_a8r8g8b8)
1569706f2543Smrg    {
1570706f2543Smrg	(*pScreen->GetImage) (pSrc->pDrawable,
1571706f2543Smrg			      0, 0, width, height, ZPixmap,
1572706f2543Smrg			      0xffffffff, (pointer) argbbits);
1573706f2543Smrg    }
1574706f2543Smrg    else
1575706f2543Smrg    {
1576706f2543Smrg	PixmapPtr	pPixmap;
1577706f2543Smrg	PicturePtr	pPicture;
1578706f2543Smrg	PictFormatPtr	pFormat;
1579706f2543Smrg	int		error;
1580706f2543Smrg
1581706f2543Smrg	pFormat = PictureMatchFormat (pScreen, 32, PICT_a8r8g8b8);
1582706f2543Smrg	if (!pFormat)
1583706f2543Smrg	{
1584706f2543Smrg	    free(argbbits);
1585706f2543Smrg	    free(srcbits);
1586706f2543Smrg	    free(mskbits);
1587706f2543Smrg	    return BadImplementation;
1588706f2543Smrg	}
1589706f2543Smrg	pPixmap = (*pScreen->CreatePixmap) (pScreen, width, height, 32,
1590706f2543Smrg					    CREATE_PIXMAP_USAGE_SCRATCH);
1591706f2543Smrg	if (!pPixmap)
1592706f2543Smrg	{
1593706f2543Smrg	    free(argbbits);
1594706f2543Smrg	    free(srcbits);
1595706f2543Smrg	    free(mskbits);
1596706f2543Smrg	    return BadAlloc;
1597706f2543Smrg	}
1598706f2543Smrg	pPicture = CreatePicture (0, &pPixmap->drawable, pFormat, 0, 0,
1599706f2543Smrg				  client, &error);
1600706f2543Smrg	if (!pPicture)
1601706f2543Smrg	{
1602706f2543Smrg	    free(argbbits);
1603706f2543Smrg	    free(srcbits);
1604706f2543Smrg	    free(mskbits);
1605706f2543Smrg	    return error;
1606706f2543Smrg	}
1607706f2543Smrg	(*pScreen->DestroyPixmap) (pPixmap);
1608706f2543Smrg	CompositePicture (PictOpSrc,
1609706f2543Smrg			  pSrc, 0, pPicture,
1610706f2543Smrg			  0, 0, 0, 0, 0, 0, width, height);
1611706f2543Smrg	(*pScreen->GetImage) (pPicture->pDrawable,
1612706f2543Smrg			      0, 0, width, height, ZPixmap,
1613706f2543Smrg			      0xffffffff, (pointer) argbbits);
1614706f2543Smrg	FreePicture (pPicture, 0);
1615706f2543Smrg    }
1616706f2543Smrg    /*
1617706f2543Smrg     * Check whether the cursor can be directly supported by
1618706f2543Smrg     * the core cursor code
1619706f2543Smrg     */
1620706f2543Smrg    ncolor = 0;
1621706f2543Smrg    argb = argbbits;
1622706f2543Smrg    for (y = 0; ncolor <= 2 && y < height; y++)
1623706f2543Smrg    {
1624706f2543Smrg	for (x = 0; ncolor <= 2 && x < width; x++)
1625706f2543Smrg	{
1626706f2543Smrg	    CARD32  p = *argb++;
1627706f2543Smrg	    CARD32  a = (p >> 24);
1628706f2543Smrg
1629706f2543Smrg	    if (a == 0)	    /* transparent */
1630706f2543Smrg		continue;
1631706f2543Smrg	    if (a == 0xff)  /* opaque */
1632706f2543Smrg	    {
1633706f2543Smrg		int n;
1634706f2543Smrg		for (n = 0; n < ncolor; n++)
1635706f2543Smrg		    if (p == twocolor[n])
1636706f2543Smrg			break;
1637706f2543Smrg		if (n == ncolor)
1638706f2543Smrg		    twocolor[ncolor++] = p;
1639706f2543Smrg	    }
1640706f2543Smrg	    else
1641706f2543Smrg		ncolor = 3;
1642706f2543Smrg	}
1643706f2543Smrg    }
1644706f2543Smrg
1645706f2543Smrg    /*
1646706f2543Smrg     * Convert argb image to two plane cursor
1647706f2543Smrg     */
1648706f2543Smrg    srcline = srcbits;
1649706f2543Smrg    mskline = mskbits;
1650706f2543Smrg    argb = argbbits;
1651706f2543Smrg    for (y = 0; y < height; y++)
1652706f2543Smrg    {
1653706f2543Smrg	for (x = 0; x < width; x++)
1654706f2543Smrg	{
1655706f2543Smrg	    CARD32  p = *argb++;
1656706f2543Smrg
1657706f2543Smrg	    if (ncolor <= 2)
1658706f2543Smrg	    {
1659706f2543Smrg		CARD32	a = ((p >> 24));
1660706f2543Smrg
1661706f2543Smrg		RenderSetBit (mskline, x, a != 0);
1662706f2543Smrg		RenderSetBit (srcline, x, a != 0 && p == twocolor[0]);
1663706f2543Smrg	    }
1664706f2543Smrg	    else
1665706f2543Smrg	    {
1666706f2543Smrg		CARD32	a = ((p >> 24) * DITHER_SIZE + 127) / 255;
1667706f2543Smrg		CARD32	i = ((CvtR8G8B8toY15(p) >> 7) * DITHER_SIZE + 127) / 255;
1668706f2543Smrg		CARD32	d = orderedDither[y&(DITHER_DIM-1)][x&(DITHER_DIM-1)];
1669706f2543Smrg		/* Set mask from dithered alpha value */
1670706f2543Smrg		RenderSetBit(mskline, x, a > d);
1671706f2543Smrg		/* Set src from dithered intensity value */
1672706f2543Smrg		RenderSetBit(srcline, x, a > d && i <= d);
1673706f2543Smrg	    }
1674706f2543Smrg	}
1675706f2543Smrg	srcline += stride;
1676706f2543Smrg	mskline += stride;
1677706f2543Smrg    }
1678706f2543Smrg    /*
1679706f2543Smrg     * Dither to white and black if the cursor has more than two colors
1680706f2543Smrg     */
1681706f2543Smrg    if (ncolor > 2)
1682706f2543Smrg    {
1683706f2543Smrg	twocolor[0] = 0xff000000;
1684706f2543Smrg	twocolor[1] = 0xffffffff;
1685706f2543Smrg    }
1686706f2543Smrg    else
1687706f2543Smrg    {
1688706f2543Smrg	free(argbbits);
1689706f2543Smrg	argbbits = 0;
1690706f2543Smrg    }
1691706f2543Smrg
1692706f2543Smrg#define GetByte(p,s)	(((p) >> (s)) & 0xff)
1693706f2543Smrg#define GetColor(p,s)	(GetByte(p,s) | (GetByte(p,s) << 8))
1694706f2543Smrg
1695706f2543Smrg    cm.width = width;
1696706f2543Smrg    cm.height = height;
1697706f2543Smrg    cm.xhot = stuff->x;
1698706f2543Smrg    cm.yhot = stuff->y;
1699706f2543Smrg    rc = AllocARGBCursor(srcbits, mskbits, argbbits, &cm,
1700706f2543Smrg			 GetColor(twocolor[0], 16),
1701706f2543Smrg			 GetColor(twocolor[0], 8),
1702706f2543Smrg			 GetColor(twocolor[0], 0),
1703706f2543Smrg			 GetColor(twocolor[1], 16),
1704706f2543Smrg			 GetColor(twocolor[1], 8),
1705706f2543Smrg			 GetColor(twocolor[1], 0),
1706706f2543Smrg			 &pCursor, client, stuff->cid);
1707706f2543Smrg    if (rc != Success)
1708706f2543Smrg	return rc;
1709706f2543Smrg    if (!AddResource(stuff->cid, RT_CURSOR, (pointer)pCursor))
1710706f2543Smrg	return BadAlloc;
1711706f2543Smrg
1712706f2543Smrg    return Success;
1713706f2543Smrg}
1714706f2543Smrg
1715706f2543Smrgstatic int
1716706f2543SmrgProcRenderSetPictureTransform (ClientPtr client)
1717706f2543Smrg{
1718706f2543Smrg    REQUEST(xRenderSetPictureTransformReq);
1719706f2543Smrg    PicturePtr	pPicture;
1720706f2543Smrg
1721706f2543Smrg    REQUEST_SIZE_MATCH(xRenderSetPictureTransformReq);
1722706f2543Smrg    VERIFY_PICTURE (pPicture, stuff->picture, client, DixSetAttrAccess);
1723706f2543Smrg    return SetPictureTransform (pPicture, (PictTransform *) &stuff->transform);
1724706f2543Smrg}
1725706f2543Smrg
1726706f2543Smrgstatic int
1727706f2543SmrgProcRenderQueryFilters (ClientPtr client)
1728706f2543Smrg{
1729706f2543Smrg    REQUEST (xRenderQueryFiltersReq);
1730706f2543Smrg    DrawablePtr			pDrawable;
1731706f2543Smrg    xRenderQueryFiltersReply	*reply;
1732706f2543Smrg    int				nbytesName;
1733706f2543Smrg    int				nnames;
1734706f2543Smrg    ScreenPtr			pScreen;
1735706f2543Smrg    PictureScreenPtr		ps;
1736706f2543Smrg    int				i, j, len, total_bytes, rc;
1737706f2543Smrg    INT16			*aliases;
1738706f2543Smrg    char			*names;
1739706f2543Smrg
1740706f2543Smrg    REQUEST_SIZE_MATCH(xRenderQueryFiltersReq);
1741706f2543Smrg    rc = dixLookupDrawable(&pDrawable, stuff->drawable, client, 0,
1742706f2543Smrg			   DixGetAttrAccess);
1743706f2543Smrg    if (rc != Success)
1744706f2543Smrg	return rc;
1745706f2543Smrg
1746706f2543Smrg    pScreen = pDrawable->pScreen;
1747706f2543Smrg    nbytesName = 0;
1748706f2543Smrg    nnames = 0;
1749706f2543Smrg    ps = GetPictureScreenIfSet(pScreen);
1750706f2543Smrg    if (ps)
1751706f2543Smrg    {
1752706f2543Smrg	for (i = 0; i < ps->nfilters; i++)
1753706f2543Smrg	    nbytesName += 1 + strlen (ps->filters[i].name);
1754706f2543Smrg	for (i = 0; i < ps->nfilterAliases; i++)
1755706f2543Smrg	    nbytesName += 1 + strlen (ps->filterAliases[i].alias);
1756706f2543Smrg	nnames = ps->nfilters + ps->nfilterAliases;
1757706f2543Smrg    }
1758706f2543Smrg    len = ((nnames + 1) >> 1) + bytes_to_int32(nbytesName);
1759706f2543Smrg    total_bytes = sizeof (xRenderQueryFiltersReply) + (len << 2);
1760706f2543Smrg    reply = (xRenderQueryFiltersReply *) malloc(total_bytes);
1761706f2543Smrg    if (!reply)
1762706f2543Smrg	return BadAlloc;
1763706f2543Smrg    aliases = (INT16 *) (reply + 1);
1764706f2543Smrg    names = (char *) (aliases + ((nnames + 1) & ~1));
1765706f2543Smrg
1766706f2543Smrg    reply->type = X_Reply;
1767706f2543Smrg    reply->sequenceNumber = client->sequence;
1768706f2543Smrg    reply->length = len;
1769706f2543Smrg    reply->numAliases = nnames;
1770706f2543Smrg    reply->numFilters = nnames;
1771706f2543Smrg    if (ps)
1772706f2543Smrg    {
1773706f2543Smrg
1774706f2543Smrg	/* fill in alias values */
1775706f2543Smrg	for (i = 0; i < ps->nfilters; i++)
1776706f2543Smrg	    aliases[i] = FilterAliasNone;
1777706f2543Smrg	for (i = 0; i < ps->nfilterAliases; i++)
1778706f2543Smrg	{
1779706f2543Smrg	    for (j = 0; j < ps->nfilters; j++)
1780706f2543Smrg		if (ps->filterAliases[i].filter_id == ps->filters[j].id)
1781706f2543Smrg		    break;
1782706f2543Smrg	    if (j == ps->nfilters)
1783706f2543Smrg	    {
1784706f2543Smrg		for (j = 0; j < ps->nfilterAliases; j++)
1785706f2543Smrg		    if (ps->filterAliases[i].filter_id ==
1786706f2543Smrg			ps->filterAliases[j].alias_id)
1787706f2543Smrg		    {
1788706f2543Smrg			break;
1789706f2543Smrg		    }
1790706f2543Smrg		if (j == ps->nfilterAliases)
1791706f2543Smrg		    j = FilterAliasNone;
1792706f2543Smrg		else
1793706f2543Smrg		    j = j + ps->nfilters;
1794706f2543Smrg	    }
1795706f2543Smrg	    aliases[i + ps->nfilters] = j;
1796706f2543Smrg	}
1797706f2543Smrg
1798706f2543Smrg	/* fill in filter names */
1799706f2543Smrg	for (i = 0; i < ps->nfilters; i++)
1800706f2543Smrg	{
1801706f2543Smrg	    j = strlen (ps->filters[i].name);
1802706f2543Smrg	    *names++ = j;
1803706f2543Smrg	    strncpy (names, ps->filters[i].name, j);
1804706f2543Smrg	    names += j;
1805706f2543Smrg	}
1806706f2543Smrg
1807706f2543Smrg	/* fill in filter alias names */
1808706f2543Smrg	for (i = 0; i < ps->nfilterAliases; i++)
1809706f2543Smrg	{
1810706f2543Smrg	    j = strlen (ps->filterAliases[i].alias);
1811706f2543Smrg	    *names++ = j;
1812706f2543Smrg	    strncpy (names, ps->filterAliases[i].alias, j);
1813706f2543Smrg	    names += j;
1814706f2543Smrg	}
1815706f2543Smrg    }
1816706f2543Smrg
1817706f2543Smrg    if (client->swapped)
1818706f2543Smrg    {
1819706f2543Smrg	register int n;
1820706f2543Smrg
1821706f2543Smrg	for (i = 0; i < reply->numAliases; i++)
1822706f2543Smrg	{
1823706f2543Smrg	    swaps (&aliases[i], n);
1824706f2543Smrg	}
1825706f2543Smrg    	swaps(&reply->sequenceNumber, n);
1826706f2543Smrg    	swapl(&reply->length, n);
1827706f2543Smrg	swapl(&reply->numAliases, n);
1828706f2543Smrg	swapl(&reply->numFilters, n);
1829706f2543Smrg    }
1830706f2543Smrg    WriteToClient(client, total_bytes, (char *) reply);
1831706f2543Smrg    free(reply);
1832706f2543Smrg
1833706f2543Smrg    return Success;
1834706f2543Smrg}
1835706f2543Smrg
1836706f2543Smrgstatic int
1837706f2543SmrgProcRenderSetPictureFilter (ClientPtr client)
1838706f2543Smrg{
1839706f2543Smrg    REQUEST (xRenderSetPictureFilterReq);
1840706f2543Smrg    PicturePtr	pPicture;
1841706f2543Smrg    int		result;
1842706f2543Smrg    xFixed	*params;
1843706f2543Smrg    int		nparams;
1844706f2543Smrg    char	*name;
1845706f2543Smrg
1846706f2543Smrg    REQUEST_AT_LEAST_SIZE (xRenderSetPictureFilterReq);
1847706f2543Smrg    VERIFY_PICTURE (pPicture, stuff->picture, client, DixSetAttrAccess);
1848706f2543Smrg    name = (char *) (stuff + 1);
1849706f2543Smrg    params = (xFixed *) (name + pad_to_int32(stuff->nbytes));
1850706f2543Smrg    nparams = ((xFixed *) stuff + client->req_len) - params;
1851706f2543Smrg    result = SetPictureFilter (pPicture, name, stuff->nbytes, params, nparams);
1852706f2543Smrg    return result;
1853706f2543Smrg}
1854706f2543Smrg
1855706f2543Smrgstatic int
1856706f2543SmrgProcRenderCreateAnimCursor (ClientPtr client)
1857706f2543Smrg{
1858706f2543Smrg    REQUEST(xRenderCreateAnimCursorReq);
1859706f2543Smrg    CursorPtr	    *cursors;
1860706f2543Smrg    CARD32	    *deltas;
1861706f2543Smrg    CursorPtr	    pCursor;
1862706f2543Smrg    int		    ncursor;
1863706f2543Smrg    xAnimCursorElt  *elt;
1864706f2543Smrg    int		    i;
1865706f2543Smrg    int		    ret;
1866706f2543Smrg
1867706f2543Smrg    REQUEST_AT_LEAST_SIZE(xRenderCreateAnimCursorReq);
1868706f2543Smrg    LEGAL_NEW_RESOURCE(stuff->cid, client);
1869706f2543Smrg    if (client->req_len & 1)
1870706f2543Smrg	return BadLength;
1871706f2543Smrg    ncursor = (client->req_len - (bytes_to_int32(sizeof(xRenderCreateAnimCursorReq)))) >> 1;
1872706f2543Smrg    cursors = malloc(ncursor * (sizeof (CursorPtr) + sizeof (CARD32)));
1873706f2543Smrg    if (!cursors)
1874706f2543Smrg	return BadAlloc;
1875706f2543Smrg    deltas = (CARD32 *) (cursors + ncursor);
1876706f2543Smrg    elt = (xAnimCursorElt *) (stuff + 1);
1877706f2543Smrg    for (i = 0; i < ncursor; i++)
1878706f2543Smrg    {
1879706f2543Smrg	ret = dixLookupResourceByType((pointer *)(cursors + i), elt->cursor,
1880706f2543Smrg				      RT_CURSOR, client, DixReadAccess);
1881706f2543Smrg	if (ret != Success)
1882706f2543Smrg	{
1883706f2543Smrg	    free(cursors);
1884706f2543Smrg	    return ret;
1885706f2543Smrg	}
1886706f2543Smrg	deltas[i] = elt->delay;
1887706f2543Smrg	elt++;
1888706f2543Smrg    }
1889706f2543Smrg    ret = AnimCursorCreate (cursors, deltas, ncursor, &pCursor, client,
1890706f2543Smrg			    stuff->cid);
1891706f2543Smrg    free(cursors);
1892706f2543Smrg    if (ret != Success)
1893706f2543Smrg	return ret;
1894706f2543Smrg
1895706f2543Smrg    if (AddResource (stuff->cid, RT_CURSOR, (pointer)pCursor))
1896706f2543Smrg	return Success;
1897706f2543Smrg    return BadAlloc;
1898706f2543Smrg}
1899706f2543Smrg
1900706f2543Smrgstatic int
1901706f2543SmrgProcRenderAddTraps (ClientPtr client)
1902706f2543Smrg{
1903706f2543Smrg    int		ntraps;
1904706f2543Smrg    PicturePtr	pPicture;
1905706f2543Smrg    REQUEST(xRenderAddTrapsReq);
1906706f2543Smrg
1907706f2543Smrg    REQUEST_AT_LEAST_SIZE(xRenderAddTrapsReq);
1908706f2543Smrg    VERIFY_PICTURE (pPicture, stuff->picture, client, DixWriteAccess);
1909706f2543Smrg    if (!pPicture->pDrawable)
1910706f2543Smrg        return BadDrawable;
1911706f2543Smrg    ntraps = (client->req_len << 2) - sizeof (xRenderAddTrapsReq);
1912706f2543Smrg    if (ntraps % sizeof (xTrap))
1913706f2543Smrg	return BadLength;
1914706f2543Smrg    ntraps /= sizeof (xTrap);
1915706f2543Smrg    if (ntraps)
1916706f2543Smrg	AddTraps (pPicture,
1917706f2543Smrg		  stuff->xOff, stuff->yOff,
1918706f2543Smrg		  ntraps, (xTrap *) &stuff[1]);
1919706f2543Smrg    return Success;
1920706f2543Smrg}
1921706f2543Smrg
1922706f2543Smrgstatic int ProcRenderCreateSolidFill(ClientPtr client)
1923706f2543Smrg{
1924706f2543Smrg    PicturePtr	    pPicture;
1925706f2543Smrg    int		    error = 0;
1926706f2543Smrg    REQUEST(xRenderCreateSolidFillReq);
1927706f2543Smrg
1928706f2543Smrg    REQUEST_AT_LEAST_SIZE(xRenderCreateSolidFillReq);
1929706f2543Smrg
1930706f2543Smrg    LEGAL_NEW_RESOURCE(stuff->pid, client);
1931706f2543Smrg
1932706f2543Smrg    pPicture = CreateSolidPicture(stuff->pid, &stuff->color, &error);
1933706f2543Smrg    if (!pPicture)
1934706f2543Smrg	return error;
1935706f2543Smrg    /* security creation/labeling check */
1936706f2543Smrg    error = XaceHook(XACE_RESOURCE_ACCESS, client, stuff->pid, PictureType,
1937706f2543Smrg		     pPicture, RT_NONE, NULL, DixCreateAccess);
1938706f2543Smrg    if (error != Success)
1939706f2543Smrg	return error;
1940706f2543Smrg    if (!AddResource (stuff->pid, PictureType, (pointer)pPicture))
1941706f2543Smrg	return BadAlloc;
1942706f2543Smrg    return Success;
1943706f2543Smrg}
1944706f2543Smrg
1945706f2543Smrgstatic int ProcRenderCreateLinearGradient (ClientPtr client)
1946706f2543Smrg{
1947706f2543Smrg    PicturePtr	    pPicture;
1948706f2543Smrg    int		    len;
1949706f2543Smrg    int		    error = 0;
1950706f2543Smrg    xFixed          *stops;
1951706f2543Smrg    xRenderColor   *colors;
1952706f2543Smrg    REQUEST(xRenderCreateLinearGradientReq);
1953706f2543Smrg
1954706f2543Smrg    REQUEST_AT_LEAST_SIZE(xRenderCreateLinearGradientReq);
1955706f2543Smrg
1956706f2543Smrg    LEGAL_NEW_RESOURCE(stuff->pid, client);
1957706f2543Smrg
1958706f2543Smrg    len = (client->req_len << 2) - sizeof(xRenderCreateLinearGradientReq);
1959706f2543Smrg    if (stuff->nStops > UINT32_MAX/(sizeof(xFixed) + sizeof(xRenderColor)))
1960706f2543Smrg	return BadLength;
1961706f2543Smrg    if (len != stuff->nStops*(sizeof(xFixed) + sizeof(xRenderColor)))
1962706f2543Smrg        return BadLength;
1963706f2543Smrg
1964706f2543Smrg    stops = (xFixed *)(stuff + 1);
1965706f2543Smrg    colors = (xRenderColor *)(stops + stuff->nStops);
1966706f2543Smrg
1967706f2543Smrg    pPicture = CreateLinearGradientPicture (stuff->pid, &stuff->p1, &stuff->p2,
1968706f2543Smrg                                            stuff->nStops, stops, colors, &error);
1969706f2543Smrg    if (!pPicture)
1970706f2543Smrg	return error;
1971706f2543Smrg    /* security creation/labeling check */
1972706f2543Smrg    error = XaceHook(XACE_RESOURCE_ACCESS, client, stuff->pid, PictureType,
1973706f2543Smrg		     pPicture, RT_NONE, NULL, DixCreateAccess);
1974706f2543Smrg    if (error != Success)
1975706f2543Smrg	return error;
1976706f2543Smrg    if (!AddResource (stuff->pid, PictureType, (pointer)pPicture))
1977706f2543Smrg	return BadAlloc;
1978706f2543Smrg    return Success;
1979706f2543Smrg}
1980706f2543Smrg
1981706f2543Smrgstatic int ProcRenderCreateRadialGradient (ClientPtr client)
1982706f2543Smrg{
1983706f2543Smrg    PicturePtr	    pPicture;
1984706f2543Smrg    int		    len;
1985706f2543Smrg    int		    error = 0;
1986706f2543Smrg    xFixed          *stops;
1987706f2543Smrg    xRenderColor   *colors;
1988706f2543Smrg    REQUEST(xRenderCreateRadialGradientReq);
1989706f2543Smrg
1990706f2543Smrg    REQUEST_AT_LEAST_SIZE(xRenderCreateRadialGradientReq);
1991706f2543Smrg
1992706f2543Smrg    LEGAL_NEW_RESOURCE(stuff->pid, client);
1993706f2543Smrg
1994706f2543Smrg    len = (client->req_len << 2) - sizeof(xRenderCreateRadialGradientReq);
1995706f2543Smrg    if (len != stuff->nStops*(sizeof(xFixed) + sizeof(xRenderColor)))
1996706f2543Smrg        return BadLength;
1997706f2543Smrg
1998706f2543Smrg    stops = (xFixed *)(stuff + 1);
1999706f2543Smrg    colors = (xRenderColor *)(stops + stuff->nStops);
2000706f2543Smrg
2001706f2543Smrg    pPicture = CreateRadialGradientPicture (stuff->pid, &stuff->inner, &stuff->outer,
2002706f2543Smrg                                            stuff->inner_radius, stuff->outer_radius,
2003706f2543Smrg                                            stuff->nStops, stops, colors, &error);
2004706f2543Smrg    if (!pPicture)
2005706f2543Smrg	return error;
2006706f2543Smrg    /* security creation/labeling check */
2007706f2543Smrg    error = XaceHook(XACE_RESOURCE_ACCESS, client, stuff->pid, PictureType,
2008706f2543Smrg		     pPicture, RT_NONE, NULL, DixCreateAccess);
2009706f2543Smrg    if (error != Success)
2010706f2543Smrg	return error;
2011706f2543Smrg    if (!AddResource (stuff->pid, PictureType, (pointer)pPicture))
2012706f2543Smrg	return BadAlloc;
2013706f2543Smrg    return Success;
2014706f2543Smrg}
2015706f2543Smrg
2016706f2543Smrgstatic int ProcRenderCreateConicalGradient (ClientPtr client)
2017706f2543Smrg{
2018706f2543Smrg    PicturePtr	    pPicture;
2019706f2543Smrg    int		    len;
2020706f2543Smrg    int		    error = 0;
2021706f2543Smrg    xFixed          *stops;
2022706f2543Smrg    xRenderColor   *colors;
2023706f2543Smrg    REQUEST(xRenderCreateConicalGradientReq);
2024706f2543Smrg
2025706f2543Smrg    REQUEST_AT_LEAST_SIZE(xRenderCreateConicalGradientReq);
2026706f2543Smrg
2027706f2543Smrg    LEGAL_NEW_RESOURCE(stuff->pid, client);
2028706f2543Smrg
2029706f2543Smrg    len = (client->req_len << 2) - sizeof(xRenderCreateConicalGradientReq);
2030706f2543Smrg    if (len != stuff->nStops*(sizeof(xFixed) + sizeof(xRenderColor)))
2031706f2543Smrg        return BadLength;
2032706f2543Smrg
2033706f2543Smrg    stops = (xFixed *)(stuff + 1);
2034706f2543Smrg    colors = (xRenderColor *)(stops + stuff->nStops);
2035706f2543Smrg
2036706f2543Smrg    pPicture = CreateConicalGradientPicture (stuff->pid, &stuff->center, stuff->angle,
2037706f2543Smrg                                             stuff->nStops, stops, colors, &error);
2038706f2543Smrg    if (!pPicture)
2039706f2543Smrg	return error;
2040706f2543Smrg    /* security creation/labeling check */
2041706f2543Smrg    error = XaceHook(XACE_RESOURCE_ACCESS, client, stuff->pid, PictureType,
2042706f2543Smrg		     pPicture, RT_NONE, NULL, DixCreateAccess);
2043706f2543Smrg    if (error != Success)
2044706f2543Smrg	return error;
2045706f2543Smrg    if (!AddResource (stuff->pid, PictureType, (pointer)pPicture))
2046706f2543Smrg	return BadAlloc;
2047706f2543Smrg    return Success;
2048706f2543Smrg}
2049706f2543Smrg
2050706f2543Smrg
2051706f2543Smrgstatic int
2052706f2543SmrgProcRenderDispatch (ClientPtr client)
2053706f2543Smrg{
2054706f2543Smrg    REQUEST(xReq);
2055706f2543Smrg
2056706f2543Smrg    if (stuff->data < RenderNumberRequests)
2057706f2543Smrg	return (*ProcRenderVector[stuff->data]) (client);
2058706f2543Smrg    else
2059706f2543Smrg	return BadRequest;
2060706f2543Smrg}
2061706f2543Smrg
2062706f2543Smrgstatic int
2063706f2543SmrgSProcRenderQueryVersion (ClientPtr client)
2064706f2543Smrg{
2065706f2543Smrg    register int n;
2066706f2543Smrg    REQUEST(xRenderQueryVersionReq);
2067706f2543Smrg    REQUEST_SIZE_MATCH(xRenderQueryVersionReq);
2068706f2543Smrg
2069706f2543Smrg    swaps(&stuff->length, n);
2070706f2543Smrg    swapl(&stuff->majorVersion, n);
2071706f2543Smrg    swapl(&stuff->minorVersion, n);
2072706f2543Smrg    return (*ProcRenderVector[stuff->renderReqType])(client);
2073706f2543Smrg}
2074706f2543Smrg
2075706f2543Smrgstatic int
2076706f2543SmrgSProcRenderQueryPictFormats (ClientPtr client)
2077706f2543Smrg{
2078706f2543Smrg    register int n;
2079706f2543Smrg    REQUEST(xRenderQueryPictFormatsReq);
2080706f2543Smrg    REQUEST_SIZE_MATCH(xRenderQueryPictFormatsReq);
2081706f2543Smrg    swaps(&stuff->length, n);
2082706f2543Smrg    return (*ProcRenderVector[stuff->renderReqType]) (client);
2083706f2543Smrg}
2084706f2543Smrg
2085706f2543Smrgstatic int
2086706f2543SmrgSProcRenderQueryPictIndexValues (ClientPtr client)
2087706f2543Smrg{
2088706f2543Smrg    register int n;
2089706f2543Smrg    REQUEST(xRenderQueryPictIndexValuesReq);
2090706f2543Smrg    REQUEST_AT_LEAST_SIZE(xRenderQueryPictIndexValuesReq);
2091706f2543Smrg    swaps(&stuff->length, n);
2092706f2543Smrg    swapl(&stuff->format, n);
2093706f2543Smrg    return (*ProcRenderVector[stuff->renderReqType]) (client);
2094706f2543Smrg}
2095706f2543Smrg
2096706f2543Smrgstatic int
2097706f2543SmrgSProcRenderQueryDithers (ClientPtr client)
2098706f2543Smrg{
2099706f2543Smrg    return BadImplementation;
2100706f2543Smrg}
2101706f2543Smrg
2102706f2543Smrgstatic int
2103706f2543SmrgSProcRenderCreatePicture (ClientPtr client)
2104706f2543Smrg{
2105706f2543Smrg    register int n;
2106706f2543Smrg    REQUEST(xRenderCreatePictureReq);
2107706f2543Smrg    REQUEST_AT_LEAST_SIZE(xRenderCreatePictureReq);
2108706f2543Smrg    swaps(&stuff->length, n);
2109706f2543Smrg    swapl(&stuff->pid, n);
2110706f2543Smrg    swapl(&stuff->drawable, n);
2111706f2543Smrg    swapl(&stuff->format, n);
2112706f2543Smrg    swapl(&stuff->mask, n);
2113706f2543Smrg    SwapRestL(stuff);
2114706f2543Smrg    return (*ProcRenderVector[stuff->renderReqType]) (client);
2115706f2543Smrg}
2116706f2543Smrg
2117706f2543Smrgstatic int
2118706f2543SmrgSProcRenderChangePicture (ClientPtr client)
2119706f2543Smrg{
2120706f2543Smrg    register int n;
2121706f2543Smrg    REQUEST(xRenderChangePictureReq);
2122706f2543Smrg    REQUEST_AT_LEAST_SIZE(xRenderChangePictureReq);
2123706f2543Smrg    swaps(&stuff->length, n);
2124706f2543Smrg    swapl(&stuff->picture, n);
2125706f2543Smrg    swapl(&stuff->mask, n);
2126706f2543Smrg    SwapRestL(stuff);
2127706f2543Smrg    return (*ProcRenderVector[stuff->renderReqType]) (client);
2128706f2543Smrg}
2129706f2543Smrg
2130706f2543Smrgstatic int
2131706f2543SmrgSProcRenderSetPictureClipRectangles (ClientPtr client)
2132706f2543Smrg{
2133706f2543Smrg    register int n;
2134706f2543Smrg    REQUEST(xRenderSetPictureClipRectanglesReq);
2135706f2543Smrg    REQUEST_AT_LEAST_SIZE(xRenderSetPictureClipRectanglesReq);
2136706f2543Smrg    swaps(&stuff->length, n);
2137706f2543Smrg    swapl(&stuff->picture, n);
2138706f2543Smrg    swaps(&stuff->xOrigin, n);
2139706f2543Smrg    swaps(&stuff->yOrigin, n);
2140706f2543Smrg    SwapRestS(stuff);
2141706f2543Smrg    return (*ProcRenderVector[stuff->renderReqType]) (client);
2142706f2543Smrg}
2143706f2543Smrg
2144706f2543Smrgstatic int
2145706f2543SmrgSProcRenderFreePicture (ClientPtr client)
2146706f2543Smrg{
2147706f2543Smrg    register int n;
2148706f2543Smrg    REQUEST(xRenderFreePictureReq);
2149706f2543Smrg    REQUEST_SIZE_MATCH(xRenderFreePictureReq);
2150706f2543Smrg    swaps(&stuff->length, n);
2151706f2543Smrg    swapl(&stuff->picture, n);
2152706f2543Smrg    return (*ProcRenderVector[stuff->renderReqType]) (client);
2153706f2543Smrg}
2154706f2543Smrg
2155706f2543Smrgstatic int
2156706f2543SmrgSProcRenderComposite (ClientPtr client)
2157706f2543Smrg{
2158706f2543Smrg    register int n;
2159706f2543Smrg    REQUEST(xRenderCompositeReq);
2160706f2543Smrg    REQUEST_SIZE_MATCH(xRenderCompositeReq);
2161706f2543Smrg    swaps(&stuff->length, n);
2162706f2543Smrg    swapl(&stuff->src, n);
2163706f2543Smrg    swapl(&stuff->mask, n);
2164706f2543Smrg    swapl(&stuff->dst, n);
2165706f2543Smrg    swaps(&stuff->xSrc, n);
2166706f2543Smrg    swaps(&stuff->ySrc, n);
2167706f2543Smrg    swaps(&stuff->xMask, n);
2168706f2543Smrg    swaps(&stuff->yMask, n);
2169706f2543Smrg    swaps(&stuff->xDst, n);
2170706f2543Smrg    swaps(&stuff->yDst, n);
2171706f2543Smrg    swaps(&stuff->width, n);
2172706f2543Smrg    swaps(&stuff->height, n);
2173706f2543Smrg    return (*ProcRenderVector[stuff->renderReqType]) (client);
2174706f2543Smrg}
2175706f2543Smrg
2176706f2543Smrgstatic int
2177706f2543SmrgSProcRenderScale (ClientPtr client)
2178706f2543Smrg{
2179706f2543Smrg    register int n;
2180706f2543Smrg    REQUEST(xRenderScaleReq);
2181706f2543Smrg    REQUEST_SIZE_MATCH(xRenderScaleReq);
2182706f2543Smrg    swaps(&stuff->length, n);
2183706f2543Smrg    swapl(&stuff->src, n);
2184706f2543Smrg    swapl(&stuff->dst, n);
2185706f2543Smrg    swapl(&stuff->colorScale, n);
2186706f2543Smrg    swapl(&stuff->alphaScale, n);
2187706f2543Smrg    swaps(&stuff->xSrc, n);
2188706f2543Smrg    swaps(&stuff->ySrc, n);
2189706f2543Smrg    swaps(&stuff->xDst, n);
2190706f2543Smrg    swaps(&stuff->yDst, n);
2191706f2543Smrg    swaps(&stuff->width, n);
2192706f2543Smrg    swaps(&stuff->height, n);
2193706f2543Smrg    return (*ProcRenderVector[stuff->renderReqType]) (client);
2194706f2543Smrg}
2195706f2543Smrg
2196706f2543Smrgstatic int
2197706f2543SmrgSProcRenderTrapezoids (ClientPtr client)
2198706f2543Smrg{
2199706f2543Smrg    register int n;
2200706f2543Smrg    REQUEST(xRenderTrapezoidsReq);
2201706f2543Smrg
2202706f2543Smrg    REQUEST_AT_LEAST_SIZE(xRenderTrapezoidsReq);
2203706f2543Smrg    swaps (&stuff->length, n);
2204706f2543Smrg    swapl (&stuff->src, n);
2205706f2543Smrg    swapl (&stuff->dst, n);
2206706f2543Smrg    swapl (&stuff->maskFormat, n);
2207706f2543Smrg    swaps (&stuff->xSrc, n);
2208706f2543Smrg    swaps (&stuff->ySrc, n);
2209706f2543Smrg    SwapRestL(stuff);
2210706f2543Smrg    return (*ProcRenderVector[stuff->renderReqType]) (client);
2211706f2543Smrg}
2212706f2543Smrg
2213706f2543Smrgstatic int
2214706f2543SmrgSProcRenderTriangles (ClientPtr client)
2215706f2543Smrg{
2216706f2543Smrg    register int n;
2217706f2543Smrg    REQUEST(xRenderTrianglesReq);
2218706f2543Smrg
2219706f2543Smrg    REQUEST_AT_LEAST_SIZE(xRenderTrianglesReq);
2220706f2543Smrg    swaps (&stuff->length, n);
2221706f2543Smrg    swapl (&stuff->src, n);
2222706f2543Smrg    swapl (&stuff->dst, n);
2223706f2543Smrg    swapl (&stuff->maskFormat, n);
2224706f2543Smrg    swaps (&stuff->xSrc, n);
2225706f2543Smrg    swaps (&stuff->ySrc, n);
2226706f2543Smrg    SwapRestL(stuff);
2227706f2543Smrg    return (*ProcRenderVector[stuff->renderReqType]) (client);
2228706f2543Smrg}
2229706f2543Smrg
2230706f2543Smrgstatic int
2231706f2543SmrgSProcRenderTriStrip (ClientPtr client)
2232706f2543Smrg{
2233706f2543Smrg    register int n;
2234706f2543Smrg    REQUEST(xRenderTriStripReq);
2235706f2543Smrg
2236706f2543Smrg    REQUEST_AT_LEAST_SIZE(xRenderTriStripReq);
2237706f2543Smrg    swaps (&stuff->length, n);
2238706f2543Smrg    swapl (&stuff->src, n);
2239706f2543Smrg    swapl (&stuff->dst, n);
2240706f2543Smrg    swapl (&stuff->maskFormat, n);
2241706f2543Smrg    swaps (&stuff->xSrc, n);
2242706f2543Smrg    swaps (&stuff->ySrc, n);
2243706f2543Smrg    SwapRestL(stuff);
2244706f2543Smrg    return (*ProcRenderVector[stuff->renderReqType]) (client);
2245706f2543Smrg}
2246706f2543Smrg
2247706f2543Smrgstatic int
2248706f2543SmrgSProcRenderTriFan (ClientPtr client)
2249706f2543Smrg{
2250706f2543Smrg    register int n;
2251706f2543Smrg    REQUEST(xRenderTriFanReq);
2252706f2543Smrg
2253706f2543Smrg    REQUEST_AT_LEAST_SIZE(xRenderTriFanReq);
2254706f2543Smrg    swaps (&stuff->length, n);
2255706f2543Smrg    swapl (&stuff->src, n);
2256706f2543Smrg    swapl (&stuff->dst, n);
2257706f2543Smrg    swapl (&stuff->maskFormat, n);
2258706f2543Smrg    swaps (&stuff->xSrc, n);
2259706f2543Smrg    swaps (&stuff->ySrc, n);
2260706f2543Smrg    SwapRestL(stuff);
2261706f2543Smrg    return (*ProcRenderVector[stuff->renderReqType]) (client);
2262706f2543Smrg}
2263706f2543Smrg
2264706f2543Smrgstatic int
2265706f2543SmrgSProcRenderColorTrapezoids (ClientPtr client)
2266706f2543Smrg{
2267706f2543Smrg    return BadImplementation;
2268706f2543Smrg}
2269706f2543Smrg
2270706f2543Smrgstatic int
2271706f2543SmrgSProcRenderColorTriangles (ClientPtr client)
2272706f2543Smrg{
2273706f2543Smrg    return BadImplementation;
2274706f2543Smrg}
2275706f2543Smrg
2276706f2543Smrgstatic int
2277706f2543SmrgSProcRenderTransform (ClientPtr client)
2278706f2543Smrg{
2279706f2543Smrg    return BadImplementation;
2280706f2543Smrg}
2281706f2543Smrg
2282706f2543Smrgstatic int
2283706f2543SmrgSProcRenderCreateGlyphSet (ClientPtr client)
2284706f2543Smrg{
2285706f2543Smrg    register int n;
2286706f2543Smrg    REQUEST(xRenderCreateGlyphSetReq);
2287706f2543Smrg    REQUEST_SIZE_MATCH(xRenderCreateGlyphSetReq);
2288706f2543Smrg    swaps(&stuff->length, n);
2289706f2543Smrg    swapl(&stuff->gsid, n);
2290706f2543Smrg    swapl(&stuff->format, n);
2291706f2543Smrg    return (*ProcRenderVector[stuff->renderReqType]) (client);
2292706f2543Smrg}
2293706f2543Smrg
2294706f2543Smrgstatic int
2295706f2543SmrgSProcRenderReferenceGlyphSet (ClientPtr client)
2296706f2543Smrg{
2297706f2543Smrg    register int n;
2298706f2543Smrg    REQUEST(xRenderReferenceGlyphSetReq);
2299706f2543Smrg    REQUEST_SIZE_MATCH(xRenderReferenceGlyphSetReq);
2300706f2543Smrg    swaps(&stuff->length, n);
2301706f2543Smrg    swapl(&stuff->gsid, n);
2302706f2543Smrg    swapl(&stuff->existing, n);
2303706f2543Smrg    return (*ProcRenderVector[stuff->renderReqType])  (client);
2304706f2543Smrg}
2305706f2543Smrg
2306706f2543Smrgstatic int
2307706f2543SmrgSProcRenderFreeGlyphSet (ClientPtr client)
2308706f2543Smrg{
2309706f2543Smrg    register int n;
2310706f2543Smrg    REQUEST(xRenderFreeGlyphSetReq);
2311706f2543Smrg    REQUEST_SIZE_MATCH(xRenderFreeGlyphSetReq);
2312706f2543Smrg    swaps(&stuff->length, n);
2313706f2543Smrg    swapl(&stuff->glyphset, n);
2314706f2543Smrg    return (*ProcRenderVector[stuff->renderReqType]) (client);
2315706f2543Smrg}
2316706f2543Smrg
2317706f2543Smrgstatic int
2318706f2543SmrgSProcRenderAddGlyphs (ClientPtr client)
2319706f2543Smrg{
2320706f2543Smrg    register int n;
2321706f2543Smrg    register int i;
2322706f2543Smrg    CARD32  *gids;
2323706f2543Smrg    void    *end;
2324706f2543Smrg    xGlyphInfo *gi;
2325706f2543Smrg    REQUEST(xRenderAddGlyphsReq);
2326706f2543Smrg    REQUEST_AT_LEAST_SIZE(xRenderAddGlyphsReq);
2327706f2543Smrg    swaps(&stuff->length, n);
2328706f2543Smrg    swapl(&stuff->glyphset, n);
2329706f2543Smrg    swapl(&stuff->nglyphs, n);
2330706f2543Smrg    if (stuff->nglyphs & 0xe0000000)
2331706f2543Smrg	return BadLength;
2332706f2543Smrg    end = (CARD8 *) stuff + (client->req_len << 2);
2333706f2543Smrg    gids = (CARD32 *) (stuff + 1);
2334706f2543Smrg    gi = (xGlyphInfo *) (gids + stuff->nglyphs);
2335706f2543Smrg    if ((char *) end - (char *) (gids + stuff->nglyphs) < 0)
2336706f2543Smrg	return BadLength;
2337706f2543Smrg    if ((char *) end - (char *) (gi + stuff->nglyphs) < 0)
2338706f2543Smrg	return BadLength;
2339706f2543Smrg    for (i = 0; i < stuff->nglyphs; i++)
2340706f2543Smrg    {
2341706f2543Smrg	swapl (&gids[i], n);
2342706f2543Smrg	swaps (&gi[i].width, n);
2343706f2543Smrg	swaps (&gi[i].height, n);
2344706f2543Smrg	swaps (&gi[i].x, n);
2345706f2543Smrg	swaps (&gi[i].y, n);
2346706f2543Smrg	swaps (&gi[i].xOff, n);
2347706f2543Smrg	swaps (&gi[i].yOff, n);
2348706f2543Smrg    }
2349706f2543Smrg    return (*ProcRenderVector[stuff->renderReqType]) (client);
2350706f2543Smrg}
2351706f2543Smrg
2352706f2543Smrgstatic int
2353706f2543SmrgSProcRenderAddGlyphsFromPicture (ClientPtr client)
2354706f2543Smrg{
2355706f2543Smrg    return BadImplementation;
2356706f2543Smrg}
2357706f2543Smrg
2358706f2543Smrgstatic int
2359706f2543SmrgSProcRenderFreeGlyphs (ClientPtr client)
2360706f2543Smrg{
2361706f2543Smrg    register int n;
2362706f2543Smrg    REQUEST(xRenderFreeGlyphsReq);
2363706f2543Smrg    REQUEST_AT_LEAST_SIZE(xRenderFreeGlyphsReq);
2364706f2543Smrg    swaps(&stuff->length, n);
2365706f2543Smrg    swapl(&stuff->glyphset, n);
2366706f2543Smrg    SwapRestL(stuff);
2367706f2543Smrg    return (*ProcRenderVector[stuff->renderReqType]) (client);
2368706f2543Smrg}
2369706f2543Smrg
2370706f2543Smrgstatic int
2371706f2543SmrgSProcRenderCompositeGlyphs (ClientPtr client)
2372706f2543Smrg{
2373706f2543Smrg    register int n;
2374706f2543Smrg    xGlyphElt	*elt;
2375706f2543Smrg    CARD8	*buffer;
2376706f2543Smrg    CARD8	*end;
2377706f2543Smrg    int		space;
2378706f2543Smrg    int		i;
2379706f2543Smrg    int		size;
2380706f2543Smrg
2381706f2543Smrg    REQUEST(xRenderCompositeGlyphsReq);
2382706f2543Smrg    REQUEST_AT_LEAST_SIZE(xRenderCompositeGlyphsReq);
2383706f2543Smrg
2384706f2543Smrg    switch (stuff->renderReqType) {
2385706f2543Smrg    default:			    size = 1; break;
2386706f2543Smrg    case X_RenderCompositeGlyphs16: size = 2; break;
2387706f2543Smrg    case X_RenderCompositeGlyphs32: size = 4; break;
2388706f2543Smrg    }
2389706f2543Smrg
2390706f2543Smrg    swaps(&stuff->length, n);
2391706f2543Smrg    swapl(&stuff->src, n);
2392706f2543Smrg    swapl(&stuff->dst, n);
2393706f2543Smrg    swapl(&stuff->maskFormat, n);
2394706f2543Smrg    swapl(&stuff->glyphset, n);
2395706f2543Smrg    swaps(&stuff->xSrc, n);
2396706f2543Smrg    swaps(&stuff->ySrc, n);
2397706f2543Smrg    buffer = (CARD8 *) (stuff + 1);
2398706f2543Smrg    end = (CARD8 *) stuff + (client->req_len << 2);
2399706f2543Smrg    while (buffer + sizeof (xGlyphElt) < end)
2400706f2543Smrg    {
2401706f2543Smrg	elt = (xGlyphElt *) buffer;
2402706f2543Smrg	buffer += sizeof (xGlyphElt);
2403706f2543Smrg
2404706f2543Smrg	swaps (&elt->deltax, n);
2405706f2543Smrg	swaps (&elt->deltay, n);
2406706f2543Smrg
2407706f2543Smrg	i = elt->len;
2408706f2543Smrg	if (i == 0xff)
2409706f2543Smrg	{
2410706f2543Smrg	    swapl (buffer, n);
2411706f2543Smrg	    buffer += 4;
2412706f2543Smrg	}
2413706f2543Smrg	else
2414706f2543Smrg	{
2415706f2543Smrg	    space = size * i;
2416706f2543Smrg	    switch (size) {
2417706f2543Smrg	    case 1:
2418706f2543Smrg		buffer += i;
2419706f2543Smrg		break;
2420706f2543Smrg	    case 2:
2421706f2543Smrg		while (i--)
2422706f2543Smrg		{
2423706f2543Smrg		    swaps (buffer, n);
2424706f2543Smrg		    buffer += 2;
2425706f2543Smrg		}
2426706f2543Smrg		break;
2427706f2543Smrg	    case 4:
2428706f2543Smrg		while (i--)
2429706f2543Smrg		{
2430706f2543Smrg		    swapl (buffer, n);
2431706f2543Smrg		    buffer += 4;
2432706f2543Smrg		}
2433706f2543Smrg		break;
2434706f2543Smrg	    }
2435706f2543Smrg	    if (space & 3)
2436706f2543Smrg		buffer += 4 - (space & 3);
2437706f2543Smrg	}
2438706f2543Smrg    }
2439706f2543Smrg    return (*ProcRenderVector[stuff->renderReqType]) (client);
2440706f2543Smrg}
2441706f2543Smrg
2442706f2543Smrgstatic int
2443706f2543SmrgSProcRenderFillRectangles (ClientPtr client)
2444706f2543Smrg{
2445706f2543Smrg    register int n;
2446706f2543Smrg    REQUEST(xRenderFillRectanglesReq);
2447706f2543Smrg
2448706f2543Smrg    REQUEST_AT_LEAST_SIZE (xRenderFillRectanglesReq);
2449706f2543Smrg    swaps(&stuff->length, n);
2450706f2543Smrg    swapl(&stuff->dst, n);
2451706f2543Smrg    swaps(&stuff->color.red, n);
2452706f2543Smrg    swaps(&stuff->color.green, n);
2453706f2543Smrg    swaps(&stuff->color.blue, n);
2454706f2543Smrg    swaps(&stuff->color.alpha, n);
2455706f2543Smrg    SwapRestS(stuff);
2456706f2543Smrg    return (*ProcRenderVector[stuff->renderReqType]) (client);
2457706f2543Smrg}
2458706f2543Smrg
2459706f2543Smrgstatic int
2460706f2543SmrgSProcRenderCreateCursor (ClientPtr client)
2461706f2543Smrg{
2462706f2543Smrg    register int n;
2463706f2543Smrg    REQUEST(xRenderCreateCursorReq);
2464706f2543Smrg    REQUEST_SIZE_MATCH (xRenderCreateCursorReq);
2465706f2543Smrg
2466706f2543Smrg    swaps(&stuff->length, n);
2467706f2543Smrg    swapl(&stuff->cid, n);
2468706f2543Smrg    swapl(&stuff->src, n);
2469706f2543Smrg    swaps(&stuff->x, n);
2470706f2543Smrg    swaps(&stuff->y, n);
2471706f2543Smrg    return (*ProcRenderVector[stuff->renderReqType]) (client);
2472706f2543Smrg}
2473706f2543Smrg
2474706f2543Smrgstatic int
2475706f2543SmrgSProcRenderSetPictureTransform (ClientPtr client)
2476706f2543Smrg{
2477706f2543Smrg    register int n;
2478706f2543Smrg    REQUEST(xRenderSetPictureTransformReq);
2479706f2543Smrg    REQUEST_SIZE_MATCH(xRenderSetPictureTransformReq);
2480706f2543Smrg
2481706f2543Smrg    swaps(&stuff->length, n);
2482706f2543Smrg    swapl(&stuff->picture, n);
2483706f2543Smrg    swapl(&stuff->transform.matrix11, n);
2484706f2543Smrg    swapl(&stuff->transform.matrix12, n);
2485706f2543Smrg    swapl(&stuff->transform.matrix13, n);
2486706f2543Smrg    swapl(&stuff->transform.matrix21, n);
2487706f2543Smrg    swapl(&stuff->transform.matrix22, n);
2488706f2543Smrg    swapl(&stuff->transform.matrix23, n);
2489706f2543Smrg    swapl(&stuff->transform.matrix31, n);
2490706f2543Smrg    swapl(&stuff->transform.matrix32, n);
2491706f2543Smrg    swapl(&stuff->transform.matrix33, n);
2492706f2543Smrg    return (*ProcRenderVector[stuff->renderReqType]) (client);
2493706f2543Smrg}
2494706f2543Smrg
2495706f2543Smrgstatic int
2496706f2543SmrgSProcRenderQueryFilters (ClientPtr client)
2497706f2543Smrg{
2498706f2543Smrg    register int n;
2499706f2543Smrg    REQUEST (xRenderQueryFiltersReq);
2500706f2543Smrg    REQUEST_SIZE_MATCH (xRenderQueryFiltersReq);
2501706f2543Smrg
2502706f2543Smrg    swaps(&stuff->length, n);
2503706f2543Smrg    swapl(&stuff->drawable, n);
2504706f2543Smrg    return (*ProcRenderVector[stuff->renderReqType]) (client);
2505706f2543Smrg}
2506706f2543Smrg
2507706f2543Smrgstatic int
2508706f2543SmrgSProcRenderSetPictureFilter (ClientPtr client)
2509706f2543Smrg{
2510706f2543Smrg    register int n;
2511706f2543Smrg    REQUEST (xRenderSetPictureFilterReq);
2512706f2543Smrg    REQUEST_AT_LEAST_SIZE (xRenderSetPictureFilterReq);
2513706f2543Smrg
2514706f2543Smrg    swaps(&stuff->length, n);
2515706f2543Smrg    swapl(&stuff->picture, n);
2516706f2543Smrg    swaps(&stuff->nbytes, n);
2517706f2543Smrg    return (*ProcRenderVector[stuff->renderReqType]) (client);
2518706f2543Smrg}
2519706f2543Smrg
2520706f2543Smrgstatic int
2521706f2543SmrgSProcRenderCreateAnimCursor (ClientPtr client)
2522706f2543Smrg{
2523706f2543Smrg    register int n;
2524706f2543Smrg    REQUEST (xRenderCreateAnimCursorReq);
2525706f2543Smrg    REQUEST_AT_LEAST_SIZE (xRenderCreateAnimCursorReq);
2526706f2543Smrg
2527706f2543Smrg    swaps(&stuff->length, n);
2528706f2543Smrg    swapl(&stuff->cid, n);
2529706f2543Smrg    SwapRestL(stuff);
2530706f2543Smrg    return (*ProcRenderVector[stuff->renderReqType]) (client);
2531706f2543Smrg}
2532706f2543Smrg
2533706f2543Smrgstatic int
2534706f2543SmrgSProcRenderAddTraps (ClientPtr client)
2535706f2543Smrg{
2536706f2543Smrg    register int n;
2537706f2543Smrg    REQUEST (xRenderAddTrapsReq);
2538706f2543Smrg    REQUEST_AT_LEAST_SIZE (xRenderAddTrapsReq);
2539706f2543Smrg
2540706f2543Smrg    swaps(&stuff->length, n);
2541706f2543Smrg    swapl(&stuff->picture, n);
2542706f2543Smrg    swaps(&stuff->xOff, n);
2543706f2543Smrg    swaps(&stuff->yOff, n);
2544706f2543Smrg    SwapRestL(stuff);
2545706f2543Smrg    return (*ProcRenderVector[stuff->renderReqType]) (client);
2546706f2543Smrg}
2547706f2543Smrg
2548706f2543Smrgstatic int
2549706f2543SmrgSProcRenderCreateSolidFill(ClientPtr client)
2550706f2543Smrg{
2551706f2543Smrg    register int n;
2552706f2543Smrg    REQUEST (xRenderCreateSolidFillReq);
2553706f2543Smrg    REQUEST_AT_LEAST_SIZE (xRenderCreateSolidFillReq);
2554706f2543Smrg
2555706f2543Smrg    swaps(&stuff->length, n);
2556706f2543Smrg    swapl(&stuff->pid, n);
2557706f2543Smrg    swaps(&stuff->color.alpha, n);
2558706f2543Smrg    swaps(&stuff->color.red, n);
2559706f2543Smrg    swaps(&stuff->color.green, n);
2560706f2543Smrg    swaps(&stuff->color.blue, n);
2561706f2543Smrg    return (*ProcRenderVector[stuff->renderReqType]) (client);
2562706f2543Smrg}
2563706f2543Smrg
2564706f2543Smrgstatic void swapStops(void *stuff, int num)
2565706f2543Smrg{
2566706f2543Smrg    int i, n;
2567706f2543Smrg    CARD32 *stops;
2568706f2543Smrg    CARD16 *colors;
2569706f2543Smrg    stops = (CARD32 *)(stuff);
2570706f2543Smrg    for (i = 0; i < num; ++i) {
2571706f2543Smrg        swapl(stops, n);
2572706f2543Smrg        ++stops;
2573706f2543Smrg    }
2574706f2543Smrg    colors = (CARD16 *)(stops);
2575706f2543Smrg    for (i = 0; i < 4*num; ++i) {
2576706f2543Smrg        swaps(colors, n);
2577706f2543Smrg        ++colors;
2578706f2543Smrg    }
2579706f2543Smrg}
2580706f2543Smrg
2581706f2543Smrgstatic int
2582706f2543SmrgSProcRenderCreateLinearGradient (ClientPtr client)
2583706f2543Smrg{
2584706f2543Smrg    register int n;
2585706f2543Smrg    int len;
2586706f2543Smrg    REQUEST (xRenderCreateLinearGradientReq);
2587706f2543Smrg    REQUEST_AT_LEAST_SIZE (xRenderCreateLinearGradientReq);
2588706f2543Smrg
2589706f2543Smrg    swaps(&stuff->length, n);
2590706f2543Smrg    swapl(&stuff->pid, n);
2591706f2543Smrg    swapl(&stuff->p1.x, n);
2592706f2543Smrg    swapl(&stuff->p1.y, n);
2593706f2543Smrg    swapl(&stuff->p2.x, n);
2594706f2543Smrg    swapl(&stuff->p2.y, n);
2595706f2543Smrg    swapl(&stuff->nStops, n);
2596706f2543Smrg
2597706f2543Smrg    len = (client->req_len << 2) - sizeof(xRenderCreateLinearGradientReq);
2598706f2543Smrg    if (stuff->nStops > UINT32_MAX/(sizeof(xFixed) + sizeof(xRenderColor)))
2599706f2543Smrg	return BadLength;
2600706f2543Smrg    if (len != stuff->nStops*(sizeof(xFixed) + sizeof(xRenderColor)))
2601706f2543Smrg        return BadLength;
2602706f2543Smrg
2603706f2543Smrg    swapStops(stuff+1, stuff->nStops);
2604706f2543Smrg
2605706f2543Smrg    return (*ProcRenderVector[stuff->renderReqType]) (client);
2606706f2543Smrg}
2607706f2543Smrg
2608706f2543Smrgstatic int
2609706f2543SmrgSProcRenderCreateRadialGradient (ClientPtr client)
2610706f2543Smrg{
2611706f2543Smrg    register int n;
2612706f2543Smrg    int len;
2613706f2543Smrg    REQUEST (xRenderCreateRadialGradientReq);
2614706f2543Smrg    REQUEST_AT_LEAST_SIZE (xRenderCreateRadialGradientReq);
2615706f2543Smrg
2616706f2543Smrg    swaps(&stuff->length, n);
2617706f2543Smrg    swapl(&stuff->pid, n);
2618706f2543Smrg    swapl(&stuff->inner.x, n);
2619706f2543Smrg    swapl(&stuff->inner.y, n);
2620706f2543Smrg    swapl(&stuff->outer.x, n);
2621706f2543Smrg    swapl(&stuff->outer.y, n);
2622706f2543Smrg    swapl(&stuff->inner_radius, n);
2623706f2543Smrg    swapl(&stuff->outer_radius, n);
2624706f2543Smrg    swapl(&stuff->nStops, n);
2625706f2543Smrg
2626706f2543Smrg    len = (client->req_len << 2) - sizeof(xRenderCreateRadialGradientReq);
2627706f2543Smrg    if (stuff->nStops > UINT32_MAX/(sizeof(xFixed) + sizeof(xRenderColor)))
2628706f2543Smrg	return BadLength;
2629706f2543Smrg    if (len != stuff->nStops*(sizeof(xFixed) + sizeof(xRenderColor)))
2630706f2543Smrg        return BadLength;
2631706f2543Smrg
2632706f2543Smrg    swapStops(stuff+1, stuff->nStops);
2633706f2543Smrg
2634706f2543Smrg    return (*ProcRenderVector[stuff->renderReqType]) (client);
2635706f2543Smrg}
2636706f2543Smrg
2637706f2543Smrgstatic int
2638706f2543SmrgSProcRenderCreateConicalGradient (ClientPtr client)
2639706f2543Smrg{
2640706f2543Smrg    register int n;
2641706f2543Smrg    int len;
2642706f2543Smrg    REQUEST (xRenderCreateConicalGradientReq);
2643706f2543Smrg    REQUEST_AT_LEAST_SIZE (xRenderCreateConicalGradientReq);
2644706f2543Smrg
2645706f2543Smrg    swaps(&stuff->length, n);
2646706f2543Smrg    swapl(&stuff->pid, n);
2647706f2543Smrg    swapl(&stuff->center.x, n);
2648706f2543Smrg    swapl(&stuff->center.y, n);
2649706f2543Smrg    swapl(&stuff->angle, n);
2650706f2543Smrg    swapl(&stuff->nStops, n);
2651706f2543Smrg
2652706f2543Smrg    len = (client->req_len << 2) - sizeof(xRenderCreateConicalGradientReq);
2653706f2543Smrg    if (stuff->nStops > UINT32_MAX/(sizeof(xFixed) + sizeof(xRenderColor)))
2654706f2543Smrg	return BadLength;
2655706f2543Smrg    if (len != stuff->nStops*(sizeof(xFixed) + sizeof(xRenderColor)))
2656706f2543Smrg        return BadLength;
2657706f2543Smrg
2658706f2543Smrg    swapStops(stuff+1, stuff->nStops);
2659706f2543Smrg
2660706f2543Smrg    return (*ProcRenderVector[stuff->renderReqType]) (client);
2661706f2543Smrg}
2662706f2543Smrg
2663706f2543Smrgstatic int
2664706f2543SmrgSProcRenderDispatch (ClientPtr client)
2665706f2543Smrg{
2666706f2543Smrg    REQUEST(xReq);
2667706f2543Smrg
2668706f2543Smrg    if (stuff->data < RenderNumberRequests)
2669706f2543Smrg	return (*SProcRenderVector[stuff->data]) (client);
2670706f2543Smrg    else
2671706f2543Smrg	return BadRequest;
2672706f2543Smrg}
2673706f2543Smrg
2674706f2543Smrg#ifdef PANORAMIX
2675706f2543Smrg#define VERIFY_XIN_PICTURE(pPicture, pid, client, mode) {\
2676706f2543Smrg    int rc = dixLookupResourceByType((pointer *)&(pPicture), pid,\
2677706f2543Smrg                                     XRT_PICTURE, client, mode);\
2678706f2543Smrg    if (rc != Success)\
2679706f2543Smrg	return rc;\
2680706f2543Smrg}
2681706f2543Smrg
2682706f2543Smrg#define VERIFY_XIN_ALPHA(pPicture, pid, client, mode) {\
2683706f2543Smrg    if (pid == None) \
2684706f2543Smrg	pPicture = 0; \
2685706f2543Smrg    else { \
2686706f2543Smrg	VERIFY_XIN_PICTURE(pPicture, pid, client, mode); \
2687706f2543Smrg    } \
2688706f2543Smrg} \
2689706f2543Smrg
2690706f2543Smrgint	    (*PanoramiXSaveRenderVector[RenderNumberRequests])(ClientPtr);
2691706f2543Smrg
2692706f2543Smrgstatic int
2693706f2543SmrgPanoramiXRenderCreatePicture (ClientPtr client)
2694706f2543Smrg{
2695706f2543Smrg    REQUEST(xRenderCreatePictureReq);
2696706f2543Smrg    PanoramiXRes    *refDraw, *newPict;
2697706f2543Smrg    int		    result, j;
2698706f2543Smrg
2699706f2543Smrg    REQUEST_AT_LEAST_SIZE(xRenderCreatePictureReq);
2700706f2543Smrg    result = dixLookupResourceByClass((pointer *)&refDraw, stuff->drawable,
2701706f2543Smrg				      XRC_DRAWABLE, client, DixWriteAccess);
2702706f2543Smrg    if (result != Success)
2703706f2543Smrg	return (result == BadValue) ? BadDrawable : result;
2704706f2543Smrg    if(!(newPict = (PanoramiXRes *) malloc(sizeof(PanoramiXRes))))
2705706f2543Smrg	return BadAlloc;
2706706f2543Smrg    newPict->type = XRT_PICTURE;
2707706f2543Smrg    newPict->info[0].id = stuff->pid;
2708706f2543Smrg
2709706f2543Smrg    if (refDraw->type == XRT_WINDOW &&
2710706f2543Smrg	stuff->drawable == screenInfo.screens[0]->root->drawable.id)
2711706f2543Smrg    {
2712706f2543Smrg	newPict->u.pict.root = TRUE;
2713706f2543Smrg    }
2714706f2543Smrg    else
2715706f2543Smrg	newPict->u.pict.root = FALSE;
2716706f2543Smrg
2717706f2543Smrg    for(j = 1; j < PanoramiXNumScreens; j++)
2718706f2543Smrg	newPict->info[j].id = FakeClientID(client->index);
2719706f2543Smrg
2720706f2543Smrg    FOR_NSCREENS_BACKWARD(j) {
2721706f2543Smrg	stuff->pid = newPict->info[j].id;
2722706f2543Smrg	stuff->drawable = refDraw->info[j].id;
2723706f2543Smrg	result = (*PanoramiXSaveRenderVector[X_RenderCreatePicture]) (client);
2724706f2543Smrg	if(result != Success) break;
2725706f2543Smrg    }
2726706f2543Smrg
2727706f2543Smrg    if (result == Success)
2728706f2543Smrg	AddResource(newPict->info[0].id, XRT_PICTURE, newPict);
2729706f2543Smrg    else
2730706f2543Smrg	free(newPict);
2731706f2543Smrg
2732706f2543Smrg    return result;
2733706f2543Smrg}
2734706f2543Smrg
2735706f2543Smrgstatic int
2736706f2543SmrgPanoramiXRenderChangePicture (ClientPtr client)
2737706f2543Smrg{
2738706f2543Smrg    PanoramiXRes    *pict;
2739706f2543Smrg    int		    result = Success, j;
2740706f2543Smrg    REQUEST(xRenderChangePictureReq);
2741706f2543Smrg
2742706f2543Smrg    REQUEST_AT_LEAST_SIZE(xRenderChangePictureReq);
2743706f2543Smrg
2744706f2543Smrg    VERIFY_XIN_PICTURE(pict, stuff->picture, client, DixWriteAccess);
2745706f2543Smrg
2746706f2543Smrg    FOR_NSCREENS_BACKWARD(j) {
2747706f2543Smrg        stuff->picture = pict->info[j].id;
2748706f2543Smrg        result = (*PanoramiXSaveRenderVector[X_RenderChangePicture]) (client);
2749706f2543Smrg        if(result != Success) break;
2750706f2543Smrg    }
2751706f2543Smrg
2752706f2543Smrg    return result;
2753706f2543Smrg}
2754706f2543Smrg
2755706f2543Smrgstatic int
2756706f2543SmrgPanoramiXRenderSetPictureClipRectangles (ClientPtr client)
2757706f2543Smrg{
2758706f2543Smrg    REQUEST(xRenderSetPictureClipRectanglesReq);
2759706f2543Smrg    int		    result = Success, j;
2760706f2543Smrg    PanoramiXRes    *pict;
2761706f2543Smrg
2762706f2543Smrg    REQUEST_AT_LEAST_SIZE(xRenderSetPictureClipRectanglesReq);
2763706f2543Smrg
2764706f2543Smrg    VERIFY_XIN_PICTURE(pict, stuff->picture, client, DixWriteAccess);
2765706f2543Smrg
2766706f2543Smrg    FOR_NSCREENS_BACKWARD(j) {
2767706f2543Smrg        stuff->picture = pict->info[j].id;
2768706f2543Smrg        result = (*PanoramiXSaveRenderVector[X_RenderSetPictureClipRectangles]) (client);
2769706f2543Smrg        if(result != Success) break;
2770706f2543Smrg    }
2771706f2543Smrg
2772706f2543Smrg    return result;
2773706f2543Smrg}
2774706f2543Smrg
2775706f2543Smrgstatic int
2776706f2543SmrgPanoramiXRenderSetPictureTransform (ClientPtr client)
2777706f2543Smrg{
2778706f2543Smrg    REQUEST(xRenderSetPictureTransformReq);
2779706f2543Smrg    int		    result = Success, j;
2780706f2543Smrg    PanoramiXRes    *pict;
2781706f2543Smrg
2782706f2543Smrg    REQUEST_AT_LEAST_SIZE(xRenderSetPictureTransformReq);
2783706f2543Smrg
2784706f2543Smrg    VERIFY_XIN_PICTURE(pict, stuff->picture, client, DixWriteAccess);
2785706f2543Smrg
2786706f2543Smrg    FOR_NSCREENS_BACKWARD(j) {
2787706f2543Smrg        stuff->picture = pict->info[j].id;
2788706f2543Smrg        result = (*PanoramiXSaveRenderVector[X_RenderSetPictureTransform]) (client);
2789706f2543Smrg        if(result != Success) break;
2790706f2543Smrg    }
2791706f2543Smrg
2792706f2543Smrg    return result;
2793706f2543Smrg}
2794706f2543Smrg
2795706f2543Smrgstatic int
2796706f2543SmrgPanoramiXRenderSetPictureFilter (ClientPtr client)
2797706f2543Smrg{
2798706f2543Smrg    REQUEST(xRenderSetPictureFilterReq);
2799706f2543Smrg    int		    result = Success, j;
2800706f2543Smrg    PanoramiXRes    *pict;
2801706f2543Smrg
2802706f2543Smrg    REQUEST_AT_LEAST_SIZE(xRenderSetPictureFilterReq);
2803706f2543Smrg
2804706f2543Smrg    VERIFY_XIN_PICTURE(pict, stuff->picture, client, DixWriteAccess);
2805706f2543Smrg
2806706f2543Smrg    FOR_NSCREENS_BACKWARD(j) {
2807706f2543Smrg        stuff->picture = pict->info[j].id;
2808706f2543Smrg        result = (*PanoramiXSaveRenderVector[X_RenderSetPictureFilter]) (client);
2809706f2543Smrg        if(result != Success) break;
2810706f2543Smrg    }
2811706f2543Smrg
2812706f2543Smrg    return result;
2813706f2543Smrg}
2814706f2543Smrg
2815706f2543Smrgstatic int
2816706f2543SmrgPanoramiXRenderFreePicture (ClientPtr client)
2817706f2543Smrg{
2818706f2543Smrg    PanoramiXRes *pict;
2819706f2543Smrg    int         result = Success, j;
2820706f2543Smrg    REQUEST(xRenderFreePictureReq);
2821706f2543Smrg
2822706f2543Smrg    REQUEST_SIZE_MATCH(xRenderFreePictureReq);
2823706f2543Smrg
2824706f2543Smrg    client->errorValue = stuff->picture;
2825706f2543Smrg
2826706f2543Smrg    VERIFY_XIN_PICTURE(pict, stuff->picture, client, DixDestroyAccess);
2827706f2543Smrg
2828706f2543Smrg
2829706f2543Smrg    FOR_NSCREENS_BACKWARD(j) {
2830706f2543Smrg	stuff->picture = pict->info[j].id;
2831706f2543Smrg	result = (*PanoramiXSaveRenderVector[X_RenderFreePicture]) (client);
2832706f2543Smrg	if(result != Success) break;
2833706f2543Smrg    }
2834706f2543Smrg
2835706f2543Smrg    /* Since ProcRenderFreePicture is using FreeResource, it will free
2836706f2543Smrg	our resource for us on the last pass through the loop above */
2837706f2543Smrg
2838706f2543Smrg    return result;
2839706f2543Smrg}
2840706f2543Smrg
2841706f2543Smrgstatic int
2842706f2543SmrgPanoramiXRenderComposite (ClientPtr client)
2843706f2543Smrg{
2844706f2543Smrg    PanoramiXRes	*src, *msk, *dst;
2845706f2543Smrg    int			result = Success, j;
2846706f2543Smrg    xRenderCompositeReq	orig;
2847706f2543Smrg    REQUEST(xRenderCompositeReq);
2848706f2543Smrg
2849706f2543Smrg    REQUEST_SIZE_MATCH(xRenderCompositeReq);
2850706f2543Smrg
2851706f2543Smrg    VERIFY_XIN_PICTURE (src, stuff->src, client, DixReadAccess);
2852706f2543Smrg    VERIFY_XIN_ALPHA (msk, stuff->mask, client, DixReadAccess);
2853706f2543Smrg    VERIFY_XIN_PICTURE (dst, stuff->dst, client, DixWriteAccess);
2854706f2543Smrg
2855706f2543Smrg    orig = *stuff;
2856706f2543Smrg
2857706f2543Smrg    FOR_NSCREENS_FORWARD(j) {
2858706f2543Smrg	stuff->src = src->info[j].id;
2859706f2543Smrg	if (src->u.pict.root)
2860706f2543Smrg	{
2861706f2543Smrg	    stuff->xSrc = orig.xSrc - screenInfo.screens[j]->x;
2862706f2543Smrg	    stuff->ySrc = orig.ySrc - screenInfo.screens[j]->y;
2863706f2543Smrg	}
2864706f2543Smrg	stuff->dst = dst->info[j].id;
2865706f2543Smrg	if (dst->u.pict.root)
2866706f2543Smrg	{
2867706f2543Smrg	    stuff->xDst = orig.xDst - screenInfo.screens[j]->x;
2868706f2543Smrg	    stuff->yDst = orig.yDst - screenInfo.screens[j]->y;
2869706f2543Smrg	}
2870706f2543Smrg	if (msk)
2871706f2543Smrg	{
2872706f2543Smrg	    stuff->mask = msk->info[j].id;
2873706f2543Smrg	    if (msk->u.pict.root)
2874706f2543Smrg	    {
2875706f2543Smrg		stuff->xMask = orig.xMask - screenInfo.screens[j]->x;
2876706f2543Smrg		stuff->yMask = orig.yMask - screenInfo.screens[j]->y;
2877706f2543Smrg	    }
2878706f2543Smrg	}
2879706f2543Smrg	result = (*PanoramiXSaveRenderVector[X_RenderComposite]) (client);
2880706f2543Smrg	if(result != Success) break;
2881706f2543Smrg    }
2882706f2543Smrg
2883706f2543Smrg    return result;
2884706f2543Smrg}
2885706f2543Smrg
2886706f2543Smrgstatic int
2887706f2543SmrgPanoramiXRenderCompositeGlyphs (ClientPtr client)
2888706f2543Smrg{
2889706f2543Smrg    PanoramiXRes    *src, *dst;
2890706f2543Smrg    int		    result = Success, j;
2891706f2543Smrg    REQUEST(xRenderCompositeGlyphsReq);
2892706f2543Smrg    xGlyphElt	    origElt, *elt;
2893706f2543Smrg    INT16	    xSrc, ySrc;
2894706f2543Smrg
2895706f2543Smrg    REQUEST_AT_LEAST_SIZE(xRenderCompositeGlyphsReq);
2896706f2543Smrg    VERIFY_XIN_PICTURE (src, stuff->src, client, DixReadAccess);
2897706f2543Smrg    VERIFY_XIN_PICTURE (dst, stuff->dst, client, DixWriteAccess);
2898706f2543Smrg
2899706f2543Smrg    if (client->req_len << 2 >= (sizeof (xRenderCompositeGlyphsReq) +
2900706f2543Smrg				 sizeof (xGlyphElt)))
2901706f2543Smrg    {
2902706f2543Smrg	elt = (xGlyphElt *) (stuff + 1);
2903706f2543Smrg	origElt = *elt;
2904706f2543Smrg	xSrc = stuff->xSrc;
2905706f2543Smrg	ySrc = stuff->ySrc;
2906706f2543Smrg	FOR_NSCREENS_FORWARD(j) {
2907706f2543Smrg	    stuff->src = src->info[j].id;
2908706f2543Smrg	    if (src->u.pict.root)
2909706f2543Smrg	    {
2910706f2543Smrg		stuff->xSrc = xSrc - screenInfo.screens[j]->x;
2911706f2543Smrg		stuff->ySrc = ySrc - screenInfo.screens[j]->y;
2912706f2543Smrg	    }
2913706f2543Smrg	    stuff->dst = dst->info[j].id;
2914706f2543Smrg	    if (dst->u.pict.root)
2915706f2543Smrg	    {
2916706f2543Smrg		elt->deltax = origElt.deltax - screenInfo.screens[j]->x;
2917706f2543Smrg		elt->deltay = origElt.deltay - screenInfo.screens[j]->y;
2918706f2543Smrg	    }
2919706f2543Smrg	    result = (*PanoramiXSaveRenderVector[stuff->renderReqType]) (client);
2920706f2543Smrg	    if(result != Success) break;
2921706f2543Smrg	}
2922706f2543Smrg    }
2923706f2543Smrg
2924706f2543Smrg    return result;
2925706f2543Smrg}
2926706f2543Smrg
2927706f2543Smrgstatic int
2928706f2543SmrgPanoramiXRenderFillRectangles (ClientPtr client)
2929706f2543Smrg{
2930706f2543Smrg    PanoramiXRes    *dst;
2931706f2543Smrg    int		    result = Success, j;
2932706f2543Smrg    REQUEST(xRenderFillRectanglesReq);
2933706f2543Smrg    char	    *extra;
2934706f2543Smrg    int		    extra_len;
2935706f2543Smrg
2936706f2543Smrg    REQUEST_AT_LEAST_SIZE (xRenderFillRectanglesReq);
2937706f2543Smrg    VERIFY_XIN_PICTURE (dst, stuff->dst, client, DixWriteAccess);
2938706f2543Smrg    extra_len = (client->req_len << 2) - sizeof (xRenderFillRectanglesReq);
2939706f2543Smrg    if (extra_len &&
2940706f2543Smrg	(extra = (char *) malloc(extra_len)))
2941706f2543Smrg    {
2942706f2543Smrg	memcpy (extra, stuff + 1, extra_len);
2943706f2543Smrg	FOR_NSCREENS_FORWARD(j) {
2944706f2543Smrg	    if (j) memcpy (stuff + 1, extra, extra_len);
2945706f2543Smrg	    if (dst->u.pict.root)
2946706f2543Smrg	    {
2947706f2543Smrg		int x_off = screenInfo.screens[j]->x;
2948706f2543Smrg		int y_off = screenInfo.screens[j]->y;
2949706f2543Smrg
2950706f2543Smrg		if(x_off || y_off) {
2951706f2543Smrg		    xRectangle	*rects = (xRectangle *) (stuff + 1);
2952706f2543Smrg		    int		i = extra_len / sizeof (xRectangle);
2953706f2543Smrg
2954706f2543Smrg		    while (i--)
2955706f2543Smrg		    {
2956706f2543Smrg			rects->x -= x_off;
2957706f2543Smrg			rects->y -= y_off;
2958706f2543Smrg			rects++;
2959706f2543Smrg		    }
2960706f2543Smrg		}
2961706f2543Smrg	    }
2962706f2543Smrg	    stuff->dst = dst->info[j].id;
2963706f2543Smrg	    result = (*PanoramiXSaveRenderVector[X_RenderFillRectangles]) (client);
2964706f2543Smrg	    if(result != Success) break;
2965706f2543Smrg	}
2966706f2543Smrg	free(extra);
2967706f2543Smrg    }
2968706f2543Smrg
2969706f2543Smrg    return result;
2970706f2543Smrg}
2971706f2543Smrg
2972706f2543Smrgstatic int
2973706f2543SmrgPanoramiXRenderTrapezoids(ClientPtr client)
2974706f2543Smrg{
2975706f2543Smrg    PanoramiXRes        *src, *dst;
2976706f2543Smrg    int                 result = Success, j;
2977706f2543Smrg    REQUEST(xRenderTrapezoidsReq);
2978706f2543Smrg    char		*extra;
2979706f2543Smrg    int			extra_len;
2980706f2543Smrg
2981706f2543Smrg    REQUEST_AT_LEAST_SIZE (xRenderTrapezoidsReq);
2982706f2543Smrg
2983706f2543Smrg    VERIFY_XIN_PICTURE (src, stuff->src, client, DixReadAccess);
2984706f2543Smrg    VERIFY_XIN_PICTURE (dst, stuff->dst, client, DixWriteAccess);
2985706f2543Smrg
2986706f2543Smrg    extra_len = (client->req_len << 2) - sizeof (xRenderTrapezoidsReq);
2987706f2543Smrg
2988706f2543Smrg    if (extra_len &&
2989706f2543Smrg	(extra = (char *) malloc(extra_len))) {
2990706f2543Smrg	memcpy (extra, stuff + 1, extra_len);
2991706f2543Smrg
2992706f2543Smrg	FOR_NSCREENS_FORWARD(j) {
2993706f2543Smrg	    if (j) memcpy (stuff + 1, extra, extra_len);
2994706f2543Smrg	    if (dst->u.pict.root) {
2995706f2543Smrg		int x_off = screenInfo.screens[j]->x;
2996706f2543Smrg		int y_off = screenInfo.screens[j]->y;
2997706f2543Smrg
2998706f2543Smrg		if(x_off || y_off) {
2999706f2543Smrg                    xTrapezoid  *trap = (xTrapezoid *) (stuff + 1);
3000706f2543Smrg		    int         i = extra_len / sizeof (xTrapezoid);
3001706f2543Smrg
3002706f2543Smrg		    while (i--) {
3003706f2543Smrg			trap->top -= y_off;
3004706f2543Smrg			trap->bottom -= y_off;
3005706f2543Smrg			trap->left.p1.x -= x_off;
3006706f2543Smrg			trap->left.p1.y -= y_off;
3007706f2543Smrg			trap->left.p2.x -= x_off;
3008706f2543Smrg			trap->left.p2.y -= y_off;
3009706f2543Smrg			trap->right.p1.x -= x_off;
3010706f2543Smrg			trap->right.p1.y -= y_off;
3011706f2543Smrg			trap->right.p2.x -= x_off;
3012706f2543Smrg			trap->right.p2.y -= y_off;
3013706f2543Smrg			trap++;
3014706f2543Smrg		    }
3015706f2543Smrg		}
3016706f2543Smrg	    }
3017706f2543Smrg
3018706f2543Smrg            stuff->src = src->info[j].id;
3019706f2543Smrg            stuff->dst = dst->info[j].id;
3020706f2543Smrg	    result =
3021706f2543Smrg		(*PanoramiXSaveRenderVector[X_RenderTrapezoids]) (client);
3022706f2543Smrg
3023706f2543Smrg	    if(result != Success) break;
3024706f2543Smrg	}
3025706f2543Smrg
3026706f2543Smrg        free(extra);
3027706f2543Smrg    }
3028706f2543Smrg
3029706f2543Smrg    return result;
3030706f2543Smrg}
3031706f2543Smrg
3032706f2543Smrgstatic int
3033706f2543SmrgPanoramiXRenderTriangles(ClientPtr client)
3034706f2543Smrg{
3035706f2543Smrg    PanoramiXRes        *src, *dst;
3036706f2543Smrg    int                 result = Success, j;
3037706f2543Smrg    REQUEST(xRenderTrianglesReq);
3038706f2543Smrg    char		*extra;
3039706f2543Smrg    int			extra_len;
3040706f2543Smrg
3041706f2543Smrg    REQUEST_AT_LEAST_SIZE (xRenderTrianglesReq);
3042706f2543Smrg
3043706f2543Smrg    VERIFY_XIN_PICTURE (src, stuff->src, client, DixReadAccess);
3044706f2543Smrg    VERIFY_XIN_PICTURE (dst, stuff->dst, client, DixWriteAccess);
3045706f2543Smrg
3046706f2543Smrg    extra_len = (client->req_len << 2) - sizeof (xRenderTrianglesReq);
3047706f2543Smrg
3048706f2543Smrg    if (extra_len &&
3049706f2543Smrg	(extra = (char *) malloc(extra_len))) {
3050706f2543Smrg	memcpy (extra, stuff + 1, extra_len);
3051706f2543Smrg
3052706f2543Smrg	FOR_NSCREENS_FORWARD(j) {
3053706f2543Smrg	    if (j) memcpy (stuff + 1, extra, extra_len);
3054706f2543Smrg	    if (dst->u.pict.root) {
3055706f2543Smrg		int x_off = screenInfo.screens[j]->x;
3056706f2543Smrg		int y_off = screenInfo.screens[j]->y;
3057706f2543Smrg
3058706f2543Smrg		if(x_off || y_off) {
3059706f2543Smrg                    xTriangle  *tri = (xTriangle *) (stuff + 1);
3060706f2543Smrg		    int         i = extra_len / sizeof (xTriangle);
3061706f2543Smrg
3062706f2543Smrg		    while (i--) {
3063706f2543Smrg			tri->p1.x -= x_off;
3064706f2543Smrg			tri->p1.y -= y_off;
3065706f2543Smrg			tri->p2.x -= x_off;
3066706f2543Smrg			tri->p2.y -= y_off;
3067706f2543Smrg			tri->p3.x -= x_off;
3068706f2543Smrg			tri->p3.y -= y_off;
3069706f2543Smrg			tri++;
3070706f2543Smrg		    }
3071706f2543Smrg		}
3072706f2543Smrg	    }
3073706f2543Smrg
3074706f2543Smrg            stuff->src = src->info[j].id;
3075706f2543Smrg            stuff->dst = dst->info[j].id;
3076706f2543Smrg	    result =
3077706f2543Smrg		(*PanoramiXSaveRenderVector[X_RenderTriangles]) (client);
3078706f2543Smrg
3079706f2543Smrg	    if(result != Success) break;
3080706f2543Smrg	}
3081706f2543Smrg
3082706f2543Smrg        free(extra);
3083706f2543Smrg    }
3084706f2543Smrg
3085706f2543Smrg    return result;
3086706f2543Smrg}
3087706f2543Smrg
3088706f2543Smrgstatic int
3089706f2543SmrgPanoramiXRenderTriStrip(ClientPtr client)
3090706f2543Smrg{
3091706f2543Smrg    PanoramiXRes        *src, *dst;
3092706f2543Smrg    int                 result = Success, j;
3093706f2543Smrg    REQUEST(xRenderTriStripReq);
3094706f2543Smrg    char		*extra;
3095706f2543Smrg    int			extra_len;
3096706f2543Smrg
3097706f2543Smrg    REQUEST_AT_LEAST_SIZE (xRenderTriStripReq);
3098706f2543Smrg
3099706f2543Smrg    VERIFY_XIN_PICTURE (src, stuff->src, client, DixReadAccess);
3100706f2543Smrg    VERIFY_XIN_PICTURE (dst, stuff->dst, client, DixWriteAccess);
3101706f2543Smrg
3102706f2543Smrg    extra_len = (client->req_len << 2) - sizeof (xRenderTriStripReq);
3103706f2543Smrg
3104706f2543Smrg    if (extra_len &&
3105706f2543Smrg	(extra = (char *) malloc(extra_len))) {
3106706f2543Smrg	memcpy (extra, stuff + 1, extra_len);
3107706f2543Smrg
3108706f2543Smrg	FOR_NSCREENS_FORWARD(j) {
3109706f2543Smrg	    if (j) memcpy (stuff + 1, extra, extra_len);
3110706f2543Smrg	    if (dst->u.pict.root) {
3111706f2543Smrg		int x_off = screenInfo.screens[j]->x;
3112706f2543Smrg		int y_off = screenInfo.screens[j]->y;
3113706f2543Smrg
3114706f2543Smrg		if(x_off || y_off) {
3115706f2543Smrg                    xPointFixed  *fixed = (xPointFixed *) (stuff + 1);
3116706f2543Smrg		    int         i = extra_len / sizeof (xPointFixed);
3117706f2543Smrg
3118706f2543Smrg		    while (i--) {
3119706f2543Smrg			fixed->x -= x_off;
3120706f2543Smrg			fixed->y -= y_off;
3121706f2543Smrg			fixed++;
3122706f2543Smrg		    }
3123706f2543Smrg		}
3124706f2543Smrg	    }
3125706f2543Smrg
3126706f2543Smrg            stuff->src = src->info[j].id;
3127706f2543Smrg            stuff->dst = dst->info[j].id;
3128706f2543Smrg	    result =
3129706f2543Smrg		(*PanoramiXSaveRenderVector[X_RenderTriStrip]) (client);
3130706f2543Smrg
3131706f2543Smrg	    if(result != Success) break;
3132706f2543Smrg	}
3133706f2543Smrg
3134706f2543Smrg        free(extra);
3135706f2543Smrg    }
3136706f2543Smrg
3137706f2543Smrg    return result;
3138706f2543Smrg}
3139706f2543Smrg
3140706f2543Smrgstatic int
3141706f2543SmrgPanoramiXRenderTriFan(ClientPtr client)
3142706f2543Smrg{
3143706f2543Smrg    PanoramiXRes        *src, *dst;
3144706f2543Smrg    int                 result = Success, j;
3145706f2543Smrg    REQUEST(xRenderTriFanReq);
3146706f2543Smrg    char		*extra;
3147706f2543Smrg    int			extra_len;
3148706f2543Smrg
3149706f2543Smrg    REQUEST_AT_LEAST_SIZE (xRenderTriFanReq);
3150706f2543Smrg
3151706f2543Smrg    VERIFY_XIN_PICTURE (src, stuff->src, client, DixReadAccess);
3152706f2543Smrg    VERIFY_XIN_PICTURE (dst, stuff->dst, client, DixWriteAccess);
3153706f2543Smrg
3154706f2543Smrg    extra_len = (client->req_len << 2) - sizeof (xRenderTriFanReq);
3155706f2543Smrg
3156706f2543Smrg    if (extra_len &&
3157706f2543Smrg	(extra = (char *) malloc(extra_len))) {
3158706f2543Smrg	memcpy (extra, stuff + 1, extra_len);
3159706f2543Smrg
3160706f2543Smrg	FOR_NSCREENS_FORWARD(j) {
3161706f2543Smrg	    if (j) memcpy (stuff + 1, extra, extra_len);
3162706f2543Smrg	    if (dst->u.pict.root) {
3163706f2543Smrg		int x_off = screenInfo.screens[j]->x;
3164706f2543Smrg		int y_off = screenInfo.screens[j]->y;
3165706f2543Smrg
3166706f2543Smrg		if(x_off || y_off) {
3167706f2543Smrg                    xPointFixed  *fixed = (xPointFixed *) (stuff + 1);
3168706f2543Smrg		    int         i = extra_len / sizeof (xPointFixed);
3169706f2543Smrg
3170706f2543Smrg		    while (i--) {
3171706f2543Smrg			fixed->x -= x_off;
3172706f2543Smrg			fixed->y -= y_off;
3173706f2543Smrg			fixed++;
3174706f2543Smrg		    }
3175706f2543Smrg		}
3176706f2543Smrg	    }
3177706f2543Smrg
3178706f2543Smrg            stuff->src = src->info[j].id;
3179706f2543Smrg            stuff->dst = dst->info[j].id;
3180706f2543Smrg	    result =
3181706f2543Smrg		(*PanoramiXSaveRenderVector[X_RenderTriFan]) (client);
3182706f2543Smrg
3183706f2543Smrg	    if(result != Success) break;
3184706f2543Smrg	}
3185706f2543Smrg
3186706f2543Smrg        free(extra);
3187706f2543Smrg    }
3188706f2543Smrg
3189706f2543Smrg    return result;
3190706f2543Smrg}
3191706f2543Smrg
3192706f2543Smrgstatic int
3193706f2543SmrgPanoramiXRenderAddTraps (ClientPtr client)
3194706f2543Smrg{
3195706f2543Smrg    PanoramiXRes    *picture;
3196706f2543Smrg    int		    result = Success, j;
3197706f2543Smrg    REQUEST(xRenderAddTrapsReq);
3198706f2543Smrg    char	    *extra;
3199706f2543Smrg    int		    extra_len;
3200706f2543Smrg    INT16    	    x_off, y_off;
3201706f2543Smrg
3202706f2543Smrg    REQUEST_AT_LEAST_SIZE (xRenderAddTrapsReq);
3203706f2543Smrg    VERIFY_XIN_PICTURE (picture, stuff->picture, client, DixWriteAccess);
3204706f2543Smrg    extra_len = (client->req_len << 2) - sizeof (xRenderAddTrapsReq);
3205706f2543Smrg    if (extra_len &&
3206706f2543Smrg	(extra = (char *) malloc(extra_len)))
3207706f2543Smrg    {
3208706f2543Smrg	memcpy (extra, stuff + 1, extra_len);
3209706f2543Smrg	x_off = stuff->xOff;
3210706f2543Smrg	y_off = stuff->yOff;
3211706f2543Smrg	FOR_NSCREENS_FORWARD(j) {
3212706f2543Smrg	    if (j) memcpy (stuff + 1, extra, extra_len);
3213706f2543Smrg	    stuff->picture = picture->info[j].id;
3214706f2543Smrg
3215706f2543Smrg	    if (picture->u.pict.root)
3216706f2543Smrg	    {
3217706f2543Smrg		stuff->xOff = x_off + screenInfo.screens[j]->x;
3218706f2543Smrg		stuff->yOff = y_off + screenInfo.screens[j]->y;
3219706f2543Smrg	    }
3220706f2543Smrg	    result = (*PanoramiXSaveRenderVector[X_RenderAddTraps]) (client);
3221706f2543Smrg	    if(result != Success) break;
3222706f2543Smrg	}
3223706f2543Smrg	free(extra);
3224706f2543Smrg    }
3225706f2543Smrg
3226706f2543Smrg    return result;
3227706f2543Smrg}
3228706f2543Smrg
3229706f2543Smrgstatic int
3230706f2543SmrgPanoramiXRenderCreateSolidFill (ClientPtr client)
3231706f2543Smrg{
3232706f2543Smrg    REQUEST(xRenderCreateSolidFillReq);
3233706f2543Smrg    PanoramiXRes    *newPict;
3234706f2543Smrg    int		    result = Success, j;
3235706f2543Smrg
3236706f2543Smrg    REQUEST_AT_LEAST_SIZE(xRenderCreateSolidFillReq);
3237706f2543Smrg
3238706f2543Smrg    if(!(newPict = (PanoramiXRes *) malloc(sizeof(PanoramiXRes))))
3239706f2543Smrg	return BadAlloc;
3240706f2543Smrg
3241706f2543Smrg    newPict->type = XRT_PICTURE;
3242706f2543Smrg    newPict->info[0].id = stuff->pid;
3243706f2543Smrg    newPict->u.pict.root = FALSE;
3244706f2543Smrg
3245706f2543Smrg    for(j = 1; j < PanoramiXNumScreens; j++)
3246706f2543Smrg	newPict->info[j].id = FakeClientID(client->index);
3247706f2543Smrg
3248706f2543Smrg    FOR_NSCREENS_BACKWARD(j) {
3249706f2543Smrg	stuff->pid = newPict->info[j].id;
3250706f2543Smrg	result = (*PanoramiXSaveRenderVector[X_RenderCreateSolidFill]) (client);
3251706f2543Smrg	if(result != Success) break;
3252706f2543Smrg    }
3253706f2543Smrg
3254706f2543Smrg    if (result == Success)
3255706f2543Smrg	AddResource(newPict->info[0].id, XRT_PICTURE, newPict);
3256706f2543Smrg    else
3257706f2543Smrg	free(newPict);
3258706f2543Smrg
3259706f2543Smrg    return result;
3260706f2543Smrg}
3261706f2543Smrg
3262706f2543Smrgstatic int
3263706f2543SmrgPanoramiXRenderCreateLinearGradient (ClientPtr client)
3264706f2543Smrg{
3265706f2543Smrg    REQUEST(xRenderCreateLinearGradientReq);
3266706f2543Smrg    PanoramiXRes    *newPict;
3267706f2543Smrg    int		    result = Success, j;
3268706f2543Smrg
3269706f2543Smrg    REQUEST_AT_LEAST_SIZE(xRenderCreateLinearGradientReq);
3270706f2543Smrg
3271706f2543Smrg    if(!(newPict = (PanoramiXRes *) malloc(sizeof(PanoramiXRes))))
3272706f2543Smrg	return BadAlloc;
3273706f2543Smrg
3274706f2543Smrg    newPict->type = XRT_PICTURE;
3275706f2543Smrg    newPict->info[0].id = stuff->pid;
3276706f2543Smrg    newPict->u.pict.root = FALSE;
3277706f2543Smrg
3278706f2543Smrg    for(j = 1; j < PanoramiXNumScreens; j++)
3279706f2543Smrg	newPict->info[j].id = FakeClientID(client->index);
3280706f2543Smrg
3281706f2543Smrg    FOR_NSCREENS_BACKWARD(j) {
3282706f2543Smrg	stuff->pid = newPict->info[j].id;
3283706f2543Smrg	result = (*PanoramiXSaveRenderVector[X_RenderCreateLinearGradient]) (client);
3284706f2543Smrg	if(result != Success) break;
3285706f2543Smrg    }
3286706f2543Smrg
3287706f2543Smrg    if (result == Success)
3288706f2543Smrg	AddResource(newPict->info[0].id, XRT_PICTURE, newPict);
3289706f2543Smrg    else
3290706f2543Smrg	free(newPict);
3291706f2543Smrg
3292706f2543Smrg    return result;
3293706f2543Smrg}
3294706f2543Smrg
3295706f2543Smrgstatic int
3296706f2543SmrgPanoramiXRenderCreateRadialGradient (ClientPtr client)
3297706f2543Smrg{
3298706f2543Smrg    REQUEST(xRenderCreateRadialGradientReq);
3299706f2543Smrg    PanoramiXRes    *newPict;
3300706f2543Smrg    int		    result = Success, j;
3301706f2543Smrg
3302706f2543Smrg    REQUEST_AT_LEAST_SIZE(xRenderCreateRadialGradientReq);
3303706f2543Smrg
3304706f2543Smrg    if(!(newPict = (PanoramiXRes *) malloc(sizeof(PanoramiXRes))))
3305706f2543Smrg	return BadAlloc;
3306706f2543Smrg
3307706f2543Smrg    newPict->type = XRT_PICTURE;
3308706f2543Smrg    newPict->info[0].id = stuff->pid;
3309706f2543Smrg    newPict->u.pict.root = FALSE;
3310706f2543Smrg
3311706f2543Smrg    for(j = 1; j < PanoramiXNumScreens; j++)
3312706f2543Smrg	newPict->info[j].id = FakeClientID(client->index);
3313706f2543Smrg
3314706f2543Smrg    FOR_NSCREENS_BACKWARD(j) {
3315706f2543Smrg	stuff->pid = newPict->info[j].id;
3316706f2543Smrg	result = (*PanoramiXSaveRenderVector[X_RenderCreateRadialGradient]) (client);
3317706f2543Smrg	if(result != Success) break;
3318706f2543Smrg    }
3319706f2543Smrg
3320706f2543Smrg    if (result == Success)
3321706f2543Smrg	AddResource(newPict->info[0].id, XRT_PICTURE, newPict);
3322706f2543Smrg    else
3323706f2543Smrg	free(newPict);
3324706f2543Smrg
3325706f2543Smrg    return result;
3326706f2543Smrg}
3327706f2543Smrg
3328706f2543Smrgstatic int
3329706f2543SmrgPanoramiXRenderCreateConicalGradient (ClientPtr client)
3330706f2543Smrg{
3331706f2543Smrg    REQUEST(xRenderCreateConicalGradientReq);
3332706f2543Smrg    PanoramiXRes    *newPict;
3333706f2543Smrg    int		    result = Success, j;
3334706f2543Smrg
3335706f2543Smrg    REQUEST_AT_LEAST_SIZE(xRenderCreateConicalGradientReq);
3336706f2543Smrg
3337706f2543Smrg    if(!(newPict = (PanoramiXRes *) malloc(sizeof(PanoramiXRes))))
3338706f2543Smrg	return BadAlloc;
3339706f2543Smrg
3340706f2543Smrg    newPict->type = XRT_PICTURE;
3341706f2543Smrg    newPict->info[0].id = stuff->pid;
3342706f2543Smrg    newPict->u.pict.root = FALSE;
3343706f2543Smrg
3344706f2543Smrg    for(j = 1; j < PanoramiXNumScreens; j++)
3345706f2543Smrg	newPict->info[j].id = FakeClientID(client->index);
3346706f2543Smrg
3347706f2543Smrg    FOR_NSCREENS_BACKWARD(j) {
3348706f2543Smrg	stuff->pid = newPict->info[j].id;
3349706f2543Smrg	result = (*PanoramiXSaveRenderVector[X_RenderCreateConicalGradient]) (client);
3350706f2543Smrg	if(result != Success) break;
3351706f2543Smrg    }
3352706f2543Smrg
3353706f2543Smrg    if (result == Success)
3354706f2543Smrg	AddResource(newPict->info[0].id, XRT_PICTURE, newPict);
3355706f2543Smrg    else
3356706f2543Smrg	free(newPict);
3357706f2543Smrg
3358706f2543Smrg    return result;
3359706f2543Smrg}
3360706f2543Smrg
3361706f2543Smrgvoid
3362706f2543SmrgPanoramiXRenderInit (void)
3363706f2543Smrg{
3364706f2543Smrg    int	    i;
3365706f2543Smrg
3366706f2543Smrg    XRT_PICTURE = CreateNewResourceType (XineramaDeleteResource,
3367706f2543Smrg					 "XineramaPicture");
3368706f2543Smrg    if (RenderErrBase)
3369706f2543Smrg	SetResourceTypeErrorValue(XRT_PICTURE, RenderErrBase + BadPicture);
3370706f2543Smrg    for (i = 0; i < RenderNumberRequests; i++)
3371706f2543Smrg	PanoramiXSaveRenderVector[i] = ProcRenderVector[i];
3372706f2543Smrg    /*
3373706f2543Smrg     * Stuff in Xinerama aware request processing hooks
3374706f2543Smrg     */
3375706f2543Smrg    ProcRenderVector[X_RenderCreatePicture] = PanoramiXRenderCreatePicture;
3376706f2543Smrg    ProcRenderVector[X_RenderChangePicture] = PanoramiXRenderChangePicture;
3377706f2543Smrg    ProcRenderVector[X_RenderSetPictureTransform] = PanoramiXRenderSetPictureTransform;
3378706f2543Smrg    ProcRenderVector[X_RenderSetPictureFilter] = PanoramiXRenderSetPictureFilter;
3379706f2543Smrg    ProcRenderVector[X_RenderSetPictureClipRectangles] = PanoramiXRenderSetPictureClipRectangles;
3380706f2543Smrg    ProcRenderVector[X_RenderFreePicture] = PanoramiXRenderFreePicture;
3381706f2543Smrg    ProcRenderVector[X_RenderComposite] = PanoramiXRenderComposite;
3382706f2543Smrg    ProcRenderVector[X_RenderCompositeGlyphs8] = PanoramiXRenderCompositeGlyphs;
3383706f2543Smrg    ProcRenderVector[X_RenderCompositeGlyphs16] = PanoramiXRenderCompositeGlyphs;
3384706f2543Smrg    ProcRenderVector[X_RenderCompositeGlyphs32] = PanoramiXRenderCompositeGlyphs;
3385706f2543Smrg    ProcRenderVector[X_RenderFillRectangles] = PanoramiXRenderFillRectangles;
3386706f2543Smrg
3387706f2543Smrg    ProcRenderVector[X_RenderTrapezoids] = PanoramiXRenderTrapezoids;
3388706f2543Smrg    ProcRenderVector[X_RenderTriangles] = PanoramiXRenderTriangles;
3389706f2543Smrg    ProcRenderVector[X_RenderTriStrip] = PanoramiXRenderTriStrip;
3390706f2543Smrg    ProcRenderVector[X_RenderTriFan] = PanoramiXRenderTriFan;
3391706f2543Smrg    ProcRenderVector[X_RenderAddTraps] = PanoramiXRenderAddTraps;
3392706f2543Smrg
3393706f2543Smrg    ProcRenderVector[X_RenderCreateSolidFill] = PanoramiXRenderCreateSolidFill;
3394706f2543Smrg    ProcRenderVector[X_RenderCreateLinearGradient] = PanoramiXRenderCreateLinearGradient;
3395706f2543Smrg    ProcRenderVector[X_RenderCreateRadialGradient] = PanoramiXRenderCreateRadialGradient;
3396706f2543Smrg    ProcRenderVector[X_RenderCreateConicalGradient] = PanoramiXRenderCreateConicalGradient;
3397706f2543Smrg}
3398706f2543Smrg
3399706f2543Smrgvoid
3400706f2543SmrgPanoramiXRenderReset (void)
3401706f2543Smrg{
3402706f2543Smrg    int	    i;
3403706f2543Smrg    for (i = 0; i < RenderNumberRequests; i++)
3404706f2543Smrg	ProcRenderVector[i] = PanoramiXSaveRenderVector[i];
3405706f2543Smrg    RenderErrBase = 0;
3406706f2543Smrg}
3407706f2543Smrg
3408706f2543Smrg#endif	/* PANORAMIX */
3409