Blame synfig-osx/launcher/rootless-screen.c

Carlos Lopez a09598
/*
Carlos Lopez a09598
 * Screen routines for Mac OS X rootless X server
Carlos Lopez a09598
 *
Carlos Lopez a09598
 * Greg Parker     gparker@cs.stanford.edu
Carlos Lopez a09598
 *
Carlos Lopez a09598
 * February 2001  Created
Carlos Lopez a09598
 * March 3, 2001  Restructured as generic rootless mode
Carlos Lopez a09598
 */
Carlos Lopez a09598
Carlos Lopez a09598
/* Copyright (c) 2002 Apple Computer, Inc. All rights reserved.
Carlos Lopez a09598
Carlos Lopez a09598
   Permission is hereby granted, free of charge, to any person
Carlos Lopez a09598
   obtaining a copy of this software and associated documentation files
Carlos Lopez a09598
   (the "Software"), to deal in the Software without restriction,
Carlos Lopez a09598
   including without limitation the rights to use, copy, modify, merge,
Carlos Lopez a09598
   publish, distribute, sublicense, and/or sell copies of the Software,
Carlos Lopez a09598
   and to permit persons to whom the Software is furnished to do so,
Carlos Lopez a09598
   subject to the following conditions:
Carlos Lopez a09598
Carlos Lopez a09598
   The above copyright notice and this permission notice shall be
Carlos Lopez a09598
   included in all copies or substantial portions of the Software.
Carlos Lopez a09598
Carlos Lopez a09598
   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
Carlos Lopez a09598
   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
Carlos Lopez a09598
   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
Carlos Lopez a09598
   NONINFRINGEMENT.  IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT
Carlos Lopez a09598
   HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
Carlos Lopez a09598
   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
Carlos Lopez a09598
   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
Carlos Lopez a09598
   DEALINGS IN THE SOFTWARE.
Carlos Lopez a09598
Carlos Lopez a09598
   Except as contained in this notice, the name(s) of the above
Carlos Lopez a09598
   copyright holders shall not be used in advertising or otherwise to
Carlos Lopez a09598
   promote the sale, use or other dealings in this Software without
Carlos Lopez a09598
   prior written authorization. */
Carlos Lopez a09598
Carlos Lopez a09598
/* $XFree86: xc/programs/Xserver/hw/darwin/quartz/rootlessScreen.c,v 1.2 2002/04/03 00:06:32 torrey Exp $ */
Carlos Lopez a09598
Carlos Lopez a09598
Carlos Lopez a09598
#include "mi.h"
Carlos Lopez a09598
#include "scrnintstr.h"
Carlos Lopez a09598
#include "gcstruct.h"
Carlos Lopez a09598
#include "pixmapstr.h"
Carlos Lopez a09598
#include "windowstr.h"
Carlos Lopez a09598
#include "propertyst.h"
Carlos Lopez a09598
#include "mivalidate.h"
Carlos Lopez a09598
#include "picturestr.h"
Carlos Lopez a09598
#include "os.h"
Carlos Lopez a09598
#include "servermd.h"
Carlos Lopez a09598
#include "colormapst.h"
Carlos Lopez a09598
Carlos Lopez a09598
#include <sys types.h=""></sys>
Carlos Lopez a09598
#include <sys stat.h=""></sys>
Carlos Lopez a09598
#include <fcntl.h></fcntl.h>
Carlos Lopez a09598
Carlos Lopez a09598
#include "rootless-common.h"
Carlos Lopez a09598
#include "rootless-window.h"
Carlos Lopez a09598
Carlos Lopez a09598
/* In milcroseconds */
Carlos Lopez a09598
#define REDISPLAY_DELAY     10
Carlos Lopez a09598
#define REDISPLAY_MAX_DELAY 60
Carlos Lopez a09598
Carlos Lopez a09598
extern int RootlessMiValidateTree(WindowPtr pRoot,
Carlos Lopez a09598
				  WindowPtr pChild, VTKind kind);
