diff options
Diffstat (limited to 'usr/chat.c')
| -rw-r--r-- | usr/chat.c | 57 |
1 files changed, 57 insertions, 0 deletions
diff --git a/usr/chat.c b/usr/chat.c new file mode 100644 index 0000000..987b336 --- /dev/null +++ b/usr/chat.c @@ -0,0 +1,57 @@ +#include "netlib.h" +/* chat: a link-port chat client. Incoming SLIP frames from the host gateway + print as messages; SELECT brings up the on-screen keyboard, type a line and + press START to send it. A poll loop interleaves receiving and typing so + messages arrive while you're not mid-line. */ + +static char rxbuf[96]; +static unsigned char rxlen, rxin, rxesc; + +/* feed one non-blocking byte to the SLIP receiver; returns a frame length when + a whole frame has arrived (copied into out), else 0. */ +static unsigned char slip_poll(char *out) { + int b = srecv_nb(); + unsigned char c, i, n; + if (b < 0) return 0; + c = (unsigned char)b; + if (c == SLIP_END) { + if (rxin && rxlen) { + n = rxlen; + for (i = 0; i < n; i++) out[i] = rxbuf[i]; + rxlen = 0; rxin = 0; rxesc = 0; + return n; + } + rxin = 1; rxlen = 0; rxesc = 0; + return 0; + } + if (!rxin) return 0; + if (rxesc) { + if (c == SLIP_ESC_END) c = SLIP_END; + else if (c == SLIP_ESC_ESC) c = SLIP_ESC; + rxesc = 0; + } else if (c == SLIP_ESC) { rxesc = 1; return 0; } + if (rxlen < 96) rxbuf[rxlen++] = (char)c; + return 0; +} + +void main(void) { + char line[64], frame[96]; + unsigned char linelen = 0, n, i, c; + puts("chat: SELECT=keyboard START=send"); nl(); + for (;;) { + n = slip_poll(frame); /* incoming message? */ + if (n) { + for (i = 0; i < n; i++) putc(frame[i]); + nl(); + } + c = pollin(); /* typed a key? */ + if (c == '\n') { + if (linelen) { slip_send(line, linelen); linelen = 0; } + } else if (c == 8) { + if (linelen) { linelen--; putc(8); } + } else if (c) { + if (linelen < 63) { line[linelen++] = (char)c; putc((char)c); } + } + yield(); + } +} |
