8 #include <sys/ttydefaults.h>
17 #if SLANG_VERSION < 20104
18 #define slsmg_printf(msg, args...) SLsmg_printf((char *)msg, ##args)
19 #define slsmg_write_nstring(msg, len) SLsmg_write_nstring((char *)msg, len)
20 #define sltt_set_color(obj, name, fg, bg) SLtt_set_color(obj,(char *)name,\
21 (char *)fg, (char *)bg)
23 #define slsmg_printf SLsmg_printf
24 #define slsmg_write_nstring SLsmg_write_nstring
25 #define sltt_set_color SLtt_set_color
29 newtComponent form, scale;
32 struct ui_progress *ui_progress__new(const char *title, u64 total)
34 struct ui_progress *self = malloc(sizeof(*self));
38 newtGetScreenSize(&cols, NULL);
40 newtCenteredWindow(cols, 1, title);
41 self->form = newtForm(NULL, NULL, 0);
42 if (self->form == NULL)
44 self->scale = newtScale(0, 0, cols, total);
45 if (self->scale == NULL)
47 newtFormAddComponent(self->form, self->scale);
54 newtFormDestroy(self->form);
60 void ui_progress__update(struct ui_progress *self, u64 curr)
62 newtScaleSet(self->scale, curr);
66 void ui_progress__delete(struct ui_progress *self)
68 newtFormDestroy(self->form);
73 static void ui_helpline__pop(void)
78 static void ui_helpline__push(const char *msg)
80 newtPushHelpLine(msg);
83 static void ui_helpline__vpush(const char *fmt, va_list ap)
87 if (vasprintf(&s, fmt, ap) < 0)
88 vfprintf(stderr, fmt, ap);
95 static void ui_helpline__fpush(const char *fmt, ...)
100 ui_helpline__vpush(fmt, ap);
104 static void ui_helpline__puts(const char *msg)
107 ui_helpline__push(msg);
110 static char browser__last_msg[1024];
112 int browser__show_help(const char *format, va_list ap)
117 ret = vsnprintf(browser__last_msg + backlog,
118 sizeof(browser__last_msg) - backlog, format, ap);
121 if (browser__last_msg[backlog - 1] == '\n') {
122 ui_helpline__puts(browser__last_msg);
130 static void newt_form__set_exit_keys(newtComponent self)
132 newtFormAddHotKey(self, NEWT_KEY_LEFT);
133 newtFormAddHotKey(self, NEWT_KEY_ESCAPE);
134 newtFormAddHotKey(self, 'Q');
135 newtFormAddHotKey(self, 'q');
136 newtFormAddHotKey(self, CTRL('c'));
139 static newtComponent newt_form__new(void)
141 newtComponent self = newtForm(NULL, NULL, 0);
143 newt_form__set_exit_keys(self);
147 static int popup_menu(int argc, char * const argv[])
149 struct newtExitStruct es;
150 int i, rc = -1, max_len = 5;
151 newtComponent listbox, form = newt_form__new();
156 listbox = newtListbox(0, 0, argc, NEWT_FLAG_RETURNEXIT);
158 goto out_destroy_form;
160 newtFormAddComponent(form, listbox);
162 for (i = 0; i < argc; ++i) {
163 int len = strlen(argv[i]);
166 if (newtListboxAddEntry(listbox, argv[i], (void *)(long)i))
167 goto out_destroy_form;
170 newtCenteredWindow(max_len, argc, NULL);
171 newtFormRun(form, &es);
172 rc = newtListboxGetCurrent(listbox) - NULL;
173 if (es.reason == NEWT_EXIT_HOTKEY)
177 newtFormDestroy(form);
181 static int ui__help_window(const char *text)
183 struct newtExitStruct es;
184 newtComponent tb, form = newt_form__new();
186 int max_len = 0, nr_lines = 0;
194 const char *sep = strchr(t, '\n');
198 sep = strchr(t, '\0');
208 tb = newtTextbox(0, 0, max_len, nr_lines, 0);
210 goto out_destroy_form;
212 newtTextboxSetText(tb, text);
213 newtFormAddComponent(form, tb);
214 newtCenteredWindow(max_len, nr_lines, NULL);
215 newtFormRun(form, &es);
219 newtFormDestroy(form);
223 static bool dialog_yesno(const char *msg)
225 /* newtWinChoice should really be accepting const char pointers... */
226 char yes[] = "Yes", no[] = "No";
227 return newtWinChoice(NULL, yes, no, (char *)msg) == 1;
230 #define HE_COLORSET_TOP 50
231 #define HE_COLORSET_MEDIUM 51
232 #define HE_COLORSET_NORMAL 52
233 #define HE_COLORSET_SELECTED 53
234 #define HE_COLORSET_CODE 54
236 static int ui_browser__percent_color(double percent, bool current)
239 return HE_COLORSET_SELECTED;
240 if (percent >= MIN_RED)
241 return HE_COLORSET_TOP;
242 if (percent >= MIN_GREEN)
243 return HE_COLORSET_MEDIUM;
244 return HE_COLORSET_NORMAL;
248 newtComponent form, sb;
249 u64 index, first_visible_entry_idx;
250 void *first_visible_entry, *entries;
251 u16 top, left, width, height;
256 static void ui_browser__refresh_dimensions(struct ui_browser *self)
259 newtGetScreenSize(&cols, &rows);
261 if (self->width > cols - 4)
262 self->width = cols - 4;
263 self->height = rows - 5;
264 if (self->height > self->nr_entries)
265 self->height = self->nr_entries;
266 self->top = (rows - self->height) / 2;
267 self->left = (cols - self->width) / 2;
270 static void ui_browser__reset_index(struct ui_browser *self)
272 self->index = self->first_visible_entry_idx = 0;
273 self->first_visible_entry = NULL;
276 static int objdump_line__show(struct objdump_line *self, struct list_head *head,
277 int width, struct hist_entry *he, int len,
280 if (self->offset != -1) {
281 struct symbol *sym = he->ms.sym;
282 unsigned int hits = 0;
283 double percent = 0.0;
285 struct sym_priv *priv = symbol__priv(sym);
286 struct sym_ext *sym_ext = priv->ext;
287 struct sym_hist *h = priv->hist;
288 s64 offset = self->offset;
289 struct objdump_line *next = objdump__get_next_ip_line(head, self);
291 while (offset < (s64)len &&
292 (next == NULL || offset < next->offset)) {
294 percent += sym_ext[offset].percent;
296 hits += h->ip[offset];
301 if (sym_ext == NULL && h->sum)
302 percent = 100.0 * hits / h->sum;
304 color = ui_browser__percent_color(percent, current_entry);
305 SLsmg_set_color(color);
306 slsmg_printf(" %7.2f ", percent);
308 SLsmg_set_color(HE_COLORSET_CODE);
310 int color = ui_browser__percent_color(0, current_entry);
311 SLsmg_set_color(color);
312 slsmg_write_nstring(" ", 9);
315 SLsmg_write_char(':');
316 slsmg_write_nstring(" ", 8);
318 slsmg_write_nstring(" ", width - 18);
320 slsmg_write_nstring(self->line, width - 18);
325 static int ui_browser__refresh_entries(struct ui_browser *self)
327 struct objdump_line *pos;
328 struct list_head *head = self->entries;
329 struct hist_entry *he = self->priv;
331 int len = he->ms.sym->end - he->ms.sym->start;
333 if (self->first_visible_entry == NULL || self->first_visible_entry == self->entries)
334 self->first_visible_entry = head->next;
336 pos = list_entry(self->first_visible_entry, struct objdump_line, node);
338 list_for_each_entry_from(pos, head, node) {
339 bool current_entry = (self->first_visible_entry_idx + row) == self->index;
340 SLsmg_gotorc(self->top + row, self->left);
341 objdump_line__show(pos, head, self->width,
342 he, len, current_entry);
343 if (++row == self->height)
347 SLsmg_set_color(HE_COLORSET_NORMAL);
348 SLsmg_fill_region(self->top + row, self->left,
349 self->height - row, self->width, ' ');
354 static int ui_browser__run(struct ui_browser *self, const char *title,
355 struct newtExitStruct *es)
358 newtFormDestroy(self->form);
362 ui_browser__refresh_dimensions(self);
363 newtCenteredWindow(self->width + 2, self->height, title);
364 self->form = newt_form__new();
365 if (self->form == NULL)
368 self->sb = newtVerticalScrollbar(self->width + 1, 0, self->height,
370 HE_COLORSET_SELECTED);
371 if (self->sb == NULL)
374 newtFormAddHotKey(self->form, NEWT_KEY_UP);
375 newtFormAddHotKey(self->form, NEWT_KEY_DOWN);
376 newtFormAddHotKey(self->form, NEWT_KEY_PGUP);
377 newtFormAddHotKey(self->form, NEWT_KEY_PGDN);
378 newtFormAddHotKey(self->form, NEWT_KEY_HOME);
379 newtFormAddHotKey(self->form, NEWT_KEY_END);
381 if (ui_browser__refresh_entries(self) < 0)
383 newtFormAddComponent(self->form, self->sb);
388 newtFormRun(self->form, es);
390 if (es->reason != NEWT_EXIT_HOTKEY)
394 if (self->index == self->nr_entries - 1)
397 if (self->index == self->first_visible_entry_idx + self->height) {
398 struct list_head *pos = self->first_visible_entry;
399 ++self->first_visible_entry_idx;
400 self->first_visible_entry = pos->next;
404 if (self->index == 0)
407 if (self->index < self->first_visible_entry_idx) {
408 struct list_head *pos = self->first_visible_entry;
409 --self->first_visible_entry_idx;
410 self->first_visible_entry = pos->prev;
414 if (self->first_visible_entry_idx + self->height > self->nr_entries - 1)
417 offset = self->height;
418 if (self->index + offset > self->nr_entries - 1)
419 offset = self->nr_entries - 1 - self->index;
420 self->index += offset;
421 self->first_visible_entry_idx += offset;
424 struct list_head *pos = self->first_visible_entry;
425 self->first_visible_entry = pos->next;
430 if (self->first_visible_entry_idx == 0)
433 if (self->first_visible_entry_idx < self->height)
434 offset = self->first_visible_entry_idx;
436 offset = self->height;
438 self->index -= offset;
439 self->first_visible_entry_idx -= offset;
442 struct list_head *pos = self->first_visible_entry;
443 self->first_visible_entry = pos->prev;
447 ui_browser__reset_index(self);
450 struct list_head *head = self->entries;
451 offset = self->height - 1;
453 if (offset > self->nr_entries)
454 offset = self->nr_entries;
456 self->index = self->first_visible_entry_idx = self->nr_entries - 1 - offset;
457 self->first_visible_entry = head->prev;
458 while (offset-- != 0) {
459 struct list_head *pos = self->first_visible_entry;
460 self->first_visible_entry = pos->prev;
464 case NEWT_KEY_ESCAPE:
473 if (ui_browser__refresh_entries(self) < 0)
480 * When debugging newt problems it was useful to be able to "unroll"
481 * the calls to newtCheckBoxTreeAdd{Array,Item}, so that we can generate
482 * a source file with the sequence of calls to these methods, to then
483 * tweak the arrays to get the intended results, so I'm keeping this code
484 * here, may be useful again in the future.
488 static void newt_checkbox_tree__add(newtComponent tree, const char *str,
489 void *priv, int *indexes)
492 /* Print the newtCheckboxTreeAddArray to tinker with its index arrays */
493 int i = 0, len = 40 - strlen(str);
496 "\tnewtCheckboxTreeAddItem(tree, %*.*s\"%s\", (void *)%p, 0, ",
497 len, len, " ", str, priv);
498 while (indexes[i] != NEWT_ARG_LAST) {
499 if (indexes[i] != NEWT_ARG_APPEND)
500 fprintf(stderr, " %d,", indexes[i]);
502 fprintf(stderr, " %s,", "NEWT_ARG_APPEND");
505 fprintf(stderr, " %s", " NEWT_ARG_LAST);\n");
508 newtCheckboxTreeAddArray(tree, str, priv, 0, indexes);
511 static char *callchain_list__sym_name(struct callchain_list *self,
512 char *bf, size_t bfsize)
515 return self->ms.sym->name;
517 snprintf(bf, bfsize, "%#Lx", self->ip);
521 static void __callchain__append_graph_browser(struct callchain_node *self,
522 newtComponent tree, u64 total,
523 int *indexes, int depth)
525 struct rb_node *node;
526 u64 new_total, remaining;
529 if (callchain_param.mode == CHAIN_GRAPH_REL)
530 new_total = self->children_hit;
534 remaining = new_total;
535 node = rb_first(&self->rb_root);
537 struct callchain_node *child = rb_entry(node, struct callchain_node, rb_node);
538 struct rb_node *next = rb_next(node);
539 u64 cumul = cumul_hits(child);
540 struct callchain_list *chain;
541 int first = true, printed = 0;
545 indexes[depth] = NEWT_ARG_APPEND;
546 indexes[depth + 1] = NEWT_ARG_LAST;
548 list_for_each_entry(chain, &child->val, list) {
549 char ipstr[BITS_PER_LONG / 4 + 1],
551 const char *str = callchain_list__sym_name(chain, ipstr, sizeof(ipstr));
554 double percent = cumul * 100.0 / new_total;
557 if (asprintf(&alloc_str, "%2.2f%% %s", percent, str) < 0)
558 str = "Not enough memory!";
562 indexes[depth] = idx;
563 indexes[depth + 1] = NEWT_ARG_APPEND;
564 indexes[depth + 2] = NEWT_ARG_LAST;
567 newt_checkbox_tree__add(tree, str, &chain->ms, indexes);
572 indexes[depth] = idx;
574 indexes[depth + 1] = chain_idx;
577 __callchain__append_graph_browser(child, tree, new_total, indexes,
578 depth + (chain_idx != -1 ? 2 : 1));
583 static void callchain__append_graph_browser(struct callchain_node *self,
584 newtComponent tree, u64 total,
585 int *indexes, int parent_idx)
587 struct callchain_list *chain;
590 indexes[1] = NEWT_ARG_APPEND;
591 indexes[2] = NEWT_ARG_LAST;
593 list_for_each_entry(chain, &self->val, list) {
594 char ipstr[BITS_PER_LONG / 4 + 1], *str;
596 if (chain->ip >= PERF_CONTEXT_MAX)
599 if (!i++ && sort__first_dimension == SORT_SYM)
602 str = callchain_list__sym_name(chain, ipstr, sizeof(ipstr));
603 newt_checkbox_tree__add(tree, str, &chain->ms, indexes);
606 indexes[1] = parent_idx;
607 indexes[2] = NEWT_ARG_APPEND;
608 indexes[3] = NEWT_ARG_LAST;
609 __callchain__append_graph_browser(self, tree, total, indexes, 2);
612 static void hist_entry__append_callchain_browser(struct hist_entry *self,
613 newtComponent tree, u64 total, int parent_idx)
615 struct rb_node *rb_node;
616 int indexes[1024] = { [0] = parent_idx, };
618 struct callchain_node *chain;
620 rb_node = rb_first(&self->sorted_chain);
622 chain = rb_entry(rb_node, struct callchain_node, rb_node);
623 switch (callchain_param.mode) {
626 case CHAIN_GRAPH_ABS: /* falldown */
627 case CHAIN_GRAPH_REL:
628 callchain__append_graph_browser(chain, tree, total, indexes, idx++);
634 rb_node = rb_next(rb_node);
638 static size_t hist_entry__append_browser(struct hist_entry *self,
639 newtComponent tree, u64 total)
644 if (symbol_conf.exclude_other && !self->parent)
647 ret = hist_entry__snprintf(self, s, sizeof(s), NULL,
648 false, 0, false, total);
649 if (symbol_conf.use_callchain) {
652 indexes[0] = NEWT_ARG_APPEND;
653 indexes[1] = NEWT_ARG_LAST;
654 newt_checkbox_tree__add(tree, s, &self->ms, indexes);
656 newtListboxAppendEntry(tree, s, &self->ms);
661 static void hist_entry__annotate_browser(struct hist_entry *self)
663 struct ui_browser browser;
664 struct newtExitStruct es;
665 struct objdump_line *pos, *n;
668 if (self->ms.sym == NULL)
671 if (hist_entry__annotate(self, &head) < 0)
674 ui_helpline__push("Press <- or ESC to exit");
676 memset(&browser, 0, sizeof(browser));
677 browser.entries = &head;
679 list_for_each_entry(pos, &head, node) {
680 size_t line_len = strlen(pos->line);
681 if (browser.width < line_len)
682 browser.width = line_len;
683 ++browser.nr_entries;
686 browser.width += 18; /* Percentage */
687 ui_browser__run(&browser, self->ms.sym->name, &es);
688 newtFormDestroy(browser.form);
690 list_for_each_entry_safe(pos, n, &head, node) {
691 list_del(&pos->node);
692 objdump_line__free(pos);
697 static const void *newt__symbol_tree_get_current(newtComponent self)
699 if (symbol_conf.use_callchain)
700 return newtCheckboxTreeGetCurrent(self);
701 return newtListboxGetCurrent(self);
704 static void hist_browser__selection(newtComponent self, void *data)
706 const struct map_symbol **symbol_ptr = data;
707 *symbol_ptr = newt__symbol_tree_get_current(self);
710 struct hist_browser {
711 newtComponent form, tree;
712 const struct map_symbol *selection;
715 static struct hist_browser *hist_browser__new(void)
717 struct hist_browser *self = malloc(sizeof(*self));
725 static void hist_browser__delete(struct hist_browser *self)
727 newtFormDestroy(self->form);
732 static int hist_browser__populate(struct hist_browser *self, struct hists *hists,
735 int max_len = 0, idx, cols, rows;
736 struct ui_progress *progress;
739 char seq[] = ".", unit;
741 unsigned long nr_events = hists->stats.nr_events[PERF_RECORD_SAMPLE];
744 newtFormDestroy(self->form);
748 nr_events = convert_unit(nr_events, &unit);
749 snprintf(str, sizeof(str), "Events: %lu%c ",
751 newtDrawRootText(0, 0, str);
753 newtGetScreenSize(NULL, &rows);
755 if (symbol_conf.use_callchain)
756 self->tree = newtCheckboxTreeMulti(0, 0, rows - 5, seq,
759 self->tree = newtListbox(0, 0, rows - 5,
761 NEWT_FLAG_RETURNEXIT));
763 newtComponentAddCallback(self->tree, hist_browser__selection,
766 progress = ui_progress__new("Adding entries to the browser...",
768 if (progress == NULL)
772 for (nd = rb_first(&hists->entries); nd; nd = rb_next(nd)) {
773 struct hist_entry *h = rb_entry(nd, struct hist_entry, rb_node);
779 len = hist_entry__append_browser(h, self->tree, hists->stats.total_period);
782 if (symbol_conf.use_callchain)
783 hist_entry__append_callchain_browser(h, self->tree,
784 hists->stats.total_period, idx++);
787 ui_progress__update(progress, curr_hist);
790 ui_progress__delete(progress);
792 newtGetScreenSize(&cols, &rows);
797 if (!symbol_conf.use_callchain)
798 newtListboxSetWidth(self->tree, max_len);
800 newtCenteredWindow(max_len + (symbol_conf.use_callchain ? 5 : 0),
802 self->form = newt_form__new();
803 if (self->form == NULL)
806 newtFormAddHotKey(self->form, 'A');
807 newtFormAddHotKey(self->form, 'a');
808 newtFormAddHotKey(self->form, 'D');
809 newtFormAddHotKey(self->form, 'd');
810 newtFormAddHotKey(self->form, 'T');
811 newtFormAddHotKey(self->form, 't');
812 newtFormAddHotKey(self->form, '?');
813 newtFormAddHotKey(self->form, 'H');
814 newtFormAddHotKey(self->form, 'h');
815 newtFormAddHotKey(self->form, NEWT_KEY_F1);
816 newtFormAddHotKey(self->form, NEWT_KEY_RIGHT);
817 newtFormAddComponents(self->form, self->tree, NULL);
818 self->selection = newt__symbol_tree_get_current(self->tree);
823 static struct hist_entry *hist_browser__selected_entry(struct hist_browser *self)
827 if (!symbol_conf.use_callchain)
830 indexes = newtCheckboxTreeFindItem(self->tree, (void *)self->selection);
832 bool is_hist_entry = indexes[1] == NEWT_ARG_LAST;
839 return container_of(self->selection, struct hist_entry, ms);
842 static struct thread *hist_browser__selected_thread(struct hist_browser *self)
844 struct hist_entry *he = hist_browser__selected_entry(self);
845 return he ? he->thread : NULL;
848 static int hist_browser__title(char *bf, size_t size, const char *input_name,
849 const struct dso *dso, const struct thread *thread)
854 printed += snprintf(bf + printed, size - printed,
856 (thread->comm_set ? thread->comm : ""),
859 printed += snprintf(bf + printed, size - printed,
860 "%sDSO: %s", thread ? " " : "",
862 return printed ?: snprintf(bf, size, "Report: %s", input_name);
865 int hists__browse(struct hists *self, const char *helpline, const char *input_name)
867 struct hist_browser *browser = hist_browser__new();
868 struct pstack *fstack = pstack__new(2);
869 const struct thread *thread_filter = NULL;
870 const struct dso *dso_filter = NULL;
871 struct newtExitStruct es;
878 fstack = pstack__new(2);
882 ui_helpline__push(helpline);
884 hist_browser__title(msg, sizeof(msg), input_name,
885 dso_filter, thread_filter);
886 if (hist_browser__populate(browser, self, msg) < 0)
890 const struct thread *thread;
891 const struct dso *dso;
893 int nr_options = 0, choice = 0, i,
894 annotate = -2, zoom_dso = -2, zoom_thread = -2;
896 newtFormRun(browser->form, &es);
898 thread = hist_browser__selected_thread(browser);
899 dso = browser->selection->map ? browser->selection->map->dso : NULL;
901 if (es.reason == NEWT_EXIT_HOTKEY) {
902 if (es.u.key == NEWT_KEY_F1)
905 switch (toupper(es.u.key)) {
915 ui__help_window("-> Zoom into DSO/Threads & Annotate current symbol\n"
917 "a Annotate current symbol\n"
918 "h/?/F1 Show this window\n"
919 "d Zoom into current DSO\n"
920 "t Zoom into current Thread\n"
921 "q/CTRL+C Exit browser");
925 if (toupper(es.u.key) == 'Q' ||
926 es.u.key == CTRL('c'))
928 if (es.u.key == NEWT_KEY_ESCAPE) {
929 if (dialog_yesno("Do you really want to exit?"))
935 if (es.u.key == NEWT_KEY_LEFT) {
938 if (pstack__empty(fstack))
940 top = pstack__pop(fstack);
941 if (top == &dso_filter)
943 if (top == &thread_filter)
944 goto zoom_out_thread;
949 if (browser->selection->sym != NULL &&
950 asprintf(&options[nr_options], "Annotate %s",
951 browser->selection->sym->name) > 0)
952 annotate = nr_options++;
954 if (thread != NULL &&
955 asprintf(&options[nr_options], "Zoom %s %s(%d) thread",
956 (thread_filter ? "out of" : "into"),
957 (thread->comm_set ? thread->comm : ""),
959 zoom_thread = nr_options++;
962 asprintf(&options[nr_options], "Zoom %s %s DSO",
963 (dso_filter ? "out of" : "into"),
964 (dso->kernel ? "the Kernel" : dso->short_name)) > 0)
965 zoom_dso = nr_options++;
967 options[nr_options++] = (char *)"Exit";
969 choice = popup_menu(nr_options, options);
971 for (i = 0; i < nr_options - 1; ++i)
974 if (choice == nr_options - 1)
980 if (choice == annotate) {
981 struct hist_entry *he;
983 if (browser->selection->map->dso->origin == DSO__ORIG_KERNEL) {
984 ui_helpline__puts("No vmlinux file found, can't "
985 "annotate with just a "
990 he = hist_browser__selected_entry(browser);
994 hist_entry__annotate_browser(he);
995 } else if (choice == zoom_dso) {
998 pstack__remove(fstack, &dso_filter);
1005 ui_helpline__fpush("To zoom out press <- or -> + \"Zoom out of %s DSO\"",
1006 dso->kernel ? "the Kernel" : dso->short_name);
1008 pstack__push(fstack, &dso_filter);
1010 hists__filter_by_dso(self, dso_filter);
1011 hist_browser__title(msg, sizeof(msg), input_name,
1012 dso_filter, thread_filter);
1013 if (hist_browser__populate(browser, self, msg) < 0)
1015 } else if (choice == zoom_thread) {
1017 if (thread_filter) {
1018 pstack__remove(fstack, &thread_filter);
1021 thread_filter = NULL;
1023 ui_helpline__fpush("To zoom out press <- or -> + \"Zoom out of %s(%d) thread\"",
1024 thread->comm_set ? thread->comm : "",
1026 thread_filter = thread;
1027 pstack__push(fstack, &thread_filter);
1029 hists__filter_by_thread(self, thread_filter);
1030 hist_browser__title(msg, sizeof(msg), input_name,
1031 dso_filter, thread_filter);
1032 if (hist_browser__populate(browser, self, msg) < 0)
1038 pstack__delete(fstack);
1040 hist_browser__delete(browser);
1044 static struct newtPercentTreeColors {
1045 const char *topColorFg, *topColorBg;
1046 const char *mediumColorFg, *mediumColorBg;
1047 const char *normalColorFg, *normalColorBg;
1048 const char *selColorFg, *selColorBg;
1049 const char *codeColorFg, *codeColorBg;
1050 } defaultPercentTreeColors = {
1052 "green", "lightgray",
1053 "black", "lightgray",
1054 "lightgray", "magenta",
1055 "blue", "lightgray",
1058 void setup_browser(void)
1060 struct newtPercentTreeColors *c = &defaultPercentTreeColors;
1067 ui_helpline__puts(" ");
1068 sltt_set_color(HE_COLORSET_TOP, NULL, c->topColorFg, c->topColorBg);
1069 sltt_set_color(HE_COLORSET_MEDIUM, NULL, c->mediumColorFg, c->mediumColorBg);
1070 sltt_set_color(HE_COLORSET_NORMAL, NULL, c->normalColorFg, c->normalColorBg);
1071 sltt_set_color(HE_COLORSET_SELECTED, NULL, c->selColorFg, c->selColorBg);
1072 sltt_set_color(HE_COLORSET_CODE, NULL, c->codeColorFg, c->codeColorBg);
1075 void exit_browser(bool wait_for_ok)
1079 char title[] = "Fatal Error", ok[] = "Ok";
1080 newtWinMessage(title, ok, browser__last_msg);