[comp.sources.amiga] DME v1.28f, part 1 of 2

afb@j.cc.purdue.edu.UUCP (11/20/87)

This is the first part of the sources for Matt Dillon's editor,
DME.  See comp.binaries.amiga for documentation, which is not
included here to save net.traffic.  I was unable to compile
this program due to lack of a needed support library, SUP32.LIB,
which I wish Matt would send us.

Matthew Bradburn
afb@j.cc.purdue.edu
bradburn@purccvm.bitnet

#	This is a shell archive.
#	Remove everything above and including the cut line.
#	Then run the rest of the file through sh.
#----cut here-----cut here-----cut here-----cut here----#
#!/bin/sh
# shar:	Shell Archiver
#	Run the following text with /bin/sh to create:
#	Makefile
#	TODO
#	defs.h
#	globals.c
#	main.c
#	text1.c
# This archive created: Thu Nov 19 16:55:32 1987
# By:	Matthew Bradburn (Purdue University)
cat << \SHAR_EOF > Makefile

#   Note:  In terms of compiling, if you do not have my latest
#   support library you may have to do some hacking to get the
#   code to link.
#
#   The precompiled symbol table, SYMBOLS.M, is *only* the AMIGA includes
#   .. */*.h (exec/*.h, etc....).  When generating a precompiled symbol
#   table remember to use the +L compiler option.

CFLAGS= +L +Ivd0:include/symbols.m
OBJS= globals.o command.o keyboard.o main.o text1.o text2.o subs.o refs.o
ASMS= globals.asm command.asm keyboard.asm main.asm text1.asm text2.asm subs.asm refs.asm
SRCS= globals.c command.c keyboard.c main.c text1.c text2.c subs.c refs.c
HDR=  defs.h

.c.o:
    cc $(CFLAGS) -o $@ $*.c

.c.asm:
    cc $(CFLAGS) -A -o ram:$@ $*.c


all: $(OBJS)
    ln +Q $(OBJS) -lsup32 -lc32 -O ram:dme

asm: $(ASMS)

arc:
    -delete ram:dme.arc
    arc a ram:dme dme.doc ram:dme dme.info README SAMPLE.EDRC

srcarc:
    -delete ram:dmesrc.arc
    arc a ram:dmesrc Makefile TODO $(SRCS) $(HDR)


clean:
    -delete $(OBJS) ram:dme

SHAR_EOF
cat << \SHAR_EOF > TODO

ni = not implemented yet

STATUS	ITEM

ni	ascii-numeric variable support
SEMI	command line variable expansion.
ni	exception handling  (abort if, repeat, keymap, etc..... trap vector?)
ni	kill/string buffer
ni	text markers
ni	character oriented blocks
ni	highlight blocks
ni	block operations across windows
ni	stackable search/replace strings
ni	cancel all user keymaps
ni	clipboard support
ni	anchored search as opposed to normal search
ni	keyboard repeat buffering too many repeats.
(1)     help! key
ni	provision to show mapping for a single key

ni	CD for each window
ni	menu add
ni	Scroll Gadgets
in	Formatted Save
ni	Case ignore for FIND, FIND-REPLACE
NO	slave the editor to a shell.


(1)
    Implementable as a keymap and the REF command.

fsave (formatted save)

    When it encounters one linefeed with the next character not whitespace,
    it writes a space.	If the next character is whitespace it leaves it
    alone (write one linefeed).  If the next character is a linefeed, write
    one linefeed then copy linefeeds up to the next non-linefeed.

    This will almost allow "word-processor" output... with columns! Very
    simple, very small, and it will save me from the horrors of
    PageSetter's editor.  You may want to do funky things to the name like
    "fsaveas" or "fbsave" or whatever.

    I'll even add it if you don't have time.






SHAR_EOF
cat << \SHAR_EOF > defs.h

/*
 * DEFS.H
 *
 *	(C)Copyright 1987 by Matthew Dillon, All Rights Reserved
 *
 */

#include <exec/types.h>
#include <exec/io.h>
#include <devices/keymap.h>
#include <devices/console.h>
#include <exec/memory.h>
#include <intuition/intuition.h>
#include <typedefs.h>
#include "xmisc.h"

#define MAXTOGGLE   256
#define QMOVE	    (0x6B|0x80)

#define COLT(n)  (XTbase + (n) * Xsize)
#define ROWT(n)  (YTbase + (n) * Ysize)
#define COL(n)	 (Xbase  + (n) * Xsize)
#define ROW(n)	 (Ybase  + (n) * Ysize)

typedef unsigned char ubyte;
typedef struct WBStartup  WBS;
typedef struct DiskObject DISKOBJ;

extern WBS	*Wbs;
extern DISKOBJ	*Do;

extern short Xsize, Ysize;
extern short XTbase, YTbase;
extern short Rows, Columns;
extern short Xbase, Ybase;
extern short Xpixs, Ypixs;
extern ubyte *av[];
extern char Wdisable;


typedef struct _ED {
    struct _ED *next, **prev;
    WIN *Win;
    long Topline, Topcolumn;
    long Line, Column;
    long Lines, Maxlines;
    ubyte **List;
    ubyte Name[64];
    ubyte Wtitle[130];
    char Modified;
    ubyte Tabstop;
    ubyte Margin;
    char Insertmode;
    char Wordwrap;
    char iconmode;	    /* window in icon mode		    */
    short Winx, Winy, Winwidth, Winheight;
    short IWinx, IWiny;
    long BSline, BEline;    /* block start and end lines	    */
    short BSchar, BEchar;   /* char start on BSline, end on BEline  */
    long dirlock;	    /* directory lock			    */
} ED;


#ifndef NULL
#define NULL 0
#endif
#ifdef E
#undef E
#endif

extern ED E, *Ep, *Base;
extern char Overide;
extern char Savetabs;
extern char memoryfail, Nsu, Msgchk;
extern ubyte CtlC;
extern ubyte Current[256];
extern ubyte Space[32];
extern short Clen;
extern char  Abortcommand, MShowTitle;
extern char  Comlinemode;
extern RP *Rp;
extern WIN *Win;
extern char *Partial;
extern char *String;

extern ubyte *allocl(), *allocb();
extern ubyte *AllocMem(), *strcpy(), *malloc();
extern char *keyspectomacro();

