6 #include "../helpline.h"
11 #define MAX_COLUMNS 32
13 static void perf_gtk__signal(int sig
)
15 perf_gtk__exit(false);
19 static void perf_gtk__resize_window(GtkWidget
*window
)
27 screen
= gtk_widget_get_screen(window
);
29 monitor
= gdk_screen_get_monitor_at_window(screen
, window
->window
);
31 gdk_screen_get_monitor_geometry(screen
, monitor
, &rect
);
33 width
= rect
.width
* 3 / 4;
34 height
= rect
.height
* 3 / 4;
36 gtk_window_resize(GTK_WINDOW(window
), width
, height
);
39 static const char *perf_gtk__get_percent_color(double percent
)
41 if (percent
>= MIN_RED
)
42 return "<span fgcolor='red'>";
43 if (percent
>= MIN_GREEN
)
44 return "<span fgcolor='dark green'>";
48 #define HPP__COLOR_FN(_name, _field) \
49 static int perf_gtk__hpp_color_ ## _name(struct perf_hpp *hpp, \
50 struct hist_entry *he) \
52 double percent = 100.0 * he->_field / hpp->total_period; \
56 markup = perf_gtk__get_percent_color(percent); \
58 ret += scnprintf(hpp->buf, hpp->size, "%s", markup); \
59 ret += scnprintf(hpp->buf + ret, hpp->size - ret, "%5.2f%%", percent); \
61 ret += scnprintf(hpp->buf + ret, hpp->size - ret, "</span>"); \
66 HPP__COLOR_FN(overhead
, period
)
67 HPP__COLOR_FN(overhead_sys
, period_sys
)
68 HPP__COLOR_FN(overhead_us
, period_us
)
69 HPP__COLOR_FN(overhead_guest_sys
, period_guest_sys
)
70 HPP__COLOR_FN(overhead_guest_us
, period_guest_us
)
74 void perf_gtk__init_hpp(void)
76 perf_hpp__init(false, false);
78 perf_hpp__format
[PERF_HPP__OVERHEAD
].color
=
79 perf_gtk__hpp_color_overhead
;
80 perf_hpp__format
[PERF_HPP__OVERHEAD_SYS
].color
=
81 perf_gtk__hpp_color_overhead_sys
;
82 perf_hpp__format
[PERF_HPP__OVERHEAD_US
].color
=
83 perf_gtk__hpp_color_overhead_us
;
84 perf_hpp__format
[PERF_HPP__OVERHEAD_GUEST_SYS
].color
=
85 perf_gtk__hpp_color_overhead_guest_sys
;
86 perf_hpp__format
[PERF_HPP__OVERHEAD_GUEST_US
].color
=
87 perf_gtk__hpp_color_overhead_guest_us
;
90 static void perf_gtk__show_hists(GtkWidget
*window
, struct hists
*hists
)
92 GType col_types
[MAX_COLUMNS
];
93 GtkCellRenderer
*renderer
;
94 struct sort_entry
*se
;
102 struct perf_hpp hpp
= {
105 .total_period
= hists
->stats
.total_period
,
110 for (i
= 0; i
< PERF_HPP__MAX_INDEX
; i
++) {
111 if (!perf_hpp__format
[i
].cond
)
114 col_types
[nr_cols
++] = G_TYPE_STRING
;
117 list_for_each_entry(se
, &hist_entry__sort_list
, list
) {
121 col_types
[nr_cols
++] = G_TYPE_STRING
;
124 store
= gtk_list_store_newv(nr_cols
, col_types
);
126 view
= gtk_tree_view_new();
128 renderer
= gtk_cell_renderer_text_new();
132 for (i
= 0; i
< PERF_HPP__MAX_INDEX
; i
++) {
133 if (!perf_hpp__format
[i
].cond
)
136 perf_hpp__format
[i
].header(&hpp
);
138 gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(view
),
144 list_for_each_entry(se
, &hist_entry__sort_list
, list
) {
148 gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(view
),
154 gtk_tree_view_set_model(GTK_TREE_VIEW(view
), GTK_TREE_MODEL(store
));
156 g_object_unref(GTK_TREE_MODEL(store
));
158 for (nd
= rb_first(&hists
->entries
); nd
; nd
= rb_next(nd
)) {
159 struct hist_entry
*h
= rb_entry(nd
, struct hist_entry
, rb_node
);
165 gtk_list_store_append(store
, &iter
);
169 for (i
= 0; i
< PERF_HPP__MAX_INDEX
; i
++) {
170 if (!perf_hpp__format
[i
].cond
)
173 if (perf_hpp__format
[i
].color
)
174 perf_hpp__format
[i
].color(&hpp
, h
);
176 perf_hpp__format
[i
].entry(&hpp
, h
);
178 gtk_list_store_set(store
, &iter
, col_idx
++, s
, -1);
181 list_for_each_entry(se
, &hist_entry__sort_list
, list
) {
185 se
->se_snprintf(h
, s
, ARRAY_SIZE(s
),
186 hists__col_len(hists
, se
->se_width_idx
));
188 gtk_list_store_set(store
, &iter
, col_idx
++, s
, -1);
192 gtk_container_add(GTK_CONTAINER(window
), view
);
195 #ifdef HAVE_GTK_INFO_BAR
196 static GtkWidget
*perf_gtk__setup_info_bar(void)
200 GtkWidget
*content_area
;
202 info_bar
= gtk_info_bar_new();
203 gtk_widget_set_no_show_all(info_bar
, TRUE
);
205 label
= gtk_label_new("");
206 gtk_widget_show(label
);
208 content_area
= gtk_info_bar_get_content_area(GTK_INFO_BAR(info_bar
));
209 gtk_container_add(GTK_CONTAINER(content_area
), label
);
211 gtk_info_bar_add_button(GTK_INFO_BAR(info_bar
), GTK_STOCK_OK
,
213 g_signal_connect(info_bar
, "response",
214 G_CALLBACK(gtk_widget_hide
), NULL
);
216 pgctx
->info_bar
= info_bar
;
217 pgctx
->message_label
= label
;
223 static GtkWidget
*perf_gtk__setup_statusbar(void)
228 stbar
= gtk_statusbar_new();
230 ctxid
= gtk_statusbar_get_context_id(GTK_STATUSBAR(stbar
),
232 pgctx
->statbar
= stbar
;
233 pgctx
->statbar_ctx_id
= ctxid
;
238 int perf_evlist__gtk_browse_hists(struct perf_evlist
*evlist
,
240 void (*timer
) (void *arg
)__maybe_unused
,
241 void *arg __maybe_unused
,
242 int delay_secs __maybe_unused
)
244 struct perf_evsel
*pos
;
251 signal(SIGSEGV
, perf_gtk__signal
);
252 signal(SIGFPE
, perf_gtk__signal
);
253 signal(SIGINT
, perf_gtk__signal
);
254 signal(SIGQUIT
, perf_gtk__signal
);
255 signal(SIGTERM
, perf_gtk__signal
);
257 window
= gtk_window_new(GTK_WINDOW_TOPLEVEL
);
259 gtk_window_set_title(GTK_WINDOW(window
), "perf report");
261 g_signal_connect(window
, "delete_event", gtk_main_quit
, NULL
);
263 pgctx
= perf_gtk__activate_context(window
);
267 vbox
= gtk_vbox_new(FALSE
, 0);
269 notebook
= gtk_notebook_new();
271 list_for_each_entry(pos
, &evlist
->entries
, node
) {
272 struct hists
*hists
= &pos
->hists
;
273 const char *evname
= perf_evsel__name(pos
);
274 GtkWidget
*scrolled_window
;
275 GtkWidget
*tab_label
;
277 scrolled_window
= gtk_scrolled_window_new(NULL
, NULL
);
279 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled_window
),
280 GTK_POLICY_AUTOMATIC
,
281 GTK_POLICY_AUTOMATIC
);
283 perf_gtk__show_hists(scrolled_window
, hists
);
285 tab_label
= gtk_label_new(evname
);
287 gtk_notebook_append_page(GTK_NOTEBOOK(notebook
), scrolled_window
, tab_label
);
290 gtk_box_pack_start(GTK_BOX(vbox
), notebook
, TRUE
, TRUE
, 0);
292 info_bar
= perf_gtk__setup_info_bar();
294 gtk_box_pack_start(GTK_BOX(vbox
), info_bar
, FALSE
, FALSE
, 0);
296 statbar
= perf_gtk__setup_statusbar();
297 gtk_box_pack_start(GTK_BOX(vbox
), statbar
, FALSE
, FALSE
, 0);
299 gtk_container_add(GTK_CONTAINER(window
), vbox
);
301 gtk_widget_show_all(window
);
303 perf_gtk__resize_window(window
);
305 gtk_window_set_position(GTK_WINDOW(window
), GTK_WIN_POS_CENTER
);
307 ui_helpline__push(help
);
311 perf_gtk__deactivate_context(&pgctx
);