1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun
3*4882a593Smuzhiyun XFree86 Xv DDX written by Mark Vojkovich (markv@valinux.com)
4*4882a593Smuzhiyun Adapted for KDrive by Pontus Lidman <pontus.lidman@nokia.com>
5*4882a593Smuzhiyun
6*4882a593Smuzhiyun Copyright (C) 2000, 2001 - Nokia Home Communications
7*4882a593Smuzhiyun Copyright (C) 1998, 1999 - The XFree86 Project Inc.
8*4882a593Smuzhiyun
9*4882a593Smuzhiyun All rights reserved.
10*4882a593Smuzhiyun
11*4882a593Smuzhiyun Permission is hereby granted, free of charge, to any person obtaining
12*4882a593Smuzhiyun a copy of this software and associated documentation files (the
13*4882a593Smuzhiyun "Software"), to deal in the Software without restriction, including
14*4882a593Smuzhiyun without limitation the rights to use, copy, modify, merge, publish,
15*4882a593Smuzhiyun distribute, and/or sell copies of the Software, and to permit persons
16*4882a593Smuzhiyun to whom the Software is furnished to do so, provided that the above
17*4882a593Smuzhiyun copyright notice(s) and this permission notice appear in all copies of
18*4882a593Smuzhiyun the Software and that both the above copyright notice(s) and this
19*4882a593Smuzhiyun permission notice appear in supporting documentation.
20*4882a593Smuzhiyun
21*4882a593Smuzhiyun THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
22*4882a593Smuzhiyun EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
23*4882a593Smuzhiyun MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
24*4882a593Smuzhiyun OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
25*4882a593Smuzhiyun HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY
26*4882a593Smuzhiyun SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER
27*4882a593Smuzhiyun RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
28*4882a593Smuzhiyun CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
29*4882a593Smuzhiyun CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
30*4882a593Smuzhiyun
31*4882a593Smuzhiyun Except as contained in this notice, the name of a copyright holder
32*4882a593Smuzhiyun shall not be used in advertising or otherwise to promote the sale, use
33*4882a593Smuzhiyun or other dealings in this Software without prior written authorization
34*4882a593Smuzhiyun of the copyright holder.
35*4882a593Smuzhiyun
36*4882a593Smuzhiyun */
37*4882a593Smuzhiyun
38*4882a593Smuzhiyun #ifdef HAVE_DIX_CONFIG_H
39*4882a593Smuzhiyun #include <dix-config.h>
40*4882a593Smuzhiyun #endif
41*4882a593Smuzhiyun #include "kdrive.h"
42*4882a593Smuzhiyun
43*4882a593Smuzhiyun #include "scrnintstr.h"
44*4882a593Smuzhiyun #include "regionstr.h"
45*4882a593Smuzhiyun #include "windowstr.h"
46*4882a593Smuzhiyun #include "pixmapstr.h"
47*4882a593Smuzhiyun #include "mivalidate.h"
48*4882a593Smuzhiyun #include "validate.h"
49*4882a593Smuzhiyun #include "resource.h"
50*4882a593Smuzhiyun #include "gcstruct.h"
51*4882a593Smuzhiyun #include "dixstruct.h"
52*4882a593Smuzhiyun
53*4882a593Smuzhiyun #include <X11/extensions/Xv.h>
54*4882a593Smuzhiyun #include <X11/extensions/Xvproto.h>
55*4882a593Smuzhiyun
56*4882a593Smuzhiyun #include "kxv.h"
57*4882a593Smuzhiyun #include "fourcc.h"
58*4882a593Smuzhiyun
59*4882a593Smuzhiyun /* XvAdaptorRec fields */
60*4882a593Smuzhiyun
61*4882a593Smuzhiyun static int KdXVPutVideo(DrawablePtr, XvPortPtr, GCPtr,
62*4882a593Smuzhiyun INT16, INT16, CARD16, CARD16,
63*4882a593Smuzhiyun INT16, INT16, CARD16, CARD16);
64*4882a593Smuzhiyun static int KdXVPutStill(DrawablePtr, XvPortPtr, GCPtr,
65*4882a593Smuzhiyun INT16, INT16, CARD16, CARD16,
66*4882a593Smuzhiyun INT16, INT16, CARD16, CARD16);
67*4882a593Smuzhiyun static int KdXVGetVideo(DrawablePtr, XvPortPtr, GCPtr,
68*4882a593Smuzhiyun INT16, INT16, CARD16, CARD16,
69*4882a593Smuzhiyun INT16, INT16, CARD16, CARD16);
70*4882a593Smuzhiyun static int KdXVGetStill(DrawablePtr, XvPortPtr, GCPtr,
71*4882a593Smuzhiyun INT16, INT16, CARD16, CARD16,
72*4882a593Smuzhiyun INT16, INT16, CARD16, CARD16);
73*4882a593Smuzhiyun static int KdXVStopVideo(XvPortPtr, DrawablePtr);
74*4882a593Smuzhiyun static int KdXVSetPortAttribute(XvPortPtr, Atom, INT32);
75*4882a593Smuzhiyun static int KdXVGetPortAttribute(XvPortPtr, Atom, INT32 *);
76*4882a593Smuzhiyun static int KdXVQueryBestSize(XvPortPtr, CARD8,
77*4882a593Smuzhiyun CARD16, CARD16, CARD16, CARD16,
78*4882a593Smuzhiyun unsigned int *, unsigned int *);
79*4882a593Smuzhiyun static int KdXVPutImage(DrawablePtr, XvPortPtr, GCPtr,
80*4882a593Smuzhiyun INT16, INT16, CARD16, CARD16,
81*4882a593Smuzhiyun INT16, INT16, CARD16, CARD16,
82*4882a593Smuzhiyun XvImagePtr, unsigned char *, Bool, CARD16, CARD16);
83*4882a593Smuzhiyun static int KdXVQueryImageAttributes(XvPortPtr, XvImagePtr,
84*4882a593Smuzhiyun CARD16 *, CARD16 *, int *, int *);
85*4882a593Smuzhiyun
86*4882a593Smuzhiyun /* ScreenRec fields */
87*4882a593Smuzhiyun
88*4882a593Smuzhiyun static Bool KdXVDestroyWindow(WindowPtr pWin);
89*4882a593Smuzhiyun static void KdXVWindowExposures(WindowPtr pWin, RegionPtr r1);
90*4882a593Smuzhiyun static void KdXVClipNotify(WindowPtr pWin, int dx, int dy);
91*4882a593Smuzhiyun static Bool KdXVCloseScreen(ScreenPtr);
92*4882a593Smuzhiyun
93*4882a593Smuzhiyun /* misc */
94*4882a593Smuzhiyun static Bool KdXVInitAdaptors(ScreenPtr, KdVideoAdaptorPtr, int);
95*4882a593Smuzhiyun
96*4882a593Smuzhiyun static DevPrivateKeyRec KdXVWindowKeyRec;
97*4882a593Smuzhiyun
98*4882a593Smuzhiyun #define KdXVWindowKey (&KdXVWindowKeyRec)
99*4882a593Smuzhiyun static DevPrivateKey KdXvScreenKey;
100*4882a593Smuzhiyun static DevPrivateKeyRec KdXVScreenPrivateKey;
101*4882a593Smuzhiyun static unsigned long KdXVGeneration = 0;
102*4882a593Smuzhiyun static unsigned long PortResource = 0;
103*4882a593Smuzhiyun
104*4882a593Smuzhiyun #define GET_XV_SCREEN(pScreen) ((XvScreenPtr) \
105*4882a593Smuzhiyun dixLookupPrivate(&(pScreen)->devPrivates, KdXvScreenKey))
106*4882a593Smuzhiyun
107*4882a593Smuzhiyun #define GET_KDXV_SCREEN(pScreen) \
108*4882a593Smuzhiyun ((KdXVScreenPtr)(dixGetPrivate(&pScreen->devPrivates, &KdXVScreenPrivateKey)))
109*4882a593Smuzhiyun
110*4882a593Smuzhiyun #define GET_KDXV_WINDOW(pWin) ((KdXVWindowPtr) \
111*4882a593Smuzhiyun dixLookupPrivate(&(pWin)->devPrivates, KdXVWindowKey))
112*4882a593Smuzhiyun
113*4882a593Smuzhiyun Bool
KdXVScreenInit(ScreenPtr pScreen,KdVideoAdaptorPtr adaptors,int num)114*4882a593Smuzhiyun KdXVScreenInit(ScreenPtr pScreen, KdVideoAdaptorPtr adaptors, int num)
115*4882a593Smuzhiyun {
116*4882a593Smuzhiyun KdXVScreenPtr ScreenPriv;
117*4882a593Smuzhiyun
118*4882a593Smuzhiyun /* fprintf(stderr,"KdXVScreenInit initializing %d adaptors\n",num); */
119*4882a593Smuzhiyun
120*4882a593Smuzhiyun if (KdXVGeneration != serverGeneration)
121*4882a593Smuzhiyun KdXVGeneration = serverGeneration;
122*4882a593Smuzhiyun
123*4882a593Smuzhiyun if (noXvExtension)
124*4882a593Smuzhiyun return FALSE;
125*4882a593Smuzhiyun
126*4882a593Smuzhiyun if (!dixRegisterPrivateKey(&KdXVWindowKeyRec, PRIVATE_WINDOW, 0))
127*4882a593Smuzhiyun return FALSE;
128*4882a593Smuzhiyun if (!dixRegisterPrivateKey(&KdXVScreenPrivateKey, PRIVATE_SCREEN, 0))
129*4882a593Smuzhiyun return FALSE;
130*4882a593Smuzhiyun
131*4882a593Smuzhiyun if (Success != XvScreenInit(pScreen))
132*4882a593Smuzhiyun return FALSE;
133*4882a593Smuzhiyun
134*4882a593Smuzhiyun KdXvScreenKey = XvGetScreenKey();
135*4882a593Smuzhiyun PortResource = XvGetRTPort();
136*4882a593Smuzhiyun
137*4882a593Smuzhiyun ScreenPriv = malloc(sizeof(KdXVScreenRec));
138*4882a593Smuzhiyun dixSetPrivate(&pScreen->devPrivates, &KdXVScreenPrivateKey, ScreenPriv);
139*4882a593Smuzhiyun
140*4882a593Smuzhiyun if (!ScreenPriv)
141*4882a593Smuzhiyun return FALSE;
142*4882a593Smuzhiyun
143*4882a593Smuzhiyun ScreenPriv->DestroyWindow = pScreen->DestroyWindow;
144*4882a593Smuzhiyun ScreenPriv->WindowExposures = pScreen->WindowExposures;
145*4882a593Smuzhiyun ScreenPriv->ClipNotify = pScreen->ClipNotify;
146*4882a593Smuzhiyun ScreenPriv->CloseScreen = pScreen->CloseScreen;
147*4882a593Smuzhiyun
148*4882a593Smuzhiyun /* fprintf(stderr,"XV: Wrapping screen funcs\n"); */
149*4882a593Smuzhiyun
150*4882a593Smuzhiyun pScreen->DestroyWindow = KdXVDestroyWindow;
151*4882a593Smuzhiyun pScreen->WindowExposures = KdXVWindowExposures;
152*4882a593Smuzhiyun pScreen->ClipNotify = KdXVClipNotify;
153*4882a593Smuzhiyun pScreen->CloseScreen = KdXVCloseScreen;
154*4882a593Smuzhiyun
155*4882a593Smuzhiyun if (!KdXVInitAdaptors(pScreen, adaptors, num))
156*4882a593Smuzhiyun return FALSE;
157*4882a593Smuzhiyun
158*4882a593Smuzhiyun return TRUE;
159*4882a593Smuzhiyun }
160*4882a593Smuzhiyun
161*4882a593Smuzhiyun static void
KdXVFreeAdaptor(XvAdaptorPtr pAdaptor)162*4882a593Smuzhiyun KdXVFreeAdaptor(XvAdaptorPtr pAdaptor)
163*4882a593Smuzhiyun {
164*4882a593Smuzhiyun int i;
165*4882a593Smuzhiyun
166*4882a593Smuzhiyun if (pAdaptor->pPorts) {
167*4882a593Smuzhiyun XvPortPtr pPort = pAdaptor->pPorts;
168*4882a593Smuzhiyun XvPortRecPrivatePtr pPriv;
169*4882a593Smuzhiyun
170*4882a593Smuzhiyun for (i = 0; i < pAdaptor->nPorts; i++, pPort++) {
171*4882a593Smuzhiyun pPriv = (XvPortRecPrivatePtr) pPort->devPriv.ptr;
172*4882a593Smuzhiyun if (pPriv) {
173*4882a593Smuzhiyun if (pPriv->clientClip)
174*4882a593Smuzhiyun RegionDestroy(pPriv->clientClip);
175*4882a593Smuzhiyun if (pPriv->pCompositeClip && pPriv->FreeCompositeClip)
176*4882a593Smuzhiyun RegionDestroy(pPriv->pCompositeClip);
177*4882a593Smuzhiyun free(pPriv);
178*4882a593Smuzhiyun }
179*4882a593Smuzhiyun }
180*4882a593Smuzhiyun }
181*4882a593Smuzhiyun
182*4882a593Smuzhiyun XvFreeAdaptor(pAdaptor);
183*4882a593Smuzhiyun }
184*4882a593Smuzhiyun
185*4882a593Smuzhiyun static Bool
KdXVInitAdaptors(ScreenPtr pScreen,KdVideoAdaptorPtr infoPtr,int number)186*4882a593Smuzhiyun KdXVInitAdaptors(ScreenPtr pScreen, KdVideoAdaptorPtr infoPtr, int number)
187*4882a593Smuzhiyun {
188*4882a593Smuzhiyun KdScreenPriv(pScreen);
189*4882a593Smuzhiyun KdScreenInfo *screen = pScreenPriv->screen;
190*4882a593Smuzhiyun
191*4882a593Smuzhiyun XvScreenPtr pxvs = GET_XV_SCREEN(pScreen);
192*4882a593Smuzhiyun KdVideoAdaptorPtr adaptorPtr;
193*4882a593Smuzhiyun XvAdaptorPtr pAdaptor, pa;
194*4882a593Smuzhiyun XvAdaptorRecPrivatePtr adaptorPriv;
195*4882a593Smuzhiyun int na, numAdaptor;
196*4882a593Smuzhiyun XvPortRecPrivatePtr portPriv;
197*4882a593Smuzhiyun XvPortPtr pPort, pp;
198*4882a593Smuzhiyun int numPort;
199*4882a593Smuzhiyun KdVideoFormatPtr formatPtr;
200*4882a593Smuzhiyun XvFormatPtr pFormat, pf;
201*4882a593Smuzhiyun int numFormat, totFormat;
202*4882a593Smuzhiyun KdVideoEncodingPtr encodingPtr;
203*4882a593Smuzhiyun XvEncodingPtr pEncode, pe;
204*4882a593Smuzhiyun int numVisuals;
205*4882a593Smuzhiyun VisualPtr pVisual;
206*4882a593Smuzhiyun int i;
207*4882a593Smuzhiyun
208*4882a593Smuzhiyun pxvs->nAdaptors = 0;
209*4882a593Smuzhiyun pxvs->pAdaptors = NULL;
210*4882a593Smuzhiyun
211*4882a593Smuzhiyun if (!(pAdaptor = calloc(number, sizeof(XvAdaptorRec))))
212*4882a593Smuzhiyun return FALSE;
213*4882a593Smuzhiyun
214*4882a593Smuzhiyun for (pa = pAdaptor, na = 0, numAdaptor = 0; na < number; na++, adaptorPtr++) {
215*4882a593Smuzhiyun adaptorPtr = &infoPtr[na];
216*4882a593Smuzhiyun
217*4882a593Smuzhiyun if (!adaptorPtr->StopVideo || !adaptorPtr->SetPortAttribute ||
218*4882a593Smuzhiyun !adaptorPtr->GetPortAttribute || !adaptorPtr->QueryBestSize)
219*4882a593Smuzhiyun continue;
220*4882a593Smuzhiyun
221*4882a593Smuzhiyun /* client libs expect at least one encoding */
222*4882a593Smuzhiyun if (!adaptorPtr->nEncodings || !adaptorPtr->pEncodings)
223*4882a593Smuzhiyun continue;
224*4882a593Smuzhiyun
225*4882a593Smuzhiyun pa->type = adaptorPtr->type;
226*4882a593Smuzhiyun
227*4882a593Smuzhiyun if (!adaptorPtr->PutVideo && !adaptorPtr->GetVideo)
228*4882a593Smuzhiyun pa->type &= ~XvVideoMask;
229*4882a593Smuzhiyun
230*4882a593Smuzhiyun if (!adaptorPtr->PutStill && !adaptorPtr->GetStill)
231*4882a593Smuzhiyun pa->type &= ~XvStillMask;
232*4882a593Smuzhiyun
233*4882a593Smuzhiyun if (!adaptorPtr->PutImage || !adaptorPtr->QueryImageAttributes)
234*4882a593Smuzhiyun pa->type &= ~XvImageMask;
235*4882a593Smuzhiyun
236*4882a593Smuzhiyun if (!adaptorPtr->PutVideo && !adaptorPtr->PutImage &&
237*4882a593Smuzhiyun !adaptorPtr->PutStill)
238*4882a593Smuzhiyun pa->type &= ~XvInputMask;
239*4882a593Smuzhiyun
240*4882a593Smuzhiyun if (!adaptorPtr->GetVideo && !adaptorPtr->GetStill)
241*4882a593Smuzhiyun pa->type &= ~XvOutputMask;
242*4882a593Smuzhiyun
243*4882a593Smuzhiyun if (!(adaptorPtr->type & (XvPixmapMask | XvWindowMask)))
244*4882a593Smuzhiyun continue;
245*4882a593Smuzhiyun if (!(adaptorPtr->type & (XvImageMask | XvVideoMask | XvStillMask)))
246*4882a593Smuzhiyun continue;
247*4882a593Smuzhiyun
248*4882a593Smuzhiyun pa->pScreen = pScreen;
249*4882a593Smuzhiyun pa->ddPutVideo = KdXVPutVideo;
250*4882a593Smuzhiyun pa->ddPutStill = KdXVPutStill;
251*4882a593Smuzhiyun pa->ddGetVideo = KdXVGetVideo;
252*4882a593Smuzhiyun pa->ddGetStill = KdXVGetStill;
253*4882a593Smuzhiyun pa->ddStopVideo = KdXVStopVideo;
254*4882a593Smuzhiyun pa->ddPutImage = KdXVPutImage;
255*4882a593Smuzhiyun pa->ddSetPortAttribute = KdXVSetPortAttribute;
256*4882a593Smuzhiyun pa->ddGetPortAttribute = KdXVGetPortAttribute;
257*4882a593Smuzhiyun pa->ddQueryBestSize = KdXVQueryBestSize;
258*4882a593Smuzhiyun pa->ddQueryImageAttributes = KdXVQueryImageAttributes;
259*4882a593Smuzhiyun pa->name = strdup(adaptorPtr->name);
260*4882a593Smuzhiyun
261*4882a593Smuzhiyun if (adaptorPtr->nEncodings &&
262*4882a593Smuzhiyun (pEncode = calloc(adaptorPtr->nEncodings, sizeof(XvEncodingRec)))) {
263*4882a593Smuzhiyun
264*4882a593Smuzhiyun for (pe = pEncode, encodingPtr = adaptorPtr->pEncodings, i = 0;
265*4882a593Smuzhiyun i < adaptorPtr->nEncodings; pe++, i++, encodingPtr++) {
266*4882a593Smuzhiyun pe->id = encodingPtr->id;
267*4882a593Smuzhiyun pe->pScreen = pScreen;
268*4882a593Smuzhiyun pe->name = strdup(encodingPtr->name);
269*4882a593Smuzhiyun pe->width = encodingPtr->width;
270*4882a593Smuzhiyun pe->height = encodingPtr->height;
271*4882a593Smuzhiyun pe->rate.numerator = encodingPtr->rate.numerator;
272*4882a593Smuzhiyun pe->rate.denominator = encodingPtr->rate.denominator;
273*4882a593Smuzhiyun }
274*4882a593Smuzhiyun pa->nEncodings = adaptorPtr->nEncodings;
275*4882a593Smuzhiyun pa->pEncodings = pEncode;
276*4882a593Smuzhiyun }
277*4882a593Smuzhiyun
278*4882a593Smuzhiyun if (adaptorPtr->nImages &&
279*4882a593Smuzhiyun (pa->pImages = calloc(adaptorPtr->nImages, sizeof(XvImageRec)))) {
280*4882a593Smuzhiyun memcpy(pa->pImages, adaptorPtr->pImages,
281*4882a593Smuzhiyun adaptorPtr->nImages * sizeof(XvImageRec));
282*4882a593Smuzhiyun pa->nImages = adaptorPtr->nImages;
283*4882a593Smuzhiyun }
284*4882a593Smuzhiyun
285*4882a593Smuzhiyun if (adaptorPtr->nAttributes &&
286*4882a593Smuzhiyun (pa->pAttributes = calloc(adaptorPtr->nAttributes,
287*4882a593Smuzhiyun sizeof(XvAttributeRec)))) {
288*4882a593Smuzhiyun memcpy(pa->pAttributes, adaptorPtr->pAttributes,
289*4882a593Smuzhiyun adaptorPtr->nAttributes * sizeof(XvAttributeRec));
290*4882a593Smuzhiyun
291*4882a593Smuzhiyun for (i = 0; i < adaptorPtr->nAttributes; i++) {
292*4882a593Smuzhiyun pa->pAttributes[i].name =
293*4882a593Smuzhiyun strdup(adaptorPtr->pAttributes[i].name);
294*4882a593Smuzhiyun }
295*4882a593Smuzhiyun
296*4882a593Smuzhiyun pa->nAttributes = adaptorPtr->nAttributes;
297*4882a593Smuzhiyun }
298*4882a593Smuzhiyun
299*4882a593Smuzhiyun totFormat = adaptorPtr->nFormats;
300*4882a593Smuzhiyun
301*4882a593Smuzhiyun if (!(pFormat = calloc(totFormat, sizeof(XvFormatRec)))) {
302*4882a593Smuzhiyun KdXVFreeAdaptor(pa);
303*4882a593Smuzhiyun continue;
304*4882a593Smuzhiyun }
305*4882a593Smuzhiyun for (pf = pFormat, i = 0, numFormat = 0, formatPtr =
306*4882a593Smuzhiyun adaptorPtr->pFormats; i < adaptorPtr->nFormats; i++, formatPtr++) {
307*4882a593Smuzhiyun numVisuals = pScreen->numVisuals;
308*4882a593Smuzhiyun pVisual = pScreen->visuals;
309*4882a593Smuzhiyun
310*4882a593Smuzhiyun while (numVisuals--) {
311*4882a593Smuzhiyun if ((pVisual->class == formatPtr->class) &&
312*4882a593Smuzhiyun (pVisual->nplanes == formatPtr->depth)) {
313*4882a593Smuzhiyun
314*4882a593Smuzhiyun if (numFormat >= totFormat) {
315*4882a593Smuzhiyun void *moreSpace;
316*4882a593Smuzhiyun
317*4882a593Smuzhiyun totFormat *= 2;
318*4882a593Smuzhiyun moreSpace = reallocarray(pFormat, totFormat,
319*4882a593Smuzhiyun sizeof(XvFormatRec));
320*4882a593Smuzhiyun if (!moreSpace)
321*4882a593Smuzhiyun break;
322*4882a593Smuzhiyun pFormat = moreSpace;
323*4882a593Smuzhiyun pf = pFormat + numFormat;
324*4882a593Smuzhiyun }
325*4882a593Smuzhiyun
326*4882a593Smuzhiyun pf->visual = pVisual->vid;
327*4882a593Smuzhiyun pf->depth = formatPtr->depth;
328*4882a593Smuzhiyun
329*4882a593Smuzhiyun pf++;
330*4882a593Smuzhiyun numFormat++;
331*4882a593Smuzhiyun }
332*4882a593Smuzhiyun pVisual++;
333*4882a593Smuzhiyun }
334*4882a593Smuzhiyun }
335*4882a593Smuzhiyun pa->nFormats = numFormat;
336*4882a593Smuzhiyun pa->pFormats = pFormat;
337*4882a593Smuzhiyun if (!numFormat) {
338*4882a593Smuzhiyun KdXVFreeAdaptor(pa);
339*4882a593Smuzhiyun continue;
340*4882a593Smuzhiyun }
341*4882a593Smuzhiyun
342*4882a593Smuzhiyun if (!(adaptorPriv = calloc(1, sizeof(XvAdaptorRecPrivate)))) {
343*4882a593Smuzhiyun KdXVFreeAdaptor(pa);
344*4882a593Smuzhiyun continue;
345*4882a593Smuzhiyun }
346*4882a593Smuzhiyun
347*4882a593Smuzhiyun adaptorPriv->flags = adaptorPtr->flags;
348*4882a593Smuzhiyun adaptorPriv->PutVideo = adaptorPtr->PutVideo;
349*4882a593Smuzhiyun adaptorPriv->PutStill = adaptorPtr->PutStill;
350*4882a593Smuzhiyun adaptorPriv->GetVideo = adaptorPtr->GetVideo;
351*4882a593Smuzhiyun adaptorPriv->GetStill = adaptorPtr->GetStill;
352*4882a593Smuzhiyun adaptorPriv->StopVideo = adaptorPtr->StopVideo;
353*4882a593Smuzhiyun adaptorPriv->SetPortAttribute = adaptorPtr->SetPortAttribute;
354*4882a593Smuzhiyun adaptorPriv->GetPortAttribute = adaptorPtr->GetPortAttribute;
355*4882a593Smuzhiyun adaptorPriv->QueryBestSize = adaptorPtr->QueryBestSize;
356*4882a593Smuzhiyun adaptorPriv->QueryImageAttributes = adaptorPtr->QueryImageAttributes;
357*4882a593Smuzhiyun adaptorPriv->PutImage = adaptorPtr->PutImage;
358*4882a593Smuzhiyun adaptorPriv->ReputImage = adaptorPtr->ReputImage;
359*4882a593Smuzhiyun
360*4882a593Smuzhiyun pa->devPriv.ptr = (void *) adaptorPriv;
361*4882a593Smuzhiyun
362*4882a593Smuzhiyun if (!(pPort = calloc(adaptorPtr->nPorts, sizeof(XvPortRec)))) {
363*4882a593Smuzhiyun KdXVFreeAdaptor(pa);
364*4882a593Smuzhiyun continue;
365*4882a593Smuzhiyun }
366*4882a593Smuzhiyun for (pp = pPort, i = 0, numPort = 0; i < adaptorPtr->nPorts; i++) {
367*4882a593Smuzhiyun
368*4882a593Smuzhiyun if (!(pp->id = FakeClientID(0)))
369*4882a593Smuzhiyun continue;
370*4882a593Smuzhiyun
371*4882a593Smuzhiyun if (!(portPriv = calloc(1, sizeof(XvPortRecPrivate))))
372*4882a593Smuzhiyun continue;
373*4882a593Smuzhiyun
374*4882a593Smuzhiyun if (!AddResource(pp->id, PortResource, pp)) {
375*4882a593Smuzhiyun free(portPriv);
376*4882a593Smuzhiyun continue;
377*4882a593Smuzhiyun }
378*4882a593Smuzhiyun
379*4882a593Smuzhiyun pp->pAdaptor = pa;
380*4882a593Smuzhiyun pp->pNotify = (XvPortNotifyPtr) NULL;
381*4882a593Smuzhiyun pp->pDraw = (DrawablePtr) NULL;
382*4882a593Smuzhiyun pp->client = (ClientPtr) NULL;
383*4882a593Smuzhiyun pp->grab.client = (ClientPtr) NULL;
384*4882a593Smuzhiyun pp->time = currentTime;
385*4882a593Smuzhiyun pp->devPriv.ptr = portPriv;
386*4882a593Smuzhiyun
387*4882a593Smuzhiyun portPriv->screen = screen;
388*4882a593Smuzhiyun portPriv->AdaptorRec = adaptorPriv;
389*4882a593Smuzhiyun portPriv->DevPriv.ptr = adaptorPtr->pPortPrivates[i].ptr;
390*4882a593Smuzhiyun
391*4882a593Smuzhiyun pp++;
392*4882a593Smuzhiyun numPort++;
393*4882a593Smuzhiyun }
394*4882a593Smuzhiyun pa->nPorts = numPort;
395*4882a593Smuzhiyun pa->pPorts = pPort;
396*4882a593Smuzhiyun if (!numPort) {
397*4882a593Smuzhiyun KdXVFreeAdaptor(pa);
398*4882a593Smuzhiyun continue;
399*4882a593Smuzhiyun }
400*4882a593Smuzhiyun
401*4882a593Smuzhiyun pa->base_id = pPort->id;
402*4882a593Smuzhiyun
403*4882a593Smuzhiyun pa++;
404*4882a593Smuzhiyun numAdaptor++;
405*4882a593Smuzhiyun }
406*4882a593Smuzhiyun
407*4882a593Smuzhiyun if (numAdaptor) {
408*4882a593Smuzhiyun pxvs->nAdaptors = numAdaptor;
409*4882a593Smuzhiyun pxvs->pAdaptors = pAdaptor;
410*4882a593Smuzhiyun }
411*4882a593Smuzhiyun else {
412*4882a593Smuzhiyun free(pAdaptor);
413*4882a593Smuzhiyun return FALSE;
414*4882a593Smuzhiyun }
415*4882a593Smuzhiyun
416*4882a593Smuzhiyun return TRUE;
417*4882a593Smuzhiyun }
418*4882a593Smuzhiyun
419*4882a593Smuzhiyun /* Video should be clipped to the intersection of the window cliplist
420*4882a593Smuzhiyun and the client cliplist specified in the GC for which the video was
421*4882a593Smuzhiyun initialized. When we need to reclip a window, the GC that started
422*4882a593Smuzhiyun the video may not even be around anymore. That's why we save the
423*4882a593Smuzhiyun client clip from the GC when the video is initialized. We then
424*4882a593Smuzhiyun use KdXVUpdateCompositeClip to calculate the new composite clip
425*4882a593Smuzhiyun when we need it. This is different from what DEC did. They saved
426*4882a593Smuzhiyun the GC and used it's clip list when they needed to reclip the window,
427*4882a593Smuzhiyun even if the client clip was different from the one the video was
428*4882a593Smuzhiyun initialized with. If the original GC was destroyed, they had to stop
429*4882a593Smuzhiyun the video. I like the new method better (MArk).
430*4882a593Smuzhiyun
431*4882a593Smuzhiyun This function only works for windows. Will need to rewrite when
432*4882a593Smuzhiyun (if) we support pixmap rendering.
433*4882a593Smuzhiyun */
434*4882a593Smuzhiyun
435*4882a593Smuzhiyun static void
KdXVUpdateCompositeClip(XvPortRecPrivatePtr portPriv)436*4882a593Smuzhiyun KdXVUpdateCompositeClip(XvPortRecPrivatePtr portPriv)
437*4882a593Smuzhiyun {
438*4882a593Smuzhiyun RegionPtr pregWin, pCompositeClip;
439*4882a593Smuzhiyun WindowPtr pWin;
440*4882a593Smuzhiyun Bool freeCompClip = FALSE;
441*4882a593Smuzhiyun
442*4882a593Smuzhiyun if (portPriv->pCompositeClip)
443*4882a593Smuzhiyun return;
444*4882a593Smuzhiyun
445*4882a593Smuzhiyun pWin = (WindowPtr) portPriv->pDraw;
446*4882a593Smuzhiyun
447*4882a593Smuzhiyun /* get window clip list */
448*4882a593Smuzhiyun if (portPriv->subWindowMode == IncludeInferiors) {
449*4882a593Smuzhiyun pregWin = NotClippedByChildren(pWin);
450*4882a593Smuzhiyun freeCompClip = TRUE;
451*4882a593Smuzhiyun }
452*4882a593Smuzhiyun else
453*4882a593Smuzhiyun pregWin = &pWin->clipList;
454*4882a593Smuzhiyun
455*4882a593Smuzhiyun if (!portPriv->clientClip) {
456*4882a593Smuzhiyun portPriv->pCompositeClip = pregWin;
457*4882a593Smuzhiyun portPriv->FreeCompositeClip = freeCompClip;
458*4882a593Smuzhiyun return;
459*4882a593Smuzhiyun }
460*4882a593Smuzhiyun
461*4882a593Smuzhiyun pCompositeClip = RegionCreate(NullBox, 1);
462*4882a593Smuzhiyun RegionCopy(pCompositeClip, portPriv->clientClip);
463*4882a593Smuzhiyun RegionTranslate(pCompositeClip,
464*4882a593Smuzhiyun portPriv->pDraw->x + portPriv->clipOrg.x,
465*4882a593Smuzhiyun portPriv->pDraw->y + portPriv->clipOrg.y);
466*4882a593Smuzhiyun RegionIntersect(pCompositeClip, pregWin, pCompositeClip);
467*4882a593Smuzhiyun
468*4882a593Smuzhiyun portPriv->pCompositeClip = pCompositeClip;
469*4882a593Smuzhiyun portPriv->FreeCompositeClip = TRUE;
470*4882a593Smuzhiyun
471*4882a593Smuzhiyun if (freeCompClip) {
472*4882a593Smuzhiyun RegionDestroy(pregWin);
473*4882a593Smuzhiyun }
474*4882a593Smuzhiyun }
475*4882a593Smuzhiyun
476*4882a593Smuzhiyun /* Save the current clientClip and update the CompositeClip whenever
477*4882a593Smuzhiyun we have a fresh GC */
478*4882a593Smuzhiyun
479*4882a593Smuzhiyun static void
KdXVCopyClip(XvPortRecPrivatePtr portPriv,GCPtr pGC)480*4882a593Smuzhiyun KdXVCopyClip(XvPortRecPrivatePtr portPriv, GCPtr pGC)
481*4882a593Smuzhiyun {
482*4882a593Smuzhiyun /* copy the new clip if it exists */
483*4882a593Smuzhiyun if (pGC->clientClip) {
484*4882a593Smuzhiyun if (!portPriv->clientClip)
485*4882a593Smuzhiyun portPriv->clientClip = RegionCreate(NullBox, 1);
486*4882a593Smuzhiyun /* Note: this is in window coordinates */
487*4882a593Smuzhiyun RegionCopy(portPriv->clientClip, pGC->clientClip);
488*4882a593Smuzhiyun }
489*4882a593Smuzhiyun else if (portPriv->clientClip) { /* free the old clientClip */
490*4882a593Smuzhiyun RegionDestroy(portPriv->clientClip);
491*4882a593Smuzhiyun portPriv->clientClip = NULL;
492*4882a593Smuzhiyun }
493*4882a593Smuzhiyun
494*4882a593Smuzhiyun /* get rid of the old clip list */
495*4882a593Smuzhiyun if (portPriv->pCompositeClip && portPriv->FreeCompositeClip) {
496*4882a593Smuzhiyun RegionDestroy(portPriv->pCompositeClip);
497*4882a593Smuzhiyun }
498*4882a593Smuzhiyun
499*4882a593Smuzhiyun portPriv->clipOrg = pGC->clipOrg;
500*4882a593Smuzhiyun portPriv->pCompositeClip = pGC->pCompositeClip;
501*4882a593Smuzhiyun portPriv->FreeCompositeClip = FALSE;
502*4882a593Smuzhiyun portPriv->subWindowMode = pGC->subWindowMode;
503*4882a593Smuzhiyun }
504*4882a593Smuzhiyun
505*4882a593Smuzhiyun static int
KdXVRegetVideo(XvPortRecPrivatePtr portPriv)506*4882a593Smuzhiyun KdXVRegetVideo(XvPortRecPrivatePtr portPriv)
507*4882a593Smuzhiyun {
508*4882a593Smuzhiyun RegionRec WinRegion;
509*4882a593Smuzhiyun RegionRec ClipRegion;
510*4882a593Smuzhiyun BoxRec WinBox;
511*4882a593Smuzhiyun int ret = Success;
512*4882a593Smuzhiyun Bool clippedAway = FALSE;
513*4882a593Smuzhiyun
514*4882a593Smuzhiyun KdXVUpdateCompositeClip(portPriv);
515*4882a593Smuzhiyun
516*4882a593Smuzhiyun /* translate the video region to the screen */
517*4882a593Smuzhiyun WinBox.x1 = portPriv->pDraw->x + portPriv->drw_x;
518*4882a593Smuzhiyun WinBox.y1 = portPriv->pDraw->y + portPriv->drw_y;
519*4882a593Smuzhiyun WinBox.x2 = WinBox.x1 + portPriv->drw_w;
520*4882a593Smuzhiyun WinBox.y2 = WinBox.y1 + portPriv->drw_h;
521*4882a593Smuzhiyun
522*4882a593Smuzhiyun /* clip to the window composite clip */
523*4882a593Smuzhiyun RegionInit(&WinRegion, &WinBox, 1);
524*4882a593Smuzhiyun RegionInit(&ClipRegion, NullBox, 1);
525*4882a593Smuzhiyun RegionIntersect(&ClipRegion, &WinRegion, portPriv->pCompositeClip);
526*4882a593Smuzhiyun
527*4882a593Smuzhiyun /* that's all if it's totally obscured */
528*4882a593Smuzhiyun if (!RegionNotEmpty(&ClipRegion)) {
529*4882a593Smuzhiyun clippedAway = TRUE;
530*4882a593Smuzhiyun goto CLIP_VIDEO_BAILOUT;
531*4882a593Smuzhiyun }
532*4882a593Smuzhiyun
533*4882a593Smuzhiyun ret = (*portPriv->AdaptorRec->GetVideo) (portPriv->screen, portPriv->pDraw,
534*4882a593Smuzhiyun portPriv->vid_x, portPriv->vid_y,
535*4882a593Smuzhiyun WinBox.x1, WinBox.y1,
536*4882a593Smuzhiyun portPriv->vid_w, portPriv->vid_h,
537*4882a593Smuzhiyun portPriv->drw_w, portPriv->drw_h,
538*4882a593Smuzhiyun &ClipRegion,
539*4882a593Smuzhiyun portPriv->DevPriv.ptr);
540*4882a593Smuzhiyun
541*4882a593Smuzhiyun if (ret == Success)
542*4882a593Smuzhiyun portPriv->isOn = XV_ON;
543*4882a593Smuzhiyun
544*4882a593Smuzhiyun CLIP_VIDEO_BAILOUT:
545*4882a593Smuzhiyun
546*4882a593Smuzhiyun if ((clippedAway || (ret != Success)) && portPriv->isOn == XV_ON) {
547*4882a593Smuzhiyun (*portPriv->AdaptorRec->StopVideo) (portPriv->screen,
548*4882a593Smuzhiyun portPriv->DevPriv.ptr, FALSE);
549*4882a593Smuzhiyun portPriv->isOn = XV_PENDING;
550*4882a593Smuzhiyun }
551*4882a593Smuzhiyun
552*4882a593Smuzhiyun /* This clip was copied and only good for one shot */
553*4882a593Smuzhiyun if (!portPriv->FreeCompositeClip)
554*4882a593Smuzhiyun portPriv->pCompositeClip = NULL;
555*4882a593Smuzhiyun
556*4882a593Smuzhiyun RegionUninit(&WinRegion);
557*4882a593Smuzhiyun RegionUninit(&ClipRegion);
558*4882a593Smuzhiyun
559*4882a593Smuzhiyun return ret;
560*4882a593Smuzhiyun }
561*4882a593Smuzhiyun
562*4882a593Smuzhiyun static int
KdXVReputVideo(XvPortRecPrivatePtr portPriv)563*4882a593Smuzhiyun KdXVReputVideo(XvPortRecPrivatePtr portPriv)
564*4882a593Smuzhiyun {
565*4882a593Smuzhiyun RegionRec WinRegion;
566*4882a593Smuzhiyun RegionRec ClipRegion;
567*4882a593Smuzhiyun BoxRec WinBox;
568*4882a593Smuzhiyun ScreenPtr pScreen = portPriv->pDraw->pScreen;
569*4882a593Smuzhiyun
570*4882a593Smuzhiyun KdScreenPriv(pScreen);
571*4882a593Smuzhiyun KdScreenInfo *screen = pScreenPriv->screen;
572*4882a593Smuzhiyun int ret = Success;
573*4882a593Smuzhiyun Bool clippedAway = FALSE;
574*4882a593Smuzhiyun
575*4882a593Smuzhiyun KdXVUpdateCompositeClip(portPriv);
576*4882a593Smuzhiyun
577*4882a593Smuzhiyun /* translate the video region to the screen */
578*4882a593Smuzhiyun WinBox.x1 = portPriv->pDraw->x + portPriv->drw_x;
579*4882a593Smuzhiyun WinBox.y1 = portPriv->pDraw->y + portPriv->drw_y;
580*4882a593Smuzhiyun WinBox.x2 = WinBox.x1 + portPriv->drw_w;
581*4882a593Smuzhiyun WinBox.y2 = WinBox.y1 + portPriv->drw_h;
582*4882a593Smuzhiyun
583*4882a593Smuzhiyun /* clip to the window composite clip */
584*4882a593Smuzhiyun RegionInit(&WinRegion, &WinBox, 1);
585*4882a593Smuzhiyun RegionInit(&ClipRegion, NullBox, 1);
586*4882a593Smuzhiyun RegionIntersect(&ClipRegion, &WinRegion, portPriv->pCompositeClip);
587*4882a593Smuzhiyun
588*4882a593Smuzhiyun /* clip and translate to the viewport */
589*4882a593Smuzhiyun if (portPriv->AdaptorRec->flags & VIDEO_CLIP_TO_VIEWPORT) {
590*4882a593Smuzhiyun RegionRec VPReg;
591*4882a593Smuzhiyun BoxRec VPBox;
592*4882a593Smuzhiyun
593*4882a593Smuzhiyun VPBox.x1 = 0;
594*4882a593Smuzhiyun VPBox.y1 = 0;
595*4882a593Smuzhiyun VPBox.x2 = screen->width;
596*4882a593Smuzhiyun VPBox.y2 = screen->height;
597*4882a593Smuzhiyun
598*4882a593Smuzhiyun RegionInit(&VPReg, &VPBox, 1);
599*4882a593Smuzhiyun RegionIntersect(&ClipRegion, &ClipRegion, &VPReg);
600*4882a593Smuzhiyun RegionUninit(&VPReg);
601*4882a593Smuzhiyun }
602*4882a593Smuzhiyun
603*4882a593Smuzhiyun /* that's all if it's totally obscured */
604*4882a593Smuzhiyun if (!RegionNotEmpty(&ClipRegion)) {
605*4882a593Smuzhiyun clippedAway = TRUE;
606*4882a593Smuzhiyun goto CLIP_VIDEO_BAILOUT;
607*4882a593Smuzhiyun }
608*4882a593Smuzhiyun
609*4882a593Smuzhiyun ret = (*portPriv->AdaptorRec->PutVideo) (portPriv->screen, portPriv->pDraw,
610*4882a593Smuzhiyun portPriv->vid_x, portPriv->vid_y,
611*4882a593Smuzhiyun WinBox.x1, WinBox.y1,
612*4882a593Smuzhiyun portPriv->vid_w, portPriv->vid_h,
613*4882a593Smuzhiyun portPriv->drw_w, portPriv->drw_h,
614*4882a593Smuzhiyun &ClipRegion,
615*4882a593Smuzhiyun portPriv->DevPriv.ptr);
616*4882a593Smuzhiyun
617*4882a593Smuzhiyun if (ret == Success)
618*4882a593Smuzhiyun portPriv->isOn = XV_ON;
619*4882a593Smuzhiyun
620*4882a593Smuzhiyun CLIP_VIDEO_BAILOUT:
621*4882a593Smuzhiyun
622*4882a593Smuzhiyun if ((clippedAway || (ret != Success)) && (portPriv->isOn == XV_ON)) {
623*4882a593Smuzhiyun (*portPriv->AdaptorRec->StopVideo) (portPriv->screen,
624*4882a593Smuzhiyun portPriv->DevPriv.ptr, FALSE);
625*4882a593Smuzhiyun portPriv->isOn = XV_PENDING;
626*4882a593Smuzhiyun }
627*4882a593Smuzhiyun
628*4882a593Smuzhiyun /* This clip was copied and only good for one shot */
629*4882a593Smuzhiyun if (!portPriv->FreeCompositeClip)
630*4882a593Smuzhiyun portPriv->pCompositeClip = NULL;
631*4882a593Smuzhiyun
632*4882a593Smuzhiyun RegionUninit(&WinRegion);
633*4882a593Smuzhiyun RegionUninit(&ClipRegion);
634*4882a593Smuzhiyun
635*4882a593Smuzhiyun return ret;
636*4882a593Smuzhiyun }
637*4882a593Smuzhiyun
638*4882a593Smuzhiyun static int
KdXVReputImage(XvPortRecPrivatePtr portPriv)639*4882a593Smuzhiyun KdXVReputImage(XvPortRecPrivatePtr portPriv)
640*4882a593Smuzhiyun {
641*4882a593Smuzhiyun RegionRec WinRegion;
642*4882a593Smuzhiyun RegionRec ClipRegion;
643*4882a593Smuzhiyun BoxRec WinBox;
644*4882a593Smuzhiyun ScreenPtr pScreen = portPriv->pDraw->pScreen;
645*4882a593Smuzhiyun
646*4882a593Smuzhiyun KdScreenPriv(pScreen);
647*4882a593Smuzhiyun KdScreenInfo *screen = pScreenPriv->screen;
648*4882a593Smuzhiyun int ret = Success;
649*4882a593Smuzhiyun Bool clippedAway = FALSE;
650*4882a593Smuzhiyun
651*4882a593Smuzhiyun KdXVUpdateCompositeClip(portPriv);
652*4882a593Smuzhiyun
653*4882a593Smuzhiyun /* translate the video region to the screen */
654*4882a593Smuzhiyun WinBox.x1 = portPriv->pDraw->x + portPriv->drw_x;
655*4882a593Smuzhiyun WinBox.y1 = portPriv->pDraw->y + portPriv->drw_y;
656*4882a593Smuzhiyun WinBox.x2 = WinBox.x1 + portPriv->drw_w;
657*4882a593Smuzhiyun WinBox.y2 = WinBox.y1 + portPriv->drw_h;
658*4882a593Smuzhiyun
659*4882a593Smuzhiyun /* clip to the window composite clip */
660*4882a593Smuzhiyun RegionInit(&WinRegion, &WinBox, 1);
661*4882a593Smuzhiyun RegionInit(&ClipRegion, NullBox, 1);
662*4882a593Smuzhiyun RegionIntersect(&ClipRegion, &WinRegion, portPriv->pCompositeClip);
663*4882a593Smuzhiyun
664*4882a593Smuzhiyun /* clip and translate to the viewport */
665*4882a593Smuzhiyun if (portPriv->AdaptorRec->flags & VIDEO_CLIP_TO_VIEWPORT) {
666*4882a593Smuzhiyun RegionRec VPReg;
667*4882a593Smuzhiyun BoxRec VPBox;
668*4882a593Smuzhiyun
669*4882a593Smuzhiyun VPBox.x1 = 0;
670*4882a593Smuzhiyun VPBox.y1 = 0;
671*4882a593Smuzhiyun VPBox.x2 = screen->width;
672*4882a593Smuzhiyun VPBox.y2 = screen->height;
673*4882a593Smuzhiyun
674*4882a593Smuzhiyun RegionInit(&VPReg, &VPBox, 1);
675*4882a593Smuzhiyun RegionIntersect(&ClipRegion, &ClipRegion, &VPReg);
676*4882a593Smuzhiyun RegionUninit(&VPReg);
677*4882a593Smuzhiyun }
678*4882a593Smuzhiyun
679*4882a593Smuzhiyun /* that's all if it's totally obscured */
680*4882a593Smuzhiyun if (!RegionNotEmpty(&ClipRegion)) {
681*4882a593Smuzhiyun clippedAway = TRUE;
682*4882a593Smuzhiyun goto CLIP_VIDEO_BAILOUT;
683*4882a593Smuzhiyun }
684*4882a593Smuzhiyun
685*4882a593Smuzhiyun ret =
686*4882a593Smuzhiyun (*portPriv->AdaptorRec->ReputImage) (portPriv->screen, portPriv->pDraw,
687*4882a593Smuzhiyun WinBox.x1, WinBox.y1, &ClipRegion,
688*4882a593Smuzhiyun portPriv->DevPriv.ptr);
689*4882a593Smuzhiyun
690*4882a593Smuzhiyun portPriv->isOn = (ret == Success) ? XV_ON : XV_OFF;
691*4882a593Smuzhiyun
692*4882a593Smuzhiyun CLIP_VIDEO_BAILOUT:
693*4882a593Smuzhiyun
694*4882a593Smuzhiyun if ((clippedAway || (ret != Success)) && (portPriv->isOn == XV_ON)) {
695*4882a593Smuzhiyun (*portPriv->AdaptorRec->StopVideo) (portPriv->screen,
696*4882a593Smuzhiyun portPriv->DevPriv.ptr, FALSE);
697*4882a593Smuzhiyun portPriv->isOn = XV_PENDING;
698*4882a593Smuzhiyun }
699*4882a593Smuzhiyun
700*4882a593Smuzhiyun /* This clip was copied and only good for one shot */
701*4882a593Smuzhiyun if (!portPriv->FreeCompositeClip)
702*4882a593Smuzhiyun portPriv->pCompositeClip = NULL;
703*4882a593Smuzhiyun
704*4882a593Smuzhiyun RegionUninit(&WinRegion);
705*4882a593Smuzhiyun RegionUninit(&ClipRegion);
706*4882a593Smuzhiyun
707*4882a593Smuzhiyun return ret;
708*4882a593Smuzhiyun }
709*4882a593Smuzhiyun
710*4882a593Smuzhiyun static int
KdXVEnlistPortInWindow(WindowPtr pWin,XvPortRecPrivatePtr portPriv)711*4882a593Smuzhiyun KdXVEnlistPortInWindow(WindowPtr pWin, XvPortRecPrivatePtr portPriv)
712*4882a593Smuzhiyun {
713*4882a593Smuzhiyun KdXVWindowPtr winPriv, PrivRoot;
714*4882a593Smuzhiyun
715*4882a593Smuzhiyun winPriv = PrivRoot = GET_KDXV_WINDOW(pWin);
716*4882a593Smuzhiyun
717*4882a593Smuzhiyun /* Enlist our port in the window private */
718*4882a593Smuzhiyun while (winPriv) {
719*4882a593Smuzhiyun if (winPriv->PortRec == portPriv) /* we're already listed */
720*4882a593Smuzhiyun break;
721*4882a593Smuzhiyun winPriv = winPriv->next;
722*4882a593Smuzhiyun }
723*4882a593Smuzhiyun
724*4882a593Smuzhiyun if (!winPriv) {
725*4882a593Smuzhiyun winPriv = malloc(sizeof(KdXVWindowRec));
726*4882a593Smuzhiyun if (!winPriv)
727*4882a593Smuzhiyun return BadAlloc;
728*4882a593Smuzhiyun winPriv->PortRec = portPriv;
729*4882a593Smuzhiyun winPriv->next = PrivRoot;
730*4882a593Smuzhiyun dixSetPrivate(&pWin->devPrivates, KdXVWindowKey, winPriv);
731*4882a593Smuzhiyun }
732*4882a593Smuzhiyun return Success;
733*4882a593Smuzhiyun }
734*4882a593Smuzhiyun
735*4882a593Smuzhiyun static void
KdXVRemovePortFromWindow(WindowPtr pWin,XvPortRecPrivatePtr portPriv)736*4882a593Smuzhiyun KdXVRemovePortFromWindow(WindowPtr pWin, XvPortRecPrivatePtr portPriv)
737*4882a593Smuzhiyun {
738*4882a593Smuzhiyun KdXVWindowPtr winPriv, prevPriv = NULL;
739*4882a593Smuzhiyun
740*4882a593Smuzhiyun winPriv = GET_KDXV_WINDOW(pWin);
741*4882a593Smuzhiyun
742*4882a593Smuzhiyun while (winPriv) {
743*4882a593Smuzhiyun if (winPriv->PortRec == portPriv) {
744*4882a593Smuzhiyun if (prevPriv)
745*4882a593Smuzhiyun prevPriv->next = winPriv->next;
746*4882a593Smuzhiyun else
747*4882a593Smuzhiyun dixSetPrivate(&pWin->devPrivates, KdXVWindowKey, winPriv->next);
748*4882a593Smuzhiyun free(winPriv);
749*4882a593Smuzhiyun break;
750*4882a593Smuzhiyun }
751*4882a593Smuzhiyun prevPriv = winPriv;
752*4882a593Smuzhiyun winPriv = winPriv->next;
753*4882a593Smuzhiyun }
754*4882a593Smuzhiyun portPriv->pDraw = NULL;
755*4882a593Smuzhiyun }
756*4882a593Smuzhiyun
757*4882a593Smuzhiyun /**** ScreenRec fields ****/
758*4882a593Smuzhiyun
759*4882a593Smuzhiyun static Bool
KdXVDestroyWindow(WindowPtr pWin)760*4882a593Smuzhiyun KdXVDestroyWindow(WindowPtr pWin)
761*4882a593Smuzhiyun {
762*4882a593Smuzhiyun ScreenPtr pScreen = pWin->drawable.pScreen;
763*4882a593Smuzhiyun KdXVScreenPtr ScreenPriv = GET_KDXV_SCREEN(pScreen);
764*4882a593Smuzhiyun KdXVWindowPtr tmp, WinPriv = GET_KDXV_WINDOW(pWin);
765*4882a593Smuzhiyun int ret;
766*4882a593Smuzhiyun
767*4882a593Smuzhiyun while (WinPriv) {
768*4882a593Smuzhiyun XvPortRecPrivatePtr pPriv = WinPriv->PortRec;
769*4882a593Smuzhiyun
770*4882a593Smuzhiyun if (pPriv->isOn > XV_OFF) {
771*4882a593Smuzhiyun (*pPriv->AdaptorRec->StopVideo) (pPriv->screen, pPriv->DevPriv.ptr,
772*4882a593Smuzhiyun TRUE);
773*4882a593Smuzhiyun pPriv->isOn = XV_OFF;
774*4882a593Smuzhiyun }
775*4882a593Smuzhiyun
776*4882a593Smuzhiyun pPriv->pDraw = NULL;
777*4882a593Smuzhiyun tmp = WinPriv;
778*4882a593Smuzhiyun WinPriv = WinPriv->next;
779*4882a593Smuzhiyun free(tmp);
780*4882a593Smuzhiyun }
781*4882a593Smuzhiyun
782*4882a593Smuzhiyun dixSetPrivate(&pWin->devPrivates, KdXVWindowKey, NULL);
783*4882a593Smuzhiyun
784*4882a593Smuzhiyun pScreen->DestroyWindow = ScreenPriv->DestroyWindow;
785*4882a593Smuzhiyun ret = (*pScreen->DestroyWindow) (pWin);
786*4882a593Smuzhiyun pScreen->DestroyWindow = KdXVDestroyWindow;
787*4882a593Smuzhiyun
788*4882a593Smuzhiyun return ret;
789*4882a593Smuzhiyun }
790*4882a593Smuzhiyun
791*4882a593Smuzhiyun static void
KdXVWindowExposures(WindowPtr pWin,RegionPtr reg1)792*4882a593Smuzhiyun KdXVWindowExposures(WindowPtr pWin, RegionPtr reg1)
793*4882a593Smuzhiyun {
794*4882a593Smuzhiyun ScreenPtr pScreen = pWin->drawable.pScreen;
795*4882a593Smuzhiyun KdXVScreenPtr ScreenPriv = GET_KDXV_SCREEN(pScreen);
796*4882a593Smuzhiyun KdXVWindowPtr WinPriv = GET_KDXV_WINDOW(pWin);
797*4882a593Smuzhiyun KdXVWindowPtr pPrev;
798*4882a593Smuzhiyun XvPortRecPrivatePtr pPriv;
799*4882a593Smuzhiyun Bool AreasExposed;
800*4882a593Smuzhiyun
801*4882a593Smuzhiyun AreasExposed = (WinPriv && reg1 && RegionNotEmpty(reg1));
802*4882a593Smuzhiyun
803*4882a593Smuzhiyun pScreen->WindowExposures = ScreenPriv->WindowExposures;
804*4882a593Smuzhiyun (*pScreen->WindowExposures) (pWin, reg1);
805*4882a593Smuzhiyun pScreen->WindowExposures = KdXVWindowExposures;
806*4882a593Smuzhiyun
807*4882a593Smuzhiyun /* filter out XClearWindow/Area */
808*4882a593Smuzhiyun if (!pWin->valdata)
809*4882a593Smuzhiyun return;
810*4882a593Smuzhiyun
811*4882a593Smuzhiyun pPrev = NULL;
812*4882a593Smuzhiyun
813*4882a593Smuzhiyun while (WinPriv) {
814*4882a593Smuzhiyun pPriv = WinPriv->PortRec;
815*4882a593Smuzhiyun
816*4882a593Smuzhiyun /* Reput anyone with a reput function */
817*4882a593Smuzhiyun
818*4882a593Smuzhiyun switch (pPriv->type) {
819*4882a593Smuzhiyun case XvInputMask:
820*4882a593Smuzhiyun KdXVReputVideo(pPriv);
821*4882a593Smuzhiyun break;
822*4882a593Smuzhiyun case XvOutputMask:
823*4882a593Smuzhiyun KdXVRegetVideo(pPriv);
824*4882a593Smuzhiyun break;
825*4882a593Smuzhiyun default: /* overlaid still/image */
826*4882a593Smuzhiyun if (pPriv->AdaptorRec->ReputImage)
827*4882a593Smuzhiyun KdXVReputImage(pPriv);
828*4882a593Smuzhiyun else if (AreasExposed) {
829*4882a593Smuzhiyun KdXVWindowPtr tmp;
830*4882a593Smuzhiyun
831*4882a593Smuzhiyun if (pPriv->isOn == XV_ON) {
832*4882a593Smuzhiyun (*pPriv->AdaptorRec->StopVideo) (pPriv->screen,
833*4882a593Smuzhiyun pPriv->DevPriv.ptr, FALSE);
834*4882a593Smuzhiyun pPriv->isOn = XV_PENDING;
835*4882a593Smuzhiyun }
836*4882a593Smuzhiyun pPriv->pDraw = NULL;
837*4882a593Smuzhiyun
838*4882a593Smuzhiyun if (!pPrev)
839*4882a593Smuzhiyun dixSetPrivate(&pWin->devPrivates, KdXVWindowKey,
840*4882a593Smuzhiyun WinPriv->next);
841*4882a593Smuzhiyun else
842*4882a593Smuzhiyun pPrev->next = WinPriv->next;
843*4882a593Smuzhiyun tmp = WinPriv;
844*4882a593Smuzhiyun WinPriv = WinPriv->next;
845*4882a593Smuzhiyun free(tmp);
846*4882a593Smuzhiyun continue;
847*4882a593Smuzhiyun }
848*4882a593Smuzhiyun break;
849*4882a593Smuzhiyun }
850*4882a593Smuzhiyun pPrev = WinPriv;
851*4882a593Smuzhiyun WinPriv = WinPriv->next;
852*4882a593Smuzhiyun }
853*4882a593Smuzhiyun }
854*4882a593Smuzhiyun
855*4882a593Smuzhiyun static void
KdXVClipNotify(WindowPtr pWin,int dx,int dy)856*4882a593Smuzhiyun KdXVClipNotify(WindowPtr pWin, int dx, int dy)
857*4882a593Smuzhiyun {
858*4882a593Smuzhiyun ScreenPtr pScreen = pWin->drawable.pScreen;
859*4882a593Smuzhiyun KdXVScreenPtr ScreenPriv = GET_KDXV_SCREEN(pScreen);
860*4882a593Smuzhiyun KdXVWindowPtr WinPriv = GET_KDXV_WINDOW(pWin);
861*4882a593Smuzhiyun KdXVWindowPtr tmp, pPrev = NULL;
862*4882a593Smuzhiyun XvPortRecPrivatePtr pPriv;
863*4882a593Smuzhiyun Bool visible = (pWin->visibility == VisibilityUnobscured) ||
864*4882a593Smuzhiyun (pWin->visibility == VisibilityPartiallyObscured);
865*4882a593Smuzhiyun
866*4882a593Smuzhiyun while (WinPriv) {
867*4882a593Smuzhiyun pPriv = WinPriv->PortRec;
868*4882a593Smuzhiyun
869*4882a593Smuzhiyun if (pPriv->pCompositeClip && pPriv->FreeCompositeClip)
870*4882a593Smuzhiyun RegionDestroy(pPriv->pCompositeClip);
871*4882a593Smuzhiyun
872*4882a593Smuzhiyun pPriv->pCompositeClip = NULL;
873*4882a593Smuzhiyun
874*4882a593Smuzhiyun /* Stop everything except images, but stop them too if the
875*4882a593Smuzhiyun window isn't visible. But we only remove the images. */
876*4882a593Smuzhiyun
877*4882a593Smuzhiyun if (pPriv->type || !visible) {
878*4882a593Smuzhiyun if (pPriv->isOn == XV_ON) {
879*4882a593Smuzhiyun (*pPriv->AdaptorRec->StopVideo) (pPriv->screen,
880*4882a593Smuzhiyun pPriv->DevPriv.ptr, FALSE);
881*4882a593Smuzhiyun pPriv->isOn = XV_PENDING;
882*4882a593Smuzhiyun }
883*4882a593Smuzhiyun
884*4882a593Smuzhiyun if (!pPriv->type) { /* overlaid still/image */
885*4882a593Smuzhiyun pPriv->pDraw = NULL;
886*4882a593Smuzhiyun
887*4882a593Smuzhiyun if (!pPrev)
888*4882a593Smuzhiyun dixSetPrivate(&pWin->devPrivates, KdXVWindowKey,
889*4882a593Smuzhiyun WinPriv->next);
890*4882a593Smuzhiyun else
891*4882a593Smuzhiyun pPrev->next = WinPriv->next;
892*4882a593Smuzhiyun tmp = WinPriv;
893*4882a593Smuzhiyun WinPriv = WinPriv->next;
894*4882a593Smuzhiyun free(tmp);
895*4882a593Smuzhiyun continue;
896*4882a593Smuzhiyun }
897*4882a593Smuzhiyun }
898*4882a593Smuzhiyun
899*4882a593Smuzhiyun pPrev = WinPriv;
900*4882a593Smuzhiyun WinPriv = WinPriv->next;
901*4882a593Smuzhiyun }
902*4882a593Smuzhiyun
903*4882a593Smuzhiyun if (ScreenPriv->ClipNotify) {
904*4882a593Smuzhiyun pScreen->ClipNotify = ScreenPriv->ClipNotify;
905*4882a593Smuzhiyun (*pScreen->ClipNotify) (pWin, dx, dy);
906*4882a593Smuzhiyun pScreen->ClipNotify = KdXVClipNotify;
907*4882a593Smuzhiyun }
908*4882a593Smuzhiyun }
909*4882a593Smuzhiyun
910*4882a593Smuzhiyun /**** Required XvScreenRec fields ****/
911*4882a593Smuzhiyun
912*4882a593Smuzhiyun static Bool
KdXVCloseScreen(ScreenPtr pScreen)913*4882a593Smuzhiyun KdXVCloseScreen(ScreenPtr pScreen)
914*4882a593Smuzhiyun {
915*4882a593Smuzhiyun XvScreenPtr pxvs = GET_XV_SCREEN(pScreen);
916*4882a593Smuzhiyun KdXVScreenPtr ScreenPriv = GET_KDXV_SCREEN(pScreen);
917*4882a593Smuzhiyun XvAdaptorPtr pa;
918*4882a593Smuzhiyun int c;
919*4882a593Smuzhiyun
920*4882a593Smuzhiyun if (!ScreenPriv)
921*4882a593Smuzhiyun return TRUE;
922*4882a593Smuzhiyun
923*4882a593Smuzhiyun pScreen->DestroyWindow = ScreenPriv->DestroyWindow;
924*4882a593Smuzhiyun pScreen->WindowExposures = ScreenPriv->WindowExposures;
925*4882a593Smuzhiyun pScreen->ClipNotify = ScreenPriv->ClipNotify;
926*4882a593Smuzhiyun pScreen->CloseScreen = ScreenPriv->CloseScreen;
927*4882a593Smuzhiyun
928*4882a593Smuzhiyun /* fprintf(stderr,"XV: Unwrapping screen funcs\n"); */
929*4882a593Smuzhiyun
930*4882a593Smuzhiyun for (c = 0, pa = pxvs->pAdaptors; c < pxvs->nAdaptors; c++, pa++) {
931*4882a593Smuzhiyun KdXVFreeAdaptor(pa);
932*4882a593Smuzhiyun }
933*4882a593Smuzhiyun
934*4882a593Smuzhiyun free(pxvs->pAdaptors);
935*4882a593Smuzhiyun free(ScreenPriv);
936*4882a593Smuzhiyun
937*4882a593Smuzhiyun return pScreen->CloseScreen(pScreen);
938*4882a593Smuzhiyun }
939*4882a593Smuzhiyun
940*4882a593Smuzhiyun /**** XvAdaptorRec fields ****/
941*4882a593Smuzhiyun
942*4882a593Smuzhiyun static int
KdXVPutVideo(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)943*4882a593Smuzhiyun KdXVPutVideo(DrawablePtr pDraw,
944*4882a593Smuzhiyun XvPortPtr pPort,
945*4882a593Smuzhiyun GCPtr pGC,
946*4882a593Smuzhiyun INT16 vid_x, INT16 vid_y,
947*4882a593Smuzhiyun CARD16 vid_w, CARD16 vid_h,
948*4882a593Smuzhiyun INT16 drw_x, INT16 drw_y, CARD16 drw_w, CARD16 drw_h)
949*4882a593Smuzhiyun {
950*4882a593Smuzhiyun XvPortRecPrivatePtr portPriv = (XvPortRecPrivatePtr) (pPort->devPriv.ptr);
951*4882a593Smuzhiyun
952*4882a593Smuzhiyun KdScreenPriv(portPriv->screen->pScreen);
953*4882a593Smuzhiyun int result;
954*4882a593Smuzhiyun
955*4882a593Smuzhiyun /* No dumping video to pixmaps... For now anyhow */
956*4882a593Smuzhiyun if (pDraw->type != DRAWABLE_WINDOW) {
957*4882a593Smuzhiyun pPort->pDraw = (DrawablePtr) NULL;
958*4882a593Smuzhiyun return BadAlloc;
959*4882a593Smuzhiyun }
960*4882a593Smuzhiyun
961*4882a593Smuzhiyun /* If we are changing windows, unregister our port in the old window */
962*4882a593Smuzhiyun if (portPriv->pDraw && (portPriv->pDraw != pDraw))
963*4882a593Smuzhiyun KdXVRemovePortFromWindow((WindowPtr) (portPriv->pDraw), portPriv);
964*4882a593Smuzhiyun
965*4882a593Smuzhiyun /* Register our port with the new window */
966*4882a593Smuzhiyun result = KdXVEnlistPortInWindow((WindowPtr) pDraw, portPriv);
967*4882a593Smuzhiyun if (result != Success)
968*4882a593Smuzhiyun return result;
969*4882a593Smuzhiyun
970*4882a593Smuzhiyun portPriv->pDraw = pDraw;
971*4882a593Smuzhiyun portPriv->type = XvInputMask;
972*4882a593Smuzhiyun
973*4882a593Smuzhiyun /* save a copy of these parameters */
974*4882a593Smuzhiyun portPriv->vid_x = vid_x;
975*4882a593Smuzhiyun portPriv->vid_y = vid_y;
976*4882a593Smuzhiyun portPriv->vid_w = vid_w;
977*4882a593Smuzhiyun portPriv->vid_h = vid_h;
978*4882a593Smuzhiyun portPriv->drw_x = drw_x;
979*4882a593Smuzhiyun portPriv->drw_y = drw_y;
980*4882a593Smuzhiyun portPriv->drw_w = drw_w;
981*4882a593Smuzhiyun portPriv->drw_h = drw_h;
982*4882a593Smuzhiyun
983*4882a593Smuzhiyun /* make sure we have the most recent copy of the clientClip */
984*4882a593Smuzhiyun KdXVCopyClip(portPriv, pGC);
985*4882a593Smuzhiyun
986*4882a593Smuzhiyun /* To indicate to the DI layer that we were successful */
987*4882a593Smuzhiyun pPort->pDraw = pDraw;
988*4882a593Smuzhiyun
989*4882a593Smuzhiyun if (!pScreenPriv->enabled)
990*4882a593Smuzhiyun return Success;
991*4882a593Smuzhiyun
992*4882a593Smuzhiyun return (KdXVReputVideo(portPriv));
993*4882a593Smuzhiyun }
994*4882a593Smuzhiyun
995*4882a593Smuzhiyun static int
KdXVPutStill(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)996*4882a593Smuzhiyun KdXVPutStill(DrawablePtr pDraw,
997*4882a593Smuzhiyun XvPortPtr pPort,
998*4882a593Smuzhiyun GCPtr pGC,
999*4882a593Smuzhiyun INT16 vid_x, INT16 vid_y,
1000*4882a593Smuzhiyun CARD16 vid_w, CARD16 vid_h,
1001*4882a593Smuzhiyun INT16 drw_x, INT16 drw_y, CARD16 drw_w, CARD16 drw_h)
1002*4882a593Smuzhiyun {
1003*4882a593Smuzhiyun XvPortRecPrivatePtr portPriv = (XvPortRecPrivatePtr) (pPort->devPriv.ptr);
1004*4882a593Smuzhiyun ScreenPtr pScreen = pDraw->pScreen;
1005*4882a593Smuzhiyun
1006*4882a593Smuzhiyun KdScreenPriv(pScreen);
1007*4882a593Smuzhiyun KdScreenInfo *screen = pScreenPriv->screen;
1008*4882a593Smuzhiyun RegionRec WinRegion;
1009*4882a593Smuzhiyun RegionRec ClipRegion;
1010*4882a593Smuzhiyun BoxRec WinBox;
1011*4882a593Smuzhiyun int ret = Success;
1012*4882a593Smuzhiyun Bool clippedAway = FALSE;
1013*4882a593Smuzhiyun
1014*4882a593Smuzhiyun if (pDraw->type != DRAWABLE_WINDOW)
1015*4882a593Smuzhiyun return BadAlloc;
1016*4882a593Smuzhiyun
1017*4882a593Smuzhiyun if (!pScreenPriv->enabled)
1018*4882a593Smuzhiyun return Success;
1019*4882a593Smuzhiyun
1020*4882a593Smuzhiyun WinBox.x1 = pDraw->x + drw_x;
1021*4882a593Smuzhiyun WinBox.y1 = pDraw->y + drw_y;
1022*4882a593Smuzhiyun WinBox.x2 = WinBox.x1 + drw_w;
1023*4882a593Smuzhiyun WinBox.y2 = WinBox.y1 + drw_h;
1024*4882a593Smuzhiyun
1025*4882a593Smuzhiyun RegionInit(&WinRegion, &WinBox, 1);
1026*4882a593Smuzhiyun RegionInit(&ClipRegion, NullBox, 1);
1027*4882a593Smuzhiyun RegionIntersect(&ClipRegion, &WinRegion, pGC->pCompositeClip);
1028*4882a593Smuzhiyun
1029*4882a593Smuzhiyun if (portPriv->AdaptorRec->flags & VIDEO_CLIP_TO_VIEWPORT) {
1030*4882a593Smuzhiyun RegionRec VPReg;
1031*4882a593Smuzhiyun BoxRec VPBox;
1032*4882a593Smuzhiyun
1033*4882a593Smuzhiyun VPBox.x1 = 0;
1034*4882a593Smuzhiyun VPBox.y1 = 0;
1035*4882a593Smuzhiyun VPBox.x2 = screen->width;
1036*4882a593Smuzhiyun VPBox.y2 = screen->height;
1037*4882a593Smuzhiyun
1038*4882a593Smuzhiyun RegionInit(&VPReg, &VPBox, 1);
1039*4882a593Smuzhiyun RegionIntersect(&ClipRegion, &ClipRegion, &VPReg);
1040*4882a593Smuzhiyun RegionUninit(&VPReg);
1041*4882a593Smuzhiyun }
1042*4882a593Smuzhiyun
1043*4882a593Smuzhiyun if (portPriv->pDraw) {
1044*4882a593Smuzhiyun KdXVRemovePortFromWindow((WindowPtr) (portPriv->pDraw), portPriv);
1045*4882a593Smuzhiyun }
1046*4882a593Smuzhiyun
1047*4882a593Smuzhiyun if (!RegionNotEmpty(&ClipRegion)) {
1048*4882a593Smuzhiyun clippedAway = TRUE;
1049*4882a593Smuzhiyun goto PUT_STILL_BAILOUT;
1050*4882a593Smuzhiyun }
1051*4882a593Smuzhiyun
1052*4882a593Smuzhiyun ret = (*portPriv->AdaptorRec->PutStill) (portPriv->screen, pDraw,
1053*4882a593Smuzhiyun vid_x, vid_y, WinBox.x1, WinBox.y1,
1054*4882a593Smuzhiyun vid_w, vid_h, drw_w, drw_h,
1055*4882a593Smuzhiyun &ClipRegion,
1056*4882a593Smuzhiyun portPriv->DevPriv.ptr);
1057*4882a593Smuzhiyun
1058*4882a593Smuzhiyun if ((ret == Success) &&
1059*4882a593Smuzhiyun (portPriv->AdaptorRec->flags & VIDEO_OVERLAID_STILLS)) {
1060*4882a593Smuzhiyun
1061*4882a593Smuzhiyun KdXVEnlistPortInWindow((WindowPtr) pDraw, portPriv);
1062*4882a593Smuzhiyun portPriv->isOn = XV_ON;
1063*4882a593Smuzhiyun portPriv->pDraw = pDraw;
1064*4882a593Smuzhiyun portPriv->drw_x = drw_x;
1065*4882a593Smuzhiyun portPriv->drw_y = drw_y;
1066*4882a593Smuzhiyun portPriv->drw_w = drw_w;
1067*4882a593Smuzhiyun portPriv->drw_h = drw_h;
1068*4882a593Smuzhiyun portPriv->type = 0; /* no mask means it's transient and should
1069*4882a593Smuzhiyun not be reput once it's removed */
1070*4882a593Smuzhiyun pPort->pDraw = pDraw; /* make sure we can get stop requests */
1071*4882a593Smuzhiyun }
1072*4882a593Smuzhiyun
1073*4882a593Smuzhiyun PUT_STILL_BAILOUT:
1074*4882a593Smuzhiyun
1075*4882a593Smuzhiyun if ((clippedAway || (ret != Success)) && (portPriv->isOn == XV_ON)) {
1076*4882a593Smuzhiyun (*portPriv->AdaptorRec->StopVideo) (portPriv->screen,
1077*4882a593Smuzhiyun portPriv->DevPriv.ptr, FALSE);
1078*4882a593Smuzhiyun portPriv->isOn = XV_PENDING;
1079*4882a593Smuzhiyun }
1080*4882a593Smuzhiyun
1081*4882a593Smuzhiyun RegionUninit(&WinRegion);
1082*4882a593Smuzhiyun RegionUninit(&ClipRegion);
1083*4882a593Smuzhiyun
1084*4882a593Smuzhiyun return ret;
1085*4882a593Smuzhiyun }
1086*4882a593Smuzhiyun
1087*4882a593Smuzhiyun static int
KdXVGetVideo(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)1088*4882a593Smuzhiyun KdXVGetVideo(DrawablePtr pDraw,
1089*4882a593Smuzhiyun XvPortPtr pPort,
1090*4882a593Smuzhiyun GCPtr pGC,
1091*4882a593Smuzhiyun INT16 vid_x, INT16 vid_y,
1092*4882a593Smuzhiyun CARD16 vid_w, CARD16 vid_h,
1093*4882a593Smuzhiyun INT16 drw_x, INT16 drw_y, CARD16 drw_w, CARD16 drw_h)
1094*4882a593Smuzhiyun {
1095*4882a593Smuzhiyun XvPortRecPrivatePtr portPriv = (XvPortRecPrivatePtr) (pPort->devPriv.ptr);
1096*4882a593Smuzhiyun int result;
1097*4882a593Smuzhiyun
1098*4882a593Smuzhiyun KdScreenPriv(portPriv->screen->pScreen);
1099*4882a593Smuzhiyun
1100*4882a593Smuzhiyun /* No pixmaps... For now anyhow */
1101*4882a593Smuzhiyun if (pDraw->type != DRAWABLE_WINDOW) {
1102*4882a593Smuzhiyun pPort->pDraw = (DrawablePtr) NULL;
1103*4882a593Smuzhiyun return BadAlloc;
1104*4882a593Smuzhiyun }
1105*4882a593Smuzhiyun
1106*4882a593Smuzhiyun /* If we are changing windows, unregister our port in the old window */
1107*4882a593Smuzhiyun if (portPriv->pDraw && (portPriv->pDraw != pDraw))
1108*4882a593Smuzhiyun KdXVRemovePortFromWindow((WindowPtr) (portPriv->pDraw), portPriv);
1109*4882a593Smuzhiyun
1110*4882a593Smuzhiyun /* Register our port with the new window */
1111*4882a593Smuzhiyun result = KdXVEnlistPortInWindow((WindowPtr) pDraw, portPriv);
1112*4882a593Smuzhiyun if (result != Success)
1113*4882a593Smuzhiyun return result;
1114*4882a593Smuzhiyun
1115*4882a593Smuzhiyun portPriv->pDraw = pDraw;
1116*4882a593Smuzhiyun portPriv->type = XvOutputMask;
1117*4882a593Smuzhiyun
1118*4882a593Smuzhiyun /* save a copy of these parameters */
1119*4882a593Smuzhiyun portPriv->vid_x = vid_x;
1120*4882a593Smuzhiyun portPriv->vid_y = vid_y;
1121*4882a593Smuzhiyun portPriv->vid_w = vid_w;
1122*4882a593Smuzhiyun portPriv->vid_h = vid_h;
1123*4882a593Smuzhiyun portPriv->drw_x = drw_x;
1124*4882a593Smuzhiyun portPriv->drw_y = drw_y;
1125*4882a593Smuzhiyun portPriv->drw_w = drw_w;
1126*4882a593Smuzhiyun portPriv->drw_h = drw_h;
1127*4882a593Smuzhiyun
1128*4882a593Smuzhiyun /* make sure we have the most recent copy of the clientClip */
1129*4882a593Smuzhiyun KdXVCopyClip(portPriv, pGC);
1130*4882a593Smuzhiyun
1131*4882a593Smuzhiyun /* To indicate to the DI layer that we were successful */
1132*4882a593Smuzhiyun pPort->pDraw = pDraw;
1133*4882a593Smuzhiyun
1134*4882a593Smuzhiyun if (!pScreenPriv->enabled)
1135*4882a593Smuzhiyun return Success;
1136*4882a593Smuzhiyun
1137*4882a593Smuzhiyun return (KdXVRegetVideo(portPriv));
1138*4882a593Smuzhiyun }
1139*4882a593Smuzhiyun
1140*4882a593Smuzhiyun static int
KdXVGetStill(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)1141*4882a593Smuzhiyun KdXVGetStill(DrawablePtr pDraw,
1142*4882a593Smuzhiyun XvPortPtr pPort,
1143*4882a593Smuzhiyun GCPtr pGC,
1144*4882a593Smuzhiyun INT16 vid_x, INT16 vid_y,
1145*4882a593Smuzhiyun CARD16 vid_w, CARD16 vid_h,
1146*4882a593Smuzhiyun INT16 drw_x, INT16 drw_y, CARD16 drw_w, CARD16 drw_h)
1147*4882a593Smuzhiyun {
1148*4882a593Smuzhiyun XvPortRecPrivatePtr portPriv = (XvPortRecPrivatePtr) (pPort->devPriv.ptr);
1149*4882a593Smuzhiyun ScreenPtr pScreen = pDraw->pScreen;
1150*4882a593Smuzhiyun
1151*4882a593Smuzhiyun KdScreenPriv(pScreen);
1152*4882a593Smuzhiyun RegionRec WinRegion;
1153*4882a593Smuzhiyun RegionRec ClipRegion;
1154*4882a593Smuzhiyun BoxRec WinBox;
1155*4882a593Smuzhiyun int ret = Success;
1156*4882a593Smuzhiyun Bool clippedAway = FALSE;
1157*4882a593Smuzhiyun
1158*4882a593Smuzhiyun if (pDraw->type != DRAWABLE_WINDOW)
1159*4882a593Smuzhiyun return BadAlloc;
1160*4882a593Smuzhiyun
1161*4882a593Smuzhiyun if (!pScreenPriv->enabled)
1162*4882a593Smuzhiyun return Success;
1163*4882a593Smuzhiyun
1164*4882a593Smuzhiyun WinBox.x1 = pDraw->x + drw_x;
1165*4882a593Smuzhiyun WinBox.y1 = pDraw->y + drw_y;
1166*4882a593Smuzhiyun WinBox.x2 = WinBox.x1 + drw_w;
1167*4882a593Smuzhiyun WinBox.y2 = WinBox.y1 + drw_h;
1168*4882a593Smuzhiyun
1169*4882a593Smuzhiyun RegionInit(&WinRegion, &WinBox, 1);
1170*4882a593Smuzhiyun RegionInit(&ClipRegion, NullBox, 1);
1171*4882a593Smuzhiyun RegionIntersect(&ClipRegion, &WinRegion, pGC->pCompositeClip);
1172*4882a593Smuzhiyun
1173*4882a593Smuzhiyun if (portPriv->pDraw) {
1174*4882a593Smuzhiyun KdXVRemovePortFromWindow((WindowPtr) (portPriv->pDraw), portPriv);
1175*4882a593Smuzhiyun }
1176*4882a593Smuzhiyun
1177*4882a593Smuzhiyun if (!RegionNotEmpty(&ClipRegion)) {
1178*4882a593Smuzhiyun clippedAway = TRUE;
1179*4882a593Smuzhiyun goto GET_STILL_BAILOUT;
1180*4882a593Smuzhiyun }
1181*4882a593Smuzhiyun
1182*4882a593Smuzhiyun ret = (*portPriv->AdaptorRec->GetStill) (portPriv->screen, pDraw,
1183*4882a593Smuzhiyun vid_x, vid_y, WinBox.x1, WinBox.y1,
1184*4882a593Smuzhiyun vid_w, vid_h, drw_w, drw_h,
1185*4882a593Smuzhiyun &ClipRegion,
1186*4882a593Smuzhiyun portPriv->DevPriv.ptr);
1187*4882a593Smuzhiyun
1188*4882a593Smuzhiyun GET_STILL_BAILOUT:
1189*4882a593Smuzhiyun
1190*4882a593Smuzhiyun if ((clippedAway || (ret != Success)) && (portPriv->isOn == XV_ON)) {
1191*4882a593Smuzhiyun (*portPriv->AdaptorRec->StopVideo) (portPriv->screen,
1192*4882a593Smuzhiyun portPriv->DevPriv.ptr, FALSE);
1193*4882a593Smuzhiyun portPriv->isOn = XV_PENDING;
1194*4882a593Smuzhiyun }
1195*4882a593Smuzhiyun
1196*4882a593Smuzhiyun RegionUninit(&WinRegion);
1197*4882a593Smuzhiyun RegionUninit(&ClipRegion);
1198*4882a593Smuzhiyun
1199*4882a593Smuzhiyun return ret;
1200*4882a593Smuzhiyun }
1201*4882a593Smuzhiyun
1202*4882a593Smuzhiyun static int
KdXVStopVideo(XvPortPtr pPort,DrawablePtr pDraw)1203*4882a593Smuzhiyun KdXVStopVideo(XvPortPtr pPort, DrawablePtr pDraw)
1204*4882a593Smuzhiyun {
1205*4882a593Smuzhiyun XvPortRecPrivatePtr portPriv = (XvPortRecPrivatePtr) (pPort->devPriv.ptr);
1206*4882a593Smuzhiyun
1207*4882a593Smuzhiyun KdScreenPriv(portPriv->screen->pScreen);
1208*4882a593Smuzhiyun
1209*4882a593Smuzhiyun if (pDraw->type != DRAWABLE_WINDOW)
1210*4882a593Smuzhiyun return BadAlloc;
1211*4882a593Smuzhiyun
1212*4882a593Smuzhiyun KdXVRemovePortFromWindow((WindowPtr) pDraw, portPriv);
1213*4882a593Smuzhiyun
1214*4882a593Smuzhiyun if (!pScreenPriv->enabled)
1215*4882a593Smuzhiyun return Success;
1216*4882a593Smuzhiyun
1217*4882a593Smuzhiyun /* Must free resources. */
1218*4882a593Smuzhiyun
1219*4882a593Smuzhiyun if (portPriv->isOn > XV_OFF) {
1220*4882a593Smuzhiyun (*portPriv->AdaptorRec->StopVideo) (portPriv->screen,
1221*4882a593Smuzhiyun portPriv->DevPriv.ptr, TRUE);
1222*4882a593Smuzhiyun portPriv->isOn = XV_OFF;
1223*4882a593Smuzhiyun }
1224*4882a593Smuzhiyun
1225*4882a593Smuzhiyun return Success;
1226*4882a593Smuzhiyun }
1227*4882a593Smuzhiyun
1228*4882a593Smuzhiyun static int
KdXVSetPortAttribute(XvPortPtr pPort,Atom attribute,INT32 value)1229*4882a593Smuzhiyun KdXVSetPortAttribute(XvPortPtr pPort, Atom attribute, INT32 value)
1230*4882a593Smuzhiyun {
1231*4882a593Smuzhiyun XvPortRecPrivatePtr portPriv = (XvPortRecPrivatePtr) (pPort->devPriv.ptr);
1232*4882a593Smuzhiyun
1233*4882a593Smuzhiyun return ((*portPriv->AdaptorRec->SetPortAttribute) (portPriv->screen,
1234*4882a593Smuzhiyun attribute, value,
1235*4882a593Smuzhiyun portPriv->DevPriv.ptr));
1236*4882a593Smuzhiyun }
1237*4882a593Smuzhiyun
1238*4882a593Smuzhiyun static int
KdXVGetPortAttribute(XvPortPtr pPort,Atom attribute,INT32 * p_value)1239*4882a593Smuzhiyun KdXVGetPortAttribute(XvPortPtr pPort, Atom attribute, INT32 *p_value)
1240*4882a593Smuzhiyun {
1241*4882a593Smuzhiyun XvPortRecPrivatePtr portPriv = (XvPortRecPrivatePtr) (pPort->devPriv.ptr);
1242*4882a593Smuzhiyun
1243*4882a593Smuzhiyun return ((*portPriv->AdaptorRec->GetPortAttribute) (portPriv->screen,
1244*4882a593Smuzhiyun attribute,
1245*4882a593Smuzhiyun (int *) p_value,
1246*4882a593Smuzhiyun portPriv->DevPriv.ptr));
1247*4882a593Smuzhiyun }
1248*4882a593Smuzhiyun
1249*4882a593Smuzhiyun static int
KdXVQueryBestSize(XvPortPtr pPort,CARD8 motion,CARD16 vid_w,CARD16 vid_h,CARD16 drw_w,CARD16 drw_h,unsigned int * p_w,unsigned int * p_h)1250*4882a593Smuzhiyun KdXVQueryBestSize(XvPortPtr pPort,
1251*4882a593Smuzhiyun CARD8 motion,
1252*4882a593Smuzhiyun CARD16 vid_w, CARD16 vid_h,
1253*4882a593Smuzhiyun CARD16 drw_w, CARD16 drw_h,
1254*4882a593Smuzhiyun unsigned int *p_w, unsigned int *p_h)
1255*4882a593Smuzhiyun {
1256*4882a593Smuzhiyun XvPortRecPrivatePtr portPriv = (XvPortRecPrivatePtr) (pPort->devPriv.ptr);
1257*4882a593Smuzhiyun
1258*4882a593Smuzhiyun (*portPriv->AdaptorRec->QueryBestSize) (portPriv->screen,
1259*4882a593Smuzhiyun (Bool) motion, vid_w, vid_h, drw_w,
1260*4882a593Smuzhiyun drw_h, p_w, p_h,
1261*4882a593Smuzhiyun portPriv->DevPriv.ptr);
1262*4882a593Smuzhiyun
1263*4882a593Smuzhiyun return Success;
1264*4882a593Smuzhiyun }
1265*4882a593Smuzhiyun
1266*4882a593Smuzhiyun static int
KdXVPutImage(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)1267*4882a593Smuzhiyun KdXVPutImage(DrawablePtr pDraw,
1268*4882a593Smuzhiyun XvPortPtr pPort,
1269*4882a593Smuzhiyun GCPtr pGC,
1270*4882a593Smuzhiyun INT16 src_x, INT16 src_y,
1271*4882a593Smuzhiyun CARD16 src_w, CARD16 src_h,
1272*4882a593Smuzhiyun INT16 drw_x, INT16 drw_y,
1273*4882a593Smuzhiyun CARD16 drw_w, CARD16 drw_h,
1274*4882a593Smuzhiyun XvImagePtr format,
1275*4882a593Smuzhiyun unsigned char *data, Bool sync, CARD16 width, CARD16 height)
1276*4882a593Smuzhiyun {
1277*4882a593Smuzhiyun XvPortRecPrivatePtr portPriv = (XvPortRecPrivatePtr) (pPort->devPriv.ptr);
1278*4882a593Smuzhiyun ScreenPtr pScreen = pDraw->pScreen;
1279*4882a593Smuzhiyun
1280*4882a593Smuzhiyun KdScreenPriv(pScreen);
1281*4882a593Smuzhiyun RegionRec WinRegion;
1282*4882a593Smuzhiyun RegionRec ClipRegion;
1283*4882a593Smuzhiyun BoxRec WinBox;
1284*4882a593Smuzhiyun int ret = Success;
1285*4882a593Smuzhiyun Bool clippedAway = FALSE;
1286*4882a593Smuzhiyun
1287*4882a593Smuzhiyun if (pDraw->type != DRAWABLE_WINDOW)
1288*4882a593Smuzhiyun return BadAlloc;
1289*4882a593Smuzhiyun
1290*4882a593Smuzhiyun if (!pScreenPriv->enabled)
1291*4882a593Smuzhiyun return Success;
1292*4882a593Smuzhiyun
1293*4882a593Smuzhiyun WinBox.x1 = pDraw->x + drw_x;
1294*4882a593Smuzhiyun WinBox.y1 = pDraw->y + drw_y;
1295*4882a593Smuzhiyun WinBox.x2 = WinBox.x1 + drw_w;
1296*4882a593Smuzhiyun WinBox.y2 = WinBox.y1 + drw_h;
1297*4882a593Smuzhiyun
1298*4882a593Smuzhiyun RegionInit(&WinRegion, &WinBox, 1);
1299*4882a593Smuzhiyun RegionInit(&ClipRegion, NullBox, 1);
1300*4882a593Smuzhiyun RegionIntersect(&ClipRegion, &WinRegion, pGC->pCompositeClip);
1301*4882a593Smuzhiyun
1302*4882a593Smuzhiyun if (portPriv->AdaptorRec->flags & VIDEO_CLIP_TO_VIEWPORT) {
1303*4882a593Smuzhiyun RegionRec VPReg;
1304*4882a593Smuzhiyun BoxRec VPBox;
1305*4882a593Smuzhiyun
1306*4882a593Smuzhiyun VPBox.x1 = 0;
1307*4882a593Smuzhiyun VPBox.y1 = 0;
1308*4882a593Smuzhiyun VPBox.x2 = pScreen->width;
1309*4882a593Smuzhiyun VPBox.y2 = pScreen->height;
1310*4882a593Smuzhiyun
1311*4882a593Smuzhiyun RegionInit(&VPReg, &VPBox, 1);
1312*4882a593Smuzhiyun RegionIntersect(&ClipRegion, &ClipRegion, &VPReg);
1313*4882a593Smuzhiyun RegionUninit(&VPReg);
1314*4882a593Smuzhiyun }
1315*4882a593Smuzhiyun
1316*4882a593Smuzhiyun if (portPriv->pDraw) {
1317*4882a593Smuzhiyun KdXVRemovePortFromWindow((WindowPtr) (portPriv->pDraw), portPriv);
1318*4882a593Smuzhiyun }
1319*4882a593Smuzhiyun
1320*4882a593Smuzhiyun if (!RegionNotEmpty(&ClipRegion)) {
1321*4882a593Smuzhiyun clippedAway = TRUE;
1322*4882a593Smuzhiyun goto PUT_IMAGE_BAILOUT;
1323*4882a593Smuzhiyun }
1324*4882a593Smuzhiyun
1325*4882a593Smuzhiyun ret = (*portPriv->AdaptorRec->PutImage) (portPriv->screen, pDraw,
1326*4882a593Smuzhiyun src_x, src_y, WinBox.x1, WinBox.y1,
1327*4882a593Smuzhiyun src_w, src_h, drw_w, drw_h,
1328*4882a593Smuzhiyun format->id, data, width, height,
1329*4882a593Smuzhiyun sync, &ClipRegion,
1330*4882a593Smuzhiyun portPriv->DevPriv.ptr);
1331*4882a593Smuzhiyun
1332*4882a593Smuzhiyun if ((ret == Success) &&
1333*4882a593Smuzhiyun (portPriv->AdaptorRec->flags & VIDEO_OVERLAID_IMAGES)) {
1334*4882a593Smuzhiyun
1335*4882a593Smuzhiyun KdXVEnlistPortInWindow((WindowPtr) pDraw, portPriv);
1336*4882a593Smuzhiyun portPriv->isOn = XV_ON;
1337*4882a593Smuzhiyun portPriv->pDraw = pDraw;
1338*4882a593Smuzhiyun portPriv->drw_x = drw_x;
1339*4882a593Smuzhiyun portPriv->drw_y = drw_y;
1340*4882a593Smuzhiyun portPriv->drw_w = drw_w;
1341*4882a593Smuzhiyun portPriv->drw_h = drw_h;
1342*4882a593Smuzhiyun portPriv->type = 0; /* no mask means it's transient and should
1343*4882a593Smuzhiyun not be reput once it's removed */
1344*4882a593Smuzhiyun pPort->pDraw = pDraw; /* make sure we can get stop requests */
1345*4882a593Smuzhiyun }
1346*4882a593Smuzhiyun
1347*4882a593Smuzhiyun PUT_IMAGE_BAILOUT:
1348*4882a593Smuzhiyun
1349*4882a593Smuzhiyun if ((clippedAway || (ret != Success)) && (portPriv->isOn == XV_ON)) {
1350*4882a593Smuzhiyun (*portPriv->AdaptorRec->StopVideo) (portPriv->screen,
1351*4882a593Smuzhiyun portPriv->DevPriv.ptr, FALSE);
1352*4882a593Smuzhiyun portPriv->isOn = XV_PENDING;
1353*4882a593Smuzhiyun }
1354*4882a593Smuzhiyun
1355*4882a593Smuzhiyun RegionUninit(&WinRegion);
1356*4882a593Smuzhiyun RegionUninit(&ClipRegion);
1357*4882a593Smuzhiyun
1358*4882a593Smuzhiyun return ret;
1359*4882a593Smuzhiyun }
1360*4882a593Smuzhiyun
1361*4882a593Smuzhiyun static int
KdXVQueryImageAttributes(XvPortPtr pPort,XvImagePtr format,CARD16 * width,CARD16 * height,int * pitches,int * offsets)1362*4882a593Smuzhiyun KdXVQueryImageAttributes(XvPortPtr pPort,
1363*4882a593Smuzhiyun XvImagePtr format,
1364*4882a593Smuzhiyun CARD16 *width,
1365*4882a593Smuzhiyun CARD16 *height, int *pitches, int *offsets)
1366*4882a593Smuzhiyun {
1367*4882a593Smuzhiyun XvPortRecPrivatePtr portPriv = (XvPortRecPrivatePtr) (pPort->devPriv.ptr);
1368*4882a593Smuzhiyun
1369*4882a593Smuzhiyun return (*portPriv->AdaptorRec->QueryImageAttributes) (portPriv->screen,
1370*4882a593Smuzhiyun format->id, width,
1371*4882a593Smuzhiyun height, pitches,
1372*4882a593Smuzhiyun offsets);
1373*4882a593Smuzhiyun }
1374