#include "Xmd.h"
#include "servermd.h"
#include "scrnintstr.h"
#include "pixmapstr.h"
#include "mi.h"
#include "cfb.h"
#include "cfbmskbits.h"
extern CfbBits endtab[];
PixmapPtr
cfbCreatePixmap (pScreen, width, height, depth)
ScreenPtr pScreen;
int width;
int height;
int depth;
{
PixmapPtr pPixmap;
int datasize;
int paddedWidth;
paddedWidth = PixmapBytePad(width, depth);
datasize = height * paddedWidth;
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 = BitsPerPixel(depth);
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;
#ifdef PIXPRIV
pPixmap->devPrivate.ptr = datasize ?
(pointer)((char *)pPixmap + pScreen->totalPixmapSize) : NULL;
#else
pPixmap->devPrivate.ptr = (pointer)(pPixmap + 1);
#endif
return pPixmap;
}
Bool
cfbDestroyPixmap(pPixmap)
PixmapPtr pPixmap;
{
if(--pPixmap->refcnt)
return TRUE;
xfree(pPixmap);
return TRUE;
}
PixmapPtr
cfbCopyPixmap(pSrc)
register PixmapPtr pSrc;
{
register PixmapPtr pDst;
int size;
ScreenPtr pScreen;
size = pSrc->drawable.height * pSrc->devKind;
pScreen = pSrc->drawable.pScreen;
pDst = (*pScreen->CreatePixmap) (pScreen, pSrc->drawable.width,
pSrc->drawable.height, pSrc->drawable.depth);
if (!pDst)
return NullPixmap;
memmove((char *)pDst->devPrivate.ptr, (char *)pSrc->devPrivate.ptr, size);
return pDst;
}
void
cfbPadPixmap(pPixmap)
PixmapPtr pPixmap;
{
register int width = (pPixmap->drawable.width) * (pPixmap->drawable.bitsPerPixel);
register int h;
register CfbBits mask;
register CfbBits *p;
register CfbBits bits;
register int i;
int rep;
if (width >= PGSZ)
return;
rep = PGSZ/width;
if (rep*width != PGSZ)
return;
mask = endtab[width];
p = (CfbBits *)(pPixmap->devPrivate.ptr);
for (h=0; h < pPixmap->drawable.height; h++)
{
*p &= mask;
bits = *p;
for(i=1; i<rep; i++)
{
#if (BITMAP_BIT_ORDER == MSBFirst)
bits >>= width;
#else
bits <<= width;
#endif
*p |= bits;
}
p++;
}
pPixmap->drawable.width = PGSZ/(pPixmap->drawable.bitsPerPixel);
}
#ifdef notdef
static cfbdumppixmap(pPix)
PixmapPtr pPix;
{
unsigned int *pw;
char *psrc, *pdst;
int i, j;
char line[66];
ErrorF( "pPixmap: 0x%x\n", pPix);
ErrorF( "%d wide %d high\n", pPix->drawable.width, pPix->drawable.height);
if (pPix->drawable.width > 64)
{
ErrorF( "too wide to see\n");
return;
}
pw = (unsigned int *) pPix->devPrivate.ptr;
psrc = (char *) pw;
for ( i = 0; i < pPix->drawable.height; ++i ) {
pdst = line;
for(j = 0; j < pPix->drawable.width; j++) {
*pdst++ = *psrc++ ? 'X' : ' ' ;
}
*pdst++ = '\n';
*pdst++ = '\0';
ErrorF( "%s", line);
}
}
#endif
void
cfbXRotatePixmap(pPix, rw)
PixmapPtr pPix;
register int rw;
{
register CfbBits *pw, *pwFinal;
register CfbBits t;
int rot;
if (pPix == NullPixmap)
return;
switch (((DrawablePtr) pPix)->bitsPerPixel) {
case PSZ:
break;
case 1:
mfbXRotatePixmap(pPix, rw);
return;
default:
ErrorF("cfbXRotatePixmap: unsupported bitsPerPixel %d\n", ((DrawablePtr) pPix)->bitsPerPixel);
return;
}
pw = (CfbBits *)pPix->devPrivate.ptr;
modulus (rw, (int) pPix->drawable.width, rot);
if(pPix->drawable.width == PPW)
{
pwFinal = pw + pPix->drawable.height;
while(pw < pwFinal)
{
t = *pw;
*pw++ = SCRRIGHT(t, rot) |
(SCRLEFT(t, (PPW-rot)) & cfbendtab[rot]);
}
}
else
{
ErrorF("cfb internal error: trying to rotate odd-sized pixmap.\n");
#ifdef notdef
register CfbBits *pwTmp;
int size, tsize;
tsize = PixmapBytePad(pPix->drawable.width - rot, pPix->drawable.depth);
pwTmp = (CfbBits *) ALLOCATE_LOCAL(pPix->drawable.height * tsize);
if (!pwTmp)
return;
tsize >>= 2;
size = pPix->devKind >> SIZE0F(PixelGroup);
cfbQuickBlt((CfbBits *)pw, (CfbBits *)pwTmp,
0, 0, 0, 0,
(int)pPix->drawable.width - rot, (int)pPix->drawable.height,
size, tsize);
cfbQuickBlt((CfbBits *)pw, (CfbBits *)pw,
(int)pPix->drawable.width - rot, 0, 0, 0,
rot, (int)pPix->drawable.height,
size, size);
cfbQuickBlt((CfbBits *)pwTmp, (CfbBits *)pw,
0, 0, rot, 0,
(int)pPix->drawable.width - rot, (int)pPix->drawable.height,
tsize, size);
DEALLOCATE_LOCAL(pwTmp);
#endif
}
}
void
cfbYRotatePixmap(pPix, rh)
register PixmapPtr pPix;
int rh;
{
int nbyDown;
int nbyUp;
char *pbase;
char *ptmp;
int rot;
if (pPix == NullPixmap)
return;
switch (((DrawablePtr) pPix)->bitsPerPixel) {
case PSZ:
break;
case 1:
mfbYRotatePixmap(pPix, rh);
return;
default:
ErrorF("cfbYRotatePixmap: unsupported bitsPerPixel %d\n", ((DrawablePtr) pPix)->bitsPerPixel);
return;
}
modulus (rh, (int) pPix->drawable.height, rot);
pbase = (char *)pPix->devPrivate.ptr;
nbyDown = rot * pPix->devKind;
nbyUp = (pPix->devKind * pPix->drawable.height) - nbyDown;
if(!(ptmp = (char *)ALLOCATE_LOCAL(nbyUp)))
return;
memmove(ptmp, pbase, nbyUp);
memmove(pbase, pbase+nbyUp, nbyDown);
memmove(pbase+nbyDown, ptmp, nbyUp);
DEALLOCATE_LOCAL(ptmp);
}
void
cfbCopyRotatePixmap(psrcPix, ppdstPix, xrot, yrot)
register PixmapPtr psrcPix, *ppdstPix;
int xrot, yrot;
{
register PixmapPtr pdstPix;
if ((pdstPix = *ppdstPix) &&
(pdstPix->devKind == psrcPix->devKind) &&
(pdstPix->drawable.height == psrcPix->drawable.height))
{
memmove((char *)pdstPix->devPrivate.ptr,
(char *)psrcPix->devPrivate.ptr,
psrcPix->drawable.height * psrcPix->devKind);
pdstPix->drawable.width = psrcPix->drawable.width;
pdstPix->drawable.depth = psrcPix->drawable.depth;
pdstPix->drawable.bitsPerPixel = psrcPix->drawable.bitsPerPixel;
pdstPix->drawable.serialNumber = NEXT_SERIAL_NUMBER;
}
else
{
if (pdstPix)
(*pdstPix->drawable.pScreen->DestroyPixmap)(pdstPix);
*ppdstPix = pdstPix = cfbCopyPixmap(psrcPix);
if (!pdstPix)
return;
}
cfbPadPixmap(pdstPix);
if (xrot)
cfbXRotatePixmap(pdstPix, xrot);
if (yrot)
cfbYRotatePixmap(pdstPix, yrot);
}