SDL-1.2.14
[sdl_omap.git] / src / video / Xext / Xv / Xv.c
1 /***********************************************************
2 Copyright 1991 by Digital Equipment Corporation, Maynard, Massachusetts,
3 and the Massachusetts Institute of Technology, Cambridge, Massachusetts.
4
5                         All Rights Reserved
6
7 Permission to use, copy, modify, and distribute this software and its 
8 documentation for any purpose and without fee is hereby granted, 
9 provided that the above copyright notice appear in all copies and that
10 both that copyright notice and this permission notice appear in 
11 supporting documentation, and that the names of Digital or MIT not be
12 used in advertising or publicity pertaining to distribution of the
13 software without specific, written prior permission.  
14
15 DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
16 ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
17 DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
18 ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
19 WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
20 ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
21 SOFTWARE.
22
23 ******************************************************************/
24 /* $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
59 static XExtensionInfo _xv_info_data;
60 static XExtensionInfo *xv_info = &_xv_info_data;
61 static char *xv_extension_name = XvName;
62
63 #define XvCheckExtension(dpy, i, val) \
64   XextCheckExtension(dpy, i, xv_extension_name, val)
65
66 static char *xv_error_string();
67 static int xv_close_display();
68 static Bool xv_wire_to_event();
69
70 static 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
85 static char *xv_error_list[] = 
86 {
87    "BadPort",       /* XvBadPort     */
88    "BadEncoding",   /* XvBadEncoding */
89    "BadControl"     /* XvBadControl  */
90 };
91
92 static XEXT_GENERATE_CLOSE_DISPLAY (xv_close_display, xv_info)
93
94
95 static XEXT_GENERATE_FIND_DISPLAY (xv_find_display, xv_info, 
96                                    xv_extension_name, 
97                                    &xv_extension_hooks,
98                                    XvNumEvents, NULL)
99      
100
101 static XEXT_GENERATE_ERROR_STRING (xv_error_string, xv_extension_name,
102                                    XvNumErrors, xv_error_list)
103
104
105 int
106 SDL_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
142 int
143 SDL_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
277 void
278 SDL_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
303 int
304 SDL_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
403 void
404 SDL_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
421 int
422 SDL_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
461 int
462 SDL_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
500 int
501 SDL_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
539 int
540 SDL_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
578 int
579 SDL_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
601 int
602 SDL_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
631 int
632 SDL_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
654 int
655 SDL_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
677 int
678 SDL_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
700 int
701 SDL_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
726 int
727 SDL_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
762 int
763 SDL_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
809 SDL_NAME(XvAttribute)* 
810 SDL_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
862 SDL_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
932 SDL_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
983 SDL_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
1001 int 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
1058 int 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
1111 static Bool
1112 xv_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