Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Path: utzoo!mnetor!uunet!seismo!rutgers!ames!think!bloom-beacon!mit-hermes!iuvax!isrnix!mr From: mr@isrnix.UUCP (a.k.a regoli@silver.bacs.indiana.edu) Newsgroups: comp.sys.ibm.pc Subject: Repost: EMACS 3.8L Source (Part 9 of 9) Message-ID: <877@isrnix.UUCP> Date: Fri, 31-Jul-87 15:32:01 EDT Article-I.D.: isrnix.877 Posted: Fri Jul 31 15:32:01 1987 Date-Received: Sun, 2-Aug-87 06:35:07 EDT Sender: mr@isrnix.UUCP Organization: indiana university, bloomington Lines: 2239 #! /bin/sh # This is a shell archive, meaning: # 1. Remove everything above the #! /bin/sh line. # 2. Save the resulting text in a file. # 3. Execute the file with /bin/sh (not csh) to create: # vmsvt.c # vt52.c # window.c # word.c # z309.c # This archive created: Fri Jul 31 13:54:49 1987 # By: michael regoli (indiana university, bloomington) export PATH; PATH=/bin:/usr/bin:$PATH echo shar: "extracting 'vmsvt.c'" '(0 character)' if test -f 'vmsvt.c' then echo shar: "will not over-write existing file 'vmsvt.c'" else cat << \SHAR_EOF > 'vmsvt.c' /* * VMS terminal handling routines * * Known types are: * VT52, VT100, and UNKNOWN (which is defined to be an ADM3a) * written by Curtis Smith */ #include #include "estruct.h" #include "edef.h" #if VMSVT #define termdef 1 /* don't define "term" external */ #include /* Status code definitions */ #include /* Descriptor structures */ #include /* IO commands */ #include /* tty commands */ extern int ttopen(); /* Forward references. */ extern int ttgetc(); extern int ttputc(); extern int ttflush(); extern int ttclose(); extern int vmsopen(); extern int vmskopen(); extern int vmskclose(); extern int vmseeol(); extern int vmseeop(); extern int vmsbeep(); extern int vmsmove(); extern int vmsrev(); extern int vmscres(); extern int eolexist; #if COLOR extern int vmsfcol(); extern int vmsbcol(); #endif #define NROWS 24 /* # of screen rolls */ #define NCOLS 80 /* # of screen columns */ #define MARGIN 8 /* size of minimim margin and */ #define SCRSIZ 64 /* scroll size for extended lines */ #define NPAUSE 100 /* # times thru update to pause */ /* * Dispatch table. All the * hard fields just point into the * terminal I/O code. */ TERM term = { NROWS - 1, NROWS - 1, NCOLS, NCOLS, MARGIN, SCRSIZ, NPAUSE, &vmsopen, &ttclose, &vmskopen, &vmskclose, &ttgetc, &ttputc, &ttflush, &vmsmove, &vmseeol, &vmseeop, &vmsbeep, &vmsrev, &vmscres #if COLOR , &vmsfcol, &vmsbcol #endif }; char * termeop; /* Erase to end of page string */ int eoppad; /* Number of pad characters after eop */ char * termeol; /* Erase to end of line string */ int eolpad; /* Number of pad characters after eol */ char termtype; /* Terminal type identifier */ /******* * ttputs - Send a string to ttputc *******/ ttputs(string) char * string; { while (*string != '\0') ttputc(*string++); } /******* * vmspad - Pad the output after an escape sequence *******/ vmspad(count) int count; { while (count-- > 0) ttputc('\0'); } /******* * vmsmove - Move the cursor *******/ vmsmove(row, col) { switch (termtype) { case TT$_UNKNOWN: ttputc('\033'); ttputc('='); ttputc(row+' '); ttputc(col+' '); break; case TT$_VT52: ttputc('\033'); ttputc('Y'); ttputc(row+' '); ttputc(col+' '); break; case TT$_VT100: /* I'm assuming that all these */ case TT$_VT101: /* are a super set of the VT100 */ case TT$_VT102: /* If I'm wrong, just remove */ case TT$_VT105: /* those entries that aren't. */ case TT$_VT125: case TT$_VT131: case TT$_VT132: case TT$_VT200_SERIES: { char buffer[24]; sprintf(buffer, "\033[%d;%dH", row+1, col+1); ttputs(buffer); vmspad(50); } } } /******* * vmsrev - set the reverse video status *******/ vmsrev(status) int status; /* TRUE = reverse video, FALSE = normal video */ { switch (termtype) { case TT$_UNKNOWN: break; case TT$_VT52: break; case TT$_VT100: if (status) { ttputc('\033'); ttputc('['); ttputc('7'); ttputc('m'); } else { ttputc('\033'); ttputc('['); ttputc('m'); } break; } } /******* * vmscres - Change screen resolution (which it doesn't) *******/ vmscres() { return(TRUE); } spal() /* change palette string */ { /* Does nothing here */ } #if COLOR /******* * vmsfcol - Set the forground color (not implimented) *******/ vmsfcol() { } /******* * vmsbcol - Set the background color (not implimented) *******/ vmsbcol() { } #endif /******* * vmseeol - Erase to end of line *******/ vmseeol() { ttputs(termeol); vmspad(eolpad); } /******* * vmseeop - Erase to end of page (clear screen) *******/ vmseeop() { ttputs(termeop); vmspad(eoppad); } /******* * vmsbeep - Ring the bell *******/ vmsbeep() { ttputc('\007'); } /******* * vmsopen - Get terminal type and open terminal *******/ vmsopen() { termtype = vmsgtty(); switch (termtype) { case TT$_UNKNOWN: /* Assume ADM3a */ eolexist = FALSE; termeop = "\032"; eoppad = 0; break; case TT$_VT52: termeol = "\033K"; eolpad = 0; termeop = "\033H\033J"; eoppad = 0; break; case TT$_VT100: revexist = TRUE; termeol = "\033[K"; eolpad = 3; termeop = "\033[;H\033[2J"; eoppad = 50; break; default: puts("Terminal type not supported"); exit (SS$_NORMAL); } strcpy(sres, "NORMAL"); ttopen(); } struct iosb { /* I/O status block */ short i_cond; /* Condition value */ short i_xfer; /* Transfer count */ long i_info; /* Device information */ }; struct termchar { /* Terminal characteristics */ char t_class; /* Terminal class */ char t_type; /* Terminal type */ short t_width; /* Terminal width in characters */ long t_mandl; /* Terminal's mode and length */ long t_extend; /* Extended terminal characteristics */ }; /******* * vmsgtty - Get terminal type from system control block *******/ vmsgtty() { short fd; int status; struct iosb iostatus; struct termchar tc; $DESCRIPTOR(devnam, "SYS$INPUT"); status = sys$assign(&devnam, &fd, 0, 0); if (status != SS$_NORMAL) exit (status); status = sys$qiow( /* Queue and wait */ 0, /* Wait on event flag zero */ fd, /* Channel to input terminal */ IO$_SENSEMODE, /* Get current characteristic */ &iostatus, /* Status after operation */ 0, 0, /* No AST service */ &tc, /* Terminal characteristics buf */ sizeof(tc), /* Size of the buffer */ 0, 0, 0, 0); /* P3-P6 unused */ /* De-assign the input device */ if (sys$dassgn(fd) != SS$_NORMAL) exit(status); if (status != SS$_NORMAL) /* Jump out if bad status */ exit(status); if (iostatus.i_cond != SS$_NORMAL) exit(iostatus.i_cond); return tc.t_type; /* Return terminal type */ } vmskopen() { } vmskclose() { } #if FLABEL fnclabel(f, n) /* label a function key */ int f,n; /* default flag, numeric argument [unused] */ { /* on machines with no function keys...don't bother */ return(TRUE); } #endif #else hellovms() { } #endif VMSVT SHAR_EOF chmod +x 'vmsvt.c' fi echo shar: "extracting 'vt52.c'" '(0 character)' if test -f 'vt52.c' then echo shar: "will not over-write existing file 'vt52.c'" else cat << \SHAR_EOF > 'vt52.c' /* * The routines in this file * provide support for VT52 style terminals * over a serial line. The serial I/O services are * provided by routines in "termio.c". It compiles * into nothing if not a VT52 style device. The * bell on the VT52 is terrible, so the "beep" * routine is conditionalized on defining BEL. */ #define termdef 1 /* don't define "term" external */ #include #include "estruct.h" #include "edef.h" #if VT52 #define NROW 24 /* Screen size. */ #define NCOL 80 /* Edit if you want to. */ #define MARGIN 8 /* size of minimim margin and */ #define SCRSIZ 64 /* scroll size for extended lines */ #define NPAUSE 100 /* # times thru update to pause */ #define BIAS 0x20 /* Origin 0 coordinate bias. */ #define ESC 0x1B /* ESC character. */ #define BEL 0x07 /* ascii bell character */ extern int ttopen(); /* Forward references. */ extern int ttgetc(); extern int ttputc(); extern int ttflush(); extern int ttclose(); extern int vt52move(); extern int vt52eeol(); extern int vt52eeop(); extern int vt52beep(); extern int vt52open(); extern int vt52rev(); extern int vt52cres(); extern int vt52kopen(); extern int vt52kclose(); #if COLOR extern int vt52fcol(); extern int vt52bcol(); #endif /* * Dispatch table. All the * hard fields just point into the * terminal I/O code. */ TERM term = { NROW-1, NROW-1, NCOL, NCOL, MARGIN, SCRSIZ, NPAUSE, &vt52open, &ttclose, &vt52kopen, &vt52kclose, &ttgetc, &ttputc, &ttflush, &vt52move, &vt52eeol, &vt52eeop, &vt52beep, &vt52rev, &vt52cres #if COLOR , &vt52fcol, &vt52bcol #endif }; vt52move(row, col) { ttputc(ESC); ttputc('Y'); ttputc(row+BIAS); ttputc(col+BIAS); } vt52eeol() { ttputc(ESC); ttputc('K'); } vt52eeop() { ttputc(ESC); ttputc('J'); } vt52rev(status) /* set the reverse video state */ int status; /* TRUE = reverse video, FALSE = normal video */ { /* can't do this here, so we won't */ } vt52cres() /* change screen resolution - (not here though) */ { return(TRUE); } spal() /* change palette string */ { /* Does nothing here */ } #if COLOR vt52fcol() /* set the forground color [NOT IMPLIMENTED] */ { } vt52bcol() /* set the background color [NOT IMPLIMENTED] */ { } #endif vt52beep() { #ifdef BEL ttputc(BEL); ttflush(); #endif } vt52open() { #if V7 | BSD register char *cp; char *getenv(); if ((cp = getenv("TERM")) == NULL) { puts("Shell variable TERM not defined!"); exit(1); } if (strcmp(cp, "vt52") != 0 && strcmp(cp, "z19") != 0) { puts("Terminal type not 'vt52'or 'z19' !"); exit(1); } #endif ttopen(); } vt52kopen() { } vt52kclose() { } #if FLABEL fnclabel(f, n) /* label a function key */ int f,n; /* default flag, numeric argument [unused] */ { /* on machines with no function keys...don't bother */ return(TRUE); } #endif #else vt52hello() { } #endif SHAR_EOF chmod +x 'vt52.c' fi echo shar: "extracting 'window.c'" '(0 character)' if test -f 'window.c' then echo shar: "will not over-write existing file 'window.c'" else cat << \SHAR_EOF > 'window.c' /* * Window management. Some of the functions are internal, and some are * attached to keys that the user actually types. */ #include #include "estruct.h" #include "edef.h" #if MEGAMAX & ST520 overlay "window" #endif /* * Reposition dot in the current window to line "n". If the argument is * positive, it is that line. If it is negative it is that line from the * bottom. If it is 0 the window is centered (this is what the standard * redisplay code does). With no argument it defaults to 0. Bound to M-!. */ reposition(f, n) { if (f == FALSE) /* default to 0 to center screen */ n = 0; curwp->w_force = n; curwp->w_flag |= WFFORCE; return (TRUE); } /* * Refresh the screen. With no argument, it just does the refresh. With an * argument it recenters "." in the current window. Bound to "C-L". */ refresh(f, n) { if (f == FALSE) sgarbf = TRUE; else { curwp->w_force = 0; /* Center dot. */ curwp->w_flag |= WFFORCE; } return (TRUE); } /* * The command make the next window (next => down the screen) the current * window. There are no real errors, although the command does nothing if * there is only 1 window on the screen. Bound to "C-X C-N". * * with an argument this command finds the th window from the top * */ nextwind(f, n) int f, n; /* default flag and numeric argument */ { register WINDOW *wp; register int nwindows; /* total number of windows */ if (f) { /* first count the # of windows */ wp = wheadp; nwindows = 1; while (wp->w_wndp != NULL) { nwindows++; wp = wp->w_wndp; } /* if the argument is negative, it is the nth window from the bottom of the screen */ if (n < 0) n = nwindows + n + 1; /* if an argument, give them that window from the top */ if (n > 0 && n <= nwindows) { wp = wheadp; while (--n) wp = wp->w_wndp; } else { mlwrite("Window number out of range"); return(FALSE); } } else if ((wp = curwp->w_wndp) == NULL) wp = wheadp; curwp = wp; curbp = wp->w_bufp; upmode(); return (TRUE); } /* * This command makes the previous window (previous => up the screen) the * current window. There arn't any errors, although the command does not do a * lot if there is 1 window. */ prevwind(f, n) { register WINDOW *wp1; register WINDOW *wp2; /* if we have an argument, we mean the nth window from the bottom */ if (f) return(nextwind(f, -n)); wp1 = wheadp; wp2 = curwp; if (wp1 == wp2) wp2 = NULL; while (wp1->w_wndp != wp2) wp1 = wp1->w_wndp; curwp = wp1; curbp = wp1->w_bufp; upmode(); return (TRUE); } /* * This command moves the current window down by "arg" lines. Recompute the * top line in the window. The move up and move down code is almost completely * the same; most of the work has to do with reframing the window, and picking * a new dot. We share the code by having "move down" just be an interface to * "move up". Magic. Bound to "C-X C-N". */ mvdnwind(f, n) int n; { return (mvupwind(f, -n)); } /* * Move the current window up by "arg" lines. Recompute the new top line of * the window. Look to see if "." is still on the screen. If it is, you win. * If it isn't, then move "." to center it in the new framing of the window * (this command does not really move "."; it moves the frame). Bound to * "C-X C-P". */ mvupwind(f, n) int n; { register LINE *lp; register int i; lp = curwp->w_linep; if (n < 0) { while (n++ && lp!=curbp->b_linep) lp = lforw(lp); } else { while (n-- && lback(lp)!=curbp->b_linep) lp = lback(lp); } curwp->w_linep = lp; curwp->w_flag |= WFHARD; /* Mode line is OK. */ for (i = 0; i < curwp->w_ntrows; ++i) { if (lp == curwp->w_dotp) return (TRUE); if (lp == curbp->b_linep) break; lp = lforw(lp); } lp = curwp->w_linep; i = curwp->w_ntrows/2; while (i-- && lp != curbp->b_linep) lp = lforw(lp); curwp->w_dotp = lp; curwp->w_doto = 0; return (TRUE); } /* * This command makes the current window the only window on the screen. Bound * to "C-X 1". Try to set the framing so that "." does not have to move on the * display. Some care has to be taken to keep the values of dot and mark in * the buffer structures right if the distruction of a window makes a buffer * become undisplayed. */ onlywind(f, n) { register WINDOW *wp; register LINE *lp; register int i; while (wheadp != curwp) { wp = wheadp; wheadp = wp->w_wndp; if (--wp->w_bufp->b_nwnd == 0) { wp->w_bufp->b_dotp = wp->w_dotp; wp->w_bufp->b_doto = wp->w_doto; wp->w_bufp->b_markp = wp->w_markp; wp->w_bufp->b_marko = wp->w_marko; } free((char *) wp); } while (curwp->w_wndp != NULL) { wp = curwp->w_wndp; curwp->w_wndp = wp->w_wndp; if (--wp->w_bufp->b_nwnd == 0) { wp->w_bufp->b_dotp = wp->w_dotp; wp->w_bufp->b_doto = wp->w_doto; wp->w_bufp->b_markp = wp->w_markp; wp->w_bufp->b_marko = wp->w_marko; } free((char *) wp); } lp = curwp->w_linep; i = curwp->w_toprow; while (i!=0 && lback(lp)!=curbp->b_linep) { --i; lp = lback(lp); } curwp->w_toprow = 0; curwp->w_ntrows = term.t_nrow-1; curwp->w_linep = lp; curwp->w_flag |= WFMODE|WFHARD; return (TRUE); } /* * Delete the current window, placing its space in the window above, * or, if it is the top window, the window below. Bound to C-X 0. */ delwind(f,n) int f, n; /* arguments are ignored for this command */ { register WINDOW *wp; /* window to recieve deleted space */ register WINDOW *lwp; /* ptr window before curwp */ register int target; /* target line to search for */ /* if there is only one window, don't delete it */ if (wheadp->w_wndp == NULL) { mlwrite("Can not delete this window"); return(FALSE); } /* find window before curwp in linked list */ wp = wheadp; lwp = NULL; while (wp != NULL) { if (wp == curwp) break; lwp = wp; wp = wp->w_wndp; } /* find recieving window and give up our space */ wp = wheadp; if (curwp->w_toprow == 0) { /* find the next window down */ target = curwp->w_ntrows + 1; while (wp != NULL) { if (wp->w_toprow == target) break; wp = wp->w_wndp; } if (wp == NULL) return(FALSE); wp->w_toprow = 0; wp->w_ntrows += target; } else { /* find the next window up */ target = curwp->w_toprow - 1; while (wp != NULL) { if ((wp->w_toprow + wp->w_ntrows) == target) break; wp = wp->w_wndp; } if (wp == NULL) return(FALSE); wp->w_ntrows += 1 + curwp->w_ntrows; } /* get rid of the current window */ if (--curwp->w_bufp->b_nwnd == 0) { curwp->w_bufp->b_dotp = curwp->w_dotp; curwp->w_bufp->b_doto = curwp->w_doto; curwp->w_bufp->b_markp = curwp->w_markp; curwp->w_bufp->b_marko = curwp->w_marko; } if (lwp == NULL) wheadp = curwp->w_wndp; else lwp->w_wndp = curwp->w_wndp; free((char *)curwp); curwp = wp; wp->w_flag |= WFHARD; curbp = wp->w_bufp; upmode(); return(TRUE); } /* Split the current window. A window smaller than 3 lines cannot be split. An argument of 1 forces the cursor into the upper window, an argument of two forces the cursor to the lower window. The only other error that is possible is a "malloc" failure allocating the structure for the new window. Bound to "C-X 2". */ splitwind(f, n) int f, n; /* default flag and numeric argument */ { register WINDOW *wp; register LINE *lp; register int ntru; register int ntrl; register int ntrd; register WINDOW *wp1; register WINDOW *wp2; char *malloc(); if (curwp->w_ntrows < 3) { mlwrite("Cannot split a %d line window", curwp->w_ntrows); return (FALSE); } if ((wp = (WINDOW *) malloc(sizeof(WINDOW))) == NULL) { mlwrite("Cannot allocate WINDOW block"); return (FALSE); } ++curbp->b_nwnd; /* Displayed twice. */ wp->w_bufp = curbp; wp->w_dotp = curwp->w_dotp; wp->w_doto = curwp->w_doto; wp->w_markp = curwp->w_markp; wp->w_marko = curwp->w_marko; wp->w_flag = 0; wp->w_force = 0; #if COLOR /* set the colors of the new window */ wp->w_fcolor = gfcolor; wp->w_bcolor = gbcolor; #endif ntru = (curwp->w_ntrows-1) / 2; /* Upper size */ ntrl = (curwp->w_ntrows-1) - ntru; /* Lower size */ lp = curwp->w_linep; ntrd = 0; while (lp != curwp->w_dotp) { ++ntrd; lp = lforw(lp); } lp = curwp->w_linep; if (((f == FALSE) && (ntrd <= ntru)) || ((f == TRUE) && (n == 1))) { /* Old is upper window. */ if (ntrd == ntru) /* Hit mode line. */ lp = lforw(lp); curwp->w_ntrows = ntru; wp->w_wndp = curwp->w_wndp; curwp->w_wndp = wp; wp->w_toprow = curwp->w_toprow+ntru+1; wp->w_ntrows = ntrl; } else { /* Old is lower window */ wp1 = NULL; wp2 = wheadp; while (wp2 != curwp) { wp1 = wp2; wp2 = wp2->w_wndp; } if (wp1 == NULL) wheadp = wp; else wp1->w_wndp = wp; wp->w_wndp = curwp; wp->w_toprow = curwp->w_toprow; wp->w_ntrows = ntru; ++ntru; /* Mode line. */ curwp->w_toprow += ntru; curwp->w_ntrows = ntrl; while (ntru--) lp = lforw(lp); } curwp->w_linep = lp; /* Adjust the top lines */ wp->w_linep = lp; /* if necessary. */ curwp->w_flag |= WFMODE|WFHARD; wp->w_flag |= WFMODE|WFHARD; return (TRUE); } /* * Enlarge the current window. Find the window that loses space. Make sure it * is big enough. If so, hack the window descriptions, and ask redisplay to do * all the hard work. You don't just set "force reframe" because dot would * move. Bound to "C-X Z". */ enlargewind(f, n) { register WINDOW *adjwp; register LINE *lp; register int i; if (n < 0) return (shrinkwind(f, -n)); if (wheadp->w_wndp == NULL) { mlwrite("Only one window"); return (FALSE); } if ((adjwp=curwp->w_wndp) == NULL) { adjwp = wheadp; while (adjwp->w_wndp != curwp) adjwp = adjwp->w_wndp; } if (adjwp->w_ntrows <= n) { mlwrite("Impossible change"); return (FALSE); } if (curwp->w_wndp == adjwp) { /* Shrink below. */ lp = adjwp->w_linep; for (i=0; iw_bufp->b_linep; ++i) lp = lforw(lp); adjwp->w_linep = lp; adjwp->w_toprow += n; } else { /* Shrink above. */ lp = curwp->w_linep; for (i=0; ib_linep; ++i) lp = lback(lp); curwp->w_linep = lp; curwp->w_toprow -= n; } curwp->w_ntrows += n; adjwp->w_ntrows -= n; curwp->w_flag |= WFMODE|WFHARD; adjwp->w_flag |= WFMODE|WFHARD; return (TRUE); } /* * Shrink the current window. Find the window that gains space. Hack at the * window descriptions. Ask the redisplay to do all the hard work. Bound to * "C-X C-Z". */ shrinkwind(f, n) { register WINDOW *adjwp; register LINE *lp; register int i; if (n < 0) return (enlargewind(f, -n)); if (wheadp->w_wndp == NULL) { mlwrite("Only one window"); return (FALSE); } if ((adjwp=curwp->w_wndp) == NULL) { adjwp = wheadp; while (adjwp->w_wndp != curwp) adjwp = adjwp->w_wndp; } if (curwp->w_ntrows <= n) { mlwrite("Impossible change"); return (FALSE); } if (curwp->w_wndp == adjwp) { /* Grow below. */ lp = adjwp->w_linep; for (i=0; iw_bufp->b_linep; ++i) lp = lback(lp); adjwp->w_linep = lp; adjwp->w_toprow -= n; } else { /* Grow above. */ lp = curwp->w_linep; for (i=0; ib_linep; ++i) lp = lforw(lp); curwp->w_linep = lp; curwp->w_toprow += n; } curwp->w_ntrows -= n; adjwp->w_ntrows += n; curwp->w_flag |= WFMODE|WFHARD; adjwp->w_flag |= WFMODE|WFHARD; return (TRUE); } /* Resize the current window to the requested size */ resize(f, n) int f, n; /* default flag and numeric argument */ { int clines; /* current # of lines in window */ /* must have a non-default argument, else ignore call */ if (f == FALSE) return(TRUE); /* find out what to do */ clines = curwp->w_ntrows; /* already the right size? */ if (clines == n) return(TRUE); return(enlargewind(TRUE, n - clines)); } /* * Pick a window for a pop-up. Split the screen if there is only one window. * Pick the uppermost window that isn't the current window. An LRU algorithm * might be better. Return a pointer, or NULL on error. */ WINDOW * wpopup() { register WINDOW *wp; if (wheadp->w_wndp == NULL /* Only 1 window */ && splitwind(FALSE, 0) == FALSE) /* and it won't split */ return (NULL); wp = wheadp; /* Find window to use */ while (wp!=NULL && wp==curwp) wp = wp->w_wndp; return (wp); } scrnextup(f, n) /* scroll the next window up (back) a page */ { nextwind(FALSE, 1); backpage(f, n); prevwind(FALSE, 1); } scrnextdw(f, n) /* scroll the next window down (forward) a page */ { nextwind(FALSE, 1); forwpage(f, n); prevwind(FALSE, 1); } savewnd(f, n) /* save ptr to current window */ { swindow = curwp; return(TRUE); } restwnd(f, n) /* restore the saved screen */ { register WINDOW *wp; /* find the window */ wp = wheadp; while (wp != NULL) { if (wp == swindow) { curwp = wp; curbp = wp->w_bufp; upmode(); return (TRUE); } wp = wp->w_wndp; } mlwrite("[No such window exists]"); return(FALSE); } newsize(f, n) /* resize the screen, re-writing the screen */ int f; /* default flag */ int n; /* numeric argument */ { WINDOW *wp; /* current window being examined */ WINDOW *nextwp; /* next window to scan */ WINDOW *lastwp; /* last window scanned */ int lastline; /* screen line of last line of current window */ /* if the command defaults, assume the largest */ if (f == FALSE) n = term.t_mrow + 1; /* make sure it's in range */ if (n < 3 || n > term.t_mrow + 1) { mlwrite("%%Screen size out of range"); return(FALSE); } if (term.t_nrow == n - 1) return(TRUE); else if (term.t_nrow < n - 1) { /* go to the last window */ wp = wheadp; while (wp->w_wndp != NULL) wp = wp->w_wndp; /* and enlarge it as needed */ wp->w_ntrows = n - wp->w_toprow - 2; wp->w_flag |= WFHARD|WFMODE; } else { /* rebuild the window structure */ nextwp = wheadp; wp = NULL; lastwp = NULL; while (nextwp != NULL) { wp = nextwp; nextwp = wp->w_wndp; /* get rid of it if it is too low */ if (wp->w_toprow > n - 2) { /* save the point/mark if needed */ if (--wp->w_bufp->b_nwnd == 0) { wp->w_bufp->b_dotp = wp->w_dotp; wp->w_bufp->b_doto = wp->w_doto; wp->w_bufp->b_markp = wp->w_markp; wp->w_bufp->b_marko = wp->w_marko; } /* update curwp and lastwp if needed */ if (wp == curwp) curwp = wheadp; curbp = curwp->w_bufp; if (lastwp != NULL) lastwp->w_wndp = NULL; /* free the structure */ free((char *)wp); wp = NULL; } else { /* need to change this window size? */ lastline = wp->w_toprow + wp->w_ntrows - 1; if (lastline >= n - 2) { wp->w_ntrows = n - wp->w_toprow - 2; wp->w_flag |= WFHARD|WFMODE; } } lastwp = wp; } } /* screen is garbage */ term.t_nrow = n - 1; sgarbf = TRUE; return(TRUE); } newwidth(f, n) /* resize the screen, re-writing the screen */ int f; /* default flag */ int n; /* numeric argument */ { register WINDOW *wp; /* if the command defaults, assume the largest */ if (f == FALSE) n = term.t_mcol; /* make sure it's in range */ if (n < 10 || n > term.t_mcol) { mlwrite("%%Screen width out of range"); return(FALSE); } /* otherwise, just re-width it (no big deal) */ term.t_ncol = n; term.t_margin = n / 10; term.t_scrsiz = n - (term.t_margin * 2); /* florce all windows to redraw */ wp = wheadp; while (wp) { wp->w_flag |= WFHARD | WFMOVE | WFMODE; wp = wp->w_wndp; } sgarbf = TRUE; return(TRUE); } int getwpos() /* get screen offset of current line in current window */ { register int sline; /* screen line from top of window */ register LINE *lp; /* scannile line pointer */ /* search down the line we want */ lp = curwp->w_linep; sline = 1; while (lp != curwp->w_dotp) { ++sline; lp = lforw(lp); } /* and return the value */ return(sline); } SHAR_EOF chmod +x 'window.c' fi echo shar: "extracting 'word.c'" '(0 character)' if test -f 'word.c' then echo shar: "will not over-write existing file 'word.c'" else cat << \SHAR_EOF > 'word.c' /* * The routines in this file implement commands that work word or a * paragraph at a time. There are all sorts of word mode commands. If I * do any sentence mode commands, they are likely to be put in this file. */ #include #include "estruct.h" #include "edef.h" /* Word wrap on n-spaces. Back-over whatever precedes the point on the current * line and stop on the first word-break or the beginning of the line. If we * reach the beginning of the line, jump back to the end of the word and start * a new line. Otherwise, break the line at the word-break, eat it, and jump * back to the end of the word. * Returns TRUE on success, FALSE on errors. */ wrapword(f, n) int f; /* default flag */ int n; /* numeric argument */ { register int cnt; /* size of word wrapped to next line */ register int c; /* charector temporary */ /* backup from the 1 char */ if (!backchar(0, 1)) return(FALSE); /* back up until we aren't in a word, make sure there is a break in the line */ cnt = 0; while (((c = lgetc(curwp->w_dotp, curwp->w_doto)) != ' ') && (c != '\t')) { cnt++; if (!backchar(0, 1)) return(FALSE); /* if we make it to the beginning, start a new line */ if (curwp->w_doto == 0) { gotoeol(FALSE, 0); return(lnewline()); } } /* delete the forward white space */ if (!forwdel(0, 1)) return(FALSE); /* put in a end of line */ if (!lnewline()) return(FALSE); /* and past the first word */ while (cnt-- > 0) { if (forwchar(FALSE, 1) == FALSE) return(FALSE); } return(TRUE); } /* * Move the cursor backward by "n" words. All of the details of motion are * performed by the "backchar" and "forwchar" routines. Error if you try to * move beyond the buffers. */ backword(f, n) { if (n < 0) return (forwword(f, -n)); if (backchar(FALSE, 1) == FALSE) return (FALSE); while (n--) { while (inword() == FALSE) { if (backchar(FALSE, 1) == FALSE) return (FALSE); } while (inword() != FALSE) { if (backchar(FALSE, 1) == FALSE) return (FALSE); } } return (forwchar(FALSE, 1)); } /* * Move the cursor forward by the specified number of words. All of the motion * is done by "forwchar". Error if you try and move beyond the buffer's end. */ forwword(f, n) { if (n < 0) return (backword(f, -n)); while (n--) { while (inword() == TRUE) { if (forwchar(FALSE, 1) == FALSE) return (FALSE); } while (inword() == FALSE) { if (forwchar(FALSE, 1) == FALSE) return (FALSE); } } return(TRUE); } /* * Move the cursor forward by the specified number of words. As you move, * convert any characters to upper case. Error if you try and move beyond the * end of the buffer. Bound to "M-U". */ upperword(f, n) { register int c; if (curbp->b_mode&MDVIEW) /* don't allow this command if */ return(rdonly()); /* we are in read only mode */ if (n < 0) return (FALSE); while (n--) { while (inword() == FALSE) { if (forwchar(FALSE, 1) == FALSE) return (FALSE); } while (inword() != FALSE) { c = lgetc(curwp->w_dotp, curwp->w_doto); if (c>='a' && c<='z') { c -= 'a'-'A'; lputc(curwp->w_dotp, curwp->w_doto, c); lchange(WFHARD); } if (forwchar(FALSE, 1) == FALSE) return (FALSE); } } return (TRUE); } /* * Move the cursor forward by the specified number of words. As you move * convert characters to lower case. Error if you try and move over the end of * the buffer. Bound to "M-L". */ lowerword(f, n) { register int c; if (curbp->b_mode&MDVIEW) /* don't allow this command if */ return(rdonly()); /* we are in read only mode */ if (n < 0) return (FALSE); while (n--) { while (inword() == FALSE) { if (forwchar(FALSE, 1) == FALSE) return (FALSE); } while (inword() != FALSE) { c = lgetc(curwp->w_dotp, curwp->w_doto); if (c>='A' && c<='Z') { c += 'a'-'A'; lputc(curwp->w_dotp, curwp->w_doto, c); lchange(WFHARD); } if (forwchar(FALSE, 1) == FALSE) return (FALSE); } } return (TRUE); } /* * Move the cursor forward by the specified number of words. As you move * convert the first character of the word to upper case, and subsequent * characters to lower case. Error if you try and move past the end of the * buffer. Bound to "M-C". */ capword(f, n) { register int c; if (curbp->b_mode&MDVIEW) /* don't allow this command if */ return(rdonly()); /* we are in read only mode */ if (n < 0) return (FALSE); while (n--) { while (inword() == FALSE) { if (forwchar(FALSE, 1) == FALSE) return (FALSE); } if (inword() != FALSE) { c = lgetc(curwp->w_dotp, curwp->w_doto); if (c>='a' && c<='z') { c -= 'a'-'A'; lputc(curwp->w_dotp, curwp->w_doto, c); lchange(WFHARD); } if (forwchar(FALSE, 1) == FALSE) return (FALSE); while (inword() != FALSE) { c = lgetc(curwp->w_dotp, curwp->w_doto); if (c>='A' && c<='Z') { c += 'a'-'A'; lputc(curwp->w_dotp, curwp->w_doto, c); lchange(WFHARD); } if (forwchar(FALSE, 1) == FALSE) return (FALSE); } } } return (TRUE); } /* * Kill forward by "n" words. Remember the location of dot. Move forward by * the right number of words. Put dot back where it was and issue the kill * command for the right number of characters. With a zero argument, just * kill one word and no whitespace. Bound to "M-D". */ delfword(f, n) { register LINE *dotp; /* original cursor line */ register int doto; /* and row */ register int c; /* temp char */ long size; /* # of chars to delete */ /* don't allow this command if we are in read only mode */ if (curbp->b_mode&MDVIEW) return(rdonly()); /* ignore the command if there is a negative argument */ if (n < 0) return (FALSE); /* Clear the kill buffer if last command wasn't a kill */ if ((lastflag&CFKILL) == 0) kdelete(); thisflag |= CFKILL; /* this command is a kill */ /* save the current cursor position */ dotp = curwp->w_dotp; doto = curwp->w_doto; /* figure out how many characters to give the axe */ size = 0; /* get us into a word.... */ while (inword() == FALSE) { if (forwchar(FALSE, 1) == FALSE) return(FALSE); ++size; } if (n == 0) { /* skip one word, no whitespace! */ while (inword() == TRUE) { if (forwchar(FALSE, 1) == FALSE) return(FALSE); ++size; } } else { /* skip n words.... */ while (n--) { /* if we are at EOL; skip to the beginning of the next */ while (curwp->w_doto == llength(curwp->w_dotp)) { if (forwchar(FALSE, 1) == FALSE) return(FALSE); ++size; } /* move forward till we are at the end of the word */ while (inword() == TRUE) { if (forwchar(FALSE, 1) == FALSE) return(FALSE); ++size; } /* if there are more words, skip the interword stuff */ if (n != 0) while (inword() == FALSE) { if (forwchar(FALSE, 1) == FALSE) return(FALSE); ++size; } } /* skip whitespace and newlines */ while ((curwp->w_doto == llength(curwp->w_dotp)) || ((c = lgetc(curwp->w_dotp, curwp->w_doto)) == ' ') || (c == '\t')) { if (forwchar(FALSE, 1) == FALSE) return(FALSE); ++size; } } /* restore the original position and delete the words */ curwp->w_dotp = dotp; curwp->w_doto = doto; return (ldelete(size, TRUE)); } /* * Kill backwards by "n" words. Move backwards by the desired number of words, * counting the characters. When dot is finally moved to its resting place, * fire off the kill command. Bound to "M-Rubout" and to "M-Backspace". */ delbword(f, n) { long size; /* don't allow this command if we are in read only mode */ if (curbp->b_mode&MDVIEW) return(rdonly()); /* ignore the command if there is a nonpositive argument */ if (n <= 0) return (FALSE); /* Clear the kill buffer if last command wasn't a kill */ if ((lastflag&CFKILL) == 0) kdelete(); thisflag |= CFKILL; /* this command is a kill */ if (backchar(FALSE, 1) == FALSE) return (FALSE); size = 0; while (n--) { while (inword() == FALSE) { if (backchar(FALSE, 1) == FALSE) return (FALSE); ++size; } while (inword() != FALSE) { if (backchar(FALSE, 1) == FALSE) return (FALSE); ++size; } } if (forwchar(FALSE, 1) == FALSE) return (FALSE); return (ldelete(size, TRUE)); } /* * Return TRUE if the character at dot is a character that is considered to be * part of a word. The word character list is hard coded. Should be setable. */ inword() { register int c; if (curwp->w_doto == llength(curwp->w_dotp)) return (FALSE); c = lgetc(curwp->w_dotp, curwp->w_doto); if (c>='a' && c<='z') return (TRUE); if (c>='A' && c<='Z') return (TRUE); if (c>='0' && c<='9') return (TRUE); if (c=='\'') return (TRUE); return (FALSE); } #if WORDPRO fillpara(f, n) /* Fill the current paragraph according to the current fill column */ int f, n; /* deFault flag and Numeric argument */ { register int c; /* current char durring scan */ register int wordlen; /* length of current word */ register int clength; /* position on line during fill */ register int i; /* index during word copy */ register int newlength; /* tentative new line length */ register int eopflag; /* Are we at the End-Of-Paragraph? */ register int firstflag; /* first word? (needs no space) */ register LINE *eopline; /* pointer to line just past EOP */ register int dotflag; /* was the last char a period? */ char wbuf[NSTRING]; /* buffer for current word */ if (curbp->b_mode&MDVIEW) /* don't allow this command if */ return(rdonly()); /* we are in read only mode */ if (fillcol == 0) { /* no fill column set */ mlwrite("No fill column set"); return(FALSE); } /* record the pointer to the line just past the EOP */ gotoeop(FALSE, 1); eopline = lforw(curwp->w_dotp); /* and back top the beginning of the paragraph */ gotobop(FALSE, 1); /* initialize various info */ clength = curwp->w_doto; if (clength && curwp->w_dotp->l_text[0] == TAB) clength = 8; wordlen = 0; dotflag = FALSE; /* scan through lines, filling words */ firstflag = TRUE; eopflag = FALSE; while (!eopflag) { /* get the next character in the paragraph */ if (curwp->w_doto == llength(curwp->w_dotp)) { c = ' '; if (lforw(curwp->w_dotp) == eopline) eopflag = TRUE; } else c = lgetc(curwp->w_dotp, curwp->w_doto); /* and then delete it */ ldelete(1L, FALSE); /* if not a separator, just add it in */ if (c != ' ' && c != '\t') { dotflag = (c == '.'); /* was it a dot */ if (wordlen < NSTRING - 1) wbuf[wordlen++] = c; } else if (wordlen) { /* at a word break with a word waiting */ /* calculate tantitive new length with word added */ newlength = clength + 1 + wordlen; if (newlength <= fillcol) { /* add word to current line */ if (!firstflag) { linsert(1, ' '); /* the space */ ++clength; } firstflag = FALSE; } else { /* start a new line */ lnewline(); clength = 0; } /* and add the word in in either case */ for (i=0; iw_markp = curwp->w_dotp; curwp->w_marko = curwp->w_doto; /* go to the beginning of the paragraph */ gotobop(FALSE, 1); curwp->w_doto = 0; /* force us to the beginning of line */ /* and delete it */ if ((status = killregion(FALSE, 1)) != TRUE) return(status); /* and clean up the 2 extra lines */ ldelete(2L, TRUE); } return(TRUE); } /* wordcount: count the # of words in the marked region, along with average word sizes, # of chars, etc, and report on them. */ wordcount(f, n) int f, n; /* ignored numeric arguments */ { register LINE *lp; /* current line to scan */ register int offset; /* current char to scan */ long size; /* size of region left to count */ register int ch; /* current character to scan */ register int wordflag; /* are we in a word now? */ register int lastword; /* were we just in a word? */ long nwords; /* total # of words */ long nchars; /* total number of chars */ int nlines; /* total number of lines in region */ int avgch; /* average number of chars/word */ int status; /* status return code */ REGION region; /* region to look at */ /* make sure we have a region to count */ if ((status = getregion(®ion)) != TRUE) return(status); lp = region.r_linep; offset = region.r_offset; size = region.r_size; /* count up things */ lastword = FALSE; nchars = 0L; nwords = 0L; nlines = 0; while (size--) { /* get the current character */ if (offset == llength(lp)) { /* end of line */ ch = '\n'; lp = lforw(lp); offset = 0; ++nlines; } else { ch = lgetc(lp, offset); ++offset; } /* and tabulate it */ wordflag = ((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') || (ch >= '0' && ch <= '9') || (ch == '\'')); if (wordflag == TRUE && lastword == FALSE) ++nwords; lastword = wordflag; ++nchars; } /* and report on the info */ if (nwords > 0L) avgch = (int)((100L * nchars) / nwords); else avgch = 0; mlwrite("Words %D Chars %D Lines %d Avg chars/word %f", nwords, nchars, nlines + 1, avgch); return(TRUE); } #endif SHAR_EOF fi echo shar: "extracting 'z309.c'" '(0 character)' if test -f 'z309.c' then echo shar: "will not over-write existing file 'z309.c'" else cat << \SHAR_EOF > 'z309.c' /* * The routines in this file provide support for the Zenith Z-100 PC * family. It goes directly to the graphics RAM to do screen output. * It compiles into nothing if not a Zenith driver. */ #define termdef 1 /* don't define "term" external */ #include #include "estruct.h" #include "edef.h" #if Z309 /* set NROW to 25 for 25-line interlaced mode */ #define NROW 50 /* Screen size. */ #define NCOL 80 /* Edit if you want to. */ #define MARGIN 8 /* size of minimim margin and */ #define SCRSIZ 64 /* scroll size for extended lines */ #define NPAUSE 200 /* # times thru update to pause */ #define BEL 0x07 /* BEL character. */ #define ESC 0x1B /* ESC character. */ #define SPACE 32 /* space character */ #define SCADC 0xb8000000L /* CGA address of screen RAM */ #define SCADM 0xb0000000L /* MONO address of screen RAM */ #define CDMONO 0 /* monochrome text card */ #define CDCGA50 1 /* 50-line color graphics card */ #define CDCGI25 2 /* 25-line interlaced CGA text */ #define CDCGA25 3 /* 25-line color graphics card */ #define CDSENSE 9 /* detect the card type */ int dtype = CDCGA50; /* current display type */ long scadd; /* address of screen ram */ int *scptr[NROW]; /* pointer to screen lines */ int sline[NCOL]; /* screen line image */ extern union REGS rg; /* cpu register for use of DOS calls */ extern int ttopen(); /* Forward references. */ extern int ttgetc(); extern int ttputc(); extern int ttflush(); extern int ttclose(); extern int z309move(); extern int z309eeol(); extern int z309eeop(); extern int z309beep(); extern int z309open(); extern int z309rev(); extern int z309cres(); extern int z309close(); extern int z309putc(); extern int z309kopen(); extern int z309kclose(); #if COLOR extern int z309fcol(); extern int z309bcol(); int cfcolor = -1; /* current forground color */ int cbcolor = -1; /* current background color */ int ctrans[] = /* ansi to z309 color translation table */ {0, 4, 2, 6, 1, 5, 3, 7}; #endif /* * Standard terminal interface dispatch table. Most of the fields point into * "termio" code. */ TERM term = { NROW-1, NROW-1, NCOL, NCOL, MARGIN, SCRSIZ, NPAUSE, z309open, z309close, z309kopen, z309kclose, ttgetc, z309putc, ttflush, z309move, z309eeol, z309eeop, z309beep, z309rev, z309cres #if COLOR , z309fcol, z309bcol #endif }; extern union REGS rg; #if COLOR z309fcol(color) /* set the current output color */ int color; /* color to set */ { cfcolor = ctrans[color]; } z309bcol(color) /* set the current background color */ int color; /* color to set */ { cbcolor = ctrans[color]; } #endif z309move(row, col) { rg.h.ah = 2; /* set cursor position function code */ rg.h.dl = col; rg.h.dh = row; rg.h.bh = 0; /* set screen page number */ int86(0x10, &rg, &rg); } z309eeol() /* erase to the end of the line */ { int attr; /* attribute byte mask to place in RAM */ int *lnptr; /* pointer to the destination line */ int i; int ccol; /* current column cursor lives */ int crow; /* row */ /* find the current cursor position */ rg.h.ah = 3; /* read cursor position function code */ rg.h.bh = 0; /* current video page */ int86(0x10, &rg, &rg); ccol = rg.h.dl; /* record current column */ crow = rg.h.dh; /* and row */ /* build the attribute byte and setup the screen pointer */ #if COLOR if (dtype != CDMONO) attr = (((cbcolor & 15) << 4) | (cfcolor & 15)) << 8; else attr = 0x0700; #else attr = 0x0700; #endif lnptr = &sline[0]; for (i=0; i < term.t_ncol; i++) *lnptr++ = SPACE | attr; #if 0 /* Heath/Zenith builds flicker-less CGAs */ if (flickcode) { /* wait for vertical retrace to be off */ while ((inp(0x3da) & 8)) ; /* and to be back on */ while ((inp(0x3da) & 8) == 0) ; } #endif /* and send the string out */ movmem(&sline[0], scptr[crow]+ccol, (term.t_ncol-ccol)*2); } z309putc(ch) /* put a character at the current position in the current colors */ int ch; { rg.h.ah = 14; /* write char to screen with current attrs */ rg.h.al = ch; #if COLOR if (dtype != CDMONO) rg.h.bl = cfcolor; else rg.h.bl = 0x07; #else rg.h.bl = 0x07; #endif int86(0x10, &rg, &rg); } z309eeop() { int attr; /* attribute to fill screen with */ rg.h.ah = 6; /* scroll page up function code */ rg.h.al = 0; /* # lines to scroll (clear it) */ rg.x.cx = 0; /* upper left corner of scroll */ /*HERE*/ rg.x.dx = 0x184f; /* lower right corner of scroll */ #if COLOR if (dtype != CDMONO) attr = ((ctrans[gbcolor] & 15) << 4) | (ctrans[gfcolor] & 15); else attr = 0; #else attr = 0; #endif rg.h.bh = attr; int86(0x10, &rg, &rg); } z309rev(state) /* change reverse video state */ int state; /* TRUE = reverse, FALSE = normal */ { /* This never gets used under the z309-PC driver */ } z309cres(res) /* change screen resolution */ char *res; /* resolution to change to */ { if (strcmp(res, "CGA50") == 0) { scinit(CDCGA50); return(TRUE); } else if (strcmp(res, "MONO") == 0) { scinit(CDMONO); return(TRUE); } else return(FALSE); } z309beep() { #if MWC86 putcnb(BEL); #else bdos(6, BEL, 0); #endif } z309open() { scinit(CDSENSE); revexist = TRUE; ttopen(); } z309close() { rg.h.ah = 101; rg.h.al = 1; /* 25-line interlace mode */ int86(0x10, &rg, &rg); #if COLOR z309fcol(7); z309bcol(0); #endif ttclose(); } z309kopen() /* open the keyboard */ { } z309kclose() /* close the keyboard */ { } scinit(type) /* initialize the screen head pointers */ int type; /* type of adapter to init for */ { union { long laddr; /* long form of address */ int *paddr; /* pointer form of address */ } addr; int i; /* if asked...find out what display is connected */ int86(0x11, &rg, &rg); dtype = CDCGA50; scadd = SCADC; strcpy(sres, "CGA50"); if ((((rg.x.ax >> 4) & 11) == 3) || type == CDMONO) { strcpy(sres, "MONO"); dtype = CDMONO; scadd = SCADM; } else { rg.h.ah = 101; /* set al = 1 for 25-line interlace mode */ rg.h.al = 2; /* 50-line interlace mode */ int86(0x10, &rg, &rg); } /* initialize the screen pointer array */ for (i = 0; i < NROW; i++) { addr.laddr = scadd + (long)(NCOL * i * 2); scptr[i] = addr.paddr; } } scwrite(row, outstr, forg, bacg) /* write a line out*/ int row; /* row of screen to place outstr on */ char *outstr; /* string to write out (must be term.t_ncol long) */ int forg; /* forground color of string to write */ int bacg; /* background color */ { int attr; /* attribute byte mask to place in RAM */ int *lnptr; /* pointer to the destination line */ int i; /* build the attribute byte and setup the screen pointer */ #if COLOR if (dtype != CDMONO) attr = (((ctrans[bacg] & 15) << 4) | (ctrans[forg] & 15)) << 8; else attr = (((bacg & 15) << 4) | (forg & 15)) << 8; #else attr = (((bacg & 15) << 4) | (forg & 15)) << 8; #endif lnptr = &sline[0]; for (i=0; i