1
/* $XFree86: xc/programs/Xserver/GL/dri/xf86dri.c,v 1.12 2002/12/14 01:36:08 dawes Exp $ */
2
/**************************************************************************
4
Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
5
Copyright 2000 VA Linux Systems, Inc.
8
Permission is hereby granted, free of charge, to any person obtaining a
9
copy of this software and associated documentation files (the
10
"Software"), to deal in the Software without restriction, including
11
without limitation the rights to use, copy, modify, merge, publish,
12
distribute, sub license, and/or sell copies of the Software, and to
13
permit persons to whom the Software is furnished to do so, subject to
14
the following conditions:
16
The above copyright notice and this permission notice (including the
17
next paragraph) shall be included in all copies or substantial portions
20
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
21
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
23
IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
24
ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
25
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
26
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
28
**************************************************************************/
32
* Kevin E. Martin <martin@valinux.com>
33
* Jens Owen <jens@tungstengraphics.com>
34
* Rickard E. (Rik) Faith <faith@valinux.com>
38
#ifdef HAVE_XORG_CONFIG_H
39
#include <xorg-config.h>
44
#include "xf86_ansic.h"
50
#include <X11/Xproto.h>
52
#include "dixstruct.h"
53
#include "extnsionst.h"
54
#include "colormapst.h"
55
#include "cursorstr.h"
56
#include "scrnintstr.h"
58
#define _XF86DRI_SERVER_
59
#include "xf86dristr.h"
64
#include "dristruct.h"
68
static int DRIErrorBase;
70
static DISPATCH_PROC(ProcXF86DRIQueryVersion);
71
static DISPATCH_PROC(ProcXF86DRIQueryDirectRenderingCapable);
72
static DISPATCH_PROC(ProcXF86DRIOpenConnection);
73
static DISPATCH_PROC(ProcXF86DRICloseConnection);
74
static DISPATCH_PROC(ProcXF86DRIGetClientDriverName);
75
static DISPATCH_PROC(ProcXF86DRICreateContext);
76
static DISPATCH_PROC(ProcXF86DRIDestroyContext);
77
static DISPATCH_PROC(ProcXF86DRICreateDrawable);
78
static DISPATCH_PROC(ProcXF86DRIDestroyDrawable);
79
static DISPATCH_PROC(ProcXF86DRIGetDrawableInfo);
80
static DISPATCH_PROC(ProcXF86DRIGetDeviceInfo);
81
static DISPATCH_PROC(ProcXF86DRIDispatch);
82
static DISPATCH_PROC(ProcXF86DRIAuthConnection);
84
static DISPATCH_PROC(SProcXF86DRIQueryVersion);
85
static DISPATCH_PROC(SProcXF86DRIDispatch);
87
static void XF86DRIResetProc(ExtensionEntry* extEntry);
89
static unsigned char DRIReqCode = 0;
91
extern void XFree86DRIExtensionInit(void);
94
XFree86DRIExtensionInit(void)
96
ExtensionEntry* extEntry;
99
EventType = CreateNewResourceType(XF86DRIFreeEvents);
103
DRIExtensionInit() &&
104
#ifdef XF86DRI_EVENTS
105
EventType && ScreenPrivateIndex != -1 &&
107
(extEntry = AddExtension(XF86DRINAME,
111
SProcXF86DRIDispatch,
113
StandardMinorOpcode))) {
114
DRIReqCode = (unsigned char)extEntry->base;
115
DRIErrorBase = extEntry->errorBase;
122
ExtensionEntry* extEntry
129
ProcXF86DRIQueryVersion(
130
register ClientPtr client
133
xXF86DRIQueryVersionReply rep;
136
REQUEST_SIZE_MATCH(xXF86DRIQueryVersionReq);
139
rep.sequenceNumber = client->sequence;
140
rep.majorVersion = XF86DRI_MAJOR_VERSION;
141
rep.minorVersion = XF86DRI_MINOR_VERSION;
142
rep.patchVersion = XF86DRI_PATCH_VERSION;
143
if (client->swapped) {
144
swaps(&rep.sequenceNumber, n);
145
swapl(&rep.length, n);
147
WriteToClient(client, sizeof(xXF86DRIQueryVersionReply), (char *)&rep);
148
return (client->noClientException);
152
ProcXF86DRIQueryDirectRenderingCapable(
153
register ClientPtr client
156
xXF86DRIQueryDirectRenderingCapableReply rep;
159
REQUEST(xXF86DRIQueryDirectRenderingCapableReq);
160
REQUEST_SIZE_MATCH(xXF86DRIQueryDirectRenderingCapableReq);
161
if (stuff->screen >= screenInfo.numScreens) {
162
client->errorValue = stuff->screen;
168
rep.sequenceNumber = client->sequence;
170
if (!DRIQueryDirectRenderingCapable( screenInfo.screens[stuff->screen],
174
rep.isCapable = isCapable;
176
if (!LocalClient(client))
179
WriteToClient(client,
180
sizeof(xXF86DRIQueryDirectRenderingCapableReply), (char *)&rep);
181
return (client->noClientException);
185
ProcXF86DRIOpenConnection(
186
register ClientPtr client
189
xXF86DRIOpenConnectionReply rep;
193
REQUEST(xXF86DRIOpenConnectionReq);
194
REQUEST_SIZE_MATCH(xXF86DRIOpenConnectionReq);
195
if (stuff->screen >= screenInfo.numScreens) {
196
client->errorValue = stuff->screen;
200
if (!DRIOpenConnection( screenInfo.screens[stuff->screen],
207
rep.sequenceNumber = client->sequence;
208
rep.busIdStringLength = 0;
210
rep.busIdStringLength = strlen(busIdString);
211
rep.length = (SIZEOF(xXF86DRIOpenConnectionReply) - SIZEOF(xGenericReply) +
212
((rep.busIdStringLength + 3) & ~3)) >> 2;
214
rep.hSAREALow = (CARD32)(hSAREA & 0xffffffff);
215
#if defined(LONG64) && !defined(__linux__)
216
rep.hSAREAHigh = (CARD32)(hSAREA >> 32);
221
WriteToClient(client, sizeof(xXF86DRIOpenConnectionReply), (char *)&rep);
222
if (rep.busIdStringLength)
223
WriteToClient(client, rep.busIdStringLength, busIdString);
224
return (client->noClientException);
228
ProcXF86DRIAuthConnection(
229
register ClientPtr client
232
xXF86DRIAuthConnectionReply rep;
234
REQUEST(xXF86DRIAuthConnectionReq);
235
REQUEST_SIZE_MATCH(xXF86DRIAuthConnectionReq);
236
if (stuff->screen >= screenInfo.numScreens) {
237
client->errorValue = stuff->screen;
243
rep.sequenceNumber = client->sequence;
244
rep.authenticated = 1;
246
if (!DRIAuthConnection( screenInfo.screens[stuff->screen], stuff->magic)) {
247
ErrorF("Failed to authenticate %lu\n", (unsigned long)stuff->magic);
248
rep.authenticated = 0;
250
WriteToClient(client, sizeof(xXF86DRIAuthConnectionReply), (char *)&rep);
251
return (client->noClientException);
255
ProcXF86DRICloseConnection(
256
register ClientPtr client
259
REQUEST(xXF86DRICloseConnectionReq);
260
REQUEST_SIZE_MATCH(xXF86DRICloseConnectionReq);
261
if (stuff->screen >= screenInfo.numScreens) {
262
client->errorValue = stuff->screen;
266
DRICloseConnection( screenInfo.screens[stuff->screen]);
268
return (client->noClientException);
272
ProcXF86DRIGetClientDriverName(
273
register ClientPtr client
276
xXF86DRIGetClientDriverNameReply rep;
277
char* clientDriverName;
279
REQUEST(xXF86DRIGetClientDriverNameReq);
280
REQUEST_SIZE_MATCH(xXF86DRIGetClientDriverNameReq);
281
if (stuff->screen >= screenInfo.numScreens) {
282
client->errorValue = stuff->screen;
286
DRIGetClientDriverName( screenInfo.screens[stuff->screen],
287
(int *)&rep.ddxDriverMajorVersion,
288
(int *)&rep.ddxDriverMinorVersion,
289
(int *)&rep.ddxDriverPatchVersion,
293
rep.sequenceNumber = client->sequence;
294
rep.clientDriverNameLength = 0;
295
if (clientDriverName)
296
rep.clientDriverNameLength = strlen(clientDriverName);
297
rep.length = (SIZEOF(xXF86DRIGetClientDriverNameReply) -
298
SIZEOF(xGenericReply) +
299
((rep.clientDriverNameLength + 3) & ~3)) >> 2;
301
WriteToClient(client,
302
sizeof(xXF86DRIGetClientDriverNameReply), (char *)&rep);
303
if (rep.clientDriverNameLength)
304
WriteToClient(client,
305
rep.clientDriverNameLength,
307
return (client->noClientException);
311
ProcXF86DRICreateContext(
312
register ClientPtr client
315
xXF86DRICreateContextReply rep;
320
REQUEST(xXF86DRICreateContextReq);
321
REQUEST_SIZE_MATCH(xXF86DRICreateContextReq);
322
if (stuff->screen >= screenInfo.numScreens) {
323
client->errorValue = stuff->screen;
329
rep.sequenceNumber = client->sequence;
331
pScreen = screenInfo.screens[stuff->screen];
332
visual = pScreen->visuals;
334
/* Find the requested X visual */
335
for (i = 0; i < pScreen->numVisuals; i++, visual++)
336
if (visual->vid == stuff->visual)
338
if (i == pScreen->numVisuals) {
339
/* No visual found */
343
if (!DRICreateContext( pScreen,
346
(drm_context_t *)&rep.hHWContext)) {
350
WriteToClient(client, sizeof(xXF86DRICreateContextReply), (char *)&rep);
351
return (client->noClientException);
355
ProcXF86DRIDestroyContext(
356
register ClientPtr client
359
REQUEST(xXF86DRIDestroyContextReq);
360
REQUEST_SIZE_MATCH(xXF86DRIDestroyContextReq);
361
if (stuff->screen >= screenInfo.numScreens) {
362
client->errorValue = stuff->screen;
366
if (!DRIDestroyContext( screenInfo.screens[stuff->screen],
371
return (client->noClientException);
375
ProcXF86DRICreateDrawable(
379
xXF86DRICreateDrawableReply rep;
380
DrawablePtr pDrawable;
382
REQUEST(xXF86DRICreateDrawableReq);
383
REQUEST_SIZE_MATCH(xXF86DRICreateDrawableReq);
384
if (stuff->screen >= screenInfo.numScreens) {
385
client->errorValue = stuff->screen;
391
rep.sequenceNumber = client->sequence;
393
if (!(pDrawable = (DrawablePtr)SecurityLookupDrawable(
394
(Drawable)stuff->drawable,
396
SecurityReadAccess))) {
400
if (!DRICreateDrawable( screenInfo.screens[stuff->screen],
401
(Drawable)stuff->drawable,
403
(drm_drawable_t *)&rep.hHWDrawable)) {
407
WriteToClient(client, sizeof(xXF86DRICreateDrawableReply), (char *)&rep);
408
return (client->noClientException);
412
ProcXF86DRIDestroyDrawable(
413
register ClientPtr client
416
REQUEST(xXF86DRIDestroyDrawableReq);
417
DrawablePtr pDrawable;
418
REQUEST_SIZE_MATCH(xXF86DRIDestroyDrawableReq);
419
if (stuff->screen >= screenInfo.numScreens) {
420
client->errorValue = stuff->screen;
424
if (!(pDrawable = (DrawablePtr)SecurityLookupDrawable(
425
(Drawable)stuff->drawable,
427
SecurityReadAccess))) {
431
if (!DRIDestroyDrawable( screenInfo.screens[stuff->screen],
432
(Drawable)stuff->drawable,
437
return (client->noClientException);
441
ProcXF86DRIGetDrawableInfo(
442
register ClientPtr client
445
xXF86DRIGetDrawableInfoReply rep;
446
DrawablePtr pDrawable;
448
drm_clip_rect_t * pClipRects;
449
drm_clip_rect_t * pBackClipRects;
452
REQUEST(xXF86DRIGetDrawableInfoReq);
453
REQUEST_SIZE_MATCH(xXF86DRIGetDrawableInfoReq);
454
if (stuff->screen >= screenInfo.numScreens) {
455
client->errorValue = stuff->screen;
461
rep.sequenceNumber = client->sequence;
463
if (!(pDrawable = (DrawablePtr)SecurityLookupDrawable(
464
(Drawable)stuff->drawable,
466
SecurityReadAccess))) {
470
if (!DRIGetDrawableInfo( screenInfo.screens[stuff->screen],
472
(unsigned int*)&rep.drawableTableIndex,
473
(unsigned int*)&rep.drawableTableStamp,
478
(int*)&rep.numClipRects,
482
(int*)&rep.numBackClipRects,
489
rep.drawableWidth = W;
490
rep.drawableHeight = H;
491
rep.length = (SIZEOF(xXF86DRIGetDrawableInfoReply) -
492
SIZEOF(xGenericReply));
497
if (rep.numBackClipRects)
498
rep.length += sizeof(drm_clip_rect_t) * rep.numBackClipRects;
500
if (rep.numClipRects)
501
rep.length += sizeof(drm_clip_rect_t) * rep.numClipRects;
503
rep.length = ((rep.length + 3) & ~3) >> 2;
505
WriteToClient(client, sizeof(xXF86DRIGetDrawableInfoReply), (char *)&rep);
507
if (rep.numClipRects) {
508
WriteToClient(client,
509
sizeof(drm_clip_rect_t) * rep.numClipRects,
513
if (rep.numBackClipRects) {
514
WriteToClient(client,
515
sizeof(drm_clip_rect_t) * rep.numBackClipRects,
516
(char *)pBackClipRects);
519
return (client->noClientException);
523
ProcXF86DRIGetDeviceInfo(
524
register ClientPtr client
527
xXF86DRIGetDeviceInfoReply rep;
528
drm_handle_t hFrameBuffer;
531
REQUEST(xXF86DRIGetDeviceInfoReq);
532
REQUEST_SIZE_MATCH(xXF86DRIGetDeviceInfoReq);
533
if (stuff->screen >= screenInfo.numScreens) {
534
client->errorValue = stuff->screen;
540
rep.sequenceNumber = client->sequence;
542
if (!DRIGetDeviceInfo( screenInfo.screens[stuff->screen],
544
(int*)&rep.framebufferOrigin,
545
(int*)&rep.framebufferSize,
546
(int*)&rep.framebufferStride,
547
(int*)&rep.devPrivateSize,
552
rep.hFrameBufferLow = (CARD32)(hFrameBuffer & 0xffffffff);
553
#if defined(LONG64) && !defined(__linux__)
554
rep.hFrameBufferHigh = (CARD32)(hFrameBuffer >> 32);
556
rep.hFrameBufferHigh = 0;
560
if (rep.devPrivateSize) {
561
rep.length = (SIZEOF(xXF86DRIGetDeviceInfoReply) -
562
SIZEOF(xGenericReply) +
563
((rep.devPrivateSize + 3) & ~3)) >> 2;
566
WriteToClient(client, sizeof(xXF86DRIGetDeviceInfoReply), (char *)&rep);
568
WriteToClient(client, rep.devPrivateSize, (char *)pDevPrivate);
570
return (client->noClientException);
574
ProcXF86DRIDispatch (
575
register ClientPtr client
582
case X_XF86DRIQueryVersion:
583
return ProcXF86DRIQueryVersion(client);
584
case X_XF86DRIQueryDirectRenderingCapable:
585
return ProcXF86DRIQueryDirectRenderingCapable(client);
588
if (!LocalClient(client))
589
return DRIErrorBase + XF86DRIClientNotLocal;
593
case X_XF86DRIOpenConnection:
594
return ProcXF86DRIOpenConnection(client);
595
case X_XF86DRICloseConnection:
596
return ProcXF86DRICloseConnection(client);
597
case X_XF86DRIGetClientDriverName:
598
return ProcXF86DRIGetClientDriverName(client);
599
case X_XF86DRICreateContext:
600
return ProcXF86DRICreateContext(client);
601
case X_XF86DRIDestroyContext:
602
return ProcXF86DRIDestroyContext(client);
603
case X_XF86DRICreateDrawable:
604
return ProcXF86DRICreateDrawable(client);
605
case X_XF86DRIDestroyDrawable:
606
return ProcXF86DRIDestroyDrawable(client);
607
case X_XF86DRIGetDrawableInfo:
608
return ProcXF86DRIGetDrawableInfo(client);
609
case X_XF86DRIGetDeviceInfo:
610
return ProcXF86DRIGetDeviceInfo(client);
611
case X_XF86DRIAuthConnection:
612
return ProcXF86DRIAuthConnection(client);
613
/* {Open,Close}FullScreen are deprecated now */
620
SProcXF86DRIQueryVersion(
621
register ClientPtr client
625
REQUEST(xXF86DRIQueryVersionReq);
626
swaps(&stuff->length, n);
627
return ProcXF86DRIQueryVersion(client);
631
SProcXF86DRIDispatch (
632
register ClientPtr client
637
/* It is bound to be non-local when there is byte swapping */
638
if (!LocalClient(client))
639
return DRIErrorBase + XF86DRIClientNotLocal;
641
/* only local clients are allowed DRI access */
644
case X_XF86DRIQueryVersion:
645
return SProcXF86DRIQueryVersion(client);