xref: /openbmc/linux/tools/perf/ui/browsers/header.c (revision b34e08d5)
1 #include "util/cache.h"
2 #include "util/debug.h"
3 #include "ui/browser.h"
4 #include "ui/ui.h"
5 #include "ui/util.h"
6 #include "ui/libslang.h"
7 #include "util/header.h"
8 #include "util/session.h"
9 
10 static void ui_browser__argv_write(struct ui_browser *browser,
11 				   void *entry, int row)
12 {
13 	char **arg = entry;
14 	char *str = *arg;
15 	char empty[] = " ";
16 	bool current_entry = ui_browser__is_current_entry(browser, row);
17 	unsigned long offset = (unsigned long)browser->priv;
18 
19 	if (offset >= strlen(str))
20 		str = empty;
21 	else
22 		str = str + offset;
23 
24 	ui_browser__set_color(browser, current_entry ? HE_COLORSET_SELECTED :
25 						       HE_COLORSET_NORMAL);
26 
27 	slsmg_write_nstring(str, browser->width);
28 }
29 
30 static int list_menu__run(struct ui_browser *menu)
31 {
32 	int key;
33 	unsigned long offset;
34 	const char help[] =
35 	"h/?/F1        Show this window\n"
36 	"UP/DOWN/PGUP\n"
37 	"PGDN/SPACE\n"
38 	"LEFT/RIGHT    Navigate\n"
39 	"q/ESC/CTRL+C  Exit browser";
40 
41 	if (ui_browser__show(menu, "Header information", "Press 'q' to exit") < 0)
42 		return -1;
43 
44 	while (1) {
45 		key = ui_browser__run(menu, 0);
46 
47 		switch (key) {
48 		case K_RIGHT:
49 			offset = (unsigned long)menu->priv;
50 			offset += 10;
51 			menu->priv = (void *)offset;
52 			continue;
53 		case K_LEFT:
54 			offset = (unsigned long)menu->priv;
55 			if (offset >= 10)
56 				offset -= 10;
57 			menu->priv = (void *)offset;
58 			continue;
59 		case K_F1:
60 		case 'h':
61 		case '?':
62 			ui_browser__help_window(menu, help);
63 			continue;
64 		case K_ESC:
65 		case 'q':
66 		case CTRL('c'):
67 			key = -1;
68 			break;
69 		default:
70 			continue;
71 		}
72 
73 		break;
74 	}
75 
76 	ui_browser__hide(menu);
77 	return key;
78 }
79 
80 static int ui__list_menu(int argc, char * const argv[])
81 {
82 	struct ui_browser menu = {
83 		.entries    = (void *)argv,
84 		.refresh    = ui_browser__argv_refresh,
85 		.seek	    = ui_browser__argv_seek,
86 		.write	    = ui_browser__argv_write,
87 		.nr_entries = argc,
88 	};
89 
90 	return list_menu__run(&menu);
91 }
92 
93 int tui__header_window(struct perf_session_env *env)
94 {
95 	int i, argc = 0;
96 	char **argv;
97 	struct perf_session *session;
98 	char *ptr, *pos;
99 	size_t size;
100 	FILE *fp = open_memstream(&ptr, &size);
101 
102 	session = container_of(env, struct perf_session, header.env);
103 	perf_header__fprintf_info(session, fp, true);
104 	fclose(fp);
105 
106 	for (pos = ptr, argc = 0; (pos = strchr(pos, '\n')) != NULL; pos++)
107 		argc++;
108 
109 	argv = calloc(argc + 1, sizeof(*argv));
110 	if (argv == NULL)
111 		goto out;
112 
113 	argv[0] = pos = ptr;
114 	for (i = 1; (pos = strchr(pos, '\n')) != NULL; i++) {
115 		*pos++ = '\0';
116 		argv[i] = pos;
117 	}
118 
119 	BUG_ON(i != argc + 1);
120 
121 	ui__list_menu(argc, argv);
122 
123 out:
124 	free(argv);
125 	free(ptr);
126 	return 0;
127 }
128