182 lines
		
	
	
		
			4.9 KiB
		
	
	
	
		
			C
		
	
	
	
			
		
		
	
	
			182 lines
		
	
	
		
			4.9 KiB
		
	
	
	
		
			C
		
	
	
	
| /*
 | |
|  * 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.
 | |
|  */
 | |
| 
 | |
| #include <dix-config.h>
 | |
| 
 | |
| #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;
 | |
| 
 | |
|     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);
 | |
| }
 | |
| 
 | |
| 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 (changes & GCTile) {
 | |
|         if (!pGC->tileIsPixel &&
 | |
|             FbEvenTile(pGC->tile.pixmap->drawable.width *
 | |
|                        pDrawable->bitsPerPixel))
 | |
|             fbPadPixmap(pGC->tile.pixmap);
 | |
|     }
 | |
|     if (changes & GCStipple) {
 | |
|         if (pGC->stipple) {
 | |
|             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;
 | |
|     }
 | |
| }
 |