[comp.sources.amiga] Unix Windows source code

doc@j.cc.purdue.edu (Craig Norborg) (05/24/87)

    Here is the source code to match the binaries posted to comp.sys.amiga
for the UW protocol window manager/term program..

#	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
#	console.c
#	intui.c
#	menus.c
#	serial.c
#	terminal.c
#	uw.c
#	windows.c
#	term.h
# This archive created: Sun May 24 01:03:00 1987
# By:	Craig Norborg (Purdue University Computing Center)
cat << \SHAR_EOF > makefile
# MakeFile for Unix Windows Amiga Client

INCLUDE = -iLC:include/ -iLC:include/lattice/
CC     = LC:lc $(INCLUDE)
LIB    = LC:
LIBS   = $(LIB)amiga.lib $(LIB)lc.lib 
# LIBS   = $(LIB)lc.lib $(LIB)amiga.lib
START  = $(LIB)Astartup.obj
# START  = $(LIB)Lstartup.obj
LINK   = LC:blink

H       = term.h

FILES   = $H terminal.c windows.c menus.c serial.c console.c intui.c uw.c

OBJS    = terminal.o windows.o menus.o serial.o console.o intui.o uw.o
LOBJS  = terminal.o+windows.o+menus.o+serial.o+console.o+intui.o+uw.o

uw : $(OBJS)
   $(LINK) $(START)+$(LOBJS) TO uw LIBRARY $(LIBS)

terminal.o : terminal.c $H
   $(CC) $(CFLAGS)  terminal.c

windows.o : windows.c
   $(CC) $(CFLAGS)  windows.c

menus.o : menus.c
   $(CC) $(CFLAGS)  menus.c

serial.o : serial.c
   $(CC) $(CFLAGS)  serial.c

console.o : console.c
   $(CC) $(CFLAGS)  console.c

intui.o : intui.c
   $(CC) $(CFLAGS)  intui.c

uw.o : $H uw.c
   $(CC) $(CFLAGS) uw.c
SHAR_EOF
cat << \SHAR_EOF > console.c
#include "exec/types.h"
#include "exec/ports.h"
#include "exec/devices.h"
#include "exec/io.h"
#include "exec/memory.h"
#include "devices/console.h"

/* These functions are taken directly from the console.device chapter
 * in the Amiga V1.1 ROM KERNEL manual.  See manual for documentation. */


/* Open a console device */
      int
OpenConsole(writerequest,readrequest,window)
      struct IOStdReq *writerequest;
      struct IOStdReq *readrequest;
      struct Window *window;
      {
            int error; 
            writerequest->io_Data = (APTR) window;
            writerequest->io_Length = sizeof(*window);
            error = OpenDevice("console.device", 0, writerequest, 0);
            readrequest->io_Device = writerequest->io_Device;
            readrequest->io_Unit   = writerequest->io_Unit;
                  /* clone required parts of the request */
            return(error);
      }

/* Output a single character to a specified console */ 

      int
ConPutChar(request,character)
      struct IOStdReq *request;
      char character;
      {
            request->io_Command = CMD_WRITE;
            request->io_Data = (APTR)&character;
            request->io_Length = 1;
            request->io_Flags = IOF_QUICK;
            DoIO(request);
            return(0);
      }
 
/* Output a NULL-terminated string of characters to a console */ 

      int
ConPutStr(request,string)
      struct IOStdReq *request;
      char *string;
      {
            request->io_Command = CMD_WRITE;
            request->io_Data = (APTR)string;
            request->io_Length = -1;
            DoIO(request);
            return(0);
      }
 
      /* queue up a read request to a console */

      int
QueueRead(request,whereto)
      struct IOStdReq *request;
      char *whereto;
      {
            request->io_Command = CMD_READ;
            request->io_Data = (APTR)whereto;
            request->io_Length = 1;
            SendIO(request);
            return(0);
      }

SHAR_EOF
cat << \SHAR_EOF > intui.c

#include "exec/types.h"
#include "exec/ports.h"
#include "exec/devices.h"
#include "exec/io.h"
#include "exec/memory.h"

#include "libraries/dos.h"
#include "graphics/text.h"
#include "libraries/diskfont.h"
#include "intuition/intuition.h"
 
/* Dynamic Intuition Text functions */

struct IntuiText *NewIText(text, left, top)
char *text;
int left, top;
{
   struct IntuiText *newtext = NULL;

   if (newtext = (struct IntuiText *)AllocMem(sizeof(*newtext),
                                              MEMF_PUBLIC | MEMF_CLEAR))
      {
      newtext->IText = (UBYTE *)text;
      newtext->FrontPen = 0;
      newtext->BackPen = 1;
      newtext->DrawMode = JAM2;
      newtext->LeftEdge = left;
      newtext->TopEdge = top;
      newtext->ITextFont = NULL;
      newtext->NextText = NULL;
      }
   return(newtext);
}

struct IntuiText *AddIText(IText, text)
struct IntuiText *IText;
char *text;
{
   struct IntuiText *newtext = NULL;

   if (IText) {
      if (newtext = (struct IntuiText *)AllocMem(sizeof(*newtext),
                                                 MEMF_PUBLIC | MEMF_CLEAR))
         {
         newtext->IText = (UBYTE *)text;
            newtext->FrontPen = IText->FrontPen;
         newtext->BackPen  = IText->BackPen;
         newtext->DrawMode = IText->DrawMode;
         newtext->LeftEdge = IText->LeftEdge;
         newtext->TopEdge  = IText->TopEdge + 11;
         newtext->ITextFont = IText->ITextFont;
         newtext->NextText = NULL;
         IText->NextText   = newtext;
         }
      }
   return(newtext);
}

DisposeIText(IText)
struct IntuiText *IText;
{
   struct IntuiText *current, *next;

   current = IText;
   for(next = current->NextText; current != NULL; next = next->NextText)
      {
      FreeMem(current,sizeof(*current));
      current = next;
      }
}


/* Dynamic Menu Constructor Functions */

#define InterMenuWidth 15

struct Menu *NewMenu(menuname, width, height)
char *menuname;
int width, height;
{
   struct Menu *menu = NULL;

   if(menu = (struct Menu *)AllocMem(sizeof(*menu),
                                     MEMF_PUBLIC | MEMF_CLEAR))
      {
      menu->NextMenu = NULL;
      menu->LeftEdge = 0;
      menu->TopEdge = 0;
      menu->Width = width;
      menu->Height = height;
      menu->Flags = MENUENABLED;
      menu->MenuName = menuname;
      menu->FirstItem = NULL;
      }
   return(menu);
}

struct Menu *AddMenu(menus, MenuName, width, height)
struct Menu *menus;
char *MenuName;
int width, height;
{
   struct Menu *newmenu;

   if (menus) {
      if (newmenu = NewMenu(MenuName, width, height)) {
         newmenu->LeftEdge = menus->LeftEdge + menus->Width + InterMenuWidth;
         menus->NextMenu = newmenu;
         }
      }
   return(newmenu);
}