Carlos Lopez a09598
extern Bool RootlessCreateGC(GCPtr pGC);
Carlos Lopez a09598
Carlos Lopez a09598
int rootlessGCPrivateIndex = -1;
Carlos Lopez a09598
int rootlessScreenPrivateIndex = -1;
Carlos Lopez a09598
int rootlessWindowPrivateIndex = -1;
Carlos Lopez a09598
Carlos Lopez a09598
void
Carlos Lopez a09598
RootlessUpdateScreenPixmap (ScreenPtr pScreen)
Carlos Lopez a09598
{
Carlos Lopez a09598
    RootlessScreenRec *s = SCREENREC(pScreen);
Carlos Lopez a09598
    PixmapPtr pPix;
Carlos Lopez a09598
    unsigned int rowbytes;
Carlos Lopez a09598
Carlos Lopez a09598
    pPix = (*pScreen->GetScreenPixmap) (pScreen);
Carlos Lopez a09598
    if (pPix == NULL)
Carlos Lopez a09598
    {
Carlos Lopez a09598
	pPix = (*pScreen->CreatePixmap) (pScreen, 0, 0, pScreen->rootDepth);
Carlos Lopez a09598
	(*pScreen->SetScreenPixmap) (pPix);
Carlos Lopez a09598
    }
Carlos Lopez a09598
Carlos Lopez a09598
    rowbytes = PixmapBytePad (pScreen->width, pScreen->rootDepth);
Carlos Lopez a09598
Carlos Lopez a09598
    if (s->pixmap_data_size < rowbytes)
Carlos Lopez a09598
    {
Carlos Lopez a09598
	if (s->pixmap_data != NULL)
Carlos Lopez a09598
	    xfree (s->pixmap_data);
Carlos Lopez a09598
Carlos Lopez a09598
	s->pixmap_data_size = rowbytes;
Carlos Lopez a09598
	s->pixmap_data = xalloc (s->pixmap_data_size);
Carlos Lopez a09598
	if (s->pixmap_data == NULL)
Carlos Lopez a09598
	    return;
Carlos Lopez a09598
Carlos Lopez a09598
	xp_fill_bytes (s->pixmap_data_size, 1, ~0,
Carlos Lopez a09598
		       s->pixmap_data, s->pixmap_data_size);
Carlos Lopez a09598
Carlos Lopez a09598
	pScreen->ModifyPixmapHeader (pPix, pScreen->width, pScreen->height,
Carlos Lopez a09598
				     pScreen->rootDepth,
Carlos Lopez a09598
				     BitsPerPixel (pScreen->rootDepth),
Carlos Lopez a09598
				     0, s->pixmap_data);
Carlos Lopez a09598
	/* ModifyPixmapHeader ignores zero arguments, so install rowbytes
Carlos Lopez a09598
	   by hand. */
Carlos Lopez a09598
	pPix->devKind = 0;
Carlos Lopez a09598
    }
Carlos Lopez a09598
}
Carlos Lopez a09598
Carlos Lopez a09598
static Bool
Carlos Lopez a09598
RootlessCreateScreenResources (ScreenPtr pScreen)
Carlos Lopez a09598
{
Carlos Lopez a09598
    Bool ret = TRUE;
Carlos Lopez a09598
Carlos Lopez a09598
    SCREEN_UNWRAP (pScreen, CreateScreenResources);
Carlos Lopez a09598
Carlos Lopez a09598
    if (pScreen->CreateScreenResources != NULL)
Carlos Lopez a09598
	ret = (*pScreen->CreateScreenResources) (pScreen);
Carlos Lopez a09598
   
Carlos Lopez a09598
    SCREEN_WRAP(pScreen, CreateScreenResources);
Carlos Lopez a09598
Carlos Lopez a09598
    if (!ret)
Carlos Lopez a09598
	return ret;
Carlos Lopez a09598
Carlos Lopez a09598
    /* miCreateScreenResources doesn't like our null framebuffer pointer,
Carlos Lopez a09598
       it leaves the screen pixmap with an uninitialized data pointer. So
Carlos Lopez a09598
       we gave it depth=0,bits=0, which says, leave it the fsck alone.
Carlos Lopez a09598
       So we have some work to do since we need the screen pixmap to be
Carlos Lopez a09598
       valid (e.g. CopyArea from the root window) */
Carlos Lopez a09598
Carlos Lopez a09598
    RootlessUpdateScreenPixmap (pScreen);
Carlos Lopez a09598
Carlos Lopez a09598
    return ret;
Carlos Lopez a09598
}
Carlos Lopez a09598
Carlos Lopez a09598
static Bool
Carlos Lopez a09598
RootlessCloseScreen(int i, ScreenPtr pScreen)
Carlos Lopez a09598
{
Carlos Lopez a09598
    RootlessScreenRec *s;
Carlos Lopez a09598
Carlos Lopez a09598
    s = SCREENREC(pScreen);
Carlos Lopez a09598
Carlos Lopez a09598
    /* FIXME: unwrap everything that was wrapped? */
Carlos Lopez a09598
    pScreen->CloseScreen = s->CloseScreen;
Carlos Lopez a09598
Carlos Lopez a09598
    if (s->pixmap_data != NULL)
Carlos Lopez a09598
    {
Carlos Lopez a09598
	xfree (s->pixmap_data);
Carlos Lopez a09598
	s->pixmap_data = NULL;
Carlos Lopez a09598
	s->pixmap_data_size = 0;
Carlos Lopez a09598
    }
Carlos Lopez a09598
Carlos Lopez a09598
    xfree(s);
Carlos Lopez a09598
    return pScreen->CloseScreen(i, pScreen);
Carlos Lopez a09598
}
Carlos Lopez a09598
Carlos Lopez a09598
static void
Carlos Lopez a09598
RootlessGetImage(DrawablePtr pDrawable, int sx, int sy, int w, int h,
Carlos Lopez a09598
                 unsigned int format, unsigned long planeMask, char *pdstLine)
Carlos Lopez a09598
{
Carlos Lopez a09598
    ScreenPtr pScreen = pDrawable->pScreen;
Carlos Lopez a09598
    SCREEN_UNWRAP(pScreen, GetImage);
Carlos Lopez a09598
Carlos Lopez a09598
    if (pDrawable->type == DRAWABLE_WINDOW)
Carlos Lopez a09598
    {
Carlos Lopez a09598
	int x0, y0, x1, y1;
Carlos Lopez a09598
Carlos Lopez a09598
	RootlessWindowRec *winRec;
Carlos Lopez a09598
Carlos Lopez a09598
        /* Many apps use GetImage to sync with the visible frame buffer
Carlos Lopez a09598
           FIXME: entire screen or just window or all screens? */
Carlos Lopez a09598
        RootlessRedisplayScreen (pScreen);
Carlos Lopez a09598
Carlos Lopez a09598
        /* RedisplayScreen stops drawing, so we need to start it again */
Carlos Lopez a09598
        RootlessStartDrawing ((WindowPtr) pDrawable);
Carlos Lopez a09598
Carlos Lopez a09598
	/* Check that we have some place to read from. */
Carlos Lopez a09598
	winRec = WINREC (TopLevelParent ((WindowPtr) pDrawable));
Carlos Lopez a09598
	if (winRec == NULL)
Carlos Lopez a09598
	    goto out;
Carlos Lopez a09598
Carlos Lopez a09598
	/* Clip to top-level window bounds. */
Carlos Lopez a09598
Carlos Lopez a09598
	x0 = pDrawable->x + sx;
Carlos Lopez a09598
	y0 = pDrawable->y + sy;
Carlos Lopez a09598
	x1 = x0 + w;
Carlos Lopez a09598
	y1 = y0 + h;
Carlos Lopez a09598
Carlos Lopez a09598
	x0 = MAX (x0, winRec->x);
Carlos Lopez a09598
	y0 = MAX (y0, winRec->y);
Carlos Lopez a09598
	x1 = MIN (x1, winRec->x + (int) winRec->width);
Carlos Lopez a09598
	y1 = MIN (y1, winRec->y + (int) winRec->height);
Carlos Lopez a09598
Carlos Lopez a09598
	/* FIXME: if clipped we need to adjust the data returned from
Carlos Lopez a09598
	   fbGetImage (), since it calculates the destination stride
Carlos Lopez a09598
	   from the passed in width.. */
Carlos Lopez a09598
Carlos Lopez a09598
	sx = x0 - pDrawable->x;
Carlos Lopez a09598
	sy = y0 - pDrawable->y;
Carlos Lopez a09598
	w = x1 - x0;
Carlos Lopez a09598
	h = y1 - y0;
Carlos Lopez a09598
Carlos Lopez a09598
	if (w <= 0 || h <= 0)
Carlos Lopez a09598
	    goto out;
Carlos Lopez a09598
    }
Carlos Lopez a09598
Carlos Lopez a09598
    pScreen->GetImage(pDrawable, sx, sy, w, h, format, planeMask, pdstLine);
Carlos Lopez a09598
Carlos Lopez a09598
out:
Carlos Lopez a09598
    SCREEN_WRAP(pScreen, GetImage);
Carlos Lopez a09598
}
Carlos Lopez a09598
Carlos Lopez a09598
/*
Carlos Lopez a09598
 * RootlessSourceValidate
Carlos Lopez a09598
 *  CopyArea and CopyPlane use a GC tied to the destination drawable.
Carlos Lopez a09598
 *  StartDrawing/StopDrawing wrappers won't be called if source is
Carlos Lopez a09598
 *  a visible window but the destination isn't. So, we call StartDrawing
Carlos Lopez a09598
 *  here and leave StopDrawing for the block handler.
Carlos Lopez a09598
 */