extern void search_operation();



SHAR_EOF
cat << \SHAR_EOF > globals.c

/*
 * GLOBALS.C
 *
 *	(C)Copyright 1987 by Matthew Dillon, All Rights Reserved
 */

#include "defs.h"

ED E, *Ep;		/* Current Window		*/
ED *Base;		/* Doubly linked list of Files	*/

char Nsu;		/* Used in formatter to disable screen updates	*/
char Msgchk;		/* Force message queue check for break		*/
ubyte CtlC;		/* Keycode for 'c'                              */
char Savetabs;		/* SaveTabs mode?				*/
char memoryfail;	/* out of memory flag				*/
ubyte Current[256];	/* Current Line buffer and length		*/
ubyte Space[32] = { 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,
		    32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32 };
short Clen;
char	*Partial;	/* Partial command line when executing ESCIMM	*/
char	*String;	/* String Capture variable			*/

char Comlinemode;
char Abortcommand;


SHAR_EOF
cat << \SHAR_EOF > main.c

/*
 * MAIN.C
 *
 *	(C)Copyright 1987 by Matthew Dillon, All Rights Reserved.
 *
 */

#include "defs.h"

#define IDCMPFLAGS   CLOSEWINDOW|NEWSIZE|RAWKEY|MOUSEBUTTONS|ACTIVEWINDOW|MOUSEMOVE

extern WIN *OpenWindow();

NW Nw = {
   0, 1, 640, 199, -1, -1,
   IDCMPFLAGS,
   ACTIVATE|WINDOWSIZING|WINDOWDRAG|WINDOWDEPTH|WINDOWCLOSE|NOCAREREFRESH|RMBTRAP,
   NULL, NULL, (ubyte *)"   WAIT   ",
   NULL, NULL,
   32, 32, -1, -1,
   WBENCHSCREEN
};

short Sharedrefs;
short Oldtlen = 999;	  /*  Old Title Length	  */
struct MsgPort *Sharedport;
DISKOBJ *Do;
WBS	*Wbs;

WIN *Win;
RP  *Rp;

short Xsize,  Ysize;		/* font character sizes        */
short Rows,  Columns;		/* character rows/cols available       */
short Xbase,  Ybase;		/* offset pixel base for display       */
short XTbase,YTbase;		/* used for text display	       */
short Xpixs,  Ypixs;		/* actual # X/Y pixels available       */
short Mx, My;

ubyte *av[8];
char Quitflag;
char Overide;
char SizeOveride;
char Wdisable = 1;		/* Disable icon save		       */
char MShowTitle, MForceTitle;
short Nwwidth, Nwheight, Nwtopedge, Nwleftedge, Nwtmpwidth, Nwtmpheight;

int Enable_Abort;

extern ED E, *Ep, *Base;
extern char memoryfail;
extern WIN *opensharedwindow();
extern IMESS *GetMsg();

static char *Ffile;

main(mac, mav)
char *mav[];
{
    register IMESS *im;
    register WIN *win;
    char nf, ni;	    /* # files on command line	*/
    char notdone;
    char iawm = 0;
    char dontwait = 0;
    short i;
    short Code;

    init_command();

    Nwwidth	= Nw.Width;
    Nwheight	= Nw.Height;
    Nwtopedge	= Nw.TopEdge;
    Nwleftedge	= Nw.LeftEdge;

    Enable_Abort= 0;

    String  = (char *)malloc(1);
    *String = 0;

    if (!openlibs(INTUITION_LIB|GRAPHICS_LIB))
	exiterr("cannot open intuition or graphics library");

    if (mac == 0) {
	long oldlock;

	Wdisable = 0;
	Wbs = (WBS *)mav;
	if (!openlibs(ICON_LIB))
	    exiterr("unable to open icon library");
	oldlock = CurrentDir(Wbs->sm_ArgList[0].wa_Lock);   /* tool */
	Do = GetDiskObject(Wbs->sm_ArgList[0].wa_Name);
	CurrentDir(oldlock);
	if (Do == NULL)
	    exiterr("unable to get disk object");
	mac = 99;
    }

    resethash();

    if (Do) {
	ops(Do->do_ToolTypes, 1);
	nf = Wbs->sm_NumArgs - 1;
	E.dirlock = Wbs->sm_ArgList[0].wa_Lock;
    } else {
	nf = ops(mav+1, 0);
    }

    for (ni = 0, i = 1; i < mac; ++i) {
	register char *str;
	register DISKOBJ *dso;
	long oldlock;
	if (Wbs) {
	    if (i > nf)
		break;
	    str = Wbs->sm_ArgList[i].wa_Name;
	    oldlock = CurrentDir(Wbs->sm_ArgList[i].wa_Lock);
	    if (dso = GetDiskObject(Wbs->sm_ArgList[i].wa_Name)) {
		ops(dso->do_ToolTypes, 1);
		FreeDiskObject(dso);
	    }
	    E.dirlock = CurrentDir(oldlock);
	} else {
	    str = mav[i];
	    if (*str == '-')
		continue;
	}
	do_newwindow(nf > 1, ni * 10);
	++ni;
	av[0] = (ubyte *)"newfile";
	av[1] = (ubyte *)str;
	do_edit();
	MForceTitle = 1;
	window_title();
    }
    if (nf == 0)                     /* no files to edit */
	do_newwindow(nf > 1, ni * 10);

    mountrequest(0);
    av[0] = NULL;
    av[1] = (ubyte *)"s:.edrc";
    do_source();
    av[0] = NULL;
    av[1] = (ubyte *)((Ffile) ? Ffile : ".edrc");
    do_source();
    mountrequest(1);
    title("DME V1.28f \251Copyright 1987 Matthew Dillon,  All Rights Reserved                  ");
loop:
    if (!E.iconmode)
	text_cursor(1);
    for (notdone = 1; !Quitflag && notdone;) {
	char mmove = 0;
	short mqual;

	if (!E.iconmode)
	    window_title();
	if (dontwait)
	    --dontwait;
	else
	    WaitPort(Win->UserPort);

	/*
	 *  NOTE: due to operation of breakcheck(), the userport signal
	 *  may not be set even if there are messages pending.
	 */

	while (im = (IMESS *)GetMsg(Win->UserPort)) {
	    Msgchk = 1;
	    Abortcommand = 0;
	    Code = im->Code;
	    if (im->IDCMPWindow != Win) {
		Overide = 0;
		if (Comlinemode)
		    escapecomlinemode();
		text_sync();
		MShowTitle = 0;
		if (!E.iconmode)
		    window_title();
		if (text_switch(im->IDCMPWindow) == 0) {
		    ReplyMsg(im);
		    continue;
		}
		if (!E.iconmode) {
		    set_window_params();
		    window_title();
		}
	    }
	    Mx = im->MouseX;
	    My = im->MouseY;
	    switch(im->Class) {
	    case NEWSIZE:
		if (!E.iconmode) {
		    if (Comlinemode)
			escapecomlinemode();
		    set_window_params();
		    if (!text_sync())
		       text_redisplay();
		    text_cursor(1);
		}
		break;
	    case MOUSEBUTTONS:
		switch(Code) {
		case SELECTDOWN:
		case MENUDOWN:
		    if (E.iconmode || iawm) {
			uniconify();
			break;
		    }
		    ReportMouse(-1, Win);
		    uniconify();
		    text_cursor(0);
		    keyctl(NULL, im->Code|0x80, im->Qualifier);
		    text_cursor(1);
		    break;
		case SELECTUP:
		case MENUUP:
		    ReportMouse(0, Win);
		    break;
		}
		break;
	    case RAWKEY:
		if ((im->Qualifier & 0x80) == 0) {
		    if (E.iconmode) {
			uniconify();
			break;
		    }
		    text_cursor(0);
		    keyctl(im, im->Code, im->Qualifier);
		    text_cursor(1);
		}
		break;
	    case CLOSEWINDOW:
		if (Comlinemode)
		    escapecomlinemode();
		text_sync();
		notdone = 0;
		break;
	    case ACTIVEWINDOW:
		if (!E.iconmode)
		    iawm = 1;
		break;
	    case MOUSEMOVE:
		mmove = 1;
		mqual = im->Qualifier;
		break;
	    }
	    if (im)
		ReplyMsg(im);
	    if (notdone == 0 || Quitflag) {
		dontwait = 2;
		goto boom;
	    }
	}
	iawm = 0;
	if (mmove) {
	    uniconify();
	    mmove = 0;
	    text_cursor(0);
	    keyctl(NULL, QMOVE, mqual);
	    text_cursor(1);
	}
	closesharedwindow(NULL);
    }
boom:
    if (E.Modified && !Overide) {
	uniconify();
	Overide = 1;
	title("*** File has been modified ***");
	Quitflag = 0;
	goto loop;
    }
    SetWindowTitles(Win, "", -1);
    text_uninit();                      /* uninitialize text portion    */
    closesharedwindow(Win);
    if (Base) {
	Quitflag = 0;
	Win = E.Win;			/* make arbitrary other window act. */
	Rp = Win->RPort;
	if (!E.iconmode)
	    set_window_params();
	text_load();
	MShowTitle = 0;
	goto loop;
    }
    closesharedwindow(NULL);
    if (Do)
	FreeDiskObject(Do);
    closelibs(-1);
    dealloc_hash();
}