struct MenuItem *NewMenuItem(name, width, height)
char *name;
int width, height;
{
   struct MenuItem *newitem = NULL;
   struct IntuiText *NewIText(), *newtext = NULL;

   if (newitem = (struct MenuItem *)AllocMem(sizeof(*newitem),
                                             MEMF_PUBLIC | MEMF_CLEAR))
      {
      if (newtext = NewIText(name,0,1)) {
         newitem->NextItem = NULL;
         newitem->ItemFill = (APTR) newtext;
         newitem->LeftEdge = 0;
         newitem->TopEdge = 0;
         newitem->Width = width;
         newitem->Height = height;
         newitem->Flags = ITEMTEXT | ITEMENABLED | HIGHCOMP;
         newitem->MutualExclude = 0;
         newitem->SelectFill = NULL;
         newitem->Command = 0;
         newitem->SubItem = NULL;
         newitem->NextSelect = 0;
         } else {
         DisposeItem(newitem);
         newitem = NULL;
         }
      }
   return(newitem);
}

struct MenuItem *AddNewMenuItem(menu, name, width, height)
struct Menu *menu;
char *name;
int width, height;
{
   struct MenuItem *newitem = NULL, *NewMenuItem();

   if (menu) {
      if (newitem = NewMenuItem(name, width, height)) {
         menu->FirstItem = newitem;
         }
      }
   return(newitem);
}

struct MenuItem *AddItem(items, name)
struct MenuItem *items;
char *name;
{
   struct MenuItem *newitem = NULL, *NewMenuItem();

   if (items) {
      if (newitem = NewMenuItem(name, items->Width, items->Height))
         {
         newitem->TopEdge = items->TopEdge + items->Height;
         newitem->LeftEdge = items->LeftEdge;
         items->NextItem = newitem;
         if (items->MutualExclude) {
            newitem->MutualExclude = (~((~items->MutualExclude) << 1));
            newitem->Flags |= CHECKIT;
            }
         }
      }
   return(newitem);
}

struct MenuItem *AddNewSubItem(item, name, width, height)
struct MenuItem *item;
char *name;
int width, height;
{
   struct MenuItem *newitem = NULL, *NewMenuItem();

   if (item) {
      if (newitem = NewMenuItem(name, width, height)) {
         item->SubItem = newitem;
         newitem->LeftEdge = item->Width;
         }
      }
   return(newitem);
}

DisposeItem(item)
struct MenuItem *item;
{
   DisposeIText((struct ItuiText *)item->ItemFill);
   FreeMem(item,sizeof(*item));
}

DisposeItems(items)
struct MenuItem *items;
{
   struct MenuItem *current, *next;

   current = items;
   for(next = current->NextItem; current != NULL; next = next->NextItem){
      DisposeItem(current);
      current = next;
   }
}

DisposeMenu(menu)
struct Menu *menu;
{
   DisposeItems(menu->FirstItem);
   FreeMem(menu,sizeof(*menu));
}

DisposeMenus(menus)
struct Menu *menus;
{
   struct Menu *current, *next;

   current = menus;
   for(next = current->NextMenu; current != NULL; next = next->NextMenu){
      DisposeMenu(current);
      current = next;
   }
}

/* modified autorequester */


USHORT   OKBoolV1[18] = {
   0,0,  35,0, 35,17,   0,17,
   0,0,  34,0, 34,17,   1,17, 1,0
   };

USHORT OKBoolV2[18] = {
   0,0,  31,0, 31,15,   0,15,
   0,0,  30,0, 30,15,   1,15, 1,0
   };

struct Border OKBoolBorder2 = {
   0, 0,
   0, 1, JAM1,
   9,
   OKBoolV2,
   NULL
   };

struct Border OKBoolBorder1 = {
   -2, -1,
   3, 1, JAM1,
   9,
   OKBoolV1,
   &OKBoolBorder2
   };

struct IntuiText OKText = {
   0, 1, JAM2,
   8, 4,
   NULL,
   "OK",
   NULL
   };

struct Gadget OKBoolGadget = {
   NULL,
   -46, -24, 32, 16,
   GADGHCOMP| GRELRIGHT | GRELBOTTOM,
   TOGGLESELECT | RELVERIFY | ENDGADGET,
   BOOLGADGET | REQGADGET,
   (APTR)&OKBoolBorder1,
   NULL,
   &OKText,
   0, NULL, 0, NULL
   };

USHORT CancelBoolV1[18] = {
   0,0,  67,0, 67,17,   0,17,
   0,0,  66,0, 66,17,   1,17, 1,0
   };

USHORT CancelBoolV2[18] = {
   0,0,  63,0, 63,15,   0,15,
   0,0,  62,0, 62,15,   1,15, 1,0
   };

struct Border CancelBoolBorder2 = {
   0, 0,
   0, 1, JAM1,
   9,
   CancelBoolV2,
   NULL
   };

struct Border CancelBoolBorder1 = {
   -2, -1,
   3, 1, JAM1,
   9,
   CancelBoolV1,
   &CancelBoolBorder2
   };

struct IntuiText CancelText = {
   0, 1, JAM2,
   7, 4,
   NULL,
   "Cancel",
   NULL
   };

struct Gadget CancelBoolGadget = {
   NULL,
   14, -24, 64, 16,
   GADGHCOMP| GRELBOTTOM,
   TOGGLESELECT | RELVERIFY | ENDGADGET,
   BOOLGADGET | REQGADGET,
   (APTR)&CancelBoolBorder1,
   NULL,
   &CancelText,
   0, NULL, 0, NULL
   };

USHORT ReqV1[18], ReqV2[18];

struct Border ReqBorder2 = {
   6, 3,
   0, 1, JAM1,
   9,
   ReqV2,
   NULL
   };

struct Border ReqBorder1 = {
   2, 1,
   0, 1, JAM1,
   9,
   ReqV1,
   &ReqBorder2
   };

struct Requester autoreq;

initrequester(width, height)
int width, height;
{
   ReqV1[0] = 0;
   ReqV1[1] = 0;
   ReqV1[2] = width-5;
   ReqV1[3] = 0;
   ReqV1[4] = width-5;
   ReqV1[5] = height-3;
   ReqV1[6] = 0;
   ReqV1[7] = height-3;
   ReqV1[8] = 0;
   ReqV1[9] = 0;
   ReqV1[10] = width-6;
   ReqV1[11] = 0;
   ReqV1[12] = width-6;
   ReqV1[13] = height-3;
   ReqV1[14] = 1;
   ReqV1[15] = height-3;
   ReqV1[16] = 1;
   ReqV1[17] = 0;
   ReqV2[0] = 0;
   ReqV2[1] = 0;
   ReqV2[2] = width-14;
   ReqV2[3] = 0;
   ReqV2[4] = width-14;
   ReqV2[5] = height-7;
   ReqV2[6] = 0;
   ReqV2[7] = height-7;
   ReqV2[8] = 0;
   ReqV2[9] = 0;
   ReqV2[10] = width-13;
   ReqV2[11] = 0;
   ReqV2[12] = width-13;
   ReqV2[13] = height-7;
   ReqV2[14] = 1;
   ReqV2[15] = height-7;
   ReqV2[16] = 1;
   ReqV2[17] = 0;
   InitRequester(&autoreq);
   autoreq.LeftEdge = (640 - width)/2;
   autoreq.TopEdge = (200 - height)/2;
   autoreq.Width = width;
   autoreq.Height = height;
   autoreq.RelLeft = 0;
   autoreq.RelTop = 0;
   autoreq.ReqBorder = &ReqBorder1;
   autoreq.Flags = NULL;
   autoreq.BackFill = 1;
}

