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