diff options
Diffstat (limited to 'tools/perf/util/ui/browser.c')
-rw-r--r-- | tools/perf/util/ui/browser.c | 137 |
1 files changed, 90 insertions, 47 deletions
diff --git a/tools/perf/util/ui/browser.c b/tools/perf/util/ui/browser.c index 5911bba63858..05a0f61312d8 100644 --- a/tools/perf/util/ui/browser.c +++ b/tools/perf/util/ui/browser.c | |||
@@ -1,4 +1,7 @@ | |||
1 | #include "../util.h" | ||
2 | #include "../../perf.h" | ||
1 | #include "libslang.h" | 3 | #include "libslang.h" |
4 | #include <newt.h> | ||
2 | #include "ui.h" | 5 | #include "ui.h" |
3 | #include <linux/compiler.h> | 6 | #include <linux/compiler.h> |
4 | #include <linux/list.h> | 7 | #include <linux/list.h> |
@@ -8,8 +11,8 @@ | |||
8 | #include "browser.h" | 11 | #include "browser.h" |
9 | #include "helpline.h" | 12 | #include "helpline.h" |
10 | #include "../color.h" | 13 | #include "../color.h" |
11 | #include "../util.h" | 14 | |
12 | #include <stdio.h> | 15 | int newtGetKey(void); |
13 | 16 | ||
14 | static int ui_browser__percent_color(double percent, bool current) | 17 | static int ui_browser__percent_color(double percent, bool current) |
15 | { | 18 | { |
@@ -127,11 +130,8 @@ bool ui_browser__is_current_entry(struct ui_browser *self, unsigned row) | |||
127 | 130 | ||
128 | void ui_browser__refresh_dimensions(struct ui_browser *self) | 131 | void ui_browser__refresh_dimensions(struct ui_browser *self) |
129 | { | 132 | { |
130 | int cols, rows; | 133 | self->width = SLtt_Screen_Cols - 1; |
131 | newtGetScreenSize(&cols, &rows); | 134 | self->height = SLtt_Screen_Rows - 2; |
132 | |||
133 | self->width = cols - 1; | ||
134 | self->height = rows - 2; | ||
135 | self->y = 1; | 135 | self->y = 1; |
136 | self->x = 0; | 136 | self->x = 0; |
137 | } | 137 | } |
@@ -142,9 +142,8 @@ void ui_browser__reset_index(struct ui_browser *self) | |||
142 | self->seek(self, 0, SEEK_SET); | 142 | self->seek(self, 0, SEEK_SET); |
143 | } | 143 | } |
144 | 144 | ||
145 | void ui_browser__add_exit_key(struct ui_browser *self, int key) | 145 | void ui_browser__add_exit_key(struct ui_browser *browser __used, int key __used) |
146 | { | 146 | { |
147 | newtFormAddHotKey(self->form, key); | ||
148 | } | 147 | } |
149 | 148 | ||
150 | void ui_browser__add_exit_keys(struct ui_browser *self, int keys[]) | 149 | void ui_browser__add_exit_keys(struct ui_browser *self, int keys[]) |
@@ -161,7 +160,7 @@ void __ui_browser__show_title(struct ui_browser *browser, const char *title) | |||
161 | { | 160 | { |
162 | SLsmg_gotorc(0, 0); | 161 | SLsmg_gotorc(0, 0); |
163 | ui_browser__set_color(browser, NEWT_COLORSET_ROOT); | 162 | ui_browser__set_color(browser, NEWT_COLORSET_ROOT); |
164 | slsmg_write_nstring(title, browser->width); | 163 | slsmg_write_nstring(title, browser->width + 1); |
165 | } | 164 | } |
166 | 165 | ||
167 | void ui_browser__show_title(struct ui_browser *browser, const char *title) | 166 | void ui_browser__show_title(struct ui_browser *browser, const char *title) |
@@ -174,57 +173,75 @@ void ui_browser__show_title(struct ui_browser *browser, const char *title) | |||
174 | int ui_browser__show(struct ui_browser *self, const char *title, | 173 | int ui_browser__show(struct ui_browser *self, const char *title, |
175 | const char *helpline, ...) | 174 | const char *helpline, ...) |
176 | { | 175 | { |
176 | int err; | ||
177 | va_list ap; | 177 | va_list ap; |
178 | int keys[] = { NEWT_KEY_UP, NEWT_KEY_DOWN, NEWT_KEY_PGUP, | 178 | int keys[] = { NEWT_KEY_UP, NEWT_KEY_DOWN, NEWT_KEY_PGUP, |
179 | NEWT_KEY_PGDN, NEWT_KEY_HOME, NEWT_KEY_END, ' ', | 179 | NEWT_KEY_PGDN, NEWT_KEY_HOME, NEWT_KEY_END, ' ', |
180 | NEWT_KEY_LEFT, NEWT_KEY_ESCAPE, 'q', CTRL('c'), 0 }; | 180 | NEWT_KEY_LEFT, NEWT_KEY_ESCAPE, 'q', CTRL('c'), 0 }; |
181 | 181 | ||
182 | if (self->form != NULL) | ||
183 | newtFormDestroy(self->form); | ||
184 | |||
185 | ui_browser__refresh_dimensions(self); | 182 | ui_browser__refresh_dimensions(self); |
186 | self->form = newtForm(NULL, NULL, 0); | ||
187 | if (self->form == NULL) | ||
188 | return -1; | ||
189 | |||
190 | self->sb = newtVerticalScrollbar(self->width, 1, self->height, | ||
191 | HE_COLORSET_NORMAL, | ||
192 | HE_COLORSET_SELECTED); | ||
193 | if (self->sb == NULL) | ||
194 | return -1; | ||
195 | 183 | ||
196 | pthread_mutex_lock(&ui__lock); | 184 | pthread_mutex_lock(&ui__lock); |
197 | __ui_browser__show_title(self, title); | 185 | __ui_browser__show_title(self, title); |
198 | 186 | ||
199 | ui_browser__add_exit_keys(self, keys); | 187 | ui_browser__add_exit_keys(self, keys); |
200 | newtFormAddComponent(self->form, self->sb); | 188 | self->title = title; |
189 | free(self->helpline); | ||
190 | self->helpline = NULL; | ||
201 | 191 | ||
202 | va_start(ap, helpline); | 192 | va_start(ap, helpline); |
203 | ui_helpline__vpush(helpline, ap); | 193 | err = vasprintf(&self->helpline, helpline, ap); |
204 | va_end(ap); | 194 | va_end(ap); |
195 | if (err > 0) | ||
196 | ui_helpline__push(self->helpline); | ||
205 | pthread_mutex_unlock(&ui__lock); | 197 | pthread_mutex_unlock(&ui__lock); |
206 | return 0; | 198 | return err ? 0 : -1; |
207 | } | 199 | } |
208 | 200 | ||
209 | void ui_browser__hide(struct ui_browser *self) | 201 | void ui_browser__hide(struct ui_browser *browser __used) |
210 | { | 202 | { |
211 | pthread_mutex_lock(&ui__lock); | 203 | pthread_mutex_lock(&ui__lock); |
212 | newtFormDestroy(self->form); | ||
213 | self->form = NULL; | ||
214 | ui_helpline__pop(); | 204 | ui_helpline__pop(); |
215 | pthread_mutex_unlock(&ui__lock); | 205 | pthread_mutex_unlock(&ui__lock); |
216 | } | 206 | } |
217 | 207 | ||
218 | int ui_browser__refresh(struct ui_browser *self) | 208 | static void ui_browser__scrollbar_set(struct ui_browser *browser) |
209 | { | ||
210 | int height = browser->height, h = 0, pct = 0, | ||
211 | col = browser->width, | ||
212 | row = browser->y - 1; | ||
213 | |||
214 | if (browser->nr_entries > 1) { | ||
215 | pct = ((browser->index * (browser->height - 1)) / | ||
216 | (browser->nr_entries - 1)); | ||
217 | } | ||
218 | |||
219 | while (h < height) { | ||
220 | ui_browser__gotorc(browser, row++, col); | ||
221 | SLsmg_set_char_set(1); | ||
222 | SLsmg_write_char(h == pct ? SLSMG_DIAMOND_CHAR : SLSMG_BOARD_CHAR); | ||
223 | SLsmg_set_char_set(0); | ||
224 | ++h; | ||
225 | } | ||
226 | } | ||
227 | |||
228 | static int __ui_browser__refresh(struct ui_browser *browser) | ||
219 | { | 229 | { |
220 | int row; | 230 | int row; |
221 | 231 | ||
232 | row = browser->refresh(browser); | ||
233 | ui_browser__set_color(browser, HE_COLORSET_NORMAL); | ||
234 | SLsmg_fill_region(browser->y + row, browser->x, | ||
235 | browser->height - row, browser->width, ' '); | ||
236 | ui_browser__scrollbar_set(browser); | ||
237 | |||
238 | return 0; | ||
239 | } | ||
240 | |||
241 | int ui_browser__refresh(struct ui_browser *browser) | ||
242 | { | ||
222 | pthread_mutex_lock(&ui__lock); | 243 | pthread_mutex_lock(&ui__lock); |
223 | newtScrollbarSet(self->sb, self->index, self->nr_entries - 1); | 244 | __ui_browser__refresh(browser); |
224 | row = self->refresh(self); | ||
225 | ui_browser__set_color(self, HE_COLORSET_NORMAL); | ||
226 | SLsmg_fill_region(self->y + row, self->x, | ||
227 | self->height - row, self->width, ' '); | ||
228 | pthread_mutex_unlock(&ui__lock); | 245 | pthread_mutex_unlock(&ui__lock); |
229 | 246 | ||
230 | return 0; | 247 | return 0; |
@@ -253,21 +270,49 @@ void ui_browser__update_nr_entries(struct ui_browser *browser, u32 nr_entries) | |||
253 | browser->seek(browser, browser->top_idx, SEEK_SET); | 270 | browser->seek(browser, browser->top_idx, SEEK_SET); |
254 | } | 271 | } |
255 | 272 | ||
256 | int ui_browser__run(struct ui_browser *self) | 273 | int ui_browser__run(struct ui_browser *self, int delay_secs) |
257 | { | 274 | { |
258 | struct newtExitStruct es; | 275 | int err, key; |
276 | struct timeval timeout, *ptimeout = delay_secs ? &timeout : NULL; | ||
259 | 277 | ||
260 | if (ui_browser__refresh(self) < 0) | 278 | pthread__unblock_sigwinch(); |
261 | return -1; | ||
262 | 279 | ||
263 | while (1) { | 280 | while (1) { |
264 | off_t offset; | 281 | off_t offset; |
282 | fd_set read_set; | ||
265 | 283 | ||
266 | newtFormRun(self->form, &es); | 284 | pthread_mutex_lock(&ui__lock); |
285 | err = __ui_browser__refresh(self); | ||
286 | SLsmg_refresh(); | ||
287 | pthread_mutex_unlock(&ui__lock); | ||
288 | if (err < 0) | ||
289 | break; | ||
290 | |||
291 | FD_ZERO(&read_set); | ||
292 | FD_SET(0, &read_set); | ||
293 | |||
294 | if (delay_secs) { | ||
295 | timeout.tv_sec = delay_secs; | ||
296 | timeout.tv_usec = 0; | ||
297 | } | ||
267 | 298 | ||
268 | if (es.reason != NEWT_EXIT_HOTKEY) | 299 | err = select(1, &read_set, NULL, NULL, ptimeout); |
300 | if (err > 0 && FD_ISSET(0, &read_set)) | ||
301 | key = newtGetKey(); | ||
302 | else if (err == 0) | ||
269 | break; | 303 | break; |
270 | switch (es.u.key) { | 304 | else { |
305 | pthread_mutex_lock(&ui__lock); | ||
306 | SLtt_get_screen_size(); | ||
307 | SLsmg_reinit_smg(); | ||
308 | pthread_mutex_unlock(&ui__lock); | ||
309 | ui_browser__refresh_dimensions(self); | ||
310 | __ui_browser__show_title(self, self->title); | ||
311 | ui_helpline__puts(self->helpline); | ||
312 | continue; | ||
313 | } | ||
314 | |||
315 | switch (key) { | ||
271 | case NEWT_KEY_DOWN: | 316 | case NEWT_KEY_DOWN: |
272 | if (self->index == self->nr_entries - 1) | 317 | if (self->index == self->nr_entries - 1) |
273 | break; | 318 | break; |
@@ -324,10 +369,8 @@ int ui_browser__run(struct ui_browser *self) | |||
324 | self->seek(self, -offset, SEEK_END); | 369 | self->seek(self, -offset, SEEK_END); |
325 | break; | 370 | break; |
326 | default: | 371 | default: |
327 | return es.u.key; | 372 | return key; |
328 | } | 373 | } |
329 | if (ui_browser__refresh(self) < 0) | ||
330 | return -1; | ||
331 | } | 374 | } |
332 | return -1; | 375 | return -1; |
333 | } | 376 | } |
@@ -353,13 +396,13 @@ unsigned int ui_browser__list_head_refresh(struct ui_browser *self) | |||
353 | return row; | 396 | return row; |
354 | } | 397 | } |
355 | 398 | ||
356 | static struct newtPercentTreeColors { | 399 | static struct ui_browser__colors { |
357 | const char *topColorFg, *topColorBg; | 400 | const char *topColorFg, *topColorBg; |
358 | const char *mediumColorFg, *mediumColorBg; | 401 | const char *mediumColorFg, *mediumColorBg; |
359 | const char *normalColorFg, *normalColorBg; | 402 | const char *normalColorFg, *normalColorBg; |
360 | const char *selColorFg, *selColorBg; | 403 | const char *selColorFg, *selColorBg; |
361 | const char *codeColorFg, *codeColorBg; | 404 | const char *codeColorFg, *codeColorBg; |
362 | } defaultPercentTreeColors = { | 405 | } ui_browser__default_colors = { |
363 | "red", "lightgray", | 406 | "red", "lightgray", |
364 | "green", "lightgray", | 407 | "green", "lightgray", |
365 | "black", "lightgray", | 408 | "black", "lightgray", |
@@ -369,7 +412,7 @@ static struct newtPercentTreeColors { | |||
369 | 412 | ||
370 | void ui_browser__init(void) | 413 | void ui_browser__init(void) |
371 | { | 414 | { |
372 | struct newtPercentTreeColors *c = &defaultPercentTreeColors; | 415 | struct ui_browser__colors *c = &ui_browser__default_colors; |
373 | 416 | ||
374 | sltt_set_color(HE_COLORSET_TOP, NULL, c->topColorFg, c->topColorBg); | 417 | sltt_set_color(HE_COLORSET_TOP, NULL, c->topColorFg, c->topColorBg); |
375 | sltt_set_color(HE_COLORSET_MEDIUM, NULL, c->mediumColorFg, c->mediumColorBg); | 418 | sltt_set_color(HE_COLORSET_MEDIUM, NULL, c->mediumColorFg, c->mediumColorBg); |