New upstream version 3.5.99.27

This commit is contained in:
geos_one
2025-08-08 20:00:36 +02:00
commit bc8d10cc33
4267 changed files with 1757978 additions and 0 deletions

View File

@@ -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))

File diff suppressed because it is too large Load Diff

View File

@@ -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);
}

View File

@@ -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;
}

View File

@@ -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);
}

View File

@@ -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

View File

@@ -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

View File

@@ -0,0 +1,968 @@
/*
* 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 <string.h>
#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 ();
if (alu == GXcopy && pm == FB_ALLONES &&
!(srcX & 7) && !(dstX & 7) && !(width & 7))
{
CARD8 *src_byte = (CARD8 *) srcLine + (srcX >> 3);
CARD8 *dst_byte = (CARD8 *) dstLine + (dstX >> 3);
FbStride src_byte_stride = srcStride << (FB_SHIFT - 3);
FbStride dst_byte_stride = dstStride << (FB_SHIFT - 3);
int width_byte = (width >> 3);
/* Make sure there's no overlap; we can't use memcpy in that
* case as it's not well defined, so fall through to the
* general code
*/
if (src_byte + width_byte <= dst_byte ||
dst_byte + width_byte <= src_byte)
{
int i;
if (!upsidedown)
for (i = 0; i < height; i++)
memcpy(dst_byte + i * dst_byte_stride,
src_byte + i * src_byte_stride,
width_byte);
else
for (i = height - 1; i >= 0; i--)
memcpy(dst_byte + i * dst_byte_stride,
src_byte + i * src_byte_stride,
width_byte);
return;
}
}
#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);
}
}

View File

@@ -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);
}
}

View File

@@ -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);
}

View File

@@ -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

File diff suppressed because it is too large Load Diff

View File

@@ -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);
}

View File

@@ -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 */

View File

@@ -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

View File

@@ -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);
}
}

View File

@@ -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);
}
}
}
}

View File

@@ -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++;
}
}
}
}

View File

@@ -0,0 +1,319 @@
/*
* 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;
int stride;
int bpp;
_X_UNUSED int xOff, yOff;
fbGetDrawable (&pPixmap->drawable, bits, stride, bpp, xOff, yOff);
width = pPixmap->drawable.width * pPixmap->drawable.bitsPerPixel;
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;
bits += stride;
}
}
/*
* 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;
}
}

View File

@@ -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++;
}
}

View File

@@ -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;
}
}

View File

@@ -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);
}
}

View File

@@ -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);
}

View File

@@ -0,0 +1,463 @@
/*
* 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)) {
free(pScrPriv);
return FALSE;
}
if (! miScreenInit(pScreen, 0, xsize, ysize, dpix, dpiy, 0,
depth1, ndepths, depths,
defaultVisual, nvisuals, visuals
#ifdef FB_OLD_MISCREENINIT
, (miBSFuncPtr) 0
#endif
)) {
free(pScrPriv);
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;
}

View File

@@ -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_ */

File diff suppressed because it is too large Load Diff

View File

@@ -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 - ((x >> 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_ */

View File

@@ -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 */

View File

@@ -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);
}

View File

@@ -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);
}

View File

@@ -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

View File

@@ -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

View File

@@ -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--) */
}

View File

@@ -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);
}

View File

@@ -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

View File

@@ -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);
}

View File

@@ -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);
}

View File

@@ -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 */

View File

@@ -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,
};

View File

@@ -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);
}