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/traceset.h>
42 #include <lttv/stats.h>
43 #include <lttv/sync/sync_chain_lttv.h>
44 #endif /* BABEL_CLEANUP */
45 #include <lttv/filter.h>
46 #include <lttvwindow/mainwindow.h>
47 #include <lttvwindow/mainwindow-private.h>
48 #include <lttvwindow/menu.h>
49 #include <lttvwindow/timebar.h>
50 #include <lttvwindow/toolbar.h>
51 #include <lttvwindow/lttvwindow.h>
52 #include <lttvwindow/lttvwindowtraces.h>
53 #include <lttvwindow/lttv_plugin_tab.h>
55 #include <babeltrace/babeltrace.h>
56 #include <babeltrace/ctf/events.h>
57 #include <babeltrace/ctf/iterator.h>
59 static LttTime lttvwindow_default_time_width
= { 1, 0 };
60 #define CLIP_BUF 256 // size of clipboard buffer
62 extern LttvTrace
*g_init_trace
;
65 /** Array containing instanced objects. */
66 extern GSList
* g_main_window_list
;
68 /** MD : keep old directory. */
69 static char remember_plugins_dir
[PATH_MAX
] = "";
70 static char remember_trace_dir
[PATH_MAX
] = "";
72 void tab_destructor(LttvPluginTab
* ptab
);
74 MainWindow
* get_window_data_struct(GtkWidget
* widget
);
75 char * get_load_module(MainWindow
*mw
,
76 char ** load_module_name
, int nb_module
);
77 char * get_unload_module(MainWindow
*mw
,
78 char ** loaded_module_name
, int nb_module
);
79 char * get_remove_trace(MainWindow
*mw
, char ** all_trace_name
, int nb_trace
);
80 char * get_selection(MainWindow
*mw
,
81 char ** all_name
, int nb
, char *title
, char * column_title
);
82 void init_tab(Tab
*tab
, MainWindow
* mw
, Tab
*copy_tab
,
83 GtkNotebook
* notebook
, char * label
);
85 int update_traceset(Tab
*tab
, LttvTraceset
*traceset
);
87 static void insert_viewer(GtkWidget
* widget
, lttvwindow_viewer_constructor constructor
);
89 LttvPluginTab
*create_new_tab(GtkWidget
* widget
, gpointer user_data
);
91 static gboolean
lttvwindow_process_pending_requests(Tab
*tab
);
93 static void on_timebar_starttime_changed(Timebar
*timebar
,
95 static void on_timebar_endtime_changed(Timebar
*timebar
,
97 static void on_timebar_currenttime_changed(Timebar
*timebar
,
114 static void on_top_notify(GObject
*gobject
,
118 Tab
*tab
= (Tab
*)user_data
;
119 g_message("in on_top_notify.\n");
123 static gboolean
viewer_grab_focus(GtkWidget
*widget
, GdkEventButton
*event
,
126 GtkWidget
*viewer
= GTK_WIDGET(data
);
127 GtkWidget
*viewer_container
= gtk_widget_get_parent(viewer
);
129 g_debug("FOCUS GRABBED");
130 g_object_set_data(G_OBJECT(viewer_container
), "focused_viewer", viewer
);
135 static void connect_focus_recursive(GtkWidget
*widget
,
138 if(GTK_IS_CONTAINER(widget
)) {
139 gtk_container_forall(GTK_CONTAINER(widget
),
140 (GtkCallback
)connect_focus_recursive
,
144 if(GTK_IS_TREE_VIEW(widget
)) {
145 gtk_tree_view_set_headers_clickable(GTK_TREE_VIEW(widget
), TRUE
);
147 gtk_widget_add_events(widget
, GDK_BUTTON_PRESS_MASK
);
148 g_signal_connect (G_OBJECT(widget
),
149 "button-press-event",
150 G_CALLBACK (viewer_grab_focus
),
154 /* Stop all the processings and call gtk_main_quit() */
155 static void mainwindow_quit()
157 lttvwindowtraces_unregister_requests(g_quark_from_string("stats"));
158 lttvwindowtraces_unregister_requests(g_quark_from_string("state"));
159 lttvwindowtraces_unregister_computation_hooks(g_quark_from_string("stats"));
160 lttvwindowtraces_unregister_computation_hooks(g_quark_from_string("state"));
166 /* insert_viewer function constructs an instance of a viewer first,
167 * then inserts the widget of the instance into the container of the
172 insert_viewer_wrap(GtkWidget
*menuitem
, gpointer user_data
)
174 insert_viewer((GtkWidget
*)menuitem
, (lttvwindow_viewer_constructor
)user_data
);
178 /* internal functions */
179 void insert_viewer(GtkWidget
* widget
, lttvwindow_viewer_constructor constructor
)
181 GtkWidget
* viewer_container
;
182 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
184 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
185 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
190 ptab
= create_new_tab(widget
, NULL
);
192 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
196 viewer_container
= tab
->viewer_container
;
198 viewer
= (GtkWidget
*)constructor(&ptab
->parent
);
201 //gtk_multivpaned_widget_add(GTK_MULTIVPANED(multivpaned), viewer);
203 gtk_box_pack_end(GTK_BOX(viewer_container
),
209 /* We want to connect the viewer_grab_focus to EVERY
210 * child of this widget. The little trick is to get each child
211 * of each GTK_CONTAINER, even subchildren.
213 connect_focus_recursive(viewer
, viewer
);
218 * Function to set/update traceset for the viewers
219 * @param tab viewer's tab
220 * @param traceset traceset of the main window.
222 * 0 : traceset updated
223 * 1 : no traceset hooks to update; not an error.
226 int SetTraceset(Tab
* tab
, LttvTraceset
*traceset
)
230 TimeInterval time_span
;
231 TimeWindow new_time_window
;
232 LttTime new_current_time
;
235 // Perform time synchronization on the traces
236 if (syncTraceset(tsc
))
238 /* There is some time-dependant information that was calculated during
239 * context initialization. Destroy the old contexts and initialize new
241 * Modified from lttvwindow_add_trace()
243 // Keep a reference to the traces so they are not freed
244 for(i
= 0; i
< lttv_traceset_number(traceset
); i
++)
246 LttvTrace
*trace
= lttv_traceset_get(traceset
, i
);
247 lttv_trace_ref(trace
);
250 // Remove state update hooks
251 lttv_state_remove_event_hooks(
252 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
254 lttv_context_fini(LTTV_TRACESET_CONTEXT(
255 tab
->traceset_info
->traceset_context
));
256 g_object_unref(tab
->traceset_info
->traceset_context
);
258 for(i
= 0; i
< lttv_traceset_number(traceset
); i
++)
260 LttvTrace
*trace
= lttv_traceset_get(traceset
, i
);
261 lttvwindowtraces_remove_trace(trace
);
262 lttvwindowtraces_add_trace(trace
);
265 // Create new context
266 tab
->traceset_info
->traceset_context
=
267 g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
268 lttv_context_init(LTTV_TRACESET_CONTEXT(tab
->traceset_info
->
269 traceset_context
), traceset
);
271 // Add state update hooks
272 lttv_state_add_event_hooks(
273 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
275 // Remove local reference to the traces
276 for(i
=0; i
<lttv_traceset_number(traceset
); i
++)
278 LttvTrace
*trace
= lttv_traceset_get(traceset
, i
);
279 lttv_trace_unref(trace
);
282 tsc
= LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
284 #endif /*BABEL_CLEANUP*/
287 time_span
.start_time
=ltt_time_from_uint64( lttv_traceset_get_timestamp_begin(traceset
));
288 time_span
.end_time
= ltt_time_from_uint64(lttv_traceset_get_timestamp_end(traceset
));
290 tab
->traceset_info
->traceset
= traceset
;
292 new_time_window
= tab
->time_window
;
293 new_current_time
= tab
->current_time
;
295 /* Set the tab's time window and current time if
297 if(ltt_time_compare(tab
->time_window
.start_time
, time_span
.start_time
) < 0
298 || ltt_time_compare(tab
->time_window
.end_time
,
299 time_span
.end_time
) > 0) {
300 new_time_window
.start_time
= time_span
.start_time
;
302 new_current_time
= time_span
.start_time
;
306 if(ltt_time_compare(lttvwindow_default_time_width
,
307 ltt_time_sub(time_span
.end_time
, time_span
.start_time
)) < 0
309 ltt_time_compare(time_span
.end_time
, time_span
.start_time
) == 0)
310 tmp_time
= lttvwindow_default_time_width
;
312 tmp_time
= time_span
.end_time
;
314 new_time_window
.time_width
= tmp_time
;
315 new_time_window
.time_width_double
= ltt_time_to_double(tmp_time
);
316 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
317 new_time_window
.time_width
) ;
320 /* Finally, call the update hooks of the viewers */
321 gint retval
= update_traceset(tab
, traceset
);
323 time_change_manager(tab
, new_time_window
);
324 current_time_change_manager(tab
, new_current_time
);
331 * Function to set/update filter for the viewers
332 * @param tab viewer's tab
333 * @param filter filter of the main window.
336 * 0 : filters updated
337 * 1 : no filter hooks to update; not an error.
340 int SetFilter(Tab
* tab
, gpointer filter
)
343 LttvAttributeValue value
;
345 g_assert(lttv_iattribute_find_by_path(tab
->attributes
,
346 "hooks/updatefilter", LTTV_POINTER
, &value
));
348 tmp
= (LttvHooks
*)*(value
.v_pointer
);
350 if(tmp
== NULL
) return 1;
351 lttv_hooks_call(tmp
,filter
);
359 * Function to redraw each viewer belonging to the current tab
360 * @param tab viewer's tab
363 int update_traceset(Tab
*tab
, LttvTraceset
*traceset
)
365 LttvAttributeValue value
;
369 retval
= lttv_iattribute_find_by_path(tab
->attributes
,
370 "hooks/updatetraceset",
374 tmp
= (LttvHooks
*)*(value
.v_pointer
);
378 lttv_hooks_call(tmp
, traceset
);
384 Call hooks register to get update on traceset time span changes
386 int notify_time_span_changed(Tab
*tab
)
388 LttvAttributeValue value
;
392 retval
= lttv_iattribute_find_by_path(tab
->attributes
,
393 "hooks/updatetimespan",
397 tmp
= (LttvHooks
*)*(value
.v_pointer
);
401 lttv_hooks_call(tmp
, NULL
);
406 /* get_label function is used to get user input, it displays an input
407 * box, which allows user to input a string
410 void get_label_string (GtkWidget
* text
, gchar
* label
)
412 GtkEntry
* entry
= (GtkEntry
*)text
;
413 if(strlen(gtk_entry_get_text(entry
))!=0)
414 strcpy(label
,gtk_entry_get_text(entry
));
417 gboolean
get_label(MainWindow
* mw
, gchar
* str
, gchar
* dialogue_title
, gchar
* label_str
)
419 GtkWidget
* dialogue
;
424 dialogue
= gtk_dialog_new_with_buttons(dialogue_title
,NULL
,
426 GTK_STOCK_OK
,GTK_RESPONSE_ACCEPT
,
427 GTK_STOCK_CANCEL
,GTK_RESPONSE_REJECT
,
430 label
= gtk_label_new(label_str
);
431 gtk_widget_show(label
);
433 text
= gtk_entry_new();
434 gtk_widget_show(text
);
436 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialogue
)->vbox
), label
,TRUE
, TRUE
,0);
437 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialogue
)->vbox
), text
,FALSE
, FALSE
,0);
439 id
= gtk_dialog_run(GTK_DIALOG(dialogue
));
441 case GTK_RESPONSE_ACCEPT
:
442 get_label_string(text
,str
);
443 gtk_widget_destroy(dialogue
);
445 case GTK_RESPONSE_REJECT
:
447 gtk_widget_destroy(dialogue
);
454 /* get_window_data_struct function is actually a lookup function,
455 * given a widget which is in the tree of the main window, it will
456 * return the MainWindow data structure associated with main window
459 MainWindow
* get_window_data_struct(GtkWidget
* widget
)
462 MainWindow
* mw_data
;
464 mw
= lookup_widget(widget
, "MWindow");
466 g_info("Main window does not exist\n");
470 mw_data
= (MainWindow
*) g_object_get_data(G_OBJECT(mw
),"main_window_data");
472 g_warning("Main window data does not exist\n");
479 /* create_new_window function, just constructs a new main window
482 void create_new_window(GtkWidget
* widget
, gpointer user_data
, gboolean clone
)
484 MainWindow
* parent
= get_window_data_struct(widget
);
487 g_info("Clone : use the same traceset\n");
488 construct_main_window(parent
);
490 g_info("Empty : traceset is set to NULL\n");
491 construct_main_window(NULL
);
495 /* Get the currently focused viewer.
496 * If no viewer is focused, use the first one.
498 * If no viewer available, return NULL.
500 GtkWidget
*viewer_container_focus(GtkWidget
*container
)
504 widget
= (GtkWidget
*)g_object_get_data(G_OBJECT(container
),
508 g_debug("no widget focused");
509 GList
*children
= gtk_container_get_children(GTK_CONTAINER(container
));
512 widget
= GTK_WIDGET(children
->data
);
513 g_object_set_data(G_OBJECT(container
),
523 gint
viewer_container_position(GtkWidget
*container
, GtkWidget
*child
)
526 if(child
== NULL
) return -1;
530 memset(&value
, 0, sizeof(GValue
));
531 g_value_init(&value
, G_TYPE_INT
);
532 gtk_container_child_get_property(GTK_CONTAINER(container
),
536 pos
= g_value_get_int(&value
);
542 /* move_*_viewer functions move the selected view up/down in
546 void move_down_viewer(GtkWidget
* widget
, gpointer user_data
)
548 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
550 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
551 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
558 ptab
= g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
562 //gtk_multivpaned_widget_move_up(GTK_MULTIVPANED(tab->multivpaned));
564 /* change the position in the vbox */
565 GtkWidget
*focus_widget
;
567 focus_widget
= viewer_container_focus(tab
->viewer_container
);
568 position
= viewer_container_position(tab
->viewer_container
, focus_widget
);
571 /* can move up one position */
572 gtk_box_reorder_child(GTK_BOX(tab
->viewer_container
),
579 void move_up_viewer(GtkWidget
* widget
, gpointer user_data
)
581 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
583 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
584 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
591 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
595 //gtk_multivpaned_widget_move_down(GTK_MULTIVPANED(tab->multivpaned));
596 /* change the position in the vbox */
597 GtkWidget
*focus_widget
;
599 focus_widget
= viewer_container_focus(tab
->viewer_container
);
600 position
= viewer_container_position(tab
->viewer_container
, focus_widget
);
604 g_list_length(gtk_container_get_children(
605 GTK_CONTAINER(tab
->viewer_container
)))-1
607 /* can move down one position */
608 gtk_box_reorder_child(GTK_BOX(tab
->viewer_container
),
616 /* delete_viewer deletes the selected viewer in the current tab
619 void delete_viewer(GtkWidget
* widget
, gpointer user_data
)
621 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
623 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
624 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
631 ptab
= g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
635 //gtk_multivpaned_widget_delete(GTK_MULTIVPANED(tab->multivpaned));
637 GtkWidget
*focus_widget
= viewer_container_focus(tab
->viewer_container
);
639 if(focus_widget
!= NULL
)
640 gtk_widget_destroy(focus_widget
);
642 g_object_set_data(G_OBJECT(tab
->viewer_container
), "focused_viewer", NULL
);
645 #if UNFINISHED_FEATURE
646 /* TODO ybrosseau 2012-03-15: Function is half implemented. Should be removed */
647 /* open_traceset will open a traceset saved in a file
648 * Right now, it is not finished yet, (not working)
652 void open_traceset(GtkWidget
* widget
, gpointer user_data
)
656 LttvTraceset
* traceset
;
657 MainWindow
* mw_data
= get_window_data_struct(widget
);
658 GtkFileSelection
* file_selector
=
659 (GtkFileSelection
*)gtk_file_selection_new("Select a traceset");
661 gtk_file_selection_hide_fileop_buttons(file_selector
);
663 gtk_window_set_transient_for(GTK_WINDOW(file_selector
),
664 GTK_WINDOW(mw_data
->mwindow
));
666 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
668 case GTK_RESPONSE_ACCEPT
:
669 case GTK_RESPONSE_OK
:
670 dir
= gtk_file_selection_get_selections (file_selector
);
671 traceset
= lttv_traceset_load(dir
[0]);
672 g_info("Open a trace set %s\n", dir
[0]);
675 case GTK_RESPONSE_REJECT
:
676 case GTK_RESPONSE_CANCEL
:
678 gtk_widget_destroy((GtkWidget
*)file_selector
);
684 /* lttvwindow_process_pending_requests
686 * Process requests for parts of the trace from viewers.
688 * These requests are made by lttvwindow_events_request().
690 * This internal function gets called by g_idle, taking care of the pending
691 * requests. It is responsible for concatenation of time intervals and position
692 * requests. It does it with the following algorithm organizing process traceset
693 * calls. Here is the detailed description of the way it works :
695 * - Events Requests Servicing Algorithm
697 * Data structures necessary :
699 * List of requests added to context : list_in
700 * List of requests not added to context : list_out
705 * list_out : many events requests
707 * FIXME : insert rest of algorithm here
711 #define list_out tab->events_requests
713 gboolean
lttvwindow_process_pending_requests(Tab
*tab
)
716 LttvTracesetContext
*tsc
;
717 LttvTracefileContext
*tfc
;
718 GSList
*list_in
= NULL
;
722 LttvTracesetContextPosition
*end_position
;
724 if(lttvwindow_preempt_count
> 0) return TRUE
;
727 g_critical("Foreground processing : tab does not exist. Processing removed.");
731 /* There is no events requests pending : we should never have been called! */
732 g_assert(g_slist_length(list_out
) != 0);
734 tsc
= LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
736 //set the cursor to be X shape, indicating that the computer is busy in doing its job
738 new = gdk_cursor_new(GDK_X_CURSOR
);
739 widget
= lookup_widget(tab
->mw
->mwindow
, "MToolbar1");
740 win
= gtk_widget_get_parent_window(widget
);
741 gdk_window_set_cursor(win
, new);
742 gdk_cursor_unref(new);
743 gdk_window_stick(win
);
744 gdk_window_unstick(win
);
747 g_debug("SIZE events req len : %d", g_slist_length(list_out
));
749 /* Preliminary check for no trace in traceset */
750 /* Unregister the routine if empty, empty list_out too */
751 if(lttv_traceset_number(tsc
->ts
) == 0) {
753 /* - For each req in list_out */
754 GSList
*iter
= list_out
;
756 while(iter
!= NULL
) {
758 gboolean remove
= FALSE
;
759 gboolean free_data
= FALSE
;
760 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
762 /* - Call end request for req */
763 if(events_request
->servicing
== TRUE
)
764 lttv_hooks_call(events_request
->after_request
, (gpointer
)tsc
);
766 /* - remove req from list_out */
767 /* Destroy the request */
774 GSList
*remove_iter
= iter
;
776 iter
= g_slist_next(iter
);
777 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
778 list_out
= g_slist_remove_link(list_out
, remove_iter
);
779 } else { // not remove
780 iter
= g_slist_next(iter
);
785 /* 0.1 Lock Traces */
790 iter_trace
<lttv_traceset_number(tsc
->ts
);
792 LttvTrace
*trace_v
= lttv_traceset_get(tsc
->ts
, iter_trace
);
794 if(lttvwindowtraces_lock(trace_v
) != 0) {
795 g_critical("Foreground processing : Unable to get trace lock");
796 return TRUE
; /* Cannot get lock, try later */
801 /* 0.2 Seek tracefiles positions to context position */
802 //g_assert(lttv_process_traceset_seek_position(tsc, sync_position) == 0);
803 lttv_process_traceset_synchronize_tracefiles(tsc
);
806 /* Events processing algorithm implementation */
807 /* Warning : the gtk_events_pending takes a LOT of cpu time. So what we do
808 * instead is to leave the control to GTK and take it back.
810 /* A. Servicing loop */
811 //while( (g_slist_length(list_in) != 0 || g_slist_length(list_out) != 0)) {
812 if((g_slist_length(list_in
) != 0 || g_slist_length(list_out
) != 0)) {
814 /* 1. If list_in is empty (need a seek) */
815 if( g_slist_length(list_in
) == 0 ) {
817 /* list in is empty, need a seek */
819 /* 1.1 Add requests to list_in */
820 GSList
*ltime
= NULL
;
824 /* 1.1.1 Find all time requests with the lowest start time in list_out
827 if(g_slist_length(list_out
) > 0)
828 ltime
= g_slist_append(ltime
, g_slist_nth_data(list_out
, 0));
829 for(iter
=g_slist_nth(list_out
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
830 /* Find all time requests with the lowest start time in list_out */
831 EventsRequest
*event_request_ltime
= (EventsRequest
*)g_slist_nth_data(ltime
, 0);
832 EventsRequest
*event_request_list_out
= (EventsRequest
*)iter
->data
;
835 comp
= ltt_time_compare(event_request_ltime
->start_time
,
836 event_request_list_out
->start_time
);
838 ltime
= g_slist_append(ltime
, event_request_list_out
);
840 /* Remove all elements from ltime, and add current */
842 ltime
= g_slist_delete_link(ltime
, g_slist_nth(ltime
, 0));
843 ltime
= g_slist_append(ltime
, event_request_list_out
);
847 /* 1.1.2 Find all position requests with the lowest position in list_out
850 if(g_slist_length(list_out
) > 0)
851 lpos
= g_slist_append(lpos
, g_slist_nth_data(list_out
, 0));
852 for(iter
=g_slist_nth(list_out
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
853 /* Find all position requests with the lowest position in list_out */
854 EventsRequest
*event_request_lpos
= (EventsRequest
*)g_slist_nth_data(lpos
, 0);
855 EventsRequest
*event_request_list_out
= (EventsRequest
*)iter
->data
;
858 if(event_request_lpos
->start_position
!= NULL
859 && event_request_list_out
->start_position
!= NULL
)
861 comp
= lttv_traceset_context_pos_pos_compare
862 (event_request_lpos
->start_position
,
863 event_request_list_out
->start_position
);
868 lpos
= g_slist_append(lpos
, event_request_list_out
);
870 /* Remove all elements from lpos, and add current */
872 lpos
= g_slist_delete_link(lpos
, g_slist_nth(lpos
, 0));
873 lpos
= g_slist_append(lpos
, event_request_list_out
);
878 EventsRequest
*event_request_lpos
= (EventsRequest
*)g_slist_nth_data(lpos
, 0);
879 EventsRequest
*event_request_ltime
= (EventsRequest
*)g_slist_nth_data(ltime
, 0);
880 LttTime lpos_start_time
;
882 if(event_request_lpos
!= NULL
883 && event_request_lpos
->start_position
!= NULL
) {
884 lpos_start_time
= lttv_traceset_context_position_get_time(
885 event_request_lpos
->start_position
);
888 /* 1.1.3 If lpos.start time < ltime */
889 if(event_request_lpos
!= NULL
890 && event_request_lpos
->start_position
!= NULL
891 && ltt_time_compare(lpos_start_time
,
892 event_request_ltime
->start_time
)<0) {
893 /* Add lpos to list_in, remove them from list_out */
894 for(iter
=lpos
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
896 EventsRequest
*event_request_lpos
=
897 (EventsRequest
*)iter
->data
;
899 list_in
= g_slist_append(list_in
, event_request_lpos
);
900 /* Remove from list_out */
901 list_out
= g_slist_remove(list_out
, event_request_lpos
);
904 /* 1.1.4 (lpos.start time >= ltime) */
905 /* Add ltime to list_in, remove them from list_out */
907 for(iter
=ltime
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
909 EventsRequest
*event_request_ltime
=
910 (EventsRequest
*)iter
->data
;
912 list_in
= g_slist_append(list_in
, event_request_ltime
);
913 /* Remove from list_out */
914 list_out
= g_slist_remove(list_out
, event_request_ltime
);
924 tfc
= lttv_traceset_context_get_current_tfc(tsc
);
925 g_assert(g_slist_length(list_in
)>0);
926 EventsRequest
*events_request
= g_slist_nth_data(list_in
, 0);
931 /* 1.2.1 If first request in list_in is a time request */
932 if(events_request
->start_position
== NULL
) {
933 /* - If first req in list_in start time != current time */
934 if(tfc
== NULL
|| ltt_time_compare(events_request
->start_time
,
935 tfc
->timestamp
) != 0)
936 /* - Seek to that time */
937 g_debug("SEEK TIME : %lu, %lu", events_request
->start_time
.tv_sec
,
938 events_request
->start_time
.tv_nsec
);
939 //lttv_process_traceset_seek_time(tsc, events_request->start_time);
940 lttv_state_traceset_seek_time_closest(LTTV_TRACESET_STATE(tsc
),
941 events_request
->start_time
);
943 /* Process the traceset with only state hooks */
947 lttv_process_traceset_middle(tsc
,
948 events_request
->start_time
,
951 g_assert(seek_count
< LTTV_STATE_SAVE_INTERVAL
);
957 LttvTracefileContext
*tfc
=
958 lttv_traceset_context_get_current_tfc(tsc
);
959 /* Else, the first request in list_in is a position request */
960 /* If first req in list_in pos != current pos */
961 g_assert(events_request
->start_position
!= NULL
);
962 g_debug("SEEK POS time : %lu, %lu",
963 lttv_traceset_context_position_get_time(
964 events_request
->start_position
).tv_sec
,
965 lttv_traceset_context_position_get_time(
966 events_request
->start_position
).tv_nsec
);
969 g_debug("SEEK POS context time : %lu, %lu",
970 tfc
->timestamp
.tv_sec
,
971 tfc
->timestamp
.tv_nsec
);
973 g_debug("SEEK POS context time : %lu, %lu",
974 ltt_time_infinite
.tv_sec
,
975 ltt_time_infinite
.tv_nsec
);
977 g_assert(events_request
->start_position
!= NULL
);
978 if(lttv_traceset_context_ctx_pos_compare(tsc
,
979 events_request
->start_position
) != 0) {
980 /* 1.2.2.1 Seek to that position */
981 g_debug("SEEK POSITION");
982 //lttv_process_traceset_seek_position(tsc, events_request->start_position);
983 pos_time
= lttv_traceset_context_position_get_time(
984 events_request
->start_position
);
986 lttv_state_traceset_seek_time_closest(LTTV_TRACESET_STATE(tsc
),
989 /* Process the traceset with only state hooks */
993 lttv_process_traceset_middle(tsc
,
996 events_request
->start_position
);
997 g_assert(lttv_traceset_context_ctx_pos_compare(tsc
,
998 events_request
->start_position
) == 0);
1005 /* 1.3 Add hooks and call before request for all list_in members */
1007 GSList
*iter
= NULL
;
1009 for(iter
=list_in
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
1010 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1011 /* 1.3.1 If !servicing */
1012 if(events_request
->servicing
== FALSE
) {
1013 /* - begin request hooks called
1014 * - servicing = TRUE
1016 lttv_hooks_call(events_request
->before_request
, (gpointer
)tsc
);
1017 events_request
->servicing
= TRUE
;
1019 /* 1.3.2 call before chunk
1020 * 1.3.3 events hooks added
1022 if(events_request
->trace
== -1)
1023 lttv_process_traceset_begin(tsc
,
1024 events_request
->before_chunk_traceset
,
1025 events_request
->before_chunk_trace
,
1026 events_request
->before_chunk_tracefile
,
1027 events_request
->event
,
1028 events_request
->event_by_id_channel
);
1030 guint nb_trace
= lttv_traceset_number(tsc
->ts
);
1031 g_assert((guint
)events_request
->trace
< nb_trace
&&
1032 events_request
->trace
> -1);
1033 LttvTraceContext
*tc
= tsc
->traces
[events_request
->trace
];
1035 lttv_hooks_call(events_request
->before_chunk_traceset
, tsc
);
1037 lttv_trace_context_add_hooks(tc
,
1038 events_request
->before_chunk_trace
,
1039 events_request
->before_chunk_tracefile
,
1040 events_request
->event
,
1041 events_request
->event_by_id_channel
);
1046 /* 2. Else, list_in is not empty, we continue a read */
1049 /* 2.0 For each req of list_in */
1050 GSList
*iter
= list_in
;
1052 while(iter
!= NULL
) {
1054 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1056 /* - Call before chunk
1057 * - events hooks added
1059 if(events_request
->trace
== -1)
1060 lttv_process_traceset_begin(tsc
,
1061 events_request
->before_chunk_traceset
,
1062 events_request
->before_chunk_trace
,
1063 events_request
->before_chunk_tracefile
,
1064 events_request
->event
,
1065 events_request
->event_by_id_channel
);
1067 guint nb_trace
= lttv_traceset_number(tsc
->ts
);
1068 g_assert((guint
)events_request
->trace
< nb_trace
&&
1069 events_request
->trace
> -1);
1070 LttvTraceContext
*tc
= tsc
->traces
[events_request
->trace
];
1072 lttv_hooks_call(events_request
->before_chunk_traceset
, tsc
);
1074 lttv_trace_context_add_hooks(tc
,
1075 events_request
->before_chunk_trace
,
1076 events_request
->before_chunk_tracefile
,
1077 events_request
->event
,
1078 events_request
->event_by_id_channel
);
1081 iter
= g_slist_next(iter
);
1086 tfc
= lttv_traceset_context_get_current_tfc(tsc
);
1088 /* 2.1 For each req of list_out */
1089 GSList
*iter
= list_out
;
1091 while(iter
!= NULL
) {
1093 gboolean remove
= FALSE
;
1094 gboolean free_data
= FALSE
;
1095 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1097 /* if req.start time == current context time
1098 * or req.start position == current position*/
1099 if( ltt_time_compare(events_request
->start_time
,
1100 tfc
->timestamp
) == 0
1102 (events_request
->start_position
!= NULL
1104 lttv_traceset_context_ctx_pos_compare(tsc
,
1105 events_request
->start_position
) == 0)
1107 /* - Add to list_in, remove from list_out */
1108 list_in
= g_slist_append(list_in
, events_request
);
1112 /* - If !servicing */
1113 if(events_request
->servicing
== FALSE
) {
1114 /* - begin request hooks called
1115 * - servicing = TRUE
1117 lttv_hooks_call(events_request
->before_request
, (gpointer
)tsc
);
1118 events_request
->servicing
= TRUE
;
1120 /* call before chunk
1121 * events hooks added
1123 if(events_request
->trace
== -1)
1124 lttv_process_traceset_begin(tsc
,
1125 events_request
->before_chunk_traceset
,
1126 events_request
->before_chunk_trace
,
1127 events_request
->before_chunk_tracefile
,
1128 events_request
->event
,
1129 events_request
->event_by_id_channel
);
1131 guint nb_trace
= lttv_traceset_number(tsc
->ts
);
1132 g_assert((guint
)events_request
->trace
< nb_trace
&&
1133 events_request
->trace
> -1);
1134 LttvTraceContext
*tc
= tsc
->traces
[events_request
->trace
];
1136 lttv_hooks_call(events_request
->before_chunk_traceset
, tsc
);
1138 lttv_trace_context_add_hooks(tc
,
1139 events_request
->before_chunk_trace
,
1140 events_request
->before_chunk_tracefile
,
1141 events_request
->event
,
1142 events_request
->event_by_id_channel
);
1151 GSList
*remove_iter
= iter
;
1153 iter
= g_slist_next(iter
);
1154 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
1155 list_out
= g_slist_remove_link(list_out
, remove_iter
);
1156 } else { // not remove
1157 iter
= g_slist_next(iter
);
1163 /* 3. Find end criterions */
1168 /* 3.1.1 Find lowest end time in list_in */
1169 g_assert(g_slist_length(list_in
)>0);
1170 end_time
= ((EventsRequest
*)g_slist_nth_data(list_in
,0))->end_time
;
1172 for(iter
=g_slist_nth(list_in
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
1173 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1175 if(ltt_time_compare(events_request
->end_time
,
1177 end_time
= events_request
->end_time
;
1180 /* 3.1.2 Find lowest start time in list_out */
1181 for(iter
=list_out
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
1182 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1184 if(ltt_time_compare(events_request
->start_time
,
1186 end_time
= events_request
->start_time
;
1191 /* 3.2 Number of events */
1193 /* 3.2.1 Find lowest number of events in list_in */
1196 end_nb_events
= ((EventsRequest
*)g_slist_nth_data(list_in
,0))->num_events
;
1198 for(iter
=g_slist_nth(list_in
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
1199 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1201 if(events_request
->num_events
< end_nb_events
)
1202 end_nb_events
= events_request
->num_events
;
1205 /* 3.2.2 Use min(CHUNK_NUM_EVENTS, min num events in list_in) as
1208 end_nb_events
= MIN(CHUNK_NUM_EVENTS
, end_nb_events
);
1212 /* 3.3 End position */
1214 /* 3.3.1 Find lowest end position in list_in */
1217 end_position
=((EventsRequest
*)g_slist_nth_data(list_in
,0))->end_position
;
1219 for(iter
=g_slist_nth(list_in
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
1220 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1222 if(events_request
->end_position
!= NULL
&& end_position
!= NULL
&&
1223 lttv_traceset_context_pos_pos_compare(events_request
->end_position
,
1225 end_position
= events_request
->end_position
;
1230 /* 3.3.2 Find lowest start position in list_out */
1233 for(iter
=list_out
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
1234 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1236 if(events_request
->end_position
!= NULL
&& end_position
!= NULL
&&
1237 lttv_traceset_context_pos_pos_compare(events_request
->end_position
,
1239 end_position
= events_request
->end_position
;
1244 /* 4. Call process traceset middle */
1245 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
);
1246 count
= lttv_process_traceset_middle(tsc
, end_time
, end_nb_events
, end_position
);
1248 tfc
= lttv_traceset_context_get_current_tfc(tsc
);
1250 g_debug("Context time after middle : %lu, %lu", tfc
->timestamp
.tv_sec
,
1251 tfc
->timestamp
.tv_nsec
);
1253 g_debug("End of trace reached after middle.");
1257 /* 5. After process traceset middle */
1258 tfc
= lttv_traceset_context_get_current_tfc(tsc
);
1260 /* - if current context time > traceset.end time */
1261 if(tfc
== NULL
|| ltt_time_compare(tfc
->timestamp
,
1262 tsc
->time_span
.end_time
) > 0) {
1263 /* - For each req in list_in */
1264 GSList
*iter
= list_in
;
1266 while(iter
!= NULL
) {
1268 gboolean remove
= FALSE
;
1269 gboolean free_data
= FALSE
;
1270 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1272 /* - Remove events hooks for req
1273 * - Call end chunk for req
1276 if(events_request
->trace
== -1)
1277 lttv_process_traceset_end(tsc
,
1278 events_request
->after_chunk_traceset
,
1279 events_request
->after_chunk_trace
,
1280 events_request
->after_chunk_tracefile
,
1281 events_request
->event
,
1282 events_request
->event_by_id_channel
);
1285 guint nb_trace
= lttv_traceset_number(tsc
->ts
);
1286 g_assert(events_request
->trace
< nb_trace
&&
1287 events_request
->trace
> -1);
1288 LttvTraceContext
*tc
= tsc
->traces
[events_request
->trace
];
1290 lttv_trace_context_remove_hooks(tc
,
1291 events_request
->after_chunk_trace
,
1292 events_request
->after_chunk_tracefile
,
1293 events_request
->event
,
1294 events_request
->event_by_id_channel
);
1295 lttv_hooks_call(events_request
->after_chunk_traceset
, tsc
);
1300 /* - Call end request for req */
1301 lttv_hooks_call(events_request
->after_request
, (gpointer
)tsc
);
1303 /* - remove req from list_in */
1304 /* Destroy the request */
1311 GSList
*remove_iter
= iter
;
1313 iter
= g_slist_next(iter
);
1314 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
1315 list_in
= g_slist_remove_link(list_in
, remove_iter
);
1316 } else { // not remove
1317 iter
= g_slist_next(iter
);
1322 /* 5.1 For each req in list_in */
1323 GSList
*iter
= list_in
;
1325 while(iter
!= NULL
) {
1327 gboolean remove
= FALSE
;
1328 gboolean free_data
= FALSE
;
1329 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1331 /* - Remove events hooks for req
1332 * - Call end chunk for req
1334 if(events_request
->trace
== -1)
1335 lttv_process_traceset_end(tsc
,
1336 events_request
->after_chunk_traceset
,
1337 events_request
->after_chunk_trace
,
1338 events_request
->after_chunk_tracefile
,
1339 events_request
->event
,
1340 events_request
->event_by_id_channel
);
1343 guint nb_trace
= lttv_traceset_number(tsc
->ts
);
1344 g_assert(events_request
->trace
< nb_trace
&&
1345 events_request
->trace
> -1);
1346 LttvTraceContext
*tc
= tsc
->traces
[events_request
->trace
];
1348 lttv_trace_context_remove_hooks(tc
,
1349 events_request
->after_chunk_trace
,
1350 events_request
->after_chunk_tracefile
,
1351 events_request
->event
,
1352 events_request
->event_by_id_channel
);
1354 lttv_hooks_call(events_request
->after_chunk_traceset
, tsc
);
1357 /* - req.num -= count */
1358 g_assert(events_request
->num_events
>= count
);
1359 events_request
->num_events
-= count
;
1361 g_assert(tfc
!= NULL
);
1362 /* - if req.num == 0
1364 * current context time >= req.end time
1366 * req.end pos == current pos
1368 * req.stop_flag == TRUE
1370 if( events_request
->num_events
== 0
1372 events_request
->stop_flag
== TRUE
1374 ltt_time_compare(tfc
->timestamp
,
1375 events_request
->end_time
) >= 0
1377 (events_request
->end_position
!= NULL
1379 lttv_traceset_context_ctx_pos_compare(tsc
,
1380 events_request
->end_position
) == 0)
1383 g_assert(events_request
->servicing
== TRUE
);
1384 /* - Call end request for req
1385 * - remove req from list_in */
1386 lttv_hooks_call(events_request
->after_request
, (gpointer
)tsc
);
1387 /* - remove req from list_in */
1388 /* Destroy the request */
1396 GSList
*remove_iter
= iter
;
1398 iter
= g_slist_next(iter
);
1399 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
1400 list_in
= g_slist_remove_link(list_in
, remove_iter
);
1401 } else { // not remove
1402 iter
= g_slist_next(iter
);
1408 /* End of removed servicing loop : leave control to GTK instead. */
1409 // if(gtk_events_pending()) break;
1412 /* B. When interrupted between chunks */
1415 GSList
*iter
= list_in
;
1417 /* 1. for each request in list_in */
1418 while(iter
!= NULL
) {
1420 gboolean remove
= FALSE
;
1421 gboolean free_data
= FALSE
;
1422 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1424 /* 1.1. Use current postition as start position */
1425 if(events_request
->start_position
!= NULL
)
1426 lttv_traceset_context_position_destroy(events_request
->start_position
);
1427 events_request
->start_position
= lttv_traceset_context_position_new(tsc
);
1428 lttv_traceset_context_position_save(tsc
, events_request
->start_position
);
1430 /* 1.2. Remove start time */
1431 events_request
->start_time
= ltt_time_infinite
;
1433 /* 1.3. Move from list_in to list_out */
1436 list_out
= g_slist_append(list_out
, events_request
);
1441 GSList
*remove_iter
= iter
;
1443 iter
= g_slist_next(iter
);
1444 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
1445 list_in
= g_slist_remove_link(list_in
, remove_iter
);
1446 } else { // not remove
1447 iter
= g_slist_next(iter
);
1453 /* C Unlock Traces */
1455 lttv_process_traceset_get_sync_data(tsc
);
1456 //lttv_traceset_context_position_save(tsc, sync_position);
1461 iter_trace
<lttv_traceset_number(tsc
->ts
);
1463 LttvTrace
*trace_v
= lttv_traceset_get(tsc
->ts
, iter_trace
);
1465 lttvwindowtraces_unlock(trace_v
);
1469 //set the cursor back to normal
1470 gdk_window_set_cursor(win
, NULL
);
1473 g_assert(g_slist_length(list_in
) == 0);
1475 if( g_slist_length(list_out
) == 0 ) {
1476 /* Put tab's request pending flag back to normal */
1477 tab
->events_request_pending
= FALSE
;
1478 g_debug("remove the idle fct");
1479 return FALSE
; /* Remove the idle function */
1481 g_debug("leave the idle fct");
1482 return TRUE
; /* Leave the idle function */
1484 /* We do not use simili-round-robin, it may require to read 1 meg buffers
1485 * again and again if many tracesets use the same tracefiles. */
1486 /* Hack for round-robin idle functions */
1487 /* It will put the idle function at the end of the pool */
1488 /*g_idle_add_full((G_PRIORITY_HIGH_IDLE + 21),
1489 (GSourceFunc)execute_events_requests,
1495 #endif /* BABEL_CLEANUP */
1500 Manage the periodic update of a live trace
1503 live_trace_update_handler(Tab
*tab
)
1505 unsigned int updated_count
;
1506 #ifdef BABEL_CLEANUP
1507 LttvTracesetContext
*tsc
= LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
1508 TimeInterval initial_time_span
= tsc
->time_span
;
1509 TimeInterval updated_time_span
;
1511 updated_count
= lttv_process_traceset_update(tsc
);
1513 /* TODO ybrosseau 2011-01-12: Add trace resynchronization */
1515 /* Get the changed period bounds */
1516 updated_time_span
= tsc
->time_span
;
1518 if(ltt_time_compare(updated_time_span
.start_time
,
1519 initial_time_span
.start_time
) != 0) {
1520 /* The initial time should not change on a live update */
1524 /* Notify viewers (only on updates) */
1525 if(ltt_time_compare(updated_time_span
.end_time
,
1526 initial_time_span
.end_time
) != 0) {
1528 notify_time_span_changed(tab
);
1529 /* TODO ybrosseau 2011-01-12: Change the timebar to register
1530 to the time_span hook */
1531 timebar_set_minmax_time(TIMEBAR(tab
->MTimebar
),
1532 &updated_time_span
.start_time
,
1533 &updated_time_span
.end_time
);
1535 /* To update the min max */
1536 time_change_manager(tab
, tab
->time_window
);
1539 /* Timer will be recalled as long as there is files to update */
1540 return (updated_count
> 0);
1541 #endif /* BABEL_CLEANUP */
1544 static void lttvwindow_add_trace(Tab
*tab
, LttvTrace
*trace_v
)
1546 #ifdef BABEL_CLEANUP
1547 LttvTraceset
*traceset
= tab
->traceset_info
->traceset
;
1549 guint num_traces
= lttv_traceset_number(traceset
);
1551 //Verify if trace is already present.
1552 for(i
=0; i
<num_traces
; i
++)
1554 LttvTrace
* trace
= lttv_traceset_get(traceset
, i
);
1555 if(trace
== trace_v
)
1559 //Keep a reference to the traces so they are not freed.
1560 for(i
=0; i
<lttv_traceset_number(traceset
); i
++)
1562 LttvTrace
* trace
= lttv_traceset_get(traceset
, i
);
1563 lttv_trace_ref(trace
);
1566 //remove state update hooks
1567 lttv_state_remove_event_hooks(
1568 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1570 lttv_context_fini(LTTV_TRACESET_CONTEXT(
1571 tab
->traceset_info
->traceset_context
));
1572 g_object_unref(tab
->traceset_info
->traceset_context
);
1574 lttv_traceset_add(traceset
, trace_v
);
1575 lttv_trace_ref(trace_v
); /* local ref */
1577 /* Create new context */
1578 tab
->traceset_info
->traceset_context
=
1579 g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
1581 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->
1586 //add state update hooks
1587 lttv_state_add_event_hooks(
1588 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1589 //Remove local reference to the traces.
1590 for(i
=0; i
<lttv_traceset_number(traceset
); i
++)
1592 LttvTrace
* trace
= lttv_traceset_get(traceset
, i
);
1593 lttv_trace_unref(trace
);
1597 //add_trace_into_traceset_selector(GTK_MULTIVPANED(tab->multivpaned), lttv_trace(trace_v));
1600 if (lttv_trace(trace_v
)->is_live
) {
1601 /* Add timer for live update */
1602 /* TODO ybrosseau 2011-01-12: Parametrize the hardcoded 1 seconds */
1603 g_timeout_add_seconds (1,
1604 (GSourceFunc
) live_trace_update_handler
,
1607 #endif /* BABEL_CLEANUP */
1610 /* add_trace adds a trace into the current traceset. It first displays a
1611 * directory selection dialogue to let user choose a trace, then recreates
1612 * tracset_context, and redraws all the viewer of the current tab
1615 void add_trace(GtkWidget
* widget
, gpointer user_data
)
1617 #ifdef BABEL_CLEANUP
1619 LttvTrace
* trace_v
;
1620 LttvTraceset
* traceset
;
1622 char abs_path
[PATH_MAX
];
1624 MainWindow
* mw_data
= get_window_data_struct(widget
);
1625 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
1627 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
1628 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
1629 LttvPluginTab
*ptab
;
1633 ptab
= create_new_tab(widget
, NULL
);
1636 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
1640 /* File open dialog management */
1641 GtkWidget
*extra_live_button
;
1642 GtkFileChooser
* file_chooser
=
1644 gtk_file_chooser_dialog_new ("Select a trace",
1645 GTK_WINDOW(mw_data
->mwindow
),
1646 GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER
,
1647 GTK_STOCK_CANCEL
, GTK_RESPONSE_CANCEL
,
1648 GTK_STOCK_OPEN
, GTK_RESPONSE_ACCEPT
,
1651 /* Button to indicate the opening of a live trace */
1652 extra_live_button
= gtk_check_button_new_with_mnemonic ("Trace is live (currently being writen)");
1653 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (extra_live_button
), FALSE
);
1654 gtk_file_chooser_set_extra_widget (GTK_FILE_CHOOSER (file_chooser
), extra_live_button
);
1656 gtk_file_chooser_set_show_hidden (file_chooser
, TRUE
);
1657 if(remember_trace_dir
[0] != '\0')
1658 gtk_file_chooser_set_filename(file_chooser
, remember_trace_dir
);
1660 id
= gtk_dialog_run(GTK_DIALOG(file_chooser
));
1663 case GTK_RESPONSE_ACCEPT
:
1664 case GTK_RESPONSE_OK
:
1665 dir
= gtk_file_chooser_get_filename (file_chooser
);
1667 strncpy(remember_trace_dir
, dir
, PATH_MAX
);
1668 strncat(remember_trace_dir
, "/", PATH_MAX
);
1669 if(!dir
|| strlen(dir
) == 0){
1672 get_absolute_pathname(dir
, abs_path
);
1673 trace_v
= lttvwindowtraces_get_trace_by_name(abs_path
);
1674 if(trace_v
== NULL
) {
1675 if(gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (extra_live_button
))) {
1676 trace
= ltt_trace_open_live(abs_path
);
1678 trace
= ltt_trace_open(abs_path
);
1682 g_warning("cannot open trace %s", abs_path
);
1684 GtkWidget
*dialogue
=
1685 gtk_message_dialog_new(
1686 GTK_WINDOW(gtk_widget_get_toplevel(widget
)),
1687 GTK_DIALOG_MODAL
|GTK_DIALOG_DESTROY_WITH_PARENT
,
1690 "Cannot open trace : maybe you should enter in the trace "
1691 "directory to select it ?");
1692 gtk_dialog_run(GTK_DIALOG(dialogue
));
1693 gtk_widget_destroy(dialogue
);
1696 trace_v
= lttv_trace_new(trace
);
1697 lttvwindowtraces_add_trace(trace_v
);
1698 lttvwindow_add_trace(tab
, trace_v
);
1701 lttvwindow_add_trace(tab
, trace_v
);
1705 //update current tab
1706 //update_traceset(mw_data);
1708 /* Call the updatetraceset hooks */
1710 traceset
= tab
->traceset_info
->traceset
;
1711 SetTraceset(tab
, traceset
);
1712 // in expose now call_pending_read_hooks(mw_data);
1714 //lttvwindow_report_current_time(mw_data,&(tab->current_time));
1716 case GTK_RESPONSE_REJECT
:
1717 case GTK_RESPONSE_CANCEL
:
1721 gtk_widget_destroy((GtkWidget
*)file_chooser
);
1723 #endif /* BABEL_CLEANUP */
1727 /* remove_trace removes a trace from the current traceset if all viewers in
1728 * the current tab are not interested in the trace. It first displays a
1729 * dialogue, which shows all traces in the current traceset, to let user choose
1730 * a trace, then it checks if all viewers unselect the trace, if it is true,
1731 * it will remove the trace, recreate the traceset_contex,
1732 * and redraws all the viewer of the current tab. If there is on trace in the
1733 * current traceset, it will delete all viewers of the current tab
1735 * It destroys the filter tree. FIXME... we should request for an update
1739 void remove_trace(GtkWidget
*widget
, gpointer user_data
)
1741 #ifdef BABEL_CLEANUP
1743 LttvTrace
* trace_v
;
1744 LttvTraceset
* traceset
;
1745 gint i
, j
, nb_trace
, index
=-1;
1746 char ** name
, *remove_trace_name
;
1747 MainWindow
* mw_data
= get_window_data_struct(widget
);
1748 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
1750 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
1751 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
1757 LttvPluginTab
*ptab
;
1758 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
1762 nb_trace
=lttv_traceset_number(tab
->traceset_info
->traceset
);
1763 name
= g_new(char*,nb_trace
);
1764 for(i
= 0; i
< nb_trace
; i
++){
1765 trace_v
= lttv_traceset_get(tab
->traceset_info
->traceset
, i
);
1766 trace
= lttv_trace(trace_v
);
1767 name
[i
] = (char *) g_quark_to_string(ltt_trace_name(trace
));
1770 remove_trace_name
= get_remove_trace(mw_data
, name
, nb_trace
);
1773 if(remove_trace_name
){
1775 /* yuk, cut n paste from old code.. should be better (MD)*/
1776 for(i
= 0; i
<nb_trace
; i
++) {
1777 if(strcmp(remove_trace_name
,name
[i
]) == 0){
1782 traceset
= tab
->traceset_info
->traceset
;
1783 //Keep a reference to the traces so they are not freed.
1784 for(j
=0; j
<lttv_traceset_number(traceset
); j
++)
1786 LttvTrace
* trace
= lttv_traceset_get(traceset
, j
);
1787 lttv_trace_ref(trace
);
1790 //remove state update hooks
1791 lttv_state_remove_event_hooks(
1792 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1793 lttv_context_fini(LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
));
1794 g_object_unref(tab
->traceset_info
->traceset_context
);
1796 trace_v
= lttv_traceset_get(traceset
, index
);
1798 lttv_traceset_remove(traceset
, index
);
1799 lttv_trace_unref(trace_v
); // Remove local reference
1801 if(lttv_trace_get_ref_number(trace_v
) <= 1) {
1802 /* ref 1 : lttvwindowtraces only*/
1803 ltt_trace_close(lttv_trace(trace_v
));
1804 /* lttvwindowtraces_remove_trace takes care of destroying
1805 * the traceset linked with the trace_v and also of destroying
1806 * the trace_v at the same time.
1808 lttvwindowtraces_remove_trace(trace_v
);
1811 tab
->traceset_info
->traceset_context
=
1812 g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
1814 LTTV_TRACESET_CONTEXT(tab
->
1815 traceset_info
->traceset_context
),traceset
);
1816 //add state update hooks
1817 lttv_state_add_event_hooks(
1818 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1820 //Remove local reference to the traces.
1821 for(j
=0; j
<lttv_traceset_number(traceset
); j
++)
1823 LttvTrace
* trace
= lttv_traceset_get(traceset
, j
);
1824 lttv_trace_unref(trace
);
1827 SetTraceset(tab
, (gpointer
)traceset
);
1830 #endif /* BABEL_CLEANUP */
1834 void remove_trace(GtkWidget
* widget
, gpointer user_data
)
1837 LttvTrace
* trace_v
;
1838 LttvTraceset
* traceset
;
1839 gint i
, j
, nb_trace
;
1840 char ** name
, *remove_trace_name
;
1841 MainWindow
* mw_data
= get_window_data_struct(widget
);
1842 LttvTracesetSelector
* s
;
1843 LttvTraceSelector
* t
;
1846 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
1848 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
1849 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
1855 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
1858 nb_trace
=lttv_traceset_number(tab
->traceset_info
->traceset
);
1859 name
= g_new(char*,nb_trace
);
1860 for(i
= 0; i
< nb_trace
; i
++){
1861 trace_v
= lttv_traceset_get(tab
->traceset_info
->traceset
, i
);
1862 trace
= lttv_trace(trace_v
);
1863 name
[i
] = ltt_trace_name(trace
);
1866 remove_trace_name
= get_remove_trace(name
, nb_trace
);
1868 if(remove_trace_name
){
1869 for(i
=0; i
<nb_trace
; i
++){
1870 if(strcmp(remove_trace_name
,name
[i
]) == 0){
1871 //unselect the trace from the current viewer
1873 w
= gtk_multivpaned_get_widget(GTK_MULTIVPANED(tab
->multivpaned
));
1875 s
= g_object_get_data(G_OBJECT(w
), "Traceset_Selector");
1877 t
= lttv_traceset_selector_trace_get(s
,i
);
1878 lttv_trace_selector_set_selected(t
, FALSE
);
1881 //check if other viewers select the trace
1882 w
= gtk_multivpaned_get_first_widget(GTK_MULTIVPANED(tab
->multivpaned
));
1884 s
= g_object_get_data(G_OBJECT(w
), "Traceset_Selector");
1886 t
= lttv_traceset_selector_trace_get(s
,i
);
1887 selected
= lttv_trace_selector_get_selected(t
);
1890 w
= gtk_multivpaned_get_next_widget(GTK_MULTIVPANED(tab
->multivpaned
));
1892 }else selected
= FALSE
;
1894 //if no viewer selects the trace, remove it
1896 remove_trace_from_traceset_selector(GTK_MULTIVPANED(tab
->multivpaned
), i
);
1898 traceset
= tab
->traceset_info
->traceset
;
1899 //Keep a reference to the traces so they are not freed.
1900 for(j
=0; j
<lttv_traceset_number(traceset
); j
++)
1902 LttvTrace
* trace
= lttv_traceset_get(traceset
, j
);
1903 lttv_trace_ref(trace
);
1906 //remove state update hooks
1907 lttv_state_remove_event_hooks(
1908 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1909 lttv_context_fini(LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
));
1910 g_object_unref(tab
->traceset_info
->traceset_context
);
1913 trace_v
= lttv_traceset_get(traceset
, i
);
1915 if(lttv_trace_get_ref_number(trace_v
) <= 2) {
1916 /* ref 2 : traceset, local */
1917 lttvwindowtraces_remove_trace(trace_v
);
1918 ltt_trace_close(lttv_trace(trace_v
));
1921 lttv_traceset_remove(traceset
, i
);
1922 lttv_trace_unref(trace_v
); // Remove local reference
1924 if(!lttv_trace_get_ref_number(trace_v
))
1925 lttv_trace_destroy(trace_v
);
1927 tab
->traceset_info
->traceset_context
=
1928 g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
1930 LTTV_TRACESET_CONTEXT(tab
->
1931 traceset_info
->traceset_context
),traceset
);
1932 //add state update hooks
1933 lttv_state_add_event_hooks(
1934 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1936 //Remove local reference to the traces.
1937 for(j
=0; j
<lttv_traceset_number(traceset
); j
++)
1939 LttvTrace
* trace
= lttv_traceset_get(traceset
, j
);
1940 lttv_trace_unref(trace
);
1944 //update current tab
1945 //update_traceset(mw_data);
1948 SetTraceset(tab
, (gpointer
)traceset
);
1949 // in expose now call_pending_read_hooks(mw_data);
1951 //lttvwindow_report_current_time(mw_data,&(tab->current_time));
1954 // while(tab->multi_vpaned->num_children){
1955 // gtk_multi_vpaned_widget_delete(tab->multi_vpaned);
1969 /* Redraw all the viewers in the current tab */
1970 void redraw(GtkWidget
*widget
, gpointer user_data
)
1972 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
1973 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
1974 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
1981 LttvPluginTab
*ptab
;
1982 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
1987 LttvAttributeValue value
;
1989 retval
= lttv_iattribute_find_by_path(tab
->attributes
, "hooks/redraw", LTTV_POINTER
, &value
);
1992 tmp
= (LttvHooks
*)*(value
.v_pointer
);
1994 lttv_hooks_call(tmp
,NULL
);
1998 void continue_processing(GtkWidget
*widget
, gpointer user_data
)
2000 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
2001 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2002 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2009 LttvPluginTab
*ptab
;
2010 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
2015 LttvAttributeValue value
;
2017 retval
= lttv_iattribute_find_by_path(tab
->attributes
, "hooks/continue",
2018 LTTV_POINTER
, &value
);
2021 tmp
= (LttvHooks
*)*(value
.v_pointer
);
2023 lttv_hooks_call(tmp
,NULL
);
2026 /* Stop the processing for the calling main window's current tab.
2027 * It removes every processing requests that are in its list. It does not call
2028 * the end request hooks, because the request is not finished.
2031 void stop_processing(GtkWidget
*widget
, gpointer user_data
)
2033 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
2034 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2035 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2040 LttvPluginTab
*ptab
;
2041 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
2044 GSList
*iter
= tab
->events_requests
;
2046 while(iter
!= NULL
) {
2047 GSList
*remove_iter
= iter
;
2048 iter
= g_slist_next(iter
);
2050 g_free(remove_iter
->data
);
2051 tab
->events_requests
=
2052 g_slist_remove_link(tab
->events_requests
, remove_iter
);
2054 tab
->events_request_pending
= FALSE
;
2055 tab
->stop_foreground
= TRUE
;
2056 g_idle_remove_by_data(tab
);
2057 g_assert(g_slist_length(tab
->events_requests
) == 0);
2061 /* save will save the traceset to a file
2062 * Not implemented yet FIXME
2065 void save(GtkWidget
* widget
, gpointer user_data
)
2070 void save_as(GtkWidget
* widget
, gpointer user_data
)
2072 g_info("Save as\n");
2076 /* zoom will change the time_window of all the viewers of the
2077 * current tab, and redisplay them. The main functionality is to
2078 * determine the new time_window of the current tab
2081 void zoom(GtkWidget
* widget
, double size
)
2083 #ifdef BABEL_CLEANUP
2084 TimeInterval time_span
;
2085 TimeWindow new_time_window
;
2086 LttTime current_time
, time_delta
;
2087 LttvTracesetContext
*tsc
;
2088 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
2090 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2091 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2097 LttvPluginTab
*ptab
;
2098 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
2102 if(size
== 1) return;
2104 tsc
= LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
2105 time_span
= tsc
->time_span
;
2106 new_time_window
= tab
->time_window
;
2107 current_time
= tab
->current_time
;
2109 time_delta
= ltt_time_sub(time_span
.end_time
,time_span
.start_time
);
2111 new_time_window
.start_time
= time_span
.start_time
;
2112 new_time_window
.time_width
= time_delta
;
2113 new_time_window
.time_width_double
= ltt_time_to_double(time_delta
);
2114 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
2115 new_time_window
.time_width
) ;
2117 new_time_window
.time_width
= ltt_time_div(new_time_window
.time_width
, size
);
2118 new_time_window
.time_width_double
=
2119 ltt_time_to_double(new_time_window
.time_width
);
2120 if(ltt_time_compare(new_time_window
.time_width
,time_delta
) > 0)
2121 { /* Case where zoom out is bigger than trace length */
2122 new_time_window
.start_time
= time_span
.start_time
;
2123 new_time_window
.time_width
= time_delta
;
2124 new_time_window
.time_width_double
= ltt_time_to_double(time_delta
);
2125 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
2126 new_time_window
.time_width
) ;
2130 /* Center the image on the current time */
2131 new_time_window
.start_time
=
2132 ltt_time_sub(current_time
,
2133 ltt_time_from_double(new_time_window
.time_width_double
/2.0));
2134 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
2135 new_time_window
.time_width
) ;
2136 /* If on borders, don't fall off */
2137 if(ltt_time_compare(new_time_window
.start_time
, time_span
.start_time
) <0
2138 || ltt_time_compare(new_time_window
.start_time
, time_span
.end_time
) >0)
2140 new_time_window
.start_time
= time_span
.start_time
;
2141 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
2142 new_time_window
.time_width
) ;
2146 if(ltt_time_compare(new_time_window
.end_time
,
2147 time_span
.end_time
) > 0
2148 || ltt_time_compare(new_time_window
.end_time
,
2149 time_span
.start_time
) < 0)
2151 new_time_window
.start_time
=
2152 ltt_time_sub(time_span
.end_time
, new_time_window
.time_width
);
2154 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
2155 new_time_window
.time_width
) ;
2162 if(ltt_time_compare(new_time_window
.time_width
, ltt_time_zero
) == 0) {
2163 g_warning("Zoom more than 1 ns impossible");
2165 time_change_manager(tab
, new_time_window
);
2168 #endif /* BABEL_CLEANUP */
2171 void zoom_in(GtkWidget
* widget
, gpointer user_data
)
2176 void zoom_out(GtkWidget
* widget
, gpointer user_data
)
2181 void zoom_extended(GtkWidget
* widget
, gpointer user_data
)
2186 void go_to_time(GtkWidget
* widget
, gpointer user_data
)
2188 g_info("Go to time\n");
2191 void show_time_frame(GtkWidget
* widget
, gpointer user_data
)
2193 g_info("Show time frame\n");
2197 /* callback function */
2200 on_empty_traceset_activate (GtkMenuItem
*menuitem
,
2203 create_new_window((GtkWidget
*)menuitem
, user_data
, FALSE
);
2208 on_clone_traceset_activate (GtkMenuItem
*menuitem
,
2211 create_new_window((GtkWidget
*)menuitem
, user_data
, TRUE
);
2215 /* create_new_tab calls create_tab to construct a new tab in the main window
2218 LttvPluginTab
*create_new_tab(GtkWidget
* widget
, gpointer user_data
)
2220 gchar label
[PATH_MAX
];
2221 MainWindow
* mw_data
= get_window_data_struct(widget
);
2223 GtkNotebook
* notebook
= (GtkNotebook
*)lookup_widget(widget
, "MNotebook");
2224 if(notebook
== NULL
){
2225 g_info("Notebook does not exist\n");
2228 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2229 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2235 LttvPluginTab
*ptab
;
2236 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
2237 copy_tab
= ptab
->tab
;
2240 strcpy(label
,"Page");
2241 if(get_label(mw_data
, label
,"Get the name of the tab","Please input tab's name")) {
2242 LttvPluginTab
*ptab
;
2244 ptab
= g_object_new(LTTV_TYPE_PLUGIN_TAB
, NULL
);
2245 init_tab (ptab
->tab
, mw_data
, copy_tab
, notebook
, label
);
2246 ptab
->parent
.top_widget
= ptab
->tab
->top_widget
;
2247 g_object_set_data_full(
2248 G_OBJECT(ptab
->tab
->vbox
),
2251 (GDestroyNotify
)tab_destructor
);
2258 on_tab_activate (GtkMenuItem
*menuitem
,
2261 create_new_tab((GtkWidget
*)menuitem
, user_data
);
2266 on_open_activate (GtkMenuItem
*menuitem
,
2269 #ifdef UNFINISHED_FEATURE
2270 open_traceset((GtkWidget
*)menuitem
, user_data
);
2276 on_close_activate (GtkMenuItem
*menuitem
,
2279 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2280 main_window_destructor(mw_data
);
2284 /* remove the current tab from the main window
2288 on_close_tab_activate (GtkWidget
*widget
,
2292 GtkWidget
* notebook
;
2293 notebook
= lookup_widget(widget
, "MNotebook");
2294 if(notebook
== NULL
){
2295 g_info("Notebook does not exist\n");
2299 page_num
= gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
));
2301 gtk_notebook_remove_page(GTK_NOTEBOOK(notebook
), page_num
);
2306 on_close_tab_X_clicked (GtkWidget
*widget
,
2310 GtkWidget
*notebook
= lookup_widget(widget
, "MNotebook");
2311 if(notebook
== NULL
){
2312 g_info("Notebook does not exist\n");
2316 if((page_num
= gtk_notebook_page_num(GTK_NOTEBOOK(notebook
), widget
)) != -1)
2317 gtk_notebook_remove_page(GTK_NOTEBOOK(notebook
), page_num
);
2323 on_add_trace_activate (GtkMenuItem
*menuitem
,
2326 add_trace((GtkWidget
*)menuitem
, user_data
);
2331 on_remove_trace_activate (GtkMenuItem
*menuitem
,
2334 remove_trace((GtkWidget
*)menuitem
, user_data
);
2339 on_save_activate (GtkMenuItem
*menuitem
,
2342 save((GtkWidget
*)menuitem
, user_data
);
2347 on_save_as_activate (GtkMenuItem
*menuitem
,
2350 save_as((GtkWidget
*)menuitem
, user_data
);
2355 on_quit_activate (GtkMenuItem
*menuitem
,
2358 while (g_slist_length(g_main_window_list
) != 0) {
2359 on_MWindow_destroy(((MainWindow
*)g_main_window_list
->data
)->mwindow
,
2366 on_cut_activate (GtkMenuItem
*menuitem
,
2374 on_copy_activate (GtkMenuItem
*menuitem
,
2382 on_paste_activate (GtkMenuItem
*menuitem
,
2390 on_delete_activate (GtkMenuItem
*menuitem
,
2398 on_zoom_in_activate (GtkMenuItem
*menuitem
,
2401 zoom_in((GtkWidget
*)menuitem
, user_data
);
2406 on_zoom_out_activate (GtkMenuItem
*menuitem
,
2409 zoom_out((GtkWidget
*)menuitem
, user_data
);
2414 on_zoom_extended_activate (GtkMenuItem
*menuitem
,
2417 zoom_extended((GtkWidget
*)menuitem
, user_data
);
2422 on_go_to_time_activate (GtkMenuItem
*menuitem
,
2425 go_to_time((GtkWidget
*)menuitem
, user_data
);
2430 on_show_time_frame_activate (GtkMenuItem
*menuitem
,
2433 show_time_frame((GtkWidget
*)menuitem
, user_data
);
2438 on_move_viewer_up_activate (GtkMenuItem
*menuitem
,
2441 move_up_viewer((GtkWidget
*)menuitem
, user_data
);
2446 on_move_viewer_down_activate (GtkMenuItem
*menuitem
,
2449 move_down_viewer((GtkWidget
*)menuitem
, user_data
);
2454 on_remove_viewer_activate (GtkMenuItem
*menuitem
,
2457 delete_viewer((GtkWidget
*)menuitem
, user_data
);
2461 on_trace_facility_activate (GtkMenuItem
*menuitem
,
2464 g_info("Trace facility selector: %s\n", "");
2468 /* Dispaly a file selection dialogue to let user select a library, then call
2469 * lttv_library_load().
2473 on_load_library_activate (GtkMenuItem
*menuitem
,
2476 GError
*error
= NULL
;
2477 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2479 gchar load_module_path_alter
[PATH_MAX
];
2483 gchar
*load_module_path
;
2484 name
= g_ptr_array_new();
2485 nb
= lttv_library_path_number();
2486 /* ask for the library path */
2490 path
= lttv_library_path_get(i
);
2491 g_ptr_array_add(name
, path
);
2494 load_module_path
= get_selection(mw_data
,
2495 (char **)(name
->pdata
), name
->len
,
2496 "Select a library path", "Library paths");
2497 if(load_module_path
!= NULL
)
2498 strncpy(load_module_path_alter
, load_module_path
, PATH_MAX
-1); // -1 for /
2500 g_ptr_array_free(name
, TRUE
);
2502 if(load_module_path
== NULL
) return;
2506 /* Make sure the module path ends with a / */
2507 gchar
*ptr
= load_module_path_alter
;
2509 ptr
= strchr(ptr
, '\0');
2511 if(*(ptr
-1) != '/') {
2518 /* Ask for the library to load : list files in the previously selected
2520 gchar str
[PATH_MAX
];
2523 GtkFileSelection
* file_selector
=
2524 (GtkFileSelection
*)gtk_file_selection_new("Select a module");
2525 gtk_file_selection_set_filename(file_selector
, load_module_path_alter
);
2526 gtk_file_selection_hide_fileop_buttons(file_selector
);
2528 gtk_window_set_transient_for(GTK_WINDOW(file_selector
),
2529 GTK_WINDOW(mw_data
->mwindow
));
2532 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
2534 case GTK_RESPONSE_ACCEPT
:
2535 case GTK_RESPONSE_OK
:
2536 dir
= gtk_file_selection_get_selections (file_selector
);
2537 strncpy(str
,dir
[0],PATH_MAX
);
2538 strncpy(remember_plugins_dir
,dir
[0],PATH_MAX
);
2539 /* only keep file name */
2541 str1
= strrchr(str
,'/');
2544 str1
= strrchr(str
,'\\');
2549 if(*str1
== 'l' && *(str1
+1)== 'i' && *(str1
+2)=='b')
2551 remove info after
. */
2555 str2
= strrchr(str2
, '.');
2556 if(str2
!= NULL
) *str2
= '\0';
2558 lttv_module_require(str1
, &error
);
2560 lttv_library_load(str1
, &error
);
2561 if(error
!= NULL
) g_warning("%s", error
->message
);
2562 else g_info("Load library: %s\n", str
);
2564 case GTK_RESPONSE_REJECT
:
2565 case GTK_RESPONSE_CANCEL
:
2567 gtk_widget_destroy((GtkWidget
*)file_selector
);
2578 /* Display all loaded modules, let user to select a module to unload
2579 * by calling lttv_module_unload
2583 on_unload_library_activate (GtkMenuItem
*menuitem
,
2586 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2588 LttvLibrary
*library
= NULL
;
2593 name
= g_ptr_array_new();
2594 nb
= lttv_library_number();
2595 LttvLibraryInfo
*lib_info
= g_new(LttvLibraryInfo
,nb
);
2596 /* ask for the library name */
2599 LttvLibrary
*iter_lib
= lttv_library_get(i
);
2600 lttv_library_info(iter_lib
, &lib_info
[i
]);
2602 gchar
*path
= lib_info
[i
].name
;
2603 g_ptr_array_add(name
, path
);
2605 lib_name
= get_selection(mw_data
, (char **)(name
->pdata
), name
->len
,
2606 "Select a library", "Libraries");
2607 if(lib_name
!= NULL
) {
2609 if(strcmp(lib_name
, lib_info
[i
].name
) == 0) {
2610 library
= lttv_library_get(i
);
2615 g_ptr_array_free(name
, TRUE
);
2618 if(lib_name
== NULL
) return;
2620 if(library
!= NULL
) lttv_library_unload(library
);
2624 /* Dispaly a file selection dialogue to let user select a module, then call
2625 * lttv_module_require().
2629 on_load_module_activate (GtkMenuItem
*menuitem
,
2632 GError
*error
= NULL
;
2633 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2635 LttvLibrary
*library
= NULL
;
2640 name
= g_ptr_array_new();
2641 nb
= lttv_library_number();
2642 LttvLibraryInfo
*lib_info
= g_new(LttvLibraryInfo
,nb
);
2643 /* ask for the library name */
2646 LttvLibrary
*iter_lib
= lttv_library_get(i
);
2647 lttv_library_info(iter_lib
, &lib_info
[i
]);
2649 gchar
*path
= lib_info
[i
].name
;
2650 g_ptr_array_add(name
, path
);
2652 lib_name
= get_selection(mw_data
,(char **)(name
->pdata
), name
->len
,
2653 "Select a library", "Libraries");
2654 if(lib_name
!= NULL
) {
2656 if(strcmp(lib_name
, lib_info
[i
].name
) == 0) {
2657 library
= lttv_library_get(i
);
2662 g_ptr_array_free(name
, TRUE
);
2665 if(lib_name
== NULL
) return;
2668 //LttvModule *module;
2669 gchar module_name_out
[PATH_MAX
];
2671 /* Ask for the module to load : list modules in the selected lib */
2675 nb
= lttv_library_module_number(library
);
2676 LttvModuleInfo
*module_info
= g_new(LttvModuleInfo
,nb
);
2677 name
= g_ptr_array_new();
2678 /* ask for the module name */
2681 LttvModule
*iter_module
= lttv_library_module_get(library
, i
);
2682 lttv_module_info(iter_module
, &module_info
[i
]);
2684 gchar
*path
= module_info
[i
].name
;
2685 g_ptr_array_add(name
, path
);
2687 module_name
= get_selection(mw_data
, (char **)(name
->pdata
), name
->len
,
2688 "Select a module", "Modules");
2689 if(module_name
!= NULL
) {
2691 if(strcmp(module_name
, module_info
[i
].name
) == 0) {
2692 strncpy(module_name_out
, module_name
, PATH_MAX
);
2693 //module = lttv_library_module_get(i);
2699 g_ptr_array_free(name
, TRUE
);
2700 g_free(module_info
);
2702 if(module_name
== NULL
) return;
2705 lttv_module_require(module_name_out
, &error
);
2706 if(error
!= NULL
) g_warning("%s", error
->message
);
2707 else g_info("Load module: %s", module_name_out
);
2714 gchar str
[PATH_MAX
];
2717 GtkFileSelection
* file_selector
=
2718 (GtkFileSelection
*)gtk_file_selection_new("Select a module");
2719 gtk_file_selection_set_filename(file_selector
, load_module_path_alter
);
2720 gtk_file_selection_hide_fileop_buttons(file_selector
);
2723 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
2725 case GTK_RESPONSE_ACCEPT
:
2726 case GTK_RESPONSE_OK
:
2727 dir
= gtk_file_selection_get_selections (file_selector
);
2728 strncpy(str
,dir
[0],PATH_MAX
);
2729 strncpy(remember_plugins_dir
,dir
[0],PATH_MAX
);
2731 /* only keep file name */
2733 str1
= strrchr(str
,'/');
2736 str1
= strrchr(str
,'\\');
2741 if(*str1
== 'l' && *(str1
+1)== 'i' && *(str1
+2)=='b')
2743 remove info after
. */
2747 str2
= strrchr(str2
, '.');
2748 if(str2
!= NULL
) *str2
= '\0';
2750 lttv_module_require(str1
, &error
);
2752 lttv_library_load(str1
, &error
);
2753 if(error
!= NULL
) g_warning(error
->message
);
2754 else g_info("Load library: %s\n", str
);
2756 case GTK_RESPONSE_REJECT
:
2757 case GTK_RESPONSE_CANCEL
:
2759 gtk_widget_destroy((GtkWidget
*)file_selector
);
2771 /* Display all loaded modules, let user to select a module to unload
2772 * by calling lttv_module_unload
2776 on_unload_module_activate (GtkMenuItem
*menuitem
,
2779 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2781 LttvLibrary
*library
= NULL
;
2786 name
= g_ptr_array_new();
2787 nb
= lttv_library_number();
2788 LttvLibraryInfo
*lib_info
= g_new(LttvLibraryInfo
,nb
);
2789 /* ask for the library name */
2792 LttvLibrary
*iter_lib
= lttv_library_get(i
);
2793 lttv_library_info(iter_lib
, &lib_info
[i
]);
2795 gchar
*path
= lib_info
[i
].name
;
2796 g_ptr_array_add(name
, path
);
2798 lib_name
= get_selection(mw_data
, (char **)(name
->pdata
), name
->len
,
2799 "Select a library", "Libraries");
2800 if(lib_name
!= NULL
) {
2802 if(strcmp(lib_name
, lib_info
[i
].name
) == 0) {
2803 library
= lttv_library_get(i
);
2808 g_ptr_array_free(name
, TRUE
);
2811 if(lib_name
== NULL
) return;
2814 LttvModule
*module
= NULL
;
2816 /* Ask for the module to load : list modules in the selected lib */
2820 nb
= lttv_library_module_number(library
);
2821 LttvModuleInfo
*module_info
= g_new(LttvModuleInfo
,nb
);
2822 name
= g_ptr_array_new();
2823 /* ask for the module name */
2826 LttvModule
*iter_module
= lttv_library_module_get(library
, i
);
2827 lttv_module_info(iter_module
, &module_info
[i
]);
2829 gchar
*path
= module_info
[i
].name
;
2830 if(module_info
[i
].use_count
> 0) g_ptr_array_add(name
, path
);
2832 module_name
= get_selection(mw_data
, (char **)(name
->pdata
), name
->len
,
2833 "Select a module", "Modules");
2834 if(module_name
!= NULL
) {
2836 if(strcmp(module_name
, module_info
[i
].name
) == 0) {
2837 module
= lttv_library_module_get(library
, i
);
2843 g_ptr_array_free(name
, TRUE
);
2844 g_free(module_info
);
2846 if(module_name
== NULL
) return;
2849 LttvModuleInfo module_info
;
2850 lttv_module_info(module
, &module_info
);
2851 g_info("Release module: %s\n", module_info
.name
);
2853 lttv_module_release(module
);
2857 /* Display a directory dialogue to let user select a path for library searching
2861 on_add_library_search_path_activate (GtkMenuItem
*menuitem
,
2864 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2865 //GtkDirSelection * file_selector = (GtkDirSelection *)gtk_dir_selection_new("Select library path");
2866 GtkFileSelection
* file_selector
= (GtkFileSelection
*)gtk_file_selection_new("Select a trace");
2867 gtk_widget_hide( (file_selector
)->file_list
->parent
) ;
2869 gtk_window_set_transient_for(GTK_WINDOW(file_selector
),
2870 GTK_WINDOW(mw_data
->mwindow
));
2875 if(remember_plugins_dir
[0] != '\0')
2876 gtk_file_selection_set_filename(file_selector
, remember_plugins_dir
);
2878 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
2880 case GTK_RESPONSE_ACCEPT
:
2881 case GTK_RESPONSE_OK
:
2882 dir
= gtk_file_selection_get_filename (file_selector
);
2883 strncpy(remember_plugins_dir
,dir
,PATH_MAX
);
2884 strncat(remember_plugins_dir
,"/",PATH_MAX
);
2885 lttv_library_path_add(dir
);
2886 case GTK_RESPONSE_REJECT
:
2887 case GTK_RESPONSE_CANCEL
:
2889 gtk_widget_destroy((GtkWidget
*)file_selector
);
2895 /* Display a directory dialogue to let user select a path for library searching
2899 on_remove_library_search_path_activate (GtkMenuItem
*menuitem
,
2902 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2904 const char *lib_path
;
2908 name
= g_ptr_array_new();
2909 nb
= lttv_library_path_number();
2910 /* ask for the library name */
2913 gchar
*path
= lttv_library_path_get(i
);
2914 g_ptr_array_add(name
, path
);
2916 lib_path
= get_selection(mw_data
, (char **)(name
->pdata
), name
->len
,
2917 "Select a library path", "Library paths");
2919 g_ptr_array_free(name
, TRUE
);
2921 if(lib_path
== NULL
) return;
2924 lttv_library_path_remove(lib_path
);
2928 on_color_activate (GtkMenuItem
*menuitem
,
2936 on_save_configuration_activate (GtkMenuItem
*menuitem
,
2939 g_info("Save configuration\n");
2944 on_content_activate (GtkMenuItem
*menuitem
,
2947 char* filename
= NULL
,
2950 const char* relativePath
= "doc/user/user_guide/html/index.html";
2951 filename
= g_build_filename (g_get_current_dir(), relativePath
, NULL
);
2952 path
= g_strdup_printf ("ghelp://%s", filename
);
2954 screen
= gdk_screen_get_default();
2955 gtk_show_uri (screen
, path
, gtk_get_current_event_time(), NULL
);
2959 g_info("Content\n");
2964 on_about_close_activate (GtkButton
*button
,
2967 GtkWidget
*about_widget
= GTK_WIDGET(user_data
);
2969 gtk_widget_destroy(about_widget
);
2973 on_about_activate (GtkMenuItem
*menuitem
,
2976 MainWindow
*main_window
= get_window_data_struct(GTK_WIDGET(menuitem
));
2977 GtkWidget
*window_widget
= main_window
->mwindow
;
2978 GtkWidget
*about_widget
= gtk_window_new(GTK_WINDOW_TOPLEVEL
);
2979 GtkWindow
*about_window
= GTK_WINDOW(about_widget
);
2981 gtk_window_set_title(about_window
, "About Linux Trace Toolkit");
2983 gtk_window_set_resizable(about_window
, FALSE
);
2984 gtk_window_set_transient_for(about_window
, GTK_WINDOW(window_widget
));
2985 gtk_window_set_destroy_with_parent(about_window
, TRUE
);
2986 gtk_window_set_modal(about_window
, FALSE
);
2988 /* Put the about window at the center of the screen */
2989 gtk_window_set_position(about_window
, GTK_WIN_POS_CENTER_ALWAYS
);
2991 GtkWidget
*vbox
= gtk_vbox_new(FALSE
, 1);
2993 gtk_container_add(GTK_CONTAINER(about_widget
), vbox
);
2996 GtkWidget
*label1
= gtk_label_new("");
2997 gtk_misc_set_padding(GTK_MISC(label1
), 10, 20);
2998 gtk_label_set_markup(GTK_LABEL(label1
), "\
2999 <big>Linux Trace Toolkit " VERSION
"</big>");
3000 gtk_label_set_justify(GTK_LABEL(label1
), GTK_JUSTIFY_CENTER
);
3002 GtkWidget
*label2
= gtk_label_new("");
3003 gtk_misc_set_padding(GTK_MISC(label2
), 10, 20);
3004 gtk_label_set_markup(GTK_LABEL(label2
), "\
3007 Michel Dagenais (New trace format, lttv main)\n\
3008 Mathieu Desnoyers (Kernel Tracer, Directory structure, build with automake/conf,\n\
3009 lttv gui, control flow view, gui cooperative trace reading\n\
3010 scheduler with interruptible foreground and background\n\
3011 computation, detailed event list (rewrite), trace reading\n\
3012 library (rewrite))\n\
3013 Benoit Des Ligneris, Eric Clement (Cluster adaptation, work in progress)\n\
3014 Xang-Xiu Yang (new trace reading library and converter, lttv gui, \n\
3015 detailed event list and statistics view)\n\
3016 Tom Zanussi (RelayFS)\n\
3018 Inspired from the original Linux Trace Toolkit Visualizer made by\n\
3021 GtkWidget
*label3
= gtk_label_new("");
3022 gtk_label_set_markup(GTK_LABEL(label3
), "\
3023 Linux Trace Toolkit Viewer, Copyright (C) 2004, 2005, 2006\n\
3025 Mathieu Desnoyers\n\
3027 Linux Trace Toolkit comes with ABSOLUTELY NO WARRANTY.\n\
3028 This is free software, and you are welcome to redistribute it\n\
3029 under certain conditions. See COPYING for details.");
3030 gtk_misc_set_padding(GTK_MISC(label3
), 10, 20);
3032 gtk_box_pack_start_defaults(GTK_BOX(vbox
), label1
);
3033 gtk_box_pack_start_defaults(GTK_BOX(vbox
), label2
);
3034 gtk_box_pack_start_defaults(GTK_BOX(vbox
), label3
);
3036 GtkWidget
*hbox
= gtk_hbox_new(TRUE
, 0);
3037 gtk_box_pack_end(GTK_BOX(vbox
), hbox
, FALSE
, FALSE
, 0);
3038 GtkWidget
*close_button
= gtk_button_new_with_mnemonic("_Close");
3039 gtk_box_pack_end(GTK_BOX(hbox
), close_button
, FALSE
, FALSE
, 0);
3040 gtk_container_set_border_width(GTK_CONTAINER(close_button
), 20);
3042 g_signal_connect(G_OBJECT(close_button
), "clicked",
3043 G_CALLBACK(on_about_close_activate
),
3044 (gpointer
)about_widget
);
3046 gtk_widget_show_all(about_widget
);
3051 on_button_new_clicked (GtkButton
*button
,
3054 create_new_window((GtkWidget
*)button
, user_data
, TRUE
);
3058 on_button_new_tab_clicked (GtkButton
*button
,
3061 create_new_tab((GtkWidget
*)button
, user_data
);
3065 on_button_open_clicked (GtkButton
*button
,
3068 #ifdef UNFINISHED_FEATURE
3069 open_traceset((GtkWidget
*)button
, user_data
);
3075 on_button_add_trace_clicked (GtkButton
*button
,
3078 add_trace((GtkWidget
*)button
, user_data
);
3083 on_button_remove_trace_clicked (GtkButton
*button
,
3086 remove_trace((GtkWidget
*)button
, user_data
);
3090 on_button_redraw_clicked (GtkButton
*button
,
3093 redraw((GtkWidget
*)button
, user_data
);
3097 on_button_continue_processing_clicked (GtkButton
*button
,
3100 continue_processing((GtkWidget
*)button
, user_data
);
3104 on_button_stop_processing_clicked (GtkButton
*button
,
3107 stop_processing((GtkWidget
*)button
, user_data
);
3113 on_button_save_clicked (GtkButton
*button
,
3116 save((GtkWidget
*)button
, user_data
);
3121 on_button_save_as_clicked (GtkButton
*button
,
3124 save_as((GtkWidget
*)button
, user_data
);
3129 on_button_zoom_in_clicked (GtkButton
*button
,
3132 zoom_in((GtkWidget
*)button
, user_data
);
3137 on_button_zoom_out_clicked (GtkButton
*button
,
3140 zoom_out((GtkWidget
*)button
, user_data
);
3145 on_button_zoom_extended_clicked (GtkButton
*button
,
3148 zoom_extended((GtkWidget
*)button
, user_data
);
3153 on_button_go_to_time_clicked (GtkButton
*button
,
3156 go_to_time((GtkWidget
*)button
, user_data
);
3161 on_button_show_time_frame_clicked (GtkButton
*button
,
3164 show_time_frame((GtkWidget
*)button
, user_data
);
3169 on_button_move_up_clicked (GtkButton
*button
,
3172 move_up_viewer((GtkWidget
*)button
, user_data
);
3177 on_button_move_down_clicked (GtkButton
*button
,
3180 move_down_viewer((GtkWidget
*)button
, user_data
);
3185 on_button_delete_viewer_clicked (GtkButton
*button
,
3188 delete_viewer((GtkWidget
*)button
, user_data
);
3192 on_MWindow_destroy (GtkWidget
*widget
,
3195 MainWindow
*main_window
= get_window_data_struct(widget
);
3196 LttvIAttribute
*attributes
= main_window
->attributes
;
3197 LttvAttributeValue value
;
3200 //This is unnecessary, since widgets will be destroyed
3201 //by the main window widget anyway.
3202 //remove_all_menu_toolbar_constructors(main_window, NULL);
3204 retval
= lttv_iattribute_find_by_path(attributes
, "viewers/menu",
3205 LTTV_POINTER
, &value
);
3207 lttv_menus_destroy((LttvMenus
*)*(value
.v_pointer
));
3209 retval
= lttv_iattribute_find_by_path(attributes
, "viewers/toolbar",
3210 LTTV_POINTER
, &value
);
3212 lttv_toolbars_destroy((LttvToolbars
*)*(value
.v_pointer
));
3214 g_object_unref(main_window
->attributes
);
3215 g_main_window_list
= g_slist_remove(g_main_window_list
, main_window
);
3217 g_info("There are now : %d windows\n",g_slist_length(g_main_window_list
));
3218 if(g_slist_length(g_main_window_list
) == 0)
3223 on_MWindow_configure (GtkWidget
*widget
,
3224 GdkEventConfigure
*event
,
3227 // MD : removed time width modification upon resizing of the main window.
3228 // The viewers will redraw themselves completely, without time interval
3231 if(mw_data->window_width){
3232 time_span = LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context)->Time_Span ;
3233 time_win = tab->time_window;
3234 ratio = width / mw_data->window_width;
3235 tab->time_window.time_width = ltt_time_mul(time_win.time_width,ratio);
3236 time = ltt_time_sub(time_span->endTime, time_win.start_time);
3237 if(ltt_time_compare(time, tab->time_window.time_width) < 0){
3238 tab->time_window.time_width = time;
3244 mw_data->window_width = (int)width;
3253 on_MNotebook_switch_page (GtkNotebook
*notebook
,
3254 GtkNotebookPage
*page
,
3262 void time_change_manager (Tab
*tab
,
3263 TimeWindow new_time_window
)
3266 /* Only one source of time change */
3267 if(tab
->time_manager_lock
== TRUE
) return;
3269 tab
->time_manager_lock
= TRUE
;
3270 TimeInterval time_span
;
3272 LttvTraceset
*ts
= tab
->traceset_info
->traceset
;
3273 time_span
.start_time
=ltt_time_from_uint64( lttv_traceset_get_timestamp_begin(ts
));
3274 time_span
.end_time
= ltt_time_from_uint64(lttv_traceset_get_timestamp_end(ts
));
3277 LttTime start_time
= new_time_window
.start_time
;
3278 LttTime end_time
= new_time_window
.end_time
;
3280 g_assert(ltt_time_compare(start_time
, end_time
) < 0);
3283 GtkAdjustment
*adjustment
= gtk_range_get_adjustment(GTK_RANGE(tab
->scrollbar
));
3284 LttTime upper
= ltt_time_sub(time_span
.end_time
, time_span
.start_time
);
3287 gtk_range_set_increments(GTK_RANGE(tab
->scrollbar
),
3288 ltt_time_to_double(new_time_window
.time_width
)
3289 / SCROLL_STEP_PER_PAGE
3290 * NANOSECONDS_PER_SECOND
, /* step increment */
3291 ltt_time_to_double(new_time_window
.time_width
)
3292 * NANOSECONDS_PER_SECOND
); /* page increment */
3293 gtk_range_set_range(GTK_RANGE(tab
->scrollbar
),
3295 ltt_time_to_double(upper
)
3296 * NANOSECONDS_PER_SECOND
); /* upper */
3298 g_object_set(G_OBJECT(adjustment
),
3302 ltt_time_to_double(upper
), /* upper */
3304 new_time_window
.time_width_double
3305 / SCROLL_STEP_PER_PAGE
, /* step increment */
3307 new_time_window
.time_width_double
,
3308 /* page increment */
3310 new_time_window
.time_width_double
, /* page size */
3312 gtk_adjustment_changed(adjustment
);
3314 // g_object_set(G_OBJECT(adjustment),
3316 // ltt_time_to_double(
3317 // ltt_time_sub(start_time, time_span.start_time))
3320 //gtk_adjustment_value_changed(adjustment);
3321 gtk_range_set_value(GTK_RANGE(tab
->scrollbar
),
3323 ltt_time_sub(start_time
, time_span
.start_time
)) /* value */);
3325 /* set the time bar. */
3328 timebar_set_minmax_time(TIMEBAR(tab
->MTimebar
),
3329 &time_span
.start_time
,
3330 &time_span
.end_time
);
3331 timebar_set_start_time(TIMEBAR(tab
->MTimebar
),&start_time
);
3332 timebar_set_end_time(TIMEBAR(tab
->MTimebar
),&end_time
);
3336 /* call viewer hooks for new time window */
3337 set_time_window(tab
, &new_time_window
);
3339 tab
->time_manager_lock
= FALSE
;
3348 void current_time_change_manager (Tab
*tab
,
3349 LttTime new_current_time
)
3351 /* Only one source of time change */
3352 if(tab
->current_time_manager_lock
== TRUE
) return;
3354 tab
->current_time_manager_lock
= TRUE
;
3356 timebar_set_current_time(TIMEBAR(tab
->MTimebar
), &new_current_time
);
3358 set_current_time(tab
, &new_current_time
);
3360 tab
->current_time_manager_lock
= FALSE
;
3363 void current_position_change_manager(Tab
*tab
,
3364 LttvTracesetPosition
*pos
)
3366 #ifdef BABEL_CLEANUP
3367 LttvTracesetContext
*tsc
=
3368 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3371 retval
= lttv_process_traceset_seek_position(tsc
, pos
);
3372 g_assert_cmpint(retval
, ==, 0);
3373 LttTime new_time
= lttv_traceset_context_position_get_time(pos
);
3374 /* Put the context in a state coherent position */
3375 lttv_state_traceset_seek_time_closest((LttvTracesetState
*)tsc
, ltt_time_zero
);
3377 current_time_change_manager(tab
, new_time
);
3379 set_current_position(tab
, pos
);
3380 #endif /* BABEL_CLEANUP */
3383 static void on_timebar_starttime_changed(Timebar
*timebar
,
3386 #ifdef BABEL_CLEANUP
3387 Tab
*tab
= (Tab
*)user_data
;
3388 LttvTracesetContext
* tsc
=
3389 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3390 TimeInterval time_span
= tsc
->time_span
;
3392 TimeWindow new_time_window
= tab
->time_window
;
3393 new_time_window
.start_time
= timebar_get_start_time(timebar
);
3395 LttTime end_time
= new_time_window
.end_time
;
3397 /* TODO ybrosseau 2010-12-02: This if should have been checked
3398 by the timebar already */
3399 if(ltt_time_compare(new_time_window
.start_time
, end_time
) >= 0) {
3400 /* Then, we must push back end time : keep the same time width
3401 * if possible, else end traceset time */
3402 end_time
= LTT_TIME_MIN(ltt_time_add(new_time_window
.start_time
,
3403 new_time_window
.time_width
),
3404 time_span
.end_time
);
3407 /* Fix the time width to fit start time and end time */
3408 new_time_window
.time_width
= ltt_time_sub(end_time
,
3409 new_time_window
.start_time
);
3411 new_time_window
.time_width_double
=
3412 ltt_time_to_double(new_time_window
.time_width
);
3414 new_time_window
.end_time
= end_time
;
3416 /* Notify the time_manager */
3417 time_change_manager(tab
, new_time_window
);
3418 #endif /* BABEL_CLEANUP */
3421 static void on_timebar_endtime_changed(Timebar
*timebar
,
3424 #ifdef BABEL_CLEANUP
3425 Tab
*tab
= (Tab
*)user_data
;
3426 LttvTracesetContext
* tsc
=
3427 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3428 TimeInterval time_span
= tsc
->time_span
;
3430 TimeWindow new_time_window
= tab
->time_window
;
3432 LttTime end_time
= timebar_get_end_time(timebar
);
3434 /* TODO ybrosseau 2010-12-02: This if should have been
3435 checked by the timebar already */
3436 if(ltt_time_compare(new_time_window
.start_time
, end_time
) >= 0) {
3437 /* Then, we must push front start time : keep the same time
3438 width if possible, else end traceset time */
3439 new_time_window
.start_time
= LTT_TIME_MAX(
3440 ltt_time_sub(end_time
,
3441 new_time_window
.time_width
),
3442 time_span
.start_time
);
3445 /* Fix the time width to fit start time and end time */
3446 new_time_window
.time_width
= ltt_time_sub(end_time
,
3447 new_time_window
.start_time
);
3449 new_time_window
.time_width_double
=
3450 ltt_time_to_double(new_time_window
.time_width
);
3452 new_time_window
.end_time
= end_time
;
3454 /* Notify the time_manager */
3455 time_change_manager(tab
, new_time_window
);
3456 #endif /* BABEL_CLEANUP*/
3458 static void on_timebar_currenttime_changed(Timebar
*timebar
,
3461 Tab
*tab
= (Tab
*)user_data
;
3463 LttTime new_current_time
= timebar_get_current_time(timebar
);
3465 current_time_change_manager(tab
, new_current_time
);
3468 void scroll_value_changed_cb(GtkWidget
*scrollbar
,
3471 #ifdef BABEL_CLEANUP
3472 Tab
*tab
= (Tab
*)user_data
;
3473 TimeWindow new_time_window
;
3475 GtkAdjustment
*adjust
= gtk_range_get_adjustment(GTK_RANGE(scrollbar
));
3476 gdouble value
= gtk_adjustment_get_value(adjust
);
3477 // gdouble upper, lower, ratio, page_size;
3479 LttvTracesetContext
* tsc
=
3480 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3481 TimeInterval time_span
= tsc
->time_span
;
3483 time
= ltt_time_add(ltt_time_from_double(value
),
3484 time_span
.start_time
);
3486 new_time_window
.start_time
= time
;
3488 page_size
= adjust
->page_size
;
3490 new_time_window
.time_width
=
3491 ltt_time_from_double(page_size
);
3493 new_time_window
.time_width_double
=
3496 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
3497 new_time_window
.time_width
);
3500 time_change_manager(tab
, new_time_window
);
3502 //time_window = tab->time_window;
3504 lower
= adjust
->lower
;
3505 upper
= adjust
->upper
;
3506 ratio
= (value
- lower
) / (upper
- lower
);
3507 g_info("lower %lu, upper %lu, value %lu, ratio %lu", lower
, upper
, value
, ratio
);
3509 //time = ltt_time_sub(time_span->end_time, time_span->start_time);
3510 //time = ltt_time_mul(time, (float)ratio);
3511 //time = ltt_time_add(time_span->start_time, time);
3512 time
= ltt_time_add(ltt_time_from_double(value
),
3513 time_span
.start_time
);
3515 time_window
.start_time
= time
;
3517 page_size
= adjust
->page_size
;
3519 time_window
.time_width
=
3520 ltt_time_from_double(page_size
);
3521 //time = ltt_time_sub(time_span.end_time, time);
3522 //if(ltt_time_compare(time,time_window.time_width) < 0){
3523 // time_window.time_width = time;
3526 /* call viewer hooks for new time window */
3527 set_time_window(tab
, &time_window
);
3529 #endif /* BABEL_CLEANUP */
3533 /* Display a dialogue showing all eventtypes and traces, let user to select the interested
3534 * eventtypes, tracefiles and traces (filter)
3537 /* Select a trace which will be removed from traceset
3540 char * get_remove_trace(MainWindow
*mw_data
,
3541 char ** all_trace_name
, int nb_trace
)
3543 return get_selection(mw_data
, all_trace_name
, nb_trace
,
3544 "Select a trace", "Trace pathname");
3548 /* Select a module which will be loaded
3551 char * get_load_module(MainWindow
*mw_data
,
3552 char ** load_module_name
, int nb_module
)
3554 return get_selection(mw_data
, load_module_name
, nb_module
,
3555 "Select a module to load", "Module name");
3561 /* Select a module which will be unloaded
3564 char * get_unload_module(MainWindow
*mw_data
,
3565 char ** loaded_module_name
, int nb_module
)
3567 return get_selection(mw_data
, loaded_module_name
, nb_module
,
3568 "Select a module to unload", "Module name");
3572 /* Display a dialogue which shows all selectable items, let user to
3573 * select one of them
3576 char * get_selection(MainWindow
*mw_data
,
3577 char ** loaded_module_name
, int nb_module
,
3578 char *title
, char * column_title
)
3580 GtkWidget
* dialogue
;
3581 GtkWidget
* scroll_win
;
3583 GtkListStore
* store
;
3584 GtkTreeViewColumn
* column
;
3585 GtkCellRenderer
* renderer
;
3586 GtkTreeSelection
* select
;
3589 char * unload_module_name
= NULL
;
3591 dialogue
= gtk_dialog_new_with_buttons(title
,
3594 GTK_STOCK_OK
,GTK_RESPONSE_ACCEPT
,
3595 GTK_STOCK_CANCEL
,GTK_RESPONSE_REJECT
,
3597 gtk_window_set_default_size((GtkWindow
*)dialogue
, 500, 200);
3598 gtk_window_set_transient_for(GTK_WINDOW(dialogue
),
3599 GTK_WINDOW(mw_data
->mwindow
));
3601 scroll_win
= gtk_scrolled_window_new (NULL
, NULL
);
3602 gtk_widget_show ( scroll_win
);
3603 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll_win
),
3604 GTK_POLICY_AUTOMATIC
, GTK_POLICY_AUTOMATIC
);
3606 store
= gtk_list_store_new (N_COLUMNS
,G_TYPE_STRING
);
3607 tree
= gtk_tree_view_new_with_model(GTK_TREE_MODEL (store
));
3608 gtk_widget_show ( tree
);
3609 g_object_unref (G_OBJECT (store
));
3611 renderer
= gtk_cell_renderer_text_new ();
3612 column
= gtk_tree_view_column_new_with_attributes (column_title
,
3614 "text", MODULE_COLUMN
,
3616 gtk_tree_view_column_set_alignment (column
, 0.5);
3617 gtk_tree_view_column_set_fixed_width (column
, 150);
3618 gtk_tree_view_append_column (GTK_TREE_VIEW (tree
), column
);
3620 select
= gtk_tree_view_get_selection (GTK_TREE_VIEW (tree
));
3621 gtk_tree_selection_set_mode (select
, GTK_SELECTION_SINGLE
);
3623 gtk_container_add (GTK_CONTAINER (scroll_win
), tree
);
3625 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialogue
)->vbox
), scroll_win
,TRUE
, TRUE
,0);
3627 for(i
=0;i
<nb_module
;i
++){
3628 gtk_list_store_append (store
, &iter
);
3629 gtk_list_store_set (store
, &iter
, MODULE_COLUMN
,loaded_module_name
[i
],-1);
3632 id
= gtk_dialog_run(GTK_DIALOG(dialogue
));
3633 GtkTreeModel
**store_model
= (GtkTreeModel
**)&store
;
3635 case GTK_RESPONSE_ACCEPT
:
3636 case GTK_RESPONSE_OK
:
3637 if (gtk_tree_selection_get_selected (select
, store_model
, &iter
)){
3638 gtk_tree_model_get ((GtkTreeModel
*)store
, &iter
, MODULE_COLUMN
, &unload_module_name
, -1);
3640 case GTK_RESPONSE_REJECT
:
3641 case GTK_RESPONSE_CANCEL
:
3643 gtk_widget_destroy(dialogue
);
3647 return unload_module_name
;
3651 /* Insert all menu entry and tool buttons into this main window
3656 void add_all_menu_toolbar_constructors(MainWindow
* mw
, gpointer user_data
)
3660 lttvwindow_viewer_constructor constructor
;
3661 LttvMenus
* global_menu
, * instance_menu
;
3662 LttvToolbars
* global_toolbar
, * instance_toolbar
;
3663 LttvMenuClosure
*menu_item
;
3664 LttvToolbarClosure
*toolbar_item
;
3665 LttvAttributeValue value
;
3666 LttvIAttribute
*global_attributes
= LTTV_IATTRIBUTE(lttv_global_attributes());
3667 LttvIAttribute
*attributes
= mw
->attributes
;
3668 GtkWidget
* tool_menu_title_menu
, *new_widget
, *pixmap
;
3671 retval
= lttv_iattribute_find_by_path(global_attributes
, "viewers/menu",
3672 LTTV_POINTER
, &value
);
3674 if(*(value
.v_pointer
) == NULL
)
3675 *(value
.v_pointer
) = lttv_menus_new();
3676 global_menu
= (LttvMenus
*)*(value
.v_pointer
);
3678 retval
= lttv_iattribute_find_by_path(attributes
, "viewers/menu",
3679 LTTV_POINTER
, &value
);
3681 if(*(value
.v_pointer
) == NULL
)
3682 *(value
.v_pointer
) = lttv_menus_new();
3683 instance_menu
= (LttvMenus
*)*(value
.v_pointer
);
3685 retval
= lttv_iattribute_find_by_path(global_attributes
, "viewers/toolbar",
3686 LTTV_POINTER
, &value
);
3688 if(*(value
.v_pointer
) == NULL
)
3689 *(value
.v_pointer
) = lttv_toolbars_new();
3690 global_toolbar
= (LttvToolbars
*)*(value
.v_pointer
);
3692 retval
= lttv_iattribute_find_by_path(attributes
, "viewers/toolbar",
3693 LTTV_POINTER
, &value
);
3695 if(*(value
.v_pointer
) == NULL
)
3696 *(value
.v_pointer
) = lttv_toolbars_new();
3697 instance_toolbar
= (LttvToolbars
*)*(value
.v_pointer
);
3699 /* Add missing menu entries to window instance */
3700 for(i
=0;i
<global_menu
->len
;i
++) {
3701 menu_item
= &g_array_index(global_menu
, LttvMenuClosure
, i
);
3703 //add menu_item to window instance;
3704 constructor
= menu_item
->con
;
3705 tool_menu_title_menu
= lookup_widget(mw
->mwindow
,"ToolMenuTitle_menu");
3707 gtk_menu_item_new_with_mnemonic (menu_item
->menu_text
);
3708 gtk_container_add (GTK_CONTAINER (tool_menu_title_menu
),
3710 g_signal_connect ((gpointer
) new_widget
, "activate",
3711 G_CALLBACK (insert_viewer_wrap
),
3713 gtk_widget_show (new_widget
);
3714 lttv_menus_add(instance_menu
, menu_item
->con
,
3715 menu_item
->menu_path
,
3716 menu_item
->menu_text
,
3721 /* Add missing toolbar entries to window instance */
3722 for(i
=0;i
<global_toolbar
->len
;i
++) {
3723 toolbar_item
= &g_array_index(global_toolbar
, LttvToolbarClosure
, i
);
3725 //add toolbar_item to window instance;
3726 constructor
= toolbar_item
->con
;
3727 tool_menu_title_menu
= lookup_widget(mw
->mwindow
,"MToolbar1");
3728 pixbuf
= gdk_pixbuf_new_from_xpm_data((const char**)toolbar_item
->pixmap
);
3729 pixmap
= gtk_image_new_from_pixbuf(pixbuf
);
3731 gtk_toolbar_append_element (GTK_TOOLBAR (tool_menu_title_menu
),
3732 GTK_TOOLBAR_CHILD_BUTTON
,
3735 toolbar_item
->tooltip
, NULL
,
3736 pixmap
, NULL
, NULL
);
3737 gtk_label_set_use_underline(
3738 GTK_LABEL (((GtkToolbarChild
*) (
3739 g_list_last (GTK_TOOLBAR
3740 (tool_menu_title_menu
)->children
)->data
))->label
),
3742 gtk_container_set_border_width (GTK_CONTAINER (new_widget
), 1);
3743 g_signal_connect ((gpointer
) new_widget
,
3745 G_CALLBACK (insert_viewer_wrap
),
3747 gtk_widget_show (new_widget
);
3749 lttv_toolbars_add(instance_toolbar
, toolbar_item
->con
,
3750 toolbar_item
->tooltip
,
3751 toolbar_item
->pixmap
,
3759 /* Create a main window
3762 MainWindow
*construct_main_window(MainWindow
* parent
)
3766 g_debug("construct_main_window()");
3767 GtkWidget
* new_window
; /* New generated main window */
3768 MainWindow
* new_m_window
;/* New main window structure */
3769 GtkNotebook
* notebook
;
3770 LttvIAttribute
*attributes
=
3771 LTTV_IATTRIBUTE(g_object_new(LTTV_ATTRIBUTE_TYPE
, NULL
));
3772 LttvAttributeValue value
;
3774 new_m_window
= g_new(MainWindow
, 1);
3776 // Add the object's information to the module's array
3777 g_main_window_list
= g_slist_append(g_main_window_list
, new_m_window
);
3779 new_window
= create_MWindow();
3780 gtk_widget_show (new_window
);
3782 new_m_window
->mwindow
= new_window
;
3783 new_m_window
->attributes
= attributes
;
3785 retval
= lttv_iattribute_find_by_path(attributes
, "viewers/menu",
3786 LTTV_POINTER
, &value
);
3788 *(value
.v_pointer
) = lttv_menus_new();
3790 retval
= lttv_iattribute_find_by_path(attributes
, "viewers/toolbar",
3791 LTTV_POINTER
, &value
);
3793 *(value
.v_pointer
) = lttv_toolbars_new();
3795 add_all_menu_toolbar_constructors(new_m_window
, NULL
);
3797 g_object_set_data_full(G_OBJECT(new_window
),
3799 (gpointer
)new_m_window
,
3800 (GDestroyNotify
)g_free
);
3801 //create a default tab
3802 notebook
= (GtkNotebook
*)lookup_widget(new_m_window
->mwindow
, "MNotebook");
3803 if(notebook
== NULL
){
3804 g_info("Notebook does not exist\n");
3805 /* FIXME : destroy partially created widgets */
3806 g_free(new_m_window
);
3809 //gtk_notebook_popup_enable (GTK_NOTEBOOK(notebook));
3810 //for now there is no name field in LttvTraceset structure
3811 //Use "Traceset" as the label for the default tab
3813 GtkWidget
* parent_notebook
= lookup_widget(parent
->mwindow
, "MNotebook");
3814 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(parent_notebook
),
3815 gtk_notebook_get_current_page(GTK_NOTEBOOK(parent_notebook
)));
3821 LttvPluginTab
*ptab
;
3822 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
3823 parent_tab
= ptab
->tab
;
3825 LttvPluginTab
*ptab
= g_object_new(LTTV_TYPE_PLUGIN_TAB
, NULL
);
3827 new_m_window
, parent_tab
, notebook
, "Traceset");
3828 ptab
->parent
.top_widget
= ptab
->tab
->top_widget
;
3829 g_object_set_data_full(
3830 G_OBJECT(ptab
->tab
->vbox
),
3833 (GDestroyNotify
)tab_destructor
);
3835 LttvPluginTab
*ptab
= g_object_new(LTTV_TYPE_PLUGIN_TAB
, NULL
);
3836 init_tab(ptab
->tab
, new_m_window
, NULL
, notebook
, "Traceset");
3837 ptab
->parent
.top_widget
= ptab
->tab
->top_widget
;
3838 g_object_set_data_full(
3839 G_OBJECT(ptab
->tab
->vbox
),
3842 (GDestroyNotify
)tab_destructor
);
3845 /* Insert default viewers */
3847 LttvAttributeType type
;
3848 LttvAttributeName name
;
3849 LttvAttributeValue value
;
3850 LttvAttribute
*attribute
;
3852 LttvIAttribute
*attributes_global
=
3853 LTTV_IATTRIBUTE(lttv_global_attributes());
3855 attribute
= LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
3856 LTTV_IATTRIBUTE(attributes_global
),
3857 LTTV_VIEWER_CONSTRUCTORS
));
3858 g_assert(attribute
);
3860 name
= g_quark_from_string("guievents");
3861 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
3863 if(type
== LTTV_POINTER
) {
3864 lttvwindow_viewer_constructor viewer_constructor
=
3865 (lttvwindow_viewer_constructor
)*value
.v_pointer
;
3866 insert_viewer(new_window
, viewer_constructor
);
3869 name
= g_quark_from_string("guicontrolflow");
3870 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
3872 if(type
== LTTV_POINTER
) {
3873 lttvwindow_viewer_constructor viewer_constructor
=
3874 (lttvwindow_viewer_constructor
)*value
.v_pointer
;
3875 insert_viewer(new_window
, viewer_constructor
);
3878 name
= g_quark_from_string("guistatistics");
3879 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
3881 if(type
== LTTV_POINTER
) {
3882 lttvwindow_viewer_constructor viewer_constructor
=
3883 (lttvwindow_viewer_constructor
)*value
.v_pointer
;
3884 insert_viewer(new_window
, viewer_constructor
);
3888 g_info("There are now : %d windows\n",g_slist_length(g_main_window_list
));
3890 return new_m_window
;
3894 /* Free the memory occupied by a tab structure
3898 void tab_destructor(LttvPluginTab
* ptab
)
3900 #ifdef BABEL_CLEANUP
3901 int i
, nb
, ref_count
;
3903 Tab
*tab
= ptab
->tab
;
3906 g_object_unref(tab
->attributes
);
3908 if(tab
->interrupted_state
)
3909 g_object_unref(tab
->interrupted_state
);
3912 if(tab
->traceset_info
->traceset_context
!= NULL
){
3913 //remove state update hooks
3914 lttv_state_remove_event_hooks(
3915 (LttvTracesetState
*)tab
->traceset_info
->
3917 lttv_context_fini(LTTV_TRACESET_CONTEXT(tab
->traceset_info
->
3919 g_object_unref(tab
->traceset_info
->traceset_context
);
3921 if(tab
->traceset_info
->traceset
!= NULL
) {
3922 nb
= lttv_traceset_number(tab
->traceset_info
->traceset
);
3923 for(i
= 0 ; i
< nb
; i
++) {
3924 trace
= lttv_traceset_get(tab
->traceset_info
->traceset
, i
);
3925 ref_count
= lttv_trace_get_ref_number(trace
);
3927 ltt_trace_close(lttv_trace(trace
));
3931 lttv_traceset_destroy(tab
->traceset_info
->traceset
);
3932 /* Remove the idle events requests processing function of the tab */
3933 g_idle_remove_by_data(tab
);
3935 g_slist_free(tab
->events_requests
);
3936 g_free(tab
->traceset_info
);
3938 g_object_unref(ptab
);
3939 #endif /* BABEL_CLEANUP */
3943 /* Create a tab and insert it into the current main window
3946 void init_tab(Tab
*tab
, MainWindow
* mw
, Tab
*copy_tab
,
3947 GtkNotebook
* notebook
, char * label
)
3952 //LttvFilter *filter = NULL;
3954 //create a new tab data structure
3955 //tab = g_new(Tab,1);
3957 //construct and initialize the traceset_info
3958 tab
->traceset_info
= g_new(TracesetInfo
,1);
3961 tab
->traceset_info
->traceset
=
3962 lttv_traceset_copy(copy_tab
->traceset_info
->traceset
);
3964 /* Copy the previous tab's filter */
3965 /* We can clone the filter, as we copy the trace set also */
3966 /* The filter must always be in sync with the trace set */
3968 #ifdef BABEL_CLEANUP
3969 tab
->filter
= lttv_filter_clone(copy_tab
->filter
);
3970 #endif /* BABEL_CLEANUP */
3972 tab
->traceset_info
->traceset
= lttv_traceset_new();
3977 lttv_attribute_write_xml(
3978 lttv_traceset_attribute(tab
->traceset_info
->traceset
),
3984 tab
->time_manager_lock
= FALSE
;
3985 tab
->current_time_manager_lock
= FALSE
;
3986 #ifdef BABEL_CLEANUP
3987 //FIXME copy not implemented in lower level
3988 tab
->traceset_info
->traceset_context
=
3989 g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
3990 //add state update hooks
3991 lttv_state_add_event_hooks(
3992 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
3993 #endif //BABEL_CLEANUP
3994 //determine the current_time and time_window of the tab
3996 if(copy_tab
!= NULL
){
3997 tab
->time_window
= copy_tab
->time_window
;
3998 tab
->current_time
= copy_tab
->current_time
;
4000 tab
->time_window
.start_time
=
4001 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
4002 time_span
.start_time
;
4003 if(DEFAULT_TIME_WIDTH_S
<
4004 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
4005 time_span
.end_time
.tv_sec
)
4006 tmp_time
.tv_sec
= DEFAULT_TIME_WIDTH_S
;
4009 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
4010 time_span
.end_time
.tv_sec
;
4011 tmp_time
.tv_nsec
= 0;
4012 tab
->time_window
.time_width
= tmp_time
;
4013 tab
->current_time
.tv_sec
=
4014 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
4015 time_span
.start_time
.tv_sec
;
4016 tab
->current_time
.tv_nsec
=
4017 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
4018 time_span
.start_time
.tv_nsec
;
4021 tab
->attributes
= LTTV_IATTRIBUTE(g_object_new(LTTV_ATTRIBUTE_TYPE
, NULL
));
4022 tab
->interrupted_state
= g_object_new(LTTV_ATTRIBUTE_TYPE
, NULL
);
4024 tab
->vbox
= gtk_vbox_new(FALSE
, 2);
4025 tab
->top_widget
= tab
->vbox
;
4026 //g_object_set_data_full(G_OBJECT(tab->top_widget), "filter",
4027 // filter, (GDestroyNotify)lttv_filter_destroy);
4029 // g_signal_connect (G_OBJECT(tab->top_widget),
4031 // G_CALLBACK (on_top_notify),
4034 tab
->viewer_container
= gtk_vbox_new(TRUE
, 2);
4035 tab
->scrollbar
= gtk_hscrollbar_new(NULL
);
4036 //tab->multivpaned = gtk_multi_vpaned_new();
4038 gtk_box_pack_start(GTK_BOX(tab
->vbox
),
4039 tab
->viewer_container
,
4041 TRUE
, /* Give the extra space to the child */
4042 0); /* No padding */
4045 // tab->time_window = copy_tab->time_window;
4046 // tab->current_time = copy_tab->current_time;
4049 /* Create the timebar */
4051 tab
->MTimebar
= timebar_new();
4053 gtk_box_pack_end(GTK_BOX(tab
->vbox
),
4055 FALSE
, /* Do not expand */
4056 FALSE
, /* Fill has no effect here (expand false) */
4057 0); /* No padding */
4059 gtk_box_pack_end(GTK_BOX(tab
->vbox
),
4061 FALSE
, /* Do not expand */
4062 FALSE
, /* Fill has no effect here (expand false) */
4063 0); /* No padding */
4065 g_object_set_data(G_OBJECT(tab
->viewer_container
), "focused_viewer", NULL
);
4071 // Display a label with a X
4072 GtkWidget *w_hbox = gtk_hbox_new(FALSE, 4);
4073 GtkWidget *w_label = gtk_label_new (label);
4074 GtkWidget *pixmap = create_pixmap(GTK_WIDGET(notebook), "close.png");
4075 GtkWidget *w_button = gtk_button_new ();
4076 gtk_container_add(GTK_CONTAINER(w_button), pixmap);
4077 //GtkWidget *w_button = gtk_button_new_with_label("x");
4079 gtk_button_set_relief(GTK_BUTTON(w_button), GTK_RELIEF_NONE);
4081 gtk_box_pack_start(GTK_BOX(w_hbox), w_label, TRUE, TRUE, 0);
4082 gtk_box_pack_end(GTK_BOX(w_hbox), w_button, FALSE,
4085 g_signal_connect_swapped (w_button, "clicked",
4086 G_CALLBACK (on_close_tab_X_clicked),
4089 gtk_widget_set_state(w_button, GTK_STATE_ACTIVE);
4091 gtk_widget_show (w_label);
4092 gtk_widget_show (pixmap);
4093 gtk_widget_show (w_button);
4094 gtk_widget_show (w_hbox);
4096 tab->label = w_hbox;
4100 tab
->label
= gtk_label_new (label
);
4102 gtk_widget_show(tab
->label
);
4103 gtk_widget_show(tab
->scrollbar
);
4104 gtk_widget_show(tab
->MTimebar
);
4105 gtk_widget_show(tab
->viewer_container
);
4106 gtk_widget_show(tab
->vbox
);
4108 //gtk_widget_show(tab->multivpaned);
4111 /* Start with empty events requests list */
4112 tab
->events_requests
= NULL
;
4113 tab
->events_request_pending
= FALSE
;
4114 tab
->stop_foreground
= FALSE
;
4118 g_signal_connect(G_OBJECT(tab
->scrollbar
), "value-changed",
4119 G_CALLBACK(scroll_value_changed_cb
), tab
);
4122 /* Timebar signal handler */
4123 g_signal_connect(G_OBJECT(tab
->MTimebar
), "start-time-changed",
4124 G_CALLBACK(on_timebar_starttime_changed
), tab
);
4125 g_signal_connect(G_OBJECT(tab
->MTimebar
), "end-time-changed",
4126 G_CALLBACK(on_timebar_endtime_changed
), tab
);
4127 g_signal_connect(G_OBJECT(tab
->MTimebar
), "current-time-changed",
4128 G_CALLBACK(on_timebar_currenttime_changed
), tab
);
4130 //g_signal_connect(G_OBJECT(tab->scrollbar), "changed",
4131 // G_CALLBACK(scroll_value_changed_cb), tab);
4134 //insert tab into notebook
4135 gtk_notebook_append_page(notebook
,
4138 list
= gtk_container_get_children(GTK_CONTAINER(notebook
));
4139 gtk_notebook_set_current_page(notebook
,g_list_length(list
)-1);
4140 // always show : not if(g_list_length(list)>1)
4141 gtk_notebook_set_show_tabs(notebook
, TRUE
);
4144 lttvwindow_report_time_window(tab
, copy_tab
->time_window
);
4145 lttvwindow_report_current_time(tab
, copy_tab
->current_time
);
4147 TimeWindow time_window
;
4149 time_window
.start_time
= ltt_time_zero
;
4150 time_window
.end_time
= ltt_time_add(time_window
.start_time
,
4151 lttvwindow_default_time_width
);
4152 time_window
.time_width
= lttvwindow_default_time_width
;
4153 time_window
.time_width_double
= ltt_time_to_double(time_window
.time_width
);
4155 lttvwindow_report_time_window(tab
, time_window
);
4156 lttvwindow_report_current_time(tab
, ltt_time_zero
);
4159 LttvTraceset
*traceset
= tab
->traceset_info
->traceset
;
4160 SetTraceset(tab
, traceset
);
4164 * execute_events_requests
4166 * Idle function that executes the pending requests for a tab.
4168 * @return return value : TRUE : keep the idle function, FALSE : remove it.
4170 gboolean
execute_events_requests(Tab
*tab
)
4172 return ( lttvwindow_process_pending_requests(tab
) );
4176 __EXPORT
void create_main_window_with_trace_list(GSList
*traces
)
4179 GSList
*iter
= NULL
;
4182 MainWindow
*mw
= construct_main_window(NULL
);
4183 GtkWidget
*widget
= mw
->mwindow
;
4185 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
4186 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
4187 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
4188 LttvPluginTab
*ptab
;
4192 ptab
= create_new_tab(widget
, NULL
);
4195 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
4199 LttvTraceset
* traceset
= lttv_traceset_new();
4200 for(iter
=traces
; iter
!=NULL
; iter
=g_slist_next(iter
)) {
4201 gchar
*path
= (gchar
*)iter
->data
;
4203 gchar abs_path
[PATH_MAX
];
4206 get_absolute_pathname(path
, abs_path
);
4208 if(lttv_traceset_add_path(traceset
,abs_path
) != 0 ){ /*failure*/
4210 g_warning("cannot open trace %s", abs_path
);
4212 GtkWidget
*dialogue
=
4213 gtk_message_dialog_new(
4214 GTK_WINDOW(gtk_widget_get_toplevel(widget
)),
4215 GTK_DIALOG_MODAL
|GTK_DIALOG_DESTROY_WITH_PARENT
,
4218 "Cannot open trace : maybe you should enter in the directory "
4220 gtk_dialog_run(GTK_DIALOG(dialogue
));
4221 gtk_widget_destroy(dialogue
);
4224 SetTraceset(tab
, traceset
);