do_iconify()
{
    if (!Comlinemode)
	iconify();
}

do_tomouse()
{
    text_position((Mx-Xbase)/Xsize, (My-Ybase)/Ysize);
}

iconify()
{
    if (!E.iconmode) {
	E.Winx	    = Win->LeftEdge;
	E.Winy	    = Win->TopEdge;
	E.Winwidth  = Win->Width;
	E.Winheight = Win->Height;
	Nw.Height = 10;
	Nw.Width  = 20 + 5*8 + strlen(E.Name)*8;
	Nw.LeftEdge= E.IWinx;
	Nw.TopEdge = E.IWiny;
	if (Nw.LeftEdge + Nw.Width > Win->WScreen->Width)
	    Nw.LeftEdge = Win->WScreen->Width - Nw.Width;
	if (Nw.TopEdge + Nw.Height > Win->WScreen->Height)
	    Nw.TopEdge = Win->WScreen->Height - Nw.Height;
	Nw.Title = Ep->Wtitle;
	Nw.Flags &= ~(WINDOWSIZING|WINDOWDEPTH|ACTIVATE);
	Nw.Flags |= BORDERLESS;
	sprintf(Ep->Wtitle, "%s %s    ", E.Name, ((E.Modified) ? "(mod)":""));
	closesharedwindow(Win);
	Win = E.Win = Ep->Win = opensharedwindow(&Nw);
	Nw.Flags |= WINDOWSIZING|WINDOWDEPTH|ACTIVATE;
	Nw.Flags &= ~BORDERLESS;
	Rp = Win->RPort;
    }
    E.iconmode = 1;
}

uniconify()
{
    if (E.iconmode) {
	E.IWinx = Win->LeftEdge;
	E.IWiny = Win->TopEdge;
	closesharedwindow(Win);
	Nw.LeftEdge = E.Winx;
	Nw.TopEdge  = E.Winy;
	Nw.Width    = E.Winwidth;
	Nw.Height   = E.Winheight;
	Nw.Title = Ep->Wtitle;
	Win = E.Win = Ep->Win = opensharedwindow(&Nw);
	Rp = Win->RPort;
	set_window_params();
	if (!text_sync())
	    text_redisplay();
	text_cursor(1);
	MShowTitle = 0;
	window_title();
    }
    E.iconmode = 0;
}


do_newwindow(makesmall, deltaheight)
{
    WIN *win;
    int msadj = makesmall;

    if (SizeOveride)
	msadj = 0;
    if (Ep)
	text_sync();
    Nw.Title = (ubyte *)"    OK    ";
    Nw.Width = (Nwtmpwidth) ? Nwtmpwidth : Nwwidth;
    Nw.Height= (Nwtmpheight)? Nwtmpheight: Nwheight;
    Nwtmpwidth = Nwtmpheight = 0;
    Nw.LeftEdge = Nwleftedge;
    Nw.TopEdge	= Nwtopedge;
    if (msadj > 0) {                    /* deltaheight must be valid    */
	Nw.TopEdge = deltaheight + 16;
	Nw.LeftEdge= 10*8;
	Nw.Flags &= ~ACTIVATE;
	Nw.Width = 40*8;
	Nw.Height= 10*8;
	if (Nw.TopEdge + Nw.Height > 200)
	    Nw.TopEdge = deltaheight = 200 - Nw.Height;
    }
    win = opensharedwindow(&Nw);
    Nw.Flags |= ACTIVATE;
    if (win) {
	Win = win;			/* set new window   */
	Rp = Win->RPort;
	set_window_params();
	text_init();                    /* initialize       */
	text_load();
	if (makesmall != -1)            /* if deltaheight valid */
	    E.IWiny = deltaheight + 16;
    }
}

