#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 0x07: /* Bell, abort */ conout( '^' ); conout( 'G' ); ttcol += 2; ctrlg(); return (ABORT); 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; default: out_it: conout( c ); ++ttcol; } } ansieeol(); mpresf = TRUE; } /* * 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  .