autorequest(window, body, cancel, width, height)
struct Window *window;
struct IntuiText *body;
int cancel, width, height;
{
   struct IntuiMessage *IntuiMsg;
   USHORT idcmpflags;            /* holding place for window's flags */

   idcmpflags = window->IDCMPFlags;
   window->IDCMPFlags = GADGETUP;

   initrequester(width, height);
   autoreq.ReqText = body;
   autoreq.ReqGadget = &OKBoolGadget;
   OKBoolGadget.NextGadget = NULL;
   if (cancel) {
      OnGadget(&CancelBoolGadget, window, &autoreq);
      CancelBoolGadget.Flags = GADGHCOMP | GRELBOTTOM;
      OKBoolGadget.NextGadget = &CancelBoolGadget;
      }
   OKBoolGadget.Flags = GADGHCOMP | GRELRIGHT | GRELBOTTOM;
   OnGadget(&OKBoolGadget, window, &autoreq);

   Request(&autoreq, window);

   while ((IntuiMsg = (struct IntuiMessage *)
                      GetMsg(window->UserPort)) == 0)
      Wait(1 << window->UserPort->mp_SigBit);
   ReplyMsg(IntuiMsg);

   window->IDCMPFlags = idcmpflags;
   return((CancelBoolGadget.Flags & SELECTED) == 0);
}

length(s)
char *s;
{
   char *p = s;

   while(*p++);
   return(p-s);
}

Notify(window, message)
struct Window *window;
char *message;
{
   int c;
   struct IntuiText *MsgText;

   MsgText = NewIText(message, 14, 7);
   c = length(message) * 8 + 14;
   autorequest(window, MsgText, FALSE, c, 50);
}

Query(window, message)
struct Window *window;
char *message;
{
   int c;
   struct IntuiText *MsgText;

   MsgText = NewIText(message, 14, 7);
   c = length(message) * 8 + 14;
   return(autorequest(window, MsgText, TRUE, c, 50));
}


/*  Standard File Package */

USHORT   SaveBoolV1[18] = {
   0,0,  51,0, 51,17,   0,17,
   0,0,  50,0, 50,17,   1,17, 1,0
   };

USHORT SaveBoolV2[18] = {
   0,0,  47,0, 47,15,   0,15,
   0,0,  46,0, 46,15,   1,15, 1,0
   };

struct Border SaveBoolBorder2 = {
   0, 0,
   0, 1, JAM1,
   9,
   SaveBoolV2,
   NULL
   };

struct Border SaveBoolBorder1 = {
   -2, -1,
   3, 1, JAM1,
   9,
   SaveBoolV1,
   &SaveBoolBorder2
   };

struct IntuiText SaveText = {
   0, 1, JAM2,
   8, 4,
   NULL,
   "Save",
   NULL
   };

struct Gadget SaveBoolGadget = {
   &CancelBoolGadget,
   -62, -24, 48, 16,
   GADGHCOMP| GRELRIGHT | GRELBOTTOM,
   TOGGLESELECT | RELVERIFY | ENDGADGET,
   BOOLGADGET | REQGADGET,
   (APTR)&SaveBoolBorder1,
   NULL,
   &SaveText,
   0, NULL, 0, NULL
   };

USHORT   OpenBoolV1[18] = {
   0,0,  51,0, 51,17,   0,17,
   0,0,  50,0, 50,17,   1,17, 1,0
   };

USHORT OpenBoolV2[18] = {
   0,0,  47,0, 47,15,   0,15,
   0,0,  46,0, 46,15,   1,15, 1,0
   };

struct Border OpenBoolBorder2 = {
   0, 0,
   0, 1, JAM1,
   9,
   OpenBoolV2,
   NULL
   };

struct Border OpenBoolBorder1 = {
   -2, -1,
   3, 1, JAM1,
   9,
   OpenBoolV1,
   &OpenBoolBorder2
   };

struct IntuiText OpenText = {
   0, 1, JAM2,
   8, 4,
   NULL,
   "Open",
   NULL
   };

struct Gadget OpenBoolGadget = {
   &CancelBoolGadget,
   -62, -24, 48, 16,
   GADGHCOMP| GRELRIGHT | GRELBOTTOM,
   TOGGLESELECT | RELVERIFY | ENDGADGET,
   BOOLGADGET | REQGADGET,
   (APTR)&OpenBoolBorder1,
   NULL,
   &OpenText,
   0, NULL, 0, NULL
   };

char GFNBuffer[255];
char GFNUBuffer[255];

struct StringInfo GFNStrInfo =
   {
   (UBYTE *)GFNBuffer,
   (UBYTE *)GFNUBuffer,
   0, 255, 0,
   0, 0, 0, 0, 0,
   NULL, 0, NULL
   };

struct Gadget GFNStrGad =
   {
   NULL,
   14, 19, 270, 11,
   GADGHCOMP | SELECTED,
   RELVERIFY | ENDGADGET,
   STRGADGET | REQGADGET,
   NULL,       /* Border */
   NULL,
   NULL,       /* To point to Gadget text */
   0,
   (APTR)&GFNStrInfo,
   0, NULL
   };

GFN(window, openflag, message)
struct Window *window;
int openflag;
char *message;
{
   struct IntuiText *GFNText, *NewIText(), *AddIText();
   struct IntuiMessage *IntuiMsg;

   GFNText = NewIText( message, 14, 7);
   initrequester(300, 60);
   autoreq.ReqText = GFNText;

   autoreq.ReqGadget = &GFNStrGad;
   if (openflag) {
      GFNStrGad.NextGadget = &OpenBoolGadget;
      OnGadget(&OpenBoolGadget, window, &autoreq);
      OpenBoolGadget.Flags = GADGHCOMP | GRELBOTTOM | GRELRIGHT;
      } else {
      GFNStrGad.NextGadget = &SaveBoolGadget;
      OnGadget(&SaveBoolGadget, window, &autoreq);
      SaveBoolGadget.Flags = GADGHCOMP | GRELBOTTOM | GRELRIGHT;
      }
   OnGadget(&GFNStrGad, window, &autoreq);
   OnGadget(&CancelBoolGadget, window, &autoreq);
   CancelBoolGadget.Flags = GADGHCOMP | GRELBOTTOM;

   Request(&autoreq, window);
   while ((IntuiMsg = (struct IntuiMessage *)GetMsg(window->UserPort)) == 0)
      Wait(1 << window->UserPort->mp_SigBit);
   ReplyMsg(IntuiMsg);
   DisposeIText(GFNText);
   return((CancelBoolGadget.Flags & SELECTED) == 0);
}

