/*
 * Name:	MicroEMACS
 *		Digital ANSI terminal display
 * Version:	29
 * Last edit:	10-Feb-86
 * By:		rex::conroy
 *		decvax!decwrl!dec-rhea!dec-rex!conroy
 *
 * The SCALD display is just an ANSI display, with
 * some special hacks to kludge around the bugs, and
 * to make it a bit more friendly. The support is
 * unquestionably non-optimal. The costs are wrong; in
 * fact, display should be fixed up to understand non
 * linear cost devices like the SCALD. The BackIndex
 * sequence. The
 * value is from the ITS EMACS manual. The
 * hard update is done because the top line in
 * the window is zapped.
 */
backpage(f, n, k)
register int	n;
{
	register LINE	*lp;

	if (f == FALSE) {
		n = curwp->w_ntrows - 2;	/* Default scroll.	*/
		if (n <= 0)			/* Don't blow up if the	*/
			n = 1;			/* window is tiny.	*/
	} else if (n < 0)
		return (forwpage(f, -n, KRANDOM));
#if	CVMVAS
	else					/* Convert from pages	*/
		n *= curwp->w_ntrows;		/* to lines.		*/
#endif
	lp = curwp->w_linep;
	while (n-- && lback(lp)!=curbp->b_linep)
		lp = lback(lp);
	curwp->w_linep = lp;
	curwp->w_dotp  = lp;
	curwp->w_doto  = 0;
	curwp->w_flag |= WFHARD;
	return (TRUE);
}

/*
 * Set the mark in the current window
 * to the value of dot. A message is written to
 * the echo line unless we are running in a keyboard
 * macro, when it would be silly.
 */
setmark(f, n, k)
{
	isetmark();
	if (kbdmop == NULL)
		eprintf("[Mark set]");
	return (TRUE);
}

/* 
 * So other commands can set the mark easily.  (daveb)
 */
isetmark()
{
	curwp->w_markp = curwp->w_dotp;
	curwp->w_marko = curwp->w_doto;
}


/*
 * Swap the values of "dot" and "mark" in
 * the current window. This is pretty easy, because
 * all of the hard work gets done by the standard routine
 * that moves the mark about. The only possible
 * error is "no mark".
 */
swapmark(f, n, k)
{
	register LINE	*odotp;
	register int	odoto;

	if (curwp->w_markp == NULL) {
		eprintf("No mark in this window");
		return (FALSE);
	}
	odotp = curwp->w_dotp;
	odoto = curwp->w_doto;
	curwp->w_dotp  = curwp->w_markp;
	curwp->w_doto  = curwp->w_marko;
	curwp->w_markp = odotp;
	curwp->w_marko = odoto;
	curwp->w_flag |= WFMOVE;
	return (TRUE);
}

/*
 * Go to a specific line, mostly for
 * looking up errors in C programs, which give the
 * error a line number. If an argument is present, then
 * it is the line number, else prompt for a line number
 * to use.
 */
gotoline(f, n, k)
register int	n;
{
	register LINE	*clp;
	register int	s;
	char		buf[32];

	if (f == FALSE) {
		if ((s=ereply("Goto line: ", buf, sizeof(buf))) != TRUE)
			return (s);
		n = atoi(buf);
	}
	if (n <= 0) {
		eprintf("Bad line");
		return (FALSE);
	}
	clp = lforw(curbp->b_linep);		/* "clp" is first line	*/
	while (n != 1) {
		if (clp == curbp->b_linep) {
			eprintf("Line number too large");
			return (FALSE);
		}
		clp = lforw(clp);
		--n;
	}
	curwp->w_dotp = clp;
	curwp->w_doto = 0;
	curwp->w_flag |= WFMOVE;
	return (TRUE);
}

	while (n-- && lback(lp)!=curbp->b_linep)
		lp = lback(lp);
	curwp->w_linep = lp;
	curwp->w_dotp  = lp;
	curwp->w_doto  = 0;
	curwp->w_flag |= WFHARD;
	return (TRUE);
}

/*
 * Set the mark in the current window
 * to the value of dot. A message is written to
 * the echo line unless we are running in a keyboard
 * macro, when it would be silly.
 */
