#ifdef HAVE_DIX_CONFIG_H
#include <dix-config.h>
#endif
#include <string.h>
#include <X11/Xmd.h>
#include "scrnintstr.h"
#include "pixmapstr.h"
#include "maskbits.h"
#include "mfb.h"
#include "mi.h"
#include "servermd.h"
PixmapPtr
mfbCreatePixmap (pScreen, width, height, depth)
ScreenPtr pScreen;
int width;
int height;
int depth;
{
PixmapPtr pPixmap;
size_t datasize;
size_t paddedWidth;
if (depth != 1)
return NullPixmap;
paddedWidth = BitmapBytePad(width);
if (paddedWidth / 4 > 32767 || height > 32767)
return NullPixmap;
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 = 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;
pPixmap->devPrivate.ptr = datasize ?
(pointer)((char *)pPixmap + pScreen->totalPixmapSize) : NULL;
return pPixmap;
}
Bool
mfbDestroyPixmap(pPixmap)
PixmapPtr pPixmap;
{
if(--pPixmap->refcnt)
return TRUE;
xfree(pPixmap);
return TRUE;
}
PixmapPtr
mfbCopyPixmap(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
mfbPadPixmap(pPixmap)
PixmapPtr pPixmap;
{
register int width = pPixmap->drawable.width;
register int h;
register PixelType mask;
register PixelType *p;
register PixelType bits;
register int i;
int rep;
if (width >= PPW)
return;
rep = PPW/width;
if (rep*width != PPW)
return;
mask = endtab[width];
p = (PixelType *)(pPixmap->devPrivate.ptr);
for (h=0; h < pPixmap->drawable.height; h++)
{
*p &= mask;
bits = *p;
for(i=1; i<rep; i++)
{
bits = SCRRIGHT(bits, width);
*p |= bits;
}
p++;
}
pPixmap->drawable.width = PPW;
}
void
mfbXRotatePixmap(pPix, rw)
PixmapPtr pPix;
register int rw;
{
register PixelType *pw, *pwFinal;
register PixelType t;
if (pPix == NullPixmap)
return;
pw = (PixelType *)pPix->devPrivate.ptr;
rw %= (int)pPix->drawable.width;
if (rw < 0)
rw += (int)pPix->drawable.width;
if(pPix->drawable.width == PPW)
{
pwFinal = pw + pPix->drawable.height;
while(pw < pwFinal)
{
t = *pw;
*pw++ = SCRRIGHT(t, rw) |
(SCRLEFT(t, (PPW-rw)) & endtab[rw]);
}
}
else
{
ErrorF("X internal error: trying to rotate odd-sized pixmap.\n");
}
}
void
mfbYRotatePixmap(pPix, rh)
register PixmapPtr pPix;
int rh;
{
int nbyDown;
int nbyUp;
char *pbase;
char *ptmp;
int height;
if (pPix == NullPixmap)
return;
height = (int) pPix->drawable.height;
rh %= height;
if (rh < 0)
rh += height;
pbase = (char *)pPix->devPrivate.ptr;
nbyDown = rh * pPix->devKind;
nbyUp = (pPix->devKind * 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
mfbCopyRotatePixmap(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.serialNumber = NEXT_SERIAL_NUMBER;
}
else
{
if (pdstPix)
(*pdstPix->drawable.pScreen->DestroyPixmap)(pdstPix);
*ppdstPix = pdstPix = mfbCopyPixmap(psrcPix);
if (!pdstPix)
return;
}
mfbPadPixmap(pdstPix);
if (xrot)
mfbXRotatePixmap(pdstPix, xrot);
if (yrot)
mfbYRotatePixmap(pdstPix, yrot);
}