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;
185148a68b89Smrg    if (nparams < 0)
185248a68b89Smrg	return BadLength;
185348a68b89Smrg
1854706f2543Smrg    result = SetPictureFilter (pPicture, name, stuff->nbytes, params, nparams);
1855706f2543Smrg    return result;
1856706f2543Smrg}
1857706f2543Smrg
1858706f2543Smrgstatic int
1859706f2543SmrgProcRenderCreateAnimCursor (ClientPtr client)
1860706f2543Smrg{
1861706f2543Smrg    REQUEST(xRenderCreateAnimCursorReq);
1862706f2543Smrg    CursorPtr	    *cursors;
1863706f2543Smrg    CARD32	    *deltas;
1864706f2543Smrg    CursorPtr	    pCursor;
1865706f2543Smrg    int		    ncursor;
1866706f2543Smrg    xAnimCursorElt  *elt;
1867706f2543Smrg    int		    i;
1868706f2543Smrg    int		    ret;
1869706f2543Smrg
1870706f2543Smrg    REQUEST_AT_LEAST_SIZE(xRenderCreateAnimCursorReq);
1871706f2543Smrg    LEGAL_NEW_RESOURCE(stuff->cid, client);
1872706f2543Smrg    if (client->req_len & 1)
1873706f2543Smrg	return BadLength;
1874706f2543Smrg    ncursor = (client->req_len - (bytes_to_int32(sizeof(xRenderCreateAnimCursorReq)))) >> 1;
1875706f2543Smrg    cursors = malloc(ncursor * (sizeof (CursorPtr) + sizeof (CARD32)));
1876706f2543Smrg    if (!cursors)
1877706f2543Smrg	return BadAlloc;
1878706f2543Smrg    deltas = (CARD32 *) (cursors + ncursor);
1879706f2543Smrg    elt = (xAnimCursorElt *) (stuff + 1);
1880706f2543Smrg    for (i = 0; i < ncursor; i++)
1881706f2543Smrg    {
1882706f2543Smrg	ret = dixLookupResourceByType((pointer *)(cursors + i), elt->cursor,
1883706f2543Smrg				      RT_CURSOR, client, DixReadAccess);
1884706f2543Smrg	if (ret != Success)
1885706f2543Smrg	{
1886706f2543Smrg	    free(cursors);
1887706f2543Smrg	    return ret;
1888706f2543Smrg	}
1889706f2543Smrg	deltas[i] = elt->delay;
1890706f2543Smrg	elt++;
1891706f2543Smrg    }
1892706f2543Smrg    ret = AnimCursorCreate (cursors, deltas, ncursor, &pCursor, client,
1893706f2543Smrg			    stuff->cid);
1894706f2543Smrg    free(cursors);
1895706f2543Smrg    if (ret != Success)
1896706f2543Smrg	return ret;
1897706f2543Smrg
1898706f2543Smrg    if (AddResource (stuff->cid, RT_CURSOR, (pointer)pCursor))
1899706f2543Smrg	return Success;
1900706f2543Smrg    return BadAlloc;
1901706f2543Smrg}
1902706f2543Smrg
1903706f2543Smrgstatic int
1904706f2543SmrgProcRenderAddTraps (ClientPtr client)
1905706f2543Smrg{
1906706f2543Smrg    int		ntraps;
1907706f2543Smrg    PicturePtr	pPicture;
1908706f2543Smrg    REQUEST(xRenderAddTrapsReq);
1909706f2543Smrg
1910706f2543Smrg    REQUEST_AT_LEAST_SIZE(xRenderAddTrapsReq);
1911706f2543Smrg    VERIFY_PICTURE (pPicture, stuff->picture, client, DixWriteAccess);
1912706f2543Smrg    if (!pPicture->pDrawable)
1913706f2543Smrg        return BadDrawable;
1914706f2543Smrg    ntraps = (client->req_len << 2) - sizeof (xRenderAddTrapsReq);
1915706f2543Smrg    if (ntraps % sizeof (xTrap))
1916706f2543Smrg	return BadLength;
1917706f2543Smrg    ntraps /= sizeof (xTrap);
1918706f2543Smrg    if (ntraps)
1919706f2543Smrg	AddTraps (pPicture,
1920706f2543Smrg		  stuff->xOff, stuff->yOff,
1921706f2543Smrg		  ntraps, (xTrap *) &stuff[1]);
1922706f2543Smrg    return Success;
1923706f2543Smrg}
1924706f2543Smrg
1925706f2543Smrgstatic int ProcRenderCreateSolidFill(ClientPtr client)
1926706f2543Smrg{
1927706f2543Smrg    PicturePtr	    pPicture;
1928706f2543Smrg    int		    error = 0;
1929706f2543Smrg    REQUEST(xRenderCreateSolidFillReq);
1930706f2543Smrg
1931706f2543Smrg    REQUEST_AT_LEAST_SIZE(xRenderCreateSolidFillReq);
1932706f2543Smrg
1933706f2543Smrg    LEGAL_NEW_RESOURCE(stuff->pid, client);
1934706f2543Smrg
1935706f2543Smrg    pPicture = CreateSolidPicture(stuff->pid, &stuff->color, &error);
1936706f2543Smrg    if (!pPicture)
1937706f2543Smrg	return error;
1938706f2543Smrg    /* security creation/labeling check */
1939706f2543Smrg    error = XaceHook(XACE_RESOURCE_ACCESS, client, stuff->pid, PictureType,
1940706f2543Smrg		     pPicture, RT_NONE, NULL, DixCreateAccess);
1941706f2543Smrg    if (error != Success)
1942706f2543Smrg	return error;
1943706f2543Smrg    if (!AddResource (stuff->pid, PictureType, (pointer)pPicture))
1944706f2543Smrg	return BadAlloc;
1945706f2543Smrg    return Success;
1946706f2543Smrg}
1947706f2543Smrg
1948706f2543Smrgstatic int ProcRenderCreateLinearGradient (ClientPtr client)
1949706f2543Smrg{
1950706f2543Smrg    PicturePtr	    pPicture;
1951706f2543Smrg    int		    len;
1952706f2543Smrg    int		    error = 0;
1953706f2543Smrg    xFixed          *stops;
1954706f2543Smrg    xRenderColor   *colors;
1955706f2543Smrg    REQUEST(xRenderCreateLinearGradientReq);
1956706f2543Smrg
1957706f2543Smrg    REQUEST_AT_LEAST_SIZE(xRenderCreateLinearGradientReq);
1958706f2543Smrg
1959706f2543Smrg    LEGAL_NEW_RESOURCE(stuff->pid, client);
1960706f2543Smrg
1961706f2543Smrg    len = (client->req_len << 2) - sizeof(xRenderCreateLinearGradientReq);
1962706f2543Smrg    if (stuff->nStops > UINT32_MAX/(sizeof(xFixed) + sizeof(xRenderColor)))
1963706f2543Smrg	return BadLength;
1964706f2543Smrg    if (len != stuff->nStops*(sizeof(xFixed) + sizeof(xRenderColor)))
1965706f2543Smrg        return BadLength;
1966706f2543Smrg
1967706f2543Smrg    stops = (xFixed *)(stuff + 1);
1968706f2543Smrg    colors = (xRenderColor *)(stops + stuff->nStops);
1969706f2543Smrg
1970706f2543Smrg    pPicture = CreateLinearGradientPicture (stuff->pid, &stuff->p1, &stuff->p2,
1971706f2543Smrg                                            stuff->nStops, stops, colors, &error);
1972706f2543Smrg    if (!pPicture)
1973706f2543Smrg	return error;
1974706f2543Smrg    /* security creation/labeling check */
1975706f2543Smrg    error = XaceHook(XACE_RESOURCE_ACCESS, client, stuff->pid, PictureType,
1976706f2543Smrg		     pPicture, RT_NONE, NULL, DixCreateAccess);
1977706f2543Smrg    if (error != Success)
1978706f2543Smrg	return error;
1979706f2543Smrg    if (!AddResource (stuff->pid, PictureType, (pointer)pPicture))
1980706f2543Smrg	return BadAlloc;
1981706f2543Smrg    return Success;
1982706f2543Smrg}
1983706f2543Smrg
1984706f2543Smrgstatic int ProcRenderCreateRadialGradient (ClientPtr client)
1985706f2543Smrg{
1986706f2543Smrg    PicturePtr	    pPicture;
1987706f2543Smrg    int		    len;
1988706f2543Smrg    int		    error = 0;
1989706f2543Smrg    xFixed          *stops;
1990706f2543Smrg    xRenderColor   *colors;
1991706f2543Smrg    REQUEST(xRenderCreateRadialGradientReq);
1992706f2543Smrg
1993706f2543Smrg    REQUEST_AT_LEAST_SIZE(xRenderCreateRadialGradientReq);
1994706f2543Smrg
1995706f2543Smrg    LEGAL_NEW_RESOURCE(stuff->pid, client);
1996706f2543Smrg
1997706f2543Smrg    len = (client->req_len << 2) - sizeof(xRenderCreateRadialGradientReq);
1998706f2543Smrg    if (len != stuff->nStops*(sizeof(xFixed) + sizeof(xRenderColor)))
1999706f2543Smrg        return BadLength;
2000706f2543Smrg
2001706f2543Smrg    stops = (xFixed *)(stuff + 1);
2002706f2543Smrg    colors = (xRenderColor *)(stops + stuff->nStops);
2003706f2543Smrg
2004706f2543Smrg    pPicture = CreateRadialGradientPicture (stuff->pid, &stuff->inner, &stuff->outer,
2005706f2543Smrg                                            stuff->inner_radius, stuff->outer_radius,
2006706f2543Smrg                                            stuff->nStops, stops, colors, &error);
2007706f2543Smrg    if (!pPicture)
2008706f2543Smrg	return error;
2009706f2543Smrg    /* security creation/labeling check */
2010706f2543Smrg    error = XaceHook(XACE_RESOURCE_ACCESS, client, stuff->pid, PictureType,
2011706f2543Smrg		     pPicture, RT_NONE, NULL, DixCreateAccess);
2012706f2543Smrg    if (error != Success)
2013706f2543Smrg	return error;
2014706f2543Smrg    if (!AddResource (stuff->pid, PictureType, (pointer)pPicture))
2015706f2543Smrg	return BadAlloc;
2016706f2543Smrg    return Success;
2017706f2543Smrg}
2018706f2543Smrg
2019706f2543Smrgstatic int ProcRenderCreateConicalGradient (ClientPtr client)
2020706f2543Smrg{
2021706f2543Smrg    PicturePtr	    pPicture;
2022706f2543Smrg    int		    len;
2023706f2543Smrg    int		    error = 0;
2024706f2543Smrg    xFixed          *stops;
2025706f2543Smrg    xRenderColor   *colors;
2026706f2543Smrg    REQUEST(xRenderCreateConicalGradientReq);
2027706f2543Smrg
2028706f2543Smrg    REQUEST_AT_LEAST_SIZE(xRenderCreateConicalGradientReq);
2029706f2543Smrg
2030706f2543Smrg    LEGAL_NEW_RESOURCE(stuff->pid, client);
2031706f2543Smrg
2032706f2543Smrg    len = (client->req_len << 2) - sizeof(xRenderCreateConicalGradientReq);
2033706f2543Smrg    if (len != stuff->nStops*(sizeof(xFixed) + sizeof(xRenderColor)))
2034706f2543Smrg        return BadLength;
2035706f2543Smrg
2036706f2543Smrg    stops = (xFixed *)(stuff + 1);
2037706f2543Smrg    colors = (xRenderColor *)(stops + stuff->nStops);
2038706f2543Smrg
2039706f2543Smrg    pPicture = CreateConicalGradientPicture (stuff->pid, &stuff->center, stuff->angle,
2040706f2543Smrg                                             stuff->nStops, stops, colors, &error);
2041706f2543Smrg    if (!pPicture)
2042706f2543Smrg	return error;
2043706f2543Smrg    /* security creation/labeling check */
2044706f2543Smrg    error = XaceHook(XACE_RESOURCE_ACCESS, client, stuff->pid, PictureType,
2045706f2543Smrg		     pPicture, RT_NONE, NULL, DixCreateAccess);
2046706f2543Smrg    if (error != Success)
2047706f2543Smrg	return error;
2048706f2543Smrg    if (!AddResource (stuff->pid, PictureType, (pointer)pPicture))
2049706f2543Smrg	return BadAlloc;
2050706f2543Smrg    return Success;
2051706f2543Smrg}
2052706f2543Smrg
2053706f2543Smrg
2054706f2543Smrgstatic int
2055706f2543SmrgProcRenderDispatch (ClientPtr client)
2056706f2543Smrg{
2057706f2543Smrg    REQUEST(xReq);
2058706f2543Smrg
2059706f2543Smrg    if (stuff->data < RenderNumberRequests)
2060706f2543Smrg	return (*ProcRenderVector[stuff->data]) (client);
2061706f2543Smrg    else
2062706f2543Smrg	return BadRequest;
2063706f2543Smrg}
2064706f2543Smrg
2065706f2543Smrgstatic int
2066706f2543SmrgSProcRenderQueryVersion (ClientPtr client)
2067706f2543Smrg{
2068706f2543Smrg    register int n;
2069706f2543Smrg    REQUEST(xRenderQueryVersionReq);
2070706f2543Smrg    REQUEST_SIZE_MATCH(xRenderQueryVersionReq);
2071706f2543Smrg
2072706f2543Smrg    swaps(&stuff->length, n);
2073706f2543Smrg    swapl(&stuff->majorVersion, n);
2074706f2543Smrg    swapl(&stuff->minorVersion, n);
2075706f2543Smrg    return (*ProcRenderVector[stuff->renderReqType])(client);
2076706f2543Smrg}
2077706f2543Smrg
2078706f2543Smrgstatic int
2079706f2543SmrgSProcRenderQueryPictFormats (ClientPtr client)
2080706f2543Smrg{
2081706f2543Smrg    register int n;
2082706f2543Smrg    REQUEST(xRenderQueryPictFormatsReq);
2083706f2543Smrg    REQUEST_SIZE_MATCH(xRenderQueryPictFormatsReq);
2084706f2543Smrg    swaps(&stuff->length, n);
2085706f2543Smrg    return (*ProcRenderVector[stuff->renderReqType]) (client);
2086706f2543Smrg}
2087706f2543Smrg
2088706f2543Smrgstatic int
2089706f2543SmrgSProcRenderQueryPictIndexValues (ClientPtr client)
2090706f2543Smrg{
2091706f2543Smrg    register int n;
2092706f2543Smrg    REQUEST(xRenderQueryPictIndexValuesReq);
2093706f2543Smrg    REQUEST_AT_LEAST_SIZE(xRenderQueryPictIndexValuesReq);
2094706f2543Smrg    swaps(&stuff->length, n);
2095706f2543Smrg    swapl(&stuff->format, n);
2096706f2543Smrg    return (*ProcRenderVector[stuff->renderReqType]) (client);
2097706f2543Smrg}
2098706f2543Smrg
2099706f2543Smrgstatic int
2100706f2543SmrgSProcRenderQueryDithers (ClientPtr client)
2101706f2543Smrg{
2102706f2543Smrg    return BadImplementation;
2103706f2543Smrg}
2104706f2543Smrg
2105706f2543Smrgstatic int
2106706f2543SmrgSProcRenderCreatePicture (ClientPtr client)
2107706f2543Smrg{
2108706f2543Smrg    register int n;
2109706f2543Smrg    REQUEST(xRenderCreatePictureReq);
2110706f2543Smrg    REQUEST_AT_LEAST_SIZE(xRenderCreatePictureReq);
2111706f2543Smrg    swaps(&stuff->length, n);
2112706f2543Smrg    swapl(&stuff->pid, n);
2113706f2543Smrg    swapl(&stuff->drawable, n);
2114706f2543Smrg    swapl(&stuff->format, n);
2115706f2543Smrg    swapl(&stuff->mask, n);
2116706f2543Smrg    SwapRestL(stuff);
2117706f2543Smrg    return (*ProcRenderVector[stuff->renderReqType]) (client);
2118706f2543Smrg}
2119706f2543Smrg
2120706f2543Smrgstatic int
2121706f2543SmrgSProcRenderChangePicture (ClientPtr client)
2122706f2543Smrg{
2123706f2543Smrg    register int n;
2124706f2543Smrg    REQUEST(xRenderChangePictureReq);
2125706f2543Smrg    REQUEST_AT_LEAST_SIZE(xRenderChangePictureReq);
2126706f2543Smrg    swaps(&stuff->length, n);
2127706f2543Smrg    swapl(&stuff->picture, n);
2128706f2543Smrg    swapl(&stuff->mask, n);
2129706f2543Smrg    SwapRestL(stuff);
2130706f2543Smrg    return (*ProcRenderVector[stuff->renderReqType]) (client);
2131706f2543Smrg}
2132706f2543Smrg
2133706f2543Smrgstatic int
2134706f2543SmrgSProcRenderSetPictureClipRectangles (ClientPtr client)
2135706f2543Smrg{
2136706f2543Smrg    register int n;
2137706f2543Smrg    REQUEST(xRenderSetPictureClipRectanglesReq);
2138706f2543Smrg    REQUEST_AT_LEAST_SIZE(xRenderSetPictureClipRectanglesReq);
2139706f2543Smrg    swaps(&stuff->length, n);
2140706f2543Smrg    swapl(&stuff->picture, n);
2141706f2543Smrg    swaps(&stuff->xOrigin, n);
2142706f2543Smrg    swaps(&stuff->yOrigin, n);
2143706f2543Smrg    SwapRestS(stuff);
2144706f2543Smrg    return (*ProcRenderVector[stuff->renderReqType]) (client);
2145706f2543Smrg}
2146706f2543Smrg
2147706f2543Smrgstatic int
2148706f2543SmrgSProcRenderFreePicture (ClientPtr client)
2149706f2543Smrg{
2150706f2543Smrg    register int n;
2151706f2543Smrg    REQUEST(xRenderFreePictureReq);
2152706f2543Smrg    REQUEST_SIZE_MATCH(xRenderFreePictureReq);
2153706f2543Smrg    swaps(&stuff->length, n);
2154706f2543Smrg    swapl(&stuff->picture, n);
2155706f2543Smrg    return (*ProcRenderVector[stuff->renderReqType]) (client);
2156706f2543Smrg}
2157706f2543Smrg
2158706f2543Smrgstatic int
2159706f2543SmrgSProcRenderComposite (ClientPtr client)
2160706f2543Smrg{
2161706f2543Smrg    register int n;
2162706f2543Smrg    REQUEST(xRenderCompositeReq);
2163706f2543Smrg    REQUEST_SIZE_MATCH(xRenderCompositeReq);
2164706f2543Smrg    swaps(&stuff->length, n);
2165706f2543Smrg    swapl(&stuff->src, n);
2166706f2543Smrg    swapl(&stuff->mask, n);
2167706f2543Smrg    swapl(&stuff->dst, n);
2168706f2543Smrg    swaps(&stuff->xSrc, n);
2169706f2543Smrg    swaps(&stuff->ySrc, n);
2170706f2543Smrg    swaps(&stuff->xMask, n);
2171706f2543Smrg    swaps(&stuff->yMask, n);
2172706f2543Smrg    swaps(&stuff->xDst, n);
2173706f2543Smrg    swaps(&stuff->yDst, n);
2174706f2543Smrg    swaps(&stuff->width, n);
2175706f2543Smrg    swaps(&stuff->height, n);
2176706f2543Smrg    return (*ProcRenderVector[stuff->renderReqType]) (client);
2177706f2543Smrg}
2178706f2543Smrg
2179706f2543Smrgstatic int
2180706f2543SmrgSProcRenderScale (ClientPtr client)
2181706f2543Smrg{
2182706f2543Smrg    register int n;
2183706f2543Smrg    REQUEST(xRenderScaleReq);
2184706f2543Smrg    REQUEST_SIZE_MATCH(xRenderScaleReq);
2185706f2543Smrg    swaps(&stuff->length, n);
2186706f2543Smrg    swapl(&stuff->src, n);
2187706f2543Smrg    swapl(&stuff->dst, n);
2188706f2543Smrg    swapl(&stuff->colorScale, n);
2189706f2543Smrg    swapl(&stuff->alphaScale, n);
2190706f2543Smrg    swaps(&stuff->xSrc, n);
2191706f2543Smrg    swaps(&stuff->ySrc, n);
2192706f2543Smrg    swaps(&stuff->xDst, n);
2193706f2543Smrg    swaps(&stuff->yDst, n);
2194706f2543Smrg    swaps(&stuff->width, n);
2195706f2543Smrg    swaps(&stuff->height, n);
2196706f2543Smrg    return (*ProcRenderVector[stuff->renderReqType]) (client);
2197706f2543Smrg}
2198706f2543Smrg
2199706f2543Smrgstatic int
2200706f2543SmrgSProcRenderTrapezoids (ClientPtr client)
2201706f2543Smrg{
2202706f2543Smrg    register int n;
2203706f2543Smrg    REQUEST(xRenderTrapezoidsReq);
2204706f2543Smrg
2205706f2543Smrg    REQUEST_AT_LEAST_SIZE(xRenderTrapezoidsReq);
2206706f2543Smrg    swaps (&stuff->length, n);
2207706f2543Smrg    swapl (&stuff->src, n);
2208706f2543Smrg    swapl (&stuff->dst, n);
2209706f2543Smrg    swapl (&stuff->maskFormat, n);
2210706f2543Smrg    swaps (&stuff->xSrc, n);
2211706f2543Smrg    swaps (&stuff->ySrc, n);
2212706f2543Smrg    SwapRestL(stuff);
2213706f2543Smrg    return (*ProcRenderVector[stuff->renderReqType]) (client);
2214706f2543Smrg}
2215706f2543Smrg
2216706f2543Smrgstatic int
2217706f2543SmrgSProcRenderTriangles (ClientPtr client)
2218706f2543Smrg{
2219706f2543Smrg    register int n;
2220706f2543Smrg    REQUEST(xRenderTrianglesReq);
2221706f2543Smrg
2222706f2543Smrg    REQUEST_AT_LEAST_SIZE(xRenderTrianglesReq);
2223706f2543Smrg    swaps (&stuff->length, n);
2224706f2543Smrg    swapl (&stuff->src, n);
2225706f2543Smrg    swapl (&stuff->dst, n);
2226706f2543Smrg    swapl (&stuff->maskFormat, n);
2227706f2543Smrg    swaps (&stuff->xSrc, n);
2228706f2543Smrg    swaps (&stuff->ySrc, n);
2229706f2543Smrg    SwapRestL(stuff);
2230706f2543Smrg    return (*ProcRenderVector[stuff->renderReqType]) (client);
2231706f2543Smrg}
2232706f2543Smrg
2233706f2543Smrgstatic int
2234706f2543SmrgSProcRenderTriStrip (ClientPtr client)
2235706f2543Smrg{
2236706f2543Smrg    register int n;
2237706f2543Smrg    REQUEST(xRenderTriStripReq);
2238706f2543Smrg
2239706f2543Smrg    REQUEST_AT_LEAST_SIZE(xRenderTriStripReq);
2240706f2543Smrg    swaps (&stuff->length, n);
2241706f2543Smrg    swapl (&stuff->src, n);
2242706f2543Smrg    swapl (&stuff->dst, n);
2243706f2543Smrg    swapl (&stuff->maskFormat, n);
2244706f2543Smrg    swaps (&stuff->xSrc, n);
2245706f2543Smrg    swaps (&stuff->ySrc, n);
2246706f2543Smrg    SwapRestL(stuff);
2247706f2543Smrg    return (*ProcRenderVector[stuff->renderReqType]) (client);
2248706f2543Smrg}
2249706f2543Smrg
2250706f2543Smrgstatic int
2251706f2543SmrgSProcRenderTriFan (ClientPtr client)
2252706f2543Smrg{
2253706f2543Smrg    register int n;
2254706f2543Smrg    REQUEST(xRenderTriFanReq);
2255706f2543Smrg
2256706f2543Smrg    REQUEST_AT_LEAST_SIZE(xRenderTriFanReq);
2257706f2543Smrg    swaps (&stuff->length, n);
2258706f2543Smrg    swapl (&stuff->src, n);
2259706f2543Smrg    swapl (&stuff->dst, n);
2260706f2543Smrg    swapl (&stuff->maskFormat, n);
2261706f2543Smrg    swaps (&stuff->xSrc, n);
2262706f2543Smrg    swaps (&stuff->ySrc, n);
2263706f2543Smrg    SwapRestL(stuff);
2264706f2543Smrg    return (*ProcRenderVector[stuff->renderReqType]) (client);
2265706f2543Smrg}
2266706f2543Smrg
2267706f2543Smrgstatic int
2268706f2543SmrgSProcRenderColorTrapezoids (ClientPtr client)
2269706f2543Smrg{
2270706f2543Smrg    return BadImplementation;
2271706f2543Smrg}
2272706f2543Smrg
2273706f2543Smrgstatic int
2274706f2543SmrgSProcRenderColorTriangles (ClientPtr client)
2275706f2543Smrg{
2276706f2543Smrg    return BadImplementation;
2277706f2543Smrg}
2278706f2543Smrg
2279706f2543Smrgstatic int
2280706f2543SmrgSProcRenderTransform (ClientPtr client)
2281706f2543Smrg{
2282706f2543Smrg    return BadImplementation;
2283706f2543Smrg}
2284706f2543Smrg
2285706f2543Smrgstatic int
2286706f2543SmrgSProcRenderCreateGlyphSet (ClientPtr client)
2287706f2543Smrg{
2288706f2543Smrg    register int n;
2289706f2543Smrg    REQUEST(xRenderCreateGlyphSetReq);
2290706f2543Smrg    REQUEST_SIZE_MATCH(xRenderCreateGlyphSetReq);
2291706f2543Smrg    swaps(&stuff->length, n);
2292706f2543Smrg    swapl(&stuff->gsid, n);
2293706f2543Smrg    swapl(&stuff->format, n);
2294706f2543Smrg    return (*ProcRenderVector[stuff->renderReqType]) (client);
2295706f2543Smrg}
2296706f2543Smrg
2297706f2543Smrgstatic int
2298706f2543SmrgSProcRenderReferenceGlyphSet (ClientPtr client)
2299706f2543Smrg{
2300706f2543Smrg    register int n;
2301706f2543Smrg    REQUEST(xRenderReferenceGlyphSetReq);
2302706f2543Smrg    REQUEST_SIZE_MATCH(xRenderReferenceGlyphSetReq);
2303706f2543Smrg    swaps(&stuff->length, n);
2304706f2543Smrg    swapl(&stuff->gsid, n);
2305706f2543Smrg    swapl(&stuff->existing, n);
2306706f2543Smrg    return (*ProcRenderVector[stuff->renderReqType])  (client);
2307706f2543Smrg}
2308706f2543Smrg
2309706f2543Smrgstatic int
2310706f2543SmrgSProcRenderFreeGlyphSet (ClientPtr client)
2311706f2543Smrg{
2312706f2543Smrg    register int n;
2313706f2543Smrg    REQUEST(xRenderFreeGlyphSetReq);
2314706f2543Smrg    REQUEST_SIZE_MATCH(xRenderFreeGlyphSetReq);
2315706f2543Smrg    swaps(&stuff->length, n);
2316706f2543Smrg    swapl(&stuff->glyphset, n);
2317706f2543Smrg    return (*ProcRenderVector[stuff->renderReqType]) (client);
2318706f2543Smrg}
2319706f2543Smrg
2320706f2543Smrgstatic int
2321706f2543SmrgSProcRenderAddGlyphs (ClientPtr client)
2322706f2543Smrg{
2323706f2543Smrg    register int n;
2324706f2543Smrg    register int i;
2325706f2543Smrg    CARD32  *gids;
2326706f2543Smrg    void    *end;
2327706f2543Smrg    xGlyphInfo *gi;
2328706f2543Smrg    REQUEST(xRenderAddGlyphsReq);
2329706f2543Smrg    REQUEST_AT_LEAST_SIZE(xRenderAddGlyphsReq);
2330706f2543Smrg    swaps(&stuff->length, n);
2331706f2543Smrg    swapl(&stuff->glyphset, n);
2332706f2543Smrg    swapl(&stuff->nglyphs, n);
2333706f2543Smrg    if (stuff->nglyphs & 0xe0000000)
2334706f2543Smrg	return BadLength;
2335706f2543Smrg    end = (CARD8 *) stuff + (client->req_len << 2);
2336706f2543Smrg    gids = (CARD32 *) (stuff + 1);
2337706f2543Smrg    gi = (xGlyphInfo *) (gids + stuff->nglyphs);
2338706f2543Smrg    if ((char *) end - (char *) (gids + stuff->nglyphs) < 0)
2339706f2543Smrg	return BadLength;
2340706f2543Smrg    if ((char *) end - (char *) (gi + stuff->nglyphs) < 0)
2341706f2543Smrg	return BadLength;
2342706f2543Smrg    for (i = 0; i < stuff->nglyphs; i++)
2343706f2543Smrg    {
2344706f2543Smrg	swapl (&gids[i], n);
2345706f2543Smrg	swaps (&gi[i].width, n);
2346706f2543Smrg	swaps (&gi[i].height, n);
2347706f2543Smrg	swaps (&gi[i].x, n);
2348706f2543Smrg	swaps (&gi[i].y, n);
2349706f2543Smrg	swaps (&gi[i].xOff, n);
2350706f2543Smrg	swaps (&gi[i].yOff, n);
2351706f2543Smrg    }
2352706f2543Smrg    return (*ProcRenderVector[stuff->renderReqType]) (client);
2353706f2543Smrg}
2354706f2543Smrg
2355706f2543Smrgstatic int
2356706f2543SmrgSProcRenderAddGlyphsFromPicture (ClientPtr client)
2357706f2543Smrg{
2358706f2543Smrg    return BadImplementation;
2359706f2543Smrg}
2360706f2543Smrg
2361706f2543Smrgstatic int
2362706f2543SmrgSProcRenderFreeGlyphs (ClientPtr client)
2363706f2543Smrg{
2364706f2543Smrg    register int n;
2365706f2543Smrg    REQUEST(xRenderFreeGlyphsReq);
2366706f2543Smrg    REQUEST_AT_LEAST_SIZE(xRenderFreeGlyphsReq);
2367706f2543Smrg    swaps(&stuff->length, n);
2368706f2543Smrg    swapl(&stuff->glyphset, n);
2369706f2543Smrg    SwapRestL(stuff);
2370706f2543Smrg    return (*ProcRenderVector[stuff->renderReqType]) (client);
2371706f2543Smrg}
2372706f2543Smrg
2373706f2543Smrgstatic int
2374706f2543SmrgSProcRenderCompositeGlyphs (ClientPtr client)
2375706f2543Smrg{
2376706f2543Smrg    register int n;
2377706f2543Smrg    xGlyphElt	*elt;
2378706f2543Smrg    CARD8	*buffer;
2379706f2543Smrg    CARD8	*end;
2380706f2543Smrg    int		space;
2381706f2543Smrg    int		i;
2382706f2543Smrg    int		size;
2383706f2543Smrg
2384706f2543Smrg    REQUEST(xRenderCompositeGlyphsReq);
2385706f2543Smrg    REQUEST_AT_LEAST_SIZE(xRenderCompositeGlyphsReq);
2386706f2543Smrg
2387706f2543Smrg    switch (stuff->renderReqType) {
2388706f2543Smrg    default:			    size = 1; break;
2389706f2543Smrg    case X_RenderCompositeGlyphs16: size = 2; break;
2390706f2543Smrg    case X_RenderCompositeGlyphs32: size = 4; break;
2391706f2543Smrg    }
2392706f2543Smrg
2393706f2543Smrg    swaps(&stuff->length, n);
2394706f2543Smrg    swapl(&stuff->src, n);
2395706f2543Smrg    swapl(&stuff->dst, n);
2396706f2543Smrg    swapl(&stuff->maskFormat, n);
2397706f2543Smrg    swapl(&stuff->glyphset, n);
2398706f2543Smrg    swaps(&stuff->xSrc, n);
2399706f2543Smrg    swaps(&stuff->ySrc, n);
2400706f2543Smrg    buffer = (CARD8 *) (stuff + 1);
2401706f2543Smrg    end = (CARD8 *) stuff + (client->req_len << 2);
2402706f2543Smrg    while (buffer + sizeof (xGlyphElt) < end)
2403706f2543Smrg    {
2404706f2543Smrg	elt = (xGlyphElt *) buffer;
2405706f2543Smrg	buffer += sizeof (xGlyphElt);
2406706f2543Smrg
2407706f2543Smrg	swaps (&elt->deltax, n);
2408706f2543Smrg	swaps (&elt->deltay, n);
2409706f2543Smrg
2410706f2543Smrg	i = elt->len;
2411706f2543Smrg	if (i == 0xff)
2412706f2543Smrg	{
2413706f2543Smrg	    swapl (buffer, n);
2414706f2543Smrg	    buffer += 4;
2415706f2543Smrg	}
2416706f2543Smrg	else
2417706f2543Smrg	{
2418706f2543Smrg	    space = size * i;
2419706f2543Smrg	    switch (size) {
2420706f2543Smrg	    case 1:
2421706f2543Smrg		buffer += i;
2422706f2543Smrg		break;
2423706f2543Smrg	    case 2:
2424706f2543Smrg		while (i--)
2425706f2543Smrg		{
2426706f2543Smrg		    swaps (buffer, n);
2427706f2543Smrg		    buffer += 2;
2428706f2543Smrg		}
2429706f2543Smrg		break;
2430706f2543Smrg	    case 4:
2431706f2543Smrg		while (i--)
2432706f2543Smrg		{
2433706f2543Smrg		    swapl (buffer, n);
2434706f2543Smrg		    buffer += 4;
2435706f2543Smrg		}
2436706f2543Smrg		break;
2437706f2543Smrg	    }
2438706f2543Smrg	    if (space & 3)
2439706f2543Smrg		buffer += 4 - (space & 3);
2440706f2543Smrg	}
2441706f2543Smrg    }
2442706f2543Smrg    return (*ProcRenderVector[stuff->renderReqType]) (client);
2443706f2543Smrg}
2444706f2543Smrg
2445706f2543Smrgstatic int
2446706f2543SmrgSProcRenderFillRectangles (ClientPtr client)
2447706f2543Smrg{
2448706f2543Smrg    register int n;
2449706f2543Smrg    REQUEST(xRenderFillRectanglesReq);
2450706f2543Smrg
2451706f2543Smrg    REQUEST_AT_LEAST_SIZE (xRenderFillRectanglesReq);
2452706f2543Smrg    swaps(&stuff->length, n);
2453706f2543Smrg    swapl(&stuff->dst, n);
2454706f2543Smrg    swaps(&stuff->color.red, n);
2455706f2543Smrg    swaps(&stuff->color.green, n);
2456706f2543Smrg    swaps(&stuff->color.blue, n);
2457706f2543Smrg    swaps(&stuff->color.alpha, n);
2458706f2543Smrg    SwapRestS(stuff);
2459706f2543Smrg    return (*ProcRenderVector[stuff->renderReqType]) (client);
2460706f2543Smrg}
2461706f2543Smrg
2462706f2543Smrgstatic int
2463706f2543SmrgSProcRenderCreateCursor (ClientPtr client)
2464706f2543Smrg{
2465706f2543Smrg    register int n;
2466706f2543Smrg    REQUEST(xRenderCreateCursorReq);
2467706f2543Smrg    REQUEST_SIZE_MATCH (xRenderCreateCursorReq);
2468706f2543Smrg
2469706f2543Smrg    swaps(&stuff->length, n);
2470706f2543Smrg    swapl(&stuff->cid, n);
2471706f2543Smrg    swapl(&stuff->src, n);
2472706f2543Smrg    swaps(&stuff->x, n);
2473706f2543Smrg    swaps(&stuff->y, n);
2474706f2543Smrg    return (*ProcRenderVector[stuff->renderReqType]) (client);
2475706f2543Smrg}
2476706f2543Smrg
2477706f2543Smrgstatic int
2478706f2543SmrgSProcRenderSetPictureTransform (ClientPtr client)
2479706f2543Smrg{
2480706f2543Smrg    register int n;
2481706f2543Smrg    REQUEST(xRenderSetPictureTransformReq);
2482706f2543Smrg    REQUEST_SIZE_MATCH(xRenderSetPictureTransformReq);
2483706f2543Smrg
2484706f2543Smrg    swaps(&stuff->length, n);
2485706f2543Smrg    swapl(&stuff->picture, n);
2486706f2543Smrg    swapl(&stuff->transform.matrix11, n);
2487706f2543Smrg    swapl(&stuff->transform.matrix12, n);
2488706f2543Smrg    swapl(&stuff->transform.matrix13, n);
2489706f2543Smrg    swapl(&stuff->transform.matrix21, n);
2490706f2543Smrg    swapl(&stuff->transform.matrix22, n);
2491706f2543Smrg    swapl(&stuff->transform.matrix23, n);
2492706f2543Smrg    swapl(&stuff->transform.matrix31, n);
2493706f2543Smrg    swapl(&stuff->transform.matrix32, n);
2494706f2543Smrg    swapl(&stuff->transform.matrix33, n);
2495706f2543Smrg    return (*ProcRenderVector[stuff->renderReqType]) (client);
2496706f2543Smrg}
2497706f2543Smrg
2498706f2543Smrgstatic int
2499706f2543SmrgSProcRenderQueryFilters (ClientPtr client)
2500706f2543Smrg{
2501706f2543Smrg    register int n;
2502706f2543Smrg    REQUEST (xRenderQueryFiltersReq);
2503706f2543Smrg    REQUEST_SIZE_MATCH (xRenderQueryFiltersReq);
2504706f2543Smrg
2505706f2543Smrg    swaps(&stuff->length, n);
2506706f2543Smrg    swapl(&stuff->drawable, n);
2507706f2543Smrg    return (*ProcRenderVector[stuff->renderReqType]) (client);
2508706f2543Smrg}
2509706f2543Smrg
2510706f2543Smrgstatic int
2511706f2543SmrgSProcRenderSetPictureFilter (ClientPtr client)
2512706f2543Smrg{
2513706f2543Smrg    register int n;
2514706f2543Smrg    REQUEST (xRenderSetPictureFilterReq);
2515706f2543Smrg    REQUEST_AT_LEAST_SIZE (xRenderSetPictureFilterReq);
2516706f2543Smrg
2517706f2543Smrg    swaps(&stuff->length, n);
2518706f2543Smrg    swapl(&stuff->picture, n);
2519706f2543Smrg    swaps(&stuff->nbytes, n);
2520706f2543Smrg    return (*ProcRenderVector[stuff->renderReqType]) (client);
2521706f2543Smrg}
2522706f2543Smrg
2523706f2543Smrgstatic int
2524706f2543SmrgSProcRenderCreateAnimCursor (ClientPtr client)
2525706f2543Smrg{
2526706f2543Smrg    register int n;
2527706f2543Smrg    REQUEST (xRenderCreateAnimCursorReq);
2528706f2543Smrg    REQUEST_AT_LEAST_SIZE (xRenderCreateAnimCursorReq);
2529706f2543Smrg
2530706f2543Smrg    swaps(&stuff->length, n);
2531706f2543Smrg    swapl(&stuff->cid, n);
2532706f2543Smrg    SwapRestL(stuff);
2533706f2543Smrg    return (*ProcRenderVector[stuff->renderReqType]) (client);
2534706f2543Smrg}
2535706f2543Smrg
2536706f2543Smrgstatic int
2537706f2543SmrgSProcRenderAddTraps (ClientPtr client)
2538706f2543Smrg{
2539706f2543Smrg    register int n;
2540706f2543Smrg    REQUEST (xRenderAddTrapsReq);
2541706f2543Smrg    REQUEST_AT_LEAST_SIZE (xRenderAddTrapsReq);
2542706f2543Smrg
2543706f2543Smrg    swaps(&stuff->length, n);
2544706f2543Smrg    swapl(&stuff->picture, n);
2545706f2543Smrg    swaps(&stuff->xOff, n);
2546706f2543Smrg    swaps(&stuff->yOff, n);
2547706f2543Smrg    SwapRestL(stuff);
2548706f2543Smrg    return (*ProcRenderVector[stuff->renderReqType]) (client);
2549706f2543Smrg}
2550706f2543Smrg
2551706f2543Smrgstatic int
2552706f2543SmrgSProcRenderCreateSolidFill(ClientPtr client)
2553706f2543Smrg{
2554706f2543Smrg    register int n;
2555706f2543Smrg    REQUEST (xRenderCreateSolidFillReq);
2556706f2543Smrg    REQUEST_AT_LEAST_SIZE (xRenderCreateSolidFillReq);
2557706f2543Smrg
2558706f2543Smrg    swaps(&stuff->length, n);
2559706f2543Smrg    swapl(&stuff->pid, n);
2560706f2543Smrg    swaps(&stuff->color.alpha, n);
2561706f2543Smrg    swaps(&stuff->color.red, n);
2562706f2543Smrg    swaps(&stuff->color.green, n);
2563706f2543Smrg    swaps(&stuff->color.blue, n);
2564706f2543Smrg    return (*ProcRenderVector[stuff->renderReqType]) (client);
2565706f2543Smrg}
2566706f2543Smrg
2567706f2543Smrgstatic void swapStops(void *stuff, int num)
2568706f2543Smrg{
2569706f2543Smrg    int i, n;
2570706f2543Smrg    CARD32 *stops;
2571706f2543Smrg    CARD16 *colors;
2572706f2543Smrg    stops = (CARD32 *)(stuff);
2573706f2543Smrg    for (i = 0; i < num; ++i) {
2574706f2543Smrg        swapl(stops, n);
2575706f2543Smrg        ++stops;
2576706f2543Smrg    }
2577706f2543Smrg    colors = (CARD16 *)(stops);
2578706f2543Smrg    for (i = 0; i < 4*num; ++i) {
2579706f2543Smrg        swaps(colors, n);
2580706f2543Smrg        ++colors;
2581706f2543Smrg    }
2582706f2543Smrg}
2583706f2543Smrg
2584706f2543Smrgstatic int
2585706f2543SmrgSProcRenderCreateLinearGradient (ClientPtr client)
2586706f2543Smrg{
2587706f2543Smrg    register int n;
2588706f2543Smrg    int len;
2589706f2543Smrg    REQUEST (xRenderCreateLinearGradientReq);
2590706f2543Smrg    REQUEST_AT_LEAST_SIZE (xRenderCreateLinearGradientReq);
2591706f2543Smrg
2592706f2543Smrg    swaps(&stuff->length, n);
2593706f2543Smrg    swapl(&stuff->pid, n);
2594706f2543Smrg    swapl(&stuff->p1.x, n);
2595706f2543Smrg    swapl(&stuff->p1.y, n);
2596706f2543Smrg    swapl(&stuff->p2.x, n);
2597706f2543Smrg    swapl(&stuff->p2.y, n);
2598706f2543Smrg    swapl(&stuff->nStops, n);
2599706f2543Smrg
2600706f2543Smrg    len = (client->req_len << 2) - sizeof(xRenderCreateLinearGradientReq);
2601706f2543Smrg    if (stuff->nStops > UINT32_MAX/(sizeof(xFixed) + sizeof(xRenderColor)))
2602706f2543Smrg	return BadLength;
2603706f2543Smrg    if (len != stuff->nStops*(sizeof(xFixed) + sizeof(xRenderColor)))
2604706f2543Smrg        return BadLength;
2605706f2543Smrg
2606706f2543Smrg    swapStops(stuff+1, stuff->nStops);
2607706f2543Smrg
2608706f2543Smrg    return (*ProcRenderVector[stuff->renderReqType]) (client);
2609706f2543Smrg}
2610706f2543Smrg
2611706f2543Smrgstatic int
2612706f2543SmrgSProcRenderCreateRadialGradient (ClientPtr client)
2613706f2543Smrg{
2614706f2543Smrg    register int n;
2615706f2543Smrg    int len;
2616706f2543Smrg    REQUEST (xRenderCreateRadialGradientReq);
2617706f2543Smrg    REQUEST_AT_LEAST_SIZE (xRenderCreateRadialGradientReq);
2618706f2543Smrg
2619706f2543Smrg    swaps(&stuff->length, n);
2620706f2543Smrg    swapl(&stuff->pid, n);
2621706f2543Smrg    swapl(&stuff->inner.x, n);
2622706f2543Smrg    swapl(&stuff->inner.y, n);
2623706f2543Smrg    swapl(&stuff->outer.x, n);
2624706f2543Smrg    swapl(&stuff->outer.y, n);
2625706f2543Smrg    swapl(&stuff->inner_radius, n);
2626706f2543Smrg    swapl(&stuff->outer_radius, n);
2627706f2543Smrg    swapl(&stuff->nStops, n);
2628706f2543Smrg
2629706f2543Smrg    len = (client->req_len << 2) - sizeof(xRenderCreateRadialGradientReq);
2630706f2543Smrg    if (stuff->nStops > UINT32_MAX/(sizeof(xFixed) + sizeof(xRenderColor)))
2631706f2543Smrg	return BadLength;
2632706f2543Smrg    if (len != stuff->nStops*(sizeof(xFixed) + sizeof(xRenderColor)))
2633706f2543Smrg        return BadLength;
2634706f2543Smrg
2635706f2543Smrg    swapStops(stuff+1, stuff->nStops);
2636706f2543Smrg
2637706f2543Smrg    return (*ProcRenderVector[stuff->renderReqType]) (client);
2638706f2543Smrg}
2639706f2543Smrg
2640706f2543Smrgstatic int
2641706f2543SmrgSProcRenderCreateConicalGradient (ClientPtr client)
2642706f2543Smrg{
2643706f2543Smrg    register int n;
2644706f2543Smrg    int len;
2645706f2543Smrg    REQUEST (xRenderCreateConicalGradientReq);
2646706f2543Smrg    REQUEST_AT_LEAST_SIZE (xRenderCreateConicalGradientReq);
2647706f2543Smrg
2648706f2543Smrg    swaps(&stuff->length, n);
2649706f2543Smrg    swapl(&stuff->pid, n);
2650706f2543Smrg    swapl(&stuff->center.x, n);
2651706f2543Smrg    swapl(&stuff->center.y, n);
2652706f2543Smrg    swapl(&stuff->angle, n);
2653706f2543Smrg    swapl(&stuff->nStops, n);
2654706f2543Smrg
2655706f2543Smrg    len = (client->req_len << 2) - sizeof(xRenderCreateConicalGradientReq);
2656706f2543Smrg    if (stuff->nStops > UINT32_MAX/(sizeof(xFixed) + sizeof(xRenderColor)))
2657706f2543Smrg	return BadLength;
2658706f2543Smrg    if (len != stuff->nStops*(sizeof(xFixed) + sizeof(xRenderColor)))
2659706f2543Smrg        return BadLength;
2660706f2543Smrg
2661706f2543Smrg    swapStops(stuff+1, stuff->nStops);
2662706f2543Smrg
2663706f2543Smrg    return (*ProcRenderVector[stuff->renderReqType]) (client);
2664706f2543Smrg}
2665706f2543Smrg
2666706f2543Smrgstatic int
2667706f2543SmrgSProcRenderDispatch (ClientPtr client)
2668706f2543Smrg{
2669706f2543Smrg    REQUEST(xReq);
2670706f2543Smrg
2671706f2543Smrg    if (stuff->data < RenderNumberRequests)
2672706f2543Smrg	return (*SProcRenderVector[stuff->data]) (client);
2673706f2543Smrg    else
2674706f2543Smrg	return BadRequest;
2675706f2543Smrg}
2676706f2543Smrg
2677706f2543Smrg#ifdef PANORAMIX
2678706f2543Smrg#define VERIFY_XIN_PICTURE(pPicture, pid, client, mode) {\
2679706f2543Smrg    int rc = dixLookupResourceByType((pointer *)&(pPicture), pid,\
2680706f2543Smrg                                     XRT_PICTURE, client, mode);\
2681706f2543Smrg    if (rc != Success)\
2682706f2543Smrg	return rc;\
2683706f2543Smrg}
2684706f2543Smrg
2685706f2543Smrg#define VERIFY_XIN_ALPHA(pPicture, pid, client, mode) {\
2686706f2543Smrg    if (pid == None) \
2687706f2543Smrg	pPicture = 0; \
2688706f2543Smrg    else { \
2689706f2543Smrg	VERIFY_XIN_PICTURE(pPicture, pid, client, mode); \
2690706f2543Smrg    } \
2691706f2543Smrg} \
2692706f2543Smrg
2693706f2543Smrgint	    (*PanoramiXSaveRenderVector[RenderNumberRequests])(ClientPtr);
2694706f2543Smrg
2695706f2543Smrgstatic int
2696706f2543SmrgPanoramiXRenderCreatePicture (ClientPtr client)
2697706f2543Smrg{
2698706f2543Smrg    REQUEST(xRenderCreatePictureReq);
2699706f2543Smrg    PanoramiXRes    *refDraw, *newPict;
2700706f2543Smrg    int		    result, j;
2701706f2543Smrg
2702706f2543Smrg    REQUEST_AT_LEAST_SIZE(xRenderCreatePictureReq);
2703706f2543Smrg    result = dixLookupResourceByClass((pointer *)&refDraw, stuff->drawable,
2704706f2543Smrg				      XRC_DRAWABLE, client, DixWriteAccess);
2705706f2543Smrg    if (result != Success)
2706706f2543Smrg	return (result == BadValue) ? BadDrawable : result;
2707706f2543Smrg    if(!(newPict = (PanoramiXRes *) malloc(sizeof(PanoramiXRes))))
2708706f2543Smrg	return BadAlloc;
2709706f2543Smrg    newPict->type = XRT_PICTURE;
2710706f2543Smrg    newPict->info[0].id = stuff->pid;
2711706f2543Smrg
2712706f2543Smrg    if (refDraw->type == XRT_WINDOW &&
2713706f2543Smrg	stuff->drawable == screenInfo.screens[0]->root->drawable.id)
2714706f2543Smrg    {
2715706f2543Smrg	newPict->u.pict.root = TRUE;
2716706f2543Smrg    }
2717706f2543Smrg    else
2718706f2543Smrg	newPict->u.pict.root = FALSE;
2719706f2543Smrg
2720706f2543Smrg    for(j = 1; j < PanoramiXNumScreens; j++)
2721706f2543Smrg	newPict->info[j].id = FakeClientID(client->index);
2722706f2543Smrg
2723706f2543Smrg    FOR_NSCREENS_BACKWARD(j) {
2724706f2543Smrg	stuff->pid = newPict->info[j].id;
2725706f2543Smrg	stuff->drawable = refDraw->info[j].id;
2726706f2543Smrg	result = (*PanoramiXSaveRenderVector[X_RenderCreatePicture]) (client);
2727706f2543Smrg	if(result != Success) break;
2728706f2543Smrg    }
2729706f2543Smrg
2730706f2543Smrg    if (result == Success)
2731706f2543Smrg	AddResource(newPict->info[0].id, XRT_PICTURE, newPict);
2732706f2543Smrg    else
2733706f2543Smrg	free(newPict);
2734706f2543Smrg
2735706f2543Smrg    return result;
2736706f2543Smrg}
2737706f2543Smrg
2738706f2543Smrgstatic int
2739706f2543SmrgPanoramiXRenderChangePicture (ClientPtr client)
2740706f2543Smrg{
2741706f2543Smrg    PanoramiXRes    *pict;
2742706f2543Smrg    int		    result = Success, j;
2743706f2543Smrg    REQUEST(xRenderChangePictureReq);
2744706f2543Smrg
2745706f2543Smrg    REQUEST_AT_LEAST_SIZE(xRenderChangePictureReq);
2746706f2543Smrg
2747706f2543Smrg    VERIFY_XIN_PICTURE(pict, stuff->picture, client, DixWriteAccess);
2748706f2543Smrg
2749706f2543Smrg    FOR_NSCREENS_BACKWARD(j) {
2750706f2543Smrg        stuff->picture = pict->info[j].id;
2751706f2543Smrg        result = (*PanoramiXSaveRenderVector[X_RenderChangePicture]) (client);
2752706f2543Smrg        if(result != Success) break;
2753706f2543Smrg    }
2754706f2543Smrg
2755706f2543Smrg    return result;
2756706f2543Smrg}
2757706f2543Smrg
2758706f2543Smrgstatic int
2759706f2543SmrgPanoramiXRenderSetPictureClipRectangles (ClientPtr client)
2760706f2543Smrg{
2761706f2543Smrg    REQUEST(xRenderSetPictureClipRectanglesReq);
2762706f2543Smrg    int		    result = Success, j;
2763706f2543Smrg    PanoramiXRes    *pict;
2764706f2543Smrg
2765706f2543Smrg    REQUEST_AT_LEAST_SIZE(xRenderSetPictureClipRectanglesReq);
2766706f2543Smrg
2767706f2543Smrg    VERIFY_XIN_PICTURE(pict, stuff->picture, client, DixWriteAccess);
2768706f2543Smrg
2769706f2543Smrg    FOR_NSCREENS_BACKWARD(j) {
2770706f2543Smrg        stuff->picture = pict->info[j].id;
2771706f2543Smrg        result = (*PanoramiXSaveRenderVector[X_RenderSetPictureClipRectangles]) (client);
2772706f2543Smrg        if(result != Success) break;
2773706f2543Smrg    }
2774706f2543Smrg
2775706f2543Smrg    return result;
2776706f2543Smrg}
2777706f2543Smrg
2778706f2543Smrgstatic int
2779706f2543SmrgPanoramiXRenderSetPictureTransform (ClientPtr client)
2780706f2543Smrg{
2781706f2543Smrg    REQUEST(xRenderSetPictureTransformReq);
2782706f2543Smrg    int		    result = Success, j;
2783706f2543Smrg    PanoramiXRes    *pict;
2784706f2543Smrg
2785706f2543Smrg    REQUEST_AT_LEAST_SIZE(xRenderSetPictureTransformReq);
2786706f2543Smrg
2787706f2543Smrg    VERIFY_XIN_PICTURE(pict, stuff->picture, client, DixWriteAccess);
2788706f2543Smrg
2789706f2543Smrg    FOR_NSCREENS_BACKWARD(j) {
2790706f2543Smrg        stuff->picture = pict->info[j].id;
2791706f2543Smrg        result = (*PanoramiXSaveRenderVector[X_RenderSetPictureTransform]) (client);
2792706f2543Smrg        if(result != Success) break;
2793706f2543Smrg    }
2794706f2543Smrg
2795706f2543Smrg    return result;
2796706f2543Smrg}
2797706f2543Smrg
2798706f2543Smrgstatic int
2799706f2543SmrgPanoramiXRenderSetPictureFilter (ClientPtr client)
2800706f2543Smrg{
2801706f2543Smrg    REQUEST(xRenderSetPictureFilterReq);
2802706f2543Smrg    int		    result = Success, j;
2803706f2543Smrg    PanoramiXRes    *pict;
2804706f2543Smrg
2805706f2543Smrg    REQUEST_AT_LEAST_SIZE(xRenderSetPictureFilterReq);
2806706f2543Smrg
2807706f2543Smrg    VERIFY_XIN_PICTURE(pict, stuff->picture, client, DixWriteAccess);
2808706f2543Smrg
2809706f2543Smrg    FOR_NSCREENS_BACKWARD(j) {
2810706f2543Smrg        stuff->picture = pict->info[j].id;
2811706f2543Smrg        result = (*PanoramiXSaveRenderVector[X_RenderSetPictureFilter]) (client);
2812706f2543Smrg        if(result != Success) break;
2813706f2543Smrg    }
2814706f2543Smrg
2815706f2543Smrg    return result;
2816706f2543Smrg}
2817706f2543Smrg
2818706f2543Smrgstatic int
2819706f2543SmrgPanoramiXRenderFreePicture (ClientPtr client)
2820706f2543Smrg{
2821706f2543Smrg    PanoramiXRes *pict;
2822706f2543Smrg    int         result = Success, j;
2823706f2543Smrg    REQUEST(xRenderFreePictureReq);
2824706f2543Smrg
2825706f2543Smrg    REQUEST_SIZE_MATCH(xRenderFreePictureReq);
2826706f2543Smrg
2827706f2543Smrg    client->errorValue = stuff->picture;
2828706f2543Smrg
2829706f2543Smrg    VERIFY_XIN_PICTURE(pict, stuff->picture, client, DixDestroyAccess);
2830706f2543Smrg
2831706f2543Smrg
2832706f2543Smrg    FOR_NSCREENS_BACKWARD(j) {
2833706f2543Smrg	stuff->picture = pict->info[j].id;
2834706f2543Smrg	result = (*PanoramiXSaveRenderVector[X_RenderFreePicture]) (client);
2835706f2543Smrg	if(result != Success) break;
2836706f2543Smrg    }
2837706f2543Smrg
2838706f2543Smrg    /* Since ProcRenderFreePicture is using FreeResource, it will free
2839706f2543Smrg	our resource for us on the last pass through the loop above */
2840706f2543Smrg
2841706f2543Smrg    return result;
2842706f2543Smrg}
2843706f2543Smrg
2844706f2543Smrgstatic int
2845706f2543SmrgPanoramiXRenderComposite (ClientPtr client)
2846706f2543Smrg{
2847706f2543Smrg    PanoramiXRes	*src, *msk, *dst;
2848706f2543Smrg    int			result = Success, j;
2849706f2543Smrg    xRenderCompositeReq	orig;
2850706f2543Smrg    REQUEST(xRenderCompositeReq);
2851706f2543Smrg
2852706f2543Smrg    REQUEST_SIZE_MATCH(xRenderCompositeReq);
2853706f2543Smrg
2854706f2543Smrg    VERIFY_XIN_PICTURE (src, stuff->src, client, DixReadAccess);
2855706f2543Smrg    VERIFY_XIN_ALPHA (msk, stuff->mask, client, DixReadAccess);
2856706f2543Smrg    VERIFY_XIN_PICTURE (dst, stuff->dst, client, DixWriteAccess);
2857706f2543Smrg
2858706f2543Smrg    orig = *stuff;
2859706f2543Smrg
2860706f2543Smrg    FOR_NSCREENS_FORWARD(j) {
2861706f2543Smrg	stuff->src = src->info[j].id;
2862706f2543Smrg	if (src->u.pict.root)
2863706f2543Smrg	{
2864706f2543Smrg	    stuff->xSrc = orig.xSrc - screenInfo.screens[j]->x;
2865706f2543Smrg	    stuff->ySrc = orig.ySrc - screenInfo.screens[j]->y;
2866706f2543Smrg	}
2867706f2543Smrg	stuff->dst = dst->info[j].id;
2868706f2543Smrg	if (dst->u.pict.root)
2869706f2543Smrg	{
2870706f2543Smrg	    stuff->xDst = orig.xDst - screenInfo.screens[j]->x;
2871706f2543Smrg	    stuff->yDst = orig.yDst - screenInfo.screens[j]->y;
2872706f2543Smrg	}
2873706f2543Smrg	if (msk)
2874706f2543Smrg	{
2875706f2543Smrg	    stuff->mask = msk->info[j].id;
2876706f2543Smrg	    if (msk->u.pict.root)
2877706f2543Smrg	    {
2878706f2543Smrg		stuff->xMask = orig.xMask - screenInfo.screens[j]->x;
2879706f2543Smrg		stuff->yMask = orig.yMask - screenInfo.screens[j]->y;
2880706f2543Smrg	    }
2881706f2543Smrg	}
2882706f2543Smrg	result = (*PanoramiXSaveRenderVector[X_RenderComposite]) (client);
2883706f2543Smrg	if(result != Success) break;
2884706f2543Smrg    }
2885706f2543Smrg
2886706f2543Smrg    return result;
2887706f2543Smrg}
2888706f2543Smrg
2889706f2543Smrgstatic int
2890706f2543SmrgPanoramiXRenderCompositeGlyphs (ClientPtr client)
2891706f2543Smrg{
2892706f2543Smrg    PanoramiXRes    *src, *dst;
2893706f2543Smrg    int		    result = Success, j;
2894706f2543Smrg    REQUEST(xRenderCompositeGlyphsReq);
2895706f2543Smrg    xGlyphElt	    origElt, *elt;
2896706f2543Smrg    INT16	    xSrc, ySrc;
2897706f2543Smrg
2898706f2543Smrg    REQUEST_AT_LEAST_SIZE(xRenderCompositeGlyphsReq);
2899706f2543Smrg    VERIFY_XIN_PICTURE (src, stuff->src, client, DixReadAccess);
2900706f2543Smrg    VERIFY_XIN_PICTURE (dst, stuff->dst, client, DixWriteAccess);
2901706f2543Smrg
2902706f2543Smrg    if (client->req_len << 2 >= (sizeof (xRenderCompositeGlyphsReq) +
2903706f2543Smrg				 sizeof (xGlyphElt)))
2904706f2543Smrg    {
2905706f2543Smrg	elt = (xGlyphElt *) (stuff + 1);
2906706f2543Smrg	origElt = *elt;
2907706f2543Smrg	xSrc = stuff->xSrc;
2908706f2543Smrg	ySrc = stuff->ySrc;
2909706f2543Smrg	FOR_NSCREENS_FORWARD(j) {
2910706f2543Smrg	    stuff->src = src->info[j].id;
2911706f2543Smrg	    if (src->u.pict.root)
2912706f2543Smrg	    {
2913706f2543Smrg		stuff->xSrc = xSrc - screenInfo.screens[j]->x;
2914706f2543Smrg		stuff->ySrc = ySrc - screenInfo.screens[j]->y;
2915706f2543Smrg	    }
2916706f2543Smrg	    stuff->dst = dst->info[j].id;
2917706f2543Smrg	    if (dst->u.pict.root)
2918706f2543Smrg	    {
2919706f2543Smrg		elt->deltax = origElt.deltax - screenInfo.screens[j]->x;
2920706f2543Smrg		elt->deltay = origElt.deltay - screenInfo.screens[j]->y;
2921706f2543Smrg	    }
2922706f2543Smrg	    result = (*PanoramiXSaveRenderVector[stuff->renderReqType]) (client);
2923706f2543Smrg	    if(result != Success) break;
2924706f2543Smrg	}
2925706f2543Smrg    }
2926706f2543Smrg
2927706f2543Smrg    return result;
2928706f2543Smrg}
2929706f2543Smrg
2930706f2543Smrgstatic int
2931706f2543SmrgPanoramiXRenderFillRectangles (ClientPtr client)
2932706f2543Smrg{
2933706f2543Smrg    PanoramiXRes    *dst;
2934706f2543Smrg    int		    result = Success, j;
2935706f2543Smrg    REQUEST(xRenderFillRectanglesReq);
2936706f2543Smrg    char	    *extra;
2937706f2543Smrg    int		    extra_len;
2938706f2543Smrg
2939706f2543Smrg    REQUEST_AT_LEAST_SIZE (xRenderFillRectanglesReq);
2940706f2543Smrg    VERIFY_XIN_PICTURE (dst, stuff->dst, client, DixWriteAccess);
2941706f2543Smrg    extra_len = (client->req_len << 2) - sizeof (xRenderFillRectanglesReq);
2942706f2543Smrg    if (extra_len &&
2943706f2543Smrg	(extra = (char *) malloc(extra_len)))
2944706f2543Smrg    {
2945706f2543Smrg	memcpy (extra, stuff + 1, extra_len);
2946706f2543Smrg	FOR_NSCREENS_FORWARD(j) {
2947706f2543Smrg	    if (j) memcpy (stuff + 1, extra, extra_len);
2948706f2543Smrg	    if (dst->u.pict.root)
2949706f2543Smrg	    {
2950706f2543Smrg		int x_off = screenInfo.screens[j]->x;
2951706f2543Smrg		int y_off = screenInfo.screens[j]->y;
2952706f2543Smrg
2953706f2543Smrg		if(x_off || y_off) {
2954706f2543Smrg		    xRectangle	*rects = (xRectangle *) (stuff + 1);
2955706f2543Smrg		    int		i = extra_len / sizeof (xRectangle);
2956706f2543Smrg
2957706f2543Smrg		    while (i--)
2958706f2543Smrg		    {
2959706f2543Smrg			rects->x -= x_off;
2960706f2543Smrg			rects->y -= y_off;
2961706f2543Smrg			rects++;
2962706f2543Smrg		    }
2963706f2543Smrg		}
2964706f2543Smrg	    }
2965706f2543Smrg	    stuff->dst = dst->info[j].id;
2966706f2543Smrg	    result = (*PanoramiXSaveRenderVector[X_RenderFillRectangles]) (client);
2967706f2543Smrg	    if(result != Success) break;
2968706f2543Smrg	}
2969706f2543Smrg	free(extra);
2970706f2543Smrg    }
2971706f2543Smrg
2972706f2543Smrg    return result;
2973706f2543Smrg}
2974706f2543Smrg
2975706f2543Smrgstatic int
2976706f2543SmrgPanoramiXRenderTrapezoids(ClientPtr client)
2977706f2543Smrg{
2978706f2543Smrg    PanoramiXRes        *src, *dst;
2979706f2543Smrg    int                 result = Success, j;
2980706f2543Smrg    REQUEST(xRenderTrapezoidsReq);
2981706f2543Smrg    char		*extra;
2982706f2543Smrg    int			extra_len;
2983706f2543Smrg
2984706f2543Smrg    REQUEST_AT_LEAST_SIZE (xRenderTrapezoidsReq);
2985706f2543Smrg
2986706f2543Smrg    VERIFY_XIN_PICTURE (src, stuff->src, client, DixReadAccess);
2987706f2543Smrg    VERIFY_XIN_PICTURE (dst, stuff->dst, client, DixWriteAccess);
2988706f2543Smrg
2989706f2543Smrg    extra_len = (client->req_len << 2) - sizeof (xRenderTrapezoidsReq);
2990706f2543Smrg
2991706f2543Smrg    if (extra_len &&
2992706f2543Smrg	(extra = (char *) malloc(extra_len))) {
2993706f2543Smrg	memcpy (extra, stuff + 1, extra_len);
2994706f2543Smrg
2995706f2543Smrg	FOR_NSCREENS_FORWARD(j) {
2996706f2543Smrg	    if (j) memcpy (stuff + 1, extra, extra_len);
2997706f2543Smrg	    if (dst->u.pict.root) {
2998706f2543Smrg		int x_off = screenInfo.screens[j]->x;
2999706f2543Smrg		int y_off = screenInfo.screens[j]->y;
3000706f2543Smrg
3001706f2543Smrg		if(x_off || y_off) {
3002706f2543Smrg                    xTrapezoid  *trap = (xTrapezoid *) (stuff + 1);
3003706f2543Smrg		    int         i = extra_len / sizeof (xTrapezoid);
3004706f2543Smrg
3005706f2543Smrg		    while (i--) {
3006706f2543Smrg			trap->top -= y_off;
3007706f2543Smrg			trap->bottom -= y_off;
3008706f2543Smrg			trap->left.p1.x -= x_off;
3009706f2543Smrg			trap->left.p1.y -= y_off;
3010706f2543Smrg			trap->left.p2.x -= x_off;
3011706f2543Smrg			trap->left.p2.y -= y_off;
3012706f2543Smrg			trap->right.p1.x -= x_off;
3013706f2543Smrg			trap->right.p1.y -= y_off;
3014706f2543Smrg			trap->right.p2.x -= x_off;
3015706f2543Smrg			trap->right.p2.y -= y_off;
3016706f2543Smrg			trap++;
3017706f2543Smrg		    }
3018706f2543Smrg		}
3019706f2543Smrg	    }
3020706f2543Smrg
3021706f2543Smrg            stuff->src = src->info[j].id;
3022706f2543Smrg            stuff->dst = dst->info[j].id;
3023706f2543Smrg	    result =
3024706f2543Smrg		(*PanoramiXSaveRenderVector[X_RenderTrapezoids]) (client);
3025706f2543Smrg
3026706f2543Smrg	    if(result != Success) break;
3027706f2543Smrg	}
3028706f2543Smrg
3029706f2543Smrg        free(extra);
3030706f2543Smrg    }
3031706f2543Smrg
3032706f2543Smrg    return result;
3033706f2543Smrg}
3034706f2543Smrg
3035706f2543Smrgstatic int
3036706f2543SmrgPanoramiXRenderTriangles(ClientPtr client)
3037706f2543Smrg{
3038706f2543Smrg    PanoramiXRes        *src, *dst;
3039706f2543Smrg    int                 result = Success, j;
3040706f2543Smrg    REQUEST(xRenderTrianglesReq);
3041706f2543Smrg    char		*extra;
3042706f2543Smrg    int			extra_len;
3043706f2543Smrg
3044706f2543Smrg    REQUEST_AT_LEAST_SIZE (xRenderTrianglesReq);
3045706f2543Smrg
3046706f2543Smrg    VERIFY_XIN_PICTURE (src, stuff->src, client, DixReadAccess);
3047706f2543Smrg    VERIFY_XIN_PICTURE (dst, stuff->dst, client, DixWriteAccess);
3048706f2543Smrg
3049706f2543Smrg    extra_len = (client->req_len << 2) - sizeof (xRenderTrianglesReq);
3050706f2543Smrg
3051706f2543Smrg    if (extra_len &&
3052706f2543Smrg	(extra = (char *) malloc(extra_len))) {
3053706f2543Smrg	memcpy (extra, stuff + 1, extra_len);
3054706f2543Smrg
3055706f2543Smrg	FOR_NSCREENS_FORWARD(j) {
3056706f2543Smrg	    if (j) memcpy (stuff + 1, extra, extra_len);
3057706f2543Smrg	    if (dst->u.pict.root) {
3058706f2543Smrg		int x_off = screenInfo.screens[j]->x;
3059706f2543Smrg		int y_off = screenInfo.screens[j]->y;
3060706f2543Smrg
3061706f2543Smrg		if(x_off || y_off) {
3062706f2543Smrg                    xTriangle  *tri = (xTriangle *) (stuff + 1);
3063706f2543Smrg		    int         i = extra_len / sizeof (xTriangle);
3064706f2543Smrg
3065706f2543Smrg		    while (i--) {
3066706f2543Smrg			tri->p1.x -= x_off;
3067706f2543Smrg			tri->p1.y -= y_off;
3068706f2543Smrg			tri->p2.x -= x_off;
3069706f2543Smrg			tri->p2.y -= y_off;
3070706f2543Smrg			tri->p3.x -= x_off;
3071706f2543Smrg			tri->p3.y -= y_off;
3072706f2543Smrg			tri++;
3073706f2543Smrg		    }
3074706f2543Smrg		}
3075706f2543Smrg	    }
3076706f2543Smrg
3077706f2543Smrg            stuff->src = src->info[j].id;
3078706f2543Smrg            stuff->dst = dst->info[j].id;
3079706f2543Smrg	    result =
3080706f2543Smrg		(*PanoramiXSaveRenderVector[X_RenderTriangles]) (client);
3081706f2543Smrg
3082706f2543Smrg	    if(result != Success) break;
3083706f2543Smrg	}
3084706f2543Smrg
3085706f2543Smrg        free(extra);
3086706f2543Smrg    }
3087706f2543Smrg
3088706f2543Smrg    return result;
3089706f2543Smrg}
3090706f2543Smrg
3091706f2543Smrgstatic int
3092706f2543SmrgPanoramiXRenderTriStrip(ClientPtr client)
3093706f2543Smrg{
3094706f2543Smrg    PanoramiXRes        *src, *dst;
3095706f2543Smrg    int                 result = Success, j;
3096706f2543Smrg    REQUEST(xRenderTriStripReq);
3097706f2543Smrg    char		*extra;
3098706f2543Smrg    int			extra_len;
3099706f2543Smrg
3100706f2543Smrg    REQUEST_AT_LEAST_SIZE (xRenderTriStripReq);
3101706f2543Smrg
3102706f2543Smrg    VERIFY_XIN_PICTURE (src, stuff->src, client, DixReadAccess);
3103706f2543Smrg    VERIFY_XIN_PICTURE (dst, stuff->dst, client, DixWriteAccess);
3104706f2543Smrg
3105706f2543Smrg    extra_len = (client->req_len << 2) - sizeof (xRenderTriStripReq);
3106706f2543Smrg
3107706f2543Smrg    if (extra_len &&
3108706f2543Smrg	(extra = (char *) malloc(extra_len))) {
3109706f2543Smrg	memcpy (extra, stuff + 1, extra_len);
3110706f2543Smrg
3111706f2543Smrg	FOR_NSCREENS_FORWARD(j) {
3112706f2543Smrg	    if (j) memcpy (stuff + 1, extra, extra_len);
3113706f2543Smrg	    if (dst->u.pict.root) {
3114706f2543Smrg		int x_off = screenInfo.screens[j]->x;
3115706f2543Smrg		int y_off = screenInfo.screens[j]->y;
3116706f2543Smrg
3117706f2543Smrg		if(x_off || y_off) {
3118706f2543Smrg                    xPointFixed  *fixed = (xPointFixed *) (stuff + 1);
3119706f2543Smrg		    int         i = extra_len / sizeof (xPointFixed);
3120706f2543Smrg
3121706f2543Smrg		    while (i--) {
3122706f2543Smrg			fixed->x -= x_off;
3123706f2543Smrg			fixed->y -= y_off;
3124706f2543Smrg			fixed++;
3125706f2543Smrg		    }
3126706f2543Smrg		}
3127706f2543Smrg	    }
3128706f2543Smrg
3129706f2543Smrg            stuff->src = src->info[j].id;
3130706f2543Smrg            stuff->dst = dst->info[j].id;
3131706f2543Smrg	    result =
3132706f2543Smrg		(*PanoramiXSaveRenderVector[X_RenderTriStrip]) (client);
3133706f2543Smrg
3134706f2543Smrg	    if(result != Success) break;
3135706f2543Smrg	}
3136706f2543Smrg
3137706f2543Smrg        free(extra);
3138706f2543Smrg    }
3139706f2543Smrg
3140706f2543Smrg    return result;
3141706f2543Smrg}
3142706f2543Smrg
3143706f2543Smrgstatic int
3144706f2543SmrgPanoramiXRenderTriFan(ClientPtr client)
3145706f2543Smrg{
3146706f2543Smrg    PanoramiXRes        *src, *dst;
3147706f2543Smrg    int                 result = Success, j;
3148706f2543Smrg    REQUEST(xRenderTriFanReq);
3149706f2543Smrg    char		*extra;
3150706f2543Smrg    int			extra_len;
3151706f2543Smrg
3152706f2543Smrg    REQUEST_AT_LEAST_SIZE (xRenderTriFanReq);
3153706f2543Smrg
3154706f2543Smrg    VERIFY_XIN_PICTURE (src, stuff->src, client, DixReadAccess);
3155706f2543Smrg    VERIFY_XIN_PICTURE (dst, stuff->dst, client, DixWriteAccess);
3156706f2543Smrg
3157706f2543Smrg    extra_len = (client->req_len << 2) - sizeof (xRenderTriFanReq);
3158706f2543Smrg
3159706f2543Smrg    if (extra_len &&
3160706f2543Smrg	(extra = (char *) malloc(extra_len))) {
3161706f2543Smrg	memcpy (extra, stuff + 1, extra_len);
3162706f2543Smrg
3163706f2543Smrg	FOR_NSCREENS_FORWARD(j) {
3164706f2543Smrg	    if (j) memcpy (stuff + 1, extra, extra_len);
3165706f2543Smrg	    if (dst->u.pict.root) {
3166706f2543Smrg		int x_off = screenInfo.screens[j]->x;
3167706f2543Smrg		int y_off = screenInfo.screens[j]->y;
3168706f2543Smrg
3169706f2543Smrg		if(x_off || y_off) {
3170706f2543Smrg                    xPointFixed  *fixed = (xPointFixed *) (stuff + 1);
3171706f2543Smrg		    int         i = extra_len / sizeof (xPointFixed);
3172706f2543Smrg
3173706f2543Smrg		    while (i--) {
3174706f2543Smrg			fixed->x -= x_off;
3175706f2543Smrg			fixed->y -= y_off;
3176706f2543Smrg			fixed++;
3177706f2543Smrg		    }
3178706f2543Smrg		}
3179706f2543Smrg	    }
3180706f2543Smrg
3181706f2543Smrg            stuff->src = src->info[j].id;
3182706f2543Smrg            stuff->dst = dst->info[j].id;
3183706f2543Smrg	    result =
3184706f2543Smrg		(*PanoramiXSaveRenderVector[X_RenderTriFan]) (client);
3185706f2543Smrg
3186706f2543Smrg	    if(result != Success) break;
3187706f2543Smrg	}
3188706f2543Smrg
3189706f2543Smrg        free(extra);
3190706f2543Smrg    }
3191706f2543Smrg
3192706f2543Smrg    return result;
3193706f2543Smrg}
3194706f2543Smrg
3195706f2543Smrgstatic int
3196706f2543SmrgPanoramiXRenderAddTraps (ClientPtr client)
3197706f2543Smrg{
3198706f2543Smrg    PanoramiXRes    *picture;
3199706f2543Smrg    int		    result = Success, j;
3200706f2543Smrg    REQUEST(xRenderAddTrapsReq);
3201706f2543Smrg    char	    *extra;
3202706f2543Smrg    int		    extra_len;
3203706f2543Smrg    INT16    	    x_off, y_off;
3204706f2543Smrg
3205706f2543Smrg    REQUEST_AT_LEAST_SIZE (xRenderAddTrapsReq);
3206706f2543Smrg    VERIFY_XIN_PICTURE (picture, stuff->picture, client, DixWriteAccess);
3207706f2543Smrg    extra_len = (client->req_len << 2) - sizeof (xRenderAddTrapsReq);
3208706f2543Smrg    if (extra_len &&
3209706f2543Smrg	(extra = (char *) malloc(extra_len)))
3210706f2543Smrg    {
3211706f2543Smrg	memcpy (extra, stuff + 1, extra_len);
3212706f2543Smrg	x_off = stuff->xOff;
3213706f2543Smrg	y_off = stuff->yOff;
3214706f2543Smrg	FOR_NSCREENS_FORWARD(j) {
3215706f2543Smrg	    if (j) memcpy (stuff + 1, extra, extra_len);
3216706f2543Smrg	    stuff->picture = picture->info[j].id;
3217706f2543Smrg
3218706f2543Smrg	    if (picture->u.pict.root)
3219706f2543Smrg	    {
3220706f2543Smrg		stuff->xOff = x_off + screenInfo.screens[j]->x;
3221706f2543Smrg		stuff->yOff = y_off + screenInfo.screens[j]->y;
3222706f2543Smrg	    }
3223706f2543Smrg	    result = (*PanoramiXSaveRenderVector[X_RenderAddTraps]) (client);
3224706f2543Smrg	    if(result != Success) break;
3225706f2543Smrg	}
3226706f2543Smrg	free(extra);
3227706f2543Smrg    }
3228706f2543Smrg
3229706f2543Smrg    return result;
3230706f2543Smrg}
3231706f2543Smrg
3232706f2543Smrgstatic int
3233706f2543SmrgPanoramiXRenderCreateSolidFill (ClientPtr client)
3234706f2543Smrg{
3235706f2543Smrg    REQUEST(xRenderCreateSolidFillReq);
3236706f2543Smrg    PanoramiXRes    *newPict;
3237706f2543Smrg    int		    result = Success, j;
3238706f2543Smrg
3239706f2543Smrg    REQUEST_AT_LEAST_SIZE(xRenderCreateSolidFillReq);
3240706f2543Smrg
3241706f2543Smrg    if(!(newPict = (PanoramiXRes *) malloc(sizeof(PanoramiXRes))))
3242706f2543Smrg	return BadAlloc;
3243706f2543Smrg
3244706f2543Smrg    newPict->type = XRT_PICTURE;
3245706f2543Smrg    newPict->info[0].id = stuff->pid;
3246706f2543Smrg    newPict->u.pict.root = FALSE;
3247706f2543Smrg
3248706f2543Smrg    for(j = 1; j < PanoramiXNumScreens; j++)
3249706f2543Smrg	newPict->info[j].id = FakeClientID(client->index);
3250706f2543Smrg
3251706f2543Smrg    FOR_NSCREENS_BACKWARD(j) {
3252706f2543Smrg	stuff->pid = newPict->info[j].id;
3253706f2543Smrg	result = (*PanoramiXSaveRenderVector[X_RenderCreateSolidFill]) (client);
3254706f2543Smrg	if(result != Success) break;
3255706f2543Smrg    }
3256706f2543Smrg
3257706f2543Smrg    if (result == Success)
3258706f2543Smrg	AddResource(newPict->info[0].id, XRT_PICTURE, newPict);
3259706f2543Smrg    else
3260706f2543Smrg	free(newPict);
3261706f2543Smrg
3262706f2543Smrg    return result;
3263706f2543Smrg}
3264706f2543Smrg
3265706f2543Smrgstatic int
3266706f2543SmrgPanoramiXRenderCreateLinearGradient (ClientPtr client)
3267706f2543Smrg{
3268706f2543Smrg    REQUEST(xRenderCreateLinearGradientReq);
3269706f2543Smrg    PanoramiXRes    *newPict;
3270706f2543Smrg    int		    result = Success, j;
3271706f2543Smrg
3272706f2543Smrg    REQUEST_AT_LEAST_SIZE(xRenderCreateLinearGradientReq);
3273706f2543Smrg
3274706f2543Smrg    if(!(newPict = (PanoramiXRes *) malloc(sizeof(PanoramiXRes))))
3275706f2543Smrg	return BadAlloc;
3276706f2543Smrg
3277706f2543Smrg    newPict->type = XRT_PICTURE;
3278706f2543Smrg    newPict->info[0].id = stuff->pid;
3279706f2543Smrg    newPict->u.pict.root = FALSE;
3280706f2543Smrg
3281706f2543Smrg    for(j = 1; j < PanoramiXNumScreens; j++)
3282706f2543Smrg	newPict->info[j].id = FakeClientID(client->index);
3283706f2543Smrg
3284706f2543Smrg    FOR_NSCREENS_BACKWARD(j) {
3285706f2543Smrg	stuff->pid = newPict->info[j].id;
3286706f2543Smrg	result = (*PanoramiXSaveRenderVector[X_RenderCreateLinearGradient]) (client);
3287706f2543Smrg	if(result != Success) break;
3288706f2543Smrg    }
3289706f2543Smrg
3290706f2543Smrg    if (result == Success)
3291706f2543Smrg	AddResource(newPict->info[0].id, XRT_PICTURE, newPict);
3292706f2543Smrg    else
3293706f2543Smrg	free(newPict);
3294706f2543Smrg
3295706f2543Smrg    return result;
3296706f2543Smrg}
3297706f2543Smrg
3298706f2543Smrgstatic int
3299706f2543SmrgPanoramiXRenderCreateRadialGradient (ClientPtr client)
3300706f2543Smrg{
3301706f2543Smrg    REQUEST(xRenderCreateRadialGradientReq);
3302706f2543Smrg    PanoramiXRes    *newPict;
3303706f2543Smrg    int		    result = Success, j;
3304706f2543Smrg
3305706f2543Smrg    REQUEST_AT_LEAST_SIZE(xRenderCreateRadialGradientReq);
3306706f2543Smrg
3307706f2543Smrg    if(!(newPict = (PanoramiXRes *) malloc(sizeof(PanoramiXRes))))
3308706f2543Smrg	return BadAlloc;
3309706f2543Smrg
3310706f2543Smrg    newPict->type = XRT_PICTURE;
3311706f2543Smrg    newPict->info[0].id = stuff->pid;
3312706f2543Smrg    newPict->u.pict.root = FALSE;
3313706f2543Smrg
3314706f2543Smrg    for(j = 1; j < PanoramiXNumScreens; j++)
3315706f2543Smrg	newPict->info[j].id = FakeClientID(client->index);
3316706f2543Smrg
3317706f2543Smrg    FOR_NSCREENS_BACKWARD(j) {
3318706f2543Smrg	stuff->pid = newPict->info[j].id;
3319706f2543Smrg	result = (*PanoramiXSaveRenderVector[X_RenderCreateRadialGradient]) (client);
3320706f2543Smrg	if(result != Success) break;
3321706f2543Smrg    }
3322706f2543Smrg
3323706f2543Smrg    if (result == Success)
3324706f2543Smrg	AddResource(newPict->info[0].id, XRT_PICTURE, newPict);
3325706f2543Smrg    else
3326706f2543Smrg	free(newPict);
3327706f2543Smrg
3328706f2543Smrg    return result;
3329706f2543Smrg}
3330706f2543Smrg
3331706f2543Smrgstatic int
3332706f2543SmrgPanoramiXRenderCreateConicalGradient (ClientPtr client)
3333706f2543Smrg{
3334706f2543Smrg    REQUEST(xRenderCreateConicalGradientReq);
3335706f2543Smrg    PanoramiXRes    *newPict;
3336706f2543Smrg    int		    result = Success, j;
3337706f2543Smrg
3338706f2543Smrg    REQUEST_AT_LEAST_SIZE(xRenderCreateConicalGradientReq);
3339706f2543Smrg
3340706f2543Smrg    if(!(newPict = (PanoramiXRes *) malloc(sizeof(PanoramiXRes))))
3341706f2543Smrg	return BadAlloc;
3342706f2543Smrg
3343706f2543Smrg    newPict->type = XRT_PICTURE;
3344706f2543Smrg    newPict->info[0].id = stuff->pid;
3345706f2543Smrg    newPict->u.pict.root = FALSE;
3346706f2543Smrg
3347706f2543Smrg    for(j = 1; j < PanoramiXNumScreens; j++)
3348706f2543Smrg	newPict->info[j].id = FakeClientID(client->index);
3349706f2543Smrg
3350706f2543Smrg    FOR_NSCREENS_BACKWARD(j) {
3351706f2543Smrg	stuff->pid = newPict->info[j].id;
3352706f2543Smrg	result = (*PanoramiXSaveRenderVector[X_RenderCreateConicalGradient]) (client);
3353706f2543Smrg	if(result != Success) break;
3354706f2543Smrg    }
3355706f2543Smrg
3356706f2543Smrg    if (result == Success)
3357706f2543Smrg	AddResource(newPict->info[0].id, XRT_PICTURE, newPict);
3358706f2543Smrg    else
3359706f2543Smrg	free(newPict);
3360706f2543Smrg
3361706f2543Smrg    return result;
3362706f2543Smrg}
3363706f2543Smrg
3364706f2543Smrgvoid
3365706f2543SmrgPanoramiXRenderInit (void)
3366706f2543Smrg{
3367706f2543Smrg    int	    i;
3368706f2543Smrg
3369706f2543Smrg    XRT_PICTURE = CreateNewResourceType (XineramaDeleteResource,
3370706f2543Smrg					 "XineramaPicture");
3371706f2543Smrg    if (RenderErrBase)
3372706f2543Smrg	SetResourceTypeErrorValue(XRT_PICTURE, RenderErrBase + BadPicture);
3373706f2543Smrg    for (i = 0; i < RenderNumberRequests; i++)
3374706f2543Smrg	PanoramiXSaveRenderVector[i] = ProcRenderVector[i];
3375706f2543Smrg    /*
3376706f2543Smrg     * Stuff in Xinerama aware request processing hooks
3377706f2543Smrg     */
3378706f2543Smrg    ProcRenderVector[X_RenderCreatePicture] = PanoramiXRenderCreatePicture;
3379706f2543Smrg    ProcRenderVector[X_RenderChangePicture] = PanoramiXRenderChangePicture;
3380706f2543Smrg    ProcRenderVector[X_RenderSetPictureTransform] = PanoramiXRenderSetPictureTransform;
3381706f2543Smrg    ProcRenderVector[X_RenderSetPictureFilter] = PanoramiXRenderSetPictureFilter;
3382706f2543Smrg    ProcRenderVector[X_RenderSetPictureClipRectangles] = PanoramiXRenderSetPictureClipRectangles;
3383706f2543Smrg    ProcRenderVector[X_RenderFreePicture] = PanoramiXRenderFreePicture;
3384706f2543Smrg    ProcRenderVector[X_RenderComposite] = PanoramiXRenderComposite;
3385706f2543Smrg    ProcRenderVector[X_RenderCompositeGlyphs8] = PanoramiXRenderCompositeGlyphs;
3386706f2543Smrg    ProcRenderVector[X_RenderCompositeGlyphs16] = PanoramiXRenderCompositeGlyphs;
3387706f2543Smrg    ProcRenderVector[X_RenderCompositeGlyphs32] = PanoramiXRenderCompositeGlyphs;
3388706f2543Smrg    ProcRenderVector[X_RenderFillRectangles] = PanoramiXRenderFillRectangles;
3389706f2543Smrg
3390706f2543Smrg    ProcRenderVector[X_RenderTrapezoids] = PanoramiXRenderTrapezoids;
3391706f2543Smrg    ProcRenderVector[X_RenderTriangles] = PanoramiXRenderTriangles;
3392706f2543Smrg    ProcRenderVector[X_RenderTriStrip] = PanoramiXRenderTriStrip;
3393706f2543Smrg    ProcRenderVector[X_RenderTriFan] = PanoramiXRenderTriFan;
3394706f2543Smrg    ProcRenderVector[X_RenderAddTraps] = PanoramiXRenderAddTraps;
3395706f2543Smrg
3396706f2543Smrg    ProcRenderVector[X_RenderCreateSolidFill] = PanoramiXRenderCreateSolidFill;
3397706f2543Smrg    ProcRenderVector[X_RenderCreateLinearGradient] = PanoramiXRenderCreateLinearGradient;
3398706f2543Smrg    ProcRenderVector[X_RenderCreateRadialGradient] = PanoramiXRenderCreateRadialGradient;
3399706f2543Smrg    ProcRenderVector[X_RenderCreateConicalGradient] = PanoramiXRenderCreateConicalGradient;
3400706f2543Smrg}
3401706f2543Smrg
3402706f2543Smrgvoid
3403706f2543SmrgPanoramiXRenderReset (void)
3404706f2543Smrg{
3405706f2543Smrg    int	    i;
3406706f2543Smrg    for (i = 0; i < RenderNumberRequests; i++)
3407706f2543Smrg	ProcRenderVector[i] = PanoramiXSaveRenderVector[i];
3408706f2543Smrg    RenderErrBase = 0;
3409706f2543Smrg}
3410706f2543Smrg
3411706f2543Smrg#endif	/* PANORAMIX */
3412