Carlos Lopez a09598
static void
Carlos Lopez a09598
RootlessSourceValidate(DrawablePtr pDrawable, int x, int y, int w, int h)
Carlos Lopez a09598
{
Carlos Lopez a09598
    SCREEN_UNWRAP(pDrawable->pScreen, SourceValidate);
Carlos Lopez a09598
    if (pDrawable->type == DRAWABLE_WINDOW) {
Carlos Lopez a09598
        WindowPtr pWin = (WindowPtr)pDrawable;
Carlos Lopez a09598
        RootlessStartDrawing(pWin);
Carlos Lopez a09598
    }
Carlos Lopez a09598
    if (pDrawable->pScreen->SourceValidate) {
Carlos Lopez a09598
        pDrawable->pScreen->SourceValidate(pDrawable, x, y, w, h);
Carlos Lopez a09598
    }
Carlos Lopez a09598
    SCREEN_WRAP(pDrawable->pScreen, SourceValidate);
Carlos Lopez a09598
}
Carlos Lopez a09598
Carlos Lopez a09598
#ifdef RENDER
Carlos Lopez a09598
Carlos Lopez a09598
static void
Carlos Lopez a09598
rootlessComposite(CARD8 op, PicturePtr pSrc, PicturePtr pMask, PicturePtr pDst,
Carlos Lopez a09598
                  INT16 xSrc, INT16 ySrc, INT16  xMask, INT16  yMask,
Carlos Lopez a09598
                  INT16 xDst, INT16 yDst, CARD16 width, CARD16 height)
Carlos Lopez a09598
{
Carlos Lopez a09598
    ScreenPtr pScreen = pDst->pDrawable->pScreen;
Carlos Lopez a09598
    PictureScreenPtr ps = GetPictureScreen(pScreen);
Carlos Lopez a09598
    WindowPtr srcWin, dstWin, maskWin = NULL;
Carlos Lopez a09598
Carlos Lopez a09598
    if (pMask) {
Carlos Lopez a09598
        maskWin = (pMask->pDrawable->type == DRAWABLE_WINDOW) ?
Carlos Lopez a09598
                  (WindowPtr)pMask->pDrawable :  NULL;
Carlos Lopez a09598
    }
Carlos Lopez a09598
    srcWin  = (pSrc->pDrawable->type  == DRAWABLE_WINDOW) ?
Carlos Lopez a09598
              (WindowPtr)pSrc->pDrawable  :  NULL;
Carlos Lopez a09598
    dstWin  = (pDst->pDrawable->type == DRAWABLE_WINDOW) ?
Carlos Lopez a09598
              (WindowPtr)pDst->pDrawable  :  NULL;
Carlos Lopez a09598
Carlos Lopez a09598
    ps->Composite = SCREENREC(pScreen)->Composite;
Carlos Lopez a09598
Carlos Lopez a09598
    if (srcWin  && IsFramedWindow(srcWin))  RootlessStartDrawing(srcWin);
Carlos Lopez a09598
    if (maskWin && IsFramedWindow(maskWin)) RootlessStartDrawing(maskWin);
Carlos Lopez a09598
    if (dstWin  && IsFramedWindow(dstWin))  RootlessStartDrawing(dstWin);
Carlos Lopez a09598
Carlos Lopez a09598
    ps->Composite(op, pSrc, pMask, pDst,
Carlos Lopez a09598
                  xSrc, ySrc, xMask, yMask,
Carlos Lopez a09598
                  xDst, yDst, width, height);
Carlos Lopez a09598
Carlos Lopez a09598
    if (dstWin  && IsFramedWindow(dstWin)) {
Carlos Lopez a09598
        RootlessDamageRect(dstWin, xDst, yDst, width, height);
Carlos Lopez a09598
    }
Carlos Lopez a09598
Carlos Lopez a09598
    ps->Composite = RootlessComposite;
Carlos Lopez a09598
}
Carlos Lopez a09598
Carlos Lopez a09598
static void
Carlos Lopez a09598
RootlessGlyphs(CARD8 op, PicturePtr pSrc, PicturePtr pDst,
Carlos Lopez a09598
               PictFormatPtr maskFormat, INT16 xSrc, INT16 ySrc,
Carlos Lopez a09598
               int nlist, GlyphListPtr list, GlyphPtr *glyphs)
