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 <stdlib.h> 28 29#include "fb.h" 30 31/* Compatibility wrapper, to be removed at next ABI change. */ 32void 33fbCopyRegion (DrawablePtr pSrcDrawable, 34 DrawablePtr pDstDrawable, 35 GCPtr pGC, 36 RegionPtr pDstRegion, 37 int dx, 38 int dy, 39 fbCopyProc copyProc, 40 Pixel bitPlane, 41 void *closure) 42{ 43 miCopyRegion(pSrcDrawable, pDstDrawable, pGC, pDstRegion, dx, dy, copyProc, bitPlane, closure); 44} 45 46/* Compatibility wrapper, to be removed at next ABI change. */ 47RegionPtr 48fbDoCopy (DrawablePtr pSrcDrawable, 49 DrawablePtr pDstDrawable, 50 GCPtr pGC, 51 int xIn, 52 int yIn, 53 int widthSrc, 54 int heightSrc, 55 int xOut, 56 int yOut, 57 fbCopyProc copyProc, 58 Pixel bitPlane, 59 void *closure) 60{ 61 return miDoCopy(pSrcDrawable, pDstDrawable, pGC, xIn, yIn, widthSrc, heightSrc, xOut, yOut, copyProc, bitPlane, closure); 62} 63 64void 65fbCopyNtoN (DrawablePtr pSrcDrawable, 66 DrawablePtr pDstDrawable, 67 GCPtr pGC, 68 BoxPtr pbox, 69 int nbox, 70 int dx, 71 int dy, 72 Bool reverse, 73 Bool upsidedown, 74 Pixel bitplane, 75 void *closure) 76{ 77 CARD8 alu = pGC ? pGC->alu : GXcopy; 78 FbBits pm = pGC ? fbGetGCPrivate(pGC)->pm : FB_ALLONES; 79 FbBits *src; 80 FbStride srcStride; 81 int srcBpp; 82 int srcXoff, srcYoff; 83 FbBits *dst; 84 FbStride dstStride; 85 int dstBpp; 86 int dstXoff, dstYoff; 87 88 fbGetDrawable (pSrcDrawable, src, srcStride, srcBpp, srcXoff, srcYoff); 89 fbGetDrawable (pDstDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff); 90 91 while (nbox--) 92 { 93#ifndef FB_ACCESS_WRAPPER /* pixman_blt() doesn't support accessors yet */ 94 if (pm == FB_ALLONES && alu == GXcopy && !reverse && 95 !upsidedown) 96 { 97 if (!pixman_blt ((uint32_t *)src, (uint32_t *)dst, srcStride, dstStride, srcBpp, dstBpp, 98 (pbox->x1 + dx + srcXoff), 99 (pbox->y1 + dy + srcYoff), 100 (pbox->x1 + dstXoff), 101 (pbox->y1 + dstYoff), 102 (pbox->x2 - pbox->x1), 103 (pbox->y2 - pbox->y1))) 104 goto fallback; 105 else 106 goto next; 107 } 108 fallback: 109#endif 110 fbBlt (src + (pbox->y1 + dy + srcYoff) * srcStride, 111 srcStride, 112 (pbox->x1 + dx + srcXoff) * srcBpp, 113 114 dst + (pbox->y1 + dstYoff) * dstStride, 115 dstStride, 116 (pbox->x1 + dstXoff) * dstBpp, 117 118 (pbox->x2 - pbox->x1) * dstBpp, 119 (pbox->y2 - pbox->y1), 120 121 alu, 122 pm, 123 dstBpp, 124 125 reverse, 126 upsidedown); 127#ifndef FB_ACCESS_WRAPPER 128 next: 129#endif 130 pbox++; 131 } 132 fbFinishAccess (pDstDrawable); 133 fbFinishAccess (pSrcDrawable); 134} 135 136void 137fbCopy1toN (DrawablePtr pSrcDrawable, 138 DrawablePtr pDstDrawable, 139 GCPtr pGC, 140 BoxPtr pbox, 141 int nbox, 142 int dx, 143 int dy, 144 Bool reverse, 145 Bool upsidedown, 146 Pixel bitplane, 147 void *closure) 148{ 149 FbGCPrivPtr pPriv = fbGetGCPrivate(pGC); 150 FbBits *src; 151 FbStride srcStride; 152 int srcBpp; 153 int srcXoff, srcYoff; 154 FbBits *dst; 155 FbStride dstStride; 156 int dstBpp; 157 int dstXoff, dstYoff; 158 159 fbGetDrawable (pSrcDrawable, src, srcStride, srcBpp, srcXoff, srcYoff); 160 fbGetDrawable (pDstDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff); 161 162 while (nbox--) 163 { 164 if (dstBpp == 1) 165 { 166 fbBlt (src + (pbox->y1 + dy + srcYoff) * srcStride, 167 srcStride, 168 (pbox->x1 + dx + srcXoff) * srcBpp, 169 170 dst + (pbox->y1 + dstYoff) * dstStride, 171 dstStride, 172 (pbox->x1 + dstXoff) * dstBpp, 173 174 (pbox->x2 - pbox->x1) * dstBpp, 175 (pbox->y2 - pbox->y1), 176 177 FbOpaqueStipple1Rop(pGC->alu, 178 pGC->fgPixel,pGC->bgPixel), 179 pPriv->pm, 180 dstBpp, 181 182 reverse, 183 upsidedown); 184 } 185 else 186 { 187 fbBltOne ((FbStip *) (src + (pbox->y1 + dy + srcYoff) * srcStride), 188 srcStride*(FB_UNIT/FB_STIP_UNIT), 189 (pbox->x1 + dx + srcXoff), 190 191 dst + (pbox->y1 + dstYoff) * dstStride, 192 dstStride, 193 (pbox->x1 + dstXoff) * dstBpp, 194 dstBpp, 195 196 (pbox->x2 - pbox->x1) * dstBpp, 197 (pbox->y2 - pbox->y1), 198 199 pPriv->and, pPriv->xor, 200 pPriv->bgand, pPriv->bgxor); 201 } 202 pbox++; 203 } 204 205 fbFinishAccess (pDstDrawable); 206 fbFinishAccess (pSrcDrawable); 207} 208 209void 210fbCopyNto1 (DrawablePtr pSrcDrawable, 211 DrawablePtr pDstDrawable, 212 GCPtr pGC, 213 BoxPtr pbox, 214 int nbox, 215 int dx, 216 int dy, 217 Bool reverse, 218 Bool upsidedown, 219 Pixel bitplane, 220 void *closure) 221{ 222 FbGCPrivPtr pPriv = fbGetGCPrivate (pGC); 223 224 while (nbox--) 225 { 226 if (pDstDrawable->bitsPerPixel == 1) 227 { 228 FbBits *src; 229 FbStride srcStride; 230 int srcBpp; 231 int srcXoff, srcYoff; 232 233 FbStip *dst; 234 FbStride dstStride; 235 int dstBpp; 236 int dstXoff, dstYoff; 237 238 fbGetDrawable (pSrcDrawable, src, srcStride, srcBpp, srcXoff, srcYoff); 239 fbGetStipDrawable (pDstDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff); 240 fbBltPlane (src + (pbox->y1+ dy + srcYoff) * srcStride, 241 srcStride, 242 (pbox->x1 + dx + srcXoff) * srcBpp, 243 srcBpp, 244 245 dst + (pbox->y1 + dstYoff) * dstStride, 246 dstStride, 247 (pbox->x1 + dstXoff) * dstBpp, 248 249 (pbox->x2 - pbox->x1) * srcBpp, 250 (pbox->y2 - pbox->y1), 251 252 (FbStip) pPriv->and, (FbStip) pPriv->xor, 253 (FbStip) pPriv->bgand, (FbStip) pPriv->bgxor, 254 bitplane); 255 fbFinishAccess (pDstDrawable); 256 fbFinishAccess (pSrcDrawable); 257 } 258 else 259 { 260 FbBits *src; 261 FbStride srcStride; 262 int srcBpp; 263 int srcXoff, srcYoff; 264 265 FbBits *dst; 266 FbStride dstStride; 267 int dstBpp; 268 int dstXoff, dstYoff; 269 270 FbStip *tmp; 271 FbStride tmpStride; 272 int width, height; 273 274 width = pbox->x2 - pbox->x1; 275 height = pbox->y2 - pbox->y1; 276 277 tmpStride = ((width + FB_STIP_MASK) >> FB_STIP_SHIFT); 278 tmp = malloc(tmpStride * height * sizeof (FbStip)); 279 if (!tmp) 280 return; 281 282 fbGetDrawable (pSrcDrawable, src, srcStride, srcBpp, srcXoff, srcYoff); 283 fbGetDrawable (pDstDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff); 284 285 fbBltPlane (src + (pbox->y1+ dy + srcYoff) * srcStride, 286 srcStride, 287 (pbox->x1 + dx + srcXoff) * srcBpp, 288 srcBpp, 289 290 tmp, 291 tmpStride, 292 0, 293 294 width * srcBpp, 295 height, 296 297 fbAndStip(GXcopy,FB_ALLONES,FB_ALLONES), 298 fbXorStip(GXcopy,FB_ALLONES,FB_ALLONES), 299 fbAndStip(GXcopy,0,FB_ALLONES), 300 fbXorStip(GXcopy,0,FB_ALLONES), 301 bitplane); 302 fbBltOne (tmp, 303 tmpStride, 304 0, 305 306 dst + (pbox->y1 + dstYoff) * dstStride, 307 dstStride, 308 (pbox->x1 + dstXoff) * dstBpp, 309 dstBpp, 310 311 width * dstBpp, 312 height, 313 314 pPriv->and, pPriv->xor, 315 pPriv->bgand, pPriv->bgxor); 316 free(tmp); 317 318 fbFinishAccess (pDstDrawable); 319 fbFinishAccess (pSrcDrawable); 320 } 321 pbox++; 322 } 323} 324 325RegionPtr 326fbCopyArea (DrawablePtr pSrcDrawable, 327 DrawablePtr pDstDrawable, 328 GCPtr pGC, 329 int xIn, 330 int yIn, 331 int widthSrc, 332 int heightSrc, 333 int xOut, 334 int yOut) 335{ 336 miCopyProc copy; 337 338#ifdef FB_24_32BIT 339 if (pSrcDrawable->bitsPerPixel != pDstDrawable->bitsPerPixel) 340 copy = fb24_32CopyMtoN; 341 else 342#endif 343 copy = fbCopyNtoN; 344 return miDoCopy (pSrcDrawable, pDstDrawable, pGC, xIn, yIn, 345 widthSrc, heightSrc, xOut, yOut, copy, 0, 0); 346} 347 348RegionPtr 349fbCopyPlane (DrawablePtr pSrcDrawable, 350 DrawablePtr pDstDrawable, 351 GCPtr pGC, 352 int xIn, 353 int yIn, 354 int widthSrc, 355 int heightSrc, 356 int xOut, 357 int yOut, 358 unsigned long bitplane) 359{ 360 if (pSrcDrawable->bitsPerPixel > 1) 361 return miDoCopy (pSrcDrawable, pDstDrawable, pGC, 362 xIn, yIn, widthSrc, heightSrc, 363 xOut, yOut, fbCopyNto1, (Pixel) bitplane, 0); 364 else if (bitplane & 1) 365 return miDoCopy (pSrcDrawable, pDstDrawable, pGC, xIn, yIn, 366 widthSrc, heightSrc, xOut, yOut, fbCopy1toN, 367 (Pixel) bitplane, 0); 368 else 369 return miHandleExposures(pSrcDrawable, pDstDrawable, pGC, 370 xIn, yIn, 371 widthSrc, 372 heightSrc, 373 xOut, yOut, bitplane); 374} 375