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");
1683 //TODO fdeslauriers 2012-07-06: Remove this popup when we support multiple traces
1684 traceset
= lttvwindow_get_traceset(tab
);
1685 if(traceset
!= NULL
&& lttv_traceset_number(traceset
) > 0){
1686 GtkWidget
*dialogue
=
1687 gtk_message_dialog_new(
1688 GTK_WINDOW(gtk_widget_get_toplevel(widget
)),
1689 GTK_DIALOG_MODAL
|GTK_DIALOG_DESTROY_WITH_PARENT
,
1692 "Loading multiple traces is not supported at the moment.");
1693 gtk_dialog_run(GTK_DIALOG(dialogue
));
1694 gtk_widget_destroy(dialogue
);
1698 /* Create a new traceset*/
1699 traceset
= lttv_traceset_new();
1700 /* File open dialog management */
1701 #ifdef BABEL_CLEANUP
1702 GtkWidget
*extra_live_button
;
1703 #endif //babel_cleanup
1704 GtkFileChooser
* file_chooser
=
1706 gtk_file_chooser_dialog_new ("Select a trace",
1707 GTK_WINDOW(mw_data
->mwindow
),
1708 GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER
,
1709 GTK_STOCK_CANCEL
, GTK_RESPONSE_CANCEL
,
1710 GTK_STOCK_OPEN
, GTK_RESPONSE_ACCEPT
,
1712 #ifdef BABEL_CLEANUP
1713 /* Button to indicate the opening of a live trace */
1714 extra_live_button
= gtk_check_button_new_with_mnemonic ("Trace is live (currently being writen)");
1715 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (extra_live_button
), FALSE
);
1716 gtk_file_chooser_set_extra_widget (GTK_FILE_CHOOSER (file_chooser
), extra_live_button
);
1717 #endif //babel_cleanup
1718 gtk_file_chooser_set_show_hidden (file_chooser
, TRUE
);
1719 if(remember_trace_dir
[0] != '\0')
1720 gtk_file_chooser_set_filename(file_chooser
, remember_trace_dir
);
1722 gboolean closeFileChooserDialog
= TRUE
;
1726 id
= gtk_dialog_run(GTK_DIALOG(file_chooser
));
1728 case GTK_RESPONSE_ACCEPT
:
1729 case GTK_RESPONSE_OK
:
1730 path
= gtk_file_chooser_get_filename (file_chooser
);
1732 strncpy(remember_trace_dir
, path
, PATH_MAX
);
1733 strncat(remember_trace_dir
, "/", PATH_MAX
);
1734 if(!path
|| strlen(path
) == 0){
1737 get_absolute_pathname(path
, abs_path
);
1739 if(lttv_traceset_add_path(traceset
,abs_path
) != 0 ){ /*failure*/
1741 g_warning("cannot open trace %s", abs_path
);
1742 strncpy(remember_trace_dir
, "\0", PATH_MAX
);
1743 GtkWidget
*dialogue
=
1744 gtk_message_dialog_new(
1745 GTK_WINDOW(gtk_widget_get_toplevel(widget
)),
1746 GTK_DIALOG_MODAL
|GTK_DIALOG_DESTROY_WITH_PARENT
,
1749 "Cannot open trace : maybe you should enter in the directory "
1751 gtk_dialog_run(GTK_DIALOG(dialogue
));
1752 gtk_widget_destroy(dialogue
);
1753 closeFileChooserDialog
= FALSE
;
1756 closeFileChooserDialog
= TRUE
;
1757 SetTraceset(tab
, traceset
);
1760 //update current tab
1761 //update_traceset(mw_data);
1763 // in expose now call_pending_read_hooks(mw_data);
1765 //lttvwindow_report_current_time(mw_data,&(tab->current_time));
1767 case GTK_RESPONSE_REJECT
:
1768 case GTK_RESPONSE_CANCEL
:
1770 closeFileChooserDialog
= TRUE
;
1773 }while(!closeFileChooserDialog
);
1775 gtk_widget_destroy((GtkWidget
*)file_chooser
);
1779 /* remove_trace removes a trace from the current traceset if all viewers in
1780 * the current tab are not interested in the trace. It first displays a
1781 * dialogue, which shows all traces in the current traceset, to let user choose
1782 * a trace, then it checks if all viewers unselect the trace, if it is true,
1783 * it will remove the trace, recreate the traceset_contex,
1784 * and redraws all the viewer of the current tab. If there is on trace in the
1785 * current traceset, it will delete all viewers of the current tab
1787 * It destroys the filter tree. FIXME... we should request for an update
1791 void remove_trace(GtkWidget
*widget
, gpointer user_data
)
1793 #ifdef BABEL_CLEANUP
1795 LttvTrace
* trace_v
;
1796 LttvTraceset
* traceset
;
1797 gint i
, j
, nb_trace
, index
=-1;
1798 char ** name
, *remove_trace_name
;
1799 MainWindow
* mw_data
= get_window_data_struct(widget
);
1800 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
1802 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
1803 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
1809 LttvPluginTab
*ptab
;
1810 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
1814 nb_trace
=lttv_traceset_number(tab
->traceset_info
->traceset
);
1815 name
= g_new(char*,nb_trace
);
1816 for(i
= 0; i
< nb_trace
; i
++){
1817 trace_v
= lttv_traceset_get(tab
->traceset_info
->traceset
, i
);
1818 trace
= lttv_trace(trace_v
);
1819 name
[i
] = (char *) g_quark_to_string(ltt_trace_name(trace
));
1822 remove_trace_name
= get_remove_trace(mw_data
, name
, nb_trace
);
1825 if(remove_trace_name
){
1827 /* yuk, cut n paste from old code.. should be better (MD)*/
1828 for(i
= 0; i
<nb_trace
; i
++) {
1829 if(strcmp(remove_trace_name
,name
[i
]) == 0){
1834 traceset
= tab
->traceset_info
->traceset
;
1835 //Keep a reference to the traces so they are not freed.
1836 for(j
=0; j
<lttv_traceset_number(traceset
); j
++)
1838 LttvTrace
* trace
= lttv_traceset_get(traceset
, j
);
1839 lttv_trace_ref(trace
);
1842 //remove state update hooks
1843 lttv_state_remove_event_hooks(
1844 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1845 lttv_context_fini(LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
));
1846 g_object_unref(tab
->traceset_info
->traceset_context
);
1848 trace_v
= lttv_traceset_get(traceset
, index
);
1850 lttv_traceset_remove(traceset
, index
);
1851 lttv_trace_unref(trace_v
); // Remove local reference
1853 if(lttv_trace_get_ref_number(trace_v
) <= 1) {
1854 /* ref 1 : lttvwindowtraces only*/
1855 ltt_trace_close(lttv_trace(trace_v
));
1856 /* lttvwindowtraces_remove_trace takes care of destroying
1857 * the traceset linked with the trace_v and also of destroying
1858 * the trace_v at the same time.
1860 lttvwindowtraces_remove_trace(trace_v
);
1863 tab
->traceset_info
->traceset_context
=
1864 g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
1866 LTTV_TRACESET_CONTEXT(tab
->
1867 traceset_info
->traceset_context
),traceset
);
1868 //add state update hooks
1869 lttv_state_add_event_hooks(
1870 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1872 //Remove local reference to the traces.
1873 for(j
=0; j
<lttv_traceset_number(traceset
); j
++)
1875 LttvTrace
* trace
= lttv_traceset_get(traceset
, j
);
1876 lttv_trace_unref(trace
);
1879 SetTraceset(tab
, (gpointer
)traceset
);
1882 #endif /* BABEL_CLEANUP */
1886 void remove_trace(GtkWidget
* widget
, gpointer user_data
)
1889 LttvTrace
* trace_v
;
1890 LttvTraceset
* traceset
;
1891 gint i
, j
, nb_trace
;
1892 char ** name
, *remove_trace_name
;
1893 MainWindow
* mw_data
= get_window_data_struct(widget
);
1894 LttvTracesetSelector
* s
;
1895 LttvTraceSelector
* t
;
1898 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
1900 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
1901 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
1907 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
1910 nb_trace
=lttv_traceset_number(tab
->traceset_info
->traceset
);
1911 name
= g_new(char*,nb_trace
);
1912 for(i
= 0; i
< nb_trace
; i
++){
1913 trace_v
= lttv_traceset_get(tab
->traceset_info
->traceset
, i
);
1914 trace
= lttv_trace(trace_v
);
1915 name
[i
] = ltt_trace_name(trace
);
1918 remove_trace_name
= get_remove_trace(name
, nb_trace
);
1920 if(remove_trace_name
){
1921 for(i
=0; i
<nb_trace
; i
++){
1922 if(strcmp(remove_trace_name
,name
[i
]) == 0){
1923 //unselect the trace from the current viewer
1925 w
= gtk_multivpaned_get_widget(GTK_MULTIVPANED(tab
->multivpaned
));
1927 s
= g_object_get_data(G_OBJECT(w
), "Traceset_Selector");
1929 t
= lttv_traceset_selector_trace_get(s
,i
);
1930 lttv_trace_selector_set_selected(t
, FALSE
);
1933 //check if other viewers select the trace
1934 w
= gtk_multivpaned_get_first_widget(GTK_MULTIVPANED(tab
->multivpaned
));
1936 s
= g_object_get_data(G_OBJECT(w
), "Traceset_Selector");
1938 t
= lttv_traceset_selector_trace_get(s
,i
);
1939 selected
= lttv_trace_selector_get_selected(t
);
1942 w
= gtk_multivpaned_get_next_widget(GTK_MULTIVPANED(tab
->multivpaned
));
1944 }else selected
= FALSE
;
1946 //if no viewer selects the trace, remove it
1948 remove_trace_from_traceset_selector(GTK_MULTIVPANED(tab
->multivpaned
), i
);
1950 traceset
= tab
->traceset_info
->traceset
;
1951 //Keep a reference to the traces so they are not freed.
1952 for(j
=0; j
<lttv_traceset_number(traceset
); j
++)
1954 LttvTrace
* trace
= lttv_traceset_get(traceset
, j
);
1955 lttv_trace_ref(trace
);
1958 //remove state update hooks
1959 lttv_state_remove_event_hooks(
1960 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1961 lttv_context_fini(LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
));
1962 g_object_unref(tab
->traceset_info
->traceset_context
);
1965 trace_v
= lttv_traceset_get(traceset
, i
);
1967 if(lttv_trace_get_ref_number(trace_v
) <= 2) {
1968 /* ref 2 : traceset, local */
1969 lttvwindowtraces_remove_trace(trace_v
);
1970 ltt_trace_close(lttv_trace(trace_v
));
1973 lttv_traceset_remove(traceset
, i
);
1974 lttv_trace_unref(trace_v
); // Remove local reference
1976 if(!lttv_trace_get_ref_number(trace_v
))
1977 lttv_trace_destroy(trace_v
);
1979 tab
->traceset_info
->traceset_context
=
1980 g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
1982 LTTV_TRACESET_CONTEXT(tab
->
1983 traceset_info
->traceset_context
),traceset
);
1984 //add state update hooks
1985 lttv_state_add_event_hooks(
1986 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1988 //Remove local reference to the traces.
1989 for(j
=0; j
<lttv_traceset_number(traceset
); j
++)
1991 LttvTrace
* trace
= lttv_traceset_get(traceset
, j
);
1992 lttv_trace_unref(trace
);
1996 //update current tab
1997 //update_traceset(mw_data);
2000 SetTraceset(tab
, (gpointer
)traceset
);
2001 // in expose now call_pending_read_hooks(mw_data);
2003 //lttvwindow_report_current_time(mw_data,&(tab->current_time));
2006 // while(tab->multi_vpaned->num_children){
2007 // gtk_multi_vpaned_widget_delete(tab->multi_vpaned);
2021 /* Redraw all the viewers in the current tab */
2022 void redraw(GtkWidget
*widget
, gpointer user_data
)
2024 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
2025 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2026 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2033 LttvPluginTab
*ptab
;
2034 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
2039 LttvAttributeValue value
;
2041 retval
= lttv_iattribute_find_by_path(tab
->attributes
, "hooks/redraw", LTTV_POINTER
, &value
);
2044 tmp
= (LttvHooks
*)*(value
.v_pointer
);
2046 lttv_hooks_call(tmp
,NULL
);
2050 void continue_processing(GtkWidget
*widget
, gpointer user_data
)
2052 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
2053 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2054 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2061 LttvPluginTab
*ptab
;
2062 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
2067 LttvAttributeValue value
;
2069 retval
= lttv_iattribute_find_by_path(tab
->attributes
, "hooks/continue",
2070 LTTV_POINTER
, &value
);
2073 tmp
= (LttvHooks
*)*(value
.v_pointer
);
2075 lttv_hooks_call(tmp
,NULL
);
2078 /* Stop the processing for the calling main window's current tab.
2079 * It removes every processing requests that are in its list. It does not call
2080 * the end request hooks, because the request is not finished.
2083 void stop_processing(GtkWidget
*widget
, gpointer user_data
)
2085 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
2086 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2087 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2092 LttvPluginTab
*ptab
;
2093 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
2096 GSList
*iter
= tab
->events_requests
;
2098 while(iter
!= NULL
) {
2099 GSList
*remove_iter
= iter
;
2100 iter
= g_slist_next(iter
);
2102 g_free(remove_iter
->data
);
2103 tab
->events_requests
=
2104 g_slist_remove_link(tab
->events_requests
, remove_iter
);
2106 tab
->events_request_pending
= FALSE
;
2107 tab
->stop_foreground
= TRUE
;
2108 g_idle_remove_by_data(tab
);
2109 g_assert(g_slist_length(tab
->events_requests
) == 0);
2113 /* save will save the traceset to a file
2114 * Not implemented yet FIXME
2117 void save(GtkWidget
* widget
, gpointer user_data
)
2122 void save_as(GtkWidget
* widget
, gpointer user_data
)
2124 g_info("Save as\n");
2128 /* zoom will change the time_window of all the viewers of the
2129 * current tab, and redisplay them. The main functionality is to
2130 * determine the new time_window of the current tab
2133 void zoom(GtkWidget
* widget
, double size
)
2136 TimeInterval time_span
;
2137 TimeWindow new_time_window
;
2138 LttTime current_time
, time_delta
;
2140 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
2142 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2143 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2149 LttvPluginTab
*ptab
;
2150 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
2154 if(size
== 1) return;
2156 ts
= lttvwindow_get_traceset(tab
);
2157 time_span
= lttv_traceset_get_time_span_real(ts
);
2158 new_time_window
= tab
->time_window
;
2159 current_time
= tab
->current_time
;
2161 time_delta
= ltt_time_sub(time_span
.end_time
,time_span
.start_time
);
2163 new_time_window
.start_time
= time_span
.start_time
;
2164 new_time_window
.time_width
= time_delta
;
2165 new_time_window
.time_width_double
= ltt_time_to_double(time_delta
);
2166 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
2167 new_time_window
.time_width
) ;
2169 new_time_window
.time_width
= ltt_time_div(new_time_window
.time_width
, size
);
2170 new_time_window
.time_width_double
=
2171 ltt_time_to_double(new_time_window
.time_width
);
2172 if(ltt_time_compare(new_time_window
.time_width
,time_delta
) > 0)
2173 { /* Case where zoom out is bigger than trace length */
2174 new_time_window
.start_time
= time_span
.start_time
;
2175 new_time_window
.time_width
= time_delta
;
2176 new_time_window
.time_width_double
= ltt_time_to_double(time_delta
);
2177 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
2178 new_time_window
.time_width
) ;
2182 /* Center the image on the current time */
2183 new_time_window
.start_time
=
2184 ltt_time_sub(current_time
,
2185 ltt_time_from_double(new_time_window
.time_width_double
/2.0));
2186 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
2187 new_time_window
.time_width
) ;
2188 /* If on borders, don't fall off */
2189 if(ltt_time_compare(new_time_window
.start_time
, time_span
.start_time
) <0
2190 || ltt_time_compare(new_time_window
.start_time
, time_span
.end_time
) >0)
2192 new_time_window
.start_time
= time_span
.start_time
;
2193 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
2194 new_time_window
.time_width
) ;
2198 if(ltt_time_compare(new_time_window
.end_time
,
2199 time_span
.end_time
) > 0
2200 || ltt_time_compare(new_time_window
.end_time
,
2201 time_span
.start_time
) < 0)
2203 new_time_window
.start_time
=
2204 ltt_time_sub(time_span
.end_time
, new_time_window
.time_width
);
2206 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
2207 new_time_window
.time_width
) ;
2214 if(ltt_time_compare(new_time_window
.time_width
, ltt_time_zero
) == 0) {
2215 g_warning("Zoom more than 1 ns impossible");
2217 time_change_manager(tab
, new_time_window
);
2221 void zoom_in(GtkWidget
* widget
, gpointer user_data
)
2226 void zoom_out(GtkWidget
* widget
, gpointer user_data
)
2231 void zoom_extended(GtkWidget
* widget
, gpointer user_data
)
2236 void go_to_time(GtkWidget
* widget
, gpointer user_data
)
2238 g_info("Go to time\n");
2241 void show_time_frame(GtkWidget
* widget
, gpointer user_data
)
2243 g_info("Show time frame\n");
2247 /* callback function */
2250 on_empty_traceset_activate (GtkMenuItem
*menuitem
,
2253 create_new_window((GtkWidget
*)menuitem
, user_data
, FALSE
);
2258 on_clone_traceset_activate (GtkMenuItem
*menuitem
,
2261 create_new_window((GtkWidget
*)menuitem
, user_data
, TRUE
);
2265 /* create_new_tab calls create_tab to construct a new tab in the main window
2268 LttvPluginTab
*create_new_tab(GtkWidget
* widget
, gpointer user_data
)
2270 gchar label
[PATH_MAX
];
2271 MainWindow
* mw_data
= get_window_data_struct(widget
);
2273 GtkNotebook
* notebook
= (GtkNotebook
*)lookup_widget(widget
, "MNotebook");
2274 if(notebook
== NULL
){
2275 g_info("Notebook does not exist\n");
2278 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2279 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2285 LttvPluginTab
*ptab
;
2286 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
2287 copy_tab
= ptab
->tab
;
2290 strcpy(label
,"Page");
2291 if(get_label(mw_data
, label
,"Get the name of the tab","Please input tab's name")) {
2292 LttvPluginTab
*ptab
;
2294 ptab
= g_object_new(LTTV_TYPE_PLUGIN_TAB
, NULL
);
2295 init_tab (ptab
->tab
, mw_data
, copy_tab
, notebook
, label
);
2296 ptab
->parent
.top_widget
= ptab
->tab
->top_widget
;
2297 g_object_set_data_full(
2298 G_OBJECT(ptab
->tab
->vbox
),
2301 (GDestroyNotify
)tab_destructor
);
2308 on_tab_activate (GtkMenuItem
*menuitem
,
2311 create_new_tab((GtkWidget
*)menuitem
, user_data
);
2316 on_open_activate (GtkMenuItem
*menuitem
,
2319 #ifdef UNFINISHED_FEATURE
2320 open_traceset((GtkWidget
*)menuitem
, user_data
);
2326 on_close_activate (GtkMenuItem
*menuitem
,
2329 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2330 main_window_destructor(mw_data
);
2334 /* remove the current tab from the main window
2338 on_close_tab_activate (GtkWidget
*widget
,
2342 GtkWidget
* notebook
;
2343 notebook
= lookup_widget(widget
, "MNotebook");
2344 if(notebook
== NULL
){
2345 g_info("Notebook does not exist\n");
2349 page_num
= gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
));
2351 gtk_notebook_remove_page(GTK_NOTEBOOK(notebook
), page_num
);
2356 on_close_tab_X_clicked (GtkWidget
*widget
,
2360 GtkWidget
*notebook
= lookup_widget(widget
, "MNotebook");
2361 if(notebook
== NULL
){
2362 g_info("Notebook does not exist\n");
2366 if((page_num
= gtk_notebook_page_num(GTK_NOTEBOOK(notebook
), widget
)) != -1)
2367 gtk_notebook_remove_page(GTK_NOTEBOOK(notebook
), page_num
);
2373 on_add_trace_activate (GtkMenuItem
*menuitem
,
2376 add_trace((GtkWidget
*)menuitem
, user_data
);
2381 on_remove_trace_activate (GtkMenuItem
*menuitem
,
2384 remove_trace((GtkWidget
*)menuitem
, user_data
);
2389 on_save_activate (GtkMenuItem
*menuitem
,
2392 save((GtkWidget
*)menuitem
, user_data
);
2397 on_save_as_activate (GtkMenuItem
*menuitem
,
2400 save_as((GtkWidget
*)menuitem
, user_data
);
2405 on_quit_activate (GtkMenuItem
*menuitem
,
2408 while (g_slist_length(g_main_window_list
) != 0) {
2409 on_MWindow_destroy(((MainWindow
*)g_main_window_list
->data
)->mwindow
,
2416 on_cut_activate (GtkMenuItem
*menuitem
,
2424 on_copy_activate (GtkMenuItem
*menuitem
,
2432 on_paste_activate (GtkMenuItem
*menuitem
,
2440 on_delete_activate (GtkMenuItem
*menuitem
,
2448 on_zoom_in_activate (GtkMenuItem
*menuitem
,
2451 zoom_in((GtkWidget
*)menuitem
, user_data
);
2456 on_zoom_out_activate (GtkMenuItem
*menuitem
,
2459 zoom_out((GtkWidget
*)menuitem
, user_data
);
2464 on_zoom_extended_activate (GtkMenuItem
*menuitem
,
2467 zoom_extended((GtkWidget
*)menuitem
, user_data
);
2472 on_go_to_time_activate (GtkMenuItem
*menuitem
,
2475 go_to_time((GtkWidget
*)menuitem
, user_data
);
2480 on_show_time_frame_activate (GtkMenuItem
*menuitem
,
2483 show_time_frame((GtkWidget
*)menuitem
, user_data
);
2488 on_move_viewer_up_activate (GtkMenuItem
*menuitem
,
2491 move_up_viewer((GtkWidget
*)menuitem
, user_data
);
2496 on_move_viewer_down_activate (GtkMenuItem
*menuitem
,
2499 move_down_viewer((GtkWidget
*)menuitem
, user_data
);
2504 on_remove_viewer_activate (GtkMenuItem
*menuitem
,
2507 delete_viewer((GtkWidget
*)menuitem
, user_data
);
2511 on_trace_facility_activate (GtkMenuItem
*menuitem
,
2514 g_info("Trace facility selector: %s\n", "");
2518 /* Dispaly a file selection dialogue to let user select a library, then call
2519 * lttv_library_load().
2523 on_load_library_activate (GtkMenuItem
*menuitem
,
2526 GError
*error
= NULL
;
2527 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2529 gchar load_module_path_alter
[PATH_MAX
];
2533 gchar
*load_module_path
;
2534 name
= g_ptr_array_new();
2535 nb
= lttv_library_path_number();
2536 /* ask for the library path */
2540 path
= lttv_library_path_get(i
);
2541 g_ptr_array_add(name
, path
);
2544 load_module_path
= get_selection(mw_data
,
2545 (char **)(name
->pdata
), name
->len
,
2546 "Select a library path", "Library paths");
2547 if(load_module_path
!= NULL
)
2548 strncpy(load_module_path_alter
, load_module_path
, PATH_MAX
-1); // -1 for /
2550 g_ptr_array_free(name
, TRUE
);
2552 if(load_module_path
== NULL
) return;
2556 /* Make sure the module path ends with a / */
2557 gchar
*ptr
= load_module_path_alter
;
2559 ptr
= strchr(ptr
, '\0');
2561 if(*(ptr
-1) != '/') {
2568 /* Ask for the library to load : list files in the previously selected
2570 gchar str
[PATH_MAX
];
2573 GtkFileSelection
* file_selector
=
2574 (GtkFileSelection
*)gtk_file_selection_new("Select a module");
2575 gtk_file_selection_set_filename(file_selector
, load_module_path_alter
);
2576 gtk_file_selection_hide_fileop_buttons(file_selector
);
2578 gtk_window_set_transient_for(GTK_WINDOW(file_selector
),
2579 GTK_WINDOW(mw_data
->mwindow
));
2582 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
2584 case GTK_RESPONSE_ACCEPT
:
2585 case GTK_RESPONSE_OK
:
2586 dir
= gtk_file_selection_get_selections (file_selector
);
2587 strncpy(str
,dir
[0],PATH_MAX
);
2588 strncpy(remember_plugins_dir
,dir
[0],PATH_MAX
);
2589 /* only keep file name */
2591 str1
= strrchr(str
,'/');
2594 str1
= strrchr(str
,'\\');
2599 if(*str1
== 'l' && *(str1
+1)== 'i' && *(str1
+2)=='b')
2601 remove info after
. */
2605 str2
= strrchr(str2
, '.');
2606 if(str2
!= NULL
) *str2
= '\0';
2608 lttv_module_require(str1
, &error
);
2610 lttv_library_load(str1
, &error
);
2611 if(error
!= NULL
) g_warning("%s", error
->message
);
2612 else g_info("Load library: %s\n", str
);
2614 case GTK_RESPONSE_REJECT
:
2615 case GTK_RESPONSE_CANCEL
:
2617 gtk_widget_destroy((GtkWidget
*)file_selector
);
2628 /* Display all loaded modules, let user to select a module to unload
2629 * by calling lttv_module_unload
2633 on_unload_library_activate (GtkMenuItem
*menuitem
,
2636 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2638 LttvLibrary
*library
= NULL
;
2643 name
= g_ptr_array_new();
2644 nb
= lttv_library_number();
2645 LttvLibraryInfo
*lib_info
= g_new(LttvLibraryInfo
,nb
);
2646 /* ask for the library name */
2649 LttvLibrary
*iter_lib
= lttv_library_get(i
);
2650 lttv_library_info(iter_lib
, &lib_info
[i
]);
2652 gchar
*path
= lib_info
[i
].name
;
2653 g_ptr_array_add(name
, path
);
2655 lib_name
= get_selection(mw_data
, (char **)(name
->pdata
), name
->len
,
2656 "Select a library", "Libraries");
2657 if(lib_name
!= NULL
) {
2659 if(strcmp(lib_name
, lib_info
[i
].name
) == 0) {
2660 library
= lttv_library_get(i
);
2665 g_ptr_array_free(name
, TRUE
);
2668 if(lib_name
== NULL
) return;
2670 if(library
!= NULL
) lttv_library_unload(library
);
2674 /* Dispaly a file selection dialogue to let user select a module, then call
2675 * lttv_module_require().
2679 on_load_module_activate (GtkMenuItem
*menuitem
,
2682 GError
*error
= NULL
;
2683 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2685 LttvLibrary
*library
= NULL
;
2690 name
= g_ptr_array_new();
2691 nb
= lttv_library_number();
2692 LttvLibraryInfo
*lib_info
= g_new(LttvLibraryInfo
,nb
);
2693 /* ask for the library name */
2696 LttvLibrary
*iter_lib
= lttv_library_get(i
);
2697 lttv_library_info(iter_lib
, &lib_info
[i
]);
2699 gchar
*path
= lib_info
[i
].name
;
2700 g_ptr_array_add(name
, path
);
2702 lib_name
= get_selection(mw_data
,(char **)(name
->pdata
), name
->len
,
2703 "Select a library", "Libraries");
2704 if(lib_name
!= NULL
) {
2706 if(strcmp(lib_name
, lib_info
[i
].name
) == 0) {
2707 library
= lttv_library_get(i
);
2712 g_ptr_array_free(name
, TRUE
);
2715 if(lib_name
== NULL
) return;
2718 //LttvModule *module;
2719 gchar module_name_out
[PATH_MAX
];
2721 /* Ask for the module to load : list modules in the selected lib */
2725 nb
= lttv_library_module_number(library
);
2726 LttvModuleInfo
*module_info
= g_new(LttvModuleInfo
,nb
);
2727 name
= g_ptr_array_new();
2728 /* ask for the module name */
2731 LttvModule
*iter_module
= lttv_library_module_get(library
, i
);
2732 lttv_module_info(iter_module
, &module_info
[i
]);
2734 gchar
*path
= module_info
[i
].name
;
2735 g_ptr_array_add(name
, path
);
2737 module_name
= get_selection(mw_data
, (char **)(name
->pdata
), name
->len
,
2738 "Select a module", "Modules");
2739 if(module_name
!= NULL
) {
2741 if(strcmp(module_name
, module_info
[i
].name
) == 0) {
2742 strncpy(module_name_out
, module_name
, PATH_MAX
);
2743 //module = lttv_library_module_get(i);
2749 g_ptr_array_free(name
, TRUE
);
2750 g_free(module_info
);
2752 if(module_name
== NULL
) return;
2755 lttv_module_require(module_name_out
, &error
);
2756 if(error
!= NULL
) g_warning("%s", error
->message
);
2757 else g_info("Load module: %s", module_name_out
);
2764 gchar str
[PATH_MAX
];
2767 GtkFileSelection
* file_selector
=
2768 (GtkFileSelection
*)gtk_file_selection_new("Select a module");
2769 gtk_file_selection_set_filename(file_selector
, load_module_path_alter
);
2770 gtk_file_selection_hide_fileop_buttons(file_selector
);
2773 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
2775 case GTK_RESPONSE_ACCEPT
:
2776 case GTK_RESPONSE_OK
:
2777 dir
= gtk_file_selection_get_selections (file_selector
);
2778 strncpy(str
,dir
[0],PATH_MAX
);
2779 strncpy(remember_plugins_dir
,dir
[0],PATH_MAX
);
2781 /* only keep file name */
2783 str1
= strrchr(str
,'/');
2786 str1
= strrchr(str
,'\\');
2791 if(*str1
== 'l' && *(str1
+1)== 'i' && *(str1
+2)=='b')
2793 remove info after
. */
2797 str2
= strrchr(str2
, '.');
2798 if(str2
!= NULL
) *str2
= '\0';
2800 lttv_module_require(str1
, &error
);
2802 lttv_library_load(str1
, &error
);
2803 if(error
!= NULL
) g_warning(error
->message
);
2804 else g_info("Load library: %s\n", str
);
2806 case GTK_RESPONSE_REJECT
:
2807 case GTK_RESPONSE_CANCEL
:
2809 gtk_widget_destroy((GtkWidget
*)file_selector
);
2821 /* Display all loaded modules, let user to select a module to unload
2822 * by calling lttv_module_unload
2826 on_unload_module_activate (GtkMenuItem
*menuitem
,
2829 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2831 LttvLibrary
*library
= NULL
;
2836 name
= g_ptr_array_new();
2837 nb
= lttv_library_number();
2838 LttvLibraryInfo
*lib_info
= g_new(LttvLibraryInfo
,nb
);
2839 /* ask for the library name */
2842 LttvLibrary
*iter_lib
= lttv_library_get(i
);
2843 lttv_library_info(iter_lib
, &lib_info
[i
]);
2845 gchar
*path
= lib_info
[i
].name
;
2846 g_ptr_array_add(name
, path
);
2848 lib_name
= get_selection(mw_data
, (char **)(name
->pdata
), name
->len
,
2849 "Select a library", "Libraries");
2850 if(lib_name
!= NULL
) {
2852 if(strcmp(lib_name
, lib_info
[i
].name
) == 0) {
2853 library
= lttv_library_get(i
);
2858 g_ptr_array_free(name
, TRUE
);
2861 if(lib_name
== NULL
) return;
2864 LttvModule
*module
= NULL
;
2866 /* Ask for the module to load : list modules in the selected lib */
2870 nb
= lttv_library_module_number(library
);
2871 LttvModuleInfo
*module_info
= g_new(LttvModuleInfo
,nb
);
2872 name
= g_ptr_array_new();
2873 /* ask for the module name */
2876 LttvModule
*iter_module
= lttv_library_module_get(library
, i
);
2877 lttv_module_info(iter_module
, &module_info
[i
]);
2879 gchar
*path
= module_info
[i
].name
;
2880 if(module_info
[i
].use_count
> 0) g_ptr_array_add(name
, path
);
2882 module_name
= get_selection(mw_data
, (char **)(name
->pdata
), name
->len
,
2883 "Select a module", "Modules");
2884 if(module_name
!= NULL
) {
2886 if(strcmp(module_name
, module_info
[i
].name
) == 0) {
2887 module
= lttv_library_module_get(library
, i
);
2893 g_ptr_array_free(name
, TRUE
);
2894 g_free(module_info
);
2896 if(module_name
== NULL
) return;
2899 LttvModuleInfo module_info
;
2900 lttv_module_info(module
, &module_info
);
2901 g_info("Release module: %s\n", module_info
.name
);
2903 lttv_module_release(module
);
2907 /* Display a directory dialogue to let user select a path for library searching
2911 on_add_library_search_path_activate (GtkMenuItem
*menuitem
,
2914 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2915 //GtkDirSelection * file_selector = (GtkDirSelection *)gtk_dir_selection_new("Select library path");
2916 GtkFileSelection
* file_selector
= (GtkFileSelection
*)gtk_file_selection_new("Select a trace");
2917 gtk_widget_hide( (file_selector
)->file_list
->parent
) ;
2919 gtk_window_set_transient_for(GTK_WINDOW(file_selector
),
2920 GTK_WINDOW(mw_data
->mwindow
));
2925 if(remember_plugins_dir
[0] != '\0')
2926 gtk_file_selection_set_filename(file_selector
, remember_plugins_dir
);
2928 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
2930 case GTK_RESPONSE_ACCEPT
:
2931 case GTK_RESPONSE_OK
:
2932 dir
= gtk_file_selection_get_filename (file_selector
);
2933 strncpy(remember_plugins_dir
,dir
,PATH_MAX
);
2934 strncat(remember_plugins_dir
,"/",PATH_MAX
);
2935 lttv_library_path_add(dir
);
2936 case GTK_RESPONSE_REJECT
:
2937 case GTK_RESPONSE_CANCEL
:
2939 gtk_widget_destroy((GtkWidget
*)file_selector
);
2945 /* Display a directory dialogue to let user select a path for library searching
2949 on_remove_library_search_path_activate (GtkMenuItem
*menuitem
,
2952 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2954 const char *lib_path
;
2958 name
= g_ptr_array_new();
2959 nb
= lttv_library_path_number();
2960 /* ask for the library name */
2963 gchar
*path
= lttv_library_path_get(i
);
2964 g_ptr_array_add(name
, path
);
2966 lib_path
= get_selection(mw_data
, (char **)(name
->pdata
), name
->len
,
2967 "Select a library path", "Library paths");
2969 g_ptr_array_free(name
, TRUE
);
2971 if(lib_path
== NULL
) return;
2974 lttv_library_path_remove(lib_path
);
2978 on_color_activate (GtkMenuItem
*menuitem
,
2986 on_save_configuration_activate (GtkMenuItem
*menuitem
,
2989 g_info("Save configuration\n");
2994 on_content_activate (GtkMenuItem
*menuitem
,
2997 char* filename
= NULL
,
3000 const char* relativePath
= "doc/user/user_guide/html/index.html";
3001 filename
= g_build_filename (g_get_current_dir(), relativePath
, NULL
);
3002 path
= g_strdup_printf ("ghelp://%s", filename
);
3004 screen
= gdk_screen_get_default();
3005 gtk_show_uri (screen
, path
, gtk_get_current_event_time(), NULL
);
3009 g_info("Content\n");
3014 on_about_close_activate (GtkButton
*button
,
3017 GtkWidget
*about_widget
= GTK_WIDGET(user_data
);
3019 gtk_widget_destroy(about_widget
);
3023 on_about_activate (GtkMenuItem
*menuitem
,
3026 MainWindow
*main_window
= get_window_data_struct(GTK_WIDGET(menuitem
));
3027 GtkWidget
*window_widget
= main_window
->mwindow
;
3028 GtkWidget
*about_widget
= gtk_window_new(GTK_WINDOW_TOPLEVEL
);
3029 GtkWindow
*about_window
= GTK_WINDOW(about_widget
);
3031 gtk_window_set_title(about_window
, "About Linux Trace Toolkit");
3033 gtk_window_set_resizable(about_window
, FALSE
);
3034 gtk_window_set_transient_for(about_window
, GTK_WINDOW(window_widget
));
3035 gtk_window_set_destroy_with_parent(about_window
, TRUE
);
3036 gtk_window_set_modal(about_window
, FALSE
);
3038 /* Put the about window at the center of the screen */
3039 gtk_window_set_position(about_window
, GTK_WIN_POS_CENTER_ALWAYS
);
3041 GtkWidget
*vbox
= gtk_vbox_new(FALSE
, 1);
3043 gtk_container_add(GTK_CONTAINER(about_widget
), vbox
);
3046 GtkWidget
*label1
= gtk_label_new("");
3047 gtk_misc_set_padding(GTK_MISC(label1
), 10, 20);
3048 gtk_label_set_markup(GTK_LABEL(label1
), "\
3049 <big>Linux Trace Toolkit " VERSION
"</big>");
3050 gtk_label_set_justify(GTK_LABEL(label1
), GTK_JUSTIFY_CENTER
);
3052 GtkWidget
*label2
= gtk_label_new("");
3053 gtk_misc_set_padding(GTK_MISC(label2
), 10, 20);
3054 gtk_label_set_markup(GTK_LABEL(label2
), "\
3057 Michel Dagenais (New trace format, lttv main)\n\
3058 Mathieu Desnoyers (Kernel Tracer, Directory structure, build with automake/conf,\n\
3059 lttv gui, control flow view, gui cooperative trace reading\n\
3060 scheduler with interruptible foreground and background\n\
3061 computation, detailed event list (rewrite), trace reading\n\
3062 library (rewrite))\n\
3063 Benoit Des Ligneris, Eric Clement (Cluster adaptation, work in progress)\n\
3064 Xang-Xiu Yang (new trace reading library and converter, lttv gui, \n\
3065 detailed event list and statistics view)\n\
3066 Tom Zanussi (RelayFS)\n\
3068 Inspired from the original Linux Trace Toolkit Visualizer made by\n\
3071 GtkWidget
*label3
= gtk_label_new("");
3072 gtk_label_set_markup(GTK_LABEL(label3
), "\
3073 Linux Trace Toolkit Viewer, Copyright (C) 2004, 2005, 2006\n\
3075 Mathieu Desnoyers\n\
3077 Linux Trace Toolkit comes with ABSOLUTELY NO WARRANTY.\n\
3078 This is free software, and you are welcome to redistribute it\n\
3079 under certain conditions. See COPYING for details.");
3080 gtk_misc_set_padding(GTK_MISC(label3
), 10, 20);
3082 gtk_box_pack_start_defaults(GTK_BOX(vbox
), label1
);
3083 gtk_box_pack_start_defaults(GTK_BOX(vbox
), label2
);
3084 gtk_box_pack_start_defaults(GTK_BOX(vbox
), label3
);
3086 GtkWidget
*hbox
= gtk_hbox_new(TRUE
, 0);
3087 gtk_box_pack_end(GTK_BOX(vbox
), hbox
, FALSE
, FALSE
, 0);
3088 GtkWidget
*close_button
= gtk_button_new_with_mnemonic("_Close");
3089 gtk_box_pack_end(GTK_BOX(hbox
), close_button
, FALSE
, FALSE
, 0);
3090 gtk_container_set_border_width(GTK_CONTAINER(close_button
), 20);
3092 g_signal_connect(G_OBJECT(close_button
), "clicked",
3093 G_CALLBACK(on_about_close_activate
),
3094 (gpointer
)about_widget
);
3096 gtk_widget_show_all(about_widget
);
3101 on_button_new_clicked (GtkButton
*button
,
3104 create_new_window((GtkWidget
*)button
, user_data
, TRUE
);
3108 on_button_new_tab_clicked (GtkButton
*button
,
3111 create_new_tab((GtkWidget
*)button
, user_data
);
3115 on_button_open_clicked (GtkButton
*button
,
3118 #ifdef UNFINISHED_FEATURE
3119 open_traceset((GtkWidget
*)button
, user_data
);
3125 on_button_add_trace_clicked (GtkButton
*button
,
3128 add_trace((GtkWidget
*)button
, user_data
);
3133 on_button_remove_trace_clicked (GtkButton
*button
,
3136 remove_trace((GtkWidget
*)button
, user_data
);
3140 on_button_redraw_clicked (GtkButton
*button
,
3143 redraw((GtkWidget
*)button
, user_data
);
3147 on_button_continue_processing_clicked (GtkButton
*button
,
3150 continue_processing((GtkWidget
*)button
, user_data
);
3154 on_button_stop_processing_clicked (GtkButton
*button
,
3157 stop_processing((GtkWidget
*)button
, user_data
);
3163 on_button_save_clicked (GtkButton
*button
,
3166 save((GtkWidget
*)button
, user_data
);
3171 on_button_save_as_clicked (GtkButton
*button
,
3174 save_as((GtkWidget
*)button
, user_data
);
3179 on_button_zoom_in_clicked (GtkButton
*button
,
3182 zoom_in((GtkWidget
*)button
, user_data
);
3187 on_button_zoom_out_clicked (GtkButton
*button
,
3190 zoom_out((GtkWidget
*)button
, user_data
);
3195 on_button_zoom_extended_clicked (GtkButton
*button
,
3198 zoom_extended((GtkWidget
*)button
, user_data
);
3203 on_button_go_to_time_clicked (GtkButton
*button
,
3206 go_to_time((GtkWidget
*)button
, user_data
);
3211 on_button_show_time_frame_clicked (GtkButton
*button
,
3214 show_time_frame((GtkWidget
*)button
, user_data
);
3219 on_button_move_up_clicked (GtkButton
*button
,
3222 move_up_viewer((GtkWidget
*)button
, user_data
);
3227 on_button_move_down_clicked (GtkButton
*button
,
3230 move_down_viewer((GtkWidget
*)button
, user_data
);
3235 on_button_delete_viewer_clicked (GtkButton
*button
,
3238 delete_viewer((GtkWidget
*)button
, user_data
);
3242 on_MWindow_destroy (GtkWidget
*widget
,
3245 MainWindow
*main_window
= get_window_data_struct(widget
);
3246 LttvIAttribute
*attributes
= main_window
->attributes
;
3247 LttvAttributeValue value
;
3250 //This is unnecessary, since widgets will be destroyed
3251 //by the main window widget anyway.
3252 //remove_all_menu_toolbar_constructors(main_window, NULL);
3254 retval
= lttv_iattribute_find_by_path(attributes
, "viewers/menu",
3255 LTTV_POINTER
, &value
);
3257 lttv_menus_destroy((LttvMenus
*)*(value
.v_pointer
));
3259 retval
= lttv_iattribute_find_by_path(attributes
, "viewers/toolbar",
3260 LTTV_POINTER
, &value
);
3262 lttv_toolbars_destroy((LttvToolbars
*)*(value
.v_pointer
));
3264 g_object_unref(main_window
->attributes
);
3265 g_main_window_list
= g_slist_remove(g_main_window_list
, main_window
);
3267 g_info("There are now : %d windows\n",g_slist_length(g_main_window_list
));
3268 if(g_slist_length(g_main_window_list
) == 0)
3273 on_MWindow_configure (GtkWidget
*widget
,
3274 GdkEventConfigure
*event
,
3277 // MD : removed time width modification upon resizing of the main window.
3278 // The viewers will redraw themselves completely, without time interval
3281 if(mw_data->window_width){
3282 time_span = LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context)->Time_Span ;
3283 time_win = tab->time_window;
3284 ratio = width / mw_data->window_width;
3285 tab->time_window.time_width = ltt_time_mul(time_win.time_width,ratio);
3286 time = ltt_time_sub(time_span->endTime, time_win.start_time);
3287 if(ltt_time_compare(time, tab->time_window.time_width) < 0){
3288 tab->time_window.time_width = time;
3294 mw_data->window_width = (int)width;
3303 on_MNotebook_switch_page (GtkNotebook
*notebook
,
3304 GtkNotebookPage
*page
,
3312 void time_change_manager (Tab
*tab
,
3313 TimeWindow new_time_window
)
3316 /* Only one source of time change */
3317 if(tab
->time_manager_lock
== TRUE
) return;
3319 tab
->time_manager_lock
= TRUE
;
3320 TimeInterval time_span
;
3322 LttvTraceset
*ts
= tab
->traceset_info
->traceset
;
3324 time_span
= lttv_traceset_get_time_span_real(ts
);
3326 LttTime start_time
= new_time_window
.start_time
;
3327 LttTime end_time
= new_time_window
.end_time
;
3329 g_assert(ltt_time_compare(start_time
, end_time
) < 0);
3332 GtkAdjustment
*adjustment
= gtk_range_get_adjustment(GTK_RANGE(tab
->scrollbar
));
3333 LttTime upper
= ltt_time_sub(time_span
.end_time
, time_span
.start_time
);
3336 gtk_range_set_increments(GTK_RANGE(tab
->scrollbar
),
3337 ltt_time_to_double(new_time_window
.time_width
)
3338 / SCROLL_STEP_PER_PAGE
3339 * NANOSECONDS_PER_SECOND
, /* step increment */
3340 ltt_time_to_double(new_time_window
.time_width
)
3341 * NANOSECONDS_PER_SECOND
); /* page increment */
3342 gtk_range_set_range(GTK_RANGE(tab
->scrollbar
),
3344 ltt_time_to_double(upper
)
3345 * NANOSECONDS_PER_SECOND
); /* upper */
3347 g_object_set(G_OBJECT(adjustment
),
3351 ltt_time_to_double(upper
), /* upper */
3353 new_time_window
.time_width_double
3354 / SCROLL_STEP_PER_PAGE
, /* step increment */
3356 new_time_window
.time_width_double
,
3357 /* page increment */
3359 new_time_window
.time_width_double
, /* page size */
3361 gtk_adjustment_changed(adjustment
);
3363 // g_object_set(G_OBJECT(adjustment),
3365 // ltt_time_to_double(
3366 // ltt_time_sub(start_time, time_span.start_time))
3369 //gtk_adjustment_value_changed(adjustment);
3370 gtk_range_set_value(GTK_RANGE(tab
->scrollbar
),
3372 ltt_time_sub(start_time
, time_span
.start_time
)) /* value */);
3374 /* set the time bar. */
3377 timebar_set_minmax_time(TIMEBAR(tab
->MTimebar
),
3378 &time_span
.start_time
,
3379 &time_span
.end_time
);
3380 timebar_set_start_time(TIMEBAR(tab
->MTimebar
),&start_time
);
3381 timebar_set_end_time(TIMEBAR(tab
->MTimebar
),&end_time
);
3385 /* call viewer hooks for new time window */
3386 set_time_window(tab
, &new_time_window
);
3388 tab
->time_manager_lock
= FALSE
;
3397 void current_time_change_manager (Tab
*tab
,
3398 LttTime new_current_time
)
3400 /* Only one source of time change */
3401 if(tab
->current_time_manager_lock
== TRUE
) return;
3403 tab
->current_time_manager_lock
= TRUE
;
3405 timebar_set_current_time(TIMEBAR(tab
->MTimebar
), &new_current_time
);
3407 set_current_time(tab
, &new_current_time
);
3409 tab
->current_time_manager_lock
= FALSE
;
3412 void current_position_change_manager(Tab
*tab
, LttvTracesetPosition
*pos
)
3414 lttv_traceset_seek_to_position( pos
);
3416 LttTime new_time
= lttv_traceset_position_get_time(pos
);
3417 /* Put the context in a state coherent position */
3419 lttv_state_traceset_seek_time_closest(tab
->traceset_info
->traceset
, ltt_time_zero
);
3421 current_time_change_manager(tab
, new_time
);
3423 set_current_position(tab
, pos
);
3426 static void on_timebar_starttime_changed(Timebar
*timebar
,
3429 Tab
*tab
= (Tab
*)user_data
;
3430 LttvTraceset
* ts
=tab
->traceset_info
->traceset
;
3431 TimeInterval time_span
= lttv_traceset_get_time_span_real(ts
);
3433 TimeWindow new_time_window
= tab
->time_window
;
3434 new_time_window
.start_time
= timebar_get_start_time(timebar
);
3436 LttTime end_time
= new_time_window
.end_time
;
3438 /* TODO ybrosseau 2010-12-02: This if should have been checked
3439 by the timebar already */
3440 if(ltt_time_compare(new_time_window
.start_time
, end_time
) >= 0) {
3441 /* Then, we must push back end time : keep the same time width
3442 * if possible, else end traceset time */
3443 end_time
= LTT_TIME_MIN(ltt_time_add(new_time_window
.start_time
,
3444 new_time_window
.time_width
),
3445 time_span
.end_time
);
3448 /* Fix the time width to fit start time and end time */
3449 new_time_window
.time_width
= ltt_time_sub(end_time
,
3450 new_time_window
.start_time
);
3452 new_time_window
.time_width_double
=
3453 ltt_time_to_double(new_time_window
.time_width
);
3455 new_time_window
.end_time
= end_time
;
3457 /* Notify the time_manager */
3458 time_change_manager(tab
, new_time_window
);
3462 static void on_timebar_endtime_changed(Timebar
*timebar
,
3465 Tab
*tab
= (Tab
*)user_data
;
3466 LttvTraceset
* ts
=tab
->traceset_info
->traceset
;
3467 TimeInterval time_span
= lttv_traceset_get_time_span_real(ts
);
3469 TimeWindow new_time_window
= tab
->time_window
;
3471 LttTime end_time
= timebar_get_end_time(timebar
);
3473 /* TODO ybrosseau 2010-12-02: This if should have been
3474 checked by the timebar already */
3475 if(ltt_time_compare(new_time_window
.start_time
, end_time
) >= 0) {
3476 /* Then, we must push front start time : keep the same time
3477 width if possible, else end traceset time */
3478 new_time_window
.start_time
= LTT_TIME_MAX(
3479 ltt_time_sub(end_time
,
3480 new_time_window
.time_width
),
3481 time_span
.start_time
);
3484 /* Fix the time width to fit start time and end time */
3485 new_time_window
.time_width
= ltt_time_sub(end_time
,
3486 new_time_window
.start_time
);
3488 new_time_window
.time_width_double
=
3489 ltt_time_to_double(new_time_window
.time_width
);
3491 new_time_window
.end_time
= end_time
;
3493 /* Notify the time_manager */
3494 time_change_manager(tab
, new_time_window
);
3496 static void on_timebar_currenttime_changed(Timebar
*timebar
,
3499 Tab
*tab
= (Tab
*)user_data
;
3501 LttTime new_current_time
= timebar_get_current_time(timebar
);
3503 current_time_change_manager(tab
, new_current_time
);
3506 void scroll_value_changed_cb(GtkWidget
*scrollbar
,
3509 Tab
*tab
= (Tab
*)user_data
;
3510 TimeWindow new_time_window
;
3512 GtkAdjustment
*adjust
= gtk_range_get_adjustment(GTK_RANGE(scrollbar
));
3513 gdouble value
= gtk_adjustment_get_value(adjust
);
3514 // gdouble upper, lower, ratio, page_size;
3517 LttvTraceset
* ts
= tab
->traceset_info
->traceset
;
3518 TimeInterval time_span
= lttv_traceset_get_time_span_real(ts
);
3520 time
= ltt_time_add(ltt_time_from_double(value
),
3521 time_span
.start_time
);
3523 new_time_window
.start_time
= time
;
3525 page_size
= adjust
->page_size
;
3527 new_time_window
.time_width
=
3528 ltt_time_from_double(page_size
);
3530 new_time_window
.time_width_double
=
3533 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
3534 new_time_window
.time_width
);
3537 time_change_manager(tab
, new_time_window
);
3540 //time_window = tab->time_window;
3542 lower
= adjust
->lower
;
3543 upper
= adjust
->upper
;
3544 ratio
= (value
- lower
) / (upper
- lower
);
3545 g_info("lower %lu, upper %lu, value %lu, ratio %lu", lower
, upper
, value
, ratio
);
3547 //time = ltt_time_sub(time_span->end_time, time_span->start_time);
3548 //time = ltt_time_mul(time, (float)ratio);
3549 //time = ltt_time_add(time_span->start_time, time);
3550 time
= ltt_time_add(ltt_time_from_double(value
),
3551 time_span
.start_time
);
3553 time_window
.start_time
= time
;
3555 page_size
= adjust
->page_size
;
3557 time_window
.time_width
=
3558 ltt_time_from_double(page_size
);
3559 //time = ltt_time_sub(time_span.end_time, time);
3560 //if(ltt_time_compare(time,time_window.time_width) < 0){
3561 // time_window.time_width = time;
3564 /* call viewer hooks for new time window */
3565 set_time_window(tab
, &time_window
);
3571 /* Display a dialogue showing all eventtypes and traces, let user to select the interested
3572 * eventtypes, tracefiles and traces (filter)
3575 /* Select a trace which will be removed from traceset
3578 char * get_remove_trace(MainWindow
*mw_data
,
3579 char ** all_trace_name
, int nb_trace
)
3581 return get_selection(mw_data
, all_trace_name
, nb_trace
,
3582 "Select a trace", "Trace pathname");
3586 /* Select a module which will be loaded
3589 char * get_load_module(MainWindow
*mw_data
,
3590 char ** load_module_name
, int nb_module
)
3592 return get_selection(mw_data
, load_module_name
, nb_module
,
3593 "Select a module to load", "Module name");
3599 /* Select a module which will be unloaded
3602 char * get_unload_module(MainWindow
*mw_data
,
3603 char ** loaded_module_name
, int nb_module
)
3605 return get_selection(mw_data
, loaded_module_name
, nb_module
,
3606 "Select a module to unload", "Module name");
3610 /* Display a dialogue which shows all selectable items, let user to
3611 * select one of them
3614 char * get_selection(MainWindow
*mw_data
,
3615 char ** loaded_module_name
, int nb_module
,
3616 char *title
, char * column_title
)
3618 GtkWidget
* dialogue
;
3619 GtkWidget
* scroll_win
;
3621 GtkListStore
* store
;
3622 GtkTreeViewColumn
* column
;
3623 GtkCellRenderer
* renderer
;
3624 GtkTreeSelection
* select
;
3627 char * unload_module_name
= NULL
;
3629 dialogue
= gtk_dialog_new_with_buttons(title
,
3632 GTK_STOCK_OK
,GTK_RESPONSE_ACCEPT
,
3633 GTK_STOCK_CANCEL
,GTK_RESPONSE_REJECT
,
3635 gtk_window_set_default_size((GtkWindow
*)dialogue
, 500, 200);
3636 gtk_window_set_transient_for(GTK_WINDOW(dialogue
),
3637 GTK_WINDOW(mw_data
->mwindow
));
3639 scroll_win
= gtk_scrolled_window_new (NULL
, NULL
);
3640 gtk_widget_show ( scroll_win
);
3641 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll_win
),
3642 GTK_POLICY_AUTOMATIC
, GTK_POLICY_AUTOMATIC
);
3644 store
= gtk_list_store_new (N_COLUMNS
,G_TYPE_STRING
);
3645 tree
= gtk_tree_view_new_with_model(GTK_TREE_MODEL (store
));
3646 gtk_widget_show ( tree
);
3647 g_object_unref (G_OBJECT (store
));
3649 renderer
= gtk_cell_renderer_text_new ();
3650 column
= gtk_tree_view_column_new_with_attributes (column_title
,
3652 "text", MODULE_COLUMN
,
3654 gtk_tree_view_column_set_alignment (column
, 0.5);
3655 gtk_tree_view_column_set_fixed_width (column
, 150);
3656 gtk_tree_view_append_column (GTK_TREE_VIEW (tree
), column
);
3658 select
= gtk_tree_view_get_selection (GTK_TREE_VIEW (tree
));
3659 gtk_tree_selection_set_mode (select
, GTK_SELECTION_SINGLE
);
3661 gtk_container_add (GTK_CONTAINER (scroll_win
), tree
);
3663 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialogue
)->vbox
), scroll_win
,TRUE
, TRUE
,0);
3665 for(i
=0;i
<nb_module
;i
++){
3666 gtk_list_store_append (store
, &iter
);
3667 gtk_list_store_set (store
, &iter
, MODULE_COLUMN
,loaded_module_name
[i
],-1);
3670 id
= gtk_dialog_run(GTK_DIALOG(dialogue
));
3671 GtkTreeModel
**store_model
= (GtkTreeModel
**)&store
;
3673 case GTK_RESPONSE_ACCEPT
:
3674 case GTK_RESPONSE_OK
:
3675 if (gtk_tree_selection_get_selected (select
, store_model
, &iter
)){
3676 gtk_tree_model_get ((GtkTreeModel
*)store
, &iter
, MODULE_COLUMN
, &unload_module_name
, -1);
3678 case GTK_RESPONSE_REJECT
:
3679 case GTK_RESPONSE_CANCEL
:
3681 gtk_widget_destroy(dialogue
);
3685 return unload_module_name
;
3689 /* Insert all menu entry and tool buttons into this main window
3694 void add_all_menu_toolbar_constructors(MainWindow
* mw
, gpointer user_data
)
3698 lttvwindow_viewer_constructor constructor
;
3699 LttvMenus
* global_menu
, * instance_menu
;
3700 LttvToolbars
* global_toolbar
, * instance_toolbar
;
3701 LttvMenuClosure
*menu_item
;
3702 LttvToolbarClosure
*toolbar_item
;
3703 LttvAttributeValue value
;
3704 LttvIAttribute
*global_attributes
= LTTV_IATTRIBUTE(lttv_global_attributes());
3705 LttvIAttribute
*attributes
= mw
->attributes
;
3706 GtkWidget
* tool_menu_title_menu
, *new_widget
, *pixmap
;
3709 retval
= lttv_iattribute_find_by_path(global_attributes
, "viewers/menu",
3710 LTTV_POINTER
, &value
);
3712 if(*(value
.v_pointer
) == NULL
)
3713 *(value
.v_pointer
) = lttv_menus_new();
3714 global_menu
= (LttvMenus
*)*(value
.v_pointer
);
3716 retval
= lttv_iattribute_find_by_path(attributes
, "viewers/menu",
3717 LTTV_POINTER
, &value
);
3719 if(*(value
.v_pointer
) == NULL
)
3720 *(value
.v_pointer
) = lttv_menus_new();
3721 instance_menu
= (LttvMenus
*)*(value
.v_pointer
);
3723 retval
= lttv_iattribute_find_by_path(global_attributes
, "viewers/toolbar",
3724 LTTV_POINTER
, &value
);
3726 if(*(value
.v_pointer
) == NULL
)
3727 *(value
.v_pointer
) = lttv_toolbars_new();
3728 global_toolbar
= (LttvToolbars
*)*(value
.v_pointer
);
3730 retval
= lttv_iattribute_find_by_path(attributes
, "viewers/toolbar",
3731 LTTV_POINTER
, &value
);
3733 if(*(value
.v_pointer
) == NULL
)
3734 *(value
.v_pointer
) = lttv_toolbars_new();
3735 instance_toolbar
= (LttvToolbars
*)*(value
.v_pointer
);
3737 /* Add missing menu entries to window instance */
3738 for(i
=0;i
<global_menu
->len
;i
++) {
3739 menu_item
= &g_array_index(global_menu
, LttvMenuClosure
, i
);
3741 //add menu_item to window instance;
3742 constructor
= menu_item
->con
;
3743 tool_menu_title_menu
= lookup_widget(mw
->mwindow
,"ToolMenuTitle_menu");
3745 gtk_menu_item_new_with_mnemonic (menu_item
->menu_text
);
3746 gtk_container_add (GTK_CONTAINER (tool_menu_title_menu
),
3748 g_signal_connect ((gpointer
) new_widget
, "activate",
3749 G_CALLBACK (insert_viewer_wrap
),
3751 gtk_widget_show (new_widget
);
3752 lttv_menus_add(instance_menu
, menu_item
->con
,
3753 menu_item
->menu_path
,
3754 menu_item
->menu_text
,
3759 /* Add missing toolbar entries to window instance */
3760 for(i
=0;i
<global_toolbar
->len
;i
++) {
3761 toolbar_item
= &g_array_index(global_toolbar
, LttvToolbarClosure
, i
);
3763 //add toolbar_item to window instance;
3764 constructor
= toolbar_item
->con
;
3765 tool_menu_title_menu
= lookup_widget(mw
->mwindow
,"MToolbar1");
3766 pixbuf
= gdk_pixbuf_new_from_xpm_data((const char**)toolbar_item
->pixmap
);
3767 pixmap
= gtk_image_new_from_pixbuf(pixbuf
);
3769 gtk_toolbar_append_element (GTK_TOOLBAR (tool_menu_title_menu
),
3770 GTK_TOOLBAR_CHILD_BUTTON
,
3773 toolbar_item
->tooltip
, NULL
,
3774 pixmap
, NULL
, NULL
);
3775 gtk_label_set_use_underline(
3776 GTK_LABEL (((GtkToolbarChild
*) (
3777 g_list_last (GTK_TOOLBAR
3778 (tool_menu_title_menu
)->children
)->data
))->label
),
3780 gtk_container_set_border_width (GTK_CONTAINER (new_widget
), 1);
3781 g_signal_connect ((gpointer
) new_widget
,
3783 G_CALLBACK (insert_viewer_wrap
),
3785 gtk_widget_show (new_widget
);
3787 lttv_toolbars_add(instance_toolbar
, toolbar_item
->con
,
3788 toolbar_item
->tooltip
,
3789 toolbar_item
->pixmap
,
3797 /* Create a main window
3800 MainWindow
*construct_main_window(MainWindow
* parent
)
3804 g_debug("construct_main_window()");
3805 GtkWidget
* new_window
; /* New generated main window */
3806 MainWindow
* new_m_window
;/* New main window structure */
3807 GtkNotebook
* notebook
;
3808 LttvIAttribute
*attributes
=
3809 LTTV_IATTRIBUTE(g_object_new(LTTV_ATTRIBUTE_TYPE
, NULL
));
3810 LttvAttributeValue value
;
3812 new_m_window
= g_new(MainWindow
, 1);
3814 // Add the object's information to the module's array
3815 g_main_window_list
= g_slist_append(g_main_window_list
, new_m_window
);
3817 new_window
= create_MWindow();
3818 gtk_widget_show (new_window
);
3820 new_m_window
->mwindow
= new_window
;
3821 new_m_window
->attributes
= attributes
;
3823 retval
= lttv_iattribute_find_by_path(attributes
, "viewers/menu",
3824 LTTV_POINTER
, &value
);
3826 *(value
.v_pointer
) = lttv_menus_new();
3828 retval
= lttv_iattribute_find_by_path(attributes
, "viewers/toolbar",
3829 LTTV_POINTER
, &value
);
3831 *(value
.v_pointer
) = lttv_toolbars_new();
3833 add_all_menu_toolbar_constructors(new_m_window
, NULL
);
3835 g_object_set_data_full(G_OBJECT(new_window
),
3837 (gpointer
)new_m_window
,
3838 (GDestroyNotify
)g_free
);
3839 //create a default tab
3840 notebook
= (GtkNotebook
*)lookup_widget(new_m_window
->mwindow
, "MNotebook");
3841 if(notebook
== NULL
){
3842 g_info("Notebook does not exist\n");
3843 /* FIXME : destroy partially created widgets */
3844 g_free(new_m_window
);
3847 //gtk_notebook_popup_enable (GTK_NOTEBOOK(notebook));
3848 //for now there is no name field in LttvTraceset structure
3849 //Use "Traceset" as the label for the default tab
3851 GtkWidget
* parent_notebook
= lookup_widget(parent
->mwindow
, "MNotebook");
3852 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(parent_notebook
),
3853 gtk_notebook_get_current_page(GTK_NOTEBOOK(parent_notebook
)));
3859 LttvPluginTab
*ptab
;
3860 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
3861 parent_tab
= ptab
->tab
;
3863 LttvPluginTab
*ptab
= g_object_new(LTTV_TYPE_PLUGIN_TAB
, NULL
);
3865 new_m_window
, parent_tab
, notebook
, "Traceset");
3866 ptab
->parent
.top_widget
= ptab
->tab
->top_widget
;
3867 g_object_set_data_full(
3868 G_OBJECT(ptab
->tab
->vbox
),
3871 (GDestroyNotify
)tab_destructor
);
3873 LttvPluginTab
*ptab
= g_object_new(LTTV_TYPE_PLUGIN_TAB
, NULL
);
3874 init_tab(ptab
->tab
, new_m_window
, NULL
, notebook
, "Traceset");
3875 ptab
->parent
.top_widget
= ptab
->tab
->top_widget
;
3876 g_object_set_data_full(
3877 G_OBJECT(ptab
->tab
->vbox
),
3880 (GDestroyNotify
)tab_destructor
);
3883 /* Insert default viewers */
3885 LttvAttributeType type
;
3886 LttvAttributeName name
;
3887 LttvAttributeValue value
;
3888 LttvAttribute
*attribute
;
3890 LttvIAttribute
*attributes_global
=
3891 LTTV_IATTRIBUTE(lttv_global_attributes());
3893 attribute
= LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
3894 LTTV_IATTRIBUTE(attributes_global
),
3895 LTTV_VIEWER_CONSTRUCTORS
));
3896 g_assert(attribute
);
3898 name
= g_quark_from_string("guievents");
3899 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
3901 if(type
== LTTV_POINTER
) {
3902 lttvwindow_viewer_constructor viewer_constructor
=
3903 (lttvwindow_viewer_constructor
)*value
.v_pointer
;
3904 insert_viewer(new_window
, viewer_constructor
);
3907 name
= g_quark_from_string("guicontrolflow");
3908 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
3910 if(type
== LTTV_POINTER
) {
3911 lttvwindow_viewer_constructor viewer_constructor
=
3912 (lttvwindow_viewer_constructor
)*value
.v_pointer
;
3913 insert_viewer(new_window
, viewer_constructor
);
3916 name
= g_quark_from_string("guistatistics");
3917 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
3919 if(type
== LTTV_POINTER
) {
3920 lttvwindow_viewer_constructor viewer_constructor
=
3921 (lttvwindow_viewer_constructor
)*value
.v_pointer
;
3922 insert_viewer(new_window
, viewer_constructor
);
3926 g_info("There are now : %d windows\n",g_slist_length(g_main_window_list
));
3928 return new_m_window
;
3932 /* Free the memory occupied by a tab structure
3936 void tab_destructor(LttvPluginTab
* ptab
)
3938 #ifdef BABEL_CLEANUP
3939 int i
, nb
, ref_count
;
3941 Tab
*tab
= ptab
->tab
;
3944 g_object_unref(tab
->attributes
);
3946 if(tab
->interrupted_state
)
3947 g_object_unref(tab
->interrupted_state
);
3950 if(tab
->traceset_info
->traceset_context
!= NULL
){
3951 //remove state update hooks
3952 lttv_state_remove_event_hooks(
3953 (LttvTracesetState
*)tab
->traceset_info
->
3955 lttv_context_fini(LTTV_TRACESET_CONTEXT(tab
->traceset_info
->
3957 g_object_unref(tab
->traceset_info
->traceset_context
);
3959 if(tab
->traceset_info
->traceset
!= NULL
) {
3960 nb
= lttv_traceset_number(tab
->traceset_info
->traceset
);
3961 for(i
= 0 ; i
< nb
; i
++) {
3962 trace
= lttv_traceset_get(tab
->traceset_info
->traceset
, i
);
3963 ref_count
= lttv_trace_get_ref_number(trace
);
3965 ltt_trace_close(lttv_trace(trace
));
3969 lttv_traceset_destroy(tab
->traceset_info
->traceset
);
3970 /* Remove the idle events requests processing function of the tab */
3971 g_idle_remove_by_data(tab
);
3973 g_slist_free(tab
->events_requests
);
3974 g_free(tab
->traceset_info
);
3976 g_object_unref(ptab
);
3977 #endif /* BABEL_CLEANUP */
3981 /* Create a tab and insert it into the current main window
3984 void init_tab(Tab
*tab
, MainWindow
* mw
, Tab
*copy_tab
,
3985 GtkNotebook
* notebook
, char * label
)
3990 //LttvFilter *filter = NULL;
3992 //create a new tab data structure
3993 //tab = g_new(Tab,1);
3995 //construct and initialize the traceset_info
3996 tab
->traceset_info
= g_new(TracesetInfo
,1);
3999 tab
->traceset_info
->traceset
=
4000 lttv_traceset_copy(copy_tab
->traceset_info
->traceset
);
4002 /* Copy the previous tab's filter */
4003 /* We can clone the filter, as we copy the trace set also */
4004 /* The filter must always be in sync with the trace set */
4006 #ifdef BABEL_CLEANUP
4007 tab
->filter
= lttv_filter_clone(copy_tab
->filter
);
4008 #endif /* BABEL_CLEANUP */
4010 tab
->traceset_info
->traceset
= lttv_traceset_new();
4015 lttv_attribute_write_xml(
4016 lttv_traceset_attribute(tab
->traceset_info
->traceset
),
4022 tab
->time_manager_lock
= FALSE
;
4023 tab
->current_time_manager_lock
= FALSE
;
4024 #ifdef BABEL_CLEANUP
4025 //FIXME copy not implemented in lower level
4026 tab
->traceset_info
->traceset_context
=
4027 g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
4028 //add state update hooks
4029 #endif //BABEL_CLEANUP
4030 lttv_state_add_event_hooks(
4031 tab
->traceset_info
->traceset
);
4033 //determine the current_time and time_window of the tab
4035 if(copy_tab
!= NULL
){
4036 tab
->time_window
= copy_tab
->time_window
;
4037 tab
->current_time
= copy_tab
->current_time
;
4039 tab
->time_window
.start_time
=
4040 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
4041 time_span
.start_time
;
4042 if(DEFAULT_TIME_WIDTH_S
<
4043 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
4044 time_span
.end_time
.tv_sec
)
4045 tmp_time
.tv_sec
= DEFAULT_TIME_WIDTH_S
;
4048 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
4049 time_span
.end_time
.tv_sec
;
4050 tmp_time
.tv_nsec
= 0;
4051 tab
->time_window
.time_width
= tmp_time
;
4052 tab
->current_time
.tv_sec
=
4053 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
4054 time_span
.start_time
.tv_sec
;
4055 tab
->current_time
.tv_nsec
=
4056 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
4057 time_span
.start_time
.tv_nsec
;
4060 tab
->attributes
= LTTV_IATTRIBUTE(g_object_new(LTTV_ATTRIBUTE_TYPE
, NULL
));
4061 tab
->interrupted_state
= g_object_new(LTTV_ATTRIBUTE_TYPE
, NULL
);
4063 tab
->vbox
= gtk_vbox_new(FALSE
, 2);
4064 tab
->top_widget
= tab
->vbox
;
4065 //g_object_set_data_full(G_OBJECT(tab->top_widget), "filter",
4066 // filter, (GDestroyNotify)lttv_filter_destroy);
4068 // g_signal_connect (G_OBJECT(tab->top_widget),
4070 // G_CALLBACK (on_top_notify),
4073 tab
->viewer_container
= gtk_vbox_new(TRUE
, 2);
4074 tab
->scrollbar
= gtk_hscrollbar_new(NULL
);
4075 //tab->multivpaned = gtk_multi_vpaned_new();
4077 gtk_box_pack_start(GTK_BOX(tab
->vbox
),
4078 tab
->viewer_container
,
4080 TRUE
, /* Give the extra space to the child */
4081 0); /* No padding */
4084 // tab->time_window = copy_tab->time_window;
4085 // tab->current_time = copy_tab->current_time;
4088 /* Create the timebar */
4090 tab
->MTimebar
= timebar_new();
4092 gtk_box_pack_end(GTK_BOX(tab
->vbox
),
4094 FALSE
, /* Do not expand */
4095 FALSE
, /* Fill has no effect here (expand false) */
4096 0); /* No padding */
4098 gtk_box_pack_end(GTK_BOX(tab
->vbox
),
4100 FALSE
, /* Do not expand */
4101 FALSE
, /* Fill has no effect here (expand false) */
4102 0); /* No padding */
4104 g_object_set_data(G_OBJECT(tab
->viewer_container
), "focused_viewer", NULL
);
4110 // Display a label with a X
4111 GtkWidget *w_hbox = gtk_hbox_new(FALSE, 4);
4112 GtkWidget *w_label = gtk_label_new (label);
4113 GtkWidget *pixmap = create_pixmap(GTK_WIDGET(notebook), "close.png");
4114 GtkWidget *w_button = gtk_button_new ();
4115 gtk_container_add(GTK_CONTAINER(w_button), pixmap);
4116 //GtkWidget *w_button = gtk_button_new_with_label("x");
4118 gtk_button_set_relief(GTK_BUTTON(w_button), GTK_RELIEF_NONE);
4120 gtk_box_pack_start(GTK_BOX(w_hbox), w_label, TRUE, TRUE, 0);
4121 gtk_box_pack_end(GTK_BOX(w_hbox), w_button, FALSE,
4124 g_signal_connect_swapped (w_button, "clicked",
4125 G_CALLBACK (on_close_tab_X_clicked),
4128 gtk_widget_set_state(w_button, GTK_STATE_ACTIVE);
4130 gtk_widget_show (w_label);
4131 gtk_widget_show (pixmap);
4132 gtk_widget_show (w_button);
4133 gtk_widget_show (w_hbox);
4135 tab->label = w_hbox;
4139 tab
->label
= gtk_label_new (label
);
4141 gtk_widget_show(tab
->label
);
4142 gtk_widget_show(tab
->scrollbar
);
4143 gtk_widget_show(tab
->MTimebar
);
4144 gtk_widget_show(tab
->viewer_container
);
4145 gtk_widget_show(tab
->vbox
);
4147 //gtk_widget_show(tab->multivpaned);
4150 /* Start with empty events requests list */
4151 tab
->events_requests
= NULL
;
4152 tab
->events_request_pending
= FALSE
;
4153 tab
->stop_foreground
= FALSE
;
4157 g_signal_connect(G_OBJECT(tab
->scrollbar
), "value-changed",
4158 G_CALLBACK(scroll_value_changed_cb
), tab
);
4161 /* Timebar signal handler */
4162 g_signal_connect(G_OBJECT(tab
->MTimebar
), "start-time-changed",
4163 G_CALLBACK(on_timebar_starttime_changed
), tab
);
4164 g_signal_connect(G_OBJECT(tab
->MTimebar
), "end-time-changed",
4165 G_CALLBACK(on_timebar_endtime_changed
), tab
);
4166 g_signal_connect(G_OBJECT(tab
->MTimebar
), "current-time-changed",
4167 G_CALLBACK(on_timebar_currenttime_changed
), tab
);
4169 //g_signal_connect(G_OBJECT(tab->scrollbar), "changed",
4170 // G_CALLBACK(scroll_value_changed_cb), tab);
4173 //insert tab into notebook
4174 gtk_notebook_append_page(notebook
,
4177 list
= gtk_container_get_children(GTK_CONTAINER(notebook
));
4178 gtk_notebook_set_current_page(notebook
,g_list_length(list
)-1);
4179 // always show : not if(g_list_length(list)>1)
4180 gtk_notebook_set_show_tabs(notebook
, TRUE
);
4183 lttvwindow_report_time_window(tab
, copy_tab
->time_window
);
4184 lttvwindow_report_current_time(tab
, copy_tab
->current_time
);
4186 TimeWindow time_window
;
4188 time_window
.start_time
= ltt_time_zero
;
4189 time_window
.end_time
= ltt_time_add(time_window
.start_time
,
4190 lttvwindow_default_time_width
);
4191 time_window
.time_width
= lttvwindow_default_time_width
;
4192 time_window
.time_width_double
= ltt_time_to_double(time_window
.time_width
);
4194 lttvwindow_report_time_window(tab
, time_window
);
4195 lttvwindow_report_current_time(tab
, ltt_time_zero
);
4198 LttvTraceset
*traceset
= tab
->traceset_info
->traceset
;
4199 SetTraceset(tab
, traceset
);
4203 * execute_events_requests
4205 * Idle function that executes the pending requests for a tab.
4207 * @return return value : TRUE : keep the idle function, FALSE : remove it.
4209 gboolean
execute_events_requests(Tab
*tab
)
4211 return ( lttvwindow_process_pending_requests(tab
) );
4215 __EXPORT
void create_main_window_with_trace_list(GSList
*traces
)
4218 GSList
*iter
= NULL
;
4221 MainWindow
*mw
= construct_main_window(NULL
);
4222 GtkWidget
*widget
= mw
->mwindow
;
4224 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
4225 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
4226 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
4227 LttvPluginTab
*ptab
;
4231 ptab
= create_new_tab(widget
, NULL
);
4234 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
4238 LttvTraceset
* traceset
= lttv_traceset_new();
4239 for(iter
=traces
; iter
!=NULL
; iter
=g_slist_next(iter
)) {
4240 gchar
*path
= (gchar
*)iter
->data
;
4242 gchar abs_path
[PATH_MAX
];
4245 get_absolute_pathname(path
, abs_path
);
4247 if(lttv_traceset_add_path(traceset
,abs_path
) != 0 ){ /*failure*/
4249 g_warning("cannot open trace %s", abs_path
);
4251 GtkWidget
*dialogue
=
4252 gtk_message_dialog_new(
4253 GTK_WINDOW(gtk_widget_get_toplevel(widget
)),
4254 GTK_DIALOG_MODAL
|GTK_DIALOG_DESTROY_WITH_PARENT
,
4257 "Cannot open trace : maybe you should enter in the directory "
4259 gtk_dialog_run(GTK_DIALOG(dialogue
));
4260 gtk_widget_destroy(dialogue
);
4263 SetTraceset(tab
, traceset
);