mirror of
https://github.com/X11Libre/xserver.git
synced 2026-09-25 21:02:21 +00:00
Initial revision
This commit is contained in:
parent
d461855a73
commit
90f1536dd3
91 changed files with 27196 additions and 0 deletions
135
miext/rootless/accel/rlAccel.h
Normal file
135
miext/rootless/accel/rlAccel.h
Normal file
|
|
@ -0,0 +1,135 @@
|
|||
/*
|
||||
* Rootless Acceleration Code
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 2003 Torrey T. Lyons. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* Except as contained in this notice, the name(s) of the above copyright
|
||||
* holders shall not be used in advertising or otherwise to promote the sale,
|
||||
* use or other dealings in this Software without prior written authorization.
|
||||
*/
|
||||
/* $XFree86: xc/programs/Xserver/miext/rootless/accel/rlAccel.h,v 1.1 2003/10/24 00:33:15 torrey Exp $ */
|
||||
|
||||
/*
|
||||
* rlBlt.c
|
||||
*/
|
||||
void
|
||||
rlBlt (FbBits *srcLine,
|
||||
FbStride srcStride,
|
||||
int srcX,
|
||||
|
||||
ScreenPtr pDstScreen,
|
||||
FbBits *dstLine,
|
||||
FbStride dstStride,
|
||||
int dstX,
|
||||
|
||||
int width,
|
||||
int height,
|
||||
|
||||
int alu,
|
||||
FbBits pm,
|
||||
int bpp,
|
||||
|
||||
Bool reverse,
|
||||
Bool upsidedown);
|
||||
|
||||
/*
|
||||
* rlCopy.c
|
||||
*/
|
||||
RegionPtr
|
||||
rlCopyArea (DrawablePtr pSrcDrawable,
|
||||
DrawablePtr pDstDrawable,
|
||||
GCPtr pGC,
|
||||
int xIn,
|
||||
int yIn,
|
||||
int widthSrc,
|
||||
int heightSrc,
|
||||
int xOut,
|
||||
int yOut);
|
||||
|
||||
/*
|
||||
* rlFill.c
|
||||
*/
|
||||
void
|
||||
rlFill (DrawablePtr pDrawable,
|
||||
GCPtr pGC,
|
||||
int x,
|
||||
int y,
|
||||
int width,
|
||||
int height);
|
||||
|
||||
void
|
||||
rlSolidBoxClipped (DrawablePtr pDrawable,
|
||||
RegionPtr pClip,
|
||||
int x1,
|
||||
int y1,
|
||||
int x2,
|
||||
int y2,
|
||||
FbBits and,
|
||||
FbBits xor);
|
||||
|
||||
/*
|
||||
* rlFillRect.c
|
||||
*/
|
||||
void
|
||||
rlPolyFillRect(DrawablePtr pDrawable,
|
||||
GCPtr pGC,
|
||||
int nrect,
|
||||
xRectangle *prect);
|
||||
|
||||
/*
|
||||
* rlFillSpans.c
|
||||
*/
|
||||
void
|
||||
rlFillSpans (DrawablePtr pDrawable,
|
||||
GCPtr pGC,
|
||||
int n,
|
||||
DDXPointPtr ppt,
|
||||
int *pwidth,
|
||||
int fSorted);
|
||||
|
||||
/*
|
||||
* rlGlyph.c
|
||||
*/
|
||||
void
|
||||
rlImageGlyphBlt (DrawablePtr pDrawable,
|
||||
GCPtr pGC,
|
||||
int x,
|
||||
int y,
|
||||
unsigned int nglyph,
|
||||
CharInfoPtr *ppciInit,
|
||||
pointer pglyphBase);
|
||||
|
||||
/*
|
||||
* rlSolid.c
|
||||
*/
|
||||
void
|
||||
rlSolid (ScreenPtr pScreen,
|
||||
FbBits *dst,
|
||||
FbStride dstStride,
|
||||
int dstX,
|
||||
int bpp,
|
||||
|
||||
int width,
|
||||
int height,
|
||||
|
||||
FbBits and,
|
||||
FbBits xor);
|
||||
366
miext/rootless/accel/rlBlt.c
Normal file
366
miext/rootless/accel/rlBlt.c
Normal file
|
|
@ -0,0 +1,366 @@
|
|||
/*
|
||||
* Accelerated rootless blit
|
||||
*/
|
||||
/*
|
||||
* This code is largely copied from fbBlt.c.
|
||||
*
|
||||
* Copyright © 1998 Keith Packard
|
||||
* Copyright (c) 2002 Apple Computer, Inc. All Rights Reserved.
|
||||
* Copyright (c) 2003 Torrey T. Lyons. 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 Keith Packard not be used in
|
||||
* advertising or publicity pertaining to distribution of the software without
|
||||
* specific, written prior permission. Keith Packard makes no
|
||||
* representations about the suitability of this software for any purpose. It
|
||||
* is provided "as is" without express or implied warranty.
|
||||
*
|
||||
* KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
||||
* EVENT SHALL KEITH PACKARD 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.
|
||||
*/
|
||||
/* $XFree86: xc/programs/Xserver/miext/rootless/accel/rlBlt.c,v 1.1 2003/10/24 00:33:15 torrey Exp $ */
|
||||
|
||||
#include "fb.h"
|
||||
#include "rootlessCommon.h"
|
||||
#include "rlAccel.h"
|
||||
|
||||
|
||||
void
|
||||
rlBlt (FbBits *srcLine,
|
||||
FbStride srcStride,
|
||||
int srcX,
|
||||
|
||||
ScreenPtr pDstScreen,
|
||||
FbBits *dstLine,
|
||||
FbStride dstStride,
|
||||
int dstX,
|
||||
|
||||
int width,
|
||||
int height,
|
||||
|
||||
int alu,
|
||||
FbBits pm,
|
||||
int bpp,
|
||||
|
||||
Bool reverse,
|
||||
Bool upsidedown)
|
||||
{
|
||||
FbBits *src, *dst;
|
||||
int leftShift, rightShift;
|
||||
FbBits startmask, endmask;
|
||||
FbBits bits, bits1;
|
||||
int n, nmiddle;
|
||||
Bool destInvarient;
|
||||
int startbyte, endbyte;
|
||||
FbDeclareMergeRop ();
|
||||
|
||||
#ifdef FB_24BIT
|
||||
if (bpp == 24 && !FbCheck24Pix (pm))
|
||||
{
|
||||
fbBlt24 (srcLine, srcStride, srcX, dstLine, dstStride, dstX,
|
||||
width, height, alu, pm, reverse, upsidedown);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
FbInitializeMergeRop(alu, pm);
|
||||
destInvarient = FbDestInvarientMergeRop();
|
||||
if (upsidedown)
|
||||
{
|
||||
srcLine += (height - 1) * (srcStride);
|
||||
dstLine += (height - 1) * (dstStride);
|
||||
srcStride = -srcStride;
|
||||
dstStride = -dstStride;
|
||||
}
|
||||
FbMaskBitsBytes (dstX, width, destInvarient, startmask, startbyte,
|
||||
nmiddle, endmask, endbyte);
|
||||
|
||||
/*
|
||||
* Beginning of the rootless acceleration code
|
||||
*/
|
||||
if (!startmask && !endmask && alu == GXcopy &&
|
||||
height * nmiddle * sizeof(*dst) > rootless_CopyBytes_threshold)
|
||||
{
|
||||
if (pm == FB_ALLONES && SCREENREC(pDstScreen)->imp->CopyBytes)
|
||||
{
|
||||
SCREENREC(pDstScreen)->imp->CopyBytes(
|
||||
nmiddle * sizeof(*dst), height,
|
||||
(char *) srcLine + (srcX >> 3),
|
||||
srcStride * sizeof (*src),
|
||||
(char *) dstLine + (dstX >> 3),
|
||||
dstStride * sizeof (*dst));
|
||||
return;
|
||||
}
|
||||
|
||||
/* FIXME: the pm test here isn't super-wonderful - just because
|
||||
we don't care about the top eight bits doesn't necessarily
|
||||
mean we want them set to 255. But doing this does give a
|
||||
factor of two performance improvement when copying from a
|
||||
pixmap to a window, which is pretty common.. */
|
||||
|
||||
else if (bpp == 32 && sizeof(FbBits) == 4 &&
|
||||
pm == 0x00FFFFFFUL && !reverse &&
|
||||
SCREENREC(pDstScreen)->imp->CompositePixels)
|
||||
{
|
||||
/* need to copy XRGB to ARGB. */
|
||||
|
||||
void *src[2], *dest[2];
|
||||
unsigned int src_rowbytes[2], dest_rowbytes[2];
|
||||
unsigned int fn;
|
||||
|
||||
src[0] = (char *) srcLine + (srcX >> 3);
|
||||
src[1] = NULL;
|
||||
src_rowbytes[0] = srcStride * sizeof(*src);
|
||||
src_rowbytes[1] = 0;
|
||||
|
||||
dest[0] = (char *) dstLine + (dstX >> 3);
|
||||
dest[1] = dest[0];
|
||||
dest_rowbytes[0] = dstStride * sizeof(*dst);
|
||||
dest_rowbytes[1] = dest_rowbytes[0];
|
||||
|
||||
fn = RL_COMPOSITE_FUNCTION(RL_COMPOSITE_SRC, RL_DEPTH_ARGB8888,
|
||||
RL_DEPTH_NIL, RL_DEPTH_ARGB8888);
|
||||
|
||||
if (SCREENREC(pDstScreen)->imp->CompositePixels(
|
||||
nmiddle, height,
|
||||
fn, src, src_rowbytes,
|
||||
NULL, 0, dest, dest_rowbytes) == Success)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* End of the rootless acceleration code */
|
||||
|
||||
if (reverse)
|
||||
{
|
||||
srcLine += ((srcX + width - 1) >> FB_SHIFT) + 1;
|
||||
dstLine += ((dstX + width - 1) >> FB_SHIFT) + 1;
|
||||
srcX = (srcX + width - 1) & FB_MASK;
|
||||
dstX = (dstX + width - 1) & FB_MASK;
|
||||
}
|
||||
else
|
||||
{
|
||||
srcLine += srcX >> FB_SHIFT;
|
||||
dstLine += dstX >> FB_SHIFT;
|
||||
srcX &= FB_MASK;
|
||||
dstX &= FB_MASK;
|
||||
}
|
||||
if (srcX == dstX)
|
||||
{
|
||||
while (height--)
|
||||
{
|
||||
src = srcLine;
|
||||
srcLine += srcStride;
|
||||
dst = dstLine;
|
||||
dstLine += dstStride;
|
||||
if (reverse)
|
||||
{
|
||||
if (endmask)
|
||||
{
|
||||
bits = *--src;
|
||||
--dst;
|
||||
FbDoRightMaskByteMergeRop(dst, bits, endbyte, endmask);
|
||||
}
|
||||
n = nmiddle;
|
||||
if (destInvarient)
|
||||
{
|
||||
while (n--)
|
||||
*--dst = FbDoDestInvarientMergeRop(*--src);
|
||||
}
|
||||
else
|
||||
{
|
||||
while (n--)
|
||||
{
|
||||
bits = *--src;
|
||||
--dst;
|
||||
*dst = FbDoMergeRop (bits, *dst);
|
||||
}
|
||||
}
|
||||
if (startmask)
|
||||
{
|
||||
bits = *--src;
|
||||
--dst;
|
||||
FbDoLeftMaskByteMergeRop(dst, bits, startbyte, startmask);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (startmask)
|
||||
{
|
||||
bits = *src++;
|
||||
FbDoLeftMaskByteMergeRop(dst, bits, startbyte, startmask);
|
||||
dst++;
|
||||
}
|
||||
n = nmiddle;
|
||||
if (destInvarient)
|
||||
{
|
||||
#if 0
|
||||
/*
|
||||
* This provides some speedup on screen->screen blts
|
||||
* over the PCI bus, usually about 10%. But fb
|
||||
* isn't usually used for this operation...
|
||||
*/
|
||||
if (_ca2 + 1 == 0 && _cx2 == 0)
|
||||
{
|
||||
FbBits t1, t2, t3, t4;
|
||||
while (n >= 4)
|
||||
{
|
||||
t1 = *src++;
|
||||
t2 = *src++;
|
||||
t3 = *src++;
|
||||
t4 = *src++;
|
||||
*dst++ = t1;
|
||||
*dst++ = t2;
|
||||
*dst++ = t3;
|
||||
*dst++ = t4;
|
||||
n -= 4;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
while (n--)
|
||||
*dst++ = FbDoDestInvarientMergeRop(*src++);
|
||||
}
|
||||
else
|
||||
{
|
||||
while (n--)
|
||||
{
|
||||
bits = *src++;
|
||||
*dst = FbDoMergeRop (bits, *dst);
|
||||
dst++;
|
||||
}
|
||||
}
|
||||
if (endmask)
|
||||
{
|
||||
bits = *src;
|
||||
FbDoRightMaskByteMergeRop(dst, bits, endbyte, endmask);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (srcX > dstX)
|
||||
{
|
||||
leftShift = srcX - dstX;
|
||||
rightShift = FB_UNIT - leftShift;
|
||||
}
|
||||
else
|
||||
{
|
||||
rightShift = dstX - srcX;
|
||||
leftShift = FB_UNIT - rightShift;
|
||||
}
|
||||
while (height--)
|
||||
{
|
||||
src = srcLine;
|
||||
srcLine += srcStride;
|
||||
dst = dstLine;
|
||||
dstLine += dstStride;
|
||||
|
||||
bits1 = 0;
|
||||
if (reverse)
|
||||
{
|
||||
if (srcX < dstX)
|
||||
bits1 = *--src;
|
||||
if (endmask)
|
||||
{
|
||||
bits = FbScrRight(bits1, rightShift);
|
||||
if (FbScrRight(endmask, leftShift))
|
||||
{
|
||||
bits1 = *--src;
|
||||
bits |= FbScrLeft(bits1, leftShift);
|
||||
}
|
||||
--dst;
|
||||
FbDoRightMaskByteMergeRop(dst, bits, endbyte, endmask);
|
||||
}
|
||||
n = nmiddle;
|
||||
if (destInvarient)
|
||||
{
|
||||
while (n--)
|
||||
{
|
||||
bits = FbScrRight(bits1, rightShift);
|
||||
bits1 = *--src;
|
||||
bits |= FbScrLeft(bits1, leftShift);
|
||||
--dst;
|
||||
*dst = FbDoDestInvarientMergeRop(bits);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
while (n--)
|
||||
{
|
||||
bits = FbScrRight(bits1, rightShift);
|
||||
bits1 = *--src;
|
||||
bits |= FbScrLeft(bits1, leftShift);
|
||||
--dst;
|
||||
*dst = FbDoMergeRop(bits, *dst);
|
||||
}
|
||||
}
|
||||
if (startmask)
|
||||
{
|
||||
bits = FbScrRight(bits1, rightShift);
|
||||
if (FbScrRight(startmask, leftShift))
|
||||
{
|
||||
bits1 = *--src;
|
||||
bits |= FbScrLeft(bits1, leftShift);
|
||||
}
|
||||
--dst;
|
||||
FbDoLeftMaskByteMergeRop (dst, bits, startbyte, startmask);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (srcX > dstX)
|
||||
bits1 = *src++;
|
||||
if (startmask)
|
||||
{
|
||||
bits = FbScrLeft(bits1, leftShift);
|
||||
bits1 = *src++;
|
||||
bits |= FbScrRight(bits1, rightShift);
|
||||
FbDoLeftMaskByteMergeRop (dst, bits, startbyte, startmask);
|
||||
dst++;
|
||||
}
|
||||
n = nmiddle;
|
||||
if (destInvarient)
|
||||
{
|
||||
while (n--)
|
||||
{
|
||||
bits = FbScrLeft(bits1, leftShift);
|
||||
bits1 = *src++;
|
||||
bits |= FbScrRight(bits1, rightShift);
|
||||
*dst = FbDoDestInvarientMergeRop(bits);
|
||||
dst++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
while (n--)
|
||||
{
|
||||
bits = FbScrLeft(bits1, leftShift);
|
||||
bits1 = *src++;
|
||||
bits |= FbScrRight(bits1, rightShift);
|
||||
*dst = FbDoMergeRop(bits, *dst);
|
||||
dst++;
|
||||
}
|
||||
}
|
||||
if (endmask)
|
||||
{
|
||||
bits = FbScrLeft(bits1, leftShift);
|
||||
if (FbScrLeft(endmask, rightShift))
|
||||
{
|
||||
bits1 = *src;
|
||||
bits |= FbScrRight(bits1, rightShift);
|
||||
}
|
||||
FbDoRightMaskByteMergeRop (dst, bits, endbyte, endmask);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
103
miext/rootless/accel/rlCopy.c
Normal file
103
miext/rootless/accel/rlCopy.c
Normal file
|
|
@ -0,0 +1,103 @@
|
|||
/*
|
||||
* This code is largely copied from fbcopy.c.
|
||||
*
|
||||
* Copyright © 1998 Keith Packard
|
||||
* Copyright (c) 2003 Torrey T. Lyons. 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 Keith Packard not be used in
|
||||
* advertising or publicity pertaining to distribution of the software without
|
||||
* specific, written prior permission. Keith Packard makes no
|
||||
* representations about the suitability of this software for any purpose. It
|
||||
* is provided "as is" without express or implied warranty.
|
||||
*
|
||||
* KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
||||
* EVENT SHALL KEITH PACKARD 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.
|
||||
*/
|
||||
/* $XFree86: xc/programs/Xserver/miext/rootless/accel/rlCopy.c,v 1.1 2003/10/24 00:33:15 torrey Exp $ */
|
||||
|
||||
#include "fb.h"
|
||||
#include "rlAccel.h"
|
||||
|
||||
|
||||
void
|
||||
rlCopyNtoN (DrawablePtr pSrcDrawable,
|
||||
DrawablePtr pDstDrawable,
|
||||
GCPtr pGC,
|
||||
BoxPtr pbox,
|
||||
int nbox,
|
||||
int dx,
|
||||
int dy,
|
||||
Bool reverse,
|
||||
Bool upsidedown,
|
||||
Pixel bitplane,
|
||||
void *closure)
|
||||
{
|
||||
CARD8 alu = pGC ? pGC->alu : GXcopy;
|
||||
FbBits pm = pGC ? fbGetGCPrivate(pGC)->pm : FB_ALLONES;
|
||||
FbBits *src;
|
||||
FbStride srcStride;
|
||||
int srcBpp;
|
||||
int srcXoff, srcYoff;
|
||||
FbBits *dst;
|
||||
FbStride dstStride;
|
||||
int dstBpp;
|
||||
int dstXoff, dstYoff;
|
||||
|
||||
fbGetDrawable (pSrcDrawable, src, srcStride, srcBpp, srcXoff, srcYoff);
|
||||
fbGetDrawable (pDstDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff);
|
||||
|
||||
while (nbox--)
|
||||
{
|
||||
rlBlt (src + (pbox->y1 + dy + srcYoff) * srcStride,
|
||||
srcStride,
|
||||
(pbox->x1 + dx + srcXoff) * srcBpp,
|
||||
|
||||
pDstDrawable->pScreen,
|
||||
dst + (pbox->y1 + dstYoff) * dstStride,
|
||||
dstStride,
|
||||
(pbox->x1 + dstXoff) * dstBpp,
|
||||
|
||||
(pbox->x2 - pbox->x1) * dstBpp,
|
||||
(pbox->y2 - pbox->y1),
|
||||
|
||||
alu,
|
||||
pm,
|
||||
dstBpp,
|
||||
|
||||
reverse,
|
||||
upsidedown);
|
||||
pbox++;
|
||||
}
|
||||
}
|
||||
|
||||
RegionPtr
|
||||
rlCopyArea (DrawablePtr pSrcDrawable,
|
||||
DrawablePtr pDstDrawable,
|
||||
GCPtr pGC,
|
||||
int xIn,
|
||||
int yIn,
|
||||
int widthSrc,
|
||||
int heightSrc,
|
||||
int xOut,
|
||||
int yOut)
|
||||
{
|
||||
fbCopyProc copy;
|
||||
|
||||
#ifdef FB_24_32BIT
|
||||
if (pSrcDrawable->bitsPerPixel != pDstDrawable->bitsPerPixel)
|
||||
copy = fb24_32CopyMtoN;
|
||||
else
|
||||
#endif
|
||||
copy = rlCopyNtoN;
|
||||
return fbDoCopy (pSrcDrawable, pDstDrawable, pGC, xIn, yIn,
|
||||
widthSrc, heightSrc, xOut, yOut, copy, 0, 0);
|
||||
}
|
||||
217
miext/rootless/accel/rlFill.c
Normal file
217
miext/rootless/accel/rlFill.c
Normal file
|
|
@ -0,0 +1,217 @@
|
|||
/*
|
||||
* This code is largely copied from fbfill.c.
|
||||
*
|
||||
* Copyright © 1998 Keith Packard
|
||||
* Copyright (c) 2003 Torrey T. Lyons. 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 Keith Packard not be used in
|
||||
* advertising or publicity pertaining to distribution of the software without
|
||||
* specific, written prior permission. Keith Packard makes no
|
||||
* representations about the suitability of this software for any purpose. It
|
||||
* is provided "as is" without express or implied warranty.
|
||||
*
|
||||
* KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
||||
* EVENT SHALL KEITH PACKARD 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.
|
||||
*/
|
||||
/* $XFree86: xc/programs/Xserver/miext/rootless/accel/rlFill.c,v 1.1 2003/10/24 00:33:15 torrey Exp $ */
|
||||
|
||||
#include "fb.h"
|
||||
#include "rlAccel.h"
|
||||
|
||||
|
||||
void
|
||||
rlFill (DrawablePtr pDrawable,
|
||||
GCPtr pGC,
|
||||
int x,
|
||||
int y,
|
||||
int width,
|
||||
int height)
|
||||
{
|
||||
FbBits *dst;
|
||||
FbStride dstStride;
|
||||
int dstBpp;
|
||||
int dstXoff, dstYoff;
|
||||
FbGCPrivPtr pPriv = fbGetGCPrivate(pGC);
|
||||
|
||||
fbGetDrawable (pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff);
|
||||
|
||||
switch (pGC->fillStyle) {
|
||||
case FillSolid:
|
||||
rlSolid (pDrawable->pScreen,
|
||||
dst + (y + dstYoff) * dstStride,
|
||||
dstStride,
|
||||
(x + dstXoff) * dstBpp,
|
||||
dstBpp,
|
||||
width * dstBpp, height,
|
||||
pPriv->and, pPriv->xor);
|
||||
break;
|
||||
case FillStippled:
|
||||
case FillOpaqueStippled: {
|
||||
PixmapPtr pStip = pGC->stipple;
|
||||
int stipWidth = pStip->drawable.width;
|
||||
int stipHeight = pStip->drawable.height;
|
||||
|
||||
if (dstBpp == 1)
|
||||
{
|
||||
int alu;
|
||||
FbBits *stip;
|
||||
FbStride stipStride;
|
||||
int stipBpp;
|
||||
int stipXoff, stipYoff; /* XXX assumed to be zero */
|
||||
|
||||
if (pGC->fillStyle == FillStippled)
|
||||
alu = FbStipple1Rop(pGC->alu,pGC->fgPixel);
|
||||
else
|
||||
alu = FbOpaqueStipple1Rop(pGC->alu,pGC->fgPixel,pGC->bgPixel);
|
||||
fbGetDrawable (&pStip->drawable, stip, stipStride, stipBpp, stipXoff, stipYoff);
|
||||
fbTile (dst + (y + dstYoff) * dstStride,
|
||||
dstStride,
|
||||
x + dstXoff,
|
||||
width, height,
|
||||
stip,
|
||||
stipStride,
|
||||
stipWidth,
|
||||
stipHeight,
|
||||
alu,
|
||||
pPriv->pm,
|
||||
dstBpp,
|
||||
|
||||
(pGC->patOrg.x + pDrawable->x + dstXoff),
|
||||
pGC->patOrg.y + pDrawable->y + dstYoff - y);
|
||||
}
|
||||
else
|
||||
{
|
||||
FbStip *stip;
|
||||
FbStride stipStride;
|
||||
int stipBpp;
|
||||
int stipXoff, stipYoff; /* XXX assumed to be zero */
|
||||
FbBits fgand, fgxor, bgand, bgxor;
|
||||
|
||||
fgand = pPriv->and;
|
||||
fgxor = pPriv->xor;
|
||||
if (pGC->fillStyle == FillStippled)
|
||||
{
|
||||
bgand = fbAnd(GXnoop,(FbBits) 0,FB_ALLONES);
|
||||
bgxor = fbXor(GXnoop,(FbBits) 0,FB_ALLONES);
|
||||
}
|
||||
else
|
||||
{
|
||||
bgand = pPriv->bgand;
|
||||
bgxor = pPriv->bgxor;
|
||||
}
|
||||
|
||||
fbGetStipDrawable (&pStip->drawable, stip, stipStride, stipBpp, stipXoff, stipYoff);
|
||||
fbStipple (dst + (y + dstYoff) * dstStride,
|
||||
dstStride,
|
||||
(x + dstXoff) * dstBpp,
|
||||
dstBpp,
|
||||
width * dstBpp, height,
|
||||
stip,
|
||||
stipStride,
|
||||
stipWidth,
|
||||
stipHeight,
|
||||
pPriv->evenStipple,
|
||||
fgand, fgxor,
|
||||
bgand, bgxor,
|
||||
pGC->patOrg.x + pDrawable->x + dstXoff,
|
||||
pGC->patOrg.y + pDrawable->y + dstYoff - y);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case FillTiled: {
|
||||
PixmapPtr pTile = pGC->tile.pixmap;
|
||||
FbBits *tile;
|
||||
FbStride tileStride;
|
||||
int tileBpp;
|
||||
int tileWidth;
|
||||
int tileHeight;
|
||||
int tileXoff, tileYoff; /* XXX assumed to be zero */
|
||||
|
||||
fbGetDrawable (&pTile->drawable, tile, tileStride, tileBpp, tileXoff, tileYoff);
|
||||
tileWidth = pTile->drawable.width;
|
||||
tileHeight = pTile->drawable.height;
|
||||
fbTile (dst + (y + dstYoff) * dstStride,
|
||||
dstStride,
|
||||
(x + dstXoff) * dstBpp,
|
||||
width * dstBpp, height,
|
||||
tile,
|
||||
tileStride,
|
||||
tileWidth * tileBpp,
|
||||
tileHeight,
|
||||
pGC->alu,
|
||||
pPriv->pm,
|
||||
dstBpp,
|
||||
(pGC->patOrg.x + pDrawable->x + dstXoff) * dstBpp,
|
||||
pGC->patOrg.y + pDrawable->y + dstYoff - y);
|
||||
break;
|
||||
}
|
||||
}
|
||||
fbValidateDrawable (pDrawable);
|
||||
}
|
||||
|
||||
void
|
||||
rlSolidBoxClipped (DrawablePtr pDrawable,
|
||||
RegionPtr pClip,
|
||||
int x1,
|
||||
int y1,
|
||||
int x2,
|
||||
int y2,
|
||||
FbBits and,
|
||||
FbBits xor)
|
||||
{
|
||||
FbBits *dst;
|
||||
FbStride dstStride;
|
||||
int dstBpp;
|
||||
int dstXoff, dstYoff;
|
||||
BoxPtr pbox;
|
||||
int nbox;
|
||||
int partX1, partX2, partY1, partY2;
|
||||
|
||||
fbGetDrawable (pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff);
|
||||
|
||||
for (nbox = REGION_NUM_RECTS(pClip), pbox = REGION_RECTS(pClip);
|
||||
nbox--;
|
||||
pbox++)
|
||||
{
|
||||
partX1 = pbox->x1;
|
||||
if (partX1 < x1)
|
||||
partX1 = x1;
|
||||
|
||||
partX2 = pbox->x2;
|
||||
if (partX2 > x2)
|
||||
partX2 = x2;
|
||||
|
||||
if (partX2 <= partX1)
|
||||
continue;
|
||||
|
||||
partY1 = pbox->y1;
|
||||
if (partY1 < y1)
|
||||
partY1 = y1;
|
||||
|
||||
partY2 = pbox->y2;
|
||||
if (partY2 > y2)
|
||||
partY2 = y2;
|
||||
|
||||
if (partY2 <= partY1)
|
||||
continue;
|
||||
|
||||
rlSolid (pDrawable->pScreen,
|
||||
dst + (partY1 + dstYoff) * dstStride,
|
||||
dstStride,
|
||||
(partX1 + dstXoff) * dstBpp,
|
||||
dstBpp,
|
||||
|
||||
(partX2 - partX1) * dstBpp,
|
||||
(partY2 - partY1),
|
||||
and, xor);
|
||||
}
|
||||
}
|
||||
114
miext/rootless/accel/rlFillRect.c
Normal file
114
miext/rootless/accel/rlFillRect.c
Normal file
|
|
@ -0,0 +1,114 @@
|
|||
/*
|
||||
* This code is largely copied from fbfillrect.c.
|
||||
*
|
||||
* Copyright © 1998 Keith Packard
|
||||
* Copyright (c) 2003 Torrey T. Lyons. 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 Keith Packard not be used in
|
||||
* advertising or publicity pertaining to distribution of the software without
|
||||
* specific, written prior permission. Keith Packard makes no
|
||||
* representations about the suitability of this software for any purpose. It
|
||||
* is provided "as is" without express or implied warranty.
|
||||
*
|
||||
* KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
||||
* EVENT SHALL KEITH PACKARD 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.
|
||||
*/
|
||||
/* $XFree86: xc/programs/Xserver/miext/rootless/accel/rlFillRect.c,v 1.1 2003/10/24 00:33:15 torrey Exp $ */
|
||||
|
||||
#include "fb.h"
|
||||
#include "rlAccel.h"
|
||||
|
||||
|
||||
void
|
||||
rlPolyFillRect(DrawablePtr pDrawable,
|
||||
GCPtr pGC,
|
||||
int nrect,
|
||||
xRectangle *prect)
|
||||
{
|
||||
RegionPtr pClip = fbGetCompositeClip(pGC);
|
||||
register BoxPtr pbox;
|
||||
BoxPtr pextent;
|
||||
int extentX1, extentX2, extentY1, extentY2;
|
||||
int fullX1, fullX2, fullY1, fullY2;
|
||||
int partX1, partX2, partY1, partY2;
|
||||
int xorg, yorg;
|
||||
int n;
|
||||
|
||||
xorg = pDrawable->x;
|
||||
yorg = pDrawable->y;
|
||||
|
||||
pextent = REGION_EXTENTS(pGC->pScreen, pClip);
|
||||
extentX1 = pextent->x1;
|
||||
extentY1 = pextent->y1;
|
||||
extentX2 = pextent->x2;
|
||||
extentY2 = pextent->y2;
|
||||
while (nrect--)
|
||||
{
|
||||
fullX1 = prect->x + xorg;
|
||||
fullY1 = prect->y + yorg;
|
||||
fullX2 = fullX1 + (int) prect->width;
|
||||
fullY2 = fullY1 + (int) prect->height;
|
||||
prect++;
|
||||
|
||||
if (fullX1 < extentX1)
|
||||
fullX1 = extentX1;
|
||||
|
||||
if (fullY1 < extentY1)
|
||||
fullY1 = extentY1;
|
||||
|
||||
if (fullX2 > extentX2)
|
||||
fullX2 = extentX2;
|
||||
|
||||
if (fullY2 > extentY2)
|
||||
fullY2 = extentY2;
|
||||
|
||||
if ((fullX1 >= fullX2) || (fullY1 >= fullY2))
|
||||
continue;
|
||||
n = REGION_NUM_RECTS (pClip);
|
||||
if (n == 1)
|
||||
{
|
||||
rlFill (pDrawable,
|
||||
pGC,
|
||||
fullX1, fullY1, fullX2-fullX1, fullY2-fullY1);
|
||||
}
|
||||
else
|
||||
{
|
||||
pbox = REGION_RECTS(pClip);
|
||||
/*
|
||||
* clip the rectangle to each box in the clip region
|
||||
* this is logically equivalent to calling Intersect()
|
||||
*/
|
||||
while(n--)
|
||||
{
|
||||
partX1 = pbox->x1;
|
||||
if (partX1 < fullX1)
|
||||
partX1 = fullX1;
|
||||
partY1 = pbox->y1;
|
||||
if (partY1 < fullY1)
|
||||
partY1 = fullY1;
|
||||
partX2 = pbox->x2;
|
||||
if (partX2 > fullX2)
|
||||
partX2 = fullX2;
|
||||
partY2 = pbox->y2;
|
||||
if (partY2 > fullY2)
|
||||
partY2 = fullY2;
|
||||
|
||||
pbox++;
|
||||
|
||||
if (partX1 < partX2 && partY1 < partY2)
|
||||
rlFill (pDrawable, pGC,
|
||||
partX1, partY1,
|
||||
partX2 - partX1, partY2 - partY1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
102
miext/rootless/accel/rlFillSpans.c
Normal file
102
miext/rootless/accel/rlFillSpans.c
Normal file
|
|
@ -0,0 +1,102 @@
|
|||
/*
|
||||
* This code is largely copied from fbfillsp.c.
|
||||
*
|
||||
* Copyright © 1998 Keith Packard
|
||||
* Copyright (c) 2003 Torrey T. Lyons. 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 Keith Packard not be used in
|
||||
* advertising or publicity pertaining to distribution of the software without
|
||||
* specific, written prior permission. Keith Packard makes no
|
||||
* representations about the suitability of this software for any purpose. It
|
||||
* is provided "as is" without express or implied warranty.
|
||||
*
|
||||
* KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
||||
* EVENT SHALL KEITH PACKARD 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.
|
||||
*/
|
||||
/* $XFree86: xc/programs/Xserver/miext/rootless/accel/rlFillSpans.c,v 1.1 2003/10/24 00:33:15 torrey Exp $ */
|
||||
|
||||
#include "fb.h"
|
||||
#include "rlAccel.h"
|
||||
|
||||
|
||||
void
|
||||
rlFillSpans (DrawablePtr pDrawable,
|
||||
GCPtr pGC,
|
||||
int n,
|
||||
DDXPointPtr ppt,
|
||||
int *pwidth,
|
||||
int fSorted)
|
||||
{
|
||||
RegionPtr pClip = fbGetCompositeClip(pGC);
|
||||
BoxPtr pextent, pbox;
|
||||
int nbox;
|
||||
int extentX1, extentX2, extentY1, extentY2;
|
||||
int fullX1, fullX2, fullY1;
|
||||
int partX1, partX2;
|
||||
|
||||
pextent = REGION_EXTENTS(pGC->pScreen, pClip);
|
||||
extentX1 = pextent->x1;
|
||||
extentY1 = pextent->y1;
|
||||
extentX2 = pextent->x2;
|
||||
extentY2 = pextent->y2;
|
||||
while (n--)
|
||||
{
|
||||
fullX1 = ppt->x;
|
||||
fullY1 = ppt->y;
|
||||
fullX2 = fullX1 + (int) *pwidth;
|
||||
ppt++;
|
||||
pwidth++;
|
||||
|
||||
if (fullY1 < extentY1 || extentY2 <= fullY1)
|
||||
continue;
|
||||
|
||||
if (fullX1 < extentX1)
|
||||
fullX1 = extentX1;
|
||||
|
||||
if (fullX2 > extentX2)
|
||||
fullX2 = extentX2;
|
||||
|
||||
if (fullX1 >= fullX2)
|
||||
continue;
|
||||
|
||||
nbox = REGION_NUM_RECTS (pClip);
|
||||
if (nbox == 1)
|
||||
{
|
||||
rlFill (pDrawable,
|
||||
pGC,
|
||||
fullX1, fullY1, fullX2-fullX1, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
pbox = REGION_RECTS(pClip);
|
||||
while(nbox--)
|
||||
{
|
||||
if (pbox->y1 <= fullY1 && fullY1 < pbox->y2)
|
||||
{
|
||||
partX1 = pbox->x1;
|
||||
if (partX1 < fullX1)
|
||||
partX1 = fullX1;
|
||||
partX2 = pbox->x2;
|
||||
if (partX2 > fullX2)
|
||||
partX2 = fullX2;
|
||||
if (partX2 > partX1)
|
||||
{
|
||||
rlFill (pDrawable, pGC,
|
||||
partX1, fullY1,
|
||||
partX2 - partX1, 1);
|
||||
}
|
||||
}
|
||||
pbox++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
166
miext/rootless/accel/rlGlyph.c
Normal file
166
miext/rootless/accel/rlGlyph.c
Normal file
|
|
@ -0,0 +1,166 @@
|
|||
/*
|
||||
* This code is largely copied from fbglyph.c.
|
||||
*
|
||||
* Copyright © 1998 Keith Packard
|
||||
* Copyright (c) 2003 Torrey T. Lyons. 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 Keith Packard not be used in
|
||||
* advertising or publicity pertaining to distribution of the software without
|
||||
* specific, written prior permission. Keith Packard makes no
|
||||
* representations about the suitability of this software for any purpose. It
|
||||
* is provided "as is" without express or implied warranty.
|
||||
*
|
||||
* KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
||||
* EVENT SHALL KEITH PACKARD 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.
|
||||
*/
|
||||
/* $XFree86: xc/programs/Xserver/miext/rootless/accel/rlGlyph.c,v 1.1 2003/10/24 00:33:15 torrey Exp $ */
|
||||
|
||||
#include "fb.h"
|
||||
#include "fontstruct.h"
|
||||
#include "dixfontstr.h"
|
||||
#include "rlAccel.h"
|
||||
|
||||
|
||||
void
|
||||
rlImageGlyphBlt (DrawablePtr pDrawable,
|
||||
GCPtr pGC,
|
||||
int x,
|
||||
int y,
|
||||
unsigned int nglyph,
|
||||
CharInfoPtr *ppciInit,
|
||||
pointer pglyphBase)
|
||||
{
|
||||
FbGCPrivPtr pPriv = fbGetGCPrivate(pGC);
|
||||
CharInfoPtr *ppci;
|
||||
CharInfoPtr pci;
|
||||
unsigned char *pglyph; /* pointer bits in glyph */
|
||||
int gWidth, gHeight; /* width and height of glyph */
|
||||
FbStride gStride; /* stride of glyph */
|
||||
Bool opaque;
|
||||
int n;
|
||||
int gx, gy;
|
||||
#ifndef FBNOPIXADDR
|
||||
void (*glyph) (FbBits *,
|
||||
FbStride,
|
||||
int,
|
||||
FbStip *,
|
||||
FbBits,
|
||||
int,
|
||||
int);
|
||||
FbBits *dst = 0;
|
||||
FbStride dstStride = 0;
|
||||
int dstBpp = 0;
|
||||
int dstXoff = 0, dstYoff = 0;
|
||||
|
||||
glyph = 0;
|
||||
if (pPriv->and == 0)
|
||||
{
|
||||
fbGetDrawable (pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff);
|
||||
switch (dstBpp) {
|
||||
case 8: glyph = fbGlyph8; break;
|
||||
case 16: glyph = fbGlyph16; break;
|
||||
#ifdef FB_24BIT
|
||||
case 24: glyph = fbGlyph24; break;
|
||||
#endif
|
||||
case 32: glyph = fbGlyph32; break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
x += pDrawable->x;
|
||||
y += pDrawable->y;
|
||||
|
||||
if (TERMINALFONT (pGC->font)
|
||||
#ifndef FBNOPIXADDR
|
||||
&& !glyph
|
||||
#endif
|
||||
)
|
||||
{
|
||||
opaque = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
int xBack, widthBack;
|
||||
int yBack, heightBack;
|
||||
|
||||
ppci = ppciInit;
|
||||
n = nglyph;
|
||||
widthBack = 0;
|
||||
while (n--)
|
||||
widthBack += (*ppci++)->metrics.characterWidth;
|
||||
|
||||
xBack = x;
|
||||
if (widthBack < 0)
|
||||
{
|
||||
xBack += widthBack;
|
||||
widthBack = -widthBack;
|
||||
}
|
||||
yBack = y - FONTASCENT(pGC->font);
|
||||
heightBack = FONTASCENT(pGC->font) + FONTDESCENT(pGC->font);
|
||||
rlSolidBoxClipped (pDrawable,
|
||||
fbGetCompositeClip(pGC),
|
||||
xBack,
|
||||
yBack,
|
||||
xBack + widthBack,
|
||||
yBack + heightBack,
|
||||
fbAnd(GXcopy,pPriv->bg,pPriv->pm),
|
||||
fbXor(GXcopy,pPriv->bg,pPriv->pm));
|
||||
opaque = FALSE;
|
||||
}
|
||||
|
||||
ppci = ppciInit;
|
||||
while (nglyph--)
|
||||
{
|
||||
pci = *ppci++;
|
||||
pglyph = FONTGLYPHBITS(pglyphBase, pci);
|
||||
gWidth = GLYPHWIDTHPIXELS(pci);
|
||||
gHeight = GLYPHHEIGHTPIXELS(pci);
|
||||
if (gWidth && gHeight)
|
||||
{
|
||||
gx = x + pci->metrics.leftSideBearing;
|
||||
gy = y - pci->metrics.ascent;
|
||||
#ifndef FBNOPIXADDR
|
||||
if (glyph && gWidth <= sizeof (FbStip) * 8 &&
|
||||
fbGlyphIn (fbGetCompositeClip(pGC), gx, gy, gWidth, gHeight))
|
||||
{
|
||||
(*glyph) (dst + (gy + dstYoff) * dstStride,
|
||||
dstStride,
|
||||
dstBpp,
|
||||
(FbStip *) pglyph,
|
||||
pPriv->fg,
|
||||
gx + dstXoff,
|
||||
gHeight);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
gStride = GLYPHWIDTHBYTESPADDED(pci) / sizeof (FbStip);
|
||||
fbPutXYImage (pDrawable,
|
||||
fbGetCompositeClip(pGC),
|
||||
pPriv->fg,
|
||||
pPriv->bg,
|
||||
pPriv->pm,
|
||||
GXcopy,
|
||||
opaque,
|
||||
|
||||
gx,
|
||||
gy,
|
||||
gWidth, gHeight,
|
||||
|
||||
(FbStip *) pglyph,
|
||||
gStride,
|
||||
0);
|
||||
}
|
||||
}
|
||||
x += pci->metrics.characterWidth;
|
||||
}
|
||||
}
|
||||
108
miext/rootless/accel/rlSolid.c
Normal file
108
miext/rootless/accel/rlSolid.c
Normal file
|
|
@ -0,0 +1,108 @@
|
|||
/*
|
||||
* Accelerated rootless fill
|
||||
*/
|
||||
/*
|
||||
* This code is largely copied from fbsolid.c.
|
||||
*
|
||||
* Copyright © 1998 Keith Packard
|
||||
* Copyright (c) 2002 Apple Computer, Inc. All Rights Reserved.
|
||||
* Copyright (c) 2003 Torrey T. Lyons. 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 Keith Packard not be used in
|
||||
* advertising or publicity pertaining to distribution of the software without
|
||||
* specific, written prior permission. Keith Packard makes no
|
||||
* representations about the suitability of this software for any purpose. It
|
||||
* is provided "as is" without express or implied warranty.
|
||||
*
|
||||
* KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
||||
* EVENT SHALL KEITH PACKARD 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.
|
||||
*/
|
||||
/* $XFree86: xc/programs/Xserver/miext/rootless/accel/rlSolid.c,v 1.1 2003/10/24 00:33:15 torrey Exp $ */
|
||||
|
||||
#include "fb.h"
|
||||
#include "rootlessCommon.h"
|
||||
|
||||
|
||||
void
|
||||
rlSolid (ScreenPtr pScreen,
|
||||
FbBits *dst,
|
||||
FbStride dstStride,
|
||||
int dstX,
|
||||
int bpp,
|
||||
|
||||
int width,
|
||||
int height,
|
||||
|
||||
FbBits and,
|
||||
FbBits xor)
|
||||
{
|
||||
FbBits startmask, endmask;
|
||||
int n, nmiddle;
|
||||
int startbyte, endbyte;
|
||||
|
||||
#ifdef FB_24BIT
|
||||
if (bpp == 24 && (!FbCheck24Pix(and) || !FbCheck24Pix(xor)))
|
||||
{
|
||||
fbSolid24 (dst, dstStride, dstX, width, height, and, xor);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
dst += dstX >> FB_SHIFT;
|
||||
dstX &= FB_MASK;
|
||||
FbMaskBitsBytes(dstX, width, and == 0, startmask, startbyte,
|
||||
nmiddle, endmask, endbyte);
|
||||
|
||||
/*
|
||||
* Beginning of the rootless acceleration code
|
||||
*/
|
||||
if (!startmask && !endmask && !and &&
|
||||
height * nmiddle * sizeof (*dst) > rootless_FillBytes_threshold &&
|
||||
SCREENREC(pScreen)->imp->FillBytes)
|
||||
{
|
||||
if (bpp <= 8)
|
||||
xor |= xor << 8;
|
||||
if (bpp <= 16)
|
||||
xor |= xor << 16;
|
||||
|
||||
SCREENREC(pScreen)->imp->FillBytes(nmiddle * sizeof (*dst), height,
|
||||
xor, (char *) dst + (dstX >> 3),
|
||||
dstStride * sizeof (*dst));
|
||||
return;
|
||||
}
|
||||
/* End of the rootless acceleration code */
|
||||
|
||||
if (startmask)
|
||||
dstStride--;
|
||||
dstStride -= nmiddle;
|
||||
while (height--)
|
||||
{
|
||||
if (startmask)
|
||||
{
|
||||
FbDoLeftMaskByteRRop(dst,startbyte,startmask,and,xor);
|
||||
dst++;
|
||||
}
|
||||
n = nmiddle;
|
||||
if (!and)
|
||||
while (n--)
|
||||
*dst++ = xor;
|
||||
else
|
||||
while (n--)
|
||||
{
|
||||
*dst = FbDoRRop (*dst, and, xor);
|
||||
dst++;
|
||||
}
|
||||
if (endmask)
|
||||
FbDoRightMaskByteRRop(dst,endbyte,endmask,and,xor);
|
||||
dst += dstStride;
|
||||
}
|
||||
}
|
||||
399
miext/rootless/rootless.h
Normal file
399
miext/rootless/rootless.h
Normal file
|
|
@ -0,0 +1,399 @@
|
|||
/*
|
||||
* External interface to generic rootless mode
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 2001 Greg Parker. All Rights Reserved.
|
||||
* Copyright (c) 2002-2003 Torrey T. Lyons. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* Except as contained in this notice, the name(s) of the above copyright
|
||||
* holders shall not be used in advertising or otherwise to promote the sale,
|
||||
* use or other dealings in this Software without prior written authorization.
|
||||
*/
|
||||
/* $XFree86: xc/programs/Xserver/miext/rootless/rootless.h,v 1.6 2003/10/24 00:33:14 torrey Exp $ */
|
||||
|
||||
#ifndef _ROOTLESS_H
|
||||
#define _ROOTLESS_H
|
||||
|
||||
#include "rootlessConfig.h"
|
||||
#include "mi.h"
|
||||
#include "gcstruct.h"
|
||||
|
||||
/*
|
||||
Each top-level rootless window has a one-to-one correspondence to a physical
|
||||
on-screen window. The physical window is refered to as a "frame".
|
||||
*/
|
||||
|
||||
typedef void * RootlessFrameID;
|
||||
|
||||
/*
|
||||
* RootlessWindowRec
|
||||
* This structure stores the per-frame data used by the rootless code.
|
||||
* Each top-level X window has one RootlessWindowRec associated with it.
|
||||
*/
|
||||
typedef struct _RootlessWindowRec {
|
||||
// Position and size includes the window border
|
||||
// Position is in per-screen coordinates
|
||||
int x, y;
|
||||
unsigned int width, height;
|
||||
unsigned int borderWidth;
|
||||
|
||||
RootlessFrameID wid; // implementation specific frame id
|
||||
WindowPtr win; // underlying X window
|
||||
|
||||
// Valid only when drawing (ie. is_drawing is set)
|
||||
char *pixelData;
|
||||
int bytesPerRow;
|
||||
|
||||
PixmapPtr pixmap;
|
||||
PixmapPtr oldPixmap;
|
||||
|
||||
#ifdef ROOTLESS_TRACK_DAMAGE
|
||||
RegionRec damage;
|
||||
#endif
|
||||
|
||||
unsigned int is_drawing :1; // Currently drawing?
|
||||
unsigned int is_reorder_pending :1;
|
||||
} RootlessWindowRec, *RootlessWindowPtr;
|
||||
|
||||
|
||||
/* Offset for screen-local to global coordinate transforms */
|
||||
#ifdef ROOTLESS_GLOBAL_COORDS
|
||||
extern int rootlessGlobalOffsetX;
|
||||
extern int rootlessGlobalOffsetY;
|
||||
#endif
|
||||
|
||||
/* The minimum number of bytes or pixels for which to use the
|
||||
implementation's accelerated functions. */
|
||||
extern unsigned int rootless_CopyBytes_threshold;
|
||||
extern unsigned int rootless_FillBytes_threshold;
|
||||
extern unsigned int rootless_CompositePixels_threshold;
|
||||
extern unsigned int rootless_CopyWindow_threshold;
|
||||
|
||||
/* Operations used by CompositePixels */
|
||||
enum rl_composite_op_enum {
|
||||
RL_COMPOSITE_SRC = 0,
|
||||
RL_COMPOSITE_OVER,
|
||||
};
|
||||
|
||||
/* Data formats for depth field and composite functions */
|
||||
enum rl_depth_enum {
|
||||
RL_DEPTH_NIL = 0, /* null source when compositing */
|
||||
RL_DEPTH_ARGB8888,
|
||||
RL_DEPTH_RGB555,
|
||||
RL_DEPTH_A8, /* for masks when compositing */
|
||||
RL_DEPTH_INDEX8,
|
||||
};
|
||||
|
||||
/* Macro to form the composite function for CompositePixels */
|
||||
#define RL_COMPOSITE_FUNCTION(op, src_depth, mask_depth, dest_depth) \
|
||||
(((op) << 24) | ((src_depth) << 16) \
|
||||
| ((mask_depth) << 8) | ((dest_depth) << 0))
|
||||
|
||||
/* Gravity for window contents during resizing */
|
||||
enum rl_gravity_enum {
|
||||
RL_GRAVITY_NONE = 0, /* no gravity, fill everything */
|
||||
RL_GRAVITY_NORTH_WEST = 1, /* anchor to top-left corner */
|
||||
RL_GRAVITY_NORTH_EAST = 2, /* anchor to top-right corner */
|
||||
RL_GRAVITY_SOUTH_EAST = 3, /* anchor to bottom-right corner */
|
||||
RL_GRAVITY_SOUTH_WEST = 4, /* anchor to bottom-left corner */
|
||||
};
|
||||
|
||||
|
||||
/*------------------------------------------
|
||||
Rootless Implementation Functions
|
||||
------------------------------------------*/
|
||||
|
||||
/*
|
||||
* Create a new frame.
|
||||
* The frame is created unmapped.
|
||||
*
|
||||
* pFrame RootlessWindowPtr for this frame should be completely
|
||||
* initialized before calling except for pFrame->wid, which
|
||||
* is set by this function.
|
||||
* pScreen Screen on which to place the new frame
|
||||
* newX, newY Position of the frame. These will be identical to pFrame-x,
|
||||
* pFrame->y unless ROOTLESS_GLOBAL_COORDS is set.
|
||||
* pNewShape Shape for the frame (in frame-local coordinates). NULL for
|
||||
* unshaped frames.
|
||||
*/
|
||||
typedef Bool (*RootlessCreateFrameProc)
|
||||
(RootlessWindowPtr pFrame, ScreenPtr pScreen, int newX, int newY,
|
||||
RegionPtr pNewShape);
|
||||
|
||||
/*
|
||||
* Destroy a frame.
|
||||
* Drawing is stopped and all updates are flushed before this is called.
|
||||
*
|
||||
* wid Frame id
|
||||
*/
|
||||
typedef void (*RootlessDestroyFrameProc)
|
||||
(RootlessFrameID wid);
|
||||
|
||||
/*
|
||||
* Move a frame on screen.
|
||||
* Drawing is stopped and all updates are flushed before this is called.
|
||||
*
|
||||
* wid Frame id
|
||||
* pScreen Screen to move the new frame to
|
||||
* newX, newY New position of the frame
|
||||
*/
|
||||
typedef void (*RootlessMoveFrameProc)
|
||||
(RootlessFrameID wid, ScreenPtr pScreen, int newX, int newY);
|
||||
|
||||
/*
|
||||
* Resize and move a frame.
|
||||
* Drawing is stopped and all updates are flushed before this is called.
|
||||
*
|
||||
* wid Frame id
|
||||
* pScreen Screen to move the new frame to
|
||||
* newX, newY New position of the frame
|
||||
* newW, newH New size of the frame
|
||||
* gravity Gravity for window contents (rl_gravity_enum). This is always
|
||||
* RL_GRAVITY_NONE unless ROOTLESS_RESIZE_GRAVITY is set.
|
||||
*/
|
||||
typedef void (*RootlessResizeFrameProc)
|
||||
(RootlessFrameID wid, ScreenPtr pScreen,
|
||||
int newX, int newY, unsigned int newW, unsigned int newH,
|
||||
unsigned int gravity);
|
||||
|
||||
/*
|
||||
* Change frame ordering (AKA stacking, layering).
|
||||
* Drawing is stopped before this is called. Unmapped frames are mapped by
|
||||
* setting their ordering.
|
||||
*
|
||||
* wid Frame id
|
||||
* nextWid Frame id of frame that is now above this one or NULL if this
|
||||
* frame is at the top.
|
||||
*/
|
||||
typedef void (*RootlessRestackFrameProc)
|
||||
(RootlessFrameID wid, RootlessFrameID nextWid);
|
||||
|
||||
/*
|
||||
* Change frame's shape.
|
||||
* Drawing is stopped before this is called.
|
||||
*
|
||||
* wid Frame id
|
||||
* pNewShape New shape for the frame (in frame-local coordinates)
|
||||
* or NULL if now unshaped.
|
||||
*/
|
||||
typedef void (*RootlessReshapeFrameProc)
|
||||
(RootlessFrameID wid, RegionPtr pNewShape);
|
||||
|
||||
/*
|
||||
* Unmap a frame.
|
||||
*
|
||||
* wid Frame id
|
||||
*/
|
||||
typedef void (*RootlessUnmapFrameProc)
|
||||
(RootlessFrameID wid);
|
||||
|
||||
/*
|
||||
* Start drawing to a frame.
|
||||
* Prepare a frame for direct access to its backing buffer.
|
||||
*
|
||||
* wid Frame id
|
||||
* pixelData Address of the backing buffer (returned)
|
||||
* bytesPerRow Width in bytes of the backing buffer (returned)
|
||||
*/
|
||||
typedef void (*RootlessStartDrawingProc)
|
||||
(RootlessFrameID wid, char **pixelData, int *bytesPerRow);
|
||||
|
||||
/*
|
||||
* Stop drawing to a frame.
|
||||
* No drawing to the frame's backing buffer will occur until drawing
|
||||
* is started again.
|
||||
*
|
||||
* wid Frame id
|
||||
* flush Flush drawing updates for this frame to the screen. This
|
||||
* will always be FALSE if ROOTLESS_TRACK_DAMAGE is set.
|
||||
*/
|
||||
typedef void (*RootlessStopDrawingProc)
|
||||
(RootlessFrameID wid, Bool flush);
|
||||
|
||||
/*
|
||||
* Flush drawing updates to the screen.
|
||||
* Drawing is stopped before this is called.
|
||||
*
|
||||
* wid Frame id
|
||||
* pDamage Region containing all the changed pixels in frame-lcoal
|
||||
* coordinates. This is clipped to the window's clip. This
|
||||
* will be NULL if ROOTLESS_TRACK_DAMAGE is not set.
|
||||
*/
|
||||
typedef void (*RootlessUpdateRegionProc)
|
||||
(RootlessFrameID wid, RegionPtr pDamage);
|
||||
|
||||
/*
|
||||
* Mark damaged rectangles as requiring redisplay to screen.
|
||||
* This will only be called if ROOTLESS_TRACK_DAMAGE is not set.
|
||||
*
|
||||
* wid Frame id
|
||||
* nrects Number of damaged rectangles
|
||||
* rects Array of damaged rectangles in frame-local coordinates
|
||||
* shift_x, Vector to shift rectangles by
|
||||
* shift_y
|
||||
*/
|
||||
typedef void (*RootlessDamageRectsProc)
|
||||
(RootlessFrameID wid, int nrects, const BoxRec *rects,
|
||||
int shift_x, int shift_y);
|
||||
|
||||
/*
|
||||
* Switch the window associated with a frame. (Optional)
|
||||
* When a framed window is reparented, the frame is resized and set to
|
||||
* use the new top-level parent. If defined this function will be called
|
||||
* afterwards for implementation specific bookkeeping.
|
||||
*
|
||||
* pFrame Frame whose window has switched
|
||||
* oldWin Previous window wrapped by this frame
|
||||
*/
|
||||
typedef void (*RootlessSwitchWindowProc)
|
||||
(RootlessWindowPtr pFrame, WindowPtr oldWin);
|
||||
|
||||
/*
|
||||
* Copy bytes. (Optional)
|
||||
* Source and destinate may overlap and the right thing should happen.
|
||||
*
|
||||
* width Bytes to copy per row
|
||||
* height Number of rows
|
||||
* src Source data
|
||||
* srcRowBytes Width of source in bytes
|
||||
* dst Destination data
|
||||
* dstRowBytes Width of destination in bytes
|
||||
*/
|
||||
typedef void (*RootlessCopyBytesProc)
|
||||
(unsigned int width, unsigned int height,
|
||||
const void *src, unsigned int srcRowBytes,
|
||||
void *dst, unsigned int dstRowBytes);
|
||||
|
||||
/*
|
||||
* Fill memory with 32-bit pattern. (Optional)
|
||||
*
|
||||
* width Bytes to fill per row
|
||||
* height Number of rows
|
||||
* value 32-bit pattern to fill with
|
||||
* dst Destination data
|
||||
* dstRowBytes Width of destination in bytes
|
||||
*/
|
||||
typedef void (*RootlessFillBytesProc)
|
||||
(unsigned int width, unsigned int height, unsigned int value,
|
||||
void *dst, unsigned int dstRowBytes);
|
||||
|
||||
/*
|
||||
* Composite pixels from source and mask to destination. (Optional)
|
||||
*
|
||||
* width, height Size of area to composite to in pizels
|
||||
* function Composite function built with RL_COMPOSITE_FUNCTION
|
||||
* src Source data
|
||||
* srcRowBytes Width of source in bytes (Passing NULL means source
|
||||
* is a single pixel.
|
||||
* mask Mask data
|
||||
* maskRowBytes Width of mask in bytes
|
||||
* dst Destination data
|
||||
* dstRowBytes Width of destination in bytes
|
||||
*
|
||||
* For src and dst, the first element of the array is the color data. If
|
||||
* the second element is non-null it implies there is alpha data (which
|
||||
* may be meshed or planar). Data without alpha is assumed to be opaque.
|
||||
*
|
||||
* An X11 error code is returned.
|
||||
*/
|
||||
typedef int (*RootlessCompositePixelsProc)
|
||||
(unsigned int width, unsigned int height, unsigned int function,
|
||||
void *src[2], unsigned int srcRowBytes[2],
|
||||
void *mask, unsigned int maskRowBytes,
|
||||
void *dst[2], unsigned int dstRowBytes[2]);
|
||||
|
||||
/*
|
||||
* Copy area in frame to another part of frame. (Optional)
|
||||
*
|
||||
* wid Frame id
|
||||
* dstNrects Number of rectangles to copy
|
||||
* dstRects Array of rectangles to copy
|
||||
* dx, dy Number of pixels away to copy area
|
||||
*/
|
||||
typedef void (*RootlessCopyWindowProc)
|
||||
(RootlessFrameID wid, int dstNrects, const BoxRec *dstRects,
|
||||
int dx, int dy);
|
||||
|
||||
/*
|
||||
* Rootless implementation function list
|
||||
*/
|
||||
typedef struct _RootlessFrameProcs {
|
||||
RootlessCreateFrameProc CreateFrame;
|
||||
RootlessDestroyFrameProc DestroyFrame;
|
||||
|
||||
RootlessMoveFrameProc MoveFrame;
|
||||
RootlessResizeFrameProc ResizeFrame;
|
||||
RootlessRestackFrameProc RestackFrame;
|
||||
RootlessReshapeFrameProc ReshapeFrame;
|
||||
RootlessUnmapFrameProc UnmapFrame;
|
||||
|
||||
RootlessStartDrawingProc StartDrawing;
|
||||
RootlessStopDrawingProc StopDrawing;
|
||||
RootlessUpdateRegionProc UpdateRegion;
|
||||
#ifndef ROOTLESS_TRACK_DAMAGE
|
||||
RootlessDamageRectsProc DamageRects;
|
||||
#endif
|
||||
|
||||
/* Optional frame functions */
|
||||
RootlessSwitchWindowProc SwitchWindow;
|
||||
|
||||
/* Optional acceleration functions */
|
||||
RootlessCopyBytesProc CopyBytes;
|
||||
RootlessFillBytesProc FillBytes;
|
||||
RootlessCompositePixelsProc CompositePixels;
|
||||
RootlessCopyWindowProc CopyWindow;
|
||||
} RootlessFrameProcsRec, *RootlessFrameProcsPtr;
|
||||
|
||||
|
||||
/*
|
||||
* Initialize rootless mode on the given screen.
|
||||
*/
|
||||
Bool RootlessInit(ScreenPtr pScreen, RootlessFrameProcsPtr procs);
|
||||
|
||||
/*
|
||||
* Return the frame ID for the physical window displaying the given window.
|
||||
*
|
||||
* create If true and the window has no frame, attempt to create one
|
||||
*/
|
||||
RootlessFrameID RootlessFrameForWindow(WindowPtr pWin, Bool create);
|
||||
|
||||
/*
|
||||
* Return the top-level parent of a window.
|
||||
* The root is the top-level parent of itself, even though the root is
|
||||
* not otherwise considered to be a top-level window.
|
||||
*/
|
||||
WindowPtr TopLevelParent(WindowPtr pWindow);
|
||||
|
||||
/*
|
||||
* Prepare a window for direct access to its backing buffer.
|
||||
*/
|
||||
void RootlessStartDrawing(WindowPtr pWindow);
|
||||
|
||||
/*
|
||||
* Finish drawing to a window's backing buffer.
|
||||
*
|
||||
* flush If true and ROOTLESS_TRACK_DAMAGE is set, damaged areas
|
||||
* are flushed to the screen.
|
||||
*/
|
||||
void RootlessStopDrawing(WindowPtr pWindow, Bool flush);
|
||||
|
||||
|
||||
#endif /* _ROOTLESS_H */
|
||||
380
miext/rootless/rootlessCommon.c
Normal file
380
miext/rootless/rootlessCommon.c
Normal file
|
|
@ -0,0 +1,380 @@
|
|||
/*
|
||||
* Common rootless definitions and code
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 2001 Greg Parker. All Rights Reserved.
|
||||
* Copyright (c) 2002-2003 Torrey T. Lyons. All Rights Reserved.
|
||||
* Copyright (c) 2002 Apple Computer, Inc. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* Except as contained in this notice, the name(s) of the above copyright
|
||||
* holders shall not be used in advertising or otherwise to promote the sale,
|
||||
* use or other dealings in this Software without prior written authorization.
|
||||
*/
|
||||
/* $XFree86: xc/programs/Xserver/miext/rootless/rootlessCommon.c,v 1.5 2003/11/10 18:22:50 tsi Exp $ */
|
||||
|
||||
#include "rootlessCommon.h"
|
||||
|
||||
unsigned int rootless_CopyBytes_threshold = 0;
|
||||
unsigned int rootless_FillBytes_threshold = 0;
|
||||
unsigned int rootless_CompositePixels_threshold = 0;
|
||||
unsigned int rootless_CopyWindow_threshold = 0;
|
||||
#ifdef ROOTLESS_GLOBAL_COORDS
|
||||
int rootlessGlobalOffsetX = 0;
|
||||
int rootlessGlobalOffsetY = 0;
|
||||
#endif
|
||||
|
||||
RegionRec rootlessHugeRoot = {{-32767, -32767, 32767, 32767}, NULL};
|
||||
|
||||
/* Following macro from miregion.c */
|
||||
|
||||
/* true iff two Boxes overlap */
|
||||
#define EXTENTCHECK(r1,r2) \
|
||||
(!( ((r1)->x2 <= (r2)->x1) || \
|
||||
((r1)->x1 >= (r2)->x2) || \
|
||||
((r1)->y2 <= (r2)->y1) || \
|
||||
((r1)->y1 >= (r2)->y2) ) )
|
||||
|
||||
|
||||
/*
|
||||
* TopLevelParent
|
||||
* Returns the top-level parent of pWindow.
|
||||
* The root is the top-level parent of itself, even though the root is
|
||||
* not otherwise considered to be a top-level window.
|
||||
*/
|
||||
WindowPtr
|
||||
TopLevelParent(WindowPtr pWindow)
|
||||
{
|
||||
WindowPtr top;
|
||||
|
||||
if (IsRoot(pWindow))
|
||||
return pWindow;
|
||||
|
||||
top = pWindow;
|
||||
while (top && ! IsTopLevel(top))
|
||||
top = top->parent;
|
||||
|
||||
return top;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* IsFramedWindow
|
||||
* Returns TRUE if this window is visible inside a frame
|
||||
* (e.g. it is visible and has a top-level or root parent)
|
||||
*/
|
||||
Bool
|
||||
IsFramedWindow(WindowPtr pWin)
|
||||
{
|
||||
WindowPtr top;
|
||||
|
||||
if (!pWin->realized)
|
||||
return FALSE;
|
||||
top = TopLevelParent(pWin);
|
||||
|
||||
return (top && WINREC(top));
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* RootlessStartDrawing
|
||||
* Prepare a window for direct access to its backing buffer.
|
||||
* Each top-level parent has a Pixmap representing its backing buffer,
|
||||
* which all of its children inherit.
|
||||
*/
|
||||
void RootlessStartDrawing(WindowPtr pWindow)
|
||||
{
|
||||
ScreenPtr pScreen = pWindow->drawable.pScreen;
|
||||
WindowPtr top = TopLevelParent(pWindow);
|
||||
RootlessWindowRec *winRec;
|
||||
|
||||
if (top == NULL)
|
||||
return;
|
||||
winRec = WINREC(top);
|
||||
if (winRec == NULL)
|
||||
return;
|
||||
|
||||
// Make sure the window's top-level parent is prepared for drawing.
|
||||
if (!winRec->is_drawing) {
|
||||
int bw = wBorderWidth(top);
|
||||
|
||||
SCREENREC(pScreen)->imp->StartDrawing(winRec->wid, &winRec->pixelData,
|
||||
&winRec->bytesPerRow);
|
||||
|
||||
winRec->pixmap =
|
||||
GetScratchPixmapHeader(pScreen, winRec->width, winRec->height,
|
||||
top->drawable.depth,
|
||||
top->drawable.bitsPerPixel,
|
||||
winRec->bytesPerRow,
|
||||
winRec->pixelData);
|
||||
SetPixmapBaseToScreen(winRec->pixmap,
|
||||
top->drawable.x - bw, top->drawable.y - bw);
|
||||
|
||||
winRec->is_drawing = TRUE;
|
||||
}
|
||||
|
||||
winRec->oldPixmap = pScreen->GetWindowPixmap(pWindow);
|
||||
pScreen->SetWindowPixmap(pWindow, winRec->pixmap);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* RootlessStopDrawing
|
||||
* Stop drawing to a window's backing buffer. If flush is true,
|
||||
* damaged regions are flushed to the screen.
|
||||
*/
|
||||
void RootlessStopDrawing(WindowPtr pWindow, Bool flush)
|
||||
{
|
||||
ScreenPtr pScreen = pWindow->drawable.pScreen;
|
||||
WindowPtr top = TopLevelParent(pWindow);
|
||||
RootlessWindowRec *winRec;
|
||||
|
||||
if (top == NULL)
|
||||
return;
|
||||
winRec = WINREC(top);
|
||||
if (winRec == NULL)
|
||||
return;
|
||||
|
||||
if (winRec->is_drawing) {
|
||||
SCREENREC(pScreen)->imp->StopDrawing(winRec->wid, flush);
|
||||
|
||||
FreeScratchPixmapHeader(winRec->pixmap);
|
||||
pScreen->SetWindowPixmap(pWindow, winRec->oldPixmap);
|
||||
winRec->pixmap = NULL;
|
||||
|
||||
winRec->is_drawing = FALSE;
|
||||
}
|
||||
else if (flush) {
|
||||
SCREENREC(pScreen)->imp->UpdateRegion(winRec->wid, NULL);
|
||||
}
|
||||
|
||||
if (flush && winRec->is_reorder_pending) {
|
||||
winRec->is_reorder_pending = FALSE;
|
||||
RootlessReorderWindow(pWindow);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* RootlessDamageRegion
|
||||
* Mark a damaged region as requiring redisplay to screen.
|
||||
* pRegion is in GLOBAL coordinates.
|
||||
*/
|
||||
void
|
||||
RootlessDamageRegion(WindowPtr pWindow, RegionPtr pRegion)
|
||||
{
|
||||
ScreenPtr pScreen = pWindow->drawable.pScreen;
|
||||
RootlessWindowRec *winRec;
|
||||
RegionRec clipped;
|
||||
WindowPtr pTop;
|
||||
BoxPtr b1, b2;
|
||||
|
||||
RL_DEBUG_MSG("Damaged win 0x%x ", pWindow);
|
||||
|
||||
pTop = TopLevelParent(pWindow);
|
||||
if (pTop == NULL)
|
||||
return;
|
||||
|
||||
winRec = WINREC(pTop);
|
||||
if (winRec == NULL)
|
||||
return;
|
||||
|
||||
/* We need to intersect the drawn region with the clip of the window
|
||||
to avoid marking places we didn't actually draw (which can cause
|
||||
problems when the window has an extra client-side backing store)
|
||||
|
||||
But this is a costly operation and since we'll normally just be
|
||||
drawing inside the clip, go to some lengths to avoid the general
|
||||
case intersection. */
|
||||
|
||||
b1 = REGION_EXTENTS(pScreen, &pWindow->borderClip);
|
||||
b2 = REGION_EXTENTS(pScreen, pRegion);
|
||||
|
||||
if (EXTENTCHECK(b1, b2)) {
|
||||
/* Regions may overlap. */
|
||||
|
||||
if (REGION_NUM_RECTS(pRegion) == 1) {
|
||||
int in;
|
||||
|
||||
/* Damaged region only has a single rect, so we can
|
||||
just compare that against the region */
|
||||
|
||||
in = RECT_IN_REGION(pScreen, &pWindow->borderClip,
|
||||
REGION_RECTS (pRegion));
|
||||
if (in == rgnIN) {
|
||||
/* clip totally contains pRegion */
|
||||
|
||||
#ifdef ROOTLESS_TRACK_DAMAGE
|
||||
REGION_UNION(pScreen, &winRec->damage,
|
||||
&winRec->damage, (pRegion));
|
||||
#else
|
||||
SCREENREC(pScreen)->imp->DamageRects(winRec->wid,
|
||||
REGION_NUM_RECTS(pRegion),
|
||||
REGION_RECTS(pRegion),
|
||||
-winRec->x, -winRec->y);
|
||||
#endif
|
||||
|
||||
RootlessQueueRedisplay(pTop->drawable.pScreen);
|
||||
goto out;
|
||||
}
|
||||
else if (in == rgnOUT) {
|
||||
/* clip doesn't contain pRegion */
|
||||
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
/* clip overlaps pRegion, need to intersect */
|
||||
|
||||
REGION_NULL(pScreen, &clipped);
|
||||
REGION_INTERSECT(pScreen, &clipped, &pWindow->borderClip, pRegion);
|
||||
|
||||
#ifdef ROOTLESS_TRACK_DAMAGE
|
||||
REGION_UNION(pScreen, &winRec->damage,
|
||||
&winRec->damage, (pRegion));
|
||||
#else
|
||||
SCREENREC(pScreen)->imp->DamageRects(winRec->wid,
|
||||
REGION_NUM_RECTS(&clipped),
|
||||
REGION_RECTS(&clipped),
|
||||
-winRec->x, -winRec->y);
|
||||
#endif
|
||||
|
||||
REGION_UNINIT(pScreen, &clipped);
|
||||
|
||||
RootlessQueueRedisplay(pTop->drawable.pScreen);
|
||||
}
|
||||
|
||||
out:
|
||||
#ifdef ROOTLESSDEBUG
|
||||
{
|
||||
BoxRec *box = REGION_RECTS(pRegion), *end;
|
||||
int numBox = REGION_NUM_RECTS(pRegion);
|
||||
|
||||
for (end = box+numBox; box < end; box++) {
|
||||
RL_DEBUG_MSG("Damage rect: %i, %i, %i, %i\n",
|
||||
box->x1, box->x2, box->y1, box->y2);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* RootlessDamageBox
|
||||
* Mark a damaged box as requiring redisplay to screen.
|
||||
* pRegion is in GLOBAL coordinates.
|
||||
*/
|
||||
void
|
||||
RootlessDamageBox(WindowPtr pWindow, BoxPtr pBox)
|
||||
{
|
||||
RegionRec region;
|
||||
|
||||
REGION_INIT(pWindow->drawable.pScreen, ®ion, pBox, 1);
|
||||
|
||||
RootlessDamageRegion(pWindow, ®ion);
|
||||
|
||||
REGION_UNINIT(pWindow->drawable.pScreen, ®ion); /* no-op */
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* RootlessDamageRect
|
||||
* Mark a damaged rectangle as requiring redisplay to screen.
|
||||
* (x, y, w, h) is in window-local coordinates.
|
||||
*/
|
||||
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);
|
||||
|
||||
REGION_UNINIT(pWindow->drawable.pScreen, ®ion); /* no-op */
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* RootlessRedisplay
|
||||
* Stop drawing and redisplay the damaged region of a window.
|
||||
*/
|
||||
void
|
||||
RootlessRedisplay(WindowPtr pWindow)
|
||||
{
|
||||
#ifdef ROOTLESS_TRACK_DAMAGE
|
||||
|
||||
RootlessWindowRec *winRec = WINREC(pWindow);
|
||||
ScreenPtr pScreen = pWindow->drawable.pScreen;
|
||||
|
||||
RootlessStopDrawing(pWindow, FALSE);
|
||||
|
||||
if (REGION_NOTEMPTY(pScreen, &winRec->damage)) {
|
||||
RL_DEBUG_MSG("Redisplay Win 0x%x, %i x %i @ (%i, %i)\n",
|
||||
pWindow, winRec->width, winRec->height,
|
||||
winRec->x, winRec->y);
|
||||
|
||||
// move region to window local coords
|
||||
REGION_TRANSLATE(pScreen, &winRec->damage,
|
||||
-winRec->x, -winRec->y);
|
||||
|
||||
SCREENREC(pScreen)->imp->UpdateRegion(winRec->wid, &winRec->damage);
|
||||
|
||||
REGION_EMPTY(pScreen, &winRec->damage);
|
||||
}
|
||||
|
||||
#else /* !ROOTLESS_TRACK_DAMAGE */
|
||||
|
||||
RootlessStopDrawing(pWindow, TRUE);
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* RootlessRedisplayScreen
|
||||
* Walk every window on a screen and redisplay the damaged regions.
|
||||
*/
|
||||
void
|
||||
RootlessRedisplayScreen(ScreenPtr pScreen)
|
||||
{
|
||||
WindowPtr root = WindowTable[pScreen->myNum];
|
||||
|
||||
if (root != NULL) {
|
||||
WindowPtr win;
|
||||
|
||||
RootlessRedisplay(root);
|
||||
for (win = root->firstChild; win; win = win->nextSib) {
|
||||
if (WINREC(win) != NULL) {
|
||||
RootlessRedisplay(win);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
254
miext/rootless/rootlessCommon.h
Normal file
254
miext/rootless/rootlessCommon.h
Normal file
|
|
@ -0,0 +1,254 @@
|
|||
/*
|
||||
* Common internal rootless definitions and code
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 2001 Greg Parker. All Rights Reserved.
|
||||
* Copyright (c) 2002-2003 Torrey T. Lyons. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* Except as contained in this notice, the name(s) of the above copyright
|
||||
* holders shall not be used in advertising or otherwise to promote the sale,
|
||||
* use or other dealings in this Software without prior written authorization.
|
||||
*/
|
||||
/* $XFree86: xc/programs/Xserver/miext/rootless/rootlessCommon.h,v 1.4 2003/09/16 00:36:20 torrey Exp $ */
|
||||
|
||||
#ifndef _ROOTLESSCOMMON_H
|
||||
#define _ROOTLESSCOMMON_H
|
||||
|
||||
#include "rootless.h"
|
||||
#include "fb.h"
|
||||
|
||||
#ifdef RENDER
|
||||
#include "picturestr.h"
|
||||
#endif
|
||||
|
||||
|
||||
// Debug output, or not.
|
||||
#ifdef ROOTLESSDEBUG
|
||||
#define RL_DEBUG_MSG ErrorF
|
||||
#else
|
||||
#define RL_DEBUG_MSG(a, ...)
|
||||
#endif
|
||||
|
||||
|
||||
// Global variables
|
||||
extern int rootlessGCPrivateIndex;
|
||||
extern int rootlessScreenPrivateIndex;
|
||||
extern int rootlessWindowPrivateIndex;
|
||||
|
||||
|
||||
// RootlessGCRec: private per-gc data
|
||||
typedef struct {
|
||||
GCFuncs *originalFuncs;
|
||||
GCOps *originalOps;
|
||||
} RootlessGCRec;
|
||||
|
||||
|
||||
// RootlessScreenRec: per-screen private data
|
||||
typedef struct _RootlessScreenRec {
|
||||
// Rootless implementation functions
|
||||
RootlessFrameProcsPtr imp;
|
||||
|
||||
// Wrapped screen functions
|
||||
CreateScreenResourcesProcPtr CreateScreenResources;
|
||||
CloseScreenProcPtr CloseScreen;
|
||||
|
||||
CreateWindowProcPtr CreateWindow;
|
||||
DestroyWindowProcPtr DestroyWindow;
|
||||
RealizeWindowProcPtr RealizeWindow;
|
||||
UnrealizeWindowProcPtr UnrealizeWindow;
|
||||
MoveWindowProcPtr MoveWindow;
|
||||
ResizeWindowProcPtr ResizeWindow;
|
||||
RestackWindowProcPtr RestackWindow;
|
||||
ReparentWindowProcPtr ReparentWindow;
|
||||
ChangeBorderWidthProcPtr ChangeBorderWidth;
|
||||
PositionWindowProcPtr PositionWindow;
|
||||
ChangeWindowAttributesProcPtr ChangeWindowAttributes;
|
||||
|
||||
CreateGCProcPtr CreateGC;
|
||||
PaintWindowBackgroundProcPtr PaintWindowBackground;
|
||||
PaintWindowBorderProcPtr PaintWindowBorder;
|
||||
CopyWindowProcPtr CopyWindow;
|
||||
GetImageProcPtr GetImage;
|
||||
SourceValidateProcPtr SourceValidate;
|
||||
|
||||
MarkOverlappedWindowsProcPtr MarkOverlappedWindows;
|
||||
ValidateTreeProcPtr ValidateTree;
|
||||
|
||||
#ifdef SHAPE
|
||||
SetShapeProcPtr SetShape;
|
||||
#endif
|
||||
|
||||
#ifdef RENDER
|
||||
CompositeProcPtr Composite;
|
||||
GlyphsProcPtr Glyphs;
|
||||
#endif
|
||||
|
||||
void *pixmap_data;
|
||||
unsigned int pixmap_data_size;
|
||||
|
||||
void *redisplay_timer;
|
||||
unsigned int redisplay_timer_set :1;
|
||||
unsigned int redisplay_queued :1;
|
||||
unsigned int redisplay_expired :1;
|
||||
} RootlessScreenRec, *RootlessScreenPtr;
|
||||
|
||||
|
||||
#undef MIN
|
||||
#define MIN(x,y) ((x) < (y) ? (x) : (y))
|
||||
#undef MAX
|
||||
#define MAX(x,y) ((x) > (y) ? (x) : (y))
|
||||
|
||||
// "Definition of the Porting Layer for the X11 Sample Server" says
|
||||
// unwrap and rewrap of screen functions is unnecessary, but
|
||||
// screen->CreateGC changes after a call to cfbCreateGC.
|
||||
|
||||
#define SCREEN_UNWRAP(screen, fn) \
|
||||
screen->fn = SCREENREC(screen)->fn;
|
||||
|
||||
#define SCREEN_WRAP(screen, fn) \
|
||||
SCREENREC(screen)->fn = screen->fn; \
|
||||
screen->fn = Rootless##fn
|
||||
|
||||
|
||||
// Accessors for screen and window privates
|
||||
|
||||
#define SCREENREC(pScreen) \
|
||||
((RootlessScreenRec *)(pScreen)->devPrivates[rootlessScreenPrivateIndex].ptr)
|
||||
|
||||
#define WINREC(pWin) \
|
||||
((RootlessWindowRec *)(pWin)->devPrivates[rootlessWindowPrivateIndex].ptr)
|
||||
|
||||
|
||||
// Call a rootless implementation function.
|
||||
// Many rootless implementation functions are allowed to be NULL.
|
||||
#define CallFrameProc(pScreen, proc, params) \
|
||||
if (SCREENREC(pScreen)->frameProcs.proc) { \
|
||||
RL_DEBUG_MSG("calling frame proc " #proc " "); \
|
||||
SCREENREC(pScreen)->frameProcs.proc params; \
|
||||
}
|
||||
|
||||
|
||||
// BoxRec manipulators
|
||||
// Copied from shadowfb
|
||||
|
||||
#define TRIM_BOX(box, pGC) { \
|
||||
BoxPtr extents = &pGC->pCompositeClip->extents;\
|
||||
if(box.x1 < extents->x1) box.x1 = extents->x1; \
|
||||
if(box.x2 > extents->x2) box.x2 = extents->x2; \
|
||||
if(box.y1 < extents->y1) box.y1 = extents->y1; \
|
||||
if(box.y2 > extents->y2) box.y2 = extents->y2; \
|
||||
}
|
||||
|
||||
#define TRANSLATE_BOX(box, pDraw) { \
|
||||
box.x1 += pDraw->x; \
|
||||
box.x2 += pDraw->x; \
|
||||
box.y1 += pDraw->y; \
|
||||
box.y2 += pDraw->y; \
|
||||
}
|
||||
|
||||
#define TRIM_AND_TRANSLATE_BOX(box, pDraw, pGC) { \
|
||||
TRANSLATE_BOX(box, pDraw); \
|
||||
TRIM_BOX(box, pGC); \
|
||||
}
|
||||
|
||||
#define BOX_NOT_EMPTY(box) \
|
||||
(((box.x2 - box.x1) > 0) && ((box.y2 - box.y1) > 0))
|
||||
|
||||
|
||||
// HUGE_ROOT and NORMAL_ROOT
|
||||
// We don't want to clip windows to the edge of the screen.
|
||||
// HUGE_ROOT temporarily makes the root window really big.
|
||||
// This is needed as a wrapper around any function that calls
|
||||
// SetWinSize or SetBorderSize which clip a window against its
|
||||
// parents, including the root.
|
||||
|
||||
extern RegionRec rootlessHugeRoot;
|
||||
|
||||
#define HUGE_ROOT(pWin) \
|
||||
do { \
|
||||
WindowPtr w = pWin; \
|
||||
while (w->parent) \
|
||||
w = w->parent; \
|
||||
saveRoot = w->winSize; \
|
||||
w->winSize = rootlessHugeRoot; \
|
||||
} while (0)
|
||||
|
||||
#define NORMAL_ROOT(pWin) \
|
||||
do { \
|
||||
WindowPtr w = pWin; \
|
||||
while (w->parent) \
|
||||
w = w->parent; \
|
||||
w->winSize = saveRoot; \
|
||||
} while (0)
|
||||
|
||||
|
||||
// Returns TRUE if this window is a top-level window (i.e. child of the root)
|
||||
// The root is not a top-level window.
|
||||
#define IsTopLevel(pWin) \
|
||||
((pWin) && (pWin)->parent && !(pWin)->parent->parent)
|
||||
|
||||
// Returns TRUE if this window is a root window
|
||||
#define IsRoot(pWin) \
|
||||
((pWin) == WindowTable[(pWin)->drawable.pScreen->myNum])
|
||||
|
||||
|
||||
/*
|
||||
* SetPixmapBaseToScreen
|
||||
* Move the given pixmap's base address to where pixel (0, 0)
|
||||
* would be if the pixmap's actual data started at (x, y).
|
||||
* Can't access the bits before the first word of the drawable's data in
|
||||
* rootless mode, so make sure our base address is always 32-bit aligned.
|
||||
*/
|
||||
#define SetPixmapBaseToScreen(pix, _x, _y) { \
|
||||
PixmapPtr _pPix = (PixmapPtr) (pix); \
|
||||
_pPix->devPrivate.ptr = (char *) (_pPix->devPrivate.ptr) - \
|
||||
((int)(_x) * _pPix->drawable.bitsPerPixel/8 + \
|
||||
(int)(_y) * _pPix->devKind); \
|
||||
if (_pPix->drawable.bitsPerPixel != FB_UNIT) { \
|
||||
unsigned _diff = ((unsigned) _pPix->devPrivate.ptr) & \
|
||||
(FB_UNIT / CHAR_BIT - 1); \
|
||||
_pPix->devPrivate.ptr = (char *) (_pPix->devPrivate.ptr) - \
|
||||
_diff; \
|
||||
_pPix->drawable.x = _diff / \
|
||||
(_pPix->drawable.bitsPerPixel / CHAR_BIT); \
|
||||
} \
|
||||
}
|
||||
|
||||
|
||||
// Returns TRUE if this window is visible inside a frame
|
||||
// (e.g. it is visible and has a top-level or root parent)
|
||||
Bool IsFramedWindow(WindowPtr pWin);
|
||||
|
||||
// Routines that cause regions to get redrawn.
|
||||
// DamageRegion and DamageRect are in global coordinates.
|
||||
// DamageBox is in window-local coordinates.
|
||||
void RootlessDamageRegion(WindowPtr pWindow, RegionPtr pRegion);
|
||||
void RootlessDamageRect(WindowPtr pWindow, int x, int y, int w, int h);
|
||||
void RootlessDamageBox(WindowPtr pWindow, BoxPtr pBox);
|
||||
void RootlessRedisplay(WindowPtr pWindow);
|
||||
void RootlessRedisplayScreen(ScreenPtr pScreen);
|
||||
|
||||
void RootlessQueueRedisplay (ScreenPtr pScreen);
|
||||
|
||||
// Move the window to it's correct place in the physical stacking order.
|
||||
void RootlessReorderWindow (WindowPtr pWin);
|
||||
|
||||
#endif /* _ROOTLESSCOMMON_H */
|
||||
50
miext/rootless/rootlessConfig.h
Normal file
50
miext/rootless/rootlessConfig.h
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* Platform specific rootless configuration
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 2003 Torrey T. Lyons. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* Except as contained in this notice, the name(s) of the above copyright
|
||||
* holders shall not be used in advertising or otherwise to promote the sale,
|
||||
* use or other dealings in this Software without prior written authorization.
|
||||
*/
|
||||
/* $XFree86: xc/programs/Xserver/miext/rootless/rootlessConfig.h,v 1.2 2003/10/24 00:33:14 torrey Exp $ */
|
||||
|
||||
#ifndef _ROOTLESSCONFIG_H
|
||||
#define _ROOTLESSCONFIG_H
|
||||
|
||||
#ifdef __DARWIN__
|
||||
|
||||
# define ROOTLESS_ACCEL TRUE
|
||||
# define ROOTLESS_GLOBAL_COORDS TRUE
|
||||
# define ROOTLESS_PROTECT_ALPHA TRUE
|
||||
# define ROOTLESS_REDISPLAY_DELAY 10
|
||||
# define ROOTLESS_RESIZE_GRAVITY TRUE
|
||||
# undef ROOTLESS_TRACK_DAMAGE
|
||||
|
||||
/* Bit mask for alpha channel with a particular number of bits per
|
||||
pixel. Note that we only care for 32bpp data. Mac OS X uses planar
|
||||
alpha for 16bpp. */
|
||||
# define RootlessAlphaMask(bpp) ((bpp) == 32 ? 0xFF000000 : 0)
|
||||
|
||||
#endif /* __DARWIN__ */
|
||||
|
||||
#endif /* _ROOTLESSCONFIG_H */
|
||||
1515
miext/rootless/rootlessGC.c
Normal file
1515
miext/rootless/rootlessGC.c
Normal file
File diff suppressed because it is too large
Load diff
666
miext/rootless/rootlessScreen.c
Normal file
666
miext/rootless/rootlessScreen.c
Normal file
|
|
@ -0,0 +1,666 @@
|
|||
/*
|
||||
* Screen routines for generic rootless X server
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 2001 Greg Parker. All Rights Reserved.
|
||||
* Copyright (c) 2002-2003 Torrey T. Lyons. All Rights Reserved.
|
||||
* Copyright (c) 2002 Apple Computer, Inc. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* Except as contained in this notice, the name(s) of the above copyright
|
||||
* holders shall not be used in advertising or otherwise to promote the sale,
|
||||
* use or other dealings in this Software without prior written authorization.
|
||||
*/
|
||||
/* $XFree86: xc/programs/Xserver/miext/rootless/rootlessScreen.c,v 1.3 2003/06/30 01:45:13 torrey Exp $ */
|
||||
|
||||
|
||||
#include "mi.h"
|
||||
#include "scrnintstr.h"
|
||||
#include "gcstruct.h"
|
||||
#include "pixmapstr.h"
|
||||
#include "windowstr.h"
|
||||
#include "propertyst.h"
|
||||
#include "mivalidate.h"
|
||||
#include "picturestr.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "rootlessCommon.h"
|
||||
#include "rootlessWindow.h"
|
||||
|
||||
/* In milliseconds */
|
||||
#ifndef ROOTLESS_REDISPLAY_DELAY
|
||||
#define ROOTLESS_REDISPLAY_DELAY 10
|
||||
#endif
|
||||
|
||||
extern int RootlessMiValidateTree(WindowPtr pRoot, WindowPtr pChild,
|
||||
VTKind kind);
|
||||
extern Bool RootlessCreateGC(GCPtr pGC);
|
||||
|
||||
// Initialize globals
|
||||
int rootlessGCPrivateIndex = -1;
|
||||
int rootlessScreenPrivateIndex = -1;
|
||||
int rootlessWindowPrivateIndex = -1;
|
||||
|
||||
|
||||
/*
|
||||
* RootlessUpdateScreenPixmap
|
||||
* miCreateScreenResources does not like a null framebuffer pointer,
|
||||
* it leaves the screen pixmap with an uninitialized data pointer.
|
||||
* Thus, rootless implementations typically set the framebuffer width
|
||||
* to zero so that miCreateScreenResources does not allocate a screen
|
||||
* pixmap for us. We allocate our own screen pixmap here since we need
|
||||
* the screen pixmap to be valid (e.g. CopyArea from the root window).
|
||||
*/
|
||||
void
|
||||
RootlessUpdateScreenPixmap(ScreenPtr pScreen)
|
||||
{
|
||||
RootlessScreenRec *s = SCREENREC(pScreen);
|
||||
PixmapPtr pPix;
|
||||
unsigned int rowbytes;
|
||||
|
||||
pPix = (*pScreen->GetScreenPixmap)(pScreen);
|
||||
if (pPix == NULL) {
|
||||
pPix = (*pScreen->CreatePixmap)(pScreen, 0, 0, pScreen->rootDepth);
|
||||
(*pScreen->SetScreenPixmap)(pPix);
|
||||
}
|
||||
|
||||
rowbytes = PixmapBytePad(pScreen->width, pScreen->rootDepth);
|
||||
|
||||
if (s->pixmap_data_size < rowbytes) {
|
||||
if (s->pixmap_data != NULL)
|
||||
xfree(s->pixmap_data);
|
||||
|
||||
s->pixmap_data_size = rowbytes;
|
||||
s->pixmap_data = xalloc(s->pixmap_data_size);
|
||||
if (s->pixmap_data == NULL)
|
||||
return;
|
||||
|
||||
memset(s->pixmap_data, 0xFF, s->pixmap_data_size);
|
||||
|
||||
pScreen->ModifyPixmapHeader(pPix, pScreen->width, pScreen->height,
|
||||
pScreen->rootDepth,
|
||||
BitsPerPixel(pScreen->rootDepth),
|
||||
0, s->pixmap_data);
|
||||
/* ModifyPixmapHeader ignores zero arguments, so install rowbytes
|
||||
by hand. */
|
||||
pPix->devKind = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* RootlessCreateScreenResources
|
||||
* Rootless implementations typically set a null framebuffer pointer, which
|
||||
* causes problems with miCreateScreenResources. We fix things up here.
|
||||
*/
|
||||
static Bool
|
||||
RootlessCreateScreenResources(ScreenPtr pScreen)
|
||||
{
|
||||
Bool ret = TRUE;
|
||||
|
||||
SCREEN_UNWRAP(pScreen, CreateScreenResources);
|
||||
|
||||
if (pScreen->CreateScreenResources != NULL)
|
||||
ret = (*pScreen->CreateScreenResources)(pScreen);
|
||||
|
||||
SCREEN_WRAP(pScreen, CreateScreenResources);
|
||||
|
||||
if (!ret)
|
||||
return ret;
|
||||
|
||||
/* Make sure we have a valid screen pixmap. */
|
||||
|
||||
RootlessUpdateScreenPixmap(pScreen);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static Bool
|
||||
RootlessCloseScreen(int i, ScreenPtr pScreen)
|
||||
{
|
||||
RootlessScreenRec *s;
|
||||
|
||||
s = SCREENREC(pScreen);
|
||||
|
||||
// fixme unwrap everything that was wrapped?
|
||||
pScreen->CloseScreen = s->CloseScreen;
|
||||
|
||||
if (s->pixmap_data != NULL) {
|
||||
xfree (s->pixmap_data);
|
||||
s->pixmap_data = NULL;
|
||||
s->pixmap_data_size = 0;
|
||||
}
|
||||
|
||||
xfree(s);
|
||||
return pScreen->CloseScreen(i, pScreen);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
RootlessGetImage(DrawablePtr pDrawable, int sx, int sy, int w, int h,
|
||||
unsigned int format, unsigned long planeMask, char *pdstLine)
|
||||
{
|
||||
ScreenPtr pScreen = pDrawable->pScreen;
|
||||
SCREEN_UNWRAP(pScreen, GetImage);
|
||||
|
||||
if (pDrawable->type == DRAWABLE_WINDOW) {
|
||||
int x0, y0, x1, y1;
|
||||
RootlessWindowRec *winRec;
|
||||
|
||||
// Many apps use GetImage to sync with the visible frame buffer
|
||||
// FIXME: entire screen or just window or all screens?
|
||||
RootlessRedisplayScreen(pScreen);
|
||||
|
||||
// RedisplayScreen stops drawing, so we need to start it again
|
||||
RootlessStartDrawing((WindowPtr)pDrawable);
|
||||
|
||||
/* Check that we have some place to read from. */
|
||||
winRec = WINREC(TopLevelParent((WindowPtr) pDrawable));
|
||||
if (winRec == NULL)
|
||||
goto out;
|
||||
|
||||
/* Clip to top-level window bounds. */
|
||||
/* FIXME: fbGetImage uses the width parameter to calculate the
|
||||
stride of the destination pixmap. If w is clipped, the data
|
||||
returned will be garbage, although we will not crash. */
|
||||
|
||||
x0 = pDrawable->x + sx;
|
||||
y0 = pDrawable->y + sy;
|
||||
x1 = x0 + w;
|
||||
y1 = y0 + h;
|
||||
|
||||
x0 = MAX (x0, winRec->x);
|
||||
y0 = MAX (y0, winRec->y);
|
||||
x1 = MIN (x1, winRec->x + winRec->width);
|
||||
y1 = MIN (y1, winRec->y + winRec->height);
|
||||
|
||||
sx = x0 - pDrawable->x;
|
||||
sy = y0 - pDrawable->y;
|
||||
w = x1 - x0;
|
||||
h = y1 - y0;
|
||||
|
||||
if (w <= 0 || h <= 0)
|
||||
goto out;
|
||||
}
|
||||
|
||||
pScreen->GetImage(pDrawable, sx, sy, w, h, format, planeMask, pdstLine);
|
||||
|
||||
out:
|
||||
SCREEN_WRAP(pScreen, GetImage);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* RootlessSourceValidate
|
||||
* CopyArea and CopyPlane use a GC tied to the destination drawable.
|
||||
* StartDrawing/StopDrawing wrappers won't be called if source is
|
||||
* a visible window but the destination isn't. So, we call StartDrawing
|
||||
* here and leave StopDrawing for the block handler.
|
||||
*/
|
||||
static void
|
||||
RootlessSourceValidate(DrawablePtr pDrawable, int x, int y, int w, int h)
|
||||
{
|
||||
SCREEN_UNWRAP(pDrawable->pScreen, SourceValidate);
|
||||
if (pDrawable->type == DRAWABLE_WINDOW) {
|
||||
WindowPtr pWin = (WindowPtr)pDrawable;
|
||||
RootlessStartDrawing(pWin);
|
||||
}
|
||||
if (pDrawable->pScreen->SourceValidate) {
|
||||
pDrawable->pScreen->SourceValidate(pDrawable, x, y, w, h);
|
||||
}
|
||||
SCREEN_WRAP(pDrawable->pScreen, SourceValidate);
|
||||
}
|
||||
|
||||
#ifdef RENDER
|
||||
|
||||
static void
|
||||
RootlessComposite(CARD8 op, PicturePtr pSrc, PicturePtr pMask, PicturePtr pDst,
|
||||
INT16 xSrc, INT16 ySrc, INT16 xMask, INT16 yMask,
|
||||
INT16 xDst, INT16 yDst, CARD16 width, CARD16 height)
|
||||
{
|
||||
ScreenPtr pScreen = pDst->pDrawable->pScreen;
|
||||
PictureScreenPtr ps = GetPictureScreen(pScreen);
|
||||
WindowPtr srcWin, dstWin, maskWin = NULL;
|
||||
|
||||
if (pMask) { // pMask can be NULL
|
||||
maskWin = (pMask->pDrawable->type == DRAWABLE_WINDOW) ?
|
||||
(WindowPtr)pMask->pDrawable : NULL;
|
||||
}
|
||||
srcWin = (pSrc->pDrawable->type == DRAWABLE_WINDOW) ?
|
||||
(WindowPtr)pSrc->pDrawable : NULL;
|
||||
dstWin = (pDst->pDrawable->type == DRAWABLE_WINDOW) ?
|
||||
(WindowPtr)pDst->pDrawable : NULL;
|
||||
|
||||
// SCREEN_UNWRAP(ps, Composite);
|
||||
ps->Composite = SCREENREC(pScreen)->Composite;
|
||||
|
||||
if (srcWin && IsFramedWindow(srcWin))
|
||||
RootlessStartDrawing(srcWin);
|
||||
if (maskWin && IsFramedWindow(maskWin))
|
||||
RootlessStartDrawing(maskWin);
|
||||
if (dstWin && IsFramedWindow(dstWin))
|
||||
RootlessStartDrawing(dstWin);
|
||||
|
||||
ps->Composite(op, pSrc, pMask, pDst,
|
||||
xSrc, ySrc, xMask, yMask,
|
||||
xDst, yDst, width, height);
|
||||
|
||||
if (dstWin && IsFramedWindow(dstWin)) {
|
||||
RootlessDamageRect(dstWin, xDst, yDst, width, height);
|
||||
}
|
||||
|
||||
ps->Composite = RootlessComposite;
|
||||
// SCREEN_WRAP(ps, Composite);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
RootlessGlyphs(CARD8 op, PicturePtr pSrc, PicturePtr pDst,
|
||||
PictFormatPtr maskFormat, INT16 xSrc, INT16 ySrc,
|
||||
int nlist, GlyphListPtr list, GlyphPtr *glyphs)
|
||||
{
|
||||
ScreenPtr pScreen = pDst->pDrawable->pScreen;
|
||||
PictureScreenPtr ps = GetPictureScreen(pScreen);
|
||||
int x, y;
|
||||
int n;
|
||||
GlyphPtr glyph;
|
||||
WindowPtr srcWin, dstWin;
|
||||
|
||||
srcWin = (pSrc->pDrawable->type == DRAWABLE_WINDOW) ?
|
||||
(WindowPtr)pSrc->pDrawable : NULL;
|
||||
dstWin = (pDst->pDrawable->type == DRAWABLE_WINDOW) ?
|
||||
(WindowPtr)pDst->pDrawable : NULL;
|
||||
|
||||
if (srcWin && IsFramedWindow(srcWin)) RootlessStartDrawing(srcWin);
|
||||
if (dstWin && IsFramedWindow(dstWin)) RootlessStartDrawing(dstWin);
|
||||
|
||||
//SCREEN_UNWRAP(ps, Glyphs);
|
||||
ps->Glyphs = SCREENREC(pScreen)->Glyphs;
|
||||
ps->Glyphs(op, pSrc, pDst, maskFormat, xSrc, ySrc, nlist, list, glyphs);
|
||||
ps->Glyphs = RootlessGlyphs;
|
||||
//SCREEN_WRAP(ps, Glyphs);
|
||||
|
||||
if (dstWin && IsFramedWindow(dstWin)) {
|
||||
x = xSrc;
|
||||
y = ySrc;
|
||||
|
||||
while (nlist--) {
|
||||
x += list->xOff;
|
||||
y += list->yOff;
|
||||
n = list->len;
|
||||
|
||||
/* Calling DamageRect for the bounding box of each glyph is
|
||||
inefficient. So compute the union of all glyphs in a list
|
||||
and damage that. */
|
||||
|
||||
if (n > 0) {
|
||||
BoxRec box;
|
||||
|
||||
glyph = *glyphs++;
|
||||
|
||||
box.x1 = x - glyph->info.x;
|
||||
box.y1 = y - glyph->info.y;
|
||||
box.x2 = box.x1 + glyph->info.width;
|
||||
box.y2 = box.y2 + glyph->info.height;
|
||||
|
||||
x += glyph->info.xOff;
|
||||
y += glyph->info.yOff;
|
||||
|
||||
while (--n > 0) {
|
||||
short x1, y1, x2, y2;
|
||||
|
||||
glyph = *glyphs++;
|
||||
|
||||
x1 = x - glyph->info.x;
|
||||
y1 = y - glyph->info.y;
|
||||
x2 = x1 + glyph->info.width;
|
||||
y2 = y1 + glyph->info.height;
|
||||
|
||||
box.x1 = MAX (box.x1, x1);
|
||||
box.y1 = MAX (box.y1, y1);
|
||||
box.x2 = MAX (box.x2, x2);
|
||||
box.y2 = MAX (box.y2, y2);
|
||||
|
||||
x += glyph->info.xOff;
|
||||
y += glyph->info.yOff;
|
||||
}
|
||||
|
||||
RootlessDamageBox(dstWin, &box);
|
||||
}
|
||||
list++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif // RENDER
|
||||
|
||||
|
||||
/*
|
||||
* RootlessValidateTree
|
||||
* ValidateTree is modified in two ways:
|
||||
* - top-level windows don't clip each other
|
||||
* - windows aren't clipped against root.
|
||||
* These only matter when validating from the root.
|
||||
*/
|
||||
static int
|
||||
RootlessValidateTree(WindowPtr pParent, WindowPtr pChild, VTKind kind)
|
||||
{
|
||||
int result;
|
||||
RegionRec saveRoot;
|
||||
ScreenPtr pScreen = pParent->drawable.pScreen;
|
||||
|
||||
SCREEN_UNWRAP(pScreen, ValidateTree);
|
||||
RL_DEBUG_MSG("VALIDATETREE start ");
|
||||
|
||||
// Use our custom version to validate from root
|
||||
if (IsRoot(pParent)) {
|
||||
RL_DEBUG_MSG("custom ");
|
||||
result = RootlessMiValidateTree(pParent, pChild, kind);
|
||||
} else {
|
||||
HUGE_ROOT(pParent);
|
||||
result = pScreen->ValidateTree(pParent, pChild, kind);
|
||||
NORMAL_ROOT(pParent);
|
||||
}
|
||||
|
||||
SCREEN_WRAP(pScreen, ValidateTree);
|
||||
RL_DEBUG_MSG("VALIDATETREE end\n");
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* RootlessMarkOverlappedWindows
|
||||
* MarkOverlappedWindows is modified to ignore overlapping
|
||||
* top-level windows.
|
||||
*/
|
||||
static Bool
|
||||
RootlessMarkOverlappedWindows(WindowPtr pWin, WindowPtr pFirst,
|
||||
WindowPtr *ppLayerWin)
|
||||
{
|
||||
RegionRec saveRoot;
|
||||
Bool result;
|
||||
ScreenPtr pScreen = pWin->drawable.pScreen;
|
||||
SCREEN_UNWRAP(pScreen, MarkOverlappedWindows);
|
||||
RL_DEBUG_MSG("MARKOVERLAPPEDWINDOWS start ");
|
||||
|
||||
HUGE_ROOT(pWin);
|
||||
if (IsRoot(pWin)) {
|
||||
// root - mark nothing
|
||||
RL_DEBUG_MSG("is root not marking ");
|
||||
result = FALSE;
|
||||
}
|
||||
else if (! IsTopLevel(pWin)) {
|
||||
// not top-level window - mark normally
|
||||
result = pScreen->MarkOverlappedWindows(pWin, pFirst, ppLayerWin);
|
||||
}
|
||||
else {
|
||||
//top-level window - mark children ONLY - NO overlaps with sibs (?)
|
||||
// This code copied from miMarkOverlappedWindows()
|
||||
|
||||
register WindowPtr pChild;
|
||||
Bool anyMarked = FALSE;
|
||||
void (* MarkWindow)() = pScreen->MarkWindow;
|
||||
|
||||
RL_DEBUG_MSG("is top level! ");
|
||||
/* single layered systems are easy */
|
||||
if (ppLayerWin) *ppLayerWin = pWin;
|
||||
|
||||
if (pWin == pFirst) {
|
||||
/* Blindly mark pWin and all of its inferiors. This is a slight
|
||||
* overkill if there are mapped windows that outside pWin's border,
|
||||
* but it's better than wasting time on RectIn checks.
|
||||
*/
|
||||
pChild = pWin;
|
||||
while (1) {
|
||||
if (pChild->viewable) {
|
||||
if (REGION_BROKEN (pScreen, &pChild->winSize))
|
||||
SetWinSize (pChild);
|
||||
if (REGION_BROKEN (pScreen, &pChild->borderSize))
|
||||
SetBorderSize (pChild);
|
||||
(* MarkWindow)(pChild);
|
||||
if (pChild->firstChild) {
|
||||
pChild = pChild->firstChild;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
while (!pChild->nextSib && (pChild != pWin))
|
||||
pChild = pChild->parent;
|
||||
if (pChild == pWin)
|
||||
break;
|
||||
pChild = pChild->nextSib;
|
||||
}
|
||||
anyMarked = TRUE;
|
||||
pFirst = pFirst->nextSib;
|
||||
}
|
||||
if (anyMarked)
|
||||
(* MarkWindow)(pWin->parent);
|
||||
result = anyMarked;
|
||||
}
|
||||
NORMAL_ROOT(pWin);
|
||||
SCREEN_WRAP(pScreen, MarkOverlappedWindows);
|
||||
RL_DEBUG_MSG("MARKOVERLAPPEDWINDOWS end\n");
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
static CARD32
|
||||
RootlessRedisplayCallback(OsTimerPtr timer, CARD32 time, void *arg)
|
||||
{
|
||||
RootlessScreenRec *screenRec = arg;
|
||||
|
||||
if (!screenRec->redisplay_queued) {
|
||||
/* No update needed. Stop the timer. */
|
||||
|
||||
screenRec->redisplay_timer_set = FALSE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
screenRec->redisplay_queued = FALSE;
|
||||
|
||||
/* Mark that we should redisplay before waiting for I/O next time */
|
||||
screenRec->redisplay_expired = TRUE;
|
||||
|
||||
/* Reinstall the timer immediately, so we get as close to our
|
||||
redisplay interval as possible. */
|
||||
|
||||
return ROOTLESS_REDISPLAY_DELAY;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* RootlessQueueRedisplay
|
||||
* Queue a redisplay after a timer delay to ensure we do not redisplay
|
||||
* too frequently.
|
||||
*/
|
||||
void
|
||||
RootlessQueueRedisplay(ScreenPtr pScreen)
|
||||
{
|
||||
RootlessScreenRec *screenRec = SCREENREC(pScreen);
|
||||
|
||||
screenRec->redisplay_queued = TRUE;
|
||||
|
||||
if (screenRec->redisplay_timer_set)
|
||||
return;
|
||||
|
||||
screenRec->redisplay_timer = TimerSet(screenRec->redisplay_timer,
|
||||
0, ROOTLESS_REDISPLAY_DELAY,
|
||||
RootlessRedisplayCallback,
|
||||
screenRec);
|
||||
screenRec->redisplay_timer_set = TRUE;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* RootlessBlockHandler
|
||||
* If the redisplay timer has expired, flush drawing before blocking
|
||||
* on select().
|
||||
*/
|
||||
static void
|
||||
RootlessBlockHandler(pointer pbdata, OSTimePtr pTimeout, pointer pReadmask)
|
||||
{
|
||||
ScreenPtr pScreen = pbdata;
|
||||
RootlessScreenRec *screenRec = SCREENREC(pScreen);
|
||||
|
||||
if (screenRec->redisplay_expired) {
|
||||
screenRec->redisplay_expired = FALSE;
|
||||
|
||||
RootlessRedisplayScreen(pScreen);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
RootlessWakeupHandler(pointer data, int i, pointer LastSelectMask)
|
||||
{
|
||||
// nothing here
|
||||
}
|
||||
|
||||
|
||||
static Bool
|
||||
RootlessAllocatePrivates(ScreenPtr pScreen)
|
||||
{
|
||||
RootlessScreenRec *s;
|
||||
static unsigned long rootlessGeneration = 0;
|
||||
|
||||
if (rootlessGeneration != serverGeneration) {
|
||||
rootlessScreenPrivateIndex = AllocateScreenPrivateIndex();
|
||||
if (rootlessScreenPrivateIndex == -1) return FALSE;
|
||||
rootlessGCPrivateIndex = AllocateGCPrivateIndex();
|
||||
if (rootlessGCPrivateIndex == -1) return FALSE;
|
||||
rootlessWindowPrivateIndex = AllocateWindowPrivateIndex();
|
||||
if (rootlessWindowPrivateIndex == -1) return FALSE;
|
||||
rootlessGeneration = serverGeneration;
|
||||
}
|
||||
|
||||
// no allocation needed for screen privates
|
||||
if (!AllocateGCPrivate(pScreen, rootlessGCPrivateIndex,
|
||||
sizeof(RootlessGCRec)))
|
||||
return FALSE;
|
||||
if (!AllocateWindowPrivate(pScreen, rootlessWindowPrivateIndex, 0))
|
||||
return FALSE;
|
||||
|
||||
s = xalloc(sizeof(RootlessScreenRec));
|
||||
if (! s) return FALSE;
|
||||
SCREENREC(pScreen) = s;
|
||||
|
||||
s->pixmap_data = NULL;
|
||||
s->pixmap_data_size = 0;
|
||||
|
||||
s->redisplay_timer = NULL;
|
||||
s->redisplay_timer_set = FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
RootlessWrap(ScreenPtr pScreen)
|
||||
{
|
||||
RootlessScreenRec *s = (RootlessScreenRec*)
|
||||
pScreen->devPrivates[rootlessScreenPrivateIndex].ptr;
|
||||
|
||||
#define WRAP(a) \
|
||||
if (pScreen->a) { \
|
||||
s->a = pScreen->a; \
|
||||
} else { \
|
||||
RL_DEBUG_MSG("null screen fn " #a "\n"); \
|
||||
s->a = NULL; \
|
||||
} \
|
||||
pScreen->a = Rootless##a
|
||||
|
||||
WRAP(CreateScreenResources);
|
||||
WRAP(CloseScreen);
|
||||
WRAP(CreateGC);
|
||||
WRAP(PaintWindowBackground);
|
||||
WRAP(PaintWindowBorder);
|
||||
WRAP(CopyWindow);
|
||||
WRAP(GetImage);
|
||||
WRAP(SourceValidate);
|
||||
WRAP(CreateWindow);
|
||||
WRAP(DestroyWindow);
|
||||
WRAP(RealizeWindow);
|
||||
WRAP(UnrealizeWindow);
|
||||
WRAP(MoveWindow);
|
||||
WRAP(PositionWindow);
|
||||
WRAP(ResizeWindow);
|
||||
WRAP(RestackWindow);
|
||||
WRAP(ReparentWindow);
|
||||
WRAP(ChangeBorderWidth);
|
||||
WRAP(MarkOverlappedWindows);
|
||||
WRAP(ValidateTree);
|
||||
WRAP(ChangeWindowAttributes);
|
||||
|
||||
#ifdef SHAPE
|
||||
WRAP(SetShape);
|
||||
#endif
|
||||
|
||||
#ifdef RENDER
|
||||
{
|
||||
// Composite and Glyphs don't use normal screen wrapping
|
||||
PictureScreenPtr ps = GetPictureScreen(pScreen);
|
||||
s->Composite = ps->Composite;
|
||||
ps->Composite = RootlessComposite;
|
||||
s->Glyphs = ps->Glyphs;
|
||||
ps->Glyphs = RootlessGlyphs;
|
||||
}
|
||||
#endif
|
||||
|
||||
// WRAP(ClearToBackground); fixme put this back? useful for shaped wins?
|
||||
// WRAP(RestoreAreas); fixme put this back?
|
||||
|
||||
#undef WRAP
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* RootlessInit
|
||||
* Called by the rootless implementation to initialize the rootless layer.
|
||||
* Rootless wraps lots of stuff and needs a bunch of devPrivates.
|
||||
*/
|
||||
Bool RootlessInit(ScreenPtr pScreen, RootlessFrameProcsPtr procs)
|
||||
{
|
||||
RootlessScreenRec *s;
|
||||
|
||||
if (!RootlessAllocatePrivates(pScreen))
|
||||
return FALSE;
|
||||
|
||||
s = (RootlessScreenRec*)
|
||||
pScreen->devPrivates[rootlessScreenPrivateIndex].ptr;
|
||||
|
||||
s->imp = procs;
|
||||
|
||||
RootlessWrap(pScreen);
|
||||
|
||||
if (!RegisterBlockAndWakeupHandlers(RootlessBlockHandler,
|
||||
RootlessWakeupHandler,
|
||||
(pointer) pScreen))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
638
miext/rootless/rootlessValTree.c
Normal file
638
miext/rootless/rootlessValTree.c
Normal file
|
|
@ -0,0 +1,638 @@
|
|||
/*
|
||||
* Calculate window clip lists for rootless mode
|
||||
*
|
||||
* This file is very closely based on mivaltree.c.
|
||||
*/
|
||||
/* $XFree86: xc/programs/Xserver/miext/rootless/rootlessValTree.c,v 1.2 2003/11/10 18:22:50 tsi Exp $ */
|
||||
|
||||
/*
|
||||
* mivaltree.c --
|
||||
* Functions for recalculating window clip lists. Main function
|
||||
* is miValidateTree.
|
||||
*
|
||||
|
||||
Copyright 1987, 1988, 1989, 1998 The Open Group
|
||||
|
||||
All Rights Reserved.
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
Except as contained in this notice, the name of The Open Group shall not be
|
||||
used in advertising or otherwise to promote the sale, use or other dealings
|
||||
in this Software without prior written authorization from The Open Group.
|
||||
|
||||
*
|
||||
* Copyright 1987, 1988, 1989 by
|
||||
* Digital Equipment Corporation, Maynard, Massachusetts,
|
||||
*
|
||||
* All Rights Reserved
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software and its
|
||||
* documentation for any purpose and without fee is hereby granted,
|
||||
* 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 Digital not be
|
||||
* used in advertising or publicity pertaining to distribution of the
|
||||
* software without specific, written prior permission.
|
||||
*
|
||||
* DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
|
||||
* ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
|
||||
* DIGITAL 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.
|
||||
*
|
||||
******************************************************************/
|
||||
|
||||
/* The panoramix components contained the following notice */
|
||||
/****************************************************************
|
||||
* *
|
||||
* Copyright (c) Digital Equipment Corporation, 1991, 1997 *
|
||||
* *
|
||||
* All Rights Reserved. Unpublished rights reserved under *
|
||||
* the copyright laws of the United States. *
|
||||
* *
|
||||
* The software contained on this media is proprietary to *
|
||||
* and embodies the confidential technology of Digital *
|
||||
* Equipment Corporation. Possession, use, duplication or *
|
||||
* dissemination of the software and media is authorized only *
|
||||
* pursuant to a valid written license from Digital Equipment *
|
||||
* Corporation. *
|
||||
* *
|
||||
* RESTRICTED RIGHTS LEGEND Use, duplication, or disclosure *
|
||||
* by the U.S. Government is subject to restrictions as set *
|
||||
* forth in Subparagraph (c)(1)(ii) of DFARS 252.227-7013, *
|
||||
* or in FAR 52.227-19, as applicable. *
|
||||
* *
|
||||
*****************************************************************/
|
||||
|
||||
/*
|
||||
* Aug '86: Susan Angebranndt -- original code
|
||||
* July '87: Adam de Boor -- substantially modified and commented
|
||||
* Summer '89: Joel McCormack -- so fast you wouldn't believe it possible.
|
||||
* In particular, much improved code for window mapping and
|
||||
* circulating.
|
||||
* Bob Scheifler -- avoid miComputeClips for unmapped windows,
|
||||
* valdata changes
|
||||
*/
|
||||
#include "X.h"
|
||||
#include "scrnintstr.h"
|
||||
#include "validate.h"
|
||||
#include "windowstr.h"
|
||||
#include "mi.h"
|
||||
#include "regionstr.h"
|
||||
#include "mivalidate.h"
|
||||
|
||||
#include "globals.h"
|
||||
|
||||
#ifdef SHAPE
|
||||
/*
|
||||
* Compute the visibility of a shaped window
|
||||
*/
|
||||
int
|
||||
RootlessShapedWindowIn (pScreen, universe, bounding, rect, x, y)
|
||||
ScreenPtr pScreen;
|
||||
RegionPtr universe, bounding;
|
||||
BoxPtr rect;
|
||||
register int x, y;
|
||||
{
|
||||
BoxRec box;
|
||||
register BoxPtr boundBox;
|
||||
int nbox;
|
||||
Bool someIn, someOut;
|
||||
register int t, x1, y1, x2, y2;
|
||||
|
||||
nbox = REGION_NUM_RECTS (bounding);
|
||||
boundBox = REGION_RECTS (bounding);
|
||||
someIn = someOut = FALSE;
|
||||
x1 = rect->x1;
|
||||
y1 = rect->y1;
|
||||
x2 = rect->x2;
|
||||
y2 = rect->y2;
|
||||
while (nbox--)
|
||||
{
|
||||
if ((t = boundBox->x1 + x) < x1)
|
||||
t = x1;
|
||||
box.x1 = t;
|
||||
if ((t = boundBox->y1 + y) < y1)
|
||||
t = y1;
|
||||
box.y1 = t;
|
||||
if ((t = boundBox->x2 + x) > x2)
|
||||
t = x2;
|
||||
box.x2 = t;
|
||||
if ((t = boundBox->y2 + y) > y2)
|
||||
t = y2;
|
||||
box.y2 = t;
|
||||
if (box.x1 > box.x2)
|
||||
box.x2 = box.x1;
|
||||
if (box.y1 > box.y2)
|
||||
box.y2 = box.y1;
|
||||
switch (RECT_IN_REGION(pScreen, universe, &box))
|
||||
{
|
||||
case rgnIN:
|
||||
if (someOut)
|
||||
return rgnPART;
|
||||
someIn = TRUE;
|
||||
break;
|
||||
case rgnOUT:
|
||||
if (someIn)
|
||||
return rgnPART;
|
||||
someOut = TRUE;
|
||||
break;
|
||||
default:
|
||||
return rgnPART;
|
||||
}
|
||||
boundBox++;
|
||||
}
|
||||
if (someIn)
|
||||
return rgnIN;
|
||||
return rgnOUT;
|
||||
}
|
||||
#endif
|
||||
|
||||
#define HasParentRelativeBorder(w) (!(w)->borderIsPixel && \
|
||||
HasBorder(w) && \
|
||||
(w)->backgroundState == ParentRelative)
|
||||
|
||||
|
||||
/*
|
||||
*-----------------------------------------------------------------------
|
||||
* RootlessComputeClips --
|
||||
* Recompute the clipList, borderClip, exposed and borderExposed
|
||||
* regions for pParent and its children. Only viewable windows are
|
||||
* taken into account.
|
||||
*
|
||||
* Results:
|
||||
* None.
|
||||
*
|
||||
* Side Effects:
|
||||
* clipList, borderClip, exposed and borderExposed are altered.
|
||||
* A VisibilityNotify event may be generated on the parent window.
|
||||
*
|
||||
*-----------------------------------------------------------------------
|
||||
*/
|
||||
static void
|
||||
RootlessComputeClips (pParent, pScreen, universe, kind, exposed)
|
||||
register WindowPtr pParent;
|
||||
register ScreenPtr pScreen;
|
||||
register RegionPtr universe;
|
||||
VTKind kind;
|
||||
RegionPtr exposed; /* for intermediate calculations */
|
||||
{
|
||||
int dx,
|
||||
dy;
|
||||
RegionRec childUniverse;
|
||||
register WindowPtr pChild;
|
||||
int oldVis, newVis;
|
||||
BoxRec borderSize;
|
||||
RegionRec childUnion;
|
||||
Bool overlap;
|
||||
RegionPtr borderVisible;
|
||||
Bool resized;
|
||||
/*
|
||||
* Figure out the new visibility of this window.
|
||||
* The extent of the universe should be the same as the extent of
|
||||
* the borderSize region. If the window is unobscured, this rectangle
|
||||
* will be completely inside the universe (the universe will cover it
|
||||
* completely). If the window is completely obscured, none of the
|
||||
* universe will cover the rectangle.
|
||||
*/
|
||||
borderSize.x1 = pParent->drawable.x - wBorderWidth(pParent);
|
||||
borderSize.y1 = pParent->drawable.y - wBorderWidth(pParent);
|
||||
dx = (int) pParent->drawable.x + (int) pParent->drawable.width + wBorderWidth(pParent);
|
||||
if (dx > 32767)
|
||||
dx = 32767;
|
||||
borderSize.x2 = dx;
|
||||
dy = (int) pParent->drawable.y + (int) pParent->drawable.height + wBorderWidth(pParent);
|
||||
if (dy > 32767)
|
||||
dy = 32767;
|
||||
borderSize.y2 = dy;
|
||||
|
||||
oldVis = pParent->visibility;
|
||||
switch (RECT_IN_REGION( pScreen, universe, &borderSize))
|
||||
{
|
||||
case rgnIN:
|
||||
newVis = VisibilityUnobscured;
|
||||
break;
|
||||
case rgnPART:
|
||||
newVis = VisibilityPartiallyObscured;
|
||||
#ifdef SHAPE
|
||||
{
|
||||
RegionPtr pBounding;
|
||||
|
||||
if ((pBounding = wBoundingShape (pParent)))
|
||||
{
|
||||
switch (RootlessShapedWindowIn (pScreen, universe,
|
||||
pBounding, &borderSize,
|
||||
pParent->drawable.x,
|
||||
pParent->drawable.y))
|
||||
{
|
||||
case rgnIN:
|
||||
newVis = VisibilityUnobscured;
|
||||
break;
|
||||
case rgnOUT:
|
||||
newVis = VisibilityFullyObscured;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
default:
|
||||
newVis = VisibilityFullyObscured;
|
||||
break;
|
||||
}
|
||||
|
||||
pParent->visibility = newVis;
|
||||
if (oldVis != newVis &&
|
||||
((pParent->eventMask | wOtherEventMasks(pParent)) & VisibilityChangeMask))
|
||||
SendVisibilityNotify(pParent);
|
||||
|
||||
dx = pParent->drawable.x - pParent->valdata->before.oldAbsCorner.x;
|
||||
dy = pParent->drawable.y - pParent->valdata->before.oldAbsCorner.y;
|
||||
|
||||
/*
|
||||
* avoid computations when dealing with simple operations
|
||||
*/
|
||||
|
||||
switch (kind) {
|
||||
case VTMap:
|
||||
case VTStack:
|
||||
case VTUnmap:
|
||||
break;
|
||||
case VTMove:
|
||||
if ((oldVis == newVis) &&
|
||||
((oldVis == VisibilityFullyObscured) ||
|
||||
(oldVis == VisibilityUnobscured)))
|
||||
{
|
||||
pChild = pParent;
|
||||
while (1)
|
||||
{
|
||||
if (pChild->viewable)
|
||||
{
|
||||
if (pChild->visibility != VisibilityFullyObscured)
|
||||
{
|
||||
REGION_TRANSLATE( pScreen, &pChild->borderClip,
|
||||
dx, dy);
|
||||
REGION_TRANSLATE( pScreen, &pChild->clipList,
|
||||
dx, dy);
|
||||
pChild->drawable.serialNumber = NEXT_SERIAL_NUMBER;
|
||||
if (pScreen->ClipNotify)
|
||||
(* pScreen->ClipNotify) (pChild, dx, dy);
|
||||
|
||||
}
|
||||
if (pChild->valdata)
|
||||
{
|
||||
REGION_NULL(pScreen,
|
||||
&pChild->valdata->after.borderExposed);
|
||||
if (HasParentRelativeBorder(pChild))
|
||||
{
|
||||
REGION_SUBTRACT(pScreen,
|
||||
&pChild->valdata->after.borderExposed,
|
||||
&pChild->borderClip,
|
||||
&pChild->winSize);
|
||||
}
|
||||
REGION_NULL(pScreen, &pChild->valdata->after.exposed);
|
||||
}
|
||||
if (pChild->firstChild)
|
||||
{
|
||||
pChild = pChild->firstChild;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
while (!pChild->nextSib && (pChild != pParent))
|
||||
pChild = pChild->parent;
|
||||
if (pChild == pParent)
|
||||
break;
|
||||
pChild = pChild->nextSib;
|
||||
}
|
||||
return;
|
||||
}
|
||||
/* fall through */
|
||||
default:
|
||||
/*
|
||||
* To calculate exposures correctly, we have to translate the old
|
||||
* borderClip and clipList regions to the window's new location so there
|
||||
* is a correspondence between pieces of the new and old clipping regions.
|
||||
*/
|
||||
if (dx || dy)
|
||||
{
|
||||
/*
|
||||
* We translate the old clipList because that will be exposed or copied
|
||||
* if gravity is right.
|
||||
*/
|
||||
REGION_TRANSLATE( pScreen, &pParent->borderClip, dx, dy);
|
||||
REGION_TRANSLATE( pScreen, &pParent->clipList, dx, dy);
|
||||
}
|
||||
break;
|
||||
case VTBroken:
|
||||
REGION_EMPTY (pScreen, &pParent->borderClip);
|
||||
REGION_EMPTY (pScreen, &pParent->clipList);
|
||||
break;
|
||||
}
|
||||
|
||||
borderVisible = pParent->valdata->before.borderVisible;
|
||||
resized = pParent->valdata->before.resized;
|
||||
REGION_NULL(pScreen, &pParent->valdata->after.borderExposed);
|
||||
REGION_NULL(pScreen, &pParent->valdata->after.exposed);
|
||||
|
||||
/*
|
||||
* Since the borderClip must not be clipped by the children, we do
|
||||
* the border exposure first...
|
||||
*
|
||||
* 'universe' is the window's borderClip. To figure the exposures, remove
|
||||
* the area that used to be exposed from the new.
|
||||
* This leaves a region of pieces that weren't exposed before.
|
||||
*/
|
||||
|
||||
if (HasBorder (pParent))
|
||||
{
|
||||
if (borderVisible)
|
||||
{
|
||||
/*
|
||||
* when the border changes shape, the old visible portions
|
||||
* of the border will be saved by DIX in borderVisible --
|
||||
* use that region and destroy it
|
||||
*/
|
||||
REGION_SUBTRACT( pScreen, exposed, universe, borderVisible);
|
||||
REGION_DESTROY( pScreen, borderVisible);
|
||||
}
|
||||
else
|
||||
{
|
||||
REGION_SUBTRACT( pScreen, exposed, universe, &pParent->borderClip);
|
||||
}
|
||||
if (HasParentRelativeBorder(pParent) && (dx || dy)) {
|
||||
REGION_SUBTRACT( pScreen, &pParent->valdata->after.borderExposed,
|
||||
universe,
|
||||
&pParent->winSize);
|
||||
} else {
|
||||
REGION_SUBTRACT( pScreen, &pParent->valdata->after.borderExposed,
|
||||
exposed, &pParent->winSize);
|
||||
}
|
||||
|
||||
REGION_COPY( pScreen, &pParent->borderClip, universe);
|
||||
|
||||
/*
|
||||
* To get the right clipList for the parent, and to make doubly sure
|
||||
* that no child overlaps the parent's border, we remove the parent's
|
||||
* border from the universe before proceeding.
|
||||
*/
|
||||
|
||||
REGION_INTERSECT( pScreen, universe, universe, &pParent->winSize);
|
||||
}
|
||||
else
|
||||
REGION_COPY( pScreen, &pParent->borderClip, universe);
|
||||
|
||||
if ((pChild = pParent->firstChild) && pParent->mapped)
|
||||
{
|
||||
REGION_NULL(pScreen, &childUniverse);
|
||||
REGION_NULL(pScreen, &childUnion);
|
||||
if ((pChild->drawable.y < pParent->lastChild->drawable.y) ||
|
||||
((pChild->drawable.y == pParent->lastChild->drawable.y) &&
|
||||
(pChild->drawable.x < pParent->lastChild->drawable.x)))
|
||||
{
|
||||
for (; pChild; pChild = pChild->nextSib)
|
||||
{
|
||||
if (pChild->viewable)
|
||||
REGION_APPEND( pScreen, &childUnion, &pChild->borderSize);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (pChild = pParent->lastChild; pChild; pChild = pChild->prevSib)
|
||||
{
|
||||
if (pChild->viewable)
|
||||
REGION_APPEND( pScreen, &childUnion, &pChild->borderSize);
|
||||
}
|
||||
}
|
||||
REGION_VALIDATE( pScreen, &childUnion, &overlap);
|
||||
|
||||
for (pChild = pParent->firstChild;
|
||||
pChild;
|
||||
pChild = pChild->nextSib)
|
||||
{
|
||||
if (pChild->viewable) {
|
||||
/*
|
||||
* If the child is viewable, we want to remove its extents
|
||||
* from the current universe, but we only re-clip it if
|
||||
* it's been marked.
|
||||
*/
|
||||
if (pChild->valdata) {
|
||||
/*
|
||||
* Figure out the new universe from the child's
|
||||
* perspective and recurse.
|
||||
*/
|
||||
REGION_INTERSECT( pScreen, &childUniverse,
|
||||
universe,
|
||||
&pChild->borderSize);
|
||||
RootlessComputeClips (pChild, pScreen, &childUniverse,
|
||||
kind, exposed);
|
||||
}
|
||||
/*
|
||||
* Once the child has been processed, we remove its extents
|
||||
* from the current universe, thus denying its space to any
|
||||
* other sibling.
|
||||
*/
|
||||
if (overlap)
|
||||
REGION_SUBTRACT( pScreen, universe, universe,
|
||||
&pChild->borderSize);
|
||||
}
|
||||
}
|
||||
if (!overlap)
|
||||
REGION_SUBTRACT( pScreen, universe, universe, &childUnion);
|
||||
REGION_UNINIT( pScreen, &childUnion);
|
||||
REGION_UNINIT( pScreen, &childUniverse);
|
||||
} /* if any children */
|
||||
|
||||
/*
|
||||
* 'universe' now contains the new clipList for the parent window.
|
||||
*
|
||||
* To figure the exposure of the window we subtract the old clip from the
|
||||
* new, just as for the border.
|
||||
*/
|
||||
|
||||
if (oldVis == VisibilityFullyObscured ||
|
||||
oldVis == VisibilityNotViewable)
|
||||
{
|
||||
REGION_COPY( pScreen, &pParent->valdata->after.exposed, universe);
|
||||
}
|
||||
else if (newVis != VisibilityFullyObscured &&
|
||||
newVis != VisibilityNotViewable)
|
||||
{
|
||||
REGION_SUBTRACT( pScreen, &pParent->valdata->after.exposed,
|
||||
universe, &pParent->clipList);
|
||||
}
|
||||
|
||||
/*
|
||||
* One last thing: backing storage. We have to try to save what parts of
|
||||
* the window are about to be obscured. We can just subtract the universe
|
||||
* from the old clipList and get the areas that were in the old but aren't
|
||||
* in the new and, hence, are about to be obscured.
|
||||
*/
|
||||
if (pParent->backStorage && !resized)
|
||||
{
|
||||
REGION_SUBTRACT( pScreen, exposed, &pParent->clipList, universe);
|
||||
(* pScreen->SaveDoomedAreas)(pParent, exposed, dx, dy);
|
||||
}
|
||||
|
||||
/* HACK ALERT - copying contents of regions, instead of regions */
|
||||
{
|
||||
RegionRec tmp;
|
||||
|
||||
tmp = pParent->clipList;
|
||||
pParent->clipList = *universe;
|
||||
*universe = tmp;
|
||||
}
|
||||
|
||||
#ifdef NOTDEF
|
||||
REGION_COPY( pScreen, &pParent->clipList, universe);
|
||||
#endif
|
||||
|
||||
pParent->drawable.serialNumber = NEXT_SERIAL_NUMBER;
|
||||
|
||||
if (pScreen->ClipNotify)
|
||||
(* pScreen->ClipNotify) (pParent, dx, dy);
|
||||
}
|
||||
|
||||
static void
|
||||
RootlessTreeObscured(pParent)
|
||||
register WindowPtr pParent;
|
||||
{
|
||||
register WindowPtr pChild;
|
||||
register int oldVis;
|
||||
|
||||
pChild = pParent;
|
||||
while (1)
|
||||
{
|
||||
if (pChild->viewable)
|
||||
{
|
||||
oldVis = pChild->visibility;
|
||||
if (oldVis != (pChild->visibility = VisibilityFullyObscured) &&
|
||||
((pChild->eventMask | wOtherEventMasks(pChild)) & VisibilityChangeMask))
|
||||
SendVisibilityNotify(pChild);
|
||||
if (pChild->firstChild)
|
||||
{
|
||||
pChild = pChild->firstChild;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
while (!pChild->nextSib && (pChild != pParent))
|
||||
pChild = pChild->parent;
|
||||
if (pChild == pParent)
|
||||
break;
|
||||
pChild = pChild->nextSib;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
*-----------------------------------------------------------------------
|
||||
* RootlessMiValidateTree --
|
||||
* Recomputes the clip list for pParent and all its inferiors.
|
||||
*
|
||||
* Results:
|
||||
* Always returns 1.
|
||||
*
|
||||
* Side Effects:
|
||||
* The clipList, borderClip, exposed, and borderExposed regions for
|
||||
* each marked window are altered.
|
||||
*
|
||||
* Notes:
|
||||
* This routine assumes that all affected windows have been marked
|
||||
* (valdata created) and their winSize and borderSize regions
|
||||
* adjusted to correspond to their new positions. The borderClip and
|
||||
* clipList regions should not have been touched.
|
||||
*
|
||||
* The top-most level is treated differently from all lower levels
|
||||
* because pParent is unchanged. For the top level, we merge the
|
||||
* regions taken up by the marked children back into the clipList
|
||||
* for pParent, thus forming a region from which the marked children
|
||||
* can claim their areas. For lower levels, where the old clipList
|
||||
* and borderClip are invalid, we can't do this and have to do the
|
||||
* extra operations done in miComputeClips, but this is much faster
|
||||
* e.g. when only one child has moved...
|
||||
*
|
||||
*-----------------------------------------------------------------------
|
||||
*/
|
||||
/*
|
||||
Quartz version: used for validate from root in rootless mode.
|
||||
We need to make sure top-level windows don't clip each other,
|
||||
and that top-level windows aren't clipped to the root window.
|
||||
*/
|
||||
/*ARGSUSED*/
|
||||
// fixme this is ugly
|
||||
// Xprint/ValTree.c doesn't work, but maybe that method can?
|
||||
int
|
||||
RootlessMiValidateTree (pRoot, pChild, kind)
|
||||
WindowPtr pRoot; /* Parent to validate */
|
||||
WindowPtr pChild; /* First child of pRoot that was
|
||||
* affected */
|
||||
VTKind kind; /* What kind of configuration caused call */
|
||||
{
|
||||
RegionRec childClip; /* The new borderClip for the current
|
||||
* child */
|
||||
RegionRec exposed; /* For intermediate calculations */
|
||||
register ScreenPtr pScreen;
|
||||
register WindowPtr pWin;
|
||||
|
||||
pScreen = pRoot->drawable.pScreen;
|
||||
if (pChild == NullWindow)
|
||||
pChild = pRoot->firstChild;
|
||||
|
||||
REGION_NULL(pScreen, &childClip);
|
||||
REGION_NULL(pScreen, &exposed);
|
||||
|
||||
if (REGION_BROKEN (pScreen, &pRoot->clipList) &&
|
||||
!REGION_BROKEN (pScreen, &pRoot->borderClip))
|
||||
{
|
||||
// fixme this might not work, but hopefully doesn't happen anyway.
|
||||
kind = VTBroken;
|
||||
REGION_EMPTY (pScreen, &pRoot->clipList);
|
||||
ErrorF("ValidateTree: BUSTED!\n");
|
||||
}
|
||||
|
||||
/*
|
||||
* Recursively compute the clips for all children of the root.
|
||||
* They don't clip against each other or the root itself, so
|
||||
* childClip is always reset to that child's size.
|
||||
*/
|
||||
|
||||
for (pWin = pChild;
|
||||
pWin != NullWindow;
|
||||
pWin = pWin->nextSib)
|
||||
{
|
||||
if (pWin->viewable) {
|
||||
if (pWin->valdata) {
|
||||
REGION_COPY( pScreen, &childClip, &pWin->borderSize);
|
||||
RootlessComputeClips (pWin, pScreen, &childClip, kind, &exposed);
|
||||
} else if (pWin->visibility == VisibilityNotViewable) {
|
||||
RootlessTreeObscured(pWin);
|
||||
}
|
||||
} else {
|
||||
if (pWin->valdata) {
|
||||
REGION_EMPTY( pScreen, &pWin->clipList);
|
||||
if (pScreen->ClipNotify)
|
||||
(* pScreen->ClipNotify) (pWin, 0, 0);
|
||||
REGION_EMPTY( pScreen, &pWin->borderClip);
|
||||
pWin->valdata = (ValidatePtr)NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
REGION_UNINIT(pScreen, &childClip);
|
||||
|
||||
/* The root is never clipped by its children, so nothing on the root
|
||||
is ever exposed by moving or mapping its children. */
|
||||
REGION_NULL(pScreen, &pRoot->valdata->after.exposed);
|
||||
REGION_NULL(pScreen, &pRoot->valdata->after.borderExposed);
|
||||
|
||||
return 1;
|
||||
}
|
||||
1435
miext/rootless/rootlessWindow.c
Normal file
1435
miext/rootless/rootlessWindow.c
Normal file
File diff suppressed because it is too large
Load diff
60
miext/rootless/rootlessWindow.h
Normal file
60
miext/rootless/rootlessWindow.h
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
/*
|
||||
* Rootless window management
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 2001 Greg Parker. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* Except as contained in this notice, the name(s) of the above copyright
|
||||
* holders shall not be used in advertising or otherwise to promote the sale,
|
||||
* use or other dealings in this Software without prior written authorization.
|
||||
*/
|
||||
/* $XFree86: xc/programs/Xserver/miext/rootless/rootlessWindow.h,v 1.2 2003/06/30 01:45:13 torrey Exp $ */
|
||||
|
||||
#ifndef _ROOTLESSWINDOW_H
|
||||
#define _ROOTLESSWINDOW_H
|
||||
|
||||
#include "rootlessCommon.h"
|
||||
|
||||
|
||||
Bool RootlessCreateWindow(WindowPtr pWin);
|
||||
Bool RootlessDestroyWindow(WindowPtr pWin);
|
||||
|
||||
#ifdef SHAPE
|
||||
void RootlessSetShape(WindowPtr pWin);
|
||||
#endif // SHAPE
|
||||
|
||||
Bool RootlessChangeWindowAttributes(WindowPtr pWin, unsigned long vmask);
|
||||
Bool RootlessPositionWindow(WindowPtr pWin, int x, int y);
|
||||
Bool RootlessRealizeWindow(WindowPtr pWin);
|
||||
Bool RootlessUnrealizeWindow(WindowPtr pWin);
|
||||
void RootlessRestackWindow(WindowPtr pWin, WindowPtr pOldNextSib);
|
||||
void RootlessCopyWindow(WindowPtr pWin,DDXPointRec ptOldOrg,RegionPtr prgnSrc);
|
||||
void RootlessMoveWindow(WindowPtr pWin,int x,int y,WindowPtr pSib,VTKind kind);
|
||||
void RootlessResizeWindow(WindowPtr pWin, int x, int y,
|
||||
unsigned int w, unsigned int h, WindowPtr pSib);
|
||||
void RootlessReparentWindow(WindowPtr pWin, WindowPtr pPriorParent);
|
||||
void RootlessPaintWindowBackground(WindowPtr pWin, RegionPtr pRegion,
|
||||
int what);
|
||||
void RootlessPaintWindowBorder(WindowPtr pWin, RegionPtr pRegion,
|
||||
int what);
|
||||
void RootlessChangeBorderWidth(WindowPtr pWin, unsigned int width);
|
||||
|
||||
#endif
|
||||
46
miext/rootless/safeAlpha/safeAlpha.h
Normal file
46
miext/rootless/safeAlpha/safeAlpha.h
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
* Replacement functions to protect the alpha channel
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 2002-2003 Torrey T. Lyons. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* Except as contained in this notice, the name(s) of the above copyright
|
||||
* holders shall not be used in advertising or otherwise to promote the sale,
|
||||
* use or other dealings in this Software without prior written authorization.
|
||||
*/
|
||||
/* $XFree86: xc/programs/Xserver/miext/rootless/safeAlpha/safeAlpha.h,v 1.2 2003/10/18 00:00:34 torrey Exp $ */
|
||||
|
||||
#ifndef _SAFEALPHA_H
|
||||
#define _SAFEALPHA_H
|
||||
|
||||
#include "picturestr.h"
|
||||
#include "rootlessCommon.h"
|
||||
|
||||
void SafeAlphaPaintWindow(WindowPtr pWin, RegionPtr pRegion, int what);
|
||||
|
||||
#ifdef RENDER
|
||||
void
|
||||
SafeAlphaComposite(CARD8 op, PicturePtr pSrc, PicturePtr pMask, PicturePtr pDst,
|
||||
INT16 xSrc, INT16 ySrc, INT16 xMask, INT16 yMask,
|
||||
INT16 xDst, INT16 yDst, CARD16 width, CARD16 height);
|
||||
#endif /* RENDER */
|
||||
|
||||
#endif /* _SAFEALPHA_H */
|
||||
595
miext/rootless/safeAlpha/safeAlphaPicture.c
Normal file
595
miext/rootless/safeAlpha/safeAlphaPicture.c
Normal file
|
|
@ -0,0 +1,595 @@
|
|||
/*
|
||||
* Support for RENDER extension while protecting the alpha channel
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 2002-2003 Torrey T. Lyons. All Rights Reserved.
|
||||
* Copyright (c) 2002 Apple Computer, Inc. All Rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* Except as contained in this notice, the name(s) of the above copyright
|
||||
* holders shall not be used in advertising or otherwise to promote the sale,
|
||||
* use or other dealings in this Software without prior written authorization.
|
||||
*/
|
||||
/* This file is largely based on fbcompose.c and fbpict.c, which contain
|
||||
* the following copyright:
|
||||
*
|
||||
* Copyright © 2000 Keith Packard, member of The XFree86 Project, Inc.
|
||||
*/
|
||||
/* $XFree86: xc/programs/Xserver/miext/rootless/safeAlpha/safeAlphaPicture.c,v 1.3 2003/10/24 00:33:15 torrey Exp $ */
|
||||
|
||||
#ifdef RENDER
|
||||
|
||||
#include "fb.h"
|
||||
#include "picturestr.h"
|
||||
#include "mipict.h"
|
||||
#include "fbpict.h"
|
||||
#include "safeAlpha.h"
|
||||
|
||||
# define mod(a,b) ((b) == 1 ? 0 : (a) >= 0 ? (a) % (b) : (b) - (-a) % (b))
|
||||
|
||||
|
||||
// Replacement for fbStore_x8r8g8b8 that sets the alpha channel
|
||||
void
|
||||
SafeAlphaStore_x8r8g8b8 (FbCompositeOperand *op, CARD32 value)
|
||||
{
|
||||
FbBits *line = op->u.drawable.line; CARD32 offset = op->u.drawable.offset;
|
||||
((CARD32 *)line)[offset >> 5] = (value & ~RootlessAlphaMask(32)) |
|
||||
RootlessAlphaMask(32);
|
||||
}
|
||||
|
||||
|
||||
// Defined in fbcompose.c
|
||||
extern FbCombineFunc fbCombineFuncU[];
|
||||
extern FbCombineFunc fbCombineFuncC[];
|
||||
|
||||
/* A bunch of macros from fbpict.c */
|
||||
#define cvt0565to8888(s) (((((s) << 3) & 0xf8) | (((s) >> 2) & 0x7)) | \
|
||||
((((s) << 5) & 0xfc00) | (((s) >> 1) & 0x300)) | \
|
||||
((((s) << 8) & 0xf80000) | (((s) << 3) & 0x70000)))
|
||||
|
||||
#if IMAGE_BYTE_ORDER == MSBFirst
|
||||
#define Fetch24(a) ((unsigned long) (a) & 1 ? \
|
||||
((*(a) << 16) | *((CARD16 *) ((a)+1))) : \
|
||||
((*((CARD16 *) (a)) << 8) | *((a)+2)))
|
||||
#define Store24(a,v) ((unsigned long) (a) & 1 ? \
|
||||
((*(a) = (CARD8) ((v) >> 16)), \
|
||||
(*((CARD16 *) ((a)+1)) = (CARD16) (v))) : \
|
||||
((*((CARD16 *) (a)) = (CARD16) ((v) >> 8)), \
|
||||
(*((a)+2) = (CARD8) (v))))
|
||||
#else
|
||||
#define Fetch24(a) ((unsigned long) (a) & 1 ? \
|
||||
((*(a)) | (*((CARD16 *) ((a)+1)) << 8)) : \
|
||||
((*((CARD16 *) (a))) | (*((a)+2) << 16)))
|
||||
#define Store24(a,v) ((unsigned long) (a) & 1 ? \
|
||||
((*(a) = (CARD8) (v)), \
|
||||
(*((CARD16 *) ((a)+1)) = (CARD16) ((v) >> 8))) : \
|
||||
((*((CARD16 *) (a)) = (CARD16) (v)),\
|
||||
(*((a)+2) = (CARD8) ((v) >> 16))))
|
||||
#endif
|
||||
|
||||
#define fbComposeGetSolid(pict, bits) { \
|
||||
FbBits *__bits__; \
|
||||
FbStride __stride__; \
|
||||
int __bpp__; \
|
||||
int __xoff__,__yoff__; \
|
||||
\
|
||||
fbGetDrawable((pict)->pDrawable,__bits__,__stride__,__bpp__,__xoff__,__yoff__); \
|
||||
switch (__bpp__) { \
|
||||
case 32: \
|
||||
(bits) = *(CARD32 *) __bits__; \
|
||||
break; \
|
||||
case 24: \
|
||||
(bits) = Fetch24 ((CARD8 *) __bits__); \
|
||||
break; \
|
||||
case 16: \
|
||||
(bits) = *(CARD16 *) __bits__; \
|
||||
(bits) = cvt0565to8888(bits); \
|
||||
break; \
|
||||
default: \
|
||||
return; \
|
||||
} \
|
||||
/* manage missing src alpha */ \
|
||||
if ((pict)->pFormat->direct.alphaMask == 0) \
|
||||
(bits) |= 0xff000000; \
|
||||
}
|
||||
|
||||
#define fbComposeGetStart(pict,x,y,type,stride,line,mul) {\
|
||||
FbBits *__bits__; \
|
||||
FbStride __stride__; \
|
||||
int __bpp__; \
|
||||
int __xoff__,__yoff__; \
|
||||
\
|
||||
fbGetDrawable((pict)->pDrawable,__bits__,__stride__,__bpp__,__xoff__,__yoff__); \
|
||||
(stride) = __stride__ * sizeof (FbBits) / sizeof (type); \
|
||||
(line) = ((type *) __bits__) + (stride) * ((y) - __yoff__) + (mul) * ((x) - __xoff__); \
|
||||
}
|
||||
|
||||
|
||||
/* Optimized version of fbCompositeSolidMask_nx8x8888 */
|
||||
void
|
||||
SafeAlphaCompositeSolidMask_nx8x8888(
|
||||
CARD8 op,
|
||||
PicturePtr pSrc,
|
||||
PicturePtr pMask,
|
||||
PicturePtr pDst,
|
||||
INT16 xSrc,
|
||||
INT16 ySrc,
|
||||
INT16 xMask,
|
||||
INT16 yMask,
|
||||
INT16 xDst,
|
||||
INT16 yDst,
|
||||
CARD16 width,
|
||||
CARD16 height)
|
||||
{
|
||||
CARD32 src, srca;
|
||||
CARD32 *dstLine, *dst, d, dstMask;
|
||||
CARD8 *maskLine, *mask, m;
|
||||
FbStride dstStride, maskStride;
|
||||
CARD16 w;
|
||||
|
||||
fbComposeGetSolid(pSrc, src);
|
||||
|
||||
dstMask = FbFullMask (pDst->pDrawable->depth);
|
||||
srca = src >> 24;
|
||||
if (src == 0)
|
||||
return;
|
||||
|
||||
fbComposeGetStart (pDst, xDst, yDst, CARD32, dstStride, dstLine, 1);
|
||||
fbComposeGetStart (pMask, xMask, yMask, CARD8, maskStride, maskLine, 1);
|
||||
|
||||
if (dstMask == FB_ALLONES && pDst->pDrawable->bitsPerPixel == 32 &&
|
||||
width * height > rootless_CompositePixels_threshold &&
|
||||
SCREENREC(pDst->pDrawable->pScreen)->imp->CompositePixels)
|
||||
{
|
||||
void *srcp[2], *destp[2];
|
||||
unsigned int dest_rowbytes[2];
|
||||
unsigned int fn;
|
||||
|
||||
srcp[0] = &src; srcp[1] = &src;
|
||||
/* null rowbytes pointer means use first value as a constant */
|
||||
destp[0] = dstLine; destp[1] = dstLine;
|
||||
dest_rowbytes[0] = dstStride * 4; dest_rowbytes[1] = dest_rowbytes[0];
|
||||
fn = RL_COMPOSITE_FUNCTION(RL_COMPOSITE_OVER, RL_DEPTH_ARGB8888,
|
||||
RL_DEPTH_A8, RL_DEPTH_ARGB8888);
|
||||
|
||||
if (SCREENREC(pDst->pDrawable->pScreen)->imp->CompositePixels(
|
||||
width, height, fn, srcp, NULL,
|
||||
maskLine, maskStride,
|
||||
destp, dest_rowbytes) == Success)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
while (height--)
|
||||
{
|
||||
dst = dstLine;
|
||||
dstLine += dstStride;
|
||||
mask = maskLine;
|
||||
maskLine += maskStride;
|
||||
w = width;
|
||||
|
||||
while (w--)
|
||||
{
|
||||
m = *mask++;
|
||||
if (m == 0xff)
|
||||
{
|
||||
if (srca == 0xff)
|
||||
*dst = src & dstMask;
|
||||
else
|
||||
*dst = fbOver (src, *dst) & dstMask;
|
||||
}
|
||||
else if (m)
|
||||
{
|
||||
d = fbIn (src, m);
|
||||
*dst = fbOver (d, *dst) & dstMask;
|
||||
}
|
||||
dst++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
SafeAlphaCompositeGeneral(
|
||||
CARD8 op,
|
||||
PicturePtr pSrc,
|
||||
PicturePtr pMask,
|
||||
PicturePtr pDst,
|
||||
INT16 xSrc,
|
||||
INT16 ySrc,
|
||||
INT16 xMask,
|
||||
INT16 yMask,
|
||||
INT16 xDst,
|
||||
INT16 yDst,
|
||||
CARD16 width,
|
||||
CARD16 height)
|
||||
{
|
||||
FbCompositeOperand src[4],msk[4],dst[4],*pmsk;
|
||||
FbCompositeOperand *srcPict, *srcAlpha;
|
||||
FbCompositeOperand *dstPict, *dstAlpha;
|
||||
FbCompositeOperand *mskPict = 0, *mskAlpha = 0;
|
||||
FbCombineFunc f;
|
||||
int w;
|
||||
|
||||
if (!fbBuildCompositeOperand (pSrc, src, xSrc, ySrc, TRUE, TRUE))
|
||||
return;
|
||||
if (!fbBuildCompositeOperand (pDst, dst, xDst, yDst, FALSE, TRUE))
|
||||
return;
|
||||
|
||||
// Use SafeAlpha operands for on screen picture formats
|
||||
if (pDst->format == PICT_x8r8g8b8) {
|
||||
dst[0].store = SafeAlphaStore_x8r8g8b8;
|
||||
}
|
||||
|
||||
if (pSrc->alphaMap)
|
||||
{
|
||||
srcPict = &src[1];
|
||||
srcAlpha = &src[2];
|
||||
}
|
||||
else
|
||||
{
|
||||
srcPict = &src[0];
|
||||
srcAlpha = 0;
|
||||
}
|
||||
if (pDst->alphaMap)
|
||||
{
|
||||
dstPict = &dst[1];
|
||||
dstAlpha = &dst[2];
|
||||
}
|
||||
else
|
||||
{
|
||||
dstPict = &dst[0];
|
||||
dstAlpha = 0;
|
||||
}
|
||||
f = fbCombineFuncU[op];
|
||||
if (pMask)
|
||||
{
|
||||
if (!fbBuildCompositeOperand (pMask, msk, xMask, yMask, TRUE, TRUE))
|
||||
return;
|
||||
pmsk = msk;
|
||||
if (pMask->componentAlpha)
|
||||
f = fbCombineFuncC[op];
|
||||
if (pMask->alphaMap)
|
||||
{
|
||||
mskPict = &msk[1];
|
||||
mskAlpha = &msk[2];
|
||||
}
|
||||
else
|
||||
{
|
||||
mskPict = &msk[0];
|
||||
mskAlpha = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
pmsk = 0;
|
||||
while (height--)
|
||||
{
|
||||
w = width;
|
||||
|
||||
while (w--)
|
||||
{
|
||||
(*f) (src, pmsk, dst);
|
||||
(*src->over) (src);
|
||||
(*dst->over) (dst);
|
||||
if (pmsk)
|
||||
(*pmsk->over) (pmsk);
|
||||
}
|
||||
(*src->down) (src);
|
||||
(*dst->down) (dst);
|
||||
if (pmsk)
|
||||
(*pmsk->down) (pmsk);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
SafeAlphaComposite(
|
||||
CARD8 op,
|
||||
PicturePtr pSrc,
|
||||
PicturePtr pMask,
|
||||
PicturePtr pDst,
|
||||
INT16 xSrc,
|
||||
INT16 ySrc,
|
||||
INT16 xMask,
|
||||
INT16 yMask,
|
||||
INT16 xDst,
|
||||
INT16 yDst,
|
||||
CARD16 width,
|
||||
CARD16 height)
|
||||
{
|
||||
RegionRec region;
|
||||
int n;
|
||||
BoxPtr pbox;
|
||||
CompositeFunc func;
|
||||
Bool srcRepeat = pSrc->repeat;
|
||||
Bool maskRepeat = FALSE;
|
||||
Bool srcAlphaMap = pSrc->alphaMap != 0;
|
||||
Bool maskAlphaMap = FALSE;
|
||||
Bool dstAlphaMap = pDst->alphaMap != 0;
|
||||
int x_msk, y_msk, x_src, y_src, x_dst, y_dst;
|
||||
int w, h, w_this, h_this;
|
||||
int dstDepth = pDst->pDrawable->depth;
|
||||
|
||||
xDst += pDst->pDrawable->x;
|
||||
yDst += pDst->pDrawable->y;
|
||||
xSrc += pSrc->pDrawable->x;
|
||||
ySrc += pSrc->pDrawable->y;
|
||||
if (pMask)
|
||||
{
|
||||
xMask += pMask->pDrawable->x;
|
||||
yMask += pMask->pDrawable->y;
|
||||
maskRepeat = pMask->repeat;
|
||||
maskAlphaMap = pMask->alphaMap != 0;
|
||||
}
|
||||
|
||||
if (!miComputeCompositeRegion (®ion,
|
||||
pSrc,
|
||||
pMask,
|
||||
pDst,
|
||||
xSrc,
|
||||
ySrc,
|
||||
xMask,
|
||||
yMask,
|
||||
xDst,
|
||||
yDst,
|
||||
width,
|
||||
height))
|
||||
return;
|
||||
|
||||
// To preserve the alpha channel we have a special,
|
||||
// non-optimzied compositor.
|
||||
func = SafeAlphaCompositeGeneral;
|
||||
|
||||
/*
|
||||
* We can use the more optimized fbpict code, but it sets bits above
|
||||
* the depth to zero. Temporarily adjust destination depth if needed.
|
||||
*/
|
||||
if (pDst->pDrawable->type == DRAWABLE_WINDOW
|
||||
&& pDst->pDrawable->depth == 24
|
||||
&& pDst->pDrawable->bitsPerPixel == 32)
|
||||
{
|
||||
pDst->pDrawable->depth = 32;
|
||||
}
|
||||
|
||||
if (!pSrc->transform && !(pMask && pMask->transform))
|
||||
if (!maskAlphaMap && !srcAlphaMap && !dstAlphaMap)
|
||||
switch (op) {
|
||||
case PictOpOver:
|
||||
if (pMask)
|
||||
{
|
||||
if (srcRepeat &&
|
||||
pSrc->pDrawable->width == 1 &&
|
||||
pSrc->pDrawable->height == 1)
|
||||
{
|
||||
srcRepeat = FALSE;
|
||||
if (PICT_FORMAT_COLOR(pSrc->format)) {
|
||||
switch (pMask->format) {
|
||||
case PICT_a8:
|
||||
switch (pDst->format) {
|
||||
case PICT_r5g6b5:
|
||||
case PICT_b5g6r5:
|
||||
func = fbCompositeSolidMask_nx8x0565;
|
||||
break;
|
||||
case PICT_r8g8b8:
|
||||
case PICT_b8g8r8:
|
||||
func = fbCompositeSolidMask_nx8x0888;
|
||||
break;
|
||||
case PICT_a8r8g8b8:
|
||||
case PICT_x8r8g8b8:
|
||||
case PICT_a8b8g8r8:
|
||||
case PICT_x8b8g8r8:
|
||||
func = SafeAlphaCompositeSolidMask_nx8x8888;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case PICT_a8r8g8b8:
|
||||
if (pMask->componentAlpha) {
|
||||
switch (pDst->format) {
|
||||
case PICT_a8r8g8b8:
|
||||
case PICT_x8r8g8b8:
|
||||
func = fbCompositeSolidMask_nx8888x8888C;
|
||||
break;
|
||||
case PICT_r5g6b5:
|
||||
func = fbCompositeSolidMask_nx8888x0565C;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case PICT_a8b8g8r8:
|
||||
if (pMask->componentAlpha) {
|
||||
switch (pDst->format) {
|
||||
case PICT_a8b8g8r8:
|
||||
case PICT_x8b8g8r8:
|
||||
func = fbCompositeSolidMask_nx8888x8888C;
|
||||
break;
|
||||
case PICT_b5g6r5:
|
||||
func = fbCompositeSolidMask_nx8888x0565C;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case PICT_a1:
|
||||
switch (pDst->format) {
|
||||
case PICT_r5g6b5:
|
||||
case PICT_b5g6r5:
|
||||
case PICT_r8g8b8:
|
||||
case PICT_b8g8r8:
|
||||
case PICT_a8r8g8b8:
|
||||
case PICT_x8r8g8b8:
|
||||
case PICT_a8b8g8r8:
|
||||
case PICT_x8b8g8r8:
|
||||
func = fbCompositeSolidMask_nx1xn;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (pSrc->format) {
|
||||
case PICT_a8r8g8b8:
|
||||
case PICT_x8r8g8b8:
|
||||
switch (pDst->format) {
|
||||
case PICT_a8r8g8b8:
|
||||
case PICT_x8r8g8b8:
|
||||
func = fbCompositeSrc_8888x8888;
|
||||
break;
|
||||
case PICT_r8g8b8:
|
||||
func = fbCompositeSrc_8888x0888;
|
||||
break;
|
||||
case PICT_r5g6b5:
|
||||
func = fbCompositeSrc_8888x0565;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case PICT_a8b8g8r8:
|
||||
case PICT_x8b8g8r8:
|
||||
switch (pDst->format) {
|
||||
case PICT_a8b8g8r8:
|
||||
case PICT_x8b8g8r8:
|
||||
func = fbCompositeSrc_8888x8888;
|
||||
break;
|
||||
case PICT_b8g8r8:
|
||||
func = fbCompositeSrc_8888x0888;
|
||||
break;
|
||||
case PICT_b5g6r5:
|
||||
func = fbCompositeSrc_8888x0565;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case PICT_r5g6b5:
|
||||
switch (pDst->format) {
|
||||
case PICT_r5g6b5:
|
||||
func = fbCompositeSrc_0565x0565;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case PICT_b5g6r5:
|
||||
switch (pDst->format) {
|
||||
case PICT_b5g6r5:
|
||||
func = fbCompositeSrc_0565x0565;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case PictOpAdd:
|
||||
if (pMask == 0)
|
||||
{
|
||||
switch (pSrc->format) {
|
||||
case PICT_a8r8g8b8:
|
||||
switch (pDst->format) {
|
||||
case PICT_a8r8g8b8:
|
||||
func = fbCompositeSrcAdd_8888x8888;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case PICT_a8b8g8r8:
|
||||
switch (pDst->format) {
|
||||
case PICT_a8b8g8r8:
|
||||
func = fbCompositeSrcAdd_8888x8888;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case PICT_a8:
|
||||
switch (pDst->format) {
|
||||
case PICT_a8:
|
||||
func = fbCompositeSrcAdd_8000x8000;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case PICT_a1:
|
||||
switch (pDst->format) {
|
||||
case PICT_a1:
|
||||
func = fbCompositeSrcAdd_1000x1000;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
n = REGION_NUM_RECTS (®ion);
|
||||
pbox = REGION_RECTS (®ion);
|
||||
while (n--)
|
||||
{
|
||||
h = pbox->y2 - pbox->y1;
|
||||
y_src = pbox->y1 - yDst + ySrc;
|
||||
y_msk = pbox->y1 - yDst + yMask;
|
||||
y_dst = pbox->y1;
|
||||
while (h)
|
||||
{
|
||||
h_this = h;
|
||||
w = pbox->x2 - pbox->x1;
|
||||
x_src = pbox->x1 - xDst + xSrc;
|
||||
x_msk = pbox->x1 - xDst + xMask;
|
||||
x_dst = pbox->x1;
|
||||
if (maskRepeat)
|
||||
{
|
||||
y_msk = mod (y_msk, pMask->pDrawable->height);
|
||||
if (h_this > pMask->pDrawable->height - y_msk)
|
||||
h_this = pMask->pDrawable->height - y_msk;
|
||||
}
|
||||
if (srcRepeat)
|
||||
{
|
||||
y_src = mod (y_src, pSrc->pDrawable->height);
|
||||
if (h_this > pSrc->pDrawable->height - y_src)
|
||||
h_this = pSrc->pDrawable->height - y_src;
|
||||
}
|
||||
while (w)
|
||||
{
|
||||
w_this = w;
|
||||
if (maskRepeat)
|
||||
{
|
||||
x_msk = mod (x_msk, pMask->pDrawable->width);
|
||||
if (w_this > pMask->pDrawable->width - x_msk)
|
||||
w_this = pMask->pDrawable->width - x_msk;
|
||||
}
|
||||
if (srcRepeat)
|
||||
{
|
||||
x_src = mod (x_src, pSrc->pDrawable->width);
|
||||
if (w_this > pSrc->pDrawable->width - x_src)
|
||||
w_this = pSrc->pDrawable->width - x_src;
|
||||
}
|
||||
(*func) (op, pSrc, pMask, pDst,
|
||||
x_src, y_src, x_msk, y_msk, x_dst, y_dst,
|
||||
w_this, h_this);
|
||||
w -= w_this;
|
||||
x_src += w_this;
|
||||
x_msk += w_this;
|
||||
x_dst += w_this;
|
||||
}
|
||||
h -= h_this;
|
||||
y_src += h_this;
|
||||
y_msk += h_this;
|
||||
y_dst += h_this;
|
||||
}
|
||||
pbox++;
|
||||
}
|
||||
REGION_UNINIT (pDst->pDrawable->pScreen, ®ion);
|
||||
|
||||
// Reset destination depth to its true value
|
||||
pDst->pDrawable->depth = dstDepth;
|
||||
}
|
||||
|
||||
#endif /* RENDER */
|
||||
173
miext/rootless/safeAlpha/safeAlphaWindow.c
Normal file
173
miext/rootless/safeAlpha/safeAlphaWindow.c
Normal file
|
|
@ -0,0 +1,173 @@
|
|||
/*
|
||||
* Specialized window functions to protect the alpha channel
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 2002-2003 Torrey T. Lyons. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* Except as contained in this notice, the name(s) of the above copyright
|
||||
* holders shall not be used in advertising or otherwise to promote the sale,
|
||||
* use or other dealings in this Software without prior written authorization.
|
||||
*/
|
||||
/* Portions of this file are based on fbwindow.c, which contains the
|
||||
* following copyright:
|
||||
*
|
||||
* Copyright © 1998 Keith Packard
|
||||
*/
|
||||
/* $XFree86: xc/programs/Xserver/miext/rootless/safeAlpha/safeAlphaWindow.c,v 1.1 2003/09/16 00:36:20 torrey Exp $ */
|
||||
|
||||
#include "fb.h"
|
||||
#include "safeAlpha.h"
|
||||
|
||||
#ifdef PANORAMIX
|
||||
#include "panoramiX.h"
|
||||
#include "panoramiXsrv.h"
|
||||
#endif
|
||||
|
||||
/*
|
||||
* SafeAlphaFillRegionTiled
|
||||
* Fill using a tile while leaving the alpha channel untouched.
|
||||
* Based on fbfillRegionTiled.
|
||||
*/
|
||||
void
|
||||
SafeAlphaFillRegionTiled(
|
||||
DrawablePtr pDrawable,
|
||||
RegionPtr pRegion,
|
||||
PixmapPtr pTile)
|
||||
{
|
||||
FbBits *dst;
|
||||
FbStride dstStride;
|
||||
int dstBpp;
|
||||
int dstXoff, dstYoff;
|
||||
FbBits *tile;
|
||||
FbStride tileStride;
|
||||
int tileBpp;
|
||||
int tileXoff, tileYoff; /* XXX assumed to be zero */
|
||||
int tileWidth, tileHeight;
|
||||
int n = REGION_NUM_RECTS(pRegion);
|
||||
BoxPtr pbox = REGION_RECTS(pRegion);
|
||||
int xRot = pDrawable->x;
|
||||
int yRot = pDrawable->y;
|
||||
FbBits planeMask;
|
||||
|
||||
#ifdef PANORAMIX
|
||||
if(!noPanoramiXExtension)
|
||||
{
|
||||
int index = pDrawable->pScreen->myNum;
|
||||
if(&WindowTable[index]->drawable == pDrawable)
|
||||
{
|
||||
xRot -= panoramiXdataPtr[index].x;
|
||||
yRot -= panoramiXdataPtr[index].y;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
fbGetDrawable (pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff);
|
||||
fbGetDrawable (&pTile->drawable, tile, tileStride, tileBpp,
|
||||
tileXoff, tileYoff);
|
||||
tileWidth = pTile->drawable.width;
|
||||
tileHeight = pTile->drawable.height;
|
||||
xRot += dstXoff;
|
||||
yRot += dstYoff;
|
||||
planeMask = FB_ALLONES & ~RootlessAlphaMask(dstBpp);
|
||||
|
||||
while (n--)
|
||||
{
|
||||
fbTile (dst + (pbox->y1 + dstYoff) * dstStride,
|
||||
dstStride,
|
||||
(pbox->x1 + dstXoff) * dstBpp,
|
||||
(pbox->x2 - pbox->x1) * dstBpp,
|
||||
pbox->y2 - pbox->y1,
|
||||
tile,
|
||||
tileStride,
|
||||
tileWidth * dstBpp,
|
||||
tileHeight,
|
||||
GXcopy,
|
||||
planeMask,
|
||||
dstBpp,
|
||||
xRot * dstBpp,
|
||||
yRot - pbox->y1);
|
||||
pbox++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* SafeAlphaPaintWindow
|
||||
* Paint the window while filling in the alpha channel with all on.
|
||||
* We can't use fbPaintWindow because it zeros the alpha channel.
|
||||
*/
|
||||
void
|
||||
SafeAlphaPaintWindow(
|
||||
WindowPtr pWin,
|
||||
RegionPtr pRegion,
|
||||
int what)
|
||||
{
|
||||
switch (what) {
|
||||
case PW_BACKGROUND:
|
||||
|
||||
switch (pWin->backgroundState) {
|
||||
case None:
|
||||
break;
|
||||
case ParentRelative:
|
||||
do {
|
||||
pWin = pWin->parent;
|
||||
} while (pWin->backgroundState == ParentRelative);
|
||||
(*pWin->drawable.pScreen->PaintWindowBackground)(pWin, pRegion,
|
||||
what);
|
||||
break;
|
||||
case BackgroundPixmap:
|
||||
SafeAlphaFillRegionTiled (&pWin->drawable,
|
||||
pRegion,
|
||||
pWin->background.pixmap);
|
||||
break;
|
||||
case BackgroundPixel:
|
||||
{
|
||||
Pixel pixel = pWin->background.pixel |
|
||||
RootlessAlphaMask(pWin->drawable.bitsPerPixel);
|
||||
fbFillRegionSolid (&pWin->drawable, pRegion, 0,
|
||||
fbReplicatePixel (pixel,
|
||||
pWin->drawable.bitsPerPixel));
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case PW_BORDER:
|
||||
if (pWin->borderIsPixel)
|
||||
{
|
||||
Pixel pixel = pWin->border.pixel |
|
||||
RootlessAlphaMask(pWin->drawable.bitsPerPixel);
|
||||
fbFillRegionSolid (&pWin->drawable, pRegion, 0,
|
||||
fbReplicatePixel (pixel,
|
||||
pWin->drawable.bitsPerPixel));
|
||||
}
|
||||
else
|
||||
{
|
||||
WindowPtr pBgWin;
|
||||
for (pBgWin = pWin; pBgWin->backgroundState == ParentRelative;
|
||||
pBgWin = pBgWin->parent);
|
||||
|
||||
SafeAlphaFillRegionTiled (&pBgWin->drawable,
|
||||
pRegion,
|
||||
pWin->border.pixmap);
|
||||
}
|
||||
break;
|
||||
}
|
||||
fbValidateDrawable (&pWin->drawable);
|
||||
}
|
||||
Loading…
Reference in a new issue