16747b715Smrg/*
205b261ecSmrg
36747b715Smrg   XFree86 Xv DDX written by Mark Vojkovich (markv@valinux.com)
405b261ecSmrg   Adapted for KDrive by Pontus Lidman <pontus.lidman@nokia.com>
505b261ecSmrg
605b261ecSmrg   Copyright (C) 2000, 2001 - Nokia Home Communications
705b261ecSmrg   Copyright (C) 1998, 1999 - The XFree86 Project Inc.
805b261ecSmrg
905b261ecSmrgAll rights reserved.
1005b261ecSmrg
1105b261ecSmrgPermission is hereby granted, free of charge, to any person obtaining
1205b261ecSmrga copy of this software and associated documentation files (the
1305b261ecSmrg"Software"), to deal in the Software without restriction, including
1405b261ecSmrgwithout limitation the rights to use, copy, modify, merge, publish,
1505b261ecSmrgdistribute, and/or sell copies of the Software, and to permit persons
1605b261ecSmrgto whom the Software is furnished to do so, provided that the above
1705b261ecSmrgcopyright notice(s) and this permission notice appear in all copies of
1805b261ecSmrgthe Software and that both the above copyright notice(s) and this
1905b261ecSmrgpermission notice appear in supporting documentation.
2005b261ecSmrg
2105b261ecSmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
2205b261ecSmrgEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
2305b261ecSmrgMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
2405b261ecSmrgOF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
2505b261ecSmrgHOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY
2605b261ecSmrgSPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER
2705b261ecSmrgRESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
2805b261ecSmrgCONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
2905b261ecSmrgCONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
3005b261ecSmrg
3105b261ecSmrgExcept as contained in this notice, the name of a copyright holder
3205b261ecSmrgshall not be used in advertising or otherwise to promote the sale, use
3305b261ecSmrgor other dealings in this Software without prior written authorization
3405b261ecSmrgof the copyright holder.
3505b261ecSmrg
3605b261ecSmrg*/
3705b261ecSmrg
381b5d61b8Smrg#ifdef HAVE_DIX_CONFIG_H
391b5d61b8Smrg#include <dix-config.h>
4005b261ecSmrg#endif
4105b261ecSmrg#include "kdrive.h"
4205b261ecSmrg
4305b261ecSmrg#include "scrnintstr.h"
4405b261ecSmrg#include "regionstr.h"
4505b261ecSmrg#include "windowstr.h"
4605b261ecSmrg#include "pixmapstr.h"
4705b261ecSmrg#include "mivalidate.h"
4805b261ecSmrg#include "validate.h"
4905b261ecSmrg#include "resource.h"
5005b261ecSmrg#include "gcstruct.h"
5105b261ecSmrg#include "dixstruct.h"
5205b261ecSmrg
5305b261ecSmrg#include <X11/extensions/Xv.h>
5405b261ecSmrg#include <X11/extensions/Xvproto.h>
5505b261ecSmrg
5605b261ecSmrg#include "kxv.h"
5705b261ecSmrg#include "fourcc.h"
5805b261ecSmrg
5905b261ecSmrg/* XvAdaptorRec fields */
6005b261ecSmrg
6135c4bbdfSmrgstatic int KdXVPutVideo(DrawablePtr, XvPortPtr, GCPtr,
6235c4bbdfSmrg                        INT16, INT16, CARD16, CARD16,
6335c4bbdfSmrg                        INT16, INT16, CARD16, CARD16);
6435c4bbdfSmrgstatic int KdXVPutStill(DrawablePtr, XvPortPtr, GCPtr,
6535c4bbdfSmrg                        INT16, INT16, CARD16, CARD16,
6635c4bbdfSmrg                        INT16, INT16, CARD16, CARD16);
6735c4bbdfSmrgstatic int KdXVGetVideo(DrawablePtr, XvPortPtr, GCPtr,
6835c4bbdfSmrg                        INT16, INT16, CARD16, CARD16,
6935c4bbdfSmrg                        INT16, INT16, CARD16, CARD16);
7035c4bbdfSmrgstatic int KdXVGetStill(DrawablePtr, XvPortPtr, GCPtr,
7135c4bbdfSmrg                        INT16, INT16, CARD16, CARD16,
7235c4bbdfSmrg                        INT16, INT16, CARD16, CARD16);
7335c4bbdfSmrgstatic int KdXVStopVideo(XvPortPtr, DrawablePtr);
7435c4bbdfSmrgstatic int KdXVSetPortAttribute(XvPortPtr, Atom, INT32);
7535c4bbdfSmrgstatic int KdXVGetPortAttribute(XvPortPtr, Atom, INT32 *);
7635c4bbdfSmrgstatic int KdXVQueryBestSize(XvPortPtr, CARD8,
7735c4bbdfSmrg                             CARD16, CARD16, CARD16, CARD16,
7835c4bbdfSmrg                             unsigned int *, unsigned int *);
7935c4bbdfSmrgstatic int KdXVPutImage(DrawablePtr, XvPortPtr, GCPtr,
8035c4bbdfSmrg                        INT16, INT16, CARD16, CARD16,
8135c4bbdfSmrg                        INT16, INT16, CARD16, CARD16,
8235c4bbdfSmrg                        XvImagePtr, unsigned char *, Bool, CARD16, CARD16);
8335c4bbdfSmrgstatic int KdXVQueryImageAttributes(XvPortPtr, XvImagePtr,
8435c4bbdfSmrg                                    CARD16 *, CARD16 *, int *, int *);
8505b261ecSmrg
8605b261ecSmrg/* ScreenRec fields */
8705b261ecSmrg
8805b261ecSmrgstatic Bool KdXVDestroyWindow(WindowPtr pWin);
8935c4bbdfSmrgstatic void KdXVWindowExposures(WindowPtr pWin, RegionPtr r1);
9005b261ecSmrgstatic void KdXVClipNotify(WindowPtr pWin, int dx, int dy);
9135c4bbdfSmrgstatic Bool KdXVCloseScreen(ScreenPtr);
9205b261ecSmrg
9305b261ecSmrg/* misc */
9435c4bbdfSmrgstatic Bool KdXVInitAdaptors(ScreenPtr, KdVideoAdaptorPtr, int);
9505b261ecSmrg
966747b715Smrgstatic DevPrivateKeyRec KdXVWindowKeyRec;
9735c4bbdfSmrg
986747b715Smrg#define KdXVWindowKey (&KdXVWindowKeyRec)
996747b715Smrgstatic DevPrivateKey KdXvScreenKey;
10035c4bbdfSmrgstatic DevPrivateKeyRec KdXVScreenPrivateKey;
10105b261ecSmrgstatic unsigned long KdXVGeneration = 0;
10205b261ecSmrgstatic unsigned long PortResource = 0;
10305b261ecSmrg
1044642e01fSmrg#define GET_XV_SCREEN(pScreen) ((XvScreenPtr) \
1054642e01fSmrg    dixLookupPrivate(&(pScreen)->devPrivates, KdXvScreenKey))
10605b261ecSmrg
10705b261ecSmrg#define GET_KDXV_SCREEN(pScreen) \
10835c4bbdfSmrg    ((KdXVScreenPtr)(dixGetPrivate(&pScreen->devPrivates, &KdXVScreenPrivateKey)))
10905b261ecSmrg
1104642e01fSmrg#define GET_KDXV_WINDOW(pWin) ((KdXVWindowPtr) \
1114642e01fSmrg    dixLookupPrivate(&(pWin)->devPrivates, KdXVWindowKey))
11205b261ecSmrg
11305b261ecSmrgBool
11435c4bbdfSmrgKdXVScreenInit(ScreenPtr pScreen, KdVideoAdaptorPtr adaptors, int num)
11535c4bbdfSmrg{
11635c4bbdfSmrg    KdXVScreenPtr ScreenPriv;
11705b261ecSmrg
11805b261ecSmrg/*   fprintf(stderr,"KdXVScreenInit initializing %d adaptors\n",num); */
11905b261ecSmrg
12035c4bbdfSmrg    if (KdXVGeneration != serverGeneration)
12135c4bbdfSmrg        KdXVGeneration = serverGeneration;
12205b261ecSmrg
12335c4bbdfSmrg    if (noXvExtension)
12435c4bbdfSmrg        return FALSE;
12505b261ecSmrg
12635c4bbdfSmrg    if (!dixRegisterPrivateKey(&KdXVWindowKeyRec, PRIVATE_WINDOW, 0))
12735c4bbdfSmrg        return FALSE;
12835c4bbdfSmrg    if (!dixRegisterPrivateKey(&KdXVScreenPrivateKey, PRIVATE_SCREEN, 0))
12935c4bbdfSmrg        return FALSE;
13005b261ecSmrg
13135c4bbdfSmrg    if (Success != XvScreenInit(pScreen))
13235c4bbdfSmrg        return FALSE;
13305b261ecSmrg
13435c4bbdfSmrg    KdXvScreenKey = XvGetScreenKey();
13535c4bbdfSmrg    PortResource = XvGetRTPort();
13605b261ecSmrg
13735c4bbdfSmrg    ScreenPriv = malloc(sizeof(KdXVScreenRec));
13835c4bbdfSmrg    dixSetPrivate(&pScreen->devPrivates, &KdXVScreenPrivateKey, ScreenPriv);
13905b261ecSmrg
14035c4bbdfSmrg    if (!ScreenPriv)
14135c4bbdfSmrg        return FALSE;
14205b261ecSmrg
14335c4bbdfSmrg    ScreenPriv->DestroyWindow = pScreen->DestroyWindow;
14435c4bbdfSmrg    ScreenPriv->WindowExposures = pScreen->WindowExposures;
14535c4bbdfSmrg    ScreenPriv->ClipNotify = pScreen->ClipNotify;
14635c4bbdfSmrg    ScreenPriv->CloseScreen = pScreen->CloseScreen;
14705b261ecSmrg
14805b261ecSmrg/*   fprintf(stderr,"XV: Wrapping screen funcs\n"); */
14905b261ecSmrg
15035c4bbdfSmrg    pScreen->DestroyWindow = KdXVDestroyWindow;
15135c4bbdfSmrg    pScreen->WindowExposures = KdXVWindowExposures;
15235c4bbdfSmrg    pScreen->ClipNotify = KdXVClipNotify;
15335c4bbdfSmrg    pScreen->CloseScreen = KdXVCloseScreen;
15405b261ecSmrg
15535c4bbdfSmrg    if (!KdXVInitAdaptors(pScreen, adaptors, num))
15635c4bbdfSmrg        return FALSE;
15705b261ecSmrg
15835c4bbdfSmrg    return TRUE;
15905b261ecSmrg}
16005b261ecSmrg
16105b261ecSmrgstatic void
16205b261ecSmrgKdXVFreeAdaptor(XvAdaptorPtr pAdaptor)
16305b261ecSmrg{
16435c4bbdfSmrg    int i;
16535c4bbdfSmrg
16635c4bbdfSmrg    if (pAdaptor->pPorts) {
16735c4bbdfSmrg        XvPortPtr pPort = pAdaptor->pPorts;
16835c4bbdfSmrg        XvPortRecPrivatePtr pPriv;
16935c4bbdfSmrg
17035c4bbdfSmrg        for (i = 0; i < pAdaptor->nPorts; i++, pPort++) {
17135c4bbdfSmrg            pPriv = (XvPortRecPrivatePtr) pPort->devPriv.ptr;
17235c4bbdfSmrg            if (pPriv) {
17335c4bbdfSmrg                if (pPriv->clientClip)
17435c4bbdfSmrg                    RegionDestroy(pPriv->clientClip);
17535c4bbdfSmrg                if (pPriv->pCompositeClip && pPriv->FreeCompositeClip)
17635c4bbdfSmrg                    RegionDestroy(pPriv->pCompositeClip);
17735c4bbdfSmrg                free(pPriv);
17835c4bbdfSmrg            }
17935c4bbdfSmrg        }
18035c4bbdfSmrg    }
1816747b715Smrg
18235c4bbdfSmrg    XvFreeAdaptor(pAdaptor);
18305b261ecSmrg}
18405b261ecSmrg
18505b261ecSmrgstatic Bool
18635c4bbdfSmrgKdXVInitAdaptors(ScreenPtr pScreen, KdVideoAdaptorPtr infoPtr, int number)
18735c4bbdfSmrg{
18805b261ecSmrg    KdScreenPriv(pScreen);
18935c4bbdfSmrg    KdScreenInfo *screen = pScreenPriv->screen;
19035c4bbdfSmrg
19135c4bbdfSmrg    XvScreenPtr pxvs = GET_XV_SCREEN(pScreen);
19235c4bbdfSmrg    KdVideoAdaptorPtr adaptorPtr;
19335c4bbdfSmrg    XvAdaptorPtr pAdaptor, pa;
19435c4bbdfSmrg    XvAdaptorRecPrivatePtr adaptorPriv;
19535c4bbdfSmrg    int na, numAdaptor;
19635c4bbdfSmrg    XvPortRecPrivatePtr portPriv;
19735c4bbdfSmrg    XvPortPtr pPort, pp;
19835c4bbdfSmrg    int numPort;
19935c4bbdfSmrg    KdVideoFormatPtr formatPtr;
20035c4bbdfSmrg    XvFormatPtr pFormat, pf;
20135c4bbdfSmrg    int numFormat, totFormat;
20235c4bbdfSmrg    KdVideoEncodingPtr encodingPtr;
20335c4bbdfSmrg    XvEncodingPtr pEncode, pe;
20435c4bbdfSmrg    int numVisuals;
20535c4bbdfSmrg    VisualPtr pVisual;
20635c4bbdfSmrg    int i;
20735c4bbdfSmrg
20835c4bbdfSmrg    pxvs->nAdaptors = 0;
20935c4bbdfSmrg    pxvs->pAdaptors = NULL;
21035c4bbdfSmrg
21135c4bbdfSmrg    if (!(pAdaptor = calloc(number, sizeof(XvAdaptorRec))))
21235c4bbdfSmrg        return FALSE;
21335c4bbdfSmrg
21435c4bbdfSmrg    for (pa = pAdaptor, na = 0, numAdaptor = 0; na < number; na++, adaptorPtr++) {
21535c4bbdfSmrg        adaptorPtr = &infoPtr[na];
21635c4bbdfSmrg
21735c4bbdfSmrg        if (!adaptorPtr->StopVideo || !adaptorPtr->SetPortAttribute ||
21835c4bbdfSmrg            !adaptorPtr->GetPortAttribute || !adaptorPtr->QueryBestSize)
21935c4bbdfSmrg            continue;
22035c4bbdfSmrg
22135c4bbdfSmrg        /* client libs expect at least one encoding */
22235c4bbdfSmrg        if (!adaptorPtr->nEncodings || !adaptorPtr->pEncodings)
22335c4bbdfSmrg            continue;
22435c4bbdfSmrg
22535c4bbdfSmrg        pa->type = adaptorPtr->type;
22635c4bbdfSmrg
22735c4bbdfSmrg        if (!adaptorPtr->PutVideo && !adaptorPtr->GetVideo)
22835c4bbdfSmrg            pa->type &= ~XvVideoMask;
22935c4bbdfSmrg
23035c4bbdfSmrg        if (!adaptorPtr->PutStill && !adaptorPtr->GetStill)
23135c4bbdfSmrg            pa->type &= ~XvStillMask;
23235c4bbdfSmrg
23335c4bbdfSmrg        if (!adaptorPtr->PutImage || !adaptorPtr->QueryImageAttributes)
23435c4bbdfSmrg            pa->type &= ~XvImageMask;
23535c4bbdfSmrg
23635c4bbdfSmrg        if (!adaptorPtr->PutVideo && !adaptorPtr->PutImage &&
23735c4bbdfSmrg            !adaptorPtr->PutStill)
23835c4bbdfSmrg            pa->type &= ~XvInputMask;
23935c4bbdfSmrg
24035c4bbdfSmrg        if (!adaptorPtr->GetVideo && !adaptorPtr->GetStill)
24135c4bbdfSmrg            pa->type &= ~XvOutputMask;
24235c4bbdfSmrg
24335c4bbdfSmrg        if (!(adaptorPtr->type & (XvPixmapMask | XvWindowMask)))
24435c4bbdfSmrg            continue;
24535c4bbdfSmrg        if (!(adaptorPtr->type & (XvImageMask | XvVideoMask | XvStillMask)))
24635c4bbdfSmrg            continue;
24735c4bbdfSmrg
24835c4bbdfSmrg        pa->pScreen = pScreen;
24935c4bbdfSmrg        pa->ddPutVideo = KdXVPutVideo;
25035c4bbdfSmrg        pa->ddPutStill = KdXVPutStill;
25135c4bbdfSmrg        pa->ddGetVideo = KdXVGetVideo;
25235c4bbdfSmrg        pa->ddGetStill = KdXVGetStill;
25335c4bbdfSmrg        pa->ddStopVideo = KdXVStopVideo;
25435c4bbdfSmrg        pa->ddPutImage = KdXVPutImage;
25535c4bbdfSmrg        pa->ddSetPortAttribute = KdXVSetPortAttribute;
25635c4bbdfSmrg        pa->ddGetPortAttribute = KdXVGetPortAttribute;
25735c4bbdfSmrg        pa->ddQueryBestSize = KdXVQueryBestSize;
25835c4bbdfSmrg        pa->ddQueryImageAttributes = KdXVQueryImageAttributes;
25935c4bbdfSmrg        pa->name = strdup(adaptorPtr->name);
26035c4bbdfSmrg
26135c4bbdfSmrg        if (adaptorPtr->nEncodings &&
26235c4bbdfSmrg            (pEncode = calloc(adaptorPtr->nEncodings, sizeof(XvEncodingRec)))) {
26335c4bbdfSmrg
26435c4bbdfSmrg            for (pe = pEncode, encodingPtr = adaptorPtr->pEncodings, i = 0;
26535c4bbdfSmrg                 i < adaptorPtr->nEncodings; pe++, i++, encodingPtr++) {
26635c4bbdfSmrg                pe->id = encodingPtr->id;
26735c4bbdfSmrg                pe->pScreen = pScreen;
26835c4bbdfSmrg                pe->name = strdup(encodingPtr->name);
26935c4bbdfSmrg                pe->width = encodingPtr->width;
27035c4bbdfSmrg                pe->height = encodingPtr->height;
27135c4bbdfSmrg                pe->rate.numerator = encodingPtr->rate.numerator;
27235c4bbdfSmrg                pe->rate.denominator = encodingPtr->rate.denominator;
27335c4bbdfSmrg            }
27435c4bbdfSmrg            pa->nEncodings = adaptorPtr->nEncodings;
27535c4bbdfSmrg            pa->pEncodings = pEncode;
27635c4bbdfSmrg        }
27735c4bbdfSmrg
27835c4bbdfSmrg        if (adaptorPtr->nImages &&
27935c4bbdfSmrg            (pa->pImages = calloc(adaptorPtr->nImages, sizeof(XvImageRec)))) {
28035c4bbdfSmrg            memcpy(pa->pImages, adaptorPtr->pImages,
28135c4bbdfSmrg                   adaptorPtr->nImages * sizeof(XvImageRec));
28235c4bbdfSmrg            pa->nImages = adaptorPtr->nImages;
28335c4bbdfSmrg        }
28435c4bbdfSmrg
28535c4bbdfSmrg        if (adaptorPtr->nAttributes &&
28635c4bbdfSmrg            (pa->pAttributes = calloc(adaptorPtr->nAttributes,
28735c4bbdfSmrg                                      sizeof(XvAttributeRec)))) {
28835c4bbdfSmrg            memcpy(pa->pAttributes, adaptorPtr->pAttributes,
28935c4bbdfSmrg                   adaptorPtr->nAttributes * sizeof(XvAttributeRec));
29035c4bbdfSmrg
29135c4bbdfSmrg            for (i = 0; i < adaptorPtr->nAttributes; i++) {
29235c4bbdfSmrg                pa->pAttributes[i].name =
29335c4bbdfSmrg                    strdup(adaptorPtr->pAttributes[i].name);
29435c4bbdfSmrg            }
29535c4bbdfSmrg
29635c4bbdfSmrg            pa->nAttributes = adaptorPtr->nAttributes;
29735c4bbdfSmrg        }
29835c4bbdfSmrg
29935c4bbdfSmrg        totFormat = adaptorPtr->nFormats;
30035c4bbdfSmrg
30135c4bbdfSmrg        if (!(pFormat = calloc(totFormat, sizeof(XvFormatRec)))) {
30235c4bbdfSmrg            KdXVFreeAdaptor(pa);
30335c4bbdfSmrg            continue;
30435c4bbdfSmrg        }
30535c4bbdfSmrg        for (pf = pFormat, i = 0, numFormat = 0, formatPtr =
30635c4bbdfSmrg             adaptorPtr->pFormats; i < adaptorPtr->nFormats; i++, formatPtr++) {
30735c4bbdfSmrg            numVisuals = pScreen->numVisuals;
30835c4bbdfSmrg            pVisual = pScreen->visuals;
30935c4bbdfSmrg
31035c4bbdfSmrg            while (numVisuals--) {
31135c4bbdfSmrg                if ((pVisual->class == formatPtr->class) &&
31235c4bbdfSmrg                    (pVisual->nplanes == formatPtr->depth)) {
31335c4bbdfSmrg
31435c4bbdfSmrg                    if (numFormat >= totFormat) {
31535c4bbdfSmrg                        void *moreSpace;
31635c4bbdfSmrg
31735c4bbdfSmrg                        totFormat *= 2;
31835c4bbdfSmrg                        moreSpace = reallocarray(pFormat, totFormat,
31935c4bbdfSmrg                                                 sizeof(XvFormatRec));
32035c4bbdfSmrg                        if (!moreSpace)
32135c4bbdfSmrg                            break;
32235c4bbdfSmrg                        pFormat = moreSpace;
32335c4bbdfSmrg                        pf = pFormat + numFormat;
32435c4bbdfSmrg                    }
32535c4bbdfSmrg
32635c4bbdfSmrg                    pf->visual = pVisual->vid;
32735c4bbdfSmrg                    pf->depth = formatPtr->depth;
32835c4bbdfSmrg
32935c4bbdfSmrg                    pf++;
33035c4bbdfSmrg                    numFormat++;
33135c4bbdfSmrg                }
33235c4bbdfSmrg                pVisual++;
33335c4bbdfSmrg            }
33435c4bbdfSmrg        }
33535c4bbdfSmrg        pa->nFormats = numFormat;
33635c4bbdfSmrg        pa->pFormats = pFormat;
33735c4bbdfSmrg        if (!numFormat) {
33835c4bbdfSmrg            KdXVFreeAdaptor(pa);
33935c4bbdfSmrg            continue;
34035c4bbdfSmrg        }
34135c4bbdfSmrg
34235c4bbdfSmrg        if (!(adaptorPriv = calloc(1, sizeof(XvAdaptorRecPrivate)))) {
34335c4bbdfSmrg            KdXVFreeAdaptor(pa);
34435c4bbdfSmrg            continue;
34535c4bbdfSmrg        }
34635c4bbdfSmrg
34735c4bbdfSmrg        adaptorPriv->flags = adaptorPtr->flags;
34835c4bbdfSmrg        adaptorPriv->PutVideo = adaptorPtr->PutVideo;
34935c4bbdfSmrg        adaptorPriv->PutStill = adaptorPtr->PutStill;
35035c4bbdfSmrg        adaptorPriv->GetVideo = adaptorPtr->GetVideo;
35135c4bbdfSmrg        adaptorPriv->GetStill = adaptorPtr->GetStill;
35235c4bbdfSmrg        adaptorPriv->StopVideo = adaptorPtr->StopVideo;
35335c4bbdfSmrg        adaptorPriv->SetPortAttribute = adaptorPtr->SetPortAttribute;
35435c4bbdfSmrg        adaptorPriv->GetPortAttribute = adaptorPtr->GetPortAttribute;
35535c4bbdfSmrg        adaptorPriv->QueryBestSize = adaptorPtr->QueryBestSize;
35635c4bbdfSmrg        adaptorPriv->QueryImageAttributes = adaptorPtr->QueryImageAttributes;
35735c4bbdfSmrg        adaptorPriv->PutImage = adaptorPtr->PutImage;
35835c4bbdfSmrg        adaptorPriv->ReputImage = adaptorPtr->ReputImage;
35935c4bbdfSmrg
36035c4bbdfSmrg        pa->devPriv.ptr = (void *) adaptorPriv;
36135c4bbdfSmrg
36235c4bbdfSmrg        if (!(pPort = calloc(adaptorPtr->nPorts, sizeof(XvPortRec)))) {
36335c4bbdfSmrg            KdXVFreeAdaptor(pa);
36435c4bbdfSmrg            continue;
36535c4bbdfSmrg        }
36635c4bbdfSmrg        for (pp = pPort, i = 0, numPort = 0; i < adaptorPtr->nPorts; i++) {
36735c4bbdfSmrg
36835c4bbdfSmrg            if (!(pp->id = FakeClientID(0)))
36935c4bbdfSmrg                continue;
37035c4bbdfSmrg
37135c4bbdfSmrg            if (!(portPriv = calloc(1, sizeof(XvPortRecPrivate))))
37235c4bbdfSmrg                continue;
37335c4bbdfSmrg
37435c4bbdfSmrg            if (!AddResource(pp->id, PortResource, pp)) {
37535c4bbdfSmrg                free(portPriv);
37635c4bbdfSmrg                continue;
37735c4bbdfSmrg            }
37835c4bbdfSmrg
37935c4bbdfSmrg            pp->pAdaptor = pa;
38035c4bbdfSmrg            pp->pNotify = (XvPortNotifyPtr) NULL;
38135c4bbdfSmrg            pp->pDraw = (DrawablePtr) NULL;
38235c4bbdfSmrg            pp->client = (ClientPtr) NULL;
38335c4bbdfSmrg            pp->grab.client = (ClientPtr) NULL;
38435c4bbdfSmrg            pp->time = currentTime;
38535c4bbdfSmrg            pp->devPriv.ptr = portPriv;
38635c4bbdfSmrg
38735c4bbdfSmrg            portPriv->screen = screen;
38835c4bbdfSmrg            portPriv->AdaptorRec = adaptorPriv;
38935c4bbdfSmrg            portPriv->DevPriv.ptr = adaptorPtr->pPortPrivates[i].ptr;
39035c4bbdfSmrg
39135c4bbdfSmrg            pp++;
39235c4bbdfSmrg            numPort++;
39335c4bbdfSmrg        }
39435c4bbdfSmrg        pa->nPorts = numPort;
39535c4bbdfSmrg        pa->pPorts = pPort;
39635c4bbdfSmrg        if (!numPort) {
39735c4bbdfSmrg            KdXVFreeAdaptor(pa);
39835c4bbdfSmrg            continue;
39935c4bbdfSmrg        }
40035c4bbdfSmrg
40135c4bbdfSmrg        pa->base_id = pPort->id;
40235c4bbdfSmrg
40335c4bbdfSmrg        pa++;
40435c4bbdfSmrg        numAdaptor++;
40535c4bbdfSmrg    }
40635c4bbdfSmrg
40735c4bbdfSmrg    if (numAdaptor) {
40835c4bbdfSmrg        pxvs->nAdaptors = numAdaptor;
40935c4bbdfSmrg        pxvs->pAdaptors = pAdaptor;
41035c4bbdfSmrg    }
41135c4bbdfSmrg    else {
41235c4bbdfSmrg        free(pAdaptor);
41335c4bbdfSmrg        return FALSE;
41435c4bbdfSmrg    }
41535c4bbdfSmrg
41635c4bbdfSmrg    return TRUE;
41705b261ecSmrg}
41805b261ecSmrg
41905b261ecSmrg/* Video should be clipped to the intersection of the window cliplist
42005b261ecSmrg   and the client cliplist specified in the GC for which the video was
42105b261ecSmrg   initialized.  When we need to reclip a window, the GC that started
42205b261ecSmrg   the video may not even be around anymore.  That's why we save the
42305b261ecSmrg   client clip from the GC when the video is initialized.  We then
42405b261ecSmrg   use KdXVUpdateCompositeClip to calculate the new composite clip
42505b261ecSmrg   when we need it.  This is different from what DEC did.  They saved
426ed6184dfSmrg   the GC and used its clip list when they needed to reclip the window,
42705b261ecSmrg   even if the client clip was different from the one the video was
42805b261ecSmrg   initialized with.  If the original GC was destroyed, they had to stop
4296747b715Smrg   the video.  I like the new method better (MArk).
43005b261ecSmrg
43105b261ecSmrg   This function only works for windows.  Will need to rewrite when
43205b261ecSmrg   (if) we support pixmap rendering.
43305b261ecSmrg*/
43405b261ecSmrg
4356747b715Smrgstatic void
43605b261ecSmrgKdXVUpdateCompositeClip(XvPortRecPrivatePtr portPriv)
43705b261ecSmrg{
43835c4bbdfSmrg    RegionPtr pregWin, pCompositeClip;
43935c4bbdfSmrg    WindowPtr pWin;
44035c4bbdfSmrg    Bool freeCompClip = FALSE;
44135c4bbdfSmrg
44235c4bbdfSmrg    if (portPriv->pCompositeClip)
44335c4bbdfSmrg        return;
44435c4bbdfSmrg
44535c4bbdfSmrg    pWin = (WindowPtr) portPriv->pDraw;
44635c4bbdfSmrg
44735c4bbdfSmrg    /* get window clip list */
44835c4bbdfSmrg    if (portPriv->subWindowMode == IncludeInferiors) {
44935c4bbdfSmrg        pregWin = NotClippedByChildren(pWin);
45035c4bbdfSmrg        freeCompClip = TRUE;
45135c4bbdfSmrg    }
45235c4bbdfSmrg    else
45335c4bbdfSmrg        pregWin = &pWin->clipList;
45435c4bbdfSmrg
45535c4bbdfSmrg    if (!portPriv->clientClip) {
45635c4bbdfSmrg        portPriv->pCompositeClip = pregWin;
45735c4bbdfSmrg        portPriv->FreeCompositeClip = freeCompClip;
45835c4bbdfSmrg        return;
45935c4bbdfSmrg    }
46035c4bbdfSmrg
46135c4bbdfSmrg    pCompositeClip = RegionCreate(NullBox, 1);
46235c4bbdfSmrg    RegionCopy(pCompositeClip, portPriv->clientClip);
46335c4bbdfSmrg    RegionTranslate(pCompositeClip,
46435c4bbdfSmrg                    portPriv->pDraw->x + portPriv->clipOrg.x,
46535c4bbdfSmrg                    portPriv->pDraw->y + portPriv->clipOrg.y);
46635c4bbdfSmrg    RegionIntersect(pCompositeClip, pregWin, pCompositeClip);
46735c4bbdfSmrg
46835c4bbdfSmrg    portPriv->pCompositeClip = pCompositeClip;
46935c4bbdfSmrg    portPriv->FreeCompositeClip = TRUE;
47035c4bbdfSmrg
47135c4bbdfSmrg    if (freeCompClip) {
47235c4bbdfSmrg        RegionDestroy(pregWin);
47335c4bbdfSmrg    }
47405b261ecSmrg}
47505b261ecSmrg
47605b261ecSmrg/* Save the current clientClip and update the CompositeClip whenever
47705b261ecSmrg   we have a fresh GC */
47805b261ecSmrg
47905b261ecSmrgstatic void
48035c4bbdfSmrgKdXVCopyClip(XvPortRecPrivatePtr portPriv, GCPtr pGC)
48135c4bbdfSmrg{
48205b261ecSmrg    /* copy the new clip if it exists */
48335c4bbdfSmrg    if (pGC->clientClip) {
48435c4bbdfSmrg        if (!portPriv->clientClip)
48535c4bbdfSmrg            portPriv->clientClip = RegionCreate(NullBox, 1);
48635c4bbdfSmrg        /* Note: this is in window coordinates */
48735c4bbdfSmrg        RegionCopy(portPriv->clientClip, pGC->clientClip);
48835c4bbdfSmrg    }
48935c4bbdfSmrg    else if (portPriv->clientClip) {    /* free the old clientClip */
49035c4bbdfSmrg        RegionDestroy(portPriv->clientClip);
49135c4bbdfSmrg        portPriv->clientClip = NULL;
49205b261ecSmrg    }
49305b261ecSmrg
49405b261ecSmrg    /* get rid of the old clip list */
49535c4bbdfSmrg    if (portPriv->pCompositeClip && portPriv->FreeCompositeClip) {
49635c4bbdfSmrg        RegionDestroy(portPriv->pCompositeClip);
49705b261ecSmrg    }
49805b261ecSmrg
49905b261ecSmrg    portPriv->clipOrg = pGC->clipOrg;
50005b261ecSmrg    portPriv->pCompositeClip = pGC->pCompositeClip;
50105b261ecSmrg    portPriv->FreeCompositeClip = FALSE;
50205b261ecSmrg    portPriv->subWindowMode = pGC->subWindowMode;
50305b261ecSmrg}
50405b261ecSmrg
50505b261ecSmrgstatic int
50605b261ecSmrgKdXVRegetVideo(XvPortRecPrivatePtr portPriv)
50705b261ecSmrg{
50835c4bbdfSmrg    RegionRec WinRegion;
50935c4bbdfSmrg    RegionRec ClipRegion;
51035c4bbdfSmrg    BoxRec WinBox;
51135c4bbdfSmrg    int ret = Success;
51235c4bbdfSmrg    Bool clippedAway = FALSE;
51335c4bbdfSmrg
51435c4bbdfSmrg    KdXVUpdateCompositeClip(portPriv);
51535c4bbdfSmrg
51635c4bbdfSmrg    /* translate the video region to the screen */
51735c4bbdfSmrg    WinBox.x1 = portPriv->pDraw->x + portPriv->drw_x;
51835c4bbdfSmrg    WinBox.y1 = portPriv->pDraw->y + portPriv->drw_y;
51935c4bbdfSmrg    WinBox.x2 = WinBox.x1 + portPriv->drw_w;
52035c4bbdfSmrg    WinBox.y2 = WinBox.y1 + portPriv->drw_h;
52135c4bbdfSmrg
52235c4bbdfSmrg    /* clip to the window composite clip */
52335c4bbdfSmrg    RegionInit(&WinRegion, &WinBox, 1);
52435c4bbdfSmrg    RegionInit(&ClipRegion, NullBox, 1);
52535c4bbdfSmrg    RegionIntersect(&ClipRegion, &WinRegion, portPriv->pCompositeClip);
52635c4bbdfSmrg
52735c4bbdfSmrg    /* that's all if it's totally obscured */
52835c4bbdfSmrg    if (!RegionNotEmpty(&ClipRegion)) {
52935c4bbdfSmrg        clippedAway = TRUE;
53035c4bbdfSmrg        goto CLIP_VIDEO_BAILOUT;
53135c4bbdfSmrg    }
53235c4bbdfSmrg
53335c4bbdfSmrg    ret = (*portPriv->AdaptorRec->GetVideo) (portPriv->screen, portPriv->pDraw,
53435c4bbdfSmrg                                             portPriv->vid_x, portPriv->vid_y,
53535c4bbdfSmrg                                             WinBox.x1, WinBox.y1,
53635c4bbdfSmrg                                             portPriv->vid_w, portPriv->vid_h,
53735c4bbdfSmrg                                             portPriv->drw_w, portPriv->drw_h,
53835c4bbdfSmrg                                             &ClipRegion,
53935c4bbdfSmrg                                             portPriv->DevPriv.ptr);
54035c4bbdfSmrg
54135c4bbdfSmrg    if (ret == Success)
54235c4bbdfSmrg        portPriv->isOn = XV_ON;
54335c4bbdfSmrg
54435c4bbdfSmrg CLIP_VIDEO_BAILOUT:
54535c4bbdfSmrg
54635c4bbdfSmrg    if ((clippedAway || (ret != Success)) && portPriv->isOn == XV_ON) {
54735c4bbdfSmrg        (*portPriv->AdaptorRec->StopVideo) (portPriv->screen,
54835c4bbdfSmrg                                            portPriv->DevPriv.ptr, FALSE);
54935c4bbdfSmrg        portPriv->isOn = XV_PENDING;
55035c4bbdfSmrg    }
55135c4bbdfSmrg
55235c4bbdfSmrg    /* This clip was copied and only good for one shot */
55335c4bbdfSmrg    if (!portPriv->FreeCompositeClip)
55435c4bbdfSmrg        portPriv->pCompositeClip = NULL;
55505b261ecSmrg
55635c4bbdfSmrg    RegionUninit(&WinRegion);
55735c4bbdfSmrg    RegionUninit(&ClipRegion);
55835c4bbdfSmrg
55935c4bbdfSmrg    return ret;
56035c4bbdfSmrg}
56105b261ecSmrg
56205b261ecSmrgstatic int
56305b261ecSmrgKdXVReputVideo(XvPortRecPrivatePtr portPriv)
56405b261ecSmrg{
56535c4bbdfSmrg    RegionRec WinRegion;
56635c4bbdfSmrg    RegionRec ClipRegion;
56735c4bbdfSmrg    BoxRec WinBox;
56835c4bbdfSmrg    ScreenPtr pScreen = portPriv->pDraw->pScreen;
56935c4bbdfSmrg
57035c4bbdfSmrg    KdScreenPriv(pScreen);
57135c4bbdfSmrg    KdScreenInfo *screen = pScreenPriv->screen;
57235c4bbdfSmrg    int ret = Success;
57335c4bbdfSmrg    Bool clippedAway = FALSE;
57435c4bbdfSmrg
57535c4bbdfSmrg    KdXVUpdateCompositeClip(portPriv);
57635c4bbdfSmrg
57735c4bbdfSmrg    /* translate the video region to the screen */
57835c4bbdfSmrg    WinBox.x1 = portPriv->pDraw->x + portPriv->drw_x;
57935c4bbdfSmrg    WinBox.y1 = portPriv->pDraw->y + portPriv->drw_y;
58035c4bbdfSmrg    WinBox.x2 = WinBox.x1 + portPriv->drw_w;
58135c4bbdfSmrg    WinBox.y2 = WinBox.y1 + portPriv->drw_h;
58235c4bbdfSmrg
58335c4bbdfSmrg    /* clip to the window composite clip */
58435c4bbdfSmrg    RegionInit(&WinRegion, &WinBox, 1);
58535c4bbdfSmrg    RegionInit(&ClipRegion, NullBox, 1);
58635c4bbdfSmrg    RegionIntersect(&ClipRegion, &WinRegion, portPriv->pCompositeClip);
58735c4bbdfSmrg
58835c4bbdfSmrg    /* clip and translate to the viewport */
58935c4bbdfSmrg    if (portPriv->AdaptorRec->flags & VIDEO_CLIP_TO_VIEWPORT) {
59035c4bbdfSmrg        RegionRec VPReg;
59135c4bbdfSmrg        BoxRec VPBox;
59235c4bbdfSmrg
59335c4bbdfSmrg        VPBox.x1 = 0;
59435c4bbdfSmrg        VPBox.y1 = 0;
59535c4bbdfSmrg        VPBox.x2 = screen->width;
59635c4bbdfSmrg        VPBox.y2 = screen->height;
59735c4bbdfSmrg
59835c4bbdfSmrg        RegionInit(&VPReg, &VPBox, 1);
59935c4bbdfSmrg        RegionIntersect(&ClipRegion, &ClipRegion, &VPReg);
60035c4bbdfSmrg        RegionUninit(&VPReg);
60135c4bbdfSmrg    }
60235c4bbdfSmrg
60335c4bbdfSmrg    /* that's all if it's totally obscured */
60435c4bbdfSmrg    if (!RegionNotEmpty(&ClipRegion)) {
60535c4bbdfSmrg        clippedAway = TRUE;
60635c4bbdfSmrg        goto CLIP_VIDEO_BAILOUT;
60735c4bbdfSmrg    }
60835c4bbdfSmrg
60935c4bbdfSmrg    ret = (*portPriv->AdaptorRec->PutVideo) (portPriv->screen, portPriv->pDraw,
61035c4bbdfSmrg                                             portPriv->vid_x, portPriv->vid_y,
61135c4bbdfSmrg                                             WinBox.x1, WinBox.y1,
61235c4bbdfSmrg                                             portPriv->vid_w, portPriv->vid_h,
61335c4bbdfSmrg                                             portPriv->drw_w, portPriv->drw_h,
61435c4bbdfSmrg                                             &ClipRegion,
61535c4bbdfSmrg                                             portPriv->DevPriv.ptr);
61635c4bbdfSmrg
61735c4bbdfSmrg    if (ret == Success)
61835c4bbdfSmrg        portPriv->isOn = XV_ON;
61935c4bbdfSmrg
62035c4bbdfSmrg CLIP_VIDEO_BAILOUT:
62135c4bbdfSmrg
62235c4bbdfSmrg    if ((clippedAway || (ret != Success)) && (portPriv->isOn == XV_ON)) {
62335c4bbdfSmrg        (*portPriv->AdaptorRec->StopVideo) (portPriv->screen,
62435c4bbdfSmrg                                            portPriv->DevPriv.ptr, FALSE);
62535c4bbdfSmrg        portPriv->isOn = XV_PENDING;
62635c4bbdfSmrg    }
62735c4bbdfSmrg
62835c4bbdfSmrg    /* This clip was copied and only good for one shot */
62935c4bbdfSmrg    if (!portPriv->FreeCompositeClip)
63035c4bbdfSmrg        portPriv->pCompositeClip = NULL;
63135c4bbdfSmrg
63235c4bbdfSmrg    RegionUninit(&WinRegion);
63335c4bbdfSmrg    RegionUninit(&ClipRegion);
63435c4bbdfSmrg
63535c4bbdfSmrg    return ret;
63605b261ecSmrg}
63705b261ecSmrg
63805b261ecSmrgstatic int
63905b261ecSmrgKdXVReputImage(XvPortRecPrivatePtr portPriv)
64005b261ecSmrg{
64135c4bbdfSmrg    RegionRec WinRegion;
64235c4bbdfSmrg    RegionRec ClipRegion;
64335c4bbdfSmrg    BoxRec WinBox;
64435c4bbdfSmrg    ScreenPtr pScreen = portPriv->pDraw->pScreen;
64505b261ecSmrg
64635c4bbdfSmrg    KdScreenPriv(pScreen);
64735c4bbdfSmrg    KdScreenInfo *screen = pScreenPriv->screen;
64835c4bbdfSmrg    int ret = Success;
64935c4bbdfSmrg    Bool clippedAway = FALSE;
65035c4bbdfSmrg
65135c4bbdfSmrg    KdXVUpdateCompositeClip(portPriv);
65235c4bbdfSmrg
65335c4bbdfSmrg    /* translate the video region to the screen */
65435c4bbdfSmrg    WinBox.x1 = portPriv->pDraw->x + portPriv->drw_x;
65535c4bbdfSmrg    WinBox.y1 = portPriv->pDraw->y + portPriv->drw_y;
65635c4bbdfSmrg    WinBox.x2 = WinBox.x1 + portPriv->drw_w;
65735c4bbdfSmrg    WinBox.y2 = WinBox.y1 + portPriv->drw_h;
65835c4bbdfSmrg
65935c4bbdfSmrg    /* clip to the window composite clip */
66035c4bbdfSmrg    RegionInit(&WinRegion, &WinBox, 1);
66135c4bbdfSmrg    RegionInit(&ClipRegion, NullBox, 1);
66235c4bbdfSmrg    RegionIntersect(&ClipRegion, &WinRegion, portPriv->pCompositeClip);
66335c4bbdfSmrg
66435c4bbdfSmrg    /* clip and translate to the viewport */
66535c4bbdfSmrg    if (portPriv->AdaptorRec->flags & VIDEO_CLIP_TO_VIEWPORT) {
66635c4bbdfSmrg        RegionRec VPReg;
66735c4bbdfSmrg        BoxRec VPBox;
66835c4bbdfSmrg
66935c4bbdfSmrg        VPBox.x1 = 0;
67035c4bbdfSmrg        VPBox.y1 = 0;
67135c4bbdfSmrg        VPBox.x2 = screen->width;
67235c4bbdfSmrg        VPBox.y2 = screen->height;
67335c4bbdfSmrg
67435c4bbdfSmrg        RegionInit(&VPReg, &VPBox, 1);
67535c4bbdfSmrg        RegionIntersect(&ClipRegion, &ClipRegion, &VPReg);
67635c4bbdfSmrg        RegionUninit(&VPReg);
67735c4bbdfSmrg    }
67835c4bbdfSmrg
67935c4bbdfSmrg    /* that's all if it's totally obscured */
68035c4bbdfSmrg    if (!RegionNotEmpty(&ClipRegion)) {
68135c4bbdfSmrg        clippedAway = TRUE;
68235c4bbdfSmrg        goto CLIP_VIDEO_BAILOUT;
68335c4bbdfSmrg    }
68435c4bbdfSmrg
68535c4bbdfSmrg    ret =
68635c4bbdfSmrg        (*portPriv->AdaptorRec->ReputImage) (portPriv->screen, portPriv->pDraw,
68735c4bbdfSmrg                                             WinBox.x1, WinBox.y1, &ClipRegion,
68835c4bbdfSmrg                                             portPriv->DevPriv.ptr);
68935c4bbdfSmrg
69035c4bbdfSmrg    portPriv->isOn = (ret == Success) ? XV_ON : XV_OFF;
69135c4bbdfSmrg
69235c4bbdfSmrg CLIP_VIDEO_BAILOUT:
69335c4bbdfSmrg
69435c4bbdfSmrg    if ((clippedAway || (ret != Success)) && (portPriv->isOn == XV_ON)) {
69535c4bbdfSmrg        (*portPriv->AdaptorRec->StopVideo) (portPriv->screen,
69635c4bbdfSmrg                                            portPriv->DevPriv.ptr, FALSE);
69735c4bbdfSmrg        portPriv->isOn = XV_PENDING;
69835c4bbdfSmrg    }
69935c4bbdfSmrg
70035c4bbdfSmrg    /* This clip was copied and only good for one shot */
70135c4bbdfSmrg    if (!portPriv->FreeCompositeClip)
70235c4bbdfSmrg        portPriv->pCompositeClip = NULL;
70335c4bbdfSmrg
70435c4bbdfSmrg    RegionUninit(&WinRegion);
70535c4bbdfSmrg    RegionUninit(&ClipRegion);
70635c4bbdfSmrg
70735c4bbdfSmrg    return ret;
70835c4bbdfSmrg}
70905b261ecSmrg
71005b261ecSmrgstatic int
71105b261ecSmrgKdXVEnlistPortInWindow(WindowPtr pWin, XvPortRecPrivatePtr portPriv)
71205b261ecSmrg{
71335c4bbdfSmrg    KdXVWindowPtr winPriv, PrivRoot;
71435c4bbdfSmrg
71535c4bbdfSmrg    winPriv = PrivRoot = GET_KDXV_WINDOW(pWin);
71635c4bbdfSmrg
71735c4bbdfSmrg    /* Enlist our port in the window private */
71835c4bbdfSmrg    while (winPriv) {
71935c4bbdfSmrg        if (winPriv->PortRec == portPriv)       /* we're already listed */
72035c4bbdfSmrg            break;
72135c4bbdfSmrg        winPriv = winPriv->next;
72235c4bbdfSmrg    }
72305b261ecSmrg
72435c4bbdfSmrg    if (!winPriv) {
72535c4bbdfSmrg        winPriv = malloc(sizeof(KdXVWindowRec));
72635c4bbdfSmrg        if (!winPriv)
72735c4bbdfSmrg            return BadAlloc;
72835c4bbdfSmrg        winPriv->PortRec = portPriv;
72935c4bbdfSmrg        winPriv->next = PrivRoot;
73035c4bbdfSmrg        dixSetPrivate(&pWin->devPrivates, KdXVWindowKey, winPriv);
73135c4bbdfSmrg    }
73235c4bbdfSmrg    return Success;
73335c4bbdfSmrg}
73405b261ecSmrg
73505b261ecSmrgstatic void
73605b261ecSmrgKdXVRemovePortFromWindow(WindowPtr pWin, XvPortRecPrivatePtr portPriv)
73705b261ecSmrg{
73835c4bbdfSmrg    KdXVWindowPtr winPriv, prevPriv = NULL;
73935c4bbdfSmrg
74035c4bbdfSmrg    winPriv = GET_KDXV_WINDOW(pWin);
74135c4bbdfSmrg
74235c4bbdfSmrg    while (winPriv) {
74335c4bbdfSmrg        if (winPriv->PortRec == portPriv) {
74435c4bbdfSmrg            if (prevPriv)
74535c4bbdfSmrg                prevPriv->next = winPriv->next;
74635c4bbdfSmrg            else
74735c4bbdfSmrg                dixSetPrivate(&pWin->devPrivates, KdXVWindowKey, winPriv->next);
74835c4bbdfSmrg            free(winPriv);
74935c4bbdfSmrg            break;
75035c4bbdfSmrg        }
75135c4bbdfSmrg        prevPriv = winPriv;
75235c4bbdfSmrg        winPriv = winPriv->next;
75335c4bbdfSmrg    }
75435c4bbdfSmrg    portPriv->pDraw = NULL;
75505b261ecSmrg}
75605b261ecSmrg
75705b261ecSmrg/****  ScreenRec fields ****/
75805b261ecSmrg
75905b261ecSmrgstatic Bool
76005b261ecSmrgKdXVDestroyWindow(WindowPtr pWin)
76105b261ecSmrg{
76235c4bbdfSmrg    ScreenPtr pScreen = pWin->drawable.pScreen;
76335c4bbdfSmrg    KdXVScreenPtr ScreenPriv = GET_KDXV_SCREEN(pScreen);
76435c4bbdfSmrg    KdXVWindowPtr tmp, WinPriv = GET_KDXV_WINDOW(pWin);
76535c4bbdfSmrg    int ret;
76635c4bbdfSmrg
76735c4bbdfSmrg    while (WinPriv) {
76835c4bbdfSmrg        XvPortRecPrivatePtr pPriv = WinPriv->PortRec;
76935c4bbdfSmrg
77035c4bbdfSmrg        if (pPriv->isOn > XV_OFF) {
77135c4bbdfSmrg            (*pPriv->AdaptorRec->StopVideo) (pPriv->screen, pPriv->DevPriv.ptr,
77235c4bbdfSmrg                                             TRUE);
77335c4bbdfSmrg            pPriv->isOn = XV_OFF;
77435c4bbdfSmrg        }
77535c4bbdfSmrg
77635c4bbdfSmrg        pPriv->pDraw = NULL;
77735c4bbdfSmrg        tmp = WinPriv;
77835c4bbdfSmrg        WinPriv = WinPriv->next;
77935c4bbdfSmrg        free(tmp);
78035c4bbdfSmrg    }
78105b261ecSmrg
78235c4bbdfSmrg    dixSetPrivate(&pWin->devPrivates, KdXVWindowKey, NULL);
78305b261ecSmrg
78435c4bbdfSmrg    pScreen->DestroyWindow = ScreenPriv->DestroyWindow;
78535c4bbdfSmrg    ret = (*pScreen->DestroyWindow) (pWin);
78635c4bbdfSmrg    pScreen->DestroyWindow = KdXVDestroyWindow;
78705b261ecSmrg
78835c4bbdfSmrg    return ret;
78905b261ecSmrg}
79005b261ecSmrg
79105b261ecSmrgstatic void
79235c4bbdfSmrgKdXVWindowExposures(WindowPtr pWin, RegionPtr reg1)
79305b261ecSmrg{
79435c4bbdfSmrg    ScreenPtr pScreen = pWin->drawable.pScreen;
79535c4bbdfSmrg    KdXVScreenPtr ScreenPriv = GET_KDXV_SCREEN(pScreen);
79635c4bbdfSmrg    KdXVWindowPtr WinPriv = GET_KDXV_WINDOW(pWin);
79735c4bbdfSmrg    KdXVWindowPtr pPrev;
79835c4bbdfSmrg    XvPortRecPrivatePtr pPriv;
79935c4bbdfSmrg    Bool AreasExposed;
80035c4bbdfSmrg
80135c4bbdfSmrg    AreasExposed = (WinPriv && reg1 && RegionNotEmpty(reg1));
80235c4bbdfSmrg
80335c4bbdfSmrg    pScreen->WindowExposures = ScreenPriv->WindowExposures;
80435c4bbdfSmrg    (*pScreen->WindowExposures) (pWin, reg1);
80535c4bbdfSmrg    pScreen->WindowExposures = KdXVWindowExposures;
80635c4bbdfSmrg
80735c4bbdfSmrg    /* filter out XClearWindow/Area */
80835c4bbdfSmrg    if (!pWin->valdata)
80935c4bbdfSmrg        return;
81035c4bbdfSmrg
81135c4bbdfSmrg    pPrev = NULL;
81235c4bbdfSmrg
81335c4bbdfSmrg    while (WinPriv) {
81435c4bbdfSmrg        pPriv = WinPriv->PortRec;
81535c4bbdfSmrg
81635c4bbdfSmrg        /* Reput anyone with a reput function */
81735c4bbdfSmrg
81835c4bbdfSmrg        switch (pPriv->type) {
81935c4bbdfSmrg        case XvInputMask:
82035c4bbdfSmrg            KdXVReputVideo(pPriv);
82135c4bbdfSmrg            break;
82235c4bbdfSmrg        case XvOutputMask:
82335c4bbdfSmrg            KdXVRegetVideo(pPriv);
82435c4bbdfSmrg            break;
82535c4bbdfSmrg        default:               /* overlaid still/image */
82635c4bbdfSmrg            if (pPriv->AdaptorRec->ReputImage)
82735c4bbdfSmrg                KdXVReputImage(pPriv);
82835c4bbdfSmrg            else if (AreasExposed) {
82935c4bbdfSmrg                KdXVWindowPtr tmp;
83035c4bbdfSmrg
83135c4bbdfSmrg                if (pPriv->isOn == XV_ON) {
83235c4bbdfSmrg                    (*pPriv->AdaptorRec->StopVideo) (pPriv->screen,
83335c4bbdfSmrg                                                     pPriv->DevPriv.ptr, FALSE);
83435c4bbdfSmrg                    pPriv->isOn = XV_PENDING;
83535c4bbdfSmrg                }
83635c4bbdfSmrg                pPriv->pDraw = NULL;
83735c4bbdfSmrg
83835c4bbdfSmrg                if (!pPrev)
83935c4bbdfSmrg                    dixSetPrivate(&pWin->devPrivates, KdXVWindowKey,
84035c4bbdfSmrg                                  WinPriv->next);
84135c4bbdfSmrg                else
84235c4bbdfSmrg                    pPrev->next = WinPriv->next;
84335c4bbdfSmrg                tmp = WinPriv;
84435c4bbdfSmrg                WinPriv = WinPriv->next;
84535c4bbdfSmrg                free(tmp);
84635c4bbdfSmrg                continue;
84735c4bbdfSmrg            }
84835c4bbdfSmrg            break;
84935c4bbdfSmrg        }
85035c4bbdfSmrg        pPrev = WinPriv;
85135c4bbdfSmrg        WinPriv = WinPriv->next;
85235c4bbdfSmrg    }
85305b261ecSmrg}
85405b261ecSmrg
8556747b715Smrgstatic void
85605b261ecSmrgKdXVClipNotify(WindowPtr pWin, int dx, int dy)
85705b261ecSmrg{
85835c4bbdfSmrg    ScreenPtr pScreen = pWin->drawable.pScreen;
85935c4bbdfSmrg    KdXVScreenPtr ScreenPriv = GET_KDXV_SCREEN(pScreen);
86035c4bbdfSmrg    KdXVWindowPtr WinPriv = GET_KDXV_WINDOW(pWin);
86135c4bbdfSmrg    KdXVWindowPtr tmp, pPrev = NULL;
86235c4bbdfSmrg    XvPortRecPrivatePtr pPriv;
86335c4bbdfSmrg    Bool visible = (pWin->visibility == VisibilityUnobscured) ||
86435c4bbdfSmrg        (pWin->visibility == VisibilityPartiallyObscured);
86535c4bbdfSmrg
86635c4bbdfSmrg    while (WinPriv) {
86735c4bbdfSmrg        pPriv = WinPriv->PortRec;
86835c4bbdfSmrg
86935c4bbdfSmrg        if (pPriv->pCompositeClip && pPriv->FreeCompositeClip)
87035c4bbdfSmrg            RegionDestroy(pPriv->pCompositeClip);
87135c4bbdfSmrg
87235c4bbdfSmrg        pPriv->pCompositeClip = NULL;
87335c4bbdfSmrg
87435c4bbdfSmrg        /* Stop everything except images, but stop them too if the
87535c4bbdfSmrg           window isn't visible.  But we only remove the images. */
87635c4bbdfSmrg
87735c4bbdfSmrg        if (pPriv->type || !visible) {
87835c4bbdfSmrg            if (pPriv->isOn == XV_ON) {
87935c4bbdfSmrg                (*pPriv->AdaptorRec->StopVideo) (pPriv->screen,
88035c4bbdfSmrg                                                 pPriv->DevPriv.ptr, FALSE);
88135c4bbdfSmrg                pPriv->isOn = XV_PENDING;
88235c4bbdfSmrg            }
88335c4bbdfSmrg
88435c4bbdfSmrg            if (!pPriv->type) { /* overlaid still/image */
88535c4bbdfSmrg                pPriv->pDraw = NULL;
88635c4bbdfSmrg
88735c4bbdfSmrg                if (!pPrev)
88835c4bbdfSmrg                    dixSetPrivate(&pWin->devPrivates, KdXVWindowKey,
88935c4bbdfSmrg                                  WinPriv->next);
89035c4bbdfSmrg                else
89135c4bbdfSmrg                    pPrev->next = WinPriv->next;
89235c4bbdfSmrg                tmp = WinPriv;
89335c4bbdfSmrg                WinPriv = WinPriv->next;
89435c4bbdfSmrg                free(tmp);
89535c4bbdfSmrg                continue;
89635c4bbdfSmrg            }
89735c4bbdfSmrg        }
89835c4bbdfSmrg
89935c4bbdfSmrg        pPrev = WinPriv;
90035c4bbdfSmrg        WinPriv = WinPriv->next;
90135c4bbdfSmrg    }
90205b261ecSmrg
90335c4bbdfSmrg    if (ScreenPriv->ClipNotify) {
90435c4bbdfSmrg        pScreen->ClipNotify = ScreenPriv->ClipNotify;
90535c4bbdfSmrg        (*pScreen->ClipNotify) (pWin, dx, dy);
90635c4bbdfSmrg        pScreen->ClipNotify = KdXVClipNotify;
90735c4bbdfSmrg    }
90835c4bbdfSmrg}
90905b261ecSmrg
91005b261ecSmrg/**** Required XvScreenRec fields ****/
91105b261ecSmrg
91205b261ecSmrgstatic Bool
91335c4bbdfSmrgKdXVCloseScreen(ScreenPtr pScreen)
91405b261ecSmrg{
91535c4bbdfSmrg    XvScreenPtr pxvs = GET_XV_SCREEN(pScreen);
91635c4bbdfSmrg    KdXVScreenPtr ScreenPriv = GET_KDXV_SCREEN(pScreen);
91735c4bbdfSmrg    XvAdaptorPtr pa;
91835c4bbdfSmrg    int c;
91905b261ecSmrg
92035c4bbdfSmrg    if (!ScreenPriv)
92135c4bbdfSmrg        return TRUE;
92205b261ecSmrg
92335c4bbdfSmrg    pScreen->DestroyWindow = ScreenPriv->DestroyWindow;
92435c4bbdfSmrg    pScreen->WindowExposures = ScreenPriv->WindowExposures;
92535c4bbdfSmrg    pScreen->ClipNotify = ScreenPriv->ClipNotify;
92635c4bbdfSmrg    pScreen->CloseScreen = ScreenPriv->CloseScreen;
92705b261ecSmrg
92805b261ecSmrg/*   fprintf(stderr,"XV: Unwrapping screen funcs\n"); */
92905b261ecSmrg
93035c4bbdfSmrg    for (c = 0, pa = pxvs->pAdaptors; c < pxvs->nAdaptors; c++, pa++) {
93135c4bbdfSmrg        KdXVFreeAdaptor(pa);
93235c4bbdfSmrg    }
93305b261ecSmrg
93435c4bbdfSmrg    free(pxvs->pAdaptors);
93535c4bbdfSmrg    free(ScreenPriv);
93605b261ecSmrg
93735c4bbdfSmrg    return pScreen->CloseScreen(pScreen);
93805b261ecSmrg}
93905b261ecSmrg
94005b261ecSmrg/**** XvAdaptorRec fields ****/
94105b261ecSmrg
94205b261ecSmrgstatic int
94335c4bbdfSmrgKdXVPutVideo(DrawablePtr pDraw,
94435c4bbdfSmrg             XvPortPtr pPort,
94535c4bbdfSmrg             GCPtr pGC,
94635c4bbdfSmrg             INT16 vid_x, INT16 vid_y,
94735c4bbdfSmrg             CARD16 vid_w, CARD16 vid_h,
94835c4bbdfSmrg             INT16 drw_x, INT16 drw_y, CARD16 drw_w, CARD16 drw_h)
94935c4bbdfSmrg{
95035c4bbdfSmrg    XvPortRecPrivatePtr portPriv = (XvPortRecPrivatePtr) (pPort->devPriv.ptr);
95135c4bbdfSmrg
95235c4bbdfSmrg    KdScreenPriv(portPriv->screen->pScreen);
95335c4bbdfSmrg    int result;
95435c4bbdfSmrg
95535c4bbdfSmrg    /* No dumping video to pixmaps... For now anyhow */
95635c4bbdfSmrg    if (pDraw->type != DRAWABLE_WINDOW) {
95735c4bbdfSmrg        pPort->pDraw = (DrawablePtr) NULL;
95835c4bbdfSmrg        return BadAlloc;
95935c4bbdfSmrg    }
96035c4bbdfSmrg
96135c4bbdfSmrg    /* If we are changing windows, unregister our port in the old window */
96235c4bbdfSmrg    if (portPriv->pDraw && (portPriv->pDraw != pDraw))
96335c4bbdfSmrg        KdXVRemovePortFromWindow((WindowPtr) (portPriv->pDraw), portPriv);
96435c4bbdfSmrg
96535c4bbdfSmrg    /* Register our port with the new window */
96635c4bbdfSmrg    result = KdXVEnlistPortInWindow((WindowPtr) pDraw, portPriv);
96735c4bbdfSmrg    if (result != Success)
96835c4bbdfSmrg        return result;
96935c4bbdfSmrg
97035c4bbdfSmrg    portPriv->pDraw = pDraw;
97135c4bbdfSmrg    portPriv->type = XvInputMask;
97235c4bbdfSmrg
97335c4bbdfSmrg    /* save a copy of these parameters */
97435c4bbdfSmrg    portPriv->vid_x = vid_x;
97535c4bbdfSmrg    portPriv->vid_y = vid_y;
97635c4bbdfSmrg    portPriv->vid_w = vid_w;
97735c4bbdfSmrg    portPriv->vid_h = vid_h;
97835c4bbdfSmrg    portPriv->drw_x = drw_x;
97935c4bbdfSmrg    portPriv->drw_y = drw_y;
98035c4bbdfSmrg    portPriv->drw_w = drw_w;
98135c4bbdfSmrg    portPriv->drw_h = drw_h;
98235c4bbdfSmrg
98335c4bbdfSmrg    /* make sure we have the most recent copy of the clientClip */
98435c4bbdfSmrg    KdXVCopyClip(portPriv, pGC);
98535c4bbdfSmrg
98635c4bbdfSmrg    /* To indicate to the DI layer that we were successful */
98735c4bbdfSmrg    pPort->pDraw = pDraw;
98835c4bbdfSmrg
98935c4bbdfSmrg    if (!pScreenPriv->enabled)
99035c4bbdfSmrg        return Success;
99135c4bbdfSmrg
99235c4bbdfSmrg    return (KdXVReputVideo(portPriv));
99305b261ecSmrg}
99405b261ecSmrg
99505b261ecSmrgstatic int
99635c4bbdfSmrgKdXVPutStill(DrawablePtr pDraw,
99735c4bbdfSmrg             XvPortPtr pPort,
99835c4bbdfSmrg             GCPtr pGC,
99935c4bbdfSmrg             INT16 vid_x, INT16 vid_y,
100035c4bbdfSmrg             CARD16 vid_w, CARD16 vid_h,
100135c4bbdfSmrg             INT16 drw_x, INT16 drw_y, CARD16 drw_w, CARD16 drw_h)
100205b261ecSmrg{
100335c4bbdfSmrg    XvPortRecPrivatePtr portPriv = (XvPortRecPrivatePtr) (pPort->devPriv.ptr);
100435c4bbdfSmrg    ScreenPtr pScreen = pDraw->pScreen;
100505b261ecSmrg
100635c4bbdfSmrg    KdScreenPriv(pScreen);
100735c4bbdfSmrg    KdScreenInfo *screen = pScreenPriv->screen;
100835c4bbdfSmrg    RegionRec WinRegion;
100935c4bbdfSmrg    RegionRec ClipRegion;
101035c4bbdfSmrg    BoxRec WinBox;
101135c4bbdfSmrg    int ret = Success;
101235c4bbdfSmrg    Bool clippedAway = FALSE;
101335c4bbdfSmrg
101435c4bbdfSmrg    if (pDraw->type != DRAWABLE_WINDOW)
101535c4bbdfSmrg        return BadAlloc;
101635c4bbdfSmrg
101735c4bbdfSmrg    if (!pScreenPriv->enabled)
101835c4bbdfSmrg        return Success;
101935c4bbdfSmrg
102035c4bbdfSmrg    WinBox.x1 = pDraw->x + drw_x;
102135c4bbdfSmrg    WinBox.y1 = pDraw->y + drw_y;
102235c4bbdfSmrg    WinBox.x2 = WinBox.x1 + drw_w;
102335c4bbdfSmrg    WinBox.y2 = WinBox.y1 + drw_h;
102435c4bbdfSmrg
102535c4bbdfSmrg    RegionInit(&WinRegion, &WinBox, 1);
102635c4bbdfSmrg    RegionInit(&ClipRegion, NullBox, 1);
102735c4bbdfSmrg    RegionIntersect(&ClipRegion, &WinRegion, pGC->pCompositeClip);
102835c4bbdfSmrg
102935c4bbdfSmrg    if (portPriv->AdaptorRec->flags & VIDEO_CLIP_TO_VIEWPORT) {
103035c4bbdfSmrg        RegionRec VPReg;
103135c4bbdfSmrg        BoxRec VPBox;
103235c4bbdfSmrg
103335c4bbdfSmrg        VPBox.x1 = 0;
103435c4bbdfSmrg        VPBox.y1 = 0;
103535c4bbdfSmrg        VPBox.x2 = screen->width;
103635c4bbdfSmrg        VPBox.y2 = screen->height;
103735c4bbdfSmrg
103835c4bbdfSmrg        RegionInit(&VPReg, &VPBox, 1);
103935c4bbdfSmrg        RegionIntersect(&ClipRegion, &ClipRegion, &VPReg);
104035c4bbdfSmrg        RegionUninit(&VPReg);
104135c4bbdfSmrg    }
104205b261ecSmrg
104335c4bbdfSmrg    if (portPriv->pDraw) {
104435c4bbdfSmrg        KdXVRemovePortFromWindow((WindowPtr) (portPriv->pDraw), portPriv);
104535c4bbdfSmrg    }
104635c4bbdfSmrg
104735c4bbdfSmrg    if (!RegionNotEmpty(&ClipRegion)) {
104835c4bbdfSmrg        clippedAway = TRUE;
104935c4bbdfSmrg        goto PUT_STILL_BAILOUT;
105035c4bbdfSmrg    }
105135c4bbdfSmrg
105235c4bbdfSmrg    ret = (*portPriv->AdaptorRec->PutStill) (portPriv->screen, pDraw,
105335c4bbdfSmrg                                             vid_x, vid_y, WinBox.x1, WinBox.y1,
105435c4bbdfSmrg                                             vid_w, vid_h, drw_w, drw_h,
105535c4bbdfSmrg                                             &ClipRegion,
105635c4bbdfSmrg                                             portPriv->DevPriv.ptr);
105735c4bbdfSmrg
105835c4bbdfSmrg    if ((ret == Success) &&
105935c4bbdfSmrg        (portPriv->AdaptorRec->flags & VIDEO_OVERLAID_STILLS)) {
106035c4bbdfSmrg
106135c4bbdfSmrg        KdXVEnlistPortInWindow((WindowPtr) pDraw, portPriv);
106235c4bbdfSmrg        portPriv->isOn = XV_ON;
106335c4bbdfSmrg        portPriv->pDraw = pDraw;
106435c4bbdfSmrg        portPriv->drw_x = drw_x;
106535c4bbdfSmrg        portPriv->drw_y = drw_y;
106635c4bbdfSmrg        portPriv->drw_w = drw_w;
106735c4bbdfSmrg        portPriv->drw_h = drw_h;
106835c4bbdfSmrg        portPriv->type = 0;     /* no mask means it's transient and should
106935c4bbdfSmrg                                   not be reput once it's removed */
107035c4bbdfSmrg        pPort->pDraw = pDraw;   /* make sure we can get stop requests */
107135c4bbdfSmrg    }
107235c4bbdfSmrg
107335c4bbdfSmrg PUT_STILL_BAILOUT:
107435c4bbdfSmrg
107535c4bbdfSmrg    if ((clippedAway || (ret != Success)) && (portPriv->isOn == XV_ON)) {
107635c4bbdfSmrg        (*portPriv->AdaptorRec->StopVideo) (portPriv->screen,
107735c4bbdfSmrg                                            portPriv->DevPriv.ptr, FALSE);
107805b261ecSmrg        portPriv->isOn = XV_PENDING;
107935c4bbdfSmrg    }
108005b261ecSmrg
108135c4bbdfSmrg    RegionUninit(&WinRegion);
108235c4bbdfSmrg    RegionUninit(&ClipRegion);
108305b261ecSmrg
108435c4bbdfSmrg    return ret;
108505b261ecSmrg}
108605b261ecSmrg
108705b261ecSmrgstatic int
108835c4bbdfSmrgKdXVGetVideo(DrawablePtr pDraw,
108935c4bbdfSmrg             XvPortPtr pPort,
109035c4bbdfSmrg             GCPtr pGC,
109135c4bbdfSmrg             INT16 vid_x, INT16 vid_y,
109235c4bbdfSmrg             CARD16 vid_w, CARD16 vid_h,
109335c4bbdfSmrg             INT16 drw_x, INT16 drw_y, CARD16 drw_w, CARD16 drw_h)
109435c4bbdfSmrg{
109535c4bbdfSmrg    XvPortRecPrivatePtr portPriv = (XvPortRecPrivatePtr) (pPort->devPriv.ptr);
109635c4bbdfSmrg    int result;
109735c4bbdfSmrg
109835c4bbdfSmrg    KdScreenPriv(portPriv->screen->pScreen);
109935c4bbdfSmrg
110035c4bbdfSmrg    /* No pixmaps... For now anyhow */
110135c4bbdfSmrg    if (pDraw->type != DRAWABLE_WINDOW) {
110235c4bbdfSmrg        pPort->pDraw = (DrawablePtr) NULL;
110335c4bbdfSmrg        return BadAlloc;
110435c4bbdfSmrg    }
110535c4bbdfSmrg
110635c4bbdfSmrg    /* If we are changing windows, unregister our port in the old window */
110735c4bbdfSmrg    if (portPriv->pDraw && (portPriv->pDraw != pDraw))
110835c4bbdfSmrg        KdXVRemovePortFromWindow((WindowPtr) (portPriv->pDraw), portPriv);
110935c4bbdfSmrg
111035c4bbdfSmrg    /* Register our port with the new window */
111135c4bbdfSmrg    result = KdXVEnlistPortInWindow((WindowPtr) pDraw, portPriv);
111235c4bbdfSmrg    if (result != Success)
111335c4bbdfSmrg        return result;
111435c4bbdfSmrg
111535c4bbdfSmrg    portPriv->pDraw = pDraw;
111635c4bbdfSmrg    portPriv->type = XvOutputMask;
111735c4bbdfSmrg
111835c4bbdfSmrg    /* save a copy of these parameters */
111935c4bbdfSmrg    portPriv->vid_x = vid_x;
112035c4bbdfSmrg    portPriv->vid_y = vid_y;
112135c4bbdfSmrg    portPriv->vid_w = vid_w;
112235c4bbdfSmrg    portPriv->vid_h = vid_h;
112335c4bbdfSmrg    portPriv->drw_x = drw_x;
112435c4bbdfSmrg    portPriv->drw_y = drw_y;
112535c4bbdfSmrg    portPriv->drw_w = drw_w;
112635c4bbdfSmrg    portPriv->drw_h = drw_h;
112735c4bbdfSmrg
112835c4bbdfSmrg    /* make sure we have the most recent copy of the clientClip */
112935c4bbdfSmrg    KdXVCopyClip(portPriv, pGC);
113035c4bbdfSmrg
113135c4bbdfSmrg    /* To indicate to the DI layer that we were successful */
113235c4bbdfSmrg    pPort->pDraw = pDraw;
113335c4bbdfSmrg
113435c4bbdfSmrg    if (!pScreenPriv->enabled)
113535c4bbdfSmrg        return Success;
113635c4bbdfSmrg
113735c4bbdfSmrg    return (KdXVRegetVideo(portPriv));
113805b261ecSmrg}
113905b261ecSmrg
114005b261ecSmrgstatic int
114135c4bbdfSmrgKdXVGetStill(DrawablePtr pDraw,
114235c4bbdfSmrg             XvPortPtr pPort,
114335c4bbdfSmrg             GCPtr pGC,
114435c4bbdfSmrg             INT16 vid_x, INT16 vid_y,
114535c4bbdfSmrg             CARD16 vid_w, CARD16 vid_h,
114635c4bbdfSmrg             INT16 drw_x, INT16 drw_y, CARD16 drw_w, CARD16 drw_h)
114735c4bbdfSmrg{
114835c4bbdfSmrg    XvPortRecPrivatePtr portPriv = (XvPortRecPrivatePtr) (pPort->devPriv.ptr);
114935c4bbdfSmrg    ScreenPtr pScreen = pDraw->pScreen;
115005b261ecSmrg
115135c4bbdfSmrg    KdScreenPriv(pScreen);
115235c4bbdfSmrg    RegionRec WinRegion;
115335c4bbdfSmrg    RegionRec ClipRegion;
115435c4bbdfSmrg    BoxRec WinBox;
115535c4bbdfSmrg    int ret = Success;
115635c4bbdfSmrg    Bool clippedAway = FALSE;
115705b261ecSmrg
115835c4bbdfSmrg    if (pDraw->type != DRAWABLE_WINDOW)
115935c4bbdfSmrg        return BadAlloc;
116005b261ecSmrg
116135c4bbdfSmrg    if (!pScreenPriv->enabled)
116235c4bbdfSmrg        return Success;
11636747b715Smrg
116435c4bbdfSmrg    WinBox.x1 = pDraw->x + drw_x;
116535c4bbdfSmrg    WinBox.y1 = pDraw->y + drw_y;
116635c4bbdfSmrg    WinBox.x2 = WinBox.x1 + drw_w;
116735c4bbdfSmrg    WinBox.y2 = WinBox.y1 + drw_h;
116805b261ecSmrg
116935c4bbdfSmrg    RegionInit(&WinRegion, &WinBox, 1);
117035c4bbdfSmrg    RegionInit(&ClipRegion, NullBox, 1);
117135c4bbdfSmrg    RegionIntersect(&ClipRegion, &WinRegion, pGC->pCompositeClip);
117205b261ecSmrg
117335c4bbdfSmrg    if (portPriv->pDraw) {
117435c4bbdfSmrg        KdXVRemovePortFromWindow((WindowPtr) (portPriv->pDraw), portPriv);
117535c4bbdfSmrg    }
11766747b715Smrg
117735c4bbdfSmrg    if (!RegionNotEmpty(&ClipRegion)) {
117835c4bbdfSmrg        clippedAway = TRUE;
117935c4bbdfSmrg        goto GET_STILL_BAILOUT;
118035c4bbdfSmrg    }
118105b261ecSmrg
118235c4bbdfSmrg    ret = (*portPriv->AdaptorRec->GetStill) (portPriv->screen, pDraw,
118335c4bbdfSmrg                                             vid_x, vid_y, WinBox.x1, WinBox.y1,
118435c4bbdfSmrg                                             vid_w, vid_h, drw_w, drw_h,
118535c4bbdfSmrg                                             &ClipRegion,
118635c4bbdfSmrg                                             portPriv->DevPriv.ptr);
118705b261ecSmrg
118835c4bbdfSmrg GET_STILL_BAILOUT:
118905b261ecSmrg
119035c4bbdfSmrg    if ((clippedAway || (ret != Success)) && (portPriv->isOn == XV_ON)) {
119135c4bbdfSmrg        (*portPriv->AdaptorRec->StopVideo) (portPriv->screen,
119235c4bbdfSmrg                                            portPriv->DevPriv.ptr, FALSE);
119335c4bbdfSmrg        portPriv->isOn = XV_PENDING;
119435c4bbdfSmrg    }
119505b261ecSmrg
119635c4bbdfSmrg    RegionUninit(&WinRegion);
119735c4bbdfSmrg    RegionUninit(&ClipRegion);
119835c4bbdfSmrg
119935c4bbdfSmrg    return ret;
120005b261ecSmrg}
120105b261ecSmrg
120205b261ecSmrgstatic int
120335c4bbdfSmrgKdXVStopVideo(XvPortPtr pPort, DrawablePtr pDraw)
120435c4bbdfSmrg{
120535c4bbdfSmrg    XvPortRecPrivatePtr portPriv = (XvPortRecPrivatePtr) (pPort->devPriv.ptr);
120605b261ecSmrg
120735c4bbdfSmrg    KdScreenPriv(portPriv->screen->pScreen);
120805b261ecSmrg
120935c4bbdfSmrg    if (pDraw->type != DRAWABLE_WINDOW)
121035c4bbdfSmrg        return BadAlloc;
121135c4bbdfSmrg
121235c4bbdfSmrg    KdXVRemovePortFromWindow((WindowPtr) pDraw, portPriv);
121335c4bbdfSmrg
121435c4bbdfSmrg    if (!pScreenPriv->enabled)
121535c4bbdfSmrg        return Success;
121635c4bbdfSmrg
121735c4bbdfSmrg    /* Must free resources. */
121835c4bbdfSmrg
121935c4bbdfSmrg    if (portPriv->isOn > XV_OFF) {
122035c4bbdfSmrg        (*portPriv->AdaptorRec->StopVideo) (portPriv->screen,
122135c4bbdfSmrg                                            portPriv->DevPriv.ptr, TRUE);
122235c4bbdfSmrg        portPriv->isOn = XV_OFF;
122335c4bbdfSmrg    }
122435c4bbdfSmrg
122535c4bbdfSmrg    return Success;
122605b261ecSmrg}
122705b261ecSmrg
122835c4bbdfSmrgstatic int
122935c4bbdfSmrgKdXVSetPortAttribute(XvPortPtr pPort, Atom attribute, INT32 value)
123035c4bbdfSmrg{
123135c4bbdfSmrg    XvPortRecPrivatePtr portPriv = (XvPortRecPrivatePtr) (pPort->devPriv.ptr);
123205b261ecSmrg
123335c4bbdfSmrg    return ((*portPriv->AdaptorRec->SetPortAttribute) (portPriv->screen,
123435c4bbdfSmrg                                                       attribute, value,
123535c4bbdfSmrg                                                       portPriv->DevPriv.ptr));
123635c4bbdfSmrg}
123705b261ecSmrg
123805b261ecSmrgstatic int
123935c4bbdfSmrgKdXVGetPortAttribute(XvPortPtr pPort, Atom attribute, INT32 *p_value)
124035c4bbdfSmrg{
124135c4bbdfSmrg    XvPortRecPrivatePtr portPriv = (XvPortRecPrivatePtr) (pPort->devPriv.ptr);
124235c4bbdfSmrg
124335c4bbdfSmrg    return ((*portPriv->AdaptorRec->GetPortAttribute) (portPriv->screen,
124435c4bbdfSmrg                                                       attribute,
124535c4bbdfSmrg                                                       (int *) p_value,
124635c4bbdfSmrg                                                       portPriv->DevPriv.ptr));
124705b261ecSmrg}
124805b261ecSmrg
124935c4bbdfSmrgstatic int
125035c4bbdfSmrgKdXVQueryBestSize(XvPortPtr pPort,
125135c4bbdfSmrg                  CARD8 motion,
125235c4bbdfSmrg                  CARD16 vid_w, CARD16 vid_h,
125335c4bbdfSmrg                  CARD16 drw_w, CARD16 drw_h,
125435c4bbdfSmrg                  unsigned int *p_w, unsigned int *p_h)
125535c4bbdfSmrg{
125635c4bbdfSmrg    XvPortRecPrivatePtr portPriv = (XvPortRecPrivatePtr) (pPort->devPriv.ptr);
125735c4bbdfSmrg
125835c4bbdfSmrg    (*portPriv->AdaptorRec->QueryBestSize) (portPriv->screen,
125935c4bbdfSmrg                                            (Bool) motion, vid_w, vid_h, drw_w,
126035c4bbdfSmrg                                            drw_h, p_w, p_h,
126135c4bbdfSmrg                                            portPriv->DevPriv.ptr);
126235c4bbdfSmrg
126335c4bbdfSmrg    return Success;
126435c4bbdfSmrg}
126505b261ecSmrg
12666747b715Smrgstatic int
126735c4bbdfSmrgKdXVPutImage(DrawablePtr pDraw,
126835c4bbdfSmrg             XvPortPtr pPort,
126935c4bbdfSmrg             GCPtr pGC,
127035c4bbdfSmrg             INT16 src_x, INT16 src_y,
127135c4bbdfSmrg             CARD16 src_w, CARD16 src_h,
127235c4bbdfSmrg             INT16 drw_x, INT16 drw_y,
127335c4bbdfSmrg             CARD16 drw_w, CARD16 drw_h,
127435c4bbdfSmrg             XvImagePtr format,
127535c4bbdfSmrg             unsigned char *data, Bool sync, CARD16 width, CARD16 height)
127635c4bbdfSmrg{
127735c4bbdfSmrg    XvPortRecPrivatePtr portPriv = (XvPortRecPrivatePtr) (pPort->devPriv.ptr);
127835c4bbdfSmrg    ScreenPtr pScreen = pDraw->pScreen;
127935c4bbdfSmrg
128035c4bbdfSmrg    KdScreenPriv(pScreen);
128135c4bbdfSmrg    RegionRec WinRegion;
128235c4bbdfSmrg    RegionRec ClipRegion;
128335c4bbdfSmrg    BoxRec WinBox;
128435c4bbdfSmrg    int ret = Success;
128535c4bbdfSmrg    Bool clippedAway = FALSE;
128635c4bbdfSmrg
128735c4bbdfSmrg    if (pDraw->type != DRAWABLE_WINDOW)
128835c4bbdfSmrg        return BadAlloc;
128935c4bbdfSmrg
129035c4bbdfSmrg    if (!pScreenPriv->enabled)
129135c4bbdfSmrg        return Success;
129235c4bbdfSmrg
129335c4bbdfSmrg    WinBox.x1 = pDraw->x + drw_x;
129435c4bbdfSmrg    WinBox.y1 = pDraw->y + drw_y;
129535c4bbdfSmrg    WinBox.x2 = WinBox.x1 + drw_w;
129635c4bbdfSmrg    WinBox.y2 = WinBox.y1 + drw_h;
129735c4bbdfSmrg
129835c4bbdfSmrg    RegionInit(&WinRegion, &WinBox, 1);
129935c4bbdfSmrg    RegionInit(&ClipRegion, NullBox, 1);
130035c4bbdfSmrg    RegionIntersect(&ClipRegion, &WinRegion, pGC->pCompositeClip);
130135c4bbdfSmrg
130235c4bbdfSmrg    if (portPriv->AdaptorRec->flags & VIDEO_CLIP_TO_VIEWPORT) {
130335c4bbdfSmrg        RegionRec VPReg;
130435c4bbdfSmrg        BoxRec VPBox;
130535c4bbdfSmrg
130635c4bbdfSmrg        VPBox.x1 = 0;
130735c4bbdfSmrg        VPBox.y1 = 0;
130835c4bbdfSmrg        VPBox.x2 = pScreen->width;
130935c4bbdfSmrg        VPBox.y2 = pScreen->height;
131035c4bbdfSmrg
131135c4bbdfSmrg        RegionInit(&VPReg, &VPBox, 1);
131235c4bbdfSmrg        RegionIntersect(&ClipRegion, &ClipRegion, &VPReg);
131335c4bbdfSmrg        RegionUninit(&VPReg);
131435c4bbdfSmrg    }
131535c4bbdfSmrg
131635c4bbdfSmrg    if (portPriv->pDraw) {
131735c4bbdfSmrg        KdXVRemovePortFromWindow((WindowPtr) (portPriv->pDraw), portPriv);
131835c4bbdfSmrg    }
131935c4bbdfSmrg
132035c4bbdfSmrg    if (!RegionNotEmpty(&ClipRegion)) {
132135c4bbdfSmrg        clippedAway = TRUE;
132235c4bbdfSmrg        goto PUT_IMAGE_BAILOUT;
132335c4bbdfSmrg    }
132435c4bbdfSmrg
132535c4bbdfSmrg    ret = (*portPriv->AdaptorRec->PutImage) (portPriv->screen, pDraw,
132635c4bbdfSmrg                                             src_x, src_y, WinBox.x1, WinBox.y1,
132735c4bbdfSmrg                                             src_w, src_h, drw_w, drw_h,
132835c4bbdfSmrg                                             format->id, data, width, height,
132935c4bbdfSmrg                                             sync, &ClipRegion,
133035c4bbdfSmrg                                             portPriv->DevPriv.ptr);
133135c4bbdfSmrg
133235c4bbdfSmrg    if ((ret == Success) &&
133335c4bbdfSmrg        (portPriv->AdaptorRec->flags & VIDEO_OVERLAID_IMAGES)) {
133435c4bbdfSmrg
133535c4bbdfSmrg        KdXVEnlistPortInWindow((WindowPtr) pDraw, portPriv);
133635c4bbdfSmrg        portPriv->isOn = XV_ON;
133735c4bbdfSmrg        portPriv->pDraw = pDraw;
133835c4bbdfSmrg        portPriv->drw_x = drw_x;
133935c4bbdfSmrg        portPriv->drw_y = drw_y;
134035c4bbdfSmrg        portPriv->drw_w = drw_w;
134135c4bbdfSmrg        portPriv->drw_h = drw_h;
134235c4bbdfSmrg        portPriv->type = 0;     /* no mask means it's transient and should
134335c4bbdfSmrg                                   not be reput once it's removed */
134435c4bbdfSmrg        pPort->pDraw = pDraw;   /* make sure we can get stop requests */
134535c4bbdfSmrg    }
134635c4bbdfSmrg
134735c4bbdfSmrg PUT_IMAGE_BAILOUT:
134835c4bbdfSmrg
134935c4bbdfSmrg    if ((clippedAway || (ret != Success)) && (portPriv->isOn == XV_ON)) {
135035c4bbdfSmrg        (*portPriv->AdaptorRec->StopVideo) (portPriv->screen,
135135c4bbdfSmrg                                            portPriv->DevPriv.ptr, FALSE);
135205b261ecSmrg        portPriv->isOn = XV_PENDING;
135335c4bbdfSmrg    }
135405b261ecSmrg
135535c4bbdfSmrg    RegionUninit(&WinRegion);
135635c4bbdfSmrg    RegionUninit(&ClipRegion);
135705b261ecSmrg
135835c4bbdfSmrg    return ret;
135905b261ecSmrg}
136005b261ecSmrg
136135c4bbdfSmrgstatic int
136235c4bbdfSmrgKdXVQueryImageAttributes(XvPortPtr pPort,
136335c4bbdfSmrg                         XvImagePtr format,
136435c4bbdfSmrg                         CARD16 *width,
136535c4bbdfSmrg                         CARD16 *height, int *pitches, int *offsets)
136635c4bbdfSmrg{
136735c4bbdfSmrg    XvPortRecPrivatePtr portPriv = (XvPortRecPrivatePtr) (pPort->devPriv.ptr);
136805b261ecSmrg
136935c4bbdfSmrg    return (*portPriv->AdaptorRec->QueryImageAttributes) (portPriv->screen,
137035c4bbdfSmrg                                                          format->id, width,
137135c4bbdfSmrg                                                          height, pitches,
137235c4bbdfSmrg                                                          offsets);
137305b261ecSmrg}
1374