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;