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
)
229 TimeInterval time_span
;
230 TimeWindow new_time_window
;
231 LttTime new_current_time
;
234 // Perform time synchronization on the traces
235 if (syncTraceset(tsc
))
237 /* There is some time-dependant information that was calculated during
238 * context initialization. Destroy the old contexts and initialize new
240 * Modified from lttvwindow_add_trace()
242 // Keep a reference to the traces so they are not freed
243 for(i
= 0; i
< lttv_traceset_number(traceset
); i
++)
245 LttvTrace
*trace
= lttv_traceset_get(traceset
, i
);
246 lttv_trace_ref(trace
);
249 // Remove state update hooks
250 lttv_state_remove_event_hooks(
251 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
253 lttv_context_fini(LTTV_TRACESET_CONTEXT(
254 tab
->traceset_info
->traceset_context
));
255 g_object_unref(tab
->traceset_info
->traceset_context
);
257 for(i
= 0; i
< lttv_traceset_number(traceset
); i
++)
259 LttvTrace
*trace
= lttv_traceset_get(traceset
, i
);
260 lttvwindowtraces_remove_trace(trace
);
261 lttvwindowtraces_add_trace(trace
);
264 // Create new context
265 tab
->traceset_info
->traceset_context
=
266 g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
267 lttv_context_init(LTTV_TRACESET_CONTEXT(tab
->traceset_info
->
268 traceset_context
), traceset
);
270 // Add state update hooks
271 lttv_state_add_event_hooks(
272 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
274 // Remove local reference to the traces
275 for(i
=0; i
<lttv_traceset_number(traceset
); i
++)
277 LttvTrace
*trace
= lttv_traceset_get(traceset
, i
);
278 lttv_trace_unref(trace
);
281 tsc
= LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
283 #endif /*BABEL_CLEANUP*/
285 time_span
= lttv_traceset_get_time_span(traceset
);
287 tab
->traceset_info
->traceset
= traceset
;
289 new_time_window
= tab
->time_window
;
290 new_current_time
= tab
->current_time
;
292 /* Set the tab's time window and current time if
294 if(ltt_time_compare(tab
->time_window
.start_time
, time_span
.start_time
) < 0
295 || ltt_time_compare(tab
->time_window
.end_time
,
296 time_span
.end_time
) > 0) {
297 new_time_window
.start_time
= time_span
.start_time
;
299 new_current_time
= time_span
.start_time
;
303 if(ltt_time_compare(lttvwindow_default_time_width
,
304 ltt_time_sub(time_span
.end_time
, time_span
.start_time
)) < 0
306 ltt_time_compare(time_span
.end_time
, time_span
.start_time
) == 0)
307 tmp_time
= lttvwindow_default_time_width
;
309 tmp_time
= time_span
.end_time
;
311 new_time_window
.time_width
= tmp_time
;
312 new_time_window
.time_width_double
= ltt_time_to_double(tmp_time
);
313 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
314 new_time_window
.time_width
) ;
316 lttv_state_add_event_hooks(traceset
);
318 /* Finally, call the update hooks of the viewers */
319 gint retval
= update_traceset(tab
, traceset
);
321 time_change_manager(tab
, new_time_window
);
322 current_time_change_manager(tab
, new_current_time
);
329 * Function to set/update filter for the viewers
330 * @param tab viewer's tab
331 * @param filter filter of the main window.
334 * 0 : filters updated
335 * 1 : no filter hooks to update; not an error.
338 int SetFilter(Tab
* tab
, gpointer filter
)
341 LttvAttributeValue value
;
343 g_assert(lttv_iattribute_find_by_path(tab
->attributes
,
344 "hooks/updatefilter", LTTV_POINTER
, &value
));
346 tmp
= (LttvHooks
*)*(value
.v_pointer
);
348 if(tmp
== NULL
) return 1;
349 lttv_hooks_call(tmp
,filter
);
357 * Function to redraw each viewer belonging to the current tab
358 * @param tab viewer's tab
361 int update_traceset(Tab
*tab
, LttvTraceset
*traceset
)
363 LttvAttributeValue value
;
367 retval
= lttv_iattribute_find_by_path(tab
->attributes
,
368 "hooks/updatetraceset",
372 tmp
= (LttvHooks
*)*(value
.v_pointer
);
376 lttv_hooks_call(tmp
, traceset
);
382 Call hooks register to get update on traceset time span changes
384 int notify_time_span_changed(Tab
*tab
)
386 LttvAttributeValue value
;
390 retval
= lttv_iattribute_find_by_path(tab
->attributes
,
391 "hooks/updatetimespan",
395 tmp
= (LttvHooks
*)*(value
.v_pointer
);
399 lttv_hooks_call(tmp
, NULL
);
404 /* get_label function is used to get user input, it displays an input
405 * box, which allows user to input a string
408 void get_label_string (GtkWidget
* text
, gchar
* label
)
410 GtkEntry
* entry
= (GtkEntry
*)text
;
411 if(strlen(gtk_entry_get_text(entry
))!=0)
412 strcpy(label
,gtk_entry_get_text(entry
));
415 gboolean
get_label(MainWindow
* mw
, gchar
* str
, gchar
* dialogue_title
, gchar
* label_str
)
417 GtkWidget
* dialogue
;
422 dialogue
= gtk_dialog_new_with_buttons(dialogue_title
,NULL
,
424 GTK_STOCK_OK
,GTK_RESPONSE_ACCEPT
,
425 GTK_STOCK_CANCEL
,GTK_RESPONSE_REJECT
,
428 label
= gtk_label_new(label_str
);
429 gtk_widget_show(label
);
431 text
= gtk_entry_new();
432 gtk_widget_show(text
);
434 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialogue
)->vbox
), label
,TRUE
, TRUE
,0);
435 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialogue
)->vbox
), text
,FALSE
, FALSE
,0);
437 id
= gtk_dialog_run(GTK_DIALOG(dialogue
));
439 case GTK_RESPONSE_ACCEPT
:
440 get_label_string(text
,str
);
441 gtk_widget_destroy(dialogue
);
443 case GTK_RESPONSE_REJECT
:
445 gtk_widget_destroy(dialogue
);
452 /* get_window_data_struct function is actually a lookup function,
453 * given a widget which is in the tree of the main window, it will
454 * return the MainWindow data structure associated with main window
457 MainWindow
* get_window_data_struct(GtkWidget
* widget
)
460 MainWindow
* mw_data
;
462 mw
= lookup_widget(widget
, "MWindow");
464 g_info("Main window does not exist\n");
468 mw_data
= (MainWindow
*) g_object_get_data(G_OBJECT(mw
),"main_window_data");
470 g_warning("Main window data does not exist\n");
477 /* create_new_window function, just constructs a new main window
480 void create_new_window(GtkWidget
* widget
, gpointer user_data
, gboolean clone
)
482 MainWindow
* parent
= get_window_data_struct(widget
);
485 g_info("Clone : use the same traceset\n");
486 construct_main_window(parent
);
488 g_info("Empty : traceset is set to NULL\n");
489 construct_main_window(NULL
);
493 /* Get the currently focused viewer.
494 * If no viewer is focused, use the first one.
496 * If no viewer available, return NULL.
498 GtkWidget
*viewer_container_focus(GtkWidget
*container
)
502 widget
= (GtkWidget
*)g_object_get_data(G_OBJECT(container
),
506 g_debug("no widget focused");
507 GList
*children
= gtk_container_get_children(GTK_CONTAINER(container
));
510 widget
= GTK_WIDGET(children
->data
);
511 g_object_set_data(G_OBJECT(container
),
521 gint
viewer_container_position(GtkWidget
*container
, GtkWidget
*child
)
524 if(child
== NULL
) return -1;
528 memset(&value
, 0, sizeof(GValue
));
529 g_value_init(&value
, G_TYPE_INT
);
530 gtk_container_child_get_property(GTK_CONTAINER(container
),
534 pos
= g_value_get_int(&value
);
540 /* move_*_viewer functions move the selected view up/down in
544 void move_down_viewer(GtkWidget
* widget
, gpointer user_data
)
546 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
548 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
549 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
556 ptab
= g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
560 //gtk_multivpaned_widget_move_up(GTK_MULTIVPANED(tab->multivpaned));
562 /* change the position in the vbox */
563 GtkWidget
*focus_widget
;
565 focus_widget
= viewer_container_focus(tab
->viewer_container
);
566 position
= viewer_container_position(tab
->viewer_container
, focus_widget
);
569 /* can move up one position */
570 gtk_box_reorder_child(GTK_BOX(tab
->viewer_container
),
577 void move_up_viewer(GtkWidget
* widget
, gpointer user_data
)
579 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
581 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
582 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
589 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
593 //gtk_multivpaned_widget_move_down(GTK_MULTIVPANED(tab->multivpaned));
594 /* change the position in the vbox */
595 GtkWidget
*focus_widget
;
597 focus_widget
= viewer_container_focus(tab
->viewer_container
);
598 position
= viewer_container_position(tab
->viewer_container
, focus_widget
);
602 g_list_length(gtk_container_get_children(
603 GTK_CONTAINER(tab
->viewer_container
)))-1
605 /* can move down one position */
606 gtk_box_reorder_child(GTK_BOX(tab
->viewer_container
),
614 /* delete_viewer deletes the selected viewer in the current tab
617 void delete_viewer(GtkWidget
* widget
, gpointer user_data
)
619 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
621 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
622 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
629 ptab
= g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
633 //gtk_multivpaned_widget_delete(GTK_MULTIVPANED(tab->multivpaned));
635 GtkWidget
*focus_widget
= viewer_container_focus(tab
->viewer_container
);
637 if(focus_widget
!= NULL
)
638 gtk_widget_destroy(focus_widget
);
640 g_object_set_data(G_OBJECT(tab
->viewer_container
), "focused_viewer", NULL
);
643 #if UNFINISHED_FEATURE
644 /* TODO ybrosseau 2012-03-15: Function is half implemented. Should be removed */
645 /* open_traceset will open a traceset saved in a file
646 * Right now, it is not finished yet, (not working)
650 void open_traceset(GtkWidget
* widget
, gpointer user_data
)
654 LttvTraceset
* traceset
;
655 MainWindow
* mw_data
= get_window_data_struct(widget
);
656 GtkFileSelection
* file_selector
=
657 (GtkFileSelection
*)gtk_file_selection_new("Select a traceset");
659 gtk_file_selection_hide_fileop_buttons(file_selector
);
661 gtk_window_set_transient_for(GTK_WINDOW(file_selector
),
662 GTK_WINDOW(mw_data
->mwindow
));
664 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
666 case GTK_RESPONSE_ACCEPT
:
667 case GTK_RESPONSE_OK
:
668 dir
= gtk_file_selection_get_selections (file_selector
);
669 traceset
= lttv_traceset_load(dir
[0]);
670 g_info("Open a trace set %s\n", dir
[0]);
673 case GTK_RESPONSE_REJECT
:
674 case GTK_RESPONSE_CANCEL
:
676 gtk_widget_destroy((GtkWidget
*)file_selector
);
682 /* lttvwindow_process_pending_requests
684 * Process requests for parts of the trace from viewers.
686 * These requests are made by lttvwindow_events_request().
688 * This internal function gets called by g_idle, taking care of the pending
689 * requests. It is responsible for concatenation of time intervals and position
690 * requests. It does it with the following algorithm organizing process traceset
691 * calls. Here is the detailed description of the way it works :
693 * - Events Requests Servicing Algorithm
695 * Data structures necessary :
697 * List of requests added to context : list_in
698 * List of requests not added to context : list_out
703 * list_out : many events requests
705 * FIXME : insert rest of algorithm here
709 #define list_out tab->events_requests
711 gboolean
lttvwindow_process_pending_requests(Tab
*tab
)
716 GSList
*list_in
= NULL
;
720 LttvTracesetPosition
*end_position
;
722 if(lttvwindow_preempt_count
> 0) return TRUE
;
725 g_critical("Foreground processing : tab does not exist. Processing removed.");
729 /* There is no events requests pending : we should never have been called! */
730 g_assert(g_slist_length(list_out
) != 0);
732 ts
= tab
->traceset_info
->traceset
;
734 //set the cursor to be X shape, indicating that the computer is busy in doing its job
736 new = gdk_cursor_new(GDK_X_CURSOR
);
737 widget
= lookup_widget(tab
->mw
->mwindow
, "MToolbar1");
738 win
= gtk_widget_get_parent_window(widget
);
739 gdk_window_set_cursor(win
, new);
740 gdk_cursor_unref(new);
741 gdk_window_stick(win
);
742 gdk_window_unstick(win
);
745 g_debug("SIZE events req len : %d", g_slist_length(list_out
));
747 /* Preliminary check for no trace in traceset */
748 /* Unregister the routine if empty, empty list_out too */
749 if(lttv_traceset_number(ts
) == 0) {
751 /* - For each req in list_out */
752 GSList
*iter
= list_out
;
754 while(iter
!= NULL
) {
756 gboolean remove
= FALSE
;
757 gboolean free_data
= FALSE
;
758 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
760 /* - Call end request for req */
761 if(events_request
->servicing
== TRUE
)
762 lttv_hooks_call(events_request
->after_request
, (gpointer
)ts
);
764 /* - remove req from list_out */
765 /* Destroy the request */
768 //TODO ybrosseau: This if is always true
772 GSList
*remove_iter
= iter
;
774 iter
= g_slist_next(iter
);
775 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
776 list_out
= g_slist_remove_link(list_out
, remove_iter
);
777 } else { // not remove
778 iter
= g_slist_next(iter
);
783 /* 0.1 Lock Traces */
788 iter_trace
<lttv_traceset_number(ts
);
790 LttvTrace
*trace_v
= lttv_traceset_get(ts
, iter_trace
);
792 if(lttvwindowtraces_lock(trace_v
) != 0) {
793 g_critical("Foreground processing : Unable to get trace lock");
794 return TRUE
; /* Cannot get lock, try later */
799 /* 0.2 Seek tracefiles positions to context position */
801 //g_assert(lttv_process_traceset_seek_position(tsc, sync_position) == 0);
802 lttv_process_traceset_synchronize_tracefiles(tsc
);
805 /* Events processing algorithm implementation */
806 /* Warning : the gtk_events_pending takes a LOT of cpu time. So what we do
807 * instead is to leave the control to GTK and take it back.
809 /* A. Servicing loop */
810 //while( (g_slist_length(list_in) != 0 || g_slist_length(list_out) != 0)) {
811 if((g_slist_length(list_in
) != 0 || g_slist_length(list_out
) != 0)) {
813 /* 1. If list_in is empty (need a seek) */
814 if( g_slist_length(list_in
) == 0 ) {
816 /* list in is empty, need a seek */
818 /* 1.1 Add requests to list_in */
819 GSList
*ltime
= NULL
;
823 /* 1.1.1 Find all time requests with the lowest start time in list_out
826 if(g_slist_length(list_out
) > 0)
827 ltime
= g_slist_append(ltime
, g_slist_nth_data(list_out
, 0));
828 for(iter
=g_slist_nth(list_out
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
829 /* Find all time requests with the lowest start time in list_out */
830 EventsRequest
*event_request_ltime
= (EventsRequest
*)g_slist_nth_data(ltime
, 0);
831 EventsRequest
*event_request_list_out
= (EventsRequest
*)iter
->data
;
834 comp
= ltt_time_compare(event_request_ltime
->start_time
,
835 event_request_list_out
->start_time
);
837 ltime
= g_slist_append(ltime
, event_request_list_out
);
839 /* Remove all elements from ltime, and add current */
841 ltime
= g_slist_delete_link(ltime
, g_slist_nth(ltime
, 0));
842 ltime
= g_slist_append(ltime
, event_request_list_out
);
846 /* 1.1.2 Find all position requests with the lowest position in list_out
849 if(g_slist_length(list_out
) > 0)
850 lpos
= g_slist_append(lpos
, g_slist_nth_data(list_out
, 0));
851 for(iter
=g_slist_nth(list_out
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
852 /* Find all position requests with the lowest position in list_out */
853 EventsRequest
*event_request_lpos
= (EventsRequest
*)g_slist_nth_data(lpos
, 0);
854 EventsRequest
*event_request_list_out
= (EventsRequest
*)iter
->data
;
857 if(event_request_lpos
->start_position
!= NULL
858 && event_request_list_out
->start_position
!= NULL
)
860 //TODO ybrosseau: this compare is in fact an equal, so the behavior might not be right.
861 comp
= lttv_traceset_position_time_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_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
);
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 //TODO ybrosseau: if commented out, since it was only affecting the g_debug
935 //if(tfc == NULL || ltt_time_compare(events_request->start_time,
936 // tfc->timestamp) != 0)
937 /* - Seek to that time */
938 g_debug("SEEK TIME : %lu, %lu", events_request
->start_time
.tv_sec
,
939 events_request
->start_time
.tv_nsec
);
940 //lttv_process_traceset_seek_time(tsc, events_request->start_time);
941 lttv_process_traceset_seek_time(ts
,
942 events_request
->start_time
);
944 /* Process the traceset with only state hooks */
948 lttv_process_traceset_middle(ts
,
949 events_request
->start_time
,
952 g_assert(seek_count
< LTTV_STATE_SAVE_INTERVAL
);
958 //LttvTracefileContext *tfc =
959 // lttv_traceset_context_get_current_tfc(tsc);
960 /* Else, the first request in list_in is a position request */
961 /* If first req in list_in pos != current pos */
962 g_assert(events_request
->start_position
!= NULL
);
963 g_debug("SEEK POS time : %lu, %lu",
964 lttv_traceset_position_get_time(
965 events_request
->start_position
).tv_sec
,
966 lttv_traceset_position_get_time(
967 events_request
->start_position
).tv_nsec
);
969 /*if(tfc) {*/ if(0) {
970 /* g_debug("SEEK POS context time : %lu, %lu",
971 tfc->timestamp.tv_sec,
972 tfc->timestamp.tv_nsec); */
974 g_debug("SEEK POS context time : %lu, %lu",
975 ltt_time_infinite
.tv_sec
,
976 ltt_time_infinite
.tv_nsec
);
978 g_assert(events_request
->start_position
!= NULL
);
979 //TODO ybrosseau: for now, always seek
980 if(/*lttv_traceset_context_ctx_pos_compare(tsc,
981 events_request->start_position) != 0*/1) {
982 /* 1.2.2.1 Seek to that position */
983 g_debug("SEEK POSITION");
984 //lttv_process_traceset_seek_position(tsc, events_request->start_position);
985 //pos_time = lttv_traceset_position_get_time(
986 // events_request->start_position);
988 //lttv_state_traceset_seek_time(ts,
990 lttv_traceset_seek_to_position( events_request
->start_position
);
992 /* Process the traceset with only state hooks */
996 lttv_process_traceset_middle(ts
,
999 events_request
->start_position
);
1001 //g_assert(lttv_traceset_context_ctx_pos_compare(tsc,
1002 // events_request->start_position) == 0);
1009 /* 1.3 Add hooks and call before request for all list_in members */
1011 GSList
*iter
= NULL
;
1013 for(iter
=list_in
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
1014 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1015 /* 1.3.1 If !servicing */
1016 if(events_request
->servicing
== FALSE
) {
1017 /* - begin request hooks called
1018 * - servicing = TRUE
1020 lttv_hooks_call(events_request
->before_request
, (gpointer
)ts
);
1021 events_request
->servicing
= TRUE
;
1023 /* 1.3.2 call before chunk
1024 * 1.3.3 events hooks added
1026 //TODO ybrosseau 2012-07-10: || TRUE added since we only support
1027 // traceset wide requests
1028 if(events_request
->trace
== -1 || TRUE
)
1029 lttv_process_traceset_begin(ts
,
1030 events_request
->before_chunk_traceset
,
1031 events_request
->before_chunk_trace
,
1032 events_request
->event
1035 guint nb_trace
= lttv_traceset_number(ts
);
1036 g_assert((guint
)events_request
->trace
< nb_trace
&&
1037 events_request
->trace
> -1);
1038 LttvTrace
*trace
= lttv_traceset_get(ts
, events_request
->trace
);
1040 lttv_hooks_call(events_request
->before_chunk_traceset
, ts
);
1042 lttv_trace_add_hooks(trace
,
1043 events_request
->before_chunk_trace
,
1045 events_request
->event
1051 /* 2. Else, list_in is not empty, we continue a read */
1054 /* 2.0 For each req of list_in */
1055 GSList
*iter
= list_in
;
1057 while(iter
!= NULL
) {
1059 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1061 /* - Call before chunk
1062 * - events hooks added
1064 //TODO ybrosseau 2012-07-10: || TRUE added since we only support
1065 // traceset wide requests
1066 if(events_request
->trace
== -1 || TRUE
)
1067 lttv_process_traceset_begin(ts
,
1068 events_request
->before_chunk_traceset
,
1069 events_request
->before_chunk_trace
,
1070 events_request
->event
1073 guint nb_trace
= lttv_traceset_number(ts
);
1074 g_assert((guint
)events_request
->trace
< nb_trace
&&
1075 events_request
->trace
> -1);
1076 LttvTrace
*trace
= lttv_traceset_get(ts
, events_request
->trace
);
1078 lttv_hooks_call(events_request
->before_chunk_traceset
, ts
);
1080 lttv_trace_add_hooks(trace
,
1081 events_request
->before_chunk_trace
,
1083 events_request
->event
1087 iter
= g_slist_next(iter
);
1094 /* 2.1 For each req of list_out */
1095 GSList
*iter
= list_out
;
1097 while(iter
!= NULL
) {
1099 gboolean remove
= FALSE
;
1100 gboolean free_data
= FALSE
;
1101 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1103 /* if req.start time == current context time
1104 * or req.start position == current position*/
1105 /* if( ltt_time_compare(events_request->start_time,
1106 tfc->timestamp) == 0
1108 (events_request->start_position != NULL
1110 lttv_traceset_context_ctx_pos_compare(tsc,
1111 events_request->start_position) == 0)
1114 if(lttv_traceset_position_compare_current(ts
, events_request
->start_position
) == 0) {
1116 /* - Add to list_in, remove from list_out */
1117 list_in
= g_slist_append(list_in
, events_request
);
1121 /* - If !servicing */
1122 if(events_request
->servicing
== FALSE
) {
1123 /* - begin request hooks called
1124 * - servicing = TRUE
1126 lttv_hooks_call(events_request
->before_request
, (gpointer
)ts
);
1127 events_request
->servicing
= TRUE
;
1129 /* call before chunk
1130 * events hooks added
1132 //TODO ybrosseau 2012-07-10: || TRUE added since we only support
1133 // traceset wide requests
1134 if(events_request
->trace
== -1 || TRUE
)
1135 lttv_process_traceset_begin(ts
,
1136 events_request
->before_chunk_traceset
,
1137 events_request
->before_chunk_trace
,
1138 events_request
->event
1141 guint nb_trace
= lttv_traceset_number(ts
);
1142 g_assert((guint
)events_request
->trace
< nb_trace
&&
1143 events_request
->trace
> -1);
1144 LttvTrace
* trace
= lttv_traceset_get(ts
,events_request
->trace
);
1146 lttv_hooks_call(events_request
->before_chunk_traceset
, ts
);
1148 lttv_trace_add_hooks(trace
,
1149 events_request
->before_chunk_trace
,
1151 events_request
->event
);
1161 GSList
*remove_iter
= iter
;
1163 iter
= g_slist_next(iter
);
1164 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
1165 list_out
= g_slist_remove_link(list_out
, remove_iter
);
1166 } else { // not remove
1167 iter
= g_slist_next(iter
);
1173 /* 3. Find end criterions */
1178 /* 3.1.1 Find lowest end time in list_in */
1179 g_assert(g_slist_length(list_in
)>0);
1180 end_time
= ((EventsRequest
*)g_slist_nth_data(list_in
,0))->end_time
;
1182 for(iter
=g_slist_nth(list_in
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
1183 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1185 if(ltt_time_compare(events_request
->end_time
,
1187 end_time
= events_request
->end_time
;
1190 /* 3.1.2 Find lowest start time in list_out */
1191 for(iter
=list_out
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
1192 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1194 if(ltt_time_compare(events_request
->start_time
,
1196 end_time
= events_request
->start_time
;
1201 /* 3.2 Number of events */
1203 /* 3.2.1 Find lowest number of events in list_in */
1206 end_nb_events
= ((EventsRequest
*)g_slist_nth_data(list_in
,0))->num_events
;
1208 for(iter
=g_slist_nth(list_in
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
1209 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1211 if(events_request
->num_events
< end_nb_events
)
1212 end_nb_events
= events_request
->num_events
;
1215 /* 3.2.2 Use min(CHUNK_NUM_EVENTS, min num events in list_in) as
1218 end_nb_events
= MIN(CHUNK_NUM_EVENTS
, end_nb_events
);
1222 /* 3.3 End position */
1224 /* 3.3.1 Find lowest end position in list_in */
1227 end_position
=((EventsRequest
*)g_slist_nth_data(list_in
,0))->end_position
;
1229 for(iter
=g_slist_nth(list_in
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
1230 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1232 if(events_request
->end_position
!= NULL
&& end_position
!= NULL
&&
1233 lttv_traceset_position_time_compare(events_request
->end_position
,
1235 end_position
= events_request
->end_position
;
1240 /* 3.3.2 Find lowest start position in list_out */
1243 for(iter
=list_out
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
1244 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1246 if(events_request
->end_position
!= NULL
&& end_position
!= NULL
&&
1247 lttv_traceset_position_time_compare(events_request
->end_position
,
1249 end_position
= events_request
->end_position
;
1254 /* 4. Call process traceset middle */
1255 g_debug("Calling process traceset middle with %p, %lu sec %lu nsec, %u nb ev, %p end pos", ts
, end_time
.tv_sec
, end_time
.tv_nsec
, end_nb_events
, end_position
);
1256 count
= lttv_process_traceset_middle(ts
, end_time
, end_nb_events
, end_position
);
1258 #ifdef BABEL_CLEANUP
1259 tfc
= lttv_traceset_context_get_current_tfc(tsc
);
1261 g_debug("Context time after middle : %lu, %lu", tfc
->timestamp
.tv_sec
,
1262 tfc
->timestamp
.tv_nsec
);
1264 g_debug("End of trace reached after middle.");
1269 /* 5. After process traceset middle */
1271 LttTime curTime
= lttv_traceset_get_current_time(ts
);
1272 /* - if current context time > traceset.end time */
1273 if(ltt_time_compare(curTime
,
1274 lttv_traceset_get_time_span_real(ts
).end_time
) > 0) {
1275 /* - For each req in list_in */
1276 GSList
*iter
= list_in
;
1278 while(iter
!= NULL
) {
1280 gboolean remove
= FALSE
;
1281 gboolean free_data
= FALSE
;
1282 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1284 /* - Remove events hooks for req
1285 * - Call end chunk for req
1287 //TODO ybrosseau 2012-07-10: || TRUE added since we only support
1288 // traceset wide requests
1289 if(events_request
->trace
== -1 || TRUE
)
1290 lttv_process_traceset_end(ts
,
1291 events_request
->after_chunk_traceset
,
1292 events_request
->after_chunk_trace
,
1294 events_request
->event
);
1297 guint nb_trace
= lttv_traceset_number(ts
);
1298 g_assert(events_request
->trace
< nb_trace
&&
1299 events_request
->trace
> -1);
1300 LttvTrace
*trace
= lttv_traceset_get(ts
,events_request
->trace
);
1302 lttv_trace_remove_hooks(trace
,
1303 events_request
->after_chunk_trace
,
1305 events_request
->event
);
1307 lttv_hooks_call(events_request
->after_chunk_traceset
, ts
);
1312 /* - Call end request for req */
1313 lttv_hooks_call(events_request
->after_request
, (gpointer
)ts
);
1315 /* - remove req from list_in */
1316 /* Destroy the request */
1323 GSList
*remove_iter
= iter
;
1325 iter
= g_slist_next(iter
);
1326 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
1327 list_in
= g_slist_remove_link(list_in
, remove_iter
);
1328 } else { // not remove
1329 iter
= g_slist_next(iter
);
1334 /* 5.1 For each req in list_in */
1335 GSList
*iter
= list_in
;
1337 while(iter
!= NULL
) {
1339 gboolean remove
= FALSE
;
1340 gboolean free_data
= FALSE
;
1341 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1343 /* - Remove events hooks for req
1344 * - Call end chunk for req
1346 //TODO ybrosseau 2012-07-10: || TRUE added since we only support
1347 // traceset wide requests
1348 if(events_request
->trace
== -1 || TRUE
)
1349 lttv_process_traceset_end(ts
,
1350 events_request
->after_chunk_traceset
,
1351 events_request
->after_chunk_trace
,
1353 events_request
->event
);
1357 guint nb_trace
= lttv_traceset_number(ts
);
1358 g_assert(events_request
->trace
< nb_trace
&&
1359 events_request
->trace
> -1);
1360 LttvTrace
*trace
= lttv_traceset_get(ts
, events_request
->trace
);
1362 lttv_trace_remove_hooks(trace
,
1363 events_request
->after_chunk_trace
,
1365 events_request
->event
);
1368 lttv_hooks_call(events_request
->after_chunk_traceset
, ts
);
1371 /* - req.num -= count */
1372 g_assert(events_request
->num_events
>= count
);
1373 events_request
->num_events
-= count
;
1375 //g_assert(tfc != NULL);
1376 /* - if req.num == 0
1378 * current context time >= req.end time
1380 * req.end pos == current pos
1382 * req.stop_flag == TRUE
1384 if( events_request
->num_events
== 0
1386 events_request
->stop_flag
== TRUE
1388 ltt_time_compare(lttv_traceset_get_current_time(ts
),
1389 events_request
->end_time
) >= 0
1391 (events_request
->end_position
!= NULL
1393 lttv_traceset_position_compare_current(ts
,
1394 events_request
->end_position
) == 0)
1397 g_assert(events_request
->servicing
== TRUE
);
1398 /* - Call end request for req
1399 * - remove req from list_in */
1400 lttv_hooks_call(events_request
->after_request
, (gpointer
)ts
);
1401 /* - remove req from list_in */
1402 /* Destroy the request */
1410 GSList
*remove_iter
= iter
;
1412 iter
= g_slist_next(iter
);
1413 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
1414 list_in
= g_slist_remove_link(list_in
, remove_iter
);
1415 } else { // not remove
1416 iter
= g_slist_next(iter
);
1422 /* End of removed servicing loop : leave control to GTK instead. */
1423 // if(gtk_events_pending()) break;
1426 /* B. When interrupted between chunks */
1429 GSList
*iter
= list_in
;
1431 /* 1. for each request in list_in */
1432 while(iter
!= NULL
) {
1434 gboolean remove
= FALSE
;
1435 gboolean free_data
= FALSE
;
1436 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1438 /* 1.1. Use current postition as start position */
1439 if(events_request
->start_position
!= NULL
)
1440 lttv_traceset_destroy_position(events_request
->start_position
);
1441 events_request
->start_position
= lttv_traceset_create_current_position(ts
);
1444 /* 1.2. Remove start time */
1445 events_request
->start_time
= ltt_time_infinite
;
1447 /* 1.3. Move from list_in to list_out */
1450 list_out
= g_slist_append(list_out
, events_request
);
1455 GSList
*remove_iter
= iter
;
1457 iter
= g_slist_next(iter
);
1458 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
1459 list_in
= g_slist_remove_link(list_in
, remove_iter
);
1460 } else { // not remove
1461 iter
= g_slist_next(iter
);
1467 /* C Unlock Traces */
1469 #ifdef BABEL_CLEANUP
1470 lttv_process_traceset_get_sync_data(tsc
);
1472 //lttv_traceset_context_position_save(tsc, sync_position);
1477 iter_trace
<lttv_traceset_number(ts
);
1479 LttvTrace
*trace_v
= lttv_traceset_get(ts
, iter_trace
);
1481 lttvwindowtraces_unlock(trace_v
);
1485 //set the cursor back to normal
1486 gdk_window_set_cursor(win
, NULL
);
1489 g_assert(g_slist_length(list_in
) == 0);
1491 if( g_slist_length(list_out
) == 0 ) {
1492 /* Put tab's request pending flag back to normal */
1493 tab
->events_request_pending
= FALSE
;
1494 g_debug("remove the idle fct");
1495 return FALSE
; /* Remove the idle function */
1497 g_debug("leave the idle fct");
1498 return TRUE
; /* Leave the idle function */
1500 /* We do not use simili-round-robin, it may require to read 1 meg buffers
1501 * again and again if many tracesets use the same tracefiles. */
1502 /* Hack for round-robin idle functions */
1503 /* It will put the idle function at the end of the pool */
1504 /*g_idle_add_full((G_PRIORITY_HIGH_IDLE + 21),
1505 (GSourceFunc)execute_events_requests,
1516 Manage the periodic update of a live trace
1519 live_trace_update_handler(Tab
*tab
)
1521 #ifdef BABEL_CLEANUP
1522 unsigned int updated_count
;
1523 LttvTracesetContext
*tsc
= LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
1524 TimeInterval initial_time_span
= tsc
->time_span
;
1525 TimeInterval updated_time_span
;
1527 updated_count
= lttv_process_traceset_update(tsc
);
1529 /* TODO ybrosseau 2011-01-12: Add trace resynchronization */
1531 /* Get the changed period bounds */
1532 updated_time_span
= tsc
->time_span
;
1534 if(ltt_time_compare(updated_time_span
.start_time
,
1535 initial_time_span
.start_time
) != 0) {
1536 /* The initial time should not change on a live update */
1540 /* Notify viewers (only on updates) */
1541 if(ltt_time_compare(updated_time_span
.end_time
,
1542 initial_time_span
.end_time
) != 0) {
1544 notify_time_span_changed(tab
);
1545 /* TODO ybrosseau 2011-01-12: Change the timebar to register
1546 to the time_span hook */
1547 timebar_set_minmax_time(TIMEBAR(tab
->MTimebar
),
1548 &updated_time_span
.start_time
,
1549 &updated_time_span
.end_time
);
1551 /* To update the min max */
1552 time_change_manager(tab
, tab
->time_window
);
1555 /* Timer will be recalled as long as there is files to update */
1556 return (updated_count
> 0);
1557 #endif /* BABEL_CLEANUP */
1560 static void lttvwindow_add_trace(Tab
*tab
, LttvTrace
*trace_v
)
1562 #ifdef BABEL_CLEANUP
1563 LttvTraceset
*traceset
= tab
->traceset_info
->traceset
;
1565 guint num_traces
= lttv_traceset_number(traceset
);
1567 //Verify if trace is already present.
1568 for(i
=0; i
<num_traces
; i
++)
1570 LttvTrace
* trace
= lttv_traceset_get(traceset
, i
);
1571 if(trace
== trace_v
)
1575 //Keep a reference to the traces so they are not freed.
1576 for(i
=0; i
<lttv_traceset_number(traceset
); i
++)
1578 LttvTrace
* trace
= lttv_traceset_get(traceset
, i
);
1579 lttv_trace_ref(trace
);
1582 //remove state update hooks
1583 lttv_state_remove_event_hooks(
1584 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1586 lttv_context_fini(LTTV_TRACESET_CONTEXT(
1587 tab
->traceset_info
->traceset_context
));
1588 g_object_unref(tab
->traceset_info
->traceset_context
);
1590 lttv_traceset_add(traceset
, trace_v
);
1591 lttv_trace_ref(trace_v
); /* local ref */
1593 /* Create new context */
1594 tab
->traceset_info
->traceset_context
=
1595 g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
1597 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->
1602 //add state update hooks
1603 lttv_state_add_event_hooks(
1604 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1605 //Remove local reference to the traces.
1606 for(i
=0; i
<lttv_traceset_number(traceset
); i
++)
1608 LttvTrace
* trace
= lttv_traceset_get(traceset
, i
);
1609 lttv_trace_unref(trace
);
1613 //add_trace_into_traceset_selector(GTK_MULTIVPANED(tab->multivpaned), lttv_trace(trace_v));
1616 if (lttv_trace(trace_v
)->is_live
) {
1617 /* Add timer for live update */
1618 /* TODO ybrosseau 2011-01-12: Parametrize the hardcoded 1 seconds */
1619 g_timeout_add_seconds (1,
1620 (GSourceFunc
) live_trace_update_handler
,
1623 #endif /* BABEL_CLEANUP */
1626 /* add_trace adds a trace into the current traceset. It first displays a
1627 * directory selection dialogue to let user choose a trace, then recreates
1628 * tracset_context, and redraws all the viewer of the current tab
1631 void add_trace(GtkWidget
* widget
, gpointer user_data
)
1634 LttvTraceset
* traceset
= NULL
;
1636 char abs_path
[PATH_MAX
];
1638 MainWindow
* mw_data
= get_window_data_struct(widget
);
1639 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
1641 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
1642 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
1643 LttvPluginTab
*ptab
;
1647 ptab
= create_new_tab(widget
, NULL
);
1650 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
1653 //TODO fdeslauriers 2012-07-06: Remove this popup when we support multiple traces
1654 traceset
= lttvwindow_get_traceset(tab
);
1655 if(traceset
!= NULL
&& lttv_traceset_number(traceset
) > 0){
1656 GtkWidget
*dialogue
=
1657 gtk_message_dialog_new(
1658 GTK_WINDOW(gtk_widget_get_toplevel(widget
)),
1659 GTK_DIALOG_MODAL
|GTK_DIALOG_DESTROY_WITH_PARENT
,
1662 "Loading multiple traces is not supported at the moment.");
1663 gtk_dialog_run(GTK_DIALOG(dialogue
));
1664 gtk_widget_destroy(dialogue
);
1668 /* Create a new traceset*/
1669 traceset
= lttv_traceset_new();
1670 /* File open dialog management */
1671 #ifdef BABEL_CLEANUP
1672 GtkWidget
*extra_live_button
;
1673 #endif //babel_cleanup
1674 GtkFileChooser
* file_chooser
=
1676 gtk_file_chooser_dialog_new ("Select a trace",
1677 GTK_WINDOW(mw_data
->mwindow
),
1678 GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER
,
1679 GTK_STOCK_CANCEL
, GTK_RESPONSE_CANCEL
,
1680 GTK_STOCK_OPEN
, GTK_RESPONSE_ACCEPT
,
1682 #ifdef BABEL_CLEANUP
1683 /* Button to indicate the opening of a live trace */
1684 extra_live_button
= gtk_check_button_new_with_mnemonic ("Trace is live (currently being writen)");
1685 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (extra_live_button
), FALSE
);
1686 gtk_file_chooser_set_extra_widget (GTK_FILE_CHOOSER (file_chooser
), extra_live_button
);
1687 #endif //babel_cleanup
1688 gtk_file_chooser_set_show_hidden (file_chooser
, TRUE
);
1689 if(remember_trace_dir
[0] != '\0')
1690 gtk_file_chooser_set_filename(file_chooser
, remember_trace_dir
);
1692 gboolean closeFileChooserDialog
= TRUE
;
1696 id
= gtk_dialog_run(GTK_DIALOG(file_chooser
));
1698 case GTK_RESPONSE_ACCEPT
:
1699 case GTK_RESPONSE_OK
:
1700 path
= gtk_file_chooser_get_filename (file_chooser
);
1702 strncpy(remember_trace_dir
, path
, PATH_MAX
);
1703 strncat(remember_trace_dir
, "/", PATH_MAX
);
1704 if(!path
|| strlen(path
) == 0){
1707 get_absolute_pathname(path
, abs_path
);
1709 if(lttv_traceset_add_path(traceset
,abs_path
) != 0 ){ /*failure*/
1711 g_warning("cannot open trace %s", abs_path
);
1712 strncpy(remember_trace_dir
, "\0", PATH_MAX
);
1713 GtkWidget
*dialogue
=
1714 gtk_message_dialog_new(
1715 GTK_WINDOW(gtk_widget_get_toplevel(widget
)),
1716 GTK_DIALOG_MODAL
|GTK_DIALOG_DESTROY_WITH_PARENT
,
1719 "Cannot open trace : maybe you should enter in the directory "
1721 gtk_dialog_run(GTK_DIALOG(dialogue
));
1722 gtk_widget_destroy(dialogue
);
1723 closeFileChooserDialog
= FALSE
;
1726 closeFileChooserDialog
= TRUE
;
1727 SetTraceset(tab
, traceset
);
1730 //update current tab
1731 //update_traceset(mw_data);
1733 // in expose now call_pending_read_hooks(mw_data);
1735 //lttvwindow_report_current_time(mw_data,&(tab->current_time));
1737 case GTK_RESPONSE_REJECT
:
1738 case GTK_RESPONSE_CANCEL
:
1740 closeFileChooserDialog
= TRUE
;
1743 }while(!closeFileChooserDialog
);
1745 gtk_widget_destroy((GtkWidget
*)file_chooser
);
1749 /* remove_trace removes a trace from the current traceset if all viewers in
1750 * the current tab are not interested in the trace. It first displays a
1751 * dialogue, which shows all traces in the current traceset, to let user choose
1752 * a trace, then it checks if all viewers unselect the trace, if it is true,
1753 * it will remove the trace, recreate the traceset_contex,
1754 * and redraws all the viewer of the current tab. If there is on trace in the
1755 * current traceset, it will delete all viewers of the current tab
1757 * It destroys the filter tree. FIXME... we should request for an update
1761 void remove_trace(GtkWidget
*widget
, gpointer user_data
)
1763 #ifdef BABEL_CLEANUP
1765 LttvTrace
* trace_v
;
1766 LttvTraceset
* traceset
;
1767 gint i
, j
, nb_trace
, index
=-1;
1768 char ** name
, *remove_trace_name
;
1769 MainWindow
* mw_data
= get_window_data_struct(widget
);
1770 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
1772 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
1773 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
1779 LttvPluginTab
*ptab
;
1780 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
1784 nb_trace
=lttv_traceset_number(tab
->traceset_info
->traceset
);
1785 name
= g_new(char*,nb_trace
);
1786 for(i
= 0; i
< nb_trace
; i
++){
1787 trace_v
= lttv_traceset_get(tab
->traceset_info
->traceset
, i
);
1788 trace
= lttv_trace(trace_v
);
1789 name
[i
] = (char *) g_quark_to_string(ltt_trace_name(trace
));
1792 remove_trace_name
= get_remove_trace(mw_data
, name
, nb_trace
);
1795 if(remove_trace_name
){
1797 /* yuk, cut n paste from old code.. should be better (MD)*/
1798 for(i
= 0; i
<nb_trace
; i
++) {
1799 if(strcmp(remove_trace_name
,name
[i
]) == 0){
1804 traceset
= tab
->traceset_info
->traceset
;
1805 //Keep a reference to the traces so they are not freed.
1806 for(j
=0; j
<lttv_traceset_number(traceset
); j
++)
1808 LttvTrace
* trace
= lttv_traceset_get(traceset
, j
);
1809 lttv_trace_ref(trace
);
1812 //remove state update hooks
1813 lttv_state_remove_event_hooks(
1814 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1815 lttv_context_fini(LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
));
1816 g_object_unref(tab
->traceset_info
->traceset_context
);
1818 trace_v
= lttv_traceset_get(traceset
, index
);
1820 lttv_traceset_remove(traceset
, index
);
1821 lttv_trace_unref(trace_v
); // Remove local reference
1823 if(lttv_trace_get_ref_number(trace_v
) <= 1) {
1824 /* ref 1 : lttvwindowtraces only*/
1825 ltt_trace_close(lttv_trace(trace_v
));
1826 /* lttvwindowtraces_remove_trace takes care of destroying
1827 * the traceset linked with the trace_v and also of destroying
1828 * the trace_v at the same time.
1830 lttvwindowtraces_remove_trace(trace_v
);
1833 tab
->traceset_info
->traceset_context
=
1834 g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
1836 LTTV_TRACESET_CONTEXT(tab
->
1837 traceset_info
->traceset_context
),traceset
);
1838 //add state update hooks
1839 lttv_state_add_event_hooks(
1840 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1842 //Remove local reference to the traces.
1843 for(j
=0; j
<lttv_traceset_number(traceset
); j
++)
1845 LttvTrace
* trace
= lttv_traceset_get(traceset
, j
);
1846 lttv_trace_unref(trace
);
1849 SetTraceset(tab
, (gpointer
)traceset
);
1852 #endif /* BABEL_CLEANUP */
1856 void remove_trace(GtkWidget
* widget
, gpointer user_data
)
1859 LttvTrace
* trace_v
;
1860 LttvTraceset
* traceset
;
1861 gint i
, j
, nb_trace
;
1862 char ** name
, *remove_trace_name
;
1863 MainWindow
* mw_data
= get_window_data_struct(widget
);
1864 LttvTracesetSelector
* s
;
1865 LttvTraceSelector
* t
;
1868 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
1870 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
1871 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
1877 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
1880 nb_trace
=lttv_traceset_number(tab
->traceset_info
->traceset
);
1881 name
= g_new(char*,nb_trace
);
1882 for(i
= 0; i
< nb_trace
; i
++){
1883 trace_v
= lttv_traceset_get(tab
->traceset_info
->traceset
, i
);
1884 trace
= lttv_trace(trace_v
);
1885 name
[i
] = ltt_trace_name(trace
);
1888 remove_trace_name
= get_remove_trace(name
, nb_trace
);
1890 if(remove_trace_name
){
1891 for(i
=0; i
<nb_trace
; i
++){
1892 if(strcmp(remove_trace_name
,name
[i
]) == 0){
1893 //unselect the trace from the current viewer
1895 w
= gtk_multivpaned_get_widget(GTK_MULTIVPANED(tab
->multivpaned
));
1897 s
= g_object_get_data(G_OBJECT(w
), "Traceset_Selector");
1899 t
= lttv_traceset_selector_trace_get(s
,i
);
1900 lttv_trace_selector_set_selected(t
, FALSE
);
1903 //check if other viewers select the trace
1904 w
= gtk_multivpaned_get_first_widget(GTK_MULTIVPANED(tab
->multivpaned
));
1906 s
= g_object_get_data(G_OBJECT(w
), "Traceset_Selector");
1908 t
= lttv_traceset_selector_trace_get(s
,i
);
1909 selected
= lttv_trace_selector_get_selected(t
);
1912 w
= gtk_multivpaned_get_next_widget(GTK_MULTIVPANED(tab
->multivpaned
));
1914 }else selected
= FALSE
;
1916 //if no viewer selects the trace, remove it
1918 remove_trace_from_traceset_selector(GTK_MULTIVPANED(tab
->multivpaned
), i
);
1920 traceset
= tab
->traceset_info
->traceset
;
1921 //Keep a reference to the traces so they are not freed.
1922 for(j
=0; j
<lttv_traceset_number(traceset
); j
++)
1924 LttvTrace
* trace
= lttv_traceset_get(traceset
, j
);
1925 lttv_trace_ref(trace
);
1928 //remove state update hooks
1929 lttv_state_remove_event_hooks(
1930 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1931 lttv_context_fini(LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
));
1932 g_object_unref(tab
->traceset_info
->traceset_context
);
1935 trace_v
= lttv_traceset_get(traceset
, i
);
1937 if(lttv_trace_get_ref_number(trace_v
) <= 2) {
1938 /* ref 2 : traceset, local */
1939 lttvwindowtraces_remove_trace(trace_v
);
1940 ltt_trace_close(lttv_trace(trace_v
));
1943 lttv_traceset_remove(traceset
, i
);
1944 lttv_trace_unref(trace_v
); // Remove local reference
1946 if(!lttv_trace_get_ref_number(trace_v
))
1947 lttv_trace_destroy(trace_v
);
1949 tab
->traceset_info
->traceset_context
=
1950 g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
1952 LTTV_TRACESET_CONTEXT(tab
->
1953 traceset_info
->traceset_context
),traceset
);
1954 //add state update hooks
1955 lttv_state_add_event_hooks(
1956 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1958 //Remove local reference to the traces.
1959 for(j
=0; j
<lttv_traceset_number(traceset
); j
++)
1961 LttvTrace
* trace
= lttv_traceset_get(traceset
, j
);
1962 lttv_trace_unref(trace
);
1966 //update current tab
1967 //update_traceset(mw_data);
1970 SetTraceset(tab
, (gpointer
)traceset
);
1971 // in expose now call_pending_read_hooks(mw_data);
1973 //lttvwindow_report_current_time(mw_data,&(tab->current_time));
1976 // while(tab->multi_vpaned->num_children){
1977 // gtk_multi_vpaned_widget_delete(tab->multi_vpaned);
1991 /* Redraw all the viewers in the current tab */
1992 void redraw(GtkWidget
*widget
, gpointer user_data
)
1994 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
1995 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
1996 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2003 LttvPluginTab
*ptab
;
2004 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
2009 LttvAttributeValue value
;
2011 retval
= lttv_iattribute_find_by_path(tab
->attributes
, "hooks/redraw", LTTV_POINTER
, &value
);
2014 tmp
= (LttvHooks
*)*(value
.v_pointer
);
2016 lttv_hooks_call(tmp
,NULL
);
2020 void continue_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
)));
2031 LttvPluginTab
*ptab
;
2032 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
2037 LttvAttributeValue value
;
2039 retval
= lttv_iattribute_find_by_path(tab
->attributes
, "hooks/continue",
2040 LTTV_POINTER
, &value
);
2043 tmp
= (LttvHooks
*)*(value
.v_pointer
);
2045 lttv_hooks_call(tmp
,NULL
);
2048 /* Stop the processing for the calling main window's current tab.
2049 * It removes every processing requests that are in its list. It does not call
2050 * the end request hooks, because the request is not finished.
2053 void stop_processing(GtkWidget
*widget
, gpointer user_data
)
2055 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
2056 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2057 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2062 LttvPluginTab
*ptab
;
2063 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
2066 GSList
*iter
= tab
->events_requests
;
2068 while(iter
!= NULL
) {
2069 GSList
*remove_iter
= iter
;
2070 iter
= g_slist_next(iter
);
2072 g_free(remove_iter
->data
);
2073 tab
->events_requests
=
2074 g_slist_remove_link(tab
->events_requests
, remove_iter
);
2076 tab
->events_request_pending
= FALSE
;
2077 tab
->stop_foreground
= TRUE
;
2078 g_idle_remove_by_data(tab
);
2079 g_assert(g_slist_length(tab
->events_requests
) == 0);
2083 /* save will save the traceset to a file
2084 * Not implemented yet FIXME
2087 void save(GtkWidget
* widget
, gpointer user_data
)
2092 void save_as(GtkWidget
* widget
, gpointer user_data
)
2094 g_info("Save as\n");
2098 /* zoom will change the time_window of all the viewers of the
2099 * current tab, and redisplay them. The main functionality is to
2100 * determine the new time_window of the current tab
2103 void zoom(GtkWidget
* widget
, double size
)
2105 #ifdef BABEL_CLEANUP
2106 TimeInterval time_span
;
2107 TimeWindow new_time_window
;
2108 LttTime current_time
, time_delta
;
2109 LttvTracesetContext
*tsc
;
2110 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
2112 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2113 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2119 LttvPluginTab
*ptab
;
2120 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
2124 if(size
== 1) return;
2126 tsc
= LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
2127 time_span
= tsc
->time_span
;
2128 new_time_window
= tab
->time_window
;
2129 current_time
= tab
->current_time
;
2131 time_delta
= ltt_time_sub(time_span
.end_time
,time_span
.start_time
);
2133 new_time_window
.start_time
= time_span
.start_time
;
2134 new_time_window
.time_width
= time_delta
;
2135 new_time_window
.time_width_double
= ltt_time_to_double(time_delta
);
2136 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
2137 new_time_window
.time_width
) ;
2139 new_time_window
.time_width
= ltt_time_div(new_time_window
.time_width
, size
);
2140 new_time_window
.time_width_double
=
2141 ltt_time_to_double(new_time_window
.time_width
);
2142 if(ltt_time_compare(new_time_window
.time_width
,time_delta
) > 0)
2143 { /* Case where zoom out is bigger than trace length */
2144 new_time_window
.start_time
= time_span
.start_time
;
2145 new_time_window
.time_width
= time_delta
;
2146 new_time_window
.time_width_double
= ltt_time_to_double(time_delta
);
2147 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
2148 new_time_window
.time_width
) ;
2152 /* Center the image on the current time */
2153 new_time_window
.start_time
=
2154 ltt_time_sub(current_time
,
2155 ltt_time_from_double(new_time_window
.time_width_double
/2.0));
2156 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
2157 new_time_window
.time_width
) ;
2158 /* If on borders, don't fall off */
2159 if(ltt_time_compare(new_time_window
.start_time
, time_span
.start_time
) <0
2160 || ltt_time_compare(new_time_window
.start_time
, time_span
.end_time
) >0)
2162 new_time_window
.start_time
= time_span
.start_time
;
2163 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
2164 new_time_window
.time_width
) ;
2168 if(ltt_time_compare(new_time_window
.end_time
,
2169 time_span
.end_time
) > 0
2170 || ltt_time_compare(new_time_window
.end_time
,
2171 time_span
.start_time
) < 0)
2173 new_time_window
.start_time
=
2174 ltt_time_sub(time_span
.end_time
, new_time_window
.time_width
);
2176 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
2177 new_time_window
.time_width
) ;
2184 if(ltt_time_compare(new_time_window
.time_width
, ltt_time_zero
) == 0) {
2185 g_warning("Zoom more than 1 ns impossible");
2187 time_change_manager(tab
, new_time_window
);
2190 #endif /* BABEL_CLEANUP */
2193 void zoom_in(GtkWidget
* widget
, gpointer user_data
)
2198 void zoom_out(GtkWidget
* widget
, gpointer user_data
)
2203 void zoom_extended(GtkWidget
* widget
, gpointer user_data
)
2208 void go_to_time(GtkWidget
* widget
, gpointer user_data
)
2210 g_info("Go to time\n");
2213 void show_time_frame(GtkWidget
* widget
, gpointer user_data
)
2215 g_info("Show time frame\n");
2219 /* callback function */
2222 on_empty_traceset_activate (GtkMenuItem
*menuitem
,
2225 create_new_window((GtkWidget
*)menuitem
, user_data
, FALSE
);
2230 on_clone_traceset_activate (GtkMenuItem
*menuitem
,
2233 create_new_window((GtkWidget
*)menuitem
, user_data
, TRUE
);
2237 /* create_new_tab calls create_tab to construct a new tab in the main window
2240 LttvPluginTab
*create_new_tab(GtkWidget
* widget
, gpointer user_data
)
2242 gchar label
[PATH_MAX
];
2243 MainWindow
* mw_data
= get_window_data_struct(widget
);
2245 GtkNotebook
* notebook
= (GtkNotebook
*)lookup_widget(widget
, "MNotebook");
2246 if(notebook
== NULL
){
2247 g_info("Notebook does not exist\n");
2250 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2251 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2257 LttvPluginTab
*ptab
;
2258 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
2259 copy_tab
= ptab
->tab
;
2262 strcpy(label
,"Page");
2263 if(get_label(mw_data
, label
,"Get the name of the tab","Please input tab's name")) {
2264 LttvPluginTab
*ptab
;
2266 ptab
= g_object_new(LTTV_TYPE_PLUGIN_TAB
, NULL
);
2267 init_tab (ptab
->tab
, mw_data
, copy_tab
, notebook
, label
);
2268 ptab
->parent
.top_widget
= ptab
->tab
->top_widget
;
2269 g_object_set_data_full(
2270 G_OBJECT(ptab
->tab
->vbox
),
2273 (GDestroyNotify
)tab_destructor
);
2280 on_tab_activate (GtkMenuItem
*menuitem
,
2283 create_new_tab((GtkWidget
*)menuitem
, user_data
);
2288 on_open_activate (GtkMenuItem
*menuitem
,
2291 #ifdef UNFINISHED_FEATURE
2292 open_traceset((GtkWidget
*)menuitem
, user_data
);
2298 on_close_activate (GtkMenuItem
*menuitem
,
2301 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2302 main_window_destructor(mw_data
);
2306 /* remove the current tab from the main window
2310 on_close_tab_activate (GtkWidget
*widget
,
2314 GtkWidget
* notebook
;
2315 notebook
= lookup_widget(widget
, "MNotebook");
2316 if(notebook
== NULL
){
2317 g_info("Notebook does not exist\n");
2321 page_num
= gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
));
2323 gtk_notebook_remove_page(GTK_NOTEBOOK(notebook
), page_num
);
2328 on_close_tab_X_clicked (GtkWidget
*widget
,
2332 GtkWidget
*notebook
= lookup_widget(widget
, "MNotebook");
2333 if(notebook
== NULL
){
2334 g_info("Notebook does not exist\n");
2338 if((page_num
= gtk_notebook_page_num(GTK_NOTEBOOK(notebook
), widget
)) != -1)
2339 gtk_notebook_remove_page(GTK_NOTEBOOK(notebook
), page_num
);
2345 on_add_trace_activate (GtkMenuItem
*menuitem
,
2348 add_trace((GtkWidget
*)menuitem
, user_data
);
2353 on_remove_trace_activate (GtkMenuItem
*menuitem
,
2356 remove_trace((GtkWidget
*)menuitem
, user_data
);
2361 on_save_activate (GtkMenuItem
*menuitem
,
2364 save((GtkWidget
*)menuitem
, user_data
);
2369 on_save_as_activate (GtkMenuItem
*menuitem
,
2372 save_as((GtkWidget
*)menuitem
, user_data
);
2377 on_quit_activate (GtkMenuItem
*menuitem
,
2380 while (g_slist_length(g_main_window_list
) != 0) {
2381 on_MWindow_destroy(((MainWindow
*)g_main_window_list
->data
)->mwindow
,
2388 on_cut_activate (GtkMenuItem
*menuitem
,
2396 on_copy_activate (GtkMenuItem
*menuitem
,
2404 on_paste_activate (GtkMenuItem
*menuitem
,
2412 on_delete_activate (GtkMenuItem
*menuitem
,
2420 on_zoom_in_activate (GtkMenuItem
*menuitem
,
2423 zoom_in((GtkWidget
*)menuitem
, user_data
);
2428 on_zoom_out_activate (GtkMenuItem
*menuitem
,
2431 zoom_out((GtkWidget
*)menuitem
, user_data
);
2436 on_zoom_extended_activate (GtkMenuItem
*menuitem
,
2439 zoom_extended((GtkWidget
*)menuitem
, user_data
);
2444 on_go_to_time_activate (GtkMenuItem
*menuitem
,
2447 go_to_time((GtkWidget
*)menuitem
, user_data
);
2452 on_show_time_frame_activate (GtkMenuItem
*menuitem
,
2455 show_time_frame((GtkWidget
*)menuitem
, user_data
);
2460 on_move_viewer_up_activate (GtkMenuItem
*menuitem
,
2463 move_up_viewer((GtkWidget
*)menuitem
, user_data
);
2468 on_move_viewer_down_activate (GtkMenuItem
*menuitem
,
2471 move_down_viewer((GtkWidget
*)menuitem
, user_data
);
2476 on_remove_viewer_activate (GtkMenuItem
*menuitem
,
2479 delete_viewer((GtkWidget
*)menuitem
, user_data
);
2483 on_trace_facility_activate (GtkMenuItem
*menuitem
,
2486 g_info("Trace facility selector: %s\n", "");
2490 /* Dispaly a file selection dialogue to let user select a library, then call
2491 * lttv_library_load().
2495 on_load_library_activate (GtkMenuItem
*menuitem
,
2498 GError
*error
= NULL
;
2499 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2501 gchar load_module_path_alter
[PATH_MAX
];
2505 gchar
*load_module_path
;
2506 name
= g_ptr_array_new();
2507 nb
= lttv_library_path_number();
2508 /* ask for the library path */
2512 path
= lttv_library_path_get(i
);
2513 g_ptr_array_add(name
, path
);
2516 load_module_path
= get_selection(mw_data
,
2517 (char **)(name
->pdata
), name
->len
,
2518 "Select a library path", "Library paths");
2519 if(load_module_path
!= NULL
)
2520 strncpy(load_module_path_alter
, load_module_path
, PATH_MAX
-1); // -1 for /
2522 g_ptr_array_free(name
, TRUE
);
2524 if(load_module_path
== NULL
) return;
2528 /* Make sure the module path ends with a / */
2529 gchar
*ptr
= load_module_path_alter
;
2531 ptr
= strchr(ptr
, '\0');
2533 if(*(ptr
-1) != '/') {
2540 /* Ask for the library to load : list files in the previously selected
2542 gchar str
[PATH_MAX
];
2545 GtkFileSelection
* file_selector
=
2546 (GtkFileSelection
*)gtk_file_selection_new("Select a module");
2547 gtk_file_selection_set_filename(file_selector
, load_module_path_alter
);
2548 gtk_file_selection_hide_fileop_buttons(file_selector
);
2550 gtk_window_set_transient_for(GTK_WINDOW(file_selector
),
2551 GTK_WINDOW(mw_data
->mwindow
));
2554 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
2556 case GTK_RESPONSE_ACCEPT
:
2557 case GTK_RESPONSE_OK
:
2558 dir
= gtk_file_selection_get_selections (file_selector
);
2559 strncpy(str
,dir
[0],PATH_MAX
);
2560 strncpy(remember_plugins_dir
,dir
[0],PATH_MAX
);
2561 /* only keep file name */
2563 str1
= strrchr(str
,'/');
2566 str1
= strrchr(str
,'\\');
2571 if(*str1
== 'l' && *(str1
+1)== 'i' && *(str1
+2)=='b')
2573 remove info after
. */
2577 str2
= strrchr(str2
, '.');
2578 if(str2
!= NULL
) *str2
= '\0';
2580 lttv_module_require(str1
, &error
);
2582 lttv_library_load(str1
, &error
);
2583 if(error
!= NULL
) g_warning("%s", error
->message
);
2584 else g_info("Load library: %s\n", str
);
2586 case GTK_RESPONSE_REJECT
:
2587 case GTK_RESPONSE_CANCEL
:
2589 gtk_widget_destroy((GtkWidget
*)file_selector
);
2600 /* Display all loaded modules, let user to select a module to unload
2601 * by calling lttv_module_unload
2605 on_unload_library_activate (GtkMenuItem
*menuitem
,
2608 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2610 LttvLibrary
*library
= NULL
;
2615 name
= g_ptr_array_new();
2616 nb
= lttv_library_number();
2617 LttvLibraryInfo
*lib_info
= g_new(LttvLibraryInfo
,nb
);
2618 /* ask for the library name */
2621 LttvLibrary
*iter_lib
= lttv_library_get(i
);
2622 lttv_library_info(iter_lib
, &lib_info
[i
]);
2624 gchar
*path
= lib_info
[i
].name
;
2625 g_ptr_array_add(name
, path
);
2627 lib_name
= get_selection(mw_data
, (char **)(name
->pdata
), name
->len
,
2628 "Select a library", "Libraries");
2629 if(lib_name
!= NULL
) {
2631 if(strcmp(lib_name
, lib_info
[i
].name
) == 0) {
2632 library
= lttv_library_get(i
);
2637 g_ptr_array_free(name
, TRUE
);
2640 if(lib_name
== NULL
) return;
2642 if(library
!= NULL
) lttv_library_unload(library
);
2646 /* Dispaly a file selection dialogue to let user select a module, then call
2647 * lttv_module_require().
2651 on_load_module_activate (GtkMenuItem
*menuitem
,
2654 GError
*error
= NULL
;
2655 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2657 LttvLibrary
*library
= NULL
;
2662 name
= g_ptr_array_new();
2663 nb
= lttv_library_number();
2664 LttvLibraryInfo
*lib_info
= g_new(LttvLibraryInfo
,nb
);
2665 /* ask for the library name */
2668 LttvLibrary
*iter_lib
= lttv_library_get(i
);
2669 lttv_library_info(iter_lib
, &lib_info
[i
]);
2671 gchar
*path
= lib_info
[i
].name
;
2672 g_ptr_array_add(name
, path
);
2674 lib_name
= get_selection(mw_data
,(char **)(name
->pdata
), name
->len
,
2675 "Select a library", "Libraries");
2676 if(lib_name
!= NULL
) {
2678 if(strcmp(lib_name
, lib_info
[i
].name
) == 0) {
2679 library
= lttv_library_get(i
);
2684 g_ptr_array_free(name
, TRUE
);
2687 if(lib_name
== NULL
) return;
2690 //LttvModule *module;
2691 gchar module_name_out
[PATH_MAX
];
2693 /* Ask for the module to load : list modules in the selected lib */
2697 nb
= lttv_library_module_number(library
);
2698 LttvModuleInfo
*module_info
= g_new(LttvModuleInfo
,nb
);
2699 name
= g_ptr_array_new();
2700 /* ask for the module name */
2703 LttvModule
*iter_module
= lttv_library_module_get(library
, i
);
2704 lttv_module_info(iter_module
, &module_info
[i
]);
2706 gchar
*path
= module_info
[i
].name
;
2707 g_ptr_array_add(name
, path
);
2709 module_name
= get_selection(mw_data
, (char **)(name
->pdata
), name
->len
,
2710 "Select a module", "Modules");
2711 if(module_name
!= NULL
) {
2713 if(strcmp(module_name
, module_info
[i
].name
) == 0) {
2714 strncpy(module_name_out
, module_name
, PATH_MAX
);
2715 //module = lttv_library_module_get(i);
2721 g_ptr_array_free(name
, TRUE
);
2722 g_free(module_info
);
2724 if(module_name
== NULL
) return;
2727 lttv_module_require(module_name_out
, &error
);
2728 if(error
!= NULL
) g_warning("%s", error
->message
);
2729 else g_info("Load module: %s", module_name_out
);
2736 gchar str
[PATH_MAX
];
2739 GtkFileSelection
* file_selector
=
2740 (GtkFileSelection
*)gtk_file_selection_new("Select a module");
2741 gtk_file_selection_set_filename(file_selector
, load_module_path_alter
);
2742 gtk_file_selection_hide_fileop_buttons(file_selector
);
2745 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
2747 case GTK_RESPONSE_ACCEPT
:
2748 case GTK_RESPONSE_OK
:
2749 dir
= gtk_file_selection_get_selections (file_selector
);
2750 strncpy(str
,dir
[0],PATH_MAX
);
2751 strncpy(remember_plugins_dir
,dir
[0],PATH_MAX
);
2753 /* only keep file name */
2755 str1
= strrchr(str
,'/');
2758 str1
= strrchr(str
,'\\');
2763 if(*str1
== 'l' && *(str1
+1)== 'i' && *(str1
+2)=='b')
2765 remove info after
. */
2769 str2
= strrchr(str2
, '.');
2770 if(str2
!= NULL
) *str2
= '\0';
2772 lttv_module_require(str1
, &error
);
2774 lttv_library_load(str1
, &error
);
2775 if(error
!= NULL
) g_warning(error
->message
);
2776 else g_info("Load library: %s\n", str
);
2778 case GTK_RESPONSE_REJECT
:
2779 case GTK_RESPONSE_CANCEL
:
2781 gtk_widget_destroy((GtkWidget
*)file_selector
);
2793 /* Display all loaded modules, let user to select a module to unload
2794 * by calling lttv_module_unload
2798 on_unload_module_activate (GtkMenuItem
*menuitem
,
2801 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2803 LttvLibrary
*library
= NULL
;
2808 name
= g_ptr_array_new();
2809 nb
= lttv_library_number();
2810 LttvLibraryInfo
*lib_info
= g_new(LttvLibraryInfo
,nb
);
2811 /* ask for the library name */
2814 LttvLibrary
*iter_lib
= lttv_library_get(i
);
2815 lttv_library_info(iter_lib
, &lib_info
[i
]);
2817 gchar
*path
= lib_info
[i
].name
;
2818 g_ptr_array_add(name
, path
);
2820 lib_name
= get_selection(mw_data
, (char **)(name
->pdata
), name
->len
,
2821 "Select a library", "Libraries");
2822 if(lib_name
!= NULL
) {
2824 if(strcmp(lib_name
, lib_info
[i
].name
) == 0) {
2825 library
= lttv_library_get(i
);
2830 g_ptr_array_free(name
, TRUE
);
2833 if(lib_name
== NULL
) return;
2836 LttvModule
*module
= NULL
;
2838 /* Ask for the module to load : list modules in the selected lib */
2842 nb
= lttv_library_module_number(library
);
2843 LttvModuleInfo
*module_info
= g_new(LttvModuleInfo
,nb
);
2844 name
= g_ptr_array_new();
2845 /* ask for the module name */
2848 LttvModule
*iter_module
= lttv_library_module_get(library
, i
);
2849 lttv_module_info(iter_module
, &module_info
[i
]);
2851 gchar
*path
= module_info
[i
].name
;
2852 if(module_info
[i
].use_count
> 0) g_ptr_array_add(name
, path
);
2854 module_name
= get_selection(mw_data
, (char **)(name
->pdata
), name
->len
,
2855 "Select a module", "Modules");
2856 if(module_name
!= NULL
) {
2858 if(strcmp(module_name
, module_info
[i
].name
) == 0) {
2859 module
= lttv_library_module_get(library
, i
);
2865 g_ptr_array_free(name
, TRUE
);
2866 g_free(module_info
);
2868 if(module_name
== NULL
) return;
2871 LttvModuleInfo module_info
;
2872 lttv_module_info(module
, &module_info
);
2873 g_info("Release module: %s\n", module_info
.name
);
2875 lttv_module_release(module
);
2879 /* Display a directory dialogue to let user select a path for library searching
2883 on_add_library_search_path_activate (GtkMenuItem
*menuitem
,
2886 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2887 //GtkDirSelection * file_selector = (GtkDirSelection *)gtk_dir_selection_new("Select library path");
2888 GtkFileSelection
* file_selector
= (GtkFileSelection
*)gtk_file_selection_new("Select a trace");
2889 gtk_widget_hide( (file_selector
)->file_list
->parent
) ;
2891 gtk_window_set_transient_for(GTK_WINDOW(file_selector
),
2892 GTK_WINDOW(mw_data
->mwindow
));
2897 if(remember_plugins_dir
[0] != '\0')
2898 gtk_file_selection_set_filename(file_selector
, remember_plugins_dir
);
2900 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
2902 case GTK_RESPONSE_ACCEPT
:
2903 case GTK_RESPONSE_OK
:
2904 dir
= gtk_file_selection_get_filename (file_selector
);
2905 strncpy(remember_plugins_dir
,dir
,PATH_MAX
);
2906 strncat(remember_plugins_dir
,"/",PATH_MAX
);
2907 lttv_library_path_add(dir
);
2908 case GTK_RESPONSE_REJECT
:
2909 case GTK_RESPONSE_CANCEL
:
2911 gtk_widget_destroy((GtkWidget
*)file_selector
);
2917 /* Display a directory dialogue to let user select a path for library searching
2921 on_remove_library_search_path_activate (GtkMenuItem
*menuitem
,
2924 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2926 const char *lib_path
;
2930 name
= g_ptr_array_new();
2931 nb
= lttv_library_path_number();
2932 /* ask for the library name */
2935 gchar
*path
= lttv_library_path_get(i
);
2936 g_ptr_array_add(name
, path
);
2938 lib_path
= get_selection(mw_data
, (char **)(name
->pdata
), name
->len
,
2939 "Select a library path", "Library paths");
2941 g_ptr_array_free(name
, TRUE
);
2943 if(lib_path
== NULL
) return;
2946 lttv_library_path_remove(lib_path
);
2950 on_color_activate (GtkMenuItem
*menuitem
,
2958 on_save_configuration_activate (GtkMenuItem
*menuitem
,
2961 g_info("Save configuration\n");
2966 on_content_activate (GtkMenuItem
*menuitem
,
2969 char* filename
= NULL
,
2972 const char* relativePath
= "doc/user/user_guide/html/index.html";
2973 filename
= g_build_filename (g_get_current_dir(), relativePath
, NULL
);
2974 path
= g_strdup_printf ("ghelp://%s", filename
);
2976 screen
= gdk_screen_get_default();
2977 gtk_show_uri (screen
, path
, gtk_get_current_event_time(), NULL
);
2981 g_info("Content\n");
2986 on_about_close_activate (GtkButton
*button
,
2989 GtkWidget
*about_widget
= GTK_WIDGET(user_data
);
2991 gtk_widget_destroy(about_widget
);
2995 on_about_activate (GtkMenuItem
*menuitem
,
2998 MainWindow
*main_window
= get_window_data_struct(GTK_WIDGET(menuitem
));
2999 GtkWidget
*window_widget
= main_window
->mwindow
;
3000 GtkWidget
*about_widget
= gtk_window_new(GTK_WINDOW_TOPLEVEL
);
3001 GtkWindow
*about_window
= GTK_WINDOW(about_widget
);
3003 gtk_window_set_title(about_window
, "About Linux Trace Toolkit");
3005 gtk_window_set_resizable(about_window
, FALSE
);
3006 gtk_window_set_transient_for(about_window
, GTK_WINDOW(window_widget
));
3007 gtk_window_set_destroy_with_parent(about_window
, TRUE
);
3008 gtk_window_set_modal(about_window
, FALSE
);
3010 /* Put the about window at the center of the screen */
3011 gtk_window_set_position(about_window
, GTK_WIN_POS_CENTER_ALWAYS
);
3013 GtkWidget
*vbox
= gtk_vbox_new(FALSE
, 1);
3015 gtk_container_add(GTK_CONTAINER(about_widget
), vbox
);
3018 GtkWidget
*label1
= gtk_label_new("");
3019 gtk_misc_set_padding(GTK_MISC(label1
), 10, 20);
3020 gtk_label_set_markup(GTK_LABEL(label1
), "\
3021 <big>Linux Trace Toolkit " VERSION
"</big>");
3022 gtk_label_set_justify(GTK_LABEL(label1
), GTK_JUSTIFY_CENTER
);
3024 GtkWidget
*label2
= gtk_label_new("");
3025 gtk_misc_set_padding(GTK_MISC(label2
), 10, 20);
3026 gtk_label_set_markup(GTK_LABEL(label2
), "\
3029 Michel Dagenais (New trace format, lttv main)\n\
3030 Mathieu Desnoyers (Kernel Tracer, Directory structure, build with automake/conf,\n\
3031 lttv gui, control flow view, gui cooperative trace reading\n\
3032 scheduler with interruptible foreground and background\n\
3033 computation, detailed event list (rewrite), trace reading\n\
3034 library (rewrite))\n\
3035 Benoit Des Ligneris, Eric Clement (Cluster adaptation, work in progress)\n\
3036 Xang-Xiu Yang (new trace reading library and converter, lttv gui, \n\
3037 detailed event list and statistics view)\n\
3038 Tom Zanussi (RelayFS)\n\
3040 Inspired from the original Linux Trace Toolkit Visualizer made by\n\
3043 GtkWidget
*label3
= gtk_label_new("");
3044 gtk_label_set_markup(GTK_LABEL(label3
), "\
3045 Linux Trace Toolkit Viewer, Copyright (C) 2004, 2005, 2006\n\
3047 Mathieu Desnoyers\n\
3049 Linux Trace Toolkit comes with ABSOLUTELY NO WARRANTY.\n\
3050 This is free software, and you are welcome to redistribute it\n\
3051 under certain conditions. See COPYING for details.");
3052 gtk_misc_set_padding(GTK_MISC(label3
), 10, 20);
3054 gtk_box_pack_start_defaults(GTK_BOX(vbox
), label1
);
3055 gtk_box_pack_start_defaults(GTK_BOX(vbox
), label2
);
3056 gtk_box_pack_start_defaults(GTK_BOX(vbox
), label3
);
3058 GtkWidget
*hbox
= gtk_hbox_new(TRUE
, 0);
3059 gtk_box_pack_end(GTK_BOX(vbox
), hbox
, FALSE
, FALSE
, 0);
3060 GtkWidget
*close_button
= gtk_button_new_with_mnemonic("_Close");
3061 gtk_box_pack_end(GTK_BOX(hbox
), close_button
, FALSE
, FALSE
, 0);
3062 gtk_container_set_border_width(GTK_CONTAINER(close_button
), 20);
3064 g_signal_connect(G_OBJECT(close_button
), "clicked",
3065 G_CALLBACK(on_about_close_activate
),
3066 (gpointer
)about_widget
);
3068 gtk_widget_show_all(about_widget
);
3073 on_button_new_clicked (GtkButton
*button
,
3076 create_new_window((GtkWidget
*)button
, user_data
, TRUE
);
3080 on_button_new_tab_clicked (GtkButton
*button
,
3083 create_new_tab((GtkWidget
*)button
, user_data
);
3087 on_button_open_clicked (GtkButton
*button
,
3090 #ifdef UNFINISHED_FEATURE
3091 open_traceset((GtkWidget
*)button
, user_data
);
3097 on_button_add_trace_clicked (GtkButton
*button
,
3100 add_trace((GtkWidget
*)button
, user_data
);
3105 on_button_remove_trace_clicked (GtkButton
*button
,
3108 remove_trace((GtkWidget
*)button
, user_data
);
3112 on_button_redraw_clicked (GtkButton
*button
,
3115 redraw((GtkWidget
*)button
, user_data
);
3119 on_button_continue_processing_clicked (GtkButton
*button
,
3122 continue_processing((GtkWidget
*)button
, user_data
);
3126 on_button_stop_processing_clicked (GtkButton
*button
,
3129 stop_processing((GtkWidget
*)button
, user_data
);
3135 on_button_save_clicked (GtkButton
*button
,
3138 save((GtkWidget
*)button
, user_data
);
3143 on_button_save_as_clicked (GtkButton
*button
,
3146 save_as((GtkWidget
*)button
, user_data
);
3151 on_button_zoom_in_clicked (GtkButton
*button
,
3154 zoom_in((GtkWidget
*)button
, user_data
);
3159 on_button_zoom_out_clicked (GtkButton
*button
,
3162 zoom_out((GtkWidget
*)button
, user_data
);
3167 on_button_zoom_extended_clicked (GtkButton
*button
,
3170 zoom_extended((GtkWidget
*)button
, user_data
);
3175 on_button_go_to_time_clicked (GtkButton
*button
,
3178 go_to_time((GtkWidget
*)button
, user_data
);
3183 on_button_show_time_frame_clicked (GtkButton
*button
,
3186 show_time_frame((GtkWidget
*)button
, user_data
);
3191 on_button_move_up_clicked (GtkButton
*button
,
3194 move_up_viewer((GtkWidget
*)button
, user_data
);
3199 on_button_move_down_clicked (GtkButton
*button
,
3202 move_down_viewer((GtkWidget
*)button
, user_data
);
3207 on_button_delete_viewer_clicked (GtkButton
*button
,
3210 delete_viewer((GtkWidget
*)button
, user_data
);
3214 on_MWindow_destroy (GtkWidget
*widget
,
3217 MainWindow
*main_window
= get_window_data_struct(widget
);
3218 LttvIAttribute
*attributes
= main_window
->attributes
;
3219 LttvAttributeValue value
;
3222 //This is unnecessary, since widgets will be destroyed
3223 //by the main window widget anyway.
3224 //remove_all_menu_toolbar_constructors(main_window, NULL);
3226 retval
= lttv_iattribute_find_by_path(attributes
, "viewers/menu",
3227 LTTV_POINTER
, &value
);
3229 lttv_menus_destroy((LttvMenus
*)*(value
.v_pointer
));
3231 retval
= lttv_iattribute_find_by_path(attributes
, "viewers/toolbar",
3232 LTTV_POINTER
, &value
);
3234 lttv_toolbars_destroy((LttvToolbars
*)*(value
.v_pointer
));
3236 g_object_unref(main_window
->attributes
);
3237 g_main_window_list
= g_slist_remove(g_main_window_list
, main_window
);
3239 g_info("There are now : %d windows\n",g_slist_length(g_main_window_list
));
3240 if(g_slist_length(g_main_window_list
) == 0)
3245 on_MWindow_configure (GtkWidget
*widget
,
3246 GdkEventConfigure
*event
,
3249 // MD : removed time width modification upon resizing of the main window.
3250 // The viewers will redraw themselves completely, without time interval
3253 if(mw_data->window_width){
3254 time_span = LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context)->Time_Span ;
3255 time_win = tab->time_window;
3256 ratio = width / mw_data->window_width;
3257 tab->time_window.time_width = ltt_time_mul(time_win.time_width,ratio);
3258 time = ltt_time_sub(time_span->endTime, time_win.start_time);
3259 if(ltt_time_compare(time, tab->time_window.time_width) < 0){
3260 tab->time_window.time_width = time;
3266 mw_data->window_width = (int)width;
3275 on_MNotebook_switch_page (GtkNotebook
*notebook
,
3276 GtkNotebookPage
*page
,
3284 void time_change_manager (Tab
*tab
,
3285 TimeWindow new_time_window
)
3288 /* Only one source of time change */
3289 if(tab
->time_manager_lock
== TRUE
) return;
3291 tab
->time_manager_lock
= TRUE
;
3292 TimeInterval time_span
;
3294 LttvTraceset
*ts
= tab
->traceset_info
->traceset
;
3295 time_span
.start_time
=ltt_time_from_uint64( lttv_traceset_get_timestamp_begin(ts
));
3296 time_span
.end_time
= ltt_time_from_uint64(lttv_traceset_get_timestamp_end(ts
));
3299 LttTime start_time
= new_time_window
.start_time
;
3300 LttTime end_time
= new_time_window
.end_time
;
3302 g_assert(ltt_time_compare(start_time
, end_time
) < 0);
3305 GtkAdjustment
*adjustment
= gtk_range_get_adjustment(GTK_RANGE(tab
->scrollbar
));
3306 LttTime upper
= ltt_time_sub(time_span
.end_time
, time_span
.start_time
);
3309 gtk_range_set_increments(GTK_RANGE(tab
->scrollbar
),
3310 ltt_time_to_double(new_time_window
.time_width
)
3311 / SCROLL_STEP_PER_PAGE
3312 * NANOSECONDS_PER_SECOND
, /* step increment */
3313 ltt_time_to_double(new_time_window
.time_width
)
3314 * NANOSECONDS_PER_SECOND
); /* page increment */
3315 gtk_range_set_range(GTK_RANGE(tab
->scrollbar
),
3317 ltt_time_to_double(upper
)
3318 * NANOSECONDS_PER_SECOND
); /* upper */
3320 g_object_set(G_OBJECT(adjustment
),
3324 ltt_time_to_double(upper
), /* upper */
3326 new_time_window
.time_width_double
3327 / SCROLL_STEP_PER_PAGE
, /* step increment */
3329 new_time_window
.time_width_double
,
3330 /* page increment */
3332 new_time_window
.time_width_double
, /* page size */
3334 gtk_adjustment_changed(adjustment
);
3336 // g_object_set(G_OBJECT(adjustment),
3338 // ltt_time_to_double(
3339 // ltt_time_sub(start_time, time_span.start_time))
3342 //gtk_adjustment_value_changed(adjustment);
3343 gtk_range_set_value(GTK_RANGE(tab
->scrollbar
),
3345 ltt_time_sub(start_time
, time_span
.start_time
)) /* value */);
3347 /* set the time bar. */
3350 timebar_set_minmax_time(TIMEBAR(tab
->MTimebar
),
3351 &time_span
.start_time
,
3352 &time_span
.end_time
);
3353 timebar_set_start_time(TIMEBAR(tab
->MTimebar
),&start_time
);
3354 timebar_set_end_time(TIMEBAR(tab
->MTimebar
),&end_time
);
3358 /* call viewer hooks for new time window */
3359 set_time_window(tab
, &new_time_window
);
3361 tab
->time_manager_lock
= FALSE
;
3370 void current_time_change_manager (Tab
*tab
,
3371 LttTime new_current_time
)
3373 /* Only one source of time change */
3374 if(tab
->current_time_manager_lock
== TRUE
) return;
3376 tab
->current_time_manager_lock
= TRUE
;
3378 timebar_set_current_time(TIMEBAR(tab
->MTimebar
), &new_current_time
);
3380 set_current_time(tab
, &new_current_time
);
3382 tab
->current_time_manager_lock
= FALSE
;
3385 void current_position_change_manager(Tab
*tab
, LttvTracesetPosition
*pos
)
3387 lttv_traceset_seek_to_position( pos
);
3389 LttTime new_time
= lttv_traceset_position_get_time(pos
);
3390 /* Put the context in a state coherent position */
3391 #ifdef BABEL_CLEANUP
3392 lttv_state_traceset_seek_time_closest((LttvTracesetState
*)tsc
, ltt_time_zero
);
3393 #endif /* BABEL_CLEANUP */
3394 current_time_change_manager(tab
, new_time
);
3396 set_current_position(tab
, pos
);
3399 static void on_timebar_starttime_changed(Timebar
*timebar
,
3402 Tab
*tab
= (Tab
*)user_data
;
3403 LttvTraceset
* ts
=tab
->traceset_info
->traceset
;
3404 TimeInterval time_span
= lttv_traceset_get_time_span(ts
);
3406 TimeWindow new_time_window
= tab
->time_window
;
3407 new_time_window
.start_time
= timebar_get_start_time(timebar
);
3409 LttTime end_time
= new_time_window
.end_time
;
3411 /* TODO ybrosseau 2010-12-02: This if should have been checked
3412 by the timebar already */
3413 if(ltt_time_compare(new_time_window
.start_time
, end_time
) >= 0) {
3414 /* Then, we must push back end time : keep the same time width
3415 * if possible, else end traceset time */
3416 end_time
= LTT_TIME_MIN(ltt_time_add(new_time_window
.start_time
,
3417 new_time_window
.time_width
),
3418 time_span
.end_time
);
3421 /* Fix the time width to fit start time and end time */
3422 new_time_window
.time_width
= ltt_time_sub(end_time
,
3423 new_time_window
.start_time
);
3425 new_time_window
.time_width_double
=
3426 ltt_time_to_double(new_time_window
.time_width
);
3428 new_time_window
.end_time
= end_time
;
3430 /* Notify the time_manager */
3431 time_change_manager(tab
, new_time_window
);
3435 static void on_timebar_endtime_changed(Timebar
*timebar
,
3438 Tab
*tab
= (Tab
*)user_data
;
3439 LttvTraceset
* ts
=tab
->traceset_info
->traceset
;
3440 TimeInterval time_span
= lttv_traceset_get_time_span(ts
);
3442 TimeWindow new_time_window
= tab
->time_window
;
3444 LttTime end_time
= timebar_get_end_time(timebar
);
3446 /* TODO ybrosseau 2010-12-02: This if should have been
3447 checked by the timebar already */
3448 if(ltt_time_compare(new_time_window
.start_time
, end_time
) >= 0) {
3449 /* Then, we must push front start time : keep the same time
3450 width if possible, else end traceset time */
3451 new_time_window
.start_time
= LTT_TIME_MAX(
3452 ltt_time_sub(end_time
,
3453 new_time_window
.time_width
),
3454 time_span
.start_time
);
3457 /* Fix the time width to fit start time and end time */
3458 new_time_window
.time_width
= ltt_time_sub(end_time
,
3459 new_time_window
.start_time
);
3461 new_time_window
.time_width_double
=
3462 ltt_time_to_double(new_time_window
.time_width
);
3464 new_time_window
.end_time
= end_time
;
3466 /* Notify the time_manager */
3467 time_change_manager(tab
, new_time_window
);
3469 static void on_timebar_currenttime_changed(Timebar
*timebar
,
3472 Tab
*tab
= (Tab
*)user_data
;
3474 LttTime new_current_time
= timebar_get_current_time(timebar
);
3476 current_time_change_manager(tab
, new_current_time
);
3479 void scroll_value_changed_cb(GtkWidget
*scrollbar
,
3482 Tab
*tab
= (Tab
*)user_data
;
3483 TimeWindow new_time_window
;
3485 GtkAdjustment
*adjust
= gtk_range_get_adjustment(GTK_RANGE(scrollbar
));
3486 gdouble value
= gtk_adjustment_get_value(adjust
);
3487 // gdouble upper, lower, ratio, page_size;
3490 LttvTraceset
* ts
= tab
->traceset_info
->traceset
;
3491 TimeInterval time_span
= lttv_traceset_get_time_span(ts
);
3493 time
= ltt_time_add(ltt_time_from_double(value
),
3494 time_span
.start_time
);
3496 new_time_window
.start_time
= time
;
3498 page_size
= adjust
->page_size
;
3500 new_time_window
.time_width
=
3501 ltt_time_from_double(page_size
);
3503 new_time_window
.time_width_double
=
3506 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
3507 new_time_window
.time_width
);
3510 time_change_manager(tab
, new_time_window
);
3513 //time_window = tab->time_window;
3515 lower
= adjust
->lower
;
3516 upper
= adjust
->upper
;
3517 ratio
= (value
- lower
) / (upper
- lower
);
3518 g_info("lower %lu, upper %lu, value %lu, ratio %lu", lower
, upper
, value
, ratio
);
3520 //time = ltt_time_sub(time_span->end_time, time_span->start_time);
3521 //time = ltt_time_mul(time, (float)ratio);
3522 //time = ltt_time_add(time_span->start_time, time);
3523 time
= ltt_time_add(ltt_time_from_double(value
),
3524 time_span
.start_time
);
3526 time_window
.start_time
= time
;
3528 page_size
= adjust
->page_size
;
3530 time_window
.time_width
=
3531 ltt_time_from_double(page_size
);
3532 //time = ltt_time_sub(time_span.end_time, time);
3533 //if(ltt_time_compare(time,time_window.time_width) < 0){
3534 // time_window.time_width = time;
3537 /* call viewer hooks for new time window */
3538 set_time_window(tab
, &time_window
);
3544 /* Display a dialogue showing all eventtypes and traces, let user to select the interested
3545 * eventtypes, tracefiles and traces (filter)
3548 /* Select a trace which will be removed from traceset
3551 char * get_remove_trace(MainWindow
*mw_data
,
3552 char ** all_trace_name
, int nb_trace
)
3554 return get_selection(mw_data
, all_trace_name
, nb_trace
,
3555 "Select a trace", "Trace pathname");
3559 /* Select a module which will be loaded
3562 char * get_load_module(MainWindow
*mw_data
,
3563 char ** load_module_name
, int nb_module
)
3565 return get_selection(mw_data
, load_module_name
, nb_module
,
3566 "Select a module to load", "Module name");
3572 /* Select a module which will be unloaded
3575 char * get_unload_module(MainWindow
*mw_data
,
3576 char ** loaded_module_name
, int nb_module
)
3578 return get_selection(mw_data
, loaded_module_name
, nb_module
,
3579 "Select a module to unload", "Module name");
3583 /* Display a dialogue which shows all selectable items, let user to
3584 * select one of them
3587 char * get_selection(MainWindow
*mw_data
,
3588 char ** loaded_module_name
, int nb_module
,
3589 char *title
, char * column_title
)
3591 GtkWidget
* dialogue
;
3592 GtkWidget
* scroll_win
;
3594 GtkListStore
* store
;
3595 GtkTreeViewColumn
* column
;
3596 GtkCellRenderer
* renderer
;
3597 GtkTreeSelection
* select
;
3600 char * unload_module_name
= NULL
;
3602 dialogue
= gtk_dialog_new_with_buttons(title
,
3605 GTK_STOCK_OK
,GTK_RESPONSE_ACCEPT
,
3606 GTK_STOCK_CANCEL
,GTK_RESPONSE_REJECT
,
3608 gtk_window_set_default_size((GtkWindow
*)dialogue
, 500, 200);
3609 gtk_window_set_transient_for(GTK_WINDOW(dialogue
),
3610 GTK_WINDOW(mw_data
->mwindow
));
3612 scroll_win
= gtk_scrolled_window_new (NULL
, NULL
);
3613 gtk_widget_show ( scroll_win
);
3614 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll_win
),
3615 GTK_POLICY_AUTOMATIC
, GTK_POLICY_AUTOMATIC
);
3617 store
= gtk_list_store_new (N_COLUMNS
,G_TYPE_STRING
);
3618 tree
= gtk_tree_view_new_with_model(GTK_TREE_MODEL (store
));
3619 gtk_widget_show ( tree
);
3620 g_object_unref (G_OBJECT (store
));
3622 renderer
= gtk_cell_renderer_text_new ();
3623 column
= gtk_tree_view_column_new_with_attributes (column_title
,
3625 "text", MODULE_COLUMN
,
3627 gtk_tree_view_column_set_alignment (column
, 0.5);
3628 gtk_tree_view_column_set_fixed_width (column
, 150);
3629 gtk_tree_view_append_column (GTK_TREE_VIEW (tree
), column
);
3631 select
= gtk_tree_view_get_selection (GTK_TREE_VIEW (tree
));
3632 gtk_tree_selection_set_mode (select
, GTK_SELECTION_SINGLE
);
3634 gtk_container_add (GTK_CONTAINER (scroll_win
), tree
);
3636 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialogue
)->vbox
), scroll_win
,TRUE
, TRUE
,0);
3638 for(i
=0;i
<nb_module
;i
++){
3639 gtk_list_store_append (store
, &iter
);
3640 gtk_list_store_set (store
, &iter
, MODULE_COLUMN
,loaded_module_name
[i
],-1);
3643 id
= gtk_dialog_run(GTK_DIALOG(dialogue
));
3644 GtkTreeModel
**store_model
= (GtkTreeModel
**)&store
;
3646 case GTK_RESPONSE_ACCEPT
:
3647 case GTK_RESPONSE_OK
:
3648 if (gtk_tree_selection_get_selected (select
, store_model
, &iter
)){
3649 gtk_tree_model_get ((GtkTreeModel
*)store
, &iter
, MODULE_COLUMN
, &unload_module_name
, -1);
3651 case GTK_RESPONSE_REJECT
:
3652 case GTK_RESPONSE_CANCEL
:
3654 gtk_widget_destroy(dialogue
);
3658 return unload_module_name
;
3662 /* Insert all menu entry and tool buttons into this main window
3667 void add_all_menu_toolbar_constructors(MainWindow
* mw
, gpointer user_data
)
3671 lttvwindow_viewer_constructor constructor
;
3672 LttvMenus
* global_menu
, * instance_menu
;
3673 LttvToolbars
* global_toolbar
, * instance_toolbar
;
3674 LttvMenuClosure
*menu_item
;
3675 LttvToolbarClosure
*toolbar_item
;
3676 LttvAttributeValue value
;
3677 LttvIAttribute
*global_attributes
= LTTV_IATTRIBUTE(lttv_global_attributes());
3678 LttvIAttribute
*attributes
= mw
->attributes
;
3679 GtkWidget
* tool_menu_title_menu
, *new_widget
, *pixmap
;
3682 retval
= lttv_iattribute_find_by_path(global_attributes
, "viewers/menu",
3683 LTTV_POINTER
, &value
);
3685 if(*(value
.v_pointer
) == NULL
)
3686 *(value
.v_pointer
) = lttv_menus_new();
3687 global_menu
= (LttvMenus
*)*(value
.v_pointer
);
3689 retval
= lttv_iattribute_find_by_path(attributes
, "viewers/menu",
3690 LTTV_POINTER
, &value
);
3692 if(*(value
.v_pointer
) == NULL
)
3693 *(value
.v_pointer
) = lttv_menus_new();
3694 instance_menu
= (LttvMenus
*)*(value
.v_pointer
);
3696 retval
= lttv_iattribute_find_by_path(global_attributes
, "viewers/toolbar",
3697 LTTV_POINTER
, &value
);
3699 if(*(value
.v_pointer
) == NULL
)
3700 *(value
.v_pointer
) = lttv_toolbars_new();
3701 global_toolbar
= (LttvToolbars
*)*(value
.v_pointer
);
3703 retval
= lttv_iattribute_find_by_path(attributes
, "viewers/toolbar",
3704 LTTV_POINTER
, &value
);
3706 if(*(value
.v_pointer
) == NULL
)
3707 *(value
.v_pointer
) = lttv_toolbars_new();
3708 instance_toolbar
= (LttvToolbars
*)*(value
.v_pointer
);
3710 /* Add missing menu entries to window instance */
3711 for(i
=0;i
<global_menu
->len
;i
++) {
3712 menu_item
= &g_array_index(global_menu
, LttvMenuClosure
, i
);
3714 //add menu_item to window instance;
3715 constructor
= menu_item
->con
;
3716 tool_menu_title_menu
= lookup_widget(mw
->mwindow
,"ToolMenuTitle_menu");
3718 gtk_menu_item_new_with_mnemonic (menu_item
->menu_text
);
3719 gtk_container_add (GTK_CONTAINER (tool_menu_title_menu
),
3721 g_signal_connect ((gpointer
) new_widget
, "activate",
3722 G_CALLBACK (insert_viewer_wrap
),
3724 gtk_widget_show (new_widget
);
3725 lttv_menus_add(instance_menu
, menu_item
->con
,
3726 menu_item
->menu_path
,
3727 menu_item
->menu_text
,
3732 /* Add missing toolbar entries to window instance */
3733 for(i
=0;i
<global_toolbar
->len
;i
++) {
3734 toolbar_item
= &g_array_index(global_toolbar
, LttvToolbarClosure
, i
);
3736 //add toolbar_item to window instance;
3737 constructor
= toolbar_item
->con
;
3738 tool_menu_title_menu
= lookup_widget(mw
->mwindow
,"MToolbar1");
3739 pixbuf
= gdk_pixbuf_new_from_xpm_data((const char**)toolbar_item
->pixmap
);
3740 pixmap
= gtk_image_new_from_pixbuf(pixbuf
);
3742 gtk_toolbar_append_element (GTK_TOOLBAR (tool_menu_title_menu
),
3743 GTK_TOOLBAR_CHILD_BUTTON
,
3746 toolbar_item
->tooltip
, NULL
,
3747 pixmap
, NULL
, NULL
);
3748 gtk_label_set_use_underline(
3749 GTK_LABEL (((GtkToolbarChild
*) (
3750 g_list_last (GTK_TOOLBAR
3751 (tool_menu_title_menu
)->children
)->data
))->label
),
3753 gtk_container_set_border_width (GTK_CONTAINER (new_widget
), 1);
3754 g_signal_connect ((gpointer
) new_widget
,
3756 G_CALLBACK (insert_viewer_wrap
),
3758 gtk_widget_show (new_widget
);
3760 lttv_toolbars_add(instance_toolbar
, toolbar_item
->con
,
3761 toolbar_item
->tooltip
,
3762 toolbar_item
->pixmap
,
3770 /* Create a main window
3773 MainWindow
*construct_main_window(MainWindow
* parent
)
3777 g_debug("construct_main_window()");
3778 GtkWidget
* new_window
; /* New generated main window */
3779 MainWindow
* new_m_window
;/* New main window structure */
3780 GtkNotebook
* notebook
;
3781 LttvIAttribute
*attributes
=
3782 LTTV_IATTRIBUTE(g_object_new(LTTV_ATTRIBUTE_TYPE
, NULL
));
3783 LttvAttributeValue value
;
3785 new_m_window
= g_new(MainWindow
, 1);
3787 // Add the object's information to the module's array
3788 g_main_window_list
= g_slist_append(g_main_window_list
, new_m_window
);
3790 new_window
= create_MWindow();
3791 gtk_widget_show (new_window
);
3793 new_m_window
->mwindow
= new_window
;
3794 new_m_window
->attributes
= attributes
;
3796 retval
= lttv_iattribute_find_by_path(attributes
, "viewers/menu",
3797 LTTV_POINTER
, &value
);
3799 *(value
.v_pointer
) = lttv_menus_new();
3801 retval
= lttv_iattribute_find_by_path(attributes
, "viewers/toolbar",
3802 LTTV_POINTER
, &value
);
3804 *(value
.v_pointer
) = lttv_toolbars_new();
3806 add_all_menu_toolbar_constructors(new_m_window
, NULL
);
3808 g_object_set_data_full(G_OBJECT(new_window
),
3810 (gpointer
)new_m_window
,
3811 (GDestroyNotify
)g_free
);
3812 //create a default tab
3813 notebook
= (GtkNotebook
*)lookup_widget(new_m_window
->mwindow
, "MNotebook");
3814 if(notebook
== NULL
){
3815 g_info("Notebook does not exist\n");
3816 /* FIXME : destroy partially created widgets */
3817 g_free(new_m_window
);
3820 //gtk_notebook_popup_enable (GTK_NOTEBOOK(notebook));
3821 //for now there is no name field in LttvTraceset structure
3822 //Use "Traceset" as the label for the default tab
3824 GtkWidget
* parent_notebook
= lookup_widget(parent
->mwindow
, "MNotebook");
3825 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(parent_notebook
),
3826 gtk_notebook_get_current_page(GTK_NOTEBOOK(parent_notebook
)));
3832 LttvPluginTab
*ptab
;
3833 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
3834 parent_tab
= ptab
->tab
;
3836 LttvPluginTab
*ptab
= g_object_new(LTTV_TYPE_PLUGIN_TAB
, NULL
);
3838 new_m_window
, parent_tab
, notebook
, "Traceset");
3839 ptab
->parent
.top_widget
= ptab
->tab
->top_widget
;
3840 g_object_set_data_full(
3841 G_OBJECT(ptab
->tab
->vbox
),
3844 (GDestroyNotify
)tab_destructor
);
3846 LttvPluginTab
*ptab
= g_object_new(LTTV_TYPE_PLUGIN_TAB
, NULL
);
3847 init_tab(ptab
->tab
, new_m_window
, NULL
, notebook
, "Traceset");
3848 ptab
->parent
.top_widget
= ptab
->tab
->top_widget
;
3849 g_object_set_data_full(
3850 G_OBJECT(ptab
->tab
->vbox
),
3853 (GDestroyNotify
)tab_destructor
);
3856 /* Insert default viewers */
3858 LttvAttributeType type
;
3859 LttvAttributeName name
;
3860 LttvAttributeValue value
;
3861 LttvAttribute
*attribute
;
3863 LttvIAttribute
*attributes_global
=
3864 LTTV_IATTRIBUTE(lttv_global_attributes());
3866 attribute
= LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
3867 LTTV_IATTRIBUTE(attributes_global
),
3868 LTTV_VIEWER_CONSTRUCTORS
));
3869 g_assert(attribute
);
3871 name
= g_quark_from_string("guievents");
3872 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
3874 if(type
== LTTV_POINTER
) {
3875 lttvwindow_viewer_constructor viewer_constructor
=
3876 (lttvwindow_viewer_constructor
)*value
.v_pointer
;
3877 insert_viewer(new_window
, viewer_constructor
);
3880 name
= g_quark_from_string("guicontrolflow");
3881 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
3883 if(type
== LTTV_POINTER
) {
3884 lttvwindow_viewer_constructor viewer_constructor
=
3885 (lttvwindow_viewer_constructor
)*value
.v_pointer
;
3886 insert_viewer(new_window
, viewer_constructor
);
3889 name
= g_quark_from_string("guistatistics");
3890 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
3892 if(type
== LTTV_POINTER
) {
3893 lttvwindow_viewer_constructor viewer_constructor
=
3894 (lttvwindow_viewer_constructor
)*value
.v_pointer
;
3895 insert_viewer(new_window
, viewer_constructor
);
3899 g_info("There are now : %d windows\n",g_slist_length(g_main_window_list
));
3901 return new_m_window
;
3905 /* Free the memory occupied by a tab structure
3909 void tab_destructor(LttvPluginTab
* ptab
)
3911 #ifdef BABEL_CLEANUP
3912 int i
, nb
, ref_count
;
3914 Tab
*tab
= ptab
->tab
;
3917 g_object_unref(tab
->attributes
);
3919 if(tab
->interrupted_state
)
3920 g_object_unref(tab
->interrupted_state
);
3923 if(tab
->traceset_info
->traceset_context
!= NULL
){
3924 //remove state update hooks
3925 lttv_state_remove_event_hooks(
3926 (LttvTracesetState
*)tab
->traceset_info
->
3928 lttv_context_fini(LTTV_TRACESET_CONTEXT(tab
->traceset_info
->
3930 g_object_unref(tab
->traceset_info
->traceset_context
);
3932 if(tab
->traceset_info
->traceset
!= NULL
) {
3933 nb
= lttv_traceset_number(tab
->traceset_info
->traceset
);
3934 for(i
= 0 ; i
< nb
; i
++) {
3935 trace
= lttv_traceset_get(tab
->traceset_info
->traceset
, i
);
3936 ref_count
= lttv_trace_get_ref_number(trace
);
3938 ltt_trace_close(lttv_trace(trace
));
3942 lttv_traceset_destroy(tab
->traceset_info
->traceset
);
3943 /* Remove the idle events requests processing function of the tab */
3944 g_idle_remove_by_data(tab
);
3946 g_slist_free(tab
->events_requests
);
3947 g_free(tab
->traceset_info
);
3949 g_object_unref(ptab
);
3950 #endif /* BABEL_CLEANUP */
3954 /* Create a tab and insert it into the current main window
3957 void init_tab(Tab
*tab
, MainWindow
* mw
, Tab
*copy_tab
,
3958 GtkNotebook
* notebook
, char * label
)
3963 //LttvFilter *filter = NULL;
3965 //create a new tab data structure
3966 //tab = g_new(Tab,1);
3968 //construct and initialize the traceset_info
3969 tab
->traceset_info
= g_new(TracesetInfo
,1);
3972 tab
->traceset_info
->traceset
=
3973 lttv_traceset_copy(copy_tab
->traceset_info
->traceset
);
3975 /* Copy the previous tab's filter */
3976 /* We can clone the filter, as we copy the trace set also */
3977 /* The filter must always be in sync with the trace set */
3979 #ifdef BABEL_CLEANUP
3980 tab
->filter
= lttv_filter_clone(copy_tab
->filter
);
3981 #endif /* BABEL_CLEANUP */
3983 tab
->traceset_info
->traceset
= lttv_traceset_new();
3988 lttv_attribute_write_xml(
3989 lttv_traceset_attribute(tab
->traceset_info
->traceset
),
3995 tab
->time_manager_lock
= FALSE
;
3996 tab
->current_time_manager_lock
= FALSE
;
3997 #ifdef BABEL_CLEANUP
3998 //FIXME copy not implemented in lower level
3999 tab
->traceset_info
->traceset_context
=
4000 g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
4001 //add state update hooks
4002 #endif //BABEL_CLEANUP
4003 lttv_state_add_event_hooks(
4004 tab
->traceset_info
->traceset
);
4006 //determine the current_time and time_window of the tab
4008 if(copy_tab
!= NULL
){
4009 tab
->time_window
= copy_tab
->time_window
;
4010 tab
->current_time
= copy_tab
->current_time
;
4012 tab
->time_window
.start_time
=
4013 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
4014 time_span
.start_time
;
4015 if(DEFAULT_TIME_WIDTH_S
<
4016 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
4017 time_span
.end_time
.tv_sec
)
4018 tmp_time
.tv_sec
= DEFAULT_TIME_WIDTH_S
;
4021 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
4022 time_span
.end_time
.tv_sec
;
4023 tmp_time
.tv_nsec
= 0;
4024 tab
->time_window
.time_width
= tmp_time
;
4025 tab
->current_time
.tv_sec
=
4026 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
4027 time_span
.start_time
.tv_sec
;
4028 tab
->current_time
.tv_nsec
=
4029 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
4030 time_span
.start_time
.tv_nsec
;
4033 tab
->attributes
= LTTV_IATTRIBUTE(g_object_new(LTTV_ATTRIBUTE_TYPE
, NULL
));
4034 tab
->interrupted_state
= g_object_new(LTTV_ATTRIBUTE_TYPE
, NULL
);
4036 tab
->vbox
= gtk_vbox_new(FALSE
, 2);
4037 tab
->top_widget
= tab
->vbox
;
4038 //g_object_set_data_full(G_OBJECT(tab->top_widget), "filter",
4039 // filter, (GDestroyNotify)lttv_filter_destroy);
4041 // g_signal_connect (G_OBJECT(tab->top_widget),
4043 // G_CALLBACK (on_top_notify),
4046 tab
->viewer_container
= gtk_vbox_new(TRUE
, 2);
4047 tab
->scrollbar
= gtk_hscrollbar_new(NULL
);
4048 //tab->multivpaned = gtk_multi_vpaned_new();
4050 gtk_box_pack_start(GTK_BOX(tab
->vbox
),
4051 tab
->viewer_container
,
4053 TRUE
, /* Give the extra space to the child */
4054 0); /* No padding */
4057 // tab->time_window = copy_tab->time_window;
4058 // tab->current_time = copy_tab->current_time;
4061 /* Create the timebar */
4063 tab
->MTimebar
= timebar_new();
4065 gtk_box_pack_end(GTK_BOX(tab
->vbox
),
4067 FALSE
, /* Do not expand */
4068 FALSE
, /* Fill has no effect here (expand false) */
4069 0); /* No padding */
4071 gtk_box_pack_end(GTK_BOX(tab
->vbox
),
4073 FALSE
, /* Do not expand */
4074 FALSE
, /* Fill has no effect here (expand false) */
4075 0); /* No padding */
4077 g_object_set_data(G_OBJECT(tab
->viewer_container
), "focused_viewer", NULL
);
4083 // Display a label with a X
4084 GtkWidget *w_hbox = gtk_hbox_new(FALSE, 4);
4085 GtkWidget *w_label = gtk_label_new (label);
4086 GtkWidget *pixmap = create_pixmap(GTK_WIDGET(notebook), "close.png");
4087 GtkWidget *w_button = gtk_button_new ();
4088 gtk_container_add(GTK_CONTAINER(w_button), pixmap);
4089 //GtkWidget *w_button = gtk_button_new_with_label("x");
4091 gtk_button_set_relief(GTK_BUTTON(w_button), GTK_RELIEF_NONE);
4093 gtk_box_pack_start(GTK_BOX(w_hbox), w_label, TRUE, TRUE, 0);
4094 gtk_box_pack_end(GTK_BOX(w_hbox), w_button, FALSE,
4097 g_signal_connect_swapped (w_button, "clicked",
4098 G_CALLBACK (on_close_tab_X_clicked),
4101 gtk_widget_set_state(w_button, GTK_STATE_ACTIVE);
4103 gtk_widget_show (w_label);
4104 gtk_widget_show (pixmap);
4105 gtk_widget_show (w_button);
4106 gtk_widget_show (w_hbox);
4108 tab->label = w_hbox;
4112 tab
->label
= gtk_label_new (label
);
4114 gtk_widget_show(tab
->label
);
4115 gtk_widget_show(tab
->scrollbar
);
4116 gtk_widget_show(tab
->MTimebar
);
4117 gtk_widget_show(tab
->viewer_container
);
4118 gtk_widget_show(tab
->vbox
);
4120 //gtk_widget_show(tab->multivpaned);
4123 /* Start with empty events requests list */
4124 tab
->events_requests
= NULL
;
4125 tab
->events_request_pending
= FALSE
;
4126 tab
->stop_foreground
= FALSE
;
4130 g_signal_connect(G_OBJECT(tab
->scrollbar
), "value-changed",
4131 G_CALLBACK(scroll_value_changed_cb
), tab
);
4134 /* Timebar signal handler */
4135 g_signal_connect(G_OBJECT(tab
->MTimebar
), "start-time-changed",
4136 G_CALLBACK(on_timebar_starttime_changed
), tab
);
4137 g_signal_connect(G_OBJECT(tab
->MTimebar
), "end-time-changed",
4138 G_CALLBACK(on_timebar_endtime_changed
), tab
);
4139 g_signal_connect(G_OBJECT(tab
->MTimebar
), "current-time-changed",
4140 G_CALLBACK(on_timebar_currenttime_changed
), tab
);
4142 //g_signal_connect(G_OBJECT(tab->scrollbar), "changed",
4143 // G_CALLBACK(scroll_value_changed_cb), tab);
4146 //insert tab into notebook
4147 gtk_notebook_append_page(notebook
,
4150 list
= gtk_container_get_children(GTK_CONTAINER(notebook
));
4151 gtk_notebook_set_current_page(notebook
,g_list_length(list
)-1);
4152 // always show : not if(g_list_length(list)>1)
4153 gtk_notebook_set_show_tabs(notebook
, TRUE
);
4156 lttvwindow_report_time_window(tab
, copy_tab
->time_window
);
4157 lttvwindow_report_current_time(tab
, copy_tab
->current_time
);
4159 TimeWindow time_window
;
4161 time_window
.start_time
= ltt_time_zero
;
4162 time_window
.end_time
= ltt_time_add(time_window
.start_time
,
4163 lttvwindow_default_time_width
);
4164 time_window
.time_width
= lttvwindow_default_time_width
;
4165 time_window
.time_width_double
= ltt_time_to_double(time_window
.time_width
);
4167 lttvwindow_report_time_window(tab
, time_window
);
4168 lttvwindow_report_current_time(tab
, ltt_time_zero
);
4171 LttvTraceset
*traceset
= tab
->traceset_info
->traceset
;
4172 SetTraceset(tab
, traceset
);
4176 * execute_events_requests
4178 * Idle function that executes the pending requests for a tab.
4180 * @return return value : TRUE : keep the idle function, FALSE : remove it.
4182 gboolean
execute_events_requests(Tab
*tab
)
4184 return ( lttvwindow_process_pending_requests(tab
) );
4188 __EXPORT
void create_main_window_with_trace_list(GSList
*traces
)
4191 GSList
*iter
= NULL
;
4194 MainWindow
*mw
= construct_main_window(NULL
);
4195 GtkWidget
*widget
= mw
->mwindow
;
4197 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
4198 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
4199 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
4200 LttvPluginTab
*ptab
;
4204 ptab
= create_new_tab(widget
, NULL
);
4207 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
4211 LttvTraceset
* traceset
= lttv_traceset_new();
4212 for(iter
=traces
; iter
!=NULL
; iter
=g_slist_next(iter
)) {
4213 gchar
*path
= (gchar
*)iter
->data
;
4215 gchar abs_path
[PATH_MAX
];
4218 get_absolute_pathname(path
, abs_path
);
4220 if(lttv_traceset_add_path(traceset
,abs_path
) != 0 ){ /*failure*/
4222 g_warning("cannot open trace %s", abs_path
);
4224 GtkWidget
*dialogue
=
4225 gtk_message_dialog_new(
4226 GTK_WINDOW(gtk_widget_get_toplevel(widget
)),
4227 GTK_DIALOG_MODAL
|GTK_DIALOG_DESTROY_WITH_PARENT
,
4230 "Cannot open trace : maybe you should enter in the directory "
4232 gtk_dialog_run(GTK_DIALOG(dialogue
));
4233 gtk_widget_destroy(dialogue
);
4236 SetTraceset(tab
, traceset
);