xref: /third_party/libdrm/tests/ttmtest/src/xf86dri.c (revision d722e3fb)
1/* $XFree86: xc/lib/GL/dri/XF86dri.c,v 1.13 2002/10/30 12:51:25 alanh Exp $ */
2/**************************************************************************
3
4Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
5Copyright 2000 VA Linux Systems, Inc.
6All Rights Reserved.
7
8Permission is hereby granted, free of charge, to any person obtaining a
9copy of this software and associated documentation files (the
10"Software"), to deal in the Software without restriction, including
11without limitation the rights to use, copy, modify, merge, publish,
12distribute, sub license, and/or sell copies of the Software, and to
13permit persons to whom the Software is furnished to do so, subject to
14the following conditions:
15
16The above copyright notice and this permission notice (including the
17next paragraph) shall be included in all copies or substantial portions
18of the Software.
19
20THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
21OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
23IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
24ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
25TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
26SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27
28**************************************************************************/
29
30/*
31 * Authors:
32 *   Kevin E. Martin <martin@valinux.com>
33 *   Jens Owen <jens@tungstengraphics.com>
34 *   Rickard E. (Rik) Faith <faith@valinux.com>
35 *
36 */
37
38/* THIS IS NOT AN X CONSORTIUM STANDARD */
39
40#ifdef HAVE_CONFIG_H
41#include "config.h"
42#endif
43
44#include <X11/Xlibint.h>
45#include <X11/extensions/Xext.h>
46#include <X11/extensions/extutil.h>
47#include <stdint.h>
48#include "xf86dristr.h"
49
50static XExtensionInfo _xf86dri_info_data;
51static XExtensionInfo *xf86dri_info = &_xf86dri_info_data;
52static char xf86dri_extension_name[] = XF86DRINAME;
53
54#define uniDRICheckExtension(dpy,i,val) \
55  XextCheckExtension (dpy, i, xf86dri_extension_name, val)
56
57/*****************************************************************************
58 *                                                                           *
59 *			   private utility routines                          *
60 *                                                                           *
61 *****************************************************************************/
62
63static int close_display(Display * dpy, XExtCodes * extCodes);
64static /* const */ XExtensionHooks xf86dri_extension_hooks = {
65    NULL,			       /* create_gc */
66    NULL,			       /* copy_gc */
67    NULL,			       /* flush_gc */
68    NULL,			       /* free_gc */
69    NULL,			       /* create_font */
70    NULL,			       /* free_font */
71    close_display,		       /* close_display */
72    NULL,			       /* wire_to_event */
73    NULL,			       /* event_to_wire */
74    NULL,			       /* error */
75    NULL,			       /* error_string */
76};
77
78static
79XEXT_GENERATE_FIND_DISPLAY(find_display, xf86dri_info,
80    xf86dri_extension_name, &xf86dri_extension_hooks, 0, NULL)
81
82    static XEXT_GENERATE_CLOSE_DISPLAY(close_display, xf86dri_info)
83
84/*****************************************************************************
85 *                                                                           *
86 *		    public XFree86-DRI Extension routines                    *
87 *                                                                           *
88 *****************************************************************************/
89#if 0
90#include <stdio.h>
91#define TRACE(msg)  fprintf(stderr,"uniDRI%s\n", msg);
92#else
93#define TRACE(msg)
94#endif
95    Bool uniDRIQueryExtension(dpy, event_basep, error_basep)
96    Display *dpy;
97    int *event_basep, *error_basep;
98{
99    XExtDisplayInfo *info = find_display(dpy);
100
101    TRACE("QueryExtension...");
102    if (XextHasExtension(info)) {
103	*event_basep = info->codes->first_event;
104	*error_basep = info->codes->first_error;
105	TRACE("QueryExtension... return True");
106	return True;
107    } else {
108	TRACE("QueryExtension... return False");
109	return False;
110    }
111}
112
113Bool
114uniDRIQueryVersion(dpy, majorVersion, minorVersion, patchVersion)
115    Display *dpy;
116    int *majorVersion;
117    int *minorVersion;
118    int *patchVersion;
119{
120    XExtDisplayInfo *info = find_display(dpy);
121    xXF86DRIQueryVersionReply rep;
122    xXF86DRIQueryVersionReq *req;
123
124    TRACE("QueryVersion...");
125    uniDRICheckExtension(dpy, info, False);
126
127    LockDisplay(dpy);
128    GetReq(XF86DRIQueryVersion, req);
129    req->reqType = info->codes->major_opcode;
130    req->driReqType = X_XF86DRIQueryVersion;
131    if (!_XReply(dpy, (xReply *) & rep, 0, xFalse)) {
132	UnlockDisplay(dpy);
133	SyncHandle();
134	TRACE("QueryVersion... return False");
135	return False;
136    }
137    *majorVersion = rep.majorVersion;
138    *minorVersion = rep.minorVersion;
139    *patchVersion = rep.patchVersion;
140    UnlockDisplay(dpy);
141    SyncHandle();
142    TRACE("QueryVersion... return True");
143    return True;
144}
145
146Bool
147uniDRIQueryDirectRenderingCapable(dpy, screen, isCapable)
148    Display *dpy;
149    int screen;
150    Bool *isCapable;
151{
152    XExtDisplayInfo *info = find_display(dpy);
153    xXF86DRIQueryDirectRenderingCapableReply rep;
154    xXF86DRIQueryDirectRenderingCapableReq *req;
155
156    TRACE("QueryDirectRenderingCapable...");
157    uniDRICheckExtension(dpy, info, False);
158
159    LockDisplay(dpy);
160    GetReq(XF86DRIQueryDirectRenderingCapable, req);
161    req->reqType = info->codes->major_opcode;
162    req->driReqType = X_XF86DRIQueryDirectRenderingCapable;
163    req->screen = screen;
164    if (!_XReply(dpy, (xReply *) & rep, 0, xFalse)) {
165	UnlockDisplay(dpy);
166	SyncHandle();
167	TRACE("QueryDirectRenderingCapable... return False");
168	return False;
169    }
170    *isCapable = rep.isCapable;
171    UnlockDisplay(dpy);
172    SyncHandle();
173    TRACE("QueryDirectRenderingCapable... return True");
174    return True;
175}
176
177Bool
178uniDRIOpenConnection(dpy, screen, hSAREA, busIdString)
179    Display *dpy;
180    int screen;
181    drm_handle_t *hSAREA;
182    char **busIdString;
183{
184    XExtDisplayInfo *info = find_display(dpy);
185    xXF86DRIOpenConnectionReply rep;
186    xXF86DRIOpenConnectionReq *req;
187
188    TRACE("OpenConnection...");
189    uniDRICheckExtension(dpy, info, False);
190
191    LockDisplay(dpy);
192    GetReq(XF86DRIOpenConnection, req);
193    req->reqType = info->codes->major_opcode;
194    req->driReqType = X_XF86DRIOpenConnection;
195    req->screen = screen;
196    if (!_XReply(dpy, (xReply *) & rep, 0, xFalse)) {
197	UnlockDisplay(dpy);
198	SyncHandle();
199	TRACE("OpenConnection... return False");
200	return False;
201    }
202
203    *hSAREA = rep.hSAREALow;
204#ifdef LONG64
205    if (sizeof(drm_handle_t) == 8) {
206	*hSAREA |= ((unsigned long)rep.hSAREAHigh) << 32;
207    }
208#endif
209    if (rep.length) {
210	if (!(*busIdString = (char *)Xcalloc(rep.busIdStringLength + 1, 1))) {
211	    _XEatData(dpy, ((rep.busIdStringLength + 3) & ~3));
212	    UnlockDisplay(dpy);
213	    SyncHandle();
214	    TRACE("OpenConnection... return False");
215	    return False;
216	}
217	_XReadPad(dpy, *busIdString, rep.busIdStringLength);
218    } else {
219	*busIdString = NULL;
220    }
221    UnlockDisplay(dpy);
222    SyncHandle();
223    TRACE("OpenConnection... return True");
224    return True;
225}
226
227Bool
228uniDRIAuthConnection(dpy, screen, magic)
229    Display *dpy;
230    int screen;
231    drm_magic_t magic;
232{
233    XExtDisplayInfo *info = find_display(dpy);
234    xXF86DRIAuthConnectionReq *req;
235    xXF86DRIAuthConnectionReply rep;
236
237    TRACE("AuthConnection...");
238    uniDRICheckExtension(dpy, info, False);
239
240    LockDisplay(dpy);
241    GetReq(XF86DRIAuthConnection, req);
242    req->reqType = info->codes->major_opcode;
243    req->driReqType = X_XF86DRIAuthConnection;
244    req->screen = screen;
245    req->magic = magic;
246    rep.authenticated = 0;
247    if (!_XReply(dpy, (xReply *) & rep, 0, xFalse) || !rep.authenticated) {
248	UnlockDisplay(dpy);
249	SyncHandle();
250	TRACE("AuthConnection... return False");
251	return False;
252    }
253    UnlockDisplay(dpy);
254    SyncHandle();
255    TRACE("AuthConnection... return True");
256    return True;
257}
258
259Bool
260uniDRICloseConnection(dpy, screen)
261    Display *dpy;
262    int screen;
263{
264    XExtDisplayInfo *info = find_display(dpy);
265    xXF86DRICloseConnectionReq *req;
266
267    TRACE("CloseConnection...");
268
269    uniDRICheckExtension(dpy, info, False);
270
271    LockDisplay(dpy);
272    GetReq(XF86DRICloseConnection, req);
273    req->reqType = info->codes->major_opcode;
274    req->driReqType = X_XF86DRICloseConnection;
275    req->screen = screen;
276    UnlockDisplay(dpy);
277    SyncHandle();
278    TRACE("CloseConnection... return True");
279    return True;
280}
281
282Bool
283uniDRIGetClientDriverName(dpy, screen, ddxDriverMajorVersion,
284    ddxDriverMinorVersion, ddxDriverPatchVersion, clientDriverName)
285    Display *dpy;
286    int screen;
287    int *ddxDriverMajorVersion;
288    int *ddxDriverMinorVersion;
289    int *ddxDriverPatchVersion;
290    char **clientDriverName;
291{
292    XExtDisplayInfo *info = find_display(dpy);
293    xXF86DRIGetClientDriverNameReply rep;
294    xXF86DRIGetClientDriverNameReq *req;
295
296    TRACE("GetClientDriverName...");
297    uniDRICheckExtension(dpy, info, False);
298
299    LockDisplay(dpy);
300    GetReq(XF86DRIGetClientDriverName, req);
301    req->reqType = info->codes->major_opcode;
302    req->driReqType = X_XF86DRIGetClientDriverName;
303    req->screen = screen;
304    if (!_XReply(dpy, (xReply *) & rep, 0, xFalse)) {
305	UnlockDisplay(dpy);
306	SyncHandle();
307	TRACE("GetClientDriverName... return False");
308	return False;
309    }
310
311    *ddxDriverMajorVersion = rep.ddxDriverMajorVersion;
312    *ddxDriverMinorVersion = rep.ddxDriverMinorVersion;
313    *ddxDriverPatchVersion = rep.ddxDriverPatchVersion;
314
315    if (rep.length) {
316	if (!(*clientDriverName =
317		(char *)Xcalloc(rep.clientDriverNameLength + 1, 1))) {
318	    _XEatData(dpy, ((rep.clientDriverNameLength + 3) & ~3));
319	    UnlockDisplay(dpy);
320	    SyncHandle();
321	    TRACE("GetClientDriverName... return False");
322	    return False;
323	}
324	_XReadPad(dpy, *clientDriverName, rep.clientDriverNameLength);
325    } else {
326	*clientDriverName = NULL;
327    }
328    UnlockDisplay(dpy);
329    SyncHandle();
330    TRACE("GetClientDriverName... return True");
331    return True;
332}
333
334Bool
335uniDRICreateContextWithConfig(dpy, screen, configID, context, hHWContext)
336    Display *dpy;
337    int screen;
338    int configID;
339    XID *context;
340    drm_context_t *hHWContext;
341{
342    XExtDisplayInfo *info = find_display(dpy);
343    xXF86DRICreateContextReply rep;
344    xXF86DRICreateContextReq *req;
345
346    TRACE("CreateContext...");
347    uniDRICheckExtension(dpy, info, False);
348
349    LockDisplay(dpy);
350    GetReq(XF86DRICreateContext, req);
351    req->reqType = info->codes->major_opcode;
352    req->driReqType = X_XF86DRICreateContext;
353    req->visual = configID;
354    req->screen = screen;
355    *context = XAllocID(dpy);
356    req->context = *context;
357    if (!_XReply(dpy, (xReply *) & rep, 0, xFalse)) {
358	UnlockDisplay(dpy);
359	SyncHandle();
360	TRACE("CreateContext... return False");
361	return False;
362    }
363    *hHWContext = rep.hHWContext;
364    UnlockDisplay(dpy);
365    SyncHandle();
366    TRACE("CreateContext... return True");
367    return True;
368}
369
370Bool
371uniDRICreateContext(dpy, screen, visual, context, hHWContext)
372    Display *dpy;
373    int screen;
374    Visual *visual;
375    XID *context;
376    drm_context_t *hHWContext;
377{
378    return uniDRICreateContextWithConfig(dpy, screen, visual->visualid,
379	context, hHWContext);
380}
381
382Bool
383uniDRIDestroyContext(Display * ndpy, int screen, XID context)
384{
385    Display *const dpy = (Display *) ndpy;
386    XExtDisplayInfo *info = find_display(dpy);
387    xXF86DRIDestroyContextReq *req;
388
389    TRACE("DestroyContext...");
390    uniDRICheckExtension(dpy, info, False);
391
392    LockDisplay(dpy);
393    GetReq(XF86DRIDestroyContext, req);
394    req->reqType = info->codes->major_opcode;
395    req->driReqType = X_XF86DRIDestroyContext;
396    req->screen = screen;
397    req->context = context;
398    UnlockDisplay(dpy);
399    SyncHandle();
400    TRACE("DestroyContext... return True");
401    return True;
402}
403
404Bool
405uniDRICreateDrawable(Display * ndpy, int screen,
406    Drawable drawable, drm_drawable_t * hHWDrawable)
407{
408    Display *const dpy = (Display *) ndpy;
409    XExtDisplayInfo *info = find_display(dpy);
410    xXF86DRICreateDrawableReply rep;
411    xXF86DRICreateDrawableReq *req;
412
413    TRACE("CreateDrawable...");
414    uniDRICheckExtension(dpy, info, False);
415
416    LockDisplay(dpy);
417    GetReq(XF86DRICreateDrawable, req);
418    req->reqType = info->codes->major_opcode;
419    req->driReqType = X_XF86DRICreateDrawable;
420    req->screen = screen;
421    req->drawable = drawable;
422    if (!_XReply(dpy, (xReply *) & rep, 0, xFalse)) {
423	UnlockDisplay(dpy);
424	SyncHandle();
425	TRACE("CreateDrawable... return False");
426	return False;
427    }
428    *hHWDrawable = rep.hHWDrawable;
429    UnlockDisplay(dpy);
430    SyncHandle();
431    TRACE("CreateDrawable... return True");
432    return True;
433}
434
435Bool
436uniDRIDestroyDrawable(Display * ndpy, int screen, Drawable drawable)
437{
438    Display *const dpy = (Display *) ndpy;
439    XExtDisplayInfo *info = find_display(dpy);
440    xXF86DRIDestroyDrawableReq *req;
441
442    TRACE("DestroyDrawable...");
443    uniDRICheckExtension(dpy, info, False);
444
445    LockDisplay(dpy);
446    GetReq(XF86DRIDestroyDrawable, req);
447    req->reqType = info->codes->major_opcode;
448    req->driReqType = X_XF86DRIDestroyDrawable;
449    req->screen = screen;
450    req->drawable = drawable;
451    UnlockDisplay(dpy);
452    SyncHandle();
453    TRACE("DestroyDrawable... return True");
454    return True;
455}
456
457Bool
458uniDRIGetDrawableInfo(Display * dpy, int screen, Drawable drawable,
459    unsigned int *index, unsigned int *stamp,
460    int *X, int *Y, int *W, int *H,
461    int *numClipRects, drm_clip_rect_t ** pClipRects,
462    int *backX, int *backY,
463    int *numBackClipRects, drm_clip_rect_t ** pBackClipRects)
464{
465    XExtDisplayInfo *info = find_display(dpy);
466    xXF86DRIGetDrawableInfoReply rep;
467    xXF86DRIGetDrawableInfoReq *req;
468    int total_rects;
469
470    TRACE("GetDrawableInfo...");
471    uniDRICheckExtension(dpy, info, False);
472
473    LockDisplay(dpy);
474    GetReq(XF86DRIGetDrawableInfo, req);
475    req->reqType = info->codes->major_opcode;
476    req->driReqType = X_XF86DRIGetDrawableInfo;
477    req->screen = screen;
478    req->drawable = drawable;
479
480    if (!_XReply(dpy, (xReply *) & rep, 1, xFalse)) {
481	UnlockDisplay(dpy);
482	SyncHandle();
483	TRACE("GetDrawableInfo... return False");
484	return False;
485    }
486    *index = rep.drawableTableIndex;
487    *stamp = rep.drawableTableStamp;
488    *X = (int)rep.drawableX;
489    *Y = (int)rep.drawableY;
490    *W = (int)rep.drawableWidth;
491    *H = (int)rep.drawableHeight;
492    *numClipRects = rep.numClipRects;
493    total_rects = *numClipRects;
494
495    *backX = rep.backX;
496    *backY = rep.backY;
497    *numBackClipRects = rep.numBackClipRects;
498    total_rects += *numBackClipRects;
499
500#if 0
501    /* Because of the fix in Xserver/GL/dri/xf86dri.c, this check breaks
502     * backwards compatibility (Because of the >> 2 shift) but the fix
503     * enables multi-threaded apps to work.
504     */
505    if (rep.length != ((((SIZEOF(xXF86DRIGetDrawableInfoReply) -
506			SIZEOF(xGenericReply) +
507			total_rects * sizeof(drm_clip_rect_t)) +
508		    3) & ~3) >> 2)) {
509	_XEatData(dpy, rep.length);
510	UnlockDisplay(dpy);
511	SyncHandle();
512	TRACE("GetDrawableInfo... return False");
513	return False;
514    }
515#endif
516
517    if (*numClipRects) {
518	int len = sizeof(drm_clip_rect_t) * (*numClipRects);
519
520	*pClipRects = (drm_clip_rect_t *) Xcalloc(len, 1);
521	if (*pClipRects)
522	    _XRead(dpy, (char *)*pClipRects, len);
523    } else {
524	*pClipRects = NULL;
525    }
526
527    if (*numBackClipRects) {
528	int len = sizeof(drm_clip_rect_t) * (*numBackClipRects);
529
530	*pBackClipRects = (drm_clip_rect_t *) Xcalloc(len, 1);
531	if (*pBackClipRects)
532	    _XRead(dpy, (char *)*pBackClipRects, len);
533    } else {
534	*pBackClipRects = NULL;
535    }
536
537    UnlockDisplay(dpy);
538    SyncHandle();
539    TRACE("GetDrawableInfo... return True");
540    return True;
541}
542
543Bool
544uniDRIGetDeviceInfo(dpy, screen, hFrameBuffer,
545    fbOrigin, fbSize, fbStride, devPrivateSize, pDevPrivate)
546    Display *dpy;
547    int screen;
548    drm_handle_t *hFrameBuffer;
549    int *fbOrigin;
550    int *fbSize;
551    int *fbStride;
552    int *devPrivateSize;
553    void **pDevPrivate;
554{
555    XExtDisplayInfo *info = find_display(dpy);
556    xXF86DRIGetDeviceInfoReply rep;
557    xXF86DRIGetDeviceInfoReq *req;
558
559    TRACE("GetDeviceInfo...");
560    uniDRICheckExtension(dpy, info, False);
561
562    LockDisplay(dpy);
563    GetReq(XF86DRIGetDeviceInfo, req);
564    req->reqType = info->codes->major_opcode;
565    req->driReqType = X_XF86DRIGetDeviceInfo;
566    req->screen = screen;
567    if (!_XReply(dpy, (xReply *) & rep, 0, xFalse)) {
568	UnlockDisplay(dpy);
569	SyncHandle();
570	TRACE("GetDeviceInfo... return False");
571	return False;
572    }
573
574    *hFrameBuffer = rep.hFrameBufferLow;
575#ifdef LONG64
576    if (sizeof(drm_handle_t) == 8) {
577	*hFrameBuffer |= ((unsigned long)rep.hFrameBufferHigh) << 32;
578    }
579#endif
580
581    *fbOrigin = rep.framebufferOrigin;
582    *fbSize = rep.framebufferSize;
583    *fbStride = rep.framebufferStride;
584    *devPrivateSize = rep.devPrivateSize;
585
586    if (rep.length) {
587	if (!(*pDevPrivate = (void *)Xcalloc(rep.devPrivateSize, 1))) {
588	    _XEatData(dpy, ((rep.devPrivateSize + 3) & ~3));
589	    UnlockDisplay(dpy);
590	    SyncHandle();
591	    TRACE("GetDeviceInfo... return False");
592	    return False;
593	}
594	_XRead(dpy, (char *)*pDevPrivate, rep.devPrivateSize);
595    } else {
596	*pDevPrivate = NULL;
597    }
598
599    UnlockDisplay(dpy);
600    SyncHandle();
601    TRACE("GetDeviceInfo... return True");
602    return True;
603}
604