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 <lttv/time.h>
35 #include <lttv/lttv.h>
36 #include <lttv/module.h>
37 #include <lttv/iattribute.h>
38 #include <lttv/traceset.h>
39 #include <lttv/state.h>
41 #include <lttv/stats.h>
42 #include <lttv/sync/sync_chain_lttv.h>
43 #endif /* BABEL_CLEANUP */
44 #include <lttv/filter.h>
45 #include <lttvwindow/mainwindow.h>
46 #include <lttvwindow/mainwindow-private.h>
47 #include <lttvwindow/menu.h>
48 #include <lttvwindow/timebar.h>
49 #include <lttvwindow/toolbar.h>
50 #include <lttvwindow/lttvwindow.h>
51 #include <lttvwindow/lttvwindowtraces.h>
52 #include <lttvwindow/lttv_plugin_tab.h>
54 #include <babeltrace/babeltrace.h>
55 #include <babeltrace/ctf/events.h>
56 #include <babeltrace/ctf/iterator.h>
58 static LttTime lttvwindow_default_time_width
= { 1, 0 };
59 #define CLIP_BUF 256 // size of clipboard buffer
61 extern LttvTrace
*g_init_trace
;
64 /** Array containing instanced objects. */
65 extern GSList
* g_main_window_list
;
67 /** MD : keep old directory. */
68 static char remember_plugins_dir
[PATH_MAX
] = "";
69 static char remember_trace_dir
[PATH_MAX
] = "";
71 void tab_destructor(LttvPluginTab
* ptab
);
73 MainWindow
* get_window_data_struct(GtkWidget
* widget
);
74 char * get_load_module(MainWindow
*mw
,
75 char ** load_module_name
, int nb_module
);
76 char * get_unload_module(MainWindow
*mw
,
77 char ** loaded_module_name
, int nb_module
);
78 char * get_remove_trace(MainWindow
*mw
, char ** all_trace_name
, int nb_trace
);
79 char * get_selection(MainWindow
*mw
,
80 char ** all_name
, int nb
, char *title
, char * column_title
);
81 void init_tab(Tab
*tab
, MainWindow
* mw
, Tab
*copy_tab
,
82 GtkNotebook
* notebook
, char * label
);
84 int update_traceset(Tab
*tab
, LttvTraceset
*traceset
);
86 static void insert_viewer(GtkWidget
* widget
, lttvwindow_viewer_constructor constructor
);
88 LttvPluginTab
*create_new_tab(GtkWidget
* widget
, gpointer user_data
);
90 static gboolean
lttvwindow_process_pending_requests(Tab
*tab
);
92 static void on_timebar_starttime_changed(Timebar
*timebar
,
94 static void on_timebar_endtime_changed(Timebar
*timebar
,
96 static void on_timebar_currenttime_changed(Timebar
*timebar
,
113 static void on_top_notify(GObject
*gobject
,
117 Tab
*tab
= (Tab
*)user_data
;
118 g_message("in on_top_notify.\n");
122 static gboolean
viewer_grab_focus(GtkWidget
*widget
, GdkEventButton
*event
,
125 GtkWidget
*viewer
= GTK_WIDGET(data
);
126 GtkWidget
*viewer_container
= gtk_widget_get_parent(viewer
);
128 g_debug("FOCUS GRABBED");
129 g_object_set_data(G_OBJECT(viewer_container
), "focused_viewer", viewer
);
134 static void connect_focus_recursive(GtkWidget
*widget
,
137 if(GTK_IS_CONTAINER(widget
)) {
138 gtk_container_forall(GTK_CONTAINER(widget
),
139 (GtkCallback
)connect_focus_recursive
,
143 if(GTK_IS_TREE_VIEW(widget
)) {
144 gtk_tree_view_set_headers_clickable(GTK_TREE_VIEW(widget
), TRUE
);
146 gtk_widget_add_events(widget
, GDK_BUTTON_PRESS_MASK
);
147 g_signal_connect (G_OBJECT(widget
),
148 "button-press-event",
149 G_CALLBACK (viewer_grab_focus
),
153 /* Stop all the processings and call gtk_main_quit() */
154 static void mainwindow_quit()
156 lttvwindowtraces_unregister_requests(g_quark_from_string("stats"));
157 lttvwindowtraces_unregister_requests(g_quark_from_string("state"));
158 lttvwindowtraces_unregister_computation_hooks(g_quark_from_string("stats"));
159 lttvwindowtraces_unregister_computation_hooks(g_quark_from_string("state"));
165 /* insert_viewer function constructs an instance of a viewer first,
166 * then inserts the widget of the instance into the container of the
171 insert_viewer_wrap(GtkWidget
*menuitem
, gpointer user_data
)
173 insert_viewer((GtkWidget
*)menuitem
, (lttvwindow_viewer_constructor
)user_data
);
177 /* internal functions */
178 void insert_viewer(GtkWidget
* widget
, lttvwindow_viewer_constructor constructor
)
180 GtkWidget
* viewer_container
;
181 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
183 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
184 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
189 ptab
= create_new_tab(widget
, NULL
);
191 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
195 viewer_container
= tab
->viewer_container
;
197 viewer
= (GtkWidget
*)constructor(&ptab
->parent
);
200 //gtk_multivpaned_widget_add(GTK_MULTIVPANED(multivpaned), viewer);
202 gtk_box_pack_end(GTK_BOX(viewer_container
),
208 /* We want to connect the viewer_grab_focus to EVERY
209 * child of this widget. The little trick is to get each child
210 * of each GTK_CONTAINER, even subchildren.
212 connect_focus_recursive(viewer
, viewer
);
217 * Function to set/update traceset for the viewers
218 * @param tab viewer's tab
219 * @param traceset traceset of the main window.
221 * 0 : traceset updated
222 * 1 : no traceset hooks to update; not an error.
225 int SetTraceset(Tab
* tab
, LttvTraceset
*traceset
)
228 TimeInterval time_span
;
229 TimeWindow new_time_window
;
230 LttTime new_current_time
;
233 // Perform time synchronization on the traces
234 if (syncTraceset(tsc
))
236 /* There is some time-dependant information that was calculated during
237 * context initialization. Destroy the old contexts and initialize new
239 * Modified from lttvwindow_add_trace()
241 // Keep a reference to the traces so they are not freed
242 for(i
= 0; i
< lttv_traceset_number(traceset
); i
++)
244 LttvTrace
*trace
= lttv_traceset_get(traceset
, i
);
245 lttv_trace_ref(trace
);
248 // Remove state update hooks
249 lttv_state_remove_event_hooks(
250 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
252 lttv_context_fini(LTTV_TRACESET_CONTEXT(
253 tab
->traceset_info
->traceset_context
));
254 g_object_unref(tab
->traceset_info
->traceset_context
);
256 for(i
= 0; i
< lttv_traceset_number(traceset
); i
++)
258 LttvTrace
*trace
= lttv_traceset_get(traceset
, i
);
259 lttvwindowtraces_remove_trace(trace
);
260 lttvwindowtraces_add_trace(trace
);
263 // Create new context
264 tab
->traceset_info
->traceset_context
=
265 g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
266 lttv_context_init(LTTV_TRACESET_CONTEXT(tab
->traceset_info
->
267 traceset_context
), traceset
);
269 // Add state update hooks
270 lttv_state_add_event_hooks(
271 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
273 // Remove local reference to the traces
274 for(i
=0; i
<lttv_traceset_number(traceset
); i
++)
276 LttvTrace
*trace
= lttv_traceset_get(traceset
, i
);
277 lttv_trace_unref(trace
);
280 tsc
= LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
282 #endif /*BABEL_CLEANUP*/
284 time_span
= lttv_traceset_get_time_span_real(traceset
);
286 tab
->traceset_info
->traceset
= traceset
;
288 new_time_window
= tab
->time_window
;
289 new_current_time
= tab
->current_time
;
291 /* Set the tab's time window and current time if
293 if(ltt_time_compare(tab
->time_window
.start_time
, time_span
.start_time
) < 0
294 || ltt_time_compare(tab
->time_window
.end_time
,
295 time_span
.end_time
) > 0) {
296 new_time_window
.start_time
= time_span
.start_time
;
298 new_current_time
= time_span
.start_time
;
302 if(ltt_time_compare(lttvwindow_default_time_width
,
303 ltt_time_sub(time_span
.end_time
, time_span
.start_time
)) < 0
305 ltt_time_compare(time_span
.end_time
, time_span
.start_time
) == 0)
306 tmp_time
= lttvwindow_default_time_width
;
308 tmp_time
= time_span
.end_time
;
310 new_time_window
.time_width
= tmp_time
;
311 new_time_window
.time_width_double
= ltt_time_to_double(tmp_time
);
312 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
313 new_time_window
.time_width
) ;
315 lttv_state_add_event_hooks(traceset
);
317 //TODO ybrosseau 2012-08-03 Temporarly compute checkpoints right at the adding
319 //Compute the traceset state checkpoint
322 EventsRequest
*events_request
= g_new(EventsRequest
, 1);
324 LttvHooks
*hook_adder
= lttv_hooks_new();
325 lttv_hooks_add(hook_adder
, lttv_state_save_hook_add_event_hooks
, NULL
,
327 LttvHooks
*hook_remover
= lttv_hooks_new();
328 lttv_hooks_add(hook_remover
, lttv_state_save_hook_remove_event_hooks
,
329 NULL
, LTTV_PRIO_DEFAULT
);
331 // Fill the events request
332 events_request
->owner
= NULL
;
333 events_request
->viewer_data
= NULL
;
334 events_request
->servicing
= FALSE
;
335 events_request
->start_time
= ltt_time_zero
;
336 events_request
->start_position
= NULL
;
337 events_request
->stop_flag
= FALSE
;
338 events_request
->end_time
= ltt_time_infinite
;
339 events_request
->num_events
= G_MAXUINT
;
340 events_request
->end_position
= NULL
;
341 events_request
->trace
= 1; //fixed /* FIXME */
342 events_request
->before_chunk_traceset
= NULL
;
343 events_request
->before_chunk_trace
= NULL
;
344 events_request
->before_chunk_tracefile
= NULL
;
345 events_request
->event
= NULL
;
346 events_request
->after_chunk_tracefile
= NULL
;
347 events_request
->after_chunk_trace
= NULL
;
348 events_request
->after_chunk_traceset
= NULL
;
349 events_request
->before_request
= hook_adder
;
350 events_request
->after_request
= hook_remover
;
352 lttvwindow_events_request(tab
, events_request
);
355 /* Finally, call the update hooks of the viewers */
356 gint retval
= update_traceset(tab
, traceset
);
358 time_change_manager(tab
, new_time_window
);
359 current_time_change_manager(tab
, new_current_time
);
366 * Function to set/update filter for the viewers
367 * @param tab viewer's tab
368 * @param filter filter of the main window.
371 * 0 : filters updated
372 * 1 : no filter hooks to update; not an error.
375 int SetFilter(Tab
* tab
, gpointer filter
)
378 LttvAttributeValue value
;
380 g_assert(lttv_iattribute_find_by_path(tab
->attributes
,
381 "hooks/updatefilter", LTTV_POINTER
, &value
));
383 tmp
= (LttvHooks
*)*(value
.v_pointer
);
385 if(tmp
== NULL
) return 1;
386 lttv_hooks_call(tmp
,filter
);
394 * Function to redraw each viewer belonging to the current tab
395 * @param tab viewer's tab
398 int update_traceset(Tab
*tab
, LttvTraceset
*traceset
)
400 LttvAttributeValue value
;
404 retval
= lttv_iattribute_find_by_path(tab
->attributes
,
405 "hooks/updatetraceset",
409 tmp
= (LttvHooks
*)*(value
.v_pointer
);
413 lttv_hooks_call(tmp
, traceset
);
419 Call hooks register to get update on traceset time span changes
421 int notify_time_span_changed(Tab
*tab
)
423 LttvAttributeValue value
;
427 retval
= lttv_iattribute_find_by_path(tab
->attributes
,
428 "hooks/updatetimespan",
432 tmp
= (LttvHooks
*)*(value
.v_pointer
);
436 lttv_hooks_call(tmp
, NULL
);
441 /* get_label function is used to get user input, it displays an input
442 * box, which allows user to input a string
445 void get_label_string (GtkWidget
* text
, gchar
* label
)
447 GtkEntry
* entry
= (GtkEntry
*)text
;
448 if(strlen(gtk_entry_get_text(entry
))!=0)
449 strcpy(label
,gtk_entry_get_text(entry
));
452 gboolean
get_label(MainWindow
* mw
, gchar
* str
, gchar
* dialogue_title
, gchar
* label_str
)
454 GtkWidget
* dialogue
;
459 dialogue
= gtk_dialog_new_with_buttons(dialogue_title
,NULL
,
461 GTK_STOCK_OK
,GTK_RESPONSE_ACCEPT
,
462 GTK_STOCK_CANCEL
,GTK_RESPONSE_REJECT
,
465 label
= gtk_label_new(label_str
);
466 gtk_widget_show(label
);
468 text
= gtk_entry_new();
469 gtk_widget_show(text
);
471 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialogue
)->vbox
), label
,TRUE
, TRUE
,0);
472 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialogue
)->vbox
), text
,FALSE
, FALSE
,0);
474 id
= gtk_dialog_run(GTK_DIALOG(dialogue
));
476 case GTK_RESPONSE_ACCEPT
:
477 get_label_string(text
,str
);
478 gtk_widget_destroy(dialogue
);
480 case GTK_RESPONSE_REJECT
:
482 gtk_widget_destroy(dialogue
);
489 /* get_window_data_struct function is actually a lookup function,
490 * given a widget which is in the tree of the main window, it will
491 * return the MainWindow data structure associated with main window
494 MainWindow
* get_window_data_struct(GtkWidget
* widget
)
497 MainWindow
* mw_data
;
499 mw
= lookup_widget(widget
, "MWindow");
501 g_info("Main window does not exist\n");
505 mw_data
= (MainWindow
*) g_object_get_data(G_OBJECT(mw
),"main_window_data");
507 g_warning("Main window data does not exist\n");
514 /* create_new_window function, just constructs a new main window
517 void create_new_window(GtkWidget
* widget
, gpointer user_data
, gboolean clone
)
519 MainWindow
* parent
= get_window_data_struct(widget
);
522 g_info("Clone : use the same traceset\n");
523 construct_main_window(parent
);
525 g_info("Empty : traceset is set to NULL\n");
526 construct_main_window(NULL
);
530 /* Get the currently focused viewer.
531 * If no viewer is focused, use the first one.
533 * If no viewer available, return NULL.
535 GtkWidget
*viewer_container_focus(GtkWidget
*container
)
539 widget
= (GtkWidget
*)g_object_get_data(G_OBJECT(container
),
543 g_debug("no widget focused");
544 GList
*children
= gtk_container_get_children(GTK_CONTAINER(container
));
547 widget
= GTK_WIDGET(children
->data
);
548 g_object_set_data(G_OBJECT(container
),
558 gint
viewer_container_position(GtkWidget
*container
, GtkWidget
*child
)
561 if(child
== NULL
) return -1;
565 memset(&value
, 0, sizeof(GValue
));
566 g_value_init(&value
, G_TYPE_INT
);
567 gtk_container_child_get_property(GTK_CONTAINER(container
),
571 pos
= g_value_get_int(&value
);
577 /* move_*_viewer functions move the selected view up/down in
581 void move_down_viewer(GtkWidget
* widget
, gpointer user_data
)
583 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
585 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
586 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
593 ptab
= g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
597 //gtk_multivpaned_widget_move_up(GTK_MULTIVPANED(tab->multivpaned));
599 /* change the position in the vbox */
600 GtkWidget
*focus_widget
;
602 focus_widget
= viewer_container_focus(tab
->viewer_container
);
603 position
= viewer_container_position(tab
->viewer_container
, focus_widget
);
606 /* can move up one position */
607 gtk_box_reorder_child(GTK_BOX(tab
->viewer_container
),
614 void move_up_viewer(GtkWidget
* widget
, gpointer user_data
)
616 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
618 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
619 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
626 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
630 //gtk_multivpaned_widget_move_down(GTK_MULTIVPANED(tab->multivpaned));
631 /* change the position in the vbox */
632 GtkWidget
*focus_widget
;
634 focus_widget
= viewer_container_focus(tab
->viewer_container
);
635 position
= viewer_container_position(tab
->viewer_container
, focus_widget
);
639 g_list_length(gtk_container_get_children(
640 GTK_CONTAINER(tab
->viewer_container
)))-1
642 /* can move down one position */
643 gtk_box_reorder_child(GTK_BOX(tab
->viewer_container
),
651 /* delete_viewer deletes the selected viewer in the current tab
654 void delete_viewer(GtkWidget
* widget
, gpointer user_data
)
656 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
658 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
659 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
666 ptab
= g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
670 //gtk_multivpaned_widget_delete(GTK_MULTIVPANED(tab->multivpaned));
672 GtkWidget
*focus_widget
= viewer_container_focus(tab
->viewer_container
);
674 if(focus_widget
!= NULL
)
675 gtk_widget_destroy(focus_widget
);
677 g_object_set_data(G_OBJECT(tab
->viewer_container
), "focused_viewer", NULL
);
680 #if UNFINISHED_FEATURE
681 /* TODO ybrosseau 2012-03-15: Function is half implemented. Should be removed */
682 /* open_traceset will open a traceset saved in a file
683 * Right now, it is not finished yet, (not working)
687 void open_traceset(GtkWidget
* widget
, gpointer user_data
)
691 LttvTraceset
* traceset
;
692 MainWindow
* mw_data
= get_window_data_struct(widget
);
693 GtkFileSelection
* file_selector
=
694 (GtkFileSelection
*)gtk_file_selection_new("Select a traceset");
696 gtk_file_selection_hide_fileop_buttons(file_selector
);
698 gtk_window_set_transient_for(GTK_WINDOW(file_selector
),
699 GTK_WINDOW(mw_data
->mwindow
));
701 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
703 case GTK_RESPONSE_ACCEPT
:
704 case GTK_RESPONSE_OK
:
705 dir
= gtk_file_selection_get_selections (file_selector
);
706 traceset
= lttv_traceset_load(dir
[0]);
707 g_info("Open a trace set %s\n", dir
[0]);
710 case GTK_RESPONSE_REJECT
:
711 case GTK_RESPONSE_CANCEL
:
713 gtk_widget_destroy((GtkWidget
*)file_selector
);
719 /* lttvwindow_process_pending_requests
721 * Process requests for parts of the trace from viewers.
723 * These requests are made by lttvwindow_events_request().
725 * This internal function gets called by g_idle, taking care of the pending
726 * requests. It is responsible for concatenation of time intervals and position
727 * requests. It does it with the following algorithm organizing process traceset
728 * calls. Here is the detailed description of the way it works :
730 * - Events Requests Servicing Algorithm
732 * Data structures necessary :
734 * List of requests added to context : list_in
735 * List of requests not added to context : list_out
740 * list_out : many events requests
742 * FIXME : insert rest of algorithm here
746 #define list_out tab->events_requests
748 gboolean
lttvwindow_process_pending_requests(Tab
*tab
)
753 GSList
*list_in
= NULL
;
757 LttvTracesetPosition
*end_position
;
759 if(lttvwindow_preempt_count
> 0) return TRUE
;
762 g_critical("Foreground processing : tab does not exist. Processing removed.");
766 /* There is no events requests pending : we should never have been called! */
767 g_assert(g_slist_length(list_out
) != 0);
769 ts
= tab
->traceset_info
->traceset
;
771 //set the cursor to be X shape, indicating that the computer is busy in doing its job
773 new = gdk_cursor_new(GDK_X_CURSOR
);
774 widget
= lookup_widget(tab
->mw
->mwindow
, "MToolbar1");
775 win
= gtk_widget_get_parent_window(widget
);
776 gdk_window_set_cursor(win
, new);
777 gdk_cursor_unref(new);
778 gdk_window_stick(win
);
779 gdk_window_unstick(win
);
782 g_debug("SIZE events req len : %d", g_slist_length(list_out
));
784 /* Preliminary check for no trace in traceset */
785 /* Unregister the routine if empty, empty list_out too */
786 if(lttv_traceset_number(ts
) == 0) {
788 /* - For each req in list_out */
789 GSList
*iter
= list_out
;
791 while(iter
!= NULL
) {
793 gboolean remove
= FALSE
;
794 gboolean free_data
= FALSE
;
795 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
797 /* - Call end request for req */
798 if(events_request
->servicing
== TRUE
)
799 lttv_hooks_call(events_request
->after_request
, (gpointer
)ts
);
801 /* - remove req from list_out */
802 /* Destroy the request */
805 //TODO ybrosseau: This if is always true
809 GSList
*remove_iter
= iter
;
811 iter
= g_slist_next(iter
);
812 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
813 list_out
= g_slist_remove_link(list_out
, remove_iter
);
814 } else { // not remove
815 iter
= g_slist_next(iter
);
820 /* 0.1 Lock Traces */
825 iter_trace
<lttv_traceset_number(ts
);
827 LttvTrace
*trace_v
= lttv_traceset_get(ts
, iter_trace
);
829 if(lttvwindowtraces_lock(trace_v
) != 0) {
830 g_critical("Foreground processing : Unable to get trace lock");
831 return TRUE
; /* Cannot get lock, try later */
836 /* 0.2 Seek tracefiles positions to context position */
838 //g_assert(lttv_process_traceset_seek_position(tsc, sync_position) == 0);
839 lttv_process_traceset_synchronize_tracefiles(tsc
);
842 /* Events processing algorithm implementation */
843 /* Warning : the gtk_events_pending takes a LOT of cpu time. So what we do
844 * instead is to leave the control to GTK and take it back.
846 /* A. Servicing loop */
847 //while( (g_slist_length(list_in) != 0 || g_slist_length(list_out) != 0)) {
848 if((g_slist_length(list_in
) != 0 || g_slist_length(list_out
) != 0)) {
850 /* 1. If list_in is empty (need a seek) */
851 if( g_slist_length(list_in
) == 0 ) {
853 /* list in is empty, need a seek */
855 /* 1.1 Add requests to list_in */
856 GSList
*ltime
= NULL
;
860 /* 1.1.1 Find all time requests with the lowest start time in list_out
863 if(g_slist_length(list_out
) > 0)
864 ltime
= g_slist_append(ltime
, g_slist_nth_data(list_out
, 0));
865 for(iter
=g_slist_nth(list_out
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
866 /* Find all time requests with the lowest start time in list_out */
867 EventsRequest
*event_request_ltime
= (EventsRequest
*)g_slist_nth_data(ltime
, 0);
868 EventsRequest
*event_request_list_out
= (EventsRequest
*)iter
->data
;
871 comp
= ltt_time_compare(event_request_ltime
->start_time
,
872 event_request_list_out
->start_time
);
874 ltime
= g_slist_append(ltime
, event_request_list_out
);
876 /* Remove all elements from ltime, and add current */
878 ltime
= g_slist_delete_link(ltime
, g_slist_nth(ltime
, 0));
879 ltime
= g_slist_append(ltime
, event_request_list_out
);
883 /* 1.1.2 Find all position requests with the lowest position in list_out
886 if(g_slist_length(list_out
) > 0)
887 lpos
= g_slist_append(lpos
, g_slist_nth_data(list_out
, 0));
888 for(iter
=g_slist_nth(list_out
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
889 /* Find all position requests with the lowest position in list_out */
890 EventsRequest
*event_request_lpos
= (EventsRequest
*)g_slist_nth_data(lpos
, 0);
891 EventsRequest
*event_request_list_out
= (EventsRequest
*)iter
->data
;
894 if(event_request_lpos
->start_position
!= NULL
895 && event_request_list_out
->start_position
!= NULL
)
897 //TODO ybrosseau: this compare is in fact an equal, so the behavior might not be right.
898 comp
= lttv_traceset_position_time_compare
899 (event_request_lpos
->start_position
,
900 event_request_list_out
->start_position
);
905 lpos
= g_slist_append(lpos
, event_request_list_out
);
907 /* Remove all elements from lpos, and add current */
909 lpos
= g_slist_delete_link(lpos
, g_slist_nth(lpos
, 0));
910 lpos
= g_slist_append(lpos
, event_request_list_out
);
915 EventsRequest
*event_request_lpos
= (EventsRequest
*)g_slist_nth_data(lpos
, 0);
916 EventsRequest
*event_request_ltime
= (EventsRequest
*)g_slist_nth_data(ltime
, 0);
917 LttTime lpos_start_time
;
919 if(event_request_lpos
!= NULL
920 && event_request_lpos
->start_position
!= NULL
) {
921 lpos_start_time
= lttv_traceset_position_get_time(
922 event_request_lpos
->start_position
);
925 /* 1.1.3 If lpos.start time < ltime */
926 if(event_request_lpos
!= NULL
927 && event_request_lpos
->start_position
!= NULL
928 && ltt_time_compare(lpos_start_time
,
929 event_request_ltime
->start_time
)<0) {
930 /* Add lpos to list_in, remove them from list_out */
931 for(iter
=lpos
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
933 EventsRequest
*event_request_lpos
=
934 (EventsRequest
*)iter
->data
;
936 list_in
= g_slist_append(list_in
, event_request_lpos
);
937 /* Remove from list_out */
938 list_out
= g_slist_remove(list_out
, event_request_lpos
);
941 /* 1.1.4 (lpos.start time >= ltime) */
942 /* Add ltime to list_in, remove them from list_out */
944 for(iter
=ltime
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
946 EventsRequest
*event_request_ltime
=
947 (EventsRequest
*)iter
->data
;
949 list_in
= g_slist_append(list_in
, event_request_ltime
);
950 /* Remove from list_out */
951 list_out
= g_slist_remove(list_out
, event_request_ltime
);
962 g_assert(g_slist_length(list_in
)>0);
963 EventsRequest
*events_request
= g_slist_nth_data(list_in
, 0);
968 /* 1.2.1 If first request in list_in is a time request */
969 if(events_request
->start_position
== NULL
) {
970 /* - If first req in list_in start time != current time */
971 //TODO ybrosseau: if commented out, since it was only affecting the g_debug
972 //if(tfc == NULL || ltt_time_compare(events_request->start_time,
973 // tfc->timestamp) != 0)
974 /* - Seek to that time */
975 g_debug("SEEK TIME : %lu, %lu", events_request
->start_time
.tv_sec
,
976 events_request
->start_time
.tv_nsec
);
977 lttv_state_traceset_seek_time_closest(ts
,
978 events_request
->start_time
);
980 /* Process the traceset with only state hooks */
984 lttv_process_traceset_middle(ts
,
985 events_request
->start_time
,
988 g_assert(seek_count
< LTTV_STATE_SAVE_INTERVAL
);
994 //LttvTracefileContext *tfc =
995 // lttv_traceset_context_get_current_tfc(tsc);
996 /* Else, the first request in list_in is a position request */
997 /* If first req in list_in pos != current pos */
998 g_assert(events_request
->start_position
!= NULL
);
999 g_debug("SEEK POS time : %lu, %lu",
1000 lttv_traceset_position_get_time(
1001 events_request
->start_position
).tv_sec
,
1002 lttv_traceset_position_get_time(
1003 events_request
->start_position
).tv_nsec
);
1005 /*if(tfc) {*/ if(0) {
1006 /* g_debug("SEEK POS context time : %lu, %lu",
1007 tfc->timestamp.tv_sec,
1008 tfc->timestamp.tv_nsec); */
1010 g_debug("SEEK POS context time : %lu, %lu",
1011 ltt_time_infinite
.tv_sec
,
1012 ltt_time_infinite
.tv_nsec
);
1014 g_assert(events_request
->start_position
!= NULL
);
1015 //TODO ybrosseau: for now, always seek
1016 if(/*lttv_traceset_context_ctx_pos_compare(tsc,
1017 events_request->start_position) != 0*/1) {
1018 /* 1.2.2.1 Seek to that position */
1019 g_debug("SEEK POSITION");
1020 //lttv_process_traceset_seek_position(tsc, events_request->start_position);
1021 pos_time
= lttv_traceset_position_get_time(
1022 events_request
->start_position
);
1024 lttv_state_traceset_seek_time_closest(ts
,
1026 //lttv_traceset_seek_to_position( events_request->start_position);
1028 /* Process the traceset with only state hooks */
1032 lttv_process_traceset_middle(ts
,
1035 events_request
->start_position
);
1037 //g_assert(lttv_traceset_context_ctx_pos_compare(tsc,
1038 // events_request->start_position) == 0);
1045 /* 1.3 Add hooks and call before request for all list_in members */
1047 GSList
*iter
= NULL
;
1048 for(iter
=list_in
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
1049 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1050 /* 1.3.1 If !servicing */
1051 if(events_request
->servicing
== FALSE
) {
1052 /* - begin request hooks called
1053 * - servicing = TRUE
1055 lttv_hooks_call(events_request
->before_request
, (gpointer
)ts
);
1056 events_request
->servicing
= TRUE
;
1058 /* 1.3.2 call before chunk
1059 * 1.3.3 events hooks added
1061 //TODO ybrosseau 2012-07-10: || TRUE added since we only support
1062 // traceset wide requests
1063 if(events_request
->trace
== -1 || TRUE
) {
1065 lttv_process_traceset_begin(ts
,
1066 events_request
->before_chunk_traceset
,
1067 events_request
->before_chunk_trace
,
1068 events_request
->event
1071 guint nb_trace
= lttv_traceset_number(ts
);
1072 g_assert((guint
)events_request
->trace
< nb_trace
&&
1073 events_request
->trace
> -1);
1074 LttvTrace
*trace
= lttv_traceset_get(ts
, events_request
->trace
);
1076 lttv_hooks_call(events_request
->before_chunk_traceset
, ts
);
1078 lttv_trace_add_hooks(trace
, events_request
->before_chunk_trace
,
1079 events_request
->event
);
1084 /* 2. Else, list_in is not empty, we continue a read */
1087 /* 2.0 For each req of list_in */
1088 GSList
*iter
= list_in
;
1090 while(iter
!= NULL
) {
1092 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1094 /* - Call before chunk
1095 * - events hooks added
1097 //TODO ybrosseau 2012-07-10: || TRUE added since we only support
1098 // traceset wide requests
1099 if(events_request
->trace
== -1 || TRUE
)
1100 lttv_process_traceset_begin(ts
,
1101 events_request
->before_chunk_traceset
,
1102 events_request
->before_chunk_trace
,
1103 events_request
->event
1106 guint nb_trace
= lttv_traceset_number(ts
);
1107 g_assert((guint
)events_request
->trace
< nb_trace
&&
1108 events_request
->trace
> -1);
1109 LttvTrace
*trace
= lttv_traceset_get(ts
, events_request
->trace
);
1111 lttv_hooks_call(events_request
->before_chunk_traceset
, ts
);
1113 lttv_trace_add_hooks(trace
,
1114 events_request
->before_chunk_trace
,
1115 events_request
->event
1119 iter
= g_slist_next(iter
);
1126 /* 2.1 For each req of list_out */
1127 GSList
*iter
= list_out
;
1129 while(iter
!= NULL
) {
1131 gboolean remove
= FALSE
;
1132 gboolean free_data
= FALSE
;
1133 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1135 /* if req.start time == current context time
1136 * or req.start position == current position*/
1137 /* if( ltt_time_compare(events_request->start_time,
1138 tfc->timestamp) == 0
1140 (events_request->start_position != NULL
1142 lttv_traceset_context_ctx_pos_compare(tsc,
1143 events_request->start_position) == 0)
1146 if(lttv_traceset_position_compare_current(ts
, events_request
->start_position
) == 0) {
1148 /* - Add to list_in, remove from list_out */
1149 list_in
= g_slist_append(list_in
, events_request
);
1153 /* - If !servicing */
1154 if(events_request
->servicing
== FALSE
) {
1155 /* - begin request hooks called
1156 * - servicing = TRUE
1158 lttv_hooks_call(events_request
->before_request
, (gpointer
)ts
);
1159 events_request
->servicing
= TRUE
;
1161 /* call before chunk
1162 * events hooks added
1164 //TODO ybrosseau 2012-07-10: || TRUE added since we only support
1165 // traceset wide requests
1166 if(events_request
->trace
== -1 || TRUE
)
1167 lttv_process_traceset_begin(ts
,
1168 events_request
->before_chunk_traceset
,
1169 events_request
->before_chunk_trace
,
1170 events_request
->event
1173 guint nb_trace
= lttv_traceset_number(ts
);
1174 g_assert((guint
)events_request
->trace
< nb_trace
&&
1175 events_request
->trace
> -1);
1176 LttvTrace
* trace
= lttv_traceset_get(ts
,events_request
->trace
);
1178 lttv_hooks_call(events_request
->before_chunk_traceset
, ts
);
1180 lttv_trace_add_hooks(trace
,
1181 events_request
->before_chunk_trace
,
1183 events_request
->event
);
1193 GSList
*remove_iter
= iter
;
1195 iter
= g_slist_next(iter
);
1196 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
1197 list_out
= g_slist_remove_link(list_out
, remove_iter
);
1198 } else { // not remove
1199 iter
= g_slist_next(iter
);
1205 /* 3. Find end criterions */
1210 /* 3.1.1 Find lowest end time in list_in */
1211 g_assert(g_slist_length(list_in
)>0);
1212 end_time
= ((EventsRequest
*)g_slist_nth_data(list_in
,0))->end_time
;
1214 for(iter
=g_slist_nth(list_in
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
1215 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1217 if(ltt_time_compare(events_request
->end_time
,
1219 end_time
= events_request
->end_time
;
1222 /* 3.1.2 Find lowest start time in list_out */
1223 for(iter
=list_out
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
1224 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1226 if(ltt_time_compare(events_request
->start_time
,
1228 end_time
= events_request
->start_time
;
1233 /* 3.2 Number of events */
1235 /* 3.2.1 Find lowest number of events in list_in */
1238 end_nb_events
= ((EventsRequest
*)g_slist_nth_data(list_in
,0))->num_events
;
1240 for(iter
=g_slist_nth(list_in
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
1241 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1243 if(events_request
->num_events
< end_nb_events
)
1244 end_nb_events
= events_request
->num_events
;
1247 /* 3.2.2 Use min(CHUNK_NUM_EVENTS, min num events in list_in) as
1250 end_nb_events
= MIN(CHUNK_NUM_EVENTS
, end_nb_events
);
1254 /* 3.3 End position */
1256 /* 3.3.1 Find lowest end position in list_in */
1259 end_position
=((EventsRequest
*)g_slist_nth_data(list_in
,0))->end_position
;
1261 for(iter
=g_slist_nth(list_in
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
1262 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1264 if(events_request
->end_position
!= NULL
&& end_position
!= NULL
&&
1265 lttv_traceset_position_time_compare(events_request
->end_position
,
1267 end_position
= events_request
->end_position
;
1272 /* 3.3.2 Find lowest start position in list_out */
1275 for(iter
=list_out
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
1276 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1278 if(events_request
->end_position
!= NULL
&& end_position
!= NULL
&&
1279 lttv_traceset_position_time_compare(events_request
->end_position
,
1281 end_position
= events_request
->end_position
;
1286 /* 4. Call process traceset middle */
1287 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
);
1288 count
= lttv_process_traceset_middle(ts
, end_time
, end_nb_events
, end_position
);
1290 #ifdef BABEL_CLEANUP
1291 tfc
= lttv_traceset_context_get_current_tfc(tsc
);
1293 g_debug("Context time after middle : %lu, %lu", tfc
->timestamp
.tv_sec
,
1294 tfc
->timestamp
.tv_nsec
);
1296 g_debug("End of trace reached after middle.");
1301 /* 5. After process traceset middle */
1303 LttTime curTime
= lttv_traceset_get_current_time(ts
);
1304 /* - if the iterator is not valid anymore (got to the end) */
1305 if(bt_ctf_iter_read_event(ts
->iter
) == NULL
) {
1306 /* - For each req in list_in */
1307 GSList
*iter
= list_in
;
1309 while(iter
!= NULL
) {
1311 gboolean remove
= FALSE
;
1312 gboolean free_data
= FALSE
;
1313 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1315 /* - Remove events hooks for req
1316 * - Call end chunk for req
1318 //TODO ybrosseau 2012-07-10: || TRUE added since we only support
1319 // traceset wide requests
1320 if(events_request
->trace
== -1 || TRUE
)
1321 lttv_process_traceset_end(ts
,
1322 events_request
->after_chunk_traceset
,
1323 events_request
->after_chunk_trace
,
1325 events_request
->event
);
1328 guint nb_trace
= lttv_traceset_number(ts
);
1329 g_assert(events_request
->trace
< nb_trace
&&
1330 events_request
->trace
> -1);
1331 LttvTrace
*trace
= lttv_traceset_get(ts
,events_request
->trace
);
1333 lttv_trace_remove_hooks(trace
,
1334 events_request
->after_chunk_trace
,
1336 events_request
->event
);
1338 lttv_hooks_call(events_request
->after_chunk_traceset
, ts
);
1343 /* - Call end request for req */
1344 lttv_hooks_call(events_request
->after_request
, (gpointer
)ts
);
1346 /* - remove req from list_in */
1347 /* Destroy the request */
1354 GSList
*remove_iter
= iter
;
1356 iter
= g_slist_next(iter
);
1357 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
1358 list_in
= g_slist_remove_link(list_in
, remove_iter
);
1359 } else { // not remove
1360 iter
= g_slist_next(iter
);
1365 /* 5.1 For each req in list_in */
1366 GSList
*iter
= list_in
;
1368 while(iter
!= NULL
) {
1370 gboolean remove
= FALSE
;
1371 gboolean free_data
= FALSE
;
1372 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1374 /* - Remove events hooks for req
1375 * - Call end chunk for req
1377 //TODO ybrosseau 2012-07-10: || TRUE added since we only support
1378 // traceset wide requests
1379 if(events_request
->trace
== -1 || TRUE
) {
1380 lttv_process_traceset_end(ts
,
1381 events_request
->after_chunk_traceset
,
1382 events_request
->after_chunk_trace
,
1383 events_request
->event
);
1385 guint nb_trace
= lttv_traceset_number(ts
);
1386 g_assert(events_request
->trace
< nb_trace
&&
1387 events_request
->trace
> -1);
1388 LttvTrace
*trace
= lttv_traceset_get(ts
, events_request
->trace
);
1390 lttv_trace_remove_hooks(trace
,
1391 events_request
->after_chunk_trace
,
1393 events_request
->event
);
1396 lttv_hooks_call(events_request
->after_chunk_traceset
, ts
);
1399 /* - req.num -= count */
1400 g_assert(events_request
->num_events
>= count
);
1401 events_request
->num_events
-= count
;
1403 //g_assert(tfc != NULL);
1404 /* - if req.num == 0
1406 * current context time >= req.end time
1408 * req.end pos == current pos
1410 * req.stop_flag == TRUE
1412 if( events_request
->num_events
== 0
1414 events_request
->stop_flag
== TRUE
1416 ltt_time_compare(lttv_traceset_get_current_time(ts
),
1417 events_request
->end_time
) >= 0
1419 (events_request
->end_position
!= NULL
1421 lttv_traceset_position_compare_current(ts
,
1422 events_request
->end_position
) == 0)
1425 g_assert(events_request
->servicing
== TRUE
);
1426 /* - Call end request for req
1427 * - remove req from list_in */
1428 lttv_hooks_call(events_request
->after_request
, (gpointer
)ts
);
1429 /* - remove req from list_in */
1430 /* Destroy the request */
1438 GSList
*remove_iter
= iter
;
1440 iter
= g_slist_next(iter
);
1441 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
1442 list_in
= g_slist_remove_link(list_in
, remove_iter
);
1443 } else { // not remove
1444 iter
= g_slist_next(iter
);
1450 /* End of removed servicing loop : leave control to GTK instead. */
1451 // if(gtk_events_pending()) break;
1454 /* B. When interrupted between chunks */
1457 GSList
*iter
= list_in
;
1459 /* 1. for each request in list_in */
1460 while(iter
!= NULL
) {
1462 gboolean remove
= FALSE
;
1463 gboolean free_data
= FALSE
;
1464 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1466 /* 1.1. Use current postition as start position */
1467 if(events_request
->start_position
!= NULL
)
1468 lttv_traceset_destroy_position(events_request
->start_position
);
1469 events_request
->start_position
= lttv_traceset_create_current_position(ts
);
1472 /* 1.2. Remove start time */
1473 events_request
->start_time
= ltt_time_infinite
;
1475 /* 1.3. Move from list_in to list_out */
1478 list_out
= g_slist_append(list_out
, events_request
);
1483 GSList
*remove_iter
= iter
;
1485 iter
= g_slist_next(iter
);
1486 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
1487 list_in
= g_slist_remove_link(list_in
, remove_iter
);
1488 } else { // not remove
1489 iter
= g_slist_next(iter
);
1495 /* C Unlock Traces */
1497 #ifdef BABEL_CLEANUP
1498 lttv_process_traceset_get_sync_data(tsc
);
1500 //lttv_traceset_context_position_save(tsc, sync_position);
1505 iter_trace
<lttv_traceset_number(ts
);
1507 LttvTrace
*trace_v
= lttv_traceset_get(ts
, iter_trace
);
1509 lttvwindowtraces_unlock(trace_v
);
1513 //set the cursor back to normal
1514 gdk_window_set_cursor(win
, NULL
);
1517 g_assert(g_slist_length(list_in
) == 0);
1519 if( g_slist_length(list_out
) == 0 ) {
1520 /* Put tab's request pending flag back to normal */
1521 tab
->events_request_pending
= FALSE
;
1522 g_debug("remove the idle fct");
1523 return FALSE
; /* Remove the idle function */
1525 g_debug("leave the idle fct");
1526 return TRUE
; /* Leave the idle function */
1528 /* We do not use simili-round-robin, it may require to read 1 meg buffers
1529 * again and again if many tracesets use the same tracefiles. */
1530 /* Hack for round-robin idle functions */
1531 /* It will put the idle function at the end of the pool */
1532 /*g_idle_add_full((G_PRIORITY_HIGH_IDLE + 21),
1533 (GSourceFunc)execute_events_requests,
1544 Manage the periodic update of a live trace
1547 live_trace_update_handler(Tab
*tab
)
1549 #ifdef BABEL_CLEANUP
1550 unsigned int updated_count
;
1551 LttvTracesetContext
*tsc
= LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
1552 TimeInterval initial_time_span
= tsc
->time_span
;
1553 TimeInterval updated_time_span
;
1555 updated_count
= lttv_process_traceset_update(tsc
);
1557 /* TODO ybrosseau 2011-01-12: Add trace resynchronization */
1559 /* Get the changed period bounds */
1560 updated_time_span
= tsc
->time_span
;
1562 if(ltt_time_compare(updated_time_span
.start_time
,
1563 initial_time_span
.start_time
) != 0) {
1564 /* The initial time should not change on a live update */
1568 /* Notify viewers (only on updates) */
1569 if(ltt_time_compare(updated_time_span
.end_time
,
1570 initial_time_span
.end_time
) != 0) {
1572 notify_time_span_changed(tab
);
1573 /* TODO ybrosseau 2011-01-12: Change the timebar to register
1574 to the time_span hook */
1575 timebar_set_minmax_time(TIMEBAR(tab
->MTimebar
),
1576 &updated_time_span
.start_time
,
1577 &updated_time_span
.end_time
);
1579 /* To update the min max */
1580 time_change_manager(tab
, tab
->time_window
);
1583 /* Timer will be recalled as long as there is files to update */
1584 return (updated_count
> 0);
1585 #endif /* BABEL_CLEANUP */
1588 static void lttvwindow_add_trace(Tab
*tab
, LttvTrace
*trace_v
)
1590 #ifdef BABEL_CLEANUP
1591 LttvTraceset
*traceset
= tab
->traceset_info
->traceset
;
1593 guint num_traces
= lttv_traceset_number(traceset
);
1595 //Verify if trace is already present.
1596 for(i
=0; i
<num_traces
; i
++)
1598 LttvTrace
* trace
= lttv_traceset_get(traceset
, i
);
1599 if(trace
== trace_v
)
1603 //Keep a reference to the traces so they are not freed.
1604 for(i
=0; i
<lttv_traceset_number(traceset
); i
++)
1606 LttvTrace
* trace
= lttv_traceset_get(traceset
, i
);
1607 lttv_trace_ref(trace
);
1610 //remove state update hooks
1611 lttv_state_remove_event_hooks(
1612 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1614 lttv_context_fini(LTTV_TRACESET_CONTEXT(
1615 tab
->traceset_info
->traceset_context
));
1616 g_object_unref(tab
->traceset_info
->traceset_context
);
1618 lttv_traceset_add(traceset
, trace_v
);
1619 lttv_trace_ref(trace_v
); /* local ref */
1621 /* Create new context */
1622 tab
->traceset_info
->traceset_context
=
1623 g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
1625 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->
1630 //add state update hooks
1631 lttv_state_add_event_hooks(
1632 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1633 //Remove local reference to the traces.
1634 for(i
=0; i
<lttv_traceset_number(traceset
); i
++)
1636 LttvTrace
* trace
= lttv_traceset_get(traceset
, i
);
1637 lttv_trace_unref(trace
);
1641 //add_trace_into_traceset_selector(GTK_MULTIVPANED(tab->multivpaned), lttv_trace(trace_v));
1644 if (lttv_trace(trace_v
)->is_live
) {
1645 /* Add timer for live update */
1646 /* TODO ybrosseau 2011-01-12: Parametrize the hardcoded 1 seconds */
1647 g_timeout_add_seconds (1,
1648 (GSourceFunc
) live_trace_update_handler
,
1651 #endif /* BABEL_CLEANUP */
1654 /* add_trace adds a trace into the current traceset. It first displays a
1655 * directory selection dialogue to let user choose a trace, then recreates
1656 * tracset_context, and redraws all the viewer of the current tab
1659 void add_trace(GtkWidget
* widget
, gpointer user_data
)
1662 LttvTraceset
* traceset
= NULL
;
1664 char abs_path
[PATH_MAX
];
1666 MainWindow
* mw_data
= get_window_data_struct(widget
);
1667 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
1669 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
1670 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
1671 LttvPluginTab
*ptab
;
1675 ptab
= create_new_tab(widget
, NULL
);
1678 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
1682 /* Create a new traceset*/
1683 traceset
= tab
->traceset_info
->traceset
;
1684 if(traceset
== NULL
) {
1685 traceset
= lttv_traceset_new();
1687 /* File open dialog management */
1688 #ifdef BABEL_CLEANUP
1689 GtkWidget
*extra_live_button
;
1690 #endif //babel_cleanup
1691 GtkFileChooser
* file_chooser
=
1693 gtk_file_chooser_dialog_new ("Select a trace",
1694 GTK_WINDOW(mw_data
->mwindow
),
1695 GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER
,
1696 GTK_STOCK_CANCEL
, GTK_RESPONSE_CANCEL
,
1697 GTK_STOCK_OPEN
, GTK_RESPONSE_ACCEPT
,
1699 #ifdef BABEL_CLEANUP
1700 /* Button to indicate the opening of a live trace */
1701 extra_live_button
= gtk_check_button_new_with_mnemonic ("Trace is live (currently being writen)");
1702 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (extra_live_button
), FALSE
);
1703 gtk_file_chooser_set_extra_widget (GTK_FILE_CHOOSER (file_chooser
), extra_live_button
);
1704 #endif //babel_cleanup
1705 gtk_file_chooser_set_show_hidden (file_chooser
, TRUE
);
1706 if(remember_trace_dir
[0] != '\0')
1707 gtk_file_chooser_set_filename(file_chooser
, remember_trace_dir
);
1709 gboolean closeFileChooserDialog
= TRUE
;
1713 id
= gtk_dialog_run(GTK_DIALOG(file_chooser
));
1715 case GTK_RESPONSE_ACCEPT
:
1716 case GTK_RESPONSE_OK
:
1717 path
= gtk_file_chooser_get_filename (file_chooser
);
1719 strncpy(remember_trace_dir
, path
, PATH_MAX
);
1720 strncat(remember_trace_dir
, "/", PATH_MAX
);
1721 if(!path
|| strlen(path
) == 0){
1724 get_absolute_pathname(path
, abs_path
);
1726 if(lttv_traceset_add_path(traceset
,abs_path
) != 0 ){ /*failure*/
1728 g_warning("cannot open trace %s", abs_path
);
1729 strncpy(remember_trace_dir
, "\0", PATH_MAX
);
1730 GtkWidget
*dialogue
=
1731 gtk_message_dialog_new(
1732 GTK_WINDOW(gtk_widget_get_toplevel(widget
)),
1733 GTK_DIALOG_MODAL
|GTK_DIALOG_DESTROY_WITH_PARENT
,
1736 "Cannot open trace : maybe you should enter in the directory "
1738 gtk_dialog_run(GTK_DIALOG(dialogue
));
1739 gtk_widget_destroy(dialogue
);
1740 closeFileChooserDialog
= FALSE
;
1743 closeFileChooserDialog
= TRUE
;
1744 SetTraceset(tab
, traceset
);
1747 //update current tab
1748 //update_traceset(mw_data);
1750 // in expose now call_pending_read_hooks(mw_data);
1752 //lttvwindow_report_current_time(mw_data,&(tab->current_time));
1754 case GTK_RESPONSE_REJECT
:
1755 case GTK_RESPONSE_CANCEL
:
1757 closeFileChooserDialog
= TRUE
;
1760 }while(!closeFileChooserDialog
);
1762 gtk_widget_destroy((GtkWidget
*)file_chooser
);
1766 /* remove_trace removes a trace from the current traceset if all viewers in
1767 * the current tab are not interested in the trace. It first displays a
1768 * dialogue, which shows all traces in the current traceset, to let user choose
1769 * a trace, then it checks if all viewers unselect the trace, if it is true,
1770 * it will remove the trace, recreate the traceset_contex,
1771 * and redraws all the viewer of the current tab. If there is on trace in the
1772 * current traceset, it will delete all viewers of the current tab
1774 * It destroys the filter tree. FIXME... we should request for an update
1778 void remove_trace(GtkWidget
*widget
, gpointer user_data
)
1780 #ifdef BABEL_CLEANUP
1782 LttvTrace
* trace_v
;
1783 LttvTraceset
* traceset
;
1784 gint i
, j
, nb_trace
, index
=-1;
1785 char ** name
, *remove_trace_name
;
1786 MainWindow
* mw_data
= get_window_data_struct(widget
);
1787 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
1789 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
1790 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
1796 LttvPluginTab
*ptab
;
1797 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
1801 nb_trace
=lttv_traceset_number(tab
->traceset_info
->traceset
);
1802 name
= g_new(char*,nb_trace
);
1803 for(i
= 0; i
< nb_trace
; i
++){
1804 trace_v
= lttv_traceset_get(tab
->traceset_info
->traceset
, i
);
1805 trace
= lttv_trace(trace_v
);
1806 name
[i
] = (char *) g_quark_to_string(ltt_trace_name(trace
));
1809 remove_trace_name
= get_remove_trace(mw_data
, name
, nb_trace
);
1812 if(remove_trace_name
){
1814 /* yuk, cut n paste from old code.. should be better (MD)*/
1815 for(i
= 0; i
<nb_trace
; i
++) {
1816 if(strcmp(remove_trace_name
,name
[i
]) == 0){
1821 traceset
= tab
->traceset_info
->traceset
;
1822 //Keep a reference to the traces so they are not freed.
1823 for(j
=0; j
<lttv_traceset_number(traceset
); j
++)
1825 LttvTrace
* trace
= lttv_traceset_get(traceset
, j
);
1826 lttv_trace_ref(trace
);
1829 //remove state update hooks
1830 lttv_state_remove_event_hooks(
1831 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1832 lttv_context_fini(LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
));
1833 g_object_unref(tab
->traceset_info
->traceset_context
);
1835 trace_v
= lttv_traceset_get(traceset
, index
);
1837 lttv_traceset_remove(traceset
, index
);
1838 lttv_trace_unref(trace_v
); // Remove local reference
1840 if(lttv_trace_get_ref_number(trace_v
) <= 1) {
1841 /* ref 1 : lttvwindowtraces only*/
1842 ltt_trace_close(lttv_trace(trace_v
));
1843 /* lttvwindowtraces_remove_trace takes care of destroying
1844 * the traceset linked with the trace_v and also of destroying
1845 * the trace_v at the same time.
1847 lttvwindowtraces_remove_trace(trace_v
);
1850 tab
->traceset_info
->traceset_context
=
1851 g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
1853 LTTV_TRACESET_CONTEXT(tab
->
1854 traceset_info
->traceset_context
),traceset
);
1855 //add state update hooks
1856 lttv_state_add_event_hooks(
1857 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1859 //Remove local reference to the traces.
1860 for(j
=0; j
<lttv_traceset_number(traceset
); j
++)
1862 LttvTrace
* trace
= lttv_traceset_get(traceset
, j
);
1863 lttv_trace_unref(trace
);
1866 SetTraceset(tab
, (gpointer
)traceset
);
1869 #endif /* BABEL_CLEANUP */
1873 void remove_trace(GtkWidget
* widget
, gpointer user_data
)
1876 LttvTrace
* trace_v
;
1877 LttvTraceset
* traceset
;
1878 gint i
, j
, nb_trace
;
1879 char ** name
, *remove_trace_name
;
1880 MainWindow
* mw_data
= get_window_data_struct(widget
);
1881 LttvTracesetSelector
* s
;
1882 LttvTraceSelector
* t
;
1885 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
1887 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
1888 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
1894 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
1897 nb_trace
=lttv_traceset_number(tab
->traceset_info
->traceset
);
1898 name
= g_new(char*,nb_trace
);
1899 for(i
= 0; i
< nb_trace
; i
++){
1900 trace_v
= lttv_traceset_get(tab
->traceset_info
->traceset
, i
);
1901 trace
= lttv_trace(trace_v
);
1902 name
[i
] = ltt_trace_name(trace
);
1905 remove_trace_name
= get_remove_trace(name
, nb_trace
);
1907 if(remove_trace_name
){
1908 for(i
=0; i
<nb_trace
; i
++){
1909 if(strcmp(remove_trace_name
,name
[i
]) == 0){
1910 //unselect the trace from the current viewer
1912 w
= gtk_multivpaned_get_widget(GTK_MULTIVPANED(tab
->multivpaned
));
1914 s
= g_object_get_data(G_OBJECT(w
), "Traceset_Selector");
1916 t
= lttv_traceset_selector_trace_get(s
,i
);
1917 lttv_trace_selector_set_selected(t
, FALSE
);
1920 //check if other viewers select the trace
1921 w
= gtk_multivpaned_get_first_widget(GTK_MULTIVPANED(tab
->multivpaned
));
1923 s
= g_object_get_data(G_OBJECT(w
), "Traceset_Selector");
1925 t
= lttv_traceset_selector_trace_get(s
,i
);
1926 selected
= lttv_trace_selector_get_selected(t
);
1929 w
= gtk_multivpaned_get_next_widget(GTK_MULTIVPANED(tab
->multivpaned
));
1931 }else selected
= FALSE
;
1933 //if no viewer selects the trace, remove it
1935 remove_trace_from_traceset_selector(GTK_MULTIVPANED(tab
->multivpaned
), i
);
1937 traceset
= tab
->traceset_info
->traceset
;
1938 //Keep a reference to the traces so they are not freed.
1939 for(j
=0; j
<lttv_traceset_number(traceset
); j
++)
1941 LttvTrace
* trace
= lttv_traceset_get(traceset
, j
);
1942 lttv_trace_ref(trace
);
1945 //remove state update hooks
1946 lttv_state_remove_event_hooks(
1947 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1948 lttv_context_fini(LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
));
1949 g_object_unref(tab
->traceset_info
->traceset_context
);
1952 trace_v
= lttv_traceset_get(traceset
, i
);
1954 if(lttv_trace_get_ref_number(trace_v
) <= 2) {
1955 /* ref 2 : traceset, local */
1956 lttvwindowtraces_remove_trace(trace_v
);
1957 ltt_trace_close(lttv_trace(trace_v
));
1960 lttv_traceset_remove(traceset
, i
);
1961 lttv_trace_unref(trace_v
); // Remove local reference
1963 if(!lttv_trace_get_ref_number(trace_v
))
1964 lttv_trace_destroy(trace_v
);
1966 tab
->traceset_info
->traceset_context
=
1967 g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
1969 LTTV_TRACESET_CONTEXT(tab
->
1970 traceset_info
->traceset_context
),traceset
);
1971 //add state update hooks
1972 lttv_state_add_event_hooks(
1973 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1975 //Remove local reference to the traces.
1976 for(j
=0; j
<lttv_traceset_number(traceset
); j
++)
1978 LttvTrace
* trace
= lttv_traceset_get(traceset
, j
);
1979 lttv_trace_unref(trace
);
1983 //update current tab
1984 //update_traceset(mw_data);
1987 SetTraceset(tab
, (gpointer
)traceset
);
1988 // in expose now call_pending_read_hooks(mw_data);
1990 //lttvwindow_report_current_time(mw_data,&(tab->current_time));
1993 // while(tab->multi_vpaned->num_children){
1994 // gtk_multi_vpaned_widget_delete(tab->multi_vpaned);
2008 /* Redraw all the viewers in the current tab */
2009 void redraw(GtkWidget
*widget
, gpointer user_data
)
2011 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
2012 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2013 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2020 LttvPluginTab
*ptab
;
2021 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
2026 LttvAttributeValue value
;
2028 retval
= lttv_iattribute_find_by_path(tab
->attributes
, "hooks/redraw", LTTV_POINTER
, &value
);
2031 tmp
= (LttvHooks
*)*(value
.v_pointer
);
2033 lttv_hooks_call(tmp
,NULL
);
2037 void continue_processing(GtkWidget
*widget
, gpointer user_data
)
2039 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
2040 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2041 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2048 LttvPluginTab
*ptab
;
2049 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
2054 LttvAttributeValue value
;
2056 retval
= lttv_iattribute_find_by_path(tab
->attributes
, "hooks/continue",
2057 LTTV_POINTER
, &value
);
2060 tmp
= (LttvHooks
*)*(value
.v_pointer
);
2062 lttv_hooks_call(tmp
,NULL
);
2065 /* Stop the processing for the calling main window's current tab.
2066 * It removes every processing requests that are in its list. It does not call
2067 * the end request hooks, because the request is not finished.
2070 void stop_processing(GtkWidget
*widget
, gpointer user_data
)
2072 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
2073 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2074 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2079 LttvPluginTab
*ptab
;
2080 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
2083 GSList
*iter
= tab
->events_requests
;
2085 while(iter
!= NULL
) {
2086 GSList
*remove_iter
= iter
;
2087 iter
= g_slist_next(iter
);
2089 g_free(remove_iter
->data
);
2090 tab
->events_requests
=
2091 g_slist_remove_link(tab
->events_requests
, remove_iter
);
2093 tab
->events_request_pending
= FALSE
;
2094 tab
->stop_foreground
= TRUE
;
2095 g_idle_remove_by_data(tab
);
2096 g_assert(g_slist_length(tab
->events_requests
) == 0);
2100 /* save will save the traceset to a file
2101 * Not implemented yet FIXME
2104 void save(GtkWidget
* widget
, gpointer user_data
)
2109 void save_as(GtkWidget
* widget
, gpointer user_data
)
2111 g_info("Save as\n");
2115 /* zoom will change the time_window of all the viewers of the
2116 * current tab, and redisplay them. The main functionality is to
2117 * determine the new time_window of the current tab
2120 void zoom(GtkWidget
* widget
, double size
)
2123 TimeInterval time_span
;
2124 TimeWindow new_time_window
;
2125 LttTime current_time
, time_delta
;
2127 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
2129 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2130 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2136 LttvPluginTab
*ptab
;
2137 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
2141 if(size
== 1) return;
2143 ts
= lttvwindow_get_traceset(tab
);
2144 time_span
= lttv_traceset_get_time_span_real(ts
);
2145 new_time_window
= tab
->time_window
;
2146 current_time
= tab
->current_time
;
2148 time_delta
= ltt_time_sub(time_span
.end_time
,time_span
.start_time
);
2150 new_time_window
.start_time
= time_span
.start_time
;
2151 new_time_window
.time_width
= time_delta
;
2152 new_time_window
.time_width_double
= ltt_time_to_double(time_delta
);
2153 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
2154 new_time_window
.time_width
) ;
2156 new_time_window
.time_width
= ltt_time_div(new_time_window
.time_width
, size
);
2157 new_time_window
.time_width_double
=
2158 ltt_time_to_double(new_time_window
.time_width
);
2159 if(ltt_time_compare(new_time_window
.time_width
,time_delta
) > 0)
2160 { /* Case where zoom out is bigger than trace length */
2161 new_time_window
.start_time
= time_span
.start_time
;
2162 new_time_window
.time_width
= time_delta
;
2163 new_time_window
.time_width_double
= ltt_time_to_double(time_delta
);
2164 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
2165 new_time_window
.time_width
) ;
2169 /* Center the image on the current time */
2170 new_time_window
.start_time
=
2171 ltt_time_sub(current_time
,
2172 ltt_time_from_double(new_time_window
.time_width_double
/2.0));
2173 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
2174 new_time_window
.time_width
) ;
2175 /* If on borders, don't fall off */
2176 if(ltt_time_compare(new_time_window
.start_time
, time_span
.start_time
) <0
2177 || ltt_time_compare(new_time_window
.start_time
, time_span
.end_time
) >0)
2179 new_time_window
.start_time
= time_span
.start_time
;
2180 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
2181 new_time_window
.time_width
) ;
2185 if(ltt_time_compare(new_time_window
.end_time
,
2186 time_span
.end_time
) > 0
2187 || ltt_time_compare(new_time_window
.end_time
,
2188 time_span
.start_time
) < 0)
2190 new_time_window
.start_time
=
2191 ltt_time_sub(time_span
.end_time
, new_time_window
.time_width
);
2193 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
2194 new_time_window
.time_width
) ;
2201 if(ltt_time_compare(new_time_window
.time_width
, ltt_time_zero
) == 0) {
2202 g_warning("Zoom more than 1 ns impossible");
2204 time_change_manager(tab
, new_time_window
);
2208 void zoom_in(GtkWidget
* widget
, gpointer user_data
)
2213 void zoom_out(GtkWidget
* widget
, gpointer user_data
)
2218 void zoom_extended(GtkWidget
* widget
, gpointer user_data
)
2223 void go_to_time(GtkWidget
* widget
, gpointer user_data
)
2225 g_info("Go to time\n");
2228 void show_time_frame(GtkWidget
* widget
, gpointer user_data
)
2230 g_info("Show time frame\n");
2234 /* callback function */
2237 on_empty_traceset_activate (GtkMenuItem
*menuitem
,
2240 create_new_window((GtkWidget
*)menuitem
, user_data
, FALSE
);
2245 on_clone_traceset_activate (GtkMenuItem
*menuitem
,
2248 create_new_window((GtkWidget
*)menuitem
, user_data
, TRUE
);
2252 /* create_new_tab calls create_tab to construct a new tab in the main window
2255 LttvPluginTab
*create_new_tab(GtkWidget
* widget
, gpointer user_data
)
2257 gchar label
[PATH_MAX
];
2258 MainWindow
* mw_data
= get_window_data_struct(widget
);
2260 GtkNotebook
* notebook
= (GtkNotebook
*)lookup_widget(widget
, "MNotebook");
2261 if(notebook
== NULL
){
2262 g_info("Notebook does not exist\n");
2265 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2266 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2269 if(!page
|| TRUE
) {
2272 LttvPluginTab
*ptab
;
2273 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
2274 copy_tab
= ptab
->tab
;
2277 strcpy(label
,"Page");
2278 if(get_label(mw_data
, label
,"Get the name of the tab","Please input tab's name")) {
2279 LttvPluginTab
*ptab
;
2281 ptab
= g_object_new(LTTV_TYPE_PLUGIN_TAB
, NULL
);
2282 init_tab (ptab
->tab
, mw_data
, copy_tab
, notebook
, label
);
2283 ptab
->parent
.top_widget
= ptab
->tab
->top_widget
;
2284 g_object_set_data_full(
2285 G_OBJECT(ptab
->tab
->vbox
),
2288 (GDestroyNotify
)tab_destructor
);
2295 on_tab_activate (GtkMenuItem
*menuitem
,
2298 create_new_tab((GtkWidget
*)menuitem
, user_data
);
2303 on_open_activate (GtkMenuItem
*menuitem
,
2306 #ifdef UNFINISHED_FEATURE
2307 open_traceset((GtkWidget
*)menuitem
, user_data
);
2313 on_close_activate (GtkMenuItem
*menuitem
,
2316 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2317 main_window_destructor(mw_data
);
2321 /* remove the current tab from the main window
2325 on_close_tab_activate (GtkWidget
*widget
,
2329 GtkWidget
* notebook
;
2330 notebook
= lookup_widget(widget
, "MNotebook");
2331 if(notebook
== NULL
){
2332 g_info("Notebook does not exist\n");
2336 page_num
= gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
));
2338 gtk_notebook_remove_page(GTK_NOTEBOOK(notebook
), page_num
);
2343 on_close_tab_X_clicked (GtkWidget
*widget
,
2347 GtkWidget
*notebook
= lookup_widget(widget
, "MNotebook");
2348 if(notebook
== NULL
){
2349 g_info("Notebook does not exist\n");
2353 if((page_num
= gtk_notebook_page_num(GTK_NOTEBOOK(notebook
), widget
)) != -1)
2354 gtk_notebook_remove_page(GTK_NOTEBOOK(notebook
), page_num
);
2360 on_add_trace_activate (GtkMenuItem
*menuitem
,
2363 add_trace((GtkWidget
*)menuitem
, user_data
);
2368 on_remove_trace_activate (GtkMenuItem
*menuitem
,
2371 remove_trace((GtkWidget
*)menuitem
, user_data
);
2376 on_save_activate (GtkMenuItem
*menuitem
,
2379 save((GtkWidget
*)menuitem
, user_data
);
2384 on_save_as_activate (GtkMenuItem
*menuitem
,
2387 save_as((GtkWidget
*)menuitem
, user_data
);
2392 on_quit_activate (GtkMenuItem
*menuitem
,
2395 while (g_slist_length(g_main_window_list
) != 0) {
2396 on_MWindow_destroy(((MainWindow
*)g_main_window_list
->data
)->mwindow
,
2403 on_cut_activate (GtkMenuItem
*menuitem
,
2411 on_copy_activate (GtkMenuItem
*menuitem
,
2419 on_paste_activate (GtkMenuItem
*menuitem
,
2427 on_delete_activate (GtkMenuItem
*menuitem
,
2435 on_zoom_in_activate (GtkMenuItem
*menuitem
,
2438 zoom_in((GtkWidget
*)menuitem
, user_data
);
2443 on_zoom_out_activate (GtkMenuItem
*menuitem
,
2446 zoom_out((GtkWidget
*)menuitem
, user_data
);
2451 on_zoom_extended_activate (GtkMenuItem
*menuitem
,
2454 zoom_extended((GtkWidget
*)menuitem
, user_data
);
2459 on_go_to_time_activate (GtkMenuItem
*menuitem
,
2462 go_to_time((GtkWidget
*)menuitem
, user_data
);
2467 on_show_time_frame_activate (GtkMenuItem
*menuitem
,
2470 show_time_frame((GtkWidget
*)menuitem
, user_data
);
2475 on_move_viewer_up_activate (GtkMenuItem
*menuitem
,
2478 move_up_viewer((GtkWidget
*)menuitem
, user_data
);
2483 on_move_viewer_down_activate (GtkMenuItem
*menuitem
,
2486 move_down_viewer((GtkWidget
*)menuitem
, user_data
);
2491 on_remove_viewer_activate (GtkMenuItem
*menuitem
,
2494 delete_viewer((GtkWidget
*)menuitem
, user_data
);
2498 on_trace_facility_activate (GtkMenuItem
*menuitem
,
2501 g_info("Trace facility selector: %s\n", "");
2505 /* Dispaly a file selection dialogue to let user select a library, then call
2506 * lttv_library_load().
2510 on_load_library_activate (GtkMenuItem
*menuitem
,
2513 GError
*error
= NULL
;
2514 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2516 gchar load_module_path_alter
[PATH_MAX
];
2520 gchar
*load_module_path
;
2521 name
= g_ptr_array_new();
2522 nb
= lttv_library_path_number();
2523 /* ask for the library path */
2527 path
= lttv_library_path_get(i
);
2528 g_ptr_array_add(name
, path
);
2531 load_module_path
= get_selection(mw_data
,
2532 (char **)(name
->pdata
), name
->len
,
2533 "Select a library path", "Library paths");
2534 if(load_module_path
!= NULL
)
2535 strncpy(load_module_path_alter
, load_module_path
, PATH_MAX
-1); // -1 for /
2537 g_ptr_array_free(name
, TRUE
);
2539 if(load_module_path
== NULL
) return;
2543 /* Make sure the module path ends with a / */
2544 gchar
*ptr
= load_module_path_alter
;
2546 ptr
= strchr(ptr
, '\0');
2548 if(*(ptr
-1) != '/') {
2555 /* Ask for the library to load : list files in the previously selected
2557 gchar str
[PATH_MAX
];
2560 GtkFileSelection
* file_selector
=
2561 (GtkFileSelection
*)gtk_file_selection_new("Select a module");
2562 gtk_file_selection_set_filename(file_selector
, load_module_path_alter
);
2563 gtk_file_selection_hide_fileop_buttons(file_selector
);
2565 gtk_window_set_transient_for(GTK_WINDOW(file_selector
),
2566 GTK_WINDOW(mw_data
->mwindow
));
2569 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
2571 case GTK_RESPONSE_ACCEPT
:
2572 case GTK_RESPONSE_OK
:
2573 dir
= gtk_file_selection_get_selections (file_selector
);
2574 strncpy(str
,dir
[0],PATH_MAX
);
2575 strncpy(remember_plugins_dir
,dir
[0],PATH_MAX
);
2576 /* only keep file name */
2578 str1
= strrchr(str
,'/');
2581 str1
= strrchr(str
,'\\');
2586 if(*str1
== 'l' && *(str1
+1)== 'i' && *(str1
+2)=='b')
2588 remove info after
. */
2592 str2
= strrchr(str2
, '.');
2593 if(str2
!= NULL
) *str2
= '\0';
2595 lttv_module_require(str1
, &error
);
2597 lttv_library_load(str1
, &error
);
2598 if(error
!= NULL
) g_warning("%s", error
->message
);
2599 else g_info("Load library: %s\n", str
);
2601 case GTK_RESPONSE_REJECT
:
2602 case GTK_RESPONSE_CANCEL
:
2604 gtk_widget_destroy((GtkWidget
*)file_selector
);
2615 /* Display all loaded modules, let user to select a module to unload
2616 * by calling lttv_module_unload
2620 on_unload_library_activate (GtkMenuItem
*menuitem
,
2623 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2625 LttvLibrary
*library
= NULL
;
2630 name
= g_ptr_array_new();
2631 nb
= lttv_library_number();
2632 LttvLibraryInfo
*lib_info
= g_new(LttvLibraryInfo
,nb
);
2633 /* ask for the library name */
2636 LttvLibrary
*iter_lib
= lttv_library_get(i
);
2637 lttv_library_info(iter_lib
, &lib_info
[i
]);
2639 gchar
*path
= lib_info
[i
].name
;
2640 g_ptr_array_add(name
, path
);
2642 lib_name
= get_selection(mw_data
, (char **)(name
->pdata
), name
->len
,
2643 "Select a library", "Libraries");
2644 if(lib_name
!= NULL
) {
2646 if(strcmp(lib_name
, lib_info
[i
].name
) == 0) {
2647 library
= lttv_library_get(i
);
2652 g_ptr_array_free(name
, TRUE
);
2655 if(lib_name
== NULL
) return;
2657 if(library
!= NULL
) lttv_library_unload(library
);
2661 /* Dispaly a file selection dialogue to let user select a module, then call
2662 * lttv_module_require().
2666 on_load_module_activate (GtkMenuItem
*menuitem
,
2669 GError
*error
= NULL
;
2670 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2672 LttvLibrary
*library
= NULL
;
2677 name
= g_ptr_array_new();
2678 nb
= lttv_library_number();
2679 LttvLibraryInfo
*lib_info
= g_new(LttvLibraryInfo
,nb
);
2680 /* ask for the library name */
2683 LttvLibrary
*iter_lib
= lttv_library_get(i
);
2684 lttv_library_info(iter_lib
, &lib_info
[i
]);
2686 gchar
*path
= lib_info
[i
].name
;
2687 g_ptr_array_add(name
, path
);
2689 lib_name
= get_selection(mw_data
,(char **)(name
->pdata
), name
->len
,
2690 "Select a library", "Libraries");
2691 if(lib_name
!= NULL
) {
2693 if(strcmp(lib_name
, lib_info
[i
].name
) == 0) {
2694 library
= lttv_library_get(i
);
2699 g_ptr_array_free(name
, TRUE
);
2702 if(lib_name
== NULL
) return;
2705 //LttvModule *module;
2706 gchar module_name_out
[PATH_MAX
];
2708 /* Ask for the module to load : list modules in the selected lib */
2712 nb
= lttv_library_module_number(library
);
2713 LttvModuleInfo
*module_info
= g_new(LttvModuleInfo
,nb
);
2714 name
= g_ptr_array_new();
2715 /* ask for the module name */
2718 LttvModule
*iter_module
= lttv_library_module_get(library
, i
);
2719 lttv_module_info(iter_module
, &module_info
[i
]);
2721 gchar
*path
= module_info
[i
].name
;
2722 g_ptr_array_add(name
, path
);
2724 module_name
= get_selection(mw_data
, (char **)(name
->pdata
), name
->len
,
2725 "Select a module", "Modules");
2726 if(module_name
!= NULL
) {
2728 if(strcmp(module_name
, module_info
[i
].name
) == 0) {
2729 strncpy(module_name_out
, module_name
, PATH_MAX
);
2730 //module = lttv_library_module_get(i);
2736 g_ptr_array_free(name
, TRUE
);
2737 g_free(module_info
);
2739 if(module_name
== NULL
) return;
2742 lttv_module_require(module_name_out
, &error
);
2743 if(error
!= NULL
) g_warning("%s", error
->message
);
2744 else g_info("Load module: %s", module_name_out
);
2751 gchar str
[PATH_MAX
];
2754 GtkFileSelection
* file_selector
=
2755 (GtkFileSelection
*)gtk_file_selection_new("Select a module");
2756 gtk_file_selection_set_filename(file_selector
, load_module_path_alter
);
2757 gtk_file_selection_hide_fileop_buttons(file_selector
);
2760 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
2762 case GTK_RESPONSE_ACCEPT
:
2763 case GTK_RESPONSE_OK
:
2764 dir
= gtk_file_selection_get_selections (file_selector
);
2765 strncpy(str
,dir
[0],PATH_MAX
);
2766 strncpy(remember_plugins_dir
,dir
[0],PATH_MAX
);
2768 /* only keep file name */
2770 str1
= strrchr(str
,'/');
2773 str1
= strrchr(str
,'\\');
2778 if(*str1
== 'l' && *(str1
+1)== 'i' && *(str1
+2)=='b')
2780 remove info after
. */
2784 str2
= strrchr(str2
, '.');
2785 if(str2
!= NULL
) *str2
= '\0';
2787 lttv_module_require(str1
, &error
);
2789 lttv_library_load(str1
, &error
);
2790 if(error
!= NULL
) g_warning(error
->message
);
2791 else g_info("Load library: %s\n", str
);
2793 case GTK_RESPONSE_REJECT
:
2794 case GTK_RESPONSE_CANCEL
:
2796 gtk_widget_destroy((GtkWidget
*)file_selector
);
2808 /* Display all loaded modules, let user to select a module to unload
2809 * by calling lttv_module_unload
2813 on_unload_module_activate (GtkMenuItem
*menuitem
,
2816 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2818 LttvLibrary
*library
= NULL
;
2823 name
= g_ptr_array_new();
2824 nb
= lttv_library_number();
2825 LttvLibraryInfo
*lib_info
= g_new(LttvLibraryInfo
,nb
);
2826 /* ask for the library name */
2829 LttvLibrary
*iter_lib
= lttv_library_get(i
);
2830 lttv_library_info(iter_lib
, &lib_info
[i
]);
2832 gchar
*path
= lib_info
[i
].name
;
2833 g_ptr_array_add(name
, path
);
2835 lib_name
= get_selection(mw_data
, (char **)(name
->pdata
), name
->len
,
2836 "Select a library", "Libraries");
2837 if(lib_name
!= NULL
) {
2839 if(strcmp(lib_name
, lib_info
[i
].name
) == 0) {
2840 library
= lttv_library_get(i
);
2845 g_ptr_array_free(name
, TRUE
);
2848 if(lib_name
== NULL
) return;
2851 LttvModule
*module
= NULL
;
2853 /* Ask for the module to load : list modules in the selected lib */
2857 nb
= lttv_library_module_number(library
);
2858 LttvModuleInfo
*module_info
= g_new(LttvModuleInfo
,nb
);
2859 name
= g_ptr_array_new();
2860 /* ask for the module name */
2863 LttvModule
*iter_module
= lttv_library_module_get(library
, i
);
2864 lttv_module_info(iter_module
, &module_info
[i
]);
2866 gchar
*path
= module_info
[i
].name
;
2867 if(module_info
[i
].use_count
> 0) g_ptr_array_add(name
, path
);
2869 module_name
= get_selection(mw_data
, (char **)(name
->pdata
), name
->len
,
2870 "Select a module", "Modules");
2871 if(module_name
!= NULL
) {
2873 if(strcmp(module_name
, module_info
[i
].name
) == 0) {
2874 module
= lttv_library_module_get(library
, i
);
2880 g_ptr_array_free(name
, TRUE
);
2881 g_free(module_info
);
2883 if(module_name
== NULL
) return;
2886 LttvModuleInfo module_info
;
2887 lttv_module_info(module
, &module_info
);
2888 g_info("Release module: %s\n", module_info
.name
);
2890 lttv_module_release(module
);
2894 /* Display a directory dialogue to let user select a path for library searching
2898 on_add_library_search_path_activate (GtkMenuItem
*menuitem
,
2901 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2902 //GtkDirSelection * file_selector = (GtkDirSelection *)gtk_dir_selection_new("Select library path");
2903 GtkFileSelection
* file_selector
= (GtkFileSelection
*)gtk_file_selection_new("Select a trace");
2904 gtk_widget_hide( (file_selector
)->file_list
->parent
) ;
2906 gtk_window_set_transient_for(GTK_WINDOW(file_selector
),
2907 GTK_WINDOW(mw_data
->mwindow
));
2912 if(remember_plugins_dir
[0] != '\0')
2913 gtk_file_selection_set_filename(file_selector
, remember_plugins_dir
);
2915 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
2917 case GTK_RESPONSE_ACCEPT
:
2918 case GTK_RESPONSE_OK
:
2919 dir
= gtk_file_selection_get_filename (file_selector
);
2920 strncpy(remember_plugins_dir
,dir
,PATH_MAX
);
2921 strncat(remember_plugins_dir
,"/",PATH_MAX
);
2922 lttv_library_path_add(dir
);
2923 case GTK_RESPONSE_REJECT
:
2924 case GTK_RESPONSE_CANCEL
:
2926 gtk_widget_destroy((GtkWidget
*)file_selector
);
2932 /* Display a directory dialogue to let user select a path for library searching
2936 on_remove_library_search_path_activate (GtkMenuItem
*menuitem
,
2939 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2941 const char *lib_path
;
2945 name
= g_ptr_array_new();
2946 nb
= lttv_library_path_number();
2947 /* ask for the library name */
2950 gchar
*path
= lttv_library_path_get(i
);
2951 g_ptr_array_add(name
, path
);
2953 lib_path
= get_selection(mw_data
, (char **)(name
->pdata
), name
->len
,
2954 "Select a library path", "Library paths");
2956 g_ptr_array_free(name
, TRUE
);
2958 if(lib_path
== NULL
) return;
2961 lttv_library_path_remove(lib_path
);
2965 on_color_activate (GtkMenuItem
*menuitem
,
2973 on_save_configuration_activate (GtkMenuItem
*menuitem
,
2976 g_info("Save configuration\n");
2981 on_content_activate (GtkMenuItem
*menuitem
,
2984 char* filename
= NULL
,
2987 const char* relativePath
= "doc/user/user_guide/html/index.html";
2988 filename
= g_build_filename (g_get_current_dir(), relativePath
, NULL
);
2989 path
= g_strdup_printf ("ghelp://%s", filename
);
2991 screen
= gdk_screen_get_default();
2992 gtk_show_uri (screen
, path
, gtk_get_current_event_time(), NULL
);
2996 g_info("Content\n");
3001 on_about_close_activate (GtkButton
*button
,
3004 GtkWidget
*about_widget
= GTK_WIDGET(user_data
);
3006 gtk_widget_destroy(about_widget
);
3010 on_about_activate (GtkMenuItem
*menuitem
,
3013 MainWindow
*main_window
= get_window_data_struct(GTK_WIDGET(menuitem
));
3014 GtkWidget
*window_widget
= main_window
->mwindow
;
3015 GtkWidget
*about_widget
= gtk_window_new(GTK_WINDOW_TOPLEVEL
);
3016 GtkWindow
*about_window
= GTK_WINDOW(about_widget
);
3018 gtk_window_set_title(about_window
, "About Linux Trace Toolkit");
3020 gtk_window_set_resizable(about_window
, FALSE
);
3021 gtk_window_set_transient_for(about_window
, GTK_WINDOW(window_widget
));
3022 gtk_window_set_destroy_with_parent(about_window
, TRUE
);
3023 gtk_window_set_modal(about_window
, FALSE
);
3025 /* Put the about window at the center of the screen */
3026 gtk_window_set_position(about_window
, GTK_WIN_POS_CENTER_ALWAYS
);
3028 GtkWidget
*vbox
= gtk_vbox_new(FALSE
, 1);
3030 gtk_container_add(GTK_CONTAINER(about_widget
), vbox
);
3033 GtkWidget
*label1
= gtk_label_new("");
3034 gtk_misc_set_padding(GTK_MISC(label1
), 10, 20);
3035 gtk_label_set_markup(GTK_LABEL(label1
), "\
3036 <big>Linux Trace Toolkit " VERSION
"</big>");
3037 gtk_label_set_justify(GTK_LABEL(label1
), GTK_JUSTIFY_CENTER
);
3039 GtkWidget
*label2
= gtk_label_new("");
3040 gtk_misc_set_padding(GTK_MISC(label2
), 10, 20);
3041 gtk_label_set_markup(GTK_LABEL(label2
), "\
3044 Michel Dagenais (New trace format, lttv main)\n\
3045 Mathieu Desnoyers (Kernel Tracer, Directory structure, build with automake/conf,\n\
3046 lttv gui, control flow view, gui cooperative trace reading\n\
3047 scheduler with interruptible foreground and background\n\
3048 computation, detailed event list (rewrite), trace reading\n\
3049 library (rewrite))\n\
3050 Benoit Des Ligneris, Eric Clement (Cluster adaptation, work in progress)\n\
3051 Xang-Xiu Yang (new trace reading library and converter, lttv gui, \n\
3052 detailed event list and statistics view)\n\
3053 Tom Zanussi (RelayFS)\n\
3055 Inspired from the original Linux Trace Toolkit Visualizer made by\n\
3058 GtkWidget
*label3
= gtk_label_new("");
3059 gtk_label_set_markup(GTK_LABEL(label3
), "\
3060 Linux Trace Toolkit Viewer, Copyright (C) 2004, 2005, 2006\n\
3062 Mathieu Desnoyers\n\
3064 Linux Trace Toolkit comes with ABSOLUTELY NO WARRANTY.\n\
3065 This is free software, and you are welcome to redistribute it\n\
3066 under certain conditions. See COPYING for details.");
3067 gtk_misc_set_padding(GTK_MISC(label3
), 10, 20);
3069 gtk_box_pack_start_defaults(GTK_BOX(vbox
), label1
);
3070 gtk_box_pack_start_defaults(GTK_BOX(vbox
), label2
);
3071 gtk_box_pack_start_defaults(GTK_BOX(vbox
), label3
);
3073 GtkWidget
*hbox
= gtk_hbox_new(TRUE
, 0);
3074 gtk_box_pack_end(GTK_BOX(vbox
), hbox
, FALSE
, FALSE
, 0);
3075 GtkWidget
*close_button
= gtk_button_new_with_mnemonic("_Close");
3076 gtk_box_pack_end(GTK_BOX(hbox
), close_button
, FALSE
, FALSE
, 0);
3077 gtk_container_set_border_width(GTK_CONTAINER(close_button
), 20);
3079 g_signal_connect(G_OBJECT(close_button
), "clicked",
3080 G_CALLBACK(on_about_close_activate
),
3081 (gpointer
)about_widget
);
3083 gtk_widget_show_all(about_widget
);
3088 on_button_new_clicked (GtkButton
*button
,
3091 #ifdef BABEL_CLEANUP
3092 create_new_window((GtkWidget
*)button
, user_data
, TRUE
);
3094 GtkWidget
*dialogue
=
3095 gtk_message_dialog_new(
3096 GTK_WINDOW(gtk_widget_get_toplevel(button
)),
3097 GTK_DIALOG_MODAL
|GTK_DIALOG_DESTROY_WITH_PARENT
,
3100 "Opening multiple windows is disabled.");
3101 gtk_dialog_run(GTK_DIALOG(dialogue
));
3102 gtk_widget_destroy(dialogue
);
3107 on_button_new_tab_clicked (GtkButton
*button
,
3110 create_new_tab((GtkWidget
*)button
, user_data
);
3114 on_button_open_clicked (GtkButton
*button
,
3117 #ifdef UNFINISHED_FEATURE
3118 open_traceset((GtkWidget
*)button
, user_data
);
3124 on_button_add_trace_clicked (GtkButton
*button
,
3127 add_trace((GtkWidget
*)button
, user_data
);
3132 on_button_remove_trace_clicked (GtkButton
*button
,
3135 remove_trace((GtkWidget
*)button
, user_data
);
3139 on_button_redraw_clicked (GtkButton
*button
,
3142 redraw((GtkWidget
*)button
, user_data
);
3146 on_button_continue_processing_clicked (GtkButton
*button
,
3149 continue_processing((GtkWidget
*)button
, user_data
);
3153 on_button_stop_processing_clicked (GtkButton
*button
,
3156 stop_processing((GtkWidget
*)button
, user_data
);
3162 on_button_save_clicked (GtkButton
*button
,
3165 save((GtkWidget
*)button
, user_data
);
3170 on_button_save_as_clicked (GtkButton
*button
,
3173 save_as((GtkWidget
*)button
, user_data
);
3178 on_button_zoom_in_clicked (GtkButton
*button
,
3181 zoom_in((GtkWidget
*)button
, user_data
);
3186 on_button_zoom_out_clicked (GtkButton
*button
,
3189 zoom_out((GtkWidget
*)button
, user_data
);
3194 on_button_zoom_extended_clicked (GtkButton
*button
,
3197 zoom_extended((GtkWidget
*)button
, user_data
);
3202 on_button_go_to_time_clicked (GtkButton
*button
,
3205 go_to_time((GtkWidget
*)button
, user_data
);
3210 on_button_show_time_frame_clicked (GtkButton
*button
,
3213 show_time_frame((GtkWidget
*)button
, user_data
);
3218 on_button_move_up_clicked (GtkButton
*button
,
3221 move_up_viewer((GtkWidget
*)button
, user_data
);
3226 on_button_move_down_clicked (GtkButton
*button
,
3229 move_down_viewer((GtkWidget
*)button
, user_data
);
3234 on_button_delete_viewer_clicked (GtkButton
*button
,
3237 delete_viewer((GtkWidget
*)button
, user_data
);
3241 on_MWindow_destroy (GtkWidget
*widget
,
3244 MainWindow
*main_window
= get_window_data_struct(widget
);
3245 LttvIAttribute
*attributes
= main_window
->attributes
;
3246 LttvAttributeValue value
;
3249 //This is unnecessary, since widgets will be destroyed
3250 //by the main window widget anyway.
3251 //remove_all_menu_toolbar_constructors(main_window, NULL);
3253 retval
= lttv_iattribute_find_by_path(attributes
, "viewers/menu",
3254 LTTV_POINTER
, &value
);
3256 lttv_menus_destroy((LttvMenus
*)*(value
.v_pointer
));
3258 retval
= lttv_iattribute_find_by_path(attributes
, "viewers/toolbar",
3259 LTTV_POINTER
, &value
);
3261 lttv_toolbars_destroy((LttvToolbars
*)*(value
.v_pointer
));
3263 g_object_unref(main_window
->attributes
);
3264 g_main_window_list
= g_slist_remove(g_main_window_list
, main_window
);
3266 g_info("There are now : %d windows\n",g_slist_length(g_main_window_list
));
3267 if(g_slist_length(g_main_window_list
) == 0)
3272 on_MWindow_configure (GtkWidget
*widget
,
3273 GdkEventConfigure
*event
,
3276 // MD : removed time width modification upon resizing of the main window.
3277 // The viewers will redraw themselves completely, without time interval
3280 if(mw_data->window_width){
3281 time_span = LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context)->Time_Span ;
3282 time_win = tab->time_window;
3283 ratio = width / mw_data->window_width;
3284 tab->time_window.time_width = ltt_time_mul(time_win.time_width,ratio);
3285 time = ltt_time_sub(time_span->endTime, time_win.start_time);
3286 if(ltt_time_compare(time, tab->time_window.time_width) < 0){
3287 tab->time_window.time_width = time;
3293 mw_data->window_width = (int)width;
3302 on_MNotebook_switch_page (GtkNotebook
*notebook
,
3303 GtkNotebookPage
*page
,
3311 void time_change_manager (Tab
*tab
,
3312 TimeWindow new_time_window
)
3315 /* Only one source of time change */
3316 if(tab
->time_manager_lock
== TRUE
) return;
3318 tab
->time_manager_lock
= TRUE
;
3319 TimeInterval time_span
;
3321 LttvTraceset
*ts
= tab
->traceset_info
->traceset
;
3323 time_span
= lttv_traceset_get_time_span_real(ts
);
3325 LttTime start_time
= new_time_window
.start_time
;
3326 LttTime end_time
= new_time_window
.end_time
;
3328 g_assert(ltt_time_compare(start_time
, end_time
) < 0);
3331 GtkAdjustment
*adjustment
= gtk_range_get_adjustment(GTK_RANGE(tab
->scrollbar
));
3332 LttTime upper
= ltt_time_sub(time_span
.end_time
, time_span
.start_time
);
3335 gtk_range_set_increments(GTK_RANGE(tab
->scrollbar
),
3336 ltt_time_to_double(new_time_window
.time_width
)
3337 / SCROLL_STEP_PER_PAGE
3338 * NANOSECONDS_PER_SECOND
, /* step increment */
3339 ltt_time_to_double(new_time_window
.time_width
)
3340 * NANOSECONDS_PER_SECOND
); /* page increment */
3341 gtk_range_set_range(GTK_RANGE(tab
->scrollbar
),
3343 ltt_time_to_double(upper
)
3344 * NANOSECONDS_PER_SECOND
); /* upper */
3346 g_object_set(G_OBJECT(adjustment
),
3350 ltt_time_to_double(upper
), /* upper */
3352 new_time_window
.time_width_double
3353 / SCROLL_STEP_PER_PAGE
, /* step increment */
3355 new_time_window
.time_width_double
,
3356 /* page increment */
3358 new_time_window
.time_width_double
, /* page size */
3360 gtk_adjustment_changed(adjustment
);
3362 // g_object_set(G_OBJECT(adjustment),
3364 // ltt_time_to_double(
3365 // ltt_time_sub(start_time, time_span.start_time))
3368 //gtk_adjustment_value_changed(adjustment);
3369 gtk_range_set_value(GTK_RANGE(tab
->scrollbar
),
3371 ltt_time_sub(start_time
, time_span
.start_time
)) /* value */);
3373 /* set the time bar. */
3376 timebar_set_minmax_time(TIMEBAR(tab
->MTimebar
),
3377 &time_span
.start_time
,
3378 &time_span
.end_time
);
3379 timebar_set_start_time(TIMEBAR(tab
->MTimebar
),&start_time
);
3380 timebar_set_end_time(TIMEBAR(tab
->MTimebar
),&end_time
);
3384 /* call viewer hooks for new time window */
3385 set_time_window(tab
, &new_time_window
);
3387 tab
->time_manager_lock
= FALSE
;
3396 void current_time_change_manager (Tab
*tab
,
3397 LttTime new_current_time
)
3399 /* Only one source of time change */
3400 if(tab
->current_time_manager_lock
== TRUE
) return;
3402 tab
->current_time_manager_lock
= TRUE
;
3404 timebar_set_current_time(TIMEBAR(tab
->MTimebar
), &new_current_time
);
3406 set_current_time(tab
, &new_current_time
);
3408 tab
->current_time_manager_lock
= FALSE
;
3411 void current_position_change_manager(Tab
*tab
, LttvTracesetPosition
*pos
)
3413 lttv_traceset_seek_to_position( pos
);
3415 LttTime new_time
= lttv_traceset_position_get_time(pos
);
3416 /* Put the context in a state coherent position */
3418 lttv_state_traceset_seek_time_closest(tab
->traceset_info
->traceset
, ltt_time_zero
);
3420 current_time_change_manager(tab
, new_time
);
3422 set_current_position(tab
, pos
);
3425 static void on_timebar_starttime_changed(Timebar
*timebar
,
3428 Tab
*tab
= (Tab
*)user_data
;
3429 LttvTraceset
* ts
=tab
->traceset_info
->traceset
;
3430 TimeInterval time_span
= lttv_traceset_get_time_span_real(ts
);
3432 TimeWindow new_time_window
= tab
->time_window
;
3433 new_time_window
.start_time
= timebar_get_start_time(timebar
);
3435 LttTime end_time
= new_time_window
.end_time
;
3437 /* TODO ybrosseau 2010-12-02: This if should have been checked
3438 by the timebar already */
3439 if(ltt_time_compare(new_time_window
.start_time
, end_time
) >= 0) {
3440 /* Then, we must push back end time : keep the same time width
3441 * if possible, else end traceset time */
3442 end_time
= LTT_TIME_MIN(ltt_time_add(new_time_window
.start_time
,
3443 new_time_window
.time_width
),
3444 time_span
.end_time
);
3447 /* Fix the time width to fit start time and end time */
3448 new_time_window
.time_width
= ltt_time_sub(end_time
,
3449 new_time_window
.start_time
);
3451 new_time_window
.time_width_double
=
3452 ltt_time_to_double(new_time_window
.time_width
);
3454 new_time_window
.end_time
= end_time
;
3456 /* Notify the time_manager */
3457 time_change_manager(tab
, new_time_window
);
3461 static void on_timebar_endtime_changed(Timebar
*timebar
,
3464 Tab
*tab
= (Tab
*)user_data
;
3465 LttvTraceset
* ts
=tab
->traceset_info
->traceset
;
3466 TimeInterval time_span
= lttv_traceset_get_time_span_real(ts
);
3468 TimeWindow new_time_window
= tab
->time_window
;
3470 LttTime end_time
= timebar_get_end_time(timebar
);
3472 /* TODO ybrosseau 2010-12-02: This if should have been
3473 checked by the timebar already */
3474 if(ltt_time_compare(new_time_window
.start_time
, end_time
) >= 0) {
3475 /* Then, we must push front start time : keep the same time
3476 width if possible, else end traceset time */
3477 new_time_window
.start_time
= LTT_TIME_MAX(
3478 ltt_time_sub(end_time
,
3479 new_time_window
.time_width
),
3480 time_span
.start_time
);
3483 /* Fix the time width to fit start time and end time */
3484 new_time_window
.time_width
= ltt_time_sub(end_time
,
3485 new_time_window
.start_time
);
3487 new_time_window
.time_width_double
=
3488 ltt_time_to_double(new_time_window
.time_width
);
3490 new_time_window
.end_time
= end_time
;
3492 /* Notify the time_manager */
3493 time_change_manager(tab
, new_time_window
);
3495 static void on_timebar_currenttime_changed(Timebar
*timebar
,
3498 Tab
*tab
= (Tab
*)user_data
;
3500 LttTime new_current_time
= timebar_get_current_time(timebar
);
3502 current_time_change_manager(tab
, new_current_time
);
3505 void scroll_value_changed_cb(GtkWidget
*scrollbar
,
3508 Tab
*tab
= (Tab
*)user_data
;
3509 TimeWindow new_time_window
;
3511 GtkAdjustment
*adjust
= gtk_range_get_adjustment(GTK_RANGE(scrollbar
));
3512 gdouble value
= gtk_adjustment_get_value(adjust
);
3513 // gdouble upper, lower, ratio, page_size;
3516 LttvTraceset
* ts
= tab
->traceset_info
->traceset
;
3517 TimeInterval time_span
= lttv_traceset_get_time_span_real(ts
);
3519 time
= ltt_time_add(ltt_time_from_double(value
),
3520 time_span
.start_time
);
3522 new_time_window
.start_time
= time
;
3524 page_size
= adjust
->page_size
;
3526 new_time_window
.time_width
=
3527 ltt_time_from_double(page_size
);
3529 new_time_window
.time_width_double
=
3532 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
3533 new_time_window
.time_width
);
3536 time_change_manager(tab
, new_time_window
);
3539 //time_window = tab->time_window;
3541 lower
= adjust
->lower
;
3542 upper
= adjust
->upper
;
3543 ratio
= (value
- lower
) / (upper
- lower
);
3544 g_info("lower %lu, upper %lu, value %lu, ratio %lu", lower
, upper
, value
, ratio
);
3546 //time = ltt_time_sub(time_span->end_time, time_span->start_time);
3547 //time = ltt_time_mul(time, (float)ratio);
3548 //time = ltt_time_add(time_span->start_time, time);
3549 time
= ltt_time_add(ltt_time_from_double(value
),
3550 time_span
.start_time
);
3552 time_window
.start_time
= time
;
3554 page_size
= adjust
->page_size
;
3556 time_window
.time_width
=
3557 ltt_time_from_double(page_size
);
3558 //time = ltt_time_sub(time_span.end_time, time);
3559 //if(ltt_time_compare(time,time_window.time_width) < 0){
3560 // time_window.time_width = time;
3563 /* call viewer hooks for new time window */
3564 set_time_window(tab
, &time_window
);
3570 /* Display a dialogue showing all eventtypes and traces, let user to select the interested
3571 * eventtypes, tracefiles and traces (filter)
3574 /* Select a trace which will be removed from traceset
3577 char * get_remove_trace(MainWindow
*mw_data
,
3578 char ** all_trace_name
, int nb_trace
)
3580 return get_selection(mw_data
, all_trace_name
, nb_trace
,
3581 "Select a trace", "Trace pathname");
3585 /* Select a module which will be loaded
3588 char * get_load_module(MainWindow
*mw_data
,
3589 char ** load_module_name
, int nb_module
)
3591 return get_selection(mw_data
, load_module_name
, nb_module
,
3592 "Select a module to load", "Module name");
3598 /* Select a module which will be unloaded
3601 char * get_unload_module(MainWindow
*mw_data
,
3602 char ** loaded_module_name
, int nb_module
)
3604 return get_selection(mw_data
, loaded_module_name
, nb_module
,
3605 "Select a module to unload", "Module name");
3609 /* Display a dialogue which shows all selectable items, let user to
3610 * select one of them
3613 char * get_selection(MainWindow
*mw_data
,
3614 char ** loaded_module_name
, int nb_module
,
3615 char *title
, char * column_title
)
3617 GtkWidget
* dialogue
;
3618 GtkWidget
* scroll_win
;
3620 GtkListStore
* store
;
3621 GtkTreeViewColumn
* column
;
3622 GtkCellRenderer
* renderer
;
3623 GtkTreeSelection
* select
;
3626 char * unload_module_name
= NULL
;
3628 dialogue
= gtk_dialog_new_with_buttons(title
,
3631 GTK_STOCK_OK
,GTK_RESPONSE_ACCEPT
,
3632 GTK_STOCK_CANCEL
,GTK_RESPONSE_REJECT
,
3634 gtk_window_set_default_size((GtkWindow
*)dialogue
, 500, 200);
3635 gtk_window_set_transient_for(GTK_WINDOW(dialogue
),
3636 GTK_WINDOW(mw_data
->mwindow
));
3638 scroll_win
= gtk_scrolled_window_new (NULL
, NULL
);
3639 gtk_widget_show ( scroll_win
);
3640 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll_win
),
3641 GTK_POLICY_AUTOMATIC
, GTK_POLICY_AUTOMATIC
);
3643 store
= gtk_list_store_new (N_COLUMNS
,G_TYPE_STRING
);
3644 tree
= gtk_tree_view_new_with_model(GTK_TREE_MODEL (store
));
3645 gtk_widget_show ( tree
);
3646 g_object_unref (G_OBJECT (store
));
3648 renderer
= gtk_cell_renderer_text_new ();
3649 column
= gtk_tree_view_column_new_with_attributes (column_title
,
3651 "text", MODULE_COLUMN
,
3653 gtk_tree_view_column_set_alignment (column
, 0.5);
3654 gtk_tree_view_column_set_fixed_width (column
, 150);
3655 gtk_tree_view_append_column (GTK_TREE_VIEW (tree
), column
);
3657 select
= gtk_tree_view_get_selection (GTK_TREE_VIEW (tree
));
3658 gtk_tree_selection_set_mode (select
, GTK_SELECTION_SINGLE
);
3660 gtk_container_add (GTK_CONTAINER (scroll_win
), tree
);
3662 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialogue
)->vbox
), scroll_win
,TRUE
, TRUE
,0);
3664 for(i
=0;i
<nb_module
;i
++){
3665 gtk_list_store_append (store
, &iter
);
3666 gtk_list_store_set (store
, &iter
, MODULE_COLUMN
,loaded_module_name
[i
],-1);
3669 id
= gtk_dialog_run(GTK_DIALOG(dialogue
));
3670 GtkTreeModel
**store_model
= (GtkTreeModel
**)&store
;
3672 case GTK_RESPONSE_ACCEPT
:
3673 case GTK_RESPONSE_OK
:
3674 if (gtk_tree_selection_get_selected (select
, store_model
, &iter
)){
3675 gtk_tree_model_get ((GtkTreeModel
*)store
, &iter
, MODULE_COLUMN
, &unload_module_name
, -1);
3677 case GTK_RESPONSE_REJECT
:
3678 case GTK_RESPONSE_CANCEL
:
3680 gtk_widget_destroy(dialogue
);
3684 return unload_module_name
;
3688 /* Insert all menu entry and tool buttons into this main window
3693 void add_all_menu_toolbar_constructors(MainWindow
* mw
, gpointer user_data
)
3697 lttvwindow_viewer_constructor constructor
;
3698 LttvMenus
* global_menu
, * instance_menu
;
3699 LttvToolbars
* global_toolbar
, * instance_toolbar
;
3700 LttvMenuClosure
*menu_item
;
3701 LttvToolbarClosure
*toolbar_item
;
3702 LttvAttributeValue value
;
3703 LttvIAttribute
*global_attributes
= LTTV_IATTRIBUTE(lttv_global_attributes());
3704 LttvIAttribute
*attributes
= mw
->attributes
;
3705 GtkWidget
* tool_menu_title_menu
, *new_widget
, *pixmap
;
3708 retval
= lttv_iattribute_find_by_path(global_attributes
, "viewers/menu",
3709 LTTV_POINTER
, &value
);
3711 if(*(value
.v_pointer
) == NULL
)
3712 *(value
.v_pointer
) = lttv_menus_new();
3713 global_menu
= (LttvMenus
*)*(value
.v_pointer
);
3715 retval
= lttv_iattribute_find_by_path(attributes
, "viewers/menu",
3716 LTTV_POINTER
, &value
);
3718 if(*(value
.v_pointer
) == NULL
)
3719 *(value
.v_pointer
) = lttv_menus_new();
3720 instance_menu
= (LttvMenus
*)*(value
.v_pointer
);
3722 retval
= lttv_iattribute_find_by_path(global_attributes
, "viewers/toolbar",
3723 LTTV_POINTER
, &value
);
3725 if(*(value
.v_pointer
) == NULL
)
3726 *(value
.v_pointer
) = lttv_toolbars_new();
3727 global_toolbar
= (LttvToolbars
*)*(value
.v_pointer
);
3729 retval
= lttv_iattribute_find_by_path(attributes
, "viewers/toolbar",
3730 LTTV_POINTER
, &value
);
3732 if(*(value
.v_pointer
) == NULL
)
3733 *(value
.v_pointer
) = lttv_toolbars_new();
3734 instance_toolbar
= (LttvToolbars
*)*(value
.v_pointer
);
3736 /* Add missing menu entries to window instance */
3737 for(i
=0;i
<global_menu
->len
;i
++) {
3738 menu_item
= &g_array_index(global_menu
, LttvMenuClosure
, i
);
3740 //add menu_item to window instance;
3741 constructor
= menu_item
->con
;
3742 tool_menu_title_menu
= lookup_widget(mw
->mwindow
,"ToolMenuTitle_menu");
3744 gtk_menu_item_new_with_mnemonic (menu_item
->menu_text
);
3745 gtk_container_add (GTK_CONTAINER (tool_menu_title_menu
),
3747 g_signal_connect ((gpointer
) new_widget
, "activate",
3748 G_CALLBACK (insert_viewer_wrap
),
3750 gtk_widget_show (new_widget
);
3751 lttv_menus_add(instance_menu
, menu_item
->con
,
3752 menu_item
->menu_path
,
3753 menu_item
->menu_text
,
3758 /* Add missing toolbar entries to window instance */
3759 for(i
=0;i
<global_toolbar
->len
;i
++) {
3760 toolbar_item
= &g_array_index(global_toolbar
, LttvToolbarClosure
, i
);
3762 //add toolbar_item to window instance;
3763 constructor
= toolbar_item
->con
;
3764 tool_menu_title_menu
= lookup_widget(mw
->mwindow
,"MToolbar1");
3765 pixbuf
= gdk_pixbuf_new_from_xpm_data((const char**)toolbar_item
->pixmap
);
3766 pixmap
= gtk_image_new_from_pixbuf(pixbuf
);
3768 gtk_toolbar_append_element (GTK_TOOLBAR (tool_menu_title_menu
),
3769 GTK_TOOLBAR_CHILD_BUTTON
,
3772 toolbar_item
->tooltip
, NULL
,
3773 pixmap
, NULL
, NULL
);
3774 gtk_label_set_use_underline(
3775 GTK_LABEL (((GtkToolbarChild
*) (
3776 g_list_last (GTK_TOOLBAR
3777 (tool_menu_title_menu
)->children
)->data
))->label
),
3779 gtk_container_set_border_width (GTK_CONTAINER (new_widget
), 1);
3780 g_signal_connect ((gpointer
) new_widget
,
3782 G_CALLBACK (insert_viewer_wrap
),
3784 gtk_widget_show (new_widget
);
3786 lttv_toolbars_add(instance_toolbar
, toolbar_item
->con
,
3787 toolbar_item
->tooltip
,
3788 toolbar_item
->pixmap
,
3796 /* Create a main window
3799 MainWindow
*construct_main_window(MainWindow
* parent
)
3803 g_debug("construct_main_window()");
3804 GtkWidget
* new_window
; /* New generated main window */
3805 MainWindow
* new_m_window
;/* New main window structure */
3806 GtkNotebook
* notebook
;
3807 LttvIAttribute
*attributes
=
3808 LTTV_IATTRIBUTE(g_object_new(LTTV_ATTRIBUTE_TYPE
, NULL
));
3809 LttvAttributeValue value
;
3811 new_m_window
= g_new(MainWindow
, 1);
3813 // Add the object's information to the module's array
3814 g_main_window_list
= g_slist_append(g_main_window_list
, new_m_window
);
3816 new_window
= create_MWindow();
3817 gtk_widget_show (new_window
);
3819 new_m_window
->mwindow
= new_window
;
3820 new_m_window
->attributes
= attributes
;
3822 retval
= lttv_iattribute_find_by_path(attributes
, "viewers/menu",
3823 LTTV_POINTER
, &value
);
3825 *(value
.v_pointer
) = lttv_menus_new();
3827 retval
= lttv_iattribute_find_by_path(attributes
, "viewers/toolbar",
3828 LTTV_POINTER
, &value
);
3830 *(value
.v_pointer
) = lttv_toolbars_new();
3832 add_all_menu_toolbar_constructors(new_m_window
, NULL
);
3834 g_object_set_data_full(G_OBJECT(new_window
),
3836 (gpointer
)new_m_window
,
3837 (GDestroyNotify
)g_free
);
3838 //create a default tab
3839 notebook
= (GtkNotebook
*)lookup_widget(new_m_window
->mwindow
, "MNotebook");
3840 if(notebook
== NULL
){
3841 g_info("Notebook does not exist\n");
3842 /* FIXME : destroy partially created widgets */
3843 g_free(new_m_window
);
3846 //gtk_notebook_popup_enable (GTK_NOTEBOOK(notebook));
3847 //for now there is no name field in LttvTraceset structure
3848 //Use "Traceset" as the label for the default tab
3850 GtkWidget
* parent_notebook
= lookup_widget(parent
->mwindow
, "MNotebook");
3851 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(parent_notebook
),
3852 gtk_notebook_get_current_page(GTK_NOTEBOOK(parent_notebook
)));
3858 LttvPluginTab
*ptab
;
3859 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
3860 parent_tab
= ptab
->tab
;
3862 LttvPluginTab
*ptab
= g_object_new(LTTV_TYPE_PLUGIN_TAB
, NULL
);
3864 new_m_window
, parent_tab
, notebook
, "Traceset");
3865 ptab
->parent
.top_widget
= ptab
->tab
->top_widget
;
3866 g_object_set_data_full(
3867 G_OBJECT(ptab
->tab
->vbox
),
3870 (GDestroyNotify
)tab_destructor
);
3872 LttvPluginTab
*ptab
= g_object_new(LTTV_TYPE_PLUGIN_TAB
, NULL
);
3873 init_tab(ptab
->tab
, new_m_window
, NULL
, notebook
, "Traceset");
3874 ptab
->parent
.top_widget
= ptab
->tab
->top_widget
;
3875 g_object_set_data_full(
3876 G_OBJECT(ptab
->tab
->vbox
),
3879 (GDestroyNotify
)tab_destructor
);
3882 /* Insert default viewers */
3884 LttvAttributeType type
;
3885 LttvAttributeName name
;
3886 LttvAttributeValue value
;
3887 LttvAttribute
*attribute
;
3889 LttvIAttribute
*attributes_global
=
3890 LTTV_IATTRIBUTE(lttv_global_attributes());
3892 attribute
= LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
3893 LTTV_IATTRIBUTE(attributes_global
),
3894 LTTV_VIEWER_CONSTRUCTORS
));
3895 g_assert(attribute
);
3897 name
= g_quark_from_string("guievents");
3898 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
3900 if(type
== LTTV_POINTER
) {
3901 lttvwindow_viewer_constructor viewer_constructor
=
3902 (lttvwindow_viewer_constructor
)*value
.v_pointer
;
3903 insert_viewer(new_window
, viewer_constructor
);
3906 name
= g_quark_from_string("guicontrolflow");
3907 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
3909 if(type
== LTTV_POINTER
) {
3910 lttvwindow_viewer_constructor viewer_constructor
=
3911 (lttvwindow_viewer_constructor
)*value
.v_pointer
;
3912 insert_viewer(new_window
, viewer_constructor
);
3915 name
= g_quark_from_string("guistatistics");
3916 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
3918 if(type
== LTTV_POINTER
) {
3919 lttvwindow_viewer_constructor viewer_constructor
=
3920 (lttvwindow_viewer_constructor
)*value
.v_pointer
;
3921 insert_viewer(new_window
, viewer_constructor
);
3925 g_info("There are now : %d windows\n",g_slist_length(g_main_window_list
));
3927 return new_m_window
;
3931 /* Free the memory occupied by a tab structure
3935 void tab_destructor(LttvPluginTab
* ptab
)
3937 #ifdef BABEL_CLEANUP
3938 int i
, nb
, ref_count
;
3940 Tab
*tab
= ptab
->tab
;
3943 g_object_unref(tab
->attributes
);
3945 if(tab
->interrupted_state
)
3946 g_object_unref(tab
->interrupted_state
);
3949 if(tab
->traceset_info
->traceset_context
!= NULL
){
3950 //remove state update hooks
3951 lttv_state_remove_event_hooks(
3952 (LttvTracesetState
*)tab
->traceset_info
->
3954 lttv_context_fini(LTTV_TRACESET_CONTEXT(tab
->traceset_info
->
3956 g_object_unref(tab
->traceset_info
->traceset_context
);
3958 if(tab
->traceset_info
->traceset
!= NULL
) {
3959 nb
= lttv_traceset_number(tab
->traceset_info
->traceset
);
3960 for(i
= 0 ; i
< nb
; i
++) {
3961 trace
= lttv_traceset_get(tab
->traceset_info
->traceset
, i
);
3962 ref_count
= lttv_trace_get_ref_number(trace
);
3964 ltt_trace_close(lttv_trace(trace
));
3968 lttv_traceset_destroy(tab
->traceset_info
->traceset
);
3969 /* Remove the idle events requests processing function of the tab */
3970 g_idle_remove_by_data(tab
);
3972 g_slist_free(tab
->events_requests
);
3973 g_free(tab
->traceset_info
);
3975 g_object_unref(ptab
);
3976 #endif /* BABEL_CLEANUP */
3980 /* Create a tab and insert it into the current main window
3983 void init_tab(Tab
*tab
, MainWindow
* mw
, Tab
*copy_tab
,
3984 GtkNotebook
* notebook
, char * label
)
3989 //LttvFilter *filter = NULL;
3991 //create a new tab data structure
3992 //tab = g_new(Tab,1);
3994 //construct and initialize the traceset_info
3995 tab
->traceset_info
= g_new(TracesetInfo
,1);
3998 tab
->traceset_info
->traceset
=
3999 lttv_traceset_copy(copy_tab
->traceset_info
->traceset
);
4001 /* Copy the previous tab's filter */
4002 /* We can clone the filter, as we copy the trace set also */
4003 /* The filter must always be in sync with the trace set */
4005 #ifdef BABEL_CLEANUP
4006 tab
->filter
= lttv_filter_clone(copy_tab
->filter
);
4007 #endif /* BABEL_CLEANUP */
4009 tab
->traceset_info
->traceset
= lttv_traceset_new();
4014 lttv_attribute_write_xml(
4015 lttv_traceset_attribute(tab
->traceset_info
->traceset
),
4021 tab
->time_manager_lock
= FALSE
;
4022 tab
->current_time_manager_lock
= FALSE
;
4023 #ifdef BABEL_CLEANUP
4024 //FIXME copy not implemented in lower level
4025 tab
->traceset_info
->traceset_context
=
4026 g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
4027 //add state update hooks
4028 #endif //BABEL_CLEANUP
4029 lttv_state_add_event_hooks(
4030 tab
->traceset_info
->traceset
);
4032 //determine the current_time and time_window of the tab
4034 if(copy_tab
!= NULL
){
4035 tab
->time_window
= copy_tab
->time_window
;
4036 tab
->current_time
= copy_tab
->current_time
;
4038 tab
->time_window
.start_time
=
4039 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
4040 time_span
.start_time
;
4041 if(DEFAULT_TIME_WIDTH_S
<
4042 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
4043 time_span
.end_time
.tv_sec
)
4044 tmp_time
.tv_sec
= DEFAULT_TIME_WIDTH_S
;
4047 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
4048 time_span
.end_time
.tv_sec
;
4049 tmp_time
.tv_nsec
= 0;
4050 tab
->time_window
.time_width
= tmp_time
;
4051 tab
->current_time
.tv_sec
=
4052 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
4053 time_span
.start_time
.tv_sec
;
4054 tab
->current_time
.tv_nsec
=
4055 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
4056 time_span
.start_time
.tv_nsec
;
4059 tab
->attributes
= LTTV_IATTRIBUTE(g_object_new(LTTV_ATTRIBUTE_TYPE
, NULL
));
4060 tab
->interrupted_state
= g_object_new(LTTV_ATTRIBUTE_TYPE
, NULL
);
4062 tab
->vbox
= gtk_vbox_new(FALSE
, 2);
4063 tab
->top_widget
= tab
->vbox
;
4064 //g_object_set_data_full(G_OBJECT(tab->top_widget), "filter",
4065 // filter, (GDestroyNotify)lttv_filter_destroy);
4067 // g_signal_connect (G_OBJECT(tab->top_widget),
4069 // G_CALLBACK (on_top_notify),
4072 tab
->viewer_container
= gtk_vbox_new(TRUE
, 2);
4073 tab
->scrollbar
= gtk_hscrollbar_new(NULL
);
4074 //tab->multivpaned = gtk_multi_vpaned_new();
4076 gtk_box_pack_start(GTK_BOX(tab
->vbox
),
4077 tab
->viewer_container
,
4079 TRUE
, /* Give the extra space to the child */
4080 0); /* No padding */
4083 // tab->time_window = copy_tab->time_window;
4084 // tab->current_time = copy_tab->current_time;
4087 /* Create the timebar */
4089 tab
->MTimebar
= timebar_new();
4091 gtk_box_pack_end(GTK_BOX(tab
->vbox
),
4093 FALSE
, /* Do not expand */
4094 FALSE
, /* Fill has no effect here (expand false) */
4095 0); /* No padding */
4097 gtk_box_pack_end(GTK_BOX(tab
->vbox
),
4099 FALSE
, /* Do not expand */
4100 FALSE
, /* Fill has no effect here (expand false) */
4101 0); /* No padding */
4103 g_object_set_data(G_OBJECT(tab
->viewer_container
), "focused_viewer", NULL
);
4109 // Display a label with a X
4110 GtkWidget *w_hbox = gtk_hbox_new(FALSE, 4);
4111 GtkWidget *w_label = gtk_label_new (label);
4112 GtkWidget *pixmap = create_pixmap(GTK_WIDGET(notebook), "close.png");
4113 GtkWidget *w_button = gtk_button_new ();
4114 gtk_container_add(GTK_CONTAINER(w_button), pixmap);
4115 //GtkWidget *w_button = gtk_button_new_with_label("x");
4117 gtk_button_set_relief(GTK_BUTTON(w_button), GTK_RELIEF_NONE);
4119 gtk_box_pack_start(GTK_BOX(w_hbox), w_label, TRUE, TRUE, 0);
4120 gtk_box_pack_end(GTK_BOX(w_hbox), w_button, FALSE,
4123 g_signal_connect_swapped (w_button, "clicked",
4124 G_CALLBACK (on_close_tab_X_clicked),
4127 gtk_widget_set_state(w_button, GTK_STATE_ACTIVE);
4129 gtk_widget_show (w_label);
4130 gtk_widget_show (pixmap);
4131 gtk_widget_show (w_button);
4132 gtk_widget_show (w_hbox);
4134 tab->label = w_hbox;
4138 tab
->label
= gtk_label_new (label
);
4140 gtk_widget_show(tab
->label
);
4141 gtk_widget_show(tab
->scrollbar
);
4142 gtk_widget_show(tab
->MTimebar
);
4143 gtk_widget_show(tab
->viewer_container
);
4144 gtk_widget_show(tab
->vbox
);
4146 //gtk_widget_show(tab->multivpaned);
4149 /* Start with empty events requests list */
4150 tab
->events_requests
= NULL
;
4151 tab
->events_request_pending
= FALSE
;
4152 tab
->stop_foreground
= FALSE
;
4156 g_signal_connect(G_OBJECT(tab
->scrollbar
), "value-changed",
4157 G_CALLBACK(scroll_value_changed_cb
), tab
);
4160 /* Timebar signal handler */
4161 g_signal_connect(G_OBJECT(tab
->MTimebar
), "start-time-changed",
4162 G_CALLBACK(on_timebar_starttime_changed
), tab
);
4163 g_signal_connect(G_OBJECT(tab
->MTimebar
), "end-time-changed",
4164 G_CALLBACK(on_timebar_endtime_changed
), tab
);
4165 g_signal_connect(G_OBJECT(tab
->MTimebar
), "current-time-changed",
4166 G_CALLBACK(on_timebar_currenttime_changed
), tab
);
4168 //g_signal_connect(G_OBJECT(tab->scrollbar), "changed",
4169 // G_CALLBACK(scroll_value_changed_cb), tab);
4172 //insert tab into notebook
4173 gtk_notebook_append_page(notebook
,
4176 list
= gtk_container_get_children(GTK_CONTAINER(notebook
));
4177 gtk_notebook_set_current_page(notebook
,g_list_length(list
)-1);
4178 // always show : not if(g_list_length(list)>1)
4179 gtk_notebook_set_show_tabs(notebook
, TRUE
);
4182 lttvwindow_report_time_window(tab
, copy_tab
->time_window
);
4183 lttvwindow_report_current_time(tab
, copy_tab
->current_time
);
4185 TimeWindow time_window
;
4187 time_window
.start_time
= ltt_time_zero
;
4188 time_window
.end_time
= ltt_time_add(time_window
.start_time
,
4189 lttvwindow_default_time_width
);
4190 time_window
.time_width
= lttvwindow_default_time_width
;
4191 time_window
.time_width_double
= ltt_time_to_double(time_window
.time_width
);
4193 lttvwindow_report_time_window(tab
, time_window
);
4194 lttvwindow_report_current_time(tab
, ltt_time_zero
);
4197 LttvTraceset
*traceset
= tab
->traceset_info
->traceset
;
4198 SetTraceset(tab
, traceset
);
4202 * execute_events_requests
4204 * Idle function that executes the pending requests for a tab.
4206 * @return return value : TRUE : keep the idle function, FALSE : remove it.
4208 gboolean
execute_events_requests(Tab
*tab
)
4210 return ( lttvwindow_process_pending_requests(tab
) );
4214 __EXPORT
void create_main_window_with_trace_list(GSList
*traces
)
4217 GSList
*iter
= NULL
;
4220 MainWindow
*mw
= construct_main_window(NULL
);
4221 GtkWidget
*widget
= mw
->mwindow
;
4223 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
4224 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
4225 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
4226 LttvPluginTab
*ptab
;
4230 ptab
= create_new_tab(widget
, NULL
);
4233 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
4237 LttvTraceset
* traceset
= lttv_traceset_new();
4238 for(iter
=traces
; iter
!=NULL
; iter
=g_slist_next(iter
)) {
4239 gchar
*path
= (gchar
*)iter
->data
;
4241 gchar abs_path
[PATH_MAX
];
4244 get_absolute_pathname(path
, abs_path
);
4246 if(lttv_traceset_add_path(traceset
,abs_path
) != 0 ){ /*failure*/
4248 g_warning("cannot open trace %s", abs_path
);
4250 GtkWidget
*dialogue
=
4251 gtk_message_dialog_new(
4252 GTK_WINDOW(gtk_widget_get_toplevel(widget
)),
4253 GTK_DIALOG_MODAL
|GTK_DIALOG_DESTROY_WITH_PARENT
,
4256 "Cannot open trace : maybe you should enter in the directory "
4258 gtk_dialog_run(GTK_DIALOG(dialogue
));
4259 gtk_widget_destroy(dialogue
);
4262 SetTraceset(tab
, traceset
);