xfree86: common: use LogMessageVerb() instead of xf86Msg()
[xserver.git] / Xext / xvdisp.c
blob8a315b90a04fb0b165b0f43c6301a060fedadfb1
1 /***********************************************************
2 Copyright 1991 by Digital Equipment Corporation, Maynard, Massachusetts,
3 and the Massachusetts Institute of Technology, Cambridge, Massachusetts.
5 All Rights Reserved
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.
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 ******************************************************************/
24 #include <dix-config.h>
26 #include <string.h>
28 #include <X11/X.h>
29 #include <X11/Xproto.h>
30 #include <X11/extensions/Xv.h>
31 #include <X11/extensions/Xvproto.h>
33 #include "dix/dix_priv.h"
34 #include "Xext/xvdix_priv.h"
36 #include "misc.h"
37 #include "scrnintstr.h"
38 #include "windowstr.h"
39 #include "pixmapstr.h"
40 #include "gcstruct.h"
41 #include "dixstruct.h"
42 #include "resource.h"
43 #include "opaque.h"
44 #ifdef MITSHM
45 #include <X11/extensions/shmproto.h>
46 #include "shmint.h"
47 #endif
49 #include "xvdisp.h"
51 #ifdef XINERAMA
52 #include "panoramiX.h"
53 #include "panoramiXsrv.h"
55 unsigned long XvXRTPort;
56 #endif /* XINERAMA */
58 static int
59 SWriteQueryExtensionReply(ClientPtr client, xvQueryExtensionReply * rep)
61 swaps(&rep->sequenceNumber);
62 swapl(&rep->length);
63 swaps(&rep->version);
64 swaps(&rep->revision);
66 WriteToClient(client, sz_xvQueryExtensionReply, rep);
68 return Success;
71 static int
72 SWriteQueryAdaptorsReply(ClientPtr client, xvQueryAdaptorsReply * rep)
74 swaps(&rep->sequenceNumber);
75 swapl(&rep->length);
76 swaps(&rep->num_adaptors);
78 WriteToClient(client, sz_xvQueryAdaptorsReply, rep);
80 return Success;
83 static int
84 SWriteQueryEncodingsReply(ClientPtr client, xvQueryEncodingsReply * rep)
86 swaps(&rep->sequenceNumber);
87 swapl(&rep->length);
88 swaps(&rep->num_encodings);
90 WriteToClient(client, sz_xvQueryEncodingsReply, rep);
92 return Success;
95 static int
96 SWriteAdaptorInfo(ClientPtr client, xvAdaptorInfo * pAdaptor)
98 swapl(&pAdaptor->base_id);
99 swaps(&pAdaptor->name_size);
100 swaps(&pAdaptor->num_ports);
101 swaps(&pAdaptor->num_formats);
103 WriteToClient(client, sz_xvAdaptorInfo, pAdaptor);
105 return Success;
108 static int
109 SWriteEncodingInfo(ClientPtr client, xvEncodingInfo * pEncoding)
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);
120 return Success;
123 static int
124 SWriteFormat(ClientPtr client, xvFormat * pFormat)
126 swapl(&pFormat->visual);
127 WriteToClient(client, sz_xvFormat, pFormat);
129 return Success;
132 static int
133 SWriteAttributeInfo(ClientPtr client, xvAttributeInfo * pAtt)
135 swapl(&pAtt->flags);
136 swapl(&pAtt->size);
137 swapl(&pAtt->min);
138 swapl(&pAtt->max);
139 WriteToClient(client, sz_xvAttributeInfo, pAtt);
141 return Success;
144 static int
145 SWriteImageFormatInfo(ClientPtr client, xvImageFormatInfo * pImage)
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);
161 WriteToClient(client, sz_xvImageFormatInfo, pImage);
163 return Success;
166 static int
167 SWriteGrabPortReply(ClientPtr client, xvGrabPortReply * rep)
169 swaps(&rep->sequenceNumber);
170 swapl(&rep->length);
172 WriteToClient(client, sz_xvGrabPortReply, rep);
174 return Success;
177 static int
178 SWriteGetPortAttributeReply(ClientPtr client, xvGetPortAttributeReply * rep)
180 swaps(&rep->sequenceNumber);
181 swapl(&rep->length);
182 swapl(&rep->value);
184 WriteToClient(client, sz_xvGetPortAttributeReply, rep);
186 return Success;
189 static int
190 SWriteQueryBestSizeReply(ClientPtr client, xvQueryBestSizeReply * rep)
192 swaps(&rep->sequenceNumber);
193 swapl(&rep->length);
194 swaps(&rep->actual_width);
195 swaps(&rep->actual_height);
197 WriteToClient(client, sz_xvQueryBestSizeReply, rep);
199 return Success;
202 static int
203 SWriteQueryPortAttributesReply(ClientPtr client,
204 xvQueryPortAttributesReply * rep)
206 swaps(&rep->sequenceNumber);
207 swapl(&rep->length);
208 swapl(&rep->num_attributes);
209 swapl(&rep->text_size);
211 WriteToClient(client, sz_xvQueryPortAttributesReply, rep);
213 return Success;
216 static int
217 SWriteQueryImageAttributesReply(ClientPtr client,
218 xvQueryImageAttributesReply * rep)
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);
227 WriteToClient(client, sz_xvQueryImageAttributesReply, rep);
229 return Success;
232 static int
233 SWriteListImageFormatsReply(ClientPtr client, xvListImageFormatsReply * rep)
235 swaps(&rep->sequenceNumber);
236 swapl(&rep->length);
237 swapl(&rep->num_formats);
239 WriteToClient(client, sz_xvListImageFormatsReply, rep);
241 return Success;
244 #define _WriteQueryAdaptorsReply(_c,_d) \
245 if ((_c)->swapped) SWriteQueryAdaptorsReply(_c, _d); \
246 else WriteToClient(_c, sz_xvQueryAdaptorsReply, _d)
248 #define _WriteQueryExtensionReply(_c,_d) \
249 if ((_c)->swapped) SWriteQueryExtensionReply(_c, _d); \
250 else WriteToClient(_c, sz_xvQueryExtensionReply, _d)
252 #define _WriteQueryEncodingsReply(_c,_d) \
253 if ((_c)->swapped) SWriteQueryEncodingsReply(_c, _d); \
254 else WriteToClient(_c, sz_xvQueryEncodingsReply, _d)
256 #define _WriteAdaptorInfo(_c,_d) \
257 if ((_c)->swapped) SWriteAdaptorInfo(_c, _d); \
258 else WriteToClient(_c, sz_xvAdaptorInfo, _d)
260 #define _WriteAttributeInfo(_c,_d) \
261 if ((_c)->swapped) SWriteAttributeInfo(_c, _d); \
262 else WriteToClient(_c, sz_xvAttributeInfo, _d)
264 #define _WriteEncodingInfo(_c,_d) \
265 if ((_c)->swapped) SWriteEncodingInfo(_c, _d); \
266 else WriteToClient(_c, sz_xvEncodingInfo, _d)
268 #define _WriteFormat(_c,_d) \
269 if ((_c)->swapped) SWriteFormat(_c, _d); \
270 else WriteToClient(_c, sz_xvFormat, _d)
272 #define _WriteGrabPortReply(_c,_d) \
273 if ((_c)->swapped) SWriteGrabPortReply(_c, _d); \
274 else WriteToClient(_c, sz_xvGrabPortReply, _d)
276 #define _WriteGetPortAttributeReply(_c,_d) \
277 if ((_c)->swapped) SWriteGetPortAttributeReply(_c, _d); \
278 else WriteToClient(_c, sz_xvGetPortAttributeReply, _d)
280 #define _WriteQueryBestSizeReply(_c,_d) \
281 if ((_c)->swapped) SWriteQueryBestSizeReply(_c, _d); \
282 else WriteToClient(_c, sz_xvQueryBestSizeReply, _d)
284 #define _WriteQueryPortAttributesReply(_c,_d) \
285 if ((_c)->swapped) SWriteQueryPortAttributesReply(_c, _d); \
286 else WriteToClient(_c, sz_xvQueryPortAttributesReply, _d)
288 #define _WriteQueryImageAttributesReply(_c,_d) \
289 if ((_c)->swapped) SWriteQueryImageAttributesReply(_c, _d); \
290 else WriteToClient(_c, sz_xvQueryImageAttributesReply, _d)
292 #define _WriteListImageFormatsReply(_c,_d) \
293 if ((_c)->swapped) SWriteListImageFormatsReply(_c, _d); \
294 else WriteToClient(_c, sz_xvListImageFormatsReply, _d)
296 #define _WriteImageFormatInfo(_c,_d) \
297 if ((_c)->swapped) SWriteImageFormatInfo(_c, _d); \
298 else WriteToClient(_c, sz_xvImageFormatInfo, _d)
300 static int
301 ProcXvQueryExtension(ClientPtr client)
303 xvQueryExtensionReply rep = {
304 .type = X_Reply,
305 .sequenceNumber = client->sequence,
306 .length = 0,
307 .version = XvVersion,
308 .revision = XvRevision
311 /* REQUEST(xvQueryExtensionReq); */
312 REQUEST_SIZE_MATCH(xvQueryExtensionReq);
314 _WriteQueryExtensionReply(client, &rep);
316 return Success;
319 static int
320 ProcXvQueryAdaptors(ClientPtr client)
322 xvFormat format;
323 xvAdaptorInfo ainfo;
324 xvQueryAdaptorsReply rep;
325 int totalSize, na, nf, rc;
326 int nameSize;
327 XvAdaptorPtr pa;
328 XvFormatPtr pf;
329 WindowPtr pWin;
330 ScreenPtr pScreen;
331 XvScreenPtr pxvs;
333 REQUEST(xvQueryAdaptorsReq);
334 REQUEST_SIZE_MATCH(xvQueryAdaptorsReq);
336 rc = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess);
337 if (rc != Success)
338 return rc;
340 pScreen = pWin->drawable.pScreen;
341 pxvs = (XvScreenPtr) dixLookupPrivate(&pScreen->devPrivates,
342 XvGetScreenKey());
343 if (!pxvs) {
344 rep = (xvQueryAdaptorsReply) {
345 .type = X_Reply,
346 .sequenceNumber = client->sequence,
347 .length = 0,
348 .num_adaptors = 0
351 _WriteQueryAdaptorsReply(client, &rep);
353 return Success;
356 rep = (xvQueryAdaptorsReply) {
357 .type = X_Reply,
358 .sequenceNumber = client->sequence,
359 .num_adaptors = pxvs->nAdaptors
362 /* CALCULATE THE TOTAL SIZE OF THE REPLY IN BYTES */
364 totalSize = pxvs->nAdaptors * sz_xvAdaptorInfo;
366 /* FOR EACH ADPATOR ADD UP THE BYTES FOR ENCODINGS AND FORMATS */
368 na = pxvs->nAdaptors;
369 pa = pxvs->pAdaptors;
370 while (na--) {
371 totalSize += pad_to_int32(strlen(pa->name));
372 totalSize += pa->nFormats * sz_xvFormat;
373 pa++;
376 rep.length = bytes_to_int32(totalSize);
378 _WriteQueryAdaptorsReply(client, &rep);
380 na = pxvs->nAdaptors;
381 pa = pxvs->pAdaptors;
382 while (na--) {
384 ainfo.base_id = pa->base_id;
385 ainfo.num_ports = pa->nPorts;
386 ainfo.type = pa->type;
387 ainfo.name_size = nameSize = strlen(pa->name);
388 ainfo.num_formats = pa->nFormats;
390 _WriteAdaptorInfo(client, &ainfo);
392 WriteToClient(client, nameSize, pa->name);
394 nf = pa->nFormats;
395 pf = pa->pFormats;
396 while (nf--) {
397 format.depth = pf->depth;
398 format.visual = pf->visual;
399 _WriteFormat(client, &format);
400 pf++;
403 pa++;
407 return Success;
410 static int
411 ProcXvQueryEncodings(ClientPtr client)
413 xvEncodingInfo einfo;
414 xvQueryEncodingsReply rep;
415 int totalSize;
416 int nameSize;
417 XvPortPtr pPort;
418 int ne;
419 XvEncodingPtr pe;
421 REQUEST(xvQueryEncodingsReq);
422 REQUEST_SIZE_MATCH(xvQueryEncodingsReq);
424 VALIDATE_XV_PORT(stuff->port, pPort, DixReadAccess);
426 rep = (xvQueryEncodingsReply) {
427 .type = X_Reply,
428 .sequenceNumber = client->sequence,
429 .num_encodings = pPort->pAdaptor->nEncodings
432 /* FOR EACH ENCODING ADD UP THE BYTES FOR ENCODING NAMES */
434 ne = pPort->pAdaptor->nEncodings;
435 pe = pPort->pAdaptor->pEncodings;
436 totalSize = ne * sz_xvEncodingInfo;
437 while (ne--) {
438 totalSize += pad_to_int32(strlen(pe->name));
439 pe++;
442 rep.length = bytes_to_int32(totalSize);
444 _WriteQueryEncodingsReply(client, &rep);
446 ne = pPort->pAdaptor->nEncodings;
447 pe = pPort->pAdaptor->pEncodings;
448 while (ne--) {
449 einfo.encoding = pe->id;
450 einfo.name_size = nameSize = strlen(pe->name);
451 einfo.width = pe->width;
452 einfo.height = pe->height;
453 einfo.rate.numerator = pe->rate.numerator;
454 einfo.rate.denominator = pe->rate.denominator;
455 _WriteEncodingInfo(client, &einfo);
456 WriteToClient(client, nameSize, pe->name);
457 pe++;
460 return Success;
463 static int
464 ProcXvPutVideo(ClientPtr client)
466 DrawablePtr pDraw;
467 XvPortPtr pPort;
468 GCPtr pGC;
469 int status;
471 REQUEST(xvPutVideoReq);
472 REQUEST_SIZE_MATCH(xvPutVideoReq);
474 VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess);
475 VALIDATE_XV_PORT(stuff->port, pPort, DixReadAccess);
477 if (!(pPort->pAdaptor->type & XvInputMask) ||
478 !(pPort->pAdaptor->type & XvVideoMask)) {
479 client->errorValue = stuff->port;
480 return BadMatch;
483 status = XvdiMatchPort(pPort, pDraw);
484 if (status != Success) {
485 return status;
488 return XvdiPutVideo(client, pDraw, pPort, pGC, stuff->vid_x, stuff->vid_y,
489 stuff->vid_w, stuff->vid_h, stuff->drw_x, stuff->drw_y,
490 stuff->drw_w, stuff->drw_h);
493 static int
494 ProcXvPutStill(ClientPtr client)
496 DrawablePtr pDraw;
497 XvPortPtr pPort;
498 GCPtr pGC;
499 int status;
501 REQUEST(xvPutStillReq);
502 REQUEST_SIZE_MATCH(xvPutStillReq);
504 VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess);
505 VALIDATE_XV_PORT(stuff->port, pPort, DixReadAccess);
507 if (!(pPort->pAdaptor->type & XvInputMask) ||
508 !(pPort->pAdaptor->type & XvStillMask)) {
509 client->errorValue = stuff->port;
510 return BadMatch;
513 status = XvdiMatchPort(pPort, pDraw);
514 if (status != Success) {
515 return status;
518 return XvdiPutStill(client, pDraw, pPort, pGC, stuff->vid_x, stuff->vid_y,
519 stuff->vid_w, stuff->vid_h, stuff->drw_x, stuff->drw_y,
520 stuff->drw_w, stuff->drw_h);
523 static int
524 ProcXvGetVideo(ClientPtr client)
526 DrawablePtr pDraw;
527 XvPortPtr pPort;
528 GCPtr pGC;
529 int status;
531 REQUEST(xvGetVideoReq);
532 REQUEST_SIZE_MATCH(xvGetVideoReq);
534 VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixReadAccess);
535 VALIDATE_XV_PORT(stuff->port, pPort, DixReadAccess);
537 if (!(pPort->pAdaptor->type & XvOutputMask) ||
538 !(pPort->pAdaptor->type & XvVideoMask)) {
539 client->errorValue = stuff->port;
540 return BadMatch;
543 status = XvdiMatchPort(pPort, pDraw);
544 if (status != Success) {
545 return status;
548 return XvdiGetVideo(client, pDraw, pPort, pGC, stuff->vid_x, stuff->vid_y,
549 stuff->vid_w, stuff->vid_h, stuff->drw_x, stuff->drw_y,
550 stuff->drw_w, stuff->drw_h);
553 static int
554 ProcXvGetStill(ClientPtr client)
556 DrawablePtr pDraw;
557 XvPortPtr pPort;
558 GCPtr pGC;
559 int status;
561 REQUEST(xvGetStillReq);
562 REQUEST_SIZE_MATCH(xvGetStillReq);
564 VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixReadAccess);
565 VALIDATE_XV_PORT(stuff->port, pPort, DixReadAccess);
567 if (!(pPort->pAdaptor->type & XvOutputMask) ||
568 !(pPort->pAdaptor->type & XvStillMask)) {
569 client->errorValue = stuff->port;
570 return BadMatch;
573 status = XvdiMatchPort(pPort, pDraw);
574 if (status != Success) {
575 return status;
578 return XvdiGetStill(client, pDraw, pPort, pGC, stuff->vid_x, stuff->vid_y,
579 stuff->vid_w, stuff->vid_h, stuff->drw_x, stuff->drw_y,
580 stuff->drw_w, stuff->drw_h);
583 static int
584 ProcXvSelectVideoNotify(ClientPtr client)
586 DrawablePtr pDraw;
587 int rc;
589 REQUEST(xvSelectVideoNotifyReq);
590 REQUEST_SIZE_MATCH(xvSelectVideoNotifyReq);
592 rc = dixLookupDrawable(&pDraw, stuff->drawable, client, 0,
593 DixReceiveAccess);
594 if (rc != Success)
595 return rc;
597 return XvdiSelectVideoNotify(client, pDraw, stuff->onoff);
600 static int
601 ProcXvSelectPortNotify(ClientPtr client)
603 XvPortPtr pPort;
605 REQUEST(xvSelectPortNotifyReq);
606 REQUEST_SIZE_MATCH(xvSelectPortNotifyReq);
608 VALIDATE_XV_PORT(stuff->port, pPort, DixReadAccess);
610 return XvdiSelectPortNotify(client, pPort, stuff->onoff);
613 static int
614 ProcXvGrabPort(ClientPtr client)
616 int result, status;
617 XvPortPtr pPort;
618 xvGrabPortReply rep;
620 REQUEST(xvGrabPortReq);
621 REQUEST_SIZE_MATCH(xvGrabPortReq);
623 VALIDATE_XV_PORT(stuff->port, pPort, DixReadAccess);
625 status = XvdiGrabPort(client, pPort, stuff->time, &result);
627 if (status != Success) {
628 return status;
630 rep = (xvGrabPortReply) {
631 .type = X_Reply,
632 .sequenceNumber = client->sequence,
633 .length = 0,
634 .result = result
637 _WriteGrabPortReply(client, &rep);
639 return Success;
642 static int
643 ProcXvUngrabPort(ClientPtr client)
645 XvPortPtr pPort;
647 REQUEST(xvGrabPortReq);
648 REQUEST_SIZE_MATCH(xvGrabPortReq);
650 VALIDATE_XV_PORT(stuff->port, pPort, DixReadAccess);
652 return XvdiUngrabPort(client, pPort, stuff->time);
655 static int
656 ProcXvStopVideo(ClientPtr client)
658 int ret;
659 DrawablePtr pDraw;
660 XvPortPtr pPort;
662 REQUEST(xvStopVideoReq);
663 REQUEST_SIZE_MATCH(xvStopVideoReq);
665 VALIDATE_XV_PORT(stuff->port, pPort, DixReadAccess);
667 ret = dixLookupDrawable(&pDraw, stuff->drawable, client, 0, DixWriteAccess);
668 if (ret != Success)
669 return ret;
671 return XvdiStopVideo(client, pPort, pDraw);
674 static int
675 ProcXvSetPortAttribute(ClientPtr client)
677 int status;
678 XvPortPtr pPort;
680 REQUEST(xvSetPortAttributeReq);
681 REQUEST_SIZE_MATCH(xvSetPortAttributeReq);
683 VALIDATE_XV_PORT(stuff->port, pPort, DixSetAttrAccess);
685 if (!ValidAtom(stuff->attribute)) {
686 client->errorValue = stuff->attribute;
687 return BadAtom;
690 status =
691 XvdiSetPortAttribute(client, pPort, stuff->attribute, stuff->value);
693 if (status == BadMatch)
694 client->errorValue = stuff->attribute;
695 else
696 client->errorValue = stuff->value;
698 return status;
701 static int
702 ProcXvGetPortAttribute(ClientPtr client)
704 INT32 value;
705 int status;
706 XvPortPtr pPort;
707 xvGetPortAttributeReply rep;
709 REQUEST(xvGetPortAttributeReq);
710 REQUEST_SIZE_MATCH(xvGetPortAttributeReq);
712 VALIDATE_XV_PORT(stuff->port, pPort, DixGetAttrAccess);
714 if (!ValidAtom(stuff->attribute)) {
715 client->errorValue = stuff->attribute;
716 return BadAtom;
719 status = XvdiGetPortAttribute(client, pPort, stuff->attribute, &value);
720 if (status != Success) {
721 client->errorValue = stuff->attribute;
722 return status;
725 rep = (xvGetPortAttributeReply) {
726 .type = X_Reply,
727 .sequenceNumber = client->sequence,
728 .length = 0,
729 .value = value
732 _WriteGetPortAttributeReply(client, &rep);
734 return Success;
737 static int
738 ProcXvQueryBestSize(ClientPtr client)
740 unsigned int actual_width, actual_height;
741 XvPortPtr pPort;
742 xvQueryBestSizeReply rep;
744 REQUEST(xvQueryBestSizeReq);
745 REQUEST_SIZE_MATCH(xvQueryBestSizeReq);
747 VALIDATE_XV_PORT(stuff->port, pPort, DixReadAccess);
749 (*pPort->pAdaptor->ddQueryBestSize) (pPort, stuff->motion,
750 stuff->vid_w, stuff->vid_h,
751 stuff->drw_w, stuff->drw_h,
752 &actual_width, &actual_height);
754 rep = (xvQueryBestSizeReply) {
755 .type = X_Reply,
756 .sequenceNumber = client->sequence,
757 .length = 0,
758 .actual_width = actual_width,
759 .actual_height = actual_height
762 _WriteQueryBestSizeReply(client, &rep);
764 return Success;
767 static int
768 ProcXvQueryPortAttributes(ClientPtr client)
770 int size, i;
771 XvPortPtr pPort;
772 XvAttributePtr pAtt;
773 xvQueryPortAttributesReply rep;
774 xvAttributeInfo Info;
776 REQUEST(xvQueryPortAttributesReq);
777 REQUEST_SIZE_MATCH(xvQueryPortAttributesReq);
779 VALIDATE_XV_PORT(stuff->port, pPort, DixGetAttrAccess);
781 rep = (xvQueryPortAttributesReply) {
782 .type = X_Reply,
783 .sequenceNumber = client->sequence,
784 .num_attributes = pPort->pAdaptor->nAttributes,
785 .text_size = 0
788 for (i = 0, pAtt = pPort->pAdaptor->pAttributes;
789 i < pPort->pAdaptor->nAttributes; i++, pAtt++) {
790 rep.text_size += pad_to_int32(strlen(pAtt->name) + 1);
793 rep.length = (pPort->pAdaptor->nAttributes * sz_xvAttributeInfo)
794 + rep.text_size;
795 rep.length >>= 2;
797 _WriteQueryPortAttributesReply(client, &rep);
799 for (i = 0, pAtt = pPort->pAdaptor->pAttributes;
800 i < pPort->pAdaptor->nAttributes; i++, pAtt++) {
801 size = strlen(pAtt->name) + 1; /* pass the NULL */
802 Info.flags = pAtt->flags;
803 Info.min = pAtt->min_value;
804 Info.max = pAtt->max_value;
805 Info.size = pad_to_int32(size);
807 _WriteAttributeInfo(client, &Info);
809 WriteToClient(client, size, pAtt->name);
812 return Success;
815 static int
816 ProcXvPutImage(ClientPtr client)
818 DrawablePtr pDraw;
819 XvPortPtr pPort;
820 XvImagePtr pImage = NULL;
821 GCPtr pGC;
822 int status, i, size;
823 CARD16 width, height;
825 REQUEST(xvPutImageReq);
826 REQUEST_AT_LEAST_SIZE(xvPutImageReq);
828 VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess);
829 VALIDATE_XV_PORT(stuff->port, pPort, DixReadAccess);
831 if (!(pPort->pAdaptor->type & XvImageMask) ||
832 !(pPort->pAdaptor->type & XvInputMask)) {
833 client->errorValue = stuff->port;
834 return BadMatch;
837 status = XvdiMatchPort(pPort, pDraw);
838 if (status != Success) {
839 return status;
842 for (i = 0; i < pPort->pAdaptor->nImages; i++) {
843 if (pPort->pAdaptor->pImages[i].id == stuff->id) {
844 pImage = &(pPort->pAdaptor->pImages[i]);
845 break;
849 if (!pImage)
850 return BadMatch;
852 width = stuff->width;
853 height = stuff->height;
854 size = (*pPort->pAdaptor->ddQueryImageAttributes) (pPort, pImage, &width,
855 &height, NULL, NULL);
856 size += sizeof(xvPutImageReq);
857 size = bytes_to_int32(size);
859 if ((width < stuff->width) || (height < stuff->height))
860 return BadValue;
862 if (client->req_len < size)
863 return BadLength;
865 return XvdiPutImage(client, pDraw, pPort, pGC, stuff->src_x, stuff->src_y,
866 stuff->src_w, stuff->src_h, stuff->drw_x, stuff->drw_y,
867 stuff->drw_w, stuff->drw_h, pImage,
868 (unsigned char *) (&stuff[1]), FALSE,
869 stuff->width, stuff->height);
872 #ifdef MITSHM
874 static int
875 ProcXvShmPutImage(ClientPtr client)
877 ShmDescPtr shmdesc;
878 DrawablePtr pDraw;
879 XvPortPtr pPort;
880 XvImagePtr pImage = NULL;
881 GCPtr pGC;
882 int status, size_needed, i;
883 CARD16 width, height;
885 REQUEST(xvShmPutImageReq);
886 REQUEST_SIZE_MATCH(xvShmPutImageReq);
888 VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess);
889 VALIDATE_XV_PORT(stuff->port, pPort, DixReadAccess);
891 if (!(pPort->pAdaptor->type & XvImageMask) ||
892 !(pPort->pAdaptor->type & XvInputMask)) {
893 client->errorValue = stuff->port;
894 return BadMatch;
897 status = XvdiMatchPort(pPort, pDraw);
898 if (status != Success) {
899 return status;
902 for (i = 0; i < pPort->pAdaptor->nImages; i++) {
903 if (pPort->pAdaptor->pImages[i].id == stuff->id) {
904 pImage = &(pPort->pAdaptor->pImages[i]);
905 break;
909 if (!pImage)
910 return BadMatch;
912 status = dixLookupResourceByType((void **) &shmdesc, stuff->shmseg,
913 ShmSegType, serverClient, DixReadAccess);
914 if (status != Success)
915 return status;
917 width = stuff->width;
918 height = stuff->height;
919 size_needed = (*pPort->pAdaptor->ddQueryImageAttributes) (pPort, pImage,
920 &width, &height,
921 NULL, NULL);
922 if ((size_needed + stuff->offset) > shmdesc->size)
923 return BadAccess;
925 if ((width < stuff->width) || (height < stuff->height))
926 return BadValue;
928 status = XvdiPutImage(client, pDraw, pPort, pGC, stuff->src_x, stuff->src_y,
929 stuff->src_w, stuff->src_h, stuff->drw_x,
930 stuff->drw_y, stuff->drw_w, stuff->drw_h, pImage,
931 (unsigned char *) shmdesc->addr + stuff->offset,
932 stuff->send_event, stuff->width, stuff->height);
934 if ((status == Success) && stuff->send_event) {
935 xShmCompletionEvent ev = {
936 .type = ShmCompletionCode,
937 .drawable = stuff->drawable,
938 .minorEvent = xv_ShmPutImage,
939 .majorEvent = XvReqCode,
940 .shmseg = stuff->shmseg,
941 .offset = stuff->offset
943 WriteEventsToClient(client, 1, (xEvent *) &ev);
946 return status;
948 #else /* !MITSHM */
949 static int
950 ProcXvShmPutImage(ClientPtr client)
952 return BadImplementation;
954 #endif
956 #ifdef XvMCExtension
957 #include "xvmcext.h"
958 #endif
960 static int
961 ProcXvQueryImageAttributes(ClientPtr client)
963 xvQueryImageAttributesReply rep;
964 int size, num_planes, i;
965 CARD16 width, height;
966 XvImagePtr pImage = NULL;
967 XvPortPtr pPort;
968 int *offsets;
969 int *pitches;
970 int planeLength;
972 REQUEST(xvQueryImageAttributesReq);
974 REQUEST_SIZE_MATCH(xvQueryImageAttributesReq);
976 VALIDATE_XV_PORT(stuff->port, pPort, DixReadAccess);
978 for (i = 0; i < pPort->pAdaptor->nImages; i++) {
979 if (pPort->pAdaptor->pImages[i].id == stuff->id) {
980 pImage = &(pPort->pAdaptor->pImages[i]);
981 break;
985 #ifdef XvMCExtension
986 if (!pImage)
987 pImage = XvMCFindXvImage(pPort, stuff->id);
988 #endif
990 if (!pImage)
991 return BadMatch;
993 num_planes = pImage->num_planes;
995 if (!(offsets = malloc(num_planes << 3)))
996 return BadAlloc;
997 pitches = offsets + num_planes;
999 width = stuff->width;
1000 height = stuff->height;
1002 size = (*pPort->pAdaptor->ddQueryImageAttributes) (pPort, pImage,
1003 &width, &height, offsets,
1004 pitches);
1006 rep = (xvQueryImageAttributesReply) {
1007 .type = X_Reply,
1008 .sequenceNumber = client->sequence,
1009 .length = planeLength = num_planes << 1,
1010 .num_planes = num_planes,
1011 .width = width,
1012 .height = height,
1013 .data_size = size
1016 _WriteQueryImageAttributesReply(client, &rep);
1017 if (client->swapped)
1018 SwapLongs((CARD32 *) offsets, planeLength);
1019 WriteToClient(client, planeLength << 2, offsets);
1021 free(offsets);
1023 return Success;
1026 static int
1027 ProcXvListImageFormats(ClientPtr client)
1029 XvPortPtr pPort;
1030 XvImagePtr pImage;
1031 int i;
1032 xvListImageFormatsReply rep;
1033 xvImageFormatInfo info;
1035 REQUEST(xvListImageFormatsReq);
1037 REQUEST_SIZE_MATCH(xvListImageFormatsReq);
1039 VALIDATE_XV_PORT(stuff->port, pPort, DixReadAccess);
1041 rep = (xvListImageFormatsReply) {
1042 .type = X_Reply,
1043 .sequenceNumber = client->sequence,
1044 .num_formats = pPort->pAdaptor->nImages,
1045 .length =
1046 bytes_to_int32(pPort->pAdaptor->nImages * sz_xvImageFormatInfo)
1049 _WriteListImageFormatsReply(client, &rep);
1051 pImage = pPort->pAdaptor->pImages;
1053 for (i = 0; i < pPort->pAdaptor->nImages; i++, pImage++) {
1054 info.id = pImage->id;
1055 info.type = pImage->type;
1056 info.byte_order = pImage->byte_order;
1057 memcpy(&info.guid, pImage->guid, 16);
1058 info.bpp = pImage->bits_per_pixel;
1059 info.num_planes = pImage->num_planes;
1060 info.depth = pImage->depth;
1061 info.red_mask = pImage->red_mask;
1062 info.green_mask = pImage->green_mask;
1063 info.blue_mask = pImage->blue_mask;
1064 info.format = pImage->format;
1065 info.y_sample_bits = pImage->y_sample_bits;
1066 info.u_sample_bits = pImage->u_sample_bits;
1067 info.v_sample_bits = pImage->v_sample_bits;
1068 info.horz_y_period = pImage->horz_y_period;
1069 info.horz_u_period = pImage->horz_u_period;
1070 info.horz_v_period = pImage->horz_v_period;
1071 info.vert_y_period = pImage->vert_y_period;
1072 info.vert_u_period = pImage->vert_u_period;
1073 info.vert_v_period = pImage->vert_v_period;
1074 memcpy(&info.comp_order, pImage->component_order, 32);
1075 info.scanline_order = pImage->scanline_order;
1076 _WriteImageFormatInfo(client, &info);
1079 return Success;
1082 static int (*XvProcVector[xvNumRequests]) (ClientPtr) = {
1083 ProcXvQueryExtension,
1084 ProcXvQueryAdaptors,
1085 ProcXvQueryEncodings,
1086 ProcXvGrabPort,
1087 ProcXvUngrabPort,
1088 ProcXvPutVideo,
1089 ProcXvPutStill,
1090 ProcXvGetVideo,
1091 ProcXvGetStill,
1092 ProcXvStopVideo,
1093 ProcXvSelectVideoNotify,
1094 ProcXvSelectPortNotify,
1095 ProcXvQueryBestSize,
1096 ProcXvSetPortAttribute,
1097 ProcXvGetPortAttribute,
1098 ProcXvQueryPortAttributes,
1099 ProcXvListImageFormats,
1100 ProcXvQueryImageAttributes, ProcXvPutImage, ProcXvShmPutImage,};
1103 ProcXvDispatch(ClientPtr client)
1105 REQUEST(xReq);
1107 UpdateCurrentTime();
1109 if (stuff->data >= xvNumRequests) {
1110 return BadRequest;
1113 return XvProcVector[stuff->data] (client);
1116 /* Swapped Procs */
1118 static int _X_COLD
1119 SProcXvQueryAdaptors(ClientPtr client)
1121 REQUEST(xvQueryAdaptorsReq);
1122 REQUEST_SIZE_MATCH(xvQueryAdaptorsReq);
1123 swapl(&stuff->window);
1124 return XvProcVector[xv_QueryAdaptors] (client);
1127 static int _X_COLD
1128 SProcXvQueryEncodings(ClientPtr client)
1130 REQUEST(xvQueryEncodingsReq);
1131 REQUEST_SIZE_MATCH(xvQueryEncodingsReq);
1132 swapl(&stuff->port);
1133 return XvProcVector[xv_QueryEncodings] (client);
1136 static int _X_COLD
1137 SProcXvGrabPort(ClientPtr client)
1139 REQUEST(xvGrabPortReq);
1140 REQUEST_SIZE_MATCH(xvGrabPortReq);
1141 swapl(&stuff->port);
1142 swapl(&stuff->time);
1143 return XvProcVector[xv_GrabPort] (client);
1146 static int _X_COLD
1147 SProcXvUngrabPort(ClientPtr client)
1149 REQUEST(xvUngrabPortReq);
1150 REQUEST_SIZE_MATCH(xvUngrabPortReq);
1151 swapl(&stuff->port);
1152 swapl(&stuff->time);
1153 return XvProcVector[xv_UngrabPort] (client);
1156 static int _X_COLD
1157 SProcXvPutVideo(ClientPtr client)
1159 REQUEST(xvPutVideoReq);
1160 REQUEST_SIZE_MATCH(xvPutVideoReq);
1161 swapl(&stuff->port);
1162 swapl(&stuff->drawable);
1163 swapl(&stuff->gc);
1164 swaps(&stuff->vid_x);
1165 swaps(&stuff->vid_y);
1166 swaps(&stuff->vid_w);
1167 swaps(&stuff->vid_h);
1168 swaps(&stuff->drw_x);
1169 swaps(&stuff->drw_y);
1170 swaps(&stuff->drw_w);
1171 swaps(&stuff->drw_h);
1172 return XvProcVector[xv_PutVideo] (client);
1175 static int _X_COLD
1176 SProcXvPutStill(ClientPtr client)
1178 REQUEST(xvPutStillReq);
1179 REQUEST_SIZE_MATCH(xvPutStillReq);
1180 swapl(&stuff->port);
1181 swapl(&stuff->drawable);
1182 swapl(&stuff->gc);
1183 swaps(&stuff->vid_x);
1184 swaps(&stuff->vid_y);
1185 swaps(&stuff->vid_w);
1186 swaps(&stuff->vid_h);
1187 swaps(&stuff->drw_x);
1188 swaps(&stuff->drw_y);
1189 swaps(&stuff->drw_w);
1190 swaps(&stuff->drw_h);
1191 return XvProcVector[xv_PutStill] (client);
1194 static int _X_COLD
1195 SProcXvGetVideo(ClientPtr client)
1197 REQUEST(xvGetVideoReq);
1198 REQUEST_SIZE_MATCH(xvGetVideoReq);
1199 swapl(&stuff->port);
1200 swapl(&stuff->drawable);
1201 swapl(&stuff->gc);
1202 swaps(&stuff->vid_x);
1203 swaps(&stuff->vid_y);
1204 swaps(&stuff->vid_w);
1205 swaps(&stuff->vid_h);
1206 swaps(&stuff->drw_x);
1207 swaps(&stuff->drw_y);
1208 swaps(&stuff->drw_w);
1209 swaps(&stuff->drw_h);
1210 return XvProcVector[xv_GetVideo] (client);
1213 static int _X_COLD
1214 SProcXvGetStill(ClientPtr client)
1216 REQUEST(xvGetStillReq);
1217 REQUEST_SIZE_MATCH(xvGetStillReq);
1218 swapl(&stuff->port);
1219 swapl(&stuff->drawable);
1220 swapl(&stuff->gc);
1221 swaps(&stuff->vid_x);
1222 swaps(&stuff->vid_y);
1223 swaps(&stuff->vid_w);
1224 swaps(&stuff->vid_h);
1225 swaps(&stuff->drw_x);
1226 swaps(&stuff->drw_y);
1227 swaps(&stuff->drw_w);
1228 swaps(&stuff->drw_h);
1229 return XvProcVector[xv_GetStill] (client);
1232 static int _X_COLD
1233 SProcXvPutImage(ClientPtr client)
1235 REQUEST(xvPutImageReq);
1236 REQUEST_AT_LEAST_SIZE(xvPutImageReq);
1237 swapl(&stuff->port);
1238 swapl(&stuff->drawable);
1239 swapl(&stuff->gc);
1240 swapl(&stuff->id);
1241 swaps(&stuff->src_x);
1242 swaps(&stuff->src_y);
1243 swaps(&stuff->src_w);
1244 swaps(&stuff->src_h);
1245 swaps(&stuff->drw_x);
1246 swaps(&stuff->drw_y);
1247 swaps(&stuff->drw_w);
1248 swaps(&stuff->drw_h);
1249 swaps(&stuff->width);
1250 swaps(&stuff->height);
1251 return XvProcVector[xv_PutImage] (client);
1254 #ifdef MITSHM
1255 static int _X_COLD
1256 SProcXvShmPutImage(ClientPtr client)
1258 REQUEST(xvShmPutImageReq);
1259 REQUEST_SIZE_MATCH(xvShmPutImageReq);
1260 swapl(&stuff->port);
1261 swapl(&stuff->drawable);
1262 swapl(&stuff->gc);
1263 swapl(&stuff->shmseg);
1264 swapl(&stuff->id);
1265 swapl(&stuff->offset);
1266 swaps(&stuff->src_x);
1267 swaps(&stuff->src_y);
1268 swaps(&stuff->src_w);
1269 swaps(&stuff->src_h);
1270 swaps(&stuff->drw_x);
1271 swaps(&stuff->drw_y);
1272 swaps(&stuff->drw_w);
1273 swaps(&stuff->drw_h);
1274 swaps(&stuff->width);
1275 swaps(&stuff->height);
1276 return XvProcVector[xv_ShmPutImage] (client);
1278 #else /* MITSHM */
1279 #define SProcXvShmPutImage ProcXvShmPutImage
1280 #endif
1282 static int _X_COLD
1283 SProcXvSelectVideoNotify(ClientPtr client)
1285 REQUEST(xvSelectVideoNotifyReq);
1286 REQUEST_SIZE_MATCH(xvSelectVideoNotifyReq);
1287 swapl(&stuff->drawable);
1288 return XvProcVector[xv_SelectVideoNotify] (client);
1291 static int _X_COLD
1292 SProcXvSelectPortNotify(ClientPtr client)
1294 REQUEST(xvSelectPortNotifyReq);
1295 REQUEST_SIZE_MATCH(xvSelectPortNotifyReq);
1296 swapl(&stuff->port);
1297 return XvProcVector[xv_SelectPortNotify] (client);
1300 static int _X_COLD
1301 SProcXvStopVideo(ClientPtr client)
1303 REQUEST(xvStopVideoReq);
1304 REQUEST_SIZE_MATCH(xvStopVideoReq);
1305 swapl(&stuff->port);
1306 swapl(&stuff->drawable);
1307 return XvProcVector[xv_StopVideo] (client);
1310 static int _X_COLD
1311 SProcXvSetPortAttribute(ClientPtr client)
1313 REQUEST(xvSetPortAttributeReq);
1314 REQUEST_SIZE_MATCH(xvSetPortAttributeReq);
1315 swapl(&stuff->port);
1316 swapl(&stuff->attribute);
1317 swapl(&stuff->value);
1318 return XvProcVector[xv_SetPortAttribute] (client);
1321 static int _X_COLD
1322 SProcXvGetPortAttribute(ClientPtr client)
1324 REQUEST(xvGetPortAttributeReq);
1325 REQUEST_SIZE_MATCH(xvGetPortAttributeReq);
1326 swapl(&stuff->port);
1327 swapl(&stuff->attribute);
1328 return XvProcVector[xv_GetPortAttribute] (client);
1331 static int _X_COLD
1332 SProcXvQueryBestSize(ClientPtr client)
1334 REQUEST(xvQueryBestSizeReq);
1335 REQUEST_SIZE_MATCH(xvQueryBestSizeReq);
1336 swapl(&stuff->port);
1337 swaps(&stuff->vid_w);
1338 swaps(&stuff->vid_h);
1339 swaps(&stuff->drw_w);
1340 swaps(&stuff->drw_h);
1341 return XvProcVector[xv_QueryBestSize] (client);
1344 static int _X_COLD
1345 SProcXvQueryPortAttributes(ClientPtr client)
1347 REQUEST(xvQueryPortAttributesReq);
1348 REQUEST_SIZE_MATCH(xvQueryPortAttributesReq);
1349 swapl(&stuff->port);
1350 return XvProcVector[xv_QueryPortAttributes] (client);
1353 static int _X_COLD
1354 SProcXvQueryImageAttributes(ClientPtr client)
1356 REQUEST(xvQueryImageAttributesReq);
1357 REQUEST_SIZE_MATCH(xvQueryImageAttributesReq);
1358 swapl(&stuff->port);
1359 swapl(&stuff->id);
1360 swaps(&stuff->width);
1361 swaps(&stuff->height);
1362 return XvProcVector[xv_QueryImageAttributes] (client);
1365 static int _X_COLD
1366 SProcXvListImageFormats(ClientPtr client)
1368 REQUEST(xvListImageFormatsReq);
1369 REQUEST_SIZE_MATCH(xvListImageFormatsReq);
1370 swapl(&stuff->port);
1371 return XvProcVector[xv_ListImageFormats] (client);
1374 static int (*SXvProcVector[xvNumRequests]) (ClientPtr) = {
1375 ProcXvQueryExtension,
1376 SProcXvQueryAdaptors,
1377 SProcXvQueryEncodings,
1378 SProcXvGrabPort,
1379 SProcXvUngrabPort,
1380 SProcXvPutVideo,
1381 SProcXvPutStill,
1382 SProcXvGetVideo,
1383 SProcXvGetStill,
1384 SProcXvStopVideo,
1385 SProcXvSelectVideoNotify,
1386 SProcXvSelectPortNotify,
1387 SProcXvQueryBestSize,
1388 SProcXvSetPortAttribute,
1389 SProcXvGetPortAttribute,
1390 SProcXvQueryPortAttributes,
1391 SProcXvListImageFormats,
1392 SProcXvQueryImageAttributes, SProcXvPutImage, SProcXvShmPutImage,};
1394 int _X_COLD
1395 SProcXvDispatch(ClientPtr client)
1397 REQUEST(xReq);
1399 UpdateCurrentTime();
1401 if (stuff->data >= xvNumRequests) {
1402 return BadRequest;
1405 return SXvProcVector[stuff->data] (client);
1408 #ifdef XINERAMA
1409 static int
1410 XineramaXvStopVideo(ClientPtr client)
1412 int result, i;
1413 PanoramiXRes *draw, *port;
1415 REQUEST(xvStopVideoReq);
1416 REQUEST_SIZE_MATCH(xvStopVideoReq);
1418 result = dixLookupResourceByClass((void **) &draw, stuff->drawable,
1419 XRC_DRAWABLE, client, DixWriteAccess);
1420 if (result != Success)
1421 return (result == BadValue) ? BadDrawable : result;
1423 result = dixLookupResourceByType((void **) &port, stuff->port,
1424 XvXRTPort, client, DixReadAccess);
1425 if (result != Success)
1426 return result;
1428 FOR_NSCREENS_BACKWARD(i) {
1429 if (port->info[i].id) {
1430 stuff->drawable = draw->info[i].id;
1431 stuff->port = port->info[i].id;
1432 result = ProcXvStopVideo(client);
1436 return result;
1439 static int
1440 XineramaXvSetPortAttribute(ClientPtr client)
1442 REQUEST(xvSetPortAttributeReq);
1443 PanoramiXRes *port;
1444 int result, i;
1446 REQUEST_SIZE_MATCH(xvSetPortAttributeReq);
1448 result = dixLookupResourceByType((void **) &port, stuff->port,
1449 XvXRTPort, client, DixReadAccess);
1450 if (result != Success)
1451 return result;
1453 FOR_NSCREENS_BACKWARD(i) {
1454 if (port->info[i].id) {
1455 stuff->port = port->info[i].id;
1456 result = ProcXvSetPortAttribute(client);
1459 return result;
1462 #ifdef MITSHM
1463 static int
1464 XineramaXvShmPutImage(ClientPtr client)
1466 REQUEST(xvShmPutImageReq);
1467 PanoramiXRes *draw, *gc, *port;
1468 Bool send_event;
1469 Bool isRoot;
1470 int result, i, x, y;
1472 REQUEST_SIZE_MATCH(xvShmPutImageReq);
1474 send_event = stuff->send_event;
1476 result = dixLookupResourceByClass((void **) &draw, stuff->drawable,
1477 XRC_DRAWABLE, client, DixWriteAccess);
1478 if (result != Success)
1479 return (result == BadValue) ? BadDrawable : result;
1481 result = dixLookupResourceByType((void **) &gc, stuff->gc,
1482 XRT_GC, client, DixReadAccess);
1483 if (result != Success)
1484 return result;
1486 result = dixLookupResourceByType((void **) &port, stuff->port,
1487 XvXRTPort, client, DixReadAccess);
1488 if (result != Success)
1489 return result;
1491 isRoot = (draw->type == XRT_WINDOW) && draw->u.win.root;
1493 x = stuff->drw_x;
1494 y = stuff->drw_y;
1496 FOR_NSCREENS_BACKWARD(i) {
1497 if (port->info[i].id) {
1498 stuff->drawable = draw->info[i].id;
1499 stuff->port = port->info[i].id;
1500 stuff->gc = gc->info[i].id;
1501 stuff->drw_x = x;
1502 stuff->drw_y = y;
1503 if (isRoot) {
1504 stuff->drw_x -= screenInfo.screens[i]->x;
1505 stuff->drw_y -= screenInfo.screens[i]->y;
1507 stuff->send_event = (send_event && !i) ? 1 : 0;
1509 result = ProcXvShmPutImage(client);
1512 return result;
1514 #else
1515 #define XineramaXvShmPutImage ProcXvShmPutImage
1516 #endif /* MITSHM */
1518 static int
1519 XineramaXvPutImage(ClientPtr client)
1521 REQUEST(xvPutImageReq);
1522 PanoramiXRes *draw, *gc, *port;
1523 Bool isRoot;
1524 int result, i, x, y;
1526 REQUEST_AT_LEAST_SIZE(xvPutImageReq);
1528 result = dixLookupResourceByClass((void **) &draw, stuff->drawable,
1529 XRC_DRAWABLE, client, DixWriteAccess);
1530 if (result != Success)
1531 return (result == BadValue) ? BadDrawable : result;
1533 result = dixLookupResourceByType((void **) &gc, stuff->gc,
1534 XRT_GC, client, DixReadAccess);
1535 if (result != Success)
1536 return result;
1538 result = dixLookupResourceByType((void **) &port, stuff->port,
1539 XvXRTPort, client, DixReadAccess);
1540 if (result != Success)
1541 return result;
1543 isRoot = (draw->type == XRT_WINDOW) && draw->u.win.root;
1545 x = stuff->drw_x;
1546 y = stuff->drw_y;
1548 FOR_NSCREENS_BACKWARD(i) {
1549 if (port->info[i].id) {
1550 stuff->drawable = draw->info[i].id;
1551 stuff->port = port->info[i].id;
1552 stuff->gc = gc->info[i].id;
1553 stuff->drw_x = x;
1554 stuff->drw_y = y;
1555 if (isRoot) {
1556 stuff->drw_x -= screenInfo.screens[i]->x;
1557 stuff->drw_y -= screenInfo.screens[i]->y;
1560 result = ProcXvPutImage(client);
1563 return result;
1566 static int
1567 XineramaXvPutVideo(ClientPtr client)
1569 REQUEST(xvPutImageReq);
1570 PanoramiXRes *draw, *gc, *port;
1571 Bool isRoot;
1572 int result, i, x, y;
1574 REQUEST_AT_LEAST_SIZE(xvPutVideoReq);
1576 result = dixLookupResourceByClass((void **) &draw, stuff->drawable,
1577 XRC_DRAWABLE, client, DixWriteAccess);
1578 if (result != Success)
1579 return (result == BadValue) ? BadDrawable : result;
1581 result = dixLookupResourceByType((void **) &gc, stuff->gc,
1582 XRT_GC, client, DixReadAccess);
1583 if (result != Success)
1584 return result;
1586 result = dixLookupResourceByType((void **) &port, stuff->port,
1587 XvXRTPort, client, DixReadAccess);
1588 if (result != Success)
1589 return result;
1591 isRoot = (draw->type == XRT_WINDOW) && draw->u.win.root;
1593 x = stuff->drw_x;
1594 y = stuff->drw_y;
1596 FOR_NSCREENS_BACKWARD(i) {
1597 if (port->info[i].id) {
1598 stuff->drawable = draw->info[i].id;
1599 stuff->port = port->info[i].id;
1600 stuff->gc = gc->info[i].id;
1601 stuff->drw_x = x;
1602 stuff->drw_y = y;
1603 if (isRoot) {
1604 stuff->drw_x -= screenInfo.screens[i]->x;
1605 stuff->drw_y -= screenInfo.screens[i]->y;
1608 result = ProcXvPutVideo(client);
1611 return result;
1614 static int
1615 XineramaXvPutStill(ClientPtr client)
1617 REQUEST(xvPutImageReq);
1618 PanoramiXRes *draw, *gc, *port;
1619 Bool isRoot;
1620 int result, i, x, y;
1622 REQUEST_AT_LEAST_SIZE(xvPutImageReq);
1624 result = dixLookupResourceByClass((void **) &draw, stuff->drawable,
1625 XRC_DRAWABLE, client, DixWriteAccess);
1626 if (result != Success)
1627 return (result == BadValue) ? BadDrawable : result;
1629 result = dixLookupResourceByType((void **) &gc, stuff->gc,
1630 XRT_GC, client, DixReadAccess);
1631 if (result != Success)
1632 return result;
1634 result = dixLookupResourceByType((void **) &port, stuff->port,
1635 XvXRTPort, client, DixReadAccess);
1636 if (result != Success)
1637 return result;
1639 isRoot = (draw->type == XRT_WINDOW) && draw->u.win.root;
1641 x = stuff->drw_x;
1642 y = stuff->drw_y;
1644 FOR_NSCREENS_BACKWARD(i) {
1645 if (port->info[i].id) {
1646 stuff->drawable = draw->info[i].id;
1647 stuff->port = port->info[i].id;
1648 stuff->gc = gc->info[i].id;
1649 stuff->drw_x = x;
1650 stuff->drw_y = y;
1651 if (isRoot) {
1652 stuff->drw_x -= screenInfo.screens[i]->x;
1653 stuff->drw_y -= screenInfo.screens[i]->y;
1656 result = ProcXvPutStill(client);
1659 return result;
1662 static Bool
1663 isImageAdaptor(XvAdaptorPtr pAdapt)
1665 return (pAdapt->type & XvImageMask) && (pAdapt->nImages > 0);
1668 static Bool
1669 hasOverlay(XvAdaptorPtr pAdapt)
1671 int i;
1673 for (i = 0; i < pAdapt->nAttributes; i++)
1674 if (!strcmp(pAdapt->pAttributes[i].name, "XV_COLORKEY"))
1675 return TRUE;
1676 return FALSE;
1679 static XvAdaptorPtr
1680 matchAdaptor(ScreenPtr pScreen, XvAdaptorPtr refAdapt, Bool isOverlay)
1682 int i;
1683 XvScreenPtr xvsp =
1684 dixLookupPrivate(&pScreen->devPrivates, XvGetScreenKey());
1685 /* Do not try to go on if xv is not supported on this screen */
1686 if (xvsp == NULL)
1687 return NULL;
1689 /* if the adaptor has the same name it's a perfect match */
1690 for (i = 0; i < xvsp->nAdaptors; i++) {
1691 XvAdaptorPtr pAdapt = xvsp->pAdaptors + i;
1693 if (!strcmp(refAdapt->name, pAdapt->name))
1694 return pAdapt;
1697 /* otherwise we only look for XvImage adaptors */
1698 if (!isImageAdaptor(refAdapt))
1699 return NULL;
1701 /* prefer overlay/overlay non-overlay/non-overlay pairing */
1702 for (i = 0; i < xvsp->nAdaptors; i++) {
1703 XvAdaptorPtr pAdapt = xvsp->pAdaptors + i;
1705 if (isImageAdaptor(pAdapt) && isOverlay == hasOverlay(pAdapt))
1706 return pAdapt;
1709 /* but we'll take any XvImage pairing if we can get it */
1710 for (i = 0; i < xvsp->nAdaptors; i++) {
1711 XvAdaptorPtr pAdapt = xvsp->pAdaptors + i;
1713 if (isImageAdaptor(pAdapt))
1714 return pAdapt;
1716 return NULL;
1719 void
1720 XineramifyXv(void)
1722 XvScreenPtr xvsp0 =
1723 dixLookupPrivate(&screenInfo.screens[0]->devPrivates, XvGetScreenKey());
1724 XvAdaptorPtr MatchingAdaptors[MAXSCREENS];
1725 int i, j, k;
1727 XvXRTPort = CreateNewResourceType(XineramaDeleteResource, "XvXRTPort");
1729 if (!xvsp0 || !XvXRTPort)
1730 return;
1731 SetResourceTypeErrorValue(XvXRTPort, _XvBadPort);
1733 for (i = 0; i < xvsp0->nAdaptors; i++) {
1734 Bool isOverlay;
1735 XvAdaptorPtr refAdapt = xvsp0->pAdaptors + i;
1737 if (!(refAdapt->type & XvInputMask))
1738 continue;
1740 MatchingAdaptors[0] = refAdapt;
1741 isOverlay = hasOverlay(refAdapt);
1742 FOR_NSCREENS_FORWARD_SKIP(j)
1743 MatchingAdaptors[j] =
1744 matchAdaptor(screenInfo.screens[j], refAdapt, isOverlay);
1746 /* now create a resource for each port */
1747 for (j = 0; j < refAdapt->nPorts; j++) {
1748 PanoramiXRes *port = malloc(sizeof(PanoramiXRes));
1750 if (!port)
1751 break;
1753 FOR_NSCREENS(k) {
1754 if (MatchingAdaptors[k] && (MatchingAdaptors[k]->nPorts > j))
1755 port->info[k].id = MatchingAdaptors[k]->base_id + j;
1756 else
1757 port->info[k].id = 0;
1759 AddResource(port->info[0].id, XvXRTPort, port);
1763 /* munge the dispatch vector */
1764 XvProcVector[xv_PutVideo] = XineramaXvPutVideo;
1765 XvProcVector[xv_PutStill] = XineramaXvPutStill;
1766 XvProcVector[xv_StopVideo] = XineramaXvStopVideo;
1767 XvProcVector[xv_SetPortAttribute] = XineramaXvSetPortAttribute;
1768 XvProcVector[xv_PutImage] = XineramaXvPutImage;
1769 XvProcVector[xv_ShmPutImage] = XineramaXvShmPutImage;
1771 #endif /* XINERAMA */
1773 void
1774 XvResetProcVector(void)
1776 #ifdef XINERAMA
1777 XvProcVector[xv_PutVideo] = ProcXvPutVideo;
1778 XvProcVector[xv_PutStill] = ProcXvPutStill;
1779 XvProcVector[xv_StopVideo] = ProcXvStopVideo;
1780 XvProcVector[xv_SetPortAttribute] = ProcXvSetPortAttribute;
1781 XvProcVector[xv_PutImage] = ProcXvPutImage;
1782 XvProcVector[xv_ShmPutImage] = ProcXvShmPutImage;
1783 #endif /* XINERAMA */