/* 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(); } }
static void input_delete_char_from_screen (void) { /* * Remove the current character from the screen's display. * * If we cannot do a character delete then we do a wholesale * redraw of the input line (ugh). */ if (!(termfeatures & TERM_CAN_DELETE)) update_input(UPDATE_FROM_CURSOR); else { int pos; /* * Delete the character. This is the simple part. */ term_delete(1); /* * So right now we have a blank space at the right of the * screen. If there is a character in the input buffer that * is out in that position, we need to find it and display it. */ if (INPUT_ONSCREEN == 0) /* UGH! */ pos = last_input_screen->co - INPUT_PROMPT_LEN - 1; else pos = INPUT_ONSCREEN + last_input_screen->co - 1; if (pos < (int)strlen(INPUT_BUFFER)) { term_move_cursor(last_input_screen->co - 1, INPUT_LINE); term_putchar(INPUT_BUFFER[pos]); term_move_cursor(INPUT_CURSOR, INPUT_LINE); cursor_not_in_display(last_input_screen); } /* XXX - Very possibly, this is pointless */ update_input(NO_UPDATE); } }
/* 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_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; }