WIN *
TOpenWindow(nw)
NW *nw;
{
    WIN *win;

    while ((win = OpenWindow(nw)) == NULL) {
	if (nw->Width < 50 || nw->Height < 50)
	    break;
	nw->Width -= 10;
	nw->Height-= 10;
    }
    return(win);
}


WIN *
opensharedwindow(nw)
NW *nw;
{
    WIN *win;

    if (Sharedport)
	nw->IDCMPFlags = NULL;
    else
	nw->IDCMPFlags = IDCMPFLAGS;
    win = TOpenWindow(nw);
    if (win) {
	if (Sharedport) {
	    win->UserPort = Sharedport;
	    ModifyIDCMP(win, IDCMPFLAGS);
	} else {
	    Sharedport = win->UserPort;
	}
	++Sharedrefs;
    }
    return(win);
}


closesharedwindow(win)
WIN *win;
{
    static WIN *wunlink;
    register IMESS *im;
    char notoktoclosenow = 0;

    if (win) {
	SetWindowTitles(win, "", -1);
	Forbid();
	win->UserPort = NULL;
	ModifyIDCMP(win, GADGETUP);     /* NEVER occurs */

	notoktoclosenow = 1;

	Permit();
	if (notoktoclosenow) {
	    win->UserData = (char *)wunlink;
	    wunlink = win;
	} else {
	    CloseWindow(win);
	}
	--Sharedrefs;
    } else {
	if (Sharedrefs == 0 && Sharedport) {
	    DeletePort(Sharedport);
	    Sharedport = NULL;
	}
	for (win = wunlink; win; win = wunlink) {
	    wunlink = (WIN *)win->UserData;
	    CloseWindow(win);
	}
	wunlink = NULL;
    }
}


getyn(text)
char *text;
{
    int result;
    ITEXT *body, *pos, *neg;

    body = (ITEXT *)AllocMem(sizeof(ITEXT), 0);
    pos  = (ITEXT *)AllocMem(sizeof(ITEXT), 0);
    neg  = (ITEXT *)AllocMem(sizeof(ITEXT), 0);
    bzero(body, sizeof(ITEXT));
    bzero(pos , sizeof(ITEXT));
    bzero(neg , sizeof(ITEXT));
    body->BackPen = pos->BackPen = neg->BackPen = 1;
    body->DrawMode= pos->DrawMode= neg->DrawMode= AUTODRAWMODE;
    body->LeftEdge = 10;
    body->TopEdge  = 12;
    body->IText    = (ubyte *)text;
    pos->LeftEdge = AUTOLEFTEDGE;
    pos->TopEdge = AUTOTOPEDGE;
    pos->IText = (ubyte *)"OK";
    neg->LeftEdge = AUTOLEFTEDGE;
    neg->TopEdge = AUTOTOPEDGE;
    neg->IText = (ubyte *)"CANCEL";
    result = AutoRequest(Win,body,pos,neg,0,0,320,58);
    FreeMem(body, sizeof(ITEXT));
    FreeMem(pos , sizeof(ITEXT));
    FreeMem(neg , sizeof(ITEXT));
    return(result);
}


title(buf)
char *buf;
{
    SetWindowTitles(Win, buf, -1);
    Oldtlen = 999;
    MShowTitle = 3;
}

window_title()
{
    register int len, maxlen;

    if (memoryfail) {
	title(" -- NO MEMORY -- ");
	memoryfail = 0;
	text_redisplay();
    }
    if (MForceTitle) {
	MShowTitle = 0;
	MForceTitle = 0;
    }
    if (MShowTitle) {
	--MShowTitle;
	return(0);
    }
    {
	register char *mod;
	mod = (E.Modified) ? " (modified)" : "          ";
	sprintf(Ep->Wtitle, "%3ld/%-3ld %3ld %s%s  ", text_lineno(), text_lines(), text_colno()+1, text_name(), mod);
	if (!text_imode())
	    strcat(Ep->Wtitle, "Ovr ");
	len = strlen(Ep->Wtitle);
	if (len < Columns && Columns < 128) {
	    bset(Ep->Wtitle+len, Columns - len + 1, ' ');
	    Ep->Wtitle[Columns + 1] = 0;
	}

	Win->Title = Ep->Wtitle;
	SetAPen(Rp, 0);
	SetBPen(Rp, 1);
	Move(Rp, 30, Win->RPort->Font->tf_Baseline+1);
	maxlen = (Win->Width-96)/Win->RPort->Font->tf_XSize;
	if (maxlen < 0)
	    maxlen = 0;
	if (len > maxlen)
	    len = Oldtlen = maxlen;
	if (Oldtlen > maxlen)
	    Oldtlen = maxlen;
	Text(Rp, Ep->Wtitle, len);      /*  No flash                    */
	while (Oldtlen - len >= (int)sizeof(Space)) {
	    Text(Rp, Space, sizeof(Space));
	    Oldtlen -= sizeof(Space);
	}
	if (Oldtlen - len > 0)
	    Text(Rp, Space, Oldtlen - len);
	Oldtlen = len;			/*  Oldtlen might have been <	*/
	SetAPen(Rp, 1);
	SetBPen(Rp, 0);
    }
}

set_window_params()
{
    Xsize = Rp->Font->tf_XSize;
    Ysize = Rp->Font->tf_YSize;
    Xbase = Win->BorderLeft;
    Ybase = Win->BorderTop;
    Xpixs   = Win->Width - Win->BorderRight - Xbase;
    Ypixs   = Win->Height- Win->BorderBottom- Ybase;
    Columns = Xpixs / Xsize;
    Rows    = Ypixs / Ysize;
    XTbase  =  Xbase;
    YTbase  =  Ybase + Rp->Font->tf_Baseline;
}


