/* FIXME: add comment: */ int ATTRIBUTE_CONST key_is_command_char(int ch) { return ((ch == KEY_NPAGE) || (ch == KEY_PPAGE) || (ch == KEY_LEFT) || (ch == KEY_RIGHT) || (ch == KEY_UP) || (ch == KEY_DOWN) || (ch == KEY_SF) || (ch == KEY_SR) || (ch == (int)'\f') || key_is_start_sequence(ch)); }
/* Dispatch the correct tui function based upon the control character. */ unsigned int tui_dispatch_ctrl_char (unsigned int ch) { struct tui_win_info *win_info = tui_win_with_focus (); /* Handle the CTRL-L refresh for each window. */ if (ch == '\f') tui_refresh_all_win (); /* If the command window has the logical focus, or no-one does assume it is the command window; in this case, pass the character on through and do nothing here. */ if (win_info == NULL || win_info == TUI_CMD_WIN) return ch; else { unsigned int c = 0, ch_copy = ch; int i; char *term; /* If this is an xterm, page next/prev keys aren't returned by keypad as a single char, so we must handle them here. Seems like a bug in the curses library? */ term = (char *) getenv ("TERM"); if (term) { for (i = 0; term[i]; i++) term[i] = toupper (term[i]); if ((strcmp (term, "XTERM") == 0) && key_is_start_sequence (ch)) { unsigned int page_ch = 0; unsigned int tmp_char; WINDOW *w = TUI_CMD_WIN->generic.handle; tmp_char = 0; while (!key_is_end_sequence (tmp_char)) { tmp_char = (int) wgetch (w); if (tmp_char == ERR) { return ch; } if (!tmp_char) break; if (tmp_char == 53) page_ch = KEY_PPAGE; else if (tmp_char == 54) page_ch = KEY_NPAGE; else { return 0; } } ch_copy = page_ch; } } switch (ch_copy) { case KEY_NPAGE: tui_scroll_forward (win_info, 0); break; case KEY_PPAGE: tui_scroll_backward (win_info, 0); break; case KEY_DOWN: case KEY_SF: tui_scroll_forward (win_info, 1); break; case KEY_UP: case KEY_SR: tui_scroll_backward (win_info, 1); break; case KEY_RIGHT: tui_scroll_left (win_info, 1); break; case KEY_LEFT: tui_scroll_right (win_info, 1); break; case '\f': break; default: c = ch_copy; break; } return c; } }
/* Get a character from the command window. This is called from the readline package. */ int tui_getc (FILE *fp) { int ch; WINDOW *w; w = TUI_CMD_WIN->generic.handle; #ifdef TUI_USE_PIPE_FOR_READLINE /* Flush readline output. */ tui_readline_output (0, 0); #endif ch = wgetch (w); /* The \n must be echoed because it will not be printed by readline. */ if (ch == '\n') { /* When hitting return with an empty input, gdb executes the last command. If we emit a newline, this fills up the command window with empty lines with gdb prompt at beginning. Instead of that, stay on the same line but provide a visual effect to show the user we recognized the command. */ if (rl_end == 0 && !gdb_in_secondary_prompt_p (current_ui)) { wmove (w, getcury (w), 0); /* Clear the line. This will blink the gdb prompt since it will be redrawn at the same line. */ wclrtoeol (w); wrefresh (w); napms (20); } else { /* Move cursor to the end of the command line before emitting the newline. We need to do so because when ncurses outputs a newline it truncates any text that appears past the end of the cursor. */ int px, py; getyx (w, py, px); px += rl_end - rl_point; py += px / TUI_CMD_WIN->generic.width; px %= TUI_CMD_WIN->generic.width; wmove (w, py, px); tui_putc ('\n'); } } /* Handle prev/next/up/down here. */ ch = tui_dispatch_ctrl_char (ch); if (ch == KEY_BACKSPACE) return '\b'; if (current_ui->command_editing && key_is_start_sequence (ch)) { int ch_pending; nodelay (w, TRUE); ch_pending = wgetch (w); nodelay (w, FALSE); /* If we have pending input following a start sequence, call the stdin event handler again because ncurses may have already read and stored the input into its internal buffer, meaning that we won't get an stdin event for it. If we don't compensate for this missed stdin event, key sequences as Alt_F (^[f) will not behave promptly. (We only compensates for the missed 2nd byte of a key sequence because 2-byte sequences are by far the most commonly used. ncurses may have buffered a larger, 3+-byte key sequence though it remains to be seen whether it is useful to compensate for all the bytes of such sequences.) */ if (ch_pending != ERR) { ungetch (ch_pending); call_stdin_event_handler_again_p = 1; } } return ch; }
/* Get a character from the command window. This is called from the readline package. */ int tui_getc (FILE *fp) { int ch; WINDOW *w; w = TUI_CMD_WIN->generic.handle; #ifdef TUI_USE_PIPE_FOR_READLINE /* Flush readline output. */ tui_readline_output (0, 0); #endif ch = wgetch (w); ch = tui_handle_resize_during_io (ch); /* The \n must be echoed because it will not be printed by readline. */ if (ch == '\n') { /* When hitting return with an empty input, gdb executes the last command. If we emit a newline, this fills up the command window with empty lines with gdb prompt at beginning. Instead of that, stay on the same line but provide a visual effect to show the user we recognized the command. */ if (rl_end == 0) { wmove (w, TUI_CMD_WIN->detail.command_info.cur_line, 0); /* Clear the line. This will blink the gdb prompt since it will be redrawn at the same line. */ wclrtoeol (w); wrefresh (w); napms (20); } else { wmove (w, TUI_CMD_WIN->detail.command_info.cur_line, TUI_CMD_WIN->detail.command_info.curch); waddch (w, ch); } } if (key_is_command_char (ch)) { /* Handle prev/next/up/down here. */ ch = tui_dispatch_ctrl_char (ch); } if (ch == '\n' || ch == '\r' || ch == '\f') TUI_CMD_WIN->detail.command_info.curch = 0; if (ch == KEY_BACKSPACE) return '\b'; if (async_command_editing_p && key_is_start_sequence (ch)) { int ch_pending; nodelay (w, TRUE); ch_pending = wgetch (w); nodelay (w, FALSE); /* If we have pending input following a start sequence, call the stdin event handler again because ncurses may have already read and stored the input into its internal buffer, meaning that we won't get an stdin event for it. If we don't compensate for this missed stdin event, key sequences as Alt_F (^[f) will not behave promptly. (We only compensates for the missed 2nd byte of a key sequence because 2-byte sequences are by far the most commonly used. ncurses may have buffered a larger, 3+-byte key sequence though it remains to be seen whether it is useful to compensate for all the bytes of such sequences.) */ if (ch_pending != ERR) { ungetch (ch_pending); call_stdin_event_handler_again_p = 1; } } return ch; }