#include "rootlessCommon.h"
RegionRec rootlessHugeRoot = {{-32767, -32767, 32767, 32767}, NULL};
WindowPtr TopLevelParent(WindowPtr pWindow)
{
WindowPtr top = pWindow;
if (IsRoot(pWindow)) return pWindow; while (top && ! IsTopLevel(top)) top = top->parent;
return top;
}
Bool IsFramedWindow(WindowPtr pWin)
{
WindowPtr top;
if (! pWin->realized) return FALSE;
top = TopLevelParent(pWin);
return (top && WINREC(top));
}
void SetPixmapBaseToScreen(PixmapPtr pix, int x, int y)
{
pix->devPrivate.ptr = (char *)(pix->devPrivate.ptr) -
(pix->drawable.bitsPerPixel/8 * x + y*pix->devKind);
}
void UpdatePixmap(WindowPtr pWindow)
{
WindowPtr top = TopLevelParent(pWindow);
RootlessWindowRec *winRec;
ScreenPtr pScreen = pWindow->drawable.pScreen;
PixmapPtr pix;
RL_DEBUG_MSG("update pixmap (win 0x%x)", pWindow);
if (! top) {
RL_DEBUG_MSG("no parent\n");
return;
}
winRec = WINREC(top);
if (!winRec) {
RL_DEBUG_MSG("not framed\n");
return;
}
if (pWindow == top) {
if (winRec->pixmap == NULL) {
pix = GetScratchPixmapHeader(pScreen,
winRec->frame.w, winRec->frame.h,
winRec->frame.depth,
winRec->frame.bitsPerPixel,
winRec->frame.bytesPerRow,
winRec->frame.pixelData);
SetPixmapBaseToScreen(pix, winRec->frame.x, winRec->frame.y);
pScreen->SetWindowPixmap(pWindow, pix);
winRec->pixmap = pix;
} else {
pix = winRec->pixmap;
pScreen->ModifyPixmapHeader(pix,
winRec->frame.w, winRec->frame.h,
winRec->frame.depth,
winRec->frame.bitsPerPixel,
winRec->frame.bytesPerRow,
winRec->frame.pixelData);
SetPixmapBaseToScreen(pix, winRec->frame.x, winRec->frame.y);
}
} else {
pix = winRec->pixmap;
pScreen->SetWindowPixmap(pWindow, pix);
}
RL_DEBUG_MSG("done\n");
}
#ifdef SHAPE
static void RootlessReallySetShape(WindowPtr pWin)
{
RootlessWindowRec *winRec = WINREC(pWin);
ScreenPtr pScreen = pWin->drawable.pScreen;
RegionRec newShape;
if (IsRoot(pWin)) return;
if (!IsTopLevel(pWin)) return;
if (!winRec) return;
if (wBoundingShape(pWin)) {
REGION_NULL(pScreen, &newShape);
REGION_COPY(pScreen, &newShape, wBoundingShape(pWin));
REGION_TRANSLATE(pScreen, &newShape, pWin->borderWidth,
pWin->borderWidth);
} else {
newShape.data = NULL;
newShape.extents.x1 = 0;
newShape.extents.y1 = 0;
newShape.extents.x2 = winRec->frame.w;
newShape.extents.y2 = winRec->frame.h;
}
RL_DEBUG_MSG("reshaping...");
RL_DEBUG_MSG("numrects %d, extents %d %d %d %d ",
REGION_NUM_RECTS(&newShape),
newShape.extents.x1, newShape.extents.y1,
newShape.extents.x2, newShape.extents.y2);
CallFrameProc(pScreen, ReshapeFrame,(pScreen, &winRec->frame, &newShape));
REGION_UNINIT(pScreen, &newShape);
}
#endif // SHAPE
void
RootlessDamageRegion(WindowPtr pWindow, RegionPtr pRegion)
{
pWindow = TopLevelParent(pWindow);
if (!pWindow) {
RL_DEBUG_MSG("RootlessDamageRegion: window is not framed\n");
} else if (!WINREC(pWindow)) {
RL_DEBUG_MSG("RootlessDamageRegion: top-level window not a frame\n");
} else {
REGION_UNION((pWindow)->drawable.pScreen, &WINREC(pWindow)->damage,
&WINREC(pWindow)->damage, (pRegion));
}
}
void
RootlessDamageBox(WindowPtr pWindow, BoxPtr pBox)
{
RegionRec region;
REGION_INIT(pWindow->drawable.pScreen, ®ion, pBox, 1);
RootlessDamageRegion(pWindow, ®ion);
}
void
RootlessDamageRect(WindowPtr pWindow, int x, int y, int w, int h)
{
BoxRec box;
RegionRec region;
x += pWindow->drawable.x;
y += pWindow->drawable.y;
box.x1 = x;
box.x2 = x + w;
box.y1 = y;
box.y2 = y + h;
REGION_INIT(pWindow->drawable.pScreen, ®ion, &box, 1);
RootlessDamageRegion(pWindow, ®ion);
}
#ifdef SHAPE
void
RootlessDamageShape(WindowPtr pWin)
{
RootlessWindowRec *winRec = WINREC(pWin);
if (IsRoot(pWin)) return;
if (!IsTopLevel(pWin)) return;
if (!winRec) return;
winRec->shapeDamage = TRUE;
}
#endif // SHAPE
void
RootlessRedisplay(WindowPtr pWindow)
{
RootlessWindowRec *winRec = WINREC(pWindow);
ScreenPtr pScreen = pWindow->drawable.pScreen;
#ifdef SHAPE
if (winRec->shapeDamage) {
RootlessReallySetShape(pWindow);
REGION_EMPTY(pScreen, &winRec->damage);
winRec->shapeDamage = FALSE;
}
else
#endif // SHAPE
if (REGION_NOTEMPTY(pScreen, &winRec->damage)) {
REGION_INTERSECT(pScreen, &winRec->damage, &winRec->damage,
&pWindow->borderSize);
REGION_TRANSLATE(pScreen, &winRec->damage,
-winRec->frame.x, -winRec->frame.y);
CallFrameProc(pScreen, UpdateRegion,
(pScreen, &winRec->frame, &winRec->damage));
REGION_EMPTY(pScreen, &winRec->damage);
}
}
void
RootlessRedisplayScreen(ScreenPtr pScreen)
{
WindowPtr root = WindowTable[pScreen->myNum];
if (root) {
WindowPtr win;
RootlessRedisplay(root);
for (win = root->firstChild; win; win = win->nextSib) {
if (WINREC(win)) {
RootlessRedisplay(win);
}
}
}
}