diff --git a/hw/xfree86/common/xf86Module.h b/hw/xfree86/common/xf86Module.h index f0cf5eb93..3c3247e40 100644 --- a/hw/xfree86/common/xf86Module.h +++ b/hw/xfree86/common/xf86Module.h @@ -84,7 +84,7 @@ typedef enum { * mask is 0xFFFF0000. */ #define ABI_ANSIC_VERSION SET_ABI_VERSION(0, 3) -#define ABI_VIDEODRV_VERSION SET_ABI_VERSION(1, 0) +#define ABI_VIDEODRV_VERSION SET_ABI_VERSION(1, 1) #define ABI_XINPUT_VERSION SET_ABI_VERSION(1, 0) #define ABI_EXTENSION_VERSION SET_ABI_VERSION(0, 3) #define ABI_FONT_VERSION SET_ABI_VERSION(0, 5) diff --git a/hw/xfree86/common/xf86xv.c b/hw/xfree86/common/xf86xv.c index 89cb6bac4..3e908b86a 100644 --- a/hw/xfree86/common/xf86xv.c +++ b/hw/xfree86/common/xf86xv.c @@ -974,6 +974,7 @@ xf86XVEnlistPortInWindow(WindowPtr pWin, XvPortRecPrivatePtr portPriv) if(!winPriv) { winPriv = xalloc(sizeof(XF86XVWindowRec)); if(!winPriv) return BadAlloc; + memset(winPriv, 0, sizeof(XF86XVWindowRec)); winPriv->PortRec = portPriv; winPriv->next = PrivRoot; pWin->devPrivates[XF86XVWindowIndex].ptr = (pointer)winPriv; @@ -1026,6 +1027,9 @@ xf86XVDestroyWindow(WindowPtr pWin) pPriv->pDraw = NULL; tmp = WinPriv; + if(WinPriv->pGC) { + FreeGC(WinPriv->pGC, 0); + } WinPriv = WinPriv->next; xfree(tmp); } @@ -1118,6 +1122,8 @@ xf86XVClipNotify(WindowPtr pWin, int dx, int dy) while(WinPriv) { pPriv = WinPriv->PortRec; + if(!pPriv) goto next; + if(pPriv->pCompositeClip && pPriv->FreeCompositeClip) REGION_DESTROY(pScreen, pPriv->pCompositeClip); @@ -1148,6 +1154,7 @@ xf86XVClipNotify(WindowPtr pWin, int dx, int dy) } } +next: pPrev = WinPriv; WinPriv = WinPriv->next; } @@ -1739,9 +1746,13 @@ xf86XVPutImage( REGION_UNINIT(pScreen, &VPReg); } - if(portPriv->pDraw) { + /* If we are changing windows, unregister our port in the old window */ + if(portPriv->pDraw && (portPriv->pDraw != pDraw)) xf86XVRemovePortFromWindow((WindowPtr)(portPriv->pDraw), portPriv); - } + + /* Register our port with the new window */ + ret = xf86XVEnlistPortInWindow((WindowPtr)pDraw, portPriv); + if(ret != Success) goto PUT_IMAGE_BAILOUT; if(!REGION_NOTEMPTY(pScreen, &ClipRegion)) { clippedAway = TRUE; @@ -1772,7 +1783,6 @@ xf86XVPutImage( if((ret == Success) && (portPriv->AdaptorRec->flags & VIDEO_OVERLAID_IMAGES)) { - xf86XVEnlistPortInWindow((WindowPtr)pDraw, portPriv); portPriv->isOn = XV_ON; portPriv->pDraw = pDraw; portPriv->drw_x = drw_x; portPriv->drw_y = drw_y; @@ -1813,6 +1823,56 @@ xf86XVQueryImageAttributes( format->id, width, height, pitches, offsets); } + +_X_EXPORT void +xf86XVFillKeyHelperDrawable (DrawablePtr pDraw, CARD32 key, RegionPtr clipboxes) +{ + ScreenPtr pScreen = pDraw->pScreen; + WindowPtr pWin = (WindowPtr)pDraw; + XF86XVWindowPtr pPriv = GET_XF86XV_WINDOW(pWin); + GCPtr pGC = NULL; + XID pval[2]; + BoxPtr pbox = REGION_RECTS(clipboxes); + int i, nbox = REGION_NUM_RECTS(clipboxes); + xRectangle *rects; + + if(!xf86Screens[pScreen->myNum]->vtSema) return; + + if(pPriv) + pGC = pPriv->pGC; + + if(!pGC) { + int status; + pval[0] = key; + pval[1] = IncludeInferiors; + pGC = CreateGC(pDraw, GCForeground | GCSubwindowMode, pval, &status); + if(!pGC) return; + ValidateGC(pDraw, pGC); + if (pPriv) pPriv->pGC = pGC; + } else if (key != pGC->fgPixel){ + pval[0] = key; + ChangeGC(pGC, GCForeground, pval); + ValidateGC(pDraw, pGC); + } + + REGION_TRANSLATE(pDraw->pScreen, clipboxes, -pDraw->x, -pDraw->y); + + rects = ALLOCATE_LOCAL(nbox * sizeof(xRectangle)); + + for(i = 0; i < nbox; i++, pbox++) { + rects[i].x = pbox->x1; + rects[i].y = pbox->y1; + rects[i].width = pbox->x2 - pbox->x1; + rects[i].height = pbox->y2 - pbox->y1; + } + + (*pGC->ops->PolyFillRect)(pDraw, pGC, nbox, rects); + + if (!pPriv) FreeGC(pGC, 0); + + DEALLOCATE_LOCAL(rects); +} + _X_EXPORT void xf86XVFillKeyHelper (ScreenPtr pScreen, CARD32 key, RegionPtr clipboxes) { diff --git a/hw/xfree86/common/xf86xv.h b/hw/xfree86/common/xf86xv.h index e0feb57b8..817e2b994 100644 --- a/hw/xfree86/common/xf86xv.h +++ b/hw/xfree86/common/xf86xv.h @@ -232,6 +232,9 @@ void xf86XVFreeVideoAdaptorRec(XF86VideoAdaptorPtr ptr); void xf86XVFillKeyHelper (ScreenPtr pScreen, CARD32 key, RegionPtr clipboxes); +void +xf86XVFillKeyHelperDrawable (DrawablePtr pDraw, CARD32 key, RegionPtr clipboxes); + Bool xf86XVClipVideoHelper( BoxPtr dst, diff --git a/hw/xfree86/common/xf86xvpriv.h b/hw/xfree86/common/xf86xvpriv.h index ced053679..e716c9c6a 100644 --- a/hw/xfree86/common/xf86xvpriv.h +++ b/hw/xfree86/common/xf86xvpriv.h @@ -80,6 +80,7 @@ typedef struct { typedef struct _XF86XVWindowRec{ XvPortRecPrivatePtr PortRec; struct _XF86XVWindowRec *next; + GCPtr pGC; } XF86XVWindowRec, *XF86XVWindowPtr; #endif /* _XF86XVPRIV_H_ */ diff --git a/hw/xfree86/loader/xf86sym.c b/hw/xfree86/loader/xf86sym.c index 586d5dc81..8e39373b3 100644 --- a/hw/xfree86/loader/xf86sym.c +++ b/hw/xfree86/loader/xf86sym.c @@ -621,6 +621,7 @@ _X_HIDDEN void *xfree86LookupTab[] = { SYMFUNC(xf86XVAllocateVideoAdaptorRec) SYMFUNC(xf86XVFreeVideoAdaptorRec) SYMFUNC(xf86XVFillKeyHelper) + SYMFUNC(xf86XVFillKeyHelperDrawable) SYMFUNC(xf86XVClipVideoHelper) SYMFUNC(xf86XVCopyYUV12ToPacked) SYMFUNC(xf86XVCopyPacked)