1 /* This file is part of the Linux Trace Toolkit viewer
2 * Copyright (C) 2003-2004 XangXiu Yang, Mathieu Desnoyers
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License Version 2 as
6 * published by the Free Software Foundation;
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place - Suite 330, Boston,
23 #include <limits.h> // for PATH_MAX
31 #include "callbacks.h"
32 #include "interface.h"
34 #include <ltt/trace.h>
36 #include <ltt/event.h>
37 #include <lttv/lttv.h>
38 #include <lttv/module.h>
39 #include <lttv/iattribute.h>
40 #include <lttv/traceset.h>
42 #include <lttv/stats.h>
43 #include <lttv/sync/sync_chain_lttv.h>
44 #endif /* BABEL_CLEANUP */
45 #include <lttv/filter.h>
46 #include <lttvwindow/mainwindow.h>
47 #include <lttvwindow/mainwindow-private.h>
48 #include <lttvwindow/menu.h>
49 #include <lttvwindow/timebar.h>
50 #include <lttvwindow/toolbar.h>
51 #include <lttvwindow/lttvwindow.h>
52 #include <lttvwindow/lttvwindowtraces.h>
53 #include <lttvwindow/lttv_plugin_tab.h>
55 #include <babeltrace/babeltrace.h>
56 #include <babeltrace/ctf/events.h>
57 #include <babeltrace/ctf/iterator.h>
59 static LttTime lttvwindow_default_time_width
= { 1, 0 };
60 #define CLIP_BUF 256 // size of clipboard buffer
62 extern LttvTrace
*g_init_trace
;
65 /** Array containing instanced objects. */
66 extern GSList
* g_main_window_list
;
68 /** MD : keep old directory. */
69 static char remember_plugins_dir
[PATH_MAX
] = "";
70 static char remember_trace_dir
[PATH_MAX
] = "";
72 void tab_destructor(LttvPluginTab
* ptab
);
74 MainWindow
* get_window_data_struct(GtkWidget
* widget
);
75 char * get_load_module(MainWindow
*mw
,
76 char ** load_module_name
, int nb_module
);
77 char * get_unload_module(MainWindow
*mw
,
78 char ** loaded_module_name
, int nb_module
);
79 char * get_remove_trace(MainWindow
*mw
, char ** all_trace_name
, int nb_trace
);
80 char * get_selection(MainWindow
*mw
,
81 char ** all_name
, int nb
, char *title
, char * column_title
);
82 void init_tab(Tab
*tab
, MainWindow
* mw
, Tab
*copy_tab
,
83 GtkNotebook
* notebook
, char * label
);
85 int update_traceset(Tab
*tab
, LttvTraceset
*traceset
);
87 static void insert_viewer(GtkWidget
* widget
, lttvwindow_viewer_constructor constructor
);
89 LttvPluginTab
*create_new_tab(GtkWidget
* widget
, gpointer user_data
);
91 static gboolean
lttvwindow_process_pending_requests(Tab
*tab
);
93 static void on_timebar_starttime_changed(Timebar
*timebar
,
95 static void on_timebar_endtime_changed(Timebar
*timebar
,
97 static void on_timebar_currenttime_changed(Timebar
*timebar
,
114 static void on_top_notify(GObject
*gobject
,
118 Tab
*tab
= (Tab
*)user_data
;
119 g_message("in on_top_notify.\n");
123 static gboolean
viewer_grab_focus(GtkWidget
*widget
, GdkEventButton
*event
,
126 GtkWidget
*viewer
= GTK_WIDGET(data
);
127 GtkWidget
*viewer_container
= gtk_widget_get_parent(viewer
);
129 g_debug("FOCUS GRABBED");
130 g_object_set_data(G_OBJECT(viewer_container
), "focused_viewer", viewer
);
135 static void connect_focus_recursive(GtkWidget
*widget
,
138 if(GTK_IS_CONTAINER(widget
)) {
139 gtk_container_forall(GTK_CONTAINER(widget
),
140 (GtkCallback
)connect_focus_recursive
,
144 if(GTK_IS_TREE_VIEW(widget
)) {
145 gtk_tree_view_set_headers_clickable(GTK_TREE_VIEW(widget
), TRUE
);
147 gtk_widget_add_events(widget
, GDK_BUTTON_PRESS_MASK
);
148 g_signal_connect (G_OBJECT(widget
),
149 "button-press-event",
150 G_CALLBACK (viewer_grab_focus
),
154 /* Stop all the processings and call gtk_main_quit() */
155 static void mainwindow_quit()
157 lttvwindowtraces_unregister_requests(g_quark_from_string("stats"));
158 lttvwindowtraces_unregister_requests(g_quark_from_string("state"));
159 lttvwindowtraces_unregister_computation_hooks(g_quark_from_string("stats"));
160 lttvwindowtraces_unregister_computation_hooks(g_quark_from_string("state"));
166 /* insert_viewer function constructs an instance of a viewer first,
167 * then inserts the widget of the instance into the container of the
172 insert_viewer_wrap(GtkWidget
*menuitem
, gpointer user_data
)
174 insert_viewer((GtkWidget
*)menuitem
, (lttvwindow_viewer_constructor
)user_data
);
178 /* internal functions */
179 void insert_viewer(GtkWidget
* widget
, lttvwindow_viewer_constructor constructor
)
181 GtkWidget
* viewer_container
;
182 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
184 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
185 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
190 ptab
= create_new_tab(widget
, NULL
);
192 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
196 viewer_container
= tab
->viewer_container
;
198 viewer
= (GtkWidget
*)constructor(&ptab
->parent
);
201 //gtk_multivpaned_widget_add(GTK_MULTIVPANED(multivpaned), viewer);
203 gtk_box_pack_end(GTK_BOX(viewer_container
),
209 /* We want to connect the viewer_grab_focus to EVERY
210 * child of this widget. The little trick is to get each child
211 * of each GTK_CONTAINER, even subchildren.
213 connect_focus_recursive(viewer
, viewer
);
218 * Function to set/update traceset for the viewers
219 * @param tab viewer's tab
220 * @param traceset traceset of the main window.
222 * 0 : traceset updated
223 * 1 : no traceset hooks to update; not an error.
226 int SetTraceset(Tab
* tab
, LttvTraceset
*traceset
)
229 TimeInterval time_span
;
230 TimeWindow new_time_window
;
231 LttTime new_current_time
;
234 // Perform time synchronization on the traces
235 if (syncTraceset(tsc
))
237 /* There is some time-dependant information that was calculated during
238 * context initialization. Destroy the old contexts and initialize new
240 * Modified from lttvwindow_add_trace()
242 // Keep a reference to the traces so they are not freed
243 for(i
= 0; i
< lttv_traceset_number(traceset
); i
++)
245 LttvTrace
*trace
= lttv_traceset_get(traceset
, i
);
246 lttv_trace_ref(trace
);
249 // Remove state update hooks
250 lttv_state_remove_event_hooks(
251 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
253 lttv_context_fini(LTTV_TRACESET_CONTEXT(
254 tab
->traceset_info
->traceset_context
));
255 g_object_unref(tab
->traceset_info
->traceset_context
);
257 for(i
= 0; i
< lttv_traceset_number(traceset
); i
++)
259 LttvTrace
*trace
= lttv_traceset_get(traceset
, i
);
260 lttvwindowtraces_remove_trace(trace
);
261 lttvwindowtraces_add_trace(trace
);
264 // Create new context
265 tab
->traceset_info
->traceset_context
=
266 g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
267 lttv_context_init(LTTV_TRACESET_CONTEXT(tab
->traceset_info
->
268 traceset_context
), traceset
);
270 // Add state update hooks
271 lttv_state_add_event_hooks(
272 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
274 // Remove local reference to the traces
275 for(i
=0; i
<lttv_traceset_number(traceset
); i
++)
277 LttvTrace
*trace
= lttv_traceset_get(traceset
, i
);
278 lttv_trace_unref(trace
);
281 tsc
= LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
283 #endif /*BABEL_CLEANUP*/
285 time_span
= lttv_traceset_get_time_span(traceset
);
287 tab
->traceset_info
->traceset
= traceset
;
289 new_time_window
= tab
->time_window
;
290 new_current_time
= tab
->current_time
;
292 /* Set the tab's time window and current time if
294 if(ltt_time_compare(tab
->time_window
.start_time
, time_span
.start_time
) < 0
295 || ltt_time_compare(tab
->time_window
.end_time
,
296 time_span
.end_time
) > 0) {
297 new_time_window
.start_time
= time_span
.start_time
;
299 new_current_time
= time_span
.start_time
;
303 if(ltt_time_compare(lttvwindow_default_time_width
,
304 ltt_time_sub(time_span
.end_time
, time_span
.start_time
)) < 0
306 ltt_time_compare(time_span
.end_time
, time_span
.start_time
) == 0)
307 tmp_time
= lttvwindow_default_time_width
;
309 tmp_time
= time_span
.end_time
;
311 new_time_window
.time_width
= tmp_time
;
312 new_time_window
.time_width_double
= ltt_time_to_double(tmp_time
);
313 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
314 new_time_window
.time_width
) ;
317 /* Finally, call the update hooks of the viewers */
318 gint retval
= update_traceset(tab
, traceset
);
320 time_change_manager(tab
, new_time_window
);
321 current_time_change_manager(tab
, new_current_time
);
328 * Function to set/update filter for the viewers
329 * @param tab viewer's tab
330 * @param filter filter of the main window.
333 * 0 : filters updated
334 * 1 : no filter hooks to update; not an error.
337 int SetFilter(Tab
* tab
, gpointer filter
)
340 LttvAttributeValue value
;
342 g_assert(lttv_iattribute_find_by_path(tab
->attributes
,
343 "hooks/updatefilter", LTTV_POINTER
, &value
));
345 tmp
= (LttvHooks
*)*(value
.v_pointer
);
347 if(tmp
== NULL
) return 1;
348 lttv_hooks_call(tmp
,filter
);
356 * Function to redraw each viewer belonging to the current tab
357 * @param tab viewer's tab
360 int update_traceset(Tab
*tab
, LttvTraceset
*traceset
)
362 LttvAttributeValue value
;
366 retval
= lttv_iattribute_find_by_path(tab
->attributes
,
367 "hooks/updatetraceset",
371 tmp
= (LttvHooks
*)*(value
.v_pointer
);
375 lttv_hooks_call(tmp
, traceset
);
381 Call hooks register to get update on traceset time span changes
383 int notify_time_span_changed(Tab
*tab
)
385 LttvAttributeValue value
;
389 retval
= lttv_iattribute_find_by_path(tab
->attributes
,
390 "hooks/updatetimespan",
394 tmp
= (LttvHooks
*)*(value
.v_pointer
);
398 lttv_hooks_call(tmp
, NULL
);
403 /* get_label function is used to get user input, it displays an input
404 * box, which allows user to input a string
407 void get_label_string (GtkWidget
* text
, gchar
* label
)
409 GtkEntry
* entry
= (GtkEntry
*)text
;
410 if(strlen(gtk_entry_get_text(entry
))!=0)
411 strcpy(label
,gtk_entry_get_text(entry
));
414 gboolean
get_label(MainWindow
* mw
, gchar
* str
, gchar
* dialogue_title
, gchar
* label_str
)
416 GtkWidget
* dialogue
;
421 dialogue
= gtk_dialog_new_with_buttons(dialogue_title
,NULL
,
423 GTK_STOCK_OK
,GTK_RESPONSE_ACCEPT
,
424 GTK_STOCK_CANCEL
,GTK_RESPONSE_REJECT
,
427 label
= gtk_label_new(label_str
);
428 gtk_widget_show(label
);
430 text
= gtk_entry_new();
431 gtk_widget_show(text
);
433 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialogue
)->vbox
), label
,TRUE
, TRUE
,0);
434 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialogue
)->vbox
), text
,FALSE
, FALSE
,0);
436 id
= gtk_dialog_run(GTK_DIALOG(dialogue
));
438 case GTK_RESPONSE_ACCEPT
:
439 get_label_string(text
,str
);
440 gtk_widget_destroy(dialogue
);
442 case GTK_RESPONSE_REJECT
:
444 gtk_widget_destroy(dialogue
);
451 /* get_window_data_struct function is actually a lookup function,
452 * given a widget which is in the tree of the main window, it will
453 * return the MainWindow data structure associated with main window
456 MainWindow
* get_window_data_struct(GtkWidget
* widget
)
459 MainWindow
* mw_data
;
461 mw
= lookup_widget(widget
, "MWindow");
463 g_info("Main window does not exist\n");
467 mw_data
= (MainWindow
*) g_object_get_data(G_OBJECT(mw
),"main_window_data");
469 g_warning("Main window data does not exist\n");
476 /* create_new_window function, just constructs a new main window
479 void create_new_window(GtkWidget
* widget
, gpointer user_data
, gboolean clone
)
481 MainWindow
* parent
= get_window_data_struct(widget
);
484 g_info("Clone : use the same traceset\n");
485 construct_main_window(parent
);
487 g_info("Empty : traceset is set to NULL\n");
488 construct_main_window(NULL
);
492 /* Get the currently focused viewer.
493 * If no viewer is focused, use the first one.
495 * If no viewer available, return NULL.
497 GtkWidget
*viewer_container_focus(GtkWidget
*container
)
501 widget
= (GtkWidget
*)g_object_get_data(G_OBJECT(container
),
505 g_debug("no widget focused");
506 GList
*children
= gtk_container_get_children(GTK_CONTAINER(container
));
509 widget
= GTK_WIDGET(children
->data
);
510 g_object_set_data(G_OBJECT(container
),
520 gint
viewer_container_position(GtkWidget
*container
, GtkWidget
*child
)
523 if(child
== NULL
) return -1;
527 memset(&value
, 0, sizeof(GValue
));
528 g_value_init(&value
, G_TYPE_INT
);
529 gtk_container_child_get_property(GTK_CONTAINER(container
),
533 pos
= g_value_get_int(&value
);
539 /* move_*_viewer functions move the selected view up/down in
543 void move_down_viewer(GtkWidget
* widget
, gpointer user_data
)
545 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
547 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
548 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
555 ptab
= g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
559 //gtk_multivpaned_widget_move_up(GTK_MULTIVPANED(tab->multivpaned));
561 /* change the position in the vbox */
562 GtkWidget
*focus_widget
;
564 focus_widget
= viewer_container_focus(tab
->viewer_container
);
565 position
= viewer_container_position(tab
->viewer_container
, focus_widget
);
568 /* can move up one position */
569 gtk_box_reorder_child(GTK_BOX(tab
->viewer_container
),
576 void move_up_viewer(GtkWidget
* widget
, gpointer user_data
)
578 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
580 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
581 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
588 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
592 //gtk_multivpaned_widget_move_down(GTK_MULTIVPANED(tab->multivpaned));
593 /* change the position in the vbox */
594 GtkWidget
*focus_widget
;
596 focus_widget
= viewer_container_focus(tab
->viewer_container
);
597 position
= viewer_container_position(tab
->viewer_container
, focus_widget
);
601 g_list_length(gtk_container_get_children(
602 GTK_CONTAINER(tab
->viewer_container
)))-1
604 /* can move down one position */
605 gtk_box_reorder_child(GTK_BOX(tab
->viewer_container
),
613 /* delete_viewer deletes the selected viewer in the current tab
616 void delete_viewer(GtkWidget
* widget
, gpointer user_data
)
618 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
620 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
621 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
628 ptab
= g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
632 //gtk_multivpaned_widget_delete(GTK_MULTIVPANED(tab->multivpaned));
634 GtkWidget
*focus_widget
= viewer_container_focus(tab
->viewer_container
);
636 if(focus_widget
!= NULL
)
637 gtk_widget_destroy(focus_widget
);
639 g_object_set_data(G_OBJECT(tab
->viewer_container
), "focused_viewer", NULL
);
642 #if UNFINISHED_FEATURE
643 /* TODO ybrosseau 2012-03-15: Function is half implemented. Should be removed */
644 /* open_traceset will open a traceset saved in a file
645 * Right now, it is not finished yet, (not working)
649 void open_traceset(GtkWidget
* widget
, gpointer user_data
)
653 LttvTraceset
* traceset
;
654 MainWindow
* mw_data
= get_window_data_struct(widget
);
655 GtkFileSelection
* file_selector
=
656 (GtkFileSelection
*)gtk_file_selection_new("Select a traceset");
658 gtk_file_selection_hide_fileop_buttons(file_selector
);
660 gtk_window_set_transient_for(GTK_WINDOW(file_selector
),
661 GTK_WINDOW(mw_data
->mwindow
));
663 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
665 case GTK_RESPONSE_ACCEPT
:
666 case GTK_RESPONSE_OK
:
667 dir
= gtk_file_selection_get_selections (file_selector
);
668 traceset
= lttv_traceset_load(dir
[0]);
669 g_info("Open a trace set %s\n", dir
[0]);
672 case GTK_RESPONSE_REJECT
:
673 case GTK_RESPONSE_CANCEL
:
675 gtk_widget_destroy((GtkWidget
*)file_selector
);
681 /* lttvwindow_process_pending_requests
683 * Process requests for parts of the trace from viewers.
685 * These requests are made by lttvwindow_events_request().
687 * This internal function gets called by g_idle, taking care of the pending
688 * requests. It is responsible for concatenation of time intervals and position
689 * requests. It does it with the following algorithm organizing process traceset
690 * calls. Here is the detailed description of the way it works :
692 * - Events Requests Servicing Algorithm
694 * Data structures necessary :
696 * List of requests added to context : list_in
697 * List of requests not added to context : list_out
702 * list_out : many events requests
704 * FIXME : insert rest of algorithm here
708 #define list_out tab->events_requests
710 gboolean
lttvwindow_process_pending_requests(Tab
*tab
)
713 LttvTracesetContext
*tsc
;
714 LttvTracefileContext
*tfc
;
715 GSList
*list_in
= NULL
;
719 LttvTracesetContextPosition
*end_position
;
721 if(lttvwindow_preempt_count
> 0) return TRUE
;
724 g_critical("Foreground processing : tab does not exist. Processing removed.");
728 /* There is no events requests pending : we should never have been called! */
729 g_assert(g_slist_length(list_out
) != 0);
731 tsc
= LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
733 //set the cursor to be X shape, indicating that the computer is busy in doing its job
735 new = gdk_cursor_new(GDK_X_CURSOR
);
736 widget
= lookup_widget(tab
->mw
->mwindow
, "MToolbar1");
737 win
= gtk_widget_get_parent_window(widget
);
738 gdk_window_set_cursor(win
, new);
739 gdk_cursor_unref(new);
740 gdk_window_stick(win
);
741 gdk_window_unstick(win
);
744 g_debug("SIZE events req len : %d", g_slist_length(list_out
));
746 /* Preliminary check for no trace in traceset */
747 /* Unregister the routine if empty, empty list_out too */
748 if(lttv_traceset_number(tsc
->ts
) == 0) {
750 /* - For each req in list_out */
751 GSList
*iter
= list_out
;
753 while(iter
!= NULL
) {
755 gboolean remove
= FALSE
;
756 gboolean free_data
= FALSE
;
757 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
759 /* - Call end request for req */
760 if(events_request
->servicing
== TRUE
)
761 lttv_hooks_call(events_request
->after_request
, (gpointer
)tsc
);
763 /* - remove req from list_out */
764 /* Destroy the request */
771 GSList
*remove_iter
= iter
;
773 iter
= g_slist_next(iter
);
774 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
775 list_out
= g_slist_remove_link(list_out
, remove_iter
);
776 } else { // not remove
777 iter
= g_slist_next(iter
);
782 /* 0.1 Lock Traces */
787 iter_trace
<lttv_traceset_number(tsc
->ts
);
789 LttvTrace
*trace_v
= lttv_traceset_get(tsc
->ts
, iter_trace
);
791 if(lttvwindowtraces_lock(trace_v
) != 0) {
792 g_critical("Foreground processing : Unable to get trace lock");
793 return TRUE
; /* Cannot get lock, try later */
798 /* 0.2 Seek tracefiles positions to context position */
799 //g_assert(lttv_process_traceset_seek_position(tsc, sync_position) == 0);
800 lttv_process_traceset_synchronize_tracefiles(tsc
);
803 /* Events processing algorithm implementation */
804 /* Warning : the gtk_events_pending takes a LOT of cpu time. So what we do
805 * instead is to leave the control to GTK and take it back.
807 /* A. Servicing loop */
808 //while( (g_slist_length(list_in) != 0 || g_slist_length(list_out) != 0)) {
809 if((g_slist_length(list_in
) != 0 || g_slist_length(list_out
) != 0)) {
811 /* 1. If list_in is empty (need a seek) */
812 if( g_slist_length(list_in
) == 0 ) {
814 /* list in is empty, need a seek */
816 /* 1.1 Add requests to list_in */
817 GSList
*ltime
= NULL
;
821 /* 1.1.1 Find all time requests with the lowest start time in list_out
824 if(g_slist_length(list_out
) > 0)
825 ltime
= g_slist_append(ltime
, g_slist_nth_data(list_out
, 0));
826 for(iter
=g_slist_nth(list_out
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
827 /* Find all time requests with the lowest start time in list_out */
828 EventsRequest
*event_request_ltime
= (EventsRequest
*)g_slist_nth_data(ltime
, 0);
829 EventsRequest
*event_request_list_out
= (EventsRequest
*)iter
->data
;
832 comp
= ltt_time_compare(event_request_ltime
->start_time
,
833 event_request_list_out
->start_time
);
835 ltime
= g_slist_append(ltime
, event_request_list_out
);
837 /* Remove all elements from ltime, and add current */
839 ltime
= g_slist_delete_link(ltime
, g_slist_nth(ltime
, 0));
840 ltime
= g_slist_append(ltime
, event_request_list_out
);
844 /* 1.1.2 Find all position requests with the lowest position in list_out
847 if(g_slist_length(list_out
) > 0)
848 lpos
= g_slist_append(lpos
, g_slist_nth_data(list_out
, 0));
849 for(iter
=g_slist_nth(list_out
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
850 /* Find all position requests with the lowest position in list_out */
851 EventsRequest
*event_request_lpos
= (EventsRequest
*)g_slist_nth_data(lpos
, 0);
852 EventsRequest
*event_request_list_out
= (EventsRequest
*)iter
->data
;
855 if(event_request_lpos
->start_position
!= NULL
856 && event_request_list_out
->start_position
!= NULL
)
858 comp
= lttv_traceset_context_pos_pos_compare
859 (event_request_lpos
->start_position
,
860 event_request_list_out
->start_position
);
865 lpos
= g_slist_append(lpos
, event_request_list_out
);
867 /* Remove all elements from lpos, and add current */
869 lpos
= g_slist_delete_link(lpos
, g_slist_nth(lpos
, 0));
870 lpos
= g_slist_append(lpos
, event_request_list_out
);
875 EventsRequest
*event_request_lpos
= (EventsRequest
*)g_slist_nth_data(lpos
, 0);
876 EventsRequest
*event_request_ltime
= (EventsRequest
*)g_slist_nth_data(ltime
, 0);
877 LttTime lpos_start_time
;
879 if(event_request_lpos
!= NULL
880 && event_request_lpos
->start_position
!= NULL
) {
881 lpos_start_time
= lttv_traceset_context_position_get_time(
882 event_request_lpos
->start_position
);
885 /* 1.1.3 If lpos.start time < ltime */
886 if(event_request_lpos
!= NULL
887 && event_request_lpos
->start_position
!= NULL
888 && ltt_time_compare(lpos_start_time
,
889 event_request_ltime
->start_time
)<0) {
890 /* Add lpos to list_in, remove them from list_out */
891 for(iter
=lpos
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
893 EventsRequest
*event_request_lpos
=
894 (EventsRequest
*)iter
->data
;
896 list_in
= g_slist_append(list_in
, event_request_lpos
);
897 /* Remove from list_out */
898 list_out
= g_slist_remove(list_out
, event_request_lpos
);
901 /* 1.1.4 (lpos.start time >= ltime) */
902 /* Add ltime to list_in, remove them from list_out */
904 for(iter
=ltime
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
906 EventsRequest
*event_request_ltime
=
907 (EventsRequest
*)iter
->data
;
909 list_in
= g_slist_append(list_in
, event_request_ltime
);
910 /* Remove from list_out */
911 list_out
= g_slist_remove(list_out
, event_request_ltime
);
921 tfc
= lttv_traceset_context_get_current_tfc(tsc
);
922 g_assert(g_slist_length(list_in
)>0);
923 EventsRequest
*events_request
= g_slist_nth_data(list_in
, 0);
928 /* 1.2.1 If first request in list_in is a time request */
929 if(events_request
->start_position
== NULL
) {
930 /* - If first req in list_in start time != current time */
931 if(tfc
== NULL
|| ltt_time_compare(events_request
->start_time
,
932 tfc
->timestamp
) != 0)
933 /* - Seek to that time */
934 g_debug("SEEK TIME : %lu, %lu", events_request
->start_time
.tv_sec
,
935 events_request
->start_time
.tv_nsec
);
936 //lttv_process_traceset_seek_time(tsc, events_request->start_time);
937 lttv_state_traceset_seek_time_closest(LTTV_TRACESET_STATE(tsc
),
938 events_request
->start_time
);
940 /* Process the traceset with only state hooks */
944 lttv_process_traceset_middle(tsc
,
945 events_request
->start_time
,
948 g_assert(seek_count
< LTTV_STATE_SAVE_INTERVAL
);
954 LttvTracefileContext
*tfc
=
955 lttv_traceset_context_get_current_tfc(tsc
);
956 /* Else, the first request in list_in is a position request */
957 /* If first req in list_in pos != current pos */
958 g_assert(events_request
->start_position
!= NULL
);
959 g_debug("SEEK POS time : %lu, %lu",
960 lttv_traceset_context_position_get_time(
961 events_request
->start_position
).tv_sec
,
962 lttv_traceset_context_position_get_time(
963 events_request
->start_position
).tv_nsec
);
966 g_debug("SEEK POS context time : %lu, %lu",
967 tfc
->timestamp
.tv_sec
,
968 tfc
->timestamp
.tv_nsec
);
970 g_debug("SEEK POS context time : %lu, %lu",
971 ltt_time_infinite
.tv_sec
,
972 ltt_time_infinite
.tv_nsec
);
974 g_assert(events_request
->start_position
!= NULL
);
975 if(lttv_traceset_context_ctx_pos_compare(tsc
,
976 events_request
->start_position
) != 0) {
977 /* 1.2.2.1 Seek to that position */
978 g_debug("SEEK POSITION");
979 //lttv_process_traceset_seek_position(tsc, events_request->start_position);
980 pos_time
= lttv_traceset_context_position_get_time(
981 events_request
->start_position
);
983 lttv_state_traceset_seek_time_closest(LTTV_TRACESET_STATE(tsc
),
986 /* Process the traceset with only state hooks */
990 lttv_process_traceset_middle(tsc
,
993 events_request
->start_position
);
995 g_assert(lttv_traceset_context_ctx_pos_compare(tsc
,
996 events_request
->start_position
) == 0);
1003 /* 1.3 Add hooks and call before request for all list_in members */
1005 GSList
*iter
= NULL
;
1007 for(iter
=list_in
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
1008 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1009 /* 1.3.1 If !servicing */
1010 if(events_request
->servicing
== FALSE
) {
1011 /* - begin request hooks called
1012 * - servicing = TRUE
1014 lttv_hooks_call(events_request
->before_request
, (gpointer
)tsc
);
1015 events_request
->servicing
= TRUE
;
1017 /* 1.3.2 call before chunk
1018 * 1.3.3 events hooks added
1020 if(events_request
->trace
== -1)
1021 lttv_process_traceset_begin(tsc
,
1022 events_request
->before_chunk_traceset
,
1023 events_request
->before_chunk_trace
,
1024 events_request
->before_chunk_tracefile
,
1025 events_request
->event
,
1026 events_request
->event_by_id_channel
);
1028 guint nb_trace
= lttv_traceset_number(tsc
->ts
);
1029 g_assert((guint
)events_request
->trace
< nb_trace
&&
1030 events_request
->trace
> -1);
1031 LttvTraceContext
*tc
= tsc
->traces
[events_request
->trace
];
1033 lttv_hooks_call(events_request
->before_chunk_traceset
, tsc
);
1035 lttv_trace_context_add_hooks(tc
,
1036 events_request
->before_chunk_trace
,
1037 events_request
->before_chunk_tracefile
,
1038 events_request
->event
,
1039 events_request
->event_by_id_channel
);
1044 /* 2. Else, list_in is not empty, we continue a read */
1047 /* 2.0 For each req of list_in */
1048 GSList
*iter
= list_in
;
1050 while(iter
!= NULL
) {
1052 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1054 /* - Call before chunk
1055 * - events hooks added
1057 if(events_request
->trace
== -1)
1058 lttv_process_traceset_begin(tsc
,
1059 events_request
->before_chunk_traceset
,
1060 events_request
->before_chunk_trace
,
1061 events_request
->before_chunk_tracefile
,
1062 events_request
->event
,
1063 events_request
->event_by_id_channel
);
1065 guint nb_trace
= lttv_traceset_number(tsc
->ts
);
1066 g_assert((guint
)events_request
->trace
< nb_trace
&&
1067 events_request
->trace
> -1);
1068 LttvTraceContext
*tc
= tsc
->traces
[events_request
->trace
];
1070 lttv_hooks_call(events_request
->before_chunk_traceset
, tsc
);
1072 lttv_trace_context_add_hooks(tc
,
1073 events_request
->before_chunk_trace
,
1074 events_request
->before_chunk_tracefile
,
1075 events_request
->event
,
1076 events_request
->event_by_id_channel
);
1079 iter
= g_slist_next(iter
);
1084 tfc
= lttv_traceset_context_get_current_tfc(tsc
);
1086 /* 2.1 For each req of list_out */
1087 GSList
*iter
= list_out
;
1089 while(iter
!= NULL
) {
1091 gboolean remove
= FALSE
;
1092 gboolean free_data
= FALSE
;
1093 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1095 /* if req.start time == current context time
1096 * or req.start position == current position*/
1097 if( ltt_time_compare(events_request
->start_time
,
1098 tfc
->timestamp
) == 0
1100 (events_request
->start_position
!= NULL
1102 lttv_traceset_context_ctx_pos_compare(tsc
,
1103 events_request
->start_position
) == 0)
1105 /* - Add to list_in, remove from list_out */
1106 list_in
= g_slist_append(list_in
, events_request
);
1110 /* - If !servicing */
1111 if(events_request
->servicing
== FALSE
) {
1112 /* - begin request hooks called
1113 * - servicing = TRUE
1115 lttv_hooks_call(events_request
->before_request
, (gpointer
)tsc
);
1116 events_request
->servicing
= TRUE
;
1118 /* call before chunk
1119 * events hooks added
1121 if(events_request
->trace
== -1)
1122 lttv_process_traceset_begin(tsc
,
1123 events_request
->before_chunk_traceset
,
1124 events_request
->before_chunk_trace
,
1125 events_request
->before_chunk_tracefile
,
1126 events_request
->event
,
1127 events_request
->event_by_id_channel
);
1129 guint nb_trace
= lttv_traceset_number(tsc
->ts
);
1130 g_assert((guint
)events_request
->trace
< nb_trace
&&
1131 events_request
->trace
> -1);
1132 LttvTraceContext
*tc
= tsc
->traces
[events_request
->trace
];
1134 lttv_hooks_call(events_request
->before_chunk_traceset
, tsc
);
1136 lttv_trace_context_add_hooks(tc
,
1137 events_request
->before_chunk_trace
,
1138 events_request
->before_chunk_tracefile
,
1139 events_request
->event
,
1140 events_request
->event_by_id_channel
);
1149 GSList
*remove_iter
= iter
;
1151 iter
= g_slist_next(iter
);
1152 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
1153 list_out
= g_slist_remove_link(list_out
, remove_iter
);
1154 } else { // not remove
1155 iter
= g_slist_next(iter
);
1161 /* 3. Find end criterions */
1166 /* 3.1.1 Find lowest end time in list_in */
1167 g_assert(g_slist_length(list_in
)>0);
1168 end_time
= ((EventsRequest
*)g_slist_nth_data(list_in
,0))->end_time
;
1170 for(iter
=g_slist_nth(list_in
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
1171 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1173 if(ltt_time_compare(events_request
->end_time
,
1175 end_time
= events_request
->end_time
;
1178 /* 3.1.2 Find lowest start time in list_out */
1179 for(iter
=list_out
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
1180 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1182 if(ltt_time_compare(events_request
->start_time
,
1184 end_time
= events_request
->start_time
;
1189 /* 3.2 Number of events */
1191 /* 3.2.1 Find lowest number of events in list_in */
1194 end_nb_events
= ((EventsRequest
*)g_slist_nth_data(list_in
,0))->num_events
;
1196 for(iter
=g_slist_nth(list_in
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
1197 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1199 if(events_request
->num_events
< end_nb_events
)
1200 end_nb_events
= events_request
->num_events
;
1203 /* 3.2.2 Use min(CHUNK_NUM_EVENTS, min num events in list_in) as
1206 end_nb_events
= MIN(CHUNK_NUM_EVENTS
, end_nb_events
);
1210 /* 3.3 End position */
1212 /* 3.3.1 Find lowest end position in list_in */
1215 end_position
=((EventsRequest
*)g_slist_nth_data(list_in
,0))->end_position
;
1217 for(iter
=g_slist_nth(list_in
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
1218 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1220 if(events_request
->end_position
!= NULL
&& end_position
!= NULL
&&
1221 lttv_traceset_context_pos_pos_compare(events_request
->end_position
,
1223 end_position
= events_request
->end_position
;
1228 /* 3.3.2 Find lowest start position in list_out */
1231 for(iter
=list_out
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
1232 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1234 if(events_request
->end_position
!= NULL
&& end_position
!= NULL
&&
1235 lttv_traceset_context_pos_pos_compare(events_request
->end_position
,
1237 end_position
= events_request
->end_position
;
1242 /* 4. Call process traceset middle */
1243 g_debug("Calling process traceset middle with %p, %lu sec %lu nsec, %u nb ev, %p end pos", tsc
, end_time
.tv_sec
, end_time
.tv_nsec
, end_nb_events
, end_position
);
1244 count
= lttv_process_traceset_middle(tsc
, end_time
, end_nb_events
, end_position
);
1246 tfc
= lttv_traceset_context_get_current_tfc(tsc
);
1248 g_debug("Context time after middle : %lu, %lu", tfc
->timestamp
.tv_sec
,
1249 tfc
->timestamp
.tv_nsec
);
1251 g_debug("End of trace reached after middle.");
1255 /* 5. After process traceset middle */
1256 tfc
= lttv_traceset_context_get_current_tfc(tsc
);
1258 /* - if current context time > traceset.end time */
1259 if(tfc
== NULL
|| ltt_time_compare(tfc
->timestamp
,
1260 tsc
->time_span
.end_time
) > 0) {
1261 /* - For each req in list_in */
1262 GSList
*iter
= list_in
;
1264 while(iter
!= NULL
) {
1266 gboolean remove
= FALSE
;
1267 gboolean free_data
= FALSE
;
1268 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1270 /* - Remove events hooks for req
1271 * - Call end chunk for req
1274 if(events_request
->trace
== -1)
1275 lttv_process_traceset_end(tsc
,
1276 events_request
->after_chunk_traceset
,
1277 events_request
->after_chunk_trace
,
1278 events_request
->after_chunk_tracefile
,
1279 events_request
->event
,
1280 events_request
->event_by_id_channel
);
1283 guint nb_trace
= lttv_traceset_number(tsc
->ts
);
1284 g_assert(events_request
->trace
< nb_trace
&&
1285 events_request
->trace
> -1);
1286 LttvTraceContext
*tc
= tsc
->traces
[events_request
->trace
];
1288 lttv_trace_context_remove_hooks(tc
,
1289 events_request
->after_chunk_trace
,
1290 events_request
->after_chunk_tracefile
,
1291 events_request
->event
,
1292 events_request
->event_by_id_channel
);
1293 lttv_hooks_call(events_request
->after_chunk_traceset
, tsc
);
1298 /* - Call end request for req */
1299 lttv_hooks_call(events_request
->after_request
, (gpointer
)tsc
);
1301 /* - remove req from list_in */
1302 /* Destroy the request */
1309 GSList
*remove_iter
= iter
;
1311 iter
= g_slist_next(iter
);
1312 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
1313 list_in
= g_slist_remove_link(list_in
, remove_iter
);
1314 } else { // not remove
1315 iter
= g_slist_next(iter
);
1320 /* 5.1 For each req in list_in */
1321 GSList
*iter
= list_in
;
1323 while(iter
!= NULL
) {
1325 gboolean remove
= FALSE
;
1326 gboolean free_data
= FALSE
;
1327 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1329 /* - Remove events hooks for req
1330 * - Call end chunk for req
1332 if(events_request
->trace
== -1)
1333 lttv_process_traceset_end(tsc
,
1334 events_request
->after_chunk_traceset
,
1335 events_request
->after_chunk_trace
,
1336 events_request
->after_chunk_tracefile
,
1337 events_request
->event
,
1338 events_request
->event_by_id_channel
);
1341 guint nb_trace
= lttv_traceset_number(tsc
->ts
);
1342 g_assert(events_request
->trace
< nb_trace
&&
1343 events_request
->trace
> -1);
1344 LttvTraceContext
*tc
= tsc
->traces
[events_request
->trace
];
1346 lttv_trace_context_remove_hooks(tc
,
1347 events_request
->after_chunk_trace
,
1348 events_request
->after_chunk_tracefile
,
1349 events_request
->event
,
1350 events_request
->event_by_id_channel
);
1352 lttv_hooks_call(events_request
->after_chunk_traceset
, tsc
);
1355 /* - req.num -= count */
1356 g_assert(events_request
->num_events
>= count
);
1357 events_request
->num_events
-= count
;
1359 g_assert(tfc
!= NULL
);
1360 /* - if req.num == 0
1362 * current context time >= req.end time
1364 * req.end pos == current pos
1366 * req.stop_flag == TRUE
1368 if( events_request
->num_events
== 0
1370 events_request
->stop_flag
== TRUE
1372 ltt_time_compare(tfc
->timestamp
,
1373 events_request
->end_time
) >= 0
1375 (events_request
->end_position
!= NULL
1377 lttv_traceset_context_ctx_pos_compare(tsc
,
1378 events_request
->end_position
) == 0)
1381 g_assert(events_request
->servicing
== TRUE
);
1382 /* - Call end request for req
1383 * - remove req from list_in */
1384 lttv_hooks_call(events_request
->after_request
, (gpointer
)tsc
);
1385 /* - remove req from list_in */
1386 /* Destroy the request */
1394 GSList
*remove_iter
= iter
;
1396 iter
= g_slist_next(iter
);
1397 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
1398 list_in
= g_slist_remove_link(list_in
, remove_iter
);
1399 } else { // not remove
1400 iter
= g_slist_next(iter
);
1406 /* End of removed servicing loop : leave control to GTK instead. */
1407 // if(gtk_events_pending()) break;
1410 /* B. When interrupted between chunks */
1413 GSList
*iter
= list_in
;
1415 /* 1. for each request in list_in */
1416 while(iter
!= NULL
) {
1418 gboolean remove
= FALSE
;
1419 gboolean free_data
= FALSE
;
1420 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1422 /* 1.1. Use current postition as start position */
1423 if(events_request
->start_position
!= NULL
)
1424 lttv_traceset_context_position_destroy(events_request
->start_position
);
1425 events_request
->start_position
= lttv_traceset_context_position_new(tsc
);
1426 lttv_traceset_context_position_save(tsc
, events_request
->start_position
);
1428 /* 1.2. Remove start time */
1429 events_request
->start_time
= ltt_time_infinite
;
1431 /* 1.3. Move from list_in to list_out */
1434 list_out
= g_slist_append(list_out
, events_request
);
1439 GSList
*remove_iter
= iter
;
1441 iter
= g_slist_next(iter
);
1442 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
1443 list_in
= g_slist_remove_link(list_in
, remove_iter
);
1444 } else { // not remove
1445 iter
= g_slist_next(iter
);
1451 /* C Unlock Traces */
1453 lttv_process_traceset_get_sync_data(tsc
);
1454 //lttv_traceset_context_position_save(tsc, sync_position);
1459 iter_trace
<lttv_traceset_number(tsc
->ts
);
1461 LttvTrace
*trace_v
= lttv_traceset_get(tsc
->ts
, iter_trace
);
1463 lttvwindowtraces_unlock(trace_v
);
1467 //set the cursor back to normal
1468 gdk_window_set_cursor(win
, NULL
);
1471 g_assert(g_slist_length(list_in
) == 0);
1473 if( g_slist_length(list_out
) == 0 ) {
1474 /* Put tab's request pending flag back to normal */
1475 tab
->events_request_pending
= FALSE
;
1476 g_debug("remove the idle fct");
1477 return FALSE
; /* Remove the idle function */
1479 g_debug("leave the idle fct");
1480 return TRUE
; /* Leave the idle function */
1482 /* We do not use simili-round-robin, it may require to read 1 meg buffers
1483 * again and again if many tracesets use the same tracefiles. */
1484 /* Hack for round-robin idle functions */
1485 /* It will put the idle function at the end of the pool */
1486 /*g_idle_add_full((G_PRIORITY_HIGH_IDLE + 21),
1487 (GSourceFunc)execute_events_requests,
1493 #endif /* BABEL_CLEANUP */
1498 Manage the periodic update of a live trace
1501 live_trace_update_handler(Tab
*tab
)
1503 #ifdef BABEL_CLEANUP
1504 unsigned int updated_count
;
1505 LttvTracesetContext
*tsc
= LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
1506 TimeInterval initial_time_span
= tsc
->time_span
;
1507 TimeInterval updated_time_span
;
1509 updated_count
= lttv_process_traceset_update(tsc
);
1511 /* TODO ybrosseau 2011-01-12: Add trace resynchronization */
1513 /* Get the changed period bounds */
1514 updated_time_span
= tsc
->time_span
;
1516 if(ltt_time_compare(updated_time_span
.start_time
,
1517 initial_time_span
.start_time
) != 0) {
1518 /* The initial time should not change on a live update */
1522 /* Notify viewers (only on updates) */
1523 if(ltt_time_compare(updated_time_span
.end_time
,
1524 initial_time_span
.end_time
) != 0) {
1526 notify_time_span_changed(tab
);
1527 /* TODO ybrosseau 2011-01-12: Change the timebar to register
1528 to the time_span hook */
1529 timebar_set_minmax_time(TIMEBAR(tab
->MTimebar
),
1530 &updated_time_span
.start_time
,
1531 &updated_time_span
.end_time
);
1533 /* To update the min max */
1534 time_change_manager(tab
, tab
->time_window
);
1537 /* Timer will be recalled as long as there is files to update */
1538 return (updated_count
> 0);
1539 #endif /* BABEL_CLEANUP */
1542 static void lttvwindow_add_trace(Tab
*tab
, LttvTrace
*trace_v
)
1544 #ifdef BABEL_CLEANUP
1545 LttvTraceset
*traceset
= tab
->traceset_info
->traceset
;
1547 guint num_traces
= lttv_traceset_number(traceset
);
1549 //Verify if trace is already present.
1550 for(i
=0; i
<num_traces
; i
++)
1552 LttvTrace
* trace
= lttv_traceset_get(traceset
, i
);
1553 if(trace
== trace_v
)
1557 //Keep a reference to the traces so they are not freed.
1558 for(i
=0; i
<lttv_traceset_number(traceset
); i
++)
1560 LttvTrace
* trace
= lttv_traceset_get(traceset
, i
);
1561 lttv_trace_ref(trace
);
1564 //remove state update hooks
1565 lttv_state_remove_event_hooks(
1566 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1568 lttv_context_fini(LTTV_TRACESET_CONTEXT(
1569 tab
->traceset_info
->traceset_context
));
1570 g_object_unref(tab
->traceset_info
->traceset_context
);
1572 lttv_traceset_add(traceset
, trace_v
);
1573 lttv_trace_ref(trace_v
); /* local ref */
1575 /* Create new context */
1576 tab
->traceset_info
->traceset_context
=
1577 g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
1579 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->
1584 //add state update hooks
1585 lttv_state_add_event_hooks(
1586 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1587 //Remove local reference to the traces.
1588 for(i
=0; i
<lttv_traceset_number(traceset
); i
++)
1590 LttvTrace
* trace
= lttv_traceset_get(traceset
, i
);
1591 lttv_trace_unref(trace
);
1595 //add_trace_into_traceset_selector(GTK_MULTIVPANED(tab->multivpaned), lttv_trace(trace_v));
1598 if (lttv_trace(trace_v
)->is_live
) {
1599 /* Add timer for live update */
1600 /* TODO ybrosseau 2011-01-12: Parametrize the hardcoded 1 seconds */
1601 g_timeout_add_seconds (1,
1602 (GSourceFunc
) live_trace_update_handler
,
1605 #endif /* BABEL_CLEANUP */
1608 /* add_trace adds a trace into the current traceset. It first displays a
1609 * directory selection dialogue to let user choose a trace, then recreates
1610 * tracset_context, and redraws all the viewer of the current tab
1613 void add_trace(GtkWidget
* widget
, gpointer user_data
)
1616 LttvTraceset
* traceset
= NULL
;
1618 char abs_path
[PATH_MAX
];
1620 MainWindow
* mw_data
= get_window_data_struct(widget
);
1621 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
1623 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
1624 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
1625 LttvPluginTab
*ptab
;
1629 ptab
= create_new_tab(widget
, NULL
);
1632 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
1635 //TODO fdeslauriers 2012-07-06: Remove this popup when we support multiple traces
1636 traceset
= lttvwindow_get_traceset(tab
);
1637 if(traceset
!= NULL
&& lttv_traceset_number(traceset
) > 0){
1638 GtkWidget
*dialogue
=
1639 gtk_message_dialog_new(
1640 GTK_WINDOW(gtk_widget_get_toplevel(widget
)),
1641 GTK_DIALOG_MODAL
|GTK_DIALOG_DESTROY_WITH_PARENT
,
1644 "Loading multiple traces is not supported at the moment.");
1645 gtk_dialog_run(GTK_DIALOG(dialogue
));
1646 gtk_widget_destroy(dialogue
);
1650 /* Create a new traceset*/
1651 traceset
= lttv_traceset_new();
1652 /* File open dialog management */
1653 #ifdef BABEL_CLEANUP
1654 GtkWidget
*extra_live_button
;
1655 #endif //babel_cleanup
1656 GtkFileChooser
* file_chooser
=
1658 gtk_file_chooser_dialog_new ("Select a trace",
1659 GTK_WINDOW(mw_data
->mwindow
),
1660 GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER
,
1661 GTK_STOCK_CANCEL
, GTK_RESPONSE_CANCEL
,
1662 GTK_STOCK_OPEN
, GTK_RESPONSE_ACCEPT
,
1664 #ifdef BABEL_CLEANUP
1665 /* Button to indicate the opening of a live trace */
1666 extra_live_button
= gtk_check_button_new_with_mnemonic ("Trace is live (currently being writen)");
1667 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (extra_live_button
), FALSE
);
1668 gtk_file_chooser_set_extra_widget (GTK_FILE_CHOOSER (file_chooser
), extra_live_button
);
1669 #endif //babel_cleanup
1670 gtk_file_chooser_set_show_hidden (file_chooser
, TRUE
);
1671 if(remember_trace_dir
[0] != '\0')
1672 gtk_file_chooser_set_filename(file_chooser
, remember_trace_dir
);
1674 gboolean closeFileChooserDialog
= TRUE
;
1678 id
= gtk_dialog_run(GTK_DIALOG(file_chooser
));
1680 case GTK_RESPONSE_ACCEPT
:
1681 case GTK_RESPONSE_OK
:
1682 path
= gtk_file_chooser_get_filename (file_chooser
);
1684 strncpy(remember_trace_dir
, path
, PATH_MAX
);
1685 strncat(remember_trace_dir
, "/", PATH_MAX
);
1686 if(!path
|| strlen(path
) == 0){
1689 get_absolute_pathname(path
, abs_path
);
1691 if(lttv_traceset_add_path(traceset
,abs_path
) != 0 ){ /*failure*/
1693 g_warning("cannot open trace %s", abs_path
);
1694 strncpy(remember_trace_dir
, "\0", PATH_MAX
);
1695 GtkWidget
*dialogue
=
1696 gtk_message_dialog_new(
1697 GTK_WINDOW(gtk_widget_get_toplevel(widget
)),
1698 GTK_DIALOG_MODAL
|GTK_DIALOG_DESTROY_WITH_PARENT
,
1701 "Cannot open trace : maybe you should enter in the directory "
1703 gtk_dialog_run(GTK_DIALOG(dialogue
));
1704 gtk_widget_destroy(dialogue
);
1705 closeFileChooserDialog
= FALSE
;
1708 closeFileChooserDialog
= TRUE
;
1709 SetTraceset(tab
, traceset
);
1712 //update current tab
1713 //update_traceset(mw_data);
1715 // in expose now call_pending_read_hooks(mw_data);
1717 //lttvwindow_report_current_time(mw_data,&(tab->current_time));
1719 case GTK_RESPONSE_REJECT
:
1720 case GTK_RESPONSE_CANCEL
:
1722 closeFileChooserDialog
= TRUE
;
1725 }while(!closeFileChooserDialog
);
1727 gtk_widget_destroy((GtkWidget
*)file_chooser
);
1731 /* remove_trace removes a trace from the current traceset if all viewers in
1732 * the current tab are not interested in the trace. It first displays a
1733 * dialogue, which shows all traces in the current traceset, to let user choose
1734 * a trace, then it checks if all viewers unselect the trace, if it is true,
1735 * it will remove the trace, recreate the traceset_contex,
1736 * and redraws all the viewer of the current tab. If there is on trace in the
1737 * current traceset, it will delete all viewers of the current tab
1739 * It destroys the filter tree. FIXME... we should request for an update
1743 void remove_trace(GtkWidget
*widget
, gpointer user_data
)
1745 #ifdef BABEL_CLEANUP
1747 LttvTrace
* trace_v
;
1748 LttvTraceset
* traceset
;
1749 gint i
, j
, nb_trace
, index
=-1;
1750 char ** name
, *remove_trace_name
;
1751 MainWindow
* mw_data
= get_window_data_struct(widget
);
1752 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
1754 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
1755 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
1761 LttvPluginTab
*ptab
;
1762 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
1766 nb_trace
=lttv_traceset_number(tab
->traceset_info
->traceset
);
1767 name
= g_new(char*,nb_trace
);
1768 for(i
= 0; i
< nb_trace
; i
++){
1769 trace_v
= lttv_traceset_get(tab
->traceset_info
->traceset
, i
);
1770 trace
= lttv_trace(trace_v
);
1771 name
[i
] = (char *) g_quark_to_string(ltt_trace_name(trace
));
1774 remove_trace_name
= get_remove_trace(mw_data
, name
, nb_trace
);
1777 if(remove_trace_name
){
1779 /* yuk, cut n paste from old code.. should be better (MD)*/
1780 for(i
= 0; i
<nb_trace
; i
++) {
1781 if(strcmp(remove_trace_name
,name
[i
]) == 0){
1786 traceset
= tab
->traceset_info
->traceset
;
1787 //Keep a reference to the traces so they are not freed.
1788 for(j
=0; j
<lttv_traceset_number(traceset
); j
++)
1790 LttvTrace
* trace
= lttv_traceset_get(traceset
, j
);
1791 lttv_trace_ref(trace
);
1794 //remove state update hooks
1795 lttv_state_remove_event_hooks(
1796 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1797 lttv_context_fini(LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
));
1798 g_object_unref(tab
->traceset_info
->traceset_context
);
1800 trace_v
= lttv_traceset_get(traceset
, index
);
1802 lttv_traceset_remove(traceset
, index
);
1803 lttv_trace_unref(trace_v
); // Remove local reference
1805 if(lttv_trace_get_ref_number(trace_v
) <= 1) {
1806 /* ref 1 : lttvwindowtraces only*/
1807 ltt_trace_close(lttv_trace(trace_v
));
1808 /* lttvwindowtraces_remove_trace takes care of destroying
1809 * the traceset linked with the trace_v and also of destroying
1810 * the trace_v at the same time.
1812 lttvwindowtraces_remove_trace(trace_v
);
1815 tab
->traceset_info
->traceset_context
=
1816 g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
1818 LTTV_TRACESET_CONTEXT(tab
->
1819 traceset_info
->traceset_context
),traceset
);
1820 //add state update hooks
1821 lttv_state_add_event_hooks(
1822 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1824 //Remove local reference to the traces.
1825 for(j
=0; j
<lttv_traceset_number(traceset
); j
++)
1827 LttvTrace
* trace
= lttv_traceset_get(traceset
, j
);
1828 lttv_trace_unref(trace
);
1831 SetTraceset(tab
, (gpointer
)traceset
);
1834 #endif /* BABEL_CLEANUP */
1838 void remove_trace(GtkWidget
* widget
, gpointer user_data
)
1841 LttvTrace
* trace_v
;
1842 LttvTraceset
* traceset
;
1843 gint i
, j
, nb_trace
;
1844 char ** name
, *remove_trace_name
;
1845 MainWindow
* mw_data
= get_window_data_struct(widget
);
1846 LttvTracesetSelector
* s
;
1847 LttvTraceSelector
* t
;
1850 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
1852 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
1853 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
1859 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
1862 nb_trace
=lttv_traceset_number(tab
->traceset_info
->traceset
);
1863 name
= g_new(char*,nb_trace
);
1864 for(i
= 0; i
< nb_trace
; i
++){
1865 trace_v
= lttv_traceset_get(tab
->traceset_info
->traceset
, i
);
1866 trace
= lttv_trace(trace_v
);
1867 name
[i
] = ltt_trace_name(trace
);
1870 remove_trace_name
= get_remove_trace(name
, nb_trace
);
1872 if(remove_trace_name
){
1873 for(i
=0; i
<nb_trace
; i
++){
1874 if(strcmp(remove_trace_name
,name
[i
]) == 0){
1875 //unselect the trace from the current viewer
1877 w
= gtk_multivpaned_get_widget(GTK_MULTIVPANED(tab
->multivpaned
));
1879 s
= g_object_get_data(G_OBJECT(w
), "Traceset_Selector");
1881 t
= lttv_traceset_selector_trace_get(s
,i
);
1882 lttv_trace_selector_set_selected(t
, FALSE
);
1885 //check if other viewers select the trace
1886 w
= gtk_multivpaned_get_first_widget(GTK_MULTIVPANED(tab
->multivpaned
));
1888 s
= g_object_get_data(G_OBJECT(w
), "Traceset_Selector");
1890 t
= lttv_traceset_selector_trace_get(s
,i
);
1891 selected
= lttv_trace_selector_get_selected(t
);
1894 w
= gtk_multivpaned_get_next_widget(GTK_MULTIVPANED(tab
->multivpaned
));
1896 }else selected
= FALSE
;
1898 //if no viewer selects the trace, remove it
1900 remove_trace_from_traceset_selector(GTK_MULTIVPANED(tab
->multivpaned
), i
);
1902 traceset
= tab
->traceset_info
->traceset
;
1903 //Keep a reference to the traces so they are not freed.
1904 for(j
=0; j
<lttv_traceset_number(traceset
); j
++)
1906 LttvTrace
* trace
= lttv_traceset_get(traceset
, j
);
1907 lttv_trace_ref(trace
);
1910 //remove state update hooks
1911 lttv_state_remove_event_hooks(
1912 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1913 lttv_context_fini(LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
));
1914 g_object_unref(tab
->traceset_info
->traceset_context
);
1917 trace_v
= lttv_traceset_get(traceset
, i
);
1919 if(lttv_trace_get_ref_number(trace_v
) <= 2) {
1920 /* ref 2 : traceset, local */
1921 lttvwindowtraces_remove_trace(trace_v
);
1922 ltt_trace_close(lttv_trace(trace_v
));
1925 lttv_traceset_remove(traceset
, i
);
1926 lttv_trace_unref(trace_v
); // Remove local reference
1928 if(!lttv_trace_get_ref_number(trace_v
))
1929 lttv_trace_destroy(trace_v
);
1931 tab
->traceset_info
->traceset_context
=
1932 g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
1934 LTTV_TRACESET_CONTEXT(tab
->
1935 traceset_info
->traceset_context
),traceset
);
1936 //add state update hooks
1937 lttv_state_add_event_hooks(
1938 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1940 //Remove local reference to the traces.
1941 for(j
=0; j
<lttv_traceset_number(traceset
); j
++)
1943 LttvTrace
* trace
= lttv_traceset_get(traceset
, j
);
1944 lttv_trace_unref(trace
);
1948 //update current tab
1949 //update_traceset(mw_data);
1952 SetTraceset(tab
, (gpointer
)traceset
);
1953 // in expose now call_pending_read_hooks(mw_data);
1955 //lttvwindow_report_current_time(mw_data,&(tab->current_time));
1958 // while(tab->multi_vpaned->num_children){
1959 // gtk_multi_vpaned_widget_delete(tab->multi_vpaned);
1973 /* Redraw all the viewers in the current tab */
1974 void redraw(GtkWidget
*widget
, gpointer user_data
)
1976 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
1977 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
1978 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
1985 LttvPluginTab
*ptab
;
1986 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
1991 LttvAttributeValue value
;
1993 retval
= lttv_iattribute_find_by_path(tab
->attributes
, "hooks/redraw", LTTV_POINTER
, &value
);
1996 tmp
= (LttvHooks
*)*(value
.v_pointer
);
1998 lttv_hooks_call(tmp
,NULL
);
2002 void continue_processing(GtkWidget
*widget
, gpointer user_data
)
2004 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
2005 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2006 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2013 LttvPluginTab
*ptab
;
2014 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
2019 LttvAttributeValue value
;
2021 retval
= lttv_iattribute_find_by_path(tab
->attributes
, "hooks/continue",
2022 LTTV_POINTER
, &value
);
2025 tmp
= (LttvHooks
*)*(value
.v_pointer
);
2027 lttv_hooks_call(tmp
,NULL
);
2030 /* Stop the processing for the calling main window's current tab.
2031 * It removes every processing requests that are in its list. It does not call
2032 * the end request hooks, because the request is not finished.
2035 void stop_processing(GtkWidget
*widget
, gpointer user_data
)
2037 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
2038 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2039 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2044 LttvPluginTab
*ptab
;
2045 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
2048 GSList
*iter
= tab
->events_requests
;
2050 while(iter
!= NULL
) {
2051 GSList
*remove_iter
= iter
;
2052 iter
= g_slist_next(iter
);
2054 g_free(remove_iter
->data
);
2055 tab
->events_requests
=
2056 g_slist_remove_link(tab
->events_requests
, remove_iter
);
2058 tab
->events_request_pending
= FALSE
;
2059 tab
->stop_foreground
= TRUE
;
2060 g_idle_remove_by_data(tab
);
2061 g_assert(g_slist_length(tab
->events_requests
) == 0);
2065 /* save will save the traceset to a file
2066 * Not implemented yet FIXME
2069 void save(GtkWidget
* widget
, gpointer user_data
)
2074 void save_as(GtkWidget
* widget
, gpointer user_data
)
2076 g_info("Save as\n");
2080 /* zoom will change the time_window of all the viewers of the
2081 * current tab, and redisplay them. The main functionality is to
2082 * determine the new time_window of the current tab
2085 void zoom(GtkWidget
* widget
, double size
)
2087 #ifdef BABEL_CLEANUP
2088 TimeInterval time_span
;
2089 TimeWindow new_time_window
;
2090 LttTime current_time
, time_delta
;
2091 LttvTracesetContext
*tsc
;
2092 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
2094 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2095 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2101 LttvPluginTab
*ptab
;
2102 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
2106 if(size
== 1) return;
2108 tsc
= LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
2109 time_span
= tsc
->time_span
;
2110 new_time_window
= tab
->time_window
;
2111 current_time
= tab
->current_time
;
2113 time_delta
= ltt_time_sub(time_span
.end_time
,time_span
.start_time
);
2115 new_time_window
.start_time
= time_span
.start_time
;
2116 new_time_window
.time_width
= time_delta
;
2117 new_time_window
.time_width_double
= ltt_time_to_double(time_delta
);
2118 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
2119 new_time_window
.time_width
) ;
2121 new_time_window
.time_width
= ltt_time_div(new_time_window
.time_width
, size
);
2122 new_time_window
.time_width_double
=
2123 ltt_time_to_double(new_time_window
.time_width
);
2124 if(ltt_time_compare(new_time_window
.time_width
,time_delta
) > 0)
2125 { /* Case where zoom out is bigger than trace length */
2126 new_time_window
.start_time
= time_span
.start_time
;
2127 new_time_window
.time_width
= time_delta
;
2128 new_time_window
.time_width_double
= ltt_time_to_double(time_delta
);
2129 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
2130 new_time_window
.time_width
) ;
2134 /* Center the image on the current time */
2135 new_time_window
.start_time
=
2136 ltt_time_sub(current_time
,
2137 ltt_time_from_double(new_time_window
.time_width_double
/2.0));
2138 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
2139 new_time_window
.time_width
) ;
2140 /* If on borders, don't fall off */
2141 if(ltt_time_compare(new_time_window
.start_time
, time_span
.start_time
) <0
2142 || ltt_time_compare(new_time_window
.start_time
, time_span
.end_time
) >0)
2144 new_time_window
.start_time
= time_span
.start_time
;
2145 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
2146 new_time_window
.time_width
) ;
2150 if(ltt_time_compare(new_time_window
.end_time
,
2151 time_span
.end_time
) > 0
2152 || ltt_time_compare(new_time_window
.end_time
,
2153 time_span
.start_time
) < 0)
2155 new_time_window
.start_time
=
2156 ltt_time_sub(time_span
.end_time
, new_time_window
.time_width
);
2158 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
2159 new_time_window
.time_width
) ;
2166 if(ltt_time_compare(new_time_window
.time_width
, ltt_time_zero
) == 0) {
2167 g_warning("Zoom more than 1 ns impossible");
2169 time_change_manager(tab
, new_time_window
);
2172 #endif /* BABEL_CLEANUP */
2175 void zoom_in(GtkWidget
* widget
, gpointer user_data
)
2180 void zoom_out(GtkWidget
* widget
, gpointer user_data
)
2185 void zoom_extended(GtkWidget
* widget
, gpointer user_data
)
2190 void go_to_time(GtkWidget
* widget
, gpointer user_data
)
2192 g_info("Go to time\n");
2195 void show_time_frame(GtkWidget
* widget
, gpointer user_data
)
2197 g_info("Show time frame\n");
2201 /* callback function */
2204 on_empty_traceset_activate (GtkMenuItem
*menuitem
,
2207 create_new_window((GtkWidget
*)menuitem
, user_data
, FALSE
);
2212 on_clone_traceset_activate (GtkMenuItem
*menuitem
,
2215 create_new_window((GtkWidget
*)menuitem
, user_data
, TRUE
);
2219 /* create_new_tab calls create_tab to construct a new tab in the main window
2222 LttvPluginTab
*create_new_tab(GtkWidget
* widget
, gpointer user_data
)
2224 gchar label
[PATH_MAX
];
2225 MainWindow
* mw_data
= get_window_data_struct(widget
);
2227 GtkNotebook
* notebook
= (GtkNotebook
*)lookup_widget(widget
, "MNotebook");
2228 if(notebook
== NULL
){
2229 g_info("Notebook does not exist\n");
2232 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2233 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2239 LttvPluginTab
*ptab
;
2240 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
2241 copy_tab
= ptab
->tab
;
2244 strcpy(label
,"Page");
2245 if(get_label(mw_data
, label
,"Get the name of the tab","Please input tab's name")) {
2246 LttvPluginTab
*ptab
;
2248 ptab
= g_object_new(LTTV_TYPE_PLUGIN_TAB
, NULL
);
2249 init_tab (ptab
->tab
, mw_data
, copy_tab
, notebook
, label
);
2250 ptab
->parent
.top_widget
= ptab
->tab
->top_widget
;
2251 g_object_set_data_full(
2252 G_OBJECT(ptab
->tab
->vbox
),
2255 (GDestroyNotify
)tab_destructor
);
2262 on_tab_activate (GtkMenuItem
*menuitem
,
2265 create_new_tab((GtkWidget
*)menuitem
, user_data
);
2270 on_open_activate (GtkMenuItem
*menuitem
,
2273 #ifdef UNFINISHED_FEATURE
2274 open_traceset((GtkWidget
*)menuitem
, user_data
);
2280 on_close_activate (GtkMenuItem
*menuitem
,
2283 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2284 main_window_destructor(mw_data
);
2288 /* remove the current tab from the main window
2292 on_close_tab_activate (GtkWidget
*widget
,
2296 GtkWidget
* notebook
;
2297 notebook
= lookup_widget(widget
, "MNotebook");
2298 if(notebook
== NULL
){
2299 g_info("Notebook does not exist\n");
2303 page_num
= gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
));
2305 gtk_notebook_remove_page(GTK_NOTEBOOK(notebook
), page_num
);
2310 on_close_tab_X_clicked (GtkWidget
*widget
,
2314 GtkWidget
*notebook
= lookup_widget(widget
, "MNotebook");
2315 if(notebook
== NULL
){
2316 g_info("Notebook does not exist\n");
2320 if((page_num
= gtk_notebook_page_num(GTK_NOTEBOOK(notebook
), widget
)) != -1)
2321 gtk_notebook_remove_page(GTK_NOTEBOOK(notebook
), page_num
);
2327 on_add_trace_activate (GtkMenuItem
*menuitem
,
2330 add_trace((GtkWidget
*)menuitem
, user_data
);
2335 on_remove_trace_activate (GtkMenuItem
*menuitem
,
2338 remove_trace((GtkWidget
*)menuitem
, user_data
);
2343 on_save_activate (GtkMenuItem
*menuitem
,
2346 save((GtkWidget
*)menuitem
, user_data
);
2351 on_save_as_activate (GtkMenuItem
*menuitem
,
2354 save_as((GtkWidget
*)menuitem
, user_data
);
2359 on_quit_activate (GtkMenuItem
*menuitem
,
2362 while (g_slist_length(g_main_window_list
) != 0) {
2363 on_MWindow_destroy(((MainWindow
*)g_main_window_list
->data
)->mwindow
,
2370 on_cut_activate (GtkMenuItem
*menuitem
,
2378 on_copy_activate (GtkMenuItem
*menuitem
,
2386 on_paste_activate (GtkMenuItem
*menuitem
,
2394 on_delete_activate (GtkMenuItem
*menuitem
,
2402 on_zoom_in_activate (GtkMenuItem
*menuitem
,
2405 zoom_in((GtkWidget
*)menuitem
, user_data
);
2410 on_zoom_out_activate (GtkMenuItem
*menuitem
,
2413 zoom_out((GtkWidget
*)menuitem
, user_data
);
2418 on_zoom_extended_activate (GtkMenuItem
*menuitem
,
2421 zoom_extended((GtkWidget
*)menuitem
, user_data
);
2426 on_go_to_time_activate (GtkMenuItem
*menuitem
,
2429 go_to_time((GtkWidget
*)menuitem
, user_data
);
2434 on_show_time_frame_activate (GtkMenuItem
*menuitem
,
2437 show_time_frame((GtkWidget
*)menuitem
, user_data
);
2442 on_move_viewer_up_activate (GtkMenuItem
*menuitem
,
2445 move_up_viewer((GtkWidget
*)menuitem
, user_data
);
2450 on_move_viewer_down_activate (GtkMenuItem
*menuitem
,
2453 move_down_viewer((GtkWidget
*)menuitem
, user_data
);
2458 on_remove_viewer_activate (GtkMenuItem
*menuitem
,
2461 delete_viewer((GtkWidget
*)menuitem
, user_data
);
2465 on_trace_facility_activate (GtkMenuItem
*menuitem
,
2468 g_info("Trace facility selector: %s\n", "");
2472 /* Dispaly a file selection dialogue to let user select a library, then call
2473 * lttv_library_load().
2477 on_load_library_activate (GtkMenuItem
*menuitem
,
2480 GError
*error
= NULL
;
2481 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2483 gchar load_module_path_alter
[PATH_MAX
];
2487 gchar
*load_module_path
;
2488 name
= g_ptr_array_new();
2489 nb
= lttv_library_path_number();
2490 /* ask for the library path */
2494 path
= lttv_library_path_get(i
);
2495 g_ptr_array_add(name
, path
);
2498 load_module_path
= get_selection(mw_data
,
2499 (char **)(name
->pdata
), name
->len
,
2500 "Select a library path", "Library paths");
2501 if(load_module_path
!= NULL
)
2502 strncpy(load_module_path_alter
, load_module_path
, PATH_MAX
-1); // -1 for /
2504 g_ptr_array_free(name
, TRUE
);
2506 if(load_module_path
== NULL
) return;
2510 /* Make sure the module path ends with a / */
2511 gchar
*ptr
= load_module_path_alter
;
2513 ptr
= strchr(ptr
, '\0');
2515 if(*(ptr
-1) != '/') {
2522 /* Ask for the library to load : list files in the previously selected
2524 gchar str
[PATH_MAX
];
2527 GtkFileSelection
* file_selector
=
2528 (GtkFileSelection
*)gtk_file_selection_new("Select a module");
2529 gtk_file_selection_set_filename(file_selector
, load_module_path_alter
);
2530 gtk_file_selection_hide_fileop_buttons(file_selector
);
2532 gtk_window_set_transient_for(GTK_WINDOW(file_selector
),
2533 GTK_WINDOW(mw_data
->mwindow
));
2536 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
2538 case GTK_RESPONSE_ACCEPT
:
2539 case GTK_RESPONSE_OK
:
2540 dir
= gtk_file_selection_get_selections (file_selector
);
2541 strncpy(str
,dir
[0],PATH_MAX
);
2542 strncpy(remember_plugins_dir
,dir
[0],PATH_MAX
);
2543 /* only keep file name */
2545 str1
= strrchr(str
,'/');
2548 str1
= strrchr(str
,'\\');
2553 if(*str1
== 'l' && *(str1
+1)== 'i' && *(str1
+2)=='b')
2555 remove info after
. */
2559 str2
= strrchr(str2
, '.');
2560 if(str2
!= NULL
) *str2
= '\0';
2562 lttv_module_require(str1
, &error
);
2564 lttv_library_load(str1
, &error
);
2565 if(error
!= NULL
) g_warning("%s", error
->message
);
2566 else g_info("Load library: %s\n", str
);
2568 case GTK_RESPONSE_REJECT
:
2569 case GTK_RESPONSE_CANCEL
:
2571 gtk_widget_destroy((GtkWidget
*)file_selector
);
2582 /* Display all loaded modules, let user to select a module to unload
2583 * by calling lttv_module_unload
2587 on_unload_library_activate (GtkMenuItem
*menuitem
,
2590 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2592 LttvLibrary
*library
= NULL
;
2597 name
= g_ptr_array_new();
2598 nb
= lttv_library_number();
2599 LttvLibraryInfo
*lib_info
= g_new(LttvLibraryInfo
,nb
);
2600 /* ask for the library name */
2603 LttvLibrary
*iter_lib
= lttv_library_get(i
);
2604 lttv_library_info(iter_lib
, &lib_info
[i
]);
2606 gchar
*path
= lib_info
[i
].name
;
2607 g_ptr_array_add(name
, path
);
2609 lib_name
= get_selection(mw_data
, (char **)(name
->pdata
), name
->len
,
2610 "Select a library", "Libraries");
2611 if(lib_name
!= NULL
) {
2613 if(strcmp(lib_name
, lib_info
[i
].name
) == 0) {
2614 library
= lttv_library_get(i
);
2619 g_ptr_array_free(name
, TRUE
);
2622 if(lib_name
== NULL
) return;
2624 if(library
!= NULL
) lttv_library_unload(library
);
2628 /* Dispaly a file selection dialogue to let user select a module, then call
2629 * lttv_module_require().
2633 on_load_module_activate (GtkMenuItem
*menuitem
,
2636 GError
*error
= NULL
;
2637 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2639 LttvLibrary
*library
= NULL
;
2644 name
= g_ptr_array_new();
2645 nb
= lttv_library_number();
2646 LttvLibraryInfo
*lib_info
= g_new(LttvLibraryInfo
,nb
);
2647 /* ask for the library name */
2650 LttvLibrary
*iter_lib
= lttv_library_get(i
);
2651 lttv_library_info(iter_lib
, &lib_info
[i
]);
2653 gchar
*path
= lib_info
[i
].name
;
2654 g_ptr_array_add(name
, path
);
2656 lib_name
= get_selection(mw_data
,(char **)(name
->pdata
), name
->len
,
2657 "Select a library", "Libraries");
2658 if(lib_name
!= NULL
) {
2660 if(strcmp(lib_name
, lib_info
[i
].name
) == 0) {
2661 library
= lttv_library_get(i
);
2666 g_ptr_array_free(name
, TRUE
);
2669 if(lib_name
== NULL
) return;
2672 //LttvModule *module;
2673 gchar module_name_out
[PATH_MAX
];
2675 /* Ask for the module to load : list modules in the selected lib */
2679 nb
= lttv_library_module_number(library
);
2680 LttvModuleInfo
*module_info
= g_new(LttvModuleInfo
,nb
);
2681 name
= g_ptr_array_new();
2682 /* ask for the module name */
2685 LttvModule
*iter_module
= lttv_library_module_get(library
, i
);
2686 lttv_module_info(iter_module
, &module_info
[i
]);
2688 gchar
*path
= module_info
[i
].name
;
2689 g_ptr_array_add(name
, path
);
2691 module_name
= get_selection(mw_data
, (char **)(name
->pdata
), name
->len
,
2692 "Select a module", "Modules");
2693 if(module_name
!= NULL
) {
2695 if(strcmp(module_name
, module_info
[i
].name
) == 0) {
2696 strncpy(module_name_out
, module_name
, PATH_MAX
);
2697 //module = lttv_library_module_get(i);
2703 g_ptr_array_free(name
, TRUE
);
2704 g_free(module_info
);
2706 if(module_name
== NULL
) return;
2709 lttv_module_require(module_name_out
, &error
);
2710 if(error
!= NULL
) g_warning("%s", error
->message
);
2711 else g_info("Load module: %s", module_name_out
);
2718 gchar str
[PATH_MAX
];
2721 GtkFileSelection
* file_selector
=
2722 (GtkFileSelection
*)gtk_file_selection_new("Select a module");
2723 gtk_file_selection_set_filename(file_selector
, load_module_path_alter
);
2724 gtk_file_selection_hide_fileop_buttons(file_selector
);
2727 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
2729 case GTK_RESPONSE_ACCEPT
:
2730 case GTK_RESPONSE_OK
:
2731 dir
= gtk_file_selection_get_selections (file_selector
);
2732 strncpy(str
,dir
[0],PATH_MAX
);
2733 strncpy(remember_plugins_dir
,dir
[0],PATH_MAX
);
2735 /* only keep file name */
2737 str1
= strrchr(str
,'/');
2740 str1
= strrchr(str
,'\\');
2745 if(*str1
== 'l' && *(str1
+1)== 'i' && *(str1
+2)=='b')
2747 remove info after
. */
2751 str2
= strrchr(str2
, '.');
2752 if(str2
!= NULL
) *str2
= '\0';
2754 lttv_module_require(str1
, &error
);
2756 lttv_library_load(str1
, &error
);
2757 if(error
!= NULL
) g_warning(error
->message
);
2758 else g_info("Load library: %s\n", str
);
2760 case GTK_RESPONSE_REJECT
:
2761 case GTK_RESPONSE_CANCEL
:
2763 gtk_widget_destroy((GtkWidget
*)file_selector
);
2775 /* Display all loaded modules, let user to select a module to unload
2776 * by calling lttv_module_unload
2780 on_unload_module_activate (GtkMenuItem
*menuitem
,
2783 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2785 LttvLibrary
*library
= NULL
;
2790 name
= g_ptr_array_new();
2791 nb
= lttv_library_number();
2792 LttvLibraryInfo
*lib_info
= g_new(LttvLibraryInfo
,nb
);
2793 /* ask for the library name */
2796 LttvLibrary
*iter_lib
= lttv_library_get(i
);
2797 lttv_library_info(iter_lib
, &lib_info
[i
]);
2799 gchar
*path
= lib_info
[i
].name
;
2800 g_ptr_array_add(name
, path
);
2802 lib_name
= get_selection(mw_data
, (char **)(name
->pdata
), name
->len
,
2803 "Select a library", "Libraries");
2804 if(lib_name
!= NULL
) {
2806 if(strcmp(lib_name
, lib_info
[i
].name
) == 0) {
2807 library
= lttv_library_get(i
);
2812 g_ptr_array_free(name
, TRUE
);
2815 if(lib_name
== NULL
) return;
2818 LttvModule
*module
= NULL
;
2820 /* Ask for the module to load : list modules in the selected lib */
2824 nb
= lttv_library_module_number(library
);
2825 LttvModuleInfo
*module_info
= g_new(LttvModuleInfo
,nb
);
2826 name
= g_ptr_array_new();
2827 /* ask for the module name */
2830 LttvModule
*iter_module
= lttv_library_module_get(library
, i
);
2831 lttv_module_info(iter_module
, &module_info
[i
]);
2833 gchar
*path
= module_info
[i
].name
;
2834 if(module_info
[i
].use_count
> 0) g_ptr_array_add(name
, path
);
2836 module_name
= get_selection(mw_data
, (char **)(name
->pdata
), name
->len
,
2837 "Select a module", "Modules");
2838 if(module_name
!= NULL
) {
2840 if(strcmp(module_name
, module_info
[i
].name
) == 0) {
2841 module
= lttv_library_module_get(library
, i
);
2847 g_ptr_array_free(name
, TRUE
);
2848 g_free(module_info
);
2850 if(module_name
== NULL
) return;
2853 LttvModuleInfo module_info
;
2854 lttv_module_info(module
, &module_info
);
2855 g_info("Release module: %s\n", module_info
.name
);
2857 lttv_module_release(module
);
2861 /* Display a directory dialogue to let user select a path for library searching
2865 on_add_library_search_path_activate (GtkMenuItem
*menuitem
,
2868 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2869 //GtkDirSelection * file_selector = (GtkDirSelection *)gtk_dir_selection_new("Select library path");
2870 GtkFileSelection
* file_selector
= (GtkFileSelection
*)gtk_file_selection_new("Select a trace");
2871 gtk_widget_hide( (file_selector
)->file_list
->parent
) ;
2873 gtk_window_set_transient_for(GTK_WINDOW(file_selector
),
2874 GTK_WINDOW(mw_data
->mwindow
));
2879 if(remember_plugins_dir
[0] != '\0')
2880 gtk_file_selection_set_filename(file_selector
, remember_plugins_dir
);
2882 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
2884 case GTK_RESPONSE_ACCEPT
:
2885 case GTK_RESPONSE_OK
:
2886 dir
= gtk_file_selection_get_filename (file_selector
);
2887 strncpy(remember_plugins_dir
,dir
,PATH_MAX
);
2888 strncat(remember_plugins_dir
,"/",PATH_MAX
);
2889 lttv_library_path_add(dir
);
2890 case GTK_RESPONSE_REJECT
:
2891 case GTK_RESPONSE_CANCEL
:
2893 gtk_widget_destroy((GtkWidget
*)file_selector
);
2899 /* Display a directory dialogue to let user select a path for library searching
2903 on_remove_library_search_path_activate (GtkMenuItem
*menuitem
,
2906 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2908 const char *lib_path
;
2912 name
= g_ptr_array_new();
2913 nb
= lttv_library_path_number();
2914 /* ask for the library name */
2917 gchar
*path
= lttv_library_path_get(i
);
2918 g_ptr_array_add(name
, path
);
2920 lib_path
= get_selection(mw_data
, (char **)(name
->pdata
), name
->len
,
2921 "Select a library path", "Library paths");
2923 g_ptr_array_free(name
, TRUE
);
2925 if(lib_path
== NULL
) return;
2928 lttv_library_path_remove(lib_path
);
2932 on_color_activate (GtkMenuItem
*menuitem
,
2940 on_save_configuration_activate (GtkMenuItem
*menuitem
,
2943 g_info("Save configuration\n");
2948 on_content_activate (GtkMenuItem
*menuitem
,
2951 char* filename
= NULL
,
2954 const char* relativePath
= "doc/user/user_guide/html/index.html";
2955 filename
= g_build_filename (g_get_current_dir(), relativePath
, NULL
);
2956 path
= g_strdup_printf ("ghelp://%s", filename
);
2958 screen
= gdk_screen_get_default();
2959 gtk_show_uri (screen
, path
, gtk_get_current_event_time(), NULL
);
2963 g_info("Content\n");
2968 on_about_close_activate (GtkButton
*button
,
2971 GtkWidget
*about_widget
= GTK_WIDGET(user_data
);
2973 gtk_widget_destroy(about_widget
);
2977 on_about_activate (GtkMenuItem
*menuitem
,
2980 MainWindow
*main_window
= get_window_data_struct(GTK_WIDGET(menuitem
));
2981 GtkWidget
*window_widget
= main_window
->mwindow
;
2982 GtkWidget
*about_widget
= gtk_window_new(GTK_WINDOW_TOPLEVEL
);
2983 GtkWindow
*about_window
= GTK_WINDOW(about_widget
);
2985 gtk_window_set_title(about_window
, "About Linux Trace Toolkit");
2987 gtk_window_set_resizable(about_window
, FALSE
);
2988 gtk_window_set_transient_for(about_window
, GTK_WINDOW(window_widget
));
2989 gtk_window_set_destroy_with_parent(about_window
, TRUE
);
2990 gtk_window_set_modal(about_window
, FALSE
);
2992 /* Put the about window at the center of the screen */
2993 gtk_window_set_position(about_window
, GTK_WIN_POS_CENTER_ALWAYS
);
2995 GtkWidget
*vbox
= gtk_vbox_new(FALSE
, 1);
2997 gtk_container_add(GTK_CONTAINER(about_widget
), vbox
);
3000 GtkWidget
*label1
= gtk_label_new("");
3001 gtk_misc_set_padding(GTK_MISC(label1
), 10, 20);
3002 gtk_label_set_markup(GTK_LABEL(label1
), "\
3003 <big>Linux Trace Toolkit " VERSION
"</big>");
3004 gtk_label_set_justify(GTK_LABEL(label1
), GTK_JUSTIFY_CENTER
);
3006 GtkWidget
*label2
= gtk_label_new("");
3007 gtk_misc_set_padding(GTK_MISC(label2
), 10, 20);
3008 gtk_label_set_markup(GTK_LABEL(label2
), "\
3011 Michel Dagenais (New trace format, lttv main)\n\
3012 Mathieu Desnoyers (Kernel Tracer, Directory structure, build with automake/conf,\n\
3013 lttv gui, control flow view, gui cooperative trace reading\n\
3014 scheduler with interruptible foreground and background\n\
3015 computation, detailed event list (rewrite), trace reading\n\
3016 library (rewrite))\n\
3017 Benoit Des Ligneris, Eric Clement (Cluster adaptation, work in progress)\n\
3018 Xang-Xiu Yang (new trace reading library and converter, lttv gui, \n\
3019 detailed event list and statistics view)\n\
3020 Tom Zanussi (RelayFS)\n\
3022 Inspired from the original Linux Trace Toolkit Visualizer made by\n\
3025 GtkWidget
*label3
= gtk_label_new("");
3026 gtk_label_set_markup(GTK_LABEL(label3
), "\
3027 Linux Trace Toolkit Viewer, Copyright (C) 2004, 2005, 2006\n\
3029 Mathieu Desnoyers\n\
3031 Linux Trace Toolkit comes with ABSOLUTELY NO WARRANTY.\n\
3032 This is free software, and you are welcome to redistribute it\n\
3033 under certain conditions. See COPYING for details.");
3034 gtk_misc_set_padding(GTK_MISC(label3
), 10, 20);
3036 gtk_box_pack_start_defaults(GTK_BOX(vbox
), label1
);
3037 gtk_box_pack_start_defaults(GTK_BOX(vbox
), label2
);
3038 gtk_box_pack_start_defaults(GTK_BOX(vbox
), label3
);
3040 GtkWidget
*hbox
= gtk_hbox_new(TRUE
, 0);
3041 gtk_box_pack_end(GTK_BOX(vbox
), hbox
, FALSE
, FALSE
, 0);
3042 GtkWidget
*close_button
= gtk_button_new_with_mnemonic("_Close");
3043 gtk_box_pack_end(GTK_BOX(hbox
), close_button
, FALSE
, FALSE
, 0);
3044 gtk_container_set_border_width(GTK_CONTAINER(close_button
), 20);
3046 g_signal_connect(G_OBJECT(close_button
), "clicked",
3047 G_CALLBACK(on_about_close_activate
),
3048 (gpointer
)about_widget
);
3050 gtk_widget_show_all(about_widget
);
3055 on_button_new_clicked (GtkButton
*button
,
3058 create_new_window((GtkWidget
*)button
, user_data
, TRUE
);
3062 on_button_new_tab_clicked (GtkButton
*button
,
3065 create_new_tab((GtkWidget
*)button
, user_data
);
3069 on_button_open_clicked (GtkButton
*button
,
3072 #ifdef UNFINISHED_FEATURE
3073 open_traceset((GtkWidget
*)button
, user_data
);
3079 on_button_add_trace_clicked (GtkButton
*button
,
3082 add_trace((GtkWidget
*)button
, user_data
);
3087 on_button_remove_trace_clicked (GtkButton
*button
,
3090 remove_trace((GtkWidget
*)button
, user_data
);
3094 on_button_redraw_clicked (GtkButton
*button
,
3097 redraw((GtkWidget
*)button
, user_data
);
3101 on_button_continue_processing_clicked (GtkButton
*button
,
3104 continue_processing((GtkWidget
*)button
, user_data
);
3108 on_button_stop_processing_clicked (GtkButton
*button
,
3111 stop_processing((GtkWidget
*)button
, user_data
);
3117 on_button_save_clicked (GtkButton
*button
,
3120 save((GtkWidget
*)button
, user_data
);
3125 on_button_save_as_clicked (GtkButton
*button
,
3128 save_as((GtkWidget
*)button
, user_data
);
3133 on_button_zoom_in_clicked (GtkButton
*button
,
3136 zoom_in((GtkWidget
*)button
, user_data
);
3141 on_button_zoom_out_clicked (GtkButton
*button
,
3144 zoom_out((GtkWidget
*)button
, user_data
);
3149 on_button_zoom_extended_clicked (GtkButton
*button
,
3152 zoom_extended((GtkWidget
*)button
, user_data
);
3157 on_button_go_to_time_clicked (GtkButton
*button
,
3160 go_to_time((GtkWidget
*)button
, user_data
);
3165 on_button_show_time_frame_clicked (GtkButton
*button
,
3168 show_time_frame((GtkWidget
*)button
, user_data
);
3173 on_button_move_up_clicked (GtkButton
*button
,
3176 move_up_viewer((GtkWidget
*)button
, user_data
);
3181 on_button_move_down_clicked (GtkButton
*button
,
3184 move_down_viewer((GtkWidget
*)button
, user_data
);
3189 on_button_delete_viewer_clicked (GtkButton
*button
,
3192 delete_viewer((GtkWidget
*)button
, user_data
);
3196 on_MWindow_destroy (GtkWidget
*widget
,
3199 MainWindow
*main_window
= get_window_data_struct(widget
);
3200 LttvIAttribute
*attributes
= main_window
->attributes
;
3201 LttvAttributeValue value
;
3204 //This is unnecessary, since widgets will be destroyed
3205 //by the main window widget anyway.
3206 //remove_all_menu_toolbar_constructors(main_window, NULL);
3208 retval
= lttv_iattribute_find_by_path(attributes
, "viewers/menu",
3209 LTTV_POINTER
, &value
);
3211 lttv_menus_destroy((LttvMenus
*)*(value
.v_pointer
));
3213 retval
= lttv_iattribute_find_by_path(attributes
, "viewers/toolbar",
3214 LTTV_POINTER
, &value
);
3216 lttv_toolbars_destroy((LttvToolbars
*)*(value
.v_pointer
));
3218 g_object_unref(main_window
->attributes
);
3219 g_main_window_list
= g_slist_remove(g_main_window_list
, main_window
);
3221 g_info("There are now : %d windows\n",g_slist_length(g_main_window_list
));
3222 if(g_slist_length(g_main_window_list
) == 0)
3227 on_MWindow_configure (GtkWidget
*widget
,
3228 GdkEventConfigure
*event
,
3231 // MD : removed time width modification upon resizing of the main window.
3232 // The viewers will redraw themselves completely, without time interval
3235 if(mw_data->window_width){
3236 time_span = LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context)->Time_Span ;
3237 time_win = tab->time_window;
3238 ratio = width / mw_data->window_width;
3239 tab->time_window.time_width = ltt_time_mul(time_win.time_width,ratio);
3240 time = ltt_time_sub(time_span->endTime, time_win.start_time);
3241 if(ltt_time_compare(time, tab->time_window.time_width) < 0){
3242 tab->time_window.time_width = time;
3248 mw_data->window_width = (int)width;
3257 on_MNotebook_switch_page (GtkNotebook
*notebook
,
3258 GtkNotebookPage
*page
,
3266 void time_change_manager (Tab
*tab
,
3267 TimeWindow new_time_window
)
3270 /* Only one source of time change */
3271 if(tab
->time_manager_lock
== TRUE
) return;
3273 tab
->time_manager_lock
= TRUE
;
3274 TimeInterval time_span
;
3276 LttvTraceset
*ts
= tab
->traceset_info
->traceset
;
3277 time_span
.start_time
=ltt_time_from_uint64( lttv_traceset_get_timestamp_begin(ts
));
3278 time_span
.end_time
= ltt_time_from_uint64(lttv_traceset_get_timestamp_end(ts
));
3281 LttTime start_time
= new_time_window
.start_time
;
3282 LttTime end_time
= new_time_window
.end_time
;
3284 g_assert(ltt_time_compare(start_time
, end_time
) < 0);
3287 GtkAdjustment
*adjustment
= gtk_range_get_adjustment(GTK_RANGE(tab
->scrollbar
));
3288 LttTime upper
= ltt_time_sub(time_span
.end_time
, time_span
.start_time
);
3291 gtk_range_set_increments(GTK_RANGE(tab
->scrollbar
),
3292 ltt_time_to_double(new_time_window
.time_width
)
3293 / SCROLL_STEP_PER_PAGE
3294 * NANOSECONDS_PER_SECOND
, /* step increment */
3295 ltt_time_to_double(new_time_window
.time_width
)
3296 * NANOSECONDS_PER_SECOND
); /* page increment */
3297 gtk_range_set_range(GTK_RANGE(tab
->scrollbar
),
3299 ltt_time_to_double(upper
)
3300 * NANOSECONDS_PER_SECOND
); /* upper */
3302 g_object_set(G_OBJECT(adjustment
),
3306 ltt_time_to_double(upper
), /* upper */
3308 new_time_window
.time_width_double
3309 / SCROLL_STEP_PER_PAGE
, /* step increment */
3311 new_time_window
.time_width_double
,
3312 /* page increment */
3314 new_time_window
.time_width_double
, /* page size */
3316 gtk_adjustment_changed(adjustment
);
3318 // g_object_set(G_OBJECT(adjustment),
3320 // ltt_time_to_double(
3321 // ltt_time_sub(start_time, time_span.start_time))
3324 //gtk_adjustment_value_changed(adjustment);
3325 gtk_range_set_value(GTK_RANGE(tab
->scrollbar
),
3327 ltt_time_sub(start_time
, time_span
.start_time
)) /* value */);
3329 /* set the time bar. */
3332 timebar_set_minmax_time(TIMEBAR(tab
->MTimebar
),
3333 &time_span
.start_time
,
3334 &time_span
.end_time
);
3335 timebar_set_start_time(TIMEBAR(tab
->MTimebar
),&start_time
);
3336 timebar_set_end_time(TIMEBAR(tab
->MTimebar
),&end_time
);
3340 /* call viewer hooks for new time window */
3341 set_time_window(tab
, &new_time_window
);
3343 tab
->time_manager_lock
= FALSE
;
3352 void current_time_change_manager (Tab
*tab
,
3353 LttTime new_current_time
)
3355 /* Only one source of time change */
3356 if(tab
->current_time_manager_lock
== TRUE
) return;
3358 tab
->current_time_manager_lock
= TRUE
;
3360 timebar_set_current_time(TIMEBAR(tab
->MTimebar
), &new_current_time
);
3362 set_current_time(tab
, &new_current_time
);
3364 tab
->current_time_manager_lock
= FALSE
;
3367 void current_position_change_manager(Tab
*tab
, LttvTracesetPosition
*pos
)
3369 lttv_traceset_seek_to_position( pos
);
3371 LttTime new_time
= lttv_traceset_position_get_time(pos
);
3372 /* Put the context in a state coherent position */
3373 #ifdef BABEL_CLEANUP
3374 lttv_state_traceset_seek_time_closest((LttvTracesetState
*)tsc
, ltt_time_zero
);
3375 #endif /* BABEL_CLEANUP */
3376 current_time_change_manager(tab
, new_time
);
3378 set_current_position(tab
, pos
);
3381 static void on_timebar_starttime_changed(Timebar
*timebar
,
3384 Tab
*tab
= (Tab
*)user_data
;
3385 LttvTraceset
* ts
=tab
->traceset_info
->traceset
;
3386 TimeInterval time_span
= lttv_traceset_get_time_span(ts
);
3388 TimeWindow new_time_window
= tab
->time_window
;
3389 new_time_window
.start_time
= timebar_get_start_time(timebar
);
3391 LttTime end_time
= new_time_window
.end_time
;
3393 /* TODO ybrosseau 2010-12-02: This if should have been checked
3394 by the timebar already */
3395 if(ltt_time_compare(new_time_window
.start_time
, end_time
) >= 0) {
3396 /* Then, we must push back end time : keep the same time width
3397 * if possible, else end traceset time */
3398 end_time
= LTT_TIME_MIN(ltt_time_add(new_time_window
.start_time
,
3399 new_time_window
.time_width
),
3400 time_span
.end_time
);
3403 /* Fix the time width to fit start time and end time */
3404 new_time_window
.time_width
= ltt_time_sub(end_time
,
3405 new_time_window
.start_time
);
3407 new_time_window
.time_width_double
=
3408 ltt_time_to_double(new_time_window
.time_width
);
3410 new_time_window
.end_time
= end_time
;
3412 /* Notify the time_manager */
3413 time_change_manager(tab
, new_time_window
);
3417 static void on_timebar_endtime_changed(Timebar
*timebar
,
3420 Tab
*tab
= (Tab
*)user_data
;
3421 LttvTraceset
* ts
=tab
->traceset_info
->traceset
;
3422 TimeInterval time_span
= lttv_traceset_get_time_span(ts
);
3424 TimeWindow new_time_window
= tab
->time_window
;
3426 LttTime end_time
= timebar_get_end_time(timebar
);
3428 /* TODO ybrosseau 2010-12-02: This if should have been
3429 checked by the timebar already */
3430 if(ltt_time_compare(new_time_window
.start_time
, end_time
) >= 0) {
3431 /* Then, we must push front start time : keep the same time
3432 width if possible, else end traceset time */
3433 new_time_window
.start_time
= LTT_TIME_MAX(
3434 ltt_time_sub(end_time
,
3435 new_time_window
.time_width
),
3436 time_span
.start_time
);
3439 /* Fix the time width to fit start time and end time */
3440 new_time_window
.time_width
= ltt_time_sub(end_time
,
3441 new_time_window
.start_time
);
3443 new_time_window
.time_width_double
=
3444 ltt_time_to_double(new_time_window
.time_width
);
3446 new_time_window
.end_time
= end_time
;
3448 /* Notify the time_manager */
3449 time_change_manager(tab
, new_time_window
);
3451 static void on_timebar_currenttime_changed(Timebar
*timebar
,
3454 Tab
*tab
= (Tab
*)user_data
;
3456 LttTime new_current_time
= timebar_get_current_time(timebar
);
3458 current_time_change_manager(tab
, new_current_time
);
3461 void scroll_value_changed_cb(GtkWidget
*scrollbar
,
3464 Tab
*tab
= (Tab
*)user_data
;
3465 TimeWindow new_time_window
;
3467 GtkAdjustment
*adjust
= gtk_range_get_adjustment(GTK_RANGE(scrollbar
));
3468 gdouble value
= gtk_adjustment_get_value(adjust
);
3469 // gdouble upper, lower, ratio, page_size;
3472 LttvTraceset
* ts
= tab
->traceset_info
->traceset
;
3473 TimeInterval time_span
= lttv_traceset_get_time_span(ts
);
3475 time
= ltt_time_add(ltt_time_from_double(value
),
3476 time_span
.start_time
);
3478 new_time_window
.start_time
= time
;
3480 page_size
= adjust
->page_size
;
3482 new_time_window
.time_width
=
3483 ltt_time_from_double(page_size
);
3485 new_time_window
.time_width_double
=
3488 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
3489 new_time_window
.time_width
);
3492 time_change_manager(tab
, new_time_window
);
3495 //time_window = tab->time_window;
3497 lower
= adjust
->lower
;
3498 upper
= adjust
->upper
;
3499 ratio
= (value
- lower
) / (upper
- lower
);
3500 g_info("lower %lu, upper %lu, value %lu, ratio %lu", lower
, upper
, value
, ratio
);
3502 //time = ltt_time_sub(time_span->end_time, time_span->start_time);
3503 //time = ltt_time_mul(time, (float)ratio);
3504 //time = ltt_time_add(time_span->start_time, time);
3505 time
= ltt_time_add(ltt_time_from_double(value
),
3506 time_span
.start_time
);
3508 time_window
.start_time
= time
;
3510 page_size
= adjust
->page_size
;
3512 time_window
.time_width
=
3513 ltt_time_from_double(page_size
);
3514 //time = ltt_time_sub(time_span.end_time, time);
3515 //if(ltt_time_compare(time,time_window.time_width) < 0){
3516 // time_window.time_width = time;
3519 /* call viewer hooks for new time window */
3520 set_time_window(tab
, &time_window
);
3526 /* Display a dialogue showing all eventtypes and traces, let user to select the interested
3527 * eventtypes, tracefiles and traces (filter)
3530 /* Select a trace which will be removed from traceset
3533 char * get_remove_trace(MainWindow
*mw_data
,
3534 char ** all_trace_name
, int nb_trace
)
3536 return get_selection(mw_data
, all_trace_name
, nb_trace
,
3537 "Select a trace", "Trace pathname");
3541 /* Select a module which will be loaded
3544 char * get_load_module(MainWindow
*mw_data
,
3545 char ** load_module_name
, int nb_module
)
3547 return get_selection(mw_data
, load_module_name
, nb_module
,
3548 "Select a module to load", "Module name");
3554 /* Select a module which will be unloaded
3557 char * get_unload_module(MainWindow
*mw_data
,
3558 char ** loaded_module_name
, int nb_module
)
3560 return get_selection(mw_data
, loaded_module_name
, nb_module
,
3561 "Select a module to unload", "Module name");
3565 /* Display a dialogue which shows all selectable items, let user to
3566 * select one of them
3569 char * get_selection(MainWindow
*mw_data
,
3570 char ** loaded_module_name
, int nb_module
,
3571 char *title
, char * column_title
)
3573 GtkWidget
* dialogue
;
3574 GtkWidget
* scroll_win
;
3576 GtkListStore
* store
;
3577 GtkTreeViewColumn
* column
;
3578 GtkCellRenderer
* renderer
;
3579 GtkTreeSelection
* select
;
3582 char * unload_module_name
= NULL
;
3584 dialogue
= gtk_dialog_new_with_buttons(title
,
3587 GTK_STOCK_OK
,GTK_RESPONSE_ACCEPT
,
3588 GTK_STOCK_CANCEL
,GTK_RESPONSE_REJECT
,
3590 gtk_window_set_default_size((GtkWindow
*)dialogue
, 500, 200);
3591 gtk_window_set_transient_for(GTK_WINDOW(dialogue
),
3592 GTK_WINDOW(mw_data
->mwindow
));
3594 scroll_win
= gtk_scrolled_window_new (NULL
, NULL
);
3595 gtk_widget_show ( scroll_win
);
3596 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll_win
),
3597 GTK_POLICY_AUTOMATIC
, GTK_POLICY_AUTOMATIC
);
3599 store
= gtk_list_store_new (N_COLUMNS
,G_TYPE_STRING
);
3600 tree
= gtk_tree_view_new_with_model(GTK_TREE_MODEL (store
));
3601 gtk_widget_show ( tree
);
3602 g_object_unref (G_OBJECT (store
));
3604 renderer
= gtk_cell_renderer_text_new ();
3605 column
= gtk_tree_view_column_new_with_attributes (column_title
,
3607 "text", MODULE_COLUMN
,
3609 gtk_tree_view_column_set_alignment (column
, 0.5);
3610 gtk_tree_view_column_set_fixed_width (column
, 150);
3611 gtk_tree_view_append_column (GTK_TREE_VIEW (tree
), column
);
3613 select
= gtk_tree_view_get_selection (GTK_TREE_VIEW (tree
));
3614 gtk_tree_selection_set_mode (select
, GTK_SELECTION_SINGLE
);
3616 gtk_container_add (GTK_CONTAINER (scroll_win
), tree
);
3618 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialogue
)->vbox
), scroll_win
,TRUE
, TRUE
,0);
3620 for(i
=0;i
<nb_module
;i
++){
3621 gtk_list_store_append (store
, &iter
);
3622 gtk_list_store_set (store
, &iter
, MODULE_COLUMN
,loaded_module_name
[i
],-1);
3625 id
= gtk_dialog_run(GTK_DIALOG(dialogue
));
3626 GtkTreeModel
**store_model
= (GtkTreeModel
**)&store
;
3628 case GTK_RESPONSE_ACCEPT
:
3629 case GTK_RESPONSE_OK
:
3630 if (gtk_tree_selection_get_selected (select
, store_model
, &iter
)){
3631 gtk_tree_model_get ((GtkTreeModel
*)store
, &iter
, MODULE_COLUMN
, &unload_module_name
, -1);
3633 case GTK_RESPONSE_REJECT
:
3634 case GTK_RESPONSE_CANCEL
:
3636 gtk_widget_destroy(dialogue
);
3640 return unload_module_name
;
3644 /* Insert all menu entry and tool buttons into this main window
3649 void add_all_menu_toolbar_constructors(MainWindow
* mw
, gpointer user_data
)
3653 lttvwindow_viewer_constructor constructor
;
3654 LttvMenus
* global_menu
, * instance_menu
;
3655 LttvToolbars
* global_toolbar
, * instance_toolbar
;
3656 LttvMenuClosure
*menu_item
;
3657 LttvToolbarClosure
*toolbar_item
;
3658 LttvAttributeValue value
;
3659 LttvIAttribute
*global_attributes
= LTTV_IATTRIBUTE(lttv_global_attributes());
3660 LttvIAttribute
*attributes
= mw
->attributes
;
3661 GtkWidget
* tool_menu_title_menu
, *new_widget
, *pixmap
;
3664 retval
= lttv_iattribute_find_by_path(global_attributes
, "viewers/menu",
3665 LTTV_POINTER
, &value
);
3667 if(*(value
.v_pointer
) == NULL
)
3668 *(value
.v_pointer
) = lttv_menus_new();
3669 global_menu
= (LttvMenus
*)*(value
.v_pointer
);
3671 retval
= lttv_iattribute_find_by_path(attributes
, "viewers/menu",
3672 LTTV_POINTER
, &value
);
3674 if(*(value
.v_pointer
) == NULL
)
3675 *(value
.v_pointer
) = lttv_menus_new();
3676 instance_menu
= (LttvMenus
*)*(value
.v_pointer
);
3678 retval
= lttv_iattribute_find_by_path(global_attributes
, "viewers/toolbar",
3679 LTTV_POINTER
, &value
);
3681 if(*(value
.v_pointer
) == NULL
)
3682 *(value
.v_pointer
) = lttv_toolbars_new();
3683 global_toolbar
= (LttvToolbars
*)*(value
.v_pointer
);
3685 retval
= lttv_iattribute_find_by_path(attributes
, "viewers/toolbar",
3686 LTTV_POINTER
, &value
);
3688 if(*(value
.v_pointer
) == NULL
)
3689 *(value
.v_pointer
) = lttv_toolbars_new();
3690 instance_toolbar
= (LttvToolbars
*)*(value
.v_pointer
);
3692 /* Add missing menu entries to window instance */
3693 for(i
=0;i
<global_menu
->len
;i
++) {
3694 menu_item
= &g_array_index(global_menu
, LttvMenuClosure
, i
);
3696 //add menu_item to window instance;
3697 constructor
= menu_item
->con
;
3698 tool_menu_title_menu
= lookup_widget(mw
->mwindow
,"ToolMenuTitle_menu");
3700 gtk_menu_item_new_with_mnemonic (menu_item
->menu_text
);
3701 gtk_container_add (GTK_CONTAINER (tool_menu_title_menu
),
3703 g_signal_connect ((gpointer
) new_widget
, "activate",
3704 G_CALLBACK (insert_viewer_wrap
),
3706 gtk_widget_show (new_widget
);
3707 lttv_menus_add(instance_menu
, menu_item
->con
,
3708 menu_item
->menu_path
,
3709 menu_item
->menu_text
,
3714 /* Add missing toolbar entries to window instance */
3715 for(i
=0;i
<global_toolbar
->len
;i
++) {
3716 toolbar_item
= &g_array_index(global_toolbar
, LttvToolbarClosure
, i
);
3718 //add toolbar_item to window instance;
3719 constructor
= toolbar_item
->con
;
3720 tool_menu_title_menu
= lookup_widget(mw
->mwindow
,"MToolbar1");
3721 pixbuf
= gdk_pixbuf_new_from_xpm_data((const char**)toolbar_item
->pixmap
);
3722 pixmap
= gtk_image_new_from_pixbuf(pixbuf
);
3724 gtk_toolbar_append_element (GTK_TOOLBAR (tool_menu_title_menu
),
3725 GTK_TOOLBAR_CHILD_BUTTON
,
3728 toolbar_item
->tooltip
, NULL
,
3729 pixmap
, NULL
, NULL
);
3730 gtk_label_set_use_underline(
3731 GTK_LABEL (((GtkToolbarChild
*) (
3732 g_list_last (GTK_TOOLBAR
3733 (tool_menu_title_menu
)->children
)->data
))->label
),
3735 gtk_container_set_border_width (GTK_CONTAINER (new_widget
), 1);
3736 g_signal_connect ((gpointer
) new_widget
,
3738 G_CALLBACK (insert_viewer_wrap
),
3740 gtk_widget_show (new_widget
);
3742 lttv_toolbars_add(instance_toolbar
, toolbar_item
->con
,
3743 toolbar_item
->tooltip
,
3744 toolbar_item
->pixmap
,
3752 /* Create a main window
3755 MainWindow
*construct_main_window(MainWindow
* parent
)
3759 g_debug("construct_main_window()");
3760 GtkWidget
* new_window
; /* New generated main window */
3761 MainWindow
* new_m_window
;/* New main window structure */
3762 GtkNotebook
* notebook
;
3763 LttvIAttribute
*attributes
=
3764 LTTV_IATTRIBUTE(g_object_new(LTTV_ATTRIBUTE_TYPE
, NULL
));
3765 LttvAttributeValue value
;
3767 new_m_window
= g_new(MainWindow
, 1);
3769 // Add the object's information to the module's array
3770 g_main_window_list
= g_slist_append(g_main_window_list
, new_m_window
);
3772 new_window
= create_MWindow();
3773 gtk_widget_show (new_window
);
3775 new_m_window
->mwindow
= new_window
;
3776 new_m_window
->attributes
= attributes
;
3778 retval
= lttv_iattribute_find_by_path(attributes
, "viewers/menu",
3779 LTTV_POINTER
, &value
);
3781 *(value
.v_pointer
) = lttv_menus_new();
3783 retval
= lttv_iattribute_find_by_path(attributes
, "viewers/toolbar",
3784 LTTV_POINTER
, &value
);
3786 *(value
.v_pointer
) = lttv_toolbars_new();
3788 add_all_menu_toolbar_constructors(new_m_window
, NULL
);
3790 g_object_set_data_full(G_OBJECT(new_window
),
3792 (gpointer
)new_m_window
,
3793 (GDestroyNotify
)g_free
);
3794 //create a default tab
3795 notebook
= (GtkNotebook
*)lookup_widget(new_m_window
->mwindow
, "MNotebook");
3796 if(notebook
== NULL
){
3797 g_info("Notebook does not exist\n");
3798 /* FIXME : destroy partially created widgets */
3799 g_free(new_m_window
);
3802 //gtk_notebook_popup_enable (GTK_NOTEBOOK(notebook));
3803 //for now there is no name field in LttvTraceset structure
3804 //Use "Traceset" as the label for the default tab
3806 GtkWidget
* parent_notebook
= lookup_widget(parent
->mwindow
, "MNotebook");
3807 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(parent_notebook
),
3808 gtk_notebook_get_current_page(GTK_NOTEBOOK(parent_notebook
)));
3814 LttvPluginTab
*ptab
;
3815 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
3816 parent_tab
= ptab
->tab
;
3818 LttvPluginTab
*ptab
= g_object_new(LTTV_TYPE_PLUGIN_TAB
, NULL
);
3820 new_m_window
, parent_tab
, notebook
, "Traceset");
3821 ptab
->parent
.top_widget
= ptab
->tab
->top_widget
;
3822 g_object_set_data_full(
3823 G_OBJECT(ptab
->tab
->vbox
),
3826 (GDestroyNotify
)tab_destructor
);
3828 LttvPluginTab
*ptab
= g_object_new(LTTV_TYPE_PLUGIN_TAB
, NULL
);
3829 init_tab(ptab
->tab
, new_m_window
, NULL
, notebook
, "Traceset");
3830 ptab
->parent
.top_widget
= ptab
->tab
->top_widget
;
3831 g_object_set_data_full(
3832 G_OBJECT(ptab
->tab
->vbox
),
3835 (GDestroyNotify
)tab_destructor
);
3838 /* Insert default viewers */
3840 LttvAttributeType type
;
3841 LttvAttributeName name
;
3842 LttvAttributeValue value
;
3843 LttvAttribute
*attribute
;
3845 LttvIAttribute
*attributes_global
=
3846 LTTV_IATTRIBUTE(lttv_global_attributes());
3848 attribute
= LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
3849 LTTV_IATTRIBUTE(attributes_global
),
3850 LTTV_VIEWER_CONSTRUCTORS
));
3851 g_assert(attribute
);
3853 name
= g_quark_from_string("guievents");
3854 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
3856 if(type
== LTTV_POINTER
) {
3857 lttvwindow_viewer_constructor viewer_constructor
=
3858 (lttvwindow_viewer_constructor
)*value
.v_pointer
;
3859 insert_viewer(new_window
, viewer_constructor
);
3862 name
= g_quark_from_string("guicontrolflow");
3863 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
3865 if(type
== LTTV_POINTER
) {
3866 lttvwindow_viewer_constructor viewer_constructor
=
3867 (lttvwindow_viewer_constructor
)*value
.v_pointer
;
3868 insert_viewer(new_window
, viewer_constructor
);
3871 name
= g_quark_from_string("guistatistics");
3872 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
3874 if(type
== LTTV_POINTER
) {
3875 lttvwindow_viewer_constructor viewer_constructor
=
3876 (lttvwindow_viewer_constructor
)*value
.v_pointer
;
3877 insert_viewer(new_window
, viewer_constructor
);
3881 g_info("There are now : %d windows\n",g_slist_length(g_main_window_list
));
3883 return new_m_window
;
3887 /* Free the memory occupied by a tab structure
3891 void tab_destructor(LttvPluginTab
* ptab
)
3893 #ifdef BABEL_CLEANUP
3894 int i
, nb
, ref_count
;
3896 Tab
*tab
= ptab
->tab
;
3899 g_object_unref(tab
->attributes
);
3901 if(tab
->interrupted_state
)
3902 g_object_unref(tab
->interrupted_state
);
3905 if(tab
->traceset_info
->traceset_context
!= NULL
){
3906 //remove state update hooks
3907 lttv_state_remove_event_hooks(
3908 (LttvTracesetState
*)tab
->traceset_info
->
3910 lttv_context_fini(LTTV_TRACESET_CONTEXT(tab
->traceset_info
->
3912 g_object_unref(tab
->traceset_info
->traceset_context
);
3914 if(tab
->traceset_info
->traceset
!= NULL
) {
3915 nb
= lttv_traceset_number(tab
->traceset_info
->traceset
);
3916 for(i
= 0 ; i
< nb
; i
++) {
3917 trace
= lttv_traceset_get(tab
->traceset_info
->traceset
, i
);
3918 ref_count
= lttv_trace_get_ref_number(trace
);
3920 ltt_trace_close(lttv_trace(trace
));
3924 lttv_traceset_destroy(tab
->traceset_info
->traceset
);
3925 /* Remove the idle events requests processing function of the tab */
3926 g_idle_remove_by_data(tab
);
3928 g_slist_free(tab
->events_requests
);
3929 g_free(tab
->traceset_info
);
3931 g_object_unref(ptab
);
3932 #endif /* BABEL_CLEANUP */
3936 /* Create a tab and insert it into the current main window
3939 void init_tab(Tab
*tab
, MainWindow
* mw
, Tab
*copy_tab
,
3940 GtkNotebook
* notebook
, char * label
)
3945 //LttvFilter *filter = NULL;
3947 //create a new tab data structure
3948 //tab = g_new(Tab,1);
3950 //construct and initialize the traceset_info
3951 tab
->traceset_info
= g_new(TracesetInfo
,1);
3954 tab
->traceset_info
->traceset
=
3955 lttv_traceset_copy(copy_tab
->traceset_info
->traceset
);
3957 /* Copy the previous tab's filter */
3958 /* We can clone the filter, as we copy the trace set also */
3959 /* The filter must always be in sync with the trace set */
3961 #ifdef BABEL_CLEANUP
3962 tab
->filter
= lttv_filter_clone(copy_tab
->filter
);
3963 #endif /* BABEL_CLEANUP */
3965 tab
->traceset_info
->traceset
= lttv_traceset_new();
3970 lttv_attribute_write_xml(
3971 lttv_traceset_attribute(tab
->traceset_info
->traceset
),
3977 tab
->time_manager_lock
= FALSE
;
3978 tab
->current_time_manager_lock
= FALSE
;
3979 #ifdef BABEL_CLEANUP
3980 //FIXME copy not implemented in lower level
3981 tab
->traceset_info
->traceset_context
=
3982 g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
3983 //add state update hooks
3984 lttv_state_add_event_hooks(
3985 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
3986 #endif //BABEL_CLEANUP
3987 //determine the current_time and time_window of the tab
3989 if(copy_tab
!= NULL
){
3990 tab
->time_window
= copy_tab
->time_window
;
3991 tab
->current_time
= copy_tab
->current_time
;
3993 tab
->time_window
.start_time
=
3994 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
3995 time_span
.start_time
;
3996 if(DEFAULT_TIME_WIDTH_S
<
3997 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
3998 time_span
.end_time
.tv_sec
)
3999 tmp_time
.tv_sec
= DEFAULT_TIME_WIDTH_S
;
4002 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
4003 time_span
.end_time
.tv_sec
;
4004 tmp_time
.tv_nsec
= 0;
4005 tab
->time_window
.time_width
= tmp_time
;
4006 tab
->current_time
.tv_sec
=
4007 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
4008 time_span
.start_time
.tv_sec
;
4009 tab
->current_time
.tv_nsec
=
4010 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
4011 time_span
.start_time
.tv_nsec
;
4014 tab
->attributes
= LTTV_IATTRIBUTE(g_object_new(LTTV_ATTRIBUTE_TYPE
, NULL
));
4015 tab
->interrupted_state
= g_object_new(LTTV_ATTRIBUTE_TYPE
, NULL
);
4017 tab
->vbox
= gtk_vbox_new(FALSE
, 2);
4018 tab
->top_widget
= tab
->vbox
;
4019 //g_object_set_data_full(G_OBJECT(tab->top_widget), "filter",
4020 // filter, (GDestroyNotify)lttv_filter_destroy);
4022 // g_signal_connect (G_OBJECT(tab->top_widget),
4024 // G_CALLBACK (on_top_notify),
4027 tab
->viewer_container
= gtk_vbox_new(TRUE
, 2);
4028 tab
->scrollbar
= gtk_hscrollbar_new(NULL
);
4029 //tab->multivpaned = gtk_multi_vpaned_new();
4031 gtk_box_pack_start(GTK_BOX(tab
->vbox
),
4032 tab
->viewer_container
,
4034 TRUE
, /* Give the extra space to the child */
4035 0); /* No padding */
4038 // tab->time_window = copy_tab->time_window;
4039 // tab->current_time = copy_tab->current_time;
4042 /* Create the timebar */
4044 tab
->MTimebar
= timebar_new();
4046 gtk_box_pack_end(GTK_BOX(tab
->vbox
),
4048 FALSE
, /* Do not expand */
4049 FALSE
, /* Fill has no effect here (expand false) */
4050 0); /* No padding */
4052 gtk_box_pack_end(GTK_BOX(tab
->vbox
),
4054 FALSE
, /* Do not expand */
4055 FALSE
, /* Fill has no effect here (expand false) */
4056 0); /* No padding */
4058 g_object_set_data(G_OBJECT(tab
->viewer_container
), "focused_viewer", NULL
);
4064 // Display a label with a X
4065 GtkWidget *w_hbox = gtk_hbox_new(FALSE, 4);
4066 GtkWidget *w_label = gtk_label_new (label);
4067 GtkWidget *pixmap = create_pixmap(GTK_WIDGET(notebook), "close.png");
4068 GtkWidget *w_button = gtk_button_new ();
4069 gtk_container_add(GTK_CONTAINER(w_button), pixmap);
4070 //GtkWidget *w_button = gtk_button_new_with_label("x");
4072 gtk_button_set_relief(GTK_BUTTON(w_button), GTK_RELIEF_NONE);
4074 gtk_box_pack_start(GTK_BOX(w_hbox), w_label, TRUE, TRUE, 0);
4075 gtk_box_pack_end(GTK_BOX(w_hbox), w_button, FALSE,
4078 g_signal_connect_swapped (w_button, "clicked",
4079 G_CALLBACK (on_close_tab_X_clicked),
4082 gtk_widget_set_state(w_button, GTK_STATE_ACTIVE);
4084 gtk_widget_show (w_label);
4085 gtk_widget_show (pixmap);
4086 gtk_widget_show (w_button);
4087 gtk_widget_show (w_hbox);
4089 tab->label = w_hbox;
4093 tab
->label
= gtk_label_new (label
);
4095 gtk_widget_show(tab
->label
);
4096 gtk_widget_show(tab
->scrollbar
);
4097 gtk_widget_show(tab
->MTimebar
);
4098 gtk_widget_show(tab
->viewer_container
);
4099 gtk_widget_show(tab
->vbox
);
4101 //gtk_widget_show(tab->multivpaned);
4104 /* Start with empty events requests list */
4105 tab
->events_requests
= NULL
;
4106 tab
->events_request_pending
= FALSE
;
4107 tab
->stop_foreground
= FALSE
;
4111 g_signal_connect(G_OBJECT(tab
->scrollbar
), "value-changed",
4112 G_CALLBACK(scroll_value_changed_cb
), tab
);
4115 /* Timebar signal handler */
4116 g_signal_connect(G_OBJECT(tab
->MTimebar
), "start-time-changed",
4117 G_CALLBACK(on_timebar_starttime_changed
), tab
);
4118 g_signal_connect(G_OBJECT(tab
->MTimebar
), "end-time-changed",
4119 G_CALLBACK(on_timebar_endtime_changed
), tab
);
4120 g_signal_connect(G_OBJECT(tab
->MTimebar
), "current-time-changed",
4121 G_CALLBACK(on_timebar_currenttime_changed
), tab
);
4123 //g_signal_connect(G_OBJECT(tab->scrollbar), "changed",
4124 // G_CALLBACK(scroll_value_changed_cb), tab);
4127 //insert tab into notebook
4128 gtk_notebook_append_page(notebook
,
4131 list
= gtk_container_get_children(GTK_CONTAINER(notebook
));
4132 gtk_notebook_set_current_page(notebook
,g_list_length(list
)-1);
4133 // always show : not if(g_list_length(list)>1)
4134 gtk_notebook_set_show_tabs(notebook
, TRUE
);
4137 lttvwindow_report_time_window(tab
, copy_tab
->time_window
);
4138 lttvwindow_report_current_time(tab
, copy_tab
->current_time
);
4140 TimeWindow time_window
;
4142 time_window
.start_time
= ltt_time_zero
;
4143 time_window
.end_time
= ltt_time_add(time_window
.start_time
,
4144 lttvwindow_default_time_width
);
4145 time_window
.time_width
= lttvwindow_default_time_width
;
4146 time_window
.time_width_double
= ltt_time_to_double(time_window
.time_width
);
4148 lttvwindow_report_time_window(tab
, time_window
);
4149 lttvwindow_report_current_time(tab
, ltt_time_zero
);
4152 LttvTraceset
*traceset
= tab
->traceset_info
->traceset
;
4153 SetTraceset(tab
, traceset
);
4157 * execute_events_requests
4159 * Idle function that executes the pending requests for a tab.
4161 * @return return value : TRUE : keep the idle function, FALSE : remove it.
4163 gboolean
execute_events_requests(Tab
*tab
)
4165 return ( lttvwindow_process_pending_requests(tab
) );
4169 __EXPORT
void create_main_window_with_trace_list(GSList
*traces
)
4172 GSList
*iter
= NULL
;
4175 MainWindow
*mw
= construct_main_window(NULL
);
4176 GtkWidget
*widget
= mw
->mwindow
;
4178 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
4179 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
4180 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
4181 LttvPluginTab
*ptab
;
4185 ptab
= create_new_tab(widget
, NULL
);
4188 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
4192 LttvTraceset
* traceset
= lttv_traceset_new();
4193 for(iter
=traces
; iter
!=NULL
; iter
=g_slist_next(iter
)) {
4194 gchar
*path
= (gchar
*)iter
->data
;
4196 gchar abs_path
[PATH_MAX
];
4199 get_absolute_pathname(path
, abs_path
);
4201 if(lttv_traceset_add_path(traceset
,abs_path
) != 0 ){ /*failure*/
4203 g_warning("cannot open trace %s", abs_path
);
4205 GtkWidget
*dialogue
=
4206 gtk_message_dialog_new(
4207 GTK_WINDOW(gtk_widget_get_toplevel(widget
)),
4208 GTK_DIALOG_MODAL
|GTK_DIALOG_DESTROY_WITH_PARENT
,
4211 "Cannot open trace : maybe you should enter in the directory "
4213 gtk_dialog_run(GTK_DIALOG(dialogue
));
4214 gtk_widget_destroy(dialogue
);
4217 SetTraceset(tab
, traceset
);