home *** CD-ROM | disk | FTP | other *** search
- /*
- * file:mldisplay.c ::= routines dealing with message line below the mode line.
- *
- * N.B. \033q is sent more often than should be necessary because
- * the ST remains in reverse video, in some situations, even after
- * receiving a \033q.
- */
-
- #include "ed.h"
- #include "osbind.h"
-
- #define WFDEBUG 0 /* Window flag debug. */
-
- #define VFCHG 0x0001 /* Changed. */
- #define MDLIN 0x0002
-
- extern
- int sgarbf,
- mpresf,
- vtrow,
- vtcol,
- ttrow,
- ttcol;
-
-
- extern VIDEO **vscreen; /* Virtual screen. */
- extern VIDEO **pscreen; /* Physical screen. */
-
- #define NROW 25 /* Screen size. */
- #define NCOL 80 /* Edit if you want to. */
- #define BIAS 0x20 /* Origin 0 coordinate bias. */
-
- TERM term = {
- NROW-1,
- NCOL
- };
-
- /*
- * Redisplay the mode line for the window pointed to by the "wp". This is the
- * only routine that has any idea of how the modeline is formatted. You can
- * change the modeline format by hacking at this routine. Called by "update"
- * any time there is a dirty window.
- */
- modeline(wp)
- WINDOW *wp;
- {
- register char *cp;
- register char *mp;
- register int c;
- register int n;
- register BUFFER *bp;
- char md[NCOL+NCOL]; /* so we can forget about range check */
-
-
- for (mp=md; mp < &md[NCOL];) *mp++ = '-';
-
- n = wp->w_toprow+wp->w_ntrows; /* Location. */
- vscreen[n]->v_flag |= VFCHG | MDLIN; /* Redraw next time. */
- vtmove(n, 0); /* Seek to right line. */
-
- bp = wp->w_bufp;
- if ((bp->b_flag&BFCHG) != 0) /* "*" if changed. */
- md[1] = md[2] = '*';
-
- mp = &md[4];
- cp = " microEmacs -- ";
- while ((*mp++ = *cp++) != 0);
- mp --;
-
- cp = &bp->b_bname[0]; /* Buffer name. */
- while ((*mp++ = *cp++) != 0);
- mp[-1] = ' ';
-
- if (bp->b_fname[0] != 0) /* File name. */
- {
- cp = "-- File: ";
- while ((*mp++ = *cp++) != 0);
- mp--;
- cp = &bp->b_fname[0];
- while ((*mp++ = *cp++) != 0);
- mp[-1] = ' ';
- }
-
- for(mp=md; mp < &md[NCOL];)
- vtputc(*mp++);
- }
-
- /*
- * Send a command to the terminal to move the hardware cursor to row "row"
- * and column "col". The row and column arguments are origin 0. Optimize out
- * random calls. Update "ttrow" and "ttcol".
- */
- movecursor(row, col)
- {
- static char es[5] = "\033Yrc";
-
- if (row!=ttrow || col!=ttcol)
- {
- ttrow = row;
- ttcol = col;
- /* (*term.t_move)(row, col); */
- es[2] = (char) row + BIAS;
- es[3] = (char) col + BIAS;
- Cconws(es);
- }
- }
-
- /*
- * 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(term.t_nrow, 0);
- /* (*term.t_eeol)(); */
- /* (*term.t_flush)(); */
- Cconws("\033q\033K");
- 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];
-
- for (;;)
- {
- strcpy(buf, prompt);
- strcat(buf, " [y/n]? ");
- s = mlreply(buf, buf, sizeof(buf));
-
- if (s == ABORT)
- return (ABORT);
-
- if (s != FALSE)
- {
- if (buf[0]=='y' || buf[0]=='Y')
- return (TRUE);
-
- if (buf[0]=='n' || buf[0]=='N')
- return (FALSE);
- }
- }
- }
-
- /*
- * 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 i;
- register int c;
-
- cpos = 0;
-
- if (kbdmop != NULL)
- {
- while ((c = *kbdmop++) != '\0')
- buf[cpos++] = c;
-
- buf[cpos] = 0;
-
- if (buf[0] == 0)
- return (FALSE);
-
- return (TRUE);
- }
-
- mlwrite(prompt);
-
- for (;;)
- {
- /* c = (*term.t_getchar)(); */
- c = Crawcin();
- switch (c)
- {
- case 0x12: /* ^R */
- case 0x13: /* ^S */
- buf[cpos++] = c; /* fall through! */
- case 0x0D: /* Return, end of line */
- buf[cpos++] = 0;
-
- if (kbdmip != NULL)
- {
- if (kbdmip+cpos > &kbdm[NKBDM-3])
- {
- ctrlg(FALSE, 0);
- /* (*term.t_flush)(); */
- return (ABORT);
- }
-
- for (i=0; i<cpos; ++i)
- *kbdmip++ = buf[i];
- }
-
- Cconout('\r');
- ttcol = 0;
- /* (*term.t_flush)(); */
-
- if (buf[0] == 0)
- return (FALSE);
-
- return (TRUE);
-
- case 0x07: /* Bell, abort */
- Cconws("^G");
- ttcol += 2;
- ctrlg(FALSE, 0);
- /* (*term.t_flush)(); */
- return (ABORT);
-
- case 0x7F: /* Rubout, erase */
- case 0x08: /* Backspace, erase */
- if (cpos != 0)
- {
- Cconws("\b \b");
- --ttcol;
-
- if (buf[--cpos] < 0x20)
- {
- Cconws("\b \b");
- --ttcol;
- }
-
- /* (*term.t_flush)(); */
- }
-
- break;
-
- case 0x15: /* C-U, kill */
- while (cpos != 0)
- {
- Cconws("\b \b");
- --ttcol;
-
- if (buf[--cpos] < 0x20)
- {
- Cconws("\b \b");
- --ttcol;
- }
- }
-
- /* (*term.t_flush)(); */
- break;
-
- default:
- if (cpos < nbuf-1)
- {
- buf[cpos++] = c;
-
- if (c < ' ')
- {
- Cconout('^');
- ++ttcol;
- c ^= 0x40;
- }
-
- Cconout(c);
- ++ttcol;
- /* (*term.t_flush)(); */
- }
- }
- }
- }
-
- /*
- * 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;
-
- Cconws("\033q"); /* !! */
- movecursor(term.t_nrow, 0);
- ap = (char *) &arg;
- while ((c = *fmt++) != 0) {
- if (c != '%') {
- Cconout(c);
- ++ttcol;
- }
- else
- {
- c = *fmt++;
- switch (c) {
- case 'd':
- mlputi(*(int *)ap, 10);
- ap += sizeof(int);
- break;
-
- 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;
-
- case 's':
- mlputs(*(char **)ap);
- ap += sizeof(char *);
- break;
-
- default:
- Cconout(c);
- ++ttcol;
- }
- }
- }
- /* (*term.t_eeol)(); */
- /* (*term.t_flush)(); */
- Cconws("\033K");
- 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.
- */
- /* --------- #defined as Cconws in ed.h
- mlputs(s)
- char *s;
- {
- register int c;
-
- while ((c = *s++) != 0)
- {
- * (*term.t_putchar)(c); *
- Cconout(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;
- Cconout('-');
- }
-
- q = i/r;
-
- if (q != 0)
- mlputi(q, r);
-
- Cconout(hexdigits[i%r]);
- ++ttcol;
- }
-
- /*
- * do the same except as a long integer.
- */
- mlputli(l, r)
- long l;
- {
- register long q;
-
- if (l < 0)
- {
- l = -l;
- Cconout('-');
- }
-
- q = l/r;
-
- if (q != 0)
- mlputli(q, r);
-
- Cconout((int)(l%r)+'0');
- ++ttcol;
- }
-
- /* -eof- */
-