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
XEXT_GENERATE_CLOSE_DISPLAY(xv_close_display,xv_info)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
SDL_NAME(XvQueryAdaptors)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
SDL_NAME(XvFreeAdaptorInfo)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
SDL_NAME(XvQueryEncodings)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
SDL_NAME(XvFreeEncodingInfo)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
SDL_NAME(XvPutVideo)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
SDL_NAME(XvPutStill)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
SDL_NAME(XvGetVideo)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
SDL_NAME(XvGetStill)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
SDL_NAME(XvStopVideo)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
SDL_NAME(XvGrabPort)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
SDL_NAME(XvUngrabPort)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
SDL_NAME(XvSelectVideoNotify)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
SDL_NAME(XvSelectPortNotify)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
SDL_NAME(XvSetPortAttribute)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
SDL_NAME(XvGetPortAttribute)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
SDL_NAME(XvQueryBestSize)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
SDL_NAME(XvAttribute)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
SDL_NAME(XvImageFormatValues)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
SDL_NAME(XvImage)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
SDL_NAME(XvImage)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
SDL_NAME(XvPutImage)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
SDL_NAME(XvShmPutImage)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
xv_wire_to_event(Display * dpy,XEvent * host,xEvent * wire)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
1152