#ifdef HAVE_XORG_CONFIG_H
#include <xorg-config.h>
#endif
#include "xf4bpp.h"
#include "vgaVideo.h"
#include "pixmapstr.h"
#include "scrnintstr.h"
#include "windowstr.h"
#define saved_screen(pWin) \
((unsigned char *)(((PixmapPtr)((pWin)->drawable.pScreen->devPrivate))->devPrivate.ptr))
#define SAVEDSCREEN(pWin, x, y) \
(*(saved_screen(pWin) + (y) * (BYTES_PER_LINE(pWin)) + (x)))
#define DO_ROP(src,dst,alu,planes) \
((dst) = do_rop((src),(dst),(alu),(planes)))
static int
do_rop
(
int src,
int dst,
int alu,
const unsigned long planes
)
{
int _dst;
switch ( alu ) {
case GXclear:
_dst = 0; break ;
case GXinvert:
_dst = ~dst; break ;
case GXset:
_dst = src; break ;
default:
case GXnoop:
return dst;
case GXnor:
_dst = ~src & ~dst; break ;
case GXandInverted:
_dst = ~src & dst; break ;
case GXand:
_dst = src & dst; break ;
case GXequiv:
_dst = ~src ^ dst; break ;
case GXxor:
_dst = src ^ dst; break ;
case GXandReverse:
_dst = src & ~dst; break ;
case GXnand:
_dst = ~src | ~dst; break ;
case GXorReverse:
_dst = src | ~dst; break ;
case GXorInverted:
_dst = ~src | dst; break ;
case GXor:
_dst = src | dst; break ;
case GXcopyInverted:
_dst = ~src; break ;
case GXcopy:
_dst = src; break ;
}
return (dst & ~planes) | (_dst & planes);
}
void
xf4bppOffBitBlt( pWin, alu, writeplanes, x0, y0, x1, y1, w, h )
WindowPtr pWin;
const int alu, writeplanes ;
register int x0 ;
int y0 ;
register int x1 ;
int y1 ;
register int w, h ;
{
int x,y;
switch ( alu ) {
case GXclear:
case GXinvert:
case GXset:
xf4bppOffFillSolid( pWin, VGA_ALLPLANES, alu, writeplanes,
x0, y0, w, h ) ;
case GXnoop:
return ;
default:
break ;
}
if ( (w <= 0) || (h <= 0) ) return;
for ( y = 0 ; y < h ; y++ ) {
for ( x = 0 ; x < w ; x++ ) {
DO_ROP(SAVEDSCREEN(pWin,x0+x,y0+y),SAVEDSCREEN(pWin,x1+x,y1+y),
alu,writeplanes);
}
}
}
void
xf4bppOffDrawColorImage( pWin, x, y, w, h, data, RowIncrement, alu, planes )
WindowPtr pWin;
int x, y ;
register int w, h ;
unsigned char *data ;
register int RowIncrement ;
const int alu ;
const unsigned long int planes ;
{
int dx,dy;
for ( dy = 0 ; dy < h ; dy++ ) {
for ( dx = 0 ; dx < w ; dx++ ) {
DO_ROP( data[dy * RowIncrement + dx],
SAVEDSCREEN(pWin,x+dx,y+dy), alu, planes);
}
}
}
void
xf4bppOffReadColorImage( pWin, x, y, lx, ly, data, RowIncrement )
WindowPtr pWin;
int x, y ;
int lx, ly ;
unsigned char *data ;
int RowIncrement ;
{
int dx, dy;
if ( ( lx <= 0 ) || ( ly <= 0 ) )
return ;
for ( dy = 0 ; dy < ly ; dy++ ) {
for ( dx = 0 ; dx < lx ; dx++ ) {
data[dy*RowIncrement+dx] = SAVEDSCREEN(pWin,x+dx,y+dy);
}
}
}
void xf4bppOffFillSolid( pWin, color, alu, planes, x0, y0, lx, ly )
WindowPtr pWin;
unsigned long int color ;
const int alu ;
unsigned long int planes ;
register int x0 ;
register const int y0 ;
register int lx ;
register const int ly ;
{
int dx, dy;
if ( ( lx == 0 ) || ( ly == 0 ) )
return;
for ( dy = 0 ; dy < ly ; dy++ ) {
for ( dx = 0 ; dx < lx ; dx++ ) {
DO_ROP(color,SAVEDSCREEN(pWin, x0+dx,y0+dy),alu,planes);
}
}
}
static unsigned char
xygetbits
(
register int x,
register int y,
register const unsigned int Width,
register const unsigned int paddedByteWidth,
register const unsigned int Height,
register const unsigned char * const data
)
{
register unsigned char bits ;
unsigned const char *lineptr, *cptr ;
register int shift ;
register int wrap ;
x = x % Width;
y = y % Height;
lineptr = data + (y * paddedByteWidth);
cptr = lineptr + (x >> 3) ;
bits = *cptr ;
if ((shift = x & 7))
bits = SCRLEFT8( bits, shift ) |
SCRRIGHT8( cptr[1], ( 8 - shift ) ) ;
if ( ( wrap = x + 8 - Width ) > 0 ) {
bits &= SCRLEFT8( 0xFF, wrap ) ;
bits |= SCRRIGHT8( *lineptr, ( 8 - wrap ) ) ;
}
return bits ;
}
static void
DoMono
(
WindowPtr pWin,
int w,
int x,
int y,
register const unsigned char *mastersrc,
int h,
unsigned int width,
register unsigned int paddedByteWidth,
unsigned int height,
int xshift,
int yshift,
int alu,
int planes,
int fg
)
{
int dy, dx, i;
int byte;
for ( dy = 0 ; dy < h ; dy++ ) {
for ( dx = 0; dx <= w - 8 ; dx += 8 ) {
byte = xygetbits(dx+xshift,dy+yshift,width,
paddedByteWidth, height, mastersrc);
for ( i = 0 ; i < 8 ; i++ ) {
if ( byte & (128 >> i) ) {
DO_ROP(fg,SAVEDSCREEN(pWin,x+dx+i,y+dy),
alu,planes);
}
}
}
byte = xygetbits(dx+xshift,dy+yshift,width,
paddedByteWidth, height, mastersrc);
for ( i = 0 ; i < (w - dx) ; i++ ) {
if ( byte & (128 >> i) ) {
DO_ROP(fg,SAVEDSCREEN(pWin,x+dx+i,y+dy),
alu,planes);
}
}
}
}
void
xf4bppOffFillStipple( pWin, pStipple, fg, alu, planes, x, y, w, h, xSrc, ySrc )
WindowPtr pWin;
register PixmapPtr const pStipple ;
unsigned long int fg ;
const int alu ;
unsigned long int planes ;
int x, y, w, h ;
const int xSrc, ySrc ;
{
unsigned int width ;
unsigned int height ;
int xshift ;
int yshift ;
if ( ( alu == GXnoop ) || !( planes &= VGA_ALLPLANES ) )
return ;
width = pStipple->drawable.width ;
if ( ( xshift = ( x - xSrc ) ) < 0 )
xshift = width - ( ( - xshift ) % width ) ;
else
xshift %= width ;
height = pStipple->drawable.height ;
if ( ( yshift = ( y - ySrc ) ) < 0 )
yshift = height - ( ( - yshift ) % height ) ;
else
yshift %= height ;
DoMono( pWin, w, x, y,
(const unsigned char *) pStipple->devPrivate.ptr,
h,
width,
( ( width + 31 ) & (unsigned)(~31) ) >> 3,
height,
xshift, yshift,
alu, (int)planes, (int)fg ) ;
return ;
}