struct FileHandle *OpenFile(window, prompt)
struct Window *window;
char *prompt;
{
   struct FileLock *lock, *Lock();
   struct FileHandle *file, *Open();

   if (GFN(window, TRUE, prompt)) {
      UnLock(lock = Lock(GFNBuffer, ACCESS_READ));
      if (lock != 0) {
         file = Open(GFNBuffer, MODE_OLDFILE);
         if (file != 0) {
            return(file);
            }
         Notify(window, "Can't open file.");
         return(NULL);
         }
      Notify(window, "File not found.");
   }
   return(NULL);
}

struct FileHandle *SaveFile(window, prompt)
struct Window *window;
char *prompt;
{
   struct FileLock *lock, *Lock();
   struct FileHandle *file, *Open();

   if(GFN(window, FALSE, prompt)) {
      UnLock(lock = Lock(GFNBuffer, ACCESS_WRITE));
      if (lock == 0) {
         file = Open(GFNBuffer, MODE_NEWFILE);
         if (file != 0) {
            return(file);
            }
         Notify(window,"Can't open file.");
         return(NULL);
         }
      if (Query(window,"Overwrite file?")) {
         file = Open(GFNBuffer, MODE_NEWFILE);
         if (file != 0) {
            return(file);
            }
         Notify(window,"Can't open file.", 14, 7);
         return(NULL);
         }
      }
   return(NULL);
}

SHAR_EOF
cat << \SHAR_EOF > menus.c
/* menu function calls and handlers */

#include "term.h"
#include "devices/serial.h"

/* GLOBALS ****************************************************** */
extern long IntuitionBase;
extern long GfxBase;

extern struct IOExtSer *SerReadReq, *SerWriteReq;
extern char serin;
extern int FullDuplex;

struct Menu *MenuHead;

InitMenus()
{
   struct Menu *CurrentMenu, *NewMenu(), *AddMenu();
   struct MenuItem *CurrentItem, *SubItem,
                   *AddNewMenuItem(), *AddItem(), *AddNewSubItem();

   CurrentMenu    = NewMenu("Project", 60, 10);
   MenuHead       = CurrentMenu;
      CurrentItem = AddNewMenuItem(CurrentMenu, "About...", 100,11);
         SubItem  = AddNewSubItem(CurrentItem, "UWTerm 1.00", 92,11);
         SubItem  = AddItem(SubItem,"HackerWare");
      CurrentItem = AddItem(CurrentItem, "New");
      CurrentItem = AddItem(CurrentItem, "Window");
         SubItem  = AddNewSubItem(CurrentItem, "to Back",68,11);
         SubItem  = AddItem(SubItem,"to Front");
      CurrentItem = AddItem(CurrentItem, "Quit");
   CurrentMenu    = AddMenu(CurrentMenu, "Settings",68,10);
      CurrentItem = AddNewMenuItem(CurrentMenu,"Baud",52,11);
         SubItem  = AddNewSubItem(CurrentItem, "   300   ",76,11);
         if (SubItem) {
            SubItem->MutualExclude = ~1;
            SubItem->Flags |= CHECKIT;
            }
         SubItem  = AddItem(SubItem,"  1200   ");
         SubItem  = AddItem(SubItem,"  2400   ");
         SubItem  = AddItem(SubItem,"  4800   ");
         SubItem  = AddItem(SubItem,"  9600   ");
         if (SubItem) SubItem->Flags |= CHECKED;
      CurrentItem = AddItem(CurrentItem,"Length");
         SubItem  = AddNewSubItem(CurrentItem,"   7 bits   ",100,11);
         if (SubItem) {
            SubItem->MutualExclude = ~1;
            SubItem->Flags |= CHECKIT;
            SubItem->Flags |= CHECKED;
            }
         SubItem  = AddItem(SubItem,"   8 bits   ");
      CurrentItem = AddItem(CurrentItem,"Duplex");
         SubItem  = AddNewSubItem(CurrentItem,"   Full   ",100,11);
         if (SubItem) {
            SubItem->MutualExclude = ~1;
            SubItem->Flags |= CHECKIT | CHECKED;
            }
         SubItem  = AddItem(SubItem,"   Half   ");

   if (SubItem) return(TRUE);
     else return(FALSE);
}

MenuSwitch(code)
USHORT code;
{
   USHORT menunum;
   struct MenuItem *item;
   int error;

   error = TRUE;
   while(code != MENUNULL ) {
      item = (struct MenuItem *)ItemAddress(MenuHead, code);
      menunum = MENUNUM( code );
      switch( menunum ) {
         case 0:
            error &= ProjectMenu(code);
            break;
         case 1:
            error &= SettingsMenu(code);
            break;
      } /* end of switch ( menunum ) */
      code = item->NextSelect;
   } /* end of while (code != MENUNULL) */
   return(error);
} /* end of MenuSwitch */


ProjectMenu(code)
USHORT code;
{
   USHORT itemnum;
   itemnum = ITEMNUM( code );
   switch( itemnum ) {
      case 0:  /* About */
         return(AboutMenu(code));
         break;
      case 1:  /* New */
	 MkNewWin();
	 return(TRUE);
	 break;
      case 2:  /* Window */
         return(ArrangeMenu(code));
         break;
      case 3: /* Quit */
         return( FALSE );
         break;
   } /* end of switch ( itemnum ) */
   return( TRUE );
} /* end of ProjectMenu */

AboutMenu(code)
USHORT code;
{
   struct IntuiText *InfoText, *NewIText(), *AddIText();
   USHORT subitem;
   subitem = SUBNUM( code );
   switch( subitem ) {
      case 0:
         InfoText = NewIText( "Unix Windows pcl1 !Beta!",12,5);
         AddIText(
         AddIText(
         AddIText(
         AddIText(InfoText,   "       Copyright ) 1987"),
                              "      by Michael McInerny"),
                              "       140 Spruce Ave"),
                              "      Rochester, NY  14611");
         autorequest(uw[uw_write].win, InfoText, FALSE, 276, 70);
         DisposeIText(InfoText);
         break;
      case 1:
         InfoText = NewIText( " Hackerware - Software for the People",12,5);
         AddIText(
         AddIText(
         AddIText(
         AddIText(
         AddIText(
         AddIText(InfoText,   " Feel free to use this software and"),
                              "  source--just don't sell it. "),
                              "Please distribute source with binary."),
                              "If you like this program, please send"),
                              "whatever you think it's worth to the"),
                              "     author.  Thank-you!");
         autorequest(uw[uw_write].win, InfoText, FALSE, 330, 108);
         DisposeIText(InfoText);
         break;
   } /* end of switch ( subitem ) */
   return( TRUE );
} /* end of AboutMenu */

ArrangeMenu(code)
USHORT code;
{
   USHORT subitem;
   subitem = SUBNUM( code );
   switch( subitem ) {
      case 0:
         WindowToBack( uw[uw_read].win );
         break;
      case 1:
         WindowToFront( uw[uw_read].win );
         break;
   } /* end of switch ( subitem ) */
   return( TRUE );
} /* end of ArrangeMenu */


