#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 "ega.h"
#include "maskbits.h"

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

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

void
egaGetSpans(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;
    int			iswin;
    _segment		base;
    unsigned char _based(base)	*psrcBase, _based(base) *psrc;

    pptLast = ppt + nspans;

    if (pDrawable->type == DRAWABLE_WINDOW)
    {
	egaPrivScr *pPriv = (egaPrivScr *)(pDrawable->pScreen->devPrivate);

	iswin = 1;
	base = pPriv->fb;
	psrcBase = 0;
	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
    }
    else
    {
	iswin = 0;
	base = (u_short)((u_long)(((PixmapPtr)pDrawable)->devPrivate.ptr) >> 16);
	psrcBase = (u_char _based(base) *)(u_short)(u_long)(((PixmapPtr)pDrawable)->devPrivate.ptr);
	widthSrc = (int)(((PixmapPtr)pDrawable)->devKind);
    }

    while(ppt < pptLast)
    {
	xEnd = min(ppt->x + *pwidth, widthSrc << 3);
	pwidth++;
	psrc = psrcBase + (ppt->y * widthSrc) + (ppt->x >> 3); 
#ifdef EGA_HIRES
	if (egapriv.hires && iswin) {
	    if (ppt->y >= HIRES_LPP) {
		if (!egapriv.curpage)
		    (*vga_conf.page)(egapriv.curpage = 1);
	    } else if (egapriv.curpage)
		(*vga_conf.page)(egapriv.curpage = 0);
	}
#endif
	w = xEnd - ppt->x;
	srcBit = ppt->x & 7;

	copybits((char _far *)psrc, pdst, srcBit, 0, w);
        pdst += PixmapBytePad(wMax, 1);
	ppt++;
    }
#ifdef DIRECT_MOUSE
    /* turn cursor back on */
    if (iswin)
	    ShowCursor();
#endif
}

egaGetImage(pDrawable, x, y, width, height, format, planeMask, pDst)
DrawablePtr pDrawable;
unsigned x, y;
int width, height;
unsigned int format;
unsigned long planeMask;
pointer pDst;
{
    int iswin;
    _segment base;
    unsigned char _based(base) *psrcBase;
    int bytewidth, extra;

    if (pDrawable->type == DRAWABLE_WINDOW) {
	egaPrivScr *pPriv = (egaPrivScr *)(pDrawable->pScreen->devPrivate);

	x += pDrawable->x;
	y += pDrawable->y;

	iswin = 1;
	base = pPriv->fb;
	psrcBase = 0;
	bytewidth = 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
    }
    else
    {
	iswin = 0;
	base = (u_short)((u_long)(((PixmapPtr)pDrawable)->devPrivate.ptr) >> 16);
	psrcBase = (u_char _based(base) *)(u_short)(u_long)(((PixmapPtr)pDrawable)->devPrivate.ptr);
	bytewidth = (int)(((PixmapPtr)pDrawable)->devKind);
    }
    psrcBase += (x>>3) + y * bytewidth;
#ifdef EGA_HIRES
    if (egapriv.hires && iswin) {
	if (y >= HIRES_LPP) {
	    if (!egapriv.curpage)
		(*vga_conf.page)(egapriv.curpage = 1);
	    extra = 0;
	} else {
	    if (egapriv.curpage)
		(*vga_conf.page)(egapriv.curpage = 0);
	    if (y + height > HIRES_LPP) {
		extra = y + height - HIRES_LPP;
		height -= extra;
	    } else
		extra = 0;
	}
    } else
	extra = 0;
#endif
    y = bytewidth;
    bytewidth = PixmapBytePad(width, 1);
    x &= 7;
more:
    while (height-- > 0) {
	copybits((char _far *)psrcBase, pDst, x, 0, width);
	pDst = (char *)pDst + bytewidth;
	psrcBase += y;	/* go to next line */
    }
#ifdef EGA_HIRES
    if (extra) {
	height = extra;
	extra = 0;
	(*vga_conf.page)(egapriv.curpage = 1);
	goto more;
    }
#endif
    return 0;
}
