#include "medisp.h"
/*
* Erase the message line.
* This is a special routine because
* the message line is not considered to be
* part of the virtual screen. It always works
* immediately; the terminal buffer is flushed
* via a call to the flusher.
*/
mlerase()
{
movecursor(23, 0);
ansieeol();
mpresf = FALSE;
}
/*
* Ask a yes or no question in
* the message line. Return either TRUE,
* FALSE, or ABORT. The ABORT status is returned
* if the user bumps out of the question with
* a ^G. Used any time a confirmation is
* required.
*/
mlyesno(prompt)
char *prompt;
{
register int s;
char buf[64];
strcpy(buf, prompt);
strcat(buf, " [y/n]? ");
s = mlreply(buf, buf, sizeof(buf));
if ( s == ABORT ) return (ABORT);
if ( s != FALSE && ( buf[0] == 'y' || buf[0] == 'Y' ))
return ( 1 );
return ( 0 );
}
/*
* Write a prompt into the message
* line, then read back a response. Keep
* track of the physical position of the cursor.
* If we are in a keyboard macro throw the prompt
* away, and return the remembered response. This
* lets macros run at full speed. The reply is
* always terminated by a carriage return. Handle
* erase, kill, and abort keys.
*/
mlreply(prompt, buf, nbuf)
char *prompt;
char *buf;
{
register int cpos;
register int c;
cpos = 0;
mlwrite(prompt);
for (;;)
{ switch ( c = getstroke())
{
case 0x0D: /* Return, end of line */
buf[cpos++] = 0;
conout( '\r' );
ttcol = 0;
if (buf[0] == 0)
return (FALSE);
return (TRUE);
case 0x7F: /* Rubout, erase */
case 0x08: /* Backspace, erase */
if (cpos != 0)
{ crtbs();
if (buf[--cpos] < 0x20)
{ crtbs();
}
}
break;
#ifdef NEVER
case 0x15: /* C-U, kill */
while (cpos != 0)
{ crtbs();
if (buf[--cpos] < 0x20)
{ crtbs();
}
}
break;
#endif
default:
if (cpos < nbuf-1)
{ buf[cpos++] = c;
if (c < ' ')
{ conout( '^' );
++ttcol;
c ^= 0x40;
}
conout( c );
++ttcol;
}
}
}
}
crtbs()
{ conout( '\b' );
conout( ' ' );
conout( '\b' );
--ttcol;
}
conout( c )
{ bios( 4, c );
}
/*
* Write a message into the message
* line. Keep track of the physical cursor
* position. A small class of printf like format
* items is handled. Assumes the stack grows
* down; this assumption is made by the "++"
* in the argument scan loop. Set the "message
* line" flag TRUE.
*/
mlwrite(fmt, arg)
char *fmt;
{
register int c;
register char *ap;
movecursor(23, 0);
ap = (char *) &arg;
while ((c = *fmt++) != 0)
{ if (c != '%') goto out_it;
c = *fmt++;
switch (c)
{ case 'd':
mlputi(*(int *)ap, 10);
ap += sizeof(int);
break;
#ifdef NEVER
case 'o':
mlputi(*(int *)ap, 8);
ap += sizeof(int);
break;
case 'x':
mlputi(*(int *)ap, 16);
ap += sizeof(int);
break;
case 'D':
mlputli(*(long *)ap, 10);
ap += sizeof(long);
break;
#endif
case 's':
mlputs(*(char **)ap);
ap += sizeof(char *);
break;
/*
* Write out a string.
* Update the physical cursor position.
* This assumes that the characters in the
* string all have width "1"; if this is
* not the case things will get screwed up
* a little.
*/
mlputs(s)
char *s;
{
register int c;
while ((c = *s++) != 0)
{ conout( c );
++ttcol;
}
}
/*
* Write out an integer, in
* the specified radix. Update the physical
* cursor position. This will not handle any
* negative numbers; maybe it should.
*/
mlputi(i, r)
{
register int q;
static char hexdigits[] = "0123456789ABCDEF";
if (i < 0)
{ i = -i;
conout( '-');
}
q = i/r;
if (q != 0) mlputi(q, r);
conout( hexdigits[i%r]);
++ttcol;
}
#ifdef NEVER
/*
* do the same except as a long integer.
*/
mlputli(l, r)
long l;
{
register long q;
if (l < 0)
{ l = -l;
conout( '-');
}
q = l/r;
if (q != 0) mlputli(q, r);
conout( (int)(l%r)+'0');
++ttcol;
}
#endif