char *ckxv = "AMIGA tty I/O, 1.0(000), 30 Mar 1986"; /* C K I T I O -- Terminal and Interrupt Functions for Commodore AMIGA */ /* * Copyright (C) 1986, Trustees of Columbia University in the City of * New York. Permission is granted to any individual or institution to * use, copy, or redistribute this software, so long as it is not sold * for profit, provided this copyright notice is retained. */ /* Edit History 27 Feb 1986 - Davide P. Cervone. Wrote it. This should be re-written to do menu and mouse stuff, but I don't have time for that just now. I don't have the ROM Kernal Manuals yet, so I expect that I will have done some things "wrong," and that there are better ways to do the I/O. I will try to update this when I get the manuals. The UnMap function will be used, eventually, to allow modifiable keyboard mappings (like MacKermit), and should allow for multi-character mappings, as well. Eventually, this should include a VT100 emulator. */ /* C-Kermit interrupt, terminal control & i/o functions for AMIGA systems */ char *ckxsys = " Commodore AMIGA"; /* Variables available to outside world: dftty -- Pointer to default tty name string, like "/dev/tty". dfloc -- 0 if dftty is console, 1 if external line. dfprty -- Default parity dfflow -- Default flow control ckxech -- Flag for who echoes console typein: 1 - The program (system echo is turned off) 0 - The system (or front end, or terminal). functions that want to do their own echoing should check this flag before doing so. backgrd -- Flag indicating program executing in background ( & on end of shell command). Used to ignore INT and QUIT signals. Functions for assigned communication line (either external or console tty): ttopen(ttname,local,mdmtyp) -- Open the named tty for exclusive access. ttclos() -- Close & reset the tty, releasing any access lock. ttpkt(speed,flow) -- Put the tty in packet mode and set the speed. ttvt(speed,flow) -- Put the tty in virtual terminal mode. or in DIALING or CONNECTED modem control state. ttinl(dest,max,timo) -- Timed read line from the tty. ttinc(timo) -- Timed read character from tty. ttchk() -- See how many characters in tty input buffer. ttxin(n,buf) -- Read n characters from tty (untimed). ttol(string,length) -- Write a string to the tty. ttoc(c) -- Write a character to the tty. ttflui() -- Flush tty input buffer. */ /* Functions for console terminal: congm() -- Get console terminal modes. concb(esc) -- Put the console in single-character wakeup mode with no echo. conbin(esc) -- Put the console in binary (raw) mode. conres() -- Restore the console to mode obtained by congm(). conoc(c) -- Unbuffered output, one character to console. conol(s) -- Unbuffered output, null-terminated string to the console. conola(s) -- Unbuffered output, array of strings to the console. conxo(n,s) -- Unbuffered output, n characters to the console. conchk() -- Check if characters available at console (bsd 4.2). Check if escape char (^\) typed at console (System III/V). coninc(timo) -- Timed get a character from the console. conint() -- Enable terminal interrupts on the console if not background. connoi() -- Disable terminal interrupts on the console if not background. contti() -- Get a character from either console or tty, whichever is first. Time functions msleep(m) -- Millisecond sleep ztime(&s) -- Return pointer to date/time string */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifndef max #define max(a,b) ((a)>(b)?(a):(b)) /* For Manx C (fnf) */ #endif #define INTUITION_REV 1 #define GRAPHICS_REV 1 #define SCREENCLR 12 /* character that does clear screen */ #define ERROR_EXIT 10 /* status for exit with error */ #define NODEF -1 /* undefined key */ #define NRMLKEYS 0 /* normal keys */ #define CTRLKEYS 1 /* control keys */ #define UNSHIFT 0 /* unshifted keyboard */ #define SHIFTED 1 /* shifted keyboard */ #define METABIT 0x80 /* 8th bit meta prefixing */ #define Puts(s) fputs(stdout,s) #define Printf(s) fprintf(stdout,s) #define Printf2(s,x) fprintf(stdout,s,x) char templine[500]; #define LONG_DEF #include "ckcker.h" #include "ckcdeb.h" /* Formats for debug() */ /* Declarations */ /* dftty is the device name of the default device for file transfer */ /* dfloc is 0 if dftty is the user's console terminal, 1 if an external line */ char *dftty = "SERIAL"; int dfloc = 1; /* Default location is local */ int dfprty = 0; /* Parity (0 = none) */ int dfflow = 1; /* Xon/Xoff flow control */ int batch = 0; /* Assume interactive */ int ckxech = 0; /* 0 if system normally echoes console characters, else 1 */ /* Declarations of variables global within this module */ static int conif = 0, /* Console interrupts on/off flag */ cgmf = 0, /* Flag that console modes saved */ ttychn = 0, /* TTY i/o channe; */ conch = NODEF; /* console input character buffer */ static char escchr; /* Escape or attn character */ #define LEFTEDGE 4 #define TOPEDGE 17 int Xpos=3, Ypos=17; /* current cursor position */ int Xmax, Ymax; /* current max X and Y values */ int CursorON = -1; /* cursor on or off */ struct IntuitionBase *IntuitionBase; struct GfxBase *GfxBase; struct timerequest TimerIO; struct MsgPort TimerMsgPort; extern struct MsgPort *CreatePort(); struct IOExtSer *ReadRequest; static char ReadPort[2]; struct IOExtSer *WriteRequest; static char WritePort[2]; int OpenedRead = 0; int OpenedWrite = 0; int OpenedIntui = 0; int OpenedGfx = 0; int OpenedWindow = 0; int OpenedTimer = 0; struct NewWindow NewWindow = { /* window definition */ 0, 0, 640, 200, 0, 1, CLOSEWINDOW | NEWSIZE | RAWKEY, WINDOWCLOSE | SMART_REFRESH | ACTIVATE | WINDOWDRAG | WINDOWDEPTH | WINDOWSIZING, NULL, NULL, (UBYTE *) "Amiga Kermit", NULL, NULL, 100, 35, 640, 200, WBENCHSCREEN }; struct Window *myWindow; /* new window */ OpenTimer() { extern struct Task *FindTask (); if (OpenDevice(TIMERNAME, UNIT_VBLANK, &TimerIO, 0) != 0) { Printf("Can't open Timer Device\n"); doexit(ERROR_EXIT); } else { OpenedTimer = 1; } TimerMsgPort.mp_Node.ln_Type = NT_MSGPORT; TimerMsgPort.mp_Node.ln_Name = "vt-timer"; TimerMsgPort.mp_Flags = 0; TimerMsgPort.mp_SigBit = AllocSignal(-1); TimerMsgPort.mp_SigTask = FindTask((char *)NULL); AddPort(&TimerMsgPort); TimerIO.tr_node.io_Message.mn_ReplyPort = &TimerMsgPort; } StartTimer(seconds, micros) int seconds, micros; { TimerIO.tr_node.io_Command = TR_ADDREQUEST; TimerIO.tr_node.io_Flags = IOF_QUICK; TimerIO.tr_time.tv_secs = (ULONG) seconds; TimerIO.tr_time.tv_micro = (ULONG) micros; SendIO(&TimerIO); } OpenSerial() /* Open the serial device */ { extern void *AllocMem (); ReadRequest = (struct IOExtSer *) AllocMem(sizeof(*ReadRequest), MEMF_PUBLIC | MEMF_CLEAR); ReadRequest->IOSer.io_Message.mn_ReplyPort = CreatePort("Read_RS",0); ReadRequest->io_SerFlags = SERF_SHARED | SERF_XDISABLED; OpenedRead = -1; if (OpenDevice(SERIALNAME, NULL, ReadRequest, NULL) != 0) { Printf("Can't open Serial Device for Reading\n"); doexit(ERROR_EXIT); } else { OpenedRead = 1; } WriteRequest = (struct IOExtSer *) AllocMem(sizeof(*WriteRequest), MEMF_PUBLIC | MEMF_CLEAR); WriteRequest->IOSer.io_Message.mn_ReplyPort = CreatePort("Write_RS",0); WriteRequest->io_SerFlags = SERF_SHARED | SERF_XDISABLED; OpenedWrite = -1; if (OpenDevice(SERIALNAME, NULL, WriteRequest, NULL) != 0) { Printf("Can't open Serial Device for Writing\n"); doexit(ERROR_EXIT); } else { OpenedWrite = 1; } ReadRequest->IOSer.io_Command = SDCMD_SETPARAMS; ReadRequest->IOSer.io_Length = 1; ReadRequest->IOSer.io_Data = (APTR) &ReadPort[0]; ReadRequest->io_SerFlags = SERF_SHARED | SERF_XDISABLED; ReadRequest->io_Baud = 9600; ReadRequest->io_ReadLen = 8; ReadRequest->io_WriteLen = 8; WriteRequest->IOSer.io_Command = CMD_WRITE; WriteRequest->IOSer.io_Length = 1; WriteRequest->IOSer.io_Data = (APTR) &WritePort[0]; WriteRequest->io_SerFlags = SERF_SHARED | SERF_XDISABLED; DoIO(ReadRequest); ReadRequest->IOSer.io_Command = CMD_READ; BeginIO(ReadRequest); } OpenLibraries() { extern void *OpenLibrary (); if ((IntuitionBase = (struct IntuitionBase *) OpenLibrary("intuition.library", INTUITION_REV)) == NULL) { Printf("Can't open Intuition Library\n"); doexit(ERROR_EXIT); } else { OpenedIntui = 1; } if ((GfxBase = (struct GfxBase *) OpenLibrary("graphics.library", GRAPHICS_REV)) == NULL) { Printf("Can't open Graphics Library\n"); doexit(ERROR_EXIT); } else { OpenedGfx = 1; } } OpenMyWindow() { extern struct Window *OpenWindow (); if ((myWindow = OpenWindow(&NewWindow)) == NULL) { Printf("Can't open my window\n"); doexit(ERROR_EXIT); } else { OpenedWindow = 1; } } OpenAll() { OpenLibraries(); OpenTimer(); OpenSerial(); OpenMyWindow(); } /* S Y S I N I T -- System-dependent program initialization. */ sysinit() { OpenAll(); SetAPen(myWindow->RPort,1); SetDrMd(myWindow->RPort,COMPLEMENT); Xmax = myWindow->Width; Ymax = myWindow->Height; putchar(SCREENCLR); return(0); } CloseLibraries() { if (OpenedIntui) CloseLibrary(IntuitionBase); if (OpenedGfx) CloseLibrary(GfxBase); OpenedIntui = 0; OpenedGfx = 0; } CloseSerial() { if (OpenedRead) { if (OpenedRead > 0) CloseDevice(ReadRequest); DeletePort(ReadRequest->IOSer.io_Message.mn_ReplyPort); FreeMem(ReadRequest,sizeof(*ReadRequest)); OpenedRead = 0; } if (OpenedWrite) { if (OpenedWrite > 0) CloseDevice(WriteRequest); DeletePort(WriteRequest->IOSer.io_Message.mn_ReplyPort); FreeMem(WriteRequest,sizeof(*WriteRequest)); OpenedWrite = 0; } } CloseTimer() { if (OpenedTimer) { CloseDevice(&TimerIO); RemPort(&TimerMsgPort); OpenedTimer = 0; } } CloseMyWindow() { if (OpenedWindow) { CloseWindow(myWindow); OpenedWindow = 0; } } /* S Y S C L N U P -- Clean up for final exeit from program */ sysclnup() { CloseSerial(); CloseTimer(); CloseMyWindow(); CloseLibraries(); } /* T T O P E N -- Open a tty for exclusive access. */ /* Returns 0 on success, -1 on failure. */ ttopen(ttname,lcl,modem) char *ttname; int *lcl, modem; { if (strcmp(ttname,"SERIAL")!=0) return(-1); ttychn = 1; return(0); } /* T T C L O S -- Close the TTY, releasing any lock. */ ttclos() { if (ttychn == 0) return(0); /* Wasn't open. */ ttychn = 0; /* Mark it as closed. */ return(0); } /* T T R E S -- Restore terminal to "normal" mode. */ ttres() { /* Restore the tty to normal. */ if (ttychn == 0) return(-1); /* Not open. */ debug(F101,"ttres, ttychn","",ttychn); return(0); } /* T T P K T -- Condition the communication line for packets. */ /* or for modem dialing */ #define DIALING 4 /* flags (via flow) for modem handling */ #define CONNECT 5 /* If called with speed > -1, also set the speed. */ /* Returns 0 on success, -1 on failure. */ ttpkt(speed,flow) int speed, flow; { extern char ttname[]; int s; if (ttychn == 0) return(-1); /* Not open. */ if ((s=ttsspd(speed)) <= 0) /* Check the speed */ return(-1); AbortIO(ReadRequest); ReadRequest->io_Baud = s; ReadRequest->IOSer.io_Command = SDCMD_SETPARAMS; DoIO(ReadRequest); ReadRequest->IOSer.io_Command = CMD_READ; BeginIO(ReadRequest); return(0); } /* T T V T -- Condition communication line for use as virtual terminal */ ttvt(speed,flow) int speed, flow; { ttpkt(speed,flow); return(0); } /* T T S S P D -- Return the internal baud rate code for 'speed'. */ int speeds[] = { 300, 1200, 2400, 4800, 9600, 19200, 0 } ; /* check that all of these are legal */ int ttsspd(speed) int speed; { int s; if (speed < 0) /* Unknown speed fails */ return (0); for (s = 0; speeds[s] != 0 && speeds[s] != speed; s++) ; if (speeds[s] != 0) return(speeds[s]); else { printf2("Unsupported line speed - %d\n",speed); printf("Current speed not changed\n"); return(-1); } } /* T T F L U I -- Flush tty input buffer */ ttflui() { AbortIO(ReadRequest); BeginIO(ReadRequest); return(0); } /* Interrupt Functions */ /* C O N I N T -- Console Interrupt setter */ conint(f) int (*f)(); { if (conif) return(0); /* Nothing to do if already on. */ conif = 1; /* Flag console interrupts on. */ return(0); } /* C O N N O I -- Reset console terminal interrupts */ connoi() { /* Console-no-interrupts */ conif = 0; return(0); } /* T T C H K -- Tell how many characters are waiting in tty input buffer */ ttchk() { if (CheckIO(ReadRequest)) return(1); else return(0); } /* T T X I N -- Get n characters from tty input buffer */ ttxin(n, buff) int n; char *buff; { int i; for (i=n; i > 0; i--) *buff++ = ttinc(0); *buff = '\0'; return(n); } /* T T O L -- Similar to "ttinl", but for writing. */ ttol(s,len) char s[]; int len; { int i; for (i=0; i0) { StartTimer(timo,0); time = -1; /* timed, but timer already set */ } else { time = 0; } i = 0; c = NODEF; while (i0) AbortIO(&TimerIO); if (i0) StartTimer(timo,0); while (NoChar) { if (CheckIO(ReadRequest)) { WaitIO(ReadRequest); c = ReadPort[0] & 0x7F; BeginIO(ReadRequest); NoChar = 0; } else { if (timo) { Wait ((1 << myWindow->UserPort->mp_SigBit) | (1 << TimerMsgPort.mp_SigBit) | (1 << ReadRequest->IOSer.io_Message.mn_ReplyPort->mp_SigBit)); if (CheckIO(&TimerIO)) return(-1); } else { Wait ((1 << myWindow->UserPort->mp_SigBit) | (1 << ReadRequest->IOSer.io_Message.mn_ReplyPort->mp_SigBit)); } while (NewMessage = (struct IntuiMessage *)GetMsg(myWindow->UserPort)) { class = NewMessage->Class; code = NewMessage->Code; qualifier = NewMessage->Qualifier; ReplyMsg(NewMessage); switch (class) { case CLOSEWINDOW: doexit(0); break; case NEWSIZE: Xmax = myWindow->Width; Ymax = myWindow->Height; conoc(SCREENCLR); break; case RAWKEY: if (UnMap(&c,code,qualifier)==0) conch = c; break; } } } } if (timo>0) AbortIO(&TimerIO); return(c); } /* T T S N D B -- Send a BREAK signal */ ttsndb() { if (ttychn == 0) return(-1); /* Not open. */ /* send a break */ return(0); } /* T T H A N G -- Hang up the communications line */ tthang() { if (ttychn == 0) return(-1); /* Not open. */ /* hang up */ return(0); } /* M S L E E P -- Millisecond version of sleep(). */ msleep(m) int m; { StartTimer(0,m); return(0); } /* S L E E P -- Pause for a few seconds */ sleep(time) int time; { /* StartTimer(time,0); Wait (1 << TimerMsgPort.mp_SigBit); */ } /* Z T I M E -- Return date/time string */ ztime(s) char **s; { *s = "Unknown date/time"; } /* C O N G M -- Get console terminal modes. */ /* Saves current console mode, and establishes variables for switching between current (presumably normal) mode and other modes. */ congm() { cgmf = 1; /* Flag that we got them. */ return(0); } /* C O N C B -- Put console in cbreak mode. */ /* Returns 0 if ok, -1 if not */ concb(esc) char esc; { if (cgmf == 0) congm(); /* Get modes if necessary. */ escchr = esc; /* Make this available to other fns */ ckxech = 1; /* Program can echo characters */ return(0); } /* C O N B I N -- Put console in binary mode */ /* Returns 0 if ok, -1 if not */ conbin(esc) char esc; { if (cgmf == 0) congm(); /* Get modes if necessary. */ escchr = esc; /* Make this available to other fns */ ckxech = 1; /* Program can echo characters */ return(0); } /* C O N R E S -- Restore the console terminal */ conres() { if (cgmf == 0) return(0); /* Don't do anything if modes */ ckxech = 0; /* System should echo chars */ return(0); } /* C O N O C -- Output a character to the console terminal */ conoc(c) int c; { int CursorChanged; CursorChanged = 0; if (CursorON) { XOR_Cursor(); CursorChanged = 1; } SetDrMd(myWindow->RPort,JAM2); switch(c) { case 0: break; case '\t': Xpos += 64; break; case '\n': Line_Feed(); break; case '\r': Xpos = LEFTEDGE; break; case '\b': Xpos = max(Xpos-8,LEFTEDGE); break; case SCREENCLR: /* page */ Xpos = LEFTEDGE; Ypos = TOPEDGE; SetAPen(myWindow->RPort,0); RectFill(myWindow->RPort,2,10,Xmax-19,Ymax-2); SetAPen(myWindow->RPort,1); break; case 7: /* bell */ ClipBlit(myWindow->RPort,0,0,myWindow->RPort,0,0,Xmax,Ymax,0x50); ClipBlit(myWindow->RPort,0,0,myWindow->RPort,0,0,Xmax,Ymax,0x50); break; default: if (c>31) /* only print non-control characters */ { char c1; /* temporary storage for character */ if (Xpos > Xmax-31) { Xpos = LEFTEDGE; Line_Feed(); } c1 = c; Move(myWindow->RPort,Xpos,Ypos); Text(myWindow->RPort,&c1,1); Xpos += 8; } } /* end of switch */ SetDrMd(myWindow->RPort,COMPLEMENT); if (CursorChanged) XOR_Cursor(); } Line_Feed() { if (Ypos > Ymax-12) ScrollRaster(myWindow->RPort,0,8,2,11,Xmax-20,Ymax-2); else Ypos += 8; } XOR_Cursor() { int cx, cy; CursorON = !CursorON; cy = Ypos; cx = Xpos+8; while (cx > (Xmax-23)) cx -= 8; SetAPen(myWindow->RPort,3); RectFill(myWindow->RPort,cx-8,cy-7,cx,cy+1); SetAPen(myWindow->RPort,1); } conocNL(c) /* really a putc command */ int c; { if (c == '\n') conoc('\r'); conoc(c); } /* C O N X O -- Write x characters to the console terminal */ conxo(x,s) char *s; int x; { XOR_Cursor(); while (x-- > 0) { if (*s == '\n') conoc('\r'); conoc(*s++); } XOR_Cursor(); } /* C O N O L -- Write a line to the console terminal */ conol(s) char *s; { XOR_Cursor(); while (*s != '\0') { if (*s == '\n') conoc('\r'); conoc(*s++); } XOR_Cursor(); } conolNL(s) char *s; /* really a puts */ { conol(s); conoc('\n'); conoc('\r'); } /* C O N O L A -- Write an array of lines to the console terminal */ conola(s) char *s[]; { int i; for (i=0 ; *s[i] ; i++) conol(s[i]); } /* C O N O L L -- Output a string followed by CRLF */ conoll(s) char *s; { conol(s); conol("\r\n"); } /* C O N C H K -- Check if characters available at console */ conchk() { return((conch == NODEF)? 0 : 1); } /* C O N I N C -- Get a character from the console */ coninc(timo) int timo; { int class,code,qualifier; struct IntuiMessage *NewMessage; int NoChar = -1; int c; extern struct Message *GetMsg (); /* Get buffered character, if any */ if (conch != NODEF) { c = conch; conch = NODEF; return(c); } if (timo>0) StartTimer(timo,0); while (NoChar) { if (timo) { Wait ((1 << myWindow->UserPort->mp_SigBit) | (1 << TimerMsgPort.mp_SigBit)); if (CheckIO(&TimerIO)) return(-1); } else { Wait(1 << myWindow->UserPort->mp_SigBit); } while (NewMessage = (struct IntuiMessage *)GetMsg(myWindow->UserPort)) { class = NewMessage->Class; code = NewMessage->Code; qualifier = NewMessage->Qualifier; ReplyMsg(NewMessage); switch (class) { case CLOSEWINDOW: doexit(0); break; case NEWSIZE: Xmax = myWindow->Width; Ymax = myWindow->Height; conoc(SCREENCLR); cmini(); prompt(); break; case RAWKEY: NoChar = UnMap(&c,code,qualifier); if (c == '\r') c = '\n'; if (c == 127) c = '\b'; break; } } } if (timo>0) AbortIO(&TimerIO); return(c); } UnMap(c,code,qualifier) int *c; int code, qualifier; { int CapsLock, ShiftType, MapType, MetaChar; static char KeyCode [] [2] [96] = { { /* normal keys */ { /* unshifted */ '`', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '=', '\\', NODEF, '0', 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', '[', ']', NODEF, '1', '2', '3', 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', '\'', NODEF, NODEF, '4', '5', '6', NODEF, 'z', 'x', 'c', 'v', 'b', 'n', 'm', ',', '.', '/', NODEF, '.', '7', '8', '9', /* SP BS TAB RETURN ENTER ESC DEL */ ' ', 8, '\t', '\r', '\r', 27, 127, NODEF, NODEF, NODEF, '-', NODEF, /* UP DOWN LEFT, RIGHT, */ NODEF, NODEF, NODEF, NODEF, /* Function keys 1 to 10 */ NODEF, NODEF, NODEF, NODEF, NODEF, NODEF, NODEF, NODEF, NODEF, NODEF, /* help */ NODEF, NODEF, NODEF, NODEF, NODEF, '?' }, { /* shifted */ '~', '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '_', '+', '|', NODEF, '0', 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P', '{', '}', NODEF, '1', '2', '3', 'A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L', ':', '"', NODEF, NODEF, '4', '5', '6', NODEF, 'Z', 'X', 'C', 'V', 'B', 'N', 'M', '<', '>', '?', NODEF, '.', '7', '8', '9', /* SP BS TAB RETURN ENTER ESC DEL */ ' ', 8, '\t', '\r', '\r', 27, 127, NODEF, NODEF, NODEF, '-', NODEF, /* UP DOWN LEFT, RIGHT, */ NODEF, NODEF, NODEF, NODEF, /* Function keys 1 to 10 */ NODEF, NODEF, NODEF, NODEF, NODEF, NODEF, NODEF, NODEF, NODEF, NODEF, /* help */ NODEF, NODEF, NODEF, NODEF, NODEF, '?' } }, { /* Control Keys */ { /* unshifted */ '`', '1', 0 , '3', '4', '5', 30, '7', '8', '9', '0', 31, '=', 28, NODEF, '0', 17, 23, 5 , 18, 20, 25, 21, 9 , 15, 16, 27, 29, NODEF, '1', '2', '3', 1 , 19, 4 , 6 , 7 , 8 , 10, 11, 12, ';', '\'', NODEF, NODEF, '4', '5', '6', NODEF, 26, 24, 3 , 22, 2 , 14, 13, ',', '.', '/', NODEF, '.', '7', '8', '9', /* SP BS TAB RETURN ENTER ESC DEL */ ' ', 8, '\t', '\r', '\r', 27, 127, NODEF, NODEF, NODEF, '-', NODEF, /* UP DOWN LEFT, RIGHT, */ NODEF, NODEF, NODEF, NODEF, /* Function keys 1 to 10 */ NODEF, NODEF, NODEF, NODEF, NODEF, NODEF, NODEF, NODEF, NODEF, NODEF, /* help */ NODEF, NODEF, NODEF, NODEF, NODEF, '?' }, { /* shifted */ '~', '!', 0 , '#', '$', '%', 30, '&', '*', '(', ')', 31, '+', 28, NODEF, '0', 17, 23, 5 , 18, 20, 25, 21, 9 , 15, 16, 27, 29, NODEF, '1', '2', '3', 1 , 19, 4 , 6 , 7 , 8 , 10, 11, 12, ':', '"', NODEF, NODEF, '4', '5', '6', NODEF, 26, 24, 3 , 22, 2 , 14, 13, '<', '>', '?', NODEF, '.', '7', '8', '9', /* SP BS TAB RETURN ENTER ESC DEL */ ' ', 8, '\t', '\r', '\r', 27, 127, NODEF, NODEF, NODEF, '-', NODEF, /* UP DOWN LEFT, RIGHT, */ NODEF, NODEF, NODEF, NODEF, /* Function keys 1 to 10 */ NODEF, NODEF, NODEF, NODEF, NODEF, NODEF, NODEF, NODEF, NODEF, NODEF, /* help */ NODEF, NODEF, NODEF, NODEF, NODEF, '?' } } }; if (code > 95) { *c = NODEF; return(-1); } else { ShiftType = (qualifier & (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT)) ? SHIFTED : UNSHIFT; CapsLock = (qualifier & IEQUALIFIER_CAPSLOCK) ? 1 : 0; MapType = (qualifier & IEQUALIFIER_CONTROL) ? CTRLKEYS : NRMLKEYS; MetaChar = (qualifier & (IEQUALIFIER_LALT | IEQUALIFIER_RALT)) ? METABIT : 0; if ((*c = KeyCode [MapType] [ShiftType] [code]) == NODEF) { return(-1); } else { if (CapsLock && *c >= 'a' && *c <= 'z') *c -= 32; *c |= MetaChar; return(0); } } } /* C O N T T I -- Get character from console or tty, whichever comes */ /* first. This is used in conect() when NO_FORK is defined. */ /* src is returned with 1 if the character came from the comm. line, */ /* 0 if it was from the console, and with -1 if there was any error. */ contti(c,src) int *c; int *src; { int class,code,qualifier; struct IntuiMessage *NewMessage; int NoChar = -1; while (NoChar) { if (CheckIO(ReadRequest)) { *src = 1; WaitIO(ReadRequest); *c = ReadPort[0] & 0x7F; BeginIO(ReadRequest); NoChar = 0; } else { Wait ((1 << myWindow->UserPort->mp_SigBit) | (1 << ReadRequest->IOSer.io_Message.mn_ReplyPort->mp_SigBit)); while (NewMessage = (struct IntuiMessage *)GetMsg(myWindow->UserPort)) { class = NewMessage->Class; code = NewMessage->Code; qualifier = NewMessage->Qualifier; ReplyMsg(NewMessage); switch (class) { case CLOSEWINDOW: doexit(0); break; case NEWSIZE: Xmax = myWindow->Width; Ymax = myWindow->Height; conoc(SCREENCLR); break; case RAWKEY: NoChar = UnMap(c,code,qualifier); *src = 0; break; } } } } return(0); } /* C A N C I O -- Cancel any pending i/o requests on the console or the comm. line. */ cancio() { ttflui(); }