1*4882a593Smuzhiyun /**************************************************************************
2*4882a593Smuzhiyun
3*4882a593Smuzhiyun Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
4*4882a593Smuzhiyun Copyright 2000 VA Linux Systems, Inc.
5*4882a593Smuzhiyun All Rights Reserved.
6*4882a593Smuzhiyun
7*4882a593Smuzhiyun Permission is hereby granted, free of charge, to any person obtaining a
8*4882a593Smuzhiyun copy of this software and associated documentation files (the
9*4882a593Smuzhiyun "Software"), to deal in the Software without restriction, including
10*4882a593Smuzhiyun without limitation the rights to use, copy, modify, merge, publish,
11*4882a593Smuzhiyun distribute, sub license, and/or sell copies of the Software, and to
12*4882a593Smuzhiyun permit persons to whom the Software is furnished to do so, subject to
13*4882a593Smuzhiyun the following conditions:
14*4882a593Smuzhiyun
15*4882a593Smuzhiyun The above copyright notice and this permission notice (including the
16*4882a593Smuzhiyun next paragraph) shall be included in all copies or substantial portions
17*4882a593Smuzhiyun of the Software.
18*4882a593Smuzhiyun
19*4882a593Smuzhiyun THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20*4882a593Smuzhiyun OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21*4882a593Smuzhiyun MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
22*4882a593Smuzhiyun IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
23*4882a593Smuzhiyun ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
24*4882a593Smuzhiyun TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
25*4882a593Smuzhiyun SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26*4882a593Smuzhiyun
27*4882a593Smuzhiyun **************************************************************************/
28*4882a593Smuzhiyun
29*4882a593Smuzhiyun /*
30*4882a593Smuzhiyun * Authors:
31*4882a593Smuzhiyun * Kevin E. Martin <martin@valinux.com>
32*4882a593Smuzhiyun * Jens Owen <jens@tungstengraphics.com>
33*4882a593Smuzhiyun * Rickard E. (Rik) Faith <faith@valinux.com>
34*4882a593Smuzhiyun *
35*4882a593Smuzhiyun */
36*4882a593Smuzhiyun
37*4882a593Smuzhiyun #ifdef HAVE_XORG_CONFIG_H
38*4882a593Smuzhiyun #include <xorg-config.h>
39*4882a593Smuzhiyun #endif
40*4882a593Smuzhiyun
41*4882a593Smuzhiyun #include <string.h>
42*4882a593Smuzhiyun
43*4882a593Smuzhiyun #include "xf86.h"
44*4882a593Smuzhiyun
45*4882a593Smuzhiyun #include <X11/X.h>
46*4882a593Smuzhiyun #include <X11/Xproto.h>
47*4882a593Smuzhiyun #include "misc.h"
48*4882a593Smuzhiyun #include "dixstruct.h"
49*4882a593Smuzhiyun #include "extnsionst.h"
50*4882a593Smuzhiyun #include "extinit.h"
51*4882a593Smuzhiyun #include "colormapst.h"
52*4882a593Smuzhiyun #include "cursorstr.h"
53*4882a593Smuzhiyun #include "scrnintstr.h"
54*4882a593Smuzhiyun #include "servermd.h"
55*4882a593Smuzhiyun #define _XF86DRI_SERVER_
56*4882a593Smuzhiyun #include <X11/dri/xf86driproto.h>
57*4882a593Smuzhiyun #include "swaprep.h"
58*4882a593Smuzhiyun #include "xf86str.h"
59*4882a593Smuzhiyun #include "dri.h"
60*4882a593Smuzhiyun #include "sarea.h"
61*4882a593Smuzhiyun #include "dristruct.h"
62*4882a593Smuzhiyun #include "xf86drm.h"
63*4882a593Smuzhiyun #include "protocol-versions.h"
64*4882a593Smuzhiyun #include "xf86Extensions.h"
65*4882a593Smuzhiyun
66*4882a593Smuzhiyun static int DRIErrorBase;
67*4882a593Smuzhiyun
68*4882a593Smuzhiyun static void XF86DRIResetProc(ExtensionEntry *extEntry);
69*4882a593Smuzhiyun
70*4882a593Smuzhiyun static unsigned char DRIReqCode = 0;
71*4882a593Smuzhiyun
72*4882a593Smuzhiyun /*ARGSUSED*/
73*4882a593Smuzhiyun static void
XF86DRIResetProc(ExtensionEntry * extEntry)74*4882a593Smuzhiyun XF86DRIResetProc(ExtensionEntry *extEntry)
75*4882a593Smuzhiyun {
76*4882a593Smuzhiyun DRIReset();
77*4882a593Smuzhiyun }
78*4882a593Smuzhiyun
79*4882a593Smuzhiyun static int
ProcXF86DRIQueryVersion(register ClientPtr client)80*4882a593Smuzhiyun ProcXF86DRIQueryVersion(register ClientPtr client)
81*4882a593Smuzhiyun {
82*4882a593Smuzhiyun xXF86DRIQueryVersionReply rep = {
83*4882a593Smuzhiyun .type = X_Reply,
84*4882a593Smuzhiyun .sequenceNumber = client->sequence,
85*4882a593Smuzhiyun .length = 0,
86*4882a593Smuzhiyun .majorVersion = SERVER_XF86DRI_MAJOR_VERSION,
87*4882a593Smuzhiyun .minorVersion = SERVER_XF86DRI_MINOR_VERSION,
88*4882a593Smuzhiyun .patchVersion = SERVER_XF86DRI_PATCH_VERSION
89*4882a593Smuzhiyun };
90*4882a593Smuzhiyun
91*4882a593Smuzhiyun REQUEST_SIZE_MATCH(xXF86DRIQueryVersionReq);
92*4882a593Smuzhiyun if (client->swapped) {
93*4882a593Smuzhiyun swaps(&rep.sequenceNumber);
94*4882a593Smuzhiyun swapl(&rep.length);
95*4882a593Smuzhiyun swaps(&rep.majorVersion);
96*4882a593Smuzhiyun swaps(&rep.minorVersion);
97*4882a593Smuzhiyun swapl(&rep.patchVersion);
98*4882a593Smuzhiyun }
99*4882a593Smuzhiyun WriteToClient(client, sizeof(xXF86DRIQueryVersionReply), &rep);
100*4882a593Smuzhiyun return Success;
101*4882a593Smuzhiyun }
102*4882a593Smuzhiyun
103*4882a593Smuzhiyun static int
ProcXF86DRIQueryDirectRenderingCapable(register ClientPtr client)104*4882a593Smuzhiyun ProcXF86DRIQueryDirectRenderingCapable(register ClientPtr client)
105*4882a593Smuzhiyun {
106*4882a593Smuzhiyun xXF86DRIQueryDirectRenderingCapableReply rep;
107*4882a593Smuzhiyun Bool isCapable;
108*4882a593Smuzhiyun
109*4882a593Smuzhiyun REQUEST(xXF86DRIQueryDirectRenderingCapableReq);
110*4882a593Smuzhiyun REQUEST_SIZE_MATCH(xXF86DRIQueryDirectRenderingCapableReq);
111*4882a593Smuzhiyun if (stuff->screen >= screenInfo.numScreens) {
112*4882a593Smuzhiyun client->errorValue = stuff->screen;
113*4882a593Smuzhiyun return BadValue;
114*4882a593Smuzhiyun }
115*4882a593Smuzhiyun
116*4882a593Smuzhiyun if (!DRIQueryDirectRenderingCapable(screenInfo.screens[stuff->screen],
117*4882a593Smuzhiyun &isCapable)) {
118*4882a593Smuzhiyun return BadValue;
119*4882a593Smuzhiyun }
120*4882a593Smuzhiyun
121*4882a593Smuzhiyun if (!client->local || client->swapped)
122*4882a593Smuzhiyun isCapable = 0;
123*4882a593Smuzhiyun
124*4882a593Smuzhiyun rep = (xXF86DRIQueryDirectRenderingCapableReply) {
125*4882a593Smuzhiyun .type = X_Reply,
126*4882a593Smuzhiyun .sequenceNumber = client->sequence,
127*4882a593Smuzhiyun .length = 0,
128*4882a593Smuzhiyun .isCapable = isCapable
129*4882a593Smuzhiyun };
130*4882a593Smuzhiyun
131*4882a593Smuzhiyun if (client->swapped) {
132*4882a593Smuzhiyun swaps(&rep.sequenceNumber);
133*4882a593Smuzhiyun swapl(&rep.length);
134*4882a593Smuzhiyun }
135*4882a593Smuzhiyun
136*4882a593Smuzhiyun WriteToClient(client,
137*4882a593Smuzhiyun sizeof(xXF86DRIQueryDirectRenderingCapableReply),
138*4882a593Smuzhiyun &rep);
139*4882a593Smuzhiyun return Success;
140*4882a593Smuzhiyun }
141*4882a593Smuzhiyun
142*4882a593Smuzhiyun static int
ProcXF86DRIOpenConnection(register ClientPtr client)143*4882a593Smuzhiyun ProcXF86DRIOpenConnection(register ClientPtr client)
144*4882a593Smuzhiyun {
145*4882a593Smuzhiyun xXF86DRIOpenConnectionReply rep;
146*4882a593Smuzhiyun drm_handle_t hSAREA;
147*4882a593Smuzhiyun char *busIdString;
148*4882a593Smuzhiyun CARD32 busIdStringLength = 0;
149*4882a593Smuzhiyun
150*4882a593Smuzhiyun REQUEST(xXF86DRIOpenConnectionReq);
151*4882a593Smuzhiyun REQUEST_SIZE_MATCH(xXF86DRIOpenConnectionReq);
152*4882a593Smuzhiyun if (stuff->screen >= screenInfo.numScreens) {
153*4882a593Smuzhiyun client->errorValue = stuff->screen;
154*4882a593Smuzhiyun return BadValue;
155*4882a593Smuzhiyun }
156*4882a593Smuzhiyun
157*4882a593Smuzhiyun if (!DRIOpenConnection(screenInfo.screens[stuff->screen],
158*4882a593Smuzhiyun &hSAREA, &busIdString)) {
159*4882a593Smuzhiyun return BadValue;
160*4882a593Smuzhiyun }
161*4882a593Smuzhiyun
162*4882a593Smuzhiyun if (busIdString)
163*4882a593Smuzhiyun busIdStringLength = strlen(busIdString);
164*4882a593Smuzhiyun
165*4882a593Smuzhiyun rep = (xXF86DRIOpenConnectionReply) {
166*4882a593Smuzhiyun .type = X_Reply,
167*4882a593Smuzhiyun .sequenceNumber = client->sequence,
168*4882a593Smuzhiyun .length = bytes_to_int32(SIZEOF(xXF86DRIOpenConnectionReply) -
169*4882a593Smuzhiyun SIZEOF(xGenericReply) +
170*4882a593Smuzhiyun pad_to_int32(busIdStringLength)),
171*4882a593Smuzhiyun .busIdStringLength = busIdStringLength,
172*4882a593Smuzhiyun
173*4882a593Smuzhiyun .hSAREALow = (CARD32) (hSAREA & 0xffffffff),
174*4882a593Smuzhiyun #if defined(LONG64) && !defined(__linux__)
175*4882a593Smuzhiyun .hSAREAHigh = (CARD32) (hSAREA >> 32),
176*4882a593Smuzhiyun #else
177*4882a593Smuzhiyun .hSAREAHigh = 0
178*4882a593Smuzhiyun #endif
179*4882a593Smuzhiyun };
180*4882a593Smuzhiyun
181*4882a593Smuzhiyun WriteToClient(client, sizeof(xXF86DRIOpenConnectionReply), &rep);
182*4882a593Smuzhiyun if (busIdStringLength)
183*4882a593Smuzhiyun WriteToClient(client, busIdStringLength, busIdString);
184*4882a593Smuzhiyun return Success;
185*4882a593Smuzhiyun }
186*4882a593Smuzhiyun
187*4882a593Smuzhiyun static int
ProcXF86DRIAuthConnection(register ClientPtr client)188*4882a593Smuzhiyun ProcXF86DRIAuthConnection(register ClientPtr client)
189*4882a593Smuzhiyun {
190*4882a593Smuzhiyun xXF86DRIAuthConnectionReply rep = {
191*4882a593Smuzhiyun .type = X_Reply,
192*4882a593Smuzhiyun .sequenceNumber = client->sequence,
193*4882a593Smuzhiyun .length = 0,
194*4882a593Smuzhiyun .authenticated = 1
195*4882a593Smuzhiyun };
196*4882a593Smuzhiyun
197*4882a593Smuzhiyun REQUEST(xXF86DRIAuthConnectionReq);
198*4882a593Smuzhiyun REQUEST_SIZE_MATCH(xXF86DRIAuthConnectionReq);
199*4882a593Smuzhiyun if (stuff->screen >= screenInfo.numScreens) {
200*4882a593Smuzhiyun client->errorValue = stuff->screen;
201*4882a593Smuzhiyun return BadValue;
202*4882a593Smuzhiyun }
203*4882a593Smuzhiyun
204*4882a593Smuzhiyun if (!DRIAuthConnection(screenInfo.screens[stuff->screen], stuff->magic)) {
205*4882a593Smuzhiyun ErrorF("Failed to authenticate %lu\n", (unsigned long) stuff->magic);
206*4882a593Smuzhiyun rep.authenticated = 0;
207*4882a593Smuzhiyun }
208*4882a593Smuzhiyun WriteToClient(client, sizeof(xXF86DRIAuthConnectionReply), &rep);
209*4882a593Smuzhiyun return Success;
210*4882a593Smuzhiyun }
211*4882a593Smuzhiyun
212*4882a593Smuzhiyun static int
ProcXF86DRICloseConnection(register ClientPtr client)213*4882a593Smuzhiyun ProcXF86DRICloseConnection(register ClientPtr client)
214*4882a593Smuzhiyun {
215*4882a593Smuzhiyun REQUEST(xXF86DRICloseConnectionReq);
216*4882a593Smuzhiyun REQUEST_SIZE_MATCH(xXF86DRICloseConnectionReq);
217*4882a593Smuzhiyun if (stuff->screen >= screenInfo.numScreens) {
218*4882a593Smuzhiyun client->errorValue = stuff->screen;
219*4882a593Smuzhiyun return BadValue;
220*4882a593Smuzhiyun }
221*4882a593Smuzhiyun
222*4882a593Smuzhiyun DRICloseConnection(screenInfo.screens[stuff->screen]);
223*4882a593Smuzhiyun
224*4882a593Smuzhiyun return Success;
225*4882a593Smuzhiyun }
226*4882a593Smuzhiyun
227*4882a593Smuzhiyun static int
ProcXF86DRIGetClientDriverName(register ClientPtr client)228*4882a593Smuzhiyun ProcXF86DRIGetClientDriverName(register ClientPtr client)
229*4882a593Smuzhiyun {
230*4882a593Smuzhiyun xXF86DRIGetClientDriverNameReply rep = {
231*4882a593Smuzhiyun .type = X_Reply,
232*4882a593Smuzhiyun .sequenceNumber = client->sequence,
233*4882a593Smuzhiyun .clientDriverNameLength = 0
234*4882a593Smuzhiyun };
235*4882a593Smuzhiyun char *clientDriverName;
236*4882a593Smuzhiyun
237*4882a593Smuzhiyun REQUEST(xXF86DRIGetClientDriverNameReq);
238*4882a593Smuzhiyun REQUEST_SIZE_MATCH(xXF86DRIGetClientDriverNameReq);
239*4882a593Smuzhiyun if (stuff->screen >= screenInfo.numScreens) {
240*4882a593Smuzhiyun client->errorValue = stuff->screen;
241*4882a593Smuzhiyun return BadValue;
242*4882a593Smuzhiyun }
243*4882a593Smuzhiyun
244*4882a593Smuzhiyun DRIGetClientDriverName(screenInfo.screens[stuff->screen],
245*4882a593Smuzhiyun (int *) &rep.ddxDriverMajorVersion,
246*4882a593Smuzhiyun (int *) &rep.ddxDriverMinorVersion,
247*4882a593Smuzhiyun (int *) &rep.ddxDriverPatchVersion,
248*4882a593Smuzhiyun &clientDriverName);
249*4882a593Smuzhiyun
250*4882a593Smuzhiyun if (clientDriverName)
251*4882a593Smuzhiyun rep.clientDriverNameLength = strlen(clientDriverName);
252*4882a593Smuzhiyun rep.length = bytes_to_int32(SIZEOF(xXF86DRIGetClientDriverNameReply) -
253*4882a593Smuzhiyun SIZEOF(xGenericReply) +
254*4882a593Smuzhiyun pad_to_int32(rep.clientDriverNameLength));
255*4882a593Smuzhiyun
256*4882a593Smuzhiyun WriteToClient(client, sizeof(xXF86DRIGetClientDriverNameReply), &rep);
257*4882a593Smuzhiyun if (rep.clientDriverNameLength)
258*4882a593Smuzhiyun WriteToClient(client, rep.clientDriverNameLength, clientDriverName);
259*4882a593Smuzhiyun return Success;
260*4882a593Smuzhiyun }
261*4882a593Smuzhiyun
262*4882a593Smuzhiyun static int
ProcXF86DRICreateContext(register ClientPtr client)263*4882a593Smuzhiyun ProcXF86DRICreateContext(register ClientPtr client)
264*4882a593Smuzhiyun {
265*4882a593Smuzhiyun xXF86DRICreateContextReply rep = {
266*4882a593Smuzhiyun .type = X_Reply,
267*4882a593Smuzhiyun .sequenceNumber = client->sequence,
268*4882a593Smuzhiyun .length = 0
269*4882a593Smuzhiyun };
270*4882a593Smuzhiyun ScreenPtr pScreen;
271*4882a593Smuzhiyun
272*4882a593Smuzhiyun REQUEST(xXF86DRICreateContextReq);
273*4882a593Smuzhiyun REQUEST_SIZE_MATCH(xXF86DRICreateContextReq);
274*4882a593Smuzhiyun if (stuff->screen >= screenInfo.numScreens) {
275*4882a593Smuzhiyun client->errorValue = stuff->screen;
276*4882a593Smuzhiyun return BadValue;
277*4882a593Smuzhiyun }
278*4882a593Smuzhiyun
279*4882a593Smuzhiyun pScreen = screenInfo.screens[stuff->screen];
280*4882a593Smuzhiyun
281*4882a593Smuzhiyun if (!DRICreateContext(pScreen,
282*4882a593Smuzhiyun NULL,
283*4882a593Smuzhiyun stuff->context, (drm_context_t *) &rep.hHWContext)) {
284*4882a593Smuzhiyun return BadValue;
285*4882a593Smuzhiyun }
286*4882a593Smuzhiyun
287*4882a593Smuzhiyun WriteToClient(client, sizeof(xXF86DRICreateContextReply), &rep);
288*4882a593Smuzhiyun return Success;
289*4882a593Smuzhiyun }
290*4882a593Smuzhiyun
291*4882a593Smuzhiyun static int
ProcXF86DRIDestroyContext(register ClientPtr client)292*4882a593Smuzhiyun ProcXF86DRIDestroyContext(register ClientPtr client)
293*4882a593Smuzhiyun {
294*4882a593Smuzhiyun REQUEST(xXF86DRIDestroyContextReq);
295*4882a593Smuzhiyun REQUEST_SIZE_MATCH(xXF86DRIDestroyContextReq);
296*4882a593Smuzhiyun if (stuff->screen >= screenInfo.numScreens) {
297*4882a593Smuzhiyun client->errorValue = stuff->screen;
298*4882a593Smuzhiyun return BadValue;
299*4882a593Smuzhiyun }
300*4882a593Smuzhiyun
301*4882a593Smuzhiyun if (!DRIDestroyContext(screenInfo.screens[stuff->screen], stuff->context)) {
302*4882a593Smuzhiyun return BadValue;
303*4882a593Smuzhiyun }
304*4882a593Smuzhiyun
305*4882a593Smuzhiyun return Success;
306*4882a593Smuzhiyun }
307*4882a593Smuzhiyun
308*4882a593Smuzhiyun static int
ProcXF86DRICreateDrawable(ClientPtr client)309*4882a593Smuzhiyun ProcXF86DRICreateDrawable(ClientPtr client)
310*4882a593Smuzhiyun {
311*4882a593Smuzhiyun xXF86DRICreateDrawableReply rep = {
312*4882a593Smuzhiyun .type = X_Reply,
313*4882a593Smuzhiyun .sequenceNumber = client->sequence,
314*4882a593Smuzhiyun .length = 0
315*4882a593Smuzhiyun };
316*4882a593Smuzhiyun DrawablePtr pDrawable;
317*4882a593Smuzhiyun int rc;
318*4882a593Smuzhiyun
319*4882a593Smuzhiyun REQUEST(xXF86DRICreateDrawableReq);
320*4882a593Smuzhiyun REQUEST_SIZE_MATCH(xXF86DRICreateDrawableReq);
321*4882a593Smuzhiyun if (stuff->screen >= screenInfo.numScreens) {
322*4882a593Smuzhiyun client->errorValue = stuff->screen;
323*4882a593Smuzhiyun return BadValue;
324*4882a593Smuzhiyun }
325*4882a593Smuzhiyun
326*4882a593Smuzhiyun rc = dixLookupDrawable(&pDrawable, stuff->drawable, client, 0,
327*4882a593Smuzhiyun DixReadAccess);
328*4882a593Smuzhiyun if (rc != Success)
329*4882a593Smuzhiyun return rc;
330*4882a593Smuzhiyun
331*4882a593Smuzhiyun if (!DRICreateDrawable(screenInfo.screens[stuff->screen], client,
332*4882a593Smuzhiyun pDrawable, (drm_drawable_t *) &rep.hHWDrawable)) {
333*4882a593Smuzhiyun return BadValue;
334*4882a593Smuzhiyun }
335*4882a593Smuzhiyun
336*4882a593Smuzhiyun WriteToClient(client, sizeof(xXF86DRICreateDrawableReply), &rep);
337*4882a593Smuzhiyun return Success;
338*4882a593Smuzhiyun }
339*4882a593Smuzhiyun
340*4882a593Smuzhiyun static int
ProcXF86DRIDestroyDrawable(register ClientPtr client)341*4882a593Smuzhiyun ProcXF86DRIDestroyDrawable(register ClientPtr client)
342*4882a593Smuzhiyun {
343*4882a593Smuzhiyun REQUEST(xXF86DRIDestroyDrawableReq);
344*4882a593Smuzhiyun DrawablePtr pDrawable;
345*4882a593Smuzhiyun int rc;
346*4882a593Smuzhiyun
347*4882a593Smuzhiyun REQUEST_SIZE_MATCH(xXF86DRIDestroyDrawableReq);
348*4882a593Smuzhiyun
349*4882a593Smuzhiyun if (stuff->screen >= screenInfo.numScreens) {
350*4882a593Smuzhiyun client->errorValue = stuff->screen;
351*4882a593Smuzhiyun return BadValue;
352*4882a593Smuzhiyun }
353*4882a593Smuzhiyun
354*4882a593Smuzhiyun rc = dixLookupDrawable(&pDrawable, stuff->drawable, client, 0,
355*4882a593Smuzhiyun DixReadAccess);
356*4882a593Smuzhiyun if (rc != Success)
357*4882a593Smuzhiyun return rc;
358*4882a593Smuzhiyun
359*4882a593Smuzhiyun if (!DRIDestroyDrawable(screenInfo.screens[stuff->screen], client,
360*4882a593Smuzhiyun pDrawable)) {
361*4882a593Smuzhiyun return BadValue;
362*4882a593Smuzhiyun }
363*4882a593Smuzhiyun
364*4882a593Smuzhiyun return Success;
365*4882a593Smuzhiyun }
366*4882a593Smuzhiyun
367*4882a593Smuzhiyun static int
ProcXF86DRIGetDrawableInfo(register ClientPtr client)368*4882a593Smuzhiyun ProcXF86DRIGetDrawableInfo(register ClientPtr client)
369*4882a593Smuzhiyun {
370*4882a593Smuzhiyun xXF86DRIGetDrawableInfoReply rep = {
371*4882a593Smuzhiyun .type = X_Reply,
372*4882a593Smuzhiyun .sequenceNumber = client->sequence,
373*4882a593Smuzhiyun .length = 0
374*4882a593Smuzhiyun };
375*4882a593Smuzhiyun DrawablePtr pDrawable;
376*4882a593Smuzhiyun int X, Y, W, H;
377*4882a593Smuzhiyun drm_clip_rect_t *pClipRects, *pClippedRects;
378*4882a593Smuzhiyun drm_clip_rect_t *pBackClipRects;
379*4882a593Smuzhiyun int backX, backY, rc;
380*4882a593Smuzhiyun
381*4882a593Smuzhiyun REQUEST(xXF86DRIGetDrawableInfoReq);
382*4882a593Smuzhiyun REQUEST_SIZE_MATCH(xXF86DRIGetDrawableInfoReq);
383*4882a593Smuzhiyun if (stuff->screen >= screenInfo.numScreens) {
384*4882a593Smuzhiyun client->errorValue = stuff->screen;
385*4882a593Smuzhiyun return BadValue;
386*4882a593Smuzhiyun }
387*4882a593Smuzhiyun
388*4882a593Smuzhiyun rc = dixLookupDrawable(&pDrawable, stuff->drawable, client, 0,
389*4882a593Smuzhiyun DixReadAccess);
390*4882a593Smuzhiyun if (rc != Success)
391*4882a593Smuzhiyun return rc;
392*4882a593Smuzhiyun
393*4882a593Smuzhiyun if (!DRIGetDrawableInfo(screenInfo.screens[stuff->screen],
394*4882a593Smuzhiyun pDrawable,
395*4882a593Smuzhiyun (unsigned int *) &rep.drawableTableIndex,
396*4882a593Smuzhiyun (unsigned int *) &rep.drawableTableStamp,
397*4882a593Smuzhiyun (int *) &X,
398*4882a593Smuzhiyun (int *) &Y,
399*4882a593Smuzhiyun (int *) &W,
400*4882a593Smuzhiyun (int *) &H,
401*4882a593Smuzhiyun (int *) &rep.numClipRects,
402*4882a593Smuzhiyun &pClipRects,
403*4882a593Smuzhiyun &backX,
404*4882a593Smuzhiyun &backY,
405*4882a593Smuzhiyun (int *) &rep.numBackClipRects, &pBackClipRects)) {
406*4882a593Smuzhiyun return BadValue;
407*4882a593Smuzhiyun }
408*4882a593Smuzhiyun
409*4882a593Smuzhiyun rep.drawableX = X;
410*4882a593Smuzhiyun rep.drawableY = Y;
411*4882a593Smuzhiyun rep.drawableWidth = W;
412*4882a593Smuzhiyun rep.drawableHeight = H;
413*4882a593Smuzhiyun rep.length = (SIZEOF(xXF86DRIGetDrawableInfoReply) - SIZEOF(xGenericReply));
414*4882a593Smuzhiyun
415*4882a593Smuzhiyun rep.backX = backX;
416*4882a593Smuzhiyun rep.backY = backY;
417*4882a593Smuzhiyun
418*4882a593Smuzhiyun if (rep.numBackClipRects)
419*4882a593Smuzhiyun rep.length += sizeof(drm_clip_rect_t) * rep.numBackClipRects;
420*4882a593Smuzhiyun
421*4882a593Smuzhiyun pClippedRects = pClipRects;
422*4882a593Smuzhiyun
423*4882a593Smuzhiyun if (rep.numClipRects) {
424*4882a593Smuzhiyun /* Clip cliprects to screen dimensions (redirected windows) */
425*4882a593Smuzhiyun pClippedRects = xallocarray(rep.numClipRects, sizeof(drm_clip_rect_t));
426*4882a593Smuzhiyun
427*4882a593Smuzhiyun if (pClippedRects) {
428*4882a593Smuzhiyun ScreenPtr pScreen = screenInfo.screens[stuff->screen];
429*4882a593Smuzhiyun int i, j;
430*4882a593Smuzhiyun
431*4882a593Smuzhiyun for (i = 0, j = 0; i < rep.numClipRects; i++) {
432*4882a593Smuzhiyun pClippedRects[j].x1 = max(pClipRects[i].x1, 0);
433*4882a593Smuzhiyun pClippedRects[j].y1 = max(pClipRects[i].y1, 0);
434*4882a593Smuzhiyun pClippedRects[j].x2 = min(pClipRects[i].x2, pScreen->width);
435*4882a593Smuzhiyun pClippedRects[j].y2 = min(pClipRects[i].y2, pScreen->height);
436*4882a593Smuzhiyun
437*4882a593Smuzhiyun if (pClippedRects[j].x1 < pClippedRects[j].x2 &&
438*4882a593Smuzhiyun pClippedRects[j].y1 < pClippedRects[j].y2) {
439*4882a593Smuzhiyun j++;
440*4882a593Smuzhiyun }
441*4882a593Smuzhiyun }
442*4882a593Smuzhiyun
443*4882a593Smuzhiyun rep.numClipRects = j;
444*4882a593Smuzhiyun }
445*4882a593Smuzhiyun else {
446*4882a593Smuzhiyun rep.numClipRects = 0;
447*4882a593Smuzhiyun }
448*4882a593Smuzhiyun
449*4882a593Smuzhiyun rep.length += sizeof(drm_clip_rect_t) * rep.numClipRects;
450*4882a593Smuzhiyun }
451*4882a593Smuzhiyun
452*4882a593Smuzhiyun rep.length = bytes_to_int32(rep.length);
453*4882a593Smuzhiyun
454*4882a593Smuzhiyun WriteToClient(client, sizeof(xXF86DRIGetDrawableInfoReply), &rep);
455*4882a593Smuzhiyun
456*4882a593Smuzhiyun if (rep.numClipRects) {
457*4882a593Smuzhiyun WriteToClient(client,
458*4882a593Smuzhiyun sizeof(drm_clip_rect_t) * rep.numClipRects,
459*4882a593Smuzhiyun pClippedRects);
460*4882a593Smuzhiyun free(pClippedRects);
461*4882a593Smuzhiyun }
462*4882a593Smuzhiyun
463*4882a593Smuzhiyun if (rep.numBackClipRects) {
464*4882a593Smuzhiyun WriteToClient(client,
465*4882a593Smuzhiyun sizeof(drm_clip_rect_t) * rep.numBackClipRects,
466*4882a593Smuzhiyun pBackClipRects);
467*4882a593Smuzhiyun }
468*4882a593Smuzhiyun
469*4882a593Smuzhiyun return Success;
470*4882a593Smuzhiyun }
471*4882a593Smuzhiyun
472*4882a593Smuzhiyun static int
ProcXF86DRIGetDeviceInfo(register ClientPtr client)473*4882a593Smuzhiyun ProcXF86DRIGetDeviceInfo(register ClientPtr client)
474*4882a593Smuzhiyun {
475*4882a593Smuzhiyun xXF86DRIGetDeviceInfoReply rep = {
476*4882a593Smuzhiyun .type = X_Reply,
477*4882a593Smuzhiyun .sequenceNumber = client->sequence,
478*4882a593Smuzhiyun .length = 0
479*4882a593Smuzhiyun };
480*4882a593Smuzhiyun drm_handle_t hFrameBuffer;
481*4882a593Smuzhiyun void *pDevPrivate;
482*4882a593Smuzhiyun
483*4882a593Smuzhiyun REQUEST(xXF86DRIGetDeviceInfoReq);
484*4882a593Smuzhiyun REQUEST_SIZE_MATCH(xXF86DRIGetDeviceInfoReq);
485*4882a593Smuzhiyun if (stuff->screen >= screenInfo.numScreens) {
486*4882a593Smuzhiyun client->errorValue = stuff->screen;
487*4882a593Smuzhiyun return BadValue;
488*4882a593Smuzhiyun }
489*4882a593Smuzhiyun
490*4882a593Smuzhiyun if (!DRIGetDeviceInfo(screenInfo.screens[stuff->screen],
491*4882a593Smuzhiyun &hFrameBuffer,
492*4882a593Smuzhiyun (int *) &rep.framebufferOrigin,
493*4882a593Smuzhiyun (int *) &rep.framebufferSize,
494*4882a593Smuzhiyun (int *) &rep.framebufferStride,
495*4882a593Smuzhiyun (int *) &rep.devPrivateSize, &pDevPrivate)) {
496*4882a593Smuzhiyun return BadValue;
497*4882a593Smuzhiyun }
498*4882a593Smuzhiyun
499*4882a593Smuzhiyun rep.hFrameBufferLow = (CARD32) (hFrameBuffer & 0xffffffff);
500*4882a593Smuzhiyun #if defined(LONG64) && !defined(__linux__)
501*4882a593Smuzhiyun rep.hFrameBufferHigh = (CARD32) (hFrameBuffer >> 32);
502*4882a593Smuzhiyun #else
503*4882a593Smuzhiyun rep.hFrameBufferHigh = 0;
504*4882a593Smuzhiyun #endif
505*4882a593Smuzhiyun
506*4882a593Smuzhiyun if (rep.devPrivateSize) {
507*4882a593Smuzhiyun rep.length = bytes_to_int32(SIZEOF(xXF86DRIGetDeviceInfoReply) -
508*4882a593Smuzhiyun SIZEOF(xGenericReply) +
509*4882a593Smuzhiyun pad_to_int32(rep.devPrivateSize));
510*4882a593Smuzhiyun }
511*4882a593Smuzhiyun
512*4882a593Smuzhiyun WriteToClient(client, sizeof(xXF86DRIGetDeviceInfoReply), &rep);
513*4882a593Smuzhiyun if (rep.length) {
514*4882a593Smuzhiyun WriteToClient(client, rep.devPrivateSize, pDevPrivate);
515*4882a593Smuzhiyun }
516*4882a593Smuzhiyun return Success;
517*4882a593Smuzhiyun }
518*4882a593Smuzhiyun
519*4882a593Smuzhiyun static int
ProcXF86DRIDispatch(register ClientPtr client)520*4882a593Smuzhiyun ProcXF86DRIDispatch(register ClientPtr client)
521*4882a593Smuzhiyun {
522*4882a593Smuzhiyun REQUEST(xReq);
523*4882a593Smuzhiyun
524*4882a593Smuzhiyun switch (stuff->data) {
525*4882a593Smuzhiyun case X_XF86DRIQueryVersion:
526*4882a593Smuzhiyun return ProcXF86DRIQueryVersion(client);
527*4882a593Smuzhiyun case X_XF86DRIQueryDirectRenderingCapable:
528*4882a593Smuzhiyun return ProcXF86DRIQueryDirectRenderingCapable(client);
529*4882a593Smuzhiyun }
530*4882a593Smuzhiyun
531*4882a593Smuzhiyun if (!client->local)
532*4882a593Smuzhiyun return DRIErrorBase + XF86DRIClientNotLocal;
533*4882a593Smuzhiyun
534*4882a593Smuzhiyun switch (stuff->data) {
535*4882a593Smuzhiyun case X_XF86DRIOpenConnection:
536*4882a593Smuzhiyun return ProcXF86DRIOpenConnection(client);
537*4882a593Smuzhiyun case X_XF86DRICloseConnection:
538*4882a593Smuzhiyun return ProcXF86DRICloseConnection(client);
539*4882a593Smuzhiyun case X_XF86DRIGetClientDriverName:
540*4882a593Smuzhiyun return ProcXF86DRIGetClientDriverName(client);
541*4882a593Smuzhiyun case X_XF86DRICreateContext:
542*4882a593Smuzhiyun return ProcXF86DRICreateContext(client);
543*4882a593Smuzhiyun case X_XF86DRIDestroyContext:
544*4882a593Smuzhiyun return ProcXF86DRIDestroyContext(client);
545*4882a593Smuzhiyun case X_XF86DRICreateDrawable:
546*4882a593Smuzhiyun return ProcXF86DRICreateDrawable(client);
547*4882a593Smuzhiyun case X_XF86DRIDestroyDrawable:
548*4882a593Smuzhiyun return ProcXF86DRIDestroyDrawable(client);
549*4882a593Smuzhiyun case X_XF86DRIGetDrawableInfo:
550*4882a593Smuzhiyun return ProcXF86DRIGetDrawableInfo(client);
551*4882a593Smuzhiyun case X_XF86DRIGetDeviceInfo:
552*4882a593Smuzhiyun return ProcXF86DRIGetDeviceInfo(client);
553*4882a593Smuzhiyun case X_XF86DRIAuthConnection:
554*4882a593Smuzhiyun return ProcXF86DRIAuthConnection(client);
555*4882a593Smuzhiyun /* {Open,Close}FullScreen are deprecated now */
556*4882a593Smuzhiyun default:
557*4882a593Smuzhiyun return BadRequest;
558*4882a593Smuzhiyun }
559*4882a593Smuzhiyun }
560*4882a593Smuzhiyun
561*4882a593Smuzhiyun static int _X_COLD
SProcXF86DRIQueryVersion(register ClientPtr client)562*4882a593Smuzhiyun SProcXF86DRIQueryVersion(register ClientPtr client)
563*4882a593Smuzhiyun {
564*4882a593Smuzhiyun REQUEST(xXF86DRIQueryVersionReq);
565*4882a593Smuzhiyun swaps(&stuff->length);
566*4882a593Smuzhiyun return ProcXF86DRIQueryVersion(client);
567*4882a593Smuzhiyun }
568*4882a593Smuzhiyun
569*4882a593Smuzhiyun static int _X_COLD
SProcXF86DRIQueryDirectRenderingCapable(register ClientPtr client)570*4882a593Smuzhiyun SProcXF86DRIQueryDirectRenderingCapable(register ClientPtr client)
571*4882a593Smuzhiyun {
572*4882a593Smuzhiyun REQUEST(xXF86DRIQueryDirectRenderingCapableReq);
573*4882a593Smuzhiyun REQUEST_SIZE_MATCH(xXF86DRIQueryDirectRenderingCapableReq);
574*4882a593Smuzhiyun swaps(&stuff->length);
575*4882a593Smuzhiyun swapl(&stuff->screen);
576*4882a593Smuzhiyun return ProcXF86DRIQueryDirectRenderingCapable(client);
577*4882a593Smuzhiyun }
578*4882a593Smuzhiyun
579*4882a593Smuzhiyun static int _X_COLD
SProcXF86DRIDispatch(register ClientPtr client)580*4882a593Smuzhiyun SProcXF86DRIDispatch(register ClientPtr client)
581*4882a593Smuzhiyun {
582*4882a593Smuzhiyun REQUEST(xReq);
583*4882a593Smuzhiyun
584*4882a593Smuzhiyun /*
585*4882a593Smuzhiyun * Only local clients are allowed DRI access, but remote clients still need
586*4882a593Smuzhiyun * these requests to find out cleanly.
587*4882a593Smuzhiyun */
588*4882a593Smuzhiyun switch (stuff->data) {
589*4882a593Smuzhiyun case X_XF86DRIQueryVersion:
590*4882a593Smuzhiyun return SProcXF86DRIQueryVersion(client);
591*4882a593Smuzhiyun case X_XF86DRIQueryDirectRenderingCapable:
592*4882a593Smuzhiyun return SProcXF86DRIQueryDirectRenderingCapable(client);
593*4882a593Smuzhiyun default:
594*4882a593Smuzhiyun return DRIErrorBase + XF86DRIClientNotLocal;
595*4882a593Smuzhiyun }
596*4882a593Smuzhiyun }
597*4882a593Smuzhiyun
598*4882a593Smuzhiyun void
XFree86DRIExtensionInit(void)599*4882a593Smuzhiyun XFree86DRIExtensionInit(void)
600*4882a593Smuzhiyun {
601*4882a593Smuzhiyun ExtensionEntry *extEntry;
602*4882a593Smuzhiyun
603*4882a593Smuzhiyun if (DRIExtensionInit() &&
604*4882a593Smuzhiyun (extEntry = AddExtension(XF86DRINAME,
605*4882a593Smuzhiyun XF86DRINumberEvents,
606*4882a593Smuzhiyun XF86DRINumberErrors,
607*4882a593Smuzhiyun ProcXF86DRIDispatch,
608*4882a593Smuzhiyun SProcXF86DRIDispatch,
609*4882a593Smuzhiyun XF86DRIResetProc, StandardMinorOpcode))) {
610*4882a593Smuzhiyun DRIReqCode = (unsigned char) extEntry->base;
611*4882a593Smuzhiyun DRIErrorBase = extEntry->errorBase;
612*4882a593Smuzhiyun }
613*4882a593Smuzhiyun }
614