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>
41 #include <lttv/state.h>
43 #include <lttv/stats.h>
44 #include <lttv/sync/sync_chain_lttv.h>
45 #endif /* BABEL_CLEANUP */
46 #include <lttv/filter.h>
47 #include <lttvwindow/mainwindow.h>
48 #include <lttvwindow/mainwindow-private.h>
49 #include <lttvwindow/menu.h>
50 #include <lttvwindow/timebar.h>
51 #include <lttvwindow/toolbar.h>
52 #include <lttvwindow/lttvwindow.h>
53 #include <lttvwindow/lttvwindowtraces.h>
54 #include <lttvwindow/lttv_plugin_tab.h>
56 #include <babeltrace/babeltrace.h>
57 #include <babeltrace/ctf/events.h>
58 #include <babeltrace/ctf/iterator.h>
60 static LttTime lttvwindow_default_time_width
= { 1, 0 };
61 #define CLIP_BUF 256 // size of clipboard buffer
63 extern LttvTrace
*g_init_trace
;
66 /** Array containing instanced objects. */
67 extern GSList
* g_main_window_list
;
69 /** MD : keep old directory. */
70 static char remember_plugins_dir
[PATH_MAX
] = "";
71 static char remember_trace_dir
[PATH_MAX
] = "";
73 void tab_destructor(LttvPluginTab
* ptab
);
75 MainWindow
* get_window_data_struct(GtkWidget
* widget
);
76 char * get_load_module(MainWindow
*mw
,
77 char ** load_module_name
, int nb_module
);
78 char * get_unload_module(MainWindow
*mw
,
79 char ** loaded_module_name
, int nb_module
);
80 char * get_remove_trace(MainWindow
*mw
, char ** all_trace_name
, int nb_trace
);
81 char * get_selection(MainWindow
*mw
,
82 char ** all_name
, int nb
, char *title
, char * column_title
);
83 void init_tab(Tab
*tab
, MainWindow
* mw
, Tab
*copy_tab
,
84 GtkNotebook
* notebook
, char * label
);
86 int update_traceset(Tab
*tab
, LttvTraceset
*traceset
);
88 static void insert_viewer(GtkWidget
* widget
, lttvwindow_viewer_constructor constructor
);
90 LttvPluginTab
*create_new_tab(GtkWidget
* widget
, gpointer user_data
);
92 static gboolean
lttvwindow_process_pending_requests(Tab
*tab
);
94 static void on_timebar_starttime_changed(Timebar
*timebar
,
96 static void on_timebar_endtime_changed(Timebar
*timebar
,
98 static void on_timebar_currenttime_changed(Timebar
*timebar
,
115 static void on_top_notify(GObject
*gobject
,
119 Tab
*tab
= (Tab
*)user_data
;
120 g_message("in on_top_notify.\n");
124 static gboolean
viewer_grab_focus(GtkWidget
*widget
, GdkEventButton
*event
,
127 GtkWidget
*viewer
= GTK_WIDGET(data
);
128 GtkWidget
*viewer_container
= gtk_widget_get_parent(viewer
);
130 g_debug("FOCUS GRABBED");
131 g_object_set_data(G_OBJECT(viewer_container
), "focused_viewer", viewer
);
136 static void connect_focus_recursive(GtkWidget
*widget
,
139 if(GTK_IS_CONTAINER(widget
)) {
140 gtk_container_forall(GTK_CONTAINER(widget
),
141 (GtkCallback
)connect_focus_recursive
,
145 if(GTK_IS_TREE_VIEW(widget
)) {
146 gtk_tree_view_set_headers_clickable(GTK_TREE_VIEW(widget
), TRUE
);
148 gtk_widget_add_events(widget
, GDK_BUTTON_PRESS_MASK
);
149 g_signal_connect (G_OBJECT(widget
),
150 "button-press-event",
151 G_CALLBACK (viewer_grab_focus
),
155 /* Stop all the processings and call gtk_main_quit() */
156 static void mainwindow_quit()
158 lttvwindowtraces_unregister_requests(g_quark_from_string("stats"));
159 lttvwindowtraces_unregister_requests(g_quark_from_string("state"));
160 lttvwindowtraces_unregister_computation_hooks(g_quark_from_string("stats"));
161 lttvwindowtraces_unregister_computation_hooks(g_quark_from_string("state"));
167 /* insert_viewer function constructs an instance of a viewer first,
168 * then inserts the widget of the instance into the container of the
173 insert_viewer_wrap(GtkWidget
*menuitem
, gpointer user_data
)
175 insert_viewer((GtkWidget
*)menuitem
, (lttvwindow_viewer_constructor
)user_data
);
179 /* internal functions */
180 void insert_viewer(GtkWidget
* widget
, lttvwindow_viewer_constructor constructor
)
182 GtkWidget
* viewer_container
;
183 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
185 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
186 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
191 ptab
= create_new_tab(widget
, NULL
);
193 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
197 viewer_container
= tab
->viewer_container
;
199 viewer
= (GtkWidget
*)constructor(&ptab
->parent
);
202 //gtk_multivpaned_widget_add(GTK_MULTIVPANED(multivpaned), viewer);
204 gtk_box_pack_end(GTK_BOX(viewer_container
),
210 /* We want to connect the viewer_grab_focus to EVERY
211 * child of this widget. The little trick is to get each child
212 * of each GTK_CONTAINER, even subchildren.
214 connect_focus_recursive(viewer
, viewer
);
219 * Function to set/update traceset for the viewers
220 * @param tab viewer's tab
221 * @param traceset traceset of the main window.
223 * 0 : traceset updated
224 * 1 : no traceset hooks to update; not an error.
227 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_real(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
) ;
317 lttv_state_add_event_hooks(traceset
);
319 //TODO ybrosseau 2012-08-03 Temporarly compute checkpoints right at the adding
321 //Compute the traceset state checkpoint
324 EventsRequest
*events_request
= g_new(EventsRequest
, 1);
326 LttvHooks
*hook_adder
= lttv_hooks_new();
327 lttv_hooks_add(hook_adder
, lttv_state_save_hook_add_event_hooks
, NULL
,
329 LttvHooks
*hook_remover
= lttv_hooks_new();
330 lttv_hooks_add(hook_remover
, lttv_state_save_hook_remove_event_hooks
,
331 NULL
, LTTV_PRIO_DEFAULT
);
333 // Fill the events request
334 events_request
->owner
= NULL
;
335 events_request
->viewer_data
= NULL
;
336 events_request
->servicing
= FALSE
;
337 events_request
->start_time
= ltt_time_zero
;
338 events_request
->start_position
= NULL
;
339 events_request
->stop_flag
= FALSE
;
340 events_request
->end_time
= ltt_time_infinite
;
341 events_request
->num_events
= G_MAXUINT
;
342 events_request
->end_position
= NULL
;
343 events_request
->trace
= 1; //fixed /* FIXME */
344 events_request
->before_chunk_traceset
= NULL
;
345 events_request
->before_chunk_trace
= NULL
;
346 events_request
->before_chunk_tracefile
= NULL
;
347 events_request
->event
= NULL
;
348 events_request
->after_chunk_tracefile
= NULL
;
349 events_request
->after_chunk_trace
= NULL
;
350 events_request
->after_chunk_traceset
= NULL
;
351 events_request
->before_request
= hook_adder
;
352 events_request
->after_request
= hook_remover
;
354 lttvwindow_events_request(tab
, events_request
);
357 /* Finally, call the update hooks of the viewers */
358 gint retval
= update_traceset(tab
, traceset
);
360 time_change_manager(tab
, new_time_window
);
361 current_time_change_manager(tab
, new_current_time
);
368 * Function to set/update filter for the viewers
369 * @param tab viewer's tab
370 * @param filter filter of the main window.
373 * 0 : filters updated
374 * 1 : no filter hooks to update; not an error.
377 int SetFilter(Tab
* tab
, gpointer filter
)
380 LttvAttributeValue value
;
382 g_assert(lttv_iattribute_find_by_path(tab
->attributes
,
383 "hooks/updatefilter", LTTV_POINTER
, &value
));
385 tmp
= (LttvHooks
*)*(value
.v_pointer
);
387 if(tmp
== NULL
) return 1;
388 lttv_hooks_call(tmp
,filter
);
396 * Function to redraw each viewer belonging to the current tab
397 * @param tab viewer's tab
400 int update_traceset(Tab
*tab
, LttvTraceset
*traceset
)
402 LttvAttributeValue value
;
406 retval
= lttv_iattribute_find_by_path(tab
->attributes
,
407 "hooks/updatetraceset",
411 tmp
= (LttvHooks
*)*(value
.v_pointer
);
415 lttv_hooks_call(tmp
, traceset
);
421 Call hooks register to get update on traceset time span changes
423 int notify_time_span_changed(Tab
*tab
)
425 LttvAttributeValue value
;
429 retval
= lttv_iattribute_find_by_path(tab
->attributes
,
430 "hooks/updatetimespan",
434 tmp
= (LttvHooks
*)*(value
.v_pointer
);
438 lttv_hooks_call(tmp
, NULL
);
443 /* get_label function is used to get user input, it displays an input
444 * box, which allows user to input a string
447 void get_label_string (GtkWidget
* text
, gchar
* label
)
449 GtkEntry
* entry
= (GtkEntry
*)text
;
450 if(strlen(gtk_entry_get_text(entry
))!=0)
451 strcpy(label
,gtk_entry_get_text(entry
));
454 gboolean
get_label(MainWindow
* mw
, gchar
* str
, gchar
* dialogue_title
, gchar
* label_str
)
456 GtkWidget
* dialogue
;
461 dialogue
= gtk_dialog_new_with_buttons(dialogue_title
,NULL
,
463 GTK_STOCK_OK
,GTK_RESPONSE_ACCEPT
,
464 GTK_STOCK_CANCEL
,GTK_RESPONSE_REJECT
,
467 label
= gtk_label_new(label_str
);
468 gtk_widget_show(label
);
470 text
= gtk_entry_new();
471 gtk_widget_show(text
);
473 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialogue
)->vbox
), label
,TRUE
, TRUE
,0);
474 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialogue
)->vbox
), text
,FALSE
, FALSE
,0);
476 id
= gtk_dialog_run(GTK_DIALOG(dialogue
));
478 case GTK_RESPONSE_ACCEPT
:
479 get_label_string(text
,str
);
480 gtk_widget_destroy(dialogue
);
482 case GTK_RESPONSE_REJECT
:
484 gtk_widget_destroy(dialogue
);
491 /* get_window_data_struct function is actually a lookup function,
492 * given a widget which is in the tree of the main window, it will
493 * return the MainWindow data structure associated with main window
496 MainWindow
* get_window_data_struct(GtkWidget
* widget
)
499 MainWindow
* mw_data
;
501 mw
= lookup_widget(widget
, "MWindow");
503 g_info("Main window does not exist\n");
507 mw_data
= (MainWindow
*) g_object_get_data(G_OBJECT(mw
),"main_window_data");
509 g_warning("Main window data does not exist\n");
516 /* create_new_window function, just constructs a new main window
519 void create_new_window(GtkWidget
* widget
, gpointer user_data
, gboolean clone
)
521 MainWindow
* parent
= get_window_data_struct(widget
);
524 g_info("Clone : use the same traceset\n");
525 construct_main_window(parent
);
527 g_info("Empty : traceset is set to NULL\n");
528 construct_main_window(NULL
);
532 /* Get the currently focused viewer.
533 * If no viewer is focused, use the first one.
535 * If no viewer available, return NULL.
537 GtkWidget
*viewer_container_focus(GtkWidget
*container
)
541 widget
= (GtkWidget
*)g_object_get_data(G_OBJECT(container
),
545 g_debug("no widget focused");
546 GList
*children
= gtk_container_get_children(GTK_CONTAINER(container
));
549 widget
= GTK_WIDGET(children
->data
);
550 g_object_set_data(G_OBJECT(container
),
560 gint
viewer_container_position(GtkWidget
*container
, GtkWidget
*child
)
563 if(child
== NULL
) return -1;
567 memset(&value
, 0, sizeof(GValue
));
568 g_value_init(&value
, G_TYPE_INT
);
569 gtk_container_child_get_property(GTK_CONTAINER(container
),
573 pos
= g_value_get_int(&value
);
579 /* move_*_viewer functions move the selected view up/down in
583 void move_down_viewer(GtkWidget
* widget
, gpointer user_data
)
585 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
587 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
588 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
595 ptab
= g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
599 //gtk_multivpaned_widget_move_up(GTK_MULTIVPANED(tab->multivpaned));
601 /* change the position in the vbox */
602 GtkWidget
*focus_widget
;
604 focus_widget
= viewer_container_focus(tab
->viewer_container
);
605 position
= viewer_container_position(tab
->viewer_container
, focus_widget
);
608 /* can move up one position */
609 gtk_box_reorder_child(GTK_BOX(tab
->viewer_container
),
616 void move_up_viewer(GtkWidget
* widget
, gpointer user_data
)
618 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
620 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
621 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
628 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
632 //gtk_multivpaned_widget_move_down(GTK_MULTIVPANED(tab->multivpaned));
633 /* change the position in the vbox */
634 GtkWidget
*focus_widget
;
636 focus_widget
= viewer_container_focus(tab
->viewer_container
);
637 position
= viewer_container_position(tab
->viewer_container
, focus_widget
);
641 g_list_length(gtk_container_get_children(
642 GTK_CONTAINER(tab
->viewer_container
)))-1
644 /* can move down one position */
645 gtk_box_reorder_child(GTK_BOX(tab
->viewer_container
),
653 /* delete_viewer deletes the selected viewer in the current tab
656 void delete_viewer(GtkWidget
* widget
, gpointer user_data
)
658 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
660 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
661 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
668 ptab
= g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
672 //gtk_multivpaned_widget_delete(GTK_MULTIVPANED(tab->multivpaned));
674 GtkWidget
*focus_widget
= viewer_container_focus(tab
->viewer_container
);
676 if(focus_widget
!= NULL
)
677 gtk_widget_destroy(focus_widget
);
679 g_object_set_data(G_OBJECT(tab
->viewer_container
), "focused_viewer", NULL
);
682 #if UNFINISHED_FEATURE
683 /* TODO ybrosseau 2012-03-15: Function is half implemented. Should be removed */
684 /* open_traceset will open a traceset saved in a file
685 * Right now, it is not finished yet, (not working)
689 void open_traceset(GtkWidget
* widget
, gpointer user_data
)
693 LttvTraceset
* traceset
;
694 MainWindow
* mw_data
= get_window_data_struct(widget
);
695 GtkFileSelection
* file_selector
=
696 (GtkFileSelection
*)gtk_file_selection_new("Select a traceset");
698 gtk_file_selection_hide_fileop_buttons(file_selector
);
700 gtk_window_set_transient_for(GTK_WINDOW(file_selector
),
701 GTK_WINDOW(mw_data
->mwindow
));
703 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
705 case GTK_RESPONSE_ACCEPT
:
706 case GTK_RESPONSE_OK
:
707 dir
= gtk_file_selection_get_selections (file_selector
);
708 traceset
= lttv_traceset_load(dir
[0]);
709 g_info("Open a trace set %s\n", dir
[0]);
712 case GTK_RESPONSE_REJECT
:
713 case GTK_RESPONSE_CANCEL
:
715 gtk_widget_destroy((GtkWidget
*)file_selector
);
721 /* lttvwindow_process_pending_requests
723 * Process requests for parts of the trace from viewers.
725 * These requests are made by lttvwindow_events_request().
727 * This internal function gets called by g_idle, taking care of the pending
728 * requests. It is responsible for concatenation of time intervals and position
729 * requests. It does it with the following algorithm organizing process traceset
730 * calls. Here is the detailed description of the way it works :
732 * - Events Requests Servicing Algorithm
734 * Data structures necessary :
736 * List of requests added to context : list_in
737 * List of requests not added to context : list_out
742 * list_out : many events requests
744 * FIXME : insert rest of algorithm here
748 #define list_out tab->events_requests
750 gboolean
lttvwindow_process_pending_requests(Tab
*tab
)
755 GSList
*list_in
= NULL
;
759 LttvTracesetPosition
*end_position
;
761 if(lttvwindow_preempt_count
> 0) return TRUE
;
764 g_critical("Foreground processing : tab does not exist. Processing removed.");
768 /* There is no events requests pending : we should never have been called! */
769 g_assert(g_slist_length(list_out
) != 0);
771 ts
= tab
->traceset_info
->traceset
;
773 //set the cursor to be X shape, indicating that the computer is busy in doing its job
775 new = gdk_cursor_new(GDK_X_CURSOR
);
776 widget
= lookup_widget(tab
->mw
->mwindow
, "MToolbar1");
777 win
= gtk_widget_get_parent_window(widget
);
778 gdk_window_set_cursor(win
, new);
779 gdk_cursor_unref(new);
780 gdk_window_stick(win
);
781 gdk_window_unstick(win
);
784 g_debug("SIZE events req len : %d", g_slist_length(list_out
));
786 /* Preliminary check for no trace in traceset */
787 /* Unregister the routine if empty, empty list_out too */
788 if(lttv_traceset_number(ts
) == 0) {
790 /* - For each req in list_out */
791 GSList
*iter
= list_out
;
793 while(iter
!= NULL
) {
795 gboolean remove
= FALSE
;
796 gboolean free_data
= FALSE
;
797 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
799 /* - Call end request for req */
800 if(events_request
->servicing
== TRUE
)
801 lttv_hooks_call(events_request
->after_request
, (gpointer
)ts
);
803 /* - remove req from list_out */
804 /* Destroy the request */
807 //TODO ybrosseau: This if is always true
811 GSList
*remove_iter
= iter
;
813 iter
= g_slist_next(iter
);
814 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
815 list_out
= g_slist_remove_link(list_out
, remove_iter
);
816 } else { // not remove
817 iter
= g_slist_next(iter
);
822 /* 0.1 Lock Traces */
827 iter_trace
<lttv_traceset_number(ts
);
829 LttvTrace
*trace_v
= lttv_traceset_get(ts
, iter_trace
);
831 if(lttvwindowtraces_lock(trace_v
) != 0) {
832 g_critical("Foreground processing : Unable to get trace lock");
833 return TRUE
; /* Cannot get lock, try later */
838 /* 0.2 Seek tracefiles positions to context position */
840 //g_assert(lttv_process_traceset_seek_position(tsc, sync_position) == 0);
841 lttv_process_traceset_synchronize_tracefiles(tsc
);
844 /* Events processing algorithm implementation */
845 /* Warning : the gtk_events_pending takes a LOT of cpu time. So what we do
846 * instead is to leave the control to GTK and take it back.
848 /* A. Servicing loop */
849 //while( (g_slist_length(list_in) != 0 || g_slist_length(list_out) != 0)) {
850 if((g_slist_length(list_in
) != 0 || g_slist_length(list_out
) != 0)) {
852 /* 1. If list_in is empty (need a seek) */
853 if( g_slist_length(list_in
) == 0 ) {
855 /* list in is empty, need a seek */
857 /* 1.1 Add requests to list_in */
858 GSList
*ltime
= NULL
;
862 /* 1.1.1 Find all time requests with the lowest start time in list_out
865 if(g_slist_length(list_out
) > 0)
866 ltime
= g_slist_append(ltime
, g_slist_nth_data(list_out
, 0));
867 for(iter
=g_slist_nth(list_out
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
868 /* Find all time requests with the lowest start time in list_out */
869 EventsRequest
*event_request_ltime
= (EventsRequest
*)g_slist_nth_data(ltime
, 0);
870 EventsRequest
*event_request_list_out
= (EventsRequest
*)iter
->data
;
873 comp
= ltt_time_compare(event_request_ltime
->start_time
,
874 event_request_list_out
->start_time
);
876 ltime
= g_slist_append(ltime
, event_request_list_out
);
878 /* Remove all elements from ltime, and add current */
880 ltime
= g_slist_delete_link(ltime
, g_slist_nth(ltime
, 0));
881 ltime
= g_slist_append(ltime
, event_request_list_out
);
885 /* 1.1.2 Find all position requests with the lowest position in list_out
888 if(g_slist_length(list_out
) > 0)
889 lpos
= g_slist_append(lpos
, g_slist_nth_data(list_out
, 0));
890 for(iter
=g_slist_nth(list_out
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
891 /* Find all position requests with the lowest position in list_out */
892 EventsRequest
*event_request_lpos
= (EventsRequest
*)g_slist_nth_data(lpos
, 0);
893 EventsRequest
*event_request_list_out
= (EventsRequest
*)iter
->data
;
896 if(event_request_lpos
->start_position
!= NULL
897 && event_request_list_out
->start_position
!= NULL
)
899 //TODO ybrosseau: this compare is in fact an equal, so the behavior might not be right.
900 comp
= lttv_traceset_position_time_compare
901 (event_request_lpos
->start_position
,
902 event_request_list_out
->start_position
);
907 lpos
= g_slist_append(lpos
, event_request_list_out
);
909 /* Remove all elements from lpos, and add current */
911 lpos
= g_slist_delete_link(lpos
, g_slist_nth(lpos
, 0));
912 lpos
= g_slist_append(lpos
, event_request_list_out
);
917 EventsRequest
*event_request_lpos
= (EventsRequest
*)g_slist_nth_data(lpos
, 0);
918 EventsRequest
*event_request_ltime
= (EventsRequest
*)g_slist_nth_data(ltime
, 0);
919 LttTime lpos_start_time
;
921 if(event_request_lpos
!= NULL
922 && event_request_lpos
->start_position
!= NULL
) {
923 lpos_start_time
= lttv_traceset_position_get_time(
924 event_request_lpos
->start_position
);
927 /* 1.1.3 If lpos.start time < ltime */
928 if(event_request_lpos
!= NULL
929 && event_request_lpos
->start_position
!= NULL
930 && ltt_time_compare(lpos_start_time
,
931 event_request_ltime
->start_time
)<0) {
932 /* Add lpos to list_in, remove them from list_out */
933 for(iter
=lpos
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
935 EventsRequest
*event_request_lpos
=
936 (EventsRequest
*)iter
->data
;
938 list_in
= g_slist_append(list_in
, event_request_lpos
);
939 /* Remove from list_out */
940 list_out
= g_slist_remove(list_out
, event_request_lpos
);
943 /* 1.1.4 (lpos.start time >= ltime) */
944 /* Add ltime to list_in, remove them from list_out */
946 for(iter
=ltime
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
948 EventsRequest
*event_request_ltime
=
949 (EventsRequest
*)iter
->data
;
951 list_in
= g_slist_append(list_in
, event_request_ltime
);
952 /* Remove from list_out */
953 list_out
= g_slist_remove(list_out
, event_request_ltime
);
964 g_assert(g_slist_length(list_in
)>0);
965 EventsRequest
*events_request
= g_slist_nth_data(list_in
, 0);
970 /* 1.2.1 If first request in list_in is a time request */
971 if(events_request
->start_position
== NULL
) {
972 /* - If first req in list_in start time != current time */
973 //TODO ybrosseau: if commented out, since it was only affecting the g_debug
974 //if(tfc == NULL || ltt_time_compare(events_request->start_time,
975 // tfc->timestamp) != 0)
976 /* - Seek to that time */
977 g_debug("SEEK TIME : %lu, %lu", events_request
->start_time
.tv_sec
,
978 events_request
->start_time
.tv_nsec
);
979 lttv_state_traceset_seek_time_closest(ts
,
980 events_request
->start_time
);
982 /* Process the traceset with only state hooks */
986 lttv_process_traceset_middle(ts
,
987 events_request
->start_time
,
990 g_assert(seek_count
< LTTV_STATE_SAVE_INTERVAL
);
996 //LttvTracefileContext *tfc =
997 // lttv_traceset_context_get_current_tfc(tsc);
998 /* Else, the first request in list_in is a position request */
999 /* If first req in list_in pos != current pos */
1000 g_assert(events_request
->start_position
!= NULL
);
1001 g_debug("SEEK POS time : %lu, %lu",
1002 lttv_traceset_position_get_time(
1003 events_request
->start_position
).tv_sec
,
1004 lttv_traceset_position_get_time(
1005 events_request
->start_position
).tv_nsec
);
1007 /*if(tfc) {*/ if(0) {
1008 /* g_debug("SEEK POS context time : %lu, %lu",
1009 tfc->timestamp.tv_sec,
1010 tfc->timestamp.tv_nsec); */
1012 g_debug("SEEK POS context time : %lu, %lu",
1013 ltt_time_infinite
.tv_sec
,
1014 ltt_time_infinite
.tv_nsec
);
1016 g_assert(events_request
->start_position
!= NULL
);
1017 //TODO ybrosseau: for now, always seek
1018 if(/*lttv_traceset_context_ctx_pos_compare(tsc,
1019 events_request->start_position) != 0*/1) {
1020 /* 1.2.2.1 Seek to that position */
1021 g_debug("SEEK POSITION");
1022 //lttv_process_traceset_seek_position(tsc, events_request->start_position);
1023 pos_time
= lttv_traceset_position_get_time(
1024 events_request
->start_position
);
1026 lttv_state_traceset_seek_time_closest(ts
,
1028 //lttv_traceset_seek_to_position( events_request->start_position);
1030 /* Process the traceset with only state hooks */
1034 lttv_process_traceset_middle(ts
,
1037 events_request
->start_position
);
1039 //g_assert(lttv_traceset_context_ctx_pos_compare(tsc,
1040 // events_request->start_position) == 0);
1047 /* 1.3 Add hooks and call before request for all list_in members */
1049 GSList
*iter
= NULL
;
1050 for(iter
=list_in
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
1051 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1052 /* 1.3.1 If !servicing */
1053 if(events_request
->servicing
== FALSE
) {
1054 /* - begin request hooks called
1055 * - servicing = TRUE
1057 lttv_hooks_call(events_request
->before_request
, (gpointer
)ts
);
1058 events_request
->servicing
= TRUE
;
1060 /* 1.3.2 call before chunk
1061 * 1.3.3 events hooks added
1063 //TODO ybrosseau 2012-07-10: || TRUE added since we only support
1064 // traceset wide requests
1065 if(events_request
->trace
== -1 || TRUE
) {
1067 lttv_process_traceset_begin(ts
,
1068 events_request
->before_chunk_traceset
,
1069 events_request
->before_chunk_trace
,
1070 events_request
->event
1073 guint nb_trace
= lttv_traceset_number(ts
);
1074 g_assert((guint
)events_request
->trace
< nb_trace
&&
1075 events_request
->trace
> -1);
1076 LttvTrace
*trace
= lttv_traceset_get(ts
, events_request
->trace
);
1078 lttv_hooks_call(events_request
->before_chunk_traceset
, ts
);
1080 lttv_trace_add_hooks(trace
, events_request
->before_chunk_trace
,
1081 events_request
->event
);
1086 /* 2. Else, list_in is not empty, we continue a read */
1089 /* 2.0 For each req of list_in */
1090 GSList
*iter
= list_in
;
1092 while(iter
!= NULL
) {
1094 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1096 /* - Call before chunk
1097 * - events hooks added
1099 //TODO ybrosseau 2012-07-10: || TRUE added since we only support
1100 // traceset wide requests
1101 if(events_request
->trace
== -1 || TRUE
)
1102 lttv_process_traceset_begin(ts
,
1103 events_request
->before_chunk_traceset
,
1104 events_request
->before_chunk_trace
,
1105 events_request
->event
1108 guint nb_trace
= lttv_traceset_number(ts
);
1109 g_assert((guint
)events_request
->trace
< nb_trace
&&
1110 events_request
->trace
> -1);
1111 LttvTrace
*trace
= lttv_traceset_get(ts
, events_request
->trace
);
1113 lttv_hooks_call(events_request
->before_chunk_traceset
, ts
);
1115 lttv_trace_add_hooks(trace
,
1116 events_request
->before_chunk_trace
,
1117 events_request
->event
1121 iter
= g_slist_next(iter
);
1128 /* 2.1 For each req of list_out */
1129 GSList
*iter
= list_out
;
1131 while(iter
!= NULL
) {
1133 gboolean remove
= FALSE
;
1134 gboolean free_data
= FALSE
;
1135 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1137 /* if req.start time == current context time
1138 * or req.start position == current position*/
1139 /* if( ltt_time_compare(events_request->start_time,
1140 tfc->timestamp) == 0
1142 (events_request->start_position != NULL
1144 lttv_traceset_context_ctx_pos_compare(tsc,
1145 events_request->start_position) == 0)
1148 if(lttv_traceset_position_compare_current(ts
, events_request
->start_position
) == 0) {
1150 /* - Add to list_in, remove from list_out */
1151 list_in
= g_slist_append(list_in
, events_request
);
1155 /* - If !servicing */
1156 if(events_request
->servicing
== FALSE
) {
1157 /* - begin request hooks called
1158 * - servicing = TRUE
1160 lttv_hooks_call(events_request
->before_request
, (gpointer
)ts
);
1161 events_request
->servicing
= TRUE
;
1163 /* call before chunk
1164 * events hooks added
1166 //TODO ybrosseau 2012-07-10: || TRUE added since we only support
1167 // traceset wide requests
1168 if(events_request
->trace
== -1 || TRUE
)
1169 lttv_process_traceset_begin(ts
,
1170 events_request
->before_chunk_traceset
,
1171 events_request
->before_chunk_trace
,
1172 events_request
->event
1175 guint nb_trace
= lttv_traceset_number(ts
);
1176 g_assert((guint
)events_request
->trace
< nb_trace
&&
1177 events_request
->trace
> -1);
1178 LttvTrace
* trace
= lttv_traceset_get(ts
,events_request
->trace
);
1180 lttv_hooks_call(events_request
->before_chunk_traceset
, ts
);
1182 lttv_trace_add_hooks(trace
,
1183 events_request
->before_chunk_trace
,
1185 events_request
->event
);
1195 GSList
*remove_iter
= iter
;
1197 iter
= g_slist_next(iter
);
1198 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
1199 list_out
= g_slist_remove_link(list_out
, remove_iter
);
1200 } else { // not remove
1201 iter
= g_slist_next(iter
);
1207 /* 3. Find end criterions */
1212 /* 3.1.1 Find lowest end time in list_in */
1213 g_assert(g_slist_length(list_in
)>0);
1214 end_time
= ((EventsRequest
*)g_slist_nth_data(list_in
,0))->end_time
;
1216 for(iter
=g_slist_nth(list_in
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
1217 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1219 if(ltt_time_compare(events_request
->end_time
,
1221 end_time
= events_request
->end_time
;
1224 /* 3.1.2 Find lowest start time in list_out */
1225 for(iter
=list_out
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
1226 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1228 if(ltt_time_compare(events_request
->start_time
,
1230 end_time
= events_request
->start_time
;
1235 /* 3.2 Number of events */
1237 /* 3.2.1 Find lowest number of events in list_in */
1240 end_nb_events
= ((EventsRequest
*)g_slist_nth_data(list_in
,0))->num_events
;
1242 for(iter
=g_slist_nth(list_in
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
1243 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1245 if(events_request
->num_events
< end_nb_events
)
1246 end_nb_events
= events_request
->num_events
;
1249 /* 3.2.2 Use min(CHUNK_NUM_EVENTS, min num events in list_in) as
1252 end_nb_events
= MIN(CHUNK_NUM_EVENTS
, end_nb_events
);
1256 /* 3.3 End position */
1258 /* 3.3.1 Find lowest end position in list_in */
1261 end_position
=((EventsRequest
*)g_slist_nth_data(list_in
,0))->end_position
;
1263 for(iter
=g_slist_nth(list_in
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
1264 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1266 if(events_request
->end_position
!= NULL
&& end_position
!= NULL
&&
1267 lttv_traceset_position_time_compare(events_request
->end_position
,
1269 end_position
= events_request
->end_position
;
1274 /* 3.3.2 Find lowest start position in list_out */
1277 for(iter
=list_out
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
1278 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1280 if(events_request
->end_position
!= NULL
&& end_position
!= NULL
&&
1281 lttv_traceset_position_time_compare(events_request
->end_position
,
1283 end_position
= events_request
->end_position
;
1288 /* 4. Call process traceset middle */
1289 g_debug("Calling process traceset middle with %p, %lu sec %lu nsec, %u nb ev, %p end pos", ts
, end_time
.tv_sec
, end_time
.tv_nsec
, end_nb_events
, end_position
);
1290 count
= lttv_process_traceset_middle(ts
, end_time
, end_nb_events
, end_position
);
1292 #ifdef BABEL_CLEANUP
1293 tfc
= lttv_traceset_context_get_current_tfc(tsc
);
1295 g_debug("Context time after middle : %lu, %lu", tfc
->timestamp
.tv_sec
,
1296 tfc
->timestamp
.tv_nsec
);
1298 g_debug("End of trace reached after middle.");
1303 /* 5. After process traceset middle */
1305 LttTime curTime
= lttv_traceset_get_current_time(ts
);
1306 /* - if the iterator is not valid anymore (got to the end) */
1307 if(bt_ctf_iter_read_event(ts
->iter
) == NULL
) {
1308 /* - For each req in list_in */
1309 GSList
*iter
= list_in
;
1311 while(iter
!= NULL
) {
1313 gboolean remove
= FALSE
;
1314 gboolean free_data
= FALSE
;
1315 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1317 /* - Remove events hooks for req
1318 * - Call end chunk for req
1320 //TODO ybrosseau 2012-07-10: || TRUE added since we only support
1321 // traceset wide requests
1322 if(events_request
->trace
== -1 || TRUE
)
1323 lttv_process_traceset_end(ts
,
1324 events_request
->after_chunk_traceset
,
1325 events_request
->after_chunk_trace
,
1327 events_request
->event
);
1330 guint nb_trace
= lttv_traceset_number(ts
);
1331 g_assert(events_request
->trace
< nb_trace
&&
1332 events_request
->trace
> -1);
1333 LttvTrace
*trace
= lttv_traceset_get(ts
,events_request
->trace
);
1335 lttv_trace_remove_hooks(trace
,
1336 events_request
->after_chunk_trace
,
1338 events_request
->event
);
1340 lttv_hooks_call(events_request
->after_chunk_traceset
, ts
);
1345 /* - Call end request for req */
1346 lttv_hooks_call(events_request
->after_request
, (gpointer
)ts
);
1348 /* - remove req from list_in */
1349 /* Destroy the request */
1356 GSList
*remove_iter
= iter
;
1358 iter
= g_slist_next(iter
);
1359 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
1360 list_in
= g_slist_remove_link(list_in
, remove_iter
);
1361 } else { // not remove
1362 iter
= g_slist_next(iter
);
1367 /* 5.1 For each req in list_in */
1368 GSList
*iter
= list_in
;
1370 while(iter
!= NULL
) {
1372 gboolean remove
= FALSE
;
1373 gboolean free_data
= FALSE
;
1374 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1376 /* - Remove events hooks for req
1377 * - Call end chunk for req
1379 //TODO ybrosseau 2012-07-10: || TRUE added since we only support
1380 // traceset wide requests
1381 if(events_request
->trace
== -1 || TRUE
) {
1382 lttv_process_traceset_end(ts
,
1383 events_request
->after_chunk_traceset
,
1384 events_request
->after_chunk_trace
,
1385 events_request
->event
);
1387 guint nb_trace
= lttv_traceset_number(ts
);
1388 g_assert(events_request
->trace
< nb_trace
&&
1389 events_request
->trace
> -1);
1390 LttvTrace
*trace
= lttv_traceset_get(ts
, events_request
->trace
);
1392 lttv_trace_remove_hooks(trace
,
1393 events_request
->after_chunk_trace
,
1395 events_request
->event
);
1398 lttv_hooks_call(events_request
->after_chunk_traceset
, ts
);
1401 /* - req.num -= count */
1402 g_assert(events_request
->num_events
>= count
);
1403 events_request
->num_events
-= count
;
1405 //g_assert(tfc != NULL);
1406 /* - if req.num == 0
1408 * current context time >= req.end time
1410 * req.end pos == current pos
1412 * req.stop_flag == TRUE
1414 if( events_request
->num_events
== 0
1416 events_request
->stop_flag
== TRUE
1418 ltt_time_compare(lttv_traceset_get_current_time(ts
),
1419 events_request
->end_time
) >= 0
1421 (events_request
->end_position
!= NULL
1423 lttv_traceset_position_compare_current(ts
,
1424 events_request
->end_position
) == 0)
1427 g_assert(events_request
->servicing
== TRUE
);
1428 /* - Call end request for req
1429 * - remove req from list_in */
1430 lttv_hooks_call(events_request
->after_request
, (gpointer
)ts
);
1431 /* - remove req from list_in */
1432 /* Destroy the request */
1440 GSList
*remove_iter
= iter
;
1442 iter
= g_slist_next(iter
);
1443 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
1444 list_in
= g_slist_remove_link(list_in
, remove_iter
);
1445 } else { // not remove
1446 iter
= g_slist_next(iter
);
1452 /* End of removed servicing loop : leave control to GTK instead. */
1453 // if(gtk_events_pending()) break;
1456 /* B. When interrupted between chunks */
1459 GSList
*iter
= list_in
;
1461 /* 1. for each request in list_in */
1462 while(iter
!= NULL
) {
1464 gboolean remove
= FALSE
;
1465 gboolean free_data
= FALSE
;
1466 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1468 /* 1.1. Use current postition as start position */
1469 if(events_request
->start_position
!= NULL
)
1470 lttv_traceset_destroy_position(events_request
->start_position
);
1471 events_request
->start_position
= lttv_traceset_create_current_position(ts
);
1474 /* 1.2. Remove start time */
1475 events_request
->start_time
= ltt_time_infinite
;
1477 /* 1.3. Move from list_in to list_out */
1480 list_out
= g_slist_append(list_out
, events_request
);
1485 GSList
*remove_iter
= iter
;
1487 iter
= g_slist_next(iter
);
1488 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
1489 list_in
= g_slist_remove_link(list_in
, remove_iter
);
1490 } else { // not remove
1491 iter
= g_slist_next(iter
);
1497 /* C Unlock Traces */
1499 #ifdef BABEL_CLEANUP
1500 lttv_process_traceset_get_sync_data(tsc
);
1502 //lttv_traceset_context_position_save(tsc, sync_position);
1507 iter_trace
<lttv_traceset_number(ts
);
1509 LttvTrace
*trace_v
= lttv_traceset_get(ts
, iter_trace
);
1511 lttvwindowtraces_unlock(trace_v
);
1515 //set the cursor back to normal
1516 gdk_window_set_cursor(win
, NULL
);
1519 g_assert(g_slist_length(list_in
) == 0);
1521 if( g_slist_length(list_out
) == 0 ) {
1522 /* Put tab's request pending flag back to normal */
1523 tab
->events_request_pending
= FALSE
;
1524 g_debug("remove the idle fct");
1525 return FALSE
; /* Remove the idle function */
1527 g_debug("leave the idle fct");
1528 return TRUE
; /* Leave the idle function */
1530 /* We do not use simili-round-robin, it may require to read 1 meg buffers
1531 * again and again if many tracesets use the same tracefiles. */
1532 /* Hack for round-robin idle functions */
1533 /* It will put the idle function at the end of the pool */
1534 /*g_idle_add_full((G_PRIORITY_HIGH_IDLE + 21),
1535 (GSourceFunc)execute_events_requests,
1546 Manage the periodic update of a live trace
1549 live_trace_update_handler(Tab
*tab
)
1551 #ifdef BABEL_CLEANUP
1552 unsigned int updated_count
;
1553 LttvTracesetContext
*tsc
= LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
1554 TimeInterval initial_time_span
= tsc
->time_span
;
1555 TimeInterval updated_time_span
;
1557 updated_count
= lttv_process_traceset_update(tsc
);
1559 /* TODO ybrosseau 2011-01-12: Add trace resynchronization */
1561 /* Get the changed period bounds */
1562 updated_time_span
= tsc
->time_span
;
1564 if(ltt_time_compare(updated_time_span
.start_time
,
1565 initial_time_span
.start_time
) != 0) {
1566 /* The initial time should not change on a live update */
1570 /* Notify viewers (only on updates) */
1571 if(ltt_time_compare(updated_time_span
.end_time
,
1572 initial_time_span
.end_time
) != 0) {
1574 notify_time_span_changed(tab
);
1575 /* TODO ybrosseau 2011-01-12: Change the timebar to register
1576 to the time_span hook */
1577 timebar_set_minmax_time(TIMEBAR(tab
->MTimebar
),
1578 &updated_time_span
.start_time
,
1579 &updated_time_span
.end_time
);
1581 /* To update the min max */
1582 time_change_manager(tab
, tab
->time_window
);
1585 /* Timer will be recalled as long as there is files to update */
1586 return (updated_count
> 0);
1587 #endif /* BABEL_CLEANUP */
1590 static void lttvwindow_add_trace(Tab
*tab
, LttvTrace
*trace_v
)
1592 #ifdef BABEL_CLEANUP
1593 LttvTraceset
*traceset
= tab
->traceset_info
->traceset
;
1595 guint num_traces
= lttv_traceset_number(traceset
);
1597 //Verify if trace is already present.
1598 for(i
=0; i
<num_traces
; i
++)
1600 LttvTrace
* trace
= lttv_traceset_get(traceset
, i
);
1601 if(trace
== trace_v
)
1605 //Keep a reference to the traces so they are not freed.
1606 for(i
=0; i
<lttv_traceset_number(traceset
); i
++)
1608 LttvTrace
* trace
= lttv_traceset_get(traceset
, i
);
1609 lttv_trace_ref(trace
);
1612 //remove state update hooks
1613 lttv_state_remove_event_hooks(
1614 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1616 lttv_context_fini(LTTV_TRACESET_CONTEXT(
1617 tab
->traceset_info
->traceset_context
));
1618 g_object_unref(tab
->traceset_info
->traceset_context
);
1620 lttv_traceset_add(traceset
, trace_v
);
1621 lttv_trace_ref(trace_v
); /* local ref */
1623 /* Create new context */
1624 tab
->traceset_info
->traceset_context
=
1625 g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
1627 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->
1632 //add state update hooks
1633 lttv_state_add_event_hooks(
1634 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1635 //Remove local reference to the traces.
1636 for(i
=0; i
<lttv_traceset_number(traceset
); i
++)
1638 LttvTrace
* trace
= lttv_traceset_get(traceset
, i
);
1639 lttv_trace_unref(trace
);
1643 //add_trace_into_traceset_selector(GTK_MULTIVPANED(tab->multivpaned), lttv_trace(trace_v));
1646 if (lttv_trace(trace_v
)->is_live
) {
1647 /* Add timer for live update */
1648 /* TODO ybrosseau 2011-01-12: Parametrize the hardcoded 1 seconds */
1649 g_timeout_add_seconds (1,
1650 (GSourceFunc
) live_trace_update_handler
,
1653 #endif /* BABEL_CLEANUP */
1656 /* add_trace adds a trace into the current traceset. It first displays a
1657 * directory selection dialogue to let user choose a trace, then recreates
1658 * tracset_context, and redraws all the viewer of the current tab
1661 void add_trace(GtkWidget
* widget
, gpointer user_data
)
1664 LttvTraceset
* traceset
= NULL
;
1666 char abs_path
[PATH_MAX
];
1668 MainWindow
* mw_data
= get_window_data_struct(widget
);
1669 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
1671 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
1672 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
1673 LttvPluginTab
*ptab
;
1677 ptab
= create_new_tab(widget
, NULL
);
1680 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
1684 /* Create a new traceset*/
1685 traceset
= tab
->traceset_info
->traceset
;
1686 if(traceset
== NULL
) {
1687 traceset
= lttv_traceset_new();
1689 /* File open dialog management */
1690 #ifdef BABEL_CLEANUP
1691 GtkWidget
*extra_live_button
;
1692 #endif //babel_cleanup
1693 GtkFileChooser
* file_chooser
=
1695 gtk_file_chooser_dialog_new ("Select a trace",
1696 GTK_WINDOW(mw_data
->mwindow
),
1697 GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER
,
1698 GTK_STOCK_CANCEL
, GTK_RESPONSE_CANCEL
,
1699 GTK_STOCK_OPEN
, GTK_RESPONSE_ACCEPT
,
1701 #ifdef BABEL_CLEANUP
1702 /* Button to indicate the opening of a live trace */
1703 extra_live_button
= gtk_check_button_new_with_mnemonic ("Trace is live (currently being writen)");
1704 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (extra_live_button
), FALSE
);
1705 gtk_file_chooser_set_extra_widget (GTK_FILE_CHOOSER (file_chooser
), extra_live_button
);
1706 #endif //babel_cleanup
1707 gtk_file_chooser_set_show_hidden (file_chooser
, TRUE
);
1708 if(remember_trace_dir
[0] != '\0')
1709 gtk_file_chooser_set_filename(file_chooser
, remember_trace_dir
);
1711 gboolean closeFileChooserDialog
= TRUE
;
1715 id
= gtk_dialog_run(GTK_DIALOG(file_chooser
));
1717 case GTK_RESPONSE_ACCEPT
:
1718 case GTK_RESPONSE_OK
:
1719 path
= gtk_file_chooser_get_filename (file_chooser
);
1721 strncpy(remember_trace_dir
, path
, PATH_MAX
);
1722 strncat(remember_trace_dir
, "/", PATH_MAX
);
1723 if(!path
|| strlen(path
) == 0){
1726 get_absolute_pathname(path
, abs_path
);
1728 if(lttv_traceset_add_path(traceset
,abs_path
) != 0 ){ /*failure*/
1730 g_warning("cannot open trace %s", abs_path
);
1731 strncpy(remember_trace_dir
, "\0", PATH_MAX
);
1732 GtkWidget
*dialogue
=
1733 gtk_message_dialog_new(
1734 GTK_WINDOW(gtk_widget_get_toplevel(widget
)),
1735 GTK_DIALOG_MODAL
|GTK_DIALOG_DESTROY_WITH_PARENT
,
1738 "Cannot open trace : maybe you should enter in the directory "
1740 gtk_dialog_run(GTK_DIALOG(dialogue
));
1741 gtk_widget_destroy(dialogue
);
1742 closeFileChooserDialog
= FALSE
;
1745 closeFileChooserDialog
= TRUE
;
1746 SetTraceset(tab
, traceset
);
1749 //update current tab
1750 //update_traceset(mw_data);
1752 // in expose now call_pending_read_hooks(mw_data);
1754 //lttvwindow_report_current_time(mw_data,&(tab->current_time));
1756 case GTK_RESPONSE_REJECT
:
1757 case GTK_RESPONSE_CANCEL
:
1759 closeFileChooserDialog
= TRUE
;
1762 }while(!closeFileChooserDialog
);
1764 gtk_widget_destroy((GtkWidget
*)file_chooser
);
1768 /* remove_trace removes a trace from the current traceset if all viewers in
1769 * the current tab are not interested in the trace. It first displays a
1770 * dialogue, which shows all traces in the current traceset, to let user choose
1771 * a trace, then it checks if all viewers unselect the trace, if it is true,
1772 * it will remove the trace, recreate the traceset_contex,
1773 * and redraws all the viewer of the current tab. If there is on trace in the
1774 * current traceset, it will delete all viewers of the current tab
1776 * It destroys the filter tree. FIXME... we should request for an update
1780 void remove_trace(GtkWidget
*widget
, gpointer user_data
)
1782 #ifdef BABEL_CLEANUP
1784 LttvTrace
* trace_v
;
1785 LttvTraceset
* traceset
;
1786 gint i
, j
, nb_trace
, index
=-1;
1787 char ** name
, *remove_trace_name
;
1788 MainWindow
* mw_data
= get_window_data_struct(widget
);
1789 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
1791 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
1792 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
1798 LttvPluginTab
*ptab
;
1799 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
1803 nb_trace
=lttv_traceset_number(tab
->traceset_info
->traceset
);
1804 name
= g_new(char*,nb_trace
);
1805 for(i
= 0; i
< nb_trace
; i
++){
1806 trace_v
= lttv_traceset_get(tab
->traceset_info
->traceset
, i
);
1807 trace
= lttv_trace(trace_v
);
1808 name
[i
] = (char *) g_quark_to_string(ltt_trace_name(trace
));
1811 remove_trace_name
= get_remove_trace(mw_data
, name
, nb_trace
);
1814 if(remove_trace_name
){
1816 /* yuk, cut n paste from old code.. should be better (MD)*/
1817 for(i
= 0; i
<nb_trace
; i
++) {
1818 if(strcmp(remove_trace_name
,name
[i
]) == 0){
1823 traceset
= tab
->traceset_info
->traceset
;
1824 //Keep a reference to the traces so they are not freed.
1825 for(j
=0; j
<lttv_traceset_number(traceset
); j
++)
1827 LttvTrace
* trace
= lttv_traceset_get(traceset
, j
);
1828 lttv_trace_ref(trace
);
1831 //remove state update hooks
1832 lttv_state_remove_event_hooks(
1833 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1834 lttv_context_fini(LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
));
1835 g_object_unref(tab
->traceset_info
->traceset_context
);
1837 trace_v
= lttv_traceset_get(traceset
, index
);
1839 lttv_traceset_remove(traceset
, index
);
1840 lttv_trace_unref(trace_v
); // Remove local reference
1842 if(lttv_trace_get_ref_number(trace_v
) <= 1) {
1843 /* ref 1 : lttvwindowtraces only*/
1844 ltt_trace_close(lttv_trace(trace_v
));
1845 /* lttvwindowtraces_remove_trace takes care of destroying
1846 * the traceset linked with the trace_v and also of destroying
1847 * the trace_v at the same time.
1849 lttvwindowtraces_remove_trace(trace_v
);
1852 tab
->traceset_info
->traceset_context
=
1853 g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
1855 LTTV_TRACESET_CONTEXT(tab
->
1856 traceset_info
->traceset_context
),traceset
);
1857 //add state update hooks
1858 lttv_state_add_event_hooks(
1859 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1861 //Remove local reference to the traces.
1862 for(j
=0; j
<lttv_traceset_number(traceset
); j
++)
1864 LttvTrace
* trace
= lttv_traceset_get(traceset
, j
);
1865 lttv_trace_unref(trace
);
1868 SetTraceset(tab
, (gpointer
)traceset
);
1871 #endif /* BABEL_CLEANUP */
1875 void remove_trace(GtkWidget
* widget
, gpointer user_data
)
1878 LttvTrace
* trace_v
;
1879 LttvTraceset
* traceset
;
1880 gint i
, j
, nb_trace
;
1881 char ** name
, *remove_trace_name
;
1882 MainWindow
* mw_data
= get_window_data_struct(widget
);
1883 LttvTracesetSelector
* s
;
1884 LttvTraceSelector
* t
;
1887 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
1889 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
1890 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
1896 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
1899 nb_trace
=lttv_traceset_number(tab
->traceset_info
->traceset
);
1900 name
= g_new(char*,nb_trace
);
1901 for(i
= 0; i
< nb_trace
; i
++){
1902 trace_v
= lttv_traceset_get(tab
->traceset_info
->traceset
, i
);
1903 trace
= lttv_trace(trace_v
);
1904 name
[i
] = ltt_trace_name(trace
);
1907 remove_trace_name
= get_remove_trace(name
, nb_trace
);
1909 if(remove_trace_name
){
1910 for(i
=0; i
<nb_trace
; i
++){
1911 if(strcmp(remove_trace_name
,name
[i
]) == 0){
1912 //unselect the trace from the current viewer
1914 w
= gtk_multivpaned_get_widget(GTK_MULTIVPANED(tab
->multivpaned
));
1916 s
= g_object_get_data(G_OBJECT(w
), "Traceset_Selector");
1918 t
= lttv_traceset_selector_trace_get(s
,i
);
1919 lttv_trace_selector_set_selected(t
, FALSE
);
1922 //check if other viewers select the trace
1923 w
= gtk_multivpaned_get_first_widget(GTK_MULTIVPANED(tab
->multivpaned
));
1925 s
= g_object_get_data(G_OBJECT(w
), "Traceset_Selector");
1927 t
= lttv_traceset_selector_trace_get(s
,i
);
1928 selected
= lttv_trace_selector_get_selected(t
);
1931 w
= gtk_multivpaned_get_next_widget(GTK_MULTIVPANED(tab
->multivpaned
));
1933 }else selected
= FALSE
;
1935 //if no viewer selects the trace, remove it
1937 remove_trace_from_traceset_selector(GTK_MULTIVPANED(tab
->multivpaned
), i
);
1939 traceset
= tab
->traceset_info
->traceset
;
1940 //Keep a reference to the traces so they are not freed.
1941 for(j
=0; j
<lttv_traceset_number(traceset
); j
++)
1943 LttvTrace
* trace
= lttv_traceset_get(traceset
, j
);
1944 lttv_trace_ref(trace
);
1947 //remove state update hooks
1948 lttv_state_remove_event_hooks(
1949 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1950 lttv_context_fini(LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
));
1951 g_object_unref(tab
->traceset_info
->traceset_context
);
1954 trace_v
= lttv_traceset_get(traceset
, i
);
1956 if(lttv_trace_get_ref_number(trace_v
) <= 2) {
1957 /* ref 2 : traceset, local */
1958 lttvwindowtraces_remove_trace(trace_v
);
1959 ltt_trace_close(lttv_trace(trace_v
));
1962 lttv_traceset_remove(traceset
, i
);
1963 lttv_trace_unref(trace_v
); // Remove local reference
1965 if(!lttv_trace_get_ref_number(trace_v
))
1966 lttv_trace_destroy(trace_v
);
1968 tab
->traceset_info
->traceset_context
=
1969 g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
1971 LTTV_TRACESET_CONTEXT(tab
->
1972 traceset_info
->traceset_context
),traceset
);
1973 //add state update hooks
1974 lttv_state_add_event_hooks(
1975 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1977 //Remove local reference to the traces.
1978 for(j
=0; j
<lttv_traceset_number(traceset
); j
++)
1980 LttvTrace
* trace
= lttv_traceset_get(traceset
, j
);
1981 lttv_trace_unref(trace
);
1985 //update current tab
1986 //update_traceset(mw_data);
1989 SetTraceset(tab
, (gpointer
)traceset
);
1990 // in expose now call_pending_read_hooks(mw_data);
1992 //lttvwindow_report_current_time(mw_data,&(tab->current_time));
1995 // while(tab->multi_vpaned->num_children){
1996 // gtk_multi_vpaned_widget_delete(tab->multi_vpaned);
2010 /* Redraw all the viewers in the current tab */
2011 void redraw(GtkWidget
*widget
, gpointer user_data
)
2013 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
2014 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2015 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2022 LttvPluginTab
*ptab
;
2023 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
2028 LttvAttributeValue value
;
2030 retval
= lttv_iattribute_find_by_path(tab
->attributes
, "hooks/redraw", LTTV_POINTER
, &value
);
2033 tmp
= (LttvHooks
*)*(value
.v_pointer
);
2035 lttv_hooks_call(tmp
,NULL
);
2039 void continue_processing(GtkWidget
*widget
, gpointer user_data
)
2041 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
2042 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2043 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2050 LttvPluginTab
*ptab
;
2051 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
2056 LttvAttributeValue value
;
2058 retval
= lttv_iattribute_find_by_path(tab
->attributes
, "hooks/continue",
2059 LTTV_POINTER
, &value
);
2062 tmp
= (LttvHooks
*)*(value
.v_pointer
);
2064 lttv_hooks_call(tmp
,NULL
);
2067 /* Stop the processing for the calling main window's current tab.
2068 * It removes every processing requests that are in its list. It does not call
2069 * the end request hooks, because the request is not finished.
2072 void stop_processing(GtkWidget
*widget
, gpointer user_data
)
2074 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
2075 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2076 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2081 LttvPluginTab
*ptab
;
2082 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
2085 GSList
*iter
= tab
->events_requests
;
2087 while(iter
!= NULL
) {
2088 GSList
*remove_iter
= iter
;
2089 iter
= g_slist_next(iter
);
2091 g_free(remove_iter
->data
);
2092 tab
->events_requests
=
2093 g_slist_remove_link(tab
->events_requests
, remove_iter
);
2095 tab
->events_request_pending
= FALSE
;
2096 tab
->stop_foreground
= TRUE
;
2097 g_idle_remove_by_data(tab
);
2098 g_assert(g_slist_length(tab
->events_requests
) == 0);
2102 /* save will save the traceset to a file
2103 * Not implemented yet FIXME
2106 void save(GtkWidget
* widget
, gpointer user_data
)
2111 void save_as(GtkWidget
* widget
, gpointer user_data
)
2113 g_info("Save as\n");
2117 /* zoom will change the time_window of all the viewers of the
2118 * current tab, and redisplay them. The main functionality is to
2119 * determine the new time_window of the current tab
2122 void zoom(GtkWidget
* widget
, double size
)
2125 TimeInterval time_span
;
2126 TimeWindow new_time_window
;
2127 LttTime current_time
, time_delta
;
2129 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
2131 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2132 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2138 LttvPluginTab
*ptab
;
2139 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
2143 if(size
== 1) return;
2145 ts
= lttvwindow_get_traceset(tab
);
2146 time_span
= lttv_traceset_get_time_span_real(ts
);
2147 new_time_window
= tab
->time_window
;
2148 current_time
= tab
->current_time
;
2150 time_delta
= ltt_time_sub(time_span
.end_time
,time_span
.start_time
);
2152 new_time_window
.start_time
= time_span
.start_time
;
2153 new_time_window
.time_width
= time_delta
;
2154 new_time_window
.time_width_double
= ltt_time_to_double(time_delta
);
2155 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
2156 new_time_window
.time_width
) ;
2158 new_time_window
.time_width
= ltt_time_div(new_time_window
.time_width
, size
);
2159 new_time_window
.time_width_double
=
2160 ltt_time_to_double(new_time_window
.time_width
);
2161 if(ltt_time_compare(new_time_window
.time_width
,time_delta
) > 0)
2162 { /* Case where zoom out is bigger than trace length */
2163 new_time_window
.start_time
= time_span
.start_time
;
2164 new_time_window
.time_width
= time_delta
;
2165 new_time_window
.time_width_double
= ltt_time_to_double(time_delta
);
2166 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
2167 new_time_window
.time_width
) ;
2171 /* Center the image on the current time */
2172 new_time_window
.start_time
=
2173 ltt_time_sub(current_time
,
2174 ltt_time_from_double(new_time_window
.time_width_double
/2.0));
2175 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
2176 new_time_window
.time_width
) ;
2177 /* If on borders, don't fall off */
2178 if(ltt_time_compare(new_time_window
.start_time
, time_span
.start_time
) <0
2179 || ltt_time_compare(new_time_window
.start_time
, time_span
.end_time
) >0)
2181 new_time_window
.start_time
= time_span
.start_time
;
2182 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
2183 new_time_window
.time_width
) ;
2187 if(ltt_time_compare(new_time_window
.end_time
,
2188 time_span
.end_time
) > 0
2189 || ltt_time_compare(new_time_window
.end_time
,
2190 time_span
.start_time
) < 0)
2192 new_time_window
.start_time
=
2193 ltt_time_sub(time_span
.end_time
, new_time_window
.time_width
);
2195 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
2196 new_time_window
.time_width
) ;
2203 if(ltt_time_compare(new_time_window
.time_width
, ltt_time_zero
) == 0) {
2204 g_warning("Zoom more than 1 ns impossible");
2206 time_change_manager(tab
, new_time_window
);
2210 void zoom_in(GtkWidget
* widget
, gpointer user_data
)
2215 void zoom_out(GtkWidget
* widget
, gpointer user_data
)
2220 void zoom_extended(GtkWidget
* widget
, gpointer user_data
)
2225 void go_to_time(GtkWidget
* widget
, gpointer user_data
)
2227 g_info("Go to time\n");
2230 void show_time_frame(GtkWidget
* widget
, gpointer user_data
)
2232 g_info("Show time frame\n");
2236 /* callback function */
2239 on_empty_traceset_activate (GtkMenuItem
*menuitem
,
2242 create_new_window((GtkWidget
*)menuitem
, user_data
, FALSE
);
2247 on_clone_traceset_activate (GtkMenuItem
*menuitem
,
2250 create_new_window((GtkWidget
*)menuitem
, user_data
, TRUE
);
2254 /* create_new_tab calls create_tab to construct a new tab in the main window
2257 LttvPluginTab
*create_new_tab(GtkWidget
* widget
, gpointer user_data
)
2259 gchar label
[PATH_MAX
];
2260 MainWindow
* mw_data
= get_window_data_struct(widget
);
2262 GtkNotebook
* notebook
= (GtkNotebook
*)lookup_widget(widget
, "MNotebook");
2263 if(notebook
== NULL
){
2264 g_info("Notebook does not exist\n");
2267 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2268 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2271 if(!page
|| TRUE
) {
2274 LttvPluginTab
*ptab
;
2275 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
2276 copy_tab
= ptab
->tab
;
2279 strcpy(label
,"Page");
2280 if(get_label(mw_data
, label
,"Get the name of the tab","Please input tab's name")) {
2281 LttvPluginTab
*ptab
;
2283 ptab
= g_object_new(LTTV_TYPE_PLUGIN_TAB
, NULL
);
2284 init_tab (ptab
->tab
, mw_data
, copy_tab
, notebook
, label
);
2285 ptab
->parent
.top_widget
= ptab
->tab
->top_widget
;
2286 g_object_set_data_full(
2287 G_OBJECT(ptab
->tab
->vbox
),
2290 (GDestroyNotify
)tab_destructor
);
2297 on_tab_activate (GtkMenuItem
*menuitem
,
2300 create_new_tab((GtkWidget
*)menuitem
, user_data
);
2305 on_open_activate (GtkMenuItem
*menuitem
,
2308 #ifdef UNFINISHED_FEATURE
2309 open_traceset((GtkWidget
*)menuitem
, user_data
);
2315 on_close_activate (GtkMenuItem
*menuitem
,
2318 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2319 main_window_destructor(mw_data
);
2323 /* remove the current tab from the main window
2327 on_close_tab_activate (GtkWidget
*widget
,
2331 GtkWidget
* notebook
;
2332 notebook
= lookup_widget(widget
, "MNotebook");
2333 if(notebook
== NULL
){
2334 g_info("Notebook does not exist\n");
2338 page_num
= gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
));
2340 gtk_notebook_remove_page(GTK_NOTEBOOK(notebook
), page_num
);
2345 on_close_tab_X_clicked (GtkWidget
*widget
,
2349 GtkWidget
*notebook
= lookup_widget(widget
, "MNotebook");
2350 if(notebook
== NULL
){
2351 g_info("Notebook does not exist\n");
2355 if((page_num
= gtk_notebook_page_num(GTK_NOTEBOOK(notebook
), widget
)) != -1)
2356 gtk_notebook_remove_page(GTK_NOTEBOOK(notebook
), page_num
);
2362 on_add_trace_activate (GtkMenuItem
*menuitem
,
2365 add_trace((GtkWidget
*)menuitem
, user_data
);
2370 on_remove_trace_activate (GtkMenuItem
*menuitem
,
2373 remove_trace((GtkWidget
*)menuitem
, user_data
);
2378 on_save_activate (GtkMenuItem
*menuitem
,
2381 save((GtkWidget
*)menuitem
, user_data
);
2386 on_save_as_activate (GtkMenuItem
*menuitem
,
2389 save_as((GtkWidget
*)menuitem
, user_data
);
2394 on_quit_activate (GtkMenuItem
*menuitem
,
2397 while (g_slist_length(g_main_window_list
) != 0) {
2398 on_MWindow_destroy(((MainWindow
*)g_main_window_list
->data
)->mwindow
,
2405 on_cut_activate (GtkMenuItem
*menuitem
,
2413 on_copy_activate (GtkMenuItem
*menuitem
,
2421 on_paste_activate (GtkMenuItem
*menuitem
,
2429 on_delete_activate (GtkMenuItem
*menuitem
,
2437 on_zoom_in_activate (GtkMenuItem
*menuitem
,
2440 zoom_in((GtkWidget
*)menuitem
, user_data
);
2445 on_zoom_out_activate (GtkMenuItem
*menuitem
,
2448 zoom_out((GtkWidget
*)menuitem
, user_data
);
2453 on_zoom_extended_activate (GtkMenuItem
*menuitem
,
2456 zoom_extended((GtkWidget
*)menuitem
, user_data
);
2461 on_go_to_time_activate (GtkMenuItem
*menuitem
,
2464 go_to_time((GtkWidget
*)menuitem
, user_data
);
2469 on_show_time_frame_activate (GtkMenuItem
*menuitem
,
2472 show_time_frame((GtkWidget
*)menuitem
, user_data
);
2477 on_move_viewer_up_activate (GtkMenuItem
*menuitem
,
2480 move_up_viewer((GtkWidget
*)menuitem
, user_data
);
2485 on_move_viewer_down_activate (GtkMenuItem
*menuitem
,
2488 move_down_viewer((GtkWidget
*)menuitem
, user_data
);
2493 on_remove_viewer_activate (GtkMenuItem
*menuitem
,
2496 delete_viewer((GtkWidget
*)menuitem
, user_data
);
2500 on_trace_facility_activate (GtkMenuItem
*menuitem
,
2503 g_info("Trace facility selector: %s\n", "");
2507 /* Dispaly a file selection dialogue to let user select a library, then call
2508 * lttv_library_load().
2512 on_load_library_activate (GtkMenuItem
*menuitem
,
2515 GError
*error
= NULL
;
2516 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2518 gchar load_module_path_alter
[PATH_MAX
];
2522 gchar
*load_module_path
;
2523 name
= g_ptr_array_new();
2524 nb
= lttv_library_path_number();
2525 /* ask for the library path */
2529 path
= lttv_library_path_get(i
);
2530 g_ptr_array_add(name
, path
);
2533 load_module_path
= get_selection(mw_data
,
2534 (char **)(name
->pdata
), name
->len
,
2535 "Select a library path", "Library paths");
2536 if(load_module_path
!= NULL
)
2537 strncpy(load_module_path_alter
, load_module_path
, PATH_MAX
-1); // -1 for /
2539 g_ptr_array_free(name
, TRUE
);
2541 if(load_module_path
== NULL
) return;
2545 /* Make sure the module path ends with a / */
2546 gchar
*ptr
= load_module_path_alter
;
2548 ptr
= strchr(ptr
, '\0');
2550 if(*(ptr
-1) != '/') {
2557 /* Ask for the library to load : list files in the previously selected
2559 gchar str
[PATH_MAX
];
2562 GtkFileSelection
* file_selector
=
2563 (GtkFileSelection
*)gtk_file_selection_new("Select a module");
2564 gtk_file_selection_set_filename(file_selector
, load_module_path_alter
);
2565 gtk_file_selection_hide_fileop_buttons(file_selector
);
2567 gtk_window_set_transient_for(GTK_WINDOW(file_selector
),
2568 GTK_WINDOW(mw_data
->mwindow
));
2571 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
2573 case GTK_RESPONSE_ACCEPT
:
2574 case GTK_RESPONSE_OK
:
2575 dir
= gtk_file_selection_get_selections (file_selector
);
2576 strncpy(str
,dir
[0],PATH_MAX
);
2577 strncpy(remember_plugins_dir
,dir
[0],PATH_MAX
);
2578 /* only keep file name */
2580 str1
= strrchr(str
,'/');
2583 str1
= strrchr(str
,'\\');
2588 if(*str1
== 'l' && *(str1
+1)== 'i' && *(str1
+2)=='b')
2590 remove info after
. */
2594 str2
= strrchr(str2
, '.');
2595 if(str2
!= NULL
) *str2
= '\0';
2597 lttv_module_require(str1
, &error
);
2599 lttv_library_load(str1
, &error
);
2600 if(error
!= NULL
) g_warning("%s", error
->message
);
2601 else g_info("Load library: %s\n", str
);
2603 case GTK_RESPONSE_REJECT
:
2604 case GTK_RESPONSE_CANCEL
:
2606 gtk_widget_destroy((GtkWidget
*)file_selector
);
2617 /* Display all loaded modules, let user to select a module to unload
2618 * by calling lttv_module_unload
2622 on_unload_library_activate (GtkMenuItem
*menuitem
,
2625 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2627 LttvLibrary
*library
= NULL
;
2632 name
= g_ptr_array_new();
2633 nb
= lttv_library_number();
2634 LttvLibraryInfo
*lib_info
= g_new(LttvLibraryInfo
,nb
);
2635 /* ask for the library name */
2638 LttvLibrary
*iter_lib
= lttv_library_get(i
);
2639 lttv_library_info(iter_lib
, &lib_info
[i
]);
2641 gchar
*path
= lib_info
[i
].name
;
2642 g_ptr_array_add(name
, path
);
2644 lib_name
= get_selection(mw_data
, (char **)(name
->pdata
), name
->len
,
2645 "Select a library", "Libraries");
2646 if(lib_name
!= NULL
) {
2648 if(strcmp(lib_name
, lib_info
[i
].name
) == 0) {
2649 library
= lttv_library_get(i
);
2654 g_ptr_array_free(name
, TRUE
);
2657 if(lib_name
== NULL
) return;
2659 if(library
!= NULL
) lttv_library_unload(library
);
2663 /* Dispaly a file selection dialogue to let user select a module, then call
2664 * lttv_module_require().
2668 on_load_module_activate (GtkMenuItem
*menuitem
,
2671 GError
*error
= NULL
;
2672 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2674 LttvLibrary
*library
= NULL
;
2679 name
= g_ptr_array_new();
2680 nb
= lttv_library_number();
2681 LttvLibraryInfo
*lib_info
= g_new(LttvLibraryInfo
,nb
);
2682 /* ask for the library name */
2685 LttvLibrary
*iter_lib
= lttv_library_get(i
);
2686 lttv_library_info(iter_lib
, &lib_info
[i
]);
2688 gchar
*path
= lib_info
[i
].name
;
2689 g_ptr_array_add(name
, path
);
2691 lib_name
= get_selection(mw_data
,(char **)(name
->pdata
), name
->len
,
2692 "Select a library", "Libraries");
2693 if(lib_name
!= NULL
) {
2695 if(strcmp(lib_name
, lib_info
[i
].name
) == 0) {
2696 library
= lttv_library_get(i
);
2701 g_ptr_array_free(name
, TRUE
);
2704 if(lib_name
== NULL
) return;
2707 //LttvModule *module;
2708 gchar module_name_out
[PATH_MAX
];
2710 /* Ask for the module to load : list modules in the selected lib */
2714 nb
= lttv_library_module_number(library
);
2715 LttvModuleInfo
*module_info
= g_new(LttvModuleInfo
,nb
);
2716 name
= g_ptr_array_new();
2717 /* ask for the module name */
2720 LttvModule
*iter_module
= lttv_library_module_get(library
, i
);
2721 lttv_module_info(iter_module
, &module_info
[i
]);
2723 gchar
*path
= module_info
[i
].name
;
2724 g_ptr_array_add(name
, path
);
2726 module_name
= get_selection(mw_data
, (char **)(name
->pdata
), name
->len
,
2727 "Select a module", "Modules");
2728 if(module_name
!= NULL
) {
2730 if(strcmp(module_name
, module_info
[i
].name
) == 0) {
2731 strncpy(module_name_out
, module_name
, PATH_MAX
);
2732 //module = lttv_library_module_get(i);
2738 g_ptr_array_free(name
, TRUE
);
2739 g_free(module_info
);
2741 if(module_name
== NULL
) return;
2744 lttv_module_require(module_name_out
, &error
);
2745 if(error
!= NULL
) g_warning("%s", error
->message
);
2746 else g_info("Load module: %s", module_name_out
);
2753 gchar str
[PATH_MAX
];
2756 GtkFileSelection
* file_selector
=
2757 (GtkFileSelection
*)gtk_file_selection_new("Select a module");
2758 gtk_file_selection_set_filename(file_selector
, load_module_path_alter
);
2759 gtk_file_selection_hide_fileop_buttons(file_selector
);
2762 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
2764 case GTK_RESPONSE_ACCEPT
:
2765 case GTK_RESPONSE_OK
:
2766 dir
= gtk_file_selection_get_selections (file_selector
);
2767 strncpy(str
,dir
[0],PATH_MAX
);
2768 strncpy(remember_plugins_dir
,dir
[0],PATH_MAX
);
2770 /* only keep file name */
2772 str1
= strrchr(str
,'/');
2775 str1
= strrchr(str
,'\\');
2780 if(*str1
== 'l' && *(str1
+1)== 'i' && *(str1
+2)=='b')
2782 remove info after
. */
2786 str2
= strrchr(str2
, '.');
2787 if(str2
!= NULL
) *str2
= '\0';
2789 lttv_module_require(str1
, &error
);
2791 lttv_library_load(str1
, &error
);
2792 if(error
!= NULL
) g_warning(error
->message
);
2793 else g_info("Load library: %s\n", str
);
2795 case GTK_RESPONSE_REJECT
:
2796 case GTK_RESPONSE_CANCEL
:
2798 gtk_widget_destroy((GtkWidget
*)file_selector
);
2810 /* Display all loaded modules, let user to select a module to unload
2811 * by calling lttv_module_unload
2815 on_unload_module_activate (GtkMenuItem
*menuitem
,
2818 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2820 LttvLibrary
*library
= NULL
;
2825 name
= g_ptr_array_new();
2826 nb
= lttv_library_number();
2827 LttvLibraryInfo
*lib_info
= g_new(LttvLibraryInfo
,nb
);
2828 /* ask for the library name */
2831 LttvLibrary
*iter_lib
= lttv_library_get(i
);
2832 lttv_library_info(iter_lib
, &lib_info
[i
]);
2834 gchar
*path
= lib_info
[i
].name
;
2835 g_ptr_array_add(name
, path
);
2837 lib_name
= get_selection(mw_data
, (char **)(name
->pdata
), name
->len
,
2838 "Select a library", "Libraries");
2839 if(lib_name
!= NULL
) {
2841 if(strcmp(lib_name
, lib_info
[i
].name
) == 0) {
2842 library
= lttv_library_get(i
);
2847 g_ptr_array_free(name
, TRUE
);
2850 if(lib_name
== NULL
) return;
2853 LttvModule
*module
= NULL
;
2855 /* Ask for the module to load : list modules in the selected lib */
2859 nb
= lttv_library_module_number(library
);
2860 LttvModuleInfo
*module_info
= g_new(LttvModuleInfo
,nb
);
2861 name
= g_ptr_array_new();
2862 /* ask for the module name */
2865 LttvModule
*iter_module
= lttv_library_module_get(library
, i
);
2866 lttv_module_info(iter_module
, &module_info
[i
]);
2868 gchar
*path
= module_info
[i
].name
;
2869 if(module_info
[i
].use_count
> 0) g_ptr_array_add(name
, path
);
2871 module_name
= get_selection(mw_data
, (char **)(name
->pdata
), name
->len
,
2872 "Select a module", "Modules");
2873 if(module_name
!= NULL
) {
2875 if(strcmp(module_name
, module_info
[i
].name
) == 0) {
2876 module
= lttv_library_module_get(library
, i
);
2882 g_ptr_array_free(name
, TRUE
);
2883 g_free(module_info
);
2885 if(module_name
== NULL
) return;
2888 LttvModuleInfo module_info
;
2889 lttv_module_info(module
, &module_info
);
2890 g_info("Release module: %s\n", module_info
.name
);
2892 lttv_module_release(module
);
2896 /* Display a directory dialogue to let user select a path for library searching
2900 on_add_library_search_path_activate (GtkMenuItem
*menuitem
,
2903 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2904 //GtkDirSelection * file_selector = (GtkDirSelection *)gtk_dir_selection_new("Select library path");
2905 GtkFileSelection
* file_selector
= (GtkFileSelection
*)gtk_file_selection_new("Select a trace");
2906 gtk_widget_hide( (file_selector
)->file_list
->parent
) ;
2908 gtk_window_set_transient_for(GTK_WINDOW(file_selector
),
2909 GTK_WINDOW(mw_data
->mwindow
));
2914 if(remember_plugins_dir
[0] != '\0')
2915 gtk_file_selection_set_filename(file_selector
, remember_plugins_dir
);
2917 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
2919 case GTK_RESPONSE_ACCEPT
:
2920 case GTK_RESPONSE_OK
:
2921 dir
= gtk_file_selection_get_filename (file_selector
);
2922 strncpy(remember_plugins_dir
,dir
,PATH_MAX
);
2923 strncat(remember_plugins_dir
,"/",PATH_MAX
);
2924 lttv_library_path_add(dir
);
2925 case GTK_RESPONSE_REJECT
:
2926 case GTK_RESPONSE_CANCEL
:
2928 gtk_widget_destroy((GtkWidget
*)file_selector
);
2934 /* Display a directory dialogue to let user select a path for library searching
2938 on_remove_library_search_path_activate (GtkMenuItem
*menuitem
,
2941 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2943 const char *lib_path
;
2947 name
= g_ptr_array_new();
2948 nb
= lttv_library_path_number();
2949 /* ask for the library name */
2952 gchar
*path
= lttv_library_path_get(i
);
2953 g_ptr_array_add(name
, path
);
2955 lib_path
= get_selection(mw_data
, (char **)(name
->pdata
), name
->len
,
2956 "Select a library path", "Library paths");
2958 g_ptr_array_free(name
, TRUE
);
2960 if(lib_path
== NULL
) return;
2963 lttv_library_path_remove(lib_path
);
2967 on_color_activate (GtkMenuItem
*menuitem
,
2975 on_save_configuration_activate (GtkMenuItem
*menuitem
,
2978 g_info("Save configuration\n");
2983 on_content_activate (GtkMenuItem
*menuitem
,
2986 char* filename
= NULL
,
2989 const char* relativePath
= "doc/user/user_guide/html/index.html";
2990 filename
= g_build_filename (g_get_current_dir(), relativePath
, NULL
);
2991 path
= g_strdup_printf ("ghelp://%s", filename
);
2993 screen
= gdk_screen_get_default();
2994 gtk_show_uri (screen
, path
, gtk_get_current_event_time(), NULL
);
2998 g_info("Content\n");
3003 on_about_close_activate (GtkButton
*button
,
3006 GtkWidget
*about_widget
= GTK_WIDGET(user_data
);
3008 gtk_widget_destroy(about_widget
);
3012 on_about_activate (GtkMenuItem
*menuitem
,
3015 MainWindow
*main_window
= get_window_data_struct(GTK_WIDGET(menuitem
));
3016 GtkWidget
*window_widget
= main_window
->mwindow
;
3017 GtkWidget
*about_widget
= gtk_window_new(GTK_WINDOW_TOPLEVEL
);
3018 GtkWindow
*about_window
= GTK_WINDOW(about_widget
);
3020 gtk_window_set_title(about_window
, "About Linux Trace Toolkit");
3022 gtk_window_set_resizable(about_window
, FALSE
);
3023 gtk_window_set_transient_for(about_window
, GTK_WINDOW(window_widget
));
3024 gtk_window_set_destroy_with_parent(about_window
, TRUE
);
3025 gtk_window_set_modal(about_window
, FALSE
);
3027 /* Put the about window at the center of the screen */
3028 gtk_window_set_position(about_window
, GTK_WIN_POS_CENTER_ALWAYS
);
3030 GtkWidget
*vbox
= gtk_vbox_new(FALSE
, 1);
3032 gtk_container_add(GTK_CONTAINER(about_widget
), vbox
);
3035 GtkWidget
*label1
= gtk_label_new("");
3036 gtk_misc_set_padding(GTK_MISC(label1
), 10, 20);
3037 gtk_label_set_markup(GTK_LABEL(label1
), "\
3038 <big>Linux Trace Toolkit " VERSION
"</big>");
3039 gtk_label_set_justify(GTK_LABEL(label1
), GTK_JUSTIFY_CENTER
);
3041 GtkWidget
*label2
= gtk_label_new("");
3042 gtk_misc_set_padding(GTK_MISC(label2
), 10, 20);
3043 gtk_label_set_markup(GTK_LABEL(label2
), "\
3046 Michel Dagenais (New trace format, lttv main)\n\
3047 Mathieu Desnoyers (Kernel Tracer, Directory structure, build with automake/conf,\n\
3048 lttv gui, control flow view, gui cooperative trace reading\n\
3049 scheduler with interruptible foreground and background\n\
3050 computation, detailed event list (rewrite), trace reading\n\
3051 library (rewrite))\n\
3052 Benoit Des Ligneris, Eric Clement (Cluster adaptation, work in progress)\n\
3053 Xang-Xiu Yang (new trace reading library and converter, lttv gui, \n\
3054 detailed event list and statistics view)\n\
3055 Tom Zanussi (RelayFS)\n\
3057 Inspired from the original Linux Trace Toolkit Visualizer made by\n\
3060 GtkWidget
*label3
= gtk_label_new("");
3061 gtk_label_set_markup(GTK_LABEL(label3
), "\
3062 Linux Trace Toolkit Viewer, Copyright (C) 2004, 2005, 2006\n\
3064 Mathieu Desnoyers\n\
3066 Linux Trace Toolkit comes with ABSOLUTELY NO WARRANTY.\n\
3067 This is free software, and you are welcome to redistribute it\n\
3068 under certain conditions. See COPYING for details.");
3069 gtk_misc_set_padding(GTK_MISC(label3
), 10, 20);
3071 gtk_box_pack_start_defaults(GTK_BOX(vbox
), label1
);
3072 gtk_box_pack_start_defaults(GTK_BOX(vbox
), label2
);
3073 gtk_box_pack_start_defaults(GTK_BOX(vbox
), label3
);
3075 GtkWidget
*hbox
= gtk_hbox_new(TRUE
, 0);
3076 gtk_box_pack_end(GTK_BOX(vbox
), hbox
, FALSE
, FALSE
, 0);
3077 GtkWidget
*close_button
= gtk_button_new_with_mnemonic("_Close");
3078 gtk_box_pack_end(GTK_BOX(hbox
), close_button
, FALSE
, FALSE
, 0);
3079 gtk_container_set_border_width(GTK_CONTAINER(close_button
), 20);
3081 g_signal_connect(G_OBJECT(close_button
), "clicked",
3082 G_CALLBACK(on_about_close_activate
),
3083 (gpointer
)about_widget
);
3085 gtk_widget_show_all(about_widget
);
3090 on_button_new_clicked (GtkButton
*button
,
3093 #ifdef BABEL_CLEANUP
3094 create_new_window((GtkWidget
*)button
, user_data
, TRUE
);
3096 GtkWidget
*dialogue
=
3097 gtk_message_dialog_new(
3098 GTK_WINDOW(gtk_widget_get_toplevel(button
)),
3099 GTK_DIALOG_MODAL
|GTK_DIALOG_DESTROY_WITH_PARENT
,
3102 "Opening multiple windows is disabled.");
3103 gtk_dialog_run(GTK_DIALOG(dialogue
));
3104 gtk_widget_destroy(dialogue
);
3109 on_button_new_tab_clicked (GtkButton
*button
,
3112 create_new_tab((GtkWidget
*)button
, user_data
);
3116 on_button_open_clicked (GtkButton
*button
,
3119 #ifdef UNFINISHED_FEATURE
3120 open_traceset((GtkWidget
*)button
, user_data
);
3126 on_button_add_trace_clicked (GtkButton
*button
,
3129 add_trace((GtkWidget
*)button
, user_data
);
3134 on_button_remove_trace_clicked (GtkButton
*button
,
3137 remove_trace((GtkWidget
*)button
, user_data
);
3141 on_button_redraw_clicked (GtkButton
*button
,
3144 redraw((GtkWidget
*)button
, user_data
);
3148 on_button_continue_processing_clicked (GtkButton
*button
,
3151 continue_processing((GtkWidget
*)button
, user_data
);
3155 on_button_stop_processing_clicked (GtkButton
*button
,
3158 stop_processing((GtkWidget
*)button
, user_data
);
3164 on_button_save_clicked (GtkButton
*button
,
3167 save((GtkWidget
*)button
, user_data
);
3172 on_button_save_as_clicked (GtkButton
*button
,
3175 save_as((GtkWidget
*)button
, user_data
);
3180 on_button_zoom_in_clicked (GtkButton
*button
,
3183 zoom_in((GtkWidget
*)button
, user_data
);
3188 on_button_zoom_out_clicked (GtkButton
*button
,
3191 zoom_out((GtkWidget
*)button
, user_data
);
3196 on_button_zoom_extended_clicked (GtkButton
*button
,
3199 zoom_extended((GtkWidget
*)button
, user_data
);
3204 on_button_go_to_time_clicked (GtkButton
*button
,
3207 go_to_time((GtkWidget
*)button
, user_data
);
3212 on_button_show_time_frame_clicked (GtkButton
*button
,
3215 show_time_frame((GtkWidget
*)button
, user_data
);
3220 on_button_move_up_clicked (GtkButton
*button
,
3223 move_up_viewer((GtkWidget
*)button
, user_data
);
3228 on_button_move_down_clicked (GtkButton
*button
,
3231 move_down_viewer((GtkWidget
*)button
, user_data
);
3236 on_button_delete_viewer_clicked (GtkButton
*button
,
3239 delete_viewer((GtkWidget
*)button
, user_data
);
3243 on_MWindow_destroy (GtkWidget
*widget
,
3246 MainWindow
*main_window
= get_window_data_struct(widget
);
3247 LttvIAttribute
*attributes
= main_window
->attributes
;
3248 LttvAttributeValue value
;
3251 //This is unnecessary, since widgets will be destroyed
3252 //by the main window widget anyway.
3253 //remove_all_menu_toolbar_constructors(main_window, NULL);
3255 retval
= lttv_iattribute_find_by_path(attributes
, "viewers/menu",
3256 LTTV_POINTER
, &value
);
3258 lttv_menus_destroy((LttvMenus
*)*(value
.v_pointer
));
3260 retval
= lttv_iattribute_find_by_path(attributes
, "viewers/toolbar",
3261 LTTV_POINTER
, &value
);
3263 lttv_toolbars_destroy((LttvToolbars
*)*(value
.v_pointer
));
3265 g_object_unref(main_window
->attributes
);
3266 g_main_window_list
= g_slist_remove(g_main_window_list
, main_window
);
3268 g_info("There are now : %d windows\n",g_slist_length(g_main_window_list
));
3269 if(g_slist_length(g_main_window_list
) == 0)
3274 on_MWindow_configure (GtkWidget
*widget
,
3275 GdkEventConfigure
*event
,
3278 // MD : removed time width modification upon resizing of the main window.
3279 // The viewers will redraw themselves completely, without time interval
3282 if(mw_data->window_width){
3283 time_span = LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context)->Time_Span ;
3284 time_win = tab->time_window;
3285 ratio = width / mw_data->window_width;
3286 tab->time_window.time_width = ltt_time_mul(time_win.time_width,ratio);
3287 time = ltt_time_sub(time_span->endTime, time_win.start_time);
3288 if(ltt_time_compare(time, tab->time_window.time_width) < 0){
3289 tab->time_window.time_width = time;
3295 mw_data->window_width = (int)width;
3304 on_MNotebook_switch_page (GtkNotebook
*notebook
,
3305 GtkNotebookPage
*page
,
3313 void time_change_manager (Tab
*tab
,
3314 TimeWindow new_time_window
)
3317 /* Only one source of time change */
3318 if(tab
->time_manager_lock
== TRUE
) return;
3320 tab
->time_manager_lock
= TRUE
;
3321 TimeInterval time_span
;
3323 LttvTraceset
*ts
= tab
->traceset_info
->traceset
;
3325 time_span
= lttv_traceset_get_time_span_real(ts
);
3327 LttTime start_time
= new_time_window
.start_time
;
3328 LttTime end_time
= new_time_window
.end_time
;
3330 g_assert(ltt_time_compare(start_time
, end_time
) < 0);
3333 GtkAdjustment
*adjustment
= gtk_range_get_adjustment(GTK_RANGE(tab
->scrollbar
));
3334 LttTime upper
= ltt_time_sub(time_span
.end_time
, time_span
.start_time
);
3337 gtk_range_set_increments(GTK_RANGE(tab
->scrollbar
),
3338 ltt_time_to_double(new_time_window
.time_width
)
3339 / SCROLL_STEP_PER_PAGE
3340 * NANOSECONDS_PER_SECOND
, /* step increment */
3341 ltt_time_to_double(new_time_window
.time_width
)
3342 * NANOSECONDS_PER_SECOND
); /* page increment */
3343 gtk_range_set_range(GTK_RANGE(tab
->scrollbar
),
3345 ltt_time_to_double(upper
)
3346 * NANOSECONDS_PER_SECOND
); /* upper */
3348 g_object_set(G_OBJECT(adjustment
),
3352 ltt_time_to_double(upper
), /* upper */
3354 new_time_window
.time_width_double
3355 / SCROLL_STEP_PER_PAGE
, /* step increment */
3357 new_time_window
.time_width_double
,
3358 /* page increment */
3360 new_time_window
.time_width_double
, /* page size */
3362 gtk_adjustment_changed(adjustment
);
3364 // g_object_set(G_OBJECT(adjustment),
3366 // ltt_time_to_double(
3367 // ltt_time_sub(start_time, time_span.start_time))
3370 //gtk_adjustment_value_changed(adjustment);
3371 gtk_range_set_value(GTK_RANGE(tab
->scrollbar
),
3373 ltt_time_sub(start_time
, time_span
.start_time
)) /* value */);
3375 /* set the time bar. */
3378 timebar_set_minmax_time(TIMEBAR(tab
->MTimebar
),
3379 &time_span
.start_time
,
3380 &time_span
.end_time
);
3381 timebar_set_start_time(TIMEBAR(tab
->MTimebar
),&start_time
);
3382 timebar_set_end_time(TIMEBAR(tab
->MTimebar
),&end_time
);
3386 /* call viewer hooks for new time window */
3387 set_time_window(tab
, &new_time_window
);
3389 tab
->time_manager_lock
= FALSE
;
3398 void current_time_change_manager (Tab
*tab
,
3399 LttTime new_current_time
)
3401 /* Only one source of time change */
3402 if(tab
->current_time_manager_lock
== TRUE
) return;
3404 tab
->current_time_manager_lock
= TRUE
;
3406 timebar_set_current_time(TIMEBAR(tab
->MTimebar
), &new_current_time
);
3408 set_current_time(tab
, &new_current_time
);
3410 tab
->current_time_manager_lock
= FALSE
;
3413 void current_position_change_manager(Tab
*tab
, LttvTracesetPosition
*pos
)
3415 lttv_traceset_seek_to_position( pos
);
3417 LttTime new_time
= lttv_traceset_position_get_time(pos
);
3418 /* Put the context in a state coherent position */
3420 lttv_state_traceset_seek_time_closest(tab
->traceset_info
->traceset
, ltt_time_zero
);
3422 current_time_change_manager(tab
, new_time
);
3424 set_current_position(tab
, pos
);
3427 static void on_timebar_starttime_changed(Timebar
*timebar
,
3430 Tab
*tab
= (Tab
*)user_data
;
3431 LttvTraceset
* ts
=tab
->traceset_info
->traceset
;
3432 TimeInterval time_span
= lttv_traceset_get_time_span_real(ts
);
3434 TimeWindow new_time_window
= tab
->time_window
;
3435 new_time_window
.start_time
= timebar_get_start_time(timebar
);
3437 LttTime end_time
= new_time_window
.end_time
;
3439 /* TODO ybrosseau 2010-12-02: This if should have been checked
3440 by the timebar already */
3441 if(ltt_time_compare(new_time_window
.start_time
, end_time
) >= 0) {
3442 /* Then, we must push back end time : keep the same time width
3443 * if possible, else end traceset time */
3444 end_time
= LTT_TIME_MIN(ltt_time_add(new_time_window
.start_time
,
3445 new_time_window
.time_width
),
3446 time_span
.end_time
);
3449 /* Fix the time width to fit start time and end time */
3450 new_time_window
.time_width
= ltt_time_sub(end_time
,
3451 new_time_window
.start_time
);
3453 new_time_window
.time_width_double
=
3454 ltt_time_to_double(new_time_window
.time_width
);
3456 new_time_window
.end_time
= end_time
;
3458 /* Notify the time_manager */
3459 time_change_manager(tab
, new_time_window
);
3463 static void on_timebar_endtime_changed(Timebar
*timebar
,
3466 Tab
*tab
= (Tab
*)user_data
;
3467 LttvTraceset
* ts
=tab
->traceset_info
->traceset
;
3468 TimeInterval time_span
= lttv_traceset_get_time_span_real(ts
);
3470 TimeWindow new_time_window
= tab
->time_window
;
3472 LttTime end_time
= timebar_get_end_time(timebar
);
3474 /* TODO ybrosseau 2010-12-02: This if should have been
3475 checked by the timebar already */
3476 if(ltt_time_compare(new_time_window
.start_time
, end_time
) >= 0) {
3477 /* Then, we must push front start time : keep the same time
3478 width if possible, else end traceset time */
3479 new_time_window
.start_time
= LTT_TIME_MAX(
3480 ltt_time_sub(end_time
,
3481 new_time_window
.time_width
),
3482 time_span
.start_time
);
3485 /* Fix the time width to fit start time and end time */
3486 new_time_window
.time_width
= ltt_time_sub(end_time
,
3487 new_time_window
.start_time
);
3489 new_time_window
.time_width_double
=
3490 ltt_time_to_double(new_time_window
.time_width
);
3492 new_time_window
.end_time
= end_time
;
3494 /* Notify the time_manager */
3495 time_change_manager(tab
, new_time_window
);
3497 static void on_timebar_currenttime_changed(Timebar
*timebar
,
3500 Tab
*tab
= (Tab
*)user_data
;
3502 LttTime new_current_time
= timebar_get_current_time(timebar
);
3504 current_time_change_manager(tab
, new_current_time
);
3507 void scroll_value_changed_cb(GtkWidget
*scrollbar
,
3510 Tab
*tab
= (Tab
*)user_data
;
3511 TimeWindow new_time_window
;
3513 GtkAdjustment
*adjust
= gtk_range_get_adjustment(GTK_RANGE(scrollbar
));
3514 gdouble value
= gtk_adjustment_get_value(adjust
);
3515 // gdouble upper, lower, ratio, page_size;
3518 LttvTraceset
* ts
= tab
->traceset_info
->traceset
;
3519 TimeInterval time_span
= lttv_traceset_get_time_span_real(ts
);
3521 time
= ltt_time_add(ltt_time_from_double(value
),
3522 time_span
.start_time
);
3524 new_time_window
.start_time
= time
;
3526 page_size
= adjust
->page_size
;
3528 new_time_window
.time_width
=
3529 ltt_time_from_double(page_size
);
3531 new_time_window
.time_width_double
=
3534 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
3535 new_time_window
.time_width
);
3538 time_change_manager(tab
, new_time_window
);
3541 //time_window = tab->time_window;
3543 lower
= adjust
->lower
;
3544 upper
= adjust
->upper
;
3545 ratio
= (value
- lower
) / (upper
- lower
);
3546 g_info("lower %lu, upper %lu, value %lu, ratio %lu", lower
, upper
, value
, ratio
);
3548 //time = ltt_time_sub(time_span->end_time, time_span->start_time);
3549 //time = ltt_time_mul(time, (float)ratio);
3550 //time = ltt_time_add(time_span->start_time, time);
3551 time
= ltt_time_add(ltt_time_from_double(value
),
3552 time_span
.start_time
);
3554 time_window
.start_time
= time
;
3556 page_size
= adjust
->page_size
;
3558 time_window
.time_width
=
3559 ltt_time_from_double(page_size
);
3560 //time = ltt_time_sub(time_span.end_time, time);
3561 //if(ltt_time_compare(time,time_window.time_width) < 0){
3562 // time_window.time_width = time;
3565 /* call viewer hooks for new time window */
3566 set_time_window(tab
, &time_window
);
3572 /* Display a dialogue showing all eventtypes and traces, let user to select the interested
3573 * eventtypes, tracefiles and traces (filter)
3576 /* Select a trace which will be removed from traceset
3579 char * get_remove_trace(MainWindow
*mw_data
,
3580 char ** all_trace_name
, int nb_trace
)
3582 return get_selection(mw_data
, all_trace_name
, nb_trace
,
3583 "Select a trace", "Trace pathname");
3587 /* Select a module which will be loaded
3590 char * get_load_module(MainWindow
*mw_data
,
3591 char ** load_module_name
, int nb_module
)
3593 return get_selection(mw_data
, load_module_name
, nb_module
,
3594 "Select a module to load", "Module name");
3600 /* Select a module which will be unloaded
3603 char * get_unload_module(MainWindow
*mw_data
,
3604 char ** loaded_module_name
, int nb_module
)
3606 return get_selection(mw_data
, loaded_module_name
, nb_module
,
3607 "Select a module to unload", "Module name");
3611 /* Display a dialogue which shows all selectable items, let user to
3612 * select one of them
3615 char * get_selection(MainWindow
*mw_data
,
3616 char ** loaded_module_name
, int nb_module
,
3617 char *title
, char * column_title
)
3619 GtkWidget
* dialogue
;
3620 GtkWidget
* scroll_win
;
3622 GtkListStore
* store
;
3623 GtkTreeViewColumn
* column
;
3624 GtkCellRenderer
* renderer
;
3625 GtkTreeSelection
* select
;
3628 char * unload_module_name
= NULL
;
3630 dialogue
= gtk_dialog_new_with_buttons(title
,
3633 GTK_STOCK_OK
,GTK_RESPONSE_ACCEPT
,
3634 GTK_STOCK_CANCEL
,GTK_RESPONSE_REJECT
,
3636 gtk_window_set_default_size((GtkWindow
*)dialogue
, 500, 200);
3637 gtk_window_set_transient_for(GTK_WINDOW(dialogue
),
3638 GTK_WINDOW(mw_data
->mwindow
));
3640 scroll_win
= gtk_scrolled_window_new (NULL
, NULL
);
3641 gtk_widget_show ( scroll_win
);
3642 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll_win
),
3643 GTK_POLICY_AUTOMATIC
, GTK_POLICY_AUTOMATIC
);
3645 store
= gtk_list_store_new (N_COLUMNS
,G_TYPE_STRING
);
3646 tree
= gtk_tree_view_new_with_model(GTK_TREE_MODEL (store
));
3647 gtk_widget_show ( tree
);
3648 g_object_unref (G_OBJECT (store
));
3650 renderer
= gtk_cell_renderer_text_new ();
3651 column
= gtk_tree_view_column_new_with_attributes (column_title
,
3653 "text", MODULE_COLUMN
,
3655 gtk_tree_view_column_set_alignment (column
, 0.5);
3656 gtk_tree_view_column_set_fixed_width (column
, 150);
3657 gtk_tree_view_append_column (GTK_TREE_VIEW (tree
), column
);
3659 select
= gtk_tree_view_get_selection (GTK_TREE_VIEW (tree
));
3660 gtk_tree_selection_set_mode (select
, GTK_SELECTION_SINGLE
);
3662 gtk_container_add (GTK_CONTAINER (scroll_win
), tree
);
3664 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialogue
)->vbox
), scroll_win
,TRUE
, TRUE
,0);
3666 for(i
=0;i
<nb_module
;i
++){
3667 gtk_list_store_append (store
, &iter
);
3668 gtk_list_store_set (store
, &iter
, MODULE_COLUMN
,loaded_module_name
[i
],-1);
3671 id
= gtk_dialog_run(GTK_DIALOG(dialogue
));
3672 GtkTreeModel
**store_model
= (GtkTreeModel
**)&store
;
3674 case GTK_RESPONSE_ACCEPT
:
3675 case GTK_RESPONSE_OK
:
3676 if (gtk_tree_selection_get_selected (select
, store_model
, &iter
)){
3677 gtk_tree_model_get ((GtkTreeModel
*)store
, &iter
, MODULE_COLUMN
, &unload_module_name
, -1);
3679 case GTK_RESPONSE_REJECT
:
3680 case GTK_RESPONSE_CANCEL
:
3682 gtk_widget_destroy(dialogue
);
3686 return unload_module_name
;
3690 /* Insert all menu entry and tool buttons into this main window
3695 void add_all_menu_toolbar_constructors(MainWindow
* mw
, gpointer user_data
)
3699 lttvwindow_viewer_constructor constructor
;
3700 LttvMenus
* global_menu
, * instance_menu
;
3701 LttvToolbars
* global_toolbar
, * instance_toolbar
;
3702 LttvMenuClosure
*menu_item
;
3703 LttvToolbarClosure
*toolbar_item
;
3704 LttvAttributeValue value
;
3705 LttvIAttribute
*global_attributes
= LTTV_IATTRIBUTE(lttv_global_attributes());
3706 LttvIAttribute
*attributes
= mw
->attributes
;
3707 GtkWidget
* tool_menu_title_menu
, *new_widget
, *pixmap
;
3710 retval
= lttv_iattribute_find_by_path(global_attributes
, "viewers/menu",
3711 LTTV_POINTER
, &value
);
3713 if(*(value
.v_pointer
) == NULL
)
3714 *(value
.v_pointer
) = lttv_menus_new();
3715 global_menu
= (LttvMenus
*)*(value
.v_pointer
);
3717 retval
= lttv_iattribute_find_by_path(attributes
, "viewers/menu",
3718 LTTV_POINTER
, &value
);
3720 if(*(value
.v_pointer
) == NULL
)
3721 *(value
.v_pointer
) = lttv_menus_new();
3722 instance_menu
= (LttvMenus
*)*(value
.v_pointer
);
3724 retval
= lttv_iattribute_find_by_path(global_attributes
, "viewers/toolbar",
3725 LTTV_POINTER
, &value
);
3727 if(*(value
.v_pointer
) == NULL
)
3728 *(value
.v_pointer
) = lttv_toolbars_new();
3729 global_toolbar
= (LttvToolbars
*)*(value
.v_pointer
);
3731 retval
= lttv_iattribute_find_by_path(attributes
, "viewers/toolbar",
3732 LTTV_POINTER
, &value
);
3734 if(*(value
.v_pointer
) == NULL
)
3735 *(value
.v_pointer
) = lttv_toolbars_new();
3736 instance_toolbar
= (LttvToolbars
*)*(value
.v_pointer
);
3738 /* Add missing menu entries to window instance */
3739 for(i
=0;i
<global_menu
->len
;i
++) {
3740 menu_item
= &g_array_index(global_menu
, LttvMenuClosure
, i
);
3742 //add menu_item to window instance;
3743 constructor
= menu_item
->con
;
3744 tool_menu_title_menu
= lookup_widget(mw
->mwindow
,"ToolMenuTitle_menu");
3746 gtk_menu_item_new_with_mnemonic (menu_item
->menu_text
);
3747 gtk_container_add (GTK_CONTAINER (tool_menu_title_menu
),
3749 g_signal_connect ((gpointer
) new_widget
, "activate",
3750 G_CALLBACK (insert_viewer_wrap
),
3752 gtk_widget_show (new_widget
);
3753 lttv_menus_add(instance_menu
, menu_item
->con
,
3754 menu_item
->menu_path
,
3755 menu_item
->menu_text
,
3760 /* Add missing toolbar entries to window instance */
3761 for(i
=0;i
<global_toolbar
->len
;i
++) {
3762 toolbar_item
= &g_array_index(global_toolbar
, LttvToolbarClosure
, i
);
3764 //add toolbar_item to window instance;
3765 constructor
= toolbar_item
->con
;
3766 tool_menu_title_menu
= lookup_widget(mw
->mwindow
,"MToolbar1");
3767 pixbuf
= gdk_pixbuf_new_from_xpm_data((const char**)toolbar_item
->pixmap
);
3768 pixmap
= gtk_image_new_from_pixbuf(pixbuf
);
3770 gtk_toolbar_append_element (GTK_TOOLBAR (tool_menu_title_menu
),
3771 GTK_TOOLBAR_CHILD_BUTTON
,
3774 toolbar_item
->tooltip
, NULL
,
3775 pixmap
, NULL
, NULL
);
3776 gtk_label_set_use_underline(
3777 GTK_LABEL (((GtkToolbarChild
*) (
3778 g_list_last (GTK_TOOLBAR
3779 (tool_menu_title_menu
)->children
)->data
))->label
),
3781 gtk_container_set_border_width (GTK_CONTAINER (new_widget
), 1);
3782 g_signal_connect ((gpointer
) new_widget
,
3784 G_CALLBACK (insert_viewer_wrap
),
3786 gtk_widget_show (new_widget
);
3788 lttv_toolbars_add(instance_toolbar
, toolbar_item
->con
,
3789 toolbar_item
->tooltip
,
3790 toolbar_item
->pixmap
,
3798 /* Create a main window
3801 MainWindow
*construct_main_window(MainWindow
* parent
)
3805 g_debug("construct_main_window()");
3806 GtkWidget
* new_window
; /* New generated main window */
3807 MainWindow
* new_m_window
;/* New main window structure */
3808 GtkNotebook
* notebook
;
3809 LttvIAttribute
*attributes
=
3810 LTTV_IATTRIBUTE(g_object_new(LTTV_ATTRIBUTE_TYPE
, NULL
));
3811 LttvAttributeValue value
;
3813 new_m_window
= g_new(MainWindow
, 1);
3815 // Add the object's information to the module's array
3816 g_main_window_list
= g_slist_append(g_main_window_list
, new_m_window
);
3818 new_window
= create_MWindow();
3819 gtk_widget_show (new_window
);
3821 new_m_window
->mwindow
= new_window
;
3822 new_m_window
->attributes
= attributes
;
3824 retval
= lttv_iattribute_find_by_path(attributes
, "viewers/menu",
3825 LTTV_POINTER
, &value
);
3827 *(value
.v_pointer
) = lttv_menus_new();
3829 retval
= lttv_iattribute_find_by_path(attributes
, "viewers/toolbar",
3830 LTTV_POINTER
, &value
);
3832 *(value
.v_pointer
) = lttv_toolbars_new();
3834 add_all_menu_toolbar_constructors(new_m_window
, NULL
);
3836 g_object_set_data_full(G_OBJECT(new_window
),
3838 (gpointer
)new_m_window
,
3839 (GDestroyNotify
)g_free
);
3840 //create a default tab
3841 notebook
= (GtkNotebook
*)lookup_widget(new_m_window
->mwindow
, "MNotebook");
3842 if(notebook
== NULL
){
3843 g_info("Notebook does not exist\n");
3844 /* FIXME : destroy partially created widgets */
3845 g_free(new_m_window
);
3848 //gtk_notebook_popup_enable (GTK_NOTEBOOK(notebook));
3849 //for now there is no name field in LttvTraceset structure
3850 //Use "Traceset" as the label for the default tab
3852 GtkWidget
* parent_notebook
= lookup_widget(parent
->mwindow
, "MNotebook");
3853 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(parent_notebook
),
3854 gtk_notebook_get_current_page(GTK_NOTEBOOK(parent_notebook
)));
3860 LttvPluginTab
*ptab
;
3861 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
3862 parent_tab
= ptab
->tab
;
3864 LttvPluginTab
*ptab
= g_object_new(LTTV_TYPE_PLUGIN_TAB
, NULL
);
3866 new_m_window
, parent_tab
, notebook
, "Traceset");
3867 ptab
->parent
.top_widget
= ptab
->tab
->top_widget
;
3868 g_object_set_data_full(
3869 G_OBJECT(ptab
->tab
->vbox
),
3872 (GDestroyNotify
)tab_destructor
);
3874 LttvPluginTab
*ptab
= g_object_new(LTTV_TYPE_PLUGIN_TAB
, NULL
);
3875 init_tab(ptab
->tab
, new_m_window
, NULL
, notebook
, "Traceset");
3876 ptab
->parent
.top_widget
= ptab
->tab
->top_widget
;
3877 g_object_set_data_full(
3878 G_OBJECT(ptab
->tab
->vbox
),
3881 (GDestroyNotify
)tab_destructor
);
3884 /* Insert default viewers */
3886 LttvAttributeType type
;
3887 LttvAttributeName name
;
3888 LttvAttributeValue value
;
3889 LttvAttribute
*attribute
;
3891 LttvIAttribute
*attributes_global
=
3892 LTTV_IATTRIBUTE(lttv_global_attributes());
3894 attribute
= LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
3895 LTTV_IATTRIBUTE(attributes_global
),
3896 LTTV_VIEWER_CONSTRUCTORS
));
3897 g_assert(attribute
);
3899 name
= g_quark_from_string("guievents");
3900 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
3902 if(type
== LTTV_POINTER
) {
3903 lttvwindow_viewer_constructor viewer_constructor
=
3904 (lttvwindow_viewer_constructor
)*value
.v_pointer
;
3905 insert_viewer(new_window
, viewer_constructor
);
3908 name
= g_quark_from_string("guicontrolflow");
3909 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
3911 if(type
== LTTV_POINTER
) {
3912 lttvwindow_viewer_constructor viewer_constructor
=
3913 (lttvwindow_viewer_constructor
)*value
.v_pointer
;
3914 insert_viewer(new_window
, viewer_constructor
);
3917 name
= g_quark_from_string("guistatistics");
3918 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
3920 if(type
== LTTV_POINTER
) {
3921 lttvwindow_viewer_constructor viewer_constructor
=
3922 (lttvwindow_viewer_constructor
)*value
.v_pointer
;
3923 insert_viewer(new_window
, viewer_constructor
);
3927 g_info("There are now : %d windows\n",g_slist_length(g_main_window_list
));
3929 return new_m_window
;
3933 /* Free the memory occupied by a tab structure
3937 void tab_destructor(LttvPluginTab
* ptab
)
3939 #ifdef BABEL_CLEANUP
3940 int i
, nb
, ref_count
;
3942 Tab
*tab
= ptab
->tab
;
3945 g_object_unref(tab
->attributes
);
3947 if(tab
->interrupted_state
)
3948 g_object_unref(tab
->interrupted_state
);
3951 if(tab
->traceset_info
->traceset_context
!= NULL
){
3952 //remove state update hooks
3953 lttv_state_remove_event_hooks(
3954 (LttvTracesetState
*)tab
->traceset_info
->
3956 lttv_context_fini(LTTV_TRACESET_CONTEXT(tab
->traceset_info
->
3958 g_object_unref(tab
->traceset_info
->traceset_context
);
3960 if(tab
->traceset_info
->traceset
!= NULL
) {
3961 nb
= lttv_traceset_number(tab
->traceset_info
->traceset
);
3962 for(i
= 0 ; i
< nb
; i
++) {
3963 trace
= lttv_traceset_get(tab
->traceset_info
->traceset
, i
);
3964 ref_count
= lttv_trace_get_ref_number(trace
);
3966 ltt_trace_close(lttv_trace(trace
));
3970 lttv_traceset_destroy(tab
->traceset_info
->traceset
);
3971 /* Remove the idle events requests processing function of the tab */
3972 g_idle_remove_by_data(tab
);
3974 g_slist_free(tab
->events_requests
);
3975 g_free(tab
->traceset_info
);
3977 g_object_unref(ptab
);
3978 #endif /* BABEL_CLEANUP */
3982 /* Create a tab and insert it into the current main window
3985 void init_tab(Tab
*tab
, MainWindow
* mw
, Tab
*copy_tab
,
3986 GtkNotebook
* notebook
, char * label
)
3991 //LttvFilter *filter = NULL;
3993 //create a new tab data structure
3994 //tab = g_new(Tab,1);
3996 //construct and initialize the traceset_info
3997 tab
->traceset_info
= g_new(TracesetInfo
,1);
4000 tab
->traceset_info
->traceset
=
4001 lttv_traceset_copy(copy_tab
->traceset_info
->traceset
);
4003 /* Copy the previous tab's filter */
4004 /* We can clone the filter, as we copy the trace set also */
4005 /* The filter must always be in sync with the trace set */
4007 #ifdef BABEL_CLEANUP
4008 tab
->filter
= lttv_filter_clone(copy_tab
->filter
);
4009 #endif /* BABEL_CLEANUP */
4011 tab
->traceset_info
->traceset
= lttv_traceset_new();
4016 lttv_attribute_write_xml(
4017 lttv_traceset_attribute(tab
->traceset_info
->traceset
),
4023 tab
->time_manager_lock
= FALSE
;
4024 tab
->current_time_manager_lock
= FALSE
;
4025 #ifdef BABEL_CLEANUP
4026 //FIXME copy not implemented in lower level
4027 tab
->traceset_info
->traceset_context
=
4028 g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
4029 //add state update hooks
4030 #endif //BABEL_CLEANUP
4031 lttv_state_add_event_hooks(
4032 tab
->traceset_info
->traceset
);
4034 //determine the current_time and time_window of the tab
4036 if(copy_tab
!= NULL
){
4037 tab
->time_window
= copy_tab
->time_window
;
4038 tab
->current_time
= copy_tab
->current_time
;
4040 tab
->time_window
.start_time
=
4041 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
4042 time_span
.start_time
;
4043 if(DEFAULT_TIME_WIDTH_S
<
4044 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
4045 time_span
.end_time
.tv_sec
)
4046 tmp_time
.tv_sec
= DEFAULT_TIME_WIDTH_S
;
4049 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
4050 time_span
.end_time
.tv_sec
;
4051 tmp_time
.tv_nsec
= 0;
4052 tab
->time_window
.time_width
= tmp_time
;
4053 tab
->current_time
.tv_sec
=
4054 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
4055 time_span
.start_time
.tv_sec
;
4056 tab
->current_time
.tv_nsec
=
4057 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
4058 time_span
.start_time
.tv_nsec
;
4061 tab
->attributes
= LTTV_IATTRIBUTE(g_object_new(LTTV_ATTRIBUTE_TYPE
, NULL
));
4062 tab
->interrupted_state
= g_object_new(LTTV_ATTRIBUTE_TYPE
, NULL
);
4064 tab
->vbox
= gtk_vbox_new(FALSE
, 2);
4065 tab
->top_widget
= tab
->vbox
;
4066 //g_object_set_data_full(G_OBJECT(tab->top_widget), "filter",
4067 // filter, (GDestroyNotify)lttv_filter_destroy);
4069 // g_signal_connect (G_OBJECT(tab->top_widget),
4071 // G_CALLBACK (on_top_notify),
4074 tab
->viewer_container
= gtk_vbox_new(TRUE
, 2);
4075 tab
->scrollbar
= gtk_hscrollbar_new(NULL
);
4076 //tab->multivpaned = gtk_multi_vpaned_new();
4078 gtk_box_pack_start(GTK_BOX(tab
->vbox
),
4079 tab
->viewer_container
,
4081 TRUE
, /* Give the extra space to the child */
4082 0); /* No padding */
4085 // tab->time_window = copy_tab->time_window;
4086 // tab->current_time = copy_tab->current_time;
4089 /* Create the timebar */
4091 tab
->MTimebar
= timebar_new();
4093 gtk_box_pack_end(GTK_BOX(tab
->vbox
),
4095 FALSE
, /* Do not expand */
4096 FALSE
, /* Fill has no effect here (expand false) */
4097 0); /* No padding */
4099 gtk_box_pack_end(GTK_BOX(tab
->vbox
),
4101 FALSE
, /* Do not expand */
4102 FALSE
, /* Fill has no effect here (expand false) */
4103 0); /* No padding */
4105 g_object_set_data(G_OBJECT(tab
->viewer_container
), "focused_viewer", NULL
);
4111 // Display a label with a X
4112 GtkWidget *w_hbox = gtk_hbox_new(FALSE, 4);
4113 GtkWidget *w_label = gtk_label_new (label);
4114 GtkWidget *pixmap = create_pixmap(GTK_WIDGET(notebook), "close.png");
4115 GtkWidget *w_button = gtk_button_new ();
4116 gtk_container_add(GTK_CONTAINER(w_button), pixmap);
4117 //GtkWidget *w_button = gtk_button_new_with_label("x");
4119 gtk_button_set_relief(GTK_BUTTON(w_button), GTK_RELIEF_NONE);
4121 gtk_box_pack_start(GTK_BOX(w_hbox), w_label, TRUE, TRUE, 0);
4122 gtk_box_pack_end(GTK_BOX(w_hbox), w_button, FALSE,
4125 g_signal_connect_swapped (w_button, "clicked",
4126 G_CALLBACK (on_close_tab_X_clicked),
4129 gtk_widget_set_state(w_button, GTK_STATE_ACTIVE);
4131 gtk_widget_show (w_label);
4132 gtk_widget_show (pixmap);
4133 gtk_widget_show (w_button);
4134 gtk_widget_show (w_hbox);
4136 tab->label = w_hbox;
4140 tab
->label
= gtk_label_new (label
);
4142 gtk_widget_show(tab
->label
);
4143 gtk_widget_show(tab
->scrollbar
);
4144 gtk_widget_show(tab
->MTimebar
);
4145 gtk_widget_show(tab
->viewer_container
);
4146 gtk_widget_show(tab
->vbox
);
4148 //gtk_widget_show(tab->multivpaned);
4151 /* Start with empty events requests list */
4152 tab
->events_requests
= NULL
;
4153 tab
->events_request_pending
= FALSE
;
4154 tab
->stop_foreground
= FALSE
;
4158 g_signal_connect(G_OBJECT(tab
->scrollbar
), "value-changed",
4159 G_CALLBACK(scroll_value_changed_cb
), tab
);
4162 /* Timebar signal handler */
4163 g_signal_connect(G_OBJECT(tab
->MTimebar
), "start-time-changed",
4164 G_CALLBACK(on_timebar_starttime_changed
), tab
);
4165 g_signal_connect(G_OBJECT(tab
->MTimebar
), "end-time-changed",
4166 G_CALLBACK(on_timebar_endtime_changed
), tab
);
4167 g_signal_connect(G_OBJECT(tab
->MTimebar
), "current-time-changed",
4168 G_CALLBACK(on_timebar_currenttime_changed
), tab
);
4170 //g_signal_connect(G_OBJECT(tab->scrollbar), "changed",
4171 // G_CALLBACK(scroll_value_changed_cb), tab);
4174 //insert tab into notebook
4175 gtk_notebook_append_page(notebook
,
4178 list
= gtk_container_get_children(GTK_CONTAINER(notebook
));
4179 gtk_notebook_set_current_page(notebook
,g_list_length(list
)-1);
4180 // always show : not if(g_list_length(list)>1)
4181 gtk_notebook_set_show_tabs(notebook
, TRUE
);
4184 lttvwindow_report_time_window(tab
, copy_tab
->time_window
);
4185 lttvwindow_report_current_time(tab
, copy_tab
->current_time
);
4187 TimeWindow time_window
;
4189 time_window
.start_time
= ltt_time_zero
;
4190 time_window
.end_time
= ltt_time_add(time_window
.start_time
,
4191 lttvwindow_default_time_width
);
4192 time_window
.time_width
= lttvwindow_default_time_width
;
4193 time_window
.time_width_double
= ltt_time_to_double(time_window
.time_width
);
4195 lttvwindow_report_time_window(tab
, time_window
);
4196 lttvwindow_report_current_time(tab
, ltt_time_zero
);
4199 LttvTraceset
*traceset
= tab
->traceset_info
->traceset
;
4200 SetTraceset(tab
, traceset
);
4204 * execute_events_requests
4206 * Idle function that executes the pending requests for a tab.
4208 * @return return value : TRUE : keep the idle function, FALSE : remove it.
4210 gboolean
execute_events_requests(Tab
*tab
)
4212 return ( lttvwindow_process_pending_requests(tab
) );
4216 __EXPORT
void create_main_window_with_trace_list(GSList
*traces
)
4219 GSList
*iter
= NULL
;
4222 MainWindow
*mw
= construct_main_window(NULL
);
4223 GtkWidget
*widget
= mw
->mwindow
;
4225 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
4226 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
4227 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
4228 LttvPluginTab
*ptab
;
4232 ptab
= create_new_tab(widget
, NULL
);
4235 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
4239 LttvTraceset
* traceset
= lttv_traceset_new();
4240 for(iter
=traces
; iter
!=NULL
; iter
=g_slist_next(iter
)) {
4241 gchar
*path
= (gchar
*)iter
->data
;
4243 gchar abs_path
[PATH_MAX
];
4246 get_absolute_pathname(path
, abs_path
);
4248 if(lttv_traceset_add_path(traceset
,abs_path
) != 0 ){ /*failure*/
4250 g_warning("cannot open trace %s", abs_path
);
4252 GtkWidget
*dialogue
=
4253 gtk_message_dialog_new(
4254 GTK_WINDOW(gtk_widget_get_toplevel(widget
)),
4255 GTK_DIALOG_MODAL
|GTK_DIALOG_DESTROY_WITH_PARENT
,
4258 "Cannot open trace : maybe you should enter in the directory "
4260 gtk_dialog_run(GTK_DIALOG(dialogue
));
4261 gtk_widget_destroy(dialogue
);
4264 SetTraceset(tab
, traceset
);