1 /* This file is part of the Linux Trace Toolkit viewer
2 * Copyright (C) 2003-2004 XangXiu Yang, Mathieu Desnoyers
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License Version 2 as
6 * published by the Free Software Foundation;
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place - Suite 330, Boston,
23 #include <limits.h> // for PATH_MAX
31 #include "callbacks.h"
32 #include "interface.h"
34 #include <ltt/trace.h>
36 #include <ltt/event.h>
37 #include <lttv/lttv.h>
38 #include <lttv/module.h>
39 #include <lttv/iattribute.h>
40 #include <lttv/stats.h>
41 #include <lttv/filter.h>
42 #include <lttvwindow/mainwindow.h>
43 #include <lttvwindow/mainwindow-private.h>
44 #include <lttvwindow/menu.h>
45 #include <lttvwindow/toolbar.h>
46 #include <lttvwindow/lttvwindow.h>
47 #include <lttvwindow/lttvwindowtraces.h>
48 #include <lttvwindow/lttv_plugin_tab.h>
50 static LttTime lttvwindow_default_time_width
= { 1, 0 };
51 #define CLIP_BUF 256 // size of clipboard buffer
53 extern LttvTrace
*g_init_trace
;
56 /** Array containing instanced objects. */
57 extern GSList
* g_main_window_list
;
59 /** MD : keep old directory. */
60 static char remember_plugins_dir
[PATH_MAX
] = "";
61 static char remember_trace_dir
[PATH_MAX
] = "";
63 void tab_destructor(LttvPluginTab
* ptab
);
65 MainWindow
* get_window_data_struct(GtkWidget
* widget
);
66 char * get_load_module(MainWindow
*mw
,
67 char ** load_module_name
, int nb_module
);
68 char * get_unload_module(MainWindow
*mw
,
69 char ** loaded_module_name
, int nb_module
);
70 char * get_remove_trace(MainWindow
*mw
, char ** all_trace_name
, int nb_trace
);
71 char * get_selection(MainWindow
*mw
,
72 char ** all_name
, int nb
, char *title
, char * column_title
);
73 void init_tab(Tab
*tab
, MainWindow
* mw
, Tab
*copy_tab
,
74 GtkNotebook
* notebook
, char * label
);
76 static void insert_viewer(GtkWidget
* widget
, lttvwindow_viewer_constructor constructor
);
78 LttvPluginTab
*create_new_tab(GtkWidget
* widget
, gpointer user_data
);
80 static gboolean
lttvwindow_process_pending_requests(Tab
*tab
);
94 /* Pasting routines */
96 static void MEventBox1a_receive(GtkClipboard
*clipboard
,
100 if(text
== NULL
) return;
101 Tab
*tab
= (Tab
*)data
;
102 gchar buffer
[CLIP_BUF
];
103 gchar
*ptr
= buffer
, *ptr_ssec
, *ptr_snsec
, *ptr_esec
, *ptr_ensec
;
105 strncpy(buffer
, text
, CLIP_BUF
);
108 while(!isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
109 /* remove leading junk */
111 while(isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
112 /* read all the first number */
116 while(!isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
117 /* remove leading junk */
119 while(isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
120 /* read all the first number */
124 while(!isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
125 /* remove leading junk */
127 while(isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
128 /* read all the first number */
132 while(!isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
133 /* remove leading junk */
135 while(isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
136 /* read all the first number */
139 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry1
),
140 (double)strtoul(ptr_ssec
, NULL
, 10));
141 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry2
),
142 (double)strtoul(ptr_snsec
, NULL
, 10));
143 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry3
),
144 (double)strtoul(ptr_esec
, NULL
, 10));
145 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry4
),
146 (double)strtoul(ptr_ensec
, NULL
, 10));
149 static gboolean
on_MEventBox1a_paste(GtkWidget
*widget
, GdkEventButton
*event
,
152 Tab
*tab
= (Tab
*)data
;
154 GtkClipboard
*clip
= gtk_clipboard_get_for_display(gdk_display_get_default(),
155 GDK_SELECTION_PRIMARY
);
156 gtk_clipboard_request_text(clip
,
157 (GtkClipboardTextReceivedFunc
)MEventBox1a_receive
,
164 static void MEventBox1b_receive(GtkClipboard
*clipboard
,
168 if(text
== NULL
) return;
169 Tab
*tab
= (Tab
*)data
;
170 gchar buffer
[CLIP_BUF
];
171 gchar
*ptr
= buffer
, *ptr_sec
, *ptr_nsec
;
173 strncpy(buffer
, text
, CLIP_BUF
);
175 while(!isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
176 /* remove leading junk */
178 while(isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
179 /* read all the first number */
183 while(!isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
184 /* remove leading junk */
186 while(isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
187 /* read all the first number */
190 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry1
),
191 (double)strtoul(ptr_sec
, NULL
, 10));
192 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry2
),
193 (double)strtoul(ptr_nsec
, NULL
, 10));
197 static gboolean
on_MEventBox1b_paste(GtkWidget
*widget
, GdkEventButton
*event
,
200 Tab
*tab
= (Tab
*)data
;
202 GtkClipboard
*clip
= gtk_clipboard_get_for_display(gdk_display_get_default(),
203 GDK_SELECTION_PRIMARY
);
204 gtk_clipboard_request_text(clip
,
205 (GtkClipboardTextReceivedFunc
)MEventBox1b_receive
,
211 static void MEventBox3b_receive(GtkClipboard
*clipboard
,
215 if(text
== NULL
) return;
216 Tab
*tab
= (Tab
*)data
;
217 gchar buffer
[CLIP_BUF
];
218 gchar
*ptr
= buffer
, *ptr_sec
, *ptr_nsec
;
220 strncpy(buffer
, text
, CLIP_BUF
);
222 while(!isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
223 /* remove leading junk */
225 while(isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
226 /* read all the first number */
230 while(!isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
231 /* remove leading junk */
233 while(isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
234 /* read all the first number */
237 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry3
),
238 (double)strtoul(ptr_sec
, NULL
, 10));
239 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry4
),
240 (double)strtoul(ptr_nsec
, NULL
, 10));
244 static gboolean
on_MEventBox3b_paste(GtkWidget
*widget
, GdkEventButton
*event
,
247 Tab
*tab
= (Tab
*)data
;
249 GtkClipboard
*clip
= gtk_clipboard_get_for_display(gdk_display_get_default(),
250 GDK_SELECTION_PRIMARY
);
251 gtk_clipboard_request_text(clip
,
252 (GtkClipboardTextReceivedFunc
)MEventBox3b_receive
,
258 static void MEventBox5b_receive(GtkClipboard
*clipboard
,
262 if(text
== NULL
) return;
263 Tab
*tab
= (Tab
*)data
;
264 gchar buffer
[CLIP_BUF
];
265 gchar
*ptr
= buffer
, *ptr_sec
, *ptr_nsec
;
267 strncpy(buffer
, text
, CLIP_BUF
);
269 while(!isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
270 /* remove leading junk */
272 while(isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
273 /* read all the first number */
277 while(!isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
278 /* remove leading junk */
280 while(isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
281 /* read all the first number */
284 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry5
),
285 (double)strtoul(ptr_sec
, NULL
, 10));
286 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry6
),
287 (double)strtoul(ptr_nsec
, NULL
, 10));
291 static gboolean
on_MEventBox5b_paste(GtkWidget
*widget
, GdkEventButton
*event
,
294 Tab
*tab
= (Tab
*)data
;
296 GtkClipboard
*clip
= gtk_clipboard_get_for_display(gdk_display_get_default(),
297 GDK_SELECTION_PRIMARY
);
298 gtk_clipboard_request_text(clip
,
299 (GtkClipboardTextReceivedFunc
)MEventBox5b_receive
,
305 static void MEventBox8_receive(GtkClipboard
*clipboard
,
309 if(text
== NULL
) return;
310 Tab
*tab
= (Tab
*)data
;
311 gchar buffer
[CLIP_BUF
];
312 gchar
*ptr
= buffer
, *ptr_sec
, *ptr_nsec
;
314 strncpy(buffer
, text
, CLIP_BUF
);
316 while(!isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
317 /* remove leading junk */
319 while(isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
320 /* read all the first number */
324 while(!isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
325 /* remove leading junk */
327 while(isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
328 /* read all the first number */
331 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry7
),
332 (double)strtoul(ptr_sec
, NULL
, 10));
333 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry8
),
334 (double)strtoul(ptr_nsec
, NULL
, 10));
338 static gboolean
on_MEventBox8_paste(GtkWidget
*widget
, GdkEventButton
*event
,
341 Tab
*tab
= (Tab
*)data
;
343 GtkClipboard
*clip
= gtk_clipboard_get_for_display(gdk_display_get_default(),
344 GDK_SELECTION_PRIMARY
);
345 gtk_clipboard_request_text(clip
,
346 (GtkClipboardTextReceivedFunc
)MEventBox8_receive
,
352 static void on_top_notify(GObject
*gobject
,
356 Tab
*tab
= (Tab
*)user_data
;
357 g_message("in on_top_notify.\n");
361 static gboolean
viewer_grab_focus(GtkWidget
*widget
, GdkEventButton
*event
,
364 GtkWidget
*viewer
= GTK_WIDGET(data
);
365 GtkWidget
*viewer_container
= gtk_widget_get_parent(viewer
);
367 g_debug("FOCUS GRABBED");
368 g_object_set_data(G_OBJECT(viewer_container
), "focused_viewer", viewer
);
373 static void connect_focus_recursive(GtkWidget
*widget
,
376 if(GTK_IS_CONTAINER(widget
)) {
377 gtk_container_forall(GTK_CONTAINER(widget
),
378 (GtkCallback
)connect_focus_recursive
,
382 if(GTK_IS_TREE_VIEW(widget
)) {
383 gtk_tree_view_set_headers_clickable(GTK_TREE_VIEW(widget
), TRUE
);
385 gtk_widget_add_events(widget
, GDK_BUTTON_PRESS_MASK
);
386 g_signal_connect (G_OBJECT(widget
),
387 "button-press-event",
388 G_CALLBACK (viewer_grab_focus
),
392 /* Stop all the processings and call gtk_main_quit() */
393 static void mainwindow_quit()
395 lttvwindowtraces_unregister_requests(g_quark_from_string("stats"));
396 lttvwindowtraces_unregister_requests(g_quark_from_string("state"));
397 lttvwindowtraces_unregister_computation_hooks(g_quark_from_string("stats"));
398 lttvwindowtraces_unregister_computation_hooks(g_quark_from_string("state"));
404 /* insert_viewer function constructs an instance of a viewer first,
405 * then inserts the widget of the instance into the container of the
410 insert_viewer_wrap(GtkWidget
*menuitem
, gpointer user_data
)
412 insert_viewer((GtkWidget
*)menuitem
, (lttvwindow_viewer_constructor
)user_data
);
416 /* internal functions */
417 void insert_viewer(GtkWidget
* widget
, lttvwindow_viewer_constructor constructor
)
419 GtkWidget
* viewer_container
;
420 MainWindow
* mw_data
= get_window_data_struct(widget
);
421 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
423 TimeInterval
* time_interval
;
424 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
425 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
430 ptab
= create_new_tab(widget
, NULL
);
432 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
436 viewer_container
= tab
->viewer_container
;
438 viewer
= (GtkWidget
*)constructor(ptab
);
441 //gtk_multivpaned_widget_add(GTK_MULTIVPANED(multivpaned), viewer);
443 gtk_box_pack_end(GTK_BOX(viewer_container
),
449 /* We want to connect the viewer_grab_focus to EVERY
450 * child of this widget. The little trick is to get each child
451 * of each GTK_CONTAINER, even subchildren.
453 connect_focus_recursive(viewer
, viewer
);
458 * Function to set/update traceset for the viewers
459 * @param tab viewer's tab
460 * @param traceset traceset of the main window.
462 * 0 : traceset updated
463 * 1 : no traceset hooks to update; not an error.
466 int SetTraceset(Tab
* tab
, LttvTraceset
*traceset
)
468 LttvTracesetContext
*tsc
=
469 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
470 TimeInterval time_span
= tsc
->time_span
;
471 TimeWindow new_time_window
= tab
->time_window
;
472 LttTime new_current_time
= tab
->current_time
;
474 /* Set the tab's time window and current time if
476 if(ltt_time_compare(tab
->time_window
.start_time
, time_span
.start_time
) < 0
477 || ltt_time_compare(tab
->time_window
.end_time
,
478 time_span
.end_time
) > 0) {
479 new_time_window
.start_time
= time_span
.start_time
;
481 new_current_time
= time_span
.start_time
;
485 if(ltt_time_compare(lttvwindow_default_time_width
,
486 ltt_time_sub(time_span
.end_time
, time_span
.start_time
)) < 0
488 ltt_time_compare(time_span
.end_time
, time_span
.start_time
) == 0)
489 tmp_time
= lttvwindow_default_time_width
;
491 tmp_time
= time_span
.end_time
;
493 new_time_window
.time_width
= tmp_time
;
494 new_time_window
.time_width_double
= ltt_time_to_double(tmp_time
);
495 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
496 new_time_window
.time_width
) ;
503 GtkAdjustment
*adjustment
= gtk_range_get_adjustment(GTK_RANGE(tab
->scrollbar
));
504 LttTime upper
= ltt_time_sub(time_span
.end_time
, time_span
.start_time
);
506 g_object_set(G_OBJECT(adjustment
),
510 ltt_time_to_double(upper
)
511 * NANOSECONDS_PER_SECOND
, /* upper */
513 ltt_time_to_double(tab
->time_window
.time_width
)
514 / SCROLL_STEP_PER_PAGE
515 * NANOSECONDS_PER_SECOND
, /* step increment */
517 ltt_time_to_double(tab
->time_window
.time_width
)
518 * NANOSECONDS_PER_SECOND
, /* page increment */
520 ltt_time_to_double(tab
->time_window
.time_width
)
521 * NANOSECONDS_PER_SECOND
, /* page size */
523 gtk_adjustment_changed(adjustment
);
525 g_object_set(G_OBJECT(adjustment
),
528 ltt_time_sub(tab
->time_window
.start_time
, time_span
.start_time
))
529 * NANOSECONDS_PER_SECOND
, /* value */
531 gtk_adjustment_value_changed(adjustment
);
533 /* set the time bar. The value callbacks will change their nsec themself */
535 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry1
),
536 (double)time_span
.start_time
.tv_sec
,
537 (double)time_span
.end_time
.tv_sec
);
540 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry3
),
541 (double)time_span
.start_time
.tv_sec
,
542 (double)time_span
.end_time
.tv_sec
);
544 /* current seconds */
545 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry5
),
546 (double)time_span
.start_time
.tv_sec
,
547 (double)time_span
.end_time
.tv_sec
);
550 /* Finally, call the update hooks of the viewers */
552 LttvAttributeValue value
;
556 retval
= lttv_iattribute_find_by_path(tab
->attributes
,
557 "hooks/updatetraceset", LTTV_POINTER
, &value
);
560 tmp
= (LttvHooks
*)*(value
.v_pointer
);
561 if(tmp
== NULL
) retval
= 1;
562 else lttv_hooks_call(tmp
,traceset
);
564 time_change_manager(tab
, new_time_window
);
565 current_time_change_manager(tab
, new_current_time
);
571 * Function to set/update filter for the viewers
572 * @param tab viewer's tab
573 * @param filter filter of the main window.
576 * 0 : filters updated
577 * 1 : no filter hooks to update; not an error.
580 int SetFilter(Tab
* tab
, gpointer filter
)
583 LttvAttributeValue value
;
585 g_assert(lttv_iattribute_find_by_path(tab
->attributes
,
586 "hooks/updatefilter", LTTV_POINTER
, &value
));
588 tmp
= (LttvHooks
*)*(value
.v_pointer
);
590 if(tmp
== NULL
) return 1;
591 lttv_hooks_call(tmp
,filter
);
599 * Function to redraw each viewer belonging to the current tab
600 * @param tab viewer's tab
603 void update_traceset(Tab
*tab
)
605 LttvAttributeValue value
;
609 retval
= lttv_iattribute_find_by_path(tab
->attributes
,
610 "hooks/updatetraceset", LTTV_POINTER
, &value
);
612 tmp
= (LttvHooks
*)*(value
.v_pointer
);
613 if(tmp
== NULL
) return;
614 lttv_hooks_call(tmp
, NULL
);
618 /* get_label function is used to get user input, it displays an input
619 * box, which allows user to input a string
622 void get_label_string (GtkWidget
* text
, gchar
* label
)
624 GtkEntry
* entry
= (GtkEntry
*)text
;
625 if(strlen(gtk_entry_get_text(entry
))!=0)
626 strcpy(label
,gtk_entry_get_text(entry
));
629 gboolean
get_label(MainWindow
* mw
, gchar
* str
, gchar
* dialogue_title
, gchar
* label_str
)
631 GtkWidget
* dialogue
;
636 dialogue
= gtk_dialog_new_with_buttons(dialogue_title
,NULL
,
638 GTK_STOCK_OK
,GTK_RESPONSE_ACCEPT
,
639 GTK_STOCK_CANCEL
,GTK_RESPONSE_REJECT
,
642 label
= gtk_label_new(label_str
);
643 gtk_widget_show(label
);
645 text
= gtk_entry_new();
646 gtk_widget_show(text
);
648 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialogue
)->vbox
), label
,TRUE
, TRUE
,0);
649 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialogue
)->vbox
), text
,FALSE
, FALSE
,0);
651 id
= gtk_dialog_run(GTK_DIALOG(dialogue
));
653 case GTK_RESPONSE_ACCEPT
:
654 get_label_string(text
,str
);
655 gtk_widget_destroy(dialogue
);
657 case GTK_RESPONSE_REJECT
:
659 gtk_widget_destroy(dialogue
);
666 /* get_window_data_struct function is actually a lookup function,
667 * given a widget which is in the tree of the main window, it will
668 * return the MainWindow data structure associated with main window
671 MainWindow
* get_window_data_struct(GtkWidget
* widget
)
674 MainWindow
* mw_data
;
676 mw
= lookup_widget(widget
, "MWindow");
678 g_info("Main window does not exist\n");
682 mw_data
= (MainWindow
*) g_object_get_data(G_OBJECT(mw
),"main_window_data");
684 g_warning("Main window data does not exist\n");
691 /* create_new_window function, just constructs a new main window
694 void create_new_window(GtkWidget
* widget
, gpointer user_data
, gboolean clone
)
696 MainWindow
* parent
= get_window_data_struct(widget
);
699 g_info("Clone : use the same traceset\n");
700 construct_main_window(parent
);
702 g_info("Empty : traceset is set to NULL\n");
703 construct_main_window(NULL
);
707 /* Get the currently focused viewer.
708 * If no viewer is focused, use the first one.
710 * If no viewer available, return NULL.
712 GtkWidget
*viewer_container_focus(GtkWidget
*container
)
716 widget
= (GtkWidget
*)g_object_get_data(G_OBJECT(container
),
720 g_debug("no widget focused");
721 GList
*children
= gtk_container_get_children(GTK_CONTAINER(container
));
724 widget
= GTK_WIDGET(children
->data
);
725 g_object_set_data(G_OBJECT(container
),
735 gint
viewer_container_position(GtkWidget
*container
, GtkWidget
*child
)
738 if(child
== NULL
) return -1;
742 memset(&value
, 0, sizeof(GValue
));
743 g_value_init(&value
, G_TYPE_INT
);
744 gtk_container_child_get_property(GTK_CONTAINER(container
),
748 pos
= g_value_get_int(&value
);
754 /* move_*_viewer functions move the selected view up/down in
758 void move_down_viewer(GtkWidget
* widget
, gpointer user_data
)
760 MainWindow
* mw
= get_window_data_struct(widget
);
761 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
763 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
764 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
771 ptab
= g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
775 //gtk_multivpaned_widget_move_up(GTK_MULTIVPANED(tab->multivpaned));
777 /* change the position in the vbox */
778 GtkWidget
*focus_widget
;
780 focus_widget
= viewer_container_focus(tab
->viewer_container
);
781 position
= viewer_container_position(tab
->viewer_container
, focus_widget
);
784 /* can move up one position */
785 gtk_box_reorder_child(GTK_BOX(tab
->viewer_container
),
792 void move_up_viewer(GtkWidget
* widget
, gpointer user_data
)
794 MainWindow
* mw
= get_window_data_struct(widget
);
795 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
797 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
798 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
805 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
809 //gtk_multivpaned_widget_move_down(GTK_MULTIVPANED(tab->multivpaned));
810 /* change the position in the vbox */
811 GtkWidget
*focus_widget
;
813 focus_widget
= viewer_container_focus(tab
->viewer_container
);
814 position
= viewer_container_position(tab
->viewer_container
, focus_widget
);
818 g_list_length(gtk_container_get_children(
819 GTK_CONTAINER(tab
->viewer_container
)))-1
821 /* can move down one position */
822 gtk_box_reorder_child(GTK_BOX(tab
->viewer_container
),
830 /* delete_viewer deletes the selected viewer in the current tab
833 void delete_viewer(GtkWidget
* widget
, gpointer user_data
)
835 MainWindow
* mw
= get_window_data_struct(widget
);
836 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
838 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
839 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
846 ptab
= g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
850 //gtk_multivpaned_widget_delete(GTK_MULTIVPANED(tab->multivpaned));
852 GtkWidget
*focus_widget
= viewer_container_focus(tab
->viewer_container
);
854 if(focus_widget
!= NULL
)
855 gtk_widget_destroy(focus_widget
);
857 g_object_set_data(G_OBJECT(tab
->viewer_container
), "focused_viewer", NULL
);
861 /* open_traceset will open a traceset saved in a file
862 * Right now, it is not finished yet, (not working)
866 void open_traceset(GtkWidget
* widget
, gpointer user_data
)
870 LttvTraceset
* traceset
;
871 MainWindow
* mw_data
= get_window_data_struct(widget
);
872 GtkFileSelection
* file_selector
=
873 (GtkFileSelection
*)gtk_file_selection_new("Select a traceset");
875 gtk_file_selection_hide_fileop_buttons(file_selector
);
877 gtk_window_set_transient_for(GTK_WINDOW(file_selector
),
878 GTK_WINDOW(mw_data
->mwindow
));
880 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
882 case GTK_RESPONSE_ACCEPT
:
883 case GTK_RESPONSE_OK
:
884 dir
= gtk_file_selection_get_selections (file_selector
);
885 traceset
= lttv_traceset_load(dir
[0]);
886 g_info("Open a trace set %s\n", dir
[0]);
889 case GTK_RESPONSE_REJECT
:
890 case GTK_RESPONSE_CANCEL
:
892 gtk_widget_destroy((GtkWidget
*)file_selector
);
898 /* lttvwindow_process_pending_requests
900 * Process requests for parts of the trace from viewers.
902 * These requests are made by lttvwindow_events_request().
904 * This internal function gets called by g_idle, taking care of the pending
905 * requests. It is responsible for concatenation of time intervals and position
906 * requests. It does it with the following algorithm organizing process traceset
907 * calls. Here is the detailed description of the way it works :
909 * - Events Requests Servicing Algorithm
911 * Data structures necessary :
913 * List of requests added to context : list_in
914 * List of requests not added to context : list_out
919 * list_out : many events requests
921 * FIXME : insert rest of algorithm here
925 #define list_out tab->events_requests
927 gboolean
lttvwindow_process_pending_requests(Tab
*tab
)
930 LttvTracesetContext
*tsc
;
931 LttvTracefileContext
*tfc
;
932 GSList
*list_in
= NULL
;
936 LttvTracesetContextPosition
*end_position
;
938 if(lttvwindow_preempt_count
> 0) return TRUE
;
941 g_critical("Foreground processing : tab does not exist. Processing removed.");
945 /* There is no events requests pending : we should never have been called! */
946 g_assert(g_slist_length(list_out
) != 0);
948 tsc
= LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
950 //set the cursor to be X shape, indicating that the computer is busy in doing its job
952 new = gdk_cursor_new(GDK_X_CURSOR
);
953 widget
= lookup_widget(tab
->mw
->mwindow
, "MToolbar1");
954 win
= gtk_widget_get_parent_window(widget
);
955 gdk_window_set_cursor(win
, new);
956 gdk_cursor_unref(new);
957 gdk_window_stick(win
);
958 gdk_window_unstick(win
);
961 g_debug("SIZE events req len : %d", g_slist_length(list_out
));
963 /* Preliminary check for no trace in traceset */
964 /* Unregister the routine if empty, empty list_out too */
965 if(lttv_traceset_number(tsc
->ts
) == 0) {
967 /* - For each req in list_out */
968 GSList
*iter
= list_out
;
970 while(iter
!= NULL
) {
972 gboolean remove
= FALSE
;
973 gboolean free_data
= FALSE
;
974 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
976 /* - Call end request for req */
977 if(events_request
->servicing
== TRUE
)
978 lttv_hooks_call(events_request
->after_request
, (gpointer
)tsc
);
980 /* - remove req from list_out */
981 /* Destroy the request */
988 GSList
*remove_iter
= iter
;
990 iter
= g_slist_next(iter
);
991 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
992 list_out
= g_slist_remove_link(list_out
, remove_iter
);
993 } else { // not remove
994 iter
= g_slist_next(iter
);
999 /* 0.1 Lock Traces */
1004 iter_trace
<lttv_traceset_number(tsc
->ts
);
1006 LttvTrace
*trace_v
= lttv_traceset_get(tsc
->ts
, iter_trace
);
1008 if(lttvwindowtraces_lock(trace_v
) != 0) {
1009 g_critical("Foreground processing : Unable to get trace lock");
1010 return TRUE
; /* Cannot get lock, try later */
1015 /* 0.2 Seek tracefiles positions to context position */
1016 //g_assert(lttv_process_traceset_seek_position(tsc, sync_position) == 0);
1017 lttv_process_traceset_synchronize_tracefiles(tsc
);
1020 /* Events processing algorithm implementation */
1021 /* Warning : the gtk_events_pending takes a LOT of cpu time. So what we do
1022 * instead is to leave the control to GTK and take it back.
1024 /* A. Servicing loop */
1025 //while( (g_slist_length(list_in) != 0 || g_slist_length(list_out) != 0)) {
1026 if((g_slist_length(list_in
) != 0 || g_slist_length(list_out
) != 0)) {
1028 /* 1. If list_in is empty (need a seek) */
1029 if( g_slist_length(list_in
) == 0 ) {
1031 /* list in is empty, need a seek */
1033 /* 1.1 Add requests to list_in */
1034 GSList
*ltime
= NULL
;
1035 GSList
*lpos
= NULL
;
1036 GSList
*iter
= NULL
;
1038 /* 1.1.1 Find all time requests with the lowest start time in list_out
1041 if(g_slist_length(list_out
) > 0)
1042 ltime
= g_slist_append(ltime
, g_slist_nth_data(list_out
, 0));
1043 for(iter
=g_slist_nth(list_out
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
1044 /* Find all time requests with the lowest start time in list_out */
1045 EventsRequest
*event_request_ltime
= (EventsRequest
*)g_slist_nth_data(ltime
, 0);
1046 EventsRequest
*event_request_list_out
= (EventsRequest
*)iter
->data
;
1049 comp
= ltt_time_compare(event_request_ltime
->start_time
,
1050 event_request_list_out
->start_time
);
1052 ltime
= g_slist_append(ltime
, event_request_list_out
);
1054 /* Remove all elements from ltime, and add current */
1055 while(ltime
!= NULL
)
1056 ltime
= g_slist_delete_link(ltime
, g_slist_nth(ltime
, 0));
1057 ltime
= g_slist_append(ltime
, event_request_list_out
);
1061 /* 1.1.2 Find all position requests with the lowest position in list_out
1064 if(g_slist_length(list_out
) > 0)
1065 lpos
= g_slist_append(lpos
, g_slist_nth_data(list_out
, 0));
1066 for(iter
=g_slist_nth(list_out
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
1067 /* Find all position requests with the lowest position in list_out */
1068 EventsRequest
*event_request_lpos
= (EventsRequest
*)g_slist_nth_data(lpos
, 0);
1069 EventsRequest
*event_request_list_out
= (EventsRequest
*)iter
->data
;
1072 if(event_request_lpos
->start_position
!= NULL
1073 && event_request_list_out
->start_position
!= NULL
)
1075 comp
= lttv_traceset_context_pos_pos_compare
1076 (event_request_lpos
->start_position
,
1077 event_request_list_out
->start_position
);
1082 lpos
= g_slist_append(lpos
, event_request_list_out
);
1084 /* Remove all elements from lpos, and add current */
1086 lpos
= g_slist_delete_link(lpos
, g_slist_nth(lpos
, 0));
1087 lpos
= g_slist_append(lpos
, event_request_list_out
);
1092 EventsRequest
*event_request_lpos
= (EventsRequest
*)g_slist_nth_data(lpos
, 0);
1093 EventsRequest
*event_request_ltime
= (EventsRequest
*)g_slist_nth_data(ltime
, 0);
1094 LttTime lpos_start_time
;
1096 if(event_request_lpos
!= NULL
1097 && event_request_lpos
->start_position
!= NULL
) {
1098 lpos_start_time
= lttv_traceset_context_position_get_time(
1099 event_request_lpos
->start_position
);
1102 /* 1.1.3 If lpos.start time < ltime */
1103 if(event_request_lpos
!= NULL
1104 && event_request_lpos
->start_position
!= NULL
1105 && ltt_time_compare(lpos_start_time
,
1106 event_request_ltime
->start_time
)<0) {
1107 /* Add lpos to list_in, remove them from list_out */
1108 for(iter
=lpos
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
1109 /* Add to list_in */
1110 EventsRequest
*event_request_lpos
=
1111 (EventsRequest
*)iter
->data
;
1113 list_in
= g_slist_append(list_in
, event_request_lpos
);
1114 /* Remove from list_out */
1115 list_out
= g_slist_remove(list_out
, event_request_lpos
);
1118 /* 1.1.4 (lpos.start time >= ltime) */
1119 /* Add ltime to list_in, remove them from list_out */
1121 for(iter
=ltime
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
1122 /* Add to list_in */
1123 EventsRequest
*event_request_ltime
=
1124 (EventsRequest
*)iter
->data
;
1126 list_in
= g_slist_append(list_in
, event_request_ltime
);
1127 /* Remove from list_out */
1128 list_out
= g_slist_remove(list_out
, event_request_ltime
);
1133 g_slist_free(ltime
);
1138 tfc
= lttv_traceset_context_get_current_tfc(tsc
);
1139 g_assert(g_slist_length(list_in
)>0);
1140 EventsRequest
*events_request
= g_slist_nth_data(list_in
, 0);
1143 /* 1.2.1 If first request in list_in is a time request */
1144 if(events_request
->start_position
== NULL
) {
1145 /* - If first req in list_in start time != current time */
1146 if(tfc
== NULL
|| ltt_time_compare(events_request
->start_time
,
1147 tfc
->timestamp
) != 0)
1148 /* - Seek to that time */
1149 g_debug("SEEK TIME : %lu, %lu", events_request
->start_time
.tv_sec
,
1150 events_request
->start_time
.tv_nsec
);
1151 //lttv_process_traceset_seek_time(tsc, events_request->start_time);
1152 lttv_state_traceset_seek_time_closest(LTTV_TRACESET_STATE(tsc
),
1153 events_request
->start_time
);
1155 /* Process the traceset with only state hooks */
1157 lttv_process_traceset_middle(tsc
,
1158 events_request
->start_time
,
1161 g_assert(seek_count
< LTTV_STATE_SAVE_INTERVAL
);
1167 LttvTracefileContext
*tfc
=
1168 lttv_traceset_context_get_current_tfc(tsc
);
1169 /* Else, the first request in list_in is a position request */
1170 /* If first req in list_in pos != current pos */
1171 g_assert(events_request
->start_position
!= NULL
);
1172 g_debug("SEEK POS time : %lu, %lu",
1173 lttv_traceset_context_position_get_time(
1174 events_request
->start_position
).tv_sec
,
1175 lttv_traceset_context_position_get_time(
1176 events_request
->start_position
).tv_nsec
);
1179 g_debug("SEEK POS context time : %lu, %lu",
1180 tfc
->timestamp
.tv_sec
,
1181 tfc
->timestamp
.tv_nsec
);
1183 g_debug("SEEK POS context time : %lu, %lu",
1184 ltt_time_infinite
.tv_sec
,
1185 ltt_time_infinite
.tv_nsec
);
1187 g_assert(events_request
->start_position
!= NULL
);
1188 if(lttv_traceset_context_ctx_pos_compare(tsc
,
1189 events_request
->start_position
) != 0) {
1190 /* 1.2.2.1 Seek to that position */
1191 g_debug("SEEK POSITION");
1192 //lttv_process_traceset_seek_position(tsc, events_request->start_position);
1193 pos_time
= lttv_traceset_context_position_get_time(
1194 events_request
->start_position
);
1196 lttv_state_traceset_seek_time_closest(LTTV_TRACESET_STATE(tsc
),
1199 /* Process the traceset with only state hooks */
1201 lttv_process_traceset_middle(tsc
,
1204 events_request
->start_position
);
1205 g_assert(lttv_traceset_context_ctx_pos_compare(tsc
,
1206 events_request
->start_position
) == 0);
1213 /* 1.3 Add hooks and call before request for all list_in members */
1215 GSList
*iter
= NULL
;
1217 for(iter
=list_in
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
1218 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1219 /* 1.3.1 If !servicing */
1220 if(events_request
->servicing
== FALSE
) {
1221 /* - begin request hooks called
1222 * - servicing = TRUE
1224 lttv_hooks_call(events_request
->before_request
, (gpointer
)tsc
);
1225 events_request
->servicing
= TRUE
;
1227 /* 1.3.2 call before chunk
1228 * 1.3.3 events hooks added
1230 if(events_request
->trace
== -1)
1231 lttv_process_traceset_begin(tsc
,
1232 events_request
->before_chunk_traceset
,
1233 events_request
->before_chunk_trace
,
1234 events_request
->before_chunk_tracefile
,
1235 events_request
->event
,
1236 events_request
->event_by_id_channel
);
1238 guint nb_trace
= lttv_traceset_number(tsc
->ts
);
1239 g_assert((guint
)events_request
->trace
< nb_trace
&&
1240 events_request
->trace
> -1);
1241 LttvTraceContext
*tc
= tsc
->traces
[events_request
->trace
];
1243 lttv_hooks_call(events_request
->before_chunk_traceset
, tsc
);
1245 lttv_trace_context_add_hooks(tc
,
1246 events_request
->before_chunk_trace
,
1247 events_request
->before_chunk_tracefile
,
1248 events_request
->event
,
1249 events_request
->event_by_id_channel
);
1254 /* 2. Else, list_in is not empty, we continue a read */
1257 /* 2.0 For each req of list_in */
1258 GSList
*iter
= list_in
;
1260 while(iter
!= NULL
) {
1262 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1264 /* - Call before chunk
1265 * - events hooks added
1267 if(events_request
->trace
== -1)
1268 lttv_process_traceset_begin(tsc
,
1269 events_request
->before_chunk_traceset
,
1270 events_request
->before_chunk_trace
,
1271 events_request
->before_chunk_tracefile
,
1272 events_request
->event
,
1273 events_request
->event_by_id_channel
);
1275 guint nb_trace
= lttv_traceset_number(tsc
->ts
);
1276 g_assert((guint
)events_request
->trace
< nb_trace
&&
1277 events_request
->trace
> -1);
1278 LttvTraceContext
*tc
= tsc
->traces
[events_request
->trace
];
1280 lttv_hooks_call(events_request
->before_chunk_traceset
, tsc
);
1282 lttv_trace_context_add_hooks(tc
,
1283 events_request
->before_chunk_trace
,
1284 events_request
->before_chunk_tracefile
,
1285 events_request
->event
,
1286 events_request
->event_by_id_channel
);
1289 iter
= g_slist_next(iter
);
1294 tfc
= lttv_traceset_context_get_current_tfc(tsc
);
1296 /* 2.1 For each req of list_out */
1297 GSList
*iter
= list_out
;
1299 while(iter
!= NULL
) {
1301 gboolean remove
= FALSE
;
1302 gboolean free_data
= FALSE
;
1303 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1305 /* if req.start time == current context time
1306 * or req.start position == current position*/
1307 if( ltt_time_compare(events_request
->start_time
,
1308 tfc
->timestamp
) == 0
1310 (events_request
->start_position
!= NULL
1312 lttv_traceset_context_ctx_pos_compare(tsc
,
1313 events_request
->start_position
) == 0)
1315 /* - Add to list_in, remove from list_out */
1316 list_in
= g_slist_append(list_in
, events_request
);
1320 /* - If !servicing */
1321 if(events_request
->servicing
== FALSE
) {
1322 /* - begin request hooks called
1323 * - servicing = TRUE
1325 lttv_hooks_call(events_request
->before_request
, (gpointer
)tsc
);
1326 events_request
->servicing
= TRUE
;
1328 /* call before chunk
1329 * events hooks added
1331 if(events_request
->trace
== -1)
1332 lttv_process_traceset_begin(tsc
,
1333 events_request
->before_chunk_traceset
,
1334 events_request
->before_chunk_trace
,
1335 events_request
->before_chunk_tracefile
,
1336 events_request
->event
,
1337 events_request
->event_by_id_channel
);
1339 guint nb_trace
= lttv_traceset_number(tsc
->ts
);
1340 g_assert((guint
)events_request
->trace
< nb_trace
&&
1341 events_request
->trace
> -1);
1342 LttvTraceContext
*tc
= tsc
->traces
[events_request
->trace
];
1344 lttv_hooks_call(events_request
->before_chunk_traceset
, tsc
);
1346 lttv_trace_context_add_hooks(tc
,
1347 events_request
->before_chunk_trace
,
1348 events_request
->before_chunk_tracefile
,
1349 events_request
->event
,
1350 events_request
->event_by_id_channel
);
1359 GSList
*remove_iter
= iter
;
1361 iter
= g_slist_next(iter
);
1362 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
1363 list_out
= g_slist_remove_link(list_out
, remove_iter
);
1364 } else { // not remove
1365 iter
= g_slist_next(iter
);
1371 /* 3. Find end criterions */
1376 /* 3.1.1 Find lowest end time in list_in */
1377 g_assert(g_slist_length(list_in
)>0);
1378 end_time
= ((EventsRequest
*)g_slist_nth_data(list_in
,0))->end_time
;
1380 for(iter
=g_slist_nth(list_in
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
1381 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1383 if(ltt_time_compare(events_request
->end_time
,
1385 end_time
= events_request
->end_time
;
1388 /* 3.1.2 Find lowest start time in list_out */
1389 for(iter
=list_out
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
1390 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1392 if(ltt_time_compare(events_request
->start_time
,
1394 end_time
= events_request
->start_time
;
1399 /* 3.2 Number of events */
1401 /* 3.2.1 Find lowest number of events in list_in */
1404 end_nb_events
= ((EventsRequest
*)g_slist_nth_data(list_in
,0))->num_events
;
1406 for(iter
=g_slist_nth(list_in
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
1407 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1409 if(events_request
->num_events
< end_nb_events
)
1410 end_nb_events
= events_request
->num_events
;
1413 /* 3.2.2 Use min(CHUNK_NUM_EVENTS, min num events in list_in) as
1416 end_nb_events
= MIN(CHUNK_NUM_EVENTS
, end_nb_events
);
1420 /* 3.3 End position */
1422 /* 3.3.1 Find lowest end position in list_in */
1425 end_position
=((EventsRequest
*)g_slist_nth_data(list_in
,0))->end_position
;
1427 for(iter
=g_slist_nth(list_in
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
1428 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1430 if(events_request
->end_position
!= NULL
&& end_position
!= NULL
&&
1431 lttv_traceset_context_pos_pos_compare(events_request
->end_position
,
1433 end_position
= events_request
->end_position
;
1438 /* 3.3.2 Find lowest start position in list_out */
1441 for(iter
=list_out
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
1442 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1444 if(events_request
->end_position
!= NULL
&& end_position
!= NULL
&&
1445 lttv_traceset_context_pos_pos_compare(events_request
->end_position
,
1447 end_position
= events_request
->end_position
;
1452 /* 4. Call process traceset middle */
1453 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
);
1454 count
= lttv_process_traceset_middle(tsc
, end_time
, end_nb_events
, end_position
);
1456 tfc
= lttv_traceset_context_get_current_tfc(tsc
);
1458 g_debug("Context time after middle : %lu, %lu", tfc
->timestamp
.tv_sec
,
1459 tfc
->timestamp
.tv_nsec
);
1461 g_debug("End of trace reached after middle.");
1465 /* 5. After process traceset middle */
1466 tfc
= lttv_traceset_context_get_current_tfc(tsc
);
1468 /* - if current context time > traceset.end time */
1469 if(tfc
== NULL
|| ltt_time_compare(tfc
->timestamp
,
1470 tsc
->time_span
.end_time
) > 0) {
1471 /* - For each req in list_in */
1472 GSList
*iter
= list_in
;
1474 while(iter
!= NULL
) {
1476 gboolean remove
= FALSE
;
1477 gboolean free_data
= FALSE
;
1478 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1480 /* - Remove events hooks for req
1481 * - Call end chunk for req
1484 if(events_request
->trace
== -1)
1485 lttv_process_traceset_end(tsc
,
1486 events_request
->after_chunk_traceset
,
1487 events_request
->after_chunk_trace
,
1488 events_request
->after_chunk_tracefile
,
1489 events_request
->event
,
1490 events_request
->event_by_id_channel
);
1493 guint nb_trace
= lttv_traceset_number(tsc
->ts
);
1494 g_assert(events_request
->trace
< nb_trace
&&
1495 events_request
->trace
> -1);
1496 LttvTraceContext
*tc
= tsc
->traces
[events_request
->trace
];
1498 lttv_trace_context_remove_hooks(tc
,
1499 events_request
->after_chunk_trace
,
1500 events_request
->after_chunk_tracefile
,
1501 events_request
->event
,
1502 events_request
->event_by_id_channel
);
1503 lttv_hooks_call(events_request
->after_chunk_traceset
, tsc
);
1508 /* - Call end request for req */
1509 lttv_hooks_call(events_request
->after_request
, (gpointer
)tsc
);
1511 /* - remove req from list_in */
1512 /* Destroy the request */
1519 GSList
*remove_iter
= iter
;
1521 iter
= g_slist_next(iter
);
1522 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
1523 list_in
= g_slist_remove_link(list_in
, remove_iter
);
1524 } else { // not remove
1525 iter
= g_slist_next(iter
);
1530 /* 5.1 For each req in list_in */
1531 GSList
*iter
= list_in
;
1533 while(iter
!= NULL
) {
1535 gboolean remove
= FALSE
;
1536 gboolean free_data
= FALSE
;
1537 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1539 /* - Remove events hooks for req
1540 * - Call end chunk for req
1542 if(events_request
->trace
== -1)
1543 lttv_process_traceset_end(tsc
,
1544 events_request
->after_chunk_traceset
,
1545 events_request
->after_chunk_trace
,
1546 events_request
->after_chunk_tracefile
,
1547 events_request
->event
,
1548 events_request
->event_by_id_channel
);
1551 guint nb_trace
= lttv_traceset_number(tsc
->ts
);
1552 g_assert(events_request
->trace
< nb_trace
&&
1553 events_request
->trace
> -1);
1554 LttvTraceContext
*tc
= tsc
->traces
[events_request
->trace
];
1556 lttv_trace_context_remove_hooks(tc
,
1557 events_request
->after_chunk_trace
,
1558 events_request
->after_chunk_tracefile
,
1559 events_request
->event
,
1560 events_request
->event_by_id_channel
);
1562 lttv_hooks_call(events_request
->after_chunk_traceset
, tsc
);
1565 /* - req.num -= count */
1566 g_assert(events_request
->num_events
>= count
);
1567 events_request
->num_events
-= count
;
1569 g_assert(tfc
!= NULL
);
1570 /* - if req.num == 0
1572 * current context time >= req.end time
1574 * req.end pos == current pos
1576 * req.stop_flag == TRUE
1578 if( events_request
->num_events
== 0
1580 events_request
->stop_flag
== TRUE
1582 ltt_time_compare(tfc
->timestamp
,
1583 events_request
->end_time
) >= 0
1585 (events_request
->end_position
!= NULL
1587 lttv_traceset_context_ctx_pos_compare(tsc
,
1588 events_request
->end_position
) == 0)
1591 g_assert(events_request
->servicing
== TRUE
);
1592 /* - Call end request for req
1593 * - remove req from list_in */
1594 lttv_hooks_call(events_request
->after_request
, (gpointer
)tsc
);
1595 /* - remove req from list_in */
1596 /* Destroy the request */
1604 GSList
*remove_iter
= iter
;
1606 iter
= g_slist_next(iter
);
1607 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
1608 list_in
= g_slist_remove_link(list_in
, remove_iter
);
1609 } else { // not remove
1610 iter
= g_slist_next(iter
);
1616 /* End of removed servicing loop : leave control to GTK instead. */
1617 // if(gtk_events_pending()) break;
1620 /* B. When interrupted between chunks */
1623 GSList
*iter
= list_in
;
1625 /* 1. for each request in list_in */
1626 while(iter
!= NULL
) {
1628 gboolean remove
= FALSE
;
1629 gboolean free_data
= FALSE
;
1630 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1632 /* 1.1. Use current postition as start position */
1633 if(events_request
->start_position
!= NULL
)
1634 lttv_traceset_context_position_destroy(events_request
->start_position
);
1635 events_request
->start_position
= lttv_traceset_context_position_new(tsc
);
1636 lttv_traceset_context_position_save(tsc
, events_request
->start_position
);
1638 /* 1.2. Remove start time */
1639 events_request
->start_time
= ltt_time_infinite
;
1641 /* 1.3. Move from list_in to list_out */
1644 list_out
= g_slist_append(list_out
, events_request
);
1649 GSList
*remove_iter
= iter
;
1651 iter
= g_slist_next(iter
);
1652 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
1653 list_in
= g_slist_remove_link(list_in
, remove_iter
);
1654 } else { // not remove
1655 iter
= g_slist_next(iter
);
1661 /* C Unlock Traces */
1663 lttv_process_traceset_get_sync_data(tsc
);
1664 //lttv_traceset_context_position_save(tsc, sync_position);
1669 iter_trace
<lttv_traceset_number(tsc
->ts
);
1671 LttvTrace
*trace_v
= lttv_traceset_get(tsc
->ts
, iter_trace
);
1673 lttvwindowtraces_unlock(trace_v
);
1677 //set the cursor back to normal
1678 gdk_window_set_cursor(win
, NULL
);
1681 g_assert(g_slist_length(list_in
) == 0);
1683 if( g_slist_length(list_out
) == 0 ) {
1684 /* Put tab's request pending flag back to normal */
1685 tab
->events_request_pending
= FALSE
;
1686 g_debug("remove the idle fct");
1687 return FALSE
; /* Remove the idle function */
1689 g_debug("leave the idle fct");
1690 return TRUE
; /* Leave the idle function */
1692 /* We do not use simili-round-robin, it may require to read 1 meg buffers
1693 * again and again if many tracesets use the same tracefiles. */
1694 /* Hack for round-robin idle functions */
1695 /* It will put the idle function at the end of the pool */
1696 /*g_idle_add_full((G_PRIORITY_HIGH_IDLE + 21),
1697 (GSourceFunc)execute_events_requests,
1707 static void lttvwindow_add_trace(Tab
*tab
, LttvTrace
*trace_v
)
1709 LttvTraceset
*traceset
= tab
->traceset_info
->traceset
;
1711 guint num_traces
= lttv_traceset_number(traceset
);
1713 //Verify if trace is already present.
1714 for(i
=0; i
<num_traces
; i
++)
1716 LttvTrace
* trace
= lttv_traceset_get(traceset
, i
);
1717 if(trace
== trace_v
)
1721 //Keep a reference to the traces so they are not freed.
1722 for(i
=0; i
<lttv_traceset_number(traceset
); i
++)
1724 LttvTrace
* trace
= lttv_traceset_get(traceset
, i
);
1725 lttv_trace_ref(trace
);
1728 //remove state update hooks
1729 lttv_state_remove_event_hooks(
1730 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1732 lttv_context_fini(LTTV_TRACESET_CONTEXT(
1733 tab
->traceset_info
->traceset_context
));
1734 g_object_unref(tab
->traceset_info
->traceset_context
);
1736 lttv_traceset_add(traceset
, trace_v
);
1737 lttv_trace_ref(trace_v
); /* local ref */
1739 /* Create new context */
1740 tab
->traceset_info
->traceset_context
=
1741 g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
1743 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->
1748 //add state update hooks
1749 lttv_state_add_event_hooks(
1750 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1751 //Remove local reference to the traces.
1752 for(i
=0; i
<lttv_traceset_number(traceset
); i
++)
1754 LttvTrace
* trace
= lttv_traceset_get(traceset
, i
);
1755 lttv_trace_unref(trace
);
1759 //add_trace_into_traceset_selector(GTK_MULTIVPANED(tab->multivpaned), lttv_trace(trace_v));
1762 /* add_trace adds a trace into the current traceset. It first displays a
1763 * directory selection dialogue to let user choose a trace, then recreates
1764 * tracset_context, and redraws all the viewer of the current tab
1767 void add_trace(GtkWidget
* widget
, gpointer user_data
)
1770 LttvTrace
* trace_v
;
1771 LttvTraceset
* traceset
;
1773 char abs_path
[PATH_MAX
];
1775 MainWindow
* mw_data
= get_window_data_struct(widget
);
1776 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
1778 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
1779 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
1780 LttvPluginTab
*ptab
;
1784 ptab
= create_new_tab(widget
, NULL
);
1787 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
1791 //GtkDirSelection * file_selector = (GtkDirSelection *)gtk_dir_selection_new("Select a trace");
1792 GtkFileSelection
* file_selector
= (GtkFileSelection
*)gtk_file_selection_new("Select a trace");
1793 gtk_widget_hide( (file_selector
)->file_list
->parent
) ;
1794 gtk_file_selection_hide_fileop_buttons(file_selector
);
1795 gtk_window_set_transient_for(GTK_WINDOW(file_selector
),
1796 GTK_WINDOW(mw_data
->mwindow
));
1798 if(remember_trace_dir
[0] != '\0')
1799 gtk_file_selection_set_filename(file_selector
, remember_trace_dir
);
1801 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
1803 case GTK_RESPONSE_ACCEPT
:
1804 case GTK_RESPONSE_OK
:
1805 dir
= gtk_file_selection_get_filename (file_selector
);
1806 strncpy(remember_trace_dir
, dir
, PATH_MAX
);
1807 strncat(remember_trace_dir
, "/", PATH_MAX
);
1808 if(!dir
|| strlen(dir
) == 0){
1809 gtk_widget_destroy((GtkWidget
*)file_selector
);
1812 get_absolute_pathname(dir
, abs_path
);
1813 trace_v
= lttvwindowtraces_get_trace_by_name(abs_path
);
1814 if(trace_v
== NULL
) {
1815 trace
= ltt_trace_open(abs_path
);
1817 g_warning("cannot open trace %s", abs_path
);
1819 GtkWidget
*dialogue
=
1820 gtk_message_dialog_new(
1821 GTK_WINDOW(gtk_widget_get_toplevel(widget
)),
1822 GTK_DIALOG_MODAL
|GTK_DIALOG_DESTROY_WITH_PARENT
,
1825 "Cannot open trace : maybe you should enter in the trace "
1826 "directory to select it ?");
1827 gtk_dialog_run(GTK_DIALOG(dialogue
));
1828 gtk_widget_destroy(dialogue
);
1831 trace_v
= lttv_trace_new(trace
);
1832 lttvwindowtraces_add_trace(trace_v
);
1833 lttvwindow_add_trace(tab
, trace_v
);
1836 lttvwindow_add_trace(tab
, trace_v
);
1839 gtk_widget_destroy((GtkWidget
*)file_selector
);
1841 //update current tab
1842 //update_traceset(mw_data);
1844 /* Call the updatetraceset hooks */
1846 traceset
= tab
->traceset_info
->traceset
;
1847 SetTraceset(tab
, traceset
);
1848 // in expose now call_pending_read_hooks(mw_data);
1850 //lttvwindow_report_current_time(mw_data,&(tab->current_time));
1852 case GTK_RESPONSE_REJECT
:
1853 case GTK_RESPONSE_CANCEL
:
1855 gtk_widget_destroy((GtkWidget
*)file_selector
);
1860 /* remove_trace removes a trace from the current traceset if all viewers in
1861 * the current tab are not interested in the trace. It first displays a
1862 * dialogue, which shows all traces in the current traceset, to let user choose
1863 * a trace, then it checks if all viewers unselect the trace, if it is true,
1864 * it will remove the trace, recreate the traceset_contex,
1865 * and redraws all the viewer of the current tab. If there is on trace in the
1866 * current traceset, it will delete all viewers of the current tab
1868 * It destroys the filter tree. FIXME... we should request for an update
1872 void remove_trace(GtkWidget
*widget
, gpointer user_data
)
1875 LttvTrace
* trace_v
;
1876 LttvTraceset
* traceset
;
1877 gint i
, j
, nb_trace
, index
=-1;
1878 char ** name
, *remove_trace_name
;
1879 MainWindow
* mw_data
= get_window_data_struct(widget
);
1880 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
1882 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
1883 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
1889 LttvPluginTab
*ptab
;
1890 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
1894 nb_trace
=lttv_traceset_number(tab
->traceset_info
->traceset
);
1895 name
= g_new(char*,nb_trace
);
1896 for(i
= 0; i
< nb_trace
; i
++){
1897 trace_v
= lttv_traceset_get(tab
->traceset_info
->traceset
, i
);
1898 trace
= lttv_trace(trace_v
);
1899 name
[i
] = g_quark_to_string(ltt_trace_name(trace
));
1902 remove_trace_name
= get_remove_trace(mw_data
, name
, nb_trace
);
1905 if(remove_trace_name
){
1907 /* yuk, cut n paste from old code.. should be better (MD)*/
1908 for(i
= 0; i
<nb_trace
; i
++) {
1909 if(strcmp(remove_trace_name
,name
[i
]) == 0){
1914 traceset
= tab
->traceset_info
->traceset
;
1915 //Keep a reference to the traces so they are not freed.
1916 for(j
=0; j
<lttv_traceset_number(traceset
); j
++)
1918 LttvTrace
* trace
= lttv_traceset_get(traceset
, j
);
1919 lttv_trace_ref(trace
);
1922 //remove state update hooks
1923 lttv_state_remove_event_hooks(
1924 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1925 lttv_context_fini(LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
));
1926 g_object_unref(tab
->traceset_info
->traceset_context
);
1928 trace_v
= lttv_traceset_get(traceset
, index
);
1930 lttv_traceset_remove(traceset
, index
);
1931 lttv_trace_unref(trace_v
); // Remove local reference
1933 if(lttv_trace_get_ref_number(trace_v
) <= 1) {
1934 /* ref 1 : lttvwindowtraces only*/
1935 ltt_trace_close(lttv_trace(trace_v
));
1936 /* lttvwindowtraces_remove_trace takes care of destroying
1937 * the traceset linked with the trace_v and also of destroying
1938 * the trace_v at the same time.
1940 lttvwindowtraces_remove_trace(trace_v
);
1943 tab
->traceset_info
->traceset_context
=
1944 g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
1946 LTTV_TRACESET_CONTEXT(tab
->
1947 traceset_info
->traceset_context
),traceset
);
1948 //add state update hooks
1949 lttv_state_add_event_hooks(
1950 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1952 //Remove local reference to the traces.
1953 for(j
=0; j
<lttv_traceset_number(traceset
); j
++)
1955 LttvTrace
* trace
= lttv_traceset_get(traceset
, j
);
1956 lttv_trace_unref(trace
);
1959 SetTraceset(tab
, (gpointer
)traceset
);
1965 void remove_trace(GtkWidget
* widget
, gpointer user_data
)
1968 LttvTrace
* trace_v
;
1969 LttvTraceset
* traceset
;
1970 gint i
, j
, nb_trace
;
1971 char ** name
, *remove_trace_name
;
1972 MainWindow
* mw_data
= get_window_data_struct(widget
);
1973 LttvTracesetSelector
* s
;
1974 LttvTraceSelector
* t
;
1977 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
1979 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
1980 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
1986 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
1989 nb_trace
=lttv_traceset_number(tab
->traceset_info
->traceset
);
1990 name
= g_new(char*,nb_trace
);
1991 for(i
= 0; i
< nb_trace
; i
++){
1992 trace_v
= lttv_traceset_get(tab
->traceset_info
->traceset
, i
);
1993 trace
= lttv_trace(trace_v
);
1994 name
[i
] = ltt_trace_name(trace
);
1997 remove_trace_name
= get_remove_trace(name
, nb_trace
);
1999 if(remove_trace_name
){
2000 for(i
=0; i
<nb_trace
; i
++){
2001 if(strcmp(remove_trace_name
,name
[i
]) == 0){
2002 //unselect the trace from the current viewer
2004 w
= gtk_multivpaned_get_widget(GTK_MULTIVPANED(tab
->multivpaned
));
2006 s
= g_object_get_data(G_OBJECT(w
), "Traceset_Selector");
2008 t
= lttv_traceset_selector_trace_get(s
,i
);
2009 lttv_trace_selector_set_selected(t
, FALSE
);
2012 //check if other viewers select the trace
2013 w
= gtk_multivpaned_get_first_widget(GTK_MULTIVPANED(tab
->multivpaned
));
2015 s
= g_object_get_data(G_OBJECT(w
), "Traceset_Selector");
2017 t
= lttv_traceset_selector_trace_get(s
,i
);
2018 selected
= lttv_trace_selector_get_selected(t
);
2021 w
= gtk_multivpaned_get_next_widget(GTK_MULTIVPANED(tab
->multivpaned
));
2023 }else selected
= FALSE
;
2025 //if no viewer selects the trace, remove it
2027 remove_trace_from_traceset_selector(GTK_MULTIVPANED(tab
->multivpaned
), i
);
2029 traceset
= tab
->traceset_info
->traceset
;
2030 //Keep a reference to the traces so they are not freed.
2031 for(j
=0; j
<lttv_traceset_number(traceset
); j
++)
2033 LttvTrace
* trace
= lttv_traceset_get(traceset
, j
);
2034 lttv_trace_ref(trace
);
2037 //remove state update hooks
2038 lttv_state_remove_event_hooks(
2039 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
2040 lttv_context_fini(LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
));
2041 g_object_unref(tab
->traceset_info
->traceset_context
);
2044 trace_v
= lttv_traceset_get(traceset
, i
);
2046 if(lttv_trace_get_ref_number(trace_v
) <= 2) {
2047 /* ref 2 : traceset, local */
2048 lttvwindowtraces_remove_trace(trace_v
);
2049 ltt_trace_close(lttv_trace(trace_v
));
2052 lttv_traceset_remove(traceset
, i
);
2053 lttv_trace_unref(trace_v
); // Remove local reference
2055 if(!lttv_trace_get_ref_number(trace_v
))
2056 lttv_trace_destroy(trace_v
);
2058 tab
->traceset_info
->traceset_context
=
2059 g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
2061 LTTV_TRACESET_CONTEXT(tab
->
2062 traceset_info
->traceset_context
),traceset
);
2063 //add state update hooks
2064 lttv_state_add_event_hooks(
2065 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
2067 //Remove local reference to the traces.
2068 for(j
=0; j
<lttv_traceset_number(traceset
); j
++)
2070 LttvTrace
* trace
= lttv_traceset_get(traceset
, j
);
2071 lttv_trace_unref(trace
);
2075 //update current tab
2076 //update_traceset(mw_data);
2079 SetTraceset(tab
, (gpointer
)traceset
);
2080 // in expose now call_pending_read_hooks(mw_data);
2082 //lttvwindow_report_current_time(mw_data,&(tab->current_time));
2085 // while(tab->multi_vpaned->num_children){
2086 // gtk_multi_vpaned_widget_delete(tab->multi_vpaned);
2100 /* Redraw all the viewers in the current tab */
2101 void redraw(GtkWidget
*widget
, gpointer user_data
)
2103 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
2104 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2105 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2112 LttvPluginTab
*ptab
;
2113 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
2118 LttvAttributeValue value
;
2120 retval
= lttv_iattribute_find_by_path(tab
->attributes
, "hooks/redraw", LTTV_POINTER
, &value
);
2123 tmp
= (LttvHooks
*)*(value
.v_pointer
);
2125 lttv_hooks_call(tmp
,NULL
);
2129 void continue_processing(GtkWidget
*widget
, gpointer user_data
)
2131 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
2132 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2133 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2140 LttvPluginTab
*ptab
;
2141 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
2146 LttvAttributeValue value
;
2148 retval
= lttv_iattribute_find_by_path(tab
->attributes
, "hooks/continue",
2149 LTTV_POINTER
, &value
);
2152 tmp
= (LttvHooks
*)*(value
.v_pointer
);
2154 lttv_hooks_call(tmp
,NULL
);
2157 /* Stop the processing for the calling main window's current tab.
2158 * It removes every processing requests that are in its list. It does not call
2159 * the end request hooks, because the request is not finished.
2162 void stop_processing(GtkWidget
*widget
, gpointer user_data
)
2164 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
2165 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2166 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2171 LttvPluginTab
*ptab
;
2172 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
2175 GSList
*iter
= tab
->events_requests
;
2177 while(iter
!= NULL
) {
2178 GSList
*remove_iter
= iter
;
2179 iter
= g_slist_next(iter
);
2181 g_free(remove_iter
->data
);
2182 tab
->events_requests
=
2183 g_slist_remove_link(tab
->events_requests
, remove_iter
);
2185 tab
->events_request_pending
= FALSE
;
2186 tab
->stop_foreground
= TRUE
;
2187 g_idle_remove_by_data(tab
);
2188 g_assert(g_slist_length(tab
->events_requests
) == 0);
2192 /* save will save the traceset to a file
2193 * Not implemented yet FIXME
2196 void save(GtkWidget
* widget
, gpointer user_data
)
2201 void save_as(GtkWidget
* widget
, gpointer user_data
)
2203 g_info("Save as\n");
2207 /* zoom will change the time_window of all the viewers of the
2208 * current tab, and redisplay them. The main functionality is to
2209 * determine the new time_window of the current tab
2212 void zoom(GtkWidget
* widget
, double size
)
2214 TimeInterval time_span
;
2215 TimeWindow new_time_window
;
2216 LttTime current_time
, time_delta
;
2217 MainWindow
* mw_data
= get_window_data_struct(widget
);
2218 LttvTracesetContext
*tsc
;
2219 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
2221 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2222 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2228 LttvPluginTab
*ptab
;
2229 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
2233 if(size
== 1) return;
2235 tsc
= LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
2236 time_span
= tsc
->time_span
;
2237 new_time_window
= tab
->time_window
;
2238 current_time
= tab
->current_time
;
2240 time_delta
= ltt_time_sub(time_span
.end_time
,time_span
.start_time
);
2242 new_time_window
.start_time
= time_span
.start_time
;
2243 new_time_window
.time_width
= time_delta
;
2244 new_time_window
.time_width_double
= ltt_time_to_double(time_delta
);
2245 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
2246 new_time_window
.time_width
) ;
2248 new_time_window
.time_width
= ltt_time_div(new_time_window
.time_width
, size
);
2249 new_time_window
.time_width_double
=
2250 ltt_time_to_double(new_time_window
.time_width
);
2251 if(ltt_time_compare(new_time_window
.time_width
,time_delta
) > 0)
2252 { /* Case where zoom out is bigger than trace length */
2253 new_time_window
.start_time
= time_span
.start_time
;
2254 new_time_window
.time_width
= time_delta
;
2255 new_time_window
.time_width_double
= ltt_time_to_double(time_delta
);
2256 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
2257 new_time_window
.time_width
) ;
2261 /* Center the image on the current time */
2262 new_time_window
.start_time
=
2263 ltt_time_sub(current_time
,
2264 ltt_time_from_double(new_time_window
.time_width_double
/2.0));
2265 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
2266 new_time_window
.time_width
) ;
2267 /* If on borders, don't fall off */
2268 if(ltt_time_compare(new_time_window
.start_time
, time_span
.start_time
) <0
2269 || ltt_time_compare(new_time_window
.start_time
, time_span
.end_time
) >0)
2271 new_time_window
.start_time
= time_span
.start_time
;
2272 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
2273 new_time_window
.time_width
) ;
2277 if(ltt_time_compare(new_time_window
.end_time
,
2278 time_span
.end_time
) > 0
2279 || ltt_time_compare(new_time_window
.end_time
,
2280 time_span
.start_time
) < 0)
2282 new_time_window
.start_time
=
2283 ltt_time_sub(time_span
.end_time
, new_time_window
.time_width
);
2285 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
2286 new_time_window
.time_width
) ;
2293 if(ltt_time_compare(new_time_window
.time_width
, ltt_time_zero
) == 0) {
2294 g_warning("Zoom more than 1 ns impossible");
2296 time_change_manager(tab
, new_time_window
);
2300 void zoom_in(GtkWidget
* widget
, gpointer user_data
)
2305 void zoom_out(GtkWidget
* widget
, gpointer user_data
)
2310 void zoom_extended(GtkWidget
* widget
, gpointer user_data
)
2315 void go_to_time(GtkWidget
* widget
, gpointer user_data
)
2317 g_info("Go to time\n");
2320 void show_time_frame(GtkWidget
* widget
, gpointer user_data
)
2322 g_info("Show time frame\n");
2326 /* callback function */
2329 on_empty_traceset_activate (GtkMenuItem
*menuitem
,
2332 create_new_window((GtkWidget
*)menuitem
, user_data
, FALSE
);
2337 on_clone_traceset_activate (GtkMenuItem
*menuitem
,
2340 create_new_window((GtkWidget
*)menuitem
, user_data
, TRUE
);
2344 /* create_new_tab calls create_tab to construct a new tab in the main window
2347 LttvPluginTab
*create_new_tab(GtkWidget
* widget
, gpointer user_data
)
2349 gchar label
[PATH_MAX
];
2350 MainWindow
* mw_data
= get_window_data_struct(widget
);
2352 GtkNotebook
* notebook
= (GtkNotebook
*)lookup_widget(widget
, "MNotebook");
2353 if(notebook
== NULL
){
2354 g_info("Notebook does not exist\n");
2357 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2358 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2364 LttvPluginTab
*ptab
;
2365 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
2366 copy_tab
= ptab
->tab
;
2369 strcpy(label
,"Page");
2370 if(get_label(mw_data
, label
,"Get the name of the tab","Please input tab's name")) {
2371 LttvPluginTab
*ptab
;
2373 ptab
= g_object_new(LTTV_TYPE_PLUGIN_TAB
, NULL
);
2374 init_tab (ptab
->tab
, mw_data
, copy_tab
, notebook
, label
);
2375 ptab
->parent
.top_widget
= ptab
->tab
->top_widget
;
2376 g_object_set_data_full(
2377 G_OBJECT(ptab
->tab
->vbox
),
2380 (GDestroyNotify
)tab_destructor
);
2387 on_tab_activate (GtkMenuItem
*menuitem
,
2390 create_new_tab((GtkWidget
*)menuitem
, user_data
);
2395 on_open_activate (GtkMenuItem
*menuitem
,
2398 open_traceset((GtkWidget
*)menuitem
, user_data
);
2403 on_close_activate (GtkMenuItem
*menuitem
,
2406 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2407 main_window_destructor(mw_data
);
2411 /* remove the current tab from the main window
2415 on_close_tab_activate (GtkWidget
*widget
,
2419 GtkWidget
* notebook
;
2421 MainWindow
* mw_data
= get_window_data_struct(widget
);
2422 notebook
= lookup_widget(widget
, "MNotebook");
2423 if(notebook
== NULL
){
2424 g_info("Notebook does not exist\n");
2428 page_num
= gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
));
2430 gtk_notebook_remove_page(GTK_NOTEBOOK(notebook
), page_num
);
2435 on_close_tab_X_clicked (GtkWidget
*widget
,
2439 GtkWidget
*notebook
= lookup_widget(widget
, "MNotebook");
2440 if(notebook
== NULL
){
2441 g_info("Notebook does not exist\n");
2445 if((page_num
= gtk_notebook_page_num(GTK_NOTEBOOK(notebook
), widget
)) != -1)
2446 gtk_notebook_remove_page(GTK_NOTEBOOK(notebook
), page_num
);
2452 on_add_trace_activate (GtkMenuItem
*menuitem
,
2455 add_trace((GtkWidget
*)menuitem
, user_data
);
2460 on_remove_trace_activate (GtkMenuItem
*menuitem
,
2463 remove_trace((GtkWidget
*)menuitem
, user_data
);
2468 on_save_activate (GtkMenuItem
*menuitem
,
2471 save((GtkWidget
*)menuitem
, user_data
);
2476 on_save_as_activate (GtkMenuItem
*menuitem
,
2479 save_as((GtkWidget
*)menuitem
, user_data
);
2484 on_quit_activate (GtkMenuItem
*menuitem
,
2487 while (g_slist_length(g_main_window_list
) != 0) {
2488 on_MWindow_destroy(((MainWindow
*)g_main_window_list
->data
)->mwindow
,
2495 on_cut_activate (GtkMenuItem
*menuitem
,
2503 on_copy_activate (GtkMenuItem
*menuitem
,
2511 on_paste_activate (GtkMenuItem
*menuitem
,
2519 on_delete_activate (GtkMenuItem
*menuitem
,
2527 on_zoom_in_activate (GtkMenuItem
*menuitem
,
2530 zoom_in((GtkWidget
*)menuitem
, user_data
);
2535 on_zoom_out_activate (GtkMenuItem
*menuitem
,
2538 zoom_out((GtkWidget
*)menuitem
, user_data
);
2543 on_zoom_extended_activate (GtkMenuItem
*menuitem
,
2546 zoom_extended((GtkWidget
*)menuitem
, user_data
);
2551 on_go_to_time_activate (GtkMenuItem
*menuitem
,
2554 go_to_time((GtkWidget
*)menuitem
, user_data
);
2559 on_show_time_frame_activate (GtkMenuItem
*menuitem
,
2562 show_time_frame((GtkWidget
*)menuitem
, user_data
);
2567 on_move_viewer_up_activate (GtkMenuItem
*menuitem
,
2570 move_up_viewer((GtkWidget
*)menuitem
, user_data
);
2575 on_move_viewer_down_activate (GtkMenuItem
*menuitem
,
2578 move_down_viewer((GtkWidget
*)menuitem
, user_data
);
2583 on_remove_viewer_activate (GtkMenuItem
*menuitem
,
2586 delete_viewer((GtkWidget
*)menuitem
, user_data
);
2590 on_trace_facility_activate (GtkMenuItem
*menuitem
,
2593 g_info("Trace facility selector: %s\n", "");
2597 /* Dispaly a file selection dialogue to let user select a library, then call
2598 * lttv_library_load().
2602 on_load_library_activate (GtkMenuItem
*menuitem
,
2605 GError
*error
= NULL
;
2606 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2608 gchar load_module_path_alter
[PATH_MAX
];
2612 gchar
*load_module_path
;
2613 name
= g_ptr_array_new();
2614 nb
= lttv_library_path_number();
2615 /* ask for the library path */
2619 path
= lttv_library_path_get(i
);
2620 g_ptr_array_add(name
, path
);
2623 load_module_path
= get_selection(mw_data
,
2624 (char **)(name
->pdata
), name
->len
,
2625 "Select a library path", "Library paths");
2626 if(load_module_path
!= NULL
)
2627 strncpy(load_module_path_alter
, load_module_path
, PATH_MAX
-1); // -1 for /
2629 g_ptr_array_free(name
, TRUE
);
2631 if(load_module_path
== NULL
) return;
2635 /* Make sure the module path ends with a / */
2636 gchar
*ptr
= load_module_path_alter
;
2638 ptr
= strchr(ptr
, '\0');
2640 if(*(ptr
-1) != '/') {
2647 /* Ask for the library to load : list files in the previously selected
2649 gchar str
[PATH_MAX
];
2652 GtkFileSelection
* file_selector
=
2653 (GtkFileSelection
*)gtk_file_selection_new("Select a module");
2654 gtk_file_selection_set_filename(file_selector
, load_module_path_alter
);
2655 gtk_file_selection_hide_fileop_buttons(file_selector
);
2657 gtk_window_set_transient_for(GTK_WINDOW(file_selector
),
2658 GTK_WINDOW(mw_data
->mwindow
));
2661 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
2663 case GTK_RESPONSE_ACCEPT
:
2664 case GTK_RESPONSE_OK
:
2665 dir
= gtk_file_selection_get_selections (file_selector
);
2666 strncpy(str
,dir
[0],PATH_MAX
);
2667 strncpy(remember_plugins_dir
,dir
[0],PATH_MAX
);
2668 /* only keep file name */
2670 str1
= strrchr(str
,'/');
2673 str1
= strrchr(str
,'\\');
2678 if(*str1
== 'l' && *(str1
+1)== 'i' && *(str1
+2)=='b')
2680 remove info after
. */
2684 str2
= strrchr(str2
, '.');
2685 if(str2
!= NULL
) *str2
= '\0';
2687 lttv_module_require(str1
, &error
);
2689 lttv_library_load(str1
, &error
);
2690 if(error
!= NULL
) g_warning("%s", error
->message
);
2691 else g_info("Load library: %s\n", str
);
2693 case GTK_RESPONSE_REJECT
:
2694 case GTK_RESPONSE_CANCEL
:
2696 gtk_widget_destroy((GtkWidget
*)file_selector
);
2707 /* Display all loaded modules, let user to select a module to unload
2708 * by calling lttv_module_unload
2712 on_unload_library_activate (GtkMenuItem
*menuitem
,
2715 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2717 LttvLibrary
*library
= NULL
;
2722 name
= g_ptr_array_new();
2723 nb
= lttv_library_number();
2724 LttvLibraryInfo
*lib_info
= g_new(LttvLibraryInfo
,nb
);
2725 /* ask for the library name */
2728 LttvLibrary
*iter_lib
= lttv_library_get(i
);
2729 lttv_library_info(iter_lib
, &lib_info
[i
]);
2731 gchar
*path
= lib_info
[i
].name
;
2732 g_ptr_array_add(name
, path
);
2734 lib_name
= get_selection(mw_data
, (char **)(name
->pdata
), name
->len
,
2735 "Select a library", "Libraries");
2736 if(lib_name
!= NULL
) {
2738 if(strcmp(lib_name
, lib_info
[i
].name
) == 0) {
2739 library
= lttv_library_get(i
);
2744 g_ptr_array_free(name
, TRUE
);
2747 if(lib_name
== NULL
) return;
2749 if(library
!= NULL
) lttv_library_unload(library
);
2753 /* Dispaly a file selection dialogue to let user select a module, then call
2754 * lttv_module_require().
2758 on_load_module_activate (GtkMenuItem
*menuitem
,
2761 GError
*error
= NULL
;
2762 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2764 LttvLibrary
*library
= NULL
;
2769 name
= g_ptr_array_new();
2770 nb
= lttv_library_number();
2771 LttvLibraryInfo
*lib_info
= g_new(LttvLibraryInfo
,nb
);
2772 /* ask for the library name */
2775 LttvLibrary
*iter_lib
= lttv_library_get(i
);
2776 lttv_library_info(iter_lib
, &lib_info
[i
]);
2778 gchar
*path
= lib_info
[i
].name
;
2779 g_ptr_array_add(name
, path
);
2781 lib_name
= get_selection(mw_data
,(char **)(name
->pdata
), name
->len
,
2782 "Select a library", "Libraries");
2783 if(lib_name
!= NULL
) {
2785 if(strcmp(lib_name
, lib_info
[i
].name
) == 0) {
2786 library
= lttv_library_get(i
);
2791 g_ptr_array_free(name
, TRUE
);
2794 if(lib_name
== NULL
) return;
2797 //LttvModule *module;
2798 gchar module_name_out
[PATH_MAX
];
2800 /* Ask for the module to load : list modules in the selected lib */
2804 nb
= lttv_library_module_number(library
);
2805 LttvModuleInfo
*module_info
= g_new(LttvModuleInfo
,nb
);
2806 name
= g_ptr_array_new();
2807 /* ask for the module name */
2810 LttvModule
*iter_module
= lttv_library_module_get(library
, i
);
2811 lttv_module_info(iter_module
, &module_info
[i
]);
2813 gchar
*path
= module_info
[i
].name
;
2814 g_ptr_array_add(name
, path
);
2816 module_name
= get_selection(mw_data
, (char **)(name
->pdata
), name
->len
,
2817 "Select a module", "Modules");
2818 if(module_name
!= NULL
) {
2820 if(strcmp(module_name
, module_info
[i
].name
) == 0) {
2821 strncpy(module_name_out
, module_name
, PATH_MAX
);
2822 //module = lttv_library_module_get(i);
2828 g_ptr_array_free(name
, TRUE
);
2829 g_free(module_info
);
2831 if(module_name
== NULL
) return;
2834 lttv_module_require(module_name_out
, &error
);
2835 if(error
!= NULL
) g_warning("%s", error
->message
);
2836 else g_info("Load module: %s", module_name_out
);
2843 gchar str
[PATH_MAX
];
2846 GtkFileSelection
* file_selector
=
2847 (GtkFileSelection
*)gtk_file_selection_new("Select a module");
2848 gtk_file_selection_set_filename(file_selector
, load_module_path_alter
);
2849 gtk_file_selection_hide_fileop_buttons(file_selector
);
2852 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
2854 case GTK_RESPONSE_ACCEPT
:
2855 case GTK_RESPONSE_OK
:
2856 dir
= gtk_file_selection_get_selections (file_selector
);
2857 strncpy(str
,dir
[0],PATH_MAX
);
2858 strncpy(remember_plugins_dir
,dir
[0],PATH_MAX
);
2860 /* only keep file name */
2862 str1
= strrchr(str
,'/');
2865 str1
= strrchr(str
,'\\');
2870 if(*str1
== 'l' && *(str1
+1)== 'i' && *(str1
+2)=='b')
2872 remove info after
. */
2876 str2
= strrchr(str2
, '.');
2877 if(str2
!= NULL
) *str2
= '\0';
2879 lttv_module_require(str1
, &error
);
2881 lttv_library_load(str1
, &error
);
2882 if(error
!= NULL
) g_warning(error
->message
);
2883 else g_info("Load library: %s\n", str
);
2885 case GTK_RESPONSE_REJECT
:
2886 case GTK_RESPONSE_CANCEL
:
2888 gtk_widget_destroy((GtkWidget
*)file_selector
);
2900 /* Display all loaded modules, let user to select a module to unload
2901 * by calling lttv_module_unload
2905 on_unload_module_activate (GtkMenuItem
*menuitem
,
2908 GError
*error
= NULL
;
2909 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2911 LttvLibrary
*library
= NULL
;
2916 name
= g_ptr_array_new();
2917 nb
= lttv_library_number();
2918 LttvLibraryInfo
*lib_info
= g_new(LttvLibraryInfo
,nb
);
2919 /* ask for the library name */
2922 LttvLibrary
*iter_lib
= lttv_library_get(i
);
2923 lttv_library_info(iter_lib
, &lib_info
[i
]);
2925 gchar
*path
= lib_info
[i
].name
;
2926 g_ptr_array_add(name
, path
);
2928 lib_name
= get_selection(mw_data
, (char **)(name
->pdata
), name
->len
,
2929 "Select a library", "Libraries");
2930 if(lib_name
!= NULL
) {
2932 if(strcmp(lib_name
, lib_info
[i
].name
) == 0) {
2933 library
= lttv_library_get(i
);
2938 g_ptr_array_free(name
, TRUE
);
2941 if(lib_name
== NULL
) return;
2944 LttvModule
*module
= NULL
;
2946 /* Ask for the module to load : list modules in the selected lib */
2950 nb
= lttv_library_module_number(library
);
2951 LttvModuleInfo
*module_info
= g_new(LttvModuleInfo
,nb
);
2952 name
= g_ptr_array_new();
2953 /* ask for the module name */
2956 LttvModule
*iter_module
= lttv_library_module_get(library
, i
);
2957 lttv_module_info(iter_module
, &module_info
[i
]);
2959 gchar
*path
= module_info
[i
].name
;
2960 if(module_info
[i
].use_count
> 0) g_ptr_array_add(name
, path
);
2962 module_name
= get_selection(mw_data
, (char **)(name
->pdata
), name
->len
,
2963 "Select a module", "Modules");
2964 if(module_name
!= NULL
) {
2966 if(strcmp(module_name
, module_info
[i
].name
) == 0) {
2967 module
= lttv_library_module_get(library
, i
);
2973 g_ptr_array_free(name
, TRUE
);
2974 g_free(module_info
);
2976 if(module_name
== NULL
) return;
2979 LttvModuleInfo module_info
;
2980 lttv_module_info(module
, &module_info
);
2981 g_info("Release module: %s\n", module_info
.name
);
2983 lttv_module_release(module
);
2987 /* Display a directory dialogue to let user select a path for library searching
2991 on_add_library_search_path_activate (GtkMenuItem
*menuitem
,
2994 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2995 //GtkDirSelection * file_selector = (GtkDirSelection *)gtk_dir_selection_new("Select library path");
2996 GtkFileSelection
* file_selector
= (GtkFileSelection
*)gtk_file_selection_new("Select a trace");
2997 gtk_widget_hide( (file_selector
)->file_list
->parent
) ;
2999 gtk_window_set_transient_for(GTK_WINDOW(file_selector
),
3000 GTK_WINDOW(mw_data
->mwindow
));
3005 if(remember_plugins_dir
[0] != '\0')
3006 gtk_file_selection_set_filename(file_selector
, remember_plugins_dir
);
3008 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
3010 case GTK_RESPONSE_ACCEPT
:
3011 case GTK_RESPONSE_OK
:
3012 dir
= gtk_file_selection_get_filename (file_selector
);
3013 strncpy(remember_plugins_dir
,dir
,PATH_MAX
);
3014 strncat(remember_plugins_dir
,"/",PATH_MAX
);
3015 lttv_library_path_add(dir
);
3016 case GTK_RESPONSE_REJECT
:
3017 case GTK_RESPONSE_CANCEL
:
3019 gtk_widget_destroy((GtkWidget
*)file_selector
);
3025 /* Display a directory dialogue to let user select a path for library searching
3029 on_remove_library_search_path_activate (GtkMenuItem
*menuitem
,
3032 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
3034 const char *lib_path
;
3039 name
= g_ptr_array_new();
3040 nb
= lttv_library_path_number();
3041 /* ask for the library name */
3044 gchar
*path
= lttv_library_path_get(i
);
3045 g_ptr_array_add(name
, path
);
3047 lib_path
= get_selection(mw_data
, (char **)(name
->pdata
), name
->len
,
3048 "Select a library path", "Library paths");
3050 g_ptr_array_free(name
, TRUE
);
3052 if(lib_path
== NULL
) return;
3055 lttv_library_path_remove(lib_path
);
3059 on_color_activate (GtkMenuItem
*menuitem
,
3067 on_save_configuration_activate (GtkMenuItem
*menuitem
,
3070 g_info("Save configuration\n");
3075 on_content_activate (GtkMenuItem
*menuitem
,
3078 g_info("Content\n");
3083 on_about_close_activate (GtkButton
*button
,
3086 GtkWidget
*about_widget
= GTK_WIDGET(user_data
);
3088 gtk_widget_destroy(about_widget
);
3092 on_about_activate (GtkMenuItem
*menuitem
,
3095 MainWindow
*main_window
= get_window_data_struct(GTK_WIDGET(menuitem
));
3096 GtkWidget
*window_widget
= main_window
->mwindow
;
3097 GtkWidget
*about_widget
= gtk_window_new(GTK_WINDOW_TOPLEVEL
);
3098 GtkWindow
*about_window
= GTK_WINDOW(about_widget
);
3099 gint window_width
, window_height
;
3101 gtk_window_set_title(about_window
, "About Linux Trace Toolkit");
3103 gtk_window_set_resizable(about_window
, FALSE
);
3104 gtk_window_set_transient_for(about_window
, GTK_WINDOW(window_widget
));
3105 gtk_window_set_destroy_with_parent(about_window
, TRUE
);
3106 gtk_window_set_modal(about_window
, FALSE
);
3108 /* Put the about window at the center of the screen */
3109 gtk_window_get_size(about_window
, &window_width
, &window_height
);
3110 gtk_window_move (about_window
,
3111 (gdk_screen_width() - window_width
)/2,
3112 (gdk_screen_height() - window_height
)/2);
3114 GtkWidget
*vbox
= gtk_vbox_new(FALSE
, 1);
3116 gtk_container_add(GTK_CONTAINER(about_widget
), vbox
);
3120 GtkWidget
*label1
= gtk_label_new("");
3121 gtk_misc_set_padding(GTK_MISC(label1
), 10, 20);
3122 gtk_label_set_markup(GTK_LABEL(label1
), "\
3123 <big>Linux Trace Toolkit " VERSION
"</big>");
3124 gtk_label_set_justify(GTK_LABEL(label1
), GTK_JUSTIFY_CENTER
);
3126 GtkWidget
*label2
= gtk_label_new("");
3127 gtk_misc_set_padding(GTK_MISC(label2
), 10, 20);
3128 gtk_label_set_markup(GTK_LABEL(label2
), "\
3131 Michel Dagenais (New trace format, lttv main)\n\
3132 Mathieu Desnoyers (Kernel Tracer, Directory structure, build with automake/conf,\n\
3133 lttv gui, control flow view, gui cooperative trace reading\n\
3134 scheduler with interruptible foreground and background\n\
3135 computation, detailed event list (rewrite), trace reading\n\
3136 library (rewrite))\n\
3137 Benoit Des Ligneris, Eric Clement (Cluster adaptation, work in progress)\n\
3138 Xang-Xiu Yang (new trace reading library and converter, lttv gui, \n\
3139 detailed event list and statistics view)\n\
3140 Tom Zanussi (RelayFS)\n\
3142 Inspired from the original Linux Trace Toolkit Visualizer made by\n\
3145 GtkWidget
*label3
= gtk_label_new("");
3146 gtk_label_set_markup(GTK_LABEL(label3
), "\
3147 Linux Trace Toolkit Viewer, Copyright (C) 2004, 2005, 2006\n\
3149 Mathieu Desnoyers\n\
3151 Linux Trace Toolkit comes with ABSOLUTELY NO WARRANTY.\n\
3152 This is free software, and you are welcome to redistribute it\n\
3153 under certain conditions. See COPYING for details.");
3154 gtk_misc_set_padding(GTK_MISC(label3
), 10, 20);
3156 gtk_box_pack_start_defaults(GTK_BOX(vbox
), label1
);
3157 gtk_box_pack_start_defaults(GTK_BOX(vbox
), label2
);
3158 gtk_box_pack_start_defaults(GTK_BOX(vbox
), label3
);
3160 GtkWidget
*hbox
= gtk_hbox_new(TRUE
, 0);
3161 gtk_box_pack_end(GTK_BOX(vbox
), hbox
, FALSE
, FALSE
, 0);
3162 GtkWidget
*close_button
= gtk_button_new_with_mnemonic("_Close");
3163 gtk_box_pack_end(GTK_BOX(hbox
), close_button
, FALSE
, FALSE
, 0);
3164 gtk_container_set_border_width(GTK_CONTAINER(close_button
), 20);
3166 g_signal_connect(G_OBJECT(close_button
), "clicked",
3167 G_CALLBACK(on_about_close_activate
),
3168 (gpointer
)about_widget
);
3170 gtk_widget_show_all(about_widget
);
3175 on_button_new_clicked (GtkButton
*button
,
3178 create_new_window((GtkWidget
*)button
, user_data
, TRUE
);
3182 on_button_new_tab_clicked (GtkButton
*button
,
3185 create_new_tab((GtkWidget
*)button
, user_data
);
3189 on_button_open_clicked (GtkButton
*button
,
3192 open_traceset((GtkWidget
*)button
, user_data
);
3197 on_button_add_trace_clicked (GtkButton
*button
,
3200 add_trace((GtkWidget
*)button
, user_data
);
3205 on_button_remove_trace_clicked (GtkButton
*button
,
3208 remove_trace((GtkWidget
*)button
, user_data
);
3212 on_button_redraw_clicked (GtkButton
*button
,
3215 redraw((GtkWidget
*)button
, user_data
);
3219 on_button_continue_processing_clicked (GtkButton
*button
,
3222 continue_processing((GtkWidget
*)button
, user_data
);
3226 on_button_stop_processing_clicked (GtkButton
*button
,
3229 stop_processing((GtkWidget
*)button
, user_data
);
3235 on_button_save_clicked (GtkButton
*button
,
3238 save((GtkWidget
*)button
, user_data
);
3243 on_button_save_as_clicked (GtkButton
*button
,
3246 save_as((GtkWidget
*)button
, user_data
);
3251 on_button_zoom_in_clicked (GtkButton
*button
,
3254 zoom_in((GtkWidget
*)button
, user_data
);
3259 on_button_zoom_out_clicked (GtkButton
*button
,
3262 zoom_out((GtkWidget
*)button
, user_data
);
3267 on_button_zoom_extended_clicked (GtkButton
*button
,
3270 zoom_extended((GtkWidget
*)button
, user_data
);
3275 on_button_go_to_time_clicked (GtkButton
*button
,
3278 go_to_time((GtkWidget
*)button
, user_data
);
3283 on_button_show_time_frame_clicked (GtkButton
*button
,
3286 show_time_frame((GtkWidget
*)button
, user_data
);
3291 on_button_move_up_clicked (GtkButton
*button
,
3294 move_up_viewer((GtkWidget
*)button
, user_data
);
3299 on_button_move_down_clicked (GtkButton
*button
,
3302 move_down_viewer((GtkWidget
*)button
, user_data
);
3307 on_button_delete_viewer_clicked (GtkButton
*button
,
3310 delete_viewer((GtkWidget
*)button
, user_data
);
3314 on_MWindow_destroy (GtkWidget
*widget
,
3317 MainWindow
*main_window
= get_window_data_struct(widget
);
3318 LttvIAttribute
*attributes
= main_window
->attributes
;
3319 LttvAttributeValue value
;
3322 //This is unnecessary, since widgets will be destroyed
3323 //by the main window widget anyway.
3324 //remove_all_menu_toolbar_constructors(main_window, NULL);
3326 retval
= lttv_iattribute_find_by_path(attributes
, "viewers/menu",
3327 LTTV_POINTER
, &value
);
3329 lttv_menus_destroy((LttvMenus
*)*(value
.v_pointer
));
3331 retval
= lttv_iattribute_find_by_path(attributes
, "viewers/toolbar",
3332 LTTV_POINTER
, &value
);
3334 lttv_toolbars_destroy((LttvToolbars
*)*(value
.v_pointer
));
3336 g_object_unref(main_window
->attributes
);
3337 g_main_window_list
= g_slist_remove(g_main_window_list
, main_window
);
3339 g_info("There are now : %d windows\n",g_slist_length(g_main_window_list
));
3340 if(g_slist_length(g_main_window_list
) == 0)
3345 on_MWindow_configure (GtkWidget
*widget
,
3346 GdkEventConfigure
*event
,
3349 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)widget
);
3351 // MD : removed time width modification upon resizing of the main window.
3352 // The viewers will redraw themselves completely, without time interval
3355 if(mw_data->window_width){
3356 time_span = LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context)->Time_Span ;
3357 time_win = tab->time_window;
3358 ratio = width / mw_data->window_width;
3359 tab->time_window.time_width = ltt_time_mul(time_win.time_width,ratio);
3360 time = ltt_time_sub(time_span->endTime, time_win.start_time);
3361 if(ltt_time_compare(time, tab->time_window.time_width) < 0){
3362 tab->time_window.time_width = time;
3368 mw_data->window_width = (int)width;
3377 on_MNotebook_switch_page (GtkNotebook
*notebook
,
3378 GtkNotebookPage
*page
,
3386 void time_change_manager (Tab
*tab
,
3387 TimeWindow new_time_window
)
3389 /* Only one source of time change */
3390 if(tab
->time_manager_lock
== TRUE
) return;
3392 tab
->time_manager_lock
= TRUE
;
3394 LttvTracesetContext
*tsc
= LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3395 TimeInterval time_span
= tsc
->time_span
;
3396 LttTime start_time
= new_time_window
.start_time
;
3397 LttTime end_time
= new_time_window
.end_time
;
3398 LttTime time_width
= new_time_window
.time_width
;
3400 g_assert(ltt_time_compare(start_time
, end_time
) < 0);
3403 GtkAdjustment
*adjustment
= gtk_range_get_adjustment(GTK_RANGE(tab
->scrollbar
));
3404 LttTime upper
= ltt_time_sub(time_span
.end_time
, time_span
.start_time
);
3406 gtk_range_set_increments(GTK_RANGE(tab
->scrollbar
),
3407 ltt_time_to_double(new_time_window
.time_width
)
3408 / SCROLL_STEP_PER_PAGE
3409 * NANOSECONDS_PER_SECOND
, /* step increment */
3410 ltt_time_to_double(new_time_window
.time_width
)
3411 * NANOSECONDS_PER_SECOND
); /* page increment */
3412 gtk_range_set_range(GTK_RANGE(tab
->scrollbar
),
3414 ltt_time_to_double(upper
)
3415 * NANOSECONDS_PER_SECOND
); /* upper */
3417 g_object_set(G_OBJECT(adjustment
),
3421 ltt_time_to_double(upper
), /* upper */
3423 new_time_window
.time_width_double
3424 / SCROLL_STEP_PER_PAGE
, /* step increment */
3426 new_time_window
.time_width_double
,
3427 /* page increment */
3429 new_time_window
.time_width_double
, /* page size */
3431 gtk_adjustment_changed(adjustment
);
3433 // g_object_set(G_OBJECT(adjustment),
3435 // ltt_time_to_double(
3436 // ltt_time_sub(start_time, time_span.start_time))
3439 //gtk_adjustment_value_changed(adjustment);
3440 gtk_range_set_value(GTK_RANGE(tab
->scrollbar
),
3442 ltt_time_sub(start_time
, time_span
.start_time
)) /* value */);
3444 /* set the time bar. */
3446 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry1
),
3447 (double)time_span
.start_time
.tv_sec
,
3448 (double)time_span
.end_time
.tv_sec
);
3449 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry1
),
3450 (double)start_time
.tv_sec
);
3452 /* start nanoseconds */
3453 if(start_time
.tv_sec
== time_span
.start_time
.tv_sec
) {
3454 /* can be both beginning and end at the same time. */
3455 if(start_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3456 /* If we are at the end, max nsec to end.. -1 (not zero length) */
3457 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry2
),
3458 (double)time_span
.start_time
.tv_nsec
,
3459 (double)time_span
.end_time
.tv_nsec
-1);
3461 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry2
),
3462 (double)time_span
.start_time
.tv_nsec
,
3463 (double)NANOSECONDS_PER_SECOND
-1);
3465 } else if(start_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3466 /* If we are at the end, max nsec to end.. -1 (not zero length) */
3467 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry2
),
3469 (double)time_span
.end_time
.tv_nsec
-1);
3470 } else /* anywhere else */
3471 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry2
),
3473 (double)NANOSECONDS_PER_SECOND
-1);
3474 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry2
),
3475 (double)start_time
.tv_nsec
);
3478 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry3
),
3479 (double)time_span
.start_time
.tv_sec
,
3480 (double)time_span
.end_time
.tv_sec
);
3481 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry3
),
3482 (double)end_time
.tv_sec
);
3484 /* end nanoseconds */
3485 if(end_time
.tv_sec
== time_span
.start_time
.tv_sec
) {
3486 /* can be both beginning and end at the same time. */
3487 if(end_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3488 /* If we are at the end, max nsec to end.. */
3489 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry4
),
3490 (double)time_span
.start_time
.tv_nsec
+1,
3491 (double)time_span
.end_time
.tv_nsec
);
3493 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry4
),
3494 (double)time_span
.start_time
.tv_nsec
+1,
3495 (double)NANOSECONDS_PER_SECOND
-1);
3498 else if(end_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3499 /* If we are at the end, max nsec to end.. */
3500 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry4
),
3502 (double)time_span
.end_time
.tv_nsec
);
3504 else /* anywhere else */
3505 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry4
),
3507 (double)NANOSECONDS_PER_SECOND
-1);
3508 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry4
),
3509 (double)end_time
.tv_nsec
);
3512 if(time_width
.tv_nsec
== 0) {
3513 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry7
),
3515 (double)upper
.tv_sec
);
3517 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry7
),
3519 (double)upper
.tv_sec
);
3521 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry7
),
3522 (double)time_width
.tv_sec
);
3524 /* width nanoseconds */
3525 if(time_width
.tv_sec
== upper
.tv_sec
) {
3526 if(time_width
.tv_sec
== 0) {
3527 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry8
),
3529 (double)upper
.tv_nsec
);
3531 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry8
),
3533 (double)upper
.tv_nsec
);
3536 else if(time_width
.tv_sec
== 0) {
3537 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry8
),
3539 (double)upper
.tv_nsec
);
3541 else /* anywhere else */
3542 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry8
),
3544 (double)NANOSECONDS_PER_SECOND
-1);
3545 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry8
),
3546 (double)time_width
.tv_nsec
);
3548 /* call viewer hooks for new time window */
3549 set_time_window(tab
, &new_time_window
);
3551 tab
->time_manager_lock
= FALSE
;
3555 /* value changed for frame start s
3557 * Check time span : if ns is out of range, clip it the nearest good value.
3560 on_MEntry1_value_changed (GtkSpinButton
*spinbutton
,
3563 Tab
*tab
=(Tab
*)user_data
;
3564 LttvTracesetContext
* tsc
=
3565 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3566 TimeInterval time_span
= tsc
->time_span
;
3567 gint value
= gtk_spin_button_get_value_as_int(spinbutton
);
3569 TimeWindow new_time_window
= tab
->time_window
;
3571 LttTime end_time
= new_time_window
.end_time
;
3573 new_time_window
.start_time
.tv_sec
= value
;
3575 /* start nanoseconds */
3576 if(new_time_window
.start_time
.tv_sec
== time_span
.start_time
.tv_sec
) {
3577 if(new_time_window
.start_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3578 if(new_time_window
.start_time
.tv_nsec
> time_span
.end_time
.tv_nsec
)
3579 new_time_window
.start_time
.tv_nsec
= time_span
.end_time
.tv_nsec
-1;
3580 if(new_time_window
.start_time
.tv_nsec
< time_span
.start_time
.tv_nsec
)
3581 new_time_window
.start_time
.tv_nsec
= time_span
.start_time
.tv_nsec
;
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
;
3587 else if(new_time_window
.start_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3588 if(new_time_window
.start_time
.tv_nsec
> time_span
.end_time
.tv_nsec
)
3589 new_time_window
.start_time
.tv_nsec
= time_span
.end_time
.tv_nsec
-1;
3592 if(ltt_time_compare(new_time_window
.start_time
, end_time
) >= 0) {
3593 /* Then, we must push back end time : keep the same time width
3594 * if possible, else end traceset time */
3595 end_time
= LTT_TIME_MIN(ltt_time_add(new_time_window
.start_time
,
3596 new_time_window
.time_width
),
3597 time_span
.end_time
);
3600 /* Fix the time width to fit start time and end time */
3601 new_time_window
.time_width
= ltt_time_sub(end_time
,
3602 new_time_window
.start_time
);
3603 new_time_window
.time_width_double
=
3604 ltt_time_to_double(new_time_window
.time_width
);
3606 new_time_window
.end_time
= end_time
;
3608 time_change_manager(tab
, new_time_window
);
3613 on_MEntry2_value_changed (GtkSpinButton
*spinbutton
,
3616 Tab
*tab
=(Tab
*)user_data
;
3617 LttvTracesetContext
* tsc
=
3618 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3619 TimeInterval time_span
= tsc
->time_span
;
3620 gint value
= gtk_spin_button_get_value_as_int(spinbutton
);
3622 TimeWindow new_time_window
= tab
->time_window
;
3624 LttTime end_time
= new_time_window
.end_time
;
3626 new_time_window
.start_time
.tv_nsec
= value
;
3628 if(ltt_time_compare(new_time_window
.start_time
, end_time
) >= 0) {
3629 /* Then, we must push back end time : keep the same time width
3630 * if possible, else end traceset time */
3631 end_time
= LTT_TIME_MIN(ltt_time_add(new_time_window
.start_time
,
3632 new_time_window
.time_width
),
3633 time_span
.end_time
);
3636 /* Fix the time width to fit start time and end time */
3637 new_time_window
.time_width
= ltt_time_sub(end_time
,
3638 new_time_window
.start_time
);
3639 new_time_window
.time_width_double
=
3640 ltt_time_to_double(new_time_window
.time_width
);
3642 new_time_window
.end_time
= end_time
;
3644 time_change_manager(tab
, new_time_window
);
3649 on_MEntry3_value_changed (GtkSpinButton
*spinbutton
,
3652 Tab
*tab
=(Tab
*)user_data
;
3653 LttvTracesetContext
* tsc
=
3654 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3655 TimeInterval time_span
= tsc
->time_span
;
3656 gint value
= gtk_spin_button_get_value_as_int(spinbutton
);
3658 TimeWindow new_time_window
= tab
->time_window
;
3660 LttTime end_time
= new_time_window
.end_time
;
3662 end_time
.tv_sec
= value
;
3664 /* end nanoseconds */
3665 if(end_time
.tv_sec
== time_span
.start_time
.tv_sec
) {
3666 if(end_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3667 if(end_time
.tv_nsec
> time_span
.end_time
.tv_nsec
)
3668 end_time
.tv_nsec
= time_span
.end_time
.tv_nsec
;
3669 if(end_time
.tv_nsec
< time_span
.start_time
.tv_nsec
)
3670 end_time
.tv_nsec
= time_span
.start_time
.tv_nsec
+1;
3672 if(end_time
.tv_nsec
< time_span
.start_time
.tv_nsec
)
3673 end_time
.tv_nsec
= time_span
.start_time
.tv_nsec
+1;
3676 else if(end_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3677 if(end_time
.tv_nsec
> time_span
.end_time
.tv_nsec
)
3678 end_time
.tv_nsec
= time_span
.end_time
.tv_nsec
;
3681 if(ltt_time_compare(new_time_window
.start_time
, end_time
) >= 0) {
3682 /* Then, we must push front start time : keep the same time width
3683 * if possible, else end traceset time */
3684 new_time_window
.start_time
= LTT_TIME_MAX(
3685 ltt_time_sub(end_time
,
3686 new_time_window
.time_width
),
3687 time_span
.start_time
);
3690 /* Fix the time width to fit start time and end time */
3691 new_time_window
.time_width
= ltt_time_sub(end_time
,
3692 new_time_window
.start_time
);
3693 new_time_window
.time_width_double
=
3694 ltt_time_to_double(new_time_window
.time_width
);
3696 new_time_window
.end_time
= end_time
;
3698 time_change_manager(tab
, new_time_window
);
3703 on_MEntry4_value_changed (GtkSpinButton
*spinbutton
,
3706 Tab
*tab
=(Tab
*)user_data
;
3707 LttvTracesetContext
* tsc
=
3708 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3709 TimeInterval time_span
= tsc
->time_span
;
3710 gint value
= gtk_spin_button_get_value_as_int(spinbutton
);
3712 TimeWindow new_time_window
= tab
->time_window
;
3714 LttTime end_time
= new_time_window
.end_time
;
3716 end_time
.tv_nsec
= value
;
3718 if(ltt_time_compare(new_time_window
.start_time
, end_time
) >= 0) {
3719 /* Then, we must push front start time : keep the same time width
3720 * if possible, else end traceset time */
3721 new_time_window
.start_time
= LTT_TIME_MAX(
3722 ltt_time_sub(end_time
,
3723 new_time_window
.time_width
),
3724 time_span
.start_time
);
3727 /* Fix the time width to fit start time and end time */
3728 new_time_window
.time_width
= ltt_time_sub(end_time
,
3729 new_time_window
.start_time
);
3730 new_time_window
.time_width_double
=
3731 ltt_time_to_double(new_time_window
.time_width
);
3732 new_time_window
.end_time
= end_time
;
3734 time_change_manager(tab
, new_time_window
);
3738 /* value changed for time frame interval s
3740 * Check time span : if ns is out of range, clip it the nearest good value.
3743 on_MEntry7_value_changed (GtkSpinButton
*spinbutton
,
3746 Tab
*tab
=(Tab
*)user_data
;
3747 LttvTracesetContext
* tsc
=
3748 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3749 TimeInterval time_span
= tsc
->time_span
;
3750 gint value
= gtk_spin_button_get_value_as_int(spinbutton
);
3751 LttTime current_time
, time_delta
;
3752 TimeWindow new_time_window
= tab
->time_window
;
3753 current_time
= tab
->current_time
;
3755 time_delta
= ltt_time_sub(time_span
.end_time
,time_span
.start_time
);
3756 new_time_window
.time_width
.tv_sec
= value
;
3757 new_time_window
.time_width_double
=
3758 ltt_time_to_double(new_time_window
.time_width
);
3759 if(ltt_time_compare(new_time_window
.time_width
,time_delta
) > 0)
3760 { /* Case where zoom out is bigger than trace length */
3761 new_time_window
.start_time
= time_span
.start_time
;
3762 new_time_window
.time_width
= time_delta
;
3763 new_time_window
.time_width_double
= ltt_time_to_double(time_delta
);
3764 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
3765 new_time_window
.time_width
) ;
3769 /* Center the image on the current time */
3770 new_time_window
.start_time
=
3771 ltt_time_sub(current_time
,
3772 ltt_time_from_double(new_time_window
.time_width_double
/2.0));
3773 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
3774 new_time_window
.time_width
) ;
3775 /* If on borders, don't fall off */
3776 if(ltt_time_compare(new_time_window
.start_time
, time_span
.start_time
) <0
3777 || ltt_time_compare(new_time_window
.start_time
, time_span
.end_time
) >0)
3779 new_time_window
.start_time
= time_span
.start_time
;
3780 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
3781 new_time_window
.time_width
) ;
3785 if(ltt_time_compare(new_time_window
.end_time
,
3786 time_span
.end_time
) > 0
3787 || ltt_time_compare(new_time_window
.end_time
,
3788 time_span
.start_time
) < 0)
3790 new_time_window
.start_time
=
3791 ltt_time_sub(time_span
.end_time
, new_time_window
.time_width
);
3793 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
3794 new_time_window
.time_width
) ;
3800 if(ltt_time_compare(new_time_window
.time_width
, ltt_time_zero
) == 0) {
3801 g_warning("Zoom more than 1 ns impossible");
3803 time_change_manager(tab
, new_time_window
);
3808 on_MEntry8_value_changed (GtkSpinButton
*spinbutton
,
3811 Tab
*tab
=(Tab
*)user_data
;
3812 LttvTracesetContext
* tsc
=
3813 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3814 TimeInterval time_span
= tsc
->time_span
;
3815 gint value
= gtk_spin_button_get_value_as_int(spinbutton
);
3816 LttTime current_time
, time_delta
;
3817 TimeWindow new_time_window
= tab
->time_window
;
3818 current_time
= tab
->current_time
;
3820 time_delta
= ltt_time_sub(time_span
.end_time
,time_span
.start_time
);
3821 new_time_window
.time_width
.tv_nsec
= value
;
3822 new_time_window
.time_width_double
=
3823 ltt_time_to_double(new_time_window
.time_width
);
3824 if(ltt_time_compare(new_time_window
.time_width
,time_delta
) > 0)
3825 { /* Case where zoom out is bigger than trace length */
3826 new_time_window
.start_time
= time_span
.start_time
;
3827 new_time_window
.time_width
= time_delta
;
3828 new_time_window
.time_width_double
= ltt_time_to_double(time_delta
);
3829 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
3830 new_time_window
.time_width
) ;
3834 /* Center the image on the current time */
3835 new_time_window
.start_time
=
3836 ltt_time_sub(current_time
,
3837 ltt_time_from_double(new_time_window
.time_width_double
/2.0));
3838 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
3839 new_time_window
.time_width
) ;
3840 /* If on borders, don't fall off */
3841 if(ltt_time_compare(new_time_window
.start_time
, time_span
.start_time
) <0
3842 || ltt_time_compare(new_time_window
.start_time
, time_span
.end_time
) >0)
3844 new_time_window
.start_time
= time_span
.start_time
;
3845 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
3846 new_time_window
.time_width
) ;
3850 if(ltt_time_compare(new_time_window
.end_time
,
3851 time_span
.end_time
) > 0
3852 || ltt_time_compare(new_time_window
.end_time
,
3853 time_span
.start_time
) < 0)
3855 new_time_window
.start_time
=
3856 ltt_time_sub(time_span
.end_time
, new_time_window
.time_width
);
3858 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
3859 new_time_window
.time_width
) ;
3865 if(ltt_time_compare(new_time_window
.time_width
, ltt_time_zero
) == 0) {
3866 g_warning("Zoom more than 1 ns impossible");
3868 time_change_manager(tab
, new_time_window
);
3874 void current_time_change_manager (Tab
*tab
,
3875 LttTime new_current_time
)
3877 /* Only one source of time change */
3878 if(tab
->current_time_manager_lock
== TRUE
) return;
3880 tab
->current_time_manager_lock
= TRUE
;
3882 LttvTracesetContext
*tsc
= LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3883 TimeInterval time_span
= tsc
->time_span
;
3885 /* current seconds */
3886 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry5
),
3887 (double)time_span
.start_time
.tv_sec
,
3888 (double)time_span
.end_time
.tv_sec
);
3889 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry5
),
3890 (double)new_current_time
.tv_sec
);
3893 /* start nanoseconds */
3894 if(new_current_time
.tv_sec
== time_span
.start_time
.tv_sec
) {
3895 /* can be both beginning and end at the same time. */
3896 if(new_current_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3897 /* If we are at the end, max nsec to end.. */
3898 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry6
),
3899 (double)time_span
.start_time
.tv_nsec
,
3900 (double)time_span
.end_time
.tv_nsec
);
3902 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry6
),
3903 (double)time_span
.start_time
.tv_nsec
,
3904 (double)NANOSECONDS_PER_SECOND
-1);
3906 } else if(new_current_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3907 /* If we are at the end, max nsec to end.. */
3908 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry6
),
3910 (double)time_span
.end_time
.tv_nsec
);
3911 } else /* anywhere else */
3912 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry6
),
3914 (double)NANOSECONDS_PER_SECOND
-1);
3916 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry6
),
3917 (double)new_current_time
.tv_nsec
);
3919 set_current_time(tab
, &new_current_time
);
3921 tab
->current_time_manager_lock
= FALSE
;
3924 void current_position_change_manager(Tab
*tab
,
3925 LttvTracesetContextPosition
*pos
)
3927 LttvTracesetContext
*tsc
=
3928 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3929 TimeInterval time_span
= tsc
->time_span
;
3932 retval
= lttv_process_traceset_seek_position(tsc
, pos
);
3933 g_assert_cmpint(retval
, ==, 0);
3934 LttTime new_time
= lttv_traceset_context_position_get_time(pos
);
3935 /* Put the context in a state coherent position */
3936 lttv_state_traceset_seek_time_closest((LttvTracesetState
*)tsc
, ltt_time_zero
);
3938 current_time_change_manager(tab
, new_time
);
3940 set_current_position(tab
, pos
);
3945 on_MEntry5_value_changed (GtkSpinButton
*spinbutton
,
3948 Tab
*tab
= (Tab
*)user_data
;
3949 LttvTracesetContext
* tsc
=
3950 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3951 TimeInterval time_span
= tsc
->time_span
;
3952 gint value
= gtk_spin_button_get_value_as_int(spinbutton
);
3953 LttTime new_current_time
= tab
->current_time
;
3954 new_current_time
.tv_sec
= value
;
3956 /* current nanoseconds */
3957 if(new_current_time
.tv_sec
== time_span
.start_time
.tv_sec
) {
3958 if(new_current_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3959 if(new_current_time
.tv_nsec
> time_span
.end_time
.tv_nsec
)
3960 new_current_time
.tv_nsec
= time_span
.end_time
.tv_nsec
;
3961 if(new_current_time
.tv_nsec
< time_span
.start_time
.tv_nsec
)
3962 new_current_time
.tv_nsec
= time_span
.start_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
;
3968 else if(new_current_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3969 if(new_current_time
.tv_nsec
> time_span
.end_time
.tv_nsec
)
3970 new_current_time
.tv_nsec
= time_span
.end_time
.tv_nsec
;
3973 current_time_change_manager(tab
, new_current_time
);
3977 on_MEntry6_value_changed (GtkSpinButton
*spinbutton
,
3980 Tab
*tab
= (Tab
*)user_data
;
3981 gint value
= gtk_spin_button_get_value_as_int(spinbutton
);
3982 LttTime new_current_time
= tab
->current_time
;
3983 new_current_time
.tv_nsec
= value
;
3985 current_time_change_manager(tab
, new_current_time
);
3989 void scroll_value_changed_cb(GtkWidget
*scrollbar
,
3992 Tab
*tab
= (Tab
*)user_data
;
3993 TimeWindow new_time_window
;
3995 GtkAdjustment
*adjust
= gtk_range_get_adjustment(GTK_RANGE(scrollbar
));
3996 gdouble value
= gtk_adjustment_get_value(adjust
);
3997 // gdouble upper, lower, ratio, page_size;
3999 LttvTracesetContext
* tsc
=
4000 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
4001 TimeInterval time_span
= tsc
->time_span
;
4003 time
= ltt_time_add(ltt_time_from_double(value
),
4004 time_span
.start_time
);
4006 new_time_window
.start_time
= time
;
4008 page_size
= adjust
->page_size
;
4010 new_time_window
.time_width
=
4011 ltt_time_from_double(page_size
);
4013 new_time_window
.time_width_double
=
4016 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
4017 new_time_window
.time_width
);
4020 time_change_manager(tab
, new_time_window
);
4022 //time_window = tab->time_window;
4024 lower
= adjust
->lower
;
4025 upper
= adjust
->upper
;
4026 ratio
= (value
- lower
) / (upper
- lower
);
4027 g_info("lower %lu, upper %lu, value %lu, ratio %lu", lower
, upper
, value
, ratio
);
4029 //time = ltt_time_sub(time_span->end_time, time_span->start_time);
4030 //time = ltt_time_mul(time, (float)ratio);
4031 //time = ltt_time_add(time_span->start_time, time);
4032 time
= ltt_time_add(ltt_time_from_double(value
),
4033 time_span
.start_time
);
4035 time_window
.start_time
= time
;
4037 page_size
= adjust
->page_size
;
4039 time_window
.time_width
=
4040 ltt_time_from_double(page_size
);
4041 //time = ltt_time_sub(time_span.end_time, time);
4042 //if(ltt_time_compare(time,time_window.time_width) < 0){
4043 // time_window.time_width = time;
4046 /* call viewer hooks for new time window */
4047 set_time_window(tab
, &time_window
);
4052 /* Display a dialogue showing all eventtypes and traces, let user to select the interested
4053 * eventtypes, tracefiles and traces (filter)
4056 /* Select a trace which will be removed from traceset
4059 char * get_remove_trace(MainWindow
*mw_data
,
4060 char ** all_trace_name
, int nb_trace
)
4062 return get_selection(mw_data
, all_trace_name
, nb_trace
,
4063 "Select a trace", "Trace pathname");
4067 /* Select a module which will be loaded
4070 char * get_load_module(MainWindow
*mw_data
,
4071 char ** load_module_name
, int nb_module
)
4073 return get_selection(mw_data
, load_module_name
, nb_module
,
4074 "Select a module to load", "Module name");
4080 /* Select a module which will be unloaded
4083 char * get_unload_module(MainWindow
*mw_data
,
4084 char ** loaded_module_name
, int nb_module
)
4086 return get_selection(mw_data
, loaded_module_name
, nb_module
,
4087 "Select a module to unload", "Module name");
4091 /* Display a dialogue which shows all selectable items, let user to
4092 * select one of them
4095 char * get_selection(MainWindow
*mw_data
,
4096 char ** loaded_module_name
, int nb_module
,
4097 char *title
, char * column_title
)
4099 GtkWidget
* dialogue
;
4100 GtkWidget
* scroll_win
;
4102 GtkListStore
* store
;
4103 GtkTreeViewColumn
* column
;
4104 GtkCellRenderer
* renderer
;
4105 GtkTreeSelection
* select
;
4108 char * unload_module_name
= NULL
;
4110 dialogue
= gtk_dialog_new_with_buttons(title
,
4113 GTK_STOCK_OK
,GTK_RESPONSE_ACCEPT
,
4114 GTK_STOCK_CANCEL
,GTK_RESPONSE_REJECT
,
4116 gtk_window_set_default_size((GtkWindow
*)dialogue
, 500, 200);
4117 gtk_window_set_transient_for(GTK_WINDOW(dialogue
),
4118 GTK_WINDOW(mw_data
->mwindow
));
4120 scroll_win
= gtk_scrolled_window_new (NULL
, NULL
);
4121 gtk_widget_show ( scroll_win
);
4122 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll_win
),
4123 GTK_POLICY_AUTOMATIC
, GTK_POLICY_AUTOMATIC
);
4125 store
= gtk_list_store_new (N_COLUMNS
,G_TYPE_STRING
);
4126 tree
= gtk_tree_view_new_with_model(GTK_TREE_MODEL (store
));
4127 gtk_widget_show ( tree
);
4128 g_object_unref (G_OBJECT (store
));
4130 renderer
= gtk_cell_renderer_text_new ();
4131 column
= gtk_tree_view_column_new_with_attributes (column_title
,
4133 "text", MODULE_COLUMN
,
4135 gtk_tree_view_column_set_alignment (column
, 0.5);
4136 gtk_tree_view_column_set_fixed_width (column
, 150);
4137 gtk_tree_view_append_column (GTK_TREE_VIEW (tree
), column
);
4139 select
= gtk_tree_view_get_selection (GTK_TREE_VIEW (tree
));
4140 gtk_tree_selection_set_mode (select
, GTK_SELECTION_SINGLE
);
4142 gtk_container_add (GTK_CONTAINER (scroll_win
), tree
);
4144 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialogue
)->vbox
), scroll_win
,TRUE
, TRUE
,0);
4146 for(i
=0;i
<nb_module
;i
++){
4147 gtk_list_store_append (store
, &iter
);
4148 gtk_list_store_set (store
, &iter
, MODULE_COLUMN
,loaded_module_name
[i
],-1);
4151 id
= gtk_dialog_run(GTK_DIALOG(dialogue
));
4152 GtkTreeModel
**store_model
= (GtkTreeModel
**)&store
;
4154 case GTK_RESPONSE_ACCEPT
:
4155 case GTK_RESPONSE_OK
:
4156 if (gtk_tree_selection_get_selected (select
, store_model
, &iter
)){
4157 gtk_tree_model_get ((GtkTreeModel
*)store
, &iter
, MODULE_COLUMN
, &unload_module_name
, -1);
4159 case GTK_RESPONSE_REJECT
:
4160 case GTK_RESPONSE_CANCEL
:
4162 gtk_widget_destroy(dialogue
);
4166 return unload_module_name
;
4170 /* Insert all menu entry and tool buttons into this main window
4175 void add_all_menu_toolbar_constructors(MainWindow
* mw
, gpointer user_data
)
4179 lttvwindow_viewer_constructor constructor
;
4180 LttvMenus
* global_menu
, * instance_menu
;
4181 LttvToolbars
* global_toolbar
, * instance_toolbar
;
4182 LttvMenuClosure
*menu_item
;
4183 LttvToolbarClosure
*toolbar_item
;
4184 LttvAttributeValue value
;
4185 LttvIAttribute
*global_attributes
= LTTV_IATTRIBUTE(lttv_global_attributes());
4186 LttvIAttribute
*attributes
= mw
->attributes
;
4187 GtkWidget
* tool_menu_title_menu
, *new_widget
, *pixmap
;
4190 retval
= lttv_iattribute_find_by_path(global_attributes
, "viewers/menu",
4191 LTTV_POINTER
, &value
);
4193 if(*(value
.v_pointer
) == NULL
)
4194 *(value
.v_pointer
) = lttv_menus_new();
4195 global_menu
= (LttvMenus
*)*(value
.v_pointer
);
4197 retval
= lttv_iattribute_find_by_path(attributes
, "viewers/menu",
4198 LTTV_POINTER
, &value
);
4200 if(*(value
.v_pointer
) == NULL
)
4201 *(value
.v_pointer
) = lttv_menus_new();
4202 instance_menu
= (LttvMenus
*)*(value
.v_pointer
);
4204 retval
= lttv_iattribute_find_by_path(global_attributes
, "viewers/toolbar",
4205 LTTV_POINTER
, &value
);
4207 if(*(value
.v_pointer
) == NULL
)
4208 *(value
.v_pointer
) = lttv_toolbars_new();
4209 global_toolbar
= (LttvToolbars
*)*(value
.v_pointer
);
4211 retval
= lttv_iattribute_find_by_path(attributes
, "viewers/toolbar",
4212 LTTV_POINTER
, &value
);
4214 if(*(value
.v_pointer
) == NULL
)
4215 *(value
.v_pointer
) = lttv_toolbars_new();
4216 instance_toolbar
= (LttvToolbars
*)*(value
.v_pointer
);
4218 /* Add missing menu entries to window instance */
4219 for(i
=0;i
<global_menu
->len
;i
++) {
4220 menu_item
= &g_array_index(global_menu
, LttvMenuClosure
, i
);
4222 //add menu_item to window instance;
4223 constructor
= menu_item
->con
;
4224 tool_menu_title_menu
= lookup_widget(mw
->mwindow
,"ToolMenuTitle_menu");
4226 gtk_menu_item_new_with_mnemonic (menu_item
->menu_text
);
4227 gtk_container_add (GTK_CONTAINER (tool_menu_title_menu
),
4229 g_signal_connect ((gpointer
) new_widget
, "activate",
4230 G_CALLBACK (insert_viewer_wrap
),
4232 gtk_widget_show (new_widget
);
4233 lttv_menus_add(instance_menu
, menu_item
->con
,
4234 menu_item
->menu_path
,
4235 menu_item
->menu_text
,
4240 /* Add missing toolbar entries to window instance */
4241 for(i
=0;i
<global_toolbar
->len
;i
++) {
4242 toolbar_item
= &g_array_index(global_toolbar
, LttvToolbarClosure
, i
);
4244 //add toolbar_item to window instance;
4245 constructor
= toolbar_item
->con
;
4246 tool_menu_title_menu
= lookup_widget(mw
->mwindow
,"MToolbar1");
4247 pixbuf
= gdk_pixbuf_new_from_xpm_data((const char**)toolbar_item
->pixmap
);
4248 pixmap
= gtk_image_new_from_pixbuf(pixbuf
);
4250 gtk_toolbar_append_element (GTK_TOOLBAR (tool_menu_title_menu
),
4251 GTK_TOOLBAR_CHILD_BUTTON
,
4254 toolbar_item
->tooltip
, NULL
,
4255 pixmap
, NULL
, NULL
);
4256 gtk_label_set_use_underline(
4257 GTK_LABEL (((GtkToolbarChild
*) (
4258 g_list_last (GTK_TOOLBAR
4259 (tool_menu_title_menu
)->children
)->data
))->label
),
4261 gtk_container_set_border_width (GTK_CONTAINER (new_widget
), 1);
4262 g_signal_connect ((gpointer
) new_widget
,
4264 G_CALLBACK (insert_viewer_wrap
),
4266 gtk_widget_show (new_widget
);
4268 lttv_toolbars_add(instance_toolbar
, toolbar_item
->con
,
4269 toolbar_item
->tooltip
,
4270 toolbar_item
->pixmap
,
4278 /* Create a main window
4281 MainWindow
*construct_main_window(MainWindow
* parent
)
4285 g_debug("construct_main_window()");
4286 GtkWidget
* new_window
; /* New generated main window */
4287 MainWindow
* new_m_window
;/* New main window structure */
4288 GtkNotebook
* notebook
;
4289 LttvIAttribute
*attributes
=
4290 LTTV_IATTRIBUTE(g_object_new(LTTV_ATTRIBUTE_TYPE
, NULL
));
4291 LttvAttributeValue value
;
4294 new_m_window
= g_new(MainWindow
, 1);
4296 // Add the object's information to the module's array
4297 g_main_window_list
= g_slist_append(g_main_window_list
, new_m_window
);
4299 new_window
= create_MWindow();
4300 gtk_widget_show (new_window
);
4302 new_m_window
->mwindow
= new_window
;
4303 new_m_window
->attributes
= attributes
;
4305 retval
= lttv_iattribute_find_by_path(attributes
, "viewers/menu",
4306 LTTV_POINTER
, &value
);
4308 *(value
.v_pointer
) = lttv_menus_new();
4310 retval
= lttv_iattribute_find_by_path(attributes
, "viewers/toolbar",
4311 LTTV_POINTER
, &value
);
4313 *(value
.v_pointer
) = lttv_toolbars_new();
4315 add_all_menu_toolbar_constructors(new_m_window
, NULL
);
4317 g_object_set_data_full(G_OBJECT(new_window
),
4319 (gpointer
)new_m_window
,
4320 (GDestroyNotify
)g_free
);
4321 //create a default tab
4322 notebook
= (GtkNotebook
*)lookup_widget(new_m_window
->mwindow
, "MNotebook");
4323 if(notebook
== NULL
){
4324 g_info("Notebook does not exist\n");
4325 /* FIXME : destroy partially created widgets */
4326 g_free(new_m_window
);
4329 //gtk_notebook_popup_enable (GTK_NOTEBOOK(notebook));
4330 //for now there is no name field in LttvTraceset structure
4331 //Use "Traceset" as the label for the default tab
4333 GtkWidget
* parent_notebook
= lookup_widget(parent
->mwindow
, "MNotebook");
4334 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(parent_notebook
),
4335 gtk_notebook_get_current_page(GTK_NOTEBOOK(parent_notebook
)));
4341 LttvPluginTab
*ptab
;
4342 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
4343 parent_tab
= ptab
->tab
;
4345 LttvPluginTab
*ptab
= g_object_new(LTTV_TYPE_PLUGIN_TAB
, NULL
);
4347 new_m_window
, parent_tab
, notebook
, "Traceset");
4348 ptab
->parent
.top_widget
= ptab
->tab
->top_widget
;
4349 g_object_set_data_full(
4350 G_OBJECT(ptab
->tab
->vbox
),
4353 (GDestroyNotify
)tab_destructor
);
4354 new_tab
= ptab
->tab
;
4356 LttvPluginTab
*ptab
= g_object_new(LTTV_TYPE_PLUGIN_TAB
, NULL
);
4357 init_tab(ptab
->tab
, new_m_window
, NULL
, notebook
, "Traceset");
4358 ptab
->parent
.top_widget
= ptab
->tab
->top_widget
;
4359 g_object_set_data_full(
4360 G_OBJECT(ptab
->tab
->vbox
),
4363 (GDestroyNotify
)tab_destructor
);
4364 new_tab
= ptab
->tab
;
4367 /* Insert default viewers */
4369 LttvAttributeType type
;
4370 LttvAttributeName name
;
4371 LttvAttributeValue value
;
4372 LttvAttribute
*attribute
;
4374 LttvIAttribute
*attributes_global
=
4375 LTTV_IATTRIBUTE(lttv_global_attributes());
4377 attribute
= LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
4378 LTTV_IATTRIBUTE(attributes_global
),
4379 LTTV_VIEWER_CONSTRUCTORS
));
4380 g_assert(attribute
);
4382 name
= g_quark_from_string("guievents");
4383 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
4385 if(type
== LTTV_POINTER
) {
4386 lttvwindow_viewer_constructor viewer_constructor
=
4387 (lttvwindow_viewer_constructor
)*value
.v_pointer
;
4388 insert_viewer(new_window
, viewer_constructor
);
4391 name
= g_quark_from_string("guicontrolflow");
4392 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
4394 if(type
== LTTV_POINTER
) {
4395 lttvwindow_viewer_constructor viewer_constructor
=
4396 (lttvwindow_viewer_constructor
)*value
.v_pointer
;
4397 insert_viewer(new_window
, viewer_constructor
);
4400 name
= g_quark_from_string("guistatistics");
4401 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
4403 if(type
== LTTV_POINTER
) {
4404 lttvwindow_viewer_constructor viewer_constructor
=
4405 (lttvwindow_viewer_constructor
)*value
.v_pointer
;
4406 insert_viewer(new_window
, viewer_constructor
);
4410 g_info("There are now : %d windows\n",g_slist_length(g_main_window_list
));
4412 return new_m_window
;
4416 /* Free the memory occupied by a tab structure
4420 void tab_destructor(LttvPluginTab
* ptab
)
4422 int i
, nb
, ref_count
;
4424 Tab
*tab
= ptab
->tab
;
4426 gtk_object_destroy(GTK_OBJECT(tab
->tooltips
));
4429 g_object_unref(tab
->attributes
);
4431 if(tab
->interrupted_state
)
4432 g_object_unref(tab
->interrupted_state
);
4435 if(tab
->traceset_info
->traceset_context
!= NULL
){
4436 //remove state update hooks
4437 lttv_state_remove_event_hooks(
4438 (LttvTracesetState
*)tab
->traceset_info
->
4440 lttv_context_fini(LTTV_TRACESET_CONTEXT(tab
->traceset_info
->
4442 g_object_unref(tab
->traceset_info
->traceset_context
);
4444 if(tab
->traceset_info
->traceset
!= NULL
) {
4445 nb
= lttv_traceset_number(tab
->traceset_info
->traceset
);
4446 for(i
= 0 ; i
< nb
; i
++) {
4447 trace
= lttv_traceset_get(tab
->traceset_info
->traceset
, i
);
4448 ref_count
= lttv_trace_get_ref_number(trace
);
4450 ltt_trace_close(lttv_trace(trace
));
4454 lttv_traceset_destroy(tab
->traceset_info
->traceset
);
4455 /* Remove the idle events requests processing function of the tab */
4456 g_idle_remove_by_data(tab
);
4458 g_slist_free(tab
->events_requests
);
4459 g_free(tab
->traceset_info
);
4461 g_object_unref(ptab
);
4465 /* Create a tab and insert it into the current main window
4468 void init_tab(Tab
*tab
, MainWindow
* mw
, Tab
*copy_tab
,
4469 GtkNotebook
* notebook
, char * label
)
4473 //LttvFilter *filter = NULL;
4475 //create a new tab data structure
4476 //tab = g_new(Tab,1);
4478 //construct and initialize the traceset_info
4479 tab
->traceset_info
= g_new(TracesetInfo
,1);
4482 tab
->traceset_info
->traceset
=
4483 lttv_traceset_copy(copy_tab
->traceset_info
->traceset
);
4485 /* Copy the previous tab's filter */
4486 /* We can clone the filter, as we copy the trace set also */
4487 /* The filter must always be in sync with the trace set */
4488 tab
->filter
= lttv_filter_clone(copy_tab
->filter
);
4490 tab
->traceset_info
->traceset
= lttv_traceset_new();
4494 lttv_attribute_write_xml(
4495 lttv_traceset_attribute(tab
->traceset_info
->traceset
),
4501 tab
->time_manager_lock
= FALSE
;
4502 tab
->current_time_manager_lock
= FALSE
;
4504 //FIXME copy not implemented in lower level
4505 tab
->traceset_info
->traceset_context
=
4506 g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
4507 g_assert(tab
->traceset_info
->traceset_context
!= NULL
);
4509 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
),
4510 tab
->traceset_info
->traceset
);
4511 //add state update hooks
4512 lttv_state_add_event_hooks(
4513 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
4515 //determine the current_time and time_window of the tab
4517 if(copy_tab
!= NULL
){
4518 tab
->time_window
= copy_tab
->time_window
;
4519 tab
->current_time
= copy_tab
->current_time
;
4521 tab
->time_window
.start_time
=
4522 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
4523 time_span
.start_time
;
4524 if(DEFAULT_TIME_WIDTH_S
<
4525 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
4526 time_span
.end_time
.tv_sec
)
4527 tmp_time
.tv_sec
= DEFAULT_TIME_WIDTH_S
;
4530 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
4531 time_span
.end_time
.tv_sec
;
4532 tmp_time
.tv_nsec
= 0;
4533 tab
->time_window
.time_width
= tmp_time
;
4534 tab
->current_time
.tv_sec
=
4535 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
4536 time_span
.start_time
.tv_sec
;
4537 tab
->current_time
.tv_nsec
=
4538 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
4539 time_span
.start_time
.tv_nsec
;
4542 tab
->attributes
= LTTV_IATTRIBUTE(g_object_new(LTTV_ATTRIBUTE_TYPE
, NULL
));
4543 tab
->interrupted_state
= g_object_new(LTTV_ATTRIBUTE_TYPE
, NULL
);
4545 tab
->vbox
= gtk_vbox_new(FALSE
, 2);
4546 tab
->top_widget
= tab
->vbox
;
4547 //g_object_set_data_full(G_OBJECT(tab->top_widget), "filter",
4548 // filter, (GDestroyNotify)lttv_filter_destroy);
4550 // g_signal_connect (G_OBJECT(tab->top_widget),
4552 // G_CALLBACK (on_top_notify),
4555 tab
->viewer_container
= gtk_vbox_new(TRUE
, 2);
4556 tab
->scrollbar
= gtk_hscrollbar_new(NULL
);
4557 //tab->multivpaned = gtk_multi_vpaned_new();
4559 gtk_box_pack_start(GTK_BOX(tab
->vbox
),
4560 tab
->viewer_container
,
4562 TRUE
, /* Give the extra space to the child */
4563 0); /* No padding */
4566 // tab->time_window = copy_tab->time_window;
4567 // tab->current_time = copy_tab->current_time;
4570 /* Create the timebar */
4572 tab
->MTimebar
= gtk_hbox_new(FALSE
, 2);
4573 gtk_widget_show(tab
->MTimebar
);
4574 tab
->tooltips
= gtk_tooltips_new();
4576 tab
->MEventBox1a
= gtk_event_box_new();
4577 gtk_widget_show(tab
->MEventBox1a
);
4578 gtk_tooltips_set_tip(tab
->tooltips
, tab
->MEventBox1a
,
4579 "Paste Start and End Times Here", "");
4580 tab
->MText1a
= gtk_label_new("Time Frame ");
4581 gtk_widget_show(tab
->MText1a
);
4582 gtk_container_add(GTK_CONTAINER(tab
->MEventBox1a
), tab
->MText1a
);
4583 tab
->MEventBox1b
= gtk_event_box_new();
4584 gtk_widget_show(tab
->MEventBox1b
);
4585 gtk_tooltips_set_tip(tab
->tooltips
, tab
->MEventBox1b
,
4586 "Paste Start Time Here", "");
4587 tab
->MText1b
= gtk_label_new("start: ");
4588 gtk_widget_show(tab
->MText1b
);
4589 gtk_container_add(GTK_CONTAINER(tab
->MEventBox1b
), tab
->MText1b
);
4590 tab
->MText2
= gtk_label_new("s");
4591 gtk_widget_show(tab
->MText2
);
4592 tab
->MText3a
= gtk_label_new("ns");
4593 gtk_widget_show(tab
->MText3a
);
4595 tab
->MEventBox3b
= gtk_event_box_new();
4596 gtk_widget_show(tab
->MEventBox3b
);
4597 gtk_tooltips_set_tip(tab
->tooltips
, tab
->MEventBox3b
,
4598 "Paste End Time Here", "");
4599 tab
->MText3b
= gtk_label_new("end:");
4600 gtk_widget_show(tab
->MText3b
);
4601 gtk_container_add(GTK_CONTAINER(tab
->MEventBox3b
), tab
->MText3b
);
4602 tab
->MText4
= gtk_label_new("s");
4603 gtk_widget_show(tab
->MText4
);
4604 tab
->MText5a
= gtk_label_new("ns");
4605 gtk_widget_show(tab
->MText5a
);
4607 tab
->MEventBox8
= gtk_event_box_new();
4608 gtk_widget_show(tab
->MEventBox8
);
4609 gtk_tooltips_set_tip(tab
->tooltips
, tab
->MEventBox8
,
4610 "Paste Time Interval here", "");
4611 tab
->MText8
= gtk_label_new("Time Interval:");
4612 gtk_widget_show(tab
->MText8
);
4613 gtk_container_add(GTK_CONTAINER(tab
->MEventBox8
), tab
->MText8
);
4614 tab
->MText9
= gtk_label_new("s");
4615 gtk_widget_show(tab
->MText9
);
4616 tab
->MText10
= gtk_label_new("ns");
4617 gtk_widget_show(tab
->MText10
);
4619 tab
->MEventBox5b
= gtk_event_box_new();
4620 gtk_widget_show(tab
->MEventBox5b
);
4621 gtk_tooltips_set_tip(tab
->tooltips
, tab
->MEventBox5b
,
4622 "Paste Current Time Here", "");
4623 tab
->MText5b
= gtk_label_new("Current Time:");
4624 gtk_widget_show(tab
->MText5b
);
4625 gtk_container_add(GTK_CONTAINER(tab
->MEventBox5b
), tab
->MText5b
);
4626 tab
->MText6
= gtk_label_new("s");
4627 gtk_widget_show(tab
->MText6
);
4628 tab
->MText7
= gtk_label_new("ns");
4629 gtk_widget_show(tab
->MText7
);
4631 tab
->MEntry1
= gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4632 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab
->MEntry1
),0);
4633 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab
->MEntry1
),TRUE
);
4634 gtk_widget_show(tab
->MEntry1
);
4635 tab
->MEntry2
= gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4636 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab
->MEntry2
),0);
4637 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab
->MEntry2
),TRUE
);
4638 gtk_widget_show(tab
->MEntry2
);
4639 tab
->MEntry3
= gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4640 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab
->MEntry3
),0);
4641 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab
->MEntry3
),TRUE
);
4642 gtk_widget_show(tab
->MEntry3
);
4643 tab
->MEntry4
= gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4644 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab
->MEntry4
),0);
4645 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab
->MEntry4
),TRUE
);
4646 gtk_widget_show(tab
->MEntry4
);
4647 tab
->MEntry5
= gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4648 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab
->MEntry5
),0);
4649 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab
->MEntry5
),TRUE
);
4650 gtk_widget_show(tab
->MEntry5
);
4651 tab
->MEntry6
= gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4652 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab
->MEntry6
),0);
4653 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab
->MEntry6
),TRUE
);
4654 gtk_widget_show(tab
->MEntry6
);
4655 tab
->MEntry7
= gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4656 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab
->MEntry7
),0);
4657 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab
->MEntry7
),TRUE
);
4658 gtk_widget_show(tab
->MEntry7
);
4659 tab
->MEntry8
= gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4660 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab
->MEntry8
),0);
4661 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab
->MEntry8
),TRUE
);
4662 gtk_widget_show(tab
->MEntry8
);
4664 GtkWidget
*temp_widget
;
4666 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEventBox1a
, FALSE
,
4668 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEventBox1b
, FALSE
,
4670 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEntry1
, FALSE
, FALSE
, 0);
4671 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MText2
, FALSE
, FALSE
, 0);
4672 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEntry2
, FALSE
, FALSE
, 0);
4673 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MText3a
, FALSE
, FALSE
, 0);
4674 temp_widget
= gtk_vseparator_new();
4675 gtk_widget_show(temp_widget
);
4676 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), temp_widget
, FALSE
, FALSE
, 0);
4677 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEventBox3b
, FALSE
,
4679 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEntry3
, FALSE
, FALSE
, 0);
4680 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MText4
, FALSE
, FALSE
, 0);
4681 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEntry4
, FALSE
, FALSE
, 0);
4682 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MText5a
, FALSE
, FALSE
, 0);
4683 temp_widget
= gtk_vseparator_new();
4684 gtk_widget_show(temp_widget
);
4685 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), temp_widget
, FALSE
, FALSE
, 0);
4686 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEventBox8
, FALSE
,
4688 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEntry7
, FALSE
, FALSE
, 0);
4689 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MText9
, FALSE
, FALSE
, 0);
4690 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEntry8
, FALSE
, FALSE
, 0);
4691 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MText10
, FALSE
, FALSE
, 0);
4693 temp_widget
= gtk_vseparator_new();
4694 gtk_widget_show(temp_widget
);
4695 gtk_box_pack_end (GTK_BOX (tab
->MTimebar
), tab
->MText7
, FALSE
, FALSE
, 0);
4696 gtk_box_pack_end (GTK_BOX (tab
->MTimebar
), tab
->MEntry6
, FALSE
, FALSE
, 0);
4697 gtk_box_pack_end (GTK_BOX (tab
->MTimebar
), tab
->MText6
, FALSE
, FALSE
, 0);
4698 gtk_box_pack_end (GTK_BOX (tab
->MTimebar
), tab
->MEntry5
, FALSE
, FALSE
, 0);
4699 gtk_box_pack_end (GTK_BOX (tab
->MTimebar
), tab
->MEventBox5b
, FALSE
,
4701 gtk_box_pack_end (GTK_BOX (tab
->MTimebar
), temp_widget
, FALSE
, FALSE
, 0);
4704 //GtkWidget *test = gtk_button_new_with_label("drop");
4705 //gtk_button_set_relief(GTK_BUTTON(test), GTK_RELIEF_NONE);
4706 //gtk_widget_show(test);
4707 //gtk_box_pack_end(GTK_BOX (tab->MTimebar), test, FALSE, FALSE, 0);
4708 //gtk_widget_add_events(tab->MText1, GDK_ALL_EVENTS_MASK);//GDK_BUTTON_PRESS_MASK);
4709 /*GtkWidget *event_box = gtk_event_box_new();
4710 gtk_widget_show(event_box);
4711 gtk_tooltips_set_tip(tooltips, event_box,
4712 "Paste Current Time Here", "");
4713 gtk_box_pack_end(GTK_BOX (tab->MTimebar), event_box, FALSE, FALSE, 0);
4714 GtkWidget *test = gtk_label_new("drop");
4715 gtk_container_add(GTK_CONTAINER(event_box), test);
4716 gtk_widget_show(test);
4717 g_signal_connect (G_OBJECT(event_box),
4718 "button-press-event",
4719 G_CALLBACK (on_MText1_paste),
4723 g_signal_connect (G_OBJECT(tab
->MEventBox1a
),
4724 "button-press-event",
4725 G_CALLBACK (on_MEventBox1a_paste
),
4728 g_signal_connect (G_OBJECT(tab
->MEventBox1b
),
4729 "button-press-event",
4730 G_CALLBACK (on_MEventBox1b_paste
),
4732 g_signal_connect (G_OBJECT(tab
->MEventBox3b
),
4733 "button-press-event",
4734 G_CALLBACK (on_MEventBox3b_paste
),
4736 g_signal_connect (G_OBJECT(tab
->MEventBox5b
),
4737 "button-press-event",
4738 G_CALLBACK (on_MEventBox5b_paste
),
4740 g_signal_connect (G_OBJECT(tab
->MEventBox8
),
4741 "button-press-event",
4742 G_CALLBACK (on_MEventBox8_paste
),
4746 gtk_box_pack_end(GTK_BOX(tab
->vbox
),
4748 FALSE
, /* Do not expand */
4749 FALSE
, /* Fill has no effect here (expand false) */
4750 0); /* No padding */
4752 gtk_box_pack_end(GTK_BOX(tab
->vbox
),
4754 FALSE
, /* Do not expand */
4755 FALSE
, /* Fill has no effect here (expand false) */
4756 0); /* No padding */
4758 g_object_set_data(G_OBJECT(tab
->viewer_container
), "focused_viewer", NULL
);
4764 // Display a label with a X
4765 GtkWidget *w_hbox = gtk_hbox_new(FALSE, 4);
4766 GtkWidget *w_label = gtk_label_new (label);
4767 GtkWidget *pixmap = create_pixmap(GTK_WIDGET(notebook), "close.png");
4768 GtkWidget *w_button = gtk_button_new ();
4769 gtk_container_add(GTK_CONTAINER(w_button), pixmap);
4770 //GtkWidget *w_button = gtk_button_new_with_label("x");
4772 gtk_button_set_relief(GTK_BUTTON(w_button), GTK_RELIEF_NONE);
4774 gtk_box_pack_start(GTK_BOX(w_hbox), w_label, TRUE, TRUE, 0);
4775 gtk_box_pack_end(GTK_BOX(w_hbox), w_button, FALSE,
4778 g_signal_connect_swapped (w_button, "clicked",
4779 G_CALLBACK (on_close_tab_X_clicked),
4782 gtk_widget_set_state(w_button, GTK_STATE_ACTIVE);
4784 gtk_widget_show (w_label);
4785 gtk_widget_show (pixmap);
4786 gtk_widget_show (w_button);
4787 gtk_widget_show (w_hbox);
4789 tab->label = w_hbox;
4793 tab
->label
= gtk_label_new (label
);
4795 gtk_widget_show(tab
->label
);
4796 gtk_widget_show(tab
->scrollbar
);
4797 gtk_widget_show(tab
->viewer_container
);
4798 gtk_widget_show(tab
->vbox
);
4799 //gtk_widget_show(tab->multivpaned);
4802 /* Start with empty events requests list */
4803 tab
->events_requests
= NULL
;
4804 tab
->events_request_pending
= FALSE
;
4805 tab
->stop_foreground
= FALSE
;
4809 g_signal_connect(G_OBJECT(tab
->scrollbar
), "value-changed",
4810 G_CALLBACK(scroll_value_changed_cb
), tab
);
4812 g_signal_connect ((gpointer
) tab
->MEntry1
, "value-changed",
4813 G_CALLBACK (on_MEntry1_value_changed
),
4815 g_signal_connect ((gpointer
) tab
->MEntry2
, "value-changed",
4816 G_CALLBACK (on_MEntry2_value_changed
),
4818 g_signal_connect ((gpointer
) tab
->MEntry3
, "value-changed",
4819 G_CALLBACK (on_MEntry3_value_changed
),
4821 g_signal_connect ((gpointer
) tab
->MEntry4
, "value-changed",
4822 G_CALLBACK (on_MEntry4_value_changed
),
4824 g_signal_connect ((gpointer
) tab
->MEntry5
, "value-changed",
4825 G_CALLBACK (on_MEntry5_value_changed
),
4827 g_signal_connect ((gpointer
) tab
->MEntry6
, "value-changed",
4828 G_CALLBACK (on_MEntry6_value_changed
),
4830 g_signal_connect ((gpointer
) tab
->MEntry7
, "value-changed",
4831 G_CALLBACK (on_MEntry7_value_changed
),
4833 g_signal_connect ((gpointer
) tab
->MEntry8
, "value-changed",
4834 G_CALLBACK (on_MEntry8_value_changed
),
4837 //g_signal_connect(G_OBJECT(tab->scrollbar), "changed",
4838 // G_CALLBACK(scroll_value_changed_cb), tab);
4841 //insert tab into notebook
4842 gtk_notebook_append_page(notebook
,
4845 list
= gtk_container_get_children(GTK_CONTAINER(notebook
));
4846 gtk_notebook_set_current_page(notebook
,g_list_length(list
)-1);
4847 // always show : not if(g_list_length(list)>1)
4848 gtk_notebook_set_show_tabs(notebook
, TRUE
);
4851 lttvwindow_report_time_window(tab
, copy_tab
->time_window
);
4852 lttvwindow_report_current_time(tab
, copy_tab
->current_time
);
4854 TimeWindow time_window
;
4856 time_window
.start_time
= ltt_time_zero
;
4857 time_window
.end_time
= ltt_time_add(time_window
.start_time
,
4858 lttvwindow_default_time_width
);
4859 time_window
.time_width
= lttvwindow_default_time_width
;
4860 time_window
.time_width_double
= ltt_time_to_double(time_window
.time_width
);
4862 lttvwindow_report_time_window(tab
, time_window
);
4863 lttvwindow_report_current_time(tab
, ltt_time_zero
);
4866 LttvTraceset
*traceset
= tab
->traceset_info
->traceset
;
4867 SetTraceset(tab
, traceset
);
4871 * execute_events_requests
4873 * Idle function that executes the pending requests for a tab.
4875 * @return return value : TRUE : keep the idle function, FALSE : remove it.
4877 gboolean
execute_events_requests(Tab
*tab
)
4879 return ( lttvwindow_process_pending_requests(tab
) );
4883 __EXPORT
void create_main_window_with_trace_list(GSList
*traces
)
4885 GSList
*iter
= NULL
;
4888 MainWindow
*mw
= construct_main_window(NULL
);
4889 GtkWidget
*widget
= mw
->mwindow
;
4891 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
4892 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
4893 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
4894 LttvPluginTab
*ptab
;
4898 ptab
= create_new_tab(widget
, NULL
);
4901 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
4905 for(iter
=traces
; iter
!=NULL
; iter
=g_slist_next(iter
)) {
4906 gchar
*path
= (gchar
*)iter
->data
;
4908 gchar abs_path
[PATH_MAX
];
4912 get_absolute_pathname(path
, abs_path
);
4913 trace_v
= lttvwindowtraces_get_trace_by_name(abs_path
);
4914 if(trace_v
== NULL
) {
4915 trace
= ltt_trace_open(abs_path
);
4917 g_warning("cannot open trace %s", abs_path
);
4919 GtkWidget
*dialogue
=
4920 gtk_message_dialog_new(
4921 GTK_WINDOW(gtk_widget_get_toplevel(widget
)),
4922 GTK_DIALOG_MODAL
|GTK_DIALOG_DESTROY_WITH_PARENT
,
4925 "Cannot open trace : maybe you should enter in the directory "
4927 gtk_dialog_run(GTK_DIALOG(dialogue
));
4928 gtk_widget_destroy(dialogue
);
4930 trace_v
= lttv_trace_new(trace
);
4931 lttvwindowtraces_add_trace(trace_v
);
4932 lttvwindow_add_trace(tab
, trace_v
);
4935 lttvwindow_add_trace(tab
, trace_v
);
4939 LttvTraceset
*traceset
;
4941 traceset
= tab
->traceset_info
->traceset
;
4942 SetTraceset(tab
, traceset
);