1/* 2 * Copyright © 1998 Keith Packard 3 * 4 * Permission to use, copy, modify, distribute, and sell this software and its 5 * documentation for any purpose is hereby granted without fee, provided that 6 * the above copyright notice appear in all copies and that both that 7 * copyright notice and this permission notice appear in supporting 8 * documentation, and that the name of Keith Packard not be used in 9 * advertising or publicity pertaining to distribution of the software without 10 * specific, written prior permission. Keith Packard makes no 11 * representations about the suitability of this software for any purpose. It 12 * is provided "as is" without express or implied warranty. 13 * 14 * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 15 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 16 * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR 17 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 18 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 19 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 20 * PERFORMANCE OF THIS SOFTWARE. 21 */ 22 23#ifdef HAVE_DIX_CONFIG_H 24#include <dix-config.h> 25#endif 26 27#include <string.h> 28 29#include "fb.h" 30 31void 32fbPutImage (DrawablePtr pDrawable, 33 GCPtr pGC, 34 int depth, 35 int x, 36 int y, 37 int w, 38 int h, 39 int leftPad, 40 int format, 41 char *pImage) 42{ 43 FbGCPrivPtr pPriv = fbGetGCPrivate(pGC); 44 unsigned long i; 45 FbStride srcStride; 46 FbStip *src = (FbStip *) pImage; 47 48 x += pDrawable->x; 49 y += pDrawable->y; 50 51 switch (format) 52 { 53 case XYBitmap: 54 srcStride = BitmapBytePad(w + leftPad) / sizeof (FbStip); 55 fbPutXYImage (pDrawable, 56 fbGetCompositeClip(pGC), 57 pPriv->fg, 58 pPriv->bg, 59 pPriv->pm, 60 pGC->alu, 61 TRUE, 62 x, y, w, h, 63 src, 64 srcStride, 65 leftPad); 66 break; 67 case XYPixmap: 68 srcStride = BitmapBytePad(w + leftPad) / sizeof (FbStip); 69 for (i = (unsigned long)1 << (pDrawable->depth - 1); i; i >>= 1) 70 { 71 if (i & pGC->planemask) 72 { 73 fbPutXYImage (pDrawable, 74 fbGetCompositeClip(pGC), 75 FB_ALLONES, 76 0, 77 fbReplicatePixel (i, pDrawable->bitsPerPixel), 78 pGC->alu, 79 TRUE, 80 x, y, w, h, 81 src, 82 srcStride, 83 leftPad); 84 src += srcStride * h; 85 } 86 } 87 break; 88 case ZPixmap: 89#ifdef FB_24_32BIT 90 if (pDrawable->bitsPerPixel != BitsPerPixel(pDrawable->depth)) 91 { 92 srcStride = PixmapBytePad(w, pDrawable->depth); 93 fb24_32PutZImage (pDrawable, 94 fbGetCompositeClip(pGC), 95 pGC->alu, 96 (FbBits) pGC->planemask, 97 x, y, w, h, 98 (CARD8 *) pImage, 99 srcStride); 100 } 101 else 102#endif 103 { 104 srcStride = PixmapBytePad(w, pDrawable->depth) / sizeof (FbStip); 105 fbPutZImage (pDrawable, 106 fbGetCompositeClip(pGC), 107 pGC->alu, 108 pPriv->pm, 109 x, y, w, h, 110 src, srcStride); 111 } 112 } 113} 114 115void 116fbPutZImage (DrawablePtr pDrawable, 117 RegionPtr pClip, 118 int alu, 119 FbBits pm, 120 int x, 121 int y, 122 int width, 123 int height, 124 FbStip *src, 125 FbStride srcStride) 126{ 127 FbStip *dst; 128 FbStride dstStride; 129 int dstBpp; 130 int dstXoff, dstYoff; 131 int nbox; 132 BoxPtr pbox; 133 int x1, y1, x2, y2; 134 135 fbGetStipDrawable (pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff); 136 137 for (nbox = RegionNumRects (pClip), 138 pbox = RegionRects(pClip); 139 nbox--; 140 pbox++) 141 { 142 x1 = x; 143 y1 = y; 144 x2 = x + width; 145 y2 = y + height; 146 if (x1 < pbox->x1) 147 x1 = pbox->x1; 148 if (y1 < pbox->y1) 149 y1 = pbox->y1; 150 if (x2 > pbox->x2) 151 x2 = pbox->x2; 152 if (y2 > pbox->y2) 153 y2 = pbox->y2; 154 if (x1 >= x2 || y1 >= y2) 155 continue; 156 fbBltStip (src + (y1 - y) * srcStride, 157 srcStride, 158 (x1 - x) * dstBpp, 159 160 dst + (y1 + dstYoff) * dstStride, 161 dstStride, 162 (x1 + dstXoff) * dstBpp, 163 164 (x2 - x1) * dstBpp, 165 (y2 - y1), 166 167 alu, 168 pm, 169 dstBpp); 170 } 171 172 fbFinishAccess (pDrawable); 173} 174 175void 176fbPutXYImage (DrawablePtr pDrawable, 177 RegionPtr pClip, 178 FbBits fg, 179 FbBits bg, 180 FbBits pm, 181 int alu, 182 Bool opaque, 183 184 int x, 185 int y, 186 int width, 187 int height, 188 189 FbStip *src, 190 FbStride srcStride, 191 int srcX) 192{ 193 FbBits *dst; 194 FbStride dstStride; 195 int dstBpp; 196 int dstXoff, dstYoff; 197 int nbox; 198 BoxPtr pbox; 199 int x1, y1, x2, y2; 200 FbBits fgand = 0, fgxor = 0, bgand = 0, bgxor = 0; 201 202 fbGetDrawable (pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff); 203 204 if (dstBpp == 1) 205 { 206 if (opaque) 207 alu = FbOpaqueStipple1Rop(alu,fg,bg); 208 else 209 alu = FbStipple1Rop(alu,fg); 210 } 211 else 212 { 213 fgand = fbAnd(alu,fg,pm); 214 fgxor = fbXor(alu,fg,pm); 215 if (opaque) 216 { 217 bgand = fbAnd(alu,bg,pm); 218 bgxor = fbXor(alu,bg,pm); 219 } 220 else 221 { 222 bgand = fbAnd(GXnoop,(FbBits)0,FB_ALLONES); 223 bgxor = fbXor(GXnoop,(FbBits)0,FB_ALLONES); 224 } 225 } 226 227 for (nbox = RegionNumRects (pClip), 228 pbox = RegionRects(pClip); 229 nbox--; 230 pbox++) 231 { 232 x1 = x; 233 y1 = y; 234 x2 = x + width; 235 y2 = y + height; 236 if (x1 < pbox->x1) 237 x1 = pbox->x1; 238 if (y1 < pbox->y1) 239 y1 = pbox->y1; 240 if (x2 > pbox->x2) 241 x2 = pbox->x2; 242 if (y2 > pbox->y2) 243 y2 = pbox->y2; 244 if (x1 >= x2 || y1 >= y2) 245 continue; 246 if (dstBpp == 1) 247 { 248 fbBltStip (src + (y1 - y) * srcStride, 249 srcStride, 250 (x1 - x) + srcX, 251 252 (FbStip *) (dst + (y1 + dstYoff) * dstStride), 253 FbBitsStrideToStipStride(dstStride), 254 (x1 + dstXoff) * dstBpp, 255 256 (x2 - x1) * dstBpp, 257 (y2 - y1), 258 259 alu, 260 pm, 261 dstBpp); 262 } 263 else 264 { 265 fbBltOne (src + (y1 - y) * srcStride, 266 srcStride, 267 (x1 - x) + srcX, 268 269 dst + (y1 + dstYoff) * dstStride, 270 dstStride, 271 (x1 + dstXoff) * dstBpp, 272 dstBpp, 273 274 (x2 - x1) * dstBpp, 275 (y2 - y1), 276 277 fgand, fgxor, bgand, bgxor); 278 } 279 } 280 281 fbFinishAccess (pDrawable); 282} 283 284void 285fbGetImage (DrawablePtr pDrawable, 286 int x, 287 int y, 288 int w, 289 int h, 290 unsigned int format, 291 unsigned long planeMask, 292 char *d) 293{ 294 FbBits *src; 295 FbStride srcStride; 296 int srcBpp; 297 int srcXoff, srcYoff; 298 FbStip *dst; 299 FbStride dstStride; 300 301 /* 302 * XFree86 DDX empties the root borderClip when the VT is 303 * switched away; this checks for that case 304 */ 305 if (!fbDrawableEnabled(pDrawable)) 306 return; 307 308#ifdef FB_24_32BIT 309 if (format == ZPixmap && 310 pDrawable->bitsPerPixel != BitsPerPixel (pDrawable->depth)) 311 { 312 fb24_32GetImage (pDrawable, x, y, w, h, format, planeMask, d); 313 return; 314 } 315#endif 316 317 fbGetDrawable (pDrawable, src, srcStride, srcBpp, srcXoff, srcYoff); 318 319 x += pDrawable->x; 320 y += pDrawable->y; 321 322 dst = (FbStip *) d; 323 if (format == ZPixmap || srcBpp == 1) 324 { 325 FbBits pm; 326 327 pm = fbReplicatePixel (planeMask, srcBpp); 328 dstStride = PixmapBytePad(w, pDrawable->depth); 329 if (pm != FB_ALLONES) 330 memset (d, 0, dstStride * h); 331 dstStride /= sizeof (FbStip); 332 fbBltStip ((FbStip *) (src + (y + srcYoff) * srcStride), 333 FbBitsStrideToStipStride(srcStride), 334 (x + srcXoff) * srcBpp, 335 336 dst, 337 dstStride, 338 0, 339 340 w * srcBpp, h, 341 342 GXcopy, 343 pm, 344 srcBpp); 345 } 346 else 347 { 348 dstStride = BitmapBytePad(w) / sizeof (FbStip); 349 fbBltPlane (src + (y + srcYoff) * srcStride, 350 srcStride, 351 (x + srcXoff) * srcBpp, 352 srcBpp, 353 354 dst, 355 dstStride, 356 0, 357 358 w * srcBpp, h, 359 360 fbAndStip(GXcopy,FB_STIP_ALLONES,FB_STIP_ALLONES), 361 fbXorStip(GXcopy,FB_STIP_ALLONES,FB_STIP_ALLONES), 362 fbAndStip(GXcopy,0,FB_STIP_ALLONES), 363 fbXorStip(GXcopy,0,FB_STIP_ALLONES), 364 planeMask); 365 } 366 367 fbFinishAccess (pDrawable); 368} 369