--- XFree86-4.2.0/xc.orig/programs/Xserver/hw/xfree86/drivers/neomagic/Imakefile Wed Jan 24 01:06:21 2001 +++ XFree86-4.2.0/xc/programs/Xserver/hw/xfree86/drivers/neomagic/Imakefile Thu Apr 4 16:05:44 2002 @@ -2,12 +2,12 @@ #define IHaveModules #include SRCS = neo_driver.c neo_bank.c neo_cursor.c neo_2097.c neo_2070.c \ - neo_2090.c neo_2200.c neo_i2c.c neo_shadow.c neo_dga.c + neo_2090.c neo_2200.c neo_i2c.c neo_shadow.c neo_dga.c neo_video.c OBJS = neo_driver.o neo_bank.o neo_cursor.o neo_2097.o neo_2070.o \ - neo_2090.o neo_2200.o neo_i2c.o neo_shadow.o neo_dga.o + neo_2090.o neo_2200.o neo_i2c.o neo_shadow.o neo_dga.o neo_video.o DEFINES = -DPSZ=8 --- XFree86-4.2.0/xc.orig/programs/Xserver/hw/xfree86/drivers/neomagic/NM-reg.txt Thu Jan 1 01:00:00 1970 +++ XFree86-4.2.0/xc/programs/Xserver/hw/xfree86/drivers/neomagic/NM-reg.txt Thu Apr 4 16:05:44 2002 @@ -0,0 +1,69 @@ +NM2160 Register GUESS + --- Overlay and ZV capture --- + +2002,2.3. + +1. Overlay + GRB0 bit5 Format; 0:YUY2/1:RGB + bit1 1 + bit0 Enable overlay ; 1:enable/0:disable + GRB1 bit7:4 X2[11:8] + bit3:0 X1[11:8] + GRB2 X1[7:0] + GRB3 X2[7:0] + GRB4 bit7:4 Y2[11:8] + bit3:0 Y1[11:8] + GRB5 Y1[7:0] + GRB6 Y2[7:0] + GRB7 VRAM offset[24:17] + GRB8 VRAM offset[16:9] + GRB9 VRAM offset[8:1] + GRBA Width in byte[15:8] + GRBB Width in byte[7:0] + GRBC 0x4f + GRBD - + GRBE - + GRBF bit2 0:normal/1:mirror + bit1:0 b'10' + GRC0 X scale[15:8] ; x1.0 == 0x1000 + GRC1 X scale[7:0] + GRC2 Y scale[15:8] ; x1.0 == 0x1000 + GRC3 Y scale[7:0] + GRC4 brightness ; -128 to +127 + GRC5 Color key(R) + GRC6 Color key(G) / Color key(8bpp) + GRC7 Color key(B) + +2. ZV capture + GR0A bit5 Enable extended SR reg. ; 1:enable/0:disable + bit0 1 + + SR08 bit7:1 b'1010000' + bit0 Enable capture ; 1:enable/0:disable + SR09 0x11 + SR0A 0x00 + SR0B - + SR0C VRAM offset[8:1] + SR0D VRAM offset[16:9] + SR0E VRAM offset[24:17] + SR0F - + SR10 - + SR11 - + SR12 - + SR13 - + SR14 Y1[7:0] + SR15 Y2[7:0] + SR16 bit7:4 Y2[11:4] + bit3:0 Y1[11:4] + SR17 X1[7:0] + SR18 X2[7:0] + SR19 bit7:4 X2[11:8] + bit3:0 X1[11:8] + SR1A Width in byte[7:0] + SR1B Width in byte[15:8] + SR1C 0xfb + SR1D 0x00 + SR1E 0xe2 + SR1F 0x02 + +s.nomura@mba.nifty.ne.jp --- XFree86-4.2.0/xc.orig/programs/Xserver/hw/xfree86/drivers/neomagic/neo.h Mon Oct 1 15:44:07 2001 +++ XFree86-4.2.0/xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo.h Thu Apr 4 16:05:44 2002 @@ -60,6 +60,11 @@ #include "xf86i2c.h" +#ifdef XvExtension +# include "xf86xv.h" +# include "Xv.h" +#endif /* XvExtension */ + /* * Driver data structures. */ @@ -121,6 +126,10 @@ /* in neo_dga.c */ Bool NEODGAInit(ScreenPtr pScreen); +/* in neo_video.c */ +extern void NEOInitVideo(ScreenPtr pScreen); +extern void NEOResetVideo(ScrnInfoPtr pScrn); + /* shadow regs */ #define NEO_EXT_CR_MAX 0x85 @@ -199,6 +208,8 @@ unsigned long NeoMMIOAddr; unsigned long NeoLinearAddr; unsigned char* NeoMMIOBase; + unsigned long NeoMMIOAddr2; + unsigned char* NeoMMIOBase2; unsigned char* NeoFbBase; long NeoFbMapSize; unsigned long vgaIOBase; @@ -249,6 +260,17 @@ RefreshAreaFuncPtr refreshArea; void (*PointerMoved)(int index, int x, int y); int rotate; + Bool showcache; +#ifdef XvExtension + Bool video; + double videoHZoom; + double videoVZoom; + XF86VideoAdaptorPtr overlayAdaptor; + int overlay; + int overlay_offset; + int videoKey; + int interlace; +#endif /* XvExtension */ } NEORec, *NEOPtr; typedef struct { @@ -264,18 +286,20 @@ #define GRAX 0x3CE /* vga IO functions */ -#define VGArCR(index) hwp->readCrtc(hwp,index) -#define VGAwCR(index,val) hwp->writeCrtc(hwp,index,val) -#define VGArGR(index) hwp->readGr(hwp,index) -#define VGAwGR(index,val) hwp->writeGr(hwp,index,val) +#define VGArCR(index) (*hwp->readCrtc)(hwp, index) +#define VGAwCR(index, val) (*hwp->writeCrtc)(hwp, index, val) +#define VGArGR(index) (*hwp->readGr)(hwp, index) +#define VGAwGR(index, val) (*hwp->writeGr)(hwp, index, val) +#define VGArSR(index) (*hwp->readSeq)(hwp, index) +#define VGAwSR(index, val) (*hwp->writeSeq)(hwp, index, val) /* memory mapped register access macros */ -#define INREG8(addr) MMIO_IN8(nPtr->NeoMMIOBase, (addr)) -#define INREG16(addr) MMIO_IN16(nPtr->NeoMMIOBase, (addr)) -#define INREG(addr) MMIO_IN32(nPtr->NeoMMIOBase, (addr)) -#define OUTREG8(addr, val) MMIO_OUT8(nPtr->NeoMMIOBase, (addr), (val)) -#define OUTREG16(addr, val) MMIO_OUT16(nPtr->NeoMMIOBase, (addr), (val)) -#define OUTREG(addr, val) MMIO_OUT32(nPtr->NeoMMIOBase, (addr), (val)) +#define INREG8(addr) MMIO_IN8(nPtr->NeoMMIOBase, addr) +#define INREG16(addr) MMIO_IN16(nPtr->NeoMMIOBase, addr) +#define INREG(addr) MMIO_IN32(nPtr->NeoMMIOBase, addr) +#define OUTREG8(addr, val) MMIO_OUT8(nPtr->NeoMMIOBase, addr, val) +#define OUTREG16(addr, val) MMIO_OUT16(nPtr->NeoMMIOBase, addr, val) +#define OUTREG(addr, val) MMIO_OUT32(nPtr->NeoMMIOBase, addr, val) /* This swizzle macro is to support the manipulation of cursor masks when * the sprite moves off the left edge of the display. This code is --- XFree86-4.2.0/xc.orig/programs/Xserver/hw/xfree86/drivers/neomagic/neo_2070.c Tue Sep 26 01:57:08 2000 +++ XFree86-4.2.0/xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_2070.c Thu Apr 4 16:05:44 2002 @@ -104,8 +104,6 @@ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; NEOPtr nPtr = NEOPTR(pScrn); NEOACLPtr nAcl = NEOACLPTR(pScrn); - BoxRec AvailFBArea; - int lines; nPtr->AccelInfoRec = infoPtr = XAACreateInfoRec(); if(!infoPtr) return FALSE; @@ -158,23 +156,7 @@ default: return FALSE; } - - /* Initialize for widths */ - nAcl->Pitch = pScrn->displayWidth * nAcl->PixelWidth; - lines = nAcl->cacheEnd / - (pScrn->displayWidth * (pScrn->bitsPerPixel >> 3)); - if(lines > 1024) lines = 1024; - - AvailFBArea.x1 = 0; - AvailFBArea.y1 = 0; - AvailFBArea.x2 = pScrn->displayWidth; - AvailFBArea.y2 = lines; - xf86InitFBManager(pScreen, &AvailFBArea); - - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Using %i scanlines of offscreen memory for pixmap caching\n", - lines - pScrn->virtualY); - + return(XAAInit(pScreen, infoPtr)); } --- XFree86-4.2.0/xc.orig/programs/Xserver/hw/xfree86/drivers/neomagic/neo_2090.c Mon Oct 1 15:44:07 2001 +++ XFree86-4.2.0/xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_2090.c Thu Apr 4 16:05:44 2002 @@ -101,8 +101,6 @@ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; NEOPtr nPtr = NEOPTR(pScrn); NEOACLPtr nAcl = NEOACLPTR(pScrn); - BoxRec AvailFBArea; - int lines; nPtr->AccelInfoRec = infoPtr = XAACreateInfoRec(); if(!infoPtr) return FALSE; @@ -197,20 +195,6 @@ nAcl->BltCntlFlags |= NEO_BC3_FIFO_EN; - lines = nAcl->cacheEnd / - (pScrn->displayWidth * (pScrn->bitsPerPixel >> 3)); - if(lines > 1024) lines = 1024; - - AvailFBArea.x1 = 0; - AvailFBArea.y1 = 0; - AvailFBArea.x2 = pScrn->displayWidth; - AvailFBArea.y2 = lines; - xf86InitFBManager(pScreen, &AvailFBArea); - - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Using %i scanlines of offscreen memory for pixmap caching\n", - lines - pScrn->virtualY); - return(XAAInit(pScreen, infoPtr)); } --- XFree86-4.2.0/xc.orig/programs/Xserver/hw/xfree86/drivers/neomagic/neo_2097.c Mon Oct 1 15:44:07 2001 +++ XFree86-4.2.0/xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_2097.c Thu Apr 4 16:05:44 2002 @@ -123,8 +123,6 @@ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; NEOPtr nPtr = NEOPTR(pScrn); NEOACLPtr nAcl = NEOACLPTR(pScrn); - int lines; - BoxRec AvailFBArea; nPtr->AccelInfoRec = infoPtr = XAACreateInfoRec(); if(!infoPtr) return FALSE; @@ -245,21 +243,7 @@ default: return FALSE; } - - lines = nAcl->cacheEnd / - (pScrn->displayWidth * (pScrn->bitsPerPixel >> 3)); - if(lines > 1024) lines = 1024; - - AvailFBArea.x1 = 0; - AvailFBArea.y1 = 0; - AvailFBArea.x2 = pScrn->displayWidth; - AvailFBArea.y2 = lines; - xf86InitFBManager(pScreen, &AvailFBArea); - - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Using %i scanlines of offscreen memory for pixmap caching\n", - lines - pScrn->virtualY); - + return(XAAInit(pScreen, infoPtr)); } --- XFree86-4.2.0/xc.orig/programs/Xserver/hw/xfree86/drivers/neomagic/neo_2200.c Sun Oct 28 04:33:42 2001 +++ XFree86-4.2.0/xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_2200.c Thu Apr 4 16:05:44 2002 @@ -120,8 +120,6 @@ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; NEOPtr nPtr = NEOPTR(pScrn); NEOACLPtr nAcl = NEOACLPTR(pScrn); - BoxRec AvailFBArea; - int lines; nPtr->AccelInfoRec = infoPtr = XAACreateInfoRec(); if(!infoPtr) return FALSE; @@ -251,19 +249,6 @@ return FALSE; } - lines = nAcl->cacheEnd / - (pScrn->displayWidth * (pScrn->bitsPerPixel >> 3)); - if(lines > 1024) lines = 1024; - - AvailFBArea.x1 = 0; - AvailFBArea.y1 = 0; - AvailFBArea.x2 = pScrn->displayWidth; - AvailFBArea.y2 = lines; - xf86InitFBManager(pScreen, &AvailFBArea); - - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Using %i scanlines of offscreen memory for pixmap caching\n", - lines - pScrn->virtualY); return(XAAInit(pScreen, infoPtr)); } @@ -482,7 +467,7 @@ NEOPtr nPtr = NEOPTR(pScrn); WAIT_ENGINE_IDLE(); - OUTREG(NEOREG_DSTSTARTOFF, (y<<16) | (x & 0xffff)); + OUTREG(NEOREG_DSTSTARTOFF, (y <<16) | (x & 0xffff)); OUTREG(NEOREG_XYEXT, (h<<16) | (w & 0xffff)); } --- XFree86-4.2.0/xc.orig/programs/Xserver/hw/xfree86/drivers/neomagic/neo_dga.c Mon Oct 1 15:44:07 2001 +++ XFree86-4.2.0/xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_dga.c Thu Apr 4 16:05:44 2002 @@ -43,8 +43,10 @@ static void NEO_SetViewport(ScrnInfoPtr, int, int, int); static void NEO_FillRect(ScrnInfoPtr, int, int, int, int, unsigned long); static void NEO_BlitRect(ScrnInfoPtr, int, int, int, int, int, int); +#if 0 static void NEO_BlitTransRect(ScrnInfoPtr, int, int, int, int, int, int, unsigned long); +#endif static DGAFunctionRec NEODGAFuncs = { @@ -76,7 +78,7 @@ imlines = (pScrn->videoRam * 1024) / (pScrn->displayWidth * (pScrn->bitsPerPixel >> 3)); - pixlines = (imlines > 1024 && !pNEO->noAccel) ? 1024 : imlines; + pixlines = (imlines > 1024 && !pNEO->noAccel) ? 1024 : imlines; pMode = firstMode = pScrn->modes; @@ -184,7 +186,7 @@ ){ NEOPtr pNEO = NEOPTR(pScrn); vgaHWPtr hwp = VGAHWPTR(pScrn); - + NEOAdjustFrame(pScrn->pScreen->myNum, x, y, flags); /* wait for retrace */ while((hwp->readST01(hwp) & 0x08)); @@ -240,7 +242,7 @@ } } - +#if 0 static void NEO_BlitTransRect( ScrnInfoPtr pScrn, @@ -252,7 +254,7 @@ /* this one should be separate since the XAA function would prohibit usage of ~0 as the key */ } - +#endif static Bool NEO_OpenFramebuffer( --- XFree86-4.2.0/xc.orig/programs/Xserver/hw/xfree86/drivers/neomagic/neo_driver.c Fri Nov 30 13:11:57 2001 +++ XFree86-4.2.0/xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_driver.c Sat Apr 6 19:49:40 2002 @@ -299,7 +307,11 @@ OPTION_PROG_LCD_MODE_REGS, OPTION_PROG_LCD_MODE_STRETCH, OPTION_OVERRIDE_VALIDATE_MODE, + OPTION_SHOWCACHE, OPTION_ROTATE, + OPTION_VIDEO_KEY, + OPTION_OVERLAYMEM, + OPTION_VIDEO_INTERLACE, OPTION_DISPLAY_HEIGHT_480, OPTION_STRANGE_LOCKUPS } NEOOpts; @@ -314,6 +326,7 @@ { OPTION_LCD_STRETCH, "NoStretch", OPTV_BOOLEAN, {0}, FALSE }, { OPTION_SHADOW_FB, "ShadowFB", OPTV_BOOLEAN, {0}, FALSE }, { OPTION_PCI_BURST, "pciBurst", OPTV_BOOLEAN, {0}, FALSE }, + { OPTION_SHOWCACHE, "ShowCache", OPTV_BOOLEAN, {0}, FALSE }, { OPTION_ROTATE, "Rotate", OPTV_ANYSTR, {0}, FALSE }, { OPTION_PROG_LCD_MODE_REGS, "progLcdModeRegs", OPTV_BOOLEAN, {0}, FALSE }, @@ -321,6 +334,10 @@ OPTV_BOOLEAN, {0}, FALSE }, { OPTION_OVERRIDE_VALIDATE_MODE, "overrideValidateMode", OPTV_BOOLEAN, {0}, FALSE }, + { OPTION_VIDEO_KEY, "VideoKey", OPTV_INTEGER, {0}, FALSE }, + { OPTION_OVERLAYMEM, "OverlayMem", OPTV_INTEGER, {0}, FALSE }, + { OPTION_VIDEO_INTERLACE, "Interlace", + OPTV_INTEGER, {0}, FALSE }, { -1, NULL, OPTV_NONE, {0}, FALSE } }; @@ -335,6 +352,7 @@ { OPTION_SHADOW_FB, "ShadowFB", OPTV_BOOLEAN, {0}, FALSE }, { OPTION_LCD_STRETCH,"NoStretch", OPTV_BOOLEAN, {0}, FALSE }, { OPTION_PCI_BURST, "pciBurst", OPTV_BOOLEAN, {0}, FALSE }, + { OPTION_SHOWCACHE, "ShowCache", OPTV_BOOLEAN, {0}, FALSE }, { OPTION_ROTATE, "Rotate", OPTV_ANYSTR, {0}, FALSE }, { OPTION_STRANGE_LOCKUPS, "StrangeLockups", OPTV_BOOLEAN, {0}, FALSE }, { OPTION_DISPLAY_HEIGHT_480, "DisplayHeight480", @@ -345,6 +363,10 @@ OPTV_BOOLEAN, {0}, FALSE }, { OPTION_OVERRIDE_VALIDATE_MODE, "overrideValidateMode", OPTV_BOOLEAN, {0}, FALSE }, + { OPTION_VIDEO_KEY, "VideoKey", OPTV_INTEGER, {0}, FALSE }, + { OPTION_OVERLAYMEM, "OverlayMem", OPTV_INTEGER, {0}, FALSE }, + { OPTION_VIDEO_INTERLACE, "Interlace", + OPTV_INTEGER, {0}, FALSE }, { -1, NULL, OPTV_NONE, {0}, FALSE } }; @@ -979,6 +1001,7 @@ xf86GetOptValBool(nPtr->Options, OPTION_LCD_CENTER,&nPtr->lcdCenter); xf86GetOptValBool(nPtr->Options, OPTION_LCD_STRETCH,&nPtr->noLcdStretch); xf86GetOptValBool(nPtr->Options, OPTION_SHADOW_FB,&nPtr->shadowFB); + xf86GetOptValBool(nPtr->Options, OPTION_SHOWCACHE,&nPtr->showcache); nPtr->onPciBurst = TRUE; xf86GetOptValBool(nPtr->Options, OPTION_PCI_BURST,&nPtr->onPciBurst); xf86GetOptValBool(nPtr->Options, @@ -1014,6 +1037,39 @@ "Valid options are \"CW\" or \"CCW\"\n"); } } +#ifdef XvExtension + if(xf86GetOptValInteger(nPtr->Options, + OPTION_VIDEO_KEY, &(nPtr->videoKey))) { + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "video key set to 0x%x\n", + nPtr->videoKey); + } else { + nPtr->videoKey = (1 << pScrn->offset.red) | + (1 << pScrn->offset.green) | + (((pScrn->mask.blue >> pScrn->offset.blue) - 1) + << pScrn->offset.blue); + } + if(xf86GetOptValInteger(nPtr->Options, OPTION_OVERLAYMEM, + &(nPtr->overlay))) { + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, + "reserve %d bytes for overlay.\n", nPtr->overlay); + } else { + nPtr->overlay = 0; + } + nPtr->interlace = 0; + if(xf86GetOptValInteger(nPtr->Options, OPTION_VIDEO_INTERLACE, + &(nPtr->interlace))) { + if (nPtr->interlace >= 0 && nPtr->interlace <= 2){ + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "interlace flag = %d\n", + nPtr->interlace); + } else { + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, + "\"%s\" is not a valid value for " + "Option \"Interlaced\"\n", s); + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Valid options are 0..2\n"); + } + } +#endif /* XvExtension */ + if (height_480 && nPtr->NeoPanelWidth == 800) { xf86DrvMsg(pScrn->scrnIndex,X_CONFIG, @@ -1069,6 +1125,9 @@ if (nPtr->strangeLockups) xf86DrvMsg(pScrn->scrnIndex,X_CONFIG, "Option StrangeLockups set: disabling some acceleration\n"); + if (nPtr->showcache) + xf86DrvMsg(pScrn->scrnIndex,X_CONFIG, + "Show chache for debugging\n"); if (nPtr->shadowFB) { if (nPtr->noLinear) { xf86DrvMsg(pScrn->scrnIndex, X_WARNING, @@ -1096,6 +1155,8 @@ nPtr->NeoLinearAddr = 0; } + nPtr->NeoMMIOAddr2 = 0; + nPtr->NeoMMIOBase2 = NULL; if (nPtr->pEnt->device->IOBase && !nPtr->noMMIO) { /* XXX Check this matches a PCI base address */ nPtr->NeoMMIOAddr = nPtr->pEnt->device->IOBase; @@ -1113,7 +1174,7 @@ "FB base address is set at 0x%X.\n", nPtr->NeoLinearAddr); } - if (!nPtr->NeoMMIOAddr) { + if (!nPtr->NeoMMIOAddr && !nPtr->noMMIO) { switch (nPtr->NeoChipset) { case NM2070 : nPtr->NeoMMIOAddr = nPtr->NeoLinearAddr + 0x100000; @@ -1129,11 +1190,17 @@ case NM2360: case NM2380: nPtr->NeoMMIOAddr = nPtr->PciInfo->memBase[1]; + nPtr->NeoMMIOAddr2 = nPtr->PciInfo->memBase[2]; break; } xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "MMIO base address is set at 0x%X.\n", nPtr->NeoMMIOAddr); + if (nPtr->NeoMMIOAddr2 != 0){ + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + "MMIO base address2 is set at 0x%X.\n", + nPtr->NeoMMIOAddr2); + } } /* XXX What about VGA resources in OPERATING mode? */ if (xf86RegisterResources(nPtr->pEnt->index, NULL, ResExclusive)) @@ -1152,7 +1219,7 @@ "FB base address is set at 0x%X.\n", nPtr->NeoLinearAddr); } - if (!nPtr->NeoMMIOAddr) { + if (!nPtr->NeoMMIOAddr && !nPtr->noMMIO) { nPtr->NeoMMIOAddr = nPtr->NeoLinearAddr + 0x100000; xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "MMIO base address is set at 0x%X.\n", @@ -1293,6 +1360,10 @@ /* Should we re-save the text mode on each VT enter? */ if(!neoModeInit(pScrn, pScrn->currentMode)) return FALSE; +#ifdef XvExtension + if (nPtr->video) + NEOResetVideo(pScrn); +#endif if (nPtr->NeoHWCursorShown) NeoShowCursor(pScrn); NEOAdjustFrame(pScrn->scrnIndex, pScrn->frameX0, pScrn->frameY0, 0); @@ -1384,12 +1455,12 @@ /* Map the Neo memory and possible MMIO areas */ if (!neoMapMem(pScrn)) return FALSE; - + /* * next we save the current state and setup the first mode */ neoSave(pScrn); - + if (!neoModeInit(pScrn,pScrn->currentMode)) return FALSE; vgaHWSaveScreen(pScreen,SCREEN_SAVER_ON); @@ -1431,7 +1502,7 @@ nPtr->ShadowPtr = NULL; FBStart = nPtr->NeoFbBase; } - + ret = fbScreenInit(pScreen, FBStart, width, height, pScrn->xDpi, pScrn->yDpi, @@ -1509,13 +1580,13 @@ nPtr->NeoLinearAddr); /* Setup pointers to free space in video ram */ allocatebase = (pScrn->videoRam << 10); - freespace = allocatebase - pScrn->displayWidth * + freespace = allocatebase - pScrn->displayWidth * pScrn->virtualY * (pScrn->bitsPerPixel >> 3); currentaddr = allocatebase; xf86DrvMsg(scrnIndex, X_PROBED, "%d bytes off-screen memory available\n", freespace); - if (nPtr->swCursor || nPtr->noMMIO) { + if (nPtr->swCursor || !nPtr->NeoMMIOBase) { xf86DrvMsg(scrnIndex, X_CONFIG, "Using Software Cursor.\n"); } else if (nPtr->NeoCursorMem <= freespace) { @@ -1530,19 +1601,52 @@ } else xf86DrvMsg(scrnIndex, X_ERROR, "Too little space for H/W cursor.\n"); - if (!nPtr->noAccel && nPtr->noMMIO) + if (!nPtr->noAccel && !nPtr->NeoMMIOBase) xf86DrvMsg(pScrn->scrnIndex,X_INFO, "Acceleration disabled when not using MMIO\n"); - - /* Setup the acceleration primitives */ - if (!nPtr->noAccel && !nPtr->noMMIO) { + { +#ifdef XvExtension + if (nPtr->overlay > 0){ + if (nPtr->overlay > freespace){ + xf86DrvMsg(pScrn->scrnIndex,X_INFO, + "Can not reserve %d bytes for overlay. " + "Resize to %d bytes.\n", + nPtr->overlay, freespace); + nPtr->overlay = freespace; + } + currentaddr -= nPtr->overlay; + freespace -= nPtr->overlay; + nPtr->overlay_offset = currentaddr; + xf86DrvMsg(pScrn->scrnIndex,X_INFO,"Overlay at 0x%x\n", + nPtr->overlay_offset); + } +#endif /* XvExtension */ nAcl->cacheStart = currentaddr - freespace; nAcl->cacheEnd = currentaddr; freespace = 0; + if (nAcl->cacheStart < nAcl->cacheEnd) { + BoxRec AvailFBArea; + int lines = nAcl->cacheEnd / + (pScrn->displayWidth * (pScrn->bitsPerPixel >> 3)); + if (!nPtr->noAccel && nPtr->NeoMMIOBase && lines > 1024) + lines = 1024; + AvailFBArea.x1 = 0; + AvailFBArea.y1 = 0; + AvailFBArea.x2 = pScrn->displayWidth; + AvailFBArea.y2 = lines; + xf86InitFBManager(pScreen, &AvailFBArea); + + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Using %i scanlines of offscreen memory \n" + , lines - pScrn->virtualY); + } + } + /* Setup the acceleration primitives */ + if (!nPtr->noAccel && nPtr->NeoMMIOBase) { if (nAcl->cacheStart >= nAcl->cacheEnd) { xf86DrvMsg(scrnIndex, X_ERROR, "Too little space for pixmap cache.\n"); - } + } switch(nPtr->NeoChipset) { case NM2070 : Neo2070AccelInit(pScreen); @@ -1624,6 +1728,8 @@ pScrn->racIoFlags = pScrn->racMemFlags = racflag; + NEOInitVideo(pScreen); + pScreen->SaveScreen = vgaHWSaveScreen; /* Setup DPMS mode */ @@ -1635,18 +1741,7 @@ pScrn->memPhysBase = (unsigned long)nPtr->NeoFbBase; pScrn->fbOffset = 0; } - -#ifdef XvExtension - { - XF86VideoAdaptorPtr *ptr; - int n; - - n = xf86XVListGenericAdaptors(pScrn,&ptr); - if (n) - xf86XVScreenInit(pScreen, ptr, n); - } -#endif - + /* Wrap the current CloseScreen function */ nPtr->CloseScreen = pScreen->CloseScreen; pScreen->CloseScreen = NEOCloseScreen; @@ -1677,11 +1772,21 @@ int Base; pScrn = xf86Screens[scrnIndex]; - Base = (y * pScrn->displayWidth + x) >> 2; hwp = VGAHWPTR(pScrn); nPtr = NEOPTR(pScrn); - /* Scale Base by the number of bytes per pixel. */ + if (nPtr->showcache && y) { + int lastline = nPtr->NeoFbMapSize / + ((pScrn->displayWidth * pScrn->bitsPerPixel) / 8); + + lastline -= pScrn->currentMode->VDisplay; + y += pScrn->virtualY - 1; + if (y > lastline) y = lastline; + } + + Base = (y * pScrn->displayWidth + x) >> 2; + + /* Scale Base by the number of bytes per pixel. */ switch (pScrn->depth) { case 8 : break; @@ -1730,6 +1835,7 @@ if (nPtr->NeoHWCursorShown) NeoHideCursor(pScrn); neoRestore(pScrn, &(VGAHWPTR(pScrn))->SavedReg, &nPtr->NeoSavedReg, TRUE); + neoLock(pScrn); neoUnmapMem(pScrn); } @@ -1845,12 +1951,18 @@ if (!nPtr->noLinear) { if (!nPtr->noMMIO) { - if (nPtr->pEnt->location.type == BUS_PCI) + if (nPtr->pEnt->location.type == BUS_PCI){ nPtr->NeoMMIOBase = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_MMIO, nPtr->PciTag, nPtr->NeoMMIOAddr, 0x200000L); - else + if (nPtr->NeoMMIOAddr2 != 0){ + nPtr->NeoMMIOBase2 = + xf86MapPciMem(pScrn->scrnIndex, VIDMEM_MMIO, + nPtr->PciTag, nPtr->NeoMMIOAddr2, + 0x100000L); + } + } else nPtr->NeoMMIOBase = xf86MapVidMem(pScrn->scrnIndex, VIDMEM_MMIO, nPtr->NeoMMIOAddr, @@ -1889,8 +2001,14 @@ NEOPtr nPtr = NEOPTR(pScrn); if (!nPtr->noLinear) { - xf86UnMapVidMem(pScrn->scrnIndex, (pointer)nPtr->NeoMMIOBase, 0x200000L); + if (nPtr->NeoMMIOBase) + xf86UnMapVidMem(pScrn->scrnIndex, (pointer)nPtr->NeoMMIOBase, + 0x200000L); nPtr->NeoMMIOBase = NULL; + if (nPtr->NeoMMIOBase2) + xf86UnMapVidMem(pScrn->scrnIndex, (pointer)nPtr->NeoMMIOBase2, + 0x100000L); + nPtr->NeoMMIOBase2 = NULL; xf86UnMapVidMem(pScrn->scrnIndex, (pointer)nPtr->NeoFbBase, nPtr->NeoFbMapSize); } @@ -2200,7 +2318,7 @@ unsigned char temp; int i; Bool clock_hi = FALSE; - + vgaHWProtect(pScrn,TRUE); /* Blank the screen */ VGAwGR(0x09,0x26); @@ -2220,6 +2338,7 @@ * any reserved bits. */ temp = VGArGR(0x90); + switch (nPtr->NeoChipset) { case NM2070 : temp &= 0xF0; /* Save bits 7:4 */ @@ -2238,6 +2357,7 @@ break; } VGAwGR(0x90,temp); + /* * In some rare cases a lockup might occur if we don't delay * here. (Reported by Miles Lane) @@ -2256,7 +2376,6 @@ * had time to take effect. */ xf86UDelay(200000); - /* * This function handles restoring the generic VGA registers. */ vgaHWRestore(pScrn, VgaReg, @@ -2273,6 +2392,7 @@ VGAwGR(0x11, restore->SysIfaceCntl2); VGAwGR(0x15, restore->SingleAddrPage); VGAwGR(0x16, restore->DualAddrPage); + temp = VGArGR(0x20); switch (nPtr->NeoChipset) { case NM2070 : @@ -2349,7 +2469,7 @@ } if (restore->biosMode) VGAwCR(0x23,restore->biosMode); - + if (restore->reg) { VGAwCR(0x23,restore->reg->CR[0x23]); VGAwCR(0x25,restore->reg->CR[0x25]); @@ -2371,13 +2491,13 @@ VGAwGR(i, restore->reg->GR[i]); } } + /* Program vertical extension register */ if (nPtr->NeoChipset == NM2200 || nPtr->NeoChipset == NM2230 || nPtr->NeoChipset == NM2360 || nPtr->NeoChipset == NM2380) { VGAwCR(0x70, restore->VerticalExt); } - - + vgaHWProtect(pScrn, FALSE); /* Turn on screen */ } @@ -2574,7 +2694,7 @@ NeoNew->PanelHorizCenterReg3 = 0x00; NeoNew->PanelHorizCenterReg4 = 0x00; NeoNew->PanelHorizCenterReg5 = 0x00; - + if (nPtr->lcdCenter && (NeoNew->PanelDispCntlReg1 & 0x02)) { if (mode->HDisplay == nPtr->NeoPanelWidth) { @@ -2632,6 +2752,18 @@ } } } +#ifdef XvExtension + if (!noLcdStretch) { + if (mode->HDisplay != nPtr->NeoPanelWidth) + nPtr->videoHZoom = (double)nPtr->NeoPanelWidth/mode->HDisplay; + if (mode->VDisplay != nPtr->NeoPanelHeight) + nPtr->videoVZoom = (double)nPtr->NeoPanelHeight/mode->VDisplay; + } else { + nPtr->videoHZoom = 1.0; + nPtr->videoVZoom = 1.0; + } +#endif + NeoNew->biosMode = neoFindMode(mode->HDisplay,mode->VDisplay,pScrn->depth); /* @@ -2764,9 +2896,8 @@ } /* Turn the screen on/off */ - outb(0x3C4, 0x01); - SEQ01 |= inb(0x3C5) & ~0x20; - outb(0x3C5, SEQ01); + SEQ01 |= VGArSR(0x01) & ~0x20; + VGAwSR(0x01, SEQ01); /* Turn the LCD on/off */ LCD_on |= VGArGR(0x20) & ~0x02; --- XFree86-4.2.0/xc.orig/programs/Xserver/hw/xfree86/drivers/neomagic/neo_video.c Thu Jan 1 01:00:00 1970 +++ XFree86-4.2.0/xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_video.c Thu Apr 4 16:05:44 2002 @@ -0,0 +1,1232 @@ +/********************************************************************** +Copyright 2002 by Shigehiro Nomura. + + All Rights Reserved + +Permission to use, copy, modify, distribute, and sell this software and +its documentation for any purpose is hereby granted without fee, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the name of Shigehiro Nomura not be +used in advertising or publicity pertaining to distribution of the +software without specific, written prior permission. Shigehiro Nomura +and its suppliers make no representations about the suitability of this +software for any purpose. It is provided "as is" without express or +implied warranty. + +SHIGEHIRO NOMURA DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO +EVENT SHALL SHIGEHIRO NOMURA AND/OR ITS SUPPLIERS BE LIABLE FOR ANY +SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER +RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF +CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN +CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +**********************************************************************/ + +/* + * Copyright 2002 SuSE Linux AG, Author: Egbert Eich + */ + +#include "neo.h" +#include "neo_video.h" + +#define nElems(x) (sizeof(x) / sizeof(x[0])) +#define MAKE_ATOM(a) MakeAtom(a, sizeof(a) - 1, TRUE) + +#if defined(XvExtension) + +#include "dixstruct.h" +#include "xaa.h" +#include "xaalocal.h" + +static XF86VideoAdaptorPtr NEOSetupVideo(ScreenPtr); + +static int NEOPutVideo(ScrnInfoPtr, short, short, short, short, + short, short, short, short, RegionPtr, pointer); + +static void NEOStopVideo(ScrnInfoPtr, pointer, Bool); +static int NEOSetPortAttribute(ScrnInfoPtr, Atom, INT32, pointer); +static int NEOGetPortAttribute(ScrnInfoPtr, Atom, INT32 *, pointer); +static void NEOQueryBestSize(ScrnInfoPtr, Bool, short, short, short, + short, unsigned int *, unsigned int *, pointer); +static int NEOPutImage(ScrnInfoPtr, short, short, short, short, short, short, + short, short, int, unsigned char *, short, short, Bool, + RegionPtr, pointer); +static int NEOQueryImageAttributes(ScrnInfoPtr, int, unsigned short *, + unsigned short *, int *, int *); + +static Bool RegionsEqual(RegionPtr, RegionPtr); +static void NEODisplayVideo(ScrnInfoPtr, int, int, short, short, int, int, + int, int, int, BoxPtr, short, short, short, short); + +static void NEOInitOffscreenImages(ScreenPtr); +static FBLinearPtr NEOAllocateMemory(ScrnInfoPtr, FBLinearPtr, int); +static void NEOCopyData(unsigned char *, unsigned char *, int, int, int, int); +static void NEOCopyYV12Data(unsigned char *, unsigned char *, unsigned char *, + unsigned char *, int, int, int, int, int); + +static int NEOAllocSurface(ScrnInfoPtr, int, unsigned short, unsigned short, + XF86SurfacePtr); +static int NEOFreeSurface(XF86SurfacePtr); +static int NEODisplaySurface(XF86SurfacePtr, short, short, short, short, + short, short, short, short, RegionPtr clipBoxes); +static int NEOStopSurface(XF86SurfacePtr); +static int NEOGetSurfaceAttribute(ScrnInfoPtr, Atom, INT32 *); +static int NEOSetSurfaceAttribute(ScrnInfoPtr, Atom, INT32); + +static Atom xvColorKey, xvBrightness, xvInterlace; + +void +NEOInitVideo(ScreenPtr pScreen) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + NEOPtr nPtr = NEOPTR(pScrn); + XF86VideoAdaptorPtr *overlayAdaptors, *newAdaptors = NULL; + XF86VideoAdaptorPtr newAdaptor = NULL; + int numAdaptors; + + numAdaptors = xf86XVListGenericAdaptors(pScrn, &overlayAdaptors); + + if (nPtr->NeoChipset >= NM2160 + && !nPtr->noLinear + && nPtr->NeoMMIOBase2 != NULL){ + nPtr->video = TRUE; + newAdaptor = NEOSetupVideo(pScreen); + NEOInitOffscreenImages(pScreen); + } else + nPtr->video = FALSE; + + if (newAdaptor){ + if (!numAdaptors){ + numAdaptors = 1; + overlayAdaptors = &newAdaptor; + } else { + newAdaptors = xalloc((numAdaptors + 1) + * sizeof(XF86VideoAdaptorPtr*)); + if (newAdaptors){ + memcpy(newAdaptors, overlayAdaptors, + numAdaptors * sizeof(XF86VideoAdaptorPtr)); + newAdaptors[numAdaptors++] = newAdaptor; + overlayAdaptors = newAdaptors; + } + } + } + + if (numAdaptors) + xf86XVScreenInit(pScreen, overlayAdaptors, numAdaptors); + + if (newAdaptors) + xfree(newAdaptors); +} + +static XF86VideoEncodingRec NEOVideoEncodings[] = +{ + { + NEO_VIDEO_VIDEO, + "XV_VIDEO", + 1024, 1024, + {1, 1} + }, + { + NEO_VIDEO_IMAGE, + "XV_IMAGE", + 1024, 1024, + {1, 1} + } +}; + +static XF86VideoFormatRec NEOVideoFormats[] = +{ + { 8, PseudoColor }, + { 15, TrueColor }, + { 16, TrueColor }, + { 24, TrueColor }, +}; + +static XF86AttributeRec NEOVideoAttributes[] = +{ + { + XvSettable | XvGettable, + 0x000000, 0xFFFFFF, + "XV_COLORKEY" + }, + { + XvSettable | XvGettable, + -128, 127, + "XV_BRIGHTNESS" + }, + { + XvSettable | XvGettable, + 0,2, + "XV_INTERLACE" + }, +}; + +static XF86ImageRec NEOVideoImages[] = +{ + XVIMAGE_YUY2, + XVIMAGE_YV12, + XVIMAGE_I420, + { + FOURCC_RV15, + XvRGB, + LSBFirst, + { 'R', 'V' ,'1', '5', + 0x00,'5',0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, + 16, + XvPacked, + 1, + 15, 0x001F, 0x03E0, 0x7C00, + 0, 0, 0, + 0, 0, 0, + 0, 0, 0, + { 'R', 'V', 'B' }, + XvTopToBottom + }, + { + FOURCC_RV16, + XvRGB, + LSBFirst, + { 'R', 'V' ,'1', '6', + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, + 16, + XvPacked, + 1, + 16, 0x001F, 0x07E0, 0xF800, + 0, 0, 0, + 0, 0, 0, + 0, 0, 0, + { 'R', 'V', 'B' }, + XvTopToBottom + } +}; + +static XF86VideoAdaptorPtr +NEOSetupVideo(ScreenPtr pScreen) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + NEOPtr nPtr = NEOPTR(pScrn); + NEOPortPtr pPriv; + XF86VideoAdaptorPtr overlayAdaptor; + int i; + +#ifdef DEBUG + xf86DrvMsg(pScrn->scrnIndex,X_INFO,"NEOSetupVideo\n"); +#endif + if ((overlayAdaptor = xcalloc(1, sizeof(XF86VideoAdaptorRec) + + sizeof(DevUnion) + + sizeof(NEOPortRec))) == NULL){ + return (NULL); + } + + overlayAdaptor->type = XvInputMask | XvImageMask | XvWindowMask + | XvOutputMask | XvVideoMask; + overlayAdaptor->flags = VIDEO_OVERLAID_IMAGES | VIDEO_CLIP_TO_VIEWPORT; + overlayAdaptor->name = "NeoMagic Video Engine"; + overlayAdaptor->nEncodings = nElems(NEOVideoEncodings); + overlayAdaptor->pEncodings = NEOVideoEncodings; + for (i = 0; i < nElems(NEOVideoEncodings); i++){ + NEOVideoEncodings[i].width = 1024; + NEOVideoEncodings[i].height = 1024; + } + overlayAdaptor->nFormats = nElems(NEOVideoFormats); + overlayAdaptor->pFormats = NEOVideoFormats; + overlayAdaptor->nPorts = 1; + overlayAdaptor->pPortPrivates = (DevUnion*) &overlayAdaptor[1]; + overlayAdaptor->pPortPrivates[0].ptr = + (pointer) &overlayAdaptor->pPortPrivates[1]; + overlayAdaptor->nAttributes = nElems(NEOVideoAttributes); + overlayAdaptor->pAttributes = NEOVideoAttributes; + overlayAdaptor->nImages = nElems(NEOVideoImages); + overlayAdaptor->pImages = NEOVideoImages; + + overlayAdaptor->PutVideo = NEOPutVideo; + overlayAdaptor->PutStill = NULL; + overlayAdaptor->GetVideo = NULL; + overlayAdaptor->GetStill = NULL; + + overlayAdaptor->StopVideo = NEOStopVideo; + overlayAdaptor->SetPortAttribute = NEOSetPortAttribute; + overlayAdaptor->GetPortAttribute = NEOGetPortAttribute; + overlayAdaptor->QueryBestSize = NEOQueryBestSize; + overlayAdaptor->PutImage = NEOPutImage; + overlayAdaptor->QueryImageAttributes = NEOQueryImageAttributes; + + pPriv = (NEOPortPtr)overlayAdaptor->pPortPrivates[0].ptr; + pPriv->colorKey = nPtr->videoKey; + pPriv->interlace = nPtr->interlace; + pPriv->videoStatus = 0; + pPriv->brightness = 0; + REGION_INIT(pScreen, &pPriv->clip, NullBox, 0); + nPtr->overlayAdaptor = overlayAdaptor; + + xvBrightness = MAKE_ATOM("XV_BRIGHTNESS"); + xvColorKey = MAKE_ATOM("XV_COLORKEY"); + xvInterlace = MAKE_ATOM("XV_INTERLACE"); + + NEOResetVideo(pScrn); + + return (overlayAdaptor); +} + +void +NEOResetVideo(ScrnInfoPtr pScrn) +{ + NEOPtr nPtr = NEOPTR(pScrn); + NEOPortPtr pPriv = (NEOPortPtr)nPtr->overlayAdaptor->pPortPrivates[0].ptr; + int r, g, b; + VGA_HWP(pScrn); + +#ifdef DEBUG + xf86DrvMsg(pScrn->scrnIndex,X_INFO,"NEOResetVideo\n"); +#endif + switch (pScrn->depth){ + case 8: + OUTGR(0xc6, pPriv->colorKey & 0); + OUTGR(0xc5, pPriv->colorKey & 0xff); + OUTGR(0xc7, pPriv->colorKey & 0); + break; + default: + r = (pPriv->colorKey & pScrn->mask.red) >> pScrn->offset.red; + g = (pPriv->colorKey & pScrn->mask.green) >> pScrn->offset.green; + b = (pPriv->colorKey & pScrn->mask.blue) >> pScrn->offset.blue; + OUTGR(0xc5, r); + OUTGR(0xc6, g); + OUTGR(0xc7, b); + break; + } + OUTGR(0xc4, pPriv->brightness); +} + +static int +NEOPutVideo(ScrnInfoPtr pScrn, + short src_x, short src_y, short drw_x, short drw_y, + short src_w, short src_h, short drw_w, short drw_h, + RegionPtr clipBoxes, pointer data) +{ + NEOPortPtr pPriv = (NEOPortPtr)data; + NEOPtr nPtr = NEOPTR(pScrn); + CARD32 src_pitch, offset; + int xscale, yscale; + BoxRec dstBox; + INT32 x1, y1, x2, y2; + int size, bpp; + unsigned char capctrl; + VGA_HWP(pScrn); + +#ifdef DEBUG + xf86DrvMsg(pScrn->scrnIndex,X_INFO,"NEOPutVideo: src: %d %d %d %d\n", + src_x, src_y, src_w, src_h); + xf86DrvMsg(pScrn->scrnIndex,X_INFO,"NEOPutVideo: drw: %d %d %d %d\n", + drw_x, drw_y, drw_w, drw_h); +#endif + if (src_w > 720) + src_w = 720; + if (src_h > 576) + src_h = 576; + if (pPriv->interlace != 2) + src_h /= 2; + x1 = src_x; + y1 = src_y; + x2 = src_x + src_w; + y2 = src_y + src_h; + + dstBox.x1 = drw_x; + dstBox.y1 = drw_y; + dstBox.x2 = drw_x + drw_w; + dstBox.y2 = drw_y + drw_h; + + if (!xf86XVClipVideoHelper(&dstBox, &x1, &x2, &y1, &y2, + clipBoxes, src_w, src_h)){ + return(Success); + } +#ifdef DEBUG + xf86DrvMsg(pScrn->scrnIndex,X_INFO,"NEOPutVideo: %d %d %d %d\n", + x1, y1, x2, y2); +#endif + + dstBox.x1 -= pScrn->frameX0; + dstBox.y1 -= pScrn->frameY0; + dstBox.x2 -= pScrn->frameX0; + dstBox.y2 -= pScrn->frameY0; +#ifdef DEBUG + xf86DrvMsg(pScrn->scrnIndex,X_INFO,"NEOPutVideo: dstBox %d %d %d %d\n", + dstBox.x1, dstBox.y1, dstBox.x2, dstBox.y2); +#endif + + bpp = (pScrn->bitsPerPixel + 1) >> 3; + src_pitch = (src_w + 7) & ~7; + + xscale = 0x1000; + if (src_w <= drw_w){ + xscale = (src_w * 0x1000 / drw_w) & 0xffff; + } + + yscale = 0x1000; + if (src_h <= drw_h){ + yscale = (src_h * 0x1000 / drw_h) & 0xffff; + } + + size = src_h * src_pitch * 2; + + if (size > nPtr->overlay){ + if ((pPriv->linear = NEOAllocateMemory(pScrn, pPriv->linear, size)) + == NULL){ + return (BadAlloc); + } + } else { + pPriv->linear = NULL; + } + + if (pPriv->linear == NULL){ + offset = nPtr->overlay_offset; + } else { + offset = pPriv->linear->offset * bpp; + } + +#ifdef DEBUG + xf86DrvMsg(pScrn->scrnIndex,X_INFO,"NEOPutVideo: offset=0x%x\n", offset); +#endif + WAIT_ENGINE_IDLE(); + memset(nPtr->NeoFbBase + offset, 0, size); + + if (!RegionsEqual(&pPriv->clip, clipBoxes)){ + REGION_COPY(pScreen, &pPriv->clip, clipBoxes); + xf86XVFillKeyHelper(pScrn->pScreen, pPriv->colorKey, + clipBoxes); + } + + x1 >>= 16; + y1 >>= 16; + x2 >>= 16; + y2 >>= 16; + + switch (nPtr->NeoChipset) { + default: + case NM2160: + offset/=2; + OUTGR(0xbc, 0x4f); + break; + case NM2200: + case NM2230: + case NM2360: + case NM2380: + OUTGR(0xbc, 0x2e); + break; + } + + + OUTGR(0xb1, (((dstBox.x2-1) >> 4) & 0xf0) | ((dstBox.x1 >> 8) & 0x0f)); + OUTGR(0xb2, dstBox.x1); + OUTGR(0xb3, dstBox.x2 - 1); + OUTGR(0xb4, (((dstBox.y2 - 1) >> 4) & 0xf0) | ((dstBox.y1 >> 8) & 0x0f)); + OUTGR(0xb5, dstBox.y1); + OUTGR(0xb6, dstBox.y2 - 1); + OUTGR(0xb7, offset >> 16); + OUTGR(0xb8, offset >> 8); + OUTGR(0xb9, offset ); + OUTGR(0xba, src_pitch >> 8); + OUTGR(0xbb, src_pitch); + + OUTGR(0xc0, xscale >> 8); + OUTGR(0xc1, xscale); + OUTGR(0xc2, yscale >> 8); + OUTGR(0xc3, yscale); + OUTGR(0xbf, 0x02); + + OUTGR(0x0a, 0x21); + + OUTSR(0x0c, offset ); + OUTSR(0x0d, offset >> 8); + OUTSR(0x0e, offset >> 16); + OUTSR(0x1a, src_pitch); + OUTSR(0x1b, src_pitch>>8); + + OUTSR(0x17, 0 + x1); + OUTSR(0x18, 0 + x2 -1); + OUTSR(0x19, (((0 + x2 - 1) >> 4) & 0xf0) | (((0 + x1) >> 8) & 0x0f)); + + OUTSR(0x14, 14 + y1); + OUTSR(0x15, 14 + y2 - 2); + OUTSR(0x16, (((14 + y2 - 1) >> 4) & 0xf0) | (((14 + y1) >> 8) & 0x0f)); + + OUTSR(0x1c, 0xfb); + OUTSR(0x1d, 0x00); + OUTSR(0x1e, 0xe2); + OUTSR(0x1f, 0x02); + + OUTSR(0x09, 0x11); + OUTSR(0x0a, 0x00); + + capctrl = 0x21; + switch (pPriv->interlace){ + case 0: /* Combine 2 fields */ + break; + case 1: /* one field only */ + capctrl |= 0x80; + break; + case 2: /* Interlaced fields */ + capctrl |= 0x40; + break; + } + OUTSR(0x08, capctrl); + +#if 0 + OUTGR(0x0a, 0x01); +#endif + OUTGR(0xb0, 0x03); + + pPriv->videoStatus = CLIENT_VIDEO_ON; + return (Success); +} + +static void +NEOStopVideo(ScrnInfoPtr pScrn, pointer data, Bool exit) +{ + NEOPortPtr pPriv = (NEOPortPtr)data; + NEOPtr nPtr = NEOPTR(pScrn); + VGA_HWP(pScrn); + +#ifdef DEBUG + xf86DrvMsg(pScrn->scrnIndex,X_INFO,"NEOStopVideo\n"); +#endif + REGION_EMPTY(pScrn->pScreen, &pPriv->clip); + + if (exit){ + if (pPriv->videoStatus & CLIENT_VIDEO_ON){ +#ifdef DEBUG + xf86DrvMsg(pScrn->scrnIndex,X_INFO,"NEOStopVideo: stop capture\n"); +#endif + OUTGR(0xb0, 0x02); + OUTGR(0x0a, 0x21); + OUTSR(0x08, 0xa0); +#if 0 + OUTGR(0x0a, 0x01); +#endif + } + if (pPriv->linear != NULL){ + xf86FreeOffscreenLinear(pPriv->linear); + pPriv->linear = NULL; + } + pPriv->videoStatus = 0; + } else { + if (pPriv->videoStatus & CLIENT_VIDEO_ON){ + OUTGR(0xb0, 0x02); + OUTGR(0x0a, 0x21); + OUTSR(0x08, 0xa0); +#if 0 + OUTGR(0x0a, 0x01); +#endif + pPriv->videoStatus |= OFF_TIMER; + pPriv->offTime = currentTime.milliseconds + OFF_DELAY; + } + } +} + +static int +NEOSetPortAttribute(ScrnInfoPtr pScrn, Atom attribute, INT32 value, + pointer data) +{ + NEOPortPtr pPriv = (NEOPortPtr)data; + NEOPtr nPtr = NEOPTR(pScrn); + VGA_HWP(pScrn); + +#ifdef DEBUG + xf86DrvMsg(pScrn->scrnIndex,X_INFO,"NEOSetPortAttribute\n"); +#endif + if (attribute == xvColorKey){ + int r, g, b; + + pPriv->colorKey = value; + switch (pScrn->depth){ + case 8: + OUTGR(0xc6, pPriv->colorKey & 0xff); + OUTGR(0xc5, 0x00); + OUTGR(0xc7, 0x00); + break; + default: + r = (pPriv->colorKey & pScrn->mask.red) >> pScrn->offset.red; + g = (pPriv->colorKey & pScrn->mask.green) >> pScrn->offset.green; + b = (pPriv->colorKey & pScrn->mask.blue) >> pScrn->offset.blue; + OUTGR(0xc5, r); + OUTGR(0xc6, g); + OUTGR(0xc7, b); + } + } else if (attribute == xvBrightness){ + if ((value < -128) || (value > 127)){ + return (BadValue); + } + pPriv->brightness = value; + OUTGR(0xc4, value); + } else if (attribute == xvInterlace){ + if (value < 0 || value > 2){ + return (BadValue); + } + pPriv->interlace = value; + } else { + return (BadMatch); + } + return (Success); +} + +static int +NEOGetPortAttribute(ScrnInfoPtr pScrn, Atom attribute, INT32 *value, + pointer data) +{ + NEOPortPtr pPriv = (NEOPortPtr)data; + +#ifdef DEBUG + xf86DrvMsg(pScrn->scrnIndex,X_INFO,"NEOGetPortAttribute\n"); +#endif + if (attribute == xvColorKey){ + *value = pPriv->colorKey; + } else if (attribute == xvBrightness){ + *value = pPriv->brightness; + } else if (attribute == xvInterlace){ + *value = pPriv->interlace; + } else { + return (BadMatch); + } + return (Success); +} + +static void +NEOQueryBestSize(ScrnInfoPtr pScrn, Bool motion, + short vid_w, short vid_h, short drw_w, short drw_h, + unsigned int *p_w, unsigned int *p_h, + pointer data) +{ +#ifdef DEBUG + xf86DrvMsg(pScrn->scrnIndex,X_INFO,"NEOQueryBestSize\n"); +#endif + *p_w = min(drw_w, 1024); + *p_h = min(drw_h, 1024); +} + +static int +NEOPutImage(ScrnInfoPtr pScrn, + short src_x, short src_y, short drw_x, short drw_y, + short src_w, short src_h, short drw_w, short drw_h, + int id, unsigned char *buf, short width, short height, + Bool sync, RegionPtr clipBoxes, pointer data) +{ + NEOPtr nPtr = NEOPTR(pScrn); + NEOPortPtr pPriv = (NEOPortPtr)nPtr->overlayAdaptor->pPortPrivates[0].ptr; + INT32 x1, y1, x2, y2; + int bpp; + int srcPitch, srcPitch2 = 0, dstPitch, size; + BoxRec dstBox; + CARD32 offset, offset2 = 0, offset3 = 0, tmp; + int left, top, nPixels, nLines; + unsigned char *dstStart; + +#ifdef DEBUG + xf86DrvMsg(pScrn->scrnIndex,X_INFO,"NEOPutImage\n"); +#endif + + x1 = src_x; + y1 = src_y; + x2 = src_x + src_w; + y2 = src_y + src_h; + + dstBox.x1 = drw_x; + dstBox.y1 = drw_y; + dstBox.x2 = drw_x + drw_w; + dstBox.y2 = drw_y + drw_h; + + if (!xf86XVClipVideoHelper(&dstBox, &x1, &x2, &y1, &y2, + clipBoxes, width, height)){ + return (Success); + } + + dstBox.x1 -= pScrn->frameX0; + dstBox.y1 -= pScrn->frameY0; + dstBox.x2 -= pScrn->frameX0; + dstBox.y2 -= pScrn->frameY0; + + bpp = ((pScrn->bitsPerPixel + 1) >> 3); + + switch (id){ + case FOURCC_YV12: + srcPitch = (width + 3) & ~3; + offset2 = srcPitch * height; + srcPitch2 = ((width >> 1) + 3) & ~3; + offset3 = offset2 + (srcPitch2 * (height >> 1)); + dstPitch = ((width << 1) + 15) & ~15; + break; + case FOURCC_I420: + srcPitch = (width + 3) & ~3; + offset3 = srcPitch * height; + srcPitch2 = ((width >> 1) + 3) & ~3; + offset2 = offset3 + (srcPitch2 * (height >> 1)); + dstPitch = ((width << 1) + 15) & ~15; + break; + case FOURCC_YUY2: + case FOURCC_RV15: + case FOURCC_RV16: + default: + srcPitch = width << 1; + dstPitch = (srcPitch + 15) & ~15; + break; + } + + size = dstPitch * height; + if (size > nPtr->overlay){ + if ((pPriv->linear = NEOAllocateMemory(pScrn, pPriv->linear, size)) + == NULL){ + return (BadAlloc); + } + } else { + pPriv->linear = NULL; + } + + top = y1 >> 16; + left = (x1 >> 16) & ~1; + nPixels = ((((x2 + 0xFFFF) >> 16) + 1) & ~1) - left; + left <<= 1; + + if (pPriv->linear == NULL){ + offset = nPtr->overlay_offset; + } else { + offset = pPriv->linear->offset * bpp; + } + +#ifdef DEBUG + xf86DrvMsg(pScrn->scrnIndex,X_INFO,"offset=%x\n", offset); +#endif + + dstStart = (unsigned char *)(nPtr->NeoFbBase + offset + left); + + switch (id){ + case FOURCC_YV12: + case FOURCC_I420: + top &= ~1; + tmp = ((top >> 1) * srcPitch2) + (left >> 2); + offset2 += tmp; + offset3 += tmp; + nLines = ((((y2 + 0xFFFF) >> 16) + 1) & ~1) - top; + NEOCopyYV12Data(buf + (top * srcPitch) + (left >> 1), buf + offset2, + buf + offset3, dstStart, srcPitch, srcPitch2, + dstPitch, nLines, nPixels); + break; + default: + buf += (top * srcPitch) + left; + nLines = ((y2 + 0xFFFF) >> 16) - top; + NEOCopyData(buf, dstStart, srcPitch, dstPitch, nLines, nPixels << 1); + } + + if (!RegionsEqual(&pPriv->clip, clipBoxes)){ + REGION_COPY(pScreen, &pPriv->clip, clipBoxes); + xf86XVFillKeyHelper(pScrn->pScreen, pPriv->colorKey, clipBoxes); + } + NEODisplayVideo(pScrn, id, offset, width, height, dstPitch, x1, y1, + x2, y2, &dstBox, src_w, src_h, drw_w, drw_h); + + pPriv->videoStatus = CLIENT_VIDEO_ON; + return (Success); + +} + +static int +NEOQueryImageAttributes(ScrnInfoPtr pScrn, int id, + unsigned short *width, unsigned short *height, + int *pitches, int *offsets) +{ + int size, tmp; + +#ifdef DEBUG + xf86DrvMsg(pScrn->scrnIndex,X_INFO,"NEOQueryImageAttributes\n"); +#endif + if (*width > 1024){ + *width = 1024; + } + if (*height > 1024){ + *height = 1024; + } + + *width = (*width + 1) & ~1; + if (offsets != NULL){ + offsets[0] = 0; + } + + switch (id){ + case FOURCC_YV12: + case FOURCC_I420: + *height = (*height + 1) & ~1; + size = (*width + 3) & ~3; + if (pitches != NULL){ + pitches[0] = size; + } + size *= *height; + if (offsets != NULL){ + offsets[1] = size; + } + tmp = ((*width >> 1) + 3) & ~3; + if (pitches != NULL){ + pitches[1] = pitches[2] = tmp; + } + tmp *= (*height >> 1); + size += tmp; + if (offsets != NULL){ + offsets[2] = size; + } + size += tmp; + break; + case FOURCC_YUY2: + case FOURCC_RV15: + case FOURCC_RV16: + default: + size = *width * 2; + if (pitches != NULL){ + pitches[0] = size; + } + size *= *height; + break; + } + return (size); +} + +static Bool +RegionsEqual(RegionPtr A, RegionPtr B) +{ + int *dataA, *dataB; + int num; + + num = REGION_NUM_RECTS(A); + if (num != REGION_NUM_RECTS(B)){ + return (FALSE); + } + + if ((A->extents.x1 != B->extents.x1) + || (A->extents.y1 != B->extents.y1) + || (A->extents.x2 != B->extents.x2) + || (A->extents.y2 != B->extents.y2)){ + return (FALSE); + } + + dataA = (int*) REGION_RECTS(A); + dataB = (int*) REGION_RECTS(B); + + while (num--){ + if ((dataA[0] != dataB[0]) || (dataA[1] != dataB[1])){ + return (FALSE); + } + dataA += 2; + dataB += 2; + } + return (TRUE); +} + +static void +NEODisplayVideo(ScrnInfoPtr pScrn, int id, int offset, + short width, short height, int pitch, + int x1, int y1, int x2, int y2, BoxPtr dstBox, + short src_w, short src_h, short drw_w, short drw_h) +{ + NEOPtr nPtr = NEOPTR(pScrn); + int hstretch, vstretch, fmt; + VGA_HWP(pScrn); +#ifdef DEBUG + xf86DrvMsg(pScrn->scrnIndex,X_INFO,"NEODisplayVideo\n"); + xf86DrvMsg(pScrn->scrnIndex,X_INFO,"NEODisplayVideo src_w=%d, src_h=%d, pitch=%d, drw_w=%d, drw_h=%d\n", src_w, src_h, pitch, drw_w, drw_h); +#endif +#define WIDTH_THRESHOLD 160 + if (dstBox->x2 >= pScrn->virtualX) { + /* + * This is a hack to work around a problem when video is moved + * accross the right border. + */ + int diff_s = (width - ((x2 - x1) >> 16)) & ~1; + int diff_d = (drw_w - dstBox->x2 + dstBox->x1) & ~1; + + offset -= 2 * ((diff_s > diff_d) ? diff_d : diff_s); + dstBox->x1 -= diff_d; + } else if (dstBox->x2 - dstBox->x1 < WIDTH_THRESHOLD) { + /* + * When the video window is less than about 160 pixel wide + * it will be distoreted. We attempt to fix it by actually + * making it wider and relying on the color key to prevent + * it from appearanig outside of the video. + */ + int pre, post; + int scale = 1; + + if (dstBox->x1 < WIDTH_THRESHOLD) { + pre = dstBox->x1; + post = 160 - pre; + } else { + pre = 160; + post = 0; + } + offset -= 2 * scale * pre; + dstBox->x1 -= pre; + dstBox->x2 += post; + } + if (nPtr->videoHZoom != 1.0) { + if ((dstBox->x2 += 5) > pScrn->virtualX) + dstBox->x2 = pScrn->virtualX; + if (dstBox->x1 > 0) dstBox->x1 += 2; + } + + fmt = 0x00; + switch (id){ + case FOURCC_YV12: + case FOURCC_I420: + case FOURCC_YUY2: + fmt = 0x00; + break; + case FOURCC_RV15: + case FOURCC_RV16: + fmt = 0x20; + break; + } + + offset += (x1 >> 15) & ~0x03; + + switch (nPtr->NeoChipset) { + default: + case NM2160: + offset/=2; + pitch/=2; + OUTGR(0xbc, 0x4f); + break; + case NM2200: + case NM2230: + case NM2360: + case NM2380: + OUTGR(0xbc, 0x2e); + break; + } + + /* factor 4 for granularity */ + hstretch = (double)0x1000 * 4 / (int)(nPtr->videoHZoom * 4); + if (drw_w > src_w) + hstretch = (((int)src_w) * hstretch) / (int) drw_w; + + vstretch = (double)0x1000 / nPtr->videoVZoom; + if (drw_h > src_h) + vstretch = (((int)src_h) * vstretch )/ (int) drw_h; + + OUTGR(0xb1, (((dstBox->x2 - 1) >> 4) & 0xf0) | ((dstBox->x1 >> 8) & 0x0f)); + OUTGR(0xb2, dstBox->x1); + OUTGR(0xb3, dstBox->x2 - 1); + OUTGR(0xb4, (((dstBox->y2 - 1) >> 4) & 0xf0) | ((dstBox->y1 >> 8) & 0x0f)); + OUTGR(0xb5, dstBox->y1); + OUTGR(0xb6, dstBox->y2 - 1); + OUTGR(0xb7, offset >> 16); + OUTGR(0xb8, offset >> 8); + OUTGR(0xb9, offset ); + OUTGR(0xba, pitch >> 8); + OUTGR(0xbb, pitch); + + OUTGR(0xbd, 0x02); + OUTGR(0xbe, 0x00); + OUTGR(0xbf, 0x02); + + OUTGR(0xc0, hstretch >> 8); + OUTGR(0xc1, hstretch); + OUTGR(0xc2, vstretch >> 8); + OUTGR(0xc3, vstretch); + + OUTGR(0xb0, fmt | 0x03); + + OUTGR(0x0a, 0x21); + OUTSR(0x08, 0xa0); + OUTGR(0x0a, 0x01); +} + +static void +NEOInitOffscreenImages(ScreenPtr pScreen) +{ + XF86OffscreenImagePtr offscreenImages; + +#ifdef DEBUG + xf86DrvMsg(xf86Screens[pScreen->myNum]->scrnIndex,X_INFO,"NEOInitOffscreenImages\n"); +#endif + if ((offscreenImages = xalloc(sizeof(XF86OffscreenImageRec))) == NULL){ + return; + } + + offscreenImages->image = NEOVideoImages; + offscreenImages->flags = VIDEO_OVERLAID_IMAGES | VIDEO_CLIP_TO_VIEWPORT; + offscreenImages->alloc_surface = NEOAllocSurface; + offscreenImages->free_surface = NEOFreeSurface; + offscreenImages->display = NEODisplaySurface; + offscreenImages->stop = NEOStopSurface; + offscreenImages->getAttribute = NEOGetSurfaceAttribute; + offscreenImages->setAttribute = NEOSetSurfaceAttribute; + offscreenImages->max_width = 1024; + offscreenImages->max_height = 1024; + offscreenImages->num_attributes = nElems(NEOVideoAttributes); + offscreenImages->attributes = NEOVideoAttributes; + + xf86XVRegisterOffscreenImages(pScreen, offscreenImages, 1); +} + +static FBLinearPtr +NEOAllocateMemory(ScrnInfoPtr pScrn, FBLinearPtr linear, int size) +{ + ScreenPtr pScreen; + FBLinearPtr new_linear; + int bytespp = pScrn->bitsPerPixel >> 3; + + /* convert size in bytes into number of pixels */ + size = (size + bytespp - 1) / bytespp; +#ifdef DEBUG + xf86DrvMsg(pScrn->scrnIndex,X_INFO, + "NEOAllocateMemory: linear=%x, size=%d\n", linear, size); +#endif + if (linear){ +#ifdef DEBUG + xf86DrvMsg(pScrn->scrnIndex,X_INFO, + "NEOAllocateMemory: linear->size=%d\n", linear->size); +#endif + if (linear->size >= size){ + return (linear); + } + + if (xf86ResizeOffscreenLinear(linear, size)){ + return (linear); + } + + xf86FreeOffscreenLinear(linear); + } + + + pScreen = screenInfo.screens[pScrn->scrnIndex]; + if ((new_linear = xf86AllocateOffscreenLinear(pScreen, size, 16, NULL, + NULL, NULL)) == NULL){ + int max_size; + + xf86QueryLargestOffscreenLinear(pScreen, &max_size, 16, + PRIORITY_EXTREME); +#ifdef DEBUG + xf86DrvMsg(pScrn->scrnIndex,X_INFO, + "NEOAllocateMemory: max_size=%d\n", max_size); +#endif + if (max_size < size){ + return (NULL); + } + + xf86PurgeUnlockedOffscreenAreas(pScreen); + new_linear = xf86AllocateOffscreenLinear(pScreen, + size, 16, NULL, NULL, NULL); + } + + return (new_linear); +} + +static void +NEOCopyData(unsigned char *src, unsigned char *dst, + int srcPitch, int dstPitch, + int height, int width) +{ + while (height-- > 0){ + memcpy(dst, src, width); + src += srcPitch; + dst += dstPitch; + } +} + +static void +NEOCopyYV12Data(unsigned char *src1, unsigned char *src2, + unsigned char *src3, unsigned char *dst, + int srcPitch1, int srcPitch2, int dstPitch, + int height, int width) +{ + CARD32 *pDst = (CARD32 *) dst; + int i; + + width >>= 1; + height >>= 1; + dstPitch >>= 2; + while (--height >= 0){ + for (i =0; i < width; i++){ + pDst[i] = src1[i << 1] | (src1[(i << 1) + 1] << 16) | + (src3[i] << 8) | (src2[i] << 24); + } + pDst += dstPitch; + src1 += srcPitch1; + + for (i =0; i < width; i++){ + pDst[i] = src1[i << 1] | (src1[(i << 1) + 1] << 16) | + (src3[i] << 8) | (src2[i] << 24); + } + pDst += dstPitch; + src1 += srcPitch1; + src2 += srcPitch2; + src3 += srcPitch2; + } +} + +static int +NEOAllocSurface(ScrnInfoPtr pScrn, int id, + unsigned short width, unsigned short height, + XF86SurfacePtr surface) +{ + int pitch, bpp, size; + NEOOffscreenPtr pPriv; + FBLinearPtr linear; + +#ifdef DEBUG + xf86DrvMsg(pScrn->scrnIndex,X_INFO,"NEOAllocSurface\n"); +#endif + if (width > 1024 || height > 1024){ + return (BadAlloc); + } + + width = (width + 1) & ~1; + bpp = ((pScrn->bitsPerPixel + 1) >> 3); + pitch = ((width << 1) + 15) & ~15; + size = pitch * height; + + if ((linear = NEOAllocateMemory(pScrn, NULL, size)) == NULL){ + return (BadAlloc); + } + + surface->width = width; + surface->height = height; + if ((surface->pitches = xalloc(sizeof(int))) == NULL){ + xf86FreeOffscreenLinear(linear); + return (BadAlloc); + } + if ((surface->offsets = xalloc(sizeof(int))) == NULL){ + xfree(surface->pitches); + xf86FreeOffscreenLinear(linear); + return (BadAlloc); + } + + if ((pPriv = xalloc(sizeof(NEOOffscreenRec))) == NULL){ + xfree(surface->pitches); + xfree(surface->offsets); + xf86FreeOffscreenLinear(linear); + return (BadAlloc); + } + + pPriv->linear = linear; + pPriv->isOn = FALSE; + + surface->pScrn = pScrn; + surface->id = id; + surface->pitches[0] = pitch; + surface->offsets[0] = linear->offset << 1; + surface->devPrivate.ptr = (pointer)pPriv; + return (Success); +} + +static int +NEOFreeSurface(XF86SurfacePtr surface) +{ + NEOOffscreenPtr pPriv = (NEOOffscreenPtr)surface->devPrivate.ptr; + +#ifdef DEBUG + xf86DrvMsg(0,X_INFO,"NEOFreeSurface\n"); +#endif + if (pPriv->isOn) + NEOStopSurface(surface); + + xf86FreeOffscreenLinear(pPriv->linear); + xfree(surface->pitches); + xfree(surface->offsets); + xfree(surface->devPrivate.ptr); + return (Success); +} + +static int +NEODisplaySurface(XF86SurfacePtr surface, + short src_x, short src_y, short drw_x, short drw_y, + short src_w, short src_h, short drw_w, short drw_h, + RegionPtr clipBoxes) +{ + NEOOffscreenPtr pPriv = (NEOOffscreenPtr)surface->devPrivate.ptr; + NEOPtr nPtr = NEOPTR(surface->pScrn); + NEOPortPtr portPriv = nPtr->overlayAdaptor->pPortPrivates[0].ptr; + INT32 x1, y1, x2, y2; + BoxRec dstBox; + +#ifdef DEBUG + xf86DrvMsg(surface->pScrn->scrnIndex,X_INFO,"NEODisplaySurface\n"); +#endif + x1 = src_x; + x2 = src_x + src_w; + y1 = src_y; + y2 = src_y + src_h; + + dstBox.x1 = drw_x; + dstBox.x2 = drw_x + drw_w; + dstBox.y1 = drw_y; + dstBox.y2 = drw_y + drw_h; + if (!xf86XVClipVideoHelper( &dstBox, &x1, &x2, &y1, &y2, + clipBoxes, surface->width, surface->height)){ + return (Success); + } + + dstBox.x1 -= surface->pScrn->frameX0; + dstBox.y1 -= surface->pScrn->frameY0; + dstBox.x2 -= surface->pScrn->frameX0; + dstBox.y2 -= surface->pScrn->frameY0; + + xf86XVFillKeyHelper(surface->pScrn->pScreen, portPriv->colorKey, + clipBoxes); + NEOResetVideo(surface->pScrn); + NEODisplayVideo(surface->pScrn, surface->id, surface->offsets[0], + surface->width, surface->height, surface->pitches[0], + x1, y1, x2, y2, &dstBox, src_w, src_h, drw_w, drw_h); + + pPriv->isOn = TRUE; + if (portPriv->videoStatus & CLIENT_VIDEO_ON){ + REGION_EMPTY(pScrn->pScreen, &portPriv->clip); + UpdateCurrentTime(); + portPriv->videoStatus = FREE_TIMER; + portPriv->freeTime = currentTime.milliseconds + FREE_DELAY; + } + return (Success); +} + +static int +NEOStopSurface(XF86SurfacePtr surface) +{ + NEOOffscreenPtr pPriv = (NEOOffscreenPtr)surface->devPrivate.ptr; + +#ifdef DEBUG + xf86DrvMsg(surface->pScrn->scrnIndex,X_INFO,"NEOStopSurface\n"); +#endif + if (pPriv->isOn){ + NEOPtr nPtr = NEOPTR(surface->pScrn); + VGA_HWP(surface->pScrn); + OUTGR(0xb0, 0x02); + pPriv->isOn = FALSE; + } + return (Success); +} + +static int +NEOGetSurfaceAttribute(ScrnInfoPtr pScrn, Atom attr, INT32 *value) +{ + NEOPtr nPtr = NEOPTR(pScrn); + +#ifdef DEBUG + xf86DrvMsg(pScrn->scrnIndex,X_INFO,"NEOGetSurfaceAttribute\n"); +#endif + return (NEOGetPortAttribute(pScrn, + attr, value, (pointer)nPtr->overlayAdaptor->pPortPrivates[0].ptr)); +} + +static int +NEOSetSurfaceAttribute(ScrnInfoPtr pScrn, Atom attr, INT32 value) +{ + NEOPtr nPtr = NEOPTR(pScrn); + +#ifdef DEBUG + xf86DrvMsg(pScrn->scrnIndex,X_INFO,"NEOSetSurfaceAttribute\n"); +#endif + return (NEOSetPortAttribute(pScrn, + attr, value, (pointer)nPtr->overlayAdaptor->pPortPrivates[0].ptr)); +} + +#else /* XvExtension */ + +void NEOInitVideo(ScreenPtr pScreen) {} +void NEOResetVideo(ScreenPtr pScreen) {} + +#endif --- XFree86-4.2.0/xc.orig/programs/Xserver/hw/xfree86/drivers/neomagic/neo_video.h Thu Jan 1 01:00:00 1970 +++ XFree86-4.2.0/xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_video.h Thu Apr 4 16:05:44 2002 @@ -0,0 +1,83 @@ +/********************************************************************** +Copyright 2002 by Shigehiro Nomura. + + All Rights Reserved + +Permission to use, copy, modify, distribute, and sell this software and +its documentation for any purpose is hereby granted without fee, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the name of Shigehiro Nomura not be +used in advertising or publicity pertaining to distribution of the +software without specific, written prior permission. Shigehiro Nomura +and its suppliers make no representations about the suitability of this +software for any purpose. It is provided "as is" without express or +implied warranty. + +SHIGEHIRO NOMURA DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO +EVENT SHALL SHIGEHIRO NOMURA AND/OR ITS SUPPLIERS BE LIABLE FOR ANY +SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER +RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF +CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN +CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +**********************************************************************/ + +#ifndef _NEO_VIDEO_H +#define _NEO_VIDEO_H + +#define ACC_MMIO + +#include "vgaHW.h" +#include "fourcc.h" +#include "Xv.h" + +#define NEO_VIDEO_VIDEO 0 +#define NEO_VIDEO_IMAGE 1 + +#define FOURCC_RV15 0x35315652 +#define FOURCC_RV16 0x36315652 + +#define OFF_DELAY 200 /* milliseconds */ +#define FREE_DELAY 60000 /* milliseconds */ + +#define OFF_TIMER 0x01 +#define FREE_TIMER 0x02 +#define CLIENT_VIDEO_ON 0x04 +#define TIMER_MASK (OFF_TIMER | FREE_TIMER) + +typedef struct +{ + FBLinearPtr linear; + RegionRec clip; + CARD32 colorKey; + CARD32 interlace; + CARD32 brightness; + CARD32 videoStatus; + Time offTime; + Time freeTime; +} NEOPortRec, *NEOPortPtr; + +typedef struct +{ + FBLinearPtr linear; + Bool isOn; +} NEOOffscreenRec, *NEOOffscreenPtr; + +/* I/O Functions */ +# define OUTGR(idx,dat) \ + if (nPtr->NeoMMIOBase2) \ + (*(unsigned short *)(nPtr->NeoMMIOBase2+VGA_GRAPH_INDEX)\ + =(idx)|((dat)<<8));\ + else \ + VGAwGR((idx),(dat)); + +# define OUTSR(idx,dat) \ +if (nPtr->NeoMMIOBase2) \ + (*(unsigned short *)(nPtr->NeoMMIOBase2+VGA_SEQ_INDEX)=(idx)|((dat)<<8));\ +else \ + VGAwSR((idx),(dat)); + +# define VGA_HWP(x) vgaHWPtr hwp = VGAHWPTR(x) + +#endif /* _NEO_VIDEO_H */