static void term_show_prompt2(void)
{
    term_printf("%s", term_prompt);
    term_flush();
    term_last_cmd_buf_index = 0;
    term_last_cmd_buf_size = 0;
    term_esc_state = IS_NORM;
}
Beispiel #2
0
/*
 * term_reset: sets terminal attributed back to what they were before the
 * program started
 */
void
term_reset(void)
{
	tcsetattr(tty_des, TCSADRAIN, &oldb);

	if (CS)
		tputs_x(tgoto(CS, get_li() - 1, 0));
	if (!use_termcap_enterexit() && TE)
		tputs_x(TE);
	term_move_cursor(0, get_li() - 1);
	term_reset_flag = 1;
	term_flush();
}
Beispiel #3
0
/* cursor_to_input: move the cursor to the input line, if not there already */
void cursor_to_input(void)
{
    Screen *old_current_screen;

    old_current_screen = current_screen;
    for (current_screen = screen_list; current_screen; current_screen = current_screen->next) {
	if (current_screen->alive && is_cursor_in_display(NULL)) {
	    term_move_cursor(cursor, input_line);
	    cursor_not_in_display();
	    term_flush();
	}
    }
    set_current_screen(old_current_screen);
}
Beispiel #4
0
/* cursor_to_input: move the cursor to the input line, if not there already */
void
cursor_to_input(void)
{
	if (screen_get_alive(get_current_screen()) && is_cursor_in_display())
	{
		ScreenInputData *inputdata = screen_get_inputdata(get_current_screen());

		term_move_cursor(inputdata->cursor_x, inputdata->cursor_y);
		Debug(DB_CURSOR, "cursor_to_input: moving cursor to input for screen %d",
		       screen_get_screennum(get_current_screen()));
		cursor_not_in_display();
		term_flush();
	}
}
Beispiel #5
0
/* cursor_to_input: move the cursor to the input line, if not there already */
void 	cursor_to_input (void)
{
	Screen *oldscreen = last_input_screen;
	Screen *screen;

	if (!foreground)
		return;		/* Dont bother */

	for (screen = screen_list; screen; screen = screen->next)
	{
		if (screen->alive && is_cursor_in_display(screen))
		{
			output_screen = screen;
			last_input_screen = screen;
			term_move_cursor(INPUT_CURSOR, INPUT_LINE);
			term_flush();
			cursor_not_in_display(screen);
		}
	}
	output_screen = last_input_screen = oldscreen;
}
/* update the displayed command line */
static void term_update(void)
{
    int i, delta, len;

    if (term_cmd_buf_size != term_last_cmd_buf_size ||
        memcmp(term_cmd_buf, term_last_cmd_buf, term_cmd_buf_size) != 0) {
        for(i = 0; i < term_last_cmd_buf_index; i++) {
            term_printf("\033[D");
        }
        term_cmd_buf[term_cmd_buf_size] = '\0';
        if (term_is_password) {
            len = strlen(term_cmd_buf);
            for(i = 0; i < len; i++)
                term_printf("*");
        } else {
            term_printf("%s", term_cmd_buf);
        }
        term_printf("\033[K");
        memcpy(term_last_cmd_buf, term_cmd_buf, term_cmd_buf_size);
        term_last_cmd_buf_size = term_cmd_buf_size;
        term_last_cmd_buf_index = term_cmd_buf_size;
    }
    if (term_cmd_buf_index != term_last_cmd_buf_index) {
        delta = term_cmd_buf_index - term_last_cmd_buf_index;
        if (delta > 0) {
            for(i = 0;i < delta; i++) {
                term_printf("\033[C");
            }
        } else {
            delta = -delta;
            for(i = 0;i < delta; i++) {
                term_printf("\033[D");
            }
        }
        term_last_cmd_buf_index = term_cmd_buf_index;
    }
    term_flush();
}
Beispiel #7
0
/*
 * update_input: does varying amount of updating on the input line depending
 * upon the position of the cursor and the update flag.  If the cursor has
 * move toward one of the edge boundaries on the screen, update_cursor()
 * flips the input line to the next (previous) line of text. The update flag
 * may be: 
 *
 * NO_UPDATE - only do the above bounds checking. 
 *
 * UPDATE_JUST_CURSOR - do bounds checking and position cursor where is should
 * be. 
 *
 * UPDATE_FROM_CURSOR - does all of the above, and makes sure everything from
 * the cursor to the right edge of the screen is current (by redrawing it). 
 *
 * UPDATE_ALL - redraws the entire line 
 */
