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; }
/* * 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(); }
/* 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); }
/* 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(); } }
/* 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(); }
/* * 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; }
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; } } }
///////////////////////////////////////////////////////////////////////////// // 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(); } }
/* * 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(); }
/* 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; }
void x_draw() { term_flush(); gettimeofday(&X.last_draw, NULL); }