3 XFree86 Xv DDX written by Mark Vojkovich (markv@valinux.com)
4 Adapted for KDrive by Pontus Lidman <pontus.lidman@nokia.com>
6 Copyright (C) 2000, 2001 - Nokia Home Communications
7 Copyright (C) 1998, 1999 - The XFree86 Project Inc.
11 Permission is hereby granted, free of charge, to any person obtaining
12 a copy of this software and associated documentation files (the
13 "Software"), to deal in the Software without restriction, including
14 without limitation the rights to use, copy, modify, merge, publish,
15 distribute, and/or sell copies of the Software, and to permit persons
16 to whom the Software is furnished to do so, provided that the above
17 copyright notice(s) and this permission notice appear in all copies of
18 the Software and that both the above copyright notice(s) and this
19 permission notice appear in supporting documentation.
21 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
22 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
23 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
24 OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
25 HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY
26 SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER
27 RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
28 CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
29 CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
31 Except as contained in this notice, the name of a copyright holder
32 shall not be used in advertising or otherwise to promote the sale, use
33 or other dealings in this Software without prior written authorization
34 of the copyright holder.
39 #include <kdrive-config.h>
43 #include "scrnintstr.h"
44 #include "regionstr.h"
45 #include "windowstr.h"
46 #include "pixmapstr.h"
47 #include "mivalidate.h"
51 #include "dixstruct.h"
53 #include <X11/extensions/Xv.h>
54 #include <X11/extensions/Xvproto.h>
59 /* XvScreenRec fields */
61 static Bool
KdXVCloseScreen(ScreenPtr
);
62 static int KdXVQueryAdaptors(ScreenPtr
, XvAdaptorPtr
*, int *);
64 /* XvAdaptorRec fields */
66 static int KdXVAllocatePort(unsigned long, XvPortPtr
, XvPortPtr
*);
67 static int KdXVFreePort(XvPortPtr
);
68 static int KdXVPutVideo(ClientPtr
, DrawablePtr
, XvPortPtr
, GCPtr
,
69 INT16
, INT16
, CARD16
, CARD16
,
70 INT16
, INT16
, CARD16
, CARD16
);
71 static int KdXVPutStill(ClientPtr
, DrawablePtr
, XvPortPtr
, GCPtr
,
72 INT16
, INT16
, CARD16
, CARD16
,
73 INT16
, INT16
, CARD16
, CARD16
);
74 static int KdXVGetVideo(ClientPtr
, DrawablePtr
, XvPortPtr
, GCPtr
,
75 INT16
, INT16
, CARD16
, CARD16
,
76 INT16
, INT16
, CARD16
, CARD16
);
77 static int KdXVGetStill(ClientPtr
, DrawablePtr
, XvPortPtr
, GCPtr
,
78 INT16
, INT16
, CARD16
, CARD16
,
79 INT16
, INT16
, CARD16
, CARD16
);
80 static int KdXVStopVideo(ClientPtr
, XvPortPtr
, DrawablePtr
);
81 static int KdXVSetPortAttribute(ClientPtr
, XvPortPtr
, Atom
, INT32
);
82 static int KdXVGetPortAttribute(ClientPtr
, XvPortPtr
, Atom
, INT32
*);
83 static int KdXVQueryBestSize(ClientPtr
, XvPortPtr
, CARD8
,
84 CARD16
, CARD16
, CARD16
, CARD16
,
85 unsigned int *, unsigned int *);
86 static int KdXVPutImage(ClientPtr
, DrawablePtr
, XvPortPtr
, GCPtr
,
87 INT16
, INT16
, CARD16
, CARD16
,
88 INT16
, INT16
, CARD16
, CARD16
,
89 XvImagePtr
, unsigned char *, Bool
, CARD16
, CARD16
);
90 static int KdXVQueryImageAttributes(ClientPtr
, XvPortPtr
, XvImagePtr
,
91 CARD16
*, CARD16
*, int *, int *);
93 /* ScreenRec fields */
95 static Bool
KdXVCreateWindow(WindowPtr pWin
);
96 static Bool
KdXVDestroyWindow(WindowPtr pWin
);
97 static void KdXVWindowExposures(WindowPtr pWin
, RegionPtr r1
, RegionPtr r2
);
98 static void KdXVClipNotify(WindowPtr pWin
, int dx
, int dy
);
101 static Bool
KdXVInitAdaptors(ScreenPtr
, KdVideoAdaptorPtr
*, int);
103 static DevPrivateKeyRec KdXVWindowKeyRec
;
105 #define KdXVWindowKey (&KdXVWindowKeyRec)
106 static DevPrivateKey KdXvScreenKey
;
107 static unsigned long KdXVGeneration
= 0;
108 static unsigned long PortResource
= 0;
110 #define GET_XV_SCREEN(pScreen) ((XvScreenPtr) \
111 dixLookupPrivate(&(pScreen)->devPrivates, KdXvScreenKey))
113 #define GET_KDXV_SCREEN(pScreen) \
114 ((KdXVScreenPtr)(GET_XV_SCREEN(pScreen)->devPriv.ptr))
116 #define GET_KDXV_WINDOW(pWin) ((KdXVWindowPtr) \
117 dixLookupPrivate(&(pWin)->devPrivates, KdXVWindowKey))
119 static KdXVInitGenericAdaptorPtr
*GenDrivers
= NULL
;
120 static int NumGenDrivers
= 0;
123 KdXVRegisterGenericAdaptorDriver(KdXVInitGenericAdaptorPtr InitFunc
)
125 KdXVInitGenericAdaptorPtr
*newdrivers
;
127 /* fprintf(stderr,"KdXVRegisterGenericAdaptorDriver\n"); */
129 newdrivers
= realloc(GenDrivers
, sizeof(KdXVInitGenericAdaptorPtr
) *
130 (1 + NumGenDrivers
));
133 GenDrivers
= newdrivers
;
135 GenDrivers
[NumGenDrivers
++] = InitFunc
;
141 KdXVListGenericAdaptors(KdScreenInfo
* screen
, KdVideoAdaptorPtr
** adaptors
)
144 KdVideoAdaptorPtr
*DrivAdap
, *new;
148 for (i
= 0; i
< NumGenDrivers
; i
++) {
149 n
= GenDrivers
[i
] (screen
, &DrivAdap
);
152 new = realloc(*adaptors
, sizeof(KdVideoAdaptorPtr
) * (num
+ n
));
156 for (j
= 0; j
< n
; j
++, num
++)
157 (*adaptors
)[num
] = DrivAdap
[j
];
163 KdXVAllocateVideoAdaptorRec(KdScreenInfo
* screen
)
165 return calloc(1, sizeof(KdVideoAdaptorRec
));
169 KdXVFreeVideoAdaptorRec(KdVideoAdaptorPtr ptr
)
175 KdXVScreenInit(ScreenPtr pScreen
, KdVideoAdaptorPtr
* adaptors
, int num
)
177 KdXVScreenPtr ScreenPriv
;
180 /* fprintf(stderr,"KdXVScreenInit initializing %d adaptors\n",num); */
182 if (KdXVGeneration
!= serverGeneration
)
183 KdXVGeneration
= serverGeneration
;
188 if (!dixRegisterPrivateKey(&KdXVWindowKeyRec
, PRIVATE_WINDOW
, 0))
191 if (Success
!= XvScreenInit(pScreen
))
194 KdXvScreenKey
= XvGetScreenKey();
195 PortResource
= XvGetRTPort();
197 pxvs
= GET_XV_SCREEN(pScreen
);
199 /* Anyone initializing the Xv layer must provide these two.
200 The Xv di layer calls them without even checking if they exist! */
202 pxvs
->ddCloseScreen
= KdXVCloseScreen
;
203 pxvs
->ddQueryAdaptors
= KdXVQueryAdaptors
;
205 /* The Xv di layer provides us with a private hook so that we don't
206 have to allocate our own screen private. They also provide
207 a CloseScreen hook so that we don't have to wrap it. I'm not
208 sure that I appreciate that. */
210 ScreenPriv
= malloc(sizeof(KdXVScreenRec
));
211 pxvs
->devPriv
.ptr
= (pointer
) ScreenPriv
;
216 ScreenPriv
->CreateWindow
= pScreen
->CreateWindow
;
217 ScreenPriv
->DestroyWindow
= pScreen
->DestroyWindow
;
218 ScreenPriv
->WindowExposures
= pScreen
->WindowExposures
;
219 ScreenPriv
->ClipNotify
= pScreen
->ClipNotify
;
221 /* fprintf(stderr,"XV: Wrapping screen funcs\n"); */
223 pScreen
->CreateWindow
= KdXVCreateWindow
;
224 pScreen
->DestroyWindow
= KdXVDestroyWindow
;
225 pScreen
->WindowExposures
= KdXVWindowExposures
;
226 pScreen
->ClipNotify
= KdXVClipNotify
;
228 if (!KdXVInitAdaptors(pScreen
, adaptors
, num
))
235 KdXVFreeAdaptor(XvAdaptorPtr pAdaptor
)
239 free(pAdaptor
->name
);
241 if (pAdaptor
->pEncodings
) {
242 XvEncodingPtr pEncode
= pAdaptor
->pEncodings
;
244 for (i
= 0; i
< pAdaptor
->nEncodings
; i
++, pEncode
++) {
247 free(pAdaptor
->pEncodings
);
250 free(pAdaptor
->pFormats
);
252 if (pAdaptor
->pPorts
) {
253 XvPortPtr pPort
= pAdaptor
->pPorts
;
254 XvPortRecPrivatePtr pPriv
;
256 for (i
= 0; i
< pAdaptor
->nPorts
; i
++, pPort
++) {
257 pPriv
= (XvPortRecPrivatePtr
) pPort
->devPriv
.ptr
;
259 if (pPriv
->clientClip
)
260 RegionDestroy(pPriv
->clientClip
);
261 if (pPriv
->pCompositeClip
&& pPriv
->FreeCompositeClip
)
262 RegionDestroy(pPriv
->pCompositeClip
);
266 free(pAdaptor
->pPorts
);
269 if (pAdaptor
->nAttributes
) {
270 XvAttributePtr pAttribute
= pAdaptor
->pAttributes
;
272 for (i
= 0; i
< pAdaptor
->nAttributes
; i
++, pAttribute
++) {
273 free(pAttribute
->name
);
276 free(pAdaptor
->pAttributes
);
279 free(pAdaptor
->pImages
);
281 free(pAdaptor
->devPriv
.ptr
);
285 KdXVInitAdaptors(ScreenPtr pScreen
, KdVideoAdaptorPtr
* infoPtr
, int number
)
287 KdScreenPriv(pScreen
);
288 KdScreenInfo
*screen
= pScreenPriv
->screen
;
290 XvScreenPtr pxvs
= GET_XV_SCREEN(pScreen
);
291 KdVideoAdaptorPtr adaptorPtr
;
292 XvAdaptorPtr pAdaptor
, pa
;
293 XvAdaptorRecPrivatePtr adaptorPriv
;
295 XvPortRecPrivatePtr portPriv
;
298 KdAttributePtr attributePtr
;
299 XvAttributePtr pAttribute
, pat
;
300 KdVideoFormatPtr formatPtr
;
301 XvFormatPtr pFormat
, pf
;
302 int numFormat
, totFormat
;
303 KdVideoEncodingPtr encodingPtr
;
304 XvEncodingPtr pEncode
, pe
;
306 XvImagePtr pImage
, pi
;
312 pxvs
->pAdaptors
= NULL
;
314 if (!(pAdaptor
= calloc(number
, sizeof(XvAdaptorRec
))))
317 for (pa
= pAdaptor
, na
= 0, numAdaptor
= 0; na
< number
; na
++, adaptorPtr
++) {
318 adaptorPtr
= infoPtr
[na
];
320 if (!adaptorPtr
->StopVideo
|| !adaptorPtr
->SetPortAttribute
||
321 !adaptorPtr
->GetPortAttribute
|| !adaptorPtr
->QueryBestSize
)
324 /* client libs expect at least one encoding */
325 if (!adaptorPtr
->nEncodings
|| !adaptorPtr
->pEncodings
)
328 pa
->type
= adaptorPtr
->type
;
330 if (!adaptorPtr
->PutVideo
&& !adaptorPtr
->GetVideo
)
331 pa
->type
&= ~XvVideoMask
;
333 if (!adaptorPtr
->PutStill
&& !adaptorPtr
->GetStill
)
334 pa
->type
&= ~XvStillMask
;
336 if (!adaptorPtr
->PutImage
|| !adaptorPtr
->QueryImageAttributes
)
337 pa
->type
&= ~XvImageMask
;
339 if (!adaptorPtr
->PutVideo
&& !adaptorPtr
->PutImage
&&
340 !adaptorPtr
->PutStill
)
341 pa
->type
&= ~XvInputMask
;
343 if (!adaptorPtr
->GetVideo
&& !adaptorPtr
->GetStill
)
344 pa
->type
&= ~XvOutputMask
;
346 if (!(adaptorPtr
->type
& (XvPixmapMask
| XvWindowMask
)))
348 if (!(adaptorPtr
->type
& (XvImageMask
| XvVideoMask
| XvStillMask
)))
351 pa
->pScreen
= pScreen
;
352 pa
->ddAllocatePort
= KdXVAllocatePort
;
353 pa
->ddFreePort
= KdXVFreePort
;
354 pa
->ddPutVideo
= KdXVPutVideo
;
355 pa
->ddPutStill
= KdXVPutStill
;
356 pa
->ddGetVideo
= KdXVGetVideo
;
357 pa
->ddGetStill
= KdXVGetStill
;
358 pa
->ddStopVideo
= KdXVStopVideo
;
359 pa
->ddPutImage
= KdXVPutImage
;
360 pa
->ddSetPortAttribute
= KdXVSetPortAttribute
;
361 pa
->ddGetPortAttribute
= KdXVGetPortAttribute
;
362 pa
->ddQueryBestSize
= KdXVQueryBestSize
;
363 pa
->ddQueryImageAttributes
= KdXVQueryImageAttributes
;
364 pa
->name
= strdup(adaptorPtr
->name
);
366 if (adaptorPtr
->nEncodings
&&
367 (pEncode
= calloc(adaptorPtr
->nEncodings
, sizeof(XvEncodingRec
)))) {
369 for (pe
= pEncode
, encodingPtr
= adaptorPtr
->pEncodings
, i
= 0;
370 i
< adaptorPtr
->nEncodings
; pe
++, i
++, encodingPtr
++) {
371 pe
->id
= encodingPtr
->id
;
372 pe
->pScreen
= pScreen
;
373 pe
->name
= strdup(encodingPtr
->name
);
374 pe
->width
= encodingPtr
->width
;
375 pe
->height
= encodingPtr
->height
;
376 pe
->rate
.numerator
= encodingPtr
->rate
.numerator
;
377 pe
->rate
.denominator
= encodingPtr
->rate
.denominator
;
379 pa
->nEncodings
= adaptorPtr
->nEncodings
;
380 pa
->pEncodings
= pEncode
;
383 if (adaptorPtr
->nImages
&&
384 (pImage
= calloc(adaptorPtr
->nImages
, sizeof(XvImageRec
)))) {
386 for (i
= 0, pi
= pImage
, imagePtr
= adaptorPtr
->pImages
;
387 i
< adaptorPtr
->nImages
; i
++, pi
++, imagePtr
++) {
388 pi
->id
= imagePtr
->id
;
389 pi
->type
= imagePtr
->type
;
390 pi
->byte_order
= imagePtr
->byte_order
;
391 memcpy(pi
->guid
, imagePtr
->guid
, 16);
392 pi
->bits_per_pixel
= imagePtr
->bits_per_pixel
;
393 pi
->format
= imagePtr
->format
;
394 pi
->num_planes
= imagePtr
->num_planes
;
395 pi
->depth
= imagePtr
->depth
;
396 pi
->red_mask
= imagePtr
->red_mask
;
397 pi
->green_mask
= imagePtr
->green_mask
;
398 pi
->blue_mask
= imagePtr
->blue_mask
;
399 pi
->y_sample_bits
= imagePtr
->y_sample_bits
;
400 pi
->u_sample_bits
= imagePtr
->u_sample_bits
;
401 pi
->v_sample_bits
= imagePtr
->v_sample_bits
;
402 pi
->horz_y_period
= imagePtr
->horz_y_period
;
403 pi
->horz_u_period
= imagePtr
->horz_u_period
;
404 pi
->horz_v_period
= imagePtr
->horz_v_period
;
405 pi
->vert_y_period
= imagePtr
->vert_y_period
;
406 pi
->vert_u_period
= imagePtr
->vert_u_period
;
407 pi
->vert_v_period
= imagePtr
->vert_v_period
;
408 memcpy(pi
->component_order
, imagePtr
->component_order
, 32);
409 pi
->scanline_order
= imagePtr
->scanline_order
;
411 pa
->nImages
= adaptorPtr
->nImages
;
412 pa
->pImages
= pImage
;
415 if (adaptorPtr
->nAttributes
&&
417 calloc(adaptorPtr
->nAttributes
, sizeof(XvAttributeRec
)))) {
418 for (pat
= pAttribute
, attributePtr
= adaptorPtr
->pAttributes
, i
=
419 0; i
< adaptorPtr
->nAttributes
; pat
++, i
++, attributePtr
++) {
420 pat
->flags
= attributePtr
->flags
;
421 pat
->min_value
= attributePtr
->min_value
;
422 pat
->max_value
= attributePtr
->max_value
;
423 pat
->name
= strdup(attributePtr
->name
);
425 pa
->nAttributes
= adaptorPtr
->nAttributes
;
426 pa
->pAttributes
= pAttribute
;
429 totFormat
= adaptorPtr
->nFormats
;
431 if (!(pFormat
= calloc(totFormat
, sizeof(XvFormatRec
)))) {
435 for (pf
= pFormat
, i
= 0, numFormat
= 0, formatPtr
=
436 adaptorPtr
->pFormats
; i
< adaptorPtr
->nFormats
; i
++, formatPtr
++) {
437 numVisuals
= pScreen
->numVisuals
;
438 pVisual
= pScreen
->visuals
;
440 while (numVisuals
--) {
441 if ((pVisual
->class == formatPtr
->class) &&
442 (pVisual
->nplanes
== formatPtr
->depth
)) {
444 if (numFormat
>= totFormat
) {
448 moreSpace
= realloc(pFormat
,
449 totFormat
* sizeof(XvFormatRec
));
453 pf
= pFormat
+ numFormat
;
456 pf
->visual
= pVisual
->vid
;
457 pf
->depth
= formatPtr
->depth
;
465 pa
->nFormats
= numFormat
;
466 pa
->pFormats
= pFormat
;
472 if (!(adaptorPriv
= calloc(1, sizeof(XvAdaptorRecPrivate
)))) {
477 adaptorPriv
->flags
= adaptorPtr
->flags
;
478 adaptorPriv
->PutVideo
= adaptorPtr
->PutVideo
;
479 adaptorPriv
->PutStill
= adaptorPtr
->PutStill
;
480 adaptorPriv
->GetVideo
= adaptorPtr
->GetVideo
;
481 adaptorPriv
->GetStill
= adaptorPtr
->GetStill
;
482 adaptorPriv
->StopVideo
= adaptorPtr
->StopVideo
;
483 adaptorPriv
->SetPortAttribute
= adaptorPtr
->SetPortAttribute
;
484 adaptorPriv
->GetPortAttribute
= adaptorPtr
->GetPortAttribute
;
485 adaptorPriv
->QueryBestSize
= adaptorPtr
->QueryBestSize
;
486 adaptorPriv
->QueryImageAttributes
= adaptorPtr
->QueryImageAttributes
;
487 adaptorPriv
->PutImage
= adaptorPtr
->PutImage
;
488 adaptorPriv
->ReputImage
= adaptorPtr
->ReputImage
;
490 pa
->devPriv
.ptr
= (pointer
) adaptorPriv
;
492 if (!(pPort
= calloc(adaptorPtr
->nPorts
, sizeof(XvPortRec
)))) {
496 for (pp
= pPort
, i
= 0, numPort
= 0; i
< adaptorPtr
->nPorts
; i
++) {
498 if (!(pp
->id
= FakeClientID(0)))
501 if (!(portPriv
= calloc(1, sizeof(XvPortRecPrivate
))))
504 if (!AddResource(pp
->id
, PortResource
, pp
)) {
510 pp
->pNotify
= (XvPortNotifyPtr
) NULL
;
511 pp
->pDraw
= (DrawablePtr
) NULL
;
512 pp
->client
= (ClientPtr
) NULL
;
513 pp
->grab
.client
= (ClientPtr
) NULL
;
514 pp
->time
= currentTime
;
515 pp
->devPriv
.ptr
= portPriv
;
517 portPriv
->screen
= screen
;
518 portPriv
->AdaptorRec
= adaptorPriv
;
519 portPriv
->DevPriv
.ptr
= adaptorPtr
->pPortPrivates
[i
].ptr
;
524 pa
->nPorts
= numPort
;
531 pa
->base_id
= pPort
->id
;
538 pxvs
->nAdaptors
= numAdaptor
;
539 pxvs
->pAdaptors
= pAdaptor
;
549 /* Video should be clipped to the intersection of the window cliplist
550 and the client cliplist specified in the GC for which the video was
551 initialized. When we need to reclip a window, the GC that started
552 the video may not even be around anymore. That's why we save the
553 client clip from the GC when the video is initialized. We then
554 use KdXVUpdateCompositeClip to calculate the new composite clip
555 when we need it. This is different from what DEC did. They saved
556 the GC and used it's clip list when they needed to reclip the window,
557 even if the client clip was different from the one the video was
558 initialized with. If the original GC was destroyed, they had to stop
559 the video. I like the new method better (MArk).
561 This function only works for windows. Will need to rewrite when
562 (if) we support pixmap rendering.
566 KdXVUpdateCompositeClip(XvPortRecPrivatePtr portPriv
)
568 RegionPtr pregWin
, pCompositeClip
;
570 Bool freeCompClip
= FALSE
;
572 if (portPriv
->pCompositeClip
)
575 pWin
= (WindowPtr
) portPriv
->pDraw
;
577 /* get window clip list */
578 if (portPriv
->subWindowMode
== IncludeInferiors
) {
579 pregWin
= NotClippedByChildren(pWin
);
583 pregWin
= &pWin
->clipList
;
585 if (!portPriv
->clientClip
) {
586 portPriv
->pCompositeClip
= pregWin
;
587 portPriv
->FreeCompositeClip
= freeCompClip
;
591 pCompositeClip
= RegionCreate(NullBox
, 1);
592 RegionCopy(pCompositeClip
, portPriv
->clientClip
);
593 RegionTranslate(pCompositeClip
,
594 portPriv
->pDraw
->x
+ portPriv
->clipOrg
.x
,
595 portPriv
->pDraw
->y
+ portPriv
->clipOrg
.y
);
596 RegionIntersect(pCompositeClip
, pregWin
, pCompositeClip
);
598 portPriv
->pCompositeClip
= pCompositeClip
;
599 portPriv
->FreeCompositeClip
= TRUE
;
602 RegionDestroy(pregWin
);
606 /* Save the current clientClip and update the CompositeClip whenever
607 we have a fresh GC */
610 KdXVCopyClip(XvPortRecPrivatePtr portPriv
, GCPtr pGC
)
612 /* copy the new clip if it exists */
613 if ((pGC
->clientClipType
== CT_REGION
) && pGC
->clientClip
) {
614 if (!portPriv
->clientClip
)
615 portPriv
->clientClip
= RegionCreate(NullBox
, 1);
616 /* Note: this is in window coordinates */
617 RegionCopy(portPriv
->clientClip
, pGC
->clientClip
);
619 else if (portPriv
->clientClip
) { /* free the old clientClip */
620 RegionDestroy(portPriv
->clientClip
);
621 portPriv
->clientClip
= NULL
;
624 /* get rid of the old clip list */
625 if (portPriv
->pCompositeClip
&& portPriv
->FreeCompositeClip
) {
626 RegionDestroy(portPriv
->pCompositeClip
);
629 portPriv
->clipOrg
= pGC
->clipOrg
;
630 portPriv
->pCompositeClip
= pGC
->pCompositeClip
;
631 portPriv
->FreeCompositeClip
= FALSE
;
632 portPriv
->subWindowMode
= pGC
->subWindowMode
;
636 KdXVRegetVideo(XvPortRecPrivatePtr portPriv
)
639 RegionRec ClipRegion
;
642 Bool clippedAway
= FALSE
;
644 KdXVUpdateCompositeClip(portPriv
);
646 /* translate the video region to the screen */
647 WinBox
.x1
= portPriv
->pDraw
->x
+ portPriv
->drw_x
;
648 WinBox
.y1
= portPriv
->pDraw
->y
+ portPriv
->drw_y
;
649 WinBox
.x2
= WinBox
.x1
+ portPriv
->drw_w
;
650 WinBox
.y2
= WinBox
.y1
+ portPriv
->drw_h
;
652 /* clip to the window composite clip */
653 RegionInit(&WinRegion
, &WinBox
, 1);
654 RegionInit(&ClipRegion
, NullBox
, 1);
655 RegionIntersect(&ClipRegion
, &WinRegion
, portPriv
->pCompositeClip
);
657 /* that's all if it's totally obscured */
658 if (!RegionNotEmpty(&ClipRegion
)) {
660 goto CLIP_VIDEO_BAILOUT
;
663 if (portPriv
->AdaptorRec
->flags
& VIDEO_INVERT_CLIPLIST
) {
664 RegionSubtract(&ClipRegion
, &WinRegion
, &ClipRegion
);
667 ret
= (*portPriv
->AdaptorRec
->GetVideo
) (portPriv
->screen
, portPriv
->pDraw
,
668 portPriv
->vid_x
, portPriv
->vid_y
,
669 WinBox
.x1
, WinBox
.y1
,
670 portPriv
->vid_w
, portPriv
->vid_h
,
671 portPriv
->drw_w
, portPriv
->drw_h
,
673 portPriv
->DevPriv
.ptr
);
676 portPriv
->isOn
= XV_ON
;
680 if ((clippedAway
|| (ret
!= Success
)) && portPriv
->isOn
== XV_ON
) {
681 (*portPriv
->AdaptorRec
->StopVideo
) (portPriv
->screen
,
682 portPriv
->DevPriv
.ptr
, FALSE
);
683 portPriv
->isOn
= XV_PENDING
;
686 /* This clip was copied and only good for one shot */
687 if (!portPriv
->FreeCompositeClip
)
688 portPriv
->pCompositeClip
= NULL
;
690 RegionUninit(&WinRegion
);
691 RegionUninit(&ClipRegion
);
697 KdXVReputVideo(XvPortRecPrivatePtr portPriv
)
700 RegionRec ClipRegion
;
702 ScreenPtr pScreen
= portPriv
->pDraw
->pScreen
;
704 KdScreenPriv(pScreen
);
705 KdScreenInfo
*screen
= pScreenPriv
->screen
;
707 Bool clippedAway
= FALSE
;
709 KdXVUpdateCompositeClip(portPriv
);
711 /* translate the video region to the screen */
712 WinBox
.x1
= portPriv
->pDraw
->x
+ portPriv
->drw_x
;
713 WinBox
.y1
= portPriv
->pDraw
->y
+ portPriv
->drw_y
;
714 WinBox
.x2
= WinBox
.x1
+ portPriv
->drw_w
;
715 WinBox
.y2
= WinBox
.y1
+ portPriv
->drw_h
;
717 /* clip to the window composite clip */
718 RegionInit(&WinRegion
, &WinBox
, 1);
719 RegionInit(&ClipRegion
, NullBox
, 1);
720 RegionIntersect(&ClipRegion
, &WinRegion
, portPriv
->pCompositeClip
);
722 /* clip and translate to the viewport */
723 if (portPriv
->AdaptorRec
->flags
& VIDEO_CLIP_TO_VIEWPORT
) {
729 VPBox
.x2
= screen
->width
;
730 VPBox
.y2
= screen
->height
;
732 RegionInit(&VPReg
, &VPBox
, 1);
733 RegionIntersect(&ClipRegion
, &ClipRegion
, &VPReg
);
734 RegionUninit(&VPReg
);
737 /* that's all if it's totally obscured */
738 if (!RegionNotEmpty(&ClipRegion
)) {
740 goto CLIP_VIDEO_BAILOUT
;
743 /* bailout if we have to clip but the hardware doesn't support it */
744 if (portPriv
->AdaptorRec
->flags
& VIDEO_NO_CLIPPING
) {
745 BoxPtr clipBox
= RegionRects(&ClipRegion
);
747 if ((RegionNumRects(&ClipRegion
) != 1) ||
748 (clipBox
->x1
!= WinBox
.x1
) || (clipBox
->x2
!= WinBox
.x2
) ||
749 (clipBox
->y1
!= WinBox
.y1
) || (clipBox
->y2
!= WinBox
.y2
)) {
751 goto CLIP_VIDEO_BAILOUT
;
755 if (portPriv
->AdaptorRec
->flags
& VIDEO_INVERT_CLIPLIST
) {
756 RegionSubtract(&ClipRegion
, &WinRegion
, &ClipRegion
);
759 ret
= (*portPriv
->AdaptorRec
->PutVideo
) (portPriv
->screen
, portPriv
->pDraw
,
760 portPriv
->vid_x
, portPriv
->vid_y
,
761 WinBox
.x1
, WinBox
.y1
,
762 portPriv
->vid_w
, portPriv
->vid_h
,
763 portPriv
->drw_w
, portPriv
->drw_h
,
765 portPriv
->DevPriv
.ptr
);
768 portPriv
->isOn
= XV_ON
;
772 if ((clippedAway
|| (ret
!= Success
)) && (portPriv
->isOn
== XV_ON
)) {
773 (*portPriv
->AdaptorRec
->StopVideo
) (portPriv
->screen
,
774 portPriv
->DevPriv
.ptr
, FALSE
);
775 portPriv
->isOn
= XV_PENDING
;
778 /* This clip was copied and only good for one shot */
779 if (!portPriv
->FreeCompositeClip
)
780 portPriv
->pCompositeClip
= NULL
;
782 RegionUninit(&WinRegion
);
783 RegionUninit(&ClipRegion
);
789 KdXVReputImage(XvPortRecPrivatePtr portPriv
)
792 RegionRec ClipRegion
;
794 ScreenPtr pScreen
= portPriv
->pDraw
->pScreen
;
796 KdScreenPriv(pScreen
);
797 KdScreenInfo
*screen
= pScreenPriv
->screen
;
799 Bool clippedAway
= FALSE
;
801 KdXVUpdateCompositeClip(portPriv
);
803 /* translate the video region to the screen */
804 WinBox
.x1
= portPriv
->pDraw
->x
+ portPriv
->drw_x
;
805 WinBox
.y1
= portPriv
->pDraw
->y
+ portPriv
->drw_y
;
806 WinBox
.x2
= WinBox
.x1
+ portPriv
->drw_w
;
807 WinBox
.y2
= WinBox
.y1
+ portPriv
->drw_h
;
809 /* clip to the window composite clip */
810 RegionInit(&WinRegion
, &WinBox
, 1);
811 RegionInit(&ClipRegion
, NullBox
, 1);
812 RegionIntersect(&ClipRegion
, &WinRegion
, portPriv
->pCompositeClip
);
814 /* clip and translate to the viewport */
815 if (portPriv
->AdaptorRec
->flags
& VIDEO_CLIP_TO_VIEWPORT
) {
821 VPBox
.x2
= screen
->width
;
822 VPBox
.y2
= screen
->height
;
824 RegionInit(&VPReg
, &VPBox
, 1);
825 RegionIntersect(&ClipRegion
, &ClipRegion
, &VPReg
);
826 RegionUninit(&VPReg
);
829 /* that's all if it's totally obscured */
830 if (!RegionNotEmpty(&ClipRegion
)) {
832 goto CLIP_VIDEO_BAILOUT
;
835 /* bailout if we have to clip but the hardware doesn't support it */
836 if (portPriv
->AdaptorRec
->flags
& VIDEO_NO_CLIPPING
) {
837 BoxPtr clipBox
= RegionRects(&ClipRegion
);
839 if ((RegionNumRects(&ClipRegion
) != 1) ||
840 (clipBox
->x1
!= WinBox
.x1
) || (clipBox
->x2
!= WinBox
.x2
) ||
841 (clipBox
->y1
!= WinBox
.y1
) || (clipBox
->y2
!= WinBox
.y2
)) {
843 goto CLIP_VIDEO_BAILOUT
;
847 if (portPriv
->AdaptorRec
->flags
& VIDEO_INVERT_CLIPLIST
) {
848 RegionSubtract(&ClipRegion
, &WinRegion
, &ClipRegion
);
852 (*portPriv
->AdaptorRec
->ReputImage
) (portPriv
->screen
, portPriv
->pDraw
,
853 WinBox
.x1
, WinBox
.y1
, &ClipRegion
,
854 portPriv
->DevPriv
.ptr
);
856 portPriv
->isOn
= (ret
== Success
) ? XV_ON
: XV_OFF
;
860 if ((clippedAway
|| (ret
!= Success
)) && (portPriv
->isOn
== XV_ON
)) {
861 (*portPriv
->AdaptorRec
->StopVideo
) (portPriv
->screen
,
862 portPriv
->DevPriv
.ptr
, FALSE
);
863 portPriv
->isOn
= XV_PENDING
;
866 /* This clip was copied and only good for one shot */
867 if (!portPriv
->FreeCompositeClip
)
868 portPriv
->pCompositeClip
= NULL
;
870 RegionUninit(&WinRegion
);
871 RegionUninit(&ClipRegion
);
877 KdXVReputAllVideo(WindowPtr pWin
, pointer data
)
879 KdXVWindowPtr WinPriv
;
881 if (pWin
->drawable
.type
!= DRAWABLE_WINDOW
)
882 return WT_DONTWALKCHILDREN
;
884 WinPriv
= GET_KDXV_WINDOW(pWin
);
887 if (WinPriv
->PortRec
->type
== XvInputMask
)
888 KdXVReputVideo(WinPriv
->PortRec
);
890 KdXVRegetVideo(WinPriv
->PortRec
);
891 WinPriv
= WinPriv
->next
;
894 return WT_WALKCHILDREN
;
898 KdXVEnlistPortInWindow(WindowPtr pWin
, XvPortRecPrivatePtr portPriv
)
900 KdXVWindowPtr winPriv
, PrivRoot
;
902 winPriv
= PrivRoot
= GET_KDXV_WINDOW(pWin
);
904 /* Enlist our port in the window private */
906 if (winPriv
->PortRec
== portPriv
) /* we're already listed */
908 winPriv
= winPriv
->next
;
912 winPriv
= malloc(sizeof(KdXVWindowRec
));
915 winPriv
->PortRec
= portPriv
;
916 winPriv
->next
= PrivRoot
;
917 dixSetPrivate(&pWin
->devPrivates
, KdXVWindowKey
, winPriv
);
923 KdXVRemovePortFromWindow(WindowPtr pWin
, XvPortRecPrivatePtr portPriv
)
925 KdXVWindowPtr winPriv
, prevPriv
= NULL
;
927 winPriv
= GET_KDXV_WINDOW(pWin
);
930 if (winPriv
->PortRec
== portPriv
) {
932 prevPriv
->next
= winPriv
->next
;
934 dixSetPrivate(&pWin
->devPrivates
, KdXVWindowKey
, winPriv
->next
);
939 winPriv
= winPriv
->next
;
941 portPriv
->pDraw
= NULL
;
944 /**** ScreenRec fields ****/
947 KdXVCreateWindow(WindowPtr pWin
)
949 ScreenPtr pScreen
= pWin
->drawable
.pScreen
;
950 KdXVScreenPtr ScreenPriv
= GET_KDXV_SCREEN(pScreen
);
953 pScreen
->CreateWindow
= ScreenPriv
->CreateWindow
;
954 ret
= (*pScreen
->CreateWindow
) (pWin
);
955 pScreen
->CreateWindow
= KdXVCreateWindow
;
958 dixSetPrivate(&pWin
->devPrivates
, KdXVWindowKey
, NULL
);
964 KdXVDestroyWindow(WindowPtr pWin
)
966 ScreenPtr pScreen
= pWin
->drawable
.pScreen
;
967 KdXVScreenPtr ScreenPriv
= GET_KDXV_SCREEN(pScreen
);
968 KdXVWindowPtr tmp
, WinPriv
= GET_KDXV_WINDOW(pWin
);
972 XvPortRecPrivatePtr pPriv
= WinPriv
->PortRec
;
974 if (pPriv
->isOn
> XV_OFF
) {
975 (*pPriv
->AdaptorRec
->StopVideo
) (pPriv
->screen
, pPriv
->DevPriv
.ptr
,
977 pPriv
->isOn
= XV_OFF
;
982 WinPriv
= WinPriv
->next
;
986 dixSetPrivate(&pWin
->devPrivates
, KdXVWindowKey
, NULL
);
988 pScreen
->DestroyWindow
= ScreenPriv
->DestroyWindow
;
989 ret
= (*pScreen
->DestroyWindow
) (pWin
);
990 pScreen
->DestroyWindow
= KdXVDestroyWindow
;
996 KdXVWindowExposures(WindowPtr pWin
, RegionPtr reg1
, RegionPtr reg2
)
998 ScreenPtr pScreen
= pWin
->drawable
.pScreen
;
999 KdXVScreenPtr ScreenPriv
= GET_KDXV_SCREEN(pScreen
);
1000 KdXVWindowPtr WinPriv
= GET_KDXV_WINDOW(pWin
);
1001 KdXVWindowPtr pPrev
;
1002 XvPortRecPrivatePtr pPriv
;
1005 AreasExposed
= (WinPriv
&& reg1
&& RegionNotEmpty(reg1
));
1007 pScreen
->WindowExposures
= ScreenPriv
->WindowExposures
;
1008 (*pScreen
->WindowExposures
) (pWin
, reg1
, reg2
);
1009 pScreen
->WindowExposures
= KdXVWindowExposures
;
1011 /* filter out XClearWindow/Area */
1018 pPriv
= WinPriv
->PortRec
;
1020 /* Reput anyone with a reput function */
1022 switch (pPriv
->type
) {
1024 KdXVReputVideo(pPriv
);
1027 KdXVRegetVideo(pPriv
);
1029 default: /* overlaid still/image */
1030 if (pPriv
->AdaptorRec
->ReputImage
)
1031 KdXVReputImage(pPriv
);
1032 else if (AreasExposed
) {
1035 if (pPriv
->isOn
== XV_ON
) {
1036 (*pPriv
->AdaptorRec
->StopVideo
) (pPriv
->screen
,
1037 pPriv
->DevPriv
.ptr
, FALSE
);
1038 pPriv
->isOn
= XV_PENDING
;
1040 pPriv
->pDraw
= NULL
;
1043 dixSetPrivate(&pWin
->devPrivates
, KdXVWindowKey
,
1046 pPrev
->next
= WinPriv
->next
;
1048 WinPriv
= WinPriv
->next
;
1055 WinPriv
= WinPriv
->next
;
1060 KdXVClipNotify(WindowPtr pWin
, int dx
, int dy
)
1062 ScreenPtr pScreen
= pWin
->drawable
.pScreen
;
1063 KdXVScreenPtr ScreenPriv
= GET_KDXV_SCREEN(pScreen
);
1064 KdXVWindowPtr WinPriv
= GET_KDXV_WINDOW(pWin
);
1065 KdXVWindowPtr tmp
, pPrev
= NULL
;
1066 XvPortRecPrivatePtr pPriv
;
1067 Bool visible
= (pWin
->visibility
== VisibilityUnobscured
) ||
1068 (pWin
->visibility
== VisibilityPartiallyObscured
);
1071 pPriv
= WinPriv
->PortRec
;
1073 if (pPriv
->pCompositeClip
&& pPriv
->FreeCompositeClip
)
1074 RegionDestroy(pPriv
->pCompositeClip
);
1076 pPriv
->pCompositeClip
= NULL
;
1078 /* Stop everything except images, but stop them too if the
1079 window isn't visible. But we only remove the images. */
1081 if (pPriv
->type
|| !visible
) {
1082 if (pPriv
->isOn
== XV_ON
) {
1083 (*pPriv
->AdaptorRec
->StopVideo
) (pPriv
->screen
,
1084 pPriv
->DevPriv
.ptr
, FALSE
);
1085 pPriv
->isOn
= XV_PENDING
;
1088 if (!pPriv
->type
) { /* overlaid still/image */
1089 pPriv
->pDraw
= NULL
;
1092 dixSetPrivate(&pWin
->devPrivates
, KdXVWindowKey
,
1095 pPrev
->next
= WinPriv
->next
;
1097 WinPriv
= WinPriv
->next
;
1104 WinPriv
= WinPriv
->next
;
1107 if (ScreenPriv
->ClipNotify
) {
1108 pScreen
->ClipNotify
= ScreenPriv
->ClipNotify
;
1109 (*pScreen
->ClipNotify
) (pWin
, dx
, dy
);
1110 pScreen
->ClipNotify
= KdXVClipNotify
;
1114 /**** Required XvScreenRec fields ****/
1117 KdXVCloseScreen(ScreenPtr pScreen
)
1119 XvScreenPtr pxvs
= GET_XV_SCREEN(pScreen
);
1120 KdXVScreenPtr ScreenPriv
= GET_KDXV_SCREEN(pScreen
);
1127 pScreen
->CreateWindow
= ScreenPriv
->CreateWindow
;
1128 pScreen
->DestroyWindow
= ScreenPriv
->DestroyWindow
;
1129 pScreen
->WindowExposures
= ScreenPriv
->WindowExposures
;
1130 pScreen
->ClipNotify
= ScreenPriv
->ClipNotify
;
1132 /* fprintf(stderr,"XV: Unwrapping screen funcs\n"); */
1134 for (c
= 0, pa
= pxvs
->pAdaptors
; c
< pxvs
->nAdaptors
; c
++, pa
++) {
1135 KdXVFreeAdaptor(pa
);
1138 free(pxvs
->pAdaptors
);
1145 KdXVQueryAdaptors(ScreenPtr pScreen
,
1146 XvAdaptorPtr
* p_pAdaptors
, int *p_nAdaptors
)
1148 XvScreenPtr pxvs
= GET_XV_SCREEN(pScreen
);
1150 *p_nAdaptors
= pxvs
->nAdaptors
;
1151 *p_pAdaptors
= pxvs
->pAdaptors
;
1157 KdXVRunning(ScreenPtr pScreen
)
1159 return (KdXVGeneration
== serverGeneration
&& GET_XV_SCREEN(pScreen
) != 0);
1163 KdXVEnable(ScreenPtr pScreen
)
1165 if (!KdXVRunning(pScreen
))
1168 WalkTree(pScreen
, KdXVReputAllVideo
, 0);
1174 KdXVDisable(ScreenPtr pScreen
)
1177 XvAdaptorPtr pAdaptor
;
1179 XvPortRecPrivatePtr pPriv
;
1182 if (!KdXVRunning(pScreen
))
1185 pxvs
= GET_XV_SCREEN(pScreen
);
1187 for (i
= 0; i
< pxvs
->nAdaptors
; i
++) {
1188 pAdaptor
= &pxvs
->pAdaptors
[i
];
1189 for (j
= 0; j
< pAdaptor
->nPorts
; j
++) {
1190 pPort
= &pAdaptor
->pPorts
[j
];
1191 pPriv
= (XvPortRecPrivatePtr
) pPort
->devPriv
.ptr
;
1192 if (pPriv
->isOn
> XV_OFF
) {
1194 (*pPriv
->AdaptorRec
->StopVideo
) (pPriv
->screen
,
1195 pPriv
->DevPriv
.ptr
, TRUE
);
1196 pPriv
->isOn
= XV_OFF
;
1198 if (pPriv
->pCompositeClip
&& pPriv
->FreeCompositeClip
)
1199 RegionDestroy(pPriv
->pCompositeClip
);
1201 pPriv
->pCompositeClip
= NULL
;
1203 if (!pPriv
->type
&& pPriv
->pDraw
) { /* still */
1204 KdXVRemovePortFromWindow((WindowPtr
) pPriv
->pDraw
, pPriv
);
1211 /**** XvAdaptorRec fields ****/
1214 KdXVAllocatePort(unsigned long port
, XvPortPtr pPort
, XvPortPtr
* ppPort
)
1221 KdXVFreePort(XvPortPtr pPort
)
1227 KdXVPutVideo(ClientPtr client
,
1231 INT16 vid_x
, INT16 vid_y
,
1232 CARD16 vid_w
, CARD16 vid_h
,
1233 INT16 drw_x
, INT16 drw_y
, CARD16 drw_w
, CARD16 drw_h
)
1235 XvPortRecPrivatePtr portPriv
= (XvPortRecPrivatePtr
) (pPort
->devPriv
.ptr
);
1237 KdScreenPriv(portPriv
->screen
->pScreen
);
1240 /* No dumping video to pixmaps... For now anyhow */
1241 if (pDraw
->type
!= DRAWABLE_WINDOW
) {
1242 pPort
->pDraw
= (DrawablePtr
) NULL
;
1246 /* If we are changing windows, unregister our port in the old window */
1247 if (portPriv
->pDraw
&& (portPriv
->pDraw
!= pDraw
))
1248 KdXVRemovePortFromWindow((WindowPtr
) (portPriv
->pDraw
), portPriv
);
1250 /* Register our port with the new window */
1251 result
= KdXVEnlistPortInWindow((WindowPtr
) pDraw
, portPriv
);
1252 if (result
!= Success
)
1255 portPriv
->pDraw
= pDraw
;
1256 portPriv
->type
= XvInputMask
;
1258 /* save a copy of these parameters */
1259 portPriv
->vid_x
= vid_x
;
1260 portPriv
->vid_y
= vid_y
;
1261 portPriv
->vid_w
= vid_w
;
1262 portPriv
->vid_h
= vid_h
;
1263 portPriv
->drw_x
= drw_x
;
1264 portPriv
->drw_y
= drw_y
;
1265 portPriv
->drw_w
= drw_w
;
1266 portPriv
->drw_h
= drw_h
;
1268 /* make sure we have the most recent copy of the clientClip */
1269 KdXVCopyClip(portPriv
, pGC
);
1271 /* To indicate to the DI layer that we were successful */
1272 pPort
->pDraw
= pDraw
;
1274 if (!pScreenPriv
->enabled
)
1277 return (KdXVReputVideo(portPriv
));
1281 KdXVPutStill(ClientPtr client
,
1285 INT16 vid_x
, INT16 vid_y
,
1286 CARD16 vid_w
, CARD16 vid_h
,
1287 INT16 drw_x
, INT16 drw_y
, CARD16 drw_w
, CARD16 drw_h
)
1289 XvPortRecPrivatePtr portPriv
= (XvPortRecPrivatePtr
) (pPort
->devPriv
.ptr
);
1290 ScreenPtr pScreen
= pDraw
->pScreen
;
1292 KdScreenPriv(pScreen
);
1293 KdScreenInfo
*screen
= pScreenPriv
->screen
;
1294 RegionRec WinRegion
;
1295 RegionRec ClipRegion
;
1298 Bool clippedAway
= FALSE
;
1300 if (pDraw
->type
!= DRAWABLE_WINDOW
)
1303 if (!pScreenPriv
->enabled
)
1306 WinBox
.x1
= pDraw
->x
+ drw_x
;
1307 WinBox
.y1
= pDraw
->y
+ drw_y
;
1308 WinBox
.x2
= WinBox
.x1
+ drw_w
;
1309 WinBox
.y2
= WinBox
.y1
+ drw_h
;
1311 RegionInit(&WinRegion
, &WinBox
, 1);
1312 RegionInit(&ClipRegion
, NullBox
, 1);
1313 RegionIntersect(&ClipRegion
, &WinRegion
, pGC
->pCompositeClip
);
1315 if (portPriv
->AdaptorRec
->flags
& VIDEO_CLIP_TO_VIEWPORT
) {
1321 VPBox
.x2
= screen
->width
;
1322 VPBox
.y2
= screen
->height
;
1324 RegionInit(&VPReg
, &VPBox
, 1);
1325 RegionIntersect(&ClipRegion
, &ClipRegion
, &VPReg
);
1326 RegionUninit(&VPReg
);
1329 if (portPriv
->pDraw
) {
1330 KdXVRemovePortFromWindow((WindowPtr
) (portPriv
->pDraw
), portPriv
);
1333 if (!RegionNotEmpty(&ClipRegion
)) {
1335 goto PUT_STILL_BAILOUT
;
1338 if (portPriv
->AdaptorRec
->flags
& VIDEO_NO_CLIPPING
) {
1339 BoxPtr clipBox
= RegionRects(&ClipRegion
);
1341 if ((RegionNumRects(&ClipRegion
) != 1) ||
1342 (clipBox
->x1
!= WinBox
.x1
) || (clipBox
->x2
!= WinBox
.x2
) ||
1343 (clipBox
->y1
!= WinBox
.y1
) || (clipBox
->y2
!= WinBox
.y2
)) {
1345 goto PUT_STILL_BAILOUT
;
1349 if (portPriv
->AdaptorRec
->flags
& VIDEO_INVERT_CLIPLIST
) {
1350 RegionSubtract(&ClipRegion
, &WinRegion
, &ClipRegion
);
1353 ret
= (*portPriv
->AdaptorRec
->PutStill
) (portPriv
->screen
, pDraw
,
1354 vid_x
, vid_y
, WinBox
.x1
, WinBox
.y1
,
1355 vid_w
, vid_h
, drw_w
, drw_h
,
1357 portPriv
->DevPriv
.ptr
);
1359 if ((ret
== Success
) &&
1360 (portPriv
->AdaptorRec
->flags
& VIDEO_OVERLAID_STILLS
)) {
1362 KdXVEnlistPortInWindow((WindowPtr
) pDraw
, portPriv
);
1363 portPriv
->isOn
= XV_ON
;
1364 portPriv
->pDraw
= pDraw
;
1365 portPriv
->drw_x
= drw_x
;
1366 portPriv
->drw_y
= drw_y
;
1367 portPriv
->drw_w
= drw_w
;
1368 portPriv
->drw_h
= drw_h
;
1369 portPriv
->type
= 0; /* no mask means it's transient and should
1370 not be reput once it's removed */
1371 pPort
->pDraw
= pDraw
; /* make sure we can get stop requests */
1376 if ((clippedAway
|| (ret
!= Success
)) && (portPriv
->isOn
== XV_ON
)) {
1377 (*portPriv
->AdaptorRec
->StopVideo
) (portPriv
->screen
,
1378 portPriv
->DevPriv
.ptr
, FALSE
);
1379 portPriv
->isOn
= XV_PENDING
;
1382 RegionUninit(&WinRegion
);
1383 RegionUninit(&ClipRegion
);
1389 KdXVGetVideo(ClientPtr client
,
1393 INT16 vid_x
, INT16 vid_y
,
1394 CARD16 vid_w
, CARD16 vid_h
,
1395 INT16 drw_x
, INT16 drw_y
, CARD16 drw_w
, CARD16 drw_h
)
1397 XvPortRecPrivatePtr portPriv
= (XvPortRecPrivatePtr
) (pPort
->devPriv
.ptr
);
1400 KdScreenPriv(portPriv
->screen
->pScreen
);
1402 /* No pixmaps... For now anyhow */
1403 if (pDraw
->type
!= DRAWABLE_WINDOW
) {
1404 pPort
->pDraw
= (DrawablePtr
) NULL
;
1408 /* If we are changing windows, unregister our port in the old window */
1409 if (portPriv
->pDraw
&& (portPriv
->pDraw
!= pDraw
))
1410 KdXVRemovePortFromWindow((WindowPtr
) (portPriv
->pDraw
), portPriv
);
1412 /* Register our port with the new window */
1413 result
= KdXVEnlistPortInWindow((WindowPtr
) pDraw
, portPriv
);
1414 if (result
!= Success
)
1417 portPriv
->pDraw
= pDraw
;
1418 portPriv
->type
= XvOutputMask
;
1420 /* save a copy of these parameters */
1421 portPriv
->vid_x
= vid_x
;
1422 portPriv
->vid_y
= vid_y
;
1423 portPriv
->vid_w
= vid_w
;
1424 portPriv
->vid_h
= vid_h
;
1425 portPriv
->drw_x
= drw_x
;
1426 portPriv
->drw_y
= drw_y
;
1427 portPriv
->drw_w
= drw_w
;
1428 portPriv
->drw_h
= drw_h
;
1430 /* make sure we have the most recent copy of the clientClip */
1431 KdXVCopyClip(portPriv
, pGC
);
1433 /* To indicate to the DI layer that we were successful */
1434 pPort
->pDraw
= pDraw
;
1436 if (!pScreenPriv
->enabled
)
1439 return (KdXVRegetVideo(portPriv
));
1443 KdXVGetStill(ClientPtr client
,
1447 INT16 vid_x
, INT16 vid_y
,
1448 CARD16 vid_w
, CARD16 vid_h
,
1449 INT16 drw_x
, INT16 drw_y
, CARD16 drw_w
, CARD16 drw_h
)
1451 XvPortRecPrivatePtr portPriv
= (XvPortRecPrivatePtr
) (pPort
->devPriv
.ptr
);
1452 ScreenPtr pScreen
= pDraw
->pScreen
;
1454 KdScreenPriv(pScreen
);
1455 RegionRec WinRegion
;
1456 RegionRec ClipRegion
;
1459 Bool clippedAway
= FALSE
;
1461 if (pDraw
->type
!= DRAWABLE_WINDOW
)
1464 if (!pScreenPriv
->enabled
)
1467 WinBox
.x1
= pDraw
->x
+ drw_x
;
1468 WinBox
.y1
= pDraw
->y
+ drw_y
;
1469 WinBox
.x2
= WinBox
.x1
+ drw_w
;
1470 WinBox
.y2
= WinBox
.y1
+ drw_h
;
1472 RegionInit(&WinRegion
, &WinBox
, 1);
1473 RegionInit(&ClipRegion
, NullBox
, 1);
1474 RegionIntersect(&ClipRegion
, &WinRegion
, pGC
->pCompositeClip
);
1476 if (portPriv
->pDraw
) {
1477 KdXVRemovePortFromWindow((WindowPtr
) (portPriv
->pDraw
), portPriv
);
1480 if (!RegionNotEmpty(&ClipRegion
)) {
1482 goto GET_STILL_BAILOUT
;
1485 if (portPriv
->AdaptorRec
->flags
& VIDEO_INVERT_CLIPLIST
) {
1486 RegionSubtract(&ClipRegion
, &WinRegion
, &ClipRegion
);
1489 ret
= (*portPriv
->AdaptorRec
->GetStill
) (portPriv
->screen
, pDraw
,
1490 vid_x
, vid_y
, WinBox
.x1
, WinBox
.y1
,
1491 vid_w
, vid_h
, drw_w
, drw_h
,
1493 portPriv
->DevPriv
.ptr
);
1497 if ((clippedAway
|| (ret
!= Success
)) && (portPriv
->isOn
== XV_ON
)) {
1498 (*portPriv
->AdaptorRec
->StopVideo
) (portPriv
->screen
,
1499 portPriv
->DevPriv
.ptr
, FALSE
);
1500 portPriv
->isOn
= XV_PENDING
;
1503 RegionUninit(&WinRegion
);
1504 RegionUninit(&ClipRegion
);
1510 KdXVStopVideo(ClientPtr client
, XvPortPtr pPort
, DrawablePtr pDraw
)
1512 XvPortRecPrivatePtr portPriv
= (XvPortRecPrivatePtr
) (pPort
->devPriv
.ptr
);
1514 KdScreenPriv(portPriv
->screen
->pScreen
);
1516 if (pDraw
->type
!= DRAWABLE_WINDOW
)
1519 KdXVRemovePortFromWindow((WindowPtr
) pDraw
, portPriv
);
1521 if (!pScreenPriv
->enabled
)
1524 /* Must free resources. */
1526 if (portPriv
->isOn
> XV_OFF
) {
1527 (*portPriv
->AdaptorRec
->StopVideo
) (portPriv
->screen
,
1528 portPriv
->DevPriv
.ptr
, TRUE
);
1529 portPriv
->isOn
= XV_OFF
;
1536 KdXVSetPortAttribute(ClientPtr client
,
1537 XvPortPtr pPort
, Atom attribute
, INT32 value
)
1539 XvPortRecPrivatePtr portPriv
= (XvPortRecPrivatePtr
) (pPort
->devPriv
.ptr
);
1541 return ((*portPriv
->AdaptorRec
->SetPortAttribute
) (portPriv
->screen
,
1543 portPriv
->DevPriv
.ptr
));
1547 KdXVGetPortAttribute(ClientPtr client
,
1548 XvPortPtr pPort
, Atom attribute
, INT32
*p_value
)
1550 XvPortRecPrivatePtr portPriv
= (XvPortRecPrivatePtr
) (pPort
->devPriv
.ptr
);
1552 return ((*portPriv
->AdaptorRec
->GetPortAttribute
) (portPriv
->screen
,
1555 portPriv
->DevPriv
.ptr
));
1559 KdXVQueryBestSize(ClientPtr client
,
1562 CARD16 vid_w
, CARD16 vid_h
,
1563 CARD16 drw_w
, CARD16 drw_h
,
1564 unsigned int *p_w
, unsigned int *p_h
)
1566 XvPortRecPrivatePtr portPriv
= (XvPortRecPrivatePtr
) (pPort
->devPriv
.ptr
);
1568 (*portPriv
->AdaptorRec
->QueryBestSize
) (portPriv
->screen
,
1569 (Bool
) motion
, vid_w
, vid_h
, drw_w
,
1571 portPriv
->DevPriv
.ptr
);
1577 KdXVPutImage(ClientPtr client
,
1581 INT16 src_x
, INT16 src_y
,
1582 CARD16 src_w
, CARD16 src_h
,
1583 INT16 drw_x
, INT16 drw_y
,
1584 CARD16 drw_w
, CARD16 drw_h
,
1586 unsigned char *data
, Bool sync
, CARD16 width
, CARD16 height
)
1588 XvPortRecPrivatePtr portPriv
= (XvPortRecPrivatePtr
) (pPort
->devPriv
.ptr
);
1589 ScreenPtr pScreen
= pDraw
->pScreen
;
1591 KdScreenPriv(pScreen
);
1592 RegionRec WinRegion
;
1593 RegionRec ClipRegion
;
1596 Bool clippedAway
= FALSE
;
1598 if (pDraw
->type
!= DRAWABLE_WINDOW
)
1601 if (!pScreenPriv
->enabled
)
1604 WinBox
.x1
= pDraw
->x
+ drw_x
;
1605 WinBox
.y1
= pDraw
->y
+ drw_y
;
1606 WinBox
.x2
= WinBox
.x1
+ drw_w
;
1607 WinBox
.y2
= WinBox
.y1
+ drw_h
;
1609 RegionInit(&WinRegion
, &WinBox
, 1);
1610 RegionInit(&ClipRegion
, NullBox
, 1);
1611 RegionIntersect(&ClipRegion
, &WinRegion
, pGC
->pCompositeClip
);
1613 if (portPriv
->AdaptorRec
->flags
& VIDEO_CLIP_TO_VIEWPORT
) {
1619 VPBox
.x2
= pScreen
->width
;
1620 VPBox
.y2
= pScreen
->height
;
1622 RegionInit(&VPReg
, &VPBox
, 1);
1623 RegionIntersect(&ClipRegion
, &ClipRegion
, &VPReg
);
1624 RegionUninit(&VPReg
);
1627 if (portPriv
->pDraw
) {
1628 KdXVRemovePortFromWindow((WindowPtr
) (portPriv
->pDraw
), portPriv
);
1631 if (!RegionNotEmpty(&ClipRegion
)) {
1633 goto PUT_IMAGE_BAILOUT
;
1636 if (portPriv
->AdaptorRec
->flags
& VIDEO_NO_CLIPPING
) {
1637 BoxPtr clipBox
= RegionRects(&ClipRegion
);
1639 if ((RegionNumRects(&ClipRegion
) != 1) ||
1640 (clipBox
->x1
!= WinBox
.x1
) || (clipBox
->x2
!= WinBox
.x2
) ||
1641 (clipBox
->y1
!= WinBox
.y1
) || (clipBox
->y2
!= WinBox
.y2
)) {
1643 goto PUT_IMAGE_BAILOUT
;
1647 if (portPriv
->AdaptorRec
->flags
& VIDEO_INVERT_CLIPLIST
) {
1648 RegionSubtract(&ClipRegion
, &WinRegion
, &ClipRegion
);
1651 ret
= (*portPriv
->AdaptorRec
->PutImage
) (portPriv
->screen
, pDraw
,
1652 src_x
, src_y
, WinBox
.x1
, WinBox
.y1
,
1653 src_w
, src_h
, drw_w
, drw_h
,
1654 format
->id
, data
, width
, height
,
1656 portPriv
->DevPriv
.ptr
);
1658 if ((ret
== Success
) &&
1659 (portPriv
->AdaptorRec
->flags
& VIDEO_OVERLAID_IMAGES
)) {
1661 KdXVEnlistPortInWindow((WindowPtr
) pDraw
, portPriv
);
1662 portPriv
->isOn
= XV_ON
;
1663 portPriv
->pDraw
= pDraw
;
1664 portPriv
->drw_x
= drw_x
;
1665 portPriv
->drw_y
= drw_y
;
1666 portPriv
->drw_w
= drw_w
;
1667 portPriv
->drw_h
= drw_h
;
1668 portPriv
->type
= 0; /* no mask means it's transient and should
1669 not be reput once it's removed */
1670 pPort
->pDraw
= pDraw
; /* make sure we can get stop requests */
1675 if ((clippedAway
|| (ret
!= Success
)) && (portPriv
->isOn
== XV_ON
)) {
1676 (*portPriv
->AdaptorRec
->StopVideo
) (portPriv
->screen
,
1677 portPriv
->DevPriv
.ptr
, FALSE
);
1678 portPriv
->isOn
= XV_PENDING
;
1681 RegionUninit(&WinRegion
);
1682 RegionUninit(&ClipRegion
);
1688 KdXVQueryImageAttributes(ClientPtr client
,
1692 CARD16
*height
, int *pitches
, int *offsets
)
1694 XvPortRecPrivatePtr portPriv
= (XvPortRecPrivatePtr
) (pPort
->devPriv
.ptr
);
1696 return (*portPriv
->AdaptorRec
->QueryImageAttributes
) (portPriv
->screen
,
1702 /**************** Common video manipulation functions *******************/
1705 KdXVCopyPackedData(KdScreenInfo
* screen
, CARD8
*src
, CARD8
*dst
, int randr
,
1706 int srcPitch
, int dstPitch
, int srcW
, int srcH
, int top
,
1707 int left
, int h
, int w
)
1709 int srcDown
= srcPitch
, srcRight
= 2, srcNext
;
1712 switch (randr
& RR_Rotate_All
) {
1718 src
+= (srcH
- 1) * 2;
1720 srcRight
= srcPitch
;
1723 src
+= srcPitch
* (srcH
- 1) + (srcW
- 1) * 2;
1724 srcDown
= -srcPitch
;
1728 src
+= srcPitch
* (srcW
- 1);
1730 srcRight
= -srcPitch
;
1734 src
= src
+ top
* srcDown
+ left
* srcRight
;
1737 /* srcRight >>= 1; */
1738 srcNext
= srcRight
>> 1;
1740 CARD16
*s
= (CARD16
*) src
;
1741 CARD32
*d
= (CARD32
*) dst
;
1745 *d
++ = s
[0] | (s
[srcNext
] << 16);
1754 KdXVCopyPlanarData(KdScreenInfo
* screen
, CARD8
*src
, CARD8
*dst
, int randr
,
1755 int srcPitch
, int srcPitch2
, int dstPitch
, int srcW
,
1756 int srcH
, int height
, int top
, int left
, int h
, int w
,
1760 CARD8
*src1
, *src2
, *src3
, *dst1
;
1761 int srcDown
= srcPitch
, srcDown2
= srcPitch2
;
1762 int srcRight
= 2, srcRight2
= 1, srcNext
= 1;
1764 /* compute source data pointers */
1766 src2
= src1
+ height
* srcPitch
;
1767 src3
= src2
+ (height
>> 1) * srcPitch2
;
1768 switch (randr
& RR_Rotate_All
) {
1771 srcDown2
= srcPitch2
;
1777 src1
= src1
+ srcH
- 1;
1778 src2
= src2
+ (srcH
>> 1) - 1;
1779 src3
= src3
+ (srcH
>> 1) - 1;
1782 srcRight
= srcPitch
* 2;
1783 srcRight2
= srcPitch2
;
1787 src1
= src1
+ srcPitch
* (srcH
- 1) + (srcW
- 1);
1788 src2
= src2
+ srcPitch2
* ((srcH
>> 1) - 1) + ((srcW
>> 1) - 1);
1789 src3
= src3
+ srcPitch2
* ((srcH
>> 1) - 1) + ((srcW
>> 1) - 1);
1790 srcDown
= -srcPitch
;
1791 srcDown2
= -srcPitch2
;
1797 src1
= src1
+ srcPitch
* (srcW
- 1);
1798 src2
= src2
+ srcPitch2
* ((srcW
>> 1) - 1);
1799 src3
= src3
+ srcPitch2
* ((srcW
>> 1) - 1);
1802 srcRight
= -srcPitch
* 2;
1803 srcRight2
= -srcPitch2
;
1804 srcNext
= -srcPitch
;
1808 /* adjust for origin */
1809 src1
+= top
* srcDown
+ left
* srcNext
;
1810 src2
+= (top
>> 1) * srcDown2
+ (left
>> 1) * srcRight2
;
1811 src3
+= (top
>> 1) * srcDown2
+ (left
>> 1) * srcRight2
;
1813 if (id
== FOURCC_I420
) {
1823 for (j
= 0; j
< h
; j
++) {
1824 CARD32
*dst
= (CARD32
*) dst1
;
1826 CARD8
*s1r
= src1
+ srcNext
;
1830 for (i
= 0; i
< w
; i
++) {
1831 *dst
++ = *s1l
| (*s1r
<< 16) | (*s3
<< 8) | (*s2
<< 24);
1847 KXVPaintRegion(DrawablePtr pDraw
, RegionPtr pRgn
, Pixel fg
)
1851 xRectangle
*rects
, *r
;
1852 BoxPtr pBox
= RegionRects(pRgn
);
1853 int nBox
= RegionNumRects(pRgn
);
1855 rects
= malloc(nBox
* sizeof(xRectangle
));
1860 r
->x
= pBox
->x1
- pDraw
->x
;
1861 r
->y
= pBox
->y1
- pDraw
->y
;
1862 r
->width
= pBox
->x2
- pBox
->x1
;
1863 r
->height
= pBox
->y2
- pBox
->y1
;
1868 pGC
= GetScratchGC(pDraw
->depth
, pDraw
->pScreen
);
1873 val
[1].val
= IncludeInferiors
;
1874 ChangeGC(NullClient
, pGC
, GCForeground
| GCSubwindowMode
, val
);
1876 ValidateGC(pDraw
, pGC
);
1878 (*pGC
->ops
->PolyFillRect
) (pDraw
, pGC
, RegionNumRects(pRgn
), rects
);