MicroEmacs, Version 3.7 (uEmacs3.7), Part02/12
sources-request at mirror.UUCP
sources-request at mirror.UUCP
Sat Jul 26 09:09:20 AEST 1986
Submitted by: ihnp4!pur-ee!pur-phy!duncan!lawrence
Mod.sources: Volume 6, Issue 72
Archive-name: uEmacs3.7/Part02
[ This is the latest revision of one of two programs named "MicroEmacs";
when discussing these on the net, or in contacting the authors, make
sure to mention the version number -- in this case 3.7 -- as that is
the easiest way to distinguish between them. Lawrence will be posting
uuencoded executables in net.micro.pc and net.micro.amiga; the file
'readme' contains information on how to also get these from him
directly. --r$ ]
echo extracting - dg10.c
sed 's/^X//' > dg10.c << 'FRIDAY_NIGHT'
X/*
X * The routines in this file provide support for the Data General Model 10
X * Microcomputer.
X */
X
X#define termdef 1 /* don't define "term" external */
X
X#include <stdio.h>
X#include "estruct.h"
X#include "edef.h"
X
X#if DG10
X
X#define NROW 24 /* Screen size. */
X#define NCOL 80 /* Edit if you want to. */
X#define NPAUSE 100 /* # times thru update to pause */
X#define MARGIN 8 /* size of minimim margin and */
X#define SCRSIZ 64 /* scroll size for extended lines */
X#define BEL 0x07 /* BEL character. */
X#define ESC 30 /* DG10 ESC character. */
X
Xextern int ttopen(); /* Forward references. */
Xextern int ttgetc();
Xextern int ttputc();
Xextern int ttflush();
Xextern int ttclose();
Xextern int dg10move();
Xextern int dg10eeol();
Xextern int dg10eeop();
Xextern int dg10beep();
Xextern int dg10open();
Xextern int dg10rev();
Xextern int dg10close();
X
X#if COLOR
Xextern int dg10fcol();
Xextern int dg10bcol();
X
Xint cfcolor = -1; /* current forground color */
Xint cbcolor = -1; /* current background color */
Xint ctrans[] = { /* emacs -> DG10 color translation table */
X 0, 4, 2, 6, 1, 5, 3, 7};
X#endif
X
X/*
X * Standard terminal interface dispatch table. Most of the fields point into
X * "termio" code.
X */
XTERM term = {
X NROW-1,
X NCOL,
X MARGIN,
X SCRSIZ,
X NPAUSE,
X dg10open,
X dg10close,
X ttgetc,
X ttputc,
X ttflush,
X dg10move,
X dg10eeol,
X dg10eeop,
X dg10beep,
X dg10rev
X#if COLOR
X , dg10fcol,
X dg10bcol
X#endif
X};
X
X#if COLOR
Xdg10fcol(color) /* set the current output color */
X
Xint color; /* color to set */
X
X{
X if (color == cfcolor)
X return;
X ttputc(ESC);
X ttputc(0101);
X ttputc(ctrans[color]);
X cfcolor = color;
X}
X
Xdg10bcol(color) /* set the current background color */
X
Xint color; /* color to set */
X
X{
X if (color == cbcolor)
X return;
X ttputc(ESC);
X ttputc(0102);
X ttputc(ctrans[color]);
X cbcolor = color;
X}
X#endif
X
Xdg10move(row, col)
X{
X ttputc(16);
X ttputc(col);
X ttputc(row);
X}
X
Xdg10eeol()
X{
X ttputc(11);
X}
X
Xdg10eeop()
X{
X#if COLOR
X dg10fcol(gfcolor);
X dg10bcol(gbcolor);
X#endif
X ttputc(ESC);
X ttputc(0106);
X ttputc(0106);
X}
X
Xdg10rev(state) /* change reverse video state */
X
Xint state; /* TRUE = reverse, FALSE = normal */
X
X{
X#if COLOR
X if (state == TRUE) {
X dg10fcol(0);
X dg10bcol(7);
X }
X#else
X ttputc(ESC);
X ttputc(state ? 0104: 0105);
X#endif
X}
X
Xdg10beep()
X{
X ttputc(BEL);
X ttflush();
X}
X
Xdg10open()
X{
X revexist = TRUE;
X ttopen();
X}
X
Xdg10close()
X
X{
X#if COLOR
X dg10fcol(7);
X dg10bcol(0);
X#endif
X ttclose();
X}
X#else
Xdg10hello()
X{
X}
X#endif
FRIDAY_NIGHT
echo extracting - display.c
sed 's/^X//' > display.c << 'FRIDAY_NIGHT'
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#define WFDEBUG 0 /* Window flag debug. */
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 IBMPC == 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 (*term.t_open)();
X (*term.t_rev)(FALSE);
X vscreen = (VIDEO **) malloc(term.t_nrow*sizeof(VIDEO *));
X
X if (vscreen == NULL)
X exit(1);
X
X#if IBMPC == 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_ncol);
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 IBMPC == 0
X vp = (VIDEO *) malloc(sizeof(VIDEO)+term.t_ncol);
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 (*term.t_flush)();
X (*term.t_close)();
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/*
X * Write a character to the virtual screen. The virtual row and column are
X * updated. If the line is too long put a "$" in the last column. This routine
X * only puts printing characters into the virtual terminal buffers. Only
X * column overflow is checked.
X */
Xvtputc(c)
X int c;
X{
X register VIDEO *vp;
X
X vp = vscreen[vtrow];
X
X if (vtcol >= term.t_ncol) {
X vtcol = (vtcol + 0x07) & ~0x07;
X vp->v_text[term.t_ncol - 1] = '$';
X } else if (c == '\t')
X {
X do
X {
X vtputc(' ');
X }
X while ((vtcol&0x07) != 0);
X }
X else if (c < 0x20 || c == 0x7F)
X {
X vtputc('^');
X vtputc(c ^ 0x40);
X }
X else
X vp->v_text[vtcol++] = c;
X}
X
X/* put a character to the virtual screen in an extended line. If we are
X not yet on left edge, don't print it yet. check for overflow on
X the right margin */
X
Xvtpute(c)
X
Xint c;
X
X{
X register VIDEO *vp;
X
X vp = vscreen[vtrow];
X
X if (vtcol >= term.t_ncol) {
X vtcol = (vtcol + 0x07) & ~0x07;
X vp->v_text[term.t_ncol - 1] = '$';
X } else if (c == '\t')
X {
X do
X {
X vtpute(' ');
X }
X while (((vtcol + lbound)&0x07) != 0);
X }
X else if (c < 0x20 || c == 0x7F)
X {
X vtpute('^');
X vtpute(c ^ 0x40);
X }
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
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 ~WFDEBUG
X if (wp->w_flag & WFMODE)
X modeline(wp); /* update modeline */
X#endif
X wp->w_flag = 0;
X wp->w_force = 0;
X }
X#if WFDEBUG
X modeline();
X#endif
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 IBMPC
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 (*term.t_flush)();
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 IBMPC == 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 IBMPC
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 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 vtpute(lgetc(lp, j));
X
X /* truncate the virtual line */
X vteeol();
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 IBMPC
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 (*term.t_setfor)(vp1->v_rfcolor);
X (*term.t_setback)(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 ) {
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 (*term.t_putchar)(*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 return(TRUE);
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 (*term.t_rev)((vp1->v_flag & VFREV) == VFREV);
X#endif
X
X while (cp1 != cp5) { /* Ordinary. */
X (*term.t_putchar)(*cp1);
X ++ttcol;
X *cp2++ = *cp1++;
X }
X
X if (cp5 != cp3) { /* Erase. */
X (*term.t_eeol)();
X while (cp1 != cp3)
X *cp2++ = *cp1++;
X }
X#if REVSTA
X (*term.t_rev)(FALSE);
X#endif
X vp1->v_flag &= ~VFCHG; /* flag this line is changed */
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 3.7 ("); /* Buffer name. */
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 WFDEBUG
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 (*term.t_move)(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 (*term.t_setfor)(7);
X (*term.t_setback)(0);
X#endif
X if (eolexist == TRUE)
X (*term.t_eeol)();
X else {
X for (i = 0; i < term.t_ncol - 1; i++)
X (*term.t_putchar)(' ');
X movecursor(term.t_nrow, 1); /* force the move! */
X movecursor(term.t_nrow, 0);
X }
X (*term.t_flush)();
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 (*term.t_setfor)(7);
X (*term.t_setback)(0);
X#endif
X if (eolexist == FALSE) {
X mlerase();
X (*term.t_flush)();
X }
X
X movecursor(term.t_nrow, 0);
X ap = (char *) &arg;
X while ((c = *fmt++) != 0) {
X if (c != '%') {
X (*term.t_putchar)(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 (*term.t_putchar)(c);
X ++ttcol;
X }
X }
X }
X if (eolexist == TRUE)
X (*term.t_eeol)();
X (*term.t_flush)();
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 (*term.t_putchar)(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 (*term.t_putchar)('-');
X }
X
X q = i/r;
X
X if (q != 0)
X mlputi(q, r);
X
X (*term.t_putchar)(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 (*term.t_putchar)('-');
X }
X
X q = l/r;
X
X if (q != 0)
X mlputli(q, r);
X
X (*term.t_putchar)((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 (*term.t_putchar)('.');
X (*term.t_putchar)((f / 10) + '0');
X (*term.t_putchar)((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
FRIDAY_NIGHT
echo extracting - ebind.h
sed 's/^X//' > ebind.h << 'FRIDAY_NIGHT'
X/* EBIND: Initial default key to function bindings for
X MicroEMACS 3.7
X*/
X
X/*
X * Command table.
X * This table is *roughly* in ASCII order, left to right across the
X * characters of the command. This expains the funny location of the
X * control-X commands.
X */
XKEYTAB keytab[NBINDS] = {
X {CTRL|'A', gotobol},
X {CTRL|'B', backchar},
X {CTRL|'C', insspace},
X {CTRL|'D', forwdel},
X {CTRL|'E', gotoeol},
X {CTRL|'F', forwchar},
X {CTRL|'G', ctrlg},
X {CTRL|'H', backdel},
X {CTRL|'I', tab},
X {CTRL|'J', indent},
X {CTRL|'K', killtext},
X {CTRL|'L', refresh},
X {CTRL|'M', newline},
X {CTRL|'N', forwline},
X {CTRL|'O', openline},
X {CTRL|'P', backline},
X {CTRL|'Q', quote},
X {CTRL|'R', backsearch},
X {CTRL|'S', forwsearch},
X {CTRL|'T', twiddle},
X {CTRL|'V', forwpage},
X {CTRL|'W', killregion},
X {CTRL|'X', cex},
X {CTRL|'Y', yank},
X {CTRL|'Z', backpage},
X {CTRL|']', meta},
X {CTLX|CTRL|'B', listbuffers},
X {CTLX|CTRL|'C', quit}, /* Hard quit. */
X {CTLX|CTRL|'F', filefind},
X {CTLX|CTRL|'I', insfile},
X {CTLX|CTRL|'L', lowerregion},
X {CTLX|CTRL|'M', delmode},
X {CTLX|CTRL|'N', mvdnwind},
X {CTLX|CTRL|'O', deblank},
X {CTLX|CTRL|'P', mvupwind},
X {CTLX|CTRL|'R', fileread},
X {CTLX|CTRL|'S', filesave},
X {CTLX|CTRL|'U', upperregion},
X {CTLX|CTRL|'V', viewfile},
X {CTLX|CTRL|'W', filewrite},
X {CTLX|CTRL|'X', swapmark},
X {CTLX|CTRL|'Z', shrinkwind},
X {CTLX|'?', deskey},
X {CTLX|'!', spawn},
X {CTLX|'@', pipe},
X {CTLX|'#', filter},
X {CTLX|'=', showcpos},
X {CTLX|'(', ctlxlp},
X {CTLX|')', ctlxrp},
X {CTLX|'^', enlargewind},
X {CTLX|'0', delwind},
X {CTLX|'1', onlywind},
X {CTLX|'2', splitwind},
X {CTLX|'B', usebuffer},
X {CTLX|'C', spawncli},
X#if BSD
X {CTLX|'D', bktoshell},
X#endif
X {CTLX|'E', ctlxe},
X {CTLX|'F', setfillcol},
X {CTLX|'K', killbuffer},
X {CTLX|'M', setmode},
X {CTLX|'N', filename},
X {CTLX|'O', nextwind},
X {CTLX|'P', prevwind},
X#if ISRCH
X {CTLX|'R', risearch},
X {CTLX|'S', fisearch},
X#endif
X {CTLX|'W', resize},
X {CTLX|'X', nextbuffer},
X {CTLX|'Z', enlargewind},
X#if WORDPRO
X {META|CTRL|'C', wordcount},
X#endif
X {META|CTRL|'H', delbword},
X {META|CTRL|'K', unbindkey},
X {META|CTRL|'L', reposition},
X {META|CTRL|'M', delgmode},
X {META|CTRL|'N', namebuffer},
X {META|CTRL|'R', qreplace},
X {META|CTRL|'V', scrnextdw},
X#if WORDPRO
X {META|CTRL|'W', killpara},
X#endif
X {META|CTRL|'Z', scrnextup},
X {META|' ', setmark},
X {META|'?', help},
X {META|'!', reposition},
X {META|'.', setmark},
X {META|'>', gotoeob},
X {META|'<', gotobob},
X {META|'~', unmark},
X {META|'B', backword},
X {META|'C', capword},
X {META|'D', delfword},
X {META|'F', forwword},
X {META|'G', gotoline},
X {META|'K', bindtokey},
X {META|'L', lowerword},
X {META|'M', setgmode},
X#if WORDPRO
X {META|'N', gotoeop},
X {META|'P', gotobop},
X {META|'Q', fillpara},
X#endif
X {META|'R', sreplace},
X#if BSD
X {META|'S', bktoshell},
X#endif
X {META|'U', upperword},
X {META|'V', backpage},
X {META|'W', copyregion},
X {META|'X', namedcmd},
X {META|'Z', quickexit},
X {META|0x7F, delbword},
X
X#if MSDOS & (HP150 == 0) & (WANGPC == 0)
X {SPEC|CTRL|'_', forwhunt},
X {SPEC|CTRL|'S', backhunt},
X {SPEC|71, gotobob},
X {SPEC|72, backline},
X {SPEC|73, backpage},
X {SPEC|75, backchar},
X {SPEC|77, forwchar},
X {SPEC|79, gotoeob},
X {SPEC|80, forwline},
X {SPEC|81, forwpage},
X {SPEC|82, insspace},
X {SPEC|83, forwdel},
X {SPEC|115, backword},
X {SPEC|116, forwword},
X {SPEC|132, gotobop},
X {SPEC|118, gotoeop},
X {SPEC|84, cbuf1},
X {SPEC|85, cbuf2},
X {SPEC|86, cbuf3},
X {SPEC|87, cbuf4},
X {SPEC|88, cbuf5},
X {SPEC|89, cbuf6},
X {SPEC|90, cbuf7},
X {SPEC|91, cbuf8},
X {SPEC|92, cbuf9},
X {SPEC|93, cbuf10},
X#endif
X
X#if HP150
X {SPEC|32, backline},
X {SPEC|33, forwline},
X {SPEC|35, backchar},
X {SPEC|34, forwchar},
X {SPEC|44, gotobob},
X {SPEC|46, forwpage},
X {SPEC|47, backpage},
X {SPEC|82, nextwind},
X {SPEC|68, openline},
X {SPEC|69, killtext},
X {SPEC|65, forwdel},
X {SPEC|64, ctlxe},
X {SPEC|67, refresh},
X {SPEC|66, reposition},
X {SPEC|83, help},
X {SPEC|81, deskey},
X#endif
X
X#if AMIGA
X {SPEC|'?', help},
X {SPEC|'A', backline},
X {SPEC|'B', forwline},
X {SPEC|'C', forwchar},
X {SPEC|'D', backchar},
X {SPEC|'T', backpage},
X {SPEC|'S', forwpage},
X {SPEC|'a', backword},
X {SPEC|'`', forwword},
X {SPEC|'P', cbuf1},
X {SPEC|'Q', cbuf2},
X {SPEC|'R', cbuf3},
X {SPEC|'S', cbuf4},
X {SPEC|'T', cbuf5},
X {SPEC|'U', cbuf6},
X {SPEC|'V', cbuf7},
X {SPEC|'W', cbuf8},
X {SPEC|'X', cbuf9},
X {SPEC|'Y', cbuf10},
X
X#endif
X
X#if WANGPC
X SPEC|0xE0, quit, /* Cancel */
X SPEC|0xE1, help, /* Help */
X SPEC|0xF1, help, /* ^Help */
X SPEC|0xE3, ctrlg, /* Print */
X SPEC|0xF3, ctrlg, /* ^Print */
X SPEC|0xC0, backline, /* North */
X SPEC|0xD0, gotobob, /* ^North */
X SPEC|0xC1, forwchar, /* East */
X SPEC|0xD1, gotoeol, /* ^East */
X SPEC|0xC2, forwline, /* South */
X SPEC|0xD2, gotobop, /* ^South */
X SPEC|0xC3, backchar, /* West */
X SPEC|0xD3, gotobol, /* ^West */
X SPEC|0xC4, ctrlg, /* Home */
X SPEC|0xD4, gotobob, /* ^Home */
X SPEC|0xC5, filesave, /* Execute */
X SPEC|0xD5, ctrlg, /* ^Execute */
X SPEC|0xC6, insfile, /* Insert */
X SPEC|0xD6, ctrlg, /* ^Insert */
X SPEC|0xC7, forwdel, /* Delete */
X SPEC|0xD7, killregion, /* ^Delete */
X SPEC|0xC8, backpage, /* Previous */
X SPEC|0xD8, prevwind, /* ^Previous */
X SPEC|0xC9, forwpage, /* Next */
X SPEC|0xD9, nextwind, /* ^Next */
X SPEC|0xCB, ctrlg, /* Erase */
X SPEC|0xDB, ctrlg, /* ^Erase */
X SPEC|0xDC, ctrlg, /* ^Tab */
X SPEC|0xCD, ctrlg, /* BackTab */
X SPEC|0xDD, ctrlg, /* ^BackTab */
X SPEC|0x80, ctrlg, /* Indent */
X SPEC|0x90, ctrlg, /* ^Indent */
X SPEC|0x81, ctrlg, /* Page */
X SPEC|0x91, ctrlg, /* ^Page */
X SPEC|0x82, ctrlg, /* Center */
X SPEC|0x92, ctrlg, /* ^Center */
X SPEC|0x83, ctrlg, /* DecTab */
X SPEC|0x93, ctrlg, /* ^DecTab */
X SPEC|0x84, ctrlg, /* Format */
X SPEC|0x94, ctrlg, /* ^Format */
X SPEC|0x85, ctrlg, /* Merge */
X SPEC|0x95, ctrlg, /* ^Merge */
X SPEC|0x86, setmark, /* Note */
X SPEC|0x96, ctrlg, /* ^Note */
X SPEC|0x87, ctrlg, /* Stop */
X SPEC|0x97, ctrlg, /* ^Stop */
X SPEC|0x88, forwsearch, /* Srch */
X SPEC|0x98, backsearch, /* ^Srch */
X SPEC|0x89, sreplace, /* Replac */
X SPEC|0x99, qreplace, /* ^Replac */
X SPEC|0x8A, ctrlg, /* Copy */
X SPEC|0x9A, ctrlg, /* ^Copy */
X SPEC|0x8B, ctrlg, /* Move */
X SPEC|0x9B, ctrlg, /* ^Move */
X SPEC|0x8C, namedcmd, /* Command */
X SPEC|0x9C, spawn, /* ^Command */
X SPEC|0x8D, ctrlg, /* ^ */
X SPEC|0x9D, ctrlg, /* ^^ */
X SPEC|0x8E, ctrlg, /* Blank */
X SPEC|0x9E, ctrlg, /* ^Blank */
X SPEC|0x8F, gotoline, /* GoTo */
X SPEC|0x9F, usebuffer, /* ^GoTo */
X#endif
X
X {0x7F, backdel},
X {0, NULL}
X};
X
X#if RAINBOW
X
X#include "rainbow.h"
X
X/*
X * Mapping table from the LK201 function keys to the internal EMACS character.
X */
X
Xshort lk_map[][2] = {
X Up_Key, CTRL+'P',
X Down_Key, CTRL+'N',
X Left_Key, CTRL+'B',
X Right_Key, CTRL+'F',
X Shift+Left_Key, META+'B',
X Shift+Right_Key, META+'F',
X Control+Left_Key, CTRL+'A',
X Control+Right_Key, CTRL+'E',
X Prev_Scr_Key, META+'V',
X Next_Scr_Key, CTRL+'V',
X Shift+Up_Key, META+'<',
X Shift+Down_Key, META+'>',
X Cancel_Key, CTRL+'G',
X Find_Key, CTRL+'S',
X Shift+Find_Key, CTRL+'R',
X Insert_Key, CTRL+'Y',
X Options_Key, CTRL+'D',
X Shift+Options_Key, META+'D',
X Remove_Key, CTRL+'W',
X Shift+Remove_Key, META+'W',
X Select_Key, CTRL+'@',
X Shift+Select_Key, CTLX+CTRL+'X',
X Interrupt_Key, CTRL+'U',
X Keypad_PF2, META+'L',
X Keypad_PF3, META+'C',
X Keypad_PF4, META+'U',
X Shift+Keypad_PF2, CTLX+CTRL+'L',
X Shift+Keypad_PF4, CTLX+CTRL+'U',
X Keypad_1, CTLX+'1',
X Keypad_2, CTLX+'2',
X Do_Key, CTLX+'E',
X Keypad_4, CTLX+CTRL+'B',
X Keypad_5, CTLX+'B',
X Keypad_6, CTLX+'K',
X Resume_Key, META+'!',
X Control+Next_Scr_Key, CTLX+'N',
X Control+Prev_Scr_Key, CTLX+'P',
X Control+Up_Key, CTLX+CTRL+'P',
X Control+Down_Key, CTLX+CTRL+'N',
X Help_Key, CTLX+'=',
X Shift+Do_Key, CTLX+'(',
X Control+Do_Key, CTLX+')',
X Keypad_0, CTLX+'Z',
X Shift+Keypad_0, CTLX+CTRL+'Z',
X Main_Scr_Key, CTRL+'C',
X Keypad_Enter, CTLX+'!',
X Exit_Key, CTLX+CTRL+'C',
X Shift+Exit_Key, CTRL+'Z'
X};
X
X#define lk_map_size (sizeof(lk_map)/2)
X#endif
X
FRIDAY_NIGHT
echo es.2 completed!
: That's all folks!
More information about the Mod.sources
mailing list