279 lines
		
	
	
		
			8.6 KiB
		
	
	
	
		
			C
		
	
	
	
			
		
		
	
	
			279 lines
		
	
	
		
			8.6 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.
 | |
|  */
 | |
| 
 | |
| #ifdef HAVE_DIX_CONFIG_H
 | |
| #include <dix-config.h>
 | |
| #endif
 | |
| 
 | |
| #include <string.h>
 | |
| 
 | |
| #include "fb.h"
 | |
| 
 | |
| void
 | |
| fbPutImage(DrawablePtr pDrawable,
 | |
|            GCPtr pGC,
 | |
|            int depth,
 | |
|            int x, int y, int w, int h, int leftPad, int format, char *pImage)
 | |
| {
 | |
|     FbGCPrivPtr pPriv = fbGetGCPrivate(pGC);
 | |
|     unsigned long i;
 | |
|     FbStride srcStride;
 | |
|     FbStip *src = (FbStip *) pImage;
 | |
| 
 | |
|     x += pDrawable->x;
 | |
|     y += pDrawable->y;
 | |
| 
 | |
|     switch (format) {
 | |
|     case XYBitmap:
 | |
|         srcStride = BitmapBytePad(w + leftPad) / sizeof(FbStip);
 | |
|         fbPutXYImage(pDrawable,
 | |
|                      fbGetCompositeClip(pGC),
 | |
|                      pPriv->fg,
 | |
|                      pPriv->bg,
 | |
|                      pPriv->pm,
 | |
|                      pGC->alu, TRUE, x, y, w, h, src, srcStride, leftPad);
 | |
|         break;
 | |
|     case XYPixmap:
 | |
|         srcStride = BitmapBytePad(w + leftPad) / sizeof(FbStip);
 | |
|         for (i = (unsigned long) 1 << (pDrawable->depth - 1); i; i >>= 1) {
 | |
|             if (i & pGC->planemask) {
 | |
|                 fbPutXYImage(pDrawable,
 | |
|                              fbGetCompositeClip(pGC),
 | |
|                              FB_ALLONES,
 | |
|                              0,
 | |
|                              fbReplicatePixel(i, pDrawable->bitsPerPixel),
 | |
|                              pGC->alu,
 | |
|                              TRUE, x, y, w, h, src, srcStride, leftPad);
 | |
|             }
 | |
|             src += srcStride * h;
 | |
|         }
 | |
|         break;
 | |
|     case ZPixmap:
 | |
|         if (pDrawable->bitsPerPixel != BitsPerPixel(pDrawable->depth)) {
 | |
|             srcStride = PixmapBytePad(w, pDrawable->depth);
 | |
|             fb24_32PutZImage(pDrawable,
 | |
|                              fbGetCompositeClip(pGC),
 | |
|                              pGC->alu,
 | |
|                              (FbBits) pGC->planemask,
 | |
|                              x, y, w, h, (CARD8 *) pImage, srcStride);
 | |
|         }
 | |
|         else {
 | |
|             srcStride = PixmapBytePad(w, pDrawable->depth) / sizeof(FbStip);
 | |
|             fbPutZImage(pDrawable,
 | |
|                         fbGetCompositeClip(pGC),
 | |
|                         pGC->alu, pPriv->pm, x, y, w, h, src, srcStride);
 | |
|         }
 | |
|     }
 | |
| }
 | |
| 
 | |
| void
 | |
| fbPutZImage(DrawablePtr pDrawable,
 | |
|             RegionPtr pClip,
 | |
|             int alu,
 | |
|             FbBits pm,
 | |
|             int x,
 | |
|             int y, int width, int height, FbStip * src, FbStride srcStride)
 | |
