diff options
author | Steven Rostedt <srostedt@redhat.com> | 2010-02-19 10:11:38 -0500 |
---|---|---|
committer | Steven Rostedt <rostedt@goodmis.org> | 2010-02-19 10:11:38 -0500 |
commit | 187d3cc1a0c4569ac8acf2261a7ac3f5d46616a9 (patch) | |
tree | b0c3b906dfaa1fa800fef0e54555bea5a862fb23 | |
parent | 32b0f9256e7411e0fe658bf0d0cf6b034c67e9da (diff) |
trace-filter: Add available event and fields for advanced filter
Add a combo box of events and a combo box of fields that are
available for the advanced filter.
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
-rw-r--r-- | trace-filter.c | 381 |
1 files changed, 376 insertions, 5 deletions
diff --git a/trace-filter.c b/trace-filter.c index f8d2271..54333ee 100644 --- a/trace-filter.c +++ b/trace-filter.c | |||
@@ -30,11 +30,12 @@ | |||
30 | 30 | ||
31 | #include "cpu.h" | 31 | #include "cpu.h" |
32 | #include "util.h" | 32 | #include "util.h" |
33 | #include "list.h" | ||
33 | 34 | ||
34 | #define DIALOG_WIDTH 400 | 35 | #define DIALOG_WIDTH 400 |
35 | #define DIALOG_HEIGHT 600 | 36 | #define DIALOG_HEIGHT 600 |
36 | 37 | ||
37 | #define TEXT_DIALOG_WIDTH 450 | 38 | #define TEXT_DIALOG_WIDTH 500 |
38 | #define TEXT_DIALOG_HEIGHT 400 | 39 | #define TEXT_DIALOG_HEIGHT 400 |
39 | 40 | ||
40 | int str_cmp(const void *a, const void *b) | 41 | int str_cmp(const void *a, const void *b) |
@@ -89,13 +90,373 @@ void trace_array_add(gint **array, gint *count, gint val) | |||
89 | (*array)[*count] = -1; | 90 | (*array)[*count] = -1; |
90 | } | 91 | } |
91 | 92 | ||
93 | /* --- event info box --- */ | ||
94 | |||
95 | struct event_combo_info { | ||
96 | struct pevent *pevent; | ||
97 | GtkWidget *event_combo; | ||
98 | GtkWidget *field_combo; | ||
99 | }; | ||
100 | |||
92 | struct adv_event_filter_helper { | 101 | struct adv_event_filter_helper { |
93 | trace_adv_filter_cb_func func; | 102 | trace_adv_filter_cb_func func; |
94 | GtkTreeView *view; | 103 | GtkTreeView *view; |
95 | GtkWidget *entry; | 104 | GtkWidget *entry; |
105 | struct event_combo_info combo_info; | ||
96 | gpointer data; | 106 | gpointer data; |
97 | }; | 107 | }; |
98 | 108 | ||
109 | static GtkTreeModel *create_event_combo_model(struct pevent *pevent) | ||
110 | { | ||
111 | GtkTreeStore *tree; | ||
112 | GtkTreeIter sys_iter; | ||
113 | GtkTreeIter iter; | ||
114 | struct event_format **events; | ||
115 | struct event_format *event; | ||
116 | const char *last_sys = NULL; | ||
117 | int i; | ||
118 | |||
119 | events = pevent_list_events(pevent, EVENT_SORT_SYSTEM); | ||
120 | if (!events) | ||
121 | return NULL; | ||
122 | |||
123 | tree = gtk_tree_store_new(1, G_TYPE_STRING); | ||
124 | |||
125 | |||
126 | for (i = 0; events[i]; i++) { | ||
127 | event = events[i]; | ||
128 | if (!last_sys || strcmp(last_sys, event->system) != 0) { | ||
129 | last_sys = event->system; | ||
130 | |||
131 | gtk_tree_store_append(tree, &sys_iter, NULL); | ||
132 | gtk_tree_store_set(tree, &sys_iter, | ||
133 | 0, last_sys, | ||
134 | -1); | ||
135 | } | ||
136 | gtk_tree_store_append(tree, &iter, &sys_iter); | ||
137 | gtk_tree_store_set(tree, &iter, | ||
138 | 0, event->name, | ||
139 | -1); | ||
140 | } | ||
141 | |||
142 | return GTK_TREE_MODEL(tree); | ||
143 | } | ||
144 | |||
145 | static GtkTreeModel *create_field_combo_model(struct pevent *pevent) | ||
146 | { | ||
147 | GtkListStore *list; | ||
148 | GtkTreeIter iter; | ||
149 | struct event_format **events; | ||
150 | struct format_field **fields; | ||
151 | struct format_field *field; | ||
152 | int i; | ||
153 | |||
154 | events = pevent_list_events(pevent, EVENT_SORT_SYSTEM); | ||
155 | if (!events) | ||
156 | return NULL; | ||
157 | |||
158 | list = gtk_list_store_new(1, G_TYPE_STRING); | ||
159 | |||
160 | /* use any event for common fields */ | ||
161 | fields = pevent_event_common_fields(events[0]); | ||
162 | |||
163 | for (i = 0; fields[i]; i++) { | ||
164 | field = fields[i]; | ||
165 | gtk_list_store_append(list, &iter); | ||
166 | gtk_list_store_set(list, &iter, | ||
167 | 0, field->name, | ||
168 | -1); | ||
169 | } | ||
170 | |||
171 | free(fields); | ||
172 | |||
173 | return GTK_TREE_MODEL(list); | ||
174 | } | ||
175 | |||
176 | static void update_field_combo(struct pevent *pevent, | ||
177 | GtkWidget *combo, | ||
178 | const char *system, | ||
179 | const char *event_name) | ||
180 | { | ||
181 | struct event_format **events; | ||
182 | struct event_format *event; | ||
183 | struct format_field **fields; | ||
184 | struct format_field *field; | ||
185 | GtkTreeModel *model; | ||
186 | GtkListStore *list; | ||
187 | GtkTreeIter iter; | ||
188 | int i; | ||
189 | |||
190 | model = gtk_combo_box_get_model(GTK_COMBO_BOX(combo)); | ||
191 | if (!model) | ||
192 | return; | ||
193 | |||
194 | if (!gtk_tree_model_get_iter_first(model, &iter)) | ||
195 | return; | ||
196 | |||
197 | if (event_name) { | ||
198 | event = pevent_find_event_by_name(pevent, system, event_name); | ||
199 | if (!event) | ||
200 | return; | ||
201 | } else { | ||
202 | /* use any event */ | ||
203 | events = pevent_list_events(pevent, EVENT_SORT_SYSTEM); | ||
204 | if (!events) | ||
205 | return; | ||
206 | event = events[0]; | ||
207 | } | ||
208 | |||
209 | /* Remove all the objects and reset it */ | ||
210 | g_object_ref(model); | ||
211 | gtk_combo_box_set_model(GTK_COMBO_BOX(combo), NULL); | ||
212 | |||
213 | list = GTK_LIST_STORE(model); | ||
214 | |||
215 | while (gtk_list_store_remove(list, &iter)) | ||
216 | ; | ||
217 | |||
218 | /* always load the common fields first */ | ||
219 | fields = pevent_event_common_fields(event); | ||
220 | for (i = 0; fields[i]; i++) { | ||
221 | field = fields[i]; | ||
222 | gtk_list_store_append(list, &iter); | ||
223 | gtk_list_store_set(list, &iter, | ||
224 | 0, field->name, | ||
225 | -1); | ||
226 | } | ||
227 | free(fields); | ||
228 | |||
229 | /* Now add event specific events */ | ||
230 | if (event_name) { | ||
231 | fields = pevent_event_fields(event); | ||
232 | for (i = 0; fields[i]; i++) { | ||
233 | field = fields[i]; | ||
234 | gtk_list_store_append(list, &iter); | ||
235 | gtk_list_store_set(list, &iter, | ||
236 | 0, field->name, | ||
237 | -1); | ||
238 | } | ||
239 | free(fields); | ||
240 | } | ||
241 | gtk_combo_box_set_model(GTK_COMBO_BOX(combo), model); | ||
242 | g_object_unref(model); | ||
243 | |||
244 | if (!gtk_tree_model_get_iter_first(model, &iter)) | ||
245 | return; | ||
246 | gtk_combo_box_set_active_iter(GTK_COMBO_BOX(combo), &iter); | ||
247 | } | ||
248 | |||
249 | static void event_combo_changed(GtkComboBox *combo, gpointer data) | ||
250 | { | ||
251 | struct event_combo_info *info = data; | ||
252 | GtkWidget *field_combo = info->field_combo; | ||
253 | GtkTreeIter parent_iter; | ||
254 | GtkTreeIter iter; | ||
255 | GtkTreeModel *model; | ||
256 | GtkTreePath *path; | ||
257 | gchar *system_name = NULL; | ||
258 | gchar *event_name = NULL; | ||
259 | gint depth; | ||
260 | |||
261 | model = gtk_combo_box_get_model(combo); | ||
262 | if (!model) | ||
263 | return; | ||
264 | |||
265 | if (!gtk_combo_box_get_active_iter(combo, &iter)) | ||
266 | return; | ||
267 | |||
268 | path = gtk_tree_model_get_path(model, &iter); | ||
269 | if (!path) | ||
270 | return; | ||
271 | |||
272 | depth = gtk_tree_path_get_depth(path); | ||
273 | |||
274 | if (depth > 1) { | ||
275 | gtk_tree_model_get(model, &iter, | ||
276 | 0, &event_name, | ||
277 | -1); | ||
278 | gtk_tree_model_iter_parent(model, &parent_iter, | ||
279 | &iter); | ||
280 | gtk_tree_model_get(model, &parent_iter, | ||
281 | 0, &system_name, | ||
282 | -1); | ||
283 | } else | ||
284 | gtk_tree_model_get(model, &iter, | ||
285 | 0, &system_name, | ||
286 | -1); | ||
287 | |||
288 | update_field_combo(info->pevent, field_combo, | ||
289 | system_name, event_name); | ||
290 | |||
291 | g_free(system_name); | ||
292 | g_free(event_name); | ||
293 | gtk_tree_path_free(path); | ||
294 | } | ||
295 | |||
296 | static void insert_combo_text(struct event_combo_info *info, | ||
297 | GtkComboBox *combo) | ||
298 | { | ||
299 | struct adv_event_filter_helper *event_helper; | ||
300 | GtkTreeModel *model; | ||
301 | GtkTreeIter iter; | ||
302 | GtkWidget *entry; | ||
303 | gchar *text; | ||
304 | gint pos; | ||
305 | |||
306 | model = gtk_combo_box_get_model(combo); | ||
307 | if (!model) | ||
308 | return; | ||
309 | |||
310 | if (!gtk_combo_box_get_active_iter(combo, &iter)) | ||
311 | return; | ||
312 | |||
313 | gtk_tree_model_get(model, &iter, | ||
314 | 0, &text, | ||
315 | -1); | ||
316 | |||
317 | event_helper = container_of(info, typeof(*event_helper), combo_info); | ||
318 | entry = event_helper->entry; | ||
319 | |||
320 | pos = gtk_editable_get_position(GTK_EDITABLE(entry)); | ||
321 | gtk_editable_insert_text(GTK_EDITABLE(entry), text, strlen(text), &pos); | ||
322 | gtk_editable_set_position(GTK_EDITABLE(entry), pos); | ||
323 | |||
324 | g_free(text); | ||
325 | } | ||
326 | |||
327 | static void event_insert_pressed(GtkButton *button, | ||
328 | gpointer data) | ||
329 | { | ||
330 | struct event_combo_info *info = data; | ||
331 | |||
332 | insert_combo_text(info, GTK_COMBO_BOX(info->event_combo)); | ||
333 | } | ||
334 | |||
335 | static void field_insert_pressed(GtkButton *button, | ||
336 | gpointer data) | ||
337 | { | ||
338 | struct event_combo_info *info = data; | ||
339 | |||
340 | insert_combo_text(info, GTK_COMBO_BOX(info->field_combo)); | ||
341 | } | ||
342 | |||
343 | static GtkWidget *event_info_box(struct event_combo_info *info) | ||
344 | { | ||
345 | GtkWidget *hbox; | ||
346 | GtkWidget *hbox2; | ||
347 | GtkWidget *label; | ||
348 | GtkCellRenderer *renderer; | ||
349 | GtkTreeModel *model; | ||
350 | GtkWidget *event_combo; | ||
351 | GtkWidget *field_combo; | ||
352 | GtkWidget *button; | ||
353 | |||
354 | hbox = gtk_hbox_new(FALSE, 0); | ||
355 | |||
356 | hbox2 = gtk_hbox_new(FALSE, 0); | ||
357 | gtk_box_pack_start(GTK_BOX(hbox), hbox2, TRUE, TRUE, 0); | ||
358 | gtk_widget_show(hbox2); | ||
359 | |||
360 | |||
361 | label = gtk_label_new("Event:"); | ||
362 | gtk_box_pack_start(GTK_BOX(hbox2), label, FALSE, FALSE, 0); | ||
363 | gtk_widget_show(label); | ||
364 | |||
365 | /* --- Set up the event selection combo box --- */ | ||
366 | |||
367 | model = create_event_combo_model(info->pevent); | ||
368 | |||
369 | renderer = gtk_cell_renderer_text_new(); | ||
370 | |||
371 | event_combo = gtk_combo_box_new_with_model(model); | ||
372 | gtk_box_pack_start(GTK_BOX(hbox2), event_combo, FALSE, FALSE, 0); | ||
373 | gtk_widget_show(event_combo); | ||
374 | |||
375 | /* Free model with combobox */ | ||
376 | g_object_unref(model); | ||
377 | |||
378 | gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(event_combo), | ||
379 | renderer, | ||
380 | TRUE); | ||
381 | gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(event_combo), | ||
382 | renderer, | ||
383 | "text", 0, | ||
384 | NULL); | ||
385 | |||
386 | gtk_combo_box_set_active(GTK_COMBO_BOX(event_combo), 0); | ||
387 | |||
388 | |||
389 | /* --- add insert button --- */ | ||
390 | |||
391 | button = gtk_button_new_with_label("Insert"); | ||
392 | gtk_box_pack_start(GTK_BOX(hbox2), button, FALSE, FALSE, 0); | ||
393 | gtk_widget_show(button); | ||
394 | |||
395 | |||
396 | g_signal_connect (button, "pressed", | ||
397 | G_CALLBACK (event_insert_pressed), | ||
398 | (gpointer) info); | ||
399 | |||
400 | |||
401 | /* --- second hbox ---- */ | ||
402 | |||
403 | hbox2 = gtk_hbox_new(FALSE, 0); | ||
404 | gtk_box_pack_start(GTK_BOX(hbox), hbox2, TRUE, TRUE, 0); | ||
405 | gtk_widget_show(hbox2); | ||
406 | |||
407 | label = gtk_label_new("Field:"); | ||
408 | gtk_box_pack_start(GTK_BOX(hbox2), label, FALSE, FALSE, 0); | ||
409 | gtk_widget_show(label); | ||
410 | |||
411 | |||
412 | /* --- Set up the field selection combo box --- */ | ||
413 | |||
414 | model = create_field_combo_model(info->pevent); | ||
415 | |||
416 | renderer = gtk_cell_renderer_text_new(); | ||
417 | |||
418 | field_combo = gtk_combo_box_new_with_model(model); | ||
419 | gtk_box_pack_start(GTK_BOX(hbox2), field_combo, FALSE, FALSE, 0); | ||
420 | gtk_widget_show(field_combo); | ||
421 | |||
422 | /* Free model with combobox */ | ||
423 | g_object_unref(model); | ||
424 | |||
425 | gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(field_combo), | ||
426 | renderer, | ||
427 | TRUE); | ||
428 | gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(field_combo), | ||
429 | renderer, | ||
430 | "text", 0, | ||
431 | NULL); | ||
432 | |||
433 | gtk_combo_box_set_active(GTK_COMBO_BOX(field_combo), 0); | ||
434 | |||
435 | |||
436 | /* --- add insert button --- */ | ||
437 | |||
438 | button = gtk_button_new_with_label("Insert"); | ||
439 | gtk_box_pack_start(GTK_BOX(hbox2), button, FALSE, FALSE, 0); | ||
440 | gtk_widget_show(button); | ||
441 | |||
442 | g_signal_connect (button, "pressed", | ||
443 | G_CALLBACK (field_insert_pressed), | ||
444 | (gpointer) info); | ||
445 | |||
446 | |||
447 | g_signal_connect (event_combo, "changed", | ||
448 | G_CALLBACK (event_combo_changed), | ||
449 | (gpointer) info); | ||
450 | |||
451 | info->event_combo = event_combo; | ||
452 | info->field_combo = field_combo; | ||
453 | |||
454 | return hbox; | ||
455 | } | ||
456 | |||
457 | |||
458 | /* --- advance filter --- */ | ||
459 | |||
99 | enum { | 460 | enum { |
100 | ADV_COL_DELETE, | 461 | ADV_COL_DELETE, |
101 | ADV_COL_EVENT, | 462 | ADV_COL_EVENT, |
@@ -266,9 +627,9 @@ create_adv_filter_view(struct tracecmd_input *handle, | |||
266 | 627 | ||
267 | view = gtk_tree_view_new(); | 628 | view = gtk_tree_view_new(); |
268 | 629 | ||
269 | renderer = gtk_cell_renderer_text_new(); | 630 | renderer = gtk_cell_renderer_text_new(); |
270 | 631 | ||
271 | togrend = gtk_cell_renderer_toggle_new(); | 632 | togrend = gtk_cell_renderer_toggle_new(); |
272 | 633 | ||
273 | /* --- delete column --- */ | 634 | /* --- delete column --- */ |
274 | 635 | ||
@@ -336,6 +697,7 @@ void trace_adv_filter_dialog(struct tracecmd_input *handle, | |||
336 | trace_adv_filter_cb_func func, | 697 | trace_adv_filter_cb_func func, |
337 | gpointer data) | 698 | gpointer data) |
338 | { | 699 | { |
700 | struct pevent *pevent; | ||
339 | struct dialog_helper *helper; | 701 | struct dialog_helper *helper; |
340 | struct adv_event_filter_helper *event_helper; | 702 | struct adv_event_filter_helper *event_helper; |
341 | GtkWidget *dialog; | 703 | GtkWidget *dialog; |
@@ -344,6 +706,7 @@ void trace_adv_filter_dialog(struct tracecmd_input *handle, | |||
344 | GtkWidget *entry; | 706 | GtkWidget *entry; |
345 | GtkWidget *scrollwin; | 707 | GtkWidget *scrollwin; |
346 | GtkWidget *view; | 708 | GtkWidget *view; |
709 | GtkWidget *event_box; | ||
347 | 710 | ||
348 | helper = g_malloc(sizeof(*helper)); | 711 | helper = g_malloc(sizeof(*helper)); |
349 | g_assert(helper); | 712 | g_assert(helper); |
@@ -389,11 +752,19 @@ void trace_adv_filter_dialog(struct tracecmd_input *handle, | |||
389 | "&& prev_pid != 0)\n" | 752 | "&& prev_pid != 0)\n" |
390 | " irq.* : irq != 38\n" | 753 | " irq.* : irq != 38\n" |
391 | " .* : common_pid == 1234"); | 754 | " .* : common_pid == 1234"); |
392 | gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), label, TRUE, TRUE, 0); | 755 | gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), label, TRUE, FALSE, 0); |
393 | gtk_widget_show(label); | 756 | gtk_widget_show(label); |
394 | 757 | ||
758 | pevent = tracecmd_get_pevent(handle); | ||
759 | |||
760 | event_helper->combo_info.pevent = pevent; | ||
761 | |||
762 | event_box = event_info_box(&event_helper->combo_info); | ||
763 | gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), event_box, FALSE, FALSE, 0); | ||
764 | gtk_widget_show(event_box); | ||
765 | |||
395 | hbox = gtk_hbox_new(FALSE, 0); | 766 | hbox = gtk_hbox_new(FALSE, 0); |
396 | gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), hbox, TRUE, TRUE, 0); | 767 | gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), hbox, TRUE, FALSE, 0); |
397 | gtk_widget_show(hbox); | 768 | gtk_widget_show(hbox); |
398 | 769 | ||
399 | label = gtk_label_new("Filter:"); | 770 | label = gtk_label_new("Filter:"); |