diff options
Diffstat (limited to 'xc/programs/Xserver/fb/fboverlay.c')
-rw-r--r-- | xc/programs/Xserver/fb/fboverlay.c | 259 |
1 files changed, 219 insertions, 40 deletions
diff --git a/xc/programs/Xserver/fb/fboverlay.c b/xc/programs/Xserver/fb/fboverlay.c index 548419fdc..0c0106e04 100644 --- a/xc/programs/Xserver/fb/fboverlay.c +++ b/xc/programs/Xserver/fb/fboverlay.c @@ -1,5 +1,5 @@ /* - * $XFree86: xc/programs/Xserver/fb/fboverlay.c,v 1.2 2000/05/11 18:14:13 tsi Exp $ + * $XFree86: xc/programs/Xserver/fb/fboverlay.c,v 1.3 2000/08/09 17:50:52 keithp Exp $ * * Copyright © 2000 SuSE, Inc. * @@ -38,15 +38,31 @@ fbOverlayCreateWindow(WindowPtr pWin) { FbOverlayScrPrivPtr pScrPriv = fbOverlayGetScrPriv(pWin->drawable.pScreen); int i; + PixmapPtr pPixmap; if (pWin->drawable.class != InputOutput) return TRUE; for (i = 0; i < pScrPriv->nlayers; i++) - if (pWin->drawable.depth == pScrPriv->pLayer[i]->drawable.depth) - { - pWin->devPrivates[fbWinPrivateIndex].ptr = (pointer) pScrPriv->pLayer[i]; + { + pPixmap = pScrPriv->layer[i].u.run.pixmap; + if (pWin->drawable.depth == pPixmap->drawable.depth) + { + pWin->devPrivates[fbWinPrivateIndex].ptr = (pointer) pPixmap; + /* + * Make sure layer keys are written correctly by + * having non-root layers set to full while the + * root layer is set to empty. This will cause + * all of the layers to get painted when the root + * is mapped + */ + if (!pWin->parent) + { + REGION_EMPTY (pWin->drawable.pScreen, + &pScrPriv->layer[i].u.run.region); + } return TRUE; - } + } + } return FALSE; } @@ -57,47 +73,206 @@ fbOverlayCloseScreen (int iScreen, ScreenPtr pScreen) int i; for (i = 0; i < pScrPriv->nlayers; i++) - (*pScreen->DestroyPixmap)(pScrPriv->pLayer[i]); + { + (*pScreen->DestroyPixmap)(pScrPriv->layer[i].u.run.pixmap); + REGION_UNINIT (pScreen, &pScrPriv->layer[i].u.run.region); + } return TRUE; } +/* + * Return layer containing this window + */ +int +fbOverlayWindowLayer(WindowPtr pWin) +{ + FbOverlayScrPrivPtr pScrPriv = fbOverlayGetScrPriv(pWin->drawable.pScreen); + int i; + + for (i = 0; i < pScrPriv->nlayers; i++) + if (pWin->devPrivates[fbWinPrivateIndex].ptr == + (pointer) pScrPriv->layer[i].u.run.pixmap) + return i; + return 0; +} + Bool fbOverlayCreateScreenResources(ScreenPtr pScreen) { int i; - FbOverlayScrInitPtr pInit = (FbOverlayScrInitPtr) (pScreen)->devPrivates[fbOverlayScreenPrivateIndex].ptr; - FbOverlayScrPrivPtr pScrPriv; + FbOverlayScrPrivPtr pScrPriv = fbOverlayGetScrPriv(pScreen); PixmapPtr pPixmap; - FbOverlayInitPtr overlay; + pointer pbits; + int width; + int depth; + BoxRec box; if (!miCreateScreenResources(pScreen)) return FALSE; - - pScrPriv = xalloc (sizeof (FbOverlayScrPrivRec)); - if (!pScrPriv) - return FALSE; - for (i = 0; i < pInit->nlayers; i++) + box.x1 = 0; + box.y1 = 0; + box.x2 = pScreen->width; + box.y2 = pScreen->height; + for (i = 0; i < pScrPriv->nlayers; i++) { - overlay = &pInit->init[i]; - pPixmap = (*pScreen->CreatePixmap)(pScreen, 0, 0, overlay->depth); + pbits = pScrPriv->layer[i].u.init.pbits; + width = pScrPriv->layer[i].u.init.width; + depth = pScrPriv->layer[i].u.init.depth; + pPixmap = (*pScreen->CreatePixmap)(pScreen, 0, 0, depth); if (!pPixmap) return FALSE; if (!(*pScreen->ModifyPixmapHeader)(pPixmap, pScreen->width, - pScreen->height, overlay->depth, - BitsPerPixel(overlay->depth), - PixmapBytePad(overlay->width, overlay->depth), - overlay->pbits)) + pScreen->height, depth, + BitsPerPixel(depth), + PixmapBytePad(width, depth), + pbits)) return FALSE; - pScrPriv->pLayer[i] = pPixmap; + pScrPriv->layer[i].u.run.pixmap = pPixmap; + REGION_INIT(pScreen, &pScrPriv->layer[i].u.run.region, &box, 0); } - pScrPriv->nlayers = pInit->nlayers; - xfree (pInit); - (pScreen)->devPrivates[fbOverlayScreenPrivateIndex].ptr = (pointer) pScrPriv; - pScreen->devPrivate = pScrPriv->pLayer[0]; + pScreen->devPrivate = pScrPriv->layer[0].u.run.pixmap; return TRUE; } +void +fbOverlayPaintKey (DrawablePtr pDrawable, + RegionPtr pRegion, + CARD32 pixel, + int layer) +{ + fbFillRegionSolid (pDrawable, pRegion, 0, + fbReplicatePixel (pixel, pDrawable->bitsPerPixel)); +} + +/* + * Track visible region for each layer + */ +void +fbOverlayUpdateLayerRegion (ScreenPtr pScreen, + int layer, + RegionPtr prgn) +{ + FbOverlayScrPrivPtr pScrPriv = fbOverlayGetScrPriv(pScreen); + int i; + RegionRec rgnNew; + + if (!prgn || !REGION_NOTEMPTY(pScreen, prgn)) + return; + for (i = 0; i < pScrPriv->nlayers; i++) + { + if (i == layer) + { + /* add new piece to this fb */ + REGION_UNION (pScreen, + &pScrPriv->layer[i].u.run.region, + &pScrPriv->layer[i].u.run.region, + prgn); + } + else if (REGION_NOTEMPTY (pScreen, + &pScrPriv->layer[i].u.run.region)) + { + /* paint new piece with chroma key */ + REGION_INIT (pScreen, &rgnNew, NullBox, 0); + REGION_INTERSECT (pScreen, + &rgnNew, + prgn, + &pScrPriv->layer[i].u.run.region); + (*pScrPriv->PaintKey) (&pScrPriv->layer[i].u.run.pixmap->drawable, + &rgnNew, + pScrPriv->layer[i].key, + i); + REGION_UNINIT(pScreen, &rgnNew); + /* remove piece from other fbs */ + REGION_SUBTRACT (pScreen, + &pScrPriv->layer[i].u.run.region, + &pScrPriv->layer[i].u.run.region, + prgn); + } + } +} + +/* + * Copy only areas in each layer containing real bits + */ +void +fbOverlayCopyWindow(WindowPtr pWin, + DDXPointRec ptOldOrg, + RegionPtr prgnSrc) +{ + ScreenPtr pScreen = pWin->drawable.pScreen; + FbOverlayScrPrivPtr pScrPriv = fbOverlayGetScrPriv(pWin->drawable.pScreen); + RegionRec rgnDst; + int dx, dy; + WindowPtr pwinRoot; + int i; + RegionRec layerRgn[FB_OVERLAY_MAX]; + PixmapPtr pPixmap; + + pwinRoot = WindowTable[pWin->drawable.pScreen->myNum]; + + dx = ptOldOrg.x - pWin->drawable.x; + dy = ptOldOrg.y - pWin->drawable.y; + + /* + * Clip to existing bits + */ + REGION_TRANSLATE(pScreen, prgnSrc, -dx, -dy); + REGION_INIT (pScreen, &rgnDst, NullBox, 0); + REGION_INTERSECT(pScreen, &rgnDst, &pWin->borderClip, prgnSrc); + REGION_TRANSLATE(pScreen, &rgnDst, dx, dy); + /* + * Compute the portion of each fb affected by this copy + */ + for (i = 0; i < pScrPriv->nlayers; i++) + { + REGION_INIT (pScreen, &layerRgn[i], NullBox, 0); + REGION_INTERSECT(pScreen, &layerRgn[i], &rgnDst, + &pScrPriv->layer[i].u.run.region); + if (REGION_NOTEMPTY (pScreen, &layerRgn[i])) + { + REGION_TRANSLATE(pScreen, &layerRgn[i], -dx, -dy); + pPixmap = pScrPriv->layer[i].u.run.pixmap; + fbCopyRegion (&pPixmap->drawable, &pPixmap->drawable, + 0, + &layerRgn[i], dx, dy, pScrPriv->CopyWindow, 0, + (void *) i); + } + } + /* + * Update regions + */ + for (i = 0; i < pScrPriv->nlayers; i++) + { + if (REGION_NOTEMPTY (pScreen, &layerRgn[i])) + fbOverlayUpdateLayerRegion (pScreen, i, &layerRgn[i]); + + REGION_UNINIT(pScreen, &layerRgn[i]); + } + REGION_UNINIT(pScreen, &rgnDst); +} + +void +fbOverlayWindowExposures (WindowPtr pWin, + RegionPtr prgn, + RegionPtr other_exposed) +{ + fbOverlayUpdateLayerRegion (pWin->drawable.pScreen, + fbOverlayWindowLayer (pWin), + prgn); + miWindowExposures(pWin, prgn, other_exposed); +} + +void +fbOverlayPaintWindow(WindowPtr pWin, RegionPtr pRegion, int what) +{ + if (what == PW_BORDER) + fbOverlayUpdateLayerRegion (pWin->drawable.pScreen, + fbOverlayWindowLayer (pWin), + pRegion); + fbPaintWindow (pWin, pRegion, what); +} + Bool fbOverlaySetupScreen(ScreenPtr pScreen, pointer pbits1, @@ -141,19 +316,18 @@ fbOverlayFinishScreenInit(ScreenPtr pScreen, int nvisuals; int ndepths; VisualID defaultVisual; - FbOverlayScrInitPtr pInit; - + FbOverlayScrPrivPtr pScrPriv; + if (fbOverlayGeneration != serverGeneration) { fbOverlayScreenPrivateIndex = AllocateScreenPrivateIndex (); fbOverlayGeneration = serverGeneration; } - - pInit = xalloc (sizeof (FbOverlayScrInitRec)); - if (!pInit) + + pScrPriv = xalloc (sizeof (FbOverlayScrPrivRec)); + if (!pScrPriv) return FALSE; - if (!fbInitVisuals (&visuals, &depths, &nvisuals, &ndepths, &depth1, &defaultVisual, ((unsigned long)1<<(bpp1-1)) | ((unsigned long)1<<(bpp2-1)), 8)) @@ -173,20 +347,25 @@ fbOverlayFinishScreenInit(ScreenPtr pScreen, pScreen->minInstalledCmaps = 1; pScreen->maxInstalledCmaps = 2; - pInit->nlayers = 2; - pInit->init[0].pbits = pbits1; - pInit->init[0].width = width1; - pInit->init[0].depth = depth1; + pScrPriv->nlayers = 2; + pScrPriv->PaintKey = fbOverlayPaintKey; + pScrPriv->CopyWindow = fbCopyWindowProc; + pScrPriv->layer[0].u.init.pbits = pbits1; + pScrPriv->layer[0].u.init.width = width1; + pScrPriv->layer[0].u.init.depth = depth1; - pInit->init[1].pbits = pbits2; - pInit->init[1].width = width2; - pInit->init[1].depth = depth2; - - pScreen->devPrivates[fbOverlayScreenPrivateIndex].ptr = (pointer) pInit; + pScrPriv->layer[1].u.init.pbits = pbits2; + pScrPriv->layer[1].u.init.width = width2; + pScrPriv->layer[1].u.init.depth = depth2; + + pScreen->devPrivates[fbOverlayScreenPrivateIndex].ptr = (pointer) pScrPriv; /* overwrite miCloseScreen with our own */ pScreen->CloseScreen = fbOverlayCloseScreen; pScreen->CreateScreenResources = fbOverlayCreateScreenResources; pScreen->CreateWindow = fbOverlayCreateWindow; + pScreen->WindowExposures = fbOverlayWindowExposures; + pScreen->CopyWindow = fbOverlayCopyWindow; + pScreen->PaintWindowBorder = fbOverlayPaintWindow; return TRUE; } |