fbimage.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 <string.h> 2805b261ecSmrg 2905b261ecSmrg#include "fb.h" 3005b261ecSmrg 3105b261ecSmrgvoid 3235c4bbdfSmrgfbPutImage(DrawablePtr pDrawable, 3335c4bbdfSmrg GCPtr pGC, 3435c4bbdfSmrg int depth, 3535c4bbdfSmrg int x, int y, int w, int h, int leftPad, int format, char *pImage) 3605b261ecSmrg{ 3735c4bbdfSmrg FbGCPrivPtr pPriv = fbGetGCPrivate(pGC); 3835c4bbdfSmrg unsigned long i; 3935c4bbdfSmrg FbStride srcStride; 4035c4bbdfSmrg FbStip *src = (FbStip *) pImage; 4135c4bbdfSmrg 4205b261ecSmrg x += pDrawable->x; 4305b261ecSmrg y += pDrawable->y; 4435c4bbdfSmrg 4535c4bbdfSmrg switch (format) { 4605b261ecSmrg case XYBitmap: 4735c4bbdfSmrg srcStride = BitmapBytePad(w + leftPad) / sizeof(FbStip); 4835c4bbdfSmrg fbPutXYImage(pDrawable, 4935c4bbdfSmrg fbGetCompositeClip(pGC), 5035c4bbdfSmrg pPriv->fg, 5135c4bbdfSmrg pPriv->bg, 5235c4bbdfSmrg pPriv->pm, 5335c4bbdfSmrg pGC->alu, TRUE, x, y, w, h, src, srcStride, leftPad); 5435c4bbdfSmrg break; 5505b261ecSmrg case XYPixmap: 5635c4bbdfSmrg srcStride = BitmapBytePad(w + leftPad) / sizeof(FbStip); 5735c4bbdfSmrg for (i = (unsigned long) 1 << (pDrawable->depth - 1); i; i >>= 1) { 5835c4bbdfSmrg if (i & pGC->planemask) { 5935c4bbdfSmrg fbPutXYImage(pDrawable, 6035c4bbdfSmrg fbGetCompositeClip(pGC), 6135c4bbdfSmrg FB_ALLONES, 6235c4bbdfSmrg 0, 6335c4bbdfSmrg fbReplicatePixel(i, pDrawable->bitsPerPixel), 6435c4bbdfSmrg pGC->alu, 6535c4bbdfSmrg TRUE, x, y, w, h, src, srcStride, leftPad); 6635c4bbdfSmrg src += srcStride * h; 6735c4bbdfSmrg } 6835c4bbdfSmrg } 6935c4bbdfSmrg break; 7005b261ecSmrg case ZPixmap: 7135c4bbdfSmrg if (pDrawable->bitsPerPixel != BitsPerPixel(pDrawable->depth)) { 7235c4bbdfSmrg srcStride = PixmapBytePad(w, pDrawable->depth); 7335c4bbdfSmrg fb24_32PutZImage(pDrawable, 7435c4bbdfSmrg fbGetCompositeClip(pGC), 7535c4bbdfSmrg pGC->alu, 7635c4bbdfSmrg (FbBits) pGC->planemask, 7735c4bbdfSmrg x, y, w, h, (CARD8 *) pImage, srcStride); 7835c4bbdfSmrg } 7935c4bbdfSmrg else { 8035c4bbdfSmrg srcStride = PixmapBytePad(w, pDrawable->depth) / sizeof(FbStip); 8135c4bbdfSmrg fbPutZImage(pDrawable, 8235c4bbdfSmrg fbGetCompositeClip(pGC), 8335c4bbdfSmrg pGC->alu, pPriv->pm, x, y, w, h, src, srcStride); 8435c4bbdfSmrg } 8505b261ecSmrg } 8605b261ecSmrg} 8705b261ecSmrg 8805b261ecSmrgvoid 8935c4bbdfSmrgfbPutZImage(DrawablePtr pDrawable, 9035c4bbdfSmrg RegionPtr pClip, 9135c4bbdfSmrg int alu, 9235c4bbdfSmrg FbBits pm, 9335c4bbdfSmrg int x, 9435c4bbdfSmrg int y, int width, int height, FbStip * src, FbStride srcStride) 9505b261ecSmrg{ 9635c4bbdfSmrg FbStip *dst; 9735c4bbdfSmrg FbStride dstStride; 9835c4bbdfSmrg int dstBpp; 9935c4bbdfSmrg int dstXoff, dstYoff; 10035c4bbdfSmrg int nbox; 10135c4bbdfSmrg BoxPtr pbox; 10235c4bbdfSmrg int x1, y1, x2, y2; 10305b261ecSmrg 10435c4bbdfSmrg fbGetStipDrawable(pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff); 10505b261ecSmrg 10635c4bbdfSmrg for (nbox = RegionNumRects(pClip), 10735c4bbdfSmrg pbox = RegionRects(pClip); nbox--; pbox++) { 10835c4bbdfSmrg x1 = x; 10935c4bbdfSmrg y1 = y; 11035c4bbdfSmrg x2 = x + width; 11135c4bbdfSmrg y2 = y + height; 11235c4bbdfSmrg if (x1 < pbox->x1) 11335c4bbdfSmrg x1 = pbox->x1; 11435c4bbdfSmrg if (y1 < pbox->y1) 11535c4bbdfSmrg y1 = pbox->y1; 11635c4bbdfSmrg if (x2 > pbox->x2) 11735c4bbdfSmrg x2 = pbox->x2; 11835c4bbdfSmrg if (y2 > pbox->y2) 11935c4bbdfSmrg y2 = pbox->y2; 12035c4bbdfSmrg if (x1 >= x2 || y1 >= y2) 12135c4bbdfSmrg continue; 12235c4bbdfSmrg fbBltStip(src + (y1 - y) * srcStride, 12335c4bbdfSmrg srcStride, 12435c4bbdfSmrg (x1 - x) * dstBpp, 12535c4bbdfSmrg dst + (y1 + dstYoff) * dstStride, 12635c4bbdfSmrg dstStride, 12735c4bbdfSmrg (x1 + dstXoff) * dstBpp, 12835c4bbdfSmrg (x2 - x1) * dstBpp, (y2 - y1), alu, pm, dstBpp); 12905b261ecSmrg } 13005b261ecSmrg 13135c4bbdfSmrg fbFinishAccess(pDrawable); 13205b261ecSmrg} 13305b261ecSmrg 13435c4bbdfSmrgvoid 13535c4bbdfSmrgfbPutXYImage(DrawablePtr pDrawable, 13635c4bbdfSmrg RegionPtr pClip, 13735c4bbdfSmrg FbBits fg, 13835c4bbdfSmrg FbBits bg, 13935c4bbdfSmrg FbBits pm, 14035c4bbdfSmrg int alu, 14135c4bbdfSmrg Bool opaque, 14235c4bbdfSmrg int x, 14335c4bbdfSmrg int y, 14435c4bbdfSmrg int width, int height, FbStip * src, FbStride srcStride, int srcX) 14505b261ecSmrg{ 14635c4bbdfSmrg FbBits *dst; 14735c4bbdfSmrg FbStride dstStride; 14835c4bbdfSmrg int dstBpp; 14935c4bbdfSmrg int dstXoff, dstYoff; 15035c4bbdfSmrg int nbox; 15135c4bbdfSmrg BoxPtr pbox; 15235c4bbdfSmrg int x1, y1, x2, y2; 15335c4bbdfSmrg FbBits fgand = 0, fgxor = 0, bgand = 0, bgxor = 0; 15405b261ecSmrg 15535c4bbdfSmrg fbGetDrawable(pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff); 15605b261ecSmrg 15735c4bbdfSmrg if (dstBpp == 1) { 15835c4bbdfSmrg if (opaque) 15935c4bbdfSmrg alu = FbOpaqueStipple1Rop(alu, fg, bg); 16035c4bbdfSmrg else 16135c4bbdfSmrg alu = FbStipple1Rop(alu, fg); 16205b261ecSmrg } 16335c4bbdfSmrg else { 16435c4bbdfSmrg fgand = fbAnd(alu, fg, pm); 16535c4bbdfSmrg fgxor = fbXor(alu, fg, pm); 16635c4bbdfSmrg if (opaque) { 16735c4bbdfSmrg bgand = fbAnd(alu, bg, pm); 16835c4bbdfSmrg bgxor = fbXor(alu, bg, pm); 16935c4bbdfSmrg } 17035c4bbdfSmrg else { 17135c4bbdfSmrg bgand = fbAnd(GXnoop, (FbBits) 0, FB_ALLONES); 17235c4bbdfSmrg bgxor = fbXor(GXnoop, (FbBits) 0, FB_ALLONES); 17335c4bbdfSmrg } 17405b261ecSmrg } 17505b261ecSmrg 17635c4bbdfSmrg for (nbox = RegionNumRects(pClip), 17735c4bbdfSmrg pbox = RegionRects(pClip); nbox--; pbox++) { 17835c4bbdfSmrg x1 = x; 17935c4bbdfSmrg y1 = y; 18035c4bbdfSmrg x2 = x + width; 18135c4bbdfSmrg y2 = y + height; 18235c4bbdfSmrg if (x1 < pbox->x1) 18335c4bbdfSmrg x1 = pbox->x1; 18435c4bbdfSmrg if (y1 < pbox->y1) 18535c4bbdfSmrg y1 = pbox->y1; 18635c4bbdfSmrg if (x2 > pbox->x2) 18735c4bbdfSmrg x2 = pbox->x2; 18835c4bbdfSmrg if (y2 > pbox->y2) 18935c4bbdfSmrg y2 = pbox->y2; 19035c4bbdfSmrg if (x1 >= x2 || y1 >= y2) 19135c4bbdfSmrg continue; 19235c4bbdfSmrg if (dstBpp == 1) { 19335c4bbdfSmrg fbBltStip(src + (y1 - y) * srcStride, 19435c4bbdfSmrg srcStride, 19535c4bbdfSmrg (x1 - x) + srcX, 19635c4bbdfSmrg (FbStip *) (dst + (y1 + dstYoff) * dstStride), 19735c4bbdfSmrg FbBitsStrideToStipStride(dstStride), 19835c4bbdfSmrg (x1 + dstXoff) * dstBpp, 19935c4bbdfSmrg (x2 - x1) * dstBpp, (y2 - y1), alu, pm, dstBpp); 20035c4bbdfSmrg } 20135c4bbdfSmrg else { 20235c4bbdfSmrg fbBltOne(src + (y1 - y) * srcStride, 20335c4bbdfSmrg srcStride, 20435c4bbdfSmrg (x1 - x) + srcX, 20535c4bbdfSmrg dst + (y1 + dstYoff) * dstStride, 20635c4bbdfSmrg dstStride, 20735c4bbdfSmrg (x1 + dstXoff) * dstBpp, 20835c4bbdfSmrg dstBpp, 20935c4bbdfSmrg (x2 - x1) * dstBpp, (y2 - y1), fgand, fgxor, bgand, bgxor); 21035c4bbdfSmrg } 21105b261ecSmrg } 21205b261ecSmrg 21335c4bbdfSmrg fbFinishAccess(pDrawable); 21405b261ecSmrg} 21505b261ecSmrg 21605b261ecSmrgvoid 21735c4bbdfSmrgfbGetImage(DrawablePtr pDrawable, 21835c4bbdfSmrg int x, 21935c4bbdfSmrg int y, 22035c4bbdfSmrg int w, int h, unsigned int format, unsigned long planeMask, char *d) 22105b261ecSmrg{ 22235c4bbdfSmrg FbBits *src; 22335c4bbdfSmrg FbStride srcStride; 22435c4bbdfSmrg int srcBpp; 22535c4bbdfSmrg int srcXoff, srcYoff; 22635c4bbdfSmrg FbStip *dst; 22735c4bbdfSmrg FbStride dstStride; 22835c4bbdfSmrg 22905b261ecSmrg /* 23005b261ecSmrg * XFree86 DDX empties the root borderClip when the VT is 23105b261ecSmrg * switched away; this checks for that case 23205b261ecSmrg */ 23305b261ecSmrg if (!fbDrawableEnabled(pDrawable)) 23435c4bbdfSmrg return; 23535c4bbdfSmrg 23605b261ecSmrg if (format == ZPixmap && 23735c4bbdfSmrg pDrawable->bitsPerPixel != BitsPerPixel(pDrawable->depth)) { 23835c4bbdfSmrg fb24_32GetImage(pDrawable, x, y, w, h, format, planeMask, d); 23935c4bbdfSmrg return; 24005b261ecSmrg } 24135c4bbdfSmrg 24235c4bbdfSmrg fbGetDrawable(pDrawable, src, srcStride, srcBpp, srcXoff, srcYoff); 24335c4bbdfSmrg 24405b261ecSmrg x += pDrawable->x; 24505b261ecSmrg y += pDrawable->y; 24605b261ecSmrg 24735c4bbdfSmrg dst = (FbStip *) d; 24835c4bbdfSmrg if (format == ZPixmap || srcBpp == 1) { 24935c4bbdfSmrg FbBits pm; 25005b261ecSmrg 25135c4bbdfSmrg pm = fbReplicatePixel(planeMask, srcBpp); 25235c4bbdfSmrg dstStride = PixmapBytePad(w, pDrawable->depth); 25335c4bbdfSmrg if (pm != FB_ALLONES) 25435c4bbdfSmrg memset(d, 0, dstStride * h); 25535c4bbdfSmrg dstStride /= sizeof(FbStip); 25635c4bbdfSmrg fbBltStip((FbStip *) (src + (y + srcYoff) * srcStride), 25735c4bbdfSmrg FbBitsStrideToStipStride(srcStride), 25835c4bbdfSmrg (x + srcXoff) * srcBpp, 25935c4bbdfSmrg dst, dstStride, 0, w * srcBpp, h, GXcopy, pm, srcBpp); 26005b261ecSmrg } 26135c4bbdfSmrg else { 26235c4bbdfSmrg dstStride = BitmapBytePad(w) / sizeof(FbStip); 26335c4bbdfSmrg fbBltPlane(src + (y + srcYoff) * srcStride, 26435c4bbdfSmrg srcStride, 26535c4bbdfSmrg (x + srcXoff) * srcBpp, 26635c4bbdfSmrg srcBpp, 26735c4bbdfSmrg dst, 26835c4bbdfSmrg dstStride, 26935c4bbdfSmrg 0, 27035c4bbdfSmrg w * srcBpp, h, 27135c4bbdfSmrg fbAndStip(GXcopy, FB_STIP_ALLONES, FB_STIP_ALLONES), 27235c4bbdfSmrg fbXorStip(GXcopy, FB_STIP_ALLONES, FB_STIP_ALLONES), 27335c4bbdfSmrg fbAndStip(GXcopy, 0, FB_STIP_ALLONES), 27435c4bbdfSmrg fbXorStip(GXcopy, 0, FB_STIP_ALLONES), planeMask); 27505b261ecSmrg } 27605b261ecSmrg 27735c4bbdfSmrg fbFinishAccess(pDrawable); 27805b261ecSmrg} 279