1 /*
2 * Copyright © 2014 Jon Turney
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21 * IN THE SOFTWARE.
22 */
23
24 #ifdef HAVE_DIX_CONFIG_H
25 #include <dix-config.h>
26 #endif
27
28 #include <X11/X.h>
29 #include <X11/Xproto.h>
30 #include <X11/extensions/windowsdristr.h>
31
32 #include "dixstruct.h"
33 #include "extnsionst.h"
34 #include "scrnintstr.h"
35 #include "swaprep.h"
36 #include "protocol-versions.h"
37 #include "windowsdri.h"
38 #include "glx/dri_helpers.h"
39
40 static int WindowsDRIErrorBase = 0;
41 static unsigned char WindowsDRIReqCode = 0;
42 static int WindowsDRIEventBase = 0;
43
44 static void
WindowsDRIResetProc(ExtensionEntry * extEntry)45 WindowsDRIResetProc(ExtensionEntry* extEntry)
46 {
47 }
48
49 static int
ProcWindowsDRIQueryVersion(ClientPtr client)50 ProcWindowsDRIQueryVersion(ClientPtr client)
51 {
52 xWindowsDRIQueryVersionReply rep;
53
54 REQUEST_SIZE_MATCH(xWindowsDRIQueryVersionReq);
55 rep.type = X_Reply;
56 rep.length = 0;
57 rep.sequenceNumber = client->sequence;
58 rep.majorVersion = SERVER_WINDOWSDRI_MAJOR_VERSION;
59 rep.minorVersion = SERVER_WINDOWSDRI_MINOR_VERSION;
60 rep.patchVersion = SERVER_WINDOWSDRI_PATCH_VERSION;
61 if (client->swapped) {
62 swaps(&rep.sequenceNumber);
63 swapl(&rep.length);
64 swaps(&rep.majorVersion);
65 swaps(&rep.minorVersion);
66 swapl(&rep.patchVersion);
67 }
68 WriteToClient(client, sizeof(xWindowsDRIQueryVersionReply), &rep);
69 return Success;
70 }
71
72 static int
ProcWindowsDRIQueryDirectRenderingCapable(ClientPtr client)73 ProcWindowsDRIQueryDirectRenderingCapable(ClientPtr client)
74 {
75 xWindowsDRIQueryDirectRenderingCapableReply rep;
76
77 REQUEST(xWindowsDRIQueryDirectRenderingCapableReq);
78 REQUEST_SIZE_MATCH(xWindowsDRIQueryDirectRenderingCapableReq);
79 rep.type = X_Reply;
80 rep.length = 0;
81 rep.sequenceNumber = client->sequence;
82
83 if (!client->local)
84 rep.isCapable = 0;
85 else
86 rep.isCapable = glxWinGetScreenAiglxIsActive(screenInfo.screens[stuff->screen]);
87
88 if (client->swapped) {
89 swaps(&rep.sequenceNumber);
90 swapl(&rep.length);
91 }
92
93 WriteToClient(client,
94 sizeof(xWindowsDRIQueryDirectRenderingCapableReply),
95 &rep);
96 return Success;
97 }
98
99 static int
ProcWindowsDRIQueryDrawable(ClientPtr client)100 ProcWindowsDRIQueryDrawable(ClientPtr client)
101 {
102 xWindowsDRIQueryDrawableReply rep;
103 int rc;
104
105 REQUEST(xWindowsDRIQueryDrawableReq);
106 REQUEST_SIZE_MATCH(xWindowsDRIQueryDrawableReq);
107 rep.type = X_Reply;
108 rep.length = 0;
109 rep.sequenceNumber = client->sequence;
110
111 rc = glxWinQueryDrawable(client, stuff->drawable, &(rep.drawable_type), &(rep.handle));
112
113 if (rc)
114 return rc;
115
116 if (client->swapped) {
117 swaps(&rep.sequenceNumber);
118 swapl(&rep.length);
119 swapl(&rep.handle);
120 swapl(&rep.drawable_type);
121 }
122
123 WriteToClient(client, sizeof(xWindowsDRIQueryDrawableReply), &rep);
124 return Success;
125 }
126
127 static int
ProcWindowsDRIFBConfigToPixelFormat(ClientPtr client)128 ProcWindowsDRIFBConfigToPixelFormat(ClientPtr client)
129 {
130 xWindowsDRIFBConfigToPixelFormatReply rep;
131
132 REQUEST(xWindowsDRIFBConfigToPixelFormatReq);
133 REQUEST_SIZE_MATCH(xWindowsDRIFBConfigToPixelFormatReq);
134 rep.type = X_Reply;
135 rep.length = 0;
136 rep.sequenceNumber = client->sequence;
137
138 rep.pixelFormatIndex = glxWinFBConfigIDToPixelFormatIndex(stuff->screen, stuff->fbConfigID);
139
140 if (client->swapped) {
141 swaps(&rep.sequenceNumber);
142 swapl(&rep.length);
143 swapl(&rep.pixelFormatIndex);
144 }
145
146 WriteToClient(client, sizeof(xWindowsDRIFBConfigToPixelFormatReply), &rep);
147 return Success;
148 }
149
150 /* dispatch */
151
152 static int
ProcWindowsDRIDispatch(ClientPtr client)153 ProcWindowsDRIDispatch(ClientPtr client)
154 {
155 REQUEST(xReq);
156
157 switch (stuff->data) {
158 case X_WindowsDRIQueryVersion:
159 return ProcWindowsDRIQueryVersion(client);
160
161 case X_WindowsDRIQueryDirectRenderingCapable:
162 return ProcWindowsDRIQueryDirectRenderingCapable(client);
163 }
164
165 if (!client->local)
166 return WindowsDRIErrorBase + WindowsDRIClientNotLocal;
167
168 switch (stuff->data) {
169 case X_WindowsDRIQueryDrawable:
170 return ProcWindowsDRIQueryDrawable(client);
171
172 case X_WindowsDRIFBConfigToPixelFormat:
173 return ProcWindowsDRIFBConfigToPixelFormat(client);
174
175 default:
176 return BadRequest;
177 }
178 }
179
180 static void
SNotifyEvent(xWindowsDRINotifyEvent * from,xWindowsDRINotifyEvent * to)181 SNotifyEvent(xWindowsDRINotifyEvent *from,
182 xWindowsDRINotifyEvent *to)
183 {
184 to->type = from->type;
185 to->kind = from->kind;
186 cpswaps(from->sequenceNumber, to->sequenceNumber);
187 cpswapl(from->time, to->time);
188 }
189
190 static int
SProcWindowsDRIQueryVersion(ClientPtr client)191 SProcWindowsDRIQueryVersion(ClientPtr client)
192 {
193 REQUEST(xWindowsDRIQueryVersionReq);
194 swaps(&stuff->length);
195 return ProcWindowsDRIQueryVersion(client);
196 }
197
198 static int
SProcWindowsDRIQueryDirectRenderingCapable(ClientPtr client)199 SProcWindowsDRIQueryDirectRenderingCapable(ClientPtr client)
200 {
201 REQUEST(xWindowsDRIQueryDirectRenderingCapableReq);
202 swaps(&stuff->length);
203 swapl(&stuff->screen);
204 return ProcWindowsDRIQueryDirectRenderingCapable(client);
205 }
206
207 static int
SProcWindowsDRIQueryDrawable(ClientPtr client)208 SProcWindowsDRIQueryDrawable(ClientPtr client)
209 {
210 REQUEST(xWindowsDRIQueryDrawableReq);
211 swaps(&stuff->length);
212 swapl(&stuff->screen);
213 swapl(&stuff->drawable);
214 return ProcWindowsDRIQueryDrawable(client);
215 }
216
217 static int
SProcWindowsDRIFBConfigToPixelFormat(ClientPtr client)218 SProcWindowsDRIFBConfigToPixelFormat(ClientPtr client)
219 {
220 REQUEST(xWindowsDRIFBConfigToPixelFormatReq);
221 swaps(&stuff->length);
222 swapl(&stuff->screen);
223 swapl(&stuff->fbConfigID);
224 return ProcWindowsDRIFBConfigToPixelFormat(client);
225 }
226
227 static int
SProcWindowsDRIDispatch(ClientPtr client)228 SProcWindowsDRIDispatch(ClientPtr client)
229 {
230 REQUEST(xReq);
231
232 switch (stuff->data) {
233 case X_WindowsDRIQueryVersion:
234 return SProcWindowsDRIQueryVersion(client);
235
236 case X_WindowsDRIQueryDirectRenderingCapable:
237 return SProcWindowsDRIQueryDirectRenderingCapable(client);
238 }
239
240 if (!client->local)
241 return WindowsDRIErrorBase + WindowsDRIClientNotLocal;
242
243 switch (stuff->data) {
244 case X_WindowsDRIQueryDrawable:
245 return SProcWindowsDRIQueryDrawable(client);
246
247 case X_WindowsDRIFBConfigToPixelFormat:
248 return SProcWindowsDRIFBConfigToPixelFormat(client);
249
250 default:
251 return BadRequest;
252 }
253 }
254
255 void
WindowsDRIExtensionInit(void)256 WindowsDRIExtensionInit(void)
257 {
258 ExtensionEntry* extEntry;
259
260 if ((extEntry = AddExtension(WINDOWSDRINAME,
261 WindowsDRINumberEvents,
262 WindowsDRINumberErrors,
263 ProcWindowsDRIDispatch,
264 SProcWindowsDRIDispatch,
265 WindowsDRIResetProc,
266 StandardMinorOpcode))) {
267 size_t i;
268 WindowsDRIReqCode = (unsigned char)extEntry->base;
269 WindowsDRIErrorBase = extEntry->errorBase;
270 WindowsDRIEventBase = extEntry->eventBase;
271 for (i = 0; i < WindowsDRINumberEvents; i++)
272 EventSwapVector[WindowsDRIEventBase + i] = (EventSwapPtr)SNotifyEvent;
273 }
274 }
275