1706f2543Smrg/* 2706f2543Smrg 3706f2543Smrg XFree86 Xv DDX written by Mark Vojkovich (markv@valinux.com) 4706f2543Smrg Adapted for KDrive by Pontus Lidman <pontus.lidman@nokia.com> 5706f2543Smrg 6706f2543Smrg Copyright (C) 2000, 2001 - Nokia Home Communications 7706f2543Smrg Copyright (C) 1998, 1999 - The XFree86 Project Inc. 8706f2543Smrg 9706f2543SmrgAll rights reserved. 10706f2543Smrg 11706f2543SmrgPermission is hereby granted, free of charge, to any person obtaining 12706f2543Smrga copy of this software and associated documentation files (the 13706f2543Smrg"Software"), to deal in the Software without restriction, including 14706f2543Smrgwithout limitation the rights to use, copy, modify, merge, publish, 15706f2543Smrgdistribute, and/or sell copies of the Software, and to permit persons 16706f2543Smrgto whom the Software is furnished to do so, provided that the above 17706f2543Smrgcopyright notice(s) and this permission notice appear in all copies of 18706f2543Smrgthe Software and that both the above copyright notice(s) and this 19706f2543Smrgpermission notice appear in supporting documentation. 20706f2543Smrg 21706f2543SmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 22706f2543SmrgEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 23706f2543SmrgMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT 24706f2543SmrgOF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 25706f2543SmrgHOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY 26706f2543SmrgSPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER 27706f2543SmrgRESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF 28706f2543SmrgCONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN 29706f2543SmrgCONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 30706f2543Smrg 31706f2543SmrgExcept as contained in this notice, the name of a copyright holder 32706f2543Smrgshall not be used in advertising or otherwise to promote the sale, use 33706f2543Smrgor other dealings in this Software without prior written authorization 34706f2543Smrgof the copyright holder. 35706f2543Smrg 36706f2543Smrg*/ 37706f2543Smrg 38706f2543Smrg#ifdef HAVE_CONFIG_H 39706f2543Smrg#include <kdrive-config.h> 40706f2543Smrg#endif 41706f2543Smrg#include "kdrive.h" 42706f2543Smrg 43706f2543Smrg#include "scrnintstr.h" 44706f2543Smrg#include "regionstr.h" 45706f2543Smrg#include "windowstr.h" 46706f2543Smrg#include "pixmapstr.h" 47706f2543Smrg#include "mivalidate.h" 48706f2543Smrg#include "validate.h" 49706f2543Smrg#include "resource.h" 50706f2543Smrg#include "gcstruct.h" 51706f2543Smrg#include "dixstruct.h" 52706f2543Smrg 53706f2543Smrg#include <X11/extensions/Xv.h> 54706f2543Smrg#include <X11/extensions/Xvproto.h> 55706f2543Smrg 56706f2543Smrg#include "kxv.h" 57706f2543Smrg#include "fourcc.h" 58706f2543Smrg 59706f2543Smrg 60706f2543Smrg/* XvScreenRec fields */ 61706f2543Smrg 62706f2543Smrgstatic Bool KdXVCloseScreen(int, ScreenPtr); 63706f2543Smrgstatic int KdXVQueryAdaptors(ScreenPtr, XvAdaptorPtr *, int *); 64706f2543Smrg 65706f2543Smrg/* XvAdaptorRec fields */ 66706f2543Smrg 67706f2543Smrgstatic int KdXVAllocatePort(unsigned long, XvPortPtr, XvPortPtr*); 68706f2543Smrgstatic int KdXVFreePort(XvPortPtr); 69706f2543Smrgstatic int KdXVPutVideo(ClientPtr, DrawablePtr,XvPortPtr, GCPtr, 70706f2543Smrg INT16, INT16, CARD16, CARD16, 71706f2543Smrg INT16, INT16, CARD16, CARD16); 72706f2543Smrgstatic int KdXVPutStill(ClientPtr, DrawablePtr,XvPortPtr, GCPtr, 73706f2543Smrg INT16, INT16, CARD16, CARD16, 74706f2543Smrg INT16, INT16, CARD16, CARD16); 75706f2543Smrgstatic int KdXVGetVideo(ClientPtr, DrawablePtr,XvPortPtr, GCPtr, 76706f2543Smrg INT16, INT16, CARD16, CARD16, 77706f2543Smrg INT16, INT16, CARD16, CARD16); 78706f2543Smrgstatic int KdXVGetStill(ClientPtr, DrawablePtr,XvPortPtr, GCPtr, 79706f2543Smrg INT16, INT16, CARD16, CARD16, 80706f2543Smrg INT16, INT16, CARD16, CARD16); 81706f2543Smrgstatic int KdXVStopVideo(ClientPtr, XvPortPtr, DrawablePtr); 82706f2543Smrgstatic int KdXVSetPortAttribute(ClientPtr, XvPortPtr, Atom, INT32); 83706f2543Smrgstatic int KdXVGetPortAttribute(ClientPtr, XvPortPtr, Atom, INT32 *); 84706f2543Smrgstatic int KdXVQueryBestSize(ClientPtr, XvPortPtr, CARD8, 85706f2543Smrg CARD16, CARD16,CARD16, CARD16, 86706f2543Smrg unsigned int*, unsigned int*); 87706f2543Smrgstatic int KdXVPutImage(ClientPtr, DrawablePtr, XvPortPtr, GCPtr, 88706f2543Smrg INT16, INT16, CARD16, CARD16, 89706f2543Smrg INT16, INT16, CARD16, CARD16, 90706f2543Smrg XvImagePtr, unsigned char*, Bool, 91706f2543Smrg CARD16, CARD16); 92706f2543Smrgstatic int KdXVQueryImageAttributes(ClientPtr, XvPortPtr, XvImagePtr, 93706f2543Smrg CARD16*, CARD16*, int*, int*); 94706f2543Smrg 95706f2543Smrg 96706f2543Smrg/* ScreenRec fields */ 97706f2543Smrg 98706f2543Smrgstatic Bool KdXVCreateWindow(WindowPtr pWin); 99706f2543Smrgstatic Bool KdXVDestroyWindow(WindowPtr pWin); 100706f2543Smrgstatic void KdXVWindowExposures(WindowPtr pWin, RegionPtr r1, RegionPtr r2); 101706f2543Smrgstatic void KdXVClipNotify(WindowPtr pWin, int dx, int dy); 102706f2543Smrg 103706f2543Smrg/* misc */ 104706f2543Smrgstatic Bool KdXVInitAdaptors(ScreenPtr, KdVideoAdaptorPtr*, int); 105706f2543Smrg 106706f2543Smrgstatic DevPrivateKeyRec KdXVWindowKeyRec; 107706f2543Smrg#define KdXVWindowKey (&KdXVWindowKeyRec) 108706f2543Smrgstatic DevPrivateKey KdXvScreenKey; 109706f2543Smrgstatic unsigned long KdXVGeneration = 0; 110706f2543Smrgstatic unsigned long PortResource = 0; 111706f2543Smrg 112706f2543SmrgDevPrivateKey (*XvGetScreenKeyProc)(void) = XvGetScreenKey; 113706f2543Smrgunsigned long (*XvGetRTPortProc)(void) = XvGetRTPort; 114706f2543Smrgint (*XvScreenInitProc)(ScreenPtr) = XvScreenInit; 115706f2543Smrg 116706f2543Smrg#define GET_XV_SCREEN(pScreen) ((XvScreenPtr) \ 117706f2543Smrg dixLookupPrivate(&(pScreen)->devPrivates, KdXvScreenKey)) 118706f2543Smrg 119706f2543Smrg#define GET_KDXV_SCREEN(pScreen) \ 120706f2543Smrg ((KdXVScreenPtr)(GET_XV_SCREEN(pScreen)->devPriv.ptr)) 121706f2543Smrg 122706f2543Smrg#define GET_KDXV_WINDOW(pWin) ((KdXVWindowPtr) \ 123706f2543Smrg dixLookupPrivate(&(pWin)->devPrivates, KdXVWindowKey)) 124706f2543Smrg 125706f2543Smrgstatic KdXVInitGenericAdaptorPtr *GenDrivers = NULL; 126706f2543Smrgstatic int NumGenDrivers = 0; 127706f2543Smrg 128706f2543Smrgint 129706f2543SmrgKdXVRegisterGenericAdaptorDriver( 130706f2543Smrg KdXVInitGenericAdaptorPtr InitFunc 131706f2543Smrg){ 132706f2543Smrg KdXVInitGenericAdaptorPtr *newdrivers; 133706f2543Smrg 134706f2543Smrg/* fprintf(stderr,"KdXVRegisterGenericAdaptorDriver\n"); */ 135706f2543Smrg 136706f2543Smrg newdrivers = realloc(GenDrivers, sizeof(KdXVInitGenericAdaptorPtr) * 137706f2543Smrg (1 + NumGenDrivers)); 138706f2543Smrg if (!newdrivers) 139706f2543Smrg return 0; 140706f2543Smrg GenDrivers = newdrivers; 141706f2543Smrg 142706f2543Smrg GenDrivers[NumGenDrivers++] = InitFunc; 143706f2543Smrg 144706f2543Smrg return 1; 145706f2543Smrg} 146706f2543Smrg 147706f2543Smrgint 148706f2543SmrgKdXVListGenericAdaptors( 149706f2543Smrg KdScreenInfo * screen, 150706f2543Smrg KdVideoAdaptorPtr **adaptors 151706f2543Smrg){ 152706f2543Smrg int i,j,n,num; 153706f2543Smrg KdVideoAdaptorPtr *DrivAdap,*new; 154706f2543Smrg 155706f2543Smrg num = 0; 156706f2543Smrg *adaptors = NULL; 157706f2543Smrg for (i = 0; i < NumGenDrivers; i++) { 158706f2543Smrg n = GenDrivers[i](screen,&DrivAdap); 159706f2543Smrg if (0 == n) 160706f2543Smrg continue; 161706f2543Smrg new = realloc(*adaptors, sizeof(KdVideoAdaptorPtr) * (num+n)); 162706f2543Smrg if (NULL == new) 163706f2543Smrg continue; 164706f2543Smrg *adaptors = new; 165706f2543Smrg for (j = 0; j < n; j++, num++) 166706f2543Smrg (*adaptors)[num] = DrivAdap[j]; 167706f2543Smrg } 168706f2543Smrg return num; 169706f2543Smrg} 170706f2543Smrg 171706f2543SmrgKdVideoAdaptorPtr 172706f2543SmrgKdXVAllocateVideoAdaptorRec(KdScreenInfo * screen) 173706f2543Smrg{ 174706f2543Smrg return calloc(1, sizeof(KdVideoAdaptorRec)); 175706f2543Smrg} 176706f2543Smrg 177706f2543Smrgvoid 178706f2543SmrgKdXVFreeVideoAdaptorRec(KdVideoAdaptorPtr ptr) 179706f2543Smrg{ 180706f2543Smrg free(ptr); 181706f2543Smrg} 182706f2543Smrg 183706f2543Smrg 184706f2543SmrgBool 185706f2543SmrgKdXVScreenInit( 186706f2543Smrg ScreenPtr pScreen, 187706f2543Smrg KdVideoAdaptorPtr *adaptors, 188706f2543Smrg int num 189706f2543Smrg){ 190706f2543Smrg KdXVScreenPtr ScreenPriv; 191706f2543Smrg XvScreenPtr pxvs; 192706f2543Smrg 193706f2543Smrg/* fprintf(stderr,"KdXVScreenInit initializing %d adaptors\n",num); */ 194706f2543Smrg 195706f2543Smrg if (KdXVGeneration != serverGeneration) 196706f2543Smrg KdXVGeneration = serverGeneration; 197706f2543Smrg 198706f2543Smrg if(!XvGetScreenKeyProc || !XvGetRTPortProc || !XvScreenInitProc) 199706f2543Smrg return FALSE; 200706f2543Smrg 201706f2543Smrg if (!dixRegisterPrivateKey(&KdXVWindowKeyRec, PRIVATE_WINDOW, 0)) 202706f2543Smrg return FALSE; 203706f2543Smrg 204706f2543Smrg if(Success != (*XvScreenInitProc)(pScreen)) return FALSE; 205706f2543Smrg 206706f2543Smrg KdXvScreenKey = (*XvGetScreenKeyProc)(); 207706f2543Smrg PortResource = (*XvGetRTPortProc)(); 208706f2543Smrg 209706f2543Smrg pxvs = GET_XV_SCREEN(pScreen); 210706f2543Smrg 211706f2543Smrg 212706f2543Smrg /* Anyone initializing the Xv layer must provide these two. 213706f2543Smrg The Xv di layer calls them without even checking if they exist! */ 214706f2543Smrg 215706f2543Smrg pxvs->ddCloseScreen = KdXVCloseScreen; 216706f2543Smrg pxvs->ddQueryAdaptors = KdXVQueryAdaptors; 217706f2543Smrg 218706f2543Smrg /* The Xv di layer provides us with a private hook so that we don't 219706f2543Smrg have to allocate our own screen private. They also provide 220706f2543Smrg a CloseScreen hook so that we don't have to wrap it. I'm not 221706f2543Smrg sure that I appreciate that. */ 222706f2543Smrg 223706f2543Smrg ScreenPriv = malloc(sizeof(KdXVScreenRec)); 224706f2543Smrg pxvs->devPriv.ptr = (pointer)ScreenPriv; 225706f2543Smrg 226706f2543Smrg if(!ScreenPriv) return FALSE; 227706f2543Smrg 228706f2543Smrg 229706f2543Smrg ScreenPriv->CreateWindow = pScreen->CreateWindow; 230706f2543Smrg ScreenPriv->DestroyWindow = pScreen->DestroyWindow; 231706f2543Smrg ScreenPriv->WindowExposures = pScreen->WindowExposures; 232706f2543Smrg ScreenPriv->ClipNotify = pScreen->ClipNotify; 233706f2543Smrg 234706f2543Smrg/* fprintf(stderr,"XV: Wrapping screen funcs\n"); */ 235706f2543Smrg 236706f2543Smrg pScreen->CreateWindow = KdXVCreateWindow; 237706f2543Smrg pScreen->DestroyWindow = KdXVDestroyWindow; 238706f2543Smrg pScreen->WindowExposures = KdXVWindowExposures; 239706f2543Smrg pScreen->ClipNotify = KdXVClipNotify; 240706f2543Smrg 241706f2543Smrg if(!KdXVInitAdaptors(pScreen, adaptors, num)) 242706f2543Smrg return FALSE; 243706f2543Smrg 244706f2543Smrg return TRUE; 245706f2543Smrg} 246706f2543Smrg 247706f2543Smrgstatic void 248706f2543SmrgKdXVFreeAdaptor(XvAdaptorPtr pAdaptor) 249706f2543Smrg{ 250706f2543Smrg int i; 251706f2543Smrg 252706f2543Smrg free(pAdaptor->name); 253706f2543Smrg 254706f2543Smrg if(pAdaptor->pEncodings) { 255706f2543Smrg XvEncodingPtr pEncode = pAdaptor->pEncodings; 256706f2543Smrg 257706f2543Smrg for(i = 0; i < pAdaptor->nEncodings; i++, pEncode++) { 258706f2543Smrg free(pEncode->name); 259706f2543Smrg } 260706f2543Smrg free(pAdaptor->pEncodings); 261706f2543Smrg } 262706f2543Smrg 263706f2543Smrg free(pAdaptor->pFormats); 264706f2543Smrg 265706f2543Smrg if(pAdaptor->pPorts) { 266706f2543Smrg XvPortPtr pPort = pAdaptor->pPorts; 267706f2543Smrg XvPortRecPrivatePtr pPriv; 268706f2543Smrg 269706f2543Smrg for(i = 0; i < pAdaptor->nPorts; i++, pPort++) { 270706f2543Smrg pPriv = (XvPortRecPrivatePtr)pPort->devPriv.ptr; 271706f2543Smrg if(pPriv) { 272706f2543Smrg if(pPriv->clientClip) 273706f2543Smrg RegionDestroy(pPriv->clientClip); 274706f2543Smrg if(pPriv->pCompositeClip && pPriv->FreeCompositeClip) 275706f2543Smrg RegionDestroy(pPriv->pCompositeClip); 276706f2543Smrg free(pPriv); 277706f2543Smrg } 278706f2543Smrg } 279706f2543Smrg free(pAdaptor->pPorts); 280706f2543Smrg } 281706f2543Smrg 282706f2543Smrg if(pAdaptor->nAttributes) { 283706f2543Smrg XvAttributePtr pAttribute = pAdaptor->pAttributes; 284706f2543Smrg 285706f2543Smrg for(i = 0; i < pAdaptor->nAttributes; i++, pAttribute++) { 286706f2543Smrg free(pAttribute->name); 287706f2543Smrg } 288706f2543Smrg 289706f2543Smrg free(pAdaptor->pAttributes); 290706f2543Smrg } 291706f2543Smrg 292706f2543Smrg free(pAdaptor->pImages); 293706f2543Smrg 294706f2543Smrg free(pAdaptor->devPriv.ptr); 295706f2543Smrg} 296706f2543Smrg 297706f2543Smrgstatic Bool 298706f2543SmrgKdXVInitAdaptors( 299706f2543Smrg ScreenPtr pScreen, 300706f2543Smrg KdVideoAdaptorPtr *infoPtr, 301706f2543Smrg int number 302706f2543Smrg) { 303706f2543Smrg KdScreenPriv(pScreen); 304706f2543Smrg KdScreenInfo * screen = pScreenPriv->screen; 305706f2543Smrg 306706f2543Smrg XvScreenPtr pxvs = GET_XV_SCREEN(pScreen); 307706f2543Smrg KdVideoAdaptorPtr adaptorPtr; 308706f2543Smrg XvAdaptorPtr pAdaptor, pa; 309706f2543Smrg XvAdaptorRecPrivatePtr adaptorPriv; 310706f2543Smrg int na, numAdaptor; 311706f2543Smrg XvPortRecPrivatePtr portPriv; 312706f2543Smrg XvPortPtr pPort, pp; 313706f2543Smrg int numPort; 314706f2543Smrg KdAttributePtr attributePtr; 315706f2543Smrg XvAttributePtr pAttribute, pat; 316706f2543Smrg KdVideoFormatPtr formatPtr; 317706f2543Smrg XvFormatPtr pFormat, pf; 318706f2543Smrg int numFormat, totFormat; 319706f2543Smrg KdVideoEncodingPtr encodingPtr; 320706f2543Smrg XvEncodingPtr pEncode, pe; 321706f2543Smrg KdImagePtr imagePtr; 322706f2543Smrg XvImagePtr pImage, pi; 323706f2543Smrg int numVisuals; 324706f2543Smrg VisualPtr pVisual; 325706f2543Smrg int i; 326706f2543Smrg 327706f2543Smrg pxvs->nAdaptors = 0; 328706f2543Smrg pxvs->pAdaptors = NULL; 329706f2543Smrg 330706f2543Smrg if(!(pAdaptor = calloc(number, sizeof(XvAdaptorRec)))) 331706f2543Smrg return FALSE; 332706f2543Smrg 333706f2543Smrg for(pa = pAdaptor, na = 0, numAdaptor = 0; na < number; na++, adaptorPtr++) { 334706f2543Smrg adaptorPtr = infoPtr[na]; 335706f2543Smrg 336706f2543Smrg if(!adaptorPtr->StopVideo || !adaptorPtr->SetPortAttribute || 337706f2543Smrg !adaptorPtr->GetPortAttribute || !adaptorPtr->QueryBestSize) 338706f2543Smrg continue; 339706f2543Smrg 340706f2543Smrg /* client libs expect at least one encoding */ 341706f2543Smrg if(!adaptorPtr->nEncodings || !adaptorPtr->pEncodings) 342706f2543Smrg continue; 343706f2543Smrg 344706f2543Smrg pa->type = adaptorPtr->type; 345706f2543Smrg 346706f2543Smrg if(!adaptorPtr->PutVideo && !adaptorPtr->GetVideo) 347706f2543Smrg pa->type &= ~XvVideoMask; 348706f2543Smrg 349706f2543Smrg if(!adaptorPtr->PutStill && !adaptorPtr->GetStill) 350706f2543Smrg pa->type &= ~XvStillMask; 351706f2543Smrg 352706f2543Smrg if(!adaptorPtr->PutImage || !adaptorPtr->QueryImageAttributes) 353706f2543Smrg pa->type &= ~XvImageMask; 354706f2543Smrg 355706f2543Smrg if(!adaptorPtr->PutVideo && !adaptorPtr->PutImage && 356706f2543Smrg !adaptorPtr->PutStill) 357706f2543Smrg pa->type &= ~XvInputMask; 358706f2543Smrg 359706f2543Smrg if(!adaptorPtr->GetVideo && !adaptorPtr->GetStill) 360706f2543Smrg pa->type &= ~XvOutputMask; 361706f2543Smrg 362706f2543Smrg if(!(adaptorPtr->type & (XvPixmapMask | XvWindowMask))) 363706f2543Smrg continue; 364706f2543Smrg if(!(adaptorPtr->type & (XvImageMask | XvVideoMask | XvStillMask))) 365706f2543Smrg continue; 366706f2543Smrg 367706f2543Smrg pa->pScreen = pScreen; 368706f2543Smrg pa->ddAllocatePort = KdXVAllocatePort; 369706f2543Smrg pa->ddFreePort = KdXVFreePort; 370706f2543Smrg pa->ddPutVideo = KdXVPutVideo; 371706f2543Smrg pa->ddPutStill = KdXVPutStill; 372706f2543Smrg pa->ddGetVideo = KdXVGetVideo; 373706f2543Smrg pa->ddGetStill = KdXVGetStill; 374706f2543Smrg pa->ddStopVideo = KdXVStopVideo; 375706f2543Smrg pa->ddPutImage = KdXVPutImage; 376706f2543Smrg pa->ddSetPortAttribute = KdXVSetPortAttribute; 377706f2543Smrg pa->ddGetPortAttribute = KdXVGetPortAttribute; 378706f2543Smrg pa->ddQueryBestSize = KdXVQueryBestSize; 379706f2543Smrg pa->ddQueryImageAttributes = KdXVQueryImageAttributes; 380706f2543Smrg pa->name = strdup(adaptorPtr->name); 381706f2543Smrg 382706f2543Smrg if(adaptorPtr->nEncodings && 383706f2543Smrg (pEncode = calloc(adaptorPtr->nEncodings, sizeof(XvEncodingRec)))) { 384706f2543Smrg 385706f2543Smrg for(pe = pEncode, encodingPtr = adaptorPtr->pEncodings, i = 0; 386706f2543Smrg i < adaptorPtr->nEncodings; pe++, i++, encodingPtr++) 387706f2543Smrg { 388706f2543Smrg pe->id = encodingPtr->id; 389706f2543Smrg pe->pScreen = pScreen; 390706f2543Smrg pe->name = strdup(encodingPtr->name); 391706f2543Smrg pe->width = encodingPtr->width; 392706f2543Smrg pe->height = encodingPtr->height; 393706f2543Smrg pe->rate.numerator = encodingPtr->rate.numerator; 394706f2543Smrg pe->rate.denominator = encodingPtr->rate.denominator; 395706f2543Smrg } 396706f2543Smrg pa->nEncodings = adaptorPtr->nEncodings; 397706f2543Smrg pa->pEncodings = pEncode; 398706f2543Smrg } 399706f2543Smrg 400706f2543Smrg if(adaptorPtr->nImages && 401706f2543Smrg (pImage = calloc(adaptorPtr->nImages, sizeof(XvImageRec)))) { 402706f2543Smrg 403706f2543Smrg for(i = 0, pi = pImage, imagePtr = adaptorPtr->pImages; 404706f2543Smrg i < adaptorPtr->nImages; i++, pi++, imagePtr++) 405706f2543Smrg { 406706f2543Smrg pi->id = imagePtr->id; 407706f2543Smrg pi->type = imagePtr->type; 408706f2543Smrg pi->byte_order = imagePtr->byte_order; 409706f2543Smrg memcpy(pi->guid, imagePtr->guid, 16); 410706f2543Smrg pi->bits_per_pixel = imagePtr->bits_per_pixel; 411706f2543Smrg pi->format = imagePtr->format; 412706f2543Smrg pi->num_planes = imagePtr->num_planes; 413706f2543Smrg pi->depth = imagePtr->depth; 414706f2543Smrg pi->red_mask = imagePtr->red_mask; 415706f2543Smrg pi->green_mask = imagePtr->green_mask; 416706f2543Smrg pi->blue_mask = imagePtr->blue_mask; 417706f2543Smrg pi->y_sample_bits = imagePtr->y_sample_bits; 418706f2543Smrg pi->u_sample_bits = imagePtr->u_sample_bits; 419706f2543Smrg pi->v_sample_bits = imagePtr->v_sample_bits; 420706f2543Smrg pi->horz_y_period = imagePtr->horz_y_period; 421706f2543Smrg pi->horz_u_period = imagePtr->horz_u_period; 422706f2543Smrg pi->horz_v_period = imagePtr->horz_v_period; 423706f2543Smrg pi->vert_y_period = imagePtr->vert_y_period; 424706f2543Smrg pi->vert_u_period = imagePtr->vert_u_period; 425706f2543Smrg pi->vert_v_period = imagePtr->vert_v_period; 426706f2543Smrg memcpy(pi->component_order, imagePtr->component_order, 32); 427706f2543Smrg pi->scanline_order = imagePtr->scanline_order; 428706f2543Smrg } 429706f2543Smrg pa->nImages = adaptorPtr->nImages; 430706f2543Smrg pa->pImages = pImage; 431706f2543Smrg } 432706f2543Smrg 433706f2543Smrg if(adaptorPtr->nAttributes && 434706f2543Smrg (pAttribute = calloc(adaptorPtr->nAttributes, sizeof(XvAttributeRec)))) 435706f2543Smrg { 436706f2543Smrg for(pat = pAttribute, attributePtr = adaptorPtr->pAttributes, i = 0; 437706f2543Smrg i < adaptorPtr->nAttributes; pat++, i++, attributePtr++) 438706f2543Smrg { 439706f2543Smrg pat->flags = attributePtr->flags; 440706f2543Smrg pat->min_value = attributePtr->min_value; 441706f2543Smrg pat->max_value = attributePtr->max_value; 442706f2543Smrg pat->name = strdup(attributePtr->name); 443706f2543Smrg } 444706f2543Smrg pa->nAttributes = adaptorPtr->nAttributes; 445706f2543Smrg pa->pAttributes = pAttribute; 446706f2543Smrg } 447706f2543Smrg 448706f2543Smrg 449706f2543Smrg totFormat = adaptorPtr->nFormats; 450706f2543Smrg 451706f2543Smrg if(!(pFormat = calloc(totFormat, sizeof(XvFormatRec)))) { 452706f2543Smrg KdXVFreeAdaptor(pa); 453706f2543Smrg continue; 454706f2543Smrg } 455706f2543Smrg for(pf = pFormat, i = 0, numFormat = 0, formatPtr = adaptorPtr->pFormats; 456706f2543Smrg i < adaptorPtr->nFormats; i++, formatPtr++) 457706f2543Smrg { 458706f2543Smrg numVisuals = pScreen->numVisuals; 459706f2543Smrg pVisual = pScreen->visuals; 460706f2543Smrg 461706f2543Smrg while(numVisuals--) { 462706f2543Smrg if((pVisual->class == formatPtr->class) && 463706f2543Smrg (pVisual->nplanes == formatPtr->depth)) { 464706f2543Smrg 465706f2543Smrg if(numFormat >= totFormat) { 466706f2543Smrg void *moreSpace; 467706f2543Smrg totFormat *= 2; 468706f2543Smrg moreSpace = realloc(pFormat, 469706f2543Smrg totFormat * sizeof(XvFormatRec)); 470706f2543Smrg if(!moreSpace) break; 471706f2543Smrg pFormat = moreSpace; 472706f2543Smrg pf = pFormat + numFormat; 473706f2543Smrg } 474706f2543Smrg 475706f2543Smrg pf->visual = pVisual->vid; 476706f2543Smrg pf->depth = formatPtr->depth; 477706f2543Smrg 478706f2543Smrg pf++; 479706f2543Smrg numFormat++; 480706f2543Smrg } 481706f2543Smrg pVisual++; 482706f2543Smrg } 483706f2543Smrg } 484706f2543Smrg pa->nFormats = numFormat; 485706f2543Smrg pa->pFormats = pFormat; 486706f2543Smrg if(!numFormat) { 487706f2543Smrg KdXVFreeAdaptor(pa); 488706f2543Smrg continue; 489706f2543Smrg } 490706f2543Smrg 491706f2543Smrg if(!(adaptorPriv = calloc(1, sizeof(XvAdaptorRecPrivate)))) { 492706f2543Smrg KdXVFreeAdaptor(pa); 493706f2543Smrg continue; 494706f2543Smrg } 495706f2543Smrg 496706f2543Smrg adaptorPriv->flags = adaptorPtr->flags; 497706f2543Smrg adaptorPriv->PutVideo = adaptorPtr->PutVideo; 498706f2543Smrg adaptorPriv->PutStill = adaptorPtr->PutStill; 499706f2543Smrg adaptorPriv->GetVideo = adaptorPtr->GetVideo; 500706f2543Smrg adaptorPriv->GetStill = adaptorPtr->GetStill; 501706f2543Smrg adaptorPriv->StopVideo = adaptorPtr->StopVideo; 502706f2543Smrg adaptorPriv->SetPortAttribute = adaptorPtr->SetPortAttribute; 503706f2543Smrg adaptorPriv->GetPortAttribute = adaptorPtr->GetPortAttribute; 504706f2543Smrg adaptorPriv->QueryBestSize = adaptorPtr->QueryBestSize; 505706f2543Smrg adaptorPriv->QueryImageAttributes = adaptorPtr->QueryImageAttributes; 506706f2543Smrg adaptorPriv->PutImage = adaptorPtr->PutImage; 507706f2543Smrg adaptorPriv->ReputImage = adaptorPtr->ReputImage; 508706f2543Smrg 509706f2543Smrg pa->devPriv.ptr = (pointer)adaptorPriv; 510706f2543Smrg 511706f2543Smrg if(!(pPort = calloc(adaptorPtr->nPorts, sizeof(XvPortRec)))) { 512706f2543Smrg KdXVFreeAdaptor(pa); 513706f2543Smrg continue; 514706f2543Smrg } 515706f2543Smrg for(pp = pPort, i = 0, numPort = 0; 516706f2543Smrg i < adaptorPtr->nPorts; i++) { 517706f2543Smrg 518706f2543Smrg if(!(pp->id = FakeClientID(0))) 519706f2543Smrg continue; 520706f2543Smrg 521706f2543Smrg if(!(portPriv = calloc(1, sizeof(XvPortRecPrivate)))) 522706f2543Smrg continue; 523706f2543Smrg 524706f2543Smrg if(!AddResource(pp->id, PortResource, pp)) { 525706f2543Smrg free(portPriv); 526706f2543Smrg continue; 527706f2543Smrg } 528706f2543Smrg 529706f2543Smrg pp->pAdaptor = pa; 530706f2543Smrg pp->pNotify = (XvPortNotifyPtr)NULL; 531706f2543Smrg pp->pDraw = (DrawablePtr)NULL; 532706f2543Smrg pp->client = (ClientPtr)NULL; 533706f2543Smrg pp->grab.client = (ClientPtr)NULL; 534706f2543Smrg pp->time = currentTime; 535706f2543Smrg pp->devPriv.ptr = portPriv; 536706f2543Smrg 537706f2543Smrg portPriv->screen = screen; 538706f2543Smrg portPriv->AdaptorRec = adaptorPriv; 539706f2543Smrg portPriv->DevPriv.ptr = adaptorPtr->pPortPrivates[i].ptr; 540706f2543Smrg 541706f2543Smrg pp++; 542706f2543Smrg numPort++; 543706f2543Smrg } 544706f2543Smrg pa->nPorts = numPort; 545706f2543Smrg pa->pPorts = pPort; 546706f2543Smrg if(!numPort) { 547706f2543Smrg KdXVFreeAdaptor(pa); 548706f2543Smrg continue; 549706f2543Smrg } 550706f2543Smrg 551706f2543Smrg pa->base_id = pPort->id; 552706f2543Smrg 553706f2543Smrg pa++; 554706f2543Smrg numAdaptor++; 555706f2543Smrg } 556706f2543Smrg 557706f2543Smrg if(numAdaptor) { 558706f2543Smrg pxvs->nAdaptors = numAdaptor; 559706f2543Smrg pxvs->pAdaptors = pAdaptor; 560706f2543Smrg } else { 561706f2543Smrg free(pAdaptor); 562706f2543Smrg return FALSE; 563706f2543Smrg } 564706f2543Smrg 565706f2543Smrg return TRUE; 566706f2543Smrg} 567706f2543Smrg 568706f2543Smrg/* Video should be clipped to the intersection of the window cliplist 569706f2543Smrg and the client cliplist specified in the GC for which the video was 570706f2543Smrg initialized. When we need to reclip a window, the GC that started 571706f2543Smrg the video may not even be around anymore. That's why we save the 572706f2543Smrg client clip from the GC when the video is initialized. We then 573706f2543Smrg use KdXVUpdateCompositeClip to calculate the new composite clip 574706f2543Smrg when we need it. This is different from what DEC did. They saved 575706f2543Smrg the GC and used it's clip list when they needed to reclip the window, 576706f2543Smrg even if the client clip was different from the one the video was 577706f2543Smrg initialized with. If the original GC was destroyed, they had to stop 578706f2543Smrg the video. I like the new method better (MArk). 579706f2543Smrg 580706f2543Smrg This function only works for windows. Will need to rewrite when 581706f2543Smrg (if) we support pixmap rendering. 582706f2543Smrg*/ 583706f2543Smrg 584706f2543Smrgstatic void 585706f2543SmrgKdXVUpdateCompositeClip(XvPortRecPrivatePtr portPriv) 586706f2543Smrg{ 587706f2543Smrg RegionPtr pregWin, pCompositeClip; 588706f2543Smrg WindowPtr pWin; 589706f2543Smrg Bool freeCompClip = FALSE; 590706f2543Smrg 591706f2543Smrg if(portPriv->pCompositeClip) 592706f2543Smrg return; 593706f2543Smrg 594706f2543Smrg pWin = (WindowPtr)portPriv->pDraw; 595706f2543Smrg 596706f2543Smrg /* get window clip list */ 597706f2543Smrg if(portPriv->subWindowMode == IncludeInferiors) { 598706f2543Smrg pregWin = NotClippedByChildren(pWin); 599706f2543Smrg freeCompClip = TRUE; 600706f2543Smrg } else 601706f2543Smrg pregWin = &pWin->clipList; 602706f2543Smrg 603706f2543Smrg if(!portPriv->clientClip) { 604706f2543Smrg portPriv->pCompositeClip = pregWin; 605706f2543Smrg portPriv->FreeCompositeClip = freeCompClip; 606706f2543Smrg return; 607706f2543Smrg } 608706f2543Smrg 609706f2543Smrg pCompositeClip = RegionCreate(NullBox, 1); 610706f2543Smrg RegionCopy(pCompositeClip, portPriv->clientClip); 611706f2543Smrg RegionTranslate(pCompositeClip, 612706f2543Smrg portPriv->pDraw->x + portPriv->clipOrg.x, 613706f2543Smrg portPriv->pDraw->y + portPriv->clipOrg.y); 614706f2543Smrg RegionIntersect(pCompositeClip, pregWin, pCompositeClip); 615706f2543Smrg 616706f2543Smrg portPriv->pCompositeClip = pCompositeClip; 617706f2543Smrg portPriv->FreeCompositeClip = TRUE; 618706f2543Smrg 619706f2543Smrg if(freeCompClip) { 620706f2543Smrg RegionDestroy(pregWin); 621706f2543Smrg } 622706f2543Smrg} 623706f2543Smrg 624706f2543Smrg/* Save the current clientClip and update the CompositeClip whenever 625706f2543Smrg we have a fresh GC */ 626706f2543Smrg 627706f2543Smrgstatic void 628706f2543SmrgKdXVCopyClip( 629706f2543Smrg XvPortRecPrivatePtr portPriv, 630706f2543Smrg GCPtr pGC 631706f2543Smrg){ 632706f2543Smrg /* copy the new clip if it exists */ 633706f2543Smrg if((pGC->clientClipType == CT_REGION) && pGC->clientClip) { 634706f2543Smrg if(!portPriv->clientClip) 635706f2543Smrg portPriv->clientClip = RegionCreate(NullBox, 1); 636706f2543Smrg /* Note: this is in window coordinates */ 637706f2543Smrg RegionCopy(portPriv->clientClip, pGC->clientClip); 638706f2543Smrg } else if(portPriv->clientClip) { /* free the old clientClip */ 639706f2543Smrg RegionDestroy(portPriv->clientClip); 640706f2543Smrg portPriv->clientClip = NULL; 641706f2543Smrg } 642706f2543Smrg 643706f2543Smrg /* get rid of the old clip list */ 644706f2543Smrg if(portPriv->pCompositeClip && portPriv->FreeCompositeClip) { 645706f2543Smrg RegionDestroy(portPriv->pCompositeClip); 646706f2543Smrg } 647706f2543Smrg 648706f2543Smrg portPriv->clipOrg = pGC->clipOrg; 649706f2543Smrg portPriv->pCompositeClip = pGC->pCompositeClip; 650706f2543Smrg portPriv->FreeCompositeClip = FALSE; 651706f2543Smrg portPriv->subWindowMode = pGC->subWindowMode; 652706f2543Smrg} 653706f2543Smrg 654706f2543Smrgstatic int 655706f2543SmrgKdXVRegetVideo(XvPortRecPrivatePtr portPriv) 656706f2543Smrg{ 657706f2543Smrg RegionRec WinRegion; 658706f2543Smrg RegionRec ClipRegion; 659706f2543Smrg BoxRec WinBox; 660706f2543Smrg int ret = Success; 661706f2543Smrg Bool clippedAway = FALSE; 662706f2543Smrg 663706f2543Smrg KdXVUpdateCompositeClip(portPriv); 664706f2543Smrg 665706f2543Smrg /* translate the video region to the screen */ 666706f2543Smrg WinBox.x1 = portPriv->pDraw->x + portPriv->drw_x; 667706f2543Smrg WinBox.y1 = portPriv->pDraw->y + portPriv->drw_y; 668706f2543Smrg WinBox.x2 = WinBox.x1 + portPriv->drw_w; 669706f2543Smrg WinBox.y2 = WinBox.y1 + portPriv->drw_h; 670706f2543Smrg 671706f2543Smrg /* clip to the window composite clip */ 672706f2543Smrg RegionInit(&WinRegion, &WinBox, 1); 673706f2543Smrg RegionInit(&ClipRegion, NullBox, 1); 674706f2543Smrg RegionIntersect(&ClipRegion, &WinRegion, portPriv->pCompositeClip); 675706f2543Smrg 676706f2543Smrg /* that's all if it's totally obscured */ 677706f2543Smrg if(!RegionNotEmpty(&ClipRegion)) { 678706f2543Smrg clippedAway = TRUE; 679706f2543Smrg goto CLIP_VIDEO_BAILOUT; 680706f2543Smrg } 681706f2543Smrg 682706f2543Smrg if(portPriv->AdaptorRec->flags & VIDEO_INVERT_CLIPLIST) { 683706f2543Smrg RegionSubtract(&ClipRegion, &WinRegion, &ClipRegion); 684706f2543Smrg } 685706f2543Smrg 686706f2543Smrg ret = (*portPriv->AdaptorRec->GetVideo)(portPriv->screen, portPriv->pDraw, 687706f2543Smrg portPriv->vid_x, portPriv->vid_y, 688706f2543Smrg WinBox.x1, WinBox.y1, 689706f2543Smrg portPriv->vid_w, portPriv->vid_h, 690706f2543Smrg portPriv->drw_w, portPriv->drw_h, 691706f2543Smrg &ClipRegion, portPriv->DevPriv.ptr); 692706f2543Smrg 693706f2543Smrg if(ret == Success) 694706f2543Smrg portPriv->isOn = XV_ON; 695706f2543Smrg 696706f2543SmrgCLIP_VIDEO_BAILOUT: 697706f2543Smrg 698706f2543Smrg if((clippedAway || (ret != Success)) && portPriv->isOn == XV_ON) { 699706f2543Smrg (*portPriv->AdaptorRec->StopVideo)( 700706f2543Smrg portPriv->screen, portPriv->DevPriv.ptr, FALSE); 701706f2543Smrg portPriv->isOn = XV_PENDING; 702706f2543Smrg } 703706f2543Smrg 704706f2543Smrg /* This clip was copied and only good for one shot */ 705706f2543Smrg if(!portPriv->FreeCompositeClip) 706706f2543Smrg portPriv->pCompositeClip = NULL; 707706f2543Smrg 708706f2543Smrg RegionUninit(&WinRegion); 709706f2543Smrg RegionUninit(&ClipRegion); 710706f2543Smrg 711706f2543Smrg return ret; 712706f2543Smrg} 713706f2543Smrg 714706f2543Smrg 715706f2543Smrgstatic int 716706f2543SmrgKdXVReputVideo(XvPortRecPrivatePtr portPriv) 717706f2543Smrg{ 718706f2543Smrg RegionRec WinRegion; 719706f2543Smrg RegionRec ClipRegion; 720706f2543Smrg BoxRec WinBox; 721706f2543Smrg ScreenPtr pScreen = portPriv->pDraw->pScreen; 722706f2543Smrg KdScreenPriv(pScreen); 723706f2543Smrg KdScreenInfo *screen=pScreenPriv->screen; 724706f2543Smrg int ret = Success; 725706f2543Smrg Bool clippedAway = FALSE; 726706f2543Smrg 727706f2543Smrg KdXVUpdateCompositeClip(portPriv); 728706f2543Smrg 729706f2543Smrg /* translate the video region to the screen */ 730706f2543Smrg WinBox.x1 = portPriv->pDraw->x + portPriv->drw_x; 731706f2543Smrg WinBox.y1 = portPriv->pDraw->y + portPriv->drw_y; 732706f2543Smrg WinBox.x2 = WinBox.x1 + portPriv->drw_w; 733706f2543Smrg WinBox.y2 = WinBox.y1 + portPriv->drw_h; 734706f2543Smrg 735706f2543Smrg /* clip to the window composite clip */ 736706f2543Smrg RegionInit(&WinRegion, &WinBox, 1); 737706f2543Smrg RegionInit(&ClipRegion, NullBox, 1); 738706f2543Smrg RegionIntersect(&ClipRegion, &WinRegion, portPriv->pCompositeClip); 739706f2543Smrg 740706f2543Smrg /* clip and translate to the viewport */ 741706f2543Smrg if(portPriv->AdaptorRec->flags & VIDEO_CLIP_TO_VIEWPORT) { 742706f2543Smrg RegionRec VPReg; 743706f2543Smrg BoxRec VPBox; 744706f2543Smrg 745706f2543Smrg VPBox.x1 = 0; 746706f2543Smrg VPBox.y1 = 0; 747706f2543Smrg VPBox.x2 = screen->width; 748706f2543Smrg VPBox.y2 = screen->height; 749706f2543Smrg 750706f2543Smrg RegionInit(&VPReg, &VPBox, 1); 751706f2543Smrg RegionIntersect(&ClipRegion, &ClipRegion, &VPReg); 752706f2543Smrg RegionUninit(&VPReg); 753706f2543Smrg } 754706f2543Smrg 755706f2543Smrg /* that's all if it's totally obscured */ 756706f2543Smrg if(!RegionNotEmpty(&ClipRegion)) { 757706f2543Smrg clippedAway = TRUE; 758706f2543Smrg goto CLIP_VIDEO_BAILOUT; 759706f2543Smrg } 760706f2543Smrg 761706f2543Smrg /* bailout if we have to clip but the hardware doesn't support it */ 762706f2543Smrg if(portPriv->AdaptorRec->flags & VIDEO_NO_CLIPPING) { 763706f2543Smrg BoxPtr clipBox = RegionRects(&ClipRegion); 764706f2543Smrg if( (RegionNumRects(&ClipRegion) != 1) || 765706f2543Smrg (clipBox->x1 != WinBox.x1) || (clipBox->x2 != WinBox.x2) || 766706f2543Smrg (clipBox->y1 != WinBox.y1) || (clipBox->y2 != WinBox.y2)) 767706f2543Smrg { 768706f2543Smrg clippedAway = TRUE; 769706f2543Smrg goto CLIP_VIDEO_BAILOUT; 770706f2543Smrg } 771706f2543Smrg } 772706f2543Smrg 773706f2543Smrg if(portPriv->AdaptorRec->flags & VIDEO_INVERT_CLIPLIST) { 774706f2543Smrg RegionSubtract(&ClipRegion, &WinRegion, &ClipRegion); 775706f2543Smrg } 776706f2543Smrg 777706f2543Smrg ret = (*portPriv->AdaptorRec->PutVideo)(portPriv->screen, portPriv->pDraw, 778706f2543Smrg portPriv->vid_x, portPriv->vid_y, 779706f2543Smrg WinBox.x1, WinBox.y1, 780706f2543Smrg portPriv->vid_w, portPriv->vid_h, 781706f2543Smrg portPriv->drw_w, portPriv->drw_h, 782706f2543Smrg &ClipRegion, portPriv->DevPriv.ptr); 783706f2543Smrg 784706f2543Smrg if(ret == Success) portPriv->isOn = XV_ON; 785706f2543Smrg 786706f2543SmrgCLIP_VIDEO_BAILOUT: 787706f2543Smrg 788706f2543Smrg if((clippedAway || (ret != Success)) && (portPriv->isOn == XV_ON)) { 789706f2543Smrg (*portPriv->AdaptorRec->StopVideo)( 790706f2543Smrg portPriv->screen, portPriv->DevPriv.ptr, FALSE); 791706f2543Smrg portPriv->isOn = XV_PENDING; 792706f2543Smrg } 793706f2543Smrg 794706f2543Smrg /* This clip was copied and only good for one shot */ 795706f2543Smrg if(!portPriv->FreeCompositeClip) 796706f2543Smrg portPriv->pCompositeClip = NULL; 797706f2543Smrg 798706f2543Smrg RegionUninit(&WinRegion); 799706f2543Smrg RegionUninit(&ClipRegion); 800706f2543Smrg 801706f2543Smrg return ret; 802706f2543Smrg} 803706f2543Smrg 804706f2543Smrgstatic int 805706f2543SmrgKdXVReputImage(XvPortRecPrivatePtr portPriv) 806706f2543Smrg{ 807706f2543Smrg RegionRec WinRegion; 808706f2543Smrg RegionRec ClipRegion; 809706f2543Smrg BoxRec WinBox; 810706f2543Smrg ScreenPtr pScreen = portPriv->pDraw->pScreen; 811706f2543Smrg KdScreenPriv(pScreen); 812706f2543Smrg KdScreenInfo *screen=pScreenPriv->screen; 813706f2543Smrg int ret = Success; 814706f2543Smrg Bool clippedAway = FALSE; 815706f2543Smrg 816706f2543Smrg KdXVUpdateCompositeClip(portPriv); 817706f2543Smrg 818706f2543Smrg /* translate the video region to the screen */ 819706f2543Smrg WinBox.x1 = portPriv->pDraw->x + portPriv->drw_x; 820706f2543Smrg WinBox.y1 = portPriv->pDraw->y + portPriv->drw_y; 821706f2543Smrg WinBox.x2 = WinBox.x1 + portPriv->drw_w; 822706f2543Smrg WinBox.y2 = WinBox.y1 + portPriv->drw_h; 823706f2543Smrg 824706f2543Smrg /* clip to the window composite clip */ 825706f2543Smrg RegionInit(&WinRegion, &WinBox, 1); 826706f2543Smrg RegionInit(&ClipRegion, NullBox, 1); 827706f2543Smrg RegionIntersect(&ClipRegion, &WinRegion, portPriv->pCompositeClip); 828706f2543Smrg 829706f2543Smrg /* clip and translate to the viewport */ 830706f2543Smrg if(portPriv->AdaptorRec->flags & VIDEO_CLIP_TO_VIEWPORT) { 831706f2543Smrg RegionRec VPReg; 832706f2543Smrg BoxRec VPBox; 833706f2543Smrg 834706f2543Smrg VPBox.x1 = 0; 835706f2543Smrg VPBox.y1 = 0; 836706f2543Smrg VPBox.x2 = screen->width; 837706f2543Smrg VPBox.y2 = screen->height; 838706f2543Smrg 839706f2543Smrg RegionInit(&VPReg, &VPBox, 1); 840706f2543Smrg RegionIntersect(&ClipRegion, &ClipRegion, &VPReg); 841706f2543Smrg RegionUninit(&VPReg); 842706f2543Smrg } 843706f2543Smrg 844706f2543Smrg /* that's all if it's totally obscured */ 845706f2543Smrg if(!RegionNotEmpty(&ClipRegion)) { 846706f2543Smrg clippedAway = TRUE; 847706f2543Smrg goto CLIP_VIDEO_BAILOUT; 848706f2543Smrg } 849706f2543Smrg 850706f2543Smrg /* bailout if we have to clip but the hardware doesn't support it */ 851706f2543Smrg if(portPriv->AdaptorRec->flags & VIDEO_NO_CLIPPING) { 852706f2543Smrg BoxPtr clipBox = RegionRects(&ClipRegion); 853706f2543Smrg if( (RegionNumRects(&ClipRegion) != 1) || 854706f2543Smrg (clipBox->x1 != WinBox.x1) || (clipBox->x2 != WinBox.x2) || 855706f2543Smrg (clipBox->y1 != WinBox.y1) || (clipBox->y2 != WinBox.y2)) 856706f2543Smrg { 857706f2543Smrg clippedAway = TRUE; 858706f2543Smrg goto CLIP_VIDEO_BAILOUT; 859706f2543Smrg } 860706f2543Smrg } 861706f2543Smrg 862706f2543Smrg if(portPriv->AdaptorRec->flags & VIDEO_INVERT_CLIPLIST) { 863706f2543Smrg RegionSubtract(&ClipRegion, &WinRegion, &ClipRegion); 864706f2543Smrg } 865706f2543Smrg 866706f2543Smrg ret = (*portPriv->AdaptorRec->ReputImage)(portPriv->screen, portPriv->pDraw, 867706f2543Smrg WinBox.x1, WinBox.y1, 868706f2543Smrg &ClipRegion, portPriv->DevPriv.ptr); 869706f2543Smrg 870706f2543Smrg portPriv->isOn = (ret == Success) ? XV_ON : XV_OFF; 871706f2543Smrg 872706f2543SmrgCLIP_VIDEO_BAILOUT: 873706f2543Smrg 874706f2543Smrg if((clippedAway || (ret != Success)) && (portPriv->isOn == XV_ON)) { 875706f2543Smrg (*portPriv->AdaptorRec->StopVideo)( 876706f2543Smrg portPriv->screen, portPriv->DevPriv.ptr, FALSE); 877706f2543Smrg portPriv->isOn = XV_PENDING; 878706f2543Smrg } 879706f2543Smrg 880706f2543Smrg /* This clip was copied and only good for one shot */ 881706f2543Smrg if(!portPriv->FreeCompositeClip) 882706f2543Smrg portPriv->pCompositeClip = NULL; 883706f2543Smrg 884706f2543Smrg RegionUninit(&WinRegion); 885706f2543Smrg RegionUninit(&ClipRegion); 886706f2543Smrg 887706f2543Smrg return ret; 888706f2543Smrg} 889706f2543Smrg 890706f2543Smrg 891706f2543Smrgstatic int 892706f2543SmrgKdXVReputAllVideo(WindowPtr pWin, pointer data) 893706f2543Smrg{ 894706f2543Smrg KdXVWindowPtr WinPriv; 895706f2543Smrg 896706f2543Smrg if (pWin->drawable.type != DRAWABLE_WINDOW) 897706f2543Smrg return WT_DONTWALKCHILDREN; 898706f2543Smrg 899706f2543Smrg WinPriv = GET_KDXV_WINDOW(pWin); 900706f2543Smrg 901706f2543Smrg while(WinPriv) { 902706f2543Smrg if(WinPriv->PortRec->type == XvInputMask) 903706f2543Smrg KdXVReputVideo(WinPriv->PortRec); 904706f2543Smrg else 905706f2543Smrg KdXVRegetVideo(WinPriv->PortRec); 906706f2543Smrg WinPriv = WinPriv->next; 907706f2543Smrg } 908706f2543Smrg 909706f2543Smrg return WT_WALKCHILDREN; 910706f2543Smrg} 911706f2543Smrg 912706f2543Smrgstatic int 913706f2543SmrgKdXVEnlistPortInWindow(WindowPtr pWin, XvPortRecPrivatePtr portPriv) 914706f2543Smrg{ 915706f2543Smrg KdXVWindowPtr winPriv, PrivRoot; 916706f2543Smrg 917706f2543Smrg winPriv = PrivRoot = GET_KDXV_WINDOW(pWin); 918706f2543Smrg 919706f2543Smrg /* Enlist our port in the window private */ 920706f2543Smrg while(winPriv) { 921706f2543Smrg if(winPriv->PortRec == portPriv) /* we're already listed */ 922706f2543Smrg break; 923706f2543Smrg winPriv = winPriv->next; 924706f2543Smrg } 925706f2543Smrg 926706f2543Smrg if(!winPriv) { 927706f2543Smrg winPriv = malloc(sizeof(KdXVWindowRec)); 928706f2543Smrg if(!winPriv) return BadAlloc; 929706f2543Smrg winPriv->PortRec = portPriv; 930706f2543Smrg winPriv->next = PrivRoot; 931706f2543Smrg dixSetPrivate(&pWin->devPrivates, KdXVWindowKey, winPriv); 932706f2543Smrg } 933706f2543Smrg return Success; 934706f2543Smrg} 935706f2543Smrg 936706f2543Smrg 937706f2543Smrgstatic void 938706f2543SmrgKdXVRemovePortFromWindow(WindowPtr pWin, XvPortRecPrivatePtr portPriv) 939706f2543Smrg{ 940706f2543Smrg KdXVWindowPtr winPriv, prevPriv = NULL; 941706f2543Smrg 942706f2543Smrg winPriv = GET_KDXV_WINDOW(pWin); 943706f2543Smrg 944706f2543Smrg while(winPriv) { 945706f2543Smrg if(winPriv->PortRec == portPriv) { 946706f2543Smrg if(prevPriv) 947706f2543Smrg prevPriv->next = winPriv->next; 948706f2543Smrg else 949706f2543Smrg dixSetPrivate(&pWin->devPrivates, KdXVWindowKey, winPriv->next); 950706f2543Smrg free(winPriv); 951706f2543Smrg break; 952706f2543Smrg } 953706f2543Smrg prevPriv = winPriv; 954706f2543Smrg winPriv = winPriv->next; 955706f2543Smrg } 956706f2543Smrg portPriv->pDraw = NULL; 957706f2543Smrg} 958706f2543Smrg 959706f2543Smrg/**** ScreenRec fields ****/ 960706f2543Smrg 961706f2543Smrg 962706f2543Smrgstatic Bool 963706f2543SmrgKdXVCreateWindow(WindowPtr pWin) 964706f2543Smrg{ 965706f2543Smrg ScreenPtr pScreen = pWin->drawable.pScreen; 966706f2543Smrg KdXVScreenPtr ScreenPriv = GET_KDXV_SCREEN(pScreen); 967706f2543Smrg int ret; 968706f2543Smrg 969706f2543Smrg pScreen->CreateWindow = ScreenPriv->CreateWindow; 970706f2543Smrg ret = (*pScreen->CreateWindow)(pWin); 971706f2543Smrg pScreen->CreateWindow = KdXVCreateWindow; 972706f2543Smrg 973706f2543Smrg if (ret) 974706f2543Smrg dixSetPrivate(&pWin->devPrivates, KdXVWindowKey, NULL); 975706f2543Smrg 976706f2543Smrg return ret; 977706f2543Smrg} 978706f2543Smrg 979706f2543Smrg 980706f2543Smrgstatic Bool 981706f2543SmrgKdXVDestroyWindow(WindowPtr pWin) 982706f2543Smrg{ 983706f2543Smrg ScreenPtr pScreen = pWin->drawable.pScreen; 984706f2543Smrg KdXVScreenPtr ScreenPriv = GET_KDXV_SCREEN(pScreen); 985706f2543Smrg KdXVWindowPtr tmp, WinPriv = GET_KDXV_WINDOW(pWin); 986706f2543Smrg int ret; 987706f2543Smrg 988706f2543Smrg while(WinPriv) { 989706f2543Smrg XvPortRecPrivatePtr pPriv = WinPriv->PortRec; 990706f2543Smrg 991706f2543Smrg if(pPriv->isOn > XV_OFF) { 992706f2543Smrg (*pPriv->AdaptorRec->StopVideo)( 993706f2543Smrg pPriv->screen, pPriv->DevPriv.ptr, TRUE); 994706f2543Smrg pPriv->isOn = XV_OFF; 995706f2543Smrg } 996706f2543Smrg 997706f2543Smrg pPriv->pDraw = NULL; 998706f2543Smrg tmp = WinPriv; 999706f2543Smrg WinPriv = WinPriv->next; 1000706f2543Smrg free(tmp); 1001706f2543Smrg } 1002706f2543Smrg 1003706f2543Smrg dixSetPrivate(&pWin->devPrivates, KdXVWindowKey, NULL); 1004706f2543Smrg 1005706f2543Smrg pScreen->DestroyWindow = ScreenPriv->DestroyWindow; 1006706f2543Smrg ret = (*pScreen->DestroyWindow)(pWin); 1007706f2543Smrg pScreen->DestroyWindow = KdXVDestroyWindow; 1008706f2543Smrg 1009706f2543Smrg return ret; 1010706f2543Smrg} 1011706f2543Smrg 1012706f2543Smrg 1013706f2543Smrgstatic void 1014706f2543SmrgKdXVWindowExposures(WindowPtr pWin, RegionPtr reg1, RegionPtr reg2) 1015706f2543Smrg{ 1016706f2543Smrg ScreenPtr pScreen = pWin->drawable.pScreen; 1017706f2543Smrg KdXVScreenPtr ScreenPriv = GET_KDXV_SCREEN(pScreen); 1018706f2543Smrg KdXVWindowPtr WinPriv = GET_KDXV_WINDOW(pWin); 1019706f2543Smrg KdXVWindowPtr pPrev; 1020706f2543Smrg XvPortRecPrivatePtr pPriv; 1021706f2543Smrg Bool AreasExposed; 1022706f2543Smrg 1023706f2543Smrg AreasExposed = (WinPriv && reg1 && RegionNotEmpty(reg1)); 1024706f2543Smrg 1025706f2543Smrg pScreen->WindowExposures = ScreenPriv->WindowExposures; 1026706f2543Smrg (*pScreen->WindowExposures)(pWin, reg1, reg2); 1027706f2543Smrg pScreen->WindowExposures = KdXVWindowExposures; 1028706f2543Smrg 1029706f2543Smrg /* filter out XClearWindow/Area */ 1030706f2543Smrg if (!pWin->valdata) return; 1031706f2543Smrg 1032706f2543Smrg pPrev = NULL; 1033706f2543Smrg 1034706f2543Smrg while(WinPriv) { 1035706f2543Smrg pPriv = WinPriv->PortRec; 1036706f2543Smrg 1037706f2543Smrg /* Reput anyone with a reput function */ 1038706f2543Smrg 1039706f2543Smrg switch(pPriv->type) { 1040706f2543Smrg case XvInputMask: 1041706f2543Smrg KdXVReputVideo(pPriv); 1042706f2543Smrg break; 1043706f2543Smrg case XvOutputMask: 1044706f2543Smrg KdXVRegetVideo(pPriv); 1045706f2543Smrg break; 1046706f2543Smrg default: /* overlaid still/image*/ 1047706f2543Smrg if (pPriv->AdaptorRec->ReputImage) 1048706f2543Smrg KdXVReputImage(pPriv); 1049706f2543Smrg else if(AreasExposed) { 1050706f2543Smrg KdXVWindowPtr tmp; 1051706f2543Smrg 1052706f2543Smrg if (pPriv->isOn == XV_ON) { 1053706f2543Smrg (*pPriv->AdaptorRec->StopVideo)( 1054706f2543Smrg pPriv->screen, pPriv->DevPriv.ptr, FALSE); 1055706f2543Smrg pPriv->isOn = XV_PENDING; 1056706f2543Smrg } 1057706f2543Smrg pPriv->pDraw = NULL; 1058706f2543Smrg 1059706f2543Smrg if(!pPrev) 1060706f2543Smrg dixSetPrivate(&pWin->devPrivates, KdXVWindowKey, WinPriv->next); 1061706f2543Smrg else 1062706f2543Smrg pPrev->next = WinPriv->next; 1063706f2543Smrg tmp = WinPriv; 1064706f2543Smrg WinPriv = WinPriv->next; 1065706f2543Smrg free(tmp); 1066706f2543Smrg continue; 1067706f2543Smrg } 1068706f2543Smrg break; 1069706f2543Smrg } 1070706f2543Smrg pPrev = WinPriv; 1071706f2543Smrg WinPriv = WinPriv->next; 1072706f2543Smrg } 1073706f2543Smrg} 1074706f2543Smrg 1075706f2543Smrg 1076706f2543Smrgstatic void 1077706f2543SmrgKdXVClipNotify(WindowPtr pWin, int dx, int dy) 1078706f2543Smrg{ 1079706f2543Smrg ScreenPtr pScreen = pWin->drawable.pScreen; 1080706f2543Smrg KdXVScreenPtr ScreenPriv = GET_KDXV_SCREEN(pScreen); 1081706f2543Smrg KdXVWindowPtr WinPriv = GET_KDXV_WINDOW(pWin); 1082706f2543Smrg KdXVWindowPtr tmp, pPrev = NULL; 1083706f2543Smrg XvPortRecPrivatePtr pPriv; 1084706f2543Smrg Bool visible = (pWin->visibility == VisibilityUnobscured) || 1085706f2543Smrg (pWin->visibility == VisibilityPartiallyObscured); 1086706f2543Smrg 1087706f2543Smrg while(WinPriv) { 1088706f2543Smrg pPriv = WinPriv->PortRec; 1089706f2543Smrg 1090706f2543Smrg if(pPriv->pCompositeClip && pPriv->FreeCompositeClip) 1091706f2543Smrg RegionDestroy(pPriv->pCompositeClip); 1092706f2543Smrg 1093706f2543Smrg pPriv->pCompositeClip = NULL; 1094706f2543Smrg 1095706f2543Smrg /* Stop everything except images, but stop them too if the 1096706f2543Smrg window isn't visible. But we only remove the images. */ 1097706f2543Smrg 1098706f2543Smrg if(pPriv->type || !visible) { 1099706f2543Smrg if(pPriv->isOn == XV_ON) { 1100706f2543Smrg (*pPriv->AdaptorRec->StopVideo)( 1101706f2543Smrg pPriv->screen, pPriv->DevPriv.ptr, FALSE); 1102706f2543Smrg pPriv->isOn = XV_PENDING; 1103706f2543Smrg } 1104706f2543Smrg 1105706f2543Smrg if(!pPriv->type) { /* overlaid still/image */ 1106706f2543Smrg pPriv->pDraw = NULL; 1107706f2543Smrg 1108706f2543Smrg if(!pPrev) 1109706f2543Smrg dixSetPrivate(&pWin->devPrivates, KdXVWindowKey, WinPriv->next); 1110706f2543Smrg else 1111706f2543Smrg pPrev->next = WinPriv->next; 1112706f2543Smrg tmp = WinPriv; 1113706f2543Smrg WinPriv = WinPriv->next; 1114706f2543Smrg free(tmp); 1115706f2543Smrg continue; 1116706f2543Smrg } 1117706f2543Smrg } 1118706f2543Smrg 1119706f2543Smrg pPrev = WinPriv; 1120706f2543Smrg WinPriv = WinPriv->next; 1121706f2543Smrg } 1122706f2543Smrg 1123706f2543Smrg if(ScreenPriv->ClipNotify) { 1124706f2543Smrg pScreen->ClipNotify = ScreenPriv->ClipNotify; 1125706f2543Smrg (*pScreen->ClipNotify)(pWin, dx, dy); 1126706f2543Smrg pScreen->ClipNotify = KdXVClipNotify; 1127706f2543Smrg } 1128706f2543Smrg} 1129706f2543Smrg 1130706f2543Smrg 1131706f2543Smrg 1132706f2543Smrg/**** Required XvScreenRec fields ****/ 1133706f2543Smrg 1134706f2543Smrgstatic Bool 1135706f2543SmrgKdXVCloseScreen(int i, ScreenPtr pScreen) 1136706f2543Smrg{ 1137706f2543Smrg XvScreenPtr pxvs = GET_XV_SCREEN(pScreen); 1138706f2543Smrg KdXVScreenPtr ScreenPriv = GET_KDXV_SCREEN(pScreen); 1139706f2543Smrg XvAdaptorPtr pa; 1140706f2543Smrg int c; 1141706f2543Smrg 1142706f2543Smrg if(!ScreenPriv) return TRUE; 1143706f2543Smrg 1144706f2543Smrg pScreen->CreateWindow = ScreenPriv->CreateWindow; 1145706f2543Smrg pScreen->DestroyWindow = ScreenPriv->DestroyWindow; 1146706f2543Smrg pScreen->WindowExposures = ScreenPriv->WindowExposures; 1147706f2543Smrg pScreen->ClipNotify = ScreenPriv->ClipNotify; 1148706f2543Smrg 1149706f2543Smrg/* fprintf(stderr,"XV: Unwrapping screen funcs\n"); */ 1150706f2543Smrg 1151706f2543Smrg for(c = 0, pa = pxvs->pAdaptors; c < pxvs->nAdaptors; c++, pa++) { 1152706f2543Smrg KdXVFreeAdaptor(pa); 1153706f2543Smrg } 1154706f2543Smrg 1155706f2543Smrg free(pxvs->pAdaptors); 1156706f2543Smrg free(ScreenPriv); 1157706f2543Smrg 1158706f2543Smrg return TRUE; 1159706f2543Smrg} 1160706f2543Smrg 1161706f2543Smrg 1162706f2543Smrgstatic int 1163706f2543SmrgKdXVQueryAdaptors( 1164706f2543Smrg ScreenPtr pScreen, 1165706f2543Smrg XvAdaptorPtr *p_pAdaptors, 1166706f2543Smrg int *p_nAdaptors 1167706f2543Smrg){ 1168706f2543Smrg XvScreenPtr pxvs = GET_XV_SCREEN(pScreen); 1169706f2543Smrg 1170706f2543Smrg *p_nAdaptors = pxvs->nAdaptors; 1171706f2543Smrg *p_pAdaptors = pxvs->pAdaptors; 1172706f2543Smrg 1173706f2543Smrg return Success; 1174706f2543Smrg} 1175706f2543Smrg 1176706f2543Smrgstatic Bool 1177706f2543SmrgKdXVRunning (ScreenPtr pScreen) 1178706f2543Smrg{ 1179706f2543Smrg return (KdXVGeneration == serverGeneration && 1180706f2543Smrg GET_XV_SCREEN(pScreen) != 0); 1181706f2543Smrg} 1182706f2543Smrg 1183706f2543SmrgBool 1184706f2543SmrgKdXVEnable(ScreenPtr pScreen) 1185706f2543Smrg{ 1186706f2543Smrg if (!KdXVRunning (pScreen)) 1187706f2543Smrg return TRUE; 1188706f2543Smrg 1189706f2543Smrg WalkTree(pScreen, KdXVReputAllVideo, 0); 1190706f2543Smrg 1191706f2543Smrg return TRUE; 1192706f2543Smrg} 1193706f2543Smrg 1194706f2543Smrgvoid 1195706f2543SmrgKdXVDisable(ScreenPtr pScreen) 1196706f2543Smrg{ 1197706f2543Smrg XvScreenPtr pxvs; 1198706f2543Smrg KdXVScreenPtr ScreenPriv; 1199706f2543Smrg XvAdaptorPtr pAdaptor; 1200706f2543Smrg XvPortPtr pPort; 1201706f2543Smrg XvPortRecPrivatePtr pPriv; 1202706f2543Smrg int i, j; 1203706f2543Smrg 1204706f2543Smrg if (!KdXVRunning (pScreen)) 1205706f2543Smrg return; 1206706f2543Smrg 1207706f2543Smrg pxvs = GET_XV_SCREEN(pScreen); 1208706f2543Smrg ScreenPriv = GET_KDXV_SCREEN(pScreen); 1209706f2543Smrg 1210706f2543Smrg for(i = 0; i < pxvs->nAdaptors; i++) { 1211706f2543Smrg pAdaptor = &pxvs->pAdaptors[i]; 1212706f2543Smrg for(j = 0; j < pAdaptor->nPorts; j++) { 1213706f2543Smrg pPort = &pAdaptor->pPorts[j]; 1214706f2543Smrg pPriv = (XvPortRecPrivatePtr)pPort->devPriv.ptr; 1215706f2543Smrg if(pPriv->isOn > XV_OFF) { 1216706f2543Smrg 1217706f2543Smrg (*pPriv->AdaptorRec->StopVideo)( 1218706f2543Smrg pPriv->screen, pPriv->DevPriv.ptr, TRUE); 1219706f2543Smrg pPriv->isOn = XV_OFF; 1220706f2543Smrg 1221706f2543Smrg if(pPriv->pCompositeClip && pPriv->FreeCompositeClip) 1222706f2543Smrg RegionDestroy(pPriv->pCompositeClip); 1223706f2543Smrg 1224706f2543Smrg pPriv->pCompositeClip = NULL; 1225706f2543Smrg 1226706f2543Smrg if(!pPriv->type && pPriv->pDraw) { /* still */ 1227706f2543Smrg KdXVRemovePortFromWindow((WindowPtr)pPriv->pDraw, pPriv); 1228706f2543Smrg } 1229706f2543Smrg } 1230706f2543Smrg } 1231706f2543Smrg } 1232706f2543Smrg} 1233706f2543Smrg 1234706f2543Smrg/**** XvAdaptorRec fields ****/ 1235706f2543Smrg 1236706f2543Smrgstatic int 1237706f2543SmrgKdXVAllocatePort( 1238706f2543Smrg unsigned long port, 1239706f2543Smrg XvPortPtr pPort, 1240706f2543Smrg XvPortPtr *ppPort 1241706f2543Smrg){ 1242706f2543Smrg *ppPort = pPort; 1243706f2543Smrg return Success; 1244706f2543Smrg} 1245706f2543Smrg 1246706f2543Smrgstatic int 1247706f2543SmrgKdXVFreePort(XvPortPtr pPort) 1248706f2543Smrg{ 1249706f2543Smrg return Success; 1250706f2543Smrg} 1251706f2543Smrg 1252706f2543Smrgstatic int 1253706f2543SmrgKdXVPutVideo( 1254706f2543Smrg ClientPtr client, 1255706f2543Smrg DrawablePtr pDraw, 1256706f2543Smrg XvPortPtr pPort, 1257706f2543Smrg GCPtr pGC, 1258706f2543Smrg INT16 vid_x, INT16 vid_y, 1259706f2543Smrg CARD16 vid_w, CARD16 vid_h, 1260706f2543Smrg INT16 drw_x, INT16 drw_y, 1261706f2543Smrg CARD16 drw_w, CARD16 drw_h 1262706f2543Smrg){ 1263706f2543Smrg XvPortRecPrivatePtr portPriv = (XvPortRecPrivatePtr)(pPort->devPriv.ptr); 1264706f2543Smrg KdScreenPriv(portPriv->screen->pScreen); 1265706f2543Smrg int result; 1266706f2543Smrg 1267706f2543Smrg /* No dumping video to pixmaps... For now anyhow */ 1268706f2543Smrg if(pDraw->type != DRAWABLE_WINDOW) { 1269706f2543Smrg pPort->pDraw = (DrawablePtr)NULL; 1270706f2543Smrg return BadAlloc; 1271706f2543Smrg } 1272706f2543Smrg 1273706f2543Smrg /* If we are changing windows, unregister our port in the old window */ 1274706f2543Smrg if(portPriv->pDraw && (portPriv->pDraw != pDraw)) 1275706f2543Smrg KdXVRemovePortFromWindow((WindowPtr)(portPriv->pDraw), portPriv); 1276706f2543Smrg 1277706f2543Smrg /* Register our port with the new window */ 1278706f2543Smrg result = KdXVEnlistPortInWindow((WindowPtr)pDraw, portPriv); 1279706f2543Smrg if(result != Success) return result; 1280706f2543Smrg 1281706f2543Smrg portPriv->pDraw = pDraw; 1282706f2543Smrg portPriv->type = XvInputMask; 1283706f2543Smrg 1284706f2543Smrg /* save a copy of these parameters */ 1285706f2543Smrg portPriv->vid_x = vid_x; portPriv->vid_y = vid_y; 1286706f2543Smrg portPriv->vid_w = vid_w; portPriv->vid_h = vid_h; 1287706f2543Smrg portPriv->drw_x = drw_x; portPriv->drw_y = drw_y; 1288706f2543Smrg portPriv->drw_w = drw_w; portPriv->drw_h = drw_h; 1289706f2543Smrg 1290706f2543Smrg /* make sure we have the most recent copy of the clientClip */ 1291706f2543Smrg KdXVCopyClip(portPriv, pGC); 1292706f2543Smrg 1293706f2543Smrg /* To indicate to the DI layer that we were successful */ 1294706f2543Smrg pPort->pDraw = pDraw; 1295706f2543Smrg 1296706f2543Smrg if (!pScreenPriv->enabled) return Success; 1297706f2543Smrg 1298706f2543Smrg return(KdXVReputVideo(portPriv)); 1299706f2543Smrg} 1300706f2543Smrg 1301706f2543Smrgstatic int 1302706f2543SmrgKdXVPutStill( 1303706f2543Smrg ClientPtr client, 1304706f2543Smrg DrawablePtr pDraw, 1305706f2543Smrg XvPortPtr pPort, 1306706f2543Smrg GCPtr pGC, 1307706f2543Smrg INT16 vid_x, INT16 vid_y, 1308706f2543Smrg CARD16 vid_w, CARD16 vid_h, 1309706f2543Smrg INT16 drw_x, INT16 drw_y, 1310706f2543Smrg CARD16 drw_w, CARD16 drw_h 1311706f2543Smrg){ 1312706f2543Smrg XvPortRecPrivatePtr portPriv = (XvPortRecPrivatePtr)(pPort->devPriv.ptr); 1313706f2543Smrg ScreenPtr pScreen = pDraw->pScreen; 1314706f2543Smrg KdScreenPriv(pScreen); 1315706f2543Smrg KdScreenInfo *screen=pScreenPriv->screen; 1316706f2543Smrg RegionRec WinRegion; 1317706f2543Smrg RegionRec ClipRegion; 1318706f2543Smrg BoxRec WinBox; 1319706f2543Smrg int ret = Success; 1320706f2543Smrg Bool clippedAway = FALSE; 1321706f2543Smrg 1322706f2543Smrg if (pDraw->type != DRAWABLE_WINDOW) 1323706f2543Smrg return BadAlloc; 1324706f2543Smrg 1325706f2543Smrg if (!pScreenPriv->enabled) return Success; 1326706f2543Smrg 1327706f2543Smrg WinBox.x1 = pDraw->x + drw_x; 1328706f2543Smrg WinBox.y1 = pDraw->y + drw_y; 1329706f2543Smrg WinBox.x2 = WinBox.x1 + drw_w; 1330706f2543Smrg WinBox.y2 = WinBox.y1 + drw_h; 1331706f2543Smrg 1332706f2543Smrg RegionInit(&WinRegion, &WinBox, 1); 1333706f2543Smrg RegionInit(&ClipRegion, NullBox, 1); 1334706f2543Smrg RegionIntersect(&ClipRegion, &WinRegion, pGC->pCompositeClip); 1335706f2543Smrg 1336706f2543Smrg if(portPriv->AdaptorRec->flags & VIDEO_CLIP_TO_VIEWPORT) { 1337706f2543Smrg RegionRec VPReg; 1338706f2543Smrg BoxRec VPBox; 1339706f2543Smrg 1340706f2543Smrg VPBox.x1 = 0; 1341706f2543Smrg VPBox.y1 = 0; 1342706f2543Smrg VPBox.x2 = screen->width; 1343706f2543Smrg VPBox.y2 = screen->height; 1344706f2543Smrg 1345706f2543Smrg RegionInit(&VPReg, &VPBox, 1); 1346706f2543Smrg RegionIntersect(&ClipRegion, &ClipRegion, &VPReg); 1347706f2543Smrg RegionUninit(&VPReg); 1348706f2543Smrg } 1349706f2543Smrg 1350706f2543Smrg if(portPriv->pDraw) { 1351706f2543Smrg KdXVRemovePortFromWindow((WindowPtr)(portPriv->pDraw), portPriv); 1352706f2543Smrg } 1353706f2543Smrg 1354706f2543Smrg if(!RegionNotEmpty(&ClipRegion)) { 1355706f2543Smrg clippedAway = TRUE; 1356706f2543Smrg goto PUT_STILL_BAILOUT; 1357706f2543Smrg } 1358706f2543Smrg 1359706f2543Smrg if(portPriv->AdaptorRec->flags & VIDEO_NO_CLIPPING) { 1360706f2543Smrg BoxPtr clipBox = RegionRects(&ClipRegion); 1361706f2543Smrg if( (RegionNumRects(&ClipRegion) != 1) || 1362706f2543Smrg (clipBox->x1 != WinBox.x1) || (clipBox->x2 != WinBox.x2) || 1363706f2543Smrg (clipBox->y1 != WinBox.y1) || (clipBox->y2 != WinBox.y2)) 1364706f2543Smrg { 1365706f2543Smrg clippedAway = TRUE; 1366706f2543Smrg goto PUT_STILL_BAILOUT; 1367706f2543Smrg } 1368706f2543Smrg } 1369706f2543Smrg 1370706f2543Smrg if(portPriv->AdaptorRec->flags & VIDEO_INVERT_CLIPLIST) { 1371706f2543Smrg RegionSubtract(&ClipRegion, &WinRegion, &ClipRegion); 1372706f2543Smrg } 1373706f2543Smrg 1374706f2543Smrg ret = (*portPriv->AdaptorRec->PutStill)(portPriv->screen, pDraw, 1375706f2543Smrg vid_x, vid_y, WinBox.x1, WinBox.y1, 1376706f2543Smrg vid_w, vid_h, drw_w, drw_h, 1377706f2543Smrg &ClipRegion, portPriv->DevPriv.ptr); 1378706f2543Smrg 1379706f2543Smrg if((ret == Success) && 1380706f2543Smrg (portPriv->AdaptorRec->flags & VIDEO_OVERLAID_STILLS)) { 1381706f2543Smrg 1382706f2543Smrg KdXVEnlistPortInWindow((WindowPtr)pDraw, portPriv); 1383706f2543Smrg portPriv->isOn = XV_ON; 1384706f2543Smrg portPriv->pDraw = pDraw; 1385706f2543Smrg portPriv->drw_x = drw_x; portPriv->drw_y = drw_y; 1386706f2543Smrg portPriv->drw_w = drw_w; portPriv->drw_h = drw_h; 1387706f2543Smrg portPriv->type = 0; /* no mask means it's transient and should 1388706f2543Smrg not be reput once it's removed */ 1389706f2543Smrg pPort->pDraw = pDraw; /* make sure we can get stop requests */ 1390706f2543Smrg } 1391706f2543Smrg 1392706f2543SmrgPUT_STILL_BAILOUT: 1393706f2543Smrg 1394706f2543Smrg if((clippedAway || (ret != Success)) && (portPriv->isOn == XV_ON)) { 1395706f2543Smrg (*portPriv->AdaptorRec->StopVideo)( 1396706f2543Smrg portPriv->screen, portPriv->DevPriv.ptr, FALSE); 1397706f2543Smrg portPriv->isOn = XV_PENDING; 1398706f2543Smrg } 1399706f2543Smrg 1400706f2543Smrg RegionUninit(&WinRegion); 1401706f2543Smrg RegionUninit(&ClipRegion); 1402706f2543Smrg 1403706f2543Smrg return ret; 1404706f2543Smrg} 1405706f2543Smrg 1406706f2543Smrgstatic int 1407706f2543SmrgKdXVGetVideo( 1408706f2543Smrg ClientPtr client, 1409706f2543Smrg DrawablePtr pDraw, 1410706f2543Smrg XvPortPtr pPort, 1411706f2543Smrg GCPtr pGC, 1412706f2543Smrg INT16 vid_x, INT16 vid_y, 1413706f2543Smrg CARD16 vid_w, CARD16 vid_h, 1414706f2543Smrg INT16 drw_x, INT16 drw_y, 1415706f2543Smrg CARD16 drw_w, CARD16 drw_h 1416706f2543Smrg){ 1417706f2543Smrg XvPortRecPrivatePtr portPriv = (XvPortRecPrivatePtr)(pPort->devPriv.ptr); 1418706f2543Smrg int result; 1419706f2543Smrg KdScreenPriv(portPriv->screen->pScreen); 1420706f2543Smrg 1421706f2543Smrg /* No pixmaps... For now anyhow */ 1422706f2543Smrg if(pDraw->type != DRAWABLE_WINDOW) { 1423706f2543Smrg pPort->pDraw = (DrawablePtr)NULL; 1424706f2543Smrg return BadAlloc; 1425706f2543Smrg } 1426706f2543Smrg 1427706f2543Smrg /* If we are changing windows, unregister our port in the old window */ 1428706f2543Smrg if(portPriv->pDraw && (portPriv->pDraw != pDraw)) 1429706f2543Smrg KdXVRemovePortFromWindow((WindowPtr)(portPriv->pDraw), portPriv); 1430706f2543Smrg 1431706f2543Smrg /* Register our port with the new window */ 1432706f2543Smrg result = KdXVEnlistPortInWindow((WindowPtr)pDraw, portPriv); 1433706f2543Smrg if(result != Success) return result; 1434706f2543Smrg 1435706f2543Smrg portPriv->pDraw = pDraw; 1436706f2543Smrg portPriv->type = XvOutputMask; 1437706f2543Smrg 1438706f2543Smrg /* save a copy of these parameters */ 1439706f2543Smrg portPriv->vid_x = vid_x; portPriv->vid_y = vid_y; 1440706f2543Smrg portPriv->vid_w = vid_w; portPriv->vid_h = vid_h; 1441706f2543Smrg portPriv->drw_x = drw_x; portPriv->drw_y = drw_y; 1442706f2543Smrg portPriv->drw_w = drw_w; portPriv->drw_h = drw_h; 1443706f2543Smrg 1444706f2543Smrg /* make sure we have the most recent copy of the clientClip */ 1445706f2543Smrg KdXVCopyClip(portPriv, pGC); 1446706f2543Smrg 1447706f2543Smrg /* To indicate to the DI layer that we were successful */ 1448706f2543Smrg pPort->pDraw = pDraw; 1449706f2543Smrg 1450706f2543Smrg if(!pScreenPriv->enabled) return Success; 1451706f2543Smrg 1452706f2543Smrg return(KdXVRegetVideo(portPriv)); 1453706f2543Smrg} 1454706f2543Smrg 1455706f2543Smrgstatic int 1456706f2543SmrgKdXVGetStill( 1457706f2543Smrg ClientPtr client, 1458706f2543Smrg DrawablePtr pDraw, 1459706f2543Smrg XvPortPtr pPort, 1460706f2543Smrg GCPtr pGC, 1461706f2543Smrg INT16 vid_x, INT16 vid_y, 1462706f2543Smrg CARD16 vid_w, CARD16 vid_h, 1463706f2543Smrg INT16 drw_x, INT16 drw_y, 1464706f2543Smrg CARD16 drw_w, CARD16 drw_h 1465706f2543Smrg){ 1466706f2543Smrg XvPortRecPrivatePtr portPriv = (XvPortRecPrivatePtr)(pPort->devPriv.ptr); 1467706f2543Smrg ScreenPtr pScreen = pDraw->pScreen; 1468706f2543Smrg KdScreenPriv(pScreen); 1469706f2543Smrg RegionRec WinRegion; 1470706f2543Smrg RegionRec ClipRegion; 1471706f2543Smrg BoxRec WinBox; 1472706f2543Smrg int ret = Success; 1473706f2543Smrg Bool clippedAway = FALSE; 1474706f2543Smrg 1475706f2543Smrg if (pDraw->type != DRAWABLE_WINDOW) 1476706f2543Smrg return BadAlloc; 1477706f2543Smrg 1478706f2543Smrg if(!pScreenPriv->enabled) return Success; 1479706f2543Smrg 1480706f2543Smrg WinBox.x1 = pDraw->x + drw_x; 1481706f2543Smrg WinBox.y1 = pDraw->y + drw_y; 1482706f2543Smrg WinBox.x2 = WinBox.x1 + drw_w; 1483706f2543Smrg WinBox.y2 = WinBox.y1 + drw_h; 1484706f2543Smrg 1485706f2543Smrg RegionInit(&WinRegion, &WinBox, 1); 1486706f2543Smrg RegionInit(&ClipRegion, NullBox, 1); 1487706f2543Smrg RegionIntersect(&ClipRegion, &WinRegion, pGC->pCompositeClip); 1488706f2543Smrg 1489706f2543Smrg if(portPriv->pDraw) { 1490706f2543Smrg KdXVRemovePortFromWindow((WindowPtr)(portPriv->pDraw), portPriv); 1491706f2543Smrg } 1492706f2543Smrg 1493706f2543Smrg if(!RegionNotEmpty(&ClipRegion)) { 1494706f2543Smrg clippedAway = TRUE; 1495706f2543Smrg goto GET_STILL_BAILOUT; 1496706f2543Smrg } 1497706f2543Smrg 1498706f2543Smrg if(portPriv->AdaptorRec->flags & VIDEO_INVERT_CLIPLIST) { 1499706f2543Smrg RegionSubtract(&ClipRegion, &WinRegion, &ClipRegion); 1500706f2543Smrg } 1501706f2543Smrg 1502706f2543Smrg ret = (*portPriv->AdaptorRec->GetStill)(portPriv->screen, pDraw, 1503706f2543Smrg vid_x, vid_y, WinBox.x1, WinBox.y1, 1504706f2543Smrg vid_w, vid_h, drw_w, drw_h, 1505706f2543Smrg &ClipRegion, portPriv->DevPriv.ptr); 1506706f2543Smrg 1507706f2543SmrgGET_STILL_BAILOUT: 1508706f2543Smrg 1509706f2543Smrg if((clippedAway || (ret != Success)) && (portPriv->isOn == XV_ON)) { 1510706f2543Smrg (*portPriv->AdaptorRec->StopVideo)( 1511706f2543Smrg portPriv->screen, portPriv->DevPriv.ptr, FALSE); 1512706f2543Smrg portPriv->isOn = XV_PENDING; 1513706f2543Smrg } 1514706f2543Smrg 1515706f2543Smrg RegionUninit(&WinRegion); 1516706f2543Smrg RegionUninit(&ClipRegion); 1517706f2543Smrg 1518706f2543Smrg return ret; 1519706f2543Smrg} 1520706f2543Smrg 1521706f2543Smrg 1522706f2543Smrg 1523706f2543Smrgstatic int 1524706f2543SmrgKdXVStopVideo( 1525706f2543Smrg ClientPtr client, 1526706f2543Smrg XvPortPtr pPort, 1527706f2543Smrg DrawablePtr pDraw 1528706f2543Smrg){ 1529706f2543Smrg XvPortRecPrivatePtr portPriv = (XvPortRecPrivatePtr)(pPort->devPriv.ptr); 1530706f2543Smrg KdScreenPriv(portPriv->screen->pScreen); 1531706f2543Smrg 1532706f2543Smrg if(pDraw->type != DRAWABLE_WINDOW) 1533706f2543Smrg return BadAlloc; 1534706f2543Smrg 1535706f2543Smrg KdXVRemovePortFromWindow((WindowPtr)pDraw, portPriv); 1536706f2543Smrg 1537706f2543Smrg if(!pScreenPriv->enabled) return Success; 1538706f2543Smrg 1539706f2543Smrg /* Must free resources. */ 1540706f2543Smrg 1541706f2543Smrg if(portPriv->isOn > XV_OFF) { 1542706f2543Smrg (*portPriv->AdaptorRec->StopVideo)( 1543706f2543Smrg portPriv->screen, portPriv->DevPriv.ptr, TRUE); 1544706f2543Smrg portPriv->isOn = XV_OFF; 1545706f2543Smrg } 1546706f2543Smrg 1547706f2543Smrg return Success; 1548706f2543Smrg} 1549706f2543Smrg 1550706f2543Smrgstatic int 1551706f2543SmrgKdXVSetPortAttribute( 1552706f2543Smrg ClientPtr client, 1553706f2543Smrg XvPortPtr pPort, 1554706f2543Smrg Atom attribute, 1555706f2543Smrg INT32 value 1556706f2543Smrg){ 1557706f2543Smrg XvPortRecPrivatePtr portPriv = (XvPortRecPrivatePtr)(pPort->devPriv.ptr); 1558706f2543Smrg 1559706f2543Smrg return((*portPriv->AdaptorRec->SetPortAttribute)(portPriv->screen, 1560706f2543Smrg attribute, value, portPriv->DevPriv.ptr)); 1561706f2543Smrg} 1562706f2543Smrg 1563706f2543Smrg 1564706f2543Smrgstatic int 1565706f2543SmrgKdXVGetPortAttribute( 1566706f2543Smrg ClientPtr client, 1567706f2543Smrg XvPortPtr pPort, 1568706f2543Smrg Atom attribute, 1569706f2543Smrg INT32 *p_value 1570706f2543Smrg){ 1571706f2543Smrg XvPortRecPrivatePtr portPriv = (XvPortRecPrivatePtr)(pPort->devPriv.ptr); 1572706f2543Smrg 1573706f2543Smrg return((*portPriv->AdaptorRec->GetPortAttribute)(portPriv->screen, 1574706f2543Smrg attribute, (int *) p_value, portPriv->DevPriv.ptr)); 1575706f2543Smrg} 1576706f2543Smrg 1577706f2543Smrg 1578706f2543Smrg 1579706f2543Smrgstatic int 1580706f2543SmrgKdXVQueryBestSize( 1581706f2543Smrg ClientPtr client, 1582706f2543Smrg XvPortPtr pPort, 1583706f2543Smrg CARD8 motion, 1584706f2543Smrg CARD16 vid_w, CARD16 vid_h, 1585706f2543Smrg CARD16 drw_w, CARD16 drw_h, 1586706f2543Smrg unsigned int *p_w, unsigned int *p_h 1587706f2543Smrg){ 1588706f2543Smrg XvPortRecPrivatePtr portPriv = (XvPortRecPrivatePtr)(pPort->devPriv.ptr); 1589706f2543Smrg 1590706f2543Smrg (*portPriv->AdaptorRec->QueryBestSize)(portPriv->screen, 1591706f2543Smrg (Bool)motion, vid_w, vid_h, drw_w, drw_h, 1592706f2543Smrg p_w, p_h, portPriv->DevPriv.ptr); 1593706f2543Smrg 1594706f2543Smrg return Success; 1595706f2543Smrg} 1596706f2543Smrg 1597706f2543Smrg 1598706f2543Smrgstatic int 1599706f2543SmrgKdXVPutImage( 1600706f2543Smrg ClientPtr client, 1601706f2543Smrg DrawablePtr pDraw, 1602706f2543Smrg XvPortPtr pPort, 1603706f2543Smrg GCPtr pGC, 1604706f2543Smrg INT16 src_x, INT16 src_y, 1605706f2543Smrg CARD16 src_w, CARD16 src_h, 1606706f2543Smrg INT16 drw_x, INT16 drw_y, 1607706f2543Smrg CARD16 drw_w, CARD16 drw_h, 1608706f2543Smrg XvImagePtr format, 1609706f2543Smrg unsigned char* data, 1610706f2543Smrg Bool sync, 1611706f2543Smrg CARD16 width, CARD16 height 1612706f2543Smrg){ 1613706f2543Smrg XvPortRecPrivatePtr portPriv = (XvPortRecPrivatePtr)(pPort->devPriv.ptr); 1614706f2543Smrg ScreenPtr pScreen = pDraw->pScreen; 1615706f2543Smrg KdScreenPriv(pScreen); 1616706f2543Smrg RegionRec WinRegion; 1617706f2543Smrg RegionRec ClipRegion; 1618706f2543Smrg BoxRec WinBox; 1619706f2543Smrg int ret = Success; 1620706f2543Smrg Bool clippedAway = FALSE; 1621706f2543Smrg 1622706f2543Smrg if (pDraw->type != DRAWABLE_WINDOW) 1623706f2543Smrg return BadAlloc; 1624706f2543Smrg 1625706f2543Smrg if(!pScreenPriv->enabled) return Success; 1626706f2543Smrg 1627706f2543Smrg WinBox.x1 = pDraw->x + drw_x; 1628706f2543Smrg WinBox.y1 = pDraw->y + drw_y; 1629706f2543Smrg WinBox.x2 = WinBox.x1 + drw_w; 1630706f2543Smrg WinBox.y2 = WinBox.y1 + drw_h; 1631706f2543Smrg 1632706f2543Smrg RegionInit(&WinRegion, &WinBox, 1); 1633706f2543Smrg RegionInit(&ClipRegion, NullBox, 1); 1634706f2543Smrg RegionIntersect(&ClipRegion, &WinRegion, pGC->pCompositeClip); 1635706f2543Smrg 1636706f2543Smrg if(portPriv->AdaptorRec->flags & VIDEO_CLIP_TO_VIEWPORT) { 1637706f2543Smrg RegionRec VPReg; 1638706f2543Smrg BoxRec VPBox; 1639706f2543Smrg 1640706f2543Smrg VPBox.x1 = 0; 1641706f2543Smrg VPBox.y1 = 0; 1642706f2543Smrg VPBox.x2 = pScreen->width; 1643706f2543Smrg VPBox.y2 = pScreen->height; 1644706f2543Smrg 1645706f2543Smrg RegionInit(&VPReg, &VPBox, 1); 1646706f2543Smrg RegionIntersect(&ClipRegion, &ClipRegion, &VPReg); 1647706f2543Smrg RegionUninit(&VPReg); 1648706f2543Smrg } 1649706f2543Smrg 1650706f2543Smrg if(portPriv->pDraw) { 1651706f2543Smrg KdXVRemovePortFromWindow((WindowPtr)(portPriv->pDraw), portPriv); 1652706f2543Smrg } 1653706f2543Smrg 1654706f2543Smrg if(!RegionNotEmpty(&ClipRegion)) { 1655706f2543Smrg clippedAway = TRUE; 1656706f2543Smrg goto PUT_IMAGE_BAILOUT; 1657706f2543Smrg } 1658706f2543Smrg 1659706f2543Smrg if(portPriv->AdaptorRec->flags & VIDEO_NO_CLIPPING) { 1660706f2543Smrg BoxPtr clipBox = RegionRects(&ClipRegion); 1661706f2543Smrg if( (RegionNumRects(&ClipRegion) != 1) || 1662706f2543Smrg (clipBox->x1 != WinBox.x1) || (clipBox->x2 != WinBox.x2) || 1663706f2543Smrg (clipBox->y1 != WinBox.y1) || (clipBox->y2 != WinBox.y2)) 1664706f2543Smrg { 1665706f2543Smrg clippedAway = TRUE; 1666706f2543Smrg goto PUT_IMAGE_BAILOUT; 1667706f2543Smrg } 1668706f2543Smrg } 1669706f2543Smrg 1670706f2543Smrg if(portPriv->AdaptorRec->flags & VIDEO_INVERT_CLIPLIST) { 1671706f2543Smrg RegionSubtract(&ClipRegion, &WinRegion, &ClipRegion); 1672706f2543Smrg } 1673706f2543Smrg 1674706f2543Smrg ret = (*portPriv->AdaptorRec->PutImage)(portPriv->screen, pDraw, 1675706f2543Smrg src_x, src_y, WinBox.x1, WinBox.y1, 1676706f2543Smrg src_w, src_h, drw_w, drw_h, format->id, data, width, height, 1677706f2543Smrg sync, &ClipRegion, portPriv->DevPriv.ptr); 1678706f2543Smrg 1679706f2543Smrg if((ret == Success) && 1680706f2543Smrg (portPriv->AdaptorRec->flags & VIDEO_OVERLAID_IMAGES)) { 1681706f2543Smrg 1682706f2543Smrg KdXVEnlistPortInWindow((WindowPtr)pDraw, portPriv); 1683706f2543Smrg portPriv->isOn = XV_ON; 1684706f2543Smrg portPriv->pDraw = pDraw; 1685706f2543Smrg portPriv->drw_x = drw_x; portPriv->drw_y = drw_y; 1686706f2543Smrg portPriv->drw_w = drw_w; portPriv->drw_h = drw_h; 1687706f2543Smrg portPriv->type = 0; /* no mask means it's transient and should 1688706f2543Smrg not be reput once it's removed */ 1689706f2543Smrg pPort->pDraw = pDraw; /* make sure we can get stop requests */ 1690706f2543Smrg } 1691706f2543Smrg 1692706f2543SmrgPUT_IMAGE_BAILOUT: 1693706f2543Smrg 1694706f2543Smrg if((clippedAway || (ret != Success)) && (portPriv->isOn == XV_ON)) { 1695706f2543Smrg (*portPriv->AdaptorRec->StopVideo)( 1696706f2543Smrg portPriv->screen, portPriv->DevPriv.ptr, FALSE); 1697706f2543Smrg portPriv->isOn = XV_PENDING; 1698706f2543Smrg } 1699706f2543Smrg 1700706f2543Smrg RegionUninit(&WinRegion); 1701706f2543Smrg RegionUninit(&ClipRegion); 1702706f2543Smrg 1703706f2543Smrg return ret; 1704706f2543Smrg} 1705706f2543Smrg 1706706f2543Smrg 1707706f2543Smrgstatic int 1708706f2543SmrgKdXVQueryImageAttributes( 1709706f2543Smrg ClientPtr client, 1710706f2543Smrg XvPortPtr pPort, 1711706f2543Smrg XvImagePtr format, 1712706f2543Smrg CARD16 *width, 1713706f2543Smrg CARD16 *height, 1714706f2543Smrg int *pitches, 1715706f2543Smrg int *offsets 1716706f2543Smrg){ 1717706f2543Smrg XvPortRecPrivatePtr portPriv = (XvPortRecPrivatePtr)(pPort->devPriv.ptr); 1718706f2543Smrg 1719706f2543Smrg return (*portPriv->AdaptorRec->QueryImageAttributes)(portPriv->screen, 1720706f2543Smrg format->id, width, height, pitches, offsets); 1721706f2543Smrg} 1722706f2543Smrg 1723706f2543Smrg 1724706f2543Smrg/**************** Common video manipulation functions *******************/ 1725706f2543Smrg 1726706f2543Smrgvoid 1727706f2543SmrgKdXVCopyPackedData(KdScreenInfo *screen, CARD8 *src, CARD8 *dst, int randr, 1728706f2543Smrg int srcPitch, int dstPitch, int srcW, int srcH, int top, int left, 1729706f2543Smrg int h, int w) 1730706f2543Smrg{ 1731706f2543Smrg int srcDown = srcPitch, srcRight = 2, srcNext; 1732706f2543Smrg int p; 1733706f2543Smrg 1734706f2543Smrg switch (randr & RR_Rotate_All) { 1735706f2543Smrg case RR_Rotate_0: 1736706f2543Smrg srcDown = srcPitch; 1737706f2543Smrg srcRight = 2; 1738706f2543Smrg break; 1739706f2543Smrg case RR_Rotate_90: 1740706f2543Smrg src += (srcH - 1) * 2; 1741706f2543Smrg srcDown = -2; 1742706f2543Smrg srcRight = srcPitch; 1743706f2543Smrg break; 1744706f2543Smrg case RR_Rotate_180: 1745706f2543Smrg src += srcPitch * (srcH - 1) + (srcW - 1) * 2; 1746706f2543Smrg srcDown = -srcPitch; 1747706f2543Smrg srcRight = -2; 1748706f2543Smrg break; 1749706f2543Smrg case RR_Rotate_270: 1750706f2543Smrg src += srcPitch * (srcW - 1); 1751706f2543Smrg srcDown = 2; 1752706f2543Smrg srcRight = -srcPitch; 1753706f2543Smrg break; 1754706f2543Smrg } 1755706f2543Smrg 1756706f2543Smrg src = src + top * srcDown + left * srcRight; 1757706f2543Smrg 1758706f2543Smrg w >>= 1; 1759706f2543Smrg /* srcRight >>= 1; */ 1760706f2543Smrg srcNext = srcRight >> 1; 1761706f2543Smrg while (h--) { 1762706f2543Smrg CARD16 *s = (CARD16 *)src; 1763706f2543Smrg CARD32 *d = (CARD32 *)dst; 1764706f2543Smrg p = w; 1765706f2543Smrg while (p--) { 1766706f2543Smrg *d++ = s[0] | (s[srcNext] << 16); 1767706f2543Smrg s += srcRight; 1768706f2543Smrg } 1769706f2543Smrg src += srcPitch; 1770706f2543Smrg dst += dstPitch; 1771706f2543Smrg } 1772706f2543Smrg} 1773706f2543Smrg 1774706f2543Smrgvoid 1775706f2543SmrgKdXVCopyPlanarData(KdScreenInfo *screen, CARD8 *src, CARD8 *dst, int randr, 1776706f2543Smrg int srcPitch, int srcPitch2, int dstPitch, int srcW, int srcH, int height, 1777706f2543Smrg int top, int left, int h, int w, int id) 1778706f2543Smrg{ 1779706f2543Smrg int i, j; 1780706f2543Smrg CARD8 *src1, *src2, *src3, *dst1; 1781706f2543Smrg int srcDown = srcPitch, srcDown2 = srcPitch2; 1782706f2543Smrg int srcRight = 2, srcRight2 = 1, srcNext = 1; 1783706f2543Smrg 1784706f2543Smrg /* compute source data pointers */ 1785706f2543Smrg src1 = src; 1786706f2543Smrg src2 = src1 + height * srcPitch; 1787706f2543Smrg src3 = src2 + (height >> 1) * srcPitch2; 1788706f2543Smrg switch (randr & RR_Rotate_All) { 1789706f2543Smrg case RR_Rotate_0: 1790706f2543Smrg srcDown = srcPitch; 1791706f2543Smrg srcDown2 = srcPitch2; 1792706f2543Smrg srcRight = 2; 1793706f2543Smrg srcRight2 = 1; 1794706f2543Smrg srcNext = 1; 1795706f2543Smrg break; 1796706f2543Smrg case RR_Rotate_90: 1797706f2543Smrg src1 = src1 + srcH - 1; 1798706f2543Smrg src2 = src2 + (srcH >> 1) - 1; 1799706f2543Smrg src3 = src3 + (srcH >> 1) - 1; 1800706f2543Smrg srcDown = -1; 1801706f2543Smrg srcDown2 = -1; 1802706f2543Smrg srcRight = srcPitch * 2; 1803706f2543Smrg srcRight2 = srcPitch2; 1804706f2543Smrg srcNext = srcPitch; 1805706f2543Smrg break; 1806706f2543Smrg case RR_Rotate_180: 1807706f2543Smrg src1 = src1 + srcPitch * (srcH - 1) + (srcW - 1); 1808706f2543Smrg src2 = src2 + srcPitch2 * ((srcH >> 1) - 1) + ((srcW >> 1) - 1); 1809706f2543Smrg src3 = src3 + srcPitch2 * ((srcH >> 1) - 1) + ((srcW >> 1) - 1); 1810706f2543Smrg srcDown = -srcPitch; 1811706f2543Smrg srcDown2 = -srcPitch2; 1812706f2543Smrg srcRight = -2; 1813706f2543Smrg srcRight2 = -1; 1814706f2543Smrg srcNext = -1; 1815706f2543Smrg break; 1816706f2543Smrg case RR_Rotate_270: 1817706f2543Smrg src1 = src1 + srcPitch * (srcW - 1); 1818706f2543Smrg src2 = src2 + srcPitch2 * ((srcW >> 1) - 1); 1819706f2543Smrg src3 = src3 + srcPitch2 * ((srcW >> 1) - 1); 1820706f2543Smrg srcDown = 1; 1821706f2543Smrg srcDown2 = 1; 1822706f2543Smrg srcRight = -srcPitch * 2; 1823706f2543Smrg srcRight2 = -srcPitch2; 1824706f2543Smrg srcNext = -srcPitch; 1825706f2543Smrg break; 1826706f2543Smrg } 1827706f2543Smrg 1828706f2543Smrg /* adjust for origin */ 1829706f2543Smrg src1 += top * srcDown + left * srcNext; 1830706f2543Smrg src2 += (top >> 1) * srcDown2 + (left >> 1) * srcRight2; 1831706f2543Smrg src3 += (top >> 1) * srcDown2 + (left >> 1) * srcRight2; 1832706f2543Smrg 1833706f2543Smrg if (id == FOURCC_I420) { 1834706f2543Smrg CARD8 *srct = src2; 1835706f2543Smrg src2 = src3; 1836706f2543Smrg src3 = srct; 1837706f2543Smrg } 1838706f2543Smrg 1839706f2543Smrg dst1 = dst; 1840706f2543Smrg 1841706f2543Smrg w >>= 1; 1842706f2543Smrg for (j = 0; j < h; j++) { 1843706f2543Smrg CARD32 *dst = (CARD32 *)dst1; 1844706f2543Smrg CARD8 *s1l = src1; 1845706f2543Smrg CARD8 *s1r = src1 + srcNext; 1846706f2543Smrg CARD8 *s2 = src2; 1847706f2543Smrg CARD8 *s3 = src3; 1848706f2543Smrg 1849706f2543Smrg for (i = 0; i < w; i++) { 1850706f2543Smrg *dst++ = *s1l | (*s1r << 16) | (*s3 << 8) | (*s2 << 24); 1851706f2543Smrg s1l += srcRight; 1852706f2543Smrg s1r += srcRight; 1853706f2543Smrg s2 += srcRight2; 1854706f2543Smrg s3 += srcRight2; 1855706f2543Smrg } 1856706f2543Smrg src1 += srcDown; 1857706f2543Smrg dst1 += dstPitch; 1858706f2543Smrg if (j & 1) { 1859706f2543Smrg src2 += srcDown2; 1860706f2543Smrg src3 += srcDown2; 1861706f2543Smrg } 1862706f2543Smrg } 1863706f2543Smrg} 1864706f2543Smrg 1865706f2543Smrgvoid 1866706f2543SmrgKXVPaintRegion (DrawablePtr pDraw, RegionPtr pRgn, Pixel fg) 1867706f2543Smrg{ 1868706f2543Smrg GCPtr pGC; 1869706f2543Smrg ChangeGCVal val[2]; 1870706f2543Smrg xRectangle *rects, *r; 1871706f2543Smrg BoxPtr pBox = RegionRects (pRgn); 1872706f2543Smrg int nBox = RegionNumRects (pRgn); 1873706f2543Smrg 1874706f2543Smrg rects = malloc(nBox * sizeof (xRectangle)); 1875706f2543Smrg if (!rects) 1876706f2543Smrg goto bail0; 1877706f2543Smrg r = rects; 1878706f2543Smrg while (nBox--) 1879706f2543Smrg { 1880706f2543Smrg r->x = pBox->x1 - pDraw->x; 1881706f2543Smrg r->y = pBox->y1 - pDraw->y; 1882706f2543Smrg r->width = pBox->x2 - pBox->x1; 1883706f2543Smrg r->height = pBox->y2 - pBox->y1; 1884706f2543Smrg r++; 1885706f2543Smrg pBox++; 1886706f2543Smrg } 1887706f2543Smrg 1888706f2543Smrg pGC = GetScratchGC (pDraw->depth, pDraw->pScreen); 1889706f2543Smrg if (!pGC) 1890706f2543Smrg goto bail1; 1891706f2543Smrg 1892706f2543Smrg val[0].val = fg; 1893706f2543Smrg val[1].val = IncludeInferiors; 1894706f2543Smrg ChangeGC (NullClient, pGC, GCForeground|GCSubwindowMode, val); 1895706f2543Smrg 1896706f2543Smrg ValidateGC (pDraw, pGC); 1897706f2543Smrg 1898706f2543Smrg (*pGC->ops->PolyFillRect) (pDraw, pGC, 1899706f2543Smrg RegionNumRects (pRgn), rects); 1900706f2543Smrg 1901706f2543Smrg FreeScratchGC (pGC); 1902706f2543Smrgbail1: 1903706f2543Smrg free(rects); 1904706f2543Smrgbail0: 1905706f2543Smrg ; 1906706f2543Smrg} 1907