aboutsummaryrefslogtreecommitdiffstats
path: root/kernel-shark.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel-shark.c')
-rw-r--r--kernel-shark.c308
1 files changed, 277 insertions, 31 deletions
diff --git a/kernel-shark.c b/kernel-shark.c
index bab1728..5823934 100644
--- a/kernel-shark.c
+++ b/kernel-shark.c
@@ -23,6 +23,7 @@
23#include <string.h> 23#include <string.h>
24#include <stdarg.h> 24#include <stdarg.h>
25#include <fcntl.h> 25#include <fcntl.h>
26#include <dirent.h>
26#include <sys/types.h> 27#include <sys/types.h>
27#include <sys/stat.h> 28#include <sys/stat.h>
28#include <unistd.h> 29#include <unistd.h>
@@ -35,6 +36,7 @@
35#include "trace-cmd.h" 36#include "trace-cmd.h"
36#include "trace-gui.h" 37#include "trace-gui.h"
37#include "kernel-shark.h" 38#include "kernel-shark.h"
39#include "util.h"
38#include "version.h" 40#include "version.h"
39 41
40#define ___stringify(X) #X 42#define ___stringify(X) #X
@@ -211,6 +213,7 @@ static void free_info(struct shark_info *info)
211 213
212 kernel_shark_clear_capture(info); 214 kernel_shark_clear_capture(info);
213 215
216 free(info->current_filter);
214 free(info->ginfo); 217 free(info->ginfo);
215 free(info); 218 free(info);
216} 219}
@@ -345,11 +348,52 @@ load_clicked (gpointer data)
345 g_free(filename); 348 g_free(filename);
346} 349}
347 350
348/* Callback for the clicked signal of the Load Filters button */ 351static GString *get_home_filters_new(void)
349static void 352{
350load_filters_clicked (gpointer data) 353 char *path = getenv("HOME");
354 GString *str;
355
356 str = g_string_new(path);
357 g_string_append(str, "/.trace-cmd/filters/");
358 return str;
359}
360
361static int create_home_filters(void)
362{
363 char *path = getenv("HOME");
364 GString *str;
365 struct stat st;
366 int ret;
367
368 str = g_string_new(path);
369 g_string_append(str, "/.trace-cmd");
370 ret = stat(str->str, &st);
371 if (ret < 0) {
372 ret = mkdir(str->str, 0755);
373 if (ret < 0) {
374 warning("Can not create %s", str->str);
375 goto out;
376 }
377 }
378
379 g_string_append(str, "/filters");
380 ret = stat(str->str, &st);
381 if (ret < 0) {
382 ret = mkdir(str->str, 0755);
383 if (ret < 0) {
384 warning("Can not create %s", str->str);
385 goto out;
386 }
387 }
388
389 ret = 0;
390 out:
391 g_string_free(str, TRUE);
392 return ret;
393}
394
395static void load_filter(struct shark_info *info, const char *filename)
351{ 396{
352 struct shark_info *info = data;
353 struct graph_info *ginfo = info->ginfo; 397 struct graph_info *ginfo = info->ginfo;
354 GtkTreeView *trace_tree = GTK_TREE_VIEW(info->treeview); 398 GtkTreeView *trace_tree = GTK_TREE_VIEW(info->treeview);
355 GtkTreeModel *model; 399 GtkTreeModel *model;
@@ -358,18 +402,12 @@ load_filters_clicked (gpointer data)
358 struct filter_task *task_filter; 402 struct filter_task *task_filter;
359 struct filter_task *hide_tasks; 403 struct filter_task *hide_tasks;
360 struct event_filter *event_filter; 404 struct event_filter *event_filter;
361 gchar *filename;
362 int ret; 405 int ret;
363 406
364 filename = trace_get_file_dialog_filter("Load Filters", NULL,
365 TRACE_DIALOG_FILTER_FILTER, FALSE);
366 if (!filename)
367 return;
368
369 handle = tracecmd_xml_open(filename); 407 handle = tracecmd_xml_open(filename);
370 if (!handle) { 408 if (!handle) {
371 warning("Could not open %s", filename); 409 warning("Could not open %s", filename);
372 goto out; 410 return;
373 } 411 }
374 412
375 /* Unsync the list and graph filters */ 413 /* Unsync the list and graph filters */
@@ -423,40 +461,61 @@ load_filters_clicked (gpointer data)
423 461
424 model = gtk_tree_view_get_model(trace_tree); 462 model = gtk_tree_view_get_model(trace_tree);
425 if (!model) 463 if (!model)
426 goto out; 464 return;
427 465
428 store = TRACE_VIEW_STORE(model); 466 store = TRACE_VIEW_STORE(model);
429 event_filter = trace_view_store_get_event_filter(store); 467 event_filter = trace_view_store_get_event_filter(store);
430 468
431 if (pevent_filter_compare(event_filter, ginfo->event_filter)) 469 if (pevent_filter_compare(event_filter, ginfo->event_filter))
432 sync_event_filters(info); 470 sync_event_filters(info);
471}
433 472
434 out: 473static void load_filter_clicked(GtkMenuItem *item, gpointer data)
435 g_free(filename); 474{
475 struct shark_info *info = data;
476 const char *name;
477 GString *path;
478
479 name = gtk_menu_item_get_label(item);
480
481 path = get_home_filters_new();
482 g_string_append_printf(path, "/%s.ksf", name);
483
484 load_filter(info, path->str);
485 g_string_free(path, TRUE);
436 486
487 free(info->current_filter);
488 info->current_filter = strdup(name);
437} 489}
438 490
439/* Callback for the clicked signal of the Save Filters button */ 491/* Callback for the clicked signal of the Load Filters button */
440static void 492static void
441save_filters_clicked (gpointer data) 493import_filters_clicked (gpointer data)
442{ 494{
443 struct shark_info *info = data; 495 struct shark_info *info = data;
496 gchar *filename;
497
498 filename = trace_get_file_dialog_filter("Load Filters", NULL,
499 TRACE_DIALOG_FILTER_FILTER, FALSE);
500 if (!filename)
501 return;
502
503 load_filter(info, filename);
504}
505
506static void save_filters(struct shark_info *info, const char *filename)
507{
444 struct graph_info *ginfo = info->ginfo; 508 struct graph_info *ginfo = info->ginfo;
445 struct tracecmd_xml_handle *handle; 509 struct tracecmd_xml_handle *handle;
446 GtkTreeView *trace_tree = GTK_TREE_VIEW(info->treeview); 510 GtkTreeView *trace_tree = GTK_TREE_VIEW(info->treeview);
447 struct filter_task *task_filter; 511 struct filter_task *task_filter;
448 struct filter_task *hide_tasks; 512 struct filter_task *hide_tasks;
449 gchar *filename;
450
451 filename = trace_get_file_dialog_filter("Save Filters", "Save",
452 TRACE_DIALOG_FILTER_FILTER, TRUE);
453 if (!filename)
454 return;
455 513
456 handle = tracecmd_xml_create(filename, VERSION_STRING); 514 handle = tracecmd_xml_create(filename, VERSION_STRING);
457 if (!handle) 515 if (!handle) {
458 warning("Could not create %s", filename); 516 warning("Could not create %s", filename);
459 g_free(filename); 517 return;
518 }
460 519
461 trace_view_save_filters(handle, trace_tree); 520 trace_view_save_filters(handle, trace_tree);
462 trace_graph_save_filters(ginfo, handle); 521 trace_graph_save_filters(ginfo, handle);
@@ -481,6 +540,178 @@ save_filters_clicked (gpointer data)
481 tracecmd_xml_close(handle); 540 tracecmd_xml_close(handle);
482} 541}
483 542
543/* Callback for the clicked signal of the Save Filters button */
544static void
545export_filters_clicked (gpointer data)
546{
547 struct shark_info *info = data;
548 gchar *filename;
549
550 filename = trace_get_file_dialog_filter("Save Filters", "Save",
551 TRACE_DIALOG_FILTER_FILTER, TRUE);
552 if (!filename)
553 return;
554
555 save_filters(info, filename);
556 g_free(filename);
557}
558
559static void update_load_filter(struct shark_info *info)
560{
561 struct dirent *dent;
562 struct stat st;
563 DIR *dir;
564 GtkWidget *menu;
565 GtkWidget *sub_item;
566 GString *path;
567 int ret;
568
569 path = get_home_filters_new();
570
571 menu = gtk_menu_new();
572
573 ret = stat(path->str, &st);
574 if (ret < 0 || !S_ISDIR(st.st_mode))
575 goto update_rest;
576
577 dir = opendir(path->str);
578 if (!dir)
579 goto update_rest;
580
581 while ((dent = readdir(dir))) {
582 const char *name = dent->d_name;
583 GString *file;
584 gchar *item;
585
586 if (strcmp(name, ".") == 0 ||
587 strcmp(name, "..") == 0)
588 continue;
589
590 if (strcmp(name + strlen(name) - 4, ".ksf") != 0)
591 continue;
592
593 file = g_string_new(path->str);
594 g_string_append_printf(file, "/%s", name);
595
596 /* Save the file name but remove the .kss extention */
597 item = g_strdup(name);
598 item[strlen(name) - 4] = 0;
599
600 sub_item = gtk_menu_item_new_with_label(item);
601 gtk_menu_shell_append(GTK_MENU_SHELL (menu), sub_item);
602 gtk_widget_show(sub_item);
603
604 g_signal_connect(G_OBJECT (sub_item), "activate",
605 G_CALLBACK (load_filter_clicked),
606 (gpointer) info);
607
608 g_free(item);
609 g_string_free(file, TRUE);
610 }
611
612 update_rest:
613 g_string_free(path, TRUE);
614
615 /* --- File - Load Filter - Filters --- */
616
617 sub_item = gtk_menu_item_new_with_label("Import Filter");
618
619 g_signal_connect_swapped (G_OBJECT (sub_item), "activate",
620 G_CALLBACK (import_filters_clicked),
621 (gpointer) info);
622
623 /* Add them to the menu */
624 gtk_menu_shell_append(GTK_MENU_SHELL (menu), sub_item);
625
626 /* We do need to show menu items */
627 gtk_widget_show(sub_item);
628
629 gtk_menu_item_set_submenu(GTK_MENU_ITEM (info->load_filter_menu), menu);
630
631}
632
633/* Callback for the clicked signal of the Save Filters button */
634static void
635save_filter_clicked (gpointer data)
636{
637 struct shark_info *info = data;
638 struct stat st;
639 GtkWidget *dialog;
640 GtkWidget *hbox;
641 GtkWidget *label;
642 GtkWidget *entry;
643 GString *file;
644 const char *name;
645 gint result;
646 int ret;
647
648 dialog = gtk_dialog_new_with_buttons("Save Filter",
649 NULL,
650 GTK_DIALOG_MODAL,
651 GTK_STOCK_OK,
652 GTK_RESPONSE_ACCEPT,
653 GTK_STOCK_CANCEL,
654 GTK_RESPONSE_REJECT,
655 NULL);
656
657 hbox = gtk_hbox_new(FALSE, 0);
658 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), hbox, FALSE, FALSE, 0);
659 gtk_widget_show(hbox);
660
661 label = gtk_label_new("Filter Name: ");
662 gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
663 gtk_widget_show(label);
664
665 entry = gtk_entry_new();
666 gtk_box_pack_start(GTK_BOX(hbox), entry, FALSE, FALSE, 0);
667 gtk_widget_show(entry);
668
669 if (info->current_filter)
670 gtk_entry_set_text(GTK_ENTRY(entry), info->current_filter);
671
672 again:
673 result = gtk_dialog_run(GTK_DIALOG(dialog));
674 switch (result) {
675 case GTK_RESPONSE_ACCEPT:
676 name = gtk_entry_get_text(GTK_ENTRY(entry));
677 if (!name || !has_text(name)) {
678 warning("Must enter a name");
679 goto again;
680 }
681 /* Make sure home settings exists */
682 if (create_home_filters() < 0)
683 break;
684 file = get_home_filters_new();
685 g_string_append_printf(file, "/%s.ksf", name);
686 ret = stat(file->str, &st);
687 if (ret >= 0) {
688 ret = trace_dialog(GTK_WINDOW(dialog), TRACE_GUI_ASK,
689 "The Filter '%s' already exists.\n"
690 "Are you sure you want to replace it",
691 name);
692 if (ret == GTK_RESPONSE_NO) {
693 g_string_free(file, TRUE);
694 goto again;
695 }
696 }
697 save_filters(info, file->str);
698
699 free(info->current_filter);
700 info->current_filter = strdup(name);
701
702 update_load_filter(info);
703 g_string_free(file, TRUE);
704 break;
705
706 case GTK_RESPONSE_REJECT:
707 break;
708 default:
709 break;
710 };
711
712 gtk_widget_destroy(dialog);
713}
714
484/* Callback for the clicked signal of the Exit button */ 715/* Callback for the clicked signal of the Exit button */
485static void 716static void
486exit_clicked (gpointer data) 717exit_clicked (gpointer data)
@@ -1633,30 +1864,45 @@ void kernel_shark(int argc, char **argv)
1633 gtk_widget_show(sub_item); 1864 gtk_widget_show(sub_item);
1634 1865
1635 1866
1636 /* --- File - Load Filter Option --- */ 1867 /* --- File - Load Filter --- */
1637 1868
1638 sub_item = gtk_menu_item_new_with_label("Load filters"); 1869 sub_item = gtk_menu_item_new_with_label("Load filter");
1639 1870
1640 /* Add them to the menu */ 1871 /* Add them to the menu */
1641 gtk_menu_shell_append(GTK_MENU_SHELL (menu), sub_item); 1872 gtk_menu_shell_append(GTK_MENU_SHELL (menu), sub_item);
1642 1873
1643 g_signal_connect_swapped (G_OBJECT (sub_item), "activate", 1874 info->load_filter_menu = sub_item;
1644 G_CALLBACK (load_filters_clicked),
1645 (gpointer) info);
1646 1875
1647 /* We do need to show menu items */ 1876 /* We do need to show menu items */
1648 gtk_widget_show(sub_item); 1877 gtk_widget_show(sub_item);
1649 1878
1879 update_load_filter(info);
1880
1650 1881
1651 /* --- File - Save Filter Option --- */ 1882 /* --- File - Save Filter Option --- */
1652 1883
1653 sub_item = gtk_menu_item_new_with_label("Save filters"); 1884 sub_item = gtk_menu_item_new_with_label("Save filter");
1885
1886 /* Add them to the menu */
1887 gtk_menu_shell_append(GTK_MENU_SHELL (menu), sub_item);
1888
1889 /* We do need to show menu items */
1890 gtk_widget_show(sub_item);
1891
1892 g_signal_connect_swapped (G_OBJECT (sub_item), "activate",
1893 G_CALLBACK (save_filter_clicked),
1894 (gpointer) info);
1895
1896
1897 /* --- File - Export Filter Option --- */
1898
1899 sub_item = gtk_menu_item_new_with_label("Export filters");
1654 1900
1655 /* Add them to the menu */ 1901 /* Add them to the menu */
1656 gtk_menu_shell_append(GTK_MENU_SHELL (menu), sub_item); 1902 gtk_menu_shell_append(GTK_MENU_SHELL (menu), sub_item);
1657 1903
1658 g_signal_connect_swapped (G_OBJECT (sub_item), "activate", 1904 g_signal_connect_swapped (G_OBJECT (sub_item), "activate",
1659 G_CALLBACK (save_filters_clicked), 1905 G_CALLBACK (export_filters_clicked),
1660 (gpointer) info); 1906 (gpointer) info);
1661 1907
1662 /* We do need to show menu items */ 1908 /* We do need to show menu items */