Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Path: utzoo!utgpu!water!watmath!clyde!cbosgd!mandrill!hal!ncoast!allbery From: allbery@ncoast.UUCP Newsgroups: comp.sources.misc Subject: MicroEmacs 3.9 (Part 2 of 16) Message-ID: <5649@ncoast.UUCP> Date: Sat, 14-Nov-87 16:06:32 EST Article-I.D.: ncoast.5649 Posted: Sat Nov 14 16:06:32 1987 Date-Received: Tue, 17-Nov-87 05:14:42 EST Sender: allbery@ncoast.UUCP Lines: 974 Approved: allbery@ncoast.UUCP X-Archive: comp.sources.misc/microemacs-3.9/1 # This is a shar archive. # Remove everything above this line. # Run the file through sh, not csh. # (type `sh mes.2') # If you do not see the message # `mes.2 completed!' # then the file was incomplete. echo extracting - buffer.c sed 's/^X//' > buffer.c << 'FRIDAY_NIGHT' X/* X * Buffer management. X * Some of the functions are internal, X * and some are actually attached to user X * keys. Like everyone else, they set hints X * for the display system. X */ X#include X#include "estruct.h" X#include "edef.h" X X/* X * Attach a buffer to a window. The X * values of dot and mark come from the buffer X * if the use count is 0. Otherwise, they come X * from some other window. X */ Xusebuffer(f, n) X{ X register BUFFER *bp; X register int s; X char bufn[NBUFN]; X X if ((s=mlreply("Use buffer: ", bufn, NBUFN)) != TRUE) X return (s); X if ((bp=bfind(bufn, TRUE, 0)) == NULL) X return (FALSE); X return(swbuffer(bp)); X} X Xnextbuffer(f, n) /* switch to the next buffer in the buffer list */ X Xint f, n; /* default flag, numeric argument */ X{ X register BUFFER *bp; /* eligable buffer to switch to*/ X register BUFFER *bbp; /* eligable buffer to switch to*/ X X /* make sure the arg is legit */ X if (f == FALSE) X n = 1; X if (n < 1) X return(FALSE); X X bbp = curbp; X while (n-- > 0) { X /* advance to the next buffer */ X bp = bbp->b_bufp; X X /* cycle through the buffers to find an eligable one */ X while (bp == NULL || bp->b_flag & BFINVS) { X if (bp == NULL) X bp = bheadp; X else X bp = bp->b_bufp; X X /* don't get caught in an infinite loop! */ X if (bp == bbp) X return(FALSE); X X } X X bbp = bp; X } X X return(swbuffer(bp)); X} X Xswbuffer(bp) /* make buffer BP current */ X XBUFFER *bp; X X{ X register WINDOW *wp; X X if (--curbp->b_nwnd == 0) { /* Last use. */ X curbp->b_dotp = curwp->w_dotp; X curbp->b_doto = curwp->w_doto; X curbp->b_markp = curwp->w_markp; X curbp->b_marko = curwp->w_marko; X } X curbp = bp; /* Switch. */ X if (curbp->b_active != TRUE) { /* buffer not active yet*/ X /* read it in and activate it */ X readin(curbp->b_fname, TRUE); X curbp->b_dotp = lforw(curbp->b_linep); X curbp->b_doto = 0; X curbp->b_active = TRUE; X } X curwp->w_bufp = bp; X curwp->w_linep = bp->b_linep; /* For macros, ignored. */ X curwp->w_flag |= WFMODE|WFFORCE|WFHARD; /* Quite nasty. */ X if (bp->b_nwnd++ == 0) { /* First use. */ X curwp->w_dotp = bp->b_dotp; X curwp->w_doto = bp->b_doto; X curwp->w_markp = bp->b_markp; X curwp->w_marko = bp->b_marko; X return (TRUE); X } X wp = wheadp; /* Look for old. */ X while (wp != NULL) { X if (wp!=curwp && wp->w_bufp==bp) { X curwp->w_dotp = wp->w_dotp; X curwp->w_doto = wp->w_doto; X curwp->w_markp = wp->w_markp; X curwp->w_marko = wp->w_marko; X break; X } X wp = wp->w_wndp; X } X return (TRUE); X} X X/* X * Dispose of a buffer, by name. X * Ask for the name. Look it up (don't get too X * upset if it isn't there at all!). Get quite upset X * if the buffer is being displayed. Clear the buffer (ask X * if the buffer has been changed). Then free the header X * line and the buffer header. Bound to "C-X K". X */ Xkillbuffer(f, n) X X{ X register BUFFER *bp; X register int s; X char bufn[NBUFN]; X X if ((s=mlreply("Kill buffer: ", bufn, NBUFN)) != TRUE) X return(s); X if ((bp=bfind(bufn, FALSE, 0)) == NULL) /* Easy if unknown. */ X return (TRUE); X if(bp->b_flag & BFINVS) /* Deal with special buffers */ X return (TRUE); /* by doing nothing. */ X return(zotbuf(bp)); X} X Xzotbuf(bp) /* kill the buffer pointed to by bp */ X Xregister BUFFER *bp; X X{ X register BUFFER *bp1; X register BUFFER *bp2; X register int s; X X if (bp->b_nwnd != 0) { /* Error if on screen. */ X mlwrite("Buffer is being displayed"); X return (FALSE); X } X if ((s=bclear(bp)) != TRUE) /* Blow text away. */ X return (s); X free((char *) bp->b_linep); /* Release header line. */ X bp1 = NULL; /* Find the header. */ X bp2 = bheadp; X while (bp2 != bp) { X bp1 = bp2; X bp2 = bp2->b_bufp; X } X bp2 = bp2->b_bufp; /* Next one in chain. */ X if (bp1 == NULL) /* Unlink it. */ X bheadp = bp2; X else X bp1->b_bufp = bp2; X free((char *) bp); /* Release buffer block */ X return (TRUE); X} X Xnamebuffer(f,n) /* Rename the current buffer */ X Xint f, n; /* default Flag & Numeric arg */ X X{ X register BUFFER *bp; /* pointer to scan through all buffers */ X char bufn[NBUFN]; /* buffer to hold buffer name */ X X /* prompt for and get the new buffer name */ Xask: if (mlreply("Change buffer name to: ", bufn, NBUFN) != TRUE) X return(FALSE); X X /* and check for duplicates */ X bp = bheadp; X while (bp != NULL) { X if (bp != curbp) { X /* if the names the same */ X if (strcmp(bufn, bp->b_bname) == 0) X goto ask; /* try again */ X } X bp = bp->b_bufp; /* onward */ X } X X strcpy(curbp->b_bname, bufn); /* copy buffer name to structure */ X curwp->w_flag |= WFMODE; /* make mode line replot */ X mlerase(); X return(TRUE); X} X X/* X List all of the active buffers. First update the special X buffer that holds the list. Next make sure at least 1 X window is displaying the buffer list, splitting the screen X if this is what it takes. Lastly, repaint all of the X windows that are displaying the list. Bound to "C-X C-B". X A numeric argument forces it to list invisable buffers as X well. X*/ X Xlistbuffers(f, n) X{ X register WINDOW *wp; X register BUFFER *bp; X register int s; X X if ((s=makelist(f)) != TRUE) X return (s); X if (blistp->b_nwnd == 0) { /* Not on screen yet. */ X if ((wp=wpopup()) == NULL) X return (FALSE); X bp = wp->w_bufp; X if (--bp->b_nwnd == 0) { X bp->b_dotp = wp->w_dotp; X bp->b_doto = wp->w_doto; X bp->b_markp = wp->w_markp; X bp->b_marko = wp->w_marko; X } X wp->w_bufp = blistp; X ++blistp->b_nwnd; X } X wp = wheadp; X while (wp != NULL) { X if (wp->w_bufp == blistp) { X wp->w_linep = lforw(blistp->b_linep); X wp->w_dotp = lforw(blistp->b_linep); X wp->w_doto = 0; X wp->w_markp = NULL; X wp->w_marko = 0; X wp->w_flag |= WFMODE|WFHARD; X } X wp = wp->w_wndp; X } X return (TRUE); X} X X/* X * This routine rebuilds the X * text in the special secret buffer X * that holds the buffer list. It is called X * by the list buffers command. Return TRUE X * if everything works. Return FALSE if there X * is an error (if there is no memory). Iflag X * indecates weather to list hidden buffers. X */ Xmakelist(iflag) X Xint iflag; /* list hidden buffer flag */ X X{ X register char *cp1; X register char *cp2; X register int c; X register BUFFER *bp; X register LINE *lp; X register int s; X register int i; X long nbytes; /* # of bytes in current buffer */ X char b[7+1]; X char line[128]; X X blistp->b_flag &= ~BFCHG; /* Don't complain! */ X if ((s=bclear(blistp)) != TRUE) /* Blow old text away */ X return (s); X strcpy(blistp->b_fname, ""); X if (addline("ACT MODES Size Buffer File") == FALSE X || addline("--- ----- ---- ------ ----") == FALSE) X return (FALSE); X bp = bheadp; /* For all buffers */ X X /* build line to report global mode settings */ X cp1 = &line[0]; X *cp1++ = ' '; X *cp1++ = ' '; X *cp1++ = ' '; X *cp1++ = ' '; X X /* output the mode codes */ X for (i = 0; i < NUMMODES; i++) X if (gmode & (1 << i)) X *cp1++ = modecode[i]; X else X *cp1++ = '.'; X strcpy(cp1, " Global Modes"); X if (addline(line) == FALSE) X return(FALSE); X X /* output the list of buffers */ X while (bp != NULL) { X /* skip invisable buffers if iflag is false */ X if (((bp->b_flag&BFINVS) != 0) && (iflag != TRUE)) { X bp = bp->b_bufp; X continue; X } X cp1 = &line[0]; /* Start at left edge */ X X /* output status of ACTIVE flag (has the file been read in? */ X if (bp->b_active == TRUE) /* "@" if activated */ X *cp1++ = '@'; X else X *cp1++ = ' '; X X /* output status of changed flag */ X if ((bp->b_flag&BFCHG) != 0) /* "*" if changed */ X *cp1++ = '*'; X else X *cp1++ = ' '; X X /* report if the file is truncated */ X if ((bp->b_flag&BFTRUNC) != 0) X *cp1++ = '#'; X else X *cp1++ = ' '; X X *cp1++ = ' '; /* space */ X X /* output the mode codes */ X for (i = 0; i < NUMMODES; i++) { X if (bp->b_mode & (1 << i)) X *cp1++ = modecode[i]; X else X *cp1++ = '.'; X } X *cp1++ = ' '; /* Gap. */ X nbytes = 0L; /* Count bytes in buf. */ X lp = lforw(bp->b_linep); X while (lp != bp->b_linep) { X nbytes += (long)llength(lp)+1L; X lp = lforw(lp); X } X ltoa(b, 7, nbytes); /* 6 digit buffer size. */ X cp2 = &b[0]; X while ((c = *cp2++) != 0) X *cp1++ = c; X *cp1++ = ' '; /* Gap. */ X cp2 = &bp->b_bname[0]; /* Buffer name */ X while ((c = *cp2++) != 0) X *cp1++ = c; X cp2 = &bp->b_fname[0]; /* File name */ X if (*cp2 != 0) { X while (cp1 < &line[3+1+5+1+6+4+NBUFN]) X *cp1++ = ' '; X while ((c = *cp2++) != 0) { X if (cp1 < &line[128-1]) X *cp1++ = c; X } X } X *cp1 = 0; /* Add to the buffer. */ X if (addline(line) == FALSE) X return (FALSE); X bp = bp->b_bufp; X } X return (TRUE); /* All done */ X} X Xltoa(buf, width, num) X Xchar buf[]; Xint width; Xlong num; X X{ X buf[width] = 0; /* End of string. */ X while (num >= 10) { /* Conditional digits. */ X buf[--width] = (int)(num%10L) + '0'; X num /= 10L; X } X buf[--width] = (int)num + '0'; /* Always 1 digit. */ X while (width != 0) /* Pad with blanks. */ X buf[--width] = ' '; X} X X/* X * The argument "text" points to X * a string. Append this line to the X * buffer list buffer. Handcraft the EOL X * on the end. Return TRUE if it worked and X * FALSE if you ran out of room. X */ Xaddline(text) Xchar *text; X{ X register LINE *lp; X register int i; X register int ntext; X X ntext = strlen(text); X if ((lp=lalloc(ntext)) == NULL) X return (FALSE); X for (i=0; ib_linep->l_bp->l_fp = lp; /* Hook onto the end */ X lp->l_bp = blistp->b_linep->l_bp; X blistp->b_linep->l_bp = lp; X lp->l_fp = blistp->b_linep; X if (blistp->b_dotp == blistp->b_linep) /* If "." is at the end */ X blistp->b_dotp = lp; /* move it to new line */ X return (TRUE); X} X X/* X * Look through the list of X * buffers. Return TRUE if there X * are any changed buffers. Buffers X * that hold magic internal stuff are X * not considered; who cares if the X * list of buffer names is hacked. X * Return FALSE if no buffers X * have been changed. X */ Xanycb() X{ X register BUFFER *bp; X X bp = bheadp; X while (bp != NULL) { X if ((bp->b_flag&BFINVS)==0 && (bp->b_flag&BFCHG)!=0) X return (TRUE); X bp = bp->b_bufp; X } X return (FALSE); X} X X/* X * Find a buffer, by name. Return a pointer X * to the BUFFER structure associated with it. X * If the buffer is not found X * and the "cflag" is TRUE, create it. The "bflag" is X * the settings for the flags in in buffer. X */ XBUFFER * Xbfind(bname, cflag, bflag) Xregister char *bname; X{ X register BUFFER *bp; X register BUFFER *sb; /* buffer to insert after */ X register LINE *lp; X char *malloc(); X X bp = bheadp; X while (bp != NULL) { X if (strcmp(bname, bp->b_bname) == 0) X return (bp); X bp = bp->b_bufp; X } X if (cflag != FALSE) { X if ((bp=(BUFFER *)malloc(sizeof(BUFFER))) == NULL) X return (NULL); X if ((lp=lalloc(0)) == NULL) { X free((char *) bp); X return (NULL); X } X /* find the place in the list to insert this buffer */ X if (bheadp == NULL || strcmp(bheadp->b_bname, bname) > 0) { X /* insert at the beginning */ X bp->b_bufp = bheadp; X bheadp = bp; X } else { X sb = bheadp; X while (sb->b_bufp != NULL) { X if (strcmp(sb->b_bufp->b_bname, bname) > 0) X break; X sb = sb->b_bufp; X } X X /* and insert it */ X bp->b_bufp = sb->b_bufp; X sb->b_bufp = bp; X } X X /* and set up the other buffer fields */ X bp->b_active = TRUE; X bp->b_dotp = lp; X bp->b_doto = 0; X bp->b_markp = NULL; X bp->b_marko = 0; X bp->b_flag = bflag; X bp->b_mode = gmode; X bp->b_nwnd = 0; X bp->b_linep = lp; X strcpy(bp->b_fname, ""); X strcpy(bp->b_bname, bname); X#if CRYPT X bp->b_key[0] = 0; X#endif X lp->l_fp = lp; X lp->l_bp = lp; X } X return (bp); X} X X/* X * This routine blows away all of the text X * in a buffer. If the buffer is marked as changed X * then we ask if it is ok to blow it away; this is X * to save the user the grief of losing text. The X * window chain is nearly always wrong if this gets X * called; the caller must arrange for the updates X * that are required. Return TRUE if everything X * looks good. X */ Xbclear(bp) Xregister BUFFER *bp; X{ X register LINE *lp; X register int s; X X if ((bp->b_flag&BFINVS) == 0 /* Not scratch buffer. */ X && (bp->b_flag&BFCHG) != 0 /* Something changed */ X && (s=mlyesno("Discard changes")) != TRUE) X return (s); X bp->b_flag &= ~BFCHG; /* Not changed */ X while ((lp=lforw(bp->b_linep)) != bp->b_linep) X lfree(lp); X bp->b_dotp = bp->b_linep; /* Fix "." */ X bp->b_doto = 0; X bp->b_markp = NULL; /* Invalidate "mark" */ X bp->b_marko = 0; X return (TRUE); X} X Xunmark(f, n) /* unmark the current buffers change flag */ X Xint f, n; /* unused command arguments */ X X{ X curbp->b_flag &= ~BFCHG; X curwp->w_flag |= WFMODE; X return(TRUE); X} FRIDAY_NIGHT echo extracting - crypt.c sed 's/^X//' > crypt.c << 'FRIDAY_NIGHT' X/* Crypt: Encryption routines for MicroEMACS X written by Dana Hoggatt and Daniel Lawrence X*/ X X#include X#include "estruct.h" X#include "edef.h" X X#if CRYPT Xsetkey(f, n) /* reset encryption key of current buffer */ X Xint f; /* default flag */ Xint n; /* numeric argument */ X X{ X register int status; /* return status */ X int odisinp; /* original vlaue of disinp */ X char key[NPAT]; /* new encryption string */ X X /* turn command input echo off */ X odisinp = disinp; X disinp = FALSE; X X /* get the string to use as an encrytion string */ X status = mlreply("Encryption String: ", key, NPAT - 1); X disinp = odisinp; X if (status != TRUE) X return(status); X X /* and encrypt it */ X crypt((char *)NULL, 0); X crypt(key, strlen(key)); X X /* and save it off */ X strcpy(curbp->b_key, key); X mlwrite(" "); /* clear it off the bottom line */ X return(TRUE); X} X X/********** X * X * crypt - in place encryption/decryption of a buffer X * X * (C) Copyright 1986, Dana L. Hoggatt X * 1216, Beck Lane, Lafayette, IN X * X * When consulting directly with the author of this routine, X * please refer to this routine as the "DLH-POLY-86-B CIPHER". X * X * This routine was written for Dan Lawrence, for use in V3.8 of X * MicroEMACS, a public domain text/program editor. X * X * I kept the following goals in mind when preparing this function: X * X * 1. All printable characters were to be encrypted back X * into the printable range, control characters and X * high-bit characters were to remain unaffected. this X * way, encrypted would still be just as cheap to X * transmit down a 7-bit data path as they were before. X * X * 2. The encryption had to be portable. The encrypted X * file from one computer should be able to be decrypted X * on another computer. X * X * 3. The encryption had to be inexpensive, both in terms X * of speed and space. X * X * 4. The system needed to be secure against all but the X * most determined of attackers. X * X * For encryption of a block of data, one calls crypt passing X * a pointer to the data block and its length. The data block is X * encrypted in place, that is, the encrypted output overwrites X * the input. Decryption is totally isomorphic, and is performed X * in the same manner by the same routine. X * X * Before using this routine for encrypting data, you are expected X * to specify an encryption key. This key is an arbitrary string, X * to be supplied by the user. To set the key takes two calls to X * crypt(). First, you call X * X * crypt(NULL, vector) X * X * This resets all internal control information. Typically (and X * specifically in the case on MICRO-emacs) you would use a "vector" X * of 0. Other values can be used to customize your editor to be X * "incompatable" with the normally distributed version. For X * this purpose, the best results will be obtained by avoiding X * multiples of 95. X * X * Then, you "encrypt" your password by calling X * X * crypt(pass, strlen(pass)) X * X * where "pass" is your password string. Crypt() will destroy X * the original copy of the password (it becomes encrypted), X * which is good. You do not want someone on a multiuser system X * to peruse your memory space and bump into your password. X * Still, it is a better idea to erase the password buffer to X * defeat memory perusal by a more technical snooper. X * X * For the interest of cryptologists, at the heart of this X * function is a Beaufort Cipher. The cipher alphabet is the X * range of printable characters (' ' to '~'), all "control" X * and "high-bit" characters are left unaltered. X * X * The key is a variant autokey, derived from a wieghted sum X * of all the previous clear text and cipher text. A counter X * is used as salt to obiterate any simple cyclic behavior X * from the clear text, and key feedback is used to assure X * that the entire message is based on the original key, X * preventing attacks on the last part of the message as if X * it were a pure autokey system. X * X * Overall security of encrypted data depends upon three X * factors: the fundamental cryptographic system must be X * difficult to compromise; exhaustive searching of the key X * space must be computationally expensive; keys and plaintext X * must remain out of sight. This system satisfies this set X * of conditions to within the degree desired for MicroEMACS. X * X * Though direct methods of attack (against systems such as X * this) do exist, they are not well known and will consume X * considerable amounts of computing time. An exhaustive X * search requires over a billion investigations, on average. X * X * The choice, entry, storage, manipulation, alteration, X * protection and security of the keys themselves are the X * responsiblity of the user. X * X **********/ X Xcrypt(bptr, len) Xregister char *bptr; /* buffer of characters to be encrypted */ Xregister unsigned len; /* number of characters in the buffer */ X{ X register int cc; /* current character being considered */ X X static long key = 0; /* 29 bit encipherment key */ X static int salt = 0; /* salt to spice up key with */ X X if (!bptr) { /* is there anything here to encrypt? */ X key = len; /* set the new key */ X salt = len; /* set the new salt */ X return; X } X while (len--) { /* for every character in the buffer */ X X cc = *bptr; /* get a character out of the buffer */ X X /* only encipher printable characters */ X if ((cc >= ' ') && (cc <= '~')) { X X/** If the upper bit (bit 29) is set, feed it back into the key. This X assures us that the starting key affects the entire message. **/ X X key &= 0x1FFFFFFFL; /* strip off overflow */ X if (key & 0x10000000L) { X key ^= 0x0040A001L; /* feedback */ X } X X/** Down-bias the character, perform a Beaufort encipherment, and X up-bias the character again. We want key to be positive X so that the left shift here will be more portable and the X mod95() faster **/ X X cc = mod95((int)(key % 95) - (cc - ' ')) + ' '; X X/** the salt will spice up the key a little bit, helping to obscure X any patterns in the clear text, particularly when all the X characters (or long sequences of them) are the same. We do X not want the salt to go negative, or it will affect the key X too radically. It is always a good idea to chop off cyclics X to prime values. **/ X X if (++salt >= 20857) { /* prime modulus */ X salt = 0; X } X X/** our autokey (a special case of the running key) is being X generated by a wieghted checksum of clear text, cipher X text, and salt. **/ X X key = key + key + cc + *bptr + salt; X } X *bptr++ = cc; /* put character back into buffer */ X } X return; X} X Xstatic int mod95(val) X Xregister int val; X X{ X /* The mathematical MOD does not match the computer MOD */ X X /* Yes, what I do here may look strange, but it gets the X job done, and portably at that. */ X X while (val >= 9500) X val -= 9500; X while (val >= 950) X val -= 950; X while (val >= 95) X val -= 95; X while (val < 0) X val += 95; X return (val); X} X#else Xnocrypt() X{ X} X#endif FRIDAY_NIGHT echo extracting - dg10.c sed 's/^X//' > dg10.c << 'FRIDAY_NIGHT' X/* X * The routines in this file provide support for the Data General Model 10 X * Microcomputer. X */ X X#define termdef 1 /* don't define "term" external */ X X#include X#include "estruct.h" X#include "edef.h" X X#if DG10 X X#define NROW 24 /* Screen size. */ X#define NCOL 80 /* Edit if you want to. */ X#define NPAUSE 100 /* # times thru update to pause */ X#define MARGIN 8 /* size of minimim margin and */ X#define SCRSIZ 64 /* scroll size for extended lines */ X#define BEL 0x07 /* BEL character. */ X#define ESC 30 /* DG10 ESC character. */ X Xextern int ttopen(); /* Forward references. */ Xextern int ttgetc(); Xextern int ttputc(); Xextern int ttflush(); Xextern int ttclose(); Xextern int dg10kopen(); Xextern int dg10kclose(); Xextern int dg10move(); Xextern int dg10eeol(); Xextern int dg10eeop(); Xextern int dg10beep(); Xextern int dg10open(); Xextern int dg10rev(); Xextern int dg10close(); Xextern int dg10cres(); X X#if COLOR Xextern int dg10fcol(); Xextern int dg10bcol(); X Xint cfcolor = -1; /* current forground color */ Xint cbcolor = -1; /* current background color */ Xint ctrans[] = { /* emacs -> DG10 color translation table */ X 0, 4, 2, 6, 1, 5, 3, 7}; X#endif X X/* X * Standard terminal interface dispatch table. Most of the fields point into X * "termio" code. X */ XTERM term = { X NROW-1, X NROW-1, X NCOL, X NCOL, X MARGIN, X SCRSIZ, X NPAUSE, X dg10open, X dg10close, X dg10kopen, X dg10kclose, X ttgetc, X ttputc, X ttflush, X dg10move, X dg10eeol, X dg10eeop, X dg10beep, X dg10rev, X dg10cres X#if COLOR X , dg10fcol, X dg10bcol X#endif X}; X X#if COLOR Xdg10fcol(color) /* set the current output color */ X Xint color; /* color to set */ X X{ X if (color == cfcolor) X return; X ttputc(ESC); X ttputc(0101); X ttputc(ctrans[color]); X cfcolor = color; X} X Xdg10bcol(color) /* set the current background color */ X Xint color; /* color to set */ X X{ X if (color == cbcolor) X return; X ttputc(ESC); X ttputc(0102); X ttputc(ctrans[color]); X cbcolor = color; X} X#endif X Xdg10move(row, col) X{ X ttputc(16); X ttputc(col); X ttputc(row); X} X Xdg10eeol() X{ X ttputc(11); X} X Xdg10eeop() X{ X#if COLOR X dg10fcol(gfcolor); X dg10bcol(gbcolor); X#endif X ttputc(ESC); X ttputc(0106); X ttputc(0106); X} X Xdg10rev(state) /* change reverse video state */ X Xint state; /* TRUE = reverse, FALSE = normal */ X X{ X#if COLOR X if (state == TRUE) { X dg10fcol(0); X dg10bcol(7); X } X#else X ttputc(ESC); X ttputc(state ? 0104: 0105); X#endif X} X Xdg10cres() /* change screen resolution */ X X{ X return(TRUE); X} X Xspal() /* change palette string */ X X{ X /* Does nothing here */ X} X Xdg10beep() X{ X ttputc(BEL); X ttflush(); X} X Xdg10open() X{ X strcpy(sres, "NORMAL"); X revexist = TRUE; X ttopen(); X} X Xdg10close() X X{ X#if COLOR X dg10fcol(7); X dg10bcol(0); X#endif X ttclose(); X} X Xdg10kopen() X X{ X} X Xdg10kclose() 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 Xdg10hello() X{ X} X#endif FRIDAY_NIGHT echo mes.2 completed! # That's all folks!