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