1 /* This file is part of the Linux Trace Toolkit viewer
2 * Copyright (C) 2003-2004 XangXiu Yang, Mathieu Desnoyers
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License Version 2 as
6 * published by the Free Software Foundation;
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place - Suite 330, Boston,
23 #include <limits.h> // for PATH_MAX
31 #include "callbacks.h"
32 #include "interface.h"
34 #include <ltt/trace.h>
36 #include <ltt/event.h>
37 #include <lttv/lttv.h>
38 #include <lttv/module.h>
39 #include <lttv/iattribute.h>
40 #include <lttv/traceset.h>
42 #include <lttv/stats.h>
43 #include <lttv/sync/sync_chain_lttv.h>
44 #endif /* BABEL_CLEANUP */
45 #include <lttv/filter.h>
46 #include <lttvwindow/mainwindow.h>
47 #include <lttvwindow/mainwindow-private.h>
48 #include <lttvwindow/menu.h>
49 #include <lttvwindow/timebar.h>
50 #include <lttvwindow/toolbar.h>
51 #include <lttvwindow/lttvwindow.h>
52 #include <lttvwindow/lttvwindowtraces.h>
53 #include <lttvwindow/lttv_plugin_tab.h>
55 #include <babeltrace/babeltrace.h>
56 #include <babeltrace/ctf/events.h>
57 #include <babeltrace/ctf/iterator.h>
59 static LttTime lttvwindow_default_time_width
= { 1, 0 };
60 #define CLIP_BUF 256 // size of clipboard buffer
62 extern LttvTrace
*g_init_trace
;
65 /** Array containing instanced objects. */
66 extern GSList
* g_main_window_list
;
68 /** MD : keep old directory. */
69 static char remember_plugins_dir
[PATH_MAX
] = "";
70 static char remember_trace_dir
[PATH_MAX
] = "";
72 void tab_destructor(LttvPluginTab
* ptab
);
74 MainWindow
* get_window_data_struct(GtkWidget
* widget
);
75 char * get_load_module(MainWindow
*mw
,
76 char ** load_module_name
, int nb_module
);
77 char * get_unload_module(MainWindow
*mw
,
78 char ** loaded_module_name
, int nb_module
);
79 char * get_remove_trace(MainWindow
*mw
, char ** all_trace_name
, int nb_trace
);
80 char * get_selection(MainWindow
*mw
,
81 char ** all_name
, int nb
, char *title
, char * column_title
);
82 void init_tab(Tab
*tab
, MainWindow
* mw
, Tab
*copy_tab
,
83 GtkNotebook
* notebook
, char * label
);
85 int update_traceset(Tab
*tab
, LttvTraceset
*traceset
);
87 static void insert_viewer(GtkWidget
* widget
, lttvwindow_viewer_constructor constructor
);
89 LttvPluginTab
*create_new_tab(GtkWidget
* widget
, gpointer user_data
);
91 static gboolean
lttvwindow_process_pending_requests(Tab
*tab
);
93 static void on_timebar_starttime_changed(Timebar
*timebar
,
95 static void on_timebar_endtime_changed(Timebar
*timebar
,
97 static void on_timebar_currenttime_changed(Timebar
*timebar
,
114 static void on_top_notify(GObject
*gobject
,
118 Tab
*tab
= (Tab
*)user_data
;
119 g_message("in on_top_notify.\n");
123 static gboolean
viewer_grab_focus(GtkWidget
*widget
, GdkEventButton
*event
,
126 GtkWidget
*viewer
= GTK_WIDGET(data
);
127 GtkWidget
*viewer_container
= gtk_widget_get_parent(viewer
);
129 g_debug("FOCUS GRABBED");
130 g_object_set_data(G_OBJECT(viewer_container
), "focused_viewer", viewer
);
135 static void connect_focus_recursive(GtkWidget
*widget
,
138 if(GTK_IS_CONTAINER(widget
)) {
139 gtk_container_forall(GTK_CONTAINER(widget
),
140 (GtkCallback
)connect_focus_recursive
,
144 if(GTK_IS_TREE_VIEW(widget
)) {
145 gtk_tree_view_set_headers_clickable(GTK_TREE_VIEW(widget
), TRUE
);
147 gtk_widget_add_events(widget
, GDK_BUTTON_PRESS_MASK
);
148 g_signal_connect (G_OBJECT(widget
),
149 "button-press-event",
150 G_CALLBACK (viewer_grab_focus
),
154 /* Stop all the processings and call gtk_main_quit() */
155 static void mainwindow_quit()
157 lttvwindowtraces_unregister_requests(g_quark_from_string("stats"));
158 lttvwindowtraces_unregister_requests(g_quark_from_string("state"));
159 lttvwindowtraces_unregister_computation_hooks(g_quark_from_string("stats"));
160 lttvwindowtraces_unregister_computation_hooks(g_quark_from_string("state"));
166 /* insert_viewer function constructs an instance of a viewer first,
167 * then inserts the widget of the instance into the container of the
172 insert_viewer_wrap(GtkWidget
*menuitem
, gpointer user_data
)
174 insert_viewer((GtkWidget
*)menuitem
, (lttvwindow_viewer_constructor
)user_data
);
178 /* internal functions */
179 void insert_viewer(GtkWidget
* widget
, lttvwindow_viewer_constructor constructor
)
181 GtkWidget
* viewer_container
;
182 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
184 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
185 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
190 ptab
= create_new_tab(widget
, NULL
);
192 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
196 viewer_container
= tab
->viewer_container
;
198 viewer
= (GtkWidget
*)constructor(&ptab
->parent
);
201 //gtk_multivpaned_widget_add(GTK_MULTIVPANED(multivpaned), viewer);
203 gtk_box_pack_end(GTK_BOX(viewer_container
),
209 /* We want to connect the viewer_grab_focus to EVERY
210 * child of this widget. The little trick is to get each child
211 * of each GTK_CONTAINER, even subchildren.
213 connect_focus_recursive(viewer
, viewer
);
218 * Function to set/update traceset for the viewers
219 * @param tab viewer's tab
220 * @param traceset traceset of the main window.
222 * 0 : traceset updated
223 * 1 : no traceset hooks to update; not an error.
226 int SetTraceset(Tab
* tab
, LttvTraceset
*traceset
)
230 TimeInterval time_span
;
231 TimeWindow new_time_window
;
232 LttTime new_current_time
;
235 // Perform time synchronization on the traces
236 if (syncTraceset(tsc
))
238 /* There is some time-dependant information that was calculated during
239 * context initialization. Destroy the old contexts and initialize new
241 * Modified from lttvwindow_add_trace()
243 // Keep a reference to the traces so they are not freed
244 for(i
= 0; i
< lttv_traceset_number(traceset
); i
++)
246 LttvTrace
*trace
= lttv_traceset_get(traceset
, i
);
247 lttv_trace_ref(trace
);
250 // Remove state update hooks
251 lttv_state_remove_event_hooks(
252 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
254 lttv_context_fini(LTTV_TRACESET_CONTEXT(
255 tab
->traceset_info
->traceset_context
));
256 g_object_unref(tab
->traceset_info
->traceset_context
);
258 for(i
= 0; i
< lttv_traceset_number(traceset
); i
++)
260 LttvTrace
*trace
= lttv_traceset_get(traceset
, i
);
261 lttvwindowtraces_remove_trace(trace
);
262 lttvwindowtraces_add_trace(trace
);
265 // Create new context
266 tab
->traceset_info
->traceset_context
=
267 g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
268 lttv_context_init(LTTV_TRACESET_CONTEXT(tab
->traceset_info
->
269 traceset_context
), traceset
);
271 // Add state update hooks
272 lttv_state_add_event_hooks(
273 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
275 // Remove local reference to the traces
276 for(i
=0; i
<lttv_traceset_number(traceset
); i
++)
278 LttvTrace
*trace
= lttv_traceset_get(traceset
, i
);
279 lttv_trace_unref(trace
);
282 tsc
= LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
284 #endif /*BABEL_CLEANUP*/
286 time_span
= lttv_traceset_get_time_span(traceset
);
288 tab
->traceset_info
->traceset
= traceset
;
290 new_time_window
= tab
->time_window
;
291 new_current_time
= tab
->current_time
;
293 /* Set the tab's time window and current time if
295 if(ltt_time_compare(tab
->time_window
.start_time
, time_span
.start_time
) < 0
296 || ltt_time_compare(tab
->time_window
.end_time
,
297 time_span
.end_time
) > 0) {
298 new_time_window
.start_time
= time_span
.start_time
;
300 new_current_time
= time_span
.start_time
;
304 if(ltt_time_compare(lttvwindow_default_time_width
,
305 ltt_time_sub(time_span
.end_time
, time_span
.start_time
)) < 0
307 ltt_time_compare(time_span
.end_time
, time_span
.start_time
) == 0)
308 tmp_time
= lttvwindow_default_time_width
;
310 tmp_time
= time_span
.end_time
;
312 new_time_window
.time_width
= tmp_time
;
313 new_time_window
.time_width_double
= ltt_time_to_double(tmp_time
);
314 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
315 new_time_window
.time_width
) ;
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
)
714 LttvTracesetContext
*tsc
;
715 LttvTracefileContext
*tfc
;
716 GSList
*list_in
= NULL
;
720 LttvTracesetContextPosition
*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 tsc
= LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
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(tsc
->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
)tsc
);
764 /* - remove req from list_out */
765 /* Destroy the request */
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(tsc
->ts
);
790 LttvTrace
*trace_v
= lttv_traceset_get(tsc
->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 */
800 //g_assert(lttv_process_traceset_seek_position(tsc, sync_position) == 0);
801 lttv_process_traceset_synchronize_tracefiles(tsc
);
804 /* Events processing algorithm implementation */
805 /* Warning : the gtk_events_pending takes a LOT of cpu time. So what we do
806 * instead is to leave the control to GTK and take it back.
808 /* A. Servicing loop */
809 //while( (g_slist_length(list_in) != 0 || g_slist_length(list_out) != 0)) {
810 if((g_slist_length(list_in
) != 0 || g_slist_length(list_out
) != 0)) {
812 /* 1. If list_in is empty (need a seek) */
813 if( g_slist_length(list_in
) == 0 ) {
815 /* list in is empty, need a seek */
817 /* 1.1 Add requests to list_in */
818 GSList
*ltime
= NULL
;
822 /* 1.1.1 Find all time requests with the lowest start time in list_out
825 if(g_slist_length(list_out
) > 0)
826 ltime
= g_slist_append(ltime
, g_slist_nth_data(list_out
, 0));
827 for(iter
=g_slist_nth(list_out
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
828 /* Find all time requests with the lowest start time in list_out */
829 EventsRequest
*event_request_ltime
= (EventsRequest
*)g_slist_nth_data(ltime
, 0);
830 EventsRequest
*event_request_list_out
= (EventsRequest
*)iter
->data
;
833 comp
= ltt_time_compare(event_request_ltime
->start_time
,
834 event_request_list_out
->start_time
);
836 ltime
= g_slist_append(ltime
, event_request_list_out
);
838 /* Remove all elements from ltime, and add current */
840 ltime
= g_slist_delete_link(ltime
, g_slist_nth(ltime
, 0));
841 ltime
= g_slist_append(ltime
, event_request_list_out
);
845 /* 1.1.2 Find all position requests with the lowest position in list_out
848 if(g_slist_length(list_out
) > 0)
849 lpos
= g_slist_append(lpos
, g_slist_nth_data(list_out
, 0));
850 for(iter
=g_slist_nth(list_out
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
851 /* Find all position requests with the lowest position in list_out */
852 EventsRequest
*event_request_lpos
= (EventsRequest
*)g_slist_nth_data(lpos
, 0);
853 EventsRequest
*event_request_list_out
= (EventsRequest
*)iter
->data
;
856 if(event_request_lpos
->start_position
!= NULL
857 && event_request_list_out
->start_position
!= NULL
)
859 comp
= lttv_traceset_context_pos_pos_compare
860 (event_request_lpos
->start_position
,
861 event_request_list_out
->start_position
);
866 lpos
= g_slist_append(lpos
, event_request_list_out
);
868 /* Remove all elements from lpos, and add current */
870 lpos
= g_slist_delete_link(lpos
, g_slist_nth(lpos
, 0));
871 lpos
= g_slist_append(lpos
, event_request_list_out
);
876 EventsRequest
*event_request_lpos
= (EventsRequest
*)g_slist_nth_data(lpos
, 0);
877 EventsRequest
*event_request_ltime
= (EventsRequest
*)g_slist_nth_data(ltime
, 0);
878 LttTime lpos_start_time
;
880 if(event_request_lpos
!= NULL
881 && event_request_lpos
->start_position
!= NULL
) {
882 lpos_start_time
= lttv_traceset_context_position_get_time(
883 event_request_lpos
->start_position
);
886 /* 1.1.3 If lpos.start time < ltime */
887 if(event_request_lpos
!= NULL
888 && event_request_lpos
->start_position
!= NULL
889 && ltt_time_compare(lpos_start_time
,
890 event_request_ltime
->start_time
)<0) {
891 /* Add lpos to list_in, remove them from list_out */
892 for(iter
=lpos
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
894 EventsRequest
*event_request_lpos
=
895 (EventsRequest
*)iter
->data
;
897 list_in
= g_slist_append(list_in
, event_request_lpos
);
898 /* Remove from list_out */
899 list_out
= g_slist_remove(list_out
, event_request_lpos
);
902 /* 1.1.4 (lpos.start time >= ltime) */
903 /* Add ltime to list_in, remove them from list_out */
905 for(iter
=ltime
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
907 EventsRequest
*event_request_ltime
=
908 (EventsRequest
*)iter
->data
;
910 list_in
= g_slist_append(list_in
, event_request_ltime
);
911 /* Remove from list_out */
912 list_out
= g_slist_remove(list_out
, event_request_ltime
);
922 tfc
= lttv_traceset_context_get_current_tfc(tsc
);
923 g_assert(g_slist_length(list_in
)>0);
924 EventsRequest
*events_request
= g_slist_nth_data(list_in
, 0);
929 /* 1.2.1 If first request in list_in is a time request */
930 if(events_request
->start_position
== NULL
) {
931 /* - If first req in list_in start time != current time */
932 if(tfc
== NULL
|| ltt_time_compare(events_request
->start_time
,
933 tfc
->timestamp
) != 0)
934 /* - Seek to that time */
935 g_debug("SEEK TIME : %lu, %lu", events_request
->start_time
.tv_sec
,
936 events_request
->start_time
.tv_nsec
);
937 //lttv_process_traceset_seek_time(tsc, events_request->start_time);
938 lttv_state_traceset_seek_time_closest(LTTV_TRACESET_STATE(tsc
),
939 events_request
->start_time
);
941 /* Process the traceset with only state hooks */
945 lttv_process_traceset_middle(tsc
,
946 events_request
->start_time
,
949 g_assert(seek_count
< LTTV_STATE_SAVE_INTERVAL
);
955 LttvTracefileContext
*tfc
=
956 lttv_traceset_context_get_current_tfc(tsc
);
957 /* Else, the first request in list_in is a position request */
958 /* If first req in list_in pos != current pos */
959 g_assert(events_request
->start_position
!= NULL
);
960 g_debug("SEEK POS time : %lu, %lu",
961 lttv_traceset_context_position_get_time(
962 events_request
->start_position
).tv_sec
,
963 lttv_traceset_context_position_get_time(
964 events_request
->start_position
).tv_nsec
);
967 g_debug("SEEK POS context time : %lu, %lu",
968 tfc
->timestamp
.tv_sec
,
969 tfc
->timestamp
.tv_nsec
);
971 g_debug("SEEK POS context time : %lu, %lu",
972 ltt_time_infinite
.tv_sec
,
973 ltt_time_infinite
.tv_nsec
);
975 g_assert(events_request
->start_position
!= NULL
);
976 if(lttv_traceset_context_ctx_pos_compare(tsc
,
977 events_request
->start_position
) != 0) {
978 /* 1.2.2.1 Seek to that position */
979 g_debug("SEEK POSITION");
980 //lttv_process_traceset_seek_position(tsc, events_request->start_position);
981 pos_time
= lttv_traceset_context_position_get_time(
982 events_request
->start_position
);
984 lttv_state_traceset_seek_time_closest(LTTV_TRACESET_STATE(tsc
),
987 /* Process the traceset with only state hooks */
991 lttv_process_traceset_middle(tsc
,
994 events_request
->start_position
);
995 g_assert(lttv_traceset_context_ctx_pos_compare(tsc
,
996 events_request
->start_position
) == 0);
1003 /* 1.3 Add hooks and call before request for all list_in members */
1005 GSList
*iter
= NULL
;
1007 for(iter
=list_in
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
1008 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1009 /* 1.3.1 If !servicing */
1010 if(events_request
->servicing
== FALSE
) {
1011 /* - begin request hooks called
1012 * - servicing = TRUE
1014 lttv_hooks_call(events_request
->before_request
, (gpointer
)tsc
);
1015 events_request
->servicing
= TRUE
;
1017 /* 1.3.2 call before chunk
1018 * 1.3.3 events hooks added
1020 if(events_request
->trace
== -1)
1021 lttv_process_traceset_begin(tsc
,
1022 events_request
->before_chunk_traceset
,
1023 events_request
->before_chunk_trace
,
1024 events_request
->before_chunk_tracefile
,
1025 events_request
->event
,
1026 events_request
->event_by_id_channel
);
1028 guint nb_trace
= lttv_traceset_number(tsc
->ts
);
1029 g_assert((guint
)events_request
->trace
< nb_trace
&&
1030 events_request
->trace
> -1);
1031 LttvTraceContext
*tc
= tsc
->traces
[events_request
->trace
];
1033 lttv_hooks_call(events_request
->before_chunk_traceset
, tsc
);
1035 lttv_trace_context_add_hooks(tc
,
1036 events_request
->before_chunk_trace
,
1037 events_request
->before_chunk_tracefile
,
1038 events_request
->event
,
1039 events_request
->event_by_id_channel
);
1044 /* 2. Else, list_in is not empty, we continue a read */
1047 /* 2.0 For each req of list_in */
1048 GSList
*iter
= list_in
;
1050 while(iter
!= NULL
) {
1052 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1054 /* - Call before chunk
1055 * - events hooks added
1057 if(events_request
->trace
== -1)
1058 lttv_process_traceset_begin(tsc
,
1059 events_request
->before_chunk_traceset
,
1060 events_request
->before_chunk_trace
,
1061 events_request
->before_chunk_tracefile
,
1062 events_request
->event
,
1063 events_request
->event_by_id_channel
);
1065 guint nb_trace
= lttv_traceset_number(tsc
->ts
);
1066 g_assert((guint
)events_request
->trace
< nb_trace
&&
1067 events_request
->trace
> -1);
1068 LttvTraceContext
*tc
= tsc
->traces
[events_request
->trace
];
1070 lttv_hooks_call(events_request
->before_chunk_traceset
, tsc
);
1072 lttv_trace_context_add_hooks(tc
,
1073 events_request
->before_chunk_trace
,
1074 events_request
->before_chunk_tracefile
,
1075 events_request
->event
,
1076 events_request
->event_by_id_channel
);
1079 iter
= g_slist_next(iter
);
1084 tfc
= lttv_traceset_context_get_current_tfc(tsc
);
1086 /* 2.1 For each req of list_out */
1087 GSList
*iter
= list_out
;
1089 while(iter
!= NULL
) {
1091 gboolean remove
= FALSE
;
1092 gboolean free_data
= FALSE
;
1093 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1095 /* if req.start time == current context time
1096 * or req.start position == current position*/
1097 if( ltt_time_compare(events_request
->start_time
,
1098 tfc
->timestamp
) == 0
1100 (events_request
->start_position
!= NULL
1102 lttv_traceset_context_ctx_pos_compare(tsc
,
1103 events_request
->start_position
) == 0)
1105 /* - Add to list_in, remove from list_out */
1106 list_in
= g_slist_append(list_in
, events_request
);
1110 /* - If !servicing */
1111 if(events_request
->servicing
== FALSE
) {
1112 /* - begin request hooks called
1113 * - servicing = TRUE
1115 lttv_hooks_call(events_request
->before_request
, (gpointer
)tsc
);
1116 events_request
->servicing
= TRUE
;
1118 /* call before chunk
1119 * events hooks added
1121 if(events_request
->trace
== -1)
1122 lttv_process_traceset_begin(tsc
,
1123 events_request
->before_chunk_traceset
,
1124 events_request
->before_chunk_trace
,
1125 events_request
->before_chunk_tracefile
,
1126 events_request
->event
,
1127 events_request
->event_by_id_channel
);
1129 guint nb_trace
= lttv_traceset_number(tsc
->ts
);
1130 g_assert((guint
)events_request
->trace
< nb_trace
&&
1131 events_request
->trace
> -1);
1132 LttvTraceContext
*tc
= tsc
->traces
[events_request
->trace
];
1134 lttv_hooks_call(events_request
->before_chunk_traceset
, tsc
);
1136 lttv_trace_context_add_hooks(tc
,
1137 events_request
->before_chunk_trace
,
1138 events_request
->before_chunk_tracefile
,
1139 events_request
->event
,
1140 events_request
->event_by_id_channel
);
1149 GSList
*remove_iter
= iter
;
1151 iter
= g_slist_next(iter
);
1152 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
1153 list_out
= g_slist_remove_link(list_out
, remove_iter
);
1154 } else { // not remove
1155 iter
= g_slist_next(iter
);
1161 /* 3. Find end criterions */
1166 /* 3.1.1 Find lowest end time in list_in */
1167 g_assert(g_slist_length(list_in
)>0);
1168 end_time
= ((EventsRequest
*)g_slist_nth_data(list_in
,0))->end_time
;
1170 for(iter
=g_slist_nth(list_in
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
1171 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1173 if(ltt_time_compare(events_request
->end_time
,
1175 end_time
= events_request
->end_time
;
1178 /* 3.1.2 Find lowest start time in list_out */
1179 for(iter
=list_out
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
1180 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1182 if(ltt_time_compare(events_request
->start_time
,
1184 end_time
= events_request
->start_time
;
1189 /* 3.2 Number of events */
1191 /* 3.2.1 Find lowest number of events in list_in */
1194 end_nb_events
= ((EventsRequest
*)g_slist_nth_data(list_in
,0))->num_events
;
1196 for(iter
=g_slist_nth(list_in
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
1197 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1199 if(events_request
->num_events
< end_nb_events
)
1200 end_nb_events
= events_request
->num_events
;
1203 /* 3.2.2 Use min(CHUNK_NUM_EVENTS, min num events in list_in) as
1206 end_nb_events
= MIN(CHUNK_NUM_EVENTS
, end_nb_events
);
1210 /* 3.3 End position */
1212 /* 3.3.1 Find lowest end position in list_in */
1215 end_position
=((EventsRequest
*)g_slist_nth_data(list_in
,0))->end_position
;
1217 for(iter
=g_slist_nth(list_in
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
1218 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1220 if(events_request
->end_position
!= NULL
&& end_position
!= NULL
&&
1221 lttv_traceset_context_pos_pos_compare(events_request
->end_position
,
1223 end_position
= events_request
->end_position
;
1228 /* 3.3.2 Find lowest start position in list_out */
1231 for(iter
=list_out
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
1232 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1234 if(events_request
->end_position
!= NULL
&& end_position
!= NULL
&&
1235 lttv_traceset_context_pos_pos_compare(events_request
->end_position
,
1237 end_position
= events_request
->end_position
;
1242 /* 4. Call process traceset middle */
1243 g_debug("Calling process traceset middle with %p, %lu sec %lu nsec, %u nb ev, %p end pos", tsc
, end_time
.tv_sec
, end_time
.tv_nsec
, end_nb_events
, end_position
);
1244 count
= lttv_process_traceset_middle(tsc
, end_time
, end_nb_events
, end_position
);
1246 tfc
= lttv_traceset_context_get_current_tfc(tsc
);
1248 g_debug("Context time after middle : %lu, %lu", tfc
->timestamp
.tv_sec
,
1249 tfc
->timestamp
.tv_nsec
);
1251 g_debug("End of trace reached after middle.");
1255 /* 5. After process traceset middle */
1256 tfc
= lttv_traceset_context_get_current_tfc(tsc
);
1258 /* - if current context time > traceset.end time */
1259 if(tfc
== NULL
|| ltt_time_compare(tfc
->timestamp
,
1260 tsc
->time_span
.end_time
) > 0) {
1261 /* - For each req in list_in */
1262 GSList
*iter
= list_in
;
1264 while(iter
!= NULL
) {
1266 gboolean remove
= FALSE
;
1267 gboolean free_data
= FALSE
;
1268 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1270 /* - Remove events hooks for req
1271 * - Call end chunk for req
1274 if(events_request
->trace
== -1)
1275 lttv_process_traceset_end(tsc
,
1276 events_request
->after_chunk_traceset
,
1277 events_request
->after_chunk_trace
,
1278 events_request
->after_chunk_tracefile
,
1279 events_request
->event
,
1280 events_request
->event_by_id_channel
);
1283 guint nb_trace
= lttv_traceset_number(tsc
->ts
);
1284 g_assert(events_request
->trace
< nb_trace
&&
1285 events_request
->trace
> -1);
1286 LttvTraceContext
*tc
= tsc
->traces
[events_request
->trace
];
1288 lttv_trace_context_remove_hooks(tc
,
1289 events_request
->after_chunk_trace
,
1290 events_request
->after_chunk_tracefile
,
1291 events_request
->event
,
1292 events_request
->event_by_id_channel
);
1293 lttv_hooks_call(events_request
->after_chunk_traceset
, tsc
);
1298 /* - Call end request for req */
1299 lttv_hooks_call(events_request
->after_request
, (gpointer
)tsc
);
1301 /* - remove req from list_in */
1302 /* Destroy the request */
1309 GSList
*remove_iter
= iter
;
1311 iter
= g_slist_next(iter
);
1312 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
1313 list_in
= g_slist_remove_link(list_in
, remove_iter
);
1314 } else { // not remove
1315 iter
= g_slist_next(iter
);
1320 /* 5.1 For each req in list_in */
1321 GSList
*iter
= list_in
;
1323 while(iter
!= NULL
) {
1325 gboolean remove
= FALSE
;
1326 gboolean free_data
= FALSE
;
1327 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1329 /* - Remove events hooks for req
1330 * - Call end chunk for req
1332 if(events_request
->trace
== -1)
1333 lttv_process_traceset_end(tsc
,
1334 events_request
->after_chunk_traceset
,
1335 events_request
->after_chunk_trace
,
1336 events_request
->after_chunk_tracefile
,
1337 events_request
->event
,
1338 events_request
->event_by_id_channel
);
1341 guint nb_trace
= lttv_traceset_number(tsc
->ts
);
1342 g_assert(events_request
->trace
< nb_trace
&&
1343 events_request
->trace
> -1);
1344 LttvTraceContext
*tc
= tsc
->traces
[events_request
->trace
];
1346 lttv_trace_context_remove_hooks(tc
,
1347 events_request
->after_chunk_trace
,
1348 events_request
->after_chunk_tracefile
,
1349 events_request
->event
,
1350 events_request
->event_by_id_channel
);
1352 lttv_hooks_call(events_request
->after_chunk_traceset
, tsc
);
1355 /* - req.num -= count */
1356 g_assert(events_request
->num_events
>= count
);
1357 events_request
->num_events
-= count
;
1359 g_assert(tfc
!= NULL
);
1360 /* - if req.num == 0
1362 * current context time >= req.end time
1364 * req.end pos == current pos
1366 * req.stop_flag == TRUE
1368 if( events_request
->num_events
== 0
1370 events_request
->stop_flag
== TRUE
1372 ltt_time_compare(tfc
->timestamp
,
1373 events_request
->end_time
) >= 0
1375 (events_request
->end_position
!= NULL
1377 lttv_traceset_context_ctx_pos_compare(tsc
,
1378 events_request
->end_position
) == 0)
1381 g_assert(events_request
->servicing
== TRUE
);
1382 /* - Call end request for req
1383 * - remove req from list_in */
1384 lttv_hooks_call(events_request
->after_request
, (gpointer
)tsc
);
1385 /* - remove req from list_in */
1386 /* Destroy the request */
1394 GSList
*remove_iter
= iter
;
1396 iter
= g_slist_next(iter
);
1397 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
1398 list_in
= g_slist_remove_link(list_in
, remove_iter
);
1399 } else { // not remove
1400 iter
= g_slist_next(iter
);
1406 /* End of removed servicing loop : leave control to GTK instead. */
1407 // if(gtk_events_pending()) break;
1410 /* B. When interrupted between chunks */
1413 GSList
*iter
= list_in
;
1415 /* 1. for each request in list_in */
1416 while(iter
!= NULL
) {
1418 gboolean remove
= FALSE
;
1419 gboolean free_data
= FALSE
;
1420 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1422 /* 1.1. Use current postition as start position */
1423 if(events_request
->start_position
!= NULL
)
1424 lttv_traceset_context_position_destroy(events_request
->start_position
);
1425 events_request
->start_position
= lttv_traceset_context_position_new(tsc
);
1426 lttv_traceset_context_position_save(tsc
, events_request
->start_position
);
1428 /* 1.2. Remove start time */
1429 events_request
->start_time
= ltt_time_infinite
;
1431 /* 1.3. Move from list_in to list_out */
1434 list_out
= g_slist_append(list_out
, events_request
);
1439 GSList
*remove_iter
= iter
;
1441 iter
= g_slist_next(iter
);
1442 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
1443 list_in
= g_slist_remove_link(list_in
, remove_iter
);
1444 } else { // not remove
1445 iter
= g_slist_next(iter
);
1451 /* C Unlock Traces */
1453 lttv_process_traceset_get_sync_data(tsc
);
1454 //lttv_traceset_context_position_save(tsc, sync_position);
1459 iter_trace
<lttv_traceset_number(tsc
->ts
);
1461 LttvTrace
*trace_v
= lttv_traceset_get(tsc
->ts
, iter_trace
);
1463 lttvwindowtraces_unlock(trace_v
);
1467 //set the cursor back to normal
1468 gdk_window_set_cursor(win
, NULL
);
1471 g_assert(g_slist_length(list_in
) == 0);
1473 if( g_slist_length(list_out
) == 0 ) {
1474 /* Put tab's request pending flag back to normal */
1475 tab
->events_request_pending
= FALSE
;
1476 g_debug("remove the idle fct");
1477 return FALSE
; /* Remove the idle function */
1479 g_debug("leave the idle fct");
1480 return TRUE
; /* Leave the idle function */
1482 /* We do not use simili-round-robin, it may require to read 1 meg buffers
1483 * again and again if many tracesets use the same tracefiles. */
1484 /* Hack for round-robin idle functions */
1485 /* It will put the idle function at the end of the pool */
1486 /*g_idle_add_full((G_PRIORITY_HIGH_IDLE + 21),
1487 (GSourceFunc)execute_events_requests,
1493 #endif /* BABEL_CLEANUP */
1498 Manage the periodic update of a live trace
1501 live_trace_update_handler(Tab
*tab
)
1503 unsigned int updated_count
;
1504 #ifdef BABEL_CLEANUP
1505 LttvTracesetContext
*tsc
= LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
1506 TimeInterval initial_time_span
= tsc
->time_span
;
1507 TimeInterval updated_time_span
;
1509 updated_count
= lttv_process_traceset_update(tsc
);
1511 /* TODO ybrosseau 2011-01-12: Add trace resynchronization */
1513 /* Get the changed period bounds */
1514 updated_time_span
= tsc
->time_span
;
1516 if(ltt_time_compare(updated_time_span
.start_time
,
1517 initial_time_span
.start_time
) != 0) {
1518 /* The initial time should not change on a live update */
1522 /* Notify viewers (only on updates) */
1523 if(ltt_time_compare(updated_time_span
.end_time
,
1524 initial_time_span
.end_time
) != 0) {
1526 notify_time_span_changed(tab
);
1527 /* TODO ybrosseau 2011-01-12: Change the timebar to register
1528 to the time_span hook */
1529 timebar_set_minmax_time(TIMEBAR(tab
->MTimebar
),
1530 &updated_time_span
.start_time
,
1531 &updated_time_span
.end_time
);
1533 /* To update the min max */
1534 time_change_manager(tab
, tab
->time_window
);
1537 /* Timer will be recalled as long as there is files to update */
1538 return (updated_count
> 0);
1539 #endif /* BABEL_CLEANUP */
1542 static void lttvwindow_add_trace(Tab
*tab
, LttvTrace
*trace_v
)
1544 #ifdef BABEL_CLEANUP
1545 LttvTraceset
*traceset
= tab
->traceset_info
->traceset
;
1547 guint num_traces
= lttv_traceset_number(traceset
);
1549 //Verify if trace is already present.
1550 for(i
=0; i
<num_traces
; i
++)
1552 LttvTrace
* trace
= lttv_traceset_get(traceset
, i
);
1553 if(trace
== trace_v
)
1557 //Keep a reference to the traces so they are not freed.
1558 for(i
=0; i
<lttv_traceset_number(traceset
); i
++)
1560 LttvTrace
* trace
= lttv_traceset_get(traceset
, i
);
1561 lttv_trace_ref(trace
);
1564 //remove state update hooks
1565 lttv_state_remove_event_hooks(
1566 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1568 lttv_context_fini(LTTV_TRACESET_CONTEXT(
1569 tab
->traceset_info
->traceset_context
));
1570 g_object_unref(tab
->traceset_info
->traceset_context
);
1572 lttv_traceset_add(traceset
, trace_v
);
1573 lttv_trace_ref(trace_v
); /* local ref */
1575 /* Create new context */
1576 tab
->traceset_info
->traceset_context
=
1577 g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
1579 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->
1584 //add state update hooks
1585 lttv_state_add_event_hooks(
1586 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1587 //Remove local reference to the traces.
1588 for(i
=0; i
<lttv_traceset_number(traceset
); i
++)
1590 LttvTrace
* trace
= lttv_traceset_get(traceset
, i
);
1591 lttv_trace_unref(trace
);
1595 //add_trace_into_traceset_selector(GTK_MULTIVPANED(tab->multivpaned), lttv_trace(trace_v));
1598 if (lttv_trace(trace_v
)->is_live
) {
1599 /* Add timer for live update */
1600 /* TODO ybrosseau 2011-01-12: Parametrize the hardcoded 1 seconds */
1601 g_timeout_add_seconds (1,
1602 (GSourceFunc
) live_trace_update_handler
,
1605 #endif /* BABEL_CLEANUP */
1608 /* add_trace adds a trace into the current traceset. It first displays a
1609 * directory selection dialogue to let user choose a trace, then recreates
1610 * tracset_context, and redraws all the viewer of the current tab
1613 void add_trace(GtkWidget
* widget
, gpointer user_data
)
1616 LttvTraceset
* traceset
;
1618 char abs_path
[PATH_MAX
];
1620 MainWindow
* mw_data
= get_window_data_struct(widget
);
1621 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
1623 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
1624 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
1625 LttvPluginTab
*ptab
;
1629 ptab
= create_new_tab(widget
, NULL
);
1632 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
1635 /* Create a new traceset*/
1636 traceset
= lttv_traceset_new();
1637 /* File open dialog management */
1638 GtkWidget
*extra_live_button
;
1639 GtkFileChooser
* file_chooser
=
1641 gtk_file_chooser_dialog_new ("Select a trace",
1642 GTK_WINDOW(mw_data
->mwindow
),
1643 GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER
,
1644 GTK_STOCK_CANCEL
, GTK_RESPONSE_CANCEL
,
1645 GTK_STOCK_OPEN
, GTK_RESPONSE_ACCEPT
,
1648 /* Button to indicate the opening of a live trace */
1649 extra_live_button
= gtk_check_button_new_with_mnemonic ("Trace is live (currently being writen)");
1650 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (extra_live_button
), FALSE
);
1651 gtk_file_chooser_set_extra_widget (GTK_FILE_CHOOSER (file_chooser
), extra_live_button
);
1653 gtk_file_chooser_set_show_hidden (file_chooser
, TRUE
);
1654 if(remember_trace_dir
[0] != '\0')
1655 gtk_file_chooser_set_filename(file_chooser
, remember_trace_dir
);
1657 gboolean closeFileChooserDialog
= TRUE
;
1661 id
= gtk_dialog_run(GTK_DIALOG(file_chooser
));
1663 case GTK_RESPONSE_ACCEPT
:
1664 case GTK_RESPONSE_OK
:
1665 path
= gtk_file_chooser_get_filename (file_chooser
);
1667 strncpy(remember_trace_dir
, path
, PATH_MAX
);
1668 strncat(remember_trace_dir
, "/", PATH_MAX
);
1669 if(!path
|| strlen(path
) == 0){
1672 get_absolute_pathname(path
, abs_path
);
1674 if(lttv_traceset_add_path(traceset
,abs_path
) != 0 ){ /*failure*/
1676 g_warning("cannot open trace %s", abs_path
);
1677 strncpy(remember_trace_dir
, "\0", PATH_MAX
);
1678 GtkWidget
*dialogue
=
1679 gtk_message_dialog_new(
1680 GTK_WINDOW(gtk_widget_get_toplevel(widget
)),
1681 GTK_DIALOG_MODAL
|GTK_DIALOG_DESTROY_WITH_PARENT
,
1684 "Cannot open trace : maybe you should enter in the directory "
1686 gtk_dialog_run(GTK_DIALOG(dialogue
));
1687 gtk_widget_destroy(dialogue
);
1688 closeFileChooserDialog
= FALSE
;
1691 closeFileChooserDialog
= TRUE
;
1692 SetTraceset(tab
, traceset
);
1695 //update current tab
1696 //update_traceset(mw_data);
1698 // in expose now call_pending_read_hooks(mw_data);
1700 //lttvwindow_report_current_time(mw_data,&(tab->current_time));
1702 case GTK_RESPONSE_REJECT
:
1703 case GTK_RESPONSE_CANCEL
:
1705 closeFileChooserDialog
= TRUE
;
1708 }while(!closeFileChooserDialog
);
1710 gtk_widget_destroy((GtkWidget
*)file_chooser
);
1714 /* remove_trace removes a trace from the current traceset if all viewers in
1715 * the current tab are not interested in the trace. It first displays a
1716 * dialogue, which shows all traces in the current traceset, to let user choose
1717 * a trace, then it checks if all viewers unselect the trace, if it is true,
1718 * it will remove the trace, recreate the traceset_contex,
1719 * and redraws all the viewer of the current tab. If there is on trace in the
1720 * current traceset, it will delete all viewers of the current tab
1722 * It destroys the filter tree. FIXME... we should request for an update
1726 void remove_trace(GtkWidget
*widget
, gpointer user_data
)
1728 #ifdef BABEL_CLEANUP
1730 LttvTrace
* trace_v
;
1731 LttvTraceset
* traceset
;
1732 gint i
, j
, nb_trace
, index
=-1;
1733 char ** name
, *remove_trace_name
;
1734 MainWindow
* mw_data
= get_window_data_struct(widget
);
1735 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
1737 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
1738 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
1744 LttvPluginTab
*ptab
;
1745 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
1749 nb_trace
=lttv_traceset_number(tab
->traceset_info
->traceset
);
1750 name
= g_new(char*,nb_trace
);
1751 for(i
= 0; i
< nb_trace
; i
++){
1752 trace_v
= lttv_traceset_get(tab
->traceset_info
->traceset
, i
);
1753 trace
= lttv_trace(trace_v
);
1754 name
[i
] = (char *) g_quark_to_string(ltt_trace_name(trace
));
1757 remove_trace_name
= get_remove_trace(mw_data
, name
, nb_trace
);
1760 if(remove_trace_name
){
1762 /* yuk, cut n paste from old code.. should be better (MD)*/
1763 for(i
= 0; i
<nb_trace
; i
++) {
1764 if(strcmp(remove_trace_name
,name
[i
]) == 0){
1769 traceset
= tab
->traceset_info
->traceset
;
1770 //Keep a reference to the traces so they are not freed.
1771 for(j
=0; j
<lttv_traceset_number(traceset
); j
++)
1773 LttvTrace
* trace
= lttv_traceset_get(traceset
, j
);
1774 lttv_trace_ref(trace
);
1777 //remove state update hooks
1778 lttv_state_remove_event_hooks(
1779 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1780 lttv_context_fini(LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
));
1781 g_object_unref(tab
->traceset_info
->traceset_context
);
1783 trace_v
= lttv_traceset_get(traceset
, index
);
1785 lttv_traceset_remove(traceset
, index
);
1786 lttv_trace_unref(trace_v
); // Remove local reference
1788 if(lttv_trace_get_ref_number(trace_v
) <= 1) {
1789 /* ref 1 : lttvwindowtraces only*/
1790 ltt_trace_close(lttv_trace(trace_v
));
1791 /* lttvwindowtraces_remove_trace takes care of destroying
1792 * the traceset linked with the trace_v and also of destroying
1793 * the trace_v at the same time.
1795 lttvwindowtraces_remove_trace(trace_v
);
1798 tab
->traceset_info
->traceset_context
=
1799 g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
1801 LTTV_TRACESET_CONTEXT(tab
->
1802 traceset_info
->traceset_context
),traceset
);
1803 //add state update hooks
1804 lttv_state_add_event_hooks(
1805 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1807 //Remove local reference to the traces.
1808 for(j
=0; j
<lttv_traceset_number(traceset
); j
++)
1810 LttvTrace
* trace
= lttv_traceset_get(traceset
, j
);
1811 lttv_trace_unref(trace
);
1814 SetTraceset(tab
, (gpointer
)traceset
);
1817 #endif /* BABEL_CLEANUP */
1821 void remove_trace(GtkWidget
* widget
, gpointer user_data
)
1824 LttvTrace
* trace_v
;
1825 LttvTraceset
* traceset
;
1826 gint i
, j
, nb_trace
;
1827 char ** name
, *remove_trace_name
;
1828 MainWindow
* mw_data
= get_window_data_struct(widget
);
1829 LttvTracesetSelector
* s
;
1830 LttvTraceSelector
* t
;
1833 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
1835 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
1836 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
1842 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
1845 nb_trace
=lttv_traceset_number(tab
->traceset_info
->traceset
);
1846 name
= g_new(char*,nb_trace
);
1847 for(i
= 0; i
< nb_trace
; i
++){
1848 trace_v
= lttv_traceset_get(tab
->traceset_info
->traceset
, i
);
1849 trace
= lttv_trace(trace_v
);
1850 name
[i
] = ltt_trace_name(trace
);
1853 remove_trace_name
= get_remove_trace(name
, nb_trace
);
1855 if(remove_trace_name
){
1856 for(i
=0; i
<nb_trace
; i
++){
1857 if(strcmp(remove_trace_name
,name
[i
]) == 0){
1858 //unselect the trace from the current viewer
1860 w
= gtk_multivpaned_get_widget(GTK_MULTIVPANED(tab
->multivpaned
));
1862 s
= g_object_get_data(G_OBJECT(w
), "Traceset_Selector");
1864 t
= lttv_traceset_selector_trace_get(s
,i
);
1865 lttv_trace_selector_set_selected(t
, FALSE
);
1868 //check if other viewers select the trace
1869 w
= gtk_multivpaned_get_first_widget(GTK_MULTIVPANED(tab
->multivpaned
));
1871 s
= g_object_get_data(G_OBJECT(w
), "Traceset_Selector");
1873 t
= lttv_traceset_selector_trace_get(s
,i
);
1874 selected
= lttv_trace_selector_get_selected(t
);
1877 w
= gtk_multivpaned_get_next_widget(GTK_MULTIVPANED(tab
->multivpaned
));
1879 }else selected
= FALSE
;
1881 //if no viewer selects the trace, remove it
1883 remove_trace_from_traceset_selector(GTK_MULTIVPANED(tab
->multivpaned
), i
);
1885 traceset
= tab
->traceset_info
->traceset
;
1886 //Keep a reference to the traces so they are not freed.
1887 for(j
=0; j
<lttv_traceset_number(traceset
); j
++)
1889 LttvTrace
* trace
= lttv_traceset_get(traceset
, j
);
1890 lttv_trace_ref(trace
);
1893 //remove state update hooks
1894 lttv_state_remove_event_hooks(
1895 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1896 lttv_context_fini(LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
));
1897 g_object_unref(tab
->traceset_info
->traceset_context
);
1900 trace_v
= lttv_traceset_get(traceset
, i
);
1902 if(lttv_trace_get_ref_number(trace_v
) <= 2) {
1903 /* ref 2 : traceset, local */
1904 lttvwindowtraces_remove_trace(trace_v
);
1905 ltt_trace_close(lttv_trace(trace_v
));
1908 lttv_traceset_remove(traceset
, i
);
1909 lttv_trace_unref(trace_v
); // Remove local reference
1911 if(!lttv_trace_get_ref_number(trace_v
))
1912 lttv_trace_destroy(trace_v
);
1914 tab
->traceset_info
->traceset_context
=
1915 g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
1917 LTTV_TRACESET_CONTEXT(tab
->
1918 traceset_info
->traceset_context
),traceset
);
1919 //add state update hooks
1920 lttv_state_add_event_hooks(
1921 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1923 //Remove local reference to the traces.
1924 for(j
=0; j
<lttv_traceset_number(traceset
); j
++)
1926 LttvTrace
* trace
= lttv_traceset_get(traceset
, j
);
1927 lttv_trace_unref(trace
);
1931 //update current tab
1932 //update_traceset(mw_data);
1935 SetTraceset(tab
, (gpointer
)traceset
);
1936 // in expose now call_pending_read_hooks(mw_data);
1938 //lttvwindow_report_current_time(mw_data,&(tab->current_time));
1941 // while(tab->multi_vpaned->num_children){
1942 // gtk_multi_vpaned_widget_delete(tab->multi_vpaned);
1956 /* Redraw all the viewers in the current tab */
1957 void redraw(GtkWidget
*widget
, gpointer user_data
)
1959 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
1960 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
1961 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
1968 LttvPluginTab
*ptab
;
1969 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
1974 LttvAttributeValue value
;
1976 retval
= lttv_iattribute_find_by_path(tab
->attributes
, "hooks/redraw", LTTV_POINTER
, &value
);
1979 tmp
= (LttvHooks
*)*(value
.v_pointer
);
1981 lttv_hooks_call(tmp
,NULL
);
1985 void continue_processing(GtkWidget
*widget
, gpointer user_data
)
1987 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
1988 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
1989 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
1996 LttvPluginTab
*ptab
;
1997 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
2002 LttvAttributeValue value
;
2004 retval
= lttv_iattribute_find_by_path(tab
->attributes
, "hooks/continue",
2005 LTTV_POINTER
, &value
);
2008 tmp
= (LttvHooks
*)*(value
.v_pointer
);
2010 lttv_hooks_call(tmp
,NULL
);
2013 /* Stop the processing for the calling main window's current tab.
2014 * It removes every processing requests that are in its list. It does not call
2015 * the end request hooks, because the request is not finished.
2018 void stop_processing(GtkWidget
*widget
, gpointer user_data
)
2020 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
2021 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2022 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2027 LttvPluginTab
*ptab
;
2028 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
2031 GSList
*iter
= tab
->events_requests
;
2033 while(iter
!= NULL
) {
2034 GSList
*remove_iter
= iter
;
2035 iter
= g_slist_next(iter
);
2037 g_free(remove_iter
->data
);
2038 tab
->events_requests
=
2039 g_slist_remove_link(tab
->events_requests
, remove_iter
);
2041 tab
->events_request_pending
= FALSE
;
2042 tab
->stop_foreground
= TRUE
;
2043 g_idle_remove_by_data(tab
);
2044 g_assert(g_slist_length(tab
->events_requests
) == 0);
2048 /* save will save the traceset to a file
2049 * Not implemented yet FIXME
2052 void save(GtkWidget
* widget
, gpointer user_data
)
2057 void save_as(GtkWidget
* widget
, gpointer user_data
)
2059 g_info("Save as\n");
2063 /* zoom will change the time_window of all the viewers of the
2064 * current tab, and redisplay them. The main functionality is to
2065 * determine the new time_window of the current tab
2068 void zoom(GtkWidget
* widget
, double size
)
2070 #ifdef BABEL_CLEANUP
2071 TimeInterval time_span
;
2072 TimeWindow new_time_window
;
2073 LttTime current_time
, time_delta
;
2074 LttvTracesetContext
*tsc
;
2075 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
2077 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2078 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2084 LttvPluginTab
*ptab
;
2085 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
2089 if(size
== 1) return;
2091 tsc
= LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
2092 time_span
= tsc
->time_span
;
2093 new_time_window
= tab
->time_window
;
2094 current_time
= tab
->current_time
;
2096 time_delta
= ltt_time_sub(time_span
.end_time
,time_span
.start_time
);
2098 new_time_window
.start_time
= time_span
.start_time
;
2099 new_time_window
.time_width
= time_delta
;
2100 new_time_window
.time_width_double
= ltt_time_to_double(time_delta
);
2101 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
2102 new_time_window
.time_width
) ;
2104 new_time_window
.time_width
= ltt_time_div(new_time_window
.time_width
, size
);
2105 new_time_window
.time_width_double
=
2106 ltt_time_to_double(new_time_window
.time_width
);
2107 if(ltt_time_compare(new_time_window
.time_width
,time_delta
) > 0)
2108 { /* Case where zoom out is bigger than trace length */
2109 new_time_window
.start_time
= time_span
.start_time
;
2110 new_time_window
.time_width
= time_delta
;
2111 new_time_window
.time_width_double
= ltt_time_to_double(time_delta
);
2112 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
2113 new_time_window
.time_width
) ;
2117 /* Center the image on the current time */
2118 new_time_window
.start_time
=
2119 ltt_time_sub(current_time
,
2120 ltt_time_from_double(new_time_window
.time_width_double
/2.0));
2121 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
2122 new_time_window
.time_width
) ;
2123 /* If on borders, don't fall off */
2124 if(ltt_time_compare(new_time_window
.start_time
, time_span
.start_time
) <0
2125 || ltt_time_compare(new_time_window
.start_time
, time_span
.end_time
) >0)
2127 new_time_window
.start_time
= time_span
.start_time
;
2128 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
2129 new_time_window
.time_width
) ;
2133 if(ltt_time_compare(new_time_window
.end_time
,
2134 time_span
.end_time
) > 0
2135 || ltt_time_compare(new_time_window
.end_time
,
2136 time_span
.start_time
) < 0)
2138 new_time_window
.start_time
=
2139 ltt_time_sub(time_span
.end_time
, new_time_window
.time_width
);
2141 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
2142 new_time_window
.time_width
) ;
2149 if(ltt_time_compare(new_time_window
.time_width
, ltt_time_zero
) == 0) {
2150 g_warning("Zoom more than 1 ns impossible");
2152 time_change_manager(tab
, new_time_window
);
2155 #endif /* BABEL_CLEANUP */
2158 void zoom_in(GtkWidget
* widget
, gpointer user_data
)
2163 void zoom_out(GtkWidget
* widget
, gpointer user_data
)
2168 void zoom_extended(GtkWidget
* widget
, gpointer user_data
)
2173 void go_to_time(GtkWidget
* widget
, gpointer user_data
)
2175 g_info("Go to time\n");
2178 void show_time_frame(GtkWidget
* widget
, gpointer user_data
)
2180 g_info("Show time frame\n");
2184 /* callback function */
2187 on_empty_traceset_activate (GtkMenuItem
*menuitem
,
2190 create_new_window((GtkWidget
*)menuitem
, user_data
, FALSE
);
2195 on_clone_traceset_activate (GtkMenuItem
*menuitem
,
2198 create_new_window((GtkWidget
*)menuitem
, user_data
, TRUE
);
2202 /* create_new_tab calls create_tab to construct a new tab in the main window
2205 LttvPluginTab
*create_new_tab(GtkWidget
* widget
, gpointer user_data
)
2207 gchar label
[PATH_MAX
];
2208 MainWindow
* mw_data
= get_window_data_struct(widget
);
2210 GtkNotebook
* notebook
= (GtkNotebook
*)lookup_widget(widget
, "MNotebook");
2211 if(notebook
== NULL
){
2212 g_info("Notebook does not exist\n");
2215 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2216 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2222 LttvPluginTab
*ptab
;
2223 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
2224 copy_tab
= ptab
->tab
;
2227 strcpy(label
,"Page");
2228 if(get_label(mw_data
, label
,"Get the name of the tab","Please input tab's name")) {
2229 LttvPluginTab
*ptab
;
2231 ptab
= g_object_new(LTTV_TYPE_PLUGIN_TAB
, NULL
);
2232 init_tab (ptab
->tab
, mw_data
, copy_tab
, notebook
, label
);
2233 ptab
->parent
.top_widget
= ptab
->tab
->top_widget
;
2234 g_object_set_data_full(
2235 G_OBJECT(ptab
->tab
->vbox
),
2238 (GDestroyNotify
)tab_destructor
);
2245 on_tab_activate (GtkMenuItem
*menuitem
,
2248 create_new_tab((GtkWidget
*)menuitem
, user_data
);
2253 on_open_activate (GtkMenuItem
*menuitem
,
2256 #ifdef UNFINISHED_FEATURE
2257 open_traceset((GtkWidget
*)menuitem
, user_data
);
2263 on_close_activate (GtkMenuItem
*menuitem
,
2266 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2267 main_window_destructor(mw_data
);
2271 /* remove the current tab from the main window
2275 on_close_tab_activate (GtkWidget
*widget
,
2279 GtkWidget
* notebook
;
2280 notebook
= lookup_widget(widget
, "MNotebook");
2281 if(notebook
== NULL
){
2282 g_info("Notebook does not exist\n");
2286 page_num
= gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
));
2288 gtk_notebook_remove_page(GTK_NOTEBOOK(notebook
), page_num
);
2293 on_close_tab_X_clicked (GtkWidget
*widget
,
2297 GtkWidget
*notebook
= lookup_widget(widget
, "MNotebook");
2298 if(notebook
== NULL
){
2299 g_info("Notebook does not exist\n");
2303 if((page_num
= gtk_notebook_page_num(GTK_NOTEBOOK(notebook
), widget
)) != -1)
2304 gtk_notebook_remove_page(GTK_NOTEBOOK(notebook
), page_num
);
2310 on_add_trace_activate (GtkMenuItem
*menuitem
,
2313 add_trace((GtkWidget
*)menuitem
, user_data
);
2318 on_remove_trace_activate (GtkMenuItem
*menuitem
,
2321 remove_trace((GtkWidget
*)menuitem
, user_data
);
2326 on_save_activate (GtkMenuItem
*menuitem
,
2329 save((GtkWidget
*)menuitem
, user_data
);
2334 on_save_as_activate (GtkMenuItem
*menuitem
,
2337 save_as((GtkWidget
*)menuitem
, user_data
);
2342 on_quit_activate (GtkMenuItem
*menuitem
,
2345 while (g_slist_length(g_main_window_list
) != 0) {
2346 on_MWindow_destroy(((MainWindow
*)g_main_window_list
->data
)->mwindow
,
2353 on_cut_activate (GtkMenuItem
*menuitem
,
2361 on_copy_activate (GtkMenuItem
*menuitem
,
2369 on_paste_activate (GtkMenuItem
*menuitem
,
2377 on_delete_activate (GtkMenuItem
*menuitem
,
2385 on_zoom_in_activate (GtkMenuItem
*menuitem
,
2388 zoom_in((GtkWidget
*)menuitem
, user_data
);
2393 on_zoom_out_activate (GtkMenuItem
*menuitem
,
2396 zoom_out((GtkWidget
*)menuitem
, user_data
);
2401 on_zoom_extended_activate (GtkMenuItem
*menuitem
,
2404 zoom_extended((GtkWidget
*)menuitem
, user_data
);
2409 on_go_to_time_activate (GtkMenuItem
*menuitem
,
2412 go_to_time((GtkWidget
*)menuitem
, user_data
);
2417 on_show_time_frame_activate (GtkMenuItem
*menuitem
,
2420 show_time_frame((GtkWidget
*)menuitem
, user_data
);
2425 on_move_viewer_up_activate (GtkMenuItem
*menuitem
,
2428 move_up_viewer((GtkWidget
*)menuitem
, user_data
);
2433 on_move_viewer_down_activate (GtkMenuItem
*menuitem
,
2436 move_down_viewer((GtkWidget
*)menuitem
, user_data
);
2441 on_remove_viewer_activate (GtkMenuItem
*menuitem
,
2444 delete_viewer((GtkWidget
*)menuitem
, user_data
);
2448 on_trace_facility_activate (GtkMenuItem
*menuitem
,
2451 g_info("Trace facility selector: %s\n", "");
2455 /* Dispaly a file selection dialogue to let user select a library, then call
2456 * lttv_library_load().
2460 on_load_library_activate (GtkMenuItem
*menuitem
,
2463 GError
*error
= NULL
;
2464 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2466 gchar load_module_path_alter
[PATH_MAX
];
2470 gchar
*load_module_path
;
2471 name
= g_ptr_array_new();
2472 nb
= lttv_library_path_number();
2473 /* ask for the library path */
2477 path
= lttv_library_path_get(i
);
2478 g_ptr_array_add(name
, path
);
2481 load_module_path
= get_selection(mw_data
,
2482 (char **)(name
->pdata
), name
->len
,
2483 "Select a library path", "Library paths");
2484 if(load_module_path
!= NULL
)
2485 strncpy(load_module_path_alter
, load_module_path
, PATH_MAX
-1); // -1 for /
2487 g_ptr_array_free(name
, TRUE
);
2489 if(load_module_path
== NULL
) return;
2493 /* Make sure the module path ends with a / */
2494 gchar
*ptr
= load_module_path_alter
;
2496 ptr
= strchr(ptr
, '\0');
2498 if(*(ptr
-1) != '/') {
2505 /* Ask for the library to load : list files in the previously selected
2507 gchar str
[PATH_MAX
];
2510 GtkFileSelection
* file_selector
=
2511 (GtkFileSelection
*)gtk_file_selection_new("Select a module");
2512 gtk_file_selection_set_filename(file_selector
, load_module_path_alter
);
2513 gtk_file_selection_hide_fileop_buttons(file_selector
);
2515 gtk_window_set_transient_for(GTK_WINDOW(file_selector
),
2516 GTK_WINDOW(mw_data
->mwindow
));
2519 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
2521 case GTK_RESPONSE_ACCEPT
:
2522 case GTK_RESPONSE_OK
:
2523 dir
= gtk_file_selection_get_selections (file_selector
);
2524 strncpy(str
,dir
[0],PATH_MAX
);
2525 strncpy(remember_plugins_dir
,dir
[0],PATH_MAX
);
2526 /* only keep file name */
2528 str1
= strrchr(str
,'/');
2531 str1
= strrchr(str
,'\\');
2536 if(*str1
== 'l' && *(str1
+1)== 'i' && *(str1
+2)=='b')
2538 remove info after
. */
2542 str2
= strrchr(str2
, '.');
2543 if(str2
!= NULL
) *str2
= '\0';
2545 lttv_module_require(str1
, &error
);
2547 lttv_library_load(str1
, &error
);
2548 if(error
!= NULL
) g_warning("%s", error
->message
);
2549 else g_info("Load library: %s\n", str
);
2551 case GTK_RESPONSE_REJECT
:
2552 case GTK_RESPONSE_CANCEL
:
2554 gtk_widget_destroy((GtkWidget
*)file_selector
);
2565 /* Display all loaded modules, let user to select a module to unload
2566 * by calling lttv_module_unload
2570 on_unload_library_activate (GtkMenuItem
*menuitem
,
2573 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2575 LttvLibrary
*library
= NULL
;
2580 name
= g_ptr_array_new();
2581 nb
= lttv_library_number();
2582 LttvLibraryInfo
*lib_info
= g_new(LttvLibraryInfo
,nb
);
2583 /* ask for the library name */
2586 LttvLibrary
*iter_lib
= lttv_library_get(i
);
2587 lttv_library_info(iter_lib
, &lib_info
[i
]);
2589 gchar
*path
= lib_info
[i
].name
;
2590 g_ptr_array_add(name
, path
);
2592 lib_name
= get_selection(mw_data
, (char **)(name
->pdata
), name
->len
,
2593 "Select a library", "Libraries");
2594 if(lib_name
!= NULL
) {
2596 if(strcmp(lib_name
, lib_info
[i
].name
) == 0) {
2597 library
= lttv_library_get(i
);
2602 g_ptr_array_free(name
, TRUE
);
2605 if(lib_name
== NULL
) return;
2607 if(library
!= NULL
) lttv_library_unload(library
);
2611 /* Dispaly a file selection dialogue to let user select a module, then call
2612 * lttv_module_require().
2616 on_load_module_activate (GtkMenuItem
*menuitem
,
2619 GError
*error
= NULL
;
2620 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2622 LttvLibrary
*library
= NULL
;
2627 name
= g_ptr_array_new();
2628 nb
= lttv_library_number();
2629 LttvLibraryInfo
*lib_info
= g_new(LttvLibraryInfo
,nb
);
2630 /* ask for the library name */
2633 LttvLibrary
*iter_lib
= lttv_library_get(i
);
2634 lttv_library_info(iter_lib
, &lib_info
[i
]);
2636 gchar
*path
= lib_info
[i
].name
;
2637 g_ptr_array_add(name
, path
);
2639 lib_name
= get_selection(mw_data
,(char **)(name
->pdata
), name
->len
,
2640 "Select a library", "Libraries");
2641 if(lib_name
!= NULL
) {
2643 if(strcmp(lib_name
, lib_info
[i
].name
) == 0) {
2644 library
= lttv_library_get(i
);
2649 g_ptr_array_free(name
, TRUE
);
2652 if(lib_name
== NULL
) return;
2655 //LttvModule *module;
2656 gchar module_name_out
[PATH_MAX
];
2658 /* Ask for the module to load : list modules in the selected lib */
2662 nb
= lttv_library_module_number(library
);
2663 LttvModuleInfo
*module_info
= g_new(LttvModuleInfo
,nb
);
2664 name
= g_ptr_array_new();
2665 /* ask for the module name */
2668 LttvModule
*iter_module
= lttv_library_module_get(library
, i
);
2669 lttv_module_info(iter_module
, &module_info
[i
]);
2671 gchar
*path
= module_info
[i
].name
;
2672 g_ptr_array_add(name
, path
);
2674 module_name
= get_selection(mw_data
, (char **)(name
->pdata
), name
->len
,
2675 "Select a module", "Modules");
2676 if(module_name
!= NULL
) {
2678 if(strcmp(module_name
, module_info
[i
].name
) == 0) {
2679 strncpy(module_name_out
, module_name
, PATH_MAX
);
2680 //module = lttv_library_module_get(i);
2686 g_ptr_array_free(name
, TRUE
);
2687 g_free(module_info
);
2689 if(module_name
== NULL
) return;
2692 lttv_module_require(module_name_out
, &error
);
2693 if(error
!= NULL
) g_warning("%s", error
->message
);
2694 else g_info("Load module: %s", module_name_out
);
2701 gchar str
[PATH_MAX
];
2704 GtkFileSelection
* file_selector
=
2705 (GtkFileSelection
*)gtk_file_selection_new("Select a module");
2706 gtk_file_selection_set_filename(file_selector
, load_module_path_alter
);
2707 gtk_file_selection_hide_fileop_buttons(file_selector
);
2710 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
2712 case GTK_RESPONSE_ACCEPT
:
2713 case GTK_RESPONSE_OK
:
2714 dir
= gtk_file_selection_get_selections (file_selector
);
2715 strncpy(str
,dir
[0],PATH_MAX
);
2716 strncpy(remember_plugins_dir
,dir
[0],PATH_MAX
);
2718 /* only keep file name */
2720 str1
= strrchr(str
,'/');
2723 str1
= strrchr(str
,'\\');
2728 if(*str1
== 'l' && *(str1
+1)== 'i' && *(str1
+2)=='b')
2730 remove info after
. */
2734 str2
= strrchr(str2
, '.');
2735 if(str2
!= NULL
) *str2
= '\0';
2737 lttv_module_require(str1
, &error
);
2739 lttv_library_load(str1
, &error
);
2740 if(error
!= NULL
) g_warning(error
->message
);
2741 else g_info("Load library: %s\n", str
);
2743 case GTK_RESPONSE_REJECT
:
2744 case GTK_RESPONSE_CANCEL
:
2746 gtk_widget_destroy((GtkWidget
*)file_selector
);
2758 /* Display all loaded modules, let user to select a module to unload
2759 * by calling lttv_module_unload
2763 on_unload_module_activate (GtkMenuItem
*menuitem
,
2766 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2768 LttvLibrary
*library
= NULL
;
2773 name
= g_ptr_array_new();
2774 nb
= lttv_library_number();
2775 LttvLibraryInfo
*lib_info
= g_new(LttvLibraryInfo
,nb
);
2776 /* ask for the library name */
2779 LttvLibrary
*iter_lib
= lttv_library_get(i
);
2780 lttv_library_info(iter_lib
, &lib_info
[i
]);
2782 gchar
*path
= lib_info
[i
].name
;
2783 g_ptr_array_add(name
, path
);
2785 lib_name
= get_selection(mw_data
, (char **)(name
->pdata
), name
->len
,
2786 "Select a library", "Libraries");
2787 if(lib_name
!= NULL
) {
2789 if(strcmp(lib_name
, lib_info
[i
].name
) == 0) {
2790 library
= lttv_library_get(i
);
2795 g_ptr_array_free(name
, TRUE
);
2798 if(lib_name
== NULL
) return;
2801 LttvModule
*module
= NULL
;
2803 /* Ask for the module to load : list modules in the selected lib */
2807 nb
= lttv_library_module_number(library
);
2808 LttvModuleInfo
*module_info
= g_new(LttvModuleInfo
,nb
);
2809 name
= g_ptr_array_new();
2810 /* ask for the module name */
2813 LttvModule
*iter_module
= lttv_library_module_get(library
, i
);
2814 lttv_module_info(iter_module
, &module_info
[i
]);
2816 gchar
*path
= module_info
[i
].name
;
2817 if(module_info
[i
].use_count
> 0) g_ptr_array_add(name
, path
);
2819 module_name
= get_selection(mw_data
, (char **)(name
->pdata
), name
->len
,
2820 "Select a module", "Modules");
2821 if(module_name
!= NULL
) {
2823 if(strcmp(module_name
, module_info
[i
].name
) == 0) {
2824 module
= lttv_library_module_get(library
, i
);
2830 g_ptr_array_free(name
, TRUE
);
2831 g_free(module_info
);
2833 if(module_name
== NULL
) return;
2836 LttvModuleInfo module_info
;
2837 lttv_module_info(module
, &module_info
);
2838 g_info("Release module: %s\n", module_info
.name
);
2840 lttv_module_release(module
);
2844 /* Display a directory dialogue to let user select a path for library searching
2848 on_add_library_search_path_activate (GtkMenuItem
*menuitem
,
2851 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2852 //GtkDirSelection * file_selector = (GtkDirSelection *)gtk_dir_selection_new("Select library path");
2853 GtkFileSelection
* file_selector
= (GtkFileSelection
*)gtk_file_selection_new("Select a trace");
2854 gtk_widget_hide( (file_selector
)->file_list
->parent
) ;
2856 gtk_window_set_transient_for(GTK_WINDOW(file_selector
),
2857 GTK_WINDOW(mw_data
->mwindow
));
2862 if(remember_plugins_dir
[0] != '\0')
2863 gtk_file_selection_set_filename(file_selector
, remember_plugins_dir
);
2865 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
2867 case GTK_RESPONSE_ACCEPT
:
2868 case GTK_RESPONSE_OK
:
2869 dir
= gtk_file_selection_get_filename (file_selector
);
2870 strncpy(remember_plugins_dir
,dir
,PATH_MAX
);
2871 strncat(remember_plugins_dir
,"/",PATH_MAX
);
2872 lttv_library_path_add(dir
);
2873 case GTK_RESPONSE_REJECT
:
2874 case GTK_RESPONSE_CANCEL
:
2876 gtk_widget_destroy((GtkWidget
*)file_selector
);
2882 /* Display a directory dialogue to let user select a path for library searching
2886 on_remove_library_search_path_activate (GtkMenuItem
*menuitem
,
2889 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2891 const char *lib_path
;
2895 name
= g_ptr_array_new();
2896 nb
= lttv_library_path_number();
2897 /* ask for the library name */
2900 gchar
*path
= lttv_library_path_get(i
);
2901 g_ptr_array_add(name
, path
);
2903 lib_path
= get_selection(mw_data
, (char **)(name
->pdata
), name
->len
,
2904 "Select a library path", "Library paths");
2906 g_ptr_array_free(name
, TRUE
);
2908 if(lib_path
== NULL
) return;
2911 lttv_library_path_remove(lib_path
);
2915 on_color_activate (GtkMenuItem
*menuitem
,
2923 on_save_configuration_activate (GtkMenuItem
*menuitem
,
2926 g_info("Save configuration\n");
2931 on_content_activate (GtkMenuItem
*menuitem
,
2934 char* filename
= NULL
,
2937 const char* relativePath
= "doc/user/user_guide/html/index.html";
2938 filename
= g_build_filename (g_get_current_dir(), relativePath
, NULL
);
2939 path
= g_strdup_printf ("ghelp://%s", filename
);
2941 screen
= gdk_screen_get_default();
2942 gtk_show_uri (screen
, path
, gtk_get_current_event_time(), NULL
);
2946 g_info("Content\n");
2951 on_about_close_activate (GtkButton
*button
,
2954 GtkWidget
*about_widget
= GTK_WIDGET(user_data
);
2956 gtk_widget_destroy(about_widget
);
2960 on_about_activate (GtkMenuItem
*menuitem
,
2963 MainWindow
*main_window
= get_window_data_struct(GTK_WIDGET(menuitem
));
2964 GtkWidget
*window_widget
= main_window
->mwindow
;
2965 GtkWidget
*about_widget
= gtk_window_new(GTK_WINDOW_TOPLEVEL
);
2966 GtkWindow
*about_window
= GTK_WINDOW(about_widget
);
2968 gtk_window_set_title(about_window
, "About Linux Trace Toolkit");
2970 gtk_window_set_resizable(about_window
, FALSE
);
2971 gtk_window_set_transient_for(about_window
, GTK_WINDOW(window_widget
));
2972 gtk_window_set_destroy_with_parent(about_window
, TRUE
);
2973 gtk_window_set_modal(about_window
, FALSE
);
2975 /* Put the about window at the center of the screen */
2976 gtk_window_set_position(about_window
, GTK_WIN_POS_CENTER_ALWAYS
);
2978 GtkWidget
*vbox
= gtk_vbox_new(FALSE
, 1);
2980 gtk_container_add(GTK_CONTAINER(about_widget
), vbox
);
2983 GtkWidget
*label1
= gtk_label_new("");
2984 gtk_misc_set_padding(GTK_MISC(label1
), 10, 20);
2985 gtk_label_set_markup(GTK_LABEL(label1
), "\
2986 <big>Linux Trace Toolkit " VERSION
"</big>");
2987 gtk_label_set_justify(GTK_LABEL(label1
), GTK_JUSTIFY_CENTER
);
2989 GtkWidget
*label2
= gtk_label_new("");
2990 gtk_misc_set_padding(GTK_MISC(label2
), 10, 20);
2991 gtk_label_set_markup(GTK_LABEL(label2
), "\
2994 Michel Dagenais (New trace format, lttv main)\n\
2995 Mathieu Desnoyers (Kernel Tracer, Directory structure, build with automake/conf,\n\
2996 lttv gui, control flow view, gui cooperative trace reading\n\
2997 scheduler with interruptible foreground and background\n\
2998 computation, detailed event list (rewrite), trace reading\n\
2999 library (rewrite))\n\
3000 Benoit Des Ligneris, Eric Clement (Cluster adaptation, work in progress)\n\
3001 Xang-Xiu Yang (new trace reading library and converter, lttv gui, \n\
3002 detailed event list and statistics view)\n\
3003 Tom Zanussi (RelayFS)\n\
3005 Inspired from the original Linux Trace Toolkit Visualizer made by\n\
3008 GtkWidget
*label3
= gtk_label_new("");
3009 gtk_label_set_markup(GTK_LABEL(label3
), "\
3010 Linux Trace Toolkit Viewer, Copyright (C) 2004, 2005, 2006\n\
3012 Mathieu Desnoyers\n\
3014 Linux Trace Toolkit comes with ABSOLUTELY NO WARRANTY.\n\
3015 This is free software, and you are welcome to redistribute it\n\
3016 under certain conditions. See COPYING for details.");
3017 gtk_misc_set_padding(GTK_MISC(label3
), 10, 20);
3019 gtk_box_pack_start_defaults(GTK_BOX(vbox
), label1
);
3020 gtk_box_pack_start_defaults(GTK_BOX(vbox
), label2
);
3021 gtk_box_pack_start_defaults(GTK_BOX(vbox
), label3
);
3023 GtkWidget
*hbox
= gtk_hbox_new(TRUE
, 0);
3024 gtk_box_pack_end(GTK_BOX(vbox
), hbox
, FALSE
, FALSE
, 0);
3025 GtkWidget
*close_button
= gtk_button_new_with_mnemonic("_Close");
3026 gtk_box_pack_end(GTK_BOX(hbox
), close_button
, FALSE
, FALSE
, 0);
3027 gtk_container_set_border_width(GTK_CONTAINER(close_button
), 20);
3029 g_signal_connect(G_OBJECT(close_button
), "clicked",
3030 G_CALLBACK(on_about_close_activate
),
3031 (gpointer
)about_widget
);
3033 gtk_widget_show_all(about_widget
);
3038 on_button_new_clicked (GtkButton
*button
,
3041 create_new_window((GtkWidget
*)button
, user_data
, TRUE
);
3045 on_button_new_tab_clicked (GtkButton
*button
,
3048 create_new_tab((GtkWidget
*)button
, user_data
);
3052 on_button_open_clicked (GtkButton
*button
,
3055 #ifdef UNFINISHED_FEATURE
3056 open_traceset((GtkWidget
*)button
, user_data
);
3062 on_button_add_trace_clicked (GtkButton
*button
,
3065 add_trace((GtkWidget
*)button
, user_data
);
3070 on_button_remove_trace_clicked (GtkButton
*button
,
3073 remove_trace((GtkWidget
*)button
, user_data
);
3077 on_button_redraw_clicked (GtkButton
*button
,
3080 redraw((GtkWidget
*)button
, user_data
);
3084 on_button_continue_processing_clicked (GtkButton
*button
,
3087 continue_processing((GtkWidget
*)button
, user_data
);
3091 on_button_stop_processing_clicked (GtkButton
*button
,
3094 stop_processing((GtkWidget
*)button
, user_data
);
3100 on_button_save_clicked (GtkButton
*button
,
3103 save((GtkWidget
*)button
, user_data
);
3108 on_button_save_as_clicked (GtkButton
*button
,
3111 save_as((GtkWidget
*)button
, user_data
);
3116 on_button_zoom_in_clicked (GtkButton
*button
,
3119 zoom_in((GtkWidget
*)button
, user_data
);
3124 on_button_zoom_out_clicked (GtkButton
*button
,
3127 zoom_out((GtkWidget
*)button
, user_data
);
3132 on_button_zoom_extended_clicked (GtkButton
*button
,
3135 zoom_extended((GtkWidget
*)button
, user_data
);
3140 on_button_go_to_time_clicked (GtkButton
*button
,
3143 go_to_time((GtkWidget
*)button
, user_data
);
3148 on_button_show_time_frame_clicked (GtkButton
*button
,
3151 show_time_frame((GtkWidget
*)button
, user_data
);
3156 on_button_move_up_clicked (GtkButton
*button
,
3159 move_up_viewer((GtkWidget
*)button
, user_data
);
3164 on_button_move_down_clicked (GtkButton
*button
,
3167 move_down_viewer((GtkWidget
*)button
, user_data
);
3172 on_button_delete_viewer_clicked (GtkButton
*button
,
3175 delete_viewer((GtkWidget
*)button
, user_data
);
3179 on_MWindow_destroy (GtkWidget
*widget
,
3182 MainWindow
*main_window
= get_window_data_struct(widget
);
3183 LttvIAttribute
*attributes
= main_window
->attributes
;
3184 LttvAttributeValue value
;
3187 //This is unnecessary, since widgets will be destroyed
3188 //by the main window widget anyway.
3189 //remove_all_menu_toolbar_constructors(main_window, NULL);
3191 retval
= lttv_iattribute_find_by_path(attributes
, "viewers/menu",
3192 LTTV_POINTER
, &value
);
3194 lttv_menus_destroy((LttvMenus
*)*(value
.v_pointer
));
3196 retval
= lttv_iattribute_find_by_path(attributes
, "viewers/toolbar",
3197 LTTV_POINTER
, &value
);
3199 lttv_toolbars_destroy((LttvToolbars
*)*(value
.v_pointer
));
3201 g_object_unref(main_window
->attributes
);
3202 g_main_window_list
= g_slist_remove(g_main_window_list
, main_window
);
3204 g_info("There are now : %d windows\n",g_slist_length(g_main_window_list
));
3205 if(g_slist_length(g_main_window_list
) == 0)
3210 on_MWindow_configure (GtkWidget
*widget
,
3211 GdkEventConfigure
*event
,
3214 // MD : removed time width modification upon resizing of the main window.
3215 // The viewers will redraw themselves completely, without time interval
3218 if(mw_data->window_width){
3219 time_span = LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context)->Time_Span ;
3220 time_win = tab->time_window;
3221 ratio = width / mw_data->window_width;
3222 tab->time_window.time_width = ltt_time_mul(time_win.time_width,ratio);
3223 time = ltt_time_sub(time_span->endTime, time_win.start_time);
3224 if(ltt_time_compare(time, tab->time_window.time_width) < 0){
3225 tab->time_window.time_width = time;
3231 mw_data->window_width = (int)width;
3240 on_MNotebook_switch_page (GtkNotebook
*notebook
,
3241 GtkNotebookPage
*page
,
3249 void time_change_manager (Tab
*tab
,
3250 TimeWindow new_time_window
)
3253 /* Only one source of time change */
3254 if(tab
->time_manager_lock
== TRUE
) return;
3256 tab
->time_manager_lock
= TRUE
;
3257 TimeInterval time_span
;
3259 LttvTraceset
*ts
= tab
->traceset_info
->traceset
;
3260 time_span
.start_time
=ltt_time_from_uint64( lttv_traceset_get_timestamp_begin(ts
));
3261 time_span
.end_time
= ltt_time_from_uint64(lttv_traceset_get_timestamp_end(ts
));
3264 LttTime start_time
= new_time_window
.start_time
;
3265 LttTime end_time
= new_time_window
.end_time
;
3267 g_assert(ltt_time_compare(start_time
, end_time
) < 0);
3270 GtkAdjustment
*adjustment
= gtk_range_get_adjustment(GTK_RANGE(tab
->scrollbar
));
3271 LttTime upper
= ltt_time_sub(time_span
.end_time
, time_span
.start_time
);
3274 gtk_range_set_increments(GTK_RANGE(tab
->scrollbar
),
3275 ltt_time_to_double(new_time_window
.time_width
)
3276 / SCROLL_STEP_PER_PAGE
3277 * NANOSECONDS_PER_SECOND
, /* step increment */
3278 ltt_time_to_double(new_time_window
.time_width
)
3279 * NANOSECONDS_PER_SECOND
); /* page increment */
3280 gtk_range_set_range(GTK_RANGE(tab
->scrollbar
),
3282 ltt_time_to_double(upper
)
3283 * NANOSECONDS_PER_SECOND
); /* upper */
3285 g_object_set(G_OBJECT(adjustment
),
3289 ltt_time_to_double(upper
), /* upper */
3291 new_time_window
.time_width_double
3292 / SCROLL_STEP_PER_PAGE
, /* step increment */
3294 new_time_window
.time_width_double
,
3295 /* page increment */
3297 new_time_window
.time_width_double
, /* page size */
3299 gtk_adjustment_changed(adjustment
);
3301 // g_object_set(G_OBJECT(adjustment),
3303 // ltt_time_to_double(
3304 // ltt_time_sub(start_time, time_span.start_time))
3307 //gtk_adjustment_value_changed(adjustment);
3308 gtk_range_set_value(GTK_RANGE(tab
->scrollbar
),
3310 ltt_time_sub(start_time
, time_span
.start_time
)) /* value */);
3312 /* set the time bar. */
3315 timebar_set_minmax_time(TIMEBAR(tab
->MTimebar
),
3316 &time_span
.start_time
,
3317 &time_span
.end_time
);
3318 timebar_set_start_time(TIMEBAR(tab
->MTimebar
),&start_time
);
3319 timebar_set_end_time(TIMEBAR(tab
->MTimebar
),&end_time
);
3323 /* call viewer hooks for new time window */
3324 set_time_window(tab
, &new_time_window
);
3326 tab
->time_manager_lock
= FALSE
;
3335 void current_time_change_manager (Tab
*tab
,
3336 LttTime new_current_time
)
3338 /* Only one source of time change */
3339 if(tab
->current_time_manager_lock
== TRUE
) return;
3341 tab
->current_time_manager_lock
= TRUE
;
3343 timebar_set_current_time(TIMEBAR(tab
->MTimebar
), &new_current_time
);
3345 set_current_time(tab
, &new_current_time
);
3347 tab
->current_time_manager_lock
= FALSE
;
3350 void current_position_change_manager(Tab
*tab
,
3351 LttvTracesetPosition
*pos
)
3353 #ifdef BABEL_CLEANUP
3354 LttvTracesetContext
*tsc
=
3355 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3358 retval
= lttv_process_traceset_seek_position(tsc
, pos
);
3359 g_assert_cmpint(retval
, ==, 0);
3360 LttTime new_time
= lttv_traceset_context_position_get_time(pos
);
3361 /* Put the context in a state coherent position */
3362 lttv_state_traceset_seek_time_closest((LttvTracesetState
*)tsc
, ltt_time_zero
);
3364 current_time_change_manager(tab
, new_time
);
3366 set_current_position(tab
, pos
);
3367 #endif /* BABEL_CLEANUP */
3370 static void on_timebar_starttime_changed(Timebar
*timebar
,
3374 Tab
*tab
= (Tab
*)user_data
;
3375 LttvTraceset
* ts
=tab
->traceset_info
->traceset
;
3376 TimeInterval time_span
= lttv_traceset_get_time_span(ts
);
3378 TimeWindow new_time_window
= tab
->time_window
;
3379 new_time_window
.start_time
= timebar_get_start_time(timebar
);
3381 LttTime end_time
= new_time_window
.end_time
;
3383 /* TODO ybrosseau 2010-12-02: This if should have been checked
3384 by the timebar already */
3385 if(ltt_time_compare(new_time_window
.start_time
, end_time
) >= 0) {
3386 /* Then, we must push back end time : keep the same time width
3387 * if possible, else end traceset time */
3388 end_time
= LTT_TIME_MIN(ltt_time_add(new_time_window
.start_time
,
3389 new_time_window
.time_width
),
3390 time_span
.end_time
);
3393 /* Fix the time width to fit start time and end time */
3394 new_time_window
.time_width
= ltt_time_sub(end_time
,
3395 new_time_window
.start_time
);
3397 new_time_window
.time_width_double
=
3398 ltt_time_to_double(new_time_window
.time_width
);
3400 new_time_window
.end_time
= end_time
;
3402 /* Notify the time_manager */
3403 time_change_manager(tab
, new_time_window
);
3407 static void on_timebar_endtime_changed(Timebar
*timebar
,
3411 Tab
*tab
= (Tab
*)user_data
;
3412 LttvTraceset
* ts
=tab
->traceset_info
->traceset
;
3413 TimeInterval time_span
= lttv_traceset_get_time_span(ts
);
3415 TimeWindow new_time_window
= tab
->time_window
;
3417 LttTime end_time
= timebar_get_end_time(timebar
);
3419 /* TODO ybrosseau 2010-12-02: This if should have been
3420 checked by the timebar already */
3421 if(ltt_time_compare(new_time_window
.start_time
, end_time
) >= 0) {
3422 /* Then, we must push front start time : keep the same time
3423 width if possible, else end traceset time */
3424 new_time_window
.start_time
= LTT_TIME_MAX(
3425 ltt_time_sub(end_time
,
3426 new_time_window
.time_width
),
3427 time_span
.start_time
);
3430 /* Fix the time width to fit start time and end time */
3431 new_time_window
.time_width
= ltt_time_sub(end_time
,
3432 new_time_window
.start_time
);
3434 new_time_window
.time_width_double
=
3435 ltt_time_to_double(new_time_window
.time_width
);
3437 new_time_window
.end_time
= end_time
;
3439 /* Notify the time_manager */
3440 time_change_manager(tab
, new_time_window
);
3442 static void on_timebar_currenttime_changed(Timebar
*timebar
,
3445 Tab
*tab
= (Tab
*)user_data
;
3447 LttTime new_current_time
= timebar_get_current_time(timebar
);
3449 current_time_change_manager(tab
, new_current_time
);
3452 void scroll_value_changed_cb(GtkWidget
*scrollbar
,
3456 Tab
*tab
= (Tab
*)user_data
;
3457 TimeWindow new_time_window
;
3459 GtkAdjustment
*adjust
= gtk_range_get_adjustment(GTK_RANGE(scrollbar
));
3460 gdouble value
= gtk_adjustment_get_value(adjust
);
3461 // gdouble upper, lower, ratio, page_size;
3464 LttvTraceset
* ts
= tab
->traceset_info
->traceset
;
3465 TimeInterval time_span
= lttv_traceset_get_time_span(ts
);
3467 time
= ltt_time_add(ltt_time_from_double(value
),
3468 time_span
.start_time
);
3470 new_time_window
.start_time
= time
;
3472 page_size
= adjust
->page_size
;
3474 new_time_window
.time_width
=
3475 ltt_time_from_double(page_size
);
3477 new_time_window
.time_width_double
=
3480 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
3481 new_time_window
.time_width
);
3484 time_change_manager(tab
, new_time_window
);
3487 //time_window = tab->time_window;
3489 lower
= adjust
->lower
;
3490 upper
= adjust
->upper
;
3491 ratio
= (value
- lower
) / (upper
- lower
);
3492 g_info("lower %lu, upper %lu, value %lu, ratio %lu", lower
, upper
, value
, ratio
);
3494 //time = ltt_time_sub(time_span->end_time, time_span->start_time);
3495 //time = ltt_time_mul(time, (float)ratio);
3496 //time = ltt_time_add(time_span->start_time, time);
3497 time
= ltt_time_add(ltt_time_from_double(value
),
3498 time_span
.start_time
);
3500 time_window
.start_time
= time
;
3502 page_size
= adjust
->page_size
;
3504 time_window
.time_width
=
3505 ltt_time_from_double(page_size
);
3506 //time = ltt_time_sub(time_span.end_time, time);
3507 //if(ltt_time_compare(time,time_window.time_width) < 0){
3508 // time_window.time_width = time;
3511 /* call viewer hooks for new time window */
3512 set_time_window(tab
, &time_window
);
3518 /* Display a dialogue showing all eventtypes and traces, let user to select the interested
3519 * eventtypes, tracefiles and traces (filter)
3522 /* Select a trace which will be removed from traceset
3525 char * get_remove_trace(MainWindow
*mw_data
,
3526 char ** all_trace_name
, int nb_trace
)
3528 return get_selection(mw_data
, all_trace_name
, nb_trace
,
3529 "Select a trace", "Trace pathname");
3533 /* Select a module which will be loaded
3536 char * get_load_module(MainWindow
*mw_data
,
3537 char ** load_module_name
, int nb_module
)
3539 return get_selection(mw_data
, load_module_name
, nb_module
,
3540 "Select a module to load", "Module name");
3546 /* Select a module which will be unloaded
3549 char * get_unload_module(MainWindow
*mw_data
,
3550 char ** loaded_module_name
, int nb_module
)
3552 return get_selection(mw_data
, loaded_module_name
, nb_module
,
3553 "Select a module to unload", "Module name");
3557 /* Display a dialogue which shows all selectable items, let user to
3558 * select one of them
3561 char * get_selection(MainWindow
*mw_data
,
3562 char ** loaded_module_name
, int nb_module
,
3563 char *title
, char * column_title
)
3565 GtkWidget
* dialogue
;
3566 GtkWidget
* scroll_win
;
3568 GtkListStore
* store
;
3569 GtkTreeViewColumn
* column
;
3570 GtkCellRenderer
* renderer
;
3571 GtkTreeSelection
* select
;
3574 char * unload_module_name
= NULL
;
3576 dialogue
= gtk_dialog_new_with_buttons(title
,
3579 GTK_STOCK_OK
,GTK_RESPONSE_ACCEPT
,
3580 GTK_STOCK_CANCEL
,GTK_RESPONSE_REJECT
,
3582 gtk_window_set_default_size((GtkWindow
*)dialogue
, 500, 200);
3583 gtk_window_set_transient_for(GTK_WINDOW(dialogue
),
3584 GTK_WINDOW(mw_data
->mwindow
));
3586 scroll_win
= gtk_scrolled_window_new (NULL
, NULL
);
3587 gtk_widget_show ( scroll_win
);
3588 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll_win
),
3589 GTK_POLICY_AUTOMATIC
, GTK_POLICY_AUTOMATIC
);
3591 store
= gtk_list_store_new (N_COLUMNS
,G_TYPE_STRING
);
3592 tree
= gtk_tree_view_new_with_model(GTK_TREE_MODEL (store
));
3593 gtk_widget_show ( tree
);
3594 g_object_unref (G_OBJECT (store
));
3596 renderer
= gtk_cell_renderer_text_new ();
3597 column
= gtk_tree_view_column_new_with_attributes (column_title
,
3599 "text", MODULE_COLUMN
,
3601 gtk_tree_view_column_set_alignment (column
, 0.5);
3602 gtk_tree_view_column_set_fixed_width (column
, 150);
3603 gtk_tree_view_append_column (GTK_TREE_VIEW (tree
), column
);
3605 select
= gtk_tree_view_get_selection (GTK_TREE_VIEW (tree
));
3606 gtk_tree_selection_set_mode (select
, GTK_SELECTION_SINGLE
);
3608 gtk_container_add (GTK_CONTAINER (scroll_win
), tree
);
3610 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialogue
)->vbox
), scroll_win
,TRUE
, TRUE
,0);
3612 for(i
=0;i
<nb_module
;i
++){
3613 gtk_list_store_append (store
, &iter
);
3614 gtk_list_store_set (store
, &iter
, MODULE_COLUMN
,loaded_module_name
[i
],-1);
3617 id
= gtk_dialog_run(GTK_DIALOG(dialogue
));
3618 GtkTreeModel
**store_model
= (GtkTreeModel
**)&store
;
3620 case GTK_RESPONSE_ACCEPT
:
3621 case GTK_RESPONSE_OK
:
3622 if (gtk_tree_selection_get_selected (select
, store_model
, &iter
)){
3623 gtk_tree_model_get ((GtkTreeModel
*)store
, &iter
, MODULE_COLUMN
, &unload_module_name
, -1);
3625 case GTK_RESPONSE_REJECT
:
3626 case GTK_RESPONSE_CANCEL
:
3628 gtk_widget_destroy(dialogue
);
3632 return unload_module_name
;
3636 /* Insert all menu entry and tool buttons into this main window
3641 void add_all_menu_toolbar_constructors(MainWindow
* mw
, gpointer user_data
)
3645 lttvwindow_viewer_constructor constructor
;
3646 LttvMenus
* global_menu
, * instance_menu
;
3647 LttvToolbars
* global_toolbar
, * instance_toolbar
;
3648 LttvMenuClosure
*menu_item
;
3649 LttvToolbarClosure
*toolbar_item
;
3650 LttvAttributeValue value
;
3651 LttvIAttribute
*global_attributes
= LTTV_IATTRIBUTE(lttv_global_attributes());
3652 LttvIAttribute
*attributes
= mw
->attributes
;
3653 GtkWidget
* tool_menu_title_menu
, *new_widget
, *pixmap
;
3656 retval
= lttv_iattribute_find_by_path(global_attributes
, "viewers/menu",
3657 LTTV_POINTER
, &value
);
3659 if(*(value
.v_pointer
) == NULL
)
3660 *(value
.v_pointer
) = lttv_menus_new();
3661 global_menu
= (LttvMenus
*)*(value
.v_pointer
);
3663 retval
= lttv_iattribute_find_by_path(attributes
, "viewers/menu",
3664 LTTV_POINTER
, &value
);
3666 if(*(value
.v_pointer
) == NULL
)
3667 *(value
.v_pointer
) = lttv_menus_new();
3668 instance_menu
= (LttvMenus
*)*(value
.v_pointer
);
3670 retval
= lttv_iattribute_find_by_path(global_attributes
, "viewers/toolbar",
3671 LTTV_POINTER
, &value
);
3673 if(*(value
.v_pointer
) == NULL
)
3674 *(value
.v_pointer
) = lttv_toolbars_new();
3675 global_toolbar
= (LttvToolbars
*)*(value
.v_pointer
);
3677 retval
= lttv_iattribute_find_by_path(attributes
, "viewers/toolbar",
3678 LTTV_POINTER
, &value
);
3680 if(*(value
.v_pointer
) == NULL
)
3681 *(value
.v_pointer
) = lttv_toolbars_new();
3682 instance_toolbar
= (LttvToolbars
*)*(value
.v_pointer
);
3684 /* Add missing menu entries to window instance */
3685 for(i
=0;i
<global_menu
->len
;i
++) {
3686 menu_item
= &g_array_index(global_menu
, LttvMenuClosure
, i
);
3688 //add menu_item to window instance;
3689 constructor
= menu_item
->con
;
3690 tool_menu_title_menu
= lookup_widget(mw
->mwindow
,"ToolMenuTitle_menu");
3692 gtk_menu_item_new_with_mnemonic (menu_item
->menu_text
);
3693 gtk_container_add (GTK_CONTAINER (tool_menu_title_menu
),
3695 g_signal_connect ((gpointer
) new_widget
, "activate",
3696 G_CALLBACK (insert_viewer_wrap
),
3698 gtk_widget_show (new_widget
);
3699 lttv_menus_add(instance_menu
, menu_item
->con
,
3700 menu_item
->menu_path
,
3701 menu_item
->menu_text
,
3706 /* Add missing toolbar entries to window instance */
3707 for(i
=0;i
<global_toolbar
->len
;i
++) {
3708 toolbar_item
= &g_array_index(global_toolbar
, LttvToolbarClosure
, i
);
3710 //add toolbar_item to window instance;
3711 constructor
= toolbar_item
->con
;
3712 tool_menu_title_menu
= lookup_widget(mw
->mwindow
,"MToolbar1");
3713 pixbuf
= gdk_pixbuf_new_from_xpm_data((const char**)toolbar_item
->pixmap
);
3714 pixmap
= gtk_image_new_from_pixbuf(pixbuf
);
3716 gtk_toolbar_append_element (GTK_TOOLBAR (tool_menu_title_menu
),
3717 GTK_TOOLBAR_CHILD_BUTTON
,
3720 toolbar_item
->tooltip
, NULL
,
3721 pixmap
, NULL
, NULL
);
3722 gtk_label_set_use_underline(
3723 GTK_LABEL (((GtkToolbarChild
*) (
3724 g_list_last (GTK_TOOLBAR
3725 (tool_menu_title_menu
)->children
)->data
))->label
),
3727 gtk_container_set_border_width (GTK_CONTAINER (new_widget
), 1);
3728 g_signal_connect ((gpointer
) new_widget
,
3730 G_CALLBACK (insert_viewer_wrap
),
3732 gtk_widget_show (new_widget
);
3734 lttv_toolbars_add(instance_toolbar
, toolbar_item
->con
,
3735 toolbar_item
->tooltip
,
3736 toolbar_item
->pixmap
,
3744 /* Create a main window
3747 MainWindow
*construct_main_window(MainWindow
* parent
)
3751 g_debug("construct_main_window()");
3752 GtkWidget
* new_window
; /* New generated main window */
3753 MainWindow
* new_m_window
;/* New main window structure */
3754 GtkNotebook
* notebook
;
3755 LttvIAttribute
*attributes
=
3756 LTTV_IATTRIBUTE(g_object_new(LTTV_ATTRIBUTE_TYPE
, NULL
));
3757 LttvAttributeValue value
;
3759 new_m_window
= g_new(MainWindow
, 1);
3761 // Add the object's information to the module's array
3762 g_main_window_list
= g_slist_append(g_main_window_list
, new_m_window
);
3764 new_window
= create_MWindow();
3765 gtk_widget_show (new_window
);
3767 new_m_window
->mwindow
= new_window
;
3768 new_m_window
->attributes
= attributes
;
3770 retval
= lttv_iattribute_find_by_path(attributes
, "viewers/menu",
3771 LTTV_POINTER
, &value
);
3773 *(value
.v_pointer
) = lttv_menus_new();
3775 retval
= lttv_iattribute_find_by_path(attributes
, "viewers/toolbar",
3776 LTTV_POINTER
, &value
);
3778 *(value
.v_pointer
) = lttv_toolbars_new();
3780 add_all_menu_toolbar_constructors(new_m_window
, NULL
);
3782 g_object_set_data_full(G_OBJECT(new_window
),
3784 (gpointer
)new_m_window
,
3785 (GDestroyNotify
)g_free
);
3786 //create a default tab
3787 notebook
= (GtkNotebook
*)lookup_widget(new_m_window
->mwindow
, "MNotebook");
3788 if(notebook
== NULL
){
3789 g_info("Notebook does not exist\n");
3790 /* FIXME : destroy partially created widgets */
3791 g_free(new_m_window
);
3794 //gtk_notebook_popup_enable (GTK_NOTEBOOK(notebook));
3795 //for now there is no name field in LttvTraceset structure
3796 //Use "Traceset" as the label for the default tab
3798 GtkWidget
* parent_notebook
= lookup_widget(parent
->mwindow
, "MNotebook");
3799 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(parent_notebook
),
3800 gtk_notebook_get_current_page(GTK_NOTEBOOK(parent_notebook
)));
3806 LttvPluginTab
*ptab
;
3807 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
3808 parent_tab
= ptab
->tab
;
3810 LttvPluginTab
*ptab
= g_object_new(LTTV_TYPE_PLUGIN_TAB
, NULL
);
3812 new_m_window
, parent_tab
, notebook
, "Traceset");
3813 ptab
->parent
.top_widget
= ptab
->tab
->top_widget
;
3814 g_object_set_data_full(
3815 G_OBJECT(ptab
->tab
->vbox
),
3818 (GDestroyNotify
)tab_destructor
);
3820 LttvPluginTab
*ptab
= g_object_new(LTTV_TYPE_PLUGIN_TAB
, NULL
);
3821 init_tab(ptab
->tab
, new_m_window
, NULL
, notebook
, "Traceset");
3822 ptab
->parent
.top_widget
= ptab
->tab
->top_widget
;
3823 g_object_set_data_full(
3824 G_OBJECT(ptab
->tab
->vbox
),
3827 (GDestroyNotify
)tab_destructor
);
3830 /* Insert default viewers */
3832 LttvAttributeType type
;
3833 LttvAttributeName name
;
3834 LttvAttributeValue value
;
3835 LttvAttribute
*attribute
;
3837 LttvIAttribute
*attributes_global
=
3838 LTTV_IATTRIBUTE(lttv_global_attributes());
3840 attribute
= LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
3841 LTTV_IATTRIBUTE(attributes_global
),
3842 LTTV_VIEWER_CONSTRUCTORS
));
3843 g_assert(attribute
);
3845 name
= g_quark_from_string("guievents");
3846 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
3848 if(type
== LTTV_POINTER
) {
3849 lttvwindow_viewer_constructor viewer_constructor
=
3850 (lttvwindow_viewer_constructor
)*value
.v_pointer
;
3851 insert_viewer(new_window
, viewer_constructor
);
3854 name
= g_quark_from_string("guicontrolflow");
3855 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
3857 if(type
== LTTV_POINTER
) {
3858 lttvwindow_viewer_constructor viewer_constructor
=
3859 (lttvwindow_viewer_constructor
)*value
.v_pointer
;
3860 insert_viewer(new_window
, viewer_constructor
);
3863 name
= g_quark_from_string("guistatistics");
3864 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
3866 if(type
== LTTV_POINTER
) {
3867 lttvwindow_viewer_constructor viewer_constructor
=
3868 (lttvwindow_viewer_constructor
)*value
.v_pointer
;
3869 insert_viewer(new_window
, viewer_constructor
);
3873 g_info("There are now : %d windows\n",g_slist_length(g_main_window_list
));
3875 return new_m_window
;
3879 /* Free the memory occupied by a tab structure
3883 void tab_destructor(LttvPluginTab
* ptab
)
3885 #ifdef BABEL_CLEANUP
3886 int i
, nb
, ref_count
;
3888 Tab
*tab
= ptab
->tab
;
3891 g_object_unref(tab
->attributes
);
3893 if(tab
->interrupted_state
)
3894 g_object_unref(tab
->interrupted_state
);
3897 if(tab
->traceset_info
->traceset_context
!= NULL
){
3898 //remove state update hooks
3899 lttv_state_remove_event_hooks(
3900 (LttvTracesetState
*)tab
->traceset_info
->
3902 lttv_context_fini(LTTV_TRACESET_CONTEXT(tab
->traceset_info
->
3904 g_object_unref(tab
->traceset_info
->traceset_context
);
3906 if(tab
->traceset_info
->traceset
!= NULL
) {
3907 nb
= lttv_traceset_number(tab
->traceset_info
->traceset
);
3908 for(i
= 0 ; i
< nb
; i
++) {
3909 trace
= lttv_traceset_get(tab
->traceset_info
->traceset
, i
);
3910 ref_count
= lttv_trace_get_ref_number(trace
);
3912 ltt_trace_close(lttv_trace(trace
));
3916 lttv_traceset_destroy(tab
->traceset_info
->traceset
);
3917 /* Remove the idle events requests processing function of the tab */
3918 g_idle_remove_by_data(tab
);
3920 g_slist_free(tab
->events_requests
);
3921 g_free(tab
->traceset_info
);
3923 g_object_unref(ptab
);
3924 #endif /* BABEL_CLEANUP */
3928 /* Create a tab and insert it into the current main window
3931 void init_tab(Tab
*tab
, MainWindow
* mw
, Tab
*copy_tab
,
3932 GtkNotebook
* notebook
, char * label
)
3937 //LttvFilter *filter = NULL;
3939 //create a new tab data structure
3940 //tab = g_new(Tab,1);
3942 //construct and initialize the traceset_info
3943 tab
->traceset_info
= g_new(TracesetInfo
,1);
3946 tab
->traceset_info
->traceset
=
3947 lttv_traceset_copy(copy_tab
->traceset_info
->traceset
);
3949 /* Copy the previous tab's filter */
3950 /* We can clone the filter, as we copy the trace set also */
3951 /* The filter must always be in sync with the trace set */
3953 #ifdef BABEL_CLEANUP
3954 tab
->filter
= lttv_filter_clone(copy_tab
->filter
);
3955 #endif /* BABEL_CLEANUP */
3957 tab
->traceset_info
->traceset
= lttv_traceset_new();
3962 lttv_attribute_write_xml(
3963 lttv_traceset_attribute(tab
->traceset_info
->traceset
),
3969 tab
->time_manager_lock
= FALSE
;
3970 tab
->current_time_manager_lock
= FALSE
;
3971 #ifdef BABEL_CLEANUP
3972 //FIXME copy not implemented in lower level
3973 tab
->traceset_info
->traceset_context
=
3974 g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
3975 //add state update hooks
3976 lttv_state_add_event_hooks(
3977 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
3978 #endif //BABEL_CLEANUP
3979 //determine the current_time and time_window of the tab
3981 if(copy_tab
!= NULL
){
3982 tab
->time_window
= copy_tab
->time_window
;
3983 tab
->current_time
= copy_tab
->current_time
;
3985 tab
->time_window
.start_time
=
3986 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
3987 time_span
.start_time
;
3988 if(DEFAULT_TIME_WIDTH_S
<
3989 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
3990 time_span
.end_time
.tv_sec
)
3991 tmp_time
.tv_sec
= DEFAULT_TIME_WIDTH_S
;
3994 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
3995 time_span
.end_time
.tv_sec
;
3996 tmp_time
.tv_nsec
= 0;
3997 tab
->time_window
.time_width
= tmp_time
;
3998 tab
->current_time
.tv_sec
=
3999 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
4000 time_span
.start_time
.tv_sec
;
4001 tab
->current_time
.tv_nsec
=
4002 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
4003 time_span
.start_time
.tv_nsec
;
4006 tab
->attributes
= LTTV_IATTRIBUTE(g_object_new(LTTV_ATTRIBUTE_TYPE
, NULL
));
4007 tab
->interrupted_state
= g_object_new(LTTV_ATTRIBUTE_TYPE
, NULL
);
4009 tab
->vbox
= gtk_vbox_new(FALSE
, 2);
4010 tab
->top_widget
= tab
->vbox
;
4011 //g_object_set_data_full(G_OBJECT(tab->top_widget), "filter",
4012 // filter, (GDestroyNotify)lttv_filter_destroy);
4014 // g_signal_connect (G_OBJECT(tab->top_widget),
4016 // G_CALLBACK (on_top_notify),
4019 tab
->viewer_container
= gtk_vbox_new(TRUE
, 2);
4020 tab
->scrollbar
= gtk_hscrollbar_new(NULL
);
4021 //tab->multivpaned = gtk_multi_vpaned_new();
4023 gtk_box_pack_start(GTK_BOX(tab
->vbox
),
4024 tab
->viewer_container
,
4026 TRUE
, /* Give the extra space to the child */
4027 0); /* No padding */
4030 // tab->time_window = copy_tab->time_window;
4031 // tab->current_time = copy_tab->current_time;
4034 /* Create the timebar */
4036 tab
->MTimebar
= timebar_new();
4038 gtk_box_pack_end(GTK_BOX(tab
->vbox
),
4040 FALSE
, /* Do not expand */
4041 FALSE
, /* Fill has no effect here (expand false) */
4042 0); /* No padding */
4044 gtk_box_pack_end(GTK_BOX(tab
->vbox
),
4046 FALSE
, /* Do not expand */
4047 FALSE
, /* Fill has no effect here (expand false) */
4048 0); /* No padding */
4050 g_object_set_data(G_OBJECT(tab
->viewer_container
), "focused_viewer", NULL
);
4056 // Display a label with a X
4057 GtkWidget *w_hbox = gtk_hbox_new(FALSE, 4);
4058 GtkWidget *w_label = gtk_label_new (label);
4059 GtkWidget *pixmap = create_pixmap(GTK_WIDGET(notebook), "close.png");
4060 GtkWidget *w_button = gtk_button_new ();
4061 gtk_container_add(GTK_CONTAINER(w_button), pixmap);
4062 //GtkWidget *w_button = gtk_button_new_with_label("x");
4064 gtk_button_set_relief(GTK_BUTTON(w_button), GTK_RELIEF_NONE);
4066 gtk_box_pack_start(GTK_BOX(w_hbox), w_label, TRUE, TRUE, 0);
4067 gtk_box_pack_end(GTK_BOX(w_hbox), w_button, FALSE,
4070 g_signal_connect_swapped (w_button, "clicked",
4071 G_CALLBACK (on_close_tab_X_clicked),
4074 gtk_widget_set_state(w_button, GTK_STATE_ACTIVE);
4076 gtk_widget_show (w_label);
4077 gtk_widget_show (pixmap);
4078 gtk_widget_show (w_button);
4079 gtk_widget_show (w_hbox);
4081 tab->label = w_hbox;
4085 tab
->label
= gtk_label_new (label
);
4087 gtk_widget_show(tab
->label
);
4088 gtk_widget_show(tab
->scrollbar
);
4089 gtk_widget_show(tab
->MTimebar
);
4090 gtk_widget_show(tab
->viewer_container
);
4091 gtk_widget_show(tab
->vbox
);
4093 //gtk_widget_show(tab->multivpaned);
4096 /* Start with empty events requests list */
4097 tab
->events_requests
= NULL
;
4098 tab
->events_request_pending
= FALSE
;
4099 tab
->stop_foreground
= FALSE
;
4103 g_signal_connect(G_OBJECT(tab
->scrollbar
), "value-changed",
4104 G_CALLBACK(scroll_value_changed_cb
), tab
);
4107 /* Timebar signal handler */
4108 g_signal_connect(G_OBJECT(tab
->MTimebar
), "start-time-changed",
4109 G_CALLBACK(on_timebar_starttime_changed
), tab
);
4110 g_signal_connect(G_OBJECT(tab
->MTimebar
), "end-time-changed",
4111 G_CALLBACK(on_timebar_endtime_changed
), tab
);
4112 g_signal_connect(G_OBJECT(tab
->MTimebar
), "current-time-changed",
4113 G_CALLBACK(on_timebar_currenttime_changed
), tab
);
4115 //g_signal_connect(G_OBJECT(tab->scrollbar), "changed",
4116 // G_CALLBACK(scroll_value_changed_cb), tab);
4119 //insert tab into notebook
4120 gtk_notebook_append_page(notebook
,
4123 list
= gtk_container_get_children(GTK_CONTAINER(notebook
));
4124 gtk_notebook_set_current_page(notebook
,g_list_length(list
)-1);
4125 // always show : not if(g_list_length(list)>1)
4126 gtk_notebook_set_show_tabs(notebook
, TRUE
);
4129 lttvwindow_report_time_window(tab
, copy_tab
->time_window
);
4130 lttvwindow_report_current_time(tab
, copy_tab
->current_time
);
4132 TimeWindow time_window
;
4134 time_window
.start_time
= ltt_time_zero
;
4135 time_window
.end_time
= ltt_time_add(time_window
.start_time
,
4136 lttvwindow_default_time_width
);
4137 time_window
.time_width
= lttvwindow_default_time_width
;
4138 time_window
.time_width_double
= ltt_time_to_double(time_window
.time_width
);
4140 lttvwindow_report_time_window(tab
, time_window
);
4141 lttvwindow_report_current_time(tab
, ltt_time_zero
);
4144 LttvTraceset
*traceset
= tab
->traceset_info
->traceset
;
4145 SetTraceset(tab
, traceset
);
4149 * execute_events_requests
4151 * Idle function that executes the pending requests for a tab.
4153 * @return return value : TRUE : keep the idle function, FALSE : remove it.
4155 gboolean
execute_events_requests(Tab
*tab
)
4157 return ( lttvwindow_process_pending_requests(tab
) );
4161 __EXPORT
void create_main_window_with_trace_list(GSList
*traces
)
4164 GSList
*iter
= NULL
;
4167 MainWindow
*mw
= construct_main_window(NULL
);
4168 GtkWidget
*widget
= mw
->mwindow
;
4170 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
4171 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
4172 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
4173 LttvPluginTab
*ptab
;
4177 ptab
= create_new_tab(widget
, NULL
);
4180 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
4184 LttvTraceset
* traceset
= lttv_traceset_new();
4185 for(iter
=traces
; iter
!=NULL
; iter
=g_slist_next(iter
)) {
4186 gchar
*path
= (gchar
*)iter
->data
;
4188 gchar abs_path
[PATH_MAX
];
4191 get_absolute_pathname(path
, abs_path
);
4193 if(lttv_traceset_add_path(traceset
,abs_path
) != 0 ){ /*failure*/
4195 g_warning("cannot open trace %s", abs_path
);
4197 GtkWidget
*dialogue
=
4198 gtk_message_dialog_new(
4199 GTK_WINDOW(gtk_widget_get_toplevel(widget
)),
4200 GTK_DIALOG_MODAL
|GTK_DIALOG_DESTROY_WITH_PARENT
,
4203 "Cannot open trace : maybe you should enter in the directory "
4205 gtk_dialog_run(GTK_DIALOG(dialogue
));
4206 gtk_widget_destroy(dialogue
);
4209 SetTraceset(tab
, traceset
);