exiterr(str)
char *str;
{
    if (Output()) {
	Write(Output(),str,strlen(str));
	Write(Output(),"\n",1);
    }
    exit(1);
}


/*
 *  Check break by scanning pending messages in the I stream for a ^C.
 *  Msgchk forces a check, else the check is only made if the signal is
 *  set in the I stream (the signal is reset).
 */

breakcheck()
{
    IMESS *im;
    register struct List *list = &Win->UserPort->mp_MsgList;

    if (Msgchk || (SetSignal(0,0) & (1<<Win->UserPort->mp_SigBit))) {
	Msgchk = 0;
	SetSignal(0,1<<Win->UserPort->mp_SigBit);

	im = (IMESS *)list->lh_Head;
	Forbid();
	for (; im != &list->lh_Tail; im = (IMESS *)im->ExecMessage.mn_Node.ln_Succ) {
	    if (im->Class == RAWKEY && (im->Qualifier & 0xFB) == 0x08 &&
		im->Code == CtlC) {

		Permit();
		SetSignal(SIGBREAKF_CTRL_C,SIGBREAKF_CTRL_C);
		return(1);
	    }
	}
	Permit();
    }
    return(0);
}

breakreset()
{
    SetSignal(0, SIGBREAKF_CTRL_C);
}

/*
 *  leftedge n
 *  topedge  n
 *  width    n
 *  height   n
 *  tmpwidth  n
 *  tmpheight n
 */

void
do_windowparm()
{
    int val = atoi(av[1]);

    if (av[0][0] == 't' && av[0][1] == 'm') {   /*  tmpwidth/tmpheight  */
	if (av[0][3] == 'w')
	    Nwtmpwidth = val;
	if (av[0][3] == 'h')
	    Nwtmpheight= val;
	return;
    }
    switch(av[0][0]) {
    case 'l':
	Nwleftedge = val;
	break;
    case 't':
	Nwtopedge = val;
	break;
    case 'w':
	Nwwidth = val;
	break;
    case 'h':
	Nwheight = val;
	break;
    }
}

/*
 *  resize cols rows
 */

do_resize()
{
    int cols = atoi(av[1]);
    int rows = atoi(av[2]);
    short width = (cols*Win->RPort->Font->tf_XSize) + Win->BorderLeft + Win->BorderRight;
    short height= (rows*Win->RPort->Font->tf_YSize) + Win->BorderTop + Win->BorderBottom;

    if (width < 16 || height < 16 ||
    width > Win->WScreen->Width - Win->LeftEdge ||
    height > Win->WScreen->Height - Win->TopEdge) {
	title ("window too big (try moving to upper left corner and retrying)");
	return(0);
    }
    SizeWindow(Win, width - Win->Width, height - Win->Height);
    Delay(50*2);    /* wait 2 seconds */
}

ops(av, iswb)
register char *av[];
{
    register short nonops;
    register short i;
    register long val;
    register char *str;

    for (i = nonops = 0; str = av[i]; ++i) {
	if (iswb) {
	    if (strncmp(str, "ARG", 3) == 0) {
		while (*str && *str != '-')
		    ++str;
	    }
	}
	if (*str == '-') {
	    val = atoi(str+2);
	    switch(str[1]) {
	    case 'f':
		Ffile = str+2;
		break;
	    case 'b':
		SizeOveride = 1;
		break;
	    case 't':
		Nwtopedge = val;
		break;
	    case 'l':
		Nwleftedge= val;
		break;
	    case 'w':
		SizeOveride = 1;
		Nwwidth   = val;
		break;
	    case 'h':
		SizeOveride = 1;
		Nwheight  = val;
		break;
	    }
	} else {
	    ++nonops;
	}
    }
    return(nonops);
}



SHAR_EOF
cat << \SHAR_EOF > text1.c

/*
 * TEXT1.C
 *
 *	(C)Copyright 1987 by Matthew Dillon,	All Rights Reserved
 */

#include "defs.h"

#define nomemory()  {memoryfail = 1;}

char RecallBuf[256];

text_init()
{
    register ED *e;
    long dirlock;

    text_switch(NULL);
    dirlock = E.dirlock;
    e = (ED *)allocb(sizeof(ED));
    if (e == NULL)
	return(0);
    bzero(&E, sizeof(E));
    E.Win = Win;
    if (Ep) {
	E.Insertmode = Ep->Insertmode;
	E.Tabstop    = Ep->Tabstop;
	E.Wordwrap   = Ep->Wordwrap;
    } else {
	E.Insertmode = 1;
	E.Tabstop = 4;
    }
    E.Lines = 1;
    E.Maxlines = 32;
    E.List = (ubyte **)allocl(E.Maxlines);
    E.List[0] = allocb(1);
    E.List[0][0] = Current[0] = Clen = 0;
    E.BSline = E.BEline = -1;
    E.IWiny = 16;
    E.dirlock = dirlock;	/* workbench support	*/
    *e = E;
    llink(&Base, e);
    strcpy(E.Name, "unnamed");
    Ep = e;
    text_cursor(1);
    return(1);
}


text_switch(win)
WIN *win;
{
    register ED *e;
    register ED *next, **prev;

    if (win)
	text_sync();
    if (Ep) {
	E.next = Ep->next;
	E.prev = Ep->prev;
	strcpy(E.Wtitle, Ep->Wtitle);
	*Ep = E;
    }
    if (win) {
	for (e = Base; e; e = e->next) {
	    if (e->Win == win) {
		Ep = e;
		Win = win;
		Rp = Win->RPort;
		E = *e;
		text_load();
		return(1);
	    }
	}
	return(0);
    }
}


