diff options
Diffstat (limited to 'trace-capture.c')
-rw-r--r-- | trace-capture.c | 955 |
1 files changed, 661 insertions, 294 deletions
diff --git a/trace-capture.c b/trace-capture.c index d7133ba..f866b3e 100644 --- a/trace-capture.c +++ b/trace-capture.c | |||
@@ -25,6 +25,7 @@ | |||
25 | #include <stdarg.h> | 25 | #include <stdarg.h> |
26 | #include <fcntl.h> | 26 | #include <fcntl.h> |
27 | #include <ctype.h> | 27 | #include <ctype.h> |
28 | #include <dirent.h> | ||
28 | #include <sys/time.h> | 29 | #include <sys/time.h> |
29 | #include <sys/types.h> | 30 | #include <sys/types.h> |
30 | #include <sys/stat.h> | 31 | #include <sys/stat.h> |
@@ -46,6 +47,13 @@ | |||
46 | 47 | ||
47 | #define PLUGIN_NONE "NONE" | 48 | #define PLUGIN_NONE "NONE" |
48 | 49 | ||
50 | #define DIALOG_WIDTH 820 | ||
51 | #define DIALOG_HEIGHT 600 | ||
52 | |||
53 | #define CAP_STOP "Stop" | ||
54 | |||
55 | #define DEFAULT_MAX_BUF_SIZE 1000000 | ||
56 | |||
49 | struct trace_capture { | 57 | struct trace_capture { |
50 | struct pevent *pevent; | 58 | struct pevent *pevent; |
51 | struct shark_info *info; | 59 | struct shark_info *info; |
@@ -54,9 +62,11 @@ struct trace_capture { | |||
54 | GtkWidget *file_entry; | 62 | GtkWidget *file_entry; |
55 | GtkWidget *output_text; | 63 | GtkWidget *output_text; |
56 | GtkTextBuffer *output_buffer; | 64 | GtkTextBuffer *output_buffer; |
57 | GtkWidget *output_dialog; | 65 | GtkWidget *event_view; |
58 | GtkWidget *plugin_combo; | 66 | GtkWidget *plugin_combo; |
59 | GtkWidget *stop_dialog; | 67 | GtkWidget *settings_combo; |
68 | GtkWidget *run_button; | ||
69 | GtkWidget *max_num_entry; | ||
60 | pthread_t thread; | 70 | pthread_t thread; |
61 | gboolean kill_thread; | 71 | gboolean kill_thread; |
62 | gboolean capture_done; | 72 | gboolean capture_done; |
@@ -76,6 +86,124 @@ static int is_just_ws(const char *str) | |||
76 | return !str[i]; | 86 | return !str[i]; |
77 | } | 87 | } |
78 | 88 | ||
89 | static gboolean settings_saved; | ||
90 | |||
91 | static GString *get_home_settings_new(void) | ||
92 | { | ||
93 | char *path = getenv("HOME"); | ||
94 | GString *str; | ||
95 | |||
96 | str = g_string_new(path); | ||
97 | g_string_append(str, "/.trace-cmd/settings/"); | ||
98 | return str; | ||
99 | } | ||
100 | |||
101 | static int create_home_settings(void) | ||
102 | { | ||
103 | char *path = getenv("HOME"); | ||
104 | GString *str; | ||
105 | struct stat st; | ||
106 | int ret; | ||
107 | |||
108 | str = g_string_new(path); | ||
109 | g_string_append(str, "/.trace-cmd"); | ||
110 | ret = stat(str->str, &st); | ||
111 | if (ret < 0) { | ||
112 | ret = mkdir(str->str, 0755); | ||
113 | if (ret < 0) { | ||
114 | warning("Can not create %s", str->str); | ||
115 | goto out; | ||
116 | } | ||
117 | } | ||
118 | |||
119 | g_string_append(str, "/settings"); | ||
120 | ret = stat(str->str, &st); | ||
121 | if (ret < 0) { | ||
122 | ret = mkdir(str->str, 0755); | ||
123 | if (ret < 0) { | ||
124 | warning("Can not create %s", str->str); | ||
125 | goto out; | ||
126 | } | ||
127 | } | ||
128 | |||
129 | ret = 0; | ||
130 | out: | ||
131 | g_string_free(str, TRUE); | ||
132 | return ret; | ||
133 | } | ||
134 | |||
135 | static GtkTreeModel *create_settings_model(gpointer data) | ||
136 | { | ||
137 | struct dirent *dent; | ||
138 | GtkListStore *list; | ||
139 | GtkTreeIter iter; | ||
140 | struct stat st; | ||
141 | GString *str; | ||
142 | DIR *dir; | ||
143 | int ret; | ||
144 | |||
145 | list = gtk_list_store_new(2, G_TYPE_STRING, G_TYPE_STRING); | ||
146 | |||
147 | gtk_list_store_append(list, &iter); | ||
148 | gtk_list_store_set(list, &iter, | ||
149 | 0, "Current", | ||
150 | 1, "", | ||
151 | -1); | ||
152 | |||
153 | /* Search for user settings first */ | ||
154 | str = get_home_settings_new(); | ||
155 | ret = stat(str->str, &st); | ||
156 | if (ret < 0 || !S_ISDIR(st.st_mode)) | ||
157 | goto read_system; | ||
158 | |||
159 | dir = opendir(str->str); | ||
160 | if (!dir) | ||
161 | goto read_system; | ||
162 | |||
163 | while ((dent = readdir(dir))) { | ||
164 | const char *name = dent->d_name; | ||
165 | GString *file; | ||
166 | gchar *item; | ||
167 | |||
168 | |||
169 | if (strcmp(name, ".") == 0 || | ||
170 | strcmp(name, "..") == 0) | ||
171 | continue; | ||
172 | |||
173 | if (strcmp(name + strlen(name) - 4, ".kss") != 0) | ||
174 | continue; | ||
175 | |||
176 | file = g_string_new(str->str); | ||
177 | g_string_append_printf(file, "/%s", name); | ||
178 | |||
179 | /* Save the file name but remove the .kss extention */ | ||
180 | item = g_strdup(name); | ||
181 | item[strlen(name) - 4] = 0; | ||
182 | |||
183 | gtk_list_store_append(list, &iter); | ||
184 | gtk_list_store_set(list, &iter, | ||
185 | 0, item, | ||
186 | 1, file->str, | ||
187 | -1); | ||
188 | g_free(item); | ||
189 | g_string_free(file, TRUE); | ||
190 | } | ||
191 | |||
192 | read_system: | ||
193 | g_string_free(str, TRUE); | ||
194 | |||
195 | return GTK_TREE_MODEL(list); | ||
196 | } | ||
197 | |||
198 | static void refresh_settings(struct trace_capture *cap) | ||
199 | { | ||
200 | GtkTreeModel *model; | ||
201 | |||
202 | model = create_settings_model(NULL); | ||
203 | gtk_combo_box_set_model(GTK_COMBO_BOX(cap->settings_combo), model); | ||
204 | g_object_unref(model); | ||
205 | } | ||
206 | |||
79 | static void ks_clear_capture_events(struct shark_info *info) | 207 | static void ks_clear_capture_events(struct shark_info *info) |
80 | { | 208 | { |
81 | info->cap_all_events = FALSE; | 209 | info->cap_all_events = FALSE; |
@@ -99,15 +227,28 @@ void kernel_shark_clear_capture(struct shark_info *info) | |||
99 | g_free(info->cap_plugin); | 227 | g_free(info->cap_plugin); |
100 | info->cap_plugin = NULL; | 228 | info->cap_plugin = NULL; |
101 | 229 | ||
230 | g_free(info->cap_settings_name); | ||
231 | info->cap_settings_name = NULL; | ||
232 | |||
102 | free(info->cap_file); | 233 | free(info->cap_file); |
103 | info->cap_file = NULL; | 234 | info->cap_file = NULL; |
235 | |||
236 | g_free(info->cap_buffer_output); | ||
237 | info->cap_buffer_output = NULL; | ||
104 | } | 238 | } |
105 | 239 | ||
106 | static void end_capture(struct trace_capture *cap) | 240 | static gboolean end_capture(struct trace_capture *cap) |
107 | { | 241 | { |
108 | const char *filename; | 242 | const char *filename; |
243 | const char *val; | ||
109 | int pid; | 244 | int pid; |
110 | 245 | ||
246 | val = gtk_button_get_label(GTK_BUTTON(cap->run_button)); | ||
247 | if (strcmp(val, CAP_STOP) != 0) | ||
248 | return FALSE; | ||
249 | |||
250 | gtk_button_set_label(GTK_BUTTON(cap->run_button), "Run"); | ||
251 | |||
111 | cap->capture_done = TRUE; | 252 | cap->capture_done = TRUE; |
112 | 253 | ||
113 | pid = cap->command_pid; | 254 | pid = cap->command_pid; |
@@ -141,6 +282,8 @@ static void end_capture(struct trace_capture *cap) | |||
141 | kernelshark_load_file(cap->info, filename); | 282 | kernelshark_load_file(cap->info, filename); |
142 | cap->load_file = FALSE; | 283 | cap->load_file = FALSE; |
143 | } | 284 | } |
285 | |||
286 | return TRUE; | ||
144 | } | 287 | } |
145 | 288 | ||
146 | static char *get_tracing_dir(void) | 289 | static char *get_tracing_dir(void) |
@@ -163,93 +306,6 @@ static int is_latency(char *plugin) | |||
163 | strcmp(plugin, "preemptirqsoff") == 0; | 306 | strcmp(plugin, "preemptirqsoff") == 0; |
164 | } | 307 | } |
165 | 308 | ||
166 | static void close_command_display(struct trace_capture *cap) | ||
167 | { | ||
168 | gtk_widget_destroy(cap->output_dialog); | ||
169 | cap->output_dialog = NULL; | ||
170 | cap->stop_dialog = NULL; | ||
171 | } | ||
172 | |||
173 | static void display_command_close(GtkWidget *widget, gint id, gpointer data) | ||
174 | { | ||
175 | struct trace_capture *cap = data; | ||
176 | |||
177 | close_command_display(cap); | ||
178 | } | ||
179 | |||
180 | static void display_command_destroy(GtkWidget *widget, gpointer data) | ||
181 | { | ||
182 | struct trace_capture *cap = data; | ||
183 | |||
184 | close_command_display(cap); | ||
185 | } | ||
186 | |||
187 | static void display_command(struct trace_capture *cap) | ||
188 | { | ||
189 | GtkWidget *dialog; | ||
190 | GtkWidget *scrollwin; | ||
191 | GtkWidget *viewport; | ||
192 | GtkWidget *textview; | ||
193 | GtkTextBuffer *buffer; | ||
194 | const gchar *command; | ||
195 | GString *str; | ||
196 | |||
197 | command = gtk_entry_get_text(GTK_ENTRY(cap->command_entry)); | ||
198 | |||
199 | if (!command || !strlen(command) || is_just_ws(command)) | ||
200 | command = "trace-cmd"; | ||
201 | |||
202 | str = g_string_new(""); | ||
203 | |||
204 | g_string_printf(str, "(%s)", command); | ||
205 | |||
206 | dialog = gtk_dialog_new_with_buttons(str->str, | ||
207 | NULL, | ||
208 | GTK_DIALOG_MODAL, | ||
209 | "Close", | ||
210 | GTK_RESPONSE_ACCEPT, | ||
211 | NULL); | ||
212 | |||
213 | g_string_free(str, TRUE); | ||
214 | |||
215 | g_signal_connect(dialog, "response", | ||
216 | G_CALLBACK(display_command_close), | ||
217 | (gpointer)cap); | ||
218 | |||
219 | gtk_signal_connect (GTK_OBJECT(dialog), "delete_event", | ||
220 | (GtkSignalFunc) display_command_destroy, | ||
221 | (gpointer)cap); | ||
222 | |||
223 | scrollwin = gtk_scrolled_window_new(NULL, NULL); | ||
224 | gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrollwin), | ||
225 | GTK_POLICY_AUTOMATIC, | ||
226 | GTK_POLICY_AUTOMATIC); | ||
227 | gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), scrollwin, TRUE, TRUE, 0); | ||
228 | gtk_widget_show(scrollwin); | ||
229 | |||
230 | viewport = gtk_viewport_new(NULL, NULL); | ||
231 | gtk_widget_show(viewport); | ||
232 | |||
233 | gtk_container_add(GTK_CONTAINER(scrollwin), viewport); | ||
234 | |||
235 | textview = gtk_text_view_new(); | ||
236 | buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(textview)); | ||
237 | |||
238 | gtk_container_add(GTK_CONTAINER(viewport), textview); | ||
239 | gtk_widget_show(textview); | ||
240 | |||
241 | cap->output_text = textview; | ||
242 | cap->output_buffer = buffer; | ||
243 | |||
244 | gtk_widget_set_size_request(GTK_WIDGET(dialog), | ||
245 | 500, 600); | ||
246 | |||
247 | gtk_widget_show(dialog); | ||
248 | |||
249 | cap->output_dialog = dialog; | ||
250 | |||
251 | } | ||
252 | |||
253 | static int calculate_trace_cmd_words(struct trace_capture *cap) | 309 | static int calculate_trace_cmd_words(struct trace_capture *cap) |
254 | { | 310 | { |
255 | int words = 4; /* trace-cmd record -o file */ | 311 | int words = 4; /* trace-cmd record -o file */ |
@@ -402,30 +458,31 @@ static void update_plugin(struct trace_capture *cap) | |||
402 | 458 | ||
403 | } | 459 | } |
404 | 460 | ||
405 | static void set_plugin(struct trace_capture *cap) | 461 | /* |
462 | * The plugin and settings combo's are set by the first item | ||
463 | * in the model. The can share the same code to set the model. | ||
464 | * | ||
465 | * Return TRUE if set, FALSE if name was not found. | ||
466 | */ | ||
467 | static int set_combo(GtkComboBox *combo, const char *name) | ||
406 | { | 468 | { |
407 | GtkComboBox *combo = GTK_COMBO_BOX(cap->plugin_combo); | ||
408 | GtkTreeModel *model; | 469 | GtkTreeModel *model; |
409 | GtkTreeIter iter; | 470 | GtkTreeIter iter; |
410 | gchar *text; | 471 | gchar *text; |
411 | const gchar *plugin = cap->info->cap_plugin; | 472 | gboolean ret; |
412 | gboolean ret = TRUE; | ||
413 | |||
414 | if (!plugin) | ||
415 | plugin = PLUGIN_NONE; | ||
416 | 473 | ||
417 | model = gtk_combo_box_get_model(combo); | 474 | model = gtk_combo_box_get_model(combo); |
418 | if (!model) | 475 | if (!model) |
419 | return; | 476 | return FALSE; |
420 | 477 | ||
421 | if (!gtk_tree_model_get_iter_first(model, &iter)) | 478 | if (!gtk_tree_model_get_iter_first(model, &iter)) |
422 | return; | 479 | return FALSE; |
423 | 480 | ||
424 | do { | 481 | do { |
425 | gtk_tree_model_get(model, &iter, | 482 | gtk_tree_model_get(model, &iter, |
426 | 0, &text, | 483 | 0, &text, |
427 | -1); | 484 | -1); |
428 | if (strcmp(text, plugin) == 0) { | 485 | if (strcmp(text, name) == 0) { |
429 | g_free(text); | 486 | g_free(text); |
430 | break; | 487 | break; |
431 | } | 488 | } |
@@ -436,21 +493,65 @@ static void set_plugin(struct trace_capture *cap) | |||
436 | } while (ret); | 493 | } while (ret); |
437 | 494 | ||
438 | if (ret) { | 495 | if (ret) { |
496 | /* Found */ | ||
439 | gtk_combo_box_set_active_iter(GTK_COMBO_BOX(combo), | 497 | gtk_combo_box_set_active_iter(GTK_COMBO_BOX(combo), |
440 | &iter); | 498 | &iter); |
441 | return; | 499 | return TRUE; |
442 | } | 500 | } |
443 | 501 | ||
502 | /* set to first item (default) */ | ||
503 | gtk_tree_model_get_iter_first(model, &iter); | ||
504 | gtk_combo_box_set_active_iter(GTK_COMBO_BOX(combo), | ||
505 | &iter); | ||
506 | |||
507 | return FALSE; | ||
508 | } | ||
509 | |||
510 | static void set_plugin(struct trace_capture *cap) | ||
511 | { | ||
512 | GtkComboBox *combo = GTK_COMBO_BOX(cap->plugin_combo); | ||
513 | const gchar *plugin = cap->info->cap_plugin; | ||
514 | |||
515 | if (!plugin) | ||
516 | plugin = PLUGIN_NONE; | ||
517 | |||
518 | if (set_combo(combo, plugin)) | ||
519 | return; | ||
520 | |||
444 | /* Not found? */ | 521 | /* Not found? */ |
445 | g_free(cap->info->cap_plugin); | 522 | g_free(cap->info->cap_plugin); |
446 | cap->info->cap_plugin = NULL; | 523 | cap->info->cap_plugin = NULL; |
524 | } | ||
447 | 525 | ||
448 | /* set to NONE */ | 526 | static void set_settings(struct trace_capture *cap) |
449 | if (!gtk_tree_model_get_iter_first(model, &iter)) | 527 | { |
528 | GtkComboBox *combo = GTK_COMBO_BOX(cap->settings_combo); | ||
529 | const gchar *name = cap->info->cap_settings_name; | ||
530 | |||
531 | if (!name) | ||
532 | name = ""; | ||
533 | |||
534 | if (set_combo(combo, name)) | ||
450 | return; | 535 | return; |
451 | 536 | ||
452 | gtk_combo_box_set_active_iter(GTK_COMBO_BOX(combo), | 537 | /* Not found? */ |
453 | &iter); | 538 | g_free(cap->info->cap_settings_name); |
539 | cap->info->cap_settings_name = NULL; | ||
540 | } | ||
541 | |||
542 | static void update_events(struct trace_capture *cap) | ||
543 | { | ||
544 | struct shark_info *info = cap->info; | ||
545 | |||
546 | if (!cap->event_view) | ||
547 | return; | ||
548 | |||
549 | clear_capture_events(cap); | ||
550 | |||
551 | trace_extract_event_list_view(cap->event_view, | ||
552 | &info->cap_all_events, | ||
553 | &info->cap_systems, | ||
554 | &info->cap_events); | ||
454 | } | 555 | } |
455 | 556 | ||
456 | static void execute_command(struct trace_capture *cap) | 557 | static void execute_command(struct trace_capture *cap) |
@@ -464,6 +565,7 @@ static void execute_command(struct trace_capture *cap) | |||
464 | int i; | 565 | int i; |
465 | 566 | ||
466 | update_plugin(cap); | 567 | update_plugin(cap); |
568 | update_events(cap); | ||
467 | 569 | ||
468 | ccommand = gtk_entry_get_text(GTK_ENTRY(cap->command_entry)); | 570 | ccommand = gtk_entry_get_text(GTK_ENTRY(cap->command_entry)); |
469 | if (!ccommand || !strlen(ccommand) || is_just_ws(ccommand)) { | 571 | if (!ccommand || !strlen(ccommand) || is_just_ws(ccommand)) { |
@@ -524,47 +626,35 @@ static void execute_command(struct trace_capture *cap) | |||
524 | g_free(cap->info->cap_plugin); | 626 | g_free(cap->info->cap_plugin); |
525 | } | 627 | } |
526 | 628 | ||
527 | static gint | ||
528 | delete_stop_dialog(GtkWidget *widget, GdkEvent *event, gpointer data) | ||
529 | { | ||
530 | struct trace_capture *cap = data; | ||
531 | GtkWidget *dialog = cap->stop_dialog; | ||
532 | |||
533 | cap->stop_dialog = NULL; | ||
534 | if (!dialog) | ||
535 | return TRUE; | ||
536 | |||
537 | end_capture(cap); | ||
538 | gtk_widget_destroy(dialog); | ||
539 | |||
540 | return TRUE; | ||
541 | } | ||
542 | |||
543 | void end_stop_dialog(struct trace_capture *cap) | ||
544 | { | ||
545 | GdkEvent dummy_event; | ||
546 | gboolean dummy_retval; | ||
547 | guint sigid; | ||
548 | |||
549 | if (!cap->stop_dialog) | ||
550 | return; | ||
551 | |||
552 | sigid = g_signal_lookup("delete-event", G_OBJECT_TYPE(cap->stop_dialog)); | ||
553 | g_signal_emit(cap->stop_dialog, sigid, 0, | ||
554 | cap->stop_dialog, &dummy_event , cap, &dummy_retval); | ||
555 | } | ||
556 | |||
557 | static void *monitor_pipes(void *data) | 629 | static void *monitor_pipes(void *data) |
558 | { | 630 | { |
559 | struct trace_capture *cap = data; | 631 | struct trace_capture *cap = data; |
632 | GtkTextIter start_iter; | ||
633 | GtkTextIter cut_iter; | ||
560 | GtkTextIter iter; | 634 | GtkTextIter iter; |
561 | gchar buf[BUFSIZ+1]; | 635 | gchar buf[BUFSIZ+1]; |
562 | struct timeval tv; | 636 | struct timeval tv; |
637 | const char *val; | ||
563 | fd_set fds; | 638 | fd_set fds; |
564 | gboolean eof; | 639 | gboolean eof; |
640 | int max_size; | ||
641 | int total; | ||
642 | int del; | ||
565 | int ret; | 643 | int ret; |
566 | int r; | 644 | int r; |
567 | 645 | ||
646 | gdk_threads_enter(); | ||
647 | /* get the max size */ | ||
648 | val = gtk_entry_get_text(GTK_ENTRY(cap->max_num_entry)); | ||
649 | max_size = atoi(val); | ||
650 | |||
651 | /* Clear the buffer */ | ||
652 | gtk_text_buffer_get_start_iter(cap->output_buffer, &start_iter); | ||
653 | gtk_text_buffer_get_end_iter(cap->output_buffer, &cut_iter); | ||
654 | gtk_text_buffer_delete(cap->output_buffer, &start_iter, &cut_iter); | ||
655 | total = 0; | ||
656 | gdk_threads_leave(); | ||
657 | |||
568 | do { | 658 | do { |
569 | FD_ZERO(&fds); | 659 | FD_ZERO(&fds); |
570 | FD_SET(cap->command_input_fd, &fds); | 660 | FD_SET(cap->command_input_fd, &fds); |
@@ -578,7 +668,19 @@ static void *monitor_pipes(void *data) | |||
578 | while ((r = read(cap->command_input_fd, buf, BUFSIZ)) > 0) { | 668 | while ((r = read(cap->command_input_fd, buf, BUFSIZ)) > 0) { |
579 | eof = FALSE; | 669 | eof = FALSE; |
580 | buf[r] = 0; | 670 | buf[r] = 0; |
671 | total += r; | ||
672 | if (total > max_size) | ||
673 | del = total - max_size; | ||
674 | else | ||
675 | del = 0; | ||
581 | gdk_threads_enter(); | 676 | gdk_threads_enter(); |
677 | if (del) { | ||
678 | gtk_text_buffer_get_start_iter(cap->output_buffer, &start_iter); | ||
679 | gtk_text_buffer_get_start_iter(cap->output_buffer, &cut_iter); | ||
680 | gtk_text_iter_forward_chars(&cut_iter, del); | ||
681 | gtk_text_buffer_delete(cap->output_buffer, &start_iter, &cut_iter); | ||
682 | total -= del; | ||
683 | } | ||
582 | gtk_text_buffer_get_end_iter(cap->output_buffer, | 684 | gtk_text_buffer_get_end_iter(cap->output_buffer, |
583 | &iter); | 685 | &iter); |
584 | gtk_text_buffer_insert(cap->output_buffer, &iter, buf, -1); | 686 | gtk_text_buffer_insert(cap->output_buffer, &iter, buf, -1); |
@@ -588,7 +690,7 @@ static void *monitor_pipes(void *data) | |||
588 | 690 | ||
589 | if (eof) { | 691 | if (eof) { |
590 | gdk_threads_enter(); | 692 | gdk_threads_enter(); |
591 | end_stop_dialog(cap); | 693 | end_capture(cap); |
592 | gdk_threads_leave(); | 694 | gdk_threads_leave(); |
593 | } | 695 | } |
594 | 696 | ||
@@ -682,80 +784,30 @@ static int trim_plugins(char **plugins) | |||
682 | return len; | 784 | return len; |
683 | } | 785 | } |
684 | 786 | ||
685 | static void event_filter_callback(gboolean accept, | ||
686 | gboolean all_events, | ||
687 | gchar **systems, | ||
688 | gint *events, | ||
689 | gpointer data) | ||
690 | { | ||
691 | struct trace_capture *cap = data; | ||
692 | int nr_sys, nr_events; | ||
693 | int i; | ||
694 | |||
695 | if (!accept) | ||
696 | return; | ||
697 | |||
698 | clear_capture_events(cap); | ||
699 | |||
700 | if (all_events) { | ||
701 | cap->info->cap_all_events = TRUE; | ||
702 | return; | ||
703 | } | ||
704 | |||
705 | if (systems) { | ||
706 | for (nr_sys = 0; systems[nr_sys]; nr_sys++) | ||
707 | ; | ||
708 | cap->info->cap_systems = malloc_or_die(sizeof(*cap->info->cap_systems) * | ||
709 | (nr_sys + 1)); | ||
710 | for (i = 0; i < nr_sys; i++) | ||
711 | cap->info->cap_systems[i] = strdup(systems[i]); | ||
712 | cap->info->cap_systems[i] = NULL; | ||
713 | } | ||
714 | |||
715 | if (events) { | ||
716 | for (nr_events = 0; events[nr_events] >= 0; nr_events++) | ||
717 | ; | ||
718 | cap->info->cap_events = malloc_or_die(sizeof(*cap->info->cap_events) * | ||
719 | (nr_events + 1)); | ||
720 | for (i = 0; i < nr_events; i++) | ||
721 | cap->info->cap_events[i] = events[i]; | ||
722 | cap->info->cap_events[i] = -1; | ||
723 | } | ||
724 | } | ||
725 | |||
726 | static void event_button_clicked(GtkWidget *widget, gpointer data) | ||
727 | { | ||
728 | struct trace_capture *cap = data; | ||
729 | struct pevent *pevent = cap->pevent; | ||
730 | |||
731 | trace_filter_pevent_dialog(pevent, cap->info->cap_all_events, | ||
732 | cap->info->cap_systems, cap->info->cap_events, | ||
733 | event_filter_callback, cap); | ||
734 | } | ||
735 | |||
736 | static void | 787 | static void |
737 | file_clicked (GtkWidget *widget, gpointer data) | 788 | file_clicked (GtkWidget *widget, gpointer data) |
738 | { | 789 | { |
739 | struct trace_capture *cap = data; | 790 | struct trace_capture *cap = data; |
740 | gchar *filename; | 791 | gchar *filename; |
741 | 792 | ||
742 | filename = trace_get_file_dialog("Trace File", "Save", FALSE); | 793 | filename = trace_get_file_dialog_filter("Trace File", "Save", |
794 | TRACE_DIALOG_FILTER_DATA, FALSE); | ||
743 | if (!filename) | 795 | if (!filename) |
744 | return; | 796 | return; |
745 | 797 | ||
746 | gtk_entry_set_text(GTK_ENTRY(cap->file_entry), filename); | 798 | gtk_entry_set_text(GTK_ENTRY(cap->file_entry), filename); |
747 | } | 799 | } |
748 | 800 | ||
749 | static void execute_button_clicked(GtkWidget *widget, gpointer data) | 801 | static void execute_button_clicked(struct trace_capture *cap) |
750 | { | 802 | { |
751 | struct trace_capture *cap = data; | ||
752 | struct stat st; | 803 | struct stat st; |
753 | GtkResponseType ret; | 804 | GtkResponseType ret; |
754 | GtkWidget *dialog; | ||
755 | GtkWidget *label; | ||
756 | const char *filename; | 805 | const char *filename; |
757 | char *tracecmd; | 806 | char *tracecmd; |
758 | 807 | ||
808 | if (end_capture(cap)) | ||
809 | return; | ||
810 | |||
759 | tracecmd = find_tracecmd(); | 811 | tracecmd = find_tracecmd(); |
760 | if (!tracecmd) { | 812 | if (!tracecmd) { |
761 | warning("trace-cmd not found in path"); | 813 | warning("trace-cmd not found in path"); |
@@ -774,30 +826,8 @@ static void execute_button_clicked(GtkWidget *widget, gpointer data) | |||
774 | return; | 826 | return; |
775 | } | 827 | } |
776 | 828 | ||
777 | display_command(cap); | 829 | gtk_button_set_label(GTK_BUTTON(cap->run_button), CAP_STOP); |
778 | |||
779 | run_command(cap); | 830 | run_command(cap); |
780 | |||
781 | dialog = gtk_dialog_new_with_buttons("Stop Execution", | ||
782 | NULL, | ||
783 | GTK_DIALOG_MODAL, | ||
784 | "Stop", | ||
785 | GTK_RESPONSE_ACCEPT, | ||
786 | NULL); | ||
787 | |||
788 | cap->stop_dialog = dialog; | ||
789 | |||
790 | label = gtk_label_new("Hit Stop to end execution"); | ||
791 | gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), label, TRUE, TRUE, 0); | ||
792 | gtk_widget_show(label); | ||
793 | |||
794 | gtk_signal_connect(GTK_OBJECT (dialog), "delete_event", | ||
795 | (GtkSignalFunc)delete_stop_dialog, | ||
796 | (gpointer)cap); | ||
797 | |||
798 | gtk_dialog_run(GTK_DIALOG(dialog)); | ||
799 | |||
800 | end_stop_dialog(cap); | ||
801 | } | 831 | } |
802 | 832 | ||
803 | static int load_events(struct trace_capture *cap, | 833 | static int load_events(struct trace_capture *cap, |
@@ -844,12 +874,7 @@ static int load_events(struct trace_capture *cap, | |||
844 | if (!event) | 874 | if (!event) |
845 | continue; | 875 | continue; |
846 | 876 | ||
847 | if (!events) | 877 | events = tracecmd_add_id(events, event->id, event_len++); |
848 | events = malloc_or_die(sizeof(*events) * 2); | ||
849 | else | ||
850 | events = realloc(events, sizeof(*events) * (event_len + 2)); | ||
851 | events[event_len++] = event->id; | ||
852 | events[event_len] = -1; | ||
853 | } | 878 | } |
854 | 879 | ||
855 | info->cap_events = events; | 880 | info->cap_events = events; |
@@ -893,30 +918,21 @@ static int load_cap_events(struct trace_capture *cap, | |||
893 | return 0; | 918 | return 0; |
894 | } | 919 | } |
895 | 920 | ||
896 | static void load_settings_clicked(GtkWidget *widget, gpointer data) | 921 | static void load_settings(struct trace_capture *cap, gchar *filename) |
897 | { | 922 | { |
898 | struct trace_capture *cap = data; | ||
899 | struct shark_info *info = cap->info; | 923 | struct shark_info *info = cap->info; |
900 | struct tracecmd_xml_system_node *syschild; | 924 | struct tracecmd_xml_system_node *syschild; |
901 | struct tracecmd_xml_handle *handle; | 925 | struct tracecmd_xml_handle *handle; |
902 | struct tracecmd_xml_system *system; | 926 | struct tracecmd_xml_system *system; |
903 | const char *plugin; | 927 | const char *plugin; |
904 | const char *name; | 928 | const char *name; |
905 | gchar *filename; | ||
906 | |||
907 | filename = trace_get_file_dialog("Load Filters", NULL, FALSE); | ||
908 | if (!filename) | ||
909 | return; | ||
910 | 929 | ||
911 | handle = tracecmd_xml_open(filename); | 930 | handle = tracecmd_xml_open(filename); |
912 | if (!handle) { | 931 | if (!handle) { |
913 | warning("Could not open %s", filename); | 932 | warning("Could not open %s", filename); |
914 | g_free(filename); | ||
915 | return; | 933 | return; |
916 | } | 934 | } |
917 | 935 | ||
918 | g_free(filename); | ||
919 | |||
920 | system = tracecmd_xml_find_system(handle, "CaptureSettings"); | 936 | system = tracecmd_xml_find_system(handle, "CaptureSettings"); |
921 | if (!system) | 937 | if (!system) |
922 | goto out; | 938 | goto out; |
@@ -930,8 +946,15 @@ static void load_settings_clicked(GtkWidget *widget, gpointer data) | |||
930 | 946 | ||
931 | do { | 947 | do { |
932 | name = tracecmd_xml_node_type(syschild); | 948 | name = tracecmd_xml_node_type(syschild); |
933 | if (strcmp(name, "Events") == 0) | 949 | if (strcmp(name, "Events") == 0) { |
934 | load_cap_events(cap, handle, syschild); | 950 | load_cap_events(cap, handle, syschild); |
951 | trace_update_event_view(cap->event_view, | ||
952 | cap->pevent, | ||
953 | NULL, | ||
954 | info->cap_all_events, | ||
955 | info->cap_systems, | ||
956 | info->cap_events); | ||
957 | } | ||
935 | 958 | ||
936 | else if (strcmp(name, "Plugin") == 0) { | 959 | else if (strcmp(name, "Plugin") == 0) { |
937 | plugin = tracecmd_xml_node_value(handle, syschild); | 960 | plugin = tracecmd_xml_node_value(handle, syschild); |
@@ -958,6 +981,46 @@ static void load_settings_clicked(GtkWidget *widget, gpointer data) | |||
958 | tracecmd_xml_close(handle); | 981 | tracecmd_xml_close(handle); |
959 | } | 982 | } |
960 | 983 | ||
984 | static void settings_changed(GtkComboBox *combo, | ||
985 | gpointer data) | ||
986 | { | ||
987 | struct trace_capture *cap = data; | ||
988 | GtkTreeModel *model; | ||
989 | GtkTreeIter iter; | ||
990 | gchar *text; | ||
991 | |||
992 | model = gtk_combo_box_get_model(combo); | ||
993 | if (!model) | ||
994 | return; | ||
995 | |||
996 | if (!gtk_combo_box_get_active_iter(combo, &iter)) | ||
997 | return; | ||
998 | |||
999 | gtk_tree_model_get(model, &iter, | ||
1000 | 1, &text, | ||
1001 | -1); | ||
1002 | |||
1003 | if (text && strlen(text)) | ||
1004 | load_settings(cap, text); | ||
1005 | |||
1006 | g_free(text); | ||
1007 | } | ||
1008 | |||
1009 | static void import_settings_clicked(GtkWidget *widget, gpointer data) | ||
1010 | { | ||
1011 | struct trace_capture *cap = data; | ||
1012 | gchar *filename; | ||
1013 | |||
1014 | filename = trace_get_file_dialog_filter("Import Settings", NULL, | ||
1015 | TRACE_DIALOG_FILTER_SETTING, FALSE); | ||
1016 | if (!filename) | ||
1017 | return; | ||
1018 | |||
1019 | load_settings(cap, filename); | ||
1020 | |||
1021 | g_free(filename); | ||
1022 | } | ||
1023 | |||
961 | static void save_events(struct trace_capture *cap, | 1024 | static void save_events(struct trace_capture *cap, |
962 | struct tracecmd_xml_handle *handle) | 1025 | struct tracecmd_xml_handle *handle) |
963 | { | 1026 | { |
@@ -989,27 +1052,20 @@ static void save_events(struct trace_capture *cap, | |||
989 | tracecmd_xml_end_sub_system(handle); | 1052 | tracecmd_xml_end_sub_system(handle); |
990 | } | 1053 | } |
991 | 1054 | ||
992 | static void save_settings_clicked(GtkWidget *widget, gpointer data) | 1055 | static void save_settings(struct trace_capture *cap, const char *filename) |
993 | { | 1056 | { |
994 | struct trace_capture *cap = data; | ||
995 | struct shark_info *info = cap->info; | 1057 | struct shark_info *info = cap->info; |
996 | struct tracecmd_xml_handle *handle; | 1058 | struct tracecmd_xml_handle *handle; |
997 | gchar *filename; | ||
998 | const char *file; | 1059 | const char *file; |
999 | const char *command; | 1060 | const char *command; |
1000 | 1061 | ||
1001 | filename = trace_get_file_dialog("Save Settings", "Save", TRUE); | ||
1002 | if (!filename) | ||
1003 | return; | ||
1004 | |||
1005 | handle = tracecmd_xml_create(filename, VERSION_STRING); | 1062 | handle = tracecmd_xml_create(filename, VERSION_STRING); |
1006 | if (!handle) { | 1063 | if (!handle) { |
1007 | warning("Could not create %s", filename); | 1064 | warning("Could not create %s", filename); |
1008 | g_free(filename); | ||
1009 | return; | 1065 | return; |
1010 | } | 1066 | } |
1011 | 1067 | ||
1012 | g_free(filename); | 1068 | update_events(cap); |
1013 | 1069 | ||
1014 | tracecmd_xml_start_system(handle, "CaptureSettings"); | 1070 | tracecmd_xml_start_system(handle, "CaptureSettings"); |
1015 | 1071 | ||
@@ -1041,6 +1097,99 @@ static void save_settings_clicked(GtkWidget *widget, gpointer data) | |||
1041 | tracecmd_xml_close(handle); | 1097 | tracecmd_xml_close(handle); |
1042 | } | 1098 | } |
1043 | 1099 | ||
1100 | static void save_settings_clicked(GtkWidget *widget, gpointer data) | ||
1101 | { | ||
1102 | struct trace_capture *cap = data; | ||
1103 | struct stat st; | ||
1104 | GtkWidget *dialog; | ||
1105 | GtkWidget *hbox; | ||
1106 | GtkWidget *label; | ||
1107 | GtkWidget *entry; | ||
1108 | GString *file; | ||
1109 | const char *name; | ||
1110 | gint result; | ||
1111 | int ret; | ||
1112 | |||
1113 | dialog = gtk_dialog_new_with_buttons("Save Settings", | ||
1114 | NULL, | ||
1115 | GTK_DIALOG_MODAL, | ||
1116 | GTK_STOCK_OK, | ||
1117 | GTK_RESPONSE_ACCEPT, | ||
1118 | GTK_STOCK_CANCEL, | ||
1119 | GTK_RESPONSE_REJECT, | ||
1120 | NULL); | ||
1121 | |||
1122 | hbox = gtk_hbox_new(FALSE, 0); | ||
1123 | gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), hbox, FALSE, FALSE, 0); | ||
1124 | gtk_widget_show(hbox); | ||
1125 | |||
1126 | label = gtk_label_new("Settings Name: "); | ||
1127 | gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0); | ||
1128 | gtk_widget_show(label); | ||
1129 | |||
1130 | entry = gtk_entry_new(); | ||
1131 | gtk_box_pack_start(GTK_BOX(hbox), entry, FALSE, FALSE, 0); | ||
1132 | gtk_widget_show(entry); | ||
1133 | |||
1134 | again: | ||
1135 | result = gtk_dialog_run(GTK_DIALOG(dialog)); | ||
1136 | switch (result) { | ||
1137 | case GTK_RESPONSE_ACCEPT: | ||
1138 | name = gtk_entry_get_text(GTK_ENTRY(entry)); | ||
1139 | if (!name || is_just_ws(name)) { | ||
1140 | warning("Must enter a name"); | ||
1141 | goto again; | ||
1142 | } | ||
1143 | /* Make sure home settings exists */ | ||
1144 | if (create_home_settings() < 0) | ||
1145 | break; | ||
1146 | file = get_home_settings_new(); | ||
1147 | g_string_append_printf(file, "/%s.kss", name); | ||
1148 | ret = stat(file->str, &st); | ||
1149 | if (ret >= 0) { | ||
1150 | ret = trace_dialog(GTK_WINDOW(dialog), TRACE_GUI_ASK, | ||
1151 | "The setting '%s' already exists.\n" | ||
1152 | "Are you sure you want to replace it", | ||
1153 | name); | ||
1154 | if (ret == GTK_RESPONSE_NO) { | ||
1155 | g_string_free(file, TRUE); | ||
1156 | goto again; | ||
1157 | } | ||
1158 | } | ||
1159 | save_settings(cap, file->str); | ||
1160 | |||
1161 | refresh_settings(cap); | ||
1162 | g_free(cap->info->cap_settings_name); | ||
1163 | cap->info->cap_settings_name = g_strdup(name); | ||
1164 | set_settings(cap); | ||
1165 | |||
1166 | g_string_free(file, TRUE); | ||
1167 | break; | ||
1168 | |||
1169 | case GTK_RESPONSE_REJECT: | ||
1170 | break; | ||
1171 | default: | ||
1172 | break; | ||
1173 | }; | ||
1174 | |||
1175 | gtk_widget_destroy(dialog); | ||
1176 | } | ||
1177 | |||
1178 | static void export_settings_clicked(GtkWidget *widget, gpointer data) | ||
1179 | { | ||
1180 | struct trace_capture *cap = data; | ||
1181 | gchar *filename; | ||
1182 | |||
1183 | filename = trace_get_file_dialog_filter("Save Settings", "Save", | ||
1184 | TRACE_DIALOG_FILTER_SETTING, TRUE); | ||
1185 | if (!filename) | ||
1186 | return; | ||
1187 | |||
1188 | save_settings(cap, filename); | ||
1189 | |||
1190 | g_free(filename); | ||
1191 | } | ||
1192 | |||
1044 | static GtkTreeModel *create_plugin_combo_model(gpointer data) | 1193 | static GtkTreeModel *create_plugin_combo_model(gpointer data) |
1045 | { | 1194 | { |
1046 | char **plugins = data; | 1195 | char **plugins = data; |
@@ -1065,20 +1214,71 @@ static GtkTreeModel *create_plugin_combo_model(gpointer data) | |||
1065 | return GTK_TREE_MODEL(list); | 1214 | return GTK_TREE_MODEL(list); |
1066 | } | 1215 | } |
1067 | 1216 | ||
1217 | static void insert_text(GtkEditable *buffer, | ||
1218 | gchar *new_text, | ||
1219 | gint new_text_length, | ||
1220 | gint *position, | ||
1221 | gpointer data) | ||
1222 | { | ||
1223 | int i; | ||
1224 | guint sigid; | ||
1225 | |||
1226 | /* Only allow 0-9 to be written to the entry */ | ||
1227 | for (i = 0; i < new_text_length; i++) { | ||
1228 | if (new_text[i] < '0' || new_text[i] > '9') { | ||
1229 | sigid = g_signal_lookup("insert-text", | ||
1230 | G_OBJECT_TYPE(buffer)); | ||
1231 | g_signal_stop_emission(buffer, sigid, 0); | ||
1232 | return; | ||
1233 | } | ||
1234 | } | ||
1235 | } | ||
1236 | |||
1237 | /* | ||
1238 | * Trace Capture Dialog Window | ||
1239 | * | ||
1240 | * +--------------------------------------------------------------------+ | ||
1241 | * | Dialog Window | | ||
1242 | * | +-------------------------------+-------------------------------+ | | ||
1243 | * | | Paned Window | +---------------------------+ | | | ||
1244 | * | | +---------------------------+ | | Scroll window | | | | ||
1245 | * | | | Hbox | | | +-----------------------+ | | | | ||
1246 | * | | | Label Plugin Combo | | | | Event Tree | | | | | ||
1247 | * | | +---------------------------+ | | | | | | | | ||
1248 | * | | | | | | | | | | ||
1249 | * | | | | +-----------------------+ | | | | ||
1250 | * | | | +---------------------------+ | | | ||
1251 | * | +-------------------------------+-------------------------------+ | | ||
1252 | * +--------------------------------------------------------------------+ | ||
1253 | */ | ||
1068 | static void tracing_dialog(struct shark_info *info, const char *tracing) | 1254 | static void tracing_dialog(struct shark_info *info, const char *tracing) |
1069 | { | 1255 | { |
1070 | struct pevent *pevent; | 1256 | struct pevent *pevent; |
1071 | GtkWidget *dialog; | 1257 | GtkWidget *dialog; |
1072 | GtkWidget *button; | 1258 | GtkWidget *button; |
1073 | GtkWidget *hbox; | ||
1074 | GtkWidget *combo; | 1259 | GtkWidget *combo; |
1075 | GtkWidget *label; | 1260 | GtkWidget *label; |
1076 | GtkWidget *entry; | 1261 | GtkWidget *entry; |
1262 | GtkWidget *frame; | ||
1263 | GtkWidget *vbox; | ||
1264 | GtkWidget *scrollwin; | ||
1265 | GtkWidget *table; | ||
1266 | GtkWidget *table2; | ||
1267 | GtkWidget *event_tree; | ||
1268 | GtkWidget *viewport; | ||
1269 | GtkWidget *textview; | ||
1270 | GtkWidget *hbox; | ||
1271 | GtkTextBuffer *buffer; | ||
1272 | GtkTextIter start_iter; | ||
1273 | GtkTextIter end_iter; | ||
1077 | char **plugins; | 1274 | char **plugins; |
1078 | int nr_plugins; | 1275 | int nr_plugins; |
1079 | struct trace_capture cap; | 1276 | struct trace_capture cap; |
1080 | const gchar *file; | 1277 | const gchar *file; |
1081 | const char *command; | 1278 | const char *command; |
1279 | const char *val; | ||
1280 | GString *str; | ||
1281 | gint result; | ||
1082 | 1282 | ||
1083 | memset(&cap, 0, sizeof(cap)); | 1283 | memset(&cap, 0, sizeof(cap)); |
1084 | 1284 | ||
@@ -1105,42 +1305,146 @@ static void tracing_dialog(struct shark_info *info, const char *tracing) | |||
1105 | return; | 1305 | return; |
1106 | } | 1306 | } |
1107 | 1307 | ||
1108 | dialog = gtk_dialog_new_with_buttons("Capture", | 1308 | dialog = gtk_dialog_new(); |
1109 | NULL, | 1309 | gtk_window_set_title(GTK_WINDOW(dialog), "Capture"); |
1110 | GTK_DIALOG_MODAL, | 1310 | |
1111 | "Done", | 1311 | button = gtk_button_new_with_label("Run"); |
1112 | GTK_RESPONSE_ACCEPT, | 1312 | gtk_dialog_add_action_widget(GTK_DIALOG(dialog), button, |
1113 | NULL); | 1313 | GTK_RESPONSE_ACCEPT); |
1314 | gtk_widget_show(button); | ||
1315 | |||
1316 | cap.run_button = button; | ||
1317 | |||
1318 | gtk_dialog_add_button(GTK_DIALOG(dialog), GTK_STOCK_CLOSE, | ||
1319 | GTK_RESPONSE_REJECT); | ||
1114 | 1320 | ||
1115 | cap.main_dialog = dialog; | 1321 | cap.main_dialog = dialog; |
1116 | 1322 | ||
1323 | /* --- Top Level Hpaned --- */ | ||
1324 | table = gtk_table_new(4, 2, FALSE); | ||
1325 | |||
1326 | /* It is possible that no pevents exist. */ | ||
1117 | if (pevent) { | 1327 | if (pevent) { |
1118 | button = gtk_button_new_with_label("Select Events"); | 1328 | |
1119 | gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), | 1329 | scrollwin = gtk_scrolled_window_new(NULL, NULL); |
1120 | button, TRUE, TRUE, 0); | 1330 | gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrollwin), |
1121 | gtk_widget_show(button); | 1331 | GTK_POLICY_AUTOMATIC, |
1122 | 1332 | GTK_POLICY_AUTOMATIC); | |
1123 | g_signal_connect (button, "clicked", | 1333 | |
1124 | G_CALLBACK (event_button_clicked), | 1334 | gtk_table_attach(GTK_TABLE(table), scrollwin, 0, 1, 1, 2, |
1125 | (gpointer)&cap); | 1335 | GTK_FILL, GTK_FILL|GTK_EXPAND, 0, 0); |
1336 | gtk_widget_show(scrollwin); | ||
1337 | |||
1338 | event_tree = trace_create_event_list_view(pevent, NULL, | ||
1339 | cap.info->cap_all_events, | ||
1340 | cap.info->cap_systems, | ||
1341 | cap.info->cap_events); | ||
1342 | |||
1343 | gtk_container_add(GTK_CONTAINER(scrollwin), event_tree); | ||
1344 | gtk_widget_show(event_tree); | ||
1345 | |||
1346 | cap.event_view = event_tree; | ||
1347 | |||
1348 | } else { | ||
1349 | /* No events */ | ||
1350 | label = gtk_label_new("No events enabled on system"); | ||
1351 | gtk_table_attach(GTK_TABLE(table), label, 0, 1, 1, 2, | ||
1352 | GTK_FILL, GTK_EXPAND|GTK_FILL, | ||
1353 | 0, 10); | ||
1354 | gtk_widget_show(label); | ||
1355 | cap.event_view = NULL; | ||
1126 | } | 1356 | } |
1127 | 1357 | ||
1128 | hbox = gtk_hbox_new(FALSE, 0); | 1358 | gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), table, TRUE, TRUE, 0); |
1129 | gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), hbox, TRUE, TRUE, 0); | 1359 | gtk_widget_show(table); |
1130 | gtk_widget_show(hbox); | 1360 | |
1361 | /*------------------ Frame Settings --------------------------- */ | ||
1362 | |||
1363 | frame = gtk_frame_new("Settings"); | ||
1364 | gtk_table_attach(GTK_TABLE(table), frame, 0, 1, 0, 1, | ||
1365 | GTK_FILL, 0, 0, 10); | ||
1366 | gtk_widget_show(frame); | ||
1367 | |||
1368 | table2 = gtk_table_new(2, 3, FALSE); | ||
1369 | gtk_container_add(GTK_CONTAINER(frame), table2); | ||
1370 | gtk_widget_show(table2); | ||
1371 | |||
1372 | gtk_table_set_col_spacings(GTK_TABLE(table2), 5); | ||
1373 | |||
1374 | button = gtk_button_new_with_label("Save Settings"); | ||
1375 | gtk_table_attach_defaults(GTK_TABLE(table2), button, 0, 1, 0, 1); | ||
1376 | gtk_widget_show(button); | ||
1377 | |||
1378 | g_signal_connect (button, "clicked", | ||
1379 | G_CALLBACK (save_settings_clicked), | ||
1380 | (gpointer)&cap); | ||
1381 | |||
1382 | button = gtk_button_new_with_label("Import Settings"); | ||
1383 | gtk_table_attach_defaults(GTK_TABLE(table2), button, 1, 2, 0, 1); | ||
1384 | gtk_widget_show(button); | ||
1385 | |||
1386 | g_signal_connect (button, "clicked", | ||
1387 | G_CALLBACK (import_settings_clicked), | ||
1388 | (gpointer)&cap); | ||
1131 | 1389 | ||
1132 | combo = trace_create_combo_box(hbox, "Plugin: ", create_plugin_combo_model, plugins); | 1390 | |
1391 | button = gtk_button_new_with_label("Export Settings"); | ||
1392 | gtk_table_attach_defaults(GTK_TABLE(table2), button, 2, 3, 0, 1); | ||
1393 | gtk_widget_show(button); | ||
1394 | |||
1395 | g_signal_connect (button, "clicked", | ||
1396 | G_CALLBACK (export_settings_clicked), | ||
1397 | (gpointer)&cap); | ||
1398 | |||
1399 | if (cap.info->cap_settings_name) | ||
1400 | set_settings(&cap); | ||
1401 | |||
1402 | label = gtk_label_new("Available Settings: "); | ||
1403 | gtk_table_attach_defaults(GTK_TABLE(table2), label, 0, 1, 1, 2); | ||
1404 | gtk_widget_show(label); | ||
1405 | |||
1406 | combo = trace_create_combo_box(NULL, NULL, | ||
1407 | create_settings_model, NULL); | ||
1408 | gtk_table_attach_defaults(GTK_TABLE(table2), combo, 1, 3, 1, 2); | ||
1409 | |||
1410 | cap.settings_combo = combo; | ||
1411 | |||
1412 | g_signal_connect (combo, "changed", | ||
1413 | G_CALLBACK (settings_changed), | ||
1414 | (gpointer)&cap); | ||
1415 | |||
1416 | |||
1417 | |||
1418 | /*------------------ Frame Settings --------------------------- */ | ||
1419 | |||
1420 | frame = gtk_frame_new("Execute"); | ||
1421 | gtk_table_attach(GTK_TABLE(table), frame, 0, 1, 3, 4, | ||
1422 | GTK_FILL, 0, 0, 10); | ||
1423 | gtk_widget_show(frame); | ||
1424 | |||
1425 | table2 = gtk_table_new(3, 3, FALSE); | ||
1426 | gtk_container_add(GTK_CONTAINER(frame), table2); | ||
1427 | gtk_widget_show(table2); | ||
1428 | |||
1429 | label = gtk_label_new("Plugin: "); | ||
1430 | gtk_table_attach_defaults(GTK_TABLE(table2), label, 0, 1, 0, 1); | ||
1431 | gtk_widget_show(label); | ||
1432 | |||
1433 | combo = trace_create_combo_box(NULL, NULL, create_plugin_combo_model, plugins); | ||
1133 | cap.plugin_combo = combo; | 1434 | cap.plugin_combo = combo; |
1134 | 1435 | ||
1436 | gtk_table_attach_defaults(GTK_TABLE(table2), combo, 1, 3, 0, 1); | ||
1437 | |||
1135 | if (cap.info->cap_plugin) | 1438 | if (cap.info->cap_plugin) |
1136 | set_plugin(&cap); | 1439 | set_plugin(&cap); |
1137 | 1440 | ||
1441 | |||
1138 | label = gtk_label_new("Command:"); | 1442 | label = gtk_label_new("Command:"); |
1139 | gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), label, TRUE, TRUE, 0); | 1443 | gtk_table_attach_defaults(GTK_TABLE(table2), label, 0, 1, 1, 2); |
1140 | gtk_widget_show(label); | 1444 | gtk_widget_show(label); |
1141 | 1445 | ||
1142 | entry = gtk_entry_new(); | 1446 | entry = gtk_entry_new(); |
1143 | gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), entry, TRUE, TRUE, 0); | 1447 | gtk_table_attach_defaults(GTK_TABLE(table2), entry, 1, 3, 1, 2); |
1144 | gtk_widget_show(entry); | 1448 | gtk_widget_show(entry); |
1145 | 1449 | ||
1146 | cap.command_entry = entry; | 1450 | cap.command_entry = entry; |
@@ -1148,20 +1452,12 @@ static void tracing_dialog(struct shark_info *info, const char *tracing) | |||
1148 | if (cap.info->cap_command) | 1452 | if (cap.info->cap_command) |
1149 | gtk_entry_set_text(GTK_ENTRY(entry), cap.info->cap_command); | 1453 | gtk_entry_set_text(GTK_ENTRY(entry), cap.info->cap_command); |
1150 | 1454 | ||
1151 | hbox = gtk_hbox_new(FALSE, 0); | 1455 | label = gtk_label_new("Output file: "); |
1152 | gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), hbox, TRUE, TRUE, 0); | 1456 | gtk_table_attach_defaults(GTK_TABLE(table2), label, 0, 1, 2, 3); |
1153 | gtk_widget_show(hbox); | 1457 | gtk_widget_show(label); |
1154 | |||
1155 | button = gtk_button_new_with_label("Save file: "); | ||
1156 | gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 0); | ||
1157 | gtk_widget_show(button); | ||
1158 | |||
1159 | g_signal_connect (button, "clicked", | ||
1160 | G_CALLBACK (file_clicked), | ||
1161 | (gpointer)&cap); | ||
1162 | 1458 | ||
1163 | entry = gtk_entry_new(); | 1459 | entry = gtk_entry_new(); |
1164 | gtk_box_pack_start(GTK_BOX(hbox), entry, TRUE, TRUE, 0); | 1460 | gtk_table_attach_defaults(GTK_TABLE(table2), entry, 1, 2, 2, 3); |
1165 | gtk_widget_show(entry); | 1461 | gtk_widget_show(entry); |
1166 | 1462 | ||
1167 | if (cap.info->cap_file) | 1463 | if (cap.info->cap_file) |
@@ -1172,34 +1468,108 @@ static void tracing_dialog(struct shark_info *info, const char *tracing) | |||
1172 | gtk_entry_set_text(GTK_ENTRY(entry), file); | 1468 | gtk_entry_set_text(GTK_ENTRY(entry), file); |
1173 | cap.file_entry = entry; | 1469 | cap.file_entry = entry; |
1174 | 1470 | ||
1175 | button = gtk_button_new_with_label("Execute"); | 1471 | button = gtk_button_new_with_label("Browse"); |
1176 | gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), button, TRUE, TRUE, 0); | 1472 | gtk_table_attach_defaults(GTK_TABLE(table2), button, 2, 3, 2, 3); |
1177 | gtk_widget_show(button); | 1473 | gtk_widget_show(button); |
1178 | 1474 | ||
1179 | g_signal_connect (button, "clicked", | 1475 | g_signal_connect (button, "clicked", |
1180 | G_CALLBACK (execute_button_clicked), | 1476 | G_CALLBACK (file_clicked), |
1181 | (gpointer)&cap); | 1477 | (gpointer)&cap); |
1182 | 1478 | ||
1183 | 1479 | ||
1184 | button = gtk_button_new_with_label("Load Settings"); | 1480 | /*------------------ Command Output ------------------ */ |
1185 | gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), button, TRUE, TRUE, 0); | ||
1186 | gtk_widget_show(button); | ||
1187 | 1481 | ||
1188 | g_signal_connect (button, "clicked", | 1482 | vbox = gtk_vbox_new(FALSE, 0); |
1189 | G_CALLBACK (load_settings_clicked), | 1483 | gtk_table_attach_defaults(GTK_TABLE(table), vbox, 1, 2, 0, 4); |
1190 | (gpointer)&cap); | 1484 | gtk_widget_show(vbox); |
1485 | gtk_widget_set_size_request(GTK_WIDGET(vbox), 500, 0); | ||
1191 | 1486 | ||
1192 | 1487 | ||
1193 | button = gtk_button_new_with_label("Save Settings"); | 1488 | label = gtk_label_new("Output Display:"); |
1194 | gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), button, TRUE, TRUE, 0); | 1489 | gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0); |
1195 | gtk_widget_show(button); | 1490 | gtk_widget_show(label); |
1196 | 1491 | ||
1197 | g_signal_connect (button, "clicked", | 1492 | scrollwin = gtk_scrolled_window_new(NULL, NULL); |
1198 | G_CALLBACK (save_settings_clicked), | 1493 | gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrollwin), |
1494 | GTK_POLICY_AUTOMATIC, | ||
1495 | GTK_POLICY_AUTOMATIC); | ||
1496 | gtk_box_pack_start(GTK_BOX(vbox), scrollwin, TRUE, TRUE, 0); | ||
1497 | gtk_widget_show(scrollwin); | ||
1498 | |||
1499 | viewport = gtk_viewport_new(NULL, NULL); | ||
1500 | gtk_widget_show(viewport); | ||
1501 | |||
1502 | gtk_container_add(GTK_CONTAINER(scrollwin), viewport); | ||
1503 | |||
1504 | textview = gtk_text_view_new(); | ||
1505 | buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(textview)); | ||
1506 | |||
1507 | gtk_container_add(GTK_CONTAINER(viewport), textview); | ||
1508 | gtk_widget_show(textview); | ||
1509 | |||
1510 | cap.output_text = textview; | ||
1511 | cap.output_buffer = buffer; | ||
1512 | |||
1513 | /* set the buffer from its previous setting */ | ||
1514 | if (info->cap_buffer_output) | ||
1515 | gtk_text_buffer_set_text(buffer, info->cap_buffer_output, | ||
1516 | strlen(info->cap_buffer_output)); | ||
1517 | |||
1518 | hbox = gtk_hbox_new(FALSE, 0); | ||
1519 | gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0); | ||
1520 | gtk_widget_show(hbox); | ||
1521 | |||
1522 | label = gtk_label_new("Max # of characters in output display: "); | ||
1523 | gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0); | ||
1524 | gtk_widget_show(label); | ||
1525 | |||
1526 | entry = gtk_entry_new(); | ||
1527 | gtk_box_pack_start(GTK_BOX(hbox), entry, FALSE, FALSE, 0); | ||
1528 | gtk_widget_show(entry); | ||
1529 | |||
1530 | cap.max_num_entry = entry; | ||
1531 | |||
1532 | if (!info->cap_max_buf_size) | ||
1533 | info->cap_max_buf_size = DEFAULT_MAX_BUF_SIZE; | ||
1534 | |||
1535 | str = g_string_new(""); | ||
1536 | g_string_append_printf(str, "%d", info->cap_max_buf_size); | ||
1537 | gtk_entry_set_text(GTK_ENTRY(entry), str->str); | ||
1538 | g_string_free(str, TRUE); | ||
1539 | |||
1540 | g_signal_connect (entry, "insert-text", | ||
1541 | G_CALLBACK (insert_text), | ||
1199 | (gpointer)&cap); | 1542 | (gpointer)&cap); |
1200 | 1543 | ||
1544 | |||
1545 | gtk_widget_set_size_request(GTK_WIDGET(dialog), | ||
1546 | DIALOG_WIDTH, DIALOG_HEIGHT); | ||
1547 | |||
1201 | gtk_widget_show(dialog); | 1548 | gtk_widget_show(dialog); |
1202 | gtk_dialog_run(GTK_DIALOG(dialog)); | 1549 | |
1550 | cont: | ||
1551 | result = gtk_dialog_run(GTK_DIALOG(dialog)); | ||
1552 | |||
1553 | if (result == GTK_RESPONSE_ACCEPT) { | ||
1554 | execute_button_clicked(&cap); | ||
1555 | goto cont; | ||
1556 | } | ||
1557 | |||
1558 | /* Make sure no capture is running */ | ||
1559 | end_capture(&cap); | ||
1560 | |||
1561 | /* Get the max buffer size */ | ||
1562 | val = gtk_entry_get_text(GTK_ENTRY(entry)); | ||
1563 | info->cap_max_buf_size = atoi(val); | ||
1564 | |||
1565 | gtk_text_buffer_get_start_iter(cap.output_buffer, &start_iter); | ||
1566 | gtk_text_buffer_get_end_iter(cap.output_buffer, &end_iter); | ||
1567 | |||
1568 | g_free(info->cap_buffer_output); | ||
1569 | info->cap_buffer_output = gtk_text_buffer_get_text(cap.output_buffer, | ||
1570 | &start_iter, | ||
1571 | &end_iter, | ||
1572 | FALSE); | ||
1203 | 1573 | ||
1204 | /* save the plugin and file to reuse if we come back */ | 1574 | /* save the plugin and file to reuse if we come back */ |
1205 | update_plugin(&cap); | 1575 | update_plugin(&cap); |
@@ -1214,12 +1584,9 @@ static void tracing_dialog(struct shark_info *info, const char *tracing) | |||
1214 | else | 1584 | else |
1215 | cap.info->cap_command = NULL; | 1585 | cap.info->cap_command = NULL; |
1216 | 1586 | ||
1217 | gtk_widget_destroy(dialog); | 1587 | update_events(&cap); |
1218 | 1588 | ||
1219 | end_capture(&cap); | 1589 | gtk_widget_destroy(dialog); |
1220 | |||
1221 | if (cap.output_dialog) | ||
1222 | gtk_widget_destroy(cap.output_dialog); | ||
1223 | 1590 | ||
1224 | if (pevent) | 1591 | if (pevent) |
1225 | pevent_free(pevent); | 1592 | pevent_free(pevent); |