home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
HAM Radio 3
/
hamradioversion3.0examsandprograms1992.iso
/
packet
/
n17jsrc
/
ttydriv.c
< prev
next >
Wrap
C/C++ Source or Header
|
1991-06-28
|
6KB
|
256 lines
/* TTY input line editing
* Copyright 1991 Phil Karn, KA9Q
* split screen by G. J. van der Grinten, PA0GRI
*/
#include <stdio.h>
#ifdef __TURBOC__
#include <conio.h>
#endif
#include <ctype.h>
#include "global.h"
#include "mbuf.h"
#include "session.h"
#include "tty.h"
#include "socket.h"
extern FILE *Rawterm;
#define OFF 0
#define ON 1
static int Lastsize = 1;
static char Lastline[LINESIZE+1] = "\n";
#define CTLU 21 /* delete current line in total */
#define CTLR 18 /* reprint current line */
#define CTLZ 26 /* EOF char in dos */
#define CTLW 23 /* erase last word including preceding space */
#define CTLB 02 /* use as F3 in dos but no editing */
#define DEL 0x7f
/* Accept characters from the incoming tty buffer and process them
* (if in cooked mode) or just pass them directly (if in raw mode).
*
* Echoing (if enabled) is direct to the raw terminal. This requires
* recording (if enabled) of locally typed info to be done by the session
* itself so that edited output instead of raw input is recorded.
* Control-W added by g1emm again.... for word delete.
* Control-B/Function key 3 added by g1emm for line repeat.
*/
struct mbuf *
ttydriv(sp,c)
struct session *sp;
char c;
{
struct mbuf *bp;
char *cp,*rp;
int cnt;
switch(sp->ttystate.edit){
case OFF:
bp = ambufw(1);
*bp->data = c;
bp->cnt = 1;
if(sp->ttystate.echo){
if(sp->split){
sp->tsavex = wherex();
sp->tsavey = wherey();
window(1,24,80,25);
gotoxy(sp->bsavex,sp->bsavey);
highvideo();
putch(c);
normvideo();
cputs("_\b");
sp->bsavex = wherex();
sp->bsavey = wherey();
window(1,1,80,23);
gotoxy(sp->tsavex,sp->tsavey);
} else {
putc(c,Rawterm);
}
}
return bp;
case ON:
if(sp->ttystate.line == NULLBUF)
sp->ttystate.line = ambufw(LINESIZE);
bp = sp->ttystate.line;
cp = bp->data + bp->cnt;
/* Perform cooked-mode line editing */
switch(c & 0x7f){
case '\r': /* CR and LF both terminate the line */
case '\n':
if(sp->ttystate.crnl)
*cp = '\n';
else
*cp = c;
if(sp->ttystate.echo){
if(sp->split){
highvideo();
rp = bp->data;
while(rp < cp) {
putch(*rp++);
}
normvideo();
clreol();
cputs(Eol);
clreol();
sp->tsavex = wherex();
sp->tsavey = wherey();
window(1,24,80,25);
clrscr();
cputs("_\b");
sp->bsavex = wherex();
sp->bsavey = wherey();
window(1,1,80,23);
gotoxy(sp->tsavex,sp->tsavey);
} else {
fputs(Eol,Rawterm);
}
}
bp->cnt += 1;
sp->ttystate.line = NULLBUF;
Lastsize = bp->cnt;
memcpy(Lastline, bp->data, Lastsize);
return bp;
case DEL:
case '\b': /* Character delete */
if(bp->cnt != 0){
bp->cnt--;
if(sp->ttystate.echo){
if(sp->split){
sp->tsavex = wherex();
sp->tsavey = wherey();
window(1,24,80,25);
gotoxy(sp->bsavex,sp->bsavey);
cputs(" \b\b_\b");
sp->bsavex = wherex();
sp->bsavey = wherey();
window(1,1,80,23);
gotoxy(sp->tsavex,sp->tsavey);
} else {
fputs("\b \b",Rawterm);
}
}
}
break;
case CTLR: /* print line buffer */
if(sp->ttystate.echo){
if(sp->split) {
sp->tsavex = wherex();
sp->tsavey = wherey();
window(1,24,80,25);
gotoxy(sp->bsavex,sp->bsavey);
clrscr();
rp = bp->data;
while (rp < cp)
putch(*rp++) ;
cputs("_\b");
sp->bsavex = wherex();
sp->bsavey = wherey();
window(1,1,80,23);
gotoxy(sp->tsavex,sp->tsavey);
} else {
fprintf(Rawterm,"^R%s",Eol) ;
rp = bp->data;
while (rp < cp)
putc(*rp++,Rawterm) ;
}
}
break ;
case CTLU: /* Line kill */
if(sp->split) {
sp->tsavex = wherex();
sp->tsavey = wherey();
window(1,24,80,25);
gotoxy(sp->bsavex,sp->bsavey);
cputs(" \b");
while(bp->cnt != 0){
cputs("\b \b");
bp->cnt--;
}
cputs("_\b");
sp->bsavex = wherex();
sp->bsavey = wherey();
window(1,1,80,23);
gotoxy(sp->tsavex,sp->tsavey);
} else {
while(bp->cnt != 0){
bp->cnt--;
if(sp->ttystate.echo)
fputs("\b \b",Rawterm);
}
}
break;
case CTLB: /* Use last line to finish current */
cnt = bp->cnt; /* save count so far */
while(bp->cnt != 0){
bp->cnt--;
if(sp->ttystate.echo)
fputs("\b \b", Rawterm);
}
bp->cnt = cnt;
if(bp->cnt < (Lastsize-1)){
memcpy(bp->data+bp->cnt, &Lastline[bp->cnt], (Lastsize-1) - bp->cnt);
bp->cnt = Lastsize-1;
}
*(bp->data + bp->cnt) = '\0'; /* make it a string */
if(sp->ttystate.echo)
fputs(bp->data, Rawterm); /* repaint line */
break ;
case CTLW: /* erase word */
cnt = 0 ; /* we haven't seen a printable char yet */
while(bp->cnt != 0){
*(bp->data + bp->cnt--) = '\n';
if(sp->ttystate.echo)
fputs("\b \b", Rawterm);
if (isspace((int)*(bp->data + bp->cnt))) {
if (cnt)
break ;
} else {
cnt = 1 ;
}
}
break ;
default: /* Ordinary character */
*cp = c;
bp->cnt++;
/* ^Z apparently hangs the terminal emulators under
* DoubleDos and Desqview. I REALLY HATE having to patch
* around other people's bugs like this!!!
*/
if(sp->ttystate.echo &&
#ifndef AMIGA
c != CTLZ &&
#endif
bp->cnt < LINESIZE-1){
if(sp->split) {
sp->tsavex = wherex();
sp->tsavey = wherey();
window(1,24,80,25);
gotoxy(sp->bsavex,sp->bsavey);
putch(c);
cputs("_\b");
sp->bsavex = wherex();
sp->bsavey = wherey();
window(1,1,80,23);
gotoxy(sp->tsavex,sp->tsavey);
} else {
putc(c,Rawterm);
}
} else if(bp->cnt >= LINESIZE-1){
putc('\007',Rawterm); /* Beep */
bp->cnt--;
}
break;
}
break;
}
return NULLBUF;
}