diff options
Diffstat (limited to 'nx-X11/programs/Xserver/miext/rootless/safeAlpha')
4 files changed, 881 insertions, 0 deletions
diff --git a/nx-X11/programs/Xserver/miext/rootless/safeAlpha/Imakefile b/nx-X11/programs/Xserver/miext/rootless/safeAlpha/Imakefile new file mode 100644 index 000000000..bb14bb146 --- /dev/null +++ b/nx-X11/programs/Xserver/miext/rootless/safeAlpha/Imakefile @@ -0,0 +1,18 @@ +XCOMM $XFree86: xc/programs/Xserver/miext/rootless/Imakefile,v 1.1 2003/04/15 01:05:44 torrey Exp $ + +#include <Server.tmpl> + +SRCS = safeAlphaPicture.c \ + safeAlphaWindow.c + +OBJS = safeAlphaPicture.o \ + safeAlphaWindow.o + + INCLUDES = -I. -I$(SERVERSRC)/fb -I$(SERVERSRC)/mi -I$(SERVERSRC)/include \ + -I$(XINCLUDESRC) -I$(FONTINCSRC) -I$(SERVERSRC)/render \ + -I$(EXTINCSRC) -I$(SERVERSRC)/Xext -I.. + +NormalLibraryObjectRule() +LibraryModuleTarget(safeAlpha,$(OBJS)) + +DependTarget() diff --git a/nx-X11/programs/Xserver/miext/rootless/safeAlpha/safeAlpha.h b/nx-X11/programs/Xserver/miext/rootless/safeAlpha/safeAlpha.h new file mode 100644 index 000000000..63922aeec --- /dev/null +++ b/nx-X11/programs/Xserver/miext/rootless/safeAlpha/safeAlpha.h @@ -0,0 +1,45 @@ +/* + * 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" + +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 */ diff --git a/nx-X11/programs/Xserver/miext/rootless/safeAlpha/safeAlphaPicture.c b/nx-X11/programs/Xserver/miext/rootless/safeAlpha/safeAlphaPicture.c new file mode 100644 index 000000000..f73a3b5c1 --- /dev/null +++ b/nx-X11/programs/Xserver/miext/rootless/safeAlpha/safeAlphaPicture.c @@ -0,0 +1,643 @@ +/* + * 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" +#include "rootlessCommon.h" + +# define mod(a,b) ((b) == 1 ? 0 : (a) >= 0 ? (a) % (b) : (b) - (-a) % (b)) + + +typedef void (*CompositeFunc) (CARD8 op, + PicturePtr pSrc, + PicturePtr pMask, + PicturePtr pDst, + INT16 xSrc, + INT16 ySrc, + INT16 xMask, + INT16 yMask, + INT16 xDst, + INT16 yDst, + CARD16 width, + CARD16 height); + + +/* 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, pDst->format); + + 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 +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 = 0; + 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; + int oldFormat = pDst->format; + + 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; + } + + + /* + * 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; + } + /* For rootless preserve the alpha in x8r8g8b8 which really is + * a8r8g8b8 + */ + if (oldFormat == PICT_x8r8g8b8) + { + pDst->format = PICT_a8r8g8b8; + } + + + + if (!pSrc->transform && !(pMask && pMask->transform)) + if (!maskAlphaMap && !srcAlphaMap && !dstAlphaMap) + switch (op) { + case PictOpSrc: +#ifdef USE_MMX + if (!pMask && pSrc->format == pDst->format && + pSrc->pDrawable != pDst->pDrawable) + { + func = fbCompositeCopyAreammx; + } +#endif + break; + 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: +#ifdef USE_MMX + if (fbHaveMMX()) + func = fbCompositeSolidMask_nx8x0565mmx; + else +#endif + 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: +#ifdef USE_MMX + if (fbHaveMMX()) + func = fbCompositeSolidMask_nx8888x8888Cmmx; + else +#endif + func = fbCompositeSolidMask_nx8888x8888C; + break; + case PICT_r5g6b5: +#ifdef USE_MMX + if (fbHaveMMX()) + func = fbCompositeSolidMask_nx8888x0565Cmmx; + else +#endif + func = fbCompositeSolidMask_nx8888x0565C; + break; + } + } + break; + case PICT_a8b8g8r8: + if (pMask->componentAlpha) { + switch (pDst->format) { + case PICT_a8b8g8r8: + case PICT_x8b8g8r8: +#ifdef USE_MMX + if (fbHaveMMX()) + func = fbCompositeSolidMask_nx8888x8888Cmmx; + else +#endif + func = fbCompositeSolidMask_nx8888x8888C; + break; + case PICT_b5g6r5: +#ifdef USE_MMX + if (fbHaveMMX()) + func = fbCompositeSolidMask_nx8888x0565Cmmx; + else +#endif + 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; + } + break; + } + } + } + else /* has mask and non-repeating source */ + { + if (pSrc->pDrawable == pMask->pDrawable && + xSrc == xMask && ySrc == yMask && + !pMask->componentAlpha) + { + /* source == mask: non-premultiplied data */ + switch (pSrc->format) { + case PICT_x8b8g8r8: + switch (pMask->format) { + case PICT_a8r8g8b8: + case PICT_a8b8g8r8: + switch (pDst->format) { + case PICT_a8r8g8b8: + case PICT_x8r8g8b8: +#ifdef USE_MMX + if (fbHaveMMX()) + func = fbCompositeSrc_8888RevNPx8888mmx; +#endif + break; + case PICT_r5g6b5: +#ifdef USE_MMX + if (fbHaveMMX()) + func = fbCompositeSrc_8888RevNPx0565mmx; +#endif + break; + } + break; + } + break; + case PICT_x8r8g8b8: + switch (pMask->format) { + case PICT_a8r8g8b8: + case PICT_a8b8g8r8: + switch (pDst->format) { + case PICT_a8b8g8r8: + case PICT_x8b8g8r8: +#ifdef USE_MMX + if (fbHaveMMX()) + func = fbCompositeSrc_8888RevNPx8888mmx; +#endif + break; + case PICT_r5g6b5: +#ifdef USE_MMX + if (fbHaveMMX()) + func = fbCompositeSrc_8888RevNPx0565mmx; +#endif + break; + } + break; + } + break; + } + break; + } + else + { + /* non-repeating source, repeating mask => translucent window */ + if (maskRepeat && + pMask->pDrawable->width == 1 && + pMask->pDrawable->height == 1) + { + if (pSrc->format == PICT_x8r8g8b8 && + pDst->format == PICT_x8r8g8b8 && + pMask->format == PICT_a8) + { +#ifdef USE_MMX + if (fbHaveMMX()) + func = fbCompositeSrc_8888x8x8888mmx; +#endif + } + } + } + } + } + else /* no mask */ + { + if (srcRepeat && + pSrc->pDrawable->width == 1 && + pSrc->pDrawable->height == 1) + { + /* no mask and repeating source */ + switch (pSrc->format) { + case PICT_a8r8g8b8: + switch (pDst->format) { + case PICT_a8r8g8b8: + case PICT_x8r8g8b8: +#ifdef USE_MMX + if (fbHaveMMX()) + { + srcRepeat = FALSE; + func = fbCompositeSolid_nx8888mmx; + } +#endif + break; + case PICT_r5g6b5: +#ifdef USE_MMX + if (fbHaveMMX()) + { + srcRepeat = FALSE; + func = fbCompositeSolid_nx0565mmx; + } +#endif + break; + } + break; + } + } + else + { + switch (pSrc->format) { + case PICT_a8r8g8b8: + switch (pDst->format) { + case PICT_a8r8g8b8: + case PICT_x8r8g8b8: +#ifdef USE_MMX + if (fbHaveMMX()) + func = fbCompositeSrc_8888x8888mmx; + else +#endif + func = fbCompositeSrc_8888x8888; + break; + case PICT_r8g8b8: + func = fbCompositeSrc_8888x0888; + break; + case PICT_r5g6b5: + func = fbCompositeSrc_8888x0565; + break; + } + break; + case PICT_x8r8g8b8: + switch (pDst->format) { + case PICT_a8r8g8b8: + case PICT_x8r8g8b8: +#ifdef USE_MMX + if (fbHaveMMX()) + func = fbCompositeCopyAreammx; +#endif + break; + } + case PICT_x8b8g8r8: + switch (pDst->format) { + case PICT_a8b8g8r8: + case PICT_x8b8g8r8: +#ifdef USE_MMX + if (fbHaveMMX()) + func = fbCompositeCopyAreammx; +#endif + break; + } + break; + case PICT_a8b8g8r8: + switch (pDst->format) { + case PICT_a8b8g8r8: + case PICT_x8b8g8r8: +#ifdef USE_MMX + if (fbHaveMMX()) + func = fbCompositeSrc_8888x8888mmx; + else +#endif + 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: +#ifdef USE_MMX + if (fbHaveMMX()) + func = fbCompositeSrcAdd_8888x8888mmx; + else +#endif + func = fbCompositeSrcAdd_8888x8888; + break; + } + break; + case PICT_a8b8g8r8: + switch (pDst->format) { + case PICT_a8b8g8r8: +#ifdef USE_MMX + if (fbHaveMMX()) + func = fbCompositeSrcAdd_8888x8888mmx; + else +#endif + func = fbCompositeSrcAdd_8888x8888; + break; + } + break; + case PICT_a8: + switch (pDst->format) { + case PICT_a8: +#ifdef USE_MMX + if (fbHaveMMX()) + func = fbCompositeSrcAdd_8000x8000mmx; + else +#endif + func = fbCompositeSrcAdd_8000x8000; + break; + } + break; + case PICT_a1: + switch (pDst->format) { + case PICT_a1: + func = fbCompositeSrcAdd_1000x1000; + break; + } + break; + } + } + break; + } + + if (!func) { + /* no fast path, use the general code */ + fbCompositeGeneral(op, pSrc, pMask, pDst, xSrc, ySrc, xMask, yMask, xDst, yDst, width, height); + // Reset destination depth and format to their true value + pDst->pDrawable->depth = dstDepth; + pDst->format = oldFormat; + return; + } + + if (!miComputeCompositeRegion (®ion, + pSrc, + pMask, + pDst, + xSrc, + ySrc, + xMask, + yMask, + xDst, + yDst, + width, + height)) + return; + + 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/format to its true value + pDst->pDrawable->depth = dstDepth; + pDst->format = oldFormat; +} + +#endif /* RENDER */ diff --git a/nx-X11/programs/Xserver/miext/rootless/safeAlpha/safeAlphaWindow.c b/nx-X11/programs/Xserver/miext/rootless/safeAlpha/safeAlphaWindow.c new file mode 100644 index 000000000..ff812385b --- /dev/null +++ b/nx-X11/programs/Xserver/miext/rootless/safeAlpha/safeAlphaWindow.c @@ -0,0 +1,175 @@ +/* $XdotOrg: xc/programs/Xserver/miext/rootless/safeAlpha/safeAlphaWindow.c,v 1.4 2005/07/01 22:43:42 daniels Exp $ */ +/* + * 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" +#include "rootlessCommon.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); +} |