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/* $XFree86: xc/lib/Xv/Xv.c,v 1.15 2001/05/11 08:23:22 alanh Exp $ */
25/*
26** File:
27**
28**   Xv.c --- Xv library extension module.
29**
30** Author:
31**
32**   David Carver (Digital Workstation Engineering/Project Athena)
33**
34** Revisions:
35**
36**   26.06.91 Carver
37**     - changed XvFreeAdaptors to XvFreeAdaptorInfo
38**     - changed XvFreeEncodings to XvFreeEncodingInfo
39**
40**   11.06.91 Carver
41**     - changed SetPortControl to SetPortAttribute
42**     - changed GetPortControl to GetPortAttribute
43**     - changed QueryBestSize
44**
45**   15.05.91 Carver
46**     - version 2.0 upgrade
47**
48**   240.01.91 Carver
49**     - version 1.4 upgrade
50**
51*/
52
53#include <stdio.h>
54#include "Xvlibint.h"
55#include "../extensions/Xext.h"
56#include <X11/extensions/XShm.h>
57#include "../extensions/extutil.h"
58
59static XExtensionInfo _xv_info_data;
60static XExtensionInfo *xv_info = &_xv_info_data;
61static char *xv_extension_name = XvName;
62
63#define XvCheckExtension(dpy, i, val) \
64  XextCheckExtension(dpy, i, xv_extension_name, val)
65
66static char *xv_error_string();
67static int xv_close_display();
68static Bool xv_wire_to_event();
69
70static XExtensionHooks xv_extension_hooks = {
71    NULL,                               /* create_gc */
72    NULL,                               /* copy_gc */
73    NULL,                               /* flush_gc */
74    NULL,                               /* free_gc */
75    NULL,                               /* create_font */
76    NULL,                               /* free_font */
77    xv_close_display,                   /* close_display */
78    xv_wire_to_event,                   /* wire_to_event */
79    NULL,                               /* event_to_wire */
80    NULL,                               /* error */
81    xv_error_string                     /* error_string */
82};
83
84
85static char *xv_error_list[] =
86{
87   "BadPort",	    /* XvBadPort     */
88   "BadEncoding",   /* XvBadEncoding */
89   "BadControl"     /* XvBadControl  */
90};
91
92static XEXT_GENERATE_CLOSE_DISPLAY (xv_close_display, xv_info)
93
94
95static XEXT_GENERATE_FIND_DISPLAY (xv_find_display, xv_info,
96                                   xv_extension_name,
97                                   &xv_extension_hooks,
98				   XvNumEvents, NULL)
99
100
101static XEXT_GENERATE_ERROR_STRING (xv_error_string, xv_extension_name,
102                                   XvNumErrors, xv_error_list)
103
104
105int
106SDL_NAME(XvQueryExtension)(
107     Display *dpy,
108     unsigned int *p_version,
109     unsigned int *p_revision,
110     unsigned int *p_requestBase,
111     unsigned int *p_eventBase,
112     unsigned int *p_errorBase
113){
114  XExtDisplayInfo *info = xv_find_display(dpy);
115  xvQueryExtensionReq *req;
116  xvQueryExtensionReply rep;
117
118  XvCheckExtension(dpy, info, XvBadExtension);
119
120  LockDisplay(dpy);
121
122  XvGetReq(QueryExtension, req);
123
124  if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
125     UnlockDisplay(dpy);
126     SyncHandle();
127     return XvBadExtension;
128  }
129
130  *p_version = rep.version;
131  *p_revision = rep.revision;
132  *p_requestBase = info->codes->major_opcode;
133  *p_eventBase = info->codes->first_event;
134  *p_errorBase = info->codes->first_error;
135
136  UnlockDisplay(dpy);
137  SyncHandle();
138
139  return Success;
140}
141
142int
143SDL_NAME(XvQueryAdaptors)(
144     Display *dpy,
145     Window window,
146     unsigned int *p_nAdaptors,
147     SDL_NAME(XvAdaptorInfo) **p_pAdaptors
148){
149  XExtDisplayInfo *info = xv_find_display(dpy);
150  xvQueryAdaptorsReq *req;
151  xvQueryAdaptorsReply rep;
152  int size,ii,jj;
153  char *name;
154  SDL_NAME(XvAdaptorInfo) *pas, *pa;
155  SDL_NAME(XvFormat) *pfs, *pf;
156  char *buffer;
157  union
158    {
159      char *buffer;
160      char *string;
161      xvAdaptorInfo *pa;
162      xvFormat *pf;
163    } u;
164
165  XvCheckExtension(dpy, info, XvBadExtension);
166
167  LockDisplay(dpy);
168
169  XvGetReq(QueryAdaptors, req);
170  req->window = window;
171
172  /* READ THE REPLY */
173
174  if (_XReply(dpy, (xReply *)&rep, 0, xFalse) == 0) {
175      UnlockDisplay(dpy);
176      SyncHandle();
177      return(XvBadReply);
178  }
179
180  size = rep.length << 2;
181  if ( (buffer = (char *)Xmalloc ((unsigned) size)) == NULL) {
182      UnlockDisplay(dpy);
183      SyncHandle();
184      return(XvBadAlloc);
185  }
186  _XRead (dpy, buffer, size);
187
188  u.buffer = buffer;
189
190  /* GET INPUT ADAPTORS */
191
192  if (rep.num_adaptors == 0) {
193      pas = NULL;
194  } else {
195      size = rep.num_adaptors*sizeof(SDL_NAME(XvAdaptorInfo));
196      if ((pas=(SDL_NAME(XvAdaptorInfo) *)Xmalloc(size))==NULL) {
197          Xfree(buffer);
198          UnlockDisplay(dpy);
199          SyncHandle();
200          return(XvBadAlloc);
201      }
202  }
203
204  /* INIT ADAPTOR FIELDS */
205
206  pa = pas;
207  for (ii=0; ii<rep.num_adaptors; ii++) {
208      pa->num_adaptors = 0;
209      pa->name = (char *)NULL;
210      pa->formats = (SDL_NAME(XvFormat) *)NULL;
211      pa++;
212  }
213
214  pa = pas;
215  for (ii=0; ii<rep.num_adaptors; ii++) {
216      pa->type = u.pa->type;
217      pa->base_id = u.pa->base_id;
218      pa->num_ports = u.pa->num_ports;
219      pa->num_formats = u.pa->num_formats;
220      pa->num_adaptors = rep.num_adaptors - ii;
221
222      /* GET ADAPTOR NAME */
223
224      size = u.pa->name_size;
225      u.buffer += (sz_xvAdaptorInfo + 3) & ~3;
226
227      if ( (name = (char *)Xmalloc(size+1)) == NULL)
228	{
229	  SDL_NAME(XvFreeAdaptorInfo)(pas);
230	  Xfree(buffer);
231          UnlockDisplay(dpy);
232          SyncHandle();
233	  return(XvBadAlloc);
234	}
235      SDL_strlcpy(name, u.string, size);
236      pa->name = name;
237
238      u.buffer += (size + 3) & ~3;
239
240      /* GET FORMATS */
241
242      size = pa->num_formats*sizeof(SDL_NAME(XvFormat));
243      if ((pfs=(SDL_NAME(XvFormat) *)Xmalloc(size))==NULL) {
244	  SDL_NAME(XvFreeAdaptorInfo)(pas);
245	  Xfree(buffer);
246          UnlockDisplay(dpy);
247          SyncHandle();
248	  return(XvBadAlloc);
249      }
250
251      pf = pfs;
252      for (jj=0; jj<pa->num_formats; jj++) {
253	  pf->depth = u.pf->depth;
254	  pf->visual_id = u.pf->visual;
255	  pf++;
256
257	  u.buffer += (sz_xvFormat + 3) & ~3;
258      }
259
260      pa->formats = pfs;
261
262      pa++;
263
264  }
265
266  *p_nAdaptors = rep.num_adaptors;
267  *p_pAdaptors = pas;
268
269  Xfree(buffer);
270  UnlockDisplay(dpy);
271  SyncHandle();
272
273  return (Success);
274}
275
276
277void
278SDL_NAME(XvFreeAdaptorInfo)(SDL_NAME(XvAdaptorInfo) *pAdaptors)
279{
280
281  SDL_NAME(XvAdaptorInfo) *pa;
282  int ii;
283
284  if (!pAdaptors) return;
285
286  pa = pAdaptors;
287
288  for (ii=0; ii<pAdaptors->num_adaptors; ii++, pa++)
289    {
290      if (pa->name)
291	{
292	  Xfree(pa->name);
293	}
294      if (pa->formats)
295	{
296	  Xfree(pa->formats);
297	}
298    }
299
300  Xfree(pAdaptors);
301}
302
303int
304SDL_NAME(XvQueryEncodings)(
305     Display *dpy,
306     XvPortID port,
307     unsigned int *p_nEncodings,
308     SDL_NAME(XvEncodingInfo) **p_pEncodings
309){
310  XExtDisplayInfo *info = xv_find_display(dpy);
311  xvQueryEncodingsReq *req;
312  xvQueryEncodingsReply rep;
313  int size, jj;
314  char *name;
315  SDL_NAME(XvEncodingInfo) *pes, *pe;
316  char *buffer;
317  union
318    {
319      char *buffer;
320      char *string;
321      xvEncodingInfo *pe;
322    } u;
323
324  XvCheckExtension(dpy, info, XvBadExtension);
325
326  LockDisplay(dpy);
327
328  XvGetReq(QueryEncodings, req);
329  req->port = port;
330
331  /* READ THE REPLY */
332
333  if (_XReply(dpy, (xReply *)&rep, 0, xFalse) == 0) {
334      UnlockDisplay(dpy);
335      SyncHandle();
336      return(XvBadReply);
337  }
338
339  size = rep.length << 2;
340  if ( (buffer = (char *)Xmalloc ((unsigned) size)) == NULL) {
341      UnlockDisplay(dpy);
342      SyncHandle();
343      return(XvBadAlloc);
344  }
345  _XRead (dpy, buffer, size);
346
347  u.buffer = buffer;
348
349  /* GET ENCODINGS */
350
351  size = rep.num_encodings*sizeof(SDL_NAME(XvEncodingInfo));
352  if ( (pes = (SDL_NAME(XvEncodingInfo) *)Xmalloc(size)) == NULL) {
353      Xfree(buffer);
354      UnlockDisplay(dpy);
355      SyncHandle();
356      return(XvBadAlloc);
357  }
358
359  /* INITIALIZE THE ENCODING POINTER */
360
361  pe = pes;
362  for (jj=0; jj<rep.num_encodings; jj++) {
363      pe->name = (char *)NULL;
364      pe->num_encodings = 0;
365      pe++;
366  }
367
368  pe = pes;
369  for (jj=0; jj<rep.num_encodings; jj++) {
370      pe->encoding_id = u.pe->encoding;
371      pe->width = u.pe->width;
372      pe->height = u.pe->height;
373      pe->rate.numerator = u.pe->rate.numerator;
374      pe->rate.denominator = u.pe->rate.denominator;
375      pe->num_encodings = rep.num_encodings - jj;
376
377      size = u.pe->name_size;
378      u.buffer += (sz_xvEncodingInfo + 3) & ~3;
379
380      if ( (name = (char *)Xmalloc(size+1)) == NULL) {
381	  Xfree(buffer);
382          UnlockDisplay(dpy);
383          SyncHandle();
384	  return(XvBadAlloc);
385      }
386      SDL_strlcpy(name, u.string, size);
387      pe->name = name;
388      pe++;
389
390      u.buffer += (size + 3) & ~3;
391  }
392
393  *p_nEncodings = rep.num_encodings;
394  *p_pEncodings = pes;
395
396  Xfree(buffer);
397  UnlockDisplay(dpy);
398  SyncHandle();
399
400  return (Success);
401}
402
403void
404SDL_NAME(XvFreeEncodingInfo)(SDL_NAME(XvEncodingInfo) *pEncodings)
405{
406
407  SDL_NAME(XvEncodingInfo) *pe;
408  int ii;
409
410  if (!pEncodings) return;
411
412  pe = pEncodings;
413
414  for (ii=0; ii<pEncodings->num_encodings; ii++, pe++) {
415      if (pe->name) Xfree(pe->name);
416  }
417
418  Xfree(pEncodings);
419}
420
421int
422SDL_NAME(XvPutVideo)(
423     Display *dpy,
424     XvPortID port,
425     Drawable d,
426     GC gc,
427     int vx, int vy,
428     unsigned int vw, unsigned int vh,
429     int dx, int dy,
430     unsigned int dw, unsigned int dh
431){
432  XExtDisplayInfo *info = xv_find_display(dpy);
433  xvPutVideoReq *req;
434
435  XvCheckExtension(dpy, info, XvBadExtension);
436
437  LockDisplay(dpy);
438
439  FlushGC(dpy, gc);
440
441  XvGetReq(PutVideo, req);
442
443  req->port = port;
444  req->drawable = d;
445  req->gc = gc->gid;
446  req->vid_x = vx;
447  req->vid_y = vy;
448  req->vid_w = vw;
449  req->vid_h = vh;
450  req->drw_x = dx;
451  req->drw_y = dy;
452  req->drw_w = dw;
453  req->drw_h = dh;
454
455  UnlockDisplay(dpy);
456  SyncHandle();
457
458  return Success;
459}
460
461int
462SDL_NAME(XvPutStill)(
463     Display *dpy,
464     XvPortID port,
465     Drawable d,
466     GC gc,
467     int vx, int vy,
468     unsigned int vw, unsigned int vh,
469     int dx, int dy,
470     unsigned int dw, unsigned int dh
471){
472  XExtDisplayInfo *info = xv_find_display(dpy);
473  xvPutStillReq *req;
474
475  XvCheckExtension(dpy, info, XvBadExtension);
476
477  LockDisplay(dpy);
478
479  FlushGC(dpy, gc);
480
481  XvGetReq(PutStill, req);
482  req->port = port;
483  req->drawable = d;
484  req->gc = gc->gid;
485  req->vid_x = vx;
486  req->vid_y = vy;
487  req->vid_w = vw;
488  req->vid_h = vh;
489  req->drw_x = dx;
490  req->drw_y = dy;
491  req->drw_w = dw;
492  req->drw_h = dh;
493
494  UnlockDisplay(dpy);
495  SyncHandle();
496
497  return Success;
498}
499
500int
501SDL_NAME(XvGetVideo)(
502     Display *dpy,
503     XvPortID port,
504     Drawable d,
505     GC gc,
506     int vx, int vy,
507     unsigned int vw, unsigned int vh,
508     int dx, int dy,
509     unsigned int dw, unsigned int dh
510){
511  XExtDisplayInfo *info = xv_find_display(dpy);
512  xvGetVideoReq *req;
513
514  XvCheckExtension(dpy, info, XvBadExtension);
515
516  LockDisplay(dpy);
517
518  FlushGC(dpy, gc);
519
520  XvGetReq(GetVideo, req);
521  req->port = port;
522  req->drawable = d;
523  req->gc = gc->gid;
524  req->vid_x = vx;
525  req->vid_y = vy;
526  req->vid_w = vw;
527  req->vid_h = vh;
528  req->drw_x = dx;
529  req->drw_y = dy;
530  req->drw_w = dw;
531  req->drw_h = dh;
532
533  UnlockDisplay(dpy);
534  SyncHandle();
535
536  return Success;
537}
538
539int
540SDL_NAME(XvGetStill)(
541     Display *dpy,
542     XvPortID port,
543     Drawable d,
544     GC gc,
545     int vx, int vy,
546     unsigned int vw, unsigned int vh,
547     int dx, int dy,
548     unsigned int dw, unsigned int dh
549){
550  XExtDisplayInfo *info = xv_find_display(dpy);
551  xvGetStillReq *req;
552
553  XvCheckExtension(dpy, info, XvBadExtension);
554
555  LockDisplay(dpy);
556
557  FlushGC(dpy, gc);
558
559  XvGetReq(GetStill, req);
560  req->port = port;
561  req->drawable = d;
562  req->gc = gc->gid;
563  req->vid_x = vx;
564  req->vid_y = vy;
565  req->vid_w = vw;
566  req->vid_h = vh;
567  req->drw_x = dx;
568  req->drw_y = dy;
569  req->drw_w = dw;
570  req->drw_h = dh;
571
572  UnlockDisplay(dpy);
573  SyncHandle();
574
575  return Success;
576}
577
578int
579SDL_NAME(XvStopVideo)(
580     Display *dpy,
581     XvPortID port,
582     Drawable draw
583){
584  XExtDisplayInfo *info = xv_find_display(dpy);
585  xvStopVideoReq *req;
586
587  XvCheckExtension(dpy, info, XvBadExtension);
588
589  LockDisplay(dpy);
590
591  XvGetReq(StopVideo, req);
592  req->port = port;
593  req->drawable = draw;
594
595  UnlockDisplay(dpy);
596  SyncHandle();
597
598  return Success;
599}
600
601int
602SDL_NAME(XvGrabPort)(
603     Display *dpy,
604     XvPortID port,
605     Time time
606){
607  XExtDisplayInfo *info = xv_find_display(dpy);
608  int result;
609  xvGrabPortReply rep;
610  xvGrabPortReq *req;
611
612  XvCheckExtension(dpy, info, XvBadExtension);
613
614  LockDisplay(dpy);
615
616  XvGetReq(GrabPort, req);
617  req->port = port;
618  req->time = time;
619
620  if (_XReply (dpy, (xReply *) &rep, 0, xTrue) == 0)
621    rep.result = GrabSuccess;
622
623  result = rep.result;
624
625  UnlockDisplay(dpy);
626  SyncHandle();
627
628  return result;
629}
630
631int
632SDL_NAME(XvUngrabPort)(
633     Display *dpy,
634     XvPortID port,
635     Time time
636){
637  XExtDisplayInfo *info = xv_find_display(dpy);
638  xvUngrabPortReq *req;
639
640  XvCheckExtension(dpy, info, XvBadExtension);
641
642  LockDisplay(dpy);
643
644  XvGetReq(UngrabPort, req);
645  req->port = port;
646  req->time = time;
647
648  UnlockDisplay(dpy);
649  SyncHandle();
650
651  return Success;
652}
653
654int
655SDL_NAME(XvSelectVideoNotify)(
656     Display *dpy,
657     Drawable drawable,
658     Bool onoff
659){
660  XExtDisplayInfo *info = xv_find_display(dpy);
661  xvSelectVideoNotifyReq *req;
662
663  XvCheckExtension(dpy, info, XvBadExtension);
664
665  LockDisplay(dpy);
666
667  XvGetReq(SelectVideoNotify, req);
668  req->drawable = drawable;
669  req->onoff = onoff;
670
671  UnlockDisplay(dpy);
672  SyncHandle();
673
674  return Success;
675}
676
677int
678SDL_NAME(XvSelectPortNotify)(
679     Display *dpy,
680     XvPortID port,
681     Bool onoff
682){
683  XExtDisplayInfo *info = xv_find_display(dpy);
684  xvSelectPortNotifyReq *req;
685
686  XvCheckExtension(dpy, info, XvBadExtension);
687
688  LockDisplay(dpy);
689
690  XvGetReq(SelectPortNotify, req);
691  req->port = port;
692  req->onoff = onoff;
693
694  UnlockDisplay(dpy);
695  SyncHandle();
696
697  return Success;
698}
699
700int
701SDL_NAME(XvSetPortAttribute) (
702     Display *dpy,
703     XvPortID port,
704     Atom attribute,
705     int value
706)
707{
708  XExtDisplayInfo *info = xv_find_display(dpy);
709  xvSetPortAttributeReq *req;
710
711  XvCheckExtension(dpy, info, XvBadExtension);
712
713  LockDisplay(dpy);
714
715  XvGetReq(SetPortAttribute, req);
716  req->port = port;
717  req->attribute = attribute;
718  req->value = value;
719
720  UnlockDisplay(dpy);
721  SyncHandle();
722
723  return (Success);
724}
725
726int
727SDL_NAME(XvGetPortAttribute) (
728     Display *dpy,
729     XvPortID port,
730     Atom attribute,
731     int *p_value
732)
733{
734  XExtDisplayInfo *info = xv_find_display(dpy);
735  xvGetPortAttributeReq *req;
736  xvGetPortAttributeReply rep;
737
738  XvCheckExtension(dpy, info, XvBadExtension);
739
740  LockDisplay(dpy);
741
742  XvGetReq(GetPortAttribute, req);
743  req->port = port;
744  req->attribute = attribute;
745
746  /* READ THE REPLY */
747
748  if (_XReply(dpy, (xReply *)&rep, 0, xFalse) == 0) {
749      UnlockDisplay(dpy);
750      SyncHandle();
751      return(XvBadReply);
752  }
753
754  *p_value = rep.value;
755
756  UnlockDisplay(dpy);
757  SyncHandle();
758
759  return (Success);
760}
761
762int
763SDL_NAME(XvQueryBestSize)(
764     Display *dpy,
765     XvPortID port,
766     Bool motion,
767     unsigned int vid_w,
768     unsigned int vid_h,
769     unsigned int drw_w,
770     unsigned int drw_h,
771     unsigned int *p_actual_width,
772     unsigned int *p_actual_height
773)
774{
775  XExtDisplayInfo *info = xv_find_display(dpy);
776  xvQueryBestSizeReq *req;
777  xvQueryBestSizeReply rep;
778
779  XvCheckExtension(dpy, info, XvBadExtension);
780
781  LockDisplay(dpy);
782
783  XvGetReq(QueryBestSize, req);
784  req->port = port;
785  req->motion = motion;
786  req->vid_w = vid_w;
787  req->vid_h = vid_h;
788  req->drw_w = drw_w;
789  req->drw_h = drw_h;
790
791  /* READ THE REPLY */
792
793  if (_XReply(dpy, (xReply *)&rep, 0, xFalse) == 0) {
794      UnlockDisplay(dpy);
795      SyncHandle();
796      return(XvBadReply);
797  }
798
799  *p_actual_width = rep.actual_width;
800  *p_actual_height = rep.actual_height;
801
802  UnlockDisplay(dpy);
803  SyncHandle();
804
805  return (Success);
806}
807
808
809SDL_NAME(XvAttribute)*
810SDL_NAME(XvQueryPortAttributes)(Display *dpy, XvPortID port, int *num)
811{
812  XExtDisplayInfo *info = xv_find_display(dpy);
813  xvQueryPortAttributesReq *req;
814  xvQueryPortAttributesReply rep;
815  SDL_NAME(XvAttribute) *ret = NULL;
816
817  *num = 0;
818
819  XvCheckExtension(dpy, info, NULL);
820
821  LockDisplay(dpy);
822
823  XvGetReq(QueryPortAttributes, req);
824  req->port = port;
825
826  /* READ THE REPLY */
827
828  if (_XReply(dpy, (xReply *)&rep, 0, xFalse) == 0) {
829      UnlockDisplay(dpy);
830      SyncHandle();
831      return ret;
832  }
833
834  if(rep.num_attributes) {
835      int size = (rep.num_attributes * sizeof(SDL_NAME(XvAttribute))) + rep.text_size;
836
837      if((ret = Xmalloc(size))) {
838	  char* marker = (char*)(&ret[rep.num_attributes]);
839	  xvAttributeInfo Info;
840	  int i;
841
842	  for(i = 0; i < rep.num_attributes; i++) {
843             _XRead(dpy, (char*)(&Info), sz_xvAttributeInfo);
844	      ret[i].flags = (int)Info.flags;
845	      ret[i].min_value = Info.min;
846	      ret[i].max_value = Info.max;
847	      ret[i].name = marker;
848	      _XRead(dpy, marker, Info.size);
849	      marker += Info.size;
850	      (*num)++;
851	  }
852      } else
853	_XEatData(dpy, rep.length << 2);
854  }
855
856  UnlockDisplay(dpy);
857  SyncHandle();
858
859  return ret;
860}
861
862SDL_NAME(XvImageFormatValues) * SDL_NAME(XvListImageFormats) (
863   Display 	*dpy,
864   XvPortID 	port,
865   int 		*num
866){
867  XExtDisplayInfo *info = xv_find_display(dpy);
868  xvListImageFormatsReq *req;
869  xvListImageFormatsReply rep;
870  SDL_NAME(XvImageFormatValues) *ret = NULL;
871
872  *num = 0;
873
874  XvCheckExtension(dpy, info, NULL);
875
876  LockDisplay(dpy);
877
878  XvGetReq(ListImageFormats, req);
879  req->port = port;
880
881  /* READ THE REPLY */
882
883  if (_XReply(dpy, (xReply *)&rep, 0, xFalse) == 0) {
884      UnlockDisplay(dpy);
885      SyncHandle();
886      return NULL;
887  }
888
889  if(rep.num_formats) {
890      int size = (rep.num_formats * sizeof(SDL_NAME(XvImageFormatValues)));
891
892      if((ret = Xmalloc(size))) {
893	  xvImageFormatInfo Info;
894	  int i;
895
896	  for(i = 0; i < rep.num_formats; i++) {
897              _XRead(dpy, (char*)(&Info), sz_xvImageFormatInfo);
898	      ret[i].id = Info.id;
899	      ret[i].type = Info.type;
900	      ret[i].byte_order = Info.byte_order;
901	      memcpy(&(ret[i].guid[0]), &(Info.guid[0]), 16);
902	      ret[i].bits_per_pixel = Info.bpp;
903  	      ret[i].format = Info.format;
904   	      ret[i].num_planes = Info.num_planes;
905    	      ret[i].depth = Info.depth;
906    	      ret[i].red_mask = Info.red_mask;
907    	      ret[i].green_mask = Info.green_mask;
908    	      ret[i].blue_mask = Info.blue_mask;
909    	      ret[i].y_sample_bits = Info.y_sample_bits;
910    	      ret[i].u_sample_bits = Info.u_sample_bits;
911    	      ret[i].v_sample_bits = Info.v_sample_bits;
912    	      ret[i].horz_y_period = Info.horz_y_period;
913    	      ret[i].horz_u_period = Info.horz_u_period;
914    	      ret[i].horz_v_period = Info.horz_v_period;
915    	      ret[i].vert_y_period = Info.vert_y_period;
916    	      ret[i].vert_u_period = Info.vert_u_period;
917    	      ret[i].vert_v_period = Info.vert_v_period;
918	      memcpy(&(ret[i].component_order[0]), &(Info.comp_order[0]), 32);
919    	      ret[i].scanline_order = Info.scanline_order;
920	      (*num)++;
921	  }
922      } else
923	_XEatData(dpy, rep.length << 2);
924  }
925
926  UnlockDisplay(dpy);
927  SyncHandle();
928
929  return ret;
930}
931
932SDL_NAME(XvImage) * SDL_NAME(XvCreateImage) (
933   Display *dpy,
934   XvPortID port,
935   int id,
936   char *data,
937   int width,
938   int height
939) {
940   XExtDisplayInfo *info = xv_find_display(dpy);
941   xvQueryImageAttributesReq *req;
942   xvQueryImageAttributesReply rep;
943   SDL_NAME(XvImage) *ret = NULL;
944
945   XvCheckExtension(dpy, info, NULL);
946
947   LockDisplay(dpy);
948
949   XvGetReq(QueryImageAttributes, req);
950   req->id = id;
951   req->port = port;
952   req->width = width;
953   req->height = height;
954
955   /* READ THE REPLY */
956
957   if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
958       UnlockDisplay(dpy);
959       SyncHandle();
960      return NULL;
961   }
962
963   if((ret = (SDL_NAME(XvImage)*)Xmalloc(sizeof(SDL_NAME(XvImage)) + (rep.num_planes << 3)))) {
964	ret->id = id;
965	ret->width = rep.width;
966	ret->height = rep.height;
967	ret->data_size = rep.data_size;
968	ret->num_planes = rep.num_planes;
969	ret->pitches = (int*)(&ret[1]);
970	ret->offsets = ret->pitches + rep.num_planes;
971	ret->data = data;
972	ret->obdata = NULL;
973  	_XRead(dpy, (char*)(ret->pitches), rep.num_planes << 2);
974	_XRead(dpy, (char*)(ret->offsets), rep.num_planes << 2);
975   } else
976	_XEatData(dpy, rep.length << 2);
977
978   UnlockDisplay(dpy);
979   SyncHandle();
980   return ret;
981}
982
983SDL_NAME(XvImage) * SDL_NAME(XvShmCreateImage) (
984   Display *dpy,
985   XvPortID port,
986   int id,
987   char *data,
988   int width,
989   int height,
990   XShmSegmentInfo *shminfo
991){
992   SDL_NAME(XvImage) *ret;
993
994   ret = SDL_NAME(XvCreateImage)(dpy, port, id, data, width, height);
995
996   if(ret) ret->obdata = (XPointer)shminfo;
997
998   return ret;
999}
1000
1001int SDL_NAME(XvPutImage) (
1002   Display *dpy,
1003   XvPortID port,
1004   Drawable d,
1005   GC gc,
1006   SDL_NAME(XvImage) *image,
1007   int src_x,
1008   int src_y,
1009   unsigned int src_w,
1010   unsigned int src_h,
1011   int dest_x,
1012   int dest_y,
1013   unsigned int dest_w,
1014   unsigned int dest_h
1015){
1016  XExtDisplayInfo *info = xv_find_display(dpy);
1017  xvPutImageReq *req;
1018  int len;
1019
1020  XvCheckExtension(dpy, info, XvBadExtension);
1021
1022  LockDisplay(dpy);
1023
1024  FlushGC(dpy, gc);
1025
1026  XvGetReq(PutImage, req);
1027
1028  req->port = port;
1029  req->drawable = d;
1030  req->gc = gc->gid;
1031  req->id = image->id;
1032  req->src_x = src_x;
1033  req->src_y = src_y;
1034  req->src_w = src_w;
1035  req->src_h = src_h;
1036  req->drw_x = dest_x;
1037  req->drw_y = dest_y;
1038  req->drw_w = dest_w;
1039  req->drw_h = dest_h;
1040  req->width = image->width;
1041  req->height = image->height;
1042
1043  len = (image->data_size + 3) >> 2;
1044  SetReqLen(req, len, len);
1045
1046  /* Yes it's kindof lame that we are sending the whole thing,
1047     but for video all of it may be needed even if displaying
1048     only a subsection, and I don't want to go through the
1049     trouble of creating subregions to send */
1050  Data(dpy, (char *)image->data, image->data_size);
1051
1052  UnlockDisplay(dpy);
1053  SyncHandle();
1054
1055  return Success;
1056}
1057
1058int SDL_NAME(XvShmPutImage) (
1059   Display *dpy,
1060   XvPortID port,
1061   Drawable d,
1062   GC gc,
1063   SDL_NAME(XvImage) *image,
1064   int src_x,
1065   int src_y,
1066   unsigned int src_w,
1067   unsigned int src_h,
1068   int dest_x,
1069   int dest_y,
1070   unsigned int dest_w,
1071   unsigned int dest_h,
1072   Bool send_event
1073){
1074  XExtDisplayInfo *info = xv_find_display(dpy);
1075  XShmSegmentInfo *shminfo = (XShmSegmentInfo *)image->obdata;
1076  xvShmPutImageReq *req;
1077
1078  XvCheckExtension(dpy, info, XvBadExtension);
1079
1080  LockDisplay(dpy);
1081
1082  FlushGC(dpy, gc);
1083
1084  XvGetReq(ShmPutImage, req);
1085
1086  req->port = port;
1087  req->drawable = d;
1088  req->gc = gc->gid;
1089  req->shmseg = shminfo->shmseg;
1090  req->id = image->id;
1091  req->src_x = src_x;
1092  req->src_y = src_y;
1093  req->src_w = src_w;
1094  req->src_h = src_h;
1095  req->drw_x = dest_x;
1096  req->drw_y = dest_y;
1097  req->drw_w = dest_w;
1098  req->drw_h = dest_h;
1099  req->offset = image->data - shminfo->shmaddr;
1100  req->width = image->width;
1101  req->height = image->height;
1102  req->send_event = send_event;
1103
1104  UnlockDisplay(dpy);
1105  SyncHandle();
1106
1107  return Success;
1108}
1109
1110
1111static Bool
1112xv_wire_to_event(Display *dpy, XEvent *host, xEvent *wire)
1113{
1114  XExtDisplayInfo *info = xv_find_display(dpy);
1115  SDL_NAME(XvEvent) *re    = (SDL_NAME(XvEvent) *)host;
1116  xvEvent *event = (xvEvent *)wire;
1117
1118  XvCheckExtension(dpy, info, False);
1119
1120  switch((event->u.u.type & 0x7F) - info->codes->first_event)
1121  {
1122    case XvVideoNotify:
1123      re->xvvideo.type = event->u.u.type & 0x7f;
1124      re->xvvideo.serial =
1125	_XSetLastRequestRead(dpy, (xGenericReply *)event);
1126      re->xvvideo.send_event = ((event->u.u.type & 0x80) != 0);
1127      re->xvvideo.display = dpy;
1128      re->xvvideo.time = event->u.videoNotify.time;
1129      re->xvvideo.reason = event->u.videoNotify.reason;
1130      re->xvvideo.drawable = event->u.videoNotify.drawable;
1131      re->xvvideo.port_id = event->u.videoNotify.port;
1132      break;
1133    case XvPortNotify:
1134      re->xvport.type = event->u.u.type & 0x7f;
1135      re->xvport.serial =
1136	_XSetLastRequestRead(dpy, (xGenericReply *)event);
1137      re->xvport.send_event = ((event->u.u.type & 0x80) != 0);
1138      re->xvport.display = dpy;
1139      re->xvport.time = event->u.portNotify.time;
1140      re->xvport.port_id = event->u.portNotify.port;
1141      re->xvport.attribute = event->u.portNotify.attribute;
1142      re->xvport.value = event->u.portNotify.value;
1143      break;
1144    default:
1145      return False;
1146  }
1147
1148  return (True);
1149}
1150
1151
1152