1 /* This file is part of the Linux Trace Toolkit viewer
2 * Copyright (C) 2003-2004 XangXiu Yang, Mathieu Desnoyers
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License Version 2 as
6 * published by the Free Software Foundation;
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place - Suite 330, Boston,
23 #include <limits.h> // for PATH_MAX
31 #include "callbacks.h"
32 #include "interface.h"
34 #include <ltt/trace.h>
36 #include <ltt/event.h>
37 #include <lttv/lttv.h>
38 #include <lttv/module.h>
39 #include <lttv/iattribute.h>
40 #include <lttv/traceset.h>
41 #include <lttv/state.h>
43 #include <lttv/stats.h>
44 #include <lttv/sync/sync_chain_lttv.h>
45 #endif /* BABEL_CLEANUP */
46 #include <lttv/filter.h>
47 #include <lttvwindow/mainwindow.h>
48 #include <lttvwindow/mainwindow-private.h>
49 #include <lttvwindow/menu.h>
50 #include <lttvwindow/timebar.h>
51 #include <lttvwindow/toolbar.h>
52 #include <lttvwindow/lttvwindow.h>
53 #include <lttvwindow/lttvwindowtraces.h>
54 #include <lttvwindow/lttv_plugin_tab.h>
56 #include <babeltrace/babeltrace.h>
57 #include <babeltrace/ctf/events.h>
58 #include <babeltrace/ctf/iterator.h>
60 static LttTime lttvwindow_default_time_width
= { 1, 0 };
61 #define CLIP_BUF 256 // size of clipboard buffer
63 extern LttvTrace
*g_init_trace
;
66 /** Array containing instanced objects. */
67 extern GSList
* g_main_window_list
;
69 /** MD : keep old directory. */
70 static char remember_plugins_dir
[PATH_MAX
] = "";
71 static char remember_trace_dir
[PATH_MAX
] = "";
73 void tab_destructor(LttvPluginTab
* ptab
);
75 MainWindow
* get_window_data_struct(GtkWidget
* widget
);
76 char * get_load_module(MainWindow
*mw
,
77 char ** load_module_name
, int nb_module
);
78 char * get_unload_module(MainWindow
*mw
,
79 char ** loaded_module_name
, int nb_module
);
80 char * get_remove_trace(MainWindow
*mw
, char ** all_trace_name
, int nb_trace
);
81 char * get_selection(MainWindow
*mw
,
82 char ** all_name
, int nb
, char *title
, char * column_title
);
83 void init_tab(Tab
*tab
, MainWindow
* mw
, Tab
*copy_tab
,
84 GtkNotebook
* notebook
, char * label
);
86 int update_traceset(Tab
*tab
, LttvTraceset
*traceset
);
88 static void insert_viewer(GtkWidget
* widget
, lttvwindow_viewer_constructor constructor
);
90 LttvPluginTab
*create_new_tab(GtkWidget
* widget
, gpointer user_data
);
92 static gboolean
lttvwindow_process_pending_requests(Tab
*tab
);
94 static void on_timebar_starttime_changed(Timebar
*timebar
,
96 static void on_timebar_endtime_changed(Timebar
*timebar
,
98 static void on_timebar_currenttime_changed(Timebar
*timebar
,
115 static void on_top_notify(GObject
*gobject
,
119 Tab
*tab
= (Tab
*)user_data
;
120 g_message("in on_top_notify.\n");
124 static gboolean
viewer_grab_focus(GtkWidget
*widget
, GdkEventButton
*event
,
127 GtkWidget
*viewer
= GTK_WIDGET(data
);
128 GtkWidget
*viewer_container
= gtk_widget_get_parent(viewer
);
130 g_debug("FOCUS GRABBED");
131 g_object_set_data(G_OBJECT(viewer_container
), "focused_viewer", viewer
);
136 static void connect_focus_recursive(GtkWidget
*widget
,
139 if(GTK_IS_CONTAINER(widget
)) {
140 gtk_container_forall(GTK_CONTAINER(widget
),
141 (GtkCallback
)connect_focus_recursive
,
145 if(GTK_IS_TREE_VIEW(widget
)) {
146 gtk_tree_view_set_headers_clickable(GTK_TREE_VIEW(widget
), TRUE
);
148 gtk_widget_add_events(widget
, GDK_BUTTON_PRESS_MASK
);
149 g_signal_connect (G_OBJECT(widget
),
150 "button-press-event",
151 G_CALLBACK (viewer_grab_focus
),
155 /* Stop all the processings and call gtk_main_quit() */
156 static void mainwindow_quit()
158 lttvwindowtraces_unregister_requests(g_quark_from_string("stats"));
159 lttvwindowtraces_unregister_requests(g_quark_from_string("state"));
160 lttvwindowtraces_unregister_computation_hooks(g_quark_from_string("stats"));
161 lttvwindowtraces_unregister_computation_hooks(g_quark_from_string("state"));
167 /* insert_viewer function constructs an instance of a viewer first,
168 * then inserts the widget of the instance into the container of the
173 insert_viewer_wrap(GtkWidget
*menuitem
, gpointer user_data
)
175 insert_viewer((GtkWidget
*)menuitem
, (lttvwindow_viewer_constructor
)user_data
);
179 /* internal functions */
180 void insert_viewer(GtkWidget
* widget
, lttvwindow_viewer_constructor constructor
)
182 GtkWidget
* viewer_container
;
183 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
185 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
186 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
191 ptab
= create_new_tab(widget
, NULL
);
193 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
197 viewer_container
= tab
->viewer_container
;
199 viewer
= (GtkWidget
*)constructor(&ptab
->parent
);
202 //gtk_multivpaned_widget_add(GTK_MULTIVPANED(multivpaned), viewer);
204 gtk_box_pack_end(GTK_BOX(viewer_container
),
210 /* We want to connect the viewer_grab_focus to EVERY
211 * child of this widget. The little trick is to get each child
212 * of each GTK_CONTAINER, even subchildren.
214 connect_focus_recursive(viewer
, viewer
);
219 * Function to set/update traceset for the viewers
220 * @param tab viewer's tab
221 * @param traceset traceset of the main window.
223 * 0 : traceset updated
224 * 1 : no traceset hooks to update; not an error.
227 int SetTraceset(Tab
* tab
, LttvTraceset
*traceset
)
230 TimeInterval time_span
;
231 TimeWindow new_time_window
;
232 LttTime new_current_time
;
235 // Perform time synchronization on the traces
236 if (syncTraceset(tsc
))
238 /* There is some time-dependant information that was calculated during
239 * context initialization. Destroy the old contexts and initialize new
241 * Modified from lttvwindow_add_trace()
243 // Keep a reference to the traces so they are not freed
244 for(i
= 0; i
< lttv_traceset_number(traceset
); i
++)
246 LttvTrace
*trace
= lttv_traceset_get(traceset
, i
);
247 lttv_trace_ref(trace
);
250 // Remove state update hooks
251 lttv_state_remove_event_hooks(
252 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
254 lttv_context_fini(LTTV_TRACESET_CONTEXT(
255 tab
->traceset_info
->traceset_context
));
256 g_object_unref(tab
->traceset_info
->traceset_context
);
258 for(i
= 0; i
< lttv_traceset_number(traceset
); i
++)
260 LttvTrace
*trace
= lttv_traceset_get(traceset
, i
);
261 lttvwindowtraces_remove_trace(trace
);
262 lttvwindowtraces_add_trace(trace
);
265 // Create new context
266 tab
->traceset_info
->traceset_context
=
267 g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
268 lttv_context_init(LTTV_TRACESET_CONTEXT(tab
->traceset_info
->
269 traceset_context
), traceset
);
271 // Add state update hooks
272 lttv_state_add_event_hooks(
273 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
275 // Remove local reference to the traces
276 for(i
=0; i
<lttv_traceset_number(traceset
); i
++)
278 LttvTrace
*trace
= lttv_traceset_get(traceset
, i
);
279 lttv_trace_unref(trace
);
282 tsc
= LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
284 #endif /*BABEL_CLEANUP*/
286 time_span
= lttv_traceset_get_time_span_real(traceset
);
288 tab
->traceset_info
->traceset
= traceset
;
290 new_time_window
= tab
->time_window
;
291 new_current_time
= tab
->current_time
;
293 /* Set the tab's time window and current time if
295 if(ltt_time_compare(tab
->time_window
.start_time
, time_span
.start_time
) < 0
296 || ltt_time_compare(tab
->time_window
.end_time
,
297 time_span
.end_time
) > 0) {
298 new_time_window
.start_time
= time_span
.start_time
;
300 new_current_time
= time_span
.start_time
;
304 if(ltt_time_compare(lttvwindow_default_time_width
,
305 ltt_time_sub(time_span
.end_time
, time_span
.start_time
)) < 0
307 ltt_time_compare(time_span
.end_time
, time_span
.start_time
) == 0)
308 tmp_time
= lttvwindow_default_time_width
;
310 tmp_time
= time_span
.end_time
;
312 new_time_window
.time_width
= tmp_time
;
313 new_time_window
.time_width_double
= ltt_time_to_double(tmp_time
);
314 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
315 new_time_window
.time_width
) ;
317 lttv_state_add_event_hooks(traceset
);
319 //TODO ybrosseau 2012-08-03 Temporarly compute checkpoints right at the adding
321 //Compute the traceset state checkpoint
324 EventsRequest
*events_request
= g_new(EventsRequest
, 1);
326 LttvHooks
*hook_adder
= lttv_hooks_new();
327 lttv_hooks_add(hook_adder
, lttv_state_save_hook_add_event_hooks
, NULL
,
329 LttvHooks
*hook_remover
= lttv_hooks_new();
330 lttv_hooks_add(hook_remover
, lttv_state_save_hook_remove_event_hooks
,
331 NULL
, LTTV_PRIO_DEFAULT
);
333 // Fill the events request
334 events_request
->owner
= NULL
;
335 events_request
->viewer_data
= NULL
;
336 events_request
->servicing
= FALSE
;
337 events_request
->start_time
= ltt_time_zero
;
338 events_request
->start_position
= NULL
;
339 events_request
->stop_flag
= FALSE
;
340 events_request
->end_time
= ltt_time_infinite
;
341 events_request
->num_events
= G_MAXUINT
;
342 events_request
->end_position
= NULL
;
343 events_request
->trace
= 1; //fixed /* FIXME */
344 events_request
->before_chunk_traceset
= NULL
;
345 events_request
->before_chunk_trace
= NULL
;
346 events_request
->before_chunk_tracefile
= NULL
;
347 events_request
->event
= NULL
;
348 events_request
->after_chunk_tracefile
= NULL
;
349 events_request
->after_chunk_trace
= NULL
;
350 events_request
->after_chunk_traceset
= NULL
;
351 events_request
->before_request
= hook_adder
;
352 events_request
->after_request
= hook_remover
;
354 lttvwindow_events_request(tab
, events_request
);
357 /* Finally, call the update hooks of the viewers */
358 gint retval
= update_traceset(tab
, traceset
);
360 time_change_manager(tab
, new_time_window
);
361 current_time_change_manager(tab
, new_current_time
);
368 * Function to set/update filter for the viewers
369 * @param tab viewer's tab
370 * @param filter filter of the main window.
373 * 0 : filters updated
374 * 1 : no filter hooks to update; not an error.
377 int SetFilter(Tab
* tab
, gpointer filter
)
380 LttvAttributeValue value
;
382 g_assert(lttv_iattribute_find_by_path(tab
->attributes
,
383 "hooks/updatefilter", LTTV_POINTER
, &value
));
385 tmp
= (LttvHooks
*)*(value
.v_pointer
);
387 if(tmp
== NULL
) return 1;
388 lttv_hooks_call(tmp
,filter
);
396 * Function to redraw each viewer belonging to the current tab
397 * @param tab viewer's tab
400 int update_traceset(Tab
*tab
, LttvTraceset
*traceset
)
402 LttvAttributeValue value
;
406 retval
= lttv_iattribute_find_by_path(tab
->attributes
,
407 "hooks/updatetraceset",
411 tmp
= (LttvHooks
*)*(value
.v_pointer
);
415 lttv_hooks_call(tmp
, traceset
);
421 Call hooks register to get update on traceset time span changes
423 int notify_time_span_changed(Tab
*tab
)
425 LttvAttributeValue value
;
429 retval
= lttv_iattribute_find_by_path(tab
->attributes
,
430 "hooks/updatetimespan",
434 tmp
= (LttvHooks
*)*(value
.v_pointer
);
438 lttv_hooks_call(tmp
, NULL
);
443 /* get_label function is used to get user input, it displays an input
444 * box, which allows user to input a string
447 void get_label_string (GtkWidget
* text
, gchar
* label
)
449 GtkEntry
* entry
= (GtkEntry
*)text
;
450 if(strlen(gtk_entry_get_text(entry
))!=0)
451 strcpy(label
,gtk_entry_get_text(entry
));
454 gboolean
get_label(MainWindow
* mw
, gchar
* str
, gchar
* dialogue_title
, gchar
* label_str
)
456 GtkWidget
* dialogue
;
461 dialogue
= gtk_dialog_new_with_buttons(dialogue_title
,NULL
,
463 GTK_STOCK_OK
,GTK_RESPONSE_ACCEPT
,
464 GTK_STOCK_CANCEL
,GTK_RESPONSE_REJECT
,
467 label
= gtk_label_new(label_str
);
468 gtk_widget_show(label
);
470 text
= gtk_entry_new();
471 gtk_widget_show(text
);
473 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialogue
)->vbox
), label
,TRUE
, TRUE
,0);
474 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialogue
)->vbox
), text
,FALSE
, FALSE
,0);
476 id
= gtk_dialog_run(GTK_DIALOG(dialogue
));
478 case GTK_RESPONSE_ACCEPT
:
479 get_label_string(text
,str
);
480 gtk_widget_destroy(dialogue
);
482 case GTK_RESPONSE_REJECT
:
484 gtk_widget_destroy(dialogue
);
491 /* get_window_data_struct function is actually a lookup function,
492 * given a widget which is in the tree of the main window, it will
493 * return the MainWindow data structure associated with main window
496 MainWindow
* get_window_data_struct(GtkWidget
* widget
)
499 MainWindow
* mw_data
;
501 mw
= lookup_widget(widget
, "MWindow");
503 g_info("Main window does not exist\n");
507 mw_data
= (MainWindow
*) g_object_get_data(G_OBJECT(mw
),"main_window_data");
509 g_warning("Main window data does not exist\n");
516 /* create_new_window function, just constructs a new main window
519 void create_new_window(GtkWidget
* widget
, gpointer user_data
, gboolean clone
)
521 MainWindow
* parent
= get_window_data_struct(widget
);
524 g_info("Clone : use the same traceset\n");
525 construct_main_window(parent
);
527 g_info("Empty : traceset is set to NULL\n");
528 construct_main_window(NULL
);
532 /* Get the currently focused viewer.
533 * If no viewer is focused, use the first one.
535 * If no viewer available, return NULL.
537 GtkWidget
*viewer_container_focus(GtkWidget
*container
)
541 widget
= (GtkWidget
*)g_object_get_data(G_OBJECT(container
),
545 g_debug("no widget focused");
546 GList
*children
= gtk_container_get_children(GTK_CONTAINER(container
));
549 widget
= GTK_WIDGET(children
->data
);
550 g_object_set_data(G_OBJECT(container
),
560 gint
viewer_container_position(GtkWidget
*container
, GtkWidget
*child
)
563 if(child
== NULL
) return -1;
567 memset(&value
, 0, sizeof(GValue
));
568 g_value_init(&value
, G_TYPE_INT
);
569 gtk_container_child_get_property(GTK_CONTAINER(container
),
573 pos
= g_value_get_int(&value
);
579 /* move_*_viewer functions move the selected view up/down in
583 void move_down_viewer(GtkWidget
* widget
, gpointer user_data
)
585 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
587 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
588 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
595 ptab
= g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
599 //gtk_multivpaned_widget_move_up(GTK_MULTIVPANED(tab->multivpaned));
601 /* change the position in the vbox */
602 GtkWidget
*focus_widget
;
604 focus_widget
= viewer_container_focus(tab
->viewer_container
);
605 position
= viewer_container_position(tab
->viewer_container
, focus_widget
);
608 /* can move up one position */
609 gtk_box_reorder_child(GTK_BOX(tab
->viewer_container
),
616 void move_up_viewer(GtkWidget
* widget
, gpointer user_data
)
618 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
620 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
621 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
628 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
632 //gtk_multivpaned_widget_move_down(GTK_MULTIVPANED(tab->multivpaned));
633 /* change the position in the vbox */
634 GtkWidget
*focus_widget
;
636 focus_widget
= viewer_container_focus(tab
->viewer_container
);
637 position
= viewer_container_position(tab
->viewer_container
, focus_widget
);
641 g_list_length(gtk_container_get_children(
642 GTK_CONTAINER(tab
->viewer_container
)))-1
644 /* can move down one position */
645 gtk_box_reorder_child(GTK_BOX(tab
->viewer_container
),
653 /* delete_viewer deletes the selected viewer in the current tab
656 void delete_viewer(GtkWidget
* widget
, gpointer user_data
)
658 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
660 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
661 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
668 ptab
= g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
672 //gtk_multivpaned_widget_delete(GTK_MULTIVPANED(tab->multivpaned));
674 GtkWidget
*focus_widget
= viewer_container_focus(tab
->viewer_container
);
676 if(focus_widget
!= NULL
)
677 gtk_widget_destroy(focus_widget
);
679 g_object_set_data(G_OBJECT(tab
->viewer_container
), "focused_viewer", NULL
);
682 #if UNFINISHED_FEATURE
683 /* TODO ybrosseau 2012-03-15: Function is half implemented. Should be removed */
684 /* open_traceset will open a traceset saved in a file
685 * Right now, it is not finished yet, (not working)
689 void open_traceset(GtkWidget
* widget
, gpointer user_data
)
693 LttvTraceset
* traceset
;
694 MainWindow
* mw_data
= get_window_data_struct(widget
);
695 GtkFileSelection
* file_selector
=
696 (GtkFileSelection
*)gtk_file_selection_new("Select a traceset");
698 gtk_file_selection_hide_fileop_buttons(file_selector
);
700 gtk_window_set_transient_for(GTK_WINDOW(file_selector
),
701 GTK_WINDOW(mw_data
->mwindow
));
703 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
705 case GTK_RESPONSE_ACCEPT
:
706 case GTK_RESPONSE_OK
:
707 dir
= gtk_file_selection_get_selections (file_selector
);
708 traceset
= lttv_traceset_load(dir
[0]);
709 g_info("Open a trace set %s\n", dir
[0]);
712 case GTK_RESPONSE_REJECT
:
713 case GTK_RESPONSE_CANCEL
:
715 gtk_widget_destroy((GtkWidget
*)file_selector
);
721 /* lttvwindow_process_pending_requests
723 * Process requests for parts of the trace from viewers.
725 * These requests are made by lttvwindow_events_request().
727 * This internal function gets called by g_idle, taking care of the pending
728 * requests. It is responsible for concatenation of time intervals and position
729 * requests. It does it with the following algorithm organizing process traceset
730 * calls. Here is the detailed description of the way it works :
732 * - Events Requests Servicing Algorithm
734 * Data structures necessary :
736 * List of requests added to context : list_in
737 * List of requests not added to context : list_out
742 * list_out : many events requests
744 * FIXME : insert rest of algorithm here
748 #define list_out tab->events_requests
750 gboolean
lttvwindow_process_pending_requests(Tab
*tab
)
755 GSList
*list_in
= NULL
;
759 LttvTracesetPosition
*end_position
;
761 if(lttvwindow_preempt_count
> 0) return TRUE
;
764 g_critical("Foreground processing : tab does not exist. Processing removed.");
768 /* There is no events requests pending : we should never have been called! */
769 g_assert(g_slist_length(list_out
) != 0);
771 ts
= tab
->traceset_info
->traceset
;
773 //set the cursor to be X shape, indicating that the computer is busy in doing its job
775 new = gdk_cursor_new(GDK_X_CURSOR
);
776 widget
= lookup_widget(tab
->mw
->mwindow
, "MToolbar1");
777 win
= gtk_widget_get_parent_window(widget
);
778 gdk_window_set_cursor(win
, new);
779 gdk_cursor_unref(new);
780 gdk_window_stick(win
);
781 gdk_window_unstick(win
);
784 g_debug("SIZE events req len : %d", g_slist_length(list_out
));
786 /* Preliminary check for no trace in traceset */
787 /* Unregister the routine if empty, empty list_out too */
788 if(lttv_traceset_number(ts
) == 0) {
790 /* - For each req in list_out */
791 GSList
*iter
= list_out
;
793 while(iter
!= NULL
) {
795 gboolean remove
= FALSE
;
796 gboolean free_data
= FALSE
;
797 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
799 /* - Call end request for req */
800 if(events_request
->servicing
== TRUE
)
801 lttv_hooks_call(events_request
->after_request
, (gpointer
)ts
);
803 /* - remove req from list_out */
804 /* Destroy the request */
807 //TODO ybrosseau: This if is always true
811 GSList
*remove_iter
= iter
;
813 iter
= g_slist_next(iter
);
814 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
815 list_out
= g_slist_remove_link(list_out
, remove_iter
);
816 } else { // not remove
817 iter
= g_slist_next(iter
);
822 /* 0.1 Lock Traces */
827 iter_trace
<lttv_traceset_number(ts
);
829 LttvTrace
*trace_v
= lttv_traceset_get(ts
, iter_trace
);
831 if(lttvwindowtraces_lock(trace_v
) != 0) {
832 g_critical("Foreground processing : Unable to get trace lock");
833 return TRUE
; /* Cannot get lock, try later */
838 /* 0.2 Seek tracefiles positions to context position */
840 //g_assert(lttv_process_traceset_seek_position(tsc, sync_position) == 0);
841 lttv_process_traceset_synchronize_tracefiles(tsc
);
844 /* Events processing algorithm implementation */
845 /* Warning : the gtk_events_pending takes a LOT of cpu time. So what we do
846 * instead is to leave the control to GTK and take it back.
848 /* A. Servicing loop */
849 //while( (g_slist_length(list_in) != 0 || g_slist_length(list_out) != 0)) {
850 if((g_slist_length(list_in
) != 0 || g_slist_length(list_out
) != 0)) {
852 /* 1. If list_in is empty (need a seek) */
853 if( g_slist_length(list_in
) == 0 ) {
855 /* list in is empty, need a seek */
857 /* 1.1 Add requests to list_in */
858 GSList
*ltime
= NULL
;
862 /* 1.1.1 Find all time requests with the lowest start time in list_out
865 if(g_slist_length(list_out
) > 0)
866 ltime
= g_slist_append(ltime
, g_slist_nth_data(list_out
, 0));
867 for(iter
=g_slist_nth(list_out
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
868 /* Find all time requests with the lowest start time in list_out */
869 EventsRequest
*event_request_ltime
= (EventsRequest
*)g_slist_nth_data(ltime
, 0);
870 EventsRequest
*event_request_list_out
= (EventsRequest
*)iter
->data
;
873 comp
= ltt_time_compare(event_request_ltime
->start_time
,
874 event_request_list_out
->start_time
);
876 ltime
= g_slist_append(ltime
, event_request_list_out
);
878 /* Remove all elements from ltime, and add current */
880 ltime
= g_slist_delete_link(ltime
, g_slist_nth(ltime
, 0));
881 ltime
= g_slist_append(ltime
, event_request_list_out
);
885 /* 1.1.2 Find all position requests with the lowest position in list_out
888 if(g_slist_length(list_out
) > 0)
889 lpos
= g_slist_append(lpos
, g_slist_nth_data(list_out
, 0));
890 for(iter
=g_slist_nth(list_out
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
891 /* Find all position requests with the lowest position in list_out */
892 EventsRequest
*event_request_lpos
= (EventsRequest
*)g_slist_nth_data(lpos
, 0);
893 EventsRequest
*event_request_list_out
= (EventsRequest
*)iter
->data
;
896 if(event_request_lpos
->start_position
!= NULL
897 && event_request_list_out
->start_position
!= NULL
)
899 //TODO ybrosseau: this compare is in fact an equal, so the behavior might not be right.
900 comp
= lttv_traceset_position_time_compare
901 (event_request_lpos
->start_position
,
902 event_request_list_out
->start_position
);
907 lpos
= g_slist_append(lpos
, event_request_list_out
);
909 /* Remove all elements from lpos, and add current */
911 lpos
= g_slist_delete_link(lpos
, g_slist_nth(lpos
, 0));
912 lpos
= g_slist_append(lpos
, event_request_list_out
);
917 EventsRequest
*event_request_lpos
= (EventsRequest
*)g_slist_nth_data(lpos
, 0);
918 EventsRequest
*event_request_ltime
= (EventsRequest
*)g_slist_nth_data(ltime
, 0);
919 LttTime lpos_start_time
;
921 if(event_request_lpos
!= NULL
922 && event_request_lpos
->start_position
!= NULL
) {
923 lpos_start_time
= lttv_traceset_position_get_time(
924 event_request_lpos
->start_position
);
927 /* 1.1.3 If lpos.start time < ltime */
928 if(event_request_lpos
!= NULL
929 && event_request_lpos
->start_position
!= NULL
930 && ltt_time_compare(lpos_start_time
,
931 event_request_ltime
->start_time
)<0) {
932 /* Add lpos to list_in, remove them from list_out */
933 for(iter
=lpos
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
935 EventsRequest
*event_request_lpos
=
936 (EventsRequest
*)iter
->data
;
938 list_in
= g_slist_append(list_in
, event_request_lpos
);
939 /* Remove from list_out */
940 list_out
= g_slist_remove(list_out
, event_request_lpos
);
943 /* 1.1.4 (lpos.start time >= ltime) */
944 /* Add ltime to list_in, remove them from list_out */
946 for(iter
=ltime
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
948 EventsRequest
*event_request_ltime
=
949 (EventsRequest
*)iter
->data
;
951 list_in
= g_slist_append(list_in
, event_request_ltime
);
952 /* Remove from list_out */
953 list_out
= g_slist_remove(list_out
, event_request_ltime
);
964 g_assert(g_slist_length(list_in
)>0);
965 EventsRequest
*events_request
= g_slist_nth_data(list_in
, 0);
970 /* 1.2.1 If first request in list_in is a time request */
971 if(events_request
->start_position
== NULL
) {
972 /* - If first req in list_in start time != current time */
973 //TODO ybrosseau: if commented out, since it was only affecting the g_debug
974 //if(tfc == NULL || ltt_time_compare(events_request->start_time,
975 // tfc->timestamp) != 0)
976 /* - Seek to that time */
977 g_debug("SEEK TIME : %lu, %lu", events_request
->start_time
.tv_sec
,
978 events_request
->start_time
.tv_nsec
);
979 lttv_state_traceset_seek_time_closest(ts
,
980 events_request
->start_time
);
982 /* Process the traceset with only state hooks */
986 lttv_process_traceset_middle(ts
,
987 events_request
->start_time
,
990 g_assert(seek_count
< LTTV_STATE_SAVE_INTERVAL
);
996 //LttvTracefileContext *tfc =
997 // lttv_traceset_context_get_current_tfc(tsc);
998 /* Else, the first request in list_in is a position request */
999 /* If first req in list_in pos != current pos */
1000 g_assert(events_request
->start_position
!= NULL
);
1001 g_debug("SEEK POS time : %lu, %lu",
1002 lttv_traceset_position_get_time(
1003 events_request
->start_position
).tv_sec
,
1004 lttv_traceset_position_get_time(
1005 events_request
->start_position
).tv_nsec
);
1007 /*if(tfc) {*/ if(0) {
1008 /* g_debug("SEEK POS context time : %lu, %lu",
1009 tfc->timestamp.tv_sec,
1010 tfc->timestamp.tv_nsec); */
1012 g_debug("SEEK POS context time : %lu, %lu",
1013 ltt_time_infinite
.tv_sec
,
1014 ltt_time_infinite
.tv_nsec
);
1016 g_assert(events_request
->start_position
!= NULL
);
1017 //TODO ybrosseau: for now, always seek
1018 if(/*lttv_traceset_context_ctx_pos_compare(tsc,
1019 events_request->start_position) != 0*/1) {
1020 /* 1.2.2.1 Seek to that position */
1021 g_debug("SEEK POSITION");
1022 //lttv_process_traceset_seek_position(tsc, events_request->start_position);
1023 pos_time
= lttv_traceset_position_get_time(
1024 events_request
->start_position
);
1026 lttv_state_traceset_seek_time_closest(ts
,
1028 //lttv_traceset_seek_to_position( events_request->start_position);
1030 /* Process the traceset with only state hooks */
1034 lttv_process_traceset_middle(ts
,
1037 events_request
->start_position
);
1039 //g_assert(lttv_traceset_context_ctx_pos_compare(tsc,
1040 // events_request->start_position) == 0);
1047 /* 1.3 Add hooks and call before request for all list_in members */
1049 GSList
*iter
= NULL
;
1050 for(iter
=list_in
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
1051 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1052 /* 1.3.1 If !servicing */
1053 if(events_request
->servicing
== FALSE
) {
1054 /* - begin request hooks called
1055 * - servicing = TRUE
1057 lttv_hooks_call(events_request
->before_request
, (gpointer
)ts
);
1058 events_request
->servicing
= TRUE
;
1060 /* 1.3.2 call before chunk
1061 * 1.3.3 events hooks added
1063 //TODO ybrosseau 2012-07-10: || TRUE added since we only support
1064 // traceset wide requests
1065 if(events_request
->trace
== -1 || TRUE
) {
1067 lttv_process_traceset_begin(ts
,
1068 events_request
->before_chunk_traceset
,
1069 events_request
->before_chunk_trace
,
1070 events_request
->event
1073 guint nb_trace
= lttv_traceset_number(ts
);
1074 g_assert((guint
)events_request
->trace
< nb_trace
&&
1075 events_request
->trace
> -1);
1076 LttvTrace
*trace
= lttv_traceset_get(ts
, events_request
->trace
);
1078 lttv_hooks_call(events_request
->before_chunk_traceset
, ts
);
1080 lttv_trace_add_hooks(trace
, events_request
->before_chunk_trace
,
1081 events_request
->event
);
1086 /* 2. Else, list_in is not empty, we continue a read */
1089 /* 2.0 For each req of list_in */
1090 GSList
*iter
= list_in
;
1092 while(iter
!= NULL
) {
1094 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1096 /* - Call before chunk
1097 * - events hooks added
1099 //TODO ybrosseau 2012-07-10: || TRUE added since we only support
1100 // traceset wide requests
1101 if(events_request
->trace
== -1 || TRUE
)
1102 lttv_process_traceset_begin(ts
,
1103 events_request
->before_chunk_traceset
,
1104 events_request
->before_chunk_trace
,
1105 events_request
->event
1108 guint nb_trace
= lttv_traceset_number(ts
);
1109 g_assert((guint
)events_request
->trace
< nb_trace
&&
1110 events_request
->trace
> -1);
1111 LttvTrace
*trace
= lttv_traceset_get(ts
, events_request
->trace
);
1113 lttv_hooks_call(events_request
->before_chunk_traceset
, ts
);
1115 lttv_trace_add_hooks(trace
,
1116 events_request
->before_chunk_trace
,
1117 events_request
->event
1121 iter
= g_slist_next(iter
);
1128 /* 2.1 For each req of list_out */
1129 GSList
*iter
= list_out
;
1131 while(iter
!= NULL
) {
1133 gboolean remove
= FALSE
;
1134 gboolean free_data
= FALSE
;
1135 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1137 /* if req.start time == current context time
1138 * or req.start position == current position*/
1139 /* if( ltt_time_compare(events_request->start_time,
1140 tfc->timestamp) == 0
1142 (events_request->start_position != NULL
1144 lttv_traceset_context_ctx_pos_compare(tsc,
1145 events_request->start_position) == 0)
1148 if(lttv_traceset_position_compare_current(ts
, events_request
->start_position
) == 0) {
1150 /* - Add to list_in, remove from list_out */
1151 list_in
= g_slist_append(list_in
, events_request
);
1155 /* - If !servicing */
1156 if(events_request
->servicing
== FALSE
) {
1157 /* - begin request hooks called
1158 * - servicing = TRUE
1160 lttv_hooks_call(events_request
->before_request
, (gpointer
)ts
);
1161 events_request
->servicing
= TRUE
;
1163 /* call before chunk
1164 * events hooks added
1166 //TODO ybrosseau 2012-07-10: || TRUE added since we only support
1167 // traceset wide requests
1168 if(events_request
->trace
== -1 || TRUE
)
1169 lttv_process_traceset_begin(ts
,
1170 events_request
->before_chunk_traceset
,
1171 events_request
->before_chunk_trace
,
1172 events_request
->event
1175 guint nb_trace
= lttv_traceset_number(ts
);
1176 g_assert((guint
)events_request
->trace
< nb_trace
&&
1177 events_request
->trace
> -1);
1178 LttvTrace
* trace
= lttv_traceset_get(ts
,events_request
->trace
);
1180 lttv_hooks_call(events_request
->before_chunk_traceset
, ts
);
1182 lttv_trace_add_hooks(trace
,
1183 events_request
->before_chunk_trace
,
1185 events_request
->event
);
1195 GSList
*remove_iter
= iter
;
1197 iter
= g_slist_next(iter
);
1198 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
1199 list_out
= g_slist_remove_link(list_out
, remove_iter
);
1200 } else { // not remove
1201 iter
= g_slist_next(iter
);
1207 /* 3. Find end criterions */
1212 /* 3.1.1 Find lowest end time in list_in */
1213 g_assert(g_slist_length(list_in
)>0);
1214 end_time
= ((EventsRequest
*)g_slist_nth_data(list_in
,0))->end_time
;
1216 for(iter
=g_slist_nth(list_in
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
1217 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1219 if(ltt_time_compare(events_request
->end_time
,
1221 end_time
= events_request
->end_time
;
1224 /* 3.1.2 Find lowest start time in list_out */
1225 for(iter
=list_out
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
1226 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1228 if(ltt_time_compare(events_request
->start_time
,
1230 end_time
= events_request
->start_time
;
1235 /* 3.2 Number of events */
1237 /* 3.2.1 Find lowest number of events in list_in */
1240 end_nb_events
= ((EventsRequest
*)g_slist_nth_data(list_in
,0))->num_events
;
1242 for(iter
=g_slist_nth(list_in
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
1243 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1245 if(events_request
->num_events
< end_nb_events
)
1246 end_nb_events
= events_request
->num_events
;
1249 /* 3.2.2 Use min(CHUNK_NUM_EVENTS, min num events in list_in) as
1252 end_nb_events
= MIN(CHUNK_NUM_EVENTS
, end_nb_events
);
1256 /* 3.3 End position */
1258 /* 3.3.1 Find lowest end position in list_in */
1261 end_position
=((EventsRequest
*)g_slist_nth_data(list_in
,0))->end_position
;
1263 for(iter
=g_slist_nth(list_in
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
1264 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1266 if(events_request
->end_position
!= NULL
&& end_position
!= NULL
&&
1267 lttv_traceset_position_time_compare(events_request
->end_position
,
1269 end_position
= events_request
->end_position
;
1274 /* 3.3.2 Find lowest start position in list_out */
1277 for(iter
=list_out
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
1278 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1280 if(events_request
->end_position
!= NULL
&& end_position
!= NULL
&&
1281 lttv_traceset_position_time_compare(events_request
->end_position
,
1283 end_position
= events_request
->end_position
;
1288 /* 4. Call process traceset middle */
1289 g_debug("Calling process traceset middle with %p, %lu sec %lu nsec, %u nb ev, %p end pos", ts
, end_time
.tv_sec
, end_time
.tv_nsec
, end_nb_events
, end_position
);
1290 count
= lttv_process_traceset_middle(ts
, end_time
, end_nb_events
, end_position
);
1292 #ifdef BABEL_CLEANUP
1293 tfc
= lttv_traceset_context_get_current_tfc(tsc
);
1295 g_debug("Context time after middle : %lu, %lu", tfc
->timestamp
.tv_sec
,
1296 tfc
->timestamp
.tv_nsec
);
1298 g_debug("End of trace reached after middle.");
1303 /* 5. After process traceset middle */
1305 LttTime curTime
= lttv_traceset_get_current_time(ts
);
1306 /* - if the iterator is not valid anymore (got to the end) */
1307 if(bt_ctf_iter_read_event(ts
->iter
) == NULL
) {
1308 /* - For each req in list_in */
1309 GSList
*iter
= list_in
;
1311 while(iter
!= NULL
) {
1313 gboolean remove
= FALSE
;
1314 gboolean free_data
= FALSE
;
1315 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1317 /* - Remove events hooks for req
1318 * - Call end chunk for req
1320 //TODO ybrosseau 2012-07-10: || TRUE added since we only support
1321 // traceset wide requests
1322 if(events_request
->trace
== -1 || TRUE
)
1323 lttv_process_traceset_end(ts
,
1324 events_request
->after_chunk_traceset
,
1325 events_request
->after_chunk_trace
,
1327 events_request
->event
);
1330 guint nb_trace
= lttv_traceset_number(ts
);
1331 g_assert(events_request
->trace
< nb_trace
&&
1332 events_request
->trace
> -1);
1333 LttvTrace
*trace
= lttv_traceset_get(ts
,events_request
->trace
);
1335 lttv_trace_remove_hooks(trace
,
1336 events_request
->after_chunk_trace
,
1338 events_request
->event
);
1340 lttv_hooks_call(events_request
->after_chunk_traceset
, ts
);
1345 /* - Call end request for req */
1346 lttv_hooks_call(events_request
->after_request
, (gpointer
)ts
);
1348 /* - remove req from list_in */
1349 /* Destroy the request */
1356 GSList
*remove_iter
= iter
;
1358 iter
= g_slist_next(iter
);
1359 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
1360 list_in
= g_slist_remove_link(list_in
, remove_iter
);
1361 } else { // not remove
1362 iter
= g_slist_next(iter
);
1367 /* 5.1 For each req in list_in */
1368 GSList
*iter
= list_in
;
1370 while(iter
!= NULL
) {
1372 gboolean remove
= FALSE
;
1373 gboolean free_data
= FALSE
;
1374 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1376 /* - Remove events hooks for req
1377 * - Call end chunk for req
1379 //TODO ybrosseau 2012-07-10: || TRUE added since we only support
1380 // traceset wide requests
1381 if(events_request
->trace
== -1 || TRUE
) {
1382 lttv_process_traceset_end(ts
,
1383 events_request
->after_chunk_traceset
,
1384 events_request
->after_chunk_trace
,
1385 events_request
->event
);
1387 guint nb_trace
= lttv_traceset_number(ts
);
1388 g_assert(events_request
->trace
< nb_trace
&&
1389 events_request
->trace
> -1);
1390 LttvTrace
*trace
= lttv_traceset_get(ts
, events_request
->trace
);
1392 lttv_trace_remove_hooks(trace
,
1393 events_request
->after_chunk_trace
,
1395 events_request
->event
);
1398 lttv_hooks_call(events_request
->after_chunk_traceset
, ts
);
1401 /* - req.num -= count */
1402 g_assert(events_request
->num_events
>= count
);
1403 events_request
->num_events
-= count
;
1405 //g_assert(tfc != NULL);
1406 /* - if req.num == 0
1408 * current context time >= req.end time
1410 * req.end pos == current pos
1412 * req.stop_flag == TRUE
1414 if( events_request
->num_events
== 0
1416 events_request
->stop_flag
== TRUE
1418 ltt_time_compare(lttv_traceset_get_current_time(ts
),
1419 events_request
->end_time
) >= 0
1421 (events_request
->end_position
!= NULL
1423 lttv_traceset_position_compare_current(ts
,
1424 events_request
->end_position
) == 0)
1427 g_assert(events_request
->servicing
== TRUE
);
1428 /* - Call end request for req
1429 * - remove req from list_in */
1430 lttv_hooks_call(events_request
->after_request
, (gpointer
)ts
);
1431 /* - remove req from list_in */
1432 /* Destroy the request */
1440 GSList
*remove_iter
= iter
;
1442 iter
= g_slist_next(iter
);
1443 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
1444 list_in
= g_slist_remove_link(list_in
, remove_iter
);
1445 } else { // not remove
1446 iter
= g_slist_next(iter
);
1452 /* End of removed servicing loop : leave control to GTK instead. */
1453 // if(gtk_events_pending()) break;
1456 /* B. When interrupted between chunks */
1459 GSList
*iter
= list_in
;
1461 /* 1. for each request in list_in */
1462 while(iter
!= NULL
) {
1464 gboolean remove
= FALSE
;
1465 gboolean free_data
= FALSE
;
1466 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1468 /* 1.1. Use current postition as start position */
1469 if(events_request
->start_position
!= NULL
)
1470 lttv_traceset_destroy_position(events_request
->start_position
);
1471 events_request
->start_position
= lttv_traceset_create_current_position(ts
);
1474 /* 1.2. Remove start time */
1475 events_request
->start_time
= ltt_time_infinite
;
1477 /* 1.3. Move from list_in to list_out */
1480 list_out
= g_slist_append(list_out
, events_request
);
1485 GSList
*remove_iter
= iter
;
1487 iter
= g_slist_next(iter
);
1488 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
1489 list_in
= g_slist_remove_link(list_in
, remove_iter
);
1490 } else { // not remove
1491 iter
= g_slist_next(iter
);
1497 /* C Unlock Traces */
1499 #ifdef BABEL_CLEANUP
1500 lttv_process_traceset_get_sync_data(tsc
);
1502 //lttv_traceset_context_position_save(tsc, sync_position);
1507 iter_trace
<lttv_traceset_number(ts
);
1509 LttvTrace
*trace_v
= lttv_traceset_get(ts
, iter_trace
);
1511 lttvwindowtraces_unlock(trace_v
);
1515 //set the cursor back to normal
1516 gdk_window_set_cursor(win
, NULL
);
1519 g_assert(g_slist_length(list_in
) == 0);
1521 if( g_slist_length(list_out
) == 0 ) {
1522 /* Put tab's request pending flag back to normal */
1523 tab
->events_request_pending
= FALSE
;
1524 g_debug("remove the idle fct");
1525 return FALSE
; /* Remove the idle function */
1527 g_debug("leave the idle fct");
1528 return TRUE
; /* Leave the idle function */
1530 /* We do not use simili-round-robin, it may require to read 1 meg buffers
1531 * again and again if many tracesets use the same tracefiles. */
1532 /* Hack for round-robin idle functions */
1533 /* It will put the idle function at the end of the pool */
1534 /*g_idle_add_full((G_PRIORITY_HIGH_IDLE + 21),
1535 (GSourceFunc)execute_events_requests,
1546 Manage the periodic update of a live trace
1549 live_trace_update_handler(Tab
*tab
)
1551 #ifdef BABEL_CLEANUP
1552 unsigned int updated_count
;
1553 LttvTracesetContext
*tsc
= LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
1554 TimeInterval initial_time_span
= tsc
->time_span
;
1555 TimeInterval updated_time_span
;
1557 updated_count
= lttv_process_traceset_update(tsc
);
1559 /* TODO ybrosseau 2011-01-12: Add trace resynchronization */
1561 /* Get the changed period bounds */
1562 updated_time_span
= tsc
->time_span
;
1564 if(ltt_time_compare(updated_time_span
.start_time
,
1565 initial_time_span
.start_time
) != 0) {
1566 /* The initial time should not change on a live update */
1570 /* Notify viewers (only on updates) */
1571 if(ltt_time_compare(updated_time_span
.end_time
,
1572 initial_time_span
.end_time
) != 0) {
1574 notify_time_span_changed(tab
);
1575 /* TODO ybrosseau 2011-01-12: Change the timebar to register
1576 to the time_span hook */
1577 timebar_set_minmax_time(TIMEBAR(tab
->MTimebar
),
1578 &updated_time_span
.start_time
,
1579 &updated_time_span
.end_time
);
1581 /* To update the min max */
1582 time_change_manager(tab
, tab
->time_window
);
1585 /* Timer will be recalled as long as there is files to update */
1586 return (updated_count
> 0);
1587 #endif /* BABEL_CLEANUP */
1590 static void lttvwindow_add_trace(Tab
*tab
, LttvTrace
*trace_v
)
1592 #ifdef BABEL_CLEANUP
1593 LttvTraceset
*traceset
= tab
->traceset_info
->traceset
;
1595 guint num_traces
= lttv_traceset_number(traceset
);
1597 //Verify if trace is already present.
1598 for(i
=0; i
<num_traces
; i
++)
1600 LttvTrace
* trace
= lttv_traceset_get(traceset
, i
);
1601 if(trace
== trace_v
)
1605 //Keep a reference to the traces so they are not freed.
1606 for(i
=0; i
<lttv_traceset_number(traceset
); i
++)
1608 LttvTrace
* trace
= lttv_traceset_get(traceset
, i
);
1609 lttv_trace_ref(trace
);
1612 //remove state update hooks
1613 lttv_state_remove_event_hooks(
1614 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1616 lttv_context_fini(LTTV_TRACESET_CONTEXT(
1617 tab
->traceset_info
->traceset_context
));
1618 g_object_unref(tab
->traceset_info
->traceset_context
);
1620 lttv_traceset_add(traceset
, trace_v
);
1621 lttv_trace_ref(trace_v
); /* local ref */
1623 /* Create new context */
1624 tab
->traceset_info
->traceset_context
=
1625 g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
1627 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->
1632 //add state update hooks
1633 lttv_state_add_event_hooks(
1634 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1635 //Remove local reference to the traces.
1636 for(i
=0; i
<lttv_traceset_number(traceset
); i
++)
1638 LttvTrace
* trace
= lttv_traceset_get(traceset
, i
);
1639 lttv_trace_unref(trace
);
1643 //add_trace_into_traceset_selector(GTK_MULTIVPANED(tab->multivpaned), lttv_trace(trace_v));
1646 if (lttv_trace(trace_v
)->is_live
) {
1647 /* Add timer for live update */
1648 /* TODO ybrosseau 2011-01-12: Parametrize the hardcoded 1 seconds */
1649 g_timeout_add_seconds (1,
1650 (GSourceFunc
) live_trace_update_handler
,
1653 #endif /* BABEL_CLEANUP */
1656 /* add_trace adds a trace into the current traceset. It first displays a
1657 * directory selection dialogue to let user choose a trace, then recreates
1658 * tracset_context, and redraws all the viewer of the current tab
1661 void add_trace(GtkWidget
* widget
, gpointer user_data
)
1664 LttvTraceset
* traceset
= NULL
;
1666 char abs_path
[PATH_MAX
];
1668 MainWindow
* mw_data
= get_window_data_struct(widget
);
1669 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
1671 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
1672 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
1673 LttvPluginTab
*ptab
;
1677 ptab
= create_new_tab(widget
, NULL
);
1680 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
1684 //TODO fdeslauriers 2012-07-06: Remove this popup when we support multiple traces
1685 traceset
= lttvwindow_get_traceset(tab
);
1686 if(traceset
!= NULL
&& lttv_traceset_number(traceset
) > 0){
1687 GtkWidget
*dialogue
=
1688 gtk_message_dialog_new(
1689 GTK_WINDOW(gtk_widget_get_toplevel(widget
)),
1690 GTK_DIALOG_MODAL
|GTK_DIALOG_DESTROY_WITH_PARENT
,
1693 "Loading multiple traces is not supported at the moment.");
1694 gtk_dialog_run(GTK_DIALOG(dialogue
));
1695 gtk_widget_destroy(dialogue
);
1699 /* Create a new traceset*/
1700 traceset
= tab
->traceset_info
->traceset
;
1701 if(traceset
== NULL
) {
1702 traceset
= lttv_traceset_new();
1704 /* File open dialog management */
1705 #ifdef BABEL_CLEANUP
1706 GtkWidget
*extra_live_button
;
1707 #endif //babel_cleanup
1708 GtkFileChooser
* file_chooser
=
1710 gtk_file_chooser_dialog_new ("Select a trace",
1711 GTK_WINDOW(mw_data
->mwindow
),
1712 GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER
,
1713 GTK_STOCK_CANCEL
, GTK_RESPONSE_CANCEL
,
1714 GTK_STOCK_OPEN
, GTK_RESPONSE_ACCEPT
,
1716 #ifdef BABEL_CLEANUP
1717 /* Button to indicate the opening of a live trace */
1718 extra_live_button
= gtk_check_button_new_with_mnemonic ("Trace is live (currently being writen)");
1719 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (extra_live_button
), FALSE
);
1720 gtk_file_chooser_set_extra_widget (GTK_FILE_CHOOSER (file_chooser
), extra_live_button
);
1721 #endif //babel_cleanup
1722 gtk_file_chooser_set_show_hidden (file_chooser
, TRUE
);
1723 if(remember_trace_dir
[0] != '\0')
1724 gtk_file_chooser_set_filename(file_chooser
, remember_trace_dir
);
1726 gboolean closeFileChooserDialog
= TRUE
;
1730 id
= gtk_dialog_run(GTK_DIALOG(file_chooser
));
1732 case GTK_RESPONSE_ACCEPT
:
1733 case GTK_RESPONSE_OK
:
1734 path
= gtk_file_chooser_get_filename (file_chooser
);
1736 strncpy(remember_trace_dir
, path
, PATH_MAX
);
1737 strncat(remember_trace_dir
, "/", PATH_MAX
);
1738 if(!path
|| strlen(path
) == 0){
1741 get_absolute_pathname(path
, abs_path
);
1743 if(lttv_traceset_add_path(traceset
,abs_path
) != 0 ){ /*failure*/
1745 g_warning("cannot open trace %s", abs_path
);
1746 strncpy(remember_trace_dir
, "\0", PATH_MAX
);
1747 GtkWidget
*dialogue
=
1748 gtk_message_dialog_new(
1749 GTK_WINDOW(gtk_widget_get_toplevel(widget
)),
1750 GTK_DIALOG_MODAL
|GTK_DIALOG_DESTROY_WITH_PARENT
,
1753 "Cannot open trace : maybe you should enter in the directory "
1755 gtk_dialog_run(GTK_DIALOG(dialogue
));
1756 gtk_widget_destroy(dialogue
);
1757 closeFileChooserDialog
= FALSE
;
1760 closeFileChooserDialog
= TRUE
;
1761 SetTraceset(tab
, traceset
);
1764 //update current tab
1765 //update_traceset(mw_data);
1767 // in expose now call_pending_read_hooks(mw_data);
1769 //lttvwindow_report_current_time(mw_data,&(tab->current_time));
1771 case GTK_RESPONSE_REJECT
:
1772 case GTK_RESPONSE_CANCEL
:
1774 closeFileChooserDialog
= TRUE
;
1777 }while(!closeFileChooserDialog
);
1779 gtk_widget_destroy((GtkWidget
*)file_chooser
);
1783 /* remove_trace removes a trace from the current traceset if all viewers in
1784 * the current tab are not interested in the trace. It first displays a
1785 * dialogue, which shows all traces in the current traceset, to let user choose
1786 * a trace, then it checks if all viewers unselect the trace, if it is true,
1787 * it will remove the trace, recreate the traceset_contex,
1788 * and redraws all the viewer of the current tab. If there is on trace in the
1789 * current traceset, it will delete all viewers of the current tab
1791 * It destroys the filter tree. FIXME... we should request for an update
1795 void remove_trace(GtkWidget
*widget
, gpointer user_data
)
1797 #ifdef BABEL_CLEANUP
1799 LttvTrace
* trace_v
;
1800 LttvTraceset
* traceset
;
1801 gint i
, j
, nb_trace
, index
=-1;
1802 char ** name
, *remove_trace_name
;
1803 MainWindow
* mw_data
= get_window_data_struct(widget
);
1804 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
1806 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
1807 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
1813 LttvPluginTab
*ptab
;
1814 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
1818 nb_trace
=lttv_traceset_number(tab
->traceset_info
->traceset
);
1819 name
= g_new(char*,nb_trace
);
1820 for(i
= 0; i
< nb_trace
; i
++){
1821 trace_v
= lttv_traceset_get(tab
->traceset_info
->traceset
, i
);
1822 trace
= lttv_trace(trace_v
);
1823 name
[i
] = (char *) g_quark_to_string(ltt_trace_name(trace
));
1826 remove_trace_name
= get_remove_trace(mw_data
, name
, nb_trace
);
1829 if(remove_trace_name
){
1831 /* yuk, cut n paste from old code.. should be better (MD)*/
1832 for(i
= 0; i
<nb_trace
; i
++) {
1833 if(strcmp(remove_trace_name
,name
[i
]) == 0){
1838 traceset
= tab
->traceset_info
->traceset
;
1839 //Keep a reference to the traces so they are not freed.
1840 for(j
=0; j
<lttv_traceset_number(traceset
); j
++)
1842 LttvTrace
* trace
= lttv_traceset_get(traceset
, j
);
1843 lttv_trace_ref(trace
);
1846 //remove state update hooks
1847 lttv_state_remove_event_hooks(
1848 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1849 lttv_context_fini(LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
));
1850 g_object_unref(tab
->traceset_info
->traceset_context
);
1852 trace_v
= lttv_traceset_get(traceset
, index
);
1854 lttv_traceset_remove(traceset
, index
);
1855 lttv_trace_unref(trace_v
); // Remove local reference
1857 if(lttv_trace_get_ref_number(trace_v
) <= 1) {
1858 /* ref 1 : lttvwindowtraces only*/
1859 ltt_trace_close(lttv_trace(trace_v
));
1860 /* lttvwindowtraces_remove_trace takes care of destroying
1861 * the traceset linked with the trace_v and also of destroying
1862 * the trace_v at the same time.
1864 lttvwindowtraces_remove_trace(trace_v
);
1867 tab
->traceset_info
->traceset_context
=
1868 g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
1870 LTTV_TRACESET_CONTEXT(tab
->
1871 traceset_info
->traceset_context
),traceset
);
1872 //add state update hooks
1873 lttv_state_add_event_hooks(
1874 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1876 //Remove local reference to the traces.
1877 for(j
=0; j
<lttv_traceset_number(traceset
); j
++)
1879 LttvTrace
* trace
= lttv_traceset_get(traceset
, j
);
1880 lttv_trace_unref(trace
);
1883 SetTraceset(tab
, (gpointer
)traceset
);
1886 #endif /* BABEL_CLEANUP */
1890 void remove_trace(GtkWidget
* widget
, gpointer user_data
)
1893 LttvTrace
* trace_v
;
1894 LttvTraceset
* traceset
;
1895 gint i
, j
, nb_trace
;
1896 char ** name
, *remove_trace_name
;
1897 MainWindow
* mw_data
= get_window_data_struct(widget
);
1898 LttvTracesetSelector
* s
;
1899 LttvTraceSelector
* t
;
1902 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
1904 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
1905 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
1911 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
1914 nb_trace
=lttv_traceset_number(tab
->traceset_info
->traceset
);
1915 name
= g_new(char*,nb_trace
);
1916 for(i
= 0; i
< nb_trace
; i
++){
1917 trace_v
= lttv_traceset_get(tab
->traceset_info
->traceset
, i
);
1918 trace
= lttv_trace(trace_v
);
1919 name
[i
] = ltt_trace_name(trace
);
1922 remove_trace_name
= get_remove_trace(name
, nb_trace
);
1924 if(remove_trace_name
){
1925 for(i
=0; i
<nb_trace
; i
++){
1926 if(strcmp(remove_trace_name
,name
[i
]) == 0){
1927 //unselect the trace from the current viewer
1929 w
= gtk_multivpaned_get_widget(GTK_MULTIVPANED(tab
->multivpaned
));
1931 s
= g_object_get_data(G_OBJECT(w
), "Traceset_Selector");
1933 t
= lttv_traceset_selector_trace_get(s
,i
);
1934 lttv_trace_selector_set_selected(t
, FALSE
);
1937 //check if other viewers select the trace
1938 w
= gtk_multivpaned_get_first_widget(GTK_MULTIVPANED(tab
->multivpaned
));
1940 s
= g_object_get_data(G_OBJECT(w
), "Traceset_Selector");
1942 t
= lttv_traceset_selector_trace_get(s
,i
);
1943 selected
= lttv_trace_selector_get_selected(t
);
1946 w
= gtk_multivpaned_get_next_widget(GTK_MULTIVPANED(tab
->multivpaned
));
1948 }else selected
= FALSE
;
1950 //if no viewer selects the trace, remove it
1952 remove_trace_from_traceset_selector(GTK_MULTIVPANED(tab
->multivpaned
), i
);
1954 traceset
= tab
->traceset_info
->traceset
;
1955 //Keep a reference to the traces so they are not freed.
1956 for(j
=0; j
<lttv_traceset_number(traceset
); j
++)
1958 LttvTrace
* trace
= lttv_traceset_get(traceset
, j
);
1959 lttv_trace_ref(trace
);
1962 //remove state update hooks
1963 lttv_state_remove_event_hooks(
1964 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1965 lttv_context_fini(LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
));
1966 g_object_unref(tab
->traceset_info
->traceset_context
);
1969 trace_v
= lttv_traceset_get(traceset
, i
);
1971 if(lttv_trace_get_ref_number(trace_v
) <= 2) {
1972 /* ref 2 : traceset, local */
1973 lttvwindowtraces_remove_trace(trace_v
);
1974 ltt_trace_close(lttv_trace(trace_v
));
1977 lttv_traceset_remove(traceset
, i
);
1978 lttv_trace_unref(trace_v
); // Remove local reference
1980 if(!lttv_trace_get_ref_number(trace_v
))
1981 lttv_trace_destroy(trace_v
);
1983 tab
->traceset_info
->traceset_context
=
1984 g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
1986 LTTV_TRACESET_CONTEXT(tab
->
1987 traceset_info
->traceset_context
),traceset
);
1988 //add state update hooks
1989 lttv_state_add_event_hooks(
1990 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1992 //Remove local reference to the traces.
1993 for(j
=0; j
<lttv_traceset_number(traceset
); j
++)
1995 LttvTrace
* trace
= lttv_traceset_get(traceset
, j
);
1996 lttv_trace_unref(trace
);
2000 //update current tab
2001 //update_traceset(mw_data);
2004 SetTraceset(tab
, (gpointer
)traceset
);
2005 // in expose now call_pending_read_hooks(mw_data);
2007 //lttvwindow_report_current_time(mw_data,&(tab->current_time));
2010 // while(tab->multi_vpaned->num_children){
2011 // gtk_multi_vpaned_widget_delete(tab->multi_vpaned);
2025 /* Redraw all the viewers in the current tab */
2026 void redraw(GtkWidget
*widget
, gpointer user_data
)
2028 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
2029 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2030 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2037 LttvPluginTab
*ptab
;
2038 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
2043 LttvAttributeValue value
;
2045 retval
= lttv_iattribute_find_by_path(tab
->attributes
, "hooks/redraw", LTTV_POINTER
, &value
);
2048 tmp
= (LttvHooks
*)*(value
.v_pointer
);
2050 lttv_hooks_call(tmp
,NULL
);
2054 void continue_processing(GtkWidget
*widget
, gpointer user_data
)
2056 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
2057 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2058 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2065 LttvPluginTab
*ptab
;
2066 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
2071 LttvAttributeValue value
;
2073 retval
= lttv_iattribute_find_by_path(tab
->attributes
, "hooks/continue",
2074 LTTV_POINTER
, &value
);
2077 tmp
= (LttvHooks
*)*(value
.v_pointer
);
2079 lttv_hooks_call(tmp
,NULL
);
2082 /* Stop the processing for the calling main window's current tab.
2083 * It removes every processing requests that are in its list. It does not call
2084 * the end request hooks, because the request is not finished.
2087 void stop_processing(GtkWidget
*widget
, gpointer user_data
)
2089 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
2090 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2091 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2096 LttvPluginTab
*ptab
;
2097 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
2100 GSList
*iter
= tab
->events_requests
;
2102 while(iter
!= NULL
) {
2103 GSList
*remove_iter
= iter
;
2104 iter
= g_slist_next(iter
);
2106 g_free(remove_iter
->data
);
2107 tab
->events_requests
=
2108 g_slist_remove_link(tab
->events_requests
, remove_iter
);
2110 tab
->events_request_pending
= FALSE
;
2111 tab
->stop_foreground
= TRUE
;
2112 g_idle_remove_by_data(tab
);
2113 g_assert(g_slist_length(tab
->events_requests
) == 0);
2117 /* save will save the traceset to a file
2118 * Not implemented yet FIXME
2121 void save(GtkWidget
* widget
, gpointer user_data
)
2126 void save_as(GtkWidget
* widget
, gpointer user_data
)
2128 g_info("Save as\n");
2132 /* zoom will change the time_window of all the viewers of the
2133 * current tab, and redisplay them. The main functionality is to
2134 * determine the new time_window of the current tab
2137 void zoom(GtkWidget
* widget
, double size
)
2140 TimeInterval time_span
;
2141 TimeWindow new_time_window
;
2142 LttTime current_time
, time_delta
;
2144 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
2146 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2147 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2153 LttvPluginTab
*ptab
;
2154 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
2158 if(size
== 1) return;
2160 ts
= lttvwindow_get_traceset(tab
);
2161 time_span
= lttv_traceset_get_time_span_real(ts
);
2162 new_time_window
= tab
->time_window
;
2163 current_time
= tab
->current_time
;
2165 time_delta
= ltt_time_sub(time_span
.end_time
,time_span
.start_time
);
2167 new_time_window
.start_time
= time_span
.start_time
;
2168 new_time_window
.time_width
= time_delta
;
2169 new_time_window
.time_width_double
= ltt_time_to_double(time_delta
);
2170 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
2171 new_time_window
.time_width
) ;
2173 new_time_window
.time_width
= ltt_time_div(new_time_window
.time_width
, size
);
2174 new_time_window
.time_width_double
=
2175 ltt_time_to_double(new_time_window
.time_width
);
2176 if(ltt_time_compare(new_time_window
.time_width
,time_delta
) > 0)
2177 { /* Case where zoom out is bigger than trace length */
2178 new_time_window
.start_time
= time_span
.start_time
;
2179 new_time_window
.time_width
= time_delta
;
2180 new_time_window
.time_width_double
= ltt_time_to_double(time_delta
);
2181 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
2182 new_time_window
.time_width
) ;
2186 /* Center the image on the current time */
2187 new_time_window
.start_time
=
2188 ltt_time_sub(current_time
,
2189 ltt_time_from_double(new_time_window
.time_width_double
/2.0));
2190 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
2191 new_time_window
.time_width
) ;
2192 /* If on borders, don't fall off */
2193 if(ltt_time_compare(new_time_window
.start_time
, time_span
.start_time
) <0
2194 || ltt_time_compare(new_time_window
.start_time
, time_span
.end_time
) >0)
2196 new_time_window
.start_time
= time_span
.start_time
;
2197 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
2198 new_time_window
.time_width
) ;
2202 if(ltt_time_compare(new_time_window
.end_time
,
2203 time_span
.end_time
) > 0
2204 || ltt_time_compare(new_time_window
.end_time
,
2205 time_span
.start_time
) < 0)
2207 new_time_window
.start_time
=
2208 ltt_time_sub(time_span
.end_time
, new_time_window
.time_width
);
2210 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
2211 new_time_window
.time_width
) ;
2218 if(ltt_time_compare(new_time_window
.time_width
, ltt_time_zero
) == 0) {
2219 g_warning("Zoom more than 1 ns impossible");
2221 time_change_manager(tab
, new_time_window
);
2225 void zoom_in(GtkWidget
* widget
, gpointer user_data
)
2230 void zoom_out(GtkWidget
* widget
, gpointer user_data
)
2235 void zoom_extended(GtkWidget
* widget
, gpointer user_data
)
2240 void go_to_time(GtkWidget
* widget
, gpointer user_data
)
2242 g_info("Go to time\n");
2245 void show_time_frame(GtkWidget
* widget
, gpointer user_data
)
2247 g_info("Show time frame\n");
2251 /* callback function */
2254 on_empty_traceset_activate (GtkMenuItem
*menuitem
,
2257 create_new_window((GtkWidget
*)menuitem
, user_data
, FALSE
);
2262 on_clone_traceset_activate (GtkMenuItem
*menuitem
,
2265 create_new_window((GtkWidget
*)menuitem
, user_data
, TRUE
);
2269 /* create_new_tab calls create_tab to construct a new tab in the main window
2272 LttvPluginTab
*create_new_tab(GtkWidget
* widget
, gpointer user_data
)
2274 gchar label
[PATH_MAX
];
2275 MainWindow
* mw_data
= get_window_data_struct(widget
);
2277 GtkNotebook
* notebook
= (GtkNotebook
*)lookup_widget(widget
, "MNotebook");
2278 if(notebook
== NULL
){
2279 g_info("Notebook does not exist\n");
2282 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2283 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2289 LttvPluginTab
*ptab
;
2290 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
2291 copy_tab
= ptab
->tab
;
2294 strcpy(label
,"Page");
2295 if(get_label(mw_data
, label
,"Get the name of the tab","Please input tab's name")) {
2296 LttvPluginTab
*ptab
;
2298 ptab
= g_object_new(LTTV_TYPE_PLUGIN_TAB
, NULL
);
2299 init_tab (ptab
->tab
, mw_data
, copy_tab
, notebook
, label
);
2300 ptab
->parent
.top_widget
= ptab
->tab
->top_widget
;
2301 g_object_set_data_full(
2302 G_OBJECT(ptab
->tab
->vbox
),
2305 (GDestroyNotify
)tab_destructor
);
2312 on_tab_activate (GtkMenuItem
*menuitem
,
2315 create_new_tab((GtkWidget
*)menuitem
, user_data
);
2320 on_open_activate (GtkMenuItem
*menuitem
,
2323 #ifdef UNFINISHED_FEATURE
2324 open_traceset((GtkWidget
*)menuitem
, user_data
);
2330 on_close_activate (GtkMenuItem
*menuitem
,
2333 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2334 main_window_destructor(mw_data
);
2338 /* remove the current tab from the main window
2342 on_close_tab_activate (GtkWidget
*widget
,
2346 GtkWidget
* notebook
;
2347 notebook
= lookup_widget(widget
, "MNotebook");
2348 if(notebook
== NULL
){
2349 g_info("Notebook does not exist\n");
2353 page_num
= gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
));
2355 gtk_notebook_remove_page(GTK_NOTEBOOK(notebook
), page_num
);
2360 on_close_tab_X_clicked (GtkWidget
*widget
,
2364 GtkWidget
*notebook
= lookup_widget(widget
, "MNotebook");
2365 if(notebook
== NULL
){
2366 g_info("Notebook does not exist\n");
2370 if((page_num
= gtk_notebook_page_num(GTK_NOTEBOOK(notebook
), widget
)) != -1)
2371 gtk_notebook_remove_page(GTK_NOTEBOOK(notebook
), page_num
);
2377 on_add_trace_activate (GtkMenuItem
*menuitem
,
2380 add_trace((GtkWidget
*)menuitem
, user_data
);
2385 on_remove_trace_activate (GtkMenuItem
*menuitem
,
2388 remove_trace((GtkWidget
*)menuitem
, user_data
);
2393 on_save_activate (GtkMenuItem
*menuitem
,
2396 save((GtkWidget
*)menuitem
, user_data
);
2401 on_save_as_activate (GtkMenuItem
*menuitem
,
2404 save_as((GtkWidget
*)menuitem
, user_data
);
2409 on_quit_activate (GtkMenuItem
*menuitem
,
2412 while (g_slist_length(g_main_window_list
) != 0) {
2413 on_MWindow_destroy(((MainWindow
*)g_main_window_list
->data
)->mwindow
,
2420 on_cut_activate (GtkMenuItem
*menuitem
,
2428 on_copy_activate (GtkMenuItem
*menuitem
,
2436 on_paste_activate (GtkMenuItem
*menuitem
,
2444 on_delete_activate (GtkMenuItem
*menuitem
,
2452 on_zoom_in_activate (GtkMenuItem
*menuitem
,
2455 zoom_in((GtkWidget
*)menuitem
, user_data
);
2460 on_zoom_out_activate (GtkMenuItem
*menuitem
,
2463 zoom_out((GtkWidget
*)menuitem
, user_data
);
2468 on_zoom_extended_activate (GtkMenuItem
*menuitem
,
2471 zoom_extended((GtkWidget
*)menuitem
, user_data
);
2476 on_go_to_time_activate (GtkMenuItem
*menuitem
,
2479 go_to_time((GtkWidget
*)menuitem
, user_data
);
2484 on_show_time_frame_activate (GtkMenuItem
*menuitem
,
2487 show_time_frame((GtkWidget
*)menuitem
, user_data
);
2492 on_move_viewer_up_activate (GtkMenuItem
*menuitem
,
2495 move_up_viewer((GtkWidget
*)menuitem
, user_data
);
2500 on_move_viewer_down_activate (GtkMenuItem
*menuitem
,
2503 move_down_viewer((GtkWidget
*)menuitem
, user_data
);
2508 on_remove_viewer_activate (GtkMenuItem
*menuitem
,
2511 delete_viewer((GtkWidget
*)menuitem
, user_data
);
2515 on_trace_facility_activate (GtkMenuItem
*menuitem
,
2518 g_info("Trace facility selector: %s\n", "");
2522 /* Dispaly a file selection dialogue to let user select a library, then call
2523 * lttv_library_load().
2527 on_load_library_activate (GtkMenuItem
*menuitem
,
2530 GError
*error
= NULL
;
2531 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2533 gchar load_module_path_alter
[PATH_MAX
];
2537 gchar
*load_module_path
;
2538 name
= g_ptr_array_new();
2539 nb
= lttv_library_path_number();
2540 /* ask for the library path */
2544 path
= lttv_library_path_get(i
);
2545 g_ptr_array_add(name
, path
);
2548 load_module_path
= get_selection(mw_data
,
2549 (char **)(name
->pdata
), name
->len
,
2550 "Select a library path", "Library paths");
2551 if(load_module_path
!= NULL
)
2552 strncpy(load_module_path_alter
, load_module_path
, PATH_MAX
-1); // -1 for /
2554 g_ptr_array_free(name
, TRUE
);
2556 if(load_module_path
== NULL
) return;
2560 /* Make sure the module path ends with a / */
2561 gchar
*ptr
= load_module_path_alter
;
2563 ptr
= strchr(ptr
, '\0');
2565 if(*(ptr
-1) != '/') {
2572 /* Ask for the library to load : list files in the previously selected
2574 gchar str
[PATH_MAX
];
2577 GtkFileSelection
* file_selector
=
2578 (GtkFileSelection
*)gtk_file_selection_new("Select a module");
2579 gtk_file_selection_set_filename(file_selector
, load_module_path_alter
);
2580 gtk_file_selection_hide_fileop_buttons(file_selector
);
2582 gtk_window_set_transient_for(GTK_WINDOW(file_selector
),
2583 GTK_WINDOW(mw_data
->mwindow
));
2586 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
2588 case GTK_RESPONSE_ACCEPT
:
2589 case GTK_RESPONSE_OK
:
2590 dir
= gtk_file_selection_get_selections (file_selector
);
2591 strncpy(str
,dir
[0],PATH_MAX
);
2592 strncpy(remember_plugins_dir
,dir
[0],PATH_MAX
);
2593 /* only keep file name */
2595 str1
= strrchr(str
,'/');
2598 str1
= strrchr(str
,'\\');
2603 if(*str1
== 'l' && *(str1
+1)== 'i' && *(str1
+2)=='b')
2605 remove info after
. */
2609 str2
= strrchr(str2
, '.');
2610 if(str2
!= NULL
) *str2
= '\0';
2612 lttv_module_require(str1
, &error
);
2614 lttv_library_load(str1
, &error
);
2615 if(error
!= NULL
) g_warning("%s", error
->message
);
2616 else g_info("Load library: %s\n", str
);
2618 case GTK_RESPONSE_REJECT
:
2619 case GTK_RESPONSE_CANCEL
:
2621 gtk_widget_destroy((GtkWidget
*)file_selector
);
2632 /* Display all loaded modules, let user to select a module to unload
2633 * by calling lttv_module_unload
2637 on_unload_library_activate (GtkMenuItem
*menuitem
,
2640 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2642 LttvLibrary
*library
= NULL
;
2647 name
= g_ptr_array_new();
2648 nb
= lttv_library_number();
2649 LttvLibraryInfo
*lib_info
= g_new(LttvLibraryInfo
,nb
);
2650 /* ask for the library name */
2653 LttvLibrary
*iter_lib
= lttv_library_get(i
);
2654 lttv_library_info(iter_lib
, &lib_info
[i
]);
2656 gchar
*path
= lib_info
[i
].name
;
2657 g_ptr_array_add(name
, path
);
2659 lib_name
= get_selection(mw_data
, (char **)(name
->pdata
), name
->len
,
2660 "Select a library", "Libraries");
2661 if(lib_name
!= NULL
) {
2663 if(strcmp(lib_name
, lib_info
[i
].name
) == 0) {
2664 library
= lttv_library_get(i
);
2669 g_ptr_array_free(name
, TRUE
);
2672 if(lib_name
== NULL
) return;
2674 if(library
!= NULL
) lttv_library_unload(library
);
2678 /* Dispaly a file selection dialogue to let user select a module, then call
2679 * lttv_module_require().
2683 on_load_module_activate (GtkMenuItem
*menuitem
,
2686 GError
*error
= NULL
;
2687 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2689 LttvLibrary
*library
= NULL
;
2694 name
= g_ptr_array_new();
2695 nb
= lttv_library_number();
2696 LttvLibraryInfo
*lib_info
= g_new(LttvLibraryInfo
,nb
);
2697 /* ask for the library name */
2700 LttvLibrary
*iter_lib
= lttv_library_get(i
);
2701 lttv_library_info(iter_lib
, &lib_info
[i
]);
2703 gchar
*path
= lib_info
[i
].name
;
2704 g_ptr_array_add(name
, path
);
2706 lib_name
= get_selection(mw_data
,(char **)(name
->pdata
), name
->len
,
2707 "Select a library", "Libraries");
2708 if(lib_name
!= NULL
) {
2710 if(strcmp(lib_name
, lib_info
[i
].name
) == 0) {
2711 library
= lttv_library_get(i
);
2716 g_ptr_array_free(name
, TRUE
);
2719 if(lib_name
== NULL
) return;
2722 //LttvModule *module;
2723 gchar module_name_out
[PATH_MAX
];
2725 /* Ask for the module to load : list modules in the selected lib */
2729 nb
= lttv_library_module_number(library
);
2730 LttvModuleInfo
*module_info
= g_new(LttvModuleInfo
,nb
);
2731 name
= g_ptr_array_new();
2732 /* ask for the module name */
2735 LttvModule
*iter_module
= lttv_library_module_get(library
, i
);
2736 lttv_module_info(iter_module
, &module_info
[i
]);
2738 gchar
*path
= module_info
[i
].name
;
2739 g_ptr_array_add(name
, path
);
2741 module_name
= get_selection(mw_data
, (char **)(name
->pdata
), name
->len
,
2742 "Select a module", "Modules");
2743 if(module_name
!= NULL
) {
2745 if(strcmp(module_name
, module_info
[i
].name
) == 0) {
2746 strncpy(module_name_out
, module_name
, PATH_MAX
);
2747 //module = lttv_library_module_get(i);
2753 g_ptr_array_free(name
, TRUE
);
2754 g_free(module_info
);
2756 if(module_name
== NULL
) return;
2759 lttv_module_require(module_name_out
, &error
);
2760 if(error
!= NULL
) g_warning("%s", error
->message
);
2761 else g_info("Load module: %s", module_name_out
);
2768 gchar str
[PATH_MAX
];
2771 GtkFileSelection
* file_selector
=
2772 (GtkFileSelection
*)gtk_file_selection_new("Select a module");
2773 gtk_file_selection_set_filename(file_selector
, load_module_path_alter
);
2774 gtk_file_selection_hide_fileop_buttons(file_selector
);
2777 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
2779 case GTK_RESPONSE_ACCEPT
:
2780 case GTK_RESPONSE_OK
:
2781 dir
= gtk_file_selection_get_selections (file_selector
);
2782 strncpy(str
,dir
[0],PATH_MAX
);
2783 strncpy(remember_plugins_dir
,dir
[0],PATH_MAX
);
2785 /* only keep file name */
2787 str1
= strrchr(str
,'/');
2790 str1
= strrchr(str
,'\\');
2795 if(*str1
== 'l' && *(str1
+1)== 'i' && *(str1
+2)=='b')
2797 remove info after
. */
2801 str2
= strrchr(str2
, '.');
2802 if(str2
!= NULL
) *str2
= '\0';
2804 lttv_module_require(str1
, &error
);
2806 lttv_library_load(str1
, &error
);
2807 if(error
!= NULL
) g_warning(error
->message
);
2808 else g_info("Load library: %s\n", str
);
2810 case GTK_RESPONSE_REJECT
:
2811 case GTK_RESPONSE_CANCEL
:
2813 gtk_widget_destroy((GtkWidget
*)file_selector
);
2825 /* Display all loaded modules, let user to select a module to unload
2826 * by calling lttv_module_unload
2830 on_unload_module_activate (GtkMenuItem
*menuitem
,
2833 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2835 LttvLibrary
*library
= NULL
;
2840 name
= g_ptr_array_new();
2841 nb
= lttv_library_number();
2842 LttvLibraryInfo
*lib_info
= g_new(LttvLibraryInfo
,nb
);
2843 /* ask for the library name */
2846 LttvLibrary
*iter_lib
= lttv_library_get(i
);
2847 lttv_library_info(iter_lib
, &lib_info
[i
]);
2849 gchar
*path
= lib_info
[i
].name
;
2850 g_ptr_array_add(name
, path
);
2852 lib_name
= get_selection(mw_data
, (char **)(name
->pdata
), name
->len
,
2853 "Select a library", "Libraries");
2854 if(lib_name
!= NULL
) {
2856 if(strcmp(lib_name
, lib_info
[i
].name
) == 0) {
2857 library
= lttv_library_get(i
);
2862 g_ptr_array_free(name
, TRUE
);
2865 if(lib_name
== NULL
) return;
2868 LttvModule
*module
= NULL
;
2870 /* Ask for the module to load : list modules in the selected lib */
2874 nb
= lttv_library_module_number(library
);
2875 LttvModuleInfo
*module_info
= g_new(LttvModuleInfo
,nb
);
2876 name
= g_ptr_array_new();
2877 /* ask for the module name */
2880 LttvModule
*iter_module
= lttv_library_module_get(library
, i
);
2881 lttv_module_info(iter_module
, &module_info
[i
]);
2883 gchar
*path
= module_info
[i
].name
;
2884 if(module_info
[i
].use_count
> 0) g_ptr_array_add(name
, path
);
2886 module_name
= get_selection(mw_data
, (char **)(name
->pdata
), name
->len
,
2887 "Select a module", "Modules");
2888 if(module_name
!= NULL
) {
2890 if(strcmp(module_name
, module_info
[i
].name
) == 0) {
2891 module
= lttv_library_module_get(library
, i
);
2897 g_ptr_array_free(name
, TRUE
);
2898 g_free(module_info
);
2900 if(module_name
== NULL
) return;
2903 LttvModuleInfo module_info
;
2904 lttv_module_info(module
, &module_info
);
2905 g_info("Release module: %s\n", module_info
.name
);
2907 lttv_module_release(module
);
2911 /* Display a directory dialogue to let user select a path for library searching
2915 on_add_library_search_path_activate (GtkMenuItem
*menuitem
,
2918 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2919 //GtkDirSelection * file_selector = (GtkDirSelection *)gtk_dir_selection_new("Select library path");
2920 GtkFileSelection
* file_selector
= (GtkFileSelection
*)gtk_file_selection_new("Select a trace");
2921 gtk_widget_hide( (file_selector
)->file_list
->parent
) ;
2923 gtk_window_set_transient_for(GTK_WINDOW(file_selector
),
2924 GTK_WINDOW(mw_data
->mwindow
));
2929 if(remember_plugins_dir
[0] != '\0')
2930 gtk_file_selection_set_filename(file_selector
, remember_plugins_dir
);
2932 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
2934 case GTK_RESPONSE_ACCEPT
:
2935 case GTK_RESPONSE_OK
:
2936 dir
= gtk_file_selection_get_filename (file_selector
);
2937 strncpy(remember_plugins_dir
,dir
,PATH_MAX
);
2938 strncat(remember_plugins_dir
,"/",PATH_MAX
);
2939 lttv_library_path_add(dir
);
2940 case GTK_RESPONSE_REJECT
:
2941 case GTK_RESPONSE_CANCEL
:
2943 gtk_widget_destroy((GtkWidget
*)file_selector
);
2949 /* Display a directory dialogue to let user select a path for library searching
2953 on_remove_library_search_path_activate (GtkMenuItem
*menuitem
,
2956 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2958 const char *lib_path
;
2962 name
= g_ptr_array_new();
2963 nb
= lttv_library_path_number();
2964 /* ask for the library name */
2967 gchar
*path
= lttv_library_path_get(i
);
2968 g_ptr_array_add(name
, path
);
2970 lib_path
= get_selection(mw_data
, (char **)(name
->pdata
), name
->len
,
2971 "Select a library path", "Library paths");
2973 g_ptr_array_free(name
, TRUE
);
2975 if(lib_path
== NULL
) return;
2978 lttv_library_path_remove(lib_path
);
2982 on_color_activate (GtkMenuItem
*menuitem
,
2990 on_save_configuration_activate (GtkMenuItem
*menuitem
,
2993 g_info("Save configuration\n");
2998 on_content_activate (GtkMenuItem
*menuitem
,
3001 char* filename
= NULL
,
3004 const char* relativePath
= "doc/user/user_guide/html/index.html";
3005 filename
= g_build_filename (g_get_current_dir(), relativePath
, NULL
);
3006 path
= g_strdup_printf ("ghelp://%s", filename
);
3008 screen
= gdk_screen_get_default();
3009 gtk_show_uri (screen
, path
, gtk_get_current_event_time(), NULL
);
3013 g_info("Content\n");
3018 on_about_close_activate (GtkButton
*button
,
3021 GtkWidget
*about_widget
= GTK_WIDGET(user_data
);
3023 gtk_widget_destroy(about_widget
);
3027 on_about_activate (GtkMenuItem
*menuitem
,
3030 MainWindow
*main_window
= get_window_data_struct(GTK_WIDGET(menuitem
));
3031 GtkWidget
*window_widget
= main_window
->mwindow
;
3032 GtkWidget
*about_widget
= gtk_window_new(GTK_WINDOW_TOPLEVEL
);
3033 GtkWindow
*about_window
= GTK_WINDOW(about_widget
);
3035 gtk_window_set_title(about_window
, "About Linux Trace Toolkit");
3037 gtk_window_set_resizable(about_window
, FALSE
);
3038 gtk_window_set_transient_for(about_window
, GTK_WINDOW(window_widget
));
3039 gtk_window_set_destroy_with_parent(about_window
, TRUE
);
3040 gtk_window_set_modal(about_window
, FALSE
);
3042 /* Put the about window at the center of the screen */
3043 gtk_window_set_position(about_window
, GTK_WIN_POS_CENTER_ALWAYS
);
3045 GtkWidget
*vbox
= gtk_vbox_new(FALSE
, 1);
3047 gtk_container_add(GTK_CONTAINER(about_widget
), vbox
);
3050 GtkWidget
*label1
= gtk_label_new("");
3051 gtk_misc_set_padding(GTK_MISC(label1
), 10, 20);
3052 gtk_label_set_markup(GTK_LABEL(label1
), "\
3053 <big>Linux Trace Toolkit " VERSION
"</big>");
3054 gtk_label_set_justify(GTK_LABEL(label1
), GTK_JUSTIFY_CENTER
);
3056 GtkWidget
*label2
= gtk_label_new("");
3057 gtk_misc_set_padding(GTK_MISC(label2
), 10, 20);
3058 gtk_label_set_markup(GTK_LABEL(label2
), "\
3061 Michel Dagenais (New trace format, lttv main)\n\
3062 Mathieu Desnoyers (Kernel Tracer, Directory structure, build with automake/conf,\n\
3063 lttv gui, control flow view, gui cooperative trace reading\n\
3064 scheduler with interruptible foreground and background\n\
3065 computation, detailed event list (rewrite), trace reading\n\
3066 library (rewrite))\n\
3067 Benoit Des Ligneris, Eric Clement (Cluster adaptation, work in progress)\n\
3068 Xang-Xiu Yang (new trace reading library and converter, lttv gui, \n\
3069 detailed event list and statistics view)\n\
3070 Tom Zanussi (RelayFS)\n\
3072 Inspired from the original Linux Trace Toolkit Visualizer made by\n\
3075 GtkWidget
*label3
= gtk_label_new("");
3076 gtk_label_set_markup(GTK_LABEL(label3
), "\
3077 Linux Trace Toolkit Viewer, Copyright (C) 2004, 2005, 2006\n\
3079 Mathieu Desnoyers\n\
3081 Linux Trace Toolkit comes with ABSOLUTELY NO WARRANTY.\n\
3082 This is free software, and you are welcome to redistribute it\n\
3083 under certain conditions. See COPYING for details.");
3084 gtk_misc_set_padding(GTK_MISC(label3
), 10, 20);
3086 gtk_box_pack_start_defaults(GTK_BOX(vbox
), label1
);
3087 gtk_box_pack_start_defaults(GTK_BOX(vbox
), label2
);
3088 gtk_box_pack_start_defaults(GTK_BOX(vbox
), label3
);
3090 GtkWidget
*hbox
= gtk_hbox_new(TRUE
, 0);
3091 gtk_box_pack_end(GTK_BOX(vbox
), hbox
, FALSE
, FALSE
, 0);
3092 GtkWidget
*close_button
= gtk_button_new_with_mnemonic("_Close");
3093 gtk_box_pack_end(GTK_BOX(hbox
), close_button
, FALSE
, FALSE
, 0);
3094 gtk_container_set_border_width(GTK_CONTAINER(close_button
), 20);
3096 g_signal_connect(G_OBJECT(close_button
), "clicked",
3097 G_CALLBACK(on_about_close_activate
),
3098 (gpointer
)about_widget
);
3100 gtk_widget_show_all(about_widget
);
3105 on_button_new_clicked (GtkButton
*button
,
3108 create_new_window((GtkWidget
*)button
, user_data
, TRUE
);
3112 on_button_new_tab_clicked (GtkButton
*button
,
3115 create_new_tab((GtkWidget
*)button
, user_data
);
3119 on_button_open_clicked (GtkButton
*button
,
3122 #ifdef UNFINISHED_FEATURE
3123 open_traceset((GtkWidget
*)button
, user_data
);
3129 on_button_add_trace_clicked (GtkButton
*button
,
3132 add_trace((GtkWidget
*)button
, user_data
);
3137 on_button_remove_trace_clicked (GtkButton
*button
,
3140 remove_trace((GtkWidget
*)button
, user_data
);
3144 on_button_redraw_clicked (GtkButton
*button
,
3147 redraw((GtkWidget
*)button
, user_data
);
3151 on_button_continue_processing_clicked (GtkButton
*button
,
3154 continue_processing((GtkWidget
*)button
, user_data
);
3158 on_button_stop_processing_clicked (GtkButton
*button
,
3161 stop_processing((GtkWidget
*)button
, user_data
);
3167 on_button_save_clicked (GtkButton
*button
,
3170 save((GtkWidget
*)button
, user_data
);
3175 on_button_save_as_clicked (GtkButton
*button
,
3178 save_as((GtkWidget
*)button
, user_data
);
3183 on_button_zoom_in_clicked (GtkButton
*button
,
3186 zoom_in((GtkWidget
*)button
, user_data
);
3191 on_button_zoom_out_clicked (GtkButton
*button
,
3194 zoom_out((GtkWidget
*)button
, user_data
);
3199 on_button_zoom_extended_clicked (GtkButton
*button
,
3202 zoom_extended((GtkWidget
*)button
, user_data
);
3207 on_button_go_to_time_clicked (GtkButton
*button
,
3210 go_to_time((GtkWidget
*)button
, user_data
);
3215 on_button_show_time_frame_clicked (GtkButton
*button
,
3218 show_time_frame((GtkWidget
*)button
, user_data
);
3223 on_button_move_up_clicked (GtkButton
*button
,
3226 move_up_viewer((GtkWidget
*)button
, user_data
);
3231 on_button_move_down_clicked (GtkButton
*button
,
3234 move_down_viewer((GtkWidget
*)button
, user_data
);
3239 on_button_delete_viewer_clicked (GtkButton
*button
,
3242 delete_viewer((GtkWidget
*)button
, user_data
);
3246 on_MWindow_destroy (GtkWidget
*widget
,
3249 MainWindow
*main_window
= get_window_data_struct(widget
);
3250 LttvIAttribute
*attributes
= main_window
->attributes
;
3251 LttvAttributeValue value
;
3254 //This is unnecessary, since widgets will be destroyed
3255 //by the main window widget anyway.
3256 //remove_all_menu_toolbar_constructors(main_window, NULL);
3258 retval
= lttv_iattribute_find_by_path(attributes
, "viewers/menu",
3259 LTTV_POINTER
, &value
);
3261 lttv_menus_destroy((LttvMenus
*)*(value
.v_pointer
));
3263 retval
= lttv_iattribute_find_by_path(attributes
, "viewers/toolbar",
3264 LTTV_POINTER
, &value
);
3266 lttv_toolbars_destroy((LttvToolbars
*)*(value
.v_pointer
));
3268 g_object_unref(main_window
->attributes
);
3269 g_main_window_list
= g_slist_remove(g_main_window_list
, main_window
);
3271 g_info("There are now : %d windows\n",g_slist_length(g_main_window_list
));
3272 if(g_slist_length(g_main_window_list
) == 0)
3277 on_MWindow_configure (GtkWidget
*widget
,
3278 GdkEventConfigure
*event
,
3281 // MD : removed time width modification upon resizing of the main window.
3282 // The viewers will redraw themselves completely, without time interval
3285 if(mw_data->window_width){
3286 time_span = LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context)->Time_Span ;
3287 time_win = tab->time_window;
3288 ratio = width / mw_data->window_width;
3289 tab->time_window.time_width = ltt_time_mul(time_win.time_width,ratio);
3290 time = ltt_time_sub(time_span->endTime, time_win.start_time);
3291 if(ltt_time_compare(time, tab->time_window.time_width) < 0){
3292 tab->time_window.time_width = time;
3298 mw_data->window_width = (int)width;
3307 on_MNotebook_switch_page (GtkNotebook
*notebook
,
3308 GtkNotebookPage
*page
,
3316 void time_change_manager (Tab
*tab
,
3317 TimeWindow new_time_window
)
3320 /* Only one source of time change */
3321 if(tab
->time_manager_lock
== TRUE
) return;
3323 tab
->time_manager_lock
= TRUE
;
3324 TimeInterval time_span
;
3326 LttvTraceset
*ts
= tab
->traceset_info
->traceset
;
3328 time_span
= lttv_traceset_get_time_span_real(ts
);
3330 LttTime start_time
= new_time_window
.start_time
;
3331 LttTime end_time
= new_time_window
.end_time
;
3333 g_assert(ltt_time_compare(start_time
, end_time
) < 0);
3336 GtkAdjustment
*adjustment
= gtk_range_get_adjustment(GTK_RANGE(tab
->scrollbar
));
3337 LttTime upper
= ltt_time_sub(time_span
.end_time
, time_span
.start_time
);
3340 gtk_range_set_increments(GTK_RANGE(tab
->scrollbar
),
3341 ltt_time_to_double(new_time_window
.time_width
)
3342 / SCROLL_STEP_PER_PAGE
3343 * NANOSECONDS_PER_SECOND
, /* step increment */
3344 ltt_time_to_double(new_time_window
.time_width
)
3345 * NANOSECONDS_PER_SECOND
); /* page increment */
3346 gtk_range_set_range(GTK_RANGE(tab
->scrollbar
),
3348 ltt_time_to_double(upper
)
3349 * NANOSECONDS_PER_SECOND
); /* upper */
3351 g_object_set(G_OBJECT(adjustment
),
3355 ltt_time_to_double(upper
), /* upper */
3357 new_time_window
.time_width_double
3358 / SCROLL_STEP_PER_PAGE
, /* step increment */
3360 new_time_window
.time_width_double
,
3361 /* page increment */
3363 new_time_window
.time_width_double
, /* page size */
3365 gtk_adjustment_changed(adjustment
);
3367 // g_object_set(G_OBJECT(adjustment),
3369 // ltt_time_to_double(
3370 // ltt_time_sub(start_time, time_span.start_time))
3373 //gtk_adjustment_value_changed(adjustment);
3374 gtk_range_set_value(GTK_RANGE(tab
->scrollbar
),
3376 ltt_time_sub(start_time
, time_span
.start_time
)) /* value */);
3378 /* set the time bar. */
3381 timebar_set_minmax_time(TIMEBAR(tab
->MTimebar
),
3382 &time_span
.start_time
,
3383 &time_span
.end_time
);
3384 timebar_set_start_time(TIMEBAR(tab
->MTimebar
),&start_time
);
3385 timebar_set_end_time(TIMEBAR(tab
->MTimebar
),&end_time
);
3389 /* call viewer hooks for new time window */
3390 set_time_window(tab
, &new_time_window
);
3392 tab
->time_manager_lock
= FALSE
;
3401 void current_time_change_manager (Tab
*tab
,
3402 LttTime new_current_time
)
3404 /* Only one source of time change */
3405 if(tab
->current_time_manager_lock
== TRUE
) return;
3407 tab
->current_time_manager_lock
= TRUE
;
3409 timebar_set_current_time(TIMEBAR(tab
->MTimebar
), &new_current_time
);
3411 set_current_time(tab
, &new_current_time
);
3413 tab
->current_time_manager_lock
= FALSE
;
3416 void current_position_change_manager(Tab
*tab
, LttvTracesetPosition
*pos
)
3418 lttv_traceset_seek_to_position( pos
);
3420 LttTime new_time
= lttv_traceset_position_get_time(pos
);
3421 /* Put the context in a state coherent position */
3423 lttv_state_traceset_seek_time_closest(tab
->traceset_info
->traceset
, ltt_time_zero
);
3425 current_time_change_manager(tab
, new_time
);
3427 set_current_position(tab
, pos
);
3430 static void on_timebar_starttime_changed(Timebar
*timebar
,
3433 Tab
*tab
= (Tab
*)user_data
;
3434 LttvTraceset
* ts
=tab
->traceset_info
->traceset
;
3435 TimeInterval time_span
= lttv_traceset_get_time_span_real(ts
);
3437 TimeWindow new_time_window
= tab
->time_window
;
3438 new_time_window
.start_time
= timebar_get_start_time(timebar
);
3440 LttTime end_time
= new_time_window
.end_time
;
3442 /* TODO ybrosseau 2010-12-02: This if should have been checked
3443 by the timebar already */
3444 if(ltt_time_compare(new_time_window
.start_time
, end_time
) >= 0) {
3445 /* Then, we must push back end time : keep the same time width
3446 * if possible, else end traceset time */
3447 end_time
= LTT_TIME_MIN(ltt_time_add(new_time_window
.start_time
,
3448 new_time_window
.time_width
),
3449 time_span
.end_time
);
3452 /* Fix the time width to fit start time and end time */
3453 new_time_window
.time_width
= ltt_time_sub(end_time
,
3454 new_time_window
.start_time
);
3456 new_time_window
.time_width_double
=
3457 ltt_time_to_double(new_time_window
.time_width
);
3459 new_time_window
.end_time
= end_time
;
3461 /* Notify the time_manager */
3462 time_change_manager(tab
, new_time_window
);
3466 static void on_timebar_endtime_changed(Timebar
*timebar
,
3469 Tab
*tab
= (Tab
*)user_data
;
3470 LttvTraceset
* ts
=tab
->traceset_info
->traceset
;
3471 TimeInterval time_span
= lttv_traceset_get_time_span_real(ts
);
3473 TimeWindow new_time_window
= tab
->time_window
;
3475 LttTime end_time
= timebar_get_end_time(timebar
);
3477 /* TODO ybrosseau 2010-12-02: This if should have been
3478 checked by the timebar already */
3479 if(ltt_time_compare(new_time_window
.start_time
, end_time
) >= 0) {
3480 /* Then, we must push front start time : keep the same time
3481 width if possible, else end traceset time */
3482 new_time_window
.start_time
= LTT_TIME_MAX(
3483 ltt_time_sub(end_time
,
3484 new_time_window
.time_width
),
3485 time_span
.start_time
);
3488 /* Fix the time width to fit start time and end time */
3489 new_time_window
.time_width
= ltt_time_sub(end_time
,
3490 new_time_window
.start_time
);
3492 new_time_window
.time_width_double
=
3493 ltt_time_to_double(new_time_window
.time_width
);
3495 new_time_window
.end_time
= end_time
;
3497 /* Notify the time_manager */
3498 time_change_manager(tab
, new_time_window
);
3500 static void on_timebar_currenttime_changed(Timebar
*timebar
,
3503 Tab
*tab
= (Tab
*)user_data
;
3505 LttTime new_current_time
= timebar_get_current_time(timebar
);
3507 current_time_change_manager(tab
, new_current_time
);
3510 void scroll_value_changed_cb(GtkWidget
*scrollbar
,
3513 Tab
*tab
= (Tab
*)user_data
;
3514 TimeWindow new_time_window
;
3516 GtkAdjustment
*adjust
= gtk_range_get_adjustment(GTK_RANGE(scrollbar
));
3517 gdouble value
= gtk_adjustment_get_value(adjust
);
3518 // gdouble upper, lower, ratio, page_size;
3521 LttvTraceset
* ts
= tab
->traceset_info
->traceset
;
3522 TimeInterval time_span
= lttv_traceset_get_time_span_real(ts
);
3524 time
= ltt_time_add(ltt_time_from_double(value
),
3525 time_span
.start_time
);
3527 new_time_window
.start_time
= time
;
3529 page_size
= adjust
->page_size
;
3531 new_time_window
.time_width
=
3532 ltt_time_from_double(page_size
);
3534 new_time_window
.time_width_double
=
3537 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
3538 new_time_window
.time_width
);
3541 time_change_manager(tab
, new_time_window
);
3544 //time_window = tab->time_window;
3546 lower
= adjust
->lower
;
3547 upper
= adjust
->upper
;
3548 ratio
= (value
- lower
) / (upper
- lower
);
3549 g_info("lower %lu, upper %lu, value %lu, ratio %lu", lower
, upper
, value
, ratio
);
3551 //time = ltt_time_sub(time_span->end_time, time_span->start_time);
3552 //time = ltt_time_mul(time, (float)ratio);
3553 //time = ltt_time_add(time_span->start_time, time);
3554 time
= ltt_time_add(ltt_time_from_double(value
),
3555 time_span
.start_time
);
3557 time_window
.start_time
= time
;
3559 page_size
= adjust
->page_size
;
3561 time_window
.time_width
=
3562 ltt_time_from_double(page_size
);
3563 //time = ltt_time_sub(time_span.end_time, time);
3564 //if(ltt_time_compare(time,time_window.time_width) < 0){
3565 // time_window.time_width = time;
3568 /* call viewer hooks for new time window */
3569 set_time_window(tab
, &time_window
);
3575 /* Display a dialogue showing all eventtypes and traces, let user to select the interested
3576 * eventtypes, tracefiles and traces (filter)
3579 /* Select a trace which will be removed from traceset
3582 char * get_remove_trace(MainWindow
*mw_data
,
3583 char ** all_trace_name
, int nb_trace
)
3585 return get_selection(mw_data
, all_trace_name
, nb_trace
,
3586 "Select a trace", "Trace pathname");
3590 /* Select a module which will be loaded
3593 char * get_load_module(MainWindow
*mw_data
,
3594 char ** load_module_name
, int nb_module
)
3596 return get_selection(mw_data
, load_module_name
, nb_module
,
3597 "Select a module to load", "Module name");
3603 /* Select a module which will be unloaded
3606 char * get_unload_module(MainWindow
*mw_data
,
3607 char ** loaded_module_name
, int nb_module
)
3609 return get_selection(mw_data
, loaded_module_name
, nb_module
,
3610 "Select a module to unload", "Module name");
3614 /* Display a dialogue which shows all selectable items, let user to
3615 * select one of them
3618 char * get_selection(MainWindow
*mw_data
,
3619 char ** loaded_module_name
, int nb_module
,
3620 char *title
, char * column_title
)
3622 GtkWidget
* dialogue
;
3623 GtkWidget
* scroll_win
;
3625 GtkListStore
* store
;
3626 GtkTreeViewColumn
* column
;
3627 GtkCellRenderer
* renderer
;
3628 GtkTreeSelection
* select
;
3631 char * unload_module_name
= NULL
;
3633 dialogue
= gtk_dialog_new_with_buttons(title
,
3636 GTK_STOCK_OK
,GTK_RESPONSE_ACCEPT
,
3637 GTK_STOCK_CANCEL
,GTK_RESPONSE_REJECT
,
3639 gtk_window_set_default_size((GtkWindow
*)dialogue
, 500, 200);
3640 gtk_window_set_transient_for(GTK_WINDOW(dialogue
),
3641 GTK_WINDOW(mw_data
->mwindow
));
3643 scroll_win
= gtk_scrolled_window_new (NULL
, NULL
);
3644 gtk_widget_show ( scroll_win
);
3645 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll_win
),
3646 GTK_POLICY_AUTOMATIC
, GTK_POLICY_AUTOMATIC
);
3648 store
= gtk_list_store_new (N_COLUMNS
,G_TYPE_STRING
);
3649 tree
= gtk_tree_view_new_with_model(GTK_TREE_MODEL (store
));
3650 gtk_widget_show ( tree
);
3651 g_object_unref (G_OBJECT (store
));
3653 renderer
= gtk_cell_renderer_text_new ();
3654 column
= gtk_tree_view_column_new_with_attributes (column_title
,
3656 "text", MODULE_COLUMN
,
3658 gtk_tree_view_column_set_alignment (column
, 0.5);
3659 gtk_tree_view_column_set_fixed_width (column
, 150);
3660 gtk_tree_view_append_column (GTK_TREE_VIEW (tree
), column
);
3662 select
= gtk_tree_view_get_selection (GTK_TREE_VIEW (tree
));
3663 gtk_tree_selection_set_mode (select
, GTK_SELECTION_SINGLE
);
3665 gtk_container_add (GTK_CONTAINER (scroll_win
), tree
);
3667 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialogue
)->vbox
), scroll_win
,TRUE
, TRUE
,0);
3669 for(i
=0;i
<nb_module
;i
++){
3670 gtk_list_store_append (store
, &iter
);
3671 gtk_list_store_set (store
, &iter
, MODULE_COLUMN
,loaded_module_name
[i
],-1);
3674 id
= gtk_dialog_run(GTK_DIALOG(dialogue
));
3675 GtkTreeModel
**store_model
= (GtkTreeModel
**)&store
;
3677 case GTK_RESPONSE_ACCEPT
:
3678 case GTK_RESPONSE_OK
:
3679 if (gtk_tree_selection_get_selected (select
, store_model
, &iter
)){
3680 gtk_tree_model_get ((GtkTreeModel
*)store
, &iter
, MODULE_COLUMN
, &unload_module_name
, -1);
3682 case GTK_RESPONSE_REJECT
:
3683 case GTK_RESPONSE_CANCEL
:
3685 gtk_widget_destroy(dialogue
);
3689 return unload_module_name
;
3693 /* Insert all menu entry and tool buttons into this main window
3698 void add_all_menu_toolbar_constructors(MainWindow
* mw
, gpointer user_data
)
3702 lttvwindow_viewer_constructor constructor
;
3703 LttvMenus
* global_menu
, * instance_menu
;
3704 LttvToolbars
* global_toolbar
, * instance_toolbar
;
3705 LttvMenuClosure
*menu_item
;
3706 LttvToolbarClosure
*toolbar_item
;
3707 LttvAttributeValue value
;
3708 LttvIAttribute
*global_attributes
= LTTV_IATTRIBUTE(lttv_global_attributes());
3709 LttvIAttribute
*attributes
= mw
->attributes
;
3710 GtkWidget
* tool_menu_title_menu
, *new_widget
, *pixmap
;
3713 retval
= lttv_iattribute_find_by_path(global_attributes
, "viewers/menu",
3714 LTTV_POINTER
, &value
);
3716 if(*(value
.v_pointer
) == NULL
)
3717 *(value
.v_pointer
) = lttv_menus_new();
3718 global_menu
= (LttvMenus
*)*(value
.v_pointer
);
3720 retval
= lttv_iattribute_find_by_path(attributes
, "viewers/menu",
3721 LTTV_POINTER
, &value
);
3723 if(*(value
.v_pointer
) == NULL
)
3724 *(value
.v_pointer
) = lttv_menus_new();
3725 instance_menu
= (LttvMenus
*)*(value
.v_pointer
);
3727 retval
= lttv_iattribute_find_by_path(global_attributes
, "viewers/toolbar",
3728 LTTV_POINTER
, &value
);
3730 if(*(value
.v_pointer
) == NULL
)
3731 *(value
.v_pointer
) = lttv_toolbars_new();
3732 global_toolbar
= (LttvToolbars
*)*(value
.v_pointer
);
3734 retval
= lttv_iattribute_find_by_path(attributes
, "viewers/toolbar",
3735 LTTV_POINTER
, &value
);
3737 if(*(value
.v_pointer
) == NULL
)
3738 *(value
.v_pointer
) = lttv_toolbars_new();
3739 instance_toolbar
= (LttvToolbars
*)*(value
.v_pointer
);
3741 /* Add missing menu entries to window instance */
3742 for(i
=0;i
<global_menu
->len
;i
++) {
3743 menu_item
= &g_array_index(global_menu
, LttvMenuClosure
, i
);
3745 //add menu_item to window instance;
3746 constructor
= menu_item
->con
;
3747 tool_menu_title_menu
= lookup_widget(mw
->mwindow
,"ToolMenuTitle_menu");
3749 gtk_menu_item_new_with_mnemonic (menu_item
->menu_text
);
3750 gtk_container_add (GTK_CONTAINER (tool_menu_title_menu
),
3752 g_signal_connect ((gpointer
) new_widget
, "activate",
3753 G_CALLBACK (insert_viewer_wrap
),
3755 gtk_widget_show (new_widget
);
3756 lttv_menus_add(instance_menu
, menu_item
->con
,
3757 menu_item
->menu_path
,
3758 menu_item
->menu_text
,
3763 /* Add missing toolbar entries to window instance */
3764 for(i
=0;i
<global_toolbar
->len
;i
++) {
3765 toolbar_item
= &g_array_index(global_toolbar
, LttvToolbarClosure
, i
);
3767 //add toolbar_item to window instance;
3768 constructor
= toolbar_item
->con
;
3769 tool_menu_title_menu
= lookup_widget(mw
->mwindow
,"MToolbar1");
3770 pixbuf
= gdk_pixbuf_new_from_xpm_data((const char**)toolbar_item
->pixmap
);
3771 pixmap
= gtk_image_new_from_pixbuf(pixbuf
);
3773 gtk_toolbar_append_element (GTK_TOOLBAR (tool_menu_title_menu
),
3774 GTK_TOOLBAR_CHILD_BUTTON
,
3777 toolbar_item
->tooltip
, NULL
,
3778 pixmap
, NULL
, NULL
);
3779 gtk_label_set_use_underline(
3780 GTK_LABEL (((GtkToolbarChild
*) (
3781 g_list_last (GTK_TOOLBAR
3782 (tool_menu_title_menu
)->children
)->data
))->label
),
3784 gtk_container_set_border_width (GTK_CONTAINER (new_widget
), 1);
3785 g_signal_connect ((gpointer
) new_widget
,
3787 G_CALLBACK (insert_viewer_wrap
),
3789 gtk_widget_show (new_widget
);
3791 lttv_toolbars_add(instance_toolbar
, toolbar_item
->con
,
3792 toolbar_item
->tooltip
,
3793 toolbar_item
->pixmap
,
3801 /* Create a main window
3804 MainWindow
*construct_main_window(MainWindow
* parent
)
3808 g_debug("construct_main_window()");
3809 GtkWidget
* new_window
; /* New generated main window */
3810 MainWindow
* new_m_window
;/* New main window structure */
3811 GtkNotebook
* notebook
;
3812 LttvIAttribute
*attributes
=
3813 LTTV_IATTRIBUTE(g_object_new(LTTV_ATTRIBUTE_TYPE
, NULL
));
3814 LttvAttributeValue value
;
3816 new_m_window
= g_new(MainWindow
, 1);
3818 // Add the object's information to the module's array
3819 g_main_window_list
= g_slist_append(g_main_window_list
, new_m_window
);
3821 new_window
= create_MWindow();
3822 gtk_widget_show (new_window
);
3824 new_m_window
->mwindow
= new_window
;
3825 new_m_window
->attributes
= attributes
;
3827 retval
= lttv_iattribute_find_by_path(attributes
, "viewers/menu",
3828 LTTV_POINTER
, &value
);
3830 *(value
.v_pointer
) = lttv_menus_new();
3832 retval
= lttv_iattribute_find_by_path(attributes
, "viewers/toolbar",
3833 LTTV_POINTER
, &value
);
3835 *(value
.v_pointer
) = lttv_toolbars_new();
3837 add_all_menu_toolbar_constructors(new_m_window
, NULL
);
3839 g_object_set_data_full(G_OBJECT(new_window
),
3841 (gpointer
)new_m_window
,
3842 (GDestroyNotify
)g_free
);
3843 //create a default tab
3844 notebook
= (GtkNotebook
*)lookup_widget(new_m_window
->mwindow
, "MNotebook");
3845 if(notebook
== NULL
){
3846 g_info("Notebook does not exist\n");
3847 /* FIXME : destroy partially created widgets */
3848 g_free(new_m_window
);
3851 //gtk_notebook_popup_enable (GTK_NOTEBOOK(notebook));
3852 //for now there is no name field in LttvTraceset structure
3853 //Use "Traceset" as the label for the default tab
3855 GtkWidget
* parent_notebook
= lookup_widget(parent
->mwindow
, "MNotebook");
3856 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(parent_notebook
),
3857 gtk_notebook_get_current_page(GTK_NOTEBOOK(parent_notebook
)));
3863 LttvPluginTab
*ptab
;
3864 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
3865 parent_tab
= ptab
->tab
;
3867 LttvPluginTab
*ptab
= g_object_new(LTTV_TYPE_PLUGIN_TAB
, NULL
);
3869 new_m_window
, parent_tab
, notebook
, "Traceset");
3870 ptab
->parent
.top_widget
= ptab
->tab
->top_widget
;
3871 g_object_set_data_full(
3872 G_OBJECT(ptab
->tab
->vbox
),
3875 (GDestroyNotify
)tab_destructor
);
3877 LttvPluginTab
*ptab
= g_object_new(LTTV_TYPE_PLUGIN_TAB
, NULL
);
3878 init_tab(ptab
->tab
, new_m_window
, NULL
, notebook
, "Traceset");
3879 ptab
->parent
.top_widget
= ptab
->tab
->top_widget
;
3880 g_object_set_data_full(
3881 G_OBJECT(ptab
->tab
->vbox
),
3884 (GDestroyNotify
)tab_destructor
);
3887 /* Insert default viewers */
3889 LttvAttributeType type
;
3890 LttvAttributeName name
;
3891 LttvAttributeValue value
;
3892 LttvAttribute
*attribute
;
3894 LttvIAttribute
*attributes_global
=
3895 LTTV_IATTRIBUTE(lttv_global_attributes());
3897 attribute
= LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
3898 LTTV_IATTRIBUTE(attributes_global
),
3899 LTTV_VIEWER_CONSTRUCTORS
));
3900 g_assert(attribute
);
3902 name
= g_quark_from_string("guievents");
3903 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
3905 if(type
== LTTV_POINTER
) {
3906 lttvwindow_viewer_constructor viewer_constructor
=
3907 (lttvwindow_viewer_constructor
)*value
.v_pointer
;
3908 insert_viewer(new_window
, viewer_constructor
);
3911 name
= g_quark_from_string("guicontrolflow");
3912 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
3914 if(type
== LTTV_POINTER
) {
3915 lttvwindow_viewer_constructor viewer_constructor
=
3916 (lttvwindow_viewer_constructor
)*value
.v_pointer
;
3917 insert_viewer(new_window
, viewer_constructor
);
3920 name
= g_quark_from_string("guistatistics");
3921 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
3923 if(type
== LTTV_POINTER
) {
3924 lttvwindow_viewer_constructor viewer_constructor
=
3925 (lttvwindow_viewer_constructor
)*value
.v_pointer
;
3926 insert_viewer(new_window
, viewer_constructor
);
3930 g_info("There are now : %d windows\n",g_slist_length(g_main_window_list
));
3932 return new_m_window
;
3936 /* Free the memory occupied by a tab structure
3940 void tab_destructor(LttvPluginTab
* ptab
)
3942 #ifdef BABEL_CLEANUP
3943 int i
, nb
, ref_count
;
3945 Tab
*tab
= ptab
->tab
;
3948 g_object_unref(tab
->attributes
);
3950 if(tab
->interrupted_state
)
3951 g_object_unref(tab
->interrupted_state
);
3954 if(tab
->traceset_info
->traceset_context
!= NULL
){
3955 //remove state update hooks
3956 lttv_state_remove_event_hooks(
3957 (LttvTracesetState
*)tab
->traceset_info
->
3959 lttv_context_fini(LTTV_TRACESET_CONTEXT(tab
->traceset_info
->
3961 g_object_unref(tab
->traceset_info
->traceset_context
);
3963 if(tab
->traceset_info
->traceset
!= NULL
) {
3964 nb
= lttv_traceset_number(tab
->traceset_info
->traceset
);
3965 for(i
= 0 ; i
< nb
; i
++) {
3966 trace
= lttv_traceset_get(tab
->traceset_info
->traceset
, i
);
3967 ref_count
= lttv_trace_get_ref_number(trace
);
3969 ltt_trace_close(lttv_trace(trace
));
3973 lttv_traceset_destroy(tab
->traceset_info
->traceset
);
3974 /* Remove the idle events requests processing function of the tab */
3975 g_idle_remove_by_data(tab
);
3977 g_slist_free(tab
->events_requests
);
3978 g_free(tab
->traceset_info
);
3980 g_object_unref(ptab
);
3981 #endif /* BABEL_CLEANUP */
3985 /* Create a tab and insert it into the current main window
3988 void init_tab(Tab
*tab
, MainWindow
* mw
, Tab
*copy_tab
,
3989 GtkNotebook
* notebook
, char * label
)
3994 //LttvFilter *filter = NULL;
3996 //create a new tab data structure
3997 //tab = g_new(Tab,1);
3999 //construct and initialize the traceset_info
4000 tab
->traceset_info
= g_new(TracesetInfo
,1);
4003 tab
->traceset_info
->traceset
=
4004 lttv_traceset_copy(copy_tab
->traceset_info
->traceset
);
4006 /* Copy the previous tab's filter */
4007 /* We can clone the filter, as we copy the trace set also */
4008 /* The filter must always be in sync with the trace set */
4010 #ifdef BABEL_CLEANUP
4011 tab
->filter
= lttv_filter_clone(copy_tab
->filter
);
4012 #endif /* BABEL_CLEANUP */
4014 tab
->traceset_info
->traceset
= lttv_traceset_new();
4019 lttv_attribute_write_xml(
4020 lttv_traceset_attribute(tab
->traceset_info
->traceset
),
4026 tab
->time_manager_lock
= FALSE
;
4027 tab
->current_time_manager_lock
= FALSE
;
4028 #ifdef BABEL_CLEANUP
4029 //FIXME copy not implemented in lower level
4030 tab
->traceset_info
->traceset_context
=
4031 g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
4032 //add state update hooks
4033 #endif //BABEL_CLEANUP
4034 lttv_state_add_event_hooks(
4035 tab
->traceset_info
->traceset
);
4037 //determine the current_time and time_window of the tab
4039 if(copy_tab
!= NULL
){
4040 tab
->time_window
= copy_tab
->time_window
;
4041 tab
->current_time
= copy_tab
->current_time
;
4043 tab
->time_window
.start_time
=
4044 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
4045 time_span
.start_time
;
4046 if(DEFAULT_TIME_WIDTH_S
<
4047 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
4048 time_span
.end_time
.tv_sec
)
4049 tmp_time
.tv_sec
= DEFAULT_TIME_WIDTH_S
;
4052 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
4053 time_span
.end_time
.tv_sec
;
4054 tmp_time
.tv_nsec
= 0;
4055 tab
->time_window
.time_width
= tmp_time
;
4056 tab
->current_time
.tv_sec
=
4057 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
4058 time_span
.start_time
.tv_sec
;
4059 tab
->current_time
.tv_nsec
=
4060 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
4061 time_span
.start_time
.tv_nsec
;
4064 tab
->attributes
= LTTV_IATTRIBUTE(g_object_new(LTTV_ATTRIBUTE_TYPE
, NULL
));
4065 tab
->interrupted_state
= g_object_new(LTTV_ATTRIBUTE_TYPE
, NULL
);
4067 tab
->vbox
= gtk_vbox_new(FALSE
, 2);
4068 tab
->top_widget
= tab
->vbox
;
4069 //g_object_set_data_full(G_OBJECT(tab->top_widget), "filter",
4070 // filter, (GDestroyNotify)lttv_filter_destroy);
4072 // g_signal_connect (G_OBJECT(tab->top_widget),
4074 // G_CALLBACK (on_top_notify),
4077 tab
->viewer_container
= gtk_vbox_new(TRUE
, 2);
4078 tab
->scrollbar
= gtk_hscrollbar_new(NULL
);
4079 //tab->multivpaned = gtk_multi_vpaned_new();
4081 gtk_box_pack_start(GTK_BOX(tab
->vbox
),
4082 tab
->viewer_container
,
4084 TRUE
, /* Give the extra space to the child */
4085 0); /* No padding */
4088 // tab->time_window = copy_tab->time_window;
4089 // tab->current_time = copy_tab->current_time;
4092 /* Create the timebar */
4094 tab
->MTimebar
= timebar_new();
4096 gtk_box_pack_end(GTK_BOX(tab
->vbox
),
4098 FALSE
, /* Do not expand */
4099 FALSE
, /* Fill has no effect here (expand false) */
4100 0); /* No padding */
4102 gtk_box_pack_end(GTK_BOX(tab
->vbox
),
4104 FALSE
, /* Do not expand */
4105 FALSE
, /* Fill has no effect here (expand false) */
4106 0); /* No padding */
4108 g_object_set_data(G_OBJECT(tab
->viewer_container
), "focused_viewer", NULL
);
4114 // Display a label with a X
4115 GtkWidget *w_hbox = gtk_hbox_new(FALSE, 4);
4116 GtkWidget *w_label = gtk_label_new (label);
4117 GtkWidget *pixmap = create_pixmap(GTK_WIDGET(notebook), "close.png");
4118 GtkWidget *w_button = gtk_button_new ();
4119 gtk_container_add(GTK_CONTAINER(w_button), pixmap);
4120 //GtkWidget *w_button = gtk_button_new_with_label("x");
4122 gtk_button_set_relief(GTK_BUTTON(w_button), GTK_RELIEF_NONE);
4124 gtk_box_pack_start(GTK_BOX(w_hbox), w_label, TRUE, TRUE, 0);
4125 gtk_box_pack_end(GTK_BOX(w_hbox), w_button, FALSE,
4128 g_signal_connect_swapped (w_button, "clicked",
4129 G_CALLBACK (on_close_tab_X_clicked),
4132 gtk_widget_set_state(w_button, GTK_STATE_ACTIVE);
4134 gtk_widget_show (w_label);
4135 gtk_widget_show (pixmap);
4136 gtk_widget_show (w_button);
4137 gtk_widget_show (w_hbox);
4139 tab->label = w_hbox;
4143 tab
->label
= gtk_label_new (label
);
4145 gtk_widget_show(tab
->label
);
4146 gtk_widget_show(tab
->scrollbar
);
4147 gtk_widget_show(tab
->MTimebar
);
4148 gtk_widget_show(tab
->viewer_container
);
4149 gtk_widget_show(tab
->vbox
);
4151 //gtk_widget_show(tab->multivpaned);
4154 /* Start with empty events requests list */
4155 tab
->events_requests
= NULL
;
4156 tab
->events_request_pending
= FALSE
;
4157 tab
->stop_foreground
= FALSE
;
4161 g_signal_connect(G_OBJECT(tab
->scrollbar
), "value-changed",
4162 G_CALLBACK(scroll_value_changed_cb
), tab
);
4165 /* Timebar signal handler */
4166 g_signal_connect(G_OBJECT(tab
->MTimebar
), "start-time-changed",
4167 G_CALLBACK(on_timebar_starttime_changed
), tab
);
4168 g_signal_connect(G_OBJECT(tab
->MTimebar
), "end-time-changed",
4169 G_CALLBACK(on_timebar_endtime_changed
), tab
);
4170 g_signal_connect(G_OBJECT(tab
->MTimebar
), "current-time-changed",
4171 G_CALLBACK(on_timebar_currenttime_changed
), tab
);
4173 //g_signal_connect(G_OBJECT(tab->scrollbar), "changed",
4174 // G_CALLBACK(scroll_value_changed_cb), tab);
4177 //insert tab into notebook
4178 gtk_notebook_append_page(notebook
,
4181 list
= gtk_container_get_children(GTK_CONTAINER(notebook
));
4182 gtk_notebook_set_current_page(notebook
,g_list_length(list
)-1);
4183 // always show : not if(g_list_length(list)>1)
4184 gtk_notebook_set_show_tabs(notebook
, TRUE
);
4187 lttvwindow_report_time_window(tab
, copy_tab
->time_window
);
4188 lttvwindow_report_current_time(tab
, copy_tab
->current_time
);
4190 TimeWindow time_window
;
4192 time_window
.start_time
= ltt_time_zero
;
4193 time_window
.end_time
= ltt_time_add(time_window
.start_time
,
4194 lttvwindow_default_time_width
);
4195 time_window
.time_width
= lttvwindow_default_time_width
;
4196 time_window
.time_width_double
= ltt_time_to_double(time_window
.time_width
);
4198 lttvwindow_report_time_window(tab
, time_window
);
4199 lttvwindow_report_current_time(tab
, ltt_time_zero
);
4202 LttvTraceset
*traceset
= tab
->traceset_info
->traceset
;
4203 SetTraceset(tab
, traceset
);
4207 * execute_events_requests
4209 * Idle function that executes the pending requests for a tab.
4211 * @return return value : TRUE : keep the idle function, FALSE : remove it.
4213 gboolean
execute_events_requests(Tab
*tab
)
4215 return ( lttvwindow_process_pending_requests(tab
) );
4219 __EXPORT
void create_main_window_with_trace_list(GSList
*traces
)
4222 GSList
*iter
= NULL
;
4225 MainWindow
*mw
= construct_main_window(NULL
);
4226 GtkWidget
*widget
= mw
->mwindow
;
4228 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
4229 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
4230 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
4231 LttvPluginTab
*ptab
;
4235 ptab
= create_new_tab(widget
, NULL
);
4238 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
4242 LttvTraceset
* traceset
= lttv_traceset_new();
4243 for(iter
=traces
; iter
!=NULL
; iter
=g_slist_next(iter
)) {
4244 gchar
*path
= (gchar
*)iter
->data
;
4246 gchar abs_path
[PATH_MAX
];
4249 get_absolute_pathname(path
, abs_path
);
4251 if(lttv_traceset_add_path(traceset
,abs_path
) != 0 ){ /*failure*/
4253 g_warning("cannot open trace %s", abs_path
);
4255 GtkWidget
*dialogue
=
4256 gtk_message_dialog_new(
4257 GTK_WINDOW(gtk_widget_get_toplevel(widget
)),
4258 GTK_DIALOG_MODAL
|GTK_DIALOG_DESTROY_WITH_PARENT
,
4261 "Cannot open trace : maybe you should enter in the directory "
4263 gtk_dialog_run(GTK_DIALOG(dialogue
));
4264 gtk_widget_destroy(dialogue
);
4267 SetTraceset(tab
, traceset
);