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
)
1618 LttvTraceset
* traceset
;
1620 char abs_path
[PATH_MAX
];
1622 MainWindow
* mw_data
= get_window_data_struct(widget
);
1623 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
1625 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
1626 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
1627 LttvPluginTab
*ptab
;
1631 ptab
= create_new_tab(widget
, NULL
);
1634 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
1637 /* Create a new traceset*/
1638 traceset
= lttv_traceset_new();
1639 /* File open dialog management */
1640 GtkWidget
*extra_live_button
;
1641 GtkFileChooser
* file_chooser
=
1643 gtk_file_chooser_dialog_new ("Select a trace",
1644 GTK_WINDOW(mw_data
->mwindow
),
1645 GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER
,
1646 GTK_STOCK_CANCEL
, GTK_RESPONSE_CANCEL
,
1647 GTK_STOCK_OPEN
, GTK_RESPONSE_ACCEPT
,
1650 /* Button to indicate the opening of a live trace */
1651 extra_live_button
= gtk_check_button_new_with_mnemonic ("Trace is live (currently being writen)");
1652 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (extra_live_button
), FALSE
);
1653 gtk_file_chooser_set_extra_widget (GTK_FILE_CHOOSER (file_chooser
), extra_live_button
);
1655 gtk_file_chooser_set_show_hidden (file_chooser
, TRUE
);
1656 if(remember_trace_dir
[0] != '\0')
1657 gtk_file_chooser_set_filename(file_chooser
, remember_trace_dir
);
1659 gboolean closeFileChooserDialog
= TRUE
;
1663 id
= gtk_dialog_run(GTK_DIALOG(file_chooser
));
1665 case GTK_RESPONSE_ACCEPT
:
1666 case GTK_RESPONSE_OK
:
1667 path
= gtk_file_chooser_get_filename (file_chooser
);
1669 strncpy(remember_trace_dir
, path
, PATH_MAX
);
1670 strncat(remember_trace_dir
, "/", PATH_MAX
);
1671 if(!path
|| strlen(path
) == 0){
1674 get_absolute_pathname(path
, abs_path
);
1676 if(lttv_traceset_add_path(traceset
,abs_path
) != 0 ){ /*failure*/
1678 g_warning("cannot open trace %s", abs_path
);
1679 strncpy(remember_trace_dir
, "\0", PATH_MAX
);
1680 GtkWidget
*dialogue
=
1681 gtk_message_dialog_new(
1682 GTK_WINDOW(gtk_widget_get_toplevel(widget
)),
1683 GTK_DIALOG_MODAL
|GTK_DIALOG_DESTROY_WITH_PARENT
,
1686 "Cannot open trace : maybe you should enter in the directory "
1688 gtk_dialog_run(GTK_DIALOG(dialogue
));
1689 gtk_widget_destroy(dialogue
);
1690 closeFileChooserDialog
= FALSE
;
1693 closeFileChooserDialog
= TRUE
;
1694 SetTraceset(tab
, traceset
);
1697 //update current tab
1698 //update_traceset(mw_data);
1700 // in expose now call_pending_read_hooks(mw_data);
1702 //lttvwindow_report_current_time(mw_data,&(tab->current_time));
1704 case GTK_RESPONSE_REJECT
:
1705 case GTK_RESPONSE_CANCEL
:
1707 closeFileChooserDialog
= TRUE
;
1710 }while(!closeFileChooserDialog
);
1712 gtk_widget_destroy((GtkWidget
*)file_chooser
);
1716 /* remove_trace removes a trace from the current traceset if all viewers in
1717 * the current tab are not interested in the trace. It first displays a
1718 * dialogue, which shows all traces in the current traceset, to let user choose
1719 * a trace, then it checks if all viewers unselect the trace, if it is true,
1720 * it will remove the trace, recreate the traceset_contex,
1721 * and redraws all the viewer of the current tab. If there is on trace in the
1722 * current traceset, it will delete all viewers of the current tab
1724 * It destroys the filter tree. FIXME... we should request for an update
1728 void remove_trace(GtkWidget
*widget
, gpointer user_data
)
1730 #ifdef BABEL_CLEANUP
1732 LttvTrace
* trace_v
;
1733 LttvTraceset
* traceset
;
1734 gint i
, j
, nb_trace
, index
=-1;
1735 char ** name
, *remove_trace_name
;
1736 MainWindow
* mw_data
= get_window_data_struct(widget
);
1737 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
1739 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
1740 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
1746 LttvPluginTab
*ptab
;
1747 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
1751 nb_trace
=lttv_traceset_number(tab
->traceset_info
->traceset
);
1752 name
= g_new(char*,nb_trace
);
1753 for(i
= 0; i
< nb_trace
; i
++){
1754 trace_v
= lttv_traceset_get(tab
->traceset_info
->traceset
, i
);
1755 trace
= lttv_trace(trace_v
);
1756 name
[i
] = (char *) g_quark_to_string(ltt_trace_name(trace
));
1759 remove_trace_name
= get_remove_trace(mw_data
, name
, nb_trace
);
1762 if(remove_trace_name
){
1764 /* yuk, cut n paste from old code.. should be better (MD)*/
1765 for(i
= 0; i
<nb_trace
; i
++) {
1766 if(strcmp(remove_trace_name
,name
[i
]) == 0){
1771 traceset
= tab
->traceset_info
->traceset
;
1772 //Keep a reference to the traces so they are not freed.
1773 for(j
=0; j
<lttv_traceset_number(traceset
); j
++)
1775 LttvTrace
* trace
= lttv_traceset_get(traceset
, j
);
1776 lttv_trace_ref(trace
);
1779 //remove state update hooks
1780 lttv_state_remove_event_hooks(
1781 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1782 lttv_context_fini(LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
));
1783 g_object_unref(tab
->traceset_info
->traceset_context
);
1785 trace_v
= lttv_traceset_get(traceset
, index
);
1787 lttv_traceset_remove(traceset
, index
);
1788 lttv_trace_unref(trace_v
); // Remove local reference
1790 if(lttv_trace_get_ref_number(trace_v
) <= 1) {
1791 /* ref 1 : lttvwindowtraces only*/
1792 ltt_trace_close(lttv_trace(trace_v
));
1793 /* lttvwindowtraces_remove_trace takes care of destroying
1794 * the traceset linked with the trace_v and also of destroying
1795 * the trace_v at the same time.
1797 lttvwindowtraces_remove_trace(trace_v
);
1800 tab
->traceset_info
->traceset_context
=
1801 g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
1803 LTTV_TRACESET_CONTEXT(tab
->
1804 traceset_info
->traceset_context
),traceset
);
1805 //add state update hooks
1806 lttv_state_add_event_hooks(
1807 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1809 //Remove local reference to the traces.
1810 for(j
=0; j
<lttv_traceset_number(traceset
); j
++)
1812 LttvTrace
* trace
= lttv_traceset_get(traceset
, j
);
1813 lttv_trace_unref(trace
);
1816 SetTraceset(tab
, (gpointer
)traceset
);
1819 #endif /* BABEL_CLEANUP */
1823 void remove_trace(GtkWidget
* widget
, gpointer user_data
)
1826 LttvTrace
* trace_v
;
1827 LttvTraceset
* traceset
;
1828 gint i
, j
, nb_trace
;
1829 char ** name
, *remove_trace_name
;
1830 MainWindow
* mw_data
= get_window_data_struct(widget
);
1831 LttvTracesetSelector
* s
;
1832 LttvTraceSelector
* t
;
1835 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
1837 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
1838 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
1844 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
1847 nb_trace
=lttv_traceset_number(tab
->traceset_info
->traceset
);
1848 name
= g_new(char*,nb_trace
);
1849 for(i
= 0; i
< nb_trace
; i
++){
1850 trace_v
= lttv_traceset_get(tab
->traceset_info
->traceset
, i
);
1851 trace
= lttv_trace(trace_v
);
1852 name
[i
] = ltt_trace_name(trace
);
1855 remove_trace_name
= get_remove_trace(name
, nb_trace
);
1857 if(remove_trace_name
){
1858 for(i
=0; i
<nb_trace
; i
++){
1859 if(strcmp(remove_trace_name
,name
[i
]) == 0){
1860 //unselect the trace from the current viewer
1862 w
= gtk_multivpaned_get_widget(GTK_MULTIVPANED(tab
->multivpaned
));
1864 s
= g_object_get_data(G_OBJECT(w
), "Traceset_Selector");
1866 t
= lttv_traceset_selector_trace_get(s
,i
);
1867 lttv_trace_selector_set_selected(t
, FALSE
);
1870 //check if other viewers select the trace
1871 w
= gtk_multivpaned_get_first_widget(GTK_MULTIVPANED(tab
->multivpaned
));
1873 s
= g_object_get_data(G_OBJECT(w
), "Traceset_Selector");
1875 t
= lttv_traceset_selector_trace_get(s
,i
);
1876 selected
= lttv_trace_selector_get_selected(t
);
1879 w
= gtk_multivpaned_get_next_widget(GTK_MULTIVPANED(tab
->multivpaned
));
1881 }else selected
= FALSE
;
1883 //if no viewer selects the trace, remove it
1885 remove_trace_from_traceset_selector(GTK_MULTIVPANED(tab
->multivpaned
), i
);
1887 traceset
= tab
->traceset_info
->traceset
;
1888 //Keep a reference to the traces so they are not freed.
1889 for(j
=0; j
<lttv_traceset_number(traceset
); j
++)
1891 LttvTrace
* trace
= lttv_traceset_get(traceset
, j
);
1892 lttv_trace_ref(trace
);
1895 //remove state update hooks
1896 lttv_state_remove_event_hooks(
1897 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1898 lttv_context_fini(LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
));
1899 g_object_unref(tab
->traceset_info
->traceset_context
);
1902 trace_v
= lttv_traceset_get(traceset
, i
);
1904 if(lttv_trace_get_ref_number(trace_v
) <= 2) {
1905 /* ref 2 : traceset, local */
1906 lttvwindowtraces_remove_trace(trace_v
);
1907 ltt_trace_close(lttv_trace(trace_v
));
1910 lttv_traceset_remove(traceset
, i
);
1911 lttv_trace_unref(trace_v
); // Remove local reference
1913 if(!lttv_trace_get_ref_number(trace_v
))
1914 lttv_trace_destroy(trace_v
);
1916 tab
->traceset_info
->traceset_context
=
1917 g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
1919 LTTV_TRACESET_CONTEXT(tab
->
1920 traceset_info
->traceset_context
),traceset
);
1921 //add state update hooks
1922 lttv_state_add_event_hooks(
1923 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1925 //Remove local reference to the traces.
1926 for(j
=0; j
<lttv_traceset_number(traceset
); j
++)
1928 LttvTrace
* trace
= lttv_traceset_get(traceset
, j
);
1929 lttv_trace_unref(trace
);
1933 //update current tab
1934 //update_traceset(mw_data);
1937 SetTraceset(tab
, (gpointer
)traceset
);
1938 // in expose now call_pending_read_hooks(mw_data);
1940 //lttvwindow_report_current_time(mw_data,&(tab->current_time));
1943 // while(tab->multi_vpaned->num_children){
1944 // gtk_multi_vpaned_widget_delete(tab->multi_vpaned);
1958 /* Redraw all the viewers in the current tab */
1959 void redraw(GtkWidget
*widget
, gpointer user_data
)
1961 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
1962 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
1963 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
1970 LttvPluginTab
*ptab
;
1971 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
1976 LttvAttributeValue value
;
1978 retval
= lttv_iattribute_find_by_path(tab
->attributes
, "hooks/redraw", LTTV_POINTER
, &value
);
1981 tmp
= (LttvHooks
*)*(value
.v_pointer
);
1983 lttv_hooks_call(tmp
,NULL
);
1987 void continue_processing(GtkWidget
*widget
, gpointer user_data
)
1989 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
1990 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
1991 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
1998 LttvPluginTab
*ptab
;
1999 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
2004 LttvAttributeValue value
;
2006 retval
= lttv_iattribute_find_by_path(tab
->attributes
, "hooks/continue",
2007 LTTV_POINTER
, &value
);
2010 tmp
= (LttvHooks
*)*(value
.v_pointer
);
2012 lttv_hooks_call(tmp
,NULL
);
2015 /* Stop the processing for the calling main window's current tab.
2016 * It removes every processing requests that are in its list. It does not call
2017 * the end request hooks, because the request is not finished.
2020 void stop_processing(GtkWidget
*widget
, gpointer user_data
)
2022 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
2023 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2024 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2029 LttvPluginTab
*ptab
;
2030 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
2033 GSList
*iter
= tab
->events_requests
;
2035 while(iter
!= NULL
) {
2036 GSList
*remove_iter
= iter
;
2037 iter
= g_slist_next(iter
);
2039 g_free(remove_iter
->data
);
2040 tab
->events_requests
=
2041 g_slist_remove_link(tab
->events_requests
, remove_iter
);
2043 tab
->events_request_pending
= FALSE
;
2044 tab
->stop_foreground
= TRUE
;
2045 g_idle_remove_by_data(tab
);
2046 g_assert(g_slist_length(tab
->events_requests
) == 0);
2050 /* save will save the traceset to a file
2051 * Not implemented yet FIXME
2054 void save(GtkWidget
* widget
, gpointer user_data
)
2059 void save_as(GtkWidget
* widget
, gpointer user_data
)
2061 g_info("Save as\n");
2065 /* zoom will change the time_window of all the viewers of the
2066 * current tab, and redisplay them. The main functionality is to
2067 * determine the new time_window of the current tab
2070 void zoom(GtkWidget
* widget
, double size
)
2072 #ifdef BABEL_CLEANUP
2073 TimeInterval time_span
;
2074 TimeWindow new_time_window
;
2075 LttTime current_time
, time_delta
;
2076 LttvTracesetContext
*tsc
;
2077 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
2079 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2080 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2086 LttvPluginTab
*ptab
;
2087 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
2091 if(size
== 1) return;
2093 tsc
= LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
2094 time_span
= tsc
->time_span
;
2095 new_time_window
= tab
->time_window
;
2096 current_time
= tab
->current_time
;
2098 time_delta
= ltt_time_sub(time_span
.end_time
,time_span
.start_time
);
2100 new_time_window
.start_time
= time_span
.start_time
;
2101 new_time_window
.time_width
= time_delta
;
2102 new_time_window
.time_width_double
= ltt_time_to_double(time_delta
);
2103 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
2104 new_time_window
.time_width
) ;
2106 new_time_window
.time_width
= ltt_time_div(new_time_window
.time_width
, size
);
2107 new_time_window
.time_width_double
=
2108 ltt_time_to_double(new_time_window
.time_width
);
2109 if(ltt_time_compare(new_time_window
.time_width
,time_delta
) > 0)
2110 { /* Case where zoom out is bigger than trace length */
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
) ;
2119 /* Center the image on the current time */
2120 new_time_window
.start_time
=
2121 ltt_time_sub(current_time
,
2122 ltt_time_from_double(new_time_window
.time_width_double
/2.0));
2123 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
2124 new_time_window
.time_width
) ;
2125 /* If on borders, don't fall off */
2126 if(ltt_time_compare(new_time_window
.start_time
, time_span
.start_time
) <0
2127 || ltt_time_compare(new_time_window
.start_time
, time_span
.end_time
) >0)
2129 new_time_window
.start_time
= time_span
.start_time
;
2130 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
2131 new_time_window
.time_width
) ;
2135 if(ltt_time_compare(new_time_window
.end_time
,
2136 time_span
.end_time
) > 0
2137 || ltt_time_compare(new_time_window
.end_time
,
2138 time_span
.start_time
) < 0)
2140 new_time_window
.start_time
=
2141 ltt_time_sub(time_span
.end_time
, new_time_window
.time_width
);
2143 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
2144 new_time_window
.time_width
) ;
2151 if(ltt_time_compare(new_time_window
.time_width
, ltt_time_zero
) == 0) {
2152 g_warning("Zoom more than 1 ns impossible");
2154 time_change_manager(tab
, new_time_window
);
2157 #endif /* BABEL_CLEANUP */
2160 void zoom_in(GtkWidget
* widget
, gpointer user_data
)
2165 void zoom_out(GtkWidget
* widget
, gpointer user_data
)
2170 void zoom_extended(GtkWidget
* widget
, gpointer user_data
)
2175 void go_to_time(GtkWidget
* widget
, gpointer user_data
)
2177 g_info("Go to time\n");
2180 void show_time_frame(GtkWidget
* widget
, gpointer user_data
)
2182 g_info("Show time frame\n");
2186 /* callback function */
2189 on_empty_traceset_activate (GtkMenuItem
*menuitem
,
2192 create_new_window((GtkWidget
*)menuitem
, user_data
, FALSE
);
2197 on_clone_traceset_activate (GtkMenuItem
*menuitem
,
2200 create_new_window((GtkWidget
*)menuitem
, user_data
, TRUE
);
2204 /* create_new_tab calls create_tab to construct a new tab in the main window
2207 LttvPluginTab
*create_new_tab(GtkWidget
* widget
, gpointer user_data
)
2209 gchar label
[PATH_MAX
];
2210 MainWindow
* mw_data
= get_window_data_struct(widget
);
2212 GtkNotebook
* notebook
= (GtkNotebook
*)lookup_widget(widget
, "MNotebook");
2213 if(notebook
== NULL
){
2214 g_info("Notebook does not exist\n");
2217 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2218 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2224 LttvPluginTab
*ptab
;
2225 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
2226 copy_tab
= ptab
->tab
;
2229 strcpy(label
,"Page");
2230 if(get_label(mw_data
, label
,"Get the name of the tab","Please input tab's name")) {
2231 LttvPluginTab
*ptab
;
2233 ptab
= g_object_new(LTTV_TYPE_PLUGIN_TAB
, NULL
);
2234 init_tab (ptab
->tab
, mw_data
, copy_tab
, notebook
, label
);
2235 ptab
->parent
.top_widget
= ptab
->tab
->top_widget
;
2236 g_object_set_data_full(
2237 G_OBJECT(ptab
->tab
->vbox
),
2240 (GDestroyNotify
)tab_destructor
);
2247 on_tab_activate (GtkMenuItem
*menuitem
,
2250 create_new_tab((GtkWidget
*)menuitem
, user_data
);
2255 on_open_activate (GtkMenuItem
*menuitem
,
2258 #ifdef UNFINISHED_FEATURE
2259 open_traceset((GtkWidget
*)menuitem
, user_data
);
2265 on_close_activate (GtkMenuItem
*menuitem
,
2268 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2269 main_window_destructor(mw_data
);
2273 /* remove the current tab from the main window
2277 on_close_tab_activate (GtkWidget
*widget
,
2281 GtkWidget
* notebook
;
2282 notebook
= lookup_widget(widget
, "MNotebook");
2283 if(notebook
== NULL
){
2284 g_info("Notebook does not exist\n");
2288 page_num
= gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
));
2290 gtk_notebook_remove_page(GTK_NOTEBOOK(notebook
), page_num
);
2295 on_close_tab_X_clicked (GtkWidget
*widget
,
2299 GtkWidget
*notebook
= lookup_widget(widget
, "MNotebook");
2300 if(notebook
== NULL
){
2301 g_info("Notebook does not exist\n");
2305 if((page_num
= gtk_notebook_page_num(GTK_NOTEBOOK(notebook
), widget
)) != -1)
2306 gtk_notebook_remove_page(GTK_NOTEBOOK(notebook
), page_num
);
2312 on_add_trace_activate (GtkMenuItem
*menuitem
,
2315 add_trace((GtkWidget
*)menuitem
, user_data
);
2320 on_remove_trace_activate (GtkMenuItem
*menuitem
,
2323 remove_trace((GtkWidget
*)menuitem
, user_data
);
2328 on_save_activate (GtkMenuItem
*menuitem
,
2331 save((GtkWidget
*)menuitem
, user_data
);
2336 on_save_as_activate (GtkMenuItem
*menuitem
,
2339 save_as((GtkWidget
*)menuitem
, user_data
);
2344 on_quit_activate (GtkMenuItem
*menuitem
,
2347 while (g_slist_length(g_main_window_list
) != 0) {
2348 on_MWindow_destroy(((MainWindow
*)g_main_window_list
->data
)->mwindow
,
2355 on_cut_activate (GtkMenuItem
*menuitem
,
2363 on_copy_activate (GtkMenuItem
*menuitem
,
2371 on_paste_activate (GtkMenuItem
*menuitem
,
2379 on_delete_activate (GtkMenuItem
*menuitem
,
2387 on_zoom_in_activate (GtkMenuItem
*menuitem
,
2390 zoom_in((GtkWidget
*)menuitem
, user_data
);
2395 on_zoom_out_activate (GtkMenuItem
*menuitem
,
2398 zoom_out((GtkWidget
*)menuitem
, user_data
);
2403 on_zoom_extended_activate (GtkMenuItem
*menuitem
,
2406 zoom_extended((GtkWidget
*)menuitem
, user_data
);
2411 on_go_to_time_activate (GtkMenuItem
*menuitem
,
2414 go_to_time((GtkWidget
*)menuitem
, user_data
);
2419 on_show_time_frame_activate (GtkMenuItem
*menuitem
,
2422 show_time_frame((GtkWidget
*)menuitem
, user_data
);
2427 on_move_viewer_up_activate (GtkMenuItem
*menuitem
,
2430 move_up_viewer((GtkWidget
*)menuitem
, user_data
);
2435 on_move_viewer_down_activate (GtkMenuItem
*menuitem
,
2438 move_down_viewer((GtkWidget
*)menuitem
, user_data
);
2443 on_remove_viewer_activate (GtkMenuItem
*menuitem
,
2446 delete_viewer((GtkWidget
*)menuitem
, user_data
);
2450 on_trace_facility_activate (GtkMenuItem
*menuitem
,
2453 g_info("Trace facility selector: %s\n", "");
2457 /* Dispaly a file selection dialogue to let user select a library, then call
2458 * lttv_library_load().
2462 on_load_library_activate (GtkMenuItem
*menuitem
,
2465 GError
*error
= NULL
;
2466 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2468 gchar load_module_path_alter
[PATH_MAX
];
2472 gchar
*load_module_path
;
2473 name
= g_ptr_array_new();
2474 nb
= lttv_library_path_number();
2475 /* ask for the library path */
2479 path
= lttv_library_path_get(i
);
2480 g_ptr_array_add(name
, path
);
2483 load_module_path
= get_selection(mw_data
,
2484 (char **)(name
->pdata
), name
->len
,
2485 "Select a library path", "Library paths");
2486 if(load_module_path
!= NULL
)
2487 strncpy(load_module_path_alter
, load_module_path
, PATH_MAX
-1); // -1 for /
2489 g_ptr_array_free(name
, TRUE
);
2491 if(load_module_path
== NULL
) return;
2495 /* Make sure the module path ends with a / */
2496 gchar
*ptr
= load_module_path_alter
;
2498 ptr
= strchr(ptr
, '\0');
2500 if(*(ptr
-1) != '/') {
2507 /* Ask for the library to load : list files in the previously selected
2509 gchar str
[PATH_MAX
];
2512 GtkFileSelection
* file_selector
=
2513 (GtkFileSelection
*)gtk_file_selection_new("Select a module");
2514 gtk_file_selection_set_filename(file_selector
, load_module_path_alter
);
2515 gtk_file_selection_hide_fileop_buttons(file_selector
);
2517 gtk_window_set_transient_for(GTK_WINDOW(file_selector
),
2518 GTK_WINDOW(mw_data
->mwindow
));
2521 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
2523 case GTK_RESPONSE_ACCEPT
:
2524 case GTK_RESPONSE_OK
:
2525 dir
= gtk_file_selection_get_selections (file_selector
);
2526 strncpy(str
,dir
[0],PATH_MAX
);
2527 strncpy(remember_plugins_dir
,dir
[0],PATH_MAX
);
2528 /* only keep file name */
2530 str1
= strrchr(str
,'/');
2533 str1
= strrchr(str
,'\\');
2538 if(*str1
== 'l' && *(str1
+1)== 'i' && *(str1
+2)=='b')
2540 remove info after
. */
2544 str2
= strrchr(str2
, '.');
2545 if(str2
!= NULL
) *str2
= '\0';
2547 lttv_module_require(str1
, &error
);
2549 lttv_library_load(str1
, &error
);
2550 if(error
!= NULL
) g_warning("%s", error
->message
);
2551 else g_info("Load library: %s\n", str
);
2553 case GTK_RESPONSE_REJECT
:
2554 case GTK_RESPONSE_CANCEL
:
2556 gtk_widget_destroy((GtkWidget
*)file_selector
);
2567 /* Display all loaded modules, let user to select a module to unload
2568 * by calling lttv_module_unload
2572 on_unload_library_activate (GtkMenuItem
*menuitem
,
2575 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2577 LttvLibrary
*library
= NULL
;
2582 name
= g_ptr_array_new();
2583 nb
= lttv_library_number();
2584 LttvLibraryInfo
*lib_info
= g_new(LttvLibraryInfo
,nb
);
2585 /* ask for the library name */
2588 LttvLibrary
*iter_lib
= lttv_library_get(i
);
2589 lttv_library_info(iter_lib
, &lib_info
[i
]);
2591 gchar
*path
= lib_info
[i
].name
;
2592 g_ptr_array_add(name
, path
);
2594 lib_name
= get_selection(mw_data
, (char **)(name
->pdata
), name
->len
,
2595 "Select a library", "Libraries");
2596 if(lib_name
!= NULL
) {
2598 if(strcmp(lib_name
, lib_info
[i
].name
) == 0) {
2599 library
= lttv_library_get(i
);
2604 g_ptr_array_free(name
, TRUE
);
2607 if(lib_name
== NULL
) return;
2609 if(library
!= NULL
) lttv_library_unload(library
);
2613 /* Dispaly a file selection dialogue to let user select a module, then call
2614 * lttv_module_require().
2618 on_load_module_activate (GtkMenuItem
*menuitem
,
2621 GError
*error
= NULL
;
2622 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2624 LttvLibrary
*library
= NULL
;
2629 name
= g_ptr_array_new();
2630 nb
= lttv_library_number();
2631 LttvLibraryInfo
*lib_info
= g_new(LttvLibraryInfo
,nb
);
2632 /* ask for the library name */
2635 LttvLibrary
*iter_lib
= lttv_library_get(i
);
2636 lttv_library_info(iter_lib
, &lib_info
[i
]);
2638 gchar
*path
= lib_info
[i
].name
;
2639 g_ptr_array_add(name
, path
);
2641 lib_name
= get_selection(mw_data
,(char **)(name
->pdata
), name
->len
,
2642 "Select a library", "Libraries");
2643 if(lib_name
!= NULL
) {
2645 if(strcmp(lib_name
, lib_info
[i
].name
) == 0) {
2646 library
= lttv_library_get(i
);
2651 g_ptr_array_free(name
, TRUE
);
2654 if(lib_name
== NULL
) return;
2657 //LttvModule *module;
2658 gchar module_name_out
[PATH_MAX
];
2660 /* Ask for the module to load : list modules in the selected lib */
2664 nb
= lttv_library_module_number(library
);
2665 LttvModuleInfo
*module_info
= g_new(LttvModuleInfo
,nb
);
2666 name
= g_ptr_array_new();
2667 /* ask for the module name */
2670 LttvModule
*iter_module
= lttv_library_module_get(library
, i
);
2671 lttv_module_info(iter_module
, &module_info
[i
]);
2673 gchar
*path
= module_info
[i
].name
;
2674 g_ptr_array_add(name
, path
);
2676 module_name
= get_selection(mw_data
, (char **)(name
->pdata
), name
->len
,
2677 "Select a module", "Modules");
2678 if(module_name
!= NULL
) {
2680 if(strcmp(module_name
, module_info
[i
].name
) == 0) {
2681 strncpy(module_name_out
, module_name
, PATH_MAX
);
2682 //module = lttv_library_module_get(i);
2688 g_ptr_array_free(name
, TRUE
);
2689 g_free(module_info
);
2691 if(module_name
== NULL
) return;
2694 lttv_module_require(module_name_out
, &error
);
2695 if(error
!= NULL
) g_warning("%s", error
->message
);
2696 else g_info("Load module: %s", module_name_out
);
2703 gchar str
[PATH_MAX
];
2706 GtkFileSelection
* file_selector
=
2707 (GtkFileSelection
*)gtk_file_selection_new("Select a module");
2708 gtk_file_selection_set_filename(file_selector
, load_module_path_alter
);
2709 gtk_file_selection_hide_fileop_buttons(file_selector
);
2712 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
2714 case GTK_RESPONSE_ACCEPT
:
2715 case GTK_RESPONSE_OK
:
2716 dir
= gtk_file_selection_get_selections (file_selector
);
2717 strncpy(str
,dir
[0],PATH_MAX
);
2718 strncpy(remember_plugins_dir
,dir
[0],PATH_MAX
);
2720 /* only keep file name */
2722 str1
= strrchr(str
,'/');
2725 str1
= strrchr(str
,'\\');
2730 if(*str1
== 'l' && *(str1
+1)== 'i' && *(str1
+2)=='b')
2732 remove info after
. */
2736 str2
= strrchr(str2
, '.');
2737 if(str2
!= NULL
) *str2
= '\0';
2739 lttv_module_require(str1
, &error
);
2741 lttv_library_load(str1
, &error
);
2742 if(error
!= NULL
) g_warning(error
->message
);
2743 else g_info("Load library: %s\n", str
);
2745 case GTK_RESPONSE_REJECT
:
2746 case GTK_RESPONSE_CANCEL
:
2748 gtk_widget_destroy((GtkWidget
*)file_selector
);
2760 /* Display all loaded modules, let user to select a module to unload
2761 * by calling lttv_module_unload
2765 on_unload_module_activate (GtkMenuItem
*menuitem
,
2768 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2770 LttvLibrary
*library
= NULL
;
2775 name
= g_ptr_array_new();
2776 nb
= lttv_library_number();
2777 LttvLibraryInfo
*lib_info
= g_new(LttvLibraryInfo
,nb
);
2778 /* ask for the library name */
2781 LttvLibrary
*iter_lib
= lttv_library_get(i
);
2782 lttv_library_info(iter_lib
, &lib_info
[i
]);
2784 gchar
*path
= lib_info
[i
].name
;
2785 g_ptr_array_add(name
, path
);
2787 lib_name
= get_selection(mw_data
, (char **)(name
->pdata
), name
->len
,
2788 "Select a library", "Libraries");
2789 if(lib_name
!= NULL
) {
2791 if(strcmp(lib_name
, lib_info
[i
].name
) == 0) {
2792 library
= lttv_library_get(i
);
2797 g_ptr_array_free(name
, TRUE
);
2800 if(lib_name
== NULL
) return;
2803 LttvModule
*module
= NULL
;
2805 /* Ask for the module to load : list modules in the selected lib */
2809 nb
= lttv_library_module_number(library
);
2810 LttvModuleInfo
*module_info
= g_new(LttvModuleInfo
,nb
);
2811 name
= g_ptr_array_new();
2812 /* ask for the module name */
2815 LttvModule
*iter_module
= lttv_library_module_get(library
, i
);
2816 lttv_module_info(iter_module
, &module_info
[i
]);
2818 gchar
*path
= module_info
[i
].name
;
2819 if(module_info
[i
].use_count
> 0) g_ptr_array_add(name
, path
);
2821 module_name
= get_selection(mw_data
, (char **)(name
->pdata
), name
->len
,
2822 "Select a module", "Modules");
2823 if(module_name
!= NULL
) {
2825 if(strcmp(module_name
, module_info
[i
].name
) == 0) {
2826 module
= lttv_library_module_get(library
, i
);
2832 g_ptr_array_free(name
, TRUE
);
2833 g_free(module_info
);
2835 if(module_name
== NULL
) return;
2838 LttvModuleInfo module_info
;
2839 lttv_module_info(module
, &module_info
);
2840 g_info("Release module: %s\n", module_info
.name
);
2842 lttv_module_release(module
);
2846 /* Display a directory dialogue to let user select a path for library searching
2850 on_add_library_search_path_activate (GtkMenuItem
*menuitem
,
2853 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2854 //GtkDirSelection * file_selector = (GtkDirSelection *)gtk_dir_selection_new("Select library path");
2855 GtkFileSelection
* file_selector
= (GtkFileSelection
*)gtk_file_selection_new("Select a trace");
2856 gtk_widget_hide( (file_selector
)->file_list
->parent
) ;
2858 gtk_window_set_transient_for(GTK_WINDOW(file_selector
),
2859 GTK_WINDOW(mw_data
->mwindow
));
2864 if(remember_plugins_dir
[0] != '\0')
2865 gtk_file_selection_set_filename(file_selector
, remember_plugins_dir
);
2867 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
2869 case GTK_RESPONSE_ACCEPT
:
2870 case GTK_RESPONSE_OK
:
2871 dir
= gtk_file_selection_get_filename (file_selector
);
2872 strncpy(remember_plugins_dir
,dir
,PATH_MAX
);
2873 strncat(remember_plugins_dir
,"/",PATH_MAX
);
2874 lttv_library_path_add(dir
);
2875 case GTK_RESPONSE_REJECT
:
2876 case GTK_RESPONSE_CANCEL
:
2878 gtk_widget_destroy((GtkWidget
*)file_selector
);
2884 /* Display a directory dialogue to let user select a path for library searching
2888 on_remove_library_search_path_activate (GtkMenuItem
*menuitem
,
2891 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2893 const char *lib_path
;
2897 name
= g_ptr_array_new();
2898 nb
= lttv_library_path_number();
2899 /* ask for the library name */
2902 gchar
*path
= lttv_library_path_get(i
);
2903 g_ptr_array_add(name
, path
);
2905 lib_path
= get_selection(mw_data
, (char **)(name
->pdata
), name
->len
,
2906 "Select a library path", "Library paths");
2908 g_ptr_array_free(name
, TRUE
);
2910 if(lib_path
== NULL
) return;
2913 lttv_library_path_remove(lib_path
);
2917 on_color_activate (GtkMenuItem
*menuitem
,
2925 on_save_configuration_activate (GtkMenuItem
*menuitem
,
2928 g_info("Save configuration\n");
2933 on_content_activate (GtkMenuItem
*menuitem
,
2936 char* filename
= NULL
,
2939 const char* relativePath
= "doc/user/user_guide/html/index.html";
2940 filename
= g_build_filename (g_get_current_dir(), relativePath
, NULL
);
2941 path
= g_strdup_printf ("ghelp://%s", filename
);
2943 screen
= gdk_screen_get_default();
2944 gtk_show_uri (screen
, path
, gtk_get_current_event_time(), NULL
);
2948 g_info("Content\n");
2953 on_about_close_activate (GtkButton
*button
,
2956 GtkWidget
*about_widget
= GTK_WIDGET(user_data
);
2958 gtk_widget_destroy(about_widget
);
2962 on_about_activate (GtkMenuItem
*menuitem
,
2965 MainWindow
*main_window
= get_window_data_struct(GTK_WIDGET(menuitem
));
2966 GtkWidget
*window_widget
= main_window
->mwindow
;
2967 GtkWidget
*about_widget
= gtk_window_new(GTK_WINDOW_TOPLEVEL
);
2968 GtkWindow
*about_window
= GTK_WINDOW(about_widget
);
2970 gtk_window_set_title(about_window
, "About Linux Trace Toolkit");
2972 gtk_window_set_resizable(about_window
, FALSE
);
2973 gtk_window_set_transient_for(about_window
, GTK_WINDOW(window_widget
));
2974 gtk_window_set_destroy_with_parent(about_window
, TRUE
);
2975 gtk_window_set_modal(about_window
, FALSE
);
2977 /* Put the about window at the center of the screen */
2978 gtk_window_set_position(about_window
, GTK_WIN_POS_CENTER_ALWAYS
);
2980 GtkWidget
*vbox
= gtk_vbox_new(FALSE
, 1);
2982 gtk_container_add(GTK_CONTAINER(about_widget
), vbox
);
2985 GtkWidget
*label1
= gtk_label_new("");
2986 gtk_misc_set_padding(GTK_MISC(label1
), 10, 20);
2987 gtk_label_set_markup(GTK_LABEL(label1
), "\
2988 <big>Linux Trace Toolkit " VERSION
"</big>");
2989 gtk_label_set_justify(GTK_LABEL(label1
), GTK_JUSTIFY_CENTER
);
2991 GtkWidget
*label2
= gtk_label_new("");
2992 gtk_misc_set_padding(GTK_MISC(label2
), 10, 20);
2993 gtk_label_set_markup(GTK_LABEL(label2
), "\
2996 Michel Dagenais (New trace format, lttv main)\n\
2997 Mathieu Desnoyers (Kernel Tracer, Directory structure, build with automake/conf,\n\
2998 lttv gui, control flow view, gui cooperative trace reading\n\
2999 scheduler with interruptible foreground and background\n\
3000 computation, detailed event list (rewrite), trace reading\n\
3001 library (rewrite))\n\
3002 Benoit Des Ligneris, Eric Clement (Cluster adaptation, work in progress)\n\
3003 Xang-Xiu Yang (new trace reading library and converter, lttv gui, \n\
3004 detailed event list and statistics view)\n\
3005 Tom Zanussi (RelayFS)\n\
3007 Inspired from the original Linux Trace Toolkit Visualizer made by\n\
3010 GtkWidget
*label3
= gtk_label_new("");
3011 gtk_label_set_markup(GTK_LABEL(label3
), "\
3012 Linux Trace Toolkit Viewer, Copyright (C) 2004, 2005, 2006\n\
3014 Mathieu Desnoyers\n\
3016 Linux Trace Toolkit comes with ABSOLUTELY NO WARRANTY.\n\
3017 This is free software, and you are welcome to redistribute it\n\
3018 under certain conditions. See COPYING for details.");
3019 gtk_misc_set_padding(GTK_MISC(label3
), 10, 20);
3021 gtk_box_pack_start_defaults(GTK_BOX(vbox
), label1
);
3022 gtk_box_pack_start_defaults(GTK_BOX(vbox
), label2
);
3023 gtk_box_pack_start_defaults(GTK_BOX(vbox
), label3
);
3025 GtkWidget
*hbox
= gtk_hbox_new(TRUE
, 0);
3026 gtk_box_pack_end(GTK_BOX(vbox
), hbox
, FALSE
, FALSE
, 0);
3027 GtkWidget
*close_button
= gtk_button_new_with_mnemonic("_Close");
3028 gtk_box_pack_end(GTK_BOX(hbox
), close_button
, FALSE
, FALSE
, 0);
3029 gtk_container_set_border_width(GTK_CONTAINER(close_button
), 20);
3031 g_signal_connect(G_OBJECT(close_button
), "clicked",
3032 G_CALLBACK(on_about_close_activate
),
3033 (gpointer
)about_widget
);
3035 gtk_widget_show_all(about_widget
);
3040 on_button_new_clicked (GtkButton
*button
,
3043 create_new_window((GtkWidget
*)button
, user_data
, TRUE
);
3047 on_button_new_tab_clicked (GtkButton
*button
,
3050 create_new_tab((GtkWidget
*)button
, user_data
);
3054 on_button_open_clicked (GtkButton
*button
,
3057 #ifdef UNFINISHED_FEATURE
3058 open_traceset((GtkWidget
*)button
, user_data
);
3064 on_button_add_trace_clicked (GtkButton
*button
,
3067 add_trace((GtkWidget
*)button
, user_data
);
3072 on_button_remove_trace_clicked (GtkButton
*button
,
3075 remove_trace((GtkWidget
*)button
, user_data
);
3079 on_button_redraw_clicked (GtkButton
*button
,
3082 redraw((GtkWidget
*)button
, user_data
);
3086 on_button_continue_processing_clicked (GtkButton
*button
,
3089 continue_processing((GtkWidget
*)button
, user_data
);
3093 on_button_stop_processing_clicked (GtkButton
*button
,
3096 stop_processing((GtkWidget
*)button
, user_data
);
3102 on_button_save_clicked (GtkButton
*button
,
3105 save((GtkWidget
*)button
, user_data
);
3110 on_button_save_as_clicked (GtkButton
*button
,
3113 save_as((GtkWidget
*)button
, user_data
);
3118 on_button_zoom_in_clicked (GtkButton
*button
,
3121 zoom_in((GtkWidget
*)button
, user_data
);
3126 on_button_zoom_out_clicked (GtkButton
*button
,
3129 zoom_out((GtkWidget
*)button
, user_data
);
3134 on_button_zoom_extended_clicked (GtkButton
*button
,
3137 zoom_extended((GtkWidget
*)button
, user_data
);
3142 on_button_go_to_time_clicked (GtkButton
*button
,
3145 go_to_time((GtkWidget
*)button
, user_data
);
3150 on_button_show_time_frame_clicked (GtkButton
*button
,
3153 show_time_frame((GtkWidget
*)button
, user_data
);
3158 on_button_move_up_clicked (GtkButton
*button
,
3161 move_up_viewer((GtkWidget
*)button
, user_data
);
3166 on_button_move_down_clicked (GtkButton
*button
,
3169 move_down_viewer((GtkWidget
*)button
, user_data
);
3174 on_button_delete_viewer_clicked (GtkButton
*button
,
3177 delete_viewer((GtkWidget
*)button
, user_data
);
3181 on_MWindow_destroy (GtkWidget
*widget
,
3184 MainWindow
*main_window
= get_window_data_struct(widget
);
3185 LttvIAttribute
*attributes
= main_window
->attributes
;
3186 LttvAttributeValue value
;
3189 //This is unnecessary, since widgets will be destroyed
3190 //by the main window widget anyway.
3191 //remove_all_menu_toolbar_constructors(main_window, NULL);
3193 retval
= lttv_iattribute_find_by_path(attributes
, "viewers/menu",
3194 LTTV_POINTER
, &value
);
3196 lttv_menus_destroy((LttvMenus
*)*(value
.v_pointer
));
3198 retval
= lttv_iattribute_find_by_path(attributes
, "viewers/toolbar",
3199 LTTV_POINTER
, &value
);
3201 lttv_toolbars_destroy((LttvToolbars
*)*(value
.v_pointer
));
3203 g_object_unref(main_window
->attributes
);
3204 g_main_window_list
= g_slist_remove(g_main_window_list
, main_window
);
3206 g_info("There are now : %d windows\n",g_slist_length(g_main_window_list
));
3207 if(g_slist_length(g_main_window_list
) == 0)
3212 on_MWindow_configure (GtkWidget
*widget
,
3213 GdkEventConfigure
*event
,
3216 // MD : removed time width modification upon resizing of the main window.
3217 // The viewers will redraw themselves completely, without time interval
3220 if(mw_data->window_width){
3221 time_span = LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context)->Time_Span ;
3222 time_win = tab->time_window;
3223 ratio = width / mw_data->window_width;
3224 tab->time_window.time_width = ltt_time_mul(time_win.time_width,ratio);
3225 time = ltt_time_sub(time_span->endTime, time_win.start_time);
3226 if(ltt_time_compare(time, tab->time_window.time_width) < 0){
3227 tab->time_window.time_width = time;
3233 mw_data->window_width = (int)width;
3242 on_MNotebook_switch_page (GtkNotebook
*notebook
,
3243 GtkNotebookPage
*page
,
3251 void time_change_manager (Tab
*tab
,
3252 TimeWindow new_time_window
)
3255 /* Only one source of time change */
3256 if(tab
->time_manager_lock
== TRUE
) return;
3258 tab
->time_manager_lock
= TRUE
;
3259 TimeInterval time_span
;
3261 LttvTraceset
*ts
= tab
->traceset_info
->traceset
;
3262 time_span
.start_time
=ltt_time_from_uint64( lttv_traceset_get_timestamp_begin(ts
));
3263 time_span
.end_time
= ltt_time_from_uint64(lttv_traceset_get_timestamp_end(ts
));
3266 LttTime start_time
= new_time_window
.start_time
;
3267 LttTime end_time
= new_time_window
.end_time
;
3269 g_assert(ltt_time_compare(start_time
, end_time
) < 0);
3272 GtkAdjustment
*adjustment
= gtk_range_get_adjustment(GTK_RANGE(tab
->scrollbar
));
3273 LttTime upper
= ltt_time_sub(time_span
.end_time
, time_span
.start_time
);
3276 gtk_range_set_increments(GTK_RANGE(tab
->scrollbar
),
3277 ltt_time_to_double(new_time_window
.time_width
)
3278 / SCROLL_STEP_PER_PAGE
3279 * NANOSECONDS_PER_SECOND
, /* step increment */
3280 ltt_time_to_double(new_time_window
.time_width
)
3281 * NANOSECONDS_PER_SECOND
); /* page increment */
3282 gtk_range_set_range(GTK_RANGE(tab
->scrollbar
),
3284 ltt_time_to_double(upper
)
3285 * NANOSECONDS_PER_SECOND
); /* upper */
3287 g_object_set(G_OBJECT(adjustment
),
3291 ltt_time_to_double(upper
), /* upper */
3293 new_time_window
.time_width_double
3294 / SCROLL_STEP_PER_PAGE
, /* step increment */
3296 new_time_window
.time_width_double
,
3297 /* page increment */
3299 new_time_window
.time_width_double
, /* page size */
3301 gtk_adjustment_changed(adjustment
);
3303 // g_object_set(G_OBJECT(adjustment),
3305 // ltt_time_to_double(
3306 // ltt_time_sub(start_time, time_span.start_time))
3309 //gtk_adjustment_value_changed(adjustment);
3310 gtk_range_set_value(GTK_RANGE(tab
->scrollbar
),
3312 ltt_time_sub(start_time
, time_span
.start_time
)) /* value */);
3314 /* set the time bar. */
3317 timebar_set_minmax_time(TIMEBAR(tab
->MTimebar
),
3318 &time_span
.start_time
,
3319 &time_span
.end_time
);
3320 timebar_set_start_time(TIMEBAR(tab
->MTimebar
),&start_time
);
3321 timebar_set_end_time(TIMEBAR(tab
->MTimebar
),&end_time
);
3325 /* call viewer hooks for new time window */
3326 set_time_window(tab
, &new_time_window
);
3328 tab
->time_manager_lock
= FALSE
;
3337 void current_time_change_manager (Tab
*tab
,
3338 LttTime new_current_time
)
3340 /* Only one source of time change */
3341 if(tab
->current_time_manager_lock
== TRUE
) return;
3343 tab
->current_time_manager_lock
= TRUE
;
3345 timebar_set_current_time(TIMEBAR(tab
->MTimebar
), &new_current_time
);
3347 set_current_time(tab
, &new_current_time
);
3349 tab
->current_time_manager_lock
= FALSE
;
3352 void current_position_change_manager(Tab
*tab
,
3353 LttvTracesetPosition
*pos
)
3355 #ifdef BABEL_CLEANUP
3356 LttvTracesetContext
*tsc
=
3357 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3360 retval
= lttv_process_traceset_seek_position(tsc
, pos
);
3361 g_assert_cmpint(retval
, ==, 0);
3362 LttTime new_time
= lttv_traceset_context_position_get_time(pos
);
3363 /* Put the context in a state coherent position */
3364 lttv_state_traceset_seek_time_closest((LttvTracesetState
*)tsc
, ltt_time_zero
);
3366 current_time_change_manager(tab
, new_time
);
3368 set_current_position(tab
, pos
);
3369 #endif /* BABEL_CLEANUP */
3372 static void on_timebar_starttime_changed(Timebar
*timebar
,
3375 #ifdef BABEL_CLEANUP
3376 Tab
*tab
= (Tab
*)user_data
;
3377 LttvTracesetContext
* tsc
=
3378 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3379 TimeInterval time_span
= tsc
->time_span
;
3381 TimeWindow new_time_window
= tab
->time_window
;
3382 new_time_window
.start_time
= timebar_get_start_time(timebar
);
3384 LttTime end_time
= new_time_window
.end_time
;
3386 /* TODO ybrosseau 2010-12-02: This if should have been checked
3387 by the timebar already */
3388 if(ltt_time_compare(new_time_window
.start_time
, end_time
) >= 0) {
3389 /* Then, we must push back end time : keep the same time width
3390 * if possible, else end traceset time */
3391 end_time
= LTT_TIME_MIN(ltt_time_add(new_time_window
.start_time
,
3392 new_time_window
.time_width
),
3393 time_span
.end_time
);
3396 /* Fix the time width to fit start time and end time */
3397 new_time_window
.time_width
= ltt_time_sub(end_time
,
3398 new_time_window
.start_time
);
3400 new_time_window
.time_width_double
=
3401 ltt_time_to_double(new_time_window
.time_width
);
3403 new_time_window
.end_time
= end_time
;
3405 /* Notify the time_manager */
3406 time_change_manager(tab
, new_time_window
);
3407 #endif /* BABEL_CLEANUP */
3410 static void on_timebar_endtime_changed(Timebar
*timebar
,
3413 #ifdef BABEL_CLEANUP
3414 Tab
*tab
= (Tab
*)user_data
;
3415 LttvTracesetContext
* tsc
=
3416 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3417 TimeInterval time_span
= tsc
->time_span
;
3419 TimeWindow new_time_window
= tab
->time_window
;
3421 LttTime end_time
= timebar_get_end_time(timebar
);
3423 /* TODO ybrosseau 2010-12-02: This if should have been
3424 checked by the timebar already */
3425 if(ltt_time_compare(new_time_window
.start_time
, end_time
) >= 0) {
3426 /* Then, we must push front start time : keep the same time
3427 width if possible, else end traceset time */
3428 new_time_window
.start_time
= LTT_TIME_MAX(
3429 ltt_time_sub(end_time
,
3430 new_time_window
.time_width
),
3431 time_span
.start_time
);
3434 /* Fix the time width to fit start time and end time */
3435 new_time_window
.time_width
= ltt_time_sub(end_time
,
3436 new_time_window
.start_time
);
3438 new_time_window
.time_width_double
=
3439 ltt_time_to_double(new_time_window
.time_width
);
3441 new_time_window
.end_time
= end_time
;
3443 /* Notify the time_manager */
3444 time_change_manager(tab
, new_time_window
);
3445 #endif /* BABEL_CLEANUP*/
3447 static void on_timebar_currenttime_changed(Timebar
*timebar
,
3450 Tab
*tab
= (Tab
*)user_data
;
3452 LttTime new_current_time
= timebar_get_current_time(timebar
);
3454 current_time_change_manager(tab
, new_current_time
);
3457 void scroll_value_changed_cb(GtkWidget
*scrollbar
,
3460 #ifdef BABEL_CLEANUP
3461 Tab
*tab
= (Tab
*)user_data
;
3462 TimeWindow new_time_window
;
3464 GtkAdjustment
*adjust
= gtk_range_get_adjustment(GTK_RANGE(scrollbar
));
3465 gdouble value
= gtk_adjustment_get_value(adjust
);
3466 // gdouble upper, lower, ratio, page_size;
3468 LttvTracesetContext
* tsc
=
3469 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3470 TimeInterval time_span
= tsc
->time_span
;
3472 time
= ltt_time_add(ltt_time_from_double(value
),
3473 time_span
.start_time
);
3475 new_time_window
.start_time
= time
;
3477 page_size
= adjust
->page_size
;
3479 new_time_window
.time_width
=
3480 ltt_time_from_double(page_size
);
3482 new_time_window
.time_width_double
=
3485 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
3486 new_time_window
.time_width
);
3489 time_change_manager(tab
, new_time_window
);
3491 //time_window = tab->time_window;
3493 lower
= adjust
->lower
;
3494 upper
= adjust
->upper
;
3495 ratio
= (value
- lower
) / (upper
- lower
);
3496 g_info("lower %lu, upper %lu, value %lu, ratio %lu", lower
, upper
, value
, ratio
);
3498 //time = ltt_time_sub(time_span->end_time, time_span->start_time);
3499 //time = ltt_time_mul(time, (float)ratio);
3500 //time = ltt_time_add(time_span->start_time, time);
3501 time
= ltt_time_add(ltt_time_from_double(value
),
3502 time_span
.start_time
);
3504 time_window
.start_time
= time
;
3506 page_size
= adjust
->page_size
;
3508 time_window
.time_width
=
3509 ltt_time_from_double(page_size
);
3510 //time = ltt_time_sub(time_span.end_time, time);
3511 //if(ltt_time_compare(time,time_window.time_width) < 0){
3512 // time_window.time_width = time;
3515 /* call viewer hooks for new time window */
3516 set_time_window(tab
, &time_window
);
3518 #endif /* BABEL_CLEANUP */
3522 /* Display a dialogue showing all eventtypes and traces, let user to select the interested
3523 * eventtypes, tracefiles and traces (filter)
3526 /* Select a trace which will be removed from traceset
3529 char * get_remove_trace(MainWindow
*mw_data
,
3530 char ** all_trace_name
, int nb_trace
)
3532 return get_selection(mw_data
, all_trace_name
, nb_trace
,
3533 "Select a trace", "Trace pathname");
3537 /* Select a module which will be loaded
3540 char * get_load_module(MainWindow
*mw_data
,
3541 char ** load_module_name
, int nb_module
)
3543 return get_selection(mw_data
, load_module_name
, nb_module
,
3544 "Select a module to load", "Module name");
3550 /* Select a module which will be unloaded
3553 char * get_unload_module(MainWindow
*mw_data
,
3554 char ** loaded_module_name
, int nb_module
)
3556 return get_selection(mw_data
, loaded_module_name
, nb_module
,
3557 "Select a module to unload", "Module name");
3561 /* Display a dialogue which shows all selectable items, let user to
3562 * select one of them
3565 char * get_selection(MainWindow
*mw_data
,
3566 char ** loaded_module_name
, int nb_module
,
3567 char *title
, char * column_title
)
3569 GtkWidget
* dialogue
;
3570 GtkWidget
* scroll_win
;
3572 GtkListStore
* store
;
3573 GtkTreeViewColumn
* column
;
3574 GtkCellRenderer
* renderer
;
3575 GtkTreeSelection
* select
;
3578 char * unload_module_name
= NULL
;
3580 dialogue
= gtk_dialog_new_with_buttons(title
,
3583 GTK_STOCK_OK
,GTK_RESPONSE_ACCEPT
,
3584 GTK_STOCK_CANCEL
,GTK_RESPONSE_REJECT
,
3586 gtk_window_set_default_size((GtkWindow
*)dialogue
, 500, 200);
3587 gtk_window_set_transient_for(GTK_WINDOW(dialogue
),
3588 GTK_WINDOW(mw_data
->mwindow
));
3590 scroll_win
= gtk_scrolled_window_new (NULL
, NULL
);
3591 gtk_widget_show ( scroll_win
);
3592 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll_win
),
3593 GTK_POLICY_AUTOMATIC
, GTK_POLICY_AUTOMATIC
);
3595 store
= gtk_list_store_new (N_COLUMNS
,G_TYPE_STRING
);
3596 tree
= gtk_tree_view_new_with_model(GTK_TREE_MODEL (store
));
3597 gtk_widget_show ( tree
);
3598 g_object_unref (G_OBJECT (store
));
3600 renderer
= gtk_cell_renderer_text_new ();
3601 column
= gtk_tree_view_column_new_with_attributes (column_title
,
3603 "text", MODULE_COLUMN
,
3605 gtk_tree_view_column_set_alignment (column
, 0.5);
3606 gtk_tree_view_column_set_fixed_width (column
, 150);
3607 gtk_tree_view_append_column (GTK_TREE_VIEW (tree
), column
);
3609 select
= gtk_tree_view_get_selection (GTK_TREE_VIEW (tree
));
3610 gtk_tree_selection_set_mode (select
, GTK_SELECTION_SINGLE
);
3612 gtk_container_add (GTK_CONTAINER (scroll_win
), tree
);
3614 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialogue
)->vbox
), scroll_win
,TRUE
, TRUE
,0);
3616 for(i
=0;i
<nb_module
;i
++){
3617 gtk_list_store_append (store
, &iter
);
3618 gtk_list_store_set (store
, &iter
, MODULE_COLUMN
,loaded_module_name
[i
],-1);
3621 id
= gtk_dialog_run(GTK_DIALOG(dialogue
));
3622 GtkTreeModel
**store_model
= (GtkTreeModel
**)&store
;
3624 case GTK_RESPONSE_ACCEPT
:
3625 case GTK_RESPONSE_OK
:
3626 if (gtk_tree_selection_get_selected (select
, store_model
, &iter
)){
3627 gtk_tree_model_get ((GtkTreeModel
*)store
, &iter
, MODULE_COLUMN
, &unload_module_name
, -1);
3629 case GTK_RESPONSE_REJECT
:
3630 case GTK_RESPONSE_CANCEL
:
3632 gtk_widget_destroy(dialogue
);
3636 return unload_module_name
;
3640 /* Insert all menu entry and tool buttons into this main window
3645 void add_all_menu_toolbar_constructors(MainWindow
* mw
, gpointer user_data
)
3649 lttvwindow_viewer_constructor constructor
;
3650 LttvMenus
* global_menu
, * instance_menu
;
3651 LttvToolbars
* global_toolbar
, * instance_toolbar
;
3652 LttvMenuClosure
*menu_item
;
3653 LttvToolbarClosure
*toolbar_item
;
3654 LttvAttributeValue value
;
3655 LttvIAttribute
*global_attributes
= LTTV_IATTRIBUTE(lttv_global_attributes());
3656 LttvIAttribute
*attributes
= mw
->attributes
;
3657 GtkWidget
* tool_menu_title_menu
, *new_widget
, *pixmap
;
3660 retval
= lttv_iattribute_find_by_path(global_attributes
, "viewers/menu",
3661 LTTV_POINTER
, &value
);
3663 if(*(value
.v_pointer
) == NULL
)
3664 *(value
.v_pointer
) = lttv_menus_new();
3665 global_menu
= (LttvMenus
*)*(value
.v_pointer
);
3667 retval
= lttv_iattribute_find_by_path(attributes
, "viewers/menu",
3668 LTTV_POINTER
, &value
);
3670 if(*(value
.v_pointer
) == NULL
)
3671 *(value
.v_pointer
) = lttv_menus_new();
3672 instance_menu
= (LttvMenus
*)*(value
.v_pointer
);
3674 retval
= lttv_iattribute_find_by_path(global_attributes
, "viewers/toolbar",
3675 LTTV_POINTER
, &value
);
3677 if(*(value
.v_pointer
) == NULL
)
3678 *(value
.v_pointer
) = lttv_toolbars_new();
3679 global_toolbar
= (LttvToolbars
*)*(value
.v_pointer
);
3681 retval
= lttv_iattribute_find_by_path(attributes
, "viewers/toolbar",
3682 LTTV_POINTER
, &value
);
3684 if(*(value
.v_pointer
) == NULL
)
3685 *(value
.v_pointer
) = lttv_toolbars_new();
3686 instance_toolbar
= (LttvToolbars
*)*(value
.v_pointer
);
3688 /* Add missing menu entries to window instance */
3689 for(i
=0;i
<global_menu
->len
;i
++) {
3690 menu_item
= &g_array_index(global_menu
, LttvMenuClosure
, i
);
3692 //add menu_item to window instance;
3693 constructor
= menu_item
->con
;
3694 tool_menu_title_menu
= lookup_widget(mw
->mwindow
,"ToolMenuTitle_menu");
3696 gtk_menu_item_new_with_mnemonic (menu_item
->menu_text
);
3697 gtk_container_add (GTK_CONTAINER (tool_menu_title_menu
),
3699 g_signal_connect ((gpointer
) new_widget
, "activate",
3700 G_CALLBACK (insert_viewer_wrap
),
3702 gtk_widget_show (new_widget
);
3703 lttv_menus_add(instance_menu
, menu_item
->con
,
3704 menu_item
->menu_path
,
3705 menu_item
->menu_text
,
3710 /* Add missing toolbar entries to window instance */
3711 for(i
=0;i
<global_toolbar
->len
;i
++) {
3712 toolbar_item
= &g_array_index(global_toolbar
, LttvToolbarClosure
, i
);
3714 //add toolbar_item to window instance;
3715 constructor
= toolbar_item
->con
;
3716 tool_menu_title_menu
= lookup_widget(mw
->mwindow
,"MToolbar1");
3717 pixbuf
= gdk_pixbuf_new_from_xpm_data((const char**)toolbar_item
->pixmap
);
3718 pixmap
= gtk_image_new_from_pixbuf(pixbuf
);
3720 gtk_toolbar_append_element (GTK_TOOLBAR (tool_menu_title_menu
),
3721 GTK_TOOLBAR_CHILD_BUTTON
,
3724 toolbar_item
->tooltip
, NULL
,
3725 pixmap
, NULL
, NULL
);
3726 gtk_label_set_use_underline(
3727 GTK_LABEL (((GtkToolbarChild
*) (
3728 g_list_last (GTK_TOOLBAR
3729 (tool_menu_title_menu
)->children
)->data
))->label
),
3731 gtk_container_set_border_width (GTK_CONTAINER (new_widget
), 1);
3732 g_signal_connect ((gpointer
) new_widget
,
3734 G_CALLBACK (insert_viewer_wrap
),
3736 gtk_widget_show (new_widget
);
3738 lttv_toolbars_add(instance_toolbar
, toolbar_item
->con
,
3739 toolbar_item
->tooltip
,
3740 toolbar_item
->pixmap
,
3748 /* Create a main window
3751 MainWindow
*construct_main_window(MainWindow
* parent
)
3755 g_debug("construct_main_window()");
3756 GtkWidget
* new_window
; /* New generated main window */
3757 MainWindow
* new_m_window
;/* New main window structure */
3758 GtkNotebook
* notebook
;
3759 LttvIAttribute
*attributes
=
3760 LTTV_IATTRIBUTE(g_object_new(LTTV_ATTRIBUTE_TYPE
, NULL
));
3761 LttvAttributeValue value
;
3763 new_m_window
= g_new(MainWindow
, 1);
3765 // Add the object's information to the module's array
3766 g_main_window_list
= g_slist_append(g_main_window_list
, new_m_window
);
3768 new_window
= create_MWindow();
3769 gtk_widget_show (new_window
);
3771 new_m_window
->mwindow
= new_window
;
3772 new_m_window
->attributes
= attributes
;
3774 retval
= lttv_iattribute_find_by_path(attributes
, "viewers/menu",
3775 LTTV_POINTER
, &value
);
3777 *(value
.v_pointer
) = lttv_menus_new();
3779 retval
= lttv_iattribute_find_by_path(attributes
, "viewers/toolbar",
3780 LTTV_POINTER
, &value
);
3782 *(value
.v_pointer
) = lttv_toolbars_new();
3784 add_all_menu_toolbar_constructors(new_m_window
, NULL
);
3786 g_object_set_data_full(G_OBJECT(new_window
),
3788 (gpointer
)new_m_window
,
3789 (GDestroyNotify
)g_free
);
3790 //create a default tab
3791 notebook
= (GtkNotebook
*)lookup_widget(new_m_window
->mwindow
, "MNotebook");
3792 if(notebook
== NULL
){
3793 g_info("Notebook does not exist\n");
3794 /* FIXME : destroy partially created widgets */
3795 g_free(new_m_window
);
3798 //gtk_notebook_popup_enable (GTK_NOTEBOOK(notebook));
3799 //for now there is no name field in LttvTraceset structure
3800 //Use "Traceset" as the label for the default tab
3802 GtkWidget
* parent_notebook
= lookup_widget(parent
->mwindow
, "MNotebook");
3803 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(parent_notebook
),
3804 gtk_notebook_get_current_page(GTK_NOTEBOOK(parent_notebook
)));
3810 LttvPluginTab
*ptab
;
3811 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
3812 parent_tab
= ptab
->tab
;
3814 LttvPluginTab
*ptab
= g_object_new(LTTV_TYPE_PLUGIN_TAB
, NULL
);
3816 new_m_window
, parent_tab
, notebook
, "Traceset");
3817 ptab
->parent
.top_widget
= ptab
->tab
->top_widget
;
3818 g_object_set_data_full(
3819 G_OBJECT(ptab
->tab
->vbox
),
3822 (GDestroyNotify
)tab_destructor
);
3824 LttvPluginTab
*ptab
= g_object_new(LTTV_TYPE_PLUGIN_TAB
, NULL
);
3825 init_tab(ptab
->tab
, new_m_window
, NULL
, notebook
, "Traceset");
3826 ptab
->parent
.top_widget
= ptab
->tab
->top_widget
;
3827 g_object_set_data_full(
3828 G_OBJECT(ptab
->tab
->vbox
),
3831 (GDestroyNotify
)tab_destructor
);
3834 /* Insert default viewers */
3836 LttvAttributeType type
;
3837 LttvAttributeName name
;
3838 LttvAttributeValue value
;
3839 LttvAttribute
*attribute
;
3841 LttvIAttribute
*attributes_global
=
3842 LTTV_IATTRIBUTE(lttv_global_attributes());
3844 attribute
= LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
3845 LTTV_IATTRIBUTE(attributes_global
),
3846 LTTV_VIEWER_CONSTRUCTORS
));
3847 g_assert(attribute
);
3849 name
= g_quark_from_string("guievents");
3850 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
3852 if(type
== LTTV_POINTER
) {
3853 lttvwindow_viewer_constructor viewer_constructor
=
3854 (lttvwindow_viewer_constructor
)*value
.v_pointer
;
3855 insert_viewer(new_window
, viewer_constructor
);
3858 name
= g_quark_from_string("guicontrolflow");
3859 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
3861 if(type
== LTTV_POINTER
) {
3862 lttvwindow_viewer_constructor viewer_constructor
=
3863 (lttvwindow_viewer_constructor
)*value
.v_pointer
;
3864 insert_viewer(new_window
, viewer_constructor
);
3867 name
= g_quark_from_string("guistatistics");
3868 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
3870 if(type
== LTTV_POINTER
) {
3871 lttvwindow_viewer_constructor viewer_constructor
=
3872 (lttvwindow_viewer_constructor
)*value
.v_pointer
;
3873 insert_viewer(new_window
, viewer_constructor
);
3877 g_info("There are now : %d windows\n",g_slist_length(g_main_window_list
));
3879 return new_m_window
;
3883 /* Free the memory occupied by a tab structure
3887 void tab_destructor(LttvPluginTab
* ptab
)
3889 #ifdef BABEL_CLEANUP
3890 int i
, nb
, ref_count
;
3892 Tab
*tab
= ptab
->tab
;
3895 g_object_unref(tab
->attributes
);
3897 if(tab
->interrupted_state
)
3898 g_object_unref(tab
->interrupted_state
);
3901 if(tab
->traceset_info
->traceset_context
!= NULL
){
3902 //remove state update hooks
3903 lttv_state_remove_event_hooks(
3904 (LttvTracesetState
*)tab
->traceset_info
->
3906 lttv_context_fini(LTTV_TRACESET_CONTEXT(tab
->traceset_info
->
3908 g_object_unref(tab
->traceset_info
->traceset_context
);
3910 if(tab
->traceset_info
->traceset
!= NULL
) {
3911 nb
= lttv_traceset_number(tab
->traceset_info
->traceset
);
3912 for(i
= 0 ; i
< nb
; i
++) {
3913 trace
= lttv_traceset_get(tab
->traceset_info
->traceset
, i
);
3914 ref_count
= lttv_trace_get_ref_number(trace
);
3916 ltt_trace_close(lttv_trace(trace
));
3920 lttv_traceset_destroy(tab
->traceset_info
->traceset
);
3921 /* Remove the idle events requests processing function of the tab */
3922 g_idle_remove_by_data(tab
);
3924 g_slist_free(tab
->events_requests
);
3925 g_free(tab
->traceset_info
);
3927 g_object_unref(ptab
);
3928 #endif /* BABEL_CLEANUP */
3932 /* Create a tab and insert it into the current main window
3935 void init_tab(Tab
*tab
, MainWindow
* mw
, Tab
*copy_tab
,
3936 GtkNotebook
* notebook
, char * label
)
3941 //LttvFilter *filter = NULL;
3943 //create a new tab data structure
3944 //tab = g_new(Tab,1);
3946 //construct and initialize the traceset_info
3947 tab
->traceset_info
= g_new(TracesetInfo
,1);
3950 tab
->traceset_info
->traceset
=
3951 lttv_traceset_copy(copy_tab
->traceset_info
->traceset
);
3953 /* Copy the previous tab's filter */
3954 /* We can clone the filter, as we copy the trace set also */
3955 /* The filter must always be in sync with the trace set */
3957 #ifdef BABEL_CLEANUP
3958 tab
->filter
= lttv_filter_clone(copy_tab
->filter
);
3959 #endif /* BABEL_CLEANUP */
3961 tab
->traceset_info
->traceset
= lttv_traceset_new();
3966 lttv_attribute_write_xml(
3967 lttv_traceset_attribute(tab
->traceset_info
->traceset
),
3973 tab
->time_manager_lock
= FALSE
;
3974 tab
->current_time_manager_lock
= FALSE
;
3975 #ifdef BABEL_CLEANUP
3976 //FIXME copy not implemented in lower level
3977 tab
->traceset_info
->traceset_context
=
3978 g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
3979 //add state update hooks
3980 lttv_state_add_event_hooks(
3981 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
3982 #endif //BABEL_CLEANUP
3983 //determine the current_time and time_window of the tab
3985 if(copy_tab
!= NULL
){
3986 tab
->time_window
= copy_tab
->time_window
;
3987 tab
->current_time
= copy_tab
->current_time
;
3989 tab
->time_window
.start_time
=
3990 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
3991 time_span
.start_time
;
3992 if(DEFAULT_TIME_WIDTH_S
<
3993 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
3994 time_span
.end_time
.tv_sec
)
3995 tmp_time
.tv_sec
= DEFAULT_TIME_WIDTH_S
;
3998 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
3999 time_span
.end_time
.tv_sec
;
4000 tmp_time
.tv_nsec
= 0;
4001 tab
->time_window
.time_width
= tmp_time
;
4002 tab
->current_time
.tv_sec
=
4003 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
4004 time_span
.start_time
.tv_sec
;
4005 tab
->current_time
.tv_nsec
=
4006 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
4007 time_span
.start_time
.tv_nsec
;
4010 tab
->attributes
= LTTV_IATTRIBUTE(g_object_new(LTTV_ATTRIBUTE_TYPE
, NULL
));
4011 tab
->interrupted_state
= g_object_new(LTTV_ATTRIBUTE_TYPE
, NULL
);
4013 tab
->vbox
= gtk_vbox_new(FALSE
, 2);
4014 tab
->top_widget
= tab
->vbox
;
4015 //g_object_set_data_full(G_OBJECT(tab->top_widget), "filter",
4016 // filter, (GDestroyNotify)lttv_filter_destroy);
4018 // g_signal_connect (G_OBJECT(tab->top_widget),
4020 // G_CALLBACK (on_top_notify),
4023 tab
->viewer_container
= gtk_vbox_new(TRUE
, 2);
4024 tab
->scrollbar
= gtk_hscrollbar_new(NULL
);
4025 //tab->multivpaned = gtk_multi_vpaned_new();
4027 gtk_box_pack_start(GTK_BOX(tab
->vbox
),
4028 tab
->viewer_container
,
4030 TRUE
, /* Give the extra space to the child */
4031 0); /* No padding */
4034 // tab->time_window = copy_tab->time_window;
4035 // tab->current_time = copy_tab->current_time;
4038 /* Create the timebar */
4040 tab
->MTimebar
= timebar_new();
4042 gtk_box_pack_end(GTK_BOX(tab
->vbox
),
4044 FALSE
, /* Do not expand */
4045 FALSE
, /* Fill has no effect here (expand false) */
4046 0); /* No padding */
4048 gtk_box_pack_end(GTK_BOX(tab
->vbox
),
4050 FALSE
, /* Do not expand */
4051 FALSE
, /* Fill has no effect here (expand false) */
4052 0); /* No padding */
4054 g_object_set_data(G_OBJECT(tab
->viewer_container
), "focused_viewer", NULL
);
4060 // Display a label with a X
4061 GtkWidget *w_hbox = gtk_hbox_new(FALSE, 4);
4062 GtkWidget *w_label = gtk_label_new (label);
4063 GtkWidget *pixmap = create_pixmap(GTK_WIDGET(notebook), "close.png");
4064 GtkWidget *w_button = gtk_button_new ();
4065 gtk_container_add(GTK_CONTAINER(w_button), pixmap);
4066 //GtkWidget *w_button = gtk_button_new_with_label("x");
4068 gtk_button_set_relief(GTK_BUTTON(w_button), GTK_RELIEF_NONE);
4070 gtk_box_pack_start(GTK_BOX(w_hbox), w_label, TRUE, TRUE, 0);
4071 gtk_box_pack_end(GTK_BOX(w_hbox), w_button, FALSE,
4074 g_signal_connect_swapped (w_button, "clicked",
4075 G_CALLBACK (on_close_tab_X_clicked),
4078 gtk_widget_set_state(w_button, GTK_STATE_ACTIVE);
4080 gtk_widget_show (w_label);
4081 gtk_widget_show (pixmap);
4082 gtk_widget_show (w_button);
4083 gtk_widget_show (w_hbox);
4085 tab->label = w_hbox;
4089 tab
->label
= gtk_label_new (label
);
4091 gtk_widget_show(tab
->label
);
4092 gtk_widget_show(tab
->scrollbar
);
4093 gtk_widget_show(tab
->MTimebar
);
4094 gtk_widget_show(tab
->viewer_container
);
4095 gtk_widget_show(tab
->vbox
);
4097 //gtk_widget_show(tab->multivpaned);
4100 /* Start with empty events requests list */
4101 tab
->events_requests
= NULL
;
4102 tab
->events_request_pending
= FALSE
;
4103 tab
->stop_foreground
= FALSE
;
4107 g_signal_connect(G_OBJECT(tab
->scrollbar
), "value-changed",
4108 G_CALLBACK(scroll_value_changed_cb
), tab
);
4111 /* Timebar signal handler */
4112 g_signal_connect(G_OBJECT(tab
->MTimebar
), "start-time-changed",
4113 G_CALLBACK(on_timebar_starttime_changed
), tab
);
4114 g_signal_connect(G_OBJECT(tab
->MTimebar
), "end-time-changed",
4115 G_CALLBACK(on_timebar_endtime_changed
), tab
);
4116 g_signal_connect(G_OBJECT(tab
->MTimebar
), "current-time-changed",
4117 G_CALLBACK(on_timebar_currenttime_changed
), tab
);
4119 //g_signal_connect(G_OBJECT(tab->scrollbar), "changed",
4120 // G_CALLBACK(scroll_value_changed_cb), tab);
4123 //insert tab into notebook
4124 gtk_notebook_append_page(notebook
,
4127 list
= gtk_container_get_children(GTK_CONTAINER(notebook
));
4128 gtk_notebook_set_current_page(notebook
,g_list_length(list
)-1);
4129 // always show : not if(g_list_length(list)>1)
4130 gtk_notebook_set_show_tabs(notebook
, TRUE
);
4133 lttvwindow_report_time_window(tab
, copy_tab
->time_window
);
4134 lttvwindow_report_current_time(tab
, copy_tab
->current_time
);
4136 TimeWindow time_window
;
4138 time_window
.start_time
= ltt_time_zero
;
4139 time_window
.end_time
= ltt_time_add(time_window
.start_time
,
4140 lttvwindow_default_time_width
);
4141 time_window
.time_width
= lttvwindow_default_time_width
;
4142 time_window
.time_width_double
= ltt_time_to_double(time_window
.time_width
);
4144 lttvwindow_report_time_window(tab
, time_window
);
4145 lttvwindow_report_current_time(tab
, ltt_time_zero
);
4148 LttvTraceset
*traceset
= tab
->traceset_info
->traceset
;
4149 SetTraceset(tab
, traceset
);
4153 * execute_events_requests
4155 * Idle function that executes the pending requests for a tab.
4157 * @return return value : TRUE : keep the idle function, FALSE : remove it.
4159 gboolean
execute_events_requests(Tab
*tab
)
4161 return ( lttvwindow_process_pending_requests(tab
) );
4165 __EXPORT
void create_main_window_with_trace_list(GSList
*traces
)
4168 GSList
*iter
= NULL
;
4171 MainWindow
*mw
= construct_main_window(NULL
);
4172 GtkWidget
*widget
= mw
->mwindow
;
4174 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
4175 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
4176 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
4177 LttvPluginTab
*ptab
;
4181 ptab
= create_new_tab(widget
, NULL
);
4184 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
4188 LttvTraceset
* traceset
= lttv_traceset_new();
4189 for(iter
=traces
; iter
!=NULL
; iter
=g_slist_next(iter
)) {
4190 gchar
*path
= (gchar
*)iter
->data
;
4192 gchar abs_path
[PATH_MAX
];
4195 get_absolute_pathname(path
, abs_path
);
4197 if(lttv_traceset_add_path(traceset
,abs_path
) != 0 ){ /*failure*/
4199 g_warning("cannot open trace %s", abs_path
);
4201 GtkWidget
*dialogue
=
4202 gtk_message_dialog_new(
4203 GTK_WINDOW(gtk_widget_get_toplevel(widget
)),
4204 GTK_DIALOG_MODAL
|GTK_DIALOG_DESTROY_WITH_PARENT
,
4207 "Cannot open trace : maybe you should enter in the directory "
4209 gtk_dialog_run(GTK_DIALOG(dialogue
));
4210 gtk_widget_destroy(dialogue
);
4213 SetTraceset(tab
, traceset
);