diff options
Diffstat (limited to 'xorg-server/fb/fbgc.c')
-rw-r--r-- | xorg-server/fb/fbgc.c | 614 |
1 files changed, 307 insertions, 307 deletions
diff --git a/xorg-server/fb/fbgc.c b/xorg-server/fb/fbgc.c index e9511b6c5..8108c3acb 100644 --- a/xorg-server/fb/fbgc.c +++ b/xorg-server/fb/fbgc.c @@ -1,307 +1,307 @@ -/*
- * Copyright © 1998 Keith Packard
- *
- * 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.
- */
-
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
-#include <stdlib.h>
-
-#include "fb.h"
-
-const GCFuncs fbGCFuncs = {
- fbValidateGC,
- miChangeGC,
- miCopyGC,
- miDestroyGC,
- miChangeClip,
- miDestroyClip,
- miCopyClip,
-};
-
-const GCOps fbGCOps = {
- fbFillSpans,
- fbSetSpans,
- fbPutImage,
- fbCopyArea,
- fbCopyPlane,
- fbPolyPoint,
- fbPolyLine,
- fbPolySegment,
- fbPolyRectangle,
- fbPolyArc,
- miFillPolygon,
- fbPolyFillRect,
- fbPolyFillArc,
- miPolyText8,
- miPolyText16,
- miImageText8,
- miImageText16,
- fbImageGlyphBlt,
- fbPolyGlyphBlt,
- fbPushPixels
-};
-
-Bool
-fbCreateGC(GCPtr pGC)
-{
- pGC->ops = (GCOps *) &fbGCOps;
- pGC->funcs = (GCFuncs *) &fbGCFuncs;
-
- /* fb wants to translate before scan conversion */
- pGC->miTranslate = 1;
- pGC->fExpose = 1;
-
- fbGetGCPrivate(pGC)->bpp = BitsPerPixel (pGC->depth);
- return TRUE;
-}
-
-/*
- * Pad pixmap to FB_UNIT bits wide
- */
-void
-fbPadPixmap (PixmapPtr pPixmap)
-{
- int width;
- FbBits *bits;
- FbBits b;
- FbBits mask;
- int height;
- int w;
- int stride;
- int bpp;
- _X_UNUSED int xOff, yOff;
-
- fbGetDrawable (&pPixmap->drawable, bits, stride, bpp, xOff, yOff);
-
- width = pPixmap->drawable.width * pPixmap->drawable.bitsPerPixel;
- height = pPixmap->drawable.height;
- mask = FbBitsMask (0, width);
- while (height--)
- {
- b = READ(bits) & mask;
- w = width;
- while (w < FB_UNIT)
- {
- b = b | FbScrRight(b, w);
- w <<= 1;
- }
- WRITE(bits, b);
- bits += stride;
- }
-
- fbFinishAccess (&pPixmap->drawable);
-}
-
-/*
- * Verify that 'bits' repeats every 'len' bits
- */
-static Bool
-fbBitsRepeat (FbBits bits, int len, int width)
-{
- FbBits mask = FbBitsMask(0, len);
- FbBits orig = bits & mask;
- int i;
-
- if (width > FB_UNIT)
- width = FB_UNIT;
- for (i = 0; i < width / len; i++)
- {
- if ((bits & mask) != orig)
- return FALSE;
- bits = FbScrLeft(bits,len);
- }
- return TRUE;
-}
-
-/*
- * Check whether an entire bitmap line is a repetition of
- * the first 'len' bits
- */
-static Bool
-fbLineRepeat (FbBits *bits, int len, int width)
-{
- FbBits first = bits[0];
-
- if (!fbBitsRepeat (first, len, width))
- return FALSE;
- width = (width + FB_UNIT-1) >> FB_SHIFT;
- bits++;
- while (--width)
- if (READ(bits) != first)
- return FALSE;
- return TRUE;
-}
-
-/*
- * The even stipple code wants the first FB_UNIT/bpp bits on
- * each scanline to represent the entire stipple
- */
-static Bool
-fbCanEvenStipple (PixmapPtr pStipple, int bpp)
-{
- int len = FB_UNIT / bpp;
- FbBits *bits;
- int stride;
- int stip_bpp;
- _X_UNUSED int stipXoff, stipYoff;
- int h;
-
- /* can't even stipple 24bpp drawables */
- if ((bpp & (bpp-1)) != 0)
- return FALSE;
- /* make sure the stipple width is a multiple of the even stipple width */
- if (pStipple->drawable.width % len != 0)
- return FALSE;
- fbGetDrawable (&pStipple->drawable, bits, stride, stip_bpp, stipXoff, stipYoff);
- h = pStipple->drawable.height;
- /* check to see that the stipple repeats horizontally */
- while (h--)
- {
- if (!fbLineRepeat (bits, len, pStipple->drawable.width)) {
- fbFinishAccess (&pStipple->drawable);
- return FALSE;
- }
- bits += stride;
- }
- fbFinishAccess (&pStipple->drawable);
- return TRUE;
-}
-
-void
-fbValidateGC(GCPtr pGC, unsigned long changes, DrawablePtr pDrawable)
-{
- FbGCPrivPtr pPriv = fbGetGCPrivate(pGC);
- FbBits mask;
-
- /*
- * if the client clip is different or moved OR the subwindowMode has
- * changed OR the window's clip has changed since the last validation
- * we need to recompute the composite clip
- */
-
- if ((changes & (GCClipXOrigin|GCClipYOrigin|GCClipMask|GCSubwindowMode)) ||
- (pDrawable->serialNumber != (pGC->serialNumber & DRAWABLE_SERIAL_BITS))
- )
- {
- miComputeCompositeClip (pGC, pDrawable);
- }
-
- if (pPriv->bpp != pDrawable->bitsPerPixel)
- {
- changes |= GCStipple|GCForeground|GCBackground|GCPlaneMask;
- pPriv->bpp = pDrawable->bitsPerPixel;
- }
- if ((changes & GCTile) && fbGetRotatedPixmap(pGC))
- {
- (*pGC->pScreen->DestroyPixmap) (fbGetRotatedPixmap(pGC));
- fbGetRotatedPixmap(pGC) = 0;
- }
-
- if (pGC->fillStyle == FillTiled)
- {
- PixmapPtr pOldTile, pNewTile;
-
- pOldTile = pGC->tile.pixmap;
- if (pOldTile->drawable.bitsPerPixel != pDrawable->bitsPerPixel)
- {
- pNewTile = fbGetRotatedPixmap(pGC);
- if (!pNewTile || pNewTile ->drawable.bitsPerPixel != pDrawable->bitsPerPixel)
- {
- if (pNewTile)
- (*pGC->pScreen->DestroyPixmap) (pNewTile);
- pNewTile = fb24_32ReformatTile (pOldTile, pDrawable->bitsPerPixel);
- }
- if (pNewTile)
- {
- fbGetRotatedPixmap(pGC) = pOldTile;
- pGC->tile.pixmap = pNewTile;
- changes |= GCTile;
- }
- }
- }
- if (changes & GCTile)
- {
- if (!pGC->tileIsPixel &&
- FbEvenTile (pGC->tile.pixmap->drawable.width *
- pDrawable->bitsPerPixel))
- fbPadPixmap (pGC->tile.pixmap);
- }
- if (changes & GCStipple)
- {
- pPriv->evenStipple = FALSE;
-
- if (pGC->stipple) {
-
- /* can we do an even stipple ?? */
- if (FbEvenStip (pGC->stipple->drawable.width,
- pDrawable->bitsPerPixel) &&
- (fbCanEvenStipple (pGC->stipple, pDrawable->bitsPerPixel)))
- pPriv->evenStipple = TRUE;
-
- if (pGC->stipple->drawable.width * pDrawable->bitsPerPixel < FB_UNIT)
- fbPadPixmap (pGC->stipple);
- }
- }
- /*
- * Recompute reduced rop values
- */
- if (changes & (GCForeground|GCBackground|GCPlaneMask|GCFunction))
- {
- int s;
- FbBits depthMask;
-
- mask = FbFullMask(pDrawable->bitsPerPixel);
- depthMask = FbFullMask(pDrawable->depth);
-
- pPriv->fg = pGC->fgPixel & mask;
- pPriv->bg = pGC->bgPixel & mask;
-
- if ((pGC->planemask & depthMask) == depthMask)
- pPriv->pm = mask;
- else
- pPriv->pm = pGC->planemask & mask;
-
- s = pDrawable->bitsPerPixel;
- while (s < FB_UNIT)
- {
- pPriv->fg |= pPriv->fg << s;
- pPriv->bg |= pPriv->bg << s;
- pPriv->pm |= pPriv->pm << s;
- s <<= 1;
- }
- pPriv->and = fbAnd(pGC->alu, pPriv->fg, pPriv->pm);
- pPriv->xor = fbXor(pGC->alu, pPriv->fg, pPriv->pm);
- pPriv->bgand = fbAnd(pGC->alu, pPriv->bg, pPriv->pm);
- pPriv->bgxor = fbXor(pGC->alu, pPriv->bg, pPriv->pm);
- }
- if (changes & GCDashList)
- {
- unsigned short n = pGC->numInDashList;
- unsigned char *dash = pGC->dash;
- unsigned int dashLength = 0;
-
- while (n--)
- dashLength += (unsigned int ) *dash++;
- pPriv->dashLength = dashLength;
- }
-}
+/* + * Copyright © 1998 Keith Packard + * + * 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. + */ + +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#endif + +#include <stdlib.h> + +#include "fb.h" + +const GCFuncs fbGCFuncs = { + fbValidateGC, + miChangeGC, + miCopyGC, + miDestroyGC, + miChangeClip, + miDestroyClip, + miCopyClip, +}; + +const GCOps fbGCOps = { + fbFillSpans, + fbSetSpans, + fbPutImage, + fbCopyArea, + fbCopyPlane, + fbPolyPoint, + fbPolyLine, + fbPolySegment, + fbPolyRectangle, + fbPolyArc, + miFillPolygon, + fbPolyFillRect, + fbPolyFillArc, + miPolyText8, + miPolyText16, + miImageText8, + miImageText16, + fbImageGlyphBlt, + fbPolyGlyphBlt, + fbPushPixels +}; + +Bool +fbCreateGC(GCPtr pGC) +{ + pGC->ops = (GCOps *) &fbGCOps; + pGC->funcs = (GCFuncs *) &fbGCFuncs; + + /* fb wants to translate before scan conversion */ + pGC->miTranslate = 1; + pGC->fExpose = 1; + + fbGetGCPrivate(pGC)->bpp = BitsPerPixel (pGC->depth); + return TRUE; +} + +/* + * Pad pixmap to FB_UNIT bits wide + */ +void +fbPadPixmap (PixmapPtr pPixmap) +{ + int width; + FbBits *bits; + FbBits b; + FbBits mask; + int height; + int w; + int stride; + int bpp; + _X_UNUSED int xOff, yOff; + + fbGetDrawable (&pPixmap->drawable, bits, stride, bpp, xOff, yOff); + + width = pPixmap->drawable.width * pPixmap->drawable.bitsPerPixel; + height = pPixmap->drawable.height; + mask = FbBitsMask (0, width); + while (height--) + { + b = READ(bits) & mask; + w = width; + while (w < FB_UNIT) + { + b = b | FbScrRight(b, w); + w <<= 1; + } + WRITE(bits, b); + bits += stride; + } + + fbFinishAccess (&pPixmap->drawable); +} + +/* + * Verify that 'bits' repeats every 'len' bits + */ +static Bool +fbBitsRepeat (FbBits bits, int len, int width) +{ + FbBits mask = FbBitsMask(0, len); + FbBits orig = bits & mask; + int i; + + if (width > FB_UNIT) + width = FB_UNIT; + for (i = 0; i < width / len; i++) + { + if ((bits & mask) != orig) + return FALSE; + bits = FbScrLeft(bits,len); + } + return TRUE; +} + +/* + * Check whether an entire bitmap line is a repetition of + * the first 'len' bits + */ +static Bool +fbLineRepeat (FbBits *bits, int len, int width) +{ + FbBits first = bits[0]; + + if (!fbBitsRepeat (first, len, width)) + return FALSE; + width = (width + FB_UNIT-1) >> FB_SHIFT; + bits++; + while (--width) + if (READ(bits) != first) + return FALSE; + return TRUE; +} + +/* + * The even stipple code wants the first FB_UNIT/bpp bits on + * each scanline to represent the entire stipple + */ +static Bool +fbCanEvenStipple (PixmapPtr pStipple, int bpp) +{ + int len = FB_UNIT / bpp; + FbBits *bits; + int stride; + int stip_bpp; + _X_UNUSED int stipXoff, stipYoff; + int h; + + /* can't even stipple 24bpp drawables */ + if ((bpp & (bpp-1)) != 0) + return FALSE; + /* make sure the stipple width is a multiple of the even stipple width */ + if (pStipple->drawable.width % len != 0) + return FALSE; + fbGetDrawable (&pStipple->drawable, bits, stride, stip_bpp, stipXoff, stipYoff); + h = pStipple->drawable.height; + /* check to see that the stipple repeats horizontally */ + while (h--) + { + if (!fbLineRepeat (bits, len, pStipple->drawable.width)) { + fbFinishAccess (&pStipple->drawable); + return FALSE; + } + bits += stride; + } + fbFinishAccess (&pStipple->drawable); + return TRUE; +} + +void +fbValidateGC(GCPtr pGC, unsigned long changes, DrawablePtr pDrawable) +{ + FbGCPrivPtr pPriv = fbGetGCPrivate(pGC); + FbBits mask; + + /* + * if the client clip is different or moved OR the subwindowMode has + * changed OR the window's clip has changed since the last validation + * we need to recompute the composite clip + */ + + if ((changes & (GCClipXOrigin|GCClipYOrigin|GCClipMask|GCSubwindowMode)) || + (pDrawable->serialNumber != (pGC->serialNumber & DRAWABLE_SERIAL_BITS)) + ) + { + miComputeCompositeClip (pGC, pDrawable); + } + + if (pPriv->bpp != pDrawable->bitsPerPixel) + { + changes |= GCStipple|GCForeground|GCBackground|GCPlaneMask; + pPriv->bpp = pDrawable->bitsPerPixel; + } + if ((changes & GCTile) && fbGetRotatedPixmap(pGC)) + { + (*pGC->pScreen->DestroyPixmap) (fbGetRotatedPixmap(pGC)); + fbGetRotatedPixmap(pGC) = 0; + } + + if (pGC->fillStyle == FillTiled) + { + PixmapPtr pOldTile, pNewTile; + + pOldTile = pGC->tile.pixmap; + if (pOldTile->drawable.bitsPerPixel != pDrawable->bitsPerPixel) + { + pNewTile = fbGetRotatedPixmap(pGC); + if (!pNewTile || pNewTile ->drawable.bitsPerPixel != pDrawable->bitsPerPixel) + { + if (pNewTile) + (*pGC->pScreen->DestroyPixmap) (pNewTile); + pNewTile = fb24_32ReformatTile (pOldTile, pDrawable->bitsPerPixel); + } + if (pNewTile) + { + fbGetRotatedPixmap(pGC) = pOldTile; + pGC->tile.pixmap = pNewTile; + changes |= GCTile; + } + } + } + if (changes & GCTile) + { + if (!pGC->tileIsPixel && + FbEvenTile (pGC->tile.pixmap->drawable.width * + pDrawable->bitsPerPixel)) + fbPadPixmap (pGC->tile.pixmap); + } + if (changes & GCStipple) + { + pPriv->evenStipple = FALSE; + + if (pGC->stipple) { + + /* can we do an even stipple ?? */ + if (FbEvenStip (pGC->stipple->drawable.width, + pDrawable->bitsPerPixel) && + (fbCanEvenStipple (pGC->stipple, pDrawable->bitsPerPixel))) + pPriv->evenStipple = TRUE; + + if (pGC->stipple->drawable.width * pDrawable->bitsPerPixel < FB_UNIT) + fbPadPixmap (pGC->stipple); + } + } + /* + * Recompute reduced rop values + */ + if (changes & (GCForeground|GCBackground|GCPlaneMask|GCFunction)) + { + int s; + FbBits depthMask; + + mask = FbFullMask(pDrawable->bitsPerPixel); + depthMask = FbFullMask(pDrawable->depth); + + pPriv->fg = pGC->fgPixel & mask; + pPriv->bg = pGC->bgPixel & mask; + + if ((pGC->planemask & depthMask) == depthMask) + pPriv->pm = mask; + else + pPriv->pm = pGC->planemask & mask; + + s = pDrawable->bitsPerPixel; + while (s < FB_UNIT) + { + pPriv->fg |= pPriv->fg << s; + pPriv->bg |= pPriv->bg << s; + pPriv->pm |= pPriv->pm << s; + s <<= 1; + } + pPriv->and = fbAnd(pGC->alu, pPriv->fg, pPriv->pm); + pPriv->xor = fbXor(pGC->alu, pPriv->fg, pPriv->pm); + pPriv->bgand = fbAnd(pGC->alu, pPriv->bg, pPriv->pm); + pPriv->bgxor = fbXor(pGC->alu, pPriv->bg, pPriv->pm); + } + if (changes & GCDashList) + { + unsigned short n = pGC->numInDashList; + unsigned char *dash = pGC->dash; + unsigned int dashLength = 0; + + while (n--) + dashLength += (unsigned int ) *dash++; + pPriv->dashLength = dashLength; + } +} |