text_sync()
{
    char redraw = 0;
    short len;
    ubyte *ptr;

    for (len = strlen(Current) - 1; len >= 0 && Current[len] == ' '; --len)
	Current[len] = '\0';
    Clen = len + 1;
    if (!Comlinemode) {
	if (strlen(E.List[E.Line]) != Clen) {
	    if (ptr = allocb(Clen+1)) {
		E.Modified = 1;
		Overide = 0;
		FreeMem(E.List[E.Line], strlen(E.List[E.Line])+1);
		E.List[E.Line] = ptr;
	    } else {
		nomemory();
		strcpy(Current, E.List[E.Line]);
		Clen = strlen(Current);
	    }
	} else {
	    if (strcmp(E.List[E.Line], Current)) {
		E.Modified = 1;
		Overide = 0;
	    }
	}
	strcpy(E.List[E.Line], Current);
    }
    if (Nsu == 0) {
	if (E.Column - E.Topcolumn >= Columns || E.Column < E.Topcolumn) {
	    redraw = 1;
	    E.Topcolumn = E.Column - (Columns>>1);
	    if (E.Topcolumn < 0)
		E.Topcolumn = 0;
	}
	if (E.Line - E.Topline >= Rows || E.Line < E.Topline) {
	    redraw = 1;
	    E.Topline = E.Line - (Rows>>1);
	    if (E.Topline < 0)
		E.Topline = 0;
	}
    }
    while (E.Column > Clen)
	Current[Clen++] = ' ';
    Current[Clen] = '\0';
    if (redraw)
	text_redisplay();
    return((int)redraw);
}

text_load()
{
    if (Comlinemode)
	return(0);
    strcpy(Current, E.List[E.Line]);
    Clen = strlen(Current);
    while (E.Column > Clen)
	Current[Clen++] = ' ';
    Current[Clen] = '\0';
}

text_colno()
{
    return(E.Column);
}

text_lineno()
{
    return(E.Line+1);
}

text_lines()
{
    return(E.Lines);
}

text_cols()
{
    return((int)Clen);
}

text_imode()
{
    return(E.Insertmode);
}

text_tabsize()
{
    return((int)E.Tabstop);
}

ubyte *
text_name()
{
    return(E.Name);
}


text_uninit()
{
    register int i;
    register ED *e;

    for (i = 0; i < E.Lines; ++i)
	FreeMem(E.List[i], strlen(E.List[i])+1);
    FreeMem(E.List, E.Maxlines * sizeof(char *));

    lunlink(Ep);
    FreeMem(Ep, sizeof(ED));
    if (Base) {
	E = *Base;
	Ep= Base;
	text_load();
    } else {
	Ep = NULL;
    }
}

inversemode(n)
{
    if (n) {
	SetAPen(Rp, 3);
	SetDrMd(Rp, JAM2|INVERSVID);
    } else {
	SetAPen(Rp, 1);
	SetDrMd(Rp, JAM2);
    }
}

text_cursor(n)
{
    movetocursor();
    inversemode(n);
    if (Current[E.Column])
	Text(Rp, Current+E.Column, 1);
    else
	Text(Rp, " ", 1);
    inversemode(0);
}


text_position(col, row)
{
    text_sync();
    if (col == 0)
	col = -1;
    E.Column = E.Topcolumn + col;
    if (E.Column > 254)
	E.Column = 254;
    if (E.Column < 0)
	E.Column = 0;
    E.Line = E.Topline + row;
    if (E.Line >= E.Lines)
	E.Line = E.Lines - 1;
    if (E.Line < 0)
	E.Line = 0;
    text_load();
    text_sync();
}


text_displayseg(start, n)
{
    register short i, c;
    register ubyte *ptr;
    char ib;

    if (Nsu)
	return(0);
    for (i = start; i < start+n && E.Topline + i < E.Lines; ++i) {
	if (Comlinemode) {
	    if (E.Topline + i != E.Line)
		continue;
	    ptr = Current;
	} else {
	    ptr = E.List[E.Topline + i];
	}
	for (c = E.Topcolumn; c && *ptr; ++ptr, --c);
	c = strlen(ptr);
	if (c) {
	    Move(Rp, COLT(0), ROWT(i));
	    Text(Rp, ptr, (c > Columns) ? Columns : c);
	}
    }
}

text_redisplay()
{
    if (Nsu)
	return(0);
    SetAPen(Rp, 0);
    if (Comlinemode)
	RectFill(Rp, COL(0), ROW(Rows-1), Xbase+Xpixs, Ybase+Ypixs);
    else
	RectFill(Rp, Xbase, Ybase, Xbase + Xpixs, Ybase + Ypixs);
    SetAPen(Rp, 1);
    text_displayseg(0,Rows);
}

text_redisplaycurrline()
{
    int row = E.Line - E.Topline;

    if (Nsu)
	return(0);
    SetAPen(Rp, 0);
    RectFill(Rp, COL(0), ROW(row), Xbase+Xpixs, ROW(row+1)-1);
    SetAPen(Rp, 1);
    text_displayseg(row, 1);
}

text_write(str)
ubyte *str;
{
    short len = strlen(str);
    short i;

    if (Clen + len >= 255) {
	text_sync();
	text_load();
    }
    if (E.Insertmode == 0) {
	i = len;
	if (E.Column + len < 255) {
	    bmov(str, Current + E.Column, len);
	    if (E.Column + len >= Clen)
		Clen = E.Column + len;
	    Current[Clen] = 0;
	    goto bin;
	}
	goto ok;
    }
    if (Clen + len < 255) {
	bmov(Current + E.Column, Current + E.Column + len, Clen+1-E.Column);
	bmov(str, Current + E.Column, len);
	Clen += len;
	ScrollRaster(Rp, -len * Xsize, 0 ,
		COL(E.Column - E.Topcolumn), ROW(E.Line - E.Topline),
		COL(Columns) - 1, ROW(E.Line - E.Topline + 1) - 1
	);
	i = (E.Column - E.Topcolumn + len > Columns) ? Columns - E.Column + E.Topcolumn : len;
bin:
	Move(Rp, COLT(E.Column - E.Topcolumn), ROWT(E.Line - E.Topline));
	Text(Rp, str, i);
	E.Column += len;
	if (E.Column - E.Topcolumn >= Columns)
	    text_sync();
    }
ok:
    if (Comlinemode == 0 && E.Wordwrap)
	do_reformat(0);
}


do_up()
{
    if (E.Line) {
	text_sync();
	--E.Line;
	text_load();
	if (E.Line < E.Topline) {
	    if (Nsu == 0) {
		ScrollRaster(Rp,0,-Ysize,COL(0),ROW(0),COL(Columns)-1,ROW(Rows)-1);
		--E.Topline;
		text_displayseg(0, 1);
	    }
	}
    } else {
	Abortcommand = 1;
    }
}

