aboutsummaryrefslogtreecommitdiff
path: root/xorg-server/fb/fbpush.c
diff options
context:
space:
mode:
Diffstat (limited to 'xorg-server/fb/fbpush.c')
-rw-r--r--xorg-server/fb/fbpush.c245
1 files changed, 245 insertions, 0 deletions
diff --git a/xorg-server/fb/fbpush.c b/xorg-server/fb/fbpush.c
new file mode 100644
index 000000000..891572f0d
--- /dev/null
+++ b/xorg-server/fb/fbpush.c
@@ -0,0 +1,245 @@
+/*
+ * Copyright © 1998 Keith Packard
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "fb.h"
+
+void
+fbPushPattern (DrawablePtr pDrawable,
+ GCPtr pGC,
+
+ FbStip *src,
+ FbStride srcStride,
+ int srcX,
+
+ int x,
+ int y,
+
+ int width,
+ int height)
+{
+ FbStip *s, bitsMask, bitsMask0, bits;
+ int xspan;
+ int w;
+ int lenspan;
+
+ src += srcX >> FB_STIP_SHIFT;
+ srcX &= FB_STIP_MASK;
+
+ bitsMask0 = FbStipMask (srcX, 1);
+
+ while (height--)
+ {
+ bitsMask = bitsMask0;
+ w = width;
+ s = src;
+ src += srcStride;
+ bits = READ(s++);
+ xspan = x;
+ while (w)
+ {
+ if (bits & bitsMask)
+ {
+ lenspan = 0;
+ do
+ {
+ lenspan++;
+ if (lenspan == w)
+ break;
+ bitsMask = FbStipRight (bitsMask, 1);
+ if (!bitsMask)
+ {
+ bits = READ(s++);
+ bitsMask = FbBitsMask(0,1);
+ }
+ } while (bits & bitsMask);
+ fbFill (pDrawable, pGC, xspan, y, lenspan, 1);
+ xspan += lenspan;
+ w -= lenspan;
+ }
+ else
+ {
+ do
+ {
+ w--;
+ xspan++;
+ if (!w)
+ break;
+ bitsMask = FbStipRight (bitsMask, 1);
+ if (!bitsMask)
+ {
+ bits = READ(s++);
+ bitsMask = FbBitsMask(0,1);
+ }
+ } while (!(bits & bitsMask));
+ }
+ }
+ y++;
+ }
+}
+
+void
+fbPushFill (DrawablePtr pDrawable,
+ GCPtr pGC,
+
+ FbStip *src,
+ FbStride srcStride,
+ int srcX,
+
+ int x,
+ int y,
+ int width,
+ int height)
+{
+ FbGCPrivPtr pPriv = fbGetGCPrivate(pGC);
+
+ if (pGC->fillStyle == FillSolid)
+ {
+ FbBits *dst;
+ FbStride dstStride;
+ int dstBpp;
+ int dstXoff, dstYoff;
+ int dstX;
+ int dstWidth;
+
+ fbGetDrawable (pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff);
+ dst = dst + (y + dstYoff) * dstStride;
+ dstX = (x + dstXoff) * dstBpp;
+ dstWidth = width * dstBpp;
+ if (dstBpp == 1)
+ {
+ fbBltStip (src,
+ srcStride,
+ srcX,
+
+ (FbStip *) dst,
+ FbBitsStrideToStipStride (dstStride),
+ dstX,
+
+ dstWidth,
+ height,
+
+ FbStipple1Rop(pGC->alu,pGC->fgPixel),
+ pPriv->pm,
+ dstBpp);
+ }
+ else
+ {
+ fbBltOne (src,
+ srcStride,
+ srcX,
+
+ dst,
+ dstStride,
+ dstX,
+ dstBpp,
+
+ dstWidth,
+ height,
+
+ pPriv->and, pPriv->xor,
+ fbAnd(GXnoop,(FbBits) 0,FB_ALLONES),
+ fbXor(GXnoop,(FbBits) 0,FB_ALLONES));
+ }
+ fbFinishAccess (pDrawable);
+ }
+ else
+ {
+ fbPushPattern (pDrawable, pGC, src, srcStride, srcX,
+ x, y, width, height);
+ }
+}
+
+void
+fbPushImage (DrawablePtr pDrawable,
+ GCPtr pGC,
+
+ FbStip *src,
+ FbStride srcStride,
+ int srcX,
+
+ int x,
+ int y,
+ int width,
+ int height)
+{
+ RegionPtr pClip = fbGetCompositeClip (pGC);
+ int nbox;
+ BoxPtr pbox;
+ int x1, y1, x2, y2;
+
+ for (nbox = REGION_NUM_RECTS (pClip),
+ pbox = REGION_RECTS(pClip);
+ nbox--;
+ pbox++)
+ {
+ x1 = x;
+ y1 = y;
+ x2 = x + width;
+ y2 = y + height;
+ if (x1 < pbox->x1)
+ x1 = pbox->x1;
+ if (y1 < pbox->y1)
+ y1 = pbox->y1;
+ if (x2 > pbox->x2)
+ x2 = pbox->x2;
+ if (y2 > pbox->y2)
+ y2 = pbox->y2;
+ if (x1 >= x2 || y1 >= y2)
+ continue;
+ fbPushFill (pDrawable,
+ pGC,
+
+ src + (y1 - y) * srcStride,
+ srcStride,
+ srcX + (x1 - x),
+
+ x1,
+ y1,
+ x2 - x1,
+ y2 - y1);
+ }
+}
+
+void
+fbPushPixels (GCPtr pGC,
+ PixmapPtr pBitmap,
+ DrawablePtr pDrawable,
+ int dx,
+ int dy,
+ int xOrg,
+ int yOrg)
+{
+ FbStip *stip;
+ FbStride stipStride;
+ int stipBpp;
+ int stipXoff, stipYoff; /* Assumed to be zero */
+
+ fbGetStipDrawable (&pBitmap->drawable, stip, stipStride, stipBpp, stipXoff, stipYoff);
+
+ fbPushImage (pDrawable, pGC,
+ stip, stipStride, 0,
+ xOrg, yOrg, dx, dy);
+}