diff options
Diffstat (limited to 'gdb')
-rw-r--r-- | gdb/ChangeLog | 9 | ||||
-rw-r--r-- | gdb/event-top.c | 13 | ||||
-rw-r--r-- | gdb/event-top.h | 1 | ||||
-rw-r--r-- | gdb/tui/tui-io.c | 28 |
4 files changed, 49 insertions, 2 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog index e16f28f..326a0d6 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,5 +1,14 @@ 2014-11-23 Patrick Palka <patrick@parcs.ath.cx> + * event-top.h (call_stdin_event_handler_again_p): Declare. + * event-top.c (call_stdin_event_handler_again_p): Define. + (stdin_event_handler): Use it. + * tui/tui-io.c (tui_getc): Prepare to call the stdin event + handler again if there is pending input following a + start sequence. + +2014-11-23 Patrick Palka <patrick@parcs.ath.cx> + Pushed by Joel Brobecker <brobecker@adacore.com> * linux-fork.c (checkpoint_command): Print index of new checkpoint in response message. diff --git a/gdb/event-top.c b/gdb/event-top.c index 282c0fe..cb438ac 100644 --- a/gdb/event-top.c +++ b/gdb/event-top.c @@ -119,6 +119,11 @@ int exec_done_display_p = 0; read commands from. */ int input_fd; +/* Used by the stdin event handler to compensate for missed stdin events. + Setting this to a non-zero value inside an stdin callback makes the callback + run again. */ +int call_stdin_event_handler_again_p; + /* Signal handling variables. */ /* Each of these is a pointer to a function that the event loop will invoke if the corresponding signal has received. The real signal @@ -420,7 +425,13 @@ stdin_event_handler (int error, gdb_client_data client_data) quit_command ((char *) 0, stdin == instream); } else - (*call_readline) (client_data); + { + do + { + call_stdin_event_handler_again_p = 0; + (*call_readline) (client_data); + } while (call_stdin_event_handler_again_p != 0); + } } /* Re-enable stdin after the end of an execution command in diff --git a/gdb/event-top.h b/gdb/event-top.h index ac0d47b..919287e 100644 --- a/gdb/event-top.h +++ b/gdb/event-top.h @@ -61,6 +61,7 @@ extern void (*call_readline) (void *); extern void (*input_handler) (char *); extern int input_fd; extern void (*after_char_processing_hook) (void); +extern int call_stdin_event_handler_again_p; /* Wrappers for rl_callback_handler_remove and rl_callback_handler_install that keep track of whether the callback diff --git a/gdb/tui/tui-io.c b/gdb/tui/tui-io.c index 601d278..aa1d1c7 100644 --- a/gdb/tui/tui-io.c +++ b/gdb/tui/tui-io.c @@ -691,7 +691,33 @@ tui_getc (FILE *fp) 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; } |