diff options
Diffstat (limited to 'nx-X11/programs/Xserver/fb')
40 files changed, 19469 insertions, 0 deletions
diff --git a/nx-X11/programs/Xserver/fb/Imakefile b/nx-X11/programs/Xserver/fb/Imakefile new file mode 100644 index 000000000..5daa10c6f --- /dev/null +++ b/nx-X11/programs/Xserver/fb/Imakefile @@ -0,0 +1,164 @@ +NULL = + +#include <Server.tmpl> + +#ifdef FbNoPixelAddrCode +FB_DEFINES=-DFBNOPIXADDR -DFBNO24BIT +#endif + +#if HasShm +SHM_DEFINES = ShmDefines +#endif + +#if BuildRender +RENDERSRC = fbcompose.c +RENDEROBJ = fbcompose.o +#endif + +#if defined(NXAgentServer) && NXAgentServer +NX_DEFINES = -DNXAGENT_SERVER +#endif + +#if defined(NXAgentServer) && NXAgentServer + DEFINES = $(FB_DEFINES) $(NX_DEFINES) +#else + DEFINES = $(FB_DEFINES) +#endif + +SRCS = $(XFMODSRC) \ + fballpriv.c \ + fbbits.c \ + fbblt.c \ + fbbltone.c \ + fbbstore.c \ + fbcmap.c \ + $(RENDERSRC) \ + fbcopy.c \ + fbedge.c \ + fbfill.c \ + fbfillrect.c \ + fbfillsp.c \ + fbgc.c \ + fbgetsp.c \ + fbglyph.c \ + fbimage.c \ + fbline.c \ + fboverlay.c \ + fbpixmap.c \ + fbpoint.c \ + fbpush.c \ + fbscreen.c \ + fbseg.c \ + fbsetsp.c \ + fbsolid.c \ + fbstipple.c \ + fbtile.c \ + fbtrap.c \ + fbutil.c \ + fbwindow.c \ + fb24_32.c \ + fbpict.c \ + $(NULL) + +OBJS = $(XFMODOBJ) \ + fbarc.o \ + fballpriv.o \ + fbbits.o \ + fbblt.o \ + fbbltone.o \ + fbbstore.o \ + fbcmap.o \ + $(RENDEROBJ) \ + fbcopy.o \ + fbedge.o \ + fbfill.o \ + fbfillrect.o \ + fbfillsp.o \ + fbgc.o \ + fbgetsp.o \ + fbglyph.o \ + fbimage.o \ + fbline.o \ + fboverlay.o \ + fbpixmap.o \ + fbpoint.o \ + fbpush.o \ + fbscreen.o \ + fbseg.o \ + fbsetsp.o \ + fbsolid.o \ + fbstipple.o \ + fbtile.o \ + fbtrap.o \ + fbutil.o \ + fbwindow.o \ + fb24_32.o \ + fbpict.o \ + $(NULL) + + INCLUDES = -I$(SERVERSRC)/fb -I$(SERVERSRC)/mi -I$(SERVERSRC)/include \ + -I$(XINCLUDESRC) \ + -I$(XF86SRC)/common $(EXTRAINCLUDES) \ + -I$(SERVERSRC)/render -I$(EXTINCSRC) -I$(SERVERSRC)/Xext \ + `pkg-config --cflags-only-I pixman-1` + LINTLIBS = $(SERVERSRC)/dix/llib-ldix.ln $(SERVERSRC)/os/llib-los.ln \ + $(SERVERSRC)/mi/llib-lmi.ln + +NormalLibraryObjectRule() +NormalLibraryTarget(fb,$(OBJS)) + +LintLibraryTarget(fb,$(SRCS)) + +NormalLintTarget($(SRCS)) + + +DependTarget() + +#ifdef IHaveSubdirs +MakeSubdirs($(SUBDIRS)) +DependSubdirs($(SUBDIRS)) +#endif + +SpecialCObjectRule(fboverlay,$(ICONFIGFILES),$(SHM_DEFINES)) + +#ifdef LinkDirectory +LinkSourceFile(fb24_32.c,LinkDirectory) +LinkSourceFile(fballpriv.c,LinkDirectory) +LinkSourceFile(fbarc.c,LinkDirectory) +LinkSourceFile(fbbits.c,LinkDirectory) +LinkSourceFile(fbblt.c,LinkDirectory) +LinkSourceFile(fbbltone.c,LinkDirectory) +LinkSourceFile(fbbstore.c,LinkDirectory) +LinkSourceFile(fbcmap.c,LinkDirectory) +#if BuildRender +LinkSourceFile(fbcompose.c,LinkDirectory) +#endif +LinkSourceFile(fbcopy.c,LinkDirectory) +LinkSourceFile(fbfill.c,LinkDirectory) +LinkSourceFile(fbfillrect.c,LinkDirectory) +LinkSourceFile(fbfillsp.c,LinkDirectory) +LinkSourceFile(fbgc.c,LinkDirectory) +LinkSourceFile(fbgetsp.c,LinkDirectory) +LinkSourceFile(fbglyph.c,LinkDirectory) +LinkSourceFile(fbimage.c,LinkDirectory) +LinkSourceFile(fbline.c,LinkDirectory) +LinkSourceFile(fbmodule.c,LinkDirectory) +LinkSourceFile(fboverlay.c,LinkDirectory) +LinkSourceFile(fbpict.c,LinkDirectory) +LinkSourceFile(fbpixmap.c,LinkDirectory) +LinkSourceFile(fbpoint.c,LinkDirectory) +LinkSourceFile(fbpush.c,LinkDirectory) +LinkSourceFile(fbscreen.c,LinkDirectory) +LinkSourceFile(fbseg.c,LinkDirectory) +LinkSourceFile(fbsetsp.c,LinkDirectory) +LinkSourceFile(fbsolid.c,LinkDirectory) +LinkSourceFile(fbstipple.c,LinkDirectory) +LinkSourceFile(fbtile.c,LinkDirectory) +LinkSourceFile(fbtrap.c,LinkDirectory) +LinkSourceFile(fbutil.c,LinkDirectory) +LinkSourceFile(fbwindow.c,LinkDirectory) +#endif + +InstallDriverSDKLibraryModule(fb,$(DRIVERSDKMODULEDIR),.) +InstallDriverSDKNonExecFile(fb.h,$(DRIVERSDKINCLUDEDIR)) +InstallDriverSDKNonExecFile(fbrop.h,$(DRIVERSDKINCLUDEDIR)) diff --git a/nx-X11/programs/Xserver/fb/fb.h b/nx-X11/programs/Xserver/fb/fb.h new file mode 100644 index 000000000..61bf18caf --- /dev/null +++ b/nx-X11/programs/Xserver/fb/fb.h @@ -0,0 +1,2047 @@ +/* + * 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. + */ + + +#ifndef _FB_H_ +#define _FB_H_ + +#include <nx-X11/X.h> +#include "scrnintstr.h" +#include "pixmap.h" +#include "pixmapstr.h" +#include "region.h" +#include "gcstruct.h" +#include "colormap.h" +#include "miscstruct.h" +#include "servermd.h" +#include "windowstr.h" +#include "mi.h" +#include "migc.h" +#include "mibstore.h" +#ifdef RENDER +#include "picturestr.h" +#else +#include "picture.h" +#endif + +/* + * This single define controls the basic size of data manipulated + * by this software; it must be log2(sizeof (FbBits) * 8) + */ + +#ifndef FB_SHIFT +#define FB_SHIFT LOG2_BITMAP_PAD +#endif + +#if FB_SHIFT < LOG2_BITMAP_PAD + error FB_SHIFT must be >= LOG2_BITMAP_PAD +#endif + +#define FB_UNIT (1 << FB_SHIFT) +#define FB_HALFUNIT (1 << (FB_SHIFT-1)) +#define FB_MASK (FB_UNIT - 1) +#define FB_ALLONES ((FbBits) -1) + +#if GLYPHPADBYTES != 4 +#error "GLYPHPADBYTES must be 4" +#endif +/* whether to bother to include 24bpp support */ +#ifndef FBNO24BIT +#define FB_24BIT +#endif + +/* + * Unless otherwise instructed, fb includes code to advertise 24bpp + * windows with 32bpp image format for application compatibility + */ + +#ifdef FB_24BIT +#ifndef FBNO24_32 +#define FB_24_32BIT +#endif +#endif + +#define FB_STIP_SHIFT LOG2_BITMAP_PAD +#define FB_STIP_UNIT (1 << FB_STIP_SHIFT) +#define FB_STIP_MASK (FB_STIP_UNIT - 1) +#define FB_STIP_ALLONES ((FbStip) -1) + +#define FB_STIP_ODDSTRIDE(s) (((s) & (FB_MASK >> FB_STIP_SHIFT)) != 0) +#define FB_STIP_ODDPTR(p) ((((long) (p)) & (FB_MASK >> 3)) != 0) + +#define FbStipStrideToBitsStride(s) (((s) >> (FB_SHIFT - FB_STIP_SHIFT))) +#define FbBitsStrideToStipStride(s) (((s) << (FB_SHIFT - FB_STIP_SHIFT))) + +#define FbFullMask(n) ((n) == FB_UNIT ? FB_ALLONES : ((((FbBits) 1) << n) - 1)) + +#if FB_SHIFT == 6 +# ifdef WIN32 +typedef unsigned __int64 FbBits; +# else +# if defined(__alpha__) || defined(__alpha) || \ + defined(ia64) || defined(__ia64__) || \ + defined(__sparc64__) || defined(_LP64) || \ + defined(__s390x__) || \ + defined(amd64) || defined (__amd64__) || \ + defined (__powerpc64__) +typedef unsigned long FbBits; +# else +typedef unsigned long long FbBits; +# endif +# endif +#endif + +#if FB_SHIFT == 5 +typedef CARD32 FbBits; +#endif + +#if FB_SHIFT == 4 +typedef CARD16 FbBits; +#endif + +#if LOG2_BITMAP_PAD == FB_SHIFT +typedef FbBits FbStip; +#else +# if LOG2_BITMAP_PAD == 5 +typedef CARD32 FbStip; +# endif +#endif + +typedef int FbStride; + + +#ifdef FB_DEBUG +extern void fbValidateDrawable(DrawablePtr d); +extern void fbInitializeDrawable(DrawablePtr d); +extern void fbSetBits (FbStip *bits, int stride, FbStip data); +#define FB_HEAD_BITS (FbStip) (0xbaadf00d) +#define FB_TAIL_BITS (FbStip) (0xbaddf0ad) +#else +#define fbValidateDrawable(d) +#define fdInitializeDrawable(d) +#endif + +#include "fbrop.h" + +#if BITMAP_BIT_ORDER == LSBFirst +#define FbScrLeft(x,n) ((x) >> (n)) +#define FbScrRight(x,n) ((x) << (n)) +/* #define FbLeftBits(x,n) ((x) & ((((FbBits) 1) << (n)) - 1)) */ +#define FbLeftStipBits(x,n) ((x) & ((((FbStip) 1) << (n)) - 1)) +#define FbStipMoveLsb(x,s,n) (FbStipRight (x,(s)-(n))) +#define FbPatternOffsetBits 0 +#else +#define FbScrLeft(x,n) ((x) << (n)) +#define FbScrRight(x,n) ((x) >> (n)) +/* #define FbLeftBits(x,n) ((x) >> (FB_UNIT - (n))) */ +#define FbLeftStipBits(x,n) ((x) >> (FB_STIP_UNIT - (n))) +#define FbStipMoveLsb(x,s,n) (x) +#define FbPatternOffsetBits (sizeof (FbBits) - 1) +#endif + +#include "micoord.h" + +#define FbStipLeft(x,n) FbScrLeft(x,n) +#define FbStipRight(x,n) FbScrRight(x,n) + +#define FbRotLeft(x,n) FbScrLeft(x,n) | (n ? FbScrRight(x,FB_UNIT-n) : 0) +#define FbRotRight(x,n) FbScrRight(x,n) | (n ? FbScrLeft(x,FB_UNIT-n) : 0) + +#define FbRotStipLeft(x,n) FbStipLeft(x,n) | (n ? FbStipRight(x,FB_STIP_UNIT-n) : 0) +#define FbRotStipRight(x,n) FbStipRight(x,n) | (n ? FbStipLeft(x,FB_STIP_UNIT-n) : 0) + +#define FbLeftMask(x) ( ((x) & FB_MASK) ? \ + FbScrRight(FB_ALLONES,(x) & FB_MASK) : 0) +#define FbRightMask(x) ( ((FB_UNIT - (x)) & FB_MASK) ? \ + FbScrLeft(FB_ALLONES,(FB_UNIT - (x)) & FB_MASK) : 0) + +#define FbLeftStipMask(x) ( ((x) & FB_STIP_MASK) ? \ + FbStipRight(FB_STIP_ALLONES,(x) & FB_STIP_MASK) : 0) +#define FbRightStipMask(x) ( ((FB_STIP_UNIT - (x)) & FB_STIP_MASK) ? \ + FbScrLeft(FB_STIP_ALLONES,(FB_STIP_UNIT - (x)) & FB_STIP_MASK) : 0) + +#define FbBitsMask(x,w) (FbScrRight(FB_ALLONES,(x) & FB_MASK) & \ + FbScrLeft(FB_ALLONES,(FB_UNIT - ((x) + (w))) & FB_MASK)) + +#define FbStipMask(x,w) (FbStipRight(FB_STIP_ALLONES,(x) & FB_STIP_MASK) & \ + FbStipLeft(FB_STIP_ALLONES,(FB_STIP_UNIT - ((x)+(w))) & FB_STIP_MASK)) + + +#define FbMaskBits(x,w,l,n,r) { \ + n = (w); \ + r = FbRightMask((x)+n); \ + l = FbLeftMask(x); \ + if (l) { \ + n -= FB_UNIT - ((x) & FB_MASK); \ + if (n < 0) { \ + n = 0; \ + l &= r; \ + r = 0; \ + } \ + } \ + n >>= FB_SHIFT; \ +} + +#ifdef FBNOPIXADDR +#define FbMaskBitsBytes(x,w,copy,l,lb,n,r,rb) FbMaskBits(x,w,l,n,r) +#define FbDoLeftMaskByteRRop(dst,lb,l,and,xor) { \ + *dst = FbDoMaskRRop(*dst,and,xor,l); \ +} +#define FbDoRightMaskByteRRop(dst,rb,r,and,xor) { \ + *dst = FbDoMaskRRop(*dst,and,xor,r); \ +} +#else + +#define FbByteMaskInvalid 0x10 + +#define FbPatternOffset(o,t) ((o) ^ (FbPatternOffsetBits & ~(sizeof (t) - 1))) + +#define FbPtrOffset(p,o,t) ((t *) ((CARD8 *) (p) + (o))) +#define FbSelectPatternPart(xor,o,t) ((xor) >> (FbPatternOffset (o,t) << 3)) +#define FbStorePart(dst,off,t,xor) (*FbPtrOffset(dst,off,t) = \ + FbSelectPart(xor,off,t)) +#ifndef FbSelectPart +#define FbSelectPart(x,o,t) FbSelectPatternPart(x,o,t) +#endif + +#define FbMaskBitsBytes(x,w,copy,l,lb,n,r,rb) { \ + n = (w); \ + lb = 0; \ + rb = 0; \ + r = FbRightMask((x)+n); \ + if (r) { \ + /* compute right byte length */ \ + if ((copy) && (((x) + n) & 7) == 0) { \ + rb = (((x) + n) & FB_MASK) >> 3; \ + } else { \ + rb = FbByteMaskInvalid; \ + } \ + } \ + l = FbLeftMask(x); \ + if (l) { \ + /* compute left byte length */ \ + if ((copy) && ((x) & 7) == 0) { \ + lb = ((x) & FB_MASK) >> 3; \ + } else { \ + lb = FbByteMaskInvalid; \ + } \ + /* subtract out the portion painted by leftMask */ \ + n -= FB_UNIT - ((x) & FB_MASK); \ + if (n < 0) { \ + if (lb != FbByteMaskInvalid) { \ + if (rb == FbByteMaskInvalid) { \ + lb = FbByteMaskInvalid; \ + } else if (rb) { \ + lb |= (rb - lb) << (FB_SHIFT - 3); \ + rb = 0; \ + } \ + } \ + n = 0; \ + l &= r; \ + r = 0; \ + }\ + } \ + n >>= FB_SHIFT; \ +} + +#if FB_SHIFT == 6 +#define FbDoLeftMaskByteRRop6Cases(dst,xor) \ + case (sizeof (FbBits) - 7) | (1 << (FB_SHIFT - 3)): \ + FbStorePart(dst,sizeof (FbBits) - 7,CARD8,xor); \ + break; \ + case (sizeof (FbBits) - 7) | (2 << (FB_SHIFT - 3)): \ + FbStorePart(dst,sizeof (FbBits) - 7,CARD8,xor); \ + FbStorePart(dst,sizeof (FbBits) - 6,CARD8,xor); \ + break; \ + case (sizeof (FbBits) - 7) | (3 << (FB_SHIFT - 3)): \ + FbStorePart(dst,sizeof (FbBits) - 7,CARD8,xor); \ + FbStorePart(dst,sizeof (FbBits) - 6,CARD16,xor); \ + break; \ + case (sizeof (FbBits) - 7) | (4 << (FB_SHIFT - 3)): \ + FbStorePart(dst,sizeof (FbBits) - 7,CARD8,xor); \ + FbStorePart(dst,sizeof (FbBits) - 6,CARD16,xor); \ + FbStorePart(dst,sizeof (FbBits) - 4,CARD8,xor); \ + break; \ + case (sizeof (FbBits) - 7) | (5 << (FB_SHIFT - 3)): \ + FbStorePart(dst,sizeof (FbBits) - 7,CARD8,xor); \ + FbStorePart(dst,sizeof (FbBits) - 6,CARD16,xor); \ + FbStorePart(dst,sizeof (FbBits) - 4,CARD16,xor); \ + break; \ + case (sizeof (FbBits) - 7) | (6 << (FB_SHIFT - 3)): \ + FbStorePart(dst,sizeof (FbBits) - 7,CARD8,xor); \ + FbStorePart(dst,sizeof (FbBits) - 6,CARD16,xor); \ + FbStorePart(dst,sizeof (FbBits) - 4,CARD16,xor); \ + FbStorePart(dst,sizeof (FbBits) - 2,CARD8,xor); \ + break; \ + case (sizeof (FbBits) - 7): \ + FbStorePart(dst,sizeof (FbBits) - 7,CARD8,xor); \ + FbStorePart(dst,sizeof (FbBits) - 6,CARD16,xor); \ + FbStorePart(dst,sizeof (FbBits) - 4,CARD32,xor); \ + break; \ + case (sizeof (FbBits) - 6) | (1 << (FB_SHIFT - 3)): \ + FbStorePart(dst,sizeof (FbBits) - 6,CARD8,xor); \ + break; \ + case (sizeof (FbBits) - 6) | (2 << (FB_SHIFT - 3)): \ + FbStorePart(dst,sizeof (FbBits) - 6,CARD16,xor); \ + break; \ + case (sizeof (FbBits) - 6) | (3 << (FB_SHIFT - 3)): \ + FbStorePart(dst,sizeof (FbBits) - 6,CARD16,xor); \ + FbStorePart(dst,sizeof (FbBits) - 4,CARD8,xor); \ + break; \ + case (sizeof (FbBits) - 6) | (4 << (FB_SHIFT - 3)): \ + FbStorePart(dst,sizeof (FbBits) - 6,CARD16,xor); \ + FbStorePart(dst,sizeof (FbBits) - 4,CARD16,xor); \ + break; \ + case (sizeof (FbBits) - 6) | (5 << (FB_SHIFT - 3)): \ + FbStorePart(dst,sizeof (FbBits) - 6,CARD16,xor); \ + FbStorePart(dst,sizeof (FbBits) - 4,CARD16,xor); \ + FbStorePart(dst,sizeof (FbBits) - 2,CARD8,xor); \ + break; \ + case (sizeof (FbBits) - 6): \ + FbStorePart(dst,sizeof (FbBits) - 6,CARD16,xor); \ + FbStorePart(dst,sizeof (FbBits) - 4,CARD32,xor); \ + break; \ + case (sizeof (FbBits) - 5) | (1 << (FB_SHIFT - 3)): \ + FbStorePart(dst,sizeof (FbBits) - 5,CARD8,xor); \ + break; \ + case (sizeof (FbBits) - 5) | (2 << (FB_SHIFT - 3)): \ + FbStorePart(dst,sizeof (FbBits) - 5,CARD8,xor); \ + FbStorePart(dst,sizeof (FbBits) - 4,CARD8,xor); \ + break; \ + case (sizeof (FbBits) - 5) | (3 << (FB_SHIFT - 3)): \ + FbStorePart(dst,sizeof (FbBits) - 5,CARD8,xor); \ + FbStorePart(dst,sizeof (FbBits) - 4,CARD16,xor); \ + break; \ + case (sizeof (FbBits) - 5) | (4 << (FB_SHIFT - 3)): \ + FbStorePart(dst,sizeof (FbBits) - 5,CARD8,xor); \ + FbStorePart(dst,sizeof (FbBits) - 4,CARD16,xor); \ + FbStorePart(dst,sizeof (FbBits) - 2,CARD8,xor); \ + break; \ + case (sizeof (FbBits) - 5): \ + FbStorePart(dst,sizeof (FbBits) - 5,CARD8,xor); \ + FbStorePart(dst,sizeof (FbBits) - 4,CARD32,xor); \ + break; \ + case (sizeof (FbBits) - 4) | (1 << (FB_SHIFT - 3)): \ + FbStorePart(dst,sizeof (FbBits) - 4,CARD8,xor); \ + break; \ + case (sizeof (FbBits) - 4) | (2 << (FB_SHIFT - 3)): \ + FbStorePart(dst,sizeof (FbBits) - 4,CARD16,xor); \ + break; \ + case (sizeof (FbBits) - 4) | (3 << (FB_SHIFT - 3)): \ + FbStorePart(dst,sizeof (FbBits) - 4,CARD16,xor); \ + FbStorePart(dst,sizeof (FbBits) - 2,CARD8,xor); \ + break; \ + case (sizeof (FbBits) - 4): \ + FbStorePart(dst,sizeof (FbBits) - 4,CARD32,xor); \ + break; + +#define FbDoRightMaskByteRRop6Cases(dst,xor) \ + case 4: \ + FbStorePart(dst,0,CARD32,xor); \ + break; \ + case 5: \ + FbStorePart(dst,0,CARD32,xor); \ + FbStorePart(dst,4,CARD8,xor); \ + break; \ + case 6: \ + FbStorePart(dst,0,CARD32,xor); \ + FbStorePart(dst,4,CARD16,xor); \ + break; \ + case 7: \ + FbStorePart(dst,0,CARD32,xor); \ + FbStorePart(dst,4,CARD16,xor); \ + FbStorePart(dst,6,CARD8,xor); \ + break; +#else +#define FbDoLeftMaskByteRRop6Cases(dst,xor) +#define FbDoRightMaskByteRRop6Cases(dst,xor) +#endif + +#define FbDoLeftMaskByteRRop(dst,lb,l,and,xor) { \ + switch (lb) { \ + FbDoLeftMaskByteRRop6Cases(dst,xor) \ + case (sizeof (FbBits) - 3) | (1 << (FB_SHIFT - 3)): \ + FbStorePart(dst,sizeof (FbBits) - 3,CARD8,xor); \ + break; \ + case (sizeof (FbBits) - 3) | (2 << (FB_SHIFT - 3)): \ + FbStorePart(dst,sizeof (FbBits) - 3,CARD8,xor); \ + FbStorePart(dst,sizeof (FbBits) - 2,CARD8,xor); \ + break; \ + case (sizeof (FbBits) - 2) | (1 << (FB_SHIFT - 3)): \ + FbStorePart(dst,sizeof (FbBits) - 2,CARD8,xor); \ + break; \ + case sizeof (FbBits) - 3: \ + FbStorePart(dst,sizeof (FbBits) - 3,CARD8,xor); \ + case sizeof (FbBits) - 2: \ + FbStorePart(dst,sizeof (FbBits) - 2,CARD16,xor); \ + break; \ + case sizeof (FbBits) - 1: \ + FbStorePart(dst,sizeof (FbBits) - 1,CARD8,xor); \ + break; \ + default: \ + *dst = FbDoMaskRRop(*dst, and, xor, l); \ + break; \ + } \ +} + + +#define FbDoRightMaskByteRRop(dst,rb,r,and,xor) { \ + switch (rb) { \ + case 1: \ + FbStorePart(dst,0,CARD8,xor); \ + break; \ + case 2: \ + FbStorePart(dst,0,CARD16,xor); \ + break; \ + case 3: \ + FbStorePart(dst,0,CARD16,xor); \ + FbStorePart(dst,2,CARD8,xor); \ + break; \ + FbDoRightMaskByteRRop6Cases(dst,xor) \ + default: \ + *dst = FbDoMaskRRop (*dst, and, xor, r); \ + } \ +} +#endif + +#define FbMaskStip(x,w,l,n,r) { \ + n = (w); \ + r = FbRightStipMask((x)+n); \ + l = FbLeftStipMask(x); \ + if (l) { \ + n -= FB_STIP_UNIT - ((x) & FB_STIP_MASK); \ + if (n < 0) { \ + n = 0; \ + l &= r; \ + r = 0; \ + } \ + } \ + n >>= FB_STIP_SHIFT; \ +} + +/* + * These macros are used to transparently stipple + * in copy mode; the expected usage is with 'n' constant + * so all of the conditional parts collapse into a minimal + * sequence of partial word writes + * + * 'n' is the bytemask of which bytes to store, 'a' is the address + * of the FbBits base unit, 'o' is the offset within that unit + * + * The term "lane" comes from the hardware term "byte-lane" which + */ + +#define FbLaneCase1(n,a,o) ((n) == 0x01 ? \ + (*(CARD8 *) ((a)+FbPatternOffset(o,CARD8)) = \ + fgxor) : 0) +#define FbLaneCase2(n,a,o) ((n) == 0x03 ? \ + (*(CARD16 *) ((a)+FbPatternOffset(o,CARD16)) = \ + fgxor) : \ + ((void)FbLaneCase1((n)&1,a,o), \ + FbLaneCase1((n)>>1,a,(o)+1))) +#define FbLaneCase4(n,a,o) ((n) == 0x0f ? \ + (*(CARD32 *) ((a)+FbPatternOffset(o,CARD32)) = \ + fgxor) : \ + ((void)FbLaneCase2((n)&3,a,o), \ + FbLaneCase2((n)>>2,a,(o)+2))) +#define FbLaneCase8(n,a,o) ((n) == 0x0ff ? (*(FbBits *) ((a)+(o)) = fgxor) : \ + ((void)FbLaneCase4((n)&15,a,o), \ + FbLaneCase4((n)>>4,a,(o)+4))) + +#if FB_SHIFT == 6 +#define FbLaneCase(n,a) FbLaneCase8(n,(CARD8 *) (a),0) +#endif + +#if FB_SHIFT == 5 +#define FbLaneCase(n,a) FbLaneCase4(n,(CARD8 *) (a),0) +#endif + +/* Rotate a filled pixel value to the specified alignement */ +#define FbRot24(p,b) (FbScrRight(p,b) | FbScrLeft(p,24-(b))) +#define FbRot24Stip(p,b) (FbStipRight(p,b) | FbStipLeft(p,24-(b))) + +/* step a filled pixel value to the next/previous FB_UNIT alignment */ +#define FbNext24Pix(p) (FbRot24(p,(24-FB_UNIT%24))) +#define FbPrev24Pix(p) (FbRot24(p,FB_UNIT%24)) +#define FbNext24Stip(p) (FbRot24(p,(24-FB_STIP_UNIT%24))) +#define FbPrev24Stip(p) (FbRot24(p,FB_STIP_UNIT%24)) + +/* step a rotation value to the next/previous rotation value */ +#if FB_UNIT == 64 +#define FbNext24Rot(r) ((r) == 16 ? 0 : (r) + 8) +#define FbPrev24Rot(r) ((r) == 0 ? 16 : (r) - 8) + +#if IMAGE_BYTE_ORDER == MSBFirst +#define FbFirst24Rot(x) (((x) + 8) % 24) +#else +#define FbFirst24Rot(x) ((x) % 24) +#endif + +#endif + +#if FB_UNIT == 32 +#define FbNext24Rot(r) ((r) == 0 ? 16 : (r) - 8) +#define FbPrev24Rot(r) ((r) == 16 ? 0 : (r) + 8) + +#if IMAGE_BYTE_ORDER == MSBFirst +#define FbFirst24Rot(x) (((x) + 16) % 24) +#else +#define FbFirst24Rot(x) ((x) % 24) +#endif +#endif + +#define FbNext24RotStip(r) ((r) == 0 ? 16 : (r) - 8) +#define FbPrev24RotStip(r) ((r) == 16 ? 0 : (r) + 8) + +/* Whether 24-bit specific code is needed for this filled pixel value */ +#define FbCheck24Pix(p) ((p) == FbNext24Pix(p)) + +/* Macros for dealing with dashing */ + +#define FbDashDeclare \ + unsigned char *__dash, *__firstDash, *__lastDash + +#define FbDashInit(pGC,pPriv,dashOffset,dashlen,even) { \ + (even) = TRUE; \ + __firstDash = (pGC)->dash; \ + __lastDash = __firstDash + (pGC)->numInDashList; \ + (dashOffset) %= (pPriv)->dashLength; \ + \ + __dash = __firstDash; \ + while ((dashOffset) >= ((dashlen) = *__dash)) \ + { \ + (dashOffset) -= (dashlen); \ + (even) = 1-(even); \ + if (++__dash == __lastDash) \ + __dash = __firstDash; \ + } \ + (dashlen) -= (dashOffset); \ +} + +#define FbDashNext(dashlen) { \ + if (++__dash == __lastDash) \ + __dash = __firstDash; \ + (dashlen) = *__dash; \ +} + +/* as numInDashList is always even, this case can skip a test */ + +#define FbDashNextEven(dashlen) { \ + (dashlen) = *++__dash; \ +} + +#define FbDashNextOdd(dashlen) FbDashNext(dashlen) + +#define FbDashStep(dashlen,even) { \ + if (!--(dashlen)) { \ + FbDashNext(dashlen); \ + (even) = 1-(even); \ + } \ +} + +/* XXX fb*PrivateIndex should be static, but it breaks the ABI */ + +extern int fbGCPrivateIndex; +extern int fbGetGCPrivateIndex(void); +#ifndef FB_NO_WINDOW_PIXMAPS +extern int fbWinPrivateIndex; +extern int fbGetWinPrivateIndex(void); +#endif +extern const GCOps fbGCOps; +extern const GCFuncs fbGCFuncs; + +#ifdef TEKX11 +#define FB_OLD_GC +#define FB_OLD_SCREEN +#endif + +#ifdef FB_OLD_SCREEN +# define FB_OLD_MISCREENINIT /* miScreenInit requires 14 args, not 13 */ +#endif + +#ifdef FB_24_32BIT +#define FB_SCREEN_PRIVATE +#endif + +#ifdef FB_SCREEN_PRIVATE +extern int fbScreenPrivateIndex; +extern int fbGetScreenPrivateIndex(void); + +/* private field of a screen */ +typedef struct { + unsigned char win32bpp; /* window bpp for 32-bpp images */ + unsigned char pix32bpp; /* pixmap bpp for 32-bpp images */ +} FbScreenPrivRec, *FbScreenPrivPtr; + +#define fbGetScreenPrivate(pScreen) ((FbScreenPrivPtr) \ + (pScreen)->devPrivates[fbGetScreenPrivateIndex()].ptr) +#endif + +/* private field of GC */ +typedef struct { +#ifdef FB_OLD_GC + unsigned char pad1; + unsigned char pad2; + unsigned char pad3; + unsigned fExpose:1; + unsigned freeCompClip:1; + PixmapPtr pRotatedPixmap; + RegionPtr pCompositeClip; +#endif + FbBits and, xor; /* reduced rop values */ + FbBits bgand, bgxor; /* for stipples */ + FbBits fg, bg, pm; /* expanded and filled */ + unsigned int dashLength; /* total of all dash elements */ + unsigned char oneRect; /* clip list is single rectangle */ + unsigned char evenStipple; /* stipple is even */ + unsigned char bpp; /* current drawable bpp */ +} FbGCPrivRec, *FbGCPrivPtr; + +#define fbGetGCPrivate(pGC) ((FbGCPrivPtr)\ + (pGC)->devPrivates[fbGetGCPrivateIndex()].ptr) + +#ifdef FB_OLD_GC +#define fbGetCompositeClip(pGC) (fbGetGCPrivate(pGC)->pCompositeClip) +#define fbGetExpose(pGC) (fbGetGCPrivate(pGC)->fExpose) +#define fbGetFreeCompClip(pGC) (fbGetGCPrivate(pGC)->freeCompClip) +#define fbGetRotatedPixmap(pGC) (fbGetGCPrivate(pGC)->pRotatedPixmap) +#else +#define fbGetCompositeClip(pGC) ((pGC)->pCompositeClip) +#define fbGetExpose(pGC) ((pGC)->fExpose) +#define fbGetFreeCompClip(pGC) ((pGC)->freeCompClip) +#define fbGetRotatedPixmap(pGC) ((pGC)->pRotatedPixmap) +#endif + +#define fbGetScreenPixmap(s) ((PixmapPtr) (s)->devPrivate) +#ifdef FB_NO_WINDOW_PIXMAPS +#define fbGetWindowPixmap(d) fbGetScreenPixmap(((DrawablePtr) (d))->pScreen) +#else +#define fbGetWindowPixmap(pWin) ((PixmapPtr)\ + ((WindowPtr) (pWin))->devPrivates[fbGetWinPrivateIndex()].ptr) +#endif + +#ifdef ROOTLESS +#define __fbPixDrawableX(pPix) ((pPix)->drawable.x) +#define __fbPixDrawableY(pPix) ((pPix)->drawable.y) +#else +#define __fbPixDrawableX(pPix) 0 +#define __fbPixDrawableY(pPix) 0 +#endif + +#ifdef COMPOSITE +#define __fbPixOffXWin(pPix) (__fbPixDrawableX(pPix) - (pPix)->screen_x) +#define __fbPixOffYWin(pPix) (__fbPixDrawableY(pPix) - (pPix)->screen_y) +#else +#define __fbPixOffXWin(pPix) (__fbPixDrawableX(pPix)) +#define __fbPixOffYWin(pPix) (__fbPixDrawableY(pPix)) +#endif +#define __fbPixOffXPix(pPix) (__fbPixDrawableX(pPix)) +#define __fbPixOffYPix(pPix) (__fbPixDrawableY(pPix)) + +#define fbGetDrawable(pDrawable, pointer, stride, bpp, xoff, yoff) { \ + PixmapPtr _pPix; \ + if ((pDrawable)->type != DRAWABLE_PIXMAP) { \ + _pPix = fbGetWindowPixmap(pDrawable); \ + (xoff) = __fbPixOffXWin(_pPix); \ + (yoff) = __fbPixOffYWin(_pPix); \ + } else { \ + _pPix = (PixmapPtr) (pDrawable); \ + (xoff) = __fbPixOffXPix(_pPix); \ + (yoff) = __fbPixOffYPix(_pPix); \ + } \ + (pointer) = (FbBits *) _pPix->devPrivate.ptr; \ + (stride) = ((int) _pPix->devKind) / sizeof (FbBits); (void)(stride); \ + (bpp) = _pPix->drawable.bitsPerPixel; (void)(bpp); \ +} + +#define fbGetStipDrawable(pDrawable, pointer, stride, bpp, xoff, yoff) { \ + PixmapPtr _pPix; \ + if ((pDrawable)->type != DRAWABLE_PIXMAP) { \ + _pPix = fbGetWindowPixmap(pDrawable); \ + (xoff) = __fbPixOffXWin(_pPix); \ + (yoff) = __fbPixOffYWin(_pPix); \ + } else { \ + _pPix = (PixmapPtr) (pDrawable); \ + (xoff) = __fbPixOffXPix(_pPix); \ + (yoff) = __fbPixOffYPix(_pPix); \ + } \ + (pointer) = (FbStip *) _pPix->devPrivate.ptr; \ + (stride) = ((int) _pPix->devKind) / sizeof (FbStip); (void)(stride); \ + (bpp) = _pPix->drawable.bitsPerPixel; (void)(bpp); \ +} + +/* + * XFree86 empties the root BorderClip when the VT is inactive, + * here's a macro which uses that to disable GetImage and GetSpans + */ + +#define fbWindowEnabled(pWin) \ + RegionNotEmpty(\ + &(pWin)->drawable.pScreen->root->borderClip) + +#define fbDrawableEnabled(pDrawable) \ + ((pDrawable)->type == DRAWABLE_PIXMAP ? \ + TRUE : fbWindowEnabled((WindowPtr) pDrawable)) + +#ifdef FB_OLD_SCREEN +#define BitsPerPixel(d) (\ + ((1 << PixmapWidthPaddingInfo[d].padBytesLog2) * 8 / \ + (PixmapWidthPaddingInfo[d].padRoundUp+1))) +#endif + +#define FbPowerOfTwo(w) (((w) & ((w) - 1)) == 0) +/* + * Accelerated tiles are power of 2 width <= FB_UNIT + */ +#define FbEvenTile(w) ((w) <= FB_UNIT && FbPowerOfTwo(w)) +/* + * Accelerated stipples are power of 2 width and <= FB_UNIT/dstBpp + * with dstBpp a power of 2 as well + */ +#define FbEvenStip(w,bpp) ((w) * (bpp) <= FB_UNIT && FbPowerOfTwo(w) && FbPowerOfTwo(bpp)) + +/* + * fb24_32.c + */ +void +fb24_32GetSpans(DrawablePtr pDrawable, + int wMax, + DDXPointPtr ppt, + int *pwidth, + int nspans, + char *pchardstStart); + +void +fb24_32SetSpans (DrawablePtr pDrawable, + GCPtr pGC, + char *src, + DDXPointPtr ppt, + int *pwidth, + int nspans, + int fSorted); + +void +fb24_32PutZImage (DrawablePtr pDrawable, + RegionPtr pClip, + int alu, + FbBits pm, + int x, + int y, + int width, + int height, + CARD8 *src, + FbStride srcStride); + +void +fb24_32GetImage (DrawablePtr pDrawable, + int x, + int y, + int w, + int h, + unsigned int format, + unsigned long planeMask, + char *d); + +void +fb24_32CopyMtoN (DrawablePtr pSrcDrawable, + DrawablePtr pDstDrawable, + GCPtr pGC, + BoxPtr pbox, + int nbox, + int dx, + int dy, + Bool reverse, + Bool upsidedown, + Pixel bitplane, + void *closure); + +PixmapPtr +fb24_32ReformatTile(PixmapPtr pOldTile, int bitsPerPixel); + +Bool +fb24_32CreateScreenResources(ScreenPtr pScreen); + +Bool +fb24_32ModifyPixmapHeader (PixmapPtr pPixmap, + int width, + int height, + int depth, + int bitsPerPixel, + int devKind, + void *pPixData); + +/* + * fballpriv.c + */ +Bool +fbAllocatePrivates(ScreenPtr pScreen, int *pGCIndex); + +/* + * fbarc.c + */ + +void +fbPolyArc (DrawablePtr pDrawable, + GCPtr pGC, + int narcs, + xArc *parcs); + +/* + * fbbits.c + */ + +void +fbBresSolid8(DrawablePtr pDrawable, + GCPtr pGC, + int dashOffset, + int signdx, + int signdy, + int axis, + int x, + int y, + int e, + int e1, + int e3, + int len); + +void +fbBresDash8 (DrawablePtr pDrawable, + GCPtr pGC, + int dashOffset, + int signdx, + int signdy, + int axis, + int x, + int y, + int e, + int e1, + int e3, + int len); + +void +fbDots8 (FbBits *dst, + FbStride dstStride, + int dstBpp, + BoxPtr pBox, + xPoint *pts, + int npt, + int xorg, + int yorg, + int xoff, + int yoff, + FbBits and, + FbBits xor); + +void +fbArc8 (FbBits *dst, + FbStride dstStride, + int dstBpp, + xArc *arc, + int dx, + int dy, + FbBits and, + FbBits xor); + +void +fbGlyph8 (FbBits *dstLine, + FbStride dstStride, + int dstBpp, + FbStip *stipple, + FbBits fg, + int height, + int shift); + +void +fbPolyline8 (DrawablePtr pDrawable, + GCPtr pGC, + int mode, + int npt, + DDXPointPtr ptsOrig); + +void +fbPolySegment8 (DrawablePtr pDrawable, + GCPtr pGC, + int nseg, + xSegment *pseg); + +void +fbBresSolid16(DrawablePtr pDrawable, + GCPtr pGC, + int dashOffset, + int signdx, + int signdy, + int axis, + int x, + int y, + int e, + int e1, + int e3, + int len); + +void +fbBresDash16(DrawablePtr pDrawable, + GCPtr pGC, + int dashOffset, + int signdx, + int signdy, + int axis, + int x, + int y, + int e, + int e1, + int e3, + int len); + +void +fbDots16(FbBits *dst, + FbStride dstStride, + int dstBpp, + BoxPtr pBox, + xPoint *pts, + int npt, + int xorg, + int yorg, + int xoff, + int yoff, + FbBits and, + FbBits xor); + +void +fbArc16(FbBits *dst, + FbStride dstStride, + int dstBpp, + xArc *arc, + int dx, + int dy, + FbBits and, + FbBits xor); + +void +fbGlyph16(FbBits *dstLine, + FbStride dstStride, + int dstBpp, + FbStip *stipple, + FbBits fg, + int height, + int shift); + +void +fbPolyline16 (DrawablePtr pDrawable, + GCPtr pGC, + int mode, + int npt, + DDXPointPtr ptsOrig); + +void +fbPolySegment16 (DrawablePtr pDrawable, + GCPtr pGC, + int nseg, + xSegment *pseg); + + +void +fbBresSolid24(DrawablePtr pDrawable, + GCPtr pGC, + int dashOffset, + int signdx, + int signdy, + int axis, + int x, + int y, + int e, + int e1, + int e3, + int len); + +void +fbBresDash24(DrawablePtr pDrawable, + GCPtr pGC, + int dashOffset, + int signdx, + int signdy, + int axis, + int x, + int y, + int e, + int e1, + int e3, + int len); + +void +fbDots24(FbBits *dst, + FbStride dstStride, + int dstBpp, + BoxPtr pBox, + xPoint *pts, + int npt, + int xorg, + int yorg, + int xoff, + int yoff, + FbBits and, + FbBits xor); + +void +fbArc24(FbBits *dst, + FbStride dstStride, + int dstBpp, + xArc *arc, + int dx, + int dy, + FbBits and, + FbBits xor); + +void +fbGlyph24(FbBits *dstLine, + FbStride dstStride, + int dstBpp, + FbStip *stipple, + FbBits fg, + int height, + int shift); + +void +fbPolyline24 (DrawablePtr pDrawable, + GCPtr pGC, + int mode, + int npt, + DDXPointPtr ptsOrig); + +void +fbPolySegment24 (DrawablePtr pDrawable, + GCPtr pGC, + int nseg, + xSegment *pseg); + + +void +fbBresSolid32(DrawablePtr pDrawable, + GCPtr pGC, + int dashOffset, + int signdx, + int signdy, + int axis, + int x, + int y, + int e, + int e1, + int e3, + int len); + +void +fbBresDash32(DrawablePtr pDrawable, + GCPtr pGC, + int dashOffset, + int signdx, + int signdy, + int axis, + int x, + int y, + int e, + int e1, + int e3, + int len); + +void +fbDots32(FbBits *dst, + FbStride dstStride, + int dstBpp, + BoxPtr pBox, + xPoint *pts, + int npt, + int xorg, + int yorg, + int xoff, + int yoff, + FbBits and, + FbBits xor); + +void +fbArc32(FbBits *dst, + FbStride dstStride, + int dstBpp, + xArc *arc, + int dx, + int dy, + FbBits and, + FbBits xor); + +void +fbGlyph32(FbBits *dstLine, + FbStride dstStride, + int dstBpp, + FbStip *stipple, + FbBits fg, + int height, + int shift); +void +fbPolyline32 (DrawablePtr pDrawable, + GCPtr pGC, + int mode, + int npt, + DDXPointPtr ptsOrig); + +void +fbPolySegment32 (DrawablePtr pDrawable, + GCPtr pGC, + int nseg, + xSegment *pseg); + +/* + * fbblt.c + */ +void +fbBlt (FbBits *src, + FbStride srcStride, + int srcX, + + FbBits *dst, + FbStride dstStride, + int dstX, + + int width, + int height, + + int alu, + FbBits pm, + int bpp, + + Bool reverse, + Bool upsidedown); + +void +fbBlt24 (FbBits *srcLine, + FbStride srcStride, + int srcX, + + FbBits *dstLine, + FbStride dstStride, + int dstX, + + int width, + int height, + + int alu, + FbBits pm, + + Bool reverse, + Bool upsidedown); + +void +fbBltStip (FbStip *src, + FbStride srcStride, /* in FbStip units, not FbBits units */ + int srcX, + + FbStip *dst, + FbStride dstStride, /* in FbStip units, not FbBits units */ + int dstX, + + int width, + int height, + + int alu, + FbBits pm, + int bpp); + +/* + * fbbltone.c + */ +void +fbBltOne (FbStip *src, + FbStride srcStride, + int srcX, + FbBits *dst, + FbStride dstStride, + int dstX, + int dstBpp, + + int width, + int height, + + FbBits fgand, + FbBits fbxor, + FbBits bgand, + FbBits bgxor); + +#ifdef FB_24BIT +void +fbBltOne24 (FbStip *src, + FbStride srcStride, /* FbStip units per scanline */ + int srcX, /* bit position of source */ + FbBits *dst, + FbStride dstStride, /* FbBits units per scanline */ + int dstX, /* bit position of dest */ + int dstBpp, /* bits per destination unit */ + + int width, /* width in bits of destination */ + int height, /* height in scanlines */ + + FbBits fgand, /* rrop values */ + FbBits fgxor, + FbBits bgand, + FbBits bgxor); +#endif + +void +fbBltPlane (FbBits *src, + FbStride srcStride, + int srcX, + int srcBpp, + + FbStip *dst, + FbStride dstStride, + int dstX, + + int width, + int height, + + FbStip fgand, + FbStip fgxor, + FbStip bgand, + FbStip bgxor, + Pixel planeMask); + +/* + * fbbstore.c + */ +void +fbSaveAreas(PixmapPtr pPixmap, + RegionPtr prgnSave, + int xorg, + int yorg, + WindowPtr pWin); + +void +fbRestoreAreas(PixmapPtr pPixmap, + RegionPtr prgnRestore, + int xorg, + int yorg, + WindowPtr pWin); + +/* + * fbcmap.c + */ +int +fbListInstalledColormaps(ScreenPtr pScreen, Colormap *pmaps); + +void +fbInstallColormap(ColormapPtr pmap); + +void +fbUninstallColormap(ColormapPtr pmap); + +void +fbResolveColor(unsigned short *pred, + unsigned short *pgreen, + unsigned short *pblue, + VisualPtr pVisual); + +Bool +fbInitializeColormap(ColormapPtr pmap); + +int +fbExpandDirectColors (ColormapPtr pmap, + int ndef, + xColorItem *indefs, + xColorItem *outdefs); + +Bool +fbCreateDefColormap(ScreenPtr pScreen); + +void +fbClearVisualTypes(void); + +Bool +fbSetVisualTypes (int depth, int visuals, int bitsPerRGB); + +Bool +fbSetVisualTypesAndMasks (int depth, int visuals, int bitsPerRGB, + Pixel redMask, Pixel greenMask, Pixel blueMask); + +Bool +fbInitVisuals (VisualPtr *visualp, + DepthPtr *depthp, + int *nvisualp, + int *ndepthp, + int *rootDepthp, + VisualID *defaultVisp, + unsigned long sizes, + int bitsPerRGB); + +/* + * fbcopy.c + */ + +typedef void (*fbCopyProc) (DrawablePtr pSrcDrawable, + DrawablePtr pDstDrawable, + GCPtr pGC, + BoxPtr pDstBox, + int nbox, + int dx, + int dy, + Bool reverse, + Bool upsidedown, + Pixel bitplane, + void *closure); + +void +fbCopyNtoN (DrawablePtr pSrcDrawable, + DrawablePtr pDstDrawable, + GCPtr pGC, + BoxPtr pbox, + int nbox, + int dx, + int dy, + Bool reverse, + Bool upsidedown, + Pixel bitplane, + void *closure); + +void +fbCopy1toN (DrawablePtr pSrcDrawable, + DrawablePtr pDstDrawable, + GCPtr pGC, + BoxPtr pbox, + int nbox, + int dx, + int dy, + Bool reverse, + Bool upsidedown, + Pixel bitplane, + void *closure); + +void +fbCopyNto1 (DrawablePtr pSrcDrawable, + DrawablePtr pDstDrawable, + GCPtr pGC, + BoxPtr pbox, + int nbox, + int dx, + int dy, + Bool reverse, + Bool upsidedown, + Pixel bitplane, + void *closure); + +void +fbCopyRegion (DrawablePtr pSrcDrawable, + DrawablePtr pDstDrawable, + GCPtr pGC, + RegionPtr pDstRegion, + int dx, + int dy, + fbCopyProc copyProc, + Pixel bitPlane, + void *closure); + +RegionPtr +fbDoCopy (DrawablePtr pSrcDrawable, + DrawablePtr pDstDrawable, + GCPtr pGC, + int xIn, + int yIn, + int widthSrc, + int heightSrc, + int xOut, + int yOut, + fbCopyProc copyProc, + Pixel bitplane, + void *closure); + +RegionPtr +fbCopyArea (DrawablePtr pSrcDrawable, + DrawablePtr pDstDrawable, + GCPtr pGC, + int xIn, + int yIn, + int widthSrc, + int heightSrc, + int xOut, + int yOut); + +RegionPtr +fbCopyPlane (DrawablePtr pSrcDrawable, + DrawablePtr pDstDrawable, + GCPtr pGC, + int xIn, + int yIn, + int widthSrc, + int heightSrc, + int xOut, + int yOut, + unsigned long bitplane); + +/* + * fbfill.c + */ +void +fbFill (DrawablePtr pDrawable, + GCPtr pGC, + int x, + int y, + int width, + int height); + +void +fbSolidBoxClipped (DrawablePtr pDrawable, + RegionPtr pClip, + int xa, + int ya, + int xb, + int yb, + FbBits and, + FbBits xor); + +/* + * fbfillrect.c + */ +void +fbPolyFillRect(DrawablePtr pDrawable, + GCPtr pGC, + int nrectInit, + xRectangle *prectInit); + +#define fbPolyFillArc miPolyFillArc + +#define fbFillPolygon miFillPolygon + +/* + * fbfillsp.c + */ +void +fbFillSpans (DrawablePtr pDrawable, + GCPtr pGC, + int nInit, + DDXPointPtr pptInit, + int *pwidthInit, + int fSorted); + + +/* + * fbgc.c + */ + +Bool +fbCreateGC(GCPtr pGC); + +void +fbPadPixmap (PixmapPtr pPixmap); + +void +fbValidateGC(GCPtr pGC, unsigned long changes, DrawablePtr pDrawable); + +/* + * fbgetsp.c + */ +void +fbGetSpans(DrawablePtr pDrawable, + int wMax, + DDXPointPtr ppt, + int *pwidth, + int nspans, + char *pchardstStart); + +/* + * fbglyph.c + */ + +Bool +fbGlyphIn (RegionPtr pRegion, + int x, + int y, + int width, + int height); + +void +fbPolyGlyphBlt (DrawablePtr pDrawable, + GCPtr pGC, + int x, + int y, + unsigned int nglyph, + CharInfoPtr *ppci, + void *pglyphBase); + +void +fbImageGlyphBlt (DrawablePtr pDrawable, + GCPtr pGC, + int x, + int y, + unsigned int nglyph, + CharInfoPtr *ppci, + void *pglyphBase); + +/* + * fbimage.c + */ + +void +fbPutImage (DrawablePtr pDrawable, + GCPtr pGC, + int depth, + int x, + int y, + int w, + int h, + int leftPad, + int format, + char *pImage); + +void +fbPutZImage (DrawablePtr pDrawable, + RegionPtr pClip, + int alu, + FbBits pm, + int x, + int y, + int width, + int height, + FbStip *src, + FbStride srcStride); + +void +fbPutXYImage (DrawablePtr pDrawable, + RegionPtr pClip, + FbBits fg, + FbBits bg, + FbBits pm, + int alu, + Bool opaque, + + int x, + int y, + int width, + int height, + + FbStip *src, + FbStride srcStride, + int srcX); + +void +fbGetImage (DrawablePtr pDrawable, + int x, + int y, + int w, + int h, + unsigned int format, + unsigned long planeMask, + char *d); +/* + * fbline.c + */ + +void +fbZeroLine (DrawablePtr pDrawable, + GCPtr pGC, + int mode, + int npt, + DDXPointPtr ppt); + +void +fbZeroSegment (DrawablePtr pDrawable, + GCPtr pGC, + int nseg, + xSegment *pSegs); + +void +fbPolyLine (DrawablePtr pDrawable, + GCPtr pGC, + int mode, + int npt, + DDXPointPtr ppt); + +void +fbFixCoordModePrevious (int npt, + DDXPointPtr ppt); + +void +fbPolySegment (DrawablePtr pDrawable, + GCPtr pGC, + int nseg, + xSegment *pseg); + +#define fbPolyRectangle miPolyRectangle + +/* + * fbpict.c + */ + +Bool +fbPictureInit (ScreenPtr pScreen, + PictFormatPtr formats, + int nformats); + +/* + * fbpixmap.c + */ + +PixmapPtr +fbCreatePixmapBpp (ScreenPtr pScreen, int width, int height, int depth, int bpp, + unsigned usage_hint); + +PixmapPtr +fbCreatePixmap (ScreenPtr pScreen, int width, int height, int depth, unsigned usage_hint); + +Bool +fbDestroyPixmap (PixmapPtr pPixmap); + +RegionPtr +fbPixmapToRegion(PixmapPtr pPix); + +/* + * fbpoint.c + */ + +void +fbDots (FbBits *dstOrig, + FbStride dstStride, + int dstBpp, + BoxPtr pBox, + xPoint *pts, + int npt, + int xorg, + int yorg, + int xoff, + int yoff, + FbBits andOrig, + FbBits xorOrig); + +void +fbPolyPoint (DrawablePtr pDrawable, + GCPtr pGC, + int mode, + int npt, + xPoint *pptInit); + +/* + * fbpush.c + */ +void +fbPushPattern (DrawablePtr pDrawable, + GCPtr pGC, + + FbStip *src, + FbStride srcStride, + int srcX, + + int x, + int y, + + int width, + int height); + +void +fbPushFill (DrawablePtr pDrawable, + GCPtr pGC, + + FbStip *src, + FbStride srcStride, + int srcX, + + int x, + int y, + int width, + int height); + +void +fbPush1toN (DrawablePtr pSrcDrawable, + DrawablePtr pDstDrawable, + GCPtr pGC, + BoxPtr pbox, + int nbox, + int dx, + int dy, + Bool reverse, + Bool upsidedown, + Pixel bitplane, + void *closure); + +void +fbPushImage (DrawablePtr pDrawable, + GCPtr pGC, + + FbStip *src, + FbStride srcStride, + int srcX, + + int x, + int y, + int width, + int height); + +void +fbPushPixels (GCPtr pGC, + PixmapPtr pBitmap, + DrawablePtr pDrawable, + int dx, + int dy, + int xOrg, + int yOrg); + + +/* + * fbscreen.c + */ + +Bool +fbCloseScreen (ScreenPtr pScreen); + +Bool +fbRealizeFont(ScreenPtr pScreen, FontPtr pFont); + +Bool +fbUnrealizeFont(ScreenPtr pScreen, FontPtr pFont); + +void +fbQueryBestSize (int class, + unsigned short *width, unsigned short *height, + ScreenPtr pScreen); + +#ifndef FB_OLD_SCREEN +PixmapPtr +_fbGetWindowPixmap (WindowPtr pWindow); + +void +_fbSetWindowPixmap (WindowPtr pWindow, PixmapPtr pPixmap); +#endif + +Bool +fbSetupScreen(ScreenPtr pScreen, + void *pbits, /* pointer to screen bitmap */ + int xsize, /* in pixels */ + int ysize, + int dpix, /* dots per inch */ + int dpiy, + int width, /* pixel width of frame buffer */ + int bpp); /* bits per pixel of frame buffer */ + +Bool +fbFinishScreenInit(ScreenPtr pScreen, + void *pbits, + int xsize, + int ysize, + int dpix, + int dpiy, + int width, + int bpp); + +Bool +fbScreenInit(ScreenPtr pScreen, + void *pbits, + int xsize, + int ysize, + int dpix, + int dpiy, + int width, + int bpp); + +void +fbInitializeBackingStore (ScreenPtr pScreen); + +/* + * fbseg.c + */ +typedef void FbBres (DrawablePtr pDrawable, + GCPtr pGC, + int dashOffset, + int signdx, + int signdy, + int axis, + int x, + int y, + int e, + int e1, + int e3, + int len); + +FbBres fbBresSolid, fbBresDash, fbBresFill, fbBresFillDash; +/* + * fbsetsp.c + */ + +void +fbSetSpans (DrawablePtr pDrawable, + GCPtr pGC, + char *src, + DDXPointPtr ppt, + int *pwidth, + int nspans, + int fSorted); + +FbBres * +fbSelectBres (DrawablePtr pDrawable, + GCPtr pGC); + +void +fbBres (DrawablePtr pDrawable, + GCPtr pGC, + int dashOffset, + int signdx, + int signdy, + int axis, + int x, + int y, + int e, + int e1, + int e3, + int len); + +void +fbSegment (DrawablePtr pDrawable, + GCPtr pGC, + int xa, + int ya, + int xb, + int yb, + Bool drawLast, + int *dashOffset); + + +/* + * fbsolid.c + */ + +void +fbSolid (FbBits *dst, + FbStride dstStride, + int dstX, + int bpp, + + int width, + int height, + + FbBits and, + FbBits xor); + +#ifdef FB_24BIT +void +fbSolid24 (FbBits *dst, + FbStride dstStride, + int dstX, + + int width, + int height, + + FbBits and, + FbBits xor); +#endif + +/* + * fbstipple.c + */ + +void +fbTransparentSpan (FbBits *dst, + FbBits stip, + FbBits fgxor, + int n); + +void +fbEvenStipple (FbBits *dst, + FbStride dstStride, + int dstX, + int dstBpp, + + int width, + int height, + + FbStip *stip, + FbStride stipStride, + int stipHeight, + + FbBits fgand, + FbBits fgxor, + FbBits bgand, + FbBits bgxor, + + int xRot, + int yRot); + +void +fbOddStipple (FbBits *dst, + FbStride dstStride, + int dstX, + int dstBpp, + + int width, + int height, + + FbStip *stip, + FbStride stipStride, + int stipWidth, + int stipHeight, + + FbBits fgand, + FbBits fgxor, + FbBits bgand, + FbBits bgxor, + + int xRot, + int yRot); + +void +fbStipple (FbBits *dst, + FbStride dstStride, + int dstX, + int dstBpp, + + int width, + int height, + + FbStip *stip, + FbStride stipStride, + int stipWidth, + int stipHeight, + Bool even, + + FbBits fgand, + FbBits fgxor, + FbBits bgand, + FbBits bgxor, + + int xRot, + int yRot); + +/* + * fbtile.c + */ + +void +fbEvenTile (FbBits *dst, + FbStride dstStride, + int dstX, + + int width, + int height, + + FbBits *tile, + int tileHeight, + + int alu, + FbBits pm, + int xRot, + int yRot); + +void +fbOddTile (FbBits *dst, + FbStride dstStride, + int dstX, + + int width, + int height, + + FbBits *tile, + FbStride tileStride, + int tileWidth, + int tileHeight, + + int alu, + FbBits pm, + int bpp, + + int xRot, + int yRot); + +void +fbTile (FbBits *dst, + FbStride dstStride, + int dstX, + + int width, + int height, + + FbBits *tile, + FbStride tileStride, + int tileWidth, + int tileHeight, + + int alu, + FbBits pm, + int bpp, + + int xRot, + int yRot); + +/* + * fbutil.c + */ +FbBits +fbReplicatePixel (Pixel p, int bpp); + +void +fbReduceRasterOp (int rop, FbBits fg, FbBits pm, FbBits *andp, FbBits *xorp); + +/* + * fbwindow.c + */ + +Bool +fbCreateWindow(WindowPtr pWin); + +Bool +fbDestroyWindow(WindowPtr pWin); + +Bool +fbMapWindow(WindowPtr pWindow); + +Bool +fbPositionWindow(WindowPtr pWin, int x, int y); + +Bool +fbUnmapWindow(WindowPtr pWindow); + +void +fbCopyWindowProc (DrawablePtr pSrcDrawable, + DrawablePtr pDstDrawable, + GCPtr pGC, + BoxPtr pbox, + int nbox, + int dx, + int dy, + Bool reverse, + Bool upsidedown, + Pixel bitplane, + void *closure); + +void +fbCopyWindow(WindowPtr pWin, + DDXPointRec ptOldOrg, + RegionPtr prgnSrc); + +Bool +fbChangeWindowAttributes(WindowPtr pWin, unsigned long mask); + +void +fbFillRegionSolid (DrawablePtr pDrawable, + RegionPtr pRegion, + FbBits and, + FbBits xor); + +void +fbFillRegionTiled (DrawablePtr pDrawable, + RegionPtr pRegion, + PixmapPtr pTile); + +void +fbPaintWindow(WindowPtr pWin, RegionPtr pRegion, int what); + + +#endif /* _FB_H_ */ diff --git a/nx-X11/programs/Xserver/fb/fb24_32.c b/nx-X11/programs/Xserver/fb/fb24_32.c new file mode 100644 index 000000000..7255b5021 --- /dev/null +++ b/nx-X11/programs/Xserver/fb/fb24_32.c @@ -0,0 +1,621 @@ +/* + * Copyright © 2000 SuSE, Inc. + * + * 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 SuSE not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. SuSE makes no representations about the + * suitability of this software for any purpose. It is provided "as is" + * without express or implied warranty. + * + * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE + * 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. + * + * Author: Keith Packard, SuSE, Inc. + */ + +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#endif + +#include <string.h> +#include "fb.h" + +/* X apps don't like 24bpp images, this code exposes 32bpp images */ + +/* + * These two functions do a full CopyArea while reformatting + * the data between 24 and 32bpp. They try to go a bit faster + * by reading/writing aligned CARD32s where it's easy + */ + +#define Get8(a) ((CARD32) *(a)) + +#if BITMAP_BIT_ORDER == MSBFirst +#define Get24(a) ((Get8(a) << 16) | (Get8((a)+1) << 8) | Get8((a)+2)) +#define Put24(a,p) (((a)[0] = (CARD8) ((p) >> 16)), \ + ((a)[1] = (CARD8) ((p) >> 8)), \ + ((a)[2] = (CARD8) (p))) +#else +#define Get24(a) (Get8(a) | (Get8((a)+1) << 8) | (Get8((a)+2)<<16)) +#define Put24(a,p) (((a)[0] = (CARD8) (p)), \ + ((a)[1] = (CARD8) ((p) >> 8)), \ + ((a)[2] = (CARD8) ((p) >> 16))) +#endif + +typedef void (*fb24_32BltFunc) (CARD8 *srcLine, + FbStride srcStride, + int srcX, + + CARD8 *dstLine, + FbStride dstStride, + int dstX, + + int width, + int height, + + int alu, + FbBits pm); + +static void +fb24_32BltDown (CARD8 *srcLine, + FbStride srcStride, + int srcX, + + CARD8 *dstLine, + FbStride dstStride, + int dstX, + + int width, + int height, + + int alu, + FbBits pm) +{ + CARD32 *src; + CARD8 *dst; + int w; + Bool destInvarient; + CARD32 pixel, dpixel; + FbDeclareMergeRop (); + + srcLine += srcX * 4; + dstLine += dstX * 3; + + FbInitializeMergeRop(alu, (pm | ~(FbBits) 0xffffff)); + destInvarient = FbDestInvarientMergeRop(); + + while (height--) + { + src = (CARD32 *) srcLine; + dst = dstLine; + srcLine += srcStride; + dstLine += dstStride; + w = width; + if (destInvarient) + { + while (((long) dst & 3) && w) + { + w--; + pixel = *src++; + pixel = FbDoDestInvarientMergeRop(pixel); + Put24 (dst, pixel); + dst += 3; + } + /* Do four aligned pixels at a time */ + while (w >= 4) + { + CARD32 s0, s1; + s0 = *src++; + s0 = FbDoDestInvarientMergeRop(s0); + s1 = *src++; + s1 = FbDoDestInvarientMergeRop(s1); +#if BITMAP_BIT_ORDER == LSBFirst + *(CARD32 *)(dst) = (s0 & 0xffffff) | (s1 << 24); +#else + *(CARD32 *)(dst) = (s0 << 8) | ((s1 & 0xffffff) >> 16); +#endif + s0 = *src++; + s0 = FbDoDestInvarientMergeRop(s0); +#if BITMAP_BIT_ORDER == LSBFirst + *(CARD32 *)(dst+4) = ((s1 & 0xffffff) >> 8) | (s0 << 16); +#else + *(CARD32 *)(dst+4) = (s1 << 16) | ((s0 & 0xffffff) >> 8); +#endif + s1 = *src++; + s1 = FbDoDestInvarientMergeRop(s1); +#if BITMAP_BIT_ORDER == LSBFirst + *(CARD32 *)(dst+8) = ((s0 & 0xffffff) >> 16) | (s1 << 8); +#else + *(CARD32 *)(dst+8) = (s0 << 24) | (s1 & 0xffffff); +#endif + dst += 12; + w -= 4; + } + while (w--) + { + pixel = *src++; + pixel = FbDoDestInvarientMergeRop(pixel); + Put24 (dst, pixel); + dst += 3; + } + } + else + { + while (w--) + { + pixel = *src++; + dpixel = Get24 (dst); + pixel = FbDoMergeRop(pixel, dpixel); + Put24 (dst, pixel); + dst += 3; + } + } + } +} + +static void +fb24_32BltUp (CARD8 *srcLine, + FbStride srcStride, + int srcX, + + CARD8 *dstLine, + FbStride dstStride, + int dstX, + + int width, + int height, + + int alu, + FbBits pm) +{ + CARD8 *src; + CARD32 *dst; + int w; + Bool destInvarient; + CARD32 pixel; + FbDeclareMergeRop (); + + FbInitializeMergeRop(alu, (pm | (~(FbBits) 0xffffff))); + destInvarient = FbDestInvarientMergeRop(); + + srcLine += srcX * 3; + dstLine += dstX * 4; + + while (height--) + { + w = width; + src = srcLine; + dst = (CARD32 *) dstLine; + srcLine += srcStride; + dstLine += dstStride; + if (destInvarient) + { + while (((long) src & 3) && w) + { + w--; + pixel = Get24(src); + src += 3; + *dst++ = FbDoDestInvarientMergeRop(pixel); + } + /* Do four aligned pixels at a time */ + while (w >= 4) + { + CARD32 s0, s1; + + s0 = *(CARD32 *)(src); +#if BITMAP_BIT_ORDER == LSBFirst + pixel = s0 & 0xffffff; +#else + pixel = s0 >> 8; +#endif + *dst++ = FbDoDestInvarientMergeRop(pixel); + s1 = *(CARD32 *)(src+4); +#if BITMAP_BIT_ORDER == LSBFirst + pixel = (s0 >> 24) | ((s1 << 8) & 0xffffff); +#else + pixel = ((s0 << 16) & 0xffffff) | (s1 >> 16); +#endif + *dst++ = FbDoDestInvarientMergeRop(pixel); + s0 = *(CARD32 *)(src+8); +#if BITMAP_BIT_ORDER == LSBFirst + pixel = (s1 >> 16) | ((s0 << 16) & 0xffffff); +#else + pixel = ((s1 << 8) & 0xffffff) | (s0 >> 24); +#endif + *dst++ = FbDoDestInvarientMergeRop(pixel); +#if BITMAP_BIT_ORDER == LSBFirst + pixel = s0 >> 8; +#else + pixel = s0 & 0xffffff; +#endif + *dst++ = FbDoDestInvarientMergeRop(pixel); + src += 12; + w -= 4; + } + while (w) + { + w--; + pixel = Get24(src); + src += 3; + *dst++ = FbDoDestInvarientMergeRop(pixel); + } + } + else + { + while (w--) + { + pixel = Get24(src); + src += 3; + *dst = FbDoMergeRop(pixel, *dst); + dst++; + } + } + } +} + +/* + * Spans functions; probably unused. + */ +void +fb24_32GetSpans(DrawablePtr pDrawable, + int wMax, + DDXPointPtr ppt, + int *pwidth, + int nspans, + char *pchardstStart) +{ + FbBits *srcBits; + CARD8 *src; + FbStride srcStride; + int srcBpp; + int srcXoff, srcYoff; + CARD8 *dst; + + fbGetDrawable (pDrawable, srcBits, srcStride, srcBpp, srcXoff, srcYoff); + src = (CARD8 *) srcBits; + srcStride *= sizeof (FbBits); + + while (nspans--) + { + dst = (CARD8 *) pchardstStart; + fb24_32BltUp (src + (ppt->y + srcYoff) * srcStride, srcStride, + ppt->x + srcXoff, + + dst, + 1, + 0, + + *pwidth, + 1, + + GXcopy, + FB_ALLONES); + + pchardstStart += PixmapBytePad(*pwidth, pDrawable->depth); + ppt++; + pwidth++; + } +} + +void +fb24_32SetSpans (DrawablePtr pDrawable, + GCPtr pGC, + char *src, + DDXPointPtr ppt, + int *pwidth, + int nspans, + int fSorted) +{ + FbGCPrivPtr pPriv = fbGetGCPrivate (pGC); + RegionPtr pClip = fbGetCompositeClip(pGC); + FbBits *dstBits; + CARD8 *dst, *d, *s; + FbStride dstStride; + int dstBpp; + int dstXoff, dstYoff; + BoxPtr pbox; + int n; + int x1, x2; + + fbGetDrawable (pDrawable, dstBits, dstStride, dstBpp, dstXoff, dstYoff); + dst = (CARD8 *) dstBits; + dstStride *= sizeof (FbBits); + while (nspans--) + { + d = dst + (ppt->y + dstYoff) * dstStride; + s = (CARD8 *) src; + n = RegionNumRects(pClip); + pbox = RegionRects (pClip); + while (n--) + { + if (pbox->y1 > ppt->y) + break; + if (pbox->y2 > ppt->y) + { + x1 = ppt->x; + x2 = x1 + *pwidth; + if (pbox->x1 > x1) + x1 = pbox->x1; + if (pbox->x2 < x2) + x2 = pbox->x2; + if (x1 < x2) + fb24_32BltDown (s, + 0, + (x1 - ppt->x), + d, + dstStride, + x1 + dstXoff, + + (x2 - x1), + 1, + pGC->alu, + pPriv->pm); + } + } + src += PixmapBytePad (*pwidth, pDrawable->depth); + ppt++; + pwidth++; + } +} + +/* + * Clip and put 32bpp Z-format images to a 24bpp drawable + */ +void +fb24_32PutZImage (DrawablePtr pDrawable, + RegionPtr pClip, + int alu, + FbBits pm, + int x, + int y, + int width, + int height, + CARD8 *src, + FbStride srcStride) +{ + FbBits *dstBits; + CARD8 *dst; + FbStride dstStride; + int dstBpp; + int dstXoff, dstYoff; + int nbox; + BoxPtr pbox; + int x1, y1, x2, y2; + + fbGetDrawable (pDrawable, dstBits, dstStride, dstBpp, dstXoff, dstYoff); + dstStride *= sizeof(FbBits); + dst = (CARD8 *) dstBits; + + for (nbox = RegionNumRects (pClip), + pbox = RegionRects(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; + fb24_32BltDown (src + (y1 - y) * srcStride, + srcStride, + (x1 - x), + + dst + (y1 + dstYoff) * dstStride, + dstStride, + x1 + dstXoff, + + (x2 - x1), + (y2 - y1), + + alu, + pm); + } +} + +void +fb24_32GetImage (DrawablePtr pDrawable, + int x, + int y, + int w, + int h, + unsigned int format, + unsigned long planeMask, + char *d) +{ + FbBits *srcBits; + CARD8 *src; + FbStride srcStride; + int srcBpp; + int srcXoff, srcYoff; + FbStride dstStride; + FbBits pm; + + fbGetDrawable (pDrawable, srcBits, srcStride, srcBpp, srcXoff, srcYoff); + src = (CARD8 *) srcBits; + srcStride *= sizeof (FbBits); + + x += pDrawable->x; + y += pDrawable->y; + + pm = fbReplicatePixel (planeMask, 32); + dstStride = PixmapBytePad(w, pDrawable->depth); + if (pm != FB_ALLONES) + memset (d, 0, dstStride * h); + fb24_32BltUp (src + (y + srcYoff) * srcStride, srcStride, x + srcXoff, + (CARD8 *) d, dstStride, 0, + w, h, GXcopy, pm); +} + +void +fb24_32CopyMtoN (DrawablePtr pSrcDrawable, + DrawablePtr pDstDrawable, + GCPtr pGC, + BoxPtr pbox, + int nbox, + int dx, + int dy, + Bool reverse, + Bool upsidedown, + Pixel bitplane, + void *closure) +{ + FbGCPrivPtr pPriv = fbGetGCPrivate(pGC); + FbBits *srcBits; + CARD8 *src; + FbStride srcStride; + int srcBpp; + FbBits *dstBits; + CARD8 *dst; + FbStride dstStride; + int dstBpp; + fb24_32BltFunc blt; + int srcXoff, srcYoff; + int dstXoff, dstYoff; + + fbGetDrawable (pSrcDrawable, srcBits, srcStride, srcBpp, srcXoff, srcYoff); + src = (CARD8 *) srcBits; + srcStride *= sizeof (FbBits); + fbGetDrawable (pDstDrawable, dstBits, dstStride, dstBpp, dstXoff, dstYoff); + dst = (CARD8 *) dstBits; + dstStride *= sizeof (FbBits); + if (srcBpp == 24) + blt = fb24_32BltUp; + else + blt = fb24_32BltDown; + + while (nbox--) + { + (*blt) (src + (pbox->y1 + dy + srcYoff) * srcStride, + srcStride, + (pbox->x1 + dx + srcXoff), + + dst + (pbox->y1 + dstYoff) * dstStride, + dstStride, + (pbox->x1 + dstXoff), + + (pbox->x2 - pbox->x1), + (pbox->y2 - pbox->y1), + + pGC->alu, + pPriv->pm); + pbox++; + } +} + +PixmapPtr +fb24_32ReformatTile(PixmapPtr pOldTile, int bitsPerPixel) +{ + ScreenPtr pScreen = pOldTile->drawable.pScreen; + PixmapPtr pNewTile; + FbBits *old, *new; + FbStride oldStride, newStride; + int oldBpp, newBpp; + fb24_32BltFunc blt; + _X_UNUSED int oldXoff, oldYoff; + _X_UNUSED int newXoff, newYoff; + + pNewTile = fbCreatePixmapBpp (pScreen, + pOldTile->drawable.width, + pOldTile->drawable.height, + pOldTile->drawable.depth, + bitsPerPixel, 0); + if (!pNewTile) + return 0; + fbGetDrawable (&pOldTile->drawable, + old, oldStride, oldBpp, oldXoff, oldYoff); + fbGetDrawable (&pNewTile->drawable, + new, newStride, newBpp, newXoff, newYoff); + if (oldBpp == 24) + blt = fb24_32BltUp; + else + blt = fb24_32BltDown; + + (*blt) ((CARD8 *) old, + oldStride * sizeof (FbBits), + 0, + + (CARD8 *) new, + newStride * sizeof (FbBits), + 0, + + pOldTile->drawable.width, + pOldTile->drawable.height, + + GXcopy, + FB_ALLONES); + + return pNewTile; +} + +typedef struct { + void * pbits; + int width; +} miScreenInitParmsRec, *miScreenInitParmsPtr; + +Bool +fb24_32CreateScreenResources(ScreenPtr pScreen) +{ + miScreenInitParmsPtr pScrInitParms; + int pitch; + Bool retval; + + /* get the pitch before mi destroys it */ + pScrInitParms = (miScreenInitParmsPtr)pScreen->devPrivate; + pitch = BitmapBytePad(pScrInitParms->width * 24); + + if((retval = miCreateScreenResources(pScreen))) { + /* fix the screen pixmap */ + PixmapPtr pPix = (PixmapPtr)pScreen->devPrivate; + pPix->drawable.bitsPerPixel = 24; + pPix->devKind = pitch; + } + + return retval; +} + +Bool +fb24_32ModifyPixmapHeader (PixmapPtr pPixmap, + int width, + int height, + int depth, + int bitsPerPixel, + int devKind, + void *pPixData) +{ + int bpp, w; + + if (!pPixmap) + return FALSE; + bpp = bitsPerPixel; + if (bpp <= 0) + bpp = pPixmap->drawable.bitsPerPixel; + if (bpp == 24) + { + if (devKind < 0) + { + w = width; + if (w <= 0) + w = pPixmap->drawable.width; + devKind = BitmapBytePad(w * 24); + } + } + return miModifyPixmapHeader(pPixmap, width, height, depth, bitsPerPixel, + devKind, pPixData); +} diff --git a/nx-X11/programs/Xserver/fb/fballpriv.c b/nx-X11/programs/Xserver/fb/fballpriv.c new file mode 100644 index 000000000..d2d8866e2 --- /dev/null +++ b/nx-X11/programs/Xserver/fb/fballpriv.c @@ -0,0 +1,92 @@ +/* + * Id: fballpriv.c,v 1.1 1999/11/02 03:54:45 keithp Exp $ + * + * 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" + +#ifdef FB_SCREEN_PRIVATE +int fbScreenPrivateIndex; +int fbGetScreenPrivateIndex(void) +{ + return fbScreenPrivateIndex; +} +#endif +int fbGCPrivateIndex; +int fbGetGCPrivateIndex(void) +{ + return fbGCPrivateIndex; +} +#ifndef FB_NO_WINDOW_PIXMAPS +int fbWinPrivateIndex; +int fbGetWinPrivateIndex(void) +{ + return fbWinPrivateIndex; +} +#endif +int fbGeneration; + +#ifdef FB_OLD_SCREEN +#define miAllocateGCPrivateIndex() AllocateGCPrivateIndex() +#endif + +Bool +fbAllocatePrivates(ScreenPtr pScreen, int *pGCIndex) +{ + if (fbGeneration != serverGeneration) + { + fbGCPrivateIndex = miAllocateGCPrivateIndex (); +#ifndef FB_NO_WINDOW_PIXMAPS + fbWinPrivateIndex = AllocateWindowPrivateIndex(); +#endif +#ifdef FB_SCREEN_PRIVATE + fbScreenPrivateIndex = AllocateScreenPrivateIndex (); + if (fbScreenPrivateIndex == -1) + return FALSE; +#endif + + fbGeneration = serverGeneration; + } + if (pGCIndex) + *pGCIndex = fbGCPrivateIndex; + if (!AllocateGCPrivate(pScreen, fbGCPrivateIndex, sizeof(FbGCPrivRec))) + return FALSE; +#ifndef FB_NO_WINDOW_PIXMAPS + if (!AllocateWindowPrivate(pScreen, fbWinPrivateIndex, 0)) + return FALSE; +#endif +#ifdef FB_SCREEN_PRIVATE + { + FbScreenPrivPtr pScreenPriv; + + pScreenPriv = (FbScreenPrivPtr) malloc (sizeof (FbScreenPrivRec)); + if (!pScreenPriv) + return FALSE; + pScreen->devPrivates[fbScreenPrivateIndex].ptr = (void *) pScreenPriv; + } +#endif + return TRUE; +} diff --git a/nx-X11/programs/Xserver/fb/fbarc.c b/nx-X11/programs/Xserver/fb/fbarc.c new file mode 100644 index 000000000..ae89e44d8 --- /dev/null +++ b/nx-X11/programs/Xserver/fb/fbarc.c @@ -0,0 +1,119 @@ +/* + * Id: fbarc.c,v 1.1 1999/11/02 03:54:45 keithp Exp $ + * + * 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" +#include "mizerarc.h" +#include <limits.h> + +typedef void (*FbArc) (FbBits *dst, + FbStride dstStride, + int dstBpp, + xArc *arc, + int dx, + int dy, + FbBits and, + FbBits xor); + +void +fbPolyArc (DrawablePtr pDrawable, + GCPtr pGC, + int narcs, + xArc *parcs) +{ + FbArc arc; + + if (pGC->lineWidth == 0) + { +#ifndef FBNOPIXADDR + arc = 0; + if (pGC->lineStyle == LineSolid && pGC->fillStyle == FillSolid) + { + switch (pDrawable->bitsPerPixel) + { + case 8: arc = fbArc8; break; + case 16: arc = fbArc16; break; +#ifdef FB_24BIT + case 24: arc = fbArc24; break; +#endif + case 32: arc = fbArc32; break; + } + } + if (arc) + { + FbGCPrivPtr pPriv = fbGetGCPrivate (pGC); + FbBits *dst; + FbStride dstStride; + int dstBpp; + int dstXoff, dstYoff; + BoxRec box; + int x2, y2; + RegionPtr cclip; + + cclip = fbGetCompositeClip (pGC); + fbGetDrawable (pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff); + while (narcs--) + { + if (miCanZeroArc (parcs)) + { + box.x1 = parcs->x + pDrawable->x; + box.y1 = parcs->y + pDrawable->y; + /* + * Because box.x2 and box.y2 get truncated to 16 bits, and the + * RECT_IN_REGION test treats the resulting number as a signed + * integer, the RECT_IN_REGION test alone can go the wrong way. + * This can result in a server crash because the rendering + * routines in this file deal directly with cpu addresses + * of pixels to be stored, and do not clip or otherwise check + * that all such addresses are within their respective pixmaps. + * So we only allow the RECT_IN_REGION test to be used for + * values that can be expressed correctly in a signed short. + */ + x2 = box.x1 + (int)parcs->width + 1; + box.x2 = x2; + y2 = box.y1 + (int)parcs->height + 1; + box.y2 = y2; + if ( (x2 <= SHRT_MAX) && (y2 <= SHRT_MAX) && + (RegionContainsRect(cclip, &box) == rgnIN) ) + (*arc) (dst, dstStride, dstBpp, + parcs, pDrawable->x + dstXoff, pDrawable->y + dstYoff, + pPriv->and, pPriv->xor); + else + miZeroPolyArc(pDrawable, pGC, 1, parcs); + } + else + miPolyArc(pDrawable, pGC, 1, parcs); + parcs++; + } + } + else +#endif + miZeroPolyArc (pDrawable, pGC, narcs, parcs); + } + else + miPolyArc (pDrawable, pGC, narcs, parcs); +} diff --git a/nx-X11/programs/Xserver/fb/fbbits.c b/nx-X11/programs/Xserver/fb/fbbits.c new file mode 100644 index 000000000..56b58df4e --- /dev/null +++ b/nx-X11/programs/Xserver/fb/fbbits.c @@ -0,0 +1,178 @@ +/* + * Id: fbbits.c,v 1.1 1999/11/02 03:54:45 keithp Exp $ + * + * 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" +#include "miline.h" +#include "mizerarc.h" + +#undef BRESSOLID +#undef BRESDASH +#undef DOTS +#undef ARC +#undef GLYPH +#undef BITS +#undef BITS2 +#undef BITS4 + +#define BRESSOLID fbBresSolid8 +#define BRESDASH fbBresDash8 +#define DOTS fbDots8 +#define ARC fbArc8 +#define GLYPH fbGlyph8 +#define POLYLINE fbPolyline8 +#define POLYSEGMENT fbPolySegment8 +#define BITS BYTE +#define BITS2 CARD16 +#define BITS4 CARD32 + +#include "fbbits.h" + +#undef BRESSOLID +#undef BRESDASH +#undef DOTS +#undef ARC +#undef GLYPH +#undef POLYLINE +#undef POLYSEGMENT +#undef BITS +#undef BITS2 +#undef BITS4 + +#define BRESSOLID fbBresSolid16 +#define BRESDASH fbBresDash16 +#define DOTS fbDots16 +#define ARC fbArc16 +#define GLYPH fbGlyph16 +#define POLYLINE fbPolyline16 +#define POLYSEGMENT fbPolySegment16 +#define BITS CARD16 +#define BITS2 CARD32 +#if FB_SHIFT == 6 +#define BITS4 FbBits +#endif + +#include "fbbits.h" + +#undef BRESSOLID +#undef BRESDASH +#undef DOTS +#undef ARC +#undef GLYPH +#undef POLYLINE +#undef POLYSEGMENT +#undef BITS +#undef BITS2 +#if FB_SHIFT == 6 +#undef BITS4 +#endif + +#ifdef FB_24BIT +#define BRESSOLID fbBresSolid24 +#define BRESDASH fbBresDash24 +#define DOTS fbDots24 +#define ARC fbArc24 +#define POLYLINE fbPolyline24 +#define POLYSEGMENT fbPolySegment24 + +#define BITS CARD32 +#define BITSUNIT BYTE +#define BITSMUL 3 + +#define FbDoTypeStore(b,t,x,s) (*((t *) (b)) = (x) >> (s)) +#define FbDoTypeRRop(b,t,a,x,s) (*((t *) (b)) = FbDoRRop(*((t *) (b)),\ + (a) >> (s), \ + (x) >> (s))) +#define FbDoTypeMaskRRop(b,t,a,x,m,s) (*((t *) (b)) = FbDoMaskRRop(*((t *) (b)),\ + (a) >> (s), \ + (x) >> (s), \ + (m) >> (s)) +#if BITMAP_BIT_ORDER == LSBFirst +#define BITSSTORE(b,x) ((unsigned long) (b) & 1 ? \ + (FbDoTypeStore (b, CARD8, x, 0), \ + FbDoTypeStore ((b) + 1, CARD16, x, 8)) : \ + (FbDoTypeStore (b, CARD16, x, 0), \ + FbDoTypeStore ((b) + 2, CARD8, x, 16))) +#define BITSRROP(b,a,x) ((unsigned long) (b) & 1 ? \ + (FbDoTypeRRop(b,CARD8,a,x,0), \ + FbDoTypeRRop((b)+1,CARD16,a,x,8)) : \ + (FbDoTypeRRop(b,CARD16,a,x,0), \ + FbDoTypeRRop((b)+2,CARD8,a,x,16))) +#else +#define BITSSTORE(b,x) ((unsigned long) (b) & 1 ? \ + (FbDoTypeStore (b, CARD8, x, 16), \ + FbDoTypeStore ((b) + 1, CARD16, x, 0)) : \ + (FbDoTypeStore (b, CARD16, x, 8), \ + FbDoTypeStore ((b) + 2, CARD8, x, 0))) +#define BITSRROP(b,a,x) ((unsigned long) (b) & 1 ? \ + (FbDoTypeRRop (b, CARD8, a, x, 16), \ + FbDoTypeRRop ((b) + 1, CARD16, a, x, 0)) : \ + (FbDoTypeRRop (b, CARD16, a, x, 8), \ + FbDoTypeRRop ((b) + 2, CARD8, a, x, 0))) +#endif + +#include "fbbits.h" + +#undef BITSSTORE +#undef BITSRROP +#undef BITSMUL +#undef BITSUNIT +#undef BITS + +#undef BRESSOLID +#undef BRESDASH +#undef DOTS +#undef ARC +#undef POLYLINE +#undef POLYSEGMENT +#endif /* FB_24BIT */ + +#define BRESSOLID fbBresSolid32 +#define BRESDASH fbBresDash32 +#define DOTS fbDots32 +#define ARC fbArc32 +#define GLYPH fbGlyph32 +#define POLYLINE fbPolyline32 +#define POLYSEGMENT fbPolySegment32 +#define BITS CARD32 +#if FB_SHIFT == 6 +#define BITS2 FbBits +#endif + +#include "fbbits.h" + +#undef BRESSOLID +#undef BRESDASH +#undef DOTS +#undef ARC +#undef GLYPH +#undef POLYLINE +#undef POLYSEGMENT +#undef BITS +#if FB_SHIFT == 6 +#undef BITS2 +#endif diff --git a/nx-X11/programs/Xserver/fb/fbbits.h b/nx-X11/programs/Xserver/fb/fbbits.h new file mode 100644 index 000000000..30fa21f1e --- /dev/null +++ b/nx-X11/programs/Xserver/fb/fbbits.h @@ -0,0 +1,960 @@ +/* + * 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. + */ + +/* + * This file defines functions for drawing some primitives using + * underlying datatypes instead of masks + */ + +#define isClipped(c,ul,lr) ((((c) - (ul)) | ((lr) - (c))) & 0x80008000) + +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#endif + +#ifdef BITSMUL +#define MUL BITSMUL +#else +#define MUL 1 +#endif + +#ifdef BITSSTORE +#define STORE(b,x) BITSSTORE(b,x) +#else +#define STORE(b,x) (*(b) = (x)) +#endif + +#ifdef BITSRROP +#define RROP(b,a,x) BITSRROP(b,a,x) +#else +#define RROP(b,a,x) (*(b) = FbDoRRop (*(b), (a), (x))) +#endif + +#ifdef BITSUNIT +#define UNIT BITSUNIT +#define USE_SOLID +#else +#define UNIT BITS +#endif + +/* + * Define the following before including this file: + * + * BRESSOLID name of function for drawing a solid segment + * BRESDASH name of function for drawing a dashed segment + * DOTS name of function for drawing dots + * ARC name of function for drawing a solid arc + * BITS type of underlying unit + */ + +#ifdef BRESSOLID +void +BRESSOLID (DrawablePtr pDrawable, + GCPtr pGC, + int dashOffset, + int signdx, + int signdy, + int axis, + int x1, + int y1, + int e, + int e1, + int e3, + int len) +{ + FbBits *dst; + FbStride dstStride; + int dstBpp; + int dstXoff, dstYoff; + FbGCPrivPtr pPriv = fbGetGCPrivate (pGC); + UNIT *bits; + FbStride bitsStride; + FbStride majorStep, minorStep; + BITS xor = (BITS) pPriv->xor; + + fbGetDrawable (pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff); + bits = ((UNIT *) (dst + ((y1 + dstYoff) * dstStride))) + (x1 + dstXoff) * MUL; + bitsStride = dstStride * (sizeof (FbBits) / sizeof (UNIT)); + if (signdy < 0) + bitsStride = -bitsStride; + if (axis == X_AXIS) + { + majorStep = signdx * MUL; + minorStep = bitsStride; + } + else + { + majorStep = bitsStride; + minorStep = signdx * MUL; + } + while (len--) + { + STORE(bits,xor); + bits += majorStep; + e += e1; + if (e >= 0) + { + bits += minorStep; + e += e3; + } + } +} +#endif + +#ifdef BRESDASH +void +BRESDASH (DrawablePtr pDrawable, + GCPtr pGC, + int dashOffset, + int signdx, + int signdy, + int axis, + int x1, + int y1, + int e, + int e1, + int e3, + int len) +{ + FbBits *dst; + FbStride dstStride; + int dstBpp; + int dstXoff, dstYoff; + FbGCPrivPtr pPriv = fbGetGCPrivate (pGC); + UNIT *bits; + FbStride bitsStride; + FbStride majorStep, minorStep; + BITS xorfg, xorbg; + FbDashDeclare; + int dashlen; + Bool even; + Bool doOdd; + + fbGetDrawable (pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff); + doOdd = pGC->lineStyle == LineDoubleDash; + xorfg = (BITS) pPriv->xor; + xorbg = (BITS) pPriv->bgxor; + + FbDashInit (pGC, pPriv, dashOffset, dashlen, even); + + bits = ((UNIT *) (dst + ((y1 + dstYoff) * dstStride))) + (x1 + dstXoff) * MUL; + bitsStride = dstStride * (sizeof (FbBits) / sizeof (UNIT)); + if (signdy < 0) + bitsStride = -bitsStride; + if (axis == X_AXIS) + { + majorStep = signdx * MUL; + minorStep = bitsStride; + } + else + { + majorStep = bitsStride; + minorStep = signdx * MUL; + } + if (dashlen >= len) + dashlen = len; + if (doOdd) + { + if (!even) + goto doubleOdd; + for (;;) + { + len -= dashlen; + while (dashlen--) + { + STORE(bits,xorfg); + bits += majorStep; + if ((e += e1) >= 0) + { + e += e3; + bits += minorStep; + } + } + if (!len) + break; + + FbDashNextEven(dashlen); + + if (dashlen >= len) + dashlen = len; +doubleOdd: + len -= dashlen; + while (dashlen--) + { + STORE(bits,xorbg); + bits += majorStep; + if ((e += e1) >= 0) + { + e += e3; + bits += minorStep; + } + } + if (!len) + break; + + FbDashNextOdd(dashlen); + + if (dashlen >= len) + dashlen = len; + } + } + else + { + if (!even) + goto onOffOdd; + for (;;) + { + len -= dashlen; + while (dashlen--) + { + STORE(bits,xorfg); + bits += majorStep; + if ((e += e1) >= 0) + { + e += e3; + bits += minorStep; + } + } + if (!len) + break; + + FbDashNextEven (dashlen); + + if (dashlen >= len) + dashlen = len; +onOffOdd: + len -= dashlen; + while (dashlen--) + { + bits += majorStep; + if ((e += e1) >= 0) + { + e += e3; + bits += minorStep; + } + } + if (!len) + break; + + FbDashNextOdd (dashlen); + + if (dashlen >= len) + dashlen = len; + } + } +} +#endif + +#ifdef DOTS +void +DOTS (FbBits *dst, + FbStride dstStride, + int dstBpp, + BoxPtr pBox, + xPoint *ptsOrig, + int npt, + int xorg, + int yorg, + int xoff, + int yoff, + FbBits and, + FbBits xor) +{ + INT32 *pts = (INT32 *) ptsOrig; + UNIT *bits = (UNIT *) dst; + UNIT *point; + BITS bxor = (BITS) xor; + BITS band = (BITS) and; + FbStride bitsStride = dstStride * (sizeof (FbBits) / sizeof (UNIT)); + INT32 ul, lr; + INT32 pt; + + ul = coordToInt(pBox->x1 - xorg, pBox->y1 - yorg); + lr = coordToInt(pBox->x2 - xorg - 1, pBox->y2 - yorg - 1); + + bits += bitsStride * (yorg + yoff) + (xorg + xoff) * MUL; + + if (and == 0) + { + while (npt--) + { + pt = *pts++; + if (!isClipped(pt,ul,lr)) + { + point = bits + intToY(pt) * bitsStride + intToX(pt) * MUL; + STORE(point,bxor); + } + } + } + else + { + while (npt--) + { + pt = *pts++; + if (!isClipped(pt,ul,lr)) + { + point = bits + intToY(pt) * bitsStride + intToX(pt) * MUL; + RROP(point,band,bxor); + } + } + } +} +#endif + +#ifdef ARC + +#define ARCCOPY(d) STORE(d,xorBits) +#define ARCRROP(d) RROP(d,andBits,xorBits) + +void +ARC (FbBits *dst, + FbStride dstStride, + int dstBpp, + xArc *arc, + int drawX, + int drawY, + FbBits and, + FbBits xor) +{ + UNIT *bits; + FbStride bitsStride; + miZeroArcRec info; + Bool do360; + int x; + UNIT *yorgp, *yorgop; + BITS andBits, xorBits; + int yoffset, dyoffset; + int y, a, b, d, mask; + int k1, k3, dx, dy; + + bits = (UNIT *) dst; + bitsStride = dstStride * (sizeof (FbBits) / sizeof (UNIT)); + andBits = (BITS) and; + xorBits = (BITS) xor; + do360 = miZeroArcSetup(arc, &info, TRUE); + yorgp = bits + ((info.yorg + drawY) * bitsStride); + yorgop = bits + ((info.yorgo + drawY) * bitsStride); + info.xorg = (info.xorg + drawX) * MUL; + info.xorgo = (info.xorgo + drawX) * MUL; + MIARCSETUP(); + yoffset = y ? bitsStride : 0; + dyoffset = 0; + mask = info.initialMask; + + if (!(arc->width & 1)) + { + if (andBits == 0) + { + if (mask & 2) + ARCCOPY(yorgp + info.xorgo); + if (mask & 8) + ARCCOPY(yorgop + info.xorgo); + } + else + { + if (mask & 2) + ARCRROP(yorgp + info.xorgo); + if (mask & 8) + ARCRROP(yorgop + info.xorgo); + } + } + if (!info.end.x || !info.end.y) + { + mask = info.end.mask; + info.end = info.altend; + } + if (do360 && (arc->width == arc->height) && !(arc->width & 1)) + { + int xoffset = bitsStride; + UNIT *yorghb = yorgp + (info.h * bitsStride) + info.xorg; + UNIT *yorgohb = yorghb - info.h * MUL; + + yorgp += info.xorg; + yorgop += info.xorg; + yorghb += info.h * MUL; + while (1) + { + if (andBits == 0) + { + ARCCOPY(yorgp + yoffset + x * MUL); + ARCCOPY(yorgp + yoffset - x * MUL); + ARCCOPY(yorgop - yoffset - x * MUL); + ARCCOPY(yorgop - yoffset + x * MUL); + } + else + { + ARCRROP(yorgp + yoffset + x * MUL); + ARCRROP(yorgp + yoffset - x * MUL); + ARCRROP(yorgop - yoffset - x * MUL); + ARCRROP(yorgop - yoffset + x * MUL); + } + if (a < 0) + break; + if (andBits == 0) + { + ARCCOPY(yorghb - xoffset - y * MUL); + ARCCOPY(yorgohb - xoffset + y * MUL); + ARCCOPY(yorgohb + xoffset + y * MUL); + ARCCOPY(yorghb + xoffset - y * MUL); + } + else + { + ARCRROP(yorghb - xoffset - y * MUL); + ARCRROP(yorgohb - xoffset + y * MUL); + ARCRROP(yorgohb + xoffset + y * MUL); + ARCRROP(yorghb + xoffset - y * MUL); + } + xoffset += bitsStride; + MIARCCIRCLESTEP(yoffset += bitsStride;); + } + yorgp -= info.xorg; + yorgop -= info.xorg; + x = info.w; + yoffset = info.h * bitsStride; + } + else if (do360) + { + while (y < info.h || x < info.w) + { + MIARCOCTANTSHIFT(dyoffset = bitsStride;); + if (andBits == 0) + { + ARCCOPY(yorgp + yoffset + info.xorg + x * MUL); + ARCCOPY(yorgp + yoffset + info.xorgo - x * MUL); + ARCCOPY(yorgop - yoffset + info.xorgo - x * MUL); + ARCCOPY(yorgop - yoffset + info.xorg + x * MUL); + } + else + { + ARCRROP(yorgp + yoffset + info.xorg + x * MUL); + ARCRROP(yorgp + yoffset + info.xorgo - x * MUL); + ARCRROP(yorgop - yoffset + info.xorgo - x * MUL); + ARCRROP(yorgop - yoffset + info.xorg + x * MUL); + } + MIARCSTEP(yoffset += dyoffset;, yoffset += bitsStride;); + } + } + else + { + while (y < info.h || x < info.w) + { + MIARCOCTANTSHIFT(dyoffset = bitsStride;); + if ((x == info.start.x) || (y == info.start.y)) + { + mask = info.start.mask; + info.start = info.altstart; + } + if (andBits == 0) + { + if (mask & 1) + ARCCOPY(yorgp + yoffset + info.xorg + x * MUL); + if (mask & 2) + ARCCOPY(yorgp + yoffset + info.xorgo - x * MUL); + if (mask & 4) + ARCCOPY(yorgop - yoffset + info.xorgo - x * MUL); + if (mask & 8) + ARCCOPY(yorgop - yoffset + info.xorg + x * MUL); + } + else + { + if (mask & 1) + ARCRROP(yorgp + yoffset + info.xorg + x * MUL); + if (mask & 2) + ARCRROP(yorgp + yoffset + info.xorgo - x * MUL); + if (mask & 4) + ARCRROP(yorgop - yoffset + info.xorgo - x * MUL); + if (mask & 8) + ARCRROP(yorgop - yoffset + info.xorg + x * MUL); + } + if ((x == info.end.x) || (y == info.end.y)) + { + mask = info.end.mask; + info.end = info.altend; + } + MIARCSTEP(yoffset += dyoffset;, yoffset += bitsStride;); + } + } + if ((x == info.start.x) || (y == info.start.y)) + mask = info.start.mask; + if (andBits == 0) + { + if (mask & 1) + ARCCOPY(yorgp + yoffset + info.xorg + x * MUL); + if (mask & 4) + ARCCOPY(yorgop - yoffset + info.xorgo - x * MUL); + if (arc->height & 1) + { + if (mask & 2) + ARCCOPY(yorgp + yoffset + info.xorgo - x * MUL); + if (mask & 8) + ARCCOPY(yorgop - yoffset + info.xorg + x * MUL); + } + } + else + { + if (mask & 1) + ARCRROP(yorgp + yoffset + info.xorg + x * MUL); + if (mask & 4) + ARCRROP(yorgop - yoffset + info.xorgo - x * MUL); + if (arc->height & 1) + { + if (mask & 2) + ARCRROP(yorgp + yoffset + info.xorgo - x * MUL); + if (mask & 8) + ARCRROP(yorgop - yoffset + info.xorg + x * MUL); + } + } +} +#undef ARCCOPY +#undef ARCRROP +#endif + +#ifdef GLYPH +#if BITMAP_BIT_ORDER == LSBFirst +# define WRITE_ADDR1(n) (n) +# define WRITE_ADDR2(n) (n) +# define WRITE_ADDR4(n) (n) +#else +# define WRITE_ADDR1(n) ((n) ^ 3) +# define WRITE_ADDR2(n) ((n) ^ 2) +# define WRITE_ADDR4(n) ((n)) +#endif + +#define WRITE1(d,n,fg) ((d)[WRITE_ADDR1(n)] = (BITS) (fg)) + +#ifdef BITS2 +# define WRITE2(d,n,fg) (*((BITS2 *) &((d)[WRITE_ADDR2(n)])) = (BITS2) (fg)) +#else +# define WRITE2(d,n,fg) WRITE1(d,(n)+1,WRITE1(d,n,fg)) +#endif + +#ifdef BITS4 +# define WRITE4(d,n,fg) (*((BITS4 *) &((d)[WRITE_ADDR4(n)])) = (BITS4) (fg)) +#else +# define WRITE4(d,n,fg) WRITE2(d,(n)+2,WRITE2(d,n,fg)) +#endif + +void +GLYPH (FbBits *dstBits, + FbStride dstStride, + int dstBpp, + FbStip *stipple, + FbBits fg, + int x, + int height) +{ + int lshift; + FbStip bits; + BITS *dstLine; + BITS *dst; + int n; + int shift; + + dstLine = (BITS *) dstBits; + dstLine += x & ~3; + dstStride *= (sizeof (FbBits) / sizeof (BITS)); + shift = x & 3; + lshift = 4 - shift; + while (height--) + { + bits = *stipple++; + dst = (BITS *) dstLine; + n = lshift; + while (bits) + { + switch (FbStipMoveLsb (FbLeftStipBits (bits, n), 4, n)) { + case 0: + break; + case 1: + WRITE1(dst,0,fg); + break; + case 2: + WRITE1(dst,1,fg); + break; + case 3: + WRITE2(dst,0,fg); + break; + case 4: + WRITE1(dst,2,fg); + break; + case 5: + WRITE1(dst,0,fg); + WRITE1(dst,2,fg); + break; + case 6: + WRITE1(dst,1,fg); + WRITE1(dst,2,fg); + break; + case 7: + WRITE2(dst,0,fg); + WRITE1(dst,2,fg); + break; + case 8: + WRITE1(dst,3,fg); + break; + case 9: + WRITE1(dst,0,fg); + WRITE1(dst,3,fg); + break; + case 10: + WRITE1(dst,1,fg); + WRITE1(dst,3,fg); + break; + case 11: + WRITE2(dst,0,fg); + WRITE1(dst,3,fg); + break; + case 12: + WRITE2(dst,2,fg); + break; + case 13: + WRITE1(dst,0,fg); + WRITE2(dst,2,fg); + break; + case 14: + WRITE1(dst,1,fg); + WRITE2(dst,2,fg); + break; + case 15: + WRITE4(dst,0,fg); + break; + } + bits = FbStipLeft (bits, n); + n = 4; + dst += 4; + } + dstLine += dstStride; + } +} +#undef WRITE_ADDR1 +#undef WRITE_ADDR2 +#undef WRITE_ADDR4 +#undef WRITE1 +#undef WRITE2 +#undef WRITE4 + +#endif + +#ifdef POLYLINE +void +POLYLINE (DrawablePtr pDrawable, + GCPtr pGC, + int mode, + int npt, + DDXPointPtr ptsOrig) +{ + INT32 *pts = (INT32 *) ptsOrig; + int xoff = pDrawable->x; + int yoff = pDrawable->y; + unsigned int bias = miGetZeroLineBias(pDrawable->pScreen); + BoxPtr pBox = RegionExtents(fbGetCompositeClip (pGC)); + + FbBits *dst; + int dstStride; + int dstBpp; + int dstXoff, dstYoff; + + UNIT *bits, *bitsBase; + FbStride bitsStride; + BITS xor = fbGetGCPrivate(pGC)->xor; + BITS and = fbGetGCPrivate(pGC)->and; + int dashoffset = 0; + + INT32 ul, lr; + INT32 pt1, pt2; + + int e, e1, e3, len; + int stepmajor, stepminor; + int octant; + + if (mode == CoordModePrevious) + fbFixCoordModePrevious (npt, ptsOrig); + + fbGetDrawable (pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff); + bitsStride = dstStride * (sizeof (FbBits) / sizeof (UNIT)); + bitsBase = ((UNIT *) dst) + (yoff + dstYoff) * bitsStride + (xoff + dstXoff) * MUL; + ul = coordToInt(pBox->x1 - xoff, pBox->y1 - yoff); + lr = coordToInt(pBox->x2 - xoff - 1, pBox->y2 - yoff - 1); + + pt1 = *pts++; + npt--; + pt2 = *pts++; + npt--; + for (;;) + { + if (isClipped (pt1, ul, lr) | isClipped (pt2, ul, lr)) + { + fbSegment (pDrawable, pGC, + intToX(pt1) + xoff, intToY(pt1) + yoff, + intToX(pt2) + xoff, intToY(pt2) + yoff, + npt == 0 && pGC->capStyle != CapNotLast, + &dashoffset); + if (!npt) + return; + pt1 = pt2; + pt2 = *pts++; + npt--; + } + else + { + bits = bitsBase + intToY(pt1) * bitsStride + intToX(pt1) * MUL; + for (;;) + { + CalcLineDeltas (intToX(pt1), intToY(pt1), + intToX(pt2), intToY(pt2), + len, e1, stepmajor, stepminor, 1, bitsStride, + octant); + stepmajor *= MUL; + if (len < e1) + { + e3 = len; + len = e1; + e1 = e3; + + e3 = stepminor; + stepminor = stepmajor; + stepmajor = e3; + SetYMajorOctant(octant); + } + e = -len; + e1 <<= 1; + e3 = e << 1; + FIXUP_ERROR (e, octant, bias); + if (and == 0) + { + while (len--) + { + STORE(bits,xor); + bits += stepmajor; + e += e1; + if (e >= 0) + { + bits += stepminor; + e += e3; + } + } + } + else + { + while (len--) + { + RROP(bits,and,xor); + bits += stepmajor; + e += e1; + if (e >= 0) + { + bits += stepminor; + e += e3; + } + } + } + if (!npt) + { + if (pGC->capStyle != CapNotLast && + pt2 != *((INT32 *) ptsOrig)) + { + RROP(bits,and,xor); + } + return; + } + pt1 = pt2; + pt2 = *pts++; + --npt; + if (isClipped (pt2, ul, lr)) + break; + } + } + } +} +#endif + +#ifdef POLYSEGMENT +void +POLYSEGMENT (DrawablePtr pDrawable, + GCPtr pGC, + int nseg, + xSegment *pseg) +{ + INT32 *pts = (INT32 *) pseg; + int xoff = pDrawable->x; + int yoff = pDrawable->y; + unsigned int bias = miGetZeroLineBias(pDrawable->pScreen); + BoxPtr pBox = RegionExtents(fbGetCompositeClip (pGC)); + + FbBits *dst; + int dstStride; + int dstBpp; + int dstXoff, dstYoff; + + UNIT *bits, *bitsBase; + FbStride bitsStride; + FbBits xorBits = fbGetGCPrivate(pGC)->xor; + FbBits andBits = fbGetGCPrivate(pGC)->and; + BITS xor = xorBits; + BITS and = andBits; + int dashoffset = 0; + + INT32 ul, lr; + INT32 pt1, pt2; + + int e, e1, e3, len; + int stepmajor, stepminor; + int octant; + Bool capNotLast; + + fbGetDrawable (pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff); + bitsStride = dstStride * (sizeof (FbBits) / sizeof (UNIT)); + bitsBase = ((UNIT *) dst) + (yoff + dstYoff) * bitsStride + (xoff + dstXoff) * MUL; + ul = coordToInt(pBox->x1 - xoff, pBox->y1 - yoff); + lr = coordToInt(pBox->x2 - xoff - 1, pBox->y2 - yoff - 1); + + capNotLast = pGC->capStyle == CapNotLast; + + while (nseg--) + { + pt1 = *pts++; + pt2 = *pts++; + if (isClipped (pt1, ul, lr) | isClipped (pt2, ul, lr)) + { + fbSegment (pDrawable, pGC, + intToX(pt1) + xoff, intToY(pt1) + yoff, + intToX(pt2) + xoff, intToY(pt2) + yoff, + !capNotLast, &dashoffset); + } + else + { + CalcLineDeltas (intToX(pt1), intToY(pt1), + intToX(pt2), intToY(pt2), + len, e1, stepmajor, stepminor, 1, bitsStride, + octant); + if (e1 == 0 && len > 3 +#if MUL != 1 + && FbCheck24Pix(and) && FbCheck24Pix(xor) +#endif + ) + { + int x1, x2; + FbBits *dstLine; + int dstX, width; + FbBits startmask, endmask; + int nmiddle; + + if (stepmajor < 0) + { + x1 = intToX(pt2); + x2 = intToX(pt1) + 1; + if (capNotLast) + x1++; + } + else + { + x1 = intToX(pt1); + x2 = intToX(pt2); + if (!capNotLast) + x2++; + } + dstX = (x1 + xoff + dstXoff) * (sizeof (UNIT) * 8 * MUL); + width = (x2 - x1) * (sizeof (UNIT) * 8 * MUL); + + dstLine = dst + (intToY(pt1) + yoff + dstYoff) * dstStride; + dstLine += dstX >> FB_SHIFT; + dstX &= FB_MASK; + FbMaskBits (dstX, width, startmask, nmiddle, endmask); + if (startmask) + { + *dstLine = FbDoMaskRRop (*dstLine, andBits, xorBits, startmask); + dstLine++; + } + if (!andBits) + while (nmiddle--) + *dstLine++ = xorBits; + else + while (nmiddle--) + { + *dstLine = FbDoRRop (*dstLine, andBits, xorBits); + dstLine++; + } + if (endmask) + *dstLine = FbDoMaskRRop (*dstLine, andBits, xorBits, endmask); + } + else + { + stepmajor *= MUL; + bits = bitsBase + intToY(pt1) * bitsStride + intToX(pt1) * MUL; + if (len < e1) + { + e3 = len; + len = e1; + e1 = e3; + + e3 = stepminor; + stepminor = stepmajor; + stepmajor = e3; + SetYMajorOctant(octant); + } + e = -len; + e1 <<= 1; + e3 = e << 1; + FIXUP_ERROR (e, octant, bias); + if (!capNotLast) + len++; + if (and == 0) + { + while (len--) + { + STORE(bits,xor); + bits += stepmajor; + e += e1; + if (e >= 0) + { + bits += stepminor; + e += e3; + } + } + } + else + { + while (len--) + { + RROP(bits,and,xor); + bits += stepmajor; + e += e1; + if (e >= 0) + { + bits += stepminor; + e += e3; + } + } + } + } + } + } +} +#endif + +#undef MUL +#undef STORE +#undef RROP +#undef UNIT +#undef USE_SOLID + +#undef isClipped diff --git a/nx-X11/programs/Xserver/fb/fbblt.c b/nx-X11/programs/Xserver/fb/fbblt.c new file mode 100644 index 000000000..085a8e639 --- /dev/null +++ b/nx-X11/programs/Xserver/fb/fbblt.c @@ -0,0 +1,932 @@ +/* + * Id: fbblt.c,v 1.1 1999/11/02 03:54:45 keithp Exp $ + * + * 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" + +#define InitializeShifts(sx,dx,ls,rs) { \ + if (sx != dx) { \ + if (sx > dx) { \ + ls = sx - dx; \ + rs = FB_UNIT - ls; \ + } else { \ + rs = dx - sx; \ + ls = FB_UNIT - rs; \ + } \ + } \ +} + +void +fbBlt (FbBits *srcLine, + FbStride srcStride, + int srcX, + + FbBits *dstLine, + FbStride dstStride, + int dstX, + + int width, + int height, + + int alu, + FbBits pm, + int bpp, + + Bool reverse, + Bool upsidedown) +{ + FbBits *src, *dst; + int leftShift, rightShift; + FbBits startmask, endmask; + FbBits bits, bits1; + int n, nmiddle; + Bool destInvarient; + int startbyte, endbyte; + FbDeclareMergeRop (); + +#ifdef FB_24BIT + if (bpp == 24 && !FbCheck24Pix (pm)) + { + fbBlt24 (srcLine, srcStride, srcX, dstLine, dstStride, dstX, + width, height, alu, pm, reverse, upsidedown); + return; + } +#endif + FbInitializeMergeRop(alu, pm); + destInvarient = FbDestInvarientMergeRop(); + if (upsidedown) + { + srcLine += (height - 1) * (srcStride); + dstLine += (height - 1) * (dstStride); + srcStride = -srcStride; + dstStride = -dstStride; + } + FbMaskBitsBytes (dstX, width, destInvarient, startmask, startbyte, + nmiddle, endmask, endbyte); + if (reverse) + { + srcLine += ((srcX + width - 1) >> FB_SHIFT) + 1; + dstLine += ((dstX + width - 1) >> FB_SHIFT) + 1; + srcX = (srcX + width - 1) & FB_MASK; + dstX = (dstX + width - 1) & FB_MASK; + } + else + { + srcLine += srcX >> FB_SHIFT; + dstLine += dstX >> FB_SHIFT; + srcX &= FB_MASK; + dstX &= FB_MASK; + } + if (srcX == dstX) + { + while (height--) + { + src = srcLine; + srcLine += srcStride; + dst = dstLine; + dstLine += dstStride; + if (reverse) + { + if (endmask) + { + bits = *--src; + --dst; + FbDoRightMaskByteMergeRop(dst, bits, endbyte, endmask); + } + n = nmiddle; + if (destInvarient) + { + while (n--) + *--dst = FbDoDestInvarientMergeRop(*--src); + } + else + { + while (n--) + { + bits = *--src; + --dst; + *dst = FbDoMergeRop (bits, *dst); + } + } + if (startmask) + { + bits = *--src; + --dst; + FbDoLeftMaskByteMergeRop(dst, bits, startbyte, startmask); + } + } + else + { + if (startmask) + { + bits = *src++; + FbDoLeftMaskByteMergeRop(dst, bits, startbyte, startmask); + dst++; + } + n = nmiddle; + if (destInvarient) + { +#if 0 + /* + * This provides some speedup on screen->screen blts + * over the PCI bus, usually about 10%. But fb + * isn't usually used for this operation... + */ + if (_ca2 + 1 == 0 && _cx2 == 0) + { + FbBits t1, t2, t3, t4; + while (n >= 4) + { + t1 = *src++; + t2 = *src++; + t3 = *src++; + t4 = *src++; + *dst++ = t1; + *dst++ = t2; + *dst++ = t3; + *dst++ = t4; + n -= 4; + } + } +#endif + while (n--) + *dst++ = FbDoDestInvarientMergeRop(*src++); + } + else + { + while (n--) + { + bits = *src++; + *dst = FbDoMergeRop (bits, *dst); + dst++; + } + } + if (endmask) + { + bits = *src; + FbDoRightMaskByteMergeRop(dst, bits, endbyte, endmask); + } + } + } + } + else + { + if (srcX > dstX) + { + leftShift = srcX - dstX; + rightShift = FB_UNIT - leftShift; + } + else + { + rightShift = dstX - srcX; + leftShift = FB_UNIT - rightShift; + } + while (height--) + { + src = srcLine; + srcLine += srcStride; + dst = dstLine; + dstLine += dstStride; + + bits1 = 0; + if (reverse) + { + if (srcX < dstX) + bits1 = *--src; + if (endmask) + { + bits = FbScrRight(bits1, rightShift); + if (FbScrRight(endmask, leftShift)) + { + bits1 = *--src; + bits |= FbScrLeft(bits1, leftShift); + } + --dst; + FbDoRightMaskByteMergeRop(dst, bits, endbyte, endmask); + } + n = nmiddle; + if (destInvarient) + { + while (n--) + { + bits = FbScrRight(bits1, rightShift); + bits1 = *--src; + bits |= FbScrLeft(bits1, leftShift); + --dst; + *dst = FbDoDestInvarientMergeRop(bits); + } + } + else + { + while (n--) + { + bits = FbScrRight(bits1, rightShift); + bits1 = *--src; + bits |= FbScrLeft(bits1, leftShift); + --dst; + *dst = FbDoMergeRop(bits, *dst); + } + } + if (startmask) + { + bits = FbScrRight(bits1, rightShift); + if (FbScrRight(startmask, leftShift)) + { + bits1 = *--src; + bits |= FbScrLeft(bits1, leftShift); + } + --dst; + FbDoLeftMaskByteMergeRop (dst, bits, startbyte, startmask); + } + } + else + { + if (srcX > dstX) + bits1 = *src++; + if (startmask) + { + bits = FbScrLeft(bits1, leftShift); + if (FbScrLeft(startmask, rightShift)) + { + bits1 = *src++; + bits |= FbScrRight(bits1, rightShift); + } + FbDoLeftMaskByteMergeRop (dst, bits, startbyte, startmask); + dst++; + } + n = nmiddle; + if (destInvarient) + { + while (n--) + { + bits = FbScrLeft(bits1, leftShift); + bits1 = *src++; + bits |= FbScrRight(bits1, rightShift); + *dst = FbDoDestInvarientMergeRop(bits); + dst++; + } + } + else + { + while (n--) + { + bits = FbScrLeft(bits1, leftShift); + bits1 = *src++; + bits |= FbScrRight(bits1, rightShift); + *dst = FbDoMergeRop(bits, *dst); + dst++; + } + } + if (endmask) + { + bits = FbScrLeft(bits1, leftShift); + if (FbScrLeft(endmask, rightShift)) + { + bits1 = *src; + bits |= FbScrRight(bits1, rightShift); + } + FbDoRightMaskByteMergeRop (dst, bits, endbyte, endmask); + } + } + } + } +} + +#ifdef FB_24BIT + +#undef DEBUG_BLT24 +#ifdef DEBUG_BLT24 + +static unsigned long +getPixel (char *src, int x) +{ + unsigned long l; + + l = 0; + memcpy (&l, src + x * 3, 3); + return l; +} +#endif + +static void +fbBlt24Line (FbBits *src, + int srcX, + + FbBits *dst, + int dstX, + + int width, + + int alu, + FbBits pm, + + Bool reverse) +{ +#ifdef DEBUG_BLT24 + char *origDst = (char *) dst; + FbBits *origLine = dst + ((dstX >> FB_SHIFT) - 1); + int origNlw = ((width + FB_MASK) >> FB_SHIFT) + 3; + int origX = dstX / 24; +#endif + + int leftShift, rightShift; + FbBits startmask, endmask; + int n; + + FbBits bits, bits1; + FbBits mask; + + int rot; + FbDeclareMergeRop (); + + FbInitializeMergeRop (alu, FB_ALLONES); + FbMaskBits(dstX, width, startmask, n, endmask); +#ifdef DEBUG_BLT24 + ErrorF ("dstX %d width %d reverse %d\n", dstX, width, reverse); +#endif + if (reverse) + { + src += ((srcX + width - 1) >> FB_SHIFT) + 1; + dst += ((dstX + width - 1) >> FB_SHIFT) + 1; + rot = FbFirst24Rot (((dstX + width - 8) & FB_MASK)); + rot = FbPrev24Rot(rot); +#ifdef DEBUG_BLT24 + ErrorF ("dstX + width - 8: %d rot: %d\n", (dstX + width - 8) & FB_MASK, rot); +#endif + srcX = (srcX + width - 1) & FB_MASK; + dstX = (dstX + width - 1) & FB_MASK; + } + else + { + src += srcX >> FB_SHIFT; + dst += dstX >> FB_SHIFT; + srcX &= FB_MASK; + dstX &= FB_MASK; + rot = FbFirst24Rot (dstX); +#ifdef DEBUG_BLT24 + ErrorF ("dstX: %d rot: %d\n", dstX, rot); +#endif + } + mask = FbRot24(pm,rot); +#ifdef DEBUG_BLT24 + ErrorF ("pm 0x%x mask 0x%x\n", pm, mask); +#endif + if (srcX == dstX) + { + if (reverse) + { + if (endmask) + { + bits = *--src; + --dst; + *dst = FbDoMaskMergeRop (bits, *dst, mask & endmask); + mask = FbPrev24Pix (mask); + } + while (n--) + { + bits = *--src; + --dst; + *dst = FbDoMaskMergeRop (bits, *dst, mask); + mask = FbPrev24Pix (mask); + } + if (startmask) + { + bits = *--src; + --dst; + *dst = FbDoMaskMergeRop(bits, *dst, mask & startmask); + } + } + else + { + if (startmask) + { + bits = *src++; + *dst = FbDoMaskMergeRop (bits, *dst, mask & startmask); + dst++; + mask = FbNext24Pix(mask); + } + while (n--) + { + bits = *src++; + *dst = FbDoMaskMergeRop (bits, *dst, mask); + dst++; + mask = FbNext24Pix(mask); + } + if (endmask) + { + bits = *src; + *dst = FbDoMaskMergeRop(bits, *dst, mask & endmask); + } + } + } + else + { + if (srcX > dstX) + { + leftShift = srcX - dstX; + rightShift = FB_UNIT - leftShift; + } + else + { + rightShift = dstX - srcX; + leftShift = FB_UNIT - rightShift; + } + + bits1 = 0; + if (reverse) + { + if (srcX < dstX) + bits1 = *--src; + if (endmask) + { + bits = FbScrRight(bits1, rightShift); + if (FbScrRight(endmask, leftShift)) + { + bits1 = *--src; + bits |= FbScrLeft(bits1, leftShift); + } + --dst; + *dst = FbDoMaskMergeRop (bits, *dst, mask & endmask); + mask = FbPrev24Pix(mask); + } + while (n--) + { + bits = FbScrRight(bits1, rightShift); + bits1 = *--src; + bits |= FbScrLeft(bits1, leftShift); + --dst; + *dst = FbDoMaskMergeRop(bits, *dst, mask); + mask = FbPrev24Pix(mask); + } + if (startmask) + { + bits = FbScrRight(bits1, rightShift); + if (FbScrRight(startmask, leftShift)) + { + bits1 = *--src; + bits |= FbScrLeft(bits1, leftShift); + } + --dst; + *dst = FbDoMaskMergeRop (bits, *dst, mask & startmask); + } + } + else + { + if (srcX > dstX) + bits1 = *src++; + if (startmask) + { + bits = FbScrLeft(bits1, leftShift); + bits1 = *src++; + bits |= FbScrRight(bits1, rightShift); + *dst = FbDoMaskMergeRop (bits, *dst, mask & startmask); + dst++; + mask = FbNext24Pix(mask); + } + while (n--) + { + bits = FbScrLeft(bits1, leftShift); + bits1 = *src++; + bits |= FbScrRight(bits1, rightShift); + *dst = FbDoMaskMergeRop(bits, *dst, mask); + dst++; + mask = FbNext24Pix(mask); + } + if (endmask) + { + bits = FbScrLeft(bits1, leftShift); + if (FbScrLeft(endmask, rightShift)) + { + bits1 = *src; + bits |= FbScrRight(bits1, rightShift); + } + *dst = FbDoMaskMergeRop (bits, *dst, mask & endmask); + } + } + } +#ifdef DEBUG_BLT24 + { + int firstx, lastx, x; + + firstx = origX; + if (firstx) + firstx--; + lastx = origX + width/24 + 1; + for (x = firstx; x <= lastx; x++) + ErrorF ("%06x ", getPixel (origDst, x)); + ErrorF ("\n"); + while (origNlw--) + ErrorF ("%08x ", *origLine++); + ErrorF ("\n"); + } +#endif +} + +void +fbBlt24 (FbBits *srcLine, + FbStride srcStride, + int srcX, + + FbBits *dstLine, + FbStride dstStride, + int dstX, + + int width, + int height, + + int alu, + FbBits pm, + + Bool reverse, + Bool upsidedown) +{ + if (upsidedown) + { + srcLine += (height-1) * srcStride; + dstLine += (height-1) * dstStride; + srcStride = -srcStride; + dstStride = -dstStride; + } + while (height--) + { + fbBlt24Line (srcLine, srcX, dstLine, dstX, width, alu, pm, reverse); + srcLine += srcStride; + dstLine += dstStride; + } +#ifdef DEBUG_BLT24 + ErrorF ("\n"); +#endif +} +#endif /* FB_24BIT */ + +#if FB_SHIFT == FB_STIP_SHIFT + 1 + +/* + * Could be generalized to FB_SHIFT > FB_STIP_SHIFT + 1 by + * creating an ring of values stepped through for each line + */ + +void +fbBltOdd (FbBits *srcLine, + FbStride srcStrideEven, + FbStride srcStrideOdd, + int srcXEven, + int srcXOdd, + + FbBits *dstLine, + FbStride dstStrideEven, + FbStride dstStrideOdd, + int dstXEven, + int dstXOdd, + + int width, + int height, + + int alu, + FbBits pm, + int bpp) +{ + FbBits *src; + int leftShiftEven, rightShiftEven; + FbBits startmaskEven, endmaskEven; + int nmiddleEven; + + FbBits *dst; + int leftShiftOdd, rightShiftOdd; + FbBits startmaskOdd, endmaskOdd; + int nmiddleOdd; + + int leftShift, rightShift; + FbBits startmask, endmask; + int nmiddle; + + int srcX, dstX; + + FbBits bits, bits1; + int n; + + Bool destInvarient; + Bool even; + FbDeclareMergeRop (); + + FbInitializeMergeRop (alu, pm); + destInvarient = FbDestInvarientMergeRop(); + + srcLine += srcXEven >> FB_SHIFT; + dstLine += dstXEven >> FB_SHIFT; + srcXEven &= FB_MASK; + dstXEven &= FB_MASK; + srcXOdd &= FB_MASK; + dstXOdd &= FB_MASK; + + FbMaskBits(dstXEven, width, startmaskEven, nmiddleEven, endmaskEven); + FbMaskBits(dstXOdd, width, startmaskOdd, nmiddleOdd, endmaskOdd); + + even = TRUE; + InitializeShifts(srcXEven, dstXEven, leftShiftEven, rightShiftEven); + InitializeShifts(srcXOdd, dstXOdd, leftShiftOdd, rightShiftOdd); + while (height--) + { + src = srcLine; + dst = dstLine; + if (even) + { + srcX = srcXEven; + dstX = dstXEven; + startmask = startmaskEven; + endmask = endmaskEven; + nmiddle = nmiddleEven; + leftShift = leftShiftEven; + rightShift = rightShiftEven; + srcLine += srcStrideEven; + dstLine += dstStrideEven; + even = FALSE; + } + else + { + srcX = srcXOdd; + dstX = dstXOdd; + startmask = startmaskOdd; + endmask = endmaskOdd; + nmiddle = nmiddleOdd; + leftShift = leftShiftOdd; + rightShift = rightShiftOdd; + srcLine += srcStrideOdd; + dstLine += dstStrideOdd; + even = TRUE; + } + if (srcX == dstX) + { + if (startmask) + { + bits = *src++; + *dst = FbDoMaskMergeRop (bits, *dst, startmask); + dst++; + } + n = nmiddle; + if (destInvarient) + { + while (n--) + { + bits = *src++; + *dst = FbDoDestInvarientMergeRop(bits); + dst++; + } + } + else + { + while (n--) + { + bits = *src++; + *dst = FbDoMergeRop (bits, *dst); + dst++; + } + } + if (endmask) + { + bits = *src; + *dst = FbDoMaskMergeRop(bits, *dst, endmask); + } + } + else + { + bits = 0; + if (srcX > dstX) + bits = *src++; + if (startmask) + { + bits1 = FbScrLeft(bits, leftShift); + bits = *src++; + bits1 |= FbScrRight(bits, rightShift); + *dst = FbDoMaskMergeRop (bits1, *dst, startmask); + dst++; + } + n = nmiddle; + if (destInvarient) + { + while (n--) + { + bits1 = FbScrLeft(bits, leftShift); + bits = *src++; + bits1 |= FbScrRight(bits, rightShift); + *dst = FbDoDestInvarientMergeRop(bits1); + dst++; + } + } + else + { + while (n--) + { + bits1 = FbScrLeft(bits, leftShift); + bits = *src++; + bits1 |= FbScrRight(bits, rightShift); + *dst = FbDoMergeRop(bits1, *dst); + dst++; + } + } + if (endmask) + { + bits1 = FbScrLeft(bits, leftShift); + if (FbScrLeft(endmask, rightShift)) + { + bits = *src; + bits1 |= FbScrRight(bits, rightShift); + } + *dst = FbDoMaskMergeRop (bits1, *dst, endmask); + } + } + } +} + +#ifdef FB_24BIT +void +fbBltOdd24 (FbBits *srcLine, + FbStride srcStrideEven, + FbStride srcStrideOdd, + int srcXEven, + int srcXOdd, + + FbBits *dstLine, + FbStride dstStrideEven, + FbStride dstStrideOdd, + int dstXEven, + int dstXOdd, + + int width, + int height, + + int alu, + FbBits pm) +{ + Bool even = TRUE; + + while (height--) + { + if (even) + { + fbBlt24Line (srcLine, srcXEven, dstLine, dstXEven, + width, alu, pm, FALSE); + srcLine += srcStrideEven; + dstLine += dstStrideEven; + even = FALSE; + } + else + { + fbBlt24Line (srcLine, srcXOdd, dstLine, dstXOdd, + width, alu, pm, FALSE); + srcLine += srcStrideOdd; + dstLine += dstStrideOdd; + even = TRUE; + } + } +#if 0 + fprintf (stderr, "\n"); +#endif +} +#endif + +#endif + +#if FB_STIP_SHIFT != FB_SHIFT +void +fbSetBltOdd (FbStip *stip, + FbStride stipStride, + int srcX, + FbBits **bits, + FbStride *strideEven, + FbStride *strideOdd, + int *srcXEven, + int *srcXOdd) +{ + int srcAdjust; + int strideAdjust; + + /* + * bytes needed to align source + */ + srcAdjust = (((int) stip) & (FB_MASK >> 3)); + /* + * FbStip units needed to align stride + */ + strideAdjust = stipStride & (FB_MASK >> FB_STIP_SHIFT); + + *bits = (FbBits *) ((char *) stip - srcAdjust); + if (srcAdjust) + { + *strideEven = FbStipStrideToBitsStride (stipStride + 1); + *strideOdd = FbStipStrideToBitsStride (stipStride); + + *srcXEven = srcX + (srcAdjust << 3); + *srcXOdd = srcX + (srcAdjust << 3) - (strideAdjust << FB_STIP_SHIFT); + } + else + { + *strideEven = FbStipStrideToBitsStride (stipStride); + *strideOdd = FbStipStrideToBitsStride (stipStride + 1); + + *srcXEven = srcX; + *srcXOdd = srcX + (strideAdjust << FB_STIP_SHIFT); + } +} +#endif + +void +fbBltStip (FbStip *src, + FbStride srcStride, /* in FbStip units, not FbBits units */ + int srcX, + + FbStip *dst, + FbStride dstStride, /* in FbStip units, not FbBits units */ + int dstX, + + int width, + int height, + + int alu, + FbBits pm, + int bpp) +{ +#if FB_STIP_SHIFT != FB_SHIFT + if (FB_STIP_ODDSTRIDE(srcStride) || FB_STIP_ODDPTR(src) || + FB_STIP_ODDSTRIDE(dstStride) || FB_STIP_ODDPTR(dst)) + { + FbStride srcStrideEven, srcStrideOdd; + FbStride dstStrideEven, dstStrideOdd; + int srcXEven, srcXOdd; + int dstXEven, dstXOdd; + FbBits *s, *d; + int sx, dx; + + src += srcX >> FB_STIP_SHIFT; + srcX &= FB_STIP_MASK; + dst += dstX >> FB_STIP_SHIFT; + dstX &= FB_STIP_MASK; + + fbSetBltOdd (src, srcStride, srcX, + &s, + &srcStrideEven, &srcStrideOdd, + &srcXEven, &srcXOdd); + + fbSetBltOdd (dst, dstStride, dstX, + &d, + &dstStrideEven, &dstStrideOdd, + &dstXEven, &dstXOdd); + +#ifdef FB_24BIT + if (bpp == 24 && !FbCheck24Pix (pm)) + { + fbBltOdd24 (s, srcStrideEven, srcStrideOdd, + srcXEven, srcXOdd, + + d, dstStrideEven, dstStrideOdd, + dstXEven, dstXOdd, + + width, height, alu, pm); + } + else +#endif + { + fbBltOdd (s, srcStrideEven, srcStrideOdd, + srcXEven, srcXOdd, + + d, dstStrideEven, dstStrideOdd, + dstXEven, dstXOdd, + + width, height, alu, pm, bpp); + } + } + else +#endif + { + fbBlt ((FbBits *) src, FbStipStrideToBitsStride (srcStride), + srcX, + (FbBits *) dst, FbStipStrideToBitsStride (dstStride), + dstX, + width, height, + alu, pm, bpp, FALSE, FALSE); + } +} diff --git a/nx-X11/programs/Xserver/fb/fbbltone.c b/nx-X11/programs/Xserver/fb/fbbltone.c new file mode 100644 index 000000000..f06357a37 --- /dev/null +++ b/nx-X11/programs/Xserver/fb/fbbltone.c @@ -0,0 +1,879 @@ +/* + * Id: fbbltone.c,v 1.1 1999/11/02 03:54:45 keithp Exp $ + * + * 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" + +/* + * Example: srcX = 13 dstX = 8 (FB unit 32 dstBpp 8) + * + * **** **** **** **** **** **** **** **** + * ^ + * ******** ******** ******** ******** + * ^ + * leftShift = 12 + * rightShift = 20 + * + * Example: srcX = 0 dstX = 8 (FB unit 32 dstBpp 8) + * + * **** **** **** **** **** **** **** **** + * ^ + * ******** ******** ******** ******** + * ^ + * + * leftShift = 24 + * rightShift = 8 + */ + +#define LoadBits {\ + if (leftShift) { \ + bitsRight = (src < srcEnd ? *src++ : 0); \ + bits = (FbStipLeft (bitsLeft, leftShift) | \ + FbStipRight(bitsRight, rightShift)); \ + bitsLeft = bitsRight; \ + } else \ + bits = (src < srcEnd ? *src++ : 0); \ +} + +#ifndef FBNOPIXADDR + +#define LaneCases1(n,a) case n: (void)FbLaneCase(n,a); break +#define LaneCases2(n,a) LaneCases1(n,a); LaneCases1(n+1,a) +#define LaneCases4(n,a) LaneCases2(n,a); LaneCases2(n+2,a) +#define LaneCases8(n,a) LaneCases4(n,a); LaneCases4(n+4,a) +#define LaneCases16(n,a) LaneCases8(n,a); LaneCases8(n+8,a) +#define LaneCases32(n,a) LaneCases16(n,a); LaneCases16(n+16,a) +#define LaneCases64(n,a) LaneCases32(n,a); LaneCases32(n+32,a) +#define LaneCases128(n,a) LaneCases64(n,a); LaneCases64(n+64,a) +#define LaneCases256(n,a) LaneCases128(n,a); LaneCases128(n+128,a) + +#if FB_SHIFT == 6 +#define LaneCases(a) LaneCases256(0,a) +#endif + +#if FB_SHIFT == 5 +#define LaneCases(a) LaneCases16(0,a) +#endif + +#if FB_SHIFT == 6 +CARD8 fb8Lane[256] = { +0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, +22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, +41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, +60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, +79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, +98, 99, 100, 101, 102,103,104,105,106,107,108,109,110,111,112,113,114,115, +116, 117, 118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133, +134, 135, 136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151, +152, 153, 154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169, +170, 171, 172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187, +188, 189, 190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205, +206, 207, 208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223, +224, 225, 226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241, +242, 243, 244,245,246,247,248,249,250,251,252,253,254,255, +}; + +CARD8 fb16Lane[256] = { + 0x00, 0x03, 0x0c, 0x0f, + 0x30, 0x33, 0x3c, 0x3f, + 0xc0, 0xc3, 0xcc, 0xcf, + 0xf0, 0xf3, 0xfc, 0xff, +}; + +CARD8 fb32Lane[16] = { + 0x00, 0x0f, 0xf0, 0xff, +}; +#endif + +#if FB_SHIFT == 5 +CARD8 fb8Lane[16] = { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 +}; + +CARD8 fb16Lane[16] = { + 0, 3, 12, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +}; + +CARD8 fb32Lane[16] = { + 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +}; +#endif + +CARD8 *fbLaneTable[33] = { + 0, 0, 0, 0, 0, 0, 0, 0, + fb8Lane, 0, 0, 0, 0, 0, 0, 0, + fb16Lane, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + fb32Lane +}; +#endif + +void +fbBltOne (FbStip *src, + FbStride srcStride, /* FbStip units per scanline */ + int srcX, /* bit position of source */ + FbBits *dst, + FbStride dstStride, /* FbBits units per scanline */ + int dstX, /* bit position of dest */ + int dstBpp, /* bits per destination unit */ + + int width, /* width in bits of destination */ + int height, /* height in scanlines */ + + FbBits fgand, /* rrop values */ + FbBits fgxor, + FbBits bgand, + FbBits bgxor) +{ + const FbBits *fbBits; + FbBits *srcEnd; + int pixelsPerDst; /* dst pixels per FbBits */ + int unitsPerSrc; /* src patterns per FbStip */ + int leftShift, rightShift; /* align source with dest */ + FbBits startmask, endmask; /* dest scanline masks */ + FbStip bits=0, bitsLeft, bitsRight;/* source bits */ + FbStip left; + FbBits mask; + int nDst; /* dest longwords (w.o. end) */ + int w; + int n, nmiddle; + int dstS; /* stipple-relative dst X coordinate */ + Bool copy; /* accelerate dest-invariant */ + Bool transparent; /* accelerate 0 nop */ + int srcinc; /* source units consumed */ + Bool endNeedsLoad = FALSE; /* need load for endmask */ +#ifndef FBNOPIXADDR + CARD8 *fbLane; +#endif + int startbyte, endbyte; + +#ifdef FB_24BIT + if (dstBpp == 24) + { + fbBltOne24 (src, srcStride, srcX, + dst, dstStride, dstX, dstBpp, + width, height, + fgand, fgxor, bgand, bgxor); + return; + } +#endif + + /* + * Do not read past the end of the buffer! + */ + srcEnd = src + height * srcStride; + + /* + * Number of destination units in FbBits == number of stipple pixels + * used each time + */ + pixelsPerDst = FB_UNIT / dstBpp; + + /* + * Number of source stipple patterns in FbStip + */ + unitsPerSrc = FB_STIP_UNIT / pixelsPerDst; + + copy = FALSE; + transparent = FALSE; + if (bgand == 0 && fgand == 0) + copy = TRUE; + else if (bgand == FB_ALLONES && bgxor == 0) + transparent = TRUE; + + /* + * Adjust source and dest to nearest FbBits boundary + */ + src += srcX >> FB_STIP_SHIFT; + dst += dstX >> FB_SHIFT; + srcX &= FB_STIP_MASK; + dstX &= FB_MASK; + + FbMaskBitsBytes(dstX, width, copy, + startmask, startbyte, nmiddle, endmask, endbyte); + + /* + * Compute effective dest alignment requirement for + * source -- must align source to dest unit boundary + */ + dstS = dstX / dstBpp; + /* + * Compute shift constants for effective alignement + */ + if (srcX >= dstS) + { + leftShift = srcX - dstS; + rightShift = FB_STIP_UNIT - leftShift; + } + else + { + rightShift = dstS - srcX; + leftShift = FB_STIP_UNIT - rightShift; + } + /* + * Get pointer to stipple mask array for this depth + */ + fbBits = 0; /* unused */ + if (pixelsPerDst <= 8) + fbBits = fbStippleTable[pixelsPerDst]; +#ifndef FBNOPIXADDR + fbLane = 0; + if (transparent && fgand == 0 && dstBpp >= 8) + fbLane = fbLaneTable[dstBpp]; +#endif + + /* + * Compute total number of destination words written, but + * don't count endmask + */ + nDst = nmiddle; + if (startmask) + nDst++; + + dstStride -= nDst; + + /* + * Compute total number of source words consumed + */ + + srcinc = (nDst + unitsPerSrc - 1) / unitsPerSrc; + + if (srcX > dstS) + srcinc++; + if (endmask) + { + endNeedsLoad = nDst % unitsPerSrc == 0; + if (endNeedsLoad) + srcinc++; + } + + srcStride -= srcinc; + + /* + * Copy rectangle + */ + while (height--) + { + w = nDst; /* total units across scanline */ + n = unitsPerSrc; /* units avail in single stipple */ + if (n > w) + n = w; + + bitsLeft = 0; + if (srcX > dstS) + bitsLeft = *src++; + if (n) + { + /* + * Load first set of stipple bits + */ + LoadBits; + + /* + * Consume stipple bits for startmask + */ + if (startmask) + { +#if FB_UNIT > 32 + if (pixelsPerDst == 16) + mask = FbStipple16Bits(FbLeftStipBits(bits,16)); + else +#endif + mask = fbBits[FbLeftStipBits(bits,pixelsPerDst)]; +#ifndef FBNOPIXADDR + if (fbLane) + { + fbTransparentSpan (dst, mask & startmask, fgxor, 1); + } + else +#endif + { + if (mask || !transparent) + FbDoLeftMaskByteStippleRRop (dst, mask, + fgand, fgxor, bgand, bgxor, + startbyte, startmask); + } + bits = FbStipLeft (bits, pixelsPerDst); + dst++; + n--; + w--; + } + /* + * Consume stipple bits across scanline + */ + for (;;) + { + w -= n; + if (copy) + { + while (n--) + { +#if FB_UNIT > 32 + if (pixelsPerDst == 16) + mask = FbStipple16Bits(FbLeftStipBits(bits,16)); + else +#endif + mask = fbBits[FbLeftStipBits(bits,pixelsPerDst)]; + *dst = FbOpaqueStipple (mask, fgxor, bgxor); + dst++; + bits = FbStipLeft(bits, pixelsPerDst); + } + } + else + { +#ifndef FBNOPIXADDR + if (fbLane) + { + while (bits && n) + { + switch (fbLane[FbLeftStipBits(bits,pixelsPerDst)]) { + LaneCases((CARD8 *) dst); + } + bits = FbStipLeft(bits,pixelsPerDst); + dst++; + n--; + } + dst += n; + } + else +#endif + { + while (n--) + { + left = FbLeftStipBits(bits,pixelsPerDst); + if (left || !transparent) + { + mask = fbBits[left]; + *dst = FbStippleRRop (*dst, mask, + fgand, fgxor, bgand, bgxor); + } + dst++; + bits = FbStipLeft(bits, pixelsPerDst); + } + } + } + if (!w) + break; + /* + * Load another set and reset number of available units + */ + LoadBits; + n = unitsPerSrc; + if (n > w) + n = w; + } + } + /* + * Consume stipple bits for endmask + */ + if (endmask) + { + if (endNeedsLoad) + { + LoadBits; + } +#if FB_UNIT > 32 + if (pixelsPerDst == 16) + mask = FbStipple16Bits(FbLeftStipBits(bits,16)); + else +#endif + mask = fbBits[FbLeftStipBits(bits,pixelsPerDst)]; +#ifndef FBNOPIXADDR + if (fbLane) + { + fbTransparentSpan (dst, mask & endmask, fgxor, 1); + } + else +#endif + { + if (mask || !transparent) + FbDoRightMaskByteStippleRRop (dst, mask, + fgand, fgxor, bgand, bgxor, + endbyte, endmask); + } + } + dst += dstStride; + src += srcStride; + } +} + +#ifdef FB_24BIT + +/* + * Crufty macros to initialize the mask array, most of this + * is to avoid compile-time warnings about shift overflow + */ + +#if BITMAP_BIT_ORDER == MSBFirst +#define Mask24Pos(x,r) ((x)*24-(r)) +#else +#define Mask24Pos(x,r) ((x)*24-((r) ? 24 - (r) : 0)) +#endif + +#define Mask24Neg(x,r) (Mask24Pos(x,r) < 0 ? -Mask24Pos(x,r) : 0) +#define Mask24Check(x,r) (Mask24Pos(x,r) < 0 ? 0 : \ + Mask24Pos(x,r) >= FB_UNIT ? 0 : Mask24Pos(x,r)) + +#define Mask24(x,r) (Mask24Pos(x,r) < FB_UNIT ? \ + (Mask24Pos(x,r) < 0 ? \ + 0xffffff >> Mask24Neg (x,r) : \ + 0xffffff << Mask24Check(x,r)) : 0) + +#define SelMask24(b,n,r) ((((b) >> n) & 1) * Mask24(n,r)) + +/* + * Untested for MSBFirst or FB_UNIT == 32 + */ + +#if FB_UNIT == 64 +#define C4_24(b,r) \ + (SelMask24(b,0,r) | \ + SelMask24(b,1,r) | \ + SelMask24(b,2,r) | \ + SelMask24(b,3,r)) + +#define FbStip24New(rot) (2 + (rot != 0)) +#define FbStip24Len 4 + +const FbBits fbStipple24Bits[3][1 << FbStip24Len] = { + /* rotate 0 */ + { + C4_24( 0, 0), C4_24( 1, 0), C4_24( 2, 0), C4_24( 3, 0), + C4_24( 4, 0), C4_24( 5, 0), C4_24( 6, 0), C4_24( 7, 0), + C4_24( 8, 0), C4_24( 9, 0), C4_24(10, 0), C4_24(11, 0), + C4_24(12, 0), C4_24(13, 0), C4_24(14, 0), C4_24(15, 0), + }, + /* rotate 8 */ + { + C4_24( 0, 8), C4_24( 1, 8), C4_24( 2, 8), C4_24( 3, 8), + C4_24( 4, 8), C4_24( 5, 8), C4_24( 6, 8), C4_24( 7, 8), + C4_24( 8, 8), C4_24( 9, 8), C4_24(10, 8), C4_24(11, 8), + C4_24(12, 8), C4_24(13, 8), C4_24(14, 8), C4_24(15, 8), + }, + /* rotate 16 */ + { + C4_24( 0,16), C4_24( 1,16), C4_24( 2,16), C4_24( 3,16), + C4_24( 4,16), C4_24( 5,16), C4_24( 6,16), C4_24( 7,16), + C4_24( 8,16), C4_24( 9,16), C4_24(10,16), C4_24(11,16), + C4_24(12,16), C4_24(13,16), C4_24(14,16), C4_24(15,16), + } +}; + +#endif + +#if FB_UNIT == 32 +#define C2_24(b,r) \ + (SelMask24(b,0,r) | \ + SelMask24(b,1,r)) + +#define FbStip24Len 2 +#if BITMAP_BIT_ORDER == MSBFirst +#define FbStip24New(rot) (1 + (rot == 0)) +#else +#define FbStip24New(rot) (1 + (rot == 8)) +#endif + +const FbBits fbStipple24Bits[3][1 << FbStip24Len] = { + /* rotate 0 */ + { + C2_24( 0, 0), C2_24 ( 1, 0), C2_24 ( 2, 0), C2_24 ( 3, 0), + }, + /* rotate 8 */ + { + C2_24( 0, 8), C2_24 ( 1, 8), C2_24 ( 2, 8), C2_24 ( 3, 8), + }, + /* rotate 16 */ + { + C2_24( 0,16), C2_24 ( 1,16), C2_24 ( 2,16), C2_24 ( 3,16), + } +}; +#endif + +#if BITMAP_BIT_ORDER == LSBFirst + +#define FbMergeStip24Bits(left, right, new) \ + (FbStipLeft (left, new) | FbStipRight ((right), (FbStip24Len - (new)))) + +#define FbMergePartStip24Bits(left, right, llen, rlen) \ + (left | FbStipRight(right, llen)) + +#else + +#define FbMergeStip24Bits(left, right, new) \ + ((FbStipLeft (left, new) & ((1 << FbStip24Len) - 1)) | right) + +#define FbMergePartStip24Bits(left, right, llen, rlen) \ + (FbStipLeft(left, rlen) | right) + +#endif + +#define fbFirstStipBits(len,stip) {\ + int __len = (len); \ + if (len <= remain) { \ + stip = FbLeftStipBits(bits, len); \ + } else { \ + stip = FbLeftStipBits(bits, remain); \ + bits = (src < srcEnd ? *src++ : 0); \ + __len = (len) - remain; \ + stip = FbMergePartStip24Bits(stip, FbLeftStipBits(bits, __len), \ + remain, __len); \ + remain = FB_STIP_UNIT; \ + } \ + bits = FbStipLeft (bits, __len); \ + remain -= __len; \ +} + +#define fbInitStipBits(offset,len,stip) {\ + bits = FbStipLeft (*src++,offset); \ + remain = FB_STIP_UNIT - offset; \ + fbFirstStipBits(len,stip); \ + stip = FbMergeStip24Bits (0, stip, len); \ +} + +#define fbNextStipBits(rot,stip) {\ + int __new = FbStip24New(rot); \ + FbStip __right; \ + fbFirstStipBits(__new, __right); \ + stip = FbMergeStip24Bits (stip, __right, __new); \ + rot = FbNext24Rot (rot); \ +} + +/* + * Use deep mask tables that incorporate rotation, pull + * a variable number of bits out of the stipple and + * reuse the right bits as needed for the next write + * + * Yes, this is probably too much code, but most 24-bpp screens + * have no acceleration so this code is used for stipples, copyplane + * and text + */ +void +fbBltOne24 (FbStip *srcLine, + FbStride srcStride, /* FbStip units per scanline */ + int srcX, /* bit position of source */ + FbBits *dst, + FbStride dstStride, /* FbBits units per scanline */ + int dstX, /* bit position of dest */ + int dstBpp, /* bits per destination unit */ + + int width, /* width in bits of destination */ + int height, /* height in scanlines */ + + FbBits fgand, /* rrop values */ + FbBits fgxor, + FbBits bgand, + FbBits bgxor) +{ + FbStip *src, *srcEnd; + FbBits leftMask, rightMask, mask; + int nlMiddle, nl; + FbStip stip, bits; + int remain; + int dstS; + int firstlen; + int rot0, rot; + int nDst; + + /* + * Do not read past the end of the buffer! + */ + srcEnd = srcLine + height * srcStride; + + srcLine += srcX >> FB_STIP_SHIFT; + dst += dstX >> FB_SHIFT; + srcX &= FB_STIP_MASK; + dstX &= FB_MASK; + rot0 = FbFirst24Rot (dstX); + + FbMaskBits (dstX, width, leftMask, nlMiddle, rightMask); + + dstS = (dstX + 23) / 24; + firstlen = FbStip24Len - dstS; + + nDst = nlMiddle; + if (leftMask) + nDst++; + dstStride -= nDst; + + /* opaque copy */ + if (bgand == 0 && fgand == 0) + { + while (height--) + { + rot = rot0; + src = srcLine; + srcLine += srcStride; + fbInitStipBits (srcX,firstlen, stip); + if (leftMask) + { + mask = fbStipple24Bits[rot >> 3][stip]; + *dst = (*dst & ~leftMask) | (FbOpaqueStipple (mask, + FbRot24(fgxor, rot), + FbRot24(bgxor, rot)) + & leftMask); + dst++; + fbNextStipBits(rot,stip); + } + nl = nlMiddle; + while (nl--) + { + mask = fbStipple24Bits[rot>>3][stip]; + *dst = FbOpaqueStipple (mask, + FbRot24(fgxor, rot), + FbRot24(bgxor, rot)); + dst++; + fbNextStipBits(rot,stip); + } + if (rightMask) + { + mask = fbStipple24Bits[rot >> 3][stip]; + *dst = (*dst & ~rightMask) | (FbOpaqueStipple (mask, + FbRot24(fgxor, rot), + FbRot24(bgxor, rot)) + & rightMask); + } + dst += dstStride; + src += srcStride; + } + } + /* transparent copy */ + else if (bgand == FB_ALLONES && bgxor == 0 && fgand == 0) + { + while (height--) + { + rot = rot0; + src = srcLine; + srcLine += srcStride; + fbInitStipBits (srcX, firstlen, stip); + if (leftMask) + { + if (stip) + { + mask = fbStipple24Bits[rot >> 3][stip] & leftMask; + *dst = (*dst & ~mask) | (FbRot24(fgxor, rot) & mask); + } + dst++; + fbNextStipBits (rot, stip); + } + nl = nlMiddle; + while (nl--) + { + if (stip) + { + mask = fbStipple24Bits[rot>>3][stip]; + *dst = (*dst & ~mask) | (FbRot24(fgxor,rot) & mask); + } + dst++; + fbNextStipBits (rot, stip); + } + if (rightMask) + { + if (stip) + { + mask = fbStipple24Bits[rot >> 3][stip] & rightMask; + *dst = (*dst & ~mask) | (FbRot24(fgxor, rot) & mask); + } + } + dst += dstStride; + } + } + else + { + while (height--) + { + rot = rot0; + src = srcLine; + srcLine += srcStride; + fbInitStipBits (srcX, firstlen, stip); + if (leftMask) + { + mask = fbStipple24Bits[rot >> 3][stip]; + *dst = FbStippleRRopMask (*dst, mask, + FbRot24(fgand, rot), + FbRot24(fgxor, rot), + FbRot24(bgand, rot), + FbRot24(bgxor, rot), + leftMask); + dst++; + fbNextStipBits(rot,stip); + } + nl = nlMiddle; + while (nl--) + { + mask = fbStipple24Bits[rot >> 3][stip]; + *dst = FbStippleRRop (*dst, mask, + FbRot24(fgand, rot), + FbRot24(fgxor, rot), + FbRot24(bgand, rot), + FbRot24(bgxor, rot)); + dst++; + fbNextStipBits(rot,stip); + } + if (rightMask) + { + mask = fbStipple24Bits[rot >> 3][stip]; + *dst = FbStippleRRopMask (*dst, mask, + FbRot24(fgand, rot), + FbRot24(fgxor, rot), + FbRot24(bgand, rot), + FbRot24(bgxor, rot), + rightMask); + } + dst += dstStride; + } + } +} +#endif + +/* + * Not very efficient, but simple -- copy a single plane + * from an N bit image to a 1 bit image + */ + +void +fbBltPlane (FbBits *src, + FbStride srcStride, + int srcX, + int srcBpp, + + FbStip *dst, + FbStride dstStride, + int dstX, + + int width, + int height, + + FbStip fgand, + FbStip fgxor, + FbStip bgand, + FbStip bgxor, + Pixel planeMask) +{ + FbBits *s; + FbBits pm; + FbBits srcMask; + FbBits srcMaskFirst; + FbBits srcMask0 = 0; + FbBits srcBits; + + FbStip dstBits; + FbStip *d; + FbStip dstMask; + FbStip dstMaskFirst; + FbStip dstUnion; + int w; + int wt; + int rot0; + + if (!width) + return; + + src += srcX >> FB_SHIFT; + srcX &= FB_MASK; + + dst += dstX >> FB_STIP_SHIFT; + dstX &= FB_STIP_MASK; + + w = width / srcBpp; + + pm = fbReplicatePixel (planeMask, srcBpp); +#ifdef FB_24BIT + if (srcBpp == 24) + { + int w = 24; + + rot0 = FbFirst24Rot (srcX); + if (srcX + w > FB_UNIT) + w = FB_UNIT - srcX; + srcMaskFirst = FbRot24(pm,rot0) & FbBitsMask(srcX,w); + } + else +#endif + { + rot0 = 0; + srcMaskFirst = pm & FbBitsMask(srcX, srcBpp); + srcMask0 = pm & FbBitsMask(0, srcBpp); + } + + dstMaskFirst = FbStipMask(dstX,1); + while (height--) + { + d = dst; + dst += dstStride; + s = src; + src += srcStride; + + srcMask = srcMaskFirst; +#ifdef FB_24BIT + if (srcBpp == 24) + srcMask0 = FbRot24(pm,rot0) & FbBitsMask(0, srcBpp); +#endif + srcBits = *s++; + + dstMask = dstMaskFirst; + dstUnion = 0; + dstBits = 0; + + wt = w; + + while (wt--) + { + if (!srcMask) + { + srcBits = *s++; +#ifdef FB_24BIT + if (srcBpp == 24) + srcMask0 = FbNext24Pix(srcMask0) & FbBitsMask(0,24); +#endif + srcMask = srcMask0; + } + if (!dstMask) + { + *d = FbStippleRRopMask(*d, dstBits, + fgand, fgxor, bgand, bgxor, + dstUnion); + d++; + dstMask = FbStipMask(0,1); + dstUnion = 0; + dstBits = 0; + } + if (srcBits & srcMask) + dstBits |= dstMask; + dstUnion |= dstMask; + if (srcBpp == FB_UNIT) + srcMask = 0; + else + srcMask = FbScrRight(srcMask,srcBpp); + dstMask = FbStipRight(dstMask,1); + } + if (dstUnion) + *d = FbStippleRRopMask(*d,dstBits, + fgand, fgxor, bgand, bgxor, + dstUnion); + } +} + diff --git a/nx-X11/programs/Xserver/fb/fbbstore.c b/nx-X11/programs/Xserver/fb/fbbstore.c new file mode 100644 index 000000000..75f6084c0 --- /dev/null +++ b/nx-X11/programs/Xserver/fb/fbbstore.c @@ -0,0 +1,65 @@ +/* + * Id: fbbstore.c,v 1.1 1999/11/02 03:54:45 keithp Exp $ + * + * 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 +fbSaveAreas(PixmapPtr pPixmap, + RegionPtr prgnSave, + int xorg, + int yorg, + WindowPtr pWin) +{ + fbCopyWindowProc (&pWin->drawable, + &pPixmap->drawable, + 0, + RegionRects(prgnSave), + RegionNumRects(prgnSave), + xorg, yorg, + FALSE, + FALSE, + 0,0); +} + +void +fbRestoreAreas(PixmapPtr pPixmap, + RegionPtr prgnRestore, + int xorg, + int yorg, + WindowPtr pWin) +{ + fbCopyWindowProc (&pPixmap->drawable, + &pWin->drawable, + 0, + RegionRects(prgnRestore), + RegionNumRects(prgnRestore), + -xorg, -yorg, + FALSE, + FALSE, + 0,0); +} diff --git a/nx-X11/programs/Xserver/fb/fbcmap.c b/nx-X11/programs/Xserver/fb/fbcmap.c new file mode 100644 index 000000000..ec8ddff4f --- /dev/null +++ b/nx-X11/programs/Xserver/fb/fbcmap.c @@ -0,0 +1,671 @@ +/* $XConsortium: fbcmap.c,v 4.19 94/04/17 20:28:46 dpw Exp $ */ +/************************************************************ +Copyright 1987 by Sun Microsystems, Inc. Mountain View, CA. + + All Rights Reserved + +Permission to use, copy, modify, and distribute this +software and its documentation for any purpose and without +fee is hereby granted, provided that the above copyright no- +tice appear in all copies and that both that copyright no- +tice and this permission notice appear in supporting docu- +mentation, and that the names of Sun or X Consortium +not be used in advertising or publicity pertaining to +distribution of the software without specific prior +written permission. Sun and X Consortium make no +representations about the suitability of this software for +any purpose. It is provided "as is" without any express or +implied warranty. + +SUN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FIT- +NESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SUN BE LI- +ABLE 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 <nx-X11/X.h> +#include <nx-X11/Xproto.h> +#include "scrnintstr.h" +#include "colormapst.h" +#include "resource.h" +#include "fb.h" + +#ifndef XFree86Server +ColormapPtr FbInstalledMaps[MAXSCREENS]; + +int +fbListInstalledColormaps(ScreenPtr pScreen, Colormap *pmaps) +{ + /* By the time we are processing requests, we can guarantee that there + * is always a colormap installed */ + *pmaps = FbInstalledMaps[pScreen->myNum]->mid; + return (1); +} + + +void +fbInstallColormap(ColormapPtr pmap) +{ + int index = pmap->pScreen->myNum; + ColormapPtr oldpmap = FbInstalledMaps[index]; + + if(pmap != oldpmap) + { + /* Uninstall pInstalledMap. No hardware changes required, just + * notify all interested parties. */ + if(oldpmap != (ColormapPtr)None) + WalkTree(pmap->pScreen, TellLostMap, (char *)&oldpmap->mid); + /* Install pmap */ + FbInstalledMaps[index] = pmap; + WalkTree(pmap->pScreen, TellGainedMap, (char *)&pmap->mid); + } +} + +void +fbUninstallColormap(ColormapPtr pmap) +{ + int index = pmap->pScreen->myNum; + ColormapPtr curpmap = FbInstalledMaps[index]; + + if(pmap == curpmap) + { + if (pmap->mid != pmap->pScreen->defColormap) + { + curpmap = (ColormapPtr) LookupIDByType(pmap->pScreen->defColormap, + RT_COLORMAP); + (*pmap->pScreen->InstallColormap)(curpmap); + } + } +} + +void +fbResolveColor(unsigned short *pred, + unsigned short *pgreen, + unsigned short *pblue, + VisualPtr pVisual) +{ + int shift = 16 - pVisual->bitsPerRGBValue; + unsigned lim = (1 << pVisual->bitsPerRGBValue) - 1; + + if ((pVisual->class | DynamicClass) == GrayScale) + { + /* rescale to gray then rgb bits */ + *pred = (30L * *pred + 59L * *pgreen + 11L * *pblue) / 100; + *pblue = *pgreen = *pred = ((*pred >> shift) * 65535) / lim; + } + else + { + /* rescale to rgb bits */ + *pred = ((*pred >> shift) * 65535) / lim; + *pgreen = ((*pgreen >> shift) * 65535) / lim; + *pblue = ((*pblue >> shift) * 65535) / lim; + } +} + +Bool +fbInitializeColormap(ColormapPtr pmap) +{ + register unsigned i; + register VisualPtr pVisual; + unsigned lim, maxent, shift; + + pVisual = pmap->pVisual; + lim = (1 << pVisual->bitsPerRGBValue) - 1; + shift = 16 - pVisual->bitsPerRGBValue; + maxent = pVisual->ColormapEntries - 1; + if (pVisual->class == TrueColor) + { + unsigned limr, limg, limb; + + limr = pVisual->redMask >> pVisual->offsetRed; + limg = pVisual->greenMask >> pVisual->offsetGreen; + limb = pVisual->blueMask >> pVisual->offsetBlue; + for(i = 0; i <= maxent; i++) + { + /* rescale to [0..65535] then rgb bits */ + pmap->red[i].co.local.red = + ((((i * 65535) / limr) >> shift) * 65535) / lim; + pmap->green[i].co.local.green = + ((((i * 65535) / limg) >> shift) * 65535) / lim; + pmap->blue[i].co.local.blue = + ((((i * 65535) / limb) >> shift) * 65535) / lim; + } + } + else if (pVisual->class == StaticColor) + { + unsigned n; + unsigned r, g, b; + unsigned red, green, blue; + + for (n = 0; n*n*n < pVisual->ColormapEntries; n++) + ; + n--; + i = 0; + for (r = 0; r < n; r++) + { + red = (((r * 65535 / (n - 1)) >> shift) * 65535) / lim; + for (g = 0; g < n; g++) + { + green = (((g * 65535 / (n - 1)) >> shift) * 65535) / lim; + for (b = 0; b < n; b++) + { + blue = (((b * 65535 / (n - 1)) >> shift) * 65535) / lim; + pmap->red[i].co.local.red = red; + pmap->red[i].co.local.green = green; + pmap->red[i].co.local.blue = blue; + i++; + } + } + } + n = pVisual->ColormapEntries - i; + for (r = 0; r < n; r++) + { + red = (((r * 65535 / (n - 1)) >> shift) * 65535) / lim; + pmap->red[i].co.local.red = red; + pmap->red[i].co.local.green = red; + pmap->red[i].co.local.blue = red; + i++; + } + } + else if (pVisual->class == StaticGray) + { + for(i = 0; i <= maxent; i++) + { + /* rescale to [0..65535] then rgb bits */ + pmap->red[i].co.local.red = ((((i * 65535) / maxent) >> shift) + * 65535) / lim; + pmap->red[i].co.local.green = pmap->red[i].co.local.red; + pmap->red[i].co.local.blue = pmap->red[i].co.local.red; + } + } + return TRUE; +} + +/* When simulating DirectColor on PseudoColor hardware, multiple + entries of the colormap must be updated + */ + +#define AddElement(mask) { \ + pixel = red | green | blue; \ + for (i = 0; i < nresult; i++) \ + if (outdefs[i].pixel == pixel) \ + break; \ + if (i == nresult) \ + { \ + nresult++; \ + outdefs[i].pixel = pixel; \ + outdefs[i].flags = 0; \ + } \ + outdefs[i].flags |= (mask); \ + outdefs[i].red = pmap->red[red >> pVisual->offsetRed].co.local.red; \ + outdefs[i].green = pmap->green[green >> pVisual->offsetGreen].co.local.green; \ + outdefs[i].blue = pmap->blue[blue >> pVisual->offsetBlue].co.local.blue; \ +} + +int +fbExpandDirectColors (ColormapPtr pmap, + int ndef, + xColorItem *indefs, + xColorItem *outdefs) +{ + register int red, green, blue; + int maxred, maxgreen, maxblue; + int stepred, stepgreen, stepblue; + VisualPtr pVisual; + register int pixel; + register int nresult; + register int i; + + pVisual = pmap->pVisual; + + stepred = 1 << pVisual->offsetRed; + stepgreen = 1 << pVisual->offsetGreen; + stepblue = 1 << pVisual->offsetBlue; + maxred = pVisual->redMask; + maxgreen = pVisual->greenMask; + maxblue = pVisual->blueMask; + nresult = 0; + for (;ndef--; indefs++) + { + if (indefs->flags & DoRed) + { + red = indefs->pixel & pVisual->redMask; + for (green = 0; green <= maxgreen; green += stepgreen) + { + for (blue = 0; blue <= maxblue; blue += stepblue) + { + AddElement (DoRed) + } + } + } + if (indefs->flags & DoGreen) + { + green = indefs->pixel & pVisual->greenMask; + for (red = 0; red <= maxred; red += stepred) + { + for (blue = 0; blue <= maxblue; blue += stepblue) + { + AddElement (DoGreen) + } + } + } + if (indefs->flags & DoBlue) + { + blue = indefs->pixel & pVisual->blueMask; + for (red = 0; red <= maxred; red += stepred) + { + for (green = 0; green <= maxgreen; green += stepgreen) + { + AddElement (DoBlue) + } + } + } + } + return nresult; +} + +Bool +fbCreateDefColormap(ScreenPtr pScreen) +{ + unsigned short zero = 0, ones = 0xFFFF; + VisualPtr pVisual; + ColormapPtr cmap; + Pixel wp, bp; + + for (pVisual = pScreen->visuals; + pVisual->vid != pScreen->rootVisual; + pVisual++) + ; + + if (CreateColormap(pScreen->defColormap, pScreen, pVisual, &cmap, + (pVisual->class & DynamicClass) ? AllocNone : AllocAll, + 0) + != Success) + return FALSE; + wp = pScreen->whitePixel; + bp = pScreen->blackPixel; + if ((AllocColor(cmap, &ones, &ones, &ones, &wp, 0) != + Success) || + (AllocColor(cmap, &zero, &zero, &zero, &bp, 0) != + Success)) + return FALSE; + pScreen->whitePixel = wp; + pScreen->blackPixel = bp; + (*pScreen->InstallColormap)(cmap); + return TRUE; +} + +extern int defaultColorVisualClass; + +#define _RZ(d) ((d + 2) / 3) +#define _RS(d) 0 +#define _RM(d) ((1 << _RZ(d)) - 1) +#define _GZ(d) ((d - _RZ(d) + 1) / 2) +#define _GS(d) _RZ(d) +#define _GM(d) (((1 << _GZ(d)) - 1) << _GS(d)) +#define _BZ(d) (d - _RZ(d) - _GZ(d)) +#define _BS(d) (_RZ(d) + _GZ(d)) +#define _BM(d) (((1 << _BZ(d)) - 1) << _BS(d)) +#define _CE(d) (1 << _RZ(d)) + +#define MAX_PSEUDO_DEPTH 10 /* largest DAC size I know */ + +#define StaticGrayMask (1 << StaticGray) +#define GrayScaleMask (1 << GrayScale) +#define StaticColorMask (1 << StaticColor) +#define PseudoColorMask (1 << PseudoColor) +#define TrueColorMask (1 << TrueColor) +#define DirectColorMask (1 << DirectColor) + +#define ALL_VISUALS (StaticGrayMask|\ + GrayScaleMask|\ + StaticColorMask|\ + PseudoColorMask|\ + TrueColorMask|\ + DirectColorMask) + +#define LARGE_VISUALS (TrueColorMask|\ + DirectColorMask) + +typedef struct _fbVisuals { + struct _fbVisuals *next; + int depth; + int bitsPerRGB; + int visuals; + int count; + Pixel redMask, greenMask, blueMask; +} fbVisualsRec, *fbVisualsPtr; + +static const int fbVisualPriority[] = { + PseudoColor, DirectColor, GrayScale, StaticColor, TrueColor, StaticGray +}; + +#define NUM_PRIORITY 6 + +static fbVisualsPtr fbVisuals; + +static int +popCount (int i) +{ + int count; + + count = (i >> 1) & 033333333333; + count = i - count - ((count >> 1) & 033333333333); + count = (((count + (count >> 3)) & 030707070707) % 077); /* HAKMEM 169 */ + return count; +} + +/* + * Distance to least significant one bit + */ +static int +maskShift (Pixel p) +{ + int s; + + if (!p) return 0; + s = 0; + while (!(p & 1)) + { + s++; + p >>= 1; + } + return s; +} + +Bool +fbSetVisualTypesAndMasks (int depth, int visuals, int bitsPerRGB, + Pixel redMask, Pixel greenMask, Pixel blueMask) +{ + fbVisualsPtr new, *prev, v; + + new = (fbVisualsPtr) malloc (sizeof *new); + if (!new) + return FALSE; + if (!redMask || !greenMask || !blueMask) + { + redMask = _RM(depth); + greenMask = _GM(depth); + blueMask = _BM(depth); + } + new->next = 0; + new->depth = depth; + new->visuals = visuals; + new->bitsPerRGB = bitsPerRGB; + new->redMask = redMask; + new->greenMask = greenMask; + new->blueMask = blueMask; + new->count = popCount (visuals); + for (prev = &fbVisuals; (v = *prev); prev = &v->next); + *prev = new; + return TRUE; +} + +Bool +fbHasVisualTypes (int depth) +{ + fbVisualsPtr v; + + for (v = fbVisuals; v; v = v->next) + if (v->depth == depth) + return TRUE; + return FALSE; +} + +Bool +fbSetVisualTypes (int depth, int visuals, int bitsPerRGB) +{ + return fbSetVisualTypesAndMasks (depth, visuals, bitsPerRGB, + _RM(depth), _GM(depth), _BM(depth)); +} + +/* + * Given a list of formats for a screen, create a list + * of visuals and depths for the screen which coorespond to + * the set which can be used with this version of fb. + */ + +Bool +fbInitVisuals (VisualPtr *visualp, + DepthPtr *depthp, + int *nvisualp, + int *ndepthp, + int *rootDepthp, + VisualID *defaultVisp, + unsigned long sizes, + int bitsPerRGB) +{ + int i, j = 0, k; + VisualPtr visual; + DepthPtr depth; + VisualID *vid; + int d, b; + int f; + int ndepth, nvisual; + int nvtype; + int vtype; + fbVisualsPtr visuals, nextVisuals; + + /* none specified, we'll guess from pixmap formats */ + if (!fbVisuals) + { + for (f = 0; f < screenInfo.numPixmapFormats; f++) + { + d = screenInfo.formats[f].depth; + b = screenInfo.formats[f].bitsPerPixel; + if (sizes & (1 << (b - 1))) + { + if (d > MAX_PSEUDO_DEPTH) + vtype = LARGE_VISUALS; + else if (d == 1) + vtype = StaticGrayMask; + else + vtype = ALL_VISUALS; + } + else + vtype = 0; + if (!fbSetVisualTypes (d, vtype, bitsPerRGB)) + return FALSE; + } + } + nvisual = 0; + ndepth = 0; + for (visuals = fbVisuals; visuals; visuals = nextVisuals) + { + nextVisuals = visuals->next; + ndepth++; + nvisual += visuals->count; + } + depth = (DepthPtr) malloc (ndepth * sizeof (DepthRec)); + visual = (VisualPtr) malloc (nvisual * sizeof (VisualRec)); + if (!depth || !visual) + { + free (depth); + free (visual); + return FALSE; + } + *depthp = depth; + *visualp = visual; + *ndepthp = ndepth; + *nvisualp = nvisual; + for (visuals = fbVisuals; visuals; visuals = nextVisuals) + { + nextVisuals = visuals->next; + d = visuals->depth; + vtype = visuals->visuals; + nvtype = visuals->count; + vid = NULL; + if (nvtype) + { + vid = (VisualID *) malloc (nvtype * sizeof (VisualID)); + if (!vid) + return FALSE; + } + depth->depth = d; + depth->numVids = nvtype; + depth->vids = vid; + depth++; + for (i = 0; i < NUM_PRIORITY; i++) { + if (! (vtype & (1 << fbVisualPriority[i]))) + continue; + visual->class = fbVisualPriority[i]; + visual->bitsPerRGBValue = visuals->bitsPerRGB; + visual->ColormapEntries = 1 << d; + visual->nplanes = d; + visual->vid = *vid = FakeClientID (0); + switch (visual->class) { + case PseudoColor: + case GrayScale: + case StaticGray: + case StaticColor: + visual->redMask = 0; + visual->greenMask = 0; + visual->blueMask = 0; + visual->offsetRed = 0; + visual->offsetGreen = 0; + visual->offsetBlue = 0; + break; + case DirectColor: + case TrueColor: + visual->ColormapEntries = _CE(d); + visual->redMask = visuals->redMask; + visual->greenMask = visuals->greenMask; + visual->blueMask = visuals->blueMask; + visual->offsetRed = maskShift (visuals->redMask); + visual->offsetGreen = maskShift (visuals->greenMask); + visual->offsetBlue = maskShift (visuals->blueMask); + } + vid++; + visual++; + } + free (visuals); + } + fbVisuals = NULL; + visual = *visualp; + depth = *depthp; + for (i = 0; i < ndepth; i++) + { + if (*rootDepthp && *rootDepthp != depth[i].depth) + continue; + for (j = 0; j < depth[i].numVids; j++) + { + for (k = 0; k < nvisual; k++) + if (visual[k].vid == depth[i].vids[j]) + break; + if (k == nvisual) + continue; + if (defaultColorVisualClass < 0 || + visual[k].class == defaultColorVisualClass) + break; + } + if (j != depth[i].numVids) + break; + } + if (i == ndepth) { + for (i = 0; i < ndepth; i++) + { + if (depth[i].numVids) + break; + } + if (i == ndepth) + return FALSE; + j = 0; + } + *rootDepthp = depth[i].depth; + *defaultVisp = depth[i].vids[j]; + return TRUE; +} +#else + +#include "micmap.h" + +int +fbListInstalledColormaps(ScreenPtr pScreen, Colormap *pmaps) +{ + return miListInstalledColormaps(pScreen, pmaps); +} + +void +fbInstallColormap(ColormapPtr pmap) +{ + miInstallColormap(pmap); +} + +void +fbUninstallColormap(ColormapPtr pmap) +{ + miUninstallColormap(pmap); +} + +void +fbResolveColor(unsigned short *pred, + unsigned short *pgreen, + unsigned short *pblue, + VisualPtr pVisual) +{ + miResolveColor(pred, pgreen, pblue, pVisual); +} + +Bool +fbInitializeColormap(ColormapPtr pmap) +{ + return miInitializeColormap(pmap); +} + +int +fbExpandDirectColors (ColormapPtr pmap, + int ndef, + xColorItem *indefs, + xColorItem *outdefs) +{ + return miExpandDirectColors(pmap, ndef, indefs, outdefs); +} + +Bool +fbCreateDefColormap(ScreenPtr pScreen) +{ + return miCreateDefColormap(pScreen); +} + +void +fbClearVisualTypes(void) +{ + miClearVisualTypes(); +} + +Bool +fbSetVisualTypes (int depth, int visuals, int bitsPerRGB) +{ + return miSetVisualTypes(depth, visuals, bitsPerRGB, -1); +} + +/* + * Given a list of formats for a screen, create a list + * of visuals and depths for the screen which coorespond to + * the set which can be used with this version of fb. + */ + +Bool +fbInitVisuals (VisualPtr *visualp, + DepthPtr *depthp, + int *nvisualp, + int *ndepthp, + int *rootDepthp, + VisualID *defaultVisp, + unsigned long sizes, + int bitsPerRGB) +{ + return miInitVisuals(visualp, depthp, nvisualp, ndepthp, rootDepthp, + defaultVisp, sizes, bitsPerRGB, -1); +} +#endif diff --git a/nx-X11/programs/Xserver/fb/fbcompose.c b/nx-X11/programs/Xserver/fb/fbcompose.c new file mode 100644 index 000000000..3f4e6ec20 --- /dev/null +++ b/nx-X11/programs/Xserver/fb/fbcompose.c @@ -0,0 +1,3628 @@ +/* + * Copyright © 2000 Keith Packard, member of The XFree86 Project, Inc. + * 2005 Lars Knoll & Zack Rusin, Trolltech + * + * 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. + * + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS + * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS 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" + +#ifdef RENDER + +#include <stdlib.h> +#include <string.h> +#include <math.h> +#include <assert.h> + +#include "picturestr.h" +#include "mipict.h" +#include "fbpict.h" + +#define mod(a,b) ((b) == 1 ? 0 : (a) >= 0 ? (a) % (b) : (b) - (-a) % (b)) + +#define SCANLINE_BUFFER_LENGTH 2048 + +typedef FASTCALL void (*fetchProc)(const FbBits *bits, int x, int width, CARD32 *buffer, miIndexedPtr indexed); + +/* + * All of the fetch functions + */ + +static FASTCALL void +fbFetch_a8r8g8b8 (const FbBits *bits, int x, int width, CARD32 *buffer, miIndexedPtr indexed) +{ + memcpy(buffer, (const CARD32 *)bits + x, width*sizeof(CARD32)); +} + +static FASTCALL void +fbFetch_x8r8g8b8 (const FbBits *bits, int x, int width, CARD32 *buffer, miIndexedPtr indexed) +{ + const CARD32 *pixel = (const CARD32 *)bits + x; + const CARD32 *end = pixel + width; + while (pixel < end) { + *buffer++ = *pixel++ | 0xff000000; + } +} + +static FASTCALL void +fbFetch_a8b8g8r8 (const FbBits *bits, int x, int width, CARD32 *buffer, miIndexedPtr indexed) +{ + const CARD32 *pixel = (CARD32 *)bits + x; + const CARD32 *end = pixel + width; + while (pixel < end) { + *buffer++ = ((*pixel & 0xff00ff00) | + ((*pixel >> 16) & 0xff) | + ((*pixel & 0xff) << 16)); + ++pixel; + } +} + +static FASTCALL void +fbFetch_x8b8g8r8 (const FbBits *bits, int x, int width, CARD32 *buffer, miIndexedPtr indexed) +{ + const CARD32 *pixel = (CARD32 *)bits + x; + const CARD32 *end = pixel + width; + while (pixel < end) { + *buffer++ = 0xff000000 | + ((*pixel & 0x0000ff00) | + ((*pixel >> 16) & 0xff) | + ((*pixel & 0xff) << 16)); + ++pixel; + } +} + +static FASTCALL void +fbFetch_r8g8b8 (const FbBits *bits, int x, int width, CARD32 *buffer, miIndexedPtr indexed) +{ + const CARD8 *pixel = (const CARD8 *)bits + 3*x; + const CARD8 *end = pixel + 3*width; + while (pixel < end) { + CARD32 b = Fetch24(pixel) | 0xff000000; + pixel += 3; + *buffer++ = b; + } +} + +static FASTCALL void +fbFetch_b8g8r8 (const FbBits *bits, int x, int width, CARD32 *buffer, miIndexedPtr indexed) +{ + const CARD8 *pixel = (const CARD8 *)bits + 3*x; + const CARD8 *end = pixel + 3*width; + while (pixel < end) { + CARD32 b = 0xff000000; +#if IMAGE_BYTE_ORDER == MSBFirst + b |= (*pixel++); + b |= (*pixel++ << 8); + b |= (*pixel++ << 16); +#else + b |= (*pixel++ << 16); + b |= (*pixel++ << 8); + b |= (*pixel++); +#endif + } +} + +static FASTCALL void +fbFetch_r5g6b5 (const FbBits *bits, int x, int width, CARD32 *buffer, miIndexedPtr indexed) +{ + const CARD16 *pixel = (const CARD16 *)bits + x; + const CARD16 *end = pixel + width; + while (pixel < end) { + CARD32 p = *pixel++; + CARD32 r = (((p) << 3) & 0xf8) | + (((p) << 5) & 0xfc00) | + (((p) << 8) & 0xf80000); + r |= (r >> 5) & 0x70007; + r |= (r >> 6) & 0x300; + *buffer++ = 0xff000000 | r; + } +} + +static FASTCALL void +fbFetch_b5g6r5 (const FbBits *bits, int x, int width, CARD32 *buffer, miIndexedPtr indexed) +{ + const CARD16 *pixel = (const CARD16 *)bits + x; + const CARD16 *end = pixel + width; + while (pixel < end) { + CARD32 p = *pixel++; + CARD32 r,g,b; + + b = ((p & 0xf800) | ((p & 0xe000) >> 5)) >> 8; + g = ((p & 0x07e0) | ((p & 0x0600) >> 6)) << 5; + r = ((p & 0x001c) | ((p & 0x001f) << 5)) << 14; + *buffer++ = (0xff000000 | r | g | b); + } +} + +static FASTCALL void +fbFetch_a1r5g5b5 (const FbBits *bits, int x, int width, CARD32 *buffer, miIndexedPtr indexed) +{ + const CARD16 *pixel = (const CARD16 *)bits + x; + const CARD16 *end = pixel + width; + while (pixel < end) { + CARD32 p = *pixel++; + CARD32 r,g,b, a; + + a = (CARD32) ((CARD8) (0 - ((p & 0x8000) >> 15))) << 24; + r = ((p & 0x7c00) | ((p & 0x7000) >> 5)) << 9; + g = ((p & 0x03e0) | ((p & 0x0380) >> 5)) << 6; + b = ((p & 0x001c) | ((p & 0x001f) << 5)) >> 2; + *buffer++ = (a | r | g | b); + } +} + +static FASTCALL void +fbFetch_x1r5g5b5 (const FbBits *bits, int x, int width, CARD32 *buffer, miIndexedPtr indexed) +{ + const CARD16 *pixel = (const CARD16 *)bits + x; + const CARD16 *end = pixel + width; + while (pixel < end) { + CARD32 p = *pixel++; + CARD32 r,g,b; + + r = ((p & 0x7c00) | ((p & 0x7000) >> 5)) << 9; + g = ((p & 0x03e0) | ((p & 0x0380) >> 5)) << 6; + b = ((p & 0x001c) | ((p & 0x001f) << 5)) >> 2; + *buffer++ = (0xff000000 | r | g | b); + } +} + +static FASTCALL void +fbFetch_a1b5g5r5 (const FbBits *bits, int x, int width, CARD32 *buffer, miIndexedPtr indexed) +{ + const CARD16 *pixel = (const CARD16 *)bits + x; + const CARD16 *end = pixel + width; + while (pixel < end) { + CARD32 p = *pixel++; + CARD32 r,g,b, a; + + a = (CARD32) ((CARD8) (0 - ((p & 0x8000) >> 15))) << 24; + b = ((p & 0x7c00) | ((p & 0x7000) >> 5)) >> 7; + g = ((p & 0x03e0) | ((p & 0x0380) >> 5)) << 6; + r = ((p & 0x001c) | ((p & 0x001f) << 5)) << 14; + *buffer++ = (a | r | g | b); + } +} + +static FASTCALL void +fbFetch_x1b5g5r5 (const FbBits *bits, int x, int width, CARD32 *buffer, miIndexedPtr indexed) +{ + const CARD16 *pixel = (const CARD16 *)bits + x; + const CARD16 *end = pixel + width; + while (pixel < end) { + CARD32 p = *pixel++; + CARD32 r,g,b; + + b = ((p & 0x7c00) | ((p & 0x7000) >> 5)) >> 7; + g = ((p & 0x03e0) | ((p & 0x0380) >> 5)) << 6; + r = ((p & 0x001c) | ((p & 0x001f) << 5)) << 14; + *buffer++ = (0xff000000 | r | g | b); + } +} + +static FASTCALL void +fbFetch_a4r4g4b4 (const FbBits *bits, int x, int width, CARD32 *buffer, miIndexedPtr indexed) +{ + const CARD16 *pixel = (const CARD16 *)bits + x; + const CARD16 *end = pixel + width; + while (pixel < end) { + CARD32 p = *pixel++; + CARD32 r,g,b, a; + + a = ((p & 0xf000) | ((p & 0xf000) >> 4)) << 16; + r = ((p & 0x0f00) | ((p & 0x0f00) >> 4)) << 12; + g = ((p & 0x00f0) | ((p & 0x00f0) >> 4)) << 8; + b = ((p & 0x000f) | ((p & 0x000f) << 4)); + *buffer++ = (a | r | g | b); + } +} + +static FASTCALL void +fbFetch_x4r4g4b4 (const FbBits *bits, int x, int width, CARD32 *buffer, miIndexedPtr indexed) +{ + const CARD16 *pixel = (const CARD16 *)bits + x; + const CARD16 *end = pixel + width; + while (pixel < end) { + CARD32 p = *pixel++; + CARD32 r,g,b; + + r = ((p & 0x0f00) | ((p & 0x0f00) >> 4)) << 12; + g = ((p & 0x00f0) | ((p & 0x00f0) >> 4)) << 8; + b = ((p & 0x000f) | ((p & 0x000f) << 4)); + *buffer++ = (0xff000000 | r | g | b); + } +} + +static FASTCALL void +fbFetch_a4b4g4r4 (const FbBits *bits, int x, int width, CARD32 *buffer, miIndexedPtr indexed) +{ + const CARD16 *pixel = (const CARD16 *)bits + x; + const CARD16 *end = pixel + width; + while (pixel < end) { + CARD32 p = *pixel++; + CARD32 r,g,b, a; + + a = ((p & 0xf000) | ((p & 0xf000) >> 4)) << 16; + b = ((p & 0x0f00) | ((p & 0x0f00) >> 4)) << 12; + g = ((p & 0x00f0) | ((p & 0x00f0) >> 4)) << 8; + r = ((p & 0x000f) | ((p & 0x000f) << 4)); + *buffer++ = (a | r | g | b); + } +} + +static FASTCALL void +fbFetch_x4b4g4r4 (const FbBits *bits, int x, int width, CARD32 *buffer, miIndexedPtr indexed) +{ + const CARD16 *pixel = (const CARD16 *)bits + x; + const CARD16 *end = pixel + width; + while (pixel < end) { + CARD32 p = *pixel++; + CARD32 r,g,b; + + b = ((p & 0x0f00) | ((p & 0x0f00) >> 4)) << 12; + g = ((p & 0x00f0) | ((p & 0x00f0) >> 4)) << 8; + r = ((p & 0x000f) | ((p & 0x000f) << 4)); + *buffer++ = (0xff000000 | r | g | b); + } +} + +static FASTCALL void +fbFetch_a8 (const FbBits *bits, int x, int width, CARD32 *buffer, miIndexedPtr indexed) +{ + const CARD8 *pixel = (const CARD8 *)bits + x; + const CARD8 *end = pixel + width; + while (pixel < end) { + *buffer++ = (*pixel++) << 24; + } +} + +static FASTCALL void +fbFetch_r3g3b2 (const FbBits *bits, int x, int width, CARD32 *buffer, miIndexedPtr indexed) +{ + const CARD8 *pixel = (const CARD8 *)bits + x; + const CARD8 *end = pixel + width; + while (pixel < end) { + CARD32 p = *pixel++; + CARD32 r,g,b; + + r = ((p & 0xe0) | ((p & 0xe0) >> 3) | ((p & 0xc0) >> 6)) << 16; + g = ((p & 0x1c) | ((p & 0x18) >> 3) | ((p & 0x1c) << 3)) << 8; + b = (((p & 0x03) ) | + ((p & 0x03) << 2) | + ((p & 0x03) << 4) | + ((p & 0x03) << 6)); + *buffer++ = (0xff000000 | r | g | b); + } +} + +static FASTCALL void +fbFetch_b2g3r3 (const FbBits *bits, int x, int width, CARD32 *buffer, miIndexedPtr indexed) +{ + const CARD8 *pixel = (const CARD8 *)bits + x; + const CARD8 *end = pixel + width; + while (pixel < end) { + CARD32 p = *pixel++; + CARD32 r,g,b; + + b = (((p & 0xc0) ) | + ((p & 0xc0) >> 2) | + ((p & 0xc0) >> 4) | + ((p & 0xc0) >> 6)); + g = ((p & 0x38) | ((p & 0x38) >> 3) | ((p & 0x30) << 2)) << 8; + r = (((p & 0x07) ) | + ((p & 0x07) << 3) | + ((p & 0x06) << 6)) << 16; + *buffer++ = (0xff000000 | r | g | b); + } +} + +static FASTCALL void +fbFetch_a2r2g2b2 (const FbBits *bits, int x, int width, CARD32 *buffer, miIndexedPtr indexed) +{ + const CARD8 *pixel = (const CARD8 *)bits + x; + const CARD8 *end = pixel + width; + while (pixel < end) { + CARD32 p = *pixel++; + CARD32 a,r,g,b; + + a = ((p & 0xc0) * 0x55) << 18; + r = ((p & 0x30) * 0x55) << 12; + g = ((p & 0x0c) * 0x55) << 6; + b = ((p & 0x03) * 0x55); + *buffer++ = a|r|g|b; + } +} + +static FASTCALL void +fbFetch_a2b2g2r2 (const FbBits *bits, int x, int width, CARD32 *buffer, miIndexedPtr indexed) +{ + const CARD8 *pixel = (const CARD8 *)bits + x; + const CARD8 *end = pixel + width; + while (pixel < end) { + CARD32 p = *pixel++; + CARD32 a,r,g,b; + + a = ((p & 0xc0) * 0x55) << 18; + b = ((p & 0x30) * 0x55) >> 6; + g = ((p & 0x0c) * 0x55) << 6; + r = ((p & 0x03) * 0x55) << 16; + *buffer++ = a|r|g|b; + } +} + +static FASTCALL void +fbFetch_c8 (const FbBits *bits, int x, int width, CARD32 *buffer, miIndexedPtr indexed) +{ + const CARD8 *pixel = (const CARD8 *)bits + x; + const CARD8 *end = pixel + width; + while (pixel < end) { + CARD32 p = *pixel++; + *buffer++ = indexed->rgba[p]; + } +} + +#define Fetch8(l,o) (((CARD8 *) (l))[(o) >> 2]) +#if IMAGE_BYTE_ORDER == MSBFirst +#define Fetch4(l,o) ((o) & 2 ? Fetch8(l,o) & 0xf : Fetch8(l,o) >> 4) +#else +#define Fetch4(l,o) ((o) & 2 ? Fetch8(l,o) >> 4 : Fetch8(l,o) & 0xf) +#endif + +static FASTCALL void +fbFetch_a4 (const FbBits *bits, int x, int width, CARD32 *buffer, miIndexedPtr indexed) +{ + int i; + for (i = 0; i < width; ++i) { + CARD32 p = Fetch4(bits, i + x); + + p |= p << 4; + *buffer++ = p << 24; + } +} + +static FASTCALL void +fbFetch_r1g2b1 (const FbBits *bits, int x, int width, CARD32 *buffer, miIndexedPtr indexed) +{ + int i; + for (i = 0; i < width; ++i) { + CARD32 p = Fetch4(bits, i + x); + CARD32 r,g,b; + + r = ((p & 0x8) * 0xff) << 13; + g = ((p & 0x6) * 0x55) << 7; + b = ((p & 0x1) * 0xff); + *buffer++ = 0xff000000|r|g|b; + } +} + +static FASTCALL void +fbFetch_b1g2r1 (const FbBits *bits, int x, int width, CARD32 *buffer, miIndexedPtr indexed) +{ + int i; + for (i = 0; i < width; ++i) { + CARD32 p = Fetch4(bits, i + x); + CARD32 r,g,b; + + b = ((p & 0x8) * 0xff) >> 3; + g = ((p & 0x6) * 0x55) << 7; + r = ((p & 0x1) * 0xff) << 16; + *buffer++ = 0xff000000|r|g|b; + } +} + +static FASTCALL void +fbFetch_a1r1g1b1 (const FbBits *bits, int x, int width, CARD32 *buffer, miIndexedPtr indexed) +{ + int i; + for (i = 0; i < width; ++i) { + CARD32 p = Fetch4(bits, i + x); + CARD32 a,r,g,b; + + a = ((p & 0x8) * 0xff) << 21; + r = ((p & 0x4) * 0xff) << 14; + g = ((p & 0x2) * 0xff) << 7; + b = ((p & 0x1) * 0xff); + *buffer++ = a|r|g|b; + } +} + +static FASTCALL void +fbFetch_a1b1g1r1 (const FbBits *bits, int x, int width, CARD32 *buffer, miIndexedPtr indexed) +{ + int i; + for (i = 0; i < width; ++i) { + CARD32 p = Fetch4(bits, i + x); + CARD32 a,r,g,b; + + a = ((p & 0x8) * 0xff) << 21; + r = ((p & 0x4) * 0xff) >> 3; + g = ((p & 0x2) * 0xff) << 7; + b = ((p & 0x1) * 0xff) << 16; + *buffer++ = a|r|g|b; + } +} + +static FASTCALL void +fbFetch_c4 (const FbBits *bits, int x, int width, CARD32 *buffer, miIndexedPtr indexed) +{ + int i; + for (i = 0; i < width; ++i) { + CARD32 p = Fetch4(bits, i + x); + + *buffer++ = indexed->rgba[p]; + } +} + + +static FASTCALL void +fbFetch_a1 (const FbBits *bits, int x, int width, CARD32 *buffer, miIndexedPtr indexed) +{ + int i; + for (i = 0; i < width; ++i) { + CARD32 p = ((CARD32 *)bits)[(i + x) >> 5]; + CARD32 a; +#if BITMAP_BIT_ORDER == MSBFirst + a = p >> (0x1f - ((i+x) & 0x1f)); +#else + a = p >> ((i+x) & 0x1f); +#endif + a = a & 1; + a |= a << 1; + a |= a << 2; + a |= a << 4; + *buffer++ = a << 24; + } +} + +static FASTCALL void +fbFetch_g1 (const FbBits *bits, int x, int width, CARD32 *buffer, miIndexedPtr indexed) +{ + int i; + for (i = 0; i < width; ++i) { + CARD32 p = ((CARD32 *)bits)[(i+x) >> 5]; + CARD32 a; +#if BITMAP_BIT_ORDER == MSBFirst + a = p >> (0x1f - ((i+x) & 0x1f)); +#else + a = p >> ((i+x) & 0x1f); +#endif + a = a & 1; + *buffer++ = indexed->rgba[a]; + } +} + +static fetchProc fetchProcForPicture (PicturePtr pict) +{ + switch(pict->format) { + case PICT_a8r8g8b8: return fbFetch_a8r8g8b8; + case PICT_x8r8g8b8: return fbFetch_x8r8g8b8; + case PICT_a8b8g8r8: return fbFetch_a8b8g8r8; + case PICT_x8b8g8r8: return fbFetch_x8b8g8r8; + + /* 24bpp formats */ + case PICT_r8g8b8: return fbFetch_r8g8b8; + case PICT_b8g8r8: return fbFetch_b8g8r8; + + /* 16bpp formats */ + case PICT_r5g6b5: return fbFetch_r5g6b5; + case PICT_b5g6r5: return fbFetch_b5g6r5; + + case PICT_a1r5g5b5: return fbFetch_a1r5g5b5; + case PICT_x1r5g5b5: return fbFetch_x1r5g5b5; + case PICT_a1b5g5r5: return fbFetch_a1b5g5r5; + case PICT_x1b5g5r5: return fbFetch_x1b5g5r5; + case PICT_a4r4g4b4: return fbFetch_a4r4g4b4; + case PICT_x4r4g4b4: return fbFetch_x4r4g4b4; + case PICT_a4b4g4r4: return fbFetch_a4b4g4r4; + case PICT_x4b4g4r4: return fbFetch_x4b4g4r4; + + /* 8bpp formats */ + case PICT_a8: return fbFetch_a8; + case PICT_r3g3b2: return fbFetch_r3g3b2; + case PICT_b2g3r3: return fbFetch_b2g3r3; + case PICT_a2r2g2b2: return fbFetch_a2r2g2b2; + case PICT_a2b2g2r2: return fbFetch_a2b2g2r2; + case PICT_c8: return fbFetch_c8; + case PICT_g8: return fbFetch_c8; + + /* 4bpp formats */ + case PICT_a4: return fbFetch_a4; + case PICT_r1g2b1: return fbFetch_r1g2b1; + case PICT_b1g2r1: return fbFetch_b1g2r1; + case PICT_a1r1g1b1: return fbFetch_a1r1g1b1; + case PICT_a1b1g1r1: return fbFetch_a1b1g1r1; + case PICT_c4: return fbFetch_c4; + case PICT_g4: return fbFetch_c4; + + /* 1bpp formats */ + case PICT_a1: return fbFetch_a1; + case PICT_g1: return fbFetch_g1; + default: + return NULL; + } +} + +/* + * Pixel wise fetching + */ + +typedef FASTCALL CARD32 (*fetchPixelProc)(const FbBits *bits, int offset, miIndexedPtr indexed); + +static FASTCALL CARD32 +fbFetchPixel_a8r8g8b8 (const FbBits *bits, int offset, miIndexedPtr indexed) +{ + return ((CARD32 *)bits)[offset]; +} + +static FASTCALL CARD32 +fbFetchPixel_x8r8g8b8 (const FbBits *bits, int offset, miIndexedPtr indexed) +{ + return ((CARD32 *)bits)[offset] | 0xff000000; +} + +static FASTCALL CARD32 +fbFetchPixel_a8b8g8r8 (const FbBits *bits, int offset, miIndexedPtr indexed) +{ + CARD32 pixel = ((CARD32 *)bits)[offset]; + + return ((pixel & 0xff000000) | + ((pixel >> 16) & 0xff) | + (pixel & 0x0000ff00) | + ((pixel & 0xff) << 16)); +} + +static FASTCALL CARD32 +fbFetchPixel_x8b8g8r8 (const FbBits *bits, int offset, miIndexedPtr indexed) +{ + CARD32 pixel = ((CARD32 *)bits)[offset]; + + return ((0xff000000) | + ((pixel >> 16) & 0xff) | + (pixel & 0x0000ff00) | + ((pixel & 0xff) << 16)); +} + +static FASTCALL CARD32 +fbFetchPixel_r8g8b8 (const FbBits *bits, int offset, miIndexedPtr indexed) +{ + CARD8 *pixel = ((CARD8 *) bits) + (offset*3); +#if IMAGE_BYTE_ORDER == MSBFirst + return (0xff000000 | + (pixel[0] << 16) | + (pixel[1] << 8) | + (pixel[2])); +#else + return (0xff000000 | + (pixel[2] << 16) | + (pixel[1] << 8) | + (pixel[0])); +#endif +} + +static FASTCALL CARD32 +fbFetchPixel_b8g8r8 (const FbBits *bits, int offset, miIndexedPtr indexed) +{ + CARD8 *pixel = ((CARD8 *) bits) + (offset*3); +#if IMAGE_BYTE_ORDER == MSBFirst + return (0xff000000 | + (pixel[2] << 16) | + (pixel[1] << 8) | + (pixel[0])); +#else + return (0xff000000 | + (pixel[0] << 16) | + (pixel[1] << 8) | + (pixel[2])); +#endif +} + +static FASTCALL CARD32 +fbFetchPixel_r5g6b5 (const FbBits *bits, int offset, miIndexedPtr indexed) +{ + CARD32 pixel = ((CARD16 *) bits)[offset]; + CARD32 r,g,b; + + r = ((pixel & 0xf800) | ((pixel & 0xe000) >> 5)) << 8; + g = ((pixel & 0x07e0) | ((pixel & 0x0600) >> 6)) << 5; + b = ((pixel & 0x001c) | ((pixel & 0x001f) << 5)) >> 2; + return (0xff000000 | r | g | b); +} + +static FASTCALL CARD32 +fbFetchPixel_b5g6r5 (const FbBits *bits, int offset, miIndexedPtr indexed) +{ + CARD32 pixel = ((CARD16 *) bits)[offset]; + CARD32 r,g,b; + + b = ((pixel & 0xf800) | ((pixel & 0xe000) >> 5)) >> 8; + g = ((pixel & 0x07e0) | ((pixel & 0x0600) >> 6)) << 5; + r = ((pixel & 0x001c) | ((pixel & 0x001f) << 5)) << 14; + return (0xff000000 | r | g | b); +} + +static FASTCALL CARD32 +fbFetchPixel_a1r5g5b5 (const FbBits *bits, int offset, miIndexedPtr indexed) +{ + CARD32 pixel = ((CARD16 *) bits)[offset]; + CARD32 a,r,g,b; + + a = (CARD32) ((CARD8) (0 - ((pixel & 0x8000) >> 15))) << 24; + r = ((pixel & 0x7c00) | ((pixel & 0x7000) >> 5)) << 9; + g = ((pixel & 0x03e0) | ((pixel & 0x0380) >> 5)) << 6; + b = ((pixel & 0x001c) | ((pixel & 0x001f) << 5)) >> 2; + return (a | r | g | b); +} + +static FASTCALL CARD32 +fbFetchPixel_x1r5g5b5 (const FbBits *bits, int offset, miIndexedPtr indexed) +{ + CARD32 pixel = ((CARD16 *) bits)[offset]; + CARD32 r,g,b; + + r = ((pixel & 0x7c00) | ((pixel & 0x7000) >> 5)) << 9; + g = ((pixel & 0x03e0) | ((pixel & 0x0380) >> 5)) << 6; + b = ((pixel & 0x001c) | ((pixel & 0x001f) << 5)) >> 2; + return (0xff000000 | r | g | b); +} + +static FASTCALL CARD32 +fbFetchPixel_a1b5g5r5 (const FbBits *bits, int offset, miIndexedPtr indexed) +{ + CARD32 pixel = ((CARD16 *) bits)[offset]; + CARD32 a,r,g,b; + + a = (CARD32) ((CARD8) (0 - ((pixel & 0x8000) >> 15))) << 24; + b = ((pixel & 0x7c00) | ((pixel & 0x7000) >> 5)) >> 7; + g = ((pixel & 0x03e0) | ((pixel & 0x0380) >> 5)) << 6; + r = ((pixel & 0x001c) | ((pixel & 0x001f) << 5)) << 14; + return (a | r | g | b); +} + +static FASTCALL CARD32 +fbFetchPixel_x1b5g5r5 (const FbBits *bits, int offset, miIndexedPtr indexed) +{ + CARD32 pixel = ((CARD16 *) bits)[offset]; + CARD32 r,g,b; + + b = ((pixel & 0x7c00) | ((pixel & 0x7000) >> 5)) >> 7; + g = ((pixel & 0x03e0) | ((pixel & 0x0380) >> 5)) << 6; + r = ((pixel & 0x001c) | ((pixel & 0x001f) << 5)) << 14; + return (0xff000000 | r | g | b); +} + +static FASTCALL CARD32 +fbFetchPixel_a4r4g4b4 (const FbBits *bits, int offset, miIndexedPtr indexed) +{ + CARD32 pixel = ((CARD16 *) bits)[offset]; + CARD32 a,r,g,b; + + a = ((pixel & 0xf000) | ((pixel & 0xf000) >> 4)) << 16; + r = ((pixel & 0x0f00) | ((pixel & 0x0f00) >> 4)) << 12; + g = ((pixel & 0x00f0) | ((pixel & 0x00f0) >> 4)) << 8; + b = ((pixel & 0x000f) | ((pixel & 0x000f) << 4)); + return (a | r | g | b); +} + +static FASTCALL CARD32 +fbFetchPixel_x4r4g4b4 (const FbBits *bits, int offset, miIndexedPtr indexed) +{ + CARD32 pixel = ((CARD16 *) bits)[offset]; + CARD32 r,g,b; + + r = ((pixel & 0x0f00) | ((pixel & 0x0f00) >> 4)) << 12; + g = ((pixel & 0x00f0) | ((pixel & 0x00f0) >> 4)) << 8; + b = ((pixel & 0x000f) | ((pixel & 0x000f) << 4)); + return (0xff000000 | r | g | b); +} + +static FASTCALL CARD32 +fbFetchPixel_a4b4g4r4 (const FbBits *bits, int offset, miIndexedPtr indexed) +{ + CARD32 pixel = ((CARD16 *) bits)[offset]; + CARD32 a,r,g,b; + + a = ((pixel & 0xf000) | ((pixel & 0xf000) >> 4)) << 16; + b = ((pixel & 0x0f00) | ((pixel & 0x0f00) >> 4)) << 12; + g = ((pixel & 0x00f0) | ((pixel & 0x00f0) >> 4)) << 8; + r = ((pixel & 0x000f) | ((pixel & 0x000f) << 4)); + return (a | r | g | b); +} + +static FASTCALL CARD32 +fbFetchPixel_x4b4g4r4 (const FbBits *bits, int offset, miIndexedPtr indexed) +{ + CARD32 pixel = ((CARD16 *) bits)[offset]; + CARD32 r,g,b; + + b = ((pixel & 0x0f00) | ((pixel & 0x0f00) >> 4)) << 12; + g = ((pixel & 0x00f0) | ((pixel & 0x00f0) >> 4)) << 8; + r = ((pixel & 0x000f) | ((pixel & 0x000f) << 4)); + return (0xff000000 | r | g | b); +} + +static FASTCALL CARD32 +fbFetchPixel_a8 (const FbBits *bits, int offset, miIndexedPtr indexed) +{ + CARD32 pixel = ((CARD8 *) bits)[offset]; + + return pixel << 24; +} + +static FASTCALL CARD32 +fbFetchPixel_r3g3b2 (const FbBits *bits, int offset, miIndexedPtr indexed) +{ + CARD32 pixel = ((CARD8 *) bits)[offset]; + CARD32 r,g,b; + + r = ((pixel & 0xe0) | ((pixel & 0xe0) >> 3) | ((pixel & 0xc0) >> 6)) << 16; + g = ((pixel & 0x1c) | ((pixel & 0x18) >> 3) | ((pixel & 0x1c) << 3)) << 8; + b = (((pixel & 0x03) ) | + ((pixel & 0x03) << 2) | + ((pixel & 0x03) << 4) | + ((pixel & 0x03) << 6)); + return (0xff000000 | r | g | b); +} + +static FASTCALL CARD32 +fbFetchPixel_b2g3r3 (const FbBits *bits, int offset, miIndexedPtr indexed) +{ + CARD32 pixel = ((CARD8 *) bits)[offset]; + CARD32 r,g,b; + + b = (((pixel & 0xc0) ) | + ((pixel & 0xc0) >> 2) | + ((pixel & 0xc0) >> 4) | + ((pixel & 0xc0) >> 6)); + g = ((pixel & 0x38) | ((pixel & 0x38) >> 3) | ((pixel & 0x30) << 2)) << 8; + r = (((pixel & 0x07) ) | + ((pixel & 0x07) << 3) | + ((pixel & 0x06) << 6)) << 16; + return (0xff000000 | r | g | b); +} + +static FASTCALL CARD32 +fbFetchPixel_a2r2g2b2 (const FbBits *bits, int offset, miIndexedPtr indexed) +{ + CARD32 pixel = ((CARD8 *) bits)[offset]; + CARD32 a,r,g,b; + + a = ((pixel & 0xc0) * 0x55) << 18; + r = ((pixel & 0x30) * 0x55) << 12; + g = ((pixel & 0x0c) * 0x55) << 6; + b = ((pixel & 0x03) * 0x55); + return a|r|g|b; +} + +static FASTCALL CARD32 +fbFetchPixel_a2b2g2r2 (const FbBits *bits, int offset, miIndexedPtr indexed) +{ + CARD32 pixel = ((CARD8 *) bits)[offset]; + CARD32 a,r,g,b; + + a = ((pixel & 0xc0) * 0x55) << 18; + b = ((pixel & 0x30) * 0x55) >> 6; + g = ((pixel & 0x0c) * 0x55) << 6; + r = ((pixel & 0x03) * 0x55) << 16; + return a|r|g|b; +} + +static FASTCALL CARD32 +fbFetchPixel_c8 (const FbBits *bits, int offset, miIndexedPtr indexed) +{ + CARD32 pixel = ((CARD8 *) bits)[offset]; + return indexed->rgba[pixel]; +} + +#define Fetch8(l,o) (((CARD8 *) (l))[(o) >> 2]) +#if IMAGE_BYTE_ORDER == MSBFirst +#define Fetch4(l,o) ((o) & 2 ? Fetch8(l,o) & 0xf : Fetch8(l,o) >> 4) +#else +#define Fetch4(l,o) ((o) & 2 ? Fetch8(l,o) >> 4 : Fetch8(l,o) & 0xf) +#endif + +static FASTCALL CARD32 +fbFetchPixel_a4 (const FbBits *bits, int offset, miIndexedPtr indexed) +{ + CARD32 pixel = Fetch4(bits, offset); + + pixel |= pixel << 4; + return pixel << 24; +} + +static FASTCALL CARD32 +fbFetchPixel_r1g2b1 (const FbBits *bits, int offset, miIndexedPtr indexed) +{ + CARD32 pixel = Fetch4(bits, offset); + CARD32 r,g,b; + + r = ((pixel & 0x8) * 0xff) << 13; + g = ((pixel & 0x6) * 0x55) << 7; + b = ((pixel & 0x1) * 0xff); + return 0xff000000|r|g|b; +} + +static FASTCALL CARD32 +fbFetchPixel_b1g2r1 (const FbBits *bits, int offset, miIndexedPtr indexed) +{ + CARD32 pixel = Fetch4(bits, offset); + CARD32 r,g,b; + + b = ((pixel & 0x8) * 0xff) >> 3; + g = ((pixel & 0x6) * 0x55) << 7; + r = ((pixel & 0x1) * 0xff) << 16; + return 0xff000000|r|g|b; +} + +static FASTCALL CARD32 +fbFetchPixel_a1r1g1b1 (const FbBits *bits, int offset, miIndexedPtr indexed) +{ + CARD32 pixel = Fetch4(bits, offset); + CARD32 a,r,g,b; + + a = ((pixel & 0x8) * 0xff) << 21; + r = ((pixel & 0x4) * 0xff) << 14; + g = ((pixel & 0x2) * 0xff) << 7; + b = ((pixel & 0x1) * 0xff); + return a|r|g|b; +} + +static FASTCALL CARD32 +fbFetchPixel_a1b1g1r1 (const FbBits *bits, int offset, miIndexedPtr indexed) +{ + CARD32 pixel = Fetch4(bits, offset); + CARD32 a,r,g,b; + + a = ((pixel & 0x8) * 0xff) << 21; + r = ((pixel & 0x4) * 0xff) >> 3; + g = ((pixel & 0x2) * 0xff) << 7; + b = ((pixel & 0x1) * 0xff) << 16; + return a|r|g|b; +} + +static FASTCALL CARD32 +fbFetchPixel_c4 (const FbBits *bits, int offset, miIndexedPtr indexed) +{ + CARD32 pixel = Fetch4(bits, offset); + + return indexed->rgba[pixel]; +} + + +static FASTCALL CARD32 +fbFetchPixel_a1 (const FbBits *bits, int offset, miIndexedPtr indexed) +{ + CARD32 pixel = ((CARD32 *)bits)[offset >> 5]; + CARD32 a; +#if BITMAP_BIT_ORDER == MSBFirst + a = pixel >> (0x1f - (offset & 0x1f)); +#else + a = pixel >> (offset & 0x1f); +#endif + a = a & 1; + a |= a << 1; + a |= a << 2; + a |= a << 4; + return a << 24; +} + +static FASTCALL CARD32 +fbFetchPixel_g1 (const FbBits *bits, int offset, miIndexedPtr indexed) +{ + CARD32 pixel = ((CARD32 *)bits)[offset >> 5]; + CARD32 a; +#if BITMAP_BIT_ORDER == MSBFirst + a = pixel >> (0x1f - (offset & 0x1f)); +#else + a = pixel >> (offset & 0x1f); +#endif + a = a & 1; + return indexed->rgba[a]; +} + +static fetchPixelProc fetchPixelProcForPicture (PicturePtr pict) +{ + switch(pict->format) { + case PICT_a8r8g8b8: return fbFetchPixel_a8r8g8b8; + case PICT_x8r8g8b8: return fbFetchPixel_x8r8g8b8; + case PICT_a8b8g8r8: return fbFetchPixel_a8b8g8r8; + case PICT_x8b8g8r8: return fbFetchPixel_x8b8g8r8; + + /* 24bpp formats */ + case PICT_r8g8b8: return fbFetchPixel_r8g8b8; + case PICT_b8g8r8: return fbFetchPixel_b8g8r8; + + /* 16bpp formats */ + case PICT_r5g6b5: return fbFetchPixel_r5g6b5; + case PICT_b5g6r5: return fbFetchPixel_b5g6r5; + + case PICT_a1r5g5b5: return fbFetchPixel_a1r5g5b5; + case PICT_x1r5g5b5: return fbFetchPixel_x1r5g5b5; + case PICT_a1b5g5r5: return fbFetchPixel_a1b5g5r5; + case PICT_x1b5g5r5: return fbFetchPixel_x1b5g5r5; + case PICT_a4r4g4b4: return fbFetchPixel_a4r4g4b4; + case PICT_x4r4g4b4: return fbFetchPixel_x4r4g4b4; + case PICT_a4b4g4r4: return fbFetchPixel_a4b4g4r4; + case PICT_x4b4g4r4: return fbFetchPixel_x4b4g4r4; + + /* 8bpp formats */ + case PICT_a8: return fbFetchPixel_a8; + case PICT_r3g3b2: return fbFetchPixel_r3g3b2; + case PICT_b2g3r3: return fbFetchPixel_b2g3r3; + case PICT_a2r2g2b2: return fbFetchPixel_a2r2g2b2; + case PICT_a2b2g2r2: return fbFetchPixel_a2b2g2r2; + case PICT_c8: return fbFetchPixel_c8; + case PICT_g8: return fbFetchPixel_c8; + + /* 4bpp formats */ + case PICT_a4: return fbFetchPixel_a4; + case PICT_r1g2b1: return fbFetchPixel_r1g2b1; + case PICT_b1g2r1: return fbFetchPixel_b1g2r1; + case PICT_a1r1g1b1: return fbFetchPixel_a1r1g1b1; + case PICT_a1b1g1r1: return fbFetchPixel_a1b1g1r1; + case PICT_c4: return fbFetchPixel_c4; + case PICT_g4: return fbFetchPixel_c4; + + /* 1bpp formats */ + case PICT_a1: return fbFetchPixel_a1; + case PICT_g1: return fbFetchPixel_g1; + default: + return NULL; + } +} + + + +/* + * All the store functions + */ + +typedef FASTCALL void (*storeProc) (FbBits *bits, const CARD32 *values, int x, int width, miIndexedPtr indexed); + +#define Splita(v) CARD32 a = ((v) >> 24), r = ((v) >> 16) & 0xff, g = ((v) >> 8) & 0xff, b = (v) & 0xff +#define Split(v) CARD32 r = ((v) >> 16) & 0xff, g = ((v) >> 8) & 0xff, b = (v) & 0xff + +static FASTCALL void +fbStore_a8r8g8b8 (FbBits *bits, const CARD32 *values, int x, int width, miIndexedPtr indexed) +{ + memcpy(((CARD32 *)bits) + x, values, width*sizeof(CARD32)); +} + +static FASTCALL void +fbStore_x8r8g8b8 (FbBits *bits, const CARD32 *values, int x, int width, miIndexedPtr indexed) +{ + int i; + CARD32 *pixel = (CARD32 *)bits + x; + for (i = 0; i < width; ++i) + *pixel++ = values[i] & 0xffffff; +} + +static FASTCALL void +fbStore_a8b8g8r8 (FbBits *bits, const CARD32 *values, int x, int width, miIndexedPtr indexed) +{ + int i; + CARD32 *pixel = (CARD32 *)bits + x; + for (i = 0; i < width; ++i) + *pixel++ = (values[i] & 0xff00ff00) | ((values[i] >> 16) & 0xff) | ((values[i] & 0xff) << 16); +} + +static FASTCALL void +fbStore_x8b8g8r8 (FbBits *bits, const CARD32 *values, int x, int width, miIndexedPtr indexed) +{ + int i; + CARD32 *pixel = (CARD32 *)bits + x; + for (i = 0; i < width; ++i) + *pixel++ = (values[i] & 0x0000ff00) | ((values[i] >> 16) & 0xff) | ((values[i] & 0xff) << 16); +} + +static FASTCALL void +fbStore_r8g8b8 (FbBits *bits, const CARD32 *values, int x, int width, miIndexedPtr indexed) +{ + int i; + CARD8 *pixel = ((CARD8 *) bits) + 3*x; + for (i = 0; i < width; ++i) { + Store24(pixel, values[i]); + pixel += 3; + } +} + +static FASTCALL void +fbStore_b8g8r8 (FbBits *bits, const CARD32 *values, int x, int width, miIndexedPtr indexed) +{ + int i; + CARD8 *pixel = ((CARD8 *) bits) + 3*x; + for (i = 0; i < width; ++i) { +#if IMAGE_BYTE_ORDER == MSBFirst + *pixel++ = Blue(values[i]); + *pixel++ = Green(values[i]); + *pixel++ = Red(values[i]); +#else + *pixel++ = Red(values[i]); + *pixel++ = Green(values[i]); + *pixel++ = Blue(values[i]); +#endif + } +} + +static FASTCALL void +fbStore_r5g6b5 (FbBits *bits, const CARD32 *values, int x, int width, miIndexedPtr indexed) +{ + int i; + CARD16 *pixel = ((CARD16 *) bits) + x; + for (i = 0; i < width; ++i) { + CARD32 s = values[i]; + *pixel++ = ((s >> 3) & 0x001f) | + ((s >> 5) & 0x07e0) | + ((s >> 8) & 0xf800); + } +} + +static FASTCALL void +fbStore_b5g6r5 (FbBits *bits, const CARD32 *values, int x, int width, miIndexedPtr indexed) +{ + int i; + CARD16 *pixel = ((CARD16 *) bits) + x; + for (i = 0; i < width; ++i) { + Split(values[i]); + *pixel++ = (((b << 8) & 0xf800) | + ((g << 3) & 0x07e0) | + ((r >> 3) )); + } +} + +static FASTCALL void +fbStore_a1r5g5b5 (FbBits *bits, const CARD32 *values, int x, int width, miIndexedPtr indexed) +{ + int i; + CARD16 *pixel = ((CARD16 *) bits) + x; + for (i = 0; i < width; ++i) { + Splita(values[i]); + *pixel++ = (((a << 8) & 0x8000) | + ((r << 7) & 0x7c00) | + ((g << 2) & 0x03e0) | + ((b >> 3) )); + } +} + +static FASTCALL void +fbStore_x1r5g5b5 (FbBits *bits, const CARD32 *values, int x, int width, miIndexedPtr indexed) +{ + int i; + CARD16 *pixel = ((CARD16 *) bits) + x; + for (i = 0; i < width; ++i) { + Split(values[i]); + *pixel++ = (((r << 7) & 0x7c00) | + ((g << 2) & 0x03e0) | + ((b >> 3) )); + } +} + +static FASTCALL void +fbStore_a1b5g5r5 (FbBits *bits, const CARD32 *values, int x, int width, miIndexedPtr indexed) +{ + int i; + CARD16 *pixel = ((CARD16 *) bits) + x; + for (i = 0; i < width; ++i) { + Splita(values[i]); + *pixel++ = (((a << 8) & 0x8000) | + ((b << 7) & 0x7c00) | + ((g << 2) & 0x03e0) | + ((r >> 3) )); + } +} + +static FASTCALL void +fbStore_x1b5g5r5 (FbBits *bits, const CARD32 *values, int x, int width, miIndexedPtr indexed) +{ + int i; + CARD16 *pixel = ((CARD16 *) bits) + x; + for (i = 0; i < width; ++i) { + Split(values[i]); + *pixel++ = (((b << 7) & 0x7c00) | + ((g << 2) & 0x03e0) | + ((r >> 3) )); + } +} + +static FASTCALL void +fbStore_a4r4g4b4 (FbBits *bits, const CARD32 *values, int x, int width, miIndexedPtr indexed) +{ + int i; + CARD16 *pixel = ((CARD16 *) bits) + x; + for (i = 0; i < width; ++i) { + Splita(values[i]); + *pixel++ = (((a << 8) & 0xf000) | + ((r << 4) & 0x0f00) | + ((g ) & 0x00f0) | + ((b >> 4) )); + } +} + +static FASTCALL void +fbStore_x4r4g4b4 (FbBits *bits, const CARD32 *values, int x, int width, miIndexedPtr indexed) +{ + int i; + CARD16 *pixel = ((CARD16 *) bits) + x; + for (i = 0; i < width; ++i) { + Split(values[i]); + *pixel++ = (((r << 4) & 0x0f00) | + ((g ) & 0x00f0) | + ((b >> 4) )); + } +} + +static FASTCALL void +fbStore_a4b4g4r4 (FbBits *bits, const CARD32 *values, int x, int width, miIndexedPtr indexed) +{ + int i; + CARD16 *pixel = ((CARD16 *) bits) + x; + for (i = 0; i < width; ++i) { + Splita(values[i]); + *pixel++ = (((a << 8) & 0xf000) | + ((b << 4) & 0x0f00) | + ((g ) & 0x00f0) | + ((r >> 4) )); + } +} + +static FASTCALL void +fbStore_x4b4g4r4 (FbBits *bits, const CARD32 *values, int x, int width, miIndexedPtr indexed) +{ + int i; + CARD16 *pixel = ((CARD16 *) bits) + x; + for (i = 0; i < width; ++i) { + Split(values[i]); + *pixel++ = (((b << 4) & 0x0f00) | + ((g ) & 0x00f0) | + ((r >> 4) )); + } +} + +static FASTCALL void +fbStore_a8 (FbBits *bits, const CARD32 *values, int x, int width, miIndexedPtr indexed) +{ + int i; + CARD8 *pixel = ((CARD8 *) bits) + x; + for (i = 0; i < width; ++i) { + *pixel++ = values[i] >> 24; + } +} + +static FASTCALL void +fbStore_r3g3b2 (FbBits *bits, const CARD32 *values, int x, int width, miIndexedPtr indexed) +{ + int i; + CARD8 *pixel = ((CARD8 *) bits) + x; + for (i = 0; i < width; ++i) { + Split(values[i]); + *pixel++ = (((r ) & 0xe0) | + ((g >> 3) & 0x1c) | + ((b >> 6) )); + } +} + +static FASTCALL void +fbStore_b2g3r3 (FbBits *bits, const CARD32 *values, int x, int width, miIndexedPtr indexed) +{ + int i; + CARD8 *pixel = ((CARD8 *) bits) + x; + for (i = 0; i < width; ++i) { + Split(values[i]); + *pixel++ = (((b ) & 0xe0) | + ((g >> 3) & 0x1c) | + ((r >> 6) )); + } +} + +static FASTCALL void +fbStore_a2r2g2b2 (FbBits *bits, const CARD32 *values, int x, int width, miIndexedPtr indexed) +{ + int i; + CARD8 *pixel = ((CARD8 *) bits) + x; + for (i = 0; i < width; ++i) { + Splita(values[i]); + *pixel++ = (((a ) & 0xc0) | + ((r >> 2) & 0x30) | + ((g >> 4) & 0x0c) | + ((b >> 6) )); + } +} + +static FASTCALL void +fbStore_c8 (FbBits *bits, const CARD32 *values, int x, int width, miIndexedPtr indexed) +{ + int i; + CARD8 *pixel = ((CARD8 *) bits) + x; + for (i = 0; i < width; ++i) { + *pixel++ = miIndexToEnt24(indexed,values[i]); + } +} + +#define Store8(l,o,v) (((CARD8 *) l)[(o) >> 3] = (v)) +#if IMAGE_BYTE_ORDER == MSBFirst +#define Store4(l,o,v) Store8(l,o,((o) & 4 ? \ + (Fetch8(l,o) & 0xf0) | (v) : \ + (Fetch8(l,o) & 0x0f) | ((v) << 4))) +#else +#define Store4(l,o,v) Store8(l,o,((o) & 4 ? \ + (Fetch8(l,o) & 0x0f) | ((v) << 4) : \ + (Fetch8(l,o) & 0xf0) | (v))) +#endif + +static FASTCALL void +fbStore_a4 (FbBits *bits, const CARD32 *values, int x, int width, miIndexedPtr indexed) +{ + int i; + for (i = 0; i < width; ++i) { + Store4(bits, i + x, values[i]>>28); + } +} + +static FASTCALL void +fbStore_r1g2b1 (FbBits *bits, const CARD32 *values, int x, int width, miIndexedPtr indexed) +{ + int i; + for (i = 0; i < width; ++i) { + CARD32 pixel; + + Split(values[i]); + pixel = (((r >> 4) & 0x8) | + ((g >> 5) & 0x6) | + ((b >> 7) )); + Store4(bits, i + x, pixel); + } +} + +static FASTCALL void +fbStore_b1g2r1 (FbBits *bits, const CARD32 *values, int x, int width, miIndexedPtr indexed) +{ + int i; + for (i = 0; i < width; ++i) { + CARD32 pixel; + + Split(values[i]); + pixel = (((b >> 4) & 0x8) | + ((g >> 5) & 0x6) | + ((r >> 7) )); + Store4(bits, i + x, pixel); + } +} + +static FASTCALL void +fbStore_a1r1g1b1 (FbBits *bits, const CARD32 *values, int x, int width, miIndexedPtr indexed) +{ + int i; + for (i = 0; i < width; ++i) { + CARD32 pixel; + Splita(values[i]); + pixel = (((a >> 4) & 0x8) | + ((r >> 5) & 0x4) | + ((g >> 6) & 0x2) | + ((b >> 7) )); + Store4(bits, i + x, pixel); + } +} + +static FASTCALL void +fbStore_a1b1g1r1 (FbBits *bits, const CARD32 *values, int x, int width, miIndexedPtr indexed) +{ + int i; + for (i = 0; i < width; ++i) { + CARD32 pixel; + Splita(values[i]); + pixel = (((a >> 4) & 0x8) | + ((b >> 5) & 0x4) | + ((g >> 6) & 0x2) | + ((r >> 7) )); + Store4(bits, i + x, pixel); + } +} + +static FASTCALL void +fbStore_c4 (FbBits *bits, const CARD32 *values, int x, int width, miIndexedPtr indexed) +{ + int i; + for (i = 0; i < width; ++i) { + CARD32 pixel; + + pixel = miIndexToEnt24(indexed, values[i]); + Store4(bits, i + x, pixel); + } +} + +static FASTCALL void +fbStore_a1 (FbBits *bits, const CARD32 *values, int x, int width, miIndexedPtr indexed) +{ + int i; + for (i = 0; i < width; ++i) { + CARD32 *pixel = ((CARD32 *) bits) + ((i+x) >> 5); + CARD32 mask = FbStipMask((i+x) & 0x1f, 1); + + CARD32 v = values[i] & 0x80000000 ? mask : 0; + *pixel = (*pixel & ~mask) | v; + } +} + +static FASTCALL void +fbStore_g1 (FbBits *bits, const CARD32 *values, int x, int width, miIndexedPtr indexed) +{ + int i; + for (i = 0; i < width; ++i) { + CARD32 *pixel = ((CARD32 *) bits) + ((i+x) >> 5); + CARD32 mask = FbStipMask((i+x) & 0x1f, 1); + + CARD32 v = miIndexToEntY24(indexed,values[i]) ? mask : 0; + *pixel = (*pixel & ~mask) | v; + } +} + + +static storeProc storeProcForPicture (PicturePtr pict) +{ + switch(pict->format) { + case PICT_a8r8g8b8: return fbStore_a8r8g8b8; + case PICT_x8r8g8b8: return fbStore_x8r8g8b8; + case PICT_a8b8g8r8: return fbStore_a8b8g8r8; + case PICT_x8b8g8r8: return fbStore_x8b8g8r8; + + /* 24bpp formats */ + case PICT_r8g8b8: return fbStore_r8g8b8; + case PICT_b8g8r8: return fbStore_b8g8r8; + + /* 16bpp formats */ + case PICT_r5g6b5: return fbStore_r5g6b5; + case PICT_b5g6r5: return fbStore_b5g6r5; + + case PICT_a1r5g5b5: return fbStore_a1r5g5b5; + case PICT_x1r5g5b5: return fbStore_x1r5g5b5; + case PICT_a1b5g5r5: return fbStore_a1b5g5r5; + case PICT_x1b5g5r5: return fbStore_x1b5g5r5; + case PICT_a4r4g4b4: return fbStore_a4r4g4b4; + case PICT_x4r4g4b4: return fbStore_x4r4g4b4; + case PICT_a4b4g4r4: return fbStore_a4b4g4r4; + case PICT_x4b4g4r4: return fbStore_x4b4g4r4; + + /* 8bpp formats */ + case PICT_a8: return fbStore_a8; + case PICT_r3g3b2: return fbStore_r3g3b2; + case PICT_b2g3r3: return fbStore_b2g3r3; + case PICT_a2r2g2b2: return fbStore_a2r2g2b2; + case PICT_c8: return fbStore_c8; + case PICT_g8: return fbStore_c8; + + /* 4bpp formats */ + case PICT_a4: return fbStore_a4; + case PICT_r1g2b1: return fbStore_r1g2b1; + case PICT_b1g2r1: return fbStore_b1g2r1; + case PICT_a1r1g1b1: return fbStore_a1r1g1b1; + case PICT_a1b1g1r1: return fbStore_a1b1g1r1; + case PICT_c4: return fbStore_c4; + case PICT_g4: return fbStore_c4; + + /* 1bpp formats */ + case PICT_a1: return fbStore_a1; + case PICT_g1: return fbStore_g1; + default: + return NULL; + } +} + + +/* + * Combine src and mask + */ +static FASTCALL void +fbCombineMaskU (CARD32 *src, const CARD32 *mask, int width) +{ + int i; + for (i = 0; i < width; ++i) { + CARD32 a = mask[i] >> 24; + CARD32 s = src[i]; + FbByteMul(s, a); + src[i] = s; + } +} + +/* + * All of the composing functions + */ + +static FASTCALL void +fbCombineClear (CARD32 *dest, const CARD32 *src, int width) +{ + memset(dest, 0, width*sizeof(CARD32)); +} + +static FASTCALL void +fbCombineSrcU (CARD32 *dest, const CARD32 *src, int width) +{ + memcpy(dest, src, width*sizeof(CARD32)); +} + + +static FASTCALL void +fbCombineOverU (CARD32 *dest, const CARD32 *src, int width) +{ + int i; + for (i = 0; i < width; ++i) { + CARD32 s = src[i]; + CARD32 d = dest[i]; + CARD32 ia = Alpha(~s); + + FbByteMulAdd(d, ia, s); + dest[i] = d; + } +} + +static FASTCALL void +fbCombineOverReverseU (CARD32 *dest, const CARD32 *src, int width) +{ + int i; + for (i = 0; i < width; ++i) { + CARD32 s = src[i]; + CARD32 d = dest[i]; + CARD32 ia = Alpha(~dest[i]); + FbByteMulAdd(s, ia, d); + dest[i] = s; + } +} + +static FASTCALL void +fbCombineInU (CARD32 *dest, const CARD32 *src, int width) +{ + int i; + for (i = 0; i < width; ++i) { + CARD32 s = src[i]; + CARD32 a = Alpha(dest[i]); + FbByteMul(s, a); + dest[i] = s; + } +} + +static FASTCALL void +fbCombineInReverseU (CARD32 *dest, const CARD32 *src, int width) +{ + int i; + for (i = 0; i < width; ++i) { + CARD32 d = dest[i]; + CARD32 a = Alpha(src[i]); + FbByteMul(d, a); + dest[i] = d; + } +} + +static FASTCALL void +fbCombineOutU (CARD32 *dest, const CARD32 *src, int width) +{ + int i; + for (i = 0; i < width; ++i) { + CARD32 s = src[i]; + CARD32 a = Alpha(~dest[i]); + FbByteMul(s, a); + dest[i] = s; + } +} + +static FASTCALL void +fbCombineOutReverseU (CARD32 *dest, const CARD32 *src, int width) +{ + int i; + for (i = 0; i < width; ++i) { + CARD32 d = dest[i]; + CARD32 a = Alpha(~src[i]); + FbByteMul(d, a); + dest[i] = d; + } +} + +static FASTCALL void +fbCombineAtopU (CARD32 *dest, const CARD32 *src, int width) +{ + int i; + for (i = 0; i < width; ++i) { + CARD32 s = src[i]; + CARD32 d = dest[i]; + CARD32 dest_a = Alpha(d); + CARD32 src_ia = Alpha(~s); + + FbByteAddMul(s, dest_a, d, src_ia); + dest[i] = s; + } +} + +static FASTCALL void +fbCombineAtopReverseU (CARD32 *dest, const CARD32 *src, int width) +{ + int i; + for (i = 0; i < width; ++i) { + CARD32 s = src[i]; + CARD32 d = dest[i]; + CARD32 src_a = Alpha(s); + CARD32 dest_ia = Alpha(~d); + + FbByteAddMul(s, dest_ia, d, src_a); + dest[i] = s; + } +} + +static FASTCALL void +fbCombineXorU (CARD32 *dest, const CARD32 *src, int width) +{ + int i; + for (i = 0; i < width; ++i) { + CARD32 s = src[i]; + CARD32 d = dest[i]; + CARD32 src_ia = Alpha(~s); + CARD32 dest_ia = Alpha(~d); + + FbByteAddMul(s, dest_ia, d, src_ia); + dest[i] = s; + } +} + +static FASTCALL void +fbCombineAddU (CARD32 *dest, const CARD32 *src, int width) +{ + int i; + for (i = 0; i < width; ++i) { + CARD32 s = src[i]; + CARD32 d = dest[i]; + FbByteAdd(d, s); + dest[i] = d; + } +} + +static FASTCALL void +fbCombineSaturateU (CARD32 *dest, const CARD32 *src, int width) +{ + int i; + for (i = 0; i < width; ++i) { + CARD32 s = src[i]; + CARD32 d = dest[i]; + CARD16 sa, da; + + sa = s >> 24; + da = ~d >> 24; + if (sa > da) + { + sa = FbIntDiv(da, sa); + FbByteMul(s, sa); + } + FbByteAdd(d, s); + dest[i] = d; + } +} + +/* + * All of the disjoint composing functions + + The four entries in the first column indicate what source contributions + come from each of the four areas of the picture -- areas covered by neither + A nor B, areas covered only by A, areas covered only by B and finally + areas covered by both A and B. + + Disjoint Conjoint + Fa Fb Fa Fb +(0,0,0,0) 0 0 0 0 +(0,A,0,A) 1 0 1 0 +(0,0,B,B) 0 1 0 1 +(0,A,B,A) 1 min((1-a)/b,1) 1 max(1-a/b,0) +(0,A,B,B) min((1-b)/a,1) 1 max(1-b/a,0) 1 +(0,0,0,A) max(1-(1-b)/a,0) 0 min(1,b/a) 0 +(0,0,0,B) 0 max(1-(1-a)/b,0) 0 min(a/b,1) +(0,A,0,0) min(1,(1-b)/a) 0 max(1-b/a,0) 0 +(0,0,B,0) 0 min(1,(1-a)/b) 0 max(1-a/b,0) +(0,0,B,A) max(1-(1-b)/a,0) min(1,(1-a)/b) min(1,b/a) max(1-a/b,0) +(0,A,0,B) min(1,(1-b)/a) max(1-(1-a)/b,0) max(1-b/a,0) min(1,a/b) +(0,A,B,0) min(1,(1-b)/a) min(1,(1-a)/b) max(1-b/a,0) max(1-a/b,0) + + */ + +#define CombineAOut 1 +#define CombineAIn 2 +#define CombineBOut 4 +#define CombineBIn 8 + +#define CombineClear 0 +#define CombineA (CombineAOut|CombineAIn) +#define CombineB (CombineBOut|CombineBIn) +#define CombineAOver (CombineAOut|CombineBOut|CombineAIn) +#define CombineBOver (CombineAOut|CombineBOut|CombineBIn) +#define CombineAAtop (CombineBOut|CombineAIn) +#define CombineBAtop (CombineAOut|CombineBIn) +#define CombineXor (CombineAOut|CombineBOut) + +/* portion covered by a but not b */ +static INLINE CARD8 +fbCombineDisjointOutPart (CARD8 a, CARD8 b) +{ + /* min (1, (1-b) / a) */ + + b = ~b; /* 1 - b */ + if (b >= a) /* 1 - b >= a -> (1-b)/a >= 1 */ + return 0xff; /* 1 */ + return FbIntDiv(b,a); /* (1-b) / a */ +} + +/* portion covered by both a and b */ +static INLINE CARD8 +fbCombineDisjointInPart (CARD8 a, CARD8 b) +{ + /* max (1-(1-b)/a,0) */ + /* = - min ((1-b)/a - 1, 0) */ + /* = 1 - min (1, (1-b)/a) */ + + b = ~b; /* 1 - b */ + if (b >= a) /* 1 - b >= a -> (1-b)/a >= 1 */ + return 0; /* 1 - 1 */ + return ~FbIntDiv(b,a); /* 1 - (1-b) / a */ +} + +static FASTCALL void +fbCombineDisjointGeneralU (CARD32 *dest, const CARD32 *src, int width, CARD8 combine) +{ + int i; + for (i = 0; i < width; ++i) { + CARD32 s = src[i]; + CARD32 d = dest[i]; + CARD32 m,n,o,p; + CARD16 Fa, Fb, t, u, v; + CARD8 sa = s >> 24; + CARD8 da = d >> 24; + + switch (combine & CombineA) { + default: + Fa = 0; + break; + case CombineAOut: + Fa = fbCombineDisjointOutPart (sa, da); + break; + case CombineAIn: + Fa = fbCombineDisjointInPart (sa, da); + break; + case CombineA: + Fa = 0xff; + break; + } + + switch (combine & CombineB) { + default: + Fb = 0; + break; + case CombineBOut: + Fb = fbCombineDisjointOutPart (da, sa); + break; + case CombineBIn: + Fb = fbCombineDisjointInPart (da, sa); + break; + case CombineB: + Fb = 0xff; + break; + } + m = FbGen (s,d,0,Fa,Fb,t, u, v); + n = FbGen (s,d,8,Fa,Fb,t, u, v); + o = FbGen (s,d,16,Fa,Fb,t, u, v); + p = FbGen (s,d,24,Fa,Fb,t, u, v); + s = m|n|o|p; + dest[i] = s; + } +} + +static FASTCALL void +fbCombineDisjointOverU (CARD32 *dest, const CARD32 *src, int width) +{ + int i; + for (i = 0; i < width; ++i) { + CARD32 s = src[i]; + CARD16 a = s >> 24; + + if (a != 0x00) + { + if (a != 0xff) + { + CARD32 d = dest[i]; + a = fbCombineDisjointOutPart (d >> 24, a); + FbByteMulAdd(d, a, s); + s = d; + } + dest[i] = s; + } + } +} + +static FASTCALL void +fbCombineDisjointInU (CARD32 *dest, const CARD32 *src, int width) +{ + fbCombineDisjointGeneralU (dest, src, width, CombineAIn); +} + +static FASTCALL void +fbCombineDisjointInReverseU (CARD32 *dest, const CARD32 *src, int width) +{ + fbCombineDisjointGeneralU (dest, src, width, CombineBIn); +} + +static FASTCALL void +fbCombineDisjointOutU (CARD32 *dest, const CARD32 *src, int width) +{ + fbCombineDisjointGeneralU (dest, src, width, CombineAOut); +} + +static FASTCALL void +fbCombineDisjointOutReverseU (CARD32 *dest, const CARD32 *src, int width) +{ + fbCombineDisjointGeneralU (dest, src, width, CombineBOut); +} + +static FASTCALL void +fbCombineDisjointAtopU (CARD32 *dest, const CARD32 *src, int width) +{ + fbCombineDisjointGeneralU (dest, src, width, CombineAAtop); +} + +static FASTCALL void +fbCombineDisjointAtopReverseU (CARD32 *dest, const CARD32 *src, int width) +{ + fbCombineDisjointGeneralU (dest, src, width, CombineBAtop); +} + +static FASTCALL void +fbCombineDisjointXorU (CARD32 *dest, const CARD32 *src, int width) +{ + fbCombineDisjointGeneralU (dest, src, width, CombineXor); +} + +/* portion covered by a but not b */ +static INLINE CARD8 +fbCombineConjointOutPart (CARD8 a, CARD8 b) +{ + /* max (1-b/a,0) */ + /* = 1-min(b/a,1) */ + + /* min (1, (1-b) / a) */ + + if (b >= a) /* b >= a -> b/a >= 1 */ + return 0x00; /* 0 */ + return ~FbIntDiv(b,a); /* 1 - b/a */ +} + +/* portion covered by both a and b */ +static INLINE CARD8 +fbCombineConjointInPart (CARD8 a, CARD8 b) +{ + /* min (1,b/a) */ + + if (b >= a) /* b >= a -> b/a >= 1 */ + return 0xff; /* 1 */ + return FbIntDiv(b,a); /* b/a */ +} + +static FASTCALL void +fbCombineConjointGeneralU (CARD32 *dest, const CARD32 *src, int width, CARD8 combine) +{ + int i; + for (i = 0; i < width; ++i) { + CARD32 s = src[i]; + CARD32 d = dest[i]; + CARD32 m,n,o,p; + CARD16 Fa, Fb, t, u, v; + CARD8 sa = s >> 24; + CARD8 da = d >> 24; + + switch (combine & CombineA) { + default: + Fa = 0; + break; + case CombineAOut: + Fa = fbCombineConjointOutPart (sa, da); + break; + case CombineAIn: + Fa = fbCombineConjointInPart (sa, da); + break; + case CombineA: + Fa = 0xff; + break; + } + + switch (combine & CombineB) { + default: + Fb = 0; + break; + case CombineBOut: + Fb = fbCombineConjointOutPart (da, sa); + break; + case CombineBIn: + Fb = fbCombineConjointInPart (da, sa); + break; + case CombineB: + Fb = 0xff; + break; + } + m = FbGen (s,d,0,Fa,Fb,t, u, v); + n = FbGen (s,d,8,Fa,Fb,t, u, v); + o = FbGen (s,d,16,Fa,Fb,t, u, v); + p = FbGen (s,d,24,Fa,Fb,t, u, v); + s = m|n|o|p; + dest[i] = s; + } +} + +static FASTCALL void +fbCombineConjointOverU (CARD32 *dest, const CARD32 *src, int width) +{ + fbCombineConjointGeneralU (dest, src, width, CombineAOver); +} + + +static FASTCALL void +fbCombineConjointOverReverseU (CARD32 *dest, const CARD32 *src, int width) +{ + fbCombineConjointGeneralU (dest, src, width, CombineBOver); +} + + +static FASTCALL void +fbCombineConjointInU (CARD32 *dest, const CARD32 *src, int width) +{ + fbCombineConjointGeneralU (dest, src, width, CombineAIn); +} + + +static FASTCALL void +fbCombineConjointInReverseU (CARD32 *dest, const CARD32 *src, int width) +{ + fbCombineConjointGeneralU (dest, src, width, CombineBIn); +} + +static FASTCALL void +fbCombineConjointOutU (CARD32 *dest, const CARD32 *src, int width) +{ + fbCombineConjointGeneralU (dest, src, width, CombineAOut); +} + +static FASTCALL void +fbCombineConjointOutReverseU (CARD32 *dest, const CARD32 *src, int width) +{ + fbCombineConjointGeneralU (dest, src, width, CombineBOut); +} + +static FASTCALL void +fbCombineConjointAtopU (CARD32 *dest, const CARD32 *src, int width) +{ + fbCombineConjointGeneralU (dest, src, width, CombineAAtop); +} + +static FASTCALL void +fbCombineConjointAtopReverseU (CARD32 *dest, const CARD32 *src, int width) +{ + fbCombineConjointGeneralU (dest, src, width, CombineBAtop); +} + +static FASTCALL void +fbCombineConjointXorU (CARD32 *dest, const CARD32 *src, int width) +{ + fbCombineConjointGeneralU (dest, src, width, CombineXor); +} + +static CombineFuncU fbCombineFuncU[] = { + fbCombineClear, + fbCombineSrcU, + NULL, /* CombineDst */ + fbCombineOverU, + fbCombineOverReverseU, + fbCombineInU, + fbCombineInReverseU, + fbCombineOutU, + fbCombineOutReverseU, + fbCombineAtopU, + fbCombineAtopReverseU, + fbCombineXorU, + fbCombineAddU, + fbCombineSaturateU, + NULL, + NULL, + fbCombineClear, + fbCombineSrcU, + NULL, /* CombineDst */ + fbCombineDisjointOverU, + fbCombineSaturateU, /* DisjointOverReverse */ + fbCombineDisjointInU, + fbCombineDisjointInReverseU, + fbCombineDisjointOutU, + fbCombineDisjointOutReverseU, + fbCombineDisjointAtopU, + fbCombineDisjointAtopReverseU, + fbCombineDisjointXorU, + NULL, + NULL, + NULL, + NULL, + fbCombineClear, + fbCombineSrcU, + NULL, /* CombineDst */ + fbCombineConjointOverU, + fbCombineConjointOverReverseU, + fbCombineConjointInU, + fbCombineConjointInReverseU, + fbCombineConjointOutU, + fbCombineConjointOutReverseU, + fbCombineConjointAtopU, + fbCombineConjointAtopReverseU, + fbCombineConjointXorU, +}; + +static FASTCALL void +fbCombineMaskC (CARD32 *src, CARD32 *mask, int width) +{ + int i; + for (i = 0; i < width; ++i) { + CARD32 a = mask[i]; + + CARD32 x; + CARD16 xa; + + if (!a) + { + src[i] = 0; + continue; + } + + x = src[i]; + if (a == 0xffffffff) + { + x = x >> 24; + x |= x << 8; + x |= x << 16; + mask[i] = x; + continue; + } + + xa = x >> 24; + FbByteMulC(x, a); + src[i] = x; + FbByteMul(a, xa); + mask[i] = a; + } +} + +static FASTCALL void +fbCombineMaskValueC (CARD32 *src, const CARD32 *mask, int width) +{ + int i; + for (i = 0; i < width; ++i) { + CARD32 a = mask[i]; + CARD32 x; + + if (!a) + { + src[i] = 0; + continue; + } + + if (a == 0xffffffff) + continue; + + x = src[i]; + FbByteMulC(x, a); + src[i] = x; + } +} + + +static FASTCALL void +fbCombineMaskAlphaC (const CARD32 *src, CARD32 *mask, int width) +{ + int i; + for (i = 0; i < width; ++i) { + CARD32 a = mask[i]; + CARD32 x; + + if (!a) + continue; + + x = src[i] >> 24; + if (x == 0xff) + continue; + if (a == 0xffffffff) + { + x = x >> 24; + x |= x << 8; + x |= x << 16; + mask[i] = x; + continue; + } + + FbByteMul(a, x); + mask[i] = a; + } +} + +static FASTCALL void +fbCombineClearC (CARD32 *dest, CARD32 *src, CARD32 *mask, int width) +{ + memset(dest, 0, width*sizeof(CARD32)); +} + +static FASTCALL void +fbCombineSrcC (CARD32 *dest, CARD32 *src, CARD32 *mask, int width) +{ + fbCombineMaskValueC(src, mask, width); + memcpy(dest, src, width*sizeof(CARD32)); +} + +static FASTCALL void +fbCombineOverC (CARD32 *dest, CARD32 *src, CARD32 *mask, int width) +{ + int i; + fbCombineMaskC(src, mask, width); + for (i = 0; i < width; ++i) { + CARD32 s = src[i]; + CARD32 a = ~mask[i]; + + if (a != 0xffffffff) + { + if (a) + { + CARD32 d = dest[i]; + FbByteMulAddC(d, a, s); + s = d; + } + dest[i] = s; + } + } +} + +static FASTCALL void +fbCombineOverReverseC (CARD32 *dest, CARD32 *src, CARD32 *mask, int width) +{ + int i; + fbCombineMaskValueC(src, mask, width); + for (i = 0; i < width; ++i) { + CARD32 d = dest[i]; + CARD32 a = ~d >> 24; + + if (a) + { + CARD32 s = src[i]; + if (a != 0xff) + { + FbByteMulAdd(s, a, d); + } + dest[i] = s; + } + } +} + +static FASTCALL void +fbCombineInC (CARD32 *dest, CARD32 *src, CARD32 *mask, int width) +{ + int i; + fbCombineMaskValueC(src, mask, width); + for (i = 0; i < width; ++i) { + CARD32 d = dest[i]; + CARD16 a = d >> 24; + CARD32 s = 0; + if (a) + { + s = src[i]; + if (a != 0xff) + { + FbByteMul(s, a); + } + } + dest[i] = s; + } +} + +static FASTCALL void +fbCombineInReverseC (CARD32 *dest, CARD32 *src, CARD32 *mask, int width) +{ + int i; + fbCombineMaskAlphaC(src, mask, width); + for (i = 0; i < width; ++i) { + CARD32 a = mask[i]; + + if (a != 0xffffffff) + { + CARD32 d = 0; + if (a) + { + d = dest[i]; + FbByteMulC(d, a); + } + dest[i] = d; + } + } +} + +static FASTCALL void +fbCombineOutC (CARD32 *dest, CARD32 *src, CARD32 *mask, int width) +{ + int i; + fbCombineMaskValueC(src, mask, width); + for (i = 0; i < width; ++i) { + CARD32 d = dest[i]; + CARD16 a = ~d >> 24; + CARD32 s = 0; + if (a) + { + s = src[i]; + if (a != 0xff) + { + FbByteMul(s, a); + } + } + dest[i] = s; + } +} + +static FASTCALL void +fbCombineOutReverseC (CARD32 *dest, CARD32 *src, CARD32 *mask, int width) +{ + int i; + fbCombineMaskAlphaC(src, mask, width); + for (i = 0; i < width; ++i) { + CARD32 a = ~mask[i]; + + if (a != 0xffffffff) + { + CARD32 d = 0; + if (a) + { + d = dest[i]; + FbByteMulC(d, a); + } + dest[i] = d; + } + } +} + +static FASTCALL void +fbCombineAtopC (CARD32 *dest, CARD32 *src, CARD32 *mask, int width) +{ + int i; + fbCombineMaskC(src, mask, width); + for (i = 0; i < width; ++i) { + CARD32 d = dest[i]; + CARD32 s = src[i]; + CARD32 ad = ~mask[i]; + CARD16 as = d >> 24; + FbByteAddMulC(d, ad, s, as); + dest[i] = d; + } +} + +static FASTCALL void +fbCombineAtopReverseC (CARD32 *dest, CARD32 *src, CARD32 *mask, int width) +{ + int i; + fbCombineMaskC(src, mask, width); + for (i = 0; i < width; ++i) { + + CARD32 d = dest[i]; + CARD32 s = src[i]; + CARD32 ad = mask[i]; + CARD16 as = ~d >> 24; + FbByteAddMulC(d, ad, s, as); + dest[i] = d; + } +} + +static FASTCALL void +fbCombineXorC (CARD32 *dest, CARD32 *src, CARD32 *mask, int width) +{ + int i; + fbCombineMaskC(src, mask, width); + for (i = 0; i < width; ++i) { + CARD32 d = dest[i]; + CARD32 s = src[i]; + CARD32 ad = ~mask[i]; + CARD16 as = ~d >> 24; + FbByteAddMulC(d, ad, s, as); + dest[i] = d; + } +} + +static FASTCALL void +fbCombineAddC (CARD32 *dest, CARD32 *src, CARD32 *mask, int width) +{ + int i; + fbCombineMaskValueC(src, mask, width); + for (i = 0; i < width; ++i) { + CARD32 s = src[i]; + CARD32 d = dest[i]; + FbByteAdd(d, s); + dest[i] = d; + } +} + +static FASTCALL void +fbCombineSaturateC (CARD32 *dest, CARD32 *src, CARD32 *mask, int width) +{ + int i; + fbCombineMaskC(src, mask, width); + for (i = 0; i < width; ++i) { + CARD32 s, d; + CARD16 sa, sr, sg, sb, da; + CARD16 t, u, v; + CARD32 m,n,o,p; + + d = dest[i]; + s = src[i]; + sa = (mask[i] >> 24); + sr = (mask[i] >> 16) & 0xff; + sg = (mask[i] >> 8) & 0xff; + sb = (mask[i] ) & 0xff; + da = ~d >> 24; + + if (sb <= da) + m = FbAdd(s,d,0,t); + else + m = FbGen (s, d, 0, (da << 8) / sb, 0xff, t, u, v); + + if (sg <= da) + n = FbAdd(s,d,8,t); + else + n = FbGen (s, d, 8, (da << 8) / sg, 0xff, t, u, v); + + if (sr <= da) + o = FbAdd(s,d,16,t); + else + o = FbGen (s, d, 16, (da << 8) / sr, 0xff, t, u, v); + + if (sa <= da) + p = FbAdd(s,d,24,t); + else + p = FbGen (s, d, 24, (da << 8) / sa, 0xff, t, u, v); + + dest[i] = m|n|o|p; + } +} + +static FASTCALL void +fbCombineDisjointGeneralC (CARD32 *dest, CARD32 *src, CARD32 *mask, int width, CARD8 combine) +{ + int i; + fbCombineMaskC(src, mask, width); + for (i = 0; i < width; ++i) { + CARD32 s, d; + CARD32 m,n,o,p; + CARD32 Fa, Fb; + CARD16 t, u, v; + CARD32 sa; + CARD8 da; + + s = src[i]; + sa = mask[i]; + d = dest[i]; + da = d >> 24; + + switch (combine & CombineA) { + default: + Fa = 0; + break; + case CombineAOut: + m = fbCombineDisjointOutPart ((CARD8) (sa >> 0), da); + n = fbCombineDisjointOutPart ((CARD8) (sa >> 8), da) << 8; + o = fbCombineDisjointOutPart ((CARD8) (sa >> 16), da) << 16; + p = fbCombineDisjointOutPart ((CARD8) (sa >> 24), da) << 24; + Fa = m|n|o|p; + break; + case CombineAIn: + m = fbCombineDisjointInPart ((CARD8) (sa >> 0), da); + n = fbCombineDisjointInPart ((CARD8) (sa >> 8), da) << 8; + o = fbCombineDisjointInPart ((CARD8) (sa >> 16), da) << 16; + p = fbCombineDisjointInPart ((CARD8) (sa >> 24), da) << 24; + Fa = m|n|o|p; + break; + case CombineA: + Fa = 0xffffffff; + break; + } + + switch (combine & CombineB) { + default: + Fb = 0; + break; + case CombineBOut: + m = fbCombineDisjointOutPart (da, (CARD8) (sa >> 0)); + n = fbCombineDisjointOutPart (da, (CARD8) (sa >> 8)) << 8; + o = fbCombineDisjointOutPart (da, (CARD8) (sa >> 16)) << 16; + p = fbCombineDisjointOutPart (da, (CARD8) (sa >> 24)) << 24; + Fb = m|n|o|p; + break; + case CombineBIn: + m = fbCombineDisjointInPart (da, (CARD8) (sa >> 0)); + n = fbCombineDisjointInPart (da, (CARD8) (sa >> 8)) << 8; + o = fbCombineDisjointInPart (da, (CARD8) (sa >> 16)) << 16; + p = fbCombineDisjointInPart (da, (CARD8) (sa >> 24)) << 24; + Fb = m|n|o|p; + break; + case CombineB: + Fb = 0xffffffff; + break; + } + m = FbGen (s,d,0,FbGet8(Fa,0),FbGet8(Fb,0),t, u, v); + n = FbGen (s,d,8,FbGet8(Fa,8),FbGet8(Fb,8),t, u, v); + o = FbGen (s,d,16,FbGet8(Fa,16),FbGet8(Fb,16),t, u, v); + p = FbGen (s,d,24,FbGet8(Fa,24),FbGet8(Fb,24),t, u, v); + s = m|n|o|p; + dest[i] = s; + } +} + +static FASTCALL void +fbCombineDisjointOverC (CARD32 *dest, CARD32 *src, CARD32 *mask, int width) +{ + fbCombineDisjointGeneralC (dest, src, mask, width, CombineAOver); +} + +static FASTCALL void +fbCombineDisjointInC (CARD32 *dest, CARD32 *src, CARD32 *mask, int width) +{ + fbCombineDisjointGeneralC (dest, src, mask, width, CombineAIn); +} + +static FASTCALL void +fbCombineDisjointInReverseC (CARD32 *dest, CARD32 *src, CARD32 *mask, int width) +{ + fbCombineDisjointGeneralC (dest, src, mask, width, CombineBIn); +} + +static FASTCALL void +fbCombineDisjointOutC (CARD32 *dest, CARD32 *src, CARD32 *mask, int width) +{ + fbCombineDisjointGeneralC (dest, src, mask, width, CombineAOut); +} + +static FASTCALL void +fbCombineDisjointOutReverseC (CARD32 *dest, CARD32 *src, CARD32 *mask, int width) +{ + fbCombineDisjointGeneralC (dest, src, mask, width, CombineBOut); +} + +static FASTCALL void +fbCombineDisjointAtopC (CARD32 *dest, CARD32 *src, CARD32 *mask, int width) +{ + fbCombineDisjointGeneralC (dest, src, mask, width, CombineAAtop); +} + +static FASTCALL void +fbCombineDisjointAtopReverseC (CARD32 *dest, CARD32 *src, CARD32 *mask, int width) +{ + fbCombineDisjointGeneralC (dest, src, mask, width, CombineBAtop); +} + +static FASTCALL void +fbCombineDisjointXorC (CARD32 *dest, CARD32 *src, CARD32 *mask, int width) +{ + fbCombineDisjointGeneralC (dest, src, mask, width, CombineXor); +} + +static FASTCALL void +fbCombineConjointGeneralC (CARD32 *dest, CARD32 *src, CARD32 *mask, int width, CARD8 combine) +{ + int i; + fbCombineMaskC(src, mask, width); + for (i = 0; i < width; ++i) { + CARD32 s, d; + CARD32 m,n,o,p; + CARD32 Fa, Fb; + CARD16 t, u, v; + CARD32 sa; + CARD8 da; + + s = src[i]; + sa = mask[i]; + d = dest[i]; + da = d >> 24; + + switch (combine & CombineA) { + default: + Fa = 0; + break; + case CombineAOut: + m = fbCombineConjointOutPart ((CARD8) (sa >> 0), da); + n = fbCombineConjointOutPart ((CARD8) (sa >> 8), da) << 8; + o = fbCombineConjointOutPart ((CARD8) (sa >> 16), da) << 16; + p = fbCombineConjointOutPart ((CARD8) (sa >> 24), da) << 24; + Fa = m|n|o|p; + break; + case CombineAIn: + m = fbCombineConjointInPart ((CARD8) (sa >> 0), da); + n = fbCombineConjointInPart ((CARD8) (sa >> 8), da) << 8; + o = fbCombineConjointInPart ((CARD8) (sa >> 16), da) << 16; + p = fbCombineConjointInPart ((CARD8) (sa >> 24), da) << 24; + Fa = m|n|o|p; + break; + case CombineA: + Fa = 0xffffffff; + break; + } + + switch (combine & CombineB) { + default: + Fb = 0; + break; + case CombineBOut: + m = fbCombineConjointOutPart (da, (CARD8) (sa >> 0)); + n = fbCombineConjointOutPart (da, (CARD8) (sa >> 8)) << 8; + o = fbCombineConjointOutPart (da, (CARD8) (sa >> 16)) << 16; + p = fbCombineConjointOutPart (da, (CARD8) (sa >> 24)) << 24; + Fb = m|n|o|p; + break; + case CombineBIn: + m = fbCombineConjointInPart (da, (CARD8) (sa >> 0)); + n = fbCombineConjointInPart (da, (CARD8) (sa >> 8)) << 8; + o = fbCombineConjointInPart (da, (CARD8) (sa >> 16)) << 16; + p = fbCombineConjointInPart (da, (CARD8) (sa >> 24)) << 24; + Fb = m|n|o|p; + break; + case CombineB: + Fb = 0xffffffff; + break; + } + m = FbGen (s,d,0,FbGet8(Fa,0),FbGet8(Fb,0),t, u, v); + n = FbGen (s,d,8,FbGet8(Fa,8),FbGet8(Fb,8),t, u, v); + o = FbGen (s,d,16,FbGet8(Fa,16),FbGet8(Fb,16),t, u, v); + p = FbGen (s,d,24,FbGet8(Fa,24),FbGet8(Fb,24),t, u, v); + s = m|n|o|p; + dest[i] = s; + } +} + +static FASTCALL void +fbCombineConjointOverC (CARD32 *dest, CARD32 *src, CARD32 *mask, int width) +{ + fbCombineConjointGeneralC (dest, src, mask, width, CombineAOver); +} + +static FASTCALL void +fbCombineConjointOverReverseC (CARD32 *dest, CARD32 *src, CARD32 *mask, int width) +{ + fbCombineConjointGeneralC (dest, src, mask, width, CombineBOver); +} + +static FASTCALL void +fbCombineConjointInC (CARD32 *dest, CARD32 *src, CARD32 *mask, int width) +{ + fbCombineConjointGeneralC (dest, src, mask, width, CombineAIn); +} + +static FASTCALL void +fbCombineConjointInReverseC (CARD32 *dest, CARD32 *src, CARD32 *mask, int width) +{ + fbCombineConjointGeneralC (dest, src, mask, width, CombineBIn); +} + +static FASTCALL void +fbCombineConjointOutC (CARD32 *dest, CARD32 *src, CARD32 *mask, int width) +{ + fbCombineConjointGeneralC (dest, src, mask, width, CombineAOut); +} + +static FASTCALL void +fbCombineConjointOutReverseC (CARD32 *dest, CARD32 *src, CARD32 *mask, int width) +{ + fbCombineConjointGeneralC (dest, src, mask, width, CombineBOut); +} + +static FASTCALL void +fbCombineConjointAtopC (CARD32 *dest, CARD32 *src, CARD32 *mask, int width) +{ + fbCombineConjointGeneralC (dest, src, mask, width, CombineAAtop); +} + +static FASTCALL void +fbCombineConjointAtopReverseC (CARD32 *dest, CARD32 *src, CARD32 *mask, int width) +{ + fbCombineConjointGeneralC (dest, src, mask, width, CombineBAtop); +} + +static FASTCALL void +fbCombineConjointXorC (CARD32 *dest, CARD32 *src, CARD32 *mask, int width) +{ + fbCombineConjointGeneralC (dest, src, mask, width, CombineXor); +} + +static CombineFuncC fbCombineFuncC[] = { + fbCombineClearC, + fbCombineSrcC, + NULL, /* Dest */ + fbCombineOverC, + fbCombineOverReverseC, + fbCombineInC, + fbCombineInReverseC, + fbCombineOutC, + fbCombineOutReverseC, + fbCombineAtopC, + fbCombineAtopReverseC, + fbCombineXorC, + fbCombineAddC, + fbCombineSaturateC, + NULL, + NULL, + fbCombineClearC, /* 0x10 */ + fbCombineSrcC, + NULL, /* Dest */ + fbCombineDisjointOverC, + fbCombineSaturateC, /* DisjointOverReverse */ + fbCombineDisjointInC, + fbCombineDisjointInReverseC, + fbCombineDisjointOutC, + fbCombineDisjointOutReverseC, + fbCombineDisjointAtopC, + fbCombineDisjointAtopReverseC, + fbCombineDisjointXorC, /* 0x1b */ + NULL, + NULL, + NULL, + NULL, + fbCombineClearC, + fbCombineSrcC, + NULL, /* Dest */ + fbCombineConjointOverC, + fbCombineConjointOverReverseC, + fbCombineConjointInC, + fbCombineConjointInReverseC, + fbCombineConjointOutC, + fbCombineConjointOutReverseC, + fbCombineConjointAtopC, + fbCombineConjointAtopReverseC, + fbCombineConjointXorC, +}; + + +FbComposeFunctions composeFunctions = { + fbCombineFuncU, + fbCombineFuncC, + fbCombineMaskU +}; + + +static void fbFetchSolid(PicturePtr pict, int x, int y, int width, CARD32 *buffer) +{ + FbBits *bits; + FbStride stride; + int bpp; + int xoff, yoff; + CARD32 color; + CARD32 *end; + fetchPixelProc fetch = fetchPixelProcForPicture(pict); + miIndexedPtr indexed = (miIndexedPtr) pict->pFormat->index.devPrivate; + + fbGetDrawable (pict->pDrawable, bits, stride, bpp, xoff, yoff); + bits += yoff*stride + (xoff*bpp >> FB_SHIFT); + + color = fetch(bits, 0, indexed); + + end = buffer + width; + while (buffer < end) + *buffer++ = color; +} + +static void fbFetch(PicturePtr pict, int x, int y, int width, CARD32 *buffer) +{ + FbBits *bits; + FbStride stride; + int bpp; + int xoff, yoff; + fetchProc fetch = fetchProcForPicture(pict); + miIndexedPtr indexed = (miIndexedPtr) pict->pFormat->index.devPrivate; + + fbGetDrawable (pict->pDrawable, bits, stride, bpp, xoff, yoff); + x += xoff; + y += yoff; + + bits += y*stride; + + fetch(bits, x, width, buffer, indexed); +} + +#define MOD(a,b) ((a) < 0 ? ((b) - ((-(a) - 1) % (b))) - 1 : (a) % (b)) +#define DIV(a,b) ((((a) < 0) == ((b) < 0)) ? (a) / (b) :\ + ((a) - (b) + 1 - (((b) < 0) << 1)) / (b)) + + +static CARD32 gradientPixel(const SourcePictPtr pGradient, xFixed_48_16 pos, unsigned int spread) +{ + int ipos = (pos * PICT_GRADIENT_STOPTABLE_SIZE - 1) >> 16; + + /* calculate the actual offset. */ + if (ipos < 0 || ipos >= PICT_GRADIENT_STOPTABLE_SIZE) { + if (pGradient->type == SourcePictTypeConical || spread == RepeatNormal) { + ipos = ipos % PICT_GRADIENT_STOPTABLE_SIZE; + ipos = ipos < 0 ? PICT_GRADIENT_STOPTABLE_SIZE + ipos : ipos; + + } else if (spread == RepeatReflect) { + const int limit = PICT_GRADIENT_STOPTABLE_SIZE * 2 - 1; + ipos = ipos % limit; + ipos = ipos < 0 ? limit + ipos : ipos; + ipos = ipos >= PICT_GRADIENT_STOPTABLE_SIZE ? limit - ipos : ipos; + + } else if (spread == RepeatPad) { + if (ipos < 0) + ipos = 0; + else if (ipos >= PICT_GRADIENT_STOPTABLE_SIZE) + ipos = PICT_GRADIENT_STOPTABLE_SIZE-1; + } else { /* RepeatNone */ + return 0; + } + } + + assert(ipos >= 0); + assert(ipos < PICT_GRADIENT_STOPTABLE_SIZE); + + return pGradient->linear.colorTable[ipos]; +} + +static void fbFetchSourcePict(PicturePtr pict, int x, int y, int width, CARD32 *buffer) +{ + SourcePictPtr pGradient = pict->pSourcePict; + CARD32 *end = buffer + width; + + if (pGradient->type == SourcePictTypeSolidFill) { + register CARD32 color = pGradient->solidFill.color; + while (buffer < end) { + *buffer++ = color; + } + } else if (pGradient->type == SourcePictTypeLinear) { + PictVector v, unit; + xFixed_32_32 l; + xFixed_48_16 dx, dy, a, b, off; + + v.vector[0] = IntToxFixed(x); + v.vector[1] = IntToxFixed(y); + v.vector[2] = xFixed1; + if (pict->transform) { + if (!PictureTransformPoint3d (pict->transform, &v)) + return; + unit.vector[0] = pict->transform->matrix[0][0]; + unit.vector[1] = pict->transform->matrix[1][0]; + unit.vector[2] = pict->transform->matrix[2][0]; + } else { + unit.vector[0] = xFixed1; + unit.vector[1] = 0; + unit.vector[2] = 0; + } + + dx = pGradient->linear.p2.x - pGradient->linear.p1.x; + dy = pGradient->linear.p2.y - pGradient->linear.p1.y; + l = dx*dx + dy*dy; + if (l != 0) { + a = (dx << 32) / l; + b = (dy << 32) / l; + off = (-a*pGradient->linear.p1.x - b*pGradient->linear.p1.y)>>16; + } + if (l == 0 || (unit.vector[2] == 0 && v.vector[2] == xFixed1)) { + xFixed_48_16 inc, t; + /* affine transformation only */ + if (l == 0) { + t = 0; + inc = 0; + } else { + t = ((a*v.vector[0] + b*v.vector[1]) >> 16) + off; + inc = (a * unit.vector[0] + b * unit.vector[1]) >> 16; + } + while (buffer < end) { + *buffer++ = gradientPixel(pGradient, t, pict->repeatType); + t += inc; + } + } else { + /* projective transformation */ + while (buffer < end) { + xFixed_48_16 t; + if (v.vector[2] == 0) { + t = 0; + } else { + xFixed_48_16 x, y; + x = ((xFixed_48_16)v.vector[0] << 16) / v.vector[2]; + y = ((xFixed_48_16)v.vector[1] << 16) / v.vector[2]; + t = ((a*x + b*y) >> 16) + off; + } + *buffer++ = gradientPixel(pGradient, t, pict->repeatType); + v.vector[0] += unit.vector[0]; + v.vector[1] += unit.vector[1]; + v.vector[2] += unit.vector[2]; + } + } + } else { + /* radial or conical */ + Bool affine = TRUE; + double cx = 1.; + double cy = 0.; + double cz = 0.; + double rx = x; + double ry = y; + double rz = 1.; + + if (pict->transform) { + PictVector v; + v.vector[0] = IntToxFixed(x); + v.vector[1] = IntToxFixed(y); + v.vector[2] = xFixed1; + if (!PictureTransformPoint3d (pict->transform, &v)) + return; + + cx = pict->transform->matrix[0][0]/65536.; + cy = pict->transform->matrix[1][0]/65536.; + cz = pict->transform->matrix[2][0]/65536.; + rx = v.vector[0]/65536.; + ry = v.vector[1]/65536.; + rz = v.vector[2]/65536.; + affine = pict->transform->matrix[2][0] == 0 && v.vector[2] == xFixed1; + } + + if (pGradient->type == SourcePictTypeRadial) { + if (affine) { + rx -= pGradient->radial.fx; + ry -= pGradient->radial.fy; + + while (buffer < end) { + double b = 2*(rx*pGradient->radial.dx + ry*pGradient->radial.dy); + double c = -(rx*rx + ry*ry); + double det = (b * b) - (4 * pGradient->radial.a * c); + double s = (-b + sqrt(det))/(2. * pGradient->radial.a); + *buffer = gradientPixel(pGradient, + (xFixed_48_16)((s*pGradient->radial.m + pGradient->radial.b)*65536), + pict->repeatType); + ++buffer; + rx += cx; + ry += cy; + } + } else { + while (buffer < end) { + double x, y; + double b, c, det, s; + if (rz != 0) { + x = rx/rz; + y = ry/rz; + } else { + x = y = 0.; + } + x -= pGradient->radial.fx; + y -= pGradient->radial.fy; + b = 2*(x*pGradient->radial.dx + y*pGradient->radial.dy); + c = -(x*x + y*y); + det = (b * b) - (4 * pGradient->radial.a * c); + s = (-b + sqrt(det))/(2. * pGradient->radial.a); + *buffer = gradientPixel(pGradient, + (xFixed_48_16)((s*pGradient->radial.m + pGradient->radial.b)*65536), + pict->repeatType); + ++buffer; + rx += cx; + ry += cy; + rz += cz; + } + } + } else /* SourcePictTypeConical */ { + double a = pGradient->conical.angle/(180.*65536); + if (affine) { + rx -= pGradient->conical.center.x/65536.; + ry -= pGradient->conical.center.y/65536.; + + while (buffer < end) { + double angle = atan2(ry, rx) + a; + *buffer = gradientPixel(pGradient, (xFixed_48_16) (angle * (65536. / (2*M_PI))), + pict->repeatType); + ++buffer; + rx += cx; + ry += cy; + } + } else { + + while (buffer < end) { + double x, y, angle; + if (rz != 0) { + x = rx/rz; + y = ry/rz; + } else { + x = y = 0.; + } + x -= pGradient->conical.center.x/65536.; + y -= pGradient->conical.center.y/65536.; + angle = atan2(y, x) + a; + *buffer = gradientPixel(pGradient, (xFixed_48_16) (angle * (65536. / (2*M_PI))), + pict->repeatType); + ++buffer; + rx += cx; + ry += cy; + rz += cz; + } + } + } + } +} + + + +static void fbFetchTransformed(PicturePtr pict, int x, int y, int width, CARD32 *buffer) +{ + FbBits *bits; + FbStride stride; + int bpp; + int xoff, yoff; + fetchPixelProc fetch; + PictVector v; + PictVector unit; + int i; + BoxRec box; + miIndexedPtr indexed = (miIndexedPtr) pict->pFormat->index.devPrivate; + Bool affine = TRUE; + + fetch = fetchPixelProcForPicture(pict); + + fbGetDrawable(pict->pDrawable, bits, stride, bpp, xoff, yoff); + x += xoff; + y += yoff; + + v.vector[0] = IntToxFixed(x); + v.vector[1] = IntToxFixed(y); + v.vector[2] = xFixed1; + + /* when using convolution filters one might get here without a transform */ + if (pict->transform) { + if (!PictureTransformPoint3d (pict->transform, &v)) + return; + unit.vector[0] = pict->transform->matrix[0][0]; + unit.vector[1] = pict->transform->matrix[1][0]; + unit.vector[2] = pict->transform->matrix[2][0]; + affine = v.vector[2] == xFixed1 && unit.vector[2] == 0; + } else { + unit.vector[0] = xFixed1; + unit.vector[1] = 0; + unit.vector[2] = 0; + } + + if (pict->filter == PictFilterNearest) + { + if (pict->repeatType == RepeatNormal) { + if (RegionNumRects(pict->pCompositeClip) == 1) { + box = pict->pCompositeClip->extents; + for (i = 0; i < width; ++i) { + if (!v.vector[2]) { + buffer[i] = 0; + } else { + if (!affine) { + y = MOD(DIV(v.vector[1],v.vector[2]), pict->pDrawable->height); + x = MOD(DIV(v.vector[0],v.vector[2]), pict->pDrawable->width); + } else { + y = MOD(v.vector[1]>>16, pict->pDrawable->height); + x = MOD(v.vector[0]>>16, pict->pDrawable->width); + } + buffer[i] = fetch(bits + (y + pict->pDrawable->y)*stride, x + pict->pDrawable->x, indexed); + } + v.vector[0] += unit.vector[0]; + v.vector[1] += unit.vector[1]; + v.vector[2] += unit.vector[2]; + } + } else { + for (i = 0; i < width; ++i) { + if (!v.vector[2]) { + buffer[i] = 0; + } else { + if (!affine) { + y = MOD(DIV(v.vector[1],v.vector[2]), pict->pDrawable->height); + x = MOD(DIV(v.vector[0],v.vector[2]), pict->pDrawable->width); + } else { + y = MOD(v.vector[1]>>16, pict->pDrawable->height); + x = MOD(v.vector[0]>>16, pict->pDrawable->width); + } + if (RegionContainsPoint(pict->pCompositeClip, x, y, &box)) + buffer[i] = fetch(bits + (y + pict->pDrawable->y)*stride, x + pict->pDrawable->x, indexed); + else + buffer[i] = 0; + } + v.vector[0] += unit.vector[0]; + v.vector[1] += unit.vector[1]; + v.vector[2] += unit.vector[2]; + } + } + } else { + if (RegionNumRects(pict->pCompositeClip) == 1) { + box = pict->pCompositeClip->extents; + for (i = 0; i < width; ++i) { + if (!v.vector[2]) { + buffer[i] = 0; + } else { + if (!affine) { + y = DIV(v.vector[1],v.vector[2]); + x = DIV(v.vector[0],v.vector[2]); + } else { + y = v.vector[1]>>16; + x = v.vector[0]>>16; + } + buffer[i] = ((x < box.x1) | (x >= box.x2) | (y < box.y1) | (y >= box.y2)) ? + 0 : fetch(bits + (y + pict->pDrawable->y)*stride, x + pict->pDrawable->x, indexed); + } + v.vector[0] += unit.vector[0]; + v.vector[1] += unit.vector[1]; + v.vector[2] += unit.vector[2]; + } + } else { + for (i = 0; i < width; ++i) { + if (!v.vector[2]) { + buffer[i] = 0; + } else { + if (!affine) { + y = DIV(v.vector[1],v.vector[2]); + x = DIV(v.vector[0],v.vector[2]); + } else { + y = v.vector[1]>>16; + x = v.vector[0]>>16; + } + if (RegionContainsPoint(pict->pCompositeClip, x, y, &box)) + buffer[i] = fetch(bits + (y + pict->pDrawable->y)*stride, x + pict->pDrawable->x, indexed); + else + buffer[i] = 0; + } + v.vector[0] += unit.vector[0]; + v.vector[1] += unit.vector[1]; + v.vector[2] += unit.vector[2]; + } + } + } + } else if (pict->filter == PictFilterBilinear) { + if (pict->repeatType == RepeatNormal) { + if (RegionNumRects(pict->pCompositeClip) == 1) { + box = pict->pCompositeClip->extents; + for (i = 0; i < width; ++i) { + if (!v.vector[2]) { + buffer[i] = 0; + } else { + int x1, x2, y1, y2, distx, idistx, disty, idisty; + FbBits *b; + CARD32 tl, tr, bl, br, r; + CARD32 ft, fb; + + if (!affine) { + xFixed_48_16 div; + div = ((xFixed_48_16)v.vector[0] << 16)/v.vector[2]; + x1 = div >> 16; + distx = ((xFixed)div >> 8) & 0xff; + div = ((xFixed_48_16)v.vector[1] << 16)/v.vector[2]; + y1 = div >> 16; + disty = ((xFixed)div >> 8) & 0xff; + } else { + x1 = v.vector[0] >> 16; + distx = (v.vector[0] >> 8) & 0xff; + y1 = v.vector[1] >> 16; + disty = (v.vector[1] >> 8) & 0xff; + } + x2 = x1 + 1; + y2 = y1 + 1; + + idistx = 256 - distx; + idisty = 256 - disty; + + x1 = MOD (x1, pict->pDrawable->width); + x2 = MOD (x2, pict->pDrawable->width); + y1 = MOD (y1, pict->pDrawable->height); + y2 = MOD (y2, pict->pDrawable->height); + + b = bits + (y1 + pict->pDrawable->y)*stride; + + tl = fetch(b, x1 + pict->pDrawable->x, indexed); + tr = fetch(b, x2 + pict->pDrawable->x, indexed); + b = bits + (y2 + pict->pDrawable->y)*stride; + bl = fetch(b, x1 + pict->pDrawable->x, indexed); + br = fetch(b, x2 + pict->pDrawable->x, indexed); + + ft = FbGet8(tl,0) * idistx + FbGet8(tr,0) * distx; + fb = FbGet8(bl,0) * idistx + FbGet8(br,0) * distx; + r = (((ft * idisty + fb * disty) >> 16) & 0xff); + ft = FbGet8(tl,8) * idistx + FbGet8(tr,8) * distx; + fb = FbGet8(bl,8) * idistx + FbGet8(br,8) * distx; + r |= (((ft * idisty + fb * disty) >> 8) & 0xff00); + ft = FbGet8(tl,16) * idistx + FbGet8(tr,16) * distx; + fb = FbGet8(bl,16) * idistx + FbGet8(br,16) * distx; + r |= (((ft * idisty + fb * disty)) & 0xff0000); + ft = FbGet8(tl,24) * idistx + FbGet8(tr,24) * distx; + fb = FbGet8(bl,24) * idistx + FbGet8(br,24) * distx; + r |= (((ft * idisty + fb * disty) << 8) & 0xff000000); + buffer[i] = r; + } + v.vector[0] += unit.vector[0]; + v.vector[1] += unit.vector[1]; + v.vector[2] += unit.vector[2]; + } + } else { + for (i = 0; i < width; ++i) { + if (!v.vector[2]) { + buffer[i] = 0; + } else { + int x1, x2, y1, y2, distx, idistx, disty, idisty; + FbBits *b; + CARD32 tl, tr, bl, br, r; + CARD32 ft, fb; + + if (!affine) { + xFixed_48_16 div; + div = ((xFixed_48_16)v.vector[0] << 16)/v.vector[2]; + x1 = div >> 16; + distx = ((xFixed)div >> 8) & 0xff; + div = ((xFixed_48_16)v.vector[1] << 16)/v.vector[2]; + y1 = div >> 16; + disty = ((xFixed)div >> 8) & 0xff; + } else { + x1 = v.vector[0] >> 16; + distx = (v.vector[0] >> 8) & 0xff; + y1 = v.vector[1] >> 16; + disty = (v.vector[1] >> 8) & 0xff; + } + x2 = x1 + 1; + y2 = y1 + 1; + + idistx = 256 - distx; + idisty = 256 - disty; + + x1 = MOD (x1, pict->pDrawable->width); + x2 = MOD (x2, pict->pDrawable->width); + y1 = MOD (y1, pict->pDrawable->height); + y2 = MOD (y2, pict->pDrawable->height); + + b = bits + (y1 + pict->pDrawable->y)*stride; + + tl = RegionContainsPoint(pict->pCompositeClip, x1, y1, &box) + ? fetch(b, x1 + pict->pDrawable->x, indexed) : 0; + tr = RegionContainsPoint(pict->pCompositeClip, x2, y1, &box) + ? fetch(b, x2 + pict->pDrawable->x, indexed) : 0; + b = bits + (y2 + pict->pDrawable->y)*stride; + bl = RegionContainsPoint(pict->pCompositeClip, x1, y2, &box) + ? fetch(b, x1 + pict->pDrawable->x, indexed) : 0; + br = RegionContainsPoint(pict->pCompositeClip, x2, y2, &box) + ? fetch(b, x2 + pict->pDrawable->x, indexed) : 0; + + ft = FbGet8(tl,0) * idistx + FbGet8(tr,0) * distx; + fb = FbGet8(bl,0) * idistx + FbGet8(br,0) * distx; + r = (((ft * idisty + fb * disty) >> 16) & 0xff); + ft = FbGet8(tl,8) * idistx + FbGet8(tr,8) * distx; + fb = FbGet8(bl,8) * idistx + FbGet8(br,8) * distx; + r |= (((ft * idisty + fb * disty) >> 8) & 0xff00); + ft = FbGet8(tl,16) * idistx + FbGet8(tr,16) * distx; + fb = FbGet8(bl,16) * idistx + FbGet8(br,16) * distx; + r |= (((ft * idisty + fb * disty)) & 0xff0000); + ft = FbGet8(tl,24) * idistx + FbGet8(tr,24) * distx; + fb = FbGet8(bl,24) * idistx + FbGet8(br,24) * distx; + r |= (((ft * idisty + fb * disty) << 8) & 0xff000000); + buffer[i] = r; + } + v.vector[0] += unit.vector[0]; + v.vector[1] += unit.vector[1]; + v.vector[2] += unit.vector[2]; + } + } + } else { + if (RegionNumRects(pict->pCompositeClip) == 1) { + box = pict->pCompositeClip->extents; + for (i = 0; i < width; ++i) { + if (!v.vector[2]) { + buffer[i] = 0; + } else { + int x1, x2, y1, y2, distx, idistx, disty, idisty, x_off; + FbBits *b; + CARD32 tl, tr, bl, br, r; + Bool x1_out, x2_out, y1_out, y2_out; + CARD32 ft, fb; + + if (!affine) { + xFixed_48_16 div; + div = ((xFixed_48_16)v.vector[0] << 16)/v.vector[2]; + x1 = div >> 16; + distx = ((xFixed)div >> 8) & 0xff; + div = ((xFixed_48_16)v.vector[1] << 16)/v.vector[2]; + y1 = div >> 16; + disty = ((xFixed)div >> 8) & 0xff; + } else { + x1 = v.vector[0] >> 16; + distx = (v.vector[0] >> 8) & 0xff; + y1 = v.vector[1] >> 16; + disty = (v.vector[1] >> 8) & 0xff; + } + x2 = x1 + 1; + y2 = y1 + 1; + + idistx = 256 - distx; + idisty = 256 - disty; + + b = bits + (y1 + pict->pDrawable->y)*stride; + x_off = x1 + pict->pDrawable->x; + + x1_out = (x1 < box.x1) | (x1 >= box.x2); + x2_out = (x2 < box.x1) | (x2 >= box.x2); + y1_out = (y1 < box.y1) | (y1 >= box.y2); + y2_out = (y2 < box.y1) | (y2 >= box.y2); + + tl = x1_out|y1_out ? 0 : fetch(b, x_off, indexed); + tr = x2_out|y1_out ? 0 : fetch(b, x_off + 1, indexed); + b += stride; + bl = x1_out|y2_out ? 0 : fetch(b, x_off, indexed); + br = x2_out|y2_out ? 0 : fetch(b, x_off + 1, indexed); + + ft = FbGet8(tl,0) * idistx + FbGet8(tr,0) * distx; + fb = FbGet8(bl,0) * idistx + FbGet8(br,0) * distx; + r = (((ft * idisty + fb * disty) >> 16) & 0xff); + ft = FbGet8(tl,8) * idistx + FbGet8(tr,8) * distx; + fb = FbGet8(bl,8) * idistx + FbGet8(br,8) * distx; + r |= (((ft * idisty + fb * disty) >> 8) & 0xff00); + ft = FbGet8(tl,16) * idistx + FbGet8(tr,16) * distx; + fb = FbGet8(bl,16) * idistx + FbGet8(br,16) * distx; + r |= (((ft * idisty + fb * disty)) & 0xff0000); + ft = FbGet8(tl,24) * idistx + FbGet8(tr,24) * distx; + fb = FbGet8(bl,24) * idistx + FbGet8(br,24) * distx; + r |= (((ft * idisty + fb * disty) << 8) & 0xff000000); + buffer[i] = r; + } + v.vector[0] += unit.vector[0]; + v.vector[1] += unit.vector[1]; + v.vector[2] += unit.vector[2]; + } + } else { + for (i = 0; i < width; ++i) { + if (!v.vector[2]) { + buffer[i] = 0; + } else { + int x1, x2, y1, y2, distx, idistx, disty, idisty, x_off; + FbBits *b; + CARD32 tl, tr, bl, br, r; + CARD32 ft, fb; + + if (!affine) { + xFixed_48_16 div; + div = ((xFixed_48_16)v.vector[0] << 16)/v.vector[2]; + x1 = div >> 16; + distx = ((xFixed)div >> 8) & 0xff; + div = ((xFixed_48_16)v.vector[1] << 16)/v.vector[2]; + y1 = div >> 16; + disty = ((xFixed)div >> 8) & 0xff; + } else { + x1 = v.vector[0] >> 16; + distx = (v.vector[0] >> 8) & 0xff; + y1 = v.vector[1] >> 16; + disty = (v.vector[1] >> 8) & 0xff; + } + x2 = x1 + 1; + y2 = y1 + 1; + + idistx = 256 - distx; + idisty = 256 - disty; + + b = bits + (y1 + pict->pDrawable->y)*stride; + x_off = x1 + pict->pDrawable->x; + + tl = RegionContainsPoint(pict->pCompositeClip, x1, y1, &box) + ? fetch(b, x_off, indexed) : 0; + tr = RegionContainsPoint(pict->pCompositeClip, x2, y1, &box) + ? fetch(b, x_off + 1, indexed) : 0; + b += stride; + bl = RegionContainsPoint(pict->pCompositeClip, x1, y2, &box) + ? fetch(b, x_off, indexed) : 0; + br = RegionContainsPoint(pict->pCompositeClip, x2, y2, &box) + ? fetch(b, x_off + 1, indexed) : 0; + + ft = FbGet8(tl,0) * idistx + FbGet8(tr,0) * distx; + fb = FbGet8(bl,0) * idistx + FbGet8(br,0) * distx; + r = (((ft * idisty + fb * disty) >> 16) & 0xff); + ft = FbGet8(tl,8) * idistx + FbGet8(tr,8) * distx; + fb = FbGet8(bl,8) * idistx + FbGet8(br,8) * distx; + r |= (((ft * idisty + fb * disty) >> 8) & 0xff00); + ft = FbGet8(tl,16) * idistx + FbGet8(tr,16) * distx; + fb = FbGet8(bl,16) * idistx + FbGet8(br,16) * distx; + r |= (((ft * idisty + fb * disty)) & 0xff0000); + ft = FbGet8(tl,24) * idistx + FbGet8(tr,24) * distx; + fb = FbGet8(bl,24) * idistx + FbGet8(br,24) * distx; + r |= (((ft * idisty + fb * disty) << 8) & 0xff000000); + buffer[i] = r; + } + v.vector[0] += unit.vector[0]; + v.vector[1] += unit.vector[1]; + v.vector[2] += unit.vector[2]; + } + } + } + } else if (pict->filter == PictFilterConvolution) { + xFixed *params = pict->filter_params; + INT32 cwidth = xFixedToInt(params[0]); + INT32 cheight = xFixedToInt(params[1]); + int xoff = params[0] >> 1; + int yoff = params[1] >> 1; + params += 2; + for (i = 0; i < width; ++i) { + if (!v.vector[2]) { + buffer[i] = 0; + } else { + int x1, x2, y1, y2, x, y; + INT32 srtot, sgtot, sbtot, satot; + xFixed *p = params; + + if (!affine) { + xFixed_48_16 tmp; + tmp = ((xFixed_48_16)v.vector[0] << 16)/v.vector[2] - xoff; + x1 = xFixedToInt(tmp); + tmp = ((xFixed_48_16)v.vector[1] << 16)/v.vector[2] - yoff; + y1 = xFixedToInt(tmp); + } else { + x1 = xFixedToInt(v.vector[0] - xoff); + y1 = xFixedToInt(v.vector[1] - yoff); + } + x2 = x1 + cwidth; + y2 = y1 + cheight; + + srtot = sgtot = sbtot = satot = 0; + + for (y = y1; y < y2; y++) { + int ty = (pict->repeatType == RepeatNormal) ? MOD (y, pict->pDrawable->height) : y; + for (x = x1; x < x2; x++) { + if (*p) { + int tx = (pict->repeatType == RepeatNormal) ? MOD (x, pict->pDrawable->width) : x; + if (RegionContainsPoint(pict->pCompositeClip, tx, ty, &box)) { + FbBits *b = bits + (ty + pict->pDrawable->y)*stride; + CARD32 c = fetch(b, tx + pict->pDrawable->x, indexed); + + srtot += Red(c) * *p; + sgtot += Green(c) * *p; + sbtot += Blue(c) * *p; + satot += Alpha(c) * *p; + } + } + p++; + } + } + + if (satot < 0) satot = 0; else if (satot > 0xff) satot = 0xff; + if (srtot < 0) srtot = 0; else if (srtot > 0xff) srtot = 0xff; + if (sgtot < 0) sgtot = 0; else if (sgtot > 0xff) sgtot = 0xff; + if (sbtot < 0) sbtot = 0; else if (sbtot > 0xff) sbtot = 0xff; + + buffer[i] = ((satot << 24) | + (srtot << 16) | + (sgtot << 8) | + (sbtot )); + } + v.vector[0] += unit.vector[0]; + v.vector[1] += unit.vector[1]; + v.vector[2] += unit.vector[2]; + } + } +} + + +static void fbFetchExternalAlpha(PicturePtr pict, int x, int y, int width, CARD32 *buffer) +{ + int i; + CARD32 _alpha_buffer[SCANLINE_BUFFER_LENGTH]; + CARD32 *alpha_buffer = _alpha_buffer; + + if (!pict->alphaMap) { + fbFetchTransformed(pict, x, y, width, buffer); + return; + } + if (width > SCANLINE_BUFFER_LENGTH) + alpha_buffer = (CARD32 *) malloc(width*sizeof(CARD32)); + + fbFetchTransformed(pict, x, y, width, buffer); + fbFetchTransformed(pict->alphaMap, x - pict->alphaOrigin.x, y - pict->alphaOrigin.y, width, alpha_buffer); + for (i = 0; i < width; ++i) { + int a = alpha_buffer[i]>>24; + buffer[i] = (a << 24) + | (div_255(Red(buffer[i]) * a) << 16) + | (div_255(Green(buffer[i]) * a) << 8) + | (div_255(Blue(buffer[i]) * a)); + } + + if (alpha_buffer != _alpha_buffer) + free(alpha_buffer); +} + +static void fbStore(PicturePtr pict, int x, int y, int width, CARD32 *buffer) +{ + FbBits *bits; + FbStride stride; + int bpp; + int xoff, yoff; + storeProc store = storeProcForPicture(pict); + miIndexedPtr indexed = (miIndexedPtr) pict->pFormat->index.devPrivate; + + fbGetDrawable (pict->pDrawable, bits, stride, bpp, xoff, yoff); + x += xoff; + y += yoff; + + bits += y*stride; + store(bits, buffer, x, width, indexed); +} + +static void fbStoreExternalAlpha(PicturePtr pict, int x, int y, int width, CARD32 *buffer) +{ + FbBits *bits, *alpha_bits; + FbStride stride, astride; + int bpp, abpp; + int xoff, yoff; + int ax, ay; + storeProc store; + storeProc astore; + miIndexedPtr indexed = (miIndexedPtr) pict->pFormat->index.devPrivate; + miIndexedPtr aindexed; + + if (!pict->alphaMap) { + fbStore(pict, x, y, width, buffer); + return; + } + + store = storeProcForPicture(pict); + astore = storeProcForPicture(pict->alphaMap); + aindexed = (miIndexedPtr) pict->alphaMap->pFormat->index.devPrivate; + + ax = x; + ay = y; + + fbGetDrawable (pict->pDrawable, bits, stride, bpp, xoff, yoff); + x += xoff; + y += yoff; + fbGetDrawable (pict->alphaMap->pDrawable, alpha_bits, astride, abpp, xoff, yoff); + ax += xoff; + ay += yoff; + + bits += y*stride; + alpha_bits += (ay - pict->alphaOrigin.y)*astride; + + + store(bits, buffer, x, width, indexed); + astore(alpha_bits, buffer, ax - pict->alphaOrigin.x, width, aindexed); +} + +typedef void (*scanStoreProc)(PicturePtr , int , int , int , CARD32 *); +typedef void (*scanFetchProc)(PicturePtr , int , int , int , CARD32 *); + +static void +fbCompositeRect (const FbComposeData *data, CARD32 *scanline_buffer) +{ + CARD32 *src_buffer = scanline_buffer; + CARD32 *dest_buffer = src_buffer + data->width; + int i; + scanStoreProc store; + scanFetchProc fetchSrc = NULL, fetchMask = NULL, fetchDest = NULL; + + if (data->op == PictOpClear) + fetchSrc = NULL; + else if (!data->src->pDrawable) { + if (data->src->pSourcePict) + fetchSrc = fbFetchSourcePict; + } else if (data->src->alphaMap) + fetchSrc = fbFetchExternalAlpha; + else if (data->src->repeatType == RepeatNormal && + data->src->pDrawable->width == 1 && data->src->pDrawable->height == 1) + fetchSrc = fbFetchSolid; + else if (!data->src->transform && data->src->filter != PictFilterConvolution) + fetchSrc = fbFetch; + else + fetchSrc = fbFetchTransformed; + + if (data->mask && data->op != PictOpClear) { + if (!data->mask->pDrawable) { + if (data->mask->pSourcePict) + fetchMask = fbFetchSourcePict; + } else if (data->mask->alphaMap) + fetchMask = fbFetchExternalAlpha; + else if (data->mask->repeatType == RepeatNormal + && data->mask->pDrawable->width == 1 && data->mask->pDrawable->height == 1) + fetchMask = fbFetchSolid; + else if (!data->mask->transform && data->mask->filter != PictFilterConvolution) + fetchMask = fbFetch; + else + fetchMask = fbFetchTransformed; + } else { + fetchMask = NULL; + } + + if (data->dest->alphaMap) { + fetchDest = fbFetchExternalAlpha; + store = fbStoreExternalAlpha; + } else { + fetchDest = fbFetch; + store = fbStore; + } + if (data->op == PictOpClear || data->op == PictOpSrc) + fetchDest = NULL; + + if (fetchSrc && fetchMask && data->mask && data->mask->componentAlpha && PICT_FORMAT_RGB(data->mask->format)) { + CARD32 *mask_buffer = dest_buffer + data->width; + CombineFuncC compose = composeFunctions.combineC[data->op]; + if (!compose) + return; + + for (i = 0; i < data->height; ++i) + { + /* fill first half of scanline with source */ + fetchSrc(data->src, data->xSrc, data->ySrc + i, data->width, src_buffer); + fetchMask(data->mask, data->xMask, data->yMask + i, data->width, mask_buffer); + + /* fill dest into second half of scanline */ + if (fetchDest) + fetchDest(data->dest, data->xDest, data->yDest + i, data->width, dest_buffer); + + /* blend */ + compose(dest_buffer, src_buffer, mask_buffer, data->width); + + /* write back */ + store(data->dest, data->xDest, data->yDest + i, data->width, dest_buffer); + } + } else { + + CombineFuncU compose = composeFunctions.combineU[data->op]; + if (!compose) + return; + + if (fetchSrc == fbFetchSolid && (!fetchMask || fetchMask == fbFetchSolid)) { + fetchSrc(data->src, data->xSrc, data->ySrc, data->width, src_buffer); + if (fetchMask) { + fetchMask(data->mask, data->xMask, data->yMask, data->width, dest_buffer); + composeFunctions.combineMaskU(src_buffer, dest_buffer, data->width); + } + fetchSrc = NULL; + fetchMask = NULL; + } + + for (i = 0; i < data->height; ++i) + { + /* fill first half of scanline with source */ + if (fetchSrc) { + fetchSrc(data->src, data->xSrc, data->ySrc + i, data->width, src_buffer); + + /* add in mask */ + if (fetchMask) { + fetchMask(data->mask, data->xMask, data->yMask + i, data->width, dest_buffer); + composeFunctions.combineMaskU(src_buffer, dest_buffer, data->width); + } + } + + /* fill dest into second half of scanline */ + if (fetchDest) + fetchDest(data->dest, data->xDest, data->yDest + i, data->width, dest_buffer); + + /* blend */ + compose(dest_buffer, src_buffer, data->width); + + /* write back */ + store(data->dest, data->xDest, data->yDest + i, data->width, dest_buffer); + } + } +} + +void +fbCompositeGeneral (CARD8 op, + PicturePtr pSrc, + PicturePtr pMask, + PicturePtr pDst, + INT16 xSrc, + INT16 ySrc, + INT16 xMask, + INT16 yMask, + INT16 xDst, + INT16 yDst, + CARD16 width, + CARD16 height) +{ + RegionRec region; + int n; + BoxPtr pbox; + Bool srcRepeat = FALSE; + Bool maskRepeat = FALSE; + int w, h; + CARD32 _scanline_buffer[SCANLINE_BUFFER_LENGTH*3]; + CARD32 *scanline_buffer = _scanline_buffer; + FbComposeData compose_data; + + if (pSrc->pDrawable) + srcRepeat = pSrc->repeatType == RepeatNormal && !pSrc->transform + && (pSrc->pDrawable->width != 1 || pSrc->pDrawable->height != 1); + + if (pMask && pMask->pDrawable) + maskRepeat = pMask->repeatType == RepeatNormal && !pMask->transform + && (pMask->pDrawable->width != 1 || pMask->pDrawable->height != 1); + + if (op == PictOpOver && !pMask && !pSrc->transform && !PICT_FORMAT_A(pSrc->format) && !pSrc->alphaMap) + op = PictOpSrc; + + if (!miComputeCompositeRegion (®ion, + pSrc, + pMask, + pDst, + xSrc, + ySrc, + xMask, + yMask, + xDst, + yDst, + width, + height)) + return; + + compose_data.op = op; + compose_data.src = pSrc; + compose_data.mask = pMask; + compose_data.dest = pDst; + if (width > SCANLINE_BUFFER_LENGTH) + scanline_buffer = (CARD32 *) malloc(width * 3 * sizeof(CARD32)); + + n = RegionNumRects (®ion); + pbox = RegionRects (®ion); + while (n--) + { + h = pbox->y2 - pbox->y1; + compose_data.ySrc = pbox->y1 - yDst + ySrc; + compose_data.yMask = pbox->y1 - yDst + yMask; + compose_data.yDest = pbox->y1; + while (h) + { + compose_data.height = h; + w = pbox->x2 - pbox->x1; + compose_data.xSrc = pbox->x1 - xDst + xSrc; + compose_data.xMask = pbox->x1 - xDst + xMask; + compose_data.xDest = pbox->x1; + if (maskRepeat) + { + compose_data.yMask = mod (compose_data.yMask, pMask->pDrawable->height); + if (compose_data.height > pMask->pDrawable->height - compose_data.yMask) + compose_data.height = pMask->pDrawable->height - compose_data.yMask; + } + if (srcRepeat) + { + compose_data.ySrc = mod (compose_data.ySrc, pSrc->pDrawable->height); + if (compose_data.height > pSrc->pDrawable->height - compose_data.ySrc) + compose_data.height = pSrc->pDrawable->height - compose_data.ySrc; + } + while (w) + { + compose_data.width = w; + if (maskRepeat) + { + compose_data.xMask = mod (compose_data.xMask, pMask->pDrawable->width); + if (compose_data.width > pMask->pDrawable->width - compose_data.xMask) + compose_data.width = pMask->pDrawable->width - compose_data.xMask; + } + if (srcRepeat) + { + compose_data.xSrc = mod (compose_data.xSrc, pSrc->pDrawable->width); + if (compose_data.width > pSrc->pDrawable->width - compose_data.xSrc) + compose_data.width = pSrc->pDrawable->width - compose_data.xSrc; + } + fbCompositeRect(&compose_data, scanline_buffer); + w -= compose_data.width; + compose_data.xSrc += compose_data.width; + compose_data.xMask += compose_data.width; + compose_data.xDest += compose_data.width; + } + h -= compose_data.height; + compose_data.ySrc += compose_data.height; + compose_data.yMask += compose_data.height; + compose_data.yDest += compose_data.height; + } + pbox++; + } + RegionUninit(®ion); + + if (scanline_buffer != _scanline_buffer) + free(scanline_buffer); +} + +#endif diff --git a/nx-X11/programs/Xserver/fb/fbcopy.c b/nx-X11/programs/Xserver/fb/fbcopy.c new file mode 100644 index 000000000..7a1dbb5aa --- /dev/null +++ b/nx-X11/programs/Xserver/fb/fbcopy.c @@ -0,0 +1,636 @@ +/* + * Id: fbcopy.c,v 1.1 1999/11/02 03:54:45 keithp Exp $ + * + * 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 <stdlib.h> + +#include "fb.h" + +void +fbCopyNtoN (DrawablePtr pSrcDrawable, + DrawablePtr pDstDrawable, + GCPtr pGC, + BoxPtr pbox, + int nbox, + int dx, + int dy, + Bool reverse, + Bool upsidedown, + Pixel bitplane, + void *closure) +{ + CARD8 alu = pGC ? pGC->alu : GXcopy; + FbBits pm = pGC ? fbGetGCPrivate(pGC)->pm : FB_ALLONES; + FbBits *src; + FbStride srcStride; + int srcBpp; + int srcXoff, srcYoff; + FbBits *dst; + FbStride dstStride; + int dstBpp; + int dstXoff, dstYoff; + + fbGetDrawable (pSrcDrawable, src, srcStride, srcBpp, srcXoff, srcYoff); + fbGetDrawable (pDstDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff); + + while (nbox--) + { + fbBlt (src + (pbox->y1 + dy + srcYoff) * srcStride, + srcStride, + (pbox->x1 + dx + srcXoff) * srcBpp, + + dst + (pbox->y1 + dstYoff) * dstStride, + dstStride, + (pbox->x1 + dstXoff) * dstBpp, + + (pbox->x2 - pbox->x1) * dstBpp, + (pbox->y2 - pbox->y1), + + alu, + pm, + dstBpp, + + reverse, + upsidedown); + pbox++; + } +} + +void +fbCopy1toN (DrawablePtr pSrcDrawable, + DrawablePtr pDstDrawable, + GCPtr pGC, + BoxPtr pbox, + int nbox, + int dx, + int dy, + Bool reverse, + Bool upsidedown, + Pixel bitplane, + void *closure) +{ + FbGCPrivPtr pPriv = fbGetGCPrivate(pGC); + FbBits *src; + FbStride srcStride; + int srcBpp; + int srcXoff, srcYoff; + FbBits *dst; + FbStride dstStride; + int dstBpp; + int dstXoff, dstYoff; + + fbGetDrawable (pSrcDrawable, src, srcStride, srcBpp, srcXoff, srcYoff); + fbGetDrawable (pDstDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff); + + while (nbox--) + { + if (dstBpp == 1) + { + fbBlt (src + (pbox->y1 + dy + srcYoff) * srcStride, + srcStride, + (pbox->x1 + dx + srcXoff) * srcBpp, + + dst + (pbox->y1 + dstYoff) * dstStride, + dstStride, + (pbox->x1 + dstXoff) * dstBpp, + + (pbox->x2 - pbox->x1) * dstBpp, + (pbox->y2 - pbox->y1), + + FbOpaqueStipple1Rop(pGC->alu, + pGC->fgPixel,pGC->bgPixel), + pPriv->pm, + dstBpp, + + reverse, + upsidedown); + } + else + { + fbBltOne ((FbStip *) (src + (pbox->y1 + dy + srcYoff) * srcStride), + srcStride*(FB_UNIT/FB_STIP_UNIT), + (pbox->x1 + dx + srcXoff), + + dst + (pbox->y1 + dstYoff) * dstStride, + dstStride, + (pbox->x1 + dstXoff) * dstBpp, + dstBpp, + + (pbox->x2 - pbox->x1) * dstBpp, + (pbox->y2 - pbox->y1), + + pPriv->and, pPriv->xor, + pPriv->bgand, pPriv->bgxor); + } + pbox++; + } +} + +void +fbCopyNto1 (DrawablePtr pSrcDrawable, + DrawablePtr pDstDrawable, + GCPtr pGC, + BoxPtr pbox, + int nbox, + int dx, + int dy, + Bool reverse, + Bool upsidedown, + Pixel bitplane, + void *closure) +{ + FbGCPrivPtr pPriv = fbGetGCPrivate (pGC); + + while (nbox--) + { + if (pDstDrawable->bitsPerPixel == 1) + { + FbBits *src; + FbStride srcStride; + int srcBpp; + int srcXoff, srcYoff; + + FbStip *dst; + FbStride dstStride; + int dstBpp; + int dstXoff, dstYoff; + + fbGetDrawable (pSrcDrawable, src, srcStride, srcBpp, srcXoff, srcYoff); + fbGetStipDrawable (pDstDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff); + fbBltPlane (src + (pbox->y1+ dy + srcYoff) * srcStride, + srcStride, + (pbox->x1 + dx + srcXoff) * srcBpp, + srcBpp, + + dst + (pbox->y1 + dstYoff) * dstStride, + dstStride, + (pbox->x1 + dstXoff) * dstBpp, + + (pbox->x2 - pbox->x1) * srcBpp, + (pbox->y2 - pbox->y1), + + (FbStip) pPriv->and, (FbStip) pPriv->xor, + (FbStip) pPriv->bgand, (FbStip) pPriv->bgxor, + bitplane); + } + else + { + FbBits *src; + FbStride srcStride; + int srcBpp; + int srcXoff, srcYoff; + + FbBits *dst; + FbStride dstStride; + int dstBpp; + int dstXoff, dstYoff; + + FbStip *tmp; + FbStride tmpStride; + int width, height; + + width = pbox->x2 - pbox->x1; + height = pbox->y2 - pbox->y1; + + tmpStride = ((width + FB_STIP_MASK) >> FB_STIP_SHIFT); + tmp = malloc (tmpStride * height * sizeof (FbStip)); + if (!tmp) + return; + + fbGetDrawable (pSrcDrawable, src, srcStride, srcBpp, srcXoff, srcYoff); + fbGetDrawable (pDstDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff); + + fbBltPlane (src + (pbox->y1+ dy + srcYoff) * srcStride, + srcStride, + (pbox->x1 + dx + srcXoff) * srcBpp, + srcBpp, + + tmp, + tmpStride, + 0, + + width * srcBpp, + height, + + fbAndStip(GXcopy,FB_ALLONES,FB_ALLONES), + fbXorStip(GXcopy,FB_ALLONES,FB_ALLONES), + fbAndStip(GXcopy,0,FB_ALLONES), + fbXorStip(GXcopy,0,FB_ALLONES), + bitplane); + fbBltOne (tmp, + tmpStride, + 0, + + dst + (pbox->y1 + dstYoff) * dstStride, + dstStride, + (pbox->x1 + dstXoff) * dstBpp, + dstBpp, + + width * dstBpp, + height, + + pPriv->and, pPriv->xor, + pPriv->bgand, pPriv->bgxor); + free (tmp); + } + pbox++; + } +} + +void +fbCopyRegion (DrawablePtr pSrcDrawable, + DrawablePtr pDstDrawable, + GCPtr pGC, + RegionPtr pDstRegion, + int dx, + int dy, + fbCopyProc copyProc, + Pixel bitPlane, + void *closure) +{ + int careful; + Bool reverse; + Bool upsidedown; + BoxPtr pbox; + int nbox; + BoxPtr pboxNew1, pboxNew2, pboxBase, pboxNext, pboxTmp; + + pbox = RegionRects(pDstRegion); + nbox = RegionNumRects(pDstRegion); + + /* XXX we have to err on the side of safety when both are windows, + * because we don't know if IncludeInferiors is being used. + */ + careful = ((pSrcDrawable == pDstDrawable) || + ((pSrcDrawable->type == DRAWABLE_WINDOW) && + (pDstDrawable->type == DRAWABLE_WINDOW))); + + pboxNew1 = NULL; + pboxNew2 = NULL; + if (careful && dy < 0) + { + upsidedown = TRUE; + + if (nbox > 1) + { + /* keep ordering in each band, reverse order of bands */ + pboxNew1 = (BoxPtr)malloc(sizeof(BoxRec) * nbox); + if(!pboxNew1) + return; + pboxBase = pboxNext = pbox+nbox-1; + while (pboxBase >= pbox) + { + while ((pboxNext >= pbox) && + (pboxBase->y1 == pboxNext->y1)) + pboxNext--; + pboxTmp = pboxNext+1; + while (pboxTmp <= pboxBase) + { + *pboxNew1++ = *pboxTmp++; + } + pboxBase = pboxNext; + } + pboxNew1 -= nbox; + pbox = pboxNew1; + } + } + else + { + /* walk source top to bottom */ + upsidedown = FALSE; + } + + if (careful && dx < 0) + { + /* walk source right to left */ + if (dy <= 0) + reverse = TRUE; + else + reverse = FALSE; + + if (nbox > 1) + { + /* reverse order of rects in each band */ + pboxNew2 = (BoxPtr)malloc(sizeof(BoxRec) * nbox); + if(!pboxNew2) + { + if (pboxNew1) + free(pboxNew1); + return; + } + pboxBase = pboxNext = pbox; + while (pboxBase < pbox+nbox) + { + while ((pboxNext < pbox+nbox) && + (pboxNext->y1 == pboxBase->y1)) + pboxNext++; + pboxTmp = pboxNext; + while (pboxTmp != pboxBase) + { + *pboxNew2++ = *--pboxTmp; + } + pboxBase = pboxNext; + } + pboxNew2 -= nbox; + pbox = pboxNew2; + } + } + else + { + /* walk source left to right */ + reverse = FALSE; + } + + (*copyProc) (pSrcDrawable, + pDstDrawable, + pGC, + pbox, + nbox, + dx, dy, + reverse, upsidedown, bitPlane, closure); + + if (pboxNew1) + free (pboxNew1); + if (pboxNew2) + free (pboxNew2); +} + +RegionPtr +fbDoCopy (DrawablePtr pSrcDrawable, + DrawablePtr pDstDrawable, + GCPtr pGC, + int xIn, + int yIn, + int widthSrc, + int heightSrc, + int xOut, + int yOut, + fbCopyProc copyProc, + Pixel bitPlane, + void *closure) +{ + RegionPtr prgnSrcClip = NULL; /* may be a new region, or just a copy */ + Bool freeSrcClip = FALSE; + RegionPtr prgnExposed = NULL; + RegionRec rgnDst; + int dx; + int dy; + int numRects; + int box_x1; + int box_y1; + int box_x2; + int box_y2; + Bool fastSrc = FALSE; /* for fast clipping with pixmap source */ + Bool fastDst = FALSE; /* for fast clipping with one rect dest */ + Bool fastExpose = FALSE; /* for fast exposures with pixmap source */ + + /* Short cut for unmapped windows */ + + if (pDstDrawable->type == DRAWABLE_WINDOW && + !((WindowPtr)pDstDrawable)->realized) + { + return NULL; + } + + if ((pSrcDrawable != pDstDrawable) && + pSrcDrawable->pScreen->SourceValidate) + { + (*pSrcDrawable->pScreen->SourceValidate) (pSrcDrawable, xIn, yIn, widthSrc, heightSrc); + } + + /* Compute source clip region */ + if (pSrcDrawable->type == DRAWABLE_PIXMAP) + { + if ((pSrcDrawable == pDstDrawable) && (pGC->clientClipType == CT_NONE)) + prgnSrcClip = fbGetCompositeClip(pGC); + else + fastSrc = TRUE; + } + else + { + if (pGC->subWindowMode == IncludeInferiors) + { + /* + * XFree86 DDX empties the border clip when the + * VT is inactive, make sure the region isn't empty + */ + if (!((WindowPtr) pSrcDrawable)->parent && + RegionNotEmpty( + &((WindowPtr) pSrcDrawable)->borderClip)) + { + /* + * special case bitblt from root window in + * IncludeInferiors mode; just like from a pixmap + */ + fastSrc = TRUE; + } + else if ((pSrcDrawable == pDstDrawable) && + (pGC->clientClipType == CT_NONE)) + { + prgnSrcClip = fbGetCompositeClip(pGC); + } + else + { + prgnSrcClip = NotClippedByChildren((WindowPtr)pSrcDrawable); + freeSrcClip = TRUE; + } + } + else + { + prgnSrcClip = &((WindowPtr)pSrcDrawable)->clipList; + } + } + + xIn += pSrcDrawable->x; + yIn += pSrcDrawable->y; + + xOut += pDstDrawable->x; + yOut += pDstDrawable->y; + + box_x1 = xIn; + box_y1 = yIn; + box_x2 = xIn + widthSrc; + box_y2 = yIn + heightSrc; + + dx = xIn - xOut; + dy = yIn - yOut; + + /* Don't create a source region if we are doing a fast clip */ + if (fastSrc) + { + RegionPtr cclip; + + fastExpose = TRUE; + /* + * clip the source; if regions extend beyond the source size, + * make sure exposure events get sent + */ + if (box_x1 < pSrcDrawable->x) + { + box_x1 = pSrcDrawable->x; + fastExpose = FALSE; + } + if (box_y1 < pSrcDrawable->y) + { + box_y1 = pSrcDrawable->y; + fastExpose = FALSE; + } + if (box_x2 > pSrcDrawable->x + (int) pSrcDrawable->width) + { + box_x2 = pSrcDrawable->x + (int) pSrcDrawable->width; + fastExpose = FALSE; + } + if (box_y2 > pSrcDrawable->y + (int) pSrcDrawable->height) + { + box_y2 = pSrcDrawable->y + (int) pSrcDrawable->height; + fastExpose = FALSE; + } + + /* Translate and clip the dst to the destination composite clip */ + box_x1 -= dx; + box_x2 -= dx; + box_y1 -= dy; + box_y2 -= dy; + + /* If the destination composite clip is one rectangle we can + do the clip directly. Otherwise we have to create a full + blown region and call intersect */ + + cclip = fbGetCompositeClip(pGC); + if (RegionNumRects(cclip) == 1) + { + BoxPtr pBox = RegionRects(cclip); + + if (box_x1 < pBox->x1) box_x1 = pBox->x1; + if (box_x2 > pBox->x2) box_x2 = pBox->x2; + if (box_y1 < pBox->y1) box_y1 = pBox->y1; + if (box_y2 > pBox->y2) box_y2 = pBox->y2; + fastDst = TRUE; + } + } + + /* Check to see if the region is empty */ + if (box_x1 >= box_x2 || box_y1 >= box_y2) + { + RegionNull(&rgnDst); + } + else + { + BoxRec box; + box.x1 = box_x1; + box.y1 = box_y1; + box.x2 = box_x2; + box.y2 = box_y2; + RegionInit(&rgnDst, &box, 1); + } + + /* Clip against complex source if needed */ + if (!fastSrc) + { + RegionIntersect(&rgnDst, &rgnDst, prgnSrcClip); + RegionTranslate(&rgnDst, -dx, -dy); + } + + /* Clip against complex dest if needed */ + if (!fastDst) + { + RegionIntersect(&rgnDst, &rgnDst, + fbGetCompositeClip(pGC)); + } + + /* Do bit blitting */ + numRects = RegionNumRects(&rgnDst); + if (numRects && widthSrc && heightSrc) + fbCopyRegion (pSrcDrawable, pDstDrawable, pGC, + &rgnDst, dx, dy, copyProc, bitPlane, closure); + + /* Pixmap sources generate a NoExposed (we return NULL to do this) */ + if (!fastExpose && pGC->fExpose) + prgnExposed = miHandleExposures(pSrcDrawable, pDstDrawable, pGC, + xIn - pSrcDrawable->x, + yIn - pSrcDrawable->y, + widthSrc, heightSrc, + xOut - pDstDrawable->x, + yOut - pDstDrawable->y, + (unsigned long) bitPlane); + RegionUninit(&rgnDst); + if (freeSrcClip) + RegionDestroy(prgnSrcClip); + fbValidateDrawable (pDstDrawable); + return prgnExposed; +} + +RegionPtr +fbCopyArea (DrawablePtr pSrcDrawable, + DrawablePtr pDstDrawable, + GCPtr pGC, + int xIn, + int yIn, + int widthSrc, + int heightSrc, + int xOut, + int yOut) +{ + fbCopyProc copy; + +#ifdef FB_24_32BIT + if (pSrcDrawable->bitsPerPixel != pDstDrawable->bitsPerPixel) + copy = fb24_32CopyMtoN; + else +#endif + copy = fbCopyNtoN; + return fbDoCopy (pSrcDrawable, pDstDrawable, pGC, xIn, yIn, + widthSrc, heightSrc, xOut, yOut, copy, 0, 0); +} + +RegionPtr +fbCopyPlane (DrawablePtr pSrcDrawable, + DrawablePtr pDstDrawable, + GCPtr pGC, + int xIn, + int yIn, + int widthSrc, + int heightSrc, + int xOut, + int yOut, + unsigned long bitplane) +{ + if (pSrcDrawable->bitsPerPixel > 1) + return fbDoCopy (pSrcDrawable, pDstDrawable, pGC, + xIn, yIn, widthSrc, heightSrc, + xOut, yOut, fbCopyNto1, (Pixel) bitplane, 0); + else if (bitplane & 1) + return fbDoCopy (pSrcDrawable, pDstDrawable, pGC, xIn, yIn, + widthSrc, heightSrc, xOut, yOut, fbCopy1toN, + (Pixel) bitplane, 0); + else + return miHandleExposures(pSrcDrawable, pDstDrawable, pGC, + xIn, yIn, + widthSrc, + heightSrc, + xOut, yOut, bitplane); +} diff --git a/nx-X11/programs/Xserver/fb/fbedge.c b/nx-X11/programs/Xserver/fb/fbedge.c new file mode 100644 index 000000000..66dcdc35f --- /dev/null +++ b/nx-X11/programs/Xserver/fb/fbedge.c @@ -0,0 +1,314 @@ +/* + * $Id: fbedge.c,v 1.5 2005/10/03 10:20:29 anholt Exp $ + * + * Copyright © 2004 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. + */ + +#include <string.h> + +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#endif + +#include "fb.h" + +#ifdef RENDER + +#include "picturestr.h" +#include "mipict.h" +#include "renderedge.h" +#include "fbpict.h" + +/* + * 4 bit alpha + */ + +#define N_BITS 4 +#define rasterizeEdges fbRasterizeEdges4 + +#if BITMAP_BIT_ORDER == LSBFirst +#define Shift4(o) ((o) << 2) +#else +#define Shift4(o) ((1-(o)) << 2) +#endif + +#define Get4(x,o) (((x) >> Shift4(o)) & 0xf) +#define Put4(x,o,v) (((x) & ~(0xf << Shift4(o))) | (((v) & 0xf) << Shift4(o))) + +#define DefineAlpha(line,x) \ + CARD8 *__ap = (CARD8 *) line + ((x) >> 1); \ + int __ao = (x) & 1 + +#define StepAlpha ((__ap += __ao), (__ao ^= 1)) + +#define AddAlpha(a) { \ + CARD8 __o = *__ap; \ + CARD8 __a = (a) + Get4(__o, __ao); \ + *__ap = Put4 (__o, __ao, __a | (0 - ((__a) >> 4))); \ +} + +#include "fbedgeimp.h" + +#undef AddAlpha +#undef StepAlpha +#undef DefineAlpha +#undef rasterizeEdges +#undef N_BITS + + +/* + * 1 bit alpha + */ + +#define N_BITS 1 +#define rasterizeEdges fbRasterizeEdges1 + +#include "fbedgeimp.h" + +#undef rasterizeEdges +#undef N_BITS + +/* + * 8 bit alpha + */ + +static INLINE CARD8 +clip255 (int x) +{ + if (x > 255) return 255; + return x; +} + +static INLINE void +add_saturate_8 (CARD8 *buf, int value, int length) +{ + while (length--) + { + *buf = clip255 (*buf + value); + buf++; + } +} + +/* + * We want to detect the case where we add the same value to a long + * span of pixels. The triangles on the end are filled in while we + * count how many sub-pixel scanlines contribute to the middle section. + * + * +--------------------------+ + * fill_height =| \ / + * +------------------+ + * |================| + * fill_start fill_end + */ +static void +fbRasterizeEdges8 (FbBits *buf, + int width, + int stride, + RenderEdge *l, + RenderEdge *r, + xFixed t, + xFixed b) +{ + xFixed y = t; + FbBits *line; + int fill_start = -1, fill_end = -1; + int fill_size = 0; + + line = buf + xFixedToInt (y) * stride; + + for (;;) + { + CARD8 *ap = (CARD8 *) line; + xFixed lx, rx; + int lxi, rxi; + + /* clip X */ + lx = l->x; + if (lx < 0) + lx = 0; + rx = r->x; + if (xFixedToInt (rx) >= width) + rx = IntToxFixed (width); + + /* Skip empty (or backwards) sections */ + if (rx > lx) + { + int lxs, rxs; + + /* Find pixel bounds for span. */ + lxi = xFixedToInt (lx); + rxi = xFixedToInt (rx); + + /* Sample coverage for edge pixels */ + lxs = RenderSamplesX (lx, 8); + rxs = RenderSamplesX (rx, 8); + + /* Add coverage across row */ + if (lxi == rxi) + { + ap[lxi] = clip255 (ap[lxi] + rxs - lxs); + } + else + { + ap[lxi] = clip255 (ap[lxi] + N_X_FRAC(8) - lxs); + + /* Move forward so that lxi/rxi is the pixel span */ + lxi++; + + /* Don't bother trying to optimize the fill unless + * the span is longer than 4 pixels. */ + if (rxi - lxi > 4) + { + if (fill_start < 0) + { + fill_start = lxi; + fill_end = rxi; + fill_size++; + } + else + { + if (lxi >= fill_end || rxi < fill_start) + { + /* We're beyond what we saved, just fill it */ + add_saturate_8 (ap + fill_start, + fill_size * N_X_FRAC(8), + fill_end - fill_start); + fill_start = lxi; + fill_end = rxi; + fill_size = 1; + } + else + { + /* Update fill_start */ + if (lxi > fill_start) + { + add_saturate_8 (ap + fill_start, + fill_size * N_X_FRAC(8), + lxi - fill_start); + fill_start = lxi; + } + else if (lxi < fill_start) + { + add_saturate_8 (ap + lxi, N_X_FRAC(8), + fill_start - lxi); + } + + /* Update fill_end */ + if (rxi < fill_end) + { + add_saturate_8 (ap + rxi, + fill_size * N_X_FRAC(8), + fill_end - rxi); + fill_end = rxi; + } + else if (fill_end < rxi) + { + add_saturate_8 (ap + fill_end, + N_X_FRAC(8), + rxi - fill_end); + } + fill_size++; + } + } + } + else + { + add_saturate_8 (ap + lxi, N_X_FRAC(8), rxi - lxi); + } + + /* Do not add in a 0 alpha here. This check is + * necessary to avoid a buffer overrun, (when rx + * is exactly on a pixel boundary). */ + if (rxs) + ap[rxi] = clip255 (ap[rxi] + rxs); + } + } + + if (y == b) { + /* We're done, make sure we clean up any remaining fill. */ + if (fill_start != fill_end) { + if (fill_size == N_Y_FRAC(8)) + { + memset (ap + fill_start, 0xff, fill_end - fill_start); + } + else + { + add_saturate_8 (ap + fill_start, fill_size * N_X_FRAC(8), + fill_end - fill_start); + } + } + break; + } + + if (xFixedFrac (y) != Y_FRAC_LAST(8)) + { + RenderEdgeStepSmall (l); + RenderEdgeStepSmall (r); + y += STEP_Y_SMALL(8); + } + else + { + RenderEdgeStepBig (l); + RenderEdgeStepBig (r); + y += STEP_Y_BIG(8); + if (fill_start != fill_end) + { + if (fill_size == N_Y_FRAC(8)) + { + memset (ap + fill_start, 0xff, fill_end - fill_start); + } + else + { + add_saturate_8 (ap + fill_start, fill_size * N_X_FRAC(8), + fill_end - fill_start); + } + fill_start = fill_end = -1; + fill_size = 0; + } + line += stride; + } + } +} + +void +fbRasterizeEdges (FbBits *buf, + int bpp, + int width, + int stride, + RenderEdge *l, + RenderEdge *r, + xFixed t, + xFixed b) +{ + switch (bpp) { + case 1: + fbRasterizeEdges1 (buf, width, stride, l, r, t, b); + break; + case 4: + fbRasterizeEdges4 (buf, width, stride, l, r, t, b); + break; + case 8: + fbRasterizeEdges8 (buf, width, stride, l, r, t, b); + break; + } +} + +#endif /* RENDER */ diff --git a/nx-X11/programs/Xserver/fb/fbedgeimp.h b/nx-X11/programs/Xserver/fb/fbedgeimp.h new file mode 100644 index 000000000..6b363d7ce --- /dev/null +++ b/nx-X11/programs/Xserver/fb/fbedgeimp.h @@ -0,0 +1,143 @@ +/* + * $Id: fbedgeimp.h,v 1.4 2005/08/30 03:05:21 anholt Exp $ + * + * Copyright © 2004 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 + +#ifndef rasterizeSpan +#endif + +static void +rasterizeEdges (FbBits *buf, + int width, + int stride, + RenderEdge *l, + RenderEdge *r, + xFixed t, + xFixed b) +{ + xFixed y = t; + FbBits *line; + + line = buf + xFixedToInt (y) * stride; + + for (;;) + { + xFixed lx, rx; + int lxi, rxi; + + /* clip X */ + lx = l->x; + if (lx < 0) + lx = 0; + rx = r->x; + if (xFixedToInt (rx) >= width) + rx = IntToxFixed (width); + + /* Skip empty (or backwards) sections */ + if (rx > lx) + { + + /* Find pixel bounds for span */ + lxi = xFixedToInt (lx); + rxi = xFixedToInt (rx); + +#if N_BITS == 1 + { + FbBits *a = line; + FbBits startmask, endmask; + int nmiddle; + int width = rxi - lxi; + int x = lxi; + + a += x >> FB_SHIFT; + x &= FB_MASK; + + FbMaskBits (x, width, startmask, nmiddle, endmask); + if (startmask) + *a++ |= startmask; + while (nmiddle--) + *a++ = FB_ALLONES; + if (endmask) + *a |= endmask; + } +#else + { + DefineAlpha(line,lxi); + int lxs, rxs; + + /* Sample coverage for edge pixels */ + lxs = RenderSamplesX (lx, N_BITS); + rxs = RenderSamplesX (rx, N_BITS); + + /* Add coverage across row */ + if (lxi == rxi) + { + AddAlpha (rxs - lxs); + } + else + { + int xi; + + AddAlpha (N_X_FRAC(N_BITS) - lxs); + StepAlpha; + for (xi = lxi + 1; xi < rxi; xi++) + { + AddAlpha (N_X_FRAC(N_BITS)); + StepAlpha; + } + /* Do not add in a 0 alpha here. This check is necessary + * to avoid a buffer overrun when rx is exactly on a pixel + * boundary. + */ + if (rxs != 0) + AddAlpha (rxs); + } + } +#endif + } + + if (y == b) + break; + +#if N_BITS > 1 + if (xFixedFrac (y) != Y_FRAC_LAST(N_BITS)) + { + RenderEdgeStepSmall (l); + RenderEdgeStepSmall (r); + y += STEP_Y_SMALL(N_BITS); + } + else +#endif + { + RenderEdgeStepBig (l); + RenderEdgeStepBig (r); + y += STEP_Y_BIG(N_BITS); + line += stride; + } + } +} + +#undef rasterizeSpan diff --git a/nx-X11/programs/Xserver/fb/fbfill.c b/nx-X11/programs/Xserver/fb/fbfill.c new file mode 100644 index 000000000..2d1d163f6 --- /dev/null +++ b/nx-X11/programs/Xserver/fb/fbfill.c @@ -0,0 +1,215 @@ +/* + * Id: fbfill.c,v 1.1 1999/11/02 03:54:45 keithp Exp $ + * + * 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 +fbFill (DrawablePtr pDrawable, + GCPtr pGC, + int x, + int y, + int width, + int height) +{ + FbBits *dst; + FbStride dstStride; + int dstBpp; + int dstXoff, dstYoff; + FbGCPrivPtr pPriv = fbGetGCPrivate(pGC); + + fbGetDrawable (pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff); + + switch (pGC->fillStyle) { + case FillSolid: + fbSolid (dst + (y + dstYoff) * dstStride, + dstStride, + (x + dstXoff) * dstBpp, + dstBpp, + width * dstBpp, height, + pPriv->and, pPriv->xor); + break; + case FillStippled: + case FillOpaqueStippled: { + PixmapPtr pStip = pGC->stipple; + int stipWidth = pStip->drawable.width; + int stipHeight = pStip->drawable.height; + + if (dstBpp == 1) + { + int alu; + FbBits *stip; + FbStride stipStride; + int stipBpp; + _X_UNUSED int stipXoff, stipYoff; /* XXX assumed to be zero */ + + if (pGC->fillStyle == FillStippled) + alu = FbStipple1Rop(pGC->alu,pGC->fgPixel); + else + alu = FbOpaqueStipple1Rop(pGC->alu,pGC->fgPixel,pGC->bgPixel); + fbGetDrawable (&pStip->drawable, stip, stipStride, stipBpp, stipXoff, stipYoff); + fbTile (dst + (y + dstYoff) * dstStride, + dstStride, + x + dstXoff, + width, height, + stip, + stipStride, + stipWidth, + stipHeight, + alu, + pPriv->pm, + dstBpp, + + (pGC->patOrg.x + pDrawable->x + dstXoff), + pGC->patOrg.y + pDrawable->y - y); + } + else + { + FbStip *stip; + FbStride stipStride; + int stipBpp; + _X_UNUSED int stipXoff, stipYoff; /* XXX assumed to be zero */ + FbBits fgand, fgxor, bgand, bgxor; + + fgand = pPriv->and; + fgxor = pPriv->xor; + if (pGC->fillStyle == FillStippled) + { + bgand = fbAnd(GXnoop,(FbBits) 0,FB_ALLONES); + bgxor = fbXor(GXnoop,(FbBits) 0,FB_ALLONES); + } + else + { + bgand = pPriv->bgand; + bgxor = pPriv->bgxor; + } + + fbGetStipDrawable (&pStip->drawable, stip, stipStride, stipBpp, stipXoff, stipYoff); + fbStipple (dst + (y + dstYoff) * dstStride, + dstStride, + (x + dstXoff) * dstBpp, + dstBpp, + width * dstBpp, height, + stip, + stipStride, + stipWidth, + stipHeight, + pPriv->evenStipple, + fgand, fgxor, + bgand, bgxor, + pGC->patOrg.x + pDrawable->x + dstXoff, + pGC->patOrg.y + pDrawable->y - y); + } + break; + } + case FillTiled: { + PixmapPtr pTile = pGC->tile.pixmap; + FbBits *tile; + FbStride tileStride; + int tileBpp; + int tileWidth; + int tileHeight; + _X_UNUSED int tileXoff, tileYoff; /* XXX assumed to be zero */ + + fbGetDrawable (&pTile->drawable, tile, tileStride, tileBpp, tileXoff, tileYoff); + tileWidth = pTile->drawable.width; + tileHeight = pTile->drawable.height; + fbTile (dst + (y + dstYoff) * dstStride, + dstStride, + (x + dstXoff) * dstBpp, + width * dstBpp, height, + tile, + tileStride, + tileWidth * tileBpp, + tileHeight, + pGC->alu, + pPriv->pm, + dstBpp, + (pGC->patOrg.x + pDrawable->x + dstXoff) * dstBpp, + pGC->patOrg.y + pDrawable->y - y); + break; + } + } + fbValidateDrawable (pDrawable); +} + +void +fbSolidBoxClipped (DrawablePtr pDrawable, + RegionPtr pClip, + int x1, + int y1, + int x2, + int y2, + FbBits and, + FbBits xor) +{ + FbBits *dst; + FbStride dstStride; + int dstBpp; + int dstXoff, dstYoff; + BoxPtr pbox; + int nbox; + int partX1, partX2, partY1, partY2; + + fbGetDrawable (pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff); + + for (nbox = RegionNumRects(pClip), pbox = RegionRects(pClip); + nbox--; + pbox++) + { + partX1 = pbox->x1; + if (partX1 < x1) + partX1 = x1; + + partX2 = pbox->x2; + if (partX2 > x2) + partX2 = x2; + + if (partX2 <= partX1) + continue; + + partY1 = pbox->y1; + if (partY1 < y1) + partY1 = y1; + + partY2 = pbox->y2; + if (partY2 > y2) + partY2 = y2; + + if (partY2 <= partY1) + continue; + + fbSolid (dst + (partY1 + dstYoff) * dstStride, + dstStride, + (partX1 + dstXoff) * dstBpp, + dstBpp, + + (partX2 - partX1) * dstBpp, + (partY2 - partY1), + and, xor); + } +} diff --git a/nx-X11/programs/Xserver/fb/fbfillrect.c b/nx-X11/programs/Xserver/fb/fbfillrect.c new file mode 100644 index 000000000..2a19fa7d2 --- /dev/null +++ b/nx-X11/programs/Xserver/fb/fbfillrect.c @@ -0,0 +1,114 @@ +/* + * Id: fbfillrect.c,v 1.1 1999/11/02 03:54:45 keithp Exp $ + * + * 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 +fbPolyFillRect(DrawablePtr pDrawable, + GCPtr pGC, + int nrect, + xRectangle *prect) +{ + RegionPtr pClip = fbGetCompositeClip(pGC); + register BoxPtr pbox; + BoxPtr pextent; + int extentX1, extentX2, extentY1, extentY2; + int fullX1, fullX2, fullY1, fullY2; + int partX1, partX2, partY1, partY2; + int xorg, yorg; + int n; + + xorg = pDrawable->x; + yorg = pDrawable->y; + + pextent = RegionExtents(pClip); + extentX1 = pextent->x1; + extentY1 = pextent->y1; + extentX2 = pextent->x2; + extentY2 = pextent->y2; + while (nrect--) + { + fullX1 = prect->x + xorg; + fullY1 = prect->y + yorg; + fullX2 = fullX1 + (int) prect->width; + fullY2 = fullY1 + (int) prect->height; + prect++; + + if (fullX1 < extentX1) + fullX1 = extentX1; + + if (fullY1 < extentY1) + fullY1 = extentY1; + + if (fullX2 > extentX2) + fullX2 = extentX2; + + if (fullY2 > extentY2) + fullY2 = extentY2; + + if ((fullX1 >= fullX2) || (fullY1 >= fullY2)) + continue; + n = RegionNumRects (pClip); + if (n == 1) + { + fbFill (pDrawable, + pGC, + fullX1, fullY1, fullX2-fullX1, fullY2-fullY1); + } + else + { + pbox = RegionRects(pClip); + /* + * clip the rectangle to each box in the clip region + * this is logically equivalent to calling Intersect() + */ + while(n--) + { + partX1 = pbox->x1; + if (partX1 < fullX1) + partX1 = fullX1; + partY1 = pbox->y1; + if (partY1 < fullY1) + partY1 = fullY1; + partX2 = pbox->x2; + if (partX2 > fullX2) + partX2 = fullX2; + partY2 = pbox->y2; + if (partY2 > fullY2) + partY2 = fullY2; + + pbox++; + + if (partX1 < partX2 && partY1 < partY2) + fbFill (pDrawable, pGC, + partX1, partY1, + partX2 - partX1, partY2 - partY1); + } + } + } +} diff --git a/nx-X11/programs/Xserver/fb/fbfillsp.c b/nx-X11/programs/Xserver/fb/fbfillsp.c new file mode 100644 index 000000000..ca9fdbb0a --- /dev/null +++ b/nx-X11/programs/Xserver/fb/fbfillsp.c @@ -0,0 +1,102 @@ +/* + * Id: fbfillsp.c,v 1.1 1999/11/02 03:54:45 keithp Exp $ + * + * 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 +fbFillSpans (DrawablePtr pDrawable, + GCPtr pGC, + int n, + DDXPointPtr ppt, + int *pwidth, + int fSorted) +{ + RegionPtr pClip = fbGetCompositeClip(pGC); + BoxPtr pextent, pbox; + int nbox; + int extentX1, extentX2, extentY1, extentY2; + int fullX1, fullX2, fullY1; + int partX1, partX2; + + pextent = RegionExtents(pClip); + extentX1 = pextent->x1; + extentY1 = pextent->y1; + extentX2 = pextent->x2; + extentY2 = pextent->y2; + while (n--) + { + fullX1 = ppt->x; + fullY1 = ppt->y; + fullX2 = fullX1 + (int) *pwidth; + ppt++; + pwidth++; + + if (fullY1 < extentY1 || extentY2 <= fullY1) + continue; + + if (fullX1 < extentX1) + fullX1 = extentX1; + + if (fullX2 > extentX2) + fullX2 = extentX2; + + if (fullX1 >= fullX2) + continue; + + nbox = RegionNumRects (pClip); + if (nbox == 1) + { + fbFill (pDrawable, + pGC, + fullX1, fullY1, fullX2-fullX1, 1); + } + else + { + pbox = RegionRects(pClip); + while(nbox--) + { + if (pbox->y1 <= fullY1 && fullY1 < pbox->y2) + { + partX1 = pbox->x1; + if (partX1 < fullX1) + partX1 = fullX1; + partX2 = pbox->x2; + if (partX2 > fullX2) + partX2 = fullX2; + if (partX2 > partX1) + { + fbFill (pDrawable, pGC, + partX1, fullY1, + partX2 - partX1, 1); + } + } + pbox++; + } + } + } +} diff --git a/nx-X11/programs/Xserver/fb/fbgc.c b/nx-X11/programs/Xserver/fb/fbgc.c new file mode 100644 index 000000000..437bc5df3 --- /dev/null +++ b/nx-X11/programs/Xserver/fb/fbgc.c @@ -0,0 +1,314 @@ +/* + * Id: fbgc.c,v 1.1 1999/11/02 03:54:45 keithp Exp $ + * + * 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 <stdlib.h> + +#include "fb.h" + +const GCFuncs fbGCFuncs = { + fbValidateGC, + miChangeGC, + miCopyGC, + miDestroyGC, + miChangeClip, + miDestroyClip, + miCopyClip, +}; + +const GCOps fbGCOps = { + fbFillSpans, + fbSetSpans, + fbPutImage, + fbCopyArea, + fbCopyPlane, + fbPolyPoint, + fbPolyLine, + fbPolySegment, + fbPolyRectangle, + fbPolyArc, + miFillPolygon, + fbPolyFillRect, + fbPolyFillArc, + miPolyText8, + miPolyText16, + miImageText8, + miImageText16, + fbImageGlyphBlt, + fbPolyGlyphBlt, + fbPushPixels +#ifdef NEED_LINEHELPER + ,NULL +#endif +}; + +Bool +fbCreateGC(GCPtr pGC) +{ + pGC->clientClip = NULL; + pGC->clientClipType = CT_NONE; + + pGC->ops = (GCOps *) &fbGCOps; + pGC->funcs = (GCFuncs *) &fbGCFuncs; + + /* fb wants to translate before scan conversion */ + pGC->miTranslate = 1; + + fbGetRotatedPixmap(pGC) = 0; + fbGetExpose(pGC) = 1; + fbGetFreeCompClip(pGC) = 0; + fbGetCompositeClip(pGC) = 0; + fbGetGCPrivate(pGC)->bpp = BitsPerPixel (pGC->depth); + return TRUE; +} + +/* + * Pad pixmap to FB_UNIT bits wide + */ +void +fbPadPixmap (PixmapPtr pPixmap) +{ + int width; + FbBits *bits; + FbBits b; + FbBits mask; + int height; + int w; + + width = pPixmap->drawable.width * pPixmap->drawable.bitsPerPixel; + bits = pPixmap->devPrivate.ptr; + height = pPixmap->drawable.height; + mask = FbBitsMask (0, width); + while (height--) + { + b = *bits & mask; + w = width; + while (w < FB_UNIT) + { + b = b | FbScrRight(b, w); + w <<= 1; + } + *bits++ = b; + } +} + +/* + * Verify that 'bits' repeats every 'len' bits + */ +static Bool +fbBitsRepeat (FbBits bits, int len, int width) +{ + FbBits mask = FbBitsMask(0, len); + FbBits orig = bits & mask; + int i; + + if (width > FB_UNIT) + width = FB_UNIT; + for (i = 0; i < width / len; i++) + { + if ((bits & mask) != orig) + return FALSE; + bits = FbScrLeft(bits,len); + } + return TRUE; +} + +/* + * Check whether an entire bitmap line is a repetition of + * the first 'len' bits + */ +static Bool +fbLineRepeat (FbBits *bits, int len, int width) +{ + FbBits first = bits[0]; + + if (!fbBitsRepeat (first, len, width)) + return FALSE; + width = (width + FB_UNIT-1) >> FB_SHIFT; + bits++; + while (--width) + if (*bits != first) + return FALSE; + return TRUE; +} + +/* + * The even stipple code wants the first FB_UNIT/bpp bits on + * each scanline to represent the entire stipple + */ +static Bool +fbCanEvenStipple (PixmapPtr pStipple, int bpp) +{ + int len = FB_UNIT / bpp; + FbBits *bits; + int stride; + int stip_bpp; + _X_UNUSED int stipXoff, stipYoff; + int h; + + /* can't even stipple 24bpp drawables */ + if ((bpp & (bpp-1)) != 0) + return FALSE; + /* make sure the stipple width is a multiple of the even stipple width */ + if (pStipple->drawable.width % len != 0) + return FALSE; + fbGetDrawable (&pStipple->drawable, bits, stride, stip_bpp, stipXoff, stipYoff); + h = pStipple->drawable.height; + /* check to see that the stipple repeats horizontally */ + while (h--) + { + if (!fbLineRepeat (bits, len, pStipple->drawable.width)) + return FALSE; + bits += stride; + } + return TRUE; +} + +void +fbValidateGC(GCPtr pGC, unsigned long changes, DrawablePtr pDrawable) +{ + FbGCPrivPtr pPriv = fbGetGCPrivate(pGC); + FbBits mask; + + pGC->lastWinOrg.x = pDrawable->x; + pGC->lastWinOrg.y = pDrawable->y; + + /* + * if the client clip is different or moved OR the subwindowMode has + * changed OR the window's clip has changed since the last validation + * we need to recompute the composite clip + */ + + if ((changes & (GCClipXOrigin|GCClipYOrigin|GCClipMask|GCSubwindowMode)) || + (pDrawable->serialNumber != (pGC->serialNumber & DRAWABLE_SERIAL_BITS)) + ) + { + miComputeCompositeClip (pGC, pDrawable); + pPriv->oneRect = RegionNumRects(fbGetCompositeClip(pGC)) == 1; + } + +#ifdef FB_24_32BIT + if (pPriv->bpp != pDrawable->bitsPerPixel) + { + changes |= GCStipple|GCForeground|GCBackground|GCPlaneMask; + pPriv->bpp = pDrawable->bitsPerPixel; + } + if ((changes & GCTile) && fbGetRotatedPixmap(pGC)) + { + (*pGC->pScreen->DestroyPixmap) (fbGetRotatedPixmap(pGC)); + fbGetRotatedPixmap(pGC) = 0; + } + + if (pGC->fillStyle == FillTiled) + { + PixmapPtr pOldTile, pNewTile; + + pOldTile = pGC->tile.pixmap; + if (pOldTile->drawable.bitsPerPixel != pDrawable->bitsPerPixel) + { + pNewTile = fbGetRotatedPixmap(pGC); + if (!pNewTile || pNewTile ->drawable.bitsPerPixel != pDrawable->bitsPerPixel) + { + if (pNewTile) + (*pGC->pScreen->DestroyPixmap) (pNewTile); + pNewTile = fb24_32ReformatTile (pOldTile, pDrawable->bitsPerPixel); + } + if (pNewTile) + { + fbGetRotatedPixmap(pGC) = pOldTile; + pGC->tile.pixmap = pNewTile; + changes |= GCTile; + } + } + } +#endif + if (changes & GCTile) + { + if (!pGC->tileIsPixel && + FbEvenTile (pGC->tile.pixmap->drawable.width * + pDrawable->bitsPerPixel)) + fbPadPixmap (pGC->tile.pixmap); + } + if (changes & GCStipple) + { + pPriv->evenStipple = FALSE; + + if (pGC->stipple) { + + /* can we do an even stipple ?? */ + if (FbEvenStip (pGC->stipple->drawable.width, + pDrawable->bitsPerPixel) && + (fbCanEvenStipple (pGC->stipple, pDrawable->bitsPerPixel))) + pPriv->evenStipple = TRUE; + + if (pGC->stipple->drawable.width * pDrawable->bitsPerPixel < FB_UNIT) + fbPadPixmap (pGC->stipple); + } + } + /* + * Recompute reduced rop values + */ + if (changes & (GCForeground|GCBackground|GCPlaneMask|GCFunction)) + { + int s; + FbBits depthMask; + + mask = FbFullMask(pDrawable->bitsPerPixel); + depthMask = FbFullMask(pDrawable->depth); + + pPriv->fg = pGC->fgPixel & mask; + pPriv->bg = pGC->bgPixel & mask; + + if ((pGC->planemask & depthMask) == depthMask) + pPriv->pm = mask; + else + pPriv->pm = pGC->planemask & mask; + + s = pDrawable->bitsPerPixel; + while (s < FB_UNIT) + { + pPriv->fg |= pPriv->fg << s; + pPriv->bg |= pPriv->bg << s; + pPriv->pm |= pPriv->pm << s; + s <<= 1; + } + pPriv->and = fbAnd(pGC->alu, pPriv->fg, pPriv->pm); + pPriv->xor = fbXor(pGC->alu, pPriv->fg, pPriv->pm); + pPriv->bgand = fbAnd(pGC->alu, pPriv->bg, pPriv->pm); + pPriv->bgxor = fbXor(pGC->alu, pPriv->bg, pPriv->pm); + } + if (changes & GCDashList) + { + unsigned short n = pGC->numInDashList; + unsigned char *dash = pGC->dash; + unsigned int dashLength = 0; + + while (n--) + dashLength += (unsigned int ) *dash++; + pPriv->dashLength = dashLength; + } +} diff --git a/nx-X11/programs/Xserver/fb/fbgetsp.c b/nx-X11/programs/Xserver/fb/fbgetsp.c new file mode 100644 index 000000000..f77ea8c52 --- /dev/null +++ b/nx-X11/programs/Xserver/fb/fbgetsp.c @@ -0,0 +1,87 @@ +/* + * Id: fbgetsp.c,v 1.1 1999/11/02 03:54:45 keithp Exp $ + * + * 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 +fbGetSpans(DrawablePtr pDrawable, + int wMax, + DDXPointPtr ppt, + int *pwidth, + int nspans, + char *pchardstStart) +{ + FbBits *src, *dst; + FbStride srcStride; + int srcBpp; + int srcXoff, srcYoff; + int xoff; + + /* + * XFree86 DDX empties the root borderClip when the VT is + * switched away; this checks for that case + */ + if (!fbDrawableEnabled(pDrawable)) + return; + +#ifdef FB_24_32BIT + if (pDrawable->bitsPerPixel != BitsPerPixel(pDrawable->depth)) + { + fb24_32GetSpans (pDrawable, wMax, ppt, pwidth, nspans, pchardstStart); + return; + } +#endif + + fbGetDrawable (pDrawable, src, srcStride, srcBpp, srcXoff, srcYoff); + + while (nspans--) + { + xoff = (int) (((long) pchardstStart) & (FB_MASK >> 3)); + dst = (FbBits *) (pchardstStart - xoff); + xoff <<= 3; + fbBlt (src + (ppt->y + srcYoff) * srcStride, srcStride, + (ppt->x + srcXoff) * srcBpp, + + dst, + 1, + xoff, + + *pwidth * srcBpp, + 1, + + GXcopy, + FB_ALLONES, + srcBpp, + + FALSE, + FALSE); + pchardstStart += PixmapBytePad(*pwidth, pDrawable->depth); + ppt++; + pwidth++; + } +} diff --git a/nx-X11/programs/Xserver/fb/fbglyph.c b/nx-X11/programs/Xserver/fb/fbglyph.c new file mode 100644 index 000000000..6ff90e54a --- /dev/null +++ b/nx-X11/programs/Xserver/fb/fbglyph.c @@ -0,0 +1,476 @@ +/* + * 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" +#include <X11/fonts/fontstruct.h> +#include "dixfontstr.h" + +#define dummyScreen screenInfo.screens[0] + +Bool +fbGlyphIn (RegionPtr pRegion, + int x, + int y, + int width, + int height) +{ + BoxRec box; + BoxPtr pExtents = RegionExtents(pRegion); + + /* + * Check extents by hand to avoid 16 bit overflows + */ + if (x < (int) pExtents->x1) + return FALSE; + if ((int) pExtents->x2 < x + width) + return FALSE; + if (y < (int) pExtents->y1) + return FALSE; + if ((int) pExtents->y2 < y + height) + return FALSE; + box.x1 = x; + box.x2 = x + width; + box.y1 = y; + box.y2 = y + height; + return RegionContainsRect(pRegion, &box) == rgnIN; +} + +#ifdef FB_24BIT +#ifndef FBNOPIXADDR + +#define WRITE1(d,n,fg) ((d)[n] = (CARD8) fg) +#define WRITE2(d,n,fg) (*(CARD16 *) &(d[n]) = (CARD16) fg) +#define WRITE4(d,n,fg) (*(CARD32 *) &(d[n]) = (CARD32) fg) +#if FB_UNIT == 6 && IMAGE_BYTE_ORDER == LSBFirst +#define WRITE8(d) (*(FbBits *) &(d[0]) = fg) +#else +#define WRITE8(d) WRITE4(d,0,_ABCA), WRITE4(d,4,_BCAB) +#endif + +/* + * This is a bit tricky, but it's brief. Write 12 bytes worth + * of dest, which is four pixels, at a time. This gives constant + * code for each pattern as they're always aligned the same + * + * a b c d a b c d a b c d bytes + * A B C A B C A B C A B C pixels + * + * f0 f1 f2 + * A B C A B C A B C A B C pixels LSB + * C A B C A B C A B C A B pixels MSB + * + * LSB MSB + * A f0 f1 + * B f1 f2 + * C f2 f0 + * A B f0 f2 + * B C f1 f0 + * C A f2 f1 + * A B C A f0 f1 + * B C A B f1 f2 + * C A B C f2 f0 + */ + +#undef _A +#undef _B +#undef _C +#undef _AB +#undef _BC +#undef _CA +#undef _ABCA +#undef _BCAB +#undef _CABC + +#if IMAGE_BYTE_ORDER == MSBFirst +#define _A f1 +#define _B f2 +#define _C f0 +#define _AB f2 +#define _BC f0 +#define _CA f1 +#define _ABCA f1 +#define _BCAB f2 +#define _CABC f0 +#define CASE(a,b,c,d) ((a << 3) | (b << 2) | (c << 1) | d) +#else +#define _A f0 +#define _B f1 +#define _C f2 +#define _AB f0 +#define _BC f1 +#define _CA f2 +#define _ABCA f0 +#define _BCAB f1 +#define _CABC f2 +#define CASE(a,b,c,d) (a | (b << 1) | (c << 2) | (d << 3)) +#endif + +void +fbGlyph24 (FbBits *dstBits, + FbStride dstStride, + int dstBpp, + FbStip *stipple, + FbBits fg, + int x, + int height) +{ + int lshift; + FbStip bits; + CARD8 *dstLine; + CARD8 *dst; + FbStip f0, f1, f2; + int n; + int shift; + + f0 = fg; + f1 = FbRot24(f0,16); + f2 = FbRot24(f0,8); + + dstLine = (CARD8 *) dstBits; + dstLine += (x & ~3) * 3; + dstStride *= (sizeof (FbBits) / sizeof (CARD8)); + shift = x & 3; + lshift = 4 - shift; + while (height--) + { + bits = *stipple++; + n = lshift; + dst = dstLine; + while (bits) + { + switch (FbStipMoveLsb (FbLeftStipBits (bits, n), 4, n)) { + case CASE(0,0,0,0): + break; + case CASE(1,0,0,0): + WRITE2(dst,0,_AB); + WRITE1(dst,2,_C); + break; + case CASE(0,1,0,0): + WRITE1(dst,3,_A); + WRITE2(dst,4,_BC); + break; + case CASE(1,1,0,0): + WRITE4(dst,0,_ABCA); + WRITE2(dst,4,_BC); + break; + case CASE(0,0,1,0): + WRITE2(dst,6,_AB); + WRITE1(dst,8,_C); + break; + case CASE(1,0,1,0): + WRITE2(dst,0,_AB); + WRITE1(dst,2,_C); + + WRITE2(dst,6,_AB); + WRITE1(dst,8,_C); + break; + case CASE(0,1,1,0): + WRITE1(dst,3,_A); + WRITE4(dst,4,_BCAB); + WRITE1(dst,8,_C); + break; + case CASE(1,1,1,0): + WRITE8(dst); + WRITE1(dst,8,_C); + break; + case CASE(0,0,0,1): + WRITE1(dst,9,_A); + WRITE2(dst,10,_BC); + break; + case CASE(1,0,0,1): + WRITE2(dst,0,_AB); + WRITE1(dst,2,_C); + + WRITE1(dst,9,_A); + WRITE2(dst,10,_BC); + break; + case CASE(0,1,0,1): + WRITE1(dst,3,_A); + WRITE2(dst,4,_BC); + + WRITE1(dst,9,_A); + WRITE2(dst,10,_BC); + break; + case CASE(1,1,0,1): + WRITE4(dst,0,_ABCA); + WRITE2(dst,4,_BC); + + WRITE1(dst,9,_A); + WRITE2(dst,10,_BC); + break; + case CASE(0,0,1,1): + WRITE2(dst,6,_AB); + WRITE4(dst,8,_CABC); + break; + case CASE(1,0,1,1): + WRITE2(dst,0,_AB); + WRITE1(dst,2,_C); + + WRITE2(dst,6,_AB); + WRITE4(dst,8,_CABC); + break; + case CASE(0,1,1,1): + WRITE1(dst,3,_A); + WRITE4(dst,4,_BCAB); + WRITE4(dst,8,_CABC); + break; + case CASE(1,1,1,1): + WRITE8(dst); + WRITE4(dst,8,_CABC); + break; + } + bits = FbStipLeft (bits, n); + n = 4; + dst += 12; + } + dstLine += dstStride; + } +} +#endif +#endif + +void +fbPolyGlyphBlt (DrawablePtr pDrawable, + GCPtr pGC, + int x, + int y, + unsigned int nglyph, + CharInfoPtr *ppci, + void * pglyphBase) +{ + FbGCPrivPtr pPriv = fbGetGCPrivate (pGC); + CharInfoPtr pci; + unsigned char *pglyph; /* pointer bits in glyph */ + int gx, gy; + int gWidth, gHeight; /* width and height of glyph */ + FbStride gStride; /* stride of glyph */ +#ifndef FBNOPIXADDR + void (*glyph) (FbBits *, + FbStride, + int, + FbStip *, + FbBits, + int, + int); + FbBits *dst = 0; + FbStride dstStride = 0; + int dstBpp = 0; + int dstXoff = 0, dstYoff = 0; + + glyph = 0; + if (pGC->fillStyle == FillSolid && pPriv->and == 0) + { + fbGetDrawable (pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff); + switch (dstBpp) { + case 8: glyph = fbGlyph8; break; + case 16: glyph = fbGlyph16; break; +#ifdef FB_24BIT + case 24: glyph = fbGlyph24; break; +#endif + case 32: glyph = fbGlyph32; break; + } + } +#endif + x += pDrawable->x; + y += pDrawable->y; + + while (nglyph--) + { + pci = *ppci++; + pglyph = FONTGLYPHBITS(pglyphBase, pci); + gWidth = GLYPHWIDTHPIXELS(pci); + gHeight = GLYPHHEIGHTPIXELS(pci); + if (gWidth && gHeight) + { + gx = x + pci->metrics.leftSideBearing; + gy = y - pci->metrics.ascent; +#ifndef FBNOPIXADDR + if (glyph && gWidth <= sizeof (FbStip) * 8 && + fbGlyphIn (fbGetCompositeClip(pGC), gx, gy, gWidth, gHeight)) + { + (*glyph) (dst + (gy + dstYoff) * dstStride, + dstStride, + dstBpp, + (FbStip *) pglyph, + pPriv->xor, + gx + dstXoff, + gHeight); + } + else +#endif + { + gStride = GLYPHWIDTHBYTESPADDED(pci) / sizeof (FbStip); + fbPushImage (pDrawable, + pGC, + + (FbStip *) pglyph, + gStride, + 0, + + gx, + gy, + gWidth, gHeight); + } + } + x += pci->metrics.characterWidth; + } +} + + +void +fbImageGlyphBlt (DrawablePtr pDrawable, + GCPtr pGC, + int x, + int y, + unsigned int nglyph, + CharInfoPtr *ppciInit, + void * pglyphBase) +{ + FbGCPrivPtr pPriv = fbGetGCPrivate(pGC); + CharInfoPtr *ppci; + CharInfoPtr pci; + unsigned char *pglyph; /* pointer bits in glyph */ + int gWidth, gHeight; /* width and height of glyph */ + FbStride gStride; /* stride of glyph */ + Bool opaque; + int n; + int gx, gy; +#ifndef FBNOPIXADDR + void (*glyph) (FbBits *, + FbStride, + int, + FbStip *, + FbBits, + int, + int); + FbBits *dst = 0; + FbStride dstStride = 0; + int dstBpp = 0; + int dstXoff = 0, dstYoff = 0; + + glyph = 0; + if (pPriv->and == 0) + { + fbGetDrawable (pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff); + switch (dstBpp) { + case 8: glyph = fbGlyph8; break; + case 16: glyph = fbGlyph16; break; +#ifdef FB_24BIT + case 24: glyph = fbGlyph24; break; +#endif + case 32: glyph = fbGlyph32; break; + } + } +#endif + + x += pDrawable->x; + y += pDrawable->y; + + if (TERMINALFONT (pGC->font) +#ifndef FBNOPIXADDR + && !glyph +#endif + ) + { + opaque = TRUE; + } + else + { + int xBack, widthBack; + int yBack, heightBack; + + ppci = ppciInit; + n = nglyph; + widthBack = 0; + while (n--) + widthBack += (*ppci++)->metrics.characterWidth; + + xBack = x; + if (widthBack < 0) + { + xBack += widthBack; + widthBack = -widthBack; + } + yBack = y - FONTASCENT(pGC->font); + heightBack = FONTASCENT(pGC->font) + FONTDESCENT(pGC->font); + fbSolidBoxClipped (pDrawable, + fbGetCompositeClip(pGC), + xBack, + yBack, + xBack + widthBack, + yBack + heightBack, + fbAnd(GXcopy,pPriv->bg,pPriv->pm), + fbXor(GXcopy,pPriv->bg,pPriv->pm)); + opaque = FALSE; + } + + ppci = ppciInit; + while (nglyph--) + { + pci = *ppci++; + pglyph = FONTGLYPHBITS(pglyphBase, pci); + gWidth = GLYPHWIDTHPIXELS(pci); + gHeight = GLYPHHEIGHTPIXELS(pci); + if (gWidth && gHeight) + { + gx = x + pci->metrics.leftSideBearing; + gy = y - pci->metrics.ascent; +#ifndef FBNOPIXADDR + if (glyph && gWidth <= sizeof (FbStip) * 8 && + fbGlyphIn (fbGetCompositeClip(pGC), gx, gy, gWidth, gHeight)) + { + (*glyph) (dst + (gy + dstYoff) * dstStride, + dstStride, + dstBpp, + (FbStip *) pglyph, + pPriv->fg, + gx + dstXoff, + gHeight); + } + else +#endif + { + gStride = GLYPHWIDTHBYTESPADDED(pci) / sizeof (FbStip); + fbPutXYImage (pDrawable, + fbGetCompositeClip(pGC), + pPriv->fg, + pPriv->bg, + pPriv->pm, + GXcopy, + opaque, + + gx, + gy, + gWidth, gHeight, + + (FbStip *) pglyph, + gStride, + 0); + } + } + x += pci->metrics.characterWidth; + } +} diff --git a/nx-X11/programs/Xserver/fb/fbimage.c b/nx-X11/programs/Xserver/fb/fbimage.c new file mode 100644 index 000000000..9894faf02 --- /dev/null +++ b/nx-X11/programs/Xserver/fb/fbimage.c @@ -0,0 +1,364 @@ +/* + * Id: fbimage.c,v 1.1 1999/11/02 03:54:45 keithp Exp $ + * + * 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 <string.h> + +#include "fb.h" + +void +fbPutImage (DrawablePtr pDrawable, + GCPtr pGC, + int depth, + int x, + int y, + int w, + int h, + int leftPad, + int format, + char *pImage) +{ + FbGCPrivPtr pPriv = fbGetGCPrivate(pGC); + unsigned long i; + FbStride srcStride; + FbStip *src = (FbStip *) pImage; + + x += pDrawable->x; + y += pDrawable->y; + + switch (format) + { + case XYBitmap: + srcStride = BitmapBytePad(w + leftPad) / sizeof (FbStip); + fbPutXYImage (pDrawable, + fbGetCompositeClip(pGC), + pPriv->fg, + pPriv->bg, + pPriv->pm, + pGC->alu, + TRUE, + x, y, w, h, + src, + srcStride, + leftPad); + break; + case XYPixmap: + srcStride = BitmapBytePad(w + leftPad) / sizeof (FbStip); + for (i = 1 << (pDrawable->depth - 1); i; i >>= 1) + { + if (i & pGC->planemask) + { + fbPutXYImage (pDrawable, + fbGetCompositeClip(pGC), + FB_ALLONES, + 0, + fbReplicatePixel (i, pDrawable->bitsPerPixel), + pGC->alu, + TRUE, + x, y, w, h, + src, + srcStride, + leftPad); + src += srcStride * h; + } + } + break; + case ZPixmap: +#ifdef FB_24_32BIT + if (pDrawable->bitsPerPixel != BitsPerPixel(pDrawable->depth)) + { + srcStride = PixmapBytePad(w, pDrawable->depth); + fb24_32PutZImage (pDrawable, + fbGetCompositeClip(pGC), + pGC->alu, + (FbBits) pGC->planemask, + x, y, w, h, + (CARD8 *) pImage, + srcStride); + } + else +#endif + { + srcStride = PixmapBytePad(w, pDrawable->depth) / sizeof (FbStip); + fbPutZImage (pDrawable, + fbGetCompositeClip(pGC), + pGC->alu, + pPriv->pm, + x, y, w, h, + src, srcStride); + } + } +} + +void +fbPutZImage (DrawablePtr pDrawable, + RegionPtr pClip, + int alu, + FbBits pm, + int x, + int y, + int width, + int height, + FbStip *src, + FbStride srcStride) +{ + FbStip *dst; + FbStride dstStride; + int dstBpp; + int dstXoff, dstYoff; + int nbox; + BoxPtr pbox; + int x1, y1, x2, y2; + + fbGetStipDrawable (pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff); + + for (nbox = RegionNumRects (pClip), + pbox = RegionRects(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; + fbBltStip (src + (y1 - y) * srcStride, + srcStride, + (x1 - x) * dstBpp, + + dst + (y1 + dstYoff) * dstStride, + dstStride, + (x1 + dstXoff) * dstBpp, + + (x2 - x1) * dstBpp, + (y2 - y1), + + alu, + pm, + dstBpp); + } +} + +void +fbPutXYImage (DrawablePtr pDrawable, + RegionPtr pClip, + FbBits fg, + FbBits bg, + FbBits pm, + int alu, + Bool opaque, + + int x, + int y, + int width, + int height, + + FbStip *src, + FbStride srcStride, + int srcX) +{ + FbBits *dst; + FbStride dstStride; + int dstBpp; + int dstXoff, dstYoff; + int nbox; + BoxPtr pbox; + int x1, y1, x2, y2; + FbBits fgand = 0, fgxor = 0, bgand = 0, bgxor = 0; + + fbGetDrawable (pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff); + + if (dstBpp == 1) + { + if (opaque) + alu = FbOpaqueStipple1Rop(alu,fg,bg); + else + alu = FbStipple1Rop(alu,fg); + } + else + { + fgand = fbAnd(alu,fg,pm); + fgxor = fbXor(alu,fg,pm); + if (opaque) + { + bgand = fbAnd(alu,bg,pm); + bgxor = fbXor(alu,bg,pm); + } + else + { + bgand = fbAnd(GXnoop,(FbBits)0,FB_ALLONES); + bgxor = fbXor(GXnoop,(FbBits)0,FB_ALLONES); + } + } + + for (nbox = RegionNumRects (pClip), + pbox = RegionRects(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; + if (dstBpp == 1) + { + fbBltStip (src + (y1 - y) * srcStride, + srcStride, + (x1 - x) + srcX, + + (FbStip *) (dst + (y1 + dstYoff) * dstStride), + FbBitsStrideToStipStride(dstStride), + (x1 + dstXoff) * dstBpp, + + (x2 - x1) * dstBpp, + (y2 - y1), + + alu, + pm, + dstBpp); + } + else + { + fbBltOne (src + (y1 - y) * srcStride, + srcStride, + (x1 - x) + srcX, + + dst + (y1 + dstYoff) * dstStride, + dstStride, + (x1 + dstXoff) * dstBpp, + dstBpp, + + (x2 - x1) * dstBpp, + (y2 - y1), + + fgand, fgxor, bgand, bgxor); + } + } +} + +void +fbGetImage (DrawablePtr pDrawable, + int x, + int y, + int w, + int h, + unsigned int format, + unsigned long planeMask, + char *d) +{ + FbBits *src; + FbStride srcStride; + int srcBpp; + int srcXoff, srcYoff; + FbStip *dst; + FbStride dstStride; + + /* + * XFree86 DDX empties the root borderClip when the VT is + * switched away; this checks for that case + */ + if (!fbDrawableEnabled(pDrawable)) + return; + +#ifdef FB_24_32BIT + if (format == ZPixmap && + pDrawable->bitsPerPixel != BitsPerPixel (pDrawable->depth)) + { + fb24_32GetImage (pDrawable, x, y, w, h, format, planeMask, d); + return; + } +#endif + + fbGetDrawable (pDrawable, src, srcStride, srcBpp, srcXoff, srcYoff); + + x += pDrawable->x; + y += pDrawable->y; + + dst = (FbStip *) d; + if (format == ZPixmap || srcBpp == 1) + { + FbBits pm; + + pm = fbReplicatePixel (planeMask, srcBpp); + dstStride = PixmapBytePad(w, pDrawable->depth); + if (pm != FB_ALLONES) + memset (d, 0, dstStride * h); + dstStride /= sizeof (FbStip); + fbBltStip ((FbStip *) (src + (y + srcYoff) * srcStride), + FbBitsStrideToStipStride(srcStride), + (x + srcXoff) * srcBpp, + + dst, + dstStride, + 0, + + w * srcBpp, h, + + GXcopy, + pm, + srcBpp); + } + else + { + dstStride = BitmapBytePad(w) / sizeof (FbStip); + fbBltPlane (src + (y + srcYoff) * srcStride, + srcStride, + (x + srcXoff) * srcBpp, + srcBpp, + + dst, + dstStride, + 0, + + w * srcBpp, h, + + fbAndStip(GXcopy,FB_STIP_ALLONES,FB_STIP_ALLONES), + fbXorStip(GXcopy,FB_STIP_ALLONES,FB_STIP_ALLONES), + fbAndStip(GXcopy,0,FB_STIP_ALLONES), + fbXorStip(GXcopy,0,FB_STIP_ALLONES), + planeMask); + } +} diff --git a/nx-X11/programs/Xserver/fb/fbline.c b/nx-X11/programs/Xserver/fb/fbline.c new file mode 100644 index 000000000..fa80573e2 --- /dev/null +++ b/nx-X11/programs/Xserver/fb/fbline.c @@ -0,0 +1,175 @@ +/* + * 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 +fbZeroLine (DrawablePtr pDrawable, + GCPtr pGC, + int mode, + int npt, + DDXPointPtr ppt) +{ + int x1, y1, x2, y2; + int x, y; + int dashOffset; + + x = pDrawable->x; + y = pDrawable->y; + x1 = ppt->x; + y1 = ppt->y; + dashOffset = pGC->dashOffset; + while (--npt) + { + ++ppt; + x2 = ppt->x; + y2 = ppt->y; + if (mode == CoordModePrevious) + { + x2 += x1; + y2 += y1; + } + fbSegment (pDrawable, pGC, x1 + x, y1 + y, + x2 + x, y2 + y, + npt == 1 && pGC->capStyle != CapNotLast, + &dashOffset); + x1 = x2; + y1 = y2; + } +} + +void +fbZeroSegment (DrawablePtr pDrawable, + GCPtr pGC, + int nseg, + xSegment *pSegs) +{ + int dashOffset; + int x, y; + Bool drawLast = pGC->capStyle != CapNotLast; + + x = pDrawable->x; + y = pDrawable->y; + while (nseg--) + { + dashOffset = pGC->dashOffset; + fbSegment (pDrawable, pGC, + pSegs->x1 + x, pSegs->y1 + y, + pSegs->x2 + x, pSegs->y2 + y, + drawLast, + &dashOffset); + pSegs++; + } +} + +void +fbFixCoordModePrevious (int npt, + DDXPointPtr ppt) +{ + int x, y; + + x = ppt->x; + y = ppt->y; + npt--; + while (npt--) + { + ppt++; + x = (ppt->x += x); + y = (ppt->y += y); + } +} + +void +fbPolyLine (DrawablePtr pDrawable, + GCPtr pGC, + int mode, + int npt, + DDXPointPtr ppt) +{ + void (*line) (DrawablePtr, GCPtr, int mode, int npt, DDXPointPtr ppt); + + if (pGC->lineWidth == 0) + { + line = fbZeroLine; +#ifndef FBNOPIXADDR + if (pGC->fillStyle == FillSolid && + pGC->lineStyle == LineSolid && + RegionNumRects (fbGetCompositeClip(pGC)) == 1) + { + switch (pDrawable->bitsPerPixel) { + case 8: line = fbPolyline8; break; + case 16: line = fbPolyline16; break; +#ifdef FB_24BIT + case 24: line = fbPolyline24; break; +#endif + case 32: line = fbPolyline32; break; + } + } +#endif + } + else + { + if (pGC->lineStyle != LineSolid) + line = miWideDash; + else + line = miWideLine; + } + (*line) (pDrawable, pGC, mode, npt, ppt); +} + +void +fbPolySegment (DrawablePtr pDrawable, + GCPtr pGC, + int nseg, + xSegment *pseg) +{ + void (*seg) (DrawablePtr pDrawable, GCPtr pGC, int nseg, xSegment *pseg); + + if (pGC->lineWidth == 0) + { + seg = fbZeroSegment; +#ifndef FBNOPIXADDR + if (pGC->fillStyle == FillSolid && + pGC->lineStyle == LineSolid && + RegionNumRects (fbGetCompositeClip(pGC)) == 1) + { + switch (pDrawable->bitsPerPixel) { + case 8: seg = fbPolySegment8; break; + case 16: seg = fbPolySegment16; break; +#ifdef FB_24BIT + case 24: seg = fbPolySegment24; break; +#endif + case 32: seg = fbPolySegment32; break; + } + } +#endif + } + else + { + seg = miPolySegment; + } + (*seg) (pDrawable, pGC, nseg, pseg); +} diff --git a/nx-X11/programs/Xserver/fb/fboverlay.c b/nx-X11/programs/Xserver/fb/fboverlay.c new file mode 100644 index 000000000..6e0bbf252 --- /dev/null +++ b/nx-X11/programs/Xserver/fb/fboverlay.c @@ -0,0 +1,459 @@ +/* + * Copyright © 2000 SuSE, Inc. + * + * 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 SuSE not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. SuSE makes no representations about the + * suitability of this software for any purpose. It is provided "as is" + * without express or implied warranty. + * + * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE + * 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. + * + * Author: Keith Packard, SuSE, Inc. + */ + +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#endif + +#include <stdlib.h> + +#include "fb.h" +#include "fboverlay.h" + +#ifdef MITSHM +#include "shmint.h" +#endif + +int fbOverlayGeneration; +int fbOverlayScreenPrivateIndex = -1; + +int fbOverlayGetScreenPrivateIndex(void) +{ + return fbOverlayScreenPrivateIndex; +} + +/* + * Replace this if you want something supporting + * multiple overlays with the same depth + */ +Bool +fbOverlayCreateWindow(WindowPtr pWin) +{ + FbOverlayScrPrivPtr pScrPriv = fbOverlayGetScrPriv(pWin->drawable.pScreen); + int i; + PixmapPtr pPixmap; + + if (pWin->drawable.class != InputOutput) + return TRUE; + +#ifdef FB_SCREEN_PRIVATE + if (pWin->drawable.bitsPerPixel == 32) + pWin->drawable.bitsPerPixel = fbGetScreenPrivate(pWin->drawable.pScreen)->win32bpp; +#endif + + for (i = 0; i < pScrPriv->nlayers; i++) + { + pPixmap = pScrPriv->layer[i].u.run.pixmap; + if (pWin->drawable.depth == pPixmap->drawable.depth) + { + pWin->devPrivates[fbWinPrivateIndex].ptr = (void *) pPixmap; + /* + * Make sure layer keys are written correctly by + * having non-root layers set to full while the + * root layer is set to empty. This will cause + * all of the layers to get painted when the root + * is mapped + */ + if (!pWin->parent) + { + RegionEmpty( + &pScrPriv->layer[i].u.run.region); + } + return TRUE; + } + } + return FALSE; +} + +Bool +fbOverlayCloseScreen (ScreenPtr pScreen) +{ + FbOverlayScrPrivPtr pScrPriv = fbOverlayGetScrPriv(pScreen); + int i; + + for (i = 0; i < pScrPriv->nlayers; i++) + { + (*pScreen->DestroyPixmap)(pScrPriv->layer[i].u.run.pixmap); + RegionUninit(&pScrPriv->layer[i].u.run.region); + } + return TRUE; +} + +/* + * Return layer containing this window + */ +int +fbOverlayWindowLayer(WindowPtr pWin) +{ + FbOverlayScrPrivPtr pScrPriv = fbOverlayGetScrPriv(pWin->drawable.pScreen); + int i; + + for (i = 0; i < pScrPriv->nlayers; i++) + if (pWin->devPrivates[fbWinPrivateIndex].ptr == + (void *) pScrPriv->layer[i].u.run.pixmap) + return i; + return 0; +} + +Bool +fbOverlayCreateScreenResources(ScreenPtr pScreen) +{ + int i; + FbOverlayScrPrivPtr pScrPriv = fbOverlayGetScrPriv(pScreen); + PixmapPtr pPixmap; + void * pbits; + int width; + int depth; + BoxRec box; + + if (!miCreateScreenResources(pScreen)) + return FALSE; + + box.x1 = 0; + box.y1 = 0; + box.x2 = pScreen->width; + box.y2 = pScreen->height; + for (i = 0; i < pScrPriv->nlayers; i++) + { + pbits = pScrPriv->layer[i].u.init.pbits; + width = pScrPriv->layer[i].u.init.width; + depth = pScrPriv->layer[i].u.init.depth; + pPixmap = (*pScreen->CreatePixmap)(pScreen, 0, 0, depth, 0); + if (!pPixmap) + return FALSE; + if (!(*pScreen->ModifyPixmapHeader)(pPixmap, pScreen->width, + pScreen->height, depth, + BitsPerPixel(depth), + PixmapBytePad(width, depth), + pbits)) + return FALSE; + pScrPriv->layer[i].u.run.pixmap = pPixmap; + RegionInit(&pScrPriv->layer[i].u.run.region, &box, 0); + } + pScreen->devPrivate = pScrPriv->layer[0].u.run.pixmap; + return TRUE; +} + +void +fbOverlayPaintKey (DrawablePtr pDrawable, + RegionPtr pRegion, + CARD32 pixel, + int layer) +{ + fbFillRegionSolid (pDrawable, pRegion, 0, + fbReplicatePixel (pixel, pDrawable->bitsPerPixel)); +} + +/* + * Track visible region for each layer + */ +void +fbOverlayUpdateLayerRegion (ScreenPtr pScreen, + int layer, + RegionPtr prgn) +{ + FbOverlayScrPrivPtr pScrPriv = fbOverlayGetScrPriv(pScreen); + int i; + RegionRec rgnNew; + + if (!prgn || !RegionNotEmpty(prgn)) + return; + for (i = 0; i < pScrPriv->nlayers; i++) + { + if (i == layer) + { + /* add new piece to this fb */ + RegionUnion( + &pScrPriv->layer[i].u.run.region, + &pScrPriv->layer[i].u.run.region, + prgn); + } + else if (RegionNotEmpty( + &pScrPriv->layer[i].u.run.region)) + { + /* paint new piece with chroma key */ + RegionNull(&rgnNew); + RegionIntersect( + &rgnNew, + prgn, + &pScrPriv->layer[i].u.run.region); + (*pScrPriv->PaintKey) (&pScrPriv->layer[i].u.run.pixmap->drawable, + &rgnNew, + pScrPriv->layer[i].key, + i); + RegionUninit(&rgnNew); + /* remove piece from other fbs */ + RegionSubtract( + &pScrPriv->layer[i].u.run.region, + &pScrPriv->layer[i].u.run.region, + prgn); + } + } +} + +/* + * Copy only areas in each layer containing real bits + */ +void +fbOverlayCopyWindow(WindowPtr pWin, + DDXPointRec ptOldOrg, + RegionPtr prgnSrc) +{ + ScreenPtr pScreen = pWin->drawable.pScreen; + FbOverlayScrPrivPtr pScrPriv = fbOverlayGetScrPriv(pWin->drawable.pScreen); + RegionRec rgnDst; + int dx, dy; + int i; + RegionRec layerRgn[FB_OVERLAY_MAX]; + PixmapPtr pPixmap; + + dx = ptOldOrg.x - pWin->drawable.x; + dy = ptOldOrg.y - pWin->drawable.y; + + /* + * Clip to existing bits + */ + RegionTranslate(prgnSrc, -dx, -dy); + RegionNull(&rgnDst); + RegionIntersect(&rgnDst, &pWin->borderClip, prgnSrc); + RegionTranslate(&rgnDst, dx, dy); + /* + * Compute the portion of each fb affected by this copy + */ + for (i = 0; i < pScrPriv->nlayers; i++) + { + RegionNull(&layerRgn[i]); + RegionIntersect(&layerRgn[i], &rgnDst, + &pScrPriv->layer[i].u.run.region); + if (RegionNotEmpty(&layerRgn[i])) + { + RegionTranslate(&layerRgn[i], -dx, -dy); + pPixmap = pScrPriv->layer[i].u.run.pixmap; + fbCopyRegion (&pPixmap->drawable, &pPixmap->drawable, + 0, + &layerRgn[i], dx, dy, pScrPriv->CopyWindow, 0, + (void *)(long) i); + } + } + /* + * Update regions + */ + for (i = 0; i < pScrPriv->nlayers; i++) + { + if (RegionNotEmpty(&layerRgn[i])) + fbOverlayUpdateLayerRegion (pScreen, i, &layerRgn[i]); + + RegionUninit(&layerRgn[i]); + } + RegionUninit(&rgnDst); +} + +void +fbOverlayWindowExposures (WindowPtr pWin, + RegionPtr prgn, + RegionPtr other_exposed) +{ + fbOverlayUpdateLayerRegion (pWin->drawable.pScreen, + fbOverlayWindowLayer (pWin), + prgn); + miWindowExposures(pWin, prgn, other_exposed); +} + +void +fbOverlayPaintWindow(WindowPtr pWin, RegionPtr pRegion, int what) +{ + if (what == PW_BORDER) + fbOverlayUpdateLayerRegion (pWin->drawable.pScreen, + fbOverlayWindowLayer (pWin), + pRegion); + fbPaintWindow (pWin, pRegion, what); +} + +Bool +fbOverlaySetupScreen(ScreenPtr pScreen, + void * pbits1, + void * pbits2, + int xsize, + int ysize, + int dpix, + int dpiy, + int width1, + int width2, + int bpp1, + int bpp2) +{ + return fbSetupScreen (pScreen, + pbits1, + xsize, + ysize, + dpix, + dpiy, + width1, + bpp1); +} + +static Bool +fb24_32OverlayCreateScreenResources(ScreenPtr pScreen) +{ + FbOverlayScrPrivPtr pScrPriv = fbOverlayGetScrPriv(pScreen); + int pitch; + Bool retval; + int i; + + if((retval = fbOverlayCreateScreenResources(pScreen))) { + for (i = 0; i < pScrPriv->nlayers; i++) + { + /* fix the screen pixmap */ + PixmapPtr pPix = (PixmapPtr) pScrPriv->layer[i].u.run.pixmap; + if (pPix->drawable.bitsPerPixel == 32) { + pPix->drawable.bitsPerPixel = 24; + pitch = BitmapBytePad(pPix->drawable.width * 24); + pPix->devKind = pitch; + } + } + } + + return retval; +} + +Bool +fbOverlayFinishScreenInit(ScreenPtr pScreen, + void * pbits1, + void * pbits2, + int xsize, + int ysize, + int dpix, + int dpiy, + int width1, + int width2, + int bpp1, + int bpp2, + int depth1, + int depth2) +{ + VisualPtr visuals; + DepthPtr depths; + int nvisuals; + int ndepths; + int bpp = 0, imagebpp = 32; + VisualID defaultVisual; + FbOverlayScrPrivPtr pScrPriv; + + if (fbOverlayGeneration != serverGeneration) + { + fbOverlayScreenPrivateIndex = AllocateScreenPrivateIndex (); + fbOverlayGeneration = serverGeneration; + } + + pScrPriv = malloc (sizeof (FbOverlayScrPrivRec)); + if (!pScrPriv) + return FALSE; + +#ifdef FB_24_32BIT + if (bpp1 == 32 || bpp2 == 32) + bpp = 32; + else if (bpp1 == 24 || bpp2 == 24) + bpp = 24; + + if (bpp == 24) + { + int f; + + imagebpp = 32; + /* + * Check to see if we're advertising a 24bpp image format, + * in which case windows will use it in preference to a 32 bit + * format. + */ + for (f = 0; f < screenInfo.numPixmapFormats; f++) + { + if (screenInfo.formats[f].bitsPerPixel == 24) + { + imagebpp = 24; + break; + } + } + } +#endif +#ifdef FB_SCREEN_PRIVATE + if (imagebpp == 32) + { + fbGetScreenPrivate(pScreen)->win32bpp = bpp; + fbGetScreenPrivate(pScreen)->pix32bpp = bpp; + } + else + { + fbGetScreenPrivate(pScreen)->win32bpp = 32; + fbGetScreenPrivate(pScreen)->pix32bpp = 32; + } +#endif + + if (!fbInitVisuals (&visuals, &depths, &nvisuals, &ndepths, &depth1, + &defaultVisual, ((unsigned long)1<<(bpp1-1)) | + ((unsigned long)1<<(bpp2-1)), 8)) + return FALSE; + if (! miScreenInit(pScreen, 0, xsize, ysize, dpix, dpiy, 0, + depth1, ndepths, depths, + defaultVisual, nvisuals, visuals +#ifdef FB_OLD_MISCREENINIT + , (miBSFuncPtr) 0 +#endif + )) + return FALSE; + /* MI thinks there's no frame buffer */ +#ifdef MITSHM + ShmRegisterFbFuncs(pScreen); +#endif + pScreen->minInstalledCmaps = 1; + pScreen->maxInstalledCmaps = 2; + + pScrPriv->nlayers = 2; + pScrPriv->PaintKey = fbOverlayPaintKey; + pScrPriv->CopyWindow = fbCopyWindowProc; + pScrPriv->layer[0].u.init.pbits = pbits1; + pScrPriv->layer[0].u.init.width = width1; + pScrPriv->layer[0].u.init.depth = depth1; + + pScrPriv->layer[1].u.init.pbits = pbits2; + pScrPriv->layer[1].u.init.width = width2; + pScrPriv->layer[1].u.init.depth = depth2; + + pScreen->devPrivates[fbOverlayScreenPrivateIndex].ptr = (void *) pScrPriv; + + /* overwrite miCloseScreen with our own */ + pScreen->CloseScreen = fbOverlayCloseScreen; + pScreen->CreateScreenResources = fbOverlayCreateScreenResources; + pScreen->CreateWindow = fbOverlayCreateWindow; + pScreen->WindowExposures = fbOverlayWindowExposures; + pScreen->CopyWindow = fbOverlayCopyWindow; + pScreen->PaintWindowBorder = fbOverlayPaintWindow; +#ifdef FB_24_32BIT + if (bpp == 24 && imagebpp == 32) + { + pScreen->ModifyPixmapHeader = fb24_32ModifyPixmapHeader; + pScreen->CreateScreenResources = fb24_32OverlayCreateScreenResources; + } +#endif + + return TRUE; +} diff --git a/nx-X11/programs/Xserver/fb/fboverlay.h b/nx-X11/programs/Xserver/fb/fboverlay.h new file mode 100644 index 000000000..2bb8b176a --- /dev/null +++ b/nx-X11/programs/Xserver/fb/fboverlay.h @@ -0,0 +1,127 @@ +/* + * Copyright © 2000 SuSE, Inc. + * + * 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 SuSE not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. SuSE makes no representations about the + * suitability of this software for any purpose. It is provided "as is" + * without express or implied warranty. + * + * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE + * 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. + * + * Author: Keith Packard, SuSE, Inc. + */ + +#ifndef _FBOVERLAY_H_ +#define _FBOVERLAY_H_ + +extern int fbOverlayGeneration; +extern int fbOverlayScreenPrivateIndex; /* XXX should be static */ +extern int fbOverlayGetScreenPrivateIndex(void); + +#ifndef FB_OVERLAY_MAX +#define FB_OVERLAY_MAX 2 +#endif + +typedef void (*fbOverlayPaintKeyProc) (DrawablePtr, RegionPtr, CARD32, int); + +typedef struct _fbOverlayLayer { + union { + struct { + void * pbits; + int width; + int depth; + } init; + struct { + PixmapPtr pixmap; + RegionRec region; + } run; + } u; + CARD32 key; /* special pixel value */ +} FbOverlayLayer; + +typedef struct _fbOverlayScrPriv { + int nlayers; + fbOverlayPaintKeyProc PaintKey; + fbCopyProc CopyWindow; + FbOverlayLayer layer[FB_OVERLAY_MAX]; +} FbOverlayScrPrivRec, *FbOverlayScrPrivPtr; + +#define fbOverlayGetScrPriv(s) \ + ((fbOverlayGetScreenPrivateIndex() != -1) ? \ + (s)->devPrivates[fbOverlayGetScreenPrivateIndex()].ptr : NULL) +Bool +fbOverlayCreateWindow(WindowPtr pWin); + +Bool +fbOverlayCloseScreen (ScreenPtr pScreen); + +int +fbOverlayWindowLayer(WindowPtr pWin); + +Bool +fbOverlayCreateScreenResources(ScreenPtr pScreen); + +void +fbOverlayPaintKey (DrawablePtr pDrawable, + RegionPtr pRegion, + CARD32 pixel, + int layer); +void +fbOverlayUpdateLayerRegion (ScreenPtr pScreen, + int layer, + RegionPtr prgn); + + +void +fbOverlayCopyWindow(WindowPtr pWin, + DDXPointRec ptOldOrg, + RegionPtr prgnSrc); + +void +fbOverlayWindowExposures (WindowPtr pWin, + RegionPtr prgn, + RegionPtr other_exposed); + +void +fbOverlayPaintWindow(WindowPtr pWin, RegionPtr pRegion, int what); + + +Bool +fbOverlaySetupScreen(ScreenPtr pScreen, + void * pbits1, + void * pbits2, + int xsize, + int ysize, + int dpix, + int dpiy, + int width1, + int width2, + int bpp1, + int bpp2); + +Bool +fbOverlayFinishScreenInit(ScreenPtr pScreen, + void * pbits1, + void * pbits2, + int xsize, + int ysize, + int dpix, + int dpiy, + int width1, + int width2, + int bpp1, + int bpp2, + int depth1, + int depth2); + +#endif /* _FBOVERLAY_H_ */ diff --git a/nx-X11/programs/Xserver/fb/fbpict.c b/nx-X11/programs/Xserver/fb/fbpict.c new file mode 100644 index 000000000..214ed5a4c --- /dev/null +++ b/nx-X11/programs/Xserver/fb/fbpict.c @@ -0,0 +1,1225 @@ +/* + * Copyright © 2000 SuSE, Inc. + * + * 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 SuSE not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. SuSE makes no representations about the + * suitability of this software for any purpose. It is provided "as is" + * without express or implied warranty. + * + * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE + * 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. + * + * Author: Keith Packard, SuSE, Inc. + */ + +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#endif + +#include <string.h> + +#include "fb.h" + +#ifdef RENDER + +#include "picturestr.h" +#include "mipict.h" +#include "fbpict.h" + +typedef void (*CompositeFunc) (CARD8 op, + PicturePtr pSrc, + PicturePtr pMask, + PicturePtr pDst, + INT16 xSrc, + INT16 ySrc, + INT16 xMask, + INT16 yMask, + INT16 xDst, + INT16 yDst, + CARD16 width, + CARD16 height); + +CARD32 +fbOver (CARD32 x, CARD32 y) +{ + CARD16 a = ~x >> 24; + CARD16 t; + CARD32 m,n,o,p; + + m = FbOverU(x,y,0,a,t); + n = FbOverU(x,y,8,a,t); + o = FbOverU(x,y,16,a,t); + p = FbOverU(x,y,24,a,t); + return m|n|o|p; +} + +CARD32 +fbOver24 (CARD32 x, CARD32 y) +{ + CARD16 a = ~x >> 24; + CARD16 t; + CARD32 m,n,o; + + m = FbOverU(x,y,0,a,t); + n = FbOverU(x,y,8,a,t); + o = FbOverU(x,y,16,a,t); + return m|n|o; +} + +CARD32 +fbIn (CARD32 x, CARD8 y) +{ + CARD16 a = y; + CARD16 t; + CARD32 m,n,o,p; + + m = FbInU(x,0,a,t); + n = FbInU(x,8,a,t); + o = FbInU(x,16,a,t); + p = FbInU(x,24,a,t); + return m|n|o|p; +} + +/* + * Naming convention: + * + * opSRCxMASKxDST + */ + +void +fbCompositeSolidMask_nx8x8888 (CARD8 op, + PicturePtr pSrc, + PicturePtr pMask, + PicturePtr pDst, + INT16 xSrc, + INT16 ySrc, + INT16 xMask, + INT16 yMask, + INT16 xDst, + INT16 yDst, + CARD16 width, + CARD16 height) +{ + CARD32 src, srca; + CARD32 *dstLine, *dst, d, dstMask; + CARD8 *maskLine, *mask, m; + FbStride dstStride, maskStride; + CARD16 w; + + fbComposeGetSolid(pSrc, src, pDst->format); + + dstMask = FbFullMask (pDst->pDrawable->depth); + srca = src >> 24; + if (src == 0) + return; + + fbComposeGetStart (pDst, xDst, yDst, CARD32, dstStride, dstLine, 1); + fbComposeGetStart (pMask, xMask, yMask, CARD8, maskStride, maskLine, 1); + + while (height--) + { + dst = dstLine; + dstLine += dstStride; + mask = maskLine; + maskLine += maskStride; + w = width; + + while (w--) + { + m = *mask++; + if (m == 0xff) + { + if (srca == 0xff) + *dst = src & dstMask; + else + *dst = fbOver (src, *dst) & dstMask; + } + else if (m) + { + d = fbIn (src, m); + *dst = fbOver (d, *dst) & dstMask; + } + dst++; + } + } +} + +void +fbCompositeSolidMask_nx8888x8888C (CARD8 op, + PicturePtr pSrc, + PicturePtr pMask, + PicturePtr pDst, + INT16 xSrc, + INT16 ySrc, + INT16 xMask, + INT16 yMask, + INT16 xDst, + INT16 yDst, + CARD16 width, + CARD16 height) +{ + CARD32 src, srca; + CARD32 *dstLine, *dst, d, dstMask; + CARD32 *maskLine, *mask, ma; + FbStride dstStride, maskStride; + CARD16 w; + CARD32 m, n, o, p; + + fbComposeGetSolid(pSrc, src, pDst->format); + + dstMask = FbFullMask (pDst->pDrawable->depth); + srca = src >> 24; + if (src == 0) + return; + + fbComposeGetStart (pDst, xDst, yDst, CARD32, dstStride, dstLine, 1); + fbComposeGetStart (pMask, xMask, yMask, CARD32, maskStride, maskLine, 1); + + while (height--) + { + dst = dstLine; + dstLine += dstStride; + mask = maskLine; + maskLine += maskStride; + w = width; + + while (w--) + { + ma = *mask++; + if (ma == 0xffffffff) + { + if (srca == 0xff) + *dst = src & dstMask; + else + *dst = fbOver (src, *dst) & dstMask; + } + else if (ma) + { + d = *dst; +#define FbInOverC(src,srca,msk,dst,i,result) { \ + CARD16 __a = FbGet8(msk,i); \ + CARD32 __t, __ta; \ + CARD32 __i; \ + __t = FbIntMult (FbGet8(src,i), __a,__i); \ + __ta = (CARD8) ~FbIntMult (srca, __a,__i); \ + __t = __t + FbIntMult(FbGet8(dst,i),__ta,__i); \ + __t = (CARD32) (CARD8) (__t | (-(__t >> 8))); \ + result = __t << (i); \ +} + FbInOverC (src, srca, ma, d, 0, m); + FbInOverC (src, srca, ma, d, 8, n); + FbInOverC (src, srca, ma, d, 16, o); + FbInOverC (src, srca, ma, d, 24, p); + *dst = m|n|o|p; + } + dst++; + } + } +} + +void +fbCompositeSolidMask_nx8x0888 (CARD8 op, + PicturePtr pSrc, + PicturePtr pMask, + PicturePtr pDst, + INT16 xSrc, + INT16 ySrc, + INT16 xMask, + INT16 yMask, + INT16 xDst, + INT16 yDst, + CARD16 width, + CARD16 height) +{ + CARD32 src, srca; + CARD8 *dstLine, *dst; + CARD32 d; + CARD8 *maskLine, *mask, m; + FbStride dstStride, maskStride; + CARD16 w; + + fbComposeGetSolid(pSrc, src, pDst->format); + + srca = src >> 24; + if (src == 0) + return; + + fbComposeGetStart (pDst, xDst, yDst, CARD8, dstStride, dstLine, 3); + fbComposeGetStart (pMask, xMask, yMask, CARD8, maskStride, maskLine, 1); + + while (height--) + { + dst = dstLine; + dstLine += dstStride; + mask = maskLine; + maskLine += maskStride; + w = width; + + while (w--) + { + m = *mask++; + if (m == 0xff) + { + if (srca == 0xff) + d = src; + else + { + d = Fetch24(dst); + d = fbOver24 (src, d); + } + Store24(dst,d); + } + else if (m) + { + d = fbOver24 (fbIn(src,m), Fetch24(dst)); + Store24(dst,d); + } + dst += 3; + } + } +} + +void +fbCompositeSolidMask_nx8x0565 (CARD8 op, + PicturePtr pSrc, + PicturePtr pMask, + PicturePtr pDst, + INT16 xSrc, + INT16 ySrc, + INT16 xMask, + INT16 yMask, + INT16 xDst, + INT16 yDst, + CARD16 width, + CARD16 height) +{ + CARD32 src, srca; + CARD16 *dstLine, *dst; + CARD32 d; + CARD8 *maskLine, *mask, m; + FbStride dstStride, maskStride; + CARD16 w; + + fbComposeGetSolid(pSrc, src, pDst->format); + + srca = src >> 24; + if (src == 0) + return; + + fbComposeGetStart (pDst, xDst, yDst, CARD16, dstStride, dstLine, 1); + fbComposeGetStart (pMask, xMask, yMask, CARD8, maskStride, maskLine, 1); + + while (height--) + { + dst = dstLine; + dstLine += dstStride; + mask = maskLine; + maskLine += maskStride; + w = width; + + while (w--) + { + m = *mask++; + if (m == 0xff) + { + if (srca == 0xff) + d = src; + else + { + d = *dst; + d = fbOver24 (src, cvt0565to8888(d)); + } + *dst = cvt8888to0565(d); + } + else if (m) + { + d = *dst; + d = fbOver24 (fbIn(src,m), cvt0565to8888(d)); + *dst = cvt8888to0565(d); + } + dst++; + } + } +} + +void +fbCompositeSolidMask_nx8888x0565C (CARD8 op, + PicturePtr pSrc, + PicturePtr pMask, + PicturePtr pDst, + INT16 xSrc, + INT16 ySrc, + INT16 xMask, + INT16 yMask, + INT16 xDst, + INT16 yDst, + CARD16 width, + CARD16 height) +{ + CARD32 src, srca; + CARD16 src16; + CARD16 *dstLine, *dst; + CARD32 d; + CARD32 *maskLine, *mask, ma; + FbStride dstStride, maskStride; + CARD16 w; + CARD32 m, n, o; + + fbComposeGetSolid(pSrc, src, pDst->format); + + srca = src >> 24; + if (src == 0) + return; + + src16 = cvt8888to0565(src); + + fbComposeGetStart (pDst, xDst, yDst, CARD16, dstStride, dstLine, 1); + fbComposeGetStart (pMask, xMask, yMask, CARD32, maskStride, maskLine, 1); + + while (height--) + { + dst = dstLine; + dstLine += dstStride; + mask = maskLine; + maskLine += maskStride; + w = width; + + while (w--) + { + ma = *mask++; + if (ma == 0xffffffff) + { + if (srca == 0xff) + { + *dst = src16; + } + else + { + d = *dst; + d = fbOver24 (src, cvt0565to8888(d)); + *dst = cvt8888to0565(d); + } + } + else if (ma) + { + d = *dst; + d = cvt0565to8888(d); + FbInOverC (src, srca, ma, d, 0, m); + FbInOverC (src, srca, ma, d, 8, n); + FbInOverC (src, srca, ma, d, 16, o); + d = m|n|o; + *dst = cvt8888to0565(d); + } + dst++; + } + } +} + +void +fbCompositeSrc_8888x8888 (CARD8 op, + PicturePtr pSrc, + PicturePtr pMask, + PicturePtr pDst, + INT16 xSrc, + INT16 ySrc, + INT16 xMask, + INT16 yMask, + INT16 xDst, + INT16 yDst, + CARD16 width, + CARD16 height) +{ + CARD32 *dstLine, *dst, dstMask; + CARD32 *srcLine, *src, s; + FbStride dstStride, srcStride; + CARD8 a; + CARD16 w; + + fbComposeGetStart (pDst, xDst, yDst, CARD32, dstStride, dstLine, 1); + fbComposeGetStart (pSrc, xSrc, ySrc, CARD32, srcStride, srcLine, 1); + + dstMask = FbFullMask (pDst->pDrawable->depth); + + while (height--) + { + dst = dstLine; + dstLine += dstStride; + src = srcLine; + srcLine += srcStride; + w = width; + + while (w--) + { + s = *src++; + a = s >> 24; + if (a == 0xff) + *dst = s & dstMask; + else if (a) + *dst = fbOver (s, *dst) & dstMask; + dst++; + } + } +} + +void +fbCompositeSrc_8888x0888 (CARD8 op, + PicturePtr pSrc, + PicturePtr pMask, + PicturePtr pDst, + INT16 xSrc, + INT16 ySrc, + INT16 xMask, + INT16 yMask, + INT16 xDst, + INT16 yDst, + CARD16 width, + CARD16 height) +{ + CARD8 *dstLine, *dst; + CARD32 d; + CARD32 *srcLine, *src, s; + CARD8 a; + FbStride dstStride, srcStride; + CARD16 w; + + fbComposeGetStart (pDst, xDst, yDst, CARD8, dstStride, dstLine, 3); + fbComposeGetStart (pSrc, xSrc, ySrc, CARD32, srcStride, srcLine, 1); + + while (height--) + { + dst = dstLine; + dstLine += dstStride; + src = srcLine; + srcLine += srcStride; + w = width; + + while (w--) + { + s = *src++; + a = s >> 24; + if (a) + { + if (a == 0xff) + d = s; + else + d = fbOver24 (s, Fetch24(dst)); + Store24(dst,d); + } + dst += 3; + } + } +} + +void +fbCompositeSrc_8888x0565 (CARD8 op, + PicturePtr pSrc, + PicturePtr pMask, + PicturePtr pDst, + INT16 xSrc, + INT16 ySrc, + INT16 xMask, + INT16 yMask, + INT16 xDst, + INT16 yDst, + CARD16 width, + CARD16 height) +{ + CARD16 *dstLine, *dst; + CARD32 d; + CARD32 *srcLine, *src, s; + CARD8 a; + FbStride dstStride, srcStride; + CARD16 w; + + fbComposeGetStart (pSrc, xSrc, ySrc, CARD32, srcStride, srcLine, 1); + fbComposeGetStart (pDst, xDst, yDst, CARD16, dstStride, dstLine, 1); + + while (height--) + { + dst = dstLine; + dstLine += dstStride; + src = srcLine; + srcLine += srcStride; + w = width; + + while (w--) + { + s = *src++; + a = s >> 24; + if (a) + { + if (a == 0xff) + d = s; + else + { + d = *dst; + d = fbOver24 (s, cvt0565to8888(d)); + } + *dst = cvt8888to0565(d); + } + dst++; + } + } +} + +void +fbCompositeSrc_0565x0565 (CARD8 op, + PicturePtr pSrc, + PicturePtr pMask, + PicturePtr pDst, + INT16 xSrc, + INT16 ySrc, + INT16 xMask, + INT16 yMask, + INT16 xDst, + INT16 yDst, + CARD16 width, + CARD16 height) +{ + CARD16 *dstLine, *dst; + CARD16 *srcLine, *src; + FbStride dstStride, srcStride; + CARD16 w; + + fbComposeGetStart (pSrc, xSrc, ySrc, CARD16, srcStride, srcLine, 1); + + fbComposeGetStart (pDst, xDst, yDst, CARD16, dstStride, dstLine, 1); + + while (height--) + { + dst = dstLine; + dstLine += dstStride; + src = srcLine; + srcLine += srcStride; + w = width; + + while (w--) + *dst++ = *src++; + } +} + +void +fbCompositeSrcAdd_8000x8000 (CARD8 op, + PicturePtr pSrc, + PicturePtr pMask, + PicturePtr pDst, + INT16 xSrc, + INT16 ySrc, + INT16 xMask, + INT16 yMask, + INT16 xDst, + INT16 yDst, + CARD16 width, + CARD16 height) +{ + CARD8 *dstLine, *dst; + CARD8 *srcLine, *src; + FbStride dstStride, srcStride; + CARD16 w; + CARD8 s, d; + CARD16 t; + + fbComposeGetStart (pSrc, xSrc, ySrc, CARD8, srcStride, srcLine, 1); + fbComposeGetStart (pDst, xDst, yDst, CARD8, dstStride, dstLine, 1); + + while (height--) + { + dst = dstLine; + dstLine += dstStride; + src = srcLine; + srcLine += srcStride; + w = width; + + while (w--) + { + s = *src++; + if (s) + { + if (s != 0xff) + { + d = *dst; + t = d + s; + s = t | (0 - (t >> 8)); + } + *dst = s; + } + dst++; + } + } +} + +void +fbCompositeSrcAdd_8888x8888 (CARD8 op, + PicturePtr pSrc, + PicturePtr pMask, + PicturePtr pDst, + INT16 xSrc, + INT16 ySrc, + INT16 xMask, + INT16 yMask, + INT16 xDst, + INT16 yDst, + CARD16 width, + CARD16 height) +{ + CARD32 *dstLine, *dst; + CARD32 *srcLine, *src; + FbStride dstStride, srcStride; + CARD16 w; + CARD32 s, d; + CARD16 t; + CARD32 m,n,o,p; + + fbComposeGetStart (pSrc, xSrc, ySrc, CARD32, srcStride, srcLine, 1); + fbComposeGetStart (pDst, xDst, yDst, CARD32, dstStride, dstLine, 1); + + while (height--) + { + dst = dstLine; + dstLine += dstStride; + src = srcLine; + srcLine += srcStride; + w = width; + + while (w--) + { + s = *src++; + if (s) + { + if (s != 0xffffffff) + { + d = *dst; + if (d) + { + m = FbAdd(s,d,0,t); + n = FbAdd(s,d,8,t); + o = FbAdd(s,d,16,t); + p = FbAdd(s,d,24,t); + s = m|n|o|p; + } + } + *dst = s; + } + dst++; + } + } +} + +void +fbCompositeSrcAdd_1000x1000 (CARD8 op, + PicturePtr pSrc, + PicturePtr pMask, + PicturePtr pDst, + INT16 xSrc, + INT16 ySrc, + INT16 xMask, + INT16 yMask, + INT16 xDst, + INT16 yDst, + CARD16 width, + CARD16 height) +{ + FbBits *dstBits, *srcBits; + FbStride dstStride, srcStride; + int dstBpp, srcBpp; + int dstXoff, dstYoff; + int srcXoff, srcYoff; + + fbGetDrawable(pSrc->pDrawable, srcBits, srcStride, srcBpp, srcXoff, srcYoff); + + fbGetDrawable(pDst->pDrawable, dstBits, dstStride, dstBpp, dstXoff, dstYoff); + + fbBlt (srcBits + srcStride * (ySrc + srcYoff), + srcStride, + xSrc + srcXoff, + + dstBits + dstStride * (yDst + dstYoff), + dstStride, + xDst + dstXoff, + + width, + height, + + GXor, + FB_ALLONES, + srcBpp, + + FALSE, + FALSE); +} + +void +fbCompositeSolidMask_nx1xn (CARD8 op, + PicturePtr pSrc, + PicturePtr pMask, + PicturePtr pDst, + INT16 xSrc, + INT16 ySrc, + INT16 xMask, + INT16 yMask, + INT16 xDst, + INT16 yDst, + CARD16 width, + CARD16 height) +{ + FbBits *dstBits; + FbStip *maskBits; + FbStride dstStride, maskStride; + int dstBpp, maskBpp; + int dstXoff, dstYoff; + int maskXoff, maskYoff; + FbBits src; + + fbComposeGetSolid(pSrc, src, pDst->format); + + if ((src & 0xff000000) != 0xff000000) + { + fbCompositeGeneral (op, pSrc, pMask, pDst, + xSrc, ySrc, xMask, yMask, xDst, yDst, + width, height); + return; + } + fbGetStipDrawable (pMask->pDrawable, maskBits, maskStride, maskBpp, maskXoff, maskYoff); + fbGetDrawable (pDst->pDrawable, dstBits, dstStride, dstBpp, dstXoff, dstYoff); + + switch (dstBpp) { + case 32: + break; + case 24: + break; + case 16: + src = cvt8888to0565(src); + break; + } + + src = fbReplicatePixel (src, dstBpp); + + fbBltOne (maskBits + maskStride * (yMask + maskYoff), + maskStride, + xMask + maskXoff, + + dstBits + dstStride * (yDst + dstYoff), + dstStride, + (xDst + dstXoff) * dstBpp, + dstBpp, + + width * dstBpp, + height, + + 0x0, + src, + FB_ALLONES, + 0x0); +} + +# define mod(a,b) ((b) == 1 ? 0 : (a) >= 0 ? (a) % (b) : (b) - (-a) % (b)) + +void +fbComposite (CARD8 op, + PicturePtr pSrc, + PicturePtr pMask, + PicturePtr pDst, + INT16 xSrc, + INT16 ySrc, + INT16 xMask, + INT16 yMask, + INT16 xDst, + INT16 yDst, + CARD16 width, + CARD16 height) +{ + RegionRec region; + int n; + BoxPtr pbox; + CompositeFunc func = NULL; + Bool srcRepeat = pSrc->pDrawable && pSrc->repeat == RepeatNormal; + Bool maskRepeat = FALSE; + Bool srcAlphaMap = pSrc->alphaMap != 0; + Bool maskAlphaMap = FALSE; + Bool dstAlphaMap = pDst->alphaMap != 0; + int x_msk, y_msk, x_src, y_src, x_dst, y_dst; + int w, h, w_this, h_this; + + xDst += pDst->pDrawable->x; + yDst += pDst->pDrawable->y; + if (pSrc->pDrawable) { + xSrc += pSrc->pDrawable->x; + ySrc += pSrc->pDrawable->y; + } + if (pMask && pMask->pDrawable) + { + xMask += pMask->pDrawable->x; + yMask += pMask->pDrawable->y; + maskRepeat = pMask->repeat == RepeatNormal; + maskAlphaMap = pMask->alphaMap != 0; + } + + if (pSrc->pDrawable && (!pMask || pMask->pDrawable) + && !pSrc->transform && !(pMask && pMask->transform) + && !maskAlphaMap && !srcAlphaMap && !dstAlphaMap + && (pSrc->filter != PictFilterConvolution) + && (!pMask || pMask->filter != PictFilterConvolution)) + switch (op) { + case PictOpSrc: + break; + case PictOpOver: + if (pMask) + { + if (srcRepeat && + pSrc->pDrawable->width == 1 && + pSrc->pDrawable->height == 1) + { + srcRepeat = FALSE; + if (PICT_FORMAT_COLOR(pSrc->format)) { + switch (pMask->format) { + case PICT_a8: + switch (pDst->format) { + case PICT_r5g6b5: + case PICT_b5g6r5: + func = fbCompositeSolidMask_nx8x0565; + break; + case PICT_r8g8b8: + case PICT_b8g8r8: + func = fbCompositeSolidMask_nx8x0888; + break; + case PICT_a8r8g8b8: + case PICT_x8r8g8b8: + case PICT_a8b8g8r8: + case PICT_x8b8g8r8: + func = fbCompositeSolidMask_nx8x8888; + break; + } + break; + case PICT_a8r8g8b8: + if (pMask->componentAlpha) { + switch (pDst->format) { + case PICT_a8r8g8b8: + case PICT_x8r8g8b8: + func = fbCompositeSolidMask_nx8888x8888C; + break; + case PICT_r5g6b5: + func = fbCompositeSolidMask_nx8888x0565C; + break; + } + } + break; + case PICT_a8b8g8r8: + if (pMask->componentAlpha) { + switch (pDst->format) { + case PICT_a8b8g8r8: + case PICT_x8b8g8r8: + func = fbCompositeSolidMask_nx8888x8888C; + break; + case PICT_b5g6r5: + func = fbCompositeSolidMask_nx8888x0565C; + break; + } + } + break; + case PICT_a1: + switch (pDst->format) { + case PICT_r5g6b5: + case PICT_b5g6r5: + case PICT_r8g8b8: + case PICT_b8g8r8: + case PICT_a8r8g8b8: + case PICT_x8r8g8b8: + case PICT_a8b8g8r8: + case PICT_x8b8g8r8: + func = fbCompositeSolidMask_nx1xn; + break; + } + break; + } + } + } + else /* has mask and non-repeating source */ + { + if (pSrc->pDrawable == pMask->pDrawable && + xSrc == xMask && ySrc == yMask && + !pMask->componentAlpha) + { + /* source == mask: non-premultiplied data */ + switch (pSrc->format) { + case PICT_x8b8g8r8: + switch (pMask->format) { + case PICT_a8r8g8b8: + case PICT_a8b8g8r8: + switch (pDst->format) { + case PICT_a8r8g8b8: + case PICT_x8r8g8b8: + break; + case PICT_r5g6b5: + break; + } + break; + } + break; + case PICT_x8r8g8b8: + switch (pMask->format) { + case PICT_a8r8g8b8: + case PICT_a8b8g8r8: + switch (pDst->format) { + case PICT_a8b8g8r8: + case PICT_x8b8g8r8: + break; + case PICT_r5g6b5: + break; + } + break; + } + break; + } + break; + } + else + { + /* non-repeating source, repeating mask => translucent window */ + if (maskRepeat && + pMask->pDrawable->width == 1 && + pMask->pDrawable->height == 1) + { + if (pSrc->format == PICT_x8r8g8b8 && + pDst->format == PICT_x8r8g8b8 && + pMask->format == PICT_a8) + { + } + } + } + } + } + else /* no mask */ + { + if (srcRepeat && + pSrc->pDrawable->width == 1 && + pSrc->pDrawable->height == 1) + { + /* no mask and repeating source */ + switch (pSrc->format) { + case PICT_a8r8g8b8: + switch (pDst->format) { + case PICT_a8r8g8b8: + case PICT_x8r8g8b8: + break; + case PICT_r5g6b5: + break; + } + break; + } + } + else + { + switch (pSrc->format) { + case PICT_a8r8g8b8: + switch (pDst->format) { + case PICT_a8r8g8b8: + case PICT_x8r8g8b8: + func = fbCompositeSrc_8888x8888; + break; + case PICT_r8g8b8: + func = fbCompositeSrc_8888x0888; + break; + case PICT_r5g6b5: + func = fbCompositeSrc_8888x0565; + break; + } + break; + case PICT_x8r8g8b8: + switch (pDst->format) { + case PICT_a8r8g8b8: + case PICT_x8r8g8b8: + break; + } + case PICT_x8b8g8r8: + switch (pDst->format) { + case PICT_a8b8g8r8: + case PICT_x8b8g8r8: + break; + } + break; + case PICT_a8b8g8r8: + switch (pDst->format) { + case PICT_a8b8g8r8: + case PICT_x8b8g8r8: + func = fbCompositeSrc_8888x8888; + break; + case PICT_b8g8r8: + func = fbCompositeSrc_8888x0888; + break; + case PICT_b5g6r5: + func = fbCompositeSrc_8888x0565; + break; + } + break; + case PICT_r5g6b5: + switch (pDst->format) { + case PICT_r5g6b5: + func = fbCompositeSrc_0565x0565; + break; + } + break; + case PICT_b5g6r5: + switch (pDst->format) { + case PICT_b5g6r5: + func = fbCompositeSrc_0565x0565; + break; + } + break; + } + } + } + break; + case PictOpAdd: + if (pMask == 0) + { + switch (pSrc->format) { + case PICT_a8r8g8b8: + switch (pDst->format) { + case PICT_a8r8g8b8: + func = fbCompositeSrcAdd_8888x8888; + break; + } + break; + case PICT_a8b8g8r8: + switch (pDst->format) { + case PICT_a8b8g8r8: + func = fbCompositeSrcAdd_8888x8888; + break; + } + break; + case PICT_a8: + switch (pDst->format) { + case PICT_a8: + func = fbCompositeSrcAdd_8000x8000; + break; + } + break; + case PICT_a1: + switch (pDst->format) { + case PICT_a1: + func = fbCompositeSrcAdd_1000x1000; + break; + } + break; + } + } + break; + } + + if (!func) { + /* no fast path, use the general code */ + fbCompositeGeneral(op, pSrc, pMask, pDst, xSrc, ySrc, xMask, yMask, xDst, yDst, width, height); + return; + } + + if (!miComputeCompositeRegion (®ion, + pSrc, + pMask, + pDst, + xSrc, + ySrc, + xMask, + yMask, + xDst, + yDst, + width, + height)) + return; + + n = RegionNumRects (®ion); + pbox = RegionRects (®ion); + while (n--) + { + h = pbox->y2 - pbox->y1; + y_src = pbox->y1 - yDst + ySrc; + y_msk = pbox->y1 - yDst + yMask; + y_dst = pbox->y1; + while (h) + { + h_this = h; + w = pbox->x2 - pbox->x1; + x_src = pbox->x1 - xDst + xSrc; + x_msk = pbox->x1 - xDst + xMask; + x_dst = pbox->x1; + if (maskRepeat) + { + y_msk = mod (y_msk - pMask->pDrawable->y, pMask->pDrawable->height); + if (h_this > pMask->pDrawable->height - y_msk) + h_this = pMask->pDrawable->height - y_msk; + y_msk += pMask->pDrawable->y; + } + if (srcRepeat) + { + y_src = mod (y_src - pSrc->pDrawable->y, pSrc->pDrawable->height); + if (h_this > pSrc->pDrawable->height - y_src) + h_this = pSrc->pDrawable->height - y_src; + y_src += pSrc->pDrawable->y; + } + while (w) + { + w_this = w; + if (maskRepeat) + { + x_msk = mod (x_msk - pMask->pDrawable->x, pMask->pDrawable->width); + if (w_this > pMask->pDrawable->width - x_msk) + w_this = pMask->pDrawable->width - x_msk; + x_msk += pMask->pDrawable->x; + } + if (srcRepeat) + { + x_src = mod (x_src - pSrc->pDrawable->x, pSrc->pDrawable->width); + if (w_this > pSrc->pDrawable->width - x_src) + w_this = pSrc->pDrawable->width - x_src; + x_src += pSrc->pDrawable->x; + } + (*func) (op, pSrc, pMask, pDst, + x_src, y_src, x_msk, y_msk, x_dst, y_dst, + w_this, h_this); + w -= w_this; + x_src += w_this; + x_msk += w_this; + x_dst += w_this; + } + h -= h_this; + y_src += h_this; + y_msk += h_this; + y_dst += h_this; + } + pbox++; + } + RegionUninit(®ion); +} + +#endif /* RENDER */ + +Bool +fbPictureInit (ScreenPtr pScreen, PictFormatPtr formats, int nformats) +{ + +#ifdef RENDER + + PictureScreenPtr ps; + + if (!miPictureInit (pScreen, formats, nformats)) + return FALSE; + ps = GetPictureScreen(pScreen); + ps->Composite = fbComposite; + ps->Glyphs = miGlyphs; + ps->CompositeRects = miCompositeRects; + ps->RasterizeTrapezoid = fbRasterizeTrapezoid; + ps->AddTraps = fbAddTraps; + ps->AddTriangles = fbAddTriangles; + +#endif /* RENDER */ + + return TRUE; +} diff --git a/nx-X11/programs/Xserver/fb/fbpict.h b/nx-X11/programs/Xserver/fb/fbpict.h new file mode 100644 index 000000000..78d280707 --- /dev/null +++ b/nx-X11/programs/Xserver/fb/fbpict.h @@ -0,0 +1,610 @@ +/* + * Copyright © 2000 Keith Packard, member of The XFree86 Project, Inc. + * + * 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 + +#ifndef _FBPICT_H_ +#define _FBPICT_H_ + +#include "renderedge.h" + +#define FbIntMult(a,b,t) ( (t) = (a) * (b) + 0x80, ( ( ( (t)>>8 ) + (t) )>>8 ) ) +#define FbIntDiv(a,b) (((CARD16) (a) * 255) / (b)) + +#define FbGet8(v,i) ((CARD16) (CARD8) ((v) >> i)) + +/* + * There are two ways of handling alpha -- either as a single unified value or + * a separate value for each component, hence each macro must have two + * versions. The unified alpha version has a 'U' at the end of the name, + * the component version has a 'C'. Similarly, functions which deal with + * this difference will have two versions using the same convention. + */ + +#define FbOverU(x,y,i,a,t) ((t) = FbIntMult(FbGet8(y,i),(a),(t)) + FbGet8(x,i),\ + (CARD32) ((CARD8) ((t) | (0 - ((t) >> 8)))) << (i)) + +#define FbOverC(x,y,i,a,t) ((t) = FbIntMult(FbGet8(y,i),FbGet8(a,i),(t)) + FbGet8(x,i),\ + (CARD32) ((CARD8) ((t) | (0 - ((t) >> 8)))) << (i)) + +#define FbInU(x,i,a,t) ((CARD32) FbIntMult(FbGet8(x,i),(a),(t)) << (i)) + +#define FbInC(x,i,a,t) ((CARD32) FbIntMult(FbGet8(x,i),FbGet8(a,i),(t)) << (i)) + +#define FbGen(x,y,i,ax,ay,t,u,v) ((t) = (FbIntMult(FbGet8(y,i),ay,(u)) + \ + FbIntMult(FbGet8(x,i),ax,(v))),\ + (CARD32) ((CARD8) ((t) | \ + (0 - ((t) >> 8)))) << (i)) + +#define FbAdd(x,y,i,t) ((t) = FbGet8(x,i) + FbGet8(y,i), \ + (CARD32) ((CARD8) ((t) | (0 - ((t) >> 8)))) << (i)) + + +#define Alpha(x) ((x) >> 24) +#define Red(x) (((x) >> 16) & 0xff) +#define Green(x) (((x) >> 8) & 0xff) +#define Blue(x) ((x) & 0xff) + +#define fbComposeGetSolid(pict, bits, fmt) { \ + FbBits *__bits__; \ + FbStride __stride__; \ + int __bpp__; \ + _X_UNUSED int __xoff__,__yoff__; \ +\ + fbGetDrawable((pict)->pDrawable,__bits__,__stride__,__bpp__,__xoff__,__yoff__); \ + switch (__bpp__) { \ + case 32: \ + (bits) = *(CARD32 *) __bits__; \ + break; \ + case 24: \ + (bits) = Fetch24 ((CARD8 *) __bits__); \ + break; \ + case 16: \ + (bits) = *(CARD16 *) __bits__; \ + (bits) = cvt0565to8888(bits); \ + break; \ + default: \ + return; \ + } \ + /* If necessary, convert RGB <--> BGR. */ \ + if (PICT_FORMAT_TYPE((pict)->format) != PICT_FORMAT_TYPE(fmt)) \ + { \ + (bits) = (((bits) & 0xff000000) | \ + (((bits) & 0x00ff0000) >> 16) | \ + (((bits) & 0x0000ff00) >> 0) | \ + (((bits) & 0x000000ff) << 16)); \ + } \ + /* manage missing src alpha */ \ + if ((pict)->pFormat->direct.alphaMask == 0) \ + (bits) |= 0xff000000; \ +} + +#define fbComposeGetStart(pict,x,y,type,stride,line,mul) {\ + FbBits *__bits__; \ + FbStride __stride__; \ + int __bpp__; \ + int __xoff__,__yoff__; \ +\ + fbGetDrawable((pict)->pDrawable,__bits__,__stride__,__bpp__,__xoff__,__yoff__); \ + (stride) = __stride__ * sizeof (FbBits) / sizeof (type); \ + (line) = ((type *) __bits__) + (stride) * ((y) + __yoff__) + (mul) * ((x) + __xoff__); \ +} +#define cvt8888to0565(s) ((((s) >> 3) & 0x001f) | \ + (((s) >> 5) & 0x07e0) | \ + (((s) >> 8) & 0xf800)) +#define cvt0565to8888(s) (((((s) << 3) & 0xf8) | (((s) >> 2) & 0x7)) | \ + ((((s) << 5) & 0xfc00) | (((s) >> 1) & 0x300)) | \ + ((((s) << 8) & 0xf80000) | (((s) << 3) & 0x70000))) + +#if IMAGE_BYTE_ORDER == MSBFirst +#define Fetch24(a) ((unsigned long) (a) & 1 ? \ + ((*(a) << 16) | *((CARD16 *) ((a)+1))) : \ + ((*((CARD16 *) (a)) << 8) | *((a)+2))) +#define Store24(a,v) ((unsigned long) (a) & 1 ? \ + ((*(a) = (CARD8) ((v) >> 16)), \ + (*((CARD16 *) ((a)+1)) = (CARD16) (v))) : \ + ((*((CARD16 *) (a)) = (CARD16) ((v) >> 8)), \ + (*((a)+2) = (CARD8) (v)))) +#else +#define Fetch24(a) ((unsigned long) (a) & 1 ? \ + ((*(a)) | (*((CARD16 *) ((a)+1)) << 8)) : \ + ((*((CARD16 *) (a))) | (*((a)+2) << 16))) +#define Store24(a,v) ((unsigned long) (a) & 1 ? \ + ((*(a) = (CARD8) (v)), \ + (*((CARD16 *) ((a)+1)) = (CARD16) ((v) >> 8))) : \ + ((*((CARD16 *) (a)) = (CARD16) (v)),\ + (*((a)+2) = (CARD8) ((v) >> 16)))) +#endif + +/* + The methods below use some tricks to be able to do two color + components at the same time. +*/ + +/* + x_c = (x_c * a) / 255 +*/ +#define FbByteMul(x, a) do { \ + CARD32 t = ((x & 0xff00ff) * a) + 0x800080; \ + t = (t + ((t >> 8) & 0xff00ff)) >> 8; \ + t &= 0xff00ff; \ + \ + x = (((x >> 8) & 0xff00ff) * a) + 0x800080; \ + x = (x + ((x >> 8) & 0xff00ff)); \ + x &= 0xff00ff00; \ + x += t; \ + } while (0) + +/* + x_c = (x_c * a) / 255 + y +*/ +#define FbByteMulAdd(x, a, y) do { \ + CARD32 t = ((x & 0xff00ff) * a) + 0x800080; \ + t = (t + ((t >> 8) & 0xff00ff)) >> 8; \ + t &= 0xff00ff; \ + t += y & 0xff00ff; \ + t |= 0x1000100 - ((t >> 8) & 0xff00ff); \ + t &= 0xff00ff; \ + \ + x = (((x >> 8) & 0xff00ff) * a) + 0x800080; \ + x = (x + ((x >> 8) & 0xff00ff)) >> 8; \ + x &= 0xff00ff; \ + x += (y >> 8) & 0xff00ff; \ + x |= 0x1000100 - ((t >> 8) & 0xff00ff); \ + x &= 0xff00ff; \ + x <<= 8; \ + x += t; \ + } while (0) + +/* + x_c = (x_c * a + y_c * b) / 255 +*/ +#define FbByteAddMul(x, a, y, b) do { \ + CARD32 t; \ + CARD32 r = (x >> 24) * a + (y >> 24) * b + 0x80; \ + r += (r >> 8); \ + r >>= 8; \ + \ + t = (x & 0xff00) * a + (y & 0xff00) * b; \ + t += (t >> 8) + 0x8000; \ + t >>= 16; \ + \ + t |= r << 16; \ + t |= 0x1000100 - ((t >> 8) & 0xff00ff); \ + t &= 0xff00ff; \ + t <<= 8; \ + \ + r = ((x >> 16) & 0xff) * a + ((y >> 16) & 0xff) * b + 0x80; \ + r += (r >> 8); \ + r >>= 8; \ + \ + x = (x & 0xff) * a + (y & 0xff) * b + 0x80; \ + x += (x >> 8); \ + x >>= 8; \ + x |= r << 16; \ + x |= 0x1000100 - ((x >> 8) & 0xff00ff); \ + x &= 0xff00ff; \ + x |= t; \ +} while (0) + +/* + x_c = (x_c * a + y_c *b) / 256 +*/ +#define FbByteAddMul_256(x, a, y, b) do { \ + CARD32 t = (x & 0xff00ff) * a + (y & 0xff00ff) * b; \ + t >>= 8; \ + t &= 0xff00ff; \ + \ + x = ((x >> 8) & 0xff00ff) * a + ((y >> 8) & 0xff00ff) * b; \ + x &= 0xff00ff00; \ + x += t; \ +} while (0) +/* + x_c = (x_c * a_c) / 255 +*/ +#define FbByteMulC(x, a) do { \ + CARD32 t; \ + CARD32 r = (x & 0xff) * (a & 0xff); \ + r |= (x & 0xff0000) * ((a >> 16) & 0xff); \ + r += 0x800080; \ + r = (r + ((r >> 8) & 0xff00ff)) >> 8; \ + r &= 0xff00ff; \ + \ + x >>= 8; \ + t = (x & 0xff) * ((a >> 8) & 0xff); \ + t |= (x & 0xff0000) * (a >> 24); \ + t += 0x800080; \ + t = t + ((t >> 8) & 0xff00ff); \ + x = r | (t & 0xff00ff00); \ + \ + } while (0) + +/* + x_c = (x_c * a) / 255 + y +*/ +#define FbByteMulAddC(x, a, y) do { \ + CARD32 t; \ + CARD32 r = (x & 0xff) * (a & 0xff); \ + r |= (x & 0xff0000) * ((a >> 16) & 0xff); \ + r += 0x800080; \ + r = (r + ((r >> 8) & 0xff00ff)) >> 8; \ + r &= 0xff00ff; \ + r += y & 0xff00ff; \ + r |= 0x1000100 - ((r >> 8) & 0xff00ff); \ + r &= 0xff00ff; \ + \ + x >>= 8; \ + t = (x & 0xff) * ((a >> 8) & 0xff); \ + t |= (x & 0xff0000) * (a >> 24); \ + t += 0x800080; \ + t = (t + ((t >> 8) & 0xff00ff)) >> 8; \ + t &= 0xff00ff; \ + t += (y >> 8) & 0xff00ff; \ + t |= 0x1000100 - ((t >> 8) & 0xff00ff); \ + t &= 0xff00ff; \ + x = r | (t << 8); \ + } while (0) + +/* + x_c = (x_c * a_c + y_c * b) / 255 +*/ +#define FbByteAddMulC(x, a, y, b) do { \ + CARD32 t; \ + CARD32 r = (x >> 24) * (a >> 24) + (y >> 24) * b; \ + r += (r >> 8) + 0x80; \ + r >>= 8; \ + \ + t = (x & 0xff00) * ((a >> 8) & 0xff) + (y & 0xff00) * b; \ + t += (t >> 8) + 0x8000; \ + t >>= 16; \ + \ + t |= r << 16; \ + t |= 0x1000100 - ((t >> 8) & 0xff00ff); \ + t &= 0xff00ff; \ + t <<= 8; \ + \ + r = ((x >> 16) & 0xff) * ((a >> 16) & 0xff) + ((y >> 16) & 0xff) * b + 0x80; \ + r += (r >> 8); \ + r >>= 8; \ + \ + x = (x & 0xff) * (a & 0xff) + (y & 0xff) * b + 0x80; \ + x += (x >> 8); \ + x >>= 8; \ + x |= r << 16; \ + x |= 0x1000100 - ((x >> 8) & 0xff00ff); \ + x &= 0xff00ff; \ + x |= t; \ + } while (0) + +/* + x_c = min(x_c + y_c, 255) +*/ +#define FbByteAdd(x, y) do { \ + CARD32 t; \ + CARD32 r = (x & 0xff00ff) + (y & 0xff00ff); \ + r |= 0x1000100 - ((r >> 8) & 0xff00ff); \ + r &= 0xff00ff; \ + \ + t = ((x >> 8) & 0xff00ff) + ((y >> 8) & 0xff00ff); \ + t |= 0x1000100 - ((t >> 8) & 0xff00ff); \ + r |= (t & 0xff00ff) << 8; \ + x = r; \ + } while (0) + +#define div_255(x) (((x) + 0x80 + (((x) + 0x80) >> 8)) >> 8) + +#if defined(__i386__) && defined(__GNUC__) +#define FASTCALL __attribute__((regparm(3))) +#else +#define FASTCALL +#endif + +#if defined(__GNUC__) +#define INLINE __inline__ +#else +#define INLINE +#endif + +typedef struct _FbComposeData { + CARD8 op; + PicturePtr src; + PicturePtr mask; + PicturePtr dest; + INT16 xSrc; + INT16 ySrc; + INT16 xMask; + INT16 yMask; + INT16 xDest; + INT16 yDest; + CARD16 width; + CARD16 height; +} FbComposeData; + +typedef FASTCALL void (*CombineMaskU) (CARD32 *src, const CARD32 *mask, int width); +typedef FASTCALL void (*CombineFuncU) (CARD32 *dest, const CARD32 *src, int width); +typedef FASTCALL void (*CombineFuncC) (CARD32 *dest, CARD32 *src, CARD32 *mask, int width); + +typedef struct _FbComposeFunctions { + CombineFuncU *combineU; + CombineFuncC *combineC; + CombineMaskU combineMaskU; +} FbComposeFunctions; + +/* fbcompose.c */ + +void +fbCompositeGeneral (CARD8 op, + PicturePtr pSrc, + PicturePtr pMask, + PicturePtr pDst, + INT16 xSrc, + INT16 ySrc, + INT16 xMask, + INT16 yMask, + INT16 xDst, + INT16 yDst, + CARD16 width, + CARD16 height); + + +/* fbedge.c */ +void +fbRasterizeEdges (FbBits *buf, + int bpp, + int width, + int stride, + RenderEdge *l, + RenderEdge *r, + xFixed t, + xFixed b); + +/* fbpict.c */ +CARD32 +fbOver (CARD32 x, CARD32 y); + +CARD32 +fbOver24 (CARD32 x, CARD32 y); + +CARD32 +fbIn (CARD32 x, CARD8 y); + +void +fbCompositeSolidMask_nx8x8888 (CARD8 op, + PicturePtr pSrc, + PicturePtr pMask, + PicturePtr pDst, + INT16 xSrc, + INT16 ySrc, + INT16 xMask, + INT16 yMask, + INT16 xDst, + INT16 yDst, + CARD16 width, + CARD16 height); + +void +fbCompositeSolidMask_nx8x0888 (CARD8 op, + PicturePtr pSrc, + PicturePtr pMask, + PicturePtr pDst, + INT16 xSrc, + INT16 ySrc, + INT16 xMask, + INT16 yMask, + INT16 xDst, + INT16 yDst, + CARD16 width, + CARD16 height); + +void +fbCompositeSolidMask_nx8888x8888C (CARD8 op, + PicturePtr pSrc, + PicturePtr pMask, + PicturePtr pDst, + INT16 xSrc, + INT16 ySrc, + INT16 xMask, + INT16 yMask, + INT16 xDst, + INT16 yDst, + CARD16 width, + CARD16 height); + +void +fbCompositeSolidMask_nx8x0565 (CARD8 op, + PicturePtr pSrc, + PicturePtr pMask, + PicturePtr pDst, + INT16 xSrc, + INT16 ySrc, + INT16 xMask, + INT16 yMask, + INT16 xDst, + INT16 yDst, + CARD16 width, + CARD16 height); + +void +fbCompositeSolidMask_nx8888x0565C (CARD8 op, + PicturePtr pSrc, + PicturePtr pMask, + PicturePtr pDst, + INT16 xSrc, + INT16 ySrc, + INT16 xMask, + INT16 yMask, + INT16 xDst, + INT16 yDst, + CARD16 width, + CARD16 height); + +void +fbCompositeSrc_8888x8888 (CARD8 op, + PicturePtr pSrc, + PicturePtr pMask, + PicturePtr pDst, + INT16 xSrc, + INT16 ySrc, + INT16 xMask, + INT16 yMask, + INT16 xDst, + INT16 yDst, + CARD16 width, + CARD16 height); + +void +fbCompositeSrc_8888x0888 (CARD8 op, + PicturePtr pSrc, + PicturePtr pMask, + PicturePtr pDst, + INT16 xSrc, + INT16 ySrc, + INT16 xMask, + INT16 yMask, + INT16 xDst, + INT16 yDst, + CARD16 width, + CARD16 height); + +void +fbCompositeSrc_8888x0565 (CARD8 op, + PicturePtr pSrc, + PicturePtr pMask, + PicturePtr pDst, + INT16 xSrc, + INT16 ySrc, + INT16 xMask, + INT16 yMask, + INT16 xDst, + INT16 yDst, + CARD16 width, + CARD16 height); + +void +fbCompositeSrc_0565x0565 (CARD8 op, + PicturePtr pSrc, + PicturePtr pMask, + PicturePtr pDst, + INT16 xSrc, + INT16 ySrc, + INT16 xMask, + INT16 yMask, + INT16 xDst, + INT16 yDst, + CARD16 width, + CARD16 height); + +void +fbCompositeSrcAdd_8000x8000 (CARD8 op, + PicturePtr pSrc, + PicturePtr pMask, + PicturePtr pDst, + INT16 xSrc, + INT16 ySrc, + INT16 xMask, + INT16 yMask, + INT16 xDst, + INT16 yDst, + CARD16 width, + CARD16 height); + +void +fbCompositeSrcAdd_8888x8888 (CARD8 op, + PicturePtr pSrc, + PicturePtr pMask, + PicturePtr pDst, + INT16 xSrc, + INT16 ySrc, + INT16 xMask, + INT16 yMask, + INT16 xDst, + INT16 yDst, + CARD16 width, + CARD16 height); + +void +fbCompositeSrcAdd_1000x1000 (CARD8 op, + PicturePtr pSrc, + PicturePtr pMask, + PicturePtr pDst, + INT16 xSrc, + INT16 ySrc, + INT16 xMask, + INT16 yMask, + INT16 xDst, + INT16 yDst, + CARD16 width, + CARD16 height); + +void +fbCompositeSolidMask_nx1xn (CARD8 op, + PicturePtr pSrc, + PicturePtr pMask, + PicturePtr pDst, + INT16 xSrc, + INT16 ySrc, + INT16 xMask, + INT16 yMask, + INT16 xDst, + INT16 yDst, + CARD16 width, + CARD16 height); + +void +fbComposite (CARD8 op, + PicturePtr pSrc, + PicturePtr pMask, + PicturePtr pDst, + INT16 xSrc, + INT16 ySrc, + INT16 xMask, + INT16 yMask, + INT16 xDst, + INT16 yDst, + CARD16 width, + CARD16 height); + +/* fbtrap.c */ + +void +fbAddTraps (PicturePtr pPicture, + INT16 xOff, + INT16 yOff, + int ntrap, + xTrap *traps); + +void +fbRasterizeTrapezoid (PicturePtr alpha, + xTrapezoid *trap, + int x_off, + int y_off); + +void +fbAddTriangles (PicturePtr pPicture, + INT16 xOff, + INT16 yOff, + int ntri, + xTriangle *tris); + +#endif /* _FBPICT_H_ */ diff --git a/nx-X11/programs/Xserver/fb/fbpixmap.c b/nx-X11/programs/Xserver/fb/fbpixmap.c new file mode 100644 index 000000000..5f24433e3 --- /dev/null +++ b/nx-X11/programs/Xserver/fb/fbpixmap.c @@ -0,0 +1,390 @@ +/* + * Id: fbpixmap.c,v 1.1 1999/11/02 03:54:45 keithp Exp $ + * + * 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 <stdlib.h> + +#include "fb.h" + +PixmapPtr +fbCreatePixmapBpp (ScreenPtr pScreen, int width, int height, int depth, int bpp, + unsigned usage_hint) +{ + PixmapPtr pPixmap; + size_t datasize; + size_t paddedWidth; + int adjust; + int base; + + paddedWidth = ((width * bpp + FB_MASK) >> FB_SHIFT) * sizeof (FbBits); + if (paddedWidth / 4 > 32767 || height > 32767) + return NullPixmap; + datasize = height * paddedWidth; +#ifdef PIXPRIV + base = pScreen->totalPixmapSize; +#else + base = sizeof (PixmapRec); +#endif + adjust = 0; + if (base & 7) + adjust = 8 - (base & 7); + datasize += adjust; +#ifdef FB_DEBUG + datasize += 2 * paddedWidth; +#endif + pPixmap = AllocatePixmap(pScreen, datasize); + if (!pPixmap) + return NullPixmap; + pPixmap->drawable.type = DRAWABLE_PIXMAP; + pPixmap->drawable.class = 0; + pPixmap->drawable.pScreen = pScreen; + pPixmap->drawable.depth = depth; + pPixmap->drawable.bitsPerPixel = bpp; + pPixmap->drawable.id = 0; + pPixmap->drawable.serialNumber = NEXT_SERIAL_NUMBER; + pPixmap->drawable.x = 0; + pPixmap->drawable.y = 0; + pPixmap->drawable.width = width; + pPixmap->drawable.height = height; + pPixmap->devKind = paddedWidth; + pPixmap->refcnt = 1; + pPixmap->devPrivate.ptr = (void *) ((char *)pPixmap + base + adjust); +#ifdef FB_DEBUG + pPixmap->devPrivate.ptr = (void *) ((char *) pPixmap->devPrivate.ptr + paddedWidth); + fbInitializeDrawable (&pPixmap->drawable); +#endif + +#ifdef COMPOSITE + pPixmap->screen_x = 0; + pPixmap->screen_y = 0; +#endif + pPixmap->usage_hint = usage_hint; + + return pPixmap; +} + +PixmapPtr +fbCreatePixmap (ScreenPtr pScreen, int width, int height, int depth, + unsigned usage_hint) +{ + int bpp; + bpp = BitsPerPixel (depth); +#ifdef FB_SCREEN_PRIVATE + if (bpp == 32 && depth <= 24) + bpp = fbGetScreenPrivate(pScreen)->pix32bpp; +#endif + return fbCreatePixmapBpp (pScreen, width, height, depth, bpp, usage_hint); +} + +Bool +fbDestroyPixmap (PixmapPtr pPixmap) +{ + if(--pPixmap->refcnt) + return TRUE; + free(pPixmap); + return TRUE; +} + +#define ADDRECT(reg,r,fr,rx1,ry1,rx2,ry2) \ +if (((rx1) < (rx2)) && ((ry1) < (ry2)) && \ + (!((reg)->data->numRects && \ + ((r-1)->y1 == (ry1)) && \ + ((r-1)->y2 == (ry2)) && \ + ((r-1)->x1 <= (rx1)) && \ + ((r-1)->x2 >= (rx2))))) \ +{ \ + if ((reg)->data->numRects == (reg)->data->size) \ + { \ + RegionRectAlloc(reg, 1); \ + fr = RegionBoxptr(reg); \ + r = fr + (reg)->data->numRects; \ + } \ + r->x1 = (rx1); \ + r->y1 = (ry1); \ + r->x2 = (rx2); \ + r->y2 = (ry2); \ + (reg)->data->numRects++; \ + if(r->x1 < (reg)->extents.x1) \ + (reg)->extents.x1 = r->x1; \ + if(r->x2 > (reg)->extents.x2) \ + (reg)->extents.x2 = r->x2; \ + r++; \ +} + +/* Convert bitmap clip mask into clipping region. + * First, goes through each line and makes boxes by noting the transitions + * from 0 to 1 and 1 to 0. + * Then it coalesces the current line with the previous if they have boxes + * at the same X coordinates. + */ +RegionPtr +fbPixmapToRegion(PixmapPtr pPix) +{ + register RegionPtr pReg; + FbBits *pw, w; + register int ib; + int width, h, base, rx1 = 0, crects; + FbBits *pwLineEnd; + int irectPrevStart, irectLineStart; + register BoxPtr prectO, prectN; + BoxPtr FirstRect, rects, prectLineStart; + Bool fInBox, fSame; + register FbBits mask0 = FB_ALLONES & ~FbScrRight(FB_ALLONES, 1); + FbBits *pwLine; + int nWidth; + + pReg = RegionCreate(NULL, 1); + if(!pReg) + return NullRegion; + FirstRect = RegionBoxptr(pReg); + rects = FirstRect; + + pwLine = (FbBits *) pPix->devPrivate.ptr; + nWidth = pPix->devKind >> (FB_SHIFT-3); + + width = pPix->drawable.width; + pReg->extents.x1 = width - 1; + pReg->extents.x2 = 0; + irectPrevStart = -1; + for(h = 0; h < pPix->drawable.height; h++) + { + pw = pwLine; + pwLine += nWidth; + irectLineStart = rects - FirstRect; + /* If the Screen left most bit of the word is set, we're starting in + * a box */ + if(*pw & mask0) + { + fInBox = TRUE; + rx1 = 0; + } + else + fInBox = FALSE; + /* Process all words which are fully in the pixmap */ + pwLineEnd = pw + (width >> FB_SHIFT); + for (base = 0; pw < pwLineEnd; base += FB_UNIT) + { + w = *pw++; + if (fInBox) + { + if (!~w) + continue; + } + else + { + if (!w) + continue; + } + for(ib = 0; ib < FB_UNIT; ib++) + { + /* If the Screen left most bit of the word is set, we're + * starting a box */ + if(w & mask0) + { + if(!fInBox) + { + rx1 = base + ib; + /* start new box */ + fInBox = TRUE; + } + } + else + { + if(fInBox) + { + /* end box */ + ADDRECT(pReg, rects, FirstRect, + rx1, h, base + ib, h + 1); + fInBox = FALSE; + } + } + /* Shift the word VISUALLY left one. */ + w = FbScrLeft(w, 1); + } + } + if(width & FB_MASK) + { + /* Process final partial word on line */ + w = *pw++; + for(ib = 0; ib < (width & FB_MASK); ib++) + { + /* If the Screen left most bit of the word is set, we're + * starting a box */ + if(w & mask0) + { + if(!fInBox) + { + rx1 = base + ib; + /* start new box */ + fInBox = TRUE; + } + } + else + { + if(fInBox) + { + /* end box */ + ADDRECT(pReg, rects, FirstRect, + rx1, h, base + ib, h + 1); + fInBox = FALSE; + } + } + /* Shift the word VISUALLY left one. */ + w = FbScrLeft(w, 1); + } + } + /* If scanline ended with last bit set, end the box */ + if(fInBox) + { + ADDRECT(pReg, rects, FirstRect, + rx1, h, base + (width & FB_MASK), h + 1); + } + /* if all rectangles on this line have the same x-coords as + * those on the previous line, then add 1 to all the previous y2s and + * throw away all the rectangles from this line + */ + fSame = FALSE; + if(irectPrevStart != -1) + { + crects = irectLineStart - irectPrevStart; + if(crects == ((rects - FirstRect) - irectLineStart)) + { + prectO = FirstRect + irectPrevStart; + prectN = prectLineStart = FirstRect + irectLineStart; + fSame = TRUE; + while(prectO < prectLineStart) + { + if((prectO->x1 != prectN->x1) || (prectO->x2 != prectN->x2)) + { + fSame = FALSE; + break; + } + prectO++; + prectN++; + } + if (fSame) + { + prectO = FirstRect + irectPrevStart; + while(prectO < prectLineStart) + { + prectO->y2 += 1; + prectO++; + } + rects -= crects; + pReg->data->numRects -= crects; + } + } + } + if(!fSame) + irectPrevStart = irectLineStart; + } + if (!pReg->data->numRects) + pReg->extents.x1 = pReg->extents.x2 = 0; + else + { + pReg->extents.y1 = RegionBoxptr(pReg)->y1; + pReg->extents.y2 = RegionEnd(pReg)->y2; + if (pReg->data->numRects == 1) + { + free(pReg->data); + pReg->data = (RegDataPtr)NULL; + } + } +#ifdef DEBUG + if (!RegionIsValid(pReg)) + FatalError("Assertion failed file %s, line %d: expr\n", __FILE__, __LINE__); +#endif + return(pReg); +} + +#ifdef FB_DEBUG + +#ifndef WIN32 +#include <stdio.h> +#else +#include <dbg.h> +#endif + +static Bool +fbValidateBits (FbStip *bits, int stride, FbStip data) +{ + while (stride--) + { + if (*bits != data) + { +#ifdef WIN32 + NCD_DEBUG ((DEBUG_FAILURE, "fdValidateBits failed at 0x%x (is 0x%x want 0x%x)", + bits, *bits, data)); +#else + fprintf (stderr, "fbValidateBits failed\n"); +#endif + return FALSE; + } + bits++; + } +} + +void +fbValidateDrawable (DrawablePtr pDrawable) +{ + FbStip *bits, *first, *last; + int stride, bpp; + int xoff, yoff; + int height; + Bool failed; + + if (pDrawable->type != DRAWABLE_PIXMAP) + pDrawable = (DrawablePtr) fbGetWindowPixmap(pDrawable); + fbGetStipDrawable(pDrawable, bits, stride, bpp, xoff, yoff); + first = bits - stride; + last = bits + stride * pDrawable->height; + if (!fbValidateBits (first, stride, FB_HEAD_BITS) || + !fbValidateBits (last, stride, FB_TAIL_BITS)) + fbInitializeDrawable(pDrawable); +} + +void +fbSetBits (FbStip *bits, int stride, FbStip data) +{ + while (stride--) + *bits++ = data; +} + +void +fbInitializeDrawable (DrawablePtr pDrawable) +{ + FbStip *bits, *first, *last; + int stride, bpp; + int xoff, yoff; + + fbGetStipDrawable(pDrawable, bits, stride, bpp, xoff, yoff); + first = bits - stride; + last = bits + stride * pDrawable->height; + fbSetBits (first, stride, FB_HEAD_BITS); + fbSetBits (last, stride, FB_TAIL_BITS); +} +#endif /* FB_DEBUG */ diff --git a/nx-X11/programs/Xserver/fb/fbpoint.c b/nx-X11/programs/Xserver/fb/fbpoint.c new file mode 100644 index 000000000..719dcfbb4 --- /dev/null +++ b/nx-X11/programs/Xserver/fb/fbpoint.c @@ -0,0 +1,163 @@ +/* + * Id: fbpoint.c,v 1.1 1999/11/02 03:54:45 keithp Exp $ + * + * 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" + +typedef void (*FbDots) (FbBits *dst, + FbStride dstStride, + int dstBpp, + BoxPtr pBox, + xPoint *pts, + int npt, + int xorg, + int yorg, + int xoff, + int yoff, + FbBits and, + FbBits xor); + +void +fbDots (FbBits *dstOrig, + FbStride dstStride, + int dstBpp, + BoxPtr pBox, + xPoint *pts, + int npt, + int xorg, + int yorg, + int xoff, + int yoff, + FbBits andOrig, + FbBits xorOrig) +{ + FbStip *dst = (FbStip *) dstOrig; + int x1, y1, x2, y2; + int x, y; + FbStip *d; + FbStip and = andOrig; + FbStip xor = xorOrig; + + dstStride = FbBitsStrideToStipStride (dstStride); + x1 = pBox->x1; + y1 = pBox->y1; + x2 = pBox->x2; + y2 = pBox->y2; + while (npt--) + { + x = pts->x + xorg; + y = pts->y + yorg; + pts++; + if (x1 <= x && x < x2 && y1 <= y && y < y2) + { + x = (x + xoff) * dstBpp; + d = dst + ((y + yoff) * dstStride) + (x >> FB_STIP_SHIFT); + x &= FB_STIP_MASK; +#ifdef FB_24BIT + if (dstBpp == 24) + { + FbStip leftMask, rightMask; + int n, rot; + FbStip andT, xorT; + + rot = FbFirst24Rot (x); + andT = FbRot24Stip(and,rot); + xorT = FbRot24Stip(xor,rot); + FbMaskStip (x, 24, leftMask, n, rightMask); + if (leftMask) + { + *d = FbDoMaskRRop (*d, andT, xorT, leftMask); + andT = FbNext24Stip(andT); + xorT = FbNext24Stip(xorT); + d++; + } + if (rightMask) + *d = FbDoMaskRRop(*d, andT, xorT, rightMask); + } + else +#endif + { + FbStip mask; + mask = FbStipMask(x, dstBpp); + *d = FbDoMaskRRop (*d, and, xor, mask); + } + } + } +} + +void +fbPolyPoint (DrawablePtr pDrawable, + GCPtr pGC, + int mode, + int nptInit, + xPoint *pptInit) +{ + FbGCPrivPtr pPriv = fbGetGCPrivate (pGC); + RegionPtr pClip = fbGetCompositeClip(pGC); + FbBits *dst; + FbStride dstStride; + int dstBpp; + int dstXoff, dstYoff; + FbDots dots; + FbBits and, xor; + xPoint *ppt; + int npt; + BoxPtr pBox; + int nBox; + + /* make pointlist origin relative */ + ppt = pptInit; + npt = nptInit; + if (mode == CoordModePrevious) + { + npt--; + while(npt--) + { + ppt++; + ppt->x += (ppt-1)->x; + ppt->y += (ppt-1)->y; + } + } + fbGetDrawable (pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff); + and = pPriv->and; + xor = pPriv->xor; + dots = fbDots; +#ifndef FBNOPIXADDR + switch (dstBpp) { + case 8: dots = fbDots8; break; + case 16: dots = fbDots16; break; +#ifdef FB_24BIT + case 24: dots = fbDots24; break; +#endif + case 32: dots = fbDots32; break; + } +#endif + for (nBox = RegionNumRects (pClip), pBox = RegionRects (pClip); + nBox--; pBox++) + (*dots) (dst, dstStride, dstBpp, pBox, pptInit, nptInit, + pDrawable->x, pDrawable->y, dstXoff, dstYoff, and, xor); +} diff --git a/nx-X11/programs/Xserver/fb/fbpush.c b/nx-X11/programs/Xserver/fb/fbpush.c new file mode 100644 index 000000000..6979b6f1b --- /dev/null +++ b/nx-X11/programs/Xserver/fb/fbpush.c @@ -0,0 +1,246 @@ +/* + * Id: fbpush.c,v 1.1 1999/11/02 03:54:45 keithp Exp $ + * + * 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 = *s++; + xspan = x; + while (w) + { + if (bits & bitsMask) + { + lenspan = 0; + do + { + lenspan++; + if (lenspan == w) + break; + bitsMask = FbStipRight (bitsMask, 1); + if (!bitsMask) + { + bits = *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 = *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)); + } + } + 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 = RegionNumRects (pClip), + pbox = RegionRects(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; + _X_UNUSED 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); +} diff --git a/nx-X11/programs/Xserver/fb/fbrop.h b/nx-X11/programs/Xserver/fb/fbrop.h new file mode 100644 index 000000000..f3768a265 --- /dev/null +++ b/nx-X11/programs/Xserver/fb/fbrop.h @@ -0,0 +1,138 @@ +/* + * Id: fbrop.h,v 1.1 1999/11/02 03:54:45 keithp Exp $ + * + * 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. + */ + +#ifndef _FBROP_H_ +#define _FBROP_H_ + +typedef struct _mergeRopBits { + FbBits ca1, cx1, ca2, cx2; +} FbMergeRopRec, *FbMergeRopPtr; + +extern const FbMergeRopRec FbMergeRopBits[16]; + +#define FbDeclareMergeRop() FbBits _ca1, _cx1, _ca2, _cx2; +#define FbDeclarePrebuiltMergeRop() FbBits _cca, _ccx; + +#define FbInitializeMergeRop(alu,pm) {\ + const FbMergeRopRec *_bits; \ + _bits = &FbMergeRopBits[alu]; \ + _ca1 = _bits->ca1 & pm; \ + _cx1 = _bits->cx1 | ~pm; \ + _ca2 = _bits->ca2 & pm; \ + _cx2 = _bits->cx2 & pm; \ +} + +#define FbDestInvarientRop(alu,pm) ((pm) == FB_ALLONES && \ + (((alu) >> 1 & 5) == ((alu) & 5))) + +#define FbDestInvarientMergeRop() (_ca1 == 0 && _cx1 == 0) + +/* AND has higher precedence than XOR */ + +#define FbDoMergeRop(src, dst) \ + (((dst) & (((src) & _ca1) ^ _cx1)) ^ (((src) & _ca2) ^ _cx2)) + +#define FbDoDestInvarientMergeRop(src) (((src) & _ca2) ^ _cx2) + +#define FbDoMaskMergeRop(src, dst, mask) \ + (((dst) & ((((src) & _ca1) ^ _cx1) | ~(mask))) ^ ((((src) & _ca2) ^ _cx2) & (mask))) + +#define FbDoLeftMaskByteMergeRop(dst, src, lb, l) { \ + FbBits __xor = ((src) & _ca2) ^ _cx2; \ + FbDoLeftMaskByteRRop(dst,lb,l,((src) & _ca1) ^ _cx1,__xor); \ +} + +#define FbDoRightMaskByteMergeRop(dst, src, rb, r) { \ + FbBits __xor = ((src) & _ca2) ^ _cx2; \ + FbDoRightMaskByteRRop(dst,rb,r,((src) & _ca1) ^ _cx1,__xor); \ +} + +#define FbDoRRop(dst, and, xor) (((dst) & (and)) ^ (xor)) + +#define FbDoMaskRRop(dst, and, xor, mask) \ + (((dst) & ((and) | ~(mask))) ^ (xor & mask)) + +/* + * Take a single bit (0 or 1) and generate a full mask + */ +#define fbFillFromBit(b,t) (~((t) ((b) & 1)-1)) + +#define fbXorT(rop,fg,pm,t) ((((fg) & fbFillFromBit((rop) >> 1,t)) | \ + (~(fg) & fbFillFromBit((rop) >> 3,t))) & (pm)) + +#define fbAndT(rop,fg,pm,t) ((((fg) & fbFillFromBit (rop ^ (rop>>1),t)) | \ + (~(fg) & fbFillFromBit((rop>>2) ^ (rop>>3),t))) | \ + ~(pm)) + +#define fbXor(rop,fg,pm) fbXorT(rop,fg,pm,FbBits) + +#define fbAnd(rop,fg,pm) fbAndT(rop,fg,pm,FbBits) + +#define fbXorStip(rop,fg,pm) fbXorT(rop,fg,pm,FbStip) + +#define fbAndStip(rop,fg,pm) fbAndT(rop,fg,pm,FbStip) + +/* + * Stippling operations; + */ + +extern const FbBits fbStipple16Bits[256]; /* half of table */ +#define FbStipple16Bits(b) \ + (fbStipple16Bits[(b)&0xff] | fbStipple16Bits[(b) >> 8] << FB_HALFUNIT) +extern const FbBits fbStipple8Bits[256]; +extern const FbBits fbStipple4Bits[16]; +extern const FbBits fbStipple2Bits[4]; +extern const FbBits fbStipple1Bits[2]; +extern const FbBits *const fbStippleTable[]; + +#define FbStippleRRop(dst, b, fa, fx, ba, bx) \ + (FbDoRRop(dst, fa, fx) & b) | (FbDoRRop(dst, ba, bx) & ~b) + +#define FbStippleRRopMask(dst, b, fa, fx, ba, bx, m) \ + (FbDoMaskRRop(dst, fa, fx, m) & (b)) | (FbDoMaskRRop(dst, ba, bx, m) & ~(b)) + +#define FbDoLeftMaskByteStippleRRop(dst, b, fa, fx, ba, bx, lb, l) { \ + FbBits __xor = ((fx) & (b)) | ((bx) & ~(b)); \ + FbDoLeftMaskByteRRop(dst, lb, l, ((fa) & (b)) | ((ba) & ~(b)), __xor); \ +} + +#define FbDoRightMaskByteStippleRRop(dst, b, fa, fx, ba, bx, rb, r) { \ + FbBits __xor = ((fx) & (b)) | ((bx) & ~(b)); \ + FbDoRightMaskByteRRop(dst, rb, r, ((fa) & (b)) | ((ba) & ~(b)), __xor); \ +} + +#define FbOpaqueStipple(b, fg, bg) (((fg) & (b)) | ((bg) & ~(b))) + +/* + * Compute rop for using tile code for 1-bit dest stipples; modifies + * existing rop to flip depending on pixel values + */ +#define FbStipple1RopPick(alu,b) (((alu) >> (2 - (((b) & 1) << 1))) & 3) + +#define FbOpaqueStipple1Rop(alu,fg,bg) (FbStipple1RopPick(alu,fg) | \ + (FbStipple1RopPick(alu,bg) << 2)) + +#define FbStipple1Rop(alu,fg) (FbStipple1RopPick(alu,fg) | 4) + +#endif diff --git a/nx-X11/programs/Xserver/fb/fbscreen.c b/nx-X11/programs/Xserver/fb/fbscreen.c new file mode 100644 index 000000000..b0e6d9a6b --- /dev/null +++ b/nx-X11/programs/Xserver/fb/fbscreen.c @@ -0,0 +1,300 @@ +/* $XdotOrg: xc/programs/Xserver/fb/fbscreen.c,v 1.6 2005/07/03 07:01:23 daniels Exp $ + * Id: fbscreen.c,v 1.1 1999/11/02 03:54:45 keithp Exp $ + * + * 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" + +Bool +fbCloseScreen (ScreenPtr pScreen) +{ + int d; + DepthPtr depths = pScreen->allowedDepths; + + for (d = 0; d < pScreen->numDepths; d++) + free (depths[d].vids); + free (depths); + free (pScreen->visuals); + free (pScreen->devPrivate); +#ifdef FB_SCREEN_PRIVATE + free (pScreen->devPrivates[fbScreenPrivateIndex].ptr); +#endif + return TRUE; +} + +Bool +fbRealizeFont(ScreenPtr pScreen, FontPtr pFont) +{ + return (TRUE); +} + +Bool +fbUnrealizeFont(ScreenPtr pScreen, FontPtr pFont) +{ + return (TRUE); +} + +void +fbQueryBestSize (int class, + unsigned short *width, unsigned short *height, + ScreenPtr pScreen) +{ + unsigned short w; + + switch (class) { + case CursorShape: + if (*width > pScreen->width) + *width = pScreen->width; + if (*height > pScreen->height) + *height = pScreen->height; + break; + case TileShape: + case StippleShape: + w = *width; + if ((w & (w - 1)) && w < FB_UNIT) + { + for (w = 1; w < *width; w <<= 1) + ; + *width = w; + } + } +} + +#ifndef FB_OLD_SCREEN +PixmapPtr +_fbGetWindowPixmap (WindowPtr pWindow) +{ + return fbGetWindowPixmap (pWindow); +} + +void +_fbSetWindowPixmap (WindowPtr pWindow, PixmapPtr pPixmap) +{ +#ifdef FB_NO_WINDOW_PIXMAPS + FatalError ("Attempted to set window pixmap without fb support\n"); +#else + pWindow->devPrivates[fbWinPrivateIndex].ptr = (void *) pPixmap; +#endif +} +#endif + +Bool +fbSetupScreen(ScreenPtr pScreen, + void * pbits, /* pointer to screen bitmap */ + int xsize, /* in pixels */ + int ysize, + int dpix, /* dots per inch */ + int dpiy, + int width, /* pixel width of frame buffer */ + int bpp) /* bits per pixel for screen */ +{ + if (!fbAllocatePrivates(pScreen, (int *) 0)) + return FALSE; + pScreen->defColormap = FakeClientID(0); + /* let CreateDefColormap do whatever it wants for pixels */ + pScreen->blackPixel = pScreen->whitePixel = (Pixel) 0; + pScreen->QueryBestSize = fbQueryBestSize; + /* SaveScreen */ + pScreen->GetImage = fbGetImage; + pScreen->GetSpans = fbGetSpans; + pScreen->CreateWindow = fbCreateWindow; + pScreen->DestroyWindow = fbDestroyWindow; + pScreen->PositionWindow = fbPositionWindow; + pScreen->ChangeWindowAttributes = fbChangeWindowAttributes; + pScreen->RealizeWindow = fbMapWindow; + pScreen->UnrealizeWindow = fbUnmapWindow; + pScreen->PaintWindowBackground = fbPaintWindow; + pScreen->PaintWindowBorder = fbPaintWindow; + pScreen->CopyWindow = fbCopyWindow; + pScreen->CreatePixmap = fbCreatePixmap; + pScreen->DestroyPixmap = fbDestroyPixmap; + pScreen->RealizeFont = fbRealizeFont; + pScreen->UnrealizeFont = fbUnrealizeFont; + pScreen->CreateGC = fbCreateGC; + pScreen->CreateColormap = fbInitializeColormap; + pScreen->DestroyColormap = (void (*)(ColormapPtr))NoopDDA; + pScreen->InstallColormap = fbInstallColormap; + pScreen->UninstallColormap = fbUninstallColormap; + pScreen->ListInstalledColormaps = fbListInstalledColormaps; + pScreen->StoreColors = (void (*)(ColormapPtr, int, xColorItem *))NoopDDA; + pScreen->ResolveColor = fbResolveColor; + pScreen->BitmapToRegion = fbPixmapToRegion; + +#ifndef FB_OLD_SCREEN + pScreen->GetWindowPixmap = _fbGetWindowPixmap; + pScreen->SetWindowPixmap = _fbSetWindowPixmap; + + pScreen->BackingStoreFuncs.SaveAreas = fbSaveAreas; + pScreen->BackingStoreFuncs.RestoreAreas = fbRestoreAreas; + pScreen->BackingStoreFuncs.SetClipmaskRgn = 0; + pScreen->BackingStoreFuncs.GetImagePixmap = 0; + pScreen->BackingStoreFuncs.GetSpansPixmap = 0; +#endif + + return TRUE; +} + +Bool +fbFinishScreenInit(ScreenPtr pScreen, + void * pbits, + int xsize, + int ysize, + int dpix, + int dpiy, + int width, + int bpp) +{ + VisualPtr visuals; + DepthPtr depths; + int nvisuals; + int ndepths; + int rootdepth; + VisualID defaultVisual; + int imagebpp = bpp; + +#ifdef FB_DEBUG + int stride; + + ysize -= 2; + stride = (width * bpp) / 8; + fbSetBits ((FbStip *) pbits, + stride / sizeof (FbStip), FB_HEAD_BITS); + pbits = (void *) ((char *) pbits + stride); + fbSetBits ((FbStip *) ((char *) pbits + stride * ysize), + stride / sizeof (FbStip), FB_TAIL_BITS); +#endif + /* + * By default, a 24bpp screen will use 32bpp images, this avoids + * problems with many applications which just can't handle packed + * pixels. If you want real 24bit images, include a 24bpp + * format in the pixmap formats + */ +#ifdef FB_24_32BIT + if (bpp == 24) + { + int f; + + imagebpp = 32; + /* + * Check to see if we're advertising a 24bpp image format, + * in which case windows will use it in preference to a 32 bit + * format. + */ + for (f = 0; f < screenInfo.numPixmapFormats; f++) + { + if (screenInfo.formats[f].bitsPerPixel == 24) + { + imagebpp = 24; + break; + } + } + } +#endif +#ifdef FB_SCREEN_PRIVATE + if (imagebpp == 32) + { + fbGetScreenPrivate(pScreen)->win32bpp = bpp; + fbGetScreenPrivate(pScreen)->pix32bpp = bpp; + } + else + { + fbGetScreenPrivate(pScreen)->win32bpp = 32; + fbGetScreenPrivate(pScreen)->pix32bpp = 32; + } +#endif + rootdepth = 0; + if (!fbInitVisuals (&visuals, &depths, &nvisuals, &ndepths, &rootdepth, + &defaultVisual,((unsigned long)1<<(imagebpp-1)), 8)) + return FALSE; + if (! miScreenInit(pScreen, pbits, xsize, ysize, dpix, dpiy, width, + rootdepth, ndepths, depths, + defaultVisual, nvisuals, visuals +#ifdef FB_OLD_MISCREENINIT + , (miBSFuncPtr) 0 +#endif + )) + return FALSE; + /* overwrite miCloseScreen with our own */ + pScreen->CloseScreen = fbCloseScreen; +#ifdef FB_24_32BIT + if (bpp == 24 && imagebpp == 32) + { + pScreen->ModifyPixmapHeader = fb24_32ModifyPixmapHeader; + pScreen->CreateScreenResources = fb24_32CreateScreenResources; + } +#endif +#if 0 + /* leave backing store initialization to the enclosing code so + * it can choose the correct order of wrappers + */ + /* init backing store here so we can overwrite CloseScreen without stepping + * on the backing store wrapped version */ + fbInitializeBackingStore (pScreen); +#endif + return TRUE; +} + +/* dts * (inch/dot) * (25.4 mm / inch) = mm */ +Bool +fbScreenInit(ScreenPtr pScreen, + void * pbits, + int xsize, + int ysize, + int dpix, + int dpiy, + int width, + int bpp) +{ + if (!fbSetupScreen(pScreen, pbits, xsize, ysize, dpix, dpiy, width, bpp)) + return FALSE; + if (!fbFinishScreenInit(pScreen, pbits, xsize, ysize, dpix, dpiy, + width, bpp)) + return FALSE; + return TRUE; +} + + +#ifdef FB_OLD_SCREEN +const miBSFuncRec fbBSFuncRec = { + fbSaveAreas, + fbRestoreAreas, + (void (*)(GCPtr, RegionPtr)) 0, + (PixmapPtr (*)(void)) 0, + (PixmapPtr (*)(void)) 0, +}; +#endif + +#if 0 +void +fbInitializeBackingStore (ScreenPtr pScreen) +{ +#ifdef FB_OLD_SCREEN + miInitializeBackingStore (pScreen, (miBSFuncRec *) &fbBSFuncRec); +#else + miInitializeBackingStore (pScreen); +#endif +} +#endif diff --git a/nx-X11/programs/Xserver/fb/fbseg.c b/nx-X11/programs/Xserver/fb/fbseg.c new file mode 100644 index 000000000..db3240e1b --- /dev/null +++ b/nx-X11/programs/Xserver/fb/fbseg.c @@ -0,0 +1,728 @@ +/* + * Id: fbseg.c,v 1.1 1999/11/02 03:54:45 keithp Exp $ + * + * 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 <stdlib.h> + +#include "fb.h" +#include "miline.h" + +#define fbBresShiftMask(mask,dir,bpp) ((bpp == FB_STIP_UNIT) ? 0 : \ + ((dir < 0) ? FbStipLeft(mask,bpp) : \ + FbStipRight(mask,bpp))) + +void +fbBresSolid (DrawablePtr pDrawable, + GCPtr pGC, + int dashOffset, + int signdx, + int signdy, + int axis, + int x1, + int y1, + int e, + int e1, + int e3, + int len) +{ + FbStip *dst; + FbStride dstStride; + int dstBpp; + int dstXoff, dstYoff; + FbGCPrivPtr pPriv = fbGetGCPrivate (pGC); + FbStip and = (FbStip) pPriv->and; + FbStip xor = (FbStip) pPriv->xor; + FbStip mask, mask0; + FbStip bits; + + fbGetStipDrawable (pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff); + dst += ((y1 + dstYoff) * dstStride); + x1 = (x1 + dstXoff) * dstBpp; + dst += x1 >> FB_STIP_SHIFT; + x1 &= FB_STIP_MASK; + mask0 = FbStipMask(0, dstBpp); + mask = FbStipRight (mask0, x1); + if (signdx < 0) + mask0 = FbStipRight (mask0, FB_STIP_UNIT - dstBpp); + if (signdy < 0) + dstStride = -dstStride; + if (axis == X_AXIS) + { + bits = 0; + while (len--) + { + bits |= mask; + mask = fbBresShiftMask(mask,signdx,dstBpp); + if (!mask) + { + *dst = FbDoMaskRRop (*dst, and, xor, bits); + bits = 0; + dst += signdx; + mask = mask0; + } + e += e1; + if (e >= 0) + { + *dst = FbDoMaskRRop (*dst, and, xor, bits); + bits = 0; + dst += dstStride; + e += e3; + } + } + if (bits) + *dst = FbDoMaskRRop (*dst, and, xor, bits); + } + else + { + while (len--) + { + *dst = FbDoMaskRRop (*dst, and, xor, mask); + dst += dstStride; + e += e1; + if (e >= 0) + { + e += e3; + mask = fbBresShiftMask(mask,signdx,dstBpp); + if (!mask) + { + dst += signdx; + mask = mask0; + } + } + } + } +} + +void +fbBresDash (DrawablePtr pDrawable, + GCPtr pGC, + int dashOffset, + int signdx, + int signdy, + int axis, + int x1, + int y1, + int e, + int e1, + int e3, + int len) +{ + FbStip *dst; + FbStride dstStride; + int dstBpp; + int dstXoff, dstYoff; + FbGCPrivPtr pPriv = fbGetGCPrivate (pGC); + FbStip and = (FbStip) pPriv->and; + FbStip xor = (FbStip) pPriv->xor; + FbStip bgand = (FbStip) pPriv->bgand; + FbStip bgxor = (FbStip) pPriv->bgxor; + FbStip mask, mask0; + FbDashDeclare; + int dashlen; + Bool even; + Bool doOdd; + + fbGetStipDrawable (pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff); + doOdd = pGC->lineStyle == LineDoubleDash; + + FbDashInit (pGC, pPriv, dashOffset, dashlen, even); + + dst += ((y1 + dstYoff) * dstStride); + x1 = (x1 + dstXoff) * dstBpp; + dst += x1 >> FB_STIP_SHIFT; + x1 &= FB_STIP_MASK; + mask0 = FbStipMask(0, dstBpp); + mask = FbStipRight (mask0, x1); + if (signdx < 0) + mask0 = FbStipRight (mask0, FB_STIP_UNIT - dstBpp); + if (signdy < 0) + dstStride = -dstStride; + while (len--) + { + if (even) + *dst = FbDoMaskRRop (*dst, and, xor, mask); + else if (doOdd) + *dst = FbDoMaskRRop (*dst, bgand, bgxor, mask); + if (axis == X_AXIS) + { + mask = fbBresShiftMask(mask,signdx,dstBpp); + if (!mask) + { + dst += signdx; + mask = mask0; + } + e += e1; + if (e >= 0) + { + dst += dstStride; + e += e3; + } + } + else + { + dst += dstStride; + e += e1; + if (e >= 0) + { + e += e3; + mask = fbBresShiftMask(mask,signdx,dstBpp); + if (!mask) + { + dst += signdx; + mask = mask0; + } + } + } + FbDashStep (dashlen, even); + } +} + +void +fbBresFill (DrawablePtr pDrawable, + GCPtr pGC, + int dashOffset, + int signdx, + int signdy, + int axis, + int x1, + int y1, + int e, + int e1, + int e3, + int len) +{ + while (len--) + { + fbFill (pDrawable, pGC, x1, y1, 1, 1); + if (axis == X_AXIS) + { + x1 += signdx; + e += e1; + if (e >= 0) + { + e += e3; + y1 += signdy; + } + } + else + { + y1 += signdy; + e += e1; + if (e >= 0) + { + e += e3; + x1 += signdx; + } + } + } +} + +static void +fbSetFg (DrawablePtr pDrawable, + GCPtr pGC, + Pixel fg) +{ + if (fg != pGC->fgPixel) + { + DoChangeGC (pGC, GCForeground, (XID *) &fg, FALSE); + ValidateGC (pDrawable, pGC); + } +} + +void +fbBresFillDash (DrawablePtr pDrawable, + GCPtr pGC, + int dashOffset, + int signdx, + int signdy, + int axis, + int x1, + int y1, + int e, + int e1, + int e3, + int len) +{ + FbGCPrivPtr pPriv = fbGetGCPrivate (pGC); + FbDashDeclare; + int dashlen; + Bool even; + Bool doOdd; + Bool doBg; + Pixel fg, bg; + + fg = pGC->fgPixel; + bg = pGC->bgPixel; + + /* whether to fill the odd dashes */ + doOdd = pGC->lineStyle == LineDoubleDash; + /* whether to switch fg to bg when filling odd dashes */ + doBg = doOdd && (pGC->fillStyle == FillSolid || + pGC->fillStyle == FillStippled); + + /* compute current dash position */ + FbDashInit (pGC, pPriv, dashOffset, dashlen, even); + + while (len--) + { + if (even || doOdd) + { + if (doBg) + { + if (even) + fbSetFg (pDrawable, pGC, fg); + else + fbSetFg (pDrawable, pGC, bg); + } + fbFill (pDrawable, pGC, x1, y1, 1, 1); + } + if (axis == X_AXIS) + { + x1 += signdx; + e += e1; + if (e >= 0) + { + e += e3; + y1 += signdy; + } + } + else + { + y1 += signdy; + e += e1; + if (e >= 0) + { + e += e3; + x1 += signdx; + } + } + FbDashStep (dashlen, even); + } + if (doBg) + fbSetFg (pDrawable, pGC, fg); +} + +#ifdef FB_24BIT +static void +fbBresSolid24RRop (DrawablePtr pDrawable, + GCPtr pGC, + int dashOffset, + int signdx, + int signdy, + int axis, + int x1, + int y1, + int e, + int e1, + int e3, + int len) +{ + FbStip *dst; + FbStride dstStride; + int dstBpp; + int dstXoff, dstYoff; + FbGCPrivPtr pPriv = fbGetGCPrivate (pGC); + FbStip and = pPriv->and; + FbStip xor = pPriv->xor; + FbStip leftMask, rightMask; + int nl; + FbStip *d; + int x; + int rot; + FbStip andT, xorT; + + fbGetStipDrawable (pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff); + dst += ((y1 + dstYoff) * dstStride); + x1 = (x1 + dstXoff) * 24; + if (signdy < 0) + dstStride = -dstStride; + signdx *= 24; + while (len--) + { + d = dst + (x1 >> FB_STIP_SHIFT); + x = x1 & FB_STIP_MASK; + rot = FbFirst24Rot (x); + andT = FbRot24Stip(and,rot); + xorT = FbRot24Stip(xor,rot); + FbMaskStip (x, 24, leftMask, nl, rightMask); + if (leftMask) + { + *d = FbDoMaskRRop (*d, andT, xorT, leftMask); + d++; + andT = FbNext24Stip (andT); + xorT = FbNext24Stip (xorT); + } + if (rightMask) + *d = FbDoMaskRRop (*d, andT, xorT, rightMask); + if (axis == X_AXIS) + { + x1 += signdx; + e += e1; + if (e >= 0) + { + e += e3; + dst += dstStride; + } + } + else + { + dst += dstStride; + e += e1; + if (e >= 0) + { + e += e3; + x1 += signdx; + } + } + } +} + +static void +fbBresDash24RRop (DrawablePtr pDrawable, + GCPtr pGC, + int dashOffset, + int signdx, + int signdy, + int axis, + int x1, + int y1, + int e, + int e1, + int e3, + int len) +{ + FbStip *dst; + FbStride dstStride; + int dstBpp; + int dstXoff, dstYoff; + FbGCPrivPtr pPriv = fbGetGCPrivate (pGC); + FbStip andT, xorT; + FbStip fgand = pPriv->and; + FbStip fgxor = pPriv->xor; + FbStip bgand = pPriv->bgand; + FbStip bgxor = pPriv->bgxor; + FbStip leftMask, rightMask; + int nl; + FbStip *d; + int x; + int rot; + FbDashDeclare; + int dashlen; + Bool even; + Bool doOdd; + + fbGetStipDrawable (pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff); + doOdd = pGC->lineStyle == LineDoubleDash; + + /* compute current dash position */ + FbDashInit(pGC, pPriv, dashOffset, dashlen, even); + + dst += ((y1 + dstYoff) * dstStride); + x1 = (x1 + dstXoff) * 24; + if (signdy < 0) + dstStride = -dstStride; + signdx *= 24; + while (len--) + { + if (even || doOdd) + { + if (even) + { + andT = fgand; + xorT = fgxor; + } + else + { + andT = bgand; + xorT = bgxor; + } + d = dst + (x1 >> FB_STIP_SHIFT); + x = x1 & FB_STIP_MASK; + rot = FbFirst24Rot (x); + andT = FbRot24Stip (andT, rot); + xorT = FbRot24Stip (xorT, rot); + FbMaskStip (x, 24, leftMask, nl, rightMask); + if (leftMask) + { + *d = FbDoMaskRRop (*d, andT, xorT, leftMask); + d++; + andT = FbNext24Stip (andT); + xorT = FbNext24Stip (xorT); + } + if (rightMask) + *d = FbDoMaskRRop (*d, andT, xorT, rightMask); + } + if (axis == X_AXIS) + { + x1 += signdx; + e += e1; + if (e >= 0) + { + e += e3; + dst += dstStride; + } + } + else + { + dst += dstStride; + e += e1; + if (e >= 0) + { + e += e3; + x1 += signdx; + } + } + FbDashStep (dashlen, even); + } +} +#endif + +/* + * For drivers that want to bail drawing some lines, this + * function takes care of selecting the appropriate rasterizer + * based on the contents of the specified GC. + */ + +FbBres * +fbSelectBres (DrawablePtr pDrawable, + GCPtr pGC) +{ + FbGCPrivPtr pPriv = fbGetGCPrivate(pGC); + int dstBpp = pDrawable->bitsPerPixel; + FbBres * bres; + + if (pGC->lineStyle == LineSolid) + { + bres = fbBresFill; + if (pGC->fillStyle == FillSolid) + { + bres = fbBresSolid; +#ifdef FB_24BIT + if (dstBpp == 24) + bres = fbBresSolid24RRop; +#endif +#ifndef FBNOPIXADDR + if (pPriv->and == 0) + { + switch (dstBpp) { + case 8: bres = fbBresSolid8; break; + case 16: bres = fbBresSolid16; break; +#ifdef FB_24BIT + case 24: bres = fbBresSolid24; break; +#endif + case 32: bres = fbBresSolid32; break; + } + } +#endif + } + } + else + { + bres = fbBresFillDash; + if (pGC->fillStyle == FillSolid) + { + bres = fbBresDash; +#ifdef FB_24BIT + if (dstBpp == 24) + bres = fbBresDash24RRop; +#endif +#ifndef FBNOPIXADDR + if (pPriv->and == 0 && + (pGC->lineStyle == LineOnOffDash || pPriv->bgand == 0)) + { + switch (dstBpp) { + case 8: bres = fbBresDash8; break; + case 16: bres = fbBresDash16; break; +#ifdef FB_24BIT + case 24: bres = fbBresDash24; break; +#endif + case 32: bres = fbBresDash32; break; + } + } +#endif + } + } + return bres; +} + +void +fbBres (DrawablePtr pDrawable, + GCPtr pGC, + int dashOffset, + int signdx, + int signdy, + int axis, + int x1, + int y1, + int e, + int e1, + int e3, + int len) +{ + (*fbSelectBres (pDrawable, pGC)) (pDrawable, pGC, dashOffset, + signdx, signdy, axis, x1, y1, + e, e1, e3, len); +} + +void +fbSegment (DrawablePtr pDrawable, + GCPtr pGC, + int x1, + int y1, + int x2, + int y2, + Bool drawLast, + int *dashOffset) +{ + FbBres * bres; + RegionPtr pClip = fbGetCompositeClip(pGC); + BoxPtr pBox; + int nBox; + int adx; /* abs values of dx and dy */ + int ady; + int signdx; /* sign of dx and dy */ + int signdy; + int e, e1, e2, e3; /* bresenham error and increments */ + int len; /* length of segment */ + int axis; /* major axis */ + int octant; + int dashoff; + int doff; + unsigned int bias = miGetZeroLineBias(pDrawable->pScreen); + unsigned int oc1; /* outcode of point 1 */ + unsigned int oc2; /* outcode of point 2 */ + + nBox = RegionNumRects (pClip); + pBox = RegionRects (pClip); + + bres = fbSelectBres (pDrawable, pGC); + + CalcLineDeltas(x1, y1, x2, y2, adx, ady, signdx, signdy, + 1, 1, octant); + + if (adx > ady) + { + axis = X_AXIS; + e1 = ady << 1; + e2 = e1 - (adx << 1); + e = e1 - adx; + len = adx; + } + else + { + axis = Y_AXIS; + e1 = adx << 1; + e2 = e1 - (ady << 1); + e = e1 - ady; + SetYMajorOctant(octant); + len = ady; + } + + FIXUP_ERROR (e, octant, bias); + + /* + * Adjust error terms to compare against zero + */ + e3 = e2 - e1; + e = e - e1; + + /* we have bresenham parameters and two points. + all we have to do now is clip and draw. + */ + + if (drawLast) + len++; + dashoff = *dashOffset; + *dashOffset = dashoff + len; + while(nBox--) + { + oc1 = 0; + oc2 = 0; + OUTCODES(oc1, x1, y1, pBox); + OUTCODES(oc2, x2, y2, pBox); + if ((oc1 | oc2) == 0) + { + (*bres) (pDrawable, pGC, dashoff, + signdx, signdy, axis, x1, y1, + e, e1, e3, len); + break; + } + else if (oc1 & oc2) + { + pBox++; + } + else + { + int new_x1 = x1, new_y1 = y1, new_x2 = x2, new_y2 = y2; + int clip1 = 0, clip2 = 0; + int clipdx, clipdy; + int err; + + if (miZeroClipLine(pBox->x1, pBox->y1, pBox->x2-1, + pBox->y2-1, + &new_x1, &new_y1, &new_x2, &new_y2, + adx, ady, &clip1, &clip2, + octant, bias, oc1, oc2) == -1) + { + pBox++; + continue; + } + + if (axis == X_AXIS) + len = abs(new_x2 - new_x1); + else + len = abs(new_y2 - new_y1); + if (clip2 != 0 || drawLast) + len++; + if (len) + { + /* unwind bresenham error term to first point */ + doff = dashoff; + err = e; + if (clip1) + { + clipdx = abs(new_x1 - x1); + clipdy = abs(new_y1 - y1); + if (axis == X_AXIS) + { + doff += clipdx; + err += e3 * clipdy + e1 * clipdx; + } + else + { + doff += clipdy; + err += e3 * clipdx + e1 * clipdy; + } + } + (*bres) (pDrawable, pGC, doff, + signdx, signdy, axis, new_x1, new_y1, + err, e1, e3, len); + } + pBox++; + } + } /* while (nBox--) */ +} diff --git a/nx-X11/programs/Xserver/fb/fbsetsp.c b/nx-X11/programs/Xserver/fb/fbsetsp.c new file mode 100644 index 000000000..4b3db1eda --- /dev/null +++ b/nx-X11/programs/Xserver/fb/fbsetsp.c @@ -0,0 +1,103 @@ +/* + * Id: fbsetsp.c,v 1.1 1999/11/02 03:54:45 keithp Exp $ + * + * 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 +fbSetSpans (DrawablePtr pDrawable, + GCPtr pGC, + char *src, + DDXPointPtr ppt, + int *pwidth, + int nspans, + int fSorted) +{ + FbGCPrivPtr pPriv = fbGetGCPrivate (pGC); + RegionPtr pClip = fbGetCompositeClip(pGC); + FbBits *dst, *d, *s; + FbStride dstStride; + int dstBpp; + int dstXoff, dstYoff; + BoxPtr pbox; + int n; + int xoff; + int x1, x2; + +#ifdef FB_24_32BIT + if (pDrawable->bitsPerPixel != BitsPerPixel(pDrawable->depth)) + { + fb24_32SetSpans (pDrawable, pGC, src, ppt, pwidth, nspans, fSorted); + return; + } +#endif + fbGetDrawable (pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff); + while (nspans--) + { + d = dst + (ppt->y + dstYoff) * dstStride; + xoff = (int) (((long) src) & (FB_MASK >> 3)); + s = (FbBits *) (src - xoff); + xoff <<= 3; + n = RegionNumRects(pClip); + pbox = RegionRects (pClip); + while (n--) + { + if (pbox->y1 > ppt->y) + break; + if (pbox->y2 > ppt->y) + { + x1 = ppt->x; + x2 = x1 + *pwidth; + if (pbox->x1 > x1) + x1 = pbox->x1; + if (pbox->x2 < x2) + x2 = pbox->x2; + if (x1 < x2) + fbBlt ((FbBits *) s, + 0, + (x1 - ppt->x) * dstBpp + xoff, + d, + dstStride, + (x1 + dstXoff) * dstBpp, + + (x2 - x1) * dstBpp, + 1, + pGC->alu, + pPriv->pm, + dstBpp, + + FALSE, + FALSE); + } + } + src += PixmapBytePad (*pwidth, pDrawable->depth); + ppt++; + pwidth++; + } + fbValidateDrawable (pDrawable); +} + diff --git a/nx-X11/programs/Xserver/fb/fbsolid.c b/nx-X11/programs/Xserver/fb/fbsolid.c new file mode 100644 index 000000000..99e479f49 --- /dev/null +++ b/nx-X11/programs/Xserver/fb/fbsolid.c @@ -0,0 +1,213 @@ +/* + * 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. + */ + +#define FbSelectPart(xor,o,t) xor + +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#endif + +#include "fb.h" + +void +fbSolid (FbBits *dst, + FbStride dstStride, + int dstX, + int bpp, + + int width, + int height, + + FbBits and, + FbBits xor) +{ + FbBits startmask, endmask; + int n, nmiddle; + int startbyte, endbyte; + +#ifdef FB_24BIT + if (bpp == 24 && (!FbCheck24Pix(and) || !FbCheck24Pix(xor))) + { + fbSolid24 (dst, dstStride, dstX, width, height, and, xor); + return; + } +#endif + dst += dstX >> FB_SHIFT; + dstX &= FB_MASK; + FbMaskBitsBytes(dstX, width, and == 0, startmask, startbyte, + nmiddle, endmask, endbyte); + if (startmask) + dstStride--; + dstStride -= nmiddle; + while (height--) + { + if (startmask) + { + FbDoLeftMaskByteRRop(dst,startbyte,startmask,and,xor); + dst++; + } + n = nmiddle; + if (!and) + while (n--) + *dst++ = xor; + else + while (n--) + { + *dst = FbDoRRop (*dst, and, xor); + dst++; + } + if (endmask) + FbDoRightMaskByteRRop(dst,endbyte,endmask,and,xor); + dst += dstStride; + } +} + +#ifdef FB_24BIT +void +fbSolid24 (FbBits *dst, + FbStride dstStride, + int dstX, + + int width, + int height, + + FbBits and, + FbBits xor) +{ + FbBits startmask, endmask; + FbBits xor0 = 0, xor1 = 0, xor2 = 0; + FbBits and0 = 0, and1 = 0, and2 = 0; + FbBits xorS = 0, andS = 0, xorE = 0, andE = 0; + int n, nmiddle; + int rotS, rot; + + dst += dstX >> FB_SHIFT; + dstX &= FB_MASK; + /* + * Rotate pixel values this far across the word to align on + * screen pixel boundaries + */ + rot = FbFirst24Rot (dstX); + FbMaskBits (dstX, width, startmask, nmiddle, endmask); + if (startmask) + dstStride--; + dstStride -= nmiddle; + + /* + * Precompute rotated versions of the rasterop values + */ + rotS = rot; + xor = FbRot24(xor,rotS); + and = FbRot24(and,rotS); + if (startmask) + { + xorS = xor; + andS = and; + xor = FbNext24Pix(xor); + and = FbNext24Pix(and); + } + + if (nmiddle) + { + xor0 = xor; + and0 = and; + xor1 = FbNext24Pix(xor0); + and1 = FbNext24Pix(and0); + xor2 = FbNext24Pix(xor1); + and2 = FbNext24Pix(and1); + } + + if (endmask) + { + switch (nmiddle % 3) { + case 0: + xorE = xor; + andE = and; + break; + case 1: + xorE = xor1; + andE = and1; + break; + case 2: + xorE = xor2; + andE = and2; + break; + } + } + + while (height--) + { + if (startmask) + { + *dst = FbDoMaskRRop(*dst, andS, xorS, startmask); + dst++; + } + n = nmiddle; + if (!and0) + { + while (n >= 3) + { + *dst++ = xor0; + *dst++ = xor1; + *dst++ = xor2; + n -= 3; + } + if (n) + { + *dst++ = xor0; + n--; + if (n) + { + *dst++ = xor1; + } + } + } + else + { + while (n >= 3) + { + *dst = FbDoRRop (*dst, and0, xor0); + dst++; + *dst = FbDoRRop (*dst, and1, xor1); + dst++; + *dst = FbDoRRop (*dst, and2, xor2); + dst++; + n -= 3; + } + if (n) + { + *dst = FbDoRRop (*dst, and0, xor0); + dst++; + n--; + if (n) + { + *dst = FbDoRRop (*dst, and1, xor1); + dst++; + } + } + } + if (endmask) + *dst = FbDoMaskRRop (*dst, andE, xorE, endmask); + dst += dstStride; + } +} +#endif diff --git a/nx-X11/programs/Xserver/fb/fbstipple.c b/nx-X11/programs/Xserver/fb/fbstipple.c new file mode 100644 index 000000000..486fa2030 --- /dev/null +++ b/nx-X11/programs/Xserver/fb/fbstipple.c @@ -0,0 +1,315 @@ +/* + * Id: fbstipple.c,v 1.1 1999/11/02 03:54:45 keithp Exp $ + * + * 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" + +#ifndef FBNOPIXADDR +/* + * This is a slight abuse of the preprocessor to generate repetitive + * code, the idea is to generate code for each case of a copy-mode + * transparent stipple + */ +#define LaneCases1(c,a) case c: \ + while (n--) { (void)FbLaneCase(c,a); a++; } \ + break +#define LaneCases2(c,a) LaneCases1(c,a); LaneCases1(c+1,a) +#define LaneCases4(c,a) LaneCases2(c,a); LaneCases2(c+2,a) +#define LaneCases8(c,a) LaneCases4(c,a); LaneCases4(c+4,a) +#define LaneCases16(c,a) LaneCases8(c,a); LaneCases8(c+8,a) +#define LaneCases32(c,a) LaneCases16(c,a); LaneCases16(c+16,a) +#define LaneCases64(c,a) LaneCases32(c,a); LaneCases32(c+32,a) +#define LaneCases128(c,a) LaneCases64(c,a); LaneCases64(c+64,a) +#define LaneCases256(c,a) LaneCases128(c,a); LaneCases128(c+128,a) + +#if FB_SHIFT == 6 +#define LaneCases(a) LaneCases256(0,a) +#endif + +#if FB_SHIFT == 5 +#define LaneCases(a) LaneCases16(0,a) +#endif + +/* + * Repeat a transparent stipple across a scanline n times + */ + +void +fbTransparentSpan (FbBits *dst, + FbBits stip, + FbBits fgxor, + int n) +{ + FbStip s; + + s = ((FbStip) (stip ) & 0x01); + s |= ((FbStip) (stip >> 8) & 0x02); + s |= ((FbStip) (stip >> 16) & 0x04); + s |= ((FbStip) (stip >> 24) & 0x08); +#if FB_SHIFT > 5 + s |= ((FbStip) (stip >> 32) & 0x10); + s |= ((FbStip) (stip >> 40) & 0x20); + s |= ((FbStip) (stip >> 48) & 0x40); + s |= ((FbStip) (stip >> 56) & 0x80); +#endif + switch (s) { + LaneCases(dst); + } +} +#endif + +void +fbEvenStipple (FbBits *dst, + FbStride dstStride, + int dstX, + int dstBpp, + + int width, + int height, + + FbStip *stip, + FbStride stipStride, + int stipHeight, + + FbBits fgand, + FbBits fgxor, + FbBits bgand, + FbBits bgxor, + + int xRot, + int yRot) +{ + FbBits startmask, endmask; + FbBits mask, and, xor; + int nmiddle, n; + FbStip *s, *stipEnd, bits; + int rot, stipX, stipY; + int pixelsPerDst; + const FbBits *fbBits; + Bool transparent; + int startbyte, endbyte; + + /* + * Check for a transparent stipple (stencil) + */ + transparent = FALSE; + if (dstBpp >= 8 && + fgand == 0 && bgand == FB_ALLONES && bgxor == 0) + transparent = TRUE; + + pixelsPerDst = FB_UNIT / dstBpp; + /* + * Adjust dest pointers + */ + dst += dstX >> FB_SHIFT; + dstX &= FB_MASK; + FbMaskBitsBytes (dstX, width, fgand == 0 && bgand == 0, + startmask, startbyte, nmiddle, endmask, endbyte); + + if (startmask) + dstStride--; + dstStride -= nmiddle; + + xRot *= dstBpp; + /* + * Compute stip start scanline and rotation parameters + */ + stipEnd = stip + stipStride * stipHeight; + modulus (- yRot, stipHeight, stipY); + s = stip + stipStride * stipY; + modulus (- xRot, FB_UNIT, stipX); + rot = stipX; + + /* + * Get pointer to stipple mask array for this depth + */ + fbBits = 0; /* unused */ + if (pixelsPerDst <= 8) + fbBits = fbStippleTable[pixelsPerDst]; + + while (height--) + { + /* + * Extract stipple bits for this scanline; + */ + bits = *s; + s += stipStride; + if (s == stipEnd) + s = stip; +#if FB_UNIT > 32 + if (pixelsPerDst == 16) + mask = FbStipple16Bits(FbLeftStipBits(bits,16)); + else +#endif + mask = fbBits[FbLeftStipBits(bits,pixelsPerDst)]; + /* + * Rotate into position and compute reduced rop values + */ + mask = FbRotLeft(mask, rot); + and = (fgand & mask) | (bgand & ~mask); + xor = (fgxor & mask) | (bgxor & ~mask); + +#ifndef FBNOPIXADDR + if (transparent) + { + if (startmask) + { + fbTransparentSpan(dst, mask&startmask, fgxor, 1); + dst++; + } + fbTransparentSpan (dst, mask, fgxor, nmiddle); + dst += nmiddle; + if (endmask) + fbTransparentSpan(dst, mask&endmask, fgxor, 1); + } + else +#endif + { + /* + * Fill scanline + */ + if (startmask) + { + FbDoLeftMaskByteRRop (dst, startbyte, startmask, and, xor); + dst++; + } + n = nmiddle; + if (!and) + while (n--) + *dst++ = xor; + else + { + while (n--) + { + *dst = FbDoRRop (*dst, and, xor); + dst++; + } + } + if (endmask) + FbDoRightMaskByteRRop(dst, endbyte, endmask, and, xor); + } + dst += dstStride; + } +} + +void +fbOddStipple (FbBits *dst, + FbStride dstStride, + int dstX, + int dstBpp, + + int width, + int height, + + FbStip *stip, + FbStride stipStride, + int stipWidth, + int stipHeight, + + FbBits fgand, + FbBits fgxor, + FbBits bgand, + FbBits bgxor, + + int xRot, + int yRot) +{ + int stipX, stipY, sx; + int widthTmp; + int h, w; + int x, y; + + modulus (- yRot, stipHeight, stipY); + modulus (dstX / dstBpp - xRot, stipWidth, stipX); + y = 0; + while (height) + { + h = stipHeight - stipY; + if (h > height) + h = height; + height -= h; + widthTmp = width; + x = dstX; + sx = stipX; + while (widthTmp) + { + w = (stipWidth - sx) * dstBpp; + if (w > widthTmp) + w = widthTmp; + widthTmp -= w; + fbBltOne (stip + stipY * stipStride, + stipStride, + sx, + + dst + y * dstStride, + dstStride, + x, + dstBpp, + + w, h, + + fgand, fgxor, bgand, bgxor); + x += w; + sx = 0; + } + y += h; + stipY = 0; + } +} + +void +fbStipple (FbBits *dst, + FbStride dstStride, + int dstX, + int dstBpp, + + int width, + int height, + + FbStip *stip, + FbStride stipStride, + int stipWidth, + int stipHeight, + Bool even, + + FbBits fgand, + FbBits fgxor, + FbBits bgand, + FbBits bgxor, + + int xRot, + int yRot) +{ + if (even) + fbEvenStipple (dst, dstStride, dstX, dstBpp, width, height, + stip, stipStride, stipHeight, + fgand, fgxor, bgand, bgxor, xRot, yRot); + else + fbOddStipple (dst, dstStride, dstX, dstBpp, width, height, + stip, stipStride, stipWidth, stipHeight, + fgand, fgxor, bgand, bgxor, xRot, yRot); +} diff --git a/nx-X11/programs/Xserver/fb/fbtile.c b/nx-X11/programs/Xserver/fb/fbtile.c new file mode 100644 index 000000000..0d0cfe174 --- /dev/null +++ b/nx-X11/programs/Xserver/fb/fbtile.c @@ -0,0 +1,203 @@ +/* + * Id: fbtile.c,v 1.1 1999/11/02 03:54:45 keithp Exp $ + * + * 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" + +/* + * Accelerated tile fill -- tile width is a power of two not greater + * than FB_UNIT + */ + +void +fbEvenTile (FbBits *dst, + FbStride dstStride, + int dstX, + + int width, + int height, + + FbBits *tile, + int tileHeight, + + int alu, + FbBits pm, + int xRot, + int yRot) +{ + FbBits *t, *tileEnd, bits; + FbBits startmask, endmask; + FbBits and, xor; + int n, nmiddle; + int tileX, tileY; + int rot; + int startbyte, endbyte; + + dst += dstX >> FB_SHIFT; + dstX &= FB_MASK; + FbMaskBitsBytes(dstX, width, FbDestInvarientRop(alu, pm), + startmask, startbyte, nmiddle, endmask, endbyte); + if (startmask) + dstStride--; + dstStride -= nmiddle; + + /* + * Compute tile start scanline and rotation parameters + */ + tileEnd = tile + tileHeight; + modulus (- yRot, tileHeight, tileY); + t = tile + tileY; + modulus (- xRot, FB_UNIT, tileX); + rot = tileX; + + while (height--) + { + + /* + * Pick up bits for this scanline + */ + bits = *t++; + if (t == tileEnd) t = tile; + bits = FbRotLeft(bits,rot); + and = fbAnd(alu,bits,pm); + xor = fbXor(alu,bits,pm); + + if (startmask) + { + FbDoLeftMaskByteRRop(dst, startbyte, startmask, and, xor); + dst++; + } + n = nmiddle; + if (!and) + while (n--) + *dst++ = xor; + else + while (n--) + { + *dst = FbDoRRop (*dst, and, xor); + dst++; + } + if (endmask) + FbDoRightMaskByteRRop(dst, endbyte, endmask, and, xor); + dst += dstStride; + } +} + +void +fbOddTile(FbBits *dst, + FbStride dstStride, + int dstX, + + int width, + int height, + + FbBits *tile, + FbStride tileStride, + int tileWidth, + int tileHeight, + + int alu, + FbBits pm, + int bpp, + + int xRot, + int yRot) +{ + int tileX, tileY; + int widthTmp; + int h, w; + int x, y; + + modulus (- yRot, tileHeight, tileY); + y = 0; + while (height) + { + h = tileHeight - tileY; + if (h > height) + h = height; + height -= h; + widthTmp = width; + x = dstX; + modulus (dstX - xRot, tileWidth, tileX); + while (widthTmp) + { + w = tileWidth - tileX; + if (w > widthTmp) + w = widthTmp; + widthTmp -= w; + fbBlt (tile + tileY * tileStride, + tileStride, + tileX, + + dst + y * dstStride, + dstStride, + x, + + w, h, + alu, + pm, + bpp, + + FALSE, + FALSE); + x += w; + tileX = 0; + } + y += h; + tileY = 0; + } +} + +void +fbTile (FbBits *dst, + FbStride dstStride, + int dstX, + + int width, + int height, + + FbBits *tile, + FbStride tileStride, + int tileWidth, + int tileHeight, + + int alu, + FbBits pm, + int bpp, + + int xRot, + int yRot) +{ + if (FbEvenTile (tileWidth)) + fbEvenTile (dst, dstStride, dstX, width, height, + tile, tileHeight, + alu, pm, xRot, yRot); + else + fbOddTile (dst, dstStride, dstX, width, height, + tile, tileStride, tileWidth, tileHeight, + alu, pm, bpp, xRot, yRot); +} diff --git a/nx-X11/programs/Xserver/fb/fbtrap.c b/nx-X11/programs/Xserver/fb/fbtrap.c new file mode 100644 index 000000000..c9951b00d --- /dev/null +++ b/nx-X11/programs/Xserver/fb/fbtrap.c @@ -0,0 +1,240 @@ +/* + * $Id: fbtrap.c,v 1.5 2005/07/03 07:01:23 daniels Exp $ + * + * Copyright © 2004 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" + +#ifdef RENDER + +#include "picturestr.h" +#include "mipict.h" +#include "renderedge.h" +#include "fbpict.h" + +void +fbAddTraps (PicturePtr pPicture, + INT16 x_off, + INT16 y_off, + int ntrap, + xTrap *traps) +{ + FbBits *buf; + int bpp; + int width; + int stride; + int height; + int pxoff, pyoff; + + xFixed x_off_fixed; + xFixed y_off_fixed; + RenderEdge l, r; + xFixed t, b; + + fbGetDrawable (pPicture->pDrawable, buf, stride, bpp, pxoff, pyoff); + + width = pPicture->pDrawable->width; + height = pPicture->pDrawable->height; + x_off += pxoff; + y_off += pyoff; + + x_off_fixed = IntToxFixed(y_off); + y_off_fixed = IntToxFixed(y_off); + + while (ntrap--) + { + t = traps->top.y + y_off_fixed; + if (t < 0) + t = 0; + t = RenderSampleCeilY (t, bpp); + + b = traps->bot.y + y_off_fixed; + if (xFixedToInt (b) >= height) + b = IntToxFixed (height) - 1; + b = RenderSampleFloorY (b, bpp); + + if (b >= t) + { + /* initialize edge walkers */ + RenderEdgeInit (&l, bpp, t, + traps->top.l + x_off_fixed, + traps->top.y + y_off_fixed, + traps->bot.l + x_off_fixed, + traps->bot.y + y_off_fixed); + + RenderEdgeInit (&r, bpp, t, + traps->top.r + x_off_fixed, + traps->top.y + y_off_fixed, + traps->bot.r + x_off_fixed, + traps->bot.y + y_off_fixed); + + fbRasterizeEdges (buf, bpp, width, stride, &l, &r, t, b); + } + traps++; + } +} + +void +fbRasterizeTrapezoid (PicturePtr pPicture, + xTrapezoid *trap, + int x_off, + int y_off) +{ + FbBits *buf; + int bpp; + int width; + int stride; + int height; + int pxoff, pyoff; + + xFixed y_off_fixed; + RenderEdge l, r; + xFixed t, b; + + if (!xTrapezoidValid (trap)) + return; + + fbGetDrawable (pPicture->pDrawable, buf, stride, bpp, pxoff, pyoff); + + width = pPicture->pDrawable->width; + height = pPicture->pDrawable->height; + x_off += pxoff; + y_off += pyoff; + + y_off_fixed = IntToxFixed(y_off); + t = trap->top + y_off_fixed; + if (t < 0) + t = 0; + t = RenderSampleCeilY (t, bpp); + + b = trap->bottom + y_off_fixed; + if (xFixedToInt (b) >= height) + b = IntToxFixed (height) - 1; + b = RenderSampleFloorY (b, bpp); + + if (b >= t) + { + /* initialize edge walkers */ + RenderLineFixedEdgeInit (&l, bpp, t, &trap->left, x_off, y_off); + RenderLineFixedEdgeInit (&r, bpp, t, &trap->right, x_off, y_off); + + fbRasterizeEdges (buf, bpp, width, stride, &l, &r, t, b); + } +} + +static int +_GreaterY (xPointFixed *a, xPointFixed *b) +{ + if (a->y == b->y) + return a->x > b->x; + return a->y > b->y; +} + +/* + * Note that the definition of this function is a bit odd because + * of the X coordinate space (y increasing downwards). + */ +static int +_Clockwise (xPointFixed *ref, xPointFixed *a, xPointFixed *b) +{ + xPointFixed ad, bd; + + ad.x = a->x - ref->x; + ad.y = a->y - ref->y; + bd.x = b->x - ref->x; + bd.y = b->y - ref->y; + + return ((xFixed_32_32) bd.y * ad.x - (xFixed_32_32) ad.y * bd.x) < 0; +} + +/* FIXME -- this could be made more efficient */ +void +fbAddTriangles (PicturePtr pPicture, + INT16 x_off, + INT16 y_off, + int ntri, + xTriangle *tris) +{ + xPointFixed *top, *left, *right, *tmp; + xTrapezoid trap; + + for (; ntri; ntri--, tris++) + { + top = &tris->p1; + left = &tris->p2; + right = &tris->p3; + if (_GreaterY (top, left)) { + tmp = left; left = top; top = tmp; + } + if (_GreaterY (top, right)) { + tmp = right; right = top; top = tmp; + } + if (_Clockwise (top, right, left)) { + tmp = right; right = left; left = tmp; + } + + /* + * Two cases: + * + * + + + * / \ / \ + * / \ / \ + * / + + \ + * / -- -- \ + * / -- -- \ + * / --- --- \ + * +-- --+ + */ + + trap.top = top->y; + trap.left.p1 = *top; + trap.left.p2 = *left; + trap.right.p1 = *top; + trap.right.p2 = *right; + if (right->y < left->y) + trap.bottom = right->y; + else + trap.bottom = left->y; + fbRasterizeTrapezoid (pPicture, &trap, x_off, y_off); + if (right->y < left->y) + { + trap.top = right->y; + trap.bottom = left->y; + trap.right.p1 = *right; + trap.right.p2 = *left; + } + else + { + trap.top = left->y; + trap.bottom = right->y; + trap.left.p1 = *left; + trap.left.p2 = *right; + } + fbRasterizeTrapezoid (pPicture, &trap, x_off, y_off); + } +} + +#endif /* RENDER */ diff --git a/nx-X11/programs/Xserver/fb/fbutil.c b/nx-X11/programs/Xserver/fb/fbutil.c new file mode 100644 index 000000000..4be0f233c --- /dev/null +++ b/nx-X11/programs/Xserver/fb/fbutil.c @@ -0,0 +1,364 @@ +/* + * Id: fbutil.c,v 1.1 1999/11/02 03:54:45 keithp Exp $ + * + * 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" + +FbBits +fbReplicatePixel (Pixel p, int bpp) +{ + FbBits b = p; + + b &= FbFullMask (bpp); + while (bpp < FB_UNIT) + { + b |= b << bpp; + bpp <<= 1; + } + return b; +} + +void +fbReduceRasterOp (int rop, FbBits fg, FbBits pm, FbBits *andp, FbBits *xorp) +{ + FbBits and, xor; + + switch (rop) + { + default: + case GXclear: /* 0 0 0 0 */ + and = 0; + xor = 0; + break; + case GXand: /* 0 0 0 1 */ + and = fg; + xor = 0; + break; + case GXandReverse: /* 0 0 1 0 */ + and = fg; + xor = fg; + break; + case GXcopy: /* 0 0 1 1 */ + and = 0; + xor = fg; + break; + case GXandInverted: /* 0 1 0 0 */ + and = ~fg; + xor = 0; + break; + case GXnoop: /* 0 1 0 1 */ + and = FB_ALLONES; + xor = 0; + break; + case GXxor: /* 0 1 1 0 */ + and = FB_ALLONES; + xor = fg; + break; + case GXor: /* 0 1 1 1 */ + and = ~fg; + xor = fg; + break; + case GXnor: /* 1 0 0 0 */ + and = ~fg; + xor = ~fg; + break; + case GXequiv: /* 1 0 0 1 */ + and = FB_ALLONES; + xor = ~fg; + break; + case GXinvert: /* 1 0 1 0 */ + and = FB_ALLONES; + xor = FB_ALLONES; + break; + case GXorReverse: /* 1 0 1 1 */ + and = ~fg; + xor = FB_ALLONES; + break; + case GXcopyInverted: /* 1 1 0 0 */ + and = 0; + xor = ~fg; + break; + case GXorInverted: /* 1 1 0 1 */ + and = fg; + xor = ~fg; + break; + case GXnand: /* 1 1 1 0 */ + and = fg; + xor = FB_ALLONES; + break; + case GXset: /* 1 1 1 1 */ + and = 0; + xor = FB_ALLONES; + break; + } + and |= ~pm; + xor &= pm; + *andp = and; + *xorp = xor; +} + +#define O 0 +#define I FB_ALLONES + +const FbMergeRopRec FbMergeRopBits[16] = { + { O,O,O,O }, /* clear 0x0 0 */ + { I,O,O,O }, /* and 0x1 src AND dst */ + { I,O,I,O }, /* andReverse 0x2 src AND NOT dst */ + { O,O,I,O }, /* copy 0x3 src */ + { I,I,O,O }, /* andInverted 0x4 NOT src AND dst */ + { O,I,O,O }, /* noop 0x5 dst */ + { O,I,I,O }, /* xor 0x6 src XOR dst */ + { I,I,I,O }, /* or 0x7 src OR dst */ + { I,I,I,I }, /* nor 0x8 NOT src AND NOT dst */ + { O,I,I,I }, /* equiv 0x9 NOT src XOR dst */ + { O,I,O,I }, /* invert 0xa NOT dst */ + { I,I,O,I }, /* orReverse 0xb src OR NOT dst */ + { O,O,I,I }, /* copyInverted 0xc NOT src */ + { I,O,I,I }, /* orInverted 0xd NOT src OR dst */ + { I,O,O,I }, /* nand 0xe NOT src OR NOT dst */ + { O,O,O,I }, /* set 0xf 1 */ +}; + +/* + * Stipple masks are independent of bit/byte order as long + * as bitorder == byteorder. FB doesn't handle the case + * where these differ + */ +#define BitsMask(x,w) ((FB_ALLONES << ((x) & FB_MASK)) & \ + (FB_ALLONES >> ((FB_UNIT - ((x) + (w))) & FB_MASK))) + +#define Mask(x,w) BitsMask((x)*(w),(w)) + + +#define SelMask(b,n,w) ((((b) >> n) & 1) * Mask(n,w)) + +#define C1(b,w) \ + (SelMask(b,0,w)) + +#define C2(b,w) \ + (SelMask(b,0,w) | \ + SelMask(b,1,w)) + +#define C4(b,w) \ + (SelMask(b,0,w) | \ + SelMask(b,1,w) | \ + SelMask(b,2,w) | \ + SelMask(b,3,w)) + +#define C8(b,w) \ + (SelMask(b,0,w) | \ + SelMask(b,1,w) | \ + SelMask(b,2,w) | \ + SelMask(b,3,w) | \ + SelMask(b,4,w) | \ + SelMask(b,5,w) | \ + SelMask(b,6,w) | \ + SelMask(b,7,w)) + +#if FB_UNIT == 16 +#define fbStipple16Bits 0 +#define fbStipple8Bits 0 +const FbBits fbStipple4Bits[16] = { + C4( 0,4), C4( 1,4), C4( 2,4), C4( 3,4), C4( 4,4), C4( 5,4), + C4( 6,4), C4( 7,4), C4( 8,4), C4( 9,4), C4( 10,4), C4( 11,4), + C4( 12,4), C4( 13,4), C4( 14,4), C4( 15,4),}; +const FbBits fbStipple2Bits[4] = { + C2( 0,8), C2( 1,8), C2( 2,8), C2( 3,8), +}; +const FbBits fbStipple1Bits[2] = { + C1( 0,16), C1( 1,16), +}; +#endif +#if FB_UNIT == 32 +#define fbStipple16Bits 0 +const FbBits fbStipple8Bits[256] = { + C8( 0,4), C8( 1,4), C8( 2,4), C8( 3,4), C8( 4,4), C8( 5,4), + C8( 6,4), C8( 7,4), C8( 8,4), C8( 9,4), C8( 10,4), C8( 11,4), + C8( 12,4), C8( 13,4), C8( 14,4), C8( 15,4), C8( 16,4), C8( 17,4), + C8( 18,4), C8( 19,4), C8( 20,4), C8( 21,4), C8( 22,4), C8( 23,4), + C8( 24,4), C8( 25,4), C8( 26,4), C8( 27,4), C8( 28,4), C8( 29,4), + C8( 30,4), C8( 31,4), C8( 32,4), C8( 33,4), C8( 34,4), C8( 35,4), + C8( 36,4), C8( 37,4), C8( 38,4), C8( 39,4), C8( 40,4), C8( 41,4), + C8( 42,4), C8( 43,4), C8( 44,4), C8( 45,4), C8( 46,4), C8( 47,4), + C8( 48,4), C8( 49,4), C8( 50,4), C8( 51,4), C8( 52,4), C8( 53,4), + C8( 54,4), C8( 55,4), C8( 56,4), C8( 57,4), C8( 58,4), C8( 59,4), + C8( 60,4), C8( 61,4), C8( 62,4), C8( 63,4), C8( 64,4), C8( 65,4), + C8( 66,4), C8( 67,4), C8( 68,4), C8( 69,4), C8( 70,4), C8( 71,4), + C8( 72,4), C8( 73,4), C8( 74,4), C8( 75,4), C8( 76,4), C8( 77,4), + C8( 78,4), C8( 79,4), C8( 80,4), C8( 81,4), C8( 82,4), C8( 83,4), + C8( 84,4), C8( 85,4), C8( 86,4), C8( 87,4), C8( 88,4), C8( 89,4), + C8( 90,4), C8( 91,4), C8( 92,4), C8( 93,4), C8( 94,4), C8( 95,4), + C8( 96,4), C8( 97,4), C8( 98,4), C8( 99,4), C8(100,4), C8(101,4), + C8(102,4), C8(103,4), C8(104,4), C8(105,4), C8(106,4), C8(107,4), + C8(108,4), C8(109,4), C8(110,4), C8(111,4), C8(112,4), C8(113,4), + C8(114,4), C8(115,4), C8(116,4), C8(117,4), C8(118,4), C8(119,4), + C8(120,4), C8(121,4), C8(122,4), C8(123,4), C8(124,4), C8(125,4), + C8(126,4), C8(127,4), C8(128,4), C8(129,4), C8(130,4), C8(131,4), + C8(132,4), C8(133,4), C8(134,4), C8(135,4), C8(136,4), C8(137,4), + C8(138,4), C8(139,4), C8(140,4), C8(141,4), C8(142,4), C8(143,4), + C8(144,4), C8(145,4), C8(146,4), C8(147,4), C8(148,4), C8(149,4), + C8(150,4), C8(151,4), C8(152,4), C8(153,4), C8(154,4), C8(155,4), + C8(156,4), C8(157,4), C8(158,4), C8(159,4), C8(160,4), C8(161,4), + C8(162,4), C8(163,4), C8(164,4), C8(165,4), C8(166,4), C8(167,4), + C8(168,4), C8(169,4), C8(170,4), C8(171,4), C8(172,4), C8(173,4), + C8(174,4), C8(175,4), C8(176,4), C8(177,4), C8(178,4), C8(179,4), + C8(180,4), C8(181,4), C8(182,4), C8(183,4), C8(184,4), C8(185,4), + C8(186,4), C8(187,4), C8(188,4), C8(189,4), C8(190,4), C8(191,4), + C8(192,4), C8(193,4), C8(194,4), C8(195,4), C8(196,4), C8(197,4), + C8(198,4), C8(199,4), C8(200,4), C8(201,4), C8(202,4), C8(203,4), + C8(204,4), C8(205,4), C8(206,4), C8(207,4), C8(208,4), C8(209,4), + C8(210,4), C8(211,4), C8(212,4), C8(213,4), C8(214,4), C8(215,4), + C8(216,4), C8(217,4), C8(218,4), C8(219,4), C8(220,4), C8(221,4), + C8(222,4), C8(223,4), C8(224,4), C8(225,4), C8(226,4), C8(227,4), + C8(228,4), C8(229,4), C8(230,4), C8(231,4), C8(232,4), C8(233,4), + C8(234,4), C8(235,4), C8(236,4), C8(237,4), C8(238,4), C8(239,4), + C8(240,4), C8(241,4), C8(242,4), C8(243,4), C8(244,4), C8(245,4), + C8(246,4), C8(247,4), C8(248,4), C8(249,4), C8(250,4), C8(251,4), + C8(252,4), C8(253,4), C8(254,4), C8(255,4), +}; +const FbBits fbStipple4Bits[16] = { + C4( 0,8), C4( 1,8), C4( 2,8), C4( 3,8), C4( 4,8), C4( 5,8), + C4( 6,8), C4( 7,8), C4( 8,8), C4( 9,8), C4( 10,8), C4( 11,8), + C4( 12,8), C4( 13,8), C4( 14,8), C4( 15,8),}; +const FbBits fbStipple2Bits[4] = { + C2( 0,16), C2( 1,16), C2( 2,16), C2( 3,16), +}; +const FbBits fbStipple1Bits[2] = { + C1( 0,32), C1( 1,32), +}; +#endif +#if FB_UNIT == 64 +const FbBits fbStipple16Bits[256] = { + C8( 0,4), C8( 1,4), C8( 2,4), C8( 3,4), C8( 4,4), C8( 5,4), + C8( 6,4), C8( 7,4), C8( 8,4), C8( 9,4), C8( 10,4), C8( 11,4), + C8( 12,4), C8( 13,4), C8( 14,4), C8( 15,4), C8( 16,4), C8( 17,4), + C8( 18,4), C8( 19,4), C8( 20,4), C8( 21,4), C8( 22,4), C8( 23,4), + C8( 24,4), C8( 25,4), C8( 26,4), C8( 27,4), C8( 28,4), C8( 29,4), + C8( 30,4), C8( 31,4), C8( 32,4), C8( 33,4), C8( 34,4), C8( 35,4), + C8( 36,4), C8( 37,4), C8( 38,4), C8( 39,4), C8( 40,4), C8( 41,4), + C8( 42,4), C8( 43,4), C8( 44,4), C8( 45,4), C8( 46,4), C8( 47,4), + C8( 48,4), C8( 49,4), C8( 50,4), C8( 51,4), C8( 52,4), C8( 53,4), + C8( 54,4), C8( 55,4), C8( 56,4), C8( 57,4), C8( 58,4), C8( 59,4), + C8( 60,4), C8( 61,4), C8( 62,4), C8( 63,4), C8( 64,4), C8( 65,4), + C8( 66,4), C8( 67,4), C8( 68,4), C8( 69,4), C8( 70,4), C8( 71,4), + C8( 72,4), C8( 73,4), C8( 74,4), C8( 75,4), C8( 76,4), C8( 77,4), + C8( 78,4), C8( 79,4), C8( 80,4), C8( 81,4), C8( 82,4), C8( 83,4), + C8( 84,4), C8( 85,4), C8( 86,4), C8( 87,4), C8( 88,4), C8( 89,4), + C8( 90,4), C8( 91,4), C8( 92,4), C8( 93,4), C8( 94,4), C8( 95,4), + C8( 96,4), C8( 97,4), C8( 98,4), C8( 99,4), C8(100,4), C8(101,4), + C8(102,4), C8(103,4), C8(104,4), C8(105,4), C8(106,4), C8(107,4), + C8(108,4), C8(109,4), C8(110,4), C8(111,4), C8(112,4), C8(113,4), + C8(114,4), C8(115,4), C8(116,4), C8(117,4), C8(118,4), C8(119,4), + C8(120,4), C8(121,4), C8(122,4), C8(123,4), C8(124,4), C8(125,4), + C8(126,4), C8(127,4), C8(128,4), C8(129,4), C8(130,4), C8(131,4), + C8(132,4), C8(133,4), C8(134,4), C8(135,4), C8(136,4), C8(137,4), + C8(138,4), C8(139,4), C8(140,4), C8(141,4), C8(142,4), C8(143,4), + C8(144,4), C8(145,4), C8(146,4), C8(147,4), C8(148,4), C8(149,4), + C8(150,4), C8(151,4), C8(152,4), C8(153,4), C8(154,4), C8(155,4), + C8(156,4), C8(157,4), C8(158,4), C8(159,4), C8(160,4), C8(161,4), + C8(162,4), C8(163,4), C8(164,4), C8(165,4), C8(166,4), C8(167,4), + C8(168,4), C8(169,4), C8(170,4), C8(171,4), C8(172,4), C8(173,4), + C8(174,4), C8(175,4), C8(176,4), C8(177,4), C8(178,4), C8(179,4), + C8(180,4), C8(181,4), C8(182,4), C8(183,4), C8(184,4), C8(185,4), + C8(186,4), C8(187,4), C8(188,4), C8(189,4), C8(190,4), C8(191,4), + C8(192,4), C8(193,4), C8(194,4), C8(195,4), C8(196,4), C8(197,4), + C8(198,4), C8(199,4), C8(200,4), C8(201,4), C8(202,4), C8(203,4), + C8(204,4), C8(205,4), C8(206,4), C8(207,4), C8(208,4), C8(209,4), + C8(210,4), C8(211,4), C8(212,4), C8(213,4), C8(214,4), C8(215,4), + C8(216,4), C8(217,4), C8(218,4), C8(219,4), C8(220,4), C8(221,4), + C8(222,4), C8(223,4), C8(224,4), C8(225,4), C8(226,4), C8(227,4), + C8(228,4), C8(229,4), C8(230,4), C8(231,4), C8(232,4), C8(233,4), + C8(234,4), C8(235,4), C8(236,4), C8(237,4), C8(238,4), C8(239,4), + C8(240,4), C8(241,4), C8(242,4), C8(243,4), C8(244,4), C8(245,4), + C8(246,4), C8(247,4), C8(248,4), C8(249,4), C8(250,4), C8(251,4), + C8(252,4), C8(253,4), C8(254,4), C8(255,4), +}; +const FbBits fbStipple8Bits[256] = { + C8( 0,8), C8( 1,8), C8( 2,8), C8( 3,8), C8( 4,8), C8( 5,8), + C8( 6,8), C8( 7,8), C8( 8,8), C8( 9,8), C8( 10,8), C8( 11,8), + C8( 12,8), C8( 13,8), C8( 14,8), C8( 15,8), C8( 16,8), C8( 17,8), + C8( 18,8), C8( 19,8), C8( 20,8), C8( 21,8), C8( 22,8), C8( 23,8), + C8( 24,8), C8( 25,8), C8( 26,8), C8( 27,8), C8( 28,8), C8( 29,8), + C8( 30,8), C8( 31,8), C8( 32,8), C8( 33,8), C8( 34,8), C8( 35,8), + C8( 36,8), C8( 37,8), C8( 38,8), C8( 39,8), C8( 40,8), C8( 41,8), + C8( 42,8), C8( 43,8), C8( 44,8), C8( 45,8), C8( 46,8), C8( 47,8), + C8( 48,8), C8( 49,8), C8( 50,8), C8( 51,8), C8( 52,8), C8( 53,8), + C8( 54,8), C8( 55,8), C8( 56,8), C8( 57,8), C8( 58,8), C8( 59,8), + C8( 60,8), C8( 61,8), C8( 62,8), C8( 63,8), C8( 64,8), C8( 65,8), + C8( 66,8), C8( 67,8), C8( 68,8), C8( 69,8), C8( 70,8), C8( 71,8), + C8( 72,8), C8( 73,8), C8( 74,8), C8( 75,8), C8( 76,8), C8( 77,8), + C8( 78,8), C8( 79,8), C8( 80,8), C8( 81,8), C8( 82,8), C8( 83,8), + C8( 84,8), C8( 85,8), C8( 86,8), C8( 87,8), C8( 88,8), C8( 89,8), + C8( 90,8), C8( 91,8), C8( 92,8), C8( 93,8), C8( 94,8), C8( 95,8), + C8( 96,8), C8( 97,8), C8( 98,8), C8( 99,8), C8(100,8), C8(101,8), + C8(102,8), C8(103,8), C8(104,8), C8(105,8), C8(106,8), C8(107,8), + C8(108,8), C8(109,8), C8(110,8), C8(111,8), C8(112,8), C8(113,8), + C8(114,8), C8(115,8), C8(116,8), C8(117,8), C8(118,8), C8(119,8), + C8(120,8), C8(121,8), C8(122,8), C8(123,8), C8(124,8), C8(125,8), + C8(126,8), C8(127,8), C8(128,8), C8(129,8), C8(130,8), C8(131,8), + C8(132,8), C8(133,8), C8(134,8), C8(135,8), C8(136,8), C8(137,8), + C8(138,8), C8(139,8), C8(140,8), C8(141,8), C8(142,8), C8(143,8), + C8(144,8), C8(145,8), C8(146,8), C8(147,8), C8(148,8), C8(149,8), + C8(150,8), C8(151,8), C8(152,8), C8(153,8), C8(154,8), C8(155,8), + C8(156,8), C8(157,8), C8(158,8), C8(159,8), C8(160,8), C8(161,8), + C8(162,8), C8(163,8), C8(164,8), C8(165,8), C8(166,8), C8(167,8), + C8(168,8), C8(169,8), C8(170,8), C8(171,8), C8(172,8), C8(173,8), + C8(174,8), C8(175,8), C8(176,8), C8(177,8), C8(178,8), C8(179,8), + C8(180,8), C8(181,8), C8(182,8), C8(183,8), C8(184,8), C8(185,8), + C8(186,8), C8(187,8), C8(188,8), C8(189,8), C8(190,8), C8(191,8), + C8(192,8), C8(193,8), C8(194,8), C8(195,8), C8(196,8), C8(197,8), + C8(198,8), C8(199,8), C8(200,8), C8(201,8), C8(202,8), C8(203,8), + C8(204,8), C8(205,8), C8(206,8), C8(207,8), C8(208,8), C8(209,8), + C8(210,8), C8(211,8), C8(212,8), C8(213,8), C8(214,8), C8(215,8), + C8(216,8), C8(217,8), C8(218,8), C8(219,8), C8(220,8), C8(221,8), + C8(222,8), C8(223,8), C8(224,8), C8(225,8), C8(226,8), C8(227,8), + C8(228,8), C8(229,8), C8(230,8), C8(231,8), C8(232,8), C8(233,8), + C8(234,8), C8(235,8), C8(236,8), C8(237,8), C8(238,8), C8(239,8), + C8(240,8), C8(241,8), C8(242,8), C8(243,8), C8(244,8), C8(245,8), + C8(246,8), C8(247,8), C8(248,8), C8(249,8), C8(250,8), C8(251,8), + C8(252,8), C8(253,8), C8(254,8), C8(255,8), +}; +const FbBits fbStipple4Bits[16] = { + C4( 0,16), C4( 1,16), C4( 2,16), C4( 3,16), C4( 4,16), C4( 5,16), + C4( 6,16), C4( 7,16), C4( 8,16), C4( 9,16), C4( 10,16), C4( 11,16), + C4( 12,16), C4( 13,16), C4( 14,16), C4( 15,16),}; +const FbBits fbStipple2Bits[4] = { + C2( 0,32), C2( 1,32), C2( 2,32), C2( 3,32), +}; +#define fbStipple1Bits 0 +#endif +const FbBits * const fbStippleTable[] = { + 0, + fbStipple1Bits, + fbStipple2Bits, + 0, + fbStipple4Bits, + 0, + 0, + 0, + fbStipple8Bits, +}; diff --git a/nx-X11/programs/Xserver/fb/fbwindow.c b/nx-X11/programs/Xserver/fb/fbwindow.c new file mode 100644 index 000000000..c4e28de5b --- /dev/null +++ b/nx-X11/programs/Xserver/fb/fbwindow.c @@ -0,0 +1,349 @@ +/* + * Id: fbwindow.c,v 1.1 1999/11/02 03:54:45 keithp Exp $ + * + * 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 <stdlib.h> + +#include "fb.h" + +Bool +fbCreateWindow(WindowPtr pWin) +{ +#ifndef FB_NO_WINDOW_PIXMAPS + pWin->devPrivates[fbWinPrivateIndex].ptr = + (void *) fbGetScreenPixmap(pWin->drawable.pScreen); +#endif +#ifdef FB_SCREEN_PRIVATE + if (pWin->drawable.bitsPerPixel == 32) + pWin->drawable.bitsPerPixel = fbGetScreenPrivate(pWin->drawable.pScreen)->win32bpp; +#endif + return TRUE; +} + +Bool +fbDestroyWindow(WindowPtr pWin) +{ + return TRUE; +} + +Bool +fbMapWindow(WindowPtr pWindow) +{ + return TRUE; +} + +Bool +fbPositionWindow(WindowPtr pWin, int x, int y) +{ + return TRUE; +} + +Bool +fbUnmapWindow(WindowPtr pWindow) +{ + return TRUE; +} + +void +fbCopyWindowProc (DrawablePtr pSrcDrawable, + DrawablePtr pDstDrawable, + GCPtr pGC, + BoxPtr pbox, + int nbox, + int dx, + int dy, + Bool reverse, + Bool upsidedown, + Pixel bitplane, + void *closure) +{ + FbBits *src; + FbStride srcStride; + int srcBpp; + int srcXoff, srcYoff; + FbBits *dst; + FbStride dstStride; + int dstBpp; + int dstXoff, dstYoff; + + fbGetDrawable (pSrcDrawable, src, srcStride, srcBpp, srcXoff, srcYoff); + fbGetDrawable (pDstDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff); + + while (nbox--) + { + fbBlt (src + (pbox->y1 + dy + srcYoff) * srcStride, + srcStride, + (pbox->x1 + dx + srcXoff) * srcBpp, + + dst + (pbox->y1 + dstYoff) * dstStride, + dstStride, + (pbox->x1 + dstXoff) * dstBpp, + + (pbox->x2 - pbox->x1) * dstBpp, + (pbox->y2 - pbox->y1), + + GXcopy, + FB_ALLONES, + dstBpp, + + reverse, + upsidedown); + pbox++; + } +} + +void +fbCopyWindow(WindowPtr pWin, + DDXPointRec ptOldOrg, + RegionPtr prgnSrc) +{ + RegionRec rgnDst; + int dx, dy; + + PixmapPtr pPixmap = fbGetWindowPixmap (pWin); + DrawablePtr pDrawable = &pPixmap->drawable; + + dx = ptOldOrg.x - pWin->drawable.x; + dy = ptOldOrg.y - pWin->drawable.y; + RegionTranslate(prgnSrc, -dx, -dy); + + RegionNull(&rgnDst); + + RegionIntersect(&rgnDst, &pWin->borderClip, prgnSrc); + +#ifdef COMPOSITE + if (pPixmap->screen_x || pPixmap->screen_y) + RegionTranslate(&rgnDst, + -pPixmap->screen_x, -pPixmap->screen_y); +#endif + + fbCopyRegion (pDrawable, pDrawable, + 0, + &rgnDst, dx, dy, fbCopyWindowProc, 0, 0); + + RegionUninit(&rgnDst); + fbValidateDrawable (&pWin->drawable); +} + +Bool +fbChangeWindowAttributes(WindowPtr pWin, unsigned long mask) +{ + PixmapPtr pPixmap; + + if (mask & CWBackPixmap) + { + if (pWin->backgroundState == BackgroundPixmap) + { + pPixmap = pWin->background.pixmap; +#ifdef FB_24_32BIT + if (pPixmap->drawable.bitsPerPixel != pWin->drawable.bitsPerPixel) + { + pPixmap = fb24_32ReformatTile (pPixmap, + pWin->drawable.bitsPerPixel); + if (pPixmap) + { + (*pWin->drawable.pScreen->DestroyPixmap) (pWin->background.pixmap); + pWin->background.pixmap = pPixmap; + } + } +#endif + if (FbEvenTile (pPixmap->drawable.width * + pPixmap->drawable.bitsPerPixel)) + fbPadPixmap (pPixmap); + } + } + if (mask & CWBorderPixmap) + { + if (pWin->borderIsPixel == FALSE) + { + pPixmap = pWin->border.pixmap; +#ifdef FB_24_32BIT + if (pPixmap->drawable.bitsPerPixel != + pWin->drawable.bitsPerPixel) + { + pPixmap = fb24_32ReformatTile (pPixmap, + pWin->drawable.bitsPerPixel); + if (pPixmap) + { + (*pWin->drawable.pScreen->DestroyPixmap) (pWin->border.pixmap); + pWin->border.pixmap = pPixmap; + } + } +#endif + if (FbEvenTile (pPixmap->drawable.width * + pPixmap->drawable.bitsPerPixel)) + fbPadPixmap (pPixmap); + } + } + return TRUE; +} + +void +fbFillRegionSolid (DrawablePtr pDrawable, + RegionPtr pRegion, + FbBits and, + FbBits xor) +{ + FbBits *dst; + FbStride dstStride; + int dstBpp; + int dstXoff, dstYoff; + int n = RegionNumRects(pRegion); + BoxPtr pbox = RegionRects(pRegion); + + fbGetDrawable (pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff); + + while (n--) + { + fbSolid (dst + (pbox->y1 + dstYoff) * dstStride, + dstStride, + (pbox->x1 + dstXoff) * dstBpp, + dstBpp, + (pbox->x2 - pbox->x1) * dstBpp, + pbox->y2 - pbox->y1, + and, xor); + fbValidateDrawable (pDrawable); + pbox++; + } +} + +#ifdef PANORAMIX +#include "panoramiX.h" +#include "panoramiXsrv.h" +#endif + +void +fbFillRegionTiled (DrawablePtr pDrawable, + RegionPtr pRegion, + PixmapPtr pTile) +{ + FbBits *dst; + FbStride dstStride; + int dstBpp; + int dstXoff, dstYoff; + FbBits *tile; + FbStride tileStride; + int tileBpp; + _X_UNUSED int tileXoff, tileYoff; /* XXX assumed to be zero */ + int tileWidth, tileHeight; + int n = RegionNumRects(pRegion); + BoxPtr pbox = RegionRects(pRegion); + int xRot = pDrawable->x; + int yRot = pDrawable->y; + +#ifdef PANORAMIX + if(!noPanoramiXExtension) + { + int index = pDrawable->pScreen->myNum; + if(&screenInfo.screens[index]->root->drawable == pDrawable) + { + xRot -= panoramiXdataPtr[index].x; + yRot -= panoramiXdataPtr[index].y; + } + } +#endif + fbGetDrawable (pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff); + fbGetDrawable (&pTile->drawable, tile, tileStride, tileBpp, tileXoff, tileYoff); + tileWidth = pTile->drawable.width; + tileHeight = pTile->drawable.height; + xRot += dstXoff; + yRot += dstYoff; + + while (n--) + { + fbTile (dst + (pbox->y1 + dstYoff) * dstStride, + dstStride, + (pbox->x1 + dstXoff) * dstBpp, + (pbox->x2 - pbox->x1) * dstBpp, + pbox->y2 - pbox->y1, + tile, + tileStride, + tileWidth * dstBpp, + tileHeight, + GXcopy, + FB_ALLONES, + dstBpp, + xRot * dstBpp, + yRot - (pbox->y1 + dstYoff)); + pbox++; + } +} + +void +fbPaintWindow(WindowPtr pWin, RegionPtr pRegion, int what) +{ + WindowPtr pBgWin; + + switch (what) { + case PW_BACKGROUND: + switch (pWin->backgroundState) { + case None: + break; + case ParentRelative: + do { + pWin = pWin->parent; + } while (pWin->backgroundState == ParentRelative); + (*pWin->drawable.pScreen->PaintWindowBackground)(pWin, pRegion, + what); + break; + case BackgroundPixmap: + fbFillRegionTiled (&pWin->drawable, + pRegion, + pWin->background.pixmap); + break; + case BackgroundPixel: + fbFillRegionSolid (&pWin->drawable, + pRegion, + 0, + fbReplicatePixel (pWin->background.pixel, + pWin->drawable.bitsPerPixel)); + break; + } + break; + case PW_BORDER: + if (pWin->borderIsPixel) + { + fbFillRegionSolid (&pWin->drawable, + pRegion, + 0, + fbReplicatePixel (pWin->border.pixel, + pWin->drawable.bitsPerPixel)); + } + else + { + for (pBgWin = pWin; + pBgWin->backgroundState == ParentRelative; + pBgWin = pBgWin->parent); + + fbFillRegionTiled (&pBgWin->drawable, + pRegion, + pWin->border.pixmap); + } + break; + } + fbValidateDrawable (&pWin->drawable); +} |