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
SWriteQueryExtensionReply(ClientPtr client,xvQueryExtensionReply * rep)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
SWriteQueryAdaptorsReply(ClientPtr client,xvQueryAdaptorsReply * rep)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
SWriteQueryEncodingsReply(ClientPtr client,xvQueryEncodingsReply * rep)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
SWriteAdaptorInfo(ClientPtr client,xvAdaptorInfo * pAdaptor)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
SWriteEncodingInfo(ClientPtr client,xvEncodingInfo * pEncoding)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
SWriteFormat(ClientPtr client,xvFormat * pFormat)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
SWriteAttributeInfo(ClientPtr client,xvAttributeInfo * pAtt)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
SWriteImageFormatInfo(ClientPtr client,xvImageFormatInfo * pImage)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
SWriteGrabPortReply(ClientPtr client,xvGrabPortReply * rep)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
SWriteGetPortAttributeReply(ClientPtr client,xvGetPortAttributeReply * rep)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
SWriteQueryBestSizeReply(ClientPtr client,xvQueryBestSizeReply * rep)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
SWriteQueryPortAttributesReply(ClientPtr client,xvQueryPortAttributesReply * rep)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
SWriteQueryImageAttributesReply(ClientPtr client,xvQueryImageAttributesReply * rep)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
SWriteListImageFormatsReply(ClientPtr client,xvListImageFormatsReply * rep)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 static int
ProcXvQueryExtension(ClientPtr client)301 ProcXvQueryExtension(ClientPtr client)
302 {
303 xvQueryExtensionReply rep = {
304 .type = X_Reply,
305 .sequenceNumber = client->sequence,
306 .length = 0,
307 .version = XvVersion,
308 .revision = XvRevision
309 };
310
311 /* REQUEST(xvQueryExtensionReq); */
312 REQUEST_SIZE_MATCH(xvQueryExtensionReq);
313
314 _WriteQueryExtensionReply(client, &rep);
315
316 return Success;
317 }
318
319 static int
ProcXvQueryAdaptors(ClientPtr client)320 ProcXvQueryAdaptors(ClientPtr client)
321 {
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;
332
333 REQUEST(xvQueryAdaptorsReq);
334 REQUEST_SIZE_MATCH(xvQueryAdaptorsReq);
335
336 rc = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess);
337 if (rc != Success)
338 return rc;
339
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
349 };
350
351 _WriteQueryAdaptorsReply(client, &rep);
352
353 return Success;
354 }
355
356 rep = (xvQueryAdaptorsReply) {
357 .type = X_Reply,
358 .sequenceNumber = client->sequence,
359 .num_adaptors = pxvs->nAdaptors
360 };
361
362 /* CALCULATE THE TOTAL SIZE OF THE REPLY IN BYTES */
363
364 totalSize = pxvs->nAdaptors * sz_xvAdaptorInfo;
365
366 /* FOR EACH ADPATOR ADD UP THE BYTES FOR ENCODINGS AND FORMATS */
367
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++;
374 }
375
376 rep.length = bytes_to_int32(totalSize);
377
378 _WriteQueryAdaptorsReply(client, &rep);
379
380 na = pxvs->nAdaptors;
381 pa = pxvs->pAdaptors;
382 while (na--) {
383
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;
389
390 _WriteAdaptorInfo(client, &ainfo);
391
392 WriteToClient(client, nameSize, pa->name);
393
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++;
401 }
402
403 pa++;
404
405 }
406
407 return Success;
408 }
409
410 static int
ProcXvQueryEncodings(ClientPtr client)411 ProcXvQueryEncodings(ClientPtr client)
412 {
413 xvEncodingInfo einfo;
414 xvQueryEncodingsReply rep;
415 int totalSize;
416 int nameSize;
417 XvPortPtr pPort;
418 int ne;
419 XvEncodingPtr pe;
420
421 REQUEST(xvQueryEncodingsReq);
422 REQUEST_SIZE_MATCH(xvQueryEncodingsReq);
423
424 VALIDATE_XV_PORT(stuff->port, pPort, DixReadAccess);
425
426 rep = (xvQueryEncodingsReply) {
427 .type = X_Reply,
428 .sequenceNumber = client->sequence,
429 .num_encodings = pPort->pAdaptor->nEncodings
430 };
431
432 /* FOR EACH ENCODING ADD UP THE BYTES FOR ENCODING NAMES */
433
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++;
440 }
441
442 rep.length = bytes_to_int32(totalSize);
443
444 _WriteQueryEncodingsReply(client, &rep);
445
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++;
458 }
459
460 return Success;
461 }
462
463 static int
ProcXvPutVideo(ClientPtr client)464 ProcXvPutVideo(ClientPtr client)
465 {
466 DrawablePtr pDraw;
467 XvPortPtr pPort;
468 GCPtr pGC;
469 int status;
470
471 REQUEST(xvPutVideoReq);
472 REQUEST_SIZE_MATCH(xvPutVideoReq);
473
474 VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess);
475 VALIDATE_XV_PORT(stuff->port, pPort, DixReadAccess);
476
477 if (!(pPort->pAdaptor->type & XvInputMask) ||
478 !(pPort->pAdaptor->type & XvVideoMask)) {
479 client->errorValue = stuff->port;
480 return BadMatch;
481 }
482
483 status = XvdiMatchPort(pPort, pDraw);
484 if (status != Success) {
485 return status;
486 }
487
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);
491 }
492
493 static int
ProcXvPutStill(ClientPtr client)494 ProcXvPutStill(ClientPtr client)
495 {
496 DrawablePtr pDraw;
497 XvPortPtr pPort;
498 GCPtr pGC;
499 int status;
500
501 REQUEST(xvPutStillReq);
502 REQUEST_SIZE_MATCH(xvPutStillReq);
503
504 VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess);
505 VALIDATE_XV_PORT(stuff->port, pPort, DixReadAccess);
506
507 if (!(pPort->pAdaptor->type & XvInputMask) ||
508 !(pPort->pAdaptor->type & XvStillMask)) {
509 client->errorValue = stuff->port;
510 return BadMatch;
511 }
512
513 status = XvdiMatchPort(pPort, pDraw);
514 if (status != Success) {
515 return status;
516 }
517
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);
521 }
522
523 static int
ProcXvGetVideo(ClientPtr client)524 ProcXvGetVideo(ClientPtr client)
525 {
526 DrawablePtr pDraw;
527 XvPortPtr pPort;
528 GCPtr pGC;
529 int status;
530
531 REQUEST(xvGetVideoReq);
532 REQUEST_SIZE_MATCH(xvGetVideoReq);
533
534 VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixReadAccess);
535 VALIDATE_XV_PORT(stuff->port, pPort, DixReadAccess);
536
537 if (!(pPort->pAdaptor->type & XvOutputMask) ||
538 !(pPort->pAdaptor->type & XvVideoMask)) {
539 client->errorValue = stuff->port;
540 return BadMatch;
541 }
542
543 status = XvdiMatchPort(pPort, pDraw);
544 if (status != Success) {
545 return status;
546 }
547
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);
551 }
552
553 static int
ProcXvGetStill(ClientPtr client)554 ProcXvGetStill(ClientPtr client)
555 {
556 DrawablePtr pDraw;
557 XvPortPtr pPort;
558 GCPtr pGC;
559 int status;
560
561 REQUEST(xvGetStillReq);
562 REQUEST_SIZE_MATCH(xvGetStillReq);
563
564 VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixReadAccess);
565 VALIDATE_XV_PORT(stuff->port, pPort, DixReadAccess);
566
567 if (!(pPort->pAdaptor->type & XvOutputMask) ||
568 !(pPort->pAdaptor->type & XvStillMask)) {
569 client->errorValue = stuff->port;
570 return BadMatch;
571 }
572
573 status = XvdiMatchPort(pPort, pDraw);
574 if (status != Success) {
575 return status;
576 }
577
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);
581 }
582
583 static int
ProcXvSelectVideoNotify(ClientPtr client)584 ProcXvSelectVideoNotify(ClientPtr client)
585 {
586 DrawablePtr pDraw;
587 int rc;
588
589 REQUEST(xvSelectVideoNotifyReq);
590 REQUEST_SIZE_MATCH(xvSelectVideoNotifyReq);
591
592 rc = dixLookupDrawable(&pDraw, stuff->drawable, client, 0,
593 DixReceiveAccess);
594 if (rc != Success)
595 return rc;
596
597 return XvdiSelectVideoNotify(client, pDraw, stuff->onoff);
598 }
599
600 static int
ProcXvSelectPortNotify(ClientPtr client)601 ProcXvSelectPortNotify(ClientPtr client)
602 {
603 XvPortPtr pPort;
604
605 REQUEST(xvSelectPortNotifyReq);
606 REQUEST_SIZE_MATCH(xvSelectPortNotifyReq);
607
608 VALIDATE_XV_PORT(stuff->port, pPort, DixReadAccess);
609
610 return XvdiSelectPortNotify(client, pPort, stuff->onoff);
611 }
612
613 static int
ProcXvGrabPort(ClientPtr client)614 ProcXvGrabPort(ClientPtr client)
615 {
616 int result, status;
617 XvPortPtr pPort;
618 xvGrabPortReply rep;
619
620 REQUEST(xvGrabPortReq);
621 REQUEST_SIZE_MATCH(xvGrabPortReq);
622
623 VALIDATE_XV_PORT(stuff->port, pPort, DixReadAccess);
624
625 status = XvdiGrabPort(client, pPort, stuff->time, &result);
626
627 if (status != Success) {
628 return status;
629 }
630 rep = (xvGrabPortReply) {
631 .type = X_Reply,
632 .sequenceNumber = client->sequence,
633 .length = 0,
634 .result = result
635 };
636
637 _WriteGrabPortReply(client, &rep);
638
639 return Success;
640 }
641
642 static int
ProcXvUngrabPort(ClientPtr client)643 ProcXvUngrabPort(ClientPtr client)
644 {
645 XvPortPtr pPort;
646
647 REQUEST(xvGrabPortReq);
648 REQUEST_SIZE_MATCH(xvGrabPortReq);
649
650 VALIDATE_XV_PORT(stuff->port, pPort, DixReadAccess);
651
652 return XvdiUngrabPort(client, pPort, stuff->time);
653 }
654
655 static int
ProcXvStopVideo(ClientPtr client)656 ProcXvStopVideo(ClientPtr client)
657 {
658 int ret;
659 DrawablePtr pDraw;
660 XvPortPtr pPort;
661
662 REQUEST(xvStopVideoReq);
663 REQUEST_SIZE_MATCH(xvStopVideoReq);
664
665 VALIDATE_XV_PORT(stuff->port, pPort, DixReadAccess);
666
667 ret = dixLookupDrawable(&pDraw, stuff->drawable, client, 0, DixWriteAccess);
668 if (ret != Success)
669 return ret;
670
671 return XvdiStopVideo(client, pPort, pDraw);
672 }
673
674 static int
ProcXvSetPortAttribute(ClientPtr client)675 ProcXvSetPortAttribute(ClientPtr client)
676 {
677 int status;
678 XvPortPtr pPort;
679
680 REQUEST(xvSetPortAttributeReq);
681 REQUEST_SIZE_MATCH(xvSetPortAttributeReq);
682
683 VALIDATE_XV_PORT(stuff->port, pPort, DixSetAttrAccess);
684
685 if (!ValidAtom(stuff->attribute)) {
686 client->errorValue = stuff->attribute;
687 return BadAtom;
688 }
689
690 status =
691 XvdiSetPortAttribute(client, pPort, stuff->attribute, stuff->value);
692
693 if (status == BadMatch)
694 client->errorValue = stuff->attribute;
695 else
696 client->errorValue = stuff->value;
697
698 return status;
699 }
700
701 static int
ProcXvGetPortAttribute(ClientPtr client)702 ProcXvGetPortAttribute(ClientPtr client)
703 {
704 INT32 value;
705 int status;
706 XvPortPtr pPort;
707 xvGetPortAttributeReply rep;
708
709 REQUEST(xvGetPortAttributeReq);
710 REQUEST_SIZE_MATCH(xvGetPortAttributeReq);
711
712 VALIDATE_XV_PORT(stuff->port, pPort, DixGetAttrAccess);
713
714 if (!ValidAtom(stuff->attribute)) {
715 client->errorValue = stuff->attribute;
716 return BadAtom;
717 }
718
719 status = XvdiGetPortAttribute(client, pPort, stuff->attribute, &value);
720 if (status != Success) {
721 client->errorValue = stuff->attribute;
722 return status;
723 }
724
725 rep = (xvGetPortAttributeReply) {
726 .type = X_Reply,
727 .sequenceNumber = client->sequence,
728 .length = 0,
729 .value = value
730 };
731
732 _WriteGetPortAttributeReply(client, &rep);
733
734 return Success;
735 }
736
737 static int
ProcXvQueryBestSize(ClientPtr client)738 ProcXvQueryBestSize(ClientPtr client)
739 {
740 unsigned int actual_width, actual_height;
741 XvPortPtr pPort;
742 xvQueryBestSizeReply rep;
743
744 REQUEST(xvQueryBestSizeReq);
745 REQUEST_SIZE_MATCH(xvQueryBestSizeReq);
746
747 VALIDATE_XV_PORT(stuff->port, pPort, DixReadAccess);
748
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);
753
754 rep = (xvQueryBestSizeReply) {
755 .type = X_Reply,
756 .sequenceNumber = client->sequence,
757 .length = 0,
758 .actual_width = actual_width,
759 .actual_height = actual_height
760 };
761
762 _WriteQueryBestSizeReply(client, &rep);
763
764 return Success;
765 }
766
767 static int
ProcXvQueryPortAttributes(ClientPtr client)768 ProcXvQueryPortAttributes(ClientPtr client)
769 {
770 int size, i;
771 XvPortPtr pPort;
772 XvAttributePtr pAtt;
773 xvQueryPortAttributesReply rep;
774 xvAttributeInfo Info;
775
776 REQUEST(xvQueryPortAttributesReq);
777 REQUEST_SIZE_MATCH(xvQueryPortAttributesReq);
778
779 VALIDATE_XV_PORT(stuff->port, pPort, DixGetAttrAccess);
780
781 rep = (xvQueryPortAttributesReply) {
782 .type = X_Reply,
783 .sequenceNumber = client->sequence,
784 .num_attributes = pPort->pAdaptor->nAttributes,
785 .text_size = 0
786 };
787
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);
791 }
792
793 rep.length = (pPort->pAdaptor->nAttributes * sz_xvAttributeInfo)
794 + rep.text_size;
795 rep.length >>= 2;
796
797 _WriteQueryPortAttributesReply(client, &rep);
798
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);
806
807 _WriteAttributeInfo(client, &Info);
808
809 WriteToClient(client, size, pAtt->name);
810 }
811
812 return Success;
813 }
814
815 static int
ProcXvPutImage(ClientPtr client)816 ProcXvPutImage(ClientPtr client)
817 {
818 DrawablePtr pDraw;
819 XvPortPtr pPort;
820 XvImagePtr pImage = NULL;
821 GCPtr pGC;
822 int status, i, size;
823 CARD16 width, height;
824
825 REQUEST(xvPutImageReq);
826 REQUEST_AT_LEAST_SIZE(xvPutImageReq);
827
828 VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess);
829 VALIDATE_XV_PORT(stuff->port, pPort, DixReadAccess);
830
831 if (!(pPort->pAdaptor->type & XvImageMask) ||
832 !(pPort->pAdaptor->type & XvInputMask)) {
833 client->errorValue = stuff->port;
834 return BadMatch;
835 }
836
837 status = XvdiMatchPort(pPort, pDraw);
838 if (status != Success) {
839 return status;
840 }
841
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;
846 }
847 }
848
849 if (!pImage)
850 return BadMatch;
851
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);
858
859 if ((width < stuff->width) || (height < stuff->height))
860 return BadValue;
861
862 if (client->req_len < size)
863 return BadLength;
864
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);
870 }
871
872 #ifdef MITSHM
873
874 static int
ProcXvShmPutImage(ClientPtr client)875 ProcXvShmPutImage(ClientPtr client)
876 {
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;
884
885 REQUEST(xvShmPutImageReq);
886 REQUEST_SIZE_MATCH(xvShmPutImageReq);
887
888 VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess);
889 VALIDATE_XV_PORT(stuff->port, pPort, DixReadAccess);
890
891 if (!(pPort->pAdaptor->type & XvImageMask) ||
892 !(pPort->pAdaptor->type & XvInputMask)) {
893 client->errorValue = stuff->port;
894 return BadMatch;
895 }
896
897 status = XvdiMatchPort(pPort, pDraw);
898 if (status != Success) {
899 return status;
900 }
901
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;
906 }
907 }
908
909 if (!pImage)
910 return BadMatch;
911
912 status = dixLookupResourceByType((void **) &shmdesc, stuff->shmseg,
913 ShmSegType, serverClient, DixReadAccess);
914 if (status != Success)
915 return status;
916
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;
924
925 if ((width < stuff->width) || (height < stuff->height))
926 return BadValue;
927
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);
933
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
942 };
943 WriteEventsToClient(client, 1, (xEvent *) &ev);
944 }
945
946 return status;
947 }
948 #else /* !MITSHM */
949 static int
ProcXvShmPutImage(ClientPtr client)950 ProcXvShmPutImage(ClientPtr client)
951 {
952 return BadImplementation;
953 }
954 #endif
955
956 #ifdef XvMCExtension
957 #include "xvmcext.h"
958 #endif
959
960 static int
ProcXvQueryImageAttributes(ClientPtr client)961 ProcXvQueryImageAttributes(ClientPtr client)
962 {
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;
971
972 REQUEST(xvQueryImageAttributesReq);
973
974 REQUEST_SIZE_MATCH(xvQueryImageAttributesReq);
975
976 VALIDATE_XV_PORT(stuff->port, pPort, DixReadAccess);
977
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;
982 }
983 }
984
985 #ifdef XvMCExtension
986 if (!pImage)
987 pImage = XvMCFindXvImage(pPort, stuff->id);
988 #endif
989
990 if (!pImage)
991 return BadMatch;
992
993 num_planes = pImage->num_planes;
994
995 if (!(offsets = malloc(num_planes << 3)))
996 return BadAlloc;
997 pitches = offsets + num_planes;
998
999 width = stuff->width;
1000 height = stuff->height;
1001
1002 size = (*pPort->pAdaptor->ddQueryImageAttributes) (pPort, pImage,
1003 &width, &height, offsets,
1004 pitches);
1005
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
1014 };
1015
1016 _WriteQueryImageAttributesReply(client, &rep);
1017 if (client->swapped)
1018 SwapLongs((CARD32 *) offsets, planeLength);
1019 WriteToClient(client, planeLength << 2, offsets);
1020
1021 free(offsets);
1022
1023 return Success;
1024 }
1025
1026 static int
ProcXvListImageFormats(ClientPtr client)1027 ProcXvListImageFormats(ClientPtr client)
1028 {
1029 XvPortPtr pPort;
1030 XvImagePtr pImage;
1031 int i;
1032 xvListImageFormatsReply rep;
1033 xvImageFormatInfo info;
1034
1035 REQUEST(xvListImageFormatsReq);
1036
1037 REQUEST_SIZE_MATCH(xvListImageFormatsReq);
1038
1039 VALIDATE_XV_PORT(stuff->port, pPort, DixReadAccess);
1040
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)
1047 };
1048
1049 _WriteListImageFormatsReply(client, &rep);
1050
1051 pImage = pPort->pAdaptor->pImages;
1052
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);
1077 }
1078
1079 return Success;
1080 }
1081
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,};
1101
1102 int
ProcXvDispatch(ClientPtr client)1103 ProcXvDispatch(ClientPtr client)
1104 {
1105 REQUEST(xReq);
1106
1107 UpdateCurrentTime();
1108
1109 if (stuff->data >= xvNumRequests) {
1110 return BadRequest;
1111 }
1112
1113 return XvProcVector[stuff->data] (client);
1114 }
1115
1116 /* Swapped Procs */
1117
1118 static int _X_COLD
SProcXvQueryExtension(ClientPtr client)1119 SProcXvQueryExtension(ClientPtr client)
1120 {
1121 REQUEST(xvQueryExtensionReq);
1122 REQUEST_SIZE_MATCH(xvQueryExtensionReq);
1123 swaps(&stuff->length);
1124 return XvProcVector[xv_QueryExtension] (client);
1125 }
1126
1127 static int _X_COLD
SProcXvQueryAdaptors(ClientPtr client)1128 SProcXvQueryAdaptors(ClientPtr client)
1129 {
1130 REQUEST(xvQueryAdaptorsReq);
1131 REQUEST_SIZE_MATCH(xvQueryAdaptorsReq);
1132 swaps(&stuff->length);
1133 swapl(&stuff->window);
1134 return XvProcVector[xv_QueryAdaptors] (client);
1135 }
1136
1137 static int _X_COLD
SProcXvQueryEncodings(ClientPtr client)1138 SProcXvQueryEncodings(ClientPtr client)
1139 {
1140 REQUEST(xvQueryEncodingsReq);
1141 REQUEST_SIZE_MATCH(xvQueryEncodingsReq);
1142 swaps(&stuff->length);
1143 swapl(&stuff->port);
1144 return XvProcVector[xv_QueryEncodings] (client);
1145 }
1146
1147 static int _X_COLD
SProcXvGrabPort(ClientPtr client)1148 SProcXvGrabPort(ClientPtr client)
1149 {
1150 REQUEST(xvGrabPortReq);
1151 REQUEST_SIZE_MATCH(xvGrabPortReq);
1152 swaps(&stuff->length);
1153 swapl(&stuff->port);
1154 swapl(&stuff->time);
1155 return XvProcVector[xv_GrabPort] (client);
1156 }
1157
1158 static int _X_COLD
SProcXvUngrabPort(ClientPtr client)1159 SProcXvUngrabPort(ClientPtr client)
1160 {
1161 REQUEST(xvUngrabPortReq);
1162 REQUEST_SIZE_MATCH(xvUngrabPortReq);
1163 swaps(&stuff->length);
1164 swapl(&stuff->port);
1165 swapl(&stuff->time);
1166 return XvProcVector[xv_UngrabPort] (client);
1167 }
1168
1169 static int _X_COLD
SProcXvPutVideo(ClientPtr client)1170 SProcXvPutVideo(ClientPtr client)
1171 {
1172 REQUEST(xvPutVideoReq);
1173 REQUEST_SIZE_MATCH(xvPutVideoReq);
1174 swaps(&stuff->length);
1175 swapl(&stuff->port);
1176 swapl(&stuff->drawable);
1177 swapl(&stuff->gc);
1178 swaps(&stuff->vid_x);
1179 swaps(&stuff->vid_y);
1180 swaps(&stuff->vid_w);
1181 swaps(&stuff->vid_h);
1182 swaps(&stuff->drw_x);
1183 swaps(&stuff->drw_y);
1184 swaps(&stuff->drw_w);
1185 swaps(&stuff->drw_h);
1186 return XvProcVector[xv_PutVideo] (client);
1187 }
1188
1189 static int _X_COLD
SProcXvPutStill(ClientPtr client)1190 SProcXvPutStill(ClientPtr client)
1191 {
1192 REQUEST(xvPutStillReq);
1193 REQUEST_SIZE_MATCH(xvPutStillReq);
1194 swaps(&stuff->length);
1195 swapl(&stuff->port);
1196 swapl(&stuff->drawable);
1197 swapl(&stuff->gc);
1198 swaps(&stuff->vid_x);
1199 swaps(&stuff->vid_y);
1200 swaps(&stuff->vid_w);
1201 swaps(&stuff->vid_h);
1202 swaps(&stuff->drw_x);
1203 swaps(&stuff->drw_y);
1204 swaps(&stuff->drw_w);
1205 swaps(&stuff->drw_h);
1206 return XvProcVector[xv_PutStill] (client);
1207 }
1208
1209 static int _X_COLD
SProcXvGetVideo(ClientPtr client)1210 SProcXvGetVideo(ClientPtr client)
1211 {
1212 REQUEST(xvGetVideoReq);
1213 REQUEST_SIZE_MATCH(xvGetVideoReq);
1214 swaps(&stuff->length);
1215 swapl(&stuff->port);
1216 swapl(&stuff->drawable);
1217 swapl(&stuff->gc);
1218 swaps(&stuff->vid_x);
1219 swaps(&stuff->vid_y);
1220 swaps(&stuff->vid_w);
1221 swaps(&stuff->vid_h);
1222 swaps(&stuff->drw_x);
1223 swaps(&stuff->drw_y);
1224 swaps(&stuff->drw_w);
1225 swaps(&stuff->drw_h);
1226 return XvProcVector[xv_GetVideo] (client);
1227 }
1228
1229 static int _X_COLD
SProcXvGetStill(ClientPtr client)1230 SProcXvGetStill(ClientPtr client)
1231 {
1232 REQUEST(xvGetStillReq);
1233 REQUEST_SIZE_MATCH(xvGetStillReq);
1234 swaps(&stuff->length);
1235 swapl(&stuff->port);
1236 swapl(&stuff->drawable);
1237 swapl(&stuff->gc);
1238 swaps(&stuff->vid_x);
1239 swaps(&stuff->vid_y);
1240 swaps(&stuff->vid_w);
1241 swaps(&stuff->vid_h);
1242 swaps(&stuff->drw_x);
1243 swaps(&stuff->drw_y);
1244 swaps(&stuff->drw_w);
1245 swaps(&stuff->drw_h);
1246 return XvProcVector[xv_GetStill] (client);
1247 }
1248
1249 static int _X_COLD
SProcXvPutImage(ClientPtr client)1250 SProcXvPutImage(ClientPtr client)
1251 {
1252 REQUEST(xvPutImageReq);
1253 REQUEST_AT_LEAST_SIZE(xvPutImageReq);
1254 swaps(&stuff->length);
1255 swapl(&stuff->port);
1256 swapl(&stuff->drawable);
1257 swapl(&stuff->gc);
1258 swapl(&stuff->id);
1259 swaps(&stuff->src_x);
1260 swaps(&stuff->src_y);
1261 swaps(&stuff->src_w);
1262 swaps(&stuff->src_h);
1263 swaps(&stuff->drw_x);
1264 swaps(&stuff->drw_y);
1265 swaps(&stuff->drw_w);
1266 swaps(&stuff->drw_h);
1267 swaps(&stuff->width);
1268 swaps(&stuff->height);
1269 return XvProcVector[xv_PutImage] (client);
1270 }
1271
1272 #ifdef MITSHM
1273 static int _X_COLD
SProcXvShmPutImage(ClientPtr client)1274 SProcXvShmPutImage(ClientPtr client)
1275 {
1276 REQUEST(xvShmPutImageReq);
1277 REQUEST_SIZE_MATCH(xvShmPutImageReq);
1278 swaps(&stuff->length);
1279 swapl(&stuff->port);
1280 swapl(&stuff->drawable);
1281 swapl(&stuff->gc);
1282 swapl(&stuff->shmseg);
1283 swapl(&stuff->id);
1284 swapl(&stuff->offset);
1285 swaps(&stuff->src_x);
1286 swaps(&stuff->src_y);
1287 swaps(&stuff->src_w);
1288 swaps(&stuff->src_h);
1289 swaps(&stuff->drw_x);
1290 swaps(&stuff->drw_y);
1291 swaps(&stuff->drw_w);
1292 swaps(&stuff->drw_h);
1293 swaps(&stuff->width);
1294 swaps(&stuff->height);
1295 return XvProcVector[xv_ShmPutImage] (client);
1296 }
1297 #else /* MITSHM */
1298 #define SProcXvShmPutImage ProcXvShmPutImage
1299 #endif
1300
1301 static int _X_COLD
SProcXvSelectVideoNotify(ClientPtr client)1302 SProcXvSelectVideoNotify(ClientPtr client)
1303 {
1304 REQUEST(xvSelectVideoNotifyReq);
1305 REQUEST_SIZE_MATCH(xvSelectVideoNotifyReq);
1306 swaps(&stuff->length);
1307 swapl(&stuff->drawable);
1308 return XvProcVector[xv_SelectVideoNotify] (client);
1309 }
1310
1311 static int _X_COLD
SProcXvSelectPortNotify(ClientPtr client)1312 SProcXvSelectPortNotify(ClientPtr client)
1313 {
1314 REQUEST(xvSelectPortNotifyReq);
1315 REQUEST_SIZE_MATCH(xvSelectPortNotifyReq);
1316 swaps(&stuff->length);
1317 swapl(&stuff->port);
1318 return XvProcVector[xv_SelectPortNotify] (client);
1319 }
1320
1321 static int _X_COLD
SProcXvStopVideo(ClientPtr client)1322 SProcXvStopVideo(ClientPtr client)
1323 {
1324 REQUEST(xvStopVideoReq);
1325 REQUEST_SIZE_MATCH(xvStopVideoReq);
1326 swaps(&stuff->length);
1327 swapl(&stuff->port);
1328 swapl(&stuff->drawable);
1329 return XvProcVector[xv_StopVideo] (client);
1330 }
1331
1332 static int _X_COLD
SProcXvSetPortAttribute(ClientPtr client)1333 SProcXvSetPortAttribute(ClientPtr client)
1334 {
1335 REQUEST(xvSetPortAttributeReq);
1336 REQUEST_SIZE_MATCH(xvSetPortAttributeReq);
1337 swaps(&stuff->length);
1338 swapl(&stuff->port);
1339 swapl(&stuff->attribute);
1340 swapl(&stuff->value);
1341 return XvProcVector[xv_SetPortAttribute] (client);
1342 }
1343
1344 static int _X_COLD
SProcXvGetPortAttribute(ClientPtr client)1345 SProcXvGetPortAttribute(ClientPtr client)
1346 {
1347 REQUEST(xvGetPortAttributeReq);
1348 REQUEST_SIZE_MATCH(xvGetPortAttributeReq);
1349 swaps(&stuff->length);
1350 swapl(&stuff->port);
1351 swapl(&stuff->attribute);
1352 return XvProcVector[xv_GetPortAttribute] (client);
1353 }
1354
1355 static int _X_COLD
SProcXvQueryBestSize(ClientPtr client)1356 SProcXvQueryBestSize(ClientPtr client)
1357 {
1358 REQUEST(xvQueryBestSizeReq);
1359 REQUEST_SIZE_MATCH(xvQueryBestSizeReq);
1360 swaps(&stuff->length);
1361 swapl(&stuff->port);
1362 swaps(&stuff->vid_w);
1363 swaps(&stuff->vid_h);
1364 swaps(&stuff->drw_w);
1365 swaps(&stuff->drw_h);
1366 return XvProcVector[xv_QueryBestSize] (client);
1367 }
1368
1369 static int _X_COLD
SProcXvQueryPortAttributes(ClientPtr client)1370 SProcXvQueryPortAttributes(ClientPtr client)
1371 {
1372 REQUEST(xvQueryPortAttributesReq);
1373 REQUEST_SIZE_MATCH(xvQueryPortAttributesReq);
1374 swaps(&stuff->length);
1375 swapl(&stuff->port);
1376 return XvProcVector[xv_QueryPortAttributes] (client);
1377 }
1378
1379 static int _X_COLD
SProcXvQueryImageAttributes(ClientPtr client)1380 SProcXvQueryImageAttributes(ClientPtr client)
1381 {
1382 REQUEST(xvQueryImageAttributesReq);
1383 REQUEST_SIZE_MATCH(xvQueryImageAttributesReq);
1384 swaps(&stuff->length);
1385 swapl(&stuff->port);
1386 swapl(&stuff->id);
1387 swaps(&stuff->width);
1388 swaps(&stuff->height);
1389 return XvProcVector[xv_QueryImageAttributes] (client);
1390 }
1391
1392 static int _X_COLD
SProcXvListImageFormats(ClientPtr client)1393 SProcXvListImageFormats(ClientPtr client)
1394 {
1395 REQUEST(xvListImageFormatsReq);
1396 REQUEST_SIZE_MATCH(xvListImageFormatsReq);
1397 swaps(&stuff->length);
1398 swapl(&stuff->port);
1399 return XvProcVector[xv_ListImageFormats] (client);
1400 }
1401
1402 static int (*SXvProcVector[xvNumRequests]) (ClientPtr) = {
1403 SProcXvQueryExtension,
1404 SProcXvQueryAdaptors,
1405 SProcXvQueryEncodings,
1406 SProcXvGrabPort,
1407 SProcXvUngrabPort,
1408 SProcXvPutVideo,
1409 SProcXvPutStill,
1410 SProcXvGetVideo,
1411 SProcXvGetStill,
1412 SProcXvStopVideo,
1413 SProcXvSelectVideoNotify,
1414 SProcXvSelectPortNotify,
1415 SProcXvQueryBestSize,
1416 SProcXvSetPortAttribute,
1417 SProcXvGetPortAttribute,
1418 SProcXvQueryPortAttributes,
1419 SProcXvListImageFormats,
1420 SProcXvQueryImageAttributes, SProcXvPutImage, SProcXvShmPutImage,};
1421
1422 int _X_COLD
SProcXvDispatch(ClientPtr client)1423 SProcXvDispatch(ClientPtr client)
1424 {
1425 REQUEST(xReq);
1426
1427 UpdateCurrentTime();
1428
1429 if (stuff->data >= xvNumRequests) {
1430 return BadRequest;
1431 }
1432
1433 return SXvProcVector[stuff->data] (client);
1434 }
1435
1436 #ifdef PANORAMIX
1437 static int
XineramaXvStopVideo(ClientPtr client)1438 XineramaXvStopVideo(ClientPtr client)
1439 {
1440 int result, i;
1441 PanoramiXRes *draw, *port;
1442
1443 REQUEST(xvStopVideoReq);
1444 REQUEST_SIZE_MATCH(xvStopVideoReq);
1445
1446 result = dixLookupResourceByClass((void **) &draw, stuff->drawable,
1447 XRC_DRAWABLE, client, DixWriteAccess);
1448 if (result != Success)
1449 return (result == BadValue) ? BadDrawable : result;
1450
1451 result = dixLookupResourceByType((void **) &port, stuff->port,
1452 XvXRTPort, client, DixReadAccess);
1453 if (result != Success)
1454 return result;
1455
1456 FOR_NSCREENS_BACKWARD(i) {
1457 if (port->info[i].id) {
1458 stuff->drawable = draw->info[i].id;
1459 stuff->port = port->info[i].id;
1460 result = ProcXvStopVideo(client);
1461 }
1462 }
1463
1464 return result;
1465 }
1466
1467 static int
XineramaXvSetPortAttribute(ClientPtr client)1468 XineramaXvSetPortAttribute(ClientPtr client)
1469 {
1470 REQUEST(xvSetPortAttributeReq);
1471 PanoramiXRes *port;
1472 int result, i;
1473
1474 REQUEST_SIZE_MATCH(xvSetPortAttributeReq);
1475
1476 result = dixLookupResourceByType((void **) &port, stuff->port,
1477 XvXRTPort, client, DixReadAccess);
1478 if (result != Success)
1479 return result;
1480
1481 FOR_NSCREENS_BACKWARD(i) {
1482 if (port->info[i].id) {
1483 stuff->port = port->info[i].id;
1484 result = ProcXvSetPortAttribute(client);
1485 }
1486 }
1487 return result;
1488 }
1489
1490 #ifdef MITSHM
1491 static int
XineramaXvShmPutImage(ClientPtr client)1492 XineramaXvShmPutImage(ClientPtr client)
1493 {
1494 REQUEST(xvShmPutImageReq);
1495 PanoramiXRes *draw, *gc, *port;
1496 Bool send_event;
1497 Bool isRoot;
1498 int result, i, x, y;
1499
1500 REQUEST_SIZE_MATCH(xvShmPutImageReq);
1501
1502 send_event = stuff->send_event;
1503
1504 result = dixLookupResourceByClass((void **) &draw, stuff->drawable,
1505 XRC_DRAWABLE, client, DixWriteAccess);
1506 if (result != Success)
1507 return (result == BadValue) ? BadDrawable : result;
1508
1509 result = dixLookupResourceByType((void **) &gc, stuff->gc,
1510 XRT_GC, client, DixReadAccess);
1511 if (result != Success)
1512 return result;
1513
1514 result = dixLookupResourceByType((void **) &port, stuff->port,
1515 XvXRTPort, client, DixReadAccess);
1516 if (result != Success)
1517 return result;
1518
1519 isRoot = (draw->type == XRT_WINDOW) && draw->u.win.root;
1520
1521 x = stuff->drw_x;
1522 y = stuff->drw_y;
1523
1524 FOR_NSCREENS_BACKWARD(i) {
1525 if (port->info[i].id) {
1526 stuff->drawable = draw->info[i].id;
1527 stuff->port = port->info[i].id;
1528 stuff->gc = gc->info[i].id;
1529 stuff->drw_x = x;
1530 stuff->drw_y = y;
1531 if (isRoot) {
1532 stuff->drw_x -= screenInfo.screens[i]->x;
1533 stuff->drw_y -= screenInfo.screens[i]->y;
1534 }
1535 stuff->send_event = (send_event && !i) ? 1 : 0;
1536
1537 result = ProcXvShmPutImage(client);
1538 }
1539 }
1540 return result;
1541 }
1542 #else
1543 #define XineramaXvShmPutImage ProcXvShmPutImage
1544 #endif
1545
1546 static int
XineramaXvPutImage(ClientPtr client)1547 XineramaXvPutImage(ClientPtr client)
1548 {
1549 REQUEST(xvPutImageReq);
1550 PanoramiXRes *draw, *gc, *port;
1551 Bool isRoot;
1552 int result, i, x, y;
1553
1554 REQUEST_AT_LEAST_SIZE(xvPutImageReq);
1555
1556 result = dixLookupResourceByClass((void **) &draw, stuff->drawable,
1557 XRC_DRAWABLE, client, DixWriteAccess);
1558 if (result != Success)
1559 return (result == BadValue) ? BadDrawable : result;
1560
1561 result = dixLookupResourceByType((void **) &gc, stuff->gc,
1562 XRT_GC, client, DixReadAccess);
1563 if (result != Success)
1564 return result;
1565
1566 result = dixLookupResourceByType((void **) &port, stuff->port,
1567 XvXRTPort, client, DixReadAccess);
1568 if (result != Success)
1569 return result;
1570
1571 isRoot = (draw->type == XRT_WINDOW) && draw->u.win.root;
1572
1573 x = stuff->drw_x;
1574 y = stuff->drw_y;
1575
1576 FOR_NSCREENS_BACKWARD(i) {
1577 if (port->info[i].id) {
1578 stuff->drawable = draw->info[i].id;
1579 stuff->port = port->info[i].id;
1580 stuff->gc = gc->info[i].id;
1581 stuff->drw_x = x;
1582 stuff->drw_y = y;
1583 if (isRoot) {
1584 stuff->drw_x -= screenInfo.screens[i]->x;
1585 stuff->drw_y -= screenInfo.screens[i]->y;
1586 }
1587
1588 result = ProcXvPutImage(client);
1589 }
1590 }
1591 return result;
1592 }
1593
1594 static int
XineramaXvPutVideo(ClientPtr client)1595 XineramaXvPutVideo(ClientPtr client)
1596 {
1597 REQUEST(xvPutImageReq);
1598 PanoramiXRes *draw, *gc, *port;
1599 Bool isRoot;
1600 int result, i, x, y;
1601
1602 REQUEST_AT_LEAST_SIZE(xvPutVideoReq);
1603
1604 result = dixLookupResourceByClass((void **) &draw, stuff->drawable,
1605 XRC_DRAWABLE, client, DixWriteAccess);
1606 if (result != Success)
1607 return (result == BadValue) ? BadDrawable : result;
1608
1609 result = dixLookupResourceByType((void **) &gc, stuff->gc,
1610 XRT_GC, client, DixReadAccess);
1611 if (result != Success)
1612 return result;
1613
1614 result = dixLookupResourceByType((void **) &port, stuff->port,
1615 XvXRTPort, client, DixReadAccess);
1616 if (result != Success)
1617 return result;
1618
1619 isRoot = (draw->type == XRT_WINDOW) && draw->u.win.root;
1620
1621 x = stuff->drw_x;
1622 y = stuff->drw_y;
1623
1624 FOR_NSCREENS_BACKWARD(i) {
1625 if (port->info[i].id) {
1626 stuff->drawable = draw->info[i].id;
1627 stuff->port = port->info[i].id;
1628 stuff->gc = gc->info[i].id;
1629 stuff->drw_x = x;
1630 stuff->drw_y = y;
1631 if (isRoot) {
1632 stuff->drw_x -= screenInfo.screens[i]->x;
1633 stuff->drw_y -= screenInfo.screens[i]->y;
1634 }
1635
1636 result = ProcXvPutVideo(client);
1637 }
1638 }
1639 return result;
1640 }
1641
1642 static int
XineramaXvPutStill(ClientPtr client)1643 XineramaXvPutStill(ClientPtr client)
1644 {
1645 REQUEST(xvPutImageReq);
1646 PanoramiXRes *draw, *gc, *port;
1647 Bool isRoot;
1648 int result, i, x, y;
1649
1650 REQUEST_AT_LEAST_SIZE(xvPutImageReq);
1651
1652 result = dixLookupResourceByClass((void **) &draw, stuff->drawable,
1653 XRC_DRAWABLE, client, DixWriteAccess);
1654 if (result != Success)
1655 return (result == BadValue) ? BadDrawable : result;
1656
1657 result = dixLookupResourceByType((void **) &gc, stuff->gc,
1658 XRT_GC, client, DixReadAccess);
1659 if (result != Success)
1660 return result;
1661
1662 result = dixLookupResourceByType((void **) &port, stuff->port,
1663 XvXRTPort, client, DixReadAccess);
1664 if (result != Success)
1665 return result;
1666
1667 isRoot = (draw->type == XRT_WINDOW) && draw->u.win.root;
1668
1669 x = stuff->drw_x;
1670 y = stuff->drw_y;
1671
1672 FOR_NSCREENS_BACKWARD(i) {
1673 if (port->info[i].id) {
1674 stuff->drawable = draw->info[i].id;
1675 stuff->port = port->info[i].id;
1676 stuff->gc = gc->info[i].id;
1677 stuff->drw_x = x;
1678 stuff->drw_y = y;
1679 if (isRoot) {
1680 stuff->drw_x -= screenInfo.screens[i]->x;
1681 stuff->drw_y -= screenInfo.screens[i]->y;
1682 }
1683
1684 result = ProcXvPutStill(client);
1685 }
1686 }
1687 return result;
1688 }
1689
1690 static Bool
isImageAdaptor(XvAdaptorPtr pAdapt)1691 isImageAdaptor(XvAdaptorPtr pAdapt)
1692 {
1693 return (pAdapt->type & XvImageMask) && (pAdapt->nImages > 0);
1694 }
1695
1696 static Bool
hasOverlay(XvAdaptorPtr pAdapt)1697 hasOverlay(XvAdaptorPtr pAdapt)
1698 {
1699 int i;
1700
1701 for (i = 0; i < pAdapt->nAttributes; i++)
1702 if (!strcmp(pAdapt->pAttributes[i].name, "XV_COLORKEY"))
1703 return TRUE;
1704 return FALSE;
1705 }
1706
1707 static XvAdaptorPtr
matchAdaptor(ScreenPtr pScreen,XvAdaptorPtr refAdapt,Bool isOverlay)1708 matchAdaptor(ScreenPtr pScreen, XvAdaptorPtr refAdapt, Bool isOverlay)
1709 {
1710 int i;
1711 XvScreenPtr xvsp =
1712 dixLookupPrivate(&pScreen->devPrivates, XvGetScreenKey());
1713 /* Do not try to go on if xv is not supported on this screen */
1714 if (xvsp == NULL)
1715 return NULL;
1716
1717 /* if the adaptor has the same name it's a perfect match */
1718 for (i = 0; i < xvsp->nAdaptors; i++) {
1719 XvAdaptorPtr pAdapt = xvsp->pAdaptors + i;
1720
1721 if (!strcmp(refAdapt->name, pAdapt->name))
1722 return pAdapt;
1723 }
1724
1725 /* otherwise we only look for XvImage adaptors */
1726 if (!isImageAdaptor(refAdapt))
1727 return NULL;
1728
1729 /* prefer overlay/overlay non-overlay/non-overlay pairing */
1730 for (i = 0; i < xvsp->nAdaptors; i++) {
1731 XvAdaptorPtr pAdapt = xvsp->pAdaptors + i;
1732
1733 if (isImageAdaptor(pAdapt) && isOverlay == hasOverlay(pAdapt))
1734 return pAdapt;
1735 }
1736
1737 /* but we'll take any XvImage pairing if we can get it */
1738 for (i = 0; i < xvsp->nAdaptors; i++) {
1739 XvAdaptorPtr pAdapt = xvsp->pAdaptors + i;
1740
1741 if (isImageAdaptor(pAdapt))
1742 return pAdapt;
1743 }
1744 return NULL;
1745 }
1746
1747 void
XineramifyXv(void)1748 XineramifyXv(void)
1749 {
1750 XvScreenPtr xvsp0 =
1751 dixLookupPrivate(&screenInfo.screens[0]->devPrivates, XvGetScreenKey());
1752 XvAdaptorPtr MatchingAdaptors[MAXSCREENS];
1753 int i, j, k;
1754
1755 XvXRTPort = CreateNewResourceType(XineramaDeleteResource, "XvXRTPort");
1756
1757 if (!xvsp0 || !XvXRTPort)
1758 return;
1759 SetResourceTypeErrorValue(XvXRTPort, _XvBadPort);
1760
1761 for (i = 0; i < xvsp0->nAdaptors; i++) {
1762 Bool isOverlay;
1763 XvAdaptorPtr refAdapt = xvsp0->pAdaptors + i;
1764
1765 if (!(refAdapt->type & XvInputMask))
1766 continue;
1767
1768 MatchingAdaptors[0] = refAdapt;
1769 isOverlay = hasOverlay(refAdapt);
1770 FOR_NSCREENS_FORWARD_SKIP(j)
1771 MatchingAdaptors[j] =
1772 matchAdaptor(screenInfo.screens[j], refAdapt, isOverlay);
1773
1774 /* now create a resource for each port */
1775 for (j = 0; j < refAdapt->nPorts; j++) {
1776 PanoramiXRes *port = malloc(sizeof(PanoramiXRes));
1777
1778 if (!port)
1779 break;
1780
1781 FOR_NSCREENS(k) {
1782 if (MatchingAdaptors[k] && (MatchingAdaptors[k]->nPorts > j))
1783 port->info[k].id = MatchingAdaptors[k]->base_id + j;
1784 else
1785 port->info[k].id = 0;
1786 }
1787 AddResource(port->info[0].id, XvXRTPort, port);
1788 }
1789 }
1790
1791 /* munge the dispatch vector */
1792 XvProcVector[xv_PutVideo] = XineramaXvPutVideo;
1793 XvProcVector[xv_PutStill] = XineramaXvPutStill;
1794 XvProcVector[xv_StopVideo] = XineramaXvStopVideo;
1795 XvProcVector[xv_SetPortAttribute] = XineramaXvSetPortAttribute;
1796 XvProcVector[xv_PutImage] = XineramaXvPutImage;
1797 XvProcVector[xv_ShmPutImage] = XineramaXvShmPutImage;
1798 }
1799 #endif /* PANORAMIX */
1800
1801 void
XvResetProcVector(void)1802 XvResetProcVector(void)
1803 {
1804 #ifdef PANORAMIX
1805 XvProcVector[xv_PutVideo] = ProcXvPutVideo;
1806 XvProcVector[xv_PutStill] = ProcXvPutStill;
1807 XvProcVector[xv_StopVideo] = ProcXvStopVideo;
1808 XvProcVector[xv_SetPortAttribute] = ProcXvSetPortAttribute;
1809 XvProcVector[xv_PutImage] = ProcXvPutImage;
1810 XvProcVector[xv_ShmPutImage] = ProcXvShmPutImage;
1811 #endif
1812 }
1813