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, |