/******************************************************************************
* This file is part of a software distribution, which is furnished under the *
* terms of a license. Use of this software by any means is subject to this *
* license and signifies the acceptance of the licensing terms stated *
* therein. Please see the file LICENSE in the top-level directory of this *
* software distribution for detailed copyright disclaimers and licensing *
* terms. *
******************************************************************************
* Copryight (c) by Andreas S. Wetzel - All rights reserved. *
******************************************************************************/
/* $Id: vd_input.c,v 1.3 2001/03/19 23:17:29 mickey Exp $ */
#include <vchat.h>
#include <proto_vchatd.h>
#include <ctype.h>
/*** Globals ***/
ED main_ed;
ED *ed = &main_ed;
/*** Externals ***/
extern int in_chat_window;
extern VP vp;
extern VTCAP vtcap;
/*
* int input_line(char *prompt, size_t maxlen, u_short flags);
*
* Read input from the users terminal up to maxlen characters (or the
* maximum possible length if maxlen is given as 0) and return the number
* of bytes actually read into the global ED buffer pointed to by the global
* ed variable. Flags should be the bitwise OR of any of the following flags:
*
* ED_RST_CTX - Reset input context upon startup
* ED_NO_ECHO - Suppress terminal echo while reading input
*
*/
int input_line(char *prompt, size_t maxlen, u_short flags)
{
static char lterm = 0;
u_char c;
u_char cx;
/*** Lock all interrupts during init ***/
vlock(LOCK, (V_IO | V_TIMER));
/*** Disable videosnake ***/
snake_disable();
/**** Buffer init ****/
if(flags & ED_RST_CTX)
{
/*
* Reset input context upon startup
*/
BZERO(&ed->buffer, EDBUFSIZE+1);
ed->endpos = ed->curpos = ed->margin = (char *) &ed->buffer;
ed->prompt = NULL;
}
if(prompt)
ed->prompt = prompt;
ed->offset = (ed->prompt != NULL) ? real_len(ed->prompt) : 0;
ed->maxlen = (maxlen > 0 && maxlen < EDBUFSIZE) ? maxlen : EDBUFSIZE;
ed->flags = flags;
/***** window init *****/
line_update();
/*** init completed - unlock interrupts ***/
vlock(UNLOCK, (V_IO | V_TIMER));
/*** Wait for user input ***/
for(;;)
{
/* Get character */
switch(read(0, &c, 1))
{
case 1: break;
case 0: log(VLOG_ERR, "TELNET connection closed by remote host");
snd_serv(CMD_SIGNOFF, NULL, 0);
vquit(NULL);
case -1: log(VLOG_ERR, "read error on TELNET connection (%s)",
strerror(errno));
snd_serv(CMD_SIGNOFF, NULL, 0);
vquit(NULL);
default: log(VLOG_ERR, "Oooops!!!");
snd_serv(CMD_SIGNOFF, NULL, 0);
vquit("Oooops!!!");
}
/* End of line? */
if((c == CR && lterm != LF)
|| (c == LF && lterm != CR))
{
lterm = c;
break;
}
else if(c == CR || c == LF)
{
continue;
}
/* Filter for incoming telnet commands */
if(!(cx = tel_filter(c)))
continue;
vlock(LOCK, (V_IO | V_TIMER));
snake_enable();
if(is_key_sequence(vtcap.key_cursleft, cx))
{
curs_left();
}
else if(is_key_sequence(vtcap.key_cursright, cx))
{
curs_right();
}
else if(is_key_sequence(vtcap.key_cursup, cx))
{
if((ed->flags & ED_HISTORY) != 0
&& vp.history_current != vp.history_start)
{
snake_disable();
vlock(UNLOCK, (V_IO | V_TIMER));
return(-2);
}
else
{
nop();
}
}
else if(is_key_sequence(vtcap.key_cursdown, cx))
{
if((ed->flags & ED_HISTORY) != 0
&& vp.history_current != vp.history_next)
{
snake_disable();
vlock(UNLOCK, (V_IO | V_TIMER));
return(-4);
}
else
{
nop();
}
}
else if(is_key_sequence(vtcap.key_insert, cx))
{
ungetc(' ', stdin);
}
else if(is_key_sequence(vtcap.key_delete, cx))
{
delete();
}
else if(iscntrl(cx))
{
switch(cx)
{
case DEL:
case BS: backspace();
break;
case CTL_A: jump_start();
break;
case CTL_E: jump_end();
break;
case CTL_D: delete();
break;
case CTL_K: erase_eol();
break;
case CTL_U: erase_line();
break;
case CTL_F: word_forward();
break;
case CTL_B: word_reverse();
break;
case CTL_L: line_update();
break;
case HT: tabcomplete();
break;
default: break;
}
}
else
{
if(ed->curpos != ed->endpos)
{
/*
* Insert mode
*/
insert_char(cx);
}
else
{
/*
* Append mode
*/
append_char(cx);
}
}
vlock(UNLOCK, (V_IO | V_TIMER));
}
if(ED_USED)
{
vlock(LOCK, (V_IO | V_TIMER));
mv(1, vtcap.rows);
in_chat_window = 0;
if(vtcap.clear2eol)
tputs(vtcap.clear2eol, 1, (void *)outc);
else if(vtcap.clear2eod)
tputs(vtcap.clear2eod, 1, (void *)outc);
vlock(UNLOCK, (V_IO | V_TIMER));
}
return(ED_USED);
}
syntax highlighted by Code2HTML, v. 0.9.1