SettingsMenu(code)
USHORT code;
{
   USHORT itemnum;
   itemnum = ITEMNUM( code );
   AbortIO(SerReadReq);
   switch ( itemnum ) {
      case 0:
         BaudMenu(code);
         break;
      case 1:
         LengthMenu(code);
         break;
      case 2:
         DuplexMenu(code);
         break;
   } /* end of switch ( itemnum ) */
   SerReadReq->IOSer.io_Command = SDCMD_SETPARAMS;
   DoIO(SerReadReq);
   QueueSerRead(SerReadReq, &serin);
   return( TRUE );
} /* end of SettingsMenu */

BaudMenu(code)
USHORT code;
{
   USHORT subitem;
   subitem = SUBNUM( code );
   switch( subitem ) {
      case 0:
         SerReadReq->io_Baud = 300;
         break;
      case 1:
         SerReadReq->io_Baud = 1200;
         break;
      case 2:
         SerReadReq->io_Baud = 2400;
         break;
      case 3:
         SerReadReq->io_Baud = 4800;
         break;
      case 4:
         SerReadReq->io_Baud = 9600;
         break;
   } /* end of switch ( subitem ) */
} /* end of BaudMenu */

LengthMenu(code)
USHORT code;
{
   USHORT subitem;
   subitem = SUBNUM( code );
   switch( subitem ) {
      case 0:
         SerReadReq->io_ReadLen = 0x07;
         SerReadReq->io_WriteLen = 0x07;
         break;
      case 1:
         SerReadReq->io_ReadLen = 0x08;
         SerReadReq->io_WriteLen = 0x08;
         break;
   } /* end of switch ( subitem ) */
} /* end of LengthMenu */

DuplexMenu(code)
USHORT code;
{
   USHORT subitem;
   subitem = SUBNUM( code );
   switch( subitem ) {
      case 0:
         FullDuplex = TRUE;
         break;
      case 1:
         FullDuplex = FALSE;
         break;
   } /* end of switch ( subitem ) */
} /* end of DuplexMenu */

SHAR_EOF
cat << \SHAR_EOF > serial.c
#include "exec/types.h"
#include "exec/ports.h"
#include "exec/devices.h"
#include "exec/io.h"
#include "exec/memory.h"
#include "devices/serial.h"

/* Open a serial device */
      int
OpenSerial(readrequest,writerequest)
      struct IOExtSer *readrequest;
      struct IOExtSer *writerequest;
      {
            int error;
            readrequest->io_SerFlags = NULL;
            error = OpenDevice(SERIALNAME, NULL, readrequest, NULL);
            writerequest->IOSer.io_Device = readrequest->IOSer.io_Device;
            writerequest->IOSer.io_Unit = readrequest->IOSer.io_Unit;
            writerequest->io_CtlChar = readrequest->io_CtlChar;
            writerequest->io_ReadLen = readrequest->io_ReadLen;
            writerequest->io_BrkTime = readrequest->io_BrkTime;
            writerequest->io_Baud = readrequest->io_Baud;
            writerequest->io_WriteLen = readrequest->io_WriteLen;
            writerequest->io_StopBits = readrequest->io_StopBits;
            writerequest->io_RBufLen = readrequest->io_RBufLen;
            writerequest->io_SerFlags = readrequest->io_SerFlags;
            writerequest->io_TermArray.TermArray0
            = readrequest->io_TermArray.TermArray0;
            writerequest->io_TermArray.TermArray1
            = readrequest->io_TermArray.TermArray1;
            /* clone required parts of the request */
            return(error);
      }

      int
SerPutChar(request,character)
      struct IOExtSer *request;
      char character;
      {
            request->IOSer.io_Command = CMD_WRITE;
            request->IOSer.io_Data = (APTR)&character;
            request->IOSer.io_Length = 1;
            DoIO(request);
            return(0);
      }

      int
QueueSerRead(request, whereto)
      struct IOExtSer *request;
      char *whereto;
      {
            request->IOSer.io_Command = CMD_READ;
            request->IOSer.io_Data = (APTR)whereto;
/*            request->IOSer.io_Flags = IOF_QUICK; */
            request->IOSer.io_Length = 1;
            BeginIO(request);
            return(0);
      }

      int
QuerySer(request)
	struct IOExtSer *request;
	{
		request->IOSer.io_Command = SDCMD_QUERY;
		BeginIO(request);
		WaitIO(request);
/*		DoIO(request); */
		return((int)(request->IOSer.io_Actual));
	} /* end of QuerySer */

   int
SetParams(io,rbuf_len,rlen,wlen,brk,baud,sf,ta0,ta1)
   struct IOExtSer *io;
   unsigned long rbuf_len;
   unsigned char rlen;
   unsigned char wlen;
   unsigned long brk;
   unsigned long baud;
   unsigned char sf;
   unsigned long ta0;
   unsigned long ta1;
   {
      io->io_ReadLen = rlen;
      io->io_WriteLen = wlen;
      io->io_Baud = baud;
      io->io_BrkTime = brk;
      io->io_StopBits = 0x01;
      io->io_RBufLen = rbuf_len;
      io->io_SerFlags = sf;
      io->io_TermArray.TermArray0 = ta0;
      io->io_TermArray.TermArray1 = ta1;
      io->IOSer.io_Command = SDCMD_SETPARAMS;
   
      return(DoIO(io));
}
SHAR_EOF
cat << \SHAR_EOF > terminal.c

/*  Unix Windows Client for the Amiga (ANSI Terminal Emulation only)

    ) 1987 by  Michael J. McInerny   12-May-87 version 1.00

*/

#define INTUITION_MESSAGE(x) (1<<uw[x].winsig)
#define TYPED_CHARACTER(x) (1<<uw[x].consig)
#define INPUT_CHARACTER (1<<serReadBit)

#define CloseConsole(x) CloseDevice(x)

#include "term.h"
#include "devices/serial.h"

/* GLOBALS ****************************************************** */
extern long IntuitionBase;
extern long GfxBase;

extern UWwrite();

struct uw_struct uw[8];
int uw_read, uw_write, uw_count = 0;

extern struct Window *NewTermWin();
extern struct Menu *MenuHead;

int waitmask;				/* what are we waiting for? */
struct MsgPort *serReadPort = NULL;
struct MsgPort *serWritePort = NULL;
struct IOExtSer *SerReadReq = NULL;
struct IOExtSer *SerWriteReq = NULL;

char letter[8];            /* one letter at a time from console */
char serin;             /* one letter at a time from serial  */
char serbuf[4096];	/* as much as we can get! */
int sercount;			 /* how many to get */
int FullDuplex = TRUE;  /* flag for local echo  */