void	update_input (int update)
{
	int	old_zone;
	char	*ptr, *ptr_free;
	int	len,
		free_it = 0,
		max;
	char	*prompt;
	int	do_echo = 1;
	Screen	*os = last_input_screen;
	Screen	*ns;
	Window	*saved_current_window = current_window;

	/*
	 * No input line in dumb or bg mode.
	 */
	if (dumb_mode || !foreground)
		return;

  for (ns = screen_list; ns; ns = ns->next)
  {
	if (!ns->alive)
		continue;	/* It's dead, Jim! */

	last_input_screen = ns;
	current_window = ns->current_window;

	/*
	 * Make sure the client thinks the cursor is on the input line.
	 */
	cursor_to_input();

	/*
	 * See if we're in a add_wait_prompt() call.  If we are, grab that
	 * current prompt, otherwise use the default input prompt.
	 */
	if (last_input_screen->promptlist)
		prompt = last_input_screen->promptlist->prompt;
	else
		prompt = input_prompt;

	/*
	 *
	 * GET THE INPUT PROMPT
	 *
	 */

	/*
	 * If we have a prompt, and we're supposed to update the input
	 * prompt, then we do need to expand the prompt.
	 */
	if (prompt && update != NO_UPDATE)
	{
		int	af;

		/*
		 * If the current window is query'ing an exec'd process,
		 * then we just get the current prompt for that process.
		 * Note that it is not malloced.
		 */
		if (is_valid_process(get_target_by_refnum(0)) != -1)
			ptr = get_prompt_by_refnum(0);

		/*
		 * Otherwise, we just expand the prompt as normal.
		 */
		else
		{
			ptr = expand_alias(prompt, empty_string, &af, NULL);
			free_it = 1;
		}

		/*
		 * If we're in an add_wait_prompt(), we see whether or not
		 * this is an "invisible" prompt.  If it is, we turn off the
		 * echo so what the user types doesnt show up.
		 */
		if (last_input_screen->promptlist)
			term_echo(last_input_screen->promptlist->echo);

		/*
		 * Mangle out any ansi chars or so forth.
		 */
		ptr_free = ptr;
		ptr = normalize_string(ptr, 0);	/* This should be ok */
		if (free_it)
			new_free(&ptr_free);
		free_it = 1;

		/*
		 * If the prompt has changed, or if there is no prompt...
		 */
		if (	(ptr && !INPUT_PROMPT) ||
			(!ptr && INPUT_PROMPT) ||
			strcmp(ptr, INPUT_PROMPT)	)
		{
			if (last_input_screen->input_prompt_malloc)
				new_free(&INPUT_PROMPT);

			last_input_screen->input_prompt_malloc = free_it;
			INPUT_PROMPT = ptr;
			INPUT_PROMPT_LEN = output_with_count(INPUT_PROMPT, 0, 0);
			update = UPDATE_ALL;
		}
		/*
		 * Prompt didnt change, so clean up our mess
		 */
		else
		{
			if (free_it)
				new_free(&ptr);
		}
	}


	/*
	 * 
	 * HAS THE SCREEN CHANGED SIZE SINCE THE LAST TIME?
	 *
	 */

	/*
	 * If the screen has resized, then we need to re-compute the
	 * side-to-side scrolling effect.
	 */
	if ((last_input_screen->li != last_input_screen->old_li) || 
	    (last_input_screen->co != last_input_screen->old_co))
	{
		/*
		 * The input line is always the bottom line
		 */
		INPUT_LINE = last_input_screen->li - 1;

		/*
		 * The "zone" is the range in which when you type, the
		 * input line does not scroll.  It is WIDTH chars in from
		 * either side of the display.
		 */
		ZONE = last_input_screen->co - (WIDTH * 2);
		if (ZONE < 10)
			ZONE = 10;		/* Take that! */
		START_ZONE = WIDTH;
		END_ZONE = last_input_screen->co - WIDTH;

		last_input_screen->old_co = last_input_screen->co;
		last_input_screen->old_li = last_input_screen->li;
	}

	/*
	 * About zones:
	 * The input line is divided into "zones".  A "zone" is set above,
	 * and is the width of the screen minus 20 (by default).  The input
	 * line, as displayed, is therefore composed of the current "zone",
	 * plus 10 characters from the previous zone, plus 10 characters 
	 * from the next zone.  When the cursor moves to an adjacent zone,
	 * (by going into column 9 from the right or left of the edge), the
	 * input line is redrawn.  There is one catch.  The first "zone"
	 * includes the first ten characters of the input line.
	 */
	old_zone = START_ZONE;

	/*
	 * The BEGINNING of the current "zone" is a calculated value:
	 *	The number of characters since the origin of the input buffer
	 *	is the number of printable chars in the input prompt plus the
	 *	current position in the input buffer.  We subtract from that
	 * 	the WIDTH delta to take off the first delta, which doesnt
	 *	count towards the width of the zone.  Then we divide that by
	 * 	the size of the zone, to get an integer, then we multiply it
	 * 	back.  This gives us the first character on the screen.  We
	 *	add WIDTH to the result in order to get the start of the zone
	 *	itself.
	 * The END of the current "zone" is just the beginning plus the width.
	 * If we have moved to an different "zone" since last time, we want to
	 * 	completely redraw the input line.
	 */
	START_ZONE = ((INPUT_PROMPT_LEN + THIS_POS - WIDTH) / ZONE) * ZONE + WIDTH;
	END_ZONE = START_ZONE + ZONE;

	if (old_zone != START_ZONE)
		update = UPDATE_ALL;

	/*
	 * Now that we know where the "zone" is in the input buffer, we can
	 * easily calculate where where we want to start displaying stuff
	 * from the INPUT_BUFFER.  If we're in the first "zone", then we will
	 * output from the beginning of the buffer.  If we're not in the first
	 * "zone", then we will begin to output from 10 characters to the
	 * left of the zone, after adjusting for the length of the prompt.
	 */
	if (START_ZONE == WIDTH)
	    INPUT_ONSCREEN = 0;
	else {
	    if ((INPUT_ONSCREEN = START_ZONE - WIDTH - INPUT_PROMPT_LEN) < 0)
		INPUT_ONSCREEN = 0;
	}

	/*
	 * And the cursor is simply how many characters away THIS_POS is
	 * from the first column on the screen.
	 */
	if (INPUT_ONSCREEN == 0)
		INPUT_CURSOR = INPUT_PROMPT_LEN + THIS_POS;
	else
		INPUT_CURSOR = THIS_POS - INPUT_ONSCREEN;

	/*
	 * If the cursor moved, or if we're supposed to do a full update,
	 * then redraw the entire input line.
	 */
	if (update == UPDATE_ALL)
	{
		/*
		 * Move the cursor to the start of the input line
		 */
		term_move_cursor(0, INPUT_LINE);

		/*
		 * If the input line is NOT empty, and we're starting the
		 * display at the beginning of the input buffer, then we
		 * output the prompt first.
		 */
		if (INPUT_ONSCREEN == 0 && INPUT_PROMPT && *INPUT_PROMPT)
		{
			/*
			 * Forcibly turn on echo.
			 */
			do_echo = term_echo(1);

			/*
			 * Crop back the input prompt so it does not extend
			 * past the end of the zone.
			 */
			if (INPUT_PROMPT_LEN > (last_input_screen->co - WIDTH))
				INPUT_PROMPT_LEN = last_input_screen->co - WIDTH - 1;

			/*
			 * Output the prompt.
			 */
			output_with_count(INPUT_PROMPT, 0, 1);

			/*
			 * Turn the echo back to what it was before,
			 * and output the rest of the input buffer.
			 */
			term_echo(do_echo);
			safe_puts(INPUT_BUFFER, last_input_screen->co - INPUT_PROMPT_LEN, do_echo);
		}

		/*
		 * Otherwise we just output whatever we have.
		 */
		else if (do_echo)
			safe_puts(&(INPUT_VISIBLE), last_input_screen->co, do_echo);

		/*
		 * Clear the rest of the input line and reset the cursor
		 * to the current input position.
		 */
		term_clear_to_eol();
		term_move_cursor(INPUT_CURSOR, INPUT_LINE);
		cursor_not_in_display(last_input_screen);
	}

	/*
	 * If we're just supposed to refresh whats to the right of the
	 * current logical position...
	 */
	else if (update == UPDATE_FROM_CURSOR)
	{
		/*
		 * Move the cursor to where its supposed to be,
		 * Figure out how much we can output from here,
		 * and then output it.
		 */
		term_move_cursor(INPUT_CURSOR, INPUT_LINE);
		max = last_input_screen->co - (THIS_POS - INPUT_ONSCREEN);
		if (INPUT_ONSCREEN == 0 && INPUT_PROMPT && *INPUT_PROMPT)
			max -= INPUT_PROMPT_LEN;

		if ((len = strlen(&(THIS_CHAR))) > max)
			len = max;
		safe_puts(&(THIS_CHAR), len, do_echo);
		term_clear_to_eol();
		term_move_cursor(INPUT_CURSOR, INPUT_LINE);
		cursor_not_in_display(last_input_screen);
	}

	/*
	 * If we're just supposed to move the cursor back to the input
	 * line, then go ahead and do that.
	 */
	else if (update == UPDATE_JUST_CURSOR)
	{
		term_move_cursor(INPUT_CURSOR, INPUT_LINE);
		cursor_not_in_display(last_input_screen);
	}

	/*
	 * Turn the terminal echo back on, and flush all of the output
	 * we may have done here.
	 */
	term_echo(1);
	term_flush();
    }
    last_input_screen = os;
    current_window = saved_current_window;
}
Beispiel #8
0
void
loop(void)
{
	enum {
		ST_COMMAND,
		ST_TRANSPARENT
	} state;
	int dtr_up;
	fd_set rdset, wrset;
	int newbaud, newflow, newparity, newbits;
	char *newflow_str, *newparity_str;
	char fname[128];
	int r, n;
	unsigned char c;


	tty_q.len = 0;
	state = ST_TRANSPARENT;
	dtr_up = 0;

	for (;;) {
		FD_ZERO(&rdset);
		FD_ZERO(&wrset);
		FD_SET(STI, &rdset);
		FD_SET(tty_fd, &rdset);
		if ( tty_q.len ) FD_SET(tty_fd, &wrset);

		if (select(FD_SETSIZE, &rdset, &wrset, NULL, NULL) < 0)
			fatal("select failed: %d : %s", errno, strerror(errno));

		if ( FD_ISSET(STI, &rdset) ) {

			/* read from terminal */

			do {
				n = read(STI, &c, 1);
			} while (n < 0 && errno == EINTR);
			if (n == 0)
				fatal("stdin closed");
			else if (n < 0)
				fatal("read from stdin failed: %s", strerror(errno));

			switch (state) {

			case ST_COMMAND:
				if ( c == opts.escape ) {
					state = ST_TRANSPARENT;
					/* pass the escape character down */
					if (tty_q.len <= TTY_Q_SZ)
						tty_q.buff[tty_q.len++] = c;
					else
						fd_printf(STO, "\x07");
					break;
				}
				state = ST_TRANSPARENT;
				switch (c) {
				case KEY_EXIT:
					return;
				case KEY_QUIT:
					term_set_hupcl(tty_fd, 0);
					term_flush(tty_fd);
					term_apply(tty_fd);
					term_erase(tty_fd);
					return;
				case KEY_STATUS:
					fd_printf(STO, "\r\n");
					fd_printf(STO, "*** baud: %d\r\n", opts.baud);
					fd_printf(STO, "*** flow: %s\r\n", opts.flow_str);
					fd_printf(STO, "*** parity: %s\r\n", opts.parity_str);
					fd_printf(STO, "*** databits: %d\r\n", opts.databits);
					fd_printf(STO, "*** dtr: %s\r\n", dtr_up ? "up" : "down");
					break;
				case KEY_PULSE:
					fd_printf(STO, "\r\n*** pulse DTR ***\r\n");
					if ( term_pulse_dtr(tty_fd) < 0 )
						fd_printf(STO, "*** FAILED\r\n");
					break;
				case KEY_TOGGLE:
					if ( dtr_up )
						r = term_lower_dtr(tty_fd);
					else
						r = term_raise_dtr(tty_fd);
					if ( r >= 0 ) dtr_up = ! dtr_up;
					fd_printf(STO, "\r\n*** DTR: %s ***\r\n", 
							  dtr_up ? "up" : "down");
					break;
				case KEY_BAUD_UP:
					newbaud = baud_up(opts.baud);
					term_set_baudrate(tty_fd, newbaud);
					tty_q.len = 0; term_flush(tty_fd);
					if ( term_apply(tty_fd) >= 0 ) opts.baud = newbaud;
					fd_printf(STO, "\r\n*** baud: %d ***\r\n", opts.baud);
					break;
				case KEY_BAUD_DN:
					newbaud = baud_down(opts.baud);
					term_set_baudrate(tty_fd, newbaud);
					tty_q.len = 0; term_flush(tty_fd);
					if ( term_apply(tty_fd) >= 0 ) opts.baud = newbaud;
					fd_printf(STO, "\r\n*** baud: %d ***\r\n", opts.baud);
					break;
				case KEY_FLOW:
					newflow = flow_next(opts.flow, &newflow_str);
					term_set_flowcntrl(tty_fd, newflow);
					tty_q.len = 0; term_flush(tty_fd);
					if ( term_apply(tty_fd) >= 0 ) {
						opts.flow = newflow;
						opts.flow_str = newflow_str;
					}
					fd_printf(STO, "\r\n*** flow: %s ***\r\n", opts.flow_str);
					break;
				case KEY_PARITY:
					newparity = parity_next(opts.parity, &newparity_str);
					term_set_parity(tty_fd, newparity);
					tty_q.len = 0; term_flush(tty_fd);
					if ( term_apply(tty_fd) >= 0 ) {
						opts.parity = newparity;
						opts.parity_str = newparity_str;
					}
					fd_printf(STO, "\r\n*** parity: %s ***\r\n", 
							  opts.parity_str);
					break;
				case KEY_BITS:
					newbits = bits_next(opts.databits);
					term_set_databits(tty_fd, newbits);
					tty_q.len = 0; term_flush(tty_fd);
					if ( term_apply(tty_fd) >= 0 ) opts.databits = newbits;
					fd_printf(STO, "\r\n*** databits: %d ***\r\n", 
							  opts.databits);
					break;
				case KEY_SEND:
					fd_printf(STO, "\r\n*** file: ");
					r = fd_readline(STI, STO, fname, sizeof(fname));
					fd_printf(STO, "\r\n");
					if ( r < -1 && errno == EINTR ) break;
					if ( r <= -1 )
						fatal("cannot read filename: %s", strerror(errno));
					run_cmd(tty_fd, opts.send_cmd, fname, NULL);
					break;
				case KEY_RECEIVE:
					fd_printf(STO, "*** file: ");
					r = fd_readline(STI, STO, fname, sizeof(fname));
					fd_printf(STO, "\r\n");
					if ( r < -1 && errno == EINTR ) break;
					if ( r <= -1 )
						fatal("cannot read filename: %s", strerror(errno));
					if ( fname[0] )
						run_cmd(tty_fd, opts.send_cmd, fname, NULL);
					else
						run_cmd(tty_fd, opts.receive_cmd, NULL);
					break;
				case KEY_BREAK:
					term_break(tty_fd);
					fd_printf(STO, "\r\n*** break sent ***\r\n");
					break;
				default:
					break;
				}
				break;

			case ST_TRANSPARENT:
				if ( c == opts.escape ) {
					state = ST_COMMAND;
				} else {
					if (tty_q.len <= TTY_Q_SZ)
						tty_q.buff[tty_q.len++] = c;
					else
						fd_printf(STO, "\x07");
				}
				break;

			default:
				assert(0);
				break;
			}
		}

		if ( FD_ISSET(tty_fd, &rdset) ) {

			/* read from port */

			do {
				n = read(tty_fd, &c, 1);
			} while (n < 0 && errno == EINTR);
			if (n == 0)
				fatal("term closed");
			else if ( n < 0 )
				fatal("read from term failed: %s", strerror(errno));
			
			do {
				n = write(STO, &c, 1);
			} while ( errno == EAGAIN 
					  || errno == EWOULDBLOCK
					  || errno == EINTR );
			if ( n <= 0 )
				fatal("write to stdout failed: %s", strerror(errno));
		}

		if ( FD_ISSET(tty_fd, &wrset) ) {

			/* write to port */

			do {
				n = write(tty_fd, tty_q.buff, tty_q.len);
			} while ( n < 0 && errno == EINTR );
			if ( n <= 0 )
				fatal("write to term failed: %s", strerror(errno));
			memcpy(tty_q.buff, tty_q.buff + n, tty_q.len - n);
			tty_q.len -= n;
		}
	}
}
Beispiel #9
0
/////////////////////////////////////////////////////////////////////////////
// Main-Funktion
/////////////////////////////////////////////////////////////////////////////
int main(int argc, const char *argv[])
{

	// Initializations
	//
	// first some basic hardware infrastructure
	
	timer_init();			// Timer Interrupt initialisieren
	led_init();

	provider_init();		// needs to be in the beginning, as other
					// modules like serial register here

	term_init();			// does not need endpoint/provider yet
					// but can take up to a buffer of text


#ifdef __AVR__
	stdout = &term_stdout;          // redirect stdout
#else
	device_setup(argc, argv);
#endif

	// server communication
	uarthw_init();			// first hardware
	provider_t *serial = serial_init();	// then logic layer

	// now prepare for terminal etc
	// (note: in the future the assign parameter could be used
	// to distinguish different UARTs for example)
	void *epdata = serial->prov_assign(NAMEINFO_UNUSED_DRIVE, NULL);
	term_endpoint.provider = serial;
	term_endpoint.provdata = epdata;

	// and set as default
	provider_set_default(serial, epdata);

	// debug output via "terminal"
	term_set_endpoint(&term_endpoint);

	// init file handling (active open calls)
	file_init();
	// buffer structures
	buffer_init();
	// direct buffer handling
	direct_init();
	// relfile handling
	relfile_init();
	// init main channel handling
	channel_init();

	// before we init any busses, we init the runtime config code
	// note it gets the provider to register a listener for X command line params
	rtconfig_init(&term_endpoint);

	// bus init	
	// first the general bus (with bus counter)
	bus_init();		

	// this call initializes the device-specific hardware
	// e.g. IEEE488 and IEC busses on xs1541, plus SD card on petSD and so on
	// it also handles the interrupt initialization if necessary
	device_init();

#ifdef HAS_EEPROM
	// read bus-independent settings from non volatile memory
	nv_restore_common_config();
#endif

	// enable interrupts
	enable_interrupts();

	// sync with the server
	serial_sync();		

	// pull in command line config options from server
	// also send directory charset
	rtconfig_pullconfig(argc, argv);

#ifdef USE_FAT
	// register fat provider
	provider_register("FAT", &fat_provider);
	//provider_assign(0, "FAT", "/");		// might be overwritten when fetching X-commands
	//provider_assign(1, "FAT", "/");		// from the server, but useful for standalone-mode
#endif

	// show our version...
  	ListVersion();
	// ... and some system info
	term_printf((" %u Bytes free"), BytesFree());
	term_printf((", %d kHz"), FreqKHz());
#ifdef __AVR__
	fuse_info();
#endif
	term_putcrlf();
	term_putcrlf();


	while (1)  			// Mainloop-Begin
	{
		// keep data flowing on the serial line
		main_delay();

		if (!is_locked) 
			device_loop();

		// send out log messages
		term_flush();
	}
}
Beispiel #10
0
/*
 * update_input: does varying amount of updating on the input line depending
 * upon the position of the cursor and the update flag.  If the cursor has
 * move toward one of the edge boundaries on the screen, update_cursor()
 * flips the input line to the next (previous) line of text. The update flag
 * may be: 
 *
 * NO_UPDATE - only do the above bounds checking. 
 *
 * UPDATE_JUST_CURSOR - do bounds checking and position cursor where is should
 * be. 
 *
 * UPDATE_FROM_CURSOR - does all of the above, and makes sure everything from
 * the cursor to the right edge of the screen is current (by redrawing it). 
 *
 * UPDATE_ALL - redraws the entire line 
 */
