#include "Xmd.h"
#include "servermd.h"
#include "scrnintstr.h"
#include "pixmapstr.h"
#include "mi.h"
#include "ipl.h"
#include "iplmskbits.h"
extern unsigned long endtab[];
PixmapPtr
iplCreatePixmap (pScreen, width, height, depth)
ScreenPtr pScreen;
int width;
int height;
int depth;
{
PixmapPtr pPixmap;
int datasize;
int paddedWidth;
int ipad=INTER_PLANES*2 - 1;
paddedWidth = PixmapBytePad(width, depth);
paddedWidth = (paddedWidth + ipad) & ~ipad;
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)((long)(pPixmap + 1));
#endif
return pPixmap;
}
Bool
iplDestroyPixmap(pPixmap)
PixmapPtr pPixmap;
{
if(--pPixmap->refcnt)
return TRUE;
xfree(pPixmap);
return TRUE;
}
PixmapPtr
iplCopyPixmap(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
iplPadPixmap(pPixmap)
PixmapPtr pPixmap;
{
register int width = pPixmap->drawable.width;
register int h;
register unsigned short mask;
register unsigned short *p;
register unsigned short bits;
register int i;
int rep;
if (width >= INTER_PGSZ)
return;
rep = INTER_PGSZ/width;
mask = iplendtab[width];
p = (unsigned short *)(pPixmap->devPrivate.ptr);
for (h=0; h < pPixmap->drawable.height * INTER_PLANES; 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 = rep*width;
}
#ifdef notdef
static ipldumppixmap(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
iplXRotatePixmap(pPix, rw)
PixmapPtr pPix;
register int rw;
{
INTER_DECLAREG(*pw);
INTER_DECLAREG(*pwFinal);
INTER_DECLAREGP(t);
int rot;
if (pPix == NullPixmap)
return;
switch (((DrawablePtr) pPix)->bitsPerPixel) {
case INTER_PLANES:
break;
case 1:
mfbXRotatePixmap(pPix, rw);
return;
default:
ErrorF("iplXRotatePixmap: unsupported bitsPerPixel %d\n", ((DrawablePtr) pPix)->bitsPerPixel);
return;
}
pw = (unsigned short *)pPix->devPrivate.ptr;
modulus (rw, (int) pPix->drawable.width, rot);
if(pPix->drawable.width == 16)
{
pwFinal = pw + pPix->drawable.height * INTER_PLANES;
while(pw < pwFinal)
{
INTER_COPY(pw, t);
INTER_MSKINSM(iplendtab[rot], INTER_PPG-rot, t,
~0, rot, t, pw)
INTER_NEXT_GROUP(pw);
}
}
else
{
ErrorF("ipl internal error: trying to rotate odd-sized pixmap.\n");
#ifdef notdef
register unsigned long *pwTmp;
int size, tsize;
tsize = PixmapBytePad(pPix->drawable.width - rot, pPix->drawable.depth);
pwTmp = (unsigned long *) ALLOCATE_LOCAL(pPix->drawable.height * tsize);
if (!pwTmp)
return;
tsize >>= 2;
size = pPix->devKind >> SIZE0F(PixelGroup);
iplQuickBlt((long *)pw, (long *)pwTmp,
0, 0, 0, 0,
(int)pPix->drawable.width - rot, (int)pPix->drawable.height,
size, tsize);
iplQuickBlt((long *)pw, (long *)pw,
(int)pPix->drawable.width - rot, 0, 0, 0,
rot, (int)pPix->drawable.height,
size, size);
iplQuickBlt((long *)pwTmp, (long *)pw,
0, 0, rot, 0,
(int)pPix->drawable.width - rot, (int)pPix->drawable.height,
tsize, size);
DEALLOCATE_LOCAL(pwTmp);
#endif
}
}
void
iplYRotatePixmap(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 INTER_PLANES:
break;
case 1:
mfbYRotatePixmap(pPix, rh);
return;
default:
ErrorF("iplYRotatePixmap: 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
iplCopyRotatePixmap(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 = iplCopyPixmap(psrcPix);
if (!pdstPix)
return;
}
iplPadPixmap(pdstPix);
if (xrot)
iplXRotatePixmap(pdstPix, xrot);
if (yrot)
iplYRotatePixmap(pdstPix, yrot);
}