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 | 2918 | { |
2919 | 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 | 2944 | void monitor_init(CharDriverState *chr, int flags) |
... | ... | @@ -2940,6 +2955,8 @@ void monitor_init(CharDriverState *chr, int flags) |
2940 | 2955 | |
2941 | 2956 | mon->chr = chr; |
2942 | 2957 | mon->flags = flags; |
2958 | + if (mon->chr->focus != 0) | |
2959 | + mon->suspend_cnt = 1; /* mux'ed monitors start suspended */ | |
2943 | 2960 | mon->rs = readline_init(mon, monitor_find_completion); |
2944 | 2961 | monitor_read_command(mon, 0); |
2945 | 2962 | ... | ... |
qemu-char.c
... | ... | @@ -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 | 319 | static int mux_proc_byte(CharDriverState *chr, MuxDriver *d, int ch) |
314 | 320 | { |
315 | 321 | if (d->term_got_escape) { |
... | ... | @@ -341,9 +347,11 @@ static int mux_proc_byte(CharDriverState *chr, MuxDriver *d, int ch) |
341 | 347 | break; |
342 | 348 | case 'c': |
343 | 349 | /* Switch to the next registered device */ |
350 | + mux_chr_send_event(d, chr->focus, CHR_EVENT_MUX_OUT); | |
344 | 351 | chr->focus++; |
345 | 352 | if (chr->focus >= d->mux_cnt) |
346 | 353 | chr->focus = 0; |
354 | + mux_chr_send_event(d, chr->focus, CHR_EVENT_MUX_IN); | |
347 | 355 | break; |
348 | 356 | case 't': |
349 | 357 | term_timestamps = !term_timestamps; |
... | ... | @@ -413,8 +421,7 @@ static void mux_chr_event(void *opaque, int event) |
413 | 421 | |
414 | 422 | /* Send the event to all registered listeners */ |
415 | 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 | 427 | static void mux_chr_update_read_handler(CharDriverState *chr) | ... | ... |
qemu-char.h
... | ... | @@ -6,9 +6,11 @@ |
6 | 6 | |
7 | 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 | 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 | 444 | rs->readline_func = readline_func; |
445 | 445 | rs->readline_opaque = opaque; |
446 | 446 | rs->read_password = read_password; |
447 | + readline_restart(rs); | |
448 | +} | |
449 | + | |
450 | +void readline_restart(ReadLineState *rs) | |
451 | +{ | |
447 | 452 | rs->cmd_buf_index = 0; |
448 | 453 | rs->cmd_buf_size = 0; |
449 | 454 | } | ... | ... |
readline.h
... | ... | @@ -46,6 +46,7 @@ void readline_handle_byte(ReadLineState *rs, int ch); |
46 | 46 | |
47 | 47 | void readline_start(ReadLineState *rs, const char *prompt, int read_password, |
48 | 48 | ReadLineFunc *readline_func, void *opaque); |
49 | +void readline_restart(ReadLineState *rs); | |
49 | 50 | void readline_show_prompt(ReadLineState *rs); |
50 | 51 | |
51 | 52 | ReadLineState *readline_init(Monitor *mon, | ... | ... |