Commit 2724b1806a63d66148cea62e1fe1cae3b417bc7e
1 parent
731b0364
monitor: Improve mux'ed console experience (Jan Kiszka)
Up to now, you never really knew if you already switched the console after pressing CTRL-A C or if you mistyped it again. This patch clarifies the situation by providing a prompt in a new line and injecting a linebreak when switching away again. For this purpose, the two events CHR_EVENT_MUX_IN and CHR_EVENT_MUX_OUT are introduced and distributed on focus switches. Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com> Signed-off-by: Anthony Liguori <aliguori@us.ibm.com> git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@6716 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
5 changed files
with
42 additions
and
10 deletions
monitor.c
| @@ -2918,12 +2918,27 @@ static void monitor_event(void *opaque, int event) | @@ -2918,12 +2918,27 @@ static void monitor_event(void *opaque, int event) | ||
| 2918 | { | 2918 | { |
| 2919 | Monitor *mon = opaque; | 2919 | Monitor *mon = opaque; |
| 2920 | 2920 | ||
| 2921 | - if (event != CHR_EVENT_RESET) | ||
| 2922 | - return; | 2921 | + switch (event) { |
| 2922 | + case CHR_EVENT_MUX_IN: | ||
| 2923 | + readline_restart(mon->rs); | ||
| 2924 | + monitor_resume(mon); | ||
| 2925 | + monitor_flush(mon); | ||
| 2926 | + break; | ||
| 2927 | + | ||
| 2928 | + case CHR_EVENT_MUX_OUT: | ||
| 2929 | + if (mon->suspend_cnt == 0) | ||
| 2930 | + monitor_printf(mon, "\n"); | ||
| 2931 | + monitor_flush(mon); | ||
| 2932 | + monitor_suspend(mon); | ||
| 2933 | + break; | ||
| 2923 | 2934 | ||
| 2924 | - monitor_printf(mon, "QEMU %s monitor - type 'help' for more information\n", | ||
| 2925 | - QEMU_VERSION); | ||
| 2926 | - readline_show_prompt(mon->rs); | 2935 | + case CHR_EVENT_RESET: |
| 2936 | + monitor_printf(mon, "QEMU %s monitor - type 'help' for more " | ||
| 2937 | + "information\n", QEMU_VERSION); | ||
| 2938 | + if (mon->chr->focus == 0) | ||
| 2939 | + readline_show_prompt(mon->rs); | ||
| 2940 | + break; | ||
| 2941 | + } | ||
| 2927 | } | 2942 | } |
| 2928 | 2943 | ||
| 2929 | void monitor_init(CharDriverState *chr, int flags) | 2944 | void monitor_init(CharDriverState *chr, int flags) |
| @@ -2940,6 +2955,8 @@ void monitor_init(CharDriverState *chr, int flags) | @@ -2940,6 +2955,8 @@ void monitor_init(CharDriverState *chr, int flags) | ||
| 2940 | 2955 | ||
| 2941 | mon->chr = chr; | 2956 | mon->chr = chr; |
| 2942 | mon->flags = flags; | 2957 | mon->flags = flags; |
| 2958 | + if (mon->chr->focus != 0) | ||
| 2959 | + mon->suspend_cnt = 1; /* mux'ed monitors start suspended */ | ||
| 2943 | mon->rs = readline_init(mon, monitor_find_completion); | 2960 | mon->rs = readline_init(mon, monitor_find_completion); |
| 2944 | monitor_read_command(mon, 0); | 2961 | monitor_read_command(mon, 0); |
| 2945 | 2962 |
qemu-char.c
| @@ -310,6 +310,12 @@ static void mux_print_help(CharDriverState *chr) | @@ -310,6 +310,12 @@ static void mux_print_help(CharDriverState *chr) | ||
| 310 | } | 310 | } |
| 311 | } | 311 | } |
| 312 | 312 | ||
| 313 | +static void mux_chr_send_event(MuxDriver *d, int mux_nr, int event) | ||
| 314 | +{ | ||
| 315 | + if (d->chr_event[mux_nr]) | ||
| 316 | + d->chr_event[mux_nr](d->ext_opaque[mux_nr], event); | ||
| 317 | +} | ||
| 318 | + | ||
| 313 | static int mux_proc_byte(CharDriverState *chr, MuxDriver *d, int ch) | 319 | static int mux_proc_byte(CharDriverState *chr, MuxDriver *d, int ch) |
| 314 | { | 320 | { |
| 315 | if (d->term_got_escape) { | 321 | if (d->term_got_escape) { |
| @@ -341,9 +347,11 @@ static int mux_proc_byte(CharDriverState *chr, MuxDriver *d, int ch) | @@ -341,9 +347,11 @@ static int mux_proc_byte(CharDriverState *chr, MuxDriver *d, int ch) | ||
| 341 | break; | 347 | break; |
| 342 | case 'c': | 348 | case 'c': |
| 343 | /* Switch to the next registered device */ | 349 | /* Switch to the next registered device */ |
| 350 | + mux_chr_send_event(d, chr->focus, CHR_EVENT_MUX_OUT); | ||
| 344 | chr->focus++; | 351 | chr->focus++; |
| 345 | if (chr->focus >= d->mux_cnt) | 352 | if (chr->focus >= d->mux_cnt) |
| 346 | chr->focus = 0; | 353 | chr->focus = 0; |
| 354 | + mux_chr_send_event(d, chr->focus, CHR_EVENT_MUX_IN); | ||
| 347 | break; | 355 | break; |
| 348 | case 't': | 356 | case 't': |
| 349 | term_timestamps = !term_timestamps; | 357 | term_timestamps = !term_timestamps; |
| @@ -413,8 +421,7 @@ static void mux_chr_event(void *opaque, int event) | @@ -413,8 +421,7 @@ static void mux_chr_event(void *opaque, int event) | ||
| 413 | 421 | ||
| 414 | /* Send the event to all registered listeners */ | 422 | /* Send the event to all registered listeners */ |
| 415 | for (i = 0; i < d->mux_cnt; i++) | 423 | for (i = 0; i < d->mux_cnt; i++) |
| 416 | - if (d->chr_event[i]) | ||
| 417 | - d->chr_event[i](d->ext_opaque[i], event); | 424 | + mux_chr_send_event(d, i, event); |
| 418 | } | 425 | } |
| 419 | 426 | ||
| 420 | static void mux_chr_update_read_handler(CharDriverState *chr) | 427 | static void mux_chr_update_read_handler(CharDriverState *chr) |
qemu-char.h
| @@ -6,9 +6,11 @@ | @@ -6,9 +6,11 @@ | ||
| 6 | 6 | ||
| 7 | /* character device */ | 7 | /* character device */ |
| 8 | 8 | ||
| 9 | -#define CHR_EVENT_BREAK 0 /* serial break char */ | ||
| 10 | -#define CHR_EVENT_FOCUS 1 /* focus to this terminal (modal input needed) */ | ||
| 11 | -#define CHR_EVENT_RESET 2 /* new connection established */ | 9 | +#define CHR_EVENT_BREAK 0 /* serial break char */ |
| 10 | +#define CHR_EVENT_FOCUS 1 /* focus to this terminal (modal input needed) */ | ||
| 11 | +#define CHR_EVENT_RESET 2 /* new connection established */ | ||
| 12 | +#define CHR_EVENT_MUX_IN 3 /* mux-focus was set to this terminal */ | ||
| 13 | +#define CHR_EVENT_MUX_OUT 4 /* mux-focus will move on */ | ||
| 12 | 14 | ||
| 13 | 15 | ||
| 14 | #define CHR_IOCTL_SERIAL_SET_PARAMS 1 | 16 | #define CHR_IOCTL_SERIAL_SET_PARAMS 1 |
readline.c
| @@ -444,6 +444,11 @@ void readline_start(ReadLineState *rs, const char *prompt, int read_password, | @@ -444,6 +444,11 @@ void readline_start(ReadLineState *rs, const char *prompt, int read_password, | ||
| 444 | rs->readline_func = readline_func; | 444 | rs->readline_func = readline_func; |
| 445 | rs->readline_opaque = opaque; | 445 | rs->readline_opaque = opaque; |
| 446 | rs->read_password = read_password; | 446 | rs->read_password = read_password; |
| 447 | + readline_restart(rs); | ||
| 448 | +} | ||
| 449 | + | ||
| 450 | +void readline_restart(ReadLineState *rs) | ||
| 451 | +{ | ||
| 447 | rs->cmd_buf_index = 0; | 452 | rs->cmd_buf_index = 0; |
| 448 | rs->cmd_buf_size = 0; | 453 | rs->cmd_buf_size = 0; |
| 449 | } | 454 | } |
readline.h
| @@ -46,6 +46,7 @@ void readline_handle_byte(ReadLineState *rs, int ch); | @@ -46,6 +46,7 @@ void readline_handle_byte(ReadLineState *rs, int ch); | ||
| 46 | 46 | ||
| 47 | void readline_start(ReadLineState *rs, const char *prompt, int read_password, | 47 | void readline_start(ReadLineState *rs, const char *prompt, int read_password, |
| 48 | ReadLineFunc *readline_func, void *opaque); | 48 | ReadLineFunc *readline_func, void *opaque); |
| 49 | +void readline_restart(ReadLineState *rs); | ||
| 49 | void readline_show_prompt(ReadLineState *rs); | 50 | void readline_show_prompt(ReadLineState *rs); |
| 50 | 51 | ||
| 51 | ReadLineState *readline_init(Monitor *mon, | 52 | ReadLineState *readline_init(Monitor *mon, |