setmark(f, n, k)
{
	isetmark();
	if (kbdmop == NULL)
		eprintf("[Mark set]");
	return (TRUE);
}

/* 
 * So other commands can /*
 * Name:	MicroEMACS
 *		Version stamp.
 * Version:	30
 * Last edit:	14-Feb-86
 * By:		rex::conroy
 *		decvax!decwrl!dec-rhea!dec-rex!conroy
 *
 * This file contains the string(s)
 * that get written out by the show version command.
 * Rich had it generated by a command file. I do
 * it manually, until I can figure out a way to get
 * the MicroEMACS version number generated in a
 * reasonable (automatic) manner. Perhaps a program
 * that reads "things2do.txt".
 */
#include	"def.h"

char	*version[] = {
	"MicroEMACS version 30",
	"Source from REX::USER$A:[CONROY.HACKING.MINIEMACS]",
	NULL
}; 
 curwp->w_marko;
	curwp->w_markp = odotp;
	curwp->w_marko = odoto;
	curwp->w_flag |= WFMOVE;
	return (TRUE);
}

/*
 * Go to a specific line, mostly for
 * looking up errors in C programs, which give the
 * error a line number. If an argument is present, then
 * it is the line number, else prompt for a line number
 * to use.
 */
gotoline(f, n, k)
register int	n;
{
	register                    s                 "           @           
=  R                  1   -                         i     =  ^         1            j               h   )                 N                    6         +         U           	                                           1      E            p                                           A                             (                                S                                          [                     0           (                      "                                 	                                        x                                              6               #                E   a          <              !           (     s#   @#   D H~*@,y   #   ,#   <B   8N(@#    $J g    #   a b |    BN   0X @ h "h  9   @r #   LЁRBgR@UBw   9   @ y   D$ Sԁ    SQ    S    Q"O/	N    p `f# :   a  a  #   8/ $@ * $g,y   0 @"(  N"*  g$<  N#   Hg
 @)h  Hy    N    p ` / / N   J   8g,"9   (gN"9   HgN,y   N|"y   8N .y   <L~NuH.< ,x NL`pd`A \NA \NNuC   Pp N#   0gNu              V            ~  r  \  P  H  ,                       x   L   8   (   "                  ^      }  B           2                                video.	*/
			ttputc(ESC);
			ttputc('[');
			ttputc('m');
		} else if (color == CMODE) {	/* Reverse video.	*/
			ttputc(ESC);
			ttputc('[');
			ttputc('7');
			ttputc('m');
		}
/*
endif
*/
		tthue = color;			/* Save the color.	*/
	}
}

/*
 * This routine is called by the
 * "refresh the screen" command to try and resize
 * the display. The new size, which must be deadstopped
 * to not exceed the NROW and NCOL limits, it stored
 * back into "nrow" and "ncol". Display can always deal
 * with a screen NROW by NCOL. Look in "window.c" to
 * see how the caller deals with a change.
 */
ttresize()
{
	register int	c;
	register int	newnrow;
	register int	newncol;

	ttputc(ESC);				/* Off the end of the	*/
	ttputc('[');				/* world. The terminal	*/
	asciiparm(HUGE);			/* will chop it.	*/
	ttputc(';');
	asciiparm(HUGE);
	ttputc('H');
	ttrow = HUGE;				/* Unknown.		*/
	ttcol = HUGE;
	ttputc(ESC);				/* Report position.	*/
	ttputc('[');
	ttputc('6');
	ttputc('n');
	ttflush();
	if (ttgetc()!=ESC || ttgetc()!='[')
		return;
	newnrow = 0;
	while ((c=ttgetc())>='0' && c<='9')
		newnrow = 10*newnrow + c - '0';
	if (c != ';')
		return;
	newncol = 0;
	while ((c=ttgetc())>='0' && c<='9')
		newncol = 10*newncol + c - '0';
	if (c != 'R')
		return;
	if (newnrow < 1)			/* Check limits.	*/
		newnrow = 1;
	else if (newnrow > NROW)
		newnrow = NROW;
	if (newncol < 1)
		newncol = 1;
	else if (newncol > NCOL)
		newncol = NCOL;
	nrow = newnrow;
	ncol = newncol;
}
