#include "Xmd.h"
#include "misc.h"
#include "pixmapstr.h"
#include "os.h"		/* for malloc.h */
#include "regionstr.h"

#include "svga.h"
#include "../../mi/mi.h"

#include "servermd.h"

#include "site.h"
#include <dos.h>
#include "svgafuncs.h"
#include "mxfuncs.h"

/*
 *	svgaSaveAreas:
 *	    Take an area of the screen (specified in pRegion), and save
 *	    those areas in pPixmap.  The region is in the pixmap's
 *	    coordinate system so we have to add x and y to get the screen
 *	    coordinates.
 */
void
mxSaveAreas(pPixmap, pRegion, x, y)
PixmapPtr pPixmap;
RegionPtr pRegion;
int x, y;
{
    BoxRec 	*prect;
    int i, srcx, srcy, height, width;
    u_char	SVGA_BASED *psrc;
    u_char	*pdst, *pdstBase;
    int		dstWidth;
    u_long	bytenum;
    u_char	page;

    pdstBase = pPixmap->devPrivate.ptr;
    dstWidth = pPixmap->devKind;
    prect = REGION_RECTS(pRegion);
    for(i = 0; i < REGION_NUM_RECTS(pRegion); i++, prect++) {
	width = prect->x2 - prect->x1;
  	srcx = prect->x1 + x;
	height = prect->y2 - prect->y1;
  	srcy = prect->y1 + y;
	if (CUR_OVERLAP(srcx, srcy, srcx + width, srcy + height))
	    HideCursor();
/*
printf("save %d,%d to %d,%d %dx%d %#x %d\n", x, y, prect->x1, prect->y1, width, height, pdstBase, dstWidth);
*/
	bytenum = (u_long)(srcy) * svga_width + srcx;
	page = (u_char)(bytenum >> 16);
	if (page != svga_curpage) {
		svga_curpage = page;
		SetPage();
	}
	psrc = vga_mem((u_short)bytenum);
	pdst = pdstBase + prect->y1 * dstWidth + prect->x1;

	while (height--) {
	    if (psrc + width > vga_mem(0xffff) + 1) {
		int len = 0x10000 - (u_short)psrc;

		copybytes(pdst, psrc, len);
		++svga_curpage;
		SetPage();
		psrc = vga_mem(0);
		copybytes(pdst + len, psrc, width - len);
		psrc = vga_mem(svga_width - len);
	    } else {
		vga_memcpy(pdst, psrc, width);
		psrc += svga_width;
		if (psrc > vga_mem(0xffff)) {
		    psrc -= 0x10000;
		    ++svga_curpage;
		    SetPage();
		}
	    }
	    pdst += dstWidth;
	}
    }
}

/*
 *	svgaRestoreAreas:
 *	    Does the opposite of svgaSaveAreas, except in this case the
 *	    region is in the screen's coordinate system.
 */
void
mxRestoreAreas(pPixmap, pRegion, x, y)
PixmapPtr pPixmap;
RegionPtr pRegion;
int x, y;
{
    BoxRec 	*prect;
    int i, srcx, srcy, height, width;
    u_char	SVGA_BASED *pdst;
    u_char	*psrc, *psrcBase;
    int		srcWidth;
    u_long	bytenum;
    u_char	page;

    psrcBase = pPixmap->devPrivate.ptr;
    srcWidth = pPixmap->devKind;
    prect = REGION_RECTS(pRegion);
    for(i = 0; i < REGION_NUM_RECTS(pRegion); i++, prect++) {
	width = prect->x2 - prect->x1;
  	srcx = prect->x1 - x;
	height = prect->y2 - prect->y1;
  	srcy = prect->y1 - y;
	if (CUR_OVERLAP(prect->x1, prect->y1, prect->x2, prect->y2))
	    HideCursor();
/*
printf("save %d,%d to %d,%d %dx%d %#x %d\n", x, y, prect->x1, prect->y1, width, height, pdstBase, dstWidth);
*/
	bytenum = (u_long)(prect->y1) * svga_width + prect->x1;
	page = (u_char)(bytenum >> 16);
	if (page != svga_curpage) {
		svga_curpage = page;
		SetPage();
	}
	pdst = vga_mem((u_short)bytenum);
	psrc = psrcBase + srcy * srcWidth + srcx;

	while (height--) {
	    if (pdst + width > vga_mem(0xffff) + 1) {
		int len = 0x10000 - (u_short)pdst;

		copybytes(pdst, psrc, len);
		++svga_curpage;
		SetPage();
		pdst = vga_mem(0);
		copybytes(pdst, psrc + len, width - len);
		pdst = vga_mem(svga_width - len);
	    } else {
		vga_memcpy(pdst, psrc, width);
		pdst += svga_width;
		if (pdst > vga_mem(0xffff)) {
		    pdst -= 0x10000;
		    ++svga_curpage;
		    SetPage();
		}
	    }
	    psrc += srcWidth;
	}
    }
}

/*
 *	svgaSetClipmaskRgn
 *	    If the client clip in the GC is of the CT_PIXMAP type, this
 *	    function is called to merge pRegion into that pixmap.  This
 *	    probably won't be called since client clips in a GC are
 *	    stored as CT_REGION clip lists.
 */
void
mxSetClipmaskRgn(pGC, pRegion)
GCPtr pGC;
RegionPtr pRegion;
{
	pGC = pGC;
	pRegion = pRegion;
}

PixmapPtr
mxGetImagePixmap()
{
	return NULL;
}

PixmapPtr
mxGetSpansPixmap()
{
	return NULL;
}