Carlos Lopez a09598
{
Carlos Lopez a09598
    ScreenPtr pScreen = pDst->pDrawable->pScreen;
Carlos Lopez a09598
    PictureScreenPtr ps = GetPictureScreen(pScreen);
Carlos Lopez a09598
    int x, y;
Carlos Lopez a09598
    int n;
Carlos Lopez a09598
    GlyphPtr glyph;
Carlos Lopez a09598
    WindowPtr srcWin, dstWin;
Carlos Lopez a09598
Carlos Lopez a09598
    srcWin = (pSrc->pDrawable->type == DRAWABLE_WINDOW) ?
Carlos Lopez a09598
             (WindowPtr)pSrc->pDrawable  :  NULL;
Carlos Lopez a09598
    dstWin = (pDst->pDrawable->type == DRAWABLE_WINDOW) ?
Carlos Lopez a09598
             (WindowPtr)pDst->pDrawable  :  NULL;
Carlos Lopez a09598
Carlos Lopez a09598
    if (srcWin && IsFramedWindow(srcWin)) RootlessStartDrawing(srcWin);
Carlos Lopez a09598
    if (dstWin && IsFramedWindow(dstWin)) RootlessStartDrawing(dstWin);
Carlos Lopez a09598
Carlos Lopez a09598
    ps->Glyphs = SCREENREC(pScreen)->Glyphs;
Carlos Lopez a09598
    ps->Glyphs(op, pSrc, pDst, maskFormat, xSrc, ySrc, nlist, list, glyphs);
Carlos Lopez a09598
    ps->Glyphs = RootlessGlyphs;
Carlos Lopez a09598
Carlos Lopez a09598
    if (dstWin && IsFramedWindow(dstWin))
Carlos Lopez a09598
    {
Carlos Lopez a09598
        x = xSrc;
Carlos Lopez a09598
        y = ySrc;
Carlos Lopez a09598
Carlos Lopez a09598
	while (nlist--)
Carlos Lopez a09598
	{
Carlos Lopez a09598
	    /* Originally this code called DamageRect for the bounding
Carlos Lopez a09598
	       box of each glyph. But that was causing way too much
Carlos Lopez a09598
	       time to be spent in CGSBoundingRegionAddRect. So compute
Carlos Lopez a09598
	       the union of all glyphs in a list and damage that. It
Carlos Lopez a09598
	       shouldn't be very different. */
Carlos Lopez a09598
Carlos Lopez a09598
            x += list->xOff;
Carlos Lopez a09598
            y += list->yOff;
Carlos Lopez a09598
            n = list->len;
Carlos Lopez a09598
Carlos Lopez a09598
	    if (n > 0)
Carlos Lopez a09598
	    {
Carlos Lopez a09598
		BoxRec box;
Carlos Lopez a09598
Carlos Lopez a09598
                glyph = *glyphs++;
Carlos Lopez a09598
Carlos Lopez a09598
		box.x1 = x - glyph->info.x;
Carlos Lopez a09598
		box.y1 = y - glyph->info.y;
Carlos Lopez a09598
		box.x2 = box.x1 + glyph->info.width;
Carlos Lopez a09598
		box.y2 = box.y2 + glyph->info.height;
Carlos Lopez a09598
Carlos Lopez a09598
		x += glyph->info.xOff;
Carlos Lopez a09598
		y += glyph->info.yOff;
Carlos Lopez a09598
Carlos Lopez a09598
		while (--n > 0)
Carlos Lopez a09598
		{
Carlos Lopez a09598
		    short x1, y1, x2, y2;
Carlos Lopez a09598
Carlos Lopez a09598
		    glyph = *glyphs++;
Carlos Lopez a09598
Carlos Lopez a09598
		    x1 = x - glyph->info.x;
Carlos Lopez a09598
		    y1 = y - glyph->info.y;
Carlos Lopez a09598
		    x2 = x1 + glyph->info.width;
Carlos Lopez a09598
		    y2 = y1 + glyph->info.height;
Carlos Lopez a09598
Carlos Lopez a09598
		    box.x1 = MAX (box.x1, x1);
Carlos Lopez a09598
		    box.y1 = MAX (box.y1, y1);
Carlos Lopez a09598
		    box.x2 = MAX (box.x2, x2);
Carlos Lopez a09598
		    box.y2 = MAX (box.y2, y2);
Carlos Lopez a09598
Carlos Lopez a09598
		    x += glyph->info.xOff;
Carlos Lopez a09598
		    y += glyph->info.yOff;
Carlos Lopez a09598
		}
Carlos Lopez a09598
Carlos Lopez a09598
		RootlessDamageBox (dstWin, &box);
Carlos Lopez a09598
	    }
Carlos Lopez a09598
Carlos Lopez a09598
            list++;
Carlos Lopez a09598
        }
Carlos Lopez a09598
    }
Carlos Lopez a09598
}
Carlos Lopez a09598
Carlos Lopez a09598
#endif /* RENDER */
Carlos Lopez a09598
Carlos Lopez a09598
/* ValidateTree is modified in two ways:
Carlos Lopez a09598
    - top-level windows don't clip each other
Carlos Lopez a09598
    - windows aren't clipped against root.
Carlos Lopez a09598
   These only matter when validating from the root. */
Carlos Lopez a09598
static int
Carlos Lopez a09598
RootlessValidateTree(WindowPtr pParent, WindowPtr pChild, VTKind kind)
Carlos Lopez a09598
{
Carlos Lopez a09598
    int result;
Carlos Lopez a09598
    RegionRec saveRoot;
Carlos Lopez a09598
    ScreenPtr pScreen = pParent->drawable.pScreen;
Carlos Lopez a09598
Carlos Lopez a09598
    SCREEN_UNWRAP(pScreen, ValidateTree);
Carlos Lopez a09598
    RL_DEBUG_MSG("VALIDATETREE start ");
Carlos Lopez a09598
Carlos Lopez a09598
    /* Use our custom version to validate from root */
Carlos Lopez a09598
    if (IsRoot(pParent)) {
Carlos Lopez a09598
        RL_DEBUG_MSG("custom ");
Carlos Lopez a09598
        result = RootlessMiValidateTree(pParent, pChild, kind);
Carlos Lopez a09598
    } else {
Carlos Lopez a09598
        HUGE_ROOT(pParent);
Carlos Lopez a09598
        result = pScreen->ValidateTree(pParent, pChild, kind);
Carlos Lopez a09598
        NORMAL_ROOT(pParent);
Carlos Lopez a09598
    }
Carlos Lopez a09598
Carlos Lopez a09598
    SCREEN_WRAP(pScreen, ValidateTree);
Carlos Lopez a09598
    RL_DEBUG_MSG("VALIDATETREE end\n");
Carlos Lopez a09598
Carlos Lopez a09598
    return result;
Carlos Lopez a09598
}
Carlos Lopez a09598
Carlos Lopez a09598
/* MarkOverlappedWindows is modified to ignore overlapping top-level
Carlos Lopez a09598
   windows. */
