#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 "vga.h"

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

typedef unsigned char u_char;
typedef unsigned short u_short;
typedef unsigned long u_long;

void
vgaGetSpans(pDrawable, wMax, ppt, pwidth, nspans, pdst)
    DrawablePtr		pDrawable;
    int			wMax;		/* largest value of all *pwidths */
    register 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)
    {
	vgaPrivScr *pPriv = (vgaPrivScr *)(pDrawable->pScreen->devPrivate);
	_segment		base = pPriv->fb;
	u_char _based(base)	*psrcBase;
	u_char data[4];		/* data from 4 bit planes */
	char soff, doff;
	u_char mask, dout, tmp;
	u_char *pDst;

	base = pPriv->fb;
	widthSrc = pPriv->devKind;
#ifdef DIRECT_MOUSE
	/* Turn cursor off */
	ConditionalOff(pDrawable->x, pDrawable->y,
	    pDrawable->x + pDrawable->width,
	    pDrawable->y + pDrawable->height);
#else
	if (CUR_OVERLAP(pDrawable->x, pDrawable->y,
	    pDrawable->x + pDrawable->width,
	    pDrawable->y + pDrawable->height))
		HideCursor();
#endif
	while(ppt < pptLast) {
	    psrcBase = (char _based(base) *)(ppt->y * widthSrc + (ppt->x >> 3));
	    pDst = pdst;
	    xEnd = min(ppt->x + *pwidth, widthSrc << 3);
	    w = xEnd - ppt->x;
	    soff = ppt->x & 7;
	    doff = 0;
	    while (w) {
		/* Get data from each plane into data[] */
		outpw(0x3ce, 0x0004);
		data[0] = *psrcBase;
		outpw(0x3ce, 0x0104);
		data[1] = *psrcBase;
		outpw(0x3ce, 0x0204);
		data[2] = *psrcBase;
		outpw(0x3ce, 0x0304);
		data[3] = *psrcBase;
		psrcBase++;
		mask = 0x80 >> soff;
		soff = 0;
		while (mask) {
		    tmp = (data[0] & mask ? 1 : 0) +
			  (data[1] & mask ? 2 : 0) +
			  (data[2] & mask ? 4 : 0) +
			  (data[3] & mask ? 8 : 0);
		    if (doff) {
			*pDst++ = dout | tmp;
			doff = 0;
		    } else {
			dout = tmp << 4;
			doff = 1;
		    }
		    mask >>= 1;
		    if (!--w)
			break;
		}
	    }
	    if (doff)
		*pDst = dout;
	    pdst += PixmapBytePad(wMax, 4);
	    ppt++;
	    pwidth++;
	}
printf("pdst=%lx\n", pdst);
#ifdef DIRECT_MOUSE
	ShowCursor();
#endif
    }
    else
    {
	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);
		psrc = psrcBase + (ppt->y * widthSrc) + (ppt->x >> 3);
		w = xEnd - ppt->x;
		srcBit = ppt->x & 7;

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

		copybits((char _far *)psrc, pdst, srcBit, 0, w);
		memcpy(pdst, (char far *)psrc, w);
		pdst += PixmapBytePad(wMax, 4);
		pwidth++;
		ppt++;
	    }
	}
    }
}