AllocTerm(slot)
int slot;
{
   char *s = "xxuw.con";

   uw_count += 1;
   uw[slot].free = FALSE;
   uw[slot].win = NewTermWin();
   SetMenuStrip(uw[slot].win, MenuHead);
   *s = (char)slot + 'a';
   *(s+1) = 'w';
   uw[slot].ConWritePort = CreatePort(s,0);
	   if(uw[slot].ConWritePort == 0) Cleanup();
   uw[slot].ConWriteReq = CreateStdIO(uw[slot].ConWritePort);
	   if(uw[slot].ConWriteReq == 0) Cleanup();
   *(s+1) = 'r';
   uw[slot].ConReadPort = CreatePort(s,0);
	   if(uw[slot].ConReadPort == 0) Cleanup();
   uw[slot].ConReadReq =  CreateStdIO(uw[slot].ConReadPort);
	   if(uw[slot].ConReadReq == 0) Cleanup();
   if((OpenConsole(uw[slot].ConWriteReq,
			uw[slot].ConReadReq,
			uw[slot].win)) != 0)
      Cleanup();
   uw[slot].consig = uw[slot].ConReadReq->io_Message.mn_ReplyPort->mp_SigBit;
   uw[slot].winsig = uw[slot].win->UserPort->mp_SigBit;
   waitmask |= INTUITION_MESSAGE(slot) | TYPED_CHARACTER(slot) ;
   QueueRead(uw[slot].ConReadReq, &letter[slot]);
} /* end of AllocTerm */

ZeroTerm(slot)
int slot;
{
	uw[slot].free = TRUE;
	uw[slot].ConReadPort = NULL;
	uw[slot].ConWritePort = NULL;
	uw[slot].ConReadReq = NULL;
	uw[slot].ConWriteReq = NULL;
	uw[slot].win = NULL;
	uw[slot].winsig = 0;
	uw[slot].consig = 0;
} /* end of ZeroTerm */

DeallocTerm(slot)
int slot;
{
   waitmask &= ~(INTUITION_MESSAGE(slot) | TYPED_CHARACTER(slot)) ;
   if (uw[slot].free == FALSE) {
	AbortIO(uw[slot].ConReadReq);  /* cancel the last queued read */
	uw_count -= 1;
	if (uw[slot].ConWriteReq) CloseConsole(uw[slot].ConWriteReq);
	if (uw[slot].ConReadReq) DeleteStdIO(uw[slot].ConReadReq);
	if (uw[slot].ConReadPort) DeletePort(uw[slot].ConReadPort);
	if (uw[slot].ConWriteReq) DeleteStdIO(uw[slot].ConWriteReq);
	if (uw[slot].ConWritePort) DeletePort(uw[slot].ConWritePort);
	if (uw[slot].win) {
	   ClearMenuStrip(uw[slot].win);
	   CloseWindow(uw[slot].win);
	}
	ZeroTerm(slot);
   } /* end if uw.free */
} /* end of DeallocTerm */

InitSerReqs()
{
   serReadPort = CreatePort("uw.ser.read",0);
   if (serReadPort == NULL) Cleanup();
   SerReadReq = (struct IOExtSer *)CreateExtIO(serReadPort,
                                               sizeof(struct IOExtSer));
   if (SerReadReq == NULL) Cleanup();
   serWritePort = CreatePort("uw.ser.write",0);
   if (serWritePort == NULL) Cleanup();
   SerWriteReq = (struct IOExtSer *)CreateExtIO(serWritePort,
                                               sizeof(struct IOExtSer));
   if (SerWriteReq == NULL) Cleanup();
   if ((OpenSerial(SerReadReq, SerWriteReq)) != 0) Cleanup();
   if ((SetParams( SerReadReq, 4096, 0x07, 0x07, 750000,
                           9600, 0x00, 
			   0x51040303, 0x03030303)) != 0)
      Cleanup();
}

main()
{
   USHORT class, code, qualifier;
   int problem, i, serReadBit;
   struct IntuiMessage *message; /* the message the IDCMP sends us */

   IntuitionBase = 0L;
   GfxBase = 0L;
   MenuHead = NULL;

   for(i = 0; i < 8; ++i) ZeroTerm(i);

   InitLibs();
   InitSerReqs();
   serReadBit = SerReadReq->IOSer.io_Message.mn_ReplyPort->mp_SigBit;
   waitmask = INPUT_CHARACTER;

   if (!InitMenus()) Cleanup();

   AllocTerm(1);
   uw_read = 1;
   uw_write = 1;

   sercount = 1;
   ReadSer(serbuf, sercount);

/*   UWExit(); */

   problem = TRUE;
   do {
	Wait(waitmask);
	if(CheckIO(SerReadReq))
	{
		WaitIO(SerReadReq);
		UWwrite(serbuf, sercount);
		sercount = QuerySer(SerReadReq);
		if (sercount < 1) sercount = 1;
		ReadSer(serbuf, sercount);
	} /* end if(CheckIO(SerRead)) */
      for (i = 0; i < 8; ++i) {
	if (!uw[i].free) {
		while((!uw[i].free) &&
			((message = (struct IntuiMessage *)
				GetMsg(uw[i].win->UserPort) ) != NULL)) {
				class     = message->Class;
				code      = message->Code;
				qualifier = message->Qualifier;
				ReplyMsg(message);
				problem &= HandleEvent(i,class,code,qualifier);
/*				if(problem == FALSE) break; */
			} /* end while(mess... */

		if((!uw[i].free) && CheckIO(uw[i].ConReadReq))
		{
			WaitIO(uw[i].ConReadReq);
			if (uw_read != i) SelInput(i);
	/* is this is current input window?  if not, send note off ... */
			UWWriteChar(letter[i]);
/*			SerPutChar(SerWriteReq, letter[i]);	*/
			if (!FullDuplex)
				ConPutChar(uw[uw_write].ConWriteReq, letter[i]);
			QueueRead(uw[i].ConReadReq, &letter[i]);
		} /* end if(CheckIO(ConRead)) */
	} /* end if(!uw[i].free) */
      } /* end for i */
   } while (problem); /* keep going as long as HandleEvent returns nonzero */

   AbortIO(SerReadReq);
   Cleanup();
}

Cleanup()
{
   int i;

   for (i = 0; i < 8; ++i)
	if (!uw[i].free) DeallocTerm(i);
   if (SerReadReq) CloseDevice(SerReadReq);
   if (SerWriteReq) DeleteExtIO(SerWriteReq,sizeof(struct IOExtSer));
   if (serWritePort) DeletePort(serWritePort);
   if (SerReadReq) DeleteExtIO(SerReadReq,sizeof(struct IOExtSer));
   if (serReadPort) DeletePort(serReadPort);
   if (MenuHead) DisposeMenus(MenuHead);
   if (IntuitionBase) CloseLibrary(IntuitionBase);
   if (GfxBase) CloseLibrary(GfxBase);
   exit(0);
} /* end of Cleanup */

HandleEvent(term,class,code,qualifier)
int term;
USHORT class;
USHORT code;
USHORT qualifier;
{
      switch( class ) {
	 case CLOSEWINDOW:
	    return(CloseWin(term));
	    break;
         case MENUPICK:
            return(MenuSwitch(code));
            break;
      } /* end of switch( class ) */
      return(TRUE);
} /* end of HandleEvent */

/*      R e a d S e r
 *
 *      Read characters from the serial.device
 *
 */

