diff options
author | Steven Rostedt <srostedt@redhat.com> | 2010-06-10 17:53:51 -0400 |
---|---|---|
committer | Steven Rostedt <rostedt@goodmis.org> | 2010-06-10 17:53:51 -0400 |
commit | 3c95290d3fb593145b8ce1163d795a08f05e112c (patch) | |
tree | e6fc1bea660993e4eaaf5b716bef577d6fbf692e /trace-view-main.c | |
parent | d01b699fffc573e7653e00d608444735c04f9dca (diff) | |
parent | b09e5f4f3fc5c8fc2c51376050af19660c8053f4 (diff) |
Merge branch 'kernelshark-devel' into trace-cmd
Conflicts:
Makefile
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
Diffstat (limited to 'trace-view-main.c')
-rw-r--r-- | trace-view-main.c | 358 |
1 files changed, 326 insertions, 32 deletions
diff --git a/trace-view-main.c b/trace-view-main.c index 52678ce..59d6838 100644 --- a/trace-view-main.c +++ b/trace-view-main.c | |||
@@ -28,6 +28,12 @@ | |||
28 | 28 | ||
29 | #include "trace-cmd.h" | 29 | #include "trace-cmd.h" |
30 | #include "trace-view.h" | 30 | #include "trace-view.h" |
31 | #include "trace-xml.h" | ||
32 | #include "trace-filter.h" | ||
33 | #include "trace-gui.h" | ||
34 | #include "trace-compat.h" | ||
35 | |||
36 | #include "version.h" | ||
31 | 37 | ||
32 | #define version "0.1.1" | 38 | #define version "0.1.1" |
33 | 39 | ||
@@ -38,8 +44,13 @@ | |||
38 | static char *input_file; | 44 | static char *input_file; |
39 | 45 | ||
40 | struct trace_tree_info { | 46 | struct trace_tree_info { |
41 | GtkWidget *trace_tree; | 47 | struct tracecmd_input *handle; |
42 | GtkWidget *spin; | 48 | GtkWidget *trace_tree; |
49 | GtkWidget *spin; | ||
50 | gint filter_enabled; | ||
51 | gint filter_task_selected; | ||
52 | struct filter_task *task_filter; | ||
53 | struct filter_task *hide_tasks; | ||
43 | }; | 54 | }; |
44 | 55 | ||
45 | void usage(char *prog) | 56 | void usage(char *prog) |
@@ -55,26 +66,76 @@ load_clicked (gpointer data) | |||
55 | { | 66 | { |
56 | struct trace_tree_info *info = data; | 67 | struct trace_tree_info *info = data; |
57 | struct tracecmd_input *handle; | 68 | struct tracecmd_input *handle; |
58 | GtkWidget *dialog; | ||
59 | gchar *filename; | 69 | gchar *filename; |
60 | 70 | ||
61 | dialog = gtk_file_chooser_dialog_new("Load File", | 71 | filename = trace_get_file_dialog("Load File"); |
62 | NULL, | 72 | if (!filename) |
63 | GTK_FILE_CHOOSER_ACTION_OPEN, | 73 | return; |
64 | GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, | 74 | |
65 | GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, | 75 | handle = tracecmd_open(filename); |
66 | NULL); | 76 | if (handle) { |
67 | if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) { | 77 | trace_view_reload(info->trace_tree, handle, info->spin); |
68 | filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog)); | 78 | /* Free handle when freeing the trace tree */ |
69 | handle = tracecmd_open(filename); | 79 | tracecmd_close(handle); |
70 | if (handle) { | 80 | info->handle = handle; |
71 | trace_view_reload(info->trace_tree, handle, info->spin); | ||
72 | /* Free handle when freeing the trace tree */ | ||
73 | tracecmd_close(handle); | ||
74 | } | ||
75 | g_free(filename); | ||
76 | } | 81 | } |
77 | gtk_widget_destroy(dialog); | 82 | g_free(filename); |
83 | } | ||
84 | |||
85 | /* Callback for the clicked signal of the Load Filters button */ | ||
86 | static void | ||
87 | load_filters_clicked (gpointer data) | ||
88 | { | ||
89 | struct trace_tree_info *info = data; | ||
90 | GtkTreeView *trace_tree = GTK_TREE_VIEW(info->trace_tree); | ||
91 | struct tracecmd_xml_handle *handle; | ||
92 | gchar *filename; | ||
93 | |||
94 | filename = trace_get_file_dialog("Load Filters"); | ||
95 | if (!filename) | ||
96 | return; | ||
97 | |||
98 | handle = tracecmd_xml_open(filename); | ||
99 | if (!handle) { | ||
100 | warning("Could not open %s", filename); | ||
101 | return; | ||
102 | } | ||
103 | g_free(filename); | ||
104 | |||
105 | trace_filter_load_filters(handle, | ||
106 | "ListTaskFilter", | ||
107 | info->task_filter, | ||
108 | info->hide_tasks); | ||
109 | |||
110 | trace_view_load_filters(handle, trace_tree); | ||
111 | |||
112 | tracecmd_xml_close(handle); | ||
113 | } | ||
114 | |||
115 | /* Callback for the clicked signal of the Save Filters button */ | ||
116 | static void | ||
117 | save_filters_clicked (gpointer data) | ||
118 | { | ||
119 | struct trace_tree_info *info = data; | ||
120 | GtkTreeView *trace_tree = GTK_TREE_VIEW(info->trace_tree); | ||
121 | struct tracecmd_xml_handle *handle; | ||
122 | gchar *filename; | ||
123 | |||
124 | filename = trace_get_file_dialog("Save Filters"); | ||
125 | if (!filename) | ||
126 | return; | ||
127 | |||
128 | handle = tracecmd_xml_create(filename, VERSION_STRING); | ||
129 | if (!handle) | ||
130 | warning("Could not create %s", filename); | ||
131 | g_free(filename); | ||
132 | |||
133 | trace_filter_save_filters(handle, | ||
134 | "ListTaskFilter", | ||
135 | info->task_filter, info->hide_tasks); | ||
136 | trace_view_save_filters(handle, trace_tree); | ||
137 | |||
138 | tracecmd_xml_close(handle); | ||
78 | } | 139 | } |
79 | 140 | ||
80 | /* Callback for the clicked signal of the Exit button */ | 141 | /* Callback for the clicked signal of the Exit button */ |
@@ -162,24 +223,209 @@ cpus_clicked (gpointer data) | |||
162 | trace_view_cpu_filter_callback, trace_tree); | 223 | trace_view_cpu_filter_callback, trace_tree); |
163 | } | 224 | } |
164 | 225 | ||
165 | #if 0 | 226 | static void |
166 | static GtkTreeModel * | 227 | filter_list_clicked (gpointer data) |
167 | create_combo_box_model(void) | ||
168 | { | 228 | { |
169 | GtkListStore *store; | 229 | struct trace_tree_info *info = data; |
170 | GtkTreeIter iter; | 230 | |
231 | if (!filter_task_count(info->task_filter) && | ||
232 | !filter_task_count(info->hide_tasks)) | ||
233 | return; | ||
234 | |||
235 | info->filter_enabled ^= 1; | ||
236 | |||
237 | if (info->filter_enabled) | ||
238 | trace_view_update_filters(info->trace_tree, | ||
239 | info->task_filter, | ||
240 | info->hide_tasks); | ||
241 | else | ||
242 | trace_view_update_filters(info->trace_tree, NULL, NULL); | ||
243 | } | ||
244 | |||
245 | static void update_task_filter(struct trace_tree_info *info, | ||
246 | struct filter_task *filter) | ||
247 | { | ||
248 | struct filter_task_item *task; | ||
249 | gint pid = info->filter_task_selected; | ||
250 | |||
251 | task = filter_task_find_pid(filter, pid); | ||
252 | |||
253 | if (task) | ||
254 | filter_task_remove_pid(filter, pid); | ||
255 | else | ||
256 | filter_task_add_pid(filter, pid); | ||
257 | |||
258 | if (info->filter_enabled) | ||
259 | trace_view_update_filters(info->trace_tree, | ||
260 | info->task_filter, | ||
261 | info->hide_tasks); | ||
262 | } | ||
263 | |||
264 | static void filter_add_task_clicked(gpointer data) | ||
265 | { | ||
266 | struct trace_tree_info *info = data; | ||
267 | |||
268 | update_task_filter(info, info->task_filter); | ||
269 | } | ||
270 | |||
271 | static void filter_hide_task_clicked(gpointer data) | ||
272 | { | ||
273 | struct trace_tree_info *info = data; | ||
274 | |||
275 | update_task_filter(info, info->hide_tasks); | ||
276 | } | ||
277 | |||
278 | static void | ||
279 | filter_clear_tasks_clicked (gpointer data) | ||
280 | { | ||
281 | struct trace_tree_info *info = data; | ||
282 | |||
283 | trace_view_update_filters(info->trace_tree, NULL, NULL); | ||
284 | info->filter_enabled = 0; | ||
285 | } | ||
286 | |||
287 | static gboolean | ||
288 | do_tree_popup(GtkWidget *widget, GdkEventButton *event, gpointer data) | ||
289 | { | ||
290 | struct trace_tree_info *info = data; | ||
291 | static GtkWidget *menu; | ||
292 | static GtkWidget *menu_filter_enable; | ||
293 | static GtkWidget *menu_filter_add_task; | ||
294 | static GtkWidget *menu_filter_hide_task; | ||
295 | static GtkWidget *menu_filter_clear_tasks; | ||
296 | struct pevent *pevent; | ||
297 | struct record *record; | ||
298 | TraceViewRecord *vrec; | ||
299 | GtkTreeModel *model; | ||
300 | const char *comm; | ||
301 | gchar *text; | ||
302 | gint pid; | ||
303 | gint len; | ||
304 | guint64 offset; | ||
305 | gint row; | ||
306 | gint cpu; | ||
307 | |||
308 | if (!menu) { | ||
309 | menu = gtk_menu_new(); | ||
310 | |||
311 | menu_filter_enable = gtk_menu_item_new_with_label("Enable Filter"); | ||
312 | gtk_widget_show(menu_filter_enable); | ||
313 | gtk_menu_shell_append(GTK_MENU_SHELL (menu), menu_filter_enable); | ||
314 | |||
315 | g_signal_connect_swapped (G_OBJECT (menu_filter_enable), "activate", | ||
316 | G_CALLBACK (filter_list_clicked), | ||
317 | data); | ||
318 | |||
319 | menu_filter_add_task = gtk_menu_item_new_with_label("Add Task"); | ||
320 | gtk_widget_show(menu_filter_add_task); | ||
321 | gtk_menu_shell_append(GTK_MENU_SHELL (menu), menu_filter_add_task); | ||
322 | |||
323 | g_signal_connect_swapped (G_OBJECT (menu_filter_add_task), "activate", | ||
324 | G_CALLBACK (filter_add_task_clicked), | ||
325 | data); | ||
326 | |||
327 | menu_filter_hide_task = gtk_menu_item_new_with_label("Hide Task"); | ||
328 | gtk_widget_show(menu_filter_hide_task); | ||
329 | gtk_menu_shell_append(GTK_MENU_SHELL (menu), menu_filter_hide_task); | ||
330 | |||
331 | g_signal_connect_swapped (G_OBJECT (menu_filter_hide_task), "activate", | ||
332 | G_CALLBACK (filter_hide_task_clicked), | ||
333 | data); | ||
334 | |||
335 | menu_filter_clear_tasks = gtk_menu_item_new_with_label("Clear Task Filter"); | ||
336 | gtk_widget_show(menu_filter_clear_tasks); | ||
337 | gtk_menu_shell_append(GTK_MENU_SHELL (menu), menu_filter_clear_tasks); | ||
338 | |||
339 | g_signal_connect_swapped (G_OBJECT (menu_filter_clear_tasks), "activate", | ||
340 | G_CALLBACK (filter_clear_tasks_clicked), | ||
341 | data); | ||
342 | |||
343 | } | ||
344 | |||
345 | row = trace_view_get_selected_row(GTK_WIDGET(info->trace_tree)); | ||
346 | if (row >= 0) { | ||
347 | |||
348 | model = gtk_tree_view_get_model(GTK_TREE_VIEW(info->trace_tree)); | ||
349 | vrec = trace_view_store_get_row(TRACE_VIEW_STORE(model), row); | ||
350 | offset = vrec->offset; | ||
351 | |||
352 | record = tracecmd_read_at(info->handle, offset, &cpu); | ||
353 | |||
354 | if (record) { | ||
355 | pevent = tracecmd_get_pevent(info->handle); | ||
356 | pid = pevent_data_pid(pevent, record); | ||
357 | comm = pevent_data_comm_from_pid(pevent, pid); | ||
358 | |||
359 | len = strlen(comm) + 50; | ||
360 | |||
361 | text = g_malloc(len); | ||
362 | g_assert(text); | ||
363 | |||
364 | if (filter_task_find_pid(info->task_filter, pid)) | ||
365 | snprintf(text, len, "Remove %s-%d from filter", comm, pid); | ||
366 | else | ||
367 | snprintf(text, len, "Add %s-%d to filter", comm, pid); | ||
368 | |||
369 | info->filter_task_selected = pid; | ||
370 | |||
371 | gtk_menu_item_set_label(GTK_MENU_ITEM(menu_filter_add_task), | ||
372 | text); | ||
373 | |||
374 | if (filter_task_find_pid(info->hide_tasks, pid)) | ||
375 | snprintf(text, len, "Show %s-%d", comm, pid); | ||
376 | else | ||
377 | snprintf(text, len, "Hide %s-%d", comm, pid); | ||
378 | |||
379 | gtk_menu_item_set_label(GTK_MENU_ITEM(menu_filter_hide_task), | ||
380 | text); | ||
381 | |||
382 | g_free(text); | ||
383 | |||
384 | info->filter_task_selected = pid; | ||
385 | |||
386 | gtk_widget_show(menu_filter_add_task); | ||
387 | gtk_widget_show(menu_filter_hide_task); | ||
388 | free_record(record); | ||
389 | } | ||
390 | } else { | ||
391 | gtk_widget_hide(menu_filter_add_task); | ||
392 | gtk_widget_hide(menu_filter_hide_task); | ||
393 | } | ||
394 | |||
395 | if (info->filter_enabled) | ||
396 | gtk_menu_item_set_label(GTK_MENU_ITEM(menu_filter_enable), | ||
397 | "Disable List Filter"); | ||
398 | else | ||
399 | gtk_menu_item_set_label(GTK_MENU_ITEM(menu_filter_enable), | ||
400 | "Enable List Filter"); | ||
401 | |||
402 | if (filter_task_count(info->task_filter) || | ||
403 | filter_task_count(info->hide_tasks)) { | ||
404 | gtk_widget_set_sensitive(menu_filter_clear_tasks, TRUE); | ||
405 | gtk_widget_set_sensitive(menu_filter_enable, TRUE); | ||
406 | } else { | ||
407 | gtk_widget_set_sensitive(menu_filter_clear_tasks, FALSE); | ||
408 | gtk_widget_set_sensitive(menu_filter_enable, FALSE); | ||
409 | } | ||
410 | |||
411 | gtk_menu_popup(GTK_MENU(menu), NULL, NULL, NULL, NULL, 3, | ||
412 | gtk_get_current_event_time()); | ||
413 | |||
414 | return TRUE; | ||
415 | } | ||
171 | 416 | ||
172 | store = gtk_list_store_new(1, G_TYPE_STRING); | 417 | static gboolean |
173 | gtk_list_store_append(store, &iter); | 418 | button_press_event(GtkWidget *widget, GdkEventButton *event, gpointer data) |
174 | gtk_list_store_set(store, &iter, 0, "1", -1); | 419 | { |
420 | if (event->button == 3) | ||
421 | return do_tree_popup(widget, event, data); | ||
175 | 422 | ||
176 | return GTK_TREE_MODEL(store); | 423 | return FALSE; |
177 | } | 424 | } |
178 | #endif | ||
179 | 425 | ||
180 | void trace_view(int argc, char **argv) | 426 | void trace_view(int argc, char **argv) |
181 | { | 427 | { |
182 | static struct tracecmd_input *handle; | 428 | static struct tracecmd_input *handle = NULL; |
183 | struct trace_tree_info tree_info; | 429 | struct trace_tree_info tree_info; |
184 | struct stat st; | 430 | struct stat st; |
185 | GtkWidget *trace_tree; | 431 | GtkWidget *trace_tree; |
@@ -193,6 +439,7 @@ void trace_view(int argc, char **argv) | |||
193 | GtkWidget *scrollwin; | 439 | GtkWidget *scrollwin; |
194 | GtkWidget *label; | 440 | GtkWidget *label; |
195 | GtkWidget *spin; | 441 | GtkWidget *spin; |
442 | GtkWidget *statusbar; | ||
196 | int ret; | 443 | int ret; |
197 | int c; | 444 | int c; |
198 | 445 | ||
@@ -227,10 +474,17 @@ void trace_view(int argc, char **argv) | |||
227 | if (input_file) | 474 | if (input_file) |
228 | handle = tracecmd_open(input_file); | 475 | handle = tracecmd_open(input_file); |
229 | 476 | ||
477 | memset(&tree_info, 0, sizeof(tree_info)); | ||
478 | tree_info.handle = handle; | ||
479 | tree_info.task_filter = filter_task_hash_alloc(); | ||
480 | tree_info.hide_tasks = filter_task_hash_alloc(); | ||
481 | |||
230 | /* --- Main window --- */ | 482 | /* --- Main window --- */ |
231 | 483 | ||
232 | window = gtk_window_new(GTK_WINDOW_TOPLEVEL); | 484 | window = gtk_window_new(GTK_WINDOW_TOPLEVEL); |
233 | 485 | ||
486 | trace_dialog_register_window(window); | ||
487 | |||
234 | /* --- Top Level Vbox --- */ | 488 | /* --- Top Level Vbox --- */ |
235 | 489 | ||
236 | vbox = gtk_vbox_new(FALSE, 0); | 490 | vbox = gtk_vbox_new(FALSE, 0); |
@@ -255,12 +509,11 @@ void trace_view(int argc, char **argv) | |||
255 | 509 | ||
256 | /* --- File - Load Option --- */ | 510 | /* --- File - Load Option --- */ |
257 | 511 | ||
258 | sub_item = gtk_menu_item_new_with_label("Load info"); | 512 | sub_item = gtk_menu_item_new_with_label("Load data"); |
259 | 513 | ||
260 | /* Add them to the menu */ | 514 | /* Add them to the menu */ |
261 | gtk_menu_shell_append(GTK_MENU_SHELL (menu), sub_item); | 515 | gtk_menu_shell_append(GTK_MENU_SHELL (menu), sub_item); |
262 | 516 | ||
263 | /* We can attach the Quit menu item to our exit function */ | ||
264 | g_signal_connect_swapped (G_OBJECT (sub_item), "activate", | 517 | g_signal_connect_swapped (G_OBJECT (sub_item), "activate", |
265 | G_CALLBACK (load_clicked), | 518 | G_CALLBACK (load_clicked), |
266 | (gpointer) &tree_info); | 519 | (gpointer) &tree_info); |
@@ -269,6 +522,36 @@ void trace_view(int argc, char **argv) | |||
269 | gtk_widget_show(sub_item); | 522 | gtk_widget_show(sub_item); |
270 | 523 | ||
271 | 524 | ||
525 | /* --- File - Load Filter Option --- */ | ||
526 | |||
527 | sub_item = gtk_menu_item_new_with_label("Load filters"); | ||
528 | |||
529 | /* Add them to the menu */ | ||
530 | gtk_menu_shell_append(GTK_MENU_SHELL (menu), sub_item); | ||
531 | |||
532 | g_signal_connect_swapped (G_OBJECT (sub_item), "activate", | ||
533 | G_CALLBACK (load_filters_clicked), | ||
534 | (gpointer) &tree_info); | ||
535 | |||
536 | /* We do need to show menu items */ | ||
537 | gtk_widget_show(sub_item); | ||
538 | |||
539 | |||
540 | /* --- File - Save Filter Option --- */ | ||
541 | |||
542 | sub_item = gtk_menu_item_new_with_label("Save filters"); | ||
543 | |||
544 | /* Add them to the menu */ | ||
545 | gtk_menu_shell_append(GTK_MENU_SHELL (menu), sub_item); | ||
546 | |||
547 | g_signal_connect_swapped (G_OBJECT (sub_item), "activate", | ||
548 | G_CALLBACK (save_filters_clicked), | ||
549 | (gpointer) &tree_info); | ||
550 | |||
551 | /* We do need to show menu items */ | ||
552 | gtk_widget_show(sub_item); | ||
553 | |||
554 | |||
272 | /* --- File - Quit Option --- */ | 555 | /* --- File - Quit Option --- */ |
273 | 556 | ||
274 | sub_item = gtk_menu_item_new_with_label("Quit"); | 557 | sub_item = gtk_menu_item_new_with_label("Quit"); |
@@ -385,6 +668,10 @@ void trace_view(int argc, char **argv) | |||
385 | gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0); | 668 | gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0); |
386 | gtk_widget_show(label); | 669 | gtk_widget_show(label); |
387 | 670 | ||
671 | gtk_signal_connect(GTK_OBJECT(trace_tree), "button_press_event", | ||
672 | (GtkSignalFunc) button_press_event, | ||
673 | (gpointer) &tree_info); | ||
674 | |||
388 | trace_view_search_setup(GTK_BOX(hbox), GTK_TREE_VIEW(trace_tree)); | 675 | trace_view_search_setup(GTK_BOX(hbox), GTK_TREE_VIEW(trace_tree)); |
389 | 676 | ||
390 | /* --- Top Level Hbox --- */ | 677 | /* --- Top Level Hbox --- */ |
@@ -407,6 +694,13 @@ void trace_view(int argc, char **argv) | |||
407 | gtk_widget_show(trace_tree); | 694 | gtk_widget_show(trace_tree); |
408 | 695 | ||
409 | 696 | ||
697 | /* --- Set up Status Bar --- */ | ||
698 | |||
699 | statusbar = trace_status_bar_new(); | ||
700 | |||
701 | gtk_box_pack_start(GTK_BOX(vbox), statusbar, FALSE, FALSE, 0); | ||
702 | gtk_widget_show(statusbar); | ||
703 | |||
410 | /********************************************** | 704 | /********************************************** |
411 | * Main Window | 705 | * Main Window |
412 | **********************************************/ | 706 | **********************************************/ |