105b261ecSmrg/* 205b261ecSmrg * XFree86 Xv DDX written by Mark Vojkovich (markv@valinux.com) 305b261ecSmrg */ 405b261ecSmrg/* 505b261ecSmrg * Copyright (c) 1998-2003 by The XFree86 Project, Inc. 605b261ecSmrg * 705b261ecSmrg * Permission is hereby granted, free of charge, to any person obtaining a 805b261ecSmrg * copy of this software and associated documentation files (the "Software"), 905b261ecSmrg * to deal in the Software without restriction, including without limitation 1005b261ecSmrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 1105b261ecSmrg * and/or sell copies of the Software, and to permit persons to whom the 1205b261ecSmrg * Software is furnished to do so, subject to the following conditions: 1305b261ecSmrg * 1405b261ecSmrg * The above copyright notice and this permission notice shall be included in 1505b261ecSmrg * all copies or substantial portions of the Software. 1605b261ecSmrg * 1705b261ecSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 1805b261ecSmrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 1905b261ecSmrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 2005b261ecSmrg * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 2105b261ecSmrg * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 2205b261ecSmrg * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 2305b261ecSmrg * OTHER DEALINGS IN THE SOFTWARE. 2405b261ecSmrg * 2505b261ecSmrg * Except as contained in this notice, the name of the copyright holder(s) 2605b261ecSmrg * and author(s) shall not be used in advertising or otherwise to promote 2705b261ecSmrg * the sale, use or other dealings in this Software without prior written 2805b261ecSmrg * authorization from the copyright holder(s) and author(s). 2905b261ecSmrg */ 3005b261ecSmrg 3105b261ecSmrg#ifdef HAVE_XORG_CONFIG_H 3205b261ecSmrg#include <xorg-config.h> 3305b261ecSmrg#endif 3405b261ecSmrg 3505b261ecSmrg#include "misc.h" 3605b261ecSmrg#include "xf86.h" 3705b261ecSmrg#include "xf86_OSproc.h" 3805b261ecSmrg 3905b261ecSmrg#include <X11/X.h> 4005b261ecSmrg#include <X11/Xproto.h> 4105b261ecSmrg#include "scrnintstr.h" 4205b261ecSmrg#include "regionstr.h" 4305b261ecSmrg#include "windowstr.h" 4405b261ecSmrg#include "pixmapstr.h" 4505b261ecSmrg#include "mivalidate.h" 4605b261ecSmrg#include "validate.h" 4705b261ecSmrg#include "resource.h" 4805b261ecSmrg#include "gcstruct.h" 4905b261ecSmrg#include "dixstruct.h" 5005b261ecSmrg 5105b261ecSmrg#include <X11/extensions/Xv.h> 5205b261ecSmrg#include <X11/extensions/Xvproto.h> 5305b261ecSmrg#include "xvdix.h" 5405b261ecSmrg 5505b261ecSmrg#include "xf86xvpriv.h" 5605b261ecSmrg 5705b261ecSmrg/* XvAdaptorRec fields */ 5805b261ecSmrg 5935c4bbdfSmrgstatic int xf86XVPutVideo(DrawablePtr, XvPortPtr, GCPtr, 6035c4bbdfSmrg INT16, INT16, CARD16, CARD16, 6135c4bbdfSmrg INT16, INT16, CARD16, CARD16); 6235c4bbdfSmrgstatic int xf86XVPutStill(DrawablePtr, XvPortPtr, GCPtr, 6335c4bbdfSmrg INT16, INT16, CARD16, CARD16, 6435c4bbdfSmrg INT16, INT16, CARD16, CARD16); 6535c4bbdfSmrgstatic int xf86XVGetVideo(DrawablePtr, XvPortPtr, GCPtr, 6635c4bbdfSmrg INT16, INT16, CARD16, CARD16, 6735c4bbdfSmrg INT16, INT16, CARD16, CARD16); 6835c4bbdfSmrgstatic int xf86XVGetStill(DrawablePtr, XvPortPtr, GCPtr, 6935c4bbdfSmrg INT16, INT16, CARD16, CARD16, 7035c4bbdfSmrg INT16, INT16, CARD16, CARD16); 7135c4bbdfSmrgstatic int xf86XVStopVideo(XvPortPtr, DrawablePtr); 7235c4bbdfSmrgstatic int xf86XVSetPortAttribute(XvPortPtr, Atom, INT32); 7335c4bbdfSmrgstatic int xf86XVGetPortAttribute(XvPortPtr, Atom, INT32 *); 7435c4bbdfSmrgstatic int xf86XVQueryBestSize(XvPortPtr, CARD8, 7535c4bbdfSmrg CARD16, CARD16, CARD16, CARD16, 7635c4bbdfSmrg unsigned int *, unsigned int *); 7735c4bbdfSmrgstatic int xf86XVPutImage(DrawablePtr, XvPortPtr, GCPtr, 7835c4bbdfSmrg INT16, INT16, CARD16, CARD16, 7935c4bbdfSmrg INT16, INT16, CARD16, CARD16, 8035c4bbdfSmrg XvImagePtr, unsigned char *, Bool, CARD16, CARD16); 8135c4bbdfSmrgstatic int xf86XVQueryImageAttributes(XvPortPtr, XvImagePtr, 8235c4bbdfSmrg CARD16 *, CARD16 *, int *, int *); 8305b261ecSmrg 8405b261ecSmrg/* ScreenRec fields */ 8505b261ecSmrg 8605b261ecSmrgstatic Bool xf86XVDestroyWindow(WindowPtr pWin); 8735c4bbdfSmrgstatic void xf86XVWindowExposures(WindowPtr pWin, RegionPtr r1); 8835c4bbdfSmrgstatic void xf86XVPostValidateTree(WindowPtr pWin, WindowPtr pLayerWin, 8935c4bbdfSmrg VTKind kind); 9005b261ecSmrgstatic void xf86XVClipNotify(WindowPtr pWin, int dx, int dy); 9135c4bbdfSmrgstatic Bool xf86XVCloseScreen(ScreenPtr); 9205b261ecSmrg 939ace9065Smrg#define PostValidateTreeUndefined ((PostValidateTreeProcPtr)-1) 949ace9065Smrg 9505b261ecSmrg/* ScrnInfoRec functions */ 9605b261ecSmrg 9735c4bbdfSmrgstatic Bool xf86XVEnterVT(ScrnInfoPtr); 9835c4bbdfSmrgstatic void xf86XVLeaveVT(ScrnInfoPtr); 9935c4bbdfSmrgstatic void xf86XVAdjustFrame(ScrnInfoPtr, int x, int y); 1009ace9065Smrgstatic void xf86XVModeSet(ScrnInfoPtr pScrn); 10105b261ecSmrg 10205b261ecSmrg/* misc */ 10305b261ecSmrg 10435c4bbdfSmrgstatic Bool xf86XVInitAdaptors(ScreenPtr, XF86VideoAdaptorPtr *, int); 10505b261ecSmrg 1066747b715Smrgstatic DevPrivateKeyRec XF86XVWindowKeyRec; 10735c4bbdfSmrg 1086747b715Smrg#define XF86XVWindowKey (&XF86XVWindowKeyRec) 1096747b715Smrg 11035c4bbdfSmrg/* dixmain.c XvScreenPtr screen private */ 1116747b715SmrgDevPrivateKey XF86XvScreenKey; 11235c4bbdfSmrg/** xf86xv.c XF86XVScreenPtr screen private */ 11335c4bbdfSmrgstatic DevPrivateKeyRec XF86XVScreenPrivateKey; 1146747b715Smrg 11505b261ecSmrgstatic unsigned long PortResource = 0; 11605b261ecSmrg 11705b261ecSmrg#define GET_XV_SCREEN(pScreen) \ 1184642e01fSmrg ((XvScreenPtr)dixLookupPrivate(&(pScreen)->devPrivates, XF86XvScreenKey)) 11905b261ecSmrg 12005b261ecSmrg#define GET_XF86XV_SCREEN(pScreen) \ 12135c4bbdfSmrg ((XF86XVScreenPtr)(dixGetPrivate(&pScreen->devPrivates, &XF86XVScreenPrivateKey))) 12205b261ecSmrg 12305b261ecSmrg#define GET_XF86XV_WINDOW(pWin) \ 1244642e01fSmrg ((XF86XVWindowPtr)dixLookupPrivate(&(pWin)->devPrivates, XF86XVWindowKey)) 12505b261ecSmrg 12605b261ecSmrgstatic xf86XVInitGenericAdaptorPtr *GenDrivers = NULL; 12705b261ecSmrgstatic int NumGenDrivers = 0; 12805b261ecSmrg 1296747b715Smrgint 13035c4bbdfSmrgxf86XVRegisterGenericAdaptorDriver(xf86XVInitGenericAdaptorPtr InitFunc) 13135c4bbdfSmrg{ 13235c4bbdfSmrg xf86XVInitGenericAdaptorPtr *newdrivers; 13305b261ecSmrg 13435c4bbdfSmrg newdrivers = reallocarray(GenDrivers, 1 + NumGenDrivers, 13535c4bbdfSmrg sizeof(xf86XVInitGenericAdaptorPtr)); 13635c4bbdfSmrg if (!newdrivers) 13735c4bbdfSmrg return 0; 13835c4bbdfSmrg GenDrivers = newdrivers; 13905b261ecSmrg 14035c4bbdfSmrg GenDrivers[NumGenDrivers++] = InitFunc; 14105b261ecSmrg 14235c4bbdfSmrg return 1; 14305b261ecSmrg} 14405b261ecSmrg 1456747b715Smrgint 14635c4bbdfSmrgxf86XVListGenericAdaptors(ScrnInfoPtr pScrn, XF86VideoAdaptorPtr ** adaptors) 14735c4bbdfSmrg{ 14835c4bbdfSmrg int i, j, n, num; 14935c4bbdfSmrg XF86VideoAdaptorPtr *DrivAdap, *new; 15005b261ecSmrg 15105b261ecSmrg num = 0; 15205b261ecSmrg *adaptors = NULL; 15305b261ecSmrg /* 15405b261ecSmrg * The v4l driver registers itself first, but can use surfaces registered 15505b261ecSmrg * by other drivers. So, call the v4l driver last. 15605b261ecSmrg */ 15735c4bbdfSmrg for (i = NumGenDrivers; --i >= 0;) { 15835c4bbdfSmrg DrivAdap = NULL; 15935c4bbdfSmrg n = (*GenDrivers[i]) (pScrn, &DrivAdap); 16035c4bbdfSmrg if (0 == n) 16135c4bbdfSmrg continue; 16235c4bbdfSmrg new = reallocarray(*adaptors, num + n, sizeof(XF86VideoAdaptorPtr)); 16335c4bbdfSmrg if (NULL == new) 16435c4bbdfSmrg continue; 16535c4bbdfSmrg *adaptors = new; 16635c4bbdfSmrg for (j = 0; j < n; j++, num++) 16735c4bbdfSmrg (*adaptors)[num] = DrivAdap[j]; 16805b261ecSmrg } 16905b261ecSmrg return num; 17005b261ecSmrg} 17105b261ecSmrg 17205b261ecSmrg/**************** Offscreen surface stuff *******************/ 17305b261ecSmrg 17405b261ecSmrgtypedef struct { 17535c4bbdfSmrg XF86OffscreenImagePtr images; 17635c4bbdfSmrg int num; 17705b261ecSmrg} OffscreenImageRec; 17805b261ecSmrg 1796747b715Smrgstatic DevPrivateKeyRec OffscreenPrivateKeyRec; 18035c4bbdfSmrg 1816747b715Smrg#define OffscreenPrivateKey (&OffscreenPrivateKeyRec) 1826747b715Smrg#define GetOffscreenImage(pScreen) ((OffscreenImageRec *) dixLookupPrivate(&(pScreen)->devPrivates, OffscreenPrivateKey)) 18305b261ecSmrg 1846747b715SmrgBool 18535c4bbdfSmrgxf86XVRegisterOffscreenImages(ScreenPtr pScreen, 18635c4bbdfSmrg XF86OffscreenImagePtr images, int num) 18735c4bbdfSmrg{ 1886747b715Smrg OffscreenImageRec *OffscreenImage; 18935c4bbdfSmrg 1906747b715Smrg /* This function may be called before xf86XVScreenInit, so there's 1916747b715Smrg * no better place than this to call dixRegisterPrivateKey to ensure we 1926747b715Smrg * have space reserved. After the first call it is a no-op. */ 19335c4bbdfSmrg if (!dixRegisterPrivateKey 19435c4bbdfSmrg (OffscreenPrivateKey, PRIVATE_SCREEN, sizeof(OffscreenImageRec)) || 19535c4bbdfSmrg !(OffscreenImage = GetOffscreenImage(pScreen))) 1966747b715Smrg /* Every X.org driver assumes this function always succeeds, so 1976747b715Smrg * just die on allocation failure. */ 19835c4bbdfSmrg FatalError 19935c4bbdfSmrg ("Could not allocate private storage for XV offscreen images.\n"); 2006747b715Smrg 2016747b715Smrg OffscreenImage->num = num; 2026747b715Smrg OffscreenImage->images = images; 20305b261ecSmrg return TRUE; 20405b261ecSmrg} 20505b261ecSmrg 2066747b715SmrgXF86OffscreenImagePtr 20735c4bbdfSmrgxf86XVQueryOffscreenImages(ScreenPtr pScreen, int *num) 20835c4bbdfSmrg{ 2096747b715Smrg OffscreenImageRec *OffscreenImage = GetOffscreenImage(pScreen); 21035c4bbdfSmrg 2116747b715Smrg *num = OffscreenImage->num; 2126747b715Smrg return OffscreenImage->images; 21305b261ecSmrg} 21405b261ecSmrg 2156747b715SmrgXF86VideoAdaptorPtr 21605b261ecSmrgxf86XVAllocateVideoAdaptorRec(ScrnInfoPtr pScrn) 21705b261ecSmrg{ 2186747b715Smrg return calloc(1, sizeof(XF86VideoAdaptorRec)); 21905b261ecSmrg} 22005b261ecSmrg 2216747b715Smrgvoid 22205b261ecSmrgxf86XVFreeVideoAdaptorRec(XF86VideoAdaptorPtr ptr) 22305b261ecSmrg{ 2246747b715Smrg free(ptr); 22505b261ecSmrg} 22605b261ecSmrg 2276747b715SmrgBool 22835c4bbdfSmrgxf86XVScreenInit(ScreenPtr pScreen, XF86VideoAdaptorPtr * adaptors, int num) 22935c4bbdfSmrg{ 23035c4bbdfSmrg ScrnInfoPtr pScrn; 23135c4bbdfSmrg XF86XVScreenPtr ScreenPriv; 2326747b715Smrg 23335c4bbdfSmrg if (num <= 0 || noXvExtension) 23435c4bbdfSmrg return FALSE; 23505b261ecSmrg 23635c4bbdfSmrg if (Success != XvScreenInit(pScreen)) 23735c4bbdfSmrg return FALSE; 23805b261ecSmrg 23935c4bbdfSmrg if (!dixRegisterPrivateKey(&XF86XVWindowKeyRec, PRIVATE_WINDOW, 0)) 24035c4bbdfSmrg return FALSE; 24135c4bbdfSmrg if (!dixRegisterPrivateKey(&XF86XVScreenPrivateKey, PRIVATE_SCREEN, 0)) 24235c4bbdfSmrg return FALSE; 24305b261ecSmrg 24435c4bbdfSmrg XF86XvScreenKey = XvGetScreenKey(); 24505b261ecSmrg 24635c4bbdfSmrg PortResource = XvGetRTPort(); 24705b261ecSmrg 24835c4bbdfSmrg ScreenPriv = malloc(sizeof(XF86XVScreenRec)); 24935c4bbdfSmrg dixSetPrivate(&pScreen->devPrivates, &XF86XVScreenPrivateKey, ScreenPriv); 25005b261ecSmrg 25135c4bbdfSmrg if (!ScreenPriv) 25235c4bbdfSmrg return FALSE; 25305b261ecSmrg 25435c4bbdfSmrg pScrn = xf86ScreenToScrn(pScreen); 25505b261ecSmrg 25635c4bbdfSmrg ScreenPriv->DestroyWindow = pScreen->DestroyWindow; 25735c4bbdfSmrg ScreenPriv->WindowExposures = pScreen->WindowExposures; 25835c4bbdfSmrg ScreenPriv->PostValidateTree = PostValidateTreeUndefined; 25935c4bbdfSmrg ScreenPriv->ClipNotify = pScreen->ClipNotify; 26035c4bbdfSmrg ScreenPriv->CloseScreen = pScreen->CloseScreen; 26135c4bbdfSmrg ScreenPriv->EnterVT = pScrn->EnterVT; 26235c4bbdfSmrg ScreenPriv->LeaveVT = pScrn->LeaveVT; 26335c4bbdfSmrg ScreenPriv->AdjustFrame = pScrn->AdjustFrame; 26435c4bbdfSmrg ScreenPriv->ModeSet = pScrn->ModeSet; 26505b261ecSmrg 26635c4bbdfSmrg pScreen->DestroyWindow = xf86XVDestroyWindow; 26735c4bbdfSmrg pScreen->WindowExposures = xf86XVWindowExposures; 26835c4bbdfSmrg pScreen->ClipNotify = xf86XVClipNotify; 26935c4bbdfSmrg pScreen->CloseScreen = xf86XVCloseScreen; 27035c4bbdfSmrg pScrn->EnterVT = xf86XVEnterVT; 27135c4bbdfSmrg pScrn->LeaveVT = xf86XVLeaveVT; 27235c4bbdfSmrg if (pScrn->AdjustFrame) 27335c4bbdfSmrg pScrn->AdjustFrame = xf86XVAdjustFrame; 27435c4bbdfSmrg pScrn->ModeSet = xf86XVModeSet; 27505b261ecSmrg 27635c4bbdfSmrg if (!xf86XVInitAdaptors(pScreen, adaptors, num)) 27735c4bbdfSmrg return FALSE; 27805b261ecSmrg 27935c4bbdfSmrg return TRUE; 28005b261ecSmrg} 28105b261ecSmrg 28205b261ecSmrgstatic void 28305b261ecSmrgxf86XVFreeAdaptor(XvAdaptorPtr pAdaptor) 28405b261ecSmrg{ 28535c4bbdfSmrg int i; 28635c4bbdfSmrg 28735c4bbdfSmrg if (pAdaptor->pPorts) { 28835c4bbdfSmrg XvPortPtr pPort = pAdaptor->pPorts; 28935c4bbdfSmrg XvPortRecPrivatePtr pPriv; 29035c4bbdfSmrg 29135c4bbdfSmrg for (i = 0; i < pAdaptor->nPorts; i++, pPort++) { 29235c4bbdfSmrg pPriv = (XvPortRecPrivatePtr) pPort->devPriv.ptr; 29335c4bbdfSmrg if (pPriv) { 29435c4bbdfSmrg if (pPriv->clientClip) 29535c4bbdfSmrg RegionDestroy(pPriv->clientClip); 29635c4bbdfSmrg if (pPriv->pCompositeClip && pPriv->FreeCompositeClip) 29735c4bbdfSmrg RegionDestroy(pPriv->pCompositeClip); 29835c4bbdfSmrg if (pPriv->ckeyFilled) 29935c4bbdfSmrg RegionDestroy(pPriv->ckeyFilled); 30035c4bbdfSmrg free(pPriv); 30135c4bbdfSmrg } 30235c4bbdfSmrg } 30335c4bbdfSmrg } 30435c4bbdfSmrg 30535c4bbdfSmrg XvFreeAdaptor(pAdaptor); 30605b261ecSmrg} 30705b261ecSmrg 30805b261ecSmrgstatic Bool 30935c4bbdfSmrgxf86XVInitAdaptors(ScreenPtr pScreen, XF86VideoAdaptorPtr * infoPtr, int number) 31035c4bbdfSmrg{ 31135c4bbdfSmrg XvScreenPtr pxvs = GET_XV_SCREEN(pScreen); 31235c4bbdfSmrg ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 31335c4bbdfSmrg XF86VideoAdaptorPtr adaptorPtr; 31435c4bbdfSmrg XvAdaptorPtr pAdaptor, pa; 31535c4bbdfSmrg XvAdaptorRecPrivatePtr adaptorPriv; 31635c4bbdfSmrg int na, numAdaptor; 31735c4bbdfSmrg XvPortRecPrivatePtr portPriv; 31835c4bbdfSmrg XvPortPtr pPort, pp; 31935c4bbdfSmrg int numPort; 32035c4bbdfSmrg XF86VideoFormatPtr formatPtr; 32135c4bbdfSmrg XvFormatPtr pFormat, pf; 32235c4bbdfSmrg int numFormat, totFormat; 32335c4bbdfSmrg XF86VideoEncodingPtr encodingPtr; 32435c4bbdfSmrg XvEncodingPtr pEncode, pe; 32535c4bbdfSmrg int numVisuals; 32635c4bbdfSmrg VisualPtr pVisual; 32735c4bbdfSmrg int i; 32835c4bbdfSmrg 32935c4bbdfSmrg pxvs->nAdaptors = 0; 33035c4bbdfSmrg pxvs->pAdaptors = NULL; 33135c4bbdfSmrg 33235c4bbdfSmrg if (!(pAdaptor = calloc(number, sizeof(XvAdaptorRec)))) 33335c4bbdfSmrg return FALSE; 33435c4bbdfSmrg 33535c4bbdfSmrg for (pa = pAdaptor, na = 0, numAdaptor = 0; na < number; na++, adaptorPtr++) { 33635c4bbdfSmrg adaptorPtr = infoPtr[na]; 33735c4bbdfSmrg 33835c4bbdfSmrg if (!adaptorPtr->StopVideo || !adaptorPtr->SetPortAttribute || 33935c4bbdfSmrg !adaptorPtr->GetPortAttribute || !adaptorPtr->QueryBestSize) 34035c4bbdfSmrg continue; 34135c4bbdfSmrg 34235c4bbdfSmrg /* client libs expect at least one encoding */ 34335c4bbdfSmrg if (!adaptorPtr->nEncodings || !adaptorPtr->pEncodings) 34435c4bbdfSmrg continue; 34535c4bbdfSmrg 34635c4bbdfSmrg pa->type = adaptorPtr->type; 34735c4bbdfSmrg 34835c4bbdfSmrg if (!adaptorPtr->PutVideo && !adaptorPtr->GetVideo) 34935c4bbdfSmrg pa->type &= ~XvVideoMask; 35035c4bbdfSmrg 35135c4bbdfSmrg if (!adaptorPtr->PutStill && !adaptorPtr->GetStill) 35235c4bbdfSmrg pa->type &= ~XvStillMask; 35335c4bbdfSmrg 35435c4bbdfSmrg if (!adaptorPtr->PutImage || !adaptorPtr->QueryImageAttributes) 35535c4bbdfSmrg pa->type &= ~XvImageMask; 35635c4bbdfSmrg 35735c4bbdfSmrg if (!adaptorPtr->PutVideo && !adaptorPtr->PutImage && 35835c4bbdfSmrg !adaptorPtr->PutStill) 35935c4bbdfSmrg pa->type &= ~XvInputMask; 36035c4bbdfSmrg 36135c4bbdfSmrg if (!adaptorPtr->GetVideo && !adaptorPtr->GetStill) 36235c4bbdfSmrg pa->type &= ~XvOutputMask; 36335c4bbdfSmrg 36435c4bbdfSmrg if (!(adaptorPtr->type & (XvPixmapMask | XvWindowMask))) 36535c4bbdfSmrg continue; 36635c4bbdfSmrg if (!(adaptorPtr->type & (XvImageMask | XvVideoMask | XvStillMask))) 36735c4bbdfSmrg continue; 36835c4bbdfSmrg 36935c4bbdfSmrg pa->pScreen = pScreen; 37035c4bbdfSmrg pa->ddPutVideo = xf86XVPutVideo; 37135c4bbdfSmrg pa->ddPutStill = xf86XVPutStill; 37235c4bbdfSmrg pa->ddGetVideo = xf86XVGetVideo; 37335c4bbdfSmrg pa->ddGetStill = xf86XVGetStill; 37435c4bbdfSmrg pa->ddStopVideo = xf86XVStopVideo; 37535c4bbdfSmrg pa->ddPutImage = xf86XVPutImage; 37635c4bbdfSmrg pa->ddSetPortAttribute = xf86XVSetPortAttribute; 37735c4bbdfSmrg pa->ddGetPortAttribute = xf86XVGetPortAttribute; 37835c4bbdfSmrg pa->ddQueryBestSize = xf86XVQueryBestSize; 37935c4bbdfSmrg pa->ddQueryImageAttributes = xf86XVQueryImageAttributes; 38035c4bbdfSmrg pa->name = strdup(adaptorPtr->name); 38135c4bbdfSmrg 38235c4bbdfSmrg if (adaptorPtr->nEncodings && 38335c4bbdfSmrg (pEncode = calloc(adaptorPtr->nEncodings, sizeof(XvEncodingRec)))) { 38435c4bbdfSmrg 38535c4bbdfSmrg for (pe = pEncode, encodingPtr = adaptorPtr->pEncodings, i = 0; 38635c4bbdfSmrg i < adaptorPtr->nEncodings; pe++, i++, encodingPtr++) { 38735c4bbdfSmrg pe->id = encodingPtr->id; 38835c4bbdfSmrg pe->pScreen = pScreen; 38935c4bbdfSmrg pe->name = strdup(encodingPtr->name); 39035c4bbdfSmrg pe->width = encodingPtr->width; 39135c4bbdfSmrg pe->height = encodingPtr->height; 39235c4bbdfSmrg pe->rate.numerator = encodingPtr->rate.numerator; 39335c4bbdfSmrg pe->rate.denominator = encodingPtr->rate.denominator; 39435c4bbdfSmrg } 39535c4bbdfSmrg pa->nEncodings = adaptorPtr->nEncodings; 39635c4bbdfSmrg pa->pEncodings = pEncode; 39735c4bbdfSmrg } 39835c4bbdfSmrg 39935c4bbdfSmrg if (adaptorPtr->nImages && 40035c4bbdfSmrg (pa->pImages = calloc(adaptorPtr->nImages, sizeof(XvImageRec)))) { 40135c4bbdfSmrg memcpy(pa->pImages, adaptorPtr->pImages, 40235c4bbdfSmrg adaptorPtr->nImages * sizeof(XvImageRec)); 40335c4bbdfSmrg pa->nImages = adaptorPtr->nImages; 40435c4bbdfSmrg } 40535c4bbdfSmrg 40635c4bbdfSmrg if (adaptorPtr->nAttributes && 40735c4bbdfSmrg (pa->pAttributes = calloc(adaptorPtr->nAttributes, 40835c4bbdfSmrg sizeof(XvAttributeRec)))) { 40935c4bbdfSmrg memcpy(pa->pAttributes, adaptorPtr->pAttributes, 41035c4bbdfSmrg adaptorPtr->nAttributes * sizeof(XvAttributeRec)); 41135c4bbdfSmrg 41235c4bbdfSmrg for (i = 0; i < adaptorPtr->nAttributes; i++) { 41335c4bbdfSmrg pa->pAttributes[i].name = 41435c4bbdfSmrg strdup(adaptorPtr->pAttributes[i].name); 41535c4bbdfSmrg } 41635c4bbdfSmrg 41735c4bbdfSmrg pa->nAttributes = adaptorPtr->nAttributes; 41835c4bbdfSmrg } 41935c4bbdfSmrg 42035c4bbdfSmrg totFormat = adaptorPtr->nFormats; 42135c4bbdfSmrg 42235c4bbdfSmrg if (!(pFormat = calloc(totFormat, sizeof(XvFormatRec)))) { 42335c4bbdfSmrg xf86XVFreeAdaptor(pa); 42435c4bbdfSmrg continue; 42535c4bbdfSmrg } 42635c4bbdfSmrg for (pf = pFormat, i = 0, numFormat = 0, formatPtr = 42735c4bbdfSmrg adaptorPtr->pFormats; i < adaptorPtr->nFormats; i++, formatPtr++) { 42835c4bbdfSmrg numVisuals = pScreen->numVisuals; 42935c4bbdfSmrg pVisual = pScreen->visuals; 43035c4bbdfSmrg 43135c4bbdfSmrg while (numVisuals--) { 43235c4bbdfSmrg if ((pVisual->class == formatPtr->class) && 43335c4bbdfSmrg (pVisual->nplanes == formatPtr->depth)) { 43435c4bbdfSmrg 43535c4bbdfSmrg if (numFormat >= totFormat) { 43635c4bbdfSmrg void *moreSpace; 43735c4bbdfSmrg 43835c4bbdfSmrg totFormat *= 2; 43935c4bbdfSmrg moreSpace = reallocarray(pFormat, totFormat, 44035c4bbdfSmrg sizeof(XvFormatRec)); 44135c4bbdfSmrg if (!moreSpace) 44235c4bbdfSmrg break; 44335c4bbdfSmrg pFormat = moreSpace; 44435c4bbdfSmrg pf = pFormat + numFormat; 44535c4bbdfSmrg } 44635c4bbdfSmrg 44735c4bbdfSmrg pf->visual = pVisual->vid; 44835c4bbdfSmrg pf->depth = formatPtr->depth; 44935c4bbdfSmrg 45035c4bbdfSmrg pf++; 45135c4bbdfSmrg numFormat++; 45235c4bbdfSmrg } 45335c4bbdfSmrg pVisual++; 45435c4bbdfSmrg } 45535c4bbdfSmrg } 45635c4bbdfSmrg pa->nFormats = numFormat; 45735c4bbdfSmrg pa->pFormats = pFormat; 45835c4bbdfSmrg if (!numFormat) { 45935c4bbdfSmrg xf86XVFreeAdaptor(pa); 46035c4bbdfSmrg continue; 46135c4bbdfSmrg } 46235c4bbdfSmrg 46335c4bbdfSmrg if (!(adaptorPriv = calloc(1, sizeof(XvAdaptorRecPrivate)))) { 46435c4bbdfSmrg xf86XVFreeAdaptor(pa); 46535c4bbdfSmrg continue; 46635c4bbdfSmrg } 46735c4bbdfSmrg 46835c4bbdfSmrg adaptorPriv->flags = adaptorPtr->flags; 46935c4bbdfSmrg adaptorPriv->PutVideo = adaptorPtr->PutVideo; 47035c4bbdfSmrg adaptorPriv->PutStill = adaptorPtr->PutStill; 47135c4bbdfSmrg adaptorPriv->GetVideo = adaptorPtr->GetVideo; 47235c4bbdfSmrg adaptorPriv->GetStill = adaptorPtr->GetStill; 47335c4bbdfSmrg adaptorPriv->StopVideo = adaptorPtr->StopVideo; 47435c4bbdfSmrg adaptorPriv->SetPortAttribute = adaptorPtr->SetPortAttribute; 47535c4bbdfSmrg adaptorPriv->GetPortAttribute = adaptorPtr->GetPortAttribute; 47635c4bbdfSmrg adaptorPriv->QueryBestSize = adaptorPtr->QueryBestSize; 47735c4bbdfSmrg adaptorPriv->QueryImageAttributes = adaptorPtr->QueryImageAttributes; 47835c4bbdfSmrg adaptorPriv->PutImage = adaptorPtr->PutImage; 47935c4bbdfSmrg adaptorPriv->ReputImage = adaptorPtr->ReputImage; /* image/still */ 48035c4bbdfSmrg 48135c4bbdfSmrg pa->devPriv.ptr = (void *) adaptorPriv; 48235c4bbdfSmrg 48335c4bbdfSmrg if (!(pPort = calloc(adaptorPtr->nPorts, sizeof(XvPortRec)))) { 48435c4bbdfSmrg xf86XVFreeAdaptor(pa); 48535c4bbdfSmrg continue; 48635c4bbdfSmrg } 48735c4bbdfSmrg for (pp = pPort, i = 0, numPort = 0; i < adaptorPtr->nPorts; i++) { 48835c4bbdfSmrg 48935c4bbdfSmrg if (!(pp->id = FakeClientID(0))) 49035c4bbdfSmrg continue; 49135c4bbdfSmrg 49235c4bbdfSmrg if (!(portPriv = calloc(1, sizeof(XvPortRecPrivate)))) 49335c4bbdfSmrg continue; 49435c4bbdfSmrg 49535c4bbdfSmrg if (!AddResource(pp->id, PortResource, pp)) { 49635c4bbdfSmrg free(portPriv); 49735c4bbdfSmrg continue; 49835c4bbdfSmrg } 49935c4bbdfSmrg 50035c4bbdfSmrg pp->pAdaptor = pa; 50135c4bbdfSmrg pp->pNotify = (XvPortNotifyPtr) NULL; 50235c4bbdfSmrg pp->pDraw = (DrawablePtr) NULL; 50335c4bbdfSmrg pp->client = (ClientPtr) NULL; 50435c4bbdfSmrg pp->grab.client = (ClientPtr) NULL; 50535c4bbdfSmrg pp->time = currentTime; 50635c4bbdfSmrg pp->devPriv.ptr = portPriv; 50735c4bbdfSmrg 50835c4bbdfSmrg portPriv->pScrn = pScrn; 50935c4bbdfSmrg portPriv->AdaptorRec = adaptorPriv; 51035c4bbdfSmrg portPriv->DevPriv.ptr = adaptorPtr->pPortPrivates[i].ptr; 51135c4bbdfSmrg 51235c4bbdfSmrg pp++; 51335c4bbdfSmrg numPort++; 51435c4bbdfSmrg } 51535c4bbdfSmrg pa->nPorts = numPort; 51635c4bbdfSmrg pa->pPorts = pPort; 51735c4bbdfSmrg if (!numPort) { 51835c4bbdfSmrg xf86XVFreeAdaptor(pa); 51935c4bbdfSmrg continue; 52035c4bbdfSmrg } 52135c4bbdfSmrg 52235c4bbdfSmrg pa->base_id = pPort->id; 52335c4bbdfSmrg 52435c4bbdfSmrg pa++; 52535c4bbdfSmrg numAdaptor++; 52635c4bbdfSmrg } 52735c4bbdfSmrg 52835c4bbdfSmrg if (numAdaptor) { 52935c4bbdfSmrg pxvs->nAdaptors = numAdaptor; 53035c4bbdfSmrg pxvs->pAdaptors = pAdaptor; 53135c4bbdfSmrg } 53235c4bbdfSmrg else { 53335c4bbdfSmrg free(pAdaptor); 53435c4bbdfSmrg return FALSE; 53535c4bbdfSmrg } 53635c4bbdfSmrg 53735c4bbdfSmrg return TRUE; 53805b261ecSmrg} 53905b261ecSmrg 54005b261ecSmrg/* Video should be clipped to the intersection of the window cliplist 54105b261ecSmrg and the client cliplist specified in the GC for which the video was 54205b261ecSmrg initialized. When we need to reclip a window, the GC that started 54305b261ecSmrg the video may not even be around anymore. That's why we save the 54405b261ecSmrg client clip from the GC when the video is initialized. We then 54505b261ecSmrg use xf86XVUpdateCompositeClip to calculate the new composite clip 54605b261ecSmrg when we need it. This is different from what DEC did. They saved 547ed6184dfSmrg the GC and used its clip list when they needed to reclip the window, 54805b261ecSmrg even if the client clip was different from the one the video was 54905b261ecSmrg initialized with. If the original GC was destroyed, they had to stop 55005b261ecSmrg the video. I like the new method better (MArk). 55105b261ecSmrg 55205b261ecSmrg This function only works for windows. Will need to rewrite when 55305b261ecSmrg (if) we support pixmap rendering. 55405b261ecSmrg*/ 55505b261ecSmrg 55605b261ecSmrgstatic void 55705b261ecSmrgxf86XVUpdateCompositeClip(XvPortRecPrivatePtr portPriv) 55805b261ecSmrg{ 55935c4bbdfSmrg RegionPtr pregWin, pCompositeClip; 56035c4bbdfSmrg WindowPtr pWin; 56135c4bbdfSmrg Bool freeCompClip = FALSE; 56235c4bbdfSmrg 56335c4bbdfSmrg if (portPriv->pCompositeClip) 56435c4bbdfSmrg return; 56535c4bbdfSmrg 56635c4bbdfSmrg pWin = (WindowPtr) portPriv->pDraw; 56735c4bbdfSmrg 56835c4bbdfSmrg /* get window clip list */ 56935c4bbdfSmrg if (portPriv->subWindowMode == IncludeInferiors) { 57035c4bbdfSmrg pregWin = NotClippedByChildren(pWin); 57135c4bbdfSmrg freeCompClip = TRUE; 57235c4bbdfSmrg } 57335c4bbdfSmrg else 57435c4bbdfSmrg pregWin = &pWin->clipList; 57535c4bbdfSmrg 57635c4bbdfSmrg if (!portPriv->clientClip) { 57735c4bbdfSmrg portPriv->pCompositeClip = pregWin; 57835c4bbdfSmrg portPriv->FreeCompositeClip = freeCompClip; 57935c4bbdfSmrg return; 58035c4bbdfSmrg } 58135c4bbdfSmrg 58235c4bbdfSmrg pCompositeClip = RegionCreate(NullBox, 1); 58335c4bbdfSmrg RegionCopy(pCompositeClip, portPriv->clientClip); 58435c4bbdfSmrg RegionTranslate(pCompositeClip, portPriv->pDraw->x, portPriv->pDraw->y); 58535c4bbdfSmrg RegionIntersect(pCompositeClip, pregWin, pCompositeClip); 58635c4bbdfSmrg 58735c4bbdfSmrg portPriv->pCompositeClip = pCompositeClip; 58835c4bbdfSmrg portPriv->FreeCompositeClip = TRUE; 58935c4bbdfSmrg 59035c4bbdfSmrg if (freeCompClip) { 59135c4bbdfSmrg RegionDestroy(pregWin); 59235c4bbdfSmrg } 59305b261ecSmrg} 59405b261ecSmrg 59505b261ecSmrg/* Save the current clientClip and update the CompositeClip whenever 59605b261ecSmrg we have a fresh GC */ 59705b261ecSmrg 59805b261ecSmrgstatic void 59935c4bbdfSmrgxf86XVCopyClip(XvPortRecPrivatePtr portPriv, GCPtr pGC) 60035c4bbdfSmrg{ 60105b261ecSmrg /* copy the new clip if it exists */ 60235c4bbdfSmrg if (pGC->clientClip) { 60335c4bbdfSmrg if (!portPriv->clientClip) 60435c4bbdfSmrg portPriv->clientClip = RegionCreate(NullBox, 1); 60535c4bbdfSmrg /* Note: this is in window coordinates */ 60635c4bbdfSmrg RegionCopy(portPriv->clientClip, pGC->clientClip); 60735c4bbdfSmrg RegionTranslate(portPriv->clientClip, pGC->clipOrg.x, pGC->clipOrg.y); 60835c4bbdfSmrg } 60935c4bbdfSmrg else if (portPriv->clientClip) { /* free the old clientClip */ 61035c4bbdfSmrg RegionDestroy(portPriv->clientClip); 61135c4bbdfSmrg portPriv->clientClip = NULL; 61205b261ecSmrg } 61305b261ecSmrg 61405b261ecSmrg /* get rid of the old clip list */ 61535c4bbdfSmrg if (portPriv->pCompositeClip && portPriv->FreeCompositeClip) { 61635c4bbdfSmrg RegionDestroy(portPriv->pCompositeClip); 61705b261ecSmrg } 61805b261ecSmrg 6199ace9065Smrg portPriv->pCompositeClip = pGC->pCompositeClip; 6209ace9065Smrg portPriv->FreeCompositeClip = FALSE; 6219ace9065Smrg portPriv->subWindowMode = pGC->subWindowMode; 6229ace9065Smrg} 6239ace9065Smrg 6249ace9065Smrgstatic void 6259ace9065Smrgxf86XVCopyCompositeClip(XvPortRecPrivatePtr portPriv, 62635c4bbdfSmrg GCPtr pGC, DrawablePtr pDraw) 6279ace9065Smrg{ 6289ace9065Smrg if (!portPriv->clientClip) 62935c4bbdfSmrg portPriv->clientClip = RegionCreate(NullBox, 1); 6309ace9065Smrg /* Keep the original GC composite clip around for ReputImage */ 6319ace9065Smrg RegionCopy(portPriv->clientClip, pGC->pCompositeClip); 63235c4bbdfSmrg RegionTranslate(portPriv->clientClip, -pDraw->x, -pDraw->y); 6339ace9065Smrg 6349ace9065Smrg /* get rid of the old clip list */ 6359ace9065Smrg if (portPriv->pCompositeClip && portPriv->FreeCompositeClip) 63635c4bbdfSmrg RegionDestroy(portPriv->pCompositeClip); 6379ace9065Smrg 63805b261ecSmrg portPriv->pCompositeClip = pGC->pCompositeClip; 63905b261ecSmrg portPriv->FreeCompositeClip = FALSE; 64005b261ecSmrg portPriv->subWindowMode = pGC->subWindowMode; 64105b261ecSmrg} 64205b261ecSmrg 64305b261ecSmrgstatic int 64405b261ecSmrgxf86XVRegetVideo(XvPortRecPrivatePtr portPriv) 64505b261ecSmrg{ 64635c4bbdfSmrg RegionRec WinRegion; 64735c4bbdfSmrg RegionRec ClipRegion; 64835c4bbdfSmrg BoxRec WinBox; 64935c4bbdfSmrg int ret = Success; 65035c4bbdfSmrg Bool clippedAway = FALSE; 65135c4bbdfSmrg 65235c4bbdfSmrg xf86XVUpdateCompositeClip(portPriv); 65335c4bbdfSmrg 65435c4bbdfSmrg /* translate the video region to the screen */ 65535c4bbdfSmrg WinBox.x1 = portPriv->pDraw->x + portPriv->drw_x; 65635c4bbdfSmrg WinBox.y1 = portPriv->pDraw->y + portPriv->drw_y; 65735c4bbdfSmrg WinBox.x2 = WinBox.x1 + portPriv->drw_w; 65835c4bbdfSmrg WinBox.y2 = WinBox.y1 + portPriv->drw_h; 65935c4bbdfSmrg 66035c4bbdfSmrg /* clip to the window composite clip */ 66135c4bbdfSmrg RegionInit(&WinRegion, &WinBox, 1); 66235c4bbdfSmrg RegionNull(&ClipRegion); 66335c4bbdfSmrg RegionIntersect(&ClipRegion, &WinRegion, portPriv->pCompositeClip); 66435c4bbdfSmrg 66535c4bbdfSmrg /* that's all if it's totally obscured */ 66635c4bbdfSmrg if (!RegionNotEmpty(&ClipRegion)) { 66735c4bbdfSmrg clippedAway = TRUE; 66835c4bbdfSmrg goto CLIP_VIDEO_BAILOUT; 66935c4bbdfSmrg } 67035c4bbdfSmrg 67135c4bbdfSmrg ret = (*portPriv->AdaptorRec->GetVideo) (portPriv->pScrn, 67235c4bbdfSmrg portPriv->vid_x, portPriv->vid_y, 67335c4bbdfSmrg WinBox.x1, WinBox.y1, 67435c4bbdfSmrg portPriv->vid_w, portPriv->vid_h, 67535c4bbdfSmrg portPriv->drw_w, portPriv->drw_h, 67635c4bbdfSmrg &ClipRegion, portPriv->DevPriv.ptr, 67735c4bbdfSmrg portPriv->pDraw); 67835c4bbdfSmrg 67935c4bbdfSmrg if (ret == Success) 68035c4bbdfSmrg portPriv->isOn = XV_ON; 68135c4bbdfSmrg 68235c4bbdfSmrg CLIP_VIDEO_BAILOUT: 68305b261ecSmrg 68435c4bbdfSmrg if ((clippedAway || (ret != Success)) && portPriv->isOn == XV_ON) { 68535c4bbdfSmrg (*portPriv->AdaptorRec->StopVideo) (portPriv->pScrn, 68635c4bbdfSmrg portPriv->DevPriv.ptr, FALSE); 68735c4bbdfSmrg portPriv->isOn = XV_PENDING; 68835c4bbdfSmrg } 68935c4bbdfSmrg 69035c4bbdfSmrg /* This clip was copied and only good for one shot */ 69135c4bbdfSmrg if (!portPriv->FreeCompositeClip) 69235c4bbdfSmrg portPriv->pCompositeClip = NULL; 69335c4bbdfSmrg 69435c4bbdfSmrg RegionUninit(&WinRegion); 69535c4bbdfSmrg RegionUninit(&ClipRegion); 69635c4bbdfSmrg 69735c4bbdfSmrg return ret; 69835c4bbdfSmrg} 69905b261ecSmrg 70005b261ecSmrgstatic int 70105b261ecSmrgxf86XVReputVideo(XvPortRecPrivatePtr portPriv) 70205b261ecSmrg{ 70335c4bbdfSmrg RegionRec WinRegion; 70435c4bbdfSmrg RegionRec ClipRegion; 70535c4bbdfSmrg BoxRec WinBox; 70635c4bbdfSmrg int ret = Success; 70735c4bbdfSmrg Bool clippedAway = FALSE; 70835c4bbdfSmrg 70935c4bbdfSmrg xf86XVUpdateCompositeClip(portPriv); 71035c4bbdfSmrg 71135c4bbdfSmrg /* translate the video region to the screen */ 71235c4bbdfSmrg WinBox.x1 = portPriv->pDraw->x + portPriv->drw_x; 71335c4bbdfSmrg WinBox.y1 = portPriv->pDraw->y + portPriv->drw_y; 71435c4bbdfSmrg WinBox.x2 = WinBox.x1 + portPriv->drw_w; 71535c4bbdfSmrg WinBox.y2 = WinBox.y1 + portPriv->drw_h; 71635c4bbdfSmrg 71735c4bbdfSmrg /* clip to the window composite clip */ 71835c4bbdfSmrg RegionInit(&WinRegion, &WinBox, 1); 71935c4bbdfSmrg RegionNull(&ClipRegion); 72035c4bbdfSmrg RegionIntersect(&ClipRegion, &WinRegion, portPriv->pCompositeClip); 72135c4bbdfSmrg 72235c4bbdfSmrg /* clip and translate to the viewport */ 72335c4bbdfSmrg if (portPriv->AdaptorRec->flags & VIDEO_CLIP_TO_VIEWPORT) { 72435c4bbdfSmrg RegionRec VPReg; 72535c4bbdfSmrg BoxRec VPBox; 72635c4bbdfSmrg 72735c4bbdfSmrg VPBox.x1 = portPriv->pScrn->frameX0; 72835c4bbdfSmrg VPBox.y1 = portPriv->pScrn->frameY0; 72935c4bbdfSmrg VPBox.x2 = portPriv->pScrn->frameX1 + 1; 73035c4bbdfSmrg VPBox.y2 = portPriv->pScrn->frameY1 + 1; 73135c4bbdfSmrg 73235c4bbdfSmrg RegionInit(&VPReg, &VPBox, 1); 73335c4bbdfSmrg RegionIntersect(&ClipRegion, &ClipRegion, &VPReg); 73435c4bbdfSmrg RegionUninit(&VPReg); 73535c4bbdfSmrg } 73635c4bbdfSmrg 73735c4bbdfSmrg /* that's all if it's totally obscured */ 73835c4bbdfSmrg if (!RegionNotEmpty(&ClipRegion)) { 73935c4bbdfSmrg clippedAway = TRUE; 74035c4bbdfSmrg goto CLIP_VIDEO_BAILOUT; 74135c4bbdfSmrg } 74235c4bbdfSmrg 74335c4bbdfSmrg ret = (*portPriv->AdaptorRec->PutVideo) (portPriv->pScrn, 74435c4bbdfSmrg portPriv->vid_x, portPriv->vid_y, 74535c4bbdfSmrg WinBox.x1, WinBox.y1, 74635c4bbdfSmrg portPriv->vid_w, portPriv->vid_h, 74735c4bbdfSmrg portPriv->drw_w, portPriv->drw_h, 74835c4bbdfSmrg &ClipRegion, portPriv->DevPriv.ptr, 74935c4bbdfSmrg portPriv->pDraw); 75035c4bbdfSmrg 75135c4bbdfSmrg if (ret == Success) 75235c4bbdfSmrg portPriv->isOn = XV_ON; 75335c4bbdfSmrg 75435c4bbdfSmrg CLIP_VIDEO_BAILOUT: 75535c4bbdfSmrg 75635c4bbdfSmrg if ((clippedAway || (ret != Success)) && (portPriv->isOn == XV_ON)) { 75735c4bbdfSmrg (*portPriv->AdaptorRec->StopVideo) (portPriv->pScrn, 75835c4bbdfSmrg portPriv->DevPriv.ptr, FALSE); 75935c4bbdfSmrg portPriv->isOn = XV_PENDING; 76035c4bbdfSmrg } 76135c4bbdfSmrg 76235c4bbdfSmrg /* This clip was copied and only good for one shot */ 76335c4bbdfSmrg if (!portPriv->FreeCompositeClip) 76435c4bbdfSmrg portPriv->pCompositeClip = NULL; 76535c4bbdfSmrg 76635c4bbdfSmrg RegionUninit(&WinRegion); 76735c4bbdfSmrg RegionUninit(&ClipRegion); 76835c4bbdfSmrg 76935c4bbdfSmrg return ret; 77005b261ecSmrg} 77105b261ecSmrg 7729ace9065Smrg/* Reput image/still */ 77305b261ecSmrgstatic int 77405b261ecSmrgxf86XVReputImage(XvPortRecPrivatePtr portPriv) 77505b261ecSmrg{ 77635c4bbdfSmrg RegionRec WinRegion; 77735c4bbdfSmrg RegionRec ClipRegion; 77835c4bbdfSmrg BoxRec WinBox; 77935c4bbdfSmrg int ret = Success; 78035c4bbdfSmrg Bool clippedAway = FALSE; 78135c4bbdfSmrg 78235c4bbdfSmrg xf86XVUpdateCompositeClip(portPriv); 78335c4bbdfSmrg 78435c4bbdfSmrg /* the clip can get smaller over time */ 78535c4bbdfSmrg RegionCopy(portPriv->clientClip, portPriv->pCompositeClip); 78635c4bbdfSmrg RegionTranslate(portPriv->clientClip, 78735c4bbdfSmrg -portPriv->pDraw->x, -portPriv->pDraw->y); 78835c4bbdfSmrg 78935c4bbdfSmrg /* translate the video region to the screen */ 79035c4bbdfSmrg WinBox.x1 = portPriv->pDraw->x + portPriv->drw_x; 79135c4bbdfSmrg WinBox.y1 = portPriv->pDraw->y + portPriv->drw_y; 79235c4bbdfSmrg WinBox.x2 = WinBox.x1 + portPriv->drw_w; 79335c4bbdfSmrg WinBox.y2 = WinBox.y1 + portPriv->drw_h; 79435c4bbdfSmrg 79535c4bbdfSmrg /* clip to the window composite clip */ 79635c4bbdfSmrg RegionInit(&WinRegion, &WinBox, 1); 79735c4bbdfSmrg RegionNull(&ClipRegion); 79835c4bbdfSmrg RegionIntersect(&ClipRegion, &WinRegion, portPriv->pCompositeClip); 79935c4bbdfSmrg 80035c4bbdfSmrg /* clip and translate to the viewport */ 80135c4bbdfSmrg if (portPriv->AdaptorRec->flags & VIDEO_CLIP_TO_VIEWPORT) { 80235c4bbdfSmrg RegionRec VPReg; 80335c4bbdfSmrg BoxRec VPBox; 80435c4bbdfSmrg 80535c4bbdfSmrg VPBox.x1 = portPriv->pScrn->frameX0; 80635c4bbdfSmrg VPBox.y1 = portPriv->pScrn->frameY0; 80735c4bbdfSmrg VPBox.x2 = portPriv->pScrn->frameX1 + 1; 80835c4bbdfSmrg VPBox.y2 = portPriv->pScrn->frameY1 + 1; 80935c4bbdfSmrg 81035c4bbdfSmrg RegionInit(&VPReg, &VPBox, 1); 81135c4bbdfSmrg RegionIntersect(&ClipRegion, &ClipRegion, &VPReg); 81235c4bbdfSmrg RegionUninit(&VPReg); 81335c4bbdfSmrg } 81435c4bbdfSmrg 81535c4bbdfSmrg /* that's all if it's totally obscured */ 81635c4bbdfSmrg if (!RegionNotEmpty(&ClipRegion)) { 81735c4bbdfSmrg clippedAway = TRUE; 81835c4bbdfSmrg goto CLIP_VIDEO_BAILOUT; 81935c4bbdfSmrg } 82035c4bbdfSmrg 82135c4bbdfSmrg ret = (*portPriv->AdaptorRec->ReputImage) (portPriv->pScrn, 82235c4bbdfSmrg portPriv->vid_x, portPriv->vid_y, 82335c4bbdfSmrg WinBox.x1, WinBox.y1, 82435c4bbdfSmrg portPriv->vid_w, portPriv->vid_h, 82535c4bbdfSmrg portPriv->drw_w, portPriv->drw_h, 82635c4bbdfSmrg &ClipRegion, 82735c4bbdfSmrg portPriv->DevPriv.ptr, 82835c4bbdfSmrg portPriv->pDraw); 82905b261ecSmrg 83035c4bbdfSmrg portPriv->isOn = (ret == Success) ? XV_ON : XV_OFF; 83135c4bbdfSmrg 83235c4bbdfSmrg CLIP_VIDEO_BAILOUT: 83335c4bbdfSmrg 83435c4bbdfSmrg if ((clippedAway || (ret != Success)) && (portPriv->isOn == XV_ON)) { 83535c4bbdfSmrg (*portPriv->AdaptorRec->StopVideo) (portPriv->pScrn, 83635c4bbdfSmrg portPriv->DevPriv.ptr, FALSE); 83735c4bbdfSmrg portPriv->isOn = XV_PENDING; 83835c4bbdfSmrg } 83935c4bbdfSmrg 84035c4bbdfSmrg /* This clip was copied and only good for one shot */ 84135c4bbdfSmrg if (!portPriv->FreeCompositeClip) 84235c4bbdfSmrg portPriv->pCompositeClip = NULL; 84335c4bbdfSmrg 84435c4bbdfSmrg RegionUninit(&WinRegion); 84535c4bbdfSmrg RegionUninit(&ClipRegion); 84635c4bbdfSmrg 84735c4bbdfSmrg return ret; 84835c4bbdfSmrg} 84905b261ecSmrg 85005b261ecSmrgstatic int 85135c4bbdfSmrgxf86XVReputAllVideo(WindowPtr pWin, void *data) 85205b261ecSmrg{ 85305b261ecSmrg XF86XVWindowPtr WinPriv = GET_XF86XV_WINDOW(pWin); 85405b261ecSmrg 85535c4bbdfSmrg while (WinPriv) { 85635c4bbdfSmrg if (WinPriv->PortRec->type == XvInputMask) 85735c4bbdfSmrg xf86XVReputVideo(WinPriv->PortRec); 85835c4bbdfSmrg else 85935c4bbdfSmrg xf86XVRegetVideo(WinPriv->PortRec); 86035c4bbdfSmrg WinPriv = WinPriv->next; 86105b261ecSmrg } 86205b261ecSmrg 86305b261ecSmrg return WT_WALKCHILDREN; 86405b261ecSmrg} 86505b261ecSmrg 86605b261ecSmrgstatic int 86705b261ecSmrgxf86XVEnlistPortInWindow(WindowPtr pWin, XvPortRecPrivatePtr portPriv) 86805b261ecSmrg{ 86935c4bbdfSmrg XF86XVWindowPtr winPriv, PrivRoot; 87005b261ecSmrg 87135c4bbdfSmrg winPriv = PrivRoot = GET_XF86XV_WINDOW(pWin); 87205b261ecSmrg 87335c4bbdfSmrg /* Enlist our port in the window private */ 87435c4bbdfSmrg while (winPriv) { 87535c4bbdfSmrg if (winPriv->PortRec == portPriv) /* we're already listed */ 87635c4bbdfSmrg break; 87735c4bbdfSmrg winPriv = winPriv->next; 87835c4bbdfSmrg } 87905b261ecSmrg 88035c4bbdfSmrg if (!winPriv) { 88135c4bbdfSmrg winPriv = calloc(1, sizeof(XF86XVWindowRec)); 88235c4bbdfSmrg if (!winPriv) 88335c4bbdfSmrg return BadAlloc; 88435c4bbdfSmrg winPriv->PortRec = portPriv; 88535c4bbdfSmrg winPriv->next = PrivRoot; 88635c4bbdfSmrg dixSetPrivate(&pWin->devPrivates, XF86XVWindowKey, winPriv); 88735c4bbdfSmrg } 88805b261ecSmrg 88935c4bbdfSmrg portPriv->pDraw = (DrawablePtr) pWin; 89005b261ecSmrg 89135c4bbdfSmrg return Success; 89205b261ecSmrg} 89305b261ecSmrg 89405b261ecSmrgstatic void 89505b261ecSmrgxf86XVRemovePortFromWindow(WindowPtr pWin, XvPortRecPrivatePtr portPriv) 89605b261ecSmrg{ 89735c4bbdfSmrg XF86XVWindowPtr winPriv, prevPriv = NULL; 89835c4bbdfSmrg 89935c4bbdfSmrg winPriv = GET_XF86XV_WINDOW(pWin); 90035c4bbdfSmrg 90135c4bbdfSmrg while (winPriv) { 90235c4bbdfSmrg if (winPriv->PortRec == portPriv) { 90335c4bbdfSmrg if (prevPriv) 90435c4bbdfSmrg prevPriv->next = winPriv->next; 90535c4bbdfSmrg else 90635c4bbdfSmrg dixSetPrivate(&pWin->devPrivates, XF86XVWindowKey, 90735c4bbdfSmrg winPriv->next); 90835c4bbdfSmrg free(winPriv); 90935c4bbdfSmrg break; 91035c4bbdfSmrg } 91135c4bbdfSmrg prevPriv = winPriv; 91235c4bbdfSmrg winPriv = winPriv->next; 91335c4bbdfSmrg } 91435c4bbdfSmrg portPriv->pDraw = NULL; 91535c4bbdfSmrg if (portPriv->ckeyFilled) { 91635c4bbdfSmrg RegionDestroy(portPriv->ckeyFilled); 91735c4bbdfSmrg portPriv->ckeyFilled = NULL; 91835c4bbdfSmrg } 91935c4bbdfSmrg portPriv->clipChanged = FALSE; 9209ace9065Smrg} 9219ace9065Smrg 9229ace9065Smrgstatic void 92335c4bbdfSmrgxf86XVReputOrStopPort(XvPortRecPrivatePtr pPriv, WindowPtr pWin, Bool visible) 9249ace9065Smrg{ 9259ace9065Smrg if (!visible) { 92635c4bbdfSmrg if (pPriv->isOn == XV_ON) { 92735c4bbdfSmrg (*pPriv->AdaptorRec->StopVideo) (pPriv->pScrn, pPriv->DevPriv.ptr, 92835c4bbdfSmrg FALSE); 92935c4bbdfSmrg pPriv->isOn = XV_PENDING; 93035c4bbdfSmrg } 9319ace9065Smrg 93235c4bbdfSmrg if (!pPriv->type) /* overlaid still/image */ 93335c4bbdfSmrg xf86XVRemovePortFromWindow(pWin, pPriv); 9349ace9065Smrg 93535c4bbdfSmrg return; 9369ace9065Smrg } 9379ace9065Smrg 9389ace9065Smrg switch (pPriv->type) { 9399ace9065Smrg case XvInputMask: 94035c4bbdfSmrg xf86XVReputVideo(pPriv); 94135c4bbdfSmrg break; 9429ace9065Smrg case XvOutputMask: 94335c4bbdfSmrg xf86XVRegetVideo(pPriv); 94435c4bbdfSmrg break; 94535c4bbdfSmrg default: /* overlaid still/image */ 94635c4bbdfSmrg if (pPriv->AdaptorRec->ReputImage) 94735c4bbdfSmrg xf86XVReputImage(pPriv); 94835c4bbdfSmrg break; 9499ace9065Smrg } 9509ace9065Smrg} 9519ace9065Smrg 9529ace9065Smrgstatic void 9539ace9065Smrgxf86XVReputOrStopAllPorts(ScrnInfoPtr pScrn, Bool onlyChanged) 9549ace9065Smrg{ 95535c4bbdfSmrg ScreenPtr pScreen = xf86ScrnToScreen(pScrn); 9569ace9065Smrg XvScreenPtr pxvs = GET_XV_SCREEN(pScreen); 9579ace9065Smrg XvAdaptorPtr pa; 9589ace9065Smrg int c, i; 9599ace9065Smrg 9609ace9065Smrg for (c = pxvs->nAdaptors, pa = pxvs->pAdaptors; c > 0; c--, pa++) { 96135c4bbdfSmrg XvPortPtr pPort = pa->pPorts; 9629ace9065Smrg 96335c4bbdfSmrg for (i = pa->nPorts; i > 0; i--, pPort++) { 96435c4bbdfSmrg XvPortRecPrivatePtr pPriv = 96535c4bbdfSmrg (XvPortRecPrivatePtr) pPort->devPriv.ptr; 96635c4bbdfSmrg WindowPtr pWin = (WindowPtr) pPriv->pDraw; 96735c4bbdfSmrg Bool visible; 9689ace9065Smrg 96935c4bbdfSmrg if (pPriv->isOn == XV_OFF || !pWin) 97035c4bbdfSmrg continue; 9719ace9065Smrg 97235c4bbdfSmrg if (onlyChanged && !pPriv->clipChanged) 97335c4bbdfSmrg continue; 9749ace9065Smrg 97535c4bbdfSmrg visible = pWin->visibility == VisibilityUnobscured || 97635c4bbdfSmrg pWin->visibility == VisibilityPartiallyObscured; 9779ace9065Smrg 97835c4bbdfSmrg /* 97935c4bbdfSmrg * Stop and remove still/images if 98035c4bbdfSmrg * ReputImage isn't supported. 98135c4bbdfSmrg */ 98235c4bbdfSmrg if (!pPriv->type && !pPriv->AdaptorRec->ReputImage) 98335c4bbdfSmrg visible = FALSE; 9849ace9065Smrg 98535c4bbdfSmrg xf86XVReputOrStopPort(pPriv, pWin, visible); 9869ace9065Smrg 98735c4bbdfSmrg pPriv->clipChanged = FALSE; 98835c4bbdfSmrg } 9899ace9065Smrg } 99005b261ecSmrg} 99105b261ecSmrg 99205b261ecSmrg/**** ScreenRec fields ****/ 99305b261ecSmrg 99405b261ecSmrgstatic Bool 99505b261ecSmrgxf86XVDestroyWindow(WindowPtr pWin) 99605b261ecSmrg{ 99735c4bbdfSmrg ScreenPtr pScreen = pWin->drawable.pScreen; 99835c4bbdfSmrg XF86XVScreenPtr ScreenPriv = GET_XF86XV_SCREEN(pScreen); 99935c4bbdfSmrg XF86XVWindowPtr tmp, WinPriv = GET_XF86XV_WINDOW(pWin); 100035c4bbdfSmrg int ret; 100105b261ecSmrg 100235c4bbdfSmrg while (WinPriv) { 100335c4bbdfSmrg XvPortRecPrivatePtr pPriv = WinPriv->PortRec; 100435c4bbdfSmrg 100535c4bbdfSmrg if (pPriv->isOn > XV_OFF) { 100635c4bbdfSmrg (*pPriv->AdaptorRec->StopVideo) (pPriv->pScrn, pPriv->DevPriv.ptr, 100735c4bbdfSmrg TRUE); 100835c4bbdfSmrg pPriv->isOn = XV_OFF; 100935c4bbdfSmrg } 101035c4bbdfSmrg 101135c4bbdfSmrg pPriv->pDraw = NULL; 101235c4bbdfSmrg tmp = WinPriv; 101335c4bbdfSmrg WinPriv = WinPriv->next; 101435c4bbdfSmrg free(tmp); 101535c4bbdfSmrg } 101605b261ecSmrg 101735c4bbdfSmrg dixSetPrivate(&pWin->devPrivates, XF86XVWindowKey, NULL); 101805b261ecSmrg 101935c4bbdfSmrg pScreen->DestroyWindow = ScreenPriv->DestroyWindow; 102035c4bbdfSmrg ret = (*pScreen->DestroyWindow) (pWin); 102135c4bbdfSmrg pScreen->DestroyWindow = xf86XVDestroyWindow; 102205b261ecSmrg 102335c4bbdfSmrg return ret; 102405b261ecSmrg} 102505b261ecSmrg 10269ace9065Smrgstatic void 10279ace9065Smrgxf86XVPostValidateTree(WindowPtr pWin, WindowPtr pLayerWin, VTKind kind) 10289ace9065Smrg{ 10299ace9065Smrg ScreenPtr pScreen; 10309ace9065Smrg XF86XVScreenPtr ScreenPriv; 10319ace9065Smrg ScrnInfoPtr pScrn; 10329ace9065Smrg 10339ace9065Smrg if (pWin) 103435c4bbdfSmrg pScreen = pWin->drawable.pScreen; 10359ace9065Smrg else 103635c4bbdfSmrg pScreen = pLayerWin->drawable.pScreen; 10379ace9065Smrg 10389ace9065Smrg ScreenPriv = GET_XF86XV_SCREEN(pScreen); 103935c4bbdfSmrg pScrn = xf86ScreenToScrn(pScreen); 10409ace9065Smrg 10419ace9065Smrg xf86XVReputOrStopAllPorts(pScrn, TRUE); 10429ace9065Smrg 10439ace9065Smrg pScreen->PostValidateTree = ScreenPriv->PostValidateTree; 10449ace9065Smrg if (pScreen->PostValidateTree) { 104535c4bbdfSmrg (*pScreen->PostValidateTree) (pWin, pLayerWin, kind); 10469ace9065Smrg } 10479ace9065Smrg ScreenPriv->PostValidateTree = PostValidateTreeUndefined; 10489ace9065Smrg} 104905b261ecSmrg 105005b261ecSmrgstatic void 105135c4bbdfSmrgxf86XVWindowExposures(WindowPtr pWin, RegionPtr reg1) 105205b261ecSmrg{ 105335c4bbdfSmrg ScreenPtr pScreen = pWin->drawable.pScreen; 105435c4bbdfSmrg XF86XVScreenPtr ScreenPriv = GET_XF86XV_SCREEN(pScreen); 105535c4bbdfSmrg XF86XVWindowPtr WinPriv = GET_XF86XV_WINDOW(pWin); 105635c4bbdfSmrg XvPortRecPrivatePtr pPriv; 105735c4bbdfSmrg Bool AreasExposed; 105835c4bbdfSmrg 105935c4bbdfSmrg AreasExposed = (WinPriv && reg1 && RegionNotEmpty(reg1)); 106035c4bbdfSmrg 106135c4bbdfSmrg pScreen->WindowExposures = ScreenPriv->WindowExposures; 106235c4bbdfSmrg (*pScreen->WindowExposures) (pWin, reg1); 106335c4bbdfSmrg pScreen->WindowExposures = xf86XVWindowExposures; 106435c4bbdfSmrg 106535c4bbdfSmrg /* filter out XClearWindow/Area */ 106635c4bbdfSmrg if (!pWin->valdata) 106735c4bbdfSmrg return; 106835c4bbdfSmrg 106935c4bbdfSmrg while (WinPriv) { 107035c4bbdfSmrg Bool visible = TRUE; 107135c4bbdfSmrg 107235c4bbdfSmrg pPriv = WinPriv->PortRec; 107335c4bbdfSmrg 107435c4bbdfSmrg /* 107535c4bbdfSmrg * Stop and remove still/images if areas were exposed and 107635c4bbdfSmrg * ReputImage isn't supported. 107735c4bbdfSmrg */ 107835c4bbdfSmrg if (!pPriv->type && !pPriv->AdaptorRec->ReputImage) 107935c4bbdfSmrg visible = !AreasExposed; 108035c4bbdfSmrg 108135c4bbdfSmrg /* 108235c4bbdfSmrg * Subtract exposed areas from overlaid image to match textured video 108335c4bbdfSmrg * behavior. 108435c4bbdfSmrg */ 108535c4bbdfSmrg if (!pPriv->type && pPriv->clientClip) 108635c4bbdfSmrg RegionSubtract(pPriv->clientClip, pPriv->clientClip, reg1); 108735c4bbdfSmrg 108835c4bbdfSmrg if (visible && pPriv->ckeyFilled) { 108935c4bbdfSmrg RegionRec tmp; 109035c4bbdfSmrg 109135c4bbdfSmrg RegionNull(&tmp); 109235c4bbdfSmrg RegionCopy(&tmp, reg1); 109335c4bbdfSmrg RegionTranslate(&tmp, pWin->drawable.x, pWin->drawable.y); 109435c4bbdfSmrg RegionSubtract(pPriv->ckeyFilled, pPriv->ckeyFilled, &tmp); 109535c4bbdfSmrg } 109635c4bbdfSmrg 109735c4bbdfSmrg WinPriv = WinPriv->next; 109835c4bbdfSmrg xf86XVReputOrStopPort(pPriv, pWin, visible); 109935c4bbdfSmrg 110035c4bbdfSmrg pPriv->clipChanged = FALSE; 110135c4bbdfSmrg } 110205b261ecSmrg} 110305b261ecSmrg 110405b261ecSmrgstatic void 110505b261ecSmrgxf86XVClipNotify(WindowPtr pWin, int dx, int dy) 110605b261ecSmrg{ 110735c4bbdfSmrg ScreenPtr pScreen = pWin->drawable.pScreen; 110835c4bbdfSmrg XF86XVScreenPtr ScreenPriv = GET_XF86XV_SCREEN(pScreen); 110935c4bbdfSmrg XF86XVWindowPtr WinPriv = GET_XF86XV_WINDOW(pWin); 111035c4bbdfSmrg XvPortRecPrivatePtr pPriv; 111105b261ecSmrg 111235c4bbdfSmrg while (WinPriv) { 111335c4bbdfSmrg pPriv = WinPriv->PortRec; 111405b261ecSmrg 111535c4bbdfSmrg if (pPriv->pCompositeClip && pPriv->FreeCompositeClip) 111635c4bbdfSmrg RegionDestroy(pPriv->pCompositeClip); 111705b261ecSmrg 111835c4bbdfSmrg pPriv->pCompositeClip = NULL; 11196747b715Smrg 112035c4bbdfSmrg pPriv->clipChanged = TRUE; 112105b261ecSmrg 112235c4bbdfSmrg if (ScreenPriv->PostValidateTree == PostValidateTreeUndefined) { 112335c4bbdfSmrg ScreenPriv->PostValidateTree = pScreen->PostValidateTree; 112435c4bbdfSmrg pScreen->PostValidateTree = xf86XVPostValidateTree; 112535c4bbdfSmrg } 112605b261ecSmrg 112735c4bbdfSmrg WinPriv = WinPriv->next; 112835c4bbdfSmrg } 112905b261ecSmrg 113035c4bbdfSmrg if (ScreenPriv->ClipNotify) { 113135c4bbdfSmrg pScreen->ClipNotify = ScreenPriv->ClipNotify; 113235c4bbdfSmrg (*pScreen->ClipNotify) (pWin, dx, dy); 113335c4bbdfSmrg pScreen->ClipNotify = xf86XVClipNotify; 113435c4bbdfSmrg } 113505b261ecSmrg} 113605b261ecSmrg 113705b261ecSmrg/**** Required XvScreenRec fields ****/ 113805b261ecSmrg 113905b261ecSmrgstatic Bool 114035c4bbdfSmrgxf86XVCloseScreen(ScreenPtr pScreen) 114105b261ecSmrg{ 114235c4bbdfSmrg ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 114335c4bbdfSmrg XvScreenPtr pxvs = GET_XV_SCREEN(pScreen); 114435c4bbdfSmrg XF86XVScreenPtr ScreenPriv = GET_XF86XV_SCREEN(pScreen); 114535c4bbdfSmrg XvAdaptorPtr pa; 114635c4bbdfSmrg int c; 114705b261ecSmrg 114835c4bbdfSmrg if (!ScreenPriv) 114935c4bbdfSmrg return TRUE; 115005b261ecSmrg 115135c4bbdfSmrg pScreen->DestroyWindow = ScreenPriv->DestroyWindow; 115235c4bbdfSmrg pScreen->WindowExposures = ScreenPriv->WindowExposures; 115335c4bbdfSmrg pScreen->ClipNotify = ScreenPriv->ClipNotify; 115435c4bbdfSmrg pScreen->CloseScreen = ScreenPriv->CloseScreen; 115505b261ecSmrg 115635c4bbdfSmrg pScrn->EnterVT = ScreenPriv->EnterVT; 115735c4bbdfSmrg pScrn->LeaveVT = ScreenPriv->LeaveVT; 115835c4bbdfSmrg pScrn->AdjustFrame = ScreenPriv->AdjustFrame; 115935c4bbdfSmrg pScrn->ModeSet = ScreenPriv->ModeSet; 116005b261ecSmrg 116135c4bbdfSmrg for (c = 0, pa = pxvs->pAdaptors; c < pxvs->nAdaptors; c++, pa++) { 116235c4bbdfSmrg xf86XVFreeAdaptor(pa); 116335c4bbdfSmrg } 116405b261ecSmrg 116535c4bbdfSmrg free(pxvs->pAdaptors); 116635c4bbdfSmrg free(ScreenPriv); 116735c4bbdfSmrg 116835c4bbdfSmrg return pScreen->CloseScreen(pScreen); 116935c4bbdfSmrg} 117005b261ecSmrg 117105b261ecSmrg/**** ScrnInfoRec fields ****/ 117205b261ecSmrg 117305b261ecSmrgstatic Bool 117435c4bbdfSmrgxf86XVEnterVT(ScrnInfoPtr pScrn) 117505b261ecSmrg{ 117635c4bbdfSmrg ScreenPtr pScreen = xf86ScrnToScreen(pScrn); 117705b261ecSmrg XF86XVScreenPtr ScreenPriv = GET_XF86XV_SCREEN(pScreen); 117805b261ecSmrg Bool ret; 117905b261ecSmrg 11806747b715Smrg pScrn->EnterVT = ScreenPriv->EnterVT; 118135c4bbdfSmrg ret = (*ScreenPriv->EnterVT) (pScrn); 11826747b715Smrg ScreenPriv->EnterVT = pScrn->EnterVT; 11836747b715Smrg pScrn->EnterVT = xf86XVEnterVT; 118405b261ecSmrg 118535c4bbdfSmrg if (ret) 118635c4bbdfSmrg WalkTree(pScreen, xf86XVReputAllVideo, 0); 118705b261ecSmrg 118805b261ecSmrg return ret; 118905b261ecSmrg} 119005b261ecSmrg 119105b261ecSmrgstatic void 119235c4bbdfSmrgxf86XVLeaveVT(ScrnInfoPtr pScrn) 119305b261ecSmrg{ 119435c4bbdfSmrg ScreenPtr pScreen = xf86ScrnToScreen(pScrn); 119505b261ecSmrg XvScreenPtr pxvs = GET_XV_SCREEN(pScreen); 119605b261ecSmrg XF86XVScreenPtr ScreenPriv = GET_XF86XV_SCREEN(pScreen); 119705b261ecSmrg XvAdaptorPtr pAdaptor; 119805b261ecSmrg XvPortPtr pPort; 119905b261ecSmrg XvPortRecPrivatePtr pPriv; 120005b261ecSmrg int i, j; 120105b261ecSmrg 120235c4bbdfSmrg for (i = 0; i < pxvs->nAdaptors; i++) { 120335c4bbdfSmrg pAdaptor = &pxvs->pAdaptors[i]; 120435c4bbdfSmrg for (j = 0; j < pAdaptor->nPorts; j++) { 120535c4bbdfSmrg pPort = &pAdaptor->pPorts[j]; 120635c4bbdfSmrg pPriv = (XvPortRecPrivatePtr) pPort->devPriv.ptr; 120735c4bbdfSmrg if (pPriv->isOn > XV_OFF) { 120805b261ecSmrg 120935c4bbdfSmrg (*pPriv->AdaptorRec->StopVideo) (pPriv->pScrn, 121035c4bbdfSmrg pPriv->DevPriv.ptr, TRUE); 121135c4bbdfSmrg pPriv->isOn = XV_OFF; 121205b261ecSmrg 121335c4bbdfSmrg if (pPriv->pCompositeClip && pPriv->FreeCompositeClip) 121435c4bbdfSmrg RegionDestroy(pPriv->pCompositeClip); 121505b261ecSmrg 121635c4bbdfSmrg pPriv->pCompositeClip = NULL; 121705b261ecSmrg 121835c4bbdfSmrg if (!pPriv->type && pPriv->pDraw) { /* still */ 121935c4bbdfSmrg xf86XVRemovePortFromWindow((WindowPtr) pPriv->pDraw, pPriv); 122035c4bbdfSmrg } 122135c4bbdfSmrg } 122235c4bbdfSmrg } 122305b261ecSmrg } 122405b261ecSmrg 12256747b715Smrg pScrn->LeaveVT = ScreenPriv->LeaveVT; 122635c4bbdfSmrg (*ScreenPriv->LeaveVT) (pScrn); 12276747b715Smrg ScreenPriv->LeaveVT = pScrn->LeaveVT; 12286747b715Smrg pScrn->LeaveVT = xf86XVLeaveVT; 122905b261ecSmrg} 123005b261ecSmrg 123105b261ecSmrgstatic void 123235c4bbdfSmrgxf86XVAdjustFrame(ScrnInfoPtr pScrn, int x, int y) 123305b261ecSmrg{ 123435c4bbdfSmrg ScreenPtr pScreen = xf86ScrnToScreen(pScrn); 123535c4bbdfSmrg XF86XVScreenPtr ScreenPriv = GET_XF86XV_SCREEN(pScreen); 123605b261ecSmrg 123735c4bbdfSmrg if (ScreenPriv->AdjustFrame) { 123835c4bbdfSmrg pScrn->AdjustFrame = ScreenPriv->AdjustFrame; 123935c4bbdfSmrg (*pScrn->AdjustFrame) (pScrn, x, y); 124035c4bbdfSmrg pScrn->AdjustFrame = xf86XVAdjustFrame; 124135c4bbdfSmrg } 124205b261ecSmrg 124335c4bbdfSmrg xf86XVReputOrStopAllPorts(pScrn, FALSE); 12449ace9065Smrg} 124505b261ecSmrg 12469ace9065Smrgstatic void 12479ace9065Smrgxf86XVModeSet(ScrnInfoPtr pScrn) 12489ace9065Smrg{ 124935c4bbdfSmrg ScreenPtr pScreen = xf86ScrnToScreen(pScrn); 12509ace9065Smrg XF86XVScreenPtr ScreenPriv; 125105b261ecSmrg 12529ace9065Smrg /* Can be called before pScrn->pScreen is set */ 12539ace9065Smrg if (!pScreen) 125435c4bbdfSmrg return; 125505b261ecSmrg 12569ace9065Smrg ScreenPriv = GET_XF86XV_SCREEN(pScreen); 125705b261ecSmrg 12589ace9065Smrg if (ScreenPriv->ModeSet) { 125935c4bbdfSmrg pScrn->ModeSet = ScreenPriv->ModeSet; 126035c4bbdfSmrg (*pScrn->ModeSet) (pScrn); 126135c4bbdfSmrg pScrn->ModeSet = xf86XVModeSet; 12629ace9065Smrg } 126305b261ecSmrg 12649ace9065Smrg xf86XVReputOrStopAllPorts(pScrn, FALSE); 126505b261ecSmrg} 126605b261ecSmrg 126705b261ecSmrg/**** XvAdaptorRec fields ****/ 126805b261ecSmrg 126905b261ecSmrgstatic int 127035c4bbdfSmrgxf86XVPutVideo(DrawablePtr pDraw, 127135c4bbdfSmrg XvPortPtr pPort, 127235c4bbdfSmrg GCPtr pGC, 127335c4bbdfSmrg INT16 vid_x, INT16 vid_y, 127435c4bbdfSmrg CARD16 vid_w, CARD16 vid_h, 127535c4bbdfSmrg INT16 drw_x, INT16 drw_y, CARD16 drw_w, CARD16 drw_h) 127635c4bbdfSmrg{ 127735c4bbdfSmrg XvPortRecPrivatePtr portPriv = (XvPortRecPrivatePtr) (pPort->devPriv.ptr); 127835c4bbdfSmrg int result; 127905b261ecSmrg 128035c4bbdfSmrg /* No dumping video to pixmaps... For now anyhow */ 128135c4bbdfSmrg if (pDraw->type != DRAWABLE_WINDOW) { 128235c4bbdfSmrg pPort->pDraw = (DrawablePtr) NULL; 128335c4bbdfSmrg return BadAlloc; 128435c4bbdfSmrg } 128505b261ecSmrg 128635c4bbdfSmrg /* If we are changing windows, unregister our port in the old window */ 128735c4bbdfSmrg if (portPriv->pDraw && (portPriv->pDraw != pDraw)) 128835c4bbdfSmrg xf86XVRemovePortFromWindow((WindowPtr) (portPriv->pDraw), portPriv); 128905b261ecSmrg 129035c4bbdfSmrg /* Register our port with the new window */ 129135c4bbdfSmrg result = xf86XVEnlistPortInWindow((WindowPtr) pDraw, portPriv); 129235c4bbdfSmrg if (result != Success) 129335c4bbdfSmrg return result; 129405b261ecSmrg 129535c4bbdfSmrg portPriv->type = XvInputMask; 129605b261ecSmrg 129735c4bbdfSmrg /* save a copy of these parameters */ 129835c4bbdfSmrg portPriv->vid_x = vid_x; 129935c4bbdfSmrg portPriv->vid_y = vid_y; 130035c4bbdfSmrg portPriv->vid_w = vid_w; 130135c4bbdfSmrg portPriv->vid_h = vid_h; 130235c4bbdfSmrg portPriv->drw_x = drw_x; 130335c4bbdfSmrg portPriv->drw_y = drw_y; 130435c4bbdfSmrg portPriv->drw_w = drw_w; 130535c4bbdfSmrg portPriv->drw_h = drw_h; 130635c4bbdfSmrg 130735c4bbdfSmrg /* make sure we have the most recent copy of the clientClip */ 130835c4bbdfSmrg xf86XVCopyClip(portPriv, pGC); 130935c4bbdfSmrg 131035c4bbdfSmrg /* To indicate to the DI layer that we were successful */ 131135c4bbdfSmrg pPort->pDraw = pDraw; 131235c4bbdfSmrg 131335c4bbdfSmrg if (!portPriv->pScrn->vtSema) 131435c4bbdfSmrg return Success; /* Success ? */ 131535c4bbdfSmrg 131635c4bbdfSmrg return (xf86XVReputVideo(portPriv)); 131705b261ecSmrg} 131805b261ecSmrg 131905b261ecSmrgstatic int 132035c4bbdfSmrgxf86XVPutStill(DrawablePtr pDraw, 132135c4bbdfSmrg XvPortPtr pPort, 132235c4bbdfSmrg GCPtr pGC, 132335c4bbdfSmrg INT16 vid_x, INT16 vid_y, 132435c4bbdfSmrg CARD16 vid_w, CARD16 vid_h, 132535c4bbdfSmrg INT16 drw_x, INT16 drw_y, CARD16 drw_w, CARD16 drw_h) 132635c4bbdfSmrg{ 132735c4bbdfSmrg XvPortRecPrivatePtr portPriv = (XvPortRecPrivatePtr) (pPort->devPriv.ptr); 132835c4bbdfSmrg RegionRec WinRegion; 132935c4bbdfSmrg RegionRec ClipRegion; 133035c4bbdfSmrg BoxRec WinBox; 133135c4bbdfSmrg int ret = Success; 133235c4bbdfSmrg Bool clippedAway = FALSE; 133335c4bbdfSmrg 133435c4bbdfSmrg if (pDraw->type != DRAWABLE_WINDOW) 133535c4bbdfSmrg return BadAlloc; 133635c4bbdfSmrg 133735c4bbdfSmrg if (!portPriv->pScrn->vtSema) 133835c4bbdfSmrg return Success; /* Success ? */ 133935c4bbdfSmrg 134035c4bbdfSmrg WinBox.x1 = pDraw->x + drw_x; 134135c4bbdfSmrg WinBox.y1 = pDraw->y + drw_y; 134235c4bbdfSmrg WinBox.x2 = WinBox.x1 + drw_w; 134335c4bbdfSmrg WinBox.y2 = WinBox.y1 + drw_h; 134435c4bbdfSmrg 134535c4bbdfSmrg xf86XVCopyCompositeClip(portPriv, pGC, pDraw); 134635c4bbdfSmrg 134735c4bbdfSmrg RegionInit(&WinRegion, &WinBox, 1); 134835c4bbdfSmrg RegionNull(&ClipRegion); 134935c4bbdfSmrg RegionIntersect(&ClipRegion, &WinRegion, pGC->pCompositeClip); 135035c4bbdfSmrg 135135c4bbdfSmrg if (portPriv->AdaptorRec->flags & VIDEO_CLIP_TO_VIEWPORT) { 135235c4bbdfSmrg RegionRec VPReg; 135335c4bbdfSmrg BoxRec VPBox; 135435c4bbdfSmrg 135535c4bbdfSmrg VPBox.x1 = portPriv->pScrn->frameX0; 135635c4bbdfSmrg VPBox.y1 = portPriv->pScrn->frameY0; 135735c4bbdfSmrg VPBox.x2 = portPriv->pScrn->frameX1 + 1; 135835c4bbdfSmrg VPBox.y2 = portPriv->pScrn->frameY1 + 1; 135935c4bbdfSmrg 136035c4bbdfSmrg RegionInit(&VPReg, &VPBox, 1); 136135c4bbdfSmrg RegionIntersect(&ClipRegion, &ClipRegion, &VPReg); 136235c4bbdfSmrg RegionUninit(&VPReg); 136335c4bbdfSmrg } 136435c4bbdfSmrg 136535c4bbdfSmrg if (portPriv->pDraw) { 136635c4bbdfSmrg xf86XVRemovePortFromWindow((WindowPtr) (portPriv->pDraw), portPriv); 136735c4bbdfSmrg } 136835c4bbdfSmrg 136935c4bbdfSmrg if (!RegionNotEmpty(&ClipRegion)) { 137035c4bbdfSmrg clippedAway = TRUE; 137135c4bbdfSmrg goto PUT_STILL_BAILOUT; 137235c4bbdfSmrg } 137335c4bbdfSmrg 137435c4bbdfSmrg ret = (*portPriv->AdaptorRec->PutStill) (portPriv->pScrn, 137535c4bbdfSmrg vid_x, vid_y, WinBox.x1, WinBox.y1, 137635c4bbdfSmrg vid_w, vid_h, drw_w, drw_h, 137735c4bbdfSmrg &ClipRegion, portPriv->DevPriv.ptr, 137835c4bbdfSmrg pDraw); 137935c4bbdfSmrg 138035c4bbdfSmrg if ((ret == Success) && 138135c4bbdfSmrg (portPriv->AdaptorRec->flags & VIDEO_OVERLAID_STILLS)) { 138235c4bbdfSmrg 138335c4bbdfSmrg xf86XVEnlistPortInWindow((WindowPtr) pDraw, portPriv); 138435c4bbdfSmrg portPriv->isOn = XV_ON; 138535c4bbdfSmrg portPriv->vid_x = vid_x; 138635c4bbdfSmrg portPriv->vid_y = vid_y; 138735c4bbdfSmrg portPriv->vid_w = vid_w; 138835c4bbdfSmrg portPriv->vid_h = vid_h; 138935c4bbdfSmrg portPriv->drw_x = drw_x; 139035c4bbdfSmrg portPriv->drw_y = drw_y; 139135c4bbdfSmrg portPriv->drw_w = drw_w; 139235c4bbdfSmrg portPriv->drw_h = drw_h; 139335c4bbdfSmrg portPriv->type = 0; /* no mask means it's transient and should 139435c4bbdfSmrg not be reput once it's removed */ 139535c4bbdfSmrg pPort->pDraw = pDraw; /* make sure we can get stop requests */ 139635c4bbdfSmrg } 139735c4bbdfSmrg 139835c4bbdfSmrg PUT_STILL_BAILOUT: 139935c4bbdfSmrg 140035c4bbdfSmrg if ((clippedAway || (ret != Success)) && (portPriv->isOn == XV_ON)) { 140135c4bbdfSmrg (*portPriv->AdaptorRec->StopVideo) (portPriv->pScrn, 140235c4bbdfSmrg portPriv->DevPriv.ptr, FALSE); 140335c4bbdfSmrg portPriv->isOn = XV_PENDING; 140435c4bbdfSmrg } 140535c4bbdfSmrg 140635c4bbdfSmrg /* This clip was copied and only good for one shot */ 140735c4bbdfSmrg if (!portPriv->FreeCompositeClip) 140835c4bbdfSmrg portPriv->pCompositeClip = NULL; 140935c4bbdfSmrg 141035c4bbdfSmrg RegionUninit(&WinRegion); 141135c4bbdfSmrg RegionUninit(&ClipRegion); 141235c4bbdfSmrg 141335c4bbdfSmrg return ret; 141405b261ecSmrg} 141505b261ecSmrg 141605b261ecSmrgstatic int 141735c4bbdfSmrgxf86XVGetVideo(DrawablePtr pDraw, 141835c4bbdfSmrg XvPortPtr pPort, 141935c4bbdfSmrg GCPtr pGC, 142035c4bbdfSmrg INT16 vid_x, INT16 vid_y, 142135c4bbdfSmrg CARD16 vid_w, CARD16 vid_h, 142235c4bbdfSmrg INT16 drw_x, INT16 drw_y, CARD16 drw_w, CARD16 drw_h) 142335c4bbdfSmrg{ 142435c4bbdfSmrg XvPortRecPrivatePtr portPriv = (XvPortRecPrivatePtr) (pPort->devPriv.ptr); 142535c4bbdfSmrg int result; 142635c4bbdfSmrg 142735c4bbdfSmrg /* No pixmaps... For now anyhow */ 142835c4bbdfSmrg if (pDraw->type != DRAWABLE_WINDOW) { 142935c4bbdfSmrg pPort->pDraw = (DrawablePtr) NULL; 143035c4bbdfSmrg return BadAlloc; 143135c4bbdfSmrg } 143235c4bbdfSmrg 143335c4bbdfSmrg /* If we are changing windows, unregister our port in the old window */ 143435c4bbdfSmrg if (portPriv->pDraw && (portPriv->pDraw != pDraw)) 143535c4bbdfSmrg xf86XVRemovePortFromWindow((WindowPtr) (portPriv->pDraw), portPriv); 143635c4bbdfSmrg 143735c4bbdfSmrg /* Register our port with the new window */ 143835c4bbdfSmrg result = xf86XVEnlistPortInWindow((WindowPtr) pDraw, portPriv); 143935c4bbdfSmrg if (result != Success) 144035c4bbdfSmrg return result; 144135c4bbdfSmrg 144235c4bbdfSmrg portPriv->type = XvOutputMask; 144335c4bbdfSmrg 144435c4bbdfSmrg /* save a copy of these parameters */ 144535c4bbdfSmrg portPriv->vid_x = vid_x; 144635c4bbdfSmrg portPriv->vid_y = vid_y; 144735c4bbdfSmrg portPriv->vid_w = vid_w; 144835c4bbdfSmrg portPriv->vid_h = vid_h; 144935c4bbdfSmrg portPriv->drw_x = drw_x; 145035c4bbdfSmrg portPriv->drw_y = drw_y; 145135c4bbdfSmrg portPriv->drw_w = drw_w; 145235c4bbdfSmrg portPriv->drw_h = drw_h; 145335c4bbdfSmrg 145435c4bbdfSmrg /* make sure we have the most recent copy of the clientClip */ 145535c4bbdfSmrg xf86XVCopyClip(portPriv, pGC); 145635c4bbdfSmrg 145735c4bbdfSmrg /* To indicate to the DI layer that we were successful */ 145835c4bbdfSmrg pPort->pDraw = pDraw; 145935c4bbdfSmrg 146035c4bbdfSmrg if (!portPriv->pScrn->vtSema) 146135c4bbdfSmrg return Success; /* Success ? */ 146235c4bbdfSmrg 146335c4bbdfSmrg return (xf86XVRegetVideo(portPriv)); 146405b261ecSmrg} 146505b261ecSmrg 146605b261ecSmrgstatic int 146735c4bbdfSmrgxf86XVGetStill(DrawablePtr pDraw, 146835c4bbdfSmrg XvPortPtr pPort, 146935c4bbdfSmrg GCPtr pGC, 147035c4bbdfSmrg INT16 vid_x, INT16 vid_y, 147135c4bbdfSmrg CARD16 vid_w, CARD16 vid_h, 147235c4bbdfSmrg INT16 drw_x, INT16 drw_y, CARD16 drw_w, CARD16 drw_h) 147335c4bbdfSmrg{ 147435c4bbdfSmrg XvPortRecPrivatePtr portPriv = (XvPortRecPrivatePtr) (pPort->devPriv.ptr); 147535c4bbdfSmrg RegionRec WinRegion; 147635c4bbdfSmrg RegionRec ClipRegion; 147735c4bbdfSmrg BoxRec WinBox; 147835c4bbdfSmrg int ret = Success; 147935c4bbdfSmrg Bool clippedAway = FALSE; 148035c4bbdfSmrg 148135c4bbdfSmrg if (pDraw->type != DRAWABLE_WINDOW) 148235c4bbdfSmrg return BadAlloc; 148335c4bbdfSmrg 148435c4bbdfSmrg if (!portPriv->pScrn->vtSema) 148535c4bbdfSmrg return Success; /* Success ? */ 148635c4bbdfSmrg 148735c4bbdfSmrg WinBox.x1 = pDraw->x + drw_x; 148835c4bbdfSmrg WinBox.y1 = pDraw->y + drw_y; 148935c4bbdfSmrg WinBox.x2 = WinBox.x1 + drw_w; 149035c4bbdfSmrg WinBox.y2 = WinBox.y1 + drw_h; 149135c4bbdfSmrg 149235c4bbdfSmrg RegionInit(&WinRegion, &WinBox, 1); 149335c4bbdfSmrg RegionNull(&ClipRegion); 149435c4bbdfSmrg RegionIntersect(&ClipRegion, &WinRegion, pGC->pCompositeClip); 149535c4bbdfSmrg 149635c4bbdfSmrg if (portPriv->pDraw) { 149735c4bbdfSmrg xf86XVRemovePortFromWindow((WindowPtr) (portPriv->pDraw), portPriv); 149835c4bbdfSmrg } 149935c4bbdfSmrg 150035c4bbdfSmrg if (!RegionNotEmpty(&ClipRegion)) { 150135c4bbdfSmrg clippedAway = TRUE; 150235c4bbdfSmrg goto GET_STILL_BAILOUT; 150335c4bbdfSmrg } 150435c4bbdfSmrg 150535c4bbdfSmrg ret = (*portPriv->AdaptorRec->GetStill) (portPriv->pScrn, 150635c4bbdfSmrg vid_x, vid_y, WinBox.x1, WinBox.y1, 150735c4bbdfSmrg vid_w, vid_h, drw_w, drw_h, 150835c4bbdfSmrg &ClipRegion, portPriv->DevPriv.ptr, 150935c4bbdfSmrg pDraw); 151035c4bbdfSmrg 151135c4bbdfSmrg GET_STILL_BAILOUT: 151205b261ecSmrg 151335c4bbdfSmrg if ((clippedAway || (ret != Success)) && (portPriv->isOn == XV_ON)) { 151435c4bbdfSmrg (*portPriv->AdaptorRec->StopVideo) (portPriv->pScrn, 151535c4bbdfSmrg portPriv->DevPriv.ptr, FALSE); 151635c4bbdfSmrg portPriv->isOn = XV_PENDING; 151735c4bbdfSmrg } 151835c4bbdfSmrg 151935c4bbdfSmrg RegionUninit(&WinRegion); 152035c4bbdfSmrg RegionUninit(&ClipRegion); 152105b261ecSmrg 152235c4bbdfSmrg return ret; 152335c4bbdfSmrg} 152405b261ecSmrg 152505b261ecSmrgstatic int 152635c4bbdfSmrgxf86XVStopVideo(XvPortPtr pPort, DrawablePtr pDraw) 152735c4bbdfSmrg{ 152835c4bbdfSmrg XvPortRecPrivatePtr portPriv = (XvPortRecPrivatePtr) (pPort->devPriv.ptr); 152905b261ecSmrg 153035c4bbdfSmrg if (pDraw->type != DRAWABLE_WINDOW) 153135c4bbdfSmrg return BadAlloc; 153205b261ecSmrg 153335c4bbdfSmrg xf86XVRemovePortFromWindow((WindowPtr) pDraw, portPriv); 153405b261ecSmrg 153535c4bbdfSmrg if (!portPriv->pScrn->vtSema) 153635c4bbdfSmrg return Success; /* Success ? */ 153705b261ecSmrg 153835c4bbdfSmrg /* Must free resources. */ 153905b261ecSmrg 154035c4bbdfSmrg if (portPriv->isOn > XV_OFF) { 154135c4bbdfSmrg (*portPriv->AdaptorRec->StopVideo) (portPriv->pScrn, 154235c4bbdfSmrg portPriv->DevPriv.ptr, TRUE); 154335c4bbdfSmrg portPriv->isOn = XV_OFF; 154435c4bbdfSmrg } 154505b261ecSmrg 154635c4bbdfSmrg return Success; 154705b261ecSmrg} 154805b261ecSmrg 154905b261ecSmrgstatic int 155035c4bbdfSmrgxf86XVSetPortAttribute(XvPortPtr pPort, Atom attribute, INT32 value) 155135c4bbdfSmrg{ 155235c4bbdfSmrg XvPortRecPrivatePtr portPriv = (XvPortRecPrivatePtr) (pPort->devPriv.ptr); 155305b261ecSmrg 155435c4bbdfSmrg return ((*portPriv->AdaptorRec->SetPortAttribute) (portPriv->pScrn, 155535c4bbdfSmrg attribute, value, 155635c4bbdfSmrg portPriv->DevPriv.ptr)); 155735c4bbdfSmrg} 155805b261ecSmrg 155905b261ecSmrgstatic int 156035c4bbdfSmrgxf86XVGetPortAttribute(XvPortPtr pPort, Atom attribute, INT32 *p_value) 156135c4bbdfSmrg{ 156235c4bbdfSmrg XvPortRecPrivatePtr portPriv = (XvPortRecPrivatePtr) (pPort->devPriv.ptr); 156335c4bbdfSmrg 156435c4bbdfSmrg return ((*portPriv->AdaptorRec->GetPortAttribute) (portPriv->pScrn, 156535c4bbdfSmrg attribute, p_value, 156635c4bbdfSmrg portPriv->DevPriv.ptr)); 156705b261ecSmrg} 156805b261ecSmrg 156935c4bbdfSmrgstatic int 157035c4bbdfSmrgxf86XVQueryBestSize(XvPortPtr pPort, 157135c4bbdfSmrg CARD8 motion, 157235c4bbdfSmrg CARD16 vid_w, CARD16 vid_h, 157335c4bbdfSmrg CARD16 drw_w, CARD16 drw_h, 157435c4bbdfSmrg unsigned int *p_w, unsigned int *p_h) 157535c4bbdfSmrg{ 157635c4bbdfSmrg XvPortRecPrivatePtr portPriv = (XvPortRecPrivatePtr) (pPort->devPriv.ptr); 157705b261ecSmrg 157835c4bbdfSmrg (*portPriv->AdaptorRec->QueryBestSize) (portPriv->pScrn, 157935c4bbdfSmrg (Bool) motion, vid_w, vid_h, drw_w, 158035c4bbdfSmrg drw_h, p_w, p_h, 158135c4bbdfSmrg portPriv->DevPriv.ptr); 158205b261ecSmrg 158335c4bbdfSmrg return Success; 158405b261ecSmrg} 158505b261ecSmrg 158605b261ecSmrgstatic int 158735c4bbdfSmrgxf86XVPutImage(DrawablePtr pDraw, 158835c4bbdfSmrg XvPortPtr pPort, 158935c4bbdfSmrg GCPtr pGC, 159035c4bbdfSmrg INT16 src_x, INT16 src_y, 159135c4bbdfSmrg CARD16 src_w, CARD16 src_h, 159235c4bbdfSmrg INT16 drw_x, INT16 drw_y, 159335c4bbdfSmrg CARD16 drw_w, CARD16 drw_h, 159435c4bbdfSmrg XvImagePtr format, 159535c4bbdfSmrg unsigned char *data, Bool sync, CARD16 width, CARD16 height) 159635c4bbdfSmrg{ 159735c4bbdfSmrg XvPortRecPrivatePtr portPriv = (XvPortRecPrivatePtr) (pPort->devPriv.ptr); 159835c4bbdfSmrg RegionRec WinRegion; 159935c4bbdfSmrg RegionRec ClipRegion; 160035c4bbdfSmrg BoxRec WinBox; 160135c4bbdfSmrg int ret = Success; 160235c4bbdfSmrg Bool clippedAway = FALSE; 160335c4bbdfSmrg 160435c4bbdfSmrg if (pDraw->type != DRAWABLE_WINDOW) 160535c4bbdfSmrg return BadAlloc; 160635c4bbdfSmrg 160735c4bbdfSmrg if (!portPriv->pScrn->vtSema) 160835c4bbdfSmrg return Success; /* Success ? */ 160935c4bbdfSmrg 161035c4bbdfSmrg xf86XVCopyCompositeClip(portPriv, pGC, pDraw); 161135c4bbdfSmrg 161235c4bbdfSmrg WinBox.x1 = pDraw->x + drw_x; 161335c4bbdfSmrg WinBox.y1 = pDraw->y + drw_y; 161435c4bbdfSmrg WinBox.x2 = WinBox.x1 + drw_w; 161535c4bbdfSmrg WinBox.y2 = WinBox.y1 + drw_h; 161635c4bbdfSmrg 161735c4bbdfSmrg RegionInit(&WinRegion, &WinBox, 1); 161835c4bbdfSmrg RegionNull(&ClipRegion); 161935c4bbdfSmrg RegionIntersect(&ClipRegion, &WinRegion, pGC->pCompositeClip); 162035c4bbdfSmrg 162135c4bbdfSmrg if (portPriv->AdaptorRec->flags & VIDEO_CLIP_TO_VIEWPORT) { 162235c4bbdfSmrg RegionRec VPReg; 162335c4bbdfSmrg BoxRec VPBox; 162435c4bbdfSmrg 162535c4bbdfSmrg VPBox.x1 = portPriv->pScrn->frameX0; 162635c4bbdfSmrg VPBox.y1 = portPriv->pScrn->frameY0; 162735c4bbdfSmrg VPBox.x2 = portPriv->pScrn->frameX1 + 1; 162835c4bbdfSmrg VPBox.y2 = portPriv->pScrn->frameY1 + 1; 162935c4bbdfSmrg 163035c4bbdfSmrg RegionInit(&VPReg, &VPBox, 1); 163135c4bbdfSmrg RegionIntersect(&ClipRegion, &ClipRegion, &VPReg); 163235c4bbdfSmrg RegionUninit(&VPReg); 163335c4bbdfSmrg } 163435c4bbdfSmrg 163535c4bbdfSmrg /* If we are changing windows, unregister our port in the old window */ 163635c4bbdfSmrg if (portPriv->pDraw && (portPriv->pDraw != pDraw)) 163735c4bbdfSmrg xf86XVRemovePortFromWindow((WindowPtr) (portPriv->pDraw), portPriv); 163835c4bbdfSmrg 163935c4bbdfSmrg /* Register our port with the new window */ 164035c4bbdfSmrg ret = xf86XVEnlistPortInWindow((WindowPtr) pDraw, portPriv); 164135c4bbdfSmrg if (ret != Success) 164235c4bbdfSmrg goto PUT_IMAGE_BAILOUT; 164335c4bbdfSmrg 164435c4bbdfSmrg if (!RegionNotEmpty(&ClipRegion)) { 164535c4bbdfSmrg clippedAway = TRUE; 164635c4bbdfSmrg goto PUT_IMAGE_BAILOUT; 164735c4bbdfSmrg } 164835c4bbdfSmrg 164935c4bbdfSmrg ret = (*portPriv->AdaptorRec->PutImage) (portPriv->pScrn, 165035c4bbdfSmrg src_x, src_y, WinBox.x1, WinBox.y1, 165135c4bbdfSmrg src_w, src_h, drw_w, drw_h, 165235c4bbdfSmrg format->id, data, width, height, 165335c4bbdfSmrg sync, &ClipRegion, 165435c4bbdfSmrg portPriv->DevPriv.ptr, pDraw); 165535c4bbdfSmrg 165635c4bbdfSmrg if ((ret == Success) && 165735c4bbdfSmrg (portPriv->AdaptorRec->flags & VIDEO_OVERLAID_IMAGES)) { 165835c4bbdfSmrg 165935c4bbdfSmrg portPriv->isOn = XV_ON; 166035c4bbdfSmrg portPriv->vid_x = src_x; 166135c4bbdfSmrg portPriv->vid_y = src_y; 166235c4bbdfSmrg portPriv->vid_w = src_w; 166335c4bbdfSmrg portPriv->vid_h = src_h; 166435c4bbdfSmrg portPriv->drw_x = drw_x; 166535c4bbdfSmrg portPriv->drw_y = drw_y; 166635c4bbdfSmrg portPriv->drw_w = drw_w; 166735c4bbdfSmrg portPriv->drw_h = drw_h; 166835c4bbdfSmrg portPriv->type = 0; /* no mask means it's transient and should 166935c4bbdfSmrg not be reput once it's removed */ 167035c4bbdfSmrg pPort->pDraw = pDraw; /* make sure we can get stop requests */ 167135c4bbdfSmrg } 167235c4bbdfSmrg 167335c4bbdfSmrg PUT_IMAGE_BAILOUT: 167435c4bbdfSmrg 167535c4bbdfSmrg if ((clippedAway || (ret != Success)) && (portPriv->isOn == XV_ON)) { 167635c4bbdfSmrg (*portPriv->AdaptorRec->StopVideo) (portPriv->pScrn, 167735c4bbdfSmrg portPriv->DevPriv.ptr, FALSE); 167835c4bbdfSmrg portPriv->isOn = XV_PENDING; 167935c4bbdfSmrg } 168035c4bbdfSmrg 168135c4bbdfSmrg /* This clip was copied and only good for one shot */ 168235c4bbdfSmrg if (!portPriv->FreeCompositeClip) 168335c4bbdfSmrg portPriv->pCompositeClip = NULL; 168435c4bbdfSmrg 168535c4bbdfSmrg RegionUninit(&WinRegion); 168635c4bbdfSmrg RegionUninit(&ClipRegion); 168735c4bbdfSmrg 168835c4bbdfSmrg return ret; 168905b261ecSmrg} 169005b261ecSmrg 169135c4bbdfSmrgstatic int 169235c4bbdfSmrgxf86XVQueryImageAttributes(XvPortPtr pPort, 169335c4bbdfSmrg XvImagePtr format, 169435c4bbdfSmrg CARD16 *width, 169535c4bbdfSmrg CARD16 *height, int *pitches, int *offsets) 169635c4bbdfSmrg{ 169735c4bbdfSmrg XvPortRecPrivatePtr portPriv = (XvPortRecPrivatePtr) (pPort->devPriv.ptr); 169805b261ecSmrg 169935c4bbdfSmrg return (*portPriv->AdaptorRec->QueryImageAttributes) (portPriv->pScrn, 170035c4bbdfSmrg format->id, width, 170135c4bbdfSmrg height, pitches, 170235c4bbdfSmrg offsets); 170305b261ecSmrg} 170405b261ecSmrg 17056747b715Smrgvoid 170635c4bbdfSmrgxf86XVFillKeyHelperDrawable(DrawablePtr pDraw, CARD32 key, RegionPtr fillboxes) 170705b261ecSmrg{ 170835c4bbdfSmrg ScreenPtr pScreen = pDraw->pScreen; 170935c4bbdfSmrg 171035c4bbdfSmrg if (!xf86ScreenToScrn(pScreen)->vtSema) 171135c4bbdfSmrg return; 171235c4bbdfSmrg 171335c4bbdfSmrg XvFillColorKey(pDraw, key, fillboxes); 171405b261ecSmrg} 171505b261ecSmrg 17169ace9065Smrgvoid 171735c4bbdfSmrgxf86XVFillKeyHelper(ScreenPtr pScreen, CARD32 key, RegionPtr fillboxes) 17189ace9065Smrg{ 171935c4bbdfSmrg xf86XVFillKeyHelperDrawable(&pScreen->root->drawable, key, fillboxes); 17209ace9065Smrg} 17219ace9065Smrg 17229ace9065Smrgvoid 172335c4bbdfSmrgxf86XVFillKeyHelperPort(DrawablePtr pDraw, void *data, CARD32 key, 172435c4bbdfSmrg RegionPtr clipboxes, Bool fillEverything) 17259ace9065Smrg{ 172635c4bbdfSmrg WindowPtr pWin = (WindowPtr) pDraw; 17279ace9065Smrg XF86XVWindowPtr WinPriv = GET_XF86XV_WINDOW(pWin); 17289ace9065Smrg XvPortRecPrivatePtr portPriv = NULL; 17299ace9065Smrg RegionRec reg; 17309ace9065Smrg RegionPtr fillboxes; 17319ace9065Smrg 17329ace9065Smrg while (WinPriv) { 173335c4bbdfSmrg XvPortRecPrivatePtr pPriv = WinPriv->PortRec; 17349ace9065Smrg 173535c4bbdfSmrg if (data == pPriv->DevPriv.ptr) { 173635c4bbdfSmrg portPriv = pPriv; 173735c4bbdfSmrg break; 173835c4bbdfSmrg } 17399ace9065Smrg 174035c4bbdfSmrg WinPriv = WinPriv->next; 17419ace9065Smrg } 17429ace9065Smrg 17439ace9065Smrg if (!portPriv) 174435c4bbdfSmrg return; 17459ace9065Smrg 17469ace9065Smrg if (!portPriv->ckeyFilled) 174735c4bbdfSmrg portPriv->ckeyFilled = RegionCreate(NULL, 0); 17489ace9065Smrg 17499ace9065Smrg if (!fillEverything) { 175035c4bbdfSmrg RegionNull(®); 175135c4bbdfSmrg fillboxes = ® 175235c4bbdfSmrg RegionSubtract(fillboxes, clipboxes, portPriv->ckeyFilled); 17539ace9065Smrg 175435c4bbdfSmrg if (!RegionNotEmpty(fillboxes)) 175535c4bbdfSmrg goto out; 175635c4bbdfSmrg } 175735c4bbdfSmrg else 175835c4bbdfSmrg fillboxes = clipboxes; 17599ace9065Smrg 17609ace9065Smrg RegionCopy(portPriv->ckeyFilled, clipboxes); 17619ace9065Smrg 17629ace9065Smrg xf86XVFillKeyHelperDrawable(pDraw, key, fillboxes); 176335c4bbdfSmrg out: 17649ace9065Smrg if (!fillEverything) 17659ace9065Smrg RegionUninit(®); 17669ace9065Smrg} 17679ace9065Smrg 176805b261ecSmrg/* xf86XVClipVideoHelper - 176905b261ecSmrg 177005b261ecSmrg Takes the dst box in standard X BoxRec form (top and left 177105b261ecSmrg edges inclusive, bottom and right exclusive). The new dst 177205b261ecSmrg box is returned. The source boundaries are given (x1, y1 177305b261ecSmrg inclusive, x2, y2 exclusive) and returned are the new source 177405b261ecSmrg boundaries in 16.16 fixed point. 177505b261ecSmrg*/ 177605b261ecSmrg 17776747b715SmrgBool 177835c4bbdfSmrgxf86XVClipVideoHelper(BoxPtr dst, 177935c4bbdfSmrg INT32 *xa, 178035c4bbdfSmrg INT32 *xb, 178135c4bbdfSmrg INT32 *ya, 178235c4bbdfSmrg INT32 *yb, RegionPtr reg, INT32 width, INT32 height) 178335c4bbdfSmrg{ 178405b261ecSmrg double xsw, xdw, ysw, ydw; 178505b261ecSmrg INT32 delta; 17866747b715Smrg BoxPtr extents = RegionExtents(reg); 178705b261ecSmrg int diff; 178805b261ecSmrg 178905b261ecSmrg xsw = (*xb - *xa) << 16; 179005b261ecSmrg xdw = dst->x2 - dst->x1; 179105b261ecSmrg ysw = (*yb - *ya) << 16; 179205b261ecSmrg ydw = dst->y2 - dst->y1; 179305b261ecSmrg 179435c4bbdfSmrg *xa <<= 16; 179535c4bbdfSmrg *xb <<= 16; 179635c4bbdfSmrg *ya <<= 16; 179735c4bbdfSmrg *yb <<= 16; 179805b261ecSmrg 179905b261ecSmrg diff = extents->x1 - dst->x1; 180005b261ecSmrg if (diff > 0) { 180135c4bbdfSmrg dst->x1 = extents->x1; 180235c4bbdfSmrg *xa += (diff * xsw) / xdw; 180305b261ecSmrg } 180405b261ecSmrg diff = dst->x2 - extents->x2; 180505b261ecSmrg if (diff > 0) { 180635c4bbdfSmrg dst->x2 = extents->x2; 180735c4bbdfSmrg *xb -= (diff * xsw) / xdw; 180805b261ecSmrg } 180905b261ecSmrg diff = extents->y1 - dst->y1; 181005b261ecSmrg if (diff > 0) { 181135c4bbdfSmrg dst->y1 = extents->y1; 181235c4bbdfSmrg *ya += (diff * ysw) / ydw; 181305b261ecSmrg } 181405b261ecSmrg diff = dst->y2 - extents->y2; 181505b261ecSmrg if (diff > 0) { 181635c4bbdfSmrg dst->y2 = extents->y2; 181735c4bbdfSmrg *yb -= (diff * ysw) / ydw; 181805b261ecSmrg } 181905b261ecSmrg 182005b261ecSmrg if (*xa < 0) { 182135c4bbdfSmrg diff = (((-*xa) * xdw) + xsw - 1) / xsw; 182235c4bbdfSmrg dst->x1 += diff; 182335c4bbdfSmrg *xa += (diff * xsw) / xdw; 182405b261ecSmrg } 182505b261ecSmrg delta = *xb - (width << 16); 182605b261ecSmrg if (delta > 0) { 182735c4bbdfSmrg diff = ((delta * xdw) + xsw - 1) / xsw; 182835c4bbdfSmrg dst->x2 -= diff; 182935c4bbdfSmrg *xb -= (diff * xsw) / xdw; 183005b261ecSmrg } 183135c4bbdfSmrg if (*xa >= *xb) 183235c4bbdfSmrg return FALSE; 183305b261ecSmrg 183405b261ecSmrg if (*ya < 0) { 183535c4bbdfSmrg diff = (((-*ya) * ydw) + ysw - 1) / ysw; 183635c4bbdfSmrg dst->y1 += diff; 183735c4bbdfSmrg *ya += (diff * ysw) / ydw; 183805b261ecSmrg } 183905b261ecSmrg delta = *yb - (height << 16); 184005b261ecSmrg if (delta > 0) { 184135c4bbdfSmrg diff = ((delta * ydw) + ysw - 1) / ysw; 184235c4bbdfSmrg dst->y2 -= diff; 184335c4bbdfSmrg *yb -= (diff * ysw) / ydw; 184405b261ecSmrg } 184535c4bbdfSmrg if (*ya >= *yb) 184635c4bbdfSmrg return FALSE; 184705b261ecSmrg 184805b261ecSmrg if ((dst->x1 > extents->x1) || (dst->x2 < extents->x2) || 184935c4bbdfSmrg (dst->y1 > extents->y1) || (dst->y2 < extents->y2)) { 185035c4bbdfSmrg RegionRec clipReg; 185135c4bbdfSmrg 185235c4bbdfSmrg RegionInit(&clipReg, dst, 1); 185335c4bbdfSmrg RegionIntersect(reg, reg, &clipReg); 185435c4bbdfSmrg RegionUninit(&clipReg); 185505b261ecSmrg } 185605b261ecSmrg return TRUE; 185705b261ecSmrg} 185805b261ecSmrg 18596747b715Smrgvoid 186035c4bbdfSmrgxf86XVCopyYUV12ToPacked(const void *srcy, 186135c4bbdfSmrg const void *srcv, 186235c4bbdfSmrg const void *srcu, 186335c4bbdfSmrg void *dst, 186435c4bbdfSmrg int srcPitchy, 186535c4bbdfSmrg int srcPitchuv, int dstPitch, int h, int w) 186635c4bbdfSmrg{ 186705b261ecSmrg CARD32 *Dst; 186805b261ecSmrg const CARD8 *Y, *U, *V; 186905b261ecSmrg int i, j; 187005b261ecSmrg 187105b261ecSmrg w >>= 1; 187205b261ecSmrg 187335c4bbdfSmrg for (j = 0; j < h; j++) { 187435c4bbdfSmrg Dst = dst; 187535c4bbdfSmrg Y = srcy; 187635c4bbdfSmrg V = srcv; 187735c4bbdfSmrg U = srcu; 187835c4bbdfSmrg i = w; 187935c4bbdfSmrg while (i >= 4) { 188005b261ecSmrg#if X_BYTE_ORDER == X_LITTLE_ENDIAN 188135c4bbdfSmrg Dst[0] = Y[0] | (Y[1] << 16) | (U[0] << 8) | (V[0] << 24); 188235c4bbdfSmrg Dst[1] = Y[2] | (Y[3] << 16) | (U[1] << 8) | (V[1] << 24); 188335c4bbdfSmrg Dst[2] = Y[4] | (Y[5] << 16) | (U[2] << 8) | (V[2] << 24); 188435c4bbdfSmrg Dst[3] = Y[6] | (Y[7] << 16) | (U[3] << 8) | (V[3] << 24); 188505b261ecSmrg#else 188635c4bbdfSmrg /* This assumes a little-endian framebuffer */ 188735c4bbdfSmrg Dst[0] = (Y[0] << 24) | (Y[1] << 8) | (U[0] << 16) | V[0]; 188835c4bbdfSmrg Dst[1] = (Y[2] << 24) | (Y[3] << 8) | (U[1] << 16) | V[1]; 188935c4bbdfSmrg Dst[2] = (Y[4] << 24) | (Y[5] << 8) | (U[2] << 16) | V[2]; 189035c4bbdfSmrg Dst[3] = (Y[6] << 24) | (Y[7] << 8) | (U[3] << 16) | V[3]; 189105b261ecSmrg#endif 189235c4bbdfSmrg Dst += 4; 189335c4bbdfSmrg Y += 8; 189435c4bbdfSmrg V += 4; 189535c4bbdfSmrg U += 4; 189635c4bbdfSmrg i -= 4; 189735c4bbdfSmrg } 189835c4bbdfSmrg 189935c4bbdfSmrg while (i--) { 190005b261ecSmrg#if X_BYTE_ORDER == X_LITTLE_ENDIAN 190135c4bbdfSmrg Dst[0] = Y[0] | (Y[1] << 16) | (U[0] << 8) | (V[0] << 24); 190205b261ecSmrg#else 190335c4bbdfSmrg /* This assumes a little-endian framebuffer */ 190435c4bbdfSmrg Dst[0] = (Y[0] << 24) | (Y[1] << 8) | (U[0] << 16) | V[0]; 190505b261ecSmrg#endif 190635c4bbdfSmrg Dst++; 190735c4bbdfSmrg Y += 2; 190835c4bbdfSmrg V++; 190935c4bbdfSmrg U++; 191035c4bbdfSmrg } 191135c4bbdfSmrg 191235c4bbdfSmrg dst = (CARD8 *) dst + dstPitch; 191335c4bbdfSmrg srcy = (const CARD8 *) srcy + srcPitchy; 191435c4bbdfSmrg if (j & 1) { 191535c4bbdfSmrg srcu = (const CARD8 *) srcu + srcPitchuv; 191635c4bbdfSmrg srcv = (const CARD8 *) srcv + srcPitchuv; 191735c4bbdfSmrg } 191805b261ecSmrg } 191905b261ecSmrg} 192005b261ecSmrg 19216747b715Smrgvoid 192235c4bbdfSmrgxf86XVCopyPacked(const void *src, 192335c4bbdfSmrg void *dst, int srcPitch, int dstPitch, int h, int w) 192435c4bbdfSmrg{ 192505b261ecSmrg const CARD32 *Src; 192605b261ecSmrg CARD32 *Dst; 192705b261ecSmrg int i; 192805b261ecSmrg 192905b261ecSmrg w >>= 1; 193005b261ecSmrg while (--h >= 0) { 193135c4bbdfSmrg do { 193235c4bbdfSmrg Dst = dst; 193335c4bbdfSmrg Src = src; 193435c4bbdfSmrg i = w; 193535c4bbdfSmrg while (i >= 4) { 193635c4bbdfSmrg Dst[0] = Src[0]; 193735c4bbdfSmrg Dst[1] = Src[1]; 193835c4bbdfSmrg Dst[2] = Src[2]; 193935c4bbdfSmrg Dst[3] = Src[3]; 194035c4bbdfSmrg Dst += 4; 194135c4bbdfSmrg Src += 4; 194235c4bbdfSmrg i -= 4; 194335c4bbdfSmrg } 194435c4bbdfSmrg if (!i) 194535c4bbdfSmrg break; 194635c4bbdfSmrg Dst[0] = Src[0]; 194735c4bbdfSmrg if (i == 1) 194835c4bbdfSmrg break; 194935c4bbdfSmrg Dst[1] = Src[1]; 195035c4bbdfSmrg if (i == 2) 195135c4bbdfSmrg break; 195235c4bbdfSmrg Dst[2] = Src[2]; 195335c4bbdfSmrg } while (0); 195435c4bbdfSmrg 195535c4bbdfSmrg src = (const CARD8 *) src + srcPitch; 195635c4bbdfSmrg dst = (CARD8 *) dst + dstPitch; 195705b261ecSmrg } 195805b261ecSmrg} 1959