1/* 2 * Copyright © 1998 Keith Packard 3 * Copyright © 2012 Intel Corporation 4 * 5 * Permission to use, copy, modify, distribute, and sell this software and its 6 * documentation for any purpose is hereby granted without fee, provided that 7 * the above copyright notice appear in all copies and that both that 8 * copyright notice and this permission notice appear in supporting 9 * documentation, and that the name of Keith Packard not be used in 10 * advertising or publicity pertaining to distribution of the software without 11 * specific, written prior permission. Keith Packard makes no 12 * representations about the suitability of this software for any purpose. It 13 * is provided "as is" without express or implied warranty. 14 * 15 * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 16 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 17 * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR 18 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 19 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 20 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 21 * PERFORMANCE OF THIS SOFTWARE. 22 */ 23 24#include <string.h> 25 26#include "fb.h" 27#include "fbclip.h" 28 29struct fbPutZImage { 30 FbStip *src, *dst; 31 FbStride src_stride, dst_stride; 32 33 int dst_x, dst_y; 34 int x0, y0; 35}; 36 37inline static void 38_fbPutZImage(DrawablePtr drawable, GCPtr gc, const BoxRec *b, void *_data) 39{ 40 struct fbPutZImage *data = _data; 41 int bpp = drawable->bitsPerPixel; 42 43 fbBltStip(data->src + (b->y1 - data->y0) * data->src_stride, data->src_stride, 44 (b->x1 - data->x0) * bpp, 45 data->dst + (b->y1 + data->dst_y) * data->dst_stride, 46 data->dst_stride, 47 (b->x1 + data->dst_x) * bpp, 48 (b->x2 - b->x1) * bpp, (b->y2 - b->y1), 49 gc->alu, fb_gc(gc)->pm, bpp); 50} 51 52static void 53fbPutZImage(DrawablePtr drawable, GCPtr gc, 54 int x, int y, int width, int height, 55 FbStip *src, FbStride srcStride) 56{ 57 PixmapPtr pixmap; 58 struct fbPutZImage data; 59 BoxRec box; 60 61 box.x1 = data.x0 = x; 62 box.y1 = data.y0 = y; 63 box.x2 = x + width; 64 box.y2 = y + height; 65 data.src = src; 66 data.src_stride = srcStride; 67 68 fbGetDrawablePixmap(drawable, pixmap, data.dst_x, data.dst_y); 69 data.dst = pixmap->devPrivate.ptr; 70 data.dst_stride = pixmap->devKind / sizeof(FbStip); 71 72 fbDrawableRun(drawable, gc, &box, _fbPutZImage, &data); 73} 74 75struct fbPutXYImage { 76 FbStip *src, *dst; 77 FbStride src_stride, dst_stride; 78 79 int dst_x, dst_y, src_x; 80 int x0, y0; 81 82 int alu, pm; 83 FbBits fgand, fgxor, bgand, bgxor; 84}; 85 86inline static void 87_fbPutXYImage1(DrawablePtr drawable, GCPtr gc, const BoxRec *b, void *_data) 88{ 89 struct fbPutXYImage *data = _data; 90 int bpp = drawable->bitsPerPixel; 91 92 fbBltStip(data->src + (b->y1 - data->y0) * data->src_stride, data->src_stride, 93 (b->x1 - data->x0) + data->src_x, 94 (FbStip *) (data->dst + (b->y1 + data->dst_y) * data->dst_stride), 95 data->dst_stride, 96 (b->x1 + data->dst_x) * bpp, 97 (b->x2 - b->x1) * bpp, (b->y2 - b->y1), 98 data->alu, data->pm, bpp); 99} 100 101inline static void 102_fbPutXYImageN(DrawablePtr drawable, GCPtr gc, const BoxRec *b, void *_data) 103{ 104 struct fbPutXYImage *data = _data; 105 int bpp = drawable->bitsPerPixel; 106 107 fbBltOne(data->src + (b->y1 - data->y0) * data->src_stride, 108 data->src_stride, 109 (b->x1 - data->x0) + data->src_x, 110 data->dst + (b->y1 + data->dst_y) * data->dst_stride, 111 data->dst_stride, 112 (b->x1 + data->dst_x) * bpp, bpp, 113 (b->x2 - b->x1) * bpp, (b->y2 - b->y1), 114 data->fgand, data->fgxor, 115 data->bgand, data->bgxor); 116} 117 118void 119fbPutXYImage(DrawablePtr drawable, GCPtr gc, 120 FbBits fg, FbBits bg, FbBits pm, int alu, Bool opaque, 121 int x, int y, int width, int height, 122 FbStip *src, FbStride srcStride, int srcX) 123{ 124 PixmapPtr pixmap; 125 struct fbPutXYImage data; 126 BoxRec box; 127 128 box.x1 = data.x0 = x; 129 box.y1 = data.y0 = y; 130 box.x2 = x + width; 131 box.y2 = y + height; 132 data.src = src; 133 data.src_stride = srcStride; 134 data.src_x = srcX; 135 136 fbGetDrawablePixmap(drawable, pixmap, data.dst_x, data.dst_y); 137 data.dst = pixmap->devPrivate.ptr; 138 data.dst_stride = pixmap->devKind / sizeof(FbStip); 139 140 if (drawable->bitsPerPixel == 1) { 141 if (opaque) 142 data.alu = FbOpaqueStipple1Rop(alu, fg, bg); 143 else 144 data.alu = FbStipple1Rop(alu, fg); 145 data.pm = pm; 146 147 fbDrawableRun(drawable, gc, &box, _fbPutXYImage1, &data); 148 } else { 149 data.fgand = fbAnd(alu, fg, pm); 150 data.fgxor = fbXor(alu, fg, pm); 151 if (opaque) { 152 data.bgand = fbAnd(alu, bg, pm); 153 data.bgxor = fbXor(alu, bg, pm); 154 } else { 155 data.bgand = fbAnd(GXnoop, (FbBits) 0, FB_ALLONES); 156 data.bgxor = fbXor(GXnoop, (FbBits) 0, FB_ALLONES); 157 } 158 159 fbDrawableRun(drawable, gc, &box, _fbPutXYImageN, &data); 160 } 161} 162 163void 164fbPutImage(DrawablePtr drawable, GCPtr gc, int depth, 165 int x, int y, int w, int h, 166 int leftPad, int format, char *image) 167{ 168 FbGCPrivPtr pgc = fb_gc(gc); 169 unsigned long i; 170 FbStride srcStride; 171 FbStip *src = (FbStip *)image; 172 173 DBG(("%s (%d, %d)x(%d, %d)\n", __FUNCTION__, x, y, w, h)); 174 175 x += drawable->x; 176 y += drawable->y; 177 178 switch (format) { 179 case XYBitmap: 180 srcStride = BitmapBytePad(w + leftPad) / sizeof(FbStip); 181 fbPutXYImage(drawable, gc, 182 pgc->fg, pgc->bg, pgc->pm, 183 gc->alu, TRUE, 184 x, y, w, h, 185 src, srcStride, leftPad); 186 break; 187 case XYPixmap: 188 srcStride = BitmapBytePad(w + leftPad) / sizeof(FbStip); 189 for (i = (unsigned long) 1 << (drawable->depth - 1); i; i >>= 1) { 190 if (i & gc->planemask) { 191 fbPutXYImage(drawable, gc, 192 FB_ALLONES, 193 0, 194 fbReplicatePixel(i, drawable->bitsPerPixel), 195 gc->alu, 196 TRUE, x, y, w, h, src, srcStride, leftPad); 197 src += srcStride * h; 198 } 199 } 200 break; 201 case ZPixmap: 202 srcStride = PixmapBytePad(w, drawable->depth) / sizeof(FbStip); 203 fbPutZImage(drawable, gc, 204 x, y, w, h, src, srcStride); 205 } 206} 207 208void 209fbGetImage(DrawablePtr drawable, 210 int x, int y, int w, int h, 211 unsigned int format, unsigned long planeMask, char *d) 212{ 213 FbBits *src; 214 FbStride srcStride; 215 int srcBpp; 216 int srcXoff, srcYoff; 217 FbStip *dst; 218 FbStride dstStride; 219 220 DBG(("%s (%d, %d)x(%d, %d)\n", __FUNCTION__, x, y, w, h)); 221 222 fbGetDrawable(drawable, src, srcStride, srcBpp, srcXoff, srcYoff); 223 224 x += drawable->x; 225 y += drawable->y; 226 227 dst = (FbStip *) d; 228 if (format == ZPixmap || srcBpp == 1) { 229 FbBits pm; 230 231 pm = fbReplicatePixel(planeMask, srcBpp); 232 233 dstStride = PixmapBytePad(w, drawable->depth); 234 dstStride /= sizeof(FbStip); 235 236 fbBltStip((FbStip *)(src + (y + srcYoff) * srcStride), srcStride, 237 (x + srcXoff) * srcBpp, 238 dst, dstStride, 0, w * srcBpp, h, GXcopy, FB_ALLONES, srcBpp); 239 240 if (pm != FB_ALLONES) { 241 int i = dstStride * h; 242 while (i--) 243 *dst++ &= pm; 244 } 245 } else { 246 dstStride = BitmapBytePad(w) / sizeof(FbStip); 247 fbBltPlane(src + (y + srcYoff) * srcStride, 248 srcStride, 249 (x + srcXoff) * srcBpp, 250 srcBpp, 251 dst, 252 dstStride, 253 0, 254 w * srcBpp, h, 255 fbAndStip(GXcopy, FB_STIP_ALLONES, FB_STIP_ALLONES), 256 fbXorStip(GXcopy, FB_STIP_ALLONES, FB_STIP_ALLONES), 257 fbAndStip(GXcopy, 0, FB_STIP_ALLONES), 258 fbXorStip(GXcopy, 0, FB_STIP_ALLONES), planeMask); 259 } 260} 261