ain@j.cc.purdue.edu (Patrick White) (01/25/88)
Program Name: uw (unix window client) Submitted By: denbeste@cc5.bbn.com Summary: This is a unix window client. Allows up to 7 windows into unix -- each with its own shell. Poster Boy: Pat White (ain@j.cc.purdue.edu) Tested. NOTES: I will be posting the unix server source, but I'm not sure if we will be archiving it. I've included terminal.diff even though I'm pretty sure the diffs have already been installed in terminal.c. -- Pat White (co-moderator comp.sources/binaries.amiga) UUCP: j.cc.purdue.edu!ain BITNET: PATWHITE@PURCCVM PHONE: (317) 743-8421 U.S. Mail: 320 Brown St. apt. 406, West Lafayette, IN 47906 ======================================== # 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: # README # amterm # terminal.c # terminal.diff # This archive created: Mon Jan 25 09:25:07 1988 # By: Patrick White (PUCC Land, USA) echo shar: extracting README '(1376 characters)' cat << \SHAR_EOF > README Enclosed here are the following files: <amterm> contains a termcap entry for the UW program's default window size. If you resize the window it won't work! <terminal.diff> contains the differences to 'terminal.c' to fix a bug <terminal.c> is the new version of the file <uw.uue> is an executable with the fix To use 'amterm', put it in a file in your home directory. After you log in, type: . amterm THEN run the uw-server on UNIX and carry on from there. [HOWEVER, comma, that worked just now with our current version of ULTRIX. When I was messing with this last summer, I had to run it with each window after it had been opened, when we were using a previous version of ULTRIX. Give it a try and check to see if it got exported and inherited correctly before you believe anything.] The original released version of UW has a bug in handling received linefeeds. On the screen, they show up as newlines, but certain programs which use CURSES try to use a linefeed to move the cursor straight down. As a result, the unmodified UW couldn't be used with VI or anything else that was screen oriented. This change fixes that, but unfortunately I don't remember precisely how, since I fixed it about 5 months ago. I seem to remember something about sending a special character sequence to the terminal handler to make a line-feed no longer treated as a newline. SHAR_EOF if test 1376 -ne "`wc -c README`" then echo shar: error transmitting README '(should have been 1376 characters)' fi echo shar: extracting amterm '(501 characters)' cat << \SHAR_EOF > amterm TERMCAP="sz|amiga|amiga-ansi:\ :ae=\017:as=\016:bw:mi:ms:sf=\E[S:sr=\E[T:te=\E[S\E23;H:vb=\007:\ :cr=^M:do=\ED:nl=^J:bl=^G:co#77:li#23:cl=\014:\ :le=^H:bs:am:cm=\E[%i%d;%dH:nd=\E[C:up=\E[A:\ :ce=\E[K:cd=\E[J:so=\E[3;7m:se=\E[m:us=\E[4m:ue=\E[m:\ :md=\E[1m:mr=\E[7m:mb=\E[2m:me=\E[m:is=\E[23t\E[79u\E[23;H:\ :ku=\EA:kd=\EB:kr=\EC:kl=\ED:kb=^H:kh=\E?~\ :ho=\E[H:k1=\E0~:k2=\E1~:k3=\E2~:k4=\E3~:ta=^I:pt:sr=\EM:\ :al=\E[L:dl=\E[M:dc=\E[P:ic=\E[@:im=:ei=:ed=:xn:" TERM="amiga" export TERM TERMCAP SHAR_EOF if test 501 -ne "`wc -c amterm`" then echo shar: error transmitting amterm '(should have been 501 characters)' fi echo shar: extracting terminal.c '(8109 characters)' 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 */ static char reset_mode[] = {0x9B, 0x32, 0x30, 0x6C}; 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]); uw[slot].ConWriteReq->io_Command = CMD_WRITE; uw[slot].ConWriteReq->io_Length = sizeof(reset_mode); uw[slot].ConWriteReq->io_Data = (APTR)(reset_mode); if(DoIO(uw[slot].ConWriteReq) != 0) { Notify(uw[uw_write].win, "Console write error."); } } /* 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 if test 8109 -ne "`wc -c terminal.c`" then echo shar: error transmitting terminal.c '(should have been 8109 characters)' fi echo shar: extracting terminal.diff '(359 characters)' cat << \SHAR_EOF > terminal.diff 40a41,42 > static char reset_mode[] = {0x9B, 0x32, 0x30, 0x6C}; > 68a71,78 > > uw[slot].ConWriteReq->io_Command = CMD_WRITE; > uw[slot].ConWriteReq->io_Length = sizeof(reset_mode); > uw[slot].ConWriteReq->io_Data = (APTR)(reset_mode); > > if(DoIO(uw[slot].ConWriteReq) != 0) { > Notify(uw[uw_write].win, "Console write error."); > } SHAR_EOF if test 359 -ne "`wc -c terminal.diff`" then echo shar: error transmitting terminal.diff '(should have been 359 characters)' fi # End of shell archive exit 0