do_scrolldown()
{
    if (E.Topline + Rows < E.Lines) {
	if (Nsu == 0) {
	    text_sync();
	    ScrollRaster(Rp,0,Ysize,COL(0),ROW(0),COL(Columns)-1,ROW(Rows)-1);
	    ++E.Topline;
	    ++E.Line;
	    text_load();
	    text_displayseg(Rows-1, 1);
	}
    } else {
	Abortcommand = 1;
    }
}

do_scrollup()
{
    if (E.Topline) {
	if (Nsu == 0) {
	    text_sync();
	    ScrollRaster(Rp,0,-Ysize,COL(0),ROW(0),COL(Columns)-1,ROW(Rows)-1);
	    --E.Topline;
	    --E.Line;
	    text_load();
	    text_displayseg(0, 1);
	}
    } else {
	Abortcommand = 1;
    }
}

do_down()
{
    if (E.Line + 1 < E.Lines) {
	text_sync();
	++E.Line;
	text_load();
	if (E.Line - E.Topline >= Rows) {
	    if (Nsu == 0) {
		ScrollRaster(Rp,0,Ysize,COL(0),ROW(0),COL(Columns)-1,ROW(Rows)-1);
		++E.Topline;
		text_displayseg(Rows-1, 1);
	    }
	}
    } else {
	Abortcommand = 1;
    }
}

/*
 *  PAGEUP
 *  PAGEDOWN
 *  PAGESET n	(n = 0 to 100 for percentage of #rows to scroll, minimum 1)
 *		can be > 100.
 */

do_page()
{
    register int n, multiplier = 1;
    static short pctg = 80;

    switch(av[0][4]) {
    case 'u':
	multiplier = -1;
    case 'd':
	n = multiplier * Rows * pctg / 100;
	if (!n)
	    n = multiplier;
	if (n > 0 && E.Topline >= E.Lines - Rows)
	    return(0);
	text_sync();
	E.Line += n;
	E.Topline += n;
	if (E.Line >= E.Lines)
	    E.Line = E.Lines - 1;
	if (E.Line < 0)
	    E.Line = 0;
	if (E.Topline >= E.Lines)
	    E.Topline = E.Lines - Rows - 1;
	if (E.Topline < 0)
	    E.Topline = 0;
	text_load();
	if (!text_sync())
	    text_redisplay();
	break;
    case 's':
	pctg = atoi(av[1]);
	break;
    }
}


do_downadd()
{
    ubyte *ptr;

    if (E.Line + 1 == E.Lines) {
	E.Modified = 1;
	if (makeroom(32) && (ptr = allocb(1))) {
	    E.List[E.Lines] = ptr;
	    *ptr = 0;
	    ++E.Lines;
	} else {
	    nomemory();
	}
    }
    do_down();
}


do_left()
{
    if (E.Column) {
	--E.Column;
	if (E.Column < E.Topcolumn)
	    text_sync();
    } else {
	Abortcommand = 1;
    }
}

do_right()
{
    if (E.Column != 254) {
	if (Current[E.Column] == 0) {
	    Current[E.Column] = ' ';
	    Current[E.Column+1]= '\0';
	    ++Clen;
	}
	++E.Column;
	if (E.Column - E.Topcolumn >= Columns)
	    text_sync();
    } else {
	Abortcommand = 1;
    }
}

do_tab()
{
    register short n;

    for (n = E.Tabstop-(E.Column % E.Tabstop); n > 0; --n)
	do_right();
}

do_backtab()
{
    register short n;

    n = E.Column % E.Tabstop;
    if (!n)
	n = E.Tabstop;
    for (; n > 0; --n)
	do_left();
}

do_return()
{
    ubyte buf[256];
    char *partial;

    if (Comlinemode) {
	strcpy(buf, Current);
	strcpy(RecallBuf, Current);
	partial = Partial;
	Partial = NULL;
	escapecomlinemode();
	if (partial) {
	    if (do_command(buf))
		do_command(partial);
	    free(partial);
	} else {
	    do_command(buf);
	}
    } else {
	E.Column = 0;
	text_sync();
	do_downadd();
    }
}

do_bs()
{
    if (E.Column) {
	bmov(Current + E.Column, Current + E.Column - 1, Clen - E.Column + 1);
	--E.Column;
	--Clen;
	if (E.Column < E.Topcolumn) {
	    text_sync();
	} else {
	    ScrollRaster(Rp, Xsize, 0,
		COL(E.Column - E.Topcolumn),
		ROW(E.Line   - E.Topline),
		COL(Columns)-1,
		ROW(E.Line - E.Topline + 1)-1
	    );
	    if (Clen >= E.Topcolumn + Columns) {
		Move(Rp, COLT(Columns-1), ROWT(E.Line - E.Topline));
		Text(Rp, Current + E.Topcolumn + Columns - 1, 1);
	    }
	}
	if (Comlinemode == 0 && E.Wordwrap)
	    do_reformat(0);
    } else {
	Abortcommand = 1;
    }
}


/*
 * esc, escimm
 */

int Savetopline, Savecolumn, Savetopcolumn;

do_recall()
{
    av[0] = (ubyte *)"escimm";
    av[1] = (ubyte *)RecallBuf;
    do_esc();
}

do_esc()
{
    if (Comlinemode)
	return(escapecomlinemode());
    text_sync();
    if (av[0][3] == 'i')
	strcpy(Current, av[1]);
    else
	Current[0] = 0;
    Clen = strlen(Current);
    Comlinemode = 1;
    returnoveride(1);
    Savetopline = E.Topline;
    Savecolumn	= E.Column;
    Savetopcolumn = E.Topcolumn;
    E.Column	= Clen;
    E.Topcolumn = 0;
    E.Topline	= E.Line - Rows + 1;
    SetAPen(Rp, 0);
    RectFill(Rp, COL(0), ROW(Rows-1), Xbase+Xpixs, Ybase+Ypixs);
    SetAPen(Rp, 1);
    Move(Rp, COL(0), ROW(Rows-1) - 1);
    Draw(Rp, Xbase + Xpixs, ROW(Rows-1) - 1);
    text_displayseg(Rows-1,1);
}


