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
= traceset
->event_hooks
;
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
;
1051 for(iter
=list_in
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
1052 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1053 /* 1.3.1 If !servicing */
1054 if(events_request
->servicing
== FALSE
) {
1055 /* - begin request hooks called
1056 * - servicing = TRUE
1058 lttv_hooks_call(events_request
->before_request
, (gpointer
)ts
);
1059 events_request
->servicing
= TRUE
;
1061 /* 1.3.2 call before chunk
1062 * 1.3.3 events hooks added
1064 //TODO ybrosseau 2012-07-10: || TRUE added since we only support
1065 // traceset wide requests
1066 if(events_request
->trace
== -1 || TRUE
)
1067 lttv_process_traceset_begin(ts
,
1068 events_request
->before_chunk_traceset
,
1069 events_request
->before_chunk_trace
,
1070 events_request
->event
1073 guint nb_trace
= lttv_traceset_number(ts
);
1074 g_assert((guint
)events_request
->trace
< nb_trace
&&
1075 events_request
->trace
> -1);
1076 LttvTrace
*trace
= lttv_traceset_get(ts
, events_request
->trace
);
1078 lttv_hooks_call(events_request
->before_chunk_traceset
, ts
);
1080 lttv_trace_add_hooks(trace
, 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
,
1386 events_request
->event
);
1390 guint nb_trace
= lttv_traceset_number(ts
);
1391 g_assert(events_request
->trace
< nb_trace
&&
1392 events_request
->trace
> -1);
1393 LttvTrace
*trace
= lttv_traceset_get(ts
, events_request
->trace
);
1395 lttv_trace_remove_hooks(trace
,
1396 events_request
->after_chunk_trace
,
1398 events_request
->event
);
1401 lttv_hooks_call(events_request
->after_chunk_traceset
, ts
);
1404 /* - req.num -= count */
1405 g_assert(events_request
->num_events
>= count
);
1406 events_request
->num_events
-= count
;
1408 //g_assert(tfc != NULL);
1409 /* - if req.num == 0
1411 * current context time >= req.end time
1413 * req.end pos == current pos
1415 * req.stop_flag == TRUE
1417 if( events_request
->num_events
== 0
1419 events_request
->stop_flag
== TRUE
1421 ltt_time_compare(lttv_traceset_get_current_time(ts
),
1422 events_request
->end_time
) >= 0
1424 (events_request
->end_position
!= NULL
1426 lttv_traceset_position_compare_current(ts
,
1427 events_request
->end_position
) == 0)
1430 g_assert(events_request
->servicing
== TRUE
);
1431 /* - Call end request for req
1432 * - remove req from list_in */
1433 lttv_hooks_call(events_request
->after_request
, (gpointer
)ts
);
1434 /* - remove req from list_in */
1435 /* Destroy the request */
1443 GSList
*remove_iter
= iter
;
1445 iter
= g_slist_next(iter
);
1446 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
1447 list_in
= g_slist_remove_link(list_in
, remove_iter
);
1448 } else { // not remove
1449 iter
= g_slist_next(iter
);
1455 /* End of removed servicing loop : leave control to GTK instead. */
1456 // if(gtk_events_pending()) break;
1459 /* B. When interrupted between chunks */
1462 GSList
*iter
= list_in
;
1464 /* 1. for each request in list_in */
1465 while(iter
!= NULL
) {
1467 gboolean remove
= FALSE
;
1468 gboolean free_data
= FALSE
;
1469 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1471 /* 1.1. Use current postition as start position */
1472 if(events_request
->start_position
!= NULL
)
1473 lttv_traceset_destroy_position(events_request
->start_position
);
1474 events_request
->start_position
= lttv_traceset_create_current_position(ts
);
1477 /* 1.2. Remove start time */
1478 events_request
->start_time
= ltt_time_infinite
;
1480 /* 1.3. Move from list_in to list_out */
1483 list_out
= g_slist_append(list_out
, events_request
);
1488 GSList
*remove_iter
= iter
;
1490 iter
= g_slist_next(iter
);
1491 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
1492 list_in
= g_slist_remove_link(list_in
, remove_iter
);
1493 } else { // not remove
1494 iter
= g_slist_next(iter
);
1500 /* C Unlock Traces */
1502 #ifdef BABEL_CLEANUP
1503 lttv_process_traceset_get_sync_data(tsc
);
1505 //lttv_traceset_context_position_save(tsc, sync_position);
1510 iter_trace
<lttv_traceset_number(ts
);
1512 LttvTrace
*trace_v
= lttv_traceset_get(ts
, iter_trace
);
1514 lttvwindowtraces_unlock(trace_v
);
1518 //set the cursor back to normal
1519 gdk_window_set_cursor(win
, NULL
);
1522 g_assert(g_slist_length(list_in
) == 0);
1524 if( g_slist_length(list_out
) == 0 ) {
1525 /* Put tab's request pending flag back to normal */
1526 tab
->events_request_pending
= FALSE
;
1527 g_debug("remove the idle fct");
1528 return FALSE
; /* Remove the idle function */
1530 g_debug("leave the idle fct");
1531 return TRUE
; /* Leave the idle function */
1533 /* We do not use simili-round-robin, it may require to read 1 meg buffers
1534 * again and again if many tracesets use the same tracefiles. */
1535 /* Hack for round-robin idle functions */
1536 /* It will put the idle function at the end of the pool */
1537 /*g_idle_add_full((G_PRIORITY_HIGH_IDLE + 21),
1538 (GSourceFunc)execute_events_requests,
1549 Manage the periodic update of a live trace
1552 live_trace_update_handler(Tab
*tab
)
1554 #ifdef BABEL_CLEANUP
1555 unsigned int updated_count
;
1556 LttvTracesetContext
*tsc
= LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
1557 TimeInterval initial_time_span
= tsc
->time_span
;
1558 TimeInterval updated_time_span
;
1560 updated_count
= lttv_process_traceset_update(tsc
);
1562 /* TODO ybrosseau 2011-01-12: Add trace resynchronization */
1564 /* Get the changed period bounds */
1565 updated_time_span
= tsc
->time_span
;
1567 if(ltt_time_compare(updated_time_span
.start_time
,
1568 initial_time_span
.start_time
) != 0) {
1569 /* The initial time should not change on a live update */
1573 /* Notify viewers (only on updates) */
1574 if(ltt_time_compare(updated_time_span
.end_time
,
1575 initial_time_span
.end_time
) != 0) {
1577 notify_time_span_changed(tab
);
1578 /* TODO ybrosseau 2011-01-12: Change the timebar to register
1579 to the time_span hook */
1580 timebar_set_minmax_time(TIMEBAR(tab
->MTimebar
),
1581 &updated_time_span
.start_time
,
1582 &updated_time_span
.end_time
);
1584 /* To update the min max */
1585 time_change_manager(tab
, tab
->time_window
);
1588 /* Timer will be recalled as long as there is files to update */
1589 return (updated_count
> 0);
1590 #endif /* BABEL_CLEANUP */
1593 static void lttvwindow_add_trace(Tab
*tab
, LttvTrace
*trace_v
)
1595 #ifdef BABEL_CLEANUP
1596 LttvTraceset
*traceset
= tab
->traceset_info
->traceset
;
1598 guint num_traces
= lttv_traceset_number(traceset
);
1600 //Verify if trace is already present.
1601 for(i
=0; i
<num_traces
; i
++)
1603 LttvTrace
* trace
= lttv_traceset_get(traceset
, i
);
1604 if(trace
== trace_v
)
1608 //Keep a reference to the traces so they are not freed.
1609 for(i
=0; i
<lttv_traceset_number(traceset
); i
++)
1611 LttvTrace
* trace
= lttv_traceset_get(traceset
, i
);
1612 lttv_trace_ref(trace
);
1615 //remove state update hooks
1616 lttv_state_remove_event_hooks(
1617 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1619 lttv_context_fini(LTTV_TRACESET_CONTEXT(
1620 tab
->traceset_info
->traceset_context
));
1621 g_object_unref(tab
->traceset_info
->traceset_context
);
1623 lttv_traceset_add(traceset
, trace_v
);
1624 lttv_trace_ref(trace_v
); /* local ref */
1626 /* Create new context */
1627 tab
->traceset_info
->traceset_context
=
1628 g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
1630 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->
1635 //add state update hooks
1636 lttv_state_add_event_hooks(
1637 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1638 //Remove local reference to the traces.
1639 for(i
=0; i
<lttv_traceset_number(traceset
); i
++)
1641 LttvTrace
* trace
= lttv_traceset_get(traceset
, i
);
1642 lttv_trace_unref(trace
);
1646 //add_trace_into_traceset_selector(GTK_MULTIVPANED(tab->multivpaned), lttv_trace(trace_v));
1649 if (lttv_trace(trace_v
)->is_live
) {
1650 /* Add timer for live update */
1651 /* TODO ybrosseau 2011-01-12: Parametrize the hardcoded 1 seconds */
1652 g_timeout_add_seconds (1,
1653 (GSourceFunc
) live_trace_update_handler
,
1656 #endif /* BABEL_CLEANUP */
1659 /* add_trace adds a trace into the current traceset. It first displays a
1660 * directory selection dialogue to let user choose a trace, then recreates
1661 * tracset_context, and redraws all the viewer of the current tab
1664 void add_trace(GtkWidget
* widget
, gpointer user_data
)
1667 LttvTraceset
* traceset
= NULL
;
1669 char abs_path
[PATH_MAX
];
1671 MainWindow
* mw_data
= get_window_data_struct(widget
);
1672 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
1674 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
1675 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
1676 LttvPluginTab
*ptab
;
1680 ptab
= create_new_tab(widget
, NULL
);
1683 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
1686 //TODO fdeslauriers 2012-07-06: Remove this popup when we support multiple traces
1687 traceset
= lttvwindow_get_traceset(tab
);
1688 if(traceset
!= NULL
&& lttv_traceset_number(traceset
) > 0){
1689 GtkWidget
*dialogue
=
1690 gtk_message_dialog_new(
1691 GTK_WINDOW(gtk_widget_get_toplevel(widget
)),
1692 GTK_DIALOG_MODAL
|GTK_DIALOG_DESTROY_WITH_PARENT
,
1695 "Loading multiple traces is not supported at the moment.");
1696 gtk_dialog_run(GTK_DIALOG(dialogue
));
1697 gtk_widget_destroy(dialogue
);
1701 /* Create a new traceset*/
1702 traceset
= lttv_traceset_new();
1703 /* File open dialog management */
1704 #ifdef BABEL_CLEANUP
1705 GtkWidget
*extra_live_button
;
1706 #endif //babel_cleanup
1707 GtkFileChooser
* file_chooser
=
1709 gtk_file_chooser_dialog_new ("Select a trace",
1710 GTK_WINDOW(mw_data
->mwindow
),
1711 GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER
,
1712 GTK_STOCK_CANCEL
, GTK_RESPONSE_CANCEL
,
1713 GTK_STOCK_OPEN
, GTK_RESPONSE_ACCEPT
,
1715 #ifdef BABEL_CLEANUP
1716 /* Button to indicate the opening of a live trace */
1717 extra_live_button
= gtk_check_button_new_with_mnemonic ("Trace is live (currently being writen)");
1718 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (extra_live_button
), FALSE
);
1719 gtk_file_chooser_set_extra_widget (GTK_FILE_CHOOSER (file_chooser
), extra_live_button
);
1720 #endif //babel_cleanup
1721 gtk_file_chooser_set_show_hidden (file_chooser
, TRUE
);
1722 if(remember_trace_dir
[0] != '\0')
1723 gtk_file_chooser_set_filename(file_chooser
, remember_trace_dir
);
1725 gboolean closeFileChooserDialog
= TRUE
;
1729 id
= gtk_dialog_run(GTK_DIALOG(file_chooser
));
1731 case GTK_RESPONSE_ACCEPT
:
1732 case GTK_RESPONSE_OK
:
1733 path
= gtk_file_chooser_get_filename (file_chooser
);
1735 strncpy(remember_trace_dir
, path
, PATH_MAX
);
1736 strncat(remember_trace_dir
, "/", PATH_MAX
);
1737 if(!path
|| strlen(path
) == 0){
1740 get_absolute_pathname(path
, abs_path
);
1742 if(lttv_traceset_add_path(traceset
,abs_path
) != 0 ){ /*failure*/
1744 g_warning("cannot open trace %s", abs_path
);
1745 strncpy(remember_trace_dir
, "\0", PATH_MAX
);
1746 GtkWidget
*dialogue
=
1747 gtk_message_dialog_new(
1748 GTK_WINDOW(gtk_widget_get_toplevel(widget
)),
1749 GTK_DIALOG_MODAL
|GTK_DIALOG_DESTROY_WITH_PARENT
,
1752 "Cannot open trace : maybe you should enter in the directory "
1754 gtk_dialog_run(GTK_DIALOG(dialogue
));
1755 gtk_widget_destroy(dialogue
);
1756 closeFileChooserDialog
= FALSE
;
1759 closeFileChooserDialog
= TRUE
;
1760 SetTraceset(tab
, traceset
);
1763 //update current tab
1764 //update_traceset(mw_data);
1766 // in expose now call_pending_read_hooks(mw_data);
1768 //lttvwindow_report_current_time(mw_data,&(tab->current_time));
1770 case GTK_RESPONSE_REJECT
:
1771 case GTK_RESPONSE_CANCEL
:
1773 closeFileChooserDialog
= TRUE
;
1776 }while(!closeFileChooserDialog
);
1778 gtk_widget_destroy((GtkWidget
*)file_chooser
);
1782 /* remove_trace removes a trace from the current traceset if all viewers in
1783 * the current tab are not interested in the trace. It first displays a
1784 * dialogue, which shows all traces in the current traceset, to let user choose
1785 * a trace, then it checks if all viewers unselect the trace, if it is true,
1786 * it will remove the trace, recreate the traceset_contex,
1787 * and redraws all the viewer of the current tab. If there is on trace in the
1788 * current traceset, it will delete all viewers of the current tab
1790 * It destroys the filter tree. FIXME... we should request for an update
1794 void remove_trace(GtkWidget
*widget
, gpointer user_data
)
1796 #ifdef BABEL_CLEANUP
1798 LttvTrace
* trace_v
;
1799 LttvTraceset
* traceset
;
1800 gint i
, j
, nb_trace
, index
=-1;
1801 char ** name
, *remove_trace_name
;
1802 MainWindow
* mw_data
= get_window_data_struct(widget
);
1803 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
1805 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
1806 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
1812 LttvPluginTab
*ptab
;
1813 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
1817 nb_trace
=lttv_traceset_number(tab
->traceset_info
->traceset
);
1818 name
= g_new(char*,nb_trace
);
1819 for(i
= 0; i
< nb_trace
; i
++){
1820 trace_v
= lttv_traceset_get(tab
->traceset_info
->traceset
, i
);
1821 trace
= lttv_trace(trace_v
);
1822 name
[i
] = (char *) g_quark_to_string(ltt_trace_name(trace
));
1825 remove_trace_name
= get_remove_trace(mw_data
, name
, nb_trace
);
1828 if(remove_trace_name
){
1830 /* yuk, cut n paste from old code.. should be better (MD)*/
1831 for(i
= 0; i
<nb_trace
; i
++) {
1832 if(strcmp(remove_trace_name
,name
[i
]) == 0){
1837 traceset
= tab
->traceset_info
->traceset
;
1838 //Keep a reference to the traces so they are not freed.
1839 for(j
=0; j
<lttv_traceset_number(traceset
); j
++)
1841 LttvTrace
* trace
= lttv_traceset_get(traceset
, j
);
1842 lttv_trace_ref(trace
);
1845 //remove state update hooks
1846 lttv_state_remove_event_hooks(
1847 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1848 lttv_context_fini(LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
));
1849 g_object_unref(tab
->traceset_info
->traceset_context
);
1851 trace_v
= lttv_traceset_get(traceset
, index
);
1853 lttv_traceset_remove(traceset
, index
);
1854 lttv_trace_unref(trace_v
); // Remove local reference
1856 if(lttv_trace_get_ref_number(trace_v
) <= 1) {
1857 /* ref 1 : lttvwindowtraces only*/
1858 ltt_trace_close(lttv_trace(trace_v
));
1859 /* lttvwindowtraces_remove_trace takes care of destroying
1860 * the traceset linked with the trace_v and also of destroying
1861 * the trace_v at the same time.
1863 lttvwindowtraces_remove_trace(trace_v
);
1866 tab
->traceset_info
->traceset_context
=
1867 g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
1869 LTTV_TRACESET_CONTEXT(tab
->
1870 traceset_info
->traceset_context
),traceset
);
1871 //add state update hooks
1872 lttv_state_add_event_hooks(
1873 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1875 //Remove local reference to the traces.
1876 for(j
=0; j
<lttv_traceset_number(traceset
); j
++)
1878 LttvTrace
* trace
= lttv_traceset_get(traceset
, j
);
1879 lttv_trace_unref(trace
);
1882 SetTraceset(tab
, (gpointer
)traceset
);
1885 #endif /* BABEL_CLEANUP */
1889 void remove_trace(GtkWidget
* widget
, gpointer user_data
)
1892 LttvTrace
* trace_v
;
1893 LttvTraceset
* traceset
;
1894 gint i
, j
, nb_trace
;
1895 char ** name
, *remove_trace_name
;
1896 MainWindow
* mw_data
= get_window_data_struct(widget
);
1897 LttvTracesetSelector
* s
;
1898 LttvTraceSelector
* t
;
1901 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
1903 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
1904 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
1910 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
1913 nb_trace
=lttv_traceset_number(tab
->traceset_info
->traceset
);
1914 name
= g_new(char*,nb_trace
);
1915 for(i
= 0; i
< nb_trace
; i
++){
1916 trace_v
= lttv_traceset_get(tab
->traceset_info
->traceset
, i
);
1917 trace
= lttv_trace(trace_v
);
1918 name
[i
] = ltt_trace_name(trace
);
1921 remove_trace_name
= get_remove_trace(name
, nb_trace
);
1923 if(remove_trace_name
){
1924 for(i
=0; i
<nb_trace
; i
++){
1925 if(strcmp(remove_trace_name
,name
[i
]) == 0){
1926 //unselect the trace from the current viewer
1928 w
= gtk_multivpaned_get_widget(GTK_MULTIVPANED(tab
->multivpaned
));
1930 s
= g_object_get_data(G_OBJECT(w
), "Traceset_Selector");
1932 t
= lttv_traceset_selector_trace_get(s
,i
);
1933 lttv_trace_selector_set_selected(t
, FALSE
);
1936 //check if other viewers select the trace
1937 w
= gtk_multivpaned_get_first_widget(GTK_MULTIVPANED(tab
->multivpaned
));
1939 s
= g_object_get_data(G_OBJECT(w
), "Traceset_Selector");
1941 t
= lttv_traceset_selector_trace_get(s
,i
);
1942 selected
= lttv_trace_selector_get_selected(t
);
1945 w
= gtk_multivpaned_get_next_widget(GTK_MULTIVPANED(tab
->multivpaned
));
1947 }else selected
= FALSE
;
1949 //if no viewer selects the trace, remove it
1951 remove_trace_from_traceset_selector(GTK_MULTIVPANED(tab
->multivpaned
), i
);
1953 traceset
= tab
->traceset_info
->traceset
;
1954 //Keep a reference to the traces so they are not freed.
1955 for(j
=0; j
<lttv_traceset_number(traceset
); j
++)
1957 LttvTrace
* trace
= lttv_traceset_get(traceset
, j
);
1958 lttv_trace_ref(trace
);
1961 //remove state update hooks
1962 lttv_state_remove_event_hooks(
1963 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1964 lttv_context_fini(LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
));
1965 g_object_unref(tab
->traceset_info
->traceset_context
);
1968 trace_v
= lttv_traceset_get(traceset
, i
);
1970 if(lttv_trace_get_ref_number(trace_v
) <= 2) {
1971 /* ref 2 : traceset, local */
1972 lttvwindowtraces_remove_trace(trace_v
);
1973 ltt_trace_close(lttv_trace(trace_v
));
1976 lttv_traceset_remove(traceset
, i
);
1977 lttv_trace_unref(trace_v
); // Remove local reference
1979 if(!lttv_trace_get_ref_number(trace_v
))
1980 lttv_trace_destroy(trace_v
);
1982 tab
->traceset_info
->traceset_context
=
1983 g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
1985 LTTV_TRACESET_CONTEXT(tab
->
1986 traceset_info
->traceset_context
),traceset
);
1987 //add state update hooks
1988 lttv_state_add_event_hooks(
1989 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1991 //Remove local reference to the traces.
1992 for(j
=0; j
<lttv_traceset_number(traceset
); j
++)
1994 LttvTrace
* trace
= lttv_traceset_get(traceset
, j
);
1995 lttv_trace_unref(trace
);
1999 //update current tab
2000 //update_traceset(mw_data);
2003 SetTraceset(tab
, (gpointer
)traceset
);
2004 // in expose now call_pending_read_hooks(mw_data);
2006 //lttvwindow_report_current_time(mw_data,&(tab->current_time));
2009 // while(tab->multi_vpaned->num_children){
2010 // gtk_multi_vpaned_widget_delete(tab->multi_vpaned);
2024 /* Redraw all the viewers in the current tab */
2025 void redraw(GtkWidget
*widget
, gpointer user_data
)
2027 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
2028 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2029 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2036 LttvPluginTab
*ptab
;
2037 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
2042 LttvAttributeValue value
;
2044 retval
= lttv_iattribute_find_by_path(tab
->attributes
, "hooks/redraw", LTTV_POINTER
, &value
);
2047 tmp
= (LttvHooks
*)*(value
.v_pointer
);
2049 lttv_hooks_call(tmp
,NULL
);
2053 void continue_processing(GtkWidget
*widget
, gpointer user_data
)
2055 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
2056 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2057 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2064 LttvPluginTab
*ptab
;
2065 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
2070 LttvAttributeValue value
;
2072 retval
= lttv_iattribute_find_by_path(tab
->attributes
, "hooks/continue",
2073 LTTV_POINTER
, &value
);
2076 tmp
= (LttvHooks
*)*(value
.v_pointer
);
2078 lttv_hooks_call(tmp
,NULL
);
2081 /* Stop the processing for the calling main window's current tab.
2082 * It removes every processing requests that are in its list. It does not call
2083 * the end request hooks, because the request is not finished.
2086 void stop_processing(GtkWidget
*widget
, gpointer user_data
)
2088 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
2089 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2090 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2095 LttvPluginTab
*ptab
;
2096 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
2099 GSList
*iter
= tab
->events_requests
;
2101 while(iter
!= NULL
) {
2102 GSList
*remove_iter
= iter
;
2103 iter
= g_slist_next(iter
);
2105 g_free(remove_iter
->data
);
2106 tab
->events_requests
=
2107 g_slist_remove_link(tab
->events_requests
, remove_iter
);
2109 tab
->events_request_pending
= FALSE
;
2110 tab
->stop_foreground
= TRUE
;
2111 g_idle_remove_by_data(tab
);
2112 g_assert(g_slist_length(tab
->events_requests
) == 0);
2116 /* save will save the traceset to a file
2117 * Not implemented yet FIXME
2120 void save(GtkWidget
* widget
, gpointer user_data
)
2125 void save_as(GtkWidget
* widget
, gpointer user_data
)
2127 g_info("Save as\n");
2131 /* zoom will change the time_window of all the viewers of the
2132 * current tab, and redisplay them. The main functionality is to
2133 * determine the new time_window of the current tab
2136 void zoom(GtkWidget
* widget
, double size
)
2139 TimeInterval time_span
;
2140 TimeWindow new_time_window
;
2141 LttTime current_time
, time_delta
;
2143 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
2145 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2146 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2152 LttvPluginTab
*ptab
;
2153 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
2157 if(size
== 1) return;
2159 ts
= lttvwindow_get_traceset(tab
);
2160 time_span
= lttv_traceset_get_time_span_real(ts
);
2161 new_time_window
= tab
->time_window
;
2162 current_time
= tab
->current_time
;
2164 time_delta
= ltt_time_sub(time_span
.end_time
,time_span
.start_time
);
2166 new_time_window
.start_time
= time_span
.start_time
;
2167 new_time_window
.time_width
= time_delta
;
2168 new_time_window
.time_width_double
= ltt_time_to_double(time_delta
);
2169 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
2170 new_time_window
.time_width
) ;
2172 new_time_window
.time_width
= ltt_time_div(new_time_window
.time_width
, size
);
2173 new_time_window
.time_width_double
=
2174 ltt_time_to_double(new_time_window
.time_width
);
2175 if(ltt_time_compare(new_time_window
.time_width
,time_delta
) > 0)
2176 { /* Case where zoom out is bigger than trace length */
2177 new_time_window
.start_time
= time_span
.start_time
;
2178 new_time_window
.time_width
= time_delta
;
2179 new_time_window
.time_width_double
= ltt_time_to_double(time_delta
);
2180 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
2181 new_time_window
.time_width
) ;
2185 /* Center the image on the current time */
2186 new_time_window
.start_time
=
2187 ltt_time_sub(current_time
,
2188 ltt_time_from_double(new_time_window
.time_width_double
/2.0));
2189 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
2190 new_time_window
.time_width
) ;
2191 /* If on borders, don't fall off */
2192 if(ltt_time_compare(new_time_window
.start_time
, time_span
.start_time
) <0
2193 || ltt_time_compare(new_time_window
.start_time
, time_span
.end_time
) >0)
2195 new_time_window
.start_time
= time_span
.start_time
;
2196 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
2197 new_time_window
.time_width
) ;
2201 if(ltt_time_compare(new_time_window
.end_time
,
2202 time_span
.end_time
) > 0
2203 || ltt_time_compare(new_time_window
.end_time
,
2204 time_span
.start_time
) < 0)
2206 new_time_window
.start_time
=
2207 ltt_time_sub(time_span
.end_time
, new_time_window
.time_width
);
2209 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
2210 new_time_window
.time_width
) ;
2217 if(ltt_time_compare(new_time_window
.time_width
, ltt_time_zero
) == 0) {
2218 g_warning("Zoom more than 1 ns impossible");
2220 time_change_manager(tab
, new_time_window
);
2224 void zoom_in(GtkWidget
* widget
, gpointer user_data
)
2229 void zoom_out(GtkWidget
* widget
, gpointer user_data
)
2234 void zoom_extended(GtkWidget
* widget
, gpointer user_data
)
2239 void go_to_time(GtkWidget
* widget
, gpointer user_data
)
2241 g_info("Go to time\n");
2244 void show_time_frame(GtkWidget
* widget
, gpointer user_data
)
2246 g_info("Show time frame\n");
2250 /* callback function */
2253 on_empty_traceset_activate (GtkMenuItem
*menuitem
,
2256 create_new_window((GtkWidget
*)menuitem
, user_data
, FALSE
);
2261 on_clone_traceset_activate (GtkMenuItem
*menuitem
,
2264 create_new_window((GtkWidget
*)menuitem
, user_data
, TRUE
);
2268 /* create_new_tab calls create_tab to construct a new tab in the main window
2271 LttvPluginTab
*create_new_tab(GtkWidget
* widget
, gpointer user_data
)
2273 gchar label
[PATH_MAX
];
2274 MainWindow
* mw_data
= get_window_data_struct(widget
);
2276 GtkNotebook
* notebook
= (GtkNotebook
*)lookup_widget(widget
, "MNotebook");
2277 if(notebook
== NULL
){
2278 g_info("Notebook does not exist\n");
2281 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2282 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2288 LttvPluginTab
*ptab
;
2289 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
2290 copy_tab
= ptab
->tab
;
2293 strcpy(label
,"Page");
2294 if(get_label(mw_data
, label
,"Get the name of the tab","Please input tab's name")) {
2295 LttvPluginTab
*ptab
;
2297 ptab
= g_object_new(LTTV_TYPE_PLUGIN_TAB
, NULL
);
2298 init_tab (ptab
->tab
, mw_data
, copy_tab
, notebook
, label
);
2299 ptab
->parent
.top_widget
= ptab
->tab
->top_widget
;
2300 g_object_set_data_full(
2301 G_OBJECT(ptab
->tab
->vbox
),
2304 (GDestroyNotify
)tab_destructor
);
2311 on_tab_activate (GtkMenuItem
*menuitem
,
2314 create_new_tab((GtkWidget
*)menuitem
, user_data
);
2319 on_open_activate (GtkMenuItem
*menuitem
,
2322 #ifdef UNFINISHED_FEATURE
2323 open_traceset((GtkWidget
*)menuitem
, user_data
);
2329 on_close_activate (GtkMenuItem
*menuitem
,
2332 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2333 main_window_destructor(mw_data
);
2337 /* remove the current tab from the main window
2341 on_close_tab_activate (GtkWidget
*widget
,
2345 GtkWidget
* notebook
;
2346 notebook
= lookup_widget(widget
, "MNotebook");
2347 if(notebook
== NULL
){
2348 g_info("Notebook does not exist\n");
2352 page_num
= gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
));
2354 gtk_notebook_remove_page(GTK_NOTEBOOK(notebook
), page_num
);
2359 on_close_tab_X_clicked (GtkWidget
*widget
,
2363 GtkWidget
*notebook
= lookup_widget(widget
, "MNotebook");
2364 if(notebook
== NULL
){
2365 g_info("Notebook does not exist\n");
2369 if((page_num
= gtk_notebook_page_num(GTK_NOTEBOOK(notebook
), widget
)) != -1)
2370 gtk_notebook_remove_page(GTK_NOTEBOOK(notebook
), page_num
);
2376 on_add_trace_activate (GtkMenuItem
*menuitem
,
2379 add_trace((GtkWidget
*)menuitem
, user_data
);
2384 on_remove_trace_activate (GtkMenuItem
*menuitem
,
2387 remove_trace((GtkWidget
*)menuitem
, user_data
);
2392 on_save_activate (GtkMenuItem
*menuitem
,
2395 save((GtkWidget
*)menuitem
, user_data
);
2400 on_save_as_activate (GtkMenuItem
*menuitem
,
2403 save_as((GtkWidget
*)menuitem
, user_data
);
2408 on_quit_activate (GtkMenuItem
*menuitem
,
2411 while (g_slist_length(g_main_window_list
) != 0) {
2412 on_MWindow_destroy(((MainWindow
*)g_main_window_list
->data
)->mwindow
,
2419 on_cut_activate (GtkMenuItem
*menuitem
,
2427 on_copy_activate (GtkMenuItem
*menuitem
,
2435 on_paste_activate (GtkMenuItem
*menuitem
,
2443 on_delete_activate (GtkMenuItem
*menuitem
,
2451 on_zoom_in_activate (GtkMenuItem
*menuitem
,
2454 zoom_in((GtkWidget
*)menuitem
, user_data
);
2459 on_zoom_out_activate (GtkMenuItem
*menuitem
,
2462 zoom_out((GtkWidget
*)menuitem
, user_data
);
2467 on_zoom_extended_activate (GtkMenuItem
*menuitem
,
2470 zoom_extended((GtkWidget
*)menuitem
, user_data
);
2475 on_go_to_time_activate (GtkMenuItem
*menuitem
,
2478 go_to_time((GtkWidget
*)menuitem
, user_data
);
2483 on_show_time_frame_activate (GtkMenuItem
*menuitem
,
2486 show_time_frame((GtkWidget
*)menuitem
, user_data
);
2491 on_move_viewer_up_activate (GtkMenuItem
*menuitem
,
2494 move_up_viewer((GtkWidget
*)menuitem
, user_data
);
2499 on_move_viewer_down_activate (GtkMenuItem
*menuitem
,
2502 move_down_viewer((GtkWidget
*)menuitem
, user_data
);
2507 on_remove_viewer_activate (GtkMenuItem
*menuitem
,
2510 delete_viewer((GtkWidget
*)menuitem
, user_data
);
2514 on_trace_facility_activate (GtkMenuItem
*menuitem
,
2517 g_info("Trace facility selector: %s\n", "");
2521 /* Dispaly a file selection dialogue to let user select a library, then call
2522 * lttv_library_load().
2526 on_load_library_activate (GtkMenuItem
*menuitem
,
2529 GError
*error
= NULL
;
2530 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2532 gchar load_module_path_alter
[PATH_MAX
];
2536 gchar
*load_module_path
;
2537 name
= g_ptr_array_new();
2538 nb
= lttv_library_path_number();
2539 /* ask for the library path */
2543 path
= lttv_library_path_get(i
);
2544 g_ptr_array_add(name
, path
);
2547 load_module_path
= get_selection(mw_data
,
2548 (char **)(name
->pdata
), name
->len
,
2549 "Select a library path", "Library paths");
2550 if(load_module_path
!= NULL
)
2551 strncpy(load_module_path_alter
, load_module_path
, PATH_MAX
-1); // -1 for /
2553 g_ptr_array_free(name
, TRUE
);
2555 if(load_module_path
== NULL
) return;
2559 /* Make sure the module path ends with a / */
2560 gchar
*ptr
= load_module_path_alter
;
2562 ptr
= strchr(ptr
, '\0');
2564 if(*(ptr
-1) != '/') {
2571 /* Ask for the library to load : list files in the previously selected
2573 gchar str
[PATH_MAX
];
2576 GtkFileSelection
* file_selector
=
2577 (GtkFileSelection
*)gtk_file_selection_new("Select a module");
2578 gtk_file_selection_set_filename(file_selector
, load_module_path_alter
);
2579 gtk_file_selection_hide_fileop_buttons(file_selector
);
2581 gtk_window_set_transient_for(GTK_WINDOW(file_selector
),
2582 GTK_WINDOW(mw_data
->mwindow
));
2585 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
2587 case GTK_RESPONSE_ACCEPT
:
2588 case GTK_RESPONSE_OK
:
2589 dir
= gtk_file_selection_get_selections (file_selector
);
2590 strncpy(str
,dir
[0],PATH_MAX
);
2591 strncpy(remember_plugins_dir
,dir
[0],PATH_MAX
);
2592 /* only keep file name */
2594 str1
= strrchr(str
,'/');
2597 str1
= strrchr(str
,'\\');
2602 if(*str1
== 'l' && *(str1
+1)== 'i' && *(str1
+2)=='b')
2604 remove info after
. */
2608 str2
= strrchr(str2
, '.');
2609 if(str2
!= NULL
) *str2
= '\0';
2611 lttv_module_require(str1
, &error
);
2613 lttv_library_load(str1
, &error
);
2614 if(error
!= NULL
) g_warning("%s", error
->message
);
2615 else g_info("Load library: %s\n", str
);
2617 case GTK_RESPONSE_REJECT
:
2618 case GTK_RESPONSE_CANCEL
:
2620 gtk_widget_destroy((GtkWidget
*)file_selector
);
2631 /* Display all loaded modules, let user to select a module to unload
2632 * by calling lttv_module_unload
2636 on_unload_library_activate (GtkMenuItem
*menuitem
,
2639 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2641 LttvLibrary
*library
= NULL
;
2646 name
= g_ptr_array_new();
2647 nb
= lttv_library_number();
2648 LttvLibraryInfo
*lib_info
= g_new(LttvLibraryInfo
,nb
);
2649 /* ask for the library name */
2652 LttvLibrary
*iter_lib
= lttv_library_get(i
);
2653 lttv_library_info(iter_lib
, &lib_info
[i
]);
2655 gchar
*path
= lib_info
[i
].name
;
2656 g_ptr_array_add(name
, path
);
2658 lib_name
= get_selection(mw_data
, (char **)(name
->pdata
), name
->len
,
2659 "Select a library", "Libraries");
2660 if(lib_name
!= NULL
) {
2662 if(strcmp(lib_name
, lib_info
[i
].name
) == 0) {
2663 library
= lttv_library_get(i
);
2668 g_ptr_array_free(name
, TRUE
);
2671 if(lib_name
== NULL
) return;
2673 if(library
!= NULL
) lttv_library_unload(library
);
2677 /* Dispaly a file selection dialogue to let user select a module, then call
2678 * lttv_module_require().
2682 on_load_module_activate (GtkMenuItem
*menuitem
,
2685 GError
*error
= NULL
;
2686 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2688 LttvLibrary
*library
= NULL
;
2693 name
= g_ptr_array_new();
2694 nb
= lttv_library_number();
2695 LttvLibraryInfo
*lib_info
= g_new(LttvLibraryInfo
,nb
);
2696 /* ask for the library name */
2699 LttvLibrary
*iter_lib
= lttv_library_get(i
);
2700 lttv_library_info(iter_lib
, &lib_info
[i
]);
2702 gchar
*path
= lib_info
[i
].name
;
2703 g_ptr_array_add(name
, path
);
2705 lib_name
= get_selection(mw_data
,(char **)(name
->pdata
), name
->len
,
2706 "Select a library", "Libraries");
2707 if(lib_name
!= NULL
) {
2709 if(strcmp(lib_name
, lib_info
[i
].name
) == 0) {
2710 library
= lttv_library_get(i
);
2715 g_ptr_array_free(name
, TRUE
);
2718 if(lib_name
== NULL
) return;
2721 //LttvModule *module;
2722 gchar module_name_out
[PATH_MAX
];
2724 /* Ask for the module to load : list modules in the selected lib */
2728 nb
= lttv_library_module_number(library
);
2729 LttvModuleInfo
*module_info
= g_new(LttvModuleInfo
,nb
);
2730 name
= g_ptr_array_new();
2731 /* ask for the module name */
2734 LttvModule
*iter_module
= lttv_library_module_get(library
, i
);
2735 lttv_module_info(iter_module
, &module_info
[i
]);
2737 gchar
*path
= module_info
[i
].name
;
2738 g_ptr_array_add(name
, path
);
2740 module_name
= get_selection(mw_data
, (char **)(name
->pdata
), name
->len
,
2741 "Select a module", "Modules");
2742 if(module_name
!= NULL
) {
2744 if(strcmp(module_name
, module_info
[i
].name
) == 0) {
2745 strncpy(module_name_out
, module_name
, PATH_MAX
);
2746 //module = lttv_library_module_get(i);
2752 g_ptr_array_free(name
, TRUE
);
2753 g_free(module_info
);
2755 if(module_name
== NULL
) return;
2758 lttv_module_require(module_name_out
, &error
);
2759 if(error
!= NULL
) g_warning("%s", error
->message
);
2760 else g_info("Load module: %s", module_name_out
);
2767 gchar str
[PATH_MAX
];
2770 GtkFileSelection
* file_selector
=
2771 (GtkFileSelection
*)gtk_file_selection_new("Select a module");
2772 gtk_file_selection_set_filename(file_selector
, load_module_path_alter
);
2773 gtk_file_selection_hide_fileop_buttons(file_selector
);
2776 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
2778 case GTK_RESPONSE_ACCEPT
:
2779 case GTK_RESPONSE_OK
:
2780 dir
= gtk_file_selection_get_selections (file_selector
);
2781 strncpy(str
,dir
[0],PATH_MAX
);
2782 strncpy(remember_plugins_dir
,dir
[0],PATH_MAX
);
2784 /* only keep file name */
2786 str1
= strrchr(str
,'/');
2789 str1
= strrchr(str
,'\\');
2794 if(*str1
== 'l' && *(str1
+1)== 'i' && *(str1
+2)=='b')
2796 remove info after
. */
2800 str2
= strrchr(str2
, '.');
2801 if(str2
!= NULL
) *str2
= '\0';
2803 lttv_module_require(str1
, &error
);
2805 lttv_library_load(str1
, &error
);
2806 if(error
!= NULL
) g_warning(error
->message
);
2807 else g_info("Load library: %s\n", str
);
2809 case GTK_RESPONSE_REJECT
:
2810 case GTK_RESPONSE_CANCEL
:
2812 gtk_widget_destroy((GtkWidget
*)file_selector
);
2824 /* Display all loaded modules, let user to select a module to unload
2825 * by calling lttv_module_unload
2829 on_unload_module_activate (GtkMenuItem
*menuitem
,
2832 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2834 LttvLibrary
*library
= NULL
;
2839 name
= g_ptr_array_new();
2840 nb
= lttv_library_number();
2841 LttvLibraryInfo
*lib_info
= g_new(LttvLibraryInfo
,nb
);
2842 /* ask for the library name */
2845 LttvLibrary
*iter_lib
= lttv_library_get(i
);
2846 lttv_library_info(iter_lib
, &lib_info
[i
]);
2848 gchar
*path
= lib_info
[i
].name
;
2849 g_ptr_array_add(name
, path
);
2851 lib_name
= get_selection(mw_data
, (char **)(name
->pdata
), name
->len
,
2852 "Select a library", "Libraries");
2853 if(lib_name
!= NULL
) {
2855 if(strcmp(lib_name
, lib_info
[i
].name
) == 0) {
2856 library
= lttv_library_get(i
);
2861 g_ptr_array_free(name
, TRUE
);
2864 if(lib_name
== NULL
) return;
2867 LttvModule
*module
= NULL
;
2869 /* Ask for the module to load : list modules in the selected lib */
2873 nb
= lttv_library_module_number(library
);
2874 LttvModuleInfo
*module_info
= g_new(LttvModuleInfo
,nb
);
2875 name
= g_ptr_array_new();
2876 /* ask for the module name */
2879 LttvModule
*iter_module
= lttv_library_module_get(library
, i
);
2880 lttv_module_info(iter_module
, &module_info
[i
]);
2882 gchar
*path
= module_info
[i
].name
;
2883 if(module_info
[i
].use_count
> 0) g_ptr_array_add(name
, path
);
2885 module_name
= get_selection(mw_data
, (char **)(name
->pdata
), name
->len
,
2886 "Select a module", "Modules");
2887 if(module_name
!= NULL
) {
2889 if(strcmp(module_name
, module_info
[i
].name
) == 0) {
2890 module
= lttv_library_module_get(library
, i
);
2896 g_ptr_array_free(name
, TRUE
);
2897 g_free(module_info
);
2899 if(module_name
== NULL
) return;
2902 LttvModuleInfo module_info
;
2903 lttv_module_info(module
, &module_info
);
2904 g_info("Release module: %s\n", module_info
.name
);
2906 lttv_module_release(module
);
2910 /* Display a directory dialogue to let user select a path for library searching
2914 on_add_library_search_path_activate (GtkMenuItem
*menuitem
,
2917 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2918 //GtkDirSelection * file_selector = (GtkDirSelection *)gtk_dir_selection_new("Select library path");
2919 GtkFileSelection
* file_selector
= (GtkFileSelection
*)gtk_file_selection_new("Select a trace");
2920 gtk_widget_hide( (file_selector
)->file_list
->parent
) ;
2922 gtk_window_set_transient_for(GTK_WINDOW(file_selector
),
2923 GTK_WINDOW(mw_data
->mwindow
));
2928 if(remember_plugins_dir
[0] != '\0')
2929 gtk_file_selection_set_filename(file_selector
, remember_plugins_dir
);
2931 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
2933 case GTK_RESPONSE_ACCEPT
:
2934 case GTK_RESPONSE_OK
:
2935 dir
= gtk_file_selection_get_filename (file_selector
);
2936 strncpy(remember_plugins_dir
,dir
,PATH_MAX
);
2937 strncat(remember_plugins_dir
,"/",PATH_MAX
);
2938 lttv_library_path_add(dir
);
2939 case GTK_RESPONSE_REJECT
:
2940 case GTK_RESPONSE_CANCEL
:
2942 gtk_widget_destroy((GtkWidget
*)file_selector
);
2948 /* Display a directory dialogue to let user select a path for library searching
2952 on_remove_library_search_path_activate (GtkMenuItem
*menuitem
,
2955 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2957 const char *lib_path
;
2961 name
= g_ptr_array_new();
2962 nb
= lttv_library_path_number();
2963 /* ask for the library name */
2966 gchar
*path
= lttv_library_path_get(i
);
2967 g_ptr_array_add(name
, path
);
2969 lib_path
= get_selection(mw_data
, (char **)(name
->pdata
), name
->len
,
2970 "Select a library path", "Library paths");
2972 g_ptr_array_free(name
, TRUE
);
2974 if(lib_path
== NULL
) return;
2977 lttv_library_path_remove(lib_path
);
2981 on_color_activate (GtkMenuItem
*menuitem
,
2989 on_save_configuration_activate (GtkMenuItem
*menuitem
,
2992 g_info("Save configuration\n");
2997 on_content_activate (GtkMenuItem
*menuitem
,
3000 char* filename
= NULL
,
3003 const char* relativePath
= "doc/user/user_guide/html/index.html";
3004 filename
= g_build_filename (g_get_current_dir(), relativePath
, NULL
);
3005 path
= g_strdup_printf ("ghelp://%s", filename
);
3007 screen
= gdk_screen_get_default();
3008 gtk_show_uri (screen
, path
, gtk_get_current_event_time(), NULL
);
3012 g_info("Content\n");
3017 on_about_close_activate (GtkButton
*button
,
3020 GtkWidget
*about_widget
= GTK_WIDGET(user_data
);
3022 gtk_widget_destroy(about_widget
);
3026 on_about_activate (GtkMenuItem
*menuitem
,
3029 MainWindow
*main_window
= get_window_data_struct(GTK_WIDGET(menuitem
));
3030 GtkWidget
*window_widget
= main_window
->mwindow
;
3031 GtkWidget
*about_widget
= gtk_window_new(GTK_WINDOW_TOPLEVEL
);
3032 GtkWindow
*about_window
= GTK_WINDOW(about_widget
);
3034 gtk_window_set_title(about_window
, "About Linux Trace Toolkit");
3036 gtk_window_set_resizable(about_window
, FALSE
);
3037 gtk_window_set_transient_for(about_window
, GTK_WINDOW(window_widget
));
3038 gtk_window_set_destroy_with_parent(about_window
, TRUE
);
3039 gtk_window_set_modal(about_window
, FALSE
);
3041 /* Put the about window at the center of the screen */
3042 gtk_window_set_position(about_window
, GTK_WIN_POS_CENTER_ALWAYS
);
3044 GtkWidget
*vbox
= gtk_vbox_new(FALSE
, 1);
3046 gtk_container_add(GTK_CONTAINER(about_widget
), vbox
);
3049 GtkWidget
*label1
= gtk_label_new("");
3050 gtk_misc_set_padding(GTK_MISC(label1
), 10, 20);
3051 gtk_label_set_markup(GTK_LABEL(label1
), "\
3052 <big>Linux Trace Toolkit " VERSION
"</big>");
3053 gtk_label_set_justify(GTK_LABEL(label1
), GTK_JUSTIFY_CENTER
);
3055 GtkWidget
*label2
= gtk_label_new("");
3056 gtk_misc_set_padding(GTK_MISC(label2
), 10, 20);
3057 gtk_label_set_markup(GTK_LABEL(label2
), "\
3060 Michel Dagenais (New trace format, lttv main)\n\
3061 Mathieu Desnoyers (Kernel Tracer, Directory structure, build with automake/conf,\n\
3062 lttv gui, control flow view, gui cooperative trace reading\n\
3063 scheduler with interruptible foreground and background\n\
3064 computation, detailed event list (rewrite), trace reading\n\
3065 library (rewrite))\n\
3066 Benoit Des Ligneris, Eric Clement (Cluster adaptation, work in progress)\n\
3067 Xang-Xiu Yang (new trace reading library and converter, lttv gui, \n\
3068 detailed event list and statistics view)\n\
3069 Tom Zanussi (RelayFS)\n\
3071 Inspired from the original Linux Trace Toolkit Visualizer made by\n\
3074 GtkWidget
*label3
= gtk_label_new("");
3075 gtk_label_set_markup(GTK_LABEL(label3
), "\
3076 Linux Trace Toolkit Viewer, Copyright (C) 2004, 2005, 2006\n\
3078 Mathieu Desnoyers\n\
3080 Linux Trace Toolkit comes with ABSOLUTELY NO WARRANTY.\n\
3081 This is free software, and you are welcome to redistribute it\n\
3082 under certain conditions. See COPYING for details.");
3083 gtk_misc_set_padding(GTK_MISC(label3
), 10, 20);
3085 gtk_box_pack_start_defaults(GTK_BOX(vbox
), label1
);
3086 gtk_box_pack_start_defaults(GTK_BOX(vbox
), label2
);
3087 gtk_box_pack_start_defaults(GTK_BOX(vbox
), label3
);
3089 GtkWidget
*hbox
= gtk_hbox_new(TRUE
, 0);
3090 gtk_box_pack_end(GTK_BOX(vbox
), hbox
, FALSE
, FALSE
, 0);
3091 GtkWidget
*close_button
= gtk_button_new_with_mnemonic("_Close");
3092 gtk_box_pack_end(GTK_BOX(hbox
), close_button
, FALSE
, FALSE
, 0);
3093 gtk_container_set_border_width(GTK_CONTAINER(close_button
), 20);
3095 g_signal_connect(G_OBJECT(close_button
), "clicked",
3096 G_CALLBACK(on_about_close_activate
),
3097 (gpointer
)about_widget
);
3099 gtk_widget_show_all(about_widget
);
3104 on_button_new_clicked (GtkButton
*button
,
3107 create_new_window((GtkWidget
*)button
, user_data
, TRUE
);
3111 on_button_new_tab_clicked (GtkButton
*button
,
3114 create_new_tab((GtkWidget
*)button
, user_data
);
3118 on_button_open_clicked (GtkButton
*button
,
3121 #ifdef UNFINISHED_FEATURE
3122 open_traceset((GtkWidget
*)button
, user_data
);
3128 on_button_add_trace_clicked (GtkButton
*button
,
3131 add_trace((GtkWidget
*)button
, user_data
);
3136 on_button_remove_trace_clicked (GtkButton
*button
,
3139 remove_trace((GtkWidget
*)button
, user_data
);
3143 on_button_redraw_clicked (GtkButton
*button
,
3146 redraw((GtkWidget
*)button
, user_data
);
3150 on_button_continue_processing_clicked (GtkButton
*button
,
3153 continue_processing((GtkWidget
*)button
, user_data
);
3157 on_button_stop_processing_clicked (GtkButton
*button
,
3160 stop_processing((GtkWidget
*)button
, user_data
);
3166 on_button_save_clicked (GtkButton
*button
,
3169 save((GtkWidget
*)button
, user_data
);
3174 on_button_save_as_clicked (GtkButton
*button
,
3177 save_as((GtkWidget
*)button
, user_data
);
3182 on_button_zoom_in_clicked (GtkButton
*button
,
3185 zoom_in((GtkWidget
*)button
, user_data
);
3190 on_button_zoom_out_clicked (GtkButton
*button
,
3193 zoom_out((GtkWidget
*)button
, user_data
);
3198 on_button_zoom_extended_clicked (GtkButton
*button
,
3201 zoom_extended((GtkWidget
*)button
, user_data
);
3206 on_button_go_to_time_clicked (GtkButton
*button
,
3209 go_to_time((GtkWidget
*)button
, user_data
);
3214 on_button_show_time_frame_clicked (GtkButton
*button
,
3217 show_time_frame((GtkWidget
*)button
, user_data
);
3222 on_button_move_up_clicked (GtkButton
*button
,
3225 move_up_viewer((GtkWidget
*)button
, user_data
);
3230 on_button_move_down_clicked (GtkButton
*button
,
3233 move_down_viewer((GtkWidget
*)button
, user_data
);
3238 on_button_delete_viewer_clicked (GtkButton
*button
,
3241 delete_viewer((GtkWidget
*)button
, user_data
);
3245 on_MWindow_destroy (GtkWidget
*widget
,
3248 MainWindow
*main_window
= get_window_data_struct(widget
);
3249 LttvIAttribute
*attributes
= main_window
->attributes
;
3250 LttvAttributeValue value
;
3253 //This is unnecessary, since widgets will be destroyed
3254 //by the main window widget anyway.
3255 //remove_all_menu_toolbar_constructors(main_window, NULL);
3257 retval
= lttv_iattribute_find_by_path(attributes
, "viewers/menu",
3258 LTTV_POINTER
, &value
);
3260 lttv_menus_destroy((LttvMenus
*)*(value
.v_pointer
));
3262 retval
= lttv_iattribute_find_by_path(attributes
, "viewers/toolbar",
3263 LTTV_POINTER
, &value
);
3265 lttv_toolbars_destroy((LttvToolbars
*)*(value
.v_pointer
));
3267 g_object_unref(main_window
->attributes
);
3268 g_main_window_list
= g_slist_remove(g_main_window_list
, main_window
);
3270 g_info("There are now : %d windows\n",g_slist_length(g_main_window_list
));
3271 if(g_slist_length(g_main_window_list
) == 0)
3276 on_MWindow_configure (GtkWidget
*widget
,
3277 GdkEventConfigure
*event
,
3280 // MD : removed time width modification upon resizing of the main window.
3281 // The viewers will redraw themselves completely, without time interval
3284 if(mw_data->window_width){
3285 time_span = LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context)->Time_Span ;
3286 time_win = tab->time_window;
3287 ratio = width / mw_data->window_width;
3288 tab->time_window.time_width = ltt_time_mul(time_win.time_width,ratio);
3289 time = ltt_time_sub(time_span->endTime, time_win.start_time);
3290 if(ltt_time_compare(time, tab->time_window.time_width) < 0){
3291 tab->time_window.time_width = time;
3297 mw_data->window_width = (int)width;
3306 on_MNotebook_switch_page (GtkNotebook
*notebook
,
3307 GtkNotebookPage
*page
,
3315 void time_change_manager (Tab
*tab
,
3316 TimeWindow new_time_window
)
3319 /* Only one source of time change */
3320 if(tab
->time_manager_lock
== TRUE
) return;
3322 tab
->time_manager_lock
= TRUE
;
3323 TimeInterval time_span
;
3325 LttvTraceset
*ts
= tab
->traceset_info
->traceset
;
3327 time_span
= lttv_traceset_get_time_span_real(ts
);
3329 LttTime start_time
= new_time_window
.start_time
;
3330 LttTime end_time
= new_time_window
.end_time
;
3332 g_assert(ltt_time_compare(start_time
, end_time
) < 0);
3335 GtkAdjustment
*adjustment
= gtk_range_get_adjustment(GTK_RANGE(tab
->scrollbar
));
3336 LttTime upper
= ltt_time_sub(time_span
.end_time
, time_span
.start_time
);
3339 gtk_range_set_increments(GTK_RANGE(tab
->scrollbar
),
3340 ltt_time_to_double(new_time_window
.time_width
)
3341 / SCROLL_STEP_PER_PAGE
3342 * NANOSECONDS_PER_SECOND
, /* step increment */
3343 ltt_time_to_double(new_time_window
.time_width
)
3344 * NANOSECONDS_PER_SECOND
); /* page increment */
3345 gtk_range_set_range(GTK_RANGE(tab
->scrollbar
),
3347 ltt_time_to_double(upper
)
3348 * NANOSECONDS_PER_SECOND
); /* upper */
3350 g_object_set(G_OBJECT(adjustment
),
3354 ltt_time_to_double(upper
), /* upper */
3356 new_time_window
.time_width_double
3357 / SCROLL_STEP_PER_PAGE
, /* step increment */
3359 new_time_window
.time_width_double
,
3360 /* page increment */
3362 new_time_window
.time_width_double
, /* page size */
3364 gtk_adjustment_changed(adjustment
);
3366 // g_object_set(G_OBJECT(adjustment),
3368 // ltt_time_to_double(
3369 // ltt_time_sub(start_time, time_span.start_time))
3372 //gtk_adjustment_value_changed(adjustment);
3373 gtk_range_set_value(GTK_RANGE(tab
->scrollbar
),
3375 ltt_time_sub(start_time
, time_span
.start_time
)) /* value */);
3377 /* set the time bar. */
3380 timebar_set_minmax_time(TIMEBAR(tab
->MTimebar
),
3381 &time_span
.start_time
,
3382 &time_span
.end_time
);
3383 timebar_set_start_time(TIMEBAR(tab
->MTimebar
),&start_time
);
3384 timebar_set_end_time(TIMEBAR(tab
->MTimebar
),&end_time
);
3388 /* call viewer hooks for new time window */
3389 set_time_window(tab
, &new_time_window
);
3391 tab
->time_manager_lock
= FALSE
;
3400 void current_time_change_manager (Tab
*tab
,
3401 LttTime new_current_time
)
3403 /* Only one source of time change */
3404 if(tab
->current_time_manager_lock
== TRUE
) return;
3406 tab
->current_time_manager_lock
= TRUE
;
3408 timebar_set_current_time(TIMEBAR(tab
->MTimebar
), &new_current_time
);
3410 set_current_time(tab
, &new_current_time
);
3412 tab
->current_time_manager_lock
= FALSE
;
3415 void current_position_change_manager(Tab
*tab
, LttvTracesetPosition
*pos
)
3417 lttv_traceset_seek_to_position( pos
);
3419 LttTime new_time
= lttv_traceset_position_get_time(pos
);
3420 /* Put the context in a state coherent position */
3422 lttv_state_traceset_seek_time_closest(tab
->traceset_info
->traceset
, ltt_time_zero
);
3424 current_time_change_manager(tab
, new_time
);
3426 set_current_position(tab
, pos
);
3429 static void on_timebar_starttime_changed(Timebar
*timebar
,
3432 Tab
*tab
= (Tab
*)user_data
;
3433 LttvTraceset
* ts
=tab
->traceset_info
->traceset
;
3434 TimeInterval time_span
= lttv_traceset_get_time_span_real(ts
);
3436 TimeWindow new_time_window
= tab
->time_window
;
3437 new_time_window
.start_time
= timebar_get_start_time(timebar
);
3439 LttTime end_time
= new_time_window
.end_time
;
3441 /* TODO ybrosseau 2010-12-02: This if should have been checked
3442 by the timebar already */
3443 if(ltt_time_compare(new_time_window
.start_time
, end_time
) >= 0) {
3444 /* Then, we must push back end time : keep the same time width
3445 * if possible, else end traceset time */
3446 end_time
= LTT_TIME_MIN(ltt_time_add(new_time_window
.start_time
,
3447 new_time_window
.time_width
),
3448 time_span
.end_time
);
3451 /* Fix the time width to fit start time and end time */
3452 new_time_window
.time_width
= ltt_time_sub(end_time
,
3453 new_time_window
.start_time
);
3455 new_time_window
.time_width_double
=
3456 ltt_time_to_double(new_time_window
.time_width
);
3458 new_time_window
.end_time
= end_time
;
3460 /* Notify the time_manager */
3461 time_change_manager(tab
, new_time_window
);
3465 static void on_timebar_endtime_changed(Timebar
*timebar
,
3468 Tab
*tab
= (Tab
*)user_data
;
3469 LttvTraceset
* ts
=tab
->traceset_info
->traceset
;
3470 TimeInterval time_span
= lttv_traceset_get_time_span_real(ts
);
3472 TimeWindow new_time_window
= tab
->time_window
;
3474 LttTime end_time
= timebar_get_end_time(timebar
);
3476 /* TODO ybrosseau 2010-12-02: This if should have been
3477 checked by the timebar already */
3478 if(ltt_time_compare(new_time_window
.start_time
, end_time
) >= 0) {
3479 /* Then, we must push front start time : keep the same time
3480 width if possible, else end traceset time */
3481 new_time_window
.start_time
= LTT_TIME_MAX(
3482 ltt_time_sub(end_time
,
3483 new_time_window
.time_width
),
3484 time_span
.start_time
);
3487 /* Fix the time width to fit start time and end time */
3488 new_time_window
.time_width
= ltt_time_sub(end_time
,
3489 new_time_window
.start_time
);
3491 new_time_window
.time_width_double
=
3492 ltt_time_to_double(new_time_window
.time_width
);
3494 new_time_window
.end_time
= end_time
;
3496 /* Notify the time_manager */
3497 time_change_manager(tab
, new_time_window
);
3499 static void on_timebar_currenttime_changed(Timebar
*timebar
,
3502 Tab
*tab
= (Tab
*)user_data
;
3504 LttTime new_current_time
= timebar_get_current_time(timebar
);
3506 current_time_change_manager(tab
, new_current_time
);
3509 void scroll_value_changed_cb(GtkWidget
*scrollbar
,
3512 Tab
*tab
= (Tab
*)user_data
;
3513 TimeWindow new_time_window
;
3515 GtkAdjustment
*adjust
= gtk_range_get_adjustment(GTK_RANGE(scrollbar
));
3516 gdouble value
= gtk_adjustment_get_value(adjust
);
3517 // gdouble upper, lower, ratio, page_size;
3520 LttvTraceset
* ts
= tab
->traceset_info
->traceset
;
3521 TimeInterval time_span
= lttv_traceset_get_time_span_real(ts
);
3523 time
= ltt_time_add(ltt_time_from_double(value
),
3524 time_span
.start_time
);
3526 new_time_window
.start_time
= time
;
3528 page_size
= adjust
->page_size
;
3530 new_time_window
.time_width
=
3531 ltt_time_from_double(page_size
);
3533 new_time_window
.time_width_double
=
3536 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
3537 new_time_window
.time_width
);
3540 time_change_manager(tab
, new_time_window
);
3543 //time_window = tab->time_window;
3545 lower
= adjust
->lower
;
3546 upper
= adjust
->upper
;
3547 ratio
= (value
- lower
) / (upper
- lower
);
3548 g_info("lower %lu, upper %lu, value %lu, ratio %lu", lower
, upper
, value
, ratio
);
3550 //time = ltt_time_sub(time_span->end_time, time_span->start_time);
3551 //time = ltt_time_mul(time, (float)ratio);
3552 //time = ltt_time_add(time_span->start_time, time);
3553 time
= ltt_time_add(ltt_time_from_double(value
),
3554 time_span
.start_time
);
3556 time_window
.start_time
= time
;
3558 page_size
= adjust
->page_size
;
3560 time_window
.time_width
=
3561 ltt_time_from_double(page_size
);
3562 //time = ltt_time_sub(time_span.end_time, time);
3563 //if(ltt_time_compare(time,time_window.time_width) < 0){
3564 // time_window.time_width = time;
3567 /* call viewer hooks for new time window */
3568 set_time_window(tab
, &time_window
);
3574 /* Display a dialogue showing all eventtypes and traces, let user to select the interested
3575 * eventtypes, tracefiles and traces (filter)
3578 /* Select a trace which will be removed from traceset
3581 char * get_remove_trace(MainWindow
*mw_data
,
3582 char ** all_trace_name
, int nb_trace
)
3584 return get_selection(mw_data
, all_trace_name
, nb_trace
,
3585 "Select a trace", "Trace pathname");
3589 /* Select a module which will be loaded
3592 char * get_load_module(MainWindow
*mw_data
,
3593 char ** load_module_name
, int nb_module
)
3595 return get_selection(mw_data
, load_module_name
, nb_module
,
3596 "Select a module to load", "Module name");
3602 /* Select a module which will be unloaded
3605 char * get_unload_module(MainWindow
*mw_data
,
3606 char ** loaded_module_name
, int nb_module
)
3608 return get_selection(mw_data
, loaded_module_name
, nb_module
,
3609 "Select a module to unload", "Module name");
3613 /* Display a dialogue which shows all selectable items, let user to
3614 * select one of them
3617 char * get_selection(MainWindow
*mw_data
,
3618 char ** loaded_module_name
, int nb_module
,
3619 char *title
, char * column_title
)
3621 GtkWidget
* dialogue
;
3622 GtkWidget
* scroll_win
;
3624 GtkListStore
* store
;
3625 GtkTreeViewColumn
* column
;
3626 GtkCellRenderer
* renderer
;
3627 GtkTreeSelection
* select
;
3630 char * unload_module_name
= NULL
;
3632 dialogue
= gtk_dialog_new_with_buttons(title
,
3635 GTK_STOCK_OK
,GTK_RESPONSE_ACCEPT
,
3636 GTK_STOCK_CANCEL
,GTK_RESPONSE_REJECT
,
3638 gtk_window_set_default_size((GtkWindow
*)dialogue
, 500, 200);
3639 gtk_window_set_transient_for(GTK_WINDOW(dialogue
),
3640 GTK_WINDOW(mw_data
->mwindow
));
3642 scroll_win
= gtk_scrolled_window_new (NULL
, NULL
);
3643 gtk_widget_show ( scroll_win
);
3644 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll_win
),
3645 GTK_POLICY_AUTOMATIC
, GTK_POLICY_AUTOMATIC
);
3647 store
= gtk_list_store_new (N_COLUMNS
,G_TYPE_STRING
);
3648 tree
= gtk_tree_view_new_with_model(GTK_TREE_MODEL (store
));
3649 gtk_widget_show ( tree
);
3650 g_object_unref (G_OBJECT (store
));
3652 renderer
= gtk_cell_renderer_text_new ();
3653 column
= gtk_tree_view_column_new_with_attributes (column_title
,
3655 "text", MODULE_COLUMN
,
3657 gtk_tree_view_column_set_alignment (column
, 0.5);
3658 gtk_tree_view_column_set_fixed_width (column
, 150);
3659 gtk_tree_view_append_column (GTK_TREE_VIEW (tree
), column
);
3661 select
= gtk_tree_view_get_selection (GTK_TREE_VIEW (tree
));
3662 gtk_tree_selection_set_mode (select
, GTK_SELECTION_SINGLE
);
3664 gtk_container_add (GTK_CONTAINER (scroll_win
), tree
);
3666 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialogue
)->vbox
), scroll_win
,TRUE
, TRUE
,0);
3668 for(i
=0;i
<nb_module
;i
++){
3669 gtk_list_store_append (store
, &iter
);
3670 gtk_list_store_set (store
, &iter
, MODULE_COLUMN
,loaded_module_name
[i
],-1);
3673 id
= gtk_dialog_run(GTK_DIALOG(dialogue
));
3674 GtkTreeModel
**store_model
= (GtkTreeModel
**)&store
;
3676 case GTK_RESPONSE_ACCEPT
:
3677 case GTK_RESPONSE_OK
:
3678 if (gtk_tree_selection_get_selected (select
, store_model
, &iter
)){
3679 gtk_tree_model_get ((GtkTreeModel
*)store
, &iter
, MODULE_COLUMN
, &unload_module_name
, -1);
3681 case GTK_RESPONSE_REJECT
:
3682 case GTK_RESPONSE_CANCEL
:
3684 gtk_widget_destroy(dialogue
);
3688 return unload_module_name
;
3692 /* Insert all menu entry and tool buttons into this main window
3697 void add_all_menu_toolbar_constructors(MainWindow
* mw
, gpointer user_data
)
3701 lttvwindow_viewer_constructor constructor
;
3702 LttvMenus
* global_menu
, * instance_menu
;
3703 LttvToolbars
* global_toolbar
, * instance_toolbar
;
3704 LttvMenuClosure
*menu_item
;
3705 LttvToolbarClosure
*toolbar_item
;
3706 LttvAttributeValue value
;
3707 LttvIAttribute
*global_attributes
= LTTV_IATTRIBUTE(lttv_global_attributes());
3708 LttvIAttribute
*attributes
= mw
->attributes
;
3709 GtkWidget
* tool_menu_title_menu
, *new_widget
, *pixmap
;
3712 retval
= lttv_iattribute_find_by_path(global_attributes
, "viewers/menu",
3713 LTTV_POINTER
, &value
);
3715 if(*(value
.v_pointer
) == NULL
)
3716 *(value
.v_pointer
) = lttv_menus_new();
3717 global_menu
= (LttvMenus
*)*(value
.v_pointer
);
3719 retval
= lttv_iattribute_find_by_path(attributes
, "viewers/menu",
3720 LTTV_POINTER
, &value
);
3722 if(*(value
.v_pointer
) == NULL
)
3723 *(value
.v_pointer
) = lttv_menus_new();
3724 instance_menu
= (LttvMenus
*)*(value
.v_pointer
);
3726 retval
= lttv_iattribute_find_by_path(global_attributes
, "viewers/toolbar",
3727 LTTV_POINTER
, &value
);
3729 if(*(value
.v_pointer
) == NULL
)
3730 *(value
.v_pointer
) = lttv_toolbars_new();
3731 global_toolbar
= (LttvToolbars
*)*(value
.v_pointer
);
3733 retval
= lttv_iattribute_find_by_path(attributes
, "viewers/toolbar",
3734 LTTV_POINTER
, &value
);
3736 if(*(value
.v_pointer
) == NULL
)
3737 *(value
.v_pointer
) = lttv_toolbars_new();
3738 instance_toolbar
= (LttvToolbars
*)*(value
.v_pointer
);
3740 /* Add missing menu entries to window instance */
3741 for(i
=0;i
<global_menu
->len
;i
++) {
3742 menu_item
= &g_array_index(global_menu
, LttvMenuClosure
, i
);
3744 //add menu_item to window instance;
3745 constructor
= menu_item
->con
;
3746 tool_menu_title_menu
= lookup_widget(mw
->mwindow
,"ToolMenuTitle_menu");
3748 gtk_menu_item_new_with_mnemonic (menu_item
->menu_text
);
3749 gtk_container_add (GTK_CONTAINER (tool_menu_title_menu
),
3751 g_signal_connect ((gpointer
) new_widget
, "activate",
3752 G_CALLBACK (insert_viewer_wrap
),
3754 gtk_widget_show (new_widget
);
3755 lttv_menus_add(instance_menu
, menu_item
->con
,
3756 menu_item
->menu_path
,
3757 menu_item
->menu_text
,
3762 /* Add missing toolbar entries to window instance */
3763 for(i
=0;i
<global_toolbar
->len
;i
++) {
3764 toolbar_item
= &g_array_index(global_toolbar
, LttvToolbarClosure
, i
);
3766 //add toolbar_item to window instance;
3767 constructor
= toolbar_item
->con
;
3768 tool_menu_title_menu
= lookup_widget(mw
->mwindow
,"MToolbar1");
3769 pixbuf
= gdk_pixbuf_new_from_xpm_data((const char**)toolbar_item
->pixmap
);
3770 pixmap
= gtk_image_new_from_pixbuf(pixbuf
);
3772 gtk_toolbar_append_element (GTK_TOOLBAR (tool_menu_title_menu
),
3773 GTK_TOOLBAR_CHILD_BUTTON
,
3776 toolbar_item
->tooltip
, NULL
,
3777 pixmap
, NULL
, NULL
);
3778 gtk_label_set_use_underline(
3779 GTK_LABEL (((GtkToolbarChild
*) (
3780 g_list_last (GTK_TOOLBAR
3781 (tool_menu_title_menu
)->children
)->data
))->label
),
3783 gtk_container_set_border_width (GTK_CONTAINER (new_widget
), 1);
3784 g_signal_connect ((gpointer
) new_widget
,
3786 G_CALLBACK (insert_viewer_wrap
),
3788 gtk_widget_show (new_widget
);
3790 lttv_toolbars_add(instance_toolbar
, toolbar_item
->con
,
3791 toolbar_item
->tooltip
,
3792 toolbar_item
->pixmap
,
3800 /* Create a main window
3803 MainWindow
*construct_main_window(MainWindow
* parent
)
3807 g_debug("construct_main_window()");
3808 GtkWidget
* new_window
; /* New generated main window */
3809 MainWindow
* new_m_window
;/* New main window structure */
3810 GtkNotebook
* notebook
;
3811 LttvIAttribute
*attributes
=
3812 LTTV_IATTRIBUTE(g_object_new(LTTV_ATTRIBUTE_TYPE
, NULL
));
3813 LttvAttributeValue value
;
3815 new_m_window
= g_new(MainWindow
, 1);
3817 // Add the object's information to the module's array
3818 g_main_window_list
= g_slist_append(g_main_window_list
, new_m_window
);
3820 new_window
= create_MWindow();
3821 gtk_widget_show (new_window
);
3823 new_m_window
->mwindow
= new_window
;
3824 new_m_window
->attributes
= attributes
;
3826 retval
= lttv_iattribute_find_by_path(attributes
, "viewers/menu",
3827 LTTV_POINTER
, &value
);
3829 *(value
.v_pointer
) = lttv_menus_new();
3831 retval
= lttv_iattribute_find_by_path(attributes
, "viewers/toolbar",
3832 LTTV_POINTER
, &value
);
3834 *(value
.v_pointer
) = lttv_toolbars_new();
3836 add_all_menu_toolbar_constructors(new_m_window
, NULL
);
3838 g_object_set_data_full(G_OBJECT(new_window
),
3840 (gpointer
)new_m_window
,
3841 (GDestroyNotify
)g_free
);
3842 //create a default tab
3843 notebook
= (GtkNotebook
*)lookup_widget(new_m_window
->mwindow
, "MNotebook");
3844 if(notebook
== NULL
){
3845 g_info("Notebook does not exist\n");
3846 /* FIXME : destroy partially created widgets */
3847 g_free(new_m_window
);
3850 //gtk_notebook_popup_enable (GTK_NOTEBOOK(notebook));
3851 //for now there is no name field in LttvTraceset structure
3852 //Use "Traceset" as the label for the default tab
3854 GtkWidget
* parent_notebook
= lookup_widget(parent
->mwindow
, "MNotebook");
3855 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(parent_notebook
),
3856 gtk_notebook_get_current_page(GTK_NOTEBOOK(parent_notebook
)));
3862 LttvPluginTab
*ptab
;
3863 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
3864 parent_tab
= ptab
->tab
;
3866 LttvPluginTab
*ptab
= g_object_new(LTTV_TYPE_PLUGIN_TAB
, NULL
);
3868 new_m_window
, parent_tab
, notebook
, "Traceset");
3869 ptab
->parent
.top_widget
= ptab
->tab
->top_widget
;
3870 g_object_set_data_full(
3871 G_OBJECT(ptab
->tab
->vbox
),
3874 (GDestroyNotify
)tab_destructor
);
3876 LttvPluginTab
*ptab
= g_object_new(LTTV_TYPE_PLUGIN_TAB
, NULL
);
3877 init_tab(ptab
->tab
, new_m_window
, NULL
, notebook
, "Traceset");
3878 ptab
->parent
.top_widget
= ptab
->tab
->top_widget
;
3879 g_object_set_data_full(
3880 G_OBJECT(ptab
->tab
->vbox
),
3883 (GDestroyNotify
)tab_destructor
);
3886 /* Insert default viewers */
3888 LttvAttributeType type
;
3889 LttvAttributeName name
;
3890 LttvAttributeValue value
;
3891 LttvAttribute
*attribute
;
3893 LttvIAttribute
*attributes_global
=
3894 LTTV_IATTRIBUTE(lttv_global_attributes());
3896 attribute
= LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
3897 LTTV_IATTRIBUTE(attributes_global
),
3898 LTTV_VIEWER_CONSTRUCTORS
));
3899 g_assert(attribute
);
3901 name
= g_quark_from_string("guievents");
3902 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
3904 if(type
== LTTV_POINTER
) {
3905 lttvwindow_viewer_constructor viewer_constructor
=
3906 (lttvwindow_viewer_constructor
)*value
.v_pointer
;
3907 insert_viewer(new_window
, viewer_constructor
);
3910 name
= g_quark_from_string("guicontrolflow");
3911 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
3913 if(type
== LTTV_POINTER
) {
3914 lttvwindow_viewer_constructor viewer_constructor
=
3915 (lttvwindow_viewer_constructor
)*value
.v_pointer
;
3916 insert_viewer(new_window
, viewer_constructor
);
3919 name
= g_quark_from_string("guistatistics");
3920 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
3922 if(type
== LTTV_POINTER
) {
3923 lttvwindow_viewer_constructor viewer_constructor
=
3924 (lttvwindow_viewer_constructor
)*value
.v_pointer
;
3925 insert_viewer(new_window
, viewer_constructor
);
3929 g_info("There are now : %d windows\n",g_slist_length(g_main_window_list
));
3931 return new_m_window
;
3935 /* Free the memory occupied by a tab structure
3939 void tab_destructor(LttvPluginTab
* ptab
)
3941 #ifdef BABEL_CLEANUP
3942 int i
, nb
, ref_count
;
3944 Tab
*tab
= ptab
->tab
;
3947 g_object_unref(tab
->attributes
);
3949 if(tab
->interrupted_state
)
3950 g_object_unref(tab
->interrupted_state
);
3953 if(tab
->traceset_info
->traceset_context
!= NULL
){
3954 //remove state update hooks
3955 lttv_state_remove_event_hooks(
3956 (LttvTracesetState
*)tab
->traceset_info
->
3958 lttv_context_fini(LTTV_TRACESET_CONTEXT(tab
->traceset_info
->
3960 g_object_unref(tab
->traceset_info
->traceset_context
);
3962 if(tab
->traceset_info
->traceset
!= NULL
) {
3963 nb
= lttv_traceset_number(tab
->traceset_info
->traceset
);
3964 for(i
= 0 ; i
< nb
; i
++) {
3965 trace
= lttv_traceset_get(tab
->traceset_info
->traceset
, i
);
3966 ref_count
= lttv_trace_get_ref_number(trace
);
3968 ltt_trace_close(lttv_trace(trace
));
3972 lttv_traceset_destroy(tab
->traceset_info
->traceset
);
3973 /* Remove the idle events requests processing function of the tab */
3974 g_idle_remove_by_data(tab
);
3976 g_slist_free(tab
->events_requests
);
3977 g_free(tab
->traceset_info
);
3979 g_object_unref(ptab
);
3980 #endif /* BABEL_CLEANUP */
3984 /* Create a tab and insert it into the current main window
3987 void init_tab(Tab
*tab
, MainWindow
* mw
, Tab
*copy_tab
,
3988 GtkNotebook
* notebook
, char * label
)
3993 //LttvFilter *filter = NULL;
3995 //create a new tab data structure
3996 //tab = g_new(Tab,1);
3998 //construct and initialize the traceset_info
3999 tab
->traceset_info
= g_new(TracesetInfo
,1);
4002 tab
->traceset_info
->traceset
=
4003 lttv_traceset_copy(copy_tab
->traceset_info
->traceset
);
4005 /* Copy the previous tab's filter */
4006 /* We can clone the filter, as we copy the trace set also */
4007 /* The filter must always be in sync with the trace set */
4009 #ifdef BABEL_CLEANUP
4010 tab
->filter
= lttv_filter_clone(copy_tab
->filter
);
4011 #endif /* BABEL_CLEANUP */
4013 tab
->traceset_info
->traceset
= lttv_traceset_new();
4018 lttv_attribute_write_xml(
4019 lttv_traceset_attribute(tab
->traceset_info
->traceset
),
4025 tab
->time_manager_lock
= FALSE
;
4026 tab
->current_time_manager_lock
= FALSE
;
4027 #ifdef BABEL_CLEANUP
4028 //FIXME copy not implemented in lower level
4029 tab
->traceset_info
->traceset_context
=
4030 g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
4031 //add state update hooks
4032 #endif //BABEL_CLEANUP
4033 lttv_state_add_event_hooks(
4034 tab
->traceset_info
->traceset
);
4036 //determine the current_time and time_window of the tab
4038 if(copy_tab
!= NULL
){
4039 tab
->time_window
= copy_tab
->time_window
;
4040 tab
->current_time
= copy_tab
->current_time
;
4042 tab
->time_window
.start_time
=
4043 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
4044 time_span
.start_time
;
4045 if(DEFAULT_TIME_WIDTH_S
<
4046 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
4047 time_span
.end_time
.tv_sec
)
4048 tmp_time
.tv_sec
= DEFAULT_TIME_WIDTH_S
;
4051 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
4052 time_span
.end_time
.tv_sec
;
4053 tmp_time
.tv_nsec
= 0;
4054 tab
->time_window
.time_width
= tmp_time
;
4055 tab
->current_time
.tv_sec
=
4056 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
4057 time_span
.start_time
.tv_sec
;
4058 tab
->current_time
.tv_nsec
=
4059 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
4060 time_span
.start_time
.tv_nsec
;
4063 tab
->attributes
= LTTV_IATTRIBUTE(g_object_new(LTTV_ATTRIBUTE_TYPE
, NULL
));
4064 tab
->interrupted_state
= g_object_new(LTTV_ATTRIBUTE_TYPE
, NULL
);
4066 tab
->vbox
= gtk_vbox_new(FALSE
, 2);
4067 tab
->top_widget
= tab
->vbox
;
4068 //g_object_set_data_full(G_OBJECT(tab->top_widget), "filter",
4069 // filter, (GDestroyNotify)lttv_filter_destroy);
4071 // g_signal_connect (G_OBJECT(tab->top_widget),
4073 // G_CALLBACK (on_top_notify),
4076 tab
->viewer_container
= gtk_vbox_new(TRUE
, 2);
4077 tab
->scrollbar
= gtk_hscrollbar_new(NULL
);
4078 //tab->multivpaned = gtk_multi_vpaned_new();
4080 gtk_box_pack_start(GTK_BOX(tab
->vbox
),
4081 tab
->viewer_container
,
4083 TRUE
, /* Give the extra space to the child */
4084 0); /* No padding */
4087 // tab->time_window = copy_tab->time_window;
4088 // tab->current_time = copy_tab->current_time;
4091 /* Create the timebar */
4093 tab
->MTimebar
= timebar_new();
4095 gtk_box_pack_end(GTK_BOX(tab
->vbox
),
4097 FALSE
, /* Do not expand */
4098 FALSE
, /* Fill has no effect here (expand false) */
4099 0); /* No padding */
4101 gtk_box_pack_end(GTK_BOX(tab
->vbox
),
4103 FALSE
, /* Do not expand */
4104 FALSE
, /* Fill has no effect here (expand false) */
4105 0); /* No padding */
4107 g_object_set_data(G_OBJECT(tab
->viewer_container
), "focused_viewer", NULL
);
4113 // Display a label with a X
4114 GtkWidget *w_hbox = gtk_hbox_new(FALSE, 4);
4115 GtkWidget *w_label = gtk_label_new (label);
4116 GtkWidget *pixmap = create_pixmap(GTK_WIDGET(notebook), "close.png");
4117 GtkWidget *w_button = gtk_button_new ();
4118 gtk_container_add(GTK_CONTAINER(w_button), pixmap);
4119 //GtkWidget *w_button = gtk_button_new_with_label("x");
4121 gtk_button_set_relief(GTK_BUTTON(w_button), GTK_RELIEF_NONE);
4123 gtk_box_pack_start(GTK_BOX(w_hbox), w_label, TRUE, TRUE, 0);
4124 gtk_box_pack_end(GTK_BOX(w_hbox), w_button, FALSE,
4127 g_signal_connect_swapped (w_button, "clicked",
4128 G_CALLBACK (on_close_tab_X_clicked),
4131 gtk_widget_set_state(w_button, GTK_STATE_ACTIVE);
4133 gtk_widget_show (w_label);
4134 gtk_widget_show (pixmap);
4135 gtk_widget_show (w_button);
4136 gtk_widget_show (w_hbox);
4138 tab->label = w_hbox;
4142 tab
->label
= gtk_label_new (label
);
4144 gtk_widget_show(tab
->label
);
4145 gtk_widget_show(tab
->scrollbar
);
4146 gtk_widget_show(tab
->MTimebar
);
4147 gtk_widget_show(tab
->viewer_container
);
4148 gtk_widget_show(tab
->vbox
);
4150 //gtk_widget_show(tab->multivpaned);
4153 /* Start with empty events requests list */
4154 tab
->events_requests
= NULL
;
4155 tab
->events_request_pending
= FALSE
;
4156 tab
->stop_foreground
= FALSE
;
4160 g_signal_connect(G_OBJECT(tab
->scrollbar
), "value-changed",
4161 G_CALLBACK(scroll_value_changed_cb
), tab
);
4164 /* Timebar signal handler */
4165 g_signal_connect(G_OBJECT(tab
->MTimebar
), "start-time-changed",
4166 G_CALLBACK(on_timebar_starttime_changed
), tab
);
4167 g_signal_connect(G_OBJECT(tab
->MTimebar
), "end-time-changed",
4168 G_CALLBACK(on_timebar_endtime_changed
), tab
);
4169 g_signal_connect(G_OBJECT(tab
->MTimebar
), "current-time-changed",
4170 G_CALLBACK(on_timebar_currenttime_changed
), tab
);
4172 //g_signal_connect(G_OBJECT(tab->scrollbar), "changed",
4173 // G_CALLBACK(scroll_value_changed_cb), tab);
4176 //insert tab into notebook
4177 gtk_notebook_append_page(notebook
,
4180 list
= gtk_container_get_children(GTK_CONTAINER(notebook
));
4181 gtk_notebook_set_current_page(notebook
,g_list_length(list
)-1);
4182 // always show : not if(g_list_length(list)>1)
4183 gtk_notebook_set_show_tabs(notebook
, TRUE
);
4186 lttvwindow_report_time_window(tab
, copy_tab
->time_window
);
4187 lttvwindow_report_current_time(tab
, copy_tab
->current_time
);
4189 TimeWindow time_window
;
4191 time_window
.start_time
= ltt_time_zero
;
4192 time_window
.end_time
= ltt_time_add(time_window
.start_time
,
4193 lttvwindow_default_time_width
);
4194 time_window
.time_width
= lttvwindow_default_time_width
;
4195 time_window
.time_width_double
= ltt_time_to_double(time_window
.time_width
);
4197 lttvwindow_report_time_window(tab
, time_window
);
4198 lttvwindow_report_current_time(tab
, ltt_time_zero
);
4201 LttvTraceset
*traceset
= tab
->traceset_info
->traceset
;
4202 SetTraceset(tab
, traceset
);
4206 * execute_events_requests
4208 * Idle function that executes the pending requests for a tab.
4210 * @return return value : TRUE : keep the idle function, FALSE : remove it.
4212 gboolean
execute_events_requests(Tab
*tab
)
4214 return ( lttvwindow_process_pending_requests(tab
) );
4218 __EXPORT
void create_main_window_with_trace_list(GSList
*traces
)
4221 GSList
*iter
= NULL
;
4224 MainWindow
*mw
= construct_main_window(NULL
);
4225 GtkWidget
*widget
= mw
->mwindow
;
4227 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
4228 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
4229 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
4230 LttvPluginTab
*ptab
;
4234 ptab
= create_new_tab(widget
, NULL
);
4237 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
4241 LttvTraceset
* traceset
= lttv_traceset_new();
4242 for(iter
=traces
; iter
!=NULL
; iter
=g_slist_next(iter
)) {
4243 gchar
*path
= (gchar
*)iter
->data
;
4245 gchar abs_path
[PATH_MAX
];
4248 get_absolute_pathname(path
, abs_path
);
4250 if(lttv_traceset_add_path(traceset
,abs_path
) != 0 ){ /*failure*/
4252 g_warning("cannot open trace %s", abs_path
);
4254 GtkWidget
*dialogue
=
4255 gtk_message_dialog_new(
4256 GTK_WINDOW(gtk_widget_get_toplevel(widget
)),
4257 GTK_DIALOG_MODAL
|GTK_DIALOG_DESTROY_WITH_PARENT
,
4260 "Cannot open trace : maybe you should enter in the directory "
4262 gtk_dialog_run(GTK_DIALOG(dialogue
));
4263 gtk_widget_destroy(dialogue
);
4266 SetTraceset(tab
, traceset
);