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 7405b261ecSmrg return TRUE; 7505b261ecSmrg} 7605b261ecSmrg 7705b261ecSmrg/* 7805b261ecSmrg * Pad pixmap to FB_UNIT bits wide 7905b261ecSmrg */ 8005b261ecSmrgvoid 8135c4bbdfSmrgfbPadPixmap(PixmapPtr pPixmap) 8205b261ecSmrg{ 8335c4bbdfSmrg int width; 8435c4bbdfSmrg FbBits *bits; 8535c4bbdfSmrg FbBits b; 8635c4bbdfSmrg FbBits mask; 8735c4bbdfSmrg int height; 8835c4bbdfSmrg int w; 8935c4bbdfSmrg int stride; 9035c4bbdfSmrg int bpp; 9135c4bbdfSmrg _X_UNUSED int xOff, yOff; 9235c4bbdfSmrg 9335c4bbdfSmrg fbGetDrawable(&pPixmap->drawable, bits, stride, bpp, xOff, yOff); 9405b261ecSmrg 9505b261ecSmrg width = pPixmap->drawable.width * pPixmap->drawable.bitsPerPixel; 9605b261ecSmrg height = pPixmap->drawable.height; 9735c4bbdfSmrg mask = FbBitsMask(0, width); 9835c4bbdfSmrg while (height--) { 9935c4bbdfSmrg b = READ(bits) & mask; 10035c4bbdfSmrg w = width; 10135c4bbdfSmrg while (w < FB_UNIT) { 10235c4bbdfSmrg b = b | FbScrRight(b, w); 10335c4bbdfSmrg w <<= 1; 10435c4bbdfSmrg } 10535c4bbdfSmrg WRITE(bits, b); 10635c4bbdfSmrg bits += stride; 10705b261ecSmrg } 10805b261ecSmrg 10935c4bbdfSmrg fbFinishAccess(&pPixmap->drawable); 11005b261ecSmrg} 11105b261ecSmrg 11205b261ecSmrgvoid 11305b261ecSmrgfbValidateGC(GCPtr pGC, unsigned long changes, DrawablePtr pDrawable) 11405b261ecSmrg{ 11535c4bbdfSmrg FbGCPrivPtr pPriv = fbGetGCPrivate(pGC); 11635c4bbdfSmrg FbBits mask; 11705b261ecSmrg 11805b261ecSmrg /* 11905b261ecSmrg * if the client clip is different or moved OR the subwindowMode has 12005b261ecSmrg * changed OR the window's clip has changed since the last validation 12135c4bbdfSmrg * we need to recompute the composite clip 12205b261ecSmrg */ 12305b261ecSmrg 12435c4bbdfSmrg if ((changes & 12535c4bbdfSmrg (GCClipXOrigin | GCClipYOrigin | GCClipMask | GCSubwindowMode)) || 12635c4bbdfSmrg (pDrawable->serialNumber != (pGC->serialNumber & DRAWABLE_SERIAL_BITS)) 12735c4bbdfSmrg ) { 12835c4bbdfSmrg miComputeCompositeClip(pGC, pDrawable); 12905b261ecSmrg } 13035c4bbdfSmrg 13135c4bbdfSmrg if (changes & GCTile) { 13235c4bbdfSmrg if (!pGC->tileIsPixel && 13335c4bbdfSmrg FbEvenTile(pGC->tile.pixmap->drawable.width * 13435c4bbdfSmrg pDrawable->bitsPerPixel)) 13535c4bbdfSmrg fbPadPixmap(pGC->tile.pixmap); 13605b261ecSmrg } 13735c4bbdfSmrg if (changes & GCStipple) { 13835c4bbdfSmrg if (pGC->stipple) { 13935c4bbdfSmrg if (pGC->stipple->drawable.width * pDrawable->bitsPerPixel < 14035c4bbdfSmrg FB_UNIT) 14135c4bbdfSmrg fbPadPixmap(pGC->stipple); 14235c4bbdfSmrg } 14305b261ecSmrg } 14405b261ecSmrg /* 14505b261ecSmrg * Recompute reduced rop values 14605b261ecSmrg */ 14735c4bbdfSmrg if (changes & (GCForeground | GCBackground | GCPlaneMask | GCFunction)) { 14835c4bbdfSmrg int s; 14935c4bbdfSmrg FbBits depthMask; 15035c4bbdfSmrg 15135c4bbdfSmrg mask = FbFullMask(pDrawable->bitsPerPixel); 15235c4bbdfSmrg depthMask = FbFullMask(pDrawable->depth); 15335c4bbdfSmrg 15435c4bbdfSmrg pPriv->fg = pGC->fgPixel & mask; 15535c4bbdfSmrg pPriv->bg = pGC->bgPixel & mask; 15635c4bbdfSmrg 15735c4bbdfSmrg if ((pGC->planemask & depthMask) == depthMask) 15835c4bbdfSmrg pPriv->pm = mask; 15935c4bbdfSmrg else 16035c4bbdfSmrg pPriv->pm = pGC->planemask & mask; 16135c4bbdfSmrg 16235c4bbdfSmrg s = pDrawable->bitsPerPixel; 16335c4bbdfSmrg while (s < FB_UNIT) { 16435c4bbdfSmrg pPriv->fg |= pPriv->fg << s; 16535c4bbdfSmrg pPriv->bg |= pPriv->bg << s; 16635c4bbdfSmrg pPriv->pm |= pPriv->pm << s; 16735c4bbdfSmrg s <<= 1; 16835c4bbdfSmrg } 16935c4bbdfSmrg pPriv->and = fbAnd(pGC->alu, pPriv->fg, pPriv->pm); 17035c4bbdfSmrg pPriv->xor = fbXor(pGC->alu, pPriv->fg, pPriv->pm); 17135c4bbdfSmrg pPriv->bgand = fbAnd(pGC->alu, pPriv->bg, pPriv->pm); 17235c4bbdfSmrg pPriv->bgxor = fbXor(pGC->alu, pPriv->bg, pPriv->pm); 17305b261ecSmrg } 17435c4bbdfSmrg if (changes & GCDashList) { 17535c4bbdfSmrg unsigned short n = pGC->numInDashList; 17635c4bbdfSmrg unsigned char *dash = pGC->dash; 17735c4bbdfSmrg unsigned int dashLength = 0; 17835c4bbdfSmrg 17935c4bbdfSmrg while (n--) 18035c4bbdfSmrg dashLength += (unsigned int) *dash++; 18135c4bbdfSmrg pPriv->dashLength = dashLength; 18205b261ecSmrg } 18305b261ecSmrg} 184