escapecomlinemode()
{
    if (Partial) {
	free(Partial);
	Partial = NULL;
    }
    if (Comlinemode) {
	strcpy(RecallBuf, Current);
	Comlinemode = 0;
	returnoveride(0);
	E.Topline = Savetopline;
	E.Column  = Savecolumn;
	E.Topcolumn = Savetopcolumn;
	text_load();
	SetAPen(Rp, 0);
	RectFill(Rp, COL(0), ROW(Rows-1)-1, Xbase+Xpixs, Ybase+Ypixs);
	SetAPen(Rp, 1);
	text_displayseg(Rows-2,2);
    }
}


do_del()
{
    if (Current[E.Column]) {
	bmov(Current + E.Column + 1, Current + E.Column, Clen - E.Column);
	--Clen;
	ScrollRaster(Rp, Xsize, 0,
	    COL(E.Column - E.Topcolumn),
	    ROW(E.Line - E.Topline),
	    COL(Columns)-1,
	    ROW(E.Line - E.Topline + 1) - 1
	);
	if (Clen >= E.Topcolumn + Columns) {
	    Move(Rp, COLT(Columns-1), ROWT(E.Line-E.Topline));
	    Text(Rp, Current+E.Topcolumn+Columns-1, 1);
	}
	if (Comlinemode == 0 && E.Wordwrap)
	    do_reformat(0);
    }
}

do_top()
{
    text_sync();
    E.Line = 0;
    text_load();
    text_sync();
}

do_bottom()
{
    text_sync();
    E.Line = E.Lines - 1;
    text_load();
    text_sync();
}

do_firstcolumn()
{
    if (E.Column) {
	E.Column = 0;
	text_sync();
    }
}

do_firstnb()
{
    for (E.Column = 0; Current[E.Column] == ' '; ++E.Column);
    if (Current[E.Column] == 0)
	E.Column = 0;
    text_sync();
}

do_lastcolumn()
{
    short i;

    text_sync();
    i = (Comlinemode) ? Clen : strlen(E.List[E.Line]);
    if (i != E.Column) {
	E.Column = i;
	text_sync();
    }
}

/*
 * GOTO [+/-]N
 * GOTO BLOCK	start of block
 * GOTO START	start of block
 * GOTO END	end of block
 */

do_goto()
{
    register short n, i;
    register ubyte *ptr = av[1];

    i = 0;
    n = -1;

    switch(*ptr) {
    case 'b':
    case 's':
    case 'B':
    case 'S':
	n = E.BSline;
	break;
    case 'e':
    case 'E':
	n = E.BEline;
	break;
    case '+':
	i = 1;
    case '-':
	n = E.Line;
    default:
	n += atoi(ptr+i);
    }
    if (n >= E.Lines)
	n = E.Lines - 1;
    if (n < 0)
	n = 0;
    text_sync();
    E.Line = n;
    text_load();
    text_sync();
}

do_screentop()
{
    text_sync();
    E.Line = E.Topline;
    text_load();
    text_sync();
}

do_screenbottom()
{
    text_sync();
    E.Line = E.Topline + Rows - 1;
    if (E.Line < 0 || E.Line >= E.Lines)
	E.Line = E.Lines - 1;
    text_load();
    text_sync();
}

static ubyte Fstr[256];
static ubyte Rstr[256];
static short Srch_sign;
static char Doreplace;

/*
 * findstr, repstr
 */

do_findstr()
{
    if (av[0][0] == 'f')
	strcpy(Fstr, av[1]);
    else
	strcpy(Rstr, av[1]);
}

/*
 * findr, nextr, prevr
 */

do_findr()
{
    Doreplace = 1;
    Srch_sign = 1;
    switch(av[0][0]) {
    case 'f':
	strcpy(Fstr, av[1]);
	strcpy(Rstr, av[2]);
	break;
    case 'p':
	Srch_sign = -1;
	break;
    }
    search_operation();
}

/*
 * find, next, prev
 */

do_find()
{
    Doreplace = 0;
    Srch_sign = 1;
    switch(av[0][0]) {
    case 'f':
	strcpy(Fstr, av[1]);
	break;
    case 'p':
	Srch_sign = -1;
	break;
    }
    search_operation();
}


void
search_operation()
{
    int flen = strlen(Fstr);
    int rlen = strlen(Rstr);
    char senabled = 0;
    register ubyte *ptr;
    register int i, col;

    text_sync();
    if (!flen) {
	title("No find pattern");
	Abortcommand = 1;
	return;
    }

    col = E.Column;
    if (col >= strlen(E.List[E.Line]))
	col = strlen(E.List[E.Line]);
    for (i = E.Line;;) {
	ptr = E.List[i];
	if (Srch_sign > 0) {
	    while (ptr[col]) {
		if (Fstr[0] == ptr[col] &&
		strncmp(Fstr,ptr+col,flen) == 0 &&
		senabled) {
		    goto found;
		}
		senabled = 1;
		++col;
	    }
	    senabled = 1;
	    if (++i >= E.Lines)
		break;
	    col = 0;
	} else {
	    while (col >= 0) {
		if (Fstr[0] == ptr[col] &&
		strncmp(Fstr,ptr+col,flen) == 0 &&
		senabled) {
		    goto found;
		}
		senabled = 1;
		--col;
	    }
	    senabled = 1;
	    if (--i < 0)
		break;
	    col = strlen(E.List[i]);
	}
    }
    title("Pattern Not Found");
    Abortcommand = 1;
    return;

found:
    E.Line = i;
    E.Column = col;

    text_load();
    if (Doreplace) {
	if (rlen > flen && rlen-flen+strlen(ptr) > 254) {
	    title("Replace: Line Too Long");
	    Abortcommand = 1;
	    return;
	}
	if (Clen-col-flen >= 0) {
	    bmov(Current+col+flen, Current+col+rlen, Clen-col-flen+1);
	    bmov(Rstr, Current+col, rlen);
	    Clen += rlen-flen;
	}
	text_sync();
	text_redisplaycurrline();
    } else {
	text_sync();
    }
}


SHAR_EOF
#	End of shell archive
exit 0