allbery@ncoast.UUCP (06/18/87)
: #!/bin/sh # shar+ created from directory /usr2/davidsen/emacs38i # 13:42 on Thu Jun 11, 1987 by davidsen echo 'x - hp110.c (text)' sed << 'E!O!F' 's/^X//' > hp110.c X/* X * HP110: Hewlett Packard 110 Screen Driver X */ X X#define termdef 1 /* don't define "term" external */ X X#include <stdio.h> X#include "estruct.h" X#include "edef.h" X X#if HP110 X X#define NROW 16 /* 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 0x1B /* ESC character. */ X Xextern int ttopen(); /* Forward references. */ Xextern int ttgetc(); Xextern int ttputc(); Xextern int ttflush(); Xextern int ttclose(); Xextern int h110move(); Xextern int h110eeol(); Xextern int h110eeop(); Xextern int h110beep(); Xextern int h110open(); Xextern int h110rev(); Xextern int h110cres(); Xextern int h110close(); Xextern int h110kopen(); Xextern int h110kclose(); X X#if COLOR Xextern int h110fcol(); Xextern int h110bcol(); X Xint cfcolor = -1; /* current forground color */ Xint cbcolor = -1; /* current background color */ 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 NROW-1, X NCOL, X NCOL, X MARGIN, X SCRSIZ, X NPAUSE, X h110open, X h110close, X h110kopen, X h110kclose, X ttgetc, X ttputc, X ttflush, X h110move, X h110eeol, X h110eeop, X h110beep, X h110rev, X h110cres X#if COLOR X , h110fcol, X h110bcol X#endif X}; X X#if COLOR Xh110fcol(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('['); X h110parm(color+30); X ttputc('m'); X cfcolor = color; X} X Xh110bcol(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('['); X h110parm(color+40); X ttputc('m'); X cbcolor = color; X} X#endif X Xh110move(row, col) X{ X ttputc(ESC); X ttputc('['); X h110parm(row+1); X ttputc(';'); X h110parm(col+1); X ttputc('H'); X} X Xh110eeol() X{ X ttputc(ESC); X ttputc('['); X ttputc('0'); X ttputc('K'); X} X Xh110eeop() X{ X#if COLOR X h110fcol(gfcolor); X h110bcol(gbcolor); X#endif X ttputc(ESC); X ttputc('['); X ttputc('0'); X ttputc('J'); X} X Xh110rev(state) /* change reverse video state */ X Xint state; /* TRUE = reverse, FALSE = normal */ X X{ X#if COLOR X int ftmp, btmp; /* temporaries for colors */ X#endif X X ttputc(ESC); X ttputc('['); X ttputc(state ? '7': '0'); X ttputc('m'); X#if COLOR X if (state == FALSE) { X ftmp = cfcolor; X btmp = cbcolor; X cfcolor = -1; X cbcolor = -1; X h110fcol(ftmp); X h110bcol(btmp); X } X#endif X} X Xh110cres() /* change screen resolution */ X X{ X return(TRUE); X} X Xspal() /* change pallette register */ X X{ X /* not here */ X} X Xh110beep() X{ X ttputc(BEL); X ttflush(); X} X Xh110parm(n) Xregister int n; X{ X register int q,r; X X q = n/10; X if (q != 0) { X r = q/10; X if (r != 0) { X ttputc((r%10)+'0'); X } X ttputc((q%10) + '0'); X } X ttputc((n%10) + '0'); X} X Xh110open() X{ X strcpy(sres, "15LINE"); X revexist = TRUE; X ttopen(); X} X Xh110close() X X{ X#if COLOR X h110fcol(7); X h110bcol(0); X#endif X ttclose(); X} X Xh110kopen() X X{ X} X Xh110kclose() X X{ X} X X#if FLABEL Xfnclabel(f, n) /* label a function key */ X Xint f,n; /* default flag, numeric argument [unused] */ X X{ X /* on machines with no function keys...don't bother */ X return(TRUE); X} X#endif X#else Xh110hello() X{ X} X#endif E!O!F newsize=`wc -c < hp110.c` if [ $newsize -ne 3750 ] then echo "File hp110.c was $newsize bytes, 3750 expected" fi echo 'x - hp150.c (text)' sed << 'E!O!F' 's/^X//' > hp150.c X/* X * The routines in this file provide support for HP150 screens X * and routines to access the Keyboard through KEYCODE mode. X * It compiles into nothing if not an HP150 screen device. X * added by Daniel Lawrence X */ X X#define termdef 1 /* don't define "term" external */ X X#include <stdio.h> X#include "estruct.h" X#include "edef.h" X X#if HP150 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 NPAUSE 15 /* # times thru update to pause */ X#define BEL 0x07 /* BEL character. */ X#define ESC 0x1B /* ESC character. */ X Xextern int openhp(); /* Forward references. */ Xextern int ttgetc(); Xextern int ttputc(); Xextern int ttflush(); Xextern int hpflush(); Xextern int closehp(); Xextern int hp15kopen(); Xextern int hp15kclose(); Xextern int hp15move(); Xextern int hp15eeol(); Xextern int hp15eeop(); Xextern int hp15beep(); Xextern int gethpkey(); Xextern int hp15rev(); Xextern int hp15cres(); X#if COLOR Xextern int hp15fcol(); Xextern int hp15bcol(); X#endif X X/* weird to ascii translation table */ X Xchar trans[][2] = { X 0x24, 9, /* tab */ X 0x25, 13, /* ret */ X 0x27, 8, /* backspace */ X 0x30, 48, /* zero */ X 0x31, 49, /* one */ X 0x32, 50, /* two */ X 0x33, 51, /* three */ X 0x34, 52, /* four */ X 0x35, 53, /* five */ X 0x36, 54, /* six */ X 0x37, 55, /* seven */ X 0x38, 56, /* eight */ X 0x39, 57, /* nine */ X 0x50, 13, /* enter */ X 0x54, 27, /* break -> ESC */ X 0x55, 27, /* esc */ X 0x58, 24, /* stop -> ^X */ X 0x70, 45, /* N-minus */ X 0x71, 42, /* N-asterisk */ X 0x72, 43, /* N-plus */ X 0x73, 47, /* N-slash */ X 0x74, 44, /* N-comma */ X 0x75, 13, /* N-enter */ X 0x76, 9, /* N-tab */ X 0x77, 46 /* N-period */ X}; X X#define NTRANS sizeof(trans) / 2 X Xunion REGS r; /* register set for bios and dos (AGIOS) calls */ Xint capslock = 0; /* caps lock flag */ X X/* X * Standard terminal interface dispatch table. Most of the fields point into X * "termio" code. X */ XTERM term = { X NROW-1, X NROW-1, X NCOL, X NCOL, X MARGIN, X SCRSIZ, X NPAUSE, X openhp, X closehp, X hp15kopen, X hp15kclose, X gethpkey, X ttputc, X hpflush, X hp15move, X hp15eeol, X hp15eeop, X hp15beep, X hp15rev, X hp15cres X#if COLOR X , hp15fcol, X hp15bcol X#endif X}; X Xhp15move(row, col) X{ X ttputc(ESC); X ttputc('&'); X ttputc('a'); X hp15parm(col); X ttputc('c'); X hp15parm(row); X ttputc('R'); X} X Xhpflush() X X{ X X} X Xhp15eeol() X{ X ttputc(ESC); X ttputc('K'); X} X Xhp15eeop() X{ X ttputc(ESC); X ttputc('J'); X} X Xhp15rev(status) /* change the reverse video status */ X Xint status; /* TRUE = on, FALSE = off */ X X{ X ttputc(ESC); X ttputc('&'); X ttputc('d'); X ttputc((status != FALSE) ? 'B': '@'); X} X Xhp15cres() /* change screen resolution */ X X{ X return(TRUE); X} X Xspal() /* change pallette register */ X X{ X /* not here */ X} X Xhp15beep() X{ X ttputc(BEL); X ttflush(); X} X Xhp15parm(n) Xregister int n; X{ X register int q; X X q = n/10; X if (q != 0) X hp15parm(q); X ttputc((n%10) + '0'); X} X X#if COLOR Xhp15fcol() /* we really can't do colors here, so just ignore it */ X{ X} X Xhp15bcol() /* we really can't do colors here, so just ignore it */ X{ X} X#endif X Xgethpkey() /* get a key from the HP keyboard while in keycode mode */ X X{ X static int keepflag = 0; /* kept ahead char flag */ X static int keepchar = 0; /* kept ehead flag */ X int c; X int devid; /* device ID */ X int ctype; /* type of character gotten */ X int shiftb; /* state of shift keys */ X int i; X X /* if we are in an extended char sequence, finish it */ X if (keepflag != 0) { X keepflag = 0; X return(keepchar); X } X X /* grab the next 4 char sequence */ Xnext: shiftb = ttgetc(); X devid = ttgetc(); X c = ttgetc(); X ttgetc(); /* skip null byte */ X X /* make sure we are from the keyboard */ X if (devid != 192) X goto next; X X /* if normal ascii, return it */ X if ((shiftb & 0x80) == 0) { X if (capslock && c >= 'a' && c <= 'z') X c -= 32; X return(c); X } X X /* check specifically for the caps lock key */ X if (c == 0x56) { X capslock = ~capslock; X goto next; X } X X /* check to see if it needs translation */ X for (i=0; i < NTRANS; i++) X if (trans[i][0] == c) X return((int)trans[i][1]); X X /* other wise, shove it in the keep char and return the leadin code */ X keepchar = c; X keepflag = 1; X return(0); X} X Xopenhp() /* open the HP150 screen for input */ X X{ X strcpy(sres, "NORMAL"); X revexist = TRUE; X} X Xclosehp() /* close the HP150 screen for input */ X X{ X} X Xhp15kopen() /* open the HP150 keyboard for input */ X X{ X /* define key charectoristics with AGIOS call (0, 40) */ X defkey(); X X /* Turn on RAW mode with MSDOS call 44h */ X rawon(); X X /* Turn off Control-C checking MS-DOS 33h */ X ckeyoff(); X X /* Turn on keycode mode with AGIOS call (0,43) */ X keycon(); X X /* display the application softkey labels */ X dsplbls(); X} X Xhp15kclose() /* close the HP150 keyboard for input */ X X{ X /* define key charectoristics with AGIOS call (0, 40) */ X undefkey(); X X /* Turn off RAW mode with MSDOS call 44h */ X rawoff(); X X /* Turn on Control-C checking MS-DOS 33h */ X ckeyon(); X X /* Turn off keycode mode with AGIOS call (0,43) */ X keycoff(); X} X Xrawon() /* put the HP150 keyboard into RAW mode */ X X{ X /* get the IO control info */ X X r.x.ax = 0x4400; /* IO ctrl get device information */ X r.x.bx = 0x0001; /* File handle; 1 for console */ X intdos(&r, &r); /* go fer it */ X X r.h.dh = 0; /* clear high byte for put */ X r.h.dl |= 0x20; /* set raw bit */ X X /* and put it back */ X X r.x.ax = 0x4401; /* IO ctrl put device information */ X r.x.bx = 0x0001; /* File handle; 1 for console */ X intdos(&r, &r); /* go fer it */ X} X Xrawoff() /* put the HP150 keyboard into COOKED mode */ X X{ X /* get the IO control info */ X X r.x.ax = 0x4400; /* IO ctrl get device information */ X r.x.bx = 0x0001; /* File handle; 1 for console */ X intdos(&r, &r); /* go fer it */ X X r.h.dh = 0; /* clear high byte for put */ X r.h.dl &= 0xdf; /* set raw bit */ X X /* and put it back */ X X r.x.ax = 0x4401; /* IO ctrl put device information */ X r.x.bx = 0x0001; /* File handle; 1 for console */ X intdos(&r, &r); /* go fer it */ X} X X Xckeyoff() /* turn control-C trapping off */ X X{ X r.h.ah = 0x33; /* ctrl-break check */ X r.h.al = 1; /* set the state of the ctrl-break check */ X r.h.dl = 0; /* turn it off */ X intdos(&r, &r); X} X Xckeyon() /* turn control-C trapping on */ X X{ X r.h.ah = 0x33; /* ctrl-break check */ X r.h.al = 1; /* set the state of the ctrl-break check */ X r.h.dl = 1; /* turn it on */ X intdos(&r, &r); X} X Xagios(buf, len) /* perform an AGIOS call */ X Xchar *buf; /* sequence of bytes in command */ Xint len; /* length of command in bytes */ X X{ X r.x.ax = 0x4403; /* I/O ctrl write */ X r.x.bx = 1; /* console handle */ X r.x.cx = len; /* buffer length */ X r.x.dx = (unsigned)buf; /* buffer address */ X return(intdos(&r, &r)); /* do it */ X} X Xkeycon() /* turn keycode mode on */ X X{ X static char cmd[] = {43, 0, 1}; X X return(agios(&cmd[0], 3)); X} X Xkeycoff() /* turn keycode mode off */ X X{ X static char cmd[] = {43, 0, 0}; X X return(agios(&cmd[0], 3)); X} X Xdefkey() /* change all special keys to intercept mode */ X X{ X static char cmd[] = {40, 0, 2, 0, 0xfe, 0}; X X return(agios(&cmd[0], 6)); X} X Xundefkey() /* change all special keys to intercept mode */ X X{ X static char cmd[] = {40, 0, 0, 0, 0xfe, 0}; X X return(agios(&cmd[0], 6)); X} X Xdsplbls() /* display the application softkey labels on the screen */ X X{ X static char cmd[] = {11, 0}; X X return(agios(&cmd[0], 2)); X} X X#if FLABEL Xfnclabel(f, n) /* label a function key */ X Xint f,n; /* default flag, numeric argument */ X X{ X register int status; /* return status */ X register int i; /* loop index */ X char lbl[17]; /* returned label contents */ X /* AGIOS command buffer */ X static char cmd[] = {8, 0, 1, 0, 7, 7, 7, 7, 10, 0, 10, 0}; X /* code key# ptr to top bottom X label string attribute */ X union { /* union to cast ptr into AGIOS arg string */ X char *ptr; /* pointer to arg string */ X char cstr[4]; X } ptru; X X /* must have a numeric argument */ X if (f == FALSE) { X mlwrite("%Need function key number"); X return(FALSE); X } X X /* and it must be a legal key number */ X if (n < 1 || n > 8) { X mlwrite("%Function key number out of range"); X return(FALSE); X } X X /* get the string to send */ X status = mlreply("Label contents: ", &lbl[0], 17); X if (status != TRUE) X return(status); X X /* pad the label out */ X for (i=0; i < 17; i++) { X if (lbl[i] == 0) X break; X } X for (; i < 16; i++) X lbl[i] = ' '; X lbl[16] = 0; X X /* set up the parameters */ X cmd[2] = n; /* function key number */ X ptru.ptr = &lbl[0]; /* set up pointer to label string */ Xforce: cmd[4] = ptru.cstr[0]; X cmd[5] = ptru.cstr[1]; X cmd[6] = ptru.cstr[2]; X cmd[7] = ptru.cstr[3]; X X /* and send it out */ X agios(&cmd[0], 12); X return(TRUE); X} X#endif X#else X Xh15hello() X X{ X} X#endif E!O!F newsize=`wc -c < hp150.c` if [ $newsize -ne 9192 ] then echo "File hp150.c was $newsize bytes, 9192 expected" fi echo 'x - ibmpc.c (text)' sed << 'E!O!F' 's/^X//' > ibmpc.c X/* X * The routines in this file provide support for the IBM-PC and other X * compatible terminals. It goes directly to the graphics RAM to do X * screen output. It compiles into nothing if not an IBM-PC driver X * Supported monitor cards include CGA, MONO and EGA. X */ X X#define termdef 1 /* don't define "term" external */ X X#include <stdio.h> X#include "estruct.h" X#include "edef.h" X X#if IBMPC X#define NROW 43 /* Max 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 NPAUSE 200 /* # times thru update to pause */ X#define BEL 0x07 /* BEL character. */ X#define ESC 0x1B /* ESC character. */ X#define SPACE 32 /* space character */ X X#define SCADC 0xb8000000L /* CGA address of screen RAM */ X#define SCADM 0xb0000000L /* MONO address of screen RAM */ X#define SCADE 0xb8000000L /* EGA address of screen RAM */ X X#define MONOCRSR 0x0B0D /* monochrome cursor */ X#define CGACRSR 0x0607 /* CGA cursor */ X#define EGACRSR 0x0709 /* EGA cursor */ X X#define CDCGA 0 /* color graphics card */ X#define CDMONO 1 /* monochrome text card */ X#define CDEGA 2 /* EGA color adapter */ X#define CDSENSE 9 /* detect the card type */ X X#define NDRIVE 3 /* number of screen drivers */ X Xint dtype = -1; /* current display type */ Xchar drvname[][8] = { /* screen resolution names */ X "CGA", "MONO", "EGA" X}; Xlong scadd; /* address of screen ram */ Xint *scptr[NROW]; /* pointer to screen lines */ Xint sline[NCOL]; /* screen line image */ Xint egaexist = FALSE; /* is an EGA card available? */ Xextern union REGS rg; /* cpu register for use of DOS calls */ X Xextern int ttopen(); /* Forward references. */ Xextern int ttgetc(); Xextern int ttputc(); Xextern int ttflush(); Xextern int ttclose(); Xextern int ibmmove(); Xextern int ibmeeol(); Xextern int ibmeeop(); Xextern int ibmbeep(); Xextern int ibmopen(); Xextern int ibmrev(); Xextern int ibmcres(); Xextern int ibmclose(); Xextern int ibmputc(); Xextern int ibmkopen(); Xextern int ibmkclose(); X X#if COLOR Xextern int ibmfcol(); Xextern int ibmbcol(); X Xint cfcolor = -1; /* current forground color */ Xint cbcolor = -1; /* current background color */ Xint ctrans[] = /* ansi to ibm 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 NROW-1, X NCOL, X NCOL, X MARGIN, X SCRSIZ, X NPAUSE, X ibmopen, X ibmclose, X ibmkopen, X ibmkclose, X ttgetc, X ibmputc, X ttflush, X ibmmove, X ibmeeol, X ibmeeop, X ibmbeep, X ibmrev, X ibmcres X#if COLOR X , ibmfcol, X ibmbcol X#endif X}; X Xextern union REGS rg; X X#if COLOR Xibmfcol(color) /* set the current output color */ X Xint color; /* color to set */ X X{ X cfcolor = ctrans[color]; X} X Xibmbcol(color) /* set the current background color */ X Xint color; /* color to set */ X X{ X cbcolor = ctrans[color]; X} X#endif X Xibmmove(row, col) X{ X rg.h.ah = 2; /* set cursor position function code */ X rg.h.dl = col; X rg.h.dh = row; X rg.h.bh = 0; /* set screen page number */ X int86(0x10, &rg, &rg); X} X Xibmeeol() /* erase to the end of the line */ X X{ X int attr; /* attribute byte mask to place in RAM */ X int *lnptr; /* pointer to the destination line */ X int i; X int ccol; /* current column cursor lives */ X int crow; /* row */ X X /* find the current cursor position */ X rg.h.ah = 3; /* read cursor position function code */ X rg.h.bh = 0; /* current video page */ X int86(0x10, &rg, &rg); X ccol = rg.h.dl; /* record current column */ X crow = rg.h.dh; /* and row */ X X /* build the attribute byte and setup the screen pointer */ X#if COLOR X if (dtype != CDMONO) X attr = (((cbcolor & 15) << 4) | (cfcolor & 15)) << 8; X else X attr = 0x0700; X#else X attr = 0x0700; X#endif X lnptr = &sline[0]; X for (i=0; i < term.t_ncol; i++) X *lnptr++ = SPACE | attr; X X if (flickcode && (dtype == CDCGA)) { X /* wait for vertical retrace to be off */ X while ((inp(0x3da) & 8)) X ; X X /* and to be back on */ X while ((inp(0x3da) & 8) == 0) X ; X } X X /* and send the string out */ X movmem(&sline[0], scptr[crow]+ccol, (term.t_ncol-ccol)*2); X X} X Xibmputc(ch) /* put a character at the current position in the X current colors */ X Xint ch; X X{ X rg.h.ah = 14; /* write char to screen with current attrs */ X rg.h.al = ch; X#if COLOR X if (dtype != CDMONO) X rg.h.bl = cfcolor; X else X rg.h.bl = 0x07; X#else X rg.h.bl = 0x07; X#endif X int86(0x10, &rg, &rg); X} X Xibmeeop() X{ X int attr; /* attribute to fill screen with */ X X rg.h.ah = 6; /* scroll page up function code */ X rg.h.al = 0; /* # lines to scroll (clear it) */ X rg.x.cx = 0; /* upper left corner of scroll */ X rg.x.dx = (term.t_nrow << 8) | (term.t_ncol - 1); X /* lower right corner of scroll */ X#if COLOR X if (dtype != CDMONO) X attr = ((ctrans[gbcolor] & 15) << 4) | (ctrans[gfcolor] & 15); X else X attr = 0; X#else X attr = 0; X#endif X rg.h.bh = attr; X int86(0x10, &rg, &rg); X} X Xibmrev(state) /* change reverse video state */ X Xint state; /* TRUE = reverse, FALSE = normal */ X X{ X /* This never gets used under the IBM-PC driver */ X} X Xibmcres(res) /* change screen resolution */ X Xchar *res; /* resolution to change to */ X X{ X int i; /* index */ X X for (i = 0; i < NDRIVE; i++) X if (strcmp(res, drvname[i]) == 0) { X scinit(i); X return(TRUE); X } X return(FALSE); X} X Xspal() /* reset the pallette registers */ X X{ X /* nothin here now..... */ X} X Xibmbeep() X{ X#if MWC86 X putcnb(BEL); X#else X bdos(6, BEL, 0); X#endif X} X Xibmopen() X{ X scinit(CDSENSE); X revexist = TRUE; X ttopen(); X} X Xibmclose() X X{ X#if COLOR X ibmfcol(7); X ibmbcol(0); X#endif X /* if we had the EGA open... close it */ X if (dtype == CDEGA) X egaclose(); X X ttclose(); X} X Xibmkopen() /* open the keyboard */ X X{ X} X Xibmkclose() /* close the keyboard */ X X{ X} X Xscinit(type) /* initialize the screen head pointers */ X Xint type; /* type of adapter to init for */ X X{ X union { X long laddr; /* long form of address */ X int *paddr; /* pointer form of address */ X } addr; X int i; X X /* if asked...find out what display is connected */ X if (type == CDSENSE) X type = getboard(); X X /* if we have nothing to do....don't do it */ X if (dtype == type) X return(TRUE); X X /* if we try to switch to EGA and there is none, don't */ X if (type == CDEGA && egaexist != TRUE) X return(FALSE); X X /* if we had the EGA open... close it */ X if (dtype == CDEGA) X egaclose(); X X /* and set up the various parameters as needed */ X switch (type) { X case CDMONO: /* Monochrome adapter */ X scadd = SCADM; X newsize(TRUE, 25); X break; X X case CDCGA: /* Color graphics adapter */ X scadd = SCADC; X newsize(TRUE, 25); X break; X X case CDEGA: /* Enhanced graphics adapter */ X scadd = SCADE; X egaopen(); X newsize(TRUE, 43); X break; X } X X /* reset the $sres environment variable */ X strcpy(sres, drvname[type]); X dtype = type; X X /* initialize the screen pointer array */ X for (i = 0; i < NROW; i++) { X addr.laddr = scadd + (long)(NCOL * i * 2); X scptr[i] = addr.paddr; X } X} X X/* getboard: Determine which type of display board is attached. X Current known types include: X X CDMONO Monochrome graphics adapter X CDCGA Color Graphics Adapter X CDEGA Extended graphics Adapter X*/ X X/* getbaord: Detect the current display adapter X if MONO set to MONO X CGA set to CGA EGAexist = FALSE X EGA set to CGA EGAexist = TRUE X*/ X Xint getboard() X X{ X int type; /* board type to return */ X X type = CDCGA; X int86(0x11, &rg, &rg); X if ((((rg.x.ax >> 4) & 3) == 3)) X type = CDMONO; X X /* test if EGA present */ X rg.x.ax = 0x1200; X rg.x.bx = 0xff10; X int86(0x10,&rg, &rg); /* If EGA, bh=0-1 and bl=0-3 */ X egaexist = !(rg.x.bx & 0xfefc); /* Yes, it's EGA */ X return(type); X} X Xegaopen() /* init the computer to work with the EGA */ X X{ X /* put the beast into EGA 43 row mode */ X rg.x.ax = 3; X int86(16, &rg, &rg); X X rg.h.ah = 17; /* set char. generator function code */ X rg.h.al = 18; /* to 8 by 8 double dot ROM */ X rg.h.bl = 0; /* block 0 */ X int86(16, &rg, &rg); X X rg.h.ah = 18; /* alternate select function code */ X rg.h.al = 0; /* clear AL for no good reason */ X rg.h.bl = 32; /* alt. print screen routine */ X int86(16, &rg, &rg); X X rg.h.ah = 1; /* set cursor size function code */ X rg.x.cx = 0x0607; /* turn cursor on code */ X int86(0x10, &rg, &rg); X X outp(0x3d4, 10); /* video bios bug patch */ X outp(0x3d5, 6); X} X Xegaclose() X X{ X /* put the beast into 80 column mode */ X rg.x.ax = 3; X int86(16, &rg, &rg); X} X Xscwrite(row, outstr, forg, bacg) /* write a line out*/ X Xint row; /* row of screen to place outstr on */ Xchar *outstr; /* string to write out (must be term.t_ncol long) */ Xint forg; /* forground color of string to write */ Xint bacg; /* background color */ X X{ X int attr; /* attribute byte mask to place in RAM */ X int *lnptr; /* pointer to the destination line */ X int i; X X /* build the attribute byte and setup the screen pointer */ X#if COLOR X if (dtype != CDMONO) X attr = (((ctrans[bacg] & 15) << 4) | (ctrans[forg] & 15)) << 8; X else X attr = (((bacg & 15) << 4) | (forg & 15)) << 8; X#else X attr = (((bacg & 15) << 4) | (forg & 15)) << 8; X#endif X lnptr = &sline[0]; X for (i=0; i<term.t_ncol; i++) X *lnptr++ = (outstr[i] & 255) | attr; X X if (flickcode && (dtype == CDCGA)) { X /* wait for vertical retrace to be off */ X while ((inp(0x3da) & 8)) X ; X X /* and to be back on */ X while ((inp(0x3da) & 8) == 0) X ; X } X X /* and send the string out */ X movmem(&sline[0], scptr[row],term.t_ncol*2); X} X X#if FLABEL Xfnclabel(f, n) /* label a function key */ X Xint f,n; /* default flag, numeric argument [unused] */ X X{ X /* on machines with no function keys...don't bother */ X return(TRUE); X} X#endif X#else Xibmhello() X{ X} X#endif E!O!F newsize=`wc -c < ibmpc.c` if [ $newsize -ne 9998 ] then echo "File ibmpc.c was $newsize bytes, 9998 expected" fi echo 'x - input.c (text)' sed << 'E!O!F' 's/^X//' > input.c X/* INPUT: Various input routines for MicroEMACS 3.7 X written by Daniel Lawrence X 5/9/86 */ X X#include <stdio.h> X#include "estruct.h" X#include "edef.h" X X/* X * Ask a yes or no question in the message line. Return either TRUE, FALSE, or X * ABORT. The ABORT status is returned if the user bumps out of the question X * with a ^G. Used any time a confirmation is required. X */ X Xmlyesno(prompt) X Xchar *prompt; X X{ X char c; /* input character */ X char buf[NPAT]; /* prompt to user */ X X for (;;) { X /* build and prompt the user */ X strcpy(buf, prompt); X strcat(buf, " [y/n]? "); X mlwrite(buf); X X /* get the responce */ X c = tgetc(); X X if (c == ectoc(abortc)) /* Bail out! */ X return(ABORT); X X if (c=='y' || c=='Y') X return(TRUE); X X if (c=='n' || c=='N') X return(FALSE); X } X} X X/* X * Write a prompt into the message line, then read back a response. Keep X * track of the physical position of the cursor. If we are in a keyboard X * macro throw the prompt away, and return the remembered response. This X * lets macros run at full speed. The reply is always terminated by a carriage X * return. Handle erase, kill, and abort keys. X */ X Xmlreply(prompt, buf, nbuf) X char *prompt; X char *buf; X{ X return(nextarg(prompt, buf, nbuf, ctoec('\n'))); X} X Xmlreplyt(prompt, buf, nbuf, eolchar) X Xchar *prompt; Xchar *buf; Xint eolchar; X X{ X return(nextarg(prompt, buf, nbuf, eolchar)); X} X X/* ectoc: expanded character to character X colapse the CTRL and SPEC flags back into an ascii code */ X Xectoc(c) X Xint c; X X{ X if (c & CTRL) X c = c & ~(CTRL | 0x40); X if (c & SPEC) X c= c & 255; X return(c); X} X X/* ctoec: character to extended character X pull out the CTRL and SPEC prefixes (if possible) */ X Xctoec(c) X Xint c; X X{ X if (c>=0x00 && c<=0x1F) X c = CTRL | (c+'@'); X return (c); X} X X/* get a command name from the command line. Command completion means X that pressing a <SPACE> will attempt to complete an unfinished command X name if it is unique. X*/ X Xint (*getname())() X X{ X#if ST520 & LATTICE X#define register X#endif X register int cpos; /* current column on screen output */ X register int c; X register char *sp; /* pointer to string for output */ X register NBIND *ffp; /* first ptr to entry in name binding table */ X register NBIND *cffp; /* current ptr to entry in name binding table */ X register NBIND *lffp; /* last ptr to entry in name binding table */ X char buf[NSTRING]; /* buffer to hold tentative command name */ X int (*fncmatch())(); X X /* starting at the beginning of the string buffer */ X cpos = 0; X X /* if we are executing a command line get the next arg and match it */ X if (clexec) { X if (macarg(buf) != TRUE) X return(FALSE); X return(fncmatch(&buf[0])); X } X X /* build a name string from the keyboard */ X while (TRUE) { X c = tgetc(); X X /* if we are at the end, just match it */ X if (c == 0x0d) { X buf[cpos] = 0; X X /* and match it off */ X return(fncmatch(&buf[0])); X X } else if (c == ectoc(abortc)) { /* Bell, abort */ X ctrlg(FALSE, 0); X TTflush(); X return( (int (*)()) NULL); X X } else if (c == 0x7F || c == 0x08) { /* rubout/erase */ X if (cpos != 0) { X TTputc('\b'); X TTputc(' '); X TTputc('\b'); X --ttcol; X --cpos; X TTflush(); X } X X } else if (c == 0x15) { /* C-U, kill */ X while (cpos != 0) { X TTputc('\b'); X TTputc(' '); X TTputc('\b'); X --cpos; X --ttcol; X } X X TTflush(); X X } else if (c == ' ') { X/* <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< */ X /* attempt a completion */ X buf[cpos] = 0; /* terminate it for us */ X ffp = &names[0]; /* scan for matches */ X while (ffp->n_func != NULL) { X if (strncmp(buf, ffp->n_name, strlen(buf)) == 0) { X /* a possible match! More than one? */ X if ((ffp + 1)->n_func == NULL || X (strncmp(buf, (ffp+1)->n_name, strlen(buf)) != 0)) { X /* no...we match, print it */ X sp = ffp->n_name + cpos; X while (*sp) X TTputc(*sp++); X TTflush(); X return(ffp->n_func); X } else { X/* << << << << << << << << << << << << << << << << << */ X /* try for a partial match against the list */ X X /* first scan down until we no longer match the current input */ X lffp = (ffp + 1); X while ((lffp+1)->n_func != NULL) { X if (strncmp(buf, (lffp+1)->n_name, strlen(buf)) != 0) X break; X ++lffp; X } X X /* and now, attempt to partial complete the string, char at a time */ X while (TRUE) { X /* add the next char in */ X buf[cpos] = ffp->n_name[cpos]; X X /* scan through the candidates */ X cffp = ffp + 1; X while (cffp <= lffp) { X if (cffp->n_name[cpos] != buf[cpos]) X goto onward; X ++cffp; X } X X /* add the character */ X TTputc(buf[cpos++]); X } X/* << << << << << << << << << << << << << << << << << */ X } X } X ++ffp; X } X X /* no match.....beep and onward */ X TTbeep(); Xonward:; X TTflush(); X/* <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< */ X } else { X if (cpos < NSTRING-1 && c > ' ') { X buf[cpos++] = c; X TTputc(c); X } X X ++ttcol; X TTflush(); X } X } X} X X/* tgetc: Get a key from the terminal driver, resolve any keyboard X macro action */ X Xint tgetc() X X{ X int c; /* fetched character */ X X /* if we are playing a keyboard macro back, */ X if (kbdmode == PLAY) { X X /* if there is some left... */ X if (kbdptr < kbdend) X return((int)*kbdptr++); X X /* at the end of last repitition? */ X if (--kbdrep < 1) { X kbdmode = STOP; X#if VISMAC == 0 X /* force a screen update after all is done */ X update(FALSE); X#endif X } else { X X /* reset the macro to the begining for the next rep */ X kbdptr = &kbdm[0]; X return((int)*kbdptr++); X } X } X X /* fetch a character from the terminal driver */ X c = TTgetc(); X X /* record it for $lastkey */ X lastkey = c; X X /* save it if we need to */ X if (kbdmode == RECORD) { X *kbdptr++ = c; X kbdend = kbdptr; X X /* don't overrun the buffer */ X if (kbdptr == &kbdm[NKBDM - 1]) { X kbdmode = STOP; X TTbeep(); X } X } X X /* and finally give the char back */ X return(c); X} X X/* GET1KEY: Get one keystroke. The only prefixs legal here X are the SPEC and CTRL prefixes. X */ X Xget1key() X X{ X int c; X#if AMIGA X int d; X#endif X X /* get a keystroke */ X c = tgetc(); X X#if MSDOS | ST520 X if (c == 0) { /* Apply SPEC prefix */ X c = tgetc(); X if (c>=0x00 && c<=0x1F) /* control key? */ X c = CTRL | (c+'@'); X return(SPEC | c); X } X#endif X X#if AMIGA X /* apply SPEC prefix */ X if ((unsigned)c == 155) { X c = tgetc(); X X /* first try to see if it is a cursor key */ X if ((c >= 'A' && c <= 'D') || c == 'S' || c == 'T') X return(SPEC | c); X X /* next, a 2 char sequence */ X d = tgetc(); X if (d == '~') X return(SPEC | c); X X /* decode a 3 char sequence */ X c = d + 32; X /* if a shifted function key, eat the tilde */ X if (d >= '0' && d <= '9') X d = tgetc(); X return(SPEC | c); X } X#endif X X#if WANGPC X if (c == 0x1F) { /* Apply SPEC prefix */ X c = tgetc(); X return(SPEC | c); X } X#endif X X if (c>=0x00 && c<=0x1F) /* C0 control -> C- */ X c = CTRL | (c+'@'); X return (c); X} X X/* GETCMD: Get a command from the keyboard. Process all applicable X prefix keys X */ Xgetcmd() X X{ X int c; /* fetched keystroke */ X X /* get initial character */ X c = get1key(); X X /* process META prefix */ X if (c == metac) { X c = get1key(); X if (islower(c)) /* Force to upper */ X c ^= DIFCASE; X if (c>=0x00 && c<=0x1F) /* control key */ X c = CTRL | (c+'@'); X return(META | c); X } X X /* process CTLX prefix */ X if (c == ctlxc) { X c = get1key(); X if (c>='a' && c<='z') /* Force to upper */ X c -= 0x20; X if (c>=0x00 && c<=0x1F) /* control key */ X c = CTRL | (c+'@'); X return(CTLX | c); X } X X /* otherwise, just return it */ X return(c); X} X X/* A more generalized prompt/reply function allowing the caller X to specify the proper terminator. If the terminator is not X a return ('\n') it will echo as "<NL>" X */ Xgetstring(prompt, buf, nbuf, eolchar) X Xchar *prompt; Xchar *buf; Xint eolchar; X X{ X register int cpos; /* current character position in string */ X register int c; X register int quotef; /* are we quoting the next char? */ X X cpos = 0; X quotef = FALSE; X X /* prompt the user for the input string */ X mlwrite(prompt); X X for (;;) { X /* get a character from the user */ X c = get1key(); X X /* If it is a <ret>, change it to a <NL> */ X if (c == (CTRL | 0x4d)) X c = CTRL | 0x40 | '\n'; X X /* if they hit the line terminate, wrap it up */ X if (c == eolchar && quotef == FALSE) { X buf[cpos++] = 0; X X /* clear the message line */ X mlwrite(""); X TTflush(); X X /* if we default the buffer, return FALSE */ X if (buf[0] == 0) X return(FALSE); X X return(TRUE); X } X X /* change from command form back to character form */ X c = ectoc(c); X X if (c == ectoc(abortc) && quotef == FALSE) { X /* Abort the input? */ X ctrlg(FALSE, 0); X TTflush(); X return(ABORT); X } else if ((c==0x7F || c==0x08) && quotef==FALSE) { X /* rubout/erase */ X if (cpos != 0) { X outstring("\b \b"); X --ttcol; X X if (buf[--cpos] < 0x20) { X outstring("\b \b"); X --ttcol; X } X X if (buf[cpos] == '\n') { X outstring("\b\b \b\b"); X ttcol -= 2; X } X TTflush(); X } X X } else if (c == 0x15 && quotef == FALSE) { X /* C-U, kill */ X while (cpos != 0) { X outstring("\b \b"); X --ttcol; X X if (buf[--cpos] < 0x20) { X outstring("\b \b"); X --ttcol; X } X } X TTflush(); X X } else if (c == quotec && quotef == FALSE) { X quotef = TRUE; X } else { X quotef = FALSE; X if (cpos < nbuf-1) { X buf[cpos++] = c; X X if ((c < ' ') && (c != '\n')) { X outstring("^"); X ++ttcol; X c ^= 0x40; X } X X if (c != '\n') { X if (disinp) X TTputc(c); X } else { /* put out <NL> for <ret> */ X outstring("<NL>"); X ttcol += 3; X } X ++ttcol; X TTflush(); X } X } X } X} X Xoutstring(s) /* output a string of characters */ X Xchar *s; /* string to output */ X X{ X if (disinp) X while (*s) X TTputc(*s++); X} E!O!F newsize=`wc -c < input.c` if [ $newsize -ne 9954 ] then echo "File input.c was $newsize bytes, 9954 expected" fi echo 'x - isearch.c (text)' sed << 'E!O!F' 's/^X//' > isearch.c X/* X * The functions in this file implement commands that perform incremental X * searches in the forward and backward directions. This "ISearch" command X * is intended to emulate the same command from the original EMACS X * implementation (ITS). Contains references to routines internal to X * SEARCH.C. X * X * REVISION HISTORY: X * X * D. R. Banks 9-May-86 X * - added ITS EMACSlike ISearch X * X * John M. Gamble 5-Oct-86 X * - Made iterative search use search.c's scanner() routine. X * This allowed the elimination of bakscan(). X * - Put isearch constants into estruct.h X * - Eliminated the passing of 'status' to scanmore() and X * checknext(), since there were no circumstances where X * it ever equalled FALSE. X */ X X#include <stdio.h> X#include "estruct.h" X#include "edef.h" X X#if ISRCH X Xextern int scanner(); /* Handy search routine */ Xextern int eq(); /* Compare chars, match case */ X X/* A couple of "own" variables for re-eat */ X Xint (*saved_get_char)(); /* Get character routine */ Xint eaten_char = -1; /* Re-eaten char */ X X/* A couple more "own" variables for the command string */ X Xint cmd_buff[CMDBUFLEN]; /* Save the command args here */ Xint cmd_offset; /* Current offset into command buff */ Xint cmd_reexecute = -1; /* > 0 if re-executing command */ X X X/* X * Subroutine to do incremental reverse search. It actually uses the X * same code as the normal incremental search, as both can go both ways. X */ X Xint risearch(f, n) X{ X LINE *curline; /* Current line on entry */ X int curoff; /* Current offset on entry */ X X /* remember the initial . on entry: */ X X curline = curwp->w_dotp; /* Save the current line pointer */ X curoff = curwp->w_doto; /* Save the current offset */ X X /* Make sure the search doesn't match where we already are: */ X X backchar(TRUE, 1); /* Back up a character */ X X if (!(isearch(f, -n))) /* Call ISearch backwards */ X { /* If error in search: */ X curwp->w_dotp = curline; /* Reset the line pointer */ X curwp->w_doto = curoff; /* and the offset to original value */ X curwp->w_flag |= WFMOVE; /* Say we've moved */ X update(FALSE); /* And force an update */ X mlwrite ("[search failed]"); /* Say we died */ X } else mlerase (); /* If happy, just erase the cmd line */ X} X X/* Again, but for the forward direction */ X Xint fisearch(f, n) X{ X LINE *curline; /* Current line on entry */ X int curoff; /* Current offset on entry */ X X /* remember the initial . on entry: */ X X curline = curwp->w_dotp; /* Save the current line pointer */ X curoff = curwp->w_doto; /* Save the current offset */ X X /* do the search */ X X if (!(isearch(f, n))) /* Call ISearch forwards */ X { /* If error in search: */ X curwp->w_dotp = curline; /* Reset the line pointer */ X curwp->w_doto = curoff; /* and the offset to original value */ X curwp->w_flag |= WFMOVE; /* Say we've moved */ X update(FALSE); /* And force an update */ X mlwrite ("[search failed]"); /* Say we died */ X } else mlerase (); /* If happy, just erase the cmd line */ X} X X/* X * Subroutine to do an incremental search. In general, this works similarly X * to the older micro-emacs search function, except that the search happens X * as each character is typed, with the screen and cursor updated with each X * new search character. X * X * While searching forward, each successive character will leave the cursor X * at the end of the entire matched string. Typing a Control-S or Control-X X * will cause the next occurrence of the string to be searched for (where the X * next occurrence does NOT overlap the current occurrence). A Control-R will X * change to a backwards search, META will terminate the search and Control-G X * will abort the search. Rubout will back up to the previous match of the X * string, or if the starting point is reached first, it will delete the X * last character from the search string. X * X * While searching backward, each successive character will leave the cursor X * at the beginning of the matched string. Typing a Control-R will search X * backward for the next occurrence of the string. Control-S or Control-X X * will revert the search to the forward direction. In general, the reverse X * incremental search is just like the forward incremental search inverted. X * X * In all cases, if the search fails, the user will be feeped, and the search X * will stall until the pattern string is edited back into something that X * exists (or until the search is aborted). X */ X Xisearch(f, n) X{ X int status; /* Search status */ X int col; /* prompt column */ X register int cpos; /* character number in search string */ X register int c; /* current input character */ X register int expc; /* function expanded input char */ X char pat_save[NPAT]; /* Saved copy of the old pattern str */ X LINE *curline; /* Current line on entry */ X int curoff; /* Current offset on entry */ X int init_direction; /* The initial search direction */ X X /* Initialize starting conditions */ X X cmd_reexecute = -1; /* We're not re-executing (yet?) */ X cmd_offset = 0; /* Start at the beginning of the buff */ X cmd_buff[0] = '\0'; /* Init the command buffer */ X strncpy (pat_save, pat, NPAT); /* Save the old pattern string */ X curline = curwp->w_dotp; /* Save the current line pointer */ X curoff = curwp->w_doto; /* Save the current offset */ X init_direction = n; /* Save the initial search direction */ X X /* This is a good place to start a re-execution: */ X Xstart_over: X X /* ask the user for the text of a pattern */ X col = promptpattern("ISearch: "); /* Prompt, remember the col */ X X cpos = 0; /* Start afresh */ X status = TRUE; /* Assume everything's cool */ X X /* X Get the first character in the pattern. If we get an initial Control-S X or Control-R, re-use the old search string and find the first occurrence X */ X X c = ectoc(expc = get_char()); /* Get the first character */ X if ((c == IS_FORWARD) || X (c == IS_REVERSE) || X (c == IS_VMSFORW)) /* Reuse old search string? */ X { X for (cpos = 0; pat[cpos] != 0; cpos++) /* Yup, find the length */ X col = echochar(pat[cpos],col); /* and re-echo the string */ X if (c == IS_REVERSE) { /* forward search? */ X n = -1; /* No, search in reverse */ X backchar (TRUE, 1); /* Be defensive about EOB */ X } else X n = 1; /* Yes, search forward */ X status = scanmore(pat, n); /* Do the search */ X c = ectoc(expc = get_char()); /* Get another character */ X } X X /* Top of the per character loop */ X X for (;;) /* ISearch per character loop */ X { X /* Check for special characters first: */ X /* Most cases here change the search */ X X if (expc == metac) /* Want to quit searching? */ X return (TRUE); /* Quit searching now */ X X switch (c) /* dispatch on the input char */ X { X case IS_ABORT: /* If abort search request */ X return(FALSE); /* Quit searching again */ X X case IS_REVERSE: /* If backward search */ X case IS_FORWARD: /* If forward search */ X case IS_VMSFORW: /* of either flavor */ X if (c == IS_REVERSE) /* If reverse search */ X n = -1; /* Set the reverse direction */ X else /* Otherwise, */ X n = 1; /* go forward */ X status = scanmore(pat, n); /* Start the search again */ X c = ectoc(expc = get_char()); /* Get the next char */ X continue; /* Go continue with the search*/ X X case IS_NEWLINE: /* Carriage return */ X c = '\n'; /* Make it a new line */ X break; /* Make sure we use it */ X X case IS_QUOTE: /* Quote character */ X case IS_VMSQUOTE: /* of either variety */ X c = ectoc(expc = get_char()); /* Get the next char */ X X case IS_TAB: /* Generically allowed */ X case '\n': /* controlled characters */ X break; /* Make sure we use it */ X X case IS_BACKSP: /* If a backspace: */ X case IS_RUBOUT: /* or if a Rubout: */ X if (cmd_offset <= 1) /* Anything to delete? */ X return (TRUE); /* No, just exit */ X --cmd_offset; /* Back up over the Rubout */ X cmd_buff[--cmd_offset] = '\0'; /* Yes, delete last char */ X curwp->w_dotp = curline; /* Reset the line pointer */ X curwp->w_doto = curoff; /* and the offset */ X n = init_direction; /* Reset the search direction */ X strncpy (pat, pat_save, NPAT); /* Restore the old search str */ X cmd_reexecute = 0; /* Start the whole mess over */ X goto start_over; /* Let it take care of itself */ X X /* Presumably a quasi-normal character comes here */ X X default: /* All other chars */ X if (c < ' ') /* Is it printable? */ X { /* Nope. */ X reeat (c); /* Re-eat the char */ X return (TRUE); /* And return the last status */ X } X } /* Switch */ X X /* I guess we got something to search for, so search for it */ X X pat[cpos++] = c; /* put the char in the buffer */ X if (cpos >= NPAT) /* too many chars in string? */ X { /* Yup. Complain about it */ X mlwrite("? Search string too long"); X return(TRUE); /* Return an error */ X } X pat[cpos] = 0; /* null terminate the buffer */ X col = echochar(c,col); /* Echo the character */ X if (!status) { /* If we lost last time */ X TTputc(BELL); /* Feep again */ X TTflush(); /* see that the feep feeps */ X } else /* Otherwise, we must have won*/ X if (!(status = checknext(c, pat, n))) /* See if match */ X status = scanmore(pat, n); /* or find the next match */ X c = ectoc(expc = get_char()); /* Get the next char */ X } /* for {;;} */ X} X X/* X * Trivial routine to insure that the next character in the search string is X * still true to whatever we're pointing to in the buffer. This routine will X * not attempt to move the "point" if the match fails, although it will X * implicitly move the "point" if we're forward searching, and find a match, X * since that's the way forward isearch works. X * X * If the compare fails, we return FALSE and assume the caller will call X * scanmore or something. X */ X Xint checknext (chr, patrn, dir) /* Check next character in search string */ Xchar chr; /* Next char to look for */ Xchar *patrn; /* The entire search string (incl chr) */ Xint dir; /* Search direction */ X{ X register LINE *curline; /* current line during scan */ X register int curoff; /* position within current line */ X register int buffchar; /* character at current position */ X int status; /* how well things go */ X X X /* setup the local scan pointer to current "." */ X X curline = curwp->w_dotp; /* Get the current line structure */ X curoff = curwp->w_doto; /* Get the offset within that line */ X X if (dir > 0) /* If searching forward */ X { X if (curoff == llength(curline)) /* If at end of line */ X { X curline = lforw(curline); /* Skip to the next line */ X if (curline == curbp->b_linep) X return (FALSE); /* Abort if at end of buffer */ X curoff = 0; /* Start at the beginning of the line */ X buffchar = '\n'; /* And say the next char is NL */ X } else X buffchar = lgetc(curline, curoff++); /* Get the next char */ X if (status = eq(buffchar, chr)) /* Is it what we're looking for? */ X { X curwp->w_dotp = curline; /* Yes, set the buffer's point */ X curwp->w_doto = curoff; /* to the matched character */ X curwp->w_flag |= WFMOVE; /* Say that we've moved */ X } X return (status); /* And return the status */ X } else /* Else, if reverse search: */ X return (match_pat (patrn)); /* See if we're in the right place */ X} X X/* X * This hack will search for the next occurrence of <pat> in the buffer, either X * forward or backward. It is called with the status of the prior search X * attempt, so that it knows not to bother if it didn't work last time. If X * we can't find any more matches, "point" is left where it was before. If X * we do find a match, "point" will be at the end of the matched string for X * forward searches and at the beginning of the matched string for reverse X * searches. X */ X Xint scanmore(patrn, dir) /* search forward or back for a pattern */ Xchar *patrn; /* string to scan for */ Xint dir; /* direction to search */ X{ X int sts; /* search status */ X X if (dir < 0) /* reverse search? */ X { X rvstrcpy(tap, patrn); /* Put reversed string in tap */ X sts = scanner(tap, REVERSE, PTBEG); X } X else X sts = scanner(patrn, FORWARD, PTEND); /* Nope. Go forward */ X X if (!sts) X { X TTputc(BELL); /* Feep if search fails */ X TTflush(); /* see that the feep feeps */ X } X X return(sts); /* else, don't even try */ X} X X/* X * The following is a worker subroutine used by the reverse search. It X * compares the pattern string with the characters at "." for equality. If X * any characters mismatch, it will return FALSE. X * X * This isn't used for forward searches, because forward searches leave "." X * at the end of the search string (instead of in front), so all that needs to X * be done is match the last char input. X */ X Xint match_pat (patrn) /* See if the pattern string matches string at "." */ Xchar *patrn; /* String to match to buffer */ X{ X register int i; /* Generic loop index/offset */ X register int buffchar; /* character at current position */ X register LINE *curline; /* current line during scan */ X register int curoff; /* position within current line */ X X /* setup the local scan pointer to current "." */ X X curline = curwp->w_dotp; /* Get the current line structure */ X curoff = curwp->w_doto; /* Get the offset within that line */ X X /* top of per character compare loop: */ X X for (i = 0; i < strlen(patrn); i++) /* Loop for all characters in patrn */ X { X if (curoff == llength(curline)) /* If at end of line */ X { X curline = lforw(curline); /* Skip to the next line */ X curoff = 0; /* Start at the beginning of the line */ X if (curline == curbp->b_linep) X return (FALSE); /* Abort if at end of buffer */ X buffchar = '\n'; /* And say the next char is NL */ X } else X buffchar = lgetc(curline, curoff++); /* Get the next char */ X if (!eq(buffchar, patrn[i])) /* Is it what we're looking for? */ X return (FALSE); /* Nope, just punt it then */ X } X return (TRUE); /* Everything matched? Let's celebrate*/ X} X X/* Routine to prompt for I-Search string. */ X Xint promptpattern(prompt) Xchar *prompt; X{ X char tpat[NPAT+20]; X X strcpy(tpat, prompt); /* copy prompt to output string */ X strcat(tpat, " ["); /* build new prompt string */ X expandp(pat, &tpat[strlen(tpat)], NPAT/2); /* add old pattern */ X strcat(tpat, "]<META>: "); X X /* check to see if we are executing a command line */ X if (!clexec) { X mlwrite(tpat); X } X return(strlen(tpat)); X} X X/* routine to echo i-search characters */ X Xint echochar(c,col) Xint c; /* character to be echoed */ Xint col; /* column to be echoed in */ X{ X movecursor(term.t_nrow,col); /* Position the cursor */ X if ((c < ' ') || (c == 0x7F)) /* Control character? */ X { X switch (c) /* Yes, dispatch special cases*/ X { X case '\n': /* Newline */ X TTputc('<'); X TTputc('N'); X TTputc('L'); X TTputc('>'); X col += 3; X break; X X case '\t': /* Tab */ X TTputc('<'); X TTputc('T'); X TTputc('A'); X TTputc('B'); X TTputc('>'); X col += 4; X break; X X case 0x7F: /* Rubout: */ X TTputc('^'); /* Output a funny looking */ X TTputc('?'); /* indication of Rubout */ X col++; /* Count the extra char */ X break; X X default: /* Vanilla control char */ X TTputc('^'); /* Yes, output prefix */ X TTputc(c+0x40); /* Make it "^X" */ X col++; /* Count this char */ X } X } else X TTputc(c); /* Otherwise, output raw char */ X TTflush(); /* Flush the output */ X return(++col); /* return the new column no */ X} X X/* X * Routine to get the next character from the input stream. If we're reading X * from the real terminal, force a screen update before we get the char. X * Otherwise, we must be re-executing the command string, so just return the X * next character. X */ X Xint get_char () X{ X int c; /* A place to get a character */ X X /* See if we're re-executing: */ X X if (cmd_reexecute >= 0) /* Is there an offset? */ X if ((c = cmd_buff[cmd_reexecute++]) != 0) X return (c); /* Yes, return any character */ X X /* We're not re-executing (or aren't any more). Try for a real char */ X X cmd_reexecute = -1; /* Say we're in real mode again */ X update(FALSE); /* Pretty up the screen */ X if (cmd_offset >= CMDBUFLEN-1) /* If we're getting too big ... */ X { X mlwrite ("? command too long"); /* Complain loudly and bitterly */ X return (metac); /* And force a quit */ X } X c = get1key(); /* Get the next character */ X cmd_buff[cmd_offset++] = c; /* Save the char for next time */ X cmd_buff[cmd_offset] = '\0';/* And terminate the buffer */ X return (c); /* Return the character */ X} X X/* X * Hacky routine to re-eat a character. This will save the character to be X * re-eaten by redirecting the input call to a routine here. Hack, etc. X */ X X/* Come here on the next term.t_getchar call: */ X Xint uneat() X{ X int c; X X term.t_getchar = saved_get_char; /* restore the routine address */ X c = eaten_char; /* Get the re-eaten char */ X eaten_char = -1; /* Clear the old char */ X return(c); /* and return the last char */ X} X Xint reeat(c) Xint c; X{ X if (eaten_char != -1) /* If we've already been here */ X return/*(NULL)*/; /* Don't do it again */ X eaten_char = c; /* Else, save the char for later */ X saved_get_char = term.t_getchar; /* Save the char get routine */ X term.t_getchar = uneat; /* Replace it with ours */ X} X#else Xisearch() X{ X} X#endif E!O!F newsize=`wc -c < isearch.c` if [ $newsize -ne 18697 ] then echo "File isearch.c was $newsize bytes, 18697 expected" fi bill davidsen (wedu@ge-crd.arpa) {chinet | philabs | sesimo}!steinmetz!crdos1!davidsen "Stupidity, like virtue, is its own reward" -me