void update_input(int update)
{
    int old_start;
    static int co = 0, li = 0;
    char *ptr;
    int len, free_it = 1, cnt, ansi_count, max;

    char *prompt;

    cursor_to_input();

    if (current_screen->promptlist)
	prompt = current_screen->promptlist->prompt;
    else
	prompt = input_prompt;
    if (prompt) {
	if (update != NO_UPDATE) {
	    char *inp_ptr = NULL;
	    int args_used;

	    if (is_process(get_target_by_refnum(0))) {
		ptr = (char *) get_prompt_by_refnum(0);
		free_it = 0;
	    } else if (!get_int_var(DISPLAY_ANSI_VAR))
		ptr = expand_alias(stripansicodes(prompt), empty_str, &args_used, NULL);
	    else
		ptr = expand_alias(prompt, empty_str, &args_used, NULL);
	    if (*ptr && ((my_strnicmp(ptr, "Password:"******"Operator Password:"******"Server Password:", 16) == 0)))
		term_echo(0);
	    else
		term_echo(1);
	    len = strlen(ptr);
	    if (strncmp(ptr, current_screen->input_buffer, len) || !len) {
		malloc_strcpy(&inp_ptr, INPUT_BUFFER + MIN_POS);
		strmcpy(INPUT_BUFFER, ptr, INPUT_BUFFER_SIZE);
		THIS_POS += (len - MIN_POS);
		MIN_POS = strlen(ptr);
		ADD_TO_INPUT(inp_ptr);
		new_free(&inp_ptr);
		update = UPDATE_ALL;
	    }

	    if (free_it)
		new_free(&ptr);
	}
    } else
	term_echo(1);

    if ((li != term_rows) || (co != term_cols)) {
	/* resized? Keep it simple and reset everything */
	input_line = term_rows - 1;
	zone = term_cols - (WIDTH * 2) + 4;
	lower_mark = WIDTH;
	upper_mark = term_cols - WIDTH;
	cursor = current_screen->buffer_min_pos;
	current_screen->buffer_pos = current_screen->buffer_min_pos;
	str_start = 0;
	li = term_rows;
	co = term_cols;
    }
    old_start = str_start;
    ansi_count = count_ansi(current_screen->input_buffer, zone);
    if (old_ansi != ansi_count || current_screen->buffer_pos - ansi_count > zone) {
	lower_mark = WIDTH;
	upper_mark = term_cols - WIDTH;
	str_start = 0;
    }
    ansi_count = count_ansi(&(current_screen->input_buffer[str_start]), zone);

    while ((current_screen->buffer_pos - ansi_count < lower_mark) && lower_mark > WIDTH) {
	upper_mark = lower_mark - ansi_count;
	lower_mark -= (zone + ansi_count);
	str_start -= (zone + ansi_count);
	if (str_start < zone) {
	    str_start = 0;
	    ansi_count = count_ansi(&(current_screen->input_buffer[str_start]), zone);
	    lower_mark -= ansi_count;
	    upper_mark -= ansi_count;
	}
    }
    while (current_screen->buffer_pos - ansi_count >= upper_mark) {
	lower_mark = upper_mark + ansi_count;
	upper_mark += zone + ansi_count;
	str_start += zone + ansi_count;
	if (ansi_count)
	    ansi_count = 0;
    }

    /* we need to count ansi characters again, this time in the part of the string we are gonna display in a few moments */
    ansi_count = count_ansi(&(current_screen->input_buffer[str_start]), zone);
    old_ansi = count_ansi(current_screen->input_buffer, zone);
    /* we need to substract number of ansi characters from cursor position since those are not visible, otherwise we'd display cursor
     * in wrong place */
    cursor = current_screen->buffer_pos - str_start - ansi_count;
    if ((old_start != str_start) || (update == UPDATE_ALL)) {
	term_move_cursor(0, input_line);
	if ((str_start == 0) && (MIN_POS > 0)) {
	    int echo;

	    echo = term_echo(1);
	    if (MIN_POS > (term_cols - WIDTH))
		len = term_cols - WIDTH - 1 /* + ansi_count */ ;
	    else
		len = MIN_POS;
	    cnt = /* term_puts */ safe_puts(&(INPUT_BUFFER[str_start]), len);
	    term_echo(echo);
	    cnt += /* term_puts */ safe_puts(&(current_screen->input_buffer[
									       str_start + len]), term_cols - len + ansi_count);
	} else
	    cnt = /* term_puts */ safe_puts(&(INPUT_BUFFER[str_start]), term_cols);
	term_clear_to_eol();
	term_move_cursor(cursor, input_line);
    } else if (update == UPDATE_FROM_CURSOR) {
	term_move_cursor(cursor, input_line);
	cnt = cursor;
	max = term_cols - (current_screen->buffer_pos - str_start) + ansi_count;
	if ((len = strlen(&(THIS_CHAR))) > max)
	    len = max;
	cnt += /* term_puts */ safe_puts(&(THIS_CHAR), len);
	term_clear_to_eol();
	term_move_cursor(cursor, input_line);
    } else if (update == UPDATE_JUST_CURSOR)
	term_move_cursor(cursor, input_line);
    term_flush();
}
Beispiel #11
0
/* Process command key. Returns non-zero if command results in picocom
   exit, zero otherwise. */