| {
 | |
|     FbStip *dst;
 | |
|     FbStride dstStride;
 | |
|     int dstBpp;
 | |
|     int dstXoff, dstYoff;
 | |
|     int nbox;
 | |
|     BoxPtr pbox;
 | |
|     int x1, y1, x2, y2;
 | |
| 
 | |
|     fbGetStipDrawable(pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff);
 | |
| 
 | |
|     for (nbox = RegionNumRects(pClip),
 | |
|          pbox = RegionRects(pClip); nbox--; pbox++) {
 | |
|         x1 = x;
 | |
|         y1 = y;
 | |
|         x2 = x + width;
 | |
|         y2 = y + height;
 | |
|         if (x1 < pbox->x1)
 | |
|             x1 = pbox->x1;
 | |
|         if (y1 < pbox->y1)
 | |
|             y1 = pbox->y1;
 | |
|         if (x2 > pbox->x2)
 | |
|             x2 = pbox->x2;
 | |
|         if (y2 > pbox->y2)
 | |
|             y2 = pbox->y2;
 | |
|         if (x1 >= x2 || y1 >= y2)
 | |
|             continue;
 | |
|         fbBltStip(src + (y1 - y) * srcStride,
 | |
|                   srcStride,
 | |
|                   (x1 - x) * dstBpp,
 | |
|                   dst + (y1 + dstYoff) * dstStride,
 | |
|                   dstStride,
 | |
|                   (x1 + dstXoff) * dstBpp,
 | |
|                   (x2 - x1) * dstBpp, (y2 - y1), alu, pm, dstBpp);
 | |
|     }
 | |
| 
 | |
|     fbFinishAccess(pDrawable);
 | |
| }
 | |
| 
 | |
| void
 | |
| fbPutXYImage(DrawablePtr pDrawable,
 | |
|              RegionPtr pClip,
 | |
|              FbBits fg,
 | |
|              FbBits bg,
 | |
|              FbBits pm,
 | |
|              int alu,
 | |
|              Bool opaque,
 | |
|              int x,
 | |
|              int y,
 | |
|              int width, int height, FbStip * src, FbStride srcStride, int srcX)
 | |
