1706f2543Smrg/**************************************************************************
2706f2543Smrg
3706f2543SmrgCopyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
4706f2543SmrgCopyright 2000 VA Linux Systems, Inc.
5706f2543SmrgAll Rights Reserved.
6706f2543Smrg
7706f2543SmrgPermission is hereby granted, free of charge, to any person obtaining a
8706f2543Smrgcopy of this software and associated documentation files (the
9706f2543Smrg"Software"), to deal in the Software without restriction, including
10706f2543Smrgwithout limitation the rights to use, copy, modify, merge, publish,
11706f2543Smrgdistribute, sub license, and/or sell copies of the Software, and to
12706f2543Smrgpermit persons to whom the Software is furnished to do so, subject to
13706f2543Smrgthe following conditions:
14706f2543Smrg
15706f2543SmrgThe above copyright notice and this permission notice (including the
16706f2543Smrgnext paragraph) shall be included in all copies or substantial portions
17706f2543Smrgof the Software.
18706f2543Smrg
19706f2543SmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20706f2543SmrgOR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21706f2543SmrgMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
22706f2543SmrgIN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
23706f2543SmrgANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
24706f2543SmrgTORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
25706f2543SmrgSOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26706f2543Smrg
27706f2543Smrg**************************************************************************/
28706f2543Smrg
29706f2543Smrg/*
30706f2543Smrg * Authors:
31706f2543Smrg *   Kevin E. Martin <martin@valinux.com>
32706f2543Smrg *   Jens Owen <jens@tungstengraphics.com>
33706f2543Smrg *   Rickard E. (Rik) Faith <faith@valinux.com>
34706f2543Smrg *
35706f2543Smrg */
36706f2543Smrg
37706f2543Smrg#ifdef HAVE_XORG_CONFIG_H
38706f2543Smrg#include <xorg-config.h>
39706f2543Smrg#endif
40706f2543Smrg
41706f2543Smrg#include <string.h>
42706f2543Smrg
43706f2543Smrg#include "xf86.h"
44706f2543Smrg
45706f2543Smrg#include <X11/X.h>
46706f2543Smrg#include <X11/Xproto.h>
47706f2543Smrg#include "misc.h"
48706f2543Smrg#include "dixstruct.h"
49706f2543Smrg#include "extnsionst.h"
50706f2543Smrg#include "colormapst.h"
51706f2543Smrg#include "cursorstr.h"
52706f2543Smrg#include "scrnintstr.h"
53706f2543Smrg#include "servermd.h"
54706f2543Smrg#define _XF86DRI_SERVER_
55706f2543Smrg#include <X11/dri/xf86driproto.h>
56706f2543Smrg#include "swaprep.h"
57706f2543Smrg#include "xf86str.h"
58706f2543Smrg#include "dri.h"
59706f2543Smrg#include "sarea.h"
60706f2543Smrg#include "dristruct.h"
61706f2543Smrg#include "xf86.h"
62706f2543Smrg#include "xf86drm.h"
63706f2543Smrg#include "protocol-versions.h"
64706f2543Smrg
65706f2543Smrgstatic int DRIErrorBase;
66706f2543Smrg
67706f2543Smrg
68706f2543Smrg
69706f2543Smrgstatic void XF86DRIResetProc(ExtensionEntry* extEntry);
70706f2543Smrg
71706f2543Smrgstatic unsigned char DRIReqCode = 0;
72706f2543Smrg
73706f2543Smrgextern void XFree86DRIExtensionInit(void);
74706f2543Smrg
75706f2543Smrg/*ARGSUSED*/
76706f2543Smrgstatic void
77706f2543SmrgXF86DRIResetProc (
78706f2543Smrg    ExtensionEntry* extEntry
79706f2543Smrg)
80706f2543Smrg{
81706f2543Smrg    DRIReset();
82706f2543Smrg}
83706f2543Smrg
84706f2543Smrgstatic int
85706f2543SmrgProcXF86DRIQueryVersion(
86706f2543Smrg    register ClientPtr client
87706f2543Smrg)
88706f2543Smrg{
89706f2543Smrg    xXF86DRIQueryVersionReply rep;
90706f2543Smrg    register int n;
91706f2543Smrg
92706f2543Smrg    REQUEST_SIZE_MATCH(xXF86DRIQueryVersionReq);
93706f2543Smrg    rep.type = X_Reply;
94706f2543Smrg    rep.length = 0;
95706f2543Smrg    rep.sequenceNumber = client->sequence;
96706f2543Smrg    rep.majorVersion = SERVER_XF86DRI_MAJOR_VERSION;
97706f2543Smrg    rep.minorVersion = SERVER_XF86DRI_MINOR_VERSION;
98706f2543Smrg    rep.patchVersion = SERVER_XF86DRI_PATCH_VERSION;
99706f2543Smrg    if (client->swapped) {
100706f2543Smrg    	swaps(&rep.sequenceNumber, n);
101706f2543Smrg    	swapl(&rep.length, n);
102706f2543Smrg	swaps(&rep.majorVersion, n);
103706f2543Smrg	swaps(&rep.minorVersion, n);
104706f2543Smrg	swapl(&rep.patchVersion, n);
105706f2543Smrg    }
106706f2543Smrg    WriteToClient(client, sizeof(xXF86DRIQueryVersionReply), (char *)&rep);
107706f2543Smrg    return Success;
108706f2543Smrg}
109706f2543Smrg
110706f2543Smrgstatic int
111706f2543SmrgProcXF86DRIQueryDirectRenderingCapable(
112706f2543Smrg    register ClientPtr client
113706f2543Smrg)
114706f2543Smrg{
115706f2543Smrg    xXF86DRIQueryDirectRenderingCapableReply	rep;
116706f2543Smrg    Bool isCapable;
117706f2543Smrg    register int n;
118706f2543Smrg
119706f2543Smrg    REQUEST(xXF86DRIQueryDirectRenderingCapableReq);
120706f2543Smrg    REQUEST_SIZE_MATCH(xXF86DRIQueryDirectRenderingCapableReq);
121706f2543Smrg    if (stuff->screen >= screenInfo.numScreens) {
122706f2543Smrg	client->errorValue = stuff->screen;
123706f2543Smrg	return BadValue;
124706f2543Smrg    }
125706f2543Smrg
126706f2543Smrg    rep.type = X_Reply;
127706f2543Smrg    rep.length = 0;
128706f2543Smrg    rep.sequenceNumber = client->sequence;
129706f2543Smrg
130706f2543Smrg    if (!DRIQueryDirectRenderingCapable( screenInfo.screens[stuff->screen],
131706f2543Smrg					 &isCapable)) {
132706f2543Smrg	return BadValue;
133706f2543Smrg    }
134706f2543Smrg    rep.isCapable = isCapable;
135706f2543Smrg
136706f2543Smrg    if (!LocalClient(client) || client->swapped)
137706f2543Smrg	rep.isCapable = 0;
138706f2543Smrg
139706f2543Smrg    if (client->swapped) {
140706f2543Smrg    	swaps(&rep.sequenceNumber, n);
141706f2543Smrg    	swapl(&rep.length, n);
142706f2543Smrg    }
143706f2543Smrg
144706f2543Smrg    WriteToClient(client,
145706f2543Smrg	sizeof(xXF86DRIQueryDirectRenderingCapableReply), (char *)&rep);
146706f2543Smrg    return Success;
147706f2543Smrg}
148706f2543Smrg
149706f2543Smrgstatic int
150706f2543SmrgProcXF86DRIOpenConnection(
151706f2543Smrg    register ClientPtr client
152706f2543Smrg)
153706f2543Smrg{
154706f2543Smrg    xXF86DRIOpenConnectionReply rep;
155706f2543Smrg    drm_handle_t			hSAREA;
156706f2543Smrg    char*			busIdString;
157706f2543Smrg
158706f2543Smrg    REQUEST(xXF86DRIOpenConnectionReq);
159706f2543Smrg    REQUEST_SIZE_MATCH(xXF86DRIOpenConnectionReq);
160706f2543Smrg    if (stuff->screen >= screenInfo.numScreens) {
161706f2543Smrg	client->errorValue = stuff->screen;
162706f2543Smrg	return BadValue;
163706f2543Smrg    }
164706f2543Smrg
165706f2543Smrg    if (!DRIOpenConnection( screenInfo.screens[stuff->screen],
166706f2543Smrg			    &hSAREA,
167706f2543Smrg			    &busIdString)) {
168706f2543Smrg	return BadValue;
169706f2543Smrg    }
170706f2543Smrg
171706f2543Smrg    rep.type = X_Reply;
172706f2543Smrg    rep.sequenceNumber = client->sequence;
173706f2543Smrg    rep.busIdStringLength = 0;
174706f2543Smrg    if (busIdString)
175706f2543Smrg	rep.busIdStringLength = strlen(busIdString);
176706f2543Smrg    rep.length = bytes_to_int32(SIZEOF(xXF86DRIOpenConnectionReply) - SIZEOF(xGenericReply) +
177706f2543Smrg                  pad_to_int32(rep.busIdStringLength));
178706f2543Smrg
179706f2543Smrg    rep.hSAREALow  = (CARD32)(hSAREA & 0xffffffff);
180706f2543Smrg#if defined(LONG64) && !defined(__linux__)
181706f2543Smrg    rep.hSAREAHigh = (CARD32)(hSAREA >> 32);
182706f2543Smrg#else
183706f2543Smrg    rep.hSAREAHigh = 0;
184706f2543Smrg#endif
185706f2543Smrg
186706f2543Smrg    WriteToClient(client, sizeof(xXF86DRIOpenConnectionReply), (char *)&rep);
187706f2543Smrg    if (rep.busIdStringLength)
188706f2543Smrg	WriteToClient(client, rep.busIdStringLength, busIdString);
189706f2543Smrg    return Success;
190706f2543Smrg}
191706f2543Smrg
192706f2543Smrgstatic int
193706f2543SmrgProcXF86DRIAuthConnection(
194706f2543Smrg    register ClientPtr client
195706f2543Smrg)
196706f2543Smrg{
197706f2543Smrg    xXF86DRIAuthConnectionReply rep;
198706f2543Smrg
199706f2543Smrg    REQUEST(xXF86DRIAuthConnectionReq);
200706f2543Smrg    REQUEST_SIZE_MATCH(xXF86DRIAuthConnectionReq);
201706f2543Smrg    if (stuff->screen >= screenInfo.numScreens) {
202706f2543Smrg	client->errorValue = stuff->screen;
203706f2543Smrg	return BadValue;
204706f2543Smrg    }
205706f2543Smrg
206706f2543Smrg    rep.type = X_Reply;
207706f2543Smrg    rep.length = 0;
208706f2543Smrg    rep.sequenceNumber = client->sequence;
209706f2543Smrg    rep.authenticated = 1;
210706f2543Smrg
211706f2543Smrg    if (!DRIAuthConnection( screenInfo.screens[stuff->screen], stuff->magic)) {
212706f2543Smrg        ErrorF("Failed to authenticate %lu\n", (unsigned long)stuff->magic);
213706f2543Smrg	rep.authenticated = 0;
214706f2543Smrg    }
215706f2543Smrg    WriteToClient(client, sizeof(xXF86DRIAuthConnectionReply), (char *)&rep);
216706f2543Smrg    return Success;
217706f2543Smrg}
218706f2543Smrg
219706f2543Smrgstatic int
220706f2543SmrgProcXF86DRICloseConnection(
221706f2543Smrg    register ClientPtr client
222706f2543Smrg)
223706f2543Smrg{
224706f2543Smrg    REQUEST(xXF86DRICloseConnectionReq);
225706f2543Smrg    REQUEST_SIZE_MATCH(xXF86DRICloseConnectionReq);
226706f2543Smrg    if (stuff->screen >= screenInfo.numScreens) {
227706f2543Smrg	client->errorValue = stuff->screen;
228706f2543Smrg	return BadValue;
229706f2543Smrg    }
230706f2543Smrg
231706f2543Smrg    DRICloseConnection( screenInfo.screens[stuff->screen]);
232706f2543Smrg
233706f2543Smrg    return Success;
234706f2543Smrg}
235706f2543Smrg
236706f2543Smrgstatic int
237706f2543SmrgProcXF86DRIGetClientDriverName(
238706f2543Smrg    register ClientPtr client
239706f2543Smrg)
240706f2543Smrg{
241706f2543Smrg    xXF86DRIGetClientDriverNameReply	rep;
242706f2543Smrg    char* clientDriverName;
243706f2543Smrg
244706f2543Smrg    REQUEST(xXF86DRIGetClientDriverNameReq);
245706f2543Smrg    REQUEST_SIZE_MATCH(xXF86DRIGetClientDriverNameReq);
246706f2543Smrg    if (stuff->screen >= screenInfo.numScreens) {
247706f2543Smrg	client->errorValue = stuff->screen;
248706f2543Smrg	return BadValue;
249706f2543Smrg    }
250706f2543Smrg
251706f2543Smrg    DRIGetClientDriverName( screenInfo.screens[stuff->screen],
252706f2543Smrg			    (int *)&rep.ddxDriverMajorVersion,
253706f2543Smrg			    (int *)&rep.ddxDriverMinorVersion,
254706f2543Smrg			    (int *)&rep.ddxDriverPatchVersion,
255706f2543Smrg			    &clientDriverName);
256706f2543Smrg
257706f2543Smrg    rep.type = X_Reply;
258706f2543Smrg    rep.sequenceNumber = client->sequence;
259706f2543Smrg    rep.clientDriverNameLength = 0;
260706f2543Smrg    if (clientDriverName)
261706f2543Smrg	rep.clientDriverNameLength = strlen(clientDriverName);
262706f2543Smrg    rep.length = bytes_to_int32(SIZEOF(xXF86DRIGetClientDriverNameReply) -
263706f2543Smrg			SIZEOF(xGenericReply) +
264706f2543Smrg			pad_to_int32(rep.clientDriverNameLength));
265706f2543Smrg
266706f2543Smrg    WriteToClient(client,
267706f2543Smrg	sizeof(xXF86DRIGetClientDriverNameReply), (char *)&rep);
268706f2543Smrg    if (rep.clientDriverNameLength)
269706f2543Smrg	WriteToClient(client,
270706f2543Smrg                      rep.clientDriverNameLength,
271706f2543Smrg                      clientDriverName);
272706f2543Smrg    return Success;
273706f2543Smrg}
274706f2543Smrg
275706f2543Smrgstatic int
276706f2543SmrgProcXF86DRICreateContext(
277706f2543Smrg    register ClientPtr client
278706f2543Smrg)
279706f2543Smrg{
280706f2543Smrg    xXF86DRICreateContextReply	rep;
281706f2543Smrg    ScreenPtr pScreen;
282706f2543Smrg
283706f2543Smrg    REQUEST(xXF86DRICreateContextReq);
284706f2543Smrg    REQUEST_SIZE_MATCH(xXF86DRICreateContextReq);
285706f2543Smrg    if (stuff->screen >= screenInfo.numScreens) {
286706f2543Smrg	client->errorValue = stuff->screen;
287706f2543Smrg	return BadValue;
288706f2543Smrg    }
289706f2543Smrg
290706f2543Smrg    rep.type = X_Reply;
291706f2543Smrg    rep.length = 0;
292706f2543Smrg    rep.sequenceNumber = client->sequence;
293706f2543Smrg
294706f2543Smrg    pScreen = screenInfo.screens[stuff->screen];
295706f2543Smrg
296706f2543Smrg    if (!DRICreateContext( pScreen,
297706f2543Smrg			   NULL,
298706f2543Smrg			   stuff->context,
299706f2543Smrg			   (drm_context_t *)&rep.hHWContext)) {
300706f2543Smrg	return BadValue;
301706f2543Smrg    }
302706f2543Smrg
303706f2543Smrg    WriteToClient(client, sizeof(xXF86DRICreateContextReply), (char *)&rep);
304706f2543Smrg    return Success;
305706f2543Smrg}
306706f2543Smrg
307706f2543Smrgstatic int
308706f2543SmrgProcXF86DRIDestroyContext(
309706f2543Smrg    register ClientPtr client
310706f2543Smrg)
311706f2543Smrg{
312706f2543Smrg    REQUEST(xXF86DRIDestroyContextReq);
313706f2543Smrg    REQUEST_SIZE_MATCH(xXF86DRIDestroyContextReq);
314706f2543Smrg    if (stuff->screen >= screenInfo.numScreens) {
315706f2543Smrg	client->errorValue = stuff->screen;
316706f2543Smrg	return BadValue;
317706f2543Smrg    }
318706f2543Smrg
319706f2543Smrg    if (!DRIDestroyContext( screenInfo.screens[stuff->screen],
320706f2543Smrg			    stuff->context)) {
321706f2543Smrg	return BadValue;
322706f2543Smrg    }
323706f2543Smrg
324706f2543Smrg    return Success;
325706f2543Smrg}
326706f2543Smrg
327706f2543Smrgstatic int
328706f2543SmrgProcXF86DRICreateDrawable(
329706f2543Smrg    ClientPtr client
330706f2543Smrg)
331706f2543Smrg{
332706f2543Smrg    xXF86DRICreateDrawableReply	rep;
333706f2543Smrg    DrawablePtr pDrawable;
334706f2543Smrg    int rc;
335706f2543Smrg
336706f2543Smrg    REQUEST(xXF86DRICreateDrawableReq);
337706f2543Smrg    REQUEST_SIZE_MATCH(xXF86DRICreateDrawableReq);
338706f2543Smrg    if (stuff->screen >= screenInfo.numScreens) {
339706f2543Smrg	client->errorValue = stuff->screen;
340706f2543Smrg	return BadValue;
341706f2543Smrg    }
342706f2543Smrg
343706f2543Smrg    rep.type = X_Reply;
344706f2543Smrg    rep.length = 0;
345706f2543Smrg    rep.sequenceNumber = client->sequence;
346706f2543Smrg
347706f2543Smrg    rc = dixLookupDrawable(&pDrawable, stuff->drawable, client, 0,
348706f2543Smrg			   DixReadAccess);
349706f2543Smrg    if (rc != Success)
350706f2543Smrg	return rc;
351706f2543Smrg
352706f2543Smrg    if (!DRICreateDrawable(screenInfo.screens[stuff->screen], client,
353706f2543Smrg			   pDrawable, (drm_drawable_t *)&rep.hHWDrawable)) {
354706f2543Smrg	return BadValue;
355706f2543Smrg    }
356706f2543Smrg
357706f2543Smrg    WriteToClient(client, sizeof(xXF86DRICreateDrawableReply), (char *)&rep);
358706f2543Smrg    return Success;
359706f2543Smrg}
360706f2543Smrg
361706f2543Smrgstatic int
362706f2543SmrgProcXF86DRIDestroyDrawable(
363706f2543Smrg    register ClientPtr client
364706f2543Smrg)
365706f2543Smrg{
366706f2543Smrg    REQUEST(xXF86DRIDestroyDrawableReq);
367706f2543Smrg    DrawablePtr pDrawable;
368706f2543Smrg    int rc;
369706f2543Smrg    REQUEST_SIZE_MATCH(xXF86DRIDestroyDrawableReq);
370706f2543Smrg
371706f2543Smrg    if (stuff->screen >= screenInfo.numScreens) {
372706f2543Smrg	client->errorValue = stuff->screen;
373706f2543Smrg	return BadValue;
374706f2543Smrg    }
375706f2543Smrg
376706f2543Smrg    rc = dixLookupDrawable(&pDrawable, stuff->drawable, client, 0,
377706f2543Smrg			   DixReadAccess);
378706f2543Smrg    if (rc != Success)
379706f2543Smrg	return rc;
380706f2543Smrg
381706f2543Smrg    if (!DRIDestroyDrawable(screenInfo.screens[stuff->screen], client,
382706f2543Smrg			    pDrawable)) {
383706f2543Smrg	return BadValue;
384706f2543Smrg    }
385706f2543Smrg
386706f2543Smrg    return Success;
387706f2543Smrg}
388706f2543Smrg
389706f2543Smrgstatic int
390706f2543SmrgProcXF86DRIGetDrawableInfo(
391706f2543Smrg    register ClientPtr client
392706f2543Smrg)
393706f2543Smrg{
394706f2543Smrg    xXF86DRIGetDrawableInfoReply	rep;
395706f2543Smrg    DrawablePtr pDrawable;
396706f2543Smrg    int X, Y, W, H;
397706f2543Smrg    drm_clip_rect_t * pClipRects, *pClippedRects;
398706f2543Smrg    drm_clip_rect_t * pBackClipRects;
399706f2543Smrg    int backX, backY, rc;
400706f2543Smrg
401706f2543Smrg    REQUEST(xXF86DRIGetDrawableInfoReq);
402706f2543Smrg    REQUEST_SIZE_MATCH(xXF86DRIGetDrawableInfoReq);
403706f2543Smrg    if (stuff->screen >= screenInfo.numScreens) {
404706f2543Smrg	client->errorValue = stuff->screen;
405706f2543Smrg	return BadValue;
406706f2543Smrg    }
407706f2543Smrg
408706f2543Smrg    rep.type = X_Reply;
409706f2543Smrg    rep.length = 0;
410706f2543Smrg    rep.sequenceNumber = client->sequence;
411706f2543Smrg
412706f2543Smrg    rc = dixLookupDrawable(&pDrawable, stuff->drawable, client, 0,
413706f2543Smrg			   DixReadAccess);
414706f2543Smrg    if (rc != Success)
415706f2543Smrg	return rc;
416706f2543Smrg
417706f2543Smrg    if (!DRIGetDrawableInfo( screenInfo.screens[stuff->screen],
418706f2543Smrg			     pDrawable,
419706f2543Smrg			     (unsigned int*)&rep.drawableTableIndex,
420706f2543Smrg			     (unsigned int*)&rep.drawableTableStamp,
421706f2543Smrg			     (int*)&X,
422706f2543Smrg			     (int*)&Y,
423706f2543Smrg			     (int*)&W,
424706f2543Smrg			     (int*)&H,
425706f2543Smrg			     (int*)&rep.numClipRects,
426706f2543Smrg			     &pClipRects,
427706f2543Smrg			     &backX,
428706f2543Smrg			     &backY,
429706f2543Smrg			     (int*)&rep.numBackClipRects,
430706f2543Smrg			     &pBackClipRects)) {
431706f2543Smrg	return BadValue;
432706f2543Smrg    }
433706f2543Smrg
434706f2543Smrg    rep.drawableX = X;
435706f2543Smrg    rep.drawableY = Y;
436706f2543Smrg    rep.drawableWidth = W;
437706f2543Smrg    rep.drawableHeight = H;
438706f2543Smrg    rep.length = (SIZEOF(xXF86DRIGetDrawableInfoReply) -
439706f2543Smrg		  SIZEOF(xGenericReply));
440706f2543Smrg
441706f2543Smrg    rep.backX = backX;
442706f2543Smrg    rep.backY = backY;
443706f2543Smrg
444706f2543Smrg    if (rep.numBackClipRects)
445706f2543Smrg       rep.length += sizeof(drm_clip_rect_t) * rep.numBackClipRects;
446706f2543Smrg
447706f2543Smrg    pClippedRects = pClipRects;
448706f2543Smrg
449706f2543Smrg    if (rep.numClipRects) {
450706f2543Smrg       /* Clip cliprects to screen dimensions (redirected windows) */
451706f2543Smrg       pClippedRects = malloc(rep.numClipRects * sizeof(drm_clip_rect_t));
452706f2543Smrg
453706f2543Smrg       if (pClippedRects) {
454706f2543Smrg	    ScreenPtr pScreen = screenInfo.screens[stuff->screen];
455706f2543Smrg	    int i, j;
456706f2543Smrg
457706f2543Smrg	    for (i = 0, j = 0; i < rep.numClipRects; i++) {
458706f2543Smrg		pClippedRects[j].x1 = max(pClipRects[i].x1, 0);
459706f2543Smrg		pClippedRects[j].y1 = max(pClipRects[i].y1, 0);
460706f2543Smrg		pClippedRects[j].x2 = min(pClipRects[i].x2, pScreen->width);
461706f2543Smrg		pClippedRects[j].y2 = min(pClipRects[i].y2, pScreen->height);
462706f2543Smrg
463706f2543Smrg		if (pClippedRects[j].x1 < pClippedRects[j].x2 &&
464706f2543Smrg		    pClippedRects[j].y1 < pClippedRects[j].y2) {
465706f2543Smrg		    j++;
466706f2543Smrg		}
467706f2543Smrg	    }
468706f2543Smrg
469706f2543Smrg	    rep.numClipRects = j;
470706f2543Smrg       } else {
471706f2543Smrg	    rep.numClipRects = 0;
472706f2543Smrg       }
473706f2543Smrg
474706f2543Smrg       rep.length += sizeof(drm_clip_rect_t) * rep.numClipRects;
475706f2543Smrg    }
476706f2543Smrg
477706f2543Smrg    rep.length = bytes_to_int32(rep.length);
478706f2543Smrg
479706f2543Smrg    WriteToClient(client, sizeof(xXF86DRIGetDrawableInfoReply), (char *)&rep);
480706f2543Smrg
481706f2543Smrg    if (rep.numClipRects) {
482706f2543Smrg	WriteToClient(client,
483706f2543Smrg		      sizeof(drm_clip_rect_t) * rep.numClipRects,
484706f2543Smrg		      (char *)pClippedRects);
485706f2543Smrg	free(pClippedRects);
486706f2543Smrg    }
487706f2543Smrg
488706f2543Smrg    if (rep.numBackClipRects) {
489706f2543Smrg       WriteToClient(client,
490706f2543Smrg		     sizeof(drm_clip_rect_t) * rep.numBackClipRects,
491706f2543Smrg		     (char *)pBackClipRects);
492706f2543Smrg    }
493706f2543Smrg
494706f2543Smrg    return Success;
495706f2543Smrg}
496706f2543Smrg
497706f2543Smrgstatic int
498706f2543SmrgProcXF86DRIGetDeviceInfo(
499706f2543Smrg    register ClientPtr client
500706f2543Smrg)
501706f2543Smrg{
502706f2543Smrg    xXF86DRIGetDeviceInfoReply	rep;
503706f2543Smrg    drm_handle_t hFrameBuffer;
504706f2543Smrg    void *pDevPrivate;
505706f2543Smrg
506706f2543Smrg    REQUEST(xXF86DRIGetDeviceInfoReq);
507706f2543Smrg    REQUEST_SIZE_MATCH(xXF86DRIGetDeviceInfoReq);
508706f2543Smrg    if (stuff->screen >= screenInfo.numScreens) {
509706f2543Smrg	client->errorValue = stuff->screen;
510706f2543Smrg	return BadValue;
511706f2543Smrg    }
512706f2543Smrg
513706f2543Smrg    rep.type = X_Reply;
514706f2543Smrg    rep.length = 0;
515706f2543Smrg    rep.sequenceNumber = client->sequence;
516706f2543Smrg
517706f2543Smrg    if (!DRIGetDeviceInfo( screenInfo.screens[stuff->screen],
518706f2543Smrg			   &hFrameBuffer,
519706f2543Smrg			   (int*)&rep.framebufferOrigin,
520706f2543Smrg			   (int*)&rep.framebufferSize,
521706f2543Smrg			   (int*)&rep.framebufferStride,
522706f2543Smrg			   (int*)&rep.devPrivateSize,
523706f2543Smrg			   &pDevPrivate)) {
524706f2543Smrg	return BadValue;
525706f2543Smrg    }
526706f2543Smrg
527706f2543Smrg    rep.hFrameBufferLow  = (CARD32)(hFrameBuffer & 0xffffffff);
528706f2543Smrg#if defined(LONG64) && !defined(__linux__)
529706f2543Smrg    rep.hFrameBufferHigh = (CARD32)(hFrameBuffer >> 32);
530706f2543Smrg#else
531706f2543Smrg    rep.hFrameBufferHigh = 0;
532706f2543Smrg#endif
533706f2543Smrg
534706f2543Smrg    rep.length = 0;
535706f2543Smrg    if (rep.devPrivateSize) {
536706f2543Smrg	rep.length = bytes_to_int32(SIZEOF(xXF86DRIGetDeviceInfoReply) -
537706f2543Smrg		      SIZEOF(xGenericReply) +
538706f2543Smrg		      pad_to_int32(rep.devPrivateSize));
539706f2543Smrg    }
540706f2543Smrg
541706f2543Smrg    WriteToClient(client, sizeof(xXF86DRIGetDeviceInfoReply), (char *)&rep);
542706f2543Smrg    if (rep.length) {
543706f2543Smrg	WriteToClient(client, rep.devPrivateSize, (char *)pDevPrivate);
544706f2543Smrg    }
545706f2543Smrg    return Success;
546706f2543Smrg}
547706f2543Smrg
548706f2543Smrgstatic int
549706f2543SmrgProcXF86DRIDispatch (
550706f2543Smrg    register ClientPtr	client
551706f2543Smrg)
552706f2543Smrg{
553706f2543Smrg    REQUEST(xReq);
554706f2543Smrg
555706f2543Smrg    switch (stuff->data)
556706f2543Smrg    {
557706f2543Smrg    case X_XF86DRIQueryVersion:
558706f2543Smrg	return ProcXF86DRIQueryVersion(client);
559706f2543Smrg    case X_XF86DRIQueryDirectRenderingCapable:
560706f2543Smrg	return ProcXF86DRIQueryDirectRenderingCapable(client);
561706f2543Smrg    }
562706f2543Smrg
563706f2543Smrg    if (!LocalClient(client))
564706f2543Smrg	return DRIErrorBase + XF86DRIClientNotLocal;
565706f2543Smrg
566706f2543Smrg    switch (stuff->data)
567706f2543Smrg    {
568706f2543Smrg    case X_XF86DRIOpenConnection:
569706f2543Smrg	return ProcXF86DRIOpenConnection(client);
570706f2543Smrg    case X_XF86DRICloseConnection:
571706f2543Smrg	return ProcXF86DRICloseConnection(client);
572706f2543Smrg    case X_XF86DRIGetClientDriverName:
573706f2543Smrg	return ProcXF86DRIGetClientDriverName(client);
574706f2543Smrg    case X_XF86DRICreateContext:
575706f2543Smrg	return ProcXF86DRICreateContext(client);
576706f2543Smrg    case X_XF86DRIDestroyContext:
577706f2543Smrg	return ProcXF86DRIDestroyContext(client);
578706f2543Smrg    case X_XF86DRICreateDrawable:
579706f2543Smrg	return ProcXF86DRICreateDrawable(client);
580706f2543Smrg    case X_XF86DRIDestroyDrawable:
581706f2543Smrg	return ProcXF86DRIDestroyDrawable(client);
582706f2543Smrg    case X_XF86DRIGetDrawableInfo:
583706f2543Smrg	return ProcXF86DRIGetDrawableInfo(client);
584706f2543Smrg    case X_XF86DRIGetDeviceInfo:
585706f2543Smrg	return ProcXF86DRIGetDeviceInfo(client);
586706f2543Smrg    case X_XF86DRIAuthConnection:
587706f2543Smrg	return ProcXF86DRIAuthConnection(client);
588706f2543Smrg    /* {Open,Close}FullScreen are deprecated now */
589706f2543Smrg    default:
590706f2543Smrg	return BadRequest;
591706f2543Smrg    }
592706f2543Smrg}
593706f2543Smrg
594706f2543Smrgstatic int
595706f2543SmrgSProcXF86DRIQueryVersion(
596706f2543Smrg    register ClientPtr	client
597706f2543Smrg)
598706f2543Smrg{
599706f2543Smrg    register int n;
600706f2543Smrg    REQUEST(xXF86DRIQueryVersionReq);
601706f2543Smrg    swaps(&stuff->length, n);
602706f2543Smrg    return ProcXF86DRIQueryVersion(client);
603706f2543Smrg}
604706f2543Smrg
605706f2543Smrgstatic int
606706f2543SmrgSProcXF86DRIQueryDirectRenderingCapable(
607706f2543Smrg    register ClientPtr client
608706f2543Smrg)
609706f2543Smrg{
610706f2543Smrg    register int n;
611706f2543Smrg    REQUEST(xXF86DRIQueryDirectRenderingCapableReq);
61248a68b89Smrg    REQUEST_SIZE_MATCH(xXF86DRIQueryDirectRenderingCapableReq);
613706f2543Smrg    swaps(&stuff->length, n);
614706f2543Smrg    swapl(&stuff->screen, n);
615706f2543Smrg    return ProcXF86DRIQueryDirectRenderingCapable(client);
616706f2543Smrg}
617706f2543Smrg
618706f2543Smrgstatic int
619706f2543SmrgSProcXF86DRIDispatch (
620706f2543Smrg    register ClientPtr	client
621706f2543Smrg)
622706f2543Smrg{
623706f2543Smrg    REQUEST(xReq);
624706f2543Smrg
625706f2543Smrg    /*
626706f2543Smrg     * Only local clients are allowed DRI access, but remote clients still need
627706f2543Smrg     * these requests to find out cleanly.
628706f2543Smrg     */
629706f2543Smrg    switch (stuff->data)
630706f2543Smrg    {
631706f2543Smrg    case X_XF86DRIQueryVersion:
632706f2543Smrg	return SProcXF86DRIQueryVersion(client);
633706f2543Smrg    case X_XF86DRIQueryDirectRenderingCapable:
634706f2543Smrg	return SProcXF86DRIQueryDirectRenderingCapable(client);
635706f2543Smrg    default:
636706f2543Smrg	return DRIErrorBase + XF86DRIClientNotLocal;
637706f2543Smrg    }
638706f2543Smrg}
639706f2543Smrg
640706f2543Smrgvoid
641706f2543SmrgXFree86DRIExtensionInit(void)
642706f2543Smrg{
643706f2543Smrg    ExtensionEntry* extEntry;
644706f2543Smrg
645706f2543Smrg#ifdef XF86DRI_EVENTS
646706f2543Smrg    EventType = CreateNewResourceType(XF86DRIFreeEvents, "DRIEvent");
647706f2543Smrg#endif
648706f2543Smrg
649706f2543Smrg    if (
650706f2543Smrg	DRIExtensionInit() &&
651706f2543Smrg#ifdef XF86DRI_EVENTS
652706f2543Smrg        EventType && ScreenPrivateIndex != -1 &&
653706f2543Smrg#endif
654706f2543Smrg	(extEntry = AddExtension(XF86DRINAME,
655706f2543Smrg				 XF86DRINumberEvents,
656706f2543Smrg				 XF86DRINumberErrors,
657706f2543Smrg				 ProcXF86DRIDispatch,
658706f2543Smrg				 SProcXF86DRIDispatch,
659706f2543Smrg				 XF86DRIResetProc,
660706f2543Smrg				 StandardMinorOpcode))) {
661706f2543Smrg	DRIReqCode = (unsigned char)extEntry->base;
662706f2543Smrg	DRIErrorBase = extEntry->errorBase;
663706f2543Smrg    }
664706f2543Smrg}
665