Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Posting-Version: version B 2.10.3 4.3bsd-beta 6/6/85; site mirror.UUCP Path: utzoo!decvax!cca!mirror!sources-request From: sources-request@mirror.UUCP Newsgroups: mod.sources Subject: MicroEmacs, Version 3.7 (uEmacs3.7), Part02/12 Message-ID: <160@mirror.UUCP> Date: Fri, 25-Jul-86 19:09:20 EDT Article-I.D.: mirror.160 Posted: Fri Jul 25 19:09:20 1986 Date-Received: Sat, 26-Jul-86 03:36:26 EDT Sender: rs@mirror.UUCP Lines: 1630 Approved: rs@mirror.UUCP 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 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 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; jv_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!