e74df1240ef64c0525d532e2fadb48890d412095
8 #include <sys/ttydefaults.h>
18 newtComponent form
, scale
;
21 struct ui_progress
*ui_progress__new(const char *title
, u64 total
)
23 struct ui_progress
*self
= malloc(sizeof(*self
));
27 newtGetScreenSize(&cols
, NULL
);
29 newtCenteredWindow(cols
, 1, title
);
30 self
->form
= newtForm(NULL
, NULL
, 0);
31 if (self
->form
== NULL
)
33 self
->scale
= newtScale(0, 0, cols
, total
);
34 if (self
->scale
== NULL
)
36 newtFormAddComponent(self
->form
, self
->scale
);
43 newtFormDestroy(self
->form
);
49 void ui_progress__update(struct ui_progress
*self
, u64 curr
)
51 newtScaleSet(self
->scale
, curr
);
55 void ui_progress__delete(struct ui_progress
*self
)
57 newtFormDestroy(self
->form
);
62 static void ui_helpline__pop(void)
67 static void ui_helpline__push(const char *msg
)
69 newtPushHelpLine(msg
);
72 static void ui_helpline__vpush(const char *fmt
, va_list ap
)
76 if (vasprintf(&s
, fmt
, ap
) < 0)
77 vfprintf(stderr
, fmt
, ap
);
84 static void ui_helpline__fpush(const char *fmt
, ...)
89 ui_helpline__vpush(fmt
, ap
);
93 static void ui_helpline__puts(const char *msg
)
96 ui_helpline__push(msg
);
99 static char browser__last_msg
[1024];
101 int browser__show_help(const char *format
, va_list ap
)
106 ret
= vsnprintf(browser__last_msg
+ backlog
,
107 sizeof(browser__last_msg
) - backlog
, format
, ap
);
110 if (browser__last_msg
[backlog
- 1] == '\n') {
111 ui_helpline__puts(browser__last_msg
);
119 static void newt_form__set_exit_keys(newtComponent self
)
121 newtFormAddHotKey(self
, NEWT_KEY_ESCAPE
);
122 newtFormAddHotKey(self
, 'Q');
123 newtFormAddHotKey(self
, 'q');
124 newtFormAddHotKey(self
, CTRL('c'));
127 static newtComponent
newt_form__new(void)
129 newtComponent self
= newtForm(NULL
, NULL
, 0);
131 newt_form__set_exit_keys(self
);
135 static int popup_menu(int argc
, char * const argv
[])
137 struct newtExitStruct es
;
138 int i
, rc
= -1, max_len
= 5;
139 newtComponent listbox
, form
= newt_form__new();
144 listbox
= newtListbox(0, 0, argc
, NEWT_FLAG_RETURNEXIT
);
146 goto out_destroy_form
;
148 newtFormAddComponent(form
, listbox
);
150 for (i
= 0; i
< argc
; ++i
) {
151 int len
= strlen(argv
[i
]);
154 if (newtListboxAddEntry(listbox
, argv
[i
], (void *)(long)i
))
155 goto out_destroy_form
;
158 newtCenteredWindow(max_len
, argc
, NULL
);
159 newtFormRun(form
, &es
);
160 rc
= newtListboxGetCurrent(listbox
) - NULL
;
161 if (es
.reason
== NEWT_EXIT_HOTKEY
)
165 newtFormDestroy(form
);
169 static bool dialog_yesno(const char *msg
)
171 /* newtWinChoice should really be accepting const char pointers... */
172 char yes
[] = "Yes", no
[] = "No";
173 return newtWinChoice(NULL
, yes
, no
, (char *)msg
) == 1;
176 #define HE_COLORSET_TOP 50
177 #define HE_COLORSET_MEDIUM 51
178 #define HE_COLORSET_NORMAL 52
179 #define HE_COLORSET_SELECTED 53
180 #define HE_COLORSET_CODE 54
182 static int ui_browser__percent_color(double percent
, bool current
)
185 return HE_COLORSET_SELECTED
;
186 if (percent
>= MIN_RED
)
187 return HE_COLORSET_TOP
;
188 if (percent
>= MIN_GREEN
)
189 return HE_COLORSET_MEDIUM
;
190 return HE_COLORSET_NORMAL
;
194 newtComponent form
, sb
;
195 u64 index
, first_visible_entry_idx
;
196 void *first_visible_entry
, *entries
;
197 u16 top
, left
, width
, height
;
202 static void ui_browser__refresh_dimensions(struct ui_browser
*self
)
205 newtGetScreenSize(&cols
, &rows
);
207 if (self
->width
> cols
- 4)
208 self
->width
= cols
- 4;
209 self
->height
= rows
- 5;
210 if (self
->height
> self
->nr_entries
)
211 self
->height
= self
->nr_entries
;
212 self
->top
= (rows
- self
->height
) / 2;
213 self
->left
= (cols
- self
->width
) / 2;
216 static void ui_browser__reset_index(struct ui_browser
*self
)
218 self
->index
= self
->first_visible_entry_idx
= 0;
219 self
->first_visible_entry
= NULL
;
222 static int objdump_line__show(struct objdump_line
*self
, struct list_head
*head
,
223 int width
, struct hist_entry
*he
, int len
,
226 if (self
->offset
!= -1) {
227 struct symbol
*sym
= he
->ms
.sym
;
228 unsigned int hits
= 0;
229 double percent
= 0.0;
231 struct sym_priv
*priv
= symbol__priv(sym
);
232 struct sym_ext
*sym_ext
= priv
->ext
;
233 struct sym_hist
*h
= priv
->hist
;
234 s64 offset
= self
->offset
;
235 struct objdump_line
*next
= objdump__get_next_ip_line(head
, self
);
237 while (offset
< (s64
)len
&&
238 (next
== NULL
|| offset
< next
->offset
)) {
240 percent
+= sym_ext
[offset
].percent
;
242 hits
+= h
->ip
[offset
];
247 if (sym_ext
== NULL
&& h
->sum
)
248 percent
= 100.0 * hits
/ h
->sum
;
250 color
= ui_browser__percent_color(percent
, current_entry
);
251 SLsmg_set_color(color
);
252 SLsmg_printf(" %7.2f ", percent
);
254 SLsmg_set_color(HE_COLORSET_CODE
);
256 int color
= ui_browser__percent_color(0, current_entry
);
257 SLsmg_set_color(color
);
258 SLsmg_write_nstring(" ", 9);
261 SLsmg_write_char(':');
262 SLsmg_write_nstring(" ", 8);
264 SLsmg_write_nstring(" ", width
- 18);
266 SLsmg_write_nstring(self
->line
, width
- 18);
271 static int ui_browser__refresh_entries(struct ui_browser
*self
)
273 struct objdump_line
*pos
;
274 struct list_head
*head
= self
->entries
;
275 struct hist_entry
*he
= self
->priv
;
277 int len
= he
->ms
.sym
->end
- he
->ms
.sym
->start
;
279 if (self
->first_visible_entry
== NULL
|| self
->first_visible_entry
== self
->entries
)
280 self
->first_visible_entry
= head
->next
;
282 pos
= list_entry(self
->first_visible_entry
, struct objdump_line
, node
);
284 list_for_each_entry_from(pos
, head
, node
) {
285 bool current_entry
= (self
->first_visible_entry_idx
+ row
) == self
->index
;
286 SLsmg_gotorc(self
->top
+ row
, self
->left
);
287 objdump_line__show(pos
, head
, self
->width
,
288 he
, len
, current_entry
);
289 if (++row
== self
->height
)
293 SLsmg_set_color(HE_COLORSET_NORMAL
);
294 SLsmg_fill_region(self
->top
+ row
, self
->left
,
295 self
->height
- row
, self
->width
, ' ');
300 static int ui_browser__run(struct ui_browser
*self
, const char *title
,
301 struct newtExitStruct
*es
)
304 newtFormDestroy(self
->form
);
308 ui_browser__refresh_dimensions(self
);
309 newtCenteredWindow(self
->width
+ 2, self
->height
, title
);
310 self
->form
= newt_form__new();
311 if (self
->form
== NULL
)
314 self
->sb
= newtVerticalScrollbar(self
->width
+ 1, 0, self
->height
,
316 HE_COLORSET_SELECTED
);
317 if (self
->sb
== NULL
)
320 newtFormAddHotKey(self
->form
, NEWT_KEY_UP
);
321 newtFormAddHotKey(self
->form
, NEWT_KEY_DOWN
);
322 newtFormAddHotKey(self
->form
, NEWT_KEY_PGUP
);
323 newtFormAddHotKey(self
->form
, NEWT_KEY_PGDN
);
324 newtFormAddHotKey(self
->form
, NEWT_KEY_HOME
);
325 newtFormAddHotKey(self
->form
, NEWT_KEY_END
);
327 if (ui_browser__refresh_entries(self
) < 0)
329 newtFormAddComponent(self
->form
, self
->sb
);
334 newtFormRun(self
->form
, es
);
336 if (es
->reason
!= NEWT_EXIT_HOTKEY
)
340 if (self
->index
== self
->nr_entries
- 1)
343 if (self
->index
== self
->first_visible_entry_idx
+ self
->height
) {
344 struct list_head
*pos
= self
->first_visible_entry
;
345 ++self
->first_visible_entry_idx
;
346 self
->first_visible_entry
= pos
->next
;
350 if (self
->index
== 0)
353 if (self
->index
< self
->first_visible_entry_idx
) {
354 struct list_head
*pos
= self
->first_visible_entry
;
355 --self
->first_visible_entry_idx
;
356 self
->first_visible_entry
= pos
->prev
;
360 if (self
->first_visible_entry_idx
+ self
->height
> self
->nr_entries
- 1)
363 offset
= self
->height
;
364 if (self
->index
+ offset
> self
->nr_entries
- 1)
365 offset
= self
->nr_entries
- 1 - self
->index
;
366 self
->index
+= offset
;
367 self
->first_visible_entry_idx
+= offset
;
370 struct list_head
*pos
= self
->first_visible_entry
;
371 self
->first_visible_entry
= pos
->next
;
376 if (self
->first_visible_entry_idx
== 0)
379 if (self
->first_visible_entry_idx
< self
->height
)
380 offset
= self
->first_visible_entry_idx
;
382 offset
= self
->height
;
384 self
->index
-= offset
;
385 self
->first_visible_entry_idx
-= offset
;
388 struct list_head
*pos
= self
->first_visible_entry
;
389 self
->first_visible_entry
= pos
->prev
;
393 ui_browser__reset_index(self
);
396 struct list_head
*head
= self
->entries
;
397 offset
= self
->height
- 1;
399 if (offset
> self
->nr_entries
)
400 offset
= self
->nr_entries
;
402 self
->index
= self
->first_visible_entry_idx
= self
->nr_entries
- 1 - offset
;
403 self
->first_visible_entry
= head
->prev
;
404 while (offset
-- != 0) {
405 struct list_head
*pos
= self
->first_visible_entry
;
406 self
->first_visible_entry
= pos
->prev
;
410 case NEWT_KEY_ESCAPE
:
418 if (ui_browser__refresh_entries(self
) < 0)
425 * When debugging newt problems it was useful to be able to "unroll"
426 * the calls to newtCheckBoxTreeAdd{Array,Item}, so that we can generate
427 * a source file with the sequence of calls to these methods, to then
428 * tweak the arrays to get the intended results, so I'm keeping this code
429 * here, may be useful again in the future.
433 static void newt_checkbox_tree__add(newtComponent tree
, const char *str
,
434 void *priv
, int *indexes
)
437 /* Print the newtCheckboxTreeAddArray to tinker with its index arrays */
438 int i
= 0, len
= 40 - strlen(str
);
441 "\tnewtCheckboxTreeAddItem(tree, %*.*s\"%s\", (void *)%p, 0, ",
442 len
, len
, " ", str
, priv
);
443 while (indexes
[i
] != NEWT_ARG_LAST
) {
444 if (indexes
[i
] != NEWT_ARG_APPEND
)
445 fprintf(stderr
, " %d,", indexes
[i
]);
447 fprintf(stderr
, " %s,", "NEWT_ARG_APPEND");
450 fprintf(stderr
, " %s", " NEWT_ARG_LAST);\n");
453 newtCheckboxTreeAddArray(tree
, str
, priv
, 0, indexes
);
456 static char *callchain_list__sym_name(struct callchain_list
*self
,
457 char *bf
, size_t bfsize
)
460 return self
->ms
.sym
->name
;
462 snprintf(bf
, bfsize
, "%#Lx", self
->ip
);
466 static void __callchain__append_graph_browser(struct callchain_node
*self
,
467 newtComponent tree
, u64 total
,
468 int *indexes
, int depth
)
470 struct rb_node
*node
;
471 u64 new_total
, remaining
;
474 if (callchain_param
.mode
== CHAIN_GRAPH_REL
)
475 new_total
= self
->children_hit
;
479 remaining
= new_total
;
480 node
= rb_first(&self
->rb_root
);
482 struct callchain_node
*child
= rb_entry(node
, struct callchain_node
, rb_node
);
483 struct rb_node
*next
= rb_next(node
);
484 u64 cumul
= cumul_hits(child
);
485 struct callchain_list
*chain
;
486 int first
= true, printed
= 0;
490 indexes
[depth
] = NEWT_ARG_APPEND
;
491 indexes
[depth
+ 1] = NEWT_ARG_LAST
;
493 list_for_each_entry(chain
, &child
->val
, list
) {
494 char ipstr
[BITS_PER_LONG
/ 4 + 1],
496 const char *str
= callchain_list__sym_name(chain
, ipstr
, sizeof(ipstr
));
499 double percent
= cumul
* 100.0 / new_total
;
502 if (asprintf(&alloc_str
, "%2.2f%% %s", percent
, str
) < 0)
503 str
= "Not enough memory!";
507 indexes
[depth
] = idx
;
508 indexes
[depth
+ 1] = NEWT_ARG_APPEND
;
509 indexes
[depth
+ 2] = NEWT_ARG_LAST
;
512 newt_checkbox_tree__add(tree
, str
, &chain
->ms
, indexes
);
517 indexes
[depth
] = idx
;
519 indexes
[depth
+ 1] = chain_idx
;
522 __callchain__append_graph_browser(child
, tree
, new_total
, indexes
,
523 depth
+ (chain_idx
!= -1 ? 2 : 1));
528 static void callchain__append_graph_browser(struct callchain_node
*self
,
529 newtComponent tree
, u64 total
,
530 int *indexes
, int parent_idx
)
532 struct callchain_list
*chain
;
535 indexes
[1] = NEWT_ARG_APPEND
;
536 indexes
[2] = NEWT_ARG_LAST
;
538 list_for_each_entry(chain
, &self
->val
, list
) {
539 char ipstr
[BITS_PER_LONG
/ 4 + 1], *str
;
541 if (chain
->ip
>= PERF_CONTEXT_MAX
)
544 if (!i
++ && sort__first_dimension
== SORT_SYM
)
547 str
= callchain_list__sym_name(chain
, ipstr
, sizeof(ipstr
));
548 newt_checkbox_tree__add(tree
, str
, &chain
->ms
, indexes
);
551 indexes
[1] = parent_idx
;
552 indexes
[2] = NEWT_ARG_APPEND
;
553 indexes
[3] = NEWT_ARG_LAST
;
554 __callchain__append_graph_browser(self
, tree
, total
, indexes
, 2);
557 static void hist_entry__append_callchain_browser(struct hist_entry
*self
,
558 newtComponent tree
, u64 total
, int parent_idx
)
560 struct rb_node
*rb_node
;
561 int indexes
[1024] = { [0] = parent_idx
, };
563 struct callchain_node
*chain
;
565 rb_node
= rb_first(&self
->sorted_chain
);
567 chain
= rb_entry(rb_node
, struct callchain_node
, rb_node
);
568 switch (callchain_param
.mode
) {
571 case CHAIN_GRAPH_ABS
: /* falldown */
572 case CHAIN_GRAPH_REL
:
573 callchain__append_graph_browser(chain
, tree
, total
, indexes
, idx
++);
579 rb_node
= rb_next(rb_node
);
583 static size_t hist_entry__append_browser(struct hist_entry
*self
,
584 newtComponent tree
, u64 total
)
589 if (symbol_conf
.exclude_other
&& !self
->parent
)
592 ret
= hist_entry__snprintf(self
, s
, sizeof(s
), NULL
,
593 false, 0, false, total
);
594 if (symbol_conf
.use_callchain
) {
597 indexes
[0] = NEWT_ARG_APPEND
;
598 indexes
[1] = NEWT_ARG_LAST
;
599 newt_checkbox_tree__add(tree
, s
, &self
->ms
, indexes
);
601 newtListboxAppendEntry(tree
, s
, &self
->ms
);
606 static void hist_entry__annotate_browser(struct hist_entry
*self
)
608 struct ui_browser browser
;
609 struct newtExitStruct es
;
610 struct objdump_line
*pos
, *n
;
613 if (self
->ms
.sym
== NULL
)
616 if (hist_entry__annotate(self
, &head
) < 0)
619 ui_helpline__push("Press ESC to exit");
621 memset(&browser
, 0, sizeof(browser
));
622 browser
.entries
= &head
;
624 list_for_each_entry(pos
, &head
, node
) {
625 size_t line_len
= strlen(pos
->line
);
626 if (browser
.width
< line_len
)
627 browser
.width
= line_len
;
628 ++browser
.nr_entries
;
631 browser
.width
+= 18; /* Percentage */
632 ui_browser__run(&browser
, self
->ms
.sym
->name
, &es
);
633 newtFormDestroy(browser
.form
);
635 list_for_each_entry_safe(pos
, n
, &head
, node
) {
636 list_del(&pos
->node
);
637 objdump_line__free(pos
);
642 static const void *newt__symbol_tree_get_current(newtComponent self
)
644 if (symbol_conf
.use_callchain
)
645 return newtCheckboxTreeGetCurrent(self
);
646 return newtListboxGetCurrent(self
);
649 static void hist_browser__selection(newtComponent self
, void *data
)
651 const struct map_symbol
**symbol_ptr
= data
;
652 *symbol_ptr
= newt__symbol_tree_get_current(self
);
655 struct hist_browser
{
656 newtComponent form
, tree
;
657 const struct map_symbol
*selection
;
660 static struct hist_browser
*hist_browser__new(void)
662 struct hist_browser
*self
= malloc(sizeof(*self
));
670 static void hist_browser__delete(struct hist_browser
*self
)
672 newtFormDestroy(self
->form
);
677 static int hist_browser__populate(struct hist_browser
*self
, struct hists
*hists
,
680 int max_len
= 0, idx
, cols
, rows
;
681 struct ui_progress
*progress
;
684 char seq
[] = ".", unit
;
686 unsigned long nr_events
= hists
->stats
.nr_events
[PERF_RECORD_SAMPLE
];
689 newtFormDestroy(self
->form
);
693 nr_events
= convert_unit(nr_events
, &unit
);
694 snprintf(str
, sizeof(str
), "Events: %lu%c ",
696 newtDrawRootText(0, 0, str
);
698 newtGetScreenSize(NULL
, &rows
);
700 if (symbol_conf
.use_callchain
)
701 self
->tree
= newtCheckboxTreeMulti(0, 0, rows
- 5, seq
,
704 self
->tree
= newtListbox(0, 0, rows
- 5,
706 NEWT_FLAG_RETURNEXIT
));
708 newtComponentAddCallback(self
->tree
, hist_browser__selection
,
711 progress
= ui_progress__new("Adding entries to the browser...",
713 if (progress
== NULL
)
717 for (nd
= rb_first(&hists
->entries
); nd
; nd
= rb_next(nd
)) {
718 struct hist_entry
*h
= rb_entry(nd
, struct hist_entry
, rb_node
);
724 len
= hist_entry__append_browser(h
, self
->tree
, hists
->stats
.total_period
);
727 if (symbol_conf
.use_callchain
)
728 hist_entry__append_callchain_browser(h
, self
->tree
,
729 hists
->stats
.total_period
, idx
++);
732 ui_progress__update(progress
, curr_hist
);
735 ui_progress__delete(progress
);
737 newtGetScreenSize(&cols
, &rows
);
742 if (!symbol_conf
.use_callchain
)
743 newtListboxSetWidth(self
->tree
, max_len
);
745 newtCenteredWindow(max_len
+ (symbol_conf
.use_callchain
? 5 : 0),
747 self
->form
= newt_form__new();
748 if (self
->form
== NULL
)
751 newtFormAddHotKey(self
->form
, 'A');
752 newtFormAddHotKey(self
->form
, 'a');
753 newtFormAddHotKey(self
->form
, NEWT_KEY_RIGHT
);
754 newtFormAddHotKey(self
->form
, NEWT_KEY_LEFT
);
755 newtFormAddComponents(self
->form
, self
->tree
, NULL
);
756 self
->selection
= newt__symbol_tree_get_current(self
->tree
);
761 static struct hist_entry
*hist_browser__selected_entry(struct hist_browser
*self
)
765 if (!symbol_conf
.use_callchain
)
768 indexes
= newtCheckboxTreeFindItem(self
->tree
, (void *)self
->selection
);
770 bool is_hist_entry
= indexes
[1] == NEWT_ARG_LAST
;
777 return container_of(self
->selection
, struct hist_entry
, ms
);
780 static struct thread
*hist_browser__selected_thread(struct hist_browser
*self
)
782 struct hist_entry
*he
= hist_browser__selected_entry(self
);
783 return he
? he
->thread
: NULL
;
786 static int hist_browser__title(char *bf
, size_t size
, const char *input_name
,
787 const struct dso
*dso
, const struct thread
*thread
)
792 printed
+= snprintf(bf
+ printed
, size
- printed
,
794 (thread
->comm_set
? thread
->comm
: ""),
797 printed
+= snprintf(bf
+ printed
, size
- printed
,
798 "%sDSO: %s", thread
? " " : "",
800 return printed
?: snprintf(bf
, size
, "Report: %s", input_name
);
803 int hists__browse(struct hists
*self
, const char *helpline
, const char *input_name
)
805 struct hist_browser
*browser
= hist_browser__new();
806 struct pstack
*fstack
= pstack__new(2);
807 const struct thread
*thread_filter
= NULL
;
808 const struct dso
*dso_filter
= NULL
;
809 struct newtExitStruct es
;
816 fstack
= pstack__new(2);
820 ui_helpline__push(helpline
);
822 hist_browser__title(msg
, sizeof(msg
), input_name
,
823 dso_filter
, thread_filter
);
824 if (hist_browser__populate(browser
, self
, msg
) < 0)
828 const struct thread
*thread
;
829 const struct dso
*dso
;
831 int nr_options
= 0, choice
= 0, i
,
832 annotate
= -2, zoom_dso
= -2, zoom_thread
= -2;
834 newtFormRun(browser
->form
, &es
);
835 if (es
.reason
== NEWT_EXIT_HOTKEY
) {
836 if (toupper(es
.u
.key
) == 'A')
838 if (es
.u
.key
== NEWT_KEY_ESCAPE
||
839 toupper(es
.u
.key
) == 'Q' ||
840 es
.u
.key
== CTRL('c')) {
841 if (dialog_yesno("Do you really want to exit?"))
847 if (es
.u
.key
== NEWT_KEY_LEFT
) {
850 if (pstack__empty(fstack
))
852 top
= pstack__pop(fstack
);
853 if (top
== &dso_filter
)
855 if (top
== &thread_filter
)
856 goto zoom_out_thread
;
861 if (browser
->selection
->sym
!= NULL
&&
862 asprintf(&options
[nr_options
], "Annotate %s",
863 browser
->selection
->sym
->name
) > 0)
864 annotate
= nr_options
++;
866 thread
= hist_browser__selected_thread(browser
);
867 if (thread
!= NULL
&&
868 asprintf(&options
[nr_options
], "Zoom %s %s(%d) thread",
869 (thread_filter
? "out of" : "into"),
870 (thread
->comm_set
? thread
->comm
: ""),
872 zoom_thread
= nr_options
++;
874 dso
= browser
->selection
->map
? browser
->selection
->map
->dso
: NULL
;
876 asprintf(&options
[nr_options
], "Zoom %s %s DSO",
877 (dso_filter
? "out of" : "into"),
878 (dso
->kernel
? "the Kernel" : dso
->short_name
)) > 0)
879 zoom_dso
= nr_options
++;
881 options
[nr_options
++] = (char *)"Exit";
883 choice
= popup_menu(nr_options
, options
);
885 for (i
= 0; i
< nr_options
- 1; ++i
)
888 if (choice
== nr_options
- 1)
894 if (choice
== annotate
) {
895 struct hist_entry
*he
;
897 if (browser
->selection
->map
->dso
->origin
== DSO__ORIG_KERNEL
) {
898 ui_helpline__puts("No vmlinux file found, can't "
899 "annotate with just a "
904 he
= hist_browser__selected_entry(browser
);
908 hist_entry__annotate_browser(he
);
909 } else if (choice
== zoom_dso
) {
911 pstack__remove(fstack
, &dso_filter
);
916 ui_helpline__fpush("To zoom out press <- or -> + \"Zoom out of %s DSO\"",
917 dso
->kernel
? "the Kernel" : dso
->short_name
);
919 pstack__push(fstack
, &dso_filter
);
921 hists__filter_by_dso(self
, dso_filter
);
922 hist_browser__title(msg
, sizeof(msg
), input_name
,
923 dso_filter
, thread_filter
);
924 if (hist_browser__populate(browser
, self
, msg
) < 0)
926 } else if (choice
== zoom_thread
) {
928 pstack__remove(fstack
, &thread_filter
);
931 thread_filter
= NULL
;
933 ui_helpline__fpush("To zoom out press <- or -> + \"Zoom out of %s(%d) thread\"",
934 thread
->comm_set
? thread
->comm
: "",
936 thread_filter
= thread
;
937 pstack__push(fstack
, &thread_filter
);
939 hists__filter_by_thread(self
, thread_filter
);
940 hist_browser__title(msg
, sizeof(msg
), input_name
,
941 dso_filter
, thread_filter
);
942 if (hist_browser__populate(browser
, self
, msg
) < 0)
948 pstack__delete(fstack
);
950 hist_browser__delete(browser
);
954 static struct newtPercentTreeColors
{
955 const char *topColorFg
, *topColorBg
;
956 const char *mediumColorFg
, *mediumColorBg
;
957 const char *normalColorFg
, *normalColorBg
;
958 const char *selColorFg
, *selColorBg
;
959 const char *codeColorFg
, *codeColorBg
;
960 } defaultPercentTreeColors
= {
962 "green", "lightgray",
963 "black", "lightgray",
964 "lightgray", "magenta",
968 void setup_browser(void)
970 struct newtPercentTreeColors
*c
= &defaultPercentTreeColors
;
977 ui_helpline__puts(" ");
978 SLtt_set_color(HE_COLORSET_TOP
, NULL
, c
->topColorFg
, c
->topColorBg
);
979 SLtt_set_color(HE_COLORSET_MEDIUM
, NULL
, c
->mediumColorFg
, c
->mediumColorBg
);
980 SLtt_set_color(HE_COLORSET_NORMAL
, NULL
, c
->normalColorFg
, c
->normalColorBg
);
981 SLtt_set_color(HE_COLORSET_SELECTED
, NULL
, c
->selColorFg
, c
->selColorBg
);
982 SLtt_set_color(HE_COLORSET_CODE
, NULL
, c
->codeColorFg
, c
->codeColorBg
);
985 void exit_browser(bool wait_for_ok
)
989 char title
[] = "Fatal Error", ok
[] = "Ok";
990 newtWinMessage(title
, ok
, browser__last_msg
);
This page took 0.053152 seconds and 4 git commands to generate.