changeset 995:48c646212b1c

'microEMACS' for OS-9. Posted to USENET net.micro.6809, 4-May-86. Picked up from Google groups
author roug
date Sun, 23 Feb 2003 21:26:32 +0000
parents bef1844de0dc
children 4df2fdb9045f
files 3rdparty/packages/uemacs/README 3rdparty/packages/uemacs/ueansi.c 3rdparty/packages/uemacs/uebasic.c 3rdparty/packages/uemacs/uebuffer1.c 3rdparty/packages/uemacs/uebuffer2.c 3rdparty/packages/uemacs/uecoco.c 3rdparty/packages/uemacs/uedisplay.h 3rdparty/packages/uemacs/uedisplay1.c 3rdparty/packages/uemacs/uedisplay2.c 3rdparty/packages/uemacs/uedisplay3.c 3rdparty/packages/uemacs/ueed.h 3rdparty/packages/uemacs/uefile1.c 3rdparty/packages/uemacs/uefile2.c 3rdparty/packages/uemacs/uefileio.c 3rdparty/packages/uemacs/ueline1.c 3rdparty/packages/uemacs/ueline2.c 3rdparty/packages/uemacs/uemacs.doc 3rdparty/packages/uemacs/uemacs.hlp 3rdparty/packages/uemacs/uemacs.mak 3rdparty/packages/uemacs/uemain.h 3rdparty/packages/uemacs/uemain1.c 3rdparty/packages/uemacs/uemain2.c 3rdparty/packages/uemacs/uemain3.c 3rdparty/packages/uemacs/uemain4.c 3rdparty/packages/uemacs/uemaintable.c 3rdparty/packages/uemacs/uerandom1.c 3rdparty/packages/uemacs/uerandom2.c 3rdparty/packages/uemacs/ueregion.c 3rdparty/packages/uemacs/uesearch.c 3rdparty/packages/uemacs/uespawn.c 3rdparty/packages/uemacs/uetcap.c 3rdparty/packages/uemacs/uetermio.c 3rdparty/packages/uemacs/uevt52.c 3rdparty/packages/uemacs/uewindow.c 3rdparty/packages/uemacs/ueword.c
diffstat 35 files changed, 6244 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/3rdparty/packages/uemacs/README	Sun Feb 23 21:26:32 2003 +0000
@@ -0,0 +1,30 @@
+From: jimomura@lsuc.UUCP (Jim Omura)
+Newsgroups: net.micro.6809
+Subject: MicroEMACS OS-9 Part 1 of 7
+Message-ID: <1197@lsuc.UUCP>
+Date: Sun, 4-May-86 12:51:35 EDT
+Article-I.D.: lsuc.1197
+Posted: Sun May  4 12:51:35 1986
+Date-Received: Sun, 4-May-86 15:07:58 EDT
+Reply-To: jimomura@lsuc.UUCP (Jim Omura)
+Organization: Barrister & Solicitor, Toronto
+Lines: 414
+Summary:
+
+
+
+     These files are the best I could do to get 'microEMACS' for OS-9
+'here'.  This is the now legendary Bob Santy/Bob Larson port which time
+and luck have conspired to keep out of the hands of most OS-9'ers.
+As it is, it's being brought to you from Usenet, to my Color Computer,
+to BIX, to Bob Santy, to Bob Larson, to me, to BIX again, to my
+Spectravideo CP/M machine, to 'lsuc', to the net.  That's only part
+of the story and doesn't even go into the *days* I wasted just trying
+to upload it from my Color Computer to 'lsuc' and other fiascos.
+
+     Please, someone, use it.  That's make me feel much better about
+the whole mess.
+
+                                           Cheers! -- Jim Omura
+
+ 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/3rdparty/packages/uemacs/ueansi.c	Sun Feb 23 21:26:32 2003 +0000
@@ -0,0 +1,106 @@
+/*
+ * The routines in this file provide support for ANSI style terminals
+ * over a serial line. The serial I/O services are provided by routines in
+ * "termio.c". It compiles into nothing if not an ANSI device.
+ */
+
+#include        <stdio.h>
+#include        "ueed.h"
+
+#ifdef ANSI
+
+#define NROW    23                      /* Screen size.                 */
+#define NCOL    77                      /* Edit if you want to.         */
+#define BEL     0x07                    /* BEL character.               */
+#define ESC     0x1B                    /* ESC character.               */
+
+extern  int     ttopen();               /* Forward references.          */
+extern  int     ttgetc();
+extern  int     ttputc();
+extern  int     ttflush();
+extern  int     ttclose();
+extern  int     ansimove();
+extern  int     ansieeol();
+extern  int     ansieeop();
+extern  int     ansibeep();
+extern  int     ansiopen();
+
+/*
+ * Standard terminal interface dispatch table. Most of the fields point into
+ * "termio" code.
+ */
+TERM    term    = {
+        NROW-1,
+        NCOL,
+        ansiopen,
+        ttclose,
+        ttgetc,
+        ttputc,
+        ttflush,
+        ansimove,
+        ansieeol,
+        ansieeop,
+        ansibeep
+};
+
+ansimove(row, col)
+{
+        ttputc(ESC);
+        ttputc('[');
+        ansiparm(row+1);
+        ttputc(';');
+        ansiparm(col+1);
+        ttputc('H');
+}
+
+ansieeol()
+{
+        ttputc(ESC);
+        ttputc('[');
+        ttputc('K');
+}
+
+ansieeop()
+{
+        ttputc(ESC);
+        ttputc('[');
+        ttputc('J');
+}
+
+ansibeep()
+{
+        ttputc(BEL);
+        ttflush();
+}
+
+ansiparm(n)
+register int    n;
+{
+        register int    q;
+
+        q = n/10;
+        if (q != 0)
+                ansiparm(q);
+        ttputc((n%10) + '0');
+}
+
+#endif
+
+ansiopen()
+{
+#ifdef V7
+        register char *cp;
+        char *getenv();
+
+        if ((cp = getenv("TERM")) == NULL) {
+                puts("Shell variable TERM not defined!");
+                exit(1);
+        }
+        if (strcmp(cp, "vt100") != 0) {
+                puts("Terminal type not 'vt100'!");
+                exit(1);
+        }
+#endif
+        ttopen();
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/3rdparty/packages/uemacs/uebasic.c	Sun Feb 23 21:26:32 2003 +0000
@@ -0,0 +1,283 @@
+/*
+ * The routines in this file move the cursor around on the screen. They
+ * compute a new value for the cursor, then adjust ".". The display code
+ * always updates the cursor location, so only moves between lines, or
+ * functions that adjust the top line in the window and invalidate the
+ * framing, are hard.
+ */
+#include        <stdio.h>
+#include        "ueed.h"
+
+/*
+ * Move the cursor to the
+ * beginning of the current line.
+ * Trivial.
+ */
+gotobol(f, n)
+{
+        curwp->w_doto  = 0;
+        return (TRUE);
+}
+
+/*
+ * Move the cursor backwards by "n" characters. If "n" is less than zero call
+ * "forwchar" to actually do the move. Otherwise compute the new cursor
+ * location. Error if you try and move out of the buffer. Set the flag if the
+ * line pointer for dot changes.
+ */
+backchar(f, n)
+register int    n;
+{
+        register LINE   *lp;
+
+        if (n < 0)
+                return (forwchar(f, -n));
+        while (n--) {
+                if (curwp->w_doto == 0) {
+                        if ((lp=lback(curwp->w_dotp)) == curbp->b_linep)
+                                return (FALSE);
+                        curwp->w_dotp  = lp;
+                        curwp->w_doto  = llength(lp);
+                        curwp->w_flag |= WFMOVE;
+                } else
+                        curwp->w_doto--;
+        }
+        return (TRUE);
+}
+
+/*
+ * Move the cursor to the end of the current line. Trivial. No errors.
+ */
+gotoeol(f, n)
+{
+        curwp->w_doto  = llength(curwp->w_dotp);
+        return (TRUE);
+}
+
+/*
+ * Move the cursor forwwards by "n" characters. If "n" is less than zero call
+ * "backchar" to actually do the move. Otherwise compute the new cursor
+ * location, and move ".". Error if you try and move off the end of the
+ * buffer. Set the flag if the line pointer for dot changes.
+ */
+forwchar(f, n)
+register int    n;
+{
+        if (n < 0)
+                return (backchar(f, -n));
+        while (n--) {
+                if (curwp->w_doto == llength(curwp->w_dotp)) {
+                        if (curwp->w_dotp == curbp->b_linep)
+                                return (FALSE);
+                        curwp->w_dotp  = lforw(curwp->w_dotp);
+                        curwp->w_doto  = 0;
+                        curwp->w_flag |= WFMOVE;
+                } else
+                        curwp->w_doto++;
+        }
+        return (TRUE);
+}
+
+/*
+ * Goto the beginning of the buffer. Massive adjustment of dot. This is
+ * considered to be hard motion; it really isn't if the original value of dot
+ * is the same as the new value of dot. Normally bound to "M-<".
+ */
+gotobob(f, n)
+{
+        curwp->w_dotp  = lforw(curbp->b_linep);
+        curwp->w_doto  = 0;
+        curwp->w_flag |= WFHARD;
+        return (TRUE);
+}
+
+/*
+ * Move to the end of the buffer. Dot is always put at the end of the file
+ * (ZJ). The standard screen code does most of the hard parts of update.
+ * Bound to "M->".
+ */
+gotoeob(f, n)
+{
+        curwp->w_dotp  = curbp->b_linep;
+        curwp->w_doto  = 0;
+        curwp->w_flag |= WFHARD;
+        return (TRUE);
+}
+
+/*
+ * Move forward by full lines. If the number of lines to move is less than
+ * zero, call the backward line function to actually do it. The last command
+ * controls how the goal column is set. Bound to "C-N". No errors are
+ * possible.
+ */
+forwline(f, n)
+{
+        register LINE   *dlp;
+
+        if (n < 0)
+                return (backline(f, -n));
+        if ((lastflag&CFCPCN) == 0)             /* Reset goal if last   */
+                curgoal = curcol;               /* not C-P or C-N       */
+        thisflag |= CFCPCN;
+        dlp = curwp->w_dotp;
+        while (n-- && dlp!=curbp->b_linep)
+                dlp = lforw(dlp);
+        curwp->w_dotp  = dlp;
+        curwp->w_doto  = getgoal(dlp);
+        curwp->w_flag |= WFMOVE;
+        return (TRUE);
+}
+
+/*
+ * This function is like "forwline", but goes backwards. The scheme is exactly
+ * the same. Check for arguments that are less than zero and call your
+ * alternate. Figure out the new line and call "movedot" to perform the
+ * motion. No errors are possible. Bound to "C-P".
+ */
+backline(f, n)
+{
+        register LINE   *dlp;
+
+        if (n < 0)
+                return (forwline(f, -n));
+        if ((lastflag&CFCPCN) == 0)             /* Reset goal if the    */
+                curgoal = curcol;               /* last isn't C-P, C-N  */
+        thisflag |= CFCPCN;
+        dlp = curwp->w_dotp;
+        while (n-- && lback(dlp)!=curbp->b_linep)
+                dlp = lback(dlp);
+        curwp->w_dotp  = dlp;
+        curwp->w_doto  = getgoal(dlp);
+        curwp->w_flag |= WFMOVE;
+        return (TRUE);
+}
+
+/*
+ * This routine, given a pointer to a LINE, and the current cursor goal
+ * column, return the best choice for the offset. The offset is returned.
+ * Used by "C-N" and "C-P".
+ */
+getgoal(dlp)
+register LINE   *dlp;
+{
+        register int    c;
+        register int    col;
+        register int    newcol;
+        register int    dbo;
+
+        col = 0;
+        dbo = 0;
+        while (dbo != llength(dlp)) {
+                c = lgetc(dlp, dbo);
+                newcol = col;
+                if (c == '\t')
+                        newcol |= 0x07;
+                else if (c<0x20 || c==0x7F)
+                        ++newcol;
+                ++newcol;
+                if (newcol > curgoal)
+                        break;
+                col = newcol;
+                ++dbo;
+        }
+        return (dbo);
+}
+
+/*
+ * Scroll forward by a specified number of lines, or by a full page if no
+ * argument. Bound to "C-V". The "2" in the arithmetic on the window size is
+ * the overlap; this value is the default overlap value in ITS EMACS. Because
+ * this zaps the top line in the display window, we have to do a hard update.
+ */
+forwpage(f, n)
+register int    n;
+{
+        register LINE   *lp;
+
+        if (f == FALSE) {
+                n = curwp->w_ntrows - 2;        /* Default scroll.      */
+                if (n <= 0)                     /* Forget the overlap   */
+                        n = 1;                  /* if tiny window.      */
+        } else if (n < 0)
+                return (backpage(f, -n));
+#ifdef CVMVAS
+        else                                    /* Convert from pages   */
+                n *= curwp->w_ntrows;           /* to lines.            */
+#endif
+        lp = curwp->w_linep;
+        while (n-- && lp!=curbp->b_linep)
+                lp = lforw(lp);
+        curwp->w_linep = lp;
+        curwp->w_dotp  = lp;
+        curwp->w_doto  = 0;
+        curwp->w_flag |= WFHARD;
+        return (TRUE);
+}
+
+/*
+ * This command is like "forwpage", but it goes backwards. The "2", like
+ * above, is the overlap between the two windows. The value is from the ITS
+ * EMACS manual. Bound to "M-V". We do a hard update for exactly the same
+ * reason.
+ */
+backpage(f, n)
+register int    n;
+{
+        register LINE   *lp;
+
+        if (f == FALSE) {
+                n = curwp->w_ntrows - 2;        /* Default scroll.      */
+                if (n <= 0)                     /* Don't blow up if the */
+                        n = 1;                  /* window is tiny.      */
+        } else if (n < 0)
+                return (forwpage(f, -n));
+#ifdef CVMVAS
+        else                                    /* Convert from pages   */
+                n *= curwp->w_ntrows;           /* to lines.            */
+#endif
+        lp = curwp->w_linep;
+        while (n-- && lback(lp)!=curbp->b_linep)
+                lp = lback(lp);
+        curwp->w_linep = lp;
+        curwp->w_dotp  = lp;
+        curwp->w_doto  = 0;
+        curwp->w_flag |= WFHARD;
+        return (TRUE);
+}
+
+/*
+ * Set the mark in the current window to the value of "." in the window. No
+ * errors are possible. Bound to "M-.".
+ */
+setmark(f, n)
+{
+        curwp->w_markp = curwp->w_dotp;
+        curwp->w_marko = curwp->w_doto;
+        mlwrite("[Mark set]");
+        return (TRUE);
+}
+
+/*
+ * Swap the values of "." and "mark" in the current window. This is pretty
+ * easy, bacause all of the hard work gets done by the standard routine
+ * that moves the mark about. The only possible error is "no mark". Bound to
+ * "C-X C-X".
+ */
+swapmark(f, n)
+{
+        register LINE   *odotp;
+        register int    odoto;
+
+        if (curwp->w_markp == NULL) {
+                mlwrite("No mark in this window");
+                return (FALSE);
+        }
+        odotp = curwp->w_dotp;
+        odoto = curwp->w_doto;
+        curwp->w_dotp  = curwp->w_markp;
+        curwp->w_doto  = curwp->w_marko;
+        curwp->w_markp = odotp;
+        curwp->w_marko = odoto;
+        curwp->w_flag |= WFMOVE;
+        return (TRUE);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/3rdparty/packages/uemacs/uebuffer1.c	Sun Feb 23 21:26:32 2003 +0000
@@ -0,0 +1,219 @@
+/*
+ * Buffer management.
+ * Some of the functions are internal,
+ * and some are actually attached to user
+ * keys. Like everyone else, they set hints
+ * for the display system.
+ */
+#include        <stdio.h>
+#include        "ueed.h"
+
+#ifndef OS9
+/*
+ * Attach a buffer to a window. The
+ * values of dot and mark come from the buffer
+ * if the use count is 0. Otherwise, they come
+ * from some other window.
+ */
+usebuffer(f, n)
+{
+        register BUFFER *bp;
+        register WINDOW *wp;
+        register int    s;
+        char            bufn[NBUFN];
+
+        if ((s=mlreply("Use buffer: ", bufn, NBUFN)) != TRUE)
+                return (s);
+        if ((bp=bfind(bufn, TRUE, 0)) == NULL)
+                return (FALSE);
+        if (--curbp->b_nwnd == 0) {             /* Last use.            */
+                curbp->b_dotp  = curwp->w_dotp;
+                curbp->b_doto  = curwp->w_doto;
+                curbp->b_markp = curwp->w_markp;
+                curbp->b_marko = curwp->w_marko;
+        }
+        curbp = bp;                             /* Switch.              */
+        curwp->w_bufp  = bp;
+        curwp->w_linep = bp->b_linep;           /* For macros, ignored. */
+        curwp->w_flag |= WFMODE|WFFORCE|WFHARD; /* Quite nasty.         */
+        if (bp->b_nwnd++ == 0) {                /* First use.           */
+                curwp->w_dotp  = bp->b_dotp;
+                curwp->w_doto  = bp->b_doto;
+                curwp->w_markp = bp->b_markp;
+                curwp->w_marko = bp->b_marko;
+                return (TRUE);
+        }
+        wp = wheadp;                            /* Look for old.        */
+        while (wp != NULL) {
+                if (wp!=curwp && wp->w_bufp==bp) {
+                        curwp->w_dotp  = wp->w_dotp;
+                        curwp->w_doto  = wp->w_doto;
+                        curwp->w_markp = wp->w_markp;
+                        curwp->w_marko = wp->w_marko;
+                        break;
+                }
+                wp = wp->w_wndp;
+        }
+        return (TRUE);
+}
+
+/*
+ * Dispose of a buffer, by name.
+ * Ask for the name. Look it up (don't get too
+ * upset if it isn't there at all!). Get quite upset
+ * if the buffer is being displayed. Clear the buffer (ask
+ * if the buffer has been changed). Then free the header
+ * line and the buffer header. Bound to "C-X K".
+ */
+killbuffer(f, n)
+{
+        register BUFFER *bp;
+        register BUFFER *bp1;
+        register BUFFER *bp2;
+        register int    s;
+        char            bufn[NBUFN];
+
+        if ((s=mlreply("Kill buffer: ", bufn, NBUFN)) != TRUE)
+                return (s);
+        if ((bp=bfind(bufn, FALSE, 0)) == NULL) /* Easy if unknown.     */
+                return (TRUE);
+        if (bp->b_nwnd != 0) {                  /* Error if on screen.  */
+                mlwrite("Buffer is being displayed");
+                return (FALSE);
+        }
+        if ((s=bclear(bp)) != TRUE)             /* Blow text away.      */
+                return (s);
+        free((char *) bp->b_linep);             /* Release header line. */
+        bp1 = NULL;                             /* Find the header.     */
+        bp2 = bheadp;
+        while (bp2 != bp) {
+                bp1 = bp2;
+                bp2 = bp2->b_bufp;
+        }
+        bp2 = bp2->b_bufp;                      /* Next one in chain.   */
+        if (bp1 == NULL)                        /* Unlink it.           */
+                bheadp = bp2;
+        else
+                bp1->b_bufp = bp2;
+        free((char *) bp);                      /* Release buffer block */
+        return (TRUE);
+}
+
+/*
+ * List all of the active
+ * buffers. First update the special
+ * buffer that holds the list. Next make
+ * sure at least 1 window is displaying the
+ * buffer list, splitting the screen if this
+ * is what it takes. Lastly, repaint all of
+ * the windows that are displaying the
+ * list. Bound to "C-X C-B".
+ */
+listbuffers(f, n)
+{
+        register WINDOW *wp;
+        register BUFFER *bp;
+        register int    s;
+
+        if ((s=makelist()) != TRUE)
+                return (s);
+        if (blistp->b_nwnd == 0) {              /* Not on screen yet.   */
+                if ((wp=wpopup()) == NULL)
+                        return (FALSE);
+                bp = wp->w_bufp;
+                if (--bp->b_nwnd == 0) {
+                        bp->b_dotp  = wp->w_dotp;
+                        bp->b_doto  = wp->w_doto;
+                        bp->b_markp = wp->w_markp;
+                        bp->b_marko = wp->w_marko;
+                }
+                wp->w_bufp  = blistp;
+                ++blistp->b_nwnd;
+        }
+        wp = wheadp;
+        while (wp != NULL) {
+                if (wp->w_bufp == blistp) {
+                        wp->w_linep = lforw(blistp->b_linep);
+                        wp->w_dotp  = lforw(blistp->b_linep);
+                        wp->w_doto  = 0;
+                        wp->w_markp = NULL;
+                        wp->w_marko = 0;
+                        wp->w_flag |= WFMODE|WFHARD;
+                }
+                wp = wp->w_wndp;
+        }
+        return (TRUE);
+}
+
+/*
+ * This routine rebuilds the
+ * text in the special secret buffer
+ * that holds the buffer list. It is called
+ * by the list buffers command. Return TRUE
+ * if everything works. Return FALSE if there
+ * is an error (if there is no memory).
+ */
+makelist()
+{
+        register char   *cp1;
+        register char   *cp2;
+        register int    c;
+        register BUFFER *bp;
+        register LINE   *lp;
+        register int    nbytes;
+        register int    s;
+        register int    type;
+        char            b[6+1];
+        char            line[128];
+
+        blistp->b_flag &= ~BFCHG;               /* Don't complain!      */
+        if ((s=bclear(blistp)) != TRUE)         /* Blow old text away   */
+                return (s);
+        strcpy(blistp->b_fname, "");
+        if (addline("C   Size Buffer           File") == FALSE
+        ||  addline("-   ---- ------           ----") == FALSE)
+                return (FALSE);
+        bp = bheadp;                            /* For all buffers      */
+        while (bp != NULL) {
+                if ((bp->b_flag&BFTEMP) != 0) { /* Skip magic ones.     */
+                        bp = bp->b_bufp;
+                        continue;
+                }
+                cp1 = &line[0];                 /* Start at left edge   */
+                if ((bp->b_flag&BFCHG) != 0)    /* "*" if changed       */
+                        *cp1++ = '*';
+                else
+                        *cp1++ = ' ';
+                *cp1++ = ' ';                   /* Gap.                 */
+                nbytes = 0;                     /* Count bytes in buf.  */
+                lp = lforw(bp->b_linep);
+                while (lp != bp->b_linep) {
+                        nbytes += llength(lp)+1;
+                        lp = lforw(lp);
+                }
+                itoa(b, 6, nbytes);             /* 6 digit buffer size. */
+                cp2 = &b[0];
+                while ((c = *cp2++) != 0)
+                        *cp1++ = c;
+                *cp1++ = ' ';                   /* Gap.                 */
+                cp2 = &bp->b_bname[0];          /* Buffer name          */
+                while ((c = *cp2++) != 0)
+                        *cp1++ = c;
+                cp2 = &bp->b_fname[0];          /* File name            */
+                if (*cp2 != 0) {
+                        while (cp1 < &line[1+1+6+1+NBUFN+1])
+                                *cp1++ = ' ';           
+                        while ((c = *cp2++) != 0) {
+                                if (cp1 < &line[128-1])
+                                        *cp1++ = c;
+                        }
+                }
+                *cp1 = 0;                       /* Add to the buffer.   */
+                if (addline(line) == FALSE)
+                        return (FALSE);
+                bp = bp->b_bufp;
+        }
+        return (TRUE);                          /* All done             */
+}
+#endif
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/3rdparty/packages/uemacs/uebuffer2.c	Sun Feb 23 21:26:32 2003 +0000
@@ -0,0 +1,157 @@
+/*
+ * Buffer management.
+ * Some of the functions are internal,
+ * and some are actually attached to user
+ * keys. Like everyone else, they set hints
+ * for the display system.
+ */
+#include        <stdio.h>
+#include        "ueed.h"
+
+#ifndef OS9
+itoa(buf, width, num)
+register char   buf[];
+register int    width;
+register int    num;
+{
+        buf[width] = 0;                         /* End of string.       */
+        while (num >= 10) {                     /* Conditional digits.  */
+                buf[--width] = (num%10) + '0';
+                num /= 10;
+        }
+        buf[--width] = num + '0';               /* Always 1 digit.      */
+        while (width != 0)                      /* Pad with blanks.     */
+                buf[--width] = ' ';
+}
+
+/*
+ * The argument "text" points to
+ * a string. Append this line to the
+ * buffer list buffer. Handcraft the EOL
+ * on the end. Return TRUE if it worked and
+ * FALSE if you ran out of room.
+ */
+addline(text)
+char    *text;
+{
+        register LINE   *lp;
+        register int    i;
+        register int    ntext;
+
+        ntext = strlen(text);
+        if ((lp=lalloc(ntext)) == NULL)
+                return (FALSE);
+        for (i=0; i<ntext; ++i)
+                lputc(lp, i, text[i]);
+        blistp->b_linep->l_bp->l_fp = lp;       /* Hook onto the end    */
+        lp->l_bp = blistp->b_linep->l_bp;
+        blistp->b_linep->l_bp = lp;
+        lp->l_fp = blistp->b_linep;
+        if (blistp->b_dotp == blistp->b_linep)  /* If "." is at the end */
+                blistp->b_dotp = lp;            /* move it to new line  */
+        return (TRUE);
+}
+#endif
+
+/*
+ * Look through the list of
+ * buffers. Return TRUE if there
+ * are any changed buffers. Buffers
+ * that hold magic internal stuff are
+ * not considered; who cares if the
+ * list of buffer names is hacked.
+ * Return FALSE if no buffers
+ * have been changed.
+ */
+anycb()
+{
+        register BUFFER *bp;
+
+        bp = bheadp;
+        while (bp != NULL) {
+                if ((bp->b_flag&BFTEMP)==0 && (bp->b_flag&BFCHG)!=0)
+                        return (TRUE);
+                bp = bp->b_bufp;
+        }
+        return (FALSE);
+}
+
+/*
+ * Find a buffer, by name. Return a pointer
+ * to the BUFFER structure associated with it. If
+ * the named buffer is found, but is a TEMP buffer (like
+ * the buffer list) conplain. If the buffer is not found
+ * and the "cflag" is TRUE, create it. The "bflag" is
+ * the settings for the flags in in buffer.
+ */
+BUFFER *bfind(bname, cflag, bflag)
+register char *bname;
+{
+        register BUFFER *bp;
+        register LINE   *lp;
+
+        bp = bheadp;
+        while (bp != NULL) {
+                if (strcmp(bname, bp->b_bname) == 0) {
+                        if ((bp->b_flag&BFTEMP) != 0) {
+                                mlwrite("Cannot select builtin buffer");
+                                return (NULL);
+                        }
+                        return (bp);
+                }
+                bp = bp->b_bufp;
+        }
+        if (cflag != FALSE) {
+                if ((bp=(BUFFER *)malloc(sizeof(BUFFER))) == NULL)
+                        return (NULL);
+                if ((lp=lalloc(0)) == NULL) {
+                        free((char *) bp);
+                        return (NULL);
+                }
+                bp->b_bufp  = bheadp;
+                bheadp = bp;
+                bp->b_dotp  = lp;
+                bp->b_doto  = 
+                bp->b_markp = 
+                bp->b_marko = 
+                bp->b_nwnd  = 0;
+                bp->b_linep = lp;
+                bp->b_flag  = bflag;
+                strcpy(bp->b_fname, "");
+                strcpy(bp->b_bname, bname);
+                lp->l_fp = lp;
+                lp->l_bp = lp;
+        }
+        return (bp);
+}
+
+/*
+ * This routine blows away all of the text
+ * in a buffer. If the buffer is marked as changed
+ * then we ask if it is ok to blow it away; this is
+ * to save the user the grief of losing text. The
+ * window chain is nearly always wrong if this gets
+ * called; the caller must arrange for the updates
+ * that are required. Return TRUE if everything
+ * looks good.
+ */
+bclear(bp)
+register BUFFER *bp;
+{
+        register LINE   *lp;
+        register int    s;
+        
+        if ((bp->b_flag&BFTEMP) == 0            /* Not scratch buffer.  */
+        && (bp->b_flag&BFCHG) != 0              /* Something changed    */
+        && (s=mlyesno("Discard changes")) != TRUE)
+                return (s);
+        bp->b_flag  &= ~BFCHG;                  /* Not changed          */
+        while ((lp=lforw(bp->b_linep)) != bp->b_linep)
+                lfree(lp);
+        bp->b_dotp  = bp->b_linep;              /* Fix "."              */
+        bp->b_doto  = 
+        bp->b_markp =                      /* Invalidate "mark"    */
+        bp->b_marko = 0;
+        return (TRUE);
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/3rdparty/packages/uemacs/uecoco.c	Sun Feb 23 21:26:32 2003 +0000
@@ -0,0 +1,106 @@
+/*
+ * The routines in this file provide support for the COCO /TERM  terminal
+ * under OS9. The serial I/O services are provided by routines in
+ * "termio.c".
+ * Adapted 1/5/86 by:
+ * Bob Santy
+ * 5 Johnson Ave
+ * Medford, MA 02155
+ * (617) 488-7160
+ */
+
+#include        <stdio.h>
+#include        "ueed.h"
+
+/* Color Computer /TERM specifications        */
+#define NROW    16    /* Screen size.         */
+#define NCOL    32    /* Edit if you want to. */
+#define BEL     0x07  /* BEL character.       */
+#define ESC     0x1B  /* ESC character.       */
+#define CURSOR  0x02  /* Commands manual p126 */
+#define CEOL    0x04  /* 1.01 Supplement      */
+#define CEOS    0x0B  /* 1.01 Supplement      */
+
+extern  int     ttopen();               /* Forward references.          */
+extern  int     ttgetc();
+extern  int     ttputc();
+extern  int     ttflush();
+extern  int     ttclose();
+extern  int     cocomove();
+extern  int     cocoeeol();
+extern  int     cocoeeop();
+extern  int     cocobeep();
+extern  int     cocoopen();
+
+/*
+ * Standard terminal interface dispatch table. Most of the fields point into
+ * "termio" code.
+ */
+TERM    term    = {
+        NROW-1,
+        NCOL,
+        cocoopen,
+        ttclose,
+        ttgetc,
+        ttputc,
+        ttflush,
+        cocomove,
+        cocoeeol,
+        cocoeeop,
+        cocobeep
+};
+
+/*
+ * Cursor move command.
+ */
+cocomove(row, col)
+{
+        ttputc(CURSOR);
+        cocoparm(col);
+        cocoparm(row);
+}
+
+/*
+ * Clear to end of line.
+ */
+cocoeeol()
+{
+        ttputc(CEOL);
+}
+
+/*
+ * Clear to end of screen.
+ */
+cocoeeop()
+{
+        ttputc(CEOS);
+}
+
+/*
+ * Sound the horn (will work in
+ * OS9 Rev 2.00
+ */
+cocobeep()
+{
+        ttputc(BEL);
+        ttflush();
+}
+
+/*
+ * Cursor position needs 32 added to
+ * X and Y coordinates.
+ */
+cocoparm(n)
+register int    n;
+{
+        ttputc(n + 32);
+}
+
+/*
+ * Open terminal.  No special codes.
+ */
+cocoopen()
+{
+        ttopen();
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/3rdparty/packages/uemacs/uedisplay.h	Sun Feb 23 21:26:32 2003 +0000
@@ -0,0 +1,25 @@
+/* #define WFDEBUG 0                       /* Window flag debug. */
+
+typedef struct  VIDEO {
+        short   v_flag;                 /* Flags */
+        char    v_text[1];              /* Screen data. */
+}       VIDEO;
+
+#define VFCHG   0x0001                  /* Changed. */
+
+#ifdef DISPLAY1
+int     sgarbf  = TRUE;                 /* TRUE if screen is garbage */
+int     mpresf  = FALSE;                /* TRUE if message in last line */
+int     vtrow   = 0;                    /* Row location of SW cursor */
+int     vtcol   = 0;                    /* Column location of SW cursor */
+int     ttrow   = HUGE;                 /* Row location of HW cursor */
+int     ttcol   = HUGE;                 /* Column location of HW cursor */
+#else
+extern int     sgarbf;                 /* TRUE if screen is garbage */
+extern int     mpresf;                /* TRUE if message in last line */
+extern int     vtrow;                    /* Row location of SW cursor */
+extern int     vtcol;                    /* Column location of SW cursor */
+extern int     ttrow;                 /* Row location of HW cursor */
+extern int     ttcol;                 /* Column location of HW cursor */
+#endif
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/3rdparty/packages/uemacs/uedisplay1.c	Sun Feb 23 21:26:32 2003 +0000
@@ -0,0 +1,432 @@
+/*
+ * The functions in this file handle redisplay. There are two halves, the
+ * ones that update the virtual display screen, and the ones that make the
+ * physical display screen the same as the virtual display screen. These
+ * functions use hints that are left in the windows by the commands.
+ *
+ * REVISION HISTORY:
+ *
+ * ?    Steve Wilhite, 1-Dec-85
+ *      - massive cleanup on code.
+ */
+
+#include        <stdio.h>
+#include        "ueed.h"
+#define DISPLAY1 1
+#include        "uedisplay.h"
+
+VIDEO   **vscreen;                      /* Virtual screen. */
+VIDEO   **pscreen;                      /* Physical screen. */
+
+/*
+ * Initialize the data structures used by the display code. The edge vectors
+ * used to access the screens are set up. The operating system's terminal I/O
+ * channel is set up. All the other things get initialized at compile time.
+ * The original window has "WFCHG" set, so that it will get completely
+ * redrawn on the first call to "update".
+ */
+vtinit()
+{
+    register int i;
+    register VIDEO *vp;
+
+    (*term.t_open)();
+    vscreen = (VIDEO **) malloc(term.t_nrow*sizeof(VIDEO *));
+
+    if (vscreen == NULL)
+        exit(1);
+
+    pscreen = (VIDEO **) malloc(term.t_nrow*sizeof(VIDEO *));
+
+    if (pscreen == NULL)
+        exit(1);
+
+    for (i = 0; i < term.t_nrow; ++i)
+        {
+        vp = (VIDEO *) malloc(sizeof(VIDEO)+term.t_ncol);
+
+        if (vp == NULL)
+            exit(1);
+
+        vscreen[i] = vp;
+        vp = (VIDEO *) malloc(sizeof(VIDEO)+term.t_ncol);
+
+        if (vp == NULL)
+            exit(1);
+
+        pscreen[i] = vp;
+        }
+}
+
+/*
+ * Clean up the virtual terminal system, in anticipation for a return to the
+ * operating system. Move down to the last line and clear it out (the next
+ * system prompt will be written in the line). Shut down the channel to the
+ * terminal.
+ */
+vttidy()
+{
+    movecursor(term.t_nrow, 0);
+    (*term.t_eeol)();
+    (*term.t_close)();
+}
+
+/*
+ * Set the virtual cursor to the specified row and column on the virtual
+ * screen. There is no checking for nonsense values; this might be a good
+ * idea during the early stages.
+ */
+vtmove(row, col)
+{
+    vtrow = row;
+    vtcol = col;
+}
+
+/*
+ * Write a character to the virtual screen. The virtual row and column are
+ * updated. If the line is too long put a "$" in the last column. This routine
+ * only puts printing characters into the virtual terminal buffers. Only
+ * column overflow is checked.
+ */
+vtputc(c)
+    int c;
+
+{
+    register VIDEO      *vp;
+
+    vp = vscreen[vtrow];
+
+    if (vtcol >= term.t_ncol)
+        vp->v_text[term.t_ncol - 1] = '$';
+    else if (c == '\t')
+        {
+        do
+            {
+            vtputc(' ');
+            }
+        while ((vtcol&0x07) != 0);
+        }
+    else if (c < 0x20 || c == 0x7F)
+        {
+        vtputc('^');
+        vtputc(c ^ 0x40);
+        }
+    else
+        vp->v_text[vtcol++] = c;                
+}
+
+/*
+ * Erase from the end of the software cursor to the end of the line on which
+ * the software cursor is located.
+ */
+vteeol()
+{
+    register VIDEO      *vp;
+
+    vp = vscreen[vtrow];
+    while (vtcol < term.t_ncol)
+        vp->v_text[vtcol++] = ' ';
+}
+
+/*
+ * Make sure that the display is right. This is a three part process. First,
+ * scan through all of the windows looking for dirty ones. Check the framing,
+ * and refresh the screen. Second, make sure that "currow" and "curcol" are
+ * correct for the current window. Third, make the virtual and physical
+ * screens the same.
+ */
+update()
+{
+    register LINE *lp;
+    register WINDOW *wp;
+    register VIDEO *vp1;
+    register VIDEO *vp2;
+    register int i;
+    register int j;
+    register int c;
+
+    wp = wheadp;
+
+    while (wp != NULL)
+        {
+        /* Look at any window with update flags set on. */
+
+        if (wp->w_flag != 0)
+            {
+            /* If not force reframe, check the framing. */
+
+            if ((wp->w_flag & WFFORCE) == 0)
+                {
+                lp = wp->w_linep;
+
+                for (i = 0; i < wp->w_ntrows; ++i)
+                    {
+                    if (lp == wp->w_dotp)
+                        goto out;
+
+                    if (lp == wp->w_bufp->b_linep)
+                        break;
+
+                    lp = lforw(lp);
+                    }
+                }
+
+            /* Not acceptable, better compute a new value for the line at the
+             * top of the window. Then set the "WFHARD" flag to force full
+             * redraw.
+             */
+            i = wp->w_force;
+
+            if (i > 0)
+                {
+                --i;
+
+                if (i >= wp->w_ntrows)
+                  i = wp->w_ntrows-1;
+                }
+            else if (i < 0)
+                {
+                i += wp->w_ntrows;
+
+                if (i < 0)
+                    i = 0;
+                }
+            else
+                i = wp->w_ntrows/2;
+
+            lp = wp->w_dotp;
+
+            while (i != 0 && lback(lp) != wp->w_bufp->b_linep)
+                {
+                --i;
+                lp = lback(lp);
+                }
+
+            wp->w_linep = lp;
+            wp->w_flag |= WFHARD;       /* Force full. */
+
+out:
+            /* Try to use reduced update. Mode line update has its own special
+             * flag. The fast update is used if the only thing to do is within
+             * the line editing.
+             */
+            lp = wp->w_linep;
+            i = wp->w_toprow;
+
+            if ((wp->w_flag & ~WFMODE) == WFEDIT)
+                {
+                while (lp != wp->w_dotp)
+                    {
+                    ++i;
+                    lp = lforw(lp);
+                    }
+
+                vscreen[i]->v_flag |= VFCHG;
+                vtmove(i, 0);
+
+                for (j = 0; j < llength(lp); ++j)
+                    vtputc(lgetc(lp, j));
+
+                vteeol();
+                }
+             else if ((wp->w_flag & (WFEDIT | WFHARD)) != 0)
+                {
+                while (i < wp->w_toprow+wp->w_ntrows)
+                    {
+                    vscreen[i]->v_flag |= VFCHG;
+                    vtmove(i, 0);
+
+                    if (lp != wp->w_bufp->b_linep)
+                        {
+                        for (j = 0; j < llength(lp); ++j)
+                            vtputc(lgetc(lp, j));
+
+                        lp = lforw(lp);
+                        }
+
+                    vteeol();
+                    ++i;
+                    }
+                }
+#ifndef WFDEBUG
+            if ((wp->w_flag&WFMODE) != 0)
+                modeline(wp);
+
+            wp->w_flag  = 
+            wp->w_force = 0;
+#endif
+            }           
+#ifdef WFDEBUG
+        modeline(wp);
+        wp->w_flag =  
+        wp->w_force = 0;
+#endif
+        wp = wp->w_wndp;
+        }
+
+    /* Always recompute the row and column number of the hardware cursor. This
+     * is the only update for simple moves.
+     */
+    lp = curwp->w_linep;
+    currow = curwp->w_toprow;
+
+    while (lp != curwp->w_dotp)
+        {
+        ++currow;
+        lp = lforw(lp);
+        }
+
+    curcol = 
+    i = 0;
+
+    while (i < curwp->w_doto)
+        {
+        c = lgetc(lp, i++);
+
+        if (c == '\t')
+            curcol |= 0x07;
+        else if (c < 0x20 || c == 0x7F)
+            ++curcol;
+
+        ++curcol;
+        }
+
+    if (curcol >= term.t_ncol)          /* Long line. */
+        curcol = term.t_ncol-1;
+
+    /* Special hacking if the screen is garbage. Clear the hardware screen,
+     * and update your copy to agree with it. Set all the virtual screen
+     * change bits, to force a full update.
+     */
+    if (sgarbf != FALSE)
+        {
+        for (i = 0; i < term.t_nrow; ++i)
+            {
+            vscreen[i]->v_flag |= VFCHG;
+            vp1 = pscreen[i];
+            for (j = 0; j < term.t_ncol; ++j)
+                vp1->v_text[j] = ' ';
+            }
+
+        movecursor(0, 0);               /* Erase the screen. */
+        (*term.t_eeop)();
+        sgarbf = FALSE;                 /* Erase-page clears */
+        mpresf = FALSE;                 /* the message area. */
+        }
+
+    /* Make sure that the physical and virtual displays agree. Unlike before,
+     * the "updateline" code is only called with a line that has been updated
+     * for sure.
+     */
+    for (i = 0; i < term.t_nrow; ++i)
+        {
+        vp1 = vscreen[i];
+
+        if ((vp1->v_flag&VFCHG) != 0)
+            {
+            vp1->v_flag &= ~VFCHG;
+            vp2 = pscreen[i];
+            updateline(i, &vp1->v_text[0], &vp2->v_text[0]);
+            }
+        }
+
+    /* Finally, update the hardware cursor and flush out buffers. */
+
+    movecursor(currow, curcol);
+    (*term.t_flush)();
+}
+
+/*
+ * Update a single line. This does not know how to use insert or delete
+ * character sequences; we are using VT52 functionality. Update the physical
+ * row and column variables. It does try an exploit erase to end of line. The
+ * RAINBOW version of this routine uses fast video.
+ */
+updateline(row, vline, pline)
+    char vline[];
+    char pline[];
+{
+#ifdef RAINBOW
+    register char *cp1;
+    register char *cp2;
+    register int nch;
+
+    cp1 = &vline[0];                    /* Use fast video. */
+    cp2 = &pline[0];
+    putline(row+1, 1, cp1);
+    nch = term.t_ncol;
+
+    do
+        {
+        *cp2 = *cp1;
+        ++cp2;
+        ++cp1;
+        }
+    while (--nch);
+#else
+    register char *cp1;
+    register char *cp2;
+    register char *cp3;
+    register char *cp4;
+    register char *cp5;
+    register int nbflag;
+
+    cp1 = &vline[0];                    /* Compute left match.  */
+    cp2 = &pline[0];
+
+    while (cp1!=&vline[term.t_ncol] && cp1[0]==cp2[0])
+        {
+        ++cp1;
+        ++cp2;
+        }
+
+    /* This can still happen, even though we only call this routine on changed
+     * lines. A hard update is always done when a line splits, a massive
+     * change is done, or a buffer is displayed twice. This optimizes out most
+     * of the excess updating. A lot of computes are used, but these tend to
+     * be hard operations that do a lot of update, so I don't really care.
+     */
+    if (cp1 == &vline[term.t_ncol])             /* All equal. */
+        return;
+
+    nbflag = FALSE;
+    cp3 = &vline[term.t_ncol];          /* Compute right match. */
+    cp4 = &pline[term.t_ncol];
+
+    while (cp3[-1] == cp4[-1])
+        {
+        --cp3;
+        --cp4;
+        if (cp3[0] != ' ')              /* Note if any nonblank */
+            nbflag = TRUE;              /* in right match. */
+        }
+
+    cp5 = cp3;
+
+    if (nbflag == FALSE)                /* Erase to EOL ? */
+        {
+        while (cp5!=cp1 && cp5[-1]==' ')
+            --cp5;
+
+        if (cp3-cp5 <= 3)               /* Use only if erase is */
+            cp5 = cp3;                  /* fewer characters. */
+        }
+
+    movecursor(row, cp1-&vline[0]);     /* Go to start of line. */
+
+    while (cp1 != cp5)                  /* Ordinary. */
+        {
+        (*term.t_putchar)(*cp1);
+        ++ttcol;
+        *cp2++ = *cp1++;
+        }
+
+    if (cp5 != cp3)                     /* Erase. */
+        {
+        (*term.t_eeol)();
+        while (cp1 != cp3)
+            *cp2++ = *cp1++;
+        }
+#endif
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/3rdparty/packages/uemacs/uedisplay2.c	Sun Feb 23 21:26:32 2003 +0000
@@ -0,0 +1,297 @@
+/*
+ * The functions in this file handle redisplay. There are two halves, the
+ * ones that update the virtual display screen, and the ones that make the
+ * physical display screen the same as the virtual display screen. These
+ * functions use hints that are left in the windows by the commands.
+ *
+ * REVISION HISTORY:
+ *
+ * ?    Steve Wilhite, 1-Dec-85
+ *      - massive cleanup on code.
+ */
+
+#include        <stdio.h>
+#include        "ueed.h"
+#include        "uedisplay.h"
+
+extern VIDEO   **vscreen;                      /* Virtual screen. */
+
+/*
+ * Redisplay the mode line for the window pointed to by the "wp". This is the
+ * only routine that has any idea of how the modeline is formatted. You can
+ * change the modeline format by hacking at this routine. Called by "update"
+ * any time there is a dirty window.
+ */
+modeline(wp)
+    WINDOW *wp;
+{
+    register char *cp;
+    register int c;
+    register int n;
+    register BUFFER *bp;
+
+    n = wp->w_toprow+wp->w_ntrows;              /* Location. */
+    vscreen[n]->v_flag |= VFCHG;                /* Redraw next time. */
+    vtmove(n, 0);                               /* Seek to right line. */
+    vtputc('-');
+    bp = wp->w_bufp;
+
+    if ((bp->b_flag&BFCHG) != 0)                /* "*" if changed. */
+        vtputc('*');
+    else
+        vtputc('-');
+
+    n  = 2;
+    cp = " MicroEMACS -";                     /* Buffer name. */
+
+    while ((c = *cp++) != 0)
+        {
+        vtputc(c);
+        ++n;
+        }
+
+#ifndef OS9
+    cp = &bp->b_bname[0];
+
+    while ((c = *cp++) != 0)
+        {
+        vtputc(c);
+        ++n;
+        }
+
+    vtputc(' ');
+    ++n;
+#endif
+
+    if (bp->b_fname[0] != 0)            /* File name. */
+        {
+        cp = " File: ";
+
+        while ((c = *cp++) != 0)
+            {
+            vtputc(c);
+            ++n;
+            }
+
+        cp = &bp->b_fname[0];
+
+        while ((c = *cp++) != 0)
+            {
+            vtputc(c);
+            ++n;
+            }
+
+        vtputc(' ');
+        ++n;
+        }
+
+#ifdef WFDEBUG
+    vtputc('-');
+    vtputc((wp->w_flag&WFMODE)!=0  ? 'M' : '-');
+    vtputc((wp->w_flag&WFHARD)!=0  ? 'H' : '-');
+    vtputc((wp->w_flag&WFEDIT)!=0  ? 'E' : '-');
+    vtputc((wp->w_flag&WFMOVE)!=0  ? 'V' : '-');
+    vtputc((wp->w_flag&WFFORCE)!=0 ? 'F' : '-');
+    n += 6;
+#endif
+
+    while (n < term.t_ncol)             /* Pad to full width. */
+        {
+        vtputc('-');
+        ++n;
+        }
+}
+
+/*
+ * Send a command to the terminal to move the hardware cursor to row "row"
+ * and column "col". The row and column arguments are origin 0. Optimize out
+ * random calls. Update "ttrow" and "ttcol".
+ */
+movecursor(row, col)
+    {
+    if (row!=ttrow || col!=ttcol)
+        {
+        ttrow = row;
+        ttcol = col;
+        (*term.t_move)(row, col);
+        }
+    }
+
+/*
+ * Erase the message line. This is a special routine because the message line
+ * is not considered to be part of the virtual screen. It always works
+ * immediately; the terminal buffer is flushed via a call to the flusher.
+ */
+mlerase()
+    {
+    movecursor(term.t_nrow, 0);
+    (*term.t_eeol)();
+    (*term.t_flush)();
+    mpresf = FALSE;
+    }
+
+/*
+ * Ask a yes or no question in the message line. Return either TRUE, FALSE, or
+ * ABORT. The ABORT status is returned if the user bumps out of the question
+ * with a ^G. Used any time a confirmation is required.
+ */
+mlyesno(prompt)
+    char *prompt;
+    {
+    register int s;
+    char buf[64];
+
+    for (;;)
+        {
+        strcpy(buf, prompt);
+        strcat(buf, " [y/n]? ");
+        s = mlreply(buf, buf, sizeof(buf));
+
+        if (s == ABORT)
+            return (ABORT);
+
+        if (s != FALSE)
+            {
+            if (buf[0]=='y' || buf[0]=='Y')
+                return (TRUE);
+
+            if (buf[0]=='n' || buf[0]=='N')
+                return (FALSE);
+            }
+        }
+    }
+
+/*
+ * Write a prompt into the message line, then read back a response. Keep
+ * track of the physical position of the cursor. If we are in a keyboard
+ * macro throw the prompt away, and return the remembered response. This
+ * lets macros run at full speed. The reply is always terminated by a carriage
+ * return. Handle erase, kill, and abort keys.
+ */
+mlreply(prompt, buf, nbuf)
+    char *prompt;
+    char *buf;
+    {
+    register int cpos;
+    register int i;
+    register int c;
+
+    cpos = 0;
+
+    if (kbdmop != NULL)
+        {
+        while ((c = *kbdmop++) != '\0')
+            buf[cpos++] = c;
+
+        buf[cpos] = 0;
+
+        if (buf[0] == 0)
+            return (FALSE);
+
+        return (TRUE);
+        }
+
+    mlwrite(prompt);
+
+    for (;;)
+        {
+        c = (*term.t_getchar)();
+
+        switch (c)
+            {
+            case 0x0D:                  /* Return, end of line */
+                buf[cpos++] = 0;
+
+                if (kbdmip != NULL)
+                    {
+                    if (kbdmip+cpos > &kbdm[NKBDM-3])
+                        {
+                        ctrlg(FALSE, 0);
+                        (*term.t_flush)();
+                        return (ABORT);
+                        }
+
+                    for (i=0; i<cpos; ++i)
+                        *kbdmip++ = buf[i];
+                    }
+
+                (*term.t_putchar)('\r');
+                ttcol = 0;
+                (*term.t_flush)();
+
+                if (buf[0] == 0)
+                    return (FALSE);
+
+                return (TRUE);
+
+            case 0x07:                  /* Bell, abort */
+                (*term.t_putchar)('^');
+                (*term.t_putchar)('G');
+                ttcol += 2;
+                ctrlg(FALSE, 0);
+                (*term.t_flush)();
+                return (ABORT);
+
+            case 0x7F:                  /* Rubout, erase */
+            case 0x08:                  /* Backspace, erase */
+                if (cpos != 0)
+                    {
+                    (*term.t_putchar)('\b');
+                    (*term.t_putchar)(' ');
+                    (*term.t_putchar)('\b');
+                    --ttcol;
+
+                    if (buf[--cpos] < 0x20)
+                        {
+                        (*term.t_putchar)('\b');
+                        (*term.t_putchar)(' ');
+                        (*term.t_putchar)('\b');
+                        --ttcol;
+                        }
+
+                    (*term.t_flush)();
+                    }
+
+                break;
+
+            case 0x15:                  /* C-U, kill */
+                while (cpos != 0)
+                    {
+                    (*term.t_putchar)('\b');
+                    (*term.t_putchar)(' ');
+                    (*term.t_putchar)('\b');
+                    --ttcol;
+
+                    if (buf[--cpos] < 0x20)
+                        {
+                        (*term.t_putchar)('\b');
+                        (*term.t_putchar)(' ');
+                        (*term.t_putchar)('\b');
+                        --ttcol;
+                        }
+                    }
+
+                (*term.t_flush)();
+                break;
+
+            default:
+                if (cpos < nbuf-1)
+                    {
+                    buf[cpos++] = c;
+
+                    if (c < ' ')
+                        {
+                        (*term.t_putchar)('^');
+                        ++ttcol;
+                        c ^= 0x40;
+                        }
+
+                    (*term.t_putchar)(c);
+                    ++ttcol;
+                    (*term.t_flush)();
+                    }
+            }
+        }
+    }
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/3rdparty/packages/uemacs/uedisplay3.c	Sun Feb 23 21:26:32 2003 +0000
@@ -0,0 +1,160 @@
+/*
+ * The functions in this file handle redisplay. There are two halves, the
+ * ones that update the virtual display screen, and the ones that make the
+ * physical display screen the same as the virtual display screen. These
+ * functions use hints that are left in the windows by the commands.
+ *
+ * REVISION HISTORY:
+ *
+ * ?    Steve Wilhite, 1-Dec-85
+ *      - massive cleanup on code.
+ */
+
+#include        <stdio.h>
+#include        "ueed.h"
+#include        "uedisplay.h"
+
+/*
+ * Write a message into the message line. Keep track of the physical cursor
+ * position. A small class of printf like format items is handled. 
+ * This routine is probably one of the lease portable.
+ * Assumes all arguments (with the possible exception of the first) are passed
+ * in the order expected on a downward growing stack without addtional
+ * padding; this assumption is made by the "++" in the 
+ * argument scan loop.  It works for the two or less argument case
+ * on OSK despite the fact the first two arguments are passed in registers.
+ * Set the "message line" flag TRUE.
+ */
+mlwrite(fmt, arg)
+    char *fmt;
+    {
+    register int c;
+    register char *ap;
+
+    movecursor(term.t_nrow, 0);
+    ap = (char *) &arg;
+    while ((c = *fmt++) != 0) {
+        if (c != '%') {
+            (*term.t_putchar)(c);
+            ++ttcol;
+            }
+        else
+            {
+            c = *fmt++;
+            switch (c) {
+                case 'd':
+                    mlputi(*(int *)ap, 10);
+                    ap += sizeof(int);
+                    break;
+
+                case 'o':
+                    mlputi(*(int *)ap,  8);
+                    ap += sizeof(int);
+                    break;
+
+                case 'x':
+                    mlputi(*(int *)ap, 16);
+                    ap += sizeof(int);
+                    break;
+
+                case 'D':  /* this is %ld on many printf impleminations */
+                    mlputli(*(long *)ap, 10);
+                    ap += sizeof(long);
+                    break;
+
+                case 's':
+                    mlputs(*(char **)ap);
+                    ap += sizeof(char *);
+                    break;
+
+                default:
+                    (*term.t_putchar)(c);
+                    ++ttcol;
+                }
+            }
+        }
+    (*term.t_eeol)();
+    (*term.t_flush)();
+    mpresf = TRUE;
+    }
+
+/*
+ * Write out a string. Update the physical cursor position. This assumes that
+ * the characters in the string all have width "1"; if this is not the case
+ * things will get screwed up a little.
+ */
+mlputs(s)
+    char *s;
+    {
+    register int c;
+
+    while ((c = *s++) != 0)
+        {
+        (*term.t_putchar)(c);
+        ++ttcol;
+        }
+    }
+
+/*
+ * Write out an integer, in the specified radix. Update the physical cursor
+ * position. This will not handle any negative numbers; maybe it should.
+ */
+mlputi(i, r)
+    {
+    register int q;
+    static char hexdigits[] = "0123456789ABCDEF";
+
+    if (i < 0)
+        {
+        i = -i;
+        (*term.t_putchar)('-');
+        }
+
+    q = i/r;
+
+    if (q != 0)
+        mlputi(q, r);
+
+    (*term.t_putchar)(hexdigits[i%r]);
+    ++ttcol;
+    }
+
+/*
+ * do the same except as a long integer.
+ */
+mlputli(l, r)
+    long l;
+    {
+    register long q;
+
+    if (l < 0)
+        {
+        l = -l;
+        (*term.t_putchar)('-');
+        }
+
+    q = l/r;
+
+    if (q != 0)
+        mlputli(q, r);
+
+    (*term.t_putchar)((int)(l%r)+'0');
+    ++ttcol;
+    }
+
+#ifdef RAINBOW
+
+putline(row, col, buf)
+    int row, col;
+    char buf[];
+    {
+    int n;
+
+    n = strlen(buf);
+    if (col + n - 1 > term.t_ncol)
+        n = term.t_ncol - col + 1;
+    Put_Data(row, col, n, buf);
+    }
+#endif
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/3rdparty/packages/uemacs/ueed.h	Sun Feb 23 21:26:32 2003 +0000
@@ -0,0 +1,189 @@
+/*
+ * This file is the general header file for all parts of the MicroEMACS
+ * display editor. It contains definitions used by everyone, and it contains
+ * the stuff you have to edit to create a version of the editor for a specific
+ * operating system and terminal.
+ */
+
+/* #define AMIGA   1                       /* AmigaDOS, Lattice            */
+/* #define ST520   0                       /* ST520, TOS                   */
+/* #define MWC86   0
+/* #define V7      0                       /* V7 UN*X or Coherent          */
+/* #define VMS     0                       /* VAX/VMS                      */
+/* #define CPM     0                       /* CP/M-86                      */
+#define OS9     1                       /* os9/6809 level 1 (coco)      */
+/* #define OSK     1                       /* os9/68000 predefined         */
+/* #define MSDOS   0                       /* MS-DOS predefined            */
+
+/* #define ANSI    1                       /* ANSI terminal (Vt100)        */
+/* #define VT52    1                       /* VT52 terminal (Zenith).      */
+/* #define VT100   0                       /* Handle VT100 style keypad.   */
+/* #define LK201   0                       /* Handle LK201 style keypad.   */
+/* #define RAINBOW 0                       /* Use Rainbow fast video.      */
+/* #define TERMCAP 0                       /* Use TERMCAP                  */
+
+#define CVMVAS  1                       /* C-V, M-V arg. in screens.    */
+
+#define NFILEN  80                      /* # of bytes, file name        */
+#define NBUFN   16                      /* # of bytes, buffer name      */
+#define NLINE   256                     /* # of bytes, line             */
+#define NKBDM   256                     /* # of strokes, keyboard macro */
+#define NPAT    80                      /* # of bytes, pattern          */
+#define HUGE    1000                    /* Huge number                  */
+
+#define AGRAVE  0x60                    /* M- prefix,   Grave (LK201)   */
+#define METACH  0x1B                    /* M- prefix,   Control-[, ESC  */
+#define CTMECH  0x1C                    /* C-M- prefix, Control-\       */
+#define EXITCH  0x1D                    /* Exit level,  Control-]       */
+#define CTRLCH  0x1E                    /* C- prefix,   Control-^       */
+#define HELPCH  0x1F                    /* Help key,    Control-_       */
+
+#define CTRL    0x0100                  /* Control flag, or'ed in       */
+#define META    0x0200                  /* Meta flag, or'ed in          */
+#define CTLX    0x0400                  /* ^X flag, or'ed in            */
+
+#define FALSE   0                       /* False, no, bad, etc.         */
+#define TRUE    1                       /* True, yes, good, etc.        */
+#define ABORT   2                       /* Death, ^G, abort, etc.       */
+
+#define FIOSUC  0                       /* File I/O, success.           */
+#define FIOFNF  1                       /* File I/O, file not found.    */
+#define FIOEOF  2                       /* File I/O, end of file.       */
+#define FIOERR  3                       /* File I/O, error.             */
+
+#define CFCPCN  0x0001                  /* Last command was C-P, C-N    */
+#define CFKILL  0x0002                  /* Last command was a kill      */
+
+/*
+ * There is a window structure allocated for every active display window. The
+ * windows are kept in a big list, in top to bottom screen order, with the
+ * listhead at "wheadp". Each window contains its own values of dot and mark.
+ * The flag field contains some bits that are set by commands to guide
+ * redisplay; although this is a bit of a compromise in terms of decoupling,
+ * the full blown redisplay is just too expensive to run for every input
+ * character. 
+ */
+typedef struct  WINDOW {
+        struct  WINDOW *w_wndp;         /* Next window                  */
+        struct  BUFFER *w_bufp;         /* Buffer displayed in window   */
+        struct  LINE *w_linep;          /* Top line in the window       */
+        struct  LINE *w_dotp;           /* Line containing "."          */
+        short   w_doto;                 /* Byte offset for "."          */
+        struct  LINE *w_markp;          /* Line containing "mark"       */
+        short   w_marko;                /* Byte offset for "mark"       */
+        char    w_toprow;               /* Origin 0 top row of window   */
+        char    w_ntrows;               /* # of rows of text in window  */
+        char    w_force;                /* If NZ, forcing row.          */
+        char    w_flag;                 /* Flags.                       */
+}       WINDOW;
+
+#define WFFORCE 0x01                    /* Window needs forced reframe  */
+#define WFMOVE  0x02                    /* Movement from line to line   */
+#define WFEDIT  0x04                    /* Editing within a line        */
+#define WFHARD  0x08                    /* Better to a full display     */
+#define WFMODE  0x10                    /* Update mode line.            */
+
+/*
+ * Text is kept in buffers. A buffer header, described below, exists for every
+ * buffer in the system. The buffers are kept in a big list, so that commands
+ * that search for a buffer by name can find the buffer header. There is a
+ * safe store for the dot and mark in the header, but this is only valid if
+ * the buffer is not being displayed (that is, if "b_nwnd" is 0). The text for
+ * the buffer is kept in a circularly linked list of lines, with a pointer to
+ * the header line in "b_linep".
+ */
+typedef struct  BUFFER {
+        struct  BUFFER *b_bufp;         /* Link to next BUFFER          */
+        struct  LINE *b_dotp;           /* Link to "." LINE structure   */
+        short   b_doto;                 /* Offset of "." in above LINE  */
+        struct  LINE *b_markp;          /* The same as the above two,   */
+        short   b_marko;                /* but for the "mark"           */
+        struct  LINE *b_linep;          /* Link to the header LINE      */
+        char    b_nwnd;                 /* Count of windows on buffer   */
+        char    b_flag;                 /* Flags                        */
+        char    b_fname[NFILEN];        /* File name                    */
+        char    b_bname[NBUFN];         /* Buffer name                  */
+}       BUFFER;
+
+#define BFTEMP  0x01                    /* Internal temporary buffer    */
+#define BFCHG   0x02                    /* Changed since last write     */
+
+/*
+ * The starting position of a region, and the size of the region in
+ * characters, is kept in a region structure.  Used by the region commands.
+ */
+typedef struct  {
+        struct  LINE *r_linep;          /* Origin LINE address.         */
+        short   r_offset;               /* Origin LINE offset.          */
+        short   r_size;                 /* Length in characters.        */
+}       REGION;
+
+/*
+ * All text is kept in circularly linked lists of "LINE" structures. These
+ * begin at the header line (which is the blank line beyond the end of the
+ * buffer). This line is pointed to by the "BUFFER". Each line contains a the
+ * number of bytes in the line (the "used" size), the size of the text array,
+ * and the text. The end of line is not stored as a byte; it's implied. Future
+ * additions will include update hints, and a list of marks into the line.
+ */
+typedef struct  LINE {
+        struct  LINE *l_fp;             /* Link to the next line        */
+        struct  LINE *l_bp;             /* Link to the previous line    */
+        short   l_size;                 /* Allocated size               */
+        short   l_used;                 /* Used size                    */
+        char    l_text[1];              /* A bunch of characters.       */
+}       LINE;
+
+#define lforw(lp)       ((lp)->l_fp)
+#define lback(lp)       ((lp)->l_bp)
+#define lgetc(lp, n)    ((lp)->l_text[(n)]&0xFF)
+#define lputc(lp, n, c) ((lp)->l_text[(n)]=(c))
+#define llength(lp)     ((lp)->l_used)
+
+/*
+ * The editor communicates with the display using a high level interface. A
+ * "TERM" structure holds useful variables, and indirect pointers to routines
+ * that do useful operations. The low level get and put routines are here too.
+ * This lets a terminal, in addition to having non standard commands, have
+ * funny get and put character code too. The calls might get changed to
+ * "termp->t_field" style in the future, to make it possible to run more than
+ * one terminal type.
+ */  
+typedef struct  {
+        short   t_nrow;                 /* Number of rows.              */
+        short   t_ncol;                 /* Number of columns.           */
+        int     (*t_open)();            /* Open terminal at the start.  */
+        int     (*t_close)();           /* Close terminal at end.       */
+        int     (*t_getchar)();         /* Get character from keyboard. */
+        int     (*t_putchar)();         /* Put character to display.    */
+        int     (*t_flush)();           /* Flush output buffers.        */
+        int     (*t_move)();            /* Move the cursor, origin 0.   */
+        int     (*t_eeol)();            /* Erase to end of line.        */
+        int     (*t_eeop)();            /* Erase to end of page.        */
+        int     (*t_beep)();            /* Beep.                        */
+}       TERM;
+
+extern  int     fillcol;                /* Fill column                  */
+extern  int     currow;                 /* Cursor row                   */
+extern  int     curcol;                 /* Cursor column                */
+extern  int     thisflag;               /* Flags, this command          */
+extern  int     lastflag;               /* Flags, last command          */
+extern  int     curgoal;                /* Goal for C-P, C-N            */
+extern  int     mpresf;                 /* Stuff in message line        */
+extern  int     sgarbf;                 /* State of screen unknown      */
+extern  WINDOW  *curwp;                 /* Current window               */
+extern  BUFFER  *curbp;                 /* Current buffer               */
+extern  WINDOW  *wheadp;                /* Head of list of windows      */
+extern  BUFFER  *bheadp;                /* Head of list of buffers      */
+extern  BUFFER  *blistp;                /* Buffer for C-X C-B           */
+extern  short   kbdm[];                 /* Holds kayboard macro data    */
+extern  short   *kbdmip;                /* Input pointer for above      */
+extern  short   *kbdmop;                /* Output pointer for above     */
+extern  char    pat[];                  /* Search pattern               */
+extern  TERM    term;                   /*(Terminal information.        */
+
+extern  BUFFER  *bfind();               /* Lookup a buffer by name      */
+extern  WINDOW  *wpopup();              /* Pop up window creation       */
+extern  LINE    *lalloc();              /* Allocate a line              */
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/3rdparty/packages/uemacs/uefile1.c	Sun Feb 23 21:26:32 2003 +0000
@@ -0,0 +1,264 @@
+/*
+ * The routines in this file
+ * handle the reading and writing of
+ * disk files. All of details about the
+ * reading and writing of the disk are
+ * in "fileio.c".
+ */
+#include        <stdio.h>
+#include        "ueed.h"
+
+/*
+ * Read a file into the current
+ * buffer. This is really easy; all you do it
+ * find the name of the file, and call the standard
+ * "read a file into the current buffer" code.
+ * Bound to "C-X C-R".
+ */
+fileread(f, n)
+{
+        register int    s;
+        char            fname[NFILEN];
+
+        if ((s=mlreply("Read file: ", fname, NFILEN)) != TRUE)
+                return (s);
+        return (readin(fname));
+}
+
+#ifndef OS9
+/*
+ * Select a file for editing.
+ * Look around to see if you can find the
+ * fine in another buffer; if you can find it
+ * just switch to the buffer. If you cannot find
+ * the file, create a new buffer, read in the
+ * text, and switch to the new buffer.
+ * Bound to C-X C-V.
+ */
+filevisit(f, n)
+{
+        register BUFFER *bp;
+        register WINDOW *wp;
+        register LINE   *lp;
+        register int    i;
+        register int    s;
+        char            bname[NBUFN];
+        char            fname[NFILEN];
+
+        if ((s=mlreply("Visit file: ", fname, NFILEN)) != TRUE)
+                return (s);
+        for (bp=bheadp; bp!=NULL; bp=bp->b_bufp) {
+                if ((bp->b_flag&BFTEMP)==0 && strcmp(bp->b_fname, fname)==0) {
+                        if (--curbp->b_nwnd == 0) {
+                                curbp->b_dotp  = curwp->w_dotp;
+                                curbp->b_doto  = curwp->w_doto;
+                                curbp->b_markp = curwp->w_markp;
+                                curbp->b_marko = curwp->w_marko;
+                        }
+                        curbp = bp;
+                        curwp->w_bufp  = bp;
+                        if (bp->b_nwnd++ == 0) {
+                                curwp->w_dotp  = bp->b_dotp;
+                                curwp->w_doto  = bp->b_doto;
+                                curwp->w_markp = bp->b_markp;
+                                curwp->w_marko = bp->b_marko;
+                        } else {
+                                wp = wheadp;
+                                while (wp != NULL) {
+                                        if (wp!=curwp && wp->w_bufp==bp) {
+                                                curwp->w_dotp  = wp->w_dotp;
+                                                curwp->w_doto  = wp->w_doto;
+                                                curwp->w_markp = wp->w_markp;
+                                                curwp->w_marko = wp->w_marko;
+                                                break;
+                                        }
+                                        wp = wp->w_wndp;
+                                }
+                        }
+                        lp = curwp->w_dotp;
+                        i = curwp->w_ntrows/2;
+                        while (i-- && lback(lp)!=curbp->b_linep)
+                                lp = lback(lp);
+                        curwp->w_linep = lp;
+                        curwp->w_flag |= WFMODE|WFHARD;
+                        mlwrite("[Old buffer]");
+                        return (TRUE);
+                }
+        }
+        makename(bname, fname);                 /* New buffer name.     */
+        while ((bp=bfind(bname, FALSE, 0)) != NULL) {
+                s = mlreply("Buffer name: ", bname, NBUFN);
+                if (s == ABORT)                 /* ^G to just quit      */
+                        return (s);
+                if (s == FALSE) {               /* CR to clobber it     */
+                        makename(bname, fname);
+                        break;
+                }
+        }
+        if (bp==NULL && (bp=bfind(bname, TRUE, 0))==NULL) {
+                mlwrite("Cannot create buffer");
+                return (FALSE);
+        }
+        if (--curbp->b_nwnd == 0) {             /* Undisplay.           */
+                curbp->b_dotp = curwp->w_dotp;
+                curbp->b_doto = curwp->w_doto;
+                curbp->b_markp = curwp->w_markp;
+                curbp->b_marko = curwp->w_marko;
+        }
+        curbp = bp;                             /* Switch to it.        */
+        curwp->w_bufp = bp;
+        curbp->b_nwnd++;
+        return (readin(fname));                 /* Read it in.          */
+}
+#endif
+
+/*
+ * Read file "fname" into the current
+ * buffer, blowing away any text found there. Called
+ * by both the read and visit commands. Return the final
+ * status of the read. Also called by the mainline,
+ * to read in a file specified on the command line as
+ * an argument.
+ */
+readin(fname)
+char    fname[];
+{
+        register LINE   *lp1;
+        register LINE   *lp2;
+        register int    i;
+        register WINDOW *wp;
+        register BUFFER *bp;
+        register int    s;
+        register int    nbytes;
+        register int    nline;
+        char            line[NLINE];
+
+        bp = curbp;                             /* Cheap.               */
+        if ((s=bclear(bp)) != TRUE)             /* Might be old.        */
+                return (s);
+        bp->b_flag &= ~(BFTEMP|BFCHG);
+        strcpy(bp->b_fname, fname);
+        if ((s=ffropen(fname)) == FIOERR)       /* Hard file open.      */
+                goto out;
+        if (s == FIOFNF) {                      /* File not found.      */
+                mlwrite("[New file]");
+                goto out;
+        }
+        mlwrite("[Reading file]");
+        nline = 0;
+        while ((s=ffgetline(line, NLINE)) == FIOSUC) {
+                nbytes = strlen(line);
+                if ((lp1=lalloc(nbytes)) == NULL) {
+                        s = FIOERR;             /* Keep message on the  */
+                        break;                  /* display.             */
+                }
+                lp2 = lback(curbp->b_linep);
+                lp2->l_fp = lp1;
+                lp1->l_fp = curbp->b_linep;
+                lp1->l_bp = lp2;
+                curbp->b_linep->l_bp = lp1;
+                for (i=0; i<nbytes; ++i)
+                        lputc(lp1, i, line[i]);
+                ++nline;
+        }
+        ffclose();                              /* Ignore errors.       */
+        if (s == FIOEOF) {                      /* Don't zap message!   */
+                if (nline == 1)
+                        mlwrite("[Read 1 line]");
+                else
+                        mlwrite("[Read %d lines]", nline);
+        }
+out:
+        for (wp=wheadp; wp!=NULL; wp=wp->w_wndp) {
+                if (wp->w_bufp == curbp) {
+                        wp->w_linep = lforw(curbp->b_linep);
+                        wp->w_dotp  = lforw(curbp->b_linep);
+                        wp->w_doto  = 
+                        wp->w_markp = 
+                        wp->w_marko = 0;
+                        wp->w_flag |= WFMODE|WFHARD;
+                }
+        }
+        if (s == FIOERR)                        /* False if error.      */
+                return (FALSE);
+        return (TRUE);
+}
+
+/*
+ * Take a file name, and from it
+ * fabricate a buffer name. This routine knows
+ * about the syntax of file names on the target system.
+ * I suppose that this information could be put in
+ * a better place than a line of code.
+ */
+makename(bname, fname)
+char    bname[];
+char    fname[];
+{
+        register char   *cp1;
+        register char   *cp2;
+
+        cp1 = &fname[0];
+        while (*cp1 != 0)
+                ++cp1;
+
+#ifdef AMIGA
+        while (cp1!=&fname[0] && cp1[-1]!=':' && cp1[-1]!='/')
+                --cp1;
+#endif
+#ifdef VMS
+        while (cp1!=&fname[0] && cp1[-1]!=':' && cp1[-1]!=']')
+                --cp1;
+#endif
+#ifdef CPM
+        while (cp1!=&fname[0] && cp1[-1]!=':')
+                --cp1;
+#endif
+#ifdef MSDOS
+        while (cp1!=&fname[0] && cp1[-1]!=':' && cp1[-1]!='\\')
+                --cp1;
+#endif
+#ifdef V7
+        while (cp1!=&fname[0] && cp1[-1]!='/')
+                --cp1;
+#endif
+#ifdef OSK
+        while (cp1!=&fname[0] && cp1[-1]!='/')
+                --cp1;
+#endif
+        cp2 = &bname[0];
+        while (cp2!=&bname[NBUFN-1] && *cp1!=0 && *cp1!=';')
+                *cp2++ = *cp1++;
+        *cp2 = 0;
+}
+
+/*
+ * Ask for a file name, and write the
+ * contents of the current buffer to that file.
+ * Update the remembered file name and clear the
+ * buffer changed flag. This handling of file names
+ * is different from the earlier versions, and
+ * is more compatable with Gosling EMACS than
+ * with ITS EMACS. Bound to "C-X C-W".
+ */
+filewrite(f, n)
+{
+        register WINDOW *wp;
+        register int    s;
+        char            fname[NFILEN];
+
+        if ((s=mlreply("Write file: ", fname, NFILEN)) != TRUE)
+                return (s);
+        if ((s=writeout(fname)) == TRUE) {
+                strcpy(curbp->b_fname, fname);
+                curbp->b_flag &= ~BFCHG;
+                wp = wheadp;                    /* Update mode lines.   */
+                while (wp != NULL) {
+                        if (wp->w_bufp == curbp)
+                                wp->w_flag |= WFMODE;
+                        wp = wp->w_wndp;
+                }
+        }
+        return (s);
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/3rdparty/packages/uemacs/uefile2.c	Sun Feb 23 21:26:32 2003 +0000
@@ -0,0 +1,112 @@
+/*
+ * The routines in this file
+ * handle the reading and writing of
+ * disk files. All of details about the
+ * reading and writing of the disk are
+ * in "fileio.c".
+ */
+#include        <stdio.h>
+#include        "ueed.h"
+
+/*
+ * Save the contents of the current
+ * buffer in its associatd file. No nothing
+ * if nothing has changed (this may be a bug, not a
+ * feature). Error if there is no remembered file
+ * name for the buffer. Bound to "C-X C-S". May
+ * get called by "C-Z".
+ */
+filesave(f, n)
+{
+        register WINDOW *wp;
+        register int    s;
+
+        if ((curbp->b_flag&BFCHG) == 0)         /* Return, no changes.  */
+                return (TRUE);
+        if (curbp->b_fname[0] == 0) {           /* Must have a name.    */
+                mlwrite("No file name");
+                return (FALSE);
+        }
+        if ((s=writeout(curbp->b_fname)) == TRUE) {
+                curbp->b_flag &= ~BFCHG;
+                wp = wheadp;                    /* Update mode lines.   */
+                while (wp != NULL) {
+                        if (wp->w_bufp == curbp)
+                                wp->w_flag |= WFMODE;
+                        wp = wp->w_wndp;
+                }
+        }
+        return (s);
+}
+
+/*
+ * This function performs the details of file
+ * writing. Uses the file management routines in the
+ * "fileio.c" package. The number of lines written is
+ * displayed. Sadly, it looks inside a LINE; provide
+ * a macro for this. Most of the grief is error
+ * checking of some sort.
+ */
+writeout(fn)
+char    *fn;
+{
+        register int    s;
+        register LINE   *lp;
+        register int    nline;
+
+        if ((s=ffwopen(fn)) != FIOSUC)          /* Open writes message. */
+                return (FALSE);
+        lp = lforw(curbp->b_linep);             /* First line.          */
+        nline = 0;                              /* Number of lines.     */
+        while (lp != curbp->b_linep) {
+                if ((s=ffputline(&lp->l_text[0], llength(lp))) != FIOSUC)
+                        break;
+                ++nline;
+                lp = lforw(lp);
+        }
+        if (s == FIOSUC) {                      /* No write error.      */
+                s = ffclose();
+                if (s == FIOSUC) {              /* No close error.      */
+                        if (nline == 1)
+                                mlwrite("[Wrote 1 line]");
+                        else
+                                mlwrite("[Wrote %d lines]", nline);
+                }
+        } else                                  /* Ignore close error   */
+                ffclose();                      /* if a write error.    */
+        if (s != FIOSUC)                        /* Some sort of error.  */
+                return (FALSE);
+        return (TRUE);
+}
+
+/*
+ * The command allows the user
+ * to modify the file name associated with
+ * the current buffer. It is like the "f" command
+ * in UNIX "ed". The operation is simple; just zap
+ * the name in the BUFFER structure, and mark the windows
+ * as needing an update. You can type a blank line at the
+ * prompt if you wish.
+ */
+filename(f, n)
+{
+        register WINDOW *wp;
+        register int    s;
+        char            fname[NFILEN];
+
+        if ((s=mlreply("Name: ", fname, NFILEN)) == ABORT)
+                return (s);
+        if (s == FALSE)
+                strcpy(curbp->b_fname, "");
+        else
+                strcpy(curbp->b_fname, fname);
+        wp = wheadp;                            /* Update mode lines.   */
+        while (wp != NULL) {
+                if (wp->w_bufp == curbp)
+                        wp->w_flag |= WFMODE;
+                wp = wp->w_wndp;
+        }
+        return (TRUE);
+}
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/3rdparty/packages/uemacs/uefileio.c	Sun Feb 23 21:26:32 2003 +0000
@@ -0,0 +1,120 @@
+/*
+ * The routines in this file read and write ASCII files from the disk. All of
+ * the knowledge about files are here. A better message writing scheme should
+ * be used.
+ */
+#include        <stdio.h>
+#include        "ueed.h"
+
+FILE    *ffp;                           /* File pointer, all functions. */
+
+/*
+ * Open a file for reading.
+ */
+ffropen(fn)
+char    *fn;
+{
+        if ((ffp=fopen(fn, "r")) == NULL)
+                return (FIOFNF);
+        return (FIOSUC);
+}
+
+/*
+ * Open a file for writing. Return TRUE if all is well, and FALSE on error
+ * (cannot create).
+ */
+ffwopen(fn)
+char    *fn;
+{
+#ifdef VMS
+        register int    fd;
+
+        if ((fd=creat(fn, 0666, "rfm=var", "rat=cr")) < 0
+        || (ffp=fdopen(fd, "w")) == NULL) {
+#else
+        if ((ffp=fopen(fn, "w")) == NULL) {
+#endif
+                mlwrite("Cannot open file for writing");
+                return (FIOERR);
+        }
+        return (FIOSUC);
+}
+
+/*
+ * Close a file. Should look at the status in all systems.
+ */
+ffclose()
+{
+#ifdef V7
+        if (fclose(ffp) != FALSE) {
+                mlwrite("Error closing file");
+                return(FIOERR);
+        }
+        return(FIOSUC);
+#endif
+        fclose(ffp);
+        return (FIOSUC);
+}
+
+/*
+ * Write a line to the already opened file. The "buf" points to the buffer,
+ * and the "nbuf" is its length, less the free newline. Return the status.
+ * Check only at the newline.
+ */
+ffputline(buf, nbuf)
+char    buf[];
+{
+        register int    i;
+        for (i = 0; i < nbuf; ++i)
+                putc(buf[i]&0xFF, ffp);
+
+        putc('\n', ffp);
+
+        if (ferror(ffp)) {
+                mlwrite("Write I/O error");
+                return (FIOERR);
+        }
+
+        return (FIOSUC);
+}
+
+/*
+ * Read a line from a file, and store the bytes in the supplied buffer. The
+ * "nbuf" is the length of the buffer. Complain about long lines and lines
+ * at the end of the file that don't have a newline present. Check for I/O
+ * errors too. Return status.
+ */
+ffgetline(buf, nbuf)
+register char   buf[];
+{
+        register int    c;
+        register int    i;
+
+        i = 0;
+
+        while ((c = fgetc(ffp)) != EOF && c != '\n') {
+                if (i >= nbuf-1) {
+                        mlwrite("File has long line");
+                        return (FIOERR);
+                }
+                buf[i++] = c;
+        }
+
+        if (c == EOF) {
+                if (ferror(ffp)) {
+                        mlwrite("File read error");
+                        return (FIOERR);
+                }
+
+                if (i != 0) {
+                        mlwrite("File has funny line at EOF");
+                        return (FIOERR);
+                }
+                return (FIOEOF);
+        }
+
+        buf[i] = 0;
+        return (FIOSUC);
+}
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/3rdparty/packages/uemacs/ueline1.c	Sun Feb 23 21:26:32 2003 +0000
@@ -0,0 +1,201 @@
+/*
+ * The functions in this file are a general set of line management utilities.
+ * They are the only routines that touch the text. They also touch the buffer
+ * and window structures, to make sure that the necessary updating gets done.
+ * There are routines in this file that handle the kill buffer too. It isn't
+ * here for any good reason.
+ *
+ * Note that this code only updates the dot and mark values in the window list.
+ * Since all the code acts on the current window, the buffer that we are
+ * editing must be being displayed, which means that "b_nwnd" is non zero,
+ * which means that the dot and mark values in the buffer headers are nonsense.
+ */
+
+#include        <stdio.h>
+#include        "ueed.h"
+
+#define NBLOCK  16                      /* Line block chunk size        */
+#define KBLOCK  256                     /* Kill buffer block size       */
+
+char    *kbufp  = NULL;                 /* Kill buffer data             */
+int     kused   = 0;                    /* # of bytes used in KB        */
+int     ksize   = 0;                    /* # of bytes allocated in KB   */
+
+/*
+ * This routine allocates a block of memory large enough to hold a LINE
+ * containing "used" characters. The block is always rounded up a bit. Return
+ * a pointer to the new block, or NULL if there isn't any memory left. Print a
+ * message in the message line if no space.
+ */
+LINE    *lalloc(used)
+register int    used;
+{
+        register LINE   *lp;
+        register int    size;
+
+        size = (used+NBLOCK-1) & ~(NBLOCK-1);
+        if (size == 0)                          /* Assume that an empty */
+                size = NBLOCK;                  /* line is for type-in. */
+        if ((lp = (LINE *) malloc(sizeof(LINE)+size)) == NULL) {
+                mlwrite("Cannot allocate %d bytes", size);
+                return (NULL);
+        }
+        lp->l_size = size;
+        lp->l_used = used;
+        return (lp);
+}
+
+/*
+ * Delete line "lp". Fix all of the links that might point at it (they are
+ * moved to offset 0 of the next line. Unlink the line from whatever buffer it
+ * might be in. Release the memory. The buffers are updated too; the magic
+ * conditions described in the above comments don't hold here.
+ */
+lfree(lp)
+register LINE   *lp;
+{
+        register BUFFER *bp;
+        register WINDOW *wp;
+
+        wp = wheadp;
+        while (wp != NULL) {
+                if (wp->w_linep == lp)
+                        wp->w_linep = lp->l_fp;
+                if (wp->w_dotp  == lp) {
+                        wp->w_dotp  = lp->l_fp;
+                        wp->w_doto  = 0;
+                }
+                if (wp->w_markp == lp) {
+                        wp->w_markp = lp->l_fp;
+                        wp->w_marko = 0;
+                }
+                wp = wp->w_wndp;
+        }
+        bp = bheadp;
+        while (bp != NULL) {
+                if (bp->b_nwnd == 0) {
+                        if (bp->b_dotp  == lp) {
+                                bp->b_dotp = lp->l_fp;
+                                bp->b_doto = 0;
+                        }
+                        if (bp->b_markp == lp) {
+                                bp->b_markp = lp->l_fp;
+                                bp->b_marko = 0;
+                        }
+                }
+                bp = bp->b_bufp;
+        }
+        lp->l_bp->l_fp = lp->l_fp;
+        lp->l_fp->l_bp = lp->l_bp;
+        free((char *) lp);
+}
+
+/*
+ * This routine gets called when a character is changed in place in the current
+ * buffer. It updates all of the required flags in the buffer and window
+ * system. The flag used is passed as an argument; if the buffer is being
+ * displayed in more than 1 window we change EDIT t HARD. Set MODE if the
+ * mode line needs to be updated (the "*" has to be set).
+ */
+lchange(flag)
+register int    flag;
+{
+        register WINDOW *wp;
+        if (curbp->b_nwnd != 1)                 /* Ensure hard.         */
+                flag = WFHARD;
+        if ((curbp->b_flag&BFCHG) == 0) {       /* First change, so     */
+                flag |= WFMODE;                 /* update mode lines.   */
+                curbp->b_flag |= BFCHG;
+        }
+        wp = wheadp;
+        while (wp != NULL) {
+                if (wp->w_bufp == curbp)
+                        wp->w_flag |= flag;
+                wp = wp->w_wndp;
+        }
+}
+
+/*
+ * Insert "n" copies of the character "c" at the current location of dot. In
+ * the easy case all that happens is the text is stored in the line. In the
+ * hard case, the line has to be reallocated. When the window list is updated,
+ * take special care; I screwed it up once. You always update dot in the
+ * current window. You update mark, and a dot in another window, if it is
+ * greater than the place where you did the insert. Return TRUE if all is
+ * well, and FALSE on errors.
+ */
+linsert(n, c)
+{
+        register char   *cp1;
+        register char   *cp2;
+        register LINE   *lp1;
+        register LINE   *lp2;
+        register LINE   *lp3;
+        register int    doto;
+        register int    i;
+        register WINDOW *wp;
+
+        lchange(WFEDIT);
+        lp1 = curwp->w_dotp;                    /* Current line         */
+        if (lp1 == curbp->b_linep) {            /* At the end: special  */
+                if (curwp->w_doto != 0) {
+                        mlwrite("bug: linsert");
+                        return (FALSE);
+                }
+                if ((lp2=lalloc(n)) == NULL)    /* Allocate new line    */
+                        return (FALSE);
+                lp3 = lp1->l_bp;                /* Previous line        */
+                lp3->l_fp = lp2;                /* Link in              */
+                lp2->l_fp = lp1;
+                lp1->l_bp = lp2;
+                lp2->l_bp = lp3;
+                for (i=0; i<n; ++i)
+                        lp2->l_text[i] = c;
+                curwp->w_dotp = lp2;
+                curwp->w_doto = n;
+                return (TRUE);
+        }
+        doto = curwp->w_doto;                   /* Save for later.      */
+        if (lp1->l_used+n > lp1->l_size) {      /* Hard: reallocate     */
+                if ((lp2=lalloc(lp1->l_used+n)) == NULL)
+                        return (FALSE);
+                cp1 = &lp1->l_text[0];
+                cp2 = &lp2->l_text[0];
+                while (cp1 != &lp1->l_text[doto])
+                        *cp2++ = *cp1++;
+                cp2 += n;
+                while (cp1 != &lp1->l_text[lp1->l_used])
+                        *cp2++ = *cp1++;
+                lp1->l_bp->l_fp = lp2;
+                lp2->l_fp = lp1->l_fp;
+                lp1->l_fp->l_bp = lp2;
+                lp2->l_bp = lp1->l_bp;
+                free((char *) lp1);
+        } else {                                /* Easy: in place       */
+                lp2 = lp1;                      /* Pretend new line     */
+                lp2->l_used += n;
+                cp2 = &lp1->l_text[lp1->l_used];
+                cp1 = cp2-n;
+                while (cp1 != &lp1->l_text[doto])
+                        *--cp2 = *--cp1;
+        }
+        for (i=0; i<n; ++i)                     /* Add the characters   */
+                lp2->l_text[doto+i] = c;
+        wp = wheadp;                            /* Update windows       */
+        while (wp != NULL) {
+                if (wp->w_linep == lp1)
+                        wp->w_linep = lp2;
+                if (wp->w_dotp == lp1) {
+                        wp->w_dotp = lp2;
+                        if (wp==curwp || wp->w_doto>doto)
+                                wp->w_doto += n;
+                }
+                if (wp->w_markp == lp1) {
+                        wp->w_markp = lp2;
+                        if (wp->w_marko > doto)
+                                wp->w_marko += n;
+                }
+                wp = wp->w_wndp;
+        }
+        return (TRUE);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/3rdparty/packages/uemacs/ueline2.c	Sun Feb 23 21:26:32 2003 +0000
@@ -0,0 +1,284 @@
+/*
+ * The functions in this file are a general set of line management utilities.
+ * They are the only routines that touch the text. They also touch the buffer
+ * and window structures, to make sure that the necessary updating gets done.
+ * There are routines in this file that handle the kill buffer too. It i
+sn't
+ * here for any good reason.
+ *
+ * Note that this code only updates the dot and mark values in the window list.
+ * Since all the code acts on the current window, the buffer that we are
+ * editing must be being displayed, which means that "b_nwnd" is non zero,
+ * which means that the dot and mark values in the buffer headers are nonsense.
+ */
+
+#include        <stdio.h>
+#include        "ueed.h"
+
+#define NBLOCK  16                      /* Line block chunk size        */
+#define KBLOCK  256                     /* Kill buffer block size       */
+
+extern char    *kbufp;                 /* Kill buffer data             */
+extern int     kused;                    /* # of bytes used in KB        */
+extern int     ksize;                    /* # of bytes allocated in KB   */
+
+/*
+ * Insert a newline into the buffer at the current location of dot in the
+ * current window. The funny ass-backwards way it does things is not a botch;
+ * it just makes the last line in the file not a special case. Return TRUE if
+ * everything works out and FALSE on error (memory allocation failure). The
+ * update of dot and mark is a bit easier then in the above case, because the
+ * split forces more updating.
+ */
+lnewline()
+{
+        register char   *cp1;
+        register char   *cp2;
+        register LINE   *lp1;
+        register LINE   *lp2;
+        register int    doto;
+        register WINDOW *wp;
+
+        lchange(WFHARD);
+        lp1  = curwp->w_dotp;                   /* Get the address and  */
+        doto = curwp->w_doto;                   /* offset of "."        */
+        if ((lp2=lalloc(doto)) == NULL)         /* New first half line  */
+                return (FALSE);
+        cp1 = &lp1->l_text[0];                  /* Shuffle text around  */
+        cp2 = &lp2->l_text[0];
+        while (cp1 != &lp1->l_text[doto])
+                *cp2++ = *cp1++;
+        cp2 = &lp1->l_text[0];
+        while (cp1 != &lp1->l_text[lp1->l_used])
+                *cp2++ = *cp1++;
+        lp1->l_used -= doto;
+        lp2->l_bp = lp1->l_bp;
+        lp1->l_bp = lp2;
+        lp2->l_bp->l_fp = lp2;
+        lp2->l_fp = lp1;
+        wp = wheadp;                            /* Windows              */
+        while (wp != NULL) {
+                if (wp->w_linep == lp1)
+                        wp->w_linep = lp2;
+                if (wp->w_dotp == lp1) {
+                        if (wp->w_doto < doto)
+                                wp->w_dotp = lp2;
+                        else
+                                wp->w_doto -= doto;
+                }
+                if (wp->w_markp == lp1) {
+                        if (wp->w_marko < doto)
+                                wp->w_markp = lp2;
+                        else
+                                wp->w_marko -= doto;
+                }
+                wp = wp->w_wndp;
+        }       
+        return (TRUE);
+}
+
+/*
+ * This function deletes "n" bytes, starting at dot. It understands how do deal
+ * with end of lines, etc. It returns TRUE if all of the characters were
+ * deleted, and FALSE if they were not (because dot ran into the end of the
+ * buffer. The "kflag" is TRUE if the text should be put in the kill buffer.
+ */
+ldelete(n, kflag)
+{
+        register char   *cp1;
+        register char   *cp2;
+        register LINE   *dotp;
+        register int    doto;
+        register int    chunk;
+        register WINDOW *wp;
+
+        while (n != 0) {
+                dotp = curwp->w_dotp;
+                doto = curwp->w_doto;
+                if (dotp == curbp->b_linep)     /* Hit end of buffer.   */
+                        return (FALSE);
+                chunk = dotp->l_used-doto;      /* Size of chunk.       */
+                if (chunk > n)
+                        chunk = n;
+                if (chunk == 0) {               /* End of line, merge.  */
+                        lchange(WFHARD);
+                        if (ldelnewline() == FALSE
+                        || (kflag!=FALSE && kinsert('\n')==FALSE))
+                                return (FALSE);
+                        --n;
+                        continue;
+                }
+                lchange(WFEDIT);
+                cp1 = &dotp->l_text[doto];      /* Scrunch text.        */
+                cp2 = cp1 + chunk;
+                if (kflag != FALSE) {           /* Kill?                */
+                        while (cp1 != cp2) {
+                                if (kinsert(*cp1) == FALSE)
+                                        return (FALSE);
+                                ++cp1;
+                        }
+                        cp1 = &dotp->l_text[doto];
+                }
+                while (cp2 != &dotp->l_text[dotp->l_used])
+                        *cp1++ = *cp2++;
+                dotp->l_used -= chunk;
+                wp = wheadp;                    /* Fix windows          */
+                while (wp != NULL) {
+                        if (wp->w_dotp==dotp && wp->w_doto>=doto) {
+                                wp->w_doto -= chunk;
+                                if (wp->w_doto < doto)
+                                        wp->w_doto = doto;
+                        }       
+                        if (wp->w_markp==dotp && wp->w_marko>=doto) {
+                                wp->w_marko -= chunk;
+                                if (wp->w_marko < doto)
+                                        wp->w_marko = doto;
+                        }
+                        wp = wp->w_wndp;
+                }
+                n -= chunk;
+        }
+        return (TRUE);
+}
+
+/*
+ * Delete a newline. Join the current line with the next line. If the next line
+ * is the magic header line always return TRUE; merging the last line with the
+ * header line can be thought of as always being a successful operation, even
+ * if nothing is done, and this makes the kill buffer work "right". Easy cases
+ * can be done by shuffling data around. Hard cases require that lines be moved
+ * about in memory. Return FALSE on error and TRUE if all looks ok. Called by
+ * "ldelete" only.
+ */
+ldelnewline()
+{
+        register char   *cp1;
+        register char   *cp2;
+        register LINE   *lp1;
+        register LINE   *lp2;
+        register LINE   *lp3;
+        register WINDOW *wp;
+
+        lp1 = curwp->w_dotp;
+        lp2 = lp1->l_fp;
+        if (lp2 == curbp->b_linep) {            /* At the buffer end.   */
+                if (lp1->l_used == 0)           /* Blank line.          */
+                        lfree(lp1);
+                return (TRUE);
+        }
+        if (lp2->l_used <= lp1->l_size-lp1->l_used) {
+                cp1 = &lp1->l_text[lp1->l_used];
+                cp2 = &lp2->l_text[0];
+                while (cp2 != &lp2->l_text[lp2->l_used])
+                        *cp1++ = *cp2++;
+                wp = wheadp;
+                while (wp != NULL) {
+                        if (wp->w_linep == lp2)
+                                wp->w_linep = lp1;
+                        if (wp->w_dotp == lp2) {
+                                wp->w_dotp  = lp1;
+                                wp->w_doto += lp1->l_used;
+                        }
+                        if (wp->w_markp == lp2) {
+                                wp->w_markp  = lp1;
+                                wp->w_marko += lp1->l_used;
+                        }
+                        wp = wp->w_wndp;
+                }               
+                lp1->l_used += lp2->l_used;
+                lp1->l_fp = lp2->l_fp;
+                lp2->l_fp->l_bp = lp1;
+                free((char *) lp2);
+                return (TRUE);
+        }
+        if ((lp3=lalloc(lp1->l_used+lp2->l_used)) == NULL)
+                return (FALSE);
+        cp1 = &lp1->l_text[0];
+        cp2 = &lp3->l_text[0];
+        while (cp1 != &lp1->l_text[lp1->l_used])
+                *cp2++ = *cp1++;
+        cp1 = &lp2->l_text[0];
+        while (cp1 != &lp2->l_text[lp2->l_used])
+                *cp2++ = *cp1++;
+        lp1->l_bp->l_fp = lp3;
+        lp3->l_fp = lp2->l_fp;
+        lp2->l_fp->l_bp = lp3;
+        lp3->l_bp = lp1->l_bp;
+        wp = wheadp;
+        while (wp != NULL) {
+                if (wp->w_linep==lp1 || wp->w_linep==lp2)
+                        wp->w_linep = lp3;
+                if (wp->w_dotp == lp1)
+                        wp->w_dotp  = lp3;
+                else if (wp->w_dotp == lp2) {
+                        wp->w_dotp  = lp3;
+                        wp->w_doto += lp1->l_used;
+                }
+                if (wp->w_markp == lp1)
+                        wp->w_markp  = lp3;
+                else if (wp->w_markp == lp2) {
+                        wp->w_markp  = lp3;
+                        wp->w_marko += lp1->l_used;
+                }
+                wp = wp->w_wndp;
+        }
+        free((char *) lp1);
+        free((char *) lp2);
+        return (TRUE);
+}
+
+/*
+ * Delete all of the text saved in the kill buffer. Called by commands when a
+ * new kill context is being created. The kill buffer array is released, just
+ * in case the buffer has grown to immense size. No errors.
+ */
+kdelete()
+{
+        if (kbufp != NULL) {
+                free((char *) kbufp);
+                kbufp = NULL;
+                kused = 0;
+                ksize = 0;
+        }
+}
+
+/*
+ * Insert a character to the kill buffer, enlarging the buffer if there isn't
+ * any room. Always grow the buffer in chunks, on the assumption that if you
+ * put something in the kill buffer you are going to put more stuff there too
+ * later. Return TRUE if all is well, and FALSE on errors.
+ */
+kinsert(c)
+{
+        register char   *nbufp;
+        register int    i;
+
+        if (kused == ksize) {
+                if ((nbufp=malloc(ksize+KBLOCK)) == NULL)
+                        return (FALSE);
+                for (i=0; i<ksize; ++i)
+                        nbufp[i] = kbufp[i];
+                if (kbufp != NULL)
+                        free((char *) kbufp);
+                kbufp  = nbufp;
+                ksize += KBLOCK;
+        }
+        kbufp[kused++] = c;
+        return (TRUE);
+}
+
+/*
+ * This function gets characters from the kill buffer. If the character index
+ * "n" is off the end, it returns "-1". This lets the caller just scan along
+ * until it gets a "-1" back.
+ */
+kremove(n)
+{
+        if (n >= kused)
+                return (-1);
+        else
+                return (kbufp[n] & 0xFF);
+}
+
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/3rdparty/packages/uemacs/uemacs.doc	Sun Feb 23 21:26:32 2003 +0000
@@ -0,0 +1,68 @@
+              MicroEMACS control sequences for 6809 OS9 version
+                  For Os9/68000 consult the source code.
+
+Note: For the Color Computer /TERM version, the <esc> key is <clear> and
+      <break> keys together.  <ctrl> is the <clear> key.  del is the <<->
+      key.
+
+      The window commands have been deleted.  Therefore, there is only
+      one window.
+
+<ctrl-@>        Set Mark at current position.
+<ctrl-A>        Move cursor to beginning of line.
+<ctrl-B>        Move cursor BACK one character.
+<ctrl-C>        Push to a new interactive command shell.
+<ctrl-D>        DELETE current current character.
+<ctrl-E>        Move cursor to END of line.
+<ctrl-F>        Move cursor FORWARD one character.
+<ctrl-G>        Abort any command. (shades of Teco).
+<ctrl-H>        (backspace) delete previous character.
+<ctrl-K>        KILL (delete) to end of line.
+<ctrl-L>        Redisplay screen.
+<ctrl-N>        Move cursor to NEXT line.
+<ctrl-O>        OPEN a new line.
+<ctrl-P>        Move to PREVIOUS line.
+<ctrl-Q>        QUOTE the next character (insert the next character typed).
+<ctrl-R>        REVERSE Search.
+<ctrl-S>        Forward SEARCH.
+<ctrl-T>        TRANSPOSE characters.
+<ctrl-U>        Enter repeat count for next command.
+<ctrl-V>        VIEW the next screen (scroll up one screen).
+<ctrl-W>        Kill region (all text between cursor and last mark set).
+<ctrl-Y>        YANK (undelete) last text killed (deleted).
+<ctrl-Z>        Save file in current buffer and exit.
+
+<ctrl-X>=       Show buffer statistics:
+                X=cc Y=ll CH=$$ .=loc (nn% of total chars)
+<ctrl-X>(       Begin keyboard Macro.
+<ctrl-X>)       End keyboard Macro.
+<ctrl-X>E       EXECUTE keyboard macro.
+
+<ctrl-X><ctrl-C> Exit without saving buffers.
+<ctrl-X><ctrl-N> Scroll current window up by repeat count lines.
+<ctrl-X><ctrl-P> Scroll current window down by repeat count lines.
+
+<ctrl-X><ctrl-R> READ file into current buffer.
+<ctrl-X><ctrl-S> SAVE (write) current buffer into its file.
+<ctrl-X><ctrl-W> WRITE buffer to file.
+
+<ctrl-X><ctrl-U> UPPERCASE region between cursor and mark.
+<ctrl-X><ctrl-L> LOWERCASE region between cursor and mark.
+
+<ctrl-X><ctrl-X> Swap cursor and mark positions.
+
+<del>           delete previous character.
+
+<esc>.          Set Mark at current position.
+<esc>!          Move current line to repeat count lines from top of window.
+<esc>>          Move cursor to end of buffer.
+<esc><          Move cursor to beginning of buffer.
+<esc>B          Move cursor BACK one word.
+<esc>C          CAPITALIZE (Capitalize) word.
+<esc>D          DELETE next word.
+<esc><del>      DELETE previous word.
+<esc>F          Move cursor FORWARD one word.
+<esc>L          LOWERCASE (lowercase) next word.
+<esc>U          UPPERCASE (UPPERCASE) next word.
+<esc>V          VIEW the previous screen (scroll down one screen).
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/3rdparty/packages/uemacs/uemacs.hlp	Sun Feb 23 21:26:32 2003 +0000
@@ -0,0 +1,14 @@
+Instalation:
+
+Os9/68000: 
+  Vt52: rename uemacs.mak to makefile and use make.
+  Other: Modify makefile to use appropriate terminal module (i.e. ansi)
+        rather than the vt52 module.
+
+Os9/6809: See uemacs.mak to see what modules are needed.
+
+Known Problem:
+  The 68000 version seems to have problems editing large (or many small)
+files (long before memory is exausted).  The malloc routine apperently 
+does not work well for many small allocations.  
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/3rdparty/packages/uemacs/uemacs.mak	Sun Feb 23 21:26:32 2003 +0000
@@ -0,0 +1,19 @@
+#  makefile for Micro emacs for os9/68000
+# temp files on ram disk
+CFLAGS = -t=/r0
+
+MAINR  = uemain1.r uemain2.r uemain3.r uemain4.r uemaintable.r
+DISPR  = uedisplay1.r uedisplay2.r uedisplay3.r
+RESTR  = uebasic.r uebuffer1.r uebuffer2.r uefile1.r uefile2.r uefileio.r \
+  ueline1.r ueline2.r uerandom1.r uerandom2.r ueregion.r uesearch.r uespawn.r \
+  uetermio.r uevt52.r uewindow.r ueword.r
+RFILES = $(MAINR) $(DISPR) $(RESTR)
+
+# use cio libarary
+umacs: $(RFILES)
+  cc -i $(RFILES) -f=umacs
+  
+$(MAINR): ueed.h uemain.h
+$(DISPR): ueed.h uedisplay.h
+$(RESTR): ueed.h
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/3rdparty/packages/uemacs/uemain.h	Sun Feb 23 21:26:32 2003 +0000
@@ -0,0 +1,272 @@
+/* Main header */
+
+#ifdef MAINTABLE
+int  currow;       /* Working cursor row   */
+int  curcol;       /* Working cursor column  */
+int  fillcol;      /* Current fill column  */
+int  thisflag;      /* Flags, this command  */
+int  lastflag;      /* Flags, last command  */
+int  curgoal;      /* Goal column    */
+BUFFER *curbp;       /* Current buffer    */
+WINDOW *curwp;       /* Current window    */
+BUFFER *bheadp;      /* BUFFER listhead   */
+WINDOW *wheadp;      /* WINDOW listhead   */
+BUFFER *blistp;      /* Buffer list BUFFER   */
+short kbdm[NKBDM] = {CTLX|')'};  /* Macro      */
+short *kbdmip;      /* Input for above   */
+short *kbdmop;      /* Output for above   */
+char pat[NPAT];      /* Pattern     */
+#else
+extern int  currow;       /* Working cursor row   */
+extern int  curcol;       /* Working cursor column  */
+extern int  fillcol;      /* Current fill column  */
+extern int  thisflag;      /* Flags, this command  */
+extern int  lastflag;      /* Flags, last command  */
+extern int  curgoal;      /* Goal column    */
+extern BUFFER *curbp;       /* Current buffer    */
+extern WINDOW *curwp;       /* Current window    */
+extern BUFFER *bheadp;      /* BUFFER listhead   */
+extern WINDOW *wheadp;      /* WINDOW listhead   */
+extern BUFFER *blistp;      /* Buffer list BUFFER   */
+extern short kbdm[];        /* Macro      */
+extern short *kbdmip;      /* Input for above   */
+extern short *kbdmop;      /* Output for above   */
+extern char pat[];      /* Pattern     */
+#endif
+
+typedef struct {
+  short k_code;     /* Key code      */
+  int (*k_fp)();    /* Routine to handle it   */
+}  KEYTAB;
+
+/*
+ * Command table.
+ * This table is *roughly* in ASCII order, left to right across the
+ * characters of the command. This expains the funny location of the
+ * control-X commands.
+ */
+#ifdef MAINTABLE
+
+extern      int ctrlg();                /* Abort out of things          */
+extern      int quit();                 /* Quit                         */
+extern      int ctlxlp();               /* Begin macro                  */
+extern      int ctlxrp();               /* End macro                    */
+extern     int  ctlxe();                /* Execute macro                */
+extern     int  fileread();             /* Get a file, read only        */
+extern     int  filevisit();            /* Get a file, read write       */
+extern     int  filewrite();            /* Write a file                 */
+extern     int  filesave();             /* Save current file            */
+extern     int  filename();             /* Adjust file name             */
+extern     int  getccol();              /* Get current column           */
+extern     int  gotobol();              /* Move to start of line        */
+extern     int  forwchar();             /* Move forward by characters   */
+extern     int  gotoeol();              /* Move to end of line          */
+extern     int  backchar();             /* Move backward by characters  */
+extern     int  forwline();             /* Move forward by lines        */
+extern     int  backline();             /* Move backward by lines       */
+extern     int  forwpage();             /* Move forward by pages        */
+extern     int  backpage();             /* Move backward by pages       */
+extern     int  gotobob();              /* Move to start of buffer      */
+extern     int  gotoeob();              /* Move to end of buffer        */
+extern     int  setfillcol();           /* Set fill column.             */
+extern     int  setmark();              /* Set mark                     */
+extern     int  swapmark();             /* Swap "." and mark            */
+extern     int  forwsearch();           /* Search forward               */
+extern     int  backsearch();           /* Search backwards             */
+extern     int  showcpos();             /* Show the cursor position     */
+#ifndef OS9
+extern     int  nextwind();             /* Move to the next window      */
+extern     int  prevwind();             /* Move to the previous window  */
+extern     int  onlywind();             /* Make current window only one */
+extern     int  splitwind();            /* Split current window         */
+extern     int  mvdnwind();             /* Move window down             */
+extern     int  mvupwind();             /* Move window up               */
+extern     int  enlargewind();          /* Enlarge display window.      */
+extern     int  shrinkwind();           /* Shrink window.               */
+extern     int  listbuffers();          /* Display list of buffers      */
+extern     int  usebuffer();            /* Switch a window to a buffer  */
+extern     int  killbuffer();           /* Make a buffer go away.       */
+#endif
+extern     int  reposition();           /* Reposition window            */
+extern     int  refresh();              /* Refresh the screen           */
+extern     int  twiddle();              /* Twiddle characters           */
+extern     int  tab();                  /* Insert tab                   */
+extern     int  newline();              /* Insert CR-LF                 */
+extern     int  indent();               /* Insert CR-LF, then indent    */
+extern     int  openline();             /* Open up a blank line         */
+extern     int  deblank();              /* Delete blank lines           */
+extern     int  quote();                /* Insert literal               */
+extern     int  backword();             /* Backup by words              */
+extern     int  forwword();             /* Advance by words             */
+extern     int  forwdel();              /* Forward delete               */
+extern     int  backdel();              /* Backward delete              */
+extern     int  killer();               /* Kill forward                 */
+extern     int  yank();                 /* Yank back from killbuffer.   */
+extern     int  upperword();            /* Upper case word.             */
+extern     int  lowerword();            /* Lower case word.             */
+extern     int  upperregion();          /* Upper case region.           */
+extern     int  lowerregion();          /* Lower case region.           */
+extern     int  capword();              /* Initial capitalize word.     */
+extern     int  delfword();             /* Delete forward word.         */
+extern     int  delbword();             /* Delete backward word.        */
+extern     int  killregion();           /* Kill region.                 */
+extern     int  copyregion();           /* Copy region to kill buffer.  */
+extern     int  spawncli();             /* Run CLI in a subjob.         */
+extern     int  spawn();                /* Run a command in a subjob.   */
+extern     int  quickexit();            /* low keystroke style exit.    */
+
+KEYTAB keytab[] = {
+  CTRL|'@',    setmark,
+  CTRL|'A',    gotobol,
+  CTRL|'B',    backchar,
+  CTRL|'C',    spawncli,  /* Run CLI in subjob. */
+  CTRL|'D',    forwdel,
+  CTRL|'E',    gotoeol,
+  CTRL|'F',    forwchar,
+  CTRL|'G',    ctrlg,
+  CTRL|'H',    backdel,
+  CTRL|'I',    tab,
+  CTRL|'J',    indent,
+  CTRL|'K',    killer,
+  CTRL|'L',    refresh,
+  CTRL|'M',    newline,
+  CTRL|'N',    forwline,
+  CTRL|'O',    openline,
+  CTRL|'P',    backline,
+  CTRL|'Q',    quote,   /* Often unreachable */
+  CTRL|'R',    backsearch,
+  CTRL|'S',    forwsearch, /* Often unreachable */
+  CTRL|'T',    twiddle,
+  CTRL|'V',    forwpage,
+  CTRL|'W',    killregion,
+  CTRL|'Y',    yank,
+  CTRL|'Z',    quickexit,  /* quick save and exit */
+#ifndef OS9
+  CTLX|CTRL|'B',   listbuffers,
+#endif
+  CTLX|CTRL|'C',   quit,   /* Hard quit.   */
+  CTLX|CTRL|'F',   filename,
+  CTLX|CTRL|'L',   lowerregion,
+  CTLX|CTRL|'O',   deblank,
+#ifndef OS9
+  CTLX|CTRL|'N',   mvdnwind,
+  CTLX|CTRL|'P',   mvupwind,
+#endif
+  CTLX|CTRL|'R',   fileread,
+  CTLX|CTRL|'S',   filesave,  /* Often unreachable */
+  CTLX|CTRL|'U',   upperregion,
+#ifndef OS9
+  CTLX|CTRL|'V',   filevisit,
+#endif
+  CTLX|CTRL|'W',   filewrite,
+  CTLX|CTRL|'X',   swapmark,
+#ifndef OS9
+  CTLX|CTRL|'Z',   shrinkwind,
+#endif
+  CTLX|'!',    spawn,   /* Run 1 command.  */
+  CTLX|'=',    showcpos,
+  CTLX|'(',    ctlxlp,
+  CTLX|')',    ctlxrp,
+#ifndef OS9
+  CTLX|'1',    onlywind,
+  CTLX|'2',    splitwind,
+  CTLX|'B',    usebuffer,
+#endif
+  CTLX|'E',    ctlxe,
+  CTLX|'F',    setfillcol,
+#ifndef OS9
+  CTLX|'K',    killbuffer,
+  CTLX|'N',    nextwind,
+  CTLX|'P',    prevwind,
+  CTLX|'Z',    enlargewind,
+#endif
+  META|CTRL|'H',   delbword,
+  META|'!',    reposition,
+  META|'.',    setmark,
+  META|'>',    gotoeob,
+  META|'<',    gotobob,
+  META|'B',    backword,
+  META|'C',    capword,
+  META|'D',    delfword,
+  META|'F',    forwword,
+  META|'L',    lowerword,
+  META|'U',    upperword,
+  META|'V',    backpage,
+#ifndef OS9
+  META|'W',    copyregion,
+#endif
+  META|0x7F,    delbword,
+  0x7F,     backdel,
+  0,        0 /* Signals end of table */
+};
+#else
+extern KEYTAB keytab[];
+#endif
+
+#define NKEYTAB (sizeof(keytab)/sizeof(keytab[0]))
+
+#ifdef RAINBOW
+
+#include "rainbow.h"
+
+/*
+ * Mapping table from the LK201 function keys to the internal EMACS character.
+ */
+
+short lk_map[][2] = {
+  Up_Key,       CTRL+'P',
+  Down_Key,      CTRL+'N',
+  Left_Key,      CTRL+'B',
+  Right_Key,      CTRL+'F',
+  Shift+Left_Key,     META+'B',
+  Shift+Right_Key,    META+'F',
+  Control+Left_Key,    CTRL+'A',
+  Control+Right_Key,    CTRL+'E',
+  Prev_Scr_Key,     META+'V',
+  Next_Scr_Key,     CTRL+'V',
+  Shift+Up_Key,     META+'<',
+  Shift+Down_Key,     META+'>',
+  Cancel_Key,      CTRL+'G',
+  Find_Key,      CTRL+'S',
+  Shift+Find_Key,     CTRL+'R',
+  Insert_Key,      CTRL+'Y',
+  Options_Key,     CTRL+'D',
+  Shift+Options_Key,    META+'D',
+  Remove_Key,      CTRL+'W',
+  Shift+Remove_Key,    META+'W',
+  Select_Key,      CTRL+'@',
+  Shift+Select_Key,    CTLX+CTRL+'X',
+  Interrupt_Key,     CTRL+'U',
+  Keypad_PF2,      META+'L',
+  Keypad_PF3,      META+'C',
+  Keypad_PF4,      META+'U',
+  Shift+Keypad_PF2,    CTLX+CTRL+'L',
+  Shift+Keypad_PF4,    CTLX+CTRL+'U',
+  Keypad_1,      CTLX+'1',
+  Keypad_2,      CTLX+'2',
+  Do_Key,       CTLX+'E',
+  Keypad_4,      CTLX+CTRL+'B',
+  Keypad_5,      CTLX+'B',
+  Keypad_6,      CTLX+'K',
+  Resume_Key,      META+'!',
+  Control+Next_Scr_Key,   CTLX+'N',
+  Control+Prev_Scr_Key,   CTLX+'P',
+  Control+Up_Key,     CTLX+CTRL+'P',
+  Control+Down_Key,    CTLX+CTRL+'N',
+  Help_Key,      CTLX+'=',
+  Shift+Do_Key,     CTLX+'(',
+  Control+Do_Key,     CTLX+')',
+  Keypad_0,      CTLX+'Z',
+  Shift+Keypad_0,     CTLX+CTRL+'Z',
+  Main_Scr_Key,     CTRL+'C',
+  Keypad_Enter,     CTLX+'!',
+  Exit_Key,      CTLX+CTRL+'C',
+  Shift+Exit_Key,     CTRL+'Z'
+  };
+
+#define lk_map_size  (sizeof(lk_map)/2)
+
+#endif
+
+#define NULL 0
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/3rdparty/packages/uemacs/uemain1.c	Sun Feb 23 21:26:32 2003 +0000
@@ -0,0 +1,129 @@
+/*
+ * This program is in public domain; written by Dave G. Conroy.
+ * This file contains the main driving routine, and some keyboard processing
+ * code, for the MicroEMACS screen editor.
+ *
+ * REVISION HISTORY:
+ *
+ * 1.0  Steve Wilhite, 30-Nov-85
+ *      - Removed the old LK201 and VT100 logic. Added code to support the
+ *        DEC Rainbow keyboard (which is a LK201 layout) using the the Level
+ *        1 Console In ROM INT. See "rainbow.h" for the function key definitions
+.
+ *
+ * 2.0  George Jones, 12-Dec-85
+ *      - Ported to Amiga.
+ *
+ * 3.0  Bob Santy, 5-Jan-86
+ *      - Ported to Tandy Color Computer OS9.
+ *      - COCO version has window functions
+ *        removed to save memory.
+ *      - Source modules split into more,
+ *        smaller files.
+ * ?.?  Robert Larson
+ *      - Os9/68000 version (OSK)
+ *      - Fixes to ^X= command   
+ */
+  
+/* #include        <stdio.h> */
+#include        "ueed.h"
+#ifdef VMS
+#include        <ssdef.h>
+#define GOOD    (SS$_NORMAL)
+#endif
+
+#ifndef GOOD
+#define GOOD    0
+#endif
+
+#define MAIN1 1
+#include "uemain.h"
+
+main(argc, argv)
+char    *argv[];
+{
+        register int    c;
+        register int    f;
+        register int    n;
+        register int    mflag;
+        char            bname[NBUFN];
+
+        strcpy(bname, "main");                  /* Work out the name of */
+        if (argc > 1)                           /* the default buffer.  */
+                makename(bname, argv[1]);
+        edinit(bname);                          /* Buffers, windows.    */
+        vtinit();                               /* Displays.            */
+        if (argc > 1) {
+                update();                       /* You have to update   */
+                readin(argv[1]);                /* in case "[New file]" */
+        }
+        lastflag = 0;                           /* Fake last flags.     */
+loop:
+        update();                               /* Fix up the screen    */
+        c = getkey();
+        if (mpresf != FALSE) {
+                mlerase();
+                update();
+                if (c == ' ')                   /* ITS EMACS does this  */
+                        goto loop;
+        }
+        f = FALSE;
+        n = 1;
+        if (c == (CTRL|'U')) {                  /* ^U, start argument   */
+                f = TRUE;
+                n = 4;                          /* with argument of 4 */
+                mflag = 0;                      /* that can be discarded. */
+                mlwrite("Arg: 4");
+                while ((c=getkey()) >='0' && c<='9' || c==(CTRL|'U') || c=='-'){
+                        if (c == (CTRL|'U'))
+                                n = n*4;
+                        /*
+                         * If dash, and start of argument string, set arg.
+                         * to -1.  Otherwise, insert it.
+                         */
+                        else if (c == '-') {
+                                if (mflag)
+                                        break;
+                                n = 0;
+                                mflag = -1;
+                        }
+                        /*
+                         * If first digit entered, replace previous argument
+                         * with digit and set sign.  Otherwise, append to arg.
+                         */
+                        else {
+                                if (!mflag) {
+                                        n = 0;
+                                        mflag = 1;
+                                }
+                                n = 10*n + c - '0';
+                        }
+                        mlwrite("Arg: %d", (mflag >=0) ? n : (n ? -n : -1));
+                }
+                /*
+                 * Make arguments preceded by a minus sign negative and change
+                 * the special argument "^U -" to an effective "^U -1".
+                 */
+                if (mflag == -1) {
+                        if (n == 0)
+                                n++;
+                        n = -n;
+                }
+        }
+        if (c == (CTRL|'X'))                    /* ^X is a prefix       */
+                c = CTLX | getctl();
+        if (kbdmip != NULL) {                   /* Save macro strokes.  */
+                if (c!=(CTLX|')') && kbdmip>&kbdm[NKBDM-6]) {
+                        ctrlg(FALSE, 0);
+                        goto loop;
+                }
+                if (f != FALSE) {
+                        *kbdmip++ = (CTRL|'U');
+                        *kbdmip++ = n;
+                }
+                *kbdmip++ = c;
+        }
+        execute(c, f, n);                       /* Do it.               */
+        goto loop;
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/3rdparty/packages/uemacs/uemain2.c	Sun Feb 23 21:26:32 2003 +0000
@@ -0,0 +1,150 @@
+/*
+ * This program is in public domain; written by Dave G. Conroy.
+ * This file contains the main driving routine, and some keyboard processing
+ * code, for the MicroEMACS screen editor.
+ *
+ * REVISION HISTORY:
+ *
+ * 1.0  Steve Wilhite, 30-Nov-85
+ *      - Removed the old LK201 and VT100 logic. Added code to support the
+ *        DEC Rainbow keyboard (which is a LK201 layout) using the the Level
+ *        1 Console In ROM INT. See "rainbow.h" for the function key definitions
+.
+ *
+ * 2.0  George Jones, 12-Dec-85
+ *      - Ported to Amiga.
+ */
+#include        <stdio.h>
+#include        "ueed.h"
+#ifdef VMS
+#include        <ssdef.h>
+#define GOOD    (SS$_NORMAL)
+#endif
+
+#ifndef GOOD
+#define GOOD    0
+#endif
+
+#include "uemain.h"
+        
+/*
+ * This is the general command execution routine. It handles the fake binding
+ * of all the keys to "self-insert". It also clears out the "thisflag" word,
+ * and arranges to move it to the "lastflag", so that the next command can
+ * look at it. Return the status of command.
+ */
+execute(c, f, n)
+int c,f,n;
+{
+        register KEYTAB *ktp;
+        int status;
+
+        status = TRUE;
+        ktp = &keytab[0];                       /* Look in key table.   */
+        while (ktp->k_code) {
+                if (ktp->k_code == c) {
+                        thisflag = 0;
+                        status = (*ktp->k_fp)(f, n);
+                        lastflag = thisflag;
+                        return(status);
+                }
+                ++ktp;
+        }
+
+        /*
+         * If a space was typed, fill column is defined, the argument is non-
+         * negative, and we are now past fill column, perform word wrap.
+         */
+        if (c == ' ' && fillcol > 0 && n>=0 && getccol(FALSE) > fillcol)
+                wrapword();
+
+        if ((c>=0x20 && c<=0x7E)                /* Self inserting.      */
+        ||  (c>=0xA0 && c<=0xFE)) {
+                if (n <= 0) {                   /* Fenceposts.          */
+                        lastflag = 0;
+                }
+                thisflag = 0;                   /* For the future.      */
+                linsert(n, c);
+                lastflag = thisflag;
+                return(TRUE);
+        } else {
+                lastflag = 0;                   /* Fake last flags.     */
+                return(FALSE);
+        }
+}
+
+/*
+ * Read in a key.
+ * Do the standard keyboard preprocessing. Convert the keys to the internal
+ * character set.
+ */
+getkey()
+{
+        register int    c;
+
+        c = (*term.t_getchar)();
+#ifdef DEBUG
+        printf("%4X",c);
+#endif
+
+#ifdef RAINBOW
+
+        if (c & Function_Key)
+                {
+                int i;
+
+                for (i = 0; i < lk_map_size; i++)
+                        if (c == lk_map[i][0])
+                                return lk_map[i][1];
+                }
+        else if (c == Shift + 015) return CTRL | 'J';
+        else if (c == Shift + 0x7F) return META | 0x7F;
+#endif
+
+        if (c == METACH) {                      /* Apply M- prefix      */
+#ifdef DEBUG
+                printf("META");
+#endif
+                c = getctl();
+#ifdef DEBUG
+                printf("CTL=%4X",c);
+#endif
+                return (META | c);
+        }
+
+        if (c>=0x00 && c<=0x1F)                 /* C0 control -> C-     */
+                c = CTRL | (c+'@');
+#ifdef DEBUG
+        printf("CTRL=%4X",c);
+#endif
+        return (c);
+}
+
+/*
+ * Get a key.
+ * Apply control modifications to the read key.
+ */
+getctl()
+{
+        register int    c;
+
+        c = (*term.t_getchar)();
+        if (c>='a' && c<='z')                   /* Force to upper       */
+                c -= 0x20;
+        if (c>=0x00 && c<=0x1F)                 /* C0 control -> C-     */
+                c = CTRL | (c+'@');
+        return (c);
+}
+
+/*
+ * Fancy quit command, as implemented by Norm. If the current buffer has
+ * changed do a write current buffer and exit emacs, otherwise simply exit.
+ */
+quickexit(f, n)
+{
+        if ((curbp->b_flag&BFCHG) != 0          /* Changed.             */
+        && (curbp->b_flag&BFTEMP) == 0)         /* Real.                */
+                filesave(f, n);
+        quit(f, n);                             /* conditionally quit   */
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/3rdparty/packages/uemacs/uemain3.c	Sun Feb 23 21:26:32 2003 +0000
@@ -0,0 +1,129 @@
+/*
+ * This program is in public domain; written by Dave G. Conroy.
+ * This file contains the main driving routine, and some keyboard processing
+ * code, for the MicroEMACS screen editor.
+ *
+ * REVISION HISTORY:
+ *
+ * 1.0  Steve Wilhite, 30-Nov-85
+ *      - Removed the old LK201 and VT100 logic. Added code to support the
+ *        DEC Rainbow keyboard (which is a LK201 layout) using the the Level
+ *        1 Console In ROM INT. See "rainbow.h" for the function key definitions
+ *
+ * 2.0  George Jones, 12-Dec-85
+ *      - Ported to Amiga.
+ */
+#include        <stdio.h>
+#include        "ueed.h"
+#ifdef VMS
+#include        <ssdef.h>
+#define GOOD    (SS$_NORMAL)
+#endif
+
+#ifndef GOOD
+#define GOOD    0
+#endif
+
+#include "uemain.h"
+
+/*
+ * Quit command. If an argument, always quit. Otherwise confirm if a buffer
+ * has been changed and not written out. Normally bound to "C-X C-C".
+ */
+quit(f, n)
+{
+        register int    s;
+
+        if (f != FALSE                          /* Argument forces it.  */
+        || anycb() == FALSE                     /* All buffers clean.   */
+        || (s=mlyesno("Quit")) == TRUE) {       /* User says it's OK.   */
+                vttidy();
+                exit(GOOD);
+        }
+}
+
+/*
+ * Begin a keyboard macro.
+ * Error if not at the top level in keyboard processing. Set up variables and
+ * return.
+ */
+ctlxlp(f, n)
+int f,n;
+{
+        if (kbdmip!=NULL || kbdmop!=NULL) {
+                mlwrite("Not now");
+                return(FALSE);
+        }
+        mlwrite("[Start macro]");
+        kbdmip = &kbdm[0];
+        return(TRUE);
+}
+
+/*
+ * End keyboard macro. Check for the same limit conditions as the above
+ * routine. Set up the variables and return to the caller.
+ */
+ctlxrp(f, n)
+int f,n;
+{
+        if (kbdmip == NULL) {
+                mlwrite("Not now");
+                return(FALSE);
+        }
+        mlwrite("[End macro]");
+        kbdmip = NULL;
+        return(TRUE);
+}
+
+/*
+ * Execute a macro.
+ * The command argument is the number of times to loop. Quit as soon as a
+ * command gets an error. Return TRUE if all ok, else FALSE.
+ */
+ctlxe(f, n)
+int f,n;
+{
+        register int    c;
+        register int    af;
+        register int    an;
+        register int    s;
+
+        if (kbdmip!=NULL || kbdmop!=NULL) {
+                mlwrite("Not now");
+                return(FALSE);
+        }
+        if (n <= 0) 
+                return(FALSE);
+        do {
+                kbdmop = &kbdm[0];
+                do {
+                        af = FALSE;
+                        an = 1;
+                        if ((c = *kbdmop++) == (CTRL|'U')) {
+                                af = TRUE;
+                                an = *kbdmop++;
+                                c  = *kbdmop++;
+                        }
+                        s = TRUE;
+                } while (c!=(CTLX|')')&&(s=execute(c, af, an))==TRUE);
+                kbdmop = NULL;
+        } while (s==TRUE && --n);
+        return(s);
+}
+
+/*
+ * Abort.
+ * Beep the beeper. Kill off any keyboard macro, etc., that is in progress.
+ * Sometimes called as a routine, to do general aborting of stuff.
+ */
+ctrlg(f, n)
+{
+        (*term.t_beep)();
+        if (kbdmip != NULL) {
+                kbdm[0] = (CTLX|')');
+                kbdmip  = NULL;
+        }
+        return(TRUE);
+}
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/3rdparty/packages/uemacs/uemain4.c	Sun Feb 23 21:26:32 2003 +0000
@@ -0,0 +1,63 @@
+/*
+ * This program is in public domain; written by Dave G. Conroy.
+ * This file contains the main driving routine, and some keyboard processing
+ * code, for the MicroEMACS screen editor.
+ *
+ * REVISION HISTORY:
+ *
+ * 1.0  Steve Wilhite, 30-Nov-85
+ *      - Removed the old LK201 and VT100 logic. Added code to support the
+ *        DEC Rainbow keyboard (which is a LK201 layout) using the the Level
+ *        1 Console In ROM INT. See "rainbow.h" for the function key definitions
+ *
+ * 2.0  George Jones, 12-Dec-85
+ *      - Ported to Amiga.
+ */
+#include        <stdio.h>
+#include        "ueed.h"
+#ifdef VMS
+#include        <ssdef.h>
+#define GOOD    (SS$_NORMAL)
+#endif
+
+#ifndef GOOD
+#define GOOD    0
+#endif
+
+#define MAIN1 1
+#include "uemain.h"
+
+/*
+ * Initialize all of the buffers and windows. The buffer name is passed down
+ * as an argument, because the main routine may have been told to read in a
+ * file by default, and we want the buffer name to be right.
+ */
+edinit(bname)
+char    bname[];
+{
+        register BUFFER *bp;
+        register WINDOW *wp;
+
+        bp = bfind(bname, TRUE, 0);             /* First buffer         */
+        blistp = bfind("[List]", TRUE, BFTEMP); /* Buffer list buffer   */
+        wp = (WINDOW *) malloc(sizeof(WINDOW)); /* First window         */
+        if (bp==NULL || wp==NULL || blistp==NULL)
+                exit(1);
+        curbp  = bp;                            /* Make this current    */
+        wheadp = wp;
+        curwp  = wp;
+        wp->w_bufp  = bp;
+        bp->b_nwnd  = 1;                        /* Displayed.           */
+        wp->w_linep = bp->b_linep;
+        wp->w_dotp  = bp->b_linep;
+        wp->w_wndp  =                      /* Initialize window    */
+        wp->w_doto  = 
+        wp->w_markp = 
+        wp->w_marko = 
+        wp->w_toprow = 
+        wp->w_force = 0;
+        wp->w_ntrows = term.t_nrow-1;           /* "-1" for mode line.  */
+        wp->w_flag  = WFMODE|WFHARD;            /* Full.                */
+}
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/3rdparty/packages/uemacs/uemaintable.c	Sun Feb 23 21:26:32 2003 +0000
@@ -0,0 +1,32 @@
+/*
+ * This program is in public domain; written by Dave G. Conroy.
+ * This file contains the main driving routine, and some keyboard processing
+ * code, for the MicroEMACS screen editor.
+ *
+ * REVISION HISTORY:
+ *
+ * 1.0  Steve Wilhite, 30-Nov-85
+ *      - Removed the old LK201 and VT100 logic. Added code to support the
+ *        DEC Rainbow keyboard (which is a LK201 layout) using the the Level
+ *        1 Console In ROM INT. See "rainbow.h" for the function key definitions
+ *
+ * 2.0  George Jones, 12-Dec-85
+ *      - Ported to Amiga.
+ *
+ * 3.0  Bob Santy, 28-Dec-85
+ *      -  Ported to OS9 Level I
+ */
+/* #include        <stdio.h> */
+#include        "ueed.h"
+#ifdef VMS
+#include        <ssdef.h>
+#define GOOD    (SS$_NORMAL)
+#endif
+
+#ifndef GOOD
+#define GOOD    0
+#endif
+
+#define MAINTABLE 1
+#include "uemain.h"
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/3rdparty/packages/uemacs/uerandom1.c	Sun Feb 23 21:26:32 2003 +0000
@@ -0,0 +1,259 @@
+/*
+ * This file contains the command processing functions for a number of random
+ * commands. There is no functional grouping here, for sure.
+ */
+
+#include        <stdio.h>
+#include        "ueed.h"
+
+int     tabsize;                        /* Tab size (0: use real tabs)  */
+
+/*
+ * Set fill column to n. 
+ */
+setfillcol(f, n)
+{
+        fillcol = n;
+        return(TRUE);
+}
+
+/*
+ * Display the current position of the cursor, in origin 1 X-Y coordinates,
+ * the character that is under the cursor (in hex), and the fraction of the
+ * text that is before the cursor. The displayed column is not the current
+ * column, but the column that would be used on an infinite width display.
+ * Normally this is bound to "C-X =".
+ */
+showcpos(f, n)
+{
+        register LINE   *clp;
+        register long   nch;
+        register long   nbc;
+        register int    cac;
+        register int    ratio;
+        register int    col;
+        register int    i;
+        register int    c;
+        register int    nl;
+        register int    cl;
+#ifdef OSK
+        char mline[80];
+#endif
+
+        clp = lforw(curbp->b_linep);            /* Grovel the data.     */
+        nch = 0;
+        nl  = 0;
+        while (clp != curbp->b_linep) {
+                if (clp == curwp->w_dotp) {
+                        nbc = nch + curwp->w_doto;
+                        cac = (curwp->w_doto < llength(clp)) 
+                                ? lgetc(clp, curwp->w_doto)
+                                : '\n';
+                        cl = nl;
+                }
+                nch += llength(clp)+1;
+
+                clp = lforw(clp);
+                nl++;
+        }
+        if (clp == curwp->w_dotp) { /* special case for end of buffer */
+                nbc = nch;
+                cac = '\n';
+                cl = nl;
+        }
+        col = getccol(FALSE);                   /* Get real column.     */
+        ratio = 0;                              /* Ratio before dot.    */
+        if (nch != 0)
+                ratio = (100L*nbc) / nch;
+#ifdef OSK
+        /* osk objects to this varargs technique with more than 2 arguments */
+        /* while I was changing things I made it display more info */
+        sprintf(mline, 
+"X=%d Y=%d CH=0x%02X (%s%c) Line %d of %d; Char %ld of %ld (%d%%%%)",
+                col+1, currow+1, cac, (cac<' ')?"^":"", (cac<' ')?cac+'@':cac,
+                cl, nl, nbc, nch, ratio);
+        mlwrite(mline);
+#else
+        /* note nl (number of lines) and cl (current line) arn't yet displayed */
+        mlwrite("X=%d Y=%d CH=0x%x .=%D (%d%% of %D)",
+                col+1, currow+1, cac, nbc, ratio, nch);
+#endif
+        return (TRUE);
+}
+
+/*
+ * Return current column.  Stop at first non-blank given TRUE argument.
+ */
+getccol(bflg)
+int bflg;
+{
+        register int c, i, col;
+        col = 0;
+        for (i=0; i<curwp->w_doto; ++i) {
+                c = lgetc(curwp->w_dotp, i);
+                if (c!=' ' && c!='\t' && bflg)
+                        break;
+                if (c == '\t')
+                        col |= 0x07;
+                else if (c<0x20 || c==0x7F)
+                        ++col;
+                ++col;
+        }
+        return(col);
+}
+
+/*
+ * Twiddle the two characters on either side of dot. If dot is at the end of
+ * the line twiddle the two characters before it. Return with an error if dot
+ * is at the beginning of line; it seems to be a bit pointless to make this
+ * work. This fixes up a very common typo with a single stroke. Normally bound
+ * to "C-T". This always works within a line, so "WFEDIT" is good enough.
+ */
+twiddle(f, n)
+{
+        register LINE   *dotp;
+        register int    doto;
+        register int    cl;
+        register int    cr;
+
+        dotp = curwp->w_dotp;
+        doto = curwp->w_doto;
+        if (doto==llength(dotp) && --doto<0)
+                return (FALSE);
+        cr = lgetc(dotp, doto);
+        if (--doto < 0)
+                return (FALSE);
+        cl = lgetc(dotp, doto);
+        lputc(dotp, doto+0, cr);
+        lputc(dotp, doto+1, cl);
+        lchange(WFEDIT);
+        return (TRUE);
+}
+
+/*
+ * Quote the next character, and insert it into the buffer. All the characters
+ * are taken literally, with the exception of the newline, which always has
+ * its line splitting meaning. The character is always read, even if it is
+ * inserted 0 times, for regularity. Bound to "M-Q" (for me) and "C-Q" (for
+ * Rich, and only on terminals that don't need XON-XOFF).
+ */
+quote(f, n)
+{
+        register int    s;
+        register int    c;
+
+        c = (*term.t_getchar)();
+        if (n < 0)
+                return (FALSE);
+        if (n == 0)
+                return (TRUE);
+        if (c == '\n') {
+                do {
+                        s = lnewline();
+                } while (s==TRUE && --n);
+                return (s);
+        }
+        return (linsert(n, c));
+}
+
+/*
+ * Set tab size if given non-default argument (n <> 1).  Otherwise, insert a
+ * tab into file.  If given argument, n, of zero, change to true tabs.
+ * If n > 1, simulate tab stop every n-characters using spaces. This has to be
+ * done in this slightly funny way because the tab (in ASCII) has been turned
+ * into "C-I" (in 10 bit code) already. Bound to "C-I".
+ */
+tab(f, n)
+{
+        if (n < 0)
+                return (FALSE);
+        if (n == 0 || n > 1) {
+                tabsize = n;
+                return(TRUE);
+        }
+        if (! tabsize)
+                return(linsert(1, '\t'));
+        return(linsert(tabsize - (getccol(FALSE) % tabsize), ' '));
+}
+
+/*
+ * Open up some blank space. The basic plan is to insert a bunch of newlines,
+ * and then back up over them. Everything is done by the subcommand
+ * procerssors. They even handle the looping. Normally this is bound to "C-O".
+ */
+openline(f, n)
+{
+        register int    i;
+        register int    s;
+
+        if (n < 0)
+                return (FALSE);
+        if (n == 0)
+                return (TRUE);
+        i = n;                                  /* Insert newlines.     */
+        do {
+                s = lnewline();
+        } while (s==TRUE && --i);
+        if (s == TRUE)                          /* Then back up overtop */
+                s = backchar(f, n);             /* of them all.         */
+        return (s);
+}
+
+/*
+ * Insert a newline. Bound to "C-M". If you are at the end of the line and the
+ * next line is a blank line, just move into the blank line. This makes "C-O"
+ * and "C-X C-O" work nicely, and reduces the ammount of screen update that
+ * has to be done. This would not be as critical if screen update were a lot
+ * more efficient.
+ */
+newline(f, n)
+{
+        int nicol;
+        register LINE   *lp;
+        register int    s;
+
+        if (n < 0)
+
+                return (FALSE);
+        while (n--) {
+                lp = curwp->w_dotp;
+                if (llength(lp) == curwp->w_doto
+                && lp != curbp->b_linep
+                && llength(lforw(lp)) == 0) {
+                        if ((s=forwchar(FALSE, 1)) != TRUE)
+                                return (s);
+                } else if ((s=lnewline()) != TRUE)
+                        return (s);
+        }
+        return (TRUE);
+}
+
+/*
+ * Delete blank lines around dot. What this command does depends if dot is
+ * sitting on a blank line. If dot is sitting on a blank line, this command
+ * deletes all the blank lines above and below the current line. If it is
+ * sitting on a non blank line then it deletes all of the blank lines after
+ * the line. Normally this command is bound to "C-X C-O". Any argument is
+ * ignored.
+ */
+deblank(f, n)
+{
+        register LINE   *lp1;
+        register LINE   *lp2;
+        register int    nld;
+
+        lp1 = curwp->w_dotp;
+        while (llength(lp1)==0 && (lp2=lback(lp1))!=curbp->b_linep)
+                lp1 = lp2;
+        lp2 = lp1;
+        nld = 0;
+        while ((lp2=lforw(lp2))!=curbp->b_linep && llength(lp2)==0)
+                ++nld;
+        if (nld == 0)
+                return (TRUE);
+        curwp->w_dotp = lforw(lp1);
+        curwp->w_doto = 0;
+        return (ldelete(nld));
+}
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/3rdparty/packages/uemacs/uerandom2.c	Sun Feb 23 21:26:32 2003 +0000
@@ -0,0 +1,156 @@
+/*
+ * This file contains the command processing functions for a number of random
+ * commands. There is no functional grouping here, for sure.
+ */
+
+#include        <stdio.h>
+#include        "ueed.h"
+
+/*
+ * Insert a newline, then enough tabs and spaces to duplicate the indentation
+ * of the previous line. Assumes tabs are every eight characters. Quite simple.
+ * Figure out the indentation of the current line. Insert a newline by calling
+ * the standard routine. Insert the indentation by inserting the right number
+ * of tabs and spaces. Return TRUE if all ok. Return FALSE if one of the
+ * subcomands failed. Normally bound to "C-J".
+ */
+indent(f, n)
+{
+        register int    nicol;
+        register int    c;
+        register int    i;
+
+        if (n < 0)
+                return (FALSE);
+        while (n--) {
+                nicol = 0;
+                for (i=0; i<llength(curwp->w_dotp); ++i) {
+                        c = lgetc(curwp->w_dotp, i);
+                        if (c!=' ' && c!='\t')
+                                break;
+                        if (c == '\t')
+                                nicol |= 0x07;
+                        ++nicol;
+                }
+                if (lnewline() == FALSE
+                || ((i=nicol/8)!=0 && linsert(i, '\t')==FALSE)
+                || ((i=nicol%8)!=0 && linsert(i,  ' ')==FALSE))
+                        return (FALSE);
+        }
+        return (TRUE);
+}
+
+/*
+ * Delete forward. This is real easy, because the basic delete routine does
+ * all of the work. Watches for negative arguments, and does the right thing.
+ * If any argument is present, it kills rather than deletes, to prevent loss
+ * of text if typed with a big arg
+ument. Normally bound to "C-D".
+ */
+forwdel(f, n)
+{
+        if (n < 0)
+                return (backdel(f, -n));
+
+        if (f != FALSE) {                       /* Really a kill.       */
+                if ((lastflag&CFKILL) == 0)
+                        kdelete();
+                thisflag |= CFKILL;
+        }
+        return (ldelete(n, f));
+}
+
+/*
+ * Delete backwards. This is quite easy too, because it's all done with other
+ * functions. Just move the cursor back, and delete forwards. Like delete
+ * forward, this actually does a kill if presented with an argument. Bound to
+ * both "RUBOUT" and "C-H".
+ */
+backdel(f, n)
+{
+        register int    s;
+
+        if (n < 0)
+                return (forwdel(f, -n));
+        if (f != FALSE) {                       /* Really a kill.       */
+                if ((lastflag&CFKILL) == 0)
+                        kdelete();
+                thisflag |= CFKILL;
+        }
+        if ((s=backchar(f, n)) == TRUE)
+                s = ldelete(n, f);
+        return (s);
+}
+
+/*
+ * Kill text. If called without an argument, it kills from dot to the end of
+ * the line, unless it is at the end of the line, when it kills the newline.
+ * If called with an argument of 0, it kills from the start of the line to dot.
+ * If called with a positive argument, it kills from dot forward over that
+ * number of newlines. If called with a negative argument it kills backwards
+ * that number of newlines. Normally bound to "C-K".
+ */
+killer(f, n)
+int f,n;
+{
+        register int    chunk;
+        register LINE   *nextp;
+
+        if ((lastflag&CFKILL) == 0)             /* Clear kill buffer if */
+                kdelete();                      /* last wasn't a kill.  */
+        thisflag |= CFKILL;
+        if (f == FALSE) {
+                chunk = llength(curwp->w_dotp)-curwp->w_doto;
+                if (chunk == 0)
+                        chunk = 1;
+        } else if (n == 0) {
+                chunk = curwp->w_doto;
+                curwp->w_doto = 0;
+        } else if (n > 0) {
+                chunk = llength(curwp->w_dotp)-curwp->w_doto+1;
+                nextp = lforw(curwp->w_dotp);
+                while (--n) {
+                        if (nextp == curbp->b_linep)
+                                return (FALSE);
+                        chunk += llength(nextp)+1;
+                        nextp = lforw(nextp);
+                }
+        } else {
+                mlwrite("neg kill");
+                return (FALSE);
+        }
+        return (ldelete(chunk, TRUE));
+}
+
+/*
+ * Yank text back from the kill buffer. This is really easy. All of the work
+ * is done by the standard insert routines. All you do is run the loop, and
+ * check for errors. Bound to "C-Y". The blank lines are inserted with a call
+ * to "newline" instead of a call to "lnewline" so that the magic stuff that
+ * happens when you type a carriage return also happens when a carriage return
+ * is yanked back from the kill buffer.
+ */
+yank(f, n)
+{
+        register int    c;
+        register int    i;
+        extern   int    kused;
+
+        if (n < 0)
+                return (FALSE);
+        while (n--) {
+                i = 0;
+                while ((c=kremove(i)) >= 0) {
+                        if (c == '\n') {
+                                if (newline(FALSE, 1) == FALSE)
+                                        return (FALSE);
+                        } else {
+                                if (linsert(1, c) == FALSE)
+                                        return (FALSE);
+                        }
+                        ++i;
+                }
+        }
+        return (TRUE);
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/3rdparty/packages/uemacs/ueregion.c	Sun Feb 23 21:26:32 2003 +0000
@@ -0,0 +1,201 @@
+/*
+ * The routines in this file
+ * deal with the region, that magic space
+ * between "." and mark. Some functions are
+ * commands. Some functions are just for
+ * internal use.
+ */
+#include        <stdio.h>
+#include        "ueed.h"
+
+/*
+ * Kill the region. Ask "getregion"
+ * to figure out the bounds of the region.
+ * Move "." to the start, and kill the characters.
+ * Bound to "C-W".
+ */
+killregion(f, n)
+{
+        register int    s;
+        REGION          region;
+
+        if ((s=getregion(&region)) != TRUE)
+                return (s);
+        if ((lastflag&CFKILL) == 0)             /* This is a kill type  */
+                kdelete();                      /* command, so do magic */
+        thisflag |= CFKILL;                     /* kill buffer stuff.   */
+        curwp->w_dotp = region.r_linep;
+        curwp->w_doto = region.r_offset;
+        return (ldelete(region.r_size, TRUE));
+}
+
+/*
+ * Copy all of the characters in the
+ * region to the kill buffer. Don't move dot
+ * at all. This is a bit like a kill region followed
+ * by a yank. Bound to "M-W".
+ */
+copyregion(f, n)
+{
+        register LINE   *linep;
+        register int    loffs;
+        register int    s;
+        REGION          region;
+
+        if ((s=getregion(&region)) != TRUE)
+                return (s);
+        if ((lastflag&CFKILL) == 0)             /* Kill type command.   */
+                kdelete();
+        thisflag |= CFKILL;
+        linep = region.r_linep;                 /* Current line.        */
+        loffs = region.r_offset;                /* Current offset.      */
+        while (region.r_size--) {
+                if (loffs == llength(linep)) {  /* End of line.         */
+                        if ((s=kinsert('\n')) != TRUE)
+                                return (s);
+                        linep = lforw(linep);
+                        loffs = 0;
+                } else {                        /* Middle of line.      */
+                        if ((s=kinsert(lgetc(linep, loffs))) != TRUE)
+                                return (s);
+                        ++loffs;
+                }
+        }
+        return (TRUE);
+}
+
+/*
+ * Lower case region. Zap all of the upper
+ * case characters in the region to lower case. Use
+ * the region code to set the limits. Scan the buffer,
+ * doing the changes. Call "lchange" to ensure that
+ * redisplay is done in all buffers. Bound to 
+ * "C-X C-L".
+ */
+lowerregion(f, n)
+{
+        register LINE   *linep;
+        register int    loffs;
+        register int    c;
+        register int    s;
+        REGION          region;
+
+        if ((s=getregion(&region)) != TRUE)
+                return (s);
+        lchange(WFHARD);
+        linep = region.r_linep;
+        loffs = region.r_offset;
+        while (region.r_size--) {
+                if (loffs == llength(linep)) {
+                        linep = lforw(linep);
+                        loffs = 0;
+                } else {
+                        c = lgetc(linep, loffs);
+                        if (c>='A' && c<='Z')
+                                lputc(linep, loffs, c+'a'-'A');
+                        ++loffs;
+                }
+        }
+        return (TRUE);
+}
+
+/*
+ * Upper case region. Zap all of the lower
+ * case characters in the region to upper case. Use
+ * the region code to set the limits. Scan the buffer,
+ * doing the changes. Call "lchange" to ensure that
+ * redisplay is done in all buffers. Bound to 
+ * "C-X C-L".
+ */
+upperregion(f, n)
+{
+        register LINE   *linep;
+        register int    loffs;
+        register int    c;
+        register int    s;
+        REGION          region;
+
+        if ((s=getregion(&region)) != TRUE)
+                return (s);
+        lchange(WFHARD);
+        linep = region.r_linep;
+        loffs = region.r_offset;
+        while (region.r_size--) {
+                if (loffs == llength(linep)) {
+                        linep = lforw(linep);
+                        loffs = 0;
+                } else {
+                        c = lgetc(linep, loffs);
+                        if (c>='a' && c<='z')
+                                lputc(linep, loffs, c-'a'+'A');
+                        ++loffs;
+                }
+        }
+        return (TRUE);
+}
+
+/*
+ * This routine figures out the
+ * bounds of the region in the current window, and
+ * fills in the fields of the "REGION" structure pointed
+ * to by "rp". Because the dot and mark are usually very
+ * close together, we scan outward from dot looking for
+ * mark. This should save time. Return a standard code.
+ * Callers of this routine should be prepared to get
+ * an "ABORT" status; we might make this have the
+ * conform thing later.
+ */
+getregion(rp)
+register REGION *rp;
+{
+        register LINE   *flp;
+        register LINE   *blp;
+        register int    fsize;
+        register int    bsize;
+
+        if (curwp->w_markp == NULL) {
+                mlwrite("No mark set in this window");
+                return (FALSE);
+        }
+        if (curwp->w_dotp == curwp->w_markp) {
+                rp->r_linep = curwp->w_dotp;
+                if (curwp->w_doto < curwp->w_marko) {
+                        rp->r_offset = curwp->w_doto;
+                        rp->r_size = curwp->w_marko-curwp->w_doto;
+                } else {
+                        rp->r_offset = curwp->w_marko;
+                        rp->r_size = curwp->w_doto-curwp->w_marko;
+                }
+                return (TRUE);
+        }
+        blp = curwp->w_dotp;
+        bsize = curwp->w_doto;
+        flp = curwp->w_dotp;
+        fsize = llength(flp)-curwp->w_doto+1;
+        while (flp!=curbp->b_linep || lback(blp)!=curbp->b_linep) {
+                if (flp != curbp->b_linep) {
+                        flp = lforw(flp);
+                        if (flp == curwp->w_markp) {
+                                rp->r_linep = curwp->w_dotp;
+                                rp->r_offset = curwp->w_doto;
+                                rp->r_size = fsize+curwp->w_marko;
+                                return (TRUE);
+                        }
+                        fsize += llength(flp)+1;
+                }
+                if (lback(blp) != curbp->b_linep) {
+                        blp = lback(blp);
+                        bsize += llength(blp)+1;
+                        if (blp == curwp->w_markp) {
+                                rp->r_linep = blp;
+                                rp->r_offset = curwp->w_marko;
+                                rp->r_size = bsize - curwp->w_marko;
+                                return (TRUE);
+                        }
+                }
+        }
+        mlwrite("Bug: lost mark");
+        return (FALSE);
+}
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/3rdparty/packages/uemacs/uesearch.c	Sun Feb 23 21:26:32 2003 +0000
@@ -0,0 +1,243 @@
+/*
+ * The functions in this file implement commands that search in the forward
+ * and backward directions. There are no special characters in the search
+ * strings. Probably should have a regular expression search, or something
+ * like that.
+ *
+ * REVISION HISTORY:
+ *
+ * ?    Steve Wilhite, 1-Dec-85
+ *      - massive cleanup on code.
+ */
+
+#include        <stdio.h>
+#include        "ueed.h"
+
+/*
+ * Search forward. Get a search string from the user, and search, beginning at
+ * ".", for the string. If found, reset the "." to be just after the match
+ * string, and [perhaps] repaint the display. Bound to "C-S".
+ */
+forwsearch(f, n)
+    {
+    register LINE *clp;
+    register int cbo;
+    register LINE*tlp;
+    register int tbo;
+    register int c;
+    register char *pp;
+    register int s;
+
+    if ((s = readpattern("Search")) != TRUE)
+        return (s);
+
+    clp = curwp->w_dotp;
+    cbo = curwp->w_doto;
+
+    while (clp != curbp->b_linep)
+        {
+        if (cbo == llength(clp))
+            {
+            clp = lforw(clp);
+            cbo = 0;
+            c = '\n';
+            }
+        else
+            c = lgetc(clp, cbo++);
+
+        if (eq(c, pat[0]) != FALSE)
+            {
+            tlp = clp;
+            tbo = cbo;
+            pp  = &pat[1];
+
+            while (*pp != 0)
+                {
+                if (tlp == curbp->b_linep)
+                    goto fail;
+
+                if (tbo == llength(tlp))
+                    {
+                    tlp = lforw(tlp);
+                    tbo = 0;
+                    c = '\n';
+                    }
+                else
+                    c = lgetc(tlp, tbo++);
+
+                if (eq(c, *pp++) == FALSE)
+                    goto fail;
+                }
+
+            curwp->w_dotp  = tlp;
+            curwp->w_doto  = tbo;
+            curwp->w_flag |= WFMOVE;
+            return (TRUE);
+            }
+fail:;
+        }
+
+    mlwrite("Not found");
+    return (FALSE);
+    }
+
+/*
+ * Reverse search. Get a search string from the user, and search, starting at
+ * "." and proceeding toward the front of the buffer. If found "." is left
+ * pointing at the first character of the pattern [the last character that was
+ j matched]. Bound to "C-R".
+ */
+backsearch(f, n)
+    {
+    register LINE *clp;
+    register int cbo;
+    register LINE *tlp;
+    register int tbo;
+    register int c;
+    register char *epp;
+    register char *pp;
+    register int s;
+
+    if ((s = readpattern("Reverse search")) != TRUE)
+        return (s);
+
+    for (epp = &pat[0]; epp[1] != 0; ++epp)
+        ;
+
+    clp = curwp->w_dotp;
+    cbo = curwp->w_doto;
+
+    for (;;)
+        {
+        if (cbo == 0)
+            {
+            clp = lback(clp);
+
+            if (clp == curbp->b_linep)
+                {
+                mlwrite("Not found");
+                return (FALSE);
+                }
+
+            cbo = llength(clp)+1;
+            }
+
+        if (--cbo == llength(clp))
+            c = '\n';
+        else
+            c = lgetc(clp, cbo);
+
+        if (eq(c, *epp) != FALSE)
+            {
+            tlp = clp;
+            tbo = cbo;
+            pp  = epp;
+
+            while (pp != &pat[0])
+                {
+                if (tbo == 0)
+                    {
+                    tlp = lback(tlp);
+                    if (tlp == curbp->b_linep)
+                        goto fail;
+
+                    tbo = llength(tlp)+1;
+                    }
+
+                if (--tbo == llength(tlp))
+                    c = '\n';
+                else
+                    c = lgetc(tlp, tbo);
+
+                if (eq(c, *--pp) == FALSE)
+                    goto fail;
+                }
+
+            curwp->w_dotp  = tlp;
+            curwp->w_doto  = tbo;
+            curwp->w_flag |= WFMOVE;
+            return (TRUE);
+            }
+fail:;
+        }
+    }
+
+/*
+ * Compare two characters. The "bc" comes from the buffer. It has it's case
+ * folded out. The "pc" is from the pattern.
+ */
+eq(bc, pc)
+    int bc;
+    int pc;
+    {
+    if (bc>='a' && bc<='z')
+        bc -= 0x20;
+
+    if (pc>='a' && pc<='z')
+        pc -= 0x20;
+
+    if (bc == pc)
+        return (TRUE);
+
+    return (FALSE);
+    }
+
+/*
+ * Read a pattern. Stash it in the external variable "pat". The "pat" is not
+ * updated if the user types in an empty line. If the user typed an empty line,
+ * and there is no old pattern, it is an error. Display the old pattern, in the
+ * style of Jeff Lomicka. There is some do-it-yourself control expansion.
+ */
+readpattern(prompt)
+    char *prompt;
+    {
+    register char *cp1;
+    register char *cp2;
+    register int c;
+    register int s;
+    char tpat[NPAT+20];
+
+    cp1 = &tpat[0];                     /* Copy prompt */
+    cp2 = prompt;
+
+    while ((c = *cp2++) != '\0')
+        *cp1++ = c;
+
+    if (pat[0] != '\0')                 /* Old pattern */
+        {
+        *cp1++ = ' ';
+        *cp1++ = '[';
+        cp2 = &pat[0];
+
+        while ((c = *cp2++) != 0)
+            {
+            if (cp1 < &tpat[NPAT+20-6]) /* "??]: \0" */
+                {
+                if (c<0x20 || c==0x7F) {
+                    *cp1++ = '^';
+                    c ^= 0x40;
+                    }
+                else if (c == '%')      /* Map "%" to */
+                    *cp1++ = c;         /* "%%". */
+
+                *cp1++ = c;
+                }
+            }
+
+        *cp1++ = ']';
+        }
+
+    *cp1++ = ':';                       /* Finish prompt */
+    *cp1++ = ' ';
+    *cp1++ = '\0';
+    s = mlreply(tpat, tpat, NPAT);      /* Read pattern */
+
+    if (s == TRUE)                      /* Specified */
+        strcpy(pat, tpat);
+    else if (s == FALSE && pat[0] != 0)         /* CR, but old one */
+        s = TRUE;
+
+    return (s);
+    }
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/3rdparty/packages/uemacs/uespawn.c	Sun Feb 23 21:26:32 2003 +0000
@@ -0,0 +1,256 @@
+/*
+ * The routines in this file are called to create a subjob running a command
+ * interpreter. This code is a big fat nothing on CP/M-86. You lose.
+ */
+#include        <stdio.h>
+#include        "ueed.h"
+
+#ifdef AMIGA
+#define  NEW   1006
+#endif
+
+#ifdef VMS
+#define EFN     0                               /* Event flag.          */
+
+#include        <ssdef.h>                       /* Random headers.      */
+#include        <stsdef.h>
+#include        <descrip.h>
+#include        <iodef.h>
+
+extern  int     oldmode[];                      /* In "termio.c"        */
+extern  int     newmode[];                      /* In "termio.c"        */
+extern  short   iochan;                         /* In "termio.c"        */
+#endif
+
+#ifdef MSDOS
+#include        <dos.h>
+#endif
+
+#ifdef V7
+#include        <signal.h>
+#endif
+
+#ifdef OSK
+#include        <sgstat.h>             
+extern struct  sgbuf  ostate;                   /* In "termio.c" */
+extern struct  sgbuf  nstate;                   /* In "termio.c" */
+#endif
+
+/*
+ * Create a subjob with a copy of the command intrepreter in it. When the
+ * command interpreter exits, mark the screen as garbage so that you do a full
+ * repaint. Bound to "C-C". The message at the start in VMS puts out a newline.
+ * Under some (unknown) condition, you don't get one free when DCL starts up.
+ */
+spawncli(f, n)
+{
+#ifdef AMIGA
+        long newcli;
+
+        newcli = Open("CON:1/1/639/199/MicroEmacs Subprocess", NEW);
+        mlwrite("[Starting new CLI]");
+        sgarbf = TRUE;
+        Execute("", newcli, 0);
+        Close(newcli);
+        return(TRUE);
+#endif
+#ifdef VMS
+        movecursor(term.t_nrow, 0);             /* In last line.        */
+        mlputs("[Starting DCL]\r\n");
+        (*term.t_flush)();                      /* Ignore "ttcol".      */
+        sgarbf = TRUE;
+        return (sys(NULL));                     /* NULL => DCL.         */
+#endif
+#ifdef CPM
+        mlwrite("Not in CP/M-86");
+#endif
+#ifdef MSDOS
+        movecursor(term.t_nrow, 0);             /* Seek to last line.   */
+        (*term.t_flush)();
+        sys("\\command.com", "");               /* Run CLI.             */
+        sgarbf = TRUE;
+        return(TRUE);
+#endif
+#ifdef V7
+        register char *cp;
+        char    *getenv();
+        movecursor(term.t_nrow, 0);             /* Seek to last line.   */
+        (*term.t_flush)();
+        ttclose();                              /* stty to old settings */
+        if ((cp = getenv("SHELL")) != NULL && *cp != '\0')
+                system(cp);
+        else
+                system("exec /bin/sh");
+        sgarbf = TRUE;
+        sleep(2);
+        ttopen();
+        return(TRUE);
+#endif
+#ifdef OSK
+        register char *cp;
+        char    *getenv();
+        movecursor(term.t_nrow, 0);             /* Seek to last line.   */
+        (*term.t_flush)();
+        setstat(0, 0, &ostate);                 /* stty to old settings */
+        if ((cp = getenv("SHELL")) != NULL && *cp != '\0')
+                system(cp);
+        else
+                system("shell");
+        sgarbf = TRUE;
+        setstat(0, 0, &nstate);
+        return(TRUE);
+#endif
+}
+
+/*
+ * Run a one-liner in a subjob. When the command returns, wait for a single
+ * character to be typed, then mark the screen as garbage so a full repaint is
+ * done. Bound to "C-X !".
+ */
+spawn(f, n)
+{
+        register int    s;
+        char            line[NLINE];
+#ifdef AMIGA
+        long newcli;
+
+        newcli = Open("CON:1/1/639/199/MicroEmacs Subprocess", NEW);
+        if ((s=mlreply("CLI command: ", line, NLINE)) != TRUE)
+                return (s);
+        Execute(line,0,newcli);
+        Close(newcli);
+        while ((*term.t_getchar)() != '\r')     /* Pause.               */
+                ;
+        sgarbf = TRUE;
+        return(TRUE);
+#endif
+#ifdef VMS
+        if ((s=mlreply("DCL command: ", line, NLINE)) != TRUE)
+                return (s);
+        (*term.t_putchar)('\n');                /* Already have '\r'    */
+        (*term.t_flush)();
+        s = sys(line);                          /* Run the command.     */
+        mlputs("\r\n\n[End]");                  /* Pause.               */
+        (*term.t_flush)();
+        while ((*term.t_getchar)() != '\r')
+                ;
+        sgarbf = TRUE;
+        return (s);
+#endif
+#ifdef CPM
+        mlwrite("Not in CP/M-86");
+        return (FALSE);
+#endif
+#ifdef MSDOS
+        if ((s=mlreply("MS-DOS command: ", line, NLINE)) != TRUE)
+                return (s);
+        system(line);
+        while ((*term.t_getchar)() != '\r')     /* Pause.               */
+                ;
+        sgarbf = TRUE;
+        return (TRUE);
+#endif
+#ifdef V7
+        if ((s=mlreply("! ", line, NLINE)) != TRUE)
+                return (s);
+        (*term.t_putchar)('\n');                /* Already have '\r'    */
+        (*term.t_flush)();
+        ttclose();                              /* stty to old modes    */
+        system(line);
+        sleep(2);
+        ttopen();
+        mlputs("[End]");                        /* Pause.               */
+        (*term.t_flush)();
+        while ((s = (*term.t_getchar)()) != '\r' && s != ' ')
+                ;
+        sgarbf = TRUE;
+        return (TRUE);
+#endif
+#ifdef OSK
+        if ((s=mlreply("! ", line, NLINE)) != TRUE)
+                return (s);
+        (*term.t_putchar)('\l');                /* Already have '\r'    */
+        (*term.t_flush)();
+        setstat(0, 0, &ostate);                 /* stty to old modes    */
+        s=system(line);
+        setstat(0, 0, &nstate);
+        mlputs("[End]");                        /* Pause.               */
+        (*term.t_flush)();
+        while ((s = (*term.t_getchar)()) != '\r' && s != ' ')
+                ;
+        sgarbf = TRUE;
+        return (TRUE);
+#endif
+}
+
+#ifdef VMS
+/*
+ * Run a command. The "cmd" is a pointer to a command string, or NULL if you
+ * want to run a copy of DCL in the subjob (this is how the standard routine
+ * LIB$SPAWN works. You have to do wierd stuff with the terminal on the way in
+ * and the way out, because DCL does not want the channel to be in raw mode.
+ */
+sys(cmd)
+register char   *cmd;
+{
+        struct  dsc$descriptor  cdsc;
+        struct  dsc$descriptor  *cdscp;
+        long    status;
+        long    substatus;
+        long    iosb[2];
+
+        status = SYS$QIOW(EFN, iochan, IO$_SETMODE, iosb, 0, 0,
+                          oldmode, sizeof(oldmode), 0, 0, 0, 0);
+        if (status!=SS$_NORMAL || (iosb[0]&0xFFFF)!=SS$_NORMAL)
+                return (FALSE);
+        cdscp = NULL;                           /* Assume DCL.          */
+        if (cmd != NULL) {                      /* Build descriptor.    */
+                cdsc.dsc$a_pointer = cmd;
+                cdsc.dsc$w_length  = strlen(cmd);
+                cdsc.dsc$b_dtype   = DSC$K_DTYPE_T;
+                cdsc.dsc$b_class   = DSC$K_CLASS_S;
+                cdscp = &cdsc;
+        }
+        status = LIB$SPAWN(cdscp, 0, 0, 0, 0, 0, &substatus, 0, 0, 0);
+        if (status != SS$_NORMAL)
+                substatus = status;
+        status = SYS$QIOW(EFN, iochan, IO$_SETMODE, iosb, 0, 0,
+                          newmode, sizeof(newmode), 0, 0, 0, 0);
+        if (status!=SS$_NORMAL || (iosb[0]&0xFFFF)!=SS$_NORMAL)
+                return (FALSE);
+        if ((substatus&STS$M_SUCCESS) == 0)     /* Command failed.      */
+                return (FALSE);
+        return (TRUE);
+}
+#endif
+
+#ifdef MSDOS
+/*
+ * This routine, once again by Bob McNamara, is a C translation of the "system"
+ * routine in the MWC-86 run time library. It differs from the "system" routine
+ * in that it does not unconditionally append the string ".exe" to the end of
+ * the command name. We needed to do this because we want to be able to spawn
+ * off "command.com". We really do not understand what it does, but if you don't
+ * do it exactly "malloc" starts doing very very strange things.
+ */
+sys(cmd, tail)
+char    *cmd;
+char    *tail;
+{
+#ifdef MWC_86
+        register unsigned n;
+        extern   char     *__end;
+
+        n = __end + 15;
+        n >>= 4;
+        n = ((n + dsreg() + 16) & 0xFFF0) + 16;
+        return(execall(cmd, tail, n));
+#endif
+
+#ifdef LATTICE
+        return forklp(cmd, tail, NULL);
+#endif
+}
+#endif
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/3rdparty/packages/uemacs/uetcap.c	Sun Feb 23 21:26:32 2003 +0000
@@ -0,0 +1,130 @@
+#include <stdio.h>
+#include "ueed.h"
+
+#ifdef TERMCAP
+
+#define NROW    24
+#define NCOL    80
+#define BEL     0x07
+#define ESC     0x1B
+
+
+extern int      ttopen();
+extern int      ttgetc();
+extern int      ttputc();
+extern int      ttflush();
+extern int      ttclose();
+extern int      tcapmove();
+extern int      tcapeeol();
+extern int      tcapeeop();
+extern int      tcapbeep();
+extern int      tcapopen();
+extern int      tput();
+extern char     *tgoto();
+
+#define TCAPSLEN 315
+
+char tcapbuf[TCAPSLEN];
+char    PC,
+        *CM,
+        *CL,
+        *CE,
+        *UP,
+        *CD;
+
+
+TERM term = {
+        NROW-1,
+        NCOL,
+        &tcapopen,
+        &ttclose,
+        &ttgetc,
+        &ttputc,
+        &ttflush,
+        &tcapmove,
+        &tcapeeol,
+        &tcapeeop,
+        &tcapbeep
+};
+
+tcapopen()
+
+{
+        char *getenv();
+        char *t, *p, *tgetstr();
+        char tcbuf[1024];
+        char *tv_stype;
+        char err_str[72];
+
+        if ((tv_stype = getenv("TERM")) == NULL)
+        {
+                puts("Environment variable TERM not defined!");
+                exit(1);
+        }
+
+        if((tgetent(tcbuf, tv_stype)) != 1)
+        {
+                sprintf(err_str, "Unknown terminal type %s!", tv_stype);
+                puts(err_str);
+                exit(1);
+        }
+
+        p = tcapbuf;
+        t = tgetstr("pc", &p);
+        if(t)
+                PC = *t;
+
+        CD = tgetstr("cd", &p);
+        CM = tgetstr("cm", &p);
+        CE = tgetstr("ce", &p);
+        UP = tgetstr("up", &p);
+
+        if(CD == NULL || CM == NULL || CE == NULL || UP == NULL)
+        {
+                puts("Incomplete termcap entry\n");
+                exit(1);
+        }
+
+        if (p >= &tcapbuf[TCAPSLEN])
+        {
+                puts("Terminal description too big!\n");
+                exit(1);
+        }
+        ttopen();
+}
+tcapmove(row, col)
+register int row, col;
+{
+        putpad(tgoto(CM, col, row));
+}
+
+tcapeeol()
+{
+        putpad(CE);
+}
+
+tcapeeop()
+{
+        putpad(CD);
+
+}
+
+tcapbeep()
+{
+        ttputc(BEL);
+}
+
+putpad(str)
+char    *str;
+{
+        tputs(str, 1, ttputc);
+}
+
+putnpad(str, n)
+char    *str;
+{
+        tputs(str, n, ttputc);
+}
+#endif TERMCAP
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/3rdparty/packages/uemacs/uetermio.c	Sun Feb 23 21:26:32 2003 +0000
@@ -0,0 +1,384 @@
+/*
+ * The functions in this file negotiate with the operating system for
+ * characters, and write characters in a barely buffered fashion on the display.
+ * All operating systems.
+ */
+#include        <stdio.h>
+#include        "ueed.h"
+
+#ifdef AMIGA
+#define NEW 1006
+#define LEN 1
+
+static long terminal;
+#endif
+
+#ifdef VMS
+#include        <stsdef.h>
+#include        <ssdef.h>
+#include        <descrip.h>
+#include        <iodef.h>
+#include        <ttdef.h>
+
+#define NIBUF   128                     /* Input  buffer size           */
+#define NOBUF   1024                    /* MM says bug buffers win!     */
+#define EFN     0                       /* Event flag                   */
+
+
+char    obuf[NOBUF];                    /* Output buffer                */
+int     nobuf;                          /* # of bytes in above          */
+char    ibuf[NIBUF];                    /* Input buffer                 */
+int     nibuf;                          /* # of bytes in above          */
+int     ibufi;                          /* Read index                   */
+int     oldmode[2];                     /* Old TTY mode bits            */
+int     newmode[2];                     /* New TTY mode bits            */
+short   iochan;                         /* TTY I/O channel              */
+#endif
+
+#ifdef CPM
+#include        <bdos.h>
+#endif
+
+#ifdef MSDOS
+#undef  LATTICE
+#include        <dos.h>
+#endif
+
+#ifdef RAINBOW
+#include "rainbow.h"
+#endif
+
+#ifdef V7
+#include        <sgtty.h>               /* for stty/gtty functions */
+
+struct  sgttyb  ostate;                 /* saved tty state */
+struct  sgttyb  nstate;                 /* values for editor mode */
+#endif
+
+#ifdef OS9
+#include        <sgstat.h>               /* for stty/gtty functions */
+struct  sgbuf  ostate;                 /* saved tty state */
+struct  sgbuf  nstate;                 /* values for editor mode */
+#endif
+
+#ifdef OSK
+#include        <sgstat.h>             /* same as os9/6809 */
+struct  sgbuf  ostate;
+struct  sgbuf  nstate;
+#endif
+
+/*
+ * This function is called once to set up the terminal device streams.
+ * On VMS, it translates SYS$INPUT until it finds the terminal, then assigns
+ * a channel to it and sets it raw. On CPM it is a no-op.
+ */
+ttopen()
+{
+#ifdef AMIGA
+        terminal = Open("RAW:1/1/639/199/MicroEmacs", NEW);
+#endif
+#ifdef VMS
+        struct  dsc$descriptor  idsc;
+        struct  dsc$descriptor  odsc;
+        char    oname[40];
+        int     iosb[2];
+        int     status;
+
+        odsc.dsc$a_pointer = "SYS$INPUT";
+        odsc.dsc$w_length  = strlen(odsc.dsc$a_pointer);
+        odsc.dsc$b_dtype   = DSC$K_DTYPE_T;
+        odsc.dsc$b_class   = DSC$K_CLASS_S;
+        idsc.dsc$b_dtype   = DSC$K_DTYPE_T;
+        idsc.dsc$b_class   = DSC$K_CLASS_S;
+        do {
+                idsc.dsc$a_pointer = odsc.dsc$a_pointer;
+                idsc.dsc$w_length  = odsc.dsc$w_length;
+                odsc.dsc$a_pointer = &oname[0];
+                odsc.dsc$w_length  = sizeof(oname);
+                status = LIB$SYS_TRNLOG(&idsc, &odsc.dsc$w_length, &odsc);
+                if (status!=SS$_NORMAL && status!=SS$_NOTRAN)
+                        exit(status);
+                if (oname[0] == 0x1B) {
+                        odsc.dsc$a_pointer += 4;
+                        odsc.dsc$w_length  -= 4;
+                }
+        } while (status == SS$_NORMAL);
+        status = SYS$ASSIGN(&odsc, &iochan, 0, 0);
+        if (status != SS$_NORMAL)
+                exit(status);
+        status = SYS$QIOW(EFN, iochan, IO$_SENSEMODE, iosb, 0, 0,
+                          oldmode, sizeof(oldmode), 0, 0, 0, 0);
+        if (status!=SS$_NORMAL || (iosb[0]&0xFFFF)!=SS$_NORMAL)
+                exit(status);
+        newmode[0] = oldmode[0];
+        newmode[1] = oldmode[1] | TT$M_PASSALL | TT$M_NOECHO;
+        status = SYS$QIOW(EFN, iochan, IO$_SETMODE, iosb, 0, 0,
+                          newmode, sizeof(newmode), 0, 0, 0, 0);
+        if (status!=SS$_NORMAL || (iosb[0]&0xFFFF)!=SS$_NORMAL)
+                exit(status);
+#endif
+#ifdef CPM
+#endif
+#ifdef MSDOS
+#endif
+#ifdef V7
+        gtty(1, &ostate);                       /* save old state */
+        gtty(1, &nstate);                       /* get base of new state */
+        nstate.sg_flags |= RAW;
+        nstate.sg_flags &= ~(ECHO|CRMOD);       /* no echo for now... */
+        stty(1, &nstate);                       /* set mode */
+#endif
+#ifdef OS9
+        getstat(0, 0, &ostate);                       /* save old state */
+        getstat(0, 0, &nstate);                       /* get base of new state *
+/
+        nstate.sg_echo = 0;       /* no echo for now... */
+        nstate.sg_bellch = 0;
+        nstate.sg_bsech = 0;
+        nstate.sg_kbach = 0;
+        nstate.sg_kbich = 0;
+        nstate.sg_psch = 0;
+        nstate.sg_dulnch = 0;
+        nstate.sg_rlnch = 0;
+        nstate.sg_eofch = 0;
+        nstate.sg_eorch = 0;
+        nstate.sg_dlnch = 0;
+        nstate.sg_bspch = 0;
+        nstate.sg_pause = 0;
+        nstate.sg_alf = 0;
+        nstate.sg_backsp = 0;
+        setstat(0, 0, &nstate);                       /* set mode */
+        stdin->_flag &= ~_SCF;
+        stdin->_flag |= _RBF;
+        stdout->_flag &= ~_SCF;
+        stdout->_flag |= _RBF;
+        setbuf(stdout,0);
+#endif
+#ifdef OSK
+        getstat(0, 0, &ostate);                       /* save old state */
+        getstat(0, 0, &nstate);                       /* get base of new state *
+/
+        nstate.sg_echo = 0;       /* no echo for now... */
+        nstate.sg_bellch = 0;
+        nstate.sg_bsech = 0;
+        nstate.sg_kbach = 0;
+
+        nstate.sg_kbich = 0;
+        nstate.sg_psch = 0;
+        nstate.sg_dulnch = 0;
+        nstate.sg_rlnch = 0;
+        nstate.sg_eofch = 0;
+        nstate.sg_eorch = 0;
+        nstate.sg_dlnch = 0;
+        nstate.sg_bspch = 0;
+        nstate.sg_pause = 0;
+        nstate.sg_alf = 0;
+        nstate.sg_backsp = 0;
+        nstate.sg_xoff =0;     /* new for OSK */
+        nstate.sg_xon  =0;
+        setstat(0, 0, &nstate);                       /* set mode */
+        stdin->_flag &= ~_SCF;
+        stdin->_flag |= _RBF;
+        stdout->_flag &= ~_SCF;
+        stdout->_flag |= _RBF;
+        setbuf(stdout,0);
+#endif
+}
+
+/*
+ * This function gets called just before we go back home to the command
+ * interpreter. On VMS it puts the terminal back in a reasonable state.
+ * Another no-operation on CPM.
+ */
+ttclose()
+{
+#ifdef AMIGA
+        Close(terminal);
+#endif
+#ifdef VMS
+        int     status;
+        int     iosb[1];
+
+        ttflush();
+        status = SYS$QIOW(EFN, iochan, IO$_SETMODE, iosb, 0, 0,
+                 oldmode, sizeof(oldmode), 0, 0, 0, 0);
+        if (status!=SS$_NORMAL || (iosb[0]&0xFFFF)!=SS$_NORMAL)
+                exit(status);
+        status = SYS$DASSGN(iochan);
+        if (status != SS$_NORMAL)
+                exit(status);
+#endif
+#ifdef CPM
+#endif
+#ifdef MSDOS
+#endif
+#ifdef V7
+        stty(1, &ostate);
+#endif
+#ifdef OS9
+        setstat(0, 0, &ostate);
+#endif
+#ifdef OSK
+        setstat(0, 0, &ostate);
+#endif
+}
+
+/*
+ * Write a character to the display. On VMS, terminal output is buffered, and
+ * we just put the characters in the big array, after checking for overflow.
+ * On CPM terminal I/O unbuffered, so we just write the byte out. Ditto on
+ * MS-DOS (use the very very raw console output routine).
+ */
+ttputc(c)
+char c;
+{
+#ifdef AMIGA
+        Write(terminal, &c, LEN);
+#endif
+#ifdef VMS
+        if (nobuf >= NOBUF)
+                ttflush();
+        obuf[nobuf++] = c;
+#endif
+
+#ifdef CPM
+        bios(BCONOUT, c, 0);
+#endif
+
+#ifdef MSDOS & CWC86
+        dosb(CONDIO, c, 0);
+#endif
+
+#ifdef RAINBOW
+        Put_Char(c);                    /* fast video */
+#endif
+
+#ifdef V7
+        fputc(c, stdout);
+#endif
+#ifdef OS9
+        putc(c, stdout);
+#endif
+#ifdef OSK
+        putc(c, stdout);
+#endif
+}
+
+/*
+ * Flush terminal buffer. Does real work where the terminal output is buffered
+ * up. A no-operation on systems where byte at a time terminal I/O is done.
+ */
+ttflush()
+{
+#ifdef AMIGA
+#endif
+#ifdef VMS
+        int     status;
+        int     iosb[2];
+
+        status = SS$_NORMAL;
+        if (nobuf != 0) {
+                status = SYS$QIOW(EFN, iochan, IO$_WRITELBLK|IO$M_NOFORMAT,
+                         iosb, 0, 0, obuf, nobuf, 0, 0, 0, 0);
+                if (status == SS$_NORMAL)
+                        status = iosb[0] & 0xFFFF;
+                nobuf = 0;
+        }
+        return (status);
+#endif
+#ifdef CPM
+#endif
+#ifdef MSDOS
+#endif
+#ifdef V7
+        fflush(stdout);
+#endif
+#ifdef OS9
+        fflush(stdout);
+#endif
+#ifdef OSK
+        fflush(stdout);
+#endif
+}
+
+/*
+ * Read a character from the terminal, performing no editing and doing no echo
+ * at all. More complex in VMS that almost anyplace else, which figures. Very
+ * simple on CPM, because the system can do exactly what you want.
+ */
+ttgetc()
+{
+#ifdef AMIGA
+        char ch;
+
+        Read(terminal, &ch, LEN);
+        return (int) ch;
+#endif
+#ifdef VMS
+        int     status;
+        int     iosb[2];
+        int     term[2];
+
+        while (ibufi >= nibuf) {
+                ibufi = 0;
+                term[0] = 0;
+                term[1] = 0;
+                status = SYS$QIOW(EFN, iochan, IO$_READLBLK|IO$M_TIMED,
+                         iosb, 0, 0, ibuf, NIBUF, 0, term, 0, 0);
+                if (status != SS$_NORMAL)
+                        exit(status);
+                status = iosb[0] & 0xFFFF;
+                if (status!=SS$_NORMAL && status!=SS$_TIMEOUT)
+                        exit(status);
+                nibuf = (iosb[0]>>16) + (iosb[1]>>16);
+                if (nibuf == 0) {
+                        status = SYS$QIOW(EFN, iochan, IO$_READLBLK,
+                                 iosb, 0, 0, ibuf, 1, 0, term, 0, 0);
+                        if (status != SS$_NORMAL
+                        || (status = (iosb[0]&0xFFFF)) != SS$_NORMAL)
+                                exit(status);
+                        nibuf = (iosb[0]>>16) + (iosb[1]>>16);
+                }
+        }
+        return (ibuf[ibufi++] & 0xFF);          /* Allow multinational  */
+#endif
+
+#ifdef CPM
+        return (biosb(BCONIN, 0, 0));
+#endif
+
+#ifdef RAINBOW
+        int Ch;
+
+        while ((Ch = Read_Keyboard()) < 0);
+
+        if ((Ch & Function_Key) == 0)
+                if (!((Ch & 0xFF) == 015 || (Ch & 0xFF) == 0177))
+                        Ch &= 0xFF;
+
+        return Ch;
+#endif
+
+#ifdef MSDOS
+#ifdef MWC86
+        return (dosb(CONRAW, 0, 0));
+#endif
+#endif
+
+#ifdef V7
+        return(fgetc(stdin));
+#endif
+#ifdef OS9
+    char ch;
+
+        read(0, &ch, 1);
+        return((int)ch);
+#endif
+#ifdef OSK
+    char ch;
+
+        read(0, &ch, 1);
+        return((int)ch);
+#endif
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/3rdparty/packages/uemacs/uevt52.c	Sun Feb 23 21:26:32 2003 +0000
@@ -0,0 +1,99 @@
+/*
+ * The routines in this file
+ * provide support for VT52 style terminals
+ * over a serial line. The serial I/O services are
+ * provided by routines in "termio.c". It compiles
+ * into nothing if not a VT52 style device. The
+ * bell on the VT52 is terrible, so the "beep"
+ * routine is conditionalized on defining BEL.
+ */
+#include        <stdio.h>
+#include        "ueed.h"
+
+#ifdef VT52
+
+#define NROW    24                      /* Screen size.                 */
+#define NCOL    80                      /* Edit if you want to.         */
+#define BIAS    0x20                    /* Origin 0 coordinate bias.    */
+#define ESC     0x1B                    /* ESC character.               */
+#define BEL     0x07                    /* ascii bell character         */
+
+extern  int     ttopen();               /* Forward references.          */
+extern  int     ttgetc();
+extern  int     ttputc();
+extern  int     ttflush();
+extern  int     ttclose();
+extern  int     vt52move();
+extern  int     vt52eeol();
+extern  int     vt52eeop();
+extern  int     vt52beep();
+extern  int     vt52open();
+
+/*
+ * Dispatch table. All the
+ * hard fields just point into the
+ * terminal I/O code.
+ */
+TERM    term    = {
+        NROW-1,
+        NCOL,
+        vt52open,
+        ttclose,
+        ttgetc,
+        ttputc,
+        ttflush,
+        vt52move,
+        vt52eeol,
+        vt52eeop,
+        vt52beep
+};
+
+vt52move(row, col)
+{
+        ttputc(ESC);
+        ttputc('Y');
+        ttputc(row+BIAS);
+        ttputc(col+BIAS);
+}
+
+vt52eeol()
+{
+        ttputc(ESC);
+        ttputc('K');
+}
+
+vt52eeop()
+{
+        ttputc(ESC);
+        ttputc('J');
+}
+
+vt52beep()
+{
+#ifdef  BEL
+        ttputc(BEL);
+        ttflush();
+#endif
+}
+
+#endif
+
+vt52open()
+{
+#ifdef V7
+        register char *cp;
+        char *getenv();
+
+        if ((cp = getenv("TERM")) == NULL) {
+                puts("Shell variable TERM not defined!");
+                exit(1);
+        }
+        if (strcmp(cp, "vt52") != 0 && strcmp(cp, "z19") != 0) {
+                puts("Terminal type not 'vt52'or 'z19' !");
+                exit(1);
+        }
+#endif
+        ttopen();
+}
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/3rdparty/packages/uemacs/uewindow.c	Sun Feb 23 21:26:32 2003 +0000
@@ -0,0 +1,381 @@
+/*
+ * Window management. Some of the functions are internal, and some are
+ * attached to keys that the user actually types.
+ */
+
+#include        <stdio.h>
+#include        "ueed.h"
+
+/*
+ * Reposition dot in the current window to line "n". If the argument is
+ * positive, it is that line. If it is negative it is that line from the
+ * bottom. If it is 0 the window is centered (this is what the standard
+ * redisplay code does). With no argument it defaults to 1. Bound to M-!.
+ * Because of the default, it works like in Gosling.
+ */
+reposition(f, n)
+    {
+    curwp->w_force = n;
+    curwp->w_flag |= WFFORCE;
+    return (TRUE);
+    }
+
+/*
+ * Refresh the screen. With no argument, it just does the refresh. With an
+ * argument it recenters "." in the current window. Bound to "C-L".
+ */
+refresh(f, n)
+    {
+    if (f == FALSE)
+        sgarbf = TRUE;
+    else
+        {
+        curwp->w_force = 0;             /* Center dot. */
+        curwp->w_flag |= WFFORCE;
+        }
+
+    return (TRUE);
+    }
+
+#ifndef OS9
+/*
+ * The command make the next window (next => down the screen) the current
+ * window. There are no real errors, although the command does nothing if
+ * there is only 1 window on the screen. Bound to "C-X C-N".
+ */
+nextwind(f, n)
+    {
+    register WINDOW *wp;
+
+    if ((wp = curwp->w_wndp) == NULL)
+        wp = wheadp;
+
+    curwp = wp;
+    curbp = wp->w_bufp;
+    return (TRUE);
+    }
+
+/*
+ * This command makes the previous window (previous => up the screen) the
+ * current window. There arn't any errors, although the command does not do a
+ * lot if there is 1 window.
+ */
+prevwind(f, n)
+    {
+    register WINDOW *wp1;
+    register WINDOW *wp2;
+
+    wp1 = wheadp;
+
+    wp2 = curwp;
+
+    if (wp1 == wp2)
+        wp2 = NULL;
+
+    while (wp1->w_wndp != wp2)
+        wp1 = wp1->w_wndp;
+
+    curwp = wp1;
+    curbp = wp1->w_bufp;
+    return (TRUE);
+    }
+
+/*
+ * This command moves the current window down by "arg" lines. Recompute the
+ * top line in the window. The move up and move down code is almost completely
+ * the same; most of the work has to do with reframing the window, and picking
+ * a new dot. We share the code by having "move down" just be an interface to
+ * "move up". Magic. Bound to "C-X C-N".
+ */
+mvdnwind(f, n)
+    int n;
+    {
+    return (mvupwind(f, -n));
+    }
+
+/*
+ * Move the current window up by "arg" lines. Recompute the new top line of
+ * the window. Look to see if "." is still on the screen. If it is, you win.
+ * If it isn't, then move "." to center it in the new framing of the window
+ * (this command does not really move "."; it moves the frame). Bound to
+ * "C-X C-P".
+ */
+mvupwind(f, n)
+    int n;
+    {
+    register LINE *lp;
+    register int i;
+
+    lp = curwp->w_linep;
+
+    if (n < 0)
+        {
+        while (n++ && lp!=curbp->b_linep)
+            lp = lforw(lp);
+        }
+    else
+        {
+        while (n-- && lback(lp)!=curbp->b_linep)
+            lp = lback(lp);
+        }
+
+    curwp->w_linep = lp;
+    curwp->w_flag |= WFHARD;            /* Mode line is OK. */
+
+    for (i = 0; i < curwp->w_ntrows; ++i)
+        {
+        if (lp == curwp->w_dotp)
+            return (TRUE);
+        if (lp == curbp->b_linep)
+            break;
+        lp = lforw(lp);
+        }
+
+    lp = curwp->w_linep;
+    i  = curwp->w_ntrows/2;
+
+    while (i-- && lp != curbp->b_linep)
+        lp = lforw(lp);
+
+    curwp->w_dotp  = lp;
+    curwp->w_doto  = 0;
+    return (TRUE);
+    }
+
+/*
+ * This command makes the current window the only window on the screen. Bound
+ * to "C-X 1". Try to set the framing so that "." does not have to move on the
+ * display. Some care has to be taken to keep the values of dot and mark in
+ * the buffer structures right if the distruction of a window makes a buffer
+ * become undisplayed.
+ */
+onlywind(f, n)
+{
+        register WINDOW *wp;
+        register LINE   *lp;
+        register int    i;
+
+        while (wheadp != curwp) {
+                wp = wheadp;
+                wheadp = wp->w_wndp;
+                if (--wp->w_bufp->b_nwnd == 0) {
+                        wp->w_bufp->b_dotp  = wp->w_dotp;
+                        wp->w_bufp->b_doto  = wp->w_doto;
+                        wp->w_bufp->b_markp = wp->w_markp;
+                        wp->w_bufp->b_marko = wp->w_marko;
+                }
+                free((char *) wp);
+        }
+        while (curwp->w_wndp != NULL) {
+                wp = curwp->w_wndp;
+                curwp->w_wndp = wp->w_wndp;
+                if (--wp->w_bufp->b_nwnd == 0) {
+                        wp->w_bufp->b_dotp  = wp->w_dotp;
+                        wp->w_bufp->b_doto  = wp->w_doto;
+                        wp->w_bufp->b_markp = wp->w_markp;
+                        wp->w_bufp->b_marko = wp->w_marko;
+                }
+                free((char *) wp);
+        }
+        lp = curwp->w_linep;
+        i  = curwp->w_toprow;
+        while (i!=0 && lback(lp)!=curbp->b_linep) {
+                --i;
+                lp = lback(lp);
+        }
+        curwp->w_toprow = 0;
+        curwp->w_ntrows = term.t_nrow-1;
+        curwp->w_linep  = lp;
+        curwp->w_flag  |= WFMODE|WFHARD;
+        return (TRUE);
+}
+
+/*
+ * Split the current window. A window smaller than 3 lines cannot be split.
+ * The only other error that is possible is a "malloc" failure allocating the
+ * structure for the new window. Bound to "C-X 2".
+ */
+splitwind(f, n)
+{
+        register WINDOW *wp;
+        register LINE   *lp;
+        register int    ntru;
+        register int    ntrl;
+        register int    ntrd;
+        register WINDOW *wp1;
+        register WINDOW *wp2;
+
+        if (curwp->w_ntrows < 3) {
+                mlwrite("Cannot split a %d line window", curwp->w_ntrows);
+                return (FALSE);
+        }
+        if ((wp = (WINDOW *) malloc(sizeof(WINDOW))) == NULL) {
+                mlwrite("Cannot allocate WINDOW block");
+                return (FALSE);
+        }
+        ++curbp->b_nwnd;                        /* Displayed twice.     */
+        wp->w_bufp  = curbp;
+        wp->w_dotp  = curwp->w_dotp;
+        wp->w_doto  = curwp->w_doto;
+        wp->w_markp = curwp->w_markp;
+        wp->w_marko = curwp->w_marko;
+        wp->w_flag  = 0;
+        wp->w_force = 0;
+        ntru = (curwp->w_ntrows-1) / 2;         /* Upper size           */
+        ntrl = (curwp->w_ntrows-1) - ntru;      /* Lower size           */
+        lp = curwp->w_linep;
+        ntrd = 0;
+        while (lp != curwp->w_dotp) {
+                ++ntrd;
+                lp = lforw(lp);
+        }
+        lp = curwp->w_linep;
+        if (ntrd <= ntru) {                     /* Old is upper window. */
+                if (ntrd == ntru)               /* Hit mode line.       */
+                        lp = lforw(lp);
+                curwp->w_ntrows = ntru;
+                wp->w_wndp = curwp->w_wndp;
+                curwp->w_wndp = wp;
+                wp->w_toprow = curwp->w_toprow+ntru+1;
+                wp->w_ntrows = ntrl;
+        } else {                                /* Old is lower window  */
+                wp1 = NULL;
+                wp2 = wheadp;
+                while (wp2 != curwp) {
+                        wp1 = wp2;
+                        wp2 = wp2->w_wndp;
+                }
+                if (wp1 == NULL)
+                        wheadp = wp;
+                else
+                        wp1->w_wndp = wp;
+                wp->w_wndp   = curwp;
+                wp->w_toprow = curwp->w_toprow;
+                wp->w_ntrows = ntru;
+                ++ntru;                         /* Mode line.           */
+                curwp->w_toprow += ntru;
+                curwp->w_ntrows  = ntrl;
+                while (ntru--)
+                        lp = lforw(lp);
+        }
+        curwp->w_linep = lp;                    /* Adjust the top lines */
+        wp->w_linep = lp;                       /* if necessary.        */
+        curwp->w_flag |= WFMODE|WFHARD;
+        wp->w_flag |= WFMODE|WFHARD;
+
+        return (TRUE);
+}
+
+/*
+ * Enlarge the current window. Find the window that loses space. Make sure it
+ * is big enough. If so, hack the window descriptions, and ask redisplay to do
+ * all the hard work. You don't just set "force reframe" because dot would
+ * move. Bound to "C-X Z".
+ */
+enlargewind(f, n)
+{
+        register WINDOW *adjwp;
+        register LINE   *lp;
+        register int    i;
+
+        if (n < 0)
+                return (shrinkwind(f, -n));
+        if (wheadp->w_wndp == NULL) {
+                mlwrite("Only one window");
+                return (FALSE);
+        }
+        if ((adjwp=curwp->w_wndp) == NULL) {
+                adjwp = wheadp;
+                while (adjwp->w_wndp != curwp)
+                        adjwp = adjwp->w_wndp;
+        }
+        if (adjwp->w_ntrows <= n) {
+                mlwrite("Impossible change");
+                return (FALSE);
+        }
+        if (curwp->w_wndp == adjwp) {           /* Shrink below.        */
+                lp = adjwp->w_linep;
+                for (i=0; i<n && lp!=adjwp->w_bufp->b_linep; ++i)
+                        lp = lforw(lp);
+                adjwp->w_linep  = lp;
+                adjwp->w_toprow += n;
+        } else {                                /* Shrink above.        */
+                lp = curwp->w_linep;
+                for (i=0; i<n && lback(lp)!=curbp->b_linep; ++i)
+                        lp = lback(lp);
+                curwp->w_linep  = lp;
+                curwp->w_toprow -= n;
+        }
+        curwp->w_ntrows += n;
+        adjwp->w_ntrows -= n;
+        curwp->w_flag |= WFMODE|WFHARD;
+        adjwp->w_flag |= WFMODE|WFHARD;
+        return (TRUE);
+}
+
+/*
+ * Shrink the current window. Find the window that gains space. Hack at the
+ * window descriptions. Ask the redisplay to do all the hard work. Bound to
+ * "C-X C-Z".
+ */
+shrinkwind(f, n)
+{
+        register WINDOW *adjwp;
+        register LINE   *lp;
+        register int    i;
+
+        if (n < 0)
+                return (enlargewind(f, -n));
+        if (wheadp->w_wndp == NULL) {
+                mlwrite("Only one window");
+                return (FALSE);
+        }
+        if ((adjwp=curwp->w_wndp) == NULL) {
+                adjwp = wheadp;
+                while (adjwp->w_wndp != curwp)
+                        adjwp = adjwp->w_wndp;
+        }
+        if (curwp->w_ntrows <= n) {
+                mlwrite("Impossible change");
+                return (FALSE);
+        }
+        if (curwp->w_wndp == adjwp) {           /* Grow below.          */
+                lp = adjwp->w_linep;
+                for (i=0; i<n && lback(lp)!=adjwp->w_bufp->b_linep; ++i)
+                        lp = lback(lp);
+                adjwp->w_linep  = lp;
+                adjwp->w_toprow -= n;
+        } else {                                /* Grow above.          */
+                lp = curwp->w_linep;
+                for (i=0; i<n && lp!=curbp->b_linep; ++i)
+                        lp = lforw(lp);
+                curwp->w_linep  = lp;
+                curwp->w_toprow += n;
+        }
+        curwp->w_ntrows -= n;
+        adjwp->w_ntrows += n;
+        curwp->w_flag |= WFMODE|WFHARD;
+        adjwp->w_flag |= WFMODE|WFHARD;
+        return (TRUE);
+}
+
+/*
+ * Pick a window for a pop-up. Split the screen if there is only one window.
+ * Pick the uppermost window that isn't the current window. An LRU algorithm
+ * might be better. Return a pointer, or NULL on error.
+ */
+WINDOW  *
+wpopup()
+{
+        register WINDOW *wp;
+
+        if (wheadp->w_wndp == NULL              /* Only 1 window        */
+        && splitwind(FALSE, 0) == FALSE)        /* and it won't split   */
+                return (NULL);
+        wp = wheadp;                            /* Find window to use   */
+        while (wp!=NULL && wp==curwp)
+                wp = wp->w_wndp;
+        return (wp);
+}
+#endif
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/3rdparty/packages/uemacs/ueword.c	Sun Feb 23 21:26:32 2003 +0000
@@ -0,0 +1,274 @@
+/*
+ * The routines in this file implement commands that work word at a time.
+ * There are all sorts of word mode commands. If I do any sentence and/or
+ * paragraph mode commands, they are likely to be put in this file.
+ */
+
+#include        <stdio.h>
+#include        "ueed.h"
+
+
+/* Word wrap on n-spaces. Back-over whatever precedes the point on the current
+ * line and stop on the first word-break or the beginning of the line. If we
+ * reach the beginning of the line, jump back to the end of the word and start
+ * a new line.  Otherwise, break the line at the word-break, eat it, and jump
+ * back to the end of the word.
+ *      NOTE:  This function may leaving trailing blanks.
+ * Returns TRUE on success, FALSE on errors.
+ */
+wrapword(n)
+int n;
+{
+        register int cnt, oldp;
+        oldp = curwp->w_dotp;
+        cnt = -1;
+        do {                            
+                cnt++;
+                if (! backchar(NULL, 1))
+                        return(FALSE);
+        }
+        while (! inword());
+        if (! backword(NULL, 1))
+                return(FALSE);
+        if (oldp == (int) (curwp->w_dotp && curwp->w_doto)) {
+                if (! backdel(NULL, 1))
+                        return(FALSE);
+                if (! newline(NULL, 1))
+                        return(FALSE);
+        }
+        return(forwword(NULL, 1) && forwchar(NULL, cnt));
+}
+                                
+/*
+ * Move the cursor backward by "n" words. All of the details of motion are
+ * performed by the "backchar" and "forwchar" routines. Error if you try to
+ * move beyond the buffers.
+ */
+backword(f, n)
+{
+        if (n < 0)
+                return (forwword(f, -n));
+        if (backchar(FALSE, 1) == FALSE)
+                return (FALSE);
+        while (n--) {
+                while (inword() == FALSE) {
+                        if (backchar(FALSE, 1) == FALSE)
+                                return (FALSE);
+                }
+                while (inword() != FALSE) {
+                        if (backchar(FALSE, 1) == FALSE)
+                                return (FALSE);
+                }
+        }
+        return (forwchar(FALSE, 1));
+}
+
+/*
+ * Move the cursor forward by the specified number of words. All of the motion
+ * is done by "forwchar". Error if you try and move beyond the buffer's end.
+ */
+forwword(f, n)
+{
+        if (n < 0)
+                return (backword(f, -n));
+        while (n--) {
+                while (inword() == FALSE) {
+                        if (forwchar(FALSE, 1) == FALSE)
+                                return (FALSE);
+                }
+                while (inword() != FALSE) {
+                        if (forwchar(FALSE, 1) == FALSE)
+                                return (FALSE);
+                }
+        }
+        return (TRUE);
+}
+
+/*
+ * Move the cursor forward by the specified number of words. As you move,
+ * convert any characters to upper case. Error if you try and move beyond the
+ * end of the buffer. Bound to "M-U".
+ */
+upperword(f, n)
+{
+        register int    c;
+
+        if (n < 0)
+                return (FALSE);
+        while (n--) {
+                while (inword() == FALSE) {
+                        if (forwchar(FALSE, 1) == FALSE)
+                                return (FALSE);
+                }
+                while (inword() != FALSE) {
+                        c = lgetc(curwp->w_dotp, curwp->w_doto);
+                        if (c>='a' && c<='z') {
+                                c -= 'a'-'A';
+                                lputc(curwp->w_dotp, curwp->w_doto, c);
+                                lchange(WFHARD);
+                        }
+                        if (forwchar(FALSE, 1) == FALSE)
+                                return (FALSE);
+                }
+        }
+        return (TRUE);
+}
+
+/*
+ * Move the cursor forward by the specified number of words. As you move
+ * convert characters to lower case. Error if you try and move over the end of
+ * the buffer. Bound to "M-L".
+ */
+lowerword(f, n)
+{
+        register int    c;
+
+        if (n < 0)
+                return (FALSE);
+        while (n--) {
+                while (inword() == FALSE) {
+                        if (forwchar(FALSE, 1) == FALSE)
+                                return (FALSE);
+                }
+                while (inword() != FALSE) {
+                        c = lgetc(curwp->w_dotp, curwp->w_doto);
+                        if (c>='A' && c<='Z') {
+                                c += 'a'-'A';
+                                lputc(curwp->w_dotp, curwp->w_doto, c);
+                                lchange(WFHARD);
+                        }
+                        if (forwchar(FALSE, 1) == FALSE)
+                                return (FALSE);
+                }
+        }
+        return (TRUE);
+}
+
+/*
+ * Move the cursor forward by the specified number of words. As you move
+ * convert the first character of the word to upper case, and subsequent
+ * characters to lower case. Error if you try and move past the end of the
+ * buffer. Bound to "M-C".
+ */
+capword(f, n)
+{
+        register int    c;
+
+        if (n < 0)
+                return (FALSE);
+        while (n--) {
+                while (inword() == FALSE) {
+                        if (forwchar(FALSE, 1) == FALSE)
+                                return (FALSE);
+                }
+                if (inword() != FALSE) {
+                        c = lgetc(curwp->w_dotp, curwp->w_doto);
+                        if (c>='a' && c<='z') {
+                                c -= 'a'-'A';
+                                lputc(curwp->w_dotp, curwp->w_doto, c);
+                                lchange(WFHARD);
+                        }
+                        if (forwchar(FALSE, 1) == FALSE)
+                                return (FALSE);
+                        while (inword() != FALSE) {
+                                c = lgetc(curwp->w_dotp, curwp->w_doto);
+                                if (c>='A' && c<='Z') {
+                                        c += 'a'-'A';
+                                        lputc(curwp->w_dotp, curwp->w_doto, c);
+                                        lchange(WFHARD);
+                                }
+                                if (forwchar(FALSE, 1) == FALSE)
+                                        return (FALSE);
+                        }
+                }
+        }
+        return (TRUE);
+}
+
+/*
+ * Kill forward by "n" words. Remember the location of dot. Move forward by
+ * the right number of words. Put dot back where it was and issue the kill
+ * command for the right number of characters. Bound to "M-D".
+ */
+delfword(f, n)
+{
+        register int    size;
+        register LINE   *dotp;
+        register int    doto;
+
+        if (n < 0)
+                return (FALSE);
+        dotp = curwp->w_dotp;
+        doto = curwp->w_doto;
+        size = 0;
+        while (n--) {
+                while (inword() == FALSE) {
+                        if (forwchar(FALSE, 1) == FALSE)
+                                return (FALSE);
+                        ++size;
+                }
+                while (inword() != FALSE) {
+                        if (forwchar(FALSE, 1) == FALSE)
+                                return (FALSE);
+                        ++size;
+
+                }
+        }
+        curwp->w_dotp = dotp;
+        curwp->w_doto = doto;
+        return (ldelete(size, TRUE));
+}
+
+/*
+ * Kill backwards by "n" words. Move backwards by the desired number of words,
+ * counting the characters. When dot is finally moved to its resting place,
+ * fire off the kill command. Bound to "M-Rubout" and to "M-Backspace".
+ */
+delbword(f, n)
+{
+        register int    size;
+
+        if (n < 0)
+                return (FALSE);
+        if (backchar(FALSE, 1) == FALSE)
+                return (FALSE);
+        size = 0;
+        while (n--) {
+                while (inword() == FALSE) {
+                        if (backchar(FALSE, 1) == FALSE)
+                                return (FALSE);
+                        ++size;
+                }
+                while (inword() != FALSE) {
+                        if (backchar(FALSE, 1) == FALSE)
+                                return (FALSE);
+                        ++size;
+                }
+        }
+        if (forwchar(FALSE, 1) == FALSE)
+                return (FALSE);
+        return (ldelete(size, TRUE));
+}
+
+/*
+ * Return TRUE if the character at dot is a character that is considered to be
+ * part of a word. The word character list is hard coded. Should be setable.
+ */
+inword()
+{
+        register int    c;
+
+        if (curwp->w_doto == llength(curwp->w_dotp))
+                return (FALSE);
+        c = lgetc(curwp->w_dotp, curwp->w_doto);
+        if (c>='a' && c<='z')
+                return (TRUE);
+        if (c>='A' && c<='Z')
+                return (TRUE);
+        if (c>='0' && c<='9')
+                return (TRUE);
+        if (c=='$' || c=='_')                   /* For identifiers      */
+                return (TRUE);
+        return (FALSE);
+}
+