Imported Upstream version 1.15.1
[deb_xorg-server.git] / Xext / xvdisp.c
1 /***********************************************************
2 Copyright 1991 by Digital Equipment Corporation, Maynard, Massachusetts,
3 and the Massachusetts Institute of Technology, Cambridge, Massachusetts.
4
5 All Rights Reserved
6
7 Permission to use, copy, modify, and distribute this software and its
8 documentation for any purpose and without fee is hereby granted,
9 provided that the above copyright notice appear in all copies and that
10 both that copyright notice and this permission notice appear in
11 supporting documentation, and that the names of Digital or MIT not be
12 used in advertising or publicity pertaining to distribution of the
13 software without specific, written prior permission.
14
15 DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
16 ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
17 DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
18 ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
19 WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
20 ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
21 SOFTWARE.
22 ******************************************************************/
23
24 #ifdef HAVE_DIX_CONFIG_H
25 #include <dix-config.h>
26 #endif
27
28 #include <string.h>
29
30 #include <X11/X.h>
31 #include <X11/Xproto.h>
32 #include "misc.h"
33 #include "scrnintstr.h"
34 #include "windowstr.h"
35 #include "pixmapstr.h"
36 #include "gcstruct.h"
37 #include "dixstruct.h"
38 #include "resource.h"
39 #include "opaque.h"
40
41 #include <X11/extensions/Xv.h>
42 #include <X11/extensions/Xvproto.h>
43 #include "xvdix.h"
44 #ifdef MITSHM
45 #include <X11/extensions/shmproto.h>
46 #include "shmint.h"
47 #endif
48
49 #include "xvdisp.h"
50
51 #ifdef PANORAMIX
52 #include "panoramiX.h"
53 #include "panoramiXsrv.h"
54
55 unsigned long XvXRTPort;
56 #endif
57
58 static int
59 SWriteQueryExtensionReply(ClientPtr client, xvQueryExtensionReply * rep)
60 {
61 swaps(&rep->sequenceNumber);
62 swapl(&rep->length);
63 swaps(&rep->version);
64 swaps(&rep->revision);
65
66 WriteToClient(client, sz_xvQueryExtensionReply, rep);
67
68 return Success;
69 }
70
71 static int
72 SWriteQueryAdaptorsReply(ClientPtr client, xvQueryAdaptorsReply * rep)
73 {
74 swaps(&rep->sequenceNumber);
75 swapl(&rep->length);
76 swaps(&rep->num_adaptors);
77
78 WriteToClient(client, sz_xvQueryAdaptorsReply, rep);
79
80 return Success;
81 }
82
83 static int
84 SWriteQueryEncodingsReply(ClientPtr client, xvQueryEncodingsReply * rep)
85 {
86 swaps(&rep->sequenceNumber);
87 swapl(&rep->length);
88 swaps(&rep->num_encodings);
89
90 WriteToClient(client, sz_xvQueryEncodingsReply, rep);
91
92 return Success;
93 }
94
95 static int
96 SWriteAdaptorInfo(ClientPtr client, xvAdaptorInfo * pAdaptor)
97 {
98 swapl(&pAdaptor->base_id);
99 swaps(&pAdaptor->name_size);
100 swaps(&pAdaptor->num_ports);
101 swaps(&pAdaptor->num_formats);
102
103 WriteToClient(client, sz_xvAdaptorInfo, pAdaptor);
104
105 return Success;
106 }
107
108 static int
109 SWriteEncodingInfo(ClientPtr client, xvEncodingInfo * pEncoding)
110 {
111
112 swapl(&pEncoding->encoding);
113 swaps(&pEncoding->name_size);
114 swaps(&pEncoding->width);
115 swaps(&pEncoding->height);
116 swapl(&pEncoding->rate.numerator);
117 swapl(&pEncoding->rate.denominator);
118 WriteToClient(client, sz_xvEncodingInfo, pEncoding);
119
120 return Success;
121 }
122
123 static int
124 SWriteFormat(ClientPtr client, xvFormat * pFormat)
125 {
126 swapl(&pFormat->visual);
127 WriteToClient(client, sz_xvFormat, pFormat);
128
129 return Success;
130 }
131
132 static int
133 SWriteAttributeInfo(ClientPtr client, xvAttributeInfo * pAtt)
134 {
135 swapl(&pAtt->flags);
136 swapl(&pAtt->size);
137 swapl(&pAtt->min);
138 swapl(&pAtt->max);
139 WriteToClient(client, sz_xvAttributeInfo, pAtt);
140
141 return Success;
142 }
143
144 static int
145 SWriteImageFormatInfo(ClientPtr client, xvImageFormatInfo * pImage)
146 {
147 swapl(&pImage->id);
148 swapl(&pImage->red_mask);
149 swapl(&pImage->green_mask);
150 swapl(&pImage->blue_mask);
151 swapl(&pImage->y_sample_bits);
152 swapl(&pImage->u_sample_bits);
153 swapl(&pImage->v_sample_bits);
154 swapl(&pImage->horz_y_period);
155 swapl(&pImage->horz_u_period);
156 swapl(&pImage->horz_v_period);
157 swapl(&pImage->vert_y_period);
158 swapl(&pImage->vert_u_period);
159 swapl(&pImage->vert_v_period);
160
161 WriteToClient(client, sz_xvImageFormatInfo, pImage);
162
163 return Success;
164 }
165
166 static int
167 SWriteGrabPortReply(ClientPtr client, xvGrabPortReply * rep)
168 {
169 swaps(&rep->sequenceNumber);
170 swapl(&rep->length);
171
172 WriteToClient(client, sz_xvGrabPortReply, rep);
173
174 return Success;
175 }
176
177 static int
178 SWriteGetPortAttributeReply(ClientPtr client, xvGetPortAttributeReply * rep)
179 {
180 swaps(&rep->sequenceNumber);
181 swapl(&rep->length);
182 swapl(&rep->value);
183
184 WriteToClient(client, sz_xvGetPortAttributeReply, rep);
185
186 return Success;
187 }
188
189 static int
190 SWriteQueryBestSizeReply(ClientPtr client, xvQueryBestSizeReply * rep)
191 {
192 swaps(&rep->sequenceNumber);
193 swapl(&rep->length);
194 swaps(&rep->actual_width);
195 swaps(&rep->actual_height);
196
197 WriteToClient(client, sz_xvQueryBestSizeReply, rep);
198
199 return Success;
200 }
201
202 static int
203 SWriteQueryPortAttributesReply(ClientPtr client,
204 xvQueryPortAttributesReply * rep)
205 {
206 swaps(&rep->sequenceNumber);
207 swapl(&rep->length);
208 swapl(&rep->num_attributes);
209 swapl(&rep->text_size);
210
211 WriteToClient(client, sz_xvQueryPortAttributesReply, rep);
212
213 return Success;
214 }
215
216 static int
217 SWriteQueryImageAttributesReply(ClientPtr client,
218 xvQueryImageAttributesReply * rep)
219 {
220 swaps(&rep->sequenceNumber);
221 swapl(&rep->length);
222 swapl(&rep->num_planes);
223 swapl(&rep->data_size);
224 swaps(&rep->width);
225 swaps(&rep->height);
226
227 WriteToClient(client, sz_xvQueryImageAttributesReply, rep);
228
229 return Success;
230 }
231
232 static int
233 SWriteListImageFormatsReply(ClientPtr client, xvListImageFormatsReply * rep)
234 {
235 swaps(&rep->sequenceNumber);
236 swapl(&rep->length);
237 swapl(&rep->num_formats);
238
239 WriteToClient(client, sz_xvListImageFormatsReply, rep);
240
241 return Success;
242 }
243
244 #define _WriteQueryAdaptorsReply(_c,_d) \
245 if ((_c)->swapped) SWriteQueryAdaptorsReply(_c, _d); \
246 else WriteToClient(_c, sz_xvQueryAdaptorsReply, _d)
247
248 #define _WriteQueryExtensionReply(_c,_d) \
249 if ((_c)->swapped) SWriteQueryExtensionReply(_c, _d); \
250 else WriteToClient(_c, sz_xvQueryExtensionReply, _d)
251
252 #define _WriteQueryEncodingsReply(_c,_d) \
253 if ((_c)->swapped) SWriteQueryEncodingsReply(_c, _d); \
254 else WriteToClient(_c, sz_xvQueryEncodingsReply, _d)
255
256 #define _WriteAdaptorInfo(_c,_d) \
257 if ((_c)->swapped) SWriteAdaptorInfo(_c, _d); \
258 else WriteToClient(_c, sz_xvAdaptorInfo, _d)
259
260 #define _WriteAttributeInfo(_c,_d) \
261 if ((_c)->swapped) SWriteAttributeInfo(_c, _d); \
262 else WriteToClient(_c, sz_xvAttributeInfo, _d)
263
264 #define _WriteEncodingInfo(_c,_d) \
265 if ((_c)->swapped) SWriteEncodingInfo(_c, _d); \
266 else WriteToClient(_c, sz_xvEncodingInfo, _d)
267
268 #define _WriteFormat(_c,_d) \
269 if ((_c)->swapped) SWriteFormat(_c, _d); \
270 else WriteToClient(_c, sz_xvFormat, _d)
271
272 #define _WriteGrabPortReply(_c,_d) \
273 if ((_c)->swapped) SWriteGrabPortReply(_c, _d); \
274 else WriteToClient(_c, sz_xvGrabPortReply, _d)
275
276 #define _WriteGetPortAttributeReply(_c,_d) \
277 if ((_c)->swapped) SWriteGetPortAttributeReply(_c, _d); \
278 else WriteToClient(_c, sz_xvGetPortAttributeReply, _d)
279
280 #define _WriteQueryBestSizeReply(_c,_d) \
281 if ((_c)->swapped) SWriteQueryBestSizeReply(_c, _d); \
282 else WriteToClient(_c, sz_xvQueryBestSizeReply, _d)
283
284 #define _WriteQueryPortAttributesReply(_c,_d) \
285 if ((_c)->swapped) SWriteQueryPortAttributesReply(_c, _d); \
286 else WriteToClient(_c, sz_xvQueryPortAttributesReply, _d)
287
288 #define _WriteQueryImageAttributesReply(_c,_d) \
289 if ((_c)->swapped) SWriteQueryImageAttributesReply(_c, _d); \
290 else WriteToClient(_c, sz_xvQueryImageAttributesReply, _d)
291
292 #define _WriteListImageFormatsReply(_c,_d) \
293 if ((_c)->swapped) SWriteListImageFormatsReply(_c, _d); \
294 else WriteToClient(_c, sz_xvListImageFormatsReply, _d)
295
296 #define _WriteImageFormatInfo(_c,_d) \
297 if ((_c)->swapped) SWriteImageFormatInfo(_c, _d); \
298 else WriteToClient(_c, sz_xvImageFormatInfo, _d)
299
300 #define _AllocatePort(_i,_p) \
301 ((_p)->id != _i) ? (* (_p)->pAdaptor->ddAllocatePort)(_i,_p,&_p) : Success
302
303 static int
304 ProcXvQueryExtension(ClientPtr client)
305 {
306 xvQueryExtensionReply rep = {
307 .type = X_Reply,
308 .sequenceNumber = client->sequence,
309 .length = 0,
310 .version = XvVersion,
311 .revision = XvRevision
312 };
313
314 /* REQUEST(xvQueryExtensionReq); */
315 REQUEST_SIZE_MATCH(xvQueryExtensionReq);
316
317 _WriteQueryExtensionReply(client, &rep);
318
319 return Success;
320 }
321
322 static int
323 ProcXvQueryAdaptors(ClientPtr client)
324 {
325 xvFormat format;
326 xvAdaptorInfo ainfo;
327 xvQueryAdaptorsReply rep;
328 int totalSize, na, nf, rc;
329 int nameSize;
330 XvAdaptorPtr pa;
331 XvFormatPtr pf;
332 WindowPtr pWin;
333 ScreenPtr pScreen;
334 XvScreenPtr pxvs;
335
336 REQUEST(xvQueryAdaptorsReq);
337 REQUEST_SIZE_MATCH(xvQueryAdaptorsReq);
338
339 rc = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess);
340 if (rc != Success)
341 return rc;
342
343 pScreen = pWin->drawable.pScreen;
344 pxvs = (XvScreenPtr) dixLookupPrivate(&pScreen->devPrivates,
345 XvGetScreenKey());
346 if (!pxvs) {
347 rep = (xvQueryAdaptorsReply) {
348 .type = X_Reply,
349 .sequenceNumber = client->sequence,
350 .length = 0,
351 .num_adaptors = 0
352 };
353
354 _WriteQueryAdaptorsReply(client, &rep);
355
356 return Success;
357 }
358
359 (*pxvs->ddQueryAdaptors) (pScreen, &pxvs->pAdaptors, &pxvs->nAdaptors);
360
361 rep = (xvQueryAdaptorsReply) {
362 .type = X_Reply,
363 .sequenceNumber = client->sequence,
364 .num_adaptors = pxvs->nAdaptors
365 };
366
367 /* CALCULATE THE TOTAL SIZE OF THE REPLY IN BYTES */
368
369 totalSize = pxvs->nAdaptors * sz_xvAdaptorInfo;
370
371 /* FOR EACH ADPATOR ADD UP THE BYTES FOR ENCODINGS AND FORMATS */
372
373 na = pxvs->nAdaptors;
374 pa = pxvs->pAdaptors;
375 while (na--) {
376 totalSize += pad_to_int32(strlen(pa->name));
377 totalSize += pa->nFormats * sz_xvFormat;
378 pa++;
379 }
380
381 rep.length = bytes_to_int32(totalSize);
382
383 _WriteQueryAdaptorsReply(client, &rep);
384
385 na = pxvs->nAdaptors;
386 pa = pxvs->pAdaptors;
387 while (na--) {
388
389 ainfo.base_id = pa->base_id;
390 ainfo.num_ports = pa->nPorts;
391 ainfo.type = pa->type;
392 ainfo.name_size = nameSize = strlen(pa->name);
393 ainfo.num_formats = pa->nFormats;
394
395 _WriteAdaptorInfo(client, &ainfo);
396
397 WriteToClient(client, nameSize, pa->name);
398
399 nf = pa->nFormats;
400 pf = pa->pFormats;
401 while (nf--) {
402 format.depth = pf->depth;
403 format.visual = pf->visual;
404 _WriteFormat(client, &format);
405 pf++;
406 }
407
408 pa++;
409
410 }
411
412 return Success;
413 }
414
415 static int
416 ProcXvQueryEncodings(ClientPtr client)
417 {
418 xvEncodingInfo einfo;
419 xvQueryEncodingsReply rep;
420 int totalSize;
421 int nameSize;
422 XvPortPtr pPort;
423 int ne;
424 XvEncodingPtr pe;
425 int status;
426
427 REQUEST(xvQueryEncodingsReq);
428 REQUEST_SIZE_MATCH(xvQueryEncodingsReq);
429
430 VALIDATE_XV_PORT(stuff->port, pPort, DixReadAccess);
431
432 if ((status = _AllocatePort(stuff->port, pPort)) != Success) {
433 client->errorValue = stuff->port;
434 return status;
435 }
436
437 rep = (xvQueryEncodingsReply) {
438 .type = X_Reply,
439 .sequenceNumber = client->sequence,
440 .num_encodings = pPort->pAdaptor->nEncodings
441 };
442
443 /* FOR EACH ENCODING ADD UP THE BYTES FOR ENCODING NAMES */
444
445 ne = pPort->pAdaptor->nEncodings;
446 pe = pPort->pAdaptor->pEncodings;
447 totalSize = ne * sz_xvEncodingInfo;
448 while (ne--) {
449 totalSize += pad_to_int32(strlen(pe->name));
450 pe++;
451 }
452
453 rep.length = bytes_to_int32(totalSize);
454
455 _WriteQueryEncodingsReply(client, &rep);
456
457 ne = pPort->pAdaptor->nEncodings;
458 pe = pPort->pAdaptor->pEncodings;
459 while (ne--) {
460 einfo.encoding = pe->id;
461 einfo.name_size = nameSize = strlen(pe->name);
462 einfo.width = pe->width;
463 einfo.height = pe->height;
464 einfo.rate.numerator = pe->rate.numerator;
465 einfo.rate.denominator = pe->rate.denominator;
466 _WriteEncodingInfo(client, &einfo);
467 WriteToClient(client, nameSize, pe->name);
468 pe++;
469 }
470
471 return Success;
472 }
473
474 static int
475 ProcXvPutVideo(ClientPtr client)
476 {
477 DrawablePtr pDraw;
478 XvPortPtr pPort;
479 GCPtr pGC;
480 int status;
481
482 REQUEST(xvPutVideoReq);
483 REQUEST_SIZE_MATCH(xvPutVideoReq);
484
485 VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess);
486 VALIDATE_XV_PORT(stuff->port, pPort, DixReadAccess);
487
488 if ((status = _AllocatePort(stuff->port, pPort)) != Success) {
489 client->errorValue = stuff->port;
490 return status;
491 }
492
493 if (!(pPort->pAdaptor->type & XvInputMask) ||
494 !(pPort->pAdaptor->type & XvVideoMask)) {
495 client->errorValue = stuff->port;
496 return BadMatch;
497 }
498
499 status = XvdiMatchPort(pPort, pDraw);
500 if (status != Success) {
501 return status;
502 }
503
504 return XvdiPutVideo(client, pDraw, pPort, pGC, stuff->vid_x, stuff->vid_y,
505 stuff->vid_w, stuff->vid_h, stuff->drw_x, stuff->drw_y,
506 stuff->drw_w, stuff->drw_h);
507 }
508
509 static int
510 ProcXvPutStill(ClientPtr client)
511 {
512 DrawablePtr pDraw;
513 XvPortPtr pPort;
514 GCPtr pGC;
515 int status;
516
517 REQUEST(xvPutStillReq);
518 REQUEST_SIZE_MATCH(xvPutStillReq);
519
520 VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess);
521 VALIDATE_XV_PORT(stuff->port, pPort, DixReadAccess);
522
523 if ((status = _AllocatePort(stuff->port, pPort)) != Success) {
524 client->errorValue = stuff->port;
525 return status;
526 }
527
528 if (!(pPort->pAdaptor->type & XvInputMask) ||
529 !(pPort->pAdaptor->type & XvStillMask)) {
530 client->errorValue = stuff->port;
531 return BadMatch;
532 }
533
534 status = XvdiMatchPort(pPort, pDraw);
535 if (status != Success) {
536 return status;
537 }
538
539 return XvdiPutStill(client, pDraw, pPort, pGC, stuff->vid_x, stuff->vid_y,
540 stuff->vid_w, stuff->vid_h, stuff->drw_x, stuff->drw_y,
541 stuff->drw_w, stuff->drw_h);
542 }
543
544 static int
545 ProcXvGetVideo(ClientPtr client)
546 {
547 DrawablePtr pDraw;
548 XvPortPtr pPort;
549 GCPtr pGC;
550 int status;
551
552 REQUEST(xvGetVideoReq);
553 REQUEST_SIZE_MATCH(xvGetVideoReq);
554
555 VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixReadAccess);
556 VALIDATE_XV_PORT(stuff->port, pPort, DixReadAccess);
557
558 if ((status = _AllocatePort(stuff->port, pPort)) != Success) {
559 client->errorValue = stuff->port;
560 return status;
561 }
562
563 if (!(pPort->pAdaptor->type & XvOutputMask) ||
564 !(pPort->pAdaptor->type & XvVideoMask)) {
565 client->errorValue = stuff->port;
566 return BadMatch;
567 }
568
569 status = XvdiMatchPort(pPort, pDraw);
570 if (status != Success) {
571 return status;
572 }
573
574 return XvdiGetVideo(client, pDraw, pPort, pGC, stuff->vid_x, stuff->vid_y,
575 stuff->vid_w, stuff->vid_h, stuff->drw_x, stuff->drw_y,
576 stuff->drw_w, stuff->drw_h);
577 }
578
579 static int
580 ProcXvGetStill(ClientPtr client)
581 {
582 DrawablePtr pDraw;
583 XvPortPtr pPort;
584 GCPtr pGC;
585 int status;
586
587 REQUEST(xvGetStillReq);
588 REQUEST_SIZE_MATCH(xvGetStillReq);
589
590 VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixReadAccess);
591 VALIDATE_XV_PORT(stuff->port, pPort, DixReadAccess);
592
593 if ((status = _AllocatePort(stuff->port, pPort)) != Success) {
594 client->errorValue = stuff->port;
595 return status;
596 }
597
598 if (!(pPort->pAdaptor->type & XvOutputMask) ||
599 !(pPort->pAdaptor->type & XvStillMask)) {
600 client->errorValue = stuff->port;
601 return BadMatch;
602 }
603
604 status = XvdiMatchPort(pPort, pDraw);
605 if (status != Success) {
606 return status;
607 }
608
609 return XvdiGetStill(client, pDraw, pPort, pGC, stuff->vid_x, stuff->vid_y,
610 stuff->vid_w, stuff->vid_h, stuff->drw_x, stuff->drw_y,
611 stuff->drw_w, stuff->drw_h);
612 }
613
614 static int
615 ProcXvSelectVideoNotify(ClientPtr client)
616 {
617 DrawablePtr pDraw;
618 int rc;
619
620 REQUEST(xvSelectVideoNotifyReq);
621 REQUEST_SIZE_MATCH(xvSelectVideoNotifyReq);
622
623 rc = dixLookupDrawable(&pDraw, stuff->drawable, client, 0,
624 DixReceiveAccess);
625 if (rc != Success)
626 return rc;
627
628 return XvdiSelectVideoNotify(client, pDraw, stuff->onoff);
629 }
630
631 static int
632 ProcXvSelectPortNotify(ClientPtr client)
633 {
634 int status;
635 XvPortPtr pPort;
636
637 REQUEST(xvSelectPortNotifyReq);
638 REQUEST_SIZE_MATCH(xvSelectPortNotifyReq);
639
640 VALIDATE_XV_PORT(stuff->port, pPort, DixReadAccess);
641
642 if ((status = _AllocatePort(stuff->port, pPort)) != Success) {
643 client->errorValue = stuff->port;
644 return status;
645 }
646
647 return XvdiSelectPortNotify(client, pPort, stuff->onoff);
648 }
649
650 static int
651 ProcXvGrabPort(ClientPtr client)
652 {
653 int result, status;
654 XvPortPtr pPort;
655 xvGrabPortReply rep;
656
657 REQUEST(xvGrabPortReq);
658 REQUEST_SIZE_MATCH(xvGrabPortReq);
659
660 VALIDATE_XV_PORT(stuff->port, pPort, DixReadAccess);
661
662 if ((status = _AllocatePort(stuff->port, pPort)) != Success) {
663 client->errorValue = stuff->port;
664 return status;
665 }
666
667 status = XvdiGrabPort(client, pPort, stuff->time, &result);
668
669 if (status != Success) {
670 return status;
671 }
672 rep = (xvGrabPortReply) {
673 .type = X_Reply,
674 .sequenceNumber = client->sequence,
675 .length = 0,
676 .result = result
677 };
678
679 _WriteGrabPortReply(client, &rep);
680
681 return Success;
682 }
683
684 static int
685 ProcXvUngrabPort(ClientPtr client)
686 {
687 int status;
688 XvPortPtr pPort;
689
690 REQUEST(xvGrabPortReq);
691 REQUEST_SIZE_MATCH(xvGrabPortReq);
692
693 VALIDATE_XV_PORT(stuff->port, pPort, DixReadAccess);
694
695 if ((status = _AllocatePort(stuff->port, pPort)) != Success) {
696 client->errorValue = stuff->port;
697 return status;
698 }
699
700 return XvdiUngrabPort(client, pPort, stuff->time);
701 }
702
703 static int
704 ProcXvStopVideo(ClientPtr client)
705 {
706 int status, ret;
707 DrawablePtr pDraw;
708 XvPortPtr pPort;
709
710 REQUEST(xvStopVideoReq);
711 REQUEST_SIZE_MATCH(xvStopVideoReq);
712
713 VALIDATE_XV_PORT(stuff->port, pPort, DixReadAccess);
714
715 if ((status = _AllocatePort(stuff->port, pPort)) != Success) {
716 client->errorValue = stuff->port;
717 return status;
718 }
719
720 ret = dixLookupDrawable(&pDraw, stuff->drawable, client, 0, DixWriteAccess);
721 if (ret != Success)
722 return ret;
723
724 return XvdiStopVideo(client, pPort, pDraw);
725 }
726
727 static int
728 ProcXvSetPortAttribute(ClientPtr client)
729 {
730 int status;
731 XvPortPtr pPort;
732
733 REQUEST(xvSetPortAttributeReq);
734 REQUEST_SIZE_MATCH(xvSetPortAttributeReq);
735
736 VALIDATE_XV_PORT(stuff->port, pPort, DixSetAttrAccess);
737
738 if ((status = _AllocatePort(stuff->port, pPort)) != Success) {
739 client->errorValue = stuff->port;
740 return status;
741 }
742
743 if (!ValidAtom(stuff->attribute)) {
744 client->errorValue = stuff->attribute;
745 return BadAtom;
746 }
747
748 status =
749 XvdiSetPortAttribute(client, pPort, stuff->attribute, stuff->value);
750
751 if (status == BadMatch)
752 client->errorValue = stuff->attribute;
753 else
754 client->errorValue = stuff->value;
755
756 return status;
757 }
758
759 static int
760 ProcXvGetPortAttribute(ClientPtr client)
761 {
762 INT32 value;
763 int status;
764 XvPortPtr pPort;
765 xvGetPortAttributeReply rep;
766
767 REQUEST(xvGetPortAttributeReq);
768 REQUEST_SIZE_MATCH(xvGetPortAttributeReq);
769
770 VALIDATE_XV_PORT(stuff->port, pPort, DixGetAttrAccess);
771
772 if ((status = _AllocatePort(stuff->port, pPort)) != Success) {
773 client->errorValue = stuff->port;
774 return status;
775 }
776
777 if (!ValidAtom(stuff->attribute)) {
778 client->errorValue = stuff->attribute;
779 return BadAtom;
780 }
781
782 status = XvdiGetPortAttribute(client, pPort, stuff->attribute, &value);
783 if (status != Success) {
784 client->errorValue = stuff->attribute;
785 return status;
786 }
787
788 rep = (xvGetPortAttributeReply) {
789 .type = X_Reply,
790 .sequenceNumber = client->sequence,
791 .length = 0,
792 .value = value
793 };
794
795 _WriteGetPortAttributeReply(client, &rep);
796
797 return Success;
798 }
799
800 static int
801 ProcXvQueryBestSize(ClientPtr client)
802 {
803 int status;
804 unsigned int actual_width, actual_height;
805 XvPortPtr pPort;
806 xvQueryBestSizeReply rep;
807
808 REQUEST(xvQueryBestSizeReq);
809 REQUEST_SIZE_MATCH(xvQueryBestSizeReq);
810
811 VALIDATE_XV_PORT(stuff->port, pPort, DixReadAccess);
812
813 if ((status = _AllocatePort(stuff->port, pPort)) != Success) {
814 client->errorValue = stuff->port;
815 return status;
816 }
817
818 (*pPort->pAdaptor->ddQueryBestSize) (client, pPort, stuff->motion,
819 stuff->vid_w, stuff->vid_h,
820 stuff->drw_w, stuff->drw_h,
821 &actual_width, &actual_height);
822
823 rep = (xvQueryBestSizeReply) {
824 .type = X_Reply,
825 .sequenceNumber = client->sequence,
826 .length = 0,
827 .actual_width = actual_width,
828 .actual_height = actual_height
829 };
830
831 _WriteQueryBestSizeReply(client, &rep);
832
833 return Success;
834 }
835
836 static int
837 ProcXvQueryPortAttributes(ClientPtr client)
838 {
839 int status, size, i;
840 XvPortPtr pPort;
841 XvAttributePtr pAtt;
842 xvQueryPortAttributesReply rep;
843 xvAttributeInfo Info;
844
845 REQUEST(xvQueryPortAttributesReq);
846 REQUEST_SIZE_MATCH(xvQueryPortAttributesReq);
847
848 VALIDATE_XV_PORT(stuff->port, pPort, DixGetAttrAccess);
849
850 if ((status = _AllocatePort(stuff->port, pPort)) != Success) {
851 client->errorValue = stuff->port;
852 return status;
853 }
854
855 rep = (xvQueryPortAttributesReply) {
856 .type = X_Reply,
857 .sequenceNumber = client->sequence,
858 .num_attributes = pPort->pAdaptor->nAttributes,
859 .text_size = 0
860 };
861
862 for (i = 0, pAtt = pPort->pAdaptor->pAttributes;
863 i < pPort->pAdaptor->nAttributes; i++, pAtt++) {
864 rep.text_size += pad_to_int32(strlen(pAtt->name) + 1);
865 }
866
867 rep.length = (pPort->pAdaptor->nAttributes * sz_xvAttributeInfo)
868 + rep.text_size;
869 rep.length >>= 2;
870
871 _WriteQueryPortAttributesReply(client, &rep);
872
873 for (i = 0, pAtt = pPort->pAdaptor->pAttributes;
874 i < pPort->pAdaptor->nAttributes; i++, pAtt++) {
875 size = strlen(pAtt->name) + 1; /* pass the NULL */
876 Info.flags = pAtt->flags;
877 Info.min = pAtt->min_value;
878 Info.max = pAtt->max_value;
879 Info.size = pad_to_int32(size);
880
881 _WriteAttributeInfo(client, &Info);
882
883 WriteToClient(client, size, pAtt->name);
884 }
885
886 return Success;
887 }
888
889 static int
890 ProcXvPutImage(ClientPtr client)
891 {
892 DrawablePtr pDraw;
893 XvPortPtr pPort;
894 XvImagePtr pImage = NULL;
895 GCPtr pGC;
896 int status, i, size;
897 CARD16 width, height;
898
899 REQUEST(xvPutImageReq);
900 REQUEST_AT_LEAST_SIZE(xvPutImageReq);
901
902 VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess);
903 VALIDATE_XV_PORT(stuff->port, pPort, DixReadAccess);
904
905 if ((status = _AllocatePort(stuff->port, pPort)) != Success) {
906 client->errorValue = stuff->port;
907 return status;
908 }
909
910 if (!(pPort->pAdaptor->type & XvImageMask) ||
911 !(pPort->pAdaptor->type & XvInputMask)) {
912 client->errorValue = stuff->port;
913 return BadMatch;
914 }
915
916 status = XvdiMatchPort(pPort, pDraw);
917 if (status != Success) {
918 return status;
919 }
920
921 for (i = 0; i < pPort->pAdaptor->nImages; i++) {
922 if (pPort->pAdaptor->pImages[i].id == stuff->id) {
923 pImage = &(pPort->pAdaptor->pImages[i]);
924 break;
925 }
926 }
927
928 if (!pImage)
929 return BadMatch;
930
931 width = stuff->width;
932 height = stuff->height;
933 size = (*pPort->pAdaptor->ddQueryImageAttributes) (client,
934 pPort, pImage, &width,
935 &height, NULL, NULL);
936 size += sizeof(xvPutImageReq);
937 size = bytes_to_int32(size);
938
939 if ((width < stuff->width) || (height < stuff->height))
940 return BadValue;
941
942 if (client->req_len < size)
943 return BadLength;
944
945 return XvdiPutImage(client, pDraw, pPort, pGC, stuff->src_x, stuff->src_y,
946 stuff->src_w, stuff->src_h, stuff->drw_x, stuff->drw_y,
947 stuff->drw_w, stuff->drw_h, pImage,
948 (unsigned char *) (&stuff[1]), FALSE,
949 stuff->width, stuff->height);
950 }
951
952 #ifdef MITSHM
953
954 static int
955 ProcXvShmPutImage(ClientPtr client)
956 {
957 ShmDescPtr shmdesc;
958 DrawablePtr pDraw;
959 XvPortPtr pPort;
960 XvImagePtr pImage = NULL;
961 GCPtr pGC;
962 int status, size_needed, i;
963 CARD16 width, height;
964
965 REQUEST(xvShmPutImageReq);
966 REQUEST_SIZE_MATCH(xvShmPutImageReq);
967
968 VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess);
969 VALIDATE_XV_PORT(stuff->port, pPort, DixReadAccess);
970
971 if ((status = _AllocatePort(stuff->port, pPort)) != Success) {
972 client->errorValue = stuff->port;
973 return status;
974 }
975
976 if (!(pPort->pAdaptor->type & XvImageMask) ||
977 !(pPort->pAdaptor->type & XvInputMask)) {
978 client->errorValue = stuff->port;
979 return BadMatch;
980 }
981
982 status = XvdiMatchPort(pPort, pDraw);
983 if (status != Success) {
984 return status;
985 }
986
987 for (i = 0; i < pPort->pAdaptor->nImages; i++) {
988 if (pPort->pAdaptor->pImages[i].id == stuff->id) {
989 pImage = &(pPort->pAdaptor->pImages[i]);
990 break;
991 }
992 }
993
994 if (!pImage)
995 return BadMatch;
996
997 status = dixLookupResourceByType((pointer *) &shmdesc, stuff->shmseg,
998 ShmSegType, serverClient, DixReadAccess);
999 if (status != Success)
1000 return status;
1001
1002 width = stuff->width;
1003 height = stuff->height;
1004 size_needed = (*pPort->pAdaptor->ddQueryImageAttributes) (client,
1005 pPort, pImage,
1006 &width, &height,
1007 NULL, NULL);
1008 if ((size_needed + stuff->offset) > shmdesc->size)
1009 return BadAccess;
1010
1011 if ((width < stuff->width) || (height < stuff->height))
1012 return BadValue;
1013
1014 status = XvdiPutImage(client, pDraw, pPort, pGC, stuff->src_x, stuff->src_y,
1015 stuff->src_w, stuff->src_h, stuff->drw_x,
1016 stuff->drw_y, stuff->drw_w, stuff->drw_h, pImage,
1017 (unsigned char *) shmdesc->addr + stuff->offset,
1018 stuff->send_event, stuff->width, stuff->height);
1019
1020 if ((status == Success) && stuff->send_event) {
1021 xShmCompletionEvent ev = {
1022 .type = ShmCompletionCode,
1023 .drawable = stuff->drawable,
1024 .minorEvent = xv_ShmPutImage,
1025 .majorEvent = XvReqCode,
1026 .shmseg = stuff->shmseg,
1027 .offset = stuff->offset
1028 };
1029 WriteEventsToClient(client, 1, (xEvent *) &ev);
1030 }
1031
1032 return status;
1033 }
1034 #else /* !MITSHM */
1035 static int
1036 ProcXvShmPutImage(ClientPtr client)
1037 {
1038 SendErrorToClient(client, XvReqCode, xv_ShmPutImage, 0, BadImplementation);
1039 return BadImplementation;
1040 }
1041 #endif
1042
1043 #ifdef XvMCExtension
1044 #include "xvmcext.h"
1045 #endif
1046
1047 static int
1048 ProcXvQueryImageAttributes(ClientPtr client)
1049 {
1050 xvQueryImageAttributesReply rep;
1051 int size, num_planes, i;
1052 CARD16 width, height;
1053 XvImagePtr pImage = NULL;
1054 XvPortPtr pPort;
1055 int *offsets;
1056 int *pitches;
1057 int planeLength;
1058
1059 REQUEST(xvQueryImageAttributesReq);
1060
1061 REQUEST_SIZE_MATCH(xvQueryImageAttributesReq);
1062
1063 VALIDATE_XV_PORT(stuff->port, pPort, DixReadAccess);
1064
1065 for (i = 0; i < pPort->pAdaptor->nImages; i++) {
1066 if (pPort->pAdaptor->pImages[i].id == stuff->id) {
1067 pImage = &(pPort->pAdaptor->pImages[i]);
1068 break;
1069 }
1070 }
1071
1072 #ifdef XvMCExtension
1073 if (!pImage)
1074 pImage = XvMCFindXvImage(pPort, stuff->id);
1075 #endif
1076
1077 if (!pImage)
1078 return BadMatch;
1079
1080 num_planes = pImage->num_planes;
1081
1082 if (!(offsets = malloc(num_planes << 3)))
1083 return BadAlloc;
1084 pitches = offsets + num_planes;
1085
1086 width = stuff->width;
1087 height = stuff->height;
1088
1089 size = (*pPort->pAdaptor->ddQueryImageAttributes) (client, pPort, pImage,
1090 &width, &height, offsets,
1091 pitches);
1092
1093 rep = (xvQueryImageAttributesReply) {
1094 .type = X_Reply,
1095 .sequenceNumber = client->sequence,
1096 .length = planeLength = num_planes << 1,
1097 .num_planes = num_planes,
1098 .width = width,
1099 .height = height,
1100 .data_size = size
1101 };
1102
1103 _WriteQueryImageAttributesReply(client, &rep);
1104 if (client->swapped)
1105 SwapLongs((CARD32 *) offsets, planeLength);
1106 WriteToClient(client, planeLength << 2, offsets);
1107
1108 free(offsets);
1109
1110 return Success;
1111 }
1112
1113 static int
1114 ProcXvListImageFormats(ClientPtr client)
1115 {
1116 XvPortPtr pPort;
1117 XvImagePtr pImage;
1118 int i;
1119 xvListImageFormatsReply rep;
1120 xvImageFormatInfo info;
1121
1122 REQUEST(xvListImageFormatsReq);
1123
1124 REQUEST_SIZE_MATCH(xvListImageFormatsReq);
1125
1126 VALIDATE_XV_PORT(stuff->port, pPort, DixReadAccess);
1127
1128 rep = (xvListImageFormatsReply) {
1129 .type = X_Reply,
1130 .sequenceNumber = client->sequence,
1131 .num_formats = pPort->pAdaptor->nImages,
1132 .length =
1133 bytes_to_int32(pPort->pAdaptor->nImages * sz_xvImageFormatInfo)
1134 };
1135
1136 _WriteListImageFormatsReply(client, &rep);
1137
1138 pImage = pPort->pAdaptor->pImages;
1139
1140 for (i = 0; i < pPort->pAdaptor->nImages; i++, pImage++) {
1141 info.id = pImage->id;
1142 info.type = pImage->type;
1143 info.byte_order = pImage->byte_order;
1144 memcpy(&info.guid, pImage->guid, 16);
1145 info.bpp = pImage->bits_per_pixel;
1146 info.num_planes = pImage->num_planes;
1147 info.depth = pImage->depth;
1148 info.red_mask = pImage->red_mask;
1149 info.green_mask = pImage->green_mask;
1150 info.blue_mask = pImage->blue_mask;
1151 info.format = pImage->format;
1152 info.y_sample_bits = pImage->y_sample_bits;
1153 info.u_sample_bits = pImage->u_sample_bits;
1154 info.v_sample_bits = pImage->v_sample_bits;
1155 info.horz_y_period = pImage->horz_y_period;
1156 info.horz_u_period = pImage->horz_u_period;
1157 info.horz_v_period = pImage->horz_v_period;
1158 info.vert_y_period = pImage->vert_y_period;
1159 info.vert_u_period = pImage->vert_u_period;
1160 info.vert_v_period = pImage->vert_v_period;
1161 memcpy(&info.comp_order, pImage->component_order, 32);
1162 info.scanline_order = pImage->scanline_order;
1163 _WriteImageFormatInfo(client, &info);
1164 }
1165
1166 return Success;
1167 }
1168
1169 static int (*XvProcVector[xvNumRequests]) (ClientPtr) = {
1170 ProcXvQueryExtension,
1171 ProcXvQueryAdaptors,
1172 ProcXvQueryEncodings,
1173 ProcXvGrabPort,
1174 ProcXvUngrabPort,
1175 ProcXvPutVideo,
1176 ProcXvPutStill,
1177 ProcXvGetVideo,
1178 ProcXvGetStill,
1179 ProcXvStopVideo,
1180 ProcXvSelectVideoNotify,
1181 ProcXvSelectPortNotify,
1182 ProcXvQueryBestSize,
1183 ProcXvSetPortAttribute,
1184 ProcXvGetPortAttribute,
1185 ProcXvQueryPortAttributes,
1186 ProcXvListImageFormats,
1187 ProcXvQueryImageAttributes, ProcXvPutImage, ProcXvShmPutImage,};
1188
1189 int
1190 ProcXvDispatch(ClientPtr client)
1191 {
1192 REQUEST(xReq);
1193
1194 UpdateCurrentTime();
1195
1196 if (stuff->data >= xvNumRequests) {
1197 SendErrorToClient(client, XvReqCode, stuff->data, 0, BadRequest);
1198 return BadRequest;
1199 }
1200
1201 return XvProcVector[stuff->data] (client);
1202 }
1203
1204 /* Swapped Procs */
1205
1206 static int
1207 SProcXvQueryExtension(ClientPtr client)
1208 {
1209 REQUEST(xvQueryExtensionReq);
1210 swaps(&stuff->length);
1211 return XvProcVector[xv_QueryExtension] (client);
1212 }
1213
1214 static int
1215 SProcXvQueryAdaptors(ClientPtr client)
1216 {
1217 REQUEST(xvQueryAdaptorsReq);
1218 swaps(&stuff->length);
1219 swapl(&stuff->window);
1220 return XvProcVector[xv_QueryAdaptors] (client);
1221 }
1222
1223 static int
1224 SProcXvQueryEncodings(ClientPtr client)
1225 {
1226 REQUEST(xvQueryEncodingsReq);
1227 swaps(&stuff->length);
1228 swapl(&stuff->port);
1229 return XvProcVector[xv_QueryEncodings] (client);
1230 }
1231
1232 static int
1233 SProcXvGrabPort(ClientPtr client)
1234 {
1235 REQUEST(xvGrabPortReq);
1236 swaps(&stuff->length);
1237 swapl(&stuff->port);
1238 swapl(&stuff->time);
1239 return XvProcVector[xv_GrabPort] (client);
1240 }
1241
1242 static int
1243 SProcXvUngrabPort(ClientPtr client)
1244 {
1245 REQUEST(xvUngrabPortReq);
1246 swaps(&stuff->length);
1247 swapl(&stuff->port);
1248 swapl(&stuff->time);
1249 return XvProcVector[xv_UngrabPort] (client);
1250 }
1251
1252 static int
1253 SProcXvPutVideo(ClientPtr client)
1254 {
1255 REQUEST(xvPutVideoReq);
1256 swaps(&stuff->length);
1257 swapl(&stuff->port);
1258 swapl(&stuff->drawable);
1259 swapl(&stuff->gc);
1260 swaps(&stuff->vid_x);
1261 swaps(&stuff->vid_y);
1262 swaps(&stuff->vid_w);
1263 swaps(&stuff->vid_h);
1264 swaps(&stuff->drw_x);
1265 swaps(&stuff->drw_y);
1266 swaps(&stuff->drw_w);
1267 swaps(&stuff->drw_h);
1268 return XvProcVector[xv_PutVideo] (client);
1269 }
1270
1271 static int
1272 SProcXvPutStill(ClientPtr client)
1273 {
1274 REQUEST(xvPutStillReq);
1275 swaps(&stuff->length);
1276 swapl(&stuff->port);
1277 swapl(&stuff->drawable);
1278 swapl(&stuff->gc);
1279 swaps(&stuff->vid_x);
1280 swaps(&stuff->vid_y);
1281 swaps(&stuff->vid_w);
1282 swaps(&stuff->vid_h);
1283 swaps(&stuff->drw_x);
1284 swaps(&stuff->drw_y);
1285 swaps(&stuff->drw_w);
1286 swaps(&stuff->drw_h);
1287 return XvProcVector[xv_PutStill] (client);
1288 }
1289
1290 static int
1291 SProcXvGetVideo(ClientPtr client)
1292 {
1293 REQUEST(xvGetVideoReq);
1294 swaps(&stuff->length);
1295 swapl(&stuff->port);
1296 swapl(&stuff->drawable);
1297 swapl(&stuff->gc);
1298 swaps(&stuff->vid_x);
1299 swaps(&stuff->vid_y);
1300 swaps(&stuff->vid_w);
1301 swaps(&stuff->vid_h);
1302 swaps(&stuff->drw_x);
1303 swaps(&stuff->drw_y);
1304 swaps(&stuff->drw_w);
1305 swaps(&stuff->drw_h);
1306 return XvProcVector[xv_GetVideo] (client);
1307 }
1308
1309 static int
1310 SProcXvGetStill(ClientPtr client)
1311 {
1312 REQUEST(xvGetStillReq);
1313 swaps(&stuff->length);
1314 swapl(&stuff->port);
1315 swapl(&stuff->drawable);
1316 swapl(&stuff->gc);
1317 swaps(&stuff->vid_x);
1318 swaps(&stuff->vid_y);
1319 swaps(&stuff->vid_w);
1320 swaps(&stuff->vid_h);
1321 swaps(&stuff->drw_x);
1322 swaps(&stuff->drw_y);
1323 swaps(&stuff->drw_w);
1324 swaps(&stuff->drw_h);
1325 return XvProcVector[xv_GetStill] (client);
1326 }
1327
1328 static int
1329 SProcXvPutImage(ClientPtr client)
1330 {
1331 REQUEST(xvPutImageReq);
1332 swaps(&stuff->length);
1333 swapl(&stuff->port);
1334 swapl(&stuff->drawable);
1335 swapl(&stuff->gc);
1336 swapl(&stuff->id);
1337 swaps(&stuff->src_x);
1338 swaps(&stuff->src_y);
1339 swaps(&stuff->src_w);
1340 swaps(&stuff->src_h);
1341 swaps(&stuff->drw_x);
1342 swaps(&stuff->drw_y);
1343 swaps(&stuff->drw_w);
1344 swaps(&stuff->drw_h);
1345 swaps(&stuff->width);
1346 swaps(&stuff->height);
1347 return XvProcVector[xv_PutImage] (client);
1348 }
1349
1350 #ifdef MITSHM
1351 static int
1352 SProcXvShmPutImage(ClientPtr client)
1353 {
1354 REQUEST(xvShmPutImageReq);
1355 swaps(&stuff->length);
1356 swapl(&stuff->port);
1357 swapl(&stuff->drawable);
1358 swapl(&stuff->gc);
1359 swapl(&stuff->shmseg);
1360 swapl(&stuff->id);
1361 swapl(&stuff->offset);
1362 swaps(&stuff->src_x);
1363 swaps(&stuff->src_y);
1364 swaps(&stuff->src_w);
1365 swaps(&stuff->src_h);
1366 swaps(&stuff->drw_x);
1367 swaps(&stuff->drw_y);
1368 swaps(&stuff->drw_w);
1369 swaps(&stuff->drw_h);
1370 swaps(&stuff->width);
1371 swaps(&stuff->height);
1372 return XvProcVector[xv_ShmPutImage] (client);
1373 }
1374 #else /* MITSHM */
1375 #define SProcXvShmPutImage ProcXvShmPutImage
1376 #endif
1377
1378 static int
1379 SProcXvSelectVideoNotify(ClientPtr client)
1380 {
1381 REQUEST(xvSelectVideoNotifyReq);
1382 swaps(&stuff->length);
1383 swapl(&stuff->drawable);
1384 return XvProcVector[xv_SelectVideoNotify] (client);
1385 }
1386
1387 static int
1388 SProcXvSelectPortNotify(ClientPtr client)
1389 {
1390 REQUEST(xvSelectPortNotifyReq);
1391 swaps(&stuff->length);
1392 swapl(&stuff->port);
1393 return XvProcVector[xv_SelectPortNotify] (client);
1394 }
1395
1396 static int
1397 SProcXvStopVideo(ClientPtr client)
1398 {
1399 REQUEST(xvStopVideoReq);
1400 swaps(&stuff->length);
1401 swapl(&stuff->port);
1402 swapl(&stuff->drawable);
1403 return XvProcVector[xv_StopVideo] (client);
1404 }
1405
1406 static int
1407 SProcXvSetPortAttribute(ClientPtr client)
1408 {
1409 REQUEST(xvSetPortAttributeReq);
1410 swaps(&stuff->length);
1411 swapl(&stuff->port);
1412 swapl(&stuff->attribute);
1413 swapl(&stuff->value);
1414 return XvProcVector[xv_SetPortAttribute] (client);
1415 }
1416
1417 static int
1418 SProcXvGetPortAttribute(ClientPtr client)
1419 {
1420 REQUEST(xvGetPortAttributeReq);
1421 swaps(&stuff->length);
1422 swapl(&stuff->port);
1423 swapl(&stuff->attribute);
1424 return XvProcVector[xv_GetPortAttribute] (client);
1425 }
1426
1427 static int
1428 SProcXvQueryBestSize(ClientPtr client)
1429 {
1430 REQUEST(xvQueryBestSizeReq);
1431 swaps(&stuff->length);
1432 swapl(&stuff->port);
1433 swaps(&stuff->vid_w);
1434 swaps(&stuff->vid_h);
1435 swaps(&stuff->drw_w);
1436 swaps(&stuff->drw_h);
1437 return XvProcVector[xv_QueryBestSize] (client);
1438 }
1439
1440 static int
1441 SProcXvQueryPortAttributes(ClientPtr client)
1442 {
1443 REQUEST(xvQueryPortAttributesReq);
1444 swaps(&stuff->length);
1445 swapl(&stuff->port);
1446 return XvProcVector[xv_QueryPortAttributes] (client);
1447 }
1448
1449 static int
1450 SProcXvQueryImageAttributes(ClientPtr client)
1451 {
1452 REQUEST(xvQueryImageAttributesReq);
1453 swaps(&stuff->length);
1454 swapl(&stuff->port);
1455 swapl(&stuff->id);
1456 swaps(&stuff->width);
1457 swaps(&stuff->height);
1458 return XvProcVector[xv_QueryImageAttributes] (client);
1459 }
1460
1461 static int
1462 SProcXvListImageFormats(ClientPtr client)
1463 {
1464 REQUEST(xvListImageFormatsReq);
1465 swaps(&stuff->length);
1466 swapl(&stuff->port);
1467 return XvProcVector[xv_ListImageFormats] (client);
1468 }
1469
1470 static int (*SXvProcVector[xvNumRequests]) (ClientPtr) = {
1471 SProcXvQueryExtension,
1472 SProcXvQueryAdaptors,
1473 SProcXvQueryEncodings,
1474 SProcXvGrabPort,
1475 SProcXvUngrabPort,
1476 SProcXvPutVideo,
1477 SProcXvPutStill,
1478 SProcXvGetVideo,
1479 SProcXvGetStill,
1480 SProcXvStopVideo,
1481 SProcXvSelectVideoNotify,
1482 SProcXvSelectPortNotify,
1483 SProcXvQueryBestSize,
1484 SProcXvSetPortAttribute,
1485 SProcXvGetPortAttribute,
1486 SProcXvQueryPortAttributes,
1487 SProcXvListImageFormats,
1488 SProcXvQueryImageAttributes, SProcXvPutImage, SProcXvShmPutImage,};
1489
1490 int
1491 SProcXvDispatch(ClientPtr client)
1492 {
1493 REQUEST(xReq);
1494
1495 UpdateCurrentTime();
1496
1497 if (stuff->data >= xvNumRequests) {
1498 SendErrorToClient(client, XvReqCode, stuff->data, 0, BadRequest);
1499 return BadRequest;
1500 }
1501
1502 return SXvProcVector[stuff->data] (client);
1503 }
1504
1505 #ifdef PANORAMIX
1506 static int
1507 XineramaXvStopVideo(ClientPtr client)
1508 {
1509 int result, i;
1510 PanoramiXRes *draw, *port;
1511
1512 REQUEST(xvStopVideoReq);
1513 REQUEST_SIZE_MATCH(xvStopVideoReq);
1514
1515 result = dixLookupResourceByClass((pointer *) &draw, stuff->drawable,
1516 XRC_DRAWABLE, client, DixWriteAccess);
1517 if (result != Success)
1518 return (result == BadValue) ? BadDrawable : result;
1519
1520 result = dixLookupResourceByType((pointer *) &port, stuff->port,
1521 XvXRTPort, client, DixReadAccess);
1522 if (result != Success)
1523 return result;
1524
1525 FOR_NSCREENS_BACKWARD(i) {
1526 if (port->info[i].id) {
1527 stuff->drawable = draw->info[i].id;
1528 stuff->port = port->info[i].id;
1529 result = ProcXvStopVideo(client);
1530 }
1531 }
1532
1533 return result;
1534 }
1535
1536 static int
1537 XineramaXvSetPortAttribute(ClientPtr client)
1538 {
1539 REQUEST(xvSetPortAttributeReq);
1540 PanoramiXRes *port;
1541 int result, i;
1542
1543 REQUEST_SIZE_MATCH(xvSetPortAttributeReq);
1544
1545 result = dixLookupResourceByType((pointer *) &port, stuff->port,
1546 XvXRTPort, client, DixReadAccess);
1547 if (result != Success)
1548 return result;
1549
1550 FOR_NSCREENS_BACKWARD(i) {
1551 if (port->info[i].id) {
1552 stuff->port = port->info[i].id;
1553 result = ProcXvSetPortAttribute(client);
1554 }
1555 }
1556 return result;
1557 }
1558
1559 #ifdef MITSHM
1560 static int
1561 XineramaXvShmPutImage(ClientPtr client)
1562 {
1563 REQUEST(xvShmPutImageReq);
1564 PanoramiXRes *draw, *gc, *port;
1565 Bool send_event = stuff->send_event;
1566 Bool isRoot;
1567 int result, i, x, y;
1568
1569 REQUEST_SIZE_MATCH(xvShmPutImageReq);
1570
1571 result = dixLookupResourceByClass((pointer *) &draw, stuff->drawable,
1572 XRC_DRAWABLE, client, DixWriteAccess);
1573 if (result != Success)
1574 return (result == BadValue) ? BadDrawable : result;
1575
1576 result = dixLookupResourceByType((pointer *) &gc, stuff->gc,
1577 XRT_GC, client, DixReadAccess);
1578 if (result != Success)
1579 return result;
1580
1581 result = dixLookupResourceByType((pointer *) &port, stuff->port,
1582 XvXRTPort, client, DixReadAccess);
1583 if (result != Success)
1584 return result;
1585
1586 isRoot = (draw->type == XRT_WINDOW) && draw->u.win.root;
1587
1588 x = stuff->drw_x;
1589 y = stuff->drw_y;
1590
1591 FOR_NSCREENS_BACKWARD(i) {
1592 if (port->info[i].id) {
1593 stuff->drawable = draw->info[i].id;
1594 stuff->port = port->info[i].id;
1595 stuff->gc = gc->info[i].id;
1596 stuff->drw_x = x;
1597 stuff->drw_y = y;
1598 if (isRoot) {
1599 stuff->drw_x -= screenInfo.screens[i]->x;
1600 stuff->drw_y -= screenInfo.screens[i]->y;
1601 }
1602 stuff->send_event = (send_event && !i) ? 1 : 0;
1603
1604 result = ProcXvShmPutImage(client);
1605 }
1606 }
1607 return result;
1608 }
1609 #else
1610 #define XineramaXvShmPutImage ProcXvShmPutImage
1611 #endif
1612
1613 static int
1614 XineramaXvPutImage(ClientPtr client)
1615 {
1616 REQUEST(xvPutImageReq);
1617 PanoramiXRes *draw, *gc, *port;
1618 Bool isRoot;
1619 int result, i, x, y;
1620
1621 REQUEST_AT_LEAST_SIZE(xvPutImageReq);
1622
1623 result = dixLookupResourceByClass((pointer *) &draw, stuff->drawable,
1624 XRC_DRAWABLE, client, DixWriteAccess);
1625 if (result != Success)
1626 return (result == BadValue) ? BadDrawable : result;
1627
1628 result = dixLookupResourceByType((pointer *) &gc, stuff->gc,
1629 XRT_GC, client, DixReadAccess);
1630 if (result != Success)
1631 return result;
1632
1633 result = dixLookupResourceByType((pointer *) &port, stuff->port,
1634 XvXRTPort, client, DixReadAccess);
1635 if (result != Success)
1636 return result;
1637
1638 isRoot = (draw->type == XRT_WINDOW) && draw->u.win.root;
1639
1640 x = stuff->drw_x;
1641 y = stuff->drw_y;
1642
1643 FOR_NSCREENS_BACKWARD(i) {
1644 if (port->info[i].id) {
1645 stuff->drawable = draw->info[i].id;
1646 stuff->port = port->info[i].id;
1647 stuff->gc = gc->info[i].id;
1648 stuff->drw_x = x;
1649 stuff->drw_y = y;
1650 if (isRoot) {
1651 stuff->drw_x -= screenInfo.screens[i]->x;
1652 stuff->drw_y -= screenInfo.screens[i]->y;
1653 }
1654
1655 result = ProcXvPutImage(client);
1656 }
1657 }
1658 return result;
1659 }
1660
1661 static int
1662 XineramaXvPutVideo(ClientPtr client)
1663 {
1664 REQUEST(xvPutImageReq);
1665 PanoramiXRes *draw, *gc, *port;
1666 Bool isRoot;
1667 int result, i, x, y;
1668
1669 REQUEST_AT_LEAST_SIZE(xvPutVideoReq);
1670
1671 result = dixLookupResourceByClass((pointer *) &draw, stuff->drawable,
1672 XRC_DRAWABLE, client, DixWriteAccess);
1673 if (result != Success)
1674 return (result == BadValue) ? BadDrawable : result;
1675
1676 result = dixLookupResourceByType((pointer *) &gc, stuff->gc,
1677 XRT_GC, client, DixReadAccess);
1678 if (result != Success)
1679 return result;
1680
1681 result = dixLookupResourceByType((pointer *) &port, stuff->port,
1682 XvXRTPort, client, DixReadAccess);
1683 if (result != Success)
1684 return result;
1685
1686 isRoot = (draw->type == XRT_WINDOW) && draw->u.win.root;
1687
1688 x = stuff->drw_x;
1689 y = stuff->drw_y;
1690
1691 FOR_NSCREENS_BACKWARD(i) {
1692 if (port->info[i].id) {
1693 stuff->drawable = draw->info[i].id;
1694 stuff->port = port->info[i].id;
1695 stuff->gc = gc->info[i].id;
1696 stuff->drw_x = x;
1697 stuff->drw_y = y;
1698 if (isRoot) {
1699 stuff->drw_x -= screenInfo.screens[i]->x;
1700 stuff->drw_y -= screenInfo.screens[i]->y;
1701 }
1702
1703 result = ProcXvPutVideo(client);
1704 }
1705 }
1706 return result;
1707 }
1708
1709 static int
1710 XineramaXvPutStill(ClientPtr client)
1711 {
1712 REQUEST(xvPutImageReq);
1713 PanoramiXRes *draw, *gc, *port;
1714 Bool isRoot;
1715 int result, i, x, y;
1716
1717 REQUEST_AT_LEAST_SIZE(xvPutImageReq);
1718
1719 result = dixLookupResourceByClass((pointer *) &draw, stuff->drawable,
1720 XRC_DRAWABLE, client, DixWriteAccess);
1721 if (result != Success)
1722 return (result == BadValue) ? BadDrawable : result;
1723
1724 result = dixLookupResourceByType((pointer *) &gc, stuff->gc,
1725 XRT_GC, client, DixReadAccess);
1726 if (result != Success)
1727 return result;
1728
1729 result = dixLookupResourceByType((pointer *) &port, stuff->port,
1730 XvXRTPort, client, DixReadAccess);
1731 if (result != Success)
1732 return result;
1733
1734 isRoot = (draw->type == XRT_WINDOW) && draw->u.win.root;
1735
1736 x = stuff->drw_x;
1737 y = stuff->drw_y;
1738
1739 FOR_NSCREENS_BACKWARD(i) {
1740 if (port->info[i].id) {
1741 stuff->drawable = draw->info[i].id;
1742 stuff->port = port->info[i].id;
1743 stuff->gc = gc->info[i].id;
1744 stuff->drw_x = x;
1745 stuff->drw_y = y;
1746 if (isRoot) {
1747 stuff->drw_x -= screenInfo.screens[i]->x;
1748 stuff->drw_y -= screenInfo.screens[i]->y;
1749 }
1750
1751 result = ProcXvPutStill(client);
1752 }
1753 }
1754 return result;
1755 }
1756
1757 static Bool
1758 isImageAdaptor(XvAdaptorPtr pAdapt)
1759 {
1760 return (pAdapt->type & XvImageMask) && (pAdapt->nImages > 0);
1761 }
1762
1763 static Bool
1764 hasOverlay(XvAdaptorPtr pAdapt)
1765 {
1766 int i;
1767
1768 for (i = 0; i < pAdapt->nAttributes; i++)
1769 if (!strcmp(pAdapt->pAttributes[i].name, "XV_COLORKEY"))
1770 return TRUE;
1771 return FALSE;
1772 }
1773
1774 static XvAdaptorPtr
1775 matchAdaptor(ScreenPtr pScreen, XvAdaptorPtr refAdapt, Bool isOverlay)
1776 {
1777 int i;
1778 XvScreenPtr xvsp =
1779 dixLookupPrivate(&pScreen->devPrivates, XvGetScreenKey());
1780 /* Do not try to go on if xv is not supported on this screen */
1781 if (xvsp == NULL)
1782 return NULL;
1783
1784 /* if the adaptor has the same name it's a perfect match */
1785 for (i = 0; i < xvsp->nAdaptors; i++) {
1786 XvAdaptorPtr pAdapt = xvsp->pAdaptors + i;
1787
1788 if (!strcmp(refAdapt->name, pAdapt->name))
1789 return pAdapt;
1790 }
1791
1792 /* otherwise we only look for XvImage adaptors */
1793 if (!isImageAdaptor(refAdapt))
1794 return NULL;
1795
1796 /* prefer overlay/overlay non-overlay/non-overlay pairing */
1797 for (i = 0; i < xvsp->nAdaptors; i++) {
1798 XvAdaptorPtr pAdapt = xvsp->pAdaptors + i;
1799
1800 if (isImageAdaptor(pAdapt) && isOverlay == hasOverlay(pAdapt))
1801 return pAdapt;
1802 }
1803
1804 /* but we'll take any XvImage pairing if we can get it */
1805 for (i = 0; i < xvsp->nAdaptors; i++) {
1806 XvAdaptorPtr pAdapt = xvsp->pAdaptors + i;
1807
1808 if (isImageAdaptor(pAdapt))
1809 return pAdapt;
1810 }
1811 return NULL;
1812 }
1813
1814 void
1815 XineramifyXv(void)
1816 {
1817 XvScreenPtr xvsp0 =
1818 dixLookupPrivate(&screenInfo.screens[0]->devPrivates, XvGetScreenKey());
1819 XvAdaptorPtr MatchingAdaptors[MAXSCREENS];
1820 int i, j, k;
1821
1822 XvXRTPort = CreateNewResourceType(XineramaDeleteResource, "XvXRTPort");
1823
1824 if (!xvsp0 || !XvXRTPort)
1825 return;
1826 SetResourceTypeErrorValue(XvXRTPort, _XvBadPort);
1827
1828 for (i = 0; i < xvsp0->nAdaptors; i++) {
1829 Bool isOverlay;
1830 XvAdaptorPtr refAdapt = xvsp0->pAdaptors + i;
1831
1832 if (!(refAdapt->type & XvInputMask))
1833 continue;
1834
1835 MatchingAdaptors[0] = refAdapt;
1836 isOverlay = hasOverlay(refAdapt);
1837 FOR_NSCREENS_FORWARD_SKIP(j)
1838 MatchingAdaptors[j] =
1839 matchAdaptor(screenInfo.screens[j], refAdapt, isOverlay);
1840
1841 /* now create a resource for each port */
1842 for (j = 0; j < refAdapt->nPorts; j++) {
1843 PanoramiXRes *port = malloc(sizeof(PanoramiXRes));
1844
1845 if (!port)
1846 break;
1847
1848 FOR_NSCREENS(k) {
1849 if (MatchingAdaptors[k] && (MatchingAdaptors[k]->nPorts > j))
1850 port->info[k].id = MatchingAdaptors[k]->base_id + j;
1851 else
1852 port->info[k].id = 0;
1853 }
1854 AddResource(port->info[0].id, XvXRTPort, port);
1855 }
1856 }
1857
1858 /* munge the dispatch vector */
1859 XvProcVector[xv_PutVideo] = XineramaXvPutVideo;
1860 XvProcVector[xv_PutStill] = XineramaXvPutStill;
1861 XvProcVector[xv_StopVideo] = XineramaXvStopVideo;
1862 XvProcVector[xv_SetPortAttribute] = XineramaXvSetPortAttribute;
1863 XvProcVector[xv_PutImage] = XineramaXvPutImage;
1864 XvProcVector[xv_ShmPutImage] = XineramaXvShmPutImage;
1865 }
1866 #endif /* PANORAMIX */
1867
1868 void
1869 XvResetProcVector(void)
1870 {
1871 #ifdef PANORAMIX
1872 XvProcVector[xv_PutVideo] = ProcXvPutVideo;
1873 XvProcVector[xv_PutStill] = ProcXvPutStill;
1874 XvProcVector[xv_StopVideo] = ProcXvStopVideo;
1875 XvProcVector[xv_SetPortAttribute] = ProcXvSetPortAttribute;
1876 XvProcVector[xv_PutImage] = ProcXvPutImage;
1877 XvProcVector[xv_ShmPutImage] = ProcXvShmPutImage;
1878 #endif
1879 }