Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

v09i047: Repost of display.c from MicroEmacs, Patch1

3 views
Skip to first unread message

sources...@mirror.uucp

unread,
Apr 14, 1987, 5:57:48 PM4/14/87
to
Submitted by: pur-ee!pur-phy!duncan!lawrence
Mod.sources: Volume 9, Issue 47
Archive-name: uemacs3.8b/Patch1

[ When last we heard from this group, articles had been leaving
site "mirror" with 512 bytes elided from them... This is the
first of a couple of re-posts. --r$ ]

Daniel Lawrence can be reached at:
UUCP: ihnp4!pur-ee!pur-phy!duncan!lawrence
ARPA: n...@j.cc.purdue.edu
FIDO: The Programmer's Room 201/2
(317) 742-5533 300/1200 baud 24 hours
USmail: 617 New York St
Lafayette, IN 47901
ATT: (317) 742-5153
-----CUT-----HERE-----
#! /bin/sh
# This is a shell archive. Remove anything before this line,
# then unpack it by saving it in a file and typing "sh file".
# If this archive is complete, you will see the message:
# "End of shell archive."
# Contents: display.c
# Wrapped by rs@mirror on Tue Apr 14 16:52:46 1987
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
echo shar: Extracting \"display.c\" \(23829 characters\)
if test -f display.c ; then
echo shar: Will not over-write existing file \"display.c\"
else
sed "s/^X//" >display.c <<'END_OF_display.c'
X/*
X * The functions in this file handle redisplay. There are two halves, the
X * ones that update the virtual display screen, and the ones that make the
X * physical display screen the same as the virtual display screen. These
X * functions use hints that are left in the windows by the commands.
X *
X */
X
X#include <stdio.h>
X#include "estruct.h"
X#include "edef.h"
X
X#if MEGAMAX & ST520
Xoverlay "display"
X#endif
X
Xtypedef struct VIDEO {
X int v_flag; /* Flags */
X#if COLOR
X int v_fcolor; /* current forground color */
X int v_bcolor; /* current background color */
X int v_rfcolor; /* requested forground color */
X int v_rbcolor; /* requested background color */
X#endif
X char v_text[1]; /* Screen data. */
X} VIDEO;
X
X#define VFCHG 0x0001 /* Changed flag */
X#define VFEXT 0x0002 /* extended (beyond column 80) */
X#define VFREV 0x0004 /* reverse video status */
X#define VFREQ 0x0008 /* reverse video request */
X#define VFCOL 0x0010 /* color change requested */
X
XVIDEO **vscreen; /* Virtual screen. */
X#if MEMMAP == 0
XVIDEO **pscreen; /* Physical screen. */
X#endif
X
X/*
X * Initialize the data structures used by the display code. The edge vectors
X * used to access the screens are set up. The operating system's terminal I/O
X * channel is set up. All the other things get initialized at compile time.
X * The original window has "WFCHG" set, so that it will get completely
X * redrawn on the first call to "update".
X */
Xvtinit()
X{
X register int i;
X register VIDEO *vp;
X char *malloc();
X
X TTopen(); /* open the screen */
X TTkopen(); /* open the keyboard */
X TTrev(FALSE);
X vscreen = (VIDEO **) malloc(term.t_nrow*sizeof(VIDEO *));
X
X if (vscreen == NULL)
X exit(1);
X
X#if MEMMAP == 0
X pscreen = (VIDEO **) malloc(term.t_nrow*sizeof(VIDEO *));
X
X if (pscreen == NULL)
X exit(1);
X#endif
X
X for (i = 0; i < term.t_nrow; ++i)
X {
X vp = (VIDEO *) malloc(sizeof(VIDEO)+term.t_mcol);
X
X if (vp == NULL)
X exit(1);
X
X vp->v_flag = 0;
X#if COLOR
X vp->v_rfcolor = 7;
X vp->v_rbcolor = 0;
X#endif
X vscreen[i] = vp;
X#if MEMMAP == 0
X vp = (VIDEO *) malloc(sizeof(VIDEO)+term.t_mcol);
X
X if (vp == NULL)
X exit(1);
X
X vp->v_flag = 0;
X pscreen[i] = vp;
X#endif
X }
X}
X
X/*
X * Clean up the virtual terminal system, in anticipation for a return to the
X * operating system. Move down to the last line and clear it out (the next
X * system prompt will be written in the line). Shut down the channel to the
X * terminal.
X */
Xvttidy()
X{
X mlerase();
X movecursor(term.t_nrow, 0);
X TTflush();
X TTclose();
X TTkclose();
X}
X
X/*
X * Set the virtual cursor to the specified row and column on the virtual
X * screen. There is no checking for nonsense values; this might be a good
X * idea during the early stages.
X */
Xvtmove(row, col)
X{
X vtrow = row;
X vtcol = col;
X}
X
X/* Write a character to the virtual screen. The virtual row and
X column are updated. If we are not yet on left edge, don't print
X it yet. If the line is too long put a "$" in the last column.
X This routine only puts printing characters into the virtual
X terminal buffers. Only column overflow is checked.
X*/
X
Xvtputc(c)
X
Xint c;
X
X{
X register VIDEO *vp; /* ptr to line being updated */
X
X vp = vscreen[vtrow];
X
X if (c == '\t') {
X do {
X vtputc(' ');
X } while (((vtcol + taboff)&0x07) != 0);
X } else if (vtcol >= term.t_ncol) {
X ++vtcol;
X vp->v_text[term.t_ncol - 1] = '$';
X } else if (c < 0x20 || c == 0x7F) {
X vtputc('^');
X vtputc(c ^ 0x40);
X } else {
X if (vtcol >= 0)
X vp->v_text[vtcol] = c;
X ++vtcol;
X }
X}
X
X/*
X * Erase from the end of the software cursor to the end of the line on which
X * the software cursor is located.
X */
Xvteeol()
X{
X register VIDEO *vp;
X
X vp = vscreen[vtrow];
X while (vtcol < term.t_ncol)
X vp->v_text[vtcol++] = ' ';
X}
X
X/* upscreen: user routine to force a screen update
X always finishes complete update */
X
Xupscreen(f, n)
X
X{
X update(TRUE);
X return(TRUE);
X}
X
X/*
X * Make sure that the display is right. This is a three part process. First,
X * scan through all of the windows looking for dirty ones. Check the framing,
X * and refresh the screen. Second, make sure that "currow" and "curcol" are
X * correct for the current window. Third, make the virtual and physical
X * screens the same.
X */
Xupdate(force)
X
Xint force; /* force update past type ahead? */
X
X{
X register WINDOW *wp;
X
X#if TYPEAH
X if (force == FALSE && typahead())
X return(TRUE);
X#endif
X#if VISMAC == 0
X if (force == FALSE && kbdmode == PLAY)
X return(TRUE);
X#endif
X
X /* update any windows that need refreshing */
X wp = wheadp;
X while (wp != NULL) {
X if (wp->w_flag) {
X /* if the window has changed, service it */
X reframe(wp); /* check the framing */
X if ((wp->w_flag & ~WFMODE) == WFEDIT)
X updone(wp); /* update EDITed line */
X else if (wp->w_flag & ~WFMOVE)
X updall(wp); /* update all lines */
X if (wp->w_flag & WFMODE)
X modeline(wp); /* update modeline */
X wp->w_flag = 0;
X wp->w_force = 0;
X }
X /* on to the next window */
X wp = wp->w_wndp;
X }
X
X /* recalc the current hardware cursor location */
X updpos();
X
X#if MEMMAP
X /* update the cursor and flush the buffers */
X movecursor(currow, curcol - lbound);
X#endif
X
X /* check for lines to de-extend */
X upddex();
X
X /* if screen is garbage, re-plot it */
X if (sgarbf != FALSE)
X updgar();
X
X /* update the virtual screen to the physical screen */
X updupd(force);
X
X /* update the cursor and flush the buffers */
X movecursor(currow, curcol - lbound);
X TTflush();
X return(TRUE);
X}
X
X/* reframe: check to see if the cursor is on in the window
X and re-frame it if needed or wanted */
X
Xreframe(wp)
X
XWINDOW *wp;
X
X{
X register LINE *lp;
X register int i;
X
X /* if not a requested reframe, check for a needed one */
X if ((wp->w_flag & WFFORCE) == 0) {
X lp = wp->w_linep;
X for (i = 0; i < wp->w_ntrows; i++) {
X
X /* if the line is in the window, no reframe */
X if (lp == wp->w_dotp)
X return(TRUE);
X
X /* if we are at the end of the file, reframe */
X if (lp == wp->w_bufp->b_linep)
X break;
X
X /* on to the next line */
X lp = lforw(lp);
X }
X }
X
X /* reaching here, we need a window refresh */
X i = wp->w_force;
X
X /* how far back to reframe? */
X if (i > 0) { /* only one screen worth of lines max */
X if (--i >= wp->w_ntrows)
X i = wp->w_ntrows - 1;
X } else if (i < 0) { /* negative update???? */
X i += wp->w_ntrows;
X if (i < 0)
X i = 0;
X } else
X i = wp->w_ntrows / 2;
X
X /* backup to new line at top of window */
X lp = wp->w_dotp;
X while (i != 0 && lback(lp) != wp->w_bufp->b_linep) {
X --i;
X lp = lback(lp);
X }
X
X /* and reset the current line at top of window */
X wp->w_linep = lp;
X wp->w_flag |= WFHARD;
X wp->w_flag &= ~WFFORCE;
X return(TRUE);
X}
X
X/* updone: update the current line to the virtual screen */
X
Xupdone(wp)
X
XWINDOW *wp; /* window to update current line in */
X
X{
X register LINE *lp; /* line to update */
X register int sline; /* physical screen line to update */
X register int i;
X
X /* search down the line we want */
X lp = wp->w_linep;
X sline = wp->w_toprow;
X while (lp != wp->w_dotp) {
X ++sline;
X lp = lforw(lp);
X }
X
X /* and update the virtual line */
X vscreen[sline]->v_flag |= VFCHG;
X vscreen[sline]->v_flag &= ~VFREQ;
X vtmove(sline, 0);
X for (i=0; i < llength(lp); ++i)
X vtputc(lgetc(lp, i));
X#if COLOR
X vscreen[sline]->v_rfcolor = wp->w_fcolor;
X vscreen[sline]->v_rbcolor = wp->w_bcolor;
X#endif
X vteeol();
X}
X
X/* updall: update all the lines in a window on the virtual screen */
X
Xupdall(wp)
X
XWINDOW *wp; /* window to update lines in */
X
X{
X register LINE *lp; /* line to update */
X register int sline; /* physical screen line to update */
X register int i;
X
X /* search down the lines, updating them */
X lp = wp->w_linep;
X sline = wp->w_toprow;
X while (sline < wp->w_toprow + wp->w_ntrows) {
X
X /* and update the virtual line */
X vscreen[sline]->v_flag |= VFCHG;
X vscreen[sline]->v_flag &= ~VFREQ;
X vtmove(sline, 0);
X if (lp != wp->w_bufp->b_linep) {
X /* if we are not at the end */
X for (i=0; i < llength(lp); ++i)
X vtputc(lgetc(lp, i));
X lp = lforw(lp);
X }
X
X /* on to the next one */
X#if COLOR
X vscreen[sline]->v_rfcolor = wp->w_fcolor;
X vscreen[sline]->v_rbcolor = wp->w_bcolor;
X#endif
X vteeol();
X ++sline;
X }
X
X}
X
X/* updpos: update the position of the hardware cursor and handle extended
X lines. This is the only update for simple moves. */
X
Xupdpos()
X
X{
X register LINE *lp;
X register int c;
X register int i;
X
X /* find the current row */
X lp = curwp->w_linep;
X currow = curwp->w_toprow;
X while (lp != curwp->w_dotp) {
X ++currow;
X lp = lforw(lp);
X }
X
X /* find the current column */
X curcol = 0;
X i = 0;
X while (i < curwp->w_doto) {
X c = lgetc(lp, i++);
X if (c == '\t')
X curcol |= 0x07;
X else
X if (c < 0x20 || c == 0x7f)
X ++curcol;
X
X ++curcol;
X }
X
X /* if extended, flag so and update the virtual line image */
X if (curcol >= term.t_ncol - 1) {
X vscreen[currow]->v_flag |= (VFEXT | VFCHG);
X updext();
X } else
X lbound = 0;
X}
X
X/* upddex: de-extend any line that derserves it */
X
Xupddex()
X
X{
X register WINDOW *wp;
X register LINE *lp;
X register int i,j;
X
X wp = wheadp;
X
X while (wp != NULL) {
X lp = wp->w_linep;
X i = wp->w_toprow;
X
X while (i < wp->w_toprow + wp->w_ntrows) {
X if (vscreen[i]->v_flag & VFEXT) {
X if ((wp != curwp) || (lp != wp->w_dotp) ||
X (curcol < term.t_ncol - 1)) {
X vtmove(i, 0);
X for (j = 0; j < llength(lp); ++j)
X vtputc(lgetc(lp, j));
X vteeol();
X
X /* this line no longer is extended */
X vscreen[i]->v_flag &= ~VFEXT;
X vscreen[i]->v_flag |= VFCHG;
X }
X }
X lp = lforw(lp);
X ++i;
X }
X /* and onward to the next window */
X wp = wp->w_wndp;
X }
X}
X
X/* updgar: if the screen is garbage, clear the physical screen and
X the virtual screen and force a full update */
X
Xupdgar()
X
X{
X register char *txt;
X register int i,j;
X
X for (i = 0; i < term.t_nrow; ++i) {
X vscreen[i]->v_flag |= VFCHG;
X#if REVSTA
X vscreen[i]->v_flag &= ~VFREV;
X#endif
X#if COLOR
X vscreen[i]->v_fcolor = gfcolor;
X vscreen[i]->v_bcolor = gbcolor;
X#endif
X#if MEMMAP == 0
X txt = pscreen[i]->v_text;
X for (j = 0; j < term.t_ncol; ++j)
X txt[j] = ' ';
X#endif
X }
X
X movecursor(0, 0); /* Erase the screen. */
X (*term.t_eeop)();
X sgarbf = FALSE; /* Erase-page clears */
X mpresf = FALSE; /* the message area. */
X#if COLOR
X mlerase(); /* needs to be cleared if colored */
X#endif
X}
X
X/* updupd: update the physical screen from the virtual screen */
X
Xupdupd(force)
X
Xint force; /* forced update flag */
X
X{
X register VIDEO *vp1;
X register int i;
X
X for (i = 0; i < term.t_nrow; ++i) {
X vp1 = vscreen[i];
X
X /* for each line that needs to be updated*/
X if ((vp1->v_flag & VFCHG) != 0) {
X#if TYPEAH
X if (force == FALSE && typahead())
X return(TRUE);
X#endif
X#if MEMMAP
X updateline(i, vp1);
X#else
X updateline(i, vp1, pscreen[i]);
X#endif
X }
X }
X return(TRUE);
X}
X
X/* updext: update the extended line which the cursor is currently
X on at a column greater than the terminal width. The line
X will be scrolled right or left to let the user see where
X the cursor is
X */
X
Xupdext()
X
X{
X register int rcursor; /* real cursor location */
X register LINE *lp; /* pointer to current line */
X register int j; /* index into line */
X
X /* calculate what column the real cursor will end up in */
X rcursor = ((curcol - term.t_ncol) % term.t_scrsiz) + term.t_margin;
X taboff = lbound = curcol - rcursor + 1;
X
X /* scan through the line outputing characters to the virtual screen */
X /* once we reach the left edge */
X vtmove(currow, -lbound); /* start scanning offscreen */
X lp = curwp->w_dotp; /* line to output */
X for (j=0; j<llength(lp); ++j) /* until the end-of-line */
X vtputc(lgetc(lp, j));
X
X /* truncate the virtual line, restore tab offset */
X vteeol();
X taboff = 0;
X
X /* and put a '$' in column 1 */
X vscreen[currow]->v_text[0] = '$';
X}
X
X/*
X * Update a single line. This does not know how to use insert or delete
X * character sequences; we are using VT52 functionality. Update the physical
X * row and column variables. It does try an exploit erase to end of line. The
X * RAINBOW version of this routine uses fast video.
X */
X#if MEMMAP
X/* UPDATELINE specific code for the IBM-PC and other compatables */
X
Xupdateline(row, vp1)
X
Xint row; /* row of screen to update */
Xstruct VIDEO *vp1; /* virtual screen image */
X
X{
X#if COLOR
X scwrite(row, vp1->v_text, vp1->v_rfcolor, vp1->v_rbcolor);
X vp1->v_fcolor = vp1->v_rfcolor;
X vp1->v_bcolor = vp1->v_rbcolor;
X#else
X if (vp1->v_flag & VFREQ)
X scwrite(row, vp1->v_text, 0, 7);
X else
X scwrite(row, vp1->v_text, 7, 0);
X#endif
X vp1->v_flag &= ~(VFCHG | VFCOL); /* flag this line as changed */
X
X}
X
X#else
X
Xupdateline(row, vp1, vp2)
X
Xint row; /* row of screen to update */
Xstruct VIDEO *vp1; /* virtual screen image */
Xstruct VIDEO *vp2; /* physical screen image */
X
X{
X#if RAINBOW
X/* UPDATELINE specific code for the DEC rainbow 100 micro */
X
X register char *cp1;
X register char *cp2;
X register int nch;
X
X /* since we don't know how to make the rainbow do this, turn it off */
X flags &= (~VFREV & ~VFREQ);
X
X cp1 = &vp1->v_text[0]; /* Use fast video. */
X cp2 = &vp2->v_text[0];
X putline(row+1, 1, cp1);
X nch = term.t_ncol;
X
X do
X {
X *cp2 = *cp1;
X ++cp2;
X ++cp1;
X }
X while (--nch);
X *flags &= ~VFCHG;
X#else
X/* UPDATELINE code for all other versions */
X
X register char *cp1;
X register char *cp2;
X register char *cp3;
X register char *cp4;
X register char *cp5;
X register int nbflag; /* non-blanks to the right flag? */
X int rev; /* reverse video flag */
X int req; /* reverse video request flag */
X
X
X /* set up pointers to virtual and physical lines */
X cp1 = &vp1->v_text[0];
X cp2 = &vp2->v_text[0];
X
X#if COLOR
X TTforg(vp1->v_rfcolor);
X TTbacg(vp1->v_rbcolor);
X#endif
X
X#if REVSTA | COLOR
X /* if we need to change the reverse video status of the
X current line, we need to re-write the entire line */
X rev = (vp1->v_flag & VFREV) == VFREV;
X req = (vp1->v_flag & VFREQ) == VFREQ;
X if ((rev != req)
X#if COLOR
X || (vp1->v_fcolor != vp1->v_rfcolor) || (vp1->v_bcolor != vp1->v_rbcolor)
X#endif
X#if HP150
X /* the HP150 has some reverse video problems */
X || req || rev
X#endif
X ) {
X movecursor(row, 0); /* Go to start of line. */
X /* set rev video if needed */
X if (rev != req)
X (*term.t_rev)(req);
X
X /* scan through the line and dump it to the screen and
X the virtual screen array */
X cp3 = &vp1->v_text[term.t_ncol];
X while (cp1 < cp3) {
X TTputc(*cp1);
X ++ttcol;
X *cp2++ = *cp1++;
X }
X /* turn rev video off */
X if (rev != req)
X (*term.t_rev)(FALSE);
X
X /* update the needed flags */
X vp1->v_flag &= ~VFCHG;
X if (req)
X vp1->v_flag |= VFREV;
X else
X vp1->v_flag &= ~VFREV;
X#if COLOR
X vp1->v_fcolor = vp1->v_rfcolor;
X vp1->v_bcolor = vp1->v_rbcolor;
X#endif
X return(TRUE);
X }
X#endif
X
X /* advance past any common chars at the left */
X while (cp1 != &vp1->v_text[term.t_ncol] && cp1[0] == cp2[0]) {
X ++cp1;
X ++cp2;
X }
X
X/* This can still happen, even though we only call this routine on changed
X * lines. A hard update is always done when a line splits, a massive
X * change is done, or a buffer is displayed twice. This optimizes out most
X * of the excess updating. A lot of computes are used, but these tend to
X * be hard operations that do a lot of update, so I don't really care.
X */
X /* if both lines are the same, no update needs to be done */
X if (cp1 == &vp1->v_text[term.t_ncol]) {
X vp1->v_flag &= ~VFCHG; /* flag this line is changed */
X return(TRUE);
X }
X
X /* find out if there is a match on the right */
X nbflag = FALSE;
X cp3 = &vp1->v_text[term.t_ncol];
X cp4 = &vp2->v_text[term.t_ncol];
X
X while (cp3[-1] == cp4[-1]) {
X --cp3;
X --cp4;
X if (cp3[0] != ' ') /* Note if any nonblank */
X nbflag = TRUE; /* in right match. */
X }
X
X cp5 = cp3;
X
X /* Erase to EOL ? */
X if (nbflag == FALSE && eolexist == TRUE && (req != TRUE)) {
X while (cp5!=cp1 && cp5[-1]==' ')
X --cp5;
X
X if (cp3-cp5 <= 3) /* Use only if erase is */
X cp5 = cp3; /* fewer characters. */
X }
X
X movecursor(row, cp1 - &vp1->v_text[0]); /* Go to start of line. */
X#if REVSTA
X TTrev(rev);
X#endif
X
X while (cp1 != cp5) { /* Ordinary. */
X TTputc(*cp1);
X ++ttcol;
X *cp2++ = *cp1++;
X }
X
X if (cp5 != cp3) { /* Erase. */
X TTeeol();
X while (cp1 != cp3)
X *cp2++ = *cp1++;
X }
X#if REVSTA
X TTrev(FALSE);
X#endif
X vp1->v_flag &= ~VFCHG; /* flag this line as updated */
X return(TRUE);
X#endif
X}
X#endif
X
X/*
X * Redisplay the mode line for the window pointed to by the "wp". This is the
X * only routine that has any idea of how the modeline is formatted. You can
X * change the modeline format by hacking at this routine. Called by "update"
X * any time there is a dirty window.
X */
Xmodeline(wp)
X WINDOW *wp;
X{
X register char *cp;
X register int c;
X register int n; /* cursor position count */
X register BUFFER *bp;
X register i; /* loop index */
X register lchar; /* character to draw line in buffer with */
X register firstm; /* is this the first mode? */
X char tline[NLINE]; /* buffer for part of mode line */
X
X n = wp->w_toprow+wp->w_ntrows; /* Location. */
X vscreen[n]->v_flag |= VFCHG | VFREQ | VFCOL;/* Redraw next time. */
X#if COLOR
X vscreen[n]->v_rfcolor = 0; /* black on */
X vscreen[n]->v_rbcolor = 7; /* white.....*/
X#endif
X vtmove(n, 0); /* Seek to right line. */
X if (wp == curwp) /* mark the current buffer */
X lchar = '=';
X else
X#if REVSTA
X if (revexist)
X lchar = ' ';
X else
X#endif
X lchar = '-';
X
X vtputc(lchar);
X bp = wp->w_bufp;
X
X if ((bp->b_flag&BFCHG) != 0) /* "*" if changed. */
X vtputc('*');
X else
X vtputc(lchar);
X
X n = 2;
X strcpy(tline, " MicroEMACS "); /* Buffer name. */
X strcat(tline, VERSION);
X strcat(tline, " (");
X
X /* display the modes */
X
X firstm = TRUE;
X for (i = 0; i < NUMMODES; i++) /* add in the mode flags */
X if (wp->w_bufp->b_mode & (1 << i)) {
X if (firstm != TRUE)
X strcat(tline, " ");
X firstm = FALSE;
X strcat(tline, modename[i]);
X }
X strcat(tline,") ");
X
X cp = &tline[0];
X while ((c = *cp++) != 0)
X {
X vtputc(c);
X ++n;
X }
X
X#if 0
X vtputc(lchar);
X vtputc((wp->w_flag&WFCOLR) != 0 ? 'C' : lchar);
X vtputc((wp->w_flag&WFMODE) != 0 ? 'M' : lchar);
X vtputc((wp->w_flag&WFHARD) != 0 ? 'H' : lchar);
X vtputc((wp->w_flag&WFEDIT) != 0 ? 'E' : lchar);
X vtputc((wp->w_flag&WFMOVE) != 0 ? 'V' : lchar);
X vtputc((wp->w_flag&WFFORCE) != 0 ? 'F' : lchar);
X vtputc(lchar);
X n += 8;
X#endif
X
X vtputc(lchar);
X vtputc(lchar);
X vtputc(' ');
X n += 3;
X cp = &bp->b_bname[0];
X
X while ((c = *cp++) != 0)
X {
X vtputc(c);
X ++n;
X }
X
X vtputc(' ');
X vtputc(lchar);
X vtputc(lchar);
X n += 3;
X
X if (bp->b_fname[0] != 0) /* File name. */
X {
X vtputc(' ');
X ++n;
X cp = "File: ";
X
X while ((c = *cp++) != 0)
X {
X vtputc(c);
X ++n;
X }
X
X cp = &bp->b_fname[0];
X
X while ((c = *cp++) != 0)
X {
X vtputc(c);
X ++n;
X }
X
X vtputc(' ');
X ++n;
X }
X
X while (n < term.t_ncol) /* Pad to full width. */
X {
X vtputc(lchar);
X ++n;
X }
X}
X
Xupmode() /* update all the mode lines */
X
X{
X register WINDOW *wp;
X
X wp = wheadp;
X while (wp != NULL) {
X wp->w_flag |= WFMODE;
X wp = wp->w_wndp;
X }
X}
X
X/*
X * Send a command to the terminal to move the hardware cursor to row "row"
X * and column "col". The row and column arguments are origin 0. Optimize out
X * random calls. Update "ttrow" and "ttcol".
X */
Xmovecursor(row, col)
X {
X if (row!=ttrow || col!=ttcol)
X {
X ttrow = row;
X ttcol = col;
X TTmove(row, col);
X }
X }
X
X/*
X * Erase the message line. This is a special routine because the message line
X * is not considered to be part of the virtual screen. It always works
X * immediately; the terminal buffer is flushed via a call to the flusher.
X */
Xmlerase()
X {
X int i;
X
X movecursor(term.t_nrow, 0);
X#if COLOR
X TTforg(7);
X TTbacg(0);
X#endif
X if (eolexist == TRUE)
X TTeeol();
X else {
X for (i = 0; i < term.t_ncol - 1; i++)
X TTputc(' ');
X movecursor(term.t_nrow, 1); /* force the move! */
X movecursor(term.t_nrow, 0);
X }
X TTflush();
X mpresf = FALSE;
X }
X
X/*
X * Write a message into the message line. Keep track of the physical cursor
X * position. A small class of printf like format items is handled. Assumes the
X * stack grows down; this assumption is made by the "++" in the argument scan
X * loop. Set the "message line" flag TRUE.
X */
X
Xmlwrite(fmt, arg)
X char *fmt;
X {
X register int c;
X register char *ap;
X
X#if COLOR
X TTforg(7);
X TTbacg(0);
X#endif
X if (eolexist == FALSE) {
X mlerase();
X TTflush();
X }
X
X movecursor(term.t_nrow, 0);
X ap = (char *) &arg;
X while ((c = *fmt++) != 0) {
X if (c != '%') {
X TTputc(c);
X ++ttcol;
X }
X else
X {
X c = *fmt++;
X switch (c) {
X case 'd':
X mlputi(*(int *)ap, 10);
X ap += sizeof(int);
X break;
X
X case 'o':
X mlputi(*(int *)ap, 8);
X ap += sizeof(int);
X break;
X
X case 'x':
X mlputi(*(int *)ap, 16);
X ap += sizeof(int);
X break;
X
X case 'D':
X mlputli(*(long *)ap, 10);
X ap += sizeof(long);
X break;
X
X case 's':
X mlputs(*(char **)ap);
X ap += sizeof(char *);
X break;
X
X case 'f':
X mlputf(*(int *)ap);
X ap += sizeof(int);
X break;
X
X default:
X TTputc(c);
X ++ttcol;
X }
X }
X }
X if (eolexist == TRUE)
X TTeeol();
X TTflush();
X mpresf = TRUE;
X }
X
X/*
X * Write out a string. Update the physical cursor position. This assumes that
X * the characters in the string all have width "1"; if this is not the case
X * things will get screwed up a little.
X */
Xmlputs(s)
X char *s;
X {
X register int c;
X
X while ((c = *s++) != 0)
X {
X TTputc(c);
X ++ttcol;
X }
X }
X
X/*
X * Write out an integer, in the specified radix. Update the physical cursor
X * position.
X */
Xmlputi(i, r)
X {
X register int q;
X static char hexdigits[] = "0123456789ABCDEF";
X
X if (i < 0)
X {
X i = -i;
X TTputc('-');
X }
X
X q = i/r;
X
X if (q != 0)
X mlputi(q, r);
X
X TTputc(hexdigits[i%r]);
X ++ttcol;
X }
X
X/*
X * do the same except as a long integer.
X */
Xmlputli(l, r)
X long l;
X {
X register long q;
X
X if (l < 0)
X {
X l = -l;
X TTputc('-');
X }
X
X q = l/r;
X
X if (q != 0)
X mlputli(q, r);
X
X TTputc((int)(l%r)+'0');
X ++ttcol;
X }
X
X/*
X * write out a scaled integer with two decimal places
X */
X
Xmlputf(s)
X
Xint s; /* scaled integer to output */
X
X{
X int i; /* integer portion of number */
X int f; /* fractional portion of number */
X
X /* break it up */
X i = s / 100;
X f = s % 100;
X
X /* send out the integer portion */
X mlputi(i, 10);
X TTputc('.');
X TTputc((f / 10) + '0');
X TTputc((f % 10) + '0');
X ttcol += 3;
X}
X
X#if RAINBOW
X
Xputline(row, col, buf)
X int row, col;
X char buf[];
X {
X int n;
X
X n = strlen(buf);
X if (col + n - 1 > term.t_ncol)
X n = term.t_ncol - col + 1;
X Put_Data(row, col, n, buf);
X }
X#endif
X
END_OF_display.c
if test 23829 -ne `wc -c <display.c`; then
echo shar: \"display.c\" unpacked with wrong size!?
fi
# end of overwriting check
fi
echo shar: End of shell archive.
exit 0

0 new messages