fbgc.c revision 35c4bbdf
105b261ecSmrg/* 205b261ecSmrg * Copyright © 1998 Keith Packard 305b261ecSmrg * 405b261ecSmrg * Permission to use, copy, modify, distribute, and sell this software and its 505b261ecSmrg * documentation for any purpose is hereby granted without fee, provided that 605b261ecSmrg * the above copyright notice appear in all copies and that both that 705b261ecSmrg * copyright notice and this permission notice appear in supporting 805b261ecSmrg * documentation, and that the name of Keith Packard not be used in 905b261ecSmrg * advertising or publicity pertaining to distribution of the software without 1005b261ecSmrg * specific, written prior permission. Keith Packard makes no 1105b261ecSmrg * representations about the suitability of this software for any purpose. It 1205b261ecSmrg * is provided "as is" without express or implied warranty. 1305b261ecSmrg * 1405b261ecSmrg * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 1505b261ecSmrg * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 1605b261ecSmrg * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR 1705b261ecSmrg * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 1805b261ecSmrg * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 1905b261ecSmrg * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 2005b261ecSmrg * PERFORMANCE OF THIS SOFTWARE. 2105b261ecSmrg */ 2205b261ecSmrg 2305b261ecSmrg#ifdef HAVE_DIX_CONFIG_H 2405b261ecSmrg#include <dix-config.h> 2505b261ecSmrg#endif 2605b261ecSmrg 2705b261ecSmrg#include <stdlib.h> 2805b261ecSmrg 2905b261ecSmrg#include "fb.h" 3005b261ecSmrg 3105b261ecSmrgconst GCFuncs fbGCFuncs = { 3205b261ecSmrg fbValidateGC, 3305b261ecSmrg miChangeGC, 3405b261ecSmrg miCopyGC, 3505b261ecSmrg miDestroyGC, 3605b261ecSmrg miChangeClip, 3705b261ecSmrg miDestroyClip, 3805b261ecSmrg miCopyClip, 3905b261ecSmrg}; 4005b261ecSmrg 4135c4bbdfSmrgconst GCOps fbGCOps = { 4205b261ecSmrg fbFillSpans, 4305b261ecSmrg fbSetSpans, 4405b261ecSmrg fbPutImage, 4505b261ecSmrg fbCopyArea, 4605b261ecSmrg fbCopyPlane, 4705b261ecSmrg fbPolyPoint, 4805b261ecSmrg fbPolyLine, 4905b261ecSmrg fbPolySegment, 5005b261ecSmrg fbPolyRectangle, 5105b261ecSmrg fbPolyArc, 5205b261ecSmrg miFillPolygon, 5305b261ecSmrg fbPolyFillRect, 5405b261ecSmrg fbPolyFillArc, 5505b261ecSmrg miPolyText8, 5605b261ecSmrg miPolyText16, 5705b261ecSmrg miImageText8, 5805b261ecSmrg miImageText16, 5905b261ecSmrg fbImageGlyphBlt, 6005b261ecSmrg fbPolyGlyphBlt, 6105b261ecSmrg fbPushPixels 6205b261ecSmrg}; 6305b261ecSmrg 6405b261ecSmrgBool 6505b261ecSmrgfbCreateGC(GCPtr pGC) 6605b261ecSmrg{ 6705b261ecSmrg pGC->ops = (GCOps *) &fbGCOps; 6805b261ecSmrg pGC->funcs = (GCFuncs *) &fbGCFuncs; 6905b261ecSmrg 7005b261ecSmrg /* fb wants to translate before scan conversion */ 7105b261ecSmrg pGC->miTranslate = 1; 729ace9065Smrg pGC->fExpose = 1; 7305b261ecSmrg 7435c4bbdfSmrg fbGetGCPrivate(pGC)->bpp = BitsPerPixel(pGC->depth); 7505b261ecSmrg return TRUE; 7605b261ecSmrg} 7705b261ecSmrg 7805b261ecSmrg/* 7905b261ecSmrg * Pad pixmap to FB_UNIT bits wide 8005b261ecSmrg */ 8105b261ecSmrgvoid 8235c4bbdfSmrgfbPadPixmap(PixmapPtr pPixmap) 8305b261ecSmrg{ 8435c4bbdfSmrg int width; 8535c4bbdfSmrg FbBits *bits; 8635c4bbdfSmrg FbBits b; 8735c4bbdfSmrg FbBits mask; 8835c4bbdfSmrg int height; 8935c4bbdfSmrg int w; 9035c4bbdfSmrg int stride; 9135c4bbdfSmrg int bpp; 9235c4bbdfSmrg _X_UNUSED int xOff, yOff; 9335c4bbdfSmrg 9435c4bbdfSmrg fbGetDrawable(&pPixmap->drawable, bits, stride, bpp, xOff, yOff); 9505b261ecSmrg 9605b261ecSmrg width = pPixmap->drawable.width * pPixmap->drawable.bitsPerPixel; 9705b261ecSmrg height = pPixmap->drawable.height; 9835c4bbdfSmrg mask = FbBitsMask(0, width); 9935c4bbdfSmrg while (height--) { 10035c4bbdfSmrg b = READ(bits) & mask; 10135c4bbdfSmrg w = width; 10235c4bbdfSmrg while (w < FB_UNIT) { 10335c4bbdfSmrg b = b | FbScrRight(b, w); 10435c4bbdfSmrg w <<= 1; 10535c4bbdfSmrg } 10635c4bbdfSmrg WRITE(bits, b); 10735c4bbdfSmrg bits += stride; 10805b261ecSmrg } 10905b261ecSmrg 11035c4bbdfSmrg fbFinishAccess(&pPixmap->drawable); 11105b261ecSmrg} 11205b261ecSmrg 11305b261ecSmrgvoid 11405b261ecSmrgfbValidateGC(GCPtr pGC, unsigned long changes, DrawablePtr pDrawable) 11505b261ecSmrg{ 11635c4bbdfSmrg FbGCPrivPtr pPriv = fbGetGCPrivate(pGC); 11735c4bbdfSmrg FbBits mask; 11805b261ecSmrg 11905b261ecSmrg /* 12005b261ecSmrg * if the client clip is different or moved OR the subwindowMode has 12105b261ecSmrg * changed OR the window's clip has changed since the last validation 12235c4bbdfSmrg * we need to recompute the composite clip 12305b261ecSmrg */ 12405b261ecSmrg 12535c4bbdfSmrg if ((changes & 12635c4bbdfSmrg (GCClipXOrigin | GCClipYOrigin | GCClipMask | GCSubwindowMode)) || 12735c4bbdfSmrg (pDrawable->serialNumber != (pGC->serialNumber & DRAWABLE_SERIAL_BITS)) 12835c4bbdfSmrg ) { 12935c4bbdfSmrg miComputeCompositeClip(pGC, pDrawable); 13005b261ecSmrg } 13135c4bbdfSmrg 13235c4bbdfSmrg if (pPriv->bpp != pDrawable->bitsPerPixel) { 13335c4bbdfSmrg changes |= GCStipple | GCForeground | GCBackground | GCPlaneMask; 13435c4bbdfSmrg pPriv->bpp = pDrawable->bitsPerPixel; 13505b261ecSmrg } 13635c4bbdfSmrg if ((changes & GCTile) && fbGetRotatedPixmap(pGC)) { 13735c4bbdfSmrg (*pGC->pScreen->DestroyPixmap) (fbGetRotatedPixmap(pGC)); 13835c4bbdfSmrg fbGetRotatedPixmap(pGC) = 0; 13905b261ecSmrg } 14005b261ecSmrg 14135c4bbdfSmrg if (pGC->fillStyle == FillTiled) { 14235c4bbdfSmrg PixmapPtr pOldTile, pNewTile; 14335c4bbdfSmrg 14435c4bbdfSmrg pOldTile = pGC->tile.pixmap; 14535c4bbdfSmrg if (pOldTile->drawable.bitsPerPixel != pDrawable->bitsPerPixel) { 14635c4bbdfSmrg pNewTile = fbGetRotatedPixmap(pGC); 14735c4bbdfSmrg if (!pNewTile || 14835c4bbdfSmrg pNewTile->drawable.bitsPerPixel != pDrawable->bitsPerPixel) { 14935c4bbdfSmrg if (pNewTile) 15035c4bbdfSmrg (*pGC->pScreen->DestroyPixmap) (pNewTile); 15135c4bbdfSmrg pNewTile = 15235c4bbdfSmrg fb24_32ReformatTile(pOldTile, pDrawable->bitsPerPixel); 15335c4bbdfSmrg } 15435c4bbdfSmrg if (pNewTile) { 15535c4bbdfSmrg fbGetRotatedPixmap(pGC) = pOldTile; 15635c4bbdfSmrg pGC->tile.pixmap = pNewTile; 15735c4bbdfSmrg changes |= GCTile; 15835c4bbdfSmrg } 15935c4bbdfSmrg } 16005b261ecSmrg } 16135c4bbdfSmrg if (changes & GCTile) { 16235c4bbdfSmrg if (!pGC->tileIsPixel && 16335c4bbdfSmrg FbEvenTile(pGC->tile.pixmap->drawable.width * 16435c4bbdfSmrg pDrawable->bitsPerPixel)) 16535c4bbdfSmrg fbPadPixmap(pGC->tile.pixmap); 16605b261ecSmrg } 16735c4bbdfSmrg if (changes & GCStipple) { 16835c4bbdfSmrg if (pGC->stipple) { 16935c4bbdfSmrg if (pGC->stipple->drawable.width * pDrawable->bitsPerPixel < 17035c4bbdfSmrg FB_UNIT) 17135c4bbdfSmrg fbPadPixmap(pGC->stipple); 17235c4bbdfSmrg } 17305b261ecSmrg } 17405b261ecSmrg /* 17505b261ecSmrg * Recompute reduced rop values 17605b261ecSmrg */ 17735c4bbdfSmrg if (changes & (GCForeground | GCBackground | GCPlaneMask | GCFunction)) { 17835c4bbdfSmrg int s; 17935c4bbdfSmrg FbBits depthMask; 18035c4bbdfSmrg 18135c4bbdfSmrg mask = FbFullMask(pDrawable->bitsPerPixel); 18235c4bbdfSmrg depthMask = FbFullMask(pDrawable->depth); 18335c4bbdfSmrg 18435c4bbdfSmrg pPriv->fg = pGC->fgPixel & mask; 18535c4bbdfSmrg pPriv->bg = pGC->bgPixel & mask; 18635c4bbdfSmrg 18735c4bbdfSmrg if ((pGC->planemask & depthMask) == depthMask) 18835c4bbdfSmrg pPriv->pm = mask; 18935c4bbdfSmrg else 19035c4bbdfSmrg pPriv->pm = pGC->planemask & mask; 19135c4bbdfSmrg 19235c4bbdfSmrg s = pDrawable->bitsPerPixel; 19335c4bbdfSmrg while (s < FB_UNIT) { 19435c4bbdfSmrg pPriv->fg |= pPriv->fg << s; 19535c4bbdfSmrg pPriv->bg |= pPriv->bg << s; 19635c4bbdfSmrg pPriv->pm |= pPriv->pm << s; 19735c4bbdfSmrg s <<= 1; 19835c4bbdfSmrg } 19935c4bbdfSmrg pPriv->and = fbAnd(pGC->alu, pPriv->fg, pPriv->pm); 20035c4bbdfSmrg pPriv->xor = fbXor(pGC->alu, pPriv->fg, pPriv->pm); 20135c4bbdfSmrg pPriv->bgand = fbAnd(pGC->alu, pPriv->bg, pPriv->pm); 20235c4bbdfSmrg pPriv->bgxor = fbXor(pGC->alu, pPriv->bg, pPriv->pm); 20305b261ecSmrg } 20435c4bbdfSmrg if (changes & GCDashList) { 20535c4bbdfSmrg unsigned short n = pGC->numInDashList; 20635c4bbdfSmrg unsigned char *dash = pGC->dash; 20735c4bbdfSmrg unsigned int dashLength = 0; 20835c4bbdfSmrg 20935c4bbdfSmrg while (n--) 21035c4bbdfSmrg dashLength += (unsigned int) *dash++; 21135c4bbdfSmrg pPriv->dashLength = dashLength; 21205b261ecSmrg } 21305b261ecSmrg} 214