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 } 671b5d61b8Smrg src += srcStride * h; 6835c4bbdfSmrg } 6935c4bbdfSmrg break; 7005b261ecSmrg case ZPixmap: 711b5d61b8Smrg srcStride = PixmapBytePad(w, pDrawable->depth) / sizeof(FbStip); 721b5d61b8Smrg fbPutZImage(pDrawable, fbGetCompositeClip(pGC), 731b5d61b8Smrg pGC->alu, pPriv->pm, x, y, w, h, src, srcStride); 7405b261ecSmrg } 7505b261ecSmrg} 7605b261ecSmrg 7705b261ecSmrgvoid 7835c4bbdfSmrgfbPutZImage(DrawablePtr pDrawable, 7935c4bbdfSmrg RegionPtr pClip, 8035c4bbdfSmrg int alu, 8135c4bbdfSmrg FbBits pm, 8235c4bbdfSmrg int x, 8335c4bbdfSmrg int y, int width, int height, FbStip * src, FbStride srcStride) 8405b261ecSmrg{ 8535c4bbdfSmrg FbStip *dst; 8635c4bbdfSmrg FbStride dstStride; 8735c4bbdfSmrg int dstBpp; 8835c4bbdfSmrg int dstXoff, dstYoff; 8935c4bbdfSmrg int nbox; 9035c4bbdfSmrg BoxPtr pbox; 9135c4bbdfSmrg int x1, y1, x2, y2; 9205b261ecSmrg 9335c4bbdfSmrg fbGetStipDrawable(pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff); 9405b261ecSmrg 9535c4bbdfSmrg for (nbox = RegionNumRects(pClip), 9635c4bbdfSmrg pbox = RegionRects(pClip); nbox--; pbox++) { 9735c4bbdfSmrg x1 = x; 9835c4bbdfSmrg y1 = y; 9935c4bbdfSmrg x2 = x + width; 10035c4bbdfSmrg y2 = y + height; 10135c4bbdfSmrg if (x1 < pbox->x1) 10235c4bbdfSmrg x1 = pbox->x1; 10335c4bbdfSmrg if (y1 < pbox->y1) 10435c4bbdfSmrg y1 = pbox->y1; 10535c4bbdfSmrg if (x2 > pbox->x2) 10635c4bbdfSmrg x2 = pbox->x2; 10735c4bbdfSmrg if (y2 > pbox->y2) 10835c4bbdfSmrg y2 = pbox->y2; 10935c4bbdfSmrg if (x1 >= x2 || y1 >= y2) 11035c4bbdfSmrg continue; 11135c4bbdfSmrg fbBltStip(src + (y1 - y) * srcStride, 11235c4bbdfSmrg srcStride, 11335c4bbdfSmrg (x1 - x) * dstBpp, 11435c4bbdfSmrg dst + (y1 + dstYoff) * dstStride, 11535c4bbdfSmrg dstStride, 11635c4bbdfSmrg (x1 + dstXoff) * dstBpp, 11735c4bbdfSmrg (x2 - x1) * dstBpp, (y2 - y1), alu, pm, dstBpp); 11805b261ecSmrg } 11905b261ecSmrg 12035c4bbdfSmrg fbFinishAccess(pDrawable); 12105b261ecSmrg} 12205b261ecSmrg 12335c4bbdfSmrgvoid 12435c4bbdfSmrgfbPutXYImage(DrawablePtr pDrawable, 12535c4bbdfSmrg RegionPtr pClip, 12635c4bbdfSmrg FbBits fg, 12735c4bbdfSmrg FbBits bg, 12835c4bbdfSmrg FbBits pm, 12935c4bbdfSmrg int alu, 13035c4bbdfSmrg Bool opaque, 13135c4bbdfSmrg int x, 13235c4bbdfSmrg int y, 13335c4bbdfSmrg int width, int height, FbStip * src, FbStride srcStride, int srcX) 13405b261ecSmrg{ 13535c4bbdfSmrg FbBits *dst; 13635c4bbdfSmrg FbStride dstStride; 13735c4bbdfSmrg int dstBpp; 13835c4bbdfSmrg int dstXoff, dstYoff; 13935c4bbdfSmrg int nbox; 14035c4bbdfSmrg BoxPtr pbox; 14135c4bbdfSmrg int x1, y1, x2, y2; 14235c4bbdfSmrg FbBits fgand = 0, fgxor = 0, bgand = 0, bgxor = 0; 14305b261ecSmrg 14435c4bbdfSmrg fbGetDrawable(pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff); 14505b261ecSmrg 14635c4bbdfSmrg if (dstBpp == 1) { 14735c4bbdfSmrg if (opaque) 14835c4bbdfSmrg alu = FbOpaqueStipple1Rop(alu, fg, bg); 14935c4bbdfSmrg else 15035c4bbdfSmrg alu = FbStipple1Rop(alu, fg); 15105b261ecSmrg } 15235c4bbdfSmrg else { 15335c4bbdfSmrg fgand = fbAnd(alu, fg, pm); 15435c4bbdfSmrg fgxor = fbXor(alu, fg, pm); 15535c4bbdfSmrg if (opaque) { 15635c4bbdfSmrg bgand = fbAnd(alu, bg, pm); 15735c4bbdfSmrg bgxor = fbXor(alu, bg, pm); 15835c4bbdfSmrg } 15935c4bbdfSmrg else { 16035c4bbdfSmrg bgand = fbAnd(GXnoop, (FbBits) 0, FB_ALLONES); 16135c4bbdfSmrg bgxor = fbXor(GXnoop, (FbBits) 0, FB_ALLONES); 16235c4bbdfSmrg } 16305b261ecSmrg } 16405b261ecSmrg 16535c4bbdfSmrg for (nbox = RegionNumRects(pClip), 16635c4bbdfSmrg pbox = RegionRects(pClip); nbox--; pbox++) { 16735c4bbdfSmrg x1 = x; 16835c4bbdfSmrg y1 = y; 16935c4bbdfSmrg x2 = x + width; 17035c4bbdfSmrg y2 = y + height; 17135c4bbdfSmrg if (x1 < pbox->x1) 17235c4bbdfSmrg x1 = pbox->x1; 17335c4bbdfSmrg if (y1 < pbox->y1) 17435c4bbdfSmrg y1 = pbox->y1; 17535c4bbdfSmrg if (x2 > pbox->x2) 17635c4bbdfSmrg x2 = pbox->x2; 17735c4bbdfSmrg if (y2 > pbox->y2) 17835c4bbdfSmrg y2 = pbox->y2; 17935c4bbdfSmrg if (x1 >= x2 || y1 >= y2) 18035c4bbdfSmrg continue; 18135c4bbdfSmrg if (dstBpp == 1) { 18235c4bbdfSmrg fbBltStip(src + (y1 - y) * srcStride, 18335c4bbdfSmrg srcStride, 18435c4bbdfSmrg (x1 - x) + srcX, 18535c4bbdfSmrg (FbStip *) (dst + (y1 + dstYoff) * dstStride), 18635c4bbdfSmrg FbBitsStrideToStipStride(dstStride), 18735c4bbdfSmrg (x1 + dstXoff) * dstBpp, 18835c4bbdfSmrg (x2 - x1) * dstBpp, (y2 - y1), alu, pm, dstBpp); 18935c4bbdfSmrg } 19035c4bbdfSmrg else { 19135c4bbdfSmrg fbBltOne(src + (y1 - y) * srcStride, 19235c4bbdfSmrg srcStride, 19335c4bbdfSmrg (x1 - x) + srcX, 19435c4bbdfSmrg dst + (y1 + dstYoff) * dstStride, 19535c4bbdfSmrg dstStride, 19635c4bbdfSmrg (x1 + dstXoff) * dstBpp, 19735c4bbdfSmrg dstBpp, 19835c4bbdfSmrg (x2 - x1) * dstBpp, (y2 - y1), fgand, fgxor, bgand, bgxor); 19935c4bbdfSmrg } 20005b261ecSmrg } 20105b261ecSmrg 20235c4bbdfSmrg fbFinishAccess(pDrawable); 20305b261ecSmrg} 20405b261ecSmrg 20505b261ecSmrgvoid 20635c4bbdfSmrgfbGetImage(DrawablePtr pDrawable, 20735c4bbdfSmrg int x, 20835c4bbdfSmrg int y, 20935c4bbdfSmrg int w, int h, unsigned int format, unsigned long planeMask, char *d) 21005b261ecSmrg{ 21135c4bbdfSmrg FbBits *src; 21235c4bbdfSmrg FbStride srcStride; 21335c4bbdfSmrg int srcBpp; 21435c4bbdfSmrg int srcXoff, srcYoff; 21535c4bbdfSmrg FbStip *dst; 21635c4bbdfSmrg FbStride dstStride; 21735c4bbdfSmrg 21805b261ecSmrg /* 21905b261ecSmrg * XFree86 DDX empties the root borderClip when the VT is 22005b261ecSmrg * switched away; this checks for that case 22105b261ecSmrg */ 22205b261ecSmrg if (!fbDrawableEnabled(pDrawable)) 22335c4bbdfSmrg return; 22435c4bbdfSmrg 22535c4bbdfSmrg fbGetDrawable(pDrawable, src, srcStride, srcBpp, srcXoff, srcYoff); 22635c4bbdfSmrg 22705b261ecSmrg x += pDrawable->x; 22805b261ecSmrg y += pDrawable->y; 22905b261ecSmrg 23035c4bbdfSmrg dst = (FbStip *) d; 23135c4bbdfSmrg if (format == ZPixmap || srcBpp == 1) { 23235c4bbdfSmrg FbBits pm; 23305b261ecSmrg 23435c4bbdfSmrg pm = fbReplicatePixel(planeMask, srcBpp); 23535c4bbdfSmrg dstStride = PixmapBytePad(w, pDrawable->depth); 23635c4bbdfSmrg dstStride /= sizeof(FbStip); 23735c4bbdfSmrg fbBltStip((FbStip *) (src + (y + srcYoff) * srcStride), 23835c4bbdfSmrg FbBitsStrideToStipStride(srcStride), 23935c4bbdfSmrg (x + srcXoff) * srcBpp, 2401b5d61b8Smrg dst, dstStride, 0, w * srcBpp, h, GXcopy, FB_ALLONES, srcBpp); 2411b5d61b8Smrg 2421b5d61b8Smrg if (pm != FB_ALLONES) { 2431b5d61b8Smrg for (int i = 0; i < dstStride * h; i++) 2441b5d61b8Smrg dst[i] &= pm; 2451b5d61b8Smrg } 24605b261ecSmrg } 24735c4bbdfSmrg else { 24835c4bbdfSmrg dstStride = BitmapBytePad(w) / sizeof(FbStip); 24935c4bbdfSmrg fbBltPlane(src + (y + srcYoff) * srcStride, 25035c4bbdfSmrg srcStride, 25135c4bbdfSmrg (x + srcXoff) * srcBpp, 25235c4bbdfSmrg srcBpp, 25335c4bbdfSmrg dst, 25435c4bbdfSmrg dstStride, 25535c4bbdfSmrg 0, 25635c4bbdfSmrg w * srcBpp, h, 25735c4bbdfSmrg fbAndStip(GXcopy, FB_STIP_ALLONES, FB_STIP_ALLONES), 25835c4bbdfSmrg fbXorStip(GXcopy, FB_STIP_ALLONES, FB_STIP_ALLONES), 25935c4bbdfSmrg fbAndStip(GXcopy, 0, FB_STIP_ALLONES), 26035c4bbdfSmrg fbXorStip(GXcopy, 0, FB_STIP_ALLONES), planeMask); 26105b261ecSmrg } 26205b261ecSmrg 26335c4bbdfSmrg fbFinishAccess(pDrawable); 26405b261ecSmrg} 265