1*d83cc019SAndroid Build Coastguard Worker /*
2*d83cc019SAndroid Build Coastguard Worker * Copyright © 2008 Red Hat, Inc.
3*d83cc019SAndroid Build Coastguard Worker *
4*d83cc019SAndroid Build Coastguard Worker * Permission is hereby granted, free of charge, to any person obtaining a
5*d83cc019SAndroid Build Coastguard Worker * copy of this software and associated documentation files (the "Soft-
6*d83cc019SAndroid Build Coastguard Worker * ware"), to deal in the Software without restriction, including without
7*d83cc019SAndroid Build Coastguard Worker * limitation the rights to use, copy, modify, merge, publish, distribute,
8*d83cc019SAndroid Build Coastguard Worker * and/or sell copies of the Software, and to permit persons to whom the
9*d83cc019SAndroid Build Coastguard Worker * Software is furnished to do so, provided that the above copyright
10*d83cc019SAndroid Build Coastguard Worker * notice(s) and this permission notice appear in all copies of the Soft-
11*d83cc019SAndroid Build Coastguard Worker * ware and that both the above copyright notice(s) and this permission
12*d83cc019SAndroid Build Coastguard Worker * notice appear in supporting documentation.
13*d83cc019SAndroid Build Coastguard Worker *
14*d83cc019SAndroid Build Coastguard Worker * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15*d83cc019SAndroid Build Coastguard Worker * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL-
16*d83cc019SAndroid Build Coastguard Worker * ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY
17*d83cc019SAndroid Build Coastguard Worker * RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN
18*d83cc019SAndroid Build Coastguard Worker * THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSE-
19*d83cc019SAndroid Build Coastguard Worker * QUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
20*d83cc019SAndroid Build Coastguard Worker * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
21*d83cc019SAndroid Build Coastguard Worker * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFOR-
22*d83cc019SAndroid Build Coastguard Worker * MANCE OF THIS SOFTWARE.
23*d83cc019SAndroid Build Coastguard Worker *
24*d83cc019SAndroid Build Coastguard Worker * Except as contained in this notice, the name of a copyright holder shall
25*d83cc019SAndroid Build Coastguard Worker * not be used in advertising or otherwise to promote the sale, use or
26*d83cc019SAndroid Build Coastguard Worker * other dealings in this Software without prior written authorization of
27*d83cc019SAndroid Build Coastguard Worker * the copyright holder.
28*d83cc019SAndroid Build Coastguard Worker *
29*d83cc019SAndroid Build Coastguard Worker * Authors:
30*d83cc019SAndroid Build Coastguard Worker * Kristian Høgsberg ([email protected])
31*d83cc019SAndroid Build Coastguard Worker */
32*d83cc019SAndroid Build Coastguard Worker
33*d83cc019SAndroid Build Coastguard Worker #include <stdio.h>
34*d83cc019SAndroid Build Coastguard Worker #include <X11/Xlibint.h>
35*d83cc019SAndroid Build Coastguard Worker #include <X11/extensions/Xext.h>
36*d83cc019SAndroid Build Coastguard Worker #include <X11/extensions/extutil.h>
37*d83cc019SAndroid Build Coastguard Worker #include <X11/extensions/dri2proto.h>
38*d83cc019SAndroid Build Coastguard Worker #include <X11/extensions/dri2tokens.h>
39*d83cc019SAndroid Build Coastguard Worker #include <xf86drm.h>
40*d83cc019SAndroid Build Coastguard Worker #include <drm.h>
41*d83cc019SAndroid Build Coastguard Worker #include <fcntl.h>
42*d83cc019SAndroid Build Coastguard Worker #include <unistd.h>
43*d83cc019SAndroid Build Coastguard Worker
44*d83cc019SAndroid Build Coastguard Worker #include "dri2.h"
45*d83cc019SAndroid Build Coastguard Worker
46*d83cc019SAndroid Build Coastguard Worker static char dri2ExtensionName[] = DRI2_NAME;
47*d83cc019SAndroid Build Coastguard Worker static XExtensionInfo *dri2Info;
48*d83cc019SAndroid Build Coastguard Worker static XEXT_GENERATE_CLOSE_DISPLAY (DRI2CloseDisplay, dri2Info)
49*d83cc019SAndroid Build Coastguard Worker
50*d83cc019SAndroid Build Coastguard Worker static /* const */ XExtensionHooks dri2ExtensionHooks = {
51*d83cc019SAndroid Build Coastguard Worker NULL, /* create_gc */
52*d83cc019SAndroid Build Coastguard Worker NULL, /* copy_gc */
53*d83cc019SAndroid Build Coastguard Worker NULL, /* flush_gc */
54*d83cc019SAndroid Build Coastguard Worker NULL, /* free_gc */
55*d83cc019SAndroid Build Coastguard Worker NULL, /* create_font */
56*d83cc019SAndroid Build Coastguard Worker NULL, /* free_font */
57*d83cc019SAndroid Build Coastguard Worker DRI2CloseDisplay, /* close_display */
58*d83cc019SAndroid Build Coastguard Worker };
59*d83cc019SAndroid Build Coastguard Worker
60*d83cc019SAndroid Build Coastguard Worker static XEXT_GENERATE_FIND_DISPLAY (DRI2FindDisplay,
61*d83cc019SAndroid Build Coastguard Worker dri2Info,
62*d83cc019SAndroid Build Coastguard Worker dri2ExtensionName,
63*d83cc019SAndroid Build Coastguard Worker &dri2ExtensionHooks,
64*d83cc019SAndroid Build Coastguard Worker 0, NULL)
65*d83cc019SAndroid Build Coastguard Worker
66*d83cc019SAndroid Build Coastguard Worker static Bool
DRI2Connect(Display * dpy,XID window,char ** driverName,char ** deviceName)67*d83cc019SAndroid Build Coastguard Worker DRI2Connect(Display *dpy, XID window, char **driverName, char **deviceName)
68*d83cc019SAndroid Build Coastguard Worker {
69*d83cc019SAndroid Build Coastguard Worker XExtDisplayInfo *info = DRI2FindDisplay(dpy);
70*d83cc019SAndroid Build Coastguard Worker xDRI2ConnectReply rep;
71*d83cc019SAndroid Build Coastguard Worker xDRI2ConnectReq *req;
72*d83cc019SAndroid Build Coastguard Worker
73*d83cc019SAndroid Build Coastguard Worker XextCheckExtension(dpy, info, dri2ExtensionName, False);
74*d83cc019SAndroid Build Coastguard Worker
75*d83cc019SAndroid Build Coastguard Worker LockDisplay(dpy);
76*d83cc019SAndroid Build Coastguard Worker GetReq(DRI2Connect, req);
77*d83cc019SAndroid Build Coastguard Worker req->reqType = info->codes->major_opcode;
78*d83cc019SAndroid Build Coastguard Worker req->dri2ReqType = X_DRI2Connect;
79*d83cc019SAndroid Build Coastguard Worker req->window = window;
80*d83cc019SAndroid Build Coastguard Worker req->driverType = DRI2DriverDRI;
81*d83cc019SAndroid Build Coastguard Worker if (!_XReply(dpy, (xReply *) & rep, 0, xFalse)) {
82*d83cc019SAndroid Build Coastguard Worker UnlockDisplay(dpy);
83*d83cc019SAndroid Build Coastguard Worker SyncHandle();
84*d83cc019SAndroid Build Coastguard Worker return False;
85*d83cc019SAndroid Build Coastguard Worker }
86*d83cc019SAndroid Build Coastguard Worker
87*d83cc019SAndroid Build Coastguard Worker if (rep.driverNameLength == 0 && rep.deviceNameLength == 0) {
88*d83cc019SAndroid Build Coastguard Worker UnlockDisplay(dpy);
89*d83cc019SAndroid Build Coastguard Worker SyncHandle();
90*d83cc019SAndroid Build Coastguard Worker return False;
91*d83cc019SAndroid Build Coastguard Worker }
92*d83cc019SAndroid Build Coastguard Worker
93*d83cc019SAndroid Build Coastguard Worker *driverName = Xmalloc(rep.driverNameLength + 1);
94*d83cc019SAndroid Build Coastguard Worker if (*driverName == NULL) {
95*d83cc019SAndroid Build Coastguard Worker _XEatData(dpy,
96*d83cc019SAndroid Build Coastguard Worker ((rep.driverNameLength + 3) & ~3) +
97*d83cc019SAndroid Build Coastguard Worker ((rep.deviceNameLength + 3) & ~3));
98*d83cc019SAndroid Build Coastguard Worker UnlockDisplay(dpy);
99*d83cc019SAndroid Build Coastguard Worker SyncHandle();
100*d83cc019SAndroid Build Coastguard Worker return False;
101*d83cc019SAndroid Build Coastguard Worker }
102*d83cc019SAndroid Build Coastguard Worker _XReadPad(dpy, *driverName, rep.driverNameLength);
103*d83cc019SAndroid Build Coastguard Worker (*driverName)[rep.driverNameLength] = '\0';
104*d83cc019SAndroid Build Coastguard Worker
105*d83cc019SAndroid Build Coastguard Worker *deviceName = Xmalloc(rep.deviceNameLength + 1);
106*d83cc019SAndroid Build Coastguard Worker if (*deviceName == NULL) {
107*d83cc019SAndroid Build Coastguard Worker Xfree(*driverName);
108*d83cc019SAndroid Build Coastguard Worker _XEatData(dpy, ((rep.deviceNameLength + 3) & ~3));
109*d83cc019SAndroid Build Coastguard Worker UnlockDisplay(dpy);
110*d83cc019SAndroid Build Coastguard Worker SyncHandle();
111*d83cc019SAndroid Build Coastguard Worker return False;
112*d83cc019SAndroid Build Coastguard Worker }
113*d83cc019SAndroid Build Coastguard Worker _XReadPad(dpy, *deviceName, rep.deviceNameLength);
114*d83cc019SAndroid Build Coastguard Worker (*deviceName)[rep.deviceNameLength] = '\0';
115*d83cc019SAndroid Build Coastguard Worker
116*d83cc019SAndroid Build Coastguard Worker UnlockDisplay(dpy);
117*d83cc019SAndroid Build Coastguard Worker SyncHandle();
118*d83cc019SAndroid Build Coastguard Worker
119*d83cc019SAndroid Build Coastguard Worker return True;
120*d83cc019SAndroid Build Coastguard Worker }
121*d83cc019SAndroid Build Coastguard Worker
122*d83cc019SAndroid Build Coastguard Worker static Bool
DRI2Authenticate(Display * dpy,XID window,unsigned int magic)123*d83cc019SAndroid Build Coastguard Worker DRI2Authenticate(Display * dpy, XID window, unsigned int magic)
124*d83cc019SAndroid Build Coastguard Worker {
125*d83cc019SAndroid Build Coastguard Worker XExtDisplayInfo *info = DRI2FindDisplay(dpy);
126*d83cc019SAndroid Build Coastguard Worker xDRI2AuthenticateReq *req;
127*d83cc019SAndroid Build Coastguard Worker xDRI2AuthenticateReply rep;
128*d83cc019SAndroid Build Coastguard Worker
129*d83cc019SAndroid Build Coastguard Worker XextCheckExtension(dpy, info, dri2ExtensionName, False);
130*d83cc019SAndroid Build Coastguard Worker
131*d83cc019SAndroid Build Coastguard Worker LockDisplay(dpy);
132*d83cc019SAndroid Build Coastguard Worker GetReq(DRI2Authenticate, req);
133*d83cc019SAndroid Build Coastguard Worker req->reqType = info->codes->major_opcode;
134*d83cc019SAndroid Build Coastguard Worker req->dri2ReqType = X_DRI2Authenticate;
135*d83cc019SAndroid Build Coastguard Worker req->window = window;
136*d83cc019SAndroid Build Coastguard Worker req->magic = magic;
137*d83cc019SAndroid Build Coastguard Worker
138*d83cc019SAndroid Build Coastguard Worker if (!_XReply(dpy, (xReply *) & rep, 0, xFalse)) {
139*d83cc019SAndroid Build Coastguard Worker UnlockDisplay(dpy);
140*d83cc019SAndroid Build Coastguard Worker SyncHandle();
141*d83cc019SAndroid Build Coastguard Worker return False;
142*d83cc019SAndroid Build Coastguard Worker }
143*d83cc019SAndroid Build Coastguard Worker
144*d83cc019SAndroid Build Coastguard Worker UnlockDisplay(dpy);
145*d83cc019SAndroid Build Coastguard Worker SyncHandle();
146*d83cc019SAndroid Build Coastguard Worker
147*d83cc019SAndroid Build Coastguard Worker return rep.authenticated;
148*d83cc019SAndroid Build Coastguard Worker }
149*d83cc019SAndroid Build Coastguard Worker
dri2_open(Display * dpy)150*d83cc019SAndroid Build Coastguard Worker int dri2_open(Display *dpy)
151*d83cc019SAndroid Build Coastguard Worker {
152*d83cc019SAndroid Build Coastguard Worker drm_auth_t auth;
153*d83cc019SAndroid Build Coastguard Worker char *driver, *device;
154*d83cc019SAndroid Build Coastguard Worker int fd;
155*d83cc019SAndroid Build Coastguard Worker
156*d83cc019SAndroid Build Coastguard Worker if (!DRI2Connect(dpy, DefaultRootWindow(dpy), &driver, &device))
157*d83cc019SAndroid Build Coastguard Worker return -1;
158*d83cc019SAndroid Build Coastguard Worker
159*d83cc019SAndroid Build Coastguard Worker fd = open(device, O_RDWR);
160*d83cc019SAndroid Build Coastguard Worker if (fd < 0)
161*d83cc019SAndroid Build Coastguard Worker return -1;
162*d83cc019SAndroid Build Coastguard Worker
163*d83cc019SAndroid Build Coastguard Worker if (drmIoctl(fd, DRM_IOCTL_GET_MAGIC, &auth))
164*d83cc019SAndroid Build Coastguard Worker goto err_fd;
165*d83cc019SAndroid Build Coastguard Worker
166*d83cc019SAndroid Build Coastguard Worker if (!DRI2Authenticate(dpy, DefaultRootWindow(dpy), auth.magic))
167*d83cc019SAndroid Build Coastguard Worker goto err_fd;
168*d83cc019SAndroid Build Coastguard Worker
169*d83cc019SAndroid Build Coastguard Worker return fd;
170*d83cc019SAndroid Build Coastguard Worker
171*d83cc019SAndroid Build Coastguard Worker err_fd:
172*d83cc019SAndroid Build Coastguard Worker close(fd);
173*d83cc019SAndroid Build Coastguard Worker return -1;
174*d83cc019SAndroid Build Coastguard Worker }
175