1 /*
2 * Copyright © 2013 Keith Packard
3 *
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.
13 *
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
20 * OF THIS SOFTWARE.
21 */
22
23 #ifdef HAVE_XORG_CONFIG_H
24 #include <xorg-config.h>
25 #endif
26
27 #include "dri3_priv.h"
28 #include <syncsrv.h>
29 #include <unistd.h>
30 #include <xace.h>
31 #include "../Xext/syncsdk.h"
32 #include <protocol-versions.h>
33 #include <drm_fourcc.h>
34
35 static Bool
dri3_screen_can_one_point_two(ScreenPtr screen)36 dri3_screen_can_one_point_two(ScreenPtr screen)
37 {
38 dri3_screen_priv_ptr dri3 = dri3_screen_priv(screen);
39
40 if (dri3 && dri3->info && dri3->info->version >= 2 &&
41 dri3->info->pixmap_from_fds && dri3->info->fds_from_pixmap &&
42 dri3->info->get_formats && dri3->info->get_modifiers &&
43 dri3->info->get_drawable_modifiers)
44 return TRUE;
45
46 return FALSE;
47 }
48
49 static int
proc_dri3_query_version(ClientPtr client)50 proc_dri3_query_version(ClientPtr client)
51 {
52 REQUEST(xDRI3QueryVersionReq);
53 xDRI3QueryVersionReply rep = {
54 .type = X_Reply,
55 .sequenceNumber = client->sequence,
56 .length = 0,
57 .majorVersion = SERVER_DRI3_MAJOR_VERSION,
58 .minorVersion = SERVER_DRI3_MINOR_VERSION
59 };
60
61 REQUEST_SIZE_MATCH(xDRI3QueryVersionReq);
62
63 for (int i = 0; i < screenInfo.numScreens; i++) {
64 if (!dri3_screen_can_one_point_two(screenInfo.screens[i])) {
65 rep.minorVersion = 0;
66 break;
67 }
68 }
69
70 for (int i = 0; i < screenInfo.numGPUScreens; i++) {
71 if (!dri3_screen_can_one_point_two(screenInfo.gpuscreens[i])) {
72 rep.minorVersion = 0;
73 break;
74 }
75 }
76
77 /* From DRI3 proto:
78 *
79 * The client sends the highest supported version to the server
80 * and the server sends the highest version it supports, but no
81 * higher than the requested version.
82 */
83
84 if (rep.majorVersion > stuff->majorVersion ||
85 (rep.majorVersion == stuff->majorVersion &&
86 rep.minorVersion > stuff->minorVersion)) {
87 rep.majorVersion = stuff->majorVersion;
88 rep.minorVersion = stuff->minorVersion;
89 }
90
91 if (client->swapped) {
92 swaps(&rep.sequenceNumber);
93 swapl(&rep.length);
94 swapl(&rep.majorVersion);
95 swapl(&rep.minorVersion);
96 }
97 WriteToClient(client, sizeof(rep), &rep);
98 return Success;
99 }
100
101 int
dri3_send_open_reply(ClientPtr client,int fd)102 dri3_send_open_reply(ClientPtr client, int fd)
103 {
104 xDRI3OpenReply rep = {
105 .type = X_Reply,
106 .nfd = 1,
107 .sequenceNumber = client->sequence,
108 .length = 0,
109 };
110
111 if (client->swapped) {
112 swaps(&rep.sequenceNumber);
113 swapl(&rep.length);
114 }
115
116 if (WriteFdToClient(client, fd, TRUE) < 0) {
117 close(fd);
118 return BadAlloc;
119 }
120
121 WriteToClient(client, sizeof (rep), &rep);
122
123 return Success;
124 }
125
126 static int
proc_dri3_open(ClientPtr client)127 proc_dri3_open(ClientPtr client)
128 {
129 REQUEST(xDRI3OpenReq);
130 RRProviderPtr provider;
131 DrawablePtr drawable;
132 ScreenPtr screen;
133 int fd;
134 int status;
135
136 REQUEST_SIZE_MATCH(xDRI3OpenReq);
137
138 status = dixLookupDrawable(&drawable, stuff->drawable, client, 0, DixGetAttrAccess);
139 if (status != Success)
140 return status;
141
142 if (stuff->provider == None)
143 provider = NULL;
144 else if (!RRProviderType) {
145 return BadMatch;
146 } else {
147 VERIFY_RR_PROVIDER(stuff->provider, provider, DixReadAccess);
148 if (drawable->pScreen != provider->pScreen)
149 return BadMatch;
150 }
151 screen = drawable->pScreen;
152
153 status = dri3_open(client, screen, provider, &fd);
154 if (status != Success)
155 return status;
156
157 if (client->ignoreCount == 0)
158 return dri3_send_open_reply(client, fd);
159
160 return Success;
161 }
162
163 static int
proc_dri3_pixmap_from_buffer(ClientPtr client)164 proc_dri3_pixmap_from_buffer(ClientPtr client)
165 {
166 REQUEST(xDRI3PixmapFromBufferReq);
167 int fd;
168 DrawablePtr drawable;
169 PixmapPtr pixmap;
170 CARD32 stride, offset;
171 int rc;
172
173 SetReqFds(client, 1);
174 REQUEST_SIZE_MATCH(xDRI3PixmapFromBufferReq);
175 LEGAL_NEW_RESOURCE(stuff->pixmap, client);
176 rc = dixLookupDrawable(&drawable, stuff->drawable, client, M_ANY, DixGetAttrAccess);
177 if (rc != Success) {
178 client->errorValue = stuff->drawable;
179 return rc;
180 }
181
182 if (!stuff->width || !stuff->height) {
183 client->errorValue = 0;
184 return BadValue;
185 }
186
187 if (stuff->width > 32767 || stuff->height > 32767)
188 return BadAlloc;
189
190 if (stuff->depth != 1) {
191 DepthPtr depth = drawable->pScreen->allowedDepths;
192 int i;
193 for (i = 0; i < drawable->pScreen->numDepths; i++, depth++)
194 if (depth->depth == stuff->depth)
195 break;
196 if (i == drawable->pScreen->numDepths) {
197 client->errorValue = stuff->depth;
198 return BadValue;
199 }
200 }
201
202 fd = ReadFdFromClient(client);
203 if (fd < 0)
204 return BadValue;
205
206 offset = 0;
207 stride = stuff->stride;
208 rc = dri3_pixmap_from_fds(&pixmap,
209 drawable->pScreen, 1, &fd,
210 stuff->width, stuff->height,
211 &stride, &offset,
212 stuff->depth, stuff->bpp,
213 DRM_FORMAT_MOD_INVALID);
214 close (fd);
215 if (rc != Success)
216 return rc;
217
218 pixmap->drawable.id = stuff->pixmap;
219
220 /* security creation/labeling check */
221 rc = XaceHook(XACE_RESOURCE_ACCESS, client, stuff->pixmap, RT_PIXMAP,
222 pixmap, RT_NONE, NULL, DixCreateAccess);
223
224 if (rc != Success) {
225 (*drawable->pScreen->DestroyPixmap) (pixmap);
226 return rc;
227 }
228 if (!AddResource(stuff->pixmap, RT_PIXMAP, (void *) pixmap))
229 return BadAlloc;
230
231 return Success;
232 }
233
234 static int
proc_dri3_buffer_from_pixmap(ClientPtr client)235 proc_dri3_buffer_from_pixmap(ClientPtr client)
236 {
237 REQUEST(xDRI3BufferFromPixmapReq);
238 xDRI3BufferFromPixmapReply rep = {
239 .type = X_Reply,
240 .nfd = 1,
241 .sequenceNumber = client->sequence,
242 .length = 0,
243 };
244 int rc;
245 int fd;
246 PixmapPtr pixmap;
247
248 REQUEST_SIZE_MATCH(xDRI3BufferFromPixmapReq);
249 rc = dixLookupResourceByType((void **) &pixmap, stuff->pixmap, RT_PIXMAP,
250 client, DixWriteAccess);
251 if (rc != Success) {
252 client->errorValue = stuff->pixmap;
253 return rc;
254 }
255
256 rep.width = pixmap->drawable.width;
257 rep.height = pixmap->drawable.height;
258 rep.depth = pixmap->drawable.depth;
259 rep.bpp = pixmap->drawable.bitsPerPixel;
260
261 fd = dri3_fd_from_pixmap(pixmap, &rep.stride, &rep.size);
262 if (fd < 0)
263 return BadPixmap;
264
265 if (client->swapped) {
266 swaps(&rep.sequenceNumber);
267 swapl(&rep.length);
268 swapl(&rep.size);
269 swaps(&rep.width);
270 swaps(&rep.height);
271 swaps(&rep.stride);
272 }
273 if (WriteFdToClient(client, fd, TRUE) < 0) {
274 close(fd);
275 return BadAlloc;
276 }
277
278 WriteToClient(client, sizeof(rep), &rep);
279
280 return Success;
281 }
282
283 static int
proc_dri3_fence_from_fd(ClientPtr client)284 proc_dri3_fence_from_fd(ClientPtr client)
285 {
286 REQUEST(xDRI3FenceFromFDReq);
287 DrawablePtr drawable;
288 int fd;
289 int status;
290
291 SetReqFds(client, 1);
292 REQUEST_SIZE_MATCH(xDRI3FenceFromFDReq);
293 LEGAL_NEW_RESOURCE(stuff->fence, client);
294
295 status = dixLookupDrawable(&drawable, stuff->drawable, client, M_ANY, DixGetAttrAccess);
296 if (status != Success)
297 return status;
298
299 fd = ReadFdFromClient(client);
300 if (fd < 0)
301 return BadValue;
302
303 status = SyncCreateFenceFromFD(client, drawable, stuff->fence,
304 fd, stuff->initially_triggered);
305
306 return status;
307 }
308
309 static int
proc_dri3_fd_from_fence(ClientPtr client)310 proc_dri3_fd_from_fence(ClientPtr client)
311 {
312 REQUEST(xDRI3FDFromFenceReq);
313 xDRI3FDFromFenceReply rep = {
314 .type = X_Reply,
315 .nfd = 1,
316 .sequenceNumber = client->sequence,
317 .length = 0,
318 };
319 DrawablePtr drawable;
320 int fd;
321 int status;
322 SyncFence *fence;
323
324 REQUEST_SIZE_MATCH(xDRI3FDFromFenceReq);
325
326 status = dixLookupDrawable(&drawable, stuff->drawable, client, M_ANY, DixGetAttrAccess);
327 if (status != Success)
328 return status;
329 status = SyncVerifyFence(&fence, stuff->fence, client, DixWriteAccess);
330 if (status != Success)
331 return status;
332
333 fd = SyncFDFromFence(client, drawable, fence);
334 if (fd < 0)
335 return BadMatch;
336
337 if (client->swapped) {
338 swaps(&rep.sequenceNumber);
339 swapl(&rep.length);
340 }
341 if (WriteFdToClient(client, fd, FALSE) < 0)
342 return BadAlloc;
343
344 WriteToClient(client, sizeof(rep), &rep);
345
346 return Success;
347 }
348
349 static int
proc_dri3_get_supported_modifiers(ClientPtr client)350 proc_dri3_get_supported_modifiers(ClientPtr client)
351 {
352 REQUEST(xDRI3GetSupportedModifiersReq);
353 xDRI3GetSupportedModifiersReply rep = {
354 .type = X_Reply,
355 .sequenceNumber = client->sequence,
356 };
357 WindowPtr window;
358 ScreenPtr pScreen;
359 CARD64 *window_modifiers = NULL;
360 CARD64 *screen_modifiers = NULL;
361 CARD32 nwindowmodifiers = 0;
362 CARD32 nscreenmodifiers = 0;
363 int status;
364 int i;
365
366 REQUEST_SIZE_MATCH(xDRI3GetSupportedModifiersReq);
367
368 status = dixLookupWindow(&window, stuff->window, client, DixGetAttrAccess);
369 if (status != Success)
370 return status;
371 pScreen = window->drawable.pScreen;
372
373 dri3_get_supported_modifiers(pScreen, &window->drawable,
374 stuff->depth, stuff->bpp,
375 &nwindowmodifiers, &window_modifiers,
376 &nscreenmodifiers, &screen_modifiers);
377
378 rep.numWindowModifiers = nwindowmodifiers;
379 rep.numScreenModifiers = nscreenmodifiers;
380 rep.length = bytes_to_int32(rep.numWindowModifiers * sizeof(CARD64)) +
381 bytes_to_int32(rep.numScreenModifiers * sizeof(CARD64));
382
383 if (client->swapped) {
384 swaps(&rep.sequenceNumber);
385 swapl(&rep.length);
386 swapl(&rep.numWindowModifiers);
387 swapl(&rep.numScreenModifiers);
388 for (i = 0; i < nwindowmodifiers; i++)
389 swapll(&window_modifiers[i]);
390 for (i = 0; i < nscreenmodifiers; i++)
391 swapll(&screen_modifiers[i]);
392 }
393
394 WriteToClient(client, sizeof(rep), &rep);
395 WriteToClient(client, nwindowmodifiers * sizeof(CARD64), window_modifiers);
396 WriteToClient(client, nscreenmodifiers * sizeof(CARD64), screen_modifiers);
397
398 free(window_modifiers);
399 free(screen_modifiers);
400
401 return Success;
402 }
403
404 static int
proc_dri3_pixmap_from_buffers(ClientPtr client)405 proc_dri3_pixmap_from_buffers(ClientPtr client)
406 {
407 REQUEST(xDRI3PixmapFromBuffersReq);
408 int fds[4];
409 CARD32 strides[4], offsets[4];
410 ScreenPtr screen;
411 WindowPtr window;
412 PixmapPtr pixmap;
413 int rc;
414 int i;
415
416 SetReqFds(client, stuff->num_buffers);
417 REQUEST_SIZE_MATCH(xDRI3PixmapFromBuffersReq);
418 LEGAL_NEW_RESOURCE(stuff->pixmap, client);
419 rc = dixLookupWindow(&window, stuff->window, client, DixGetAttrAccess);
420 if (rc != Success) {
421 client->errorValue = stuff->window;
422 return rc;
423 }
424 screen = window->drawable.pScreen;
425
426 if (!stuff->width || !stuff->height || !stuff->bpp || !stuff->depth) {
427 client->errorValue = 0;
428 return BadValue;
429 }
430
431 if (stuff->width > 32767 || stuff->height > 32767)
432 return BadAlloc;
433
434 if (stuff->depth != 1) {
435 DepthPtr depth = screen->allowedDepths;
436 int j;
437 for (j = 0; j < screen->numDepths; j++, depth++)
438 if (depth->depth == stuff->depth)
439 break;
440 if (j == screen->numDepths) {
441 client->errorValue = stuff->depth;
442 return BadValue;
443 }
444 }
445
446 if (!stuff->num_buffers || stuff->num_buffers > 4) {
447 client->errorValue = stuff->num_buffers;
448 return BadValue;
449 }
450
451 for (i = 0; i < stuff->num_buffers; i++) {
452 fds[i] = ReadFdFromClient(client);
453 if (fds[i] < 0) {
454 while (--i >= 0)
455 close(fds[i]);
456 return BadValue;
457 }
458 }
459
460 strides[0] = stuff->stride0;
461 strides[1] = stuff->stride1;
462 strides[2] = stuff->stride2;
463 strides[3] = stuff->stride3;
464 offsets[0] = stuff->offset0;
465 offsets[1] = stuff->offset1;
466 offsets[2] = stuff->offset2;
467 offsets[3] = stuff->offset3;
468
469 rc = dri3_pixmap_from_fds(&pixmap, screen,
470 stuff->num_buffers, fds,
471 stuff->width, stuff->height,
472 strides, offsets,
473 stuff->depth, stuff->bpp,
474 stuff->modifier);
475
476 for (i = 0; i < stuff->num_buffers; i++)
477 close (fds[i]);
478
479 if (rc != Success)
480 return rc;
481
482 pixmap->drawable.id = stuff->pixmap;
483
484 /* security creation/labeling check */
485 rc = XaceHook(XACE_RESOURCE_ACCESS, client, stuff->pixmap, RT_PIXMAP,
486 pixmap, RT_NONE, NULL, DixCreateAccess);
487
488 if (rc != Success) {
489 (*screen->DestroyPixmap) (pixmap);
490 return rc;
491 }
492 if (!AddResource(stuff->pixmap, RT_PIXMAP, (void *) pixmap))
493 return BadAlloc;
494
495 return Success;
496 }
497
498 static int
proc_dri3_buffers_from_pixmap(ClientPtr client)499 proc_dri3_buffers_from_pixmap(ClientPtr client)
500 {
501 REQUEST(xDRI3BuffersFromPixmapReq);
502 xDRI3BuffersFromPixmapReply rep = {
503 .type = X_Reply,
504 .sequenceNumber = client->sequence,
505 };
506 int rc;
507 int fds[4];
508 int num_fds;
509 uint32_t strides[4], offsets[4];
510 uint64_t modifier;
511 int i;
512 PixmapPtr pixmap;
513
514 REQUEST_SIZE_MATCH(xDRI3BuffersFromPixmapReq);
515 rc = dixLookupResourceByType((void **) &pixmap, stuff->pixmap, RT_PIXMAP,
516 client, DixWriteAccess);
517 if (rc != Success) {
518 client->errorValue = stuff->pixmap;
519 return rc;
520 }
521
522 num_fds = dri3_fds_from_pixmap(pixmap, fds, strides, offsets, &modifier);
523 if (num_fds == 0)
524 return BadPixmap;
525
526 rep.nfd = num_fds;
527 rep.length = bytes_to_int32(num_fds * 2 * sizeof(CARD32));
528 rep.width = pixmap->drawable.width;
529 rep.height = pixmap->drawable.height;
530 rep.depth = pixmap->drawable.depth;
531 rep.bpp = pixmap->drawable.bitsPerPixel;
532 rep.modifier = modifier;
533
534 if (client->swapped) {
535 swaps(&rep.sequenceNumber);
536 swapl(&rep.length);
537 swaps(&rep.width);
538 swaps(&rep.height);
539 swapll(&rep.modifier);
540 for (i = 0; i < num_fds; i++) {
541 swapl(&strides[i]);
542 swapl(&offsets[i]);
543 }
544 }
545
546 for (i = 0; i < num_fds; i++) {
547 if (WriteFdToClient(client, fds[i], TRUE) < 0) {
548 while (i--)
549 close(fds[i]);
550 return BadAlloc;
551 }
552 }
553
554 WriteToClient(client, sizeof(rep), &rep);
555 WriteToClient(client, num_fds * sizeof(CARD32), strides);
556 WriteToClient(client, num_fds * sizeof(CARD32), offsets);
557
558 return Success;
559 }
560
561 int (*proc_dri3_vector[DRI3NumberRequests]) (ClientPtr) = {
562 proc_dri3_query_version, /* 0 */
563 proc_dri3_open, /* 1 */
564 proc_dri3_pixmap_from_buffer, /* 2 */
565 proc_dri3_buffer_from_pixmap, /* 3 */
566 proc_dri3_fence_from_fd, /* 4 */
567 proc_dri3_fd_from_fence, /* 5 */
568 proc_dri3_get_supported_modifiers, /* 6 */
569 proc_dri3_pixmap_from_buffers, /* 7 */
570 proc_dri3_buffers_from_pixmap, /* 8 */
571 };
572
573 int
proc_dri3_dispatch(ClientPtr client)574 proc_dri3_dispatch(ClientPtr client)
575 {
576 REQUEST(xReq);
577 if (!client->local)
578 return BadMatch;
579 if (stuff->data >= DRI3NumberRequests || !proc_dri3_vector[stuff->data])
580 return BadRequest;
581 return (*proc_dri3_vector[stuff->data]) (client);
582 }
583
584 static int _X_COLD
sproc_dri3_query_version(ClientPtr client)585 sproc_dri3_query_version(ClientPtr client)
586 {
587 REQUEST(xDRI3QueryVersionReq);
588 REQUEST_SIZE_MATCH(xDRI3QueryVersionReq);
589
590 swaps(&stuff->length);
591 swapl(&stuff->majorVersion);
592 swapl(&stuff->minorVersion);
593 return (*proc_dri3_vector[stuff->dri3ReqType]) (client);
594 }
595
596 static int _X_COLD
sproc_dri3_open(ClientPtr client)597 sproc_dri3_open(ClientPtr client)
598 {
599 REQUEST(xDRI3OpenReq);
600 REQUEST_SIZE_MATCH(xDRI3OpenReq);
601
602 swaps(&stuff->length);
603 swapl(&stuff->drawable);
604 swapl(&stuff->provider);
605 return (*proc_dri3_vector[stuff->dri3ReqType]) (client);
606 }
607
608 static int _X_COLD
sproc_dri3_pixmap_from_buffer(ClientPtr client)609 sproc_dri3_pixmap_from_buffer(ClientPtr client)
610 {
611 REQUEST(xDRI3PixmapFromBufferReq);
612 REQUEST_SIZE_MATCH(xDRI3PixmapFromBufferReq);
613
614 swaps(&stuff->length);
615 swapl(&stuff->pixmap);
616 swapl(&stuff->drawable);
617 swapl(&stuff->size);
618 swaps(&stuff->width);
619 swaps(&stuff->height);
620 swaps(&stuff->stride);
621 return (*proc_dri3_vector[stuff->dri3ReqType]) (client);
622 }
623
624 static int _X_COLD
sproc_dri3_buffer_from_pixmap(ClientPtr client)625 sproc_dri3_buffer_from_pixmap(ClientPtr client)
626 {
627 REQUEST(xDRI3BufferFromPixmapReq);
628 REQUEST_SIZE_MATCH(xDRI3BufferFromPixmapReq);
629
630 swaps(&stuff->length);
631 swapl(&stuff->pixmap);
632 return (*proc_dri3_vector[stuff->dri3ReqType]) (client);
633 }
634
635 static int _X_COLD
sproc_dri3_fence_from_fd(ClientPtr client)636 sproc_dri3_fence_from_fd(ClientPtr client)
637 {
638 REQUEST(xDRI3FenceFromFDReq);
639 REQUEST_SIZE_MATCH(xDRI3FenceFromFDReq);
640
641 swaps(&stuff->length);
642 swapl(&stuff->drawable);
643 swapl(&stuff->fence);
644 return (*proc_dri3_vector[stuff->dri3ReqType]) (client);
645 }
646
647 static int _X_COLD
sproc_dri3_fd_from_fence(ClientPtr client)648 sproc_dri3_fd_from_fence(ClientPtr client)
649 {
650 REQUEST(xDRI3FDFromFenceReq);
651 REQUEST_SIZE_MATCH(xDRI3FDFromFenceReq);
652
653 swaps(&stuff->length);
654 swapl(&stuff->drawable);
655 swapl(&stuff->fence);
656 return (*proc_dri3_vector[stuff->dri3ReqType]) (client);
657 }
658
659 static int _X_COLD
sproc_dri3_get_supported_modifiers(ClientPtr client)660 sproc_dri3_get_supported_modifiers(ClientPtr client)
661 {
662 REQUEST(xDRI3GetSupportedModifiersReq);
663 REQUEST_SIZE_MATCH(xDRI3GetSupportedModifiersReq);
664
665 swaps(&stuff->length);
666 swapl(&stuff->window);
667 return (*proc_dri3_vector[stuff->dri3ReqType]) (client);
668 }
669
670 static int _X_COLD
sproc_dri3_pixmap_from_buffers(ClientPtr client)671 sproc_dri3_pixmap_from_buffers(ClientPtr client)
672 {
673 REQUEST(xDRI3PixmapFromBuffersReq);
674 REQUEST_SIZE_MATCH(xDRI3PixmapFromBuffersReq);
675
676 swaps(&stuff->length);
677 swapl(&stuff->pixmap);
678 swapl(&stuff->window);
679 swaps(&stuff->width);
680 swaps(&stuff->height);
681 swapl(&stuff->stride0);
682 swapl(&stuff->offset0);
683 swapl(&stuff->stride1);
684 swapl(&stuff->offset1);
685 swapl(&stuff->stride2);
686 swapl(&stuff->offset2);
687 swapl(&stuff->stride3);
688 swapl(&stuff->offset3);
689 swapll(&stuff->modifier);
690 return (*proc_dri3_vector[stuff->dri3ReqType]) (client);
691 }
692
693 static int _X_COLD
sproc_dri3_buffers_from_pixmap(ClientPtr client)694 sproc_dri3_buffers_from_pixmap(ClientPtr client)
695 {
696 REQUEST(xDRI3BuffersFromPixmapReq);
697 REQUEST_SIZE_MATCH(xDRI3BuffersFromPixmapReq);
698
699 swaps(&stuff->length);
700 swapl(&stuff->pixmap);
701 return (*proc_dri3_vector[stuff->dri3ReqType]) (client);
702 }
703
704 int (*sproc_dri3_vector[DRI3NumberRequests]) (ClientPtr) = {
705 sproc_dri3_query_version, /* 0 */
706 sproc_dri3_open, /* 1 */
707 sproc_dri3_pixmap_from_buffer, /* 2 */
708 sproc_dri3_buffer_from_pixmap, /* 3 */
709 sproc_dri3_fence_from_fd, /* 4 */
710 sproc_dri3_fd_from_fence, /* 5 */
711 sproc_dri3_get_supported_modifiers, /* 6 */
712 sproc_dri3_pixmap_from_buffers, /* 7 */
713 sproc_dri3_buffers_from_pixmap, /* 8 */
714 };
715
716 int _X_COLD
sproc_dri3_dispatch(ClientPtr client)717 sproc_dri3_dispatch(ClientPtr client)
718 {
719 REQUEST(xReq);
720 if (!client->local)
721 return BadMatch;
722 if (stuff->data >= DRI3NumberRequests || !sproc_dri3_vector[stuff->data])
723 return BadRequest;
724 return (*sproc_dri3_vector[stuff->data]) (client);
725 }
726