int
do_command (unsigned char c)
{
	static int dtr_up = 0;
	int newbaud, newflow, newparity, newbits, newstopbits;
	const char *xfr_cmd;
	char *fname;
	int r;

	switch (c) {
	case KEY_EXIT:
		return 1;
	case KEY_QUIT:
		term_set_hupcl(tty_fd, 0);
		term_flush(tty_fd);
		term_apply(tty_fd, 1);
		term_erase(tty_fd);
		return 1;
	case KEY_STATUS:
		show_status(dtr_up);
		break;
	case KEY_HELP:
	case KEY_KEYS:
		show_keys();
		break;
	case KEY_PULSE:
		fd_printf(STO, "\r\n*** pulse DTR ***\r\n");
		if ( term_pulse_dtr(tty_fd) < 0 )
			fd_printf(STO, "*** FAILED\r\n");
		break;
	case KEY_TOGGLE:
		if ( dtr_up )
			r = term_lower_dtr(tty_fd);
		else
			r = term_raise_dtr(tty_fd);
		if ( r >= 0 ) dtr_up = ! dtr_up;
		fd_printf(STO, "\r\n*** DTR: %s ***\r\n", 
				  dtr_up ? "up" : "down");
		break;
	case KEY_BAUD:
	case KEY_BAUD_UP:
	case KEY_BAUD_DN:
		if ( c== KEY_BAUD) {
			newbaud = read_baud();
			if ( newbaud < 0 ) {
				fd_printf(STO, "*** cannot read baudrate ***\r\n");
				break;
			}
			opts.baud = newbaud;
		} else if (c == KEY_BAUD_UP) {
			opts.baud = baud_up(opts.baud);
		} else {
			opts.baud = baud_down(opts.baud);
		}
		term_set_baudrate(tty_fd, opts.baud);
		tty_q.len = 0; term_flush(tty_fd);
		term_apply(tty_fd, 1);
		newbaud = term_get_baudrate(tty_fd, NULL);
		if ( opts.baud != newbaud ) {
			fd_printf(STO, "\r\n*** baud: %d (%d) ***\r\n", 
					  opts.baud, newbaud);
		} else {
			fd_printf(STO, "\r\n*** baud: %d ***\r\n", opts.baud);
		}
		set_tty_write_sz(newbaud);
		break;
	case KEY_FLOW:
		opts.flow = flow_next(opts.flow);
		term_set_flowcntrl(tty_fd, opts.flow);
		tty_q.len = 0; term_flush(tty_fd);
		term_apply(tty_fd, 1);
		newflow = term_get_flowcntrl(tty_fd);
		if ( opts.flow != newflow ) {
			fd_printf(STO, "\r\n*** flow: %s (%s) ***\r\n", 
					  flow_str[opts.flow], flow_str[newflow]);
		} else {
			fd_printf(STO, "\r\n*** flow: %s ***\r\n", 
					  flow_str[opts.flow]);
		}
		break;
	case KEY_PARITY:
		opts.parity = parity_next(opts.parity);
		term_set_parity(tty_fd, opts.parity);
		tty_q.len = 0; term_flush(tty_fd);
		term_apply(tty_fd, 1);
		newparity = term_get_parity(tty_fd);
		if (opts.parity != newparity ) {
			fd_printf(STO, "\r\n*** parity: %s (%s) ***\r\n",
					  parity_str[opts.parity], 
					  parity_str[newparity]);
		} else {
			fd_printf(STO, "\r\n*** parity: %s ***\r\n", 
					  parity_str[opts.parity]);
		}
		break;
	case KEY_BITS:
		opts.databits = bits_next(opts.databits);
		term_set_databits(tty_fd, opts.databits);
		tty_q.len = 0; term_flush(tty_fd);
		term_apply(tty_fd, 1);
		newbits = term_get_databits(tty_fd);
		if (opts.databits != newbits ) {
			fd_printf(STO, "\r\n*** databits: %d (%d) ***\r\n",
					  opts.databits, newbits);
		} else {
			fd_printf(STO, "\r\n*** databits: %d ***\r\n", 
					  opts.databits);
		}
		break;
	case KEY_STOP:
		opts.stopbits = stopbits_next(opts.stopbits);
		term_set_stopbits(tty_fd, opts.stopbits);
		tty_q.len = 0; term_flush(tty_fd);
		term_apply(tty_fd, 1);
		newstopbits = term_get_stopbits(tty_fd);
		if (opts.stopbits != newstopbits ) {
			fd_printf(STO, "\r\n*** stopbits: %d (%d) ***\r\n",
					  opts.stopbits, newstopbits);
		} else {
			fd_printf(STO, "\r\n*** stopbits: %d ***\r\n", 
					  opts.stopbits);
		}
		break;
	case KEY_LECHO:
		opts.lecho = ! opts.lecho;
		fd_printf(STO, "\r\n*** local echo: %s ***\r\n", 
				  opts.lecho ? "yes" : "no");
		break;
	case KEY_SEND:
	case KEY_RECEIVE:
		xfr_cmd = (c == KEY_SEND) ? opts.send_cmd : opts.receive_cmd;
		if ( xfr_cmd[0] == '\0' ) {
			fd_printf(STO, "\r\n*** command disabled ***\r\n");
			break;
		}
		fname = read_filename();
		if (fname == NULL) {
			fd_printf(STO, "*** cannot read filename ***\r\n");
			break;
		}
		run_cmd(tty_fd, xfr_cmd, fname);
		free(fname);
		break;
	case KEY_BREAK:
		term_break(tty_fd);
		fd_printf(STO, "\r\n*** break sent ***\r\n");
		break;
	default:
		break;
	}

	return 0;
}
Beispiel #12
0
void
x_draw()
{
    term_flush();
    gettimeofday(&X.last_draw, NULL);
}