| {
 | |
|     FbBits *dst;
 | |
|     FbStride dstStride;
 | |
|     int dstBpp;
 | |
|     int dstXoff, dstYoff;
 | |
|     int nbox;
 | |
|     BoxPtr pbox;
 | |
|     int x1, y1, x2, y2;
 | |
|     FbBits fgand = 0, fgxor = 0, bgand = 0, bgxor = 0;
 | |
| 
 | |
|     fbGetDrawable(pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff);
 | |
| 
 | |
|     if (dstBpp == 1) {
 | |
|         if (opaque)
 | |
|             alu = FbOpaqueStipple1Rop(alu, fg, bg);
 | |
|         else
 | |
|             alu = FbStipple1Rop(alu, fg);
 | |
|     }
 | |
|     else {
 | |
|         fgand = fbAnd(alu, fg, pm);
 | |
|         fgxor = fbXor(alu, fg, pm);
 | |
|         if (opaque) {
 | |
|             bgand = fbAnd(alu, bg, pm);
 | |
|             bgxor = fbXor(alu, bg, pm);
 | |
|         }
 | |
|         else {
 | |
|             bgand = fbAnd(GXnoop, (FbBits) 0, FB_ALLONES);
 | |
|             bgxor = fbXor(GXnoop, (FbBits) 0, FB_ALLONES);
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     for (nbox = RegionNumRects(pClip),
 | |
|          pbox = RegionRects(pClip); nbox--; pbox++) {
 | |
|         x1 = x;
 | |
|         y1 = y;
 | |
|         x2 = x + width;
 | |
|         y2 = y + height;
 | |
|         if (x1 < pbox->x1)
 | |
|             x1 = pbox->x1;
 | |
|         if (y1 < pbox->y1)
 | |
|             y1 = pbox->y1;
 | |
|         if (x2 > pbox->x2)
 | |
|             x2 = pbox->x2;
 | |
|         if (y2 > pbox->y2)
 | |
|             y2 = pbox->y2;
 | |
|         if (x1 >= x2 || y1 >= y2)
 | |
|             continue;
 | |
|         if (dstBpp == 1) {
 | |
|             fbBltStip(src + (y1 - y) * srcStride,
 | |
|                       srcStride,
 | |
|                       (x1 - x) + srcX,
 | |
|                       (FbStip *) (dst + (y1 + dstYoff) * dstStride),
 | |
|                       FbBitsStrideToStipStride(dstStride),
 | |
|                       (x1 + dstXoff) * dstBpp,
 | |
|                       (x2 - x1) * dstBpp, (y2 - y1), alu, pm, dstBpp);
 | |
|         }
 | |
|         else {
 | |
|             fbBltOne(src + (y1 - y) * srcStride,
 | |
|                      srcStride,
 | |
|                      (x1 - x) + srcX,
 | |
|                      dst + (y1 + dstYoff) * dstStride,
 | |
|                      dstStride,
 | |
|                      (x1 + dstXoff) * dstBpp,
 | |
|                      dstBpp,
 | |
|                      (x2 - x1) * dstBpp, (y2 - y1), fgand, fgxor, bgand, bgxor);
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     fbFinishAccess(pDrawable);
 | |
| }
 | |
| 
 | |
| void
 | |
| fbGetImage(DrawablePtr pDrawable,
 | |
|            int x,
 | |
|            int y,
 | |
|            int w, int h, unsigned int format, unsigned long planeMask, char *d)
 | |
| {
 | |
|     FbBits *src;
 | |
|     FbStride srcStride;
 | |
|     int srcBpp;
 | |
|     int srcXoff, srcYoff;
 | |
|     FbStip *dst;
 | |
|     FbStride dstStride;
 | |
| 
 | |
|     /*
 | |
|      * XFree86 DDX empties the root borderClip when the VT is
 | |
|      * switched away; this checks for that case
 | |
|      */
 | |
|     if (!fbDrawableEnabled(pDrawable))
 | |
|         return;
 | |
| 
 | |
|     if (format == ZPixmap &&
 | |
|         pDrawable->bitsPerPixel != BitsPerPixel(pDrawable->depth)) {
 | |
|         fb24_32GetImage(pDrawable, x, y, w, h, format, planeMask, d);
 | |
|         return;
 | |
|     }
 | |
| 
 | |
|     fbGetDrawable(pDrawable, src, srcStride, srcBpp, srcXoff, srcYoff);
 | |
| 
 | |
|     x += pDrawable->x;
 | |
|     y += pDrawable->y;
 | |
| 
 | |
|     dst = (FbStip *) d;
 | |
|     if (format == ZPixmap || srcBpp == 1) {
 | |
|         FbBits pm;
 | |
| 
 | |
|         pm = fbReplicatePixel(planeMask, srcBpp);
 | |
|         dstStride = PixmapBytePad(w, pDrawable->depth);
 | |
|         if (pm != FB_ALLONES)
 | |
|             memset(d, 0, dstStride * h);
 | |
|         dstStride /= sizeof(FbStip);
 | |
|         fbBltStip((FbStip *) (src + (y + srcYoff) * srcStride),
 | |
|                   FbBitsStrideToStipStride(srcStride),
 | |
|                   (x + srcXoff) * srcBpp,
 | |
|                   dst, dstStride, 0, w * srcBpp, h, GXcopy, pm, srcBpp);
 | |
|     }
 | |
|     else {
 | |
|         dstStride = BitmapBytePad(w) / sizeof(FbStip);
 | |
|         fbBltPlane(src + (y + srcYoff) * srcStride,
 | |
|                    srcStride,
 | |
|                    (x + srcXoff) * srcBpp,
 | |
|                    srcBpp,
 | |
|                    dst,
 | |
|                    dstStride,
 | |
|                    0,
 | |
|                    w * srcBpp, h,
 | |
|                    fbAndStip(GXcopy, FB_STIP_ALLONES, FB_STIP_ALLONES),
 | |
|                    fbXorStip(GXcopy, FB_STIP_ALLONES, FB_STIP_ALLONES),
 | |
|                    fbAndStip(GXcopy, 0, FB_STIP_ALLONES),
 | |
|                    fbXorStip(GXcopy, 0, FB_STIP_ALLONES), planeMask);
 | |
|     }
 | |
| 
 | |
|     fbFinishAccess(pDrawable);
 | |
| }
 |