1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun * XFree86 Xv DDX written by Mark Vojkovich (markv@valinux.com)
3*4882a593Smuzhiyun */
4*4882a593Smuzhiyun /*
5*4882a593Smuzhiyun * Copyright (c) 1998-2003 by The XFree86 Project, Inc.
6*4882a593Smuzhiyun *
7*4882a593Smuzhiyun * Permission is hereby granted, free of charge, to any person obtaining a
8*4882a593Smuzhiyun * copy of this software and associated documentation files (the "Software"),
9*4882a593Smuzhiyun * to deal in the Software without restriction, including without limitation
10*4882a593Smuzhiyun * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11*4882a593Smuzhiyun * and/or sell copies of the Software, and to permit persons to whom the
12*4882a593Smuzhiyun * Software is furnished to do so, subject to the following conditions:
13*4882a593Smuzhiyun *
14*4882a593Smuzhiyun * The above copyright notice and this permission notice shall be included in
15*4882a593Smuzhiyun * all copies or substantial portions of the Software.
16*4882a593Smuzhiyun *
17*4882a593Smuzhiyun * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18*4882a593Smuzhiyun * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19*4882a593Smuzhiyun * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20*4882a593Smuzhiyun * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
21*4882a593Smuzhiyun * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
22*4882a593Smuzhiyun * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23*4882a593Smuzhiyun * OTHER DEALINGS IN THE SOFTWARE.
24*4882a593Smuzhiyun *
25*4882a593Smuzhiyun * Except as contained in this notice, the name of the copyright holder(s)
26*4882a593Smuzhiyun * and author(s) shall not be used in advertising or otherwise to promote
27*4882a593Smuzhiyun * the sale, use or other dealings in this Software without prior written
28*4882a593Smuzhiyun * authorization from the copyright holder(s) and author(s).
29*4882a593Smuzhiyun */
30*4882a593Smuzhiyun
31*4882a593Smuzhiyun #ifdef HAVE_XORG_CONFIG_H
32*4882a593Smuzhiyun #include <xorg-config.h>
33*4882a593Smuzhiyun #endif
34*4882a593Smuzhiyun
35*4882a593Smuzhiyun #include "misc.h"
36*4882a593Smuzhiyun #include "xf86.h"
37*4882a593Smuzhiyun #include "xf86_OSproc.h"
38*4882a593Smuzhiyun
39*4882a593Smuzhiyun #include <X11/X.h>
40*4882a593Smuzhiyun #include <X11/Xproto.h>
41*4882a593Smuzhiyun #include "scrnintstr.h"
42*4882a593Smuzhiyun #include "regionstr.h"
43*4882a593Smuzhiyun #include "windowstr.h"
44*4882a593Smuzhiyun #include "pixmapstr.h"
45*4882a593Smuzhiyun #include "mivalidate.h"
46*4882a593Smuzhiyun #include "validate.h"
47*4882a593Smuzhiyun #include "resource.h"
48*4882a593Smuzhiyun #include "gcstruct.h"
49*4882a593Smuzhiyun #include "dixstruct.h"
50*4882a593Smuzhiyun
51*4882a593Smuzhiyun #include <X11/extensions/Xv.h>
52*4882a593Smuzhiyun #include <X11/extensions/Xvproto.h>
53*4882a593Smuzhiyun #include "xvdix.h"
54*4882a593Smuzhiyun
55*4882a593Smuzhiyun #include "xf86xvpriv.h"
56*4882a593Smuzhiyun
57*4882a593Smuzhiyun /* XvAdaptorRec fields */
58*4882a593Smuzhiyun
59*4882a593Smuzhiyun static int xf86XVPutVideo(DrawablePtr, XvPortPtr, GCPtr,
60*4882a593Smuzhiyun INT16, INT16, CARD16, CARD16,
61*4882a593Smuzhiyun INT16, INT16, CARD16, CARD16);
62*4882a593Smuzhiyun static int xf86XVPutStill(DrawablePtr, XvPortPtr, GCPtr,
63*4882a593Smuzhiyun INT16, INT16, CARD16, CARD16,
64*4882a593Smuzhiyun INT16, INT16, CARD16, CARD16);
65*4882a593Smuzhiyun static int xf86XVGetVideo(DrawablePtr, XvPortPtr, GCPtr,
66*4882a593Smuzhiyun INT16, INT16, CARD16, CARD16,
67*4882a593Smuzhiyun INT16, INT16, CARD16, CARD16);
68*4882a593Smuzhiyun static int xf86XVGetStill(DrawablePtr, XvPortPtr, GCPtr,
69*4882a593Smuzhiyun INT16, INT16, CARD16, CARD16,
70*4882a593Smuzhiyun INT16, INT16, CARD16, CARD16);
71*4882a593Smuzhiyun static int xf86XVStopVideo(XvPortPtr, DrawablePtr);
72*4882a593Smuzhiyun static int xf86XVSetPortAttribute(XvPortPtr, Atom, INT32);
73*4882a593Smuzhiyun static int xf86XVGetPortAttribute(XvPortPtr, Atom, INT32 *);
74*4882a593Smuzhiyun static int xf86XVQueryBestSize(XvPortPtr, CARD8,
75*4882a593Smuzhiyun CARD16, CARD16, CARD16, CARD16,
76*4882a593Smuzhiyun unsigned int *, unsigned int *);
77*4882a593Smuzhiyun static int xf86XVPutImage(DrawablePtr, XvPortPtr, GCPtr,
78*4882a593Smuzhiyun INT16, INT16, CARD16, CARD16,
79*4882a593Smuzhiyun INT16, INT16, CARD16, CARD16,
80*4882a593Smuzhiyun XvImagePtr, unsigned char *, Bool, CARD16, CARD16);
81*4882a593Smuzhiyun static int xf86XVQueryImageAttributes(XvPortPtr, XvImagePtr,
82*4882a593Smuzhiyun CARD16 *, CARD16 *, int *, int *);
83*4882a593Smuzhiyun
84*4882a593Smuzhiyun /* ScreenRec fields */
85*4882a593Smuzhiyun
86*4882a593Smuzhiyun static Bool xf86XVDestroyWindow(WindowPtr pWin);
87*4882a593Smuzhiyun static void xf86XVWindowExposures(WindowPtr pWin, RegionPtr r1);
88*4882a593Smuzhiyun static void xf86XVPostValidateTree(WindowPtr pWin, WindowPtr pLayerWin,
89*4882a593Smuzhiyun VTKind kind);
90*4882a593Smuzhiyun static void xf86XVClipNotify(WindowPtr pWin, int dx, int dy);
91*4882a593Smuzhiyun static Bool xf86XVCloseScreen(ScreenPtr);
92*4882a593Smuzhiyun
93*4882a593Smuzhiyun #define PostValidateTreeUndefined ((PostValidateTreeProcPtr)-1)
94*4882a593Smuzhiyun
95*4882a593Smuzhiyun /* ScrnInfoRec functions */
96*4882a593Smuzhiyun
97*4882a593Smuzhiyun static Bool xf86XVEnterVT(ScrnInfoPtr);
98*4882a593Smuzhiyun static void xf86XVLeaveVT(ScrnInfoPtr);
99*4882a593Smuzhiyun static void xf86XVAdjustFrame(ScrnInfoPtr, int x, int y);
100*4882a593Smuzhiyun static void xf86XVModeSet(ScrnInfoPtr pScrn);
101*4882a593Smuzhiyun
102*4882a593Smuzhiyun /* misc */
103*4882a593Smuzhiyun
104*4882a593Smuzhiyun static Bool xf86XVInitAdaptors(ScreenPtr, XF86VideoAdaptorPtr *, int);
105*4882a593Smuzhiyun
106*4882a593Smuzhiyun static DevPrivateKeyRec XF86XVWindowKeyRec;
107*4882a593Smuzhiyun
108*4882a593Smuzhiyun #define XF86XVWindowKey (&XF86XVWindowKeyRec)
109*4882a593Smuzhiyun
110*4882a593Smuzhiyun /* dixmain.c XvScreenPtr screen private */
111*4882a593Smuzhiyun DevPrivateKey XF86XvScreenKey;
112*4882a593Smuzhiyun /** xf86xv.c XF86XVScreenPtr screen private */
113*4882a593Smuzhiyun static DevPrivateKeyRec XF86XVScreenPrivateKey;
114*4882a593Smuzhiyun
115*4882a593Smuzhiyun static unsigned long PortResource = 0;
116*4882a593Smuzhiyun
117*4882a593Smuzhiyun #define GET_XV_SCREEN(pScreen) \
118*4882a593Smuzhiyun ((XvScreenPtr)dixLookupPrivate(&(pScreen)->devPrivates, XF86XvScreenKey))
119*4882a593Smuzhiyun
120*4882a593Smuzhiyun #define GET_XF86XV_SCREEN(pScreen) \
121*4882a593Smuzhiyun ((XF86XVScreenPtr)(dixGetPrivate(&pScreen->devPrivates, &XF86XVScreenPrivateKey)))
122*4882a593Smuzhiyun
123*4882a593Smuzhiyun #define GET_XF86XV_WINDOW(pWin) \
124*4882a593Smuzhiyun ((XF86XVWindowPtr)dixLookupPrivate(&(pWin)->devPrivates, XF86XVWindowKey))
125*4882a593Smuzhiyun
126*4882a593Smuzhiyun static xf86XVInitGenericAdaptorPtr *GenDrivers = NULL;
127*4882a593Smuzhiyun static int NumGenDrivers = 0;
128*4882a593Smuzhiyun
129*4882a593Smuzhiyun int
xf86XVRegisterGenericAdaptorDriver(xf86XVInitGenericAdaptorPtr InitFunc)130*4882a593Smuzhiyun xf86XVRegisterGenericAdaptorDriver(xf86XVInitGenericAdaptorPtr InitFunc)
131*4882a593Smuzhiyun {
132*4882a593Smuzhiyun xf86XVInitGenericAdaptorPtr *newdrivers;
133*4882a593Smuzhiyun
134*4882a593Smuzhiyun newdrivers = reallocarray(GenDrivers, 1 + NumGenDrivers,
135*4882a593Smuzhiyun sizeof(xf86XVInitGenericAdaptorPtr));
136*4882a593Smuzhiyun if (!newdrivers)
137*4882a593Smuzhiyun return 0;
138*4882a593Smuzhiyun GenDrivers = newdrivers;
139*4882a593Smuzhiyun
140*4882a593Smuzhiyun GenDrivers[NumGenDrivers++] = InitFunc;
141*4882a593Smuzhiyun
142*4882a593Smuzhiyun return 1;
143*4882a593Smuzhiyun }
144*4882a593Smuzhiyun
145*4882a593Smuzhiyun int
xf86XVListGenericAdaptors(ScrnInfoPtr pScrn,XF86VideoAdaptorPtr ** adaptors)146*4882a593Smuzhiyun xf86XVListGenericAdaptors(ScrnInfoPtr pScrn, XF86VideoAdaptorPtr ** adaptors)
147*4882a593Smuzhiyun {
148*4882a593Smuzhiyun int i, j, n, num;
149*4882a593Smuzhiyun XF86VideoAdaptorPtr *DrivAdap, *new;
150*4882a593Smuzhiyun
151*4882a593Smuzhiyun num = 0;
152*4882a593Smuzhiyun *adaptors = NULL;
153*4882a593Smuzhiyun /*
154*4882a593Smuzhiyun * The v4l driver registers itself first, but can use surfaces registered
155*4882a593Smuzhiyun * by other drivers. So, call the v4l driver last.
156*4882a593Smuzhiyun */
157*4882a593Smuzhiyun for (i = NumGenDrivers; --i >= 0;) {
158*4882a593Smuzhiyun DrivAdap = NULL;
159*4882a593Smuzhiyun n = (*GenDrivers[i]) (pScrn, &DrivAdap);
160*4882a593Smuzhiyun if (0 == n)
161*4882a593Smuzhiyun continue;
162*4882a593Smuzhiyun new = reallocarray(*adaptors, num + n, sizeof(XF86VideoAdaptorPtr));
163*4882a593Smuzhiyun if (NULL == new)
164*4882a593Smuzhiyun continue;
165*4882a593Smuzhiyun *adaptors = new;
166*4882a593Smuzhiyun for (j = 0; j < n; j++, num++)
167*4882a593Smuzhiyun (*adaptors)[num] = DrivAdap[j];
168*4882a593Smuzhiyun }
169*4882a593Smuzhiyun return num;
170*4882a593Smuzhiyun }
171*4882a593Smuzhiyun
172*4882a593Smuzhiyun /**************** Offscreen surface stuff *******************/
173*4882a593Smuzhiyun
174*4882a593Smuzhiyun typedef struct {
175*4882a593Smuzhiyun XF86OffscreenImagePtr images;
176*4882a593Smuzhiyun int num;
177*4882a593Smuzhiyun } OffscreenImageRec;
178*4882a593Smuzhiyun
179*4882a593Smuzhiyun static DevPrivateKeyRec OffscreenPrivateKeyRec;
180*4882a593Smuzhiyun
181*4882a593Smuzhiyun #define OffscreenPrivateKey (&OffscreenPrivateKeyRec)
182*4882a593Smuzhiyun #define GetOffscreenImage(pScreen) ((OffscreenImageRec *) dixLookupPrivate(&(pScreen)->devPrivates, OffscreenPrivateKey))
183*4882a593Smuzhiyun
184*4882a593Smuzhiyun Bool
xf86XVRegisterOffscreenImages(ScreenPtr pScreen,XF86OffscreenImagePtr images,int num)185*4882a593Smuzhiyun xf86XVRegisterOffscreenImages(ScreenPtr pScreen,
186*4882a593Smuzhiyun XF86OffscreenImagePtr images, int num)
187*4882a593Smuzhiyun {
188*4882a593Smuzhiyun OffscreenImageRec *OffscreenImage;
189*4882a593Smuzhiyun
190*4882a593Smuzhiyun /* This function may be called before xf86XVScreenInit, so there's
191*4882a593Smuzhiyun * no better place than this to call dixRegisterPrivateKey to ensure we
192*4882a593Smuzhiyun * have space reserved. After the first call it is a no-op. */
193*4882a593Smuzhiyun if (!dixRegisterPrivateKey
194*4882a593Smuzhiyun (OffscreenPrivateKey, PRIVATE_SCREEN, sizeof(OffscreenImageRec)) ||
195*4882a593Smuzhiyun !(OffscreenImage = GetOffscreenImage(pScreen)))
196*4882a593Smuzhiyun /* Every X.org driver assumes this function always succeeds, so
197*4882a593Smuzhiyun * just die on allocation failure. */
198*4882a593Smuzhiyun FatalError
199*4882a593Smuzhiyun ("Could not allocate private storage for XV offscreen images.\n");
200*4882a593Smuzhiyun
201*4882a593Smuzhiyun OffscreenImage->num = num;
202*4882a593Smuzhiyun OffscreenImage->images = images;
203*4882a593Smuzhiyun return TRUE;
204*4882a593Smuzhiyun }
205*4882a593Smuzhiyun
206*4882a593Smuzhiyun XF86OffscreenImagePtr
xf86XVQueryOffscreenImages(ScreenPtr pScreen,int * num)207*4882a593Smuzhiyun xf86XVQueryOffscreenImages(ScreenPtr pScreen, int *num)
208*4882a593Smuzhiyun {
209*4882a593Smuzhiyun OffscreenImageRec *OffscreenImage = GetOffscreenImage(pScreen);
210*4882a593Smuzhiyun
211*4882a593Smuzhiyun *num = OffscreenImage->num;
212*4882a593Smuzhiyun return OffscreenImage->images;
213*4882a593Smuzhiyun }
214*4882a593Smuzhiyun
215*4882a593Smuzhiyun XF86VideoAdaptorPtr
xf86XVAllocateVideoAdaptorRec(ScrnInfoPtr pScrn)216*4882a593Smuzhiyun xf86XVAllocateVideoAdaptorRec(ScrnInfoPtr pScrn)
217*4882a593Smuzhiyun {
218*4882a593Smuzhiyun return calloc(1, sizeof(XF86VideoAdaptorRec));
219*4882a593Smuzhiyun }
220*4882a593Smuzhiyun
221*4882a593Smuzhiyun void
xf86XVFreeVideoAdaptorRec(XF86VideoAdaptorPtr ptr)222*4882a593Smuzhiyun xf86XVFreeVideoAdaptorRec(XF86VideoAdaptorPtr ptr)
223*4882a593Smuzhiyun {
224*4882a593Smuzhiyun free(ptr);
225*4882a593Smuzhiyun }
226*4882a593Smuzhiyun
227*4882a593Smuzhiyun Bool
xf86XVScreenInit(ScreenPtr pScreen,XF86VideoAdaptorPtr * adaptors,int num)228*4882a593Smuzhiyun xf86XVScreenInit(ScreenPtr pScreen, XF86VideoAdaptorPtr * adaptors, int num)
229*4882a593Smuzhiyun {
230*4882a593Smuzhiyun ScrnInfoPtr pScrn;
231*4882a593Smuzhiyun XF86XVScreenPtr ScreenPriv;
232*4882a593Smuzhiyun
233*4882a593Smuzhiyun if (num <= 0 || noXvExtension)
234*4882a593Smuzhiyun return FALSE;
235*4882a593Smuzhiyun
236*4882a593Smuzhiyun if (Success != XvScreenInit(pScreen))
237*4882a593Smuzhiyun return FALSE;
238*4882a593Smuzhiyun
239*4882a593Smuzhiyun if (!dixRegisterPrivateKey(&XF86XVWindowKeyRec, PRIVATE_WINDOW, 0))
240*4882a593Smuzhiyun return FALSE;
241*4882a593Smuzhiyun if (!dixRegisterPrivateKey(&XF86XVScreenPrivateKey, PRIVATE_SCREEN, 0))
242*4882a593Smuzhiyun return FALSE;
243*4882a593Smuzhiyun
244*4882a593Smuzhiyun XF86XvScreenKey = XvGetScreenKey();
245*4882a593Smuzhiyun
246*4882a593Smuzhiyun PortResource = XvGetRTPort();
247*4882a593Smuzhiyun
248*4882a593Smuzhiyun ScreenPriv = malloc(sizeof(XF86XVScreenRec));
249*4882a593Smuzhiyun dixSetPrivate(&pScreen->devPrivates, &XF86XVScreenPrivateKey, ScreenPriv);
250*4882a593Smuzhiyun
251*4882a593Smuzhiyun if (!ScreenPriv)
252*4882a593Smuzhiyun return FALSE;
253*4882a593Smuzhiyun
254*4882a593Smuzhiyun pScrn = xf86ScreenToScrn(pScreen);
255*4882a593Smuzhiyun
256*4882a593Smuzhiyun ScreenPriv->DestroyWindow = pScreen->DestroyWindow;
257*4882a593Smuzhiyun ScreenPriv->WindowExposures = pScreen->WindowExposures;
258*4882a593Smuzhiyun ScreenPriv->PostValidateTree = PostValidateTreeUndefined;
259*4882a593Smuzhiyun ScreenPriv->ClipNotify = pScreen->ClipNotify;
260*4882a593Smuzhiyun ScreenPriv->CloseScreen = pScreen->CloseScreen;
261*4882a593Smuzhiyun ScreenPriv->EnterVT = pScrn->EnterVT;
262*4882a593Smuzhiyun ScreenPriv->LeaveVT = pScrn->LeaveVT;
263*4882a593Smuzhiyun ScreenPriv->AdjustFrame = pScrn->AdjustFrame;
264*4882a593Smuzhiyun ScreenPriv->ModeSet = pScrn->ModeSet;
265*4882a593Smuzhiyun
266*4882a593Smuzhiyun pScreen->DestroyWindow = xf86XVDestroyWindow;
267*4882a593Smuzhiyun pScreen->WindowExposures = xf86XVWindowExposures;
268*4882a593Smuzhiyun pScreen->ClipNotify = xf86XVClipNotify;
269*4882a593Smuzhiyun pScreen->CloseScreen = xf86XVCloseScreen;
270*4882a593Smuzhiyun pScrn->EnterVT = xf86XVEnterVT;
271*4882a593Smuzhiyun pScrn->LeaveVT = xf86XVLeaveVT;
272*4882a593Smuzhiyun if (pScrn->AdjustFrame)
273*4882a593Smuzhiyun pScrn->AdjustFrame = xf86XVAdjustFrame;
274*4882a593Smuzhiyun pScrn->ModeSet = xf86XVModeSet;
275*4882a593Smuzhiyun
276*4882a593Smuzhiyun if (!xf86XVInitAdaptors(pScreen, adaptors, num))
277*4882a593Smuzhiyun return FALSE;
278*4882a593Smuzhiyun
279*4882a593Smuzhiyun return TRUE;
280*4882a593Smuzhiyun }
281*4882a593Smuzhiyun
282*4882a593Smuzhiyun static void
xf86XVFreeAdaptor(XvAdaptorPtr pAdaptor)283*4882a593Smuzhiyun xf86XVFreeAdaptor(XvAdaptorPtr pAdaptor)
284*4882a593Smuzhiyun {
285*4882a593Smuzhiyun int i;
286*4882a593Smuzhiyun
287*4882a593Smuzhiyun if (pAdaptor->pPorts) {
288*4882a593Smuzhiyun XvPortPtr pPort = pAdaptor->pPorts;
289*4882a593Smuzhiyun XvPortRecPrivatePtr pPriv;
290*4882a593Smuzhiyun
291*4882a593Smuzhiyun for (i = 0; i < pAdaptor->nPorts; i++, pPort++) {
292*4882a593Smuzhiyun pPriv = (XvPortRecPrivatePtr) pPort->devPriv.ptr;
293*4882a593Smuzhiyun if (pPriv) {
294*4882a593Smuzhiyun if (pPriv->clientClip)
295*4882a593Smuzhiyun RegionDestroy(pPriv->clientClip);
296*4882a593Smuzhiyun if (pPriv->pCompositeClip && pPriv->FreeCompositeClip)
297*4882a593Smuzhiyun RegionDestroy(pPriv->pCompositeClip);
298*4882a593Smuzhiyun if (pPriv->ckeyFilled)
299*4882a593Smuzhiyun RegionDestroy(pPriv->ckeyFilled);
300*4882a593Smuzhiyun free(pPriv);
301*4882a593Smuzhiyun }
302*4882a593Smuzhiyun }
303*4882a593Smuzhiyun }
304*4882a593Smuzhiyun
305*4882a593Smuzhiyun XvFreeAdaptor(pAdaptor);
306*4882a593Smuzhiyun }
307*4882a593Smuzhiyun
308*4882a593Smuzhiyun static Bool
xf86XVInitAdaptors(ScreenPtr pScreen,XF86VideoAdaptorPtr * infoPtr,int number)309*4882a593Smuzhiyun xf86XVInitAdaptors(ScreenPtr pScreen, XF86VideoAdaptorPtr * infoPtr, int number)
310*4882a593Smuzhiyun {
311*4882a593Smuzhiyun XvScreenPtr pxvs = GET_XV_SCREEN(pScreen);
312*4882a593Smuzhiyun ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
313*4882a593Smuzhiyun XF86VideoAdaptorPtr adaptorPtr;
314*4882a593Smuzhiyun XvAdaptorPtr pAdaptor, pa;
315*4882a593Smuzhiyun XvAdaptorRecPrivatePtr adaptorPriv;
316*4882a593Smuzhiyun int na, numAdaptor;
317*4882a593Smuzhiyun XvPortRecPrivatePtr portPriv;
318*4882a593Smuzhiyun XvPortPtr pPort, pp;
319*4882a593Smuzhiyun int numPort;
320*4882a593Smuzhiyun XF86VideoFormatPtr formatPtr;
321*4882a593Smuzhiyun XvFormatPtr pFormat, pf;
322*4882a593Smuzhiyun int numFormat, totFormat;
323*4882a593Smuzhiyun XF86VideoEncodingPtr encodingPtr;
324*4882a593Smuzhiyun XvEncodingPtr pEncode, pe;
325*4882a593Smuzhiyun int numVisuals;
326*4882a593Smuzhiyun VisualPtr pVisual;
327*4882a593Smuzhiyun int i;
328*4882a593Smuzhiyun
329*4882a593Smuzhiyun pxvs->nAdaptors = 0;
330*4882a593Smuzhiyun pxvs->pAdaptors = NULL;
331*4882a593Smuzhiyun
332*4882a593Smuzhiyun if (!(pAdaptor = calloc(number, sizeof(XvAdaptorRec))))
333*4882a593Smuzhiyun return FALSE;
334*4882a593Smuzhiyun
335*4882a593Smuzhiyun for (pa = pAdaptor, na = 0, numAdaptor = 0; na < number; na++, adaptorPtr++) {
336*4882a593Smuzhiyun adaptorPtr = infoPtr[na];
337*4882a593Smuzhiyun
338*4882a593Smuzhiyun if (!adaptorPtr->StopVideo || !adaptorPtr->SetPortAttribute ||
339*4882a593Smuzhiyun !adaptorPtr->GetPortAttribute || !adaptorPtr->QueryBestSize)
340*4882a593Smuzhiyun continue;
341*4882a593Smuzhiyun
342*4882a593Smuzhiyun /* client libs expect at least one encoding */
343*4882a593Smuzhiyun if (!adaptorPtr->nEncodings || !adaptorPtr->pEncodings)
344*4882a593Smuzhiyun continue;
345*4882a593Smuzhiyun
346*4882a593Smuzhiyun pa->type = adaptorPtr->type;
347*4882a593Smuzhiyun
348*4882a593Smuzhiyun if (!adaptorPtr->PutVideo && !adaptorPtr->GetVideo)
349*4882a593Smuzhiyun pa->type &= ~XvVideoMask;
350*4882a593Smuzhiyun
351*4882a593Smuzhiyun if (!adaptorPtr->PutStill && !adaptorPtr->GetStill)
352*4882a593Smuzhiyun pa->type &= ~XvStillMask;
353*4882a593Smuzhiyun
354*4882a593Smuzhiyun if (!adaptorPtr->PutImage || !adaptorPtr->QueryImageAttributes)
355*4882a593Smuzhiyun pa->type &= ~XvImageMask;
356*4882a593Smuzhiyun
357*4882a593Smuzhiyun if (!adaptorPtr->PutVideo && !adaptorPtr->PutImage &&
358*4882a593Smuzhiyun !adaptorPtr->PutStill)
359*4882a593Smuzhiyun pa->type &= ~XvInputMask;
360*4882a593Smuzhiyun
361*4882a593Smuzhiyun if (!adaptorPtr->GetVideo && !adaptorPtr->GetStill)
362*4882a593Smuzhiyun pa->type &= ~XvOutputMask;
363*4882a593Smuzhiyun
364*4882a593Smuzhiyun if (!(adaptorPtr->type & (XvPixmapMask | XvWindowMask)))
365*4882a593Smuzhiyun continue;
366*4882a593Smuzhiyun if (!(adaptorPtr->type & (XvImageMask | XvVideoMask | XvStillMask)))
367*4882a593Smuzhiyun continue;
368*4882a593Smuzhiyun
369*4882a593Smuzhiyun pa->pScreen = pScreen;
370*4882a593Smuzhiyun pa->ddPutVideo = xf86XVPutVideo;
371*4882a593Smuzhiyun pa->ddPutStill = xf86XVPutStill;
372*4882a593Smuzhiyun pa->ddGetVideo = xf86XVGetVideo;
373*4882a593Smuzhiyun pa->ddGetStill = xf86XVGetStill;
374*4882a593Smuzhiyun pa->ddStopVideo = xf86XVStopVideo;
375*4882a593Smuzhiyun pa->ddPutImage = xf86XVPutImage;
376*4882a593Smuzhiyun pa->ddSetPortAttribute = xf86XVSetPortAttribute;
377*4882a593Smuzhiyun pa->ddGetPortAttribute = xf86XVGetPortAttribute;
378*4882a593Smuzhiyun pa->ddQueryBestSize = xf86XVQueryBestSize;
379*4882a593Smuzhiyun pa->ddQueryImageAttributes = xf86XVQueryImageAttributes;
380*4882a593Smuzhiyun pa->name = strdup(adaptorPtr->name);
381*4882a593Smuzhiyun
382*4882a593Smuzhiyun if (adaptorPtr->nEncodings &&
383*4882a593Smuzhiyun (pEncode = calloc(adaptorPtr->nEncodings, sizeof(XvEncodingRec)))) {
384*4882a593Smuzhiyun
385*4882a593Smuzhiyun for (pe = pEncode, encodingPtr = adaptorPtr->pEncodings, i = 0;
386*4882a593Smuzhiyun i < adaptorPtr->nEncodings; pe++, i++, encodingPtr++) {
387*4882a593Smuzhiyun pe->id = encodingPtr->id;
388*4882a593Smuzhiyun pe->pScreen = pScreen;
389*4882a593Smuzhiyun pe->name = strdup(encodingPtr->name);
390*4882a593Smuzhiyun pe->width = encodingPtr->width;
391*4882a593Smuzhiyun pe->height = encodingPtr->height;
392*4882a593Smuzhiyun pe->rate.numerator = encodingPtr->rate.numerator;
393*4882a593Smuzhiyun pe->rate.denominator = encodingPtr->rate.denominator;
394*4882a593Smuzhiyun }
395*4882a593Smuzhiyun pa->nEncodings = adaptorPtr->nEncodings;
396*4882a593Smuzhiyun pa->pEncodings = pEncode;
397*4882a593Smuzhiyun }
398*4882a593Smuzhiyun
399*4882a593Smuzhiyun if (adaptorPtr->nImages &&
400*4882a593Smuzhiyun (pa->pImages = calloc(adaptorPtr->nImages, sizeof(XvImageRec)))) {
401*4882a593Smuzhiyun memcpy(pa->pImages, adaptorPtr->pImages,
402*4882a593Smuzhiyun adaptorPtr->nImages * sizeof(XvImageRec));
403*4882a593Smuzhiyun pa->nImages = adaptorPtr->nImages;
404*4882a593Smuzhiyun }
405*4882a593Smuzhiyun
406*4882a593Smuzhiyun if (adaptorPtr->nAttributes &&
407*4882a593Smuzhiyun (pa->pAttributes = calloc(adaptorPtr->nAttributes,
408*4882a593Smuzhiyun sizeof(XvAttributeRec)))) {
409*4882a593Smuzhiyun memcpy(pa->pAttributes, adaptorPtr->pAttributes,
410*4882a593Smuzhiyun adaptorPtr->nAttributes * sizeof(XvAttributeRec));
411*4882a593Smuzhiyun
412*4882a593Smuzhiyun for (i = 0; i < adaptorPtr->nAttributes; i++) {
413*4882a593Smuzhiyun pa->pAttributes[i].name =
414*4882a593Smuzhiyun strdup(adaptorPtr->pAttributes[i].name);
415*4882a593Smuzhiyun }
416*4882a593Smuzhiyun
417*4882a593Smuzhiyun pa->nAttributes = adaptorPtr->nAttributes;
418*4882a593Smuzhiyun }
419*4882a593Smuzhiyun
420*4882a593Smuzhiyun totFormat = adaptorPtr->nFormats;
421*4882a593Smuzhiyun
422*4882a593Smuzhiyun if (!(pFormat = calloc(totFormat, sizeof(XvFormatRec)))) {
423*4882a593Smuzhiyun xf86XVFreeAdaptor(pa);
424*4882a593Smuzhiyun continue;
425*4882a593Smuzhiyun }
426*4882a593Smuzhiyun for (pf = pFormat, i = 0, numFormat = 0, formatPtr =
427*4882a593Smuzhiyun adaptorPtr->pFormats; i < adaptorPtr->nFormats; i++, formatPtr++) {
428*4882a593Smuzhiyun numVisuals = pScreen->numVisuals;
429*4882a593Smuzhiyun pVisual = pScreen->visuals;
430*4882a593Smuzhiyun
431*4882a593Smuzhiyun while (numVisuals--) {
432*4882a593Smuzhiyun if ((pVisual->class == formatPtr->class) &&
433*4882a593Smuzhiyun (pVisual->nplanes == formatPtr->depth)) {
434*4882a593Smuzhiyun
435*4882a593Smuzhiyun if (numFormat >= totFormat) {
436*4882a593Smuzhiyun void *moreSpace;
437*4882a593Smuzhiyun
438*4882a593Smuzhiyun totFormat *= 2;
439*4882a593Smuzhiyun moreSpace = reallocarray(pFormat, totFormat,
440*4882a593Smuzhiyun sizeof(XvFormatRec));
441*4882a593Smuzhiyun if (!moreSpace)
442*4882a593Smuzhiyun break;
443*4882a593Smuzhiyun pFormat = moreSpace;
444*4882a593Smuzhiyun pf = pFormat + numFormat;
445*4882a593Smuzhiyun }
446*4882a593Smuzhiyun
447*4882a593Smuzhiyun pf->visual = pVisual->vid;
448*4882a593Smuzhiyun pf->depth = formatPtr->depth;
449*4882a593Smuzhiyun
450*4882a593Smuzhiyun pf++;
451*4882a593Smuzhiyun numFormat++;
452*4882a593Smuzhiyun }
453*4882a593Smuzhiyun pVisual++;
454*4882a593Smuzhiyun }
455*4882a593Smuzhiyun }
456*4882a593Smuzhiyun pa->nFormats = numFormat;
457*4882a593Smuzhiyun pa->pFormats = pFormat;
458*4882a593Smuzhiyun if (!numFormat) {
459*4882a593Smuzhiyun xf86XVFreeAdaptor(pa);
460*4882a593Smuzhiyun continue;
461*4882a593Smuzhiyun }
462*4882a593Smuzhiyun
463*4882a593Smuzhiyun if (!(adaptorPriv = calloc(1, sizeof(XvAdaptorRecPrivate)))) {
464*4882a593Smuzhiyun xf86XVFreeAdaptor(pa);
465*4882a593Smuzhiyun continue;
466*4882a593Smuzhiyun }
467*4882a593Smuzhiyun
468*4882a593Smuzhiyun adaptorPriv->flags = adaptorPtr->flags;
469*4882a593Smuzhiyun adaptorPriv->PutVideo = adaptorPtr->PutVideo;
470*4882a593Smuzhiyun adaptorPriv->PutStill = adaptorPtr->PutStill;
471*4882a593Smuzhiyun adaptorPriv->GetVideo = adaptorPtr->GetVideo;
472*4882a593Smuzhiyun adaptorPriv->GetStill = adaptorPtr->GetStill;
473*4882a593Smuzhiyun adaptorPriv->StopVideo = adaptorPtr->StopVideo;
474*4882a593Smuzhiyun adaptorPriv->SetPortAttribute = adaptorPtr->SetPortAttribute;
475*4882a593Smuzhiyun adaptorPriv->GetPortAttribute = adaptorPtr->GetPortAttribute;
476*4882a593Smuzhiyun adaptorPriv->QueryBestSize = adaptorPtr->QueryBestSize;
477*4882a593Smuzhiyun adaptorPriv->QueryImageAttributes = adaptorPtr->QueryImageAttributes;
478*4882a593Smuzhiyun adaptorPriv->PutImage = adaptorPtr->PutImage;
479*4882a593Smuzhiyun adaptorPriv->ReputImage = adaptorPtr->ReputImage; /* image/still */
480*4882a593Smuzhiyun
481*4882a593Smuzhiyun pa->devPriv.ptr = (void *) adaptorPriv;
482*4882a593Smuzhiyun
483*4882a593Smuzhiyun if (!(pPort = calloc(adaptorPtr->nPorts, sizeof(XvPortRec)))) {
484*4882a593Smuzhiyun xf86XVFreeAdaptor(pa);
485*4882a593Smuzhiyun continue;
486*4882a593Smuzhiyun }
487*4882a593Smuzhiyun for (pp = pPort, i = 0, numPort = 0; i < adaptorPtr->nPorts; i++) {
488*4882a593Smuzhiyun
489*4882a593Smuzhiyun if (!(pp->id = FakeClientID(0)))
490*4882a593Smuzhiyun continue;
491*4882a593Smuzhiyun
492*4882a593Smuzhiyun if (!(portPriv = calloc(1, sizeof(XvPortRecPrivate))))
493*4882a593Smuzhiyun continue;
494*4882a593Smuzhiyun
495*4882a593Smuzhiyun if (!AddResource(pp->id, PortResource, pp)) {
496*4882a593Smuzhiyun free(portPriv);
497*4882a593Smuzhiyun continue;
498*4882a593Smuzhiyun }
499*4882a593Smuzhiyun
500*4882a593Smuzhiyun pp->pAdaptor = pa;
501*4882a593Smuzhiyun pp->pNotify = (XvPortNotifyPtr) NULL;
502*4882a593Smuzhiyun pp->pDraw = (DrawablePtr) NULL;
503*4882a593Smuzhiyun pp->client = (ClientPtr) NULL;
504*4882a593Smuzhiyun pp->grab.client = (ClientPtr) NULL;
505*4882a593Smuzhiyun pp->time = currentTime;
506*4882a593Smuzhiyun pp->devPriv.ptr = portPriv;
507*4882a593Smuzhiyun
508*4882a593Smuzhiyun portPriv->pScrn = pScrn;
509*4882a593Smuzhiyun portPriv->AdaptorRec = adaptorPriv;
510*4882a593Smuzhiyun portPriv->DevPriv.ptr = adaptorPtr->pPortPrivates[i].ptr;
511*4882a593Smuzhiyun
512*4882a593Smuzhiyun pp++;
513*4882a593Smuzhiyun numPort++;
514*4882a593Smuzhiyun }
515*4882a593Smuzhiyun pa->nPorts = numPort;
516*4882a593Smuzhiyun pa->pPorts = pPort;
517*4882a593Smuzhiyun if (!numPort) {
518*4882a593Smuzhiyun xf86XVFreeAdaptor(pa);
519*4882a593Smuzhiyun continue;
520*4882a593Smuzhiyun }
521*4882a593Smuzhiyun
522*4882a593Smuzhiyun pa->base_id = pPort->id;
523*4882a593Smuzhiyun
524*4882a593Smuzhiyun pa++;
525*4882a593Smuzhiyun numAdaptor++;
526*4882a593Smuzhiyun }
527*4882a593Smuzhiyun
528*4882a593Smuzhiyun if (numAdaptor) {
529*4882a593Smuzhiyun pxvs->nAdaptors = numAdaptor;
530*4882a593Smuzhiyun pxvs->pAdaptors = pAdaptor;
531*4882a593Smuzhiyun }
532*4882a593Smuzhiyun else {
533*4882a593Smuzhiyun free(pAdaptor);
534*4882a593Smuzhiyun return FALSE;
535*4882a593Smuzhiyun }
536*4882a593Smuzhiyun
537*4882a593Smuzhiyun return TRUE;
538*4882a593Smuzhiyun }
539*4882a593Smuzhiyun
540*4882a593Smuzhiyun /* Video should be clipped to the intersection of the window cliplist
541*4882a593Smuzhiyun and the client cliplist specified in the GC for which the video was
542*4882a593Smuzhiyun initialized. When we need to reclip a window, the GC that started
543*4882a593Smuzhiyun the video may not even be around anymore. That's why we save the
544*4882a593Smuzhiyun client clip from the GC when the video is initialized. We then
545*4882a593Smuzhiyun use xf86XVUpdateCompositeClip to calculate the new composite clip
546*4882a593Smuzhiyun when we need it. This is different from what DEC did. They saved
547*4882a593Smuzhiyun the GC and used it's clip list when they needed to reclip the window,
548*4882a593Smuzhiyun even if the client clip was different from the one the video was
549*4882a593Smuzhiyun initialized with. If the original GC was destroyed, they had to stop
550*4882a593Smuzhiyun the video. I like the new method better (MArk).
551*4882a593Smuzhiyun
552*4882a593Smuzhiyun This function only works for windows. Will need to rewrite when
553*4882a593Smuzhiyun (if) we support pixmap rendering.
554*4882a593Smuzhiyun */
555*4882a593Smuzhiyun
556*4882a593Smuzhiyun static void
xf86XVUpdateCompositeClip(XvPortRecPrivatePtr portPriv)557*4882a593Smuzhiyun xf86XVUpdateCompositeClip(XvPortRecPrivatePtr portPriv)
558*4882a593Smuzhiyun {
559*4882a593Smuzhiyun RegionPtr pregWin, pCompositeClip;
560*4882a593Smuzhiyun WindowPtr pWin;
561*4882a593Smuzhiyun Bool freeCompClip = FALSE;
562*4882a593Smuzhiyun
563*4882a593Smuzhiyun if (portPriv->pCompositeClip)
564*4882a593Smuzhiyun return;
565*4882a593Smuzhiyun
566*4882a593Smuzhiyun pWin = (WindowPtr) portPriv->pDraw;
567*4882a593Smuzhiyun
568*4882a593Smuzhiyun /* get window clip list */
569*4882a593Smuzhiyun if (portPriv->subWindowMode == IncludeInferiors) {
570*4882a593Smuzhiyun pregWin = NotClippedByChildren(pWin);
571*4882a593Smuzhiyun freeCompClip = TRUE;
572*4882a593Smuzhiyun }
573*4882a593Smuzhiyun else
574*4882a593Smuzhiyun pregWin = &pWin->clipList;
575*4882a593Smuzhiyun
576*4882a593Smuzhiyun if (!portPriv->clientClip) {
577*4882a593Smuzhiyun portPriv->pCompositeClip = pregWin;
578*4882a593Smuzhiyun portPriv->FreeCompositeClip = freeCompClip;
579*4882a593Smuzhiyun return;
580*4882a593Smuzhiyun }
581*4882a593Smuzhiyun
582*4882a593Smuzhiyun pCompositeClip = RegionCreate(NullBox, 1);
583*4882a593Smuzhiyun RegionCopy(pCompositeClip, portPriv->clientClip);
584*4882a593Smuzhiyun RegionTranslate(pCompositeClip, portPriv->pDraw->x, portPriv->pDraw->y);
585*4882a593Smuzhiyun RegionIntersect(pCompositeClip, pregWin, pCompositeClip);
586*4882a593Smuzhiyun
587*4882a593Smuzhiyun portPriv->pCompositeClip = pCompositeClip;
588*4882a593Smuzhiyun portPriv->FreeCompositeClip = TRUE;
589*4882a593Smuzhiyun
590*4882a593Smuzhiyun if (freeCompClip) {
591*4882a593Smuzhiyun RegionDestroy(pregWin);
592*4882a593Smuzhiyun }
593*4882a593Smuzhiyun }
594*4882a593Smuzhiyun
595*4882a593Smuzhiyun /* Save the current clientClip and update the CompositeClip whenever
596*4882a593Smuzhiyun we have a fresh GC */
597*4882a593Smuzhiyun
598*4882a593Smuzhiyun static void
xf86XVCopyClip(XvPortRecPrivatePtr portPriv,GCPtr pGC)599*4882a593Smuzhiyun xf86XVCopyClip(XvPortRecPrivatePtr portPriv, GCPtr pGC)
600*4882a593Smuzhiyun {
601*4882a593Smuzhiyun /* copy the new clip if it exists */
602*4882a593Smuzhiyun if (pGC->clientClip) {
603*4882a593Smuzhiyun if (!portPriv->clientClip)
604*4882a593Smuzhiyun portPriv->clientClip = RegionCreate(NullBox, 1);
605*4882a593Smuzhiyun /* Note: this is in window coordinates */
606*4882a593Smuzhiyun RegionCopy(portPriv->clientClip, pGC->clientClip);
607*4882a593Smuzhiyun RegionTranslate(portPriv->clientClip, pGC->clipOrg.x, pGC->clipOrg.y);
608*4882a593Smuzhiyun }
609*4882a593Smuzhiyun else if (portPriv->clientClip) { /* free the old clientClip */
610*4882a593Smuzhiyun RegionDestroy(portPriv->clientClip);
611*4882a593Smuzhiyun portPriv->clientClip = NULL;
612*4882a593Smuzhiyun }
613*4882a593Smuzhiyun
614*4882a593Smuzhiyun /* get rid of the old clip list */
615*4882a593Smuzhiyun if (portPriv->pCompositeClip && portPriv->FreeCompositeClip) {
616*4882a593Smuzhiyun RegionDestroy(portPriv->pCompositeClip);
617*4882a593Smuzhiyun }
618*4882a593Smuzhiyun
619*4882a593Smuzhiyun portPriv->pCompositeClip = pGC->pCompositeClip;
620*4882a593Smuzhiyun portPriv->FreeCompositeClip = FALSE;
621*4882a593Smuzhiyun portPriv->subWindowMode = pGC->subWindowMode;
622*4882a593Smuzhiyun }
623*4882a593Smuzhiyun
624*4882a593Smuzhiyun static void
xf86XVCopyCompositeClip(XvPortRecPrivatePtr portPriv,GCPtr pGC,DrawablePtr pDraw)625*4882a593Smuzhiyun xf86XVCopyCompositeClip(XvPortRecPrivatePtr portPriv,
626*4882a593Smuzhiyun GCPtr pGC, DrawablePtr pDraw)
627*4882a593Smuzhiyun {
628*4882a593Smuzhiyun if (!portPriv->clientClip)
629*4882a593Smuzhiyun portPriv->clientClip = RegionCreate(NullBox, 1);
630*4882a593Smuzhiyun /* Keep the original GC composite clip around for ReputImage */
631*4882a593Smuzhiyun RegionCopy(portPriv->clientClip, pGC->pCompositeClip);
632*4882a593Smuzhiyun RegionTranslate(portPriv->clientClip, -pDraw->x, -pDraw->y);
633*4882a593Smuzhiyun
634*4882a593Smuzhiyun /* get rid of the old clip list */
635*4882a593Smuzhiyun if (portPriv->pCompositeClip && portPriv->FreeCompositeClip)
636*4882a593Smuzhiyun RegionDestroy(portPriv->pCompositeClip);
637*4882a593Smuzhiyun
638*4882a593Smuzhiyun portPriv->pCompositeClip = pGC->pCompositeClip;
639*4882a593Smuzhiyun portPriv->FreeCompositeClip = FALSE;
640*4882a593Smuzhiyun portPriv->subWindowMode = pGC->subWindowMode;
641*4882a593Smuzhiyun }
642*4882a593Smuzhiyun
643*4882a593Smuzhiyun static int
xf86XVRegetVideo(XvPortRecPrivatePtr portPriv)644*4882a593Smuzhiyun xf86XVRegetVideo(XvPortRecPrivatePtr portPriv)
645*4882a593Smuzhiyun {
646*4882a593Smuzhiyun RegionRec WinRegion;
647*4882a593Smuzhiyun RegionRec ClipRegion;
648*4882a593Smuzhiyun BoxRec WinBox;
649*4882a593Smuzhiyun int ret = Success;
650*4882a593Smuzhiyun Bool clippedAway = FALSE;
651*4882a593Smuzhiyun
652*4882a593Smuzhiyun xf86XVUpdateCompositeClip(portPriv);
653*4882a593Smuzhiyun
654*4882a593Smuzhiyun /* translate the video region to the screen */
655*4882a593Smuzhiyun WinBox.x1 = portPriv->pDraw->x + portPriv->drw_x;
656*4882a593Smuzhiyun WinBox.y1 = portPriv->pDraw->y + portPriv->drw_y;
657*4882a593Smuzhiyun WinBox.x2 = WinBox.x1 + portPriv->drw_w;
658*4882a593Smuzhiyun WinBox.y2 = WinBox.y1 + portPriv->drw_h;
659*4882a593Smuzhiyun
660*4882a593Smuzhiyun /* clip to the window composite clip */
661*4882a593Smuzhiyun RegionInit(&WinRegion, &WinBox, 1);
662*4882a593Smuzhiyun RegionNull(&ClipRegion);
663*4882a593Smuzhiyun RegionIntersect(&ClipRegion, &WinRegion, portPriv->pCompositeClip);
664*4882a593Smuzhiyun
665*4882a593Smuzhiyun /* that's all if it's totally obscured */
666*4882a593Smuzhiyun if (!RegionNotEmpty(&ClipRegion)) {
667*4882a593Smuzhiyun clippedAway = TRUE;
668*4882a593Smuzhiyun goto CLIP_VIDEO_BAILOUT;
669*4882a593Smuzhiyun }
670*4882a593Smuzhiyun
671*4882a593Smuzhiyun ret = (*portPriv->AdaptorRec->GetVideo) (portPriv->pScrn,
672*4882a593Smuzhiyun portPriv->vid_x, portPriv->vid_y,
673*4882a593Smuzhiyun WinBox.x1, WinBox.y1,
674*4882a593Smuzhiyun portPriv->vid_w, portPriv->vid_h,
675*4882a593Smuzhiyun portPriv->drw_w, portPriv->drw_h,
676*4882a593Smuzhiyun &ClipRegion, portPriv->DevPriv.ptr,
677*4882a593Smuzhiyun portPriv->pDraw);
678*4882a593Smuzhiyun
679*4882a593Smuzhiyun if (ret == Success)
680*4882a593Smuzhiyun portPriv->isOn = XV_ON;
681*4882a593Smuzhiyun
682*4882a593Smuzhiyun CLIP_VIDEO_BAILOUT:
683*4882a593Smuzhiyun
684*4882a593Smuzhiyun if ((clippedAway || (ret != Success)) && portPriv->isOn == XV_ON) {
685*4882a593Smuzhiyun (*portPriv->AdaptorRec->StopVideo) (portPriv->pScrn,
686*4882a593Smuzhiyun portPriv->DevPriv.ptr, FALSE);
687*4882a593Smuzhiyun portPriv->isOn = XV_PENDING;
688*4882a593Smuzhiyun }
689*4882a593Smuzhiyun
690*4882a593Smuzhiyun /* This clip was copied and only good for one shot */
691*4882a593Smuzhiyun if (!portPriv->FreeCompositeClip)
692*4882a593Smuzhiyun portPriv->pCompositeClip = NULL;
693*4882a593Smuzhiyun
694*4882a593Smuzhiyun RegionUninit(&WinRegion);
695*4882a593Smuzhiyun RegionUninit(&ClipRegion);
696*4882a593Smuzhiyun
697*4882a593Smuzhiyun return ret;
698*4882a593Smuzhiyun }
699*4882a593Smuzhiyun
700*4882a593Smuzhiyun static int
xf86XVReputVideo(XvPortRecPrivatePtr portPriv)701*4882a593Smuzhiyun xf86XVReputVideo(XvPortRecPrivatePtr portPriv)
702*4882a593Smuzhiyun {
703*4882a593Smuzhiyun RegionRec WinRegion;
704*4882a593Smuzhiyun RegionRec ClipRegion;
705*4882a593Smuzhiyun BoxRec WinBox;
706*4882a593Smuzhiyun int ret = Success;
707*4882a593Smuzhiyun Bool clippedAway = FALSE;
708*4882a593Smuzhiyun
709*4882a593Smuzhiyun xf86XVUpdateCompositeClip(portPriv);
710*4882a593Smuzhiyun
711*4882a593Smuzhiyun /* translate the video region to the screen */
712*4882a593Smuzhiyun WinBox.x1 = portPriv->pDraw->x + portPriv->drw_x;
713*4882a593Smuzhiyun WinBox.y1 = portPriv->pDraw->y + portPriv->drw_y;
714*4882a593Smuzhiyun WinBox.x2 = WinBox.x1 + portPriv->drw_w;
715*4882a593Smuzhiyun WinBox.y2 = WinBox.y1 + portPriv->drw_h;
716*4882a593Smuzhiyun
717*4882a593Smuzhiyun /* clip to the window composite clip */
718*4882a593Smuzhiyun RegionInit(&WinRegion, &WinBox, 1);
719*4882a593Smuzhiyun RegionNull(&ClipRegion);
720*4882a593Smuzhiyun RegionIntersect(&ClipRegion, &WinRegion, portPriv->pCompositeClip);
721*4882a593Smuzhiyun
722*4882a593Smuzhiyun /* clip and translate to the viewport */
723*4882a593Smuzhiyun if (portPriv->AdaptorRec->flags & VIDEO_CLIP_TO_VIEWPORT) {
724*4882a593Smuzhiyun RegionRec VPReg;
725*4882a593Smuzhiyun BoxRec VPBox;
726*4882a593Smuzhiyun
727*4882a593Smuzhiyun VPBox.x1 = portPriv->pScrn->frameX0;
728*4882a593Smuzhiyun VPBox.y1 = portPriv->pScrn->frameY0;
729*4882a593Smuzhiyun VPBox.x2 = portPriv->pScrn->frameX1 + 1;
730*4882a593Smuzhiyun VPBox.y2 = portPriv->pScrn->frameY1 + 1;
731*4882a593Smuzhiyun
732*4882a593Smuzhiyun RegionInit(&VPReg, &VPBox, 1);
733*4882a593Smuzhiyun RegionIntersect(&ClipRegion, &ClipRegion, &VPReg);
734*4882a593Smuzhiyun RegionUninit(&VPReg);
735*4882a593Smuzhiyun }
736*4882a593Smuzhiyun
737*4882a593Smuzhiyun /* that's all if it's totally obscured */
738*4882a593Smuzhiyun if (!RegionNotEmpty(&ClipRegion)) {
739*4882a593Smuzhiyun clippedAway = TRUE;
740*4882a593Smuzhiyun goto CLIP_VIDEO_BAILOUT;
741*4882a593Smuzhiyun }
742*4882a593Smuzhiyun
743*4882a593Smuzhiyun ret = (*portPriv->AdaptorRec->PutVideo) (portPriv->pScrn,
744*4882a593Smuzhiyun portPriv->vid_x, portPriv->vid_y,
745*4882a593Smuzhiyun WinBox.x1, WinBox.y1,
746*4882a593Smuzhiyun portPriv->vid_w, portPriv->vid_h,
747*4882a593Smuzhiyun portPriv->drw_w, portPriv->drw_h,
748*4882a593Smuzhiyun &ClipRegion, portPriv->DevPriv.ptr,
749*4882a593Smuzhiyun portPriv->pDraw);
750*4882a593Smuzhiyun
751*4882a593Smuzhiyun if (ret == Success)
752*4882a593Smuzhiyun portPriv->isOn = XV_ON;
753*4882a593Smuzhiyun
754*4882a593Smuzhiyun CLIP_VIDEO_BAILOUT:
755*4882a593Smuzhiyun
756*4882a593Smuzhiyun if ((clippedAway || (ret != Success)) && (portPriv->isOn == XV_ON)) {
757*4882a593Smuzhiyun (*portPriv->AdaptorRec->StopVideo) (portPriv->pScrn,
758*4882a593Smuzhiyun portPriv->DevPriv.ptr, FALSE);
759*4882a593Smuzhiyun portPriv->isOn = XV_PENDING;
760*4882a593Smuzhiyun }
761*4882a593Smuzhiyun
762*4882a593Smuzhiyun /* This clip was copied and only good for one shot */
763*4882a593Smuzhiyun if (!portPriv->FreeCompositeClip)
764*4882a593Smuzhiyun portPriv->pCompositeClip = NULL;
765*4882a593Smuzhiyun
766*4882a593Smuzhiyun RegionUninit(&WinRegion);
767*4882a593Smuzhiyun RegionUninit(&ClipRegion);
768*4882a593Smuzhiyun
769*4882a593Smuzhiyun return ret;
770*4882a593Smuzhiyun }
771*4882a593Smuzhiyun
772*4882a593Smuzhiyun /* Reput image/still */
773*4882a593Smuzhiyun static int
xf86XVReputImage(XvPortRecPrivatePtr portPriv)774*4882a593Smuzhiyun xf86XVReputImage(XvPortRecPrivatePtr portPriv)
775*4882a593Smuzhiyun {
776*4882a593Smuzhiyun RegionRec WinRegion;
777*4882a593Smuzhiyun RegionRec ClipRegion;
778*4882a593Smuzhiyun BoxRec WinBox;
779*4882a593Smuzhiyun int ret = Success;
780*4882a593Smuzhiyun Bool clippedAway = FALSE;
781*4882a593Smuzhiyun
782*4882a593Smuzhiyun xf86XVUpdateCompositeClip(portPriv);
783*4882a593Smuzhiyun
784*4882a593Smuzhiyun /* the clip can get smaller over time */
785*4882a593Smuzhiyun RegionCopy(portPriv->clientClip, portPriv->pCompositeClip);
786*4882a593Smuzhiyun RegionTranslate(portPriv->clientClip,
787*4882a593Smuzhiyun -portPriv->pDraw->x, -portPriv->pDraw->y);
788*4882a593Smuzhiyun
789*4882a593Smuzhiyun /* translate the video region to the screen */
790*4882a593Smuzhiyun WinBox.x1 = portPriv->pDraw->x + portPriv->drw_x;
791*4882a593Smuzhiyun WinBox.y1 = portPriv->pDraw->y + portPriv->drw_y;
792*4882a593Smuzhiyun WinBox.x2 = WinBox.x1 + portPriv->drw_w;
793*4882a593Smuzhiyun WinBox.y2 = WinBox.y1 + portPriv->drw_h;
794*4882a593Smuzhiyun
795*4882a593Smuzhiyun /* clip to the window composite clip */
796*4882a593Smuzhiyun RegionInit(&WinRegion, &WinBox, 1);
797*4882a593Smuzhiyun RegionNull(&ClipRegion);
798*4882a593Smuzhiyun RegionIntersect(&ClipRegion, &WinRegion, portPriv->pCompositeClip);
799*4882a593Smuzhiyun
800*4882a593Smuzhiyun /* clip and translate to the viewport */
801*4882a593Smuzhiyun if (portPriv->AdaptorRec->flags & VIDEO_CLIP_TO_VIEWPORT) {
802*4882a593Smuzhiyun RegionRec VPReg;
803*4882a593Smuzhiyun BoxRec VPBox;
804*4882a593Smuzhiyun
805*4882a593Smuzhiyun VPBox.x1 = portPriv->pScrn->frameX0;
806*4882a593Smuzhiyun VPBox.y1 = portPriv->pScrn->frameY0;
807*4882a593Smuzhiyun VPBox.x2 = portPriv->pScrn->frameX1 + 1;
808*4882a593Smuzhiyun VPBox.y2 = portPriv->pScrn->frameY1 + 1;
809*4882a593Smuzhiyun
810*4882a593Smuzhiyun RegionInit(&VPReg, &VPBox, 1);
811*4882a593Smuzhiyun RegionIntersect(&ClipRegion, &ClipRegion, &VPReg);
812*4882a593Smuzhiyun RegionUninit(&VPReg);
813*4882a593Smuzhiyun }
814*4882a593Smuzhiyun
815*4882a593Smuzhiyun /* that's all if it's totally obscured */
816*4882a593Smuzhiyun if (!RegionNotEmpty(&ClipRegion)) {
817*4882a593Smuzhiyun clippedAway = TRUE;
818*4882a593Smuzhiyun goto CLIP_VIDEO_BAILOUT;
819*4882a593Smuzhiyun }
820*4882a593Smuzhiyun
821*4882a593Smuzhiyun ret = (*portPriv->AdaptorRec->ReputImage) (portPriv->pScrn,
822*4882a593Smuzhiyun portPriv->vid_x, portPriv->vid_y,
823*4882a593Smuzhiyun WinBox.x1, WinBox.y1,
824*4882a593Smuzhiyun portPriv->vid_w, portPriv->vid_h,
825*4882a593Smuzhiyun portPriv->drw_w, portPriv->drw_h,
826*4882a593Smuzhiyun &ClipRegion,
827*4882a593Smuzhiyun portPriv->DevPriv.ptr,
828*4882a593Smuzhiyun portPriv->pDraw);
829*4882a593Smuzhiyun
830*4882a593Smuzhiyun portPriv->isOn = (ret == Success) ? XV_ON : XV_OFF;
831*4882a593Smuzhiyun
832*4882a593Smuzhiyun CLIP_VIDEO_BAILOUT:
833*4882a593Smuzhiyun
834*4882a593Smuzhiyun if ((clippedAway || (ret != Success)) && (portPriv->isOn == XV_ON)) {
835*4882a593Smuzhiyun (*portPriv->AdaptorRec->StopVideo) (portPriv->pScrn,
836*4882a593Smuzhiyun portPriv->DevPriv.ptr, FALSE);
837*4882a593Smuzhiyun portPriv->isOn = XV_PENDING;
838*4882a593Smuzhiyun }
839*4882a593Smuzhiyun
840*4882a593Smuzhiyun /* This clip was copied and only good for one shot */
841*4882a593Smuzhiyun if (!portPriv->FreeCompositeClip)
842*4882a593Smuzhiyun portPriv->pCompositeClip = NULL;
843*4882a593Smuzhiyun
844*4882a593Smuzhiyun RegionUninit(&WinRegion);
845*4882a593Smuzhiyun RegionUninit(&ClipRegion);
846*4882a593Smuzhiyun
847*4882a593Smuzhiyun return ret;
848*4882a593Smuzhiyun }
849*4882a593Smuzhiyun
850*4882a593Smuzhiyun static int
xf86XVReputAllVideo(WindowPtr pWin,void * data)851*4882a593Smuzhiyun xf86XVReputAllVideo(WindowPtr pWin, void *data)
852*4882a593Smuzhiyun {
853*4882a593Smuzhiyun XF86XVWindowPtr WinPriv = GET_XF86XV_WINDOW(pWin);
854*4882a593Smuzhiyun
855*4882a593Smuzhiyun while (WinPriv) {
856*4882a593Smuzhiyun if (WinPriv->PortRec->type == XvInputMask)
857*4882a593Smuzhiyun xf86XVReputVideo(WinPriv->PortRec);
858*4882a593Smuzhiyun else
859*4882a593Smuzhiyun xf86XVRegetVideo(WinPriv->PortRec);
860*4882a593Smuzhiyun WinPriv = WinPriv->next;
861*4882a593Smuzhiyun }
862*4882a593Smuzhiyun
863*4882a593Smuzhiyun return WT_WALKCHILDREN;
864*4882a593Smuzhiyun }
865*4882a593Smuzhiyun
866*4882a593Smuzhiyun static int
xf86XVEnlistPortInWindow(WindowPtr pWin,XvPortRecPrivatePtr portPriv)867*4882a593Smuzhiyun xf86XVEnlistPortInWindow(WindowPtr pWin, XvPortRecPrivatePtr portPriv)
868*4882a593Smuzhiyun {
869*4882a593Smuzhiyun XF86XVWindowPtr winPriv, PrivRoot;
870*4882a593Smuzhiyun
871*4882a593Smuzhiyun winPriv = PrivRoot = GET_XF86XV_WINDOW(pWin);
872*4882a593Smuzhiyun
873*4882a593Smuzhiyun /* Enlist our port in the window private */
874*4882a593Smuzhiyun while (winPriv) {
875*4882a593Smuzhiyun if (winPriv->PortRec == portPriv) /* we're already listed */
876*4882a593Smuzhiyun break;
877*4882a593Smuzhiyun winPriv = winPriv->next;
878*4882a593Smuzhiyun }
879*4882a593Smuzhiyun
880*4882a593Smuzhiyun if (!winPriv) {
881*4882a593Smuzhiyun winPriv = calloc(1, sizeof(XF86XVWindowRec));
882*4882a593Smuzhiyun if (!winPriv)
883*4882a593Smuzhiyun return BadAlloc;
884*4882a593Smuzhiyun winPriv->PortRec = portPriv;
885*4882a593Smuzhiyun winPriv->next = PrivRoot;
886*4882a593Smuzhiyun dixSetPrivate(&pWin->devPrivates, XF86XVWindowKey, winPriv);
887*4882a593Smuzhiyun }
888*4882a593Smuzhiyun
889*4882a593Smuzhiyun portPriv->pDraw = (DrawablePtr) pWin;
890*4882a593Smuzhiyun
891*4882a593Smuzhiyun return Success;
892*4882a593Smuzhiyun }
893*4882a593Smuzhiyun
894*4882a593Smuzhiyun static void
xf86XVRemovePortFromWindow(WindowPtr pWin,XvPortRecPrivatePtr portPriv)895*4882a593Smuzhiyun xf86XVRemovePortFromWindow(WindowPtr pWin, XvPortRecPrivatePtr portPriv)
896*4882a593Smuzhiyun {
897*4882a593Smuzhiyun XF86XVWindowPtr winPriv, prevPriv = NULL;
898*4882a593Smuzhiyun
899*4882a593Smuzhiyun winPriv = GET_XF86XV_WINDOW(pWin);
900*4882a593Smuzhiyun
901*4882a593Smuzhiyun while (winPriv) {
902*4882a593Smuzhiyun if (winPriv->PortRec == portPriv) {
903*4882a593Smuzhiyun if (prevPriv)
904*4882a593Smuzhiyun prevPriv->next = winPriv->next;
905*4882a593Smuzhiyun else
906*4882a593Smuzhiyun dixSetPrivate(&pWin->devPrivates, XF86XVWindowKey,
907*4882a593Smuzhiyun winPriv->next);
908*4882a593Smuzhiyun free(winPriv);
909*4882a593Smuzhiyun break;
910*4882a593Smuzhiyun }
911*4882a593Smuzhiyun prevPriv = winPriv;
912*4882a593Smuzhiyun winPriv = winPriv->next;
913*4882a593Smuzhiyun }
914*4882a593Smuzhiyun portPriv->pDraw = NULL;
915*4882a593Smuzhiyun if (portPriv->ckeyFilled) {
916*4882a593Smuzhiyun RegionDestroy(portPriv->ckeyFilled);
917*4882a593Smuzhiyun portPriv->ckeyFilled = NULL;
918*4882a593Smuzhiyun }
919*4882a593Smuzhiyun portPriv->clipChanged = FALSE;
920*4882a593Smuzhiyun }
921*4882a593Smuzhiyun
922*4882a593Smuzhiyun static void
xf86XVReputOrStopPort(XvPortRecPrivatePtr pPriv,WindowPtr pWin,Bool visible)923*4882a593Smuzhiyun xf86XVReputOrStopPort(XvPortRecPrivatePtr pPriv, WindowPtr pWin, Bool visible)
924*4882a593Smuzhiyun {
925*4882a593Smuzhiyun if (!visible) {
926*4882a593Smuzhiyun if (pPriv->isOn == XV_ON) {
927*4882a593Smuzhiyun (*pPriv->AdaptorRec->StopVideo) (pPriv->pScrn, pPriv->DevPriv.ptr,
928*4882a593Smuzhiyun FALSE);
929*4882a593Smuzhiyun pPriv->isOn = XV_PENDING;
930*4882a593Smuzhiyun }
931*4882a593Smuzhiyun
932*4882a593Smuzhiyun if (!pPriv->type) /* overlaid still/image */
933*4882a593Smuzhiyun xf86XVRemovePortFromWindow(pWin, pPriv);
934*4882a593Smuzhiyun
935*4882a593Smuzhiyun return;
936*4882a593Smuzhiyun }
937*4882a593Smuzhiyun
938*4882a593Smuzhiyun switch (pPriv->type) {
939*4882a593Smuzhiyun case XvInputMask:
940*4882a593Smuzhiyun xf86XVReputVideo(pPriv);
941*4882a593Smuzhiyun break;
942*4882a593Smuzhiyun case XvOutputMask:
943*4882a593Smuzhiyun xf86XVRegetVideo(pPriv);
944*4882a593Smuzhiyun break;
945*4882a593Smuzhiyun default: /* overlaid still/image */
946*4882a593Smuzhiyun if (pPriv->AdaptorRec->ReputImage)
947*4882a593Smuzhiyun xf86XVReputImage(pPriv);
948*4882a593Smuzhiyun break;
949*4882a593Smuzhiyun }
950*4882a593Smuzhiyun }
951*4882a593Smuzhiyun
952*4882a593Smuzhiyun static void
xf86XVReputOrStopAllPorts(ScrnInfoPtr pScrn,Bool onlyChanged)953*4882a593Smuzhiyun xf86XVReputOrStopAllPorts(ScrnInfoPtr pScrn, Bool onlyChanged)
954*4882a593Smuzhiyun {
955*4882a593Smuzhiyun ScreenPtr pScreen = xf86ScrnToScreen(pScrn);
956*4882a593Smuzhiyun XvScreenPtr pxvs = GET_XV_SCREEN(pScreen);
957*4882a593Smuzhiyun XvAdaptorPtr pa;
958*4882a593Smuzhiyun int c, i;
959*4882a593Smuzhiyun
960*4882a593Smuzhiyun for (c = pxvs->nAdaptors, pa = pxvs->pAdaptors; c > 0; c--, pa++) {
961*4882a593Smuzhiyun XvPortPtr pPort = pa->pPorts;
962*4882a593Smuzhiyun
963*4882a593Smuzhiyun for (i = pa->nPorts; i > 0; i--, pPort++) {
964*4882a593Smuzhiyun XvPortRecPrivatePtr pPriv =
965*4882a593Smuzhiyun (XvPortRecPrivatePtr) pPort->devPriv.ptr;
966*4882a593Smuzhiyun WindowPtr pWin = (WindowPtr) pPriv->pDraw;
967*4882a593Smuzhiyun Bool visible;
968*4882a593Smuzhiyun
969*4882a593Smuzhiyun if (pPriv->isOn == XV_OFF || !pWin)
970*4882a593Smuzhiyun continue;
971*4882a593Smuzhiyun
972*4882a593Smuzhiyun if (onlyChanged && !pPriv->clipChanged)
973*4882a593Smuzhiyun continue;
974*4882a593Smuzhiyun
975*4882a593Smuzhiyun visible = pWin->visibility == VisibilityUnobscured ||
976*4882a593Smuzhiyun pWin->visibility == VisibilityPartiallyObscured;
977*4882a593Smuzhiyun
978*4882a593Smuzhiyun /*
979*4882a593Smuzhiyun * Stop and remove still/images if
980*4882a593Smuzhiyun * ReputImage isn't supported.
981*4882a593Smuzhiyun */
982*4882a593Smuzhiyun if (!pPriv->type && !pPriv->AdaptorRec->ReputImage)
983*4882a593Smuzhiyun visible = FALSE;
984*4882a593Smuzhiyun
985*4882a593Smuzhiyun xf86XVReputOrStopPort(pPriv, pWin, visible);
986*4882a593Smuzhiyun
987*4882a593Smuzhiyun pPriv->clipChanged = FALSE;
988*4882a593Smuzhiyun }
989*4882a593Smuzhiyun }
990*4882a593Smuzhiyun }
991*4882a593Smuzhiyun
992*4882a593Smuzhiyun /**** ScreenRec fields ****/
993*4882a593Smuzhiyun
994*4882a593Smuzhiyun static Bool
xf86XVDestroyWindow(WindowPtr pWin)995*4882a593Smuzhiyun xf86XVDestroyWindow(WindowPtr pWin)
996*4882a593Smuzhiyun {
997*4882a593Smuzhiyun ScreenPtr pScreen = pWin->drawable.pScreen;
998*4882a593Smuzhiyun XF86XVScreenPtr ScreenPriv = GET_XF86XV_SCREEN(pScreen);
999*4882a593Smuzhiyun XF86XVWindowPtr tmp, WinPriv = GET_XF86XV_WINDOW(pWin);
1000*4882a593Smuzhiyun int ret;
1001*4882a593Smuzhiyun
1002*4882a593Smuzhiyun while (WinPriv) {
1003*4882a593Smuzhiyun XvPortRecPrivatePtr pPriv = WinPriv->PortRec;
1004*4882a593Smuzhiyun
1005*4882a593Smuzhiyun if (pPriv->isOn > XV_OFF) {
1006*4882a593Smuzhiyun (*pPriv->AdaptorRec->StopVideo) (pPriv->pScrn, pPriv->DevPriv.ptr,
1007*4882a593Smuzhiyun TRUE);
1008*4882a593Smuzhiyun pPriv->isOn = XV_OFF;
1009*4882a593Smuzhiyun }
1010*4882a593Smuzhiyun
1011*4882a593Smuzhiyun pPriv->pDraw = NULL;
1012*4882a593Smuzhiyun tmp = WinPriv;
1013*4882a593Smuzhiyun WinPriv = WinPriv->next;
1014*4882a593Smuzhiyun free(tmp);
1015*4882a593Smuzhiyun }
1016*4882a593Smuzhiyun
1017*4882a593Smuzhiyun dixSetPrivate(&pWin->devPrivates, XF86XVWindowKey, NULL);
1018*4882a593Smuzhiyun
1019*4882a593Smuzhiyun pScreen->DestroyWindow = ScreenPriv->DestroyWindow;
1020*4882a593Smuzhiyun ret = (*pScreen->DestroyWindow) (pWin);
1021*4882a593Smuzhiyun pScreen->DestroyWindow = xf86XVDestroyWindow;
1022*4882a593Smuzhiyun
1023*4882a593Smuzhiyun return ret;
1024*4882a593Smuzhiyun }
1025*4882a593Smuzhiyun
1026*4882a593Smuzhiyun static void
xf86XVPostValidateTree(WindowPtr pWin,WindowPtr pLayerWin,VTKind kind)1027*4882a593Smuzhiyun xf86XVPostValidateTree(WindowPtr pWin, WindowPtr pLayerWin, VTKind kind)
1028*4882a593Smuzhiyun {
1029*4882a593Smuzhiyun ScreenPtr pScreen;
1030*4882a593Smuzhiyun XF86XVScreenPtr ScreenPriv;
1031*4882a593Smuzhiyun ScrnInfoPtr pScrn;
1032*4882a593Smuzhiyun
1033*4882a593Smuzhiyun if (pWin)
1034*4882a593Smuzhiyun pScreen = pWin->drawable.pScreen;
1035*4882a593Smuzhiyun else
1036*4882a593Smuzhiyun pScreen = pLayerWin->drawable.pScreen;
1037*4882a593Smuzhiyun
1038*4882a593Smuzhiyun ScreenPriv = GET_XF86XV_SCREEN(pScreen);
1039*4882a593Smuzhiyun pScrn = xf86ScreenToScrn(pScreen);
1040*4882a593Smuzhiyun
1041*4882a593Smuzhiyun xf86XVReputOrStopAllPorts(pScrn, TRUE);
1042*4882a593Smuzhiyun
1043*4882a593Smuzhiyun pScreen->PostValidateTree = ScreenPriv->PostValidateTree;
1044*4882a593Smuzhiyun if (pScreen->PostValidateTree) {
1045*4882a593Smuzhiyun (*pScreen->PostValidateTree) (pWin, pLayerWin, kind);
1046*4882a593Smuzhiyun }
1047*4882a593Smuzhiyun ScreenPriv->PostValidateTree = PostValidateTreeUndefined;
1048*4882a593Smuzhiyun }
1049*4882a593Smuzhiyun
1050*4882a593Smuzhiyun static void
xf86XVWindowExposures(WindowPtr pWin,RegionPtr reg1)1051*4882a593Smuzhiyun xf86XVWindowExposures(WindowPtr pWin, RegionPtr reg1)
1052*4882a593Smuzhiyun {
1053*4882a593Smuzhiyun ScreenPtr pScreen = pWin->drawable.pScreen;
1054*4882a593Smuzhiyun XF86XVScreenPtr ScreenPriv = GET_XF86XV_SCREEN(pScreen);
1055*4882a593Smuzhiyun XF86XVWindowPtr WinPriv = GET_XF86XV_WINDOW(pWin);
1056*4882a593Smuzhiyun XvPortRecPrivatePtr pPriv;
1057*4882a593Smuzhiyun Bool AreasExposed;
1058*4882a593Smuzhiyun
1059*4882a593Smuzhiyun AreasExposed = (WinPriv && reg1 && RegionNotEmpty(reg1));
1060*4882a593Smuzhiyun
1061*4882a593Smuzhiyun pScreen->WindowExposures = ScreenPriv->WindowExposures;
1062*4882a593Smuzhiyun (*pScreen->WindowExposures) (pWin, reg1);
1063*4882a593Smuzhiyun pScreen->WindowExposures = xf86XVWindowExposures;
1064*4882a593Smuzhiyun
1065*4882a593Smuzhiyun /* filter out XClearWindow/Area */
1066*4882a593Smuzhiyun if (!pWin->valdata)
1067*4882a593Smuzhiyun return;
1068*4882a593Smuzhiyun
1069*4882a593Smuzhiyun while (WinPriv) {
1070*4882a593Smuzhiyun Bool visible = TRUE;
1071*4882a593Smuzhiyun
1072*4882a593Smuzhiyun pPriv = WinPriv->PortRec;
1073*4882a593Smuzhiyun
1074*4882a593Smuzhiyun /*
1075*4882a593Smuzhiyun * Stop and remove still/images if areas were exposed and
1076*4882a593Smuzhiyun * ReputImage isn't supported.
1077*4882a593Smuzhiyun */
1078*4882a593Smuzhiyun if (!pPriv->type && !pPriv->AdaptorRec->ReputImage)
1079*4882a593Smuzhiyun visible = !AreasExposed;
1080*4882a593Smuzhiyun
1081*4882a593Smuzhiyun /*
1082*4882a593Smuzhiyun * Subtract exposed areas from overlaid image to match textured video
1083*4882a593Smuzhiyun * behavior.
1084*4882a593Smuzhiyun */
1085*4882a593Smuzhiyun if (!pPriv->type && pPriv->clientClip)
1086*4882a593Smuzhiyun RegionSubtract(pPriv->clientClip, pPriv->clientClip, reg1);
1087*4882a593Smuzhiyun
1088*4882a593Smuzhiyun if (visible && pPriv->ckeyFilled) {
1089*4882a593Smuzhiyun RegionRec tmp;
1090*4882a593Smuzhiyun
1091*4882a593Smuzhiyun RegionNull(&tmp);
1092*4882a593Smuzhiyun RegionCopy(&tmp, reg1);
1093*4882a593Smuzhiyun RegionTranslate(&tmp, pWin->drawable.x, pWin->drawable.y);
1094*4882a593Smuzhiyun RegionSubtract(pPriv->ckeyFilled, pPriv->ckeyFilled, &tmp);
1095*4882a593Smuzhiyun }
1096*4882a593Smuzhiyun
1097*4882a593Smuzhiyun WinPriv = WinPriv->next;
1098*4882a593Smuzhiyun xf86XVReputOrStopPort(pPriv, pWin, visible);
1099*4882a593Smuzhiyun
1100*4882a593Smuzhiyun pPriv->clipChanged = FALSE;
1101*4882a593Smuzhiyun }
1102*4882a593Smuzhiyun }
1103*4882a593Smuzhiyun
1104*4882a593Smuzhiyun static void
xf86XVClipNotify(WindowPtr pWin,int dx,int dy)1105*4882a593Smuzhiyun xf86XVClipNotify(WindowPtr pWin, int dx, int dy)
1106*4882a593Smuzhiyun {
1107*4882a593Smuzhiyun ScreenPtr pScreen = pWin->drawable.pScreen;
1108*4882a593Smuzhiyun XF86XVScreenPtr ScreenPriv = GET_XF86XV_SCREEN(pScreen);
1109*4882a593Smuzhiyun XF86XVWindowPtr WinPriv = GET_XF86XV_WINDOW(pWin);
1110*4882a593Smuzhiyun XvPortRecPrivatePtr pPriv;
1111*4882a593Smuzhiyun
1112*4882a593Smuzhiyun while (WinPriv) {
1113*4882a593Smuzhiyun pPriv = WinPriv->PortRec;
1114*4882a593Smuzhiyun
1115*4882a593Smuzhiyun if (pPriv->pCompositeClip && pPriv->FreeCompositeClip)
1116*4882a593Smuzhiyun RegionDestroy(pPriv->pCompositeClip);
1117*4882a593Smuzhiyun
1118*4882a593Smuzhiyun pPriv->pCompositeClip = NULL;
1119*4882a593Smuzhiyun
1120*4882a593Smuzhiyun pPriv->clipChanged = TRUE;
1121*4882a593Smuzhiyun
1122*4882a593Smuzhiyun if (ScreenPriv->PostValidateTree == PostValidateTreeUndefined) {
1123*4882a593Smuzhiyun ScreenPriv->PostValidateTree = pScreen->PostValidateTree;
1124*4882a593Smuzhiyun pScreen->PostValidateTree = xf86XVPostValidateTree;
1125*4882a593Smuzhiyun }
1126*4882a593Smuzhiyun
1127*4882a593Smuzhiyun WinPriv = WinPriv->next;
1128*4882a593Smuzhiyun }
1129*4882a593Smuzhiyun
1130*4882a593Smuzhiyun if (ScreenPriv->ClipNotify) {
1131*4882a593Smuzhiyun pScreen->ClipNotify = ScreenPriv->ClipNotify;
1132*4882a593Smuzhiyun (*pScreen->ClipNotify) (pWin, dx, dy);
1133*4882a593Smuzhiyun pScreen->ClipNotify = xf86XVClipNotify;
1134*4882a593Smuzhiyun }
1135*4882a593Smuzhiyun }
1136*4882a593Smuzhiyun
1137*4882a593Smuzhiyun /**** Required XvScreenRec fields ****/
1138*4882a593Smuzhiyun
1139*4882a593Smuzhiyun static Bool
xf86XVCloseScreen(ScreenPtr pScreen)1140*4882a593Smuzhiyun xf86XVCloseScreen(ScreenPtr pScreen)
1141*4882a593Smuzhiyun {
1142*4882a593Smuzhiyun ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
1143*4882a593Smuzhiyun XvScreenPtr pxvs = GET_XV_SCREEN(pScreen);
1144*4882a593Smuzhiyun XF86XVScreenPtr ScreenPriv = GET_XF86XV_SCREEN(pScreen);
1145*4882a593Smuzhiyun XvAdaptorPtr pa;
1146*4882a593Smuzhiyun int c;
1147*4882a593Smuzhiyun
1148*4882a593Smuzhiyun if (!ScreenPriv)
1149*4882a593Smuzhiyun return TRUE;
1150*4882a593Smuzhiyun
1151*4882a593Smuzhiyun pScreen->DestroyWindow = ScreenPriv->DestroyWindow;
1152*4882a593Smuzhiyun pScreen->WindowExposures = ScreenPriv->WindowExposures;
1153*4882a593Smuzhiyun pScreen->ClipNotify = ScreenPriv->ClipNotify;
1154*4882a593Smuzhiyun pScreen->CloseScreen = ScreenPriv->CloseScreen;
1155*4882a593Smuzhiyun
1156*4882a593Smuzhiyun pScrn->EnterVT = ScreenPriv->EnterVT;
1157*4882a593Smuzhiyun pScrn->LeaveVT = ScreenPriv->LeaveVT;
1158*4882a593Smuzhiyun pScrn->AdjustFrame = ScreenPriv->AdjustFrame;
1159*4882a593Smuzhiyun pScrn->ModeSet = ScreenPriv->ModeSet;
1160*4882a593Smuzhiyun
1161*4882a593Smuzhiyun for (c = 0, pa = pxvs->pAdaptors; c < pxvs->nAdaptors; c++, pa++) {
1162*4882a593Smuzhiyun xf86XVFreeAdaptor(pa);
1163*4882a593Smuzhiyun }
1164*4882a593Smuzhiyun
1165*4882a593Smuzhiyun free(pxvs->pAdaptors);
1166*4882a593Smuzhiyun free(ScreenPriv);
1167*4882a593Smuzhiyun
1168*4882a593Smuzhiyun return pScreen->CloseScreen(pScreen);
1169*4882a593Smuzhiyun }
1170*4882a593Smuzhiyun
1171*4882a593Smuzhiyun /**** ScrnInfoRec fields ****/
1172*4882a593Smuzhiyun
1173*4882a593Smuzhiyun static Bool
xf86XVEnterVT(ScrnInfoPtr pScrn)1174*4882a593Smuzhiyun xf86XVEnterVT(ScrnInfoPtr pScrn)
1175*4882a593Smuzhiyun {
1176*4882a593Smuzhiyun ScreenPtr pScreen = xf86ScrnToScreen(pScrn);
1177*4882a593Smuzhiyun XF86XVScreenPtr ScreenPriv = GET_XF86XV_SCREEN(pScreen);
1178*4882a593Smuzhiyun Bool ret;
1179*4882a593Smuzhiyun
1180*4882a593Smuzhiyun pScrn->EnterVT = ScreenPriv->EnterVT;
1181*4882a593Smuzhiyun ret = (*ScreenPriv->EnterVT) (pScrn);
1182*4882a593Smuzhiyun ScreenPriv->EnterVT = pScrn->EnterVT;
1183*4882a593Smuzhiyun pScrn->EnterVT = xf86XVEnterVT;
1184*4882a593Smuzhiyun
1185*4882a593Smuzhiyun if (ret)
1186*4882a593Smuzhiyun WalkTree(pScreen, xf86XVReputAllVideo, 0);
1187*4882a593Smuzhiyun
1188*4882a593Smuzhiyun return ret;
1189*4882a593Smuzhiyun }
1190*4882a593Smuzhiyun
1191*4882a593Smuzhiyun static void
xf86XVLeaveVT(ScrnInfoPtr pScrn)1192*4882a593Smuzhiyun xf86XVLeaveVT(ScrnInfoPtr pScrn)
1193*4882a593Smuzhiyun {
1194*4882a593Smuzhiyun ScreenPtr pScreen = xf86ScrnToScreen(pScrn);
1195*4882a593Smuzhiyun XvScreenPtr pxvs = GET_XV_SCREEN(pScreen);
1196*4882a593Smuzhiyun XF86XVScreenPtr ScreenPriv = GET_XF86XV_SCREEN(pScreen);
1197*4882a593Smuzhiyun XvAdaptorPtr pAdaptor;
1198*4882a593Smuzhiyun XvPortPtr pPort;
1199*4882a593Smuzhiyun XvPortRecPrivatePtr pPriv;
1200*4882a593Smuzhiyun int i, j;
1201*4882a593Smuzhiyun
1202*4882a593Smuzhiyun for (i = 0; i < pxvs->nAdaptors; i++) {
1203*4882a593Smuzhiyun pAdaptor = &pxvs->pAdaptors[i];
1204*4882a593Smuzhiyun for (j = 0; j < pAdaptor->nPorts; j++) {
1205*4882a593Smuzhiyun pPort = &pAdaptor->pPorts[j];
1206*4882a593Smuzhiyun pPriv = (XvPortRecPrivatePtr) pPort->devPriv.ptr;
1207*4882a593Smuzhiyun if (pPriv->isOn > XV_OFF) {
1208*4882a593Smuzhiyun
1209*4882a593Smuzhiyun (*pPriv->AdaptorRec->StopVideo) (pPriv->pScrn,
1210*4882a593Smuzhiyun pPriv->DevPriv.ptr, TRUE);
1211*4882a593Smuzhiyun pPriv->isOn = XV_OFF;
1212*4882a593Smuzhiyun
1213*4882a593Smuzhiyun if (pPriv->pCompositeClip && pPriv->FreeCompositeClip)
1214*4882a593Smuzhiyun RegionDestroy(pPriv->pCompositeClip);
1215*4882a593Smuzhiyun
1216*4882a593Smuzhiyun pPriv->pCompositeClip = NULL;
1217*4882a593Smuzhiyun
1218*4882a593Smuzhiyun if (!pPriv->type && pPriv->pDraw) { /* still */
1219*4882a593Smuzhiyun xf86XVRemovePortFromWindow((WindowPtr) pPriv->pDraw, pPriv);
1220*4882a593Smuzhiyun }
1221*4882a593Smuzhiyun }
1222*4882a593Smuzhiyun }
1223*4882a593Smuzhiyun }
1224*4882a593Smuzhiyun
1225*4882a593Smuzhiyun pScrn->LeaveVT = ScreenPriv->LeaveVT;
1226*4882a593Smuzhiyun (*ScreenPriv->LeaveVT) (pScrn);
1227*4882a593Smuzhiyun ScreenPriv->LeaveVT = pScrn->LeaveVT;
1228*4882a593Smuzhiyun pScrn->LeaveVT = xf86XVLeaveVT;
1229*4882a593Smuzhiyun }
1230*4882a593Smuzhiyun
1231*4882a593Smuzhiyun static void
xf86XVAdjustFrame(ScrnInfoPtr pScrn,int x,int y)1232*4882a593Smuzhiyun xf86XVAdjustFrame(ScrnInfoPtr pScrn, int x, int y)
1233*4882a593Smuzhiyun {
1234*4882a593Smuzhiyun ScreenPtr pScreen = xf86ScrnToScreen(pScrn);
1235*4882a593Smuzhiyun XF86XVScreenPtr ScreenPriv = GET_XF86XV_SCREEN(pScreen);
1236*4882a593Smuzhiyun
1237*4882a593Smuzhiyun if (ScreenPriv->AdjustFrame) {
1238*4882a593Smuzhiyun pScrn->AdjustFrame = ScreenPriv->AdjustFrame;
1239*4882a593Smuzhiyun (*pScrn->AdjustFrame) (pScrn, x, y);
1240*4882a593Smuzhiyun pScrn->AdjustFrame = xf86XVAdjustFrame;
1241*4882a593Smuzhiyun }
1242*4882a593Smuzhiyun
1243*4882a593Smuzhiyun xf86XVReputOrStopAllPorts(pScrn, FALSE);
1244*4882a593Smuzhiyun }
1245*4882a593Smuzhiyun
1246*4882a593Smuzhiyun static void
xf86XVModeSet(ScrnInfoPtr pScrn)1247*4882a593Smuzhiyun xf86XVModeSet(ScrnInfoPtr pScrn)
1248*4882a593Smuzhiyun {
1249*4882a593Smuzhiyun ScreenPtr pScreen = xf86ScrnToScreen(pScrn);
1250*4882a593Smuzhiyun XF86XVScreenPtr ScreenPriv;
1251*4882a593Smuzhiyun
1252*4882a593Smuzhiyun /* Can be called before pScrn->pScreen is set */
1253*4882a593Smuzhiyun if (!pScreen)
1254*4882a593Smuzhiyun return;
1255*4882a593Smuzhiyun
1256*4882a593Smuzhiyun ScreenPriv = GET_XF86XV_SCREEN(pScreen);
1257*4882a593Smuzhiyun
1258*4882a593Smuzhiyun if (ScreenPriv->ModeSet) {
1259*4882a593Smuzhiyun pScrn->ModeSet = ScreenPriv->ModeSet;
1260*4882a593Smuzhiyun (*pScrn->ModeSet) (pScrn);
1261*4882a593Smuzhiyun pScrn->ModeSet = xf86XVModeSet;
1262*4882a593Smuzhiyun }
1263*4882a593Smuzhiyun
1264*4882a593Smuzhiyun xf86XVReputOrStopAllPorts(pScrn, FALSE);
1265*4882a593Smuzhiyun }
1266*4882a593Smuzhiyun
1267*4882a593Smuzhiyun /**** XvAdaptorRec fields ****/
1268*4882a593Smuzhiyun
1269*4882a593Smuzhiyun static int
xf86XVPutVideo(DrawablePtr pDraw,XvPortPtr pPort,GCPtr pGC,INT16 vid_x,INT16 vid_y,CARD16 vid_w,CARD16 vid_h,INT16 drw_x,INT16 drw_y,CARD16 drw_w,CARD16 drw_h)1270*4882a593Smuzhiyun xf86XVPutVideo(DrawablePtr pDraw,
1271*4882a593Smuzhiyun XvPortPtr pPort,
1272*4882a593Smuzhiyun GCPtr pGC,
1273*4882a593Smuzhiyun INT16 vid_x, INT16 vid_y,
1274*4882a593Smuzhiyun CARD16 vid_w, CARD16 vid_h,
1275*4882a593Smuzhiyun INT16 drw_x, INT16 drw_y, CARD16 drw_w, CARD16 drw_h)
1276*4882a593Smuzhiyun {
1277*4882a593Smuzhiyun XvPortRecPrivatePtr portPriv = (XvPortRecPrivatePtr) (pPort->devPriv.ptr);
1278*4882a593Smuzhiyun int result;
1279*4882a593Smuzhiyun
1280*4882a593Smuzhiyun /* No dumping video to pixmaps... For now anyhow */
1281*4882a593Smuzhiyun if (pDraw->type != DRAWABLE_WINDOW) {
1282*4882a593Smuzhiyun pPort->pDraw = (DrawablePtr) NULL;
1283*4882a593Smuzhiyun return BadAlloc;
1284*4882a593Smuzhiyun }
1285*4882a593Smuzhiyun
1286*4882a593Smuzhiyun /* If we are changing windows, unregister our port in the old window */
1287*4882a593Smuzhiyun if (portPriv->pDraw && (portPriv->pDraw != pDraw))
1288*4882a593Smuzhiyun xf86XVRemovePortFromWindow((WindowPtr) (portPriv->pDraw), portPriv);
1289*4882a593Smuzhiyun
1290*4882a593Smuzhiyun /* Register our port with the new window */
1291*4882a593Smuzhiyun result = xf86XVEnlistPortInWindow((WindowPtr) pDraw, portPriv);
1292*4882a593Smuzhiyun if (result != Success)
1293*4882a593Smuzhiyun return result;
1294*4882a593Smuzhiyun
1295*4882a593Smuzhiyun portPriv->type = XvInputMask;
1296*4882a593Smuzhiyun
1297*4882a593Smuzhiyun /* save a copy of these parameters */
1298*4882a593Smuzhiyun portPriv->vid_x = vid_x;
1299*4882a593Smuzhiyun portPriv->vid_y = vid_y;
1300*4882a593Smuzhiyun portPriv->vid_w = vid_w;
1301*4882a593Smuzhiyun portPriv->vid_h = vid_h;
1302*4882a593Smuzhiyun portPriv->drw_x = drw_x;
1303*4882a593Smuzhiyun portPriv->drw_y = drw_y;
1304*4882a593Smuzhiyun portPriv->drw_w = drw_w;
1305*4882a593Smuzhiyun portPriv->drw_h = drw_h;
1306*4882a593Smuzhiyun
1307*4882a593Smuzhiyun /* make sure we have the most recent copy of the clientClip */
1308*4882a593Smuzhiyun xf86XVCopyClip(portPriv, pGC);
1309*4882a593Smuzhiyun
1310*4882a593Smuzhiyun /* To indicate to the DI layer that we were successful */
1311*4882a593Smuzhiyun pPort->pDraw = pDraw;
1312*4882a593Smuzhiyun
1313*4882a593Smuzhiyun if (!portPriv->pScrn->vtSema)
1314*4882a593Smuzhiyun return Success; /* Success ? */
1315*4882a593Smuzhiyun
1316*4882a593Smuzhiyun return (xf86XVReputVideo(portPriv));
1317*4882a593Smuzhiyun }
1318*4882a593Smuzhiyun
1319*4882a593Smuzhiyun static int
xf86XVPutStill(DrawablePtr pDraw,XvPortPtr pPort,GCPtr pGC,INT16 vid_x,INT16 vid_y,CARD16 vid_w,CARD16 vid_h,INT16 drw_x,INT16 drw_y,CARD16 drw_w,CARD16 drw_h)1320*4882a593Smuzhiyun xf86XVPutStill(DrawablePtr pDraw,
1321*4882a593Smuzhiyun XvPortPtr pPort,
1322*4882a593Smuzhiyun GCPtr pGC,
1323*4882a593Smuzhiyun INT16 vid_x, INT16 vid_y,
1324*4882a593Smuzhiyun CARD16 vid_w, CARD16 vid_h,
1325*4882a593Smuzhiyun INT16 drw_x, INT16 drw_y, CARD16 drw_w, CARD16 drw_h)
1326*4882a593Smuzhiyun {
1327*4882a593Smuzhiyun XvPortRecPrivatePtr portPriv = (XvPortRecPrivatePtr) (pPort->devPriv.ptr);
1328*4882a593Smuzhiyun RegionRec WinRegion;
1329*4882a593Smuzhiyun RegionRec ClipRegion;
1330*4882a593Smuzhiyun BoxRec WinBox;
1331*4882a593Smuzhiyun int ret = Success;
1332*4882a593Smuzhiyun Bool clippedAway = FALSE;
1333*4882a593Smuzhiyun
1334*4882a593Smuzhiyun if (pDraw->type != DRAWABLE_WINDOW)
1335*4882a593Smuzhiyun return BadAlloc;
1336*4882a593Smuzhiyun
1337*4882a593Smuzhiyun if (!portPriv->pScrn->vtSema)
1338*4882a593Smuzhiyun return Success; /* Success ? */
1339*4882a593Smuzhiyun
1340*4882a593Smuzhiyun WinBox.x1 = pDraw->x + drw_x;
1341*4882a593Smuzhiyun WinBox.y1 = pDraw->y + drw_y;
1342*4882a593Smuzhiyun WinBox.x2 = WinBox.x1 + drw_w;
1343*4882a593Smuzhiyun WinBox.y2 = WinBox.y1 + drw_h;
1344*4882a593Smuzhiyun
1345*4882a593Smuzhiyun xf86XVCopyCompositeClip(portPriv, pGC, pDraw);
1346*4882a593Smuzhiyun
1347*4882a593Smuzhiyun RegionInit(&WinRegion, &WinBox, 1);
1348*4882a593Smuzhiyun RegionNull(&ClipRegion);
1349*4882a593Smuzhiyun RegionIntersect(&ClipRegion, &WinRegion, pGC->pCompositeClip);
1350*4882a593Smuzhiyun
1351*4882a593Smuzhiyun if (portPriv->AdaptorRec->flags & VIDEO_CLIP_TO_VIEWPORT) {
1352*4882a593Smuzhiyun RegionRec VPReg;
1353*4882a593Smuzhiyun BoxRec VPBox;
1354*4882a593Smuzhiyun
1355*4882a593Smuzhiyun VPBox.x1 = portPriv->pScrn->frameX0;
1356*4882a593Smuzhiyun VPBox.y1 = portPriv->pScrn->frameY0;
1357*4882a593Smuzhiyun VPBox.x2 = portPriv->pScrn->frameX1 + 1;
1358*4882a593Smuzhiyun VPBox.y2 = portPriv->pScrn->frameY1 + 1;
1359*4882a593Smuzhiyun
1360*4882a593Smuzhiyun RegionInit(&VPReg, &VPBox, 1);
1361*4882a593Smuzhiyun RegionIntersect(&ClipRegion, &ClipRegion, &VPReg);
1362*4882a593Smuzhiyun RegionUninit(&VPReg);
1363*4882a593Smuzhiyun }
1364*4882a593Smuzhiyun
1365*4882a593Smuzhiyun if (portPriv->pDraw) {
1366*4882a593Smuzhiyun xf86XVRemovePortFromWindow((WindowPtr) (portPriv->pDraw), portPriv);
1367*4882a593Smuzhiyun }
1368*4882a593Smuzhiyun
1369*4882a593Smuzhiyun if (!RegionNotEmpty(&ClipRegion)) {
1370*4882a593Smuzhiyun clippedAway = TRUE;
1371*4882a593Smuzhiyun goto PUT_STILL_BAILOUT;
1372*4882a593Smuzhiyun }
1373*4882a593Smuzhiyun
1374*4882a593Smuzhiyun ret = (*portPriv->AdaptorRec->PutStill) (portPriv->pScrn,
1375*4882a593Smuzhiyun vid_x, vid_y, WinBox.x1, WinBox.y1,
1376*4882a593Smuzhiyun vid_w, vid_h, drw_w, drw_h,
1377*4882a593Smuzhiyun &ClipRegion, portPriv->DevPriv.ptr,
1378*4882a593Smuzhiyun pDraw);
1379*4882a593Smuzhiyun
1380*4882a593Smuzhiyun if ((ret == Success) &&
1381*4882a593Smuzhiyun (portPriv->AdaptorRec->flags & VIDEO_OVERLAID_STILLS)) {
1382*4882a593Smuzhiyun
1383*4882a593Smuzhiyun xf86XVEnlistPortInWindow((WindowPtr) pDraw, portPriv);
1384*4882a593Smuzhiyun portPriv->isOn = XV_ON;
1385*4882a593Smuzhiyun portPriv->vid_x = vid_x;
1386*4882a593Smuzhiyun portPriv->vid_y = vid_y;
1387*4882a593Smuzhiyun portPriv->vid_w = vid_w;
1388*4882a593Smuzhiyun portPriv->vid_h = vid_h;
1389*4882a593Smuzhiyun portPriv->drw_x = drw_x;
1390*4882a593Smuzhiyun portPriv->drw_y = drw_y;
1391*4882a593Smuzhiyun portPriv->drw_w = drw_w;
1392*4882a593Smuzhiyun portPriv->drw_h = drw_h;
1393*4882a593Smuzhiyun portPriv->type = 0; /* no mask means it's transient and should
1394*4882a593Smuzhiyun not be reput once it's removed */
1395*4882a593Smuzhiyun pPort->pDraw = pDraw; /* make sure we can get stop requests */
1396*4882a593Smuzhiyun }
1397*4882a593Smuzhiyun
1398*4882a593Smuzhiyun PUT_STILL_BAILOUT:
1399*4882a593Smuzhiyun
1400*4882a593Smuzhiyun if ((clippedAway || (ret != Success)) && (portPriv->isOn == XV_ON)) {
1401*4882a593Smuzhiyun (*portPriv->AdaptorRec->StopVideo) (portPriv->pScrn,
1402*4882a593Smuzhiyun portPriv->DevPriv.ptr, FALSE);
1403*4882a593Smuzhiyun portPriv->isOn = XV_PENDING;
1404*4882a593Smuzhiyun }
1405*4882a593Smuzhiyun
1406*4882a593Smuzhiyun /* This clip was copied and only good for one shot */
1407*4882a593Smuzhiyun if (!portPriv->FreeCompositeClip)
1408*4882a593Smuzhiyun portPriv->pCompositeClip = NULL;
1409*4882a593Smuzhiyun
1410*4882a593Smuzhiyun RegionUninit(&WinRegion);
1411*4882a593Smuzhiyun RegionUninit(&ClipRegion);
1412*4882a593Smuzhiyun
1413*4882a593Smuzhiyun return ret;
1414*4882a593Smuzhiyun }
1415*4882a593Smuzhiyun
1416*4882a593Smuzhiyun static int
xf86XVGetVideo(DrawablePtr pDraw,XvPortPtr pPort,GCPtr pGC,INT16 vid_x,INT16 vid_y,CARD16 vid_w,CARD16 vid_h,INT16 drw_x,INT16 drw_y,CARD16 drw_w,CARD16 drw_h)1417*4882a593Smuzhiyun xf86XVGetVideo(DrawablePtr pDraw,
1418*4882a593Smuzhiyun XvPortPtr pPort,
1419*4882a593Smuzhiyun GCPtr pGC,
1420*4882a593Smuzhiyun INT16 vid_x, INT16 vid_y,
1421*4882a593Smuzhiyun CARD16 vid_w, CARD16 vid_h,
1422*4882a593Smuzhiyun INT16 drw_x, INT16 drw_y, CARD16 drw_w, CARD16 drw_h)
1423*4882a593Smuzhiyun {
1424*4882a593Smuzhiyun XvPortRecPrivatePtr portPriv = (XvPortRecPrivatePtr) (pPort->devPriv.ptr);
1425*4882a593Smuzhiyun int result;
1426*4882a593Smuzhiyun
1427*4882a593Smuzhiyun /* No pixmaps... For now anyhow */
1428*4882a593Smuzhiyun if (pDraw->type != DRAWABLE_WINDOW) {
1429*4882a593Smuzhiyun pPort->pDraw = (DrawablePtr) NULL;
1430*4882a593Smuzhiyun return BadAlloc;
1431*4882a593Smuzhiyun }
1432*4882a593Smuzhiyun
1433*4882a593Smuzhiyun /* If we are changing windows, unregister our port in the old window */
1434*4882a593Smuzhiyun if (portPriv->pDraw && (portPriv->pDraw != pDraw))
1435*4882a593Smuzhiyun xf86XVRemovePortFromWindow((WindowPtr) (portPriv->pDraw), portPriv);
1436*4882a593Smuzhiyun
1437*4882a593Smuzhiyun /* Register our port with the new window */
1438*4882a593Smuzhiyun result = xf86XVEnlistPortInWindow((WindowPtr) pDraw, portPriv);
1439*4882a593Smuzhiyun if (result != Success)
1440*4882a593Smuzhiyun return result;
1441*4882a593Smuzhiyun
1442*4882a593Smuzhiyun portPriv->type = XvOutputMask;
1443*4882a593Smuzhiyun
1444*4882a593Smuzhiyun /* save a copy of these parameters */
1445*4882a593Smuzhiyun portPriv->vid_x = vid_x;
1446*4882a593Smuzhiyun portPriv->vid_y = vid_y;
1447*4882a593Smuzhiyun portPriv->vid_w = vid_w;
1448*4882a593Smuzhiyun portPriv->vid_h = vid_h;
1449*4882a593Smuzhiyun portPriv->drw_x = drw_x;
1450*4882a593Smuzhiyun portPriv->drw_y = drw_y;
1451*4882a593Smuzhiyun portPriv->drw_w = drw_w;
1452*4882a593Smuzhiyun portPriv->drw_h = drw_h;
1453*4882a593Smuzhiyun
1454*4882a593Smuzhiyun /* make sure we have the most recent copy of the clientClip */
1455*4882a593Smuzhiyun xf86XVCopyClip(portPriv, pGC);
1456*4882a593Smuzhiyun
1457*4882a593Smuzhiyun /* To indicate to the DI layer that we were successful */
1458*4882a593Smuzhiyun pPort->pDraw = pDraw;
1459*4882a593Smuzhiyun
1460*4882a593Smuzhiyun if (!portPriv->pScrn->vtSema)
1461*4882a593Smuzhiyun return Success; /* Success ? */
1462*4882a593Smuzhiyun
1463*4882a593Smuzhiyun return (xf86XVRegetVideo(portPriv));
1464*4882a593Smuzhiyun }
1465*4882a593Smuzhiyun
1466*4882a593Smuzhiyun static int
xf86XVGetStill(DrawablePtr pDraw,XvPortPtr pPort,GCPtr pGC,INT16 vid_x,INT16 vid_y,CARD16 vid_w,CARD16 vid_h,INT16 drw_x,INT16 drw_y,CARD16 drw_w,CARD16 drw_h)1467*4882a593Smuzhiyun xf86XVGetStill(DrawablePtr pDraw,
1468*4882a593Smuzhiyun XvPortPtr pPort,
1469*4882a593Smuzhiyun GCPtr pGC,
1470*4882a593Smuzhiyun INT16 vid_x, INT16 vid_y,
1471*4882a593Smuzhiyun CARD16 vid_w, CARD16 vid_h,
1472*4882a593Smuzhiyun INT16 drw_x, INT16 drw_y, CARD16 drw_w, CARD16 drw_h)
1473*4882a593Smuzhiyun {
1474*4882a593Smuzhiyun XvPortRecPrivatePtr portPriv = (XvPortRecPrivatePtr) (pPort->devPriv.ptr);
1475*4882a593Smuzhiyun RegionRec WinRegion;
1476*4882a593Smuzhiyun RegionRec ClipRegion;
1477*4882a593Smuzhiyun BoxRec WinBox;
1478*4882a593Smuzhiyun int ret = Success;
1479*4882a593Smuzhiyun Bool clippedAway = FALSE;
1480*4882a593Smuzhiyun
1481*4882a593Smuzhiyun if (pDraw->type != DRAWABLE_WINDOW)
1482*4882a593Smuzhiyun return BadAlloc;
1483*4882a593Smuzhiyun
1484*4882a593Smuzhiyun if (!portPriv->pScrn->vtSema)
1485*4882a593Smuzhiyun return Success; /* Success ? */
1486*4882a593Smuzhiyun
1487*4882a593Smuzhiyun WinBox.x1 = pDraw->x + drw_x;
1488*4882a593Smuzhiyun WinBox.y1 = pDraw->y + drw_y;
1489*4882a593Smuzhiyun WinBox.x2 = WinBox.x1 + drw_w;
1490*4882a593Smuzhiyun WinBox.y2 = WinBox.y1 + drw_h;
1491*4882a593Smuzhiyun
1492*4882a593Smuzhiyun RegionInit(&WinRegion, &WinBox, 1);
1493*4882a593Smuzhiyun RegionNull(&ClipRegion);
1494*4882a593Smuzhiyun RegionIntersect(&ClipRegion, &WinRegion, pGC->pCompositeClip);
1495*4882a593Smuzhiyun
1496*4882a593Smuzhiyun if (portPriv->pDraw) {
1497*4882a593Smuzhiyun xf86XVRemovePortFromWindow((WindowPtr) (portPriv->pDraw), portPriv);
1498*4882a593Smuzhiyun }
1499*4882a593Smuzhiyun
1500*4882a593Smuzhiyun if (!RegionNotEmpty(&ClipRegion)) {
1501*4882a593Smuzhiyun clippedAway = TRUE;
1502*4882a593Smuzhiyun goto GET_STILL_BAILOUT;
1503*4882a593Smuzhiyun }
1504*4882a593Smuzhiyun
1505*4882a593Smuzhiyun ret = (*portPriv->AdaptorRec->GetStill) (portPriv->pScrn,
1506*4882a593Smuzhiyun vid_x, vid_y, WinBox.x1, WinBox.y1,
1507*4882a593Smuzhiyun vid_w, vid_h, drw_w, drw_h,
1508*4882a593Smuzhiyun &ClipRegion, portPriv->DevPriv.ptr,
1509*4882a593Smuzhiyun pDraw);
1510*4882a593Smuzhiyun
1511*4882a593Smuzhiyun GET_STILL_BAILOUT:
1512*4882a593Smuzhiyun
1513*4882a593Smuzhiyun if ((clippedAway || (ret != Success)) && (portPriv->isOn == XV_ON)) {
1514*4882a593Smuzhiyun (*portPriv->AdaptorRec->StopVideo) (portPriv->pScrn,
1515*4882a593Smuzhiyun portPriv->DevPriv.ptr, FALSE);
1516*4882a593Smuzhiyun portPriv->isOn = XV_PENDING;
1517*4882a593Smuzhiyun }
1518*4882a593Smuzhiyun
1519*4882a593Smuzhiyun RegionUninit(&WinRegion);
1520*4882a593Smuzhiyun RegionUninit(&ClipRegion);
1521*4882a593Smuzhiyun
1522*4882a593Smuzhiyun return ret;
1523*4882a593Smuzhiyun }
1524*4882a593Smuzhiyun
1525*4882a593Smuzhiyun static int
xf86XVStopVideo(XvPortPtr pPort,DrawablePtr pDraw)1526*4882a593Smuzhiyun xf86XVStopVideo(XvPortPtr pPort, DrawablePtr pDraw)
1527*4882a593Smuzhiyun {
1528*4882a593Smuzhiyun XvPortRecPrivatePtr portPriv = (XvPortRecPrivatePtr) (pPort->devPriv.ptr);
1529*4882a593Smuzhiyun
1530*4882a593Smuzhiyun if (pDraw->type != DRAWABLE_WINDOW)
1531*4882a593Smuzhiyun return BadAlloc;
1532*4882a593Smuzhiyun
1533*4882a593Smuzhiyun xf86XVRemovePortFromWindow((WindowPtr) pDraw, portPriv);
1534*4882a593Smuzhiyun
1535*4882a593Smuzhiyun if (!portPriv->pScrn->vtSema)
1536*4882a593Smuzhiyun return Success; /* Success ? */
1537*4882a593Smuzhiyun
1538*4882a593Smuzhiyun /* Must free resources. */
1539*4882a593Smuzhiyun
1540*4882a593Smuzhiyun if (portPriv->isOn > XV_OFF) {
1541*4882a593Smuzhiyun (*portPriv->AdaptorRec->StopVideo) (portPriv->pScrn,
1542*4882a593Smuzhiyun portPriv->DevPriv.ptr, TRUE);
1543*4882a593Smuzhiyun portPriv->isOn = XV_OFF;
1544*4882a593Smuzhiyun }
1545*4882a593Smuzhiyun
1546*4882a593Smuzhiyun return Success;
1547*4882a593Smuzhiyun }
1548*4882a593Smuzhiyun
1549*4882a593Smuzhiyun static int
xf86XVSetPortAttribute(XvPortPtr pPort,Atom attribute,INT32 value)1550*4882a593Smuzhiyun xf86XVSetPortAttribute(XvPortPtr pPort, Atom attribute, INT32 value)
1551*4882a593Smuzhiyun {
1552*4882a593Smuzhiyun XvPortRecPrivatePtr portPriv = (XvPortRecPrivatePtr) (pPort->devPriv.ptr);
1553*4882a593Smuzhiyun
1554*4882a593Smuzhiyun return ((*portPriv->AdaptorRec->SetPortAttribute) (portPriv->pScrn,
1555*4882a593Smuzhiyun attribute, value,
1556*4882a593Smuzhiyun portPriv->DevPriv.ptr));
1557*4882a593Smuzhiyun }
1558*4882a593Smuzhiyun
1559*4882a593Smuzhiyun static int
xf86XVGetPortAttribute(XvPortPtr pPort,Atom attribute,INT32 * p_value)1560*4882a593Smuzhiyun xf86XVGetPortAttribute(XvPortPtr pPort, Atom attribute, INT32 *p_value)
1561*4882a593Smuzhiyun {
1562*4882a593Smuzhiyun XvPortRecPrivatePtr portPriv = (XvPortRecPrivatePtr) (pPort->devPriv.ptr);
1563*4882a593Smuzhiyun
1564*4882a593Smuzhiyun return ((*portPriv->AdaptorRec->GetPortAttribute) (portPriv->pScrn,
1565*4882a593Smuzhiyun attribute, p_value,
1566*4882a593Smuzhiyun portPriv->DevPriv.ptr));
1567*4882a593Smuzhiyun }
1568*4882a593Smuzhiyun
1569*4882a593Smuzhiyun static int
xf86XVQueryBestSize(XvPortPtr pPort,CARD8 motion,CARD16 vid_w,CARD16 vid_h,CARD16 drw_w,CARD16 drw_h,unsigned int * p_w,unsigned int * p_h)1570*4882a593Smuzhiyun xf86XVQueryBestSize(XvPortPtr pPort,
1571*4882a593Smuzhiyun CARD8 motion,
1572*4882a593Smuzhiyun CARD16 vid_w, CARD16 vid_h,
1573*4882a593Smuzhiyun CARD16 drw_w, CARD16 drw_h,
1574*4882a593Smuzhiyun unsigned int *p_w, unsigned int *p_h)
1575*4882a593Smuzhiyun {
1576*4882a593Smuzhiyun XvPortRecPrivatePtr portPriv = (XvPortRecPrivatePtr) (pPort->devPriv.ptr);
1577*4882a593Smuzhiyun
1578*4882a593Smuzhiyun (*portPriv->AdaptorRec->QueryBestSize) (portPriv->pScrn,
1579*4882a593Smuzhiyun (Bool) motion, vid_w, vid_h, drw_w,
1580*4882a593Smuzhiyun drw_h, p_w, p_h,
1581*4882a593Smuzhiyun portPriv->DevPriv.ptr);
1582*4882a593Smuzhiyun
1583*4882a593Smuzhiyun return Success;
1584*4882a593Smuzhiyun }
1585*4882a593Smuzhiyun
1586*4882a593Smuzhiyun static int
xf86XVPutImage(DrawablePtr pDraw,XvPortPtr pPort,GCPtr pGC,INT16 src_x,INT16 src_y,CARD16 src_w,CARD16 src_h,INT16 drw_x,INT16 drw_y,CARD16 drw_w,CARD16 drw_h,XvImagePtr format,unsigned char * data,Bool sync,CARD16 width,CARD16 height)1587*4882a593Smuzhiyun xf86XVPutImage(DrawablePtr pDraw,
1588*4882a593Smuzhiyun XvPortPtr pPort,
1589*4882a593Smuzhiyun GCPtr pGC,
1590*4882a593Smuzhiyun INT16 src_x, INT16 src_y,
1591*4882a593Smuzhiyun CARD16 src_w, CARD16 src_h,
1592*4882a593Smuzhiyun INT16 drw_x, INT16 drw_y,
1593*4882a593Smuzhiyun CARD16 drw_w, CARD16 drw_h,
1594*4882a593Smuzhiyun XvImagePtr format,
1595*4882a593Smuzhiyun unsigned char *data, Bool sync, CARD16 width, CARD16 height)
1596*4882a593Smuzhiyun {
1597*4882a593Smuzhiyun XvPortRecPrivatePtr portPriv = (XvPortRecPrivatePtr) (pPort->devPriv.ptr);
1598*4882a593Smuzhiyun RegionRec WinRegion;
1599*4882a593Smuzhiyun RegionRec ClipRegion;
1600*4882a593Smuzhiyun BoxRec WinBox;
1601*4882a593Smuzhiyun int ret = Success;
1602*4882a593Smuzhiyun Bool clippedAway = FALSE;
1603*4882a593Smuzhiyun
1604*4882a593Smuzhiyun if (pDraw->type != DRAWABLE_WINDOW)
1605*4882a593Smuzhiyun return BadAlloc;
1606*4882a593Smuzhiyun
1607*4882a593Smuzhiyun if (!portPriv->pScrn->vtSema)
1608*4882a593Smuzhiyun return Success; /* Success ? */
1609*4882a593Smuzhiyun
1610*4882a593Smuzhiyun xf86XVCopyCompositeClip(portPriv, pGC, pDraw);
1611*4882a593Smuzhiyun
1612*4882a593Smuzhiyun WinBox.x1 = pDraw->x + drw_x;
1613*4882a593Smuzhiyun WinBox.y1 = pDraw->y + drw_y;
1614*4882a593Smuzhiyun WinBox.x2 = WinBox.x1 + drw_w;
1615*4882a593Smuzhiyun WinBox.y2 = WinBox.y1 + drw_h;
1616*4882a593Smuzhiyun
1617*4882a593Smuzhiyun RegionInit(&WinRegion, &WinBox, 1);
1618*4882a593Smuzhiyun RegionNull(&ClipRegion);
1619*4882a593Smuzhiyun RegionIntersect(&ClipRegion, &WinRegion, pGC->pCompositeClip);
1620*4882a593Smuzhiyun
1621*4882a593Smuzhiyun if (portPriv->AdaptorRec->flags & VIDEO_CLIP_TO_VIEWPORT) {
1622*4882a593Smuzhiyun RegionRec VPReg;
1623*4882a593Smuzhiyun BoxRec VPBox;
1624*4882a593Smuzhiyun
1625*4882a593Smuzhiyun VPBox.x1 = portPriv->pScrn->frameX0;
1626*4882a593Smuzhiyun VPBox.y1 = portPriv->pScrn->frameY0;
1627*4882a593Smuzhiyun VPBox.x2 = portPriv->pScrn->frameX1 + 1;
1628*4882a593Smuzhiyun VPBox.y2 = portPriv->pScrn->frameY1 + 1;
1629*4882a593Smuzhiyun
1630*4882a593Smuzhiyun RegionInit(&VPReg, &VPBox, 1);
1631*4882a593Smuzhiyun RegionIntersect(&ClipRegion, &ClipRegion, &VPReg);
1632*4882a593Smuzhiyun RegionUninit(&VPReg);
1633*4882a593Smuzhiyun }
1634*4882a593Smuzhiyun
1635*4882a593Smuzhiyun /* If we are changing windows, unregister our port in the old window */
1636*4882a593Smuzhiyun if (portPriv->pDraw && (portPriv->pDraw != pDraw))
1637*4882a593Smuzhiyun xf86XVRemovePortFromWindow((WindowPtr) (portPriv->pDraw), portPriv);
1638*4882a593Smuzhiyun
1639*4882a593Smuzhiyun /* Register our port with the new window */
1640*4882a593Smuzhiyun ret = xf86XVEnlistPortInWindow((WindowPtr) pDraw, portPriv);
1641*4882a593Smuzhiyun if (ret != Success)
1642*4882a593Smuzhiyun goto PUT_IMAGE_BAILOUT;
1643*4882a593Smuzhiyun
1644*4882a593Smuzhiyun if (!RegionNotEmpty(&ClipRegion)) {
1645*4882a593Smuzhiyun clippedAway = TRUE;
1646*4882a593Smuzhiyun goto PUT_IMAGE_BAILOUT;
1647*4882a593Smuzhiyun }
1648*4882a593Smuzhiyun
1649*4882a593Smuzhiyun ret = (*portPriv->AdaptorRec->PutImage) (portPriv->pScrn,
1650*4882a593Smuzhiyun src_x, src_y, WinBox.x1, WinBox.y1,
1651*4882a593Smuzhiyun src_w, src_h, drw_w, drw_h,
1652*4882a593Smuzhiyun format->id, data, width, height,
1653*4882a593Smuzhiyun sync, &ClipRegion,
1654*4882a593Smuzhiyun portPriv->DevPriv.ptr, pDraw);
1655*4882a593Smuzhiyun
1656*4882a593Smuzhiyun if ((ret == Success) &&
1657*4882a593Smuzhiyun (portPriv->AdaptorRec->flags & VIDEO_OVERLAID_IMAGES)) {
1658*4882a593Smuzhiyun
1659*4882a593Smuzhiyun portPriv->isOn = XV_ON;
1660*4882a593Smuzhiyun portPriv->vid_x = src_x;
1661*4882a593Smuzhiyun portPriv->vid_y = src_y;
1662*4882a593Smuzhiyun portPriv->vid_w = src_w;
1663*4882a593Smuzhiyun portPriv->vid_h = src_h;
1664*4882a593Smuzhiyun portPriv->drw_x = drw_x;
1665*4882a593Smuzhiyun portPriv->drw_y = drw_y;
1666*4882a593Smuzhiyun portPriv->drw_w = drw_w;
1667*4882a593Smuzhiyun portPriv->drw_h = drw_h;
1668*4882a593Smuzhiyun portPriv->type = 0; /* no mask means it's transient and should
1669*4882a593Smuzhiyun not be reput once it's removed */
1670*4882a593Smuzhiyun pPort->pDraw = pDraw; /* make sure we can get stop requests */
1671*4882a593Smuzhiyun }
1672*4882a593Smuzhiyun
1673*4882a593Smuzhiyun PUT_IMAGE_BAILOUT:
1674*4882a593Smuzhiyun
1675*4882a593Smuzhiyun if ((clippedAway || (ret != Success)) && (portPriv->isOn == XV_ON)) {
1676*4882a593Smuzhiyun (*portPriv->AdaptorRec->StopVideo) (portPriv->pScrn,
1677*4882a593Smuzhiyun portPriv->DevPriv.ptr, FALSE);
1678*4882a593Smuzhiyun portPriv->isOn = XV_PENDING;
1679*4882a593Smuzhiyun }
1680*4882a593Smuzhiyun
1681*4882a593Smuzhiyun /* This clip was copied and only good for one shot */
1682*4882a593Smuzhiyun if (!portPriv->FreeCompositeClip)
1683*4882a593Smuzhiyun portPriv->pCompositeClip = NULL;
1684*4882a593Smuzhiyun
1685*4882a593Smuzhiyun RegionUninit(&WinRegion);
1686*4882a593Smuzhiyun RegionUninit(&ClipRegion);
1687*4882a593Smuzhiyun
1688*4882a593Smuzhiyun return ret;
1689*4882a593Smuzhiyun }
1690*4882a593Smuzhiyun
1691*4882a593Smuzhiyun static int
xf86XVQueryImageAttributes(XvPortPtr pPort,XvImagePtr format,CARD16 * width,CARD16 * height,int * pitches,int * offsets)1692*4882a593Smuzhiyun xf86XVQueryImageAttributes(XvPortPtr pPort,
1693*4882a593Smuzhiyun XvImagePtr format,
1694*4882a593Smuzhiyun CARD16 *width,
1695*4882a593Smuzhiyun CARD16 *height, int *pitches, int *offsets)
1696*4882a593Smuzhiyun {
1697*4882a593Smuzhiyun XvPortRecPrivatePtr portPriv = (XvPortRecPrivatePtr) (pPort->devPriv.ptr);
1698*4882a593Smuzhiyun
1699*4882a593Smuzhiyun return (*portPriv->AdaptorRec->QueryImageAttributes) (portPriv->pScrn,
1700*4882a593Smuzhiyun format->id, width,
1701*4882a593Smuzhiyun height, pitches,
1702*4882a593Smuzhiyun offsets);
1703*4882a593Smuzhiyun }
1704*4882a593Smuzhiyun
1705*4882a593Smuzhiyun void
xf86XVFillKeyHelperDrawable(DrawablePtr pDraw,CARD32 key,RegionPtr fillboxes)1706*4882a593Smuzhiyun xf86XVFillKeyHelperDrawable(DrawablePtr pDraw, CARD32 key, RegionPtr fillboxes)
1707*4882a593Smuzhiyun {
1708*4882a593Smuzhiyun ScreenPtr pScreen = pDraw->pScreen;
1709*4882a593Smuzhiyun
1710*4882a593Smuzhiyun if (!xf86ScreenToScrn(pScreen)->vtSema)
1711*4882a593Smuzhiyun return;
1712*4882a593Smuzhiyun
1713*4882a593Smuzhiyun XvFillColorKey(pDraw, key, fillboxes);
1714*4882a593Smuzhiyun }
1715*4882a593Smuzhiyun
1716*4882a593Smuzhiyun void
xf86XVFillKeyHelper(ScreenPtr pScreen,CARD32 key,RegionPtr fillboxes)1717*4882a593Smuzhiyun xf86XVFillKeyHelper(ScreenPtr pScreen, CARD32 key, RegionPtr fillboxes)
1718*4882a593Smuzhiyun {
1719*4882a593Smuzhiyun xf86XVFillKeyHelperDrawable(&pScreen->root->drawable, key, fillboxes);
1720*4882a593Smuzhiyun }
1721*4882a593Smuzhiyun
1722*4882a593Smuzhiyun void
xf86XVFillKeyHelperPort(DrawablePtr pDraw,void * data,CARD32 key,RegionPtr clipboxes,Bool fillEverything)1723*4882a593Smuzhiyun xf86XVFillKeyHelperPort(DrawablePtr pDraw, void *data, CARD32 key,
1724*4882a593Smuzhiyun RegionPtr clipboxes, Bool fillEverything)
1725*4882a593Smuzhiyun {
1726*4882a593Smuzhiyun WindowPtr pWin = (WindowPtr) pDraw;
1727*4882a593Smuzhiyun XF86XVWindowPtr WinPriv = GET_XF86XV_WINDOW(pWin);
1728*4882a593Smuzhiyun XvPortRecPrivatePtr portPriv = NULL;
1729*4882a593Smuzhiyun RegionRec reg;
1730*4882a593Smuzhiyun RegionPtr fillboxes;
1731*4882a593Smuzhiyun
1732*4882a593Smuzhiyun while (WinPriv) {
1733*4882a593Smuzhiyun XvPortRecPrivatePtr pPriv = WinPriv->PortRec;
1734*4882a593Smuzhiyun
1735*4882a593Smuzhiyun if (data == pPriv->DevPriv.ptr) {
1736*4882a593Smuzhiyun portPriv = pPriv;
1737*4882a593Smuzhiyun break;
1738*4882a593Smuzhiyun }
1739*4882a593Smuzhiyun
1740*4882a593Smuzhiyun WinPriv = WinPriv->next;
1741*4882a593Smuzhiyun }
1742*4882a593Smuzhiyun
1743*4882a593Smuzhiyun if (!portPriv)
1744*4882a593Smuzhiyun return;
1745*4882a593Smuzhiyun
1746*4882a593Smuzhiyun if (!portPriv->ckeyFilled)
1747*4882a593Smuzhiyun portPriv->ckeyFilled = RegionCreate(NULL, 0);
1748*4882a593Smuzhiyun
1749*4882a593Smuzhiyun if (!fillEverything) {
1750*4882a593Smuzhiyun RegionNull(®);
1751*4882a593Smuzhiyun fillboxes = ®
1752*4882a593Smuzhiyun RegionSubtract(fillboxes, clipboxes, portPriv->ckeyFilled);
1753*4882a593Smuzhiyun
1754*4882a593Smuzhiyun if (!RegionNotEmpty(fillboxes))
1755*4882a593Smuzhiyun goto out;
1756*4882a593Smuzhiyun }
1757*4882a593Smuzhiyun else
1758*4882a593Smuzhiyun fillboxes = clipboxes;
1759*4882a593Smuzhiyun
1760*4882a593Smuzhiyun RegionCopy(portPriv->ckeyFilled, clipboxes);
1761*4882a593Smuzhiyun
1762*4882a593Smuzhiyun xf86XVFillKeyHelperDrawable(pDraw, key, fillboxes);
1763*4882a593Smuzhiyun out:
1764*4882a593Smuzhiyun if (!fillEverything)
1765*4882a593Smuzhiyun RegionUninit(®);
1766*4882a593Smuzhiyun }
1767*4882a593Smuzhiyun
1768*4882a593Smuzhiyun /* xf86XVClipVideoHelper -
1769*4882a593Smuzhiyun
1770*4882a593Smuzhiyun Takes the dst box in standard X BoxRec form (top and left
1771*4882a593Smuzhiyun edges inclusive, bottom and right exclusive). The new dst
1772*4882a593Smuzhiyun box is returned. The source boundaries are given (x1, y1
1773*4882a593Smuzhiyun inclusive, x2, y2 exclusive) and returned are the new source
1774*4882a593Smuzhiyun boundaries in 16.16 fixed point.
1775*4882a593Smuzhiyun */
1776*4882a593Smuzhiyun
1777*4882a593Smuzhiyun Bool
xf86XVClipVideoHelper(BoxPtr dst,INT32 * xa,INT32 * xb,INT32 * ya,INT32 * yb,RegionPtr reg,INT32 width,INT32 height)1778*4882a593Smuzhiyun xf86XVClipVideoHelper(BoxPtr dst,
1779*4882a593Smuzhiyun INT32 *xa,
1780*4882a593Smuzhiyun INT32 *xb,
1781*4882a593Smuzhiyun INT32 *ya,
1782*4882a593Smuzhiyun INT32 *yb, RegionPtr reg, INT32 width, INT32 height)
1783*4882a593Smuzhiyun {
1784*4882a593Smuzhiyun double xsw, xdw, ysw, ydw;
1785*4882a593Smuzhiyun INT32 delta;
1786*4882a593Smuzhiyun BoxPtr extents = RegionExtents(reg);
1787*4882a593Smuzhiyun int diff;
1788*4882a593Smuzhiyun
1789*4882a593Smuzhiyun xsw = (*xb - *xa) << 16;
1790*4882a593Smuzhiyun xdw = dst->x2 - dst->x1;
1791*4882a593Smuzhiyun ysw = (*yb - *ya) << 16;
1792*4882a593Smuzhiyun ydw = dst->y2 - dst->y1;
1793*4882a593Smuzhiyun
1794*4882a593Smuzhiyun *xa <<= 16;
1795*4882a593Smuzhiyun *xb <<= 16;
1796*4882a593Smuzhiyun *ya <<= 16;
1797*4882a593Smuzhiyun *yb <<= 16;
1798*4882a593Smuzhiyun
1799*4882a593Smuzhiyun diff = extents->x1 - dst->x1;
1800*4882a593Smuzhiyun if (diff > 0) {
1801*4882a593Smuzhiyun dst->x1 = extents->x1;
1802*4882a593Smuzhiyun *xa += (diff * xsw) / xdw;
1803*4882a593Smuzhiyun }
1804*4882a593Smuzhiyun diff = dst->x2 - extents->x2;
1805*4882a593Smuzhiyun if (diff > 0) {
1806*4882a593Smuzhiyun dst->x2 = extents->x2;
1807*4882a593Smuzhiyun *xb -= (diff * xsw) / xdw;
1808*4882a593Smuzhiyun }
1809*4882a593Smuzhiyun diff = extents->y1 - dst->y1;
1810*4882a593Smuzhiyun if (diff > 0) {
1811*4882a593Smuzhiyun dst->y1 = extents->y1;
1812*4882a593Smuzhiyun *ya += (diff * ysw) / ydw;
1813*4882a593Smuzhiyun }
1814*4882a593Smuzhiyun diff = dst->y2 - extents->y2;
1815*4882a593Smuzhiyun if (diff > 0) {
1816*4882a593Smuzhiyun dst->y2 = extents->y2;
1817*4882a593Smuzhiyun *yb -= (diff * ysw) / ydw;
1818*4882a593Smuzhiyun }
1819*4882a593Smuzhiyun
1820*4882a593Smuzhiyun if (*xa < 0) {
1821*4882a593Smuzhiyun diff = (((-*xa) * xdw) + xsw - 1) / xsw;
1822*4882a593Smuzhiyun dst->x1 += diff;
1823*4882a593Smuzhiyun *xa += (diff * xsw) / xdw;
1824*4882a593Smuzhiyun }
1825*4882a593Smuzhiyun delta = *xb - (width << 16);
1826*4882a593Smuzhiyun if (delta > 0) {
1827*4882a593Smuzhiyun diff = ((delta * xdw) + xsw - 1) / xsw;
1828*4882a593Smuzhiyun dst->x2 -= diff;
1829*4882a593Smuzhiyun *xb -= (diff * xsw) / xdw;
1830*4882a593Smuzhiyun }
1831*4882a593Smuzhiyun if (*xa >= *xb)
1832*4882a593Smuzhiyun return FALSE;
1833*4882a593Smuzhiyun
1834*4882a593Smuzhiyun if (*ya < 0) {
1835*4882a593Smuzhiyun diff = (((-*ya) * ydw) + ysw - 1) / ysw;
1836*4882a593Smuzhiyun dst->y1 += diff;
1837*4882a593Smuzhiyun *ya += (diff * ysw) / ydw;
1838*4882a593Smuzhiyun }
1839*4882a593Smuzhiyun delta = *yb - (height << 16);
1840*4882a593Smuzhiyun if (delta > 0) {
1841*4882a593Smuzhiyun diff = ((delta * ydw) + ysw - 1) / ysw;
1842*4882a593Smuzhiyun dst->y2 -= diff;
1843*4882a593Smuzhiyun *yb -= (diff * ysw) / ydw;
1844*4882a593Smuzhiyun }
1845*4882a593Smuzhiyun if (*ya >= *yb)
1846*4882a593Smuzhiyun return FALSE;
1847*4882a593Smuzhiyun
1848*4882a593Smuzhiyun if ((dst->x1 > extents->x1) || (dst->x2 < extents->x2) ||
1849*4882a593Smuzhiyun (dst->y1 > extents->y1) || (dst->y2 < extents->y2)) {
1850*4882a593Smuzhiyun RegionRec clipReg;
1851*4882a593Smuzhiyun
1852*4882a593Smuzhiyun RegionInit(&clipReg, dst, 1);
1853*4882a593Smuzhiyun RegionIntersect(reg, reg, &clipReg);
1854*4882a593Smuzhiyun RegionUninit(&clipReg);
1855*4882a593Smuzhiyun }
1856*4882a593Smuzhiyun return TRUE;
1857*4882a593Smuzhiyun }
1858*4882a593Smuzhiyun
1859*4882a593Smuzhiyun void
xf86XVCopyYUV12ToPacked(const void * srcy,const void * srcv,const void * srcu,void * dst,int srcPitchy,int srcPitchuv,int dstPitch,int h,int w)1860*4882a593Smuzhiyun xf86XVCopyYUV12ToPacked(const void *srcy,
1861*4882a593Smuzhiyun const void *srcv,
1862*4882a593Smuzhiyun const void *srcu,
1863*4882a593Smuzhiyun void *dst,
1864*4882a593Smuzhiyun int srcPitchy,
1865*4882a593Smuzhiyun int srcPitchuv, int dstPitch, int h, int w)
1866*4882a593Smuzhiyun {
1867*4882a593Smuzhiyun CARD32 *Dst;
1868*4882a593Smuzhiyun const CARD8 *Y, *U, *V;
1869*4882a593Smuzhiyun int i, j;
1870*4882a593Smuzhiyun
1871*4882a593Smuzhiyun w >>= 1;
1872*4882a593Smuzhiyun
1873*4882a593Smuzhiyun for (j = 0; j < h; j++) {
1874*4882a593Smuzhiyun Dst = dst;
1875*4882a593Smuzhiyun Y = srcy;
1876*4882a593Smuzhiyun V = srcv;
1877*4882a593Smuzhiyun U = srcu;
1878*4882a593Smuzhiyun i = w;
1879*4882a593Smuzhiyun while (i >= 4) {
1880*4882a593Smuzhiyun #if X_BYTE_ORDER == X_LITTLE_ENDIAN
1881*4882a593Smuzhiyun Dst[0] = Y[0] | (Y[1] << 16) | (U[0] << 8) | (V[0] << 24);
1882*4882a593Smuzhiyun Dst[1] = Y[2] | (Y[3] << 16) | (U[1] << 8) | (V[1] << 24);
1883*4882a593Smuzhiyun Dst[2] = Y[4] | (Y[5] << 16) | (U[2] << 8) | (V[2] << 24);
1884*4882a593Smuzhiyun Dst[3] = Y[6] | (Y[7] << 16) | (U[3] << 8) | (V[3] << 24);
1885*4882a593Smuzhiyun #else
1886*4882a593Smuzhiyun /* This assumes a little-endian framebuffer */
1887*4882a593Smuzhiyun Dst[0] = (Y[0] << 24) | (Y[1] << 8) | (U[0] << 16) | V[0];
1888*4882a593Smuzhiyun Dst[1] = (Y[2] << 24) | (Y[3] << 8) | (U[1] << 16) | V[1];
1889*4882a593Smuzhiyun Dst[2] = (Y[4] << 24) | (Y[5] << 8) | (U[2] << 16) | V[2];
1890*4882a593Smuzhiyun Dst[3] = (Y[6] << 24) | (Y[7] << 8) | (U[3] << 16) | V[3];
1891*4882a593Smuzhiyun #endif
1892*4882a593Smuzhiyun Dst += 4;
1893*4882a593Smuzhiyun Y += 8;
1894*4882a593Smuzhiyun V += 4;
1895*4882a593Smuzhiyun U += 4;
1896*4882a593Smuzhiyun i -= 4;
1897*4882a593Smuzhiyun }
1898*4882a593Smuzhiyun
1899*4882a593Smuzhiyun while (i--) {
1900*4882a593Smuzhiyun #if X_BYTE_ORDER == X_LITTLE_ENDIAN
1901*4882a593Smuzhiyun Dst[0] = Y[0] | (Y[1] << 16) | (U[0] << 8) | (V[0] << 24);
1902*4882a593Smuzhiyun #else
1903*4882a593Smuzhiyun /* This assumes a little-endian framebuffer */
1904*4882a593Smuzhiyun Dst[0] = (Y[0] << 24) | (Y[1] << 8) | (U[0] << 16) | V[0];
1905*4882a593Smuzhiyun #endif
1906*4882a593Smuzhiyun Dst++;
1907*4882a593Smuzhiyun Y += 2;
1908*4882a593Smuzhiyun V++;
1909*4882a593Smuzhiyun U++;
1910*4882a593Smuzhiyun }
1911*4882a593Smuzhiyun
1912*4882a593Smuzhiyun dst = (CARD8 *) dst + dstPitch;
1913*4882a593Smuzhiyun srcy = (const CARD8 *) srcy + srcPitchy;
1914*4882a593Smuzhiyun if (j & 1) {
1915*4882a593Smuzhiyun srcu = (const CARD8 *) srcu + srcPitchuv;
1916*4882a593Smuzhiyun srcv = (const CARD8 *) srcv + srcPitchuv;
1917*4882a593Smuzhiyun }
1918*4882a593Smuzhiyun }
1919*4882a593Smuzhiyun }
1920*4882a593Smuzhiyun
1921*4882a593Smuzhiyun void
xf86XVCopyPacked(const void * src,void * dst,int srcPitch,int dstPitch,int h,int w)1922*4882a593Smuzhiyun xf86XVCopyPacked(const void *src,
1923*4882a593Smuzhiyun void *dst, int srcPitch, int dstPitch, int h, int w)
1924*4882a593Smuzhiyun {
1925*4882a593Smuzhiyun const CARD32 *Src;
1926*4882a593Smuzhiyun CARD32 *Dst;
1927*4882a593Smuzhiyun int i;
1928*4882a593Smuzhiyun
1929*4882a593Smuzhiyun w >>= 1;
1930*4882a593Smuzhiyun while (--h >= 0) {
1931*4882a593Smuzhiyun do {
1932*4882a593Smuzhiyun Dst = dst;
1933*4882a593Smuzhiyun Src = src;
1934*4882a593Smuzhiyun i = w;
1935*4882a593Smuzhiyun while (i >= 4) {
1936*4882a593Smuzhiyun Dst[0] = Src[0];
1937*4882a593Smuzhiyun Dst[1] = Src[1];
1938*4882a593Smuzhiyun Dst[2] = Src[2];
1939*4882a593Smuzhiyun Dst[3] = Src[3];
1940*4882a593Smuzhiyun Dst += 4;
1941*4882a593Smuzhiyun Src += 4;
1942*4882a593Smuzhiyun i -= 4;
1943*4882a593Smuzhiyun }
1944*4882a593Smuzhiyun if (!i)
1945*4882a593Smuzhiyun break;
1946*4882a593Smuzhiyun Dst[0] = Src[0];
1947*4882a593Smuzhiyun if (i == 1)
1948*4882a593Smuzhiyun break;
1949*4882a593Smuzhiyun Dst[1] = Src[1];
1950*4882a593Smuzhiyun if (i == 2)
1951*4882a593Smuzhiyun break;
1952*4882a593Smuzhiyun Dst[2] = Src[2];
1953*4882a593Smuzhiyun } while (0);
1954*4882a593Smuzhiyun
1955*4882a593Smuzhiyun src = (const CARD8 *) src + srcPitch;
1956*4882a593Smuzhiyun dst = (CARD8 *) dst + dstPitch;
1957*4882a593Smuzhiyun }
1958*4882a593Smuzhiyun }
1959