1/* 2 * Copyright © 1998 Keith Packard 3 * 4 * Permission to use, copy, modify, distribute, and sell this software and its 5 * documentation for any purpose is hereby granted without fee, provided that 6 * the above copyright notice appear in all copies and that both that 7 * copyright notice and this permission notice appear in supporting 8 * documentation, and that the name of Keith Packard not be used in 9 * advertising or publicity pertaining to distribution of the software without 10 * specific, written prior permission. Keith Packard makes no 11 * representations about the suitability of this software for any purpose. It 12 * is provided "as is" without express or implied warranty. 13 * 14 * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 15 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 16 * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR 17 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 18 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 19 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 20 * PERFORMANCE OF THIS SOFTWARE. 21 */ 22 23#ifdef HAVE_DIX_CONFIG_H 24#include <dix-config.h> 25#endif 26 27#include <stdlib.h> 28 29#include "fb.h" 30 31const GCFuncs fbGCFuncs = { 32 fbValidateGC, 33 miChangeGC, 34 miCopyGC, 35 miDestroyGC, 36 miChangeClip, 37 miDestroyClip, 38 miCopyClip, 39}; 40 41const GCOps fbGCOps = { 42 fbFillSpans, 43 fbSetSpans, 44 fbPutImage, 45 fbCopyArea, 46 fbCopyPlane, 47 fbPolyPoint, 48 fbPolyLine, 49 fbPolySegment, 50 fbPolyRectangle, 51 fbPolyArc, 52 miFillPolygon, 53 fbPolyFillRect, 54 fbPolyFillArc, 55 miPolyText8, 56 miPolyText16, 57 miImageText8, 58 miImageText16, 59 fbImageGlyphBlt, 60 fbPolyGlyphBlt, 61 fbPushPixels 62}; 63 64Bool 65fbCreateGC(GCPtr pGC) 66{ 67 pGC->ops = (GCOps *) &fbGCOps; 68 pGC->funcs = (GCFuncs *) &fbGCFuncs; 69 70 /* fb wants to translate before scan conversion */ 71 pGC->miTranslate = 1; 72 pGC->fExpose = 1; 73 74 return TRUE; 75} 76 77/* 78 * Pad pixmap to FB_UNIT bits wide 79 */ 80void 81fbPadPixmap(PixmapPtr pPixmap) 82{ 83 int width; 84 FbBits *bits; 85 FbBits b; 86 FbBits mask; 87 int height; 88 int w; 89 int stride; 90 int bpp; 91 _X_UNUSED int xOff, yOff; 92 93 fbGetDrawable(&pPixmap->drawable, bits, stride, bpp, xOff, yOff); 94 95 width = pPixmap->drawable.width * pPixmap->drawable.bitsPerPixel; 96 height = pPixmap->drawable.height; 97 mask = FbBitsMask(0, width); 98 while (height--) { 99 b = READ(bits) & mask; 100 w = width; 101 while (w < FB_UNIT) { 102 b = b | FbScrRight(b, w); 103 w <<= 1; 104 } 105 WRITE(bits, b); 106 bits += stride; 107 } 108 109 fbFinishAccess(&pPixmap->drawable); 110} 111 112void 113fbValidateGC(GCPtr pGC, unsigned long changes, DrawablePtr pDrawable) 114{ 115 FbGCPrivPtr pPriv = fbGetGCPrivate(pGC); 116 FbBits mask; 117 118 /* 119 * if the client clip is different or moved OR the subwindowMode has 120 * changed OR the window's clip has changed since the last validation 121 * we need to recompute the composite clip 122 */ 123 124 if ((changes & 125 (GCClipXOrigin | GCClipYOrigin | GCClipMask | GCSubwindowMode)) || 126 (pDrawable->serialNumber != (pGC->serialNumber & DRAWABLE_SERIAL_BITS)) 127 ) { 128 miComputeCompositeClip(pGC, pDrawable); 129 } 130 131 if (changes & GCTile) { 132 if (!pGC->tileIsPixel && 133 FbEvenTile(pGC->tile.pixmap->drawable.width * 134 pDrawable->bitsPerPixel)) 135 fbPadPixmap(pGC->tile.pixmap); 136 } 137 if (changes & GCStipple) { 138 if (pGC->stipple) { 139 if (pGC->stipple->drawable.width * pDrawable->bitsPerPixel < 140 FB_UNIT) 141 fbPadPixmap(pGC->stipple); 142 } 143 } 144 /* 145 * Recompute reduced rop values 146 */ 147 if (changes & (GCForeground | GCBackground | GCPlaneMask | GCFunction)) { 148 int s; 149 FbBits depthMask; 150 151 mask = FbFullMask(pDrawable->bitsPerPixel); 152 depthMask = FbFullMask(pDrawable->depth); 153 154 pPriv->fg = pGC->fgPixel & mask; 155 pPriv->bg = pGC->bgPixel & mask; 156 157 if ((pGC->planemask & depthMask) == depthMask) 158 pPriv->pm = mask; 159 else 160 pPriv->pm = pGC->planemask & mask; 161 162 s = pDrawable->bitsPerPixel; 163 while (s < FB_UNIT) { 164 pPriv->fg |= pPriv->fg << s; 165 pPriv->bg |= pPriv->bg << s; 166 pPriv->pm |= pPriv->pm << s; 167 s <<= 1; 168 } 169 pPriv->and = fbAnd(pGC->alu, pPriv->fg, pPriv->pm); 170 pPriv->xor = fbXor(pGC->alu, pPriv->fg, pPriv->pm); 171 pPriv->bgand = fbAnd(pGC->alu, pPriv->bg, pPriv->pm); 172 pPriv->bgxor = fbXor(pGC->alu, pPriv->bg, pPriv->pm); 173 } 174 if (changes & GCDashList) { 175 unsigned short n = pGC->numInDashList; 176 unsigned char *dash = pGC->dash; 177 unsigned int dashLength = 0; 178 179 while (n--) 180 dashLength += (unsigned int) *dash++; 181 pPriv->dashLength = dashLength; 182 } 183} 184