103b705cfSriastradh/* 203b705cfSriastradh * Copyright © 1998 Keith Packard 303b705cfSriastradh * Copyright © 2012 Intel Corporation 403b705cfSriastradh * 503b705cfSriastradh * Permission to use, copy, modify, distribute, and sell this software and its 603b705cfSriastradh * documentation for any purpose is hereby granted without fee, provided that 703b705cfSriastradh * the above copyright notice appear in all copies and that both that 803b705cfSriastradh * copyright notice and this permission notice appear in supporting 903b705cfSriastradh * documentation, and that the name of Keith Packard not be used in 1003b705cfSriastradh * advertising or publicity pertaining to distribution of the software without 1103b705cfSriastradh * specific, written prior permission. Keith Packard makes no 1203b705cfSriastradh * representations about the suitability of this software for any purpose. It 1303b705cfSriastradh * is provided "as is" without express or implied warranty. 1403b705cfSriastradh * 1503b705cfSriastradh * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 1603b705cfSriastradh * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 1703b705cfSriastradh * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR 1803b705cfSriastradh * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 1903b705cfSriastradh * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 2003b705cfSriastradh * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 2103b705cfSriastradh * PERFORMANCE OF THIS SOFTWARE. 2203b705cfSriastradh */ 2303b705cfSriastradh 2403b705cfSriastradh#include <string.h> 2503b705cfSriastradh 2603b705cfSriastradh#include "fb.h" 2703b705cfSriastradh#include "fbclip.h" 2803b705cfSriastradh 2903b705cfSriastradhstruct fbPutZImage { 3003b705cfSriastradh FbStip *src, *dst; 3103b705cfSriastradh FbStride src_stride, dst_stride; 3203b705cfSriastradh 3303b705cfSriastradh int dst_x, dst_y; 3403b705cfSriastradh int x0, y0; 3503b705cfSriastradh}; 3603b705cfSriastradh 3703b705cfSriastradhinline static void 3803b705cfSriastradh_fbPutZImage(DrawablePtr drawable, GCPtr gc, const BoxRec *b, void *_data) 3903b705cfSriastradh{ 4003b705cfSriastradh struct fbPutZImage *data = _data; 4103b705cfSriastradh int bpp = drawable->bitsPerPixel; 4203b705cfSriastradh 4303b705cfSriastradh fbBltStip(data->src + (b->y1 - data->y0) * data->src_stride, data->src_stride, 4403b705cfSriastradh (b->x1 - data->x0) * bpp, 4503b705cfSriastradh data->dst + (b->y1 + data->dst_y) * data->dst_stride, 4603b705cfSriastradh data->dst_stride, 4703b705cfSriastradh (b->x1 + data->dst_x) * bpp, 4803b705cfSriastradh (b->x2 - b->x1) * bpp, (b->y2 - b->y1), 4903b705cfSriastradh gc->alu, fb_gc(gc)->pm, bpp); 5003b705cfSriastradh} 5103b705cfSriastradh 5203b705cfSriastradhstatic void 5303b705cfSriastradhfbPutZImage(DrawablePtr drawable, GCPtr gc, 5403b705cfSriastradh int x, int y, int width, int height, 5503b705cfSriastradh FbStip *src, FbStride srcStride) 5603b705cfSriastradh{ 5703b705cfSriastradh PixmapPtr pixmap; 5803b705cfSriastradh struct fbPutZImage data; 5903b705cfSriastradh BoxRec box; 6003b705cfSriastradh 6103b705cfSriastradh box.x1 = data.x0 = x; 6203b705cfSriastradh box.y1 = data.y0 = y; 6303b705cfSriastradh box.x2 = x + width; 6403b705cfSriastradh box.y2 = y + height; 6503b705cfSriastradh data.src = src; 6603b705cfSriastradh data.src_stride = srcStride; 6703b705cfSriastradh 6803b705cfSriastradh fbGetDrawablePixmap(drawable, pixmap, data.dst_x, data.dst_y); 6903b705cfSriastradh data.dst = pixmap->devPrivate.ptr; 7003b705cfSriastradh data.dst_stride = pixmap->devKind / sizeof(FbStip); 7103b705cfSriastradh 7203b705cfSriastradh fbDrawableRun(drawable, gc, &box, _fbPutZImage, &data); 7303b705cfSriastradh} 7403b705cfSriastradh 7503b705cfSriastradhstruct fbPutXYImage { 7603b705cfSriastradh FbStip *src, *dst; 7703b705cfSriastradh FbStride src_stride, dst_stride; 7803b705cfSriastradh 7903b705cfSriastradh int dst_x, dst_y, src_x; 8003b705cfSriastradh int x0, y0; 8103b705cfSriastradh 8203b705cfSriastradh int alu, pm; 8303b705cfSriastradh FbBits fgand, fgxor, bgand, bgxor; 8403b705cfSriastradh}; 8503b705cfSriastradh 8603b705cfSriastradhinline static void 8703b705cfSriastradh_fbPutXYImage1(DrawablePtr drawable, GCPtr gc, const BoxRec *b, void *_data) 8803b705cfSriastradh{ 8903b705cfSriastradh struct fbPutXYImage *data = _data; 9003b705cfSriastradh int bpp = drawable->bitsPerPixel; 9103b705cfSriastradh 9203b705cfSriastradh fbBltStip(data->src + (b->y1 - data->y0) * data->src_stride, data->src_stride, 9303b705cfSriastradh (b->x1 - data->x0) + data->src_x, 9403b705cfSriastradh (FbStip *) (data->dst + (b->y1 + data->dst_y) * data->dst_stride), 9503b705cfSriastradh data->dst_stride, 9603b705cfSriastradh (b->x1 + data->dst_x) * bpp, 9703b705cfSriastradh (b->x2 - b->x1) * bpp, (b->y2 - b->y1), 9803b705cfSriastradh data->alu, data->pm, bpp); 9903b705cfSriastradh} 10003b705cfSriastradh 10103b705cfSriastradhinline static void 10203b705cfSriastradh_fbPutXYImageN(DrawablePtr drawable, GCPtr gc, const BoxRec *b, void *_data) 10303b705cfSriastradh{ 10403b705cfSriastradh struct fbPutXYImage *data = _data; 10503b705cfSriastradh int bpp = drawable->bitsPerPixel; 10603b705cfSriastradh 10703b705cfSriastradh fbBltOne(data->src + (b->y1 - data->y0) * data->src_stride, 10803b705cfSriastradh data->src_stride, 10903b705cfSriastradh (b->x1 - data->x0) + data->src_x, 11003b705cfSriastradh data->dst + (b->y1 + data->dst_y) * data->dst_stride, 11103b705cfSriastradh data->dst_stride, 11203b705cfSriastradh (b->x1 + data->dst_x) * bpp, bpp, 11303b705cfSriastradh (b->x2 - b->x1) * bpp, (b->y2 - b->y1), 11403b705cfSriastradh data->fgand, data->fgxor, 11503b705cfSriastradh data->bgand, data->bgxor); 11603b705cfSriastradh} 11703b705cfSriastradh 11803b705cfSriastradhvoid 11903b705cfSriastradhfbPutXYImage(DrawablePtr drawable, GCPtr gc, 12003b705cfSriastradh FbBits fg, FbBits bg, FbBits pm, int alu, Bool opaque, 12103b705cfSriastradh int x, int y, int width, int height, 12203b705cfSriastradh FbStip *src, FbStride srcStride, int srcX) 12303b705cfSriastradh{ 12403b705cfSriastradh PixmapPtr pixmap; 12503b705cfSriastradh struct fbPutXYImage data; 12603b705cfSriastradh BoxRec box; 12703b705cfSriastradh 12803b705cfSriastradh box.x1 = data.x0 = x; 12903b705cfSriastradh box.y1 = data.y0 = y; 13003b705cfSriastradh box.x2 = x + width; 13103b705cfSriastradh box.y2 = y + height; 13203b705cfSriastradh data.src = src; 13303b705cfSriastradh data.src_stride = srcStride; 13403b705cfSriastradh data.src_x = srcX; 13503b705cfSriastradh 13603b705cfSriastradh fbGetDrawablePixmap(drawable, pixmap, data.dst_x, data.dst_y); 13703b705cfSriastradh data.dst = pixmap->devPrivate.ptr; 13803b705cfSriastradh data.dst_stride = pixmap->devKind / sizeof(FbStip); 13903b705cfSriastradh 14003b705cfSriastradh if (drawable->bitsPerPixel == 1) { 14103b705cfSriastradh if (opaque) 14203b705cfSriastradh data.alu = FbOpaqueStipple1Rop(alu, fg, bg); 14303b705cfSriastradh else 14403b705cfSriastradh data.alu = FbStipple1Rop(alu, fg); 14503b705cfSriastradh data.pm = pm; 14603b705cfSriastradh 14703b705cfSriastradh fbDrawableRun(drawable, gc, &box, _fbPutXYImage1, &data); 14803b705cfSriastradh } else { 14903b705cfSriastradh data.fgand = fbAnd(alu, fg, pm); 15003b705cfSriastradh data.fgxor = fbXor(alu, fg, pm); 15103b705cfSriastradh if (opaque) { 15203b705cfSriastradh data.bgand = fbAnd(alu, bg, pm); 15303b705cfSriastradh data.bgxor = fbXor(alu, bg, pm); 15403b705cfSriastradh } else { 15503b705cfSriastradh data.bgand = fbAnd(GXnoop, (FbBits) 0, FB_ALLONES); 15603b705cfSriastradh data.bgxor = fbXor(GXnoop, (FbBits) 0, FB_ALLONES); 15703b705cfSriastradh } 15803b705cfSriastradh 15903b705cfSriastradh fbDrawableRun(drawable, gc, &box, _fbPutXYImageN, &data); 16003b705cfSriastradh } 16103b705cfSriastradh} 16203b705cfSriastradh 16303b705cfSriastradhvoid 16403b705cfSriastradhfbPutImage(DrawablePtr drawable, GCPtr gc, int depth, 16503b705cfSriastradh int x, int y, int w, int h, 16603b705cfSriastradh int leftPad, int format, char *image) 16703b705cfSriastradh{ 16803b705cfSriastradh FbGCPrivPtr pgc = fb_gc(gc); 16903b705cfSriastradh unsigned long i; 17003b705cfSriastradh FbStride srcStride; 17103b705cfSriastradh FbStip *src = (FbStip *)image; 17203b705cfSriastradh 17303b705cfSriastradh DBG(("%s (%d, %d)x(%d, %d)\n", __FUNCTION__, x, y, w, h)); 17403b705cfSriastradh 17503b705cfSriastradh x += drawable->x; 17603b705cfSriastradh y += drawable->y; 17703b705cfSriastradh 17803b705cfSriastradh switch (format) { 17903b705cfSriastradh case XYBitmap: 18003b705cfSriastradh srcStride = BitmapBytePad(w + leftPad) / sizeof(FbStip); 18103b705cfSriastradh fbPutXYImage(drawable, gc, 18203b705cfSriastradh pgc->fg, pgc->bg, pgc->pm, 18303b705cfSriastradh gc->alu, TRUE, 18403b705cfSriastradh x, y, w, h, 18503b705cfSriastradh src, srcStride, leftPad); 18603b705cfSriastradh break; 18703b705cfSriastradh case XYPixmap: 18803b705cfSriastradh srcStride = BitmapBytePad(w + leftPad) / sizeof(FbStip); 18903b705cfSriastradh for (i = (unsigned long) 1 << (drawable->depth - 1); i; i >>= 1) { 19003b705cfSriastradh if (i & gc->planemask) { 19103b705cfSriastradh fbPutXYImage(drawable, gc, 19203b705cfSriastradh FB_ALLONES, 19303b705cfSriastradh 0, 19403b705cfSriastradh fbReplicatePixel(i, drawable->bitsPerPixel), 19503b705cfSriastradh gc->alu, 19603b705cfSriastradh TRUE, x, y, w, h, src, srcStride, leftPad); 19703b705cfSriastradh src += srcStride * h; 19803b705cfSriastradh } 19903b705cfSriastradh } 20003b705cfSriastradh break; 20103b705cfSriastradh case ZPixmap: 20203b705cfSriastradh srcStride = PixmapBytePad(w, drawable->depth) / sizeof(FbStip); 20303b705cfSriastradh fbPutZImage(drawable, gc, 20403b705cfSriastradh x, y, w, h, src, srcStride); 20503b705cfSriastradh } 20603b705cfSriastradh} 20703b705cfSriastradh 20803b705cfSriastradhvoid 20903b705cfSriastradhfbGetImage(DrawablePtr drawable, 21003b705cfSriastradh int x, int y, int w, int h, 21103b705cfSriastradh unsigned int format, unsigned long planeMask, char *d) 21203b705cfSriastradh{ 21303b705cfSriastradh FbBits *src; 21403b705cfSriastradh FbStride srcStride; 21503b705cfSriastradh int srcBpp; 21603b705cfSriastradh int srcXoff, srcYoff; 21703b705cfSriastradh FbStip *dst; 21803b705cfSriastradh FbStride dstStride; 21903b705cfSriastradh 22003b705cfSriastradh DBG(("%s (%d, %d)x(%d, %d)\n", __FUNCTION__, x, y, w, h)); 22103b705cfSriastradh 22203b705cfSriastradh fbGetDrawable(drawable, src, srcStride, srcBpp, srcXoff, srcYoff); 22303b705cfSriastradh 22403b705cfSriastradh x += drawable->x; 22503b705cfSriastradh y += drawable->y; 22603b705cfSriastradh 22703b705cfSriastradh dst = (FbStip *) d; 22803b705cfSriastradh if (format == ZPixmap || srcBpp == 1) { 22903b705cfSriastradh FbBits pm; 23003b705cfSriastradh 23103b705cfSriastradh pm = fbReplicatePixel(planeMask, srcBpp); 232fe8aea9eSmrg 23303b705cfSriastradh dstStride = PixmapBytePad(w, drawable->depth); 23403b705cfSriastradh dstStride /= sizeof(FbStip); 235fe8aea9eSmrg 23603b705cfSriastradh fbBltStip((FbStip *)(src + (y + srcYoff) * srcStride), srcStride, 23703b705cfSriastradh (x + srcXoff) * srcBpp, 238fe8aea9eSmrg dst, dstStride, 0, w * srcBpp, h, GXcopy, FB_ALLONES, srcBpp); 239fe8aea9eSmrg 240fe8aea9eSmrg if (pm != FB_ALLONES) { 241fe8aea9eSmrg int i = dstStride * h; 242fe8aea9eSmrg while (i--) 243fe8aea9eSmrg *dst++ &= pm; 244fe8aea9eSmrg } 24503b705cfSriastradh } else { 24603b705cfSriastradh dstStride = BitmapBytePad(w) / sizeof(FbStip); 24703b705cfSriastradh fbBltPlane(src + (y + srcYoff) * srcStride, 24803b705cfSriastradh srcStride, 24903b705cfSriastradh (x + srcXoff) * srcBpp, 25003b705cfSriastradh srcBpp, 25103b705cfSriastradh dst, 25203b705cfSriastradh dstStride, 25303b705cfSriastradh 0, 25403b705cfSriastradh w * srcBpp, h, 25503b705cfSriastradh fbAndStip(GXcopy, FB_STIP_ALLONES, FB_STIP_ALLONES), 25603b705cfSriastradh fbXorStip(GXcopy, FB_STIP_ALLONES, FB_STIP_ALLONES), 25703b705cfSriastradh fbAndStip(GXcopy, 0, FB_STIP_ALLONES), 25803b705cfSriastradh fbXorStip(GXcopy, 0, FB_STIP_ALLONES), planeMask); 25903b705cfSriastradh } 26003b705cfSriastradh} 261