Carlos Lopez a09598
static Bool
Carlos Lopez a09598
RootlessMarkOverlappedWindows(WindowPtr pWin, WindowPtr pFirst,
Carlos Lopez a09598
                              WindowPtr *ppLayerWin)
Carlos Lopez a09598
{
Carlos Lopez a09598
    RegionRec saveRoot;
Carlos Lopez a09598
    Bool result;
Carlos Lopez a09598
    ScreenPtr pScreen = pWin->drawable.pScreen;
Carlos Lopez a09598
    SCREEN_UNWRAP(pScreen, MarkOverlappedWindows);
Carlos Lopez a09598
    RL_DEBUG_MSG("MARKOVERLAPPEDWINDOWS start ");
Carlos Lopez a09598
Carlos Lopez a09598
    HUGE_ROOT(pWin);
Carlos Lopez a09598
    if (IsRoot(pWin)) {
Carlos Lopez a09598
        /* root - mark nothing */
Carlos Lopez a09598
        RL_DEBUG_MSG("is root not marking ");
Carlos Lopez a09598
        result = FALSE;
Carlos Lopez a09598
    }
Carlos Lopez a09598
    else if (! IsTopLevel(pWin)) {
Carlos Lopez a09598
        /* not top-level window - mark normally */
Carlos Lopez a09598
        result = pScreen->MarkOverlappedWindows(pWin, pFirst, ppLayerWin);
Carlos Lopez a09598
    }
Carlos Lopez a09598
    else {
Carlos Lopez a09598
        /* top-level window - mark children ONLY - NO overlaps with sibs (?)
Carlos Lopez a09598
	   This code copied from miMarkOverlappedWindows() */
Carlos Lopez a09598
Carlos Lopez a09598
        register WindowPtr pChild;
Carlos Lopez a09598
        Bool anyMarked = FALSE;
Carlos Lopez a09598
        void (* MarkWindow)() = pScreen->MarkWindow;
Carlos Lopez a09598
Carlos Lopez a09598
        RL_DEBUG_MSG("is top level! ");
Carlos Lopez a09598
        /* single layered systems are easy */
Carlos Lopez a09598
        if (ppLayerWin) *ppLayerWin = pWin;
Carlos Lopez a09598
Carlos Lopez a09598
        if (pWin == pFirst) {
Carlos Lopez a09598
            /* Blindly mark pWin and all of its inferiors.   This is a slight
Carlos Lopez a09598
            * overkill if there are mapped windows that outside pWin's border,
Carlos Lopez a09598
            * but it's better than wasting time on RectIn checks.
Carlos Lopez a09598
            */
Carlos Lopez a09598
            pChild = pWin;
Carlos Lopez a09598
            while (1) {
Carlos Lopez a09598
                if (pChild->viewable) {
Carlos Lopez a09598
                    if (REGION_BROKEN (pScreen, &pChild->winSize))
Carlos Lopez a09598
                        SetWinSize (pChild);
Carlos Lopez a09598
                    if (REGION_BROKEN (pScreen, &pChild->borderSize))
Carlos Lopez a09598
                        SetBorderSize (pChild);
Carlos Lopez a09598
                    (* MarkWindow)(pChild);
Carlos Lopez a09598
                    if (pChild->firstChild) {
Carlos Lopez a09598
                        pChild = pChild->firstChild;
Carlos Lopez a09598
                        continue;
Carlos Lopez a09598
                    }
Carlos Lopez a09598
                }
Carlos Lopez a09598
                while (!pChild->nextSib && (pChild != pWin))
Carlos Lopez a09598
                    pChild = pChild->parent;
Carlos Lopez a09598
                if (pChild == pWin)
Carlos Lopez a09598
                    break;
Carlos Lopez a09598
                pChild = pChild->nextSib;
Carlos Lopez a09598
            }
Carlos Lopez a09598
            anyMarked = TRUE;
Carlos Lopez a09598
            pFirst = pFirst->nextSib;
Carlos Lopez a09598
        }
Carlos Lopez a09598
        if (anyMarked)
Carlos Lopez a09598
            (* MarkWindow)(pWin->parent);
Carlos Lopez a09598
        result = anyMarked;
Carlos Lopez a09598
    }
Carlos Lopez a09598
    NORMAL_ROOT(pWin);
Carlos Lopez a09598
    SCREEN_WRAP(pScreen, MarkOverlappedWindows);
Carlos Lopez a09598
    RL_DEBUG_MSG("MARKOVERLAPPEDWINDOWS end\n");
Carlos Lopez a09598
    return result;
Carlos Lopez a09598
}
Carlos Lopez a09598
Carlos Lopez a09598
static void
Carlos Lopez a09598
expose_1 (WindowPtr pWin)
Carlos Lopez a09598
{
Carlos Lopez a09598
    WindowPtr pChild;
Carlos Lopez a09598
Carlos Lopez a09598
    if (!pWin->realized)
Carlos Lopez a09598
	return;
Carlos Lopez a09598
Carlos Lopez a09598
    (*pWin->drawable.pScreen->PaintWindowBackground) (pWin, &pWin->borderClip,
Carlos Lopez a09598
						      PW_BACKGROUND);
Carlos Lopez a09598
Carlos Lopez a09598
    /* FIXME: comments in windowstr.h indicate that borderClip doesn't
Carlos Lopez a09598
       include subwindow visibility. But I'm not so sure.. so we may
Carlos Lopez a09598
       be exposing too much.. */
Carlos Lopez a09598
Carlos Lopez a09598
    miSendExposures (pWin, &pWin->borderClip,
Carlos Lopez a09598
		     pWin->drawable.x, pWin->drawable.y);
Carlos Lopez a09598
Carlos Lopez a09598
    for (pChild = pWin->firstChild; pChild != NULL; pChild = pChild->nextSib)
Carlos Lopez a09598
	expose_1 (pChild);
Carlos Lopez a09598
}
Carlos Lopez a09598
Carlos Lopez a09598
void
Carlos Lopez a09598
RootlessScreenExpose (ScreenPtr pScreen)
Carlos Lopez a09598
{
Carlos Lopez a09598
    expose_1 (WindowTable[pScreen->myNum]);
Carlos Lopez a09598
}
Carlos Lopez a09598
Carlos Lopez a09598
ColormapPtr
Carlos Lopez a09598
RootlessGetColormap (ScreenPtr pScreen)
Carlos Lopez a09598
{
Carlos Lopez a09598
    RootlessScreenRec *s = SCREENREC (pScreen);
Carlos Lopez a09598
Carlos Lopez a09598
    return s->colormap;
Carlos Lopez a09598
}
Carlos Lopez a09598
Carlos Lopez a09598
static void
Carlos Lopez a09598
RootlessInstallColormap (ColormapPtr pMap)
Carlos Lopez a09598
{
Carlos Lopez a09598
    ScreenPtr pScreen = pMap->pScreen;
Carlos Lopez a09598
    RootlessScreenRec *s = SCREENREC (pScreen);
Carlos Lopez a09598
Carlos Lopez a09598
    SCREEN_UNWRAP(pScreen, InstallColormap);
Carlos Lopez a09598
Carlos Lopez a09598
    if (s->colormap != pMap)
Carlos Lopez a09598
    {
Carlos Lopez a09598
	s->colormap = pMap;
Carlos Lopez a09598
	s->colormap_changed = TRUE;
Carlos Lopez a09598
	RootlessQueueRedisplay (pScreen);
Carlos Lopez a09598
    }
Carlos Lopez a09598
Carlos Lopez a09598
    pScreen->InstallColormap (pMap);
Carlos Lopez a09598
Carlos Lopez a09598
    SCREEN_WRAP (pScreen, InstallColormap);
Carlos Lopez a09598
}
Carlos Lopez a09598
Carlos Lopez a09598
static void
Carlos Lopez a09598
RootlessUninstallColormap (ColormapPtr pMap)
Carlos Lopez a09598
{
Carlos Lopez a09598
    ScreenPtr pScreen = pMap->pScreen;
Carlos Lopez a09598
    RootlessScreenRec *s = SCREENREC (pScreen);
Carlos Lopez a09598
Carlos Lopez a09598
    SCREEN_UNWRAP(pScreen, UninstallColormap);
Carlos Lopez a09598
Carlos Lopez a09598
    if (s->colormap == pMap)
Carlos Lopez a09598
	s->colormap = NULL;
Carlos Lopez a09598
Carlos Lopez a09598
    pScreen->UninstallColormap (pMap);
Carlos Lopez a09598
Carlos Lopez a09598
    SCREEN_WRAP(pScreen, UninstallColormap);
Carlos Lopez a09598
}
Carlos Lopez a09598
Carlos Lopez a09598
static void
Carlos Lopez a09598
RootlessStoreColors (ColormapPtr pMap, int ndef, xColorItem *pdef)
Carlos Lopez a09598
{
Carlos Lopez a09598
    ScreenPtr pScreen = pMap->pScreen;
Carlos Lopez a09598
    RootlessScreenRec *s = SCREENREC (pScreen);
Carlos Lopez a09598
Carlos Lopez a09598
    SCREEN_UNWRAP(pScreen, StoreColors);
Carlos Lopez a09598
Carlos Lopez a09598
    if (s->colormap == pMap && ndef > 0)
Carlos Lopez a09598
    {
Carlos Lopez a09598
	s->colormap_changed = TRUE;
Carlos Lopez a09598
	RootlessQueueRedisplay (pScreen);
Carlos Lopez a09598
    }
Carlos Lopez a09598
Carlos Lopez a09598
    pScreen->StoreColors (pMap, ndef, pdef);
Carlos Lopez a09598
Carlos Lopez a09598
    SCREEN_WRAP(pScreen, StoreColors);
Carlos Lopez a09598
}
Carlos Lopez a09598
Carlos Lopez a09598
static CARD32
Carlos Lopez a09598
redisplay_callback (OsTimerPtr timer, CARD32 time, void *arg)
Carlos Lopez a09598
{
Carlos Lopez a09598
    RootlessScreenRec *screenRec = arg;
Carlos Lopez a09598
Carlos Lopez a09598
    if (!screenRec->redisplay_queued)
Carlos Lopez a09598
    {
Carlos Lopez a09598
	/* No update needed. Stop the timer. */
Carlos Lopez a09598
Carlos Lopez a09598
	screenRec->redisplay_timer_set = FALSE;
Carlos Lopez a09598
	return 0;
Carlos Lopez a09598
    }
Carlos Lopez a09598
Carlos Lopez a09598
    screenRec->redisplay_queued = FALSE;
Carlos Lopez a09598
Carlos Lopez a09598
    /* Mark that we should redisplay before waiting for I/O next time */
Carlos Lopez a09598
    screenRec->redisplay_expired = TRUE;
Carlos Lopez a09598
Carlos Lopez a09598
    /* Reinstall the timer immediately, so we get as close to our
Carlos Lopez a09598
       redisplay interval as possible. */
Carlos Lopez a09598
Carlos Lopez a09598
    return REDISPLAY_DELAY;
Carlos Lopez a09598
}
Carlos Lopez a09598
Carlos Lopez a09598
void
Carlos Lopez a09598
RootlessQueueRedisplay (ScreenPtr pScreen)
Carlos Lopez a09598
{
Carlos Lopez a09598
    RootlessScreenRec *screenRec = SCREENREC (pScreen);
Carlos Lopez a09598
Carlos Lopez a09598
    screenRec->redisplay_queued = TRUE;
Carlos Lopez a09598
Carlos Lopez a09598
    if (screenRec->redisplay_timer_set)
Carlos Lopez a09598
	return;
Carlos Lopez a09598
Carlos Lopez a09598
    screenRec->redisplay_timer = TimerSet (screenRec->redisplay_timer,
Carlos Lopez a09598
					   0, REDISPLAY_DELAY,
Carlos Lopez a09598
					   redisplay_callback, screenRec);
Carlos Lopez a09598
    screenRec->redisplay_timer_set = TRUE;
Carlos Lopez a09598
}
Carlos Lopez a09598
Carlos Lopez a09598
/* Call this function when it might be a good idea to flush updates.
Carlos Lopez a09598
   Note that it will unlock window buffers! */
