2 * Copyright © 2013 Keith Packard
4 * Permission to use, copy, modify, distribute, and sell this software and its
5 * documentation for any purpose is hereby granted without fee, provided that
6 * the above copyright notice appear in all copies and that both that copyright
7 * notice and this permission notice appear in supporting documentation, and
8 * that the name of the copyright holders not be used in advertising or
9 * publicity pertaining to distribution of the software without specific,
10 * written prior permission. The copyright holders make no representations
11 * about the suitability of this software for any purpose. It is provided "as
12 * is" without express or implied warranty.
14 * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
15 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
16 * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
17 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
18 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
19 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
23 #ifdef HAVE_XORG_CONFIG_H
24 #include <xorg-config.h>
27 #include "dri3_priv.h"
31 #include "../Xext/syncsdk.h"
32 #include <protocol-versions.h>
35 proc_dri3_query_version(ClientPtr client
)
37 REQUEST(xDRI3QueryVersionReq
);
38 xDRI3QueryVersionReply rep
= {
40 .sequenceNumber
= client
->sequence
,
42 .majorVersion
= SERVER_DRI3_MAJOR_VERSION
,
43 .minorVersion
= SERVER_DRI3_MINOR_VERSION
46 REQUEST_SIZE_MATCH(xDRI3QueryVersionReq
);
48 if (client
->swapped
) {
49 swaps(&rep
.sequenceNumber
);
51 swapl(&rep
.majorVersion
);
52 swapl(&rep
.minorVersion
);
54 WriteToClient(client
, sizeof(rep
), &rep
);
59 proc_dri3_open(ClientPtr client
)
61 REQUEST(xDRI3OpenReq
);
62 xDRI3OpenReply rep
= {
65 .sequenceNumber
= client
->sequence
,
68 RRProviderPtr provider
;
74 REQUEST_SIZE_MATCH(xDRI3OpenReq
);
76 status
= dixLookupDrawable(&drawable
, stuff
->drawable
, client
, 0, DixReadAccess
);
77 if (status
!= Success
)
80 if (stuff
->provider
== None
)
82 else if (!RRProviderType
) {
85 VERIFY_RR_PROVIDER(stuff
->provider
, provider
, DixReadAccess
);
86 if (drawable
->pScreen
!= provider
->pScreen
)
89 screen
= drawable
->pScreen
;
91 status
= dri3_open(client
, screen
, provider
, &fd
);
92 if (status
!= Success
)
95 if (client
->swapped
) {
96 swaps(&rep
.sequenceNumber
);
100 if (WriteFdToClient(client
, fd
, TRUE
) < 0) {
105 WriteToClient(client
, sizeof (rep
), &rep
);
111 proc_dri3_pixmap_from_buffer(ClientPtr client
)
113 REQUEST(xDRI3PixmapFromBufferReq
);
115 DrawablePtr drawable
;
119 SetReqFds(client
, 1);
120 REQUEST_SIZE_MATCH(xDRI3PixmapFromBufferReq
);
121 LEGAL_NEW_RESOURCE(stuff
->pixmap
, client
);
122 rc
= dixLookupDrawable(&drawable
, stuff
->drawable
, client
, M_ANY
, DixGetAttrAccess
);
124 client
->errorValue
= stuff
->drawable
;
128 if (!stuff
->width
|| !stuff
->height
) {
129 client
->errorValue
= 0;
133 if (stuff
->width
> 32767 || stuff
->height
> 32767)
136 if (stuff
->depth
!= 1) {
137 DepthPtr depth
= drawable
->pScreen
->allowedDepths
;
139 for (i
= 0; i
< drawable
->pScreen
->numDepths
; i
++, depth
++)
140 if (depth
->depth
== stuff
->depth
)
142 if (i
== drawable
->pScreen
->numDepths
) {
143 client
->errorValue
= stuff
->depth
;
148 fd
= ReadFdFromClient(client
);
152 rc
= dri3_pixmap_from_fd(&pixmap
,
153 drawable
->pScreen
, fd
,
154 stuff
->width
, stuff
->height
,
155 stuff
->stride
, stuff
->depth
,
161 pixmap
->drawable
.id
= stuff
->pixmap
;
163 /* security creation/labeling check */
164 rc
= XaceHook(XACE_RESOURCE_ACCESS
, client
, stuff
->pixmap
, RT_PIXMAP
,
165 pixmap
, RT_NONE
, NULL
, DixCreateAccess
);
168 (*drawable
->pScreen
->DestroyPixmap
) (pixmap
);
171 if (AddResource(stuff
->pixmap
, RT_PIXMAP
, (pointer
) pixmap
))
178 proc_dri3_buffer_from_pixmap(ClientPtr client
)
180 REQUEST(xDRI3BufferFromPixmapReq
);
181 xDRI3BufferFromPixmapReply rep
= {
184 .sequenceNumber
= client
->sequence
,
191 REQUEST_SIZE_MATCH(xDRI3BufferFromPixmapReq
);
192 rc
= dixLookupResourceByType((pointer
*) &pixmap
, stuff
->pixmap
, RT_PIXMAP
,
193 client
, DixWriteAccess
);
195 client
->errorValue
= stuff
->pixmap
;
199 rep
.width
= pixmap
->drawable
.width
;
200 rep
.height
= pixmap
->drawable
.height
;
201 rep
.depth
= pixmap
->drawable
.depth
;
202 rep
.bpp
= pixmap
->drawable
.bitsPerPixel
;
204 rc
= dri3_fd_from_pixmap(&fd
, pixmap
, &rep
.stride
, &rep
.size
);
208 if (client
->swapped
) {
209 swaps(&rep
.sequenceNumber
);
216 if (WriteFdToClient(client
, fd
, TRUE
) < 0) {
221 WriteToClient(client
, sizeof(rep
), &rep
);
223 return client
->noClientException
;
227 proc_dri3_fence_from_fd(ClientPtr client
)
229 REQUEST(xDRI3FenceFromFDReq
);
230 DrawablePtr drawable
;
234 SetReqFds(client
, 1);
235 REQUEST_SIZE_MATCH(xDRI3FenceFromFDReq
);
236 LEGAL_NEW_RESOURCE(stuff
->fence
, client
);
238 status
= dixLookupDrawable(&drawable
, stuff
->drawable
, client
, M_ANY
, DixGetAttrAccess
);
239 if (status
!= Success
)
242 fd
= ReadFdFromClient(client
);
246 status
= SyncCreateFenceFromFD(client
, drawable
, stuff
->fence
,
247 fd
, stuff
->initially_triggered
);
253 proc_dri3_fd_from_fence(ClientPtr client
)
255 REQUEST(xDRI3FDFromFenceReq
);
256 xDRI3FDFromFenceReply rep
= {
259 .sequenceNumber
= client
->sequence
,
262 DrawablePtr drawable
;
267 REQUEST_SIZE_MATCH(xDRI3FDFromFenceReq
);
269 status
= dixLookupDrawable(&drawable
, stuff
->drawable
, client
, M_ANY
, DixGetAttrAccess
);
270 if (status
!= Success
)
272 status
= SyncVerifyFence(&fence
, stuff
->fence
, client
, DixWriteAccess
);
273 if (status
!= Success
)
276 fd
= SyncFDFromFence(client
, drawable
, fence
);
280 if (client
->swapped
) {
281 swaps(&rep
.sequenceNumber
);
284 if (WriteFdToClient(client
, fd
, FALSE
) < 0)
287 WriteToClient(client
, sizeof(rep
), &rep
);
289 return client
->noClientException
;
292 int (*proc_dri3_vector
[DRI3NumberRequests
]) (ClientPtr
) = {
293 proc_dri3_query_version
, /* 0 */
294 proc_dri3_open
, /* 1 */
295 proc_dri3_pixmap_from_buffer
, /* 2 */
296 proc_dri3_buffer_from_pixmap
, /* 3 */
297 proc_dri3_fence_from_fd
, /* 4 */
298 proc_dri3_fd_from_fence
, /* 5 */
302 proc_dri3_dispatch(ClientPtr client
)
305 if (stuff
->data
>= DRI3NumberRequests
|| !proc_dri3_vector
[stuff
->data
])
307 return (*proc_dri3_vector
[stuff
->data
]) (client
);
311 sproc_dri3_query_version(ClientPtr client
)
313 REQUEST(xDRI3QueryVersionReq
);
315 swaps(&stuff
->length
);
316 swapl(&stuff
->majorVersion
);
317 swapl(&stuff
->minorVersion
);
318 return (*proc_dri3_vector
[stuff
->dri3ReqType
]) (client
);
322 sproc_dri3_open(ClientPtr client
)
324 REQUEST(xDRI3OpenReq
);
326 swaps(&stuff
->length
);
327 swapl(&stuff
->drawable
);
328 swapl(&stuff
->provider
);
329 return (*proc_dri3_vector
[stuff
->dri3ReqType
]) (client
);
333 sproc_dri3_pixmap_from_buffer(ClientPtr client
)
335 REQUEST(xDRI3PixmapFromBufferReq
);
337 swaps(&stuff
->length
);
338 swapl(&stuff
->pixmap
);
339 swapl(&stuff
->drawable
);
341 swaps(&stuff
->width
);
342 swaps(&stuff
->height
);
343 swaps(&stuff
->stride
);
344 return (*proc_dri3_vector
[stuff
->dri3ReqType
]) (client
);
348 sproc_dri3_buffer_from_pixmap(ClientPtr client
)
350 REQUEST(xDRI3BufferFromPixmapReq
);
352 swaps(&stuff
->length
);
353 swapl(&stuff
->pixmap
);
354 return (*proc_dri3_vector
[stuff
->dri3ReqType
]) (client
);
358 sproc_dri3_fence_from_fd(ClientPtr client
)
360 REQUEST(xDRI3FenceFromFDReq
);
362 swaps(&stuff
->length
);
363 swapl(&stuff
->drawable
);
364 swapl(&stuff
->fence
);
365 return (*proc_dri3_vector
[stuff
->dri3ReqType
]) (client
);
369 sproc_dri3_fd_from_fence(ClientPtr client
)
371 REQUEST(xDRI3FDFromFenceReq
);
373 swaps(&stuff
->length
);
374 swapl(&stuff
->drawable
);
375 swapl(&stuff
->fence
);
376 return (*proc_dri3_vector
[stuff
->dri3ReqType
]) (client
);
379 int (*sproc_dri3_vector
[DRI3NumberRequests
]) (ClientPtr
) = {
380 sproc_dri3_query_version
, /* 0 */
381 sproc_dri3_open
, /* 1 */
382 sproc_dri3_pixmap_from_buffer
, /* 2 */
383 sproc_dri3_buffer_from_pixmap
, /* 3 */
384 sproc_dri3_fence_from_fd
, /* 4 */
385 sproc_dri3_fd_from_fence
, /* 5 */
389 sproc_dri3_dispatch(ClientPtr client
)
392 if (stuff
->data
>= DRI3NumberRequests
|| !sproc_dri3_vector
[stuff
->data
])
394 return (*sproc_dri3_vector
[stuff
->data
]) (client
);