[comp.sources.amiga] v89i189: hyperhelp - amiga help system, Part03/03

page%swap@Sun.COM (Bob Page) (10/26/89)

Submitted-by: jap@syssun.cl.msu.edu (Joe A. Porkka)
Posting-number: Volume 89, Issue 189
Archive-name: applications/hyphelp.3

# This is a shell archive.
# Remove anything above and including the cut line.
# Then run the rest of the file through 'sh'.
# Unpacked files will be owned by you and have default permissions.
#----cut here-----cut here-----cut here-----cut here----#
#!/bin/sh
# shar: SHell ARchive
# Run the following text through 'sh' to create:
#	helptext.h
#	image.c
#	indev.c
#	index.c
#	kludge.h
#	link
#	main.c
#	menu.c
#	move.c
#	oserr.c
#	print.c
#	source.readme
#	style.h
#	tokens.c
#	windows.c
# This is archive 3 of a 3-part kit.
# This archive created: Wed Oct 25 10:02:52 1989
echo "extracting helptext.h"
sed 's/^X//' << \SHAR_EOF > helptext.h
X/* HyperHelp -- Copyright 1989 Joe Porkka */
X
X/* helptext.h  --  The structure definitions for text management stuff */
X
Xstruct displaylines {
X    u_short offset;
X    u_char length, style, color;
X};
Xstruct paragraph {
X    u_char  *data;
X    u_char indent, pindent;
X    u_short length, count;
X    struct displaylines *lines;
X};
X
Xstruct	labels {
X    u_char  *name;
X    u_short paragraph;
X    u_short line;
X};
X
X#define DOC_FORMATED 1
X#define COMWIDTH 116
Xstruct textbody {
X    u_char *text, *filename;
X    unsigned long length;
X    u_short usecount;
X    struct TextAttr font;
X    u_char  comment[COMWIDTH];
X};
X
Xstruct	doc {
X    u_short lab_count;
X    struct labels *labs;
X    u_short p_count;
X    struct paragraph *p;  /* linked list of lines, formatted nicely */
X    u_char linespace, flags; /* doc flags, line spacing */
X    u_short l_count; /* total pargaphs & lines */
X    u_short pnum, lnum; /* current position */
X    struct TextFont *savefont;
X    u_short *propwidth;
X    struct textbody *body;
X};
X
Xstruct HelpNode {
X    struct  openwindows *ln_Succ;
X    struct  openwindows *ln_Pred;
X};
X
X#define ow_REFRESH 1
X#define ow_ICONIZED 2
X#define ow_SIZED 4
X#define ow_PRINTWINDOW 8
X#define ow_PRINTFILE 16
X#define ow_PRINTING 32
Xstruct openwindows {
X    struct HelpNode node;
X    struct Window *window;
X    struct Gadget *scroll,*up,*down,*icon;
X    struct doc *doc;
X    /* Save window dimensions of the current window, to prevent */
X    /* race conditions, and remember where hidden windows where */
X    SHORT LeftEdge, TopEdge;
X    SHORT Width, Height; /* Prevent race condition with user resizes */
X    SHORT MinWidth, MinHeight;
X    /*	*/
X    short  wide,high; /* character dimensions */
X    /* Save window dimensions of the icon or full size window */
X    short savewide, savehigh, saveleft, savetop;
X    short saveminwidth, saveminheight;
X    u_short flags;
X};
X
SHAR_EOF
echo "extracting image.c"
sed 's/^X//' << \SHAR_EOF > image.c
X/* HyperHelp -- Copyright 1989 Joe Porkka */
X
X/* image.c -- Contains the image data for the arrow gadgets.
X	      NOTE: The data part of this file *MUST* be forced
X		    into CHIP memory.
X*/
X
Xtypedef unsigned short USHORT;
X	    /*	   FEDCBA9876543210 */
X
X/*
X   The DATA section of this file must be forced into CHIP memory by
X   the compiler.
X   I want the program to be compiled with 16bit register offset addressing
X   for efficiency.
X   This causes a link error, since this DATA section
X   can not be combined with the rest of the DATA sections.
X   This function allows me to compile the rest of the program with 16bit
X   addressing.
X*/
Xstatic USHORT upimage[10]={
X 0xc000,    /*	   11.............. */
X 0xffff,    /*	   1111111111111111 */
X 0xfcff,    /*	   111111..11111111 */
X 0xf03f,    /*	   1111......111111 */
X 0xe49f,    /*	   111..1..1..11111 */
X 0xcccf,    /*	   11..11..11..1111 */
X 0xfcff,    /*	   111111..11111111 */
X 0xfcff,    /*	   111111..11111111 */
X 0xffff,    /*	   1111111111111111 */
X 0xc000     /*	   11.............. */
X};
Xstatic USHORT downimage[9]={
X 0xffff,    /*	   1111111111111111 */
X 0xfcff,    /*	   111111..11111111 */
X 0xfcff,    /*	   111111..11111111 */
X 0xcccf,    /*	   11..11..11..1111 */
X 0xe49f,    /*	   111..1..1..11111 */
X 0xf03f,    /*	   1111......111111 */
X 0xfcff,    /*	   111111..11111111 */
X 0xffff,    /*	   1111111111111111 */
X 0xc000     /*	   11.............. */
X};
X
X/*  nk. ( repeat 1 ((11..) del del del del left left left left down)) */ */
X
XUSHORT iconimage[40]={
X    0xcfff, 0xffc0,    /* 11.. 1111 1111 1111 1111 1111 11...... */
X    0xcc00, 0x00c0,    /* 11.. 11.. .... .... .... .... 11...... */
X    0xccff, 0xc0c0,    /* 11.. 11.. 1111 1111 11.. .... 11...... */
X    0xccff, 0xc0c0,    /* 11.. 11.. 1111 1111 11.. .... 11...... */
X    0xccff, 0xc0c0,    /* 11.. 11.. 1111 1111 11.. .... 11...... */
X    0xccff, 0xc0c0,    /* 11.. 11.. 1111 1111 11.. .... 11...... */
X    0xcc00, 0x00c0,    /* 11.. 11.. .... .... .... .... 11...... */
X    0xcc00, 0x00c0,    /* 11.. 11.. .... .... .... .... 11...... */
X    0xcc00, 0x00c0,    /* 11.. 11.. .... .... .... .... 11...... */
X    0xcfff, 0xffc0,    /* 11.. 1111 1111 1111 1111 1111 11...... */
X
X    0x0000, 0x0000,    /* .... .... .... .... .... .... ........ */
X    0x0000, 0x0f00,    /* .... .... .... .... .... 1111 ........ */
X    0x00ff, 0xcf00,    /* .... .... 1111 1111 11.. 1111 ........ */
X    0x00ff, 0xcf00,    /* .... .... 1111 1111 11.. 1111 ........ */
X    0x00ff, 0xcf00,    /* .... .... 1111 1111 11.. 1111 ........ */
X    0x00ff, 0xcf00,    /* .... .... 1111 1111 11.. 1111 ........ */
X    0x0c00, 0x0f00,    /* .... .... .... .... .... 1111 ........ */
X    0x0fff, 0xff00,    /* .... 1111 1111 1111 1111 1111 ........ */
X    0x0fff, 0xff00,    /* .... 1111 1111 1111 1111 1111 ........ */
X    0x0000, 0x0000     /* .... .... .... .... .... .... ........ */
X};
X
Xvoid getimages(up, down, icon)
X    USHORT **up, **down, **icon;
X{
X    *up=upimage;
X    *down=downimage;
X    *icon=iconimage;
X}
X
X
SHAR_EOF
echo "extracting indev.c"
sed 's/^X//' << \SHAR_EOF > indev.c
X#include <exec/types.h>
X#include <exec/ports.h>
X/* #include <exec/memory.h> */
X#include <exec/io.h>
X#include <exec/tasks.h>
X#include <exec/interrupts.h>
X#include <devices/input.h>
X#include <exec/devices.h>
X#include <devices/inputevent.h>
X
XUBYTE recevent;
XUWORD Code, Qual;
X
Xstatic struct MsgPort *inputDevPort;
Xstatic struct IOStdReq *inputRequestBlock;
Xstatic struct Interrupt handlerStuff;
X
Xextern struct MsgPort *CreatePort();
Xextern struct IOStdReq *CreateStdIO();
X
Xextern HandlerInterface();
Xextern unsigned int HotKeyCode, HotKeyQual;
Xint mysig;
X
Xextern long stdout, debug;
X
Xint
Xwaitforhotkey() {
X	SHORT error;
X	int signum=0, status;
X
X	inputDevPort=0;
X	inputRequestBlock=0;
X	recevent=0;
X
X	mysig= 1 << (signum=AllocSignal(-1));
X	if (signum==0) goto fail;
X
X	inputDevPort = CreatePort(0,0);         /* for input device */
X	if(inputDevPort == NULL) {              /* error during createport */
X	    goto fail;
X	}
X	inputRequestBlock = CreateStdIO(inputDevPort);
X	if(inputRequestBlock == 0) {
X	    goto fail;
X	}
X
X	handlerStuff.is_Data = 0;
X	handlerStuff.is_Code = (VOID *)HandlerInterface;
X	handlerStuff.is_Node.ln_Pri = 51;
X	error = OpenDevice("input.device",0,inputRequestBlock,0);
X	if(error) {
X	    DeleteStdIO(inputRequestBlock);
X	    inputRequestBlock=0;
X	    goto fail;
X	}
X
X	inputRequestBlock->io_Command = IND_ADDHANDLER;
X	inputRequestBlock->io_Data = (APTR)&handlerStuff;
X
X	DoIO(inputRequestBlock);
X#ifdef DEBUG1
X	dmsg(1,"Handler installed.\n");
X#endif
X
X#ifdef DEBUG1
X	dmsg(1,"HotKeyCode=%ld, Qual=%ld\n",HotKeyCode, HotKeyQual);
X#endif
X	for(;;)
X	{
X	    recevent=0;
X	    do {
X		Wait(-1);
X	    } while(recevent==0);
X
X#ifdef DEBUG1
X	    dmsg(1,".");
X#endif
X	    /*
X	    if(Code == 95 && (Qual & 0x0009)==0x0009) {
X		status=0;
X		recevent=0;
X		break;
X	    } else
X	    */
X	    if(Code == HotKeyCode && (Qual & HotKeyQual)==HotKeyQual) {
X		status=1;
X		recevent=0;
X		break;
X	    }
X	}
X
X	/* remove the handler from the chain */
X	inputRequestBlock->io_Command = IND_REMHANDLER;
X	inputRequestBlock->io_Data = (APTR)&handlerStuff;
X	DoIO(inputRequestBlock);
X	CloseDevice(inputRequestBlock);
X	DeleteStdIO(inputRequestBlock);
X	DeletePort(inputDevPort);
X	if(signum) FreeSignal(signum);
X	return status;
X
Xfail:
X	if(inputRequestBlock) {
X	    CloseDevice(inputRequestBlock);
X	    DeleteStdIO(inputRequestBlock);
X	}
X	if(inputDevPort) DeletePort(inputDevPort);
X	if(signum) FreeSignal(signum);
X	return 0;
X}
SHAR_EOF
echo "extracting index.c"
sed 's/^X//' << \SHAR_EOF > index.c
X/* HyperHype -- Copyright 1989 Joe Porkka */
X
X/* index.c -- look up a word in an index file */
X
X#include <exec/types.h>
X#include <exec/memory.h>
X#include <libraries/dos.h>
X#include <libraries/dosextens.h>
X#include "help.h"
X#define DEBUG1
X
X
X#define MAXWORDLEN 500
X#define QUOTE_CHAR '"'
X#define ESC_CHAR '\\'
X#define GETCHAR  {\
X    len--;\
X    pos++;\
X    if (len<=0) {\
X	if ((len=Read(fh,pos=buffer,blocksize))<=0) return 0;\
X    }\
X}
X
X/* #define INDEXFILE "help:index" */
X
Xstatic u_char *buffer;
Xstatic u_long blocksize;
Xextern u_long oserr;
Xextern int debug;
X
Xu_char *
Xlookup(fh,word,wlen)
X    u_long fh;
X    u_char *word;
X    int wlen;
X{
X    register u_char *pos=0, *wpos, *wend=word+wlen, a, b;
X    int len=0;
X#ifdef DEBUG1
X    dmsg(1,"lookup(fh,'%s',%ld);\n",word,wlen);
X#endif
X    do {
X	for(wpos=word;wpos<wend;wpos++) {
X	    GETCHAR;
X	    a=*pos; if(a==' ' || a=='\t' || a=='\n') break;
X	    b=*wpos;
X#ifdef DEBUG1
X	    dmsg(1,"%lc%lc,",a,b);
X#endif
X	    if(a!=b) {
X		if(a>='a' && a<='z') a-=32;
X		if(b>='a' && b<='z') b-=32;
X		if(a != b ) break;
X	    }
X	}
X	if(wpos==wend) {
X#ifdef DEBUG1
X	    dmsg(1,"\nGOTIT!\n");
X#endif
X	    GETCHAR;
X	    return(pos);
X	}
X	while (*pos!='\n') GETCHAR;
X#ifdef DEBUG1
X	dmsg(1,"\n");
X#endif
X    } while(1);
X    return(0);
X}
X
Xvoid
Xindex(filename,key)
X    u_char *filename;
X    struct key *key;
X{
X    int wlen;
X    u_char *word=key->name;
X    u_long fh=0, len;
X    u_char *pos;
X    int  usedlen;
X
X    for(wlen=0;key->name[wlen]!=' ' && key->name[wlen]!=0;wlen++);
X    key->length=key->type=0;
X    key->name=0;
X
X#ifdef DEBUG1
X    dmsg(1,"\nINDEX.index() Looking up '");
X#endif
X    fh=openindexfile(filename);
X    if(fh==0) {
X#ifdef DEBUG5
X	dmsg(5,"Error opening '%s' IoErr==%ld\n",filename,oserr);
X#endif
X	goto fail;
X    }
X    oserr=0;
X    pos=lookup(fh,word,wlen);
X    if(pos==0) {
X#ifdef DEBUG1
X	dmsg(1,"FAILED!\n");
X#endif
X	goto fail;
X    }
X    len= buffer+blocksize-pos;
X#ifdef DEBUG1
X    dmsg(1,"INDEX RETURNS:\n'");
X#endif
X
X    while(*pos!='\t' && *pos!=' ') {
X	pos++;
X	if ( len == 0 ) {
X	    if ( ((len=Read(fh,pos=buffer,blocksize))==0)){
X		oserr=IoErr();
X#ifdef DEBUG5
X		dmsg(5,"IOERR=%ld ",oserr);
X#endif
X		goto fail;
X	    }
X	}
X	len--;
X    }
X
X    while (*pos==' ' ||*pos=='\t') {
X	pos++;
X	if ( len == 0 ) {
X	    if ( ((len=Read(fh,pos=buffer,blocksize))==0)){
X		oserr=IoErr();
X#ifdef DEBUG5
X		dmsg(5,"IOERR=%ld ",oserr);
X#endif
X		goto fail;
X	    }
X	}
X	len--;
X    }
X    if( *pos=='x' || *pos=='X' )
X	key->type=1;
X    else if(*pos!='r' && *pos!='R') {
X#ifdef DEBUG6
X	dmsg(6,"Error in index file!!'%lc'\n",*pos);
X#endif
X	goto fail;
X    }
X
X    do {
X	pos++;
X	if ( len == 0 ) {
X	    if ( ((len=Read(fh,pos=buffer,blocksize))==0)){
X		oserr=IoErr();
X#ifdef DEBUG5
X		dmsg(5,"IOERR=%ld ",oserr);
X#endif
X		goto fail;
X	    }
X	}
X	len--;
X    } while(*pos=='\t' || *pos==' ');
X
X    key->length=80;
X    key->name=(u_char *)AllocMem(key->length,MEMF_CLEAR);
X    if(key->name==0) goto fail;
X    usedlen=0;
X    while( 1 ) {
X	key->name[usedlen++]=*pos;
X
X	if(*pos++=='\n') {
X	    key->name[--usedlen]=0;
X	    break;
X	}
X
X	if(usedlen>=key->length) {
X	    u_char *t;
X	    t=(u_char *)AllocMem(key->length+80,MEMF_CLEAR);
X	    if(t==0) {
X		goto fail;
X	    }
X	    CopyMem(key->name,t,key->length);
X	    FreeMem(key->name,key->length);
X	    key->name=t;
X	    key->length+=80;
X	}
X	if ( len == 0 ) {
X	    if ( ((len=Read(fh,pos=buffer,blocksize))==0)){
X		oserr=IoErr();
X#ifdef DEBUG"IOERR=%ld "
X		dmsg("IOERR=%ld ",oserr);
X#endif
X		break;
X	    }
X	}
X	len--;
X
X    }
X    if(fh) closeindexfile(fh);
X    return;
Xfail:
X    if(key->name!=0 && key->length!=0) FreeMem(key->name,key->length);
X    key->name=0;
X    key->length=0;
X    if(fh) closeindexfile(fh);
X    return ;
X}
X
Xu_long
Xopenindexfile(name)
X    u_char *name;
X{
X    struct InfoData *diskinfo=0;
X    struct  Lock *lock=0,*Lock();        /* to get info about the disk */
X    u_long fh=0;
X
X    buffer=0;
X    blocksize=0;
X
X    if( (diskinfo=(struct InfoData *)AllocMem(sizeof(struct InfoData),0))==0) goto fail;
X
X    if( (lock=Lock(name,1005))==0) {
X	oserr=IoErr();
X	goto fail;
X    }
X    if( Info(lock,diskinfo)==0) {
X	oserr=IoErr();
X	goto fail;
X    }
X    blocksize=diskinfo->id_BytesPerBlock;
X    if (diskinfo) FreeMem((u_char *)diskinfo,sizeof(struct InfoData));
X    diskinfo=0;
X    buffer=(u_char *)AllocMem(blocksize,0);
X    if(buffer==0) {
X	oserr=103;
X	goto fail;
X    }
X    if( (fh=Open(name,1005))==0){
X	oserr=IoErr();
X	goto fail;
X    }
X    UnLock(lock);
X    oserr=0;
X    return(fh);
X
Xfail:
X    if (lock)     UnLock(lock);
X    if (fh) Close(fh);
X    if (diskinfo) FreeMem((u_char *)diskinfo,sizeof(struct InfoData));
X    if (blocksize && buffer) FreeMem(buffer,blocksize);
X    blocksize=0;
X    buffer=0;
X    return(0);
X}
X
Xvoid
Xcloseindexfile(fh)
X    u_long fh;
X{
X    if (fh==0) return;
X    if (blocksize && buffer) FreeMem(buffer,blocksize);
X    blocksize=0;
X    buffer=0;
X    Close(fh);
X    fh=0;
X}
X
X
SHAR_EOF
echo "extracting kludge.h"
sed 's/^X//' << \SHAR_EOF > kludge.h
X/* The following ugliness if brought to you by a BUG in LATTICE 3.10 */
X    /* printitout(); */
X    if(printing) {
X	dmsg(1,"Cancel print job! printing=%ld\n",printing);
X	printing=0;
X	if(printow) {
X	    closewindow(printow);
X	    printow=0;
X	    dmsg(1,"About to dnit print\n");
X	    printdnit();
X	}
X	dmsg(1,"About to free printbuffer...");
X	if(printbuf && printbuflen) FreeMem(printbuf,printbuflen);
X	printbuf=0;
X	printbuflen=0;
X	dmsg(1,"Freed!\n");
X    }
X
SHAR_EOF
echo "extracting link"
sed 's/^X//' << \SHAR_EOF > link
Xfrom c.o+debug.o+print.o+tokens.o+menu.o+indev.o+grandcentral.o+cxm33.o+fileinit.o+getfile.o+index.o+findwordinline.o+format.o+move.o+cxd33.o+image.o+displayline.o+windows.o+main.o+gen.o+oserr.o+getenv.o+gc2.o
Xto help
Xlib lib:amiga.lib
Xsmalldata
Xnodebug
X
SHAR_EOF
echo "extracting main.c"
sed 's/^X//' << \SHAR_EOF > main.c
X/* HyperHelp -- Copyright 1989 Joe Porkka */
X
X/* main.c -- Handles startup and shut down of HyperHelp */
X
X#include <intuition/intuition.h>
X#include <exec/memory.h>
X#include <graphics/text.h>
X#include "help.h"
X#include "helptext.h"
X
Xextern long stdin, stdout,oserr, outwindow;
Xextern short windowcount, menucount;
Xextern struct Screen *screen;
Xextern struct List windowhead;
Xextern struct TextAttr font;
X
Xlong IntuitionBase=0, GfxBase=0, DiskfontBase=0;
Xstruct MsgPort *mp, *CreatePort(), *FindPort();
Xlong debug;
X
X/* Environment externals */
X
Xextern int ScreenType;
Xextern char *ENVRootFile, *ENVIndexFile;
Xextern int ENVAskFirst;
Xextern struct TextAttr *ENVFont;
X
Xchar *RootFile, *IndexFile;
X
Xvoid
Xmain(av,ac)
X    int av;
X    char *ac;
X{
X    char *string=0;
X    int test, quiet;
X    struct openwindows *ow;
X
X    debug=0; test=0; quiet=0;
X    ENVRootFile=ENVIndexFile=0;
X    RootFile="help:toplevel";
X    IndexFile="help:index";
X    while (av>0) {
X	if(string==0) string=arg(&av, &ac);
X	dmsg(1,"string='%s' av=%ld ac='%s'.\n",string,av,ac);
X	if(strnicmp("debug",string,5)==0) {
X	    debug=1;
X	    string=arg(&av, &ac);
X	    if(*string> '0' && *string <='9') {
X		debug = *string-'0';
X		string=0;
X	    }
X	} else if(strnicmp("quiet",string,5)==0) {
X	    quiet=1;
X	    string=0;
X	}
X    }
X    if(startup()==0) goto fail;
X#ifdef DEBUG9
X    dmsg(9,"Debug level=%ld., string='%s'\n",debug,string);
X#endif
X
X    if(ENVRootFile) RootFile=ENVRootFile;
X    if(ENVIndexFile) IndexFile=ENVIndexFile;
X    if(quiet) {
X	dmsg(1,"Waiting for hotkey!\n");
X	if(!waitforhotkey()) {
X	    die("canel quiet mode!");
X	    goto fail;
X	}
X    }
X
X    do	{
X	/*
X	if(windowcount==0) {
X	    ow=getfile(RootFile);
X	    if(ow==0) {
X		die("Could not open initial file.");
X		goto fail;
X	    }
X	    refresh(ow);
X	}
X	*/
X	test=grandcentral();
X	if(test) test=waitforhotkey();
X    } while(test);
X
X    die("All done!");
Xfail:
X    stdout=0;
X    /* return; */
X}
X
Xint
Xstartup() {
X
X    stdout=0;
X    stdin=0;
X    mp=0; windowcount=0; menucount=0;
X    screen=0;
X    if(fileinit()==0) {
X	die("Could not start IO stuff.");
X	return(0);
X    }
X    meminit();
X    /* Open V1.2 Libraries */
X    if ( (IntuitionBase= OpenLibrary("intuition.library",33)) == 0 ||
X	 (GfxBase      = OpenLibrary("graphics.library",33))  == 0) {
X	 die("Could not open system libraries.");
X	 return(0);
X    }
X    /* Don't get installed twice! */
X    Forbid();
X    mp=FindPort("HyperHelp");
X    Permit();
X    if(mp) {
X	mp=0;
X	die("HyperHelp already installed!");
X	return(0);
X    }
X    if( (mp=CreatePort("HyperHelp",0))==0) {
X	die("Could not Allocate a Port.");
X	return(0);
X    }
X
X    getenv(); /* This MUST be before windowinit() !!! */
X
X    if(windowinit()==0) {
X	die("Could not start windows stuff.");
X	return(0);
X    }
X
X    return(-1);
X}
X
Xvoid
Xshutdown() {
X    /* struct openwindows *ow; */
X    struct IntuiMessage *im,*GetMsg();
X
X    if(IntuitionBase) {
X	closeallwindows();
X	if(mp) {
X	    while(im=GetMsg(mp)) {
X		ReplyMsg(im);
X	    }
X	    DeletePort(mp);
X	    mp=0;
X	}
X	if(screen!=0) {
X#ifdef DEBUG9
X	    dmsg(9,"Main had to close the screen!!\n");
X#endif
X	    CloseScreen(screen);
X	    screen=0;
X	}
X	CloseLibrary(IntuitionBase);
X	IntuitionBase=0;
X    }
X    if(GfxBase) {
X	CloseLibrary(GfxBase);
X	GfxBase=0;
X    }
X    if(DiskfontBase) {
X	CloseLibrary(DiskfontBase);
X	DiskfontBase=0;
X    }
X    if(ENVRootFile) FreeMem(ENVRootFile, strlen(ENVRootFile)+1);
X    if(ENVIndexFile) FreeMem(ENVIndexFile, strlen(ENVIndexFile)+1);
X    if(ENVFont) {
X	if(ENVFont->ta_Name) FreeMem(ENVFont->ta_Name, strlen(ENVFont->ta_Name)+1);
X	FreeMem(ENVFont,sizeof(struct TextAttr));
X	ENVFont=0;
X    }
X    ENVRootFile=ENVIndexFile=0;
X    membye();
X    if(outwindow) Close(outwindow);
X    outwindow=0;
X    stdout=0;
X}
X
Xvoid
Xdie(string)
X    char *string;
X{
X    if(string)
X#ifdef DEBUG5
X	dmsg(5,"HELP: %s\n",string);
X#endif
X    shutdown();
X}
X
X/* These functions shuld be in grandcentral.c
X   However, lc1 runs out of mem if they are there
X*/
Xvoid
Xclosewindow(tmpow)
X    struct openwindows *tmpow;
X{
X#ifdef DEBUG1
X    dmsg(1,"Going to closewindowsafely...");
X#endif
X    closewindowsafely(tmpow);
X#ifdef DEBUG1
X    dmsg(1,"closed!\n");
X#endif
X    tmpow->window=0;
X    Remove(tmpow);
X#ifdef DEBUG1
X    dmsg(1,"Freeingfile...");
X#endif
X    freefile(tmpow->doc);
X#ifdef DEBUG1
X    dmsg(1,"Freed!\n");
X#endif
X    FreeMem(tmpow,sizeof(struct openwindows) );
X#ifdef DEBUG1
X    dmsg(1,"tompow freed!\n");
X#endif
X}
X
X/* From print.c */
Xextern struct IOStdReq *printreq;
Xextern int printing, printbuflen;
Xextern u_char *printbuf;
Xextern struct openwindows *printow;
Xprintitout()
X{
X    struct openwindows *ow;
X    struct doc *doc;
X    struct textbody *body;
X#ifdef DEBUG1
X    dmsg(1,"windowcount=%ld\n",windowcount);
X#endif
X    for(ow=(struct openwindows*)windowhead.lh_Head ; ow->node.ln_Succ; ow=ow->node.ln_Succ) {
X#ifdef DEBUG1
X	dmsg(1,"\nOW->HelpNode=%lx, window=%ld, scroll=%ld, doc=%ld flags=0x%lx\n",
X	    &ow->node, ow->window, ow->scroll, ow->doc, ow->flags);
X#endif
X	doc=ow->doc;
X	if(doc) {
X#ifdef DEBUG1
X	    dmsg(1,"DOC labc=%ld, labs=%ld pc=%ld parag=%ld, lcount=%ld, pnum=%ld, lnum=%ld\n",
X		doc->lab_count, doc->labs, doc->p_count, doc->p, doc->l_count, doc->pnum, doc->lnum);
X#endif
X#ifdef DEBUG1
X	    dmsg(1,"\tsavefont=%ld body=%ld\n",doc->savefont, doc->body);
X#endif
X	    body=doc->body;
X	    if(body) {
X#ifdef DEBUG1
X	    dmsg(1,"BODY text=%ld, filename='%s', len=%ld, usecount=%ld\n",
X		body->text, body->filename, body->length, body->usecount);
X#endif
X	    }
X	}
X    }
X    if(stdout) {
X#ifdef DEBUG1
X	dmsg(1,"PRESS ENTER!");
X#endif
X	Read(stdout,"buffer",1);
X    }
X}
X
Xcloseallwindows()
X{
X    struct openwindows *ow;
X
X    while(ow=(struct openwindows *)RemHead(&windowhead)) {
X	if(ow->flags & ow_PRINTING) {
X#ifdef DEBUG1
X	    dmsg(1,"main:Closeing off a printing file!\n");
X#endif
X	    if(printreq) {
X		int error=AbortIO(printreq);
X
X		if(error) {
X#ifdef DEBUG99
X		    dmsg(99,"AbortIO(printreq)=%ld. BADTHING\n",error);
X#endif
X		}
X		WaitIO(printreq);
X		printing=0;
X	    }
X#include "kludge.h"
X	    /* cancelprintjob(); */
X#ifdef DEBUG10
X	    dmsg(10,"MAIN BACK FROM CANCEL!\n");
X#endif
X	} else {
X	    closewindowsafely(ow);
X	}
X	freefile(ow->doc);
X	FreeMem(ow,sizeof(struct openwindows));
X    }
X}
X
X/* Put up an AutoRequester to verify an Execute before we do it */
Xint
Xaskforexec(win,exectext)
X    struct Window *win;
X    UBYTE  *exectext;
X{
X    static struct TextAttr font = {
X	"topaz.font",9,0,0
X    } ;
X    /* IntuiTexts for the Body + OK + CANCEL buttons. Static to avoid the stack */
X    static struct IntuiText body3={
X	0,1,
X	JAM2,6,19,&font,
X	(UBYTE *)"Do you wish to allow it?",
X	0
X    };
X    static struct IntuiText body2={
X	0,1,
X	JAM2,6,11,&font,
X	0,
X	&body3
X    };
X    static struct IntuiText body1={
X	0,1,
X	JAM2,6,3,&font,
X	(UBYTE *)"That references attempts to make this execute",
X	&body2
X    };
X    static struct IntuiText yesbutton={
X	0,1,
X	JAM2,6,4,&font,
X	(UBYTE *)"Yes",
X	0
X    };
X    static struct IntuiText nobutton={
X	0,1,
X	JAM2,6,4,&font,
X	(UBYTE *)"No!",
X	0
X    };
X
X    int textlen, width,test;
X    char tmp[64];
X    if(!ENVAskFirst) return 1;
X    textlen=strlen(exectext);
X    if(textlen>60) textlen=60;
X    strncpy(tmp,exectext,60);
X    tmp[60]=0;
X    width=strlen(body1.IText);
X    if(width<textlen) width=textlen;
X    body2.IText=tmp;
X
X    dmsg(1,"****\nAutorequest Width=%ld.\n",width);
X
X    test=AutoRequest(win,&body1,&yesbutton, &nobutton,0,0,width*10+40,63);
X    return test;
X}
X
X/* About()
X    HyperHelp  Version 1.0
X    Written by Joe Porkka -- porkka@frith.egr.msu.edu
X    Copyight 1989 Joe Porkka. All rights reserved.
X    (517) 337-9472
X*/
Xabout(win)
X    struct Window *win;
X{
X    static struct TextAttr font = {
X	"topaz.font",8,0,0
X    };
X    /* IntuiTexts for the Body + OK buttons. Static to avoid the stack */
X    static struct IntuiText body4={
X	0,1,
X	JAM2,6,30,&font,
X	(UBYTE *)"(517) 337-9472",
X	0
X    };
X    static struct IntuiText body3={
X	0,1,
X	JAM2,6,21,&font,
X	(UBYTE *)"Copyright 1989 Joe Porkka. All right reserved.",
X	&body4
X    };
X    static struct IntuiText body2={
X	0,1,
X	JAM2,6,12,&font,
X	(UBYTE*)"Written by Joe Porkka -- porkka@frith.egr.msu.edu",
X	&body3
X    };
X    static struct IntuiText body1={
X	0,1,
X	JAM2,6,3,&font,
X	(UBYTE *)"HyperHelp Version 1.0",
X	&body2
X    };
X    static struct IntuiText yesbutton={
X	0,1,
X	JAM2,6,4,&font,
X	(UBYTE *)"OK!",
X	0
X    };
X
X    AutoRequest(win,&body1,&yesbutton, &yesbutton,0,0,strlen(body2.IText)*8+40,71);
X}
X
X
SHAR_EOF
echo "extracting menu.c"
sed 's/^X//' << \SHAR_EOF > menu.c
X/* HyperHelp -- Copyright 1989 Joe Porkka */
X
X/* menu.c -- Sets up and removes window menus.
X
X*/
X
X#include <intuition/intuition.h>
X#include <graphics/text.h>
X#include "help.h"
X#include "helptext.h"
X
Xextern long IntuitionBase, GfxBase, DiskfontBase;
Xextern int debug;
X
Xstatic struct Menu ControlMenu, PrintMenu;
Xstatic struct MenuItem CFile, COpen, CClose, CHide, CGo, CAbout;
Xstatic struct IntuiText TCFile, TCOpen, TCClose, TCHide, TCGo, TCAbout;
Xstatic struct MenuItem PWindow, PFile, PCancel;
Xstatic struct IntuiText TPWindow, TPFile, TPCancel;
X
Xstatic int titleh, titlew; /* Text dimensions */
X/* BAD thing: always use topaz 9 */
X/* Also used in main for the AutoRequest */
Xstruct TextAttr font={
X    "topaz.font",
X    9,
X    0,
X    0
X};
X
Xshort	menucount;
X
Xvoid
Xmakemenu(win)
X    struct Window *win;
X{
X#ifdef DEBUG1
X    dmsg(1,"MAKEMENU!\n");
X#endif
X    if(win==0) return;
X    if(!menucount) initmenus(win);
X    menucount++;
X#ifdef DEBUG1
X    dmsg(1,"About to set menu.\n");
X#endif
X    SetMenuStrip(win,&ControlMenu);
X#ifdef DEBUG1
X    dmsg(1,"Menu set window->MenuStrip=%ld\n",win->MenuStrip);
X#endif
X#ifdef DEBUG1
X    dmsg(1,"window->Flags=%08lx, IDCMP==%08lx.\n",win->Flags,win->IDCMPFlags);
X#endif
X}
X
Xvoid
Xremovemenu(win)
X    struct Window *win;
X{
X    if(menucount==0) {
X#ifdef DEBUG9
X	dmsg(9,"Attempt removemenu when menucount==0!\n");
X#endif
X    }
X    if(win->MenuStrip==0) {
X#ifdef DEBUG9
X	dmsg(9,"Attempt to removemenu without a menu!!\n");
X#endif
X    } else {
X	menucount--;
X	ClearMenuStrip(win);
X    }
X}
X
Xvoid
Xinitmenus(win)
X    struct Window *win;
X{
X    int left, width;
X
X#ifdef DEBUG1
X    dmsg(1,"Initializing menu structs.\n");
X#endif
X    titleh = win->WScreen->RastPort.TxHeight;
X    titlew = win->WScreen->RastPort.TxWidth;
X
X    left=titlew;
X    width=0;
X
X    domenu(&ControlMenu,"Control", &left);
X    domenu(&PrintMenu,"Print", &left);
X    ControlMenu.NextMenu = &PrintMenu;
X    PrintMenu.NextMenu=0;
X
X    domenuitem(&ControlMenu,&CFile, &TCFile,"Open A File",(BYTE)0, &width);
X    CFile.Flags &= ~ITEMENABLED;
X    domenuitem(&ControlMenu,&COpen, &TCOpen,"Open Root File",(BYTE)'O', &width);
X    domenuitem(&ControlMenu,&CClose, &TCClose,"Close All Windows",(BYTE)'C', &width);
X    domenuitem(&ControlMenu,&CHide, &TCHide, "Hide Windows",(BYTE)'H', &width);
X    domenuitem(&ControlMenu,&CGo, &TCGo, "Go Away",(BYTE)'G', &width);
X    domenuitem(&ControlMenu,&CAbout, &TCAbout, "About",(BYTE)'A', &width);
X
X    width=0;
X    domenuitem(&PrintMenu, &PWindow, &TPWindow, "Window Contents",(BYTE)'W', &width);
X    domenuitem(&PrintMenu, &PFile, &TPFile, "Entire File",(BYTE)'F', &width);
X    domenuitem(&PrintMenu, &PCancel, &TPCancel, "Cancel All Prints",(BYTE)'X', &width);
X}
X
Xvoid
Xdomenu(menu,text,left)
X    struct Menu *menu;
X    BYTE *text;
X    int *left;
X{
X    menu->LeftEdge = *left;
X    menu->TopEdge=0;
X    menu->Width = (strlen(text)+2)*titlew;
X    menu->Height=titleh;
X    menu->Flags =  MENUENABLED;
X    menu->MenuName=text;
X    menu->FirstItem=0;
X    *left +=menu->Width;
X}
X
Xvoid
Xdomenuitem(menu,item,fill,text,c, width)
X    struct Menu *menu;
X    struct MenuItem *item;
X    struct IntuiText *fill;
X    BYTE *text, c;
X    int *width;
X{
X    struct MenuItem *this;
X    int  count, thiswidth;
X
X    thiswidth = (strlen(text)+2)*10+COMMWIDTH;
X    this=menu->FirstItem;
X    if(this==0) {
X	count=0;
X	menu->FirstItem=item;
X    } else {
X	count=1;
X	while (this->NextItem) {
X	    if(this->Width < thiswidth)
X		this->Width=thiswidth;
X	    else
X		thiswidth=this->Width;
X	    this=this->NextItem;
X	    count++;
X	}
X	this->NextItem=item;
X	if(this->Width < thiswidth)
X	    this->Width=thiswidth;
X	else
X	    thiswidth=this->Width;
X    }
X    *width=thiswidth;
X    item->NextItem=0;
X    item->LeftEdge=0;
X    item->TopEdge=count*11; /* 9+2 */
X    item->Width = thiswidth;
X    item->Height = 11;
X    item->Flags = ITEMTEXT | (c ? COMMSEQ : 0) | ITEMENABLED | HIGHCOMP;
X    item->MutualExclude=0;
X    item->ItemFill=(APTR)fill;
X    item->Command=c;
X    item->SubItem=0;
X
X    fill->FrontPen=0; fill->BackPen=1;
X    fill->DrawMode = JAM2;
X    fill->LeftEdge=0;
X    fill->TopEdge=1;
X    fill->ITextFont=&font;
X    fill->IText=text;
X    fill->NextText=0;
X}
X
SHAR_EOF
echo "extracting move.c"
sed 's/^X//' << \SHAR_EOF > move.c
X/* HyperHelp -- Copyright 1989 Joe Porkka */
X
X/* move.c -- Controls movement thru a file + refresh of the windows */
X
X#include <intuition/intuition.h>
X#include "help.h"
X#include "helptext.h"
X
Xextern int PenColor, PaperColor;
Xextern int debug;
X
X
Xrectfill(rp,x1,y1,x2,y2,name,ow)
X    struct RastPort *rp;
X    long x1,y1,x2,y2;
X    u_char *name;
X    struct openwindows *ow;
X{
X    if(y1==y2) return;
X    if( x1 >= x2 || y1 >= y2) {
X#ifdef DEBUG9
X	dmsg(9,"****ERROR move.c: %s() BorderLeft >= Width-BorderRight\n",name);
X#endif
X#ifdef DEBUG9
X	dmsg(9,"****      x1=%ld, y1=%ld, x2=%ld, y2=%ld.\n",x1,y1,x2,y2);
X#endif
X#ifdef DEBUG9
X	dmsg(9,"          WindowDims=(%ld,%ld) BLeft=%ld, BRight=%ld\n",
X	    ow->Width,
X	    ow->Height,
X	    ow->window->BorderLeft,
X	    ow->window->BorderRight
X	);
X#endif
X    } else {
X	RectFill(rp,x1,y1,x2,y2);
X    }
X}
X#define RectFill rectfill
Xcleardisplay(ow)
X    struct openwindows *ow;
X{
X    struct RastPort *rp=ow->window->RPort;
X    SetAPen(rp,0);
X    RectFill(rp,
X	ow->window->BorderLeft,
X	ow->window->BorderTop,
X	ow->Width - ow->window->BorderRight,
X	ow->window->BorderTop + ow->high*rp->TxHeight,
X	"cleardisplay",
X	ow
X    );
X}
Xvoid
Xmoveto(ow,line)
X    struct openwindows *ow;
X    int line;
X{
X    int pos=currentlinenum(ow->doc);
X    if(pos-line==0) return;
X    move(ow,line-pos);
X}
X
Xvoid
Xmove(ow,dir)
X    int dir;
X    struct openwindows *ow;
X{
X    int count;
X    struct RastPort *rp=ow->window->RPort;
X    u_short pnum=ow->doc->pnum, lastp;
X    u_short lnum=ow->doc->lnum, lastl;
X    struct paragraph *p;
X
X    if(dir>0) {      /* MOVE DOWN */
X	if(dir>=ow->high) {
X	    lastp=pnum;
X	    lastl=lnum;
X	    count=0;
X	    p = &ow->doc->p[pnum];
X	    while( count < ow->high) {
X		lastl++;
X		if(lastl >= p->count) {
X		    lastl=0;
X		    lastp++;
X		    if(lastp >= ow->doc->p_count) {
X			count=0;
X			break;
X		    } else {
X			p = &ow->doc->p[lastp];
X		    }
X		}
X		count++;
X	    }
X
X	    while(dir>0 && count>0 ) {
X		dir--;
X		lastl++;
X		if(lastl >= ow->doc->p[lastp].count) {
X		    lastl=0;
X		    lastp++;
X		    if(lastp >= ow->doc->p_count) {
X			count=0;
X		    }
X		}
X		lnum++;
X		if(lnum >= ow->doc->p[pnum].count) {
X		    lnum=0;
X		    pnum++;
X		    if(pnum >= ow->doc->p_count) {
X			count=0;
X		    }
X		}
X	    }
X	    ow->doc->pnum=pnum;
X	    ow->doc->lnum=lnum;
X	    cleardisplay(ow);
X	} else {
X	    while(dir>0) {
X		dir--;
X		lastp=pnum;
X		lastl=lnum;
X		count=0;
X		p = &ow->doc->p[pnum];
X		while( count < ow->high) {
X		    lastl++;
X		    if(lastl >= p->count) {
X			lastl=0;
X			lastp++;
X			if(lastp >= ow->doc->p_count) {
X			    count=0;
X			    break;
X			} else {
X			    p = &ow->doc->p[lastp];
X			}
X		    }
X		    count++;
X		}
X		if(count) {
X		    ScrollRaster(rp,0,rp->TxHeight,
X			ow->window->BorderLeft,
X			ow->window->BorderTop,
X			ow->Width - ow->window->BorderRight,
X			ow->window->BorderTop + ow->high*rp->TxHeight-1
X		    );
X		    lnum++;
X		    if(lnum >= ow->doc->p[pnum].count) {
X			lnum=0;
X			pnum++;
X			if(pnum >= ow->doc->p_count) {
X			    count=0;
X			}
X		    }
X		    if(count==0) {
X#ifdef DEBUG9
X			dmsg(9,"** BUG!! ** count==0 after count>0\n");
X#endif
X			break;
X		    } else {
X			ow->doc->pnum=pnum;
X			ow->doc->lnum=lnum;
X		    }
X
X		    rp->cp_x= ow->window->BorderLeft;
X		    rp->cp_y=rp->TxBaseline + (ow->high-1)*rp->TxHeight + ow->window->BorderTop;
X		    displayline(rp,&ow->doc->p[lastp],lastl,ow,0,0);
X		    /*
X		    SetAPen(rp,PaperColor);
X		    RectFill(rp,
X			rp->cp_x,
X			rp->cp_y-rp->TxBaseline,
X			ow->Width - ow->window->BorderRight,
X			rp->cp_y - rp->TxBaseline + rp->TxHeight,
X			"move",
X			ow
X		    );
X		    SetAPen(rp,PenColor);
X		    */
X		} else dir=0;
X	    }
X	}
X    } else if ( pnum > 0 || lnum > 0 ) {
X	if( -dir >= ow->high) {
X	    while(dir<0 && (pnum>0 || lnum>0) ) {
X		dir++;
X		if(lnum==0 ) {
X		    pnum--;
X		    lnum = ow->doc->p[pnum].count ;
X		}
X		lnum--;
X	    }
X	    ow->doc->pnum=pnum;
X	    ow->doc->lnum=lnum;
X	    cleardisplay(ow);
X	} else {
X	    while(dir<0 && (pnum>0 || lnum>0) ) {
X		dir++;
X		ScrollRaster(rp,0, -rp->TxHeight ,
X		    ow->window->BorderLeft,
X		    ow->window->BorderTop,
X		    ow->Width - ow->window->BorderRight,
X		    ow->window->BorderTop + ow->high*rp->TxHeight -1
X		);
X		if(lnum==0 ) {
X		    pnum--;
X		    lnum = ow->doc->p[pnum].count ;
X		}
X		lnum--;
X
X		rp->cp_x= ow->window->BorderLeft;
X		rp->cp_y= rp->TxBaseline +  ow->window->BorderTop;
X		displayline(rp,&ow->doc->p[pnum],lnum,ow,0,0);
X		/*
X		SetAPen(rp,PaperColor);
X		RectFill(rp,rp->cp_x, rp->cp_y-rp->TxBaseline, ow->Width - ow->window->BorderRight, rp->cp_y - rp->TxBaseline + rp->TxHeight,"move2",ow);
X		SetAPen(rp,PenColor);
X		*/
X		ow->doc->pnum=pnum;
X		ow->doc->lnum=lnum;
X	    }
X	}
X    }
X}
X
Xint
Xcurrentlinenum(doc)
X    struct doc *doc;
X{
X    int i,n=doc->lnum;
X    for(i=0;i<doc->pnum;i++) {
X	n+=doc->p[i].count;
X    }
X    return n;
X}
X
X
Xvoid
Xrefresh(ow)
X    struct openwindows *ow;
X{
X    int i,high;
X    struct paragraph *p;
X    u_short linenum;
X    u_short pnum;
X    int rightb, leftb, baseline, height;
X    struct RastPort *rp=ow->window->RPort;
X    high = ow->high;
X
X    if(ow->flags & ow_ICONIZED) return;
X
X    pnum=ow->doc->pnum;
X    p=&ow->doc->p[pnum];
X    linenum=ow->doc->lnum;
X    SetAPen(rp,PenColor);
X    SetBPen(rp,0);
X    SetDrMd(rp,JAM2);
X    rp->cp_y=ow->window->BorderTop + rp->TxBaseline;
X    leftb=ow->window->BorderLeft;
X    rightb=ow->Width - ow->window->BorderRight;
X    baseline=rp->TxBaseline;
X    height=rp->TxHeight;
X    for(i=0;i<high;i++) {
X	rp->cp_x= ow->window->BorderLeft;
X	displayline(rp,p,linenum,ow,0,0);
X	/* RectFill(rp,rp->cp_x, rp->cp_y-baseline, rightb, rp->cp_y - baseline + height -1 ,"refresh",ow); */
X	rp->cp_y += height;
X	linenum++;
X	if(linenum >= p->count) {
X	    linenum=0;
X	    pnum++;
X	    if(pnum < ow->doc->p_count)
X		p=&ow->doc->p[pnum];
X	    else
X		break; /* end of document */
X	}
X    }
X    SetAPen(rp,0);
X    RectFill(rp,
X	ow->window->BorderLeft,
X	rp->cp_y-baseline,
X	ow->Width - ow->window->BorderRight,
X	ow->Height - ow->window->BorderBottom,"refresh2",ow
X    );
X    SetAPen(rp,PenColor);
X}
X
Xint
Xsizewindow(win)
X    struct Window *win;
X{
X    struct openwindows
X	   *ow=(struct openwindows *)win->UserData;
X    struct RastPort *rp=ow->window->RPort;
X    int wide, high;
X
X    /* ModifyIDCMP(im->IDCMPWindow, HELPWINDOWIDCMPFLAGS | SIZEVERIFY); */
X    if(rp->TxWidth==0 || rp->TxHeight==0) { /* DIVIDE BY ZERO!!!*/
X#ifdef DEBUG9
X	dmsg(9,"sizewindow: TxWidth==%ld TxHeight=%ld\n",rp->TxWidth, rp->TxHeight);
X#endif
X	goto fail;
X    }
X    if((ow->doc->linespace+ow->window->RPort->Font->tf_YSize)*3 < ow->Height) {
X	ow->window->RPort->TxHeight=ow->window->RPort->Font->tf_YSize+ow->doc->linespace;
X    } else {
X	ow->window->RPort->TxHeight=ow->window->RPort->Font->tf_YSize;
X    }
X    if(ow->doc->propwidth) {
X	/* wide = (ow->Width - win->BorderLeft - win->BorderRight)-rp->TxWidth; */
X	wide = (ow->Width - win->BorderLeft - win->BorderRight);
X    } else {
X	/* wide = (ow->Width - win->BorderLeft - win->BorderRight)/rp->TxWidth-1; */
X	wide = (ow->Width - win->BorderLeft - win->BorderRight)/rp->TxWidth;
X    }
X    high = (ow->Height- win->BorderTop - win->BorderBottom)/rp->TxHeight;
X
X    if(wide<5 || high<3 || wide>1024 || high >1024) goto fail;
X    if(wide != ow->wide) {
X#ifdef DEBUG1
X	/* dmsg(1,"wide=%ld, TxWidth=%ld\n",wide,rp->TxWidth); */
X#endif
X	ow->wide=wide;
X	if(format(ow->doc,(int)ow->wide,rp)==0) {
X#ifdef DEBUG1
X	    dmsg(1,"FORMAT FAILED!\n");
X#endif
X	    goto fail;
X	}
X	ow->doc->lnum=0;
X    }
X    if(ow->doc->lnum >= ow->doc->p[ow->doc->pnum].count) {
X	ow->doc->lnum=ow->doc->p[ow->doc->pnum].count;
X	if(ow->doc->lnum>0) ow->doc->lnum--;
X    }
X    if(ow->high>=ow->doc->l_count) { /* If doc < windowfull, move to top */
X	ow->doc->lnum=0;
X	ow->doc->pnum=0;
X	ow->high=0; /* Force fixgadget, just to be sure. */
X    }
X    if(high!=ow->high) {
X	ow->high=high;
X	fixscrollgadget(ow);
X    }
X    return (-1);
Xfail:
X    return 0;
X}
X
Xvoid
Xfixscrollgadget(ow)
X    struct openwindows *ow;
X{
X    long n=currentlinenum(ow->doc);
X    ULONG VPot, VBody;
X    struct PropInfo *p= (struct PropInfo *)ow->scroll->SpecialInfo;
X
X    if(p) {
X	if(ow->high >= ow->doc->l_count) {
X	    VBody = -1;
X	    VPot = 0;
X	} else {
X	    if(ow->doc->l_count - ow->high <1) {
X#ifdef DEBUG9
X		dmsg(9,"OOOOOPPPS!! VBODY /%ld==error\n",ow->doc->l_count-ow->high);
X#endif
X		VBody=-1;
X		VPot=-1;
X	    } else {
X		VBody= (long) (ow->high*0xffff) / (ow->doc->l_count) ;
X		VPot = (n<<16)/(ow->doc->l_count - ow->high) ;
X		if(VBody>0xffff) {
X		    VBody=0xffff;
X		}
X		if(VPot>0xffff) {
X		    VPot=0xffff;
X		}
X	    }
X	}
X	ModifyProp(ow->scroll,ow->window,0,p->Flags,0,VPot,0,VBody);
X    }
X}
X
SHAR_EOF
echo "extracting oserr.c"
sed 's/^X//' << \SHAR_EOF > oserr.c
X/* HyperHelp -- Copyright 1989 Joe Porkka */
X
X/* oserr.c -- AmigaDOS Error messages + print error routine */
X
X#include <exec/types.h>
X#include <exec/nodes.h>
X#include "help.h"
Xstruct DOSerror errortext[]={
X    {103,"Out of memory"},
X    {121,"File is not an object module"},
X    {202,"Object in use"},
X    {203,"Object already exists"},
X    {204,"Directory not found"},
X    {205,"Object not found"},
X    {206,"Invalid window"},
X    {210,"Invalid file name"},
X    {212,"Object not of required type"},
X    {213,"Disk not validated"},
X    {214,"Disk is protected"},
X    {218,"Volume is not mounted"},
X    {221,"Disk is full"},
X    {223,"File is write protected"},
X    {224,"File is read protected"},
X    {225,"Not a DOS disk"},
X    {226,"No disk in drive"},
X    {209,"Invalid packet request type"},
X    {211,"Invalid object lock"},
X    {219,"Seek error"},
X    {232,"No more entries"},
X    {0,"Invalid error number"}
X};
X
Xerrnum(i)
X    int i;
X{
X    int j=0;
X    while(errortext[j].number!=0 && i!=errortext[j].number && j<100 )j++ ;
X    return(j);
X}
X
X
SHAR_EOF
echo "extracting print.c"
sed 's/^X//' << \SHAR_EOF > print.c
X/* HyperHelp -- Copyright 1989 Joe Porkka */
X
X/* print.c -- controls printer stuff */
X
X#include <exec/types.h>
X#include <exec/io.h>
X#include <intuition/intuition.h>
X#include <devices/printer.h>
X#include <devices/prtbase.h>
X
X/* long stdout,oserr,input; */
X/* #define INBUFLEN 64 */
X/* char inbuf[INBUFLEN]; */
Xstruct IOStdReq *printreq, *CreateExtIO();
X/* struct MsgPort *mp, *CreatePort(); */
X/* long debug; */
X
X/*
Xvoid
Xmain(av,ac)
X    int av;
X    char *ac;
X{
X    int i, wide, high;
X    int len;
X
X    mp=0; printreq=0;
X    debug=1;
X    stdout=Open("CON:0/0/600/170/NOTHING",1005);
X    input=Open(":test",1005);
X    if((stdout==0) || (input==0)) goto fail;
X    if( (mp=CreatePort(0,0))==0) {
X	printf("Could not Allocate a Port.");
X	goto fail;
X    }
X    if(printinit(mp)==0) goto fail;
X    getprintwidth(&wide, &high);
X    if(wide==0) {
X	printf("Width==0\n");
X	goto fail;
X    }
X    printf("Width=%ld high=%ld\n",wide,high);
X    printit("Margins are now set. This is a long long to force it to wrap around. I hope that it does.\n");
X    WaitPort(mp);
X    GetMsg(mp);
X    printit("\033#3Margins are now unset. This is a long long to force it to wrap around. I hope that it does.\n");
X    WaitPort(mp);
X    GetMsg(mp);
X    printf("Width=%ld high=%ld\n",wide,high);
X    len=Read(input,inbuf,INBUFLEN);
X    for(i=0;len;i++) {
X	inbuf[len]=0;
X	printit(inbuf);
X	printf("Now, reading data\n");
X	len=Read(input,inbuf,INBUFLEN);
X	printf("Now, waiting for reply...");
X	WaitPort(mp);
X	GetMsg(mp);
X	printf("done. Error=%ld, Actual=%ld.\n\n",printreq->io_Error, printreq->io_Actual);
X    }
X
Xfail:
X    printf("Now closeing down.IoErr=%ld\n",IoErr());
X    printdnit();
X    if(mp) {
X	DeletePort(mp);
X	mp=0;
X    }
X    if(input) {
X	if(stdout) printf("Closing main.c\n");
X	Close(input);
X	input=0;
X    }
X    if(stdout) {
X	printf("This is the last thing that main will do!!\nPress Return\n");
X	Read(stdout,"buffer",1);
X	Close(stdout);
X    }
X    stdout=0;
X}
X*/
X
Xprintit(string)
X    char *string;
X{
X    printreq->io_Command=CMD_WRITE;
X    printreq->io_Data=(APTR)string;
X    printreq->io_Length=-1; /* Write till NULL byte */
X    SendIO(printreq);
X}
X
Xprintdnit()
X{
X    if(printreq) {
X	CloseDevice(printreq);
X	DeleteExtIO(printreq);
X	printreq=0;
X    }
X}
Xint
Xprintinit(mp)
X    struct MsgPort *mp;
X{
X    printreq=CreateExtIO(mp,sizeof(struct IOStdReq));
X    if(printreq==0) {
X	dmsg(5,"Could not create stdreq\n");
X	return(0);
X    }
X    if(OpenDevice("printer.device",0,printreq,0)!=0) {
X	dmsg(5,"Could not open printer.device!\n");
X	DeleteExtIO(printreq);
X	printreq=0;
X	return 0;
X    }
X    return -1;
X}
Xgetprintwidth(width, height)
X    int *width, *height;
X{
X    struct Preferences *prefs;
X
X    *width=*height=0;
X    if(printreq->io_Device==0) {
X	dmsg(5,"Print io_Device==0!!\n");
X	return ;
X    }
X    prefs= &((struct PrinterData *)printreq->io_Device)->pd_Preferences;
X    if(prefs) {
X	*width =  prefs->PrintRightMargin - prefs->PrintLeftMargin;
X	*height = prefs->PaperLength;
X    }
X}
SHAR_EOF
echo "extracting source.readme"
sed 's/^X//' << \SHAR_EOF > source.readme
XHere is the source code to HyperHelp.
X
XIt is copyright 1989 Joe  Porkka, but is freely
Xdistributable in its unmodified form.
XIf you want it for commercial purposes please contact me.
X
XNote to Fred Fish: I'd be honored to have you include this
X		   on one of your disks.
X
XIf you like it, please send me money. If I get enough
Xmoney I could buy some extra hardware to help development of improved
Xversions of Hyperhelp.
X
X
XPlease send suggestions and bug reports to
X		porkka@frith.egr.msu.edu
X	    or to
X		Joe Porkka
X		745 Burcham #79
X		East Lansing Mi, 48823
X		(517) 337-9472
SHAR_EOF
echo "extracting style.h"
sed 's/^X//' << \SHAR_EOF > style.h
X/* HyperHelp -- Copyright 1989 Joe Porkka */
X
X/* style.h  --	The STYLE_#? defines */
X
X/* Used by:
X    findwordinline.c
X    format.c
X    displayline.c
X    getfile.c
X*/
X
X#define NCOM		  15
X#define STYLE_REF	 128
X#define STYLE_EXEC	 129
X#define STYLE_UNREF	 130
X#define STYLE_OFFSET	(STYLE_UNREF+1)
X
X#define STYLE_NORMAL	(STYLE_UNREF+1)
X#define STYLE_UNDERLINE (STYLE_UNREF+2)
X#define STYLE_BOLD	(STYLE_UNREF+3)
X#define STYLE_ITALIC	(STYLE_UNREF+4)
X#define STYLE_COLOR	(STYLE_UNREF+5)
X#define STYLE_FONT	(STYLE_UNREF+6)
X#define STYLE_WINDOW	(STYLE_UNREF+7)
X#define STYLE_TITLE	(STYLE_UNREF+8)
X#define STYLE_LSPACE	(STYLE_UNREF+9)
X#define STYLE_INDENT	(STYLE_UNREF+10)
X#define STYLE_LABEL	(STYLE_UNREF+11)
X#define STYLE_PINDENT	(STYLE_UNREF+12)
X#define STYLE_LAST	(STYLE_UNREF+12)
X#define STYLE_INVALID	 0xff
SHAR_EOF
echo "extracting tokens.c"
sed 's/^X//' << \SHAR_EOF > tokens.c
X/* HyperHelp -- Copyright 1989 Joe Porkka */
X
X/* tokens.c  -- the tokens and the token finder */
X
X#include "df0:tf/new/style.h"
X
Xtypedef unsigned char u_char;
Xtypedef unsigned long u_long;
X
Xstatic char *(commands[NCOM]) = {
X    "ref",
X    "execute",
X    "unref",
X    "normal",
X    "underline",
X    "bold",
X    "italic",
X    "color",
X    "font",
X    "window",
X    "title",
X    "lspace",
X    "indent",
X    "label",
X    "pindent"
X};
X
X
Xu_char
Xtoken(ptr,len)
X    u_char *ptr;
X    u_long len;
X{
X    int i;
X
X    for(i=0;i<NCOM;i++) {
X	if(strnicmp(commands[i],ptr,len)==0){
X	    /* dmsg(1,"MATCHED '%s'\n",commands[i]); */
X	    return (u_char)(128+i);
X	}
X    }
X    /* dmsg(1,"FAILED\n"); */
X    return (u_char) 0;
X}
X
SHAR_EOF
echo "extracting windows.c"
sed 's/^X//' << \SHAR_EOF > windows.c
X/* HyperHelp -- Copyright 1989 Joe Porkka */
X
X/* windows.c -- Manages the windows directly. Controls open, close, sizeing
X		and refreshing damaged areas.
X*/
X
X#include <intuition/intuition.h>
X#include <exec/memory.h>
X#include <libraries/dosextens.h>
X#include <graphics/gfxbase.h>
X#include "help.h"
X#include "helptext.h"
X#define DEBUG1
X
Xextern long IntuitionBase, GfxBase, DiskfontBase;
Xextern struct MsgPort *mp, *CreatePort();
Xextern struct Task *mytask; /* Defined in getfile.c*/
Xextern int debug;
Xextern struct IOStdReq *printreq;
Xextern int printing;
X
X/* ENV: Vars */
Xextern int ScreenType, NoHotKey, PenColor;
Xextern int ENVTop, ENVLeft, ENVWidth, ENVHeight, ENVXInc, ENVYInc;
Xextern ULONG ENVRefresh;
X/**/
X
Xint TOP,LEFT,WIDTH,HEIGHT,XINC,YINC;
X
Xstruct List windowhead;
Xstatic short WBscreenWIDTH, WBscreenHEIGHT, WBscreenDETAIL, WBscreenBLOCK, WBscreenBARHEIGHT;
Xshort screenWIDTH, screenHEIGHT, screenBARHEIGHT; /* Our screen, whether it be custom or WBENCH */
X
Xstruct Process *myproc;
Xshort windowcount;
Xstruct NewWindow nw;
Xstruct Screen *screen, *OpenScreen(struct NewScreen *);
Xstruct NewScreen ns = {
X    0,0,640,STDSCREENHEIGHT,2,-1,-1,HIRES,CUSTOMSCREEN,0,"Help Screen",0,0
X};
X
X/* These only get used if getborders() cannot open a test window */
X#define DEFAULTBORDER_TOP 11
X#define DEFAULTBORDER_BOT 10
X#define DEFAULTBORDER_LEFT 4
X#define DEFAULTBORDER_RIGHT 18
X/* Dimensions of the test window */
X#define TESTWIDE 100
X#define TESTHIGH 50
X
Xstatic int borderTOP, borderBOT, borderLEFT, borderRIGHT;
X
Xint
Xwindowinit()
X{
X    struct Screen *testscreen;
X    struct GfxBase *gb=(struct GfxBase *)GfxBase;
X    int test;
X
X    if(ENVRefresh==0) {
X#ifdef DEBUG1
X	dmsg(1,"SIMPLE_REFRESH has been selected.\n");
X#endif
X	ENVRefresh = SIMPLE_REFRESH;
X    } else {
X#ifdef DEBUG1
X	dmsg(1,"SMART_REFRESH has been selected.\n");
X#endif
X	ENVRefresh = SMART_REFRESH;
X    }
X
X    screenWIDTH=WBscreenWIDTH=0;
X    screenHEIGHT=WBscreenHEIGHT=0 ;
X
X    windowhead.lh_Head= (struct Node *)&windowhead.lh_Tail;
X    windowhead.lh_TailPred= (struct Node *)&windowhead.lh_Head;
X    windowhead.lh_Tail=0;
X    windowhead.lh_Type=HELPWINDOWLIST;
X
X    testscreen=(struct Screen *)AllocMem(sizeof(struct Screen),MEMF_CLEAR);
X    test=GetScreenData(testscreen,sizeof(struct Screen),WBENCHSCREEN,0);
X    WBscreenWIDTH=screenWIDTH= gb-> NormalDisplayColumns;
X    WBscreenHEIGHT=screenHEIGHT= gb->NormalDisplayRows;
X    if(test!=0) {
X	/*
X	WBscreenWIDTH=screenWIDTH=testscreen->Width;
X	WBscreenHEIGHT=screenHEIGHT=testscreen->Height;
X	*/
X	WBscreenBARHEIGHT=screenBARHEIGHT=testscreen->BarHeight;
X	if(screenWIDTH<150 || screenHEIGHT<75) { /* Too small of a screen */
X	    test=0;
X	} else {
X	    WBscreenDETAIL=testscreen->DetailPen;
X	    WBscreenBLOCK=testscreen->BlockPen;
X	    /* Make sure things are withen bounds. If they are not
X	       then try to fix the reasonably.
X	    */
X	    if(ENVWidth<100  || ENVWidth >screenWIDTH) ENVWidth=screenWIDTH;
X	    if(ENVHeight<50 || ENVHeight>screenHEIGHT)ENVHeight=screenHEIGHT-testscreen->BarHeight-2;
X	    if(ENVLeft+ENVWidth>screenWIDTH || ENVLeft<0) ENVLeft=0;
X	    if(ENVTop+ENVHeight>screenHEIGHT || ENVTop<0) ENVTop=testscreen->BarHeight;
X	    if(ENVLeft+ENVWidth>screenWIDTH) {
X		if(screenWIDTH-ENVLeft<100) { /* Too narrow */
X		    ENVLeft=0;
X		    ENVWidth=screenWIDTH/2;
X		} else ENVWidth=screenWIDTH-ENVLeft;
X		if(ENVWidth<100) ENVWidth=100; /* Something better should be done for this... */
X	    }
X	    if(ENVTop+ENVHeight>screenHEIGHT) {
X		if(screenHEIGHT-ENVTop<50) {
X		    ENVTop=testscreen->BarHeight;
X		    ENVHeight=screenHEIGHT/2;
X		} else ENVHeight=screenHEIGHT-ENVTop;
X		if(ENVHeight<50) ENVHeight=50; /* again, something better ... */
X	    }
X	    if(ENVXInc<0 || ENVXInc>screenWIDTH) ENVXInc=5;
X	    if(ENVYInc<0 || ENVYInc>screenHEIGHT) ENVYInc=testscreen->BarHeight;
X	    if(ENVXInc==0 && ENVYInc==0) {
X		ENVXInc=5;
X		ENVYInc=testscreen->BarHeight;
X	    }
X	}
X    }
X    LEFT=ENVLeft;
X    TOP=ENVTop;
X
X    WIDTH=ENVWidth;
X    HEIGHT=ENVHeight;
X    XINC=ENVXInc;
X    YINC=ENVYInc;
X
X    if(testscreen) FreeMem(testscreen,sizeof(struct Screen));
X    if(test==0) {
X#ifdef DEBUG5
X	dmsg(5,"Could not get screen info!!!\n");
X#endif
X	return(0);
X    }
X    return (-1);
X}
X
Xvoid
Xcustomscreen() {
X    screenWIDTH  = WBscreenWIDTH; /* fail-safe DEFAULTS */
X    screenHEIGHT = WBscreenHEIGHT;
X    screenBARHEIGHT = WBscreenBARHEIGHT;
X
X    ns.Height=STDSCREENHEIGHT;
X    ns.Width=WBscreenWIDTH;
X    ns.DetailPen=WBscreenDETAIL;
X    ns.BlockPen=WBscreenBLOCK;
X    ns.ViewModes = HIRES;
X    if(ScreenType & 2) ns.ViewModes |= LACE;
X    screen=OpenScreen(&ns);
X    if(screen) {
X	screenHEIGHT=screen->Height;
X	screenWIDTH=screen->Width; /* Just to be sure... */
X	screenBARHEIGHT=screen->BarHeight;
X    }
X}
X
Xvoid
XCWS(win,font)
X    struct Window *win;
X    struct TextFont *font;
X{
X    struct MsgPort *mp = (struct MsgPort *)win->UserPort;
X    struct IntuiMessage *im, *succ;
X
X    if(win==0) {
X	return;
X    }
X    removemenu(win);
X    Forbid();
X    im = (struct IntuiMessage *)mp->mp_MsgList.lh_Head;
X    while ( succ=(struct IntuiMessage *)im->ExecMessage.mn_Node.ln_Succ ) {
X       if ( im->IDCMPWindow == win ) {
X	  Remove ( im );
X	  ReplyMsg( im );
X       }
X       im = succ;
X    }
X    win->UserPort = 0;
X    ModifyIDCMP( win, 0L );
X    Permit();
X    CloseWindow( win );
X    if(font) CloseFont(font);
X}
X
Xvoid
Xclosewindowsafely(ow)
X    struct openwindows *ow;
X{
X#ifdef DEBUG1
X    dmsg(1,"cws doing CWS...");
X#endif
X    CWS(ow->window,ow->doc->savefont);
X#ifdef DEBUG1
X    dmsg(1,"done.\n");
X#endif
X    ow->doc->savefont=0;
X    if( !(ow->flags & ow_PRINTING)) {
X	if(windowcount>0)
X	    windowcount--;
X	else
X#ifdef DEBUG9
X	    dmsg(9,"WINDOWCOUNT==%ld during closewindowsafely!\n",windowcount);
X#endif
X	if(windowcount==0 && screen) {
X	    CloseScreen(screen);
X	    screen=0;
X	}
X	if(ow->scroll) {
X#ifdef DEBUG1
X	    dmsg(1,"Freeing gadgets1...");
X#endif
X	    if(ow->scroll->SpecialInfo) FreeMem(ow->scroll->SpecialInfo,sizeof(struct PropInfo));
X	    if(ow->scroll->GadgetRender) FreeMem(ow->scroll->GadgetRender,sizeof(struct Image));
X	    FreeMem(ow->scroll,sizeof(struct Gadget));
X	    ow->scroll=0;
X#ifdef DEBUG1
X	    dmsg(1,"done.\n");
X#endif
X	}
X	if(ow->up) {
X#ifdef DEBUG1
X	    dmsg(1,"Freeing gadgets2...");
X#endif
X	    if(ow->up->GadgetRender) FreeMem(ow->up->GadgetRender,sizeof(struct Image));
X	    FreeMem( ow->up,sizeof(struct Gadget));
X	    ow->up=0;
X#ifdef DEBUG1
X	    dmsg(1,"done.\n");
X#endif
X	}
X	if(ow->down) {
X#ifdef DEBUG1
X	    dmsg(1,"Freeing gadgets3...");
X#endif
X	    if(ow->down->GadgetRender) FreeMem(ow->down->GadgetRender,sizeof(struct Image));
X	    FreeMem(ow->down,sizeof(struct Gadget));
X	    ow->down=0;
X#ifdef DEBUG1
X	    dmsg(1,"done.\n");
X#endif
X	}
X	if(ow->icon) {
X#ifdef DEBUG1
X	    dmsg(1,"Freeing gadgets4...");
X#endif
X	    if(ow->icon->GadgetRender) FreeMem(ow->icon->GadgetRender,sizeof(struct Image));
X	    FreeMem(ow->icon,sizeof(struct Gadget));
X	    ow->icon=0;
X#ifdef DEBUG1
X	    dmsg(1,"done.\n");
X#endif
X	}
X    }
X}
X
X/* This function is supposed to get sizeof(window borders).
X   There is no particularly good way of doing this with
X   version 1.3 of AmigaOS. So we default for now and
X   patiently await version 1.4....
X*/
Xvoid
Xgetborders()
X{
X    /* int test; */
X    /* int i; */
X    /* struct Screen *testscreen=(struct Screen *)AllocMem(sizeof(struct Screen),MEMF_CLEAR); */
X
X    /* Set up the the defaults in case anything fails */
X    borderTOP	= DEFAULTBORDER_TOP;
X    borderBOT	= DEFAULTBORDER_BOT;
X    borderLEFT	= DEFAULTBORDER_LEFT;
X    borderRIGHT = DEFAULTBORDER_RIGHT;
X
X    /*
X#ifdef DEBUG1
X    dmsg(1,"GETTING borders");
X#endif
X    if(testscreen==0) return; /* May as well give up now */
X
X    if(screen==0) { /* Then, get wbenchscreen data */
X	test=GetScreenData(testscreen,sizeof(struct Screen),WBENCHSCREEN,0);
X    } else { /* Else get custom screen data */
X	test=GetScreenData(testscreen,sizeof(struct Screen),CUSTOMSCREEN,screen);
X    }
X
X#ifdef DEBUG1
X    dmsg(1,"\nGot screen info, test=%ld",test);
X#endif
X    if(test==0) goto fail; /* Could not get data, don't open our screen */
X
X    borderTOP=testscreen->WBorTop;
X    borderBOT=testscreen->WBorBottom;
X    borderLEFT=testscreen->WBorLeft;
X    borderRIGHT=testscreen->WBorRight;
X#ifdef DEBUG1
X    dmsg(1,"Window borders are Top=%ld, Bot=%ld, Left=%ld, Right=%ld\n",
X	borderTOP,
X	borderBOT,
X	borderLEFT,
X	borderRIGHT
X    );
X#endif
Xfail:
X#ifdef DEBUG1
X    dmsg(1,"\ntestscreen=%ld.\n",testscreen);
X#endif
X    if(testscreen) FreeMem(testscreen,sizeof(struct Screen));
X    */
X}
X
Xstruct Window *
Xmakewindow(ow,x,y,width,height,title, myfont)
X    struct openwindows *ow;
X    int x,y,width,height;
X    u_char *title;
X    struct TextAttr *myfont;
X{
X    USHORT *upimage, *downimage, *iconimage;
X    struct TextFont *font, *diskfont, *OpenFont(), *OpenDiskFont();
X    struct Window *win, *OpenWindow();
X    struct Gadget *vertbar=0, *uparrow=0, *downarrow=0, *icon=0;
X    struct Gadget *tmp;
X    struct PropInfo *pinfo;
X    struct Image *image, *image2, *image3;
X    struct Window *tmpwindow;
X    int test;
X
X    ow->Width=width;
X    ow->Height=height;
X    getimages(&upimage,&downimage,&iconimage);
X    if(ScreenType!=0 && windowcount==0) customscreen();
X    if(windowcount==0) getborders();
X
X    if( (vertbar=(struct Gadget*)AllocMem(sizeof(struct Gadget),MEMF_CLEAR|MEMF_NAMED,"makewindow1"))==0)
X	goto fail;
X    if( (vertbar->SpecialInfo=(APTR)( pinfo=(struct PropInfo *)AllocMem(sizeof(struct PropInfo),MEMF_CLEAR|MEMF_NAMED,"makewindow2")))==0)
X	goto fail;
X    if( (vertbar->GadgetRender=(APTR)AllocMem(sizeof(struct Image),MEMF_CLEAR|MEMF_NAMED,"makewindow3"))==0)
X	goto fail;
X
X    if( (uparrow=(struct Gadget*)AllocMem(sizeof(struct Gadget),MEMF_CLEAR|MEMF_NAMED,"makewindow4"))==0)
X	goto fail;
X    if( (image=(struct Image *)AllocMem(sizeof(struct Image),MEMF_CLEAR|MEMF_NAMED,"makewindow5"))==0)
X	goto fail;
X    uparrow->GadgetRender=(APTR)image;
X    if( (downarrow=(struct Gadget*)AllocMem(sizeof(struct Gadget),MEMF_CLEAR|MEMF_NAMED,"makewindow6"))==0)
X	goto fail;
X    if( (image2=(struct Image *)AllocMem(sizeof(struct Image),MEMF_CLEAR|MEMF_NAMED,"makewindow7"))==0)
X	goto fail;
X    downarrow->GadgetRender=(APTR)image2;
X
X    if( (icon=(struct Gadget*)AllocMem(sizeof(struct Gadget),MEMF_CLEAR|MEMF_NAMED,"makewindowicon1"))==0)
X	goto fail;
X    if( (image3=(struct Image *)AllocMem(sizeof(struct Image),MEMF_CLEAR|MEMF_NAMED,"makewindowicon2"))==0)
X	goto fail;
X    icon->GadgetRender=(APTR)image3;
X
X    vertbar->NextGadget=uparrow;
X    vertbar->LeftEdge= -borderRIGHT+3 ;
X    vertbar->TopEdge= borderTOP;
X    vertbar->Width= borderRIGHT-4;
X    vertbar->Height = -borderTOP - borderBOT -16 -2; /* 16=the height of the arrows */
X
X    vertbar->Flags= GADGHNONE | GADGIMAGE | GRELRIGHT | GRELHEIGHT;
X    vertbar->Activation = GADGIMMEDIATE | FOLLOWMOUSE | RIGHTBORDER;
X    vertbar->GadgetType = PROPGADGET;
X    vertbar->GadgetID=SCROLLBAR;
X    pinfo->Flags = AUTOKNOB | FREEVERT ;
X    pinfo->HorizPot=65535;
X    pinfo->VertPot=65535;
X    pinfo->HorizBody=65535;
X    pinfo->VertBody=65535;
X
X    uparrow->NextGadget=downarrow;
X    uparrow->LeftEdge= -borderRIGHT+3;
X    uparrow->TopEdge=-borderBOT-8-8;
X    uparrow->Width=14;
X    uparrow->Height=8;
X    uparrow->Flags= GADGHCOMP | GADGIMAGE | GRELRIGHT | GRELBOTTOM;
X    uparrow->Activation = RELVERIFY | GADGIMMEDIATE | RIGHTBORDER;
X    uparrow->GadgetType = BOOLGADGET;
X    uparrow->GadgetID=UPARROW;
X    image->LeftEdge=0;
X    image->TopEdge=-1;
X    image->Width=14;
X    image->Height=10;
X    image->Depth=1;
X    image->ImageData=upimage;
X
X    image->PlanePick=1;
X    image->PlaneOnOff=0;
X
X    downarrow->NextGadget=0;
X    downarrow->LeftEdge= -borderRIGHT+3;
X    downarrow->TopEdge= -borderBOT-8+2;
X    downarrow->Width=14;
X    downarrow->Height=8;
X    downarrow->Flags= GADGHCOMP | GADGIMAGE | GRELRIGHT | GRELBOTTOM;
X    downarrow->Activation = GADGIMMEDIATE | RELVERIFY | RIGHTBORDER;
X    downarrow->GadgetType = BOOLGADGET;
X    downarrow->GadgetID=DOWNARROW;
X    image2->LeftEdge=0;
X    image2->TopEdge=-1;
X    image2->Width=14;
X    image2->Height=9;
X    image2->Depth=1;
X    image2->ImageData=downimage;
X
X    image2->PlanePick=1;
X    image2->PlaneOnOff=0;
X
X    icon->NextGadget=0;
X    icon->LeftEdge= -borderRIGHT-60;
X    icon->TopEdge= 0;
X    icon->Width=24;
X    icon->Height=10;
X    icon->Flags= GADGHCOMP | GADGIMAGE | GRELRIGHT ;
X    icon->Activation = GADGIMMEDIATE | RELVERIFY | TOPBORDER;
X    icon->GadgetType = BOOLGADGET;
X    icon->GadgetID=ICONWINDOW;
X    image3->LeftEdge=0;
X    image3->TopEdge=0;
X    image3->Width=28;
X    image3->Height=10;
X    image3->Depth=2;
X    image3->ImageData=iconimage;
X
X    image3->PlanePick=3;
X    image3->PlaneOnOff=0;
X
X    nw.LeftEdge=x;
X    nw.TopEdge=y;
X    if(width <10*8+borderLEFT+borderRIGHT || height < 3*8+borderTOP+borderBOT) {
X	dmsg(9,"border stuff screwed up!");
X	dmsg(9,"width <10*8+LEFT+RIGHT (%ld<10*8+%ld+%ld) || height <3*8+TOP+BOT (%ld < 3*8+%ld+%ld.\n",width,borderLEFT,borderRIGHT,height,borderTOP,borderBOT);
X	goto fail;
X    }
X    nw.Width=width;
X    nw.Height=height;
X    nw.DetailPen= -1;
X    nw.BlockPen= -1;
X    nw.IDCMPFlags=0;
X    nw.Flags=HELPWINDOWFLAGS | ENVRefresh;
X    nw.CheckMark=0;
X    nw.Title=title;
X    nw.Screen=screen;
X    nw.BitMap=0;
X    nw.MinWidth=nw.Width;
X    nw.MinHeight=nw.Height;
X    nw.MaxWidth = -1; nw.MaxHeight = -1;
X    if(screen)
X	nw.Type=CUSTOMSCREEN;
X    else
X	nw.Type=WBENCHSCREEN;
X    nw.FirstGadget=vertbar;
X
X    win=OpenWindow(&nw);
X    if(win==0) {
X	dmsg(9,"Window would not open!\n");
X	goto fail;
X    }
X    AddGadget(win,icon,0);      /* Put the ICON gadget at the head of the class */
X    RefreshGList(icon,win,0,1); /* ...and make it appear */
X    myproc=(struct Process *)mytask;
X    tmpwindow=(struct Window *)myproc->pr_WindowPtr;
X    myproc->pr_WindowPtr=(APTR)win;
X    ScreenToFront(win->WScreen);
X    win->UserPort=mp;
X    ModifyIDCMP(win,HELPWINDOWIDCMPFLAGS);
X    windowcount++;
X    ow->window=win;
X    font=0;
X    if(myfont->ta_YSize) {
X#ifdef DEBUG1
X	dmsg(1,"OpenFont(myfont)\n");
X#endif
X	font=OpenFont(myfont);
X	if (font==0 || font->tf_YSize!=myfont->ta_YSize) {
X	    if(DiskfontBase==0) {
X#ifdef DEBUG1
X		dmsg(1,"OpenLibrary(\"diskfont.library\",0)\n");
X#endif
X		DiskfontBase=OpenLibrary("diskfont.library",0);
X	    }
X	    if(DiskfontBase) {
X#ifdef DEBUG1
X		dmsg(1,"OpenDiskFont\n");
X#endif
X		diskfont=OpenDiskFont(myfont);
X		if(diskfont) {
X		    if(font)CloseFont(font);
X		    font=diskfont;
X		}
X		CloseLibrary(DiskfontBase);
X		DiskfontBase=0;
X	    }
X	}
X    }
X    if(font) {
X	dmsg(1,"font.y=%ld, requested=%ld\n",font->tf_YSize,myfont->ta_YSize);
X	SetFont(win->RPort,font);
X	ow->doc->savefont=font;
X    }
X    SetDrMd(win->RPort,JAM1);
X    ow->savewide=borderLEFT+borderRIGHT+win->RPort->TxWidth * strlen(win->Title) + 76;
X    if(ow->savewide + 15 > win->WScreen->Width) ow->savewide=win->WScreen->Width - 30;
X    ow->savehigh=screenBARHEIGHT;
X    ow->saveleft=nw.LeftEdge+ENVXInc;
X    ow->savetop=nw.TopEdge+ENVYInc;
X    if(ow->saveleft+ow->savewide > win->WScreen->Width) ow->saveleft=0;
X    if(ow->savetop+ow->savehigh > win->WScreen->Height) ow->savetop=win->WScreen->BarHeight;
X
X    tmp=win->FirstGadget;
X
X    if(win->RPort->Font->tf_Flags & FPF_PROPORTIONAL) {
X	int i,j,k;
X	char *test="AbciOiO";
X	int lowc=win->RPort->Font->tf_LoChar;
X
X	dmsg(1,"***************\nProportional\n");
X	ow->doc->propwidth= (u_short *)win->RPort->Font->tf_CharSpace;
X	ow->doc->propwidth= ow->doc->propwidth-lowc;
X	dmsg(1,"Spaceing=%ld\n",win->RPort->TxSpacing);
X	i=TextLength(win->RPort,test,7);
X	j=0;
X	for(k=0;k<7;k++) {
X	    dmsg(1,"'%lc'=%ld.\n",test[k],ow->doc->propwidth[test[k]]);
X	    j+=ow->doc->propwidth[test[k]];
X	}
X	dmsg(1,"i=%ld, j=%ld.\n",i,j);
X    }
X
X    ow->scroll=vertbar;
X    ow->down=downarrow;
X    ow->up=uparrow;
X    ow->icon=icon;
X    myproc->pr_WindowPtr=(APTR)tmpwindow;
X
X    /* Set Minimum window limits to reasonable values */
X#ifdef DEBUG1
X    dmsg(1,"Window borders: LEFT=%ld, TOP=%ld, RIGHT=%ld, BOT=%ld, TxWidth=%ld, TxHeight=%ld.\n",
X	borderLEFT,borderTOP,borderRIGHT,borderBOT,win->RPort->TxWidth,win->RPort->TxHeight);
X#endif
X
X#ifdef DEBUG1
X    dmsg(1,"Setting limits to (%ld, %ld, %ld, %ld)==",
X	borderLEFT+borderRIGHT+win->RPort->TxWidth*20,
X	borderTOP+borderBOT+win->RPort->TxHeight*3,
X	0,
X	0
X    );
X#endif
X    test=WindowLimits(win,
X	borderLEFT+borderRIGHT+win->RPort->TxWidth*20,
X	borderTOP+borderBOT+win->RPort->TxHeight*3,
X	0,
X	0
X    );
X#ifdef DEBUG1
X    dmsg(1,"%ld.\n",test);
X#endif
X#ifdef DEBUG1
X    dmsg(1,"Window dimensions are %ld, %ld\n", win->Width, win->Height);
X#endif
X#ifdef DEBUG1
X    dmsg(1,"Window limits are %ld, %ld, %ld, %ld.\n",
X	win->MinWidth, win->MinHeight, win->MaxWidth, win->MaxHeight
X    );
X#endif
X    ow->saveminwidth=win->MinWidth;
X    ow->saveminheight=win->MinHeight;
X    ow->Width=win->Width;
X    ow->Height=win->Height;
X
X    makemenu(win);
X    return(win);
X
Xfail:
X    if(vertbar) {
X	if(vertbar->SpecialInfo) FreeMem(vertbar->SpecialInfo,sizeof(struct PropInfo));
X	if(vertbar->GadgetRender) FreeMem(vertbar->GadgetRender,sizeof(struct Image));
X	FreeMem(vertbar,sizeof(struct Gadget));
X    }
X    if(uparrow) {
X	if(uparrow->GadgetRender) FreeMem(uparrow->GadgetRender,sizeof(struct Image));
X	uparrow->GadgetRender=0;
X	FreeMem(uparrow,sizeof(struct Gadget));
X    }
X    if(downarrow) {
X	if(downarrow->GadgetRender) FreeMem(downarrow->GadgetRender,sizeof(struct Image));
X	downarrow->GadgetRender=0;
X	FreeMem(downarrow,sizeof(struct Gadget));
X    }
X    if(icon) {
X	if(icon->GadgetRender) FreeMem(icon->GadgetRender,sizeof(struct Image));
X	icon->GadgetRender=0;
X	FreeMem(icon,sizeof(struct Gadget));
X    }
X    if(windowcount==0 && screen ) {
X	CloseScreen(screen);
X	screen=0;
X    }
X    return 0;
X}
SHAR_EOF
echo "End of archive 3 (of 3)"
# if you want to concatenate archives, remove anything after this line
exit