diff options
author | Namhyung Kim <namhyung.kim@lge.com> | 2012-05-29 00:22:58 -0400 |
---|---|---|
committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2012-06-19 12:06:18 -0400 |
commit | ba47a142d9f9b84e0464a11b7a067e5ad95c5d4b (patch) | |
tree | 40a4ebe58bf9e5314667cee7fe2cea2e5e3a88c5 /tools/perf/ui/tui | |
parent | 409a8be61560c5875816da6dcb0c575d78145a5c (diff) |
perf ui: Introduce struct perf_error_ops
The struct perf_error_ops is for flexible error logging.
We can register appropriate functions based on front-end.
Signed-off-by: Namhyung Kim <namhyung.kim@lge.com>
Acked-by: Pekka Enberg <penberg@kernel.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Pekka Enberg <penberg@kernel.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Link: http://lkml.kernel.org/r/1338265382-6872-4-git-send-email-namhyung@gmail.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools/perf/ui/tui')
-rw-r--r-- | tools/perf/ui/tui/setup.c | 6 | ||||
-rw-r--r-- | tools/perf/ui/tui/util.c | 243 |
2 files changed, 249 insertions, 0 deletions
diff --git a/tools/perf/ui/tui/setup.c b/tools/perf/ui/tui/setup.c index d33e943ac434..e813c1d17346 100644 --- a/tools/perf/ui/tui/setup.c +++ b/tools/perf/ui/tui/setup.c | |||
@@ -15,6 +15,8 @@ pthread_mutex_t ui__lock = PTHREAD_MUTEX_INITIALIZER; | |||
15 | 15 | ||
16 | static volatile int ui__need_resize; | 16 | static volatile int ui__need_resize; |
17 | 17 | ||
18 | extern struct perf_error_ops perf_tui_eops; | ||
19 | |||
18 | void ui__refresh_dimensions(bool force) | 20 | void ui__refresh_dimensions(bool force) |
19 | { | 21 | { |
20 | if (force || ui__need_resize) { | 22 | if (force || ui__need_resize) { |
@@ -122,6 +124,8 @@ int ui__init(void) | |||
122 | signal(SIGINT, ui__signal); | 124 | signal(SIGINT, ui__signal); |
123 | signal(SIGQUIT, ui__signal); | 125 | signal(SIGQUIT, ui__signal); |
124 | signal(SIGTERM, ui__signal); | 126 | signal(SIGTERM, ui__signal); |
127 | |||
128 | perf_error__register(&perf_tui_eops); | ||
125 | out: | 129 | out: |
126 | return err; | 130 | return err; |
127 | } | 131 | } |
@@ -137,4 +141,6 @@ void ui__exit(bool wait_for_ok) | |||
137 | SLsmg_refresh(); | 141 | SLsmg_refresh(); |
138 | SLsmg_reset_smg(); | 142 | SLsmg_reset_smg(); |
139 | SLang_reset_tty(); | 143 | SLang_reset_tty(); |
144 | |||
145 | perf_error__unregister(&perf_tui_eops); | ||
140 | } | 146 | } |
diff --git a/tools/perf/ui/tui/util.c b/tools/perf/ui/tui/util.c new file mode 100644 index 000000000000..092902e30cee --- /dev/null +++ b/tools/perf/ui/tui/util.c | |||
@@ -0,0 +1,243 @@ | |||
1 | #include "../../util/util.h" | ||
2 | #include <signal.h> | ||
3 | #include <stdbool.h> | ||
4 | #include <string.h> | ||
5 | #include <sys/ttydefaults.h> | ||
6 | |||
7 | #include "../../util/cache.h" | ||
8 | #include "../../util/debug.h" | ||
9 | #include "../browser.h" | ||
10 | #include "../keysyms.h" | ||
11 | #include "../helpline.h" | ||
12 | #include "../ui.h" | ||
13 | #include "../util.h" | ||
14 | #include "../libslang.h" | ||
15 | |||
16 | static void ui_browser__argv_write(struct ui_browser *browser, | ||
17 | void *entry, int row) | ||
18 | { | ||
19 | char **arg = entry; | ||
20 | bool current_entry = ui_browser__is_current_entry(browser, row); | ||
21 | |||
22 | ui_browser__set_color(browser, current_entry ? HE_COLORSET_SELECTED : | ||
23 | HE_COLORSET_NORMAL); | ||
24 | slsmg_write_nstring(*arg, browser->width); | ||
25 | } | ||
26 | |||
27 | static int popup_menu__run(struct ui_browser *menu) | ||
28 | { | ||
29 | int key; | ||
30 | |||
31 | if (ui_browser__show(menu, " ", "ESC: exit, ENTER|->: Select option") < 0) | ||
32 | return -1; | ||
33 | |||
34 | while (1) { | ||
35 | key = ui_browser__run(menu, 0); | ||
36 | |||
37 | switch (key) { | ||
38 | case K_RIGHT: | ||
39 | case K_ENTER: | ||
40 | key = menu->index; | ||
41 | break; | ||
42 | case K_LEFT: | ||
43 | case K_ESC: | ||
44 | case 'q': | ||
45 | case CTRL('c'): | ||
46 | key = -1; | ||
47 | break; | ||
48 | default: | ||
49 | continue; | ||
50 | } | ||
51 | |||
52 | break; | ||
53 | } | ||
54 | |||
55 | ui_browser__hide(menu); | ||
56 | return key; | ||
57 | } | ||
58 | |||
59 | int ui__popup_menu(int argc, char * const argv[]) | ||
60 | { | ||
61 | struct ui_browser menu = { | ||
62 | .entries = (void *)argv, | ||
63 | .refresh = ui_browser__argv_refresh, | ||
64 | .seek = ui_browser__argv_seek, | ||
65 | .write = ui_browser__argv_write, | ||
66 | .nr_entries = argc, | ||
67 | }; | ||
68 | |||
69 | return popup_menu__run(&menu); | ||
70 | } | ||
71 | |||
72 | int ui_browser__input_window(const char *title, const char *text, char *input, | ||
73 | const char *exit_msg, int delay_secs) | ||
74 | { | ||
75 | int x, y, len, key; | ||
76 | int max_len = 60, nr_lines = 0; | ||
77 | static char buf[50]; | ||
78 | const char *t; | ||
79 | |||
80 | t = text; | ||
81 | while (1) { | ||
82 | const char *sep = strchr(t, '\n'); | ||
83 | |||
84 | if (sep == NULL) | ||
85 | sep = strchr(t, '\0'); | ||
86 | len = sep - t; | ||
87 | if (max_len < len) | ||
88 | max_len = len; | ||
89 | ++nr_lines; | ||
90 | if (*sep == '\0') | ||
91 | break; | ||
92 | t = sep + 1; | ||
93 | } | ||
94 | |||
95 | max_len += 2; | ||
96 | nr_lines += 8; | ||
97 | y = SLtt_Screen_Rows / 2 - nr_lines / 2; | ||
98 | x = SLtt_Screen_Cols / 2 - max_len / 2; | ||
99 | |||
100 | SLsmg_set_color(0); | ||
101 | SLsmg_draw_box(y, x++, nr_lines, max_len); | ||
102 | if (title) { | ||
103 | SLsmg_gotorc(y, x + 1); | ||
104 | SLsmg_write_string((char *)title); | ||
105 | } | ||
106 | SLsmg_gotorc(++y, x); | ||
107 | nr_lines -= 7; | ||
108 | max_len -= 2; | ||
109 | SLsmg_write_wrapped_string((unsigned char *)text, y, x, | ||
110 | nr_lines, max_len, 1); | ||
111 | y += nr_lines; | ||
112 | len = 5; | ||
113 | while (len--) { | ||
114 | SLsmg_gotorc(y + len - 1, x); | ||
115 | SLsmg_write_nstring((char *)" ", max_len); | ||
116 | } | ||
117 | SLsmg_draw_box(y++, x + 1, 3, max_len - 2); | ||
118 | |||
119 | SLsmg_gotorc(y + 3, x); | ||
120 | SLsmg_write_nstring((char *)exit_msg, max_len); | ||
121 | SLsmg_refresh(); | ||
122 | |||
123 | x += 2; | ||
124 | len = 0; | ||
125 | key = ui__getch(delay_secs); | ||
126 | while (key != K_TIMER && key != K_ENTER && key != K_ESC) { | ||
127 | if (key == K_BKSPC) { | ||
128 | if (len == 0) | ||
129 | goto next_key; | ||
130 | SLsmg_gotorc(y, x + --len); | ||
131 | SLsmg_write_char(' '); | ||
132 | } else { | ||
133 | buf[len] = key; | ||
134 | SLsmg_gotorc(y, x + len++); | ||
135 | SLsmg_write_char(key); | ||
136 | } | ||
137 | SLsmg_refresh(); | ||
138 | |||
139 | /* XXX more graceful overflow handling needed */ | ||
140 | if (len == sizeof(buf) - 1) { | ||
141 | ui_helpline__push("maximum size of symbol name reached!"); | ||
142 | key = K_ENTER; | ||
143 | break; | ||
144 | } | ||
145 | next_key: | ||
146 | key = ui__getch(delay_secs); | ||
147 | } | ||
148 | |||
149 | buf[len] = '\0'; | ||
150 | strncpy(input, buf, len+1); | ||
151 | return key; | ||
152 | } | ||
153 | |||
154 | int ui__question_window(const char *title, const char *text, | ||
155 | const char *exit_msg, int delay_secs) | ||
156 | { | ||
157 | int x, y; | ||
158 | int max_len = 0, nr_lines = 0; | ||
159 | const char *t; | ||
160 | |||
161 | t = text; | ||
162 | while (1) { | ||
163 | const char *sep = strchr(t, '\n'); | ||
164 | int len; | ||
165 | |||
166 | if (sep == NULL) | ||
167 | sep = strchr(t, '\0'); | ||
168 | len = sep - t; | ||
169 | if (max_len < len) | ||
170 | max_len = len; | ||
171 | ++nr_lines; | ||
172 | if (*sep == '\0') | ||
173 | break; | ||
174 | t = sep + 1; | ||
175 | } | ||
176 | |||
177 | max_len += 2; | ||
178 | nr_lines += 4; | ||
179 | y = SLtt_Screen_Rows / 2 - nr_lines / 2, | ||
180 | x = SLtt_Screen_Cols / 2 - max_len / 2; | ||
181 | |||
182 | SLsmg_set_color(0); | ||
183 | SLsmg_draw_box(y, x++, nr_lines, max_len); | ||
184 | if (title) { | ||
185 | SLsmg_gotorc(y, x + 1); | ||
186 | SLsmg_write_string((char *)title); | ||
187 | } | ||
188 | SLsmg_gotorc(++y, x); | ||
189 | nr_lines -= 2; | ||
190 | max_len -= 2; | ||
191 | SLsmg_write_wrapped_string((unsigned char *)text, y, x, | ||
192 | nr_lines, max_len, 1); | ||
193 | SLsmg_gotorc(y + nr_lines - 2, x); | ||
194 | SLsmg_write_nstring((char *)" ", max_len); | ||
195 | SLsmg_gotorc(y + nr_lines - 1, x); | ||
196 | SLsmg_write_nstring((char *)exit_msg, max_len); | ||
197 | SLsmg_refresh(); | ||
198 | return ui__getch(delay_secs); | ||
199 | } | ||
200 | |||
201 | int ui__help_window(const char *text) | ||
202 | { | ||
203 | return ui__question_window("Help", text, "Press any key...", 0); | ||
204 | } | ||
205 | |||
206 | int ui__dialog_yesno(const char *msg) | ||
207 | { | ||
208 | return ui__question_window(NULL, msg, "Enter: Yes, ESC: No", 0); | ||
209 | } | ||
210 | |||
211 | static int __ui__warning(const char *title, const char *format, va_list args) | ||
212 | { | ||
213 | char *s; | ||
214 | |||
215 | if (vasprintf(&s, format, args) > 0) { | ||
216 | int key; | ||
217 | |||
218 | pthread_mutex_lock(&ui__lock); | ||
219 | key = ui__question_window(title, s, "Press any key...", 0); | ||
220 | pthread_mutex_unlock(&ui__lock); | ||
221 | free(s); | ||
222 | return key; | ||
223 | } | ||
224 | |||
225 | fprintf(stderr, "%s\n", title); | ||
226 | vfprintf(stderr, format, args); | ||
227 | return K_ESC; | ||
228 | } | ||
229 | |||
230 | static int perf_tui__error(const char *format, va_list args) | ||
231 | { | ||
232 | return __ui__warning("Error:", format, args); | ||
233 | } | ||
234 | |||
235 | static int perf_tui__warning(const char *format, va_list args) | ||
236 | { | ||
237 | return __ui__warning("Warning:", format, args); | ||
238 | } | ||
239 | |||
240 | struct perf_error_ops perf_tui_eops = { | ||
241 | .error = perf_tui__error, | ||
242 | .warning = perf_tui__warning, | ||
243 | }; | ||