[PATCH 5/6] perf ui/tui: Implement log window

Namhyung Kim
2013-12-19T07:00:52Z

From: Namhyung Kim <namhyung.kim@lge.com>

Implement a simple, full-screen log window which shows error messages
saved so far. Press 'l' (lower-case 'L') key to display the log
window. It'll be used usually with -v option.

Signed-off-by: Namhyung Kim <namhyung@kernel.org>
---
tools/perf/Makefile.perf | 1 +
tools/perf/ui/browser.h | 1 +
tools/perf/ui/browsers/hists.c | 4 ++
tools/perf/ui/browsers/log.c | 92 ++++++++++++++++++++++++++++++++++++++++++
4 files changed, 98 insertions(+)
create mode 100644 tools/perf/ui/browsers/log.c

diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf
index ec8184014a76..30aabace33a0 100644
--- a/tools/perf/Makefile.perf
+++ b/tools/perf/Makefile.perf
@@ -490,6 +490,7 @@ ifndef NO_SLANG
LIB_OBJS += $(OUTPUT)ui/browsers/hists.o
LIB_OBJS += $(OUTPUT)ui/browsers/map.o
LIB_OBJS += $(OUTPUT)ui/browsers/scripts.o
+ LIB_OBJS += $(OUTPUT)ui/browsers/log.o
LIB_OBJS += $(OUTPUT)ui/tui/setup.o
LIB_OBJS += $(OUTPUT)ui/tui/util.o
LIB_OBJS += $(OUTPUT)ui/tui/helpline.o
diff --git a/tools/perf/ui/browser.h b/tools/perf/ui/browser.h
index 7d45d2f53601..fff46942a8c7 100644
--- a/tools/perf/ui/browser.h
+++ b/tools/perf/ui/browser.h
@@ -59,6 +59,7 @@ int ui_browser__help_window(struct ui_browser *browser, const char *text);
bool ui_browser__dialog_yesno(struct ui_browser *browser, const char *text);
int ui_browser__input_window(const char *title, const char *text, char *input,
const char *exit_msg, int delay_sec);
+int tui__log_window(void);

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/ui/browsers/hists.c b/tools/perf/ui/browsers/hists.c
index a440e03cd8c2..8cc6f5eaa2cf 100644
--- a/tools/perf/ui/browsers/hists.c
+++ b/tools/perf/ui/browsers/hists.c
@@ -1484,6 +1484,9 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events,
if (is_report_browser(hbt))
goto do_data_switch;
continue;
+ case 'l':
+ tui__log_window();
+ continue;
case K_F1:
case 'h':
case '?':
@@ -1506,6 +1509,7 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events,
"s Switch to another data file in PWD ('perf report' only)\n"
"P Print histograms to perf.hist.N\n"
"V Verbose (DSO names in callchains, etc)\n"
+ "l Show log messages\n"
"/ Filter symbol by name");
continue;
case K_ENTER:
diff --git a/tools/perf/ui/browsers/log.c b/tools/perf/ui/browsers/log.c
new file mode 100644
index 000000000000..f1610d6bb9d2
--- /dev/null
+++ b/tools/perf/ui/browsers/log.c
@@ -0,0 +1,92 @@
+#include <stdio.h>
+
+#include "perf.h"
+#include "util/util.h"
+#include "util/cache.h"
+#include "util/debug.h"
+#include "ui/ui.h"
+#include "ui/util.h"
+#include "ui/browser.h"
+#include "ui/libslang.h"
+#include "ui/keysyms.h"
+#include "ui/tui/tui.h"
+
+static void ui_browser__file_seek(struct ui_browser *browser __maybe_unused,
+ off_t offset __maybe_unused,
+ int whence __maybe_unused)
+{
+ /* do nothing */
+}
+
+static void ui_browser__file_write(struct ui_browser *browser,
+ void *entry, int row)
+{
+ char buf[1024];
+ FILE *fp = perf_log.fp;
+ bool current_entry = ui_browser__is_current_entry(browser, row);
+ off_t *linemap = perf_log.linemap;
+ unsigned int idx = *(unsigned int *)entry;
+
+ fseek(fp, linemap[idx], SEEK_SET);
+ if (fgets(buf, sizeof(buf), fp) == NULL)
+ return;
+
+ ui_browser__set_color(browser, current_entry ? HE_COLORSET_SELECTED :
+ HE_COLORSET_NORMAL);
+ slsmg_write_nstring(buf, browser->width);
+}
+
+static unsigned int ui_browser__file_refresh(struct ui_browser *browser)
+{
+ unsigned int row = 0;
+ unsigned int idx = browser->top_idx;
+
+ while (idx < browser->nr_entries) {
+ ui_browser__gotorc(browser, row, 0);
+ browser->write(browser, &idx, row);
+ if (++row == browser->height)
+ break;
+
+ ++idx;
+ }
+
+ return row;
+}
+
+static int log_menu__run(struct ui_browser *menu)
+{
+ int key;
+
+ if (ui_browser__show(menu, "Log messages", "Press 'q' to exit") < 0)
+ return -1;
+
+ while (1) {
+ key = ui_browser__run(menu, 0);
+ switch (key) {
+ case K_ESC:
+ case 'q':
+ case CTRL('c'):
+ key = -1;
+ break;
+ default:
+ continue;
+ }
+
+ break;
+ }
+
+ ui_browser__hide(menu);
+ return key;
+}
+
+int tui__log_window(void)
+{
+ struct ui_browser log_menu = {
+ .refresh = ui_browser__file_refresh,
+ .seek = ui_browser__file_seek,
+ .write = ui_browser__file_write,
+ .nr_entries = perf_log.lines,
+ };
+
+ return log_menu__run(&log_menu);
+}
--
1.7.11.7