diff -ur -x Makefile xc/programs/Xserver/hw/xfree86/common/xf86xv.c my/programs/Xserver/hw/xfree86/common/xf86xv.c --- xc/programs/Xserver/hw/xfree86/common/xf86xv.c Thu Mar 9 20:09:35 2000 +++ my/programs/Xserver/hw/xfree86/common/xf86xv.c Mon Mar 13 20:32:39 2000 @@ -6,7 +6,7 @@ */ -/* $XFree86: xc/programs/Xserver/hw/xfree86/common/xf86xv.c,v 1.19 2000/02/22 01:58:06 mvojkovi Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/common/xf86xv.c,v 1.16 1999/12/17 02:45:37 mvojkovi Exp $ */ #include "misc.h" #include "xf86.h" @@ -18,6 +18,7 @@ #include "regionstr.h" #include "windowstr.h" #include "pixmapstr.h" +#include "mivalidate.h" #include "validate.h" #include "resource.h" #include "gcstruct.h" @@ -73,6 +74,7 @@ static Bool xf86XVCreateWindow(WindowPtr pWin); static Bool xf86XVDestroyWindow(WindowPtr pWin); +static void xf86XVWindowExposures(WindowPtr pWin, RegionPtr r1, RegionPtr r2); static void xf86XVClipNotify(WindowPtr pWin, int dx, int dy); /* ScrnInfoRec functions */ @@ -102,6 +104,15 @@ #endif +#define GET_XV_SCREEN(pScreen) \ + ((XvScreenPtr)((pScreen)->devPrivates[XF86XvScreenIndex].ptr)) + +#define GET_XF86XV_SCREEN(pScreen) \ + ((XF86XVScreenPtr)(GET_XV_SCREEN(pScreen)->devPriv.ptr)) + +#define GET_XF86XV_WINDOW(pWin) \ + ((XF86XVWindowPtr)((pWin)->devPrivates[XF86XVWindowIndex].ptr)) + static xf86XVInitGenericAdaptorPtr *GenDrivers = NULL; static int NumGenDrivers = 0; @@ -124,7 +135,7 @@ int xf86XVListGenericAdaptors( - ScrnInfoPtr pScrn, + ScreenPtr pScreen, XF86VideoAdaptorPtr **adaptors ){ int i,j,n,num; @@ -133,7 +144,7 @@ num = 0; *adaptors = NULL; for (i = 0; i < NumGenDrivers; i++) { - n = GenDrivers[i](pScrn,&DrivAdap); + n = GenDrivers[i](pScreen,&DrivAdap); if (0 == n) continue; new = xrealloc(*adaptors, sizeof(XF86VideoAdaptorPtr) * (num+n)); @@ -173,7 +184,7 @@ XF86XvScreenIndex = (*XvGetScreenIndexProc)(); PortResource = (*XvGetRTPortProc)(); - pxvs = (XvScreenPtr)pScreen->devPrivates[XF86XvScreenIndex].ptr; + pxvs = GET_XV_SCREEN(pScreen); /* Anyone initializing the Xv layer must provide these two. @@ -193,17 +204,19 @@ if(!ScreenPriv) return FALSE; - ScreenPriv->ClipNotify = pScreen->ClipNotify; ScreenPriv->CreateWindow = pScreen->CreateWindow; ScreenPriv->DestroyWindow = pScreen->DestroyWindow; + ScreenPriv->WindowExposures = pScreen->WindowExposures; + ScreenPriv->ClipNotify = pScreen->ClipNotify; ScreenPriv->EnterVT = pScrn->EnterVT; ScreenPriv->LeaveVT = pScrn->LeaveVT; ScreenPriv->AdjustFrame = pScrn->AdjustFrame; - pScreen->ClipNotify = xf86XVClipNotify; pScreen->CreateWindow = xf86XVCreateWindow; pScreen->DestroyWindow = xf86XVDestroyWindow; + pScreen->WindowExposures = xf86XVWindowExposures; + pScreen->ClipNotify = xf86XVClipNotify; pScrn->EnterVT = xf86XVEnterVT; pScrn->LeaveVT = xf86XVLeaveVT; pScrn->AdjustFrame = xf86XVAdjustFrame; @@ -274,7 +287,7 @@ XF86VideoAdaptorPtr *infoPtr, int number ) { - XvScreenPtr pxvs = (XvScreenPtr)(pScreen->devPrivates[XF86XvScreenIndex].ptr); + XvScreenPtr pxvs = GET_XV_SCREEN(pScreen); ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; XF86VideoAdaptorPtr adaptorPtr; XvAdaptorPtr pAdaptor, pa; @@ -863,8 +876,7 @@ static int xf86XVReputAllVideo(WindowPtr pWin, pointer data) { - XF86XVWindowPtr WinPriv = - (XF86XVWindowPtr)pWin->devPrivates[XF86XVWindowIndex].ptr; + XF86XVWindowPtr WinPriv = GET_XF86XV_WINDOW(pWin); while(WinPriv) { if(WinPriv->PortRec->type == XvInputMask) @@ -882,8 +894,7 @@ { XF86XVWindowPtr winPriv, PrivRoot; - winPriv = PrivRoot = - (XF86XVWindowPtr)(pWin->devPrivates[XF86XVWindowIndex].ptr); + winPriv = PrivRoot = GET_XF86XV_WINDOW(pWin); /* Enlist our port in the window private */ while(winPriv) { @@ -908,7 +919,7 @@ { XF86XVWindowPtr winPriv, prevPriv = NULL; - winPriv = (XF86XVWindowPtr)(pWin->devPrivates[XF86XVWindowIndex].ptr); + winPriv = GET_XF86XV_WINDOW(pWin); while(winPriv) { if(winPriv->PortRec == portPriv) { @@ -933,8 +944,7 @@ xf86XVCreateWindow(WindowPtr pWin) { ScreenPtr pScreen = pWin->drawable.pScreen; - XvScreenPtr pxvs = (XvScreenPtr)pScreen->devPrivates[XF86XvScreenIndex].ptr; - XF86XVScreenPtr ScreenPriv = (XF86XVScreenPtr)pxvs->devPriv.ptr; + XF86XVScreenPtr ScreenPriv = GET_XF86XV_SCREEN(pScreen); int ret; pScreen->CreateWindow = ScreenPriv->CreateWindow; @@ -951,13 +961,10 @@ xf86XVDestroyWindow(WindowPtr pWin) { ScreenPtr pScreen = pWin->drawable.pScreen; - XvScreenPtr pxvs = (XvScreenPtr)pScreen->devPrivates[XF86XvScreenIndex].ptr; - XF86XVScreenPtr ScreenPriv = (XF86XVScreenPtr)pxvs->devPriv.ptr; - XF86XVWindowPtr tmp, WinPriv = - (XF86XVWindowPtr)pWin->devPrivates[XF86XVWindowIndex].ptr; + XF86XVScreenPtr ScreenPriv = GET_XF86XV_SCREEN(pScreen); + XF86XVWindowPtr tmp, WinPriv = GET_XF86XV_WINDOW(pWin); int ret; - /* The DI layer only stops and removes video not transient stills/images */ while(WinPriv) { XvPortRecPrivatePtr pPriv = WinPriv->PortRec; @@ -983,41 +990,80 @@ } - static void +xf86XVWindowExposures(WindowPtr pWin, RegionPtr reg1, RegionPtr reg2) +{ + ScreenPtr pScreen = pWin->drawable.pScreen; + XF86XVScreenPtr ScreenPriv = GET_XF86XV_SCREEN(pScreen); + XF86XVWindowPtr WinPriv, pPrev; + XvPortRecPrivatePtr pPriv; + + pScreen->WindowExposures = ScreenPriv->WindowExposures; + (*pScreen->WindowExposures)(pWin, reg1, reg2); + pScreen->WindowExposures = xf86XVWindowExposures; + + /* filter out XClearWindow/Area */ + if (!pWin->valdata) return; + + WinPriv = GET_XF86XV_WINDOW(pWin); + pPrev = NULL; + + while(WinPriv) { + pPriv = WinPriv->PortRec; + + /* Reput anyone with a reput function */ + + switch(pPriv->type) { + case XvInputMask: + xf86XVReputVideo(pPriv); + break; + case XvOutputMask: + xf86XVRegetVideo(pPriv); + break; + default: /* overlaid still/image*/ + if (pPriv->AdaptorRec->ReputImage) + xf86XVReputImage(pPriv); + break; + } + pPrev = WinPriv; + WinPriv = WinPriv->next; + } +} + + +static void xf86XVClipNotify(WindowPtr pWin, int dx, int dy) { ScreenPtr pScreen = pWin->drawable.pScreen; - XvScreenPtr pxvs = (XvScreenPtr)pScreen->devPrivates[XF86XvScreenIndex].ptr; - XF86XVScreenPtr ScreenPriv = (XF86XVScreenPtr)pxvs->devPriv.ptr; - XF86XVWindowPtr WinPriv = - (XF86XVWindowPtr)pWin->devPrivates[XF86XVWindowIndex].ptr; + XF86XVScreenPtr ScreenPriv = GET_XF86XV_SCREEN(pScreen); + XF86XVWindowPtr WinPriv = GET_XF86XV_WINDOW(pWin); XF86XVWindowPtr tmp, pPrev = NULL; - + XvPortRecPrivatePtr pPriv; + Bool visible = (pWin->visibility == VisibilityUnobscured) || + (pWin->visibility == VisibilityPartiallyObscured); + while(WinPriv) { - XvPortRecPrivatePtr pPriv = WinPriv->PortRec; + pPriv = WinPriv->PortRec; if(pPriv->pCompositeClip && pPriv->FreeCompositeClip) REGION_DESTROY(pScreen, pPriv->pCompositeClip); pPriv->pCompositeClip = NULL; - if(!pPriv->type) { /* overlaid still/image */ - if ((pPriv->AdaptorRec->ReputImage) && - ((pWin->visibility == VisibilityUnobscured) || - (pWin->visibility == VisibilityPartiallyObscured))) - { - xf86XVReputImage(pPriv); - } - else { - (*pPriv->AdaptorRec->StopVideo)( - pPriv->pScrn, pPriv->DevPriv.ptr, FALSE); + /* Stop everything except images, but stop them too if the + window isn't visible. But we only remove the images. */ - pPriv->isOn = FALSE; + if(pPriv->type || !visible) { + (*pPriv->AdaptorRec->StopVideo)( + pPriv->pScrn, pPriv->DevPriv.ptr, FALSE); + pPriv->isOn = FALSE; + + if(!pPriv->type) { /* overlaid still/image */ pPriv->pDraw = NULL; + if(!pPrev) - pWin->devPrivates[XF86XVWindowIndex].ptr = - (pointer)(WinPriv->next); + pWin->devPrivates[XF86XVWindowIndex].ptr = + (pointer)(WinPriv->next); else pPrev->next = WinPriv->next; tmp = WinPriv; @@ -1025,20 +1071,16 @@ xfree(tmp); continue; } - } else { - if(pPriv->type == XvInputMask) - xf86XVReputVideo(pPriv); - else - xf86XVRegetVideo(pPriv); } + pPrev = WinPriv; WinPriv = WinPriv->next; } - + if(ScreenPriv->ClipNotify) { - pScreen->ClipNotify = ScreenPriv->ClipNotify; - (*pScreen->ClipNotify)(pWin, dx, dy); - pScreen->ClipNotify = xf86XVClipNotify; + pScreen->ClipNotify = ScreenPriv->ClipNotify; + (*pScreen->ClipNotify)(pWin, dx, dy); + pScreen->ClipNotify = xf86XVClipNotify; } } @@ -1050,8 +1092,8 @@ xf86XVCloseScreen(int i, ScreenPtr pScreen) { ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; - XvScreenPtr pxvs = (XvScreenPtr) pScreen->devPrivates[XF86XvScreenIndex].ptr; - XF86XVScreenPtr ScreenPriv = (XF86XVScreenPtr)pxvs->devPriv.ptr; + XvScreenPtr pxvs = GET_XV_SCREEN(pScreen); + XF86XVScreenPtr ScreenPriv = GET_XF86XV_SCREEN(pScreen); XvAdaptorPtr pa; int c; @@ -1059,6 +1101,7 @@ pScreen->CreateWindow = ScreenPriv->CreateWindow; pScreen->DestroyWindow = ScreenPriv->DestroyWindow; + pScreen->WindowExposures = ScreenPriv->WindowExposures; pScreen->ClipNotify = ScreenPriv->ClipNotify; pScrn->EnterVT = ScreenPriv->EnterVT; @@ -1085,7 +1128,7 @@ XvAdaptorPtr *p_pAdaptors, int *p_nAdaptors ){ - XvScreenPtr pxvs = (XvScreenPtr) pScreen->devPrivates[XF86XvScreenIndex].ptr; + XvScreenPtr pxvs = GET_XV_SCREEN(pScreen); *p_nAdaptors = pxvs->nAdaptors; *p_pAdaptors = pxvs->pAdaptors; @@ -1100,9 +1143,7 @@ xf86XVEnterVT(int index, int flags) { ScreenPtr pScreen = screenInfo.screens[index]; - XvScreenPtr pxvs = - (XvScreenPtr) pScreen->devPrivates[XF86XvScreenIndex].ptr; - XF86XVScreenPtr ScreenPriv = (XF86XVScreenPtr)pxvs->devPriv.ptr; + XF86XVScreenPtr ScreenPriv = GET_XF86XV_SCREEN(pScreen); Bool ret; ret = (*ScreenPriv->EnterVT)(index, flags); @@ -1116,9 +1157,8 @@ xf86XVLeaveVT(int index, int flags) { ScreenPtr pScreen = screenInfo.screens[index]; - XvScreenPtr pxvs = - (XvScreenPtr) pScreen->devPrivates[XF86XvScreenIndex].ptr; - XF86XVScreenPtr ScreenPriv = (XF86XVScreenPtr)pxvs->devPriv.ptr; + XvScreenPtr pxvs = GET_XV_SCREEN(pScreen); + XF86XVScreenPtr ScreenPriv = GET_XF86XV_SCREEN(pScreen); XvAdaptorPtr pAdaptor; XvPortPtr pPort; XvPortRecPrivatePtr pPriv; @@ -1154,8 +1194,8 @@ { ScrnInfoPtr pScrn = xf86Screens[index]; ScreenPtr pScreen = pScrn->pScreen; - XvScreenPtr pxvs = (XvScreenPtr)pScreen->devPrivates[XF86XvScreenIndex].ptr; - XF86XVScreenPtr ScreenPriv = (XF86XVScreenPtr)pxvs->devPriv.ptr; + XvScreenPtr pxvs = GET_XV_SCREEN(pScreen); + XF86XVScreenPtr ScreenPriv = GET_XF86XV_SCREEN(pScreen); WindowPtr pWin; XvAdaptorPtr pa; int c, i; diff -ur -x Makefile xc/programs/Xserver/hw/xfree86/common/xf86xv.h my/programs/Xserver/hw/xfree86/common/xf86xv.h --- xc/programs/Xserver/hw/xfree86/common/xf86xv.h Sat Mar 11 11:02:52 2000 +++ my/programs/Xserver/hw/xfree86/common/xf86xv.h Mon Mar 13 20:30:56 2000 @@ -166,7 +166,7 @@ int num ); -typedef int (* xf86XVInitGenericAdaptorPtr)(ScrnInfoPtr pScrn, +typedef int (* xf86XVInitGenericAdaptorPtr)(ScreenPtr pScreen, XF86VideoAdaptorPtr **Adaptors); int @@ -176,7 +176,7 @@ int xf86XVListGenericAdaptors( - ScrnInfoPtr pScrn, + ScreenPtr pScreen, XF86VideoAdaptorPtr **Adaptors ); @@ -201,6 +201,7 @@ CreateWindowProcPtr CreateWindow; DestroyWindowProcPtr DestroyWindow; ClipNotifyProcPtr ClipNotify; + WindowExposuresProcPtr WindowExposures; void (*AdjustFrame)(int, int, int, int); Bool (*EnterVT)(int, int); void (*LeaveVT)(int, int); diff -ur -x Makefile xc/programs/Xserver/hw/xfree86/drivers/apm/apm_video.c my/programs/Xserver/hw/xfree86/drivers/apm/apm_video.c --- xc/programs/Xserver/hw/xfree86/drivers/apm/apm_video.c Thu Mar 9 20:09:43 2000 +++ my/programs/Xserver/hw/xfree86/drivers/apm/apm_video.c Tue Mar 7 08:18:18 2000 @@ -49,7 +49,7 @@ int num_adaptors; Bool freeAdaptors = FALSE; - num_adaptors = xf86XVListGenericAdaptors(pScrn, &adaptors); + num_adaptors = xf86XVListGenericAdaptors(pScreen, &adaptors); if (pApm->Chipset >= AT24) { if ((newAdaptor = A(SetupImageVideo)(pScreen))) { diff -ur -x Makefile xc/programs/Xserver/hw/xfree86/drivers/cirrus/alp_driver.c my/programs/Xserver/hw/xfree86/drivers/cirrus/alp_driver.c --- xc/programs/Xserver/hw/xfree86/drivers/cirrus/alp_driver.c Thu Mar 9 20:09:46 2000 +++ my/programs/Xserver/hw/xfree86/drivers/cirrus/alp_driver.c Tue Mar 7 08:18:18 2000 @@ -1629,7 +1629,7 @@ XF86VideoAdaptorPtr *ptr; int n; - n = xf86XVListGenericAdaptors(pScrn,&ptr); + n = xf86XVListGenericAdaptors(pScreen,&ptr); if (n) xf86XVScreenInit(pScreen, ptr, n); } diff -ur -x Makefile xc/programs/Xserver/hw/xfree86/drivers/cirrus/lg_driver.c my/programs/Xserver/hw/xfree86/drivers/cirrus/lg_driver.c --- xc/programs/Xserver/hw/xfree86/drivers/cirrus/lg_driver.c Thu Mar 9 20:09:46 2000 +++ my/programs/Xserver/hw/xfree86/drivers/cirrus/lg_driver.c Tue Mar 7 08:18:18 2000 @@ -1546,7 +1546,7 @@ XF86VideoAdaptorPtr *ptr; int n; - n = xf86XVListGenericAdaptors(pScrn,&ptr); + n = xf86XVListGenericAdaptors(pScreen,&ptr); if (n) xf86XVScreenInit(pScreen, ptr, n); } diff -ur -x Makefile xc/programs/Xserver/hw/xfree86/drivers/fbdev/fbdev.c my/programs/Xserver/hw/xfree86/drivers/fbdev/fbdev.c --- xc/programs/Xserver/hw/xfree86/drivers/fbdev/fbdev.c Thu Mar 9 20:09:53 2000 +++ my/programs/Xserver/hw/xfree86/drivers/fbdev/fbdev.c Tue Mar 7 08:18:18 2000 @@ -754,7 +754,7 @@ { XF86VideoAdaptorPtr *ptr; - int n = xf86XVListGenericAdaptors(pScrn,&ptr); + int n = xf86XVListGenericAdaptors(pScreen,&ptr); if (n) { xf86XVScreenInit(pScreen,ptr,n); } diff -ur -x Makefile xc/programs/Xserver/hw/xfree86/drivers/i740/i740_driver.c my/programs/Xserver/hw/xfree86/drivers/i740/i740_driver.c --- xc/programs/Xserver/hw/xfree86/drivers/i740/i740_driver.c Thu Mar 9 20:09:42 2000 +++ my/programs/Xserver/hw/xfree86/drivers/i740/i740_driver.c Tue Mar 7 20:22:30 2000 @@ -1563,7 +1563,7 @@ XF86VideoAdaptorPtr *ptr; int n; - n = xf86XVListGenericAdaptors(pScrn,&ptr); + n = xf86XVListGenericAdaptors(pScreen,&ptr); if (n) { xf86XVScreenInit(pScreen, ptr, n); } diff -ur -x Makefile xc/programs/Xserver/hw/xfree86/drivers/i810/i810_driver.c my/programs/Xserver/hw/xfree86/drivers/i810/i810_driver.c --- xc/programs/Xserver/hw/xfree86/drivers/i810/i810_driver.c Thu Mar 9 20:09:46 2000 +++ my/programs/Xserver/hw/xfree86/drivers/i810/i810_driver.c Tue Mar 7 08:18:18 2000 @@ -1723,7 +1723,7 @@ XF86VideoAdaptorPtr *ptr; int n; - n = xf86XVListGenericAdaptors(pScrn, &ptr); + n = xf86XVListGenericAdaptors(pScreen, &ptr); if (n) { xf86XVScreenInit(pScreen, ptr, n); } diff -ur -x Makefile xc/programs/Xserver/hw/xfree86/drivers/mga/mga_video.c my/programs/Xserver/hw/xfree86/drivers/mga/mga_video.c --- xc/programs/Xserver/hw/xfree86/drivers/mga/mga_video.c Sat Mar 11 11:02:53 2000 +++ my/programs/Xserver/hw/xfree86/drivers/mga/mga_video.c Sat Mar 11 15:02:57 2000 @@ -70,7 +70,7 @@ MGAInitOffscreenImages(pScreen); } - num_adaptors = xf86XVListGenericAdaptors(pScrn, &adaptors); + num_adaptors = xf86XVListGenericAdaptors(pScreen, &adaptors); if(newAdaptor) { if(!num_adaptors) { @@ -1051,6 +1051,7 @@ offscreenImages[1].attributes = AttributesG; } + xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 2, "xf86XVRegisterOffscreenImages(num=%d)\n",num); xf86XVRegisterOffscreenImages(pScreen, offscreenImages, num); } diff -ur -x Makefile xc/programs/Xserver/hw/xfree86/drivers/nv/nv_driver.c my/programs/Xserver/hw/xfree86/drivers/nv/nv_driver.c --- xc/programs/Xserver/hw/xfree86/drivers/nv/nv_driver.c Thu Mar 9 20:09:42 2000 +++ my/programs/Xserver/hw/xfree86/drivers/nv/nv_driver.c Tue Mar 7 20:22:30 2000 @@ -1684,7 +1684,7 @@ XF86VideoAdaptorPtr *ptr; int n; - n = xf86XVListGenericAdaptors(pScrn,&ptr); + n = xf86XVListGenericAdaptors(pScreen,&ptr); if (n) { xf86XVScreenInit(pScreen, ptr, n); } diff -ur -x Makefile xc/programs/Xserver/hw/xfree86/drivers/r128/r128_driver.c my/programs/Xserver/hw/xfree86/drivers/r128/r128_driver.c --- xc/programs/Xserver/hw/xfree86/drivers/r128/r128_driver.c Thu Mar 9 20:09:43 2000 +++ my/programs/Xserver/hw/xfree86/drivers/r128/r128_driver.c Tue Mar 7 20:22:30 2000 @@ -1437,7 +1437,7 @@ XF86VideoAdaptorPtr *ptr; int n; - if ((n = xf86XVListGenericAdaptors(pScrn, &ptr))) + if ((n = xf86XVListGenericAdaptors(pScreen, &ptr))) xf86XVScreenInit(pScreen, ptr, n); } #endif diff -ur -x Makefile xc/programs/Xserver/hw/xfree86/drivers/s3virge/s3v_driver.c my/programs/Xserver/hw/xfree86/drivers/s3virge/s3v_driver.c --- xc/programs/Xserver/hw/xfree86/drivers/s3virge/s3v_driver.c Thu Mar 9 20:09:53 2000 +++ my/programs/Xserver/hw/xfree86/drivers/s3virge/s3v_driver.c Tue Mar 7 20:22:31 2000 @@ -2450,7 +2450,7 @@ XF86VideoAdaptorPtr *ptr; int n; - n = xf86XVListGenericAdaptors(pScrn,&ptr); + n = xf86XVListGenericAdaptors(pScreen,&ptr); if (n) { xf86XVScreenInit(pScreen, ptr, n); } diff -ur -x Makefile xc/programs/Xserver/hw/xfree86/drivers/tdfx/tdfx_driver.c my/programs/Xserver/hw/xfree86/drivers/tdfx/tdfx_driver.c --- xc/programs/Xserver/hw/xfree86/drivers/tdfx/tdfx_driver.c Thu Mar 9 20:09:43 2000 +++ my/programs/Xserver/hw/xfree86/drivers/tdfx/tdfx_driver.c Tue Mar 7 20:22:31 2000 @@ -1750,7 +1750,7 @@ XF86VideoAdaptorPtr *ptr; int n; - n = xf86XVListGenericAdaptors(pScrn,&ptr); + n = xf86XVListGenericAdaptors(pScreen,&ptr); if (n) { xf86XVScreenInit(pScreen, ptr, n); } diff -ur -x Makefile xc/programs/Xserver/hw/xfree86/drivers/tga/tga_driver.c my/programs/Xserver/hw/xfree86/drivers/tga/tga_driver.c --- xc/programs/Xserver/hw/xfree86/drivers/tga/tga_driver.c Thu Mar 9 20:09:52 2000 +++ my/programs/Xserver/hw/xfree86/drivers/tga/tga_driver.c Tue Mar 7 20:22:31 2000 @@ -1284,7 +1284,7 @@ pScrn->memPhysBase = pTga->FbAddress; pScrn->fbOffset = 0; - n = xf86XVListGenericAdaptors(pScrn,&ptr); + n = xf86XVListGenericAdaptors(pScreen,&ptr); if(n) { xf86XVScreenInit(pScreen, ptr, n); diff -ur -x Makefile xc/programs/Xserver/hw/xfree86/drivers/trident/trident_driver.c my/programs/Xserver/hw/xfree86/drivers/trident/trident_driver.c --- xc/programs/Xserver/hw/xfree86/drivers/trident/trident_driver.c Thu Mar 9 20:09:49 2000 +++ my/programs/Xserver/hw/xfree86/drivers/trident/trident_driver.c Tue Mar 7 20:22:31 2000 @@ -2352,7 +2352,7 @@ XF86VideoAdaptorPtr *ptr; int n; - n = xf86XVListGenericAdaptors(pScrn,&ptr); + n = xf86XVListGenericAdaptors(pScreen,&ptr); if (n) { xf86XVScreenInit(pScreen, ptr, n); } diff -ur -x Makefile xc/programs/Xserver/hw/xfree86/drivers/v4l/v4l.c my/programs/Xserver/hw/xfree86/drivers/v4l/v4l.c --- xc/programs/Xserver/hw/xfree86/drivers/v4l/v4l.c Thu Mar 9 20:09:53 2000 +++ my/programs/Xserver/hw/xfree86/drivers/v4l/v4l.c Sat Mar 18 13:21:39 2000 @@ -2,7 +2,7 @@ * video4linux Xv Driver * based on Michael Schimek's permedia 2 driver. */ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/v4l/v4l.c,v 1.16 2000/02/22 02:00:54 mvojkovi Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/v4l/v4l.c,v 1.15 2000/01/30 01:15:57 alanh Exp $ */ #include "videodev.h" #include "xf86.h" @@ -25,7 +25,11 @@ /* XXX Lots of xalloc() calls don't check for failure. */ -#define DEBUG(x) (x) +#if 0 +# define DEBUG(x) (x) +#else +# define DEBUG(x) +#endif static void V4LIdentify(int flags); static Bool V4LProbe(DriverPtr drv, int flags); @@ -100,20 +104,27 @@ #endif +#define VIDEO_OFF 0 /* really off */ +#define VIDEO_RGB 1 /* rgb overlay (directly to fb) */ +#define VIDEO_YUV 2 /* yuv overlay (to offscreen memory + hw scaling) */ +#define VIDEO_RECLIP 3 /* temporarly off, window clipping changes */ + typedef struct _PortPrivRec { ScrnInfoPtr pScrn; FBAreaPtr pFBArea[2]; - int VideoOn; /* yes/no */ + int VideoOn; Bool StreamOn; /* file handle */ int fd; char devname[16]; int useCount; + struct video_capability cap; - /* overlay */ - struct video_buffer ov_fbuf; - struct video_window ov_win; + /* RGB overlay */ + struct video_buffer rgb_fbuf; + struct video_window rgb_win; + int rgbpalette; /* attributes */ struct video_picture pict; @@ -121,6 +132,17 @@ XF86VideoEncodingPtr enc; int nenc,cenc; + + /* yuv to offscreen */ + XF86OffscreenImagePtr format; /* list */ + int nformat; /* # if list entries */ + XF86OffscreenImagePtr myfmt; /* which one is YUY2 (packed) */ + int have_yuv; + + int yuv_width,yuv_height; + XF86SurfacePtr surface; + struct video_buffer yuv_fbuf; + struct video_window yuv_win; } PortPrivRec, *PortPrivPtr; #define XV_ENCODING "XV_ENCODING" @@ -143,8 +165,23 @@ { 15, TrueColor }, { 16, TrueColor }, { 24, TrueColor }, + { 32, TrueColor }, }; +#define V4L_ATTR 8 + +static XF86AttributeRec Attributes[V4L_ATTR] = { + {XvSettable | XvGettable, -1000, 1000, XV_ENCODING}, + {XvSettable | XvGettable, -1000, 1000, XV_BRIGHTNESS}, + {XvSettable | XvGettable, -1000, 1000, XV_CONTRAST}, + {XvSettable | XvGettable, -1000, 1000, XV_SATURATION}, + {XvSettable | XvGettable, -1000, 1000, XV_HUE}, + {XvSettable | XvGettable, -1000, 1000, XV_VOLUME}, + {XvSettable | XvGettable, 0, 1, XV_MUTE}, + {XvSettable | XvGettable, 0, 16*1000, XV_FREQ}, +}; + + /* ---------------------------------------------------------------------- */ /* forward decl */ @@ -172,14 +209,26 @@ if (pPPriv->fd == -1) { pPPriv->fd = open(pPPriv->devname, O_RDWR, 0); - pPPriv->ov_fbuf.width = pScrn->virtualX; - pPPriv->ov_fbuf.height = pScrn->virtualY; - pPPriv->ov_fbuf.depth = pScrn->bitsPerPixel; - pPPriv->ov_fbuf.bytesperline = pScrn->displayWidth * ((pScrn->bitsPerPixel + 7)/8); - pPPriv->ov_fbuf.base = (pointer)(pScrn->memPhysBase + pScrn->fbOffset); + pPPriv->rgb_fbuf.width = pScrn->virtualX; + pPPriv->rgb_fbuf.height = pScrn->virtualY; + pPPriv->rgb_fbuf.depth = pScrn->bitsPerPixel; + pPPriv->rgb_fbuf.bytesperline = pScrn->displayWidth * ((pScrn->bitsPerPixel + 7)/8); + pPPriv->rgb_fbuf.base = (pointer)(pScrn->memPhysBase + pScrn->fbOffset); - if (-1 == ioctl(pPPriv->fd,VIDIOCSFBUF,&(pPPriv->ov_fbuf))) - perror("ioctl VIDIOCSFBUF"); + switch (pScrn->bitsPerPixel) { + case 16: + if (pScrn->weight.green == 5) + pPPriv->rgbpalette = VIDEO_PALETTE_RGB555; + else + pPPriv->rgbpalette = VIDEO_PALETTE_RGB565; + break; + case 24: + pPPriv->rgbpalette = VIDEO_PALETTE_RGB24; + break; + case 32: + pPPriv->rgbpalette = VIDEO_PALETTE_RGB32; + break; + } } if (pPPriv->fd == -1) @@ -200,7 +249,6 @@ } } - static int V4lPutVideo(ScrnInfoPtr pScrn, short vid_x, short vid_y, short drw_x, short drw_y, @@ -210,13 +258,133 @@ PortPrivPtr pPPriv = (PortPrivPtr) data; struct video_clip *clip; BoxPtr pBox; + RegionRec newReg; + BoxRec newBox; unsigned int i,dx,dy,dw,dh; + int width,height; int one=1; - DEBUG(xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 2, "Xv/PV\n")); + /* Open a file handle to the device */ + if (VIDEO_OFF == pPPriv->VideoOn) { + if (V4lOpenDevice(pPPriv, pScrn)) + return BadAccess; + } + + if (pPPriv->have_yuv) { + DEBUG(xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 2, "Xv/PV yuv\n")); + width = pPPriv->enc[pPPriv->cenc].width; + height = pPPriv->enc[pPPriv->cenc].height/2; /* no interlace */ + if (drw_w < width) + width = drw_w; + if (drw_h < height) + height = drw_h; + if ((height != pPPriv->yuv_height) || (width != pPPriv->yuv_width)) { + /* new size -- free old surface */ + DEBUG(xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 2, " surface resize\n")); + if (pPPriv->surface) { + pPPriv->VideoOn = VIDEO_OFF; + pPPriv->myfmt->stop(pPPriv->surface); + pPPriv->myfmt->free_surface(pPPriv->surface); + xfree(pPPriv->surface); + pPPriv->surface = NULL; + } + pPPriv->yuv_width = width; + pPPriv->yuv_height = height; + } + if (!pPPriv->surface) { + /* allocate + setup offscreen surface */ + if (NULL == (pPPriv->surface = xalloc(sizeof(XF86SurfaceRec)))) + return FALSE; + if (Success != pPPriv->myfmt->alloc_surface + (pScrn,pPPriv->myfmt->image->id, + pPPriv->yuv_width,pPPriv->yuv_height,pPPriv->surface)) { + xfree(pPPriv->surface); + pPPriv->surface = NULL; + goto fallback_to_rgb; + } + pPPriv->yuv_fbuf.width = pPPriv->surface->width; + pPPriv->yuv_fbuf.height = pPPriv->surface->height; + pPPriv->yuv_fbuf.depth = 16; + pPPriv->yuv_fbuf.bytesperline = pPPriv->surface->pitches[0]; + pPPriv->yuv_fbuf.base = + (pointer)(pScrn->memPhysBase + pPPriv->surface->offsets[0]); + DEBUG(xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 2, " surface: %p+%d = %p, %dx%d, pitch %d\n", + pScrn->memPhysBase,pPPriv->surface->offsets[0], + pScrn->memPhysBase+pPPriv->surface->offsets[0], + pPPriv->surface->width,pPPriv->surface->height, + pPPriv->surface->pitches[0])); + pPPriv->yuv_win.width = pPPriv->surface->width; + pPPriv->yuv_win.height = pPPriv->surface->height; + } + + /* program driver */ + if (VIDEO_YUV != pPPriv->VideoOn) { + if (-1 == ioctl(pPPriv->fd,VIDIOCSFBUF,&(pPPriv->yuv_fbuf))) + perror("ioctl VIDIOCSFBUF"); + if (-1 == ioctl(pPPriv->fd,VIDIOCGPICT,&pPPriv->pict)) + perror("ioctl VIDIOCGPICT"); + pPPriv->pict.palette = VIDEO_PALETTE_YUV422; + if (-1 == ioctl(pPPriv->fd,VIDIOCSPICT,&pPPriv->pict)) + perror("ioctl VIDIOCSPICT"); + if (-1 == ioctl(pPPriv->fd,VIDIOCSWIN,&(pPPriv->yuv_win))) + perror("ioctl VIDIOCSWIN"); + if (-1 == ioctl(pPPriv->fd, VIDIOCCAPTURE, &one)) + perror("ioctl VIDIOCCAPTURE(1)"); + } + + if (0 == (pPPriv->myfmt->flags & VIDEO_INVERT_CLIPLIST)) { + /* invert cliplist */ + newBox.x1 = drw_x; + newBox.y1 = drw_y; + newBox.x2 = drw_x + drw_w; + newBox.y2 = drw_y + drw_h; + + if (pPPriv->myfmt->flags & VIDEO_CLIP_TO_VIEWPORT) { + /* trim to the viewport */ + if(newBox.x1 < pScrn->frameX0) + newBox.x1 = pScrn->frameX0; + if(newBox.x2 > pScrn->frameX1) + newBox.x2 = pScrn->frameX1; + + if(newBox.y1 < pScrn->frameY0) + newBox.y1 = pScrn->frameY0; + if(newBox.y2 > pScrn->frameY1) + newBox.y2 = pScrn->frameY1; + } + + REGION_INIT(pScrn->pScreen, &newReg, &newBox, 1); + REGION_SUBTRACT(pScrn->pScreen, &newReg, &newReg, clipBoxes); + clipBoxes = &newReg; + } + + /* start overlay */ + DEBUG(xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 2, + "over: - %d,%d -> %d,%d (%dx%d) (yuv=%dx%d)\n", + drw_x, drw_y, + drw_x+drw_w, drw_y+drw_h, + drw_w, drw_h, + pPPriv->surface->width,pPPriv->surface->height)); + pPPriv->myfmt->display(pPPriv->surface, + 0, 0, drw_x, drw_y, + pPPriv->surface->width, + pPPriv->surface->height, + drw_w, drw_h, + clipBoxes); + if (0 == (pPPriv->myfmt->flags & VIDEO_INVERT_CLIPLIST)) { + REGION_UNINIT(pScrn->pScreen, &newReg); + } + pPPriv->VideoOn = VIDEO_YUV; + return Success; + } + + fallback_to_rgb: + DEBUG(xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 2, "Xv/PV rgb\n")); /* FIXME: vid-* is ignored for now, not supported by v4l */ - V4lQueryBestSize(pScrn, 0, vid_w, vid_h, drw_w, drw_h, &dw, &dh, data); + dw = (drw_w < pPPriv->enc[pPPriv->cenc].width) ? + drw_w : pPPriv->enc[pPPriv->cenc].width; + dh = (drw_h < pPPriv->enc[pPPriv->cenc].height) ? + drw_h : pPPriv->enc[pPPriv->cenc].height; /* if the window is too big, center the video */ dx = drw_x + (drw_w - dw)/2; dy = drw_y + (drw_h - dh)/2; @@ -230,25 +398,25 @@ drw_w,drw_h,drw_x,drw_y)); DEBUG(xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 2, " use: %dx%d+%d+%d\n", dw,dh,dx,dy)); - pPPriv->ov_win.x = dx; - pPPriv->ov_win.y = dy; - pPPriv->ov_win.width = dw; - pPPriv->ov_win.height = dh; - pPPriv->ov_win.flags = 0; + pPPriv->rgb_win.x = dx; + pPPriv->rgb_win.y = dy; + pPPriv->rgb_win.width = dw; + pPPriv->rgb_win.height = dh; + pPPriv->rgb_win.flags = 0; /* clipping */ - if (pPPriv->ov_win.clips) { - xfree(pPPriv->ov_win.clips); - pPPriv->ov_win.clips = NULL; + if (pPPriv->rgb_win.clips) { + xfree(pPPriv->rgb_win.clips); + pPPriv->rgb_win.clips = NULL; } - pPPriv->ov_win.clipcount = REGION_NUM_RECTS(clipBoxes); + pPPriv->rgb_win.clipcount = REGION_NUM_RECTS(clipBoxes); DEBUG(xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 2," clip: have #%d\n", - pPPriv->ov_win.clipcount)); - if (0 != pPPriv->ov_win.clipcount) { - pPPriv->ov_win.clips = xalloc(pPPriv->ov_win.clipcount*sizeof(struct video_clip)); - memset(pPPriv->ov_win.clips,0,pPPriv->ov_win.clipcount*sizeof(struct video_clip)); + pPPriv->rgb_win.clipcount)); + if (0 != pPPriv->rgb_win.clipcount) { + pPPriv->rgb_win.clips = xalloc(pPPriv->rgb_win.clipcount*sizeof(struct video_clip)); + memset(pPPriv->rgb_win.clips,0,pPPriv->rgb_win.clipcount*sizeof(struct video_clip)); pBox = REGION_RECTS(clipBoxes); - clip = pPPriv->ov_win.clips; + clip = pPPriv->rgb_win.clips; for (i = 0; i < REGION_NUM_RECTS(clipBoxes); i++, pBox++, clip++) { clip->x = pBox->x1 - dx; clip->y = pBox->y1 - dy; @@ -257,20 +425,21 @@ } } - /* Open a file handle to the device */ - - if (!pPPriv->VideoOn) { - if (V4lOpenDevice(pPPriv, pScrn)) - return BadAccess; - pPPriv->VideoOn = 1; - } - /* start */ - - if (-1 == ioctl(pPPriv->fd,VIDIOCSWIN,&(pPPriv->ov_win))) + if (VIDEO_RGB != pPPriv->VideoOn) { + if (-1 == ioctl(pPPriv->fd,VIDIOCSFBUF,&(pPPriv->rgb_fbuf))) + perror("ioctl VIDIOCSFBUF"); + if (-1 == ioctl(pPPriv->fd,VIDIOCGPICT,&pPPriv->pict)) + perror("ioctl VIDIOCGPICT"); + pPPriv->pict.palette = pPPriv->rgbpalette; + if (-1 == ioctl(pPPriv->fd,VIDIOCSPICT,&pPPriv->pict)) + perror("ioctl VIDIOCSPICT"); + } + if (-1 == ioctl(pPPriv->fd,VIDIOCSWIN,&(pPPriv->rgb_win))) perror("ioctl VIDIOCSWIN"); if (-1 == ioctl(pPPriv->fd, VIDIOCCAPTURE, &one)) perror("ioctl VIDIOCCAPTURE(1)"); + pPPriv->VideoOn = VIDEO_RGB; return Success; } @@ -295,18 +464,34 @@ PortPrivPtr pPPriv = (PortPrivPtr) data; int zero=0; - if (!pPPriv->VideoOn) { + if (VIDEO_OFF == pPPriv->VideoOn) { DEBUG(xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 2, "Xv/StopVideo called with video already off\n")); return; } - DEBUG(xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 2, "Xv/StopVideo\n")); + DEBUG(xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 2, "Xv/StopVideo exit=%d\n",exit)); - if (-1 == ioctl(pPPriv->fd, VIDIOCCAPTURE, &zero)) - perror("ioctl VIDIOCCAPTURE(0)"); - - V4lCloseDevice(pPPriv); - pPPriv->VideoOn = 0; + if (!exit) { + /* just reclipping, we have to stop DMA transfers to the visible screen */ + if (VIDEO_RGB == pPPriv->VideoOn) { + if (-1 == ioctl(pPPriv->fd, VIDIOCCAPTURE, &zero)) + perror("ioctl VIDIOCCAPTURE(0)"); + pPPriv->VideoOn = VIDEO_RECLIP; + } + } else { + /* video stop - turn off and free everything */ + if (VIDEO_YUV == pPPriv->VideoOn) { + pPPriv->myfmt->stop(pPPriv->surface); + pPPriv->myfmt->free_surface(pPPriv->surface); + xfree(pPPriv->surface); + pPPriv->surface = NULL; + } + if (-1 == ioctl(pPPriv->fd, VIDIOCCAPTURE, &zero)) + perror("ioctl VIDIOCCAPTURE(0)"); + + V4lCloseDevice(pPPriv); + pPPriv->VideoOn = VIDEO_OFF; + } } /* v4l uses range 0 - 65535; Xv uses -1000 - 1000 */ @@ -333,12 +518,12 @@ struct video_channel chan; int ret = Success; - DEBUG(xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 2, "Xv/SPA %d, %d\n", - attribute, value)); - if (V4lOpenDevice(pPPriv, pScrn)) return BadAccess; + DEBUG(xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 2, "Xv/SPA %d, %d\n", + attribute, value)); + if (-1 == pPPriv->fd) { ret = Success /* FIXME: EBUSY/ENODEV ?? */; } else if (attribute == xvEncoding) { @@ -381,6 +566,12 @@ } else if (attribute == xvFreq) { if (-1 == ioctl(pPPriv->fd,VIDIOCSFREQ,&value)) perror("ioctl VIDIOCSFREQ"); +#if 0 + } else if (pPPriv->have_yuv && + pPPriv->myfmt->setAttribute) { + /* not mine -> pass to yuv scaler driver */ + ret = pPPriv->myfmt->setAttribute(pScrn, attribute, value); +#endif } else { ret = BadValue; } @@ -424,6 +615,12 @@ } } else if (attribute == xvFreq) { ioctl(pPPriv->fd,VIDIOCGFREQ,value); +#if 0 + } else if (pPPriv->have_yuv && + pPPriv->myfmt->getAttribute) { + /* not mine -> pass to yuv scaler driver */ + ret = pPPriv->myfmt->getAttribute(pScrn, attribute, value); +#endif } else { ret = BadValue; } @@ -444,8 +641,13 @@ int maxx = pPPriv->enc[pPPriv->cenc].width; int maxy = pPPriv->enc[pPPriv->cenc].height; - *p_w = (drw_w < maxx) ? drw_w : maxx; - *p_h = (drw_h < maxy) ? drw_h : maxy; + if (pPPriv->have_yuv) { + *p_w = pPPriv->myfmt->max_width; + *p_h = pPPriv->myfmt->max_height; + } else { + *p_w = (drw_w < maxx) ? drw_w : maxx; + *p_h = (drw_h < maxy) ? drw_h : maxy; + } DEBUG(xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 2, "Xv/BS %d %dx%d %dx%d\n", pPPriv->cenc,drw_w,drw_h,*p_w,*p_h)); @@ -467,32 +669,28 @@ static char* fixname(char *str) { - int s,d; - for (s=0, d=0;; s++) { - if (str[s] == '-') - continue; - str[d++] = tolower(str[s]); - if (0 == str[s]) - break; - } - return str; + int s,d; + for (s=0, d=0;; s++) { + if (str[s] == '-') + continue; + str[d++] = tolower(str[s]); + if (0 == str[s]) + break; + } + return str; } static XF86VideoEncodingPtr -V4LBuildEncodings(int fd, int *count) +V4LBuildEncodings(int fd, int *count, int channels) { - static struct video_capability cap; static struct video_channel channel; XF86VideoEncodingPtr enc; int i; - if (-1 == ioctl(fd,VIDIOCGCAP,&cap)) - return NULL; - - enc = xalloc(sizeof(XF86VideoEncodingRec)*3*cap.channels); - memset(enc,0,sizeof(XF86VideoEncodingRec)*3*cap.channels); + enc = xalloc(sizeof(XF86VideoEncodingRec)*3*channels); + memset(enc,0,sizeof(XF86VideoEncodingRec)*3*channels); - for (i = 0; i < 3*cap.channels; ) { + for (i = 0; i < 3*channels; ) { channel.channel = i/3; if (-1 == ioctl(fd,VIDIOCGCHAN,&channel)) { perror("ioctl VIDIOCGCHAN"); @@ -533,28 +731,15 @@ return enc; } - -static XF86AttributeRec Attributes[8] = { - {XvSettable | XvGettable, -1000, 1000, XV_ENCODING}, - {XvSettable | XvGettable, -1000, 1000, XV_BRIGHTNESS}, - {XvSettable | XvGettable, -1000, 1000, XV_CONTRAST}, - {XvSettable | XvGettable, -1000, 1000, XV_SATURATION}, - {XvSettable | XvGettable, -1000, 1000, XV_HUE}, - {XvSettable | XvGettable, -1000, 1000, XV_VOLUME}, - {XvSettable | XvGettable, 0, 1, XV_MUTE}, - {XvSettable | XvGettable, 0, 16*1000, XV_FREQ}, -}; - - static int -V4LInit(ScrnInfoPtr pScrn, XF86VideoAdaptorPtr **adaptors) +V4LInit(ScreenPtr pScreen, XF86VideoAdaptorPtr **adaptors) { PortPrivPtr pPPriv; DevUnion *Private; XF86VideoAdaptorPtr *VAR = NULL; XF86VideoEncodingPtr enc; char dev[16]; - int fd,i,nenc; + int fd,i,j,nenc; DEBUG(xf86Msg(X_INFO, "v4l: init start\n")); @@ -563,8 +748,6 @@ fd = open(dev, O_RDWR, 0); if (fd == -1) break; - if (NULL == (enc = V4LBuildEncodings(fd,&nenc))) - break; DEBUG(xf86Msg(X_INFO, "v4l: %s ok\n",dev)); @@ -576,9 +759,44 @@ pPPriv->fd = -1; strncpy(pPPriv->devname, dev, 16); pPPriv->useCount=0; + + /* check device */ + if (-1 == ioctl(fd,VIDIOCGCAP,&pPPriv->cap) || + NULL == (enc = V4LBuildEncodings + (fd,&nenc,pPPriv->cap.channels))) { + xfree(pPPriv); + break; + } pPPriv->enc = enc; pPPriv->nenc = nenc; +#if 1 + /* check for yuv (see if the driver accepts VIDEO_PALETTE_YUV422) */ + ioctl(fd,VIDIOCGPICT,&pPPriv->pict); + pPPriv->pict.palette = VIDEO_PALETTE_YUV422; + if (0 == ioctl(fd,VIDIOCSPICT,&pPPriv->pict)) { + ioctl(fd,VIDIOCGPICT,&pPPriv->pict); + if (VIDEO_PALETTE_YUV422 == pPPriv->pict.palette) { + /* works, check screen capabilities */ + DEBUG(xf86Msg(X_INFO, "v4l: kernel driver supports yuv422.\n")); + pPPriv->format = xf86XVQueryOffscreenImages + (pScreen,&pPPriv->nformat); + DEBUG(xf86Msg(X_INFO, "v4l: screen driver supports %d yuv formats (%p)\n", + pPPriv->nformat,pPPriv->format)); + for (j = 0; j < pPPriv->nformat; j++) { + DEBUG(xf86Msg(X_INFO, "v4l: yuv format: %4.4s\n", + (char*)&(pPPriv->format[j].image->id))); + if (pPPriv->format[j].image->id == 0x32595559 && + pPPriv->format[j].image->format == XvPacked) { + pPPriv->have_yuv = 1; + pPPriv->myfmt = pPPriv->format+j; + DEBUG(xf86Msg(X_INFO, "v4l: matching format found, offscreen yuv enabled.\n")); + } + } + } + } +#endif + /* alloc VideoAdaptorRec */ VAR = xrealloc(VAR,sizeof(XF86VideoAdaptorPtr)*(i+1)); VAR[i] = xalloc(sizeof(XF86VideoAdaptorRec)); @@ -587,8 +805,23 @@ memset(VAR[i],0,sizeof(XF86VideoAdaptorRec)); /* add attribute lists */ - VAR[i]->nAttributes = 8; - VAR[i]->pAttributes = Attributes; + if (pPPriv->have_yuv) { +#if 0 + VAR[i]->nAttributes = V4L_ATTR + pPPriv->myfmt->num_attributes; + VAR[i]->pAttributes = xalloc(VAR[i]->nAttributes * + sizeof(XF86AttributeRec)); + memcpy(VAR[i]->pAttributes, Attributes, + sizeof(XF86AttributeRec) * V4L_ATTR); + memcpy(VAR[i]->pAttributes+V4L_ATTR, pPPriv->myfmt->attributes, + sizeof(XF86AttributeRec) * pPPriv->myfmt->num_attributes); +#else + VAR[i]->nAttributes = V4L_ATTR; + VAR[i]->pAttributes = Attributes; +#endif + } else { + VAR[i]->nAttributes = V4L_ATTR; + VAR[i]->pAttributes = Attributes; + } /* hook in private data */ Private = xalloc(sizeof(DevUnion)); @@ -640,8 +873,9 @@ V4LProbe(DriverPtr drv, int flags) { if (flags & PROBE_DETECT) - return FALSE; + return TRUE; xf86XVRegisterGenericAdaptorDriver(V4LInit); + drv->refCount++; return TRUE; } diff -ur -x Makefile xc/programs/Xserver/hw/xfree86/loader/xf86sym.c my/programs/Xserver/hw/xfree86/loader/xf86sym.c --- xc/programs/Xserver/hw/xfree86/loader/xf86sym.c Thu Mar 9 20:09:59 2000 +++ my/programs/Xserver/hw/xfree86/loader/xf86sym.c Thu Mar 9 19:26:03 2000 @@ -481,6 +481,7 @@ SYMFUNC(xf86XVRegisterGenericAdaptorDriver) SYMFUNC(xf86XVListGenericAdaptors) SYMFUNC(xf86XVRegisterOffscreenImages) + SYMFUNC(xf86XVQueryOffscreenImages) /* xf86VidMode.c */ SYMFUNC(VidModeExtensionInit)