summaryrefslogtreecommitdiff
path: root/xc/programs/Xserver/fb/fboverlay.c
diff options
context:
space:
mode:
Diffstat (limited to 'xc/programs/Xserver/fb/fboverlay.c')
-rw-r--r--xc/programs/Xserver/fb/fboverlay.c259
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;
}