int rline_resize_terminal_and_redisplay(struct rline *rline, int rows, int cols) { struct winsize size; if (!rline) return -1; size.ws_row = rows; size.ws_col = cols; size.ws_xpixel = 0; size.ws_ypixel = 0; ioctl(fileno(rline->input), TIOCSWINSZ, &size); rl_resize_terminal(); return 0; }
//------------------------------------------------------------------------------ static void simulate_sigwinch() { // In the land of POSIX a terminal would raise a SIGWINCH signal when it is // resized. See rl_sigwinch_handler() in readline/signal.c. extern int _rl_vis_botlin; extern int _rl_last_c_pos; extern int _rl_last_v_pos; CONSOLE_SCREEN_BUFFER_INFO csbi; COORD cursor_pos; HANDLE handle; int cell_count; DWORD written; handle = GetStdHandle(STD_OUTPUT_HANDLE); GetConsoleScreenBufferInfo(handle, &csbi); // If the cursor was outside of the new buffer size, conhost will move it // down one line. This needs to be accounted for to prevent artefacts. if (_rl_last_c_pos >= csbi.dwSize.X) ++_rl_last_v_pos; // Move the cursor to the prompt line cursor_pos = csbi.dwCursorPosition; cursor_pos.Y -= _rl_last_v_pos; cursor_pos.X = 0; SetConsoleCursorPosition(handle, cursor_pos); // Clear the buffer used by the line previously. cell_count = csbi.dwSize.X * (_rl_vis_botlin + 1); FillConsoleOutputCharacterW(handle, ' ', cell_count, cursor_pos, &written); FillConsoleOutputAttribute(handle, csbi.wAttributes, cell_count, cursor_pos, &written); // Tell Readline the buffer's resized. rl_resize_terminal(); }
void octave_rl_resize_terminal (void) { rl_resize_terminal (); }
static char * readline_until_enter_or_signal(const char *prompt, int *signal) { char * not_done_reading = ""; fd_set selectset; *signal = 0; #ifdef HAVE_RL_CATCH_SIGNAL rl_catch_signals = 0; #endif rl_callback_handler_install (prompt, rlhandler); FD_ZERO(&selectset); completed_input_string = not_done_reading; while (completed_input_string == not_done_reading) { int has_input = 0, err = 0; while (!has_input) { struct timeval timeout = {0, 100000}; /* 0.1 seconds */ /* [Bug #1552726] Only limit the pause if an input hook has been defined. */ struct timeval *timeoutp = NULL; if (PyOS_InputHook) timeoutp = &timeout; #ifdef HAVE_RL_RESIZE_TERMINAL /* Update readline's view of the window size after SIGWINCH */ if (sigwinch_received) { sigwinch_received = 0; rl_resize_terminal(); } #endif FD_SET(fileno(rl_instream), &selectset); /* select resets selectset if no input was available */ has_input = select(fileno(rl_instream) + 1, &selectset, NULL, NULL, timeoutp); err = errno; if(PyOS_InputHook) PyOS_InputHook(); } if (has_input > 0) { rl_callback_read_char(); } else if (err == EINTR) { int s; #ifdef WITH_THREAD PyEval_RestoreThread(_PyOS_ReadlineTState); #endif s = PyErr_CheckSignals(); #ifdef WITH_THREAD PyEval_SaveThread(); #endif if (s < 0) { rl_free_line_state(); #if defined(RL_READLINE_VERSION) && RL_READLINE_VERSION >= 0x0700 rl_callback_sigcleanup(); #endif rl_cleanup_after_signal(); rl_callback_handler_remove(); *signal = 1; completed_input_string = NULL; } } } return completed_input_string; }
//------------------------------------------------------------------------------ static void simulate_sigwinch(COORD expected_cursor_pos) { // In the land of POSIX a terminal would raise a SIGWINCH signal when it is // resized. See rl_sigwinch_handler() in readline/signal.c. extern int _rl_vis_botlin; extern int _rl_last_v_pos; CONSOLE_SCREEN_BUFFER_INFO csbi; rl_voidfunc_t* redisplay_func_cache; int base_y; int bottom_line; HANDLE handle; bottom_line = _rl_vis_botlin - 1; handle = GetStdHandle(STD_OUTPUT_HANDLE); // Cache redisplay function. Need original as it handles redraw correctly. redisplay_func_cache = rl_redisplay_function; rl_redisplay_function = rl_redisplay; // Cursor may be out of sync with where Readline expects the cursor to be. // Put it back where it was, clamping if necessary. GetConsoleScreenBufferInfo(handle, &csbi); if (expected_cursor_pos.X >= csbi.dwSize.X) { expected_cursor_pos.X = csbi.dwSize.X - 1; } if (expected_cursor_pos.Y >= csbi.dwSize.Y) { expected_cursor_pos.Y = csbi.dwSize.Y - 1; } SetConsoleCursorPosition(handle, expected_cursor_pos); // Let Readline handle the buffer resize. RL_SETSTATE(RL_STATE_SIGHANDLER); rl_resize_terminal(); RL_UNSETSTATE(RL_STATE_SIGHANDLER); rl_redisplay_function = redisplay_func_cache; // Now some redraw edge cases need to be handled. GetConsoleScreenBufferInfo(handle, &csbi); base_y = csbi.dwCursorPosition.Y - _rl_last_v_pos; if (bottom_line > _rl_vis_botlin) { // Readline SIGWINCH handling assumes that at most one line needs to // be cleared which is not the case when resizing from small to large // widths. CHAR_INFO fill; SMALL_RECT rect; COORD coord; rect.Left = 0; rect.Right = csbi.dwSize.X; rect.Top = base_y + _rl_vis_botlin + 1; rect.Bottom = base_y + bottom_line; fill.Char.AsciiChar = ' '; fill.Attributes = csbi.wAttributes; coord.X = rect.Right + 1; coord.Y = rect.Top; ScrollConsoleScreenBuffer(handle, &rect, NULL, coord, &fill); } else { // Readline never writes to the last column as it wraps the cursor. The // last column will have noise when making the width smaller. Clear it. CHAR_INFO fill; SMALL_RECT rect; COORD coord; rect.Left = rect.Right = csbi.dwSize.X - 1; rect.Top = base_y; rect.Bottom = base_y + _rl_vis_botlin; fill.Char.AsciiChar = ' '; fill.Attributes = csbi.wAttributes; coord.X = rect.Right + 1; coord.Y = rect.Top; ScrollConsoleScreenBuffer(handle, &rect, NULL, coord, &fill); } }