ReadSer(data,length)
char *data;
int length;
{
  SerReadReq->IOSer.io_Command = CMD_READ;
  SerReadReq->IOSer.io_Length = length;
  SerReadReq->IOSer.io_Data = (APTR)(data);

   BeginIO(SerReadReq);
}

/*      W r i t e S e r
 *
 *      Write characters to the serial.device
 *
 */

WriteSer(data,length)
char *data;
int length;
{
/*  int i; */

  SerWriteReq->IOSer.io_Command = CMD_WRITE;
  SerWriteReq->IOSer.io_Length = length;
/*  SerWriteReq->IOSer.io_Length = 1; 
  for(i = 0; i < length; ++i) {
	SerWriteReq->IOSer.io_Data = (APTR)(data + i);
	DoIO(SerWriteReq);
  }
*/
  SerWriteReq->IOSer.io_Data = (APTR)(data);

  if(DoIO(SerWriteReq) != 0)
  {
      Notify(uw[uw_write].win, "Serial write error.");
  }
}

extern int uwflag;
sputc(c)
char c;
{
/*	printf(">0%o ",c); */
	if (uwflag) Delay(1);	/* Why is this necessary????? */
	SerPutChar(SerWriteReq, c);
}

/*      W r i t e C o n
 *
 *      Write characters to the console.device
 *
 */

WriteCon(data,length)
char *data;
int length;
{
  uw[uw_write].ConWriteReq->io_Command = CMD_WRITE;
  uw[uw_write].ConWriteReq->io_Length = length;
  uw[uw_write].ConWriteReq->io_Data = (APTR)(data);

if(!uw[uw_write].free)
  if(DoIO(uw[uw_write].ConWriteReq) != 0)
  {
      Notify(uw[uw_write].win, "Console write error.");
  }
}

SHAR_EOF
cat << \SHAR_EOF > uw.c
/* uw protocol interpretation */
#include "term.h"

/*
 * Protocol 0:
 *
 * The connection between the Macintosh and the host is simply a serial
 * line.  Flow control may be enabled, but no special commands are
 * recognized.  Only one active window is supported.  This "protocol"
 * does not require the UW server; hence, there is no need to support it.
 */
#define XON 		021
#define XOFF 		023
#define META 		0200	/* Meta Bit */

/*
 * Protocol 1: (original UW protocol)
 *
 * Two types of information are exchanged through the 7-bit serial line:
 * ordinary data and command bytes.  Command bytes are preceeded by
 * an IAC byte.  IAC bytes and literal XON/XOFF characters (those which
 * are not used for flow control) are sent by a P1_FN_CTLCH command.
 * Characters with the eighth bit set (the "meta" bit) are prefixed with
 * a P1_FN_META function.
 *
 * The next most-significant bit in the byte specifies the sender and
 * recipient of the command.  If this bit is clear (0), the command byte
 * was sent from the host computer to the Macintosh; if it is set (1)
 * the command byte was sent from the Macintosh to the host computer.
 * This prevents confusion in the event that the host computer
 * (incorrectly) echos a command back to the Macintosh.
 *
 * The remaining six bits are partitioned into two fields.  The low-order
 * three bits specify a window number from 1-7 (window 0 is reserved for
 * other uses) or another type of command-dependent parameter.  The next
 * three bits specify the operation to be performed by the recipient of
 * the command byte.
 *
 * Note that the choice of command bytes prevents the ASCII XON (021) and
 * XOFF (023) characters from being sent as commands.  P1_FN_ISELW commands
 * are only sent by the Macintosh (and thus are tagged with the P1_DIR_MTOH
 * bit).  Since XON and XOFF data characters are handled via P1_FN_CTLCH,
 * this allows them to be used for flow control purposes.
 */
#define	P1_IAC		0001		/* interpret as command */
#define	P1_DIR		0100		/* command direction: */
#define	P1_DIR_HTOM	0000		/*	from host to Mac */
#define	P1_DIR_MTOH	0100		/*	from Mac to host */
#define	P1_FN		0070		/* function code: */
#define	P1_FN_NEWW	0000		/*	new window */
#define	P1_FN_KILLW	0010		/*	kill (delete) window */
#define	P1_FN_ISELW	0020		/*	select window for input */
#define	P1_FN_OSELW	0030		/*	select window for output */
#define	P1_FN_META	0050		/*	add meta to next data char */
#define	P1_FN_CTLCH	0060		/*	low 3 bits specify char */
#define	P1_FN_MAINT	0070		/*	maintenance functions */
#define	P1_WINDOW	0007		/* window number mask */
#define	P1_CC		0007		/* control character specifier: */
#define	P1_CC_IAC	1		/*	IAC */
#define	P1_CC_XON	2		/*	XON */
#define	P1_CC_XOFF	3		/*	XOFF */
#define	P1_MF		0007		/* maintenance functions: */
#define	P1_MF_ENTRY	0		/*	beginning execution */
#define	P1_MF_ASKPCL	2		/*	request protocol negotiation */
#define	P1_MF_CANPCL	3		/*	suggest protocol */
#define	P1_MF_SETPCL	4		/*	set current protocol */
#define	P1_MF_EXIT	7		/*	execution terminating */
#define	P1_NWINDOW	7		/* maximum number of windows */


int 	uwflag = FALSE,
	IACflag = FALSE,
	Metaflag = FALSE;
char processed[4096];
int j = 0;			/* an index into to processed buffer */

UWwrite(buf,length)
char buf[];
int length;
{
	char c;
	int i;

	for(i = 0; i < length ; ++i) {
		c = buf[i];
		if (!IACflag) {
			if (c == P1_IAC) {
				IACflag = TRUE;
			} else if (!Metaflag) {
				processed[j++] = c;
			} else {
				processed[j++] = c | META;
				Metaflag = FALSE;
			}
		} else if ((c & P1_DIR) == P1_DIR_HTOM) {
/*			printf(" P1_IAC & 0%o ", c); */
			switch(c & P1_FN) {
			case P1_FN_NEWW:  NewWin(c & P1_WINDOW);
				break;
			case P1_FN_KILLW:  KillWin(c & P1_WINDOW);
				break;
			case P1_FN_OSELW:  SelOutput(c & P1_WINDOW);
				break;
			case P1_FN_META:  Metaflag = TRUE;
				break;
			case P1_FN_CTLCH:  CtlCh(c);
				break;
			case P1_FN_MAINT:  Maint(c);
				break;
			} /* end switch */
			IACflag = FALSE;
		} /* end if P1_DIR_HTOM */
	} /* end for */
	Pflush();
} /* end uw_write */

Pflush()
{
	if (j > 0) WriteCon(processed, j);
	j = 0;
}

NewWin(w)
int w;
{
	if (uwflag) {
		if (uw[w].free) {
/*			printf("NEWW %d\n", w); */
			AllocTerm(w);
		}
	} else {
		processed[j++] = P1_IAC;
		processed[j++] = P1_DIR_HTOM | P1_FN_NEWW | w;
	}
} /* end of NewWin */

