1 /**************************************************************************
3 Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
4 Copyright 2000 VA Linux Systems, Inc.
7 Permission is hereby granted, free of charge, to any person obtaining a
8 copy of this software and associated documentation files (the
9 "Software"), to deal in the Software without restriction, including
10 without limitation the rights to use, copy, modify, merge, publish,
11 distribute, sub license, and/or sell copies of the Software, and to
12 permit persons to whom the Software is furnished to do so, subject to
13 the following conditions:
15 The above copyright notice and this permission notice (including the
16 next paragraph) shall be included in all copies or substantial portions
19 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
22 IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
23 ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
24 TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
25 SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27 **************************************************************************/
31 * Kevin E. Martin <martin@valinux.com>
32 * Jens Owen <jens@tungstengraphics.com>
33 * Rickard E. (Rik) Faith <faith@valinux.com>
37 #ifdef HAVE_XORG_CONFIG_H
38 #include <xorg-config.h>
46 #include <X11/Xproto.h>
48 #include "dixstruct.h"
49 #include "extnsionst.h"
51 #include "colormapst.h"
52 #include "cursorstr.h"
53 #include "scrnintstr.h"
55 #define _XF86DRI_SERVER_
56 #include <X11/dri/xf86driproto.h>
61 #include "dristruct.h"
63 #include "protocol-versions.h"
64 #include "xf86Extensions.h"
66 static int DRIErrorBase
;
68 static void XF86DRIResetProc(ExtensionEntry
*extEntry
);
70 static unsigned char DRIReqCode
= 0;
74 XF86DRIResetProc(ExtensionEntry
*extEntry
)
80 ProcXF86DRIQueryVersion(register ClientPtr client
)
82 xXF86DRIQueryVersionReply rep
= {
84 .sequenceNumber
= client
->sequence
,
86 .majorVersion
= SERVER_XF86DRI_MAJOR_VERSION
,
87 .minorVersion
= SERVER_XF86DRI_MINOR_VERSION
,
88 .patchVersion
= SERVER_XF86DRI_PATCH_VERSION
91 REQUEST_SIZE_MATCH(xXF86DRIQueryVersionReq
);
92 if (client
->swapped
) {
93 swaps(&rep
.sequenceNumber
);
95 swaps(&rep
.majorVersion
);
96 swaps(&rep
.minorVersion
);
97 swapl(&rep
.patchVersion
);
99 WriteToClient(client
, sizeof(xXF86DRIQueryVersionReply
), &rep
);
104 ProcXF86DRIQueryDirectRenderingCapable(register ClientPtr client
)
106 xXF86DRIQueryDirectRenderingCapableReply rep
;
109 REQUEST(xXF86DRIQueryDirectRenderingCapableReq
);
110 REQUEST_SIZE_MATCH(xXF86DRIQueryDirectRenderingCapableReq
);
111 if (stuff
->screen
>= screenInfo
.numScreens
) {
112 client
->errorValue
= stuff
->screen
;
116 if (!DRIQueryDirectRenderingCapable(screenInfo
.screens
[stuff
->screen
],
121 if (!client
->local
|| client
->swapped
)
124 rep
= (xXF86DRIQueryDirectRenderingCapableReply
) {
126 .sequenceNumber
= client
->sequence
,
128 .isCapable
= isCapable
131 if (client
->swapped
) {
132 swaps(&rep
.sequenceNumber
);
136 WriteToClient(client
,
137 sizeof(xXF86DRIQueryDirectRenderingCapableReply
),
143 ProcXF86DRIOpenConnection(register ClientPtr client
)
145 xXF86DRIOpenConnectionReply rep
;
148 CARD32 busIdStringLength
= 0;
150 REQUEST(xXF86DRIOpenConnectionReq
);
151 REQUEST_SIZE_MATCH(xXF86DRIOpenConnectionReq
);
152 if (stuff
->screen
>= screenInfo
.numScreens
) {
153 client
->errorValue
= stuff
->screen
;
157 if (!DRIOpenConnection(screenInfo
.screens
[stuff
->screen
],
158 &hSAREA
, &busIdString
)) {
163 busIdStringLength
= strlen(busIdString
);
165 rep
= (xXF86DRIOpenConnectionReply
) {
167 .sequenceNumber
= client
->sequence
,
168 .length
= bytes_to_int32(SIZEOF(xXF86DRIOpenConnectionReply
) -
169 SIZEOF(xGenericReply
) +
170 pad_to_int32(busIdStringLength
)),
171 .busIdStringLength
= busIdStringLength
,
173 .hSAREALow
= (CARD32
) (hSAREA
& 0xffffffff),
174 #if defined(LONG64) && !defined(__linux__)
175 .hSAREAHigh
= (CARD32
) (hSAREA
>> 32),
181 WriteToClient(client
, sizeof(xXF86DRIOpenConnectionReply
), &rep
);
182 if (busIdStringLength
)
183 WriteToClient(client
, busIdStringLength
, busIdString
);
188 ProcXF86DRIAuthConnection(register ClientPtr client
)
190 xXF86DRIAuthConnectionReply rep
= {
192 .sequenceNumber
= client
->sequence
,
197 REQUEST(xXF86DRIAuthConnectionReq
);
198 REQUEST_SIZE_MATCH(xXF86DRIAuthConnectionReq
);
199 if (stuff
->screen
>= screenInfo
.numScreens
) {
200 client
->errorValue
= stuff
->screen
;
204 if (!DRIAuthConnection(screenInfo
.screens
[stuff
->screen
], stuff
->magic
)) {
205 ErrorF("Failed to authenticate %lu\n", (unsigned long) stuff
->magic
);
206 rep
.authenticated
= 0;
208 WriteToClient(client
, sizeof(xXF86DRIAuthConnectionReply
), &rep
);
213 ProcXF86DRICloseConnection(register ClientPtr client
)
215 REQUEST(xXF86DRICloseConnectionReq
);
216 REQUEST_SIZE_MATCH(xXF86DRICloseConnectionReq
);
217 if (stuff
->screen
>= screenInfo
.numScreens
) {
218 client
->errorValue
= stuff
->screen
;
222 DRICloseConnection(screenInfo
.screens
[stuff
->screen
]);
228 ProcXF86DRIGetClientDriverName(register ClientPtr client
)
230 xXF86DRIGetClientDriverNameReply rep
= {
232 .sequenceNumber
= client
->sequence
,
233 .clientDriverNameLength
= 0
235 char *clientDriverName
;
237 REQUEST(xXF86DRIGetClientDriverNameReq
);
238 REQUEST_SIZE_MATCH(xXF86DRIGetClientDriverNameReq
);
239 if (stuff
->screen
>= screenInfo
.numScreens
) {
240 client
->errorValue
= stuff
->screen
;
244 DRIGetClientDriverName(screenInfo
.screens
[stuff
->screen
],
245 (int *) &rep
.ddxDriverMajorVersion
,
246 (int *) &rep
.ddxDriverMinorVersion
,
247 (int *) &rep
.ddxDriverPatchVersion
,
250 if (clientDriverName
)
251 rep
.clientDriverNameLength
= strlen(clientDriverName
);
252 rep
.length
= bytes_to_int32(SIZEOF(xXF86DRIGetClientDriverNameReply
) -
253 SIZEOF(xGenericReply
) +
254 pad_to_int32(rep
.clientDriverNameLength
));
256 WriteToClient(client
, sizeof(xXF86DRIGetClientDriverNameReply
), &rep
);
257 if (rep
.clientDriverNameLength
)
258 WriteToClient(client
, rep
.clientDriverNameLength
, clientDriverName
);
263 ProcXF86DRICreateContext(register ClientPtr client
)
265 xXF86DRICreateContextReply rep
= {
267 .sequenceNumber
= client
->sequence
,
272 REQUEST(xXF86DRICreateContextReq
);
273 REQUEST_SIZE_MATCH(xXF86DRICreateContextReq
);
274 if (stuff
->screen
>= screenInfo
.numScreens
) {
275 client
->errorValue
= stuff
->screen
;
279 pScreen
= screenInfo
.screens
[stuff
->screen
];
281 if (!DRICreateContext(pScreen
,
283 stuff
->context
, (drm_context_t
*) &rep
.hHWContext
)) {
287 WriteToClient(client
, sizeof(xXF86DRICreateContextReply
), &rep
);
292 ProcXF86DRIDestroyContext(register ClientPtr client
)
294 REQUEST(xXF86DRIDestroyContextReq
);
295 REQUEST_SIZE_MATCH(xXF86DRIDestroyContextReq
);
296 if (stuff
->screen
>= screenInfo
.numScreens
) {
297 client
->errorValue
= stuff
->screen
;
301 if (!DRIDestroyContext(screenInfo
.screens
[stuff
->screen
], stuff
->context
)) {
309 ProcXF86DRICreateDrawable(ClientPtr client
)
311 xXF86DRICreateDrawableReply rep
= {
313 .sequenceNumber
= client
->sequence
,
316 DrawablePtr pDrawable
;
319 REQUEST(xXF86DRICreateDrawableReq
);
320 REQUEST_SIZE_MATCH(xXF86DRICreateDrawableReq
);
321 if (stuff
->screen
>= screenInfo
.numScreens
) {
322 client
->errorValue
= stuff
->screen
;
326 rc
= dixLookupDrawable(&pDrawable
, stuff
->drawable
, client
, 0,
331 if (!DRICreateDrawable(screenInfo
.screens
[stuff
->screen
], client
,
332 pDrawable
, (drm_drawable_t
*) &rep
.hHWDrawable
)) {
336 WriteToClient(client
, sizeof(xXF86DRICreateDrawableReply
), &rep
);
341 ProcXF86DRIDestroyDrawable(register ClientPtr client
)
343 REQUEST(xXF86DRIDestroyDrawableReq
);
344 DrawablePtr pDrawable
;
347 REQUEST_SIZE_MATCH(xXF86DRIDestroyDrawableReq
);
349 if (stuff
->screen
>= screenInfo
.numScreens
) {
350 client
->errorValue
= stuff
->screen
;
354 rc
= dixLookupDrawable(&pDrawable
, stuff
->drawable
, client
, 0,
359 if (!DRIDestroyDrawable(screenInfo
.screens
[stuff
->screen
], client
,
368 ProcXF86DRIGetDrawableInfo(register ClientPtr client
)
370 xXF86DRIGetDrawableInfoReply rep
= {
372 .sequenceNumber
= client
->sequence
,
375 DrawablePtr pDrawable
;
377 drm_clip_rect_t
*pClipRects
, *pClippedRects
;
378 drm_clip_rect_t
*pBackClipRects
;
379 int backX
, backY
, rc
;
381 REQUEST(xXF86DRIGetDrawableInfoReq
);
382 REQUEST_SIZE_MATCH(xXF86DRIGetDrawableInfoReq
);
383 if (stuff
->screen
>= screenInfo
.numScreens
) {
384 client
->errorValue
= stuff
->screen
;
388 rc
= dixLookupDrawable(&pDrawable
, stuff
->drawable
, client
, 0,
393 if (!DRIGetDrawableInfo(screenInfo
.screens
[stuff
->screen
],
395 (unsigned int *) &rep
.drawableTableIndex
,
396 (unsigned int *) &rep
.drawableTableStamp
,
401 (int *) &rep
.numClipRects
,
405 (int *) &rep
.numBackClipRects
, &pBackClipRects
)) {
411 rep
.drawableWidth
= W
;
412 rep
.drawableHeight
= H
;
413 rep
.length
= (SIZEOF(xXF86DRIGetDrawableInfoReply
) - SIZEOF(xGenericReply
));
418 if (rep
.numBackClipRects
)
419 rep
.length
+= sizeof(drm_clip_rect_t
) * rep
.numBackClipRects
;
421 pClippedRects
= pClipRects
;
423 if (rep
.numClipRects
) {
424 /* Clip cliprects to screen dimensions (redirected windows) */
425 pClippedRects
= malloc(rep
.numClipRects
* sizeof(drm_clip_rect_t
));
428 ScreenPtr pScreen
= screenInfo
.screens
[stuff
->screen
];
431 for (i
= 0, j
= 0; i
< rep
.numClipRects
; i
++) {
432 pClippedRects
[j
].x1
= max(pClipRects
[i
].x1
, 0);
433 pClippedRects
[j
].y1
= max(pClipRects
[i
].y1
, 0);
434 pClippedRects
[j
].x2
= min(pClipRects
[i
].x2
, pScreen
->width
);
435 pClippedRects
[j
].y2
= min(pClipRects
[i
].y2
, pScreen
->height
);
437 if (pClippedRects
[j
].x1
< pClippedRects
[j
].x2
&&
438 pClippedRects
[j
].y1
< pClippedRects
[j
].y2
) {
443 rep
.numClipRects
= j
;
446 rep
.numClipRects
= 0;
449 rep
.length
+= sizeof(drm_clip_rect_t
) * rep
.numClipRects
;
452 rep
.length
= bytes_to_int32(rep
.length
);
454 WriteToClient(client
, sizeof(xXF86DRIGetDrawableInfoReply
), &rep
);
456 if (rep
.numClipRects
) {
457 WriteToClient(client
,
458 sizeof(drm_clip_rect_t
) * rep
.numClipRects
,
463 if (rep
.numBackClipRects
) {
464 WriteToClient(client
,
465 sizeof(drm_clip_rect_t
) * rep
.numBackClipRects
,
473 ProcXF86DRIGetDeviceInfo(register ClientPtr client
)
475 xXF86DRIGetDeviceInfoReply rep
= {
477 .sequenceNumber
= client
->sequence
,
480 drm_handle_t hFrameBuffer
;
483 REQUEST(xXF86DRIGetDeviceInfoReq
);
484 REQUEST_SIZE_MATCH(xXF86DRIGetDeviceInfoReq
);
485 if (stuff
->screen
>= screenInfo
.numScreens
) {
486 client
->errorValue
= stuff
->screen
;
490 if (!DRIGetDeviceInfo(screenInfo
.screens
[stuff
->screen
],
492 (int *) &rep
.framebufferOrigin
,
493 (int *) &rep
.framebufferSize
,
494 (int *) &rep
.framebufferStride
,
495 (int *) &rep
.devPrivateSize
, &pDevPrivate
)) {
499 rep
.hFrameBufferLow
= (CARD32
) (hFrameBuffer
& 0xffffffff);
500 #if defined(LONG64) && !defined(__linux__)
501 rep
.hFrameBufferHigh
= (CARD32
) (hFrameBuffer
>> 32);
503 rep
.hFrameBufferHigh
= 0;
506 if (rep
.devPrivateSize
) {
507 rep
.length
= bytes_to_int32(SIZEOF(xXF86DRIGetDeviceInfoReply
) -
508 SIZEOF(xGenericReply
) +
509 pad_to_int32(rep
.devPrivateSize
));
512 WriteToClient(client
, sizeof(xXF86DRIGetDeviceInfoReply
), &rep
);
514 WriteToClient(client
, rep
.devPrivateSize
, pDevPrivate
);
520 ProcXF86DRIDispatch(register ClientPtr client
)
524 switch (stuff
->data
) {
525 case X_XF86DRIQueryVersion
:
526 return ProcXF86DRIQueryVersion(client
);
527 case X_XF86DRIQueryDirectRenderingCapable
:
528 return ProcXF86DRIQueryDirectRenderingCapable(client
);
532 return DRIErrorBase
+ XF86DRIClientNotLocal
;
534 switch (stuff
->data
) {
535 case X_XF86DRIOpenConnection
:
536 return ProcXF86DRIOpenConnection(client
);
537 case X_XF86DRICloseConnection
:
538 return ProcXF86DRICloseConnection(client
);
539 case X_XF86DRIGetClientDriverName
:
540 return ProcXF86DRIGetClientDriverName(client
);
541 case X_XF86DRICreateContext
:
542 return ProcXF86DRICreateContext(client
);
543 case X_XF86DRIDestroyContext
:
544 return ProcXF86DRIDestroyContext(client
);
545 case X_XF86DRICreateDrawable
:
546 return ProcXF86DRICreateDrawable(client
);
547 case X_XF86DRIDestroyDrawable
:
548 return ProcXF86DRIDestroyDrawable(client
);
549 case X_XF86DRIGetDrawableInfo
:
550 return ProcXF86DRIGetDrawableInfo(client
);
551 case X_XF86DRIGetDeviceInfo
:
552 return ProcXF86DRIGetDeviceInfo(client
);
553 case X_XF86DRIAuthConnection
:
554 return ProcXF86DRIAuthConnection(client
);
555 /* {Open,Close}FullScreen are deprecated now */
562 SProcXF86DRIQueryVersion(register ClientPtr client
)
564 REQUEST(xXF86DRIQueryVersionReq
);
565 swaps(&stuff
->length
);
566 return ProcXF86DRIQueryVersion(client
);
570 SProcXF86DRIQueryDirectRenderingCapable(register ClientPtr client
)
572 REQUEST(xXF86DRIQueryDirectRenderingCapableReq
);
573 swaps(&stuff
->length
);
574 swapl(&stuff
->screen
);
575 return ProcXF86DRIQueryDirectRenderingCapable(client
);
579 SProcXF86DRIDispatch(register ClientPtr client
)
584 * Only local clients are allowed DRI access, but remote clients still need
585 * these requests to find out cleanly.
587 switch (stuff
->data
) {
588 case X_XF86DRIQueryVersion
:
589 return SProcXF86DRIQueryVersion(client
);
590 case X_XF86DRIQueryDirectRenderingCapable
:
591 return SProcXF86DRIQueryDirectRenderingCapable(client
);
593 return DRIErrorBase
+ XF86DRIClientNotLocal
;
598 XFree86DRIExtensionInit(void)
600 ExtensionEntry
*extEntry
;
602 #ifdef XF86DRI_EVENTS
603 EventType
= CreateNewResourceType(XF86DRIFreeEvents
, "DRIEvent");
606 if (DRIExtensionInit() &&
607 #ifdef XF86DRI_EVENTS
608 EventType
&& ScreenPrivateIndex
!= -1 &&
610 (extEntry
= AddExtension(XF86DRINAME
,
614 SProcXF86DRIDispatch
,
615 XF86DRIResetProc
, StandardMinorOpcode
))) {
616 DRIReqCode
= (unsigned char) extEntry
->base
;
617 DRIErrorBase
= extEntry
->errorBase
;