#include "Xmd.h"
#include "servermd.h"
#include "scrnintstr.h"
#include "pixmapstr.h"
#include "mi.h"
#define PSZ 8
#include "cfb.h"
#undef PSZ
#include "cfb24_32.h"
PixmapPtr
cfb24_32CreatePixmap (
ScreenPtr pScreen,
int width,
int height,
int depth
){
cfb24_32PixmapPtr pPixPriv;
PixmapPtr pPix;
int size, bpp, pitch;
if(depth == 1) {
pitch = ((width + 31) >> 5) << 2;
bpp = 1;
} else {
pitch = ((width * 3) + 3) & ~3L;
bpp = (width && height) ? 24 : 32;
}
size = height * pitch;
pPix = AllocatePixmap(pScreen, size);
if (!pPix)
return NullPixmap;
pPix->drawable.type = DRAWABLE_PIXMAP;
pPix->drawable.class = 0;
pPix->drawable.pScreen = pScreen;
pPix->drawable.depth = depth;
pPix->drawable.bitsPerPixel = bpp;
pPix->drawable.id = 0;
pPix->drawable.serialNumber = NEXT_SERIAL_NUMBER;
pPix->drawable.x = 0;
pPix->drawable.y = 0;
pPix->drawable.width = width;
pPix->drawable.height = height;
pPix->devKind = pitch;
pPix->refcnt = 1;
pPix->devPrivate.ptr = size ?
(pointer)((char*)pPix + pScreen->totalPixmapSize) : NULL;
pPixPriv = CFB24_32_GET_PIXMAP_PRIVATE(pPix);
pPixPriv->pix = NULL;
pPixPriv->freePrivate = FALSE;
pPixPriv->isRefPix = FALSE;
return pPix;
}
Bool
cfb24_32DestroyPixmap(PixmapPtr pPix)
{
cfb24_32PixmapPtr pPriv = CFB24_32_GET_PIXMAP_PRIVATE(pPix);
PixmapPtr pClone = pPriv->pix;
if(pClone) {
cfb24_32PixmapPtr cPriv = CFB24_32_GET_PIXMAP_PRIVATE(pClone);
int refcnt = pPix->refcnt;
cPriv->pix = NULL;
if(refcnt != pClone->refcnt)
ErrorF("Pixmap refcnt mismatch in DestroyPixmap()\n");
(*pPix->drawable.pScreen->DestroyPixmap)(pClone);
if(refcnt > 1)
cPriv->pix = pPix;
}
if(--pPix->refcnt)
return TRUE;
if(pPriv->freePrivate)
xfree(pPix->devPrivate.ptr);
xfree(pPix);
return TRUE;
}
PixmapPtr
cfb24_32RefreshPixmap(PixmapPtr pPix)
{
cfb24_32PixmapPtr newPixPriv, pixPriv = CFB24_32_GET_PIXMAP_PRIVATE(pPix);
ScreenPtr pScreen = pPix->drawable.pScreen;
int width = pPix->drawable.width;
int height = pPix->drawable.height;
GCPtr pGC;
if(pPix->drawable.bitsPerPixel == 24) {
if(!pixPriv->pix) {
int pitch = width << 2;
unsigned char* data;
PixmapPtr newPix;
if(!(data = (unsigned char*)xalloc(pitch * height)))
FatalError("Out of memory\n");
newPix = (*pScreen->CreatePixmap)(pScreen, 0, 0, 24);
newPix->devKind = pitch;
newPix->devPrivate.ptr = (pointer)data;
newPix->drawable.width = width;
newPix->drawable.height = height;
newPix->refcnt = pPix->refcnt;
pixPriv->pix = newPix;
newPixPriv = CFB24_32_GET_PIXMAP_PRIVATE(newPix);
newPixPriv->pix = pPix;
newPixPriv->freePrivate = TRUE;
pixPriv->isRefPix = TRUE;
}
} else {
if(!pixPriv->pix) {
pixPriv->pix = (*pScreen->CreatePixmap)(pScreen, width, height, 24);
pixPriv->pix->refcnt = pPix->refcnt;
newPixPriv = CFB24_32_GET_PIXMAP_PRIVATE(pixPriv->pix);
newPixPriv->pix = pPix;
pixPriv->isRefPix = TRUE;
}
}
if(pPix->refcnt != pixPriv->pix->refcnt)
ErrorF("Pixmap refcnt mismatch in RefreshPixmap()\n");
if(pixPriv->isRefPix) {
pGC = GetScratchGC(24, pScreen);
ValidateGC((DrawablePtr)pixPriv->pix, pGC);
(*pGC->ops->CopyArea)((DrawablePtr)pPix, (DrawablePtr)pixPriv->pix,
pGC, 0, 0, width, height, 0, 0);
FreeScratchGC(pGC);
}
return pixPriv->pix;
}