1 /* This file is part of the Linux Trace Toolkit viewer
2 * Copyright (C) 2003-2004 XangXiu Yang, Mathieu Desnoyers
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License Version 2 as
6 * published by the Free Software Foundation;
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place - Suite 330, Boston,
23 #include <limits.h> // for PATH_MAX
31 #include "callbacks.h"
32 #include "interface.h"
34 #include <ltt/trace.h>
36 #include <ltt/event.h>
37 #include <lttv/lttv.h>
38 #include <lttv/module.h>
39 #include <lttv/iattribute.h>
40 #include <lttv/stats.h>
41 #include <lttv/filter.h>
42 #include <lttvwindow/mainwindow.h>
43 #include <lttvwindow/mainwindow-private.h>
44 #include <lttvwindow/menu.h>
45 #include <lttvwindow/toolbar.h>
46 #include <lttvwindow/lttvwindow.h>
47 #include <lttvwindow/lttvwindowtraces.h>
48 #include <lttvwindow/lttv_plugin_tab.h>
50 static LttTime lttvwindow_default_time_width
= { 1, 0 };
51 #define CLIP_BUF 256 // size of clipboard buffer
53 extern LttvTrace
*g_init_trace
;
56 /** Array containing instanced objects. */
57 extern GSList
* g_main_window_list
;
59 /** MD : keep old directory. */
60 static char remember_plugins_dir
[PATH_MAX
] = "";
61 static char remember_trace_dir
[PATH_MAX
] = "";
63 void tab_destructor(LttvPluginTab
* ptab
);
65 MainWindow
* get_window_data_struct(GtkWidget
* widget
);
66 char * get_load_module(MainWindow
*mw
,
67 char ** load_module_name
, int nb_module
);
68 char * get_unload_module(MainWindow
*mw
,
69 char ** loaded_module_name
, int nb_module
);
70 char * get_remove_trace(MainWindow
*mw
, char ** all_trace_name
, int nb_trace
);
71 char * get_selection(MainWindow
*mw
,
72 char ** all_name
, int nb
, char *title
, char * column_title
);
73 void init_tab(Tab
*tab
, MainWindow
* mw
, Tab
*copy_tab
,
74 GtkNotebook
* notebook
, char * label
);
76 static void insert_viewer(GtkWidget
* widget
, lttvwindow_viewer_constructor constructor
);
78 LttvPluginTab
*create_new_tab(GtkWidget
* widget
, gpointer user_data
);
80 static gboolean
lttvwindow_process_pending_requests(Tab
*tab
);
94 /* Pasting routines */
96 static void MEventBox1a_receive(GtkClipboard
*clipboard
,
100 if(text
== NULL
) return;
101 Tab
*tab
= (Tab
*)data
;
102 gchar buffer
[CLIP_BUF
];
103 gchar
*ptr
= buffer
, *ptr_ssec
, *ptr_snsec
, *ptr_esec
, *ptr_ensec
;
105 strncpy(buffer
, text
, CLIP_BUF
);
108 while(!isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
109 /* remove leading junk */
111 while(isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
112 /* read all the first number */
116 while(!isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
117 /* remove leading junk */
119 while(isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
120 /* read all the first number */
124 while(!isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
125 /* remove leading junk */
127 while(isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
128 /* read all the first number */
132 while(!isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
133 /* remove leading junk */
135 while(isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
136 /* read all the first number */
139 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry1
),
140 (double)strtoul(ptr_ssec
, NULL
, 10));
141 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry2
),
142 (double)strtoul(ptr_snsec
, NULL
, 10));
143 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry3
),
144 (double)strtoul(ptr_esec
, NULL
, 10));
145 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry4
),
146 (double)strtoul(ptr_ensec
, NULL
, 10));
149 static gboolean
on_MEventBox1a_paste(GtkWidget
*widget
, GdkEventButton
*event
,
152 Tab
*tab
= (Tab
*)data
;
154 GtkClipboard
*clip
= gtk_clipboard_get_for_display(gdk_display_get_default(),
155 GDK_SELECTION_PRIMARY
);
156 gtk_clipboard_request_text(clip
,
157 (GtkClipboardTextReceivedFunc
)MEventBox1a_receive
,
164 static void MEventBox1b_receive(GtkClipboard
*clipboard
,
168 if(text
== NULL
) return;
169 Tab
*tab
= (Tab
*)data
;
170 gchar buffer
[CLIP_BUF
];
171 gchar
*ptr
= buffer
, *ptr_sec
, *ptr_nsec
;
173 strncpy(buffer
, text
, CLIP_BUF
);
175 while(!isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
176 /* remove leading junk */
178 while(isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
179 /* read all the first number */
183 while(!isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
184 /* remove leading junk */
186 while(isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
187 /* read all the first number */
190 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry1
),
191 (double)strtoul(ptr_sec
, NULL
, 10));
192 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry2
),
193 (double)strtoul(ptr_nsec
, NULL
, 10));
197 static gboolean
on_MEventBox1b_paste(GtkWidget
*widget
, GdkEventButton
*event
,
200 Tab
*tab
= (Tab
*)data
;
202 GtkClipboard
*clip
= gtk_clipboard_get_for_display(gdk_display_get_default(),
203 GDK_SELECTION_PRIMARY
);
204 gtk_clipboard_request_text(clip
,
205 (GtkClipboardTextReceivedFunc
)MEventBox1b_receive
,
211 static void MEventBox3b_receive(GtkClipboard
*clipboard
,
215 if(text
== NULL
) return;
216 Tab
*tab
= (Tab
*)data
;
217 gchar buffer
[CLIP_BUF
];
218 gchar
*ptr
= buffer
, *ptr_sec
, *ptr_nsec
;
220 strncpy(buffer
, text
, CLIP_BUF
);
222 while(!isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
223 /* remove leading junk */
225 while(isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
226 /* read all the first number */
230 while(!isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
231 /* remove leading junk */
233 while(isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
234 /* read all the first number */
237 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry3
),
238 (double)strtoul(ptr_sec
, NULL
, 10));
239 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry4
),
240 (double)strtoul(ptr_nsec
, NULL
, 10));
244 static gboolean
on_MEventBox3b_paste(GtkWidget
*widget
, GdkEventButton
*event
,
247 Tab
*tab
= (Tab
*)data
;
249 GtkClipboard
*clip
= gtk_clipboard_get_for_display(gdk_display_get_default(),
250 GDK_SELECTION_PRIMARY
);
251 gtk_clipboard_request_text(clip
,
252 (GtkClipboardTextReceivedFunc
)MEventBox3b_receive
,
258 static void MEventBox5b_receive(GtkClipboard
*clipboard
,
262 if(text
== NULL
) return;
263 Tab
*tab
= (Tab
*)data
;
264 gchar buffer
[CLIP_BUF
];
265 gchar
*ptr
= buffer
, *ptr_sec
, *ptr_nsec
;
267 strncpy(buffer
, text
, CLIP_BUF
);
269 while(!isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
270 /* remove leading junk */
272 while(isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
273 /* read all the first number */
277 while(!isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
278 /* remove leading junk */
280 while(isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
281 /* read all the first number */
284 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry5
),
285 (double)strtoul(ptr_sec
, NULL
, 10));
286 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry6
),
287 (double)strtoul(ptr_nsec
, NULL
, 10));
291 static gboolean
on_MEventBox5b_paste(GtkWidget
*widget
, GdkEventButton
*event
,
294 Tab
*tab
= (Tab
*)data
;
296 GtkClipboard
*clip
= gtk_clipboard_get_for_display(gdk_display_get_default(),
297 GDK_SELECTION_PRIMARY
);
298 gtk_clipboard_request_text(clip
,
299 (GtkClipboardTextReceivedFunc
)MEventBox5b_receive
,
305 static void MEventBox8_receive(GtkClipboard
*clipboard
,
309 if(text
== NULL
) return;
310 Tab
*tab
= (Tab
*)data
;
311 gchar buffer
[CLIP_BUF
];
312 gchar
*ptr
= buffer
, *ptr_sec
, *ptr_nsec
;
314 strncpy(buffer
, text
, CLIP_BUF
);
316 while(!isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
317 /* remove leading junk */
319 while(isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
320 /* read all the first number */
324 while(!isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
325 /* remove leading junk */
327 while(isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
328 /* read all the first number */
331 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry7
),
332 (double)strtoul(ptr_sec
, NULL
, 10));
333 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry8
),
334 (double)strtoul(ptr_nsec
, NULL
, 10));
338 static gboolean
on_MEventBox8_paste(GtkWidget
*widget
, GdkEventButton
*event
,
341 Tab
*tab
= (Tab
*)data
;
343 GtkClipboard
*clip
= gtk_clipboard_get_for_display(gdk_display_get_default(),
344 GDK_SELECTION_PRIMARY
);
345 gtk_clipboard_request_text(clip
,
346 (GtkClipboardTextReceivedFunc
)MEventBox8_receive
,
352 static void on_top_notify(GObject
*gobject
,
356 Tab
*tab
= (Tab
*)user_data
;
357 g_message("in on_top_notify.\n");
361 static gboolean
viewer_grab_focus(GtkWidget
*widget
, GdkEventButton
*event
,
364 GtkWidget
*viewer
= GTK_WIDGET(data
);
365 GtkWidget
*viewer_container
= gtk_widget_get_parent(viewer
);
367 g_debug("FOCUS GRABBED");
368 g_object_set_data(G_OBJECT(viewer_container
), "focused_viewer", viewer
);
373 static void connect_focus_recursive(GtkWidget
*widget
,
376 if(GTK_IS_CONTAINER(widget
)) {
377 gtk_container_forall(GTK_CONTAINER(widget
),
378 (GtkCallback
)connect_focus_recursive
,
382 if(GTK_IS_TREE_VIEW(widget
)) {
383 gtk_tree_view_set_headers_clickable(GTK_TREE_VIEW(widget
), TRUE
);
385 gtk_widget_add_events(widget
, GDK_BUTTON_PRESS_MASK
);
386 g_signal_connect (G_OBJECT(widget
),
387 "button-press-event",
388 G_CALLBACK (viewer_grab_focus
),
392 /* Stop all the processings and call gtk_main_quit() */
393 static void mainwindow_quit()
395 lttvwindowtraces_unregister_requests(g_quark_from_string("stats"));
396 lttvwindowtraces_unregister_requests(g_quark_from_string("state"));
397 lttvwindowtraces_unregister_computation_hooks(g_quark_from_string("stats"));
398 lttvwindowtraces_unregister_computation_hooks(g_quark_from_string("state"));
404 /* insert_viewer function constructs an instance of a viewer first,
405 * then inserts the widget of the instance into the container of the
410 insert_viewer_wrap(GtkWidget
*menuitem
, gpointer user_data
)
412 insert_viewer((GtkWidget
*)menuitem
, (lttvwindow_viewer_constructor
)user_data
);
416 /* internal functions */
417 void insert_viewer(GtkWidget
* widget
, lttvwindow_viewer_constructor constructor
)
419 GtkWidget
* viewer_container
;
420 MainWindow
* mw_data
= get_window_data_struct(widget
);
421 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
423 TimeInterval
* time_interval
;
424 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
425 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
430 ptab
= create_new_tab(widget
, NULL
);
432 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
436 viewer_container
= tab
->viewer_container
;
438 viewer
= (GtkWidget
*)constructor(ptab
);
441 //gtk_multivpaned_widget_add(GTK_MULTIVPANED(multivpaned), viewer);
443 gtk_box_pack_end(GTK_BOX(viewer_container
),
449 /* We want to connect the viewer_grab_focus to EVERY
450 * child of this widget. The little trick is to get each child
451 * of each GTK_CONTAINER, even subchildren.
453 connect_focus_recursive(viewer
, viewer
);
458 * Function to set/update traceset for the viewers
459 * @param tab viewer's tab
460 * @param traceset traceset of the main window.
462 * 0 : traceset updated
463 * 1 : no traceset hooks to update; not an error.
466 int SetTraceset(Tab
* tab
, LttvTraceset
*traceset
)
468 LttvTracesetContext
*tsc
=
469 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
470 TimeInterval time_span
= tsc
->time_span
;
471 TimeWindow new_time_window
= tab
->time_window
;
472 LttTime new_current_time
= tab
->current_time
;
474 /* Set the tab's time window and current time if
476 if(ltt_time_compare(tab
->time_window
.start_time
, time_span
.start_time
) < 0
477 || ltt_time_compare(tab
->time_window
.end_time
,
478 time_span
.end_time
) > 0) {
479 new_time_window
.start_time
= time_span
.start_time
;
481 new_current_time
= time_span
.start_time
;
485 if(ltt_time_compare(lttvwindow_default_time_width
,
486 ltt_time_sub(time_span
.end_time
, time_span
.start_time
)) < 0
488 ltt_time_compare(time_span
.end_time
, time_span
.start_time
) == 0)
489 tmp_time
= lttvwindow_default_time_width
;
491 tmp_time
= time_span
.end_time
;
493 new_time_window
.time_width
= tmp_time
;
494 new_time_window
.time_width_double
= ltt_time_to_double(tmp_time
);
495 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
496 new_time_window
.time_width
) ;
503 GtkAdjustment
*adjustment
= gtk_range_get_adjustment(GTK_RANGE(tab
->scrollbar
));
504 LttTime upper
= ltt_time_sub(time_span
.end_time
, time_span
.start_time
);
506 g_object_set(G_OBJECT(adjustment
),
510 ltt_time_to_double(upper
)
511 * NANOSECONDS_PER_SECOND
, /* upper */
513 ltt_time_to_double(tab
->time_window
.time_width
)
514 / SCROLL_STEP_PER_PAGE
515 * NANOSECONDS_PER_SECOND
, /* step increment */
517 ltt_time_to_double(tab
->time_window
.time_width
)
518 * NANOSECONDS_PER_SECOND
, /* page increment */
520 ltt_time_to_double(tab
->time_window
.time_width
)
521 * NANOSECONDS_PER_SECOND
, /* page size */
523 gtk_adjustment_changed(adjustment
);
525 g_object_set(G_OBJECT(adjustment
),
528 ltt_time_sub(tab
->time_window
.start_time
, time_span
.start_time
))
529 * NANOSECONDS_PER_SECOND
, /* value */
531 gtk_adjustment_value_changed(adjustment
);
533 /* set the time bar. The value callbacks will change their nsec themself */
535 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry1
),
536 (double)time_span
.start_time
.tv_sec
,
537 (double)time_span
.end_time
.tv_sec
);
540 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry3
),
541 (double)time_span
.start_time
.tv_sec
,
542 (double)time_span
.end_time
.tv_sec
);
544 /* current seconds */
545 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry5
),
546 (double)time_span
.start_time
.tv_sec
,
547 (double)time_span
.end_time
.tv_sec
);
550 /* Finally, call the update hooks of the viewers */
552 LttvAttributeValue value
;
556 g_assert( lttv_iattribute_find_by_path(tab
->attributes
,
557 "hooks/updatetraceset", LTTV_POINTER
, &value
));
559 tmp
= (LttvHooks
*)*(value
.v_pointer
);
560 if(tmp
== NULL
) retval
= 1;
561 else lttv_hooks_call(tmp
,traceset
);
563 time_change_manager(tab
, new_time_window
);
564 current_time_change_manager(tab
, new_current_time
);
570 * Function to set/update filter for the viewers
571 * @param tab viewer's tab
572 * @param filter filter of the main window.
575 * 0 : filters updated
576 * 1 : no filter hooks to update; not an error.
579 int SetFilter(Tab
* tab
, gpointer filter
)
582 LttvAttributeValue value
;
584 g_assert(lttv_iattribute_find_by_path(tab
->attributes
,
585 "hooks/updatefilter", LTTV_POINTER
, &value
));
587 tmp
= (LttvHooks
*)*(value
.v_pointer
);
589 if(tmp
== NULL
) return 1;
590 lttv_hooks_call(tmp
,filter
);
598 * Function to redraw each viewer belonging to the current tab
599 * @param tab viewer's tab
602 void update_traceset(Tab
*tab
)
604 LttvAttributeValue value
;
606 g_assert(lttv_iattribute_find_by_path(tab
->attributes
,
607 "hooks/updatetraceset", LTTV_POINTER
, &value
));
608 tmp
= (LttvHooks
*)*(value
.v_pointer
);
609 if(tmp
== NULL
) return;
610 lttv_hooks_call(tmp
, NULL
);
614 /* get_label function is used to get user input, it displays an input
615 * box, which allows user to input a string
618 void get_label_string (GtkWidget
* text
, gchar
* label
)
620 GtkEntry
* entry
= (GtkEntry
*)text
;
621 if(strlen(gtk_entry_get_text(entry
))!=0)
622 strcpy(label
,gtk_entry_get_text(entry
));
625 gboolean
get_label(MainWindow
* mw
, gchar
* str
, gchar
* dialogue_title
, gchar
* label_str
)
627 GtkWidget
* dialogue
;
632 dialogue
= gtk_dialog_new_with_buttons(dialogue_title
,NULL
,
634 GTK_STOCK_OK
,GTK_RESPONSE_ACCEPT
,
635 GTK_STOCK_CANCEL
,GTK_RESPONSE_REJECT
,
638 label
= gtk_label_new(label_str
);
639 gtk_widget_show(label
);
641 text
= gtk_entry_new();
642 gtk_widget_show(text
);
644 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialogue
)->vbox
), label
,TRUE
, TRUE
,0);
645 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialogue
)->vbox
), text
,FALSE
, FALSE
,0);
647 id
= gtk_dialog_run(GTK_DIALOG(dialogue
));
649 case GTK_RESPONSE_ACCEPT
:
650 get_label_string(text
,str
);
651 gtk_widget_destroy(dialogue
);
653 case GTK_RESPONSE_REJECT
:
655 gtk_widget_destroy(dialogue
);
662 /* get_window_data_struct function is actually a lookup function,
663 * given a widget which is in the tree of the main window, it will
664 * return the MainWindow data structure associated with main window
667 MainWindow
* get_window_data_struct(GtkWidget
* widget
)
670 MainWindow
* mw_data
;
672 mw
= lookup_widget(widget
, "MWindow");
674 g_info("Main window does not exist\n");
678 mw_data
= (MainWindow
*) g_object_get_data(G_OBJECT(mw
),"main_window_data");
680 g_warning("Main window data does not exist\n");
687 /* create_new_window function, just constructs a new main window
690 void create_new_window(GtkWidget
* widget
, gpointer user_data
, gboolean clone
)
692 MainWindow
* parent
= get_window_data_struct(widget
);
695 g_info("Clone : use the same traceset\n");
696 construct_main_window(parent
);
698 g_info("Empty : traceset is set to NULL\n");
699 construct_main_window(NULL
);
703 /* Get the currently focused viewer.
704 * If no viewer is focused, use the first one.
706 * If no viewer available, return NULL.
708 GtkWidget
*viewer_container_focus(GtkWidget
*container
)
712 widget
= (GtkWidget
*)g_object_get_data(G_OBJECT(container
),
716 g_debug("no widget focused");
717 GList
*children
= gtk_container_get_children(GTK_CONTAINER(container
));
720 widget
= GTK_WIDGET(children
->data
);
721 g_object_set_data(G_OBJECT(container
),
731 gint
viewer_container_position(GtkWidget
*container
, GtkWidget
*child
)
734 if(child
== NULL
) return -1;
738 memset(&value
, 0, sizeof(GValue
));
739 g_value_init(&value
, G_TYPE_INT
);
740 gtk_container_child_get_property(GTK_CONTAINER(container
),
744 pos
= g_value_get_int(&value
);
750 /* move_*_viewer functions move the selected view up/down in
754 void move_down_viewer(GtkWidget
* widget
, gpointer user_data
)
756 MainWindow
* mw
= get_window_data_struct(widget
);
757 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
759 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
760 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
767 ptab
= g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
771 //gtk_multivpaned_widget_move_up(GTK_MULTIVPANED(tab->multivpaned));
773 /* change the position in the vbox */
774 GtkWidget
*focus_widget
;
776 focus_widget
= viewer_container_focus(tab
->viewer_container
);
777 position
= viewer_container_position(tab
->viewer_container
, focus_widget
);
780 /* can move up one position */
781 gtk_box_reorder_child(GTK_BOX(tab
->viewer_container
),
788 void move_up_viewer(GtkWidget
* widget
, gpointer user_data
)
790 MainWindow
* mw
= get_window_data_struct(widget
);
791 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
793 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
794 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
801 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
805 //gtk_multivpaned_widget_move_down(GTK_MULTIVPANED(tab->multivpaned));
806 /* change the position in the vbox */
807 GtkWidget
*focus_widget
;
809 focus_widget
= viewer_container_focus(tab
->viewer_container
);
810 position
= viewer_container_position(tab
->viewer_container
, focus_widget
);
814 g_list_length(gtk_container_get_children(
815 GTK_CONTAINER(tab
->viewer_container
)))-1
817 /* can move down one position */
818 gtk_box_reorder_child(GTK_BOX(tab
->viewer_container
),
826 /* delete_viewer deletes the selected viewer in the current tab
829 void delete_viewer(GtkWidget
* widget
, gpointer user_data
)
831 MainWindow
* mw
= get_window_data_struct(widget
);
832 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
834 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
835 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
842 ptab
= g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
846 //gtk_multivpaned_widget_delete(GTK_MULTIVPANED(tab->multivpaned));
848 GtkWidget
*focus_widget
= viewer_container_focus(tab
->viewer_container
);
850 if(focus_widget
!= NULL
)
851 gtk_widget_destroy(focus_widget
);
853 g_object_set_data(G_OBJECT(tab
->viewer_container
), "focused_viewer", NULL
);
857 /* open_traceset will open a traceset saved in a file
858 * Right now, it is not finished yet, (not working)
862 void open_traceset(GtkWidget
* widget
, gpointer user_data
)
866 LttvTraceset
* traceset
;
867 MainWindow
* mw_data
= get_window_data_struct(widget
);
868 GtkFileSelection
* file_selector
=
869 (GtkFileSelection
*)gtk_file_selection_new("Select a traceset");
871 gtk_file_selection_hide_fileop_buttons(file_selector
);
873 gtk_window_set_transient_for(GTK_WINDOW(file_selector
),
874 GTK_WINDOW(mw_data
->mwindow
));
876 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
878 case GTK_RESPONSE_ACCEPT
:
879 case GTK_RESPONSE_OK
:
880 dir
= gtk_file_selection_get_selections (file_selector
);
881 traceset
= lttv_traceset_load(dir
[0]);
882 g_info("Open a trace set %s\n", dir
[0]);
885 case GTK_RESPONSE_REJECT
:
886 case GTK_RESPONSE_CANCEL
:
888 gtk_widget_destroy((GtkWidget
*)file_selector
);
894 /* lttvwindow_process_pending_requests
896 * Process requests for parts of the trace from viewers.
898 * These requests are made by lttvwindow_events_request().
900 * This internal function gets called by g_idle, taking care of the pending
901 * requests. It is responsible for concatenation of time intervals and position
902 * requests. It does it with the following algorithm organizing process traceset
903 * calls. Here is the detailed description of the way it works :
905 * - Events Requests Servicing Algorithm
907 * Data structures necessary :
909 * List of requests added to context : list_in
910 * List of requests not added to context : list_out
915 * list_out : many events requests
917 * FIXME : insert rest of algorithm here
921 #define list_out tab->events_requests
923 gboolean
lttvwindow_process_pending_requests(Tab
*tab
)
926 LttvTracesetContext
*tsc
;
927 LttvTracefileContext
*tfc
;
928 GSList
*list_in
= NULL
;
932 LttvTracesetContextPosition
*end_position
;
934 if(lttvwindow_preempt_count
> 0) return TRUE
;
937 g_critical("Foreground processing : tab does not exist. Processing removed.");
941 /* There is no events requests pending : we should never have been called! */
942 g_assert(g_slist_length(list_out
) != 0);
944 tsc
= LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
946 //set the cursor to be X shape, indicating that the computer is busy in doing its job
948 new = gdk_cursor_new(GDK_X_CURSOR
);
949 widget
= lookup_widget(tab
->mw
->mwindow
, "MToolbar1");
950 win
= gtk_widget_get_parent_window(widget
);
951 gdk_window_set_cursor(win
, new);
952 gdk_cursor_unref(new);
953 gdk_window_stick(win
);
954 gdk_window_unstick(win
);
957 g_debug("SIZE events req len : %d", g_slist_length(list_out
));
959 /* Preliminary check for no trace in traceset */
960 /* Unregister the routine if empty, empty list_out too */
961 if(lttv_traceset_number(tsc
->ts
) == 0) {
963 /* - For each req in list_out */
964 GSList
*iter
= list_out
;
966 while(iter
!= NULL
) {
968 gboolean remove
= FALSE
;
969 gboolean free_data
= FALSE
;
970 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
972 /* - Call end request for req */
973 if(events_request
->servicing
== TRUE
)
974 lttv_hooks_call(events_request
->after_request
, (gpointer
)tsc
);
976 /* - remove req from list_out */
977 /* Destroy the request */
984 GSList
*remove_iter
= iter
;
986 iter
= g_slist_next(iter
);
987 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
988 list_out
= g_slist_remove_link(list_out
, remove_iter
);
989 } else { // not remove
990 iter
= g_slist_next(iter
);
995 /* 0.1 Lock Traces */
1000 iter_trace
<lttv_traceset_number(tsc
->ts
);
1002 LttvTrace
*trace_v
= lttv_traceset_get(tsc
->ts
, iter_trace
);
1004 if(lttvwindowtraces_lock(trace_v
) != 0) {
1005 g_critical("Foreground processing : Unable to get trace lock");
1006 return TRUE
; /* Cannot get lock, try later */
1011 /* 0.2 Seek tracefiles positions to context position */
1012 //g_assert(lttv_process_traceset_seek_position(tsc, sync_position) == 0);
1013 lttv_process_traceset_synchronize_tracefiles(tsc
);
1016 /* Events processing algorithm implementation */
1017 /* Warning : the gtk_events_pending takes a LOT of cpu time. So what we do
1018 * instead is to leave the control to GTK and take it back.
1020 /* A. Servicing loop */
1021 //while( (g_slist_length(list_in) != 0 || g_slist_length(list_out) != 0)) {
1022 if((g_slist_length(list_in
) != 0 || g_slist_length(list_out
) != 0)) {
1024 /* 1. If list_in is empty (need a seek) */
1025 if( g_slist_length(list_in
) == 0 ) {
1027 /* list in is empty, need a seek */
1029 /* 1.1 Add requests to list_in */
1030 GSList
*ltime
= NULL
;
1031 GSList
*lpos
= NULL
;
1032 GSList
*iter
= NULL
;
1034 /* 1.1.1 Find all time requests with the lowest start time in list_out
1037 if(g_slist_length(list_out
) > 0)
1038 ltime
= g_slist_append(ltime
, g_slist_nth_data(list_out
, 0));
1039 for(iter
=g_slist_nth(list_out
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
1040 /* Find all time requests with the lowest start time in list_out */
1041 EventsRequest
*event_request_ltime
= (EventsRequest
*)g_slist_nth_data(ltime
, 0);
1042 EventsRequest
*event_request_list_out
= (EventsRequest
*)iter
->data
;
1045 comp
= ltt_time_compare(event_request_ltime
->start_time
,
1046 event_request_list_out
->start_time
);
1048 ltime
= g_slist_append(ltime
, event_request_list_out
);
1050 /* Remove all elements from ltime, and add current */
1051 while(ltime
!= NULL
)
1052 ltime
= g_slist_delete_link(ltime
, g_slist_nth(ltime
, 0));
1053 ltime
= g_slist_append(ltime
, event_request_list_out
);
1057 /* 1.1.2 Find all position requests with the lowest position in list_out
1060 if(g_slist_length(list_out
) > 0)
1061 lpos
= g_slist_append(lpos
, g_slist_nth_data(list_out
, 0));
1062 for(iter
=g_slist_nth(list_out
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
1063 /* Find all position requests with the lowest position in list_out */
1064 EventsRequest
*event_request_lpos
= (EventsRequest
*)g_slist_nth_data(lpos
, 0);
1065 EventsRequest
*event_request_list_out
= (EventsRequest
*)iter
->data
;
1068 if(event_request_lpos
->start_position
!= NULL
1069 && event_request_list_out
->start_position
!= NULL
)
1071 comp
= lttv_traceset_context_pos_pos_compare
1072 (event_request_lpos
->start_position
,
1073 event_request_list_out
->start_position
);
1078 lpos
= g_slist_append(lpos
, event_request_list_out
);
1080 /* Remove all elements from lpos, and add current */
1082 lpos
= g_slist_delete_link(lpos
, g_slist_nth(lpos
, 0));
1083 lpos
= g_slist_append(lpos
, event_request_list_out
);
1088 EventsRequest
*event_request_lpos
= (EventsRequest
*)g_slist_nth_data(lpos
, 0);
1089 EventsRequest
*event_request_ltime
= (EventsRequest
*)g_slist_nth_data(ltime
, 0);
1090 LttTime lpos_start_time
;
1092 if(event_request_lpos
!= NULL
1093 && event_request_lpos
->start_position
!= NULL
) {
1094 lpos_start_time
= lttv_traceset_context_position_get_time(
1095 event_request_lpos
->start_position
);
1098 /* 1.1.3 If lpos.start time < ltime */
1099 if(event_request_lpos
!= NULL
1100 && event_request_lpos
->start_position
!= NULL
1101 && ltt_time_compare(lpos_start_time
,
1102 event_request_ltime
->start_time
)<0) {
1103 /* Add lpos to list_in, remove them from list_out */
1104 for(iter
=lpos
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
1105 /* Add to list_in */
1106 EventsRequest
*event_request_lpos
=
1107 (EventsRequest
*)iter
->data
;
1109 list_in
= g_slist_append(list_in
, event_request_lpos
);
1110 /* Remove from list_out */
1111 list_out
= g_slist_remove(list_out
, event_request_lpos
);
1114 /* 1.1.4 (lpos.start time >= ltime) */
1115 /* Add ltime to list_in, remove them from list_out */
1117 for(iter
=ltime
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
1118 /* Add to list_in */
1119 EventsRequest
*event_request_ltime
=
1120 (EventsRequest
*)iter
->data
;
1122 list_in
= g_slist_append(list_in
, event_request_ltime
);
1123 /* Remove from list_out */
1124 list_out
= g_slist_remove(list_out
, event_request_ltime
);
1129 g_slist_free(ltime
);
1134 tfc
= lttv_traceset_context_get_current_tfc(tsc
);
1135 g_assert(g_slist_length(list_in
)>0);
1136 EventsRequest
*events_request
= g_slist_nth_data(list_in
, 0);
1139 /* 1.2.1 If first request in list_in is a time request */
1140 if(events_request
->start_position
== NULL
) {
1141 /* - If first req in list_in start time != current time */
1142 if(tfc
== NULL
|| ltt_time_compare(events_request
->start_time
,
1143 tfc
->timestamp
) != 0)
1144 /* - Seek to that time */
1145 g_debug("SEEK TIME : %lu, %lu", events_request
->start_time
.tv_sec
,
1146 events_request
->start_time
.tv_nsec
);
1147 //lttv_process_traceset_seek_time(tsc, events_request->start_time);
1148 lttv_state_traceset_seek_time_closest(LTTV_TRACESET_STATE(tsc
),
1149 events_request
->start_time
);
1151 /* Process the traceset with only state hooks */
1153 lttv_process_traceset_middle(tsc
,
1154 events_request
->start_time
,
1157 g_assert(seek_count
< LTTV_STATE_SAVE_INTERVAL
);
1163 LttvTracefileContext
*tfc
=
1164 lttv_traceset_context_get_current_tfc(tsc
);
1165 /* Else, the first request in list_in is a position request */
1166 /* If first req in list_in pos != current pos */
1167 g_assert(events_request
->start_position
!= NULL
);
1168 g_debug("SEEK POS time : %lu, %lu",
1169 lttv_traceset_context_position_get_time(
1170 events_request
->start_position
).tv_sec
,
1171 lttv_traceset_context_position_get_time(
1172 events_request
->start_position
).tv_nsec
);
1175 g_debug("SEEK POS context time : %lu, %lu",
1176 tfc
->timestamp
.tv_sec
,
1177 tfc
->timestamp
.tv_nsec
);
1179 g_debug("SEEK POS context time : %lu, %lu",
1180 ltt_time_infinite
.tv_sec
,
1181 ltt_time_infinite
.tv_nsec
);
1183 g_assert(events_request
->start_position
!= NULL
);
1184 if(lttv_traceset_context_ctx_pos_compare(tsc
,
1185 events_request
->start_position
) != 0) {
1186 /* 1.2.2.1 Seek to that position */
1187 g_debug("SEEK POSITION");
1188 //lttv_process_traceset_seek_position(tsc, events_request->start_position);
1189 pos_time
= lttv_traceset_context_position_get_time(
1190 events_request
->start_position
);
1192 lttv_state_traceset_seek_time_closest(LTTV_TRACESET_STATE(tsc
),
1195 /* Process the traceset with only state hooks */
1197 lttv_process_traceset_middle(tsc
,
1200 events_request
->start_position
);
1201 g_assert(lttv_traceset_context_ctx_pos_compare(tsc
,
1202 events_request
->start_position
) == 0);
1209 /* 1.3 Add hooks and call before request for all list_in members */
1211 GSList
*iter
= NULL
;
1213 for(iter
=list_in
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
1214 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1215 /* 1.3.1 If !servicing */
1216 if(events_request
->servicing
== FALSE
) {
1217 /* - begin request hooks called
1218 * - servicing = TRUE
1220 lttv_hooks_call(events_request
->before_request
, (gpointer
)tsc
);
1221 events_request
->servicing
= TRUE
;
1223 /* 1.3.2 call before chunk
1224 * 1.3.3 events hooks added
1226 if(events_request
->trace
== -1)
1227 lttv_process_traceset_begin(tsc
,
1228 events_request
->before_chunk_traceset
,
1229 events_request
->before_chunk_trace
,
1230 events_request
->before_chunk_tracefile
,
1231 events_request
->event
,
1232 events_request
->event_by_id_channel
);
1234 guint nb_trace
= lttv_traceset_number(tsc
->ts
);
1235 g_assert((guint
)events_request
->trace
< nb_trace
&&
1236 events_request
->trace
> -1);
1237 LttvTraceContext
*tc
= tsc
->traces
[events_request
->trace
];
1239 lttv_hooks_call(events_request
->before_chunk_traceset
, tsc
);
1241 lttv_trace_context_add_hooks(tc
,
1242 events_request
->before_chunk_trace
,
1243 events_request
->before_chunk_tracefile
,
1244 events_request
->event
,
1245 events_request
->event_by_id_channel
);
1250 /* 2. Else, list_in is not empty, we continue a read */
1253 /* 2.0 For each req of list_in */
1254 GSList
*iter
= list_in
;
1256 while(iter
!= NULL
) {
1258 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1260 /* - Call before chunk
1261 * - events hooks added
1263 if(events_request
->trace
== -1)
1264 lttv_process_traceset_begin(tsc
,
1265 events_request
->before_chunk_traceset
,
1266 events_request
->before_chunk_trace
,
1267 events_request
->before_chunk_tracefile
,
1268 events_request
->event
,
1269 events_request
->event_by_id_channel
);
1271 guint nb_trace
= lttv_traceset_number(tsc
->ts
);
1272 g_assert((guint
)events_request
->trace
< nb_trace
&&
1273 events_request
->trace
> -1);
1274 LttvTraceContext
*tc
= tsc
->traces
[events_request
->trace
];
1276 lttv_hooks_call(events_request
->before_chunk_traceset
, tsc
);
1278 lttv_trace_context_add_hooks(tc
,
1279 events_request
->before_chunk_trace
,
1280 events_request
->before_chunk_tracefile
,
1281 events_request
->event
,
1282 events_request
->event_by_id_channel
);
1285 iter
= g_slist_next(iter
);
1290 tfc
= lttv_traceset_context_get_current_tfc(tsc
);
1292 /* 2.1 For each req of list_out */
1293 GSList
*iter
= list_out
;
1295 while(iter
!= NULL
) {
1297 gboolean remove
= FALSE
;
1298 gboolean free_data
= FALSE
;
1299 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1301 /* if req.start time == current context time
1302 * or req.start position == current position*/
1303 if( ltt_time_compare(events_request
->start_time
,
1304 tfc
->timestamp
) == 0
1306 (events_request
->start_position
!= NULL
1308 lttv_traceset_context_ctx_pos_compare(tsc
,
1309 events_request
->start_position
) == 0)
1311 /* - Add to list_in, remove from list_out */
1312 list_in
= g_slist_append(list_in
, events_request
);
1316 /* - If !servicing */
1317 if(events_request
->servicing
== FALSE
) {
1318 /* - begin request hooks called
1319 * - servicing = TRUE
1321 lttv_hooks_call(events_request
->before_request
, (gpointer
)tsc
);
1322 events_request
->servicing
= TRUE
;
1324 /* call before chunk
1325 * events hooks added
1327 if(events_request
->trace
== -1)
1328 lttv_process_traceset_begin(tsc
,
1329 events_request
->before_chunk_traceset
,
1330 events_request
->before_chunk_trace
,
1331 events_request
->before_chunk_tracefile
,
1332 events_request
->event
,
1333 events_request
->event_by_id_channel
);
1335 guint nb_trace
= lttv_traceset_number(tsc
->ts
);
1336 g_assert((guint
)events_request
->trace
< nb_trace
&&
1337 events_request
->trace
> -1);
1338 LttvTraceContext
*tc
= tsc
->traces
[events_request
->trace
];
1340 lttv_hooks_call(events_request
->before_chunk_traceset
, tsc
);
1342 lttv_trace_context_add_hooks(tc
,
1343 events_request
->before_chunk_trace
,
1344 events_request
->before_chunk_tracefile
,
1345 events_request
->event
,
1346 events_request
->event_by_id_channel
);
1355 GSList
*remove_iter
= iter
;
1357 iter
= g_slist_next(iter
);
1358 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
1359 list_out
= g_slist_remove_link(list_out
, remove_iter
);
1360 } else { // not remove
1361 iter
= g_slist_next(iter
);
1367 /* 3. Find end criterions */
1372 /* 3.1.1 Find lowest end time in list_in */
1373 g_assert(g_slist_length(list_in
)>0);
1374 end_time
= ((EventsRequest
*)g_slist_nth_data(list_in
,0))->end_time
;
1376 for(iter
=g_slist_nth(list_in
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
1377 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1379 if(ltt_time_compare(events_request
->end_time
,
1381 end_time
= events_request
->end_time
;
1384 /* 3.1.2 Find lowest start time in list_out */
1385 for(iter
=list_out
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
1386 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1388 if(ltt_time_compare(events_request
->start_time
,
1390 end_time
= events_request
->start_time
;
1395 /* 3.2 Number of events */
1397 /* 3.2.1 Find lowest number of events in list_in */
1400 end_nb_events
= ((EventsRequest
*)g_slist_nth_data(list_in
,0))->num_events
;
1402 for(iter
=g_slist_nth(list_in
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
1403 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1405 if(events_request
->num_events
< end_nb_events
)
1406 end_nb_events
= events_request
->num_events
;
1409 /* 3.2.2 Use min(CHUNK_NUM_EVENTS, min num events in list_in) as
1412 end_nb_events
= MIN(CHUNK_NUM_EVENTS
, end_nb_events
);
1416 /* 3.3 End position */
1418 /* 3.3.1 Find lowest end position in list_in */
1421 end_position
=((EventsRequest
*)g_slist_nth_data(list_in
,0))->end_position
;
1423 for(iter
=g_slist_nth(list_in
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
1424 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1426 if(events_request
->end_position
!= NULL
&& end_position
!= NULL
&&
1427 lttv_traceset_context_pos_pos_compare(events_request
->end_position
,
1429 end_position
= events_request
->end_position
;
1434 /* 3.3.2 Find lowest start position in list_out */
1437 for(iter
=list_out
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
1438 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1440 if(events_request
->end_position
!= NULL
&& end_position
!= NULL
&&
1441 lttv_traceset_context_pos_pos_compare(events_request
->end_position
,
1443 end_position
= events_request
->end_position
;
1448 /* 4. Call process traceset middle */
1449 g_debug("Calling process traceset middle with %p, %lu sec %lu nsec, %u nb ev, %p end pos", tsc
, end_time
.tv_sec
, end_time
.tv_nsec
, end_nb_events
, end_position
);
1450 count
= lttv_process_traceset_middle(tsc
, end_time
, end_nb_events
, end_position
);
1452 tfc
= lttv_traceset_context_get_current_tfc(tsc
);
1454 g_debug("Context time after middle : %lu, %lu", tfc
->timestamp
.tv_sec
,
1455 tfc
->timestamp
.tv_nsec
);
1457 g_debug("End of trace reached after middle.");
1461 /* 5. After process traceset middle */
1462 tfc
= lttv_traceset_context_get_current_tfc(tsc
);
1464 /* - if current context time > traceset.end time */
1465 if(tfc
== NULL
|| ltt_time_compare(tfc
->timestamp
,
1466 tsc
->time_span
.end_time
) > 0) {
1467 /* - For each req in list_in */
1468 GSList
*iter
= list_in
;
1470 while(iter
!= NULL
) {
1472 gboolean remove
= FALSE
;
1473 gboolean free_data
= FALSE
;
1474 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1476 /* - Remove events hooks for req
1477 * - Call end chunk for req
1480 if(events_request
->trace
== -1)
1481 lttv_process_traceset_end(tsc
,
1482 events_request
->after_chunk_traceset
,
1483 events_request
->after_chunk_trace
,
1484 events_request
->after_chunk_tracefile
,
1485 events_request
->event
,
1486 events_request
->event_by_id_channel
);
1489 guint nb_trace
= lttv_traceset_number(tsc
->ts
);
1490 g_assert(events_request
->trace
< nb_trace
&&
1491 events_request
->trace
> -1);
1492 LttvTraceContext
*tc
= tsc
->traces
[events_request
->trace
];
1494 lttv_trace_context_remove_hooks(tc
,
1495 events_request
->after_chunk_trace
,
1496 events_request
->after_chunk_tracefile
,
1497 events_request
->event
,
1498 events_request
->event_by_id_channel
);
1499 lttv_hooks_call(events_request
->after_chunk_traceset
, tsc
);
1504 /* - Call end request for req */
1505 lttv_hooks_call(events_request
->after_request
, (gpointer
)tsc
);
1507 /* - remove req from list_in */
1508 /* Destroy the request */
1515 GSList
*remove_iter
= iter
;
1517 iter
= g_slist_next(iter
);
1518 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
1519 list_in
= g_slist_remove_link(list_in
, remove_iter
);
1520 } else { // not remove
1521 iter
= g_slist_next(iter
);
1526 /* 5.1 For each req in list_in */
1527 GSList
*iter
= list_in
;
1529 while(iter
!= NULL
) {
1531 gboolean remove
= FALSE
;
1532 gboolean free_data
= FALSE
;
1533 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1535 /* - Remove events hooks for req
1536 * - Call end chunk for req
1538 if(events_request
->trace
== -1)
1539 lttv_process_traceset_end(tsc
,
1540 events_request
->after_chunk_traceset
,
1541 events_request
->after_chunk_trace
,
1542 events_request
->after_chunk_tracefile
,
1543 events_request
->event
,
1544 events_request
->event_by_id_channel
);
1547 guint nb_trace
= lttv_traceset_number(tsc
->ts
);
1548 g_assert(events_request
->trace
< nb_trace
&&
1549 events_request
->trace
> -1);
1550 LttvTraceContext
*tc
= tsc
->traces
[events_request
->trace
];
1552 lttv_trace_context_remove_hooks(tc
,
1553 events_request
->after_chunk_trace
,
1554 events_request
->after_chunk_tracefile
,
1555 events_request
->event
,
1556 events_request
->event_by_id_channel
);
1558 lttv_hooks_call(events_request
->after_chunk_traceset
, tsc
);
1561 /* - req.num -= count */
1562 g_assert(events_request
->num_events
>= count
);
1563 events_request
->num_events
-= count
;
1565 g_assert(tfc
!= NULL
);
1566 /* - if req.num == 0
1568 * current context time >= req.end time
1570 * req.end pos == current pos
1572 * req.stop_flag == TRUE
1574 if( events_request
->num_events
== 0
1576 events_request
->stop_flag
== TRUE
1578 ltt_time_compare(tfc
->timestamp
,
1579 events_request
->end_time
) >= 0
1581 (events_request
->end_position
!= NULL
1583 lttv_traceset_context_ctx_pos_compare(tsc
,
1584 events_request
->end_position
) == 0)
1587 g_assert(events_request
->servicing
== TRUE
);
1588 /* - Call end request for req
1589 * - remove req from list_in */
1590 lttv_hooks_call(events_request
->after_request
, (gpointer
)tsc
);
1591 /* - remove req from list_in */
1592 /* Destroy the request */
1600 GSList
*remove_iter
= iter
;
1602 iter
= g_slist_next(iter
);
1603 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
1604 list_in
= g_slist_remove_link(list_in
, remove_iter
);
1605 } else { // not remove
1606 iter
= g_slist_next(iter
);
1612 /* End of removed servicing loop : leave control to GTK instead. */
1613 // if(gtk_events_pending()) break;
1616 /* B. When interrupted between chunks */
1619 GSList
*iter
= list_in
;
1621 /* 1. for each request in list_in */
1622 while(iter
!= NULL
) {
1624 gboolean remove
= FALSE
;
1625 gboolean free_data
= FALSE
;
1626 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1628 /* 1.1. Use current postition as start position */
1629 if(events_request
->start_position
!= NULL
)
1630 lttv_traceset_context_position_destroy(events_request
->start_position
);
1631 events_request
->start_position
= lttv_traceset_context_position_new(tsc
);
1632 lttv_traceset_context_position_save(tsc
, events_request
->start_position
);
1634 /* 1.2. Remove start time */
1635 events_request
->start_time
= ltt_time_infinite
;
1637 /* 1.3. Move from list_in to list_out */
1640 list_out
= g_slist_append(list_out
, events_request
);
1645 GSList
*remove_iter
= iter
;
1647 iter
= g_slist_next(iter
);
1648 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
1649 list_in
= g_slist_remove_link(list_in
, remove_iter
);
1650 } else { // not remove
1651 iter
= g_slist_next(iter
);
1657 /* C Unlock Traces */
1659 lttv_process_traceset_get_sync_data(tsc
);
1660 //lttv_traceset_context_position_save(tsc, sync_position);
1665 iter_trace
<lttv_traceset_number(tsc
->ts
);
1667 LttvTrace
*trace_v
= lttv_traceset_get(tsc
->ts
, iter_trace
);
1669 lttvwindowtraces_unlock(trace_v
);
1673 //set the cursor back to normal
1674 gdk_window_set_cursor(win
, NULL
);
1677 g_assert(g_slist_length(list_in
) == 0);
1679 if( g_slist_length(list_out
) == 0 ) {
1680 /* Put tab's request pending flag back to normal */
1681 tab
->events_request_pending
= FALSE
;
1682 g_debug("remove the idle fct");
1683 return FALSE
; /* Remove the idle function */
1685 g_debug("leave the idle fct");
1686 return TRUE
; /* Leave the idle function */
1688 /* We do not use simili-round-robin, it may require to read 1 meg buffers
1689 * again and again if many tracesets use the same tracefiles. */
1690 /* Hack for round-robin idle functions */
1691 /* It will put the idle function at the end of the pool */
1692 /*g_idle_add_full((G_PRIORITY_HIGH_IDLE + 21),
1693 (GSourceFunc)execute_events_requests,
1703 static void lttvwindow_add_trace(Tab
*tab
, LttvTrace
*trace_v
)
1705 LttvTraceset
*traceset
= tab
->traceset_info
->traceset
;
1707 guint num_traces
= lttv_traceset_number(traceset
);
1709 //Verify if trace is already present.
1710 for(i
=0; i
<num_traces
; i
++)
1712 LttvTrace
* trace
= lttv_traceset_get(traceset
, i
);
1713 if(trace
== trace_v
)
1717 //Keep a reference to the traces so they are not freed.
1718 for(i
=0; i
<lttv_traceset_number(traceset
); i
++)
1720 LttvTrace
* trace
= lttv_traceset_get(traceset
, i
);
1721 lttv_trace_ref(trace
);
1724 //remove state update hooks
1725 lttv_state_remove_event_hooks(
1726 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1728 lttv_context_fini(LTTV_TRACESET_CONTEXT(
1729 tab
->traceset_info
->traceset_context
));
1730 g_object_unref(tab
->traceset_info
->traceset_context
);
1732 lttv_traceset_add(traceset
, trace_v
);
1733 lttv_trace_ref(trace_v
); /* local ref */
1735 /* Create new context */
1736 tab
->traceset_info
->traceset_context
=
1737 g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
1739 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->
1744 //add state update hooks
1745 lttv_state_add_event_hooks(
1746 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1747 //Remove local reference to the traces.
1748 for(i
=0; i
<lttv_traceset_number(traceset
); i
++)
1750 LttvTrace
* trace
= lttv_traceset_get(traceset
, i
);
1751 lttv_trace_unref(trace
);
1755 //add_trace_into_traceset_selector(GTK_MULTIVPANED(tab->multivpaned), lttv_trace(trace_v));
1758 /* add_trace adds a trace into the current traceset. It first displays a
1759 * directory selection dialogue to let user choose a trace, then recreates
1760 * tracset_context, and redraws all the viewer of the current tab
1763 void add_trace(GtkWidget
* widget
, gpointer user_data
)
1766 LttvTrace
* trace_v
;
1767 LttvTraceset
* traceset
;
1769 char abs_path
[PATH_MAX
];
1771 MainWindow
* mw_data
= get_window_data_struct(widget
);
1772 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
1774 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
1775 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
1776 LttvPluginTab
*ptab
;
1780 ptab
= create_new_tab(widget
, NULL
);
1783 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
1787 //GtkDirSelection * file_selector = (GtkDirSelection *)gtk_dir_selection_new("Select a trace");
1788 GtkFileSelection
* file_selector
= (GtkFileSelection
*)gtk_file_selection_new("Select a trace");
1789 gtk_widget_hide( (file_selector
)->file_list
->parent
) ;
1790 gtk_file_selection_hide_fileop_buttons(file_selector
);
1791 gtk_window_set_transient_for(GTK_WINDOW(file_selector
),
1792 GTK_WINDOW(mw_data
->mwindow
));
1794 if(remember_trace_dir
[0] != '\0')
1795 gtk_file_selection_set_filename(file_selector
, remember_trace_dir
);
1797 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
1799 case GTK_RESPONSE_ACCEPT
:
1800 case GTK_RESPONSE_OK
:
1801 dir
= gtk_file_selection_get_filename (file_selector
);
1802 strncpy(remember_trace_dir
, dir
, PATH_MAX
);
1803 strncat(remember_trace_dir
, "/", PATH_MAX
);
1804 if(!dir
|| strlen(dir
) == 0){
1805 gtk_widget_destroy((GtkWidget
*)file_selector
);
1808 get_absolute_pathname(dir
, abs_path
);
1809 trace_v
= lttvwindowtraces_get_trace_by_name(abs_path
);
1810 if(trace_v
== NULL
) {
1811 trace
= ltt_trace_open(abs_path
);
1813 g_warning("cannot open trace %s", abs_path
);
1815 GtkWidget
*dialogue
=
1816 gtk_message_dialog_new(
1817 GTK_WINDOW(gtk_widget_get_toplevel(widget
)),
1818 GTK_DIALOG_MODAL
|GTK_DIALOG_DESTROY_WITH_PARENT
,
1821 "Cannot open trace : maybe you should enter in the trace "
1822 "directory to select it ?");
1823 gtk_dialog_run(GTK_DIALOG(dialogue
));
1824 gtk_widget_destroy(dialogue
);
1827 trace_v
= lttv_trace_new(trace
);
1828 lttvwindowtraces_add_trace(trace_v
);
1829 lttvwindow_add_trace(tab
, trace_v
);
1832 lttvwindow_add_trace(tab
, trace_v
);
1835 gtk_widget_destroy((GtkWidget
*)file_selector
);
1837 //update current tab
1838 //update_traceset(mw_data);
1840 /* Call the updatetraceset hooks */
1842 traceset
= tab
->traceset_info
->traceset
;
1843 SetTraceset(tab
, traceset
);
1844 // in expose now call_pending_read_hooks(mw_data);
1846 //lttvwindow_report_current_time(mw_data,&(tab->current_time));
1848 case GTK_RESPONSE_REJECT
:
1849 case GTK_RESPONSE_CANCEL
:
1851 gtk_widget_destroy((GtkWidget
*)file_selector
);
1856 /* remove_trace removes a trace from the current traceset if all viewers in
1857 * the current tab are not interested in the trace. It first displays a
1858 * dialogue, which shows all traces in the current traceset, to let user choose
1859 * a trace, then it checks if all viewers unselect the trace, if it is true,
1860 * it will remove the trace, recreate the traceset_contex,
1861 * and redraws all the viewer of the current tab. If there is on trace in the
1862 * current traceset, it will delete all viewers of the current tab
1864 * It destroys the filter tree. FIXME... we should request for an update
1868 void remove_trace(GtkWidget
*widget
, gpointer user_data
)
1871 LttvTrace
* trace_v
;
1872 LttvTraceset
* traceset
;
1873 gint i
, j
, nb_trace
, index
=-1;
1874 char ** name
, *remove_trace_name
;
1875 MainWindow
* mw_data
= get_window_data_struct(widget
);
1876 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
1878 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
1879 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
1885 LttvPluginTab
*ptab
;
1886 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
1890 nb_trace
=lttv_traceset_number(tab
->traceset_info
->traceset
);
1891 name
= g_new(char*,nb_trace
);
1892 for(i
= 0; i
< nb_trace
; i
++){
1893 trace_v
= lttv_traceset_get(tab
->traceset_info
->traceset
, i
);
1894 trace
= lttv_trace(trace_v
);
1895 name
[i
] = g_quark_to_string(ltt_trace_name(trace
));
1898 remove_trace_name
= get_remove_trace(mw_data
, name
, nb_trace
);
1901 if(remove_trace_name
){
1903 /* yuk, cut n paste from old code.. should be better (MD)*/
1904 for(i
= 0; i
<nb_trace
; i
++) {
1905 if(strcmp(remove_trace_name
,name
[i
]) == 0){
1910 traceset
= tab
->traceset_info
->traceset
;
1911 //Keep a reference to the traces so they are not freed.
1912 for(j
=0; j
<lttv_traceset_number(traceset
); j
++)
1914 LttvTrace
* trace
= lttv_traceset_get(traceset
, j
);
1915 lttv_trace_ref(trace
);
1918 //remove state update hooks
1919 lttv_state_remove_event_hooks(
1920 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1921 lttv_context_fini(LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
));
1922 g_object_unref(tab
->traceset_info
->traceset_context
);
1924 trace_v
= lttv_traceset_get(traceset
, index
);
1926 lttv_traceset_remove(traceset
, index
);
1927 lttv_trace_unref(trace_v
); // Remove local reference
1929 if(lttv_trace_get_ref_number(trace_v
) <= 1) {
1930 /* ref 1 : lttvwindowtraces only*/
1931 ltt_trace_close(lttv_trace(trace_v
));
1932 /* lttvwindowtraces_remove_trace takes care of destroying
1933 * the traceset linked with the trace_v and also of destroying
1934 * the trace_v at the same time.
1936 lttvwindowtraces_remove_trace(trace_v
);
1939 tab
->traceset_info
->traceset_context
=
1940 g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
1942 LTTV_TRACESET_CONTEXT(tab
->
1943 traceset_info
->traceset_context
),traceset
);
1944 //add state update hooks
1945 lttv_state_add_event_hooks(
1946 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1948 //Remove local reference to the traces.
1949 for(j
=0; j
<lttv_traceset_number(traceset
); j
++)
1951 LttvTrace
* trace
= lttv_traceset_get(traceset
, j
);
1952 lttv_trace_unref(trace
);
1955 SetTraceset(tab
, (gpointer
)traceset
);
1961 void remove_trace(GtkWidget
* widget
, gpointer user_data
)
1964 LttvTrace
* trace_v
;
1965 LttvTraceset
* traceset
;
1966 gint i
, j
, nb_trace
;
1967 char ** name
, *remove_trace_name
;
1968 MainWindow
* mw_data
= get_window_data_struct(widget
);
1969 LttvTracesetSelector
* s
;
1970 LttvTraceSelector
* t
;
1973 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
1975 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
1976 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
1982 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
1985 nb_trace
=lttv_traceset_number(tab
->traceset_info
->traceset
);
1986 name
= g_new(char*,nb_trace
);
1987 for(i
= 0; i
< nb_trace
; i
++){
1988 trace_v
= lttv_traceset_get(tab
->traceset_info
->traceset
, i
);
1989 trace
= lttv_trace(trace_v
);
1990 name
[i
] = ltt_trace_name(trace
);
1993 remove_trace_name
= get_remove_trace(name
, nb_trace
);
1995 if(remove_trace_name
){
1996 for(i
=0; i
<nb_trace
; i
++){
1997 if(strcmp(remove_trace_name
,name
[i
]) == 0){
1998 //unselect the trace from the current viewer
2000 w
= gtk_multivpaned_get_widget(GTK_MULTIVPANED(tab
->multivpaned
));
2002 s
= g_object_get_data(G_OBJECT(w
), "Traceset_Selector");
2004 t
= lttv_traceset_selector_trace_get(s
,i
);
2005 lttv_trace_selector_set_selected(t
, FALSE
);
2008 //check if other viewers select the trace
2009 w
= gtk_multivpaned_get_first_widget(GTK_MULTIVPANED(tab
->multivpaned
));
2011 s
= g_object_get_data(G_OBJECT(w
), "Traceset_Selector");
2013 t
= lttv_traceset_selector_trace_get(s
,i
);
2014 selected
= lttv_trace_selector_get_selected(t
);
2017 w
= gtk_multivpaned_get_next_widget(GTK_MULTIVPANED(tab
->multivpaned
));
2019 }else selected
= FALSE
;
2021 //if no viewer selects the trace, remove it
2023 remove_trace_from_traceset_selector(GTK_MULTIVPANED(tab
->multivpaned
), i
);
2025 traceset
= tab
->traceset_info
->traceset
;
2026 //Keep a reference to the traces so they are not freed.
2027 for(j
=0; j
<lttv_traceset_number(traceset
); j
++)
2029 LttvTrace
* trace
= lttv_traceset_get(traceset
, j
);
2030 lttv_trace_ref(trace
);
2033 //remove state update hooks
2034 lttv_state_remove_event_hooks(
2035 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
2036 lttv_context_fini(LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
));
2037 g_object_unref(tab
->traceset_info
->traceset_context
);
2040 trace_v
= lttv_traceset_get(traceset
, i
);
2042 if(lttv_trace_get_ref_number(trace_v
) <= 2) {
2043 /* ref 2 : traceset, local */
2044 lttvwindowtraces_remove_trace(trace_v
);
2045 ltt_trace_close(lttv_trace(trace_v
));
2048 lttv_traceset_remove(traceset
, i
);
2049 lttv_trace_unref(trace_v
); // Remove local reference
2051 if(!lttv_trace_get_ref_number(trace_v
))
2052 lttv_trace_destroy(trace_v
);
2054 tab
->traceset_info
->traceset_context
=
2055 g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
2057 LTTV_TRACESET_CONTEXT(tab
->
2058 traceset_info
->traceset_context
),traceset
);
2059 //add state update hooks
2060 lttv_state_add_event_hooks(
2061 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
2063 //Remove local reference to the traces.
2064 for(j
=0; j
<lttv_traceset_number(traceset
); j
++)
2066 LttvTrace
* trace
= lttv_traceset_get(traceset
, j
);
2067 lttv_trace_unref(trace
);
2071 //update current tab
2072 //update_traceset(mw_data);
2075 SetTraceset(tab
, (gpointer
)traceset
);
2076 // in expose now call_pending_read_hooks(mw_data);
2078 //lttvwindow_report_current_time(mw_data,&(tab->current_time));
2081 // while(tab->multi_vpaned->num_children){
2082 // gtk_multi_vpaned_widget_delete(tab->multi_vpaned);
2096 /* Redraw all the viewers in the current tab */
2097 void redraw(GtkWidget
*widget
, gpointer user_data
)
2099 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
2100 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2101 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2106 LttvPluginTab
*ptab
;
2107 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
2112 LttvAttributeValue value
;
2114 g_assert(lttv_iattribute_find_by_path(tab
->attributes
, "hooks/redraw", LTTV_POINTER
, &value
));
2116 tmp
= (LttvHooks
*)*(value
.v_pointer
);
2118 lttv_hooks_call(tmp
,NULL
);
2122 void continue_processing(GtkWidget
*widget
, gpointer user_data
)
2124 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
2125 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2126 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2131 LttvPluginTab
*ptab
;
2132 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
2137 LttvAttributeValue value
;
2139 g_assert(lttv_iattribute_find_by_path(tab
->attributes
,
2140 "hooks/continue", LTTV_POINTER
, &value
));
2142 tmp
= (LttvHooks
*)*(value
.v_pointer
);
2144 lttv_hooks_call(tmp
,NULL
);
2147 /* Stop the processing for the calling main window's current tab.
2148 * It removes every processing requests that are in its list. It does not call
2149 * the end request hooks, because the request is not finished.
2152 void stop_processing(GtkWidget
*widget
, gpointer user_data
)
2154 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
2155 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2156 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2161 LttvPluginTab
*ptab
;
2162 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
2165 GSList
*iter
= tab
->events_requests
;
2167 while(iter
!= NULL
) {
2168 GSList
*remove_iter
= iter
;
2169 iter
= g_slist_next(iter
);
2171 g_free(remove_iter
->data
);
2172 tab
->events_requests
=
2173 g_slist_remove_link(tab
->events_requests
, remove_iter
);
2175 tab
->events_request_pending
= FALSE
;
2176 tab
->stop_foreground
= TRUE
;
2177 g_idle_remove_by_data(tab
);
2178 g_assert(g_slist_length(tab
->events_requests
) == 0);
2182 /* save will save the traceset to a file
2183 * Not implemented yet FIXME
2186 void save(GtkWidget
* widget
, gpointer user_data
)
2191 void save_as(GtkWidget
* widget
, gpointer user_data
)
2193 g_info("Save as\n");
2197 /* zoom will change the time_window of all the viewers of the
2198 * current tab, and redisplay them. The main functionality is to
2199 * determine the new time_window of the current tab
2202 void zoom(GtkWidget
* widget
, double size
)
2204 TimeInterval time_span
;
2205 TimeWindow new_time_window
;
2206 LttTime current_time
, time_delta
;
2207 MainWindow
* mw_data
= get_window_data_struct(widget
);
2208 LttvTracesetContext
*tsc
;
2209 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
2211 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2212 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2218 LttvPluginTab
*ptab
;
2219 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
2223 if(size
== 1) return;
2225 tsc
= LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
2226 time_span
= tsc
->time_span
;
2227 new_time_window
= tab
->time_window
;
2228 current_time
= tab
->current_time
;
2230 time_delta
= ltt_time_sub(time_span
.end_time
,time_span
.start_time
);
2232 new_time_window
.start_time
= time_span
.start_time
;
2233 new_time_window
.time_width
= time_delta
;
2234 new_time_window
.time_width_double
= ltt_time_to_double(time_delta
);
2235 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
2236 new_time_window
.time_width
) ;
2238 new_time_window
.time_width
= ltt_time_div(new_time_window
.time_width
, size
);
2239 new_time_window
.time_width_double
=
2240 ltt_time_to_double(new_time_window
.time_width
);
2241 if(ltt_time_compare(new_time_window
.time_width
,time_delta
) > 0)
2242 { /* Case where zoom out is bigger than trace length */
2243 new_time_window
.start_time
= time_span
.start_time
;
2244 new_time_window
.time_width
= time_delta
;
2245 new_time_window
.time_width_double
= ltt_time_to_double(time_delta
);
2246 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
2247 new_time_window
.time_width
) ;
2251 /* Center the image on the current time */
2252 new_time_window
.start_time
=
2253 ltt_time_sub(current_time
,
2254 ltt_time_from_double(new_time_window
.time_width_double
/2.0));
2255 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
2256 new_time_window
.time_width
) ;
2257 /* If on borders, don't fall off */
2258 if(ltt_time_compare(new_time_window
.start_time
, time_span
.start_time
) <0
2259 || ltt_time_compare(new_time_window
.start_time
, time_span
.end_time
) >0)
2261 new_time_window
.start_time
= time_span
.start_time
;
2262 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
2263 new_time_window
.time_width
) ;
2267 if(ltt_time_compare(new_time_window
.end_time
,
2268 time_span
.end_time
) > 0
2269 || ltt_time_compare(new_time_window
.end_time
,
2270 time_span
.start_time
) < 0)
2272 new_time_window
.start_time
=
2273 ltt_time_sub(time_span
.end_time
, new_time_window
.time_width
);
2275 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
2276 new_time_window
.time_width
) ;
2283 if(ltt_time_compare(new_time_window
.time_width
, ltt_time_zero
) == 0) {
2284 g_warning("Zoom more than 1 ns impossible");
2286 time_change_manager(tab
, new_time_window
);
2290 void zoom_in(GtkWidget
* widget
, gpointer user_data
)
2295 void zoom_out(GtkWidget
* widget
, gpointer user_data
)
2300 void zoom_extended(GtkWidget
* widget
, gpointer user_data
)
2305 void go_to_time(GtkWidget
* widget
, gpointer user_data
)
2307 g_info("Go to time\n");
2310 void show_time_frame(GtkWidget
* widget
, gpointer user_data
)
2312 g_info("Show time frame\n");
2316 /* callback function */
2319 on_empty_traceset_activate (GtkMenuItem
*menuitem
,
2322 create_new_window((GtkWidget
*)menuitem
, user_data
, FALSE
);
2327 on_clone_traceset_activate (GtkMenuItem
*menuitem
,
2330 create_new_window((GtkWidget
*)menuitem
, user_data
, TRUE
);
2334 /* create_new_tab calls create_tab to construct a new tab in the main window
2337 LttvPluginTab
*create_new_tab(GtkWidget
* widget
, gpointer user_data
)
2339 gchar label
[PATH_MAX
];
2340 MainWindow
* mw_data
= get_window_data_struct(widget
);
2342 GtkNotebook
* notebook
= (GtkNotebook
*)lookup_widget(widget
, "MNotebook");
2343 if(notebook
== NULL
){
2344 g_info("Notebook does not exist\n");
2347 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2348 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2354 LttvPluginTab
*ptab
;
2355 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
2356 copy_tab
= ptab
->tab
;
2359 strcpy(label
,"Page");
2360 if(get_label(mw_data
, label
,"Get the name of the tab","Please input tab's name")) {
2361 LttvPluginTab
*ptab
;
2363 ptab
= g_object_new(LTTV_TYPE_PLUGIN_TAB
, NULL
);
2364 init_tab (ptab
->tab
, mw_data
, copy_tab
, notebook
, label
);
2365 ptab
->parent
.top_widget
= ptab
->tab
->top_widget
;
2366 g_object_set_data_full(
2367 G_OBJECT(ptab
->tab
->vbox
),
2370 (GDestroyNotify
)tab_destructor
);
2377 on_tab_activate (GtkMenuItem
*menuitem
,
2380 create_new_tab((GtkWidget
*)menuitem
, user_data
);
2385 on_open_activate (GtkMenuItem
*menuitem
,
2388 open_traceset((GtkWidget
*)menuitem
, user_data
);
2393 on_close_activate (GtkMenuItem
*menuitem
,
2396 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2397 main_window_destructor(mw_data
);
2401 /* remove the current tab from the main window
2405 on_close_tab_activate (GtkWidget
*widget
,
2409 GtkWidget
* notebook
;
2411 MainWindow
* mw_data
= get_window_data_struct(widget
);
2412 notebook
= lookup_widget(widget
, "MNotebook");
2413 if(notebook
== NULL
){
2414 g_info("Notebook does not exist\n");
2418 page_num
= gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
));
2420 gtk_notebook_remove_page(GTK_NOTEBOOK(notebook
), page_num
);
2425 on_close_tab_X_clicked (GtkWidget
*widget
,
2429 GtkWidget
*notebook
= lookup_widget(widget
, "MNotebook");
2430 if(notebook
== NULL
){
2431 g_info("Notebook does not exist\n");
2435 if((page_num
= gtk_notebook_page_num(GTK_NOTEBOOK(notebook
), widget
)) != -1)
2436 gtk_notebook_remove_page(GTK_NOTEBOOK(notebook
), page_num
);
2442 on_add_trace_activate (GtkMenuItem
*menuitem
,
2445 add_trace((GtkWidget
*)menuitem
, user_data
);
2450 on_remove_trace_activate (GtkMenuItem
*menuitem
,
2453 remove_trace((GtkWidget
*)menuitem
, user_data
);
2458 on_save_activate (GtkMenuItem
*menuitem
,
2461 save((GtkWidget
*)menuitem
, user_data
);
2466 on_save_as_activate (GtkMenuItem
*menuitem
,
2469 save_as((GtkWidget
*)menuitem
, user_data
);
2474 on_quit_activate (GtkMenuItem
*menuitem
,
2477 while (g_slist_length(g_main_window_list
) != 0) {
2478 on_MWindow_destroy(((MainWindow
*)g_main_window_list
->data
)->mwindow
,
2485 on_cut_activate (GtkMenuItem
*menuitem
,
2493 on_copy_activate (GtkMenuItem
*menuitem
,
2501 on_paste_activate (GtkMenuItem
*menuitem
,
2509 on_delete_activate (GtkMenuItem
*menuitem
,
2517 on_zoom_in_activate (GtkMenuItem
*menuitem
,
2520 zoom_in((GtkWidget
*)menuitem
, user_data
);
2525 on_zoom_out_activate (GtkMenuItem
*menuitem
,
2528 zoom_out((GtkWidget
*)menuitem
, user_data
);
2533 on_zoom_extended_activate (GtkMenuItem
*menuitem
,
2536 zoom_extended((GtkWidget
*)menuitem
, user_data
);
2541 on_go_to_time_activate (GtkMenuItem
*menuitem
,
2544 go_to_time((GtkWidget
*)menuitem
, user_data
);
2549 on_show_time_frame_activate (GtkMenuItem
*menuitem
,
2552 show_time_frame((GtkWidget
*)menuitem
, user_data
);
2557 on_move_viewer_up_activate (GtkMenuItem
*menuitem
,
2560 move_up_viewer((GtkWidget
*)menuitem
, user_data
);
2565 on_move_viewer_down_activate (GtkMenuItem
*menuitem
,
2568 move_down_viewer((GtkWidget
*)menuitem
, user_data
);
2573 on_remove_viewer_activate (GtkMenuItem
*menuitem
,
2576 delete_viewer((GtkWidget
*)menuitem
, user_data
);
2580 on_trace_facility_activate (GtkMenuItem
*menuitem
,
2583 g_info("Trace facility selector: %s\n", "");
2587 /* Dispaly a file selection dialogue to let user select a library, then call
2588 * lttv_library_load().
2592 on_load_library_activate (GtkMenuItem
*menuitem
,
2595 GError
*error
= NULL
;
2596 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2598 gchar load_module_path_alter
[PATH_MAX
];
2602 gchar
*load_module_path
;
2603 name
= g_ptr_array_new();
2604 nb
= lttv_library_path_number();
2605 /* ask for the library path */
2609 path
= lttv_library_path_get(i
);
2610 g_ptr_array_add(name
, path
);
2613 load_module_path
= get_selection(mw_data
,
2614 (char **)(name
->pdata
), name
->len
,
2615 "Select a library path", "Library paths");
2616 if(load_module_path
!= NULL
)
2617 strncpy(load_module_path_alter
, load_module_path
, PATH_MAX
-1); // -1 for /
2619 g_ptr_array_free(name
, TRUE
);
2621 if(load_module_path
== NULL
) return;
2625 /* Make sure the module path ends with a / */
2626 gchar
*ptr
= load_module_path_alter
;
2628 ptr
= strchr(ptr
, '\0');
2630 if(*(ptr
-1) != '/') {
2637 /* Ask for the library to load : list files in the previously selected
2639 gchar str
[PATH_MAX
];
2642 GtkFileSelection
* file_selector
=
2643 (GtkFileSelection
*)gtk_file_selection_new("Select a module");
2644 gtk_file_selection_set_filename(file_selector
, load_module_path_alter
);
2645 gtk_file_selection_hide_fileop_buttons(file_selector
);
2647 gtk_window_set_transient_for(GTK_WINDOW(file_selector
),
2648 GTK_WINDOW(mw_data
->mwindow
));
2651 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
2653 case GTK_RESPONSE_ACCEPT
:
2654 case GTK_RESPONSE_OK
:
2655 dir
= gtk_file_selection_get_selections (file_selector
);
2656 strncpy(str
,dir
[0],PATH_MAX
);
2657 strncpy(remember_plugins_dir
,dir
[0],PATH_MAX
);
2658 /* only keep file name */
2660 str1
= strrchr(str
,'/');
2663 str1
= strrchr(str
,'\\');
2668 if(*str1
== 'l' && *(str1
+1)== 'i' && *(str1
+2)=='b')
2670 remove info after
. */
2674 str2
= strrchr(str2
, '.');
2675 if(str2
!= NULL
) *str2
= '\0';
2677 lttv_module_require(str1
, &error
);
2679 lttv_library_load(str1
, &error
);
2680 if(error
!= NULL
) g_warning("%s", error
->message
);
2681 else g_info("Load library: %s\n", str
);
2683 case GTK_RESPONSE_REJECT
:
2684 case GTK_RESPONSE_CANCEL
:
2686 gtk_widget_destroy((GtkWidget
*)file_selector
);
2697 /* Display all loaded modules, let user to select a module to unload
2698 * by calling lttv_module_unload
2702 on_unload_library_activate (GtkMenuItem
*menuitem
,
2705 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2707 LttvLibrary
*library
= NULL
;
2712 name
= g_ptr_array_new();
2713 nb
= lttv_library_number();
2714 LttvLibraryInfo
*lib_info
= g_new(LttvLibraryInfo
,nb
);
2715 /* ask for the library name */
2718 LttvLibrary
*iter_lib
= lttv_library_get(i
);
2719 lttv_library_info(iter_lib
, &lib_info
[i
]);
2721 gchar
*path
= lib_info
[i
].name
;
2722 g_ptr_array_add(name
, path
);
2724 lib_name
= get_selection(mw_data
, (char **)(name
->pdata
), name
->len
,
2725 "Select a library", "Libraries");
2726 if(lib_name
!= NULL
) {
2728 if(strcmp(lib_name
, lib_info
[i
].name
) == 0) {
2729 library
= lttv_library_get(i
);
2734 g_ptr_array_free(name
, TRUE
);
2737 if(lib_name
== NULL
) return;
2739 if(library
!= NULL
) lttv_library_unload(library
);
2743 /* Dispaly a file selection dialogue to let user select a module, then call
2744 * lttv_module_require().
2748 on_load_module_activate (GtkMenuItem
*menuitem
,
2751 GError
*error
= NULL
;
2752 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2754 LttvLibrary
*library
= NULL
;
2759 name
= g_ptr_array_new();
2760 nb
= lttv_library_number();
2761 LttvLibraryInfo
*lib_info
= g_new(LttvLibraryInfo
,nb
);
2762 /* ask for the library name */
2765 LttvLibrary
*iter_lib
= lttv_library_get(i
);
2766 lttv_library_info(iter_lib
, &lib_info
[i
]);
2768 gchar
*path
= lib_info
[i
].name
;
2769 g_ptr_array_add(name
, path
);
2771 lib_name
= get_selection(mw_data
,(char **)(name
->pdata
), name
->len
,
2772 "Select a library", "Libraries");
2773 if(lib_name
!= NULL
) {
2775 if(strcmp(lib_name
, lib_info
[i
].name
) == 0) {
2776 library
= lttv_library_get(i
);
2781 g_ptr_array_free(name
, TRUE
);
2784 if(lib_name
== NULL
) return;
2787 //LttvModule *module;
2788 gchar module_name_out
[PATH_MAX
];
2790 /* Ask for the module to load : list modules in the selected lib */
2794 nb
= lttv_library_module_number(library
);
2795 LttvModuleInfo
*module_info
= g_new(LttvModuleInfo
,nb
);
2796 name
= g_ptr_array_new();
2797 /* ask for the module name */
2800 LttvModule
*iter_module
= lttv_library_module_get(library
, i
);
2801 lttv_module_info(iter_module
, &module_info
[i
]);
2803 gchar
*path
= module_info
[i
].name
;
2804 g_ptr_array_add(name
, path
);
2806 module_name
= get_selection(mw_data
, (char **)(name
->pdata
), name
->len
,
2807 "Select a module", "Modules");
2808 if(module_name
!= NULL
) {
2810 if(strcmp(module_name
, module_info
[i
].name
) == 0) {
2811 strncpy(module_name_out
, module_name
, PATH_MAX
);
2812 //module = lttv_library_module_get(i);
2818 g_ptr_array_free(name
, TRUE
);
2819 g_free(module_info
);
2821 if(module_name
== NULL
) return;
2824 lttv_module_require(module_name_out
, &error
);
2825 if(error
!= NULL
) g_warning("%s", error
->message
);
2826 else g_info("Load module: %s", module_name_out
);
2833 gchar str
[PATH_MAX
];
2836 GtkFileSelection
* file_selector
=
2837 (GtkFileSelection
*)gtk_file_selection_new("Select a module");
2838 gtk_file_selection_set_filename(file_selector
, load_module_path_alter
);
2839 gtk_file_selection_hide_fileop_buttons(file_selector
);
2842 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
2844 case GTK_RESPONSE_ACCEPT
:
2845 case GTK_RESPONSE_OK
:
2846 dir
= gtk_file_selection_get_selections (file_selector
);
2847 strncpy(str
,dir
[0],PATH_MAX
);
2848 strncpy(remember_plugins_dir
,dir
[0],PATH_MAX
);
2850 /* only keep file name */
2852 str1
= strrchr(str
,'/');
2855 str1
= strrchr(str
,'\\');
2860 if(*str1
== 'l' && *(str1
+1)== 'i' && *(str1
+2)=='b')
2862 remove info after
. */
2866 str2
= strrchr(str2
, '.');
2867 if(str2
!= NULL
) *str2
= '\0';
2869 lttv_module_require(str1
, &error
);
2871 lttv_library_load(str1
, &error
);
2872 if(error
!= NULL
) g_warning(error
->message
);
2873 else g_info("Load library: %s\n", str
);
2875 case GTK_RESPONSE_REJECT
:
2876 case GTK_RESPONSE_CANCEL
:
2878 gtk_widget_destroy((GtkWidget
*)file_selector
);
2890 /* Display all loaded modules, let user to select a module to unload
2891 * by calling lttv_module_unload
2895 on_unload_module_activate (GtkMenuItem
*menuitem
,
2898 GError
*error
= NULL
;
2899 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2901 LttvLibrary
*library
= NULL
;
2906 name
= g_ptr_array_new();
2907 nb
= lttv_library_number();
2908 LttvLibraryInfo
*lib_info
= g_new(LttvLibraryInfo
,nb
);
2909 /* ask for the library name */
2912 LttvLibrary
*iter_lib
= lttv_library_get(i
);
2913 lttv_library_info(iter_lib
, &lib_info
[i
]);
2915 gchar
*path
= lib_info
[i
].name
;
2916 g_ptr_array_add(name
, path
);
2918 lib_name
= get_selection(mw_data
, (char **)(name
->pdata
), name
->len
,
2919 "Select a library", "Libraries");
2920 if(lib_name
!= NULL
) {
2922 if(strcmp(lib_name
, lib_info
[i
].name
) == 0) {
2923 library
= lttv_library_get(i
);
2928 g_ptr_array_free(name
, TRUE
);
2931 if(lib_name
== NULL
) return;
2934 LttvModule
*module
= NULL
;
2936 /* Ask for the module to load : list modules in the selected lib */
2940 nb
= lttv_library_module_number(library
);
2941 LttvModuleInfo
*module_info
= g_new(LttvModuleInfo
,nb
);
2942 name
= g_ptr_array_new();
2943 /* ask for the module name */
2946 LttvModule
*iter_module
= lttv_library_module_get(library
, i
);
2947 lttv_module_info(iter_module
, &module_info
[i
]);
2949 gchar
*path
= module_info
[i
].name
;
2950 if(module_info
[i
].use_count
> 0) g_ptr_array_add(name
, path
);
2952 module_name
= get_selection(mw_data
, (char **)(name
->pdata
), name
->len
,
2953 "Select a module", "Modules");
2954 if(module_name
!= NULL
) {
2956 if(strcmp(module_name
, module_info
[i
].name
) == 0) {
2957 module
= lttv_library_module_get(library
, i
);
2963 g_ptr_array_free(name
, TRUE
);
2964 g_free(module_info
);
2966 if(module_name
== NULL
) return;
2969 LttvModuleInfo module_info
;
2970 lttv_module_info(module
, &module_info
);
2971 g_info("Release module: %s\n", module_info
.name
);
2973 lttv_module_release(module
);
2977 /* Display a directory dialogue to let user select a path for library searching
2981 on_add_library_search_path_activate (GtkMenuItem
*menuitem
,
2984 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2985 //GtkDirSelection * file_selector = (GtkDirSelection *)gtk_dir_selection_new("Select library path");
2986 GtkFileSelection
* file_selector
= (GtkFileSelection
*)gtk_file_selection_new("Select a trace");
2987 gtk_widget_hide( (file_selector
)->file_list
->parent
) ;
2989 gtk_window_set_transient_for(GTK_WINDOW(file_selector
),
2990 GTK_WINDOW(mw_data
->mwindow
));
2995 if(remember_plugins_dir
[0] != '\0')
2996 gtk_file_selection_set_filename(file_selector
, remember_plugins_dir
);
2998 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
3000 case GTK_RESPONSE_ACCEPT
:
3001 case GTK_RESPONSE_OK
:
3002 dir
= gtk_file_selection_get_filename (file_selector
);
3003 strncpy(remember_plugins_dir
,dir
,PATH_MAX
);
3004 strncat(remember_plugins_dir
,"/",PATH_MAX
);
3005 lttv_library_path_add(dir
);
3006 case GTK_RESPONSE_REJECT
:
3007 case GTK_RESPONSE_CANCEL
:
3009 gtk_widget_destroy((GtkWidget
*)file_selector
);
3015 /* Display a directory dialogue to let user select a path for library searching
3019 on_remove_library_search_path_activate (GtkMenuItem
*menuitem
,
3022 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
3024 const char *lib_path
;
3029 name
= g_ptr_array_new();
3030 nb
= lttv_library_path_number();
3031 /* ask for the library name */
3034 gchar
*path
= lttv_library_path_get(i
);
3035 g_ptr_array_add(name
, path
);
3037 lib_path
= get_selection(mw_data
, (char **)(name
->pdata
), name
->len
,
3038 "Select a library path", "Library paths");
3040 g_ptr_array_free(name
, TRUE
);
3042 if(lib_path
== NULL
) return;
3045 lttv_library_path_remove(lib_path
);
3049 on_color_activate (GtkMenuItem
*menuitem
,
3057 on_save_configuration_activate (GtkMenuItem
*menuitem
,
3060 g_info("Save configuration\n");
3065 on_content_activate (GtkMenuItem
*menuitem
,
3068 g_info("Content\n");
3073 on_about_close_activate (GtkButton
*button
,
3076 GtkWidget
*about_widget
= GTK_WIDGET(user_data
);
3078 gtk_widget_destroy(about_widget
);
3082 on_about_activate (GtkMenuItem
*menuitem
,
3085 MainWindow
*main_window
= get_window_data_struct(GTK_WIDGET(menuitem
));
3086 GtkWidget
*window_widget
= main_window
->mwindow
;
3087 GtkWidget
*about_widget
= gtk_window_new(GTK_WINDOW_TOPLEVEL
);
3088 GtkWindow
*about_window
= GTK_WINDOW(about_widget
);
3089 gint window_width
, window_height
;
3091 gtk_window_set_title(about_window
, "About Linux Trace Toolkit");
3093 gtk_window_set_resizable(about_window
, FALSE
);
3094 gtk_window_set_transient_for(about_window
, GTK_WINDOW(window_widget
));
3095 gtk_window_set_destroy_with_parent(about_window
, TRUE
);
3096 gtk_window_set_modal(about_window
, FALSE
);
3098 /* Put the about window at the center of the screen */
3099 gtk_window_get_size(about_window
, &window_width
, &window_height
);
3100 gtk_window_move (about_window
,
3101 (gdk_screen_width() - window_width
)/2,
3102 (gdk_screen_height() - window_height
)/2);
3104 GtkWidget
*vbox
= gtk_vbox_new(FALSE
, 1);
3106 gtk_container_add(GTK_CONTAINER(about_widget
), vbox
);
3110 GtkWidget
*label1
= gtk_label_new("");
3111 gtk_misc_set_padding(GTK_MISC(label1
), 10, 20);
3112 gtk_label_set_markup(GTK_LABEL(label1
), "\
3113 <big>Linux Trace Toolkit " VERSION
"</big>");
3114 gtk_label_set_justify(GTK_LABEL(label1
), GTK_JUSTIFY_CENTER
);
3116 GtkWidget
*label2
= gtk_label_new("");
3117 gtk_misc_set_padding(GTK_MISC(label2
), 10, 20);
3118 gtk_label_set_markup(GTK_LABEL(label2
), "\
3121 Michel Dagenais (New trace format, lttv main)\n\
3122 Mathieu Desnoyers (Kernel Tracer, Directory structure, build with automake/conf,\n\
3123 lttv gui, control flow view, gui cooperative trace reading\n\
3124 scheduler with interruptible foreground and background\n\
3125 computation, detailed event list (rewrite), trace reading\n\
3126 library (rewrite))\n\
3127 Benoit Des Ligneris, Eric Clement (Cluster adaptation, work in progress)\n\
3128 Xang-Xiu Yang (new trace reading library and converter, lttv gui, \n\
3129 detailed event list and statistics view)\n\
3130 Tom Zanussi (RelayFS)\n\
3132 Inspired from the original Linux Trace Toolkit Visualizer made by\n\
3135 GtkWidget
*label3
= gtk_label_new("");
3136 gtk_label_set_markup(GTK_LABEL(label3
), "\
3137 Linux Trace Toolkit Viewer, Copyright (C) 2004, 2005, 2006\n\
3139 Mathieu Desnoyers\n\
3141 Linux Trace Toolkit comes with ABSOLUTELY NO WARRANTY.\n\
3142 This is free software, and you are welcome to redistribute it\n\
3143 under certain conditions. See COPYING for details.");
3144 gtk_misc_set_padding(GTK_MISC(label3
), 10, 20);
3146 gtk_box_pack_start_defaults(GTK_BOX(vbox
), label1
);
3147 gtk_box_pack_start_defaults(GTK_BOX(vbox
), label2
);
3148 gtk_box_pack_start_defaults(GTK_BOX(vbox
), label3
);
3150 GtkWidget
*hbox
= gtk_hbox_new(TRUE
, 0);
3151 gtk_box_pack_end(GTK_BOX(vbox
), hbox
, FALSE
, FALSE
, 0);
3152 GtkWidget
*close_button
= gtk_button_new_with_mnemonic("_Close");
3153 gtk_box_pack_end(GTK_BOX(hbox
), close_button
, FALSE
, FALSE
, 0);
3154 gtk_container_set_border_width(GTK_CONTAINER(close_button
), 20);
3156 g_signal_connect(G_OBJECT(close_button
), "clicked",
3157 G_CALLBACK(on_about_close_activate
),
3158 (gpointer
)about_widget
);
3160 gtk_widget_show_all(about_widget
);
3165 on_button_new_clicked (GtkButton
*button
,
3168 create_new_window((GtkWidget
*)button
, user_data
, TRUE
);
3172 on_button_new_tab_clicked (GtkButton
*button
,
3175 create_new_tab((GtkWidget
*)button
, user_data
);
3179 on_button_open_clicked (GtkButton
*button
,
3182 open_traceset((GtkWidget
*)button
, user_data
);
3187 on_button_add_trace_clicked (GtkButton
*button
,
3190 add_trace((GtkWidget
*)button
, user_data
);
3195 on_button_remove_trace_clicked (GtkButton
*button
,
3198 remove_trace((GtkWidget
*)button
, user_data
);
3202 on_button_redraw_clicked (GtkButton
*button
,
3205 redraw((GtkWidget
*)button
, user_data
);
3209 on_button_continue_processing_clicked (GtkButton
*button
,
3212 continue_processing((GtkWidget
*)button
, user_data
);
3216 on_button_stop_processing_clicked (GtkButton
*button
,
3219 stop_processing((GtkWidget
*)button
, user_data
);
3225 on_button_save_clicked (GtkButton
*button
,
3228 save((GtkWidget
*)button
, user_data
);
3233 on_button_save_as_clicked (GtkButton
*button
,
3236 save_as((GtkWidget
*)button
, user_data
);
3241 on_button_zoom_in_clicked (GtkButton
*button
,
3244 zoom_in((GtkWidget
*)button
, user_data
);
3249 on_button_zoom_out_clicked (GtkButton
*button
,
3252 zoom_out((GtkWidget
*)button
, user_data
);
3257 on_button_zoom_extended_clicked (GtkButton
*button
,
3260 zoom_extended((GtkWidget
*)button
, user_data
);
3265 on_button_go_to_time_clicked (GtkButton
*button
,
3268 go_to_time((GtkWidget
*)button
, user_data
);
3273 on_button_show_time_frame_clicked (GtkButton
*button
,
3276 show_time_frame((GtkWidget
*)button
, user_data
);
3281 on_button_move_up_clicked (GtkButton
*button
,
3284 move_up_viewer((GtkWidget
*)button
, user_data
);
3289 on_button_move_down_clicked (GtkButton
*button
,
3292 move_down_viewer((GtkWidget
*)button
, user_data
);
3297 on_button_delete_viewer_clicked (GtkButton
*button
,
3300 delete_viewer((GtkWidget
*)button
, user_data
);
3304 on_MWindow_destroy (GtkWidget
*widget
,
3307 MainWindow
*main_window
= get_window_data_struct(widget
);
3308 LttvIAttribute
*attributes
= main_window
->attributes
;
3309 LttvAttributeValue value
;
3311 //This is unnecessary, since widgets will be destroyed
3312 //by the main window widget anyway.
3313 //remove_all_menu_toolbar_constructors(main_window, NULL);
3315 g_assert(lttv_iattribute_find_by_path(attributes
,
3316 "viewers/menu", LTTV_POINTER
, &value
));
3317 lttv_menus_destroy((LttvMenus
*)*(value
.v_pointer
));
3319 g_assert(lttv_iattribute_find_by_path(attributes
,
3320 "viewers/toolbar", LTTV_POINTER
, &value
));
3321 lttv_toolbars_destroy((LttvToolbars
*)*(value
.v_pointer
));
3323 g_object_unref(main_window
->attributes
);
3324 g_main_window_list
= g_slist_remove(g_main_window_list
, main_window
);
3326 g_info("There are now : %d windows\n",g_slist_length(g_main_window_list
));
3327 if(g_slist_length(g_main_window_list
) == 0)
3332 on_MWindow_configure (GtkWidget
*widget
,
3333 GdkEventConfigure
*event
,
3336 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)widget
);
3338 // MD : removed time width modification upon resizing of the main window.
3339 // The viewers will redraw themselves completely, without time interval
3342 if(mw_data->window_width){
3343 time_span = LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context)->Time_Span ;
3344 time_win = tab->time_window;
3345 ratio = width / mw_data->window_width;
3346 tab->time_window.time_width = ltt_time_mul(time_win.time_width,ratio);
3347 time = ltt_time_sub(time_span->endTime, time_win.start_time);
3348 if(ltt_time_compare(time, tab->time_window.time_width) < 0){
3349 tab->time_window.time_width = time;
3355 mw_data->window_width = (int)width;
3364 on_MNotebook_switch_page (GtkNotebook
*notebook
,
3365 GtkNotebookPage
*page
,
3373 void time_change_manager (Tab
*tab
,
3374 TimeWindow new_time_window
)
3376 /* Only one source of time change */
3377 if(tab
->time_manager_lock
== TRUE
) return;
3379 tab
->time_manager_lock
= TRUE
;
3381 LttvTracesetContext
*tsc
= LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3382 TimeInterval time_span
= tsc
->time_span
;
3383 LttTime start_time
= new_time_window
.start_time
;
3384 LttTime end_time
= new_time_window
.end_time
;
3385 LttTime time_width
= new_time_window
.time_width
;
3387 g_assert(ltt_time_compare(start_time
, end_time
) < 0);
3390 GtkAdjustment
*adjustment
= gtk_range_get_adjustment(GTK_RANGE(tab
->scrollbar
));
3391 LttTime upper
= ltt_time_sub(time_span
.end_time
, time_span
.start_time
);
3393 gtk_range_set_increments(GTK_RANGE(tab
->scrollbar
),
3394 ltt_time_to_double(new_time_window
.time_width
)
3395 / SCROLL_STEP_PER_PAGE
3396 * NANOSECONDS_PER_SECOND
, /* step increment */
3397 ltt_time_to_double(new_time_window
.time_width
)
3398 * NANOSECONDS_PER_SECOND
); /* page increment */
3399 gtk_range_set_range(GTK_RANGE(tab
->scrollbar
),
3401 ltt_time_to_double(upper
)
3402 * NANOSECONDS_PER_SECOND
); /* upper */
3404 g_object_set(G_OBJECT(adjustment
),
3408 ltt_time_to_double(upper
), /* upper */
3410 new_time_window
.time_width_double
3411 / SCROLL_STEP_PER_PAGE
, /* step increment */
3413 new_time_window
.time_width_double
,
3414 /* page increment */
3416 new_time_window
.time_width_double
, /* page size */
3418 gtk_adjustment_changed(adjustment
);
3420 // g_object_set(G_OBJECT(adjustment),
3422 // ltt_time_to_double(
3423 // ltt_time_sub(start_time, time_span.start_time))
3426 //gtk_adjustment_value_changed(adjustment);
3427 gtk_range_set_value(GTK_RANGE(tab
->scrollbar
),
3429 ltt_time_sub(start_time
, time_span
.start_time
)) /* value */);
3431 /* set the time bar. */
3433 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry1
),
3434 (double)time_span
.start_time
.tv_sec
,
3435 (double)time_span
.end_time
.tv_sec
);
3436 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry1
),
3437 (double)start_time
.tv_sec
);
3439 /* start nanoseconds */
3440 if(start_time
.tv_sec
== time_span
.start_time
.tv_sec
) {
3441 /* can be both beginning and end at the same time. */
3442 if(start_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3443 /* If we are at the end, max nsec to end.. -1 (not zero length) */
3444 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry2
),
3445 (double)time_span
.start_time
.tv_nsec
,
3446 (double)time_span
.end_time
.tv_nsec
-1);
3448 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry2
),
3449 (double)time_span
.start_time
.tv_nsec
,
3450 (double)NANOSECONDS_PER_SECOND
-1);
3452 } else if(start_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3453 /* If we are at the end, max nsec to end.. -1 (not zero length) */
3454 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry2
),
3456 (double)time_span
.end_time
.tv_nsec
-1);
3457 } else /* anywhere else */
3458 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry2
),
3460 (double)NANOSECONDS_PER_SECOND
-1);
3461 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry2
),
3462 (double)start_time
.tv_nsec
);
3465 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry3
),
3466 (double)time_span
.start_time
.tv_sec
,
3467 (double)time_span
.end_time
.tv_sec
);
3468 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry3
),
3469 (double)end_time
.tv_sec
);
3471 /* end nanoseconds */
3472 if(end_time
.tv_sec
== time_span
.start_time
.tv_sec
) {
3473 /* can be both beginning and end at the same time. */
3474 if(end_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3475 /* If we are at the end, max nsec to end.. */
3476 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry4
),
3477 (double)time_span
.start_time
.tv_nsec
+1,
3478 (double)time_span
.end_time
.tv_nsec
);
3480 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry4
),
3481 (double)time_span
.start_time
.tv_nsec
+1,
3482 (double)NANOSECONDS_PER_SECOND
-1);
3485 else if(end_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3486 /* If we are at the end, max nsec to end.. */
3487 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry4
),
3489 (double)time_span
.end_time
.tv_nsec
);
3491 else /* anywhere else */
3492 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry4
),
3494 (double)NANOSECONDS_PER_SECOND
-1);
3495 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry4
),
3496 (double)end_time
.tv_nsec
);
3499 if(time_width
.tv_nsec
== 0) {
3500 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry7
),
3502 (double)upper
.tv_sec
);
3504 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry7
),
3506 (double)upper
.tv_sec
);
3508 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry7
),
3509 (double)time_width
.tv_sec
);
3511 /* width nanoseconds */
3512 if(time_width
.tv_sec
== upper
.tv_sec
) {
3513 if(time_width
.tv_sec
== 0) {
3514 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry8
),
3516 (double)upper
.tv_nsec
);
3518 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry8
),
3520 (double)upper
.tv_nsec
);
3523 else if(time_width
.tv_sec
== 0) {
3524 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry8
),
3526 (double)upper
.tv_nsec
);
3528 else /* anywhere else */
3529 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry8
),
3531 (double)NANOSECONDS_PER_SECOND
-1);
3532 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry8
),
3533 (double)time_width
.tv_nsec
);
3535 /* call viewer hooks for new time window */
3536 set_time_window(tab
, &new_time_window
);
3538 tab
->time_manager_lock
= FALSE
;
3542 /* value changed for frame start s
3544 * Check time span : if ns is out of range, clip it the nearest good value.
3547 on_MEntry1_value_changed (GtkSpinButton
*spinbutton
,
3550 Tab
*tab
=(Tab
*)user_data
;
3551 LttvTracesetContext
* tsc
=
3552 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3553 TimeInterval time_span
= tsc
->time_span
;
3554 gint value
= gtk_spin_button_get_value_as_int(spinbutton
);
3556 TimeWindow new_time_window
= tab
->time_window
;
3558 LttTime end_time
= new_time_window
.end_time
;
3560 new_time_window
.start_time
.tv_sec
= value
;
3562 /* start nanoseconds */
3563 if(new_time_window
.start_time
.tv_sec
== time_span
.start_time
.tv_sec
) {
3564 if(new_time_window
.start_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3565 if(new_time_window
.start_time
.tv_nsec
> time_span
.end_time
.tv_nsec
)
3566 new_time_window
.start_time
.tv_nsec
= time_span
.end_time
.tv_nsec
-1;
3567 if(new_time_window
.start_time
.tv_nsec
< time_span
.start_time
.tv_nsec
)
3568 new_time_window
.start_time
.tv_nsec
= time_span
.start_time
.tv_nsec
;
3570 if(new_time_window
.start_time
.tv_nsec
< time_span
.start_time
.tv_nsec
)
3571 new_time_window
.start_time
.tv_nsec
= time_span
.start_time
.tv_nsec
;
3574 else if(new_time_window
.start_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3575 if(new_time_window
.start_time
.tv_nsec
> time_span
.end_time
.tv_nsec
)
3576 new_time_window
.start_time
.tv_nsec
= time_span
.end_time
.tv_nsec
-1;
3579 if(ltt_time_compare(new_time_window
.start_time
, end_time
) >= 0) {
3580 /* Then, we must push back end time : keep the same time width
3581 * if possible, else end traceset time */
3582 end_time
= LTT_TIME_MIN(ltt_time_add(new_time_window
.start_time
,
3583 new_time_window
.time_width
),
3584 time_span
.end_time
);
3587 /* Fix the time width to fit start time and end time */
3588 new_time_window
.time_width
= ltt_time_sub(end_time
,
3589 new_time_window
.start_time
);
3590 new_time_window
.time_width_double
=
3591 ltt_time_to_double(new_time_window
.time_width
);
3593 new_time_window
.end_time
= end_time
;
3595 time_change_manager(tab
, new_time_window
);
3600 on_MEntry2_value_changed (GtkSpinButton
*spinbutton
,
3603 Tab
*tab
=(Tab
*)user_data
;
3604 LttvTracesetContext
* tsc
=
3605 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3606 TimeInterval time_span
= tsc
->time_span
;
3607 gint value
= gtk_spin_button_get_value_as_int(spinbutton
);
3609 TimeWindow new_time_window
= tab
->time_window
;
3611 LttTime end_time
= new_time_window
.end_time
;
3613 new_time_window
.start_time
.tv_nsec
= value
;
3615 if(ltt_time_compare(new_time_window
.start_time
, end_time
) >= 0) {
3616 /* Then, we must push back end time : keep the same time width
3617 * if possible, else end traceset time */
3618 end_time
= LTT_TIME_MIN(ltt_time_add(new_time_window
.start_time
,
3619 new_time_window
.time_width
),
3620 time_span
.end_time
);
3623 /* Fix the time width to fit start time and end time */
3624 new_time_window
.time_width
= ltt_time_sub(end_time
,
3625 new_time_window
.start_time
);
3626 new_time_window
.time_width_double
=
3627 ltt_time_to_double(new_time_window
.time_width
);
3629 new_time_window
.end_time
= end_time
;
3631 time_change_manager(tab
, new_time_window
);
3636 on_MEntry3_value_changed (GtkSpinButton
*spinbutton
,
3639 Tab
*tab
=(Tab
*)user_data
;
3640 LttvTracesetContext
* tsc
=
3641 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3642 TimeInterval time_span
= tsc
->time_span
;
3643 gint value
= gtk_spin_button_get_value_as_int(spinbutton
);
3645 TimeWindow new_time_window
= tab
->time_window
;
3647 LttTime end_time
= new_time_window
.end_time
;
3649 end_time
.tv_sec
= value
;
3651 /* end nanoseconds */
3652 if(end_time
.tv_sec
== time_span
.start_time
.tv_sec
) {
3653 if(end_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3654 if(end_time
.tv_nsec
> time_span
.end_time
.tv_nsec
)
3655 end_time
.tv_nsec
= time_span
.end_time
.tv_nsec
;
3656 if(end_time
.tv_nsec
< time_span
.start_time
.tv_nsec
)
3657 end_time
.tv_nsec
= time_span
.start_time
.tv_nsec
+1;
3659 if(end_time
.tv_nsec
< time_span
.start_time
.tv_nsec
)
3660 end_time
.tv_nsec
= time_span
.start_time
.tv_nsec
+1;
3663 else if(end_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3664 if(end_time
.tv_nsec
> time_span
.end_time
.tv_nsec
)
3665 end_time
.tv_nsec
= time_span
.end_time
.tv_nsec
;
3668 if(ltt_time_compare(new_time_window
.start_time
, end_time
) >= 0) {
3669 /* Then, we must push front start time : keep the same time width
3670 * if possible, else end traceset time */
3671 new_time_window
.start_time
= LTT_TIME_MAX(
3672 ltt_time_sub(end_time
,
3673 new_time_window
.time_width
),
3674 time_span
.start_time
);
3677 /* Fix the time width to fit start time and end time */
3678 new_time_window
.time_width
= ltt_time_sub(end_time
,
3679 new_time_window
.start_time
);
3680 new_time_window
.time_width_double
=
3681 ltt_time_to_double(new_time_window
.time_width
);
3683 new_time_window
.end_time
= end_time
;
3685 time_change_manager(tab
, new_time_window
);
3690 on_MEntry4_value_changed (GtkSpinButton
*spinbutton
,
3693 Tab
*tab
=(Tab
*)user_data
;
3694 LttvTracesetContext
* tsc
=
3695 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3696 TimeInterval time_span
= tsc
->time_span
;
3697 gint value
= gtk_spin_button_get_value_as_int(spinbutton
);
3699 TimeWindow new_time_window
= tab
->time_window
;
3701 LttTime end_time
= new_time_window
.end_time
;
3703 end_time
.tv_nsec
= value
;
3705 if(ltt_time_compare(new_time_window
.start_time
, end_time
) >= 0) {
3706 /* Then, we must push front start time : keep the same time width
3707 * if possible, else end traceset time */
3708 new_time_window
.start_time
= LTT_TIME_MAX(
3709 ltt_time_sub(end_time
,
3710 new_time_window
.time_width
),
3711 time_span
.start_time
);
3714 /* Fix the time width to fit start time and end time */
3715 new_time_window
.time_width
= ltt_time_sub(end_time
,
3716 new_time_window
.start_time
);
3717 new_time_window
.time_width_double
=
3718 ltt_time_to_double(new_time_window
.time_width
);
3719 new_time_window
.end_time
= end_time
;
3721 time_change_manager(tab
, new_time_window
);
3725 /* value changed for time frame interval s
3727 * Check time span : if ns is out of range, clip it the nearest good value.
3730 on_MEntry7_value_changed (GtkSpinButton
*spinbutton
,
3733 Tab
*tab
=(Tab
*)user_data
;
3734 LttvTracesetContext
* tsc
=
3735 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3736 TimeInterval time_span
= tsc
->time_span
;
3737 gint value
= gtk_spin_button_get_value_as_int(spinbutton
);
3738 LttTime current_time
, time_delta
;
3739 TimeWindow new_time_window
= tab
->time_window
;
3740 current_time
= tab
->current_time
;
3742 time_delta
= ltt_time_sub(time_span
.end_time
,time_span
.start_time
);
3743 new_time_window
.time_width
.tv_sec
= value
;
3744 new_time_window
.time_width_double
=
3745 ltt_time_to_double(new_time_window
.time_width
);
3746 if(ltt_time_compare(new_time_window
.time_width
,time_delta
) > 0)
3747 { /* Case where zoom out is bigger than trace length */
3748 new_time_window
.start_time
= time_span
.start_time
;
3749 new_time_window
.time_width
= time_delta
;
3750 new_time_window
.time_width_double
= ltt_time_to_double(time_delta
);
3751 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
3752 new_time_window
.time_width
) ;
3756 /* Center the image on the current time */
3757 new_time_window
.start_time
=
3758 ltt_time_sub(current_time
,
3759 ltt_time_from_double(new_time_window
.time_width_double
/2.0));
3760 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
3761 new_time_window
.time_width
) ;
3762 /* If on borders, don't fall off */
3763 if(ltt_time_compare(new_time_window
.start_time
, time_span
.start_time
) <0
3764 || ltt_time_compare(new_time_window
.start_time
, time_span
.end_time
) >0)
3766 new_time_window
.start_time
= time_span
.start_time
;
3767 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
3768 new_time_window
.time_width
) ;
3772 if(ltt_time_compare(new_time_window
.end_time
,
3773 time_span
.end_time
) > 0
3774 || ltt_time_compare(new_time_window
.end_time
,
3775 time_span
.start_time
) < 0)
3777 new_time_window
.start_time
=
3778 ltt_time_sub(time_span
.end_time
, new_time_window
.time_width
);
3780 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
3781 new_time_window
.time_width
) ;
3787 if(ltt_time_compare(new_time_window
.time_width
, ltt_time_zero
) == 0) {
3788 g_warning("Zoom more than 1 ns impossible");
3790 time_change_manager(tab
, new_time_window
);
3795 on_MEntry8_value_changed (GtkSpinButton
*spinbutton
,
3798 Tab
*tab
=(Tab
*)user_data
;
3799 LttvTracesetContext
* tsc
=
3800 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3801 TimeInterval time_span
= tsc
->time_span
;
3802 gint value
= gtk_spin_button_get_value_as_int(spinbutton
);
3803 LttTime current_time
, time_delta
;
3804 TimeWindow new_time_window
= tab
->time_window
;
3805 current_time
= tab
->current_time
;
3807 time_delta
= ltt_time_sub(time_span
.end_time
,time_span
.start_time
);
3808 new_time_window
.time_width
.tv_nsec
= value
;
3809 new_time_window
.time_width_double
=
3810 ltt_time_to_double(new_time_window
.time_width
);
3811 if(ltt_time_compare(new_time_window
.time_width
,time_delta
) > 0)
3812 { /* Case where zoom out is bigger than trace length */
3813 new_time_window
.start_time
= time_span
.start_time
;
3814 new_time_window
.time_width
= time_delta
;
3815 new_time_window
.time_width_double
= ltt_time_to_double(time_delta
);
3816 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
3817 new_time_window
.time_width
) ;
3821 /* Center the image on the current time */
3822 new_time_window
.start_time
=
3823 ltt_time_sub(current_time
,
3824 ltt_time_from_double(new_time_window
.time_width_double
/2.0));
3825 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
3826 new_time_window
.time_width
) ;
3827 /* If on borders, don't fall off */
3828 if(ltt_time_compare(new_time_window
.start_time
, time_span
.start_time
) <0
3829 || ltt_time_compare(new_time_window
.start_time
, time_span
.end_time
) >0)
3831 new_time_window
.start_time
= time_span
.start_time
;
3832 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
3833 new_time_window
.time_width
) ;
3837 if(ltt_time_compare(new_time_window
.end_time
,
3838 time_span
.end_time
) > 0
3839 || ltt_time_compare(new_time_window
.end_time
,
3840 time_span
.start_time
) < 0)
3842 new_time_window
.start_time
=
3843 ltt_time_sub(time_span
.end_time
, new_time_window
.time_width
);
3845 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
3846 new_time_window
.time_width
) ;
3852 if(ltt_time_compare(new_time_window
.time_width
, ltt_time_zero
) == 0) {
3853 g_warning("Zoom more than 1 ns impossible");
3855 time_change_manager(tab
, new_time_window
);
3861 void current_time_change_manager (Tab
*tab
,
3862 LttTime new_current_time
)
3864 /* Only one source of time change */
3865 if(tab
->current_time_manager_lock
== TRUE
) return;
3867 tab
->current_time_manager_lock
= TRUE
;
3869 LttvTracesetContext
*tsc
= LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3870 TimeInterval time_span
= tsc
->time_span
;
3872 /* current seconds */
3873 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry5
),
3874 (double)time_span
.start_time
.tv_sec
,
3875 (double)time_span
.end_time
.tv_sec
);
3876 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry5
),
3877 (double)new_current_time
.tv_sec
);
3880 /* start nanoseconds */
3881 if(new_current_time
.tv_sec
== time_span
.start_time
.tv_sec
) {
3882 /* can be both beginning and end at the same time. */
3883 if(new_current_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3884 /* If we are at the end, max nsec to end.. */
3885 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry6
),
3886 (double)time_span
.start_time
.tv_nsec
,
3887 (double)time_span
.end_time
.tv_nsec
);
3889 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry6
),
3890 (double)time_span
.start_time
.tv_nsec
,
3891 (double)NANOSECONDS_PER_SECOND
-1);
3893 } else if(new_current_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3894 /* If we are at the end, max nsec to end.. */
3895 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry6
),
3897 (double)time_span
.end_time
.tv_nsec
);
3898 } else /* anywhere else */
3899 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry6
),
3901 (double)NANOSECONDS_PER_SECOND
-1);
3903 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry6
),
3904 (double)new_current_time
.tv_nsec
);
3906 set_current_time(tab
, &new_current_time
);
3908 tab
->current_time_manager_lock
= FALSE
;
3911 void current_position_change_manager(Tab
*tab
,
3912 LttvTracesetContextPosition
*pos
)
3914 LttvTracesetContext
*tsc
=
3915 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3916 TimeInterval time_span
= tsc
->time_span
;
3918 g_assert(lttv_process_traceset_seek_position(tsc
, pos
) == 0);
3919 LttTime new_time
= lttv_traceset_context_position_get_time(pos
);
3920 /* Put the context in a state coherent position */
3921 lttv_state_traceset_seek_time_closest((LttvTracesetState
*)tsc
, ltt_time_zero
);
3923 current_time_change_manager(tab
, new_time
);
3925 set_current_position(tab
, pos
);
3930 on_MEntry5_value_changed (GtkSpinButton
*spinbutton
,
3933 Tab
*tab
= (Tab
*)user_data
;
3934 LttvTracesetContext
* tsc
=
3935 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3936 TimeInterval time_span
= tsc
->time_span
;
3937 gint value
= gtk_spin_button_get_value_as_int(spinbutton
);
3938 LttTime new_current_time
= tab
->current_time
;
3939 new_current_time
.tv_sec
= value
;
3941 /* current nanoseconds */
3942 if(new_current_time
.tv_sec
== time_span
.start_time
.tv_sec
) {
3943 if(new_current_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3944 if(new_current_time
.tv_nsec
> time_span
.end_time
.tv_nsec
)
3945 new_current_time
.tv_nsec
= time_span
.end_time
.tv_nsec
;
3946 if(new_current_time
.tv_nsec
< time_span
.start_time
.tv_nsec
)
3947 new_current_time
.tv_nsec
= time_span
.start_time
.tv_nsec
;
3949 if(new_current_time
.tv_nsec
< time_span
.start_time
.tv_nsec
)
3950 new_current_time
.tv_nsec
= time_span
.start_time
.tv_nsec
;
3953 else if(new_current_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3954 if(new_current_time
.tv_nsec
> time_span
.end_time
.tv_nsec
)
3955 new_current_time
.tv_nsec
= time_span
.end_time
.tv_nsec
;
3958 current_time_change_manager(tab
, new_current_time
);
3962 on_MEntry6_value_changed (GtkSpinButton
*spinbutton
,
3965 Tab
*tab
= (Tab
*)user_data
;
3966 gint value
= gtk_spin_button_get_value_as_int(spinbutton
);
3967 LttTime new_current_time
= tab
->current_time
;
3968 new_current_time
.tv_nsec
= value
;
3970 current_time_change_manager(tab
, new_current_time
);
3974 void scroll_value_changed_cb(GtkWidget
*scrollbar
,
3977 Tab
*tab
= (Tab
*)user_data
;
3978 TimeWindow new_time_window
;
3980 GtkAdjustment
*adjust
= gtk_range_get_adjustment(GTK_RANGE(scrollbar
));
3981 gdouble value
= gtk_adjustment_get_value(adjust
);
3982 // gdouble upper, lower, ratio, page_size;
3984 LttvTracesetContext
* tsc
=
3985 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3986 TimeInterval time_span
= tsc
->time_span
;
3988 time
= ltt_time_add(ltt_time_from_double(value
),
3989 time_span
.start_time
);
3991 new_time_window
.start_time
= time
;
3993 page_size
= adjust
->page_size
;
3995 new_time_window
.time_width
=
3996 ltt_time_from_double(page_size
);
3998 new_time_window
.time_width_double
=
4001 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
4002 new_time_window
.time_width
);
4005 time_change_manager(tab
, new_time_window
);
4007 //time_window = tab->time_window;
4009 lower
= adjust
->lower
;
4010 upper
= adjust
->upper
;
4011 ratio
= (value
- lower
) / (upper
- lower
);
4012 g_info("lower %lu, upper %lu, value %lu, ratio %lu", lower
, upper
, value
, ratio
);
4014 //time = ltt_time_sub(time_span->end_time, time_span->start_time);
4015 //time = ltt_time_mul(time, (float)ratio);
4016 //time = ltt_time_add(time_span->start_time, time);
4017 time
= ltt_time_add(ltt_time_from_double(value
),
4018 time_span
.start_time
);
4020 time_window
.start_time
= time
;
4022 page_size
= adjust
->page_size
;
4024 time_window
.time_width
=
4025 ltt_time_from_double(page_size
);
4026 //time = ltt_time_sub(time_span.end_time, time);
4027 //if(ltt_time_compare(time,time_window.time_width) < 0){
4028 // time_window.time_width = time;
4031 /* call viewer hooks for new time window */
4032 set_time_window(tab
, &time_window
);
4037 /* Display a dialogue showing all eventtypes and traces, let user to select the interested
4038 * eventtypes, tracefiles and traces (filter)
4041 /* Select a trace which will be removed from traceset
4044 char * get_remove_trace(MainWindow
*mw_data
,
4045 char ** all_trace_name
, int nb_trace
)
4047 return get_selection(mw_data
, all_trace_name
, nb_trace
,
4048 "Select a trace", "Trace pathname");
4052 /* Select a module which will be loaded
4055 char * get_load_module(MainWindow
*mw_data
,
4056 char ** load_module_name
, int nb_module
)
4058 return get_selection(mw_data
, load_module_name
, nb_module
,
4059 "Select a module to load", "Module name");
4065 /* Select a module which will be unloaded
4068 char * get_unload_module(MainWindow
*mw_data
,
4069 char ** loaded_module_name
, int nb_module
)
4071 return get_selection(mw_data
, loaded_module_name
, nb_module
,
4072 "Select a module to unload", "Module name");
4076 /* Display a dialogue which shows all selectable items, let user to
4077 * select one of them
4080 char * get_selection(MainWindow
*mw_data
,
4081 char ** loaded_module_name
, int nb_module
,
4082 char *title
, char * column_title
)
4084 GtkWidget
* dialogue
;
4085 GtkWidget
* scroll_win
;
4087 GtkListStore
* store
;
4088 GtkTreeViewColumn
* column
;
4089 GtkCellRenderer
* renderer
;
4090 GtkTreeSelection
* select
;
4093 char * unload_module_name
= NULL
;
4095 dialogue
= gtk_dialog_new_with_buttons(title
,
4098 GTK_STOCK_OK
,GTK_RESPONSE_ACCEPT
,
4099 GTK_STOCK_CANCEL
,GTK_RESPONSE_REJECT
,
4101 gtk_window_set_default_size((GtkWindow
*)dialogue
, 500, 200);
4102 gtk_window_set_transient_for(GTK_WINDOW(dialogue
),
4103 GTK_WINDOW(mw_data
->mwindow
));
4105 scroll_win
= gtk_scrolled_window_new (NULL
, NULL
);
4106 gtk_widget_show ( scroll_win
);
4107 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll_win
),
4108 GTK_POLICY_AUTOMATIC
, GTK_POLICY_AUTOMATIC
);
4110 store
= gtk_list_store_new (N_COLUMNS
,G_TYPE_STRING
);
4111 tree
= gtk_tree_view_new_with_model(GTK_TREE_MODEL (store
));
4112 gtk_widget_show ( tree
);
4113 g_object_unref (G_OBJECT (store
));
4115 renderer
= gtk_cell_renderer_text_new ();
4116 column
= gtk_tree_view_column_new_with_attributes (column_title
,
4118 "text", MODULE_COLUMN
,
4120 gtk_tree_view_column_set_alignment (column
, 0.5);
4121 gtk_tree_view_column_set_fixed_width (column
, 150);
4122 gtk_tree_view_append_column (GTK_TREE_VIEW (tree
), column
);
4124 select
= gtk_tree_view_get_selection (GTK_TREE_VIEW (tree
));
4125 gtk_tree_selection_set_mode (select
, GTK_SELECTION_SINGLE
);
4127 gtk_container_add (GTK_CONTAINER (scroll_win
), tree
);
4129 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialogue
)->vbox
), scroll_win
,TRUE
, TRUE
,0);
4131 for(i
=0;i
<nb_module
;i
++){
4132 gtk_list_store_append (store
, &iter
);
4133 gtk_list_store_set (store
, &iter
, MODULE_COLUMN
,loaded_module_name
[i
],-1);
4136 id
= gtk_dialog_run(GTK_DIALOG(dialogue
));
4137 GtkTreeModel
**store_model
= (GtkTreeModel
**)&store
;
4139 case GTK_RESPONSE_ACCEPT
:
4140 case GTK_RESPONSE_OK
:
4141 if (gtk_tree_selection_get_selected (select
, store_model
, &iter
)){
4142 gtk_tree_model_get ((GtkTreeModel
*)store
, &iter
, MODULE_COLUMN
, &unload_module_name
, -1);
4144 case GTK_RESPONSE_REJECT
:
4145 case GTK_RESPONSE_CANCEL
:
4147 gtk_widget_destroy(dialogue
);
4151 return unload_module_name
;
4155 /* Insert all menu entry and tool buttons into this main window
4160 void add_all_menu_toolbar_constructors(MainWindow
* mw
, gpointer user_data
)
4164 lttvwindow_viewer_constructor constructor
;
4165 LttvMenus
* global_menu
, * instance_menu
;
4166 LttvToolbars
* global_toolbar
, * instance_toolbar
;
4167 LttvMenuClosure
*menu_item
;
4168 LttvToolbarClosure
*toolbar_item
;
4169 LttvAttributeValue value
;
4170 LttvIAttribute
*global_attributes
= LTTV_IATTRIBUTE(lttv_global_attributes());
4171 LttvIAttribute
*attributes
= mw
->attributes
;
4172 GtkWidget
* tool_menu_title_menu
, *new_widget
, *pixmap
;
4174 g_assert(lttv_iattribute_find_by_path(global_attributes
,
4175 "viewers/menu", LTTV_POINTER
, &value
));
4176 if(*(value
.v_pointer
) == NULL
)
4177 *(value
.v_pointer
) = lttv_menus_new();
4178 global_menu
= (LttvMenus
*)*(value
.v_pointer
);
4180 g_assert(lttv_iattribute_find_by_path(attributes
,
4181 "viewers/menu", LTTV_POINTER
, &value
));
4182 if(*(value
.v_pointer
) == NULL
)
4183 *(value
.v_pointer
) = lttv_menus_new();
4184 instance_menu
= (LttvMenus
*)*(value
.v_pointer
);
4188 g_assert(lttv_iattribute_find_by_path(global_attributes
,
4189 "viewers/toolbar", LTTV_POINTER
, &value
));
4190 if(*(value
.v_pointer
) == NULL
)
4191 *(value
.v_pointer
) = lttv_toolbars_new();
4192 global_toolbar
= (LttvToolbars
*)*(value
.v_pointer
);
4194 g_assert(lttv_iattribute_find_by_path(attributes
,
4195 "viewers/toolbar", LTTV_POINTER
, &value
));
4196 if(*(value
.v_pointer
) == NULL
)
4197 *(value
.v_pointer
) = lttv_toolbars_new();
4198 instance_toolbar
= (LttvToolbars
*)*(value
.v_pointer
);
4200 /* Add missing menu entries to window instance */
4201 for(i
=0;i
<global_menu
->len
;i
++) {
4202 menu_item
= &g_array_index(global_menu
, LttvMenuClosure
, i
);
4204 //add menu_item to window instance;
4205 constructor
= menu_item
->con
;
4206 tool_menu_title_menu
= lookup_widget(mw
->mwindow
,"ToolMenuTitle_menu");
4208 gtk_menu_item_new_with_mnemonic (menu_item
->menu_text
);
4209 gtk_container_add (GTK_CONTAINER (tool_menu_title_menu
),
4211 g_signal_connect ((gpointer
) new_widget
, "activate",
4212 G_CALLBACK (insert_viewer_wrap
),
4214 gtk_widget_show (new_widget
);
4215 lttv_menus_add(instance_menu
, menu_item
->con
,
4216 menu_item
->menu_path
,
4217 menu_item
->menu_text
,
4222 /* Add missing toolbar entries to window instance */
4223 for(i
=0;i
<global_toolbar
->len
;i
++) {
4224 toolbar_item
= &g_array_index(global_toolbar
, LttvToolbarClosure
, i
);
4226 //add toolbar_item to window instance;
4227 constructor
= toolbar_item
->con
;
4228 tool_menu_title_menu
= lookup_widget(mw
->mwindow
,"MToolbar1");
4229 pixbuf
= gdk_pixbuf_new_from_xpm_data((const char**)toolbar_item
->pixmap
);
4230 pixmap
= gtk_image_new_from_pixbuf(pixbuf
);
4232 gtk_toolbar_append_element (GTK_TOOLBAR (tool_menu_title_menu
),
4233 GTK_TOOLBAR_CHILD_BUTTON
,
4236 toolbar_item
->tooltip
, NULL
,
4237 pixmap
, NULL
, NULL
);
4238 gtk_label_set_use_underline(
4239 GTK_LABEL (((GtkToolbarChild
*) (
4240 g_list_last (GTK_TOOLBAR
4241 (tool_menu_title_menu
)->children
)->data
))->label
),
4243 gtk_container_set_border_width (GTK_CONTAINER (new_widget
), 1);
4244 g_signal_connect ((gpointer
) new_widget
,
4246 G_CALLBACK (insert_viewer_wrap
),
4248 gtk_widget_show (new_widget
);
4250 lttv_toolbars_add(instance_toolbar
, toolbar_item
->con
,
4251 toolbar_item
->tooltip
,
4252 toolbar_item
->pixmap
,
4260 /* Create a main window
4263 MainWindow
*construct_main_window(MainWindow
* parent
)
4265 g_debug("construct_main_window()");
4266 GtkWidget
* new_window
; /* New generated main window */
4267 MainWindow
* new_m_window
;/* New main window structure */
4268 GtkNotebook
* notebook
;
4269 LttvIAttribute
*attributes
=
4270 LTTV_IATTRIBUTE(g_object_new(LTTV_ATTRIBUTE_TYPE
, NULL
));
4271 LttvAttributeValue value
;
4274 new_m_window
= g_new(MainWindow
, 1);
4276 // Add the object's information to the module's array
4277 g_main_window_list
= g_slist_append(g_main_window_list
, new_m_window
);
4279 new_window
= create_MWindow();
4280 gtk_widget_show (new_window
);
4282 new_m_window
->mwindow
= new_window
;
4283 new_m_window
->attributes
= attributes
;
4285 g_assert(lttv_iattribute_find_by_path(attributes
,
4286 "viewers/menu", LTTV_POINTER
, &value
));
4287 *(value
.v_pointer
) = lttv_menus_new();
4289 g_assert(lttv_iattribute_find_by_path(attributes
,
4290 "viewers/toolbar", LTTV_POINTER
, &value
));
4291 *(value
.v_pointer
) = lttv_toolbars_new();
4293 add_all_menu_toolbar_constructors(new_m_window
, NULL
);
4295 g_object_set_data_full(G_OBJECT(new_window
),
4297 (gpointer
)new_m_window
,
4298 (GDestroyNotify
)g_free
);
4299 //create a default tab
4300 notebook
= (GtkNotebook
*)lookup_widget(new_m_window
->mwindow
, "MNotebook");
4301 if(notebook
== NULL
){
4302 g_info("Notebook does not exist\n");
4303 /* FIXME : destroy partially created widgets */
4304 g_free(new_m_window
);
4307 //gtk_notebook_popup_enable (GTK_NOTEBOOK(notebook));
4308 //for now there is no name field in LttvTraceset structure
4309 //Use "Traceset" as the label for the default tab
4311 GtkWidget
* parent_notebook
= lookup_widget(parent
->mwindow
, "MNotebook");
4312 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(parent_notebook
),
4313 gtk_notebook_get_current_page(GTK_NOTEBOOK(parent_notebook
)));
4319 LttvPluginTab
*ptab
;
4320 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
4321 parent_tab
= ptab
->tab
;
4323 LttvPluginTab
*ptab
= g_object_new(LTTV_TYPE_PLUGIN_TAB
, NULL
);
4325 new_m_window
, parent_tab
, notebook
, "Traceset");
4326 ptab
->parent
.top_widget
= ptab
->tab
->top_widget
;
4327 g_object_set_data_full(
4328 G_OBJECT(ptab
->tab
->vbox
),
4331 (GDestroyNotify
)tab_destructor
);
4332 new_tab
= ptab
->tab
;
4334 LttvPluginTab
*ptab
= g_object_new(LTTV_TYPE_PLUGIN_TAB
, NULL
);
4335 init_tab(ptab
->tab
, new_m_window
, NULL
, notebook
, "Traceset");
4336 ptab
->parent
.top_widget
= ptab
->tab
->top_widget
;
4337 g_object_set_data_full(
4338 G_OBJECT(ptab
->tab
->vbox
),
4341 (GDestroyNotify
)tab_destructor
);
4342 new_tab
= ptab
->tab
;
4345 /* Insert default viewers */
4347 LttvAttributeType type
;
4348 LttvAttributeName name
;
4349 LttvAttributeValue value
;
4350 LttvAttribute
*attribute
;
4352 LttvIAttribute
*attributes_global
=
4353 LTTV_IATTRIBUTE(lttv_global_attributes());
4355 attribute
= LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
4356 LTTV_IATTRIBUTE(attributes_global
),
4357 LTTV_VIEWER_CONSTRUCTORS
));
4358 g_assert(attribute
);
4360 name
= g_quark_from_string("guievents");
4361 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
4363 if(type
== LTTV_POINTER
) {
4364 lttvwindow_viewer_constructor viewer_constructor
=
4365 (lttvwindow_viewer_constructor
)*value
.v_pointer
;
4366 insert_viewer(new_window
, viewer_constructor
);
4369 name
= g_quark_from_string("guicontrolflow");
4370 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
4372 if(type
== LTTV_POINTER
) {
4373 lttvwindow_viewer_constructor viewer_constructor
=
4374 (lttvwindow_viewer_constructor
)*value
.v_pointer
;
4375 insert_viewer(new_window
, viewer_constructor
);
4378 name
= g_quark_from_string("guistatistics");
4379 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
4381 if(type
== LTTV_POINTER
) {
4382 lttvwindow_viewer_constructor viewer_constructor
=
4383 (lttvwindow_viewer_constructor
)*value
.v_pointer
;
4384 insert_viewer(new_window
, viewer_constructor
);
4388 g_info("There are now : %d windows\n",g_slist_length(g_main_window_list
));
4390 return new_m_window
;
4394 /* Free the memory occupied by a tab structure
4398 void tab_destructor(LttvPluginTab
* ptab
)
4400 int i
, nb
, ref_count
;
4402 Tab
*tab
= ptab
->tab
;
4404 gtk_object_destroy(GTK_OBJECT(tab
->tooltips
));
4407 g_object_unref(tab
->attributes
);
4409 if(tab
->interrupted_state
)
4410 g_object_unref(tab
->interrupted_state
);
4413 if(tab
->traceset_info
->traceset_context
!= NULL
){
4414 //remove state update hooks
4415 lttv_state_remove_event_hooks(
4416 (LttvTracesetState
*)tab
->traceset_info
->
4418 lttv_context_fini(LTTV_TRACESET_CONTEXT(tab
->traceset_info
->
4420 g_object_unref(tab
->traceset_info
->traceset_context
);
4422 if(tab
->traceset_info
->traceset
!= NULL
) {
4423 nb
= lttv_traceset_number(tab
->traceset_info
->traceset
);
4424 for(i
= 0 ; i
< nb
; i
++) {
4425 trace
= lttv_traceset_get(tab
->traceset_info
->traceset
, i
);
4426 ref_count
= lttv_trace_get_ref_number(trace
);
4428 ltt_trace_close(lttv_trace(trace
));
4432 lttv_traceset_destroy(tab
->traceset_info
->traceset
);
4433 /* Remove the idle events requests processing function of the tab */
4434 g_idle_remove_by_data(tab
);
4436 g_slist_free(tab
->events_requests
);
4437 g_free(tab
->traceset_info
);
4439 g_object_unref(ptab
);
4443 /* Create a tab and insert it into the current main window
4446 void init_tab(Tab
*tab
, MainWindow
* mw
, Tab
*copy_tab
,
4447 GtkNotebook
* notebook
, char * label
)
4451 //LttvFilter *filter = NULL;
4453 //create a new tab data structure
4454 //tab = g_new(Tab,1);
4456 //construct and initialize the traceset_info
4457 tab
->traceset_info
= g_new(TracesetInfo
,1);
4460 tab
->traceset_info
->traceset
=
4461 lttv_traceset_copy(copy_tab
->traceset_info
->traceset
);
4463 /* Copy the previous tab's filter */
4464 /* We can clone the filter, as we copy the trace set also */
4465 /* The filter must always be in sync with the trace set */
4466 tab
->filter
= lttv_filter_clone(copy_tab
->filter
);
4468 tab
->traceset_info
->traceset
= lttv_traceset_new();
4472 lttv_attribute_write_xml(
4473 lttv_traceset_attribute(tab
->traceset_info
->traceset
),
4479 tab
->time_manager_lock
= FALSE
;
4480 tab
->current_time_manager_lock
= FALSE
;
4482 //FIXME copy not implemented in lower level
4483 tab
->traceset_info
->traceset_context
=
4484 g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
4485 g_assert(tab
->traceset_info
->traceset_context
!= NULL
);
4487 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
),
4488 tab
->traceset_info
->traceset
);
4489 //add state update hooks
4490 lttv_state_add_event_hooks(
4491 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
4493 //determine the current_time and time_window of the tab
4495 if(copy_tab
!= NULL
){
4496 tab
->time_window
= copy_tab
->time_window
;
4497 tab
->current_time
= copy_tab
->current_time
;
4499 tab
->time_window
.start_time
=
4500 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
4501 time_span
.start_time
;
4502 if(DEFAULT_TIME_WIDTH_S
<
4503 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
4504 time_span
.end_time
.tv_sec
)
4505 tmp_time
.tv_sec
= DEFAULT_TIME_WIDTH_S
;
4508 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
4509 time_span
.end_time
.tv_sec
;
4510 tmp_time
.tv_nsec
= 0;
4511 tab
->time_window
.time_width
= tmp_time
;
4512 tab
->current_time
.tv_sec
=
4513 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
4514 time_span
.start_time
.tv_sec
;
4515 tab
->current_time
.tv_nsec
=
4516 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
4517 time_span
.start_time
.tv_nsec
;
4520 tab
->attributes
= LTTV_IATTRIBUTE(g_object_new(LTTV_ATTRIBUTE_TYPE
, NULL
));
4521 tab
->interrupted_state
= g_object_new(LTTV_ATTRIBUTE_TYPE
, NULL
);
4523 tab
->vbox
= gtk_vbox_new(FALSE
, 2);
4524 tab
->top_widget
= tab
->vbox
;
4525 //g_object_set_data_full(G_OBJECT(tab->top_widget), "filter",
4526 // filter, (GDestroyNotify)lttv_filter_destroy);
4528 // g_signal_connect (G_OBJECT(tab->top_widget),
4530 // G_CALLBACK (on_top_notify),
4533 tab
->viewer_container
= gtk_vbox_new(TRUE
, 2);
4534 tab
->scrollbar
= gtk_hscrollbar_new(NULL
);
4535 //tab->multivpaned = gtk_multi_vpaned_new();
4537 gtk_box_pack_start(GTK_BOX(tab
->vbox
),
4538 tab
->viewer_container
,
4540 TRUE
, /* Give the extra space to the child */
4541 0); /* No padding */
4544 // tab->time_window = copy_tab->time_window;
4545 // tab->current_time = copy_tab->current_time;
4548 /* Create the timebar */
4550 tab
->MTimebar
= gtk_hbox_new(FALSE
, 2);
4551 gtk_widget_show(tab
->MTimebar
);
4552 tab
->tooltips
= gtk_tooltips_new();
4554 tab
->MEventBox1a
= gtk_event_box_new();
4555 gtk_widget_show(tab
->MEventBox1a
);
4556 gtk_tooltips_set_tip(tab
->tooltips
, tab
->MEventBox1a
,
4557 "Paste Start and End Times Here", "");
4558 tab
->MText1a
= gtk_label_new("Time Frame ");
4559 gtk_widget_show(tab
->MText1a
);
4560 gtk_container_add(GTK_CONTAINER(tab
->MEventBox1a
), tab
->MText1a
);
4561 tab
->MEventBox1b
= gtk_event_box_new();
4562 gtk_widget_show(tab
->MEventBox1b
);
4563 gtk_tooltips_set_tip(tab
->tooltips
, tab
->MEventBox1b
,
4564 "Paste Start Time Here", "");
4565 tab
->MText1b
= gtk_label_new("start: ");
4566 gtk_widget_show(tab
->MText1b
);
4567 gtk_container_add(GTK_CONTAINER(tab
->MEventBox1b
), tab
->MText1b
);
4568 tab
->MText2
= gtk_label_new("s");
4569 gtk_widget_show(tab
->MText2
);
4570 tab
->MText3a
= gtk_label_new("ns");
4571 gtk_widget_show(tab
->MText3a
);
4573 tab
->MEventBox3b
= gtk_event_box_new();
4574 gtk_widget_show(tab
->MEventBox3b
);
4575 gtk_tooltips_set_tip(tab
->tooltips
, tab
->MEventBox3b
,
4576 "Paste End Time Here", "");
4577 tab
->MText3b
= gtk_label_new("end:");
4578 gtk_widget_show(tab
->MText3b
);
4579 gtk_container_add(GTK_CONTAINER(tab
->MEventBox3b
), tab
->MText3b
);
4580 tab
->MText4
= gtk_label_new("s");
4581 gtk_widget_show(tab
->MText4
);
4582 tab
->MText5a
= gtk_label_new("ns");
4583 gtk_widget_show(tab
->MText5a
);
4585 tab
->MEventBox8
= gtk_event_box_new();
4586 gtk_widget_show(tab
->MEventBox8
);
4587 gtk_tooltips_set_tip(tab
->tooltips
, tab
->MEventBox8
,
4588 "Paste Time Interval here", "");
4589 tab
->MText8
= gtk_label_new("Time Interval:");
4590 gtk_widget_show(tab
->MText8
);
4591 gtk_container_add(GTK_CONTAINER(tab
->MEventBox8
), tab
->MText8
);
4592 tab
->MText9
= gtk_label_new("s");
4593 gtk_widget_show(tab
->MText9
);
4594 tab
->MText10
= gtk_label_new("ns");
4595 gtk_widget_show(tab
->MText10
);
4597 tab
->MEventBox5b
= gtk_event_box_new();
4598 gtk_widget_show(tab
->MEventBox5b
);
4599 gtk_tooltips_set_tip(tab
->tooltips
, tab
->MEventBox5b
,
4600 "Paste Current Time Here", "");
4601 tab
->MText5b
= gtk_label_new("Current Time:");
4602 gtk_widget_show(tab
->MText5b
);
4603 gtk_container_add(GTK_CONTAINER(tab
->MEventBox5b
), tab
->MText5b
);
4604 tab
->MText6
= gtk_label_new("s");
4605 gtk_widget_show(tab
->MText6
);
4606 tab
->MText7
= gtk_label_new("ns");
4607 gtk_widget_show(tab
->MText7
);
4609 tab
->MEntry1
= gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4610 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab
->MEntry1
),0);
4611 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab
->MEntry1
),TRUE
);
4612 gtk_widget_show(tab
->MEntry1
);
4613 tab
->MEntry2
= gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4614 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab
->MEntry2
),0);
4615 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab
->MEntry2
),TRUE
);
4616 gtk_widget_show(tab
->MEntry2
);
4617 tab
->MEntry3
= gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4618 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab
->MEntry3
),0);
4619 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab
->MEntry3
),TRUE
);
4620 gtk_widget_show(tab
->MEntry3
);
4621 tab
->MEntry4
= gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4622 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab
->MEntry4
),0);
4623 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab
->MEntry4
),TRUE
);
4624 gtk_widget_show(tab
->MEntry4
);
4625 tab
->MEntry5
= gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4626 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab
->MEntry5
),0);
4627 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab
->MEntry5
),TRUE
);
4628 gtk_widget_show(tab
->MEntry5
);
4629 tab
->MEntry6
= gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4630 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab
->MEntry6
),0);
4631 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab
->MEntry6
),TRUE
);
4632 gtk_widget_show(tab
->MEntry6
);
4633 tab
->MEntry7
= gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4634 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab
->MEntry7
),0);
4635 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab
->MEntry7
),TRUE
);
4636 gtk_widget_show(tab
->MEntry7
);
4637 tab
->MEntry8
= gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4638 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab
->MEntry8
),0);
4639 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab
->MEntry8
),TRUE
);
4640 gtk_widget_show(tab
->MEntry8
);
4642 GtkWidget
*temp_widget
;
4644 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEventBox1a
, FALSE
,
4646 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEventBox1b
, FALSE
,
4648 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEntry1
, FALSE
, FALSE
, 0);
4649 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MText2
, FALSE
, FALSE
, 0);
4650 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEntry2
, FALSE
, FALSE
, 0);
4651 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MText3a
, FALSE
, FALSE
, 0);
4652 temp_widget
= gtk_vseparator_new();
4653 gtk_widget_show(temp_widget
);
4654 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), temp_widget
, FALSE
, FALSE
, 0);
4655 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEventBox3b
, FALSE
,
4657 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEntry3
, FALSE
, FALSE
, 0);
4658 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MText4
, FALSE
, FALSE
, 0);
4659 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEntry4
, FALSE
, FALSE
, 0);
4660 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MText5a
, FALSE
, FALSE
, 0);
4661 temp_widget
= gtk_vseparator_new();
4662 gtk_widget_show(temp_widget
);
4663 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), temp_widget
, FALSE
, FALSE
, 0);
4664 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEventBox8
, FALSE
,
4666 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEntry7
, FALSE
, FALSE
, 0);
4667 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MText9
, FALSE
, FALSE
, 0);
4668 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEntry8
, FALSE
, FALSE
, 0);
4669 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MText10
, FALSE
, FALSE
, 0);
4671 temp_widget
= gtk_vseparator_new();
4672 gtk_widget_show(temp_widget
);
4673 gtk_box_pack_end (GTK_BOX (tab
->MTimebar
), tab
->MText7
, FALSE
, FALSE
, 0);
4674 gtk_box_pack_end (GTK_BOX (tab
->MTimebar
), tab
->MEntry6
, FALSE
, FALSE
, 0);
4675 gtk_box_pack_end (GTK_BOX (tab
->MTimebar
), tab
->MText6
, FALSE
, FALSE
, 0);
4676 gtk_box_pack_end (GTK_BOX (tab
->MTimebar
), tab
->MEntry5
, FALSE
, FALSE
, 0);
4677 gtk_box_pack_end (GTK_BOX (tab
->MTimebar
), tab
->MEventBox5b
, FALSE
,
4679 gtk_box_pack_end (GTK_BOX (tab
->MTimebar
), temp_widget
, FALSE
, FALSE
, 0);
4682 //GtkWidget *test = gtk_button_new_with_label("drop");
4683 //gtk_button_set_relief(GTK_BUTTON(test), GTK_RELIEF_NONE);
4684 //gtk_widget_show(test);
4685 //gtk_box_pack_end(GTK_BOX (tab->MTimebar), test, FALSE, FALSE, 0);
4686 //gtk_widget_add_events(tab->MText1, GDK_ALL_EVENTS_MASK);//GDK_BUTTON_PRESS_MASK);
4687 /*GtkWidget *event_box = gtk_event_box_new();
4688 gtk_widget_show(event_box);
4689 gtk_tooltips_set_tip(tooltips, event_box,
4690 "Paste Current Time Here", "");
4691 gtk_box_pack_end(GTK_BOX (tab->MTimebar), event_box, FALSE, FALSE, 0);
4692 GtkWidget *test = gtk_label_new("drop");
4693 gtk_container_add(GTK_CONTAINER(event_box), test);
4694 gtk_widget_show(test);
4695 g_signal_connect (G_OBJECT(event_box),
4696 "button-press-event",
4697 G_CALLBACK (on_MText1_paste),
4701 g_signal_connect (G_OBJECT(tab
->MEventBox1a
),
4702 "button-press-event",
4703 G_CALLBACK (on_MEventBox1a_paste
),
4706 g_signal_connect (G_OBJECT(tab
->MEventBox1b
),
4707 "button-press-event",
4708 G_CALLBACK (on_MEventBox1b_paste
),
4710 g_signal_connect (G_OBJECT(tab
->MEventBox3b
),
4711 "button-press-event",
4712 G_CALLBACK (on_MEventBox3b_paste
),
4714 g_signal_connect (G_OBJECT(tab
->MEventBox5b
),
4715 "button-press-event",
4716 G_CALLBACK (on_MEventBox5b_paste
),
4718 g_signal_connect (G_OBJECT(tab
->MEventBox8
),
4719 "button-press-event",
4720 G_CALLBACK (on_MEventBox8_paste
),
4724 gtk_box_pack_end(GTK_BOX(tab
->vbox
),
4726 FALSE
, /* Do not expand */
4727 FALSE
, /* Fill has no effect here (expand false) */
4728 0); /* No padding */
4730 gtk_box_pack_end(GTK_BOX(tab
->vbox
),
4732 FALSE
, /* Do not expand */
4733 FALSE
, /* Fill has no effect here (expand false) */
4734 0); /* No padding */
4736 g_object_set_data(G_OBJECT(tab
->viewer_container
), "focused_viewer", NULL
);
4742 // Display a label with a X
4743 GtkWidget *w_hbox = gtk_hbox_new(FALSE, 4);
4744 GtkWidget *w_label = gtk_label_new (label);
4745 GtkWidget *pixmap = create_pixmap(GTK_WIDGET(notebook), "close.png");
4746 GtkWidget *w_button = gtk_button_new ();
4747 gtk_container_add(GTK_CONTAINER(w_button), pixmap);
4748 //GtkWidget *w_button = gtk_button_new_with_label("x");
4750 gtk_button_set_relief(GTK_BUTTON(w_button), GTK_RELIEF_NONE);
4752 gtk_box_pack_start(GTK_BOX(w_hbox), w_label, TRUE, TRUE, 0);
4753 gtk_box_pack_end(GTK_BOX(w_hbox), w_button, FALSE,
4756 g_signal_connect_swapped (w_button, "clicked",
4757 G_CALLBACK (on_close_tab_X_clicked),
4760 gtk_widget_set_state(w_button, GTK_STATE_ACTIVE);
4762 gtk_widget_show (w_label);
4763 gtk_widget_show (pixmap);
4764 gtk_widget_show (w_button);
4765 gtk_widget_show (w_hbox);
4767 tab->label = w_hbox;
4771 tab
->label
= gtk_label_new (label
);
4773 gtk_widget_show(tab
->label
);
4774 gtk_widget_show(tab
->scrollbar
);
4775 gtk_widget_show(tab
->viewer_container
);
4776 gtk_widget_show(tab
->vbox
);
4777 //gtk_widget_show(tab->multivpaned);
4780 /* Start with empty events requests list */
4781 tab
->events_requests
= NULL
;
4782 tab
->events_request_pending
= FALSE
;
4783 tab
->stop_foreground
= FALSE
;
4787 g_signal_connect(G_OBJECT(tab
->scrollbar
), "value-changed",
4788 G_CALLBACK(scroll_value_changed_cb
), tab
);
4790 g_signal_connect ((gpointer
) tab
->MEntry1
, "value-changed",
4791 G_CALLBACK (on_MEntry1_value_changed
),
4793 g_signal_connect ((gpointer
) tab
->MEntry2
, "value-changed",
4794 G_CALLBACK (on_MEntry2_value_changed
),
4796 g_signal_connect ((gpointer
) tab
->MEntry3
, "value-changed",
4797 G_CALLBACK (on_MEntry3_value_changed
),
4799 g_signal_connect ((gpointer
) tab
->MEntry4
, "value-changed",
4800 G_CALLBACK (on_MEntry4_value_changed
),
4802 g_signal_connect ((gpointer
) tab
->MEntry5
, "value-changed",
4803 G_CALLBACK (on_MEntry5_value_changed
),
4805 g_signal_connect ((gpointer
) tab
->MEntry6
, "value-changed",
4806 G_CALLBACK (on_MEntry6_value_changed
),
4808 g_signal_connect ((gpointer
) tab
->MEntry7
, "value-changed",
4809 G_CALLBACK (on_MEntry7_value_changed
),
4811 g_signal_connect ((gpointer
) tab
->MEntry8
, "value-changed",
4812 G_CALLBACK (on_MEntry8_value_changed
),
4815 //g_signal_connect(G_OBJECT(tab->scrollbar), "changed",
4816 // G_CALLBACK(scroll_value_changed_cb), tab);
4819 //insert tab into notebook
4820 gtk_notebook_append_page(notebook
,
4823 list
= gtk_container_get_children(GTK_CONTAINER(notebook
));
4824 gtk_notebook_set_current_page(notebook
,g_list_length(list
)-1);
4825 // always show : not if(g_list_length(list)>1)
4826 gtk_notebook_set_show_tabs(notebook
, TRUE
);
4829 lttvwindow_report_time_window(tab
, copy_tab
->time_window
);
4830 lttvwindow_report_current_time(tab
, copy_tab
->current_time
);
4832 TimeWindow time_window
;
4834 time_window
.start_time
= ltt_time_zero
;
4835 time_window
.end_time
= ltt_time_add(time_window
.start_time
,
4836 lttvwindow_default_time_width
);
4837 time_window
.time_width
= lttvwindow_default_time_width
;
4838 time_window
.time_width_double
= ltt_time_to_double(time_window
.time_width
);
4840 lttvwindow_report_time_window(tab
, time_window
);
4841 lttvwindow_report_current_time(tab
, ltt_time_zero
);
4844 LttvTraceset
*traceset
= tab
->traceset_info
->traceset
;
4845 SetTraceset(tab
, traceset
);
4849 * execute_events_requests
4851 * Idle function that executes the pending requests for a tab.
4853 * @return return value : TRUE : keep the idle function, FALSE : remove it.
4855 gboolean
execute_events_requests(Tab
*tab
)
4857 return ( lttvwindow_process_pending_requests(tab
) );
4861 __EXPORT
void create_main_window_with_trace_list(GSList
*traces
)
4863 GSList
*iter
= NULL
;
4866 MainWindow
*mw
= construct_main_window(NULL
);
4867 GtkWidget
*widget
= mw
->mwindow
;
4869 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
4870 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
4871 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
4872 LttvPluginTab
*ptab
;
4876 ptab
= create_new_tab(widget
, NULL
);
4879 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
4883 for(iter
=traces
; iter
!=NULL
; iter
=g_slist_next(iter
)) {
4884 gchar
*path
= (gchar
*)iter
->data
;
4886 gchar abs_path
[PATH_MAX
];
4890 get_absolute_pathname(path
, abs_path
);
4891 trace_v
= lttvwindowtraces_get_trace_by_name(abs_path
);
4892 if(trace_v
== NULL
) {
4893 trace
= ltt_trace_open(abs_path
);
4895 g_warning("cannot open trace %s", abs_path
);
4897 GtkWidget
*dialogue
=
4898 gtk_message_dialog_new(
4899 GTK_WINDOW(gtk_widget_get_toplevel(widget
)),
4900 GTK_DIALOG_MODAL
|GTK_DIALOG_DESTROY_WITH_PARENT
,
4903 "Cannot open trace : maybe you should enter in the directory "
4905 gtk_dialog_run(GTK_DIALOG(dialogue
));
4906 gtk_widget_destroy(dialogue
);
4908 trace_v
= lttv_trace_new(trace
);
4909 lttvwindowtraces_add_trace(trace_v
);
4910 lttvwindow_add_trace(tab
, trace_v
);
4913 lttvwindow_add_trace(tab
, trace_v
);
4917 LttvTraceset
*traceset
;
4919 traceset
= tab
->traceset_info
->traceset
;
4920 SetTraceset(tab
, traceset
);