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 <lttv/sync/sync_chain_lttv.h>
43 #include <lttvwindow/mainwindow.h>
44 #include <lttvwindow/mainwindow-private.h>
45 #include <lttvwindow/menu.h>
46 #include <lttvwindow/toolbar.h>
47 #include <lttvwindow/lttvwindow.h>
48 #include <lttvwindow/lttvwindowtraces.h>
49 #include <lttvwindow/lttv_plugin_tab.h>
51 static LttTime lttvwindow_default_time_width
= { 1, 0 };
52 #define CLIP_BUF 256 // size of clipboard buffer
54 extern LttvTrace
*g_init_trace
;
57 /** Array containing instanced objects. */
58 extern GSList
* g_main_window_list
;
60 /** MD : keep old directory. */
61 static char remember_plugins_dir
[PATH_MAX
] = "";
62 static char remember_trace_dir
[PATH_MAX
] = "";
64 void tab_destructor(LttvPluginTab
* ptab
);
66 MainWindow
* get_window_data_struct(GtkWidget
* widget
);
67 char * get_load_module(MainWindow
*mw
,
68 char ** load_module_name
, int nb_module
);
69 char * get_unload_module(MainWindow
*mw
,
70 char ** loaded_module_name
, int nb_module
);
71 char * get_remove_trace(MainWindow
*mw
, char ** all_trace_name
, int nb_trace
);
72 char * get_selection(MainWindow
*mw
,
73 char ** all_name
, int nb
, char *title
, char * column_title
);
74 void init_tab(Tab
*tab
, MainWindow
* mw
, Tab
*copy_tab
,
75 GtkNotebook
* notebook
, char * label
);
77 static void insert_viewer(GtkWidget
* widget
, lttvwindow_viewer_constructor constructor
);
79 LttvPluginTab
*create_new_tab(GtkWidget
* widget
, gpointer user_data
);
81 static gboolean
lttvwindow_process_pending_requests(Tab
*tab
);
95 /* Pasting routines */
97 static void MEventBox1a_receive(GtkClipboard
*clipboard
,
101 if(text
== NULL
) return;
102 Tab
*tab
= (Tab
*)data
;
103 gchar buffer
[CLIP_BUF
];
104 gchar
*ptr
= buffer
, *ptr_ssec
, *ptr_snsec
, *ptr_esec
, *ptr_ensec
;
106 strncpy(buffer
, text
, CLIP_BUF
);
109 while(!isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
110 /* remove leading junk */
112 while(isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
113 /* read all the first number */
117 while(!isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
118 /* remove leading junk */
120 while(isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
121 /* read all the first number */
125 while(!isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
126 /* remove leading junk */
128 while(isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
129 /* read all the first number */
133 while(!isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
134 /* remove leading junk */
136 while(isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
137 /* read all the first number */
140 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry1
),
141 (double)strtoul(ptr_ssec
, NULL
, 10));
142 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry2
),
143 (double)strtoul(ptr_snsec
, NULL
, 10));
144 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry3
),
145 (double)strtoul(ptr_esec
, NULL
, 10));
146 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry4
),
147 (double)strtoul(ptr_ensec
, NULL
, 10));
150 static gboolean
on_MEventBox1a_paste(GtkWidget
*widget
, GdkEventButton
*event
,
153 Tab
*tab
= (Tab
*)data
;
155 GtkClipboard
*clip
= gtk_clipboard_get_for_display(gdk_display_get_default(),
156 GDK_SELECTION_PRIMARY
);
157 gtk_clipboard_request_text(clip
,
158 (GtkClipboardTextReceivedFunc
)MEventBox1a_receive
,
165 static void MEventBox1b_receive(GtkClipboard
*clipboard
,
169 if(text
== NULL
) return;
170 Tab
*tab
= (Tab
*)data
;
171 gchar buffer
[CLIP_BUF
];
172 gchar
*ptr
= buffer
, *ptr_sec
, *ptr_nsec
;
174 strncpy(buffer
, text
, CLIP_BUF
);
176 while(!isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
177 /* remove leading junk */
179 while(isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
180 /* read all the first number */
184 while(!isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
185 /* remove leading junk */
187 while(isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
188 /* read all the first number */
191 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry1
),
192 (double)strtoul(ptr_sec
, NULL
, 10));
193 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry2
),
194 (double)strtoul(ptr_nsec
, NULL
, 10));
198 static gboolean
on_MEventBox1b_paste(GtkWidget
*widget
, GdkEventButton
*event
,
201 Tab
*tab
= (Tab
*)data
;
203 GtkClipboard
*clip
= gtk_clipboard_get_for_display(gdk_display_get_default(),
204 GDK_SELECTION_PRIMARY
);
205 gtk_clipboard_request_text(clip
,
206 (GtkClipboardTextReceivedFunc
)MEventBox1b_receive
,
212 static void MEventBox3b_receive(GtkClipboard
*clipboard
,
216 if(text
== NULL
) return;
217 Tab
*tab
= (Tab
*)data
;
218 gchar buffer
[CLIP_BUF
];
219 gchar
*ptr
= buffer
, *ptr_sec
, *ptr_nsec
;
221 strncpy(buffer
, text
, CLIP_BUF
);
223 while(!isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
224 /* remove leading junk */
226 while(isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
227 /* read all the first number */
231 while(!isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
232 /* remove leading junk */
234 while(isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
235 /* read all the first number */
238 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry3
),
239 (double)strtoul(ptr_sec
, NULL
, 10));
240 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry4
),
241 (double)strtoul(ptr_nsec
, NULL
, 10));
245 static gboolean
on_MEventBox3b_paste(GtkWidget
*widget
, GdkEventButton
*event
,
248 Tab
*tab
= (Tab
*)data
;
250 GtkClipboard
*clip
= gtk_clipboard_get_for_display(gdk_display_get_default(),
251 GDK_SELECTION_PRIMARY
);
252 gtk_clipboard_request_text(clip
,
253 (GtkClipboardTextReceivedFunc
)MEventBox3b_receive
,
259 static void MEventBox5b_receive(GtkClipboard
*clipboard
,
263 if(text
== NULL
) return;
264 Tab
*tab
= (Tab
*)data
;
265 gchar buffer
[CLIP_BUF
];
266 gchar
*ptr
= buffer
, *ptr_sec
, *ptr_nsec
;
268 strncpy(buffer
, text
, CLIP_BUF
);
270 while(!isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
271 /* remove leading junk */
273 while(isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
274 /* read all the first number */
278 while(!isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
279 /* remove leading junk */
281 while(isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
282 /* read all the first number */
285 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry5
),
286 (double)strtoul(ptr_sec
, NULL
, 10));
287 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry6
),
288 (double)strtoul(ptr_nsec
, NULL
, 10));
292 static gboolean
on_MEventBox5b_paste(GtkWidget
*widget
, GdkEventButton
*event
,
295 Tab
*tab
= (Tab
*)data
;
297 GtkClipboard
*clip
= gtk_clipboard_get_for_display(gdk_display_get_default(),
298 GDK_SELECTION_PRIMARY
);
299 gtk_clipboard_request_text(clip
,
300 (GtkClipboardTextReceivedFunc
)MEventBox5b_receive
,
306 static void MEventBox8_receive(GtkClipboard
*clipboard
,
310 if(text
== NULL
) return;
311 Tab
*tab
= (Tab
*)data
;
312 gchar buffer
[CLIP_BUF
];
313 gchar
*ptr
= buffer
, *ptr_sec
, *ptr_nsec
;
315 strncpy(buffer
, text
, CLIP_BUF
);
317 while(!isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
318 /* remove leading junk */
320 while(isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
321 /* read all the first number */
325 while(!isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
326 /* remove leading junk */
328 while(isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
329 /* read all the first number */
332 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry7
),
333 (double)strtoul(ptr_sec
, NULL
, 10));
334 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry8
),
335 (double)strtoul(ptr_nsec
, NULL
, 10));
339 static gboolean
on_MEventBox8_paste(GtkWidget
*widget
, GdkEventButton
*event
,
342 Tab
*tab
= (Tab
*)data
;
344 GtkClipboard
*clip
= gtk_clipboard_get_for_display(gdk_display_get_default(),
345 GDK_SELECTION_PRIMARY
);
346 gtk_clipboard_request_text(clip
,
347 (GtkClipboardTextReceivedFunc
)MEventBox8_receive
,
353 static void on_top_notify(GObject
*gobject
,
357 Tab
*tab
= (Tab
*)user_data
;
358 g_message("in on_top_notify.\n");
362 static gboolean
viewer_grab_focus(GtkWidget
*widget
, GdkEventButton
*event
,
365 GtkWidget
*viewer
= GTK_WIDGET(data
);
366 GtkWidget
*viewer_container
= gtk_widget_get_parent(viewer
);
368 g_debug("FOCUS GRABBED");
369 g_object_set_data(G_OBJECT(viewer_container
), "focused_viewer", viewer
);
374 static void connect_focus_recursive(GtkWidget
*widget
,
377 if(GTK_IS_CONTAINER(widget
)) {
378 gtk_container_forall(GTK_CONTAINER(widget
),
379 (GtkCallback
)connect_focus_recursive
,
383 if(GTK_IS_TREE_VIEW(widget
)) {
384 gtk_tree_view_set_headers_clickable(GTK_TREE_VIEW(widget
), TRUE
);
386 gtk_widget_add_events(widget
, GDK_BUTTON_PRESS_MASK
);
387 g_signal_connect (G_OBJECT(widget
),
388 "button-press-event",
389 G_CALLBACK (viewer_grab_focus
),
393 /* Stop all the processings and call gtk_main_quit() */
394 static void mainwindow_quit()
396 lttvwindowtraces_unregister_requests(g_quark_from_string("stats"));
397 lttvwindowtraces_unregister_requests(g_quark_from_string("state"));
398 lttvwindowtraces_unregister_computation_hooks(g_quark_from_string("stats"));
399 lttvwindowtraces_unregister_computation_hooks(g_quark_from_string("state"));
405 /* insert_viewer function constructs an instance of a viewer first,
406 * then inserts the widget of the instance into the container of the
411 insert_viewer_wrap(GtkWidget
*menuitem
, gpointer user_data
)
413 insert_viewer((GtkWidget
*)menuitem
, (lttvwindow_viewer_constructor
)user_data
);
417 /* internal functions */
418 void insert_viewer(GtkWidget
* widget
, lttvwindow_viewer_constructor constructor
)
420 GtkWidget
* viewer_container
;
421 MainWindow
* mw_data
= get_window_data_struct(widget
);
422 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
424 TimeInterval
* time_interval
;
425 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
426 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
431 ptab
= create_new_tab(widget
, NULL
);
433 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
437 viewer_container
= tab
->viewer_container
;
439 viewer
= (GtkWidget
*)constructor(ptab
);
442 //gtk_multivpaned_widget_add(GTK_MULTIVPANED(multivpaned), viewer);
444 gtk_box_pack_end(GTK_BOX(viewer_container
),
450 /* We want to connect the viewer_grab_focus to EVERY
451 * child of this widget. The little trick is to get each child
452 * of each GTK_CONTAINER, even subchildren.
454 connect_focus_recursive(viewer
, viewer
);
459 * Function to set/update traceset for the viewers
460 * @param tab viewer's tab
461 * @param traceset traceset of the main window.
463 * 0 : traceset updated
464 * 1 : no traceset hooks to update; not an error.
467 int SetTraceset(Tab
* tab
, LttvTraceset
*traceset
)
469 LttvTracesetContext
*tsc
=
470 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
473 TimeInterval time_span
= tsc
->time_span
;
474 TimeWindow new_time_window
= tab
->time_window
;
475 LttTime new_current_time
= tab
->current_time
;
477 /* Set the tab's time window and current time if
479 if(ltt_time_compare(tab
->time_window
.start_time
, time_span
.start_time
) < 0
480 || ltt_time_compare(tab
->time_window
.end_time
,
481 time_span
.end_time
) > 0) {
482 new_time_window
.start_time
= time_span
.start_time
;
484 new_current_time
= time_span
.start_time
;
488 if(ltt_time_compare(lttvwindow_default_time_width
,
489 ltt_time_sub(time_span
.end_time
, time_span
.start_time
)) < 0
491 ltt_time_compare(time_span
.end_time
, time_span
.start_time
) == 0)
492 tmp_time
= lttvwindow_default_time_width
;
494 tmp_time
= time_span
.end_time
;
496 new_time_window
.time_width
= tmp_time
;
497 new_time_window
.time_width_double
= ltt_time_to_double(tmp_time
);
498 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
499 new_time_window
.time_width
) ;
506 GtkAdjustment
*adjustment
= gtk_range_get_adjustment(GTK_RANGE(tab
->scrollbar
));
507 LttTime upper
= ltt_time_sub(time_span
.end_time
, time_span
.start_time
);
509 g_object_set(G_OBJECT(adjustment
),
513 ltt_time_to_double(upper
)
514 * NANOSECONDS_PER_SECOND
, /* upper */
516 ltt_time_to_double(tab
->time_window
.time_width
)
517 / SCROLL_STEP_PER_PAGE
518 * NANOSECONDS_PER_SECOND
, /* step increment */
520 ltt_time_to_double(tab
->time_window
.time_width
)
521 * NANOSECONDS_PER_SECOND
, /* page increment */
523 ltt_time_to_double(tab
->time_window
.time_width
)
524 * NANOSECONDS_PER_SECOND
, /* page size */
526 gtk_adjustment_changed(adjustment
);
528 g_object_set(G_OBJECT(adjustment
),
531 ltt_time_sub(tab
->time_window
.start_time
, time_span
.start_time
))
532 * NANOSECONDS_PER_SECOND
, /* value */
534 gtk_adjustment_value_changed(adjustment
);
536 /* set the time bar. The value callbacks will change their nsec themself */
538 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry1
),
539 (double)time_span
.start_time
.tv_sec
,
540 (double)time_span
.end_time
.tv_sec
);
543 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry3
),
544 (double)time_span
.start_time
.tv_sec
,
545 (double)time_span
.end_time
.tv_sec
);
547 /* current seconds */
548 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry5
),
549 (double)time_span
.start_time
.tv_sec
,
550 (double)time_span
.end_time
.tv_sec
);
553 /* Finally, call the update hooks of the viewers */
555 LttvAttributeValue value
;
558 retval
= lttv_iattribute_find_by_path(tab
->attributes
,
559 "hooks/updatetraceset", LTTV_POINTER
, &value
);
562 tmp
= (LttvHooks
*)*(value
.v_pointer
);
566 lttv_hooks_call(tmp
,traceset
);
568 time_change_manager(tab
, new_time_window
);
569 current_time_change_manager(tab
, new_current_time
);
575 * Function to set/update filter for the viewers
576 * @param tab viewer's tab
577 * @param filter filter of the main window.
580 * 0 : filters updated
581 * 1 : no filter hooks to update; not an error.
584 int SetFilter(Tab
* tab
, gpointer filter
)
587 LttvAttributeValue value
;
589 g_assert(lttv_iattribute_find_by_path(tab
->attributes
,
590 "hooks/updatefilter", LTTV_POINTER
, &value
));
592 tmp
= (LttvHooks
*)*(value
.v_pointer
);
594 if(tmp
== NULL
) return 1;
595 lttv_hooks_call(tmp
,filter
);
603 * Function to redraw each viewer belonging to the current tab
604 * @param tab viewer's tab
607 void update_traceset(Tab
*tab
)
609 LttvAttributeValue value
;
613 retval
= lttv_iattribute_find_by_path(tab
->attributes
,
614 "hooks/updatetraceset", LTTV_POINTER
, &value
);
616 tmp
= (LttvHooks
*)*(value
.v_pointer
);
617 if(tmp
== NULL
) return;
618 lttv_hooks_call(tmp
, NULL
);
622 /* get_label function is used to get user input, it displays an input
623 * box, which allows user to input a string
626 void get_label_string (GtkWidget
* text
, gchar
* label
)
628 GtkEntry
* entry
= (GtkEntry
*)text
;
629 if(strlen(gtk_entry_get_text(entry
))!=0)
630 strcpy(label
,gtk_entry_get_text(entry
));
633 gboolean
get_label(MainWindow
* mw
, gchar
* str
, gchar
* dialogue_title
, gchar
* label_str
)
635 GtkWidget
* dialogue
;
640 dialogue
= gtk_dialog_new_with_buttons(dialogue_title
,NULL
,
642 GTK_STOCK_OK
,GTK_RESPONSE_ACCEPT
,
643 GTK_STOCK_CANCEL
,GTK_RESPONSE_REJECT
,
646 label
= gtk_label_new(label_str
);
647 gtk_widget_show(label
);
649 text
= gtk_entry_new();
650 gtk_widget_show(text
);
652 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialogue
)->vbox
), label
,TRUE
, TRUE
,0);
653 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialogue
)->vbox
), text
,FALSE
, FALSE
,0);
655 id
= gtk_dialog_run(GTK_DIALOG(dialogue
));
657 case GTK_RESPONSE_ACCEPT
:
658 get_label_string(text
,str
);
659 gtk_widget_destroy(dialogue
);
661 case GTK_RESPONSE_REJECT
:
663 gtk_widget_destroy(dialogue
);
670 /* get_window_data_struct function is actually a lookup function,
671 * given a widget which is in the tree of the main window, it will
672 * return the MainWindow data structure associated with main window
675 MainWindow
* get_window_data_struct(GtkWidget
* widget
)
678 MainWindow
* mw_data
;
680 mw
= lookup_widget(widget
, "MWindow");
682 g_info("Main window does not exist\n");
686 mw_data
= (MainWindow
*) g_object_get_data(G_OBJECT(mw
),"main_window_data");
688 g_warning("Main window data does not exist\n");
695 /* create_new_window function, just constructs a new main window
698 void create_new_window(GtkWidget
* widget
, gpointer user_data
, gboolean clone
)
700 MainWindow
* parent
= get_window_data_struct(widget
);
703 g_info("Clone : use the same traceset\n");
704 construct_main_window(parent
);
706 g_info("Empty : traceset is set to NULL\n");
707 construct_main_window(NULL
);
711 /* Get the currently focused viewer.
712 * If no viewer is focused, use the first one.
714 * If no viewer available, return NULL.
716 GtkWidget
*viewer_container_focus(GtkWidget
*container
)
720 widget
= (GtkWidget
*)g_object_get_data(G_OBJECT(container
),
724 g_debug("no widget focused");
725 GList
*children
= gtk_container_get_children(GTK_CONTAINER(container
));
728 widget
= GTK_WIDGET(children
->data
);
729 g_object_set_data(G_OBJECT(container
),
739 gint
viewer_container_position(GtkWidget
*container
, GtkWidget
*child
)
742 if(child
== NULL
) return -1;
746 memset(&value
, 0, sizeof(GValue
));
747 g_value_init(&value
, G_TYPE_INT
);
748 gtk_container_child_get_property(GTK_CONTAINER(container
),
752 pos
= g_value_get_int(&value
);
758 /* move_*_viewer functions move the selected view up/down in
762 void move_down_viewer(GtkWidget
* widget
, gpointer user_data
)
764 MainWindow
* mw
= get_window_data_struct(widget
);
765 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
767 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
768 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
775 ptab
= g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
779 //gtk_multivpaned_widget_move_up(GTK_MULTIVPANED(tab->multivpaned));
781 /* change the position in the vbox */
782 GtkWidget
*focus_widget
;
784 focus_widget
= viewer_container_focus(tab
->viewer_container
);
785 position
= viewer_container_position(tab
->viewer_container
, focus_widget
);
788 /* can move up one position */
789 gtk_box_reorder_child(GTK_BOX(tab
->viewer_container
),
796 void move_up_viewer(GtkWidget
* widget
, gpointer user_data
)
798 MainWindow
* mw
= get_window_data_struct(widget
);
799 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
801 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
802 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
809 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
813 //gtk_multivpaned_widget_move_down(GTK_MULTIVPANED(tab->multivpaned));
814 /* change the position in the vbox */
815 GtkWidget
*focus_widget
;
817 focus_widget
= viewer_container_focus(tab
->viewer_container
);
818 position
= viewer_container_position(tab
->viewer_container
, focus_widget
);
822 g_list_length(gtk_container_get_children(
823 GTK_CONTAINER(tab
->viewer_container
)))-1
825 /* can move down one position */
826 gtk_box_reorder_child(GTK_BOX(tab
->viewer_container
),
834 /* delete_viewer deletes the selected viewer in the current tab
837 void delete_viewer(GtkWidget
* widget
, gpointer user_data
)
839 MainWindow
* mw
= get_window_data_struct(widget
);
840 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
842 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
843 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
850 ptab
= g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
854 //gtk_multivpaned_widget_delete(GTK_MULTIVPANED(tab->multivpaned));
856 GtkWidget
*focus_widget
= viewer_container_focus(tab
->viewer_container
);
858 if(focus_widget
!= NULL
)
859 gtk_widget_destroy(focus_widget
);
861 g_object_set_data(G_OBJECT(tab
->viewer_container
), "focused_viewer", NULL
);
865 /* open_traceset will open a traceset saved in a file
866 * Right now, it is not finished yet, (not working)
870 void open_traceset(GtkWidget
* widget
, gpointer user_data
)
874 LttvTraceset
* traceset
;
875 MainWindow
* mw_data
= get_window_data_struct(widget
);
876 GtkFileSelection
* file_selector
=
877 (GtkFileSelection
*)gtk_file_selection_new("Select a traceset");
879 gtk_file_selection_hide_fileop_buttons(file_selector
);
881 gtk_window_set_transient_for(GTK_WINDOW(file_selector
),
882 GTK_WINDOW(mw_data
->mwindow
));
884 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
886 case GTK_RESPONSE_ACCEPT
:
887 case GTK_RESPONSE_OK
:
888 dir
= gtk_file_selection_get_selections (file_selector
);
889 traceset
= lttv_traceset_load(dir
[0]);
890 g_info("Open a trace set %s\n", dir
[0]);
893 case GTK_RESPONSE_REJECT
:
894 case GTK_RESPONSE_CANCEL
:
896 gtk_widget_destroy((GtkWidget
*)file_selector
);
902 /* lttvwindow_process_pending_requests
904 * Process requests for parts of the trace from viewers.
906 * These requests are made by lttvwindow_events_request().
908 * This internal function gets called by g_idle, taking care of the pending
909 * requests. It is responsible for concatenation of time intervals and position
910 * requests. It does it with the following algorithm organizing process traceset
911 * calls. Here is the detailed description of the way it works :
913 * - Events Requests Servicing Algorithm
915 * Data structures necessary :
917 * List of requests added to context : list_in
918 * List of requests not added to context : list_out
923 * list_out : many events requests
925 * FIXME : insert rest of algorithm here
929 #define list_out tab->events_requests
931 gboolean
lttvwindow_process_pending_requests(Tab
*tab
)
934 LttvTracesetContext
*tsc
;
935 LttvTracefileContext
*tfc
;
936 GSList
*list_in
= NULL
;
940 LttvTracesetContextPosition
*end_position
;
942 if(lttvwindow_preempt_count
> 0) return TRUE
;
945 g_critical("Foreground processing : tab does not exist. Processing removed.");
949 /* There is no events requests pending : we should never have been called! */
950 g_assert(g_slist_length(list_out
) != 0);
952 tsc
= LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
954 //set the cursor to be X shape, indicating that the computer is busy in doing its job
956 new = gdk_cursor_new(GDK_X_CURSOR
);
957 widget
= lookup_widget(tab
->mw
->mwindow
, "MToolbar1");
958 win
= gtk_widget_get_parent_window(widget
);
959 gdk_window_set_cursor(win
, new);
960 gdk_cursor_unref(new);
961 gdk_window_stick(win
);
962 gdk_window_unstick(win
);
965 g_debug("SIZE events req len : %d", g_slist_length(list_out
));
967 /* Preliminary check for no trace in traceset */
968 /* Unregister the routine if empty, empty list_out too */
969 if(lttv_traceset_number(tsc
->ts
) == 0) {
971 /* - For each req in list_out */
972 GSList
*iter
= list_out
;
974 while(iter
!= NULL
) {
976 gboolean remove
= FALSE
;
977 gboolean free_data
= FALSE
;
978 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
980 /* - Call end request for req */
981 if(events_request
->servicing
== TRUE
)
982 lttv_hooks_call(events_request
->after_request
, (gpointer
)tsc
);
984 /* - remove req from list_out */
985 /* Destroy the request */
992 GSList
*remove_iter
= iter
;
994 iter
= g_slist_next(iter
);
995 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
996 list_out
= g_slist_remove_link(list_out
, remove_iter
);
997 } else { // not remove
998 iter
= g_slist_next(iter
);
1003 /* 0.1 Lock Traces */
1008 iter_trace
<lttv_traceset_number(tsc
->ts
);
1010 LttvTrace
*trace_v
= lttv_traceset_get(tsc
->ts
, iter_trace
);
1012 if(lttvwindowtraces_lock(trace_v
) != 0) {
1013 g_critical("Foreground processing : Unable to get trace lock");
1014 return TRUE
; /* Cannot get lock, try later */
1019 /* 0.2 Seek tracefiles positions to context position */
1020 //g_assert(lttv_process_traceset_seek_position(tsc, sync_position) == 0);
1021 lttv_process_traceset_synchronize_tracefiles(tsc
);
1024 /* Events processing algorithm implementation */
1025 /* Warning : the gtk_events_pending takes a LOT of cpu time. So what we do
1026 * instead is to leave the control to GTK and take it back.
1028 /* A. Servicing loop */
1029 //while( (g_slist_length(list_in) != 0 || g_slist_length(list_out) != 0)) {
1030 if((g_slist_length(list_in
) != 0 || g_slist_length(list_out
) != 0)) {
1032 /* 1. If list_in is empty (need a seek) */
1033 if( g_slist_length(list_in
) == 0 ) {
1035 /* list in is empty, need a seek */
1037 /* 1.1 Add requests to list_in */
1038 GSList
*ltime
= NULL
;
1039 GSList
*lpos
= NULL
;
1040 GSList
*iter
= NULL
;
1042 /* 1.1.1 Find all time requests with the lowest start time in list_out
1045 if(g_slist_length(list_out
) > 0)
1046 ltime
= g_slist_append(ltime
, g_slist_nth_data(list_out
, 0));
1047 for(iter
=g_slist_nth(list_out
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
1048 /* Find all time requests with the lowest start time in list_out */
1049 EventsRequest
*event_request_ltime
= (EventsRequest
*)g_slist_nth_data(ltime
, 0);
1050 EventsRequest
*event_request_list_out
= (EventsRequest
*)iter
->data
;
1053 comp
= ltt_time_compare(event_request_ltime
->start_time
,
1054 event_request_list_out
->start_time
);
1056 ltime
= g_slist_append(ltime
, event_request_list_out
);
1058 /* Remove all elements from ltime, and add current */
1059 while(ltime
!= NULL
)
1060 ltime
= g_slist_delete_link(ltime
, g_slist_nth(ltime
, 0));
1061 ltime
= g_slist_append(ltime
, event_request_list_out
);
1065 /* 1.1.2 Find all position requests with the lowest position in list_out
1068 if(g_slist_length(list_out
) > 0)
1069 lpos
= g_slist_append(lpos
, g_slist_nth_data(list_out
, 0));
1070 for(iter
=g_slist_nth(list_out
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
1071 /* Find all position requests with the lowest position in list_out */
1072 EventsRequest
*event_request_lpos
= (EventsRequest
*)g_slist_nth_data(lpos
, 0);
1073 EventsRequest
*event_request_list_out
= (EventsRequest
*)iter
->data
;
1076 if(event_request_lpos
->start_position
!= NULL
1077 && event_request_list_out
->start_position
!= NULL
)
1079 comp
= lttv_traceset_context_pos_pos_compare
1080 (event_request_lpos
->start_position
,
1081 event_request_list_out
->start_position
);
1086 lpos
= g_slist_append(lpos
, event_request_list_out
);
1088 /* Remove all elements from lpos, and add current */
1090 lpos
= g_slist_delete_link(lpos
, g_slist_nth(lpos
, 0));
1091 lpos
= g_slist_append(lpos
, event_request_list_out
);
1096 EventsRequest
*event_request_lpos
= (EventsRequest
*)g_slist_nth_data(lpos
, 0);
1097 EventsRequest
*event_request_ltime
= (EventsRequest
*)g_slist_nth_data(ltime
, 0);
1098 LttTime lpos_start_time
;
1100 if(event_request_lpos
!= NULL
1101 && event_request_lpos
->start_position
!= NULL
) {
1102 lpos_start_time
= lttv_traceset_context_position_get_time(
1103 event_request_lpos
->start_position
);
1106 /* 1.1.3 If lpos.start time < ltime */
1107 if(event_request_lpos
!= NULL
1108 && event_request_lpos
->start_position
!= NULL
1109 && ltt_time_compare(lpos_start_time
,
1110 event_request_ltime
->start_time
)<0) {
1111 /* Add lpos to list_in, remove them from list_out */
1112 for(iter
=lpos
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
1113 /* Add to list_in */
1114 EventsRequest
*event_request_lpos
=
1115 (EventsRequest
*)iter
->data
;
1117 list_in
= g_slist_append(list_in
, event_request_lpos
);
1118 /* Remove from list_out */
1119 list_out
= g_slist_remove(list_out
, event_request_lpos
);
1122 /* 1.1.4 (lpos.start time >= ltime) */
1123 /* Add ltime to list_in, remove them from list_out */
1125 for(iter
=ltime
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
1126 /* Add to list_in */
1127 EventsRequest
*event_request_ltime
=
1128 (EventsRequest
*)iter
->data
;
1130 list_in
= g_slist_append(list_in
, event_request_ltime
);
1131 /* Remove from list_out */
1132 list_out
= g_slist_remove(list_out
, event_request_ltime
);
1137 g_slist_free(ltime
);
1142 tfc
= lttv_traceset_context_get_current_tfc(tsc
);
1143 g_assert(g_slist_length(list_in
)>0);
1144 EventsRequest
*events_request
= g_slist_nth_data(list_in
, 0);
1147 /* 1.2.1 If first request in list_in is a time request */
1148 if(events_request
->start_position
== NULL
) {
1149 /* - If first req in list_in start time != current time */
1150 if(tfc
== NULL
|| ltt_time_compare(events_request
->start_time
,
1151 tfc
->timestamp
) != 0)
1152 /* - Seek to that time */
1153 g_debug("SEEK TIME : %lu, %lu", events_request
->start_time
.tv_sec
,
1154 events_request
->start_time
.tv_nsec
);
1155 //lttv_process_traceset_seek_time(tsc, events_request->start_time);
1156 lttv_state_traceset_seek_time_closest(LTTV_TRACESET_STATE(tsc
),
1157 events_request
->start_time
);
1159 /* Process the traceset with only state hooks */
1161 lttv_process_traceset_middle(tsc
,
1162 events_request
->start_time
,
1165 g_assert(seek_count
< LTTV_STATE_SAVE_INTERVAL
);
1171 LttvTracefileContext
*tfc
=
1172 lttv_traceset_context_get_current_tfc(tsc
);
1173 /* Else, the first request in list_in is a position request */
1174 /* If first req in list_in pos != current pos */
1175 g_assert(events_request
->start_position
!= NULL
);
1176 g_debug("SEEK POS time : %lu, %lu",
1177 lttv_traceset_context_position_get_time(
1178 events_request
->start_position
).tv_sec
,
1179 lttv_traceset_context_position_get_time(
1180 events_request
->start_position
).tv_nsec
);
1183 g_debug("SEEK POS context time : %lu, %lu",
1184 tfc
->timestamp
.tv_sec
,
1185 tfc
->timestamp
.tv_nsec
);
1187 g_debug("SEEK POS context time : %lu, %lu",
1188 ltt_time_infinite
.tv_sec
,
1189 ltt_time_infinite
.tv_nsec
);
1191 g_assert(events_request
->start_position
!= NULL
);
1192 if(lttv_traceset_context_ctx_pos_compare(tsc
,
1193 events_request
->start_position
) != 0) {
1194 /* 1.2.2.1 Seek to that position */
1195 g_debug("SEEK POSITION");
1196 //lttv_process_traceset_seek_position(tsc, events_request->start_position);
1197 pos_time
= lttv_traceset_context_position_get_time(
1198 events_request
->start_position
);
1200 lttv_state_traceset_seek_time_closest(LTTV_TRACESET_STATE(tsc
),
1203 /* Process the traceset with only state hooks */
1205 lttv_process_traceset_middle(tsc
,
1208 events_request
->start_position
);
1209 g_assert(lttv_traceset_context_ctx_pos_compare(tsc
,
1210 events_request
->start_position
) == 0);
1217 /* 1.3 Add hooks and call before request for all list_in members */
1219 GSList
*iter
= NULL
;
1221 for(iter
=list_in
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
1222 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1223 /* 1.3.1 If !servicing */
1224 if(events_request
->servicing
== FALSE
) {
1225 /* - begin request hooks called
1226 * - servicing = TRUE
1228 lttv_hooks_call(events_request
->before_request
, (gpointer
)tsc
);
1229 events_request
->servicing
= TRUE
;
1231 /* 1.3.2 call before chunk
1232 * 1.3.3 events hooks added
1234 if(events_request
->trace
== -1)
1235 lttv_process_traceset_begin(tsc
,
1236 events_request
->before_chunk_traceset
,
1237 events_request
->before_chunk_trace
,
1238 events_request
->before_chunk_tracefile
,
1239 events_request
->event
,
1240 events_request
->event_by_id_channel
);
1242 guint nb_trace
= lttv_traceset_number(tsc
->ts
);
1243 g_assert((guint
)events_request
->trace
< nb_trace
&&
1244 events_request
->trace
> -1);
1245 LttvTraceContext
*tc
= tsc
->traces
[events_request
->trace
];
1247 lttv_hooks_call(events_request
->before_chunk_traceset
, tsc
);
1249 lttv_trace_context_add_hooks(tc
,
1250 events_request
->before_chunk_trace
,
1251 events_request
->before_chunk_tracefile
,
1252 events_request
->event
,
1253 events_request
->event_by_id_channel
);
1258 /* 2. Else, list_in is not empty, we continue a read */
1261 /* 2.0 For each req of list_in */
1262 GSList
*iter
= list_in
;
1264 while(iter
!= NULL
) {
1266 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1268 /* - Call before chunk
1269 * - events hooks added
1271 if(events_request
->trace
== -1)
1272 lttv_process_traceset_begin(tsc
,
1273 events_request
->before_chunk_traceset
,
1274 events_request
->before_chunk_trace
,
1275 events_request
->before_chunk_tracefile
,
1276 events_request
->event
,
1277 events_request
->event_by_id_channel
);
1279 guint nb_trace
= lttv_traceset_number(tsc
->ts
);
1280 g_assert((guint
)events_request
->trace
< nb_trace
&&
1281 events_request
->trace
> -1);
1282 LttvTraceContext
*tc
= tsc
->traces
[events_request
->trace
];
1284 lttv_hooks_call(events_request
->before_chunk_traceset
, tsc
);
1286 lttv_trace_context_add_hooks(tc
,
1287 events_request
->before_chunk_trace
,
1288 events_request
->before_chunk_tracefile
,
1289 events_request
->event
,
1290 events_request
->event_by_id_channel
);
1293 iter
= g_slist_next(iter
);
1298 tfc
= lttv_traceset_context_get_current_tfc(tsc
);
1300 /* 2.1 For each req of list_out */
1301 GSList
*iter
= list_out
;
1303 while(iter
!= NULL
) {
1305 gboolean remove
= FALSE
;
1306 gboolean free_data
= FALSE
;
1307 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1309 /* if req.start time == current context time
1310 * or req.start position == current position*/
1311 if( ltt_time_compare(events_request
->start_time
,
1312 tfc
->timestamp
) == 0
1314 (events_request
->start_position
!= NULL
1316 lttv_traceset_context_ctx_pos_compare(tsc
,
1317 events_request
->start_position
) == 0)
1319 /* - Add to list_in, remove from list_out */
1320 list_in
= g_slist_append(list_in
, events_request
);
1324 /* - If !servicing */
1325 if(events_request
->servicing
== FALSE
) {
1326 /* - begin request hooks called
1327 * - servicing = TRUE
1329 lttv_hooks_call(events_request
->before_request
, (gpointer
)tsc
);
1330 events_request
->servicing
= TRUE
;
1332 /* call before chunk
1333 * events hooks added
1335 if(events_request
->trace
== -1)
1336 lttv_process_traceset_begin(tsc
,
1337 events_request
->before_chunk_traceset
,
1338 events_request
->before_chunk_trace
,
1339 events_request
->before_chunk_tracefile
,
1340 events_request
->event
,
1341 events_request
->event_by_id_channel
);
1343 guint nb_trace
= lttv_traceset_number(tsc
->ts
);
1344 g_assert((guint
)events_request
->trace
< nb_trace
&&
1345 events_request
->trace
> -1);
1346 LttvTraceContext
*tc
= tsc
->traces
[events_request
->trace
];
1348 lttv_hooks_call(events_request
->before_chunk_traceset
, tsc
);
1350 lttv_trace_context_add_hooks(tc
,
1351 events_request
->before_chunk_trace
,
1352 events_request
->before_chunk_tracefile
,
1353 events_request
->event
,
1354 events_request
->event_by_id_channel
);
1363 GSList
*remove_iter
= iter
;
1365 iter
= g_slist_next(iter
);
1366 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
1367 list_out
= g_slist_remove_link(list_out
, remove_iter
);
1368 } else { // not remove
1369 iter
= g_slist_next(iter
);
1375 /* 3. Find end criterions */
1380 /* 3.1.1 Find lowest end time in list_in */
1381 g_assert(g_slist_length(list_in
)>0);
1382 end_time
= ((EventsRequest
*)g_slist_nth_data(list_in
,0))->end_time
;
1384 for(iter
=g_slist_nth(list_in
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
1385 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1387 if(ltt_time_compare(events_request
->end_time
,
1389 end_time
= events_request
->end_time
;
1392 /* 3.1.2 Find lowest start time in list_out */
1393 for(iter
=list_out
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
1394 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1396 if(ltt_time_compare(events_request
->start_time
,
1398 end_time
= events_request
->start_time
;
1403 /* 3.2 Number of events */
1405 /* 3.2.1 Find lowest number of events in list_in */
1408 end_nb_events
= ((EventsRequest
*)g_slist_nth_data(list_in
,0))->num_events
;
1410 for(iter
=g_slist_nth(list_in
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
1411 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1413 if(events_request
->num_events
< end_nb_events
)
1414 end_nb_events
= events_request
->num_events
;
1417 /* 3.2.2 Use min(CHUNK_NUM_EVENTS, min num events in list_in) as
1420 end_nb_events
= MIN(CHUNK_NUM_EVENTS
, end_nb_events
);
1424 /* 3.3 End position */
1426 /* 3.3.1 Find lowest end position in list_in */
1429 end_position
=((EventsRequest
*)g_slist_nth_data(list_in
,0))->end_position
;
1431 for(iter
=g_slist_nth(list_in
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
1432 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1434 if(events_request
->end_position
!= NULL
&& end_position
!= NULL
&&
1435 lttv_traceset_context_pos_pos_compare(events_request
->end_position
,
1437 end_position
= events_request
->end_position
;
1442 /* 3.3.2 Find lowest start position in list_out */
1445 for(iter
=list_out
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
1446 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1448 if(events_request
->end_position
!= NULL
&& end_position
!= NULL
&&
1449 lttv_traceset_context_pos_pos_compare(events_request
->end_position
,
1451 end_position
= events_request
->end_position
;
1456 /* 4. Call process traceset middle */
1457 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
);
1458 count
= lttv_process_traceset_middle(tsc
, end_time
, end_nb_events
, end_position
);
1460 tfc
= lttv_traceset_context_get_current_tfc(tsc
);
1462 g_debug("Context time after middle : %lu, %lu", tfc
->timestamp
.tv_sec
,
1463 tfc
->timestamp
.tv_nsec
);
1465 g_debug("End of trace reached after middle.");
1469 /* 5. After process traceset middle */
1470 tfc
= lttv_traceset_context_get_current_tfc(tsc
);
1472 /* - if current context time > traceset.end time */
1473 if(tfc
== NULL
|| ltt_time_compare(tfc
->timestamp
,
1474 tsc
->time_span
.end_time
) > 0) {
1475 /* - For each req in list_in */
1476 GSList
*iter
= list_in
;
1478 while(iter
!= NULL
) {
1480 gboolean remove
= FALSE
;
1481 gboolean free_data
= FALSE
;
1482 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1484 /* - Remove events hooks for req
1485 * - Call end chunk for req
1488 if(events_request
->trace
== -1)
1489 lttv_process_traceset_end(tsc
,
1490 events_request
->after_chunk_traceset
,
1491 events_request
->after_chunk_trace
,
1492 events_request
->after_chunk_tracefile
,
1493 events_request
->event
,
1494 events_request
->event_by_id_channel
);
1497 guint nb_trace
= lttv_traceset_number(tsc
->ts
);
1498 g_assert(events_request
->trace
< nb_trace
&&
1499 events_request
->trace
> -1);
1500 LttvTraceContext
*tc
= tsc
->traces
[events_request
->trace
];
1502 lttv_trace_context_remove_hooks(tc
,
1503 events_request
->after_chunk_trace
,
1504 events_request
->after_chunk_tracefile
,
1505 events_request
->event
,
1506 events_request
->event_by_id_channel
);
1507 lttv_hooks_call(events_request
->after_chunk_traceset
, tsc
);
1512 /* - Call end request for req */
1513 lttv_hooks_call(events_request
->after_request
, (gpointer
)tsc
);
1515 /* - remove req from list_in */
1516 /* Destroy the request */
1523 GSList
*remove_iter
= iter
;
1525 iter
= g_slist_next(iter
);
1526 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
1527 list_in
= g_slist_remove_link(list_in
, remove_iter
);
1528 } else { // not remove
1529 iter
= g_slist_next(iter
);
1534 /* 5.1 For each req in list_in */
1535 GSList
*iter
= list_in
;
1537 while(iter
!= NULL
) {
1539 gboolean remove
= FALSE
;
1540 gboolean free_data
= FALSE
;
1541 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1543 /* - Remove events hooks for req
1544 * - Call end chunk for req
1546 if(events_request
->trace
== -1)
1547 lttv_process_traceset_end(tsc
,
1548 events_request
->after_chunk_traceset
,
1549 events_request
->after_chunk_trace
,
1550 events_request
->after_chunk_tracefile
,
1551 events_request
->event
,
1552 events_request
->event_by_id_channel
);
1555 guint nb_trace
= lttv_traceset_number(tsc
->ts
);
1556 g_assert(events_request
->trace
< nb_trace
&&
1557 events_request
->trace
> -1);
1558 LttvTraceContext
*tc
= tsc
->traces
[events_request
->trace
];
1560 lttv_trace_context_remove_hooks(tc
,
1561 events_request
->after_chunk_trace
,
1562 events_request
->after_chunk_tracefile
,
1563 events_request
->event
,
1564 events_request
->event_by_id_channel
);
1566 lttv_hooks_call(events_request
->after_chunk_traceset
, tsc
);
1569 /* - req.num -= count */
1570 g_assert(events_request
->num_events
>= count
);
1571 events_request
->num_events
-= count
;
1573 g_assert(tfc
!= NULL
);
1574 /* - if req.num == 0
1576 * current context time >= req.end time
1578 * req.end pos == current pos
1580 * req.stop_flag == TRUE
1582 if( events_request
->num_events
== 0
1584 events_request
->stop_flag
== TRUE
1586 ltt_time_compare(tfc
->timestamp
,
1587 events_request
->end_time
) >= 0
1589 (events_request
->end_position
!= NULL
1591 lttv_traceset_context_ctx_pos_compare(tsc
,
1592 events_request
->end_position
) == 0)
1595 g_assert(events_request
->servicing
== TRUE
);
1596 /* - Call end request for req
1597 * - remove req from list_in */
1598 lttv_hooks_call(events_request
->after_request
, (gpointer
)tsc
);
1599 /* - remove req from list_in */
1600 /* Destroy the request */
1608 GSList
*remove_iter
= iter
;
1610 iter
= g_slist_next(iter
);
1611 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
1612 list_in
= g_slist_remove_link(list_in
, remove_iter
);
1613 } else { // not remove
1614 iter
= g_slist_next(iter
);
1620 /* End of removed servicing loop : leave control to GTK instead. */
1621 // if(gtk_events_pending()) break;
1624 /* B. When interrupted between chunks */
1627 GSList
*iter
= list_in
;
1629 /* 1. for each request in list_in */
1630 while(iter
!= NULL
) {
1632 gboolean remove
= FALSE
;
1633 gboolean free_data
= FALSE
;
1634 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1636 /* 1.1. Use current postition as start position */
1637 if(events_request
->start_position
!= NULL
)
1638 lttv_traceset_context_position_destroy(events_request
->start_position
);
1639 events_request
->start_position
= lttv_traceset_context_position_new(tsc
);
1640 lttv_traceset_context_position_save(tsc
, events_request
->start_position
);
1642 /* 1.2. Remove start time */
1643 events_request
->start_time
= ltt_time_infinite
;
1645 /* 1.3. Move from list_in to list_out */
1648 list_out
= g_slist_append(list_out
, events_request
);
1653 GSList
*remove_iter
= iter
;
1655 iter
= g_slist_next(iter
);
1656 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
1657 list_in
= g_slist_remove_link(list_in
, remove_iter
);
1658 } else { // not remove
1659 iter
= g_slist_next(iter
);
1665 /* C Unlock Traces */
1667 lttv_process_traceset_get_sync_data(tsc
);
1668 //lttv_traceset_context_position_save(tsc, sync_position);
1673 iter_trace
<lttv_traceset_number(tsc
->ts
);
1675 LttvTrace
*trace_v
= lttv_traceset_get(tsc
->ts
, iter_trace
);
1677 lttvwindowtraces_unlock(trace_v
);
1681 //set the cursor back to normal
1682 gdk_window_set_cursor(win
, NULL
);
1685 g_assert(g_slist_length(list_in
) == 0);
1687 if( g_slist_length(list_out
) == 0 ) {
1688 /* Put tab's request pending flag back to normal */
1689 tab
->events_request_pending
= FALSE
;
1690 g_debug("remove the idle fct");
1691 return FALSE
; /* Remove the idle function */
1693 g_debug("leave the idle fct");
1694 return TRUE
; /* Leave the idle function */
1696 /* We do not use simili-round-robin, it may require to read 1 meg buffers
1697 * again and again if many tracesets use the same tracefiles. */
1698 /* Hack for round-robin idle functions */
1699 /* It will put the idle function at the end of the pool */
1700 /*g_idle_add_full((G_PRIORITY_HIGH_IDLE + 21),
1701 (GSourceFunc)execute_events_requests,
1711 static void lttvwindow_add_trace(Tab
*tab
, LttvTrace
*trace_v
)
1713 LttvTraceset
*traceset
= tab
->traceset_info
->traceset
;
1715 guint num_traces
= lttv_traceset_number(traceset
);
1717 //Verify if trace is already present.
1718 for(i
=0; i
<num_traces
; i
++)
1720 LttvTrace
* trace
= lttv_traceset_get(traceset
, i
);
1721 if(trace
== trace_v
)
1725 //Keep a reference to the traces so they are not freed.
1726 for(i
=0; i
<lttv_traceset_number(traceset
); i
++)
1728 LttvTrace
* trace
= lttv_traceset_get(traceset
, i
);
1729 lttv_trace_ref(trace
);
1732 //remove state update hooks
1733 lttv_state_remove_event_hooks(
1734 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1736 lttv_context_fini(LTTV_TRACESET_CONTEXT(
1737 tab
->traceset_info
->traceset_context
));
1738 g_object_unref(tab
->traceset_info
->traceset_context
);
1740 lttv_traceset_add(traceset
, trace_v
);
1741 lttv_trace_ref(trace_v
); /* local ref */
1743 /* Create new context */
1744 tab
->traceset_info
->traceset_context
=
1745 g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
1747 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->
1752 //add state update hooks
1753 lttv_state_add_event_hooks(
1754 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1755 //Remove local reference to the traces.
1756 for(i
=0; i
<lttv_traceset_number(traceset
); i
++)
1758 LttvTrace
* trace
= lttv_traceset_get(traceset
, i
);
1759 lttv_trace_unref(trace
);
1763 //add_trace_into_traceset_selector(GTK_MULTIVPANED(tab->multivpaned), lttv_trace(trace_v));
1766 /* add_trace adds a trace into the current traceset. It first displays a
1767 * directory selection dialogue to let user choose a trace, then recreates
1768 * tracset_context, and redraws all the viewer of the current tab
1771 void add_trace(GtkWidget
* widget
, gpointer user_data
)
1774 LttvTrace
* trace_v
;
1775 LttvTraceset
* traceset
;
1777 char abs_path
[PATH_MAX
];
1779 MainWindow
* mw_data
= get_window_data_struct(widget
);
1780 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
1782 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
1783 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
1784 LttvPluginTab
*ptab
;
1788 ptab
= create_new_tab(widget
, NULL
);
1791 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
1795 //GtkDirSelection * file_selector = (GtkDirSelection *)gtk_dir_selection_new("Select a trace");
1796 GtkFileSelection
* file_selector
= (GtkFileSelection
*)gtk_file_selection_new("Select a trace");
1797 gtk_widget_hide( (file_selector
)->file_list
->parent
) ;
1798 gtk_file_selection_hide_fileop_buttons(file_selector
);
1799 gtk_window_set_transient_for(GTK_WINDOW(file_selector
),
1800 GTK_WINDOW(mw_data
->mwindow
));
1802 if(remember_trace_dir
[0] != '\0')
1803 gtk_file_selection_set_filename(file_selector
, remember_trace_dir
);
1805 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
1807 case GTK_RESPONSE_ACCEPT
:
1808 case GTK_RESPONSE_OK
:
1809 dir
= gtk_file_selection_get_filename (file_selector
);
1810 strncpy(remember_trace_dir
, dir
, PATH_MAX
);
1811 strncat(remember_trace_dir
, "/", PATH_MAX
);
1812 if(!dir
|| strlen(dir
) == 0){
1813 gtk_widget_destroy((GtkWidget
*)file_selector
);
1816 get_absolute_pathname(dir
, abs_path
);
1817 trace_v
= lttvwindowtraces_get_trace_by_name(abs_path
);
1818 if(trace_v
== NULL
) {
1819 trace
= ltt_trace_open(abs_path
);
1821 g_warning("cannot open trace %s", abs_path
);
1823 GtkWidget
*dialogue
=
1824 gtk_message_dialog_new(
1825 GTK_WINDOW(gtk_widget_get_toplevel(widget
)),
1826 GTK_DIALOG_MODAL
|GTK_DIALOG_DESTROY_WITH_PARENT
,
1829 "Cannot open trace : maybe you should enter in the trace "
1830 "directory to select it ?");
1831 gtk_dialog_run(GTK_DIALOG(dialogue
));
1832 gtk_widget_destroy(dialogue
);
1835 trace_v
= lttv_trace_new(trace
);
1836 lttvwindowtraces_add_trace(trace_v
);
1837 lttvwindow_add_trace(tab
, trace_v
);
1840 lttvwindow_add_trace(tab
, trace_v
);
1843 gtk_widget_destroy((GtkWidget
*)file_selector
);
1845 //update current tab
1846 //update_traceset(mw_data);
1848 /* Call the updatetraceset hooks */
1850 traceset
= tab
->traceset_info
->traceset
;
1851 SetTraceset(tab
, traceset
);
1852 // in expose now call_pending_read_hooks(mw_data);
1854 //lttvwindow_report_current_time(mw_data,&(tab->current_time));
1856 case GTK_RESPONSE_REJECT
:
1857 case GTK_RESPONSE_CANCEL
:
1859 gtk_widget_destroy((GtkWidget
*)file_selector
);
1864 /* remove_trace removes a trace from the current traceset if all viewers in
1865 * the current tab are not interested in the trace. It first displays a
1866 * dialogue, which shows all traces in the current traceset, to let user choose
1867 * a trace, then it checks if all viewers unselect the trace, if it is true,
1868 * it will remove the trace, recreate the traceset_contex,
1869 * and redraws all the viewer of the current tab. If there is on trace in the
1870 * current traceset, it will delete all viewers of the current tab
1872 * It destroys the filter tree. FIXME... we should request for an update
1876 void remove_trace(GtkWidget
*widget
, gpointer user_data
)
1879 LttvTrace
* trace_v
;
1880 LttvTraceset
* traceset
;
1881 gint i
, j
, nb_trace
, index
=-1;
1882 char ** name
, *remove_trace_name
;
1883 MainWindow
* mw_data
= get_window_data_struct(widget
);
1884 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
1886 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
1887 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
1893 LttvPluginTab
*ptab
;
1894 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
1898 nb_trace
=lttv_traceset_number(tab
->traceset_info
->traceset
);
1899 name
= g_new(char*,nb_trace
);
1900 for(i
= 0; i
< nb_trace
; i
++){
1901 trace_v
= lttv_traceset_get(tab
->traceset_info
->traceset
, i
);
1902 trace
= lttv_trace(trace_v
);
1903 name
[i
] = g_quark_to_string(ltt_trace_name(trace
));
1906 remove_trace_name
= get_remove_trace(mw_data
, name
, nb_trace
);
1909 if(remove_trace_name
){
1911 /* yuk, cut n paste from old code.. should be better (MD)*/
1912 for(i
= 0; i
<nb_trace
; i
++) {
1913 if(strcmp(remove_trace_name
,name
[i
]) == 0){
1918 traceset
= tab
->traceset_info
->traceset
;
1919 //Keep a reference to the traces so they are not freed.
1920 for(j
=0; j
<lttv_traceset_number(traceset
); j
++)
1922 LttvTrace
* trace
= lttv_traceset_get(traceset
, j
);
1923 lttv_trace_ref(trace
);
1926 //remove state update hooks
1927 lttv_state_remove_event_hooks(
1928 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1929 lttv_context_fini(LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
));
1930 g_object_unref(tab
->traceset_info
->traceset_context
);
1932 trace_v
= lttv_traceset_get(traceset
, index
);
1934 lttv_traceset_remove(traceset
, index
);
1935 lttv_trace_unref(trace_v
); // Remove local reference
1937 if(lttv_trace_get_ref_number(trace_v
) <= 1) {
1938 /* ref 1 : lttvwindowtraces only*/
1939 ltt_trace_close(lttv_trace(trace_v
));
1940 /* lttvwindowtraces_remove_trace takes care of destroying
1941 * the traceset linked with the trace_v and also of destroying
1942 * the trace_v at the same time.
1944 lttvwindowtraces_remove_trace(trace_v
);
1947 tab
->traceset_info
->traceset_context
=
1948 g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
1950 LTTV_TRACESET_CONTEXT(tab
->
1951 traceset_info
->traceset_context
),traceset
);
1952 //add state update hooks
1953 lttv_state_add_event_hooks(
1954 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1956 //Remove local reference to the traces.
1957 for(j
=0; j
<lttv_traceset_number(traceset
); j
++)
1959 LttvTrace
* trace
= lttv_traceset_get(traceset
, j
);
1960 lttv_trace_unref(trace
);
1963 SetTraceset(tab
, (gpointer
)traceset
);
1969 void remove_trace(GtkWidget
* widget
, gpointer user_data
)
1972 LttvTrace
* trace_v
;
1973 LttvTraceset
* traceset
;
1974 gint i
, j
, nb_trace
;
1975 char ** name
, *remove_trace_name
;
1976 MainWindow
* mw_data
= get_window_data_struct(widget
);
1977 LttvTracesetSelector
* s
;
1978 LttvTraceSelector
* t
;
1981 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
1983 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
1984 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
1990 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
1993 nb_trace
=lttv_traceset_number(tab
->traceset_info
->traceset
);
1994 name
= g_new(char*,nb_trace
);
1995 for(i
= 0; i
< nb_trace
; i
++){
1996 trace_v
= lttv_traceset_get(tab
->traceset_info
->traceset
, i
);
1997 trace
= lttv_trace(trace_v
);
1998 name
[i
] = ltt_trace_name(trace
);
2001 remove_trace_name
= get_remove_trace(name
, nb_trace
);
2003 if(remove_trace_name
){
2004 for(i
=0; i
<nb_trace
; i
++){
2005 if(strcmp(remove_trace_name
,name
[i
]) == 0){
2006 //unselect the trace from the current viewer
2008 w
= gtk_multivpaned_get_widget(GTK_MULTIVPANED(tab
->multivpaned
));
2010 s
= g_object_get_data(G_OBJECT(w
), "Traceset_Selector");
2012 t
= lttv_traceset_selector_trace_get(s
,i
);
2013 lttv_trace_selector_set_selected(t
, FALSE
);
2016 //check if other viewers select the trace
2017 w
= gtk_multivpaned_get_first_widget(GTK_MULTIVPANED(tab
->multivpaned
));
2019 s
= g_object_get_data(G_OBJECT(w
), "Traceset_Selector");
2021 t
= lttv_traceset_selector_trace_get(s
,i
);
2022 selected
= lttv_trace_selector_get_selected(t
);
2025 w
= gtk_multivpaned_get_next_widget(GTK_MULTIVPANED(tab
->multivpaned
));
2027 }else selected
= FALSE
;
2029 //if no viewer selects the trace, remove it
2031 remove_trace_from_traceset_selector(GTK_MULTIVPANED(tab
->multivpaned
), i
);
2033 traceset
= tab
->traceset_info
->traceset
;
2034 //Keep a reference to the traces so they are not freed.
2035 for(j
=0; j
<lttv_traceset_number(traceset
); j
++)
2037 LttvTrace
* trace
= lttv_traceset_get(traceset
, j
);
2038 lttv_trace_ref(trace
);
2041 //remove state update hooks
2042 lttv_state_remove_event_hooks(
2043 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
2044 lttv_context_fini(LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
));
2045 g_object_unref(tab
->traceset_info
->traceset_context
);
2048 trace_v
= lttv_traceset_get(traceset
, i
);
2050 if(lttv_trace_get_ref_number(trace_v
) <= 2) {
2051 /* ref 2 : traceset, local */
2052 lttvwindowtraces_remove_trace(trace_v
);
2053 ltt_trace_close(lttv_trace(trace_v
));
2056 lttv_traceset_remove(traceset
, i
);
2057 lttv_trace_unref(trace_v
); // Remove local reference
2059 if(!lttv_trace_get_ref_number(trace_v
))
2060 lttv_trace_destroy(trace_v
);
2062 tab
->traceset_info
->traceset_context
=
2063 g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
2065 LTTV_TRACESET_CONTEXT(tab
->
2066 traceset_info
->traceset_context
),traceset
);
2067 //add state update hooks
2068 lttv_state_add_event_hooks(
2069 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
2071 //Remove local reference to the traces.
2072 for(j
=0; j
<lttv_traceset_number(traceset
); j
++)
2074 LttvTrace
* trace
= lttv_traceset_get(traceset
, j
);
2075 lttv_trace_unref(trace
);
2079 //update current tab
2080 //update_traceset(mw_data);
2083 SetTraceset(tab
, (gpointer
)traceset
);
2084 // in expose now call_pending_read_hooks(mw_data);
2086 //lttvwindow_report_current_time(mw_data,&(tab->current_time));
2089 // while(tab->multi_vpaned->num_children){
2090 // gtk_multi_vpaned_widget_delete(tab->multi_vpaned);
2104 /* Redraw all the viewers in the current tab */
2105 void redraw(GtkWidget
*widget
, gpointer user_data
)
2107 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
2108 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2109 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2116 LttvPluginTab
*ptab
;
2117 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
2122 LttvAttributeValue value
;
2124 retval
= lttv_iattribute_find_by_path(tab
->attributes
, "hooks/redraw", LTTV_POINTER
, &value
);
2127 tmp
= (LttvHooks
*)*(value
.v_pointer
);
2129 lttv_hooks_call(tmp
,NULL
);
2133 void continue_processing(GtkWidget
*widget
, gpointer user_data
)
2135 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
2136 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2137 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2144 LttvPluginTab
*ptab
;
2145 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
2150 LttvAttributeValue value
;
2152 retval
= lttv_iattribute_find_by_path(tab
->attributes
, "hooks/continue",
2153 LTTV_POINTER
, &value
);
2156 tmp
= (LttvHooks
*)*(value
.v_pointer
);
2158 lttv_hooks_call(tmp
,NULL
);
2161 /* Stop the processing for the calling main window's current tab.
2162 * It removes every processing requests that are in its list. It does not call
2163 * the end request hooks, because the request is not finished.
2166 void stop_processing(GtkWidget
*widget
, gpointer user_data
)
2168 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
2169 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2170 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2175 LttvPluginTab
*ptab
;
2176 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
2179 GSList
*iter
= tab
->events_requests
;
2181 while(iter
!= NULL
) {
2182 GSList
*remove_iter
= iter
;
2183 iter
= g_slist_next(iter
);
2185 g_free(remove_iter
->data
);
2186 tab
->events_requests
=
2187 g_slist_remove_link(tab
->events_requests
, remove_iter
);
2189 tab
->events_request_pending
= FALSE
;
2190 tab
->stop_foreground
= TRUE
;
2191 g_idle_remove_by_data(tab
);
2192 g_assert(g_slist_length(tab
->events_requests
) == 0);
2196 /* save will save the traceset to a file
2197 * Not implemented yet FIXME
2200 void save(GtkWidget
* widget
, gpointer user_data
)
2205 void save_as(GtkWidget
* widget
, gpointer user_data
)
2207 g_info("Save as\n");
2211 /* zoom will change the time_window of all the viewers of the
2212 * current tab, and redisplay them. The main functionality is to
2213 * determine the new time_window of the current tab
2216 void zoom(GtkWidget
* widget
, double size
)
2218 TimeInterval time_span
;
2219 TimeWindow new_time_window
;
2220 LttTime current_time
, time_delta
;
2221 MainWindow
* mw_data
= get_window_data_struct(widget
);
2222 LttvTracesetContext
*tsc
;
2223 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
2225 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2226 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2232 LttvPluginTab
*ptab
;
2233 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
2237 if(size
== 1) return;
2239 tsc
= LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
2240 time_span
= tsc
->time_span
;
2241 new_time_window
= tab
->time_window
;
2242 current_time
= tab
->current_time
;
2244 time_delta
= ltt_time_sub(time_span
.end_time
,time_span
.start_time
);
2246 new_time_window
.start_time
= time_span
.start_time
;
2247 new_time_window
.time_width
= time_delta
;
2248 new_time_window
.time_width_double
= ltt_time_to_double(time_delta
);
2249 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
2250 new_time_window
.time_width
) ;
2252 new_time_window
.time_width
= ltt_time_div(new_time_window
.time_width
, size
);
2253 new_time_window
.time_width_double
=
2254 ltt_time_to_double(new_time_window
.time_width
);
2255 if(ltt_time_compare(new_time_window
.time_width
,time_delta
) > 0)
2256 { /* Case where zoom out is bigger than trace length */
2257 new_time_window
.start_time
= time_span
.start_time
;
2258 new_time_window
.time_width
= time_delta
;
2259 new_time_window
.time_width_double
= ltt_time_to_double(time_delta
);
2260 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
2261 new_time_window
.time_width
) ;
2265 /* Center the image on the current time */
2266 new_time_window
.start_time
=
2267 ltt_time_sub(current_time
,
2268 ltt_time_from_double(new_time_window
.time_width_double
/2.0));
2269 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
2270 new_time_window
.time_width
) ;
2271 /* If on borders, don't fall off */
2272 if(ltt_time_compare(new_time_window
.start_time
, time_span
.start_time
) <0
2273 || ltt_time_compare(new_time_window
.start_time
, time_span
.end_time
) >0)
2275 new_time_window
.start_time
= time_span
.start_time
;
2276 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
2277 new_time_window
.time_width
) ;
2281 if(ltt_time_compare(new_time_window
.end_time
,
2282 time_span
.end_time
) > 0
2283 || ltt_time_compare(new_time_window
.end_time
,
2284 time_span
.start_time
) < 0)
2286 new_time_window
.start_time
=
2287 ltt_time_sub(time_span
.end_time
, new_time_window
.time_width
);
2289 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
2290 new_time_window
.time_width
) ;
2297 if(ltt_time_compare(new_time_window
.time_width
, ltt_time_zero
) == 0) {
2298 g_warning("Zoom more than 1 ns impossible");
2300 time_change_manager(tab
, new_time_window
);
2304 void zoom_in(GtkWidget
* widget
, gpointer user_data
)
2309 void zoom_out(GtkWidget
* widget
, gpointer user_data
)
2314 void zoom_extended(GtkWidget
* widget
, gpointer user_data
)
2319 void go_to_time(GtkWidget
* widget
, gpointer user_data
)
2321 g_info("Go to time\n");
2324 void show_time_frame(GtkWidget
* widget
, gpointer user_data
)
2326 g_info("Show time frame\n");
2330 /* callback function */
2333 on_empty_traceset_activate (GtkMenuItem
*menuitem
,
2336 create_new_window((GtkWidget
*)menuitem
, user_data
, FALSE
);
2341 on_clone_traceset_activate (GtkMenuItem
*menuitem
,
2344 create_new_window((GtkWidget
*)menuitem
, user_data
, TRUE
);
2348 /* create_new_tab calls create_tab to construct a new tab in the main window
2351 LttvPluginTab
*create_new_tab(GtkWidget
* widget
, gpointer user_data
)
2353 gchar label
[PATH_MAX
];
2354 MainWindow
* mw_data
= get_window_data_struct(widget
);
2356 GtkNotebook
* notebook
= (GtkNotebook
*)lookup_widget(widget
, "MNotebook");
2357 if(notebook
== NULL
){
2358 g_info("Notebook does not exist\n");
2361 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2362 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2368 LttvPluginTab
*ptab
;
2369 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
2370 copy_tab
= ptab
->tab
;
2373 strcpy(label
,"Page");
2374 if(get_label(mw_data
, label
,"Get the name of the tab","Please input tab's name")) {
2375 LttvPluginTab
*ptab
;
2377 ptab
= g_object_new(LTTV_TYPE_PLUGIN_TAB
, NULL
);
2378 init_tab (ptab
->tab
, mw_data
, copy_tab
, notebook
, label
);
2379 ptab
->parent
.top_widget
= ptab
->tab
->top_widget
;
2380 g_object_set_data_full(
2381 G_OBJECT(ptab
->tab
->vbox
),
2384 (GDestroyNotify
)tab_destructor
);
2391 on_tab_activate (GtkMenuItem
*menuitem
,
2394 create_new_tab((GtkWidget
*)menuitem
, user_data
);
2399 on_open_activate (GtkMenuItem
*menuitem
,
2402 open_traceset((GtkWidget
*)menuitem
, user_data
);
2407 on_close_activate (GtkMenuItem
*menuitem
,
2410 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2411 main_window_destructor(mw_data
);
2415 /* remove the current tab from the main window
2419 on_close_tab_activate (GtkWidget
*widget
,
2423 GtkWidget
* notebook
;
2425 MainWindow
* mw_data
= get_window_data_struct(widget
);
2426 notebook
= lookup_widget(widget
, "MNotebook");
2427 if(notebook
== NULL
){
2428 g_info("Notebook does not exist\n");
2432 page_num
= gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
));
2434 gtk_notebook_remove_page(GTK_NOTEBOOK(notebook
), page_num
);
2439 on_close_tab_X_clicked (GtkWidget
*widget
,
2443 GtkWidget
*notebook
= lookup_widget(widget
, "MNotebook");
2444 if(notebook
== NULL
){
2445 g_info("Notebook does not exist\n");
2449 if((page_num
= gtk_notebook_page_num(GTK_NOTEBOOK(notebook
), widget
)) != -1)
2450 gtk_notebook_remove_page(GTK_NOTEBOOK(notebook
), page_num
);
2456 on_add_trace_activate (GtkMenuItem
*menuitem
,
2459 add_trace((GtkWidget
*)menuitem
, user_data
);
2464 on_remove_trace_activate (GtkMenuItem
*menuitem
,
2467 remove_trace((GtkWidget
*)menuitem
, user_data
);
2472 on_save_activate (GtkMenuItem
*menuitem
,
2475 save((GtkWidget
*)menuitem
, user_data
);
2480 on_save_as_activate (GtkMenuItem
*menuitem
,
2483 save_as((GtkWidget
*)menuitem
, user_data
);
2488 on_quit_activate (GtkMenuItem
*menuitem
,
2491 while (g_slist_length(g_main_window_list
) != 0) {
2492 on_MWindow_destroy(((MainWindow
*)g_main_window_list
->data
)->mwindow
,
2499 on_cut_activate (GtkMenuItem
*menuitem
,
2507 on_copy_activate (GtkMenuItem
*menuitem
,
2515 on_paste_activate (GtkMenuItem
*menuitem
,
2523 on_delete_activate (GtkMenuItem
*menuitem
,
2531 on_zoom_in_activate (GtkMenuItem
*menuitem
,
2534 zoom_in((GtkWidget
*)menuitem
, user_data
);
2539 on_zoom_out_activate (GtkMenuItem
*menuitem
,
2542 zoom_out((GtkWidget
*)menuitem
, user_data
);
2547 on_zoom_extended_activate (GtkMenuItem
*menuitem
,
2550 zoom_extended((GtkWidget
*)menuitem
, user_data
);
2555 on_go_to_time_activate (GtkMenuItem
*menuitem
,
2558 go_to_time((GtkWidget
*)menuitem
, user_data
);
2563 on_show_time_frame_activate (GtkMenuItem
*menuitem
,
2566 show_time_frame((GtkWidget
*)menuitem
, user_data
);
2571 on_move_viewer_up_activate (GtkMenuItem
*menuitem
,
2574 move_up_viewer((GtkWidget
*)menuitem
, user_data
);
2579 on_move_viewer_down_activate (GtkMenuItem
*menuitem
,
2582 move_down_viewer((GtkWidget
*)menuitem
, user_data
);
2587 on_remove_viewer_activate (GtkMenuItem
*menuitem
,
2590 delete_viewer((GtkWidget
*)menuitem
, user_data
);
2594 on_trace_facility_activate (GtkMenuItem
*menuitem
,
2597 g_info("Trace facility selector: %s\n", "");
2601 /* Dispaly a file selection dialogue to let user select a library, then call
2602 * lttv_library_load().
2606 on_load_library_activate (GtkMenuItem
*menuitem
,
2609 GError
*error
= NULL
;
2610 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2612 gchar load_module_path_alter
[PATH_MAX
];
2616 gchar
*load_module_path
;
2617 name
= g_ptr_array_new();
2618 nb
= lttv_library_path_number();
2619 /* ask for the library path */
2623 path
= lttv_library_path_get(i
);
2624 g_ptr_array_add(name
, path
);
2627 load_module_path
= get_selection(mw_data
,
2628 (char **)(name
->pdata
), name
->len
,
2629 "Select a library path", "Library paths");
2630 if(load_module_path
!= NULL
)
2631 strncpy(load_module_path_alter
, load_module_path
, PATH_MAX
-1); // -1 for /
2633 g_ptr_array_free(name
, TRUE
);
2635 if(load_module_path
== NULL
) return;
2639 /* Make sure the module path ends with a / */
2640 gchar
*ptr
= load_module_path_alter
;
2642 ptr
= strchr(ptr
, '\0');
2644 if(*(ptr
-1) != '/') {
2651 /* Ask for the library to load : list files in the previously selected
2653 gchar str
[PATH_MAX
];
2656 GtkFileSelection
* file_selector
=
2657 (GtkFileSelection
*)gtk_file_selection_new("Select a module");
2658 gtk_file_selection_set_filename(file_selector
, load_module_path_alter
);
2659 gtk_file_selection_hide_fileop_buttons(file_selector
);
2661 gtk_window_set_transient_for(GTK_WINDOW(file_selector
),
2662 GTK_WINDOW(mw_data
->mwindow
));
2665 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
2667 case GTK_RESPONSE_ACCEPT
:
2668 case GTK_RESPONSE_OK
:
2669 dir
= gtk_file_selection_get_selections (file_selector
);
2670 strncpy(str
,dir
[0],PATH_MAX
);
2671 strncpy(remember_plugins_dir
,dir
[0],PATH_MAX
);
2672 /* only keep file name */
2674 str1
= strrchr(str
,'/');
2677 str1
= strrchr(str
,'\\');
2682 if(*str1
== 'l' && *(str1
+1)== 'i' && *(str1
+2)=='b')
2684 remove info after
. */
2688 str2
= strrchr(str2
, '.');
2689 if(str2
!= NULL
) *str2
= '\0';
2691 lttv_module_require(str1
, &error
);
2693 lttv_library_load(str1
, &error
);
2694 if(error
!= NULL
) g_warning("%s", error
->message
);
2695 else g_info("Load library: %s\n", str
);
2697 case GTK_RESPONSE_REJECT
:
2698 case GTK_RESPONSE_CANCEL
:
2700 gtk_widget_destroy((GtkWidget
*)file_selector
);
2711 /* Display all loaded modules, let user to select a module to unload
2712 * by calling lttv_module_unload
2716 on_unload_library_activate (GtkMenuItem
*menuitem
,
2719 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2721 LttvLibrary
*library
= NULL
;
2726 name
= g_ptr_array_new();
2727 nb
= lttv_library_number();
2728 LttvLibraryInfo
*lib_info
= g_new(LttvLibraryInfo
,nb
);
2729 /* ask for the library name */
2732 LttvLibrary
*iter_lib
= lttv_library_get(i
);
2733 lttv_library_info(iter_lib
, &lib_info
[i
]);
2735 gchar
*path
= lib_info
[i
].name
;
2736 g_ptr_array_add(name
, path
);
2738 lib_name
= get_selection(mw_data
, (char **)(name
->pdata
), name
->len
,
2739 "Select a library", "Libraries");
2740 if(lib_name
!= NULL
) {
2742 if(strcmp(lib_name
, lib_info
[i
].name
) == 0) {
2743 library
= lttv_library_get(i
);
2748 g_ptr_array_free(name
, TRUE
);
2751 if(lib_name
== NULL
) return;
2753 if(library
!= NULL
) lttv_library_unload(library
);
2757 /* Dispaly a file selection dialogue to let user select a module, then call
2758 * lttv_module_require().
2762 on_load_module_activate (GtkMenuItem
*menuitem
,
2765 GError
*error
= NULL
;
2766 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2768 LttvLibrary
*library
= NULL
;
2773 name
= g_ptr_array_new();
2774 nb
= lttv_library_number();
2775 LttvLibraryInfo
*lib_info
= g_new(LttvLibraryInfo
,nb
);
2776 /* ask for the library name */
2779 LttvLibrary
*iter_lib
= lttv_library_get(i
);
2780 lttv_library_info(iter_lib
, &lib_info
[i
]);
2782 gchar
*path
= lib_info
[i
].name
;
2783 g_ptr_array_add(name
, path
);
2785 lib_name
= get_selection(mw_data
,(char **)(name
->pdata
), name
->len
,
2786 "Select a library", "Libraries");
2787 if(lib_name
!= NULL
) {
2789 if(strcmp(lib_name
, lib_info
[i
].name
) == 0) {
2790 library
= lttv_library_get(i
);
2795 g_ptr_array_free(name
, TRUE
);
2798 if(lib_name
== NULL
) return;
2801 //LttvModule *module;
2802 gchar module_name_out
[PATH_MAX
];
2804 /* Ask for the module to load : list modules in the selected lib */
2808 nb
= lttv_library_module_number(library
);
2809 LttvModuleInfo
*module_info
= g_new(LttvModuleInfo
,nb
);
2810 name
= g_ptr_array_new();
2811 /* ask for the module name */
2814 LttvModule
*iter_module
= lttv_library_module_get(library
, i
);
2815 lttv_module_info(iter_module
, &module_info
[i
]);
2817 gchar
*path
= module_info
[i
].name
;
2818 g_ptr_array_add(name
, path
);
2820 module_name
= get_selection(mw_data
, (char **)(name
->pdata
), name
->len
,
2821 "Select a module", "Modules");
2822 if(module_name
!= NULL
) {
2824 if(strcmp(module_name
, module_info
[i
].name
) == 0) {
2825 strncpy(module_name_out
, module_name
, PATH_MAX
);
2826 //module = lttv_library_module_get(i);
2832 g_ptr_array_free(name
, TRUE
);
2833 g_free(module_info
);
2835 if(module_name
== NULL
) return;
2838 lttv_module_require(module_name_out
, &error
);
2839 if(error
!= NULL
) g_warning("%s", error
->message
);
2840 else g_info("Load module: %s", module_name_out
);
2847 gchar str
[PATH_MAX
];
2850 GtkFileSelection
* file_selector
=
2851 (GtkFileSelection
*)gtk_file_selection_new("Select a module");
2852 gtk_file_selection_set_filename(file_selector
, load_module_path_alter
);
2853 gtk_file_selection_hide_fileop_buttons(file_selector
);
2856 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
2858 case GTK_RESPONSE_ACCEPT
:
2859 case GTK_RESPONSE_OK
:
2860 dir
= gtk_file_selection_get_selections (file_selector
);
2861 strncpy(str
,dir
[0],PATH_MAX
);
2862 strncpy(remember_plugins_dir
,dir
[0],PATH_MAX
);
2864 /* only keep file name */
2866 str1
= strrchr(str
,'/');
2869 str1
= strrchr(str
,'\\');
2874 if(*str1
== 'l' && *(str1
+1)== 'i' && *(str1
+2)=='b')
2876 remove info after
. */
2880 str2
= strrchr(str2
, '.');
2881 if(str2
!= NULL
) *str2
= '\0';
2883 lttv_module_require(str1
, &error
);
2885 lttv_library_load(str1
, &error
);
2886 if(error
!= NULL
) g_warning(error
->message
);
2887 else g_info("Load library: %s\n", str
);
2889 case GTK_RESPONSE_REJECT
:
2890 case GTK_RESPONSE_CANCEL
:
2892 gtk_widget_destroy((GtkWidget
*)file_selector
);
2904 /* Display all loaded modules, let user to select a module to unload
2905 * by calling lttv_module_unload
2909 on_unload_module_activate (GtkMenuItem
*menuitem
,
2912 GError
*error
= NULL
;
2913 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2915 LttvLibrary
*library
= NULL
;
2920 name
= g_ptr_array_new();
2921 nb
= lttv_library_number();
2922 LttvLibraryInfo
*lib_info
= g_new(LttvLibraryInfo
,nb
);
2923 /* ask for the library name */
2926 LttvLibrary
*iter_lib
= lttv_library_get(i
);
2927 lttv_library_info(iter_lib
, &lib_info
[i
]);
2929 gchar
*path
= lib_info
[i
].name
;
2930 g_ptr_array_add(name
, path
);
2932 lib_name
= get_selection(mw_data
, (char **)(name
->pdata
), name
->len
,
2933 "Select a library", "Libraries");
2934 if(lib_name
!= NULL
) {
2936 if(strcmp(lib_name
, lib_info
[i
].name
) == 0) {
2937 library
= lttv_library_get(i
);
2942 g_ptr_array_free(name
, TRUE
);
2945 if(lib_name
== NULL
) return;
2948 LttvModule
*module
= NULL
;
2950 /* Ask for the module to load : list modules in the selected lib */
2954 nb
= lttv_library_module_number(library
);
2955 LttvModuleInfo
*module_info
= g_new(LttvModuleInfo
,nb
);
2956 name
= g_ptr_array_new();
2957 /* ask for the module name */
2960 LttvModule
*iter_module
= lttv_library_module_get(library
, i
);
2961 lttv_module_info(iter_module
, &module_info
[i
]);
2963 gchar
*path
= module_info
[i
].name
;
2964 if(module_info
[i
].use_count
> 0) g_ptr_array_add(name
, path
);
2966 module_name
= get_selection(mw_data
, (char **)(name
->pdata
), name
->len
,
2967 "Select a module", "Modules");
2968 if(module_name
!= NULL
) {
2970 if(strcmp(module_name
, module_info
[i
].name
) == 0) {
2971 module
= lttv_library_module_get(library
, i
);
2977 g_ptr_array_free(name
, TRUE
);
2978 g_free(module_info
);
2980 if(module_name
== NULL
) return;
2983 LttvModuleInfo module_info
;
2984 lttv_module_info(module
, &module_info
);
2985 g_info("Release module: %s\n", module_info
.name
);
2987 lttv_module_release(module
);
2991 /* Display a directory dialogue to let user select a path for library searching
2995 on_add_library_search_path_activate (GtkMenuItem
*menuitem
,
2998 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2999 //GtkDirSelection * file_selector = (GtkDirSelection *)gtk_dir_selection_new("Select library path");
3000 GtkFileSelection
* file_selector
= (GtkFileSelection
*)gtk_file_selection_new("Select a trace");
3001 gtk_widget_hide( (file_selector
)->file_list
->parent
) ;
3003 gtk_window_set_transient_for(GTK_WINDOW(file_selector
),
3004 GTK_WINDOW(mw_data
->mwindow
));
3009 if(remember_plugins_dir
[0] != '\0')
3010 gtk_file_selection_set_filename(file_selector
, remember_plugins_dir
);
3012 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
3014 case GTK_RESPONSE_ACCEPT
:
3015 case GTK_RESPONSE_OK
:
3016 dir
= gtk_file_selection_get_filename (file_selector
);
3017 strncpy(remember_plugins_dir
,dir
,PATH_MAX
);
3018 strncat(remember_plugins_dir
,"/",PATH_MAX
);
3019 lttv_library_path_add(dir
);
3020 case GTK_RESPONSE_REJECT
:
3021 case GTK_RESPONSE_CANCEL
:
3023 gtk_widget_destroy((GtkWidget
*)file_selector
);
3029 /* Display a directory dialogue to let user select a path for library searching
3033 on_remove_library_search_path_activate (GtkMenuItem
*menuitem
,
3036 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
3038 const char *lib_path
;
3043 name
= g_ptr_array_new();
3044 nb
= lttv_library_path_number();
3045 /* ask for the library name */
3048 gchar
*path
= lttv_library_path_get(i
);
3049 g_ptr_array_add(name
, path
);
3051 lib_path
= get_selection(mw_data
, (char **)(name
->pdata
), name
->len
,
3052 "Select a library path", "Library paths");
3054 g_ptr_array_free(name
, TRUE
);
3056 if(lib_path
== NULL
) return;
3059 lttv_library_path_remove(lib_path
);
3063 on_color_activate (GtkMenuItem
*menuitem
,
3071 on_save_configuration_activate (GtkMenuItem
*menuitem
,
3074 g_info("Save configuration\n");
3079 on_content_activate (GtkMenuItem
*menuitem
,
3082 g_info("Content\n");
3087 on_about_close_activate (GtkButton
*button
,
3090 GtkWidget
*about_widget
= GTK_WIDGET(user_data
);
3092 gtk_widget_destroy(about_widget
);
3096 on_about_activate (GtkMenuItem
*menuitem
,
3099 MainWindow
*main_window
= get_window_data_struct(GTK_WIDGET(menuitem
));
3100 GtkWidget
*window_widget
= main_window
->mwindow
;
3101 GtkWidget
*about_widget
= gtk_window_new(GTK_WINDOW_TOPLEVEL
);
3102 GtkWindow
*about_window
= GTK_WINDOW(about_widget
);
3103 gint window_width
, window_height
;
3105 gtk_window_set_title(about_window
, "About Linux Trace Toolkit");
3107 gtk_window_set_resizable(about_window
, FALSE
);
3108 gtk_window_set_transient_for(about_window
, GTK_WINDOW(window_widget
));
3109 gtk_window_set_destroy_with_parent(about_window
, TRUE
);
3110 gtk_window_set_modal(about_window
, FALSE
);
3112 /* Put the about window at the center of the screen */
3113 gtk_window_get_size(about_window
, &window_width
, &window_height
);
3114 gtk_window_move (about_window
,
3115 (gdk_screen_width() - window_width
)/2,
3116 (gdk_screen_height() - window_height
)/2);
3118 GtkWidget
*vbox
= gtk_vbox_new(FALSE
, 1);
3120 gtk_container_add(GTK_CONTAINER(about_widget
), vbox
);
3124 GtkWidget
*label1
= gtk_label_new("");
3125 gtk_misc_set_padding(GTK_MISC(label1
), 10, 20);
3126 gtk_label_set_markup(GTK_LABEL(label1
), "\
3127 <big>Linux Trace Toolkit " VERSION
"</big>");
3128 gtk_label_set_justify(GTK_LABEL(label1
), GTK_JUSTIFY_CENTER
);
3130 GtkWidget
*label2
= gtk_label_new("");
3131 gtk_misc_set_padding(GTK_MISC(label2
), 10, 20);
3132 gtk_label_set_markup(GTK_LABEL(label2
), "\
3135 Michel Dagenais (New trace format, lttv main)\n\
3136 Mathieu Desnoyers (Kernel Tracer, Directory structure, build with automake/conf,\n\
3137 lttv gui, control flow view, gui cooperative trace reading\n\
3138 scheduler with interruptible foreground and background\n\
3139 computation, detailed event list (rewrite), trace reading\n\
3140 library (rewrite))\n\
3141 Benoit Des Ligneris, Eric Clement (Cluster adaptation, work in progress)\n\
3142 Xang-Xiu Yang (new trace reading library and converter, lttv gui, \n\
3143 detailed event list and statistics view)\n\
3144 Tom Zanussi (RelayFS)\n\
3146 Inspired from the original Linux Trace Toolkit Visualizer made by\n\
3149 GtkWidget
*label3
= gtk_label_new("");
3150 gtk_label_set_markup(GTK_LABEL(label3
), "\
3151 Linux Trace Toolkit Viewer, Copyright (C) 2004, 2005, 2006\n\
3153 Mathieu Desnoyers\n\
3155 Linux Trace Toolkit comes with ABSOLUTELY NO WARRANTY.\n\
3156 This is free software, and you are welcome to redistribute it\n\
3157 under certain conditions. See COPYING for details.");
3158 gtk_misc_set_padding(GTK_MISC(label3
), 10, 20);
3160 gtk_box_pack_start_defaults(GTK_BOX(vbox
), label1
);
3161 gtk_box_pack_start_defaults(GTK_BOX(vbox
), label2
);
3162 gtk_box_pack_start_defaults(GTK_BOX(vbox
), label3
);
3164 GtkWidget
*hbox
= gtk_hbox_new(TRUE
, 0);
3165 gtk_box_pack_end(GTK_BOX(vbox
), hbox
, FALSE
, FALSE
, 0);
3166 GtkWidget
*close_button
= gtk_button_new_with_mnemonic("_Close");
3167 gtk_box_pack_end(GTK_BOX(hbox
), close_button
, FALSE
, FALSE
, 0);
3168 gtk_container_set_border_width(GTK_CONTAINER(close_button
), 20);
3170 g_signal_connect(G_OBJECT(close_button
), "clicked",
3171 G_CALLBACK(on_about_close_activate
),
3172 (gpointer
)about_widget
);
3174 gtk_widget_show_all(about_widget
);
3179 on_button_new_clicked (GtkButton
*button
,
3182 create_new_window((GtkWidget
*)button
, user_data
, TRUE
);
3186 on_button_new_tab_clicked (GtkButton
*button
,
3189 create_new_tab((GtkWidget
*)button
, user_data
);
3193 on_button_open_clicked (GtkButton
*button
,
3196 open_traceset((GtkWidget
*)button
, user_data
);
3201 on_button_add_trace_clicked (GtkButton
*button
,
3204 add_trace((GtkWidget
*)button
, user_data
);
3209 on_button_remove_trace_clicked (GtkButton
*button
,
3212 remove_trace((GtkWidget
*)button
, user_data
);
3216 on_button_redraw_clicked (GtkButton
*button
,
3219 redraw((GtkWidget
*)button
, user_data
);
3223 on_button_continue_processing_clicked (GtkButton
*button
,
3226 continue_processing((GtkWidget
*)button
, user_data
);
3230 on_button_stop_processing_clicked (GtkButton
*button
,
3233 stop_processing((GtkWidget
*)button
, user_data
);
3239 on_button_save_clicked (GtkButton
*button
,
3242 save((GtkWidget
*)button
, user_data
);
3247 on_button_save_as_clicked (GtkButton
*button
,
3250 save_as((GtkWidget
*)button
, user_data
);
3255 on_button_zoom_in_clicked (GtkButton
*button
,
3258 zoom_in((GtkWidget
*)button
, user_data
);
3263 on_button_zoom_out_clicked (GtkButton
*button
,
3266 zoom_out((GtkWidget
*)button
, user_data
);
3271 on_button_zoom_extended_clicked (GtkButton
*button
,
3274 zoom_extended((GtkWidget
*)button
, user_data
);
3279 on_button_go_to_time_clicked (GtkButton
*button
,
3282 go_to_time((GtkWidget
*)button
, user_data
);
3287 on_button_show_time_frame_clicked (GtkButton
*button
,
3290 show_time_frame((GtkWidget
*)button
, user_data
);
3295 on_button_move_up_clicked (GtkButton
*button
,
3298 move_up_viewer((GtkWidget
*)button
, user_data
);
3303 on_button_move_down_clicked (GtkButton
*button
,
3306 move_down_viewer((GtkWidget
*)button
, user_data
);
3311 on_button_delete_viewer_clicked (GtkButton
*button
,
3314 delete_viewer((GtkWidget
*)button
, user_data
);
3318 on_MWindow_destroy (GtkWidget
*widget
,
3321 MainWindow
*main_window
= get_window_data_struct(widget
);
3322 LttvIAttribute
*attributes
= main_window
->attributes
;
3323 LttvAttributeValue value
;
3326 //This is unnecessary, since widgets will be destroyed
3327 //by the main window widget anyway.
3328 //remove_all_menu_toolbar_constructors(main_window, NULL);
3330 retval
= lttv_iattribute_find_by_path(attributes
, "viewers/menu",
3331 LTTV_POINTER
, &value
);
3333 lttv_menus_destroy((LttvMenus
*)*(value
.v_pointer
));
3335 retval
= lttv_iattribute_find_by_path(attributes
, "viewers/toolbar",
3336 LTTV_POINTER
, &value
);
3338 lttv_toolbars_destroy((LttvToolbars
*)*(value
.v_pointer
));
3340 g_object_unref(main_window
->attributes
);
3341 g_main_window_list
= g_slist_remove(g_main_window_list
, main_window
);
3343 g_info("There are now : %d windows\n",g_slist_length(g_main_window_list
));
3344 if(g_slist_length(g_main_window_list
) == 0)
3349 on_MWindow_configure (GtkWidget
*widget
,
3350 GdkEventConfigure
*event
,
3353 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)widget
);
3355 // MD : removed time width modification upon resizing of the main window.
3356 // The viewers will redraw themselves completely, without time interval
3359 if(mw_data->window_width){
3360 time_span = LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context)->Time_Span ;
3361 time_win = tab->time_window;
3362 ratio = width / mw_data->window_width;
3363 tab->time_window.time_width = ltt_time_mul(time_win.time_width,ratio);
3364 time = ltt_time_sub(time_span->endTime, time_win.start_time);
3365 if(ltt_time_compare(time, tab->time_window.time_width) < 0){
3366 tab->time_window.time_width = time;
3372 mw_data->window_width = (int)width;
3381 on_MNotebook_switch_page (GtkNotebook
*notebook
,
3382 GtkNotebookPage
*page
,
3390 void time_change_manager (Tab
*tab
,
3391 TimeWindow new_time_window
)
3393 /* Only one source of time change */
3394 if(tab
->time_manager_lock
== TRUE
) return;
3396 tab
->time_manager_lock
= TRUE
;
3398 LttvTracesetContext
*tsc
= LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3399 TimeInterval time_span
= tsc
->time_span
;
3400 LttTime start_time
= new_time_window
.start_time
;
3401 LttTime end_time
= new_time_window
.end_time
;
3402 LttTime time_width
= new_time_window
.time_width
;
3404 g_assert(ltt_time_compare(start_time
, end_time
) < 0);
3407 GtkAdjustment
*adjustment
= gtk_range_get_adjustment(GTK_RANGE(tab
->scrollbar
));
3408 LttTime upper
= ltt_time_sub(time_span
.end_time
, time_span
.start_time
);
3410 gtk_range_set_increments(GTK_RANGE(tab
->scrollbar
),
3411 ltt_time_to_double(new_time_window
.time_width
)
3412 / SCROLL_STEP_PER_PAGE
3413 * NANOSECONDS_PER_SECOND
, /* step increment */
3414 ltt_time_to_double(new_time_window
.time_width
)
3415 * NANOSECONDS_PER_SECOND
); /* page increment */
3416 gtk_range_set_range(GTK_RANGE(tab
->scrollbar
),
3418 ltt_time_to_double(upper
)
3419 * NANOSECONDS_PER_SECOND
); /* upper */
3421 g_object_set(G_OBJECT(adjustment
),
3425 ltt_time_to_double(upper
), /* upper */
3427 new_time_window
.time_width_double
3428 / SCROLL_STEP_PER_PAGE
, /* step increment */
3430 new_time_window
.time_width_double
,
3431 /* page increment */
3433 new_time_window
.time_width_double
, /* page size */
3435 gtk_adjustment_changed(adjustment
);
3437 // g_object_set(G_OBJECT(adjustment),
3439 // ltt_time_to_double(
3440 // ltt_time_sub(start_time, time_span.start_time))
3443 //gtk_adjustment_value_changed(adjustment);
3444 gtk_range_set_value(GTK_RANGE(tab
->scrollbar
),
3446 ltt_time_sub(start_time
, time_span
.start_time
)) /* value */);
3448 /* set the time bar. */
3450 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry1
),
3451 (double)time_span
.start_time
.tv_sec
,
3452 (double)time_span
.end_time
.tv_sec
);
3453 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry1
),
3454 (double)start_time
.tv_sec
);
3456 /* start nanoseconds */
3457 if(start_time
.tv_sec
== time_span
.start_time
.tv_sec
) {
3458 /* can be both beginning and end at the same time. */
3459 if(start_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3460 /* If we are at the end, max nsec to end.. -1 (not zero length) */
3461 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry2
),
3462 (double)time_span
.start_time
.tv_nsec
,
3463 (double)time_span
.end_time
.tv_nsec
-1);
3465 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry2
),
3466 (double)time_span
.start_time
.tv_nsec
,
3467 (double)NANOSECONDS_PER_SECOND
-1);
3469 } else if(start_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3470 /* If we are at the end, max nsec to end.. -1 (not zero length) */
3471 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry2
),
3473 (double)time_span
.end_time
.tv_nsec
-1);
3474 } else /* anywhere else */
3475 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry2
),
3477 (double)NANOSECONDS_PER_SECOND
-1);
3478 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry2
),
3479 (double)start_time
.tv_nsec
);
3482 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry3
),
3483 (double)time_span
.start_time
.tv_sec
,
3484 (double)time_span
.end_time
.tv_sec
);
3485 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry3
),
3486 (double)end_time
.tv_sec
);
3488 /* end nanoseconds */
3489 if(end_time
.tv_sec
== time_span
.start_time
.tv_sec
) {
3490 /* can be both beginning and end at the same time. */
3491 if(end_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3492 /* If we are at the end, max nsec to end.. */
3493 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry4
),
3494 (double)time_span
.start_time
.tv_nsec
+1,
3495 (double)time_span
.end_time
.tv_nsec
);
3497 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry4
),
3498 (double)time_span
.start_time
.tv_nsec
+1,
3499 (double)NANOSECONDS_PER_SECOND
-1);
3502 else if(end_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3503 /* If we are at the end, max nsec to end.. */
3504 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry4
),
3506 (double)time_span
.end_time
.tv_nsec
);
3508 else /* anywhere else */
3509 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry4
),
3511 (double)NANOSECONDS_PER_SECOND
-1);
3512 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry4
),
3513 (double)end_time
.tv_nsec
);
3516 if(time_width
.tv_nsec
== 0) {
3517 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry7
),
3519 (double)upper
.tv_sec
);
3521 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry7
),
3523 (double)upper
.tv_sec
);
3525 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry7
),
3526 (double)time_width
.tv_sec
);
3528 /* width nanoseconds */
3529 if(time_width
.tv_sec
== upper
.tv_sec
) {
3530 if(time_width
.tv_sec
== 0) {
3531 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry8
),
3533 (double)upper
.tv_nsec
);
3535 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry8
),
3537 (double)upper
.tv_nsec
);
3540 else if(time_width
.tv_sec
== 0) {
3541 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry8
),
3543 (double)upper
.tv_nsec
);
3545 else /* anywhere else */
3546 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry8
),
3548 (double)NANOSECONDS_PER_SECOND
-1);
3549 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry8
),
3550 (double)time_width
.tv_nsec
);
3552 /* call viewer hooks for new time window */
3553 set_time_window(tab
, &new_time_window
);
3555 tab
->time_manager_lock
= FALSE
;
3559 /* value changed for frame start s
3561 * Check time span : if ns is out of range, clip it the nearest good value.
3564 on_MEntry1_value_changed (GtkSpinButton
*spinbutton
,
3567 Tab
*tab
=(Tab
*)user_data
;
3568 LttvTracesetContext
* tsc
=
3569 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3570 TimeInterval time_span
= tsc
->time_span
;
3571 gint value
= gtk_spin_button_get_value_as_int(spinbutton
);
3573 TimeWindow new_time_window
= tab
->time_window
;
3575 LttTime end_time
= new_time_window
.end_time
;
3577 new_time_window
.start_time
.tv_sec
= value
;
3579 /* start nanoseconds */
3580 if(new_time_window
.start_time
.tv_sec
== time_span
.start_time
.tv_sec
) {
3581 if(new_time_window
.start_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3582 if(new_time_window
.start_time
.tv_nsec
> time_span
.end_time
.tv_nsec
)
3583 new_time_window
.start_time
.tv_nsec
= time_span
.end_time
.tv_nsec
-1;
3584 if(new_time_window
.start_time
.tv_nsec
< time_span
.start_time
.tv_nsec
)
3585 new_time_window
.start_time
.tv_nsec
= time_span
.start_time
.tv_nsec
;
3587 if(new_time_window
.start_time
.tv_nsec
< time_span
.start_time
.tv_nsec
)
3588 new_time_window
.start_time
.tv_nsec
= time_span
.start_time
.tv_nsec
;
3591 else if(new_time_window
.start_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3592 if(new_time_window
.start_time
.tv_nsec
> time_span
.end_time
.tv_nsec
)
3593 new_time_window
.start_time
.tv_nsec
= time_span
.end_time
.tv_nsec
-1;
3596 if(ltt_time_compare(new_time_window
.start_time
, end_time
) >= 0) {
3597 /* Then, we must push back end time : keep the same time width
3598 * if possible, else end traceset time */
3599 end_time
= LTT_TIME_MIN(ltt_time_add(new_time_window
.start_time
,
3600 new_time_window
.time_width
),
3601 time_span
.end_time
);
3604 /* Fix the time width to fit start time and end time */
3605 new_time_window
.time_width
= ltt_time_sub(end_time
,
3606 new_time_window
.start_time
);
3607 new_time_window
.time_width_double
=
3608 ltt_time_to_double(new_time_window
.time_width
);
3610 new_time_window
.end_time
= end_time
;
3612 time_change_manager(tab
, new_time_window
);
3617 on_MEntry2_value_changed (GtkSpinButton
*spinbutton
,
3620 Tab
*tab
=(Tab
*)user_data
;
3621 LttvTracesetContext
* tsc
=
3622 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3623 TimeInterval time_span
= tsc
->time_span
;
3624 gint value
= gtk_spin_button_get_value_as_int(spinbutton
);
3626 TimeWindow new_time_window
= tab
->time_window
;
3628 LttTime end_time
= new_time_window
.end_time
;
3630 new_time_window
.start_time
.tv_nsec
= value
;
3632 if(ltt_time_compare(new_time_window
.start_time
, end_time
) >= 0) {
3633 /* Then, we must push back end time : keep the same time width
3634 * if possible, else end traceset time */
3635 end_time
= LTT_TIME_MIN(ltt_time_add(new_time_window
.start_time
,
3636 new_time_window
.time_width
),
3637 time_span
.end_time
);
3640 /* Fix the time width to fit start time and end time */
3641 new_time_window
.time_width
= ltt_time_sub(end_time
,
3642 new_time_window
.start_time
);
3643 new_time_window
.time_width_double
=
3644 ltt_time_to_double(new_time_window
.time_width
);
3646 new_time_window
.end_time
= end_time
;
3648 time_change_manager(tab
, new_time_window
);
3653 on_MEntry3_value_changed (GtkSpinButton
*spinbutton
,
3656 Tab
*tab
=(Tab
*)user_data
;
3657 LttvTracesetContext
* tsc
=
3658 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3659 TimeInterval time_span
= tsc
->time_span
;
3660 gint value
= gtk_spin_button_get_value_as_int(spinbutton
);
3662 TimeWindow new_time_window
= tab
->time_window
;
3664 LttTime end_time
= new_time_window
.end_time
;
3666 end_time
.tv_sec
= value
;
3668 /* end nanoseconds */
3669 if(end_time
.tv_sec
== time_span
.start_time
.tv_sec
) {
3670 if(end_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3671 if(end_time
.tv_nsec
> time_span
.end_time
.tv_nsec
)
3672 end_time
.tv_nsec
= time_span
.end_time
.tv_nsec
;
3673 if(end_time
.tv_nsec
< time_span
.start_time
.tv_nsec
)
3674 end_time
.tv_nsec
= time_span
.start_time
.tv_nsec
+1;
3676 if(end_time
.tv_nsec
< time_span
.start_time
.tv_nsec
)
3677 end_time
.tv_nsec
= time_span
.start_time
.tv_nsec
+1;
3680 else if(end_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3681 if(end_time
.tv_nsec
> time_span
.end_time
.tv_nsec
)
3682 end_time
.tv_nsec
= time_span
.end_time
.tv_nsec
;
3685 if(ltt_time_compare(new_time_window
.start_time
, end_time
) >= 0) {
3686 /* Then, we must push front start time : keep the same time width
3687 * if possible, else end traceset time */
3688 new_time_window
.start_time
= LTT_TIME_MAX(
3689 ltt_time_sub(end_time
,
3690 new_time_window
.time_width
),
3691 time_span
.start_time
);
3694 /* Fix the time width to fit start time and end time */
3695 new_time_window
.time_width
= ltt_time_sub(end_time
,
3696 new_time_window
.start_time
);
3697 new_time_window
.time_width_double
=
3698 ltt_time_to_double(new_time_window
.time_width
);
3700 new_time_window
.end_time
= end_time
;
3702 time_change_manager(tab
, new_time_window
);
3707 on_MEntry4_value_changed (GtkSpinButton
*spinbutton
,
3710 Tab
*tab
=(Tab
*)user_data
;
3711 LttvTracesetContext
* tsc
=
3712 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3713 TimeInterval time_span
= tsc
->time_span
;
3714 gint value
= gtk_spin_button_get_value_as_int(spinbutton
);
3716 TimeWindow new_time_window
= tab
->time_window
;
3718 LttTime end_time
= new_time_window
.end_time
;
3720 end_time
.tv_nsec
= value
;
3722 if(ltt_time_compare(new_time_window
.start_time
, end_time
) >= 0) {
3723 /* Then, we must push front start time : keep the same time width
3724 * if possible, else end traceset time */
3725 new_time_window
.start_time
= LTT_TIME_MAX(
3726 ltt_time_sub(end_time
,
3727 new_time_window
.time_width
),
3728 time_span
.start_time
);
3731 /* Fix the time width to fit start time and end time */
3732 new_time_window
.time_width
= ltt_time_sub(end_time
,
3733 new_time_window
.start_time
);
3734 new_time_window
.time_width_double
=
3735 ltt_time_to_double(new_time_window
.time_width
);
3736 new_time_window
.end_time
= end_time
;
3738 time_change_manager(tab
, new_time_window
);
3742 /* value changed for time frame interval s
3744 * Check time span : if ns is out of range, clip it the nearest good value.
3747 on_MEntry7_value_changed (GtkSpinButton
*spinbutton
,
3750 Tab
*tab
=(Tab
*)user_data
;
3751 LttvTracesetContext
* tsc
=
3752 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3753 TimeInterval time_span
= tsc
->time_span
;
3754 gint value
= gtk_spin_button_get_value_as_int(spinbutton
);
3755 LttTime current_time
, time_delta
;
3756 TimeWindow new_time_window
= tab
->time_window
;
3757 current_time
= tab
->current_time
;
3759 time_delta
= ltt_time_sub(time_span
.end_time
,time_span
.start_time
);
3760 new_time_window
.time_width
.tv_sec
= value
;
3761 new_time_window
.time_width_double
=
3762 ltt_time_to_double(new_time_window
.time_width
);
3763 if(ltt_time_compare(new_time_window
.time_width
,time_delta
) > 0)
3764 { /* Case where zoom out is bigger than trace length */
3765 new_time_window
.start_time
= time_span
.start_time
;
3766 new_time_window
.time_width
= time_delta
;
3767 new_time_window
.time_width_double
= ltt_time_to_double(time_delta
);
3768 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
3769 new_time_window
.time_width
) ;
3773 /* Center the image on the current time */
3774 new_time_window
.start_time
=
3775 ltt_time_sub(current_time
,
3776 ltt_time_from_double(new_time_window
.time_width_double
/2.0));
3777 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
3778 new_time_window
.time_width
) ;
3779 /* If on borders, don't fall off */
3780 if(ltt_time_compare(new_time_window
.start_time
, time_span
.start_time
) <0
3781 || ltt_time_compare(new_time_window
.start_time
, time_span
.end_time
) >0)
3783 new_time_window
.start_time
= time_span
.start_time
;
3784 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
3785 new_time_window
.time_width
) ;
3789 if(ltt_time_compare(new_time_window
.end_time
,
3790 time_span
.end_time
) > 0
3791 || ltt_time_compare(new_time_window
.end_time
,
3792 time_span
.start_time
) < 0)
3794 new_time_window
.start_time
=
3795 ltt_time_sub(time_span
.end_time
, new_time_window
.time_width
);
3797 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
3798 new_time_window
.time_width
) ;
3804 if(ltt_time_compare(new_time_window
.time_width
, ltt_time_zero
) == 0) {
3805 g_warning("Zoom more than 1 ns impossible");
3807 time_change_manager(tab
, new_time_window
);
3812 on_MEntry8_value_changed (GtkSpinButton
*spinbutton
,
3815 Tab
*tab
=(Tab
*)user_data
;
3816 LttvTracesetContext
* tsc
=
3817 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3818 TimeInterval time_span
= tsc
->time_span
;
3819 gint value
= gtk_spin_button_get_value_as_int(spinbutton
);
3820 LttTime current_time
, time_delta
;
3821 TimeWindow new_time_window
= tab
->time_window
;
3822 current_time
= tab
->current_time
;
3824 time_delta
= ltt_time_sub(time_span
.end_time
,time_span
.start_time
);
3825 new_time_window
.time_width
.tv_nsec
= value
;
3826 new_time_window
.time_width_double
=
3827 ltt_time_to_double(new_time_window
.time_width
);
3828 if(ltt_time_compare(new_time_window
.time_width
,time_delta
) > 0)
3829 { /* Case where zoom out is bigger than trace length */
3830 new_time_window
.start_time
= time_span
.start_time
;
3831 new_time_window
.time_width
= time_delta
;
3832 new_time_window
.time_width_double
= ltt_time_to_double(time_delta
);
3833 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
3834 new_time_window
.time_width
) ;
3838 /* Center the image on the current time */
3839 new_time_window
.start_time
=
3840 ltt_time_sub(current_time
,
3841 ltt_time_from_double(new_time_window
.time_width_double
/2.0));
3842 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
3843 new_time_window
.time_width
) ;
3844 /* If on borders, don't fall off */
3845 if(ltt_time_compare(new_time_window
.start_time
, time_span
.start_time
) <0
3846 || ltt_time_compare(new_time_window
.start_time
, time_span
.end_time
) >0)
3848 new_time_window
.start_time
= time_span
.start_time
;
3849 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
3850 new_time_window
.time_width
) ;
3854 if(ltt_time_compare(new_time_window
.end_time
,
3855 time_span
.end_time
) > 0
3856 || ltt_time_compare(new_time_window
.end_time
,
3857 time_span
.start_time
) < 0)
3859 new_time_window
.start_time
=
3860 ltt_time_sub(time_span
.end_time
, new_time_window
.time_width
);
3862 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
3863 new_time_window
.time_width
) ;
3869 if(ltt_time_compare(new_time_window
.time_width
, ltt_time_zero
) == 0) {
3870 g_warning("Zoom more than 1 ns impossible");
3872 time_change_manager(tab
, new_time_window
);
3878 void current_time_change_manager (Tab
*tab
,
3879 LttTime new_current_time
)
3881 /* Only one source of time change */
3882 if(tab
->current_time_manager_lock
== TRUE
) return;
3884 tab
->current_time_manager_lock
= TRUE
;
3886 LttvTracesetContext
*tsc
= LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3887 TimeInterval time_span
= tsc
->time_span
;
3889 /* current seconds */
3890 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry5
),
3891 (double)time_span
.start_time
.tv_sec
,
3892 (double)time_span
.end_time
.tv_sec
);
3893 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry5
),
3894 (double)new_current_time
.tv_sec
);
3897 /* start nanoseconds */
3898 if(new_current_time
.tv_sec
== time_span
.start_time
.tv_sec
) {
3899 /* can be both beginning and end at the same time. */
3900 if(new_current_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3901 /* If we are at the end, max nsec to end.. */
3902 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry6
),
3903 (double)time_span
.start_time
.tv_nsec
,
3904 (double)time_span
.end_time
.tv_nsec
);
3906 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry6
),
3907 (double)time_span
.start_time
.tv_nsec
,
3908 (double)NANOSECONDS_PER_SECOND
-1);
3910 } else if(new_current_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3911 /* If we are at the end, max nsec to end.. */
3912 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry6
),
3914 (double)time_span
.end_time
.tv_nsec
);
3915 } else /* anywhere else */
3916 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry6
),
3918 (double)NANOSECONDS_PER_SECOND
-1);
3920 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry6
),
3921 (double)new_current_time
.tv_nsec
);
3923 set_current_time(tab
, &new_current_time
);
3925 tab
->current_time_manager_lock
= FALSE
;
3928 void current_position_change_manager(Tab
*tab
,
3929 LttvTracesetContextPosition
*pos
)
3931 LttvTracesetContext
*tsc
=
3932 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3933 TimeInterval time_span
= tsc
->time_span
;
3936 retval
= lttv_process_traceset_seek_position(tsc
, pos
);
3937 g_assert_cmpint(retval
, ==, 0);
3938 LttTime new_time
= lttv_traceset_context_position_get_time(pos
);
3939 /* Put the context in a state coherent position */
3940 lttv_state_traceset_seek_time_closest((LttvTracesetState
*)tsc
, ltt_time_zero
);
3942 current_time_change_manager(tab
, new_time
);
3944 set_current_position(tab
, pos
);
3949 on_MEntry5_value_changed (GtkSpinButton
*spinbutton
,
3952 Tab
*tab
= (Tab
*)user_data
;
3953 LttvTracesetContext
* tsc
=
3954 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3955 TimeInterval time_span
= tsc
->time_span
;
3956 gint value
= gtk_spin_button_get_value_as_int(spinbutton
);
3957 LttTime new_current_time
= tab
->current_time
;
3958 new_current_time
.tv_sec
= value
;
3960 /* current nanoseconds */
3961 if(new_current_time
.tv_sec
== time_span
.start_time
.tv_sec
) {
3962 if(new_current_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3963 if(new_current_time
.tv_nsec
> time_span
.end_time
.tv_nsec
)
3964 new_current_time
.tv_nsec
= time_span
.end_time
.tv_nsec
;
3965 if(new_current_time
.tv_nsec
< time_span
.start_time
.tv_nsec
)
3966 new_current_time
.tv_nsec
= time_span
.start_time
.tv_nsec
;
3968 if(new_current_time
.tv_nsec
< time_span
.start_time
.tv_nsec
)
3969 new_current_time
.tv_nsec
= time_span
.start_time
.tv_nsec
;
3972 else if(new_current_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3973 if(new_current_time
.tv_nsec
> time_span
.end_time
.tv_nsec
)
3974 new_current_time
.tv_nsec
= time_span
.end_time
.tv_nsec
;
3977 current_time_change_manager(tab
, new_current_time
);
3981 on_MEntry6_value_changed (GtkSpinButton
*spinbutton
,
3984 Tab
*tab
= (Tab
*)user_data
;
3985 gint value
= gtk_spin_button_get_value_as_int(spinbutton
);
3986 LttTime new_current_time
= tab
->current_time
;
3987 new_current_time
.tv_nsec
= value
;
3989 current_time_change_manager(tab
, new_current_time
);
3993 void scroll_value_changed_cb(GtkWidget
*scrollbar
,
3996 Tab
*tab
= (Tab
*)user_data
;
3997 TimeWindow new_time_window
;
3999 GtkAdjustment
*adjust
= gtk_range_get_adjustment(GTK_RANGE(scrollbar
));
4000 gdouble value
= gtk_adjustment_get_value(adjust
);
4001 // gdouble upper, lower, ratio, page_size;
4003 LttvTracesetContext
* tsc
=
4004 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
4005 TimeInterval time_span
= tsc
->time_span
;
4007 time
= ltt_time_add(ltt_time_from_double(value
),
4008 time_span
.start_time
);
4010 new_time_window
.start_time
= time
;
4012 page_size
= adjust
->page_size
;
4014 new_time_window
.time_width
=
4015 ltt_time_from_double(page_size
);
4017 new_time_window
.time_width_double
=
4020 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
4021 new_time_window
.time_width
);
4024 time_change_manager(tab
, new_time_window
);
4026 //time_window = tab->time_window;
4028 lower
= adjust
->lower
;
4029 upper
= adjust
->upper
;
4030 ratio
= (value
- lower
) / (upper
- lower
);
4031 g_info("lower %lu, upper %lu, value %lu, ratio %lu", lower
, upper
, value
, ratio
);
4033 //time = ltt_time_sub(time_span->end_time, time_span->start_time);
4034 //time = ltt_time_mul(time, (float)ratio);
4035 //time = ltt_time_add(time_span->start_time, time);
4036 time
= ltt_time_add(ltt_time_from_double(value
),
4037 time_span
.start_time
);
4039 time_window
.start_time
= time
;
4041 page_size
= adjust
->page_size
;
4043 time_window
.time_width
=
4044 ltt_time_from_double(page_size
);
4045 //time = ltt_time_sub(time_span.end_time, time);
4046 //if(ltt_time_compare(time,time_window.time_width) < 0){
4047 // time_window.time_width = time;
4050 /* call viewer hooks for new time window */
4051 set_time_window(tab
, &time_window
);
4056 /* Display a dialogue showing all eventtypes and traces, let user to select the interested
4057 * eventtypes, tracefiles and traces (filter)
4060 /* Select a trace which will be removed from traceset
4063 char * get_remove_trace(MainWindow
*mw_data
,
4064 char ** all_trace_name
, int nb_trace
)
4066 return get_selection(mw_data
, all_trace_name
, nb_trace
,
4067 "Select a trace", "Trace pathname");
4071 /* Select a module which will be loaded
4074 char * get_load_module(MainWindow
*mw_data
,
4075 char ** load_module_name
, int nb_module
)
4077 return get_selection(mw_data
, load_module_name
, nb_module
,
4078 "Select a module to load", "Module name");
4084 /* Select a module which will be unloaded
4087 char * get_unload_module(MainWindow
*mw_data
,
4088 char ** loaded_module_name
, int nb_module
)
4090 return get_selection(mw_data
, loaded_module_name
, nb_module
,
4091 "Select a module to unload", "Module name");
4095 /* Display a dialogue which shows all selectable items, let user to
4096 * select one of them
4099 char * get_selection(MainWindow
*mw_data
,
4100 char ** loaded_module_name
, int nb_module
,
4101 char *title
, char * column_title
)
4103 GtkWidget
* dialogue
;
4104 GtkWidget
* scroll_win
;
4106 GtkListStore
* store
;
4107 GtkTreeViewColumn
* column
;
4108 GtkCellRenderer
* renderer
;
4109 GtkTreeSelection
* select
;
4112 char * unload_module_name
= NULL
;
4114 dialogue
= gtk_dialog_new_with_buttons(title
,
4117 GTK_STOCK_OK
,GTK_RESPONSE_ACCEPT
,
4118 GTK_STOCK_CANCEL
,GTK_RESPONSE_REJECT
,
4120 gtk_window_set_default_size((GtkWindow
*)dialogue
, 500, 200);
4121 gtk_window_set_transient_for(GTK_WINDOW(dialogue
),
4122 GTK_WINDOW(mw_data
->mwindow
));
4124 scroll_win
= gtk_scrolled_window_new (NULL
, NULL
);
4125 gtk_widget_show ( scroll_win
);
4126 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll_win
),
4127 GTK_POLICY_AUTOMATIC
, GTK_POLICY_AUTOMATIC
);
4129 store
= gtk_list_store_new (N_COLUMNS
,G_TYPE_STRING
);
4130 tree
= gtk_tree_view_new_with_model(GTK_TREE_MODEL (store
));
4131 gtk_widget_show ( tree
);
4132 g_object_unref (G_OBJECT (store
));
4134 renderer
= gtk_cell_renderer_text_new ();
4135 column
= gtk_tree_view_column_new_with_attributes (column_title
,
4137 "text", MODULE_COLUMN
,
4139 gtk_tree_view_column_set_alignment (column
, 0.5);
4140 gtk_tree_view_column_set_fixed_width (column
, 150);
4141 gtk_tree_view_append_column (GTK_TREE_VIEW (tree
), column
);
4143 select
= gtk_tree_view_get_selection (GTK_TREE_VIEW (tree
));
4144 gtk_tree_selection_set_mode (select
, GTK_SELECTION_SINGLE
);
4146 gtk_container_add (GTK_CONTAINER (scroll_win
), tree
);
4148 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialogue
)->vbox
), scroll_win
,TRUE
, TRUE
,0);
4150 for(i
=0;i
<nb_module
;i
++){
4151 gtk_list_store_append (store
, &iter
);
4152 gtk_list_store_set (store
, &iter
, MODULE_COLUMN
,loaded_module_name
[i
],-1);
4155 id
= gtk_dialog_run(GTK_DIALOG(dialogue
));
4156 GtkTreeModel
**store_model
= (GtkTreeModel
**)&store
;
4158 case GTK_RESPONSE_ACCEPT
:
4159 case GTK_RESPONSE_OK
:
4160 if (gtk_tree_selection_get_selected (select
, store_model
, &iter
)){
4161 gtk_tree_model_get ((GtkTreeModel
*)store
, &iter
, MODULE_COLUMN
, &unload_module_name
, -1);
4163 case GTK_RESPONSE_REJECT
:
4164 case GTK_RESPONSE_CANCEL
:
4166 gtk_widget_destroy(dialogue
);
4170 return unload_module_name
;
4174 /* Insert all menu entry and tool buttons into this main window
4179 void add_all_menu_toolbar_constructors(MainWindow
* mw
, gpointer user_data
)
4183 lttvwindow_viewer_constructor constructor
;
4184 LttvMenus
* global_menu
, * instance_menu
;
4185 LttvToolbars
* global_toolbar
, * instance_toolbar
;
4186 LttvMenuClosure
*menu_item
;
4187 LttvToolbarClosure
*toolbar_item
;
4188 LttvAttributeValue value
;
4189 LttvIAttribute
*global_attributes
= LTTV_IATTRIBUTE(lttv_global_attributes());
4190 LttvIAttribute
*attributes
= mw
->attributes
;
4191 GtkWidget
* tool_menu_title_menu
, *new_widget
, *pixmap
;
4194 retval
= lttv_iattribute_find_by_path(global_attributes
, "viewers/menu",
4195 LTTV_POINTER
, &value
);
4197 if(*(value
.v_pointer
) == NULL
)
4198 *(value
.v_pointer
) = lttv_menus_new();
4199 global_menu
= (LttvMenus
*)*(value
.v_pointer
);
4201 retval
= lttv_iattribute_find_by_path(attributes
, "viewers/menu",
4202 LTTV_POINTER
, &value
);
4204 if(*(value
.v_pointer
) == NULL
)
4205 *(value
.v_pointer
) = lttv_menus_new();
4206 instance_menu
= (LttvMenus
*)*(value
.v_pointer
);
4208 retval
= lttv_iattribute_find_by_path(global_attributes
, "viewers/toolbar",
4209 LTTV_POINTER
, &value
);
4211 if(*(value
.v_pointer
) == NULL
)
4212 *(value
.v_pointer
) = lttv_toolbars_new();
4213 global_toolbar
= (LttvToolbars
*)*(value
.v_pointer
);
4215 retval
= lttv_iattribute_find_by_path(attributes
, "viewers/toolbar",
4216 LTTV_POINTER
, &value
);
4218 if(*(value
.v_pointer
) == NULL
)
4219 *(value
.v_pointer
) = lttv_toolbars_new();
4220 instance_toolbar
= (LttvToolbars
*)*(value
.v_pointer
);
4222 /* Add missing menu entries to window instance */
4223 for(i
=0;i
<global_menu
->len
;i
++) {
4224 menu_item
= &g_array_index(global_menu
, LttvMenuClosure
, i
);
4226 //add menu_item to window instance;
4227 constructor
= menu_item
->con
;
4228 tool_menu_title_menu
= lookup_widget(mw
->mwindow
,"ToolMenuTitle_menu");
4230 gtk_menu_item_new_with_mnemonic (menu_item
->menu_text
);
4231 gtk_container_add (GTK_CONTAINER (tool_menu_title_menu
),
4233 g_signal_connect ((gpointer
) new_widget
, "activate",
4234 G_CALLBACK (insert_viewer_wrap
),
4236 gtk_widget_show (new_widget
);
4237 lttv_menus_add(instance_menu
, menu_item
->con
,
4238 menu_item
->menu_path
,
4239 menu_item
->menu_text
,
4244 /* Add missing toolbar entries to window instance */
4245 for(i
=0;i
<global_toolbar
->len
;i
++) {
4246 toolbar_item
= &g_array_index(global_toolbar
, LttvToolbarClosure
, i
);
4248 //add toolbar_item to window instance;
4249 constructor
= toolbar_item
->con
;
4250 tool_menu_title_menu
= lookup_widget(mw
->mwindow
,"MToolbar1");
4251 pixbuf
= gdk_pixbuf_new_from_xpm_data((const char**)toolbar_item
->pixmap
);
4252 pixmap
= gtk_image_new_from_pixbuf(pixbuf
);
4254 gtk_toolbar_append_element (GTK_TOOLBAR (tool_menu_title_menu
),
4255 GTK_TOOLBAR_CHILD_BUTTON
,
4258 toolbar_item
->tooltip
, NULL
,
4259 pixmap
, NULL
, NULL
);
4260 gtk_label_set_use_underline(
4261 GTK_LABEL (((GtkToolbarChild
*) (
4262 g_list_last (GTK_TOOLBAR
4263 (tool_menu_title_menu
)->children
)->data
))->label
),
4265 gtk_container_set_border_width (GTK_CONTAINER (new_widget
), 1);
4266 g_signal_connect ((gpointer
) new_widget
,
4268 G_CALLBACK (insert_viewer_wrap
),
4270 gtk_widget_show (new_widget
);
4272 lttv_toolbars_add(instance_toolbar
, toolbar_item
->con
,
4273 toolbar_item
->tooltip
,
4274 toolbar_item
->pixmap
,
4282 /* Create a main window
4285 MainWindow
*construct_main_window(MainWindow
* parent
)
4289 g_debug("construct_main_window()");
4290 GtkWidget
* new_window
; /* New generated main window */
4291 MainWindow
* new_m_window
;/* New main window structure */
4292 GtkNotebook
* notebook
;
4293 LttvIAttribute
*attributes
=
4294 LTTV_IATTRIBUTE(g_object_new(LTTV_ATTRIBUTE_TYPE
, NULL
));
4295 LttvAttributeValue value
;
4298 new_m_window
= g_new(MainWindow
, 1);
4300 // Add the object's information to the module's array
4301 g_main_window_list
= g_slist_append(g_main_window_list
, new_m_window
);
4303 new_window
= create_MWindow();
4304 gtk_widget_show (new_window
);
4306 new_m_window
->mwindow
= new_window
;
4307 new_m_window
->attributes
= attributes
;
4309 retval
= lttv_iattribute_find_by_path(attributes
, "viewers/menu",
4310 LTTV_POINTER
, &value
);
4312 *(value
.v_pointer
) = lttv_menus_new();
4314 retval
= lttv_iattribute_find_by_path(attributes
, "viewers/toolbar",
4315 LTTV_POINTER
, &value
);
4317 *(value
.v_pointer
) = lttv_toolbars_new();
4319 add_all_menu_toolbar_constructors(new_m_window
, NULL
);
4321 g_object_set_data_full(G_OBJECT(new_window
),
4323 (gpointer
)new_m_window
,
4324 (GDestroyNotify
)g_free
);
4325 //create a default tab
4326 notebook
= (GtkNotebook
*)lookup_widget(new_m_window
->mwindow
, "MNotebook");
4327 if(notebook
== NULL
){
4328 g_info("Notebook does not exist\n");
4329 /* FIXME : destroy partially created widgets */
4330 g_free(new_m_window
);
4333 //gtk_notebook_popup_enable (GTK_NOTEBOOK(notebook));
4334 //for now there is no name field in LttvTraceset structure
4335 //Use "Traceset" as the label for the default tab
4337 GtkWidget
* parent_notebook
= lookup_widget(parent
->mwindow
, "MNotebook");
4338 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(parent_notebook
),
4339 gtk_notebook_get_current_page(GTK_NOTEBOOK(parent_notebook
)));
4345 LttvPluginTab
*ptab
;
4346 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
4347 parent_tab
= ptab
->tab
;
4349 LttvPluginTab
*ptab
= g_object_new(LTTV_TYPE_PLUGIN_TAB
, NULL
);
4351 new_m_window
, parent_tab
, notebook
, "Traceset");
4352 ptab
->parent
.top_widget
= ptab
->tab
->top_widget
;
4353 g_object_set_data_full(
4354 G_OBJECT(ptab
->tab
->vbox
),
4357 (GDestroyNotify
)tab_destructor
);
4358 new_tab
= ptab
->tab
;
4360 LttvPluginTab
*ptab
= g_object_new(LTTV_TYPE_PLUGIN_TAB
, NULL
);
4361 init_tab(ptab
->tab
, new_m_window
, NULL
, notebook
, "Traceset");
4362 ptab
->parent
.top_widget
= ptab
->tab
->top_widget
;
4363 g_object_set_data_full(
4364 G_OBJECT(ptab
->tab
->vbox
),
4367 (GDestroyNotify
)tab_destructor
);
4368 new_tab
= ptab
->tab
;
4371 /* Insert default viewers */
4373 LttvAttributeType type
;
4374 LttvAttributeName name
;
4375 LttvAttributeValue value
;
4376 LttvAttribute
*attribute
;
4378 LttvIAttribute
*attributes_global
=
4379 LTTV_IATTRIBUTE(lttv_global_attributes());
4381 attribute
= LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
4382 LTTV_IATTRIBUTE(attributes_global
),
4383 LTTV_VIEWER_CONSTRUCTORS
));
4384 g_assert(attribute
);
4386 name
= g_quark_from_string("guievents");
4387 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
4389 if(type
== LTTV_POINTER
) {
4390 lttvwindow_viewer_constructor viewer_constructor
=
4391 (lttvwindow_viewer_constructor
)*value
.v_pointer
;
4392 insert_viewer(new_window
, viewer_constructor
);
4395 name
= g_quark_from_string("guicontrolflow");
4396 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
4398 if(type
== LTTV_POINTER
) {
4399 lttvwindow_viewer_constructor viewer_constructor
=
4400 (lttvwindow_viewer_constructor
)*value
.v_pointer
;
4401 insert_viewer(new_window
, viewer_constructor
);
4404 name
= g_quark_from_string("guistatistics");
4405 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
4407 if(type
== LTTV_POINTER
) {
4408 lttvwindow_viewer_constructor viewer_constructor
=
4409 (lttvwindow_viewer_constructor
)*value
.v_pointer
;
4410 insert_viewer(new_window
, viewer_constructor
);
4414 g_info("There are now : %d windows\n",g_slist_length(g_main_window_list
));
4416 return new_m_window
;
4420 /* Free the memory occupied by a tab structure
4424 void tab_destructor(LttvPluginTab
* ptab
)
4426 int i
, nb
, ref_count
;
4428 Tab
*tab
= ptab
->tab
;
4430 gtk_object_destroy(GTK_OBJECT(tab
->tooltips
));
4433 g_object_unref(tab
->attributes
);
4435 if(tab
->interrupted_state
)
4436 g_object_unref(tab
->interrupted_state
);
4439 if(tab
->traceset_info
->traceset_context
!= NULL
){
4440 //remove state update hooks
4441 lttv_state_remove_event_hooks(
4442 (LttvTracesetState
*)tab
->traceset_info
->
4444 lttv_context_fini(LTTV_TRACESET_CONTEXT(tab
->traceset_info
->
4446 g_object_unref(tab
->traceset_info
->traceset_context
);
4448 if(tab
->traceset_info
->traceset
!= NULL
) {
4449 nb
= lttv_traceset_number(tab
->traceset_info
->traceset
);
4450 for(i
= 0 ; i
< nb
; i
++) {
4451 trace
= lttv_traceset_get(tab
->traceset_info
->traceset
, i
);
4452 ref_count
= lttv_trace_get_ref_number(trace
);
4454 ltt_trace_close(lttv_trace(trace
));
4458 lttv_traceset_destroy(tab
->traceset_info
->traceset
);
4459 /* Remove the idle events requests processing function of the tab */
4460 g_idle_remove_by_data(tab
);
4462 g_slist_free(tab
->events_requests
);
4463 g_free(tab
->traceset_info
);
4465 g_object_unref(ptab
);
4469 /* Create a tab and insert it into the current main window
4472 void init_tab(Tab
*tab
, MainWindow
* mw
, Tab
*copy_tab
,
4473 GtkNotebook
* notebook
, char * label
)
4477 //LttvFilter *filter = NULL;
4479 //create a new tab data structure
4480 //tab = g_new(Tab,1);
4482 //construct and initialize the traceset_info
4483 tab
->traceset_info
= g_new(TracesetInfo
,1);
4486 tab
->traceset_info
->traceset
=
4487 lttv_traceset_copy(copy_tab
->traceset_info
->traceset
);
4489 /* Copy the previous tab's filter */
4490 /* We can clone the filter, as we copy the trace set also */
4491 /* The filter must always be in sync with the trace set */
4492 tab
->filter
= lttv_filter_clone(copy_tab
->filter
);
4494 tab
->traceset_info
->traceset
= lttv_traceset_new();
4498 lttv_attribute_write_xml(
4499 lttv_traceset_attribute(tab
->traceset_info
->traceset
),
4505 tab
->time_manager_lock
= FALSE
;
4506 tab
->current_time_manager_lock
= FALSE
;
4508 //FIXME copy not implemented in lower level
4509 tab
->traceset_info
->traceset_context
=
4510 g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
4511 g_assert(tab
->traceset_info
->traceset_context
!= NULL
);
4513 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
),
4514 tab
->traceset_info
->traceset
);
4515 //add state update hooks
4516 lttv_state_add_event_hooks(
4517 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
4519 //determine the current_time and time_window of the tab
4521 if(copy_tab
!= NULL
){
4522 tab
->time_window
= copy_tab
->time_window
;
4523 tab
->current_time
= copy_tab
->current_time
;
4525 tab
->time_window
.start_time
=
4526 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
4527 time_span
.start_time
;
4528 if(DEFAULT_TIME_WIDTH_S
<
4529 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
4530 time_span
.end_time
.tv_sec
)
4531 tmp_time
.tv_sec
= DEFAULT_TIME_WIDTH_S
;
4534 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
4535 time_span
.end_time
.tv_sec
;
4536 tmp_time
.tv_nsec
= 0;
4537 tab
->time_window
.time_width
= tmp_time
;
4538 tab
->current_time
.tv_sec
=
4539 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
4540 time_span
.start_time
.tv_sec
;
4541 tab
->current_time
.tv_nsec
=
4542 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
4543 time_span
.start_time
.tv_nsec
;
4546 tab
->attributes
= LTTV_IATTRIBUTE(g_object_new(LTTV_ATTRIBUTE_TYPE
, NULL
));
4547 tab
->interrupted_state
= g_object_new(LTTV_ATTRIBUTE_TYPE
, NULL
);
4549 tab
->vbox
= gtk_vbox_new(FALSE
, 2);
4550 tab
->top_widget
= tab
->vbox
;
4551 //g_object_set_data_full(G_OBJECT(tab->top_widget), "filter",
4552 // filter, (GDestroyNotify)lttv_filter_destroy);
4554 // g_signal_connect (G_OBJECT(tab->top_widget),
4556 // G_CALLBACK (on_top_notify),
4559 tab
->viewer_container
= gtk_vbox_new(TRUE
, 2);
4560 tab
->scrollbar
= gtk_hscrollbar_new(NULL
);
4561 //tab->multivpaned = gtk_multi_vpaned_new();
4563 gtk_box_pack_start(GTK_BOX(tab
->vbox
),
4564 tab
->viewer_container
,
4566 TRUE
, /* Give the extra space to the child */
4567 0); /* No padding */
4570 // tab->time_window = copy_tab->time_window;
4571 // tab->current_time = copy_tab->current_time;
4574 /* Create the timebar */
4576 tab
->MTimebar
= gtk_hbox_new(FALSE
, 2);
4577 gtk_widget_show(tab
->MTimebar
);
4578 tab
->tooltips
= gtk_tooltips_new();
4580 tab
->MEventBox1a
= gtk_event_box_new();
4581 gtk_widget_show(tab
->MEventBox1a
);
4582 gtk_tooltips_set_tip(tab
->tooltips
, tab
->MEventBox1a
,
4583 "Paste Start and End Times Here", "");
4584 tab
->MText1a
= gtk_label_new("Time Frame ");
4585 gtk_widget_show(tab
->MText1a
);
4586 gtk_container_add(GTK_CONTAINER(tab
->MEventBox1a
), tab
->MText1a
);
4587 tab
->MEventBox1b
= gtk_event_box_new();
4588 gtk_widget_show(tab
->MEventBox1b
);
4589 gtk_tooltips_set_tip(tab
->tooltips
, tab
->MEventBox1b
,
4590 "Paste Start Time Here", "");
4591 tab
->MText1b
= gtk_label_new("start: ");
4592 gtk_widget_show(tab
->MText1b
);
4593 gtk_container_add(GTK_CONTAINER(tab
->MEventBox1b
), tab
->MText1b
);
4594 tab
->MText2
= gtk_label_new("s");
4595 gtk_widget_show(tab
->MText2
);
4596 tab
->MText3a
= gtk_label_new("ns");
4597 gtk_widget_show(tab
->MText3a
);
4599 tab
->MEventBox3b
= gtk_event_box_new();
4600 gtk_widget_show(tab
->MEventBox3b
);
4601 gtk_tooltips_set_tip(tab
->tooltips
, tab
->MEventBox3b
,
4602 "Paste End Time Here", "");
4603 tab
->MText3b
= gtk_label_new("end:");
4604 gtk_widget_show(tab
->MText3b
);
4605 gtk_container_add(GTK_CONTAINER(tab
->MEventBox3b
), tab
->MText3b
);
4606 tab
->MText4
= gtk_label_new("s");
4607 gtk_widget_show(tab
->MText4
);
4608 tab
->MText5a
= gtk_label_new("ns");
4609 gtk_widget_show(tab
->MText5a
);
4611 tab
->MEventBox8
= gtk_event_box_new();
4612 gtk_widget_show(tab
->MEventBox8
);
4613 gtk_tooltips_set_tip(tab
->tooltips
, tab
->MEventBox8
,
4614 "Paste Time Interval here", "");
4615 tab
->MText8
= gtk_label_new("Time Interval:");
4616 gtk_widget_show(tab
->MText8
);
4617 gtk_container_add(GTK_CONTAINER(tab
->MEventBox8
), tab
->MText8
);
4618 tab
->MText9
= gtk_label_new("s");
4619 gtk_widget_show(tab
->MText9
);
4620 tab
->MText10
= gtk_label_new("ns");
4621 gtk_widget_show(tab
->MText10
);
4623 tab
->MEventBox5b
= gtk_event_box_new();
4624 gtk_widget_show(tab
->MEventBox5b
);
4625 gtk_tooltips_set_tip(tab
->tooltips
, tab
->MEventBox5b
,
4626 "Paste Current Time Here", "");
4627 tab
->MText5b
= gtk_label_new("Current Time:");
4628 gtk_widget_show(tab
->MText5b
);
4629 gtk_container_add(GTK_CONTAINER(tab
->MEventBox5b
), tab
->MText5b
);
4630 tab
->MText6
= gtk_label_new("s");
4631 gtk_widget_show(tab
->MText6
);
4632 tab
->MText7
= gtk_label_new("ns");
4633 gtk_widget_show(tab
->MText7
);
4635 tab
->MEntry1
= gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4636 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab
->MEntry1
),0);
4637 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab
->MEntry1
),TRUE
);
4638 gtk_widget_show(tab
->MEntry1
);
4639 tab
->MEntry2
= gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4640 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab
->MEntry2
),0);
4641 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab
->MEntry2
),TRUE
);
4642 gtk_widget_show(tab
->MEntry2
);
4643 tab
->MEntry3
= gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4644 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab
->MEntry3
),0);
4645 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab
->MEntry3
),TRUE
);
4646 gtk_widget_show(tab
->MEntry3
);
4647 tab
->MEntry4
= gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4648 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab
->MEntry4
),0);
4649 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab
->MEntry4
),TRUE
);
4650 gtk_widget_show(tab
->MEntry4
);
4651 tab
->MEntry5
= gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4652 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab
->MEntry5
),0);
4653 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab
->MEntry5
),TRUE
);
4654 gtk_widget_show(tab
->MEntry5
);
4655 tab
->MEntry6
= gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4656 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab
->MEntry6
),0);
4657 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab
->MEntry6
),TRUE
);
4658 gtk_widget_show(tab
->MEntry6
);
4659 tab
->MEntry7
= gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4660 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab
->MEntry7
),0);
4661 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab
->MEntry7
),TRUE
);
4662 gtk_widget_show(tab
->MEntry7
);
4663 tab
->MEntry8
= gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4664 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab
->MEntry8
),0);
4665 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab
->MEntry8
),TRUE
);
4666 gtk_widget_show(tab
->MEntry8
);
4668 GtkWidget
*temp_widget
;
4670 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEventBox1a
, FALSE
,
4672 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEventBox1b
, FALSE
,
4674 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEntry1
, FALSE
, FALSE
, 0);
4675 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MText2
, FALSE
, FALSE
, 0);
4676 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEntry2
, FALSE
, FALSE
, 0);
4677 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MText3a
, FALSE
, FALSE
, 0);
4678 temp_widget
= gtk_vseparator_new();
4679 gtk_widget_show(temp_widget
);
4680 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), temp_widget
, FALSE
, FALSE
, 0);
4681 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEventBox3b
, FALSE
,
4683 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEntry3
, FALSE
, FALSE
, 0);
4684 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MText4
, FALSE
, FALSE
, 0);
4685 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEntry4
, FALSE
, FALSE
, 0);
4686 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MText5a
, FALSE
, FALSE
, 0);
4687 temp_widget
= gtk_vseparator_new();
4688 gtk_widget_show(temp_widget
);
4689 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), temp_widget
, FALSE
, FALSE
, 0);
4690 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEventBox8
, FALSE
,
4692 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEntry7
, FALSE
, FALSE
, 0);
4693 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MText9
, FALSE
, FALSE
, 0);
4694 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEntry8
, FALSE
, FALSE
, 0);
4695 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MText10
, FALSE
, FALSE
, 0);
4697 temp_widget
= gtk_vseparator_new();
4698 gtk_widget_show(temp_widget
);
4699 gtk_box_pack_end (GTK_BOX (tab
->MTimebar
), tab
->MText7
, FALSE
, FALSE
, 0);
4700 gtk_box_pack_end (GTK_BOX (tab
->MTimebar
), tab
->MEntry6
, FALSE
, FALSE
, 0);
4701 gtk_box_pack_end (GTK_BOX (tab
->MTimebar
), tab
->MText6
, FALSE
, FALSE
, 0);
4702 gtk_box_pack_end (GTK_BOX (tab
->MTimebar
), tab
->MEntry5
, FALSE
, FALSE
, 0);
4703 gtk_box_pack_end (GTK_BOX (tab
->MTimebar
), tab
->MEventBox5b
, FALSE
,
4705 gtk_box_pack_end (GTK_BOX (tab
->MTimebar
), temp_widget
, FALSE
, FALSE
, 0);
4708 //GtkWidget *test = gtk_button_new_with_label("drop");
4709 //gtk_button_set_relief(GTK_BUTTON(test), GTK_RELIEF_NONE);
4710 //gtk_widget_show(test);
4711 //gtk_box_pack_end(GTK_BOX (tab->MTimebar), test, FALSE, FALSE, 0);
4712 //gtk_widget_add_events(tab->MText1, GDK_ALL_EVENTS_MASK);//GDK_BUTTON_PRESS_MASK);
4713 /*GtkWidget *event_box = gtk_event_box_new();
4714 gtk_widget_show(event_box);
4715 gtk_tooltips_set_tip(tooltips, event_box,
4716 "Paste Current Time Here", "");
4717 gtk_box_pack_end(GTK_BOX (tab->MTimebar), event_box, FALSE, FALSE, 0);
4718 GtkWidget *test = gtk_label_new("drop");
4719 gtk_container_add(GTK_CONTAINER(event_box), test);
4720 gtk_widget_show(test);
4721 g_signal_connect (G_OBJECT(event_box),
4722 "button-press-event",
4723 G_CALLBACK (on_MText1_paste),
4727 g_signal_connect (G_OBJECT(tab
->MEventBox1a
),
4728 "button-press-event",
4729 G_CALLBACK (on_MEventBox1a_paste
),
4732 g_signal_connect (G_OBJECT(tab
->MEventBox1b
),
4733 "button-press-event",
4734 G_CALLBACK (on_MEventBox1b_paste
),
4736 g_signal_connect (G_OBJECT(tab
->MEventBox3b
),
4737 "button-press-event",
4738 G_CALLBACK (on_MEventBox3b_paste
),
4740 g_signal_connect (G_OBJECT(tab
->MEventBox5b
),
4741 "button-press-event",
4742 G_CALLBACK (on_MEventBox5b_paste
),
4744 g_signal_connect (G_OBJECT(tab
->MEventBox8
),
4745 "button-press-event",
4746 G_CALLBACK (on_MEventBox8_paste
),
4750 gtk_box_pack_end(GTK_BOX(tab
->vbox
),
4752 FALSE
, /* Do not expand */
4753 FALSE
, /* Fill has no effect here (expand false) */
4754 0); /* No padding */
4756 gtk_box_pack_end(GTK_BOX(tab
->vbox
),
4758 FALSE
, /* Do not expand */
4759 FALSE
, /* Fill has no effect here (expand false) */
4760 0); /* No padding */
4762 g_object_set_data(G_OBJECT(tab
->viewer_container
), "focused_viewer", NULL
);
4768 // Display a label with a X
4769 GtkWidget *w_hbox = gtk_hbox_new(FALSE, 4);
4770 GtkWidget *w_label = gtk_label_new (label);
4771 GtkWidget *pixmap = create_pixmap(GTK_WIDGET(notebook), "close.png");
4772 GtkWidget *w_button = gtk_button_new ();
4773 gtk_container_add(GTK_CONTAINER(w_button), pixmap);
4774 //GtkWidget *w_button = gtk_button_new_with_label("x");
4776 gtk_button_set_relief(GTK_BUTTON(w_button), GTK_RELIEF_NONE);
4778 gtk_box_pack_start(GTK_BOX(w_hbox), w_label, TRUE, TRUE, 0);
4779 gtk_box_pack_end(GTK_BOX(w_hbox), w_button, FALSE,
4782 g_signal_connect_swapped (w_button, "clicked",
4783 G_CALLBACK (on_close_tab_X_clicked),
4786 gtk_widget_set_state(w_button, GTK_STATE_ACTIVE);
4788 gtk_widget_show (w_label);
4789 gtk_widget_show (pixmap);
4790 gtk_widget_show (w_button);
4791 gtk_widget_show (w_hbox);
4793 tab->label = w_hbox;
4797 tab
->label
= gtk_label_new (label
);
4799 gtk_widget_show(tab
->label
);
4800 gtk_widget_show(tab
->scrollbar
);
4801 gtk_widget_show(tab
->viewer_container
);
4802 gtk_widget_show(tab
->vbox
);
4803 //gtk_widget_show(tab->multivpaned);
4806 /* Start with empty events requests list */
4807 tab
->events_requests
= NULL
;
4808 tab
->events_request_pending
= FALSE
;
4809 tab
->stop_foreground
= FALSE
;
4813 g_signal_connect(G_OBJECT(tab
->scrollbar
), "value-changed",
4814 G_CALLBACK(scroll_value_changed_cb
), tab
);
4816 g_signal_connect ((gpointer
) tab
->MEntry1
, "value-changed",
4817 G_CALLBACK (on_MEntry1_value_changed
),
4819 g_signal_connect ((gpointer
) tab
->MEntry2
, "value-changed",
4820 G_CALLBACK (on_MEntry2_value_changed
),
4822 g_signal_connect ((gpointer
) tab
->MEntry3
, "value-changed",
4823 G_CALLBACK (on_MEntry3_value_changed
),
4825 g_signal_connect ((gpointer
) tab
->MEntry4
, "value-changed",
4826 G_CALLBACK (on_MEntry4_value_changed
),
4828 g_signal_connect ((gpointer
) tab
->MEntry5
, "value-changed",
4829 G_CALLBACK (on_MEntry5_value_changed
),
4831 g_signal_connect ((gpointer
) tab
->MEntry6
, "value-changed",
4832 G_CALLBACK (on_MEntry6_value_changed
),
4834 g_signal_connect ((gpointer
) tab
->MEntry7
, "value-changed",
4835 G_CALLBACK (on_MEntry7_value_changed
),
4837 g_signal_connect ((gpointer
) tab
->MEntry8
, "value-changed",
4838 G_CALLBACK (on_MEntry8_value_changed
),
4841 //g_signal_connect(G_OBJECT(tab->scrollbar), "changed",
4842 // G_CALLBACK(scroll_value_changed_cb), tab);
4845 //insert tab into notebook
4846 gtk_notebook_append_page(notebook
,
4849 list
= gtk_container_get_children(GTK_CONTAINER(notebook
));
4850 gtk_notebook_set_current_page(notebook
,g_list_length(list
)-1);
4851 // always show : not if(g_list_length(list)>1)
4852 gtk_notebook_set_show_tabs(notebook
, TRUE
);
4855 lttvwindow_report_time_window(tab
, copy_tab
->time_window
);
4856 lttvwindow_report_current_time(tab
, copy_tab
->current_time
);
4858 TimeWindow time_window
;
4860 time_window
.start_time
= ltt_time_zero
;
4861 time_window
.end_time
= ltt_time_add(time_window
.start_time
,
4862 lttvwindow_default_time_width
);
4863 time_window
.time_width
= lttvwindow_default_time_width
;
4864 time_window
.time_width_double
= ltt_time_to_double(time_window
.time_width
);
4866 lttvwindow_report_time_window(tab
, time_window
);
4867 lttvwindow_report_current_time(tab
, ltt_time_zero
);
4870 LttvTraceset
*traceset
= tab
->traceset_info
->traceset
;
4871 SetTraceset(tab
, traceset
);
4875 * execute_events_requests
4877 * Idle function that executes the pending requests for a tab.
4879 * @return return value : TRUE : keep the idle function, FALSE : remove it.
4881 gboolean
execute_events_requests(Tab
*tab
)
4883 return ( lttvwindow_process_pending_requests(tab
) );
4887 __EXPORT
void create_main_window_with_trace_list(GSList
*traces
)
4889 GSList
*iter
= NULL
;
4892 MainWindow
*mw
= construct_main_window(NULL
);
4893 GtkWidget
*widget
= mw
->mwindow
;
4895 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
4896 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
4897 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
4898 LttvPluginTab
*ptab
;
4902 ptab
= create_new_tab(widget
, NULL
);
4905 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
4909 for(iter
=traces
; iter
!=NULL
; iter
=g_slist_next(iter
)) {
4910 gchar
*path
= (gchar
*)iter
->data
;
4912 gchar abs_path
[PATH_MAX
];
4916 get_absolute_pathname(path
, abs_path
);
4917 trace_v
= lttvwindowtraces_get_trace_by_name(abs_path
);
4918 if(trace_v
== NULL
) {
4919 trace
= ltt_trace_open(abs_path
);
4921 g_warning("cannot open trace %s", abs_path
);
4923 GtkWidget
*dialogue
=
4924 gtk_message_dialog_new(
4925 GTK_WINDOW(gtk_widget_get_toplevel(widget
)),
4926 GTK_DIALOG_MODAL
|GTK_DIALOG_DESTROY_WITH_PARENT
,
4929 "Cannot open trace : maybe you should enter in the directory "
4931 gtk_dialog_run(GTK_DIALOG(dialogue
));
4932 gtk_widget_destroy(dialogue
);
4934 trace_v
= lttv_trace_new(trace
);
4935 lttvwindowtraces_add_trace(trace_v
);
4936 lttvwindow_add_trace(tab
, trace_v
);
4939 lttvwindow_add_trace(tab
, trace_v
);
4943 LttvTraceset
*traceset
;
4945 traceset
= tab
->traceset_info
->traceset
;
4946 SetTraceset(tab
, traceset
);