#include <dos.h>
#include <string.h>
#include "X.h"
#include "Xmd.h"
#include "Xproto.h"

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

#include "svga.h"
#include "svgafuncs.h"
#include "mxfuncs.h"

#include "servermd.h"

void
mxGetSpans(pDrawable, wMax, ppt, pwidth, nspans, pdst)
    DrawablePtr		pDrawable;
    int			wMax;		/* largest value of all *pwidths */
    DDXPointPtr ppt;
    int	*pwidth;
    int			nspans;
    unsigned char	*pdst;
{
    register DDXPointPtr pptLast;	/* one past last point to get */
    int 		widthSrc;	/* width of bitmap in bytes */
    int	 		srcBit;
    int			xEnd, w;

    pptLast = ppt + nspans;

    if (pDrawable->type == DRAWABLE_WINDOW)
    {
	u_char SVGA_BASED *cp;
	u_long bytenum;
	u_char page;		/* which page on display */

	widthSrc = svga_width;
	if (CUR_OVERLAP(pDrawable->x, pDrawable->y,
	    pDrawable->x + pDrawable->width,
	    pDrawable->y + pDrawable->height))
		HideCursor();
	while(ppt < pptLast) {
	    xEnd = min(ppt->x + *pwidth, svga_width);
	    bytenum = (u_long)ppt->y * svga_width + ppt->x;
	    cp = vga_mem((u_short)bytenum);
	    page = (u_char)(bytenum >> 16);
	    if (svga_curpage != page) {
		svga_curpage = page;
		SetPage();
	    }
	    w = xEnd - ppt->x;
	    if ((u_short)cp + w >= 0x10000) {
		int i = 0x10000 - (u_short)cp;
		vga_memcpy(pdst, cp, i);
		w -= i;
		++svga_curpage;
		cp = vga_mem(0);
		SetPage();
		vga_memcpy(pdst + i, cp, w);
	    } else
		vga_memcpy(pdst, cp, w);
	    pdst += PixmapBytePad(wMax, 8);
	    ppt++;
	    pwidth++;
	}
    }
    else
    {
	u_char *psrcBase, *psrc;

	psrcBase = ((PixmapPtr)pDrawable)->devPrivate.ptr;
	widthSrc = (int)(((PixmapPtr)pDrawable)->devKind);
	if (pDrawable->depth == 1) {	/* bitmap */
	    while(ppt < pptLast) {
		xEnd = min(ppt->x + *pwidth, widthSrc << 3);
		pwidth++;
		psrc = psrcBase + (ppt->y * widthSrc) + (ppt->x >> 3);
		w = xEnd - ppt->x;
		srcBit = ppt->x & 7;

		copybits(pdst, psrc, 0, srcBit, w);
		pdst += PixmapBytePad(wMax, 1);
		ppt++;
	    }
	} else {
	    while(ppt < pptLast) {
		xEnd = min(ppt->x + *pwidth, widthSrc);
		pwidth++;
		psrc = psrcBase + (ppt->y * widthSrc) + ppt->x;
		w = xEnd - ppt->x;

		memcpy(pdst, psrc, w);
		pdst += PixmapBytePad(wMax, 8);
		ppt++;
	    }
	}
    }
}
