From 71172ed97cd4cd45c6ae70e594ba351798d11909 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Tue, 25 Oct 2011 13:45:16 -0200 Subject: perf ui: Improve handling sigwinch a bit No need to unblock it at each ui__getch() and also allow other users to check if a resize is needed, or force an refresh of terminal dimensions. The 'force' one shouldn't be needed, but its in a slow path, so leave it like that for now, I'll revisit this another day. Cc: David Ahern Cc: Frederic Weisbecker Cc: Mike Galbraith Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Stephane Eranian Link: http://lkml.kernel.org/n/tip-aujchu6yx3bfy64non1rky0w@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/ui/util.h | 1 + 1 file changed, 1 insertion(+) (limited to 'tools/perf/util/ui/util.h') diff --git a/tools/perf/util/ui/util.h b/tools/perf/util/ui/util.h index afcbc1d99531..e53c3d334903 100644 --- a/tools/perf/util/ui/util.h +++ b/tools/perf/util/ui/util.h @@ -3,6 +3,7 @@ #include +int ui__getch(int delay_secs); int ui__popup_menu(int argc, char * const argv[]); int ui__help_window(const char *text); bool ui__dialog_yesno(const char *msg); -- cgit v1.2.3 From ae55795ef2d9ba71d46e4111b87a4d0cde93abea Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Wed, 26 Oct 2011 08:00:55 -0200 Subject: perf ui: Reimplement the popup windows using libslang Just another step in stopping the use of libnewt in perf. Cc: David Ahern Cc: Frederic Weisbecker Cc: Mike Galbraith Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Stephane Eranian Link: http://lkml.kernel.org/n/tip-vtxnmz1t1807ykprapnk9njl@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/annotate.c | 9 ++- tools/perf/util/debug.h | 1 + tools/perf/util/ui/browsers/annotate.c | 14 ++--- tools/perf/util/ui/setup.c | 8 +-- tools/perf/util/ui/util.c | 110 ++++++++++++++++++--------------- tools/perf/util/ui/util.h | 2 + 6 files changed, 77 insertions(+), 67 deletions(-) (limited to 'tools/perf/util/ui/util.h') diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c index bc8f4773d4d8..119e996035c8 100644 --- a/tools/perf/util/annotate.c +++ b/tools/perf/util/annotate.c @@ -310,9 +310,12 @@ fallback: } err = -ENOENT; dso->annotate_warned = 1; - pr_err("Can't annotate %s: No vmlinux file%s was found in the " - "path.\nPlease use 'perf buildid-cache -av vmlinux' or " - "--vmlinux vmlinux.\n", + pr_err("Can't annotate %s:\n\n" + "No vmlinux file%s\nwas found in the path.\n\n" + "Please use:\n\n" + " perf buildid-cache -av vmlinux\n\n" + "or:\n\n" + " --vmlinux vmlinux", sym->name, build_id_msg ?: ""); goto out_free_filename; } diff --git a/tools/perf/util/debug.h b/tools/perf/util/debug.h index 510adaccba84..9c59b9551ada 100644 --- a/tools/perf/util/debug.h +++ b/tools/perf/util/debug.h @@ -29,5 +29,6 @@ int ui_helpline__show_help(const char *format, va_list ap); void ui__warning(const char *format, ...) __attribute__((format(printf, 1, 2))); void ui__warning_paranoid(void); +void ui__error(const char *format, ...) __attribute__((format(printf, 1, 2))); #endif /* __PERF_DEBUG_H */ diff --git a/tools/perf/util/ui/browsers/annotate.c b/tools/perf/util/ui/browsers/annotate.c index 4e0cb7fea7d9..0575905d1205 100644 --- a/tools/perf/util/ui/browsers/annotate.c +++ b/tools/perf/util/ui/browsers/annotate.c @@ -1,6 +1,9 @@ +#include "../../util.h" #include "../browser.h" #include "../helpline.h" #include "../libslang.h" +#include "../ui.h" +#include "../util.h" #include "../../annotate.h" #include "../../hist.h" #include "../../sort.h" @@ -8,15 +11,6 @@ #include #include -static void ui__error_window(const char *fmt, ...) -{ - va_list ap; - - va_start(ap, fmt); - newtWinMessagev((char *)"Error", (char *)"Ok", (char *)fmt, ap); - va_end(ap); -} - struct annotate_browser { struct ui_browser b; struct rb_root entries; @@ -400,7 +394,7 @@ int symbol__tui_annotate(struct symbol *sym, struct map *map, int evidx, return -1; if (symbol__annotate(sym, map, sizeof(struct objdump_line_rb_node)) < 0) { - ui__error_window(ui_helpline__last_msg); + ui__error("%s", ui_helpline__last_msg); return -1; } diff --git a/tools/perf/util/ui/setup.c b/tools/perf/util/ui/setup.c index c4e025fbd6b9..85a69faa09aa 100644 --- a/tools/perf/util/ui/setup.c +++ b/tools/perf/util/ui/setup.c @@ -146,10 +146,10 @@ void setup_browser(bool fallback_to_pager) void exit_browser(bool wait_for_ok) { if (use_browser > 0) { - if (wait_for_ok) { - char title[] = "Fatal Error", ok[] = "Ok"; - newtWinMessage(title, ok, ui_helpline__last_msg); - } + if (wait_for_ok) + ui__question_window("Fatal Error", + ui_helpline__last_msg, + "Press any key...", 0); ui__exit(); } } diff --git a/tools/perf/util/ui/util.c b/tools/perf/util/ui/util.c index 37e6fe081a58..ef9b79332fe8 100644 --- a/tools/perf/util/ui/util.c +++ b/tools/perf/util/ui/util.c @@ -1,6 +1,5 @@ -#include +#include "../util.h" #include -#include #include #include #include @@ -12,6 +11,7 @@ #include "helpline.h" #include "ui.h" #include "util.h" +#include "libslang.h" static void ui_browser__argv_write(struct ui_browser *browser, void *entry, int row) @@ -56,23 +56,6 @@ static int popup_menu__run(struct ui_browser *menu) return key; } -static void newt_form__set_exit_keys(newtComponent self) -{ - newtFormAddHotKey(self, NEWT_KEY_LEFT); - newtFormAddHotKey(self, NEWT_KEY_ESCAPE); - newtFormAddHotKey(self, 'Q'); - newtFormAddHotKey(self, 'q'); - newtFormAddHotKey(self, CTRL('c')); -} - -static newtComponent newt_form__new(void) -{ - newtComponent self = newtForm(NULL, NULL, 0); - if (self) - newt_form__set_exit_keys(self); - return self; -} - int ui__popup_menu(int argc, char * const argv[]) { struct ui_browser menu = { @@ -86,17 +69,13 @@ int ui__popup_menu(int argc, char * const argv[]) return popup_menu__run(&menu); } -int ui__help_window(const char *text) +int ui__question_window(const char *title, const char *text, + const char *exit_msg, int delay_secs) { - struct newtExitStruct es; - newtComponent tb, form = newt_form__new(); - int rc = -1; + int x, y; int max_len = 0, nr_lines = 0; const char *t; - if (form == NULL) - return -1; - t = text; while (1) { const char *sep = strchr(t, '\n'); @@ -113,28 +92,56 @@ int ui__help_window(const char *text) t = sep + 1; } - tb = newtTextbox(0, 0, max_len, nr_lines, 0); - if (tb == NULL) - goto out_destroy_form; - - newtTextboxSetText(tb, text); - newtFormAddComponent(form, tb); - newtCenteredWindow(max_len, nr_lines, NULL); - newtFormRun(form, &es); - newtPopWindow(); - rc = 0; -out_destroy_form: - newtFormDestroy(form); - return rc; + max_len += 2; + nr_lines += 4; + y = SLtt_Screen_Rows / 2 - nr_lines / 2, + x = SLtt_Screen_Cols / 2 - max_len / 2; + + SLsmg_set_color(0); + SLsmg_draw_box(y, x++, nr_lines, max_len); + if (title) { + SLsmg_gotorc(y, x + 1); + SLsmg_write_string((char *)title); + } + SLsmg_gotorc(++y, x); + nr_lines -= 2; + max_len -= 2; + SLsmg_write_wrapped_string((unsigned char *)text, y, x, + nr_lines, max_len, 1); + SLsmg_gotorc(y + nr_lines - 2, x); + SLsmg_write_nstring((char *)" ", max_len); + SLsmg_gotorc(y + nr_lines - 1, x); + SLsmg_write_nstring((char *)exit_msg, max_len); + SLsmg_refresh(); + return ui__getch(delay_secs); } -static const char yes[] = "Yes", no[] = "No", - warning_str[] = "Warning!", ok[] = "Ok"; +int ui__help_window(const char *text) +{ + return ui__question_window("Help", text, "Press any key...", 0); +} bool ui__dialog_yesno(const char *msg) { - /* newtWinChoice should really be accepting const char pointers... */ - return newtWinChoice(NULL, (char *)yes, (char *)no, (char *)msg) == 1; + int answer = ui__question_window(NULL, msg, "Enter: Yes, ESC: No", 0); + + return answer == K_ENTER; +} + +static void __ui__warning(const char *title, const char *format, va_list args) +{ + char *s; + + if (use_browser > 0 && vasprintf(&s, format, args) > 0) { + pthread_mutex_lock(&ui__lock); + ui__question_window(title, s, "Press any key...", 0); + pthread_mutex_unlock(&ui__lock); + free(s); + return; + } + + fprintf(stderr, "%s:\n", title); + vfprintf(stderr, format, args); } void ui__warning(const char *format, ...) @@ -142,12 +149,15 @@ void ui__warning(const char *format, ...) va_list args; va_start(args, format); - if (use_browser > 0) { - pthread_mutex_lock(&ui__lock); - newtWinMessagev((char *)warning_str, (char *)ok, - (char *)format, args); - pthread_mutex_unlock(&ui__lock); - } else - vfprintf(stderr, format, args); + __ui__warning("Warning", format, args); + va_end(args); +} + +void ui__error(const char *format, ...) +{ + va_list args; + + va_start(args, format); + __ui__warning("Error", format, args); va_end(args); } diff --git a/tools/perf/util/ui/util.h b/tools/perf/util/ui/util.h index e53c3d334903..9a25538d4735 100644 --- a/tools/perf/util/ui/util.h +++ b/tools/perf/util/ui/util.h @@ -7,5 +7,7 @@ int ui__getch(int delay_secs); int ui__popup_menu(int argc, char * const argv[]); int ui__help_window(const char *text); bool ui__dialog_yesno(const char *msg); +int ui__question_window(const char *title, const char *text, + const char *exit_msg, int delay_secs); #endif /* _PERF_UI_UTIL_H_ */ -- cgit v1.2.3 From 4610e4137b5fb93042a248928a2c0049ef7d4190 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Wed, 26 Oct 2011 12:04:37 -0200 Subject: perf ui browser: Handle K_RESIZE in dialog windows Just provide wrappers for things like ui__warning, ui__dialog_yesno and if they return K_RESIZE, refresh dimensions, redraw the entries, etc. Cc: David Ahern Cc: Frederic Weisbecker Cc: Mike Galbraith Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Stephane Eranian Link: http://lkml.kernel.org/n/tip-3ih7hyk9weryxaxb501sfq4u@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/debug.c | 7 ++++--- tools/perf/util/debug.h | 6 +++--- tools/perf/util/ui/browser.c | 40 +++++++++++++++++++++++++++++++++++++ tools/perf/util/ui/browser.h | 5 +++++ tools/perf/util/ui/browsers/hists.c | 22 +++++++++++++------- tools/perf/util/ui/helpline.c | 6 ++++++ tools/perf/util/ui/helpline.h | 2 ++ tools/perf/util/ui/util.c | 27 +++++++++++++++---------- tools/perf/util/ui/util.h | 5 +++-- 9 files changed, 94 insertions(+), 26 deletions(-) (limited to 'tools/perf/util/ui/util.h') diff --git a/tools/perf/util/debug.c b/tools/perf/util/debug.c index 55634038af6b..26817daa2961 100644 --- a/tools/perf/util/debug.c +++ b/tools/perf/util/debug.c @@ -47,19 +47,20 @@ int dump_printf(const char *fmt, ...) } #ifdef NO_NEWT_SUPPORT -void ui__warning(const char *format, ...) +int ui__warning(const char *format, ...) { va_list args; va_start(args, format); vfprintf(stderr, format, args); va_end(args); + return 0; } #endif -void ui__error_paranoid(void) +int ui__error_paranoid(void) { - ui__error("Permission error - are you root?\n" + return ui__error("Permission error - are you root?\n" "Consider tweaking /proc/sys/kernel/perf_event_paranoid:\n" " -1 - Not paranoid at all\n" " 0 - Disallow raw tracepoint access for unpriv\n" diff --git a/tools/perf/util/debug.h b/tools/perf/util/debug.h index 16cc75227d2b..f2ce88d04f54 100644 --- a/tools/perf/util/debug.h +++ b/tools/perf/util/debug.h @@ -27,10 +27,10 @@ static inline void ui_progress__update(u64 curr __used, u64 total __used, extern char ui_helpline__last_msg[]; int ui_helpline__show_help(const char *format, va_list ap); #include "ui/progress.h" -void ui__error(const char *format, ...) __attribute__((format(printf, 1, 2))); +int ui__error(const char *format, ...) __attribute__((format(printf, 1, 2))); #endif -void ui__warning(const char *format, ...) __attribute__((format(printf, 1, 2))); -void ui__error_paranoid(void); +int ui__warning(const char *format, ...) __attribute__((format(printf, 1, 2))); +int ui__error_paranoid(void); #endif /* __PERF_DEBUG_H */ diff --git a/tools/perf/util/ui/browser.c b/tools/perf/util/ui/browser.c index 8607efa13564..d2051be04f12 100644 --- a/tools/perf/util/ui/browser.c +++ b/tools/perf/util/ui/browser.c @@ -169,6 +169,46 @@ void ui_browser__refresh_dimensions(struct ui_browser *self) self->x = 0; } +void ui_browser__handle_resize(struct ui_browser *browser) +{ + ui__refresh_dimensions(false); + ui_browser__show(browser, browser->title, ui_helpline__current); + ui_browser__refresh(browser); +} + +int ui_browser__warning(struct ui_browser *browser, const char *format, ...) +{ + va_list args; + int key; + + va_start(args, format); + while ((key = __ui__warning("Warning!", format, args)) == K_RESIZE) + ui_browser__handle_resize(browser); + va_end(args); + + return key; +} + +int ui_browser__help_window(struct ui_browser *browser, const char *text) +{ + int key; + + while ((key = ui__help_window(text)) == K_RESIZE) + ui_browser__handle_resize(browser); + + return key; +} + +bool ui_browser__dialog_yesno(struct ui_browser *browser, const char *text) +{ + int key; + + while ((key = ui__dialog_yesno(text)) == K_RESIZE) + ui_browser__handle_resize(browser); + + return key == K_ENTER || toupper(key) == 'Y'; +} + void ui_browser__reset_index(struct ui_browser *self) { self->index = self->top_idx = 0; diff --git a/tools/perf/util/ui/browser.h b/tools/perf/util/ui/browser.h index 81a8d2afaa9b..fb1c59883e6a 100644 --- a/tools/perf/util/ui/browser.h +++ b/tools/perf/util/ui/browser.h @@ -43,6 +43,11 @@ void ui_browser__hide(struct ui_browser *self); int ui_browser__refresh(struct ui_browser *self); int ui_browser__run(struct ui_browser *browser, int delay_secs); void ui_browser__update_nr_entries(struct ui_browser *browser, u32 nr_entries); +void ui_browser__handle_resize(struct ui_browser *browser); + +int ui_browser__warning(struct ui_browser *browser, const char *format, ...); +int ui_browser__help_window(struct ui_browser *browser, const char *text); +bool ui_browser__dialog_yesno(struct ui_browser *browser, const char *text); void ui_browser__argv_seek(struct ui_browser *browser, off_t offset, int whence); unsigned int ui_browser__argv_refresh(struct ui_browser *browser); diff --git a/tools/perf/util/ui/browsers/hists.c b/tools/perf/util/ui/browsers/hists.c index 44210d471719..b8733c0770cd 100644 --- a/tools/perf/util/ui/browsers/hists.c +++ b/tools/perf/util/ui/browsers/hists.c @@ -17,6 +17,7 @@ #include "../browser.h" #include "../helpline.h" #include "../util.h" +#include "../ui.h" #include "map.h" struct hist_browser { @@ -882,7 +883,7 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events, goto out_free_stack; case 'a': if (!browser->has_symbols) { - ui__warning( + ui_browser__warning(&browser->b, "Annotation is only available for symbolic views, " "include \"sym\" in --sort to use it."); continue; @@ -900,7 +901,8 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events, case K_F1: case 'h': case '?': - ui__help_window("h/?/F1 Show this window\n" + ui_browser__help_window(&browser->b, + "h/?/F1 Show this window\n" "UP/DOWN/PGUP\n" "PGDN/SPACE Navigate\n" "q/ESC/CTRL+C Exit browser\n\n" @@ -939,7 +941,8 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events, } case K_ESC: if (!left_exits && - !ui__dialog_yesno("Do you really want to exit?")) + !ui_browser__dialog_yesno(&browser->b, + "Do you really want to exit?")) continue; /* Fall thru */ case 'q': @@ -992,6 +995,7 @@ add_exit_option: if (choice == annotate) { struct hist_entry *he; + int err; do_annotate: he = hist_browser__selected_entry(browser); if (he == NULL) @@ -1000,10 +1004,12 @@ do_annotate: * Don't let this be freed, say, by hists__decay_entry. */ he->used = true; - hist_entry__tui_annotate(he, evsel->idx, nr_events, - timer, arg, delay_secs); + err = hist_entry__tui_annotate(he, evsel->idx, nr_events, + timer, arg, delay_secs); he->used = false; ui_browser__update_nr_entries(&browser->b, browser->hists->nr_entries); + if (err) + ui_browser__handle_resize(&browser->b); } else if (choice == browse_map) map__browse(browser->selection->map); else if (choice == zoom_dso) { @@ -1132,7 +1138,8 @@ browse_hists: pos = list_entry(pos->node.prev, struct perf_evsel, node); goto browse_hists; case K_ESC: - if (!ui__dialog_yesno("Do you really want to exit?")) + if (!ui_browser__dialog_yesno(&menu->b, + "Do you really want to exit?")) continue; /* Fall thru */ case 'q': @@ -1144,7 +1151,8 @@ browse_hists: case K_LEFT: continue; case K_ESC: - if (!ui__dialog_yesno("Do you really want to exit?")) + if (!ui_browser__dialog_yesno(&menu->b, + "Do you really want to exit?")) continue; /* Fall thru */ case 'q': diff --git a/tools/perf/util/ui/helpline.c b/tools/perf/util/ui/helpline.c index 600243d766c0..6ef3c5691762 100644 --- a/tools/perf/util/ui/helpline.c +++ b/tools/perf/util/ui/helpline.c @@ -1,6 +1,7 @@ #define _GNU_SOURCE #include #include +#include #include "../debug.h" #include "helpline.h" @@ -11,12 +12,17 @@ void ui_helpline__pop(void) { } +char ui_helpline__current[512]; + void ui_helpline__push(const char *msg) { + const size_t sz = sizeof(ui_helpline__current); + SLsmg_gotorc(SLtt_Screen_Rows - 1, 0); SLsmg_set_color(0); SLsmg_write_nstring((char *)msg, SLtt_Screen_Cols); SLsmg_refresh(); + strncpy(ui_helpline__current, msg, sz)[sz - 1] = '\0'; } void ui_helpline__vpush(const char *fmt, va_list ap) diff --git a/tools/perf/util/ui/helpline.h b/tools/perf/util/ui/helpline.h index fdcbc0270acd..7bab6b34e35e 100644 --- a/tools/perf/util/ui/helpline.h +++ b/tools/perf/util/ui/helpline.h @@ -11,4 +11,6 @@ void ui_helpline__vpush(const char *fmt, va_list ap); void ui_helpline__fpush(const char *fmt, ...); void ui_helpline__puts(const char *msg); +extern char ui_helpline__current[]; + #endif /* _PERF_UI_HELPLINE_H_ */ diff --git a/tools/perf/util/ui/util.c b/tools/perf/util/ui/util.c index ef9b79332fe8..45daa7c41dad 100644 --- a/tools/perf/util/ui/util.c +++ b/tools/perf/util/ui/util.c @@ -121,43 +121,48 @@ int ui__help_window(const char *text) return ui__question_window("Help", text, "Press any key...", 0); } -bool ui__dialog_yesno(const char *msg) +int ui__dialog_yesno(const char *msg) { - int answer = ui__question_window(NULL, msg, "Enter: Yes, ESC: No", 0); - - return answer == K_ENTER; + return ui__question_window(NULL, msg, "Enter: Yes, ESC: No", 0); } -static void __ui__warning(const char *title, const char *format, va_list args) +int __ui__warning(const char *title, const char *format, va_list args) { char *s; if (use_browser > 0 && vasprintf(&s, format, args) > 0) { + int key; + pthread_mutex_lock(&ui__lock); - ui__question_window(title, s, "Press any key...", 0); + key = ui__question_window(title, s, "Press any key...", 0); pthread_mutex_unlock(&ui__lock); free(s); - return; + return key; } fprintf(stderr, "%s:\n", title); vfprintf(stderr, format, args); + return K_ESC; } -void ui__warning(const char *format, ...) +int ui__warning(const char *format, ...) { + int key; va_list args; va_start(args, format); - __ui__warning("Warning", format, args); + key = __ui__warning("Warning", format, args); va_end(args); + return key; } -void ui__error(const char *format, ...) +int ui__error(const char *format, ...) { + int key; va_list args; va_start(args, format); - __ui__warning("Error", format, args); + key = __ui__warning("Error", format, args); va_end(args); + return key; } diff --git a/tools/perf/util/ui/util.h b/tools/perf/util/ui/util.h index 9a25538d4735..2d1738bd71c8 100644 --- a/tools/perf/util/ui/util.h +++ b/tools/perf/util/ui/util.h @@ -1,13 +1,14 @@ #ifndef _PERF_UI_UTIL_H_ #define _PERF_UI_UTIL_H_ 1 -#include +#include int ui__getch(int delay_secs); int ui__popup_menu(int argc, char * const argv[]); int ui__help_window(const char *text); -bool ui__dialog_yesno(const char *msg); +int ui__dialog_yesno(const char *msg); int ui__question_window(const char *title, const char *text, const char *exit_msg, int delay_secs); +int __ui__warning(const char *title, const char *format, va_list args); #endif /* _PERF_UI_UTIL_H_ */ -- cgit v1.2.3