aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSteven Rostedt <srostedt@redhat.com>2010-01-07 11:10:32 -0500
committerSteven Rostedt <rostedt@goodmis.org>2010-01-07 12:47:28 -0500
commitcd6621ae612c78d9423123cb918cd1d6a149fcf4 (patch)
treeee1d355dbaeba407a4a55a244d102833b7e926ce
parent21c3a04ebe61c2ec0cb01f89a46d19d99309a8ed (diff)
trace-view: Make event and CPU dialogs generic
Since the event and CPU dialogs may also be used by the trace-graph make it generic and remove the dependency of the trace-view-store. This also changes them to accept a callback function for when a response is made. Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
-rw-r--r--kernel-shark.c33
-rw-r--r--trace-filter.c330
-rw-r--r--trace-hash.c20
-rw-r--r--trace-hash.h5
-rw-r--r--trace-view-main.c35
-rw-r--r--trace-view-store.c20
-rw-r--r--trace-view.c90
-rw-r--r--trace-view.h64
8 files changed, 454 insertions, 143 deletions
diff --git a/kernel-shark.c b/kernel-shark.c
index a55fc8a..4b8966f 100644
--- a/kernel-shark.c
+++ b/kernel-shark.c
@@ -118,8 +118,26 @@ static void
118events_clicked (gpointer data) 118events_clicked (gpointer data)
119{ 119{
120 struct shark_info *info = data; 120 struct shark_info *info = data;
121 GtkTreeView *trace_tree = GTK_TREE_VIEW(info->treeview);
122 GtkTreeModel *model;
123 TraceViewStore *store;
124 gboolean all_events;
125 gchar **systems;
126 gint *events;
127
128 model = gtk_tree_view_get_model(trace_tree);
129 if (!model)
130 return;
121 131
122 trace_filter_event_dialog(info->treeview); 132 store = TRACE_VIEW_STORE(model);
133
134 all_events = trace_view_store_get_all_events_enabled(store);
135 systems = trace_view_store_get_systems_enabled(store);
136 events = trace_view_store_get_events_enabled(store);
137
138 trace_filter_event_dialog(store->handle, all_events,
139 systems, events,
140 trace_view_event_filter_callback, trace_tree);
123} 141}
124 142
125/* Callback for the clicked signal of the CPUs filter button */ 143/* Callback for the clicked signal of the CPUs filter button */
@@ -127,8 +145,19 @@ static void
127cpus_clicked (gpointer data) 145cpus_clicked (gpointer data)
128{ 146{
129 struct shark_info *info = data; 147 struct shark_info *info = data;
148 GtkTreeView *trace_tree = GTK_TREE_VIEW(info->treeview);
149 TraceViewStore *store;
150 gboolean all_cpus;
151 guint64 *cpu_mask;
152
153 store = TRACE_VIEW_STORE(gtk_tree_view_get_model(trace_tree));
154
155 all_cpus = trace_view_store_get_all_cpus(store);
156 cpu_mask = trace_view_store_get_cpu_mask(store);
130 157
131 trace_filter_cpu_dialog(info->treeview); 158 trace_filter_cpu_dialog(all_cpus, cpu_mask,
159 trace_view_store_get_cpus(store),
160 trace_view_cpu_filter_callback, trace_tree);
132} 161}
133 162
134static void row_double_clicked(GtkTreeView *treeview, 163static void row_double_clicked(GtkTreeView *treeview,
diff --git a/trace-filter.c b/trace-filter.c
index fd456aa..894448e 100644
--- a/trace-filter.c
+++ b/trace-filter.c
@@ -5,31 +5,15 @@
5#include "trace-cmd.h" 5#include "trace-cmd.h"
6#include "trace-local.h" 6#include "trace-local.h"
7#include "trace-view-store.h" 7#include "trace-view-store.h"
8#include "trace-view.h"
9
10#include "cpu.h"
8 11
9#define DIALOG_WIDTH 400 12#define DIALOG_WIDTH 400
10#define DIALOG_HEIGHT 600 13#define DIALOG_HEIGHT 600
11 14
12static void cpu_mask_set(guint64 *mask, gint cpu)
13{
14 mask += (cpu >> 6);
15 *mask |= 1ULL << (cpu & ((1ULL << 6) - 1));
16}
17
18static void cpu_mask_clear(guint64 *mask, gint cpu)
19{
20 mask += (cpu >> 6);
21 *mask &= ~(1ULL << (cpu & ((1ULL << 6) - 1)));
22}
23
24static gboolean cpu_mask_isset(guint64 *mask, gint cpu)
25{
26 mask += (cpu >> 6);
27 return *mask & (1ULL << (cpu & ((1ULL << 6) - 1)));
28}
29
30struct dialog_helper { 15struct dialog_helper {
31 GtkWidget *dialog; 16 GtkWidget *dialog;
32 GtkWidget *trace_tree;
33 gpointer data; 17 gpointer data;
34}; 18};
35 19
@@ -41,28 +25,56 @@ enum {
41 NUM_EVENT_COLS, 25 NUM_EVENT_COLS,
42}; 26};
43 27
28struct event_filter_helper {
29 trace_filter_event_cb_func func;
30 GtkTreeView *view;
31 gpointer data;
32};
33
34gboolean system_is_enabled(gchar **systems, gint systems_size, const gchar *system)
35{
36 const gchar **sys = &system;
37
38 if (!systems)
39 return FALSE;
40
41 sys = bsearch(sys, systems, systems_size, sizeof(system), str_cmp);
42
43 return sys != NULL;
44}
45
46gboolean event_is_enabled(gint *events, gint events_size, gint event)
47{
48 gint *ret;
49
50 if (!events)
51 return FALSE;
52
53 ret = bsearch(&event, events, events_size, sizeof(gint), id_cmp);
54
55 return ret != NULL;
56}
57
44static GtkTreeModel * 58static GtkTreeModel *
45create_tree_event_model(GtkWidget *tree_view) 59create_tree_event_model(struct tracecmd_input *handle,
60 gboolean all_events, gchar **systems_set,
61 gint *event_ids_set)
46{ 62{
47 GtkTreeModel *model;
48 TraceViewStore *trace_view;
49 GtkTreeStore *treestore; 63 GtkTreeStore *treestore;
50 GtkTreeIter iter_all, iter_sys, iter_events; 64 GtkTreeIter iter_all, iter_sys, iter_events;
51 struct pevent *pevent; 65 struct pevent *pevent;
52 struct event_format **events; 66 struct event_format **events;
53 struct event_format *event; 67 struct event_format *event;
54 char *last_system = NULL; 68 char *last_system = NULL;
55 gboolean all_events;
56 gboolean sysactive; 69 gboolean sysactive;
57 gboolean active; 70 gboolean active;
71 gchar **systems = NULL;
72 gint *event_ids = NULL;
73 gint systems_size;
74 gint event_ids_size;
58 gint i; 75 gint i;
59 76
60 model = gtk_tree_view_get_model(GTK_TREE_VIEW(tree_view)); 77 pevent = tracecmd_get_pevent(handle);
61 trace_view = TRACE_VIEW_STORE(model);
62
63 all_events = trace_view_store_get_all_events_enabled(trace_view);
64
65 pevent = tracecmd_get_pevent(trace_view->handle);
66 78
67 treestore = gtk_tree_store_new(NUM_EVENT_COLS, G_TYPE_STRING, 79 treestore = gtk_tree_store_new(NUM_EVENT_COLS, G_TYPE_STRING,
68 G_TYPE_BOOLEAN, G_TYPE_BOOLEAN, 80 G_TYPE_BOOLEAN, G_TYPE_BOOLEAN,
@@ -79,12 +91,28 @@ create_tree_event_model(GtkWidget *tree_view)
79 if (!events) 91 if (!events)
80 return GTK_TREE_MODEL(treestore); 92 return GTK_TREE_MODEL(treestore);
81 93
94 if (systems_set) {
95 for (systems_size = 0; systems_set[systems_size]; systems_size++)
96 ;
97 systems = g_new(typeof(*systems), systems_size + 1);
98 memcpy(systems, systems_set, sizeof(*systems) * (systems_size + 1));
99 qsort(systems, systems_size, sizeof(gchar *), str_cmp);
100 }
101
102 if (event_ids_set) {
103 for (event_ids_size = 0; event_ids_set[event_ids_size] != -1; event_ids_size++)
104 ;
105 event_ids = g_new(typeof(*event_ids), event_ids_size + 1);
106 memcpy(event_ids, event_ids_set, sizeof(*event_ids) * (event_ids_size + 1));
107 qsort(event_ids, event_ids_size, sizeof(gint), id_cmp);
108 }
109
82 for (i = 0; events[i]; i++) { 110 for (i = 0; events[i]; i++) {
83 event = events[i]; 111 event = events[i];
84 if (!last_system || strcmp(last_system, event->system) != 0) { 112 if (!last_system || strcmp(last_system, event->system) != 0) {
85 gtk_tree_store_append(treestore, &iter_sys, &iter_all); 113 gtk_tree_store_append(treestore, &iter_sys, &iter_all);
86 sysactive = all_events || 114 sysactive = all_events ||
87 trace_view_store_system_enabled(trace_view, event->system); 115 system_is_enabled(systems, systems_size, event->system);
88 gtk_tree_store_set(treestore, &iter_sys, 116 gtk_tree_store_set(treestore, &iter_sys,
89 COL_EVENT, event->system, 117 COL_EVENT, event->system,
90 COL_ACTIVE, sysactive, 118 COL_ACTIVE, sysactive,
@@ -93,7 +121,7 @@ create_tree_event_model(GtkWidget *tree_view)
93 } 121 }
94 122
95 active = all_events || sysactive || 123 active = all_events || sysactive ||
96 trace_view_store_event_enabled(trace_view, event->id); 124 event_is_enabled(event_ids, event_ids_size, event->id);
97 gtk_tree_store_append(treestore, &iter_events, &iter_sys); 125 gtk_tree_store_append(treestore, &iter_events, &iter_sys);
98 gtk_tree_store_set(treestore, &iter_events, 126 gtk_tree_store_set(treestore, &iter_events,
99 COL_EVENT, event->name, 127 COL_EVENT, event->name,
@@ -103,6 +131,9 @@ create_tree_event_model(GtkWidget *tree_view)
103 131
104 } 132 }
105 133
134 g_free(systems);
135 g_free(event_ids);
136
106 return GTK_TREE_MODEL(treestore); 137 return GTK_TREE_MODEL(treestore);
107} 138}
108 139
@@ -203,9 +234,13 @@ static void event_cursor_changed(GtkTreeView *treeview, gpointer data)
203 /* set this system */ 234 /* set this system */
204 update_active_events(model, &iter, active); 235 update_active_events(model, &iter, active);
205 236
206 if (!active) 237 if (!active) {
207 /* disable the all events toggle */ 238 /* disable the all events toggle */
208 gtk_tree_model_iter_parent(model, &parent, &iter); 239 gtk_tree_model_iter_parent(model, &parent, &iter);
240 gtk_tree_store_set(GTK_TREE_STORE(model), &parent,
241 COL_ACTIVE, FALSE,
242 -1);
243 }
209 244
210 } else { 245 } else {
211 if (!active) { 246 if (!active) {
@@ -225,7 +260,10 @@ static void event_cursor_changed(GtkTreeView *treeview, gpointer data)
225 gtk_tree_path_free(path); 260 gtk_tree_path_free(path);
226} 261}
227 262
228static GtkWidget *create_event_list_view(GtkWidget *tree_view) 263static GtkWidget *
264create_event_list_view(struct tracecmd_input *handle,
265 gboolean all_events, gchar **systems,
266 gint *events)
229{ 267{
230 GtkTreeViewColumn *col; 268 GtkTreeViewColumn *col;
231 GtkCellRenderer *renderer; 269 GtkCellRenderer *renderer;
@@ -253,7 +291,7 @@ static GtkWidget *create_event_list_view(GtkWidget *tree_view)
253 291
254 gtk_tree_view_column_add_attribute(col, renderer, "text", COL_EVENT); 292 gtk_tree_view_column_add_attribute(col, renderer, "text", COL_EVENT);
255 293
256 model = create_tree_event_model(tree_view); 294 model = create_tree_event_model(handle, all_events, systems, events);
257 295
258 gtk_tree_view_set_model(GTK_TREE_VIEW(view), model); 296 gtk_tree_view_set_model(GTK_TREE_VIEW(view), model);
259 297
@@ -271,16 +309,46 @@ static GtkWidget *create_event_list_view(GtkWidget *tree_view)
271 return view; 309 return view;
272} 310}
273 311
274static void update_events(TraceViewStore *store, 312static gchar **add_system(gchar **systems, gint size, gchar *system)
275 GtkTreeModel *model, 313{
276 GtkTreeIter *parent) 314 if (!systems) {
315 systems = g_new0(gchar *, 2);
316 size = 0;
317 } else {
318 systems = g_realloc(systems,
319 sizeof(*systems) * (size + 2));
320 }
321 systems[size] = g_strdup(system);
322 systems[size+1] = NULL;
323
324 return systems;
325}
326
327static gint *add_event(gint *events, gint size, gint event)
328{
329 if (!events) {
330 events = g_new0(gint, 2);
331 size = 0;
332 } else {
333 events = g_realloc(events,
334 sizeof(*events) * (size + 2));
335 }
336 events[size] = event;
337 events[size+1] = -1;
338
339 return events;
340}
341
342static gint update_events(GtkTreeModel *model,
343 GtkTreeIter *parent,
344 gint **events, gint size)
277{ 345{
278 GtkTreeIter event; 346 GtkTreeIter event;
279 gboolean active; 347 gboolean active;
280 gint id; 348 gint id;
281 349
282 if (!gtk_tree_model_iter_children(model, &event, parent)) 350 if (!gtk_tree_model_iter_children(model, &event, parent))
283 return; 351 return size;
284 352
285 for (;;) { 353 for (;;) {
286 354
@@ -290,25 +358,28 @@ static void update_events(TraceViewStore *store,
290 -1); 358 -1);
291 359
292 if (active) 360 if (active)
293 trace_view_store_set_event_enabled(store, id); 361 *events = add_event(*events, size++, id);
294 362
295 if (!gtk_tree_model_iter_next(model, &event)) 363 if (!gtk_tree_model_iter_next(model, &event))
296 break; 364 break;
297 } 365 }
366
367 return size;
298} 368}
299 369
300static void update_system_events(TraceViewStore *store, 370static gint update_system_events(GtkTreeModel *model,
301 GtkTreeModel *model, 371 GtkTreeIter *parent,
302 GtkTreeIter *parent) 372 gchar ***systems,
373 gint size,
374 gint **events,
375 gint *events_size)
303{ 376{
304 GtkTreeIter sys; 377 GtkTreeIter sys;
305 gboolean active; 378 gboolean active;
306 gchar *system; 379 gchar *system;
307 380
308 if (!gtk_tree_model_iter_children(model, &sys, parent)) 381 if (!gtk_tree_model_iter_children(model, &sys, parent))
309 return; 382 return size;
310
311 trace_view_store_clear_all_events_enabled(store);
312 383
313 for (;;) { 384 for (;;) {
314 385
@@ -318,29 +389,30 @@ static void update_system_events(TraceViewStore *store,
318 -1); 389 -1);
319 390
320 if (active) 391 if (active)
321 trace_view_store_set_system_enabled(store, system); 392 *systems = add_system(*systems, size++, system);
322 else 393 else
323 update_events(store, model, &sys); 394 *events_size = update_events(model, &sys, events, *events_size);
324 395
325 g_free(system); 396 g_free(system);
326 397
327 if (!gtk_tree_model_iter_next(model, &sys)) 398 if (!gtk_tree_model_iter_next(model, &sys))
328 break; 399 break;
329 } 400 }
401
402 return size;
330} 403}
331 404
332static void accept_events(GtkWidget *trace_tree_view, GtkTreeView *view) 405static void accept_events(struct event_filter_helper *event_helper)
333{ 406{
407 GtkTreeView *view = event_helper->view;
334 GtkTreeModel *model; 408 GtkTreeModel *model;
335 TraceViewStore *store;
336 GtkTreeIter iter; 409 GtkTreeIter iter;
337 gboolean active; 410 gboolean active;
338 411 gchar **systems = NULL;
339 model = gtk_tree_view_get_model(GTK_TREE_VIEW(trace_tree_view)); 412 gint *events = NULL;
340 if (!model) 413 gint events_size = 0;
341 return; 414 gint systems_size = 0;
342 415 gint i;
343 store = TRACE_VIEW_STORE(model);
344 416
345 model = gtk_tree_view_get_model(view); 417 model = gtk_tree_view_get_model(view);
346 if (!model) 418 if (!model)
@@ -353,21 +425,21 @@ static void accept_events(GtkWidget *trace_tree_view, GtkTreeView *view)
353 COL_ACTIVE, &active, 425 COL_ACTIVE, &active,
354 -1); 426 -1);
355 427
356 if (active) { 428 if (!active)
357 if (trace_view_store_get_all_events_enabled(store)) 429 update_system_events(model, &iter,
358 return; 430 &systems, systems_size,
431 &events, &events_size);
359 432
360 trace_view_store_set_all_events_enabled(store); 433 event_helper->func(TRUE, active, systems, events,
361 } else 434 event_helper->data);
362 update_system_events(store, model, &iter);
363 435
364 /* Force an update */ 436 if (systems) {
365 g_object_ref(store); 437 for (i = 0; systems[i]; i++)
366 gtk_tree_view_set_model(GTK_TREE_VIEW(trace_tree_view), NULL); 438 g_free(systems[i]);
367 trace_view_store_update_filter(store);
368 gtk_tree_view_set_model(GTK_TREE_VIEW(trace_tree_view), GTK_TREE_MODEL(store));
369 g_object_unref(store);
370 439
440 g_free(systems);
441 }
442 g_free(events);
371} 443}
372 444
373/* Callback for the clicked signal of the Events filter button */ 445/* Callback for the clicked signal of the Events filter button */
@@ -375,15 +447,17 @@ static void
375event_dialog_response (gpointer data, gint response_id) 447event_dialog_response (gpointer data, gint response_id)
376{ 448{
377 struct dialog_helper *helper = data; 449 struct dialog_helper *helper = data;
378 GtkTreeView *view = helper->data; 450 struct event_filter_helper *event_helper = helper->data;
379 451
380 switch (response_id) { 452 switch (response_id) {
381 case GTK_RESPONSE_ACCEPT: 453 case GTK_RESPONSE_ACCEPT:
382 printf("accept!\n"); 454 printf("accept!\n");
383 accept_events(helper->trace_tree, view); 455 accept_events(event_helper);
384 break; 456 break;
385 case GTK_RESPONSE_REJECT: 457 case GTK_RESPONSE_REJECT:
386 printf("reject!\n"); 458 printf("reject!\n");
459 event_helper->func(FALSE, FALSE, NULL, NULL,
460 event_helper->data);
387 break; 461 break;
388 default: 462 default:
389 break; 463 break;
@@ -391,13 +465,30 @@ event_dialog_response (gpointer data, gint response_id)
391 465
392 gtk_widget_destroy(GTK_WIDGET(helper->dialog)); 466 gtk_widget_destroy(GTK_WIDGET(helper->dialog));
393 467
468 g_free(event_helper);
394 g_free(helper); 469 g_free(helper);
395} 470}
396 471
397void trace_filter_event_dialog(void *trace_tree) 472/**
473 * trace_filter_event_dialog - make dialog with event listing
474 * @handle: the handle to the tracecmd data file
475 * @all_events: if TRUE then select all events.
476 * @systems: NULL or a string array of systems terminated with NULL
477 * @events: NULL or a int array of event ids terminated with -1
478 * @func: The function to call when accept or cancel is pressed
479 * @data: data to pass to the function @func
480 *
481 * If @all_events is set, then @systems and @events are ignored.
482 */
483void trace_filter_event_dialog(struct tracecmd_input *handle,
484 gboolean all_events,
485 gchar **systems,
486 gint *events,
487 trace_filter_event_cb_func func,
488 gpointer data)
398{ 489{
399 GtkWidget *tree_view = GTK_WIDGET(trace_tree);
400 struct dialog_helper *helper; 490 struct dialog_helper *helper;
491 struct event_filter_helper *event_helper;
401 GtkWidget *dialog; 492 GtkWidget *dialog;
402 GtkWidget *scrollwin; 493 GtkWidget *scrollwin;
403 GtkWidget *view; 494 GtkWidget *view;
@@ -415,8 +506,14 @@ void trace_filter_event_dialog(void *trace_tree)
415 GTK_RESPONSE_REJECT, 506 GTK_RESPONSE_REJECT,
416 NULL); 507 NULL);
417 508
509 event_helper = g_new0(typeof(*event_helper), 1);
510 g_assert(event_helper);
511
418 helper->dialog = dialog; 512 helper->dialog = dialog;
419 helper->trace_tree = tree_view; 513 helper->data = event_helper;
514
515 event_helper->func = func;
516 event_helper->data = data;
420 517
421 /* We can attach the Quit menu item to our exit function */ 518 /* We can attach the Quit menu item to our exit function */
422 g_signal_connect_swapped (dialog, "response", 519 g_signal_connect_swapped (dialog, "response",
@@ -427,8 +524,8 @@ void trace_filter_event_dialog(void *trace_tree)
427 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrollwin), 524 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrollwin),
428 GTK_POLICY_AUTOMATIC, 525 GTK_POLICY_AUTOMATIC,
429 GTK_POLICY_AUTOMATIC); 526 GTK_POLICY_AUTOMATIC);
430 view = create_event_list_view(tree_view); 527 view = create_event_list_view(handle, all_events, systems, events);
431 helper->data = view; 528 event_helper->view = GTK_TREE_VIEW(view);
432 529
433 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), scrollwin, TRUE, TRUE, 0); 530 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), scrollwin, TRUE, TRUE, 0);
434 gtk_container_add(GTK_CONTAINER(scrollwin), view); 531 gtk_container_add(GTK_CONTAINER(scrollwin), view);
@@ -440,10 +537,12 @@ void trace_filter_event_dialog(void *trace_tree)
440} 537}
441 538
442struct cpu_filter_helper { 539struct cpu_filter_helper {
443 gboolean allcpus; 540 gboolean allcpus;
444 guint64 *cpu_mask; 541 guint64 *cpu_mask;
445 GtkWidget **buttons; 542 GtkWidget **buttons;
446 int cpus; 543 int cpus;
544 trace_filter_cpu_cb_func func;
545 gpointer data;
447}; 546};
448 547
449static void destroy_cpu_helper(struct cpu_filter_helper *cpu_helper) 548static void destroy_cpu_helper(struct cpu_filter_helper *cpu_helper)
@@ -459,40 +558,28 @@ cpu_dialog_response (gpointer data, gint response_id)
459{ 558{
460 struct dialog_helper *helper = data; 559 struct dialog_helper *helper = data;
461 struct cpu_filter_helper *cpu_helper = helper->data; 560 struct cpu_filter_helper *cpu_helper = helper->data;
462 GtkTreeView *view = GTK_TREE_VIEW(helper->trace_tree); 561 guint64 *cpu_mask = NULL;
463 TraceViewStore *store;
464 gint cpu;
465
466 store = TRACE_VIEW_STORE(gtk_tree_view_get_model(view));
467 562
468 switch (response_id) { 563 switch (response_id) {
469 case GTK_RESPONSE_ACCEPT: 564 case GTK_RESPONSE_ACCEPT:
470 g_object_ref(store);
471 gtk_tree_view_set_model(view, NULL);
472 565
473 if (cpu_helper->allcpus) { 566 if (!cpu_helper->allcpus) {
474 trace_view_store_set_all_cpus(store); 567 cpu_mask = cpu_helper->cpu_mask;
475 gtk_tree_view_set_model(view, GTK_TREE_MODEL(store)); 568 cpu_helper->cpu_mask = NULL;
476 g_object_unref(store);
477 break;
478 } 569 }
479 570
480 for (cpu = 0; cpu < cpu_helper->cpus; cpu++) { 571 cpu_helper->func(TRUE, cpu_helper->allcpus, cpu_mask, cpu_helper->data);
481 if (cpu_mask_isset(cpu_helper->cpu_mask, cpu))
482 trace_view_store_set_cpu(store, cpu);
483 else
484 trace_view_store_clear_cpu(store, cpu);
485 }
486 gtk_tree_view_set_model(view, GTK_TREE_MODEL(store));
487 g_object_unref(store);
488 break; 572 break;
489 573
490 case GTK_RESPONSE_REJECT: 574 case GTK_RESPONSE_REJECT:
575 cpu_helper->func(FALSE, FALSE, NULL, cpu_helper->data);
491 break; 576 break;
492 default: 577 default:
493 break; 578 break;
494 }; 579 };
495 580
581 g_free(cpu_mask);
582
496 gtk_widget_destroy(GTK_WIDGET(helper->dialog)); 583 gtk_widget_destroy(GTK_WIDGET(helper->dialog));
497 584
498 destroy_cpu_helper(helper->data); 585 destroy_cpu_helper(helper->data);
@@ -525,11 +612,11 @@ void cpu_toggle(gpointer data, GtkWidget *widget)
525 /* Get the CPU # from the label. Pass "CPU " */ 612 /* Get the CPU # from the label. Pass "CPU " */
526 cpu = atoi(label + 4); 613 cpu = atoi(label + 4);
527 if (active) { 614 if (active) {
528 cpu_mask_set(cpu_helper->cpu_mask, cpu); 615 cpu_set(cpu_helper->cpu_mask, cpu);
529 return; 616 return;
530 } 617 }
531 618
532 cpu_mask_clear(cpu_helper->cpu_mask, cpu); 619 cpu_clear(cpu_helper->cpu_mask, cpu);
533 620
534 if (!cpu_helper->allcpus) 621 if (!cpu_helper->allcpus)
535 return; 622 return;
@@ -538,10 +625,18 @@ void cpu_toggle(gpointer data, GtkWidget *widget)
538 FALSE); 625 FALSE);
539} 626}
540 627
541void trace_filter_cpu_dialog(void *trace_tree) 628/**
629 * trace_filter_cpu_dialog - make dialog with cpu listing
630 * @all_cpus: if TRUE then select all cpus.
631 * @cpus_selected: NULL or a CPU mask with the CPUs to be select set.
632 * @func: The function to call when accept or cancel is pressed
633 * @data: data to pass to the function @func
634 *
635 * If @all_cpus is set, then @cpus_selected is ignored.
636 */
637void trace_filter_cpu_dialog(gboolean all_cpus, guint64 *cpus_selected, gint cpus,
638 trace_filter_cpu_cb_func func, gpointer data)
542{ 639{
543 GtkWidget *tree_view = GTK_WIDGET(trace_tree);
544 TraceViewStore *store;
545 struct dialog_helper *helper; 640 struct dialog_helper *helper;
546 struct cpu_filter_helper *cpu_helper; 641 struct cpu_filter_helper *cpu_helper;
547 GtkWidget *dialog; 642 GtkWidget *dialog;
@@ -554,17 +649,12 @@ void trace_filter_cpu_dialog(void *trace_tree)
554 gchar counter[100]; 649 gchar counter[100];
555 gint width, height; 650 gint width, height;
556 gint allset; 651 gint allset;
557 gint cpus;
558 gint cpu; 652 gint cpu;
559 653
560 store = TRACE_VIEW_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(tree_view)));
561
562 cpus = trace_view_store_get_cpus(store);
563
564 helper = g_malloc(sizeof(*helper)); 654 helper = g_malloc(sizeof(*helper));
565 g_assert(helper != NULL); 655 g_assert(helper != NULL);
566 656
567 cpu_helper = g_new0(typeof(*cpu_helper), sizeof(*cpu_helper)); 657 cpu_helper = g_new0(typeof(*cpu_helper), 1);
568 g_assert(cpu_helper != NULL); 658 g_assert(cpu_helper != NULL);
569 659
570 helper->data = cpu_helper; 660 helper->data = cpu_helper;
@@ -581,12 +671,14 @@ void trace_filter_cpu_dialog(void *trace_tree)
581 NULL); 671 NULL);
582 672
583 helper->dialog = dialog; 673 helper->dialog = dialog;
584 helper->trace_tree = tree_view;
585 674
586 cpu_helper->cpus = cpus; 675 cpu_helper->cpus = cpus;
587 cpu_helper->buttons = g_new0(GtkWidget *, cpus + 1); 676 cpu_helper->buttons = g_new0(GtkWidget *, cpus + 1);
588 g_assert(cpu_helper->buttons); 677 g_assert(cpu_helper->buttons);
589 678
679 cpu_helper->func = func;
680 cpu_helper->data = data;
681
590 g_signal_connect_swapped (dialog, "response", 682 g_signal_connect_swapped (dialog, "response",
591 G_CALLBACK (cpu_dialog_response), 683 G_CALLBACK (cpu_dialog_response),
592 (gpointer) helper); 684 (gpointer) helper);
@@ -618,7 +710,16 @@ void trace_filter_cpu_dialog(void *trace_tree)
618 /* The last button will be the all CPUs button */ 710 /* The last button will be the all CPUs button */
619 cpu_helper->buttons[cpus] = check; 711 cpu_helper->buttons[cpus] = check;
620 712
621 allset = trace_view_store_get_all_cpus(store); 713 allset = cpus_selected ? 0 : 1;
714 if (!allset) {
715 /* check if the list is all set */
716 for (cpu = 0; cpu < cpus; cpu++)
717 if (!cpu_isset(cpus_selected, cpu))
718 break;
719 if (cpu == cpus)
720 allset = 1;
721 }
722
622 if (allset) 723 if (allset)
623 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check), TRUE); 724 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check), TRUE);
624 725
@@ -637,10 +738,11 @@ void trace_filter_cpu_dialog(void *trace_tree)
637 check = gtk_check_button_new_with_label(counter); 738 check = gtk_check_button_new_with_label(counter);
638 cpu_helper->buttons[cpu] = check; 739 cpu_helper->buttons[cpu] = check;
639 gtk_box_pack_start(GTK_BOX(vbox), check, TRUE, FALSE, 0); 740 gtk_box_pack_start(GTK_BOX(vbox), check, TRUE, FALSE, 0);
640 if (allset || trace_view_store_cpu_isset(store, cpu)) { 741 if (cpus_selected && cpu_isset(cpus_selected, cpu)) {
641 cpu_mask_set(cpu_helper->cpu_mask, cpu); 742 cpu_set(cpu_helper->cpu_mask, cpu);
642 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check), TRUE); 743 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check), TRUE);
643 } 744 } else
745 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check), FALSE);
644 746
645 g_signal_connect_swapped (check, "toggled", 747 g_signal_connect_swapped (check, "toggled",
646 G_CALLBACK (cpu_toggle), 748 G_CALLBACK (cpu_toggle),
diff --git a/trace-hash.c b/trace-hash.c
index 8435e6c..a41b2ce 100644
--- a/trace-hash.c
+++ b/trace-hash.c
@@ -160,3 +160,23 @@ struct filter_task *filter_task_hash_copy(struct filter_task *hash)
160 return new_hash; 160 return new_hash;
161} 161}
162 162
163
164int str_cmp(const void *a, const void *b)
165{
166 char * const * sa = a;
167 char * const * sb = b;
168
169 return strcmp(*sa, *sb);
170}
171
172int id_cmp(const void *a, const void *b)
173{
174 const gint *ia = a;
175 const gint *ib = b;
176
177 if (*ia > *ib)
178 return 1;
179 if (*ia < *ib)
180 return -1;
181 return 0;
182}
diff --git a/trace-hash.h b/trace-hash.h
index 9948138..04543f7 100644
--- a/trace-hash.h
+++ b/trace-hash.h
@@ -29,4 +29,9 @@ static inline gint filter_task_count(struct filter_task *hash)
29 return hash->count; 29 return hash->count;
30} 30}
31 31
32/* put here because there's no other place */
33
34int str_cmp(const void *a, const void *b);
35int id_cmp(const void *a, const void *b);
36
32#endif /* _TRACE_HASH_H */ 37#endif /* _TRACE_HASH_H */
diff --git a/trace-view-main.c b/trace-view-main.c
index 2f4042e..122cda8 100644
--- a/trace-view-main.c
+++ b/trace-view-main.c
@@ -47,18 +47,45 @@ delete_event (GtkWidget *widget, GdkEvent *event, gpointer data)
47static void 47static void
48events_clicked (gpointer data) 48events_clicked (gpointer data)
49{ 49{
50 GtkWidget *trace_tree = data; 50 GtkTreeView *trace_tree = data;
51 GtkTreeModel *model;
52 TraceViewStore *store;
53 gboolean all_events;
54 gchar **systems;
55 gint *events;
56
57 model = gtk_tree_view_get_model(trace_tree);
58 if (!model)
59 return;
60
61 store = TRACE_VIEW_STORE(model);
62
63 all_events = trace_view_store_get_all_events_enabled(store);
64 systems = trace_view_store_get_systems_enabled(store);
65 events = trace_view_store_get_events_enabled(store);
51 66
52 trace_filter_event_dialog(trace_tree); 67 trace_filter_event_dialog(store->handle, all_events,
68 systems, events,
69 trace_view_event_filter_callback, trace_tree);
53} 70}
54 71
55/* Callback for the clicked signal of the CPUs filter button */ 72/* Callback for the clicked signal of the CPUs filter button */
56static void 73static void
57cpus_clicked (gpointer data) 74cpus_clicked (gpointer data)
58{ 75{
59 GtkWidget *trace_tree = data; 76 GtkTreeView *trace_tree = data;
77 TraceViewStore *store;
78 gboolean all_cpus;
79 guint64 *cpu_mask;
80
81 store = TRACE_VIEW_STORE(gtk_tree_view_get_model(trace_tree));
82
83 all_cpus = trace_view_store_get_all_cpus(store);
84 cpu_mask = trace_view_store_get_cpu_mask(store);
60 85
61 trace_filter_cpu_dialog(trace_tree); 86 trace_filter_cpu_dialog(all_cpus, cpu_mask,
87 trace_view_store_get_cpus(store),
88 trace_view_cpu_filter_callback, trace_tree);
62} 89}
63 90
64#if 0 91#if 0
diff --git a/trace-view-store.c b/trace-view-store.c
index 58280dd..cc6b865 100644
--- a/trace-view-store.c
+++ b/trace-view-store.c
@@ -494,26 +494,6 @@ trace_view_store_get_value (GtkTreeModel *tree_model,
494 } 494 }
495} 495}
496 496
497int str_cmp(const void *a, const void *b)
498{
499 char * const * sa = a;
500 char * const * sb = b;
501
502 return strcmp(*sa, *sb);
503}
504
505int id_cmp(const void *a, const void *b)
506{
507 const gint *ia = a;
508 const gint *ib = b;
509
510 if (*ia > *ib)
511 return 1;
512 if (*ia < *ib)
513 return -1;
514 return 0;
515}
516
517gboolean trace_view_store_system_enabled(TraceViewStore *store, const gchar *system) 497gboolean trace_view_store_system_enabled(TraceViewStore *store, const gchar *system)
518{ 498{
519 const gchar **sys = &system; 499 const gchar **sys = &system;
diff --git a/trace-view.c b/trace-view.c
index 6ed71d8..c73f95a 100644
--- a/trace-view.c
+++ b/trace-view.c
@@ -28,6 +28,7 @@
28#include "trace-local.h" 28#include "trace-local.h"
29#include "trace-view.h" 29#include "trace-view.h"
30#include "trace-compat.h" 30#include "trace-compat.h"
31#include "cpu.h"
31 32
32enum { 33enum {
33 COL_INDEX, 34 COL_INDEX,
@@ -351,3 +352,92 @@ void trace_view_select(GtkWidget *treeview, guint64 time)
351 gtk_tree_view_scroll_to_cell(tree, path, NULL, TRUE, 0.5, 0.0); 352 gtk_tree_view_scroll_to_cell(tree, path, NULL, TRUE, 0.5, 0.0);
352 gtk_tree_path_free(path); 353 gtk_tree_path_free(path);
353} 354}
355
356void trace_view_event_filter_callback(gboolean accept,
357 gboolean all_events,
358 gchar **systems,
359 gint *events,
360 gpointer data)
361{
362 GtkTreeView *trace_tree = data;
363 GtkTreeModel *model;
364 TraceViewStore *store;
365 gint i;
366
367 if (!accept)
368 return;
369
370 model = gtk_tree_view_get_model(trace_tree);
371 if (!model)
372 return;
373
374 store = TRACE_VIEW_STORE(model);
375
376 if (all_events) {
377 if (trace_view_store_get_all_events_enabled(store))
378 return;
379
380 trace_view_store_set_all_events_enabled(store);
381 } else {
382 trace_view_store_clear_all_events_enabled(store);
383
384 if (systems) {
385 for (i = 0; systems[i]; i++)
386 trace_view_store_set_system_enabled(store, systems[i]);
387 }
388
389 if (events) {
390 for (i = 0; events[i] >= 0; i++)
391 trace_view_store_set_event_enabled(store, events[i]);
392 }
393 }
394
395 /* Force an update */
396 g_object_ref(store);
397 gtk_tree_view_set_model(trace_tree, NULL);
398 trace_view_store_update_filter(store);
399 gtk_tree_view_set_model(trace_tree, GTK_TREE_MODEL(store));
400 g_object_unref(store);
401}
402
403void trace_view_cpu_filter_callback(gboolean accept,
404 gboolean all_cpus,
405 guint64 *selected_cpu_mask,
406 gpointer data)
407{
408 GtkTreeView *trace_tree = data;
409 GtkTreeModel *model;
410 TraceViewStore *store;
411 gint cpus;
412 gint cpu;
413
414 model = gtk_tree_view_get_model(trace_tree);
415 if (!model)
416 return;
417
418 store = TRACE_VIEW_STORE(model);
419
420 if (!accept)
421 return;
422
423 g_object_ref(store);
424 gtk_tree_view_set_model(trace_tree, NULL);
425
426 if (all_cpus) {
427 trace_view_store_set_all_cpus(store);
428 goto set_model;
429 }
430
431 cpus = trace_view_store_get_cpus(store);
432
433 for (cpu = 0; cpu < cpus; cpu++) {
434 if (cpu_isset(selected_cpu_mask, cpu))
435 trace_view_store_set_cpu(store, cpu);
436 else
437 trace_view_store_clear_cpu(store, cpu);
438 }
439
440 set_model:
441 gtk_tree_view_set_model(trace_tree, GTK_TREE_MODEL(store));
442 g_object_unref(store);
443}
diff --git a/trace-view.h b/trace-view.h
index 03d331c..44cf0d0 100644
--- a/trace-view.h
+++ b/trace-view.h
@@ -12,10 +12,68 @@ void trace_view(int argc, char **argv);
12void trace_view_update_task_filter(GtkWidget *treeview, struct filter_task *filter); 12void trace_view_update_task_filter(GtkWidget *treeview, struct filter_task *filter);
13void trace_view_make_selection_visible(GtkWidget *treeview); 13void trace_view_make_selection_visible(GtkWidget *treeview);
14 14
15/* We use void because this can be used by non gtk files */ 15struct event_filter_list {
16void trace_filter_event_dialog(void *traceview); 16 struct event_filter_list *next;
17void trace_filter_cpu_dialog(void *trace_tree); 17 struct event *event;
18};
19
20/**
21 * trace_filter_event_cb_func - callback type for event dialog
22 * @accept: TRUE if the accept button was pressed, otherwise FALSE
23 * @all_events: TRUE if "All Events" was checked
24 * @systems: NULL or a string array of systems terminated with NULL
25 * @events: NULL or a int array of event ids terminated with -1
26 * @data: The data given passed in to the event dialog function
27 *
28 * If @accept is FALSE then @all_events, @systems, and @events
29 * should be ignored. @data is still valid.
30 *
31 * If @all_events is TRUE then @systems and @events should be ignored.
32 */
33typedef void (*trace_filter_event_cb_func)(gboolean accept,
34 gboolean all_events,
35 char **systems,
36 gint *events,
37 gpointer data);
38
39void trace_filter_event_dialog(struct tracecmd_input *handle,
40 gboolean all_events,
41 gchar **systems,
42 gint *events,
43 trace_filter_event_cb_func func,
44 gpointer data);
45
46/**
47 * trace_filter_cpu_cb_func - callback type for CPU dialog
48 * @accept: TRUE if the accept button was pressed, otherwise FALSE
49 * @all_cpus: TRUE if "All CPUS" was checked
50 * @selected_cpus: NULL or a cpu_mask with the cpus that were checked set.
51 * @data: The data given passed in to the CPU dialog function
52 *
53 * If @accept is FALSE then @all_cpus and @selected_cpus should be ignored.
54 * @data is still valid.
55 *
56 * If @all_cpus is TRUE then @selected_cpus should be ignored.
57 */
58typedef void (*trace_filter_cpu_cb_func)(gboolean accept,
59 gboolean all_cpus,
60 guint64 *selected_cpus,
61 gpointer data);
62
63void trace_filter_cpu_dialog(gboolean all_cpus, guint64 *cpu_mask_selected, gint cpus,
64 trace_filter_cpu_cb_func func, gpointer data);
18 65
19void trace_view_select(GtkWidget *treeview, guint64 time); 66void trace_view_select(GtkWidget *treeview, guint64 time);
20 67
68void trace_view_event_filter_callback(gboolean accept,
69 gboolean all_events,
70 gchar **systems,
71 gint *events,
72 gpointer data);
73
74void trace_view_cpu_filter_callback(gboolean accept,
75 gboolean all_cpus,
76 guint64 *selected_cpu_mask,
77 gpointer data);
78
21#endif /* _TRACE_VIEW_H */ 79#endif /* _TRACE_VIEW_H */