#include "X.h"
#include "Xmd.h"

#include "misc.h"
#include "regionstr.h"
#include "gcstruct.h"
#include "windowstr.h"
#include "pixmapstr.h"
#include "scrnintstr.h"

#include "i8.h"
#include "../common/mouse.h"

#include "servermd.h"

void
i8PutImage(pDraw, pGC, depth, x, y, w, h, leftPad, format, pImage)
DrawablePtr pDraw;
GCPtr pGC;
int depth;	/* depth of pImage, not necessarily the depth of pDraw */
int w, h, leftPad;
int format;
unsigned x, y;
u_char *pImage;
{
    int i;
    DDXPointPtr		pptFirst, ppt;
    int			*pwidthFirst, *pwidth;
    BoxRec		box;
    PixmapRec		pixmap;
    PixmapPtr		oldStipple;
    int			oldFillStyle;
    DDXPointRec		oldPatOrg;

    if (!w || !h)
	return;

/* This code stolen from miPutImage. */
    ppt = pptFirst = (DDXPointPtr)ALLOCATE_LOCAL(h * sizeof(DDXPointRec));
    pwidth = pwidthFirst = (int *)ALLOCATE_LOCAL(h * sizeof(int));
    if(!pptFirst || !pwidthFirst)
    {
printf("putImage: ALLOCATE_LOCAL failed\n");
       if (pwidthFirst)
	   DEALLOCATE_LOCAL(pwidthFirst);
       if (pptFirst)
	   DEALLOCATE_LOCAL(pptFirst);
       return;
    }

    x += pDraw->x;
    y += pDraw->y;

    for(i = 0; i < h; i++)
    {
	ppt->x = x;
	ppt->y = y + i;
	ppt++;
	*pwidth++ = w;
    }
    box.x1 = x;
    box.x2 = x + w;
    box.y1 = y;
    box.y2 = y + h;

    switch(format) {
	case XYBitmap:
	    /* Turn pImage into a pixmap. */
	    pixmap.drawable.type = DRAWABLE_PIXMAP;
	    pixmap.drawable.pScreen = pDraw->pScreen;
	    pixmap.drawable.depth = 1;
	    pixmap.drawable.bitsPerPixel = 1;
	    pixmap.drawable.width = w + leftPad;
	    pixmap.drawable.height = h;
	    pixmap.drawable.serialNumber = NEXT_SERIAL_NUMBER;
	    pixmap.drawable.x = 0;
	    pixmap.drawable.y = 0;
	    pixmap.refcnt = 1;
	    pixmap.devKind = PixmapBytePad(pixmap.drawable.width, 1);
	    pixmap.devPrivate.ptr = pImage;

	    oldStipple = pGC->stipple;
	    pGC->stipple = &pixmap;
	    oldFillStyle = pGC->fillStyle;
	    pGC->fillStyle = FillOpaqueStippled;
	    oldPatOrg = pGC->patOrg;
	    pGC->patOrg.y = y - pDraw->y;
	    pGC->patOrg.x = x + leftPad - pDraw->x;

	    i8FillSpans(pDraw, pGC, h, pptFirst, pwidthFirst, SPANS_SORTED|SPANS_RECT, &box);
	    pGC->stipple = oldStipple;
	    pGC->fillStyle = oldFillStyle;
	    pGC->patOrg = oldPatOrg;

	    break;
	case XYPixmap:
	    if (depth == 1)
		goto L_ZPixmap;
printf("XYPixmap: type=%d\n", pDraw->type);
	    break;
	case ZPixmap:
L_ZPixmap:
	    i8SetSpans(pDraw, pGC, pImage, pptFirst, pwidthFirst, h,
		    SPANS_SORTED|SPANS_RECT, &box);
	    break;
    }
    DEALLOCATE_LOCAL(pwidthFirst);
    DEALLOCATE_LOCAL(pptFirst);
}

/* TODO: use planeMask */
void
i8GetImage(pDraw, sx, sy, w, h, format, planeMask, pdstLine)
    DrawablePtr 	pDraw;
    int			w, h;
    unsigned		sx, sy;
    unsigned int 	format;
    unsigned long 	planeMask;
    pointer             pdstLine;
{
    int i;
    DDXPointPtr		pptFirst, ppt;
    int			*pwidthFirst, *pwidth;

    if (!w || !h)
	return;

    ppt = pptFirst = (DDXPointPtr)ALLOCATE_LOCAL(h * sizeof(DDXPointRec));
    pwidth = pwidthFirst = (int *)ALLOCATE_LOCAL(h * sizeof(int));
    if(!pptFirst || !pwidthFirst)
    {
printf("getImage: ALLOCATE_LOCAL failed\n");
       if (pwidthFirst)
	   DEALLOCATE_LOCAL(pwidthFirst);
       if (pptFirst)
	   DEALLOCATE_LOCAL(pptFirst);
       return;
    }

    /* These will be 0 for a pixmap. */
    sx += pDraw->x;
    sy += pDraw->y;

    for(i = 0; i < h; i++)
    {
	ppt->x = sx;
	ppt->y = sy + i;
	ppt++;
	*pwidth++ = w;
    }

    if (format == ZPixmap) {
L_ZPixmap:
	i8GetSpans(pDraw, w, pptFirst, pwidthFirst, h, pdstLine);
    } else {
	if (pDraw->depth == 1)
	    goto L_ZPixmap;
printf("GetImage: format=%d -n-\n", format);
    }
    DEALLOCATE_LOCAL(pwidthFirst);
    DEALLOCATE_LOCAL(pptFirst);
}
