home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Usenet 1994 October
/
usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso
/
unix
/
volume4
/
uemacs3.6
/
part8
< prev
next >
Wrap
Text File
|
1986-11-30
|
47KB
|
1,702 lines
Subject: MicroEMACS 3.6 (Part 8 of 8)
Newsgroups: mod.sources
Approved: jpn@panda.UUCP
Mod.sources: Volume 4, Issue 105
Submitted by: ihnp4!itivax!duncan!lawrence
echo x - termio.c
sed 's/^X//' >termio.c <<'*-*-END-of-termio.c-*-*'
X/*
X * The functions in this file negotiate with the operating system for
X * characters, and write characters in a barely buffered fashion on the display.
X * All operating systems.
X */
X#include <stdio.h>
X#include "estruct.h"
X#include "edef.h"
X
X#if AMIGA
X#define NEW 1006
X#define AMG_MAXBUF 1024
Xstatic long terminal;
Xstatic char scrn_tmp[AMG_MAXBUF+1];
Xstatic int scrn_tmp_p = 0;
X#endif
X
X#if VMS
X#include <stsdef.h>
X#include <ssdef.h>
X#include <descrip.h>
X#include <iodef.h>
X#include <ttdef.h>
X
X#define NIBUF 128 /* Input buffer size */
X#define NOBUF 1024 /* MM says bug buffers win! */
X#define EFN 0 /* Event flag */
X
Xchar obuf[NOBUF]; /* Output buffer */
Xint nobuf; /* # of bytes in above */
Xchar ibuf[NIBUF]; /* Input buffer */
Xint nibuf; /* # of bytes in above */
Xint ibufi; /* Read index */
Xint oldmode[2]; /* Old TTY mode bits */
Xint newmode[2]; /* New TTY mode bits */
Xshort iochan; /* TTY I/O channel */
X#endif
X
X#if CPM
X#include <bdos.h>
X#endif
X
X#if MSDOS & LATTICE
X#undef LATTICE
X#undef CPM
X#include <dos.h>
X#undef CPM
Xunion REGS rg; /* cpu register for use of DOS calls */
Xint nxtchar = -1; /* character held from type ahead */
X#endif
X
X#if MSDOS & AZTEC
Xstruct regs { /* cpu register for use of DOS calls */
X int ax, bx, cx, dx, si, di, ds, es; } rg;
Xint nxtchar = -1; /* character held from type ahead */
X#endif
X
X#if RAINBOW
X#include "rainbow.h"
X#endif
X
X#if V7
X#undef CTRL
X#include <sgtty.h> /* for stty/gtty functions */
X#include <signal.h>
Xstruct sgttyb ostate; /* saved tty state */
Xstruct sgttyb nstate; /* values for editor mode */
Xstruct tchars otchars; /* Saved terminal special character set */
Xstruct tchars ntchars = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
X /* A lot of nothing */
X#if BSD
X#include <sys/ioctl.h> /* to get at the typeahead */
Xextern int rtfrmshell(); /* return from suspended shell */
X#define TBUFSIZ 128
Xchar tobuf[TBUFSIZ]; /* terminal output buffer */
X#endif
X#endif
X
X/*
X * This function is called once to set up the terminal device streams.
X * On VMS, it translates TT until it finds the terminal, then assigns
X * a channel to it and sets it raw. On CPM it is a no-op.
X */
Xttopen()
X{
X#if AMIGA
X terminal = Open("RAW:1/1/639/199/MicroEMACS 3.6/Amiga", NEW);
X#endif
X#if VMS
X struct dsc$descriptor idsc;
X struct dsc$descriptor odsc;
X char oname[40];
X int iosb[2];
X int status;
X
X odsc.dsc$a_pointer = "TT";
X odsc.dsc$w_length = strlen(odsc.dsc$a_pointer);
X odsc.dsc$b_dtype = DSC$K_DTYPE_T;
X odsc.dsc$b_class = DSC$K_CLASS_S;
X idsc.dsc$b_dtype = DSC$K_DTYPE_T;
X idsc.dsc$b_class = DSC$K_CLASS_S;
X do {
X idsc.dsc$a_pointer = odsc.dsc$a_pointer;
X idsc.dsc$w_length = odsc.dsc$w_length;
X odsc.dsc$a_pointer = &oname[0];
X odsc.dsc$w_length = sizeof(oname);
X status = LIB$SYS_TRNLOG(&idsc, &odsc.dsc$w_length, &odsc);
X if (status!=SS$_NORMAL && status!=SS$_NOTRAN)
X exit(status);
X if (oname[0] == 0x1B) {
X odsc.dsc$a_pointer += 4;
X odsc.dsc$w_length -= 4;
X }
X } while (status == SS$_NORMAL);
X status = SYS$ASSIGN(&odsc, &iochan, 0, 0);
X if (status != SS$_NORMAL)
X exit(status);
X status = SYS$QIOW(EFN, iochan, IO$_SENSEMODE, iosb, 0, 0,
X oldmode, sizeof(oldmode), 0, 0, 0, 0);
X if (status!=SS$_NORMAL || (iosb[0]&0xFFFF)!=SS$_NORMAL)
X exit(status);
X newmode[0] = oldmode[0];
X newmode[1] = oldmode[1] | TT$M_PASSALL | TT$M_NOECHO;
X status = SYS$QIOW(EFN, iochan, IO$_SETMODE, iosb, 0, 0,
X newmode, sizeof(newmode), 0, 0, 0, 0);
X if (status!=SS$_NORMAL || (iosb[0]&0xFFFF)!=SS$_NORMAL)
X exit(status);
X#endif
X#if CPM
X#endif
X
X#if MSDOS & (HP150 == 0) & LATTICE
X /* kill the ctrl-break interupt */
X rg.h.ah = 0x33; /* control-break check dos call */
X rg.h.al = 1; /* set the current state */
X rg.h.dl = 0; /* set it OFF */
X intdos(&rg, &rg); /* go for it! */
X#endif
X
X#if V7 | BSD
X gtty(0, &ostate); /* save old state */
X gtty(0, &nstate); /* get base of new state */
X nstate.sg_flags |= RAW;
X nstate.sg_flags &= ~(ECHO|CRMOD); /* no echo for now... */
X stty(0, &nstate); /* set mode */
X ioctl(0, TIOCGETC, &otchars); /* Save old characters */
X ioctl(0, TIOCSETC, &ntchars); /* Place new character into K */
X#if BSD
X /* provide a smaller terminal output buffer so that
X the type ahead detection works better (more often) */
X setbuffer(stdout, &tobuf[0], TBUFSIZ);
X signal(SIGTSTP,SIG_DFL); /* set signals so that we can */
X signal(SIGCONT,rtfrmshell); /* suspend & restart emacs */
X#endif
X#endif
X}
X
X/*
X * This function gets called just before we go back home to the command
X * interpreter. On VMS it puts the terminal back in a reasonable state.
X * Another no-operation on CPM.
X */
Xttclose()
X{
X#if AMIGA
X amg_flush();
X Close(terminal);
X#endif
X#if VMS
X int status;
X int iosb[1];
X
X ttflush();
X status = SYS$QIOW(EFN, iochan, IO$_SETMODE, iosb, 0, 0,
X oldmode, sizeof(oldmode), 0, 0, 0, 0);
X if (status!=SS$_NORMAL || (iosb[0]&0xFFFF)!=SS$_NORMAL)
X exit(status);
X status = SYS$DASSGN(iochan);
X if (status != SS$_NORMAL)
X exit(status);
X#endif
X#if CPM
X#endif
X#if MSDOS & (HP150 == 0) & LATTICE
X /* restore the ctrl-break interupt */
X rg.h.ah = 0x33; /* control-break check dos call */
X rg.h.al = 1; /* set the current state */
X rg.h.dl = 1; /* set it ON */
X intdos(&rg, &rg); /* go for it! */
X#endif
X
X#if V7
X stty(0, &ostate);
X ioctl(0, TIOCSETC, &otchars); /* Place old character into K */
X#endif
X}
X
X/*
X * Write a character to the display. On VMS, terminal output is buffered, and
X * we just put the characters in the big array, after checking for overflow.
X * On CPM terminal I/O unbuffered, so we just write the byte out. Ditto on
X * MS-DOS (use the very very raw console output routine).
X */
Xttputc(c)
X#if AMIGA
X char c;
X#endif
X{
X#if AMIGA
X scrn_tmp[scrn_tmp_p++] = c;
X if(scrn_tmp_p>=AMG_MAXBUF)
X amg_flush();
X#endif
X#if VMS
X if (nobuf >= NOBUF)
X ttflush();
X obuf[nobuf++] = c;
X#endif
X
X#if CPM
X bios(BCONOUT, c, 0);
X#endif
X
X#if MSDOS & CWC86
X dosb(CONDIO, c, 0);
X#endif
X
X#if MSDOS & LATTICE
X bdos(6, c, 0);
X#endif
X
X#if MSDOS & AZTEC
X bdos(6, c, 0);
X#endif
X
X#if RAINBOW
X Put_Char(c); /* fast video */
X#endif
X
X#if V7
X fputc(c, stdout);
X#endif
X}
X
X#if AMIGA
Xamg_flush()
X{
X if(scrn_tmp_p)
X Write(terminal,scrn_tmp,scrn_tmp_p);
X scrn_tmp_p = 0;
X}
X#endif
X
X/*
X * Flush terminal buffer. Does real work where the terminal output is buffered
X * up. A no-operation on systems where byte at a time terminal I/O is done.
X */
Xttflush()
X{
X#if AMIGA
X amg_flush();
X#endif
X#if VMS
X int status;
X int iosb[2];
X
X status = SS$_NORMAL;
X if (nobuf != 0) {
X status = SYS$QIOW(EFN, iochan, IO$_WRITELBLK|IO$M_NOFORMAT,
X iosb, 0, 0, obuf, nobuf, 0, 0, 0, 0);
X if (status == SS$_NORMAL)
X status = iosb[0] & 0xFFFF;
X nobuf = 0;
X }
X return (status);
X#endif
X#if CPM
X#endif
X#if MSDOS
X#endif
X#if V7
X fflush(stdout);
X#endif
X}
X
X/*
X * Read a character from the terminal, performing no editing and doing no echo
X * at all. More complex in VMS that almost anyplace else, which figures. Very
X * simple on CPM, because the system can do exactly what you want.
X */
Xttgetc()
X{
X#if AMIGA
X char ch;
X amg_flush();
X Read(terminal, &ch, 1);
X return(255 & (int)ch);
X#endif
X#if VMS
X int status;
X int iosb[2];
X int term[2];
X
X while (ibufi >= nibuf) {
X ibufi = 0;
X term[0] = 0;
X term[1] = 0;
X status = SYS$QIOW(EFN, iochan, IO$_READLBLK|IO$M_TIMED,
X iosb, 0, 0, ibuf, NIBUF, 0, term, 0, 0);
X if (status != SS$_NORMAL)
X exit(status);
X status = iosb[0] & 0xFFFF;
X if (status!=SS$_NORMAL && status!=SS$_TIMEOUT)
X exit(status);
X nibuf = (iosb[0]>>16) + (iosb[1]>>16);
X if (nibuf == 0) {
X status = SYS$QIOW(EFN, iochan, IO$_READLBLK,
X iosb, 0, 0, ibuf, 1, 0, term, 0, 0);
X if (status != SS$_NORMAL
X || (status = (iosb[0]&0xFFFF)) != SS$_NORMAL)
X exit(status);
X nibuf = (iosb[0]>>16) + (iosb[1]>>16);
X }
X }
X return (ibuf[ibufi++] & 0xFF); /* Allow multinational */
X#endif
X
X#if CPM
X return (biosb(BCONIN, 0, 0));
X#endif
X
X#if RAINBOW
X int Ch;
X
X while ((Ch = Read_Keyboard()) < 0);
X
X if ((Ch & Function_Key) == 0)
X if (!((Ch & 0xFF) == 015 || (Ch & 0xFF) == 0177))
X Ch &= 0xFF;
X
X return Ch;
X#endif
X
X#if MSDOS & MWC86
X return (dosb(CONRAW, 0, 0));
X#endif
X
X#if MSDOS & LATTICE
X int c; /* character read */
X int flags; /* cpu flags after dos call */
X
X /* if a char already is ready, return it */
X if (nxtchar >= 0) {
X c = nxtchar;
X nxtchar = -1;
X return(c);
X }
X
X /* call the dos to get a char until one is there */
X flags = 255;
X while ((flags & 64) != 0) { /* while we don't yet have a char */
X rg.h.ah = 6; /* dos Direct Console I/O call */
X rg.h.dl = 255; /* console input */
X flags = intdos(&rg, &rg);
X c = rg.h.al; /* grab the char */
X }
X
X return(c & 255);
X#endif
X
X#if MSDOS & AZTEC
X int c; /* character read */
X int flags; /* cpu flags after dos call */
X
X /* if a char already is ready, return it */
X if (nxtchar >= 0) {
X c = nxtchar;
X nxtchar = -1;
X return(c);
X }
X
X /* call the dos to get a char until one is there */
X flags = 255;
X while ((flags & 64) != 0) { /* while we don't yet have a char */
X rg.ax = 1536; /* dos Direct Console I/O call */
X rg.dx = 255; /* console input */
X flags = sysint(33, &rg, &rg);
X c = rg.ax & 255; /* grab the char */
X }
X
X return(c);
X#endif
X
X#if V7
X return(127 & fgetc(stdin));
X#endif
X}
X
X#if TYPEAH
X/* typahead: Check to see if any characters are already in the
X keyboard buffer
X*/
X
Xtypahead()
X
X{
X#if MSDOS & LATTICE
X int c; /* character read */
X int flags; /* cpu flags from dos call */
X
X if (nxtchar >= 0)
X return(TRUE);
X
X rg.h.ah = 6; /* Direct Console I/O call */
X rg.h.dl = 255; /* does console input */
X flags = intdos(&rg, &rg);
X c = rg.h.al; /* grab the character */
X
X /* no character pending */
X if ((flags & 64) != 0)
X return(FALSE);
X
X /* save the character and return true */
X nxtchar = c;
X return(TRUE);
X#endif
X
X#if MSDOS & AZTEC
X int c; /* character read */
X int flags; /* cpu flags from dos call */
X
X if (nxtchar >= 0)
X return(TRUE);
X
X rg.ax = 1536; /* Direct Console I/O call */
X rg.dx = 255; /* does console input */
X flags = sysint(33, &rg, &rg);
X c = rg.ax & 255; /* grab the character */
X
X /* no character pending */
X if ((flags & 64) != 0)
X return(FALSE);
X
X /* save the character and return true */
X nxtchar = c;
X return(TRUE);
X#endif
X
X#if V7 & BSD
X int x; /* holds # of pending chars */
X
X return((ioctl(0,FIONREAD,&x) < 0) ? 0 : x);
X#endif
X return(FALSE);
X}
X#endif
X
*-*-END-of-termio.c-*-*
echo x - vmsvt.c
sed 's/^X//' >vmsvt.c <<'*-*-END-of-vmsvt.c-*-*'
X/*
X * VMS terminal handling routines
X *
X * Known types are:
X * VT52, VT100, and UNKNOWN (which is defined to be an ADM3a)
X * written by Curtis Smith
X */
X
X#include <stdio.h>
X#include "estruct.h"
X#include "edef.h"
X
X#if VMSVT
X
X#define termdef 1 /* don't define "term" external */
X
X#include <ssdef.h> /* Status code definitions */
X#include <descrip.h> /* Descriptor structures */
X#include <iodef.h> /* IO commands */
X#include <ttdef.h> /* tty commands */
X
Xextern int ttopen(); /* Forward references. */
Xextern int ttgetc();
Xextern int ttputc();
Xextern int ttflush();
Xextern int ttclose();
Xextern int vmsopen();
Xextern int vmseeol();
Xextern int vmseeop();
Xextern int vmsbeep();
Xextern int vmsmove();
Xextern int vmsrev();
Xextern int eolexist;
X
X#define NROWS 24 /* # of screen rolls */
X#define NCOLS 80 /* # of screen columns */
X#define MARGIN 8 /* size of minimim margin and */
X#define SCRSIZ 64 /* scroll size for extended lines */
X
X/*
X * Dispatch table. All the
X * hard fields just point into the
X * terminal I/O code.
X */
XTERM term = {
X NROWS - 1,
X NCOLS,
X MARGIN,
X SCRSIZ,
X &vmsopen,
X &ttclose,
X &ttgetc,
X &ttputc,
X &ttflush,
X &vmsmove,
X &vmseeol,
X &vmseeop,
X &vmsbeep,
X &vmsrev
X};
X
Xchar * termeop; /* Erase to end of page string */
Xint eoppad; /* Number of pad characters after eop */
Xchar * termeol; /* Erase to end of line string */
Xint eolpad; /* Number of pad characters after eol */
Xchar termtype; /* Terminal type identifier */
X
X
X/*******
X * ttputs - Send a string to ttputc
X *******/
X
Xttputs(string)
Xchar * string;
X{
X while (*string != '\0')
X ttputc(*string++);
X}
X
X
X/*******
X * vmspad - Pad the output after an escape sequence
X *******/
X
Xvmspad(count)
Xint count;
X{
X while (count-- > 0)
X ttputc('\0');
X}
X
X
X/*******
X * vmsmove - Move the cursor
X *******/
X
Xvmsmove(row, col)
X{
X switch (termtype) {
X case TT$_UNKNOWN:
X ttputc('\033');
X ttputc('=');
X ttputc(row+' ');
X ttputc(col+' ');
X break;
X case TT$_VT52:
X ttputc('\033');
X ttputc('Y');
X ttputc(row+' ');
X ttputc(col+' ');
X break;
X case TT$_VT100:
X {
X char buffer[24];
X
X sprintf(buffer, "\033[%d;%dH", row+1, col+1);
X ttputs(buffer);
X vmspad(50);
X }
X }
X}
X
X/*******
X * vmsrev - set the reverse video status
X *******/
X
Xvmsrev(status)
X
Xint status; /* TRUE = reverse video, FALSE = normal video */
X{
X switch (termtype) {
X case TT$_UNKNOWN:
X break;
X case TT$_VT52:
X break;
X case TT$_VT100:
X if (status) {
X ttputc('\033');
X ttputc('[');
X ttputc('7');
X ttputc('m');
X } else {
X ttputc('\033');
X ttputc('[');
X ttputc('m');
X }
X break;
X }
X}
X
X/*******
X * vmseeol - Erase to end of line
X *******/
X
Xvmseeol()
X{
X ttputs(termeol);
X vmspad(eolpad);
X}
X
X
X/*******
X * vmseeop - Erase to end of page (clear screen)
X *******/
X
Xvmseeop()
X{
X ttputs(termeop);
X vmspad(eoppad);
X}
X
X
X/*******
X * vmsbeep - Ring the bell
X *******/
X
Xvmsbeep()
X{
X ttputc('\007');
X}
X
X
X/*******
X * vmsopen - Get terminal type and open terminal
X *******/
X
Xvmsopen()
X{
X termtype = vmsgtty();
X switch (termtype) {
X case TT$_UNKNOWN: /* Assume ADM3a */
X eolexist = FALSE;
X termeop = "\032";
X eoppad = 0;
X break;
X case TT$_VT52:
X termeol = "\033K";
X eolpad = 0;
X termeop = "\033H\033J";
X eoppad = 0;
X break;
X case TT$_VT100:
X revexist = TRUE;
X termeol = "\033[K";
X eolpad = 3;
X termeop = "\033[;H\033[2J";
X eoppad = 50;
X break;
X default:
X puts("Terminal type not supported");
X exit (SS$_NORMAL);
X }
X ttopen();
X}
X
X
Xstruct iosb { /* I/O status block */
X short i_cond; /* Condition value */
X short i_xfer; /* Transfer count */
X long i_info; /* Device information */
X};
X
Xstruct termchar { /* Terminal characteristics */
X char t_class; /* Terminal class */
X char t_type; /* Terminal type */
X short t_width; /* Terminal width in characters */
X long t_mandl; /* Terminal's mode and length */
X long t_extend; /* Extended terminal characteristics */
X};
X
X/*******
X * vmsgtty - Get terminal type from system control block
X *******/
X
Xvmsgtty()
X{
X short fd;
X int status;
X struct iosb iostatus;
X struct termchar tc;
X $DESCRIPTOR(devnam, "SYS$INPUT");
X
X status = sys$assign(&devnam, &fd, 0, 0);
X if (status != SS$_NORMAL)
X exit (status);
X
X status = sys$qiow( /* Queue and wait */
X 0, /* Wait on event flag zero */
X fd, /* Channel to input terminal */
X IO$_SENSEMODE, /* Get current characteristic */
X &iostatus, /* Status after operation */
X 0, 0, /* No AST service */
X &tc, /* Terminal characteristics buf */
X sizeof(tc), /* Size of the buffer */
X 0, 0, 0, 0); /* P3-P6 unused */
X
X /* De-assign the input device */
X if (sys$dassgn(fd) != SS$_NORMAL)
X exit(status);
X
X if (status != SS$_NORMAL) /* Jump out if bad status */
X exit(status);
X if (iostatus.i_cond != SS$_NORMAL)
X exit(iostatus.i_cond);
X
X return tc.t_type; /* Return terminal type */
X}
X
X#else
X
Xhellovms()
X
X{
X}
X
X#endif VMSVT
*-*-END-of-vmsvt.c-*-*
echo x - vt52.c
sed 's/^X//' >vt52.c <<'*-*-END-of-vt52.c-*-*'
X/*
X * The routines in this file
X * provide support for VT52 style terminals
X * over a serial line. The serial I/O services are
X * provided by routines in "termio.c". It compiles
X * into nothing if not a VT52 style device. The
X * bell on the VT52 is terrible, so the "beep"
X * routine is conditionalized on defining BEL.
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 VT52
X
X#define NROW 24 /* Screen size. */
X#define NCOL 80 /* Edit if you want to. */
X#define MARGIN 8 /* size of minimim margin and */
X#define SCRSIZ 64 /* scroll size for extended lines */
X#define BIAS 0x20 /* Origin 0 coordinate bias. */
X#define ESC 0x1B /* ESC character. */
X#define BEL 0x07 /* ascii bell character */
X
Xextern int ttopen(); /* Forward references. */
Xextern int ttgetc();
Xextern int ttputc();
Xextern int ttflush();
Xextern int ttclose();
Xextern int vt52move();
Xextern int vt52eeol();
Xextern int vt52eeop();
Xextern int vt52beep();
Xextern int vt52open();
Xextern int vt52rev();
X
X/*
X * Dispatch table. All the
X * hard fields just point into the
X * terminal I/O code.
X */
XTERM term = {
X NROW-1,
X NCOL,
X MARGIN,
X SCRSIZ,
X &vt52open,
X &ttclose,
X &ttgetc,
X &ttputc,
X &ttflush,
X &vt52move,
X &vt52eeol,
X &vt52eeop,
X &vt52beep,
X &vt52rev
X};
X
Xvt52move(row, col)
X{
X ttputc(ESC);
X ttputc('Y');
X ttputc(row+BIAS);
X ttputc(col+BIAS);
X}
X
Xvt52eeol()
X{
X ttputc(ESC);
X ttputc('K');
X}
X
Xvt52eeop()
X{
X ttputc(ESC);
X ttputc('J');
X}
X
Xvt52rev(status) /* set the reverse video state */
X
Xint status; /* TRUE = reverse video, FALSE = normal video */
X
X{
X /* can't do this here, so we won't */
X}
X
Xvt52beep()
X{
X#ifdef BEL
X ttputc(BEL);
X ttflush();
X#endif
X}
X
X#endif
X
Xvt52open()
X{
X#if V7
X register char *cp;
X char *getenv();
X
X if ((cp = getenv("TERM")) == NULL) {
X puts("Shell variable TERM not defined!");
X exit(1);
X }
X if (strcmp(cp, "vt52") != 0 && strcmp(cp, "z19") != 0) {
X puts("Terminal type not 'vt52'or 'z19' !");
X exit(1);
X }
X#endif
X ttopen();
X}
*-*-END-of-vt52.c-*-*
echo x - window.c
sed 's/^X//' >window.c <<'*-*-END-of-window.c-*-*'
X/*
X * Window management. Some of the functions are internal, and some are
X * attached to keys that the user actually types.
X */
X
X#include <stdio.h>
X#include "estruct.h"
X#include "edef.h"
X
X/*
X * Reposition dot in the current window to line "n". If the argument is
X * positive, it is that line. If it is negative it is that line from the
X * bottom. If it is 0 the window is centered (this is what the standard
X * redisplay code does). With no argument it defaults to 1. Bound to M-!.
X * Because of the default, it works like in Gosling.
X */
Xreposition(f, n)
X {
X if (f == FALSE) /* default to 0 to center screen */
X n = 0;
X curwp->w_force = n;
X curwp->w_flag |= WFFORCE;
X return (TRUE);
X }
X
X/*
X * Refresh the screen. With no argument, it just does the refresh. With an
X * argument it recenters "." in the current window. Bound to "C-L".
X */
Xrefresh(f, n)
X {
X if (f == FALSE)
X sgarbf = TRUE;
X else
X {
X curwp->w_force = 0; /* Center dot. */
X curwp->w_flag |= WFFORCE;
X }
X
X return (TRUE);
X }
X
X/*
X * The command make the next window (next => down the screen) the current
X * window. There are no real errors, although the command does nothing if
X * there is only 1 window on the screen. Bound to "C-X C-N".
X */
Xnextwind(f, n)
X {
X register WINDOW *wp;
X
X if ((wp = curwp->w_wndp) == NULL)
X wp = wheadp;
X
X curwp = wp;
X curbp = wp->w_bufp;
X upmode();
X return (TRUE);
X }
X
X/*
X * This command makes the previous window (previous => up the screen) the
X * current window. There arn't any errors, although the command does not do a
X * lot if there is 1 window.
X */
Xprevwind(f, n)
X {
X register WINDOW *wp1;
X register WINDOW *wp2;
X
X wp1 = wheadp;
X wp2 = curwp;
X
X if (wp1 == wp2)
X wp2 = NULL;
X
X while (wp1->w_wndp != wp2)
X wp1 = wp1->w_wndp;
X
X curwp = wp1;
X curbp = wp1->w_bufp;
X upmode();
X return (TRUE);
X }
X
X/*
X * This command moves the current window down by "arg" lines. Recompute the
X * top line in the window. The move up and move down code is almost completely
X * the same; most of the work has to do with reframing the window, and picking
X * a new dot. We share the code by having "move down" just be an interface to
X * "move up". Magic. Bound to "C-X C-N".
X */
Xmvdnwind(f, n)
X int n;
X {
X return (mvupwind(f, -n));
X }
X
X/*
X * Move the current window up by "arg" lines. Recompute the new top line of
X * the window. Look to see if "." is still on the screen. If it is, you win.
X * If it isn't, then move "." to center it in the new framing of the window
X * (this command does not really move "."; it moves the frame). Bound to
X * "C-X C-P".
X */
Xmvupwind(f, n)
X int n;
X {
X register LINE *lp;
X register int i;
X
X lp = curwp->w_linep;
X
X if (n < 0)
X {
X while (n++ && lp!=curbp->b_linep)
X lp = lforw(lp);
X }
X else
X {
X while (n-- && lback(lp)!=curbp->b_linep)
X lp = lback(lp);
X }
X
X curwp->w_linep = lp;
X curwp->w_flag |= WFHARD; /* Mode line is OK. */
X
X for (i = 0; i < curwp->w_ntrows; ++i)
X {
X if (lp == curwp->w_dotp)
X return (TRUE);
X if (lp == curbp->b_linep)
X break;
X lp = lforw(lp);
X }
X
X lp = curwp->w_linep;
X i = curwp->w_ntrows/2;
X
X while (i-- && lp != curbp->b_linep)
X lp = lforw(lp);
X
X curwp->w_dotp = lp;
X curwp->w_doto = 0;
X return (TRUE);
X }
X
X/*
X * This command makes the current window the only window on the screen. Bound
X * to "C-X 1". Try to set the framing so that "." does not have to move on the
X * display. Some care has to be taken to keep the values of dot and mark in
X * the buffer structures right if the distruction of a window makes a buffer
X * become undisplayed.
X */
Xonlywind(f, n)
X{
X register WINDOW *wp;
X register LINE *lp;
X register int i;
X
X while (wheadp != curwp) {
X wp = wheadp;
X wheadp = wp->w_wndp;
X if (--wp->w_bufp->b_nwnd == 0) {
X wp->w_bufp->b_dotp = wp->w_dotp;
X wp->w_bufp->b_doto = wp->w_doto;
X wp->w_bufp->b_markp = wp->w_markp;
X wp->w_bufp->b_marko = wp->w_marko;
X }
X free((char *) wp);
X }
X while (curwp->w_wndp != NULL) {
X wp = curwp->w_wndp;
X curwp->w_wndp = wp->w_wndp;
X if (--wp->w_bufp->b_nwnd == 0) {
X wp->w_bufp->b_dotp = wp->w_dotp;
X wp->w_bufp->b_doto = wp->w_doto;
X wp->w_bufp->b_markp = wp->w_markp;
X wp->w_bufp->b_marko = wp->w_marko;
X }
X free((char *) wp);
X }
X lp = curwp->w_linep;
X i = curwp->w_toprow;
X while (i!=0 && lback(lp)!=curbp->b_linep) {
X --i;
X lp = lback(lp);
X }
X curwp->w_toprow = 0;
X curwp->w_ntrows = term.t_nrow-1;
X curwp->w_linep = lp;
X curwp->w_flag |= WFMODE|WFHARD;
X return (TRUE);
X}
X
X/*
X * Split the current window. A window smaller than 3 lines cannot be split.
X * The only other error that is possible is a "malloc" failure allocating the
X * structure for the new window. Bound to "C-X 2".
X */
Xsplitwind(f, n)
X{
X register WINDOW *wp;
X register LINE *lp;
X register int ntru;
X register int ntrl;
X register int ntrd;
X register WINDOW *wp1;
X register WINDOW *wp2;
X char *malloc();
X
X if (curwp->w_ntrows < 3) {
X mlwrite("Cannot split a %d line window", curwp->w_ntrows);
X return (FALSE);
X }
X if ((wp = (WINDOW *) malloc(sizeof(WINDOW))) == NULL) {
X mlwrite("Cannot allocate WINDOW block");
X return (FALSE);
X }
X ++curbp->b_nwnd; /* Displayed twice. */
X wp->w_bufp = curbp;
X wp->w_dotp = curwp->w_dotp;
X wp->w_doto = curwp->w_doto;
X wp->w_markp = curwp->w_markp;
X wp->w_marko = curwp->w_marko;
X wp->w_flag = 0;
X wp->w_force = 0;
X ntru = (curwp->w_ntrows-1) / 2; /* Upper size */
X ntrl = (curwp->w_ntrows-1) - ntru; /* Lower size */
X lp = curwp->w_linep;
X ntrd = 0;
X while (lp != curwp->w_dotp) {
X ++ntrd;
X lp = lforw(lp);
X }
X lp = curwp->w_linep;
X if (ntrd <= ntru) { /* Old is upper window. */
X if (ntrd == ntru) /* Hit mode line. */
X lp = lforw(lp);
X curwp->w_ntrows = ntru;
X wp->w_wndp = curwp->w_wndp;
X curwp->w_wndp = wp;
X wp->w_toprow = curwp->w_toprow+ntru+1;
X wp->w_ntrows = ntrl;
X } else { /* Old is lower window */
X wp1 = NULL;
X wp2 = wheadp;
X while (wp2 != curwp) {
X wp1 = wp2;
X wp2 = wp2->w_wndp;
X }
X if (wp1 == NULL)
X wheadp = wp;
X else
X wp1->w_wndp = wp;
X wp->w_wndp = curwp;
X wp->w_toprow = curwp->w_toprow;
X wp->w_ntrows = ntru;
X ++ntru; /* Mode line. */
X curwp->w_toprow += ntru;
X curwp->w_ntrows = ntrl;
X while (ntru--)
X lp = lforw(lp);
X }
X curwp->w_linep = lp; /* Adjust the top lines */
X wp->w_linep = lp; /* if necessary. */
X curwp->w_flag |= WFMODE|WFHARD;
X wp->w_flag |= WFMODE|WFHARD;
X return (TRUE);
X}
X
X/*
X * Enlarge the current window. Find the window that loses space. Make sure it
X * is big enough. If so, hack the window descriptions, and ask redisplay to do
X * all the hard work. You don't just set "force reframe" because dot would
X * move. Bound to "C-X Z".
X */
Xenlargewind(f, n)
X{
X register WINDOW *adjwp;
X register LINE *lp;
X register int i;
X
X if (n < 0)
X return (shrinkwind(f, -n));
X if (wheadp->w_wndp == NULL) {
X mlwrite("Only one window");
X return (FALSE);
X }
X if ((adjwp=curwp->w_wndp) == NULL) {
X adjwp = wheadp;
X while (adjwp->w_wndp != curwp)
X adjwp = adjwp->w_wndp;
X }
X if (adjwp->w_ntrows <= n) {
X mlwrite("Impossible change");
X return (FALSE);
X }
X if (curwp->w_wndp == adjwp) { /* Shrink below. */
X lp = adjwp->w_linep;
X for (i=0; i<n && lp!=adjwp->w_bufp->b_linep; ++i)
X lp = lforw(lp);
X adjwp->w_linep = lp;
X adjwp->w_toprow += n;
X } else { /* Shrink above. */
X lp = curwp->w_linep;
X for (i=0; i<n && lback(lp)!=curbp->b_linep; ++i)
X lp = lback(lp);
X curwp->w_linep = lp;
X curwp->w_toprow -= n;
X }
X curwp->w_ntrows += n;
X adjwp->w_ntrows -= n;
X curwp->w_flag |= WFMODE|WFHARD;
X adjwp->w_flag |= WFMODE|WFHARD;
X return (TRUE);
X}
X
X/*
X * Shrink the current window. Find the window that gains space. Hack at the
X * window descriptions. Ask the redisplay to do all the hard work. Bound to
X * "C-X C-Z".
X */
Xshrinkwind(f, n)
X{
X register WINDOW *adjwp;
X register LINE *lp;
X register int i;
X
X if (n < 0)
X return (enlargewind(f, -n));
X if (wheadp->w_wndp == NULL) {
X mlwrite("Only one window");
X return (FALSE);
X }
X if ((adjwp=curwp->w_wndp) == NULL) {
X adjwp = wheadp;
X while (adjwp->w_wndp != curwp)
X adjwp = adjwp->w_wndp;
X }
X if (curwp->w_ntrows <= n) {
X mlwrite("Impossible change");
X return (FALSE);
X }
X if (curwp->w_wndp == adjwp) { /* Grow below. */
X lp = adjwp->w_linep;
X for (i=0; i<n && lback(lp)!=adjwp->w_bufp->b_linep; ++i)
X lp = lback(lp);
X adjwp->w_linep = lp;
X adjwp->w_toprow -= n;
X } else { /* Grow above. */
X lp = curwp->w_linep;
X for (i=0; i<n && lp!=curbp->b_linep; ++i)
X lp = lforw(lp);
X curwp->w_linep = lp;
X curwp->w_toprow += n;
X }
X curwp->w_ntrows -= n;
X adjwp->w_ntrows += n;
X curwp->w_flag |= WFMODE|WFHARD;
X adjwp->w_flag |= WFMODE|WFHARD;
X return (TRUE);
X}
X
X/*
X * Pick a window for a pop-up. Split the screen if there is only one window.
X * Pick the uppermost window that isn't the current window. An LRU algorithm
X * might be better. Return a pointer, or NULL on error.
X */
XWINDOW *
Xwpopup()
X{
X register WINDOW *wp;
X
X if (wheadp->w_wndp == NULL /* Only 1 window */
X && splitwind(FALSE, 0) == FALSE) /* and it won't split */
X return (NULL);
X wp = wheadp; /* Find window to use */
X while (wp!=NULL && wp==curwp)
X wp = wp->w_wndp;
X return (wp);
X}
X
Xscrnextup(f, n) /* scroll the next window up (back) a page */
X
X{
X nextwind(FALSE, 1);
X backpage(f, n);
X prevwind(FALSE, 1);
X}
X
Xscrnextdw(f, n) /* scroll the next window down (forward) a page */
X
X{
X nextwind(FALSE, 1);
X forwpage(f, n);
X prevwind(FALSE, 1);
X}
*-*-END-of-window.c-*-*
echo x - word.c
sed 's/^X//' >word.c <<'*-*-END-of-word.c-*-*'
X/*
X * The routines in this file implement commands that work word at a time.
X * There are all sorts of word mode commands. If I do any sentence and/or
X * paragraph mode commands, they are likely to be put in this file.
X */
X
X#include <stdio.h>
X#include "estruct.h"
X#include "edef.h"
X
X/* Word wrap on n-spaces. Back-over whatever precedes the point on the current
X * line and stop on the first word-break or the beginning of the line. If we
X * reach the beginning of the line, jump back to the end of the word and start
X * a new line. Otherwise, break the line at the word-break, eat it, and jump
X * back to the end of the word.
X * Returns TRUE on success, FALSE on errors.
X */
Xwrapword(n)
Xint n;
X{
X register int cnt; /* size of word wrapped to next line */
X
X /* backup from the <NL> 1 char */
X if (!backchar(0, 1))
X return(FALSE);
X
X /* back up until we aren't in a word,
X make sure there is a break in the line */
X cnt = 0;
X while (inword()) {
X cnt++;
X if (!backchar(0, 1))
X return(FALSE);
X }
X
X /* delete the forward space */
X if (!forwdel(0, 1))
X return(FALSE);
X
X /* put in a end of line */
X if (!newline(0, 1))
X return(FALSE);
X
X /* and past the first word */
X while (cnt-- > 0) {
X if (forwchar(FALSE, 1) == FALSE)
X return(FALSE);
X }
X return(TRUE);
X}
X
X/*
X * Move the cursor backward by "n" words. All of the details of motion are
X * performed by the "backchar" and "forwchar" routines. Error if you try to
X * move beyond the buffers.
X */
Xbackword(f, n)
X{
X if (n < 0)
X return (forwword(f, -n));
X if (backchar(FALSE, 1) == FALSE)
X return (FALSE);
X while (n--) {
X while (inword() == FALSE) {
X if (backchar(FALSE, 1) == FALSE)
X return (FALSE);
X }
X while (inword() != FALSE) {
X if (backchar(FALSE, 1) == FALSE)
X return (FALSE);
X }
X }
X return (forwchar(FALSE, 1));
X}
X
X/*
X * Move the cursor forward by the specified number of words. All of the motion
X * is done by "forwchar". Error if you try and move beyond the buffer's end.
X */
Xforwword(f, n)
X{
X if (n < 0)
X return (backword(f, -n));
X while (n--) {
X#if NFWORD
X while (inword() != FALSE) {
X if (forwchar(FALSE, 1) == FALSE)
X return (FALSE);
X }
X#endif
X while (inword() == FALSE) {
X if (forwchar(FALSE, 1) == FALSE)
X return (FALSE);
X }
X#if NFWORD == 0
X while (inword() != FALSE) {
X if (forwchar(FALSE, 1) == FALSE)
X return (FALSE);
X }
X#endif
X }
X return(TRUE);
X}
X
X/*
X * Move the cursor forward by the specified number of words. As you move,
X * convert any characters to upper case. Error if you try and move beyond the
X * end of the buffer. Bound to "M-U".
X */
Xupperword(f, n)
X{
X register int c;
X
X if (curbp->b_mode&MDVIEW) /* don't allow this command if */
X return(rdonly()); /* we are in read only mode */
X if (n < 0)
X return (FALSE);
X while (n--) {
X while (inword() == FALSE) {
X if (forwchar(FALSE, 1) == FALSE)
X return (FALSE);
X }
X while (inword() != FALSE) {
X c = lgetc(curwp->w_dotp, curwp->w_doto);
X if (c>='a' && c<='z') {
X c -= 'a'-'A';
X lputc(curwp->w_dotp, curwp->w_doto, c);
X lchange(WFHARD);
X }
X if (forwchar(FALSE, 1) == FALSE)
X return (FALSE);
X }
X }
X return (TRUE);
X}
X
X/*
X * Move the cursor forward by the specified number of words. As you move
X * convert characters to lower case. Error if you try and move over the end of
X * the buffer. Bound to "M-L".
X */
Xlowerword(f, n)
X{
X register int c;
X
X if (curbp->b_mode&MDVIEW) /* don't allow this command if */
X return(rdonly()); /* we are in read only mode */
X if (n < 0)
X return (FALSE);
X while (n--) {
X while (inword() == FALSE) {
X if (forwchar(FALSE, 1) == FALSE)
X return (FALSE);
X }
X while (inword() != FALSE) {
X c = lgetc(curwp->w_dotp, curwp->w_doto);
X if (c>='A' && c<='Z') {
X c += 'a'-'A';
X lputc(curwp->w_dotp, curwp->w_doto, c);
X lchange(WFHARD);
X }
X if (forwchar(FALSE, 1) == FALSE)
X return (FALSE);
X }
X }
X return (TRUE);
X}
X
X/*
X * Move the cursor forward by the specified number of words. As you move
X * convert the first character of the word to upper case, and subsequent
X * characters to lower case. Error if you try and move past the end of the
X * buffer. Bound to "M-C".
X */
Xcapword(f, n)
X{
X register int c;
X
X if (curbp->b_mode&MDVIEW) /* don't allow this command if */
X return(rdonly()); /* we are in read only mode */
X if (n < 0)
X return (FALSE);
X while (n--) {
X while (inword() == FALSE) {
X if (forwchar(FALSE, 1) == FALSE)
X return (FALSE);
X }
X if (inword() != FALSE) {
X c = lgetc(curwp->w_dotp, curwp->w_doto);
X if (c>='a' && c<='z') {
X c -= 'a'-'A';
X lputc(curwp->w_dotp, curwp->w_doto, c);
X lchange(WFHARD);
X }
X if (forwchar(FALSE, 1) == FALSE)
X return (FALSE);
X while (inword() != FALSE) {
X c = lgetc(curwp->w_dotp, curwp->w_doto);
X if (c>='A' && c<='Z') {
X c += 'a'-'A';
X lputc(curwp->w_dotp, curwp->w_doto, c);
X lchange(WFHARD);
X }
X if (forwchar(FALSE, 1) == FALSE)
X return (FALSE);
X }
X }
X }
X return (TRUE);
X}
X
X/*
X * Kill forward by "n" words. Remember the location of dot. Move forward by
X * the right number of words. Put dot back where it was and issue the kill
X * command for the right number of characters. Bound to "M-D".
X */
Xdelfword(f, n)
X{
X register int size;
X register LINE *dotp;
X register int doto;
X
X if (curbp->b_mode&MDVIEW) /* don't allow this command if */
X return(rdonly()); /* we are in read only mode */
X if (n < 0)
X return (FALSE);
X dotp = curwp->w_dotp;
X doto = curwp->w_doto;
X size = 0;
X while (n--) {
X#if NFWORD
X while (inword() != FALSE) {
X if (forwchar(FALSE,1) == FALSE)
X return(FALSE);
X ++size;
X }
X#endif
X while (inword() == FALSE) {
X if (forwchar(FALSE, 1) == FALSE)
X return (FALSE);
X ++size;
X }
X#if NFWORD == 0
X while (inword() != FALSE) {
X if (forwchar(FALSE, 1) == FALSE)
X return (FALSE);
X ++size;
X }
X#endif
X }
X curwp->w_dotp = dotp;
X curwp->w_doto = doto;
X return (ldelete(size, TRUE));
X}
X
X/*
X * Kill backwards by "n" words. Move backwards by the desired number of words,
X * counting the characters. When dot is finally moved to its resting place,
X * fire off the kill command. Bound to "M-Rubout" and to "M-Backspace".
X */
Xdelbword(f, n)
X{
X register int size;
X
X if (curbp->b_mode&MDVIEW) /* don't allow this command if */
X return(rdonly()); /* we are in read only mode */
X if (n < 0)
X return (FALSE);
X if (backchar(FALSE, 1) == FALSE)
X return (FALSE);
X size = 0;
X while (n--) {
X while (inword() == FALSE) {
X if (backchar(FALSE, 1) == FALSE)
X return (FALSE);
X ++size;
X }
X while (inword() != FALSE) {
X if (backchar(FALSE, 1) == FALSE)
X return (FALSE);
X ++size;
X }
X }
X if (forwchar(FALSE, 1) == FALSE)
X return (FALSE);
X return (ldelete(size, TRUE));
X}
X
X/*
X * Return TRUE if the character at dot is a character that is considered to be
X * part of a word. The word character list is hard coded. Should be setable.
X */
Xinword()
X{
X register int c;
X
X if (curwp->w_doto == llength(curwp->w_dotp))
X return (FALSE);
X c = lgetc(curwp->w_dotp, curwp->w_doto);
X if (c>='a' && c<='z')
X return (TRUE);
X if (c>='A' && c<='Z')
X return (TRUE);
X if (c>='0' && c<='9')
X return (TRUE);
X if (c=='$' || c=='_') /* For identifiers */
X return (TRUE);
X return (FALSE);
X}
X
Xfillpara(f, n) /* Fill the current paragraph according to the current
X fill column */
X
Xint f, n; /* deFault flag and Numeric argument */
X
X{
X register int c; /* current char durring scan */
X register int wordlen; /* length of current word */
X register int clength; /* position on line during fill */
X register int i; /* index during word copy */
X register int newlength; /* tentative new line length */
X register int eopflag; /* Are we at the End-Of-Paragraph? */
X register int firstflag; /* first word? (needs no space) */
X register LINE *eopline; /* pointer to line just past EOP */
X register int dotflag; /* was the last char a period? */
X char wbuf[NSTRING]; /* buffer for current word */
X
X if (curbp->b_mode&MDVIEW) /* don't allow this command if */
X return(rdonly()); /* we are in read only mode */
X if (fillcol == 0) { /* no fill column set */
X mlwrite("No fill column set");
X return(FALSE);
X }
X
X /* record the pointer to the line just past the EOP */
X gotoeop(FALSE, 1);
X eopline = lforw(curwp->w_dotp);
X
X /* and back top the begining of the paragraph */
X gotobop(FALSE, 1);
X
X /* initialize various info */
X clength = curwp->w_doto;
X if (clength && curwp->w_dotp->l_text[0] == TAB)
X clength = 8;
X wordlen = 0;
X dotflag = FALSE;
X
X /* scan through lines, filling words */
X firstflag = TRUE;
X eopflag = FALSE;
X while (!eopflag) {
X /* get the next character in the paragraph */
X if (curwp->w_doto == llength(curwp->w_dotp)) {
X c = ' ';
X if (lforw(curwp->w_dotp) == eopline)
X eopflag = TRUE;
X } else
X c = lgetc(curwp->w_dotp, curwp->w_doto);
X
X /* and then delete it */
X ldelete(1, FALSE);
X
X /* if not a separator, just add it in */
X if (c != ' ' && c != ' ') {
X dotflag = (c == '.'); /* was it a dot */
X if (wordlen < NSTRING - 1)
X wbuf[wordlen++] = c;
X } else if (wordlen) {
X /* at a word break with a word waiting */
X /* calculate tantitive new length with word added */
X newlength = clength + 1 + wordlen;
X if (newlength <= fillcol) {
X /* add word to current line */
X if (!firstflag) {
X linsert(1, ' '); /* the space */
X ++clength;
X }
X firstflag = FALSE;
X } else {
X /* start a new line */
X lnewline();
X clength = 0;
X }
X
X /* and add the word in in either case */
X for (i=0; i<wordlen; i++) {
X linsert(1, wbuf[i]);
X ++clength;
X }
X if (dotflag) {
X linsert(1, ' ');
X ++clength;
X }
X wordlen = 0;
X }
X }
X /* and add a last newline for the end of our new paragraph */
X lnewline();
X}
X
Xkillpara(f, n) /* delete n paragraphs starting with the current one */
X
Xint f; /* default flag */
Xint n; /* # of paras to delete */
X
X{
X register int status; /* returned status of functions */
X
X while (n--) { /* for each paragraph to delete */
X
X /* mark out the end and begining of the para to delete */
X gotoeop(FALSE, 1);
X
X /* set the mark here */
X curwp->w_markp = curwp->w_dotp;
X curwp->w_marko = curwp->w_doto;
X
X /* go to the begining of the paragraph */
X gotobop(FALSE, 1);
X curwp->w_doto = 0; /* force us to the begining of line */
X
X /* and delete it */
X if ((status = killregion(FALSE, 1)) != TRUE)
X return(status);
X
X /* and clean up the 2 extra lines */
X ldelete(2, TRUE);
X }
X return(TRUE);
X}
*-*-END-of-word.c-*-*
exit