Carlos Lopez a09598
Bool
Carlos Lopez a09598
RootlessMayRedisplay (ScreenPtr pScreen)
Carlos Lopez a09598
{
Carlos Lopez a09598
    RootlessScreenRec *screenRec = SCREENREC (pScreen);
Carlos Lopez a09598
Carlos Lopez a09598
    if (!screenRec->redisplay_queued)
Carlos Lopez a09598
	return FALSE;
Carlos Lopez a09598
Carlos Lopez a09598
    /* If the timer has fired, or it's been long enough since the last
Carlos Lopez a09598
       update, redisplay everything now. */
Carlos Lopez a09598
Carlos Lopez a09598
    if (!screenRec->redisplay_expired)
Carlos Lopez a09598
    {
Carlos Lopez a09598
	CARD32 now = GetTimeInMillis ();
Carlos Lopez a09598
Carlos Lopez a09598
	if (screenRec->last_redisplay + REDISPLAY_MAX_DELAY >= now)
Carlos Lopez a09598
	    return FALSE;
Carlos Lopez a09598
    }
Carlos Lopez a09598
Carlos Lopez a09598
    if (screenRec->redisplay_timer_set)
Carlos Lopez a09598
    {
Carlos Lopez a09598
	TimerCancel (screenRec->redisplay_timer);
Carlos Lopez a09598
	screenRec->redisplay_timer_set = FALSE;
Carlos Lopez a09598
    }
Carlos Lopez a09598
Carlos Lopez a09598
    RootlessRedisplayScreen (screenRec->pScreen);
Carlos Lopez a09598
    screenRec->redisplay_expired = FALSE;
Carlos Lopez a09598
Carlos Lopez a09598
    return TRUE;
Carlos Lopez a09598
}
Carlos Lopez a09598
Carlos Lopez a09598
/* Flush drawing before blocking on select(). */
Carlos Lopez a09598
static void
Carlos Lopez a09598
RootlessBlockHandler(pointer pbdata, OSTimePtr pTimeout, pointer pReadmask)
Carlos Lopez a09598
{
Carlos Lopez a09598
    ScreenPtr pScreen = pbdata;
Carlos Lopez a09598
    RootlessScreenRec *screenRec = SCREENREC (pScreen);
Carlos Lopez a09598
Carlos Lopez a09598
    if (screenRec->redisplay_expired)
Carlos Lopez a09598
    {
Carlos Lopez a09598
	screenRec->redisplay_expired = FALSE;
Carlos Lopez a09598
Carlos Lopez a09598
	if (screenRec->colormap_changed)
Carlos Lopez a09598
	{
Carlos Lopez a09598
	    RootlessFlushScreenColormaps (screenRec->pScreen);
Carlos Lopez a09598
	    screenRec->colormap_changed = FALSE;
Carlos Lopez a09598
	}
Carlos Lopez a09598
Carlos Lopez a09598
	RootlessRedisplayScreen (screenRec->pScreen);
Carlos Lopez a09598
    }
Carlos Lopez a09598
}
Carlos Lopez a09598
Carlos Lopez a09598
static void
Carlos Lopez a09598
RootlessWakeupHandler(pointer data, int i, pointer LastSelectMask)
Carlos Lopez a09598
{
Carlos Lopez a09598
}
Carlos Lopez a09598
Carlos Lopez a09598
static Bool
Carlos Lopez a09598
RootlessAllocatePrivates(ScreenPtr pScreen)
Carlos Lopez a09598
{
Carlos Lopez a09598
    RootlessScreenRec *s;
Carlos Lopez a09598
    static unsigned int rootlessGeneration = -1;
Carlos Lopez a09598
Carlos Lopez a09598
    if (rootlessGeneration != serverGeneration) {
Carlos Lopez a09598
        rootlessScreenPrivateIndex = AllocateScreenPrivateIndex();
Carlos Lopez a09598
        if (rootlessScreenPrivateIndex == -1) return FALSE;
Carlos Lopez a09598
        rootlessGCPrivateIndex = AllocateGCPrivateIndex();
Carlos Lopez a09598
        if (rootlessGCPrivateIndex == -1) return FALSE;
Carlos Lopez a09598
        rootlessWindowPrivateIndex = AllocateWindowPrivateIndex();
Carlos Lopez a09598
        if (rootlessWindowPrivateIndex == -1) return FALSE;
Carlos Lopez a09598
        rootlessGeneration = serverGeneration;
Carlos Lopez a09598
    }
Carlos Lopez a09598
Carlos Lopez a09598
    /* no allocation needed for screen privates */
Carlos Lopez a09598
    if (!AllocateGCPrivate(pScreen, rootlessGCPrivateIndex,
Carlos Lopez a09598
                           sizeof(RootlessGCRec)))
Carlos Lopez a09598
        return FALSE;
Carlos Lopez a09598
    if (!AllocateWindowPrivate(pScreen, rootlessWindowPrivateIndex, 0))
Carlos Lopez a09598
        return FALSE;
Carlos Lopez a09598
Carlos Lopez a09598
    s = xalloc(sizeof(RootlessScreenRec));
Carlos Lopez a09598
    if (! s) return FALSE;
Carlos Lopez a09598
    SCREENREC(pScreen) = s;
Carlos Lopez a09598
Carlos Lopez a09598
    s->pixmap_data = NULL;
Carlos Lopez a09598
    s->pixmap_data_size = 0;
Carlos Lopez a09598
Carlos Lopez a09598
    s->redisplay_timer = NULL;
Carlos Lopez a09598
    s->redisplay_timer_set = FALSE;
Carlos Lopez a09598
Carlos Lopez a09598
    return TRUE;
Carlos Lopez a09598
}
Carlos Lopez a09598
Carlos Lopez a09598
static void
Carlos Lopez a09598
RootlessWrap(ScreenPtr pScreen)
Carlos Lopez a09598
{
Carlos Lopez a09598
    RootlessScreenRec *s = (RootlessScreenRec*)
Carlos Lopez a09598
            pScreen->devPrivates[rootlessScreenPrivateIndex].ptr;
Carlos Lopez a09598
Carlos Lopez a09598
#define WRAP(a) \
Carlos Lopez a09598
    if (pScreen->a) { \
Carlos Lopez a09598
        s->a = pScreen->a; \
Carlos Lopez a09598
    } else { \
Carlos Lopez a09598
        RL_DEBUG_MSG("null screen fn " #a "\n"); \
Carlos Lopez a09598
        s->a = NULL; \
Carlos Lopez a09598
    } \
Carlos Lopez a09598
    pScreen->a = Rootless##a
Carlos Lopez a09598
Carlos Lopez a09598
    WRAP(CreateScreenResources);
Carlos Lopez a09598
    WRAP(CloseScreen);
Carlos Lopez a09598
    WRAP(CreateGC);
Carlos Lopez a09598
    WRAP(PaintWindowBackground);
Carlos Lopez a09598
    WRAP(PaintWindowBorder);
Carlos Lopez a09598
    WRAP(CopyWindow);
Carlos Lopez a09598
    WRAP(GetImage);
Carlos Lopez a09598
    WRAP(SourceValidate);
Carlos Lopez a09598
    WRAP(CreateWindow);
Carlos Lopez a09598
    WRAP(DestroyWindow);
Carlos Lopez a09598
    WRAP(RealizeWindow);
Carlos Lopez a09598
    WRAP(UnrealizeWindow);
Carlos Lopez a09598
    WRAP(ReparentWindow);
Carlos Lopez a09598
    WRAP(MoveWindow);
Carlos Lopez a09598
    WRAP(PositionWindow);
Carlos Lopez a09598
    WRAP(ResizeWindow);
Carlos Lopez a09598
    WRAP(RestackWindow);
Carlos Lopez a09598
    WRAP(ChangeBorderWidth);
Carlos Lopez a09598
    WRAP(MarkOverlappedWindows);
Carlos Lopez a09598
    WRAP(ValidateTree);
Carlos Lopez a09598
    WRAP(ChangeWindowAttributes);
Carlos Lopez a09598
    WRAP(InstallColormap);
Carlos Lopez a09598
    WRAP(UninstallColormap);
Carlos Lopez a09598
    WRAP(StoreColors);
Carlos Lopez a09598
Carlos Lopez a09598
#ifdef SHAPE
Carlos Lopez a09598
    WRAP(SetShape);
Carlos Lopez a09598
#endif
Carlos Lopez a09598
Carlos Lopez a09598
#ifdef RENDER
Carlos Lopez a09598
    {
Carlos Lopez a09598
        /* Composite and Glyphs don't use normal screen wrapping */
Carlos Lopez a09598
        PictureScreenPtr ps = GetPictureScreen(pScreen);
Carlos Lopez a09598
        s->Composite = ps->Composite;
Carlos Lopez a09598
        ps->Composite = rootlessComposite;
Carlos Lopez a09598
        s->Glyphs = ps->Glyphs;
Carlos Lopez a09598
        ps->Glyphs = RootlessGlyphs;
Carlos Lopez a09598
    }
Carlos Lopez a09598
#endif
Carlos Lopez a09598
Carlos Lopez a09598
    // WRAP(ClearToBackground); fixme put this back? useful for shaped wins?
Carlos Lopez a09598
    // WRAP(RestoreAreas); fixme put this back?
Carlos Lopez a09598
Carlos Lopez a09598
#undef WRAP
Carlos Lopez a09598
}
Carlos Lopez a09598
Carlos Lopez a09598
Bool
Carlos Lopez a09598
RootlessSetupScreen(int index, ScreenPtr pScreen)
Carlos Lopez a09598
{
Carlos Lopez a09598
    RootlessScreenRec *s;
Carlos Lopez a09598
Carlos Lopez a09598
    /* Add replacements for fb screen functions */
Carlos Lopez a09598
    pScreen->PaintWindowBackground = RootlessPaintWindow;
Carlos Lopez a09598
    pScreen->PaintWindowBorder = RootlessPaintWindow;
Carlos Lopez a09598
Carlos Lopez a09598
#ifdef RENDER
Carlos Lopez a09598
    {
Carlos Lopez a09598
        PictureScreenPtr ps = GetPictureScreen(pScreen);
Carlos Lopez a09598
        ps->Composite = RootlessComposite;
Carlos Lopez a09598
    }
Carlos Lopez a09598
#endif
Carlos Lopez a09598
Carlos Lopez a09598
    if (!RootlessAllocatePrivates(pScreen))
Carlos Lopez a09598
	return FALSE;
Carlos Lopez a09598
Carlos Lopez a09598
    s = ((RootlessScreenRec*)
Carlos Lopez a09598
	 pScreen->devPrivates[rootlessScreenPrivateIndex].ptr);
Carlos Lopez a09598
Carlos Lopez a09598
    s->pScreen = pScreen;
Carlos Lopez a09598
    RootlessWrap(pScreen);
Carlos Lopez a09598
Carlos Lopez a09598
    if (!RegisterBlockAndWakeupHandlers (RootlessBlockHandler,
Carlos Lopez a09598
                                         RootlessWakeupHandler,
Carlos Lopez a09598
                                         (pointer) pScreen))
Carlos Lopez a09598
    {
Carlos Lopez a09598
        return FALSE;
Carlos Lopez a09598
    }
Carlos Lopez a09598
Carlos Lopez a09598
    return TRUE;
Carlos Lopez a09598
}
Carlos Lopez a09598
Carlos Lopez a09598
void
Carlos Lopez a09598
RootlessUpdateRooted (Bool state)
Carlos Lopez a09598
{
Carlos Lopez a09598
    int i;
Carlos Lopez a09598
Carlos Lopez a09598
    if (!state)
Carlos Lopez a09598
    {
Carlos Lopez a09598
	for (i = 0; i < screenInfo.numScreens; i++)
Carlos Lopez a09598
	    RootlessDisableRoot (screenInfo.screens[i]);
Carlos Lopez a09598
    }
Carlos Lopez a09598
    else
Carlos Lopez a09598
    {
Carlos Lopez a09598
	for (i = 0; i < screenInfo.numScreens; i++)
Carlos Lopez a09598
	    RootlessEnableRoot (screenInfo.screens[i]);
Carlos Lopez a09598
    }
Carlos Lopez a09598
}