KillWin(w)
int w;
{
	if (uwflag) {
/*		printf("KILLW %d\n", w); */
		if (uw[w].free == FALSE) CloseWinNoMsg(w);
	} else {
		processed[j++] = P1_IAC;
		processed[j++] = P1_DIR_HTOM | P1_FN_KILLW | w;
	}
} /* end of KillWin */

SelInput(w)
int w;
{
/*	printf("C:ISELW %d\n", w); */
	uw_read = w;
	sputc(P1_IAC);
	sputc(P1_DIR_MTOH | P1_FN_ISELW | w);
} /* end of SelInput */

SelOutput(w)
int w;
{
	if (uwflag) {
/*		printf("OSELW %d\n",w); */
		Pflush();
		if (uw[w].free == FALSE) uw_write = w;
	} else {
		processed[j++] = P1_IAC;
		processed[j++] = P1_DIR_HTOM | P1_FN_OSELW | w;
	}
} /* end of SelOutput */

CtlCh(c)
char c;
{
	char d;

if (uwflag) {
	d = 0;
	switch(c & P1_CC) {
	case P1_CC_IAC: d = P1_IAC;
		break;
	case P1_CC_XON: d = XON;
		break;
	case P1_CC_XOFF: d = XOFF;	
		break;
	}
	if (d != 0)
		if (Metaflag) {
			processed[j++] = d | META;
			Metaflag = FALSE;
		} else processed[j++] = d;
} else {
	processed[j++] = P1_IAC;
	processed[j++] = c;
}
} /* end of CtlCh */

Maint(c)
char c;
{
	switch (c & P1_MF) {
	case P1_MF_ENTRY:  InitUW();
		break;
	case P1_MF_EXIT: ExitUW();
		break;
	} 
} /* end of Maint */

InitUW()
{
	int i;

/*	printf("MF_ENTRY\n"); */
	uwflag = TRUE;
	for (i = 1; i < 8; ++i) if (uw[i].free == FALSE) DeallocTerm(i);
	uw_read = -1;	/* No current input */
/*	MkNewWin(); */
}

ExitUW()
{
	int i;

/*	printf("MF_EXIT\n"); */
	for(i = 0; i < 8; ++i)
		if (uw[i].free == FALSE) DeallocTerm(i);
	AllocTerm(1);
	uw_read = 1;
	uw_write = 1;
	uwflag = FALSE;
}

MkNewWin()
{
	int i;

if(uwflag){
	i = 1;
	while ((i < 8) && (uw[i].free == FALSE)) ++i;

	if (i < 8) {
/*		printf("C:NEWW %d\n",i); */
		AllocTerm(i);
		sputc(P1_IAC);
		sputc(P1_DIR_MTOH | P1_FN_NEWW | i);
	}
}
} /* end of MkNewWin */

CloseWinNoMsg(i)
int i;
{
	if (uw[i].free == FALSE) DeallocTerm(i);
	if (uw_count == 0) {
/*		printf("C:Reset\n"); */
		UWExit();
		InitTerm();
	}
} /* end of CloseWin */

CloseWin(i)
int i;
{
	if (uw[i].free == FALSE) {
/*		printf("C:KILLW %d\n",i); */
		DeallocTerm(i);
		if (uwflag) {
			sputc(P1_IAC);
			sputc(P1_DIR_MTOH | P1_FN_KILLW | i);
		}
	}
	if (uw_count == 0) {
		if(uwflag) {
			UWExit();
			InitTerm();
			return(TRUE);
		} else 	return(FALSE);
	} else return(TRUE);
} /* end of CloseWin */

UWWriteChar(c)
char c;
{
	if(uwflag) {
		switch (c) {
		case XON:  sputc(P1_IAC);
			sputc(P1_DIR_MTOH | P1_FN_CTLCH | P1_CC_XON);
			break;
		case XOFF: sputc(P1_IAC);
			sputc(P1_DIR_MTOH | P1_FN_CTLCH | P1_CC_XOFF);
			break;
		case P1_IAC: sputc(P1_IAC);
			sputc(P1_DIR_MTOH | P1_FN_CTLCH | P1_CC_IAC);
			break;
		default:
			sputc(c);
			break;
		} /* end switch */
	} else {
		sputc(c);
	}
} /* end of UWWriteChar */

UWExit()
{
/*	printf("C:MF_EXIT\n"); */
	sputc(P1_IAC);
	sputc(P1_DIR_MTOH | P1_FN_MAINT | P1_MF_EXIT);
} /* end of ExitUW */

InitTerm()
{
	uwflag = FALSE;
	Metaflag = FALSE;
	IACflag = FALSE;
	uw_read = 1;
	uw_write = uw_read;
	AllocTerm(uw_read);
}
SHAR_EOF
cat << \SHAR_EOF > windows.c
/* window init functions and data */

#include "term.h"

/* GLOBALS ****************************************************** */
long IntuitionBase=0;
long GfxBase=0;

struct NewWindow nw = {
   0, 0,             /* start position                  */
   639, 199,         /* width, height                   */
   -1, -1,           /* detail pen, block pen           */
   MENUPICK | CLOSEWINDOW | GADGETUP,
                     /* IDCMP flags                     */
   ACTIVATE | WINDOWDRAG | WINDOWDEPTH | WINDOWSIZING | WINDOWCLOSE,
                     /* window flags                    */
   NULL,             /* pointer to first user gadget    */
   NULL,             /* pointer to user checkmark       */
   "uwterm 1.00",    /* window title                    */
   NULL,             /* pointer to screen    (later)    */
   NULL,             /* pointer to superbitmap          */
   50,40,1000,1000,  /* sizing limits min and max       */
   WBENCHSCREEN      /* type of screen in which to open */
   };

InitLibs()
{
   GfxBase = OpenLibrary("graphics.library", 0);
   if (GfxBase == NULL) Cleanup();
   IntuitionBase = OpenLibrary("intuition.library", 0);
   if (IntuitionBase == NULL) Cleanup();
}
   struct Window *
NewTermWin()
{
   struct Window *win;

   win = OpenWindow(&nw);
   if ( win == NULL ) Cleanup();
   return(win);
}
SHAR_EOF
cat << \SHAR_EOF > term.h
/* INCLUDES ********************************************************** */

#include "exec/types.h"
#include "exec/ports.h"
#include "exec/devices.h"
#include "exec/io.h"
#include "exec/memory.h"

#include "libraries/dos.h"
#include "graphics/text.h"
#include "libraries/diskfont.h"
#include "intuition/intuition.h"
 
/* EXTERNALS ***************************************************** */

extern struct Window *OpenWindow();
extern struct Screen *OpenScreen();
extern struct MsgPort *CreatePort();
extern struct IOStdReq *CreateStdIO();
extern struct IORequest *CreateExtIO();

/* DATA TYPES *****************/
struct uw_struct {
	int free;		/* is this uw struct free? */
	struct MsgPort *ConReadPort, *ConWritePort;
	struct IOStdReq *ConWriteReq, *ConReadReq;
	struct Window *win;
	int winsig, consig;
};

extern struct uw_struct uw[];
extern int uw_read, uw_write, uw_count;

SHAR_EOF
#	End of shell archivnetoyl;