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