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
);
472 TimeInterval time_span
= tsc
->time_span
;
473 TimeWindow new_time_window
= tab
->time_window
;
474 LttTime new_current_time
= tab
->current_time
;
476 /* Set the tab's time window and current time if
478 if(ltt_time_compare(tab
->time_window
.start_time
, time_span
.start_time
) < 0
479 || ltt_time_compare(tab
->time_window
.end_time
,
480 time_span
.end_time
) > 0) {
481 new_time_window
.start_time
= time_span
.start_time
;
483 new_current_time
= time_span
.start_time
;
487 if(ltt_time_compare(lttvwindow_default_time_width
,
488 ltt_time_sub(time_span
.end_time
, time_span
.start_time
)) < 0
490 ltt_time_compare(time_span
.end_time
, time_span
.start_time
) == 0)
491 tmp_time
= lttvwindow_default_time_width
;
493 tmp_time
= time_span
.end_time
;
495 new_time_window
.time_width
= tmp_time
;
496 new_time_window
.time_width_double
= ltt_time_to_double(tmp_time
);
497 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
498 new_time_window
.time_width
) ;
505 GtkAdjustment
*adjustment
= gtk_range_get_adjustment(GTK_RANGE(tab
->scrollbar
));
506 LttTime upper
= ltt_time_sub(time_span
.end_time
, time_span
.start_time
);
508 g_object_set(G_OBJECT(adjustment
),
512 ltt_time_to_double(upper
)
513 * NANOSECONDS_PER_SECOND
, /* upper */
515 ltt_time_to_double(tab
->time_window
.time_width
)
516 / SCROLL_STEP_PER_PAGE
517 * NANOSECONDS_PER_SECOND
, /* step increment */
519 ltt_time_to_double(tab
->time_window
.time_width
)
520 * NANOSECONDS_PER_SECOND
, /* page increment */
522 ltt_time_to_double(tab
->time_window
.time_width
)
523 * NANOSECONDS_PER_SECOND
, /* page size */
525 gtk_adjustment_changed(adjustment
);
527 g_object_set(G_OBJECT(adjustment
),
530 ltt_time_sub(tab
->time_window
.start_time
, time_span
.start_time
))
531 * NANOSECONDS_PER_SECOND
, /* value */
533 gtk_adjustment_value_changed(adjustment
);
535 /* set the time bar. The value callbacks will change their nsec themself */
537 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry1
),
538 (double)time_span
.start_time
.tv_sec
,
539 (double)time_span
.end_time
.tv_sec
);
542 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry3
),
543 (double)time_span
.start_time
.tv_sec
,
544 (double)time_span
.end_time
.tv_sec
);
546 /* current seconds */
547 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry5
),
548 (double)time_span
.start_time
.tv_sec
,
549 (double)time_span
.end_time
.tv_sec
);
552 /* Finally, call the update hooks of the viewers */
554 LttvAttributeValue value
;
557 retval
= lttv_iattribute_find_by_path(tab
->attributes
,
558 "hooks/updatetraceset", LTTV_POINTER
, &value
);
561 tmp
= (LttvHooks
*)*(value
.v_pointer
);
565 lttv_hooks_call(tmp
,traceset
);
567 time_change_manager(tab
, new_time_window
);
568 current_time_change_manager(tab
, new_current_time
);
574 * Function to set/update filter for the viewers
575 * @param tab viewer's tab
576 * @param filter filter of the main window.
579 * 0 : filters updated
580 * 1 : no filter hooks to update; not an error.
583 int SetFilter(Tab
* tab
, gpointer filter
)
586 LttvAttributeValue value
;
588 g_assert(lttv_iattribute_find_by_path(tab
->attributes
,
589 "hooks/updatefilter", LTTV_POINTER
, &value
));
591 tmp
= (LttvHooks
*)*(value
.v_pointer
);
593 if(tmp
== NULL
) return 1;
594 lttv_hooks_call(tmp
,filter
);
602 * Function to redraw each viewer belonging to the current tab
603 * @param tab viewer's tab
606 void update_traceset(Tab
*tab
)
608 LttvAttributeValue value
;
612 retval
= lttv_iattribute_find_by_path(tab
->attributes
,
613 "hooks/updatetraceset", LTTV_POINTER
, &value
);
615 tmp
= (LttvHooks
*)*(value
.v_pointer
);
616 if(tmp
== NULL
) return;
617 lttv_hooks_call(tmp
, NULL
);
621 /* get_label function is used to get user input, it displays an input
622 * box, which allows user to input a string
625 void get_label_string (GtkWidget
* text
, gchar
* label
)
627 GtkEntry
* entry
= (GtkEntry
*)text
;
628 if(strlen(gtk_entry_get_text(entry
))!=0)
629 strcpy(label
,gtk_entry_get_text(entry
));
632 gboolean
get_label(MainWindow
* mw
, gchar
* str
, gchar
* dialogue_title
, gchar
* label_str
)
634 GtkWidget
* dialogue
;
639 dialogue
= gtk_dialog_new_with_buttons(dialogue_title
,NULL
,
641 GTK_STOCK_OK
,GTK_RESPONSE_ACCEPT
,
642 GTK_STOCK_CANCEL
,GTK_RESPONSE_REJECT
,
645 label
= gtk_label_new(label_str
);
646 gtk_widget_show(label
);
648 text
= gtk_entry_new();
649 gtk_widget_show(text
);
651 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialogue
)->vbox
), label
,TRUE
, TRUE
,0);
652 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialogue
)->vbox
), text
,FALSE
, FALSE
,0);
654 id
= gtk_dialog_run(GTK_DIALOG(dialogue
));
656 case GTK_RESPONSE_ACCEPT
:
657 get_label_string(text
,str
);
658 gtk_widget_destroy(dialogue
);
660 case GTK_RESPONSE_REJECT
:
662 gtk_widget_destroy(dialogue
);
669 /* get_window_data_struct function is actually a lookup function,
670 * given a widget which is in the tree of the main window, it will
671 * return the MainWindow data structure associated with main window
674 MainWindow
* get_window_data_struct(GtkWidget
* widget
)
677 MainWindow
* mw_data
;
679 mw
= lookup_widget(widget
, "MWindow");
681 g_info("Main window does not exist\n");
685 mw_data
= (MainWindow
*) g_object_get_data(G_OBJECT(mw
),"main_window_data");
687 g_warning("Main window data does not exist\n");
694 /* create_new_window function, just constructs a new main window
697 void create_new_window(GtkWidget
* widget
, gpointer user_data
, gboolean clone
)
699 MainWindow
* parent
= get_window_data_struct(widget
);
702 g_info("Clone : use the same traceset\n");
703 construct_main_window(parent
);
705 g_info("Empty : traceset is set to NULL\n");
706 construct_main_window(NULL
);
710 /* Get the currently focused viewer.
711 * If no viewer is focused, use the first one.
713 * If no viewer available, return NULL.
715 GtkWidget
*viewer_container_focus(GtkWidget
*container
)
719 widget
= (GtkWidget
*)g_object_get_data(G_OBJECT(container
),
723 g_debug("no widget focused");
724 GList
*children
= gtk_container_get_children(GTK_CONTAINER(container
));
727 widget
= GTK_WIDGET(children
->data
);
728 g_object_set_data(G_OBJECT(container
),
738 gint
viewer_container_position(GtkWidget
*container
, GtkWidget
*child
)
741 if(child
== NULL
) return -1;
745 memset(&value
, 0, sizeof(GValue
));
746 g_value_init(&value
, G_TYPE_INT
);
747 gtk_container_child_get_property(GTK_CONTAINER(container
),
751 pos
= g_value_get_int(&value
);
757 /* move_*_viewer functions move the selected view up/down in
761 void move_down_viewer(GtkWidget
* widget
, gpointer user_data
)
763 MainWindow
* mw
= get_window_data_struct(widget
);
764 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
766 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
767 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
774 ptab
= g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
778 //gtk_multivpaned_widget_move_up(GTK_MULTIVPANED(tab->multivpaned));
780 /* change the position in the vbox */
781 GtkWidget
*focus_widget
;
783 focus_widget
= viewer_container_focus(tab
->viewer_container
);
784 position
= viewer_container_position(tab
->viewer_container
, focus_widget
);
787 /* can move up one position */
788 gtk_box_reorder_child(GTK_BOX(tab
->viewer_container
),
795 void move_up_viewer(GtkWidget
* widget
, gpointer user_data
)
797 MainWindow
* mw
= get_window_data_struct(widget
);
798 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
800 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
801 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
808 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
812 //gtk_multivpaned_widget_move_down(GTK_MULTIVPANED(tab->multivpaned));
813 /* change the position in the vbox */
814 GtkWidget
*focus_widget
;
816 focus_widget
= viewer_container_focus(tab
->viewer_container
);
817 position
= viewer_container_position(tab
->viewer_container
, focus_widget
);
821 g_list_length(gtk_container_get_children(
822 GTK_CONTAINER(tab
->viewer_container
)))-1
824 /* can move down one position */
825 gtk_box_reorder_child(GTK_BOX(tab
->viewer_container
),
833 /* delete_viewer deletes the selected viewer in the current tab
836 void delete_viewer(GtkWidget
* widget
, gpointer user_data
)
838 MainWindow
* mw
= get_window_data_struct(widget
);
839 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
841 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
842 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
849 ptab
= g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
853 //gtk_multivpaned_widget_delete(GTK_MULTIVPANED(tab->multivpaned));
855 GtkWidget
*focus_widget
= viewer_container_focus(tab
->viewer_container
);
857 if(focus_widget
!= NULL
)
858 gtk_widget_destroy(focus_widget
);
860 g_object_set_data(G_OBJECT(tab
->viewer_container
), "focused_viewer", NULL
);
864 /* open_traceset will open a traceset saved in a file
865 * Right now, it is not finished yet, (not working)
869 void open_traceset(GtkWidget
* widget
, gpointer user_data
)
873 LttvTraceset
* traceset
;
874 MainWindow
* mw_data
= get_window_data_struct(widget
);
875 GtkFileSelection
* file_selector
=
876 (GtkFileSelection
*)gtk_file_selection_new("Select a traceset");
878 gtk_file_selection_hide_fileop_buttons(file_selector
);
880 gtk_window_set_transient_for(GTK_WINDOW(file_selector
),
881 GTK_WINDOW(mw_data
->mwindow
));
883 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
885 case GTK_RESPONSE_ACCEPT
:
886 case GTK_RESPONSE_OK
:
887 dir
= gtk_file_selection_get_selections (file_selector
);
888 traceset
= lttv_traceset_load(dir
[0]);
889 g_info("Open a trace set %s\n", dir
[0]);
892 case GTK_RESPONSE_REJECT
:
893 case GTK_RESPONSE_CANCEL
:
895 gtk_widget_destroy((GtkWidget
*)file_selector
);
901 /* lttvwindow_process_pending_requests
903 * Process requests for parts of the trace from viewers.
905 * These requests are made by lttvwindow_events_request().
907 * This internal function gets called by g_idle, taking care of the pending
908 * requests. It is responsible for concatenation of time intervals and position
909 * requests. It does it with the following algorithm organizing process traceset
910 * calls. Here is the detailed description of the way it works :
912 * - Events Requests Servicing Algorithm
914 * Data structures necessary :
916 * List of requests added to context : list_in
917 * List of requests not added to context : list_out
922 * list_out : many events requests
924 * FIXME : insert rest of algorithm here
928 #define list_out tab->events_requests
930 gboolean
lttvwindow_process_pending_requests(Tab
*tab
)
933 LttvTracesetContext
*tsc
;
934 LttvTracefileContext
*tfc
;
935 GSList
*list_in
= NULL
;
939 LttvTracesetContextPosition
*end_position
;
941 if(lttvwindow_preempt_count
> 0) return TRUE
;
944 g_critical("Foreground processing : tab does not exist. Processing removed.");
948 /* There is no events requests pending : we should never have been called! */
949 g_assert(g_slist_length(list_out
) != 0);
951 tsc
= LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
953 //set the cursor to be X shape, indicating that the computer is busy in doing its job
955 new = gdk_cursor_new(GDK_X_CURSOR
);
956 widget
= lookup_widget(tab
->mw
->mwindow
, "MToolbar1");
957 win
= gtk_widget_get_parent_window(widget
);
958 gdk_window_set_cursor(win
, new);
959 gdk_cursor_unref(new);
960 gdk_window_stick(win
);
961 gdk_window_unstick(win
);
964 g_debug("SIZE events req len : %d", g_slist_length(list_out
));
966 /* Preliminary check for no trace in traceset */
967 /* Unregister the routine if empty, empty list_out too */
968 if(lttv_traceset_number(tsc
->ts
) == 0) {
970 /* - For each req in list_out */
971 GSList
*iter
= list_out
;
973 while(iter
!= NULL
) {
975 gboolean remove
= FALSE
;
976 gboolean free_data
= FALSE
;
977 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
979 /* - Call end request for req */
980 if(events_request
->servicing
== TRUE
)
981 lttv_hooks_call(events_request
->after_request
, (gpointer
)tsc
);
983 /* - remove req from list_out */
984 /* Destroy the request */
991 GSList
*remove_iter
= iter
;
993 iter
= g_slist_next(iter
);
994 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
995 list_out
= g_slist_remove_link(list_out
, remove_iter
);
996 } else { // not remove
997 iter
= g_slist_next(iter
);
1002 /* 0.1 Lock Traces */
1007 iter_trace
<lttv_traceset_number(tsc
->ts
);
1009 LttvTrace
*trace_v
= lttv_traceset_get(tsc
->ts
, iter_trace
);
1011 if(lttvwindowtraces_lock(trace_v
) != 0) {
1012 g_critical("Foreground processing : Unable to get trace lock");
1013 return TRUE
; /* Cannot get lock, try later */
1018 /* 0.2 Seek tracefiles positions to context position */
1019 //g_assert(lttv_process_traceset_seek_position(tsc, sync_position) == 0);
1020 lttv_process_traceset_synchronize_tracefiles(tsc
);
1023 /* Events processing algorithm implementation */
1024 /* Warning : the gtk_events_pending takes a LOT of cpu time. So what we do
1025 * instead is to leave the control to GTK and take it back.
1027 /* A. Servicing loop */
1028 //while( (g_slist_length(list_in) != 0 || g_slist_length(list_out) != 0)) {
1029 if((g_slist_length(list_in
) != 0 || g_slist_length(list_out
) != 0)) {
1031 /* 1. If list_in is empty (need a seek) */
1032 if( g_slist_length(list_in
) == 0 ) {
1034 /* list in is empty, need a seek */
1036 /* 1.1 Add requests to list_in */
1037 GSList
*ltime
= NULL
;
1038 GSList
*lpos
= NULL
;
1039 GSList
*iter
= NULL
;
1041 /* 1.1.1 Find all time requests with the lowest start time in list_out
1044 if(g_slist_length(list_out
) > 0)
1045 ltime
= g_slist_append(ltime
, g_slist_nth_data(list_out
, 0));
1046 for(iter
=g_slist_nth(list_out
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
1047 /* Find all time requests with the lowest start time in list_out */
1048 EventsRequest
*event_request_ltime
= (EventsRequest
*)g_slist_nth_data(ltime
, 0);
1049 EventsRequest
*event_request_list_out
= (EventsRequest
*)iter
->data
;
1052 comp
= ltt_time_compare(event_request_ltime
->start_time
,
1053 event_request_list_out
->start_time
);
1055 ltime
= g_slist_append(ltime
, event_request_list_out
);
1057 /* Remove all elements from ltime, and add current */
1058 while(ltime
!= NULL
)
1059 ltime
= g_slist_delete_link(ltime
, g_slist_nth(ltime
, 0));
1060 ltime
= g_slist_append(ltime
, event_request_list_out
);
1064 /* 1.1.2 Find all position requests with the lowest position in list_out
1067 if(g_slist_length(list_out
) > 0)
1068 lpos
= g_slist_append(lpos
, g_slist_nth_data(list_out
, 0));
1069 for(iter
=g_slist_nth(list_out
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
1070 /* Find all position requests with the lowest position in list_out */
1071 EventsRequest
*event_request_lpos
= (EventsRequest
*)g_slist_nth_data(lpos
, 0);
1072 EventsRequest
*event_request_list_out
= (EventsRequest
*)iter
->data
;
1075 if(event_request_lpos
->start_position
!= NULL
1076 && event_request_list_out
->start_position
!= NULL
)
1078 comp
= lttv_traceset_context_pos_pos_compare
1079 (event_request_lpos
->start_position
,
1080 event_request_list_out
->start_position
);
1085 lpos
= g_slist_append(lpos
, event_request_list_out
);
1087 /* Remove all elements from lpos, and add current */
1089 lpos
= g_slist_delete_link(lpos
, g_slist_nth(lpos
, 0));
1090 lpos
= g_slist_append(lpos
, event_request_list_out
);
1095 EventsRequest
*event_request_lpos
= (EventsRequest
*)g_slist_nth_data(lpos
, 0);
1096 EventsRequest
*event_request_ltime
= (EventsRequest
*)g_slist_nth_data(ltime
, 0);
1097 LttTime lpos_start_time
;
1099 if(event_request_lpos
!= NULL
1100 && event_request_lpos
->start_position
!= NULL
) {
1101 lpos_start_time
= lttv_traceset_context_position_get_time(
1102 event_request_lpos
->start_position
);
1105 /* 1.1.3 If lpos.start time < ltime */
1106 if(event_request_lpos
!= NULL
1107 && event_request_lpos
->start_position
!= NULL
1108 && ltt_time_compare(lpos_start_time
,
1109 event_request_ltime
->start_time
)<0) {
1110 /* Add lpos to list_in, remove them from list_out */
1111 for(iter
=lpos
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
1112 /* Add to list_in */
1113 EventsRequest
*event_request_lpos
=
1114 (EventsRequest
*)iter
->data
;
1116 list_in
= g_slist_append(list_in
, event_request_lpos
);
1117 /* Remove from list_out */
1118 list_out
= g_slist_remove(list_out
, event_request_lpos
);
1121 /* 1.1.4 (lpos.start time >= ltime) */
1122 /* Add ltime to list_in, remove them from list_out */
1124 for(iter
=ltime
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
1125 /* Add to list_in */
1126 EventsRequest
*event_request_ltime
=
1127 (EventsRequest
*)iter
->data
;
1129 list_in
= g_slist_append(list_in
, event_request_ltime
);
1130 /* Remove from list_out */
1131 list_out
= g_slist_remove(list_out
, event_request_ltime
);
1136 g_slist_free(ltime
);
1141 tfc
= lttv_traceset_context_get_current_tfc(tsc
);
1142 g_assert(g_slist_length(list_in
)>0);
1143 EventsRequest
*events_request
= g_slist_nth_data(list_in
, 0);
1146 /* 1.2.1 If first request in list_in is a time request */
1147 if(events_request
->start_position
== NULL
) {
1148 /* - If first req in list_in start time != current time */
1149 if(tfc
== NULL
|| ltt_time_compare(events_request
->start_time
,
1150 tfc
->timestamp
) != 0)
1151 /* - Seek to that time */
1152 g_debug("SEEK TIME : %lu, %lu", events_request
->start_time
.tv_sec
,
1153 events_request
->start_time
.tv_nsec
);
1154 //lttv_process_traceset_seek_time(tsc, events_request->start_time);
1155 lttv_state_traceset_seek_time_closest(LTTV_TRACESET_STATE(tsc
),
1156 events_request
->start_time
);
1158 /* Process the traceset with only state hooks */
1160 lttv_process_traceset_middle(tsc
,
1161 events_request
->start_time
,
1164 g_assert(seek_count
< LTTV_STATE_SAVE_INTERVAL
);
1170 LttvTracefileContext
*tfc
=
1171 lttv_traceset_context_get_current_tfc(tsc
);
1172 /* Else, the first request in list_in is a position request */
1173 /* If first req in list_in pos != current pos */
1174 g_assert(events_request
->start_position
!= NULL
);
1175 g_debug("SEEK POS time : %lu, %lu",
1176 lttv_traceset_context_position_get_time(
1177 events_request
->start_position
).tv_sec
,
1178 lttv_traceset_context_position_get_time(
1179 events_request
->start_position
).tv_nsec
);
1182 g_debug("SEEK POS context time : %lu, %lu",
1183 tfc
->timestamp
.tv_sec
,
1184 tfc
->timestamp
.tv_nsec
);
1186 g_debug("SEEK POS context time : %lu, %lu",
1187 ltt_time_infinite
.tv_sec
,
1188 ltt_time_infinite
.tv_nsec
);
1190 g_assert(events_request
->start_position
!= NULL
);
1191 if(lttv_traceset_context_ctx_pos_compare(tsc
,
1192 events_request
->start_position
) != 0) {
1193 /* 1.2.2.1 Seek to that position */
1194 g_debug("SEEK POSITION");
1195 //lttv_process_traceset_seek_position(tsc, events_request->start_position);
1196 pos_time
= lttv_traceset_context_position_get_time(
1197 events_request
->start_position
);
1199 lttv_state_traceset_seek_time_closest(LTTV_TRACESET_STATE(tsc
),
1202 /* Process the traceset with only state hooks */
1204 lttv_process_traceset_middle(tsc
,
1207 events_request
->start_position
);
1208 g_assert(lttv_traceset_context_ctx_pos_compare(tsc
,
1209 events_request
->start_position
) == 0);
1216 /* 1.3 Add hooks and call before request for all list_in members */
1218 GSList
*iter
= NULL
;
1220 for(iter
=list_in
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
1221 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1222 /* 1.3.1 If !servicing */
1223 if(events_request
->servicing
== FALSE
) {
1224 /* - begin request hooks called
1225 * - servicing = TRUE
1227 lttv_hooks_call(events_request
->before_request
, (gpointer
)tsc
);
1228 events_request
->servicing
= TRUE
;
1230 /* 1.3.2 call before chunk
1231 * 1.3.3 events hooks added
1233 if(events_request
->trace
== -1)
1234 lttv_process_traceset_begin(tsc
,
1235 events_request
->before_chunk_traceset
,
1236 events_request
->before_chunk_trace
,
1237 events_request
->before_chunk_tracefile
,
1238 events_request
->event
,
1239 events_request
->event_by_id_channel
);
1241 guint nb_trace
= lttv_traceset_number(tsc
->ts
);
1242 g_assert((guint
)events_request
->trace
< nb_trace
&&
1243 events_request
->trace
> -1);
1244 LttvTraceContext
*tc
= tsc
->traces
[events_request
->trace
];
1246 lttv_hooks_call(events_request
->before_chunk_traceset
, tsc
);
1248 lttv_trace_context_add_hooks(tc
,
1249 events_request
->before_chunk_trace
,
1250 events_request
->before_chunk_tracefile
,
1251 events_request
->event
,
1252 events_request
->event_by_id_channel
);
1257 /* 2. Else, list_in is not empty, we continue a read */
1260 /* 2.0 For each req of list_in */
1261 GSList
*iter
= list_in
;
1263 while(iter
!= NULL
) {
1265 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1267 /* - Call before chunk
1268 * - events hooks added
1270 if(events_request
->trace
== -1)
1271 lttv_process_traceset_begin(tsc
,
1272 events_request
->before_chunk_traceset
,
1273 events_request
->before_chunk_trace
,
1274 events_request
->before_chunk_tracefile
,
1275 events_request
->event
,
1276 events_request
->event_by_id_channel
);
1278 guint nb_trace
= lttv_traceset_number(tsc
->ts
);
1279 g_assert((guint
)events_request
->trace
< nb_trace
&&
1280 events_request
->trace
> -1);
1281 LttvTraceContext
*tc
= tsc
->traces
[events_request
->trace
];
1283 lttv_hooks_call(events_request
->before_chunk_traceset
, tsc
);
1285 lttv_trace_context_add_hooks(tc
,
1286 events_request
->before_chunk_trace
,
1287 events_request
->before_chunk_tracefile
,
1288 events_request
->event
,
1289 events_request
->event_by_id_channel
);
1292 iter
= g_slist_next(iter
);
1297 tfc
= lttv_traceset_context_get_current_tfc(tsc
);
1299 /* 2.1 For each req of list_out */
1300 GSList
*iter
= list_out
;
1302 while(iter
!= NULL
) {
1304 gboolean remove
= FALSE
;
1305 gboolean free_data
= FALSE
;
1306 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1308 /* if req.start time == current context time
1309 * or req.start position == current position*/
1310 if( ltt_time_compare(events_request
->start_time
,
1311 tfc
->timestamp
) == 0
1313 (events_request
->start_position
!= NULL
1315 lttv_traceset_context_ctx_pos_compare(tsc
,
1316 events_request
->start_position
) == 0)
1318 /* - Add to list_in, remove from list_out */
1319 list_in
= g_slist_append(list_in
, events_request
);
1323 /* - If !servicing */
1324 if(events_request
->servicing
== FALSE
) {
1325 /* - begin request hooks called
1326 * - servicing = TRUE
1328 lttv_hooks_call(events_request
->before_request
, (gpointer
)tsc
);
1329 events_request
->servicing
= TRUE
;
1331 /* call before chunk
1332 * events hooks added
1334 if(events_request
->trace
== -1)
1335 lttv_process_traceset_begin(tsc
,
1336 events_request
->before_chunk_traceset
,
1337 events_request
->before_chunk_trace
,
1338 events_request
->before_chunk_tracefile
,
1339 events_request
->event
,
1340 events_request
->event_by_id_channel
);
1342 guint nb_trace
= lttv_traceset_number(tsc
->ts
);
1343 g_assert((guint
)events_request
->trace
< nb_trace
&&
1344 events_request
->trace
> -1);
1345 LttvTraceContext
*tc
= tsc
->traces
[events_request
->trace
];
1347 lttv_hooks_call(events_request
->before_chunk_traceset
, tsc
);
1349 lttv_trace_context_add_hooks(tc
,
1350 events_request
->before_chunk_trace
,
1351 events_request
->before_chunk_tracefile
,
1352 events_request
->event
,
1353 events_request
->event_by_id_channel
);
1362 GSList
*remove_iter
= iter
;
1364 iter
= g_slist_next(iter
);
1365 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
1366 list_out
= g_slist_remove_link(list_out
, remove_iter
);
1367 } else { // not remove
1368 iter
= g_slist_next(iter
);
1374 /* 3. Find end criterions */
1379 /* 3.1.1 Find lowest end time in list_in */
1380 g_assert(g_slist_length(list_in
)>0);
1381 end_time
= ((EventsRequest
*)g_slist_nth_data(list_in
,0))->end_time
;
1383 for(iter
=g_slist_nth(list_in
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
1384 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1386 if(ltt_time_compare(events_request
->end_time
,
1388 end_time
= events_request
->end_time
;
1391 /* 3.1.2 Find lowest start time in list_out */
1392 for(iter
=list_out
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
1393 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1395 if(ltt_time_compare(events_request
->start_time
,
1397 end_time
= events_request
->start_time
;
1402 /* 3.2 Number of events */
1404 /* 3.2.1 Find lowest number of events in list_in */
1407 end_nb_events
= ((EventsRequest
*)g_slist_nth_data(list_in
,0))->num_events
;
1409 for(iter
=g_slist_nth(list_in
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
1410 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1412 if(events_request
->num_events
< end_nb_events
)
1413 end_nb_events
= events_request
->num_events
;
1416 /* 3.2.2 Use min(CHUNK_NUM_EVENTS, min num events in list_in) as
1419 end_nb_events
= MIN(CHUNK_NUM_EVENTS
, end_nb_events
);
1423 /* 3.3 End position */
1425 /* 3.3.1 Find lowest end position in list_in */
1428 end_position
=((EventsRequest
*)g_slist_nth_data(list_in
,0))->end_position
;
1430 for(iter
=g_slist_nth(list_in
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
1431 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1433 if(events_request
->end_position
!= NULL
&& end_position
!= NULL
&&
1434 lttv_traceset_context_pos_pos_compare(events_request
->end_position
,
1436 end_position
= events_request
->end_position
;
1441 /* 3.3.2 Find lowest start position in list_out */
1444 for(iter
=list_out
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
1445 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1447 if(events_request
->end_position
!= NULL
&& end_position
!= NULL
&&
1448 lttv_traceset_context_pos_pos_compare(events_request
->end_position
,
1450 end_position
= events_request
->end_position
;
1455 /* 4. Call process traceset middle */
1456 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
);
1457 count
= lttv_process_traceset_middle(tsc
, end_time
, end_nb_events
, end_position
);
1459 tfc
= lttv_traceset_context_get_current_tfc(tsc
);
1461 g_debug("Context time after middle : %lu, %lu", tfc
->timestamp
.tv_sec
,
1462 tfc
->timestamp
.tv_nsec
);
1464 g_debug("End of trace reached after middle.");
1468 /* 5. After process traceset middle */
1469 tfc
= lttv_traceset_context_get_current_tfc(tsc
);
1471 /* - if current context time > traceset.end time */
1472 if(tfc
== NULL
|| ltt_time_compare(tfc
->timestamp
,
1473 tsc
->time_span
.end_time
) > 0) {
1474 /* - For each req in list_in */
1475 GSList
*iter
= list_in
;
1477 while(iter
!= NULL
) {
1479 gboolean remove
= FALSE
;
1480 gboolean free_data
= FALSE
;
1481 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1483 /* - Remove events hooks for req
1484 * - Call end chunk for req
1487 if(events_request
->trace
== -1)
1488 lttv_process_traceset_end(tsc
,
1489 events_request
->after_chunk_traceset
,
1490 events_request
->after_chunk_trace
,
1491 events_request
->after_chunk_tracefile
,
1492 events_request
->event
,
1493 events_request
->event_by_id_channel
);
1496 guint nb_trace
= lttv_traceset_number(tsc
->ts
);
1497 g_assert(events_request
->trace
< nb_trace
&&
1498 events_request
->trace
> -1);
1499 LttvTraceContext
*tc
= tsc
->traces
[events_request
->trace
];
1501 lttv_trace_context_remove_hooks(tc
,
1502 events_request
->after_chunk_trace
,
1503 events_request
->after_chunk_tracefile
,
1504 events_request
->event
,
1505 events_request
->event_by_id_channel
);
1506 lttv_hooks_call(events_request
->after_chunk_traceset
, tsc
);
1511 /* - Call end request for req */
1512 lttv_hooks_call(events_request
->after_request
, (gpointer
)tsc
);
1514 /* - remove req from list_in */
1515 /* Destroy the request */
1522 GSList
*remove_iter
= iter
;
1524 iter
= g_slist_next(iter
);
1525 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
1526 list_in
= g_slist_remove_link(list_in
, remove_iter
);
1527 } else { // not remove
1528 iter
= g_slist_next(iter
);
1533 /* 5.1 For each req in list_in */
1534 GSList
*iter
= list_in
;
1536 while(iter
!= NULL
) {
1538 gboolean remove
= FALSE
;
1539 gboolean free_data
= FALSE
;
1540 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1542 /* - Remove events hooks for req
1543 * - Call end chunk for req
1545 if(events_request
->trace
== -1)
1546 lttv_process_traceset_end(tsc
,
1547 events_request
->after_chunk_traceset
,
1548 events_request
->after_chunk_trace
,
1549 events_request
->after_chunk_tracefile
,
1550 events_request
->event
,
1551 events_request
->event_by_id_channel
);
1554 guint nb_trace
= lttv_traceset_number(tsc
->ts
);
1555 g_assert(events_request
->trace
< nb_trace
&&
1556 events_request
->trace
> -1);
1557 LttvTraceContext
*tc
= tsc
->traces
[events_request
->trace
];
1559 lttv_trace_context_remove_hooks(tc
,
1560 events_request
->after_chunk_trace
,
1561 events_request
->after_chunk_tracefile
,
1562 events_request
->event
,
1563 events_request
->event_by_id_channel
);
1565 lttv_hooks_call(events_request
->after_chunk_traceset
, tsc
);
1568 /* - req.num -= count */
1569 g_assert(events_request
->num_events
>= count
);
1570 events_request
->num_events
-= count
;
1572 g_assert(tfc
!= NULL
);
1573 /* - if req.num == 0
1575 * current context time >= req.end time
1577 * req.end pos == current pos
1579 * req.stop_flag == TRUE
1581 if( events_request
->num_events
== 0
1583 events_request
->stop_flag
== TRUE
1585 ltt_time_compare(tfc
->timestamp
,
1586 events_request
->end_time
) >= 0
1588 (events_request
->end_position
!= NULL
1590 lttv_traceset_context_ctx_pos_compare(tsc
,
1591 events_request
->end_position
) == 0)
1594 g_assert(events_request
->servicing
== TRUE
);
1595 /* - Call end request for req
1596 * - remove req from list_in */
1597 lttv_hooks_call(events_request
->after_request
, (gpointer
)tsc
);
1598 /* - remove req from list_in */
1599 /* Destroy the request */
1607 GSList
*remove_iter
= iter
;
1609 iter
= g_slist_next(iter
);
1610 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
1611 list_in
= g_slist_remove_link(list_in
, remove_iter
);
1612 } else { // not remove
1613 iter
= g_slist_next(iter
);
1619 /* End of removed servicing loop : leave control to GTK instead. */
1620 // if(gtk_events_pending()) break;
1623 /* B. When interrupted between chunks */
1626 GSList
*iter
= list_in
;
1628 /* 1. for each request in list_in */
1629 while(iter
!= NULL
) {
1631 gboolean remove
= FALSE
;
1632 gboolean free_data
= FALSE
;
1633 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1635 /* 1.1. Use current postition as start position */
1636 if(events_request
->start_position
!= NULL
)
1637 lttv_traceset_context_position_destroy(events_request
->start_position
);
1638 events_request
->start_position
= lttv_traceset_context_position_new(tsc
);
1639 lttv_traceset_context_position_save(tsc
, events_request
->start_position
);
1641 /* 1.2. Remove start time */
1642 events_request
->start_time
= ltt_time_infinite
;
1644 /* 1.3. Move from list_in to list_out */
1647 list_out
= g_slist_append(list_out
, events_request
);
1652 GSList
*remove_iter
= iter
;
1654 iter
= g_slist_next(iter
);
1655 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
1656 list_in
= g_slist_remove_link(list_in
, remove_iter
);
1657 } else { // not remove
1658 iter
= g_slist_next(iter
);
1664 /* C Unlock Traces */
1666 lttv_process_traceset_get_sync_data(tsc
);
1667 //lttv_traceset_context_position_save(tsc, sync_position);
1672 iter_trace
<lttv_traceset_number(tsc
->ts
);
1674 LttvTrace
*trace_v
= lttv_traceset_get(tsc
->ts
, iter_trace
);
1676 lttvwindowtraces_unlock(trace_v
);
1680 //set the cursor back to normal
1681 gdk_window_set_cursor(win
, NULL
);
1684 g_assert(g_slist_length(list_in
) == 0);
1686 if( g_slist_length(list_out
) == 0 ) {
1687 /* Put tab's request pending flag back to normal */
1688 tab
->events_request_pending
= FALSE
;
1689 g_debug("remove the idle fct");
1690 return FALSE
; /* Remove the idle function */
1692 g_debug("leave the idle fct");
1693 return TRUE
; /* Leave the idle function */
1695 /* We do not use simili-round-robin, it may require to read 1 meg buffers
1696 * again and again if many tracesets use the same tracefiles. */
1697 /* Hack for round-robin idle functions */
1698 /* It will put the idle function at the end of the pool */
1699 /*g_idle_add_full((G_PRIORITY_HIGH_IDLE + 21),
1700 (GSourceFunc)execute_events_requests,
1710 static void lttvwindow_add_trace(Tab
*tab
, LttvTrace
*trace_v
)
1712 LttvTraceset
*traceset
= tab
->traceset_info
->traceset
;
1714 guint num_traces
= lttv_traceset_number(traceset
);
1716 //Verify if trace is already present.
1717 for(i
=0; i
<num_traces
; i
++)
1719 LttvTrace
* trace
= lttv_traceset_get(traceset
, i
);
1720 if(trace
== trace_v
)
1724 //Keep a reference to the traces so they are not freed.
1725 for(i
=0; i
<lttv_traceset_number(traceset
); i
++)
1727 LttvTrace
* trace
= lttv_traceset_get(traceset
, i
);
1728 lttv_trace_ref(trace
);
1731 //remove state update hooks
1732 lttv_state_remove_event_hooks(
1733 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1735 lttv_context_fini(LTTV_TRACESET_CONTEXT(
1736 tab
->traceset_info
->traceset_context
));
1737 g_object_unref(tab
->traceset_info
->traceset_context
);
1739 lttv_traceset_add(traceset
, trace_v
);
1740 lttv_trace_ref(trace_v
); /* local ref */
1742 /* Create new context */
1743 tab
->traceset_info
->traceset_context
=
1744 g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
1746 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->
1751 //add state update hooks
1752 lttv_state_add_event_hooks(
1753 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1754 //Remove local reference to the traces.
1755 for(i
=0; i
<lttv_traceset_number(traceset
); i
++)
1757 LttvTrace
* trace
= lttv_traceset_get(traceset
, i
);
1758 lttv_trace_unref(trace
);
1762 //add_trace_into_traceset_selector(GTK_MULTIVPANED(tab->multivpaned), lttv_trace(trace_v));
1765 /* add_trace adds a trace into the current traceset. It first displays a
1766 * directory selection dialogue to let user choose a trace, then recreates
1767 * tracset_context, and redraws all the viewer of the current tab
1770 void add_trace(GtkWidget
* widget
, gpointer user_data
)
1773 LttvTrace
* trace_v
;
1774 LttvTraceset
* traceset
;
1776 char abs_path
[PATH_MAX
];
1778 MainWindow
* mw_data
= get_window_data_struct(widget
);
1779 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
1781 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
1782 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
1783 LttvPluginTab
*ptab
;
1787 ptab
= create_new_tab(widget
, NULL
);
1790 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
1794 //GtkDirSelection * file_selector = (GtkDirSelection *)gtk_dir_selection_new("Select a trace");
1795 GtkFileSelection
* file_selector
= (GtkFileSelection
*)gtk_file_selection_new("Select a trace");
1796 gtk_widget_hide( (file_selector
)->file_list
->parent
) ;
1797 gtk_file_selection_hide_fileop_buttons(file_selector
);
1798 gtk_window_set_transient_for(GTK_WINDOW(file_selector
),
1799 GTK_WINDOW(mw_data
->mwindow
));
1801 if(remember_trace_dir
[0] != '\0')
1802 gtk_file_selection_set_filename(file_selector
, remember_trace_dir
);
1804 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
1806 case GTK_RESPONSE_ACCEPT
:
1807 case GTK_RESPONSE_OK
:
1808 dir
= gtk_file_selection_get_filename (file_selector
);
1809 strncpy(remember_trace_dir
, dir
, PATH_MAX
);
1810 strncat(remember_trace_dir
, "/", PATH_MAX
);
1811 if(!dir
|| strlen(dir
) == 0){
1812 gtk_widget_destroy((GtkWidget
*)file_selector
);
1815 get_absolute_pathname(dir
, abs_path
);
1816 trace_v
= lttvwindowtraces_get_trace_by_name(abs_path
);
1817 if(trace_v
== NULL
) {
1818 trace
= ltt_trace_open(abs_path
);
1820 g_warning("cannot open trace %s", abs_path
);
1822 GtkWidget
*dialogue
=
1823 gtk_message_dialog_new(
1824 GTK_WINDOW(gtk_widget_get_toplevel(widget
)),
1825 GTK_DIALOG_MODAL
|GTK_DIALOG_DESTROY_WITH_PARENT
,
1828 "Cannot open trace : maybe you should enter in the trace "
1829 "directory to select it ?");
1830 gtk_dialog_run(GTK_DIALOG(dialogue
));
1831 gtk_widget_destroy(dialogue
);
1834 trace_v
= lttv_trace_new(trace
);
1835 lttvwindowtraces_add_trace(trace_v
);
1836 lttvwindow_add_trace(tab
, trace_v
);
1839 lttvwindow_add_trace(tab
, trace_v
);
1842 gtk_widget_destroy((GtkWidget
*)file_selector
);
1844 //update current tab
1845 //update_traceset(mw_data);
1847 /* Call the updatetraceset hooks */
1849 traceset
= tab
->traceset_info
->traceset
;
1850 SetTraceset(tab
, traceset
);
1851 // in expose now call_pending_read_hooks(mw_data);
1853 //lttvwindow_report_current_time(mw_data,&(tab->current_time));
1855 case GTK_RESPONSE_REJECT
:
1856 case GTK_RESPONSE_CANCEL
:
1858 gtk_widget_destroy((GtkWidget
*)file_selector
);
1863 /* remove_trace removes a trace from the current traceset if all viewers in
1864 * the current tab are not interested in the trace. It first displays a
1865 * dialogue, which shows all traces in the current traceset, to let user choose
1866 * a trace, then it checks if all viewers unselect the trace, if it is true,
1867 * it will remove the trace, recreate the traceset_contex,
1868 * and redraws all the viewer of the current tab. If there is on trace in the
1869 * current traceset, it will delete all viewers of the current tab
1871 * It destroys the filter tree. FIXME... we should request for an update
1875 void remove_trace(GtkWidget
*widget
, gpointer user_data
)
1878 LttvTrace
* trace_v
;
1879 LttvTraceset
* traceset
;
1880 gint i
, j
, nb_trace
, index
=-1;
1881 char ** name
, *remove_trace_name
;
1882 MainWindow
* mw_data
= get_window_data_struct(widget
);
1883 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
1885 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
1886 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
1892 LttvPluginTab
*ptab
;
1893 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
1897 nb_trace
=lttv_traceset_number(tab
->traceset_info
->traceset
);
1898 name
= g_new(char*,nb_trace
);
1899 for(i
= 0; i
< nb_trace
; i
++){
1900 trace_v
= lttv_traceset_get(tab
->traceset_info
->traceset
, i
);
1901 trace
= lttv_trace(trace_v
);
1902 name
[i
] = g_quark_to_string(ltt_trace_name(trace
));
1905 remove_trace_name
= get_remove_trace(mw_data
, name
, nb_trace
);
1908 if(remove_trace_name
){
1910 /* yuk, cut n paste from old code.. should be better (MD)*/
1911 for(i
= 0; i
<nb_trace
; i
++) {
1912 if(strcmp(remove_trace_name
,name
[i
]) == 0){
1917 traceset
= tab
->traceset_info
->traceset
;
1918 //Keep a reference to the traces so they are not freed.
1919 for(j
=0; j
<lttv_traceset_number(traceset
); j
++)
1921 LttvTrace
* trace
= lttv_traceset_get(traceset
, j
);
1922 lttv_trace_ref(trace
);
1925 //remove state update hooks
1926 lttv_state_remove_event_hooks(
1927 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1928 lttv_context_fini(LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
));
1929 g_object_unref(tab
->traceset_info
->traceset_context
);
1931 trace_v
= lttv_traceset_get(traceset
, index
);
1933 lttv_traceset_remove(traceset
, index
);
1934 lttv_trace_unref(trace_v
); // Remove local reference
1936 if(lttv_trace_get_ref_number(trace_v
) <= 1) {
1937 /* ref 1 : lttvwindowtraces only*/
1938 ltt_trace_close(lttv_trace(trace_v
));
1939 /* lttvwindowtraces_remove_trace takes care of destroying
1940 * the traceset linked with the trace_v and also of destroying
1941 * the trace_v at the same time.
1943 lttvwindowtraces_remove_trace(trace_v
);
1946 tab
->traceset_info
->traceset_context
=
1947 g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
1949 LTTV_TRACESET_CONTEXT(tab
->
1950 traceset_info
->traceset_context
),traceset
);
1951 //add state update hooks
1952 lttv_state_add_event_hooks(
1953 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1955 //Remove local reference to the traces.
1956 for(j
=0; j
<lttv_traceset_number(traceset
); j
++)
1958 LttvTrace
* trace
= lttv_traceset_get(traceset
, j
);
1959 lttv_trace_unref(trace
);
1962 SetTraceset(tab
, (gpointer
)traceset
);
1968 void remove_trace(GtkWidget
* widget
, gpointer user_data
)
1971 LttvTrace
* trace_v
;
1972 LttvTraceset
* traceset
;
1973 gint i
, j
, nb_trace
;
1974 char ** name
, *remove_trace_name
;
1975 MainWindow
* mw_data
= get_window_data_struct(widget
);
1976 LttvTracesetSelector
* s
;
1977 LttvTraceSelector
* t
;
1980 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
1982 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
1983 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
1989 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
1992 nb_trace
=lttv_traceset_number(tab
->traceset_info
->traceset
);
1993 name
= g_new(char*,nb_trace
);
1994 for(i
= 0; i
< nb_trace
; i
++){
1995 trace_v
= lttv_traceset_get(tab
->traceset_info
->traceset
, i
);
1996 trace
= lttv_trace(trace_v
);
1997 name
[i
] = ltt_trace_name(trace
);
2000 remove_trace_name
= get_remove_trace(name
, nb_trace
);
2002 if(remove_trace_name
){
2003 for(i
=0; i
<nb_trace
; i
++){
2004 if(strcmp(remove_trace_name
,name
[i
]) == 0){
2005 //unselect the trace from the current viewer
2007 w
= gtk_multivpaned_get_widget(GTK_MULTIVPANED(tab
->multivpaned
));
2009 s
= g_object_get_data(G_OBJECT(w
), "Traceset_Selector");
2011 t
= lttv_traceset_selector_trace_get(s
,i
);
2012 lttv_trace_selector_set_selected(t
, FALSE
);
2015 //check if other viewers select the trace
2016 w
= gtk_multivpaned_get_first_widget(GTK_MULTIVPANED(tab
->multivpaned
));
2018 s
= g_object_get_data(G_OBJECT(w
), "Traceset_Selector");
2020 t
= lttv_traceset_selector_trace_get(s
,i
);
2021 selected
= lttv_trace_selector_get_selected(t
);
2024 w
= gtk_multivpaned_get_next_widget(GTK_MULTIVPANED(tab
->multivpaned
));
2026 }else selected
= FALSE
;
2028 //if no viewer selects the trace, remove it
2030 remove_trace_from_traceset_selector(GTK_MULTIVPANED(tab
->multivpaned
), i
);
2032 traceset
= tab
->traceset_info
->traceset
;
2033 //Keep a reference to the traces so they are not freed.
2034 for(j
=0; j
<lttv_traceset_number(traceset
); j
++)
2036 LttvTrace
* trace
= lttv_traceset_get(traceset
, j
);
2037 lttv_trace_ref(trace
);
2040 //remove state update hooks
2041 lttv_state_remove_event_hooks(
2042 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
2043 lttv_context_fini(LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
));
2044 g_object_unref(tab
->traceset_info
->traceset_context
);
2047 trace_v
= lttv_traceset_get(traceset
, i
);
2049 if(lttv_trace_get_ref_number(trace_v
) <= 2) {
2050 /* ref 2 : traceset, local */
2051 lttvwindowtraces_remove_trace(trace_v
);
2052 ltt_trace_close(lttv_trace(trace_v
));
2055 lttv_traceset_remove(traceset
, i
);
2056 lttv_trace_unref(trace_v
); // Remove local reference
2058 if(!lttv_trace_get_ref_number(trace_v
))
2059 lttv_trace_destroy(trace_v
);
2061 tab
->traceset_info
->traceset_context
=
2062 g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
2064 LTTV_TRACESET_CONTEXT(tab
->
2065 traceset_info
->traceset_context
),traceset
);
2066 //add state update hooks
2067 lttv_state_add_event_hooks(
2068 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
2070 //Remove local reference to the traces.
2071 for(j
=0; j
<lttv_traceset_number(traceset
); j
++)
2073 LttvTrace
* trace
= lttv_traceset_get(traceset
, j
);
2074 lttv_trace_unref(trace
);
2078 //update current tab
2079 //update_traceset(mw_data);
2082 SetTraceset(tab
, (gpointer
)traceset
);
2083 // in expose now call_pending_read_hooks(mw_data);
2085 //lttvwindow_report_current_time(mw_data,&(tab->current_time));
2088 // while(tab->multi_vpaned->num_children){
2089 // gtk_multi_vpaned_widget_delete(tab->multi_vpaned);
2103 /* Redraw all the viewers in the current tab */
2104 void redraw(GtkWidget
*widget
, gpointer user_data
)
2106 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
2107 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2108 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2115 LttvPluginTab
*ptab
;
2116 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
2121 LttvAttributeValue value
;
2123 retval
= lttv_iattribute_find_by_path(tab
->attributes
, "hooks/redraw", LTTV_POINTER
, &value
);
2126 tmp
= (LttvHooks
*)*(value
.v_pointer
);
2128 lttv_hooks_call(tmp
,NULL
);
2132 void continue_processing(GtkWidget
*widget
, gpointer user_data
)
2134 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
2135 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2136 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2143 LttvPluginTab
*ptab
;
2144 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
2149 LttvAttributeValue value
;
2151 retval
= lttv_iattribute_find_by_path(tab
->attributes
, "hooks/continue",
2152 LTTV_POINTER
, &value
);
2155 tmp
= (LttvHooks
*)*(value
.v_pointer
);
2157 lttv_hooks_call(tmp
,NULL
);
2160 /* Stop the processing for the calling main window's current tab.
2161 * It removes every processing requests that are in its list. It does not call
2162 * the end request hooks, because the request is not finished.
2165 void stop_processing(GtkWidget
*widget
, gpointer user_data
)
2167 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
2168 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2169 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2174 LttvPluginTab
*ptab
;
2175 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
2178 GSList
*iter
= tab
->events_requests
;
2180 while(iter
!= NULL
) {
2181 GSList
*remove_iter
= iter
;
2182 iter
= g_slist_next(iter
);
2184 g_free(remove_iter
->data
);
2185 tab
->events_requests
=
2186 g_slist_remove_link(tab
->events_requests
, remove_iter
);
2188 tab
->events_request_pending
= FALSE
;
2189 tab
->stop_foreground
= TRUE
;
2190 g_idle_remove_by_data(tab
);
2191 g_assert(g_slist_length(tab
->events_requests
) == 0);
2195 /* save will save the traceset to a file
2196 * Not implemented yet FIXME
2199 void save(GtkWidget
* widget
, gpointer user_data
)
2204 void save_as(GtkWidget
* widget
, gpointer user_data
)
2206 g_info("Save as\n");
2210 /* zoom will change the time_window of all the viewers of the
2211 * current tab, and redisplay them. The main functionality is to
2212 * determine the new time_window of the current tab
2215 void zoom(GtkWidget
* widget
, double size
)
2217 TimeInterval time_span
;
2218 TimeWindow new_time_window
;
2219 LttTime current_time
, time_delta
;
2220 MainWindow
* mw_data
= get_window_data_struct(widget
);
2221 LttvTracesetContext
*tsc
;
2222 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
2224 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2225 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2231 LttvPluginTab
*ptab
;
2232 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
2236 if(size
== 1) return;
2238 tsc
= LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
2239 time_span
= tsc
->time_span
;
2240 new_time_window
= tab
->time_window
;
2241 current_time
= tab
->current_time
;
2243 time_delta
= ltt_time_sub(time_span
.end_time
,time_span
.start_time
);
2245 new_time_window
.start_time
= time_span
.start_time
;
2246 new_time_window
.time_width
= time_delta
;
2247 new_time_window
.time_width_double
= ltt_time_to_double(time_delta
);
2248 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
2249 new_time_window
.time_width
) ;
2251 new_time_window
.time_width
= ltt_time_div(new_time_window
.time_width
, size
);
2252 new_time_window
.time_width_double
=
2253 ltt_time_to_double(new_time_window
.time_width
);
2254 if(ltt_time_compare(new_time_window
.time_width
,time_delta
) > 0)
2255 { /* Case where zoom out is bigger than trace length */
2256 new_time_window
.start_time
= time_span
.start_time
;
2257 new_time_window
.time_width
= time_delta
;
2258 new_time_window
.time_width_double
= ltt_time_to_double(time_delta
);
2259 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
2260 new_time_window
.time_width
) ;
2264 /* Center the image on the current time */
2265 new_time_window
.start_time
=
2266 ltt_time_sub(current_time
,
2267 ltt_time_from_double(new_time_window
.time_width_double
/2.0));
2268 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
2269 new_time_window
.time_width
) ;
2270 /* If on borders, don't fall off */
2271 if(ltt_time_compare(new_time_window
.start_time
, time_span
.start_time
) <0
2272 || ltt_time_compare(new_time_window
.start_time
, time_span
.end_time
) >0)
2274 new_time_window
.start_time
= time_span
.start_time
;
2275 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
2276 new_time_window
.time_width
) ;
2280 if(ltt_time_compare(new_time_window
.end_time
,
2281 time_span
.end_time
) > 0
2282 || ltt_time_compare(new_time_window
.end_time
,
2283 time_span
.start_time
) < 0)
2285 new_time_window
.start_time
=
2286 ltt_time_sub(time_span
.end_time
, new_time_window
.time_width
);
2288 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
2289 new_time_window
.time_width
) ;
2296 if(ltt_time_compare(new_time_window
.time_width
, ltt_time_zero
) == 0) {
2297 g_warning("Zoom more than 1 ns impossible");
2299 time_change_manager(tab
, new_time_window
);
2303 void zoom_in(GtkWidget
* widget
, gpointer user_data
)
2308 void zoom_out(GtkWidget
* widget
, gpointer user_data
)
2313 void zoom_extended(GtkWidget
* widget
, gpointer user_data
)
2318 void go_to_time(GtkWidget
* widget
, gpointer user_data
)
2320 g_info("Go to time\n");
2323 void show_time_frame(GtkWidget
* widget
, gpointer user_data
)
2325 g_info("Show time frame\n");
2329 /* callback function */
2332 on_empty_traceset_activate (GtkMenuItem
*menuitem
,
2335 create_new_window((GtkWidget
*)menuitem
, user_data
, FALSE
);
2340 on_clone_traceset_activate (GtkMenuItem
*menuitem
,
2343 create_new_window((GtkWidget
*)menuitem
, user_data
, TRUE
);
2347 /* create_new_tab calls create_tab to construct a new tab in the main window
2350 LttvPluginTab
*create_new_tab(GtkWidget
* widget
, gpointer user_data
)
2352 gchar label
[PATH_MAX
];
2353 MainWindow
* mw_data
= get_window_data_struct(widget
);
2355 GtkNotebook
* notebook
= (GtkNotebook
*)lookup_widget(widget
, "MNotebook");
2356 if(notebook
== NULL
){
2357 g_info("Notebook does not exist\n");
2360 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2361 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2367 LttvPluginTab
*ptab
;
2368 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
2369 copy_tab
= ptab
->tab
;
2372 strcpy(label
,"Page");
2373 if(get_label(mw_data
, label
,"Get the name of the tab","Please input tab's name")) {
2374 LttvPluginTab
*ptab
;
2376 ptab
= g_object_new(LTTV_TYPE_PLUGIN_TAB
, NULL
);
2377 init_tab (ptab
->tab
, mw_data
, copy_tab
, notebook
, label
);
2378 ptab
->parent
.top_widget
= ptab
->tab
->top_widget
;
2379 g_object_set_data_full(
2380 G_OBJECT(ptab
->tab
->vbox
),
2383 (GDestroyNotify
)tab_destructor
);
2390 on_tab_activate (GtkMenuItem
*menuitem
,
2393 create_new_tab((GtkWidget
*)menuitem
, user_data
);
2398 on_open_activate (GtkMenuItem
*menuitem
,
2401 open_traceset((GtkWidget
*)menuitem
, user_data
);
2406 on_close_activate (GtkMenuItem
*menuitem
,
2409 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2410 main_window_destructor(mw_data
);
2414 /* remove the current tab from the main window
2418 on_close_tab_activate (GtkWidget
*widget
,
2422 GtkWidget
* notebook
;
2424 MainWindow
* mw_data
= get_window_data_struct(widget
);
2425 notebook
= lookup_widget(widget
, "MNotebook");
2426 if(notebook
== NULL
){
2427 g_info("Notebook does not exist\n");
2431 page_num
= gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
));
2433 gtk_notebook_remove_page(GTK_NOTEBOOK(notebook
), page_num
);
2438 on_close_tab_X_clicked (GtkWidget
*widget
,
2442 GtkWidget
*notebook
= lookup_widget(widget
, "MNotebook");
2443 if(notebook
== NULL
){
2444 g_info("Notebook does not exist\n");
2448 if((page_num
= gtk_notebook_page_num(GTK_NOTEBOOK(notebook
), widget
)) != -1)
2449 gtk_notebook_remove_page(GTK_NOTEBOOK(notebook
), page_num
);
2455 on_add_trace_activate (GtkMenuItem
*menuitem
,
2458 add_trace((GtkWidget
*)menuitem
, user_data
);
2463 on_remove_trace_activate (GtkMenuItem
*menuitem
,
2466 remove_trace((GtkWidget
*)menuitem
, user_data
);
2471 on_save_activate (GtkMenuItem
*menuitem
,
2474 save((GtkWidget
*)menuitem
, user_data
);
2479 on_save_as_activate (GtkMenuItem
*menuitem
,
2482 save_as((GtkWidget
*)menuitem
, user_data
);
2487 on_quit_activate (GtkMenuItem
*menuitem
,
2490 while (g_slist_length(g_main_window_list
) != 0) {
2491 on_MWindow_destroy(((MainWindow
*)g_main_window_list
->data
)->mwindow
,
2498 on_cut_activate (GtkMenuItem
*menuitem
,
2506 on_copy_activate (GtkMenuItem
*menuitem
,
2514 on_paste_activate (GtkMenuItem
*menuitem
,
2522 on_delete_activate (GtkMenuItem
*menuitem
,
2530 on_zoom_in_activate (GtkMenuItem
*menuitem
,
2533 zoom_in((GtkWidget
*)menuitem
, user_data
);
2538 on_zoom_out_activate (GtkMenuItem
*menuitem
,
2541 zoom_out((GtkWidget
*)menuitem
, user_data
);
2546 on_zoom_extended_activate (GtkMenuItem
*menuitem
,
2549 zoom_extended((GtkWidget
*)menuitem
, user_data
);
2554 on_go_to_time_activate (GtkMenuItem
*menuitem
,
2557 go_to_time((GtkWidget
*)menuitem
, user_data
);
2562 on_show_time_frame_activate (GtkMenuItem
*menuitem
,
2565 show_time_frame((GtkWidget
*)menuitem
, user_data
);
2570 on_move_viewer_up_activate (GtkMenuItem
*menuitem
,
2573 move_up_viewer((GtkWidget
*)menuitem
, user_data
);
2578 on_move_viewer_down_activate (GtkMenuItem
*menuitem
,
2581 move_down_viewer((GtkWidget
*)menuitem
, user_data
);
2586 on_remove_viewer_activate (GtkMenuItem
*menuitem
,
2589 delete_viewer((GtkWidget
*)menuitem
, user_data
);
2593 on_trace_facility_activate (GtkMenuItem
*menuitem
,
2596 g_info("Trace facility selector: %s\n", "");
2600 /* Dispaly a file selection dialogue to let user select a library, then call
2601 * lttv_library_load().
2605 on_load_library_activate (GtkMenuItem
*menuitem
,
2608 GError
*error
= NULL
;
2609 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2611 gchar load_module_path_alter
[PATH_MAX
];
2615 gchar
*load_module_path
;
2616 name
= g_ptr_array_new();
2617 nb
= lttv_library_path_number();
2618 /* ask for the library path */
2622 path
= lttv_library_path_get(i
);
2623 g_ptr_array_add(name
, path
);
2626 load_module_path
= get_selection(mw_data
,
2627 (char **)(name
->pdata
), name
->len
,
2628 "Select a library path", "Library paths");
2629 if(load_module_path
!= NULL
)
2630 strncpy(load_module_path_alter
, load_module_path
, PATH_MAX
-1); // -1 for /
2632 g_ptr_array_free(name
, TRUE
);
2634 if(load_module_path
== NULL
) return;
2638 /* Make sure the module path ends with a / */
2639 gchar
*ptr
= load_module_path_alter
;
2641 ptr
= strchr(ptr
, '\0');
2643 if(*(ptr
-1) != '/') {
2650 /* Ask for the library to load : list files in the previously selected
2652 gchar str
[PATH_MAX
];
2655 GtkFileSelection
* file_selector
=
2656 (GtkFileSelection
*)gtk_file_selection_new("Select a module");
2657 gtk_file_selection_set_filename(file_selector
, load_module_path_alter
);
2658 gtk_file_selection_hide_fileop_buttons(file_selector
);
2660 gtk_window_set_transient_for(GTK_WINDOW(file_selector
),
2661 GTK_WINDOW(mw_data
->mwindow
));
2664 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
2666 case GTK_RESPONSE_ACCEPT
:
2667 case GTK_RESPONSE_OK
:
2668 dir
= gtk_file_selection_get_selections (file_selector
);
2669 strncpy(str
,dir
[0],PATH_MAX
);
2670 strncpy(remember_plugins_dir
,dir
[0],PATH_MAX
);
2671 /* only keep file name */
2673 str1
= strrchr(str
,'/');
2676 str1
= strrchr(str
,'\\');
2681 if(*str1
== 'l' && *(str1
+1)== 'i' && *(str1
+2)=='b')
2683 remove info after
. */
2687 str2
= strrchr(str2
, '.');
2688 if(str2
!= NULL
) *str2
= '\0';
2690 lttv_module_require(str1
, &error
);
2692 lttv_library_load(str1
, &error
);
2693 if(error
!= NULL
) g_warning("%s", error
->message
);
2694 else g_info("Load library: %s\n", str
);
2696 case GTK_RESPONSE_REJECT
:
2697 case GTK_RESPONSE_CANCEL
:
2699 gtk_widget_destroy((GtkWidget
*)file_selector
);
2710 /* Display all loaded modules, let user to select a module to unload
2711 * by calling lttv_module_unload
2715 on_unload_library_activate (GtkMenuItem
*menuitem
,
2718 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2720 LttvLibrary
*library
= NULL
;
2725 name
= g_ptr_array_new();
2726 nb
= lttv_library_number();
2727 LttvLibraryInfo
*lib_info
= g_new(LttvLibraryInfo
,nb
);
2728 /* ask for the library name */
2731 LttvLibrary
*iter_lib
= lttv_library_get(i
);
2732 lttv_library_info(iter_lib
, &lib_info
[i
]);
2734 gchar
*path
= lib_info
[i
].name
;
2735 g_ptr_array_add(name
, path
);
2737 lib_name
= get_selection(mw_data
, (char **)(name
->pdata
), name
->len
,
2738 "Select a library", "Libraries");
2739 if(lib_name
!= NULL
) {
2741 if(strcmp(lib_name
, lib_info
[i
].name
) == 0) {
2742 library
= lttv_library_get(i
);
2747 g_ptr_array_free(name
, TRUE
);
2750 if(lib_name
== NULL
) return;
2752 if(library
!= NULL
) lttv_library_unload(library
);
2756 /* Dispaly a file selection dialogue to let user select a module, then call
2757 * lttv_module_require().
2761 on_load_module_activate (GtkMenuItem
*menuitem
,
2764 GError
*error
= NULL
;
2765 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2767 LttvLibrary
*library
= NULL
;
2772 name
= g_ptr_array_new();
2773 nb
= lttv_library_number();
2774 LttvLibraryInfo
*lib_info
= g_new(LttvLibraryInfo
,nb
);
2775 /* ask for the library name */
2778 LttvLibrary
*iter_lib
= lttv_library_get(i
);
2779 lttv_library_info(iter_lib
, &lib_info
[i
]);
2781 gchar
*path
= lib_info
[i
].name
;
2782 g_ptr_array_add(name
, path
);
2784 lib_name
= get_selection(mw_data
,(char **)(name
->pdata
), name
->len
,
2785 "Select a library", "Libraries");
2786 if(lib_name
!= NULL
) {
2788 if(strcmp(lib_name
, lib_info
[i
].name
) == 0) {
2789 library
= lttv_library_get(i
);
2794 g_ptr_array_free(name
, TRUE
);
2797 if(lib_name
== NULL
) return;
2800 //LttvModule *module;
2801 gchar module_name_out
[PATH_MAX
];
2803 /* Ask for the module to load : list modules in the selected lib */
2807 nb
= lttv_library_module_number(library
);
2808 LttvModuleInfo
*module_info
= g_new(LttvModuleInfo
,nb
);
2809 name
= g_ptr_array_new();
2810 /* ask for the module name */
2813 LttvModule
*iter_module
= lttv_library_module_get(library
, i
);
2814 lttv_module_info(iter_module
, &module_info
[i
]);
2816 gchar
*path
= module_info
[i
].name
;
2817 g_ptr_array_add(name
, path
);
2819 module_name
= get_selection(mw_data
, (char **)(name
->pdata
), name
->len
,
2820 "Select a module", "Modules");
2821 if(module_name
!= NULL
) {
2823 if(strcmp(module_name
, module_info
[i
].name
) == 0) {
2824 strncpy(module_name_out
, module_name
, PATH_MAX
);
2825 //module = lttv_library_module_get(i);
2831 g_ptr_array_free(name
, TRUE
);
2832 g_free(module_info
);
2834 if(module_name
== NULL
) return;
2837 lttv_module_require(module_name_out
, &error
);
2838 if(error
!= NULL
) g_warning("%s", error
->message
);
2839 else g_info("Load module: %s", module_name_out
);
2846 gchar str
[PATH_MAX
];
2849 GtkFileSelection
* file_selector
=
2850 (GtkFileSelection
*)gtk_file_selection_new("Select a module");
2851 gtk_file_selection_set_filename(file_selector
, load_module_path_alter
);
2852 gtk_file_selection_hide_fileop_buttons(file_selector
);
2855 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
2857 case GTK_RESPONSE_ACCEPT
:
2858 case GTK_RESPONSE_OK
:
2859 dir
= gtk_file_selection_get_selections (file_selector
);
2860 strncpy(str
,dir
[0],PATH_MAX
);
2861 strncpy(remember_plugins_dir
,dir
[0],PATH_MAX
);
2863 /* only keep file name */
2865 str1
= strrchr(str
,'/');
2868 str1
= strrchr(str
,'\\');
2873 if(*str1
== 'l' && *(str1
+1)== 'i' && *(str1
+2)=='b')
2875 remove info after
. */
2879 str2
= strrchr(str2
, '.');
2880 if(str2
!= NULL
) *str2
= '\0';
2882 lttv_module_require(str1
, &error
);
2884 lttv_library_load(str1
, &error
);
2885 if(error
!= NULL
) g_warning(error
->message
);
2886 else g_info("Load library: %s\n", str
);
2888 case GTK_RESPONSE_REJECT
:
2889 case GTK_RESPONSE_CANCEL
:
2891 gtk_widget_destroy((GtkWidget
*)file_selector
);
2903 /* Display all loaded modules, let user to select a module to unload
2904 * by calling lttv_module_unload
2908 on_unload_module_activate (GtkMenuItem
*menuitem
,
2911 GError
*error
= NULL
;
2912 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2914 LttvLibrary
*library
= NULL
;
2919 name
= g_ptr_array_new();
2920 nb
= lttv_library_number();
2921 LttvLibraryInfo
*lib_info
= g_new(LttvLibraryInfo
,nb
);
2922 /* ask for the library name */
2925 LttvLibrary
*iter_lib
= lttv_library_get(i
);
2926 lttv_library_info(iter_lib
, &lib_info
[i
]);
2928 gchar
*path
= lib_info
[i
].name
;
2929 g_ptr_array_add(name
, path
);
2931 lib_name
= get_selection(mw_data
, (char **)(name
->pdata
), name
->len
,
2932 "Select a library", "Libraries");
2933 if(lib_name
!= NULL
) {
2935 if(strcmp(lib_name
, lib_info
[i
].name
) == 0) {
2936 library
= lttv_library_get(i
);
2941 g_ptr_array_free(name
, TRUE
);
2944 if(lib_name
== NULL
) return;
2947 LttvModule
*module
= NULL
;
2949 /* Ask for the module to load : list modules in the selected lib */
2953 nb
= lttv_library_module_number(library
);
2954 LttvModuleInfo
*module_info
= g_new(LttvModuleInfo
,nb
);
2955 name
= g_ptr_array_new();
2956 /* ask for the module name */
2959 LttvModule
*iter_module
= lttv_library_module_get(library
, i
);
2960 lttv_module_info(iter_module
, &module_info
[i
]);
2962 gchar
*path
= module_info
[i
].name
;
2963 if(module_info
[i
].use_count
> 0) g_ptr_array_add(name
, path
);
2965 module_name
= get_selection(mw_data
, (char **)(name
->pdata
), name
->len
,
2966 "Select a module", "Modules");
2967 if(module_name
!= NULL
) {
2969 if(strcmp(module_name
, module_info
[i
].name
) == 0) {
2970 module
= lttv_library_module_get(library
, i
);
2976 g_ptr_array_free(name
, TRUE
);
2977 g_free(module_info
);
2979 if(module_name
== NULL
) return;
2982 LttvModuleInfo module_info
;
2983 lttv_module_info(module
, &module_info
);
2984 g_info("Release module: %s\n", module_info
.name
);
2986 lttv_module_release(module
);
2990 /* Display a directory dialogue to let user select a path for library searching
2994 on_add_library_search_path_activate (GtkMenuItem
*menuitem
,
2997 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2998 //GtkDirSelection * file_selector = (GtkDirSelection *)gtk_dir_selection_new("Select library path");
2999 GtkFileSelection
* file_selector
= (GtkFileSelection
*)gtk_file_selection_new("Select a trace");
3000 gtk_widget_hide( (file_selector
)->file_list
->parent
) ;
3002 gtk_window_set_transient_for(GTK_WINDOW(file_selector
),
3003 GTK_WINDOW(mw_data
->mwindow
));
3008 if(remember_plugins_dir
[0] != '\0')
3009 gtk_file_selection_set_filename(file_selector
, remember_plugins_dir
);
3011 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
3013 case GTK_RESPONSE_ACCEPT
:
3014 case GTK_RESPONSE_OK
:
3015 dir
= gtk_file_selection_get_filename (file_selector
);
3016 strncpy(remember_plugins_dir
,dir
,PATH_MAX
);
3017 strncat(remember_plugins_dir
,"/",PATH_MAX
);
3018 lttv_library_path_add(dir
);
3019 case GTK_RESPONSE_REJECT
:
3020 case GTK_RESPONSE_CANCEL
:
3022 gtk_widget_destroy((GtkWidget
*)file_selector
);
3028 /* Display a directory dialogue to let user select a path for library searching
3032 on_remove_library_search_path_activate (GtkMenuItem
*menuitem
,
3035 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
3037 const char *lib_path
;
3042 name
= g_ptr_array_new();
3043 nb
= lttv_library_path_number();
3044 /* ask for the library name */
3047 gchar
*path
= lttv_library_path_get(i
);
3048 g_ptr_array_add(name
, path
);
3050 lib_path
= get_selection(mw_data
, (char **)(name
->pdata
), name
->len
,
3051 "Select a library path", "Library paths");
3053 g_ptr_array_free(name
, TRUE
);
3055 if(lib_path
== NULL
) return;
3058 lttv_library_path_remove(lib_path
);
3062 on_color_activate (GtkMenuItem
*menuitem
,
3070 on_save_configuration_activate (GtkMenuItem
*menuitem
,
3073 g_info("Save configuration\n");
3078 on_content_activate (GtkMenuItem
*menuitem
,
3081 g_info("Content\n");
3086 on_about_close_activate (GtkButton
*button
,
3089 GtkWidget
*about_widget
= GTK_WIDGET(user_data
);
3091 gtk_widget_destroy(about_widget
);
3095 on_about_activate (GtkMenuItem
*menuitem
,
3098 MainWindow
*main_window
= get_window_data_struct(GTK_WIDGET(menuitem
));
3099 GtkWidget
*window_widget
= main_window
->mwindow
;
3100 GtkWidget
*about_widget
= gtk_window_new(GTK_WINDOW_TOPLEVEL
);
3101 GtkWindow
*about_window
= GTK_WINDOW(about_widget
);
3102 gint window_width
, window_height
;
3104 gtk_window_set_title(about_window
, "About Linux Trace Toolkit");
3106 gtk_window_set_resizable(about_window
, FALSE
);
3107 gtk_window_set_transient_for(about_window
, GTK_WINDOW(window_widget
));
3108 gtk_window_set_destroy_with_parent(about_window
, TRUE
);
3109 gtk_window_set_modal(about_window
, FALSE
);
3111 /* Put the about window at the center of the screen */
3112 gtk_window_get_size(about_window
, &window_width
, &window_height
);
3113 gtk_window_move (about_window
,
3114 (gdk_screen_width() - window_width
)/2,
3115 (gdk_screen_height() - window_height
)/2);
3117 GtkWidget
*vbox
= gtk_vbox_new(FALSE
, 1);
3119 gtk_container_add(GTK_CONTAINER(about_widget
), vbox
);
3123 GtkWidget
*label1
= gtk_label_new("");
3124 gtk_misc_set_padding(GTK_MISC(label1
), 10, 20);
3125 gtk_label_set_markup(GTK_LABEL(label1
), "\
3126 <big>Linux Trace Toolkit " VERSION
"</big>");
3127 gtk_label_set_justify(GTK_LABEL(label1
), GTK_JUSTIFY_CENTER
);
3129 GtkWidget
*label2
= gtk_label_new("");
3130 gtk_misc_set_padding(GTK_MISC(label2
), 10, 20);
3131 gtk_label_set_markup(GTK_LABEL(label2
), "\
3134 Michel Dagenais (New trace format, lttv main)\n\
3135 Mathieu Desnoyers (Kernel Tracer, Directory structure, build with automake/conf,\n\
3136 lttv gui, control flow view, gui cooperative trace reading\n\
3137 scheduler with interruptible foreground and background\n\
3138 computation, detailed event list (rewrite), trace reading\n\
3139 library (rewrite))\n\
3140 Benoit Des Ligneris, Eric Clement (Cluster adaptation, work in progress)\n\
3141 Xang-Xiu Yang (new trace reading library and converter, lttv gui, \n\
3142 detailed event list and statistics view)\n\
3143 Tom Zanussi (RelayFS)\n\
3145 Inspired from the original Linux Trace Toolkit Visualizer made by\n\
3148 GtkWidget
*label3
= gtk_label_new("");
3149 gtk_label_set_markup(GTK_LABEL(label3
), "\
3150 Linux Trace Toolkit Viewer, Copyright (C) 2004, 2005, 2006\n\
3152 Mathieu Desnoyers\n\
3154 Linux Trace Toolkit comes with ABSOLUTELY NO WARRANTY.\n\
3155 This is free software, and you are welcome to redistribute it\n\
3156 under certain conditions. See COPYING for details.");
3157 gtk_misc_set_padding(GTK_MISC(label3
), 10, 20);
3159 gtk_box_pack_start_defaults(GTK_BOX(vbox
), label1
);
3160 gtk_box_pack_start_defaults(GTK_BOX(vbox
), label2
);
3161 gtk_box_pack_start_defaults(GTK_BOX(vbox
), label3
);
3163 GtkWidget
*hbox
= gtk_hbox_new(TRUE
, 0);
3164 gtk_box_pack_end(GTK_BOX(vbox
), hbox
, FALSE
, FALSE
, 0);
3165 GtkWidget
*close_button
= gtk_button_new_with_mnemonic("_Close");
3166 gtk_box_pack_end(GTK_BOX(hbox
), close_button
, FALSE
, FALSE
, 0);
3167 gtk_container_set_border_width(GTK_CONTAINER(close_button
), 20);
3169 g_signal_connect(G_OBJECT(close_button
), "clicked",
3170 G_CALLBACK(on_about_close_activate
),
3171 (gpointer
)about_widget
);
3173 gtk_widget_show_all(about_widget
);
3178 on_button_new_clicked (GtkButton
*button
,
3181 create_new_window((GtkWidget
*)button
, user_data
, TRUE
);
3185 on_button_new_tab_clicked (GtkButton
*button
,
3188 create_new_tab((GtkWidget
*)button
, user_data
);
3192 on_button_open_clicked (GtkButton
*button
,
3195 open_traceset((GtkWidget
*)button
, user_data
);
3200 on_button_add_trace_clicked (GtkButton
*button
,
3203 add_trace((GtkWidget
*)button
, user_data
);
3208 on_button_remove_trace_clicked (GtkButton
*button
,
3211 remove_trace((GtkWidget
*)button
, user_data
);
3215 on_button_redraw_clicked (GtkButton
*button
,
3218 redraw((GtkWidget
*)button
, user_data
);
3222 on_button_continue_processing_clicked (GtkButton
*button
,
3225 continue_processing((GtkWidget
*)button
, user_data
);
3229 on_button_stop_processing_clicked (GtkButton
*button
,
3232 stop_processing((GtkWidget
*)button
, user_data
);
3238 on_button_save_clicked (GtkButton
*button
,
3241 save((GtkWidget
*)button
, user_data
);
3246 on_button_save_as_clicked (GtkButton
*button
,
3249 save_as((GtkWidget
*)button
, user_data
);
3254 on_button_zoom_in_clicked (GtkButton
*button
,
3257 zoom_in((GtkWidget
*)button
, user_data
);
3262 on_button_zoom_out_clicked (GtkButton
*button
,
3265 zoom_out((GtkWidget
*)button
, user_data
);
3270 on_button_zoom_extended_clicked (GtkButton
*button
,
3273 zoom_extended((GtkWidget
*)button
, user_data
);
3278 on_button_go_to_time_clicked (GtkButton
*button
,
3281 go_to_time((GtkWidget
*)button
, user_data
);
3286 on_button_show_time_frame_clicked (GtkButton
*button
,
3289 show_time_frame((GtkWidget
*)button
, user_data
);
3294 on_button_move_up_clicked (GtkButton
*button
,
3297 move_up_viewer((GtkWidget
*)button
, user_data
);
3302 on_button_move_down_clicked (GtkButton
*button
,
3305 move_down_viewer((GtkWidget
*)button
, user_data
);
3310 on_button_delete_viewer_clicked (GtkButton
*button
,
3313 delete_viewer((GtkWidget
*)button
, user_data
);
3317 on_MWindow_destroy (GtkWidget
*widget
,
3320 MainWindow
*main_window
= get_window_data_struct(widget
);
3321 LttvIAttribute
*attributes
= main_window
->attributes
;
3322 LttvAttributeValue value
;
3325 //This is unnecessary, since widgets will be destroyed
3326 //by the main window widget anyway.
3327 //remove_all_menu_toolbar_constructors(main_window, NULL);
3329 retval
= lttv_iattribute_find_by_path(attributes
, "viewers/menu",
3330 LTTV_POINTER
, &value
);
3332 lttv_menus_destroy((LttvMenus
*)*(value
.v_pointer
));
3334 retval
= lttv_iattribute_find_by_path(attributes
, "viewers/toolbar",
3335 LTTV_POINTER
, &value
);
3337 lttv_toolbars_destroy((LttvToolbars
*)*(value
.v_pointer
));
3339 g_object_unref(main_window
->attributes
);
3340 g_main_window_list
= g_slist_remove(g_main_window_list
, main_window
);
3342 g_info("There are now : %d windows\n",g_slist_length(g_main_window_list
));
3343 if(g_slist_length(g_main_window_list
) == 0)
3348 on_MWindow_configure (GtkWidget
*widget
,
3349 GdkEventConfigure
*event
,
3352 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)widget
);
3354 // MD : removed time width modification upon resizing of the main window.
3355 // The viewers will redraw themselves completely, without time interval
3358 if(mw_data->window_width){
3359 time_span = LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context)->Time_Span ;
3360 time_win = tab->time_window;
3361 ratio = width / mw_data->window_width;
3362 tab->time_window.time_width = ltt_time_mul(time_win.time_width,ratio);
3363 time = ltt_time_sub(time_span->endTime, time_win.start_time);
3364 if(ltt_time_compare(time, tab->time_window.time_width) < 0){
3365 tab->time_window.time_width = time;
3371 mw_data->window_width = (int)width;
3380 on_MNotebook_switch_page (GtkNotebook
*notebook
,
3381 GtkNotebookPage
*page
,
3389 void time_change_manager (Tab
*tab
,
3390 TimeWindow new_time_window
)
3392 /* Only one source of time change */
3393 if(tab
->time_manager_lock
== TRUE
) return;
3395 tab
->time_manager_lock
= TRUE
;
3397 LttvTracesetContext
*tsc
= LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3398 TimeInterval time_span
= tsc
->time_span
;
3399 LttTime start_time
= new_time_window
.start_time
;
3400 LttTime end_time
= new_time_window
.end_time
;
3401 LttTime time_width
= new_time_window
.time_width
;
3403 g_assert(ltt_time_compare(start_time
, end_time
) < 0);
3406 GtkAdjustment
*adjustment
= gtk_range_get_adjustment(GTK_RANGE(tab
->scrollbar
));
3407 LttTime upper
= ltt_time_sub(time_span
.end_time
, time_span
.start_time
);
3409 gtk_range_set_increments(GTK_RANGE(tab
->scrollbar
),
3410 ltt_time_to_double(new_time_window
.time_width
)
3411 / SCROLL_STEP_PER_PAGE
3412 * NANOSECONDS_PER_SECOND
, /* step increment */
3413 ltt_time_to_double(new_time_window
.time_width
)
3414 * NANOSECONDS_PER_SECOND
); /* page increment */
3415 gtk_range_set_range(GTK_RANGE(tab
->scrollbar
),
3417 ltt_time_to_double(upper
)
3418 * NANOSECONDS_PER_SECOND
); /* upper */
3420 g_object_set(G_OBJECT(adjustment
),
3424 ltt_time_to_double(upper
), /* upper */
3426 new_time_window
.time_width_double
3427 / SCROLL_STEP_PER_PAGE
, /* step increment */
3429 new_time_window
.time_width_double
,
3430 /* page increment */
3432 new_time_window
.time_width_double
, /* page size */
3434 gtk_adjustment_changed(adjustment
);
3436 // g_object_set(G_OBJECT(adjustment),
3438 // ltt_time_to_double(
3439 // ltt_time_sub(start_time, time_span.start_time))
3442 //gtk_adjustment_value_changed(adjustment);
3443 gtk_range_set_value(GTK_RANGE(tab
->scrollbar
),
3445 ltt_time_sub(start_time
, time_span
.start_time
)) /* value */);
3447 /* set the time bar. */
3449 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry1
),
3450 (double)time_span
.start_time
.tv_sec
,
3451 (double)time_span
.end_time
.tv_sec
);
3452 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry1
),
3453 (double)start_time
.tv_sec
);
3455 /* start nanoseconds */
3456 if(start_time
.tv_sec
== time_span
.start_time
.tv_sec
) {
3457 /* can be both beginning and end at the same time. */
3458 if(start_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3459 /* If we are at the end, max nsec to end.. -1 (not zero length) */
3460 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry2
),
3461 (double)time_span
.start_time
.tv_nsec
,
3462 (double)time_span
.end_time
.tv_nsec
-1);
3464 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry2
),
3465 (double)time_span
.start_time
.tv_nsec
,
3466 (double)NANOSECONDS_PER_SECOND
-1);
3468 } else if(start_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3469 /* If we are at the end, max nsec to end.. -1 (not zero length) */
3470 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry2
),
3472 (double)time_span
.end_time
.tv_nsec
-1);
3473 } else /* anywhere else */
3474 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry2
),
3476 (double)NANOSECONDS_PER_SECOND
-1);
3477 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry2
),
3478 (double)start_time
.tv_nsec
);
3481 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry3
),
3482 (double)time_span
.start_time
.tv_sec
,
3483 (double)time_span
.end_time
.tv_sec
);
3484 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry3
),
3485 (double)end_time
.tv_sec
);
3487 /* end nanoseconds */
3488 if(end_time
.tv_sec
== time_span
.start_time
.tv_sec
) {
3489 /* can be both beginning and end at the same time. */
3490 if(end_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3491 /* If we are at the end, max nsec to end.. */
3492 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry4
),
3493 (double)time_span
.start_time
.tv_nsec
+1,
3494 (double)time_span
.end_time
.tv_nsec
);
3496 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry4
),
3497 (double)time_span
.start_time
.tv_nsec
+1,
3498 (double)NANOSECONDS_PER_SECOND
-1);
3501 else if(end_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3502 /* If we are at the end, max nsec to end.. */
3503 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry4
),
3505 (double)time_span
.end_time
.tv_nsec
);
3507 else /* anywhere else */
3508 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry4
),
3510 (double)NANOSECONDS_PER_SECOND
-1);
3511 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry4
),
3512 (double)end_time
.tv_nsec
);
3515 if(time_width
.tv_nsec
== 0) {
3516 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry7
),
3518 (double)upper
.tv_sec
);
3520 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry7
),
3522 (double)upper
.tv_sec
);
3524 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry7
),
3525 (double)time_width
.tv_sec
);
3527 /* width nanoseconds */
3528 if(time_width
.tv_sec
== upper
.tv_sec
) {
3529 if(time_width
.tv_sec
== 0) {
3530 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry8
),
3532 (double)upper
.tv_nsec
);
3534 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry8
),
3536 (double)upper
.tv_nsec
);
3539 else if(time_width
.tv_sec
== 0) {
3540 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry8
),
3542 (double)upper
.tv_nsec
);
3544 else /* anywhere else */
3545 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry8
),
3547 (double)NANOSECONDS_PER_SECOND
-1);
3548 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry8
),
3549 (double)time_width
.tv_nsec
);
3551 /* call viewer hooks for new time window */
3552 set_time_window(tab
, &new_time_window
);
3554 tab
->time_manager_lock
= FALSE
;
3558 /* value changed for frame start s
3560 * Check time span : if ns is out of range, clip it the nearest good value.
3563 on_MEntry1_value_changed (GtkSpinButton
*spinbutton
,
3566 Tab
*tab
=(Tab
*)user_data
;
3567 LttvTracesetContext
* tsc
=
3568 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3569 TimeInterval time_span
= tsc
->time_span
;
3570 gint value
= gtk_spin_button_get_value_as_int(spinbutton
);
3572 TimeWindow new_time_window
= tab
->time_window
;
3574 LttTime end_time
= new_time_window
.end_time
;
3576 new_time_window
.start_time
.tv_sec
= value
;
3578 /* start nanoseconds */
3579 if(new_time_window
.start_time
.tv_sec
== time_span
.start_time
.tv_sec
) {
3580 if(new_time_window
.start_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3581 if(new_time_window
.start_time
.tv_nsec
> time_span
.end_time
.tv_nsec
)
3582 new_time_window
.start_time
.tv_nsec
= time_span
.end_time
.tv_nsec
-1;
3583 if(new_time_window
.start_time
.tv_nsec
< time_span
.start_time
.tv_nsec
)
3584 new_time_window
.start_time
.tv_nsec
= time_span
.start_time
.tv_nsec
;
3586 if(new_time_window
.start_time
.tv_nsec
< time_span
.start_time
.tv_nsec
)
3587 new_time_window
.start_time
.tv_nsec
= time_span
.start_time
.tv_nsec
;
3590 else if(new_time_window
.start_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3591 if(new_time_window
.start_time
.tv_nsec
> time_span
.end_time
.tv_nsec
)
3592 new_time_window
.start_time
.tv_nsec
= time_span
.end_time
.tv_nsec
-1;
3595 if(ltt_time_compare(new_time_window
.start_time
, end_time
) >= 0) {
3596 /* Then, we must push back end time : keep the same time width
3597 * if possible, else end traceset time */
3598 end_time
= LTT_TIME_MIN(ltt_time_add(new_time_window
.start_time
,
3599 new_time_window
.time_width
),
3600 time_span
.end_time
);
3603 /* Fix the time width to fit start time and end time */
3604 new_time_window
.time_width
= ltt_time_sub(end_time
,
3605 new_time_window
.start_time
);
3606 new_time_window
.time_width_double
=
3607 ltt_time_to_double(new_time_window
.time_width
);
3609 new_time_window
.end_time
= end_time
;
3611 time_change_manager(tab
, new_time_window
);
3616 on_MEntry2_value_changed (GtkSpinButton
*spinbutton
,
3619 Tab
*tab
=(Tab
*)user_data
;
3620 LttvTracesetContext
* tsc
=
3621 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3622 TimeInterval time_span
= tsc
->time_span
;
3623 gint value
= gtk_spin_button_get_value_as_int(spinbutton
);
3625 TimeWindow new_time_window
= tab
->time_window
;
3627 LttTime end_time
= new_time_window
.end_time
;
3629 new_time_window
.start_time
.tv_nsec
= value
;
3631 if(ltt_time_compare(new_time_window
.start_time
, end_time
) >= 0) {
3632 /* Then, we must push back end time : keep the same time width
3633 * if possible, else end traceset time */
3634 end_time
= LTT_TIME_MIN(ltt_time_add(new_time_window
.start_time
,
3635 new_time_window
.time_width
),
3636 time_span
.end_time
);
3639 /* Fix the time width to fit start time and end time */
3640 new_time_window
.time_width
= ltt_time_sub(end_time
,
3641 new_time_window
.start_time
);
3642 new_time_window
.time_width_double
=
3643 ltt_time_to_double(new_time_window
.time_width
);
3645 new_time_window
.end_time
= end_time
;
3647 time_change_manager(tab
, new_time_window
);
3652 on_MEntry3_value_changed (GtkSpinButton
*spinbutton
,
3655 Tab
*tab
=(Tab
*)user_data
;
3656 LttvTracesetContext
* tsc
=
3657 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3658 TimeInterval time_span
= tsc
->time_span
;
3659 gint value
= gtk_spin_button_get_value_as_int(spinbutton
);
3661 TimeWindow new_time_window
= tab
->time_window
;
3663 LttTime end_time
= new_time_window
.end_time
;
3665 end_time
.tv_sec
= value
;
3667 /* end nanoseconds */
3668 if(end_time
.tv_sec
== time_span
.start_time
.tv_sec
) {
3669 if(end_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3670 if(end_time
.tv_nsec
> time_span
.end_time
.tv_nsec
)
3671 end_time
.tv_nsec
= time_span
.end_time
.tv_nsec
;
3672 if(end_time
.tv_nsec
< time_span
.start_time
.tv_nsec
)
3673 end_time
.tv_nsec
= time_span
.start_time
.tv_nsec
+1;
3675 if(end_time
.tv_nsec
< time_span
.start_time
.tv_nsec
)
3676 end_time
.tv_nsec
= time_span
.start_time
.tv_nsec
+1;
3679 else if(end_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3680 if(end_time
.tv_nsec
> time_span
.end_time
.tv_nsec
)
3681 end_time
.tv_nsec
= time_span
.end_time
.tv_nsec
;
3684 if(ltt_time_compare(new_time_window
.start_time
, end_time
) >= 0) {
3685 /* Then, we must push front start time : keep the same time width
3686 * if possible, else end traceset time */
3687 new_time_window
.start_time
= LTT_TIME_MAX(
3688 ltt_time_sub(end_time
,
3689 new_time_window
.time_width
),
3690 time_span
.start_time
);
3693 /* Fix the time width to fit start time and end time */
3694 new_time_window
.time_width
= ltt_time_sub(end_time
,
3695 new_time_window
.start_time
);
3696 new_time_window
.time_width_double
=
3697 ltt_time_to_double(new_time_window
.time_width
);
3699 new_time_window
.end_time
= end_time
;
3701 time_change_manager(tab
, new_time_window
);
3706 on_MEntry4_value_changed (GtkSpinButton
*spinbutton
,
3709 Tab
*tab
=(Tab
*)user_data
;
3710 LttvTracesetContext
* tsc
=
3711 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3712 TimeInterval time_span
= tsc
->time_span
;
3713 gint value
= gtk_spin_button_get_value_as_int(spinbutton
);
3715 TimeWindow new_time_window
= tab
->time_window
;
3717 LttTime end_time
= new_time_window
.end_time
;
3719 end_time
.tv_nsec
= value
;
3721 if(ltt_time_compare(new_time_window
.start_time
, end_time
) >= 0) {
3722 /* Then, we must push front start time : keep the same time width
3723 * if possible, else end traceset time */
3724 new_time_window
.start_time
= LTT_TIME_MAX(
3725 ltt_time_sub(end_time
,
3726 new_time_window
.time_width
),
3727 time_span
.start_time
);
3730 /* Fix the time width to fit start time and end time */
3731 new_time_window
.time_width
= ltt_time_sub(end_time
,
3732 new_time_window
.start_time
);
3733 new_time_window
.time_width_double
=
3734 ltt_time_to_double(new_time_window
.time_width
);
3735 new_time_window
.end_time
= end_time
;
3737 time_change_manager(tab
, new_time_window
);
3741 /* value changed for time frame interval s
3743 * Check time span : if ns is out of range, clip it the nearest good value.
3746 on_MEntry7_value_changed (GtkSpinButton
*spinbutton
,
3749 Tab
*tab
=(Tab
*)user_data
;
3750 LttvTracesetContext
* tsc
=
3751 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3752 TimeInterval time_span
= tsc
->time_span
;
3753 gint value
= gtk_spin_button_get_value_as_int(spinbutton
);
3754 LttTime current_time
, time_delta
;
3755 TimeWindow new_time_window
= tab
->time_window
;
3756 current_time
= tab
->current_time
;
3758 time_delta
= ltt_time_sub(time_span
.end_time
,time_span
.start_time
);
3759 new_time_window
.time_width
.tv_sec
= value
;
3760 new_time_window
.time_width_double
=
3761 ltt_time_to_double(new_time_window
.time_width
);
3762 if(ltt_time_compare(new_time_window
.time_width
,time_delta
) > 0)
3763 { /* Case where zoom out is bigger than trace length */
3764 new_time_window
.start_time
= time_span
.start_time
;
3765 new_time_window
.time_width
= time_delta
;
3766 new_time_window
.time_width_double
= ltt_time_to_double(time_delta
);
3767 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
3768 new_time_window
.time_width
) ;
3772 /* Center the image on the current time */
3773 new_time_window
.start_time
=
3774 ltt_time_sub(current_time
,
3775 ltt_time_from_double(new_time_window
.time_width_double
/2.0));
3776 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
3777 new_time_window
.time_width
) ;
3778 /* If on borders, don't fall off */
3779 if(ltt_time_compare(new_time_window
.start_time
, time_span
.start_time
) <0
3780 || ltt_time_compare(new_time_window
.start_time
, time_span
.end_time
) >0)
3782 new_time_window
.start_time
= time_span
.start_time
;
3783 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
3784 new_time_window
.time_width
) ;
3788 if(ltt_time_compare(new_time_window
.end_time
,
3789 time_span
.end_time
) > 0
3790 || ltt_time_compare(new_time_window
.end_time
,
3791 time_span
.start_time
) < 0)
3793 new_time_window
.start_time
=
3794 ltt_time_sub(time_span
.end_time
, new_time_window
.time_width
);
3796 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
3797 new_time_window
.time_width
) ;
3803 if(ltt_time_compare(new_time_window
.time_width
, ltt_time_zero
) == 0) {
3804 g_warning("Zoom more than 1 ns impossible");
3806 time_change_manager(tab
, new_time_window
);
3811 on_MEntry8_value_changed (GtkSpinButton
*spinbutton
,
3814 Tab
*tab
=(Tab
*)user_data
;
3815 LttvTracesetContext
* tsc
=
3816 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3817 TimeInterval time_span
= tsc
->time_span
;
3818 gint value
= gtk_spin_button_get_value_as_int(spinbutton
);
3819 LttTime current_time
, time_delta
;
3820 TimeWindow new_time_window
= tab
->time_window
;
3821 current_time
= tab
->current_time
;
3823 time_delta
= ltt_time_sub(time_span
.end_time
,time_span
.start_time
);
3824 new_time_window
.time_width
.tv_nsec
= value
;
3825 new_time_window
.time_width_double
=
3826 ltt_time_to_double(new_time_window
.time_width
);
3827 if(ltt_time_compare(new_time_window
.time_width
,time_delta
) > 0)
3828 { /* Case where zoom out is bigger than trace length */
3829 new_time_window
.start_time
= time_span
.start_time
;
3830 new_time_window
.time_width
= time_delta
;
3831 new_time_window
.time_width_double
= ltt_time_to_double(time_delta
);
3832 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
3833 new_time_window
.time_width
) ;
3837 /* Center the image on the current time */
3838 new_time_window
.start_time
=
3839 ltt_time_sub(current_time
,
3840 ltt_time_from_double(new_time_window
.time_width_double
/2.0));
3841 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
3842 new_time_window
.time_width
) ;
3843 /* If on borders, don't fall off */
3844 if(ltt_time_compare(new_time_window
.start_time
, time_span
.start_time
) <0
3845 || ltt_time_compare(new_time_window
.start_time
, time_span
.end_time
) >0)
3847 new_time_window
.start_time
= time_span
.start_time
;
3848 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
3849 new_time_window
.time_width
) ;
3853 if(ltt_time_compare(new_time_window
.end_time
,
3854 time_span
.end_time
) > 0
3855 || ltt_time_compare(new_time_window
.end_time
,
3856 time_span
.start_time
) < 0)
3858 new_time_window
.start_time
=
3859 ltt_time_sub(time_span
.end_time
, new_time_window
.time_width
);
3861 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
3862 new_time_window
.time_width
) ;
3868 if(ltt_time_compare(new_time_window
.time_width
, ltt_time_zero
) == 0) {
3869 g_warning("Zoom more than 1 ns impossible");
3871 time_change_manager(tab
, new_time_window
);
3877 void current_time_change_manager (Tab
*tab
,
3878 LttTime new_current_time
)
3880 /* Only one source of time change */
3881 if(tab
->current_time_manager_lock
== TRUE
) return;
3883 tab
->current_time_manager_lock
= TRUE
;
3885 LttvTracesetContext
*tsc
= LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3886 TimeInterval time_span
= tsc
->time_span
;
3888 /* current seconds */
3889 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry5
),
3890 (double)time_span
.start_time
.tv_sec
,
3891 (double)time_span
.end_time
.tv_sec
);
3892 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry5
),
3893 (double)new_current_time
.tv_sec
);
3896 /* start nanoseconds */
3897 if(new_current_time
.tv_sec
== time_span
.start_time
.tv_sec
) {
3898 /* can be both beginning and end at the same time. */
3899 if(new_current_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3900 /* If we are at the end, max nsec to end.. */
3901 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry6
),
3902 (double)time_span
.start_time
.tv_nsec
,
3903 (double)time_span
.end_time
.tv_nsec
);
3905 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry6
),
3906 (double)time_span
.start_time
.tv_nsec
,
3907 (double)NANOSECONDS_PER_SECOND
-1);
3909 } else if(new_current_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3910 /* If we are at the end, max nsec to end.. */
3911 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry6
),
3913 (double)time_span
.end_time
.tv_nsec
);
3914 } else /* anywhere else */
3915 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry6
),
3917 (double)NANOSECONDS_PER_SECOND
-1);
3919 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry6
),
3920 (double)new_current_time
.tv_nsec
);
3922 set_current_time(tab
, &new_current_time
);
3924 tab
->current_time_manager_lock
= FALSE
;
3927 void current_position_change_manager(Tab
*tab
,
3928 LttvTracesetContextPosition
*pos
)
3930 LttvTracesetContext
*tsc
=
3931 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3932 TimeInterval time_span
= tsc
->time_span
;
3935 retval
= lttv_process_traceset_seek_position(tsc
, pos
);
3936 g_assert_cmpint(retval
, ==, 0);
3937 LttTime new_time
= lttv_traceset_context_position_get_time(pos
);
3938 /* Put the context in a state coherent position */
3939 lttv_state_traceset_seek_time_closest((LttvTracesetState
*)tsc
, ltt_time_zero
);
3941 current_time_change_manager(tab
, new_time
);
3943 set_current_position(tab
, pos
);
3948 on_MEntry5_value_changed (GtkSpinButton
*spinbutton
,
3951 Tab
*tab
= (Tab
*)user_data
;
3952 LttvTracesetContext
* tsc
=
3953 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3954 TimeInterval time_span
= tsc
->time_span
;
3955 gint value
= gtk_spin_button_get_value_as_int(spinbutton
);
3956 LttTime new_current_time
= tab
->current_time
;
3957 new_current_time
.tv_sec
= value
;
3959 /* current nanoseconds */
3960 if(new_current_time
.tv_sec
== time_span
.start_time
.tv_sec
) {
3961 if(new_current_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3962 if(new_current_time
.tv_nsec
> time_span
.end_time
.tv_nsec
)
3963 new_current_time
.tv_nsec
= time_span
.end_time
.tv_nsec
;
3964 if(new_current_time
.tv_nsec
< time_span
.start_time
.tv_nsec
)
3965 new_current_time
.tv_nsec
= time_span
.start_time
.tv_nsec
;
3967 if(new_current_time
.tv_nsec
< time_span
.start_time
.tv_nsec
)
3968 new_current_time
.tv_nsec
= time_span
.start_time
.tv_nsec
;
3971 else if(new_current_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3972 if(new_current_time
.tv_nsec
> time_span
.end_time
.tv_nsec
)
3973 new_current_time
.tv_nsec
= time_span
.end_time
.tv_nsec
;
3976 current_time_change_manager(tab
, new_current_time
);
3980 on_MEntry6_value_changed (GtkSpinButton
*spinbutton
,
3983 Tab
*tab
= (Tab
*)user_data
;
3984 gint value
= gtk_spin_button_get_value_as_int(spinbutton
);
3985 LttTime new_current_time
= tab
->current_time
;
3986 new_current_time
.tv_nsec
= value
;
3988 current_time_change_manager(tab
, new_current_time
);
3992 void scroll_value_changed_cb(GtkWidget
*scrollbar
,
3995 Tab
*tab
= (Tab
*)user_data
;
3996 TimeWindow new_time_window
;
3998 GtkAdjustment
*adjust
= gtk_range_get_adjustment(GTK_RANGE(scrollbar
));
3999 gdouble value
= gtk_adjustment_get_value(adjust
);
4000 // gdouble upper, lower, ratio, page_size;
4002 LttvTracesetContext
* tsc
=
4003 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
4004 TimeInterval time_span
= tsc
->time_span
;
4006 time
= ltt_time_add(ltt_time_from_double(value
),
4007 time_span
.start_time
);
4009 new_time_window
.start_time
= time
;
4011 page_size
= adjust
->page_size
;
4013 new_time_window
.time_width
=
4014 ltt_time_from_double(page_size
);
4016 new_time_window
.time_width_double
=
4019 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
4020 new_time_window
.time_width
);
4023 time_change_manager(tab
, new_time_window
);
4025 //time_window = tab->time_window;
4027 lower
= adjust
->lower
;
4028 upper
= adjust
->upper
;
4029 ratio
= (value
- lower
) / (upper
- lower
);
4030 g_info("lower %lu, upper %lu, value %lu, ratio %lu", lower
, upper
, value
, ratio
);
4032 //time = ltt_time_sub(time_span->end_time, time_span->start_time);
4033 //time = ltt_time_mul(time, (float)ratio);
4034 //time = ltt_time_add(time_span->start_time, time);
4035 time
= ltt_time_add(ltt_time_from_double(value
),
4036 time_span
.start_time
);
4038 time_window
.start_time
= time
;
4040 page_size
= adjust
->page_size
;
4042 time_window
.time_width
=
4043 ltt_time_from_double(page_size
);
4044 //time = ltt_time_sub(time_span.end_time, time);
4045 //if(ltt_time_compare(time,time_window.time_width) < 0){
4046 // time_window.time_width = time;
4049 /* call viewer hooks for new time window */
4050 set_time_window(tab
, &time_window
);
4055 /* Display a dialogue showing all eventtypes and traces, let user to select the interested
4056 * eventtypes, tracefiles and traces (filter)
4059 /* Select a trace which will be removed from traceset
4062 char * get_remove_trace(MainWindow
*mw_data
,
4063 char ** all_trace_name
, int nb_trace
)
4065 return get_selection(mw_data
, all_trace_name
, nb_trace
,
4066 "Select a trace", "Trace pathname");
4070 /* Select a module which will be loaded
4073 char * get_load_module(MainWindow
*mw_data
,
4074 char ** load_module_name
, int nb_module
)
4076 return get_selection(mw_data
, load_module_name
, nb_module
,
4077 "Select a module to load", "Module name");
4083 /* Select a module which will be unloaded
4086 char * get_unload_module(MainWindow
*mw_data
,
4087 char ** loaded_module_name
, int nb_module
)
4089 return get_selection(mw_data
, loaded_module_name
, nb_module
,
4090 "Select a module to unload", "Module name");
4094 /* Display a dialogue which shows all selectable items, let user to
4095 * select one of them
4098 char * get_selection(MainWindow
*mw_data
,
4099 char ** loaded_module_name
, int nb_module
,
4100 char *title
, char * column_title
)
4102 GtkWidget
* dialogue
;
4103 GtkWidget
* scroll_win
;
4105 GtkListStore
* store
;
4106 GtkTreeViewColumn
* column
;
4107 GtkCellRenderer
* renderer
;
4108 GtkTreeSelection
* select
;
4111 char * unload_module_name
= NULL
;
4113 dialogue
= gtk_dialog_new_with_buttons(title
,
4116 GTK_STOCK_OK
,GTK_RESPONSE_ACCEPT
,
4117 GTK_STOCK_CANCEL
,GTK_RESPONSE_REJECT
,
4119 gtk_window_set_default_size((GtkWindow
*)dialogue
, 500, 200);
4120 gtk_window_set_transient_for(GTK_WINDOW(dialogue
),
4121 GTK_WINDOW(mw_data
->mwindow
));
4123 scroll_win
= gtk_scrolled_window_new (NULL
, NULL
);
4124 gtk_widget_show ( scroll_win
);
4125 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll_win
),
4126 GTK_POLICY_AUTOMATIC
, GTK_POLICY_AUTOMATIC
);
4128 store
= gtk_list_store_new (N_COLUMNS
,G_TYPE_STRING
);
4129 tree
= gtk_tree_view_new_with_model(GTK_TREE_MODEL (store
));
4130 gtk_widget_show ( tree
);
4131 g_object_unref (G_OBJECT (store
));
4133 renderer
= gtk_cell_renderer_text_new ();
4134 column
= gtk_tree_view_column_new_with_attributes (column_title
,
4136 "text", MODULE_COLUMN
,
4138 gtk_tree_view_column_set_alignment (column
, 0.5);
4139 gtk_tree_view_column_set_fixed_width (column
, 150);
4140 gtk_tree_view_append_column (GTK_TREE_VIEW (tree
), column
);
4142 select
= gtk_tree_view_get_selection (GTK_TREE_VIEW (tree
));
4143 gtk_tree_selection_set_mode (select
, GTK_SELECTION_SINGLE
);
4145 gtk_container_add (GTK_CONTAINER (scroll_win
), tree
);
4147 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialogue
)->vbox
), scroll_win
,TRUE
, TRUE
,0);
4149 for(i
=0;i
<nb_module
;i
++){
4150 gtk_list_store_append (store
, &iter
);
4151 gtk_list_store_set (store
, &iter
, MODULE_COLUMN
,loaded_module_name
[i
],-1);
4154 id
= gtk_dialog_run(GTK_DIALOG(dialogue
));
4155 GtkTreeModel
**store_model
= (GtkTreeModel
**)&store
;
4157 case GTK_RESPONSE_ACCEPT
:
4158 case GTK_RESPONSE_OK
:
4159 if (gtk_tree_selection_get_selected (select
, store_model
, &iter
)){
4160 gtk_tree_model_get ((GtkTreeModel
*)store
, &iter
, MODULE_COLUMN
, &unload_module_name
, -1);
4162 case GTK_RESPONSE_REJECT
:
4163 case GTK_RESPONSE_CANCEL
:
4165 gtk_widget_destroy(dialogue
);
4169 return unload_module_name
;
4173 /* Insert all menu entry and tool buttons into this main window
4178 void add_all_menu_toolbar_constructors(MainWindow
* mw
, gpointer user_data
)
4182 lttvwindow_viewer_constructor constructor
;
4183 LttvMenus
* global_menu
, * instance_menu
;
4184 LttvToolbars
* global_toolbar
, * instance_toolbar
;
4185 LttvMenuClosure
*menu_item
;
4186 LttvToolbarClosure
*toolbar_item
;
4187 LttvAttributeValue value
;
4188 LttvIAttribute
*global_attributes
= LTTV_IATTRIBUTE(lttv_global_attributes());
4189 LttvIAttribute
*attributes
= mw
->attributes
;
4190 GtkWidget
* tool_menu_title_menu
, *new_widget
, *pixmap
;
4193 retval
= lttv_iattribute_find_by_path(global_attributes
, "viewers/menu",
4194 LTTV_POINTER
, &value
);
4196 if(*(value
.v_pointer
) == NULL
)
4197 *(value
.v_pointer
) = lttv_menus_new();
4198 global_menu
= (LttvMenus
*)*(value
.v_pointer
);
4200 retval
= lttv_iattribute_find_by_path(attributes
, "viewers/menu",
4201 LTTV_POINTER
, &value
);
4203 if(*(value
.v_pointer
) == NULL
)
4204 *(value
.v_pointer
) = lttv_menus_new();
4205 instance_menu
= (LttvMenus
*)*(value
.v_pointer
);
4207 retval
= lttv_iattribute_find_by_path(global_attributes
, "viewers/toolbar",
4208 LTTV_POINTER
, &value
);
4210 if(*(value
.v_pointer
) == NULL
)
4211 *(value
.v_pointer
) = lttv_toolbars_new();
4212 global_toolbar
= (LttvToolbars
*)*(value
.v_pointer
);
4214 retval
= lttv_iattribute_find_by_path(attributes
, "viewers/toolbar",
4215 LTTV_POINTER
, &value
);
4217 if(*(value
.v_pointer
) == NULL
)
4218 *(value
.v_pointer
) = lttv_toolbars_new();
4219 instance_toolbar
= (LttvToolbars
*)*(value
.v_pointer
);
4221 /* Add missing menu entries to window instance */
4222 for(i
=0;i
<global_menu
->len
;i
++) {
4223 menu_item
= &g_array_index(global_menu
, LttvMenuClosure
, i
);
4225 //add menu_item to window instance;
4226 constructor
= menu_item
->con
;
4227 tool_menu_title_menu
= lookup_widget(mw
->mwindow
,"ToolMenuTitle_menu");
4229 gtk_menu_item_new_with_mnemonic (menu_item
->menu_text
);
4230 gtk_container_add (GTK_CONTAINER (tool_menu_title_menu
),
4232 g_signal_connect ((gpointer
) new_widget
, "activate",
4233 G_CALLBACK (insert_viewer_wrap
),
4235 gtk_widget_show (new_widget
);
4236 lttv_menus_add(instance_menu
, menu_item
->con
,
4237 menu_item
->menu_path
,
4238 menu_item
->menu_text
,
4243 /* Add missing toolbar entries to window instance */
4244 for(i
=0;i
<global_toolbar
->len
;i
++) {
4245 toolbar_item
= &g_array_index(global_toolbar
, LttvToolbarClosure
, i
);
4247 //add toolbar_item to window instance;
4248 constructor
= toolbar_item
->con
;
4249 tool_menu_title_menu
= lookup_widget(mw
->mwindow
,"MToolbar1");
4250 pixbuf
= gdk_pixbuf_new_from_xpm_data((const char**)toolbar_item
->pixmap
);
4251 pixmap
= gtk_image_new_from_pixbuf(pixbuf
);
4253 gtk_toolbar_append_element (GTK_TOOLBAR (tool_menu_title_menu
),
4254 GTK_TOOLBAR_CHILD_BUTTON
,
4257 toolbar_item
->tooltip
, NULL
,
4258 pixmap
, NULL
, NULL
);
4259 gtk_label_set_use_underline(
4260 GTK_LABEL (((GtkToolbarChild
*) (
4261 g_list_last (GTK_TOOLBAR
4262 (tool_menu_title_menu
)->children
)->data
))->label
),
4264 gtk_container_set_border_width (GTK_CONTAINER (new_widget
), 1);
4265 g_signal_connect ((gpointer
) new_widget
,
4267 G_CALLBACK (insert_viewer_wrap
),
4269 gtk_widget_show (new_widget
);
4271 lttv_toolbars_add(instance_toolbar
, toolbar_item
->con
,
4272 toolbar_item
->tooltip
,
4273 toolbar_item
->pixmap
,
4281 /* Create a main window
4284 MainWindow
*construct_main_window(MainWindow
* parent
)
4288 g_debug("construct_main_window()");
4289 GtkWidget
* new_window
; /* New generated main window */
4290 MainWindow
* new_m_window
;/* New main window structure */
4291 GtkNotebook
* notebook
;
4292 LttvIAttribute
*attributes
=
4293 LTTV_IATTRIBUTE(g_object_new(LTTV_ATTRIBUTE_TYPE
, NULL
));
4294 LttvAttributeValue value
;
4297 new_m_window
= g_new(MainWindow
, 1);
4299 // Add the object's information to the module's array
4300 g_main_window_list
= g_slist_append(g_main_window_list
, new_m_window
);
4302 new_window
= create_MWindow();
4303 gtk_widget_show (new_window
);
4305 new_m_window
->mwindow
= new_window
;
4306 new_m_window
->attributes
= attributes
;
4308 retval
= lttv_iattribute_find_by_path(attributes
, "viewers/menu",
4309 LTTV_POINTER
, &value
);
4311 *(value
.v_pointer
) = lttv_menus_new();
4313 retval
= lttv_iattribute_find_by_path(attributes
, "viewers/toolbar",
4314 LTTV_POINTER
, &value
);
4316 *(value
.v_pointer
) = lttv_toolbars_new();
4318 add_all_menu_toolbar_constructors(new_m_window
, NULL
);
4320 g_object_set_data_full(G_OBJECT(new_window
),
4322 (gpointer
)new_m_window
,
4323 (GDestroyNotify
)g_free
);
4324 //create a default tab
4325 notebook
= (GtkNotebook
*)lookup_widget(new_m_window
->mwindow
, "MNotebook");
4326 if(notebook
== NULL
){
4327 g_info("Notebook does not exist\n");
4328 /* FIXME : destroy partially created widgets */
4329 g_free(new_m_window
);
4332 //gtk_notebook_popup_enable (GTK_NOTEBOOK(notebook));
4333 //for now there is no name field in LttvTraceset structure
4334 //Use "Traceset" as the label for the default tab
4336 GtkWidget
* parent_notebook
= lookup_widget(parent
->mwindow
, "MNotebook");
4337 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(parent_notebook
),
4338 gtk_notebook_get_current_page(GTK_NOTEBOOK(parent_notebook
)));
4344 LttvPluginTab
*ptab
;
4345 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
4346 parent_tab
= ptab
->tab
;
4348 LttvPluginTab
*ptab
= g_object_new(LTTV_TYPE_PLUGIN_TAB
, NULL
);
4350 new_m_window
, parent_tab
, notebook
, "Traceset");
4351 ptab
->parent
.top_widget
= ptab
->tab
->top_widget
;
4352 g_object_set_data_full(
4353 G_OBJECT(ptab
->tab
->vbox
),
4356 (GDestroyNotify
)tab_destructor
);
4357 new_tab
= ptab
->tab
;
4359 LttvPluginTab
*ptab
= g_object_new(LTTV_TYPE_PLUGIN_TAB
, NULL
);
4360 init_tab(ptab
->tab
, new_m_window
, NULL
, notebook
, "Traceset");
4361 ptab
->parent
.top_widget
= ptab
->tab
->top_widget
;
4362 g_object_set_data_full(
4363 G_OBJECT(ptab
->tab
->vbox
),
4366 (GDestroyNotify
)tab_destructor
);
4367 new_tab
= ptab
->tab
;
4370 /* Insert default viewers */
4372 LttvAttributeType type
;
4373 LttvAttributeName name
;
4374 LttvAttributeValue value
;
4375 LttvAttribute
*attribute
;
4377 LttvIAttribute
*attributes_global
=
4378 LTTV_IATTRIBUTE(lttv_global_attributes());
4380 attribute
= LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
4381 LTTV_IATTRIBUTE(attributes_global
),
4382 LTTV_VIEWER_CONSTRUCTORS
));
4383 g_assert(attribute
);
4385 name
= g_quark_from_string("guievents");
4386 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
4388 if(type
== LTTV_POINTER
) {
4389 lttvwindow_viewer_constructor viewer_constructor
=
4390 (lttvwindow_viewer_constructor
)*value
.v_pointer
;
4391 insert_viewer(new_window
, viewer_constructor
);
4394 name
= g_quark_from_string("guicontrolflow");
4395 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
4397 if(type
== LTTV_POINTER
) {
4398 lttvwindow_viewer_constructor viewer_constructor
=
4399 (lttvwindow_viewer_constructor
)*value
.v_pointer
;
4400 insert_viewer(new_window
, viewer_constructor
);
4403 name
= g_quark_from_string("guistatistics");
4404 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
4406 if(type
== LTTV_POINTER
) {
4407 lttvwindow_viewer_constructor viewer_constructor
=
4408 (lttvwindow_viewer_constructor
)*value
.v_pointer
;
4409 insert_viewer(new_window
, viewer_constructor
);
4413 g_info("There are now : %d windows\n",g_slist_length(g_main_window_list
));
4415 return new_m_window
;
4419 /* Free the memory occupied by a tab structure
4423 void tab_destructor(LttvPluginTab
* ptab
)
4425 int i
, nb
, ref_count
;
4427 Tab
*tab
= ptab
->tab
;
4429 gtk_object_destroy(GTK_OBJECT(tab
->tooltips
));
4432 g_object_unref(tab
->attributes
);
4434 if(tab
->interrupted_state
)
4435 g_object_unref(tab
->interrupted_state
);
4438 if(tab
->traceset_info
->traceset_context
!= NULL
){
4439 //remove state update hooks
4440 lttv_state_remove_event_hooks(
4441 (LttvTracesetState
*)tab
->traceset_info
->
4443 lttv_context_fini(LTTV_TRACESET_CONTEXT(tab
->traceset_info
->
4445 g_object_unref(tab
->traceset_info
->traceset_context
);
4447 if(tab
->traceset_info
->traceset
!= NULL
) {
4448 nb
= lttv_traceset_number(tab
->traceset_info
->traceset
);
4449 for(i
= 0 ; i
< nb
; i
++) {
4450 trace
= lttv_traceset_get(tab
->traceset_info
->traceset
, i
);
4451 ref_count
= lttv_trace_get_ref_number(trace
);
4453 ltt_trace_close(lttv_trace(trace
));
4457 lttv_traceset_destroy(tab
->traceset_info
->traceset
);
4458 /* Remove the idle events requests processing function of the tab */
4459 g_idle_remove_by_data(tab
);
4461 g_slist_free(tab
->events_requests
);
4462 g_free(tab
->traceset_info
);
4464 g_object_unref(ptab
);
4468 /* Create a tab and insert it into the current main window
4471 void init_tab(Tab
*tab
, MainWindow
* mw
, Tab
*copy_tab
,
4472 GtkNotebook
* notebook
, char * label
)
4476 //LttvFilter *filter = NULL;
4478 //create a new tab data structure
4479 //tab = g_new(Tab,1);
4481 //construct and initialize the traceset_info
4482 tab
->traceset_info
= g_new(TracesetInfo
,1);
4485 tab
->traceset_info
->traceset
=
4486 lttv_traceset_copy(copy_tab
->traceset_info
->traceset
);
4488 /* Copy the previous tab's filter */
4489 /* We can clone the filter, as we copy the trace set also */
4490 /* The filter must always be in sync with the trace set */
4491 tab
->filter
= lttv_filter_clone(copy_tab
->filter
);
4493 tab
->traceset_info
->traceset
= lttv_traceset_new();
4497 lttv_attribute_write_xml(
4498 lttv_traceset_attribute(tab
->traceset_info
->traceset
),
4504 tab
->time_manager_lock
= FALSE
;
4505 tab
->current_time_manager_lock
= FALSE
;
4507 //FIXME copy not implemented in lower level
4508 tab
->traceset_info
->traceset_context
=
4509 g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
4510 g_assert(tab
->traceset_info
->traceset_context
!= NULL
);
4512 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
),
4513 tab
->traceset_info
->traceset
);
4514 //add state update hooks
4515 lttv_state_add_event_hooks(
4516 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
4518 //determine the current_time and time_window of the tab
4520 if(copy_tab
!= NULL
){
4521 tab
->time_window
= copy_tab
->time_window
;
4522 tab
->current_time
= copy_tab
->current_time
;
4524 tab
->time_window
.start_time
=
4525 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
4526 time_span
.start_time
;
4527 if(DEFAULT_TIME_WIDTH_S
<
4528 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
4529 time_span
.end_time
.tv_sec
)
4530 tmp_time
.tv_sec
= DEFAULT_TIME_WIDTH_S
;
4533 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
4534 time_span
.end_time
.tv_sec
;
4535 tmp_time
.tv_nsec
= 0;
4536 tab
->time_window
.time_width
= tmp_time
;
4537 tab
->current_time
.tv_sec
=
4538 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
4539 time_span
.start_time
.tv_sec
;
4540 tab
->current_time
.tv_nsec
=
4541 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
4542 time_span
.start_time
.tv_nsec
;
4545 tab
->attributes
= LTTV_IATTRIBUTE(g_object_new(LTTV_ATTRIBUTE_TYPE
, NULL
));
4546 tab
->interrupted_state
= g_object_new(LTTV_ATTRIBUTE_TYPE
, NULL
);
4548 tab
->vbox
= gtk_vbox_new(FALSE
, 2);
4549 tab
->top_widget
= tab
->vbox
;
4550 //g_object_set_data_full(G_OBJECT(tab->top_widget), "filter",
4551 // filter, (GDestroyNotify)lttv_filter_destroy);
4553 // g_signal_connect (G_OBJECT(tab->top_widget),
4555 // G_CALLBACK (on_top_notify),
4558 tab
->viewer_container
= gtk_vbox_new(TRUE
, 2);
4559 tab
->scrollbar
= gtk_hscrollbar_new(NULL
);
4560 //tab->multivpaned = gtk_multi_vpaned_new();
4562 gtk_box_pack_start(GTK_BOX(tab
->vbox
),
4563 tab
->viewer_container
,
4565 TRUE
, /* Give the extra space to the child */
4566 0); /* No padding */
4569 // tab->time_window = copy_tab->time_window;
4570 // tab->current_time = copy_tab->current_time;
4573 /* Create the timebar */
4575 tab
->MTimebar
= gtk_hbox_new(FALSE
, 2);
4576 gtk_widget_show(tab
->MTimebar
);
4577 tab
->tooltips
= gtk_tooltips_new();
4579 tab
->MEventBox1a
= gtk_event_box_new();
4580 gtk_widget_show(tab
->MEventBox1a
);
4581 gtk_tooltips_set_tip(tab
->tooltips
, tab
->MEventBox1a
,
4582 "Paste Start and End Times Here", "");
4583 tab
->MText1a
= gtk_label_new("Time Frame ");
4584 gtk_widget_show(tab
->MText1a
);
4585 gtk_container_add(GTK_CONTAINER(tab
->MEventBox1a
), tab
->MText1a
);
4586 tab
->MEventBox1b
= gtk_event_box_new();
4587 gtk_widget_show(tab
->MEventBox1b
);
4588 gtk_tooltips_set_tip(tab
->tooltips
, tab
->MEventBox1b
,
4589 "Paste Start Time Here", "");
4590 tab
->MText1b
= gtk_label_new("start: ");
4591 gtk_widget_show(tab
->MText1b
);
4592 gtk_container_add(GTK_CONTAINER(tab
->MEventBox1b
), tab
->MText1b
);
4593 tab
->MText2
= gtk_label_new("s");
4594 gtk_widget_show(tab
->MText2
);
4595 tab
->MText3a
= gtk_label_new("ns");
4596 gtk_widget_show(tab
->MText3a
);
4598 tab
->MEventBox3b
= gtk_event_box_new();
4599 gtk_widget_show(tab
->MEventBox3b
);
4600 gtk_tooltips_set_tip(tab
->tooltips
, tab
->MEventBox3b
,
4601 "Paste End Time Here", "");
4602 tab
->MText3b
= gtk_label_new("end:");
4603 gtk_widget_show(tab
->MText3b
);
4604 gtk_container_add(GTK_CONTAINER(tab
->MEventBox3b
), tab
->MText3b
);
4605 tab
->MText4
= gtk_label_new("s");
4606 gtk_widget_show(tab
->MText4
);
4607 tab
->MText5a
= gtk_label_new("ns");
4608 gtk_widget_show(tab
->MText5a
);
4610 tab
->MEventBox8
= gtk_event_box_new();
4611 gtk_widget_show(tab
->MEventBox8
);
4612 gtk_tooltips_set_tip(tab
->tooltips
, tab
->MEventBox8
,
4613 "Paste Time Interval here", "");
4614 tab
->MText8
= gtk_label_new("Time Interval:");
4615 gtk_widget_show(tab
->MText8
);
4616 gtk_container_add(GTK_CONTAINER(tab
->MEventBox8
), tab
->MText8
);
4617 tab
->MText9
= gtk_label_new("s");
4618 gtk_widget_show(tab
->MText9
);
4619 tab
->MText10
= gtk_label_new("ns");
4620 gtk_widget_show(tab
->MText10
);
4622 tab
->MEventBox5b
= gtk_event_box_new();
4623 gtk_widget_show(tab
->MEventBox5b
);
4624 gtk_tooltips_set_tip(tab
->tooltips
, tab
->MEventBox5b
,
4625 "Paste Current Time Here", "");
4626 tab
->MText5b
= gtk_label_new("Current Time:");
4627 gtk_widget_show(tab
->MText5b
);
4628 gtk_container_add(GTK_CONTAINER(tab
->MEventBox5b
), tab
->MText5b
);
4629 tab
->MText6
= gtk_label_new("s");
4630 gtk_widget_show(tab
->MText6
);
4631 tab
->MText7
= gtk_label_new("ns");
4632 gtk_widget_show(tab
->MText7
);
4634 tab
->MEntry1
= gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4635 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab
->MEntry1
),0);
4636 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab
->MEntry1
),TRUE
);
4637 gtk_widget_show(tab
->MEntry1
);
4638 tab
->MEntry2
= gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4639 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab
->MEntry2
),0);
4640 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab
->MEntry2
),TRUE
);
4641 gtk_widget_show(tab
->MEntry2
);
4642 tab
->MEntry3
= gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4643 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab
->MEntry3
),0);
4644 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab
->MEntry3
),TRUE
);
4645 gtk_widget_show(tab
->MEntry3
);
4646 tab
->MEntry4
= gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4647 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab
->MEntry4
),0);
4648 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab
->MEntry4
),TRUE
);
4649 gtk_widget_show(tab
->MEntry4
);
4650 tab
->MEntry5
= gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4651 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab
->MEntry5
),0);
4652 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab
->MEntry5
),TRUE
);
4653 gtk_widget_show(tab
->MEntry5
);
4654 tab
->MEntry6
= gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4655 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab
->MEntry6
),0);
4656 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab
->MEntry6
),TRUE
);
4657 gtk_widget_show(tab
->MEntry6
);
4658 tab
->MEntry7
= gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4659 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab
->MEntry7
),0);
4660 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab
->MEntry7
),TRUE
);
4661 gtk_widget_show(tab
->MEntry7
);
4662 tab
->MEntry8
= gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4663 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab
->MEntry8
),0);
4664 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab
->MEntry8
),TRUE
);
4665 gtk_widget_show(tab
->MEntry8
);
4667 GtkWidget
*temp_widget
;
4669 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEventBox1a
, FALSE
,
4671 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEventBox1b
, FALSE
,
4673 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEntry1
, FALSE
, FALSE
, 0);
4674 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MText2
, FALSE
, FALSE
, 0);
4675 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEntry2
, FALSE
, FALSE
, 0);
4676 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MText3a
, FALSE
, FALSE
, 0);
4677 temp_widget
= gtk_vseparator_new();
4678 gtk_widget_show(temp_widget
);
4679 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), temp_widget
, FALSE
, FALSE
, 0);
4680 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEventBox3b
, FALSE
,
4682 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEntry3
, FALSE
, FALSE
, 0);
4683 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MText4
, FALSE
, FALSE
, 0);
4684 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEntry4
, FALSE
, FALSE
, 0);
4685 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MText5a
, FALSE
, FALSE
, 0);
4686 temp_widget
= gtk_vseparator_new();
4687 gtk_widget_show(temp_widget
);
4688 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), temp_widget
, FALSE
, FALSE
, 0);
4689 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEventBox8
, FALSE
,
4691 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEntry7
, FALSE
, FALSE
, 0);
4692 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MText9
, FALSE
, FALSE
, 0);
4693 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEntry8
, FALSE
, FALSE
, 0);
4694 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MText10
, FALSE
, FALSE
, 0);
4696 temp_widget
= gtk_vseparator_new();
4697 gtk_widget_show(temp_widget
);
4698 gtk_box_pack_end (GTK_BOX (tab
->MTimebar
), tab
->MText7
, FALSE
, FALSE
, 0);
4699 gtk_box_pack_end (GTK_BOX (tab
->MTimebar
), tab
->MEntry6
, FALSE
, FALSE
, 0);
4700 gtk_box_pack_end (GTK_BOX (tab
->MTimebar
), tab
->MText6
, FALSE
, FALSE
, 0);
4701 gtk_box_pack_end (GTK_BOX (tab
->MTimebar
), tab
->MEntry5
, FALSE
, FALSE
, 0);
4702 gtk_box_pack_end (GTK_BOX (tab
->MTimebar
), tab
->MEventBox5b
, FALSE
,
4704 gtk_box_pack_end (GTK_BOX (tab
->MTimebar
), temp_widget
, FALSE
, FALSE
, 0);
4707 //GtkWidget *test = gtk_button_new_with_label("drop");
4708 //gtk_button_set_relief(GTK_BUTTON(test), GTK_RELIEF_NONE);
4709 //gtk_widget_show(test);
4710 //gtk_box_pack_end(GTK_BOX (tab->MTimebar), test, FALSE, FALSE, 0);
4711 //gtk_widget_add_events(tab->MText1, GDK_ALL_EVENTS_MASK);//GDK_BUTTON_PRESS_MASK);
4712 /*GtkWidget *event_box = gtk_event_box_new();
4713 gtk_widget_show(event_box);
4714 gtk_tooltips_set_tip(tooltips, event_box,
4715 "Paste Current Time Here", "");
4716 gtk_box_pack_end(GTK_BOX (tab->MTimebar), event_box, FALSE, FALSE, 0);
4717 GtkWidget *test = gtk_label_new("drop");
4718 gtk_container_add(GTK_CONTAINER(event_box), test);
4719 gtk_widget_show(test);
4720 g_signal_connect (G_OBJECT(event_box),
4721 "button-press-event",
4722 G_CALLBACK (on_MText1_paste),
4726 g_signal_connect (G_OBJECT(tab
->MEventBox1a
),
4727 "button-press-event",
4728 G_CALLBACK (on_MEventBox1a_paste
),
4731 g_signal_connect (G_OBJECT(tab
->MEventBox1b
),
4732 "button-press-event",
4733 G_CALLBACK (on_MEventBox1b_paste
),
4735 g_signal_connect (G_OBJECT(tab
->MEventBox3b
),
4736 "button-press-event",
4737 G_CALLBACK (on_MEventBox3b_paste
),
4739 g_signal_connect (G_OBJECT(tab
->MEventBox5b
),
4740 "button-press-event",
4741 G_CALLBACK (on_MEventBox5b_paste
),
4743 g_signal_connect (G_OBJECT(tab
->MEventBox8
),
4744 "button-press-event",
4745 G_CALLBACK (on_MEventBox8_paste
),
4749 gtk_box_pack_end(GTK_BOX(tab
->vbox
),
4751 FALSE
, /* Do not expand */
4752 FALSE
, /* Fill has no effect here (expand false) */
4753 0); /* No padding */
4755 gtk_box_pack_end(GTK_BOX(tab
->vbox
),
4757 FALSE
, /* Do not expand */
4758 FALSE
, /* Fill has no effect here (expand false) */
4759 0); /* No padding */
4761 g_object_set_data(G_OBJECT(tab
->viewer_container
), "focused_viewer", NULL
);
4767 // Display a label with a X
4768 GtkWidget *w_hbox = gtk_hbox_new(FALSE, 4);
4769 GtkWidget *w_label = gtk_label_new (label);
4770 GtkWidget *pixmap = create_pixmap(GTK_WIDGET(notebook), "close.png");
4771 GtkWidget *w_button = gtk_button_new ();
4772 gtk_container_add(GTK_CONTAINER(w_button), pixmap);
4773 //GtkWidget *w_button = gtk_button_new_with_label("x");
4775 gtk_button_set_relief(GTK_BUTTON(w_button), GTK_RELIEF_NONE);
4777 gtk_box_pack_start(GTK_BOX(w_hbox), w_label, TRUE, TRUE, 0);
4778 gtk_box_pack_end(GTK_BOX(w_hbox), w_button, FALSE,
4781 g_signal_connect_swapped (w_button, "clicked",
4782 G_CALLBACK (on_close_tab_X_clicked),
4785 gtk_widget_set_state(w_button, GTK_STATE_ACTIVE);
4787 gtk_widget_show (w_label);
4788 gtk_widget_show (pixmap);
4789 gtk_widget_show (w_button);
4790 gtk_widget_show (w_hbox);
4792 tab->label = w_hbox;
4796 tab
->label
= gtk_label_new (label
);
4798 gtk_widget_show(tab
->label
);
4799 gtk_widget_show(tab
->scrollbar
);
4800 gtk_widget_show(tab
->viewer_container
);
4801 gtk_widget_show(tab
->vbox
);
4802 //gtk_widget_show(tab->multivpaned);
4805 /* Start with empty events requests list */
4806 tab
->events_requests
= NULL
;
4807 tab
->events_request_pending
= FALSE
;
4808 tab
->stop_foreground
= FALSE
;
4812 g_signal_connect(G_OBJECT(tab
->scrollbar
), "value-changed",
4813 G_CALLBACK(scroll_value_changed_cb
), tab
);
4815 g_signal_connect ((gpointer
) tab
->MEntry1
, "value-changed",
4816 G_CALLBACK (on_MEntry1_value_changed
),
4818 g_signal_connect ((gpointer
) tab
->MEntry2
, "value-changed",
4819 G_CALLBACK (on_MEntry2_value_changed
),
4821 g_signal_connect ((gpointer
) tab
->MEntry3
, "value-changed",
4822 G_CALLBACK (on_MEntry3_value_changed
),
4824 g_signal_connect ((gpointer
) tab
->MEntry4
, "value-changed",
4825 G_CALLBACK (on_MEntry4_value_changed
),
4827 g_signal_connect ((gpointer
) tab
->MEntry5
, "value-changed",
4828 G_CALLBACK (on_MEntry5_value_changed
),
4830 g_signal_connect ((gpointer
) tab
->MEntry6
, "value-changed",
4831 G_CALLBACK (on_MEntry6_value_changed
),
4833 g_signal_connect ((gpointer
) tab
->MEntry7
, "value-changed",
4834 G_CALLBACK (on_MEntry7_value_changed
),
4836 g_signal_connect ((gpointer
) tab
->MEntry8
, "value-changed",
4837 G_CALLBACK (on_MEntry8_value_changed
),
4840 //g_signal_connect(G_OBJECT(tab->scrollbar), "changed",
4841 // G_CALLBACK(scroll_value_changed_cb), tab);
4844 //insert tab into notebook
4845 gtk_notebook_append_page(notebook
,
4848 list
= gtk_container_get_children(GTK_CONTAINER(notebook
));
4849 gtk_notebook_set_current_page(notebook
,g_list_length(list
)-1);
4850 // always show : not if(g_list_length(list)>1)
4851 gtk_notebook_set_show_tabs(notebook
, TRUE
);
4854 lttvwindow_report_time_window(tab
, copy_tab
->time_window
);
4855 lttvwindow_report_current_time(tab
, copy_tab
->current_time
);
4857 TimeWindow time_window
;
4859 time_window
.start_time
= ltt_time_zero
;
4860 time_window
.end_time
= ltt_time_add(time_window
.start_time
,
4861 lttvwindow_default_time_width
);
4862 time_window
.time_width
= lttvwindow_default_time_width
;
4863 time_window
.time_width_double
= ltt_time_to_double(time_window
.time_width
);
4865 lttvwindow_report_time_window(tab
, time_window
);
4866 lttvwindow_report_current_time(tab
, ltt_time_zero
);
4869 LttvTraceset
*traceset
= tab
->traceset_info
->traceset
;
4870 SetTraceset(tab
, traceset
);
4874 * execute_events_requests
4876 * Idle function that executes the pending requests for a tab.
4878 * @return return value : TRUE : keep the idle function, FALSE : remove it.
4880 gboolean
execute_events_requests(Tab
*tab
)
4882 return ( lttvwindow_process_pending_requests(tab
) );
4886 __EXPORT
void create_main_window_with_trace_list(GSList
*traces
)
4888 GSList
*iter
= NULL
;
4891 MainWindow
*mw
= construct_main_window(NULL
);
4892 GtkWidget
*widget
= mw
->mwindow
;
4894 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
4895 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
4896 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
4897 LttvPluginTab
*ptab
;
4901 ptab
= create_new_tab(widget
, NULL
);
4904 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
4908 for(iter
=traces
; iter
!=NULL
; iter
=g_slist_next(iter
)) {
4909 gchar
*path
= (gchar
*)iter
->data
;
4911 gchar abs_path
[PATH_MAX
];
4915 get_absolute_pathname(path
, abs_path
);
4916 trace_v
= lttvwindowtraces_get_trace_by_name(abs_path
);
4917 if(trace_v
== NULL
) {
4918 trace
= ltt_trace_open(abs_path
);
4920 g_warning("cannot open trace %s", abs_path
);
4922 GtkWidget
*dialogue
=
4923 gtk_message_dialog_new(
4924 GTK_WINDOW(gtk_widget_get_toplevel(widget
)),
4925 GTK_DIALOG_MODAL
|GTK_DIALOG_DESTROY_WITH_PARENT
,
4928 "Cannot open trace : maybe you should enter in the directory "
4930 gtk_dialog_run(GTK_DIALOG(dialogue
));
4931 gtk_widget_destroy(dialogue
);
4933 trace_v
= lttv_trace_new(trace
);
4934 lttvwindowtraces_add_trace(trace_v
);
4935 lttvwindow_add_trace(tab
, trace_v
);
4938 lttvwindow_add_trace(tab
, trace_v
);
4942 LttvTraceset
*traceset
;
4944 traceset
= tab
->traceset_info
->traceset
;
4945 SetTraceset(tab
, traceset
);