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/stats.h>
41 #include <lttv/filter.h>
42 #include <lttv/sync/sync_chain_lttv.h>
43 #include <lttvwindow/mainwindow.h>
44 #include <lttvwindow/mainwindow-private.h>
45 #include <lttvwindow/menu.h>
46 #include <lttvwindow/timebar.h>
47 #include <lttvwindow/toolbar.h>
48 #include <lttvwindow/lttvwindow.h>
49 #include <lttvwindow/lttvwindowtraces.h>
50 #include <lttvwindow/lttv_plugin_tab.h>
52 static LttTime lttvwindow_default_time_width
= { 1, 0 };
53 #define CLIP_BUF 256 // size of clipboard buffer
55 extern LttvTrace
*g_init_trace
;
58 /** Array containing instanced objects. */
59 extern GSList
* g_main_window_list
;
61 /** MD : keep old directory. */
62 static char remember_plugins_dir
[PATH_MAX
] = "";
63 static char remember_trace_dir
[PATH_MAX
] = "";
65 void tab_destructor(LttvPluginTab
* ptab
);
67 MainWindow
* get_window_data_struct(GtkWidget
* widget
);
68 char * get_load_module(MainWindow
*mw
,
69 char ** load_module_name
, int nb_module
);
70 char * get_unload_module(MainWindow
*mw
,
71 char ** loaded_module_name
, int nb_module
);
72 char * get_remove_trace(MainWindow
*mw
, char ** all_trace_name
, int nb_trace
);
73 char * get_selection(MainWindow
*mw
,
74 char ** all_name
, int nb
, char *title
, char * column_title
);
75 void init_tab(Tab
*tab
, MainWindow
* mw
, Tab
*copy_tab
,
76 GtkNotebook
* notebook
, char * label
);
78 int update_traceset(Tab
*tab
, LttvTraceset
*traceset
);
80 static void insert_viewer(GtkWidget
* widget
, lttvwindow_viewer_constructor constructor
);
82 LttvPluginTab
*create_new_tab(GtkWidget
* widget
, gpointer user_data
);
84 static gboolean
lttvwindow_process_pending_requests(Tab
*tab
);
86 static void on_timebar_starttime_changed(Timebar
*timebar
,
88 static void on_timebar_endtime_changed(Timebar
*timebar
,
90 static void on_timebar_currenttime_changed(Timebar
*timebar
,
107 static void on_top_notify(GObject
*gobject
,
111 Tab
*tab
= (Tab
*)user_data
;
112 g_message("in on_top_notify.\n");
116 static gboolean
viewer_grab_focus(GtkWidget
*widget
, GdkEventButton
*event
,
119 GtkWidget
*viewer
= GTK_WIDGET(data
);
120 GtkWidget
*viewer_container
= gtk_widget_get_parent(viewer
);
122 g_debug("FOCUS GRABBED");
123 g_object_set_data(G_OBJECT(viewer_container
), "focused_viewer", viewer
);
128 static void connect_focus_recursive(GtkWidget
*widget
,
131 if(GTK_IS_CONTAINER(widget
)) {
132 gtk_container_forall(GTK_CONTAINER(widget
),
133 (GtkCallback
)connect_focus_recursive
,
137 if(GTK_IS_TREE_VIEW(widget
)) {
138 gtk_tree_view_set_headers_clickable(GTK_TREE_VIEW(widget
), TRUE
);
140 gtk_widget_add_events(widget
, GDK_BUTTON_PRESS_MASK
);
141 g_signal_connect (G_OBJECT(widget
),
142 "button-press-event",
143 G_CALLBACK (viewer_grab_focus
),
147 /* Stop all the processings and call gtk_main_quit() */
148 static void mainwindow_quit()
150 lttvwindowtraces_unregister_requests(g_quark_from_string("stats"));
151 lttvwindowtraces_unregister_requests(g_quark_from_string("state"));
152 lttvwindowtraces_unregister_computation_hooks(g_quark_from_string("stats"));
153 lttvwindowtraces_unregister_computation_hooks(g_quark_from_string("state"));
159 /* insert_viewer function constructs an instance of a viewer first,
160 * then inserts the widget of the instance into the container of the
165 insert_viewer_wrap(GtkWidget
*menuitem
, gpointer user_data
)
167 insert_viewer((GtkWidget
*)menuitem
, (lttvwindow_viewer_constructor
)user_data
);
171 /* internal functions */
172 void insert_viewer(GtkWidget
* widget
, lttvwindow_viewer_constructor constructor
)
174 GtkWidget
* viewer_container
;
175 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
177 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
178 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
183 ptab
= create_new_tab(widget
, NULL
);
185 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
189 viewer_container
= tab
->viewer_container
;
191 viewer
= (GtkWidget
*)constructor(&ptab
->parent
);
194 //gtk_multivpaned_widget_add(GTK_MULTIVPANED(multivpaned), viewer);
196 gtk_box_pack_end(GTK_BOX(viewer_container
),
202 /* We want to connect the viewer_grab_focus to EVERY
203 * child of this widget. The little trick is to get each child
204 * of each GTK_CONTAINER, even subchildren.
206 connect_focus_recursive(viewer
, viewer
);
211 * Function to set/update traceset for the viewers
212 * @param tab viewer's tab
213 * @param traceset traceset of the main window.
215 * 0 : traceset updated
216 * 1 : no traceset hooks to update; not an error.
219 int SetTraceset(Tab
* tab
, LttvTraceset
*traceset
)
222 TimeInterval time_span
;
223 TimeWindow new_time_window
;
224 LttTime new_current_time
;
225 LttvTracesetContext
*tsc
=
226 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
228 // Perform time synchronization on the traces
229 if (syncTraceset(tsc
))
231 /* There is some time-dependant information that was calculated during
232 * context initialization. Destroy the old contexts and initialize new
234 * Modified from lttvwindow_add_trace()
236 // Keep a reference to the traces so they are not freed
237 for(i
= 0; i
< lttv_traceset_number(traceset
); i
++)
239 LttvTrace
*trace
= lttv_traceset_get(traceset
, i
);
240 lttv_trace_ref(trace
);
243 // Remove state update hooks
244 lttv_state_remove_event_hooks(
245 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
247 lttv_context_fini(LTTV_TRACESET_CONTEXT(
248 tab
->traceset_info
->traceset_context
));
249 g_object_unref(tab
->traceset_info
->traceset_context
);
251 for(i
= 0; i
< lttv_traceset_number(traceset
); i
++)
253 LttvTrace
*trace
= lttv_traceset_get(traceset
, i
);
254 lttvwindowtraces_remove_trace(trace
);
255 lttvwindowtraces_add_trace(trace
);
258 // Create new context
259 tab
->traceset_info
->traceset_context
=
260 g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
261 lttv_context_init(LTTV_TRACESET_CONTEXT(tab
->traceset_info
->
262 traceset_context
), traceset
);
264 // Add state update hooks
265 lttv_state_add_event_hooks(
266 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
268 // Remove local reference to the traces
269 for(i
=0; i
<lttv_traceset_number(traceset
); i
++)
271 LttvTrace
*trace
= lttv_traceset_get(traceset
, i
);
272 lttv_trace_unref(trace
);
275 tsc
= LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
278 time_span
= tsc
->time_span
;
279 new_time_window
= tab
->time_window
;
280 new_current_time
= tab
->current_time
;
282 /* Set the tab's time window and current time if
284 if(ltt_time_compare(tab
->time_window
.start_time
, time_span
.start_time
) < 0
285 || ltt_time_compare(tab
->time_window
.end_time
,
286 time_span
.end_time
) > 0) {
287 new_time_window
.start_time
= time_span
.start_time
;
289 new_current_time
= time_span
.start_time
;
293 if(ltt_time_compare(lttvwindow_default_time_width
,
294 ltt_time_sub(time_span
.end_time
, time_span
.start_time
)) < 0
296 ltt_time_compare(time_span
.end_time
, time_span
.start_time
) == 0)
297 tmp_time
= lttvwindow_default_time_width
;
299 tmp_time
= time_span
.end_time
;
301 new_time_window
.time_width
= tmp_time
;
302 new_time_window
.time_width_double
= ltt_time_to_double(tmp_time
);
303 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
304 new_time_window
.time_width
) ;
307 /* Finally, call the update hooks of the viewers */
308 gint retval
= update_traceset(tab
, traceset
);
310 time_change_manager(tab
, new_time_window
);
311 current_time_change_manager(tab
, new_current_time
);
317 * Function to set/update filter for the viewers
318 * @param tab viewer's tab
319 * @param filter filter of the main window.
322 * 0 : filters updated
323 * 1 : no filter hooks to update; not an error.
326 int SetFilter(Tab
* tab
, gpointer filter
)
329 LttvAttributeValue value
;
331 g_assert(lttv_iattribute_find_by_path(tab
->attributes
,
332 "hooks/updatefilter", LTTV_POINTER
, &value
));
334 tmp
= (LttvHooks
*)*(value
.v_pointer
);
336 if(tmp
== NULL
) return 1;
337 lttv_hooks_call(tmp
,filter
);
345 * Function to redraw each viewer belonging to the current tab
346 * @param tab viewer's tab
349 int update_traceset(Tab
*tab
, LttvTraceset
*traceset
)
351 LttvAttributeValue value
;
355 retval
= lttv_iattribute_find_by_path(tab
->attributes
,
356 "hooks/updatetraceset",
360 tmp
= (LttvHooks
*)*(value
.v_pointer
);
364 lttv_hooks_call(tmp
, traceset
);
370 Call hooks register to get update on traceset time span changes
372 int notify_time_span_changed(Tab
*tab
)
374 LttvAttributeValue value
;
378 retval
= lttv_iattribute_find_by_path(tab
->attributes
,
379 "hooks/updatetimespan",
383 tmp
= (LttvHooks
*)*(value
.v_pointer
);
387 lttv_hooks_call(tmp
, NULL
);
392 /* get_label function is used to get user input, it displays an input
393 * box, which allows user to input a string
396 void get_label_string (GtkWidget
* text
, gchar
* label
)
398 GtkEntry
* entry
= (GtkEntry
*)text
;
399 if(strlen(gtk_entry_get_text(entry
))!=0)
400 strcpy(label
,gtk_entry_get_text(entry
));
403 gboolean
get_label(MainWindow
* mw
, gchar
* str
, gchar
* dialogue_title
, gchar
* label_str
)
405 GtkWidget
* dialogue
;
410 dialogue
= gtk_dialog_new_with_buttons(dialogue_title
,NULL
,
412 GTK_STOCK_OK
,GTK_RESPONSE_ACCEPT
,
413 GTK_STOCK_CANCEL
,GTK_RESPONSE_REJECT
,
416 label
= gtk_label_new(label_str
);
417 gtk_widget_show(label
);
419 text
= gtk_entry_new();
420 gtk_widget_show(text
);
422 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialogue
)->vbox
), label
,TRUE
, TRUE
,0);
423 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialogue
)->vbox
), text
,FALSE
, FALSE
,0);
425 id
= gtk_dialog_run(GTK_DIALOG(dialogue
));
427 case GTK_RESPONSE_ACCEPT
:
428 get_label_string(text
,str
);
429 gtk_widget_destroy(dialogue
);
431 case GTK_RESPONSE_REJECT
:
433 gtk_widget_destroy(dialogue
);
440 /* get_window_data_struct function is actually a lookup function,
441 * given a widget which is in the tree of the main window, it will
442 * return the MainWindow data structure associated with main window
445 MainWindow
* get_window_data_struct(GtkWidget
* widget
)
448 MainWindow
* mw_data
;
450 mw
= lookup_widget(widget
, "MWindow");
452 g_info("Main window does not exist\n");
456 mw_data
= (MainWindow
*) g_object_get_data(G_OBJECT(mw
),"main_window_data");
458 g_warning("Main window data does not exist\n");
465 /* create_new_window function, just constructs a new main window
468 void create_new_window(GtkWidget
* widget
, gpointer user_data
, gboolean clone
)
470 MainWindow
* parent
= get_window_data_struct(widget
);
473 g_info("Clone : use the same traceset\n");
474 construct_main_window(parent
);
476 g_info("Empty : traceset is set to NULL\n");
477 construct_main_window(NULL
);
481 /* Get the currently focused viewer.
482 * If no viewer is focused, use the first one.
484 * If no viewer available, return NULL.
486 GtkWidget
*viewer_container_focus(GtkWidget
*container
)
490 widget
= (GtkWidget
*)g_object_get_data(G_OBJECT(container
),
494 g_debug("no widget focused");
495 GList
*children
= gtk_container_get_children(GTK_CONTAINER(container
));
498 widget
= GTK_WIDGET(children
->data
);
499 g_object_set_data(G_OBJECT(container
),
509 gint
viewer_container_position(GtkWidget
*container
, GtkWidget
*child
)
512 if(child
== NULL
) return -1;
516 memset(&value
, 0, sizeof(GValue
));
517 g_value_init(&value
, G_TYPE_INT
);
518 gtk_container_child_get_property(GTK_CONTAINER(container
),
522 pos
= g_value_get_int(&value
);
528 /* move_*_viewer functions move the selected view up/down in
532 void move_down_viewer(GtkWidget
* widget
, gpointer user_data
)
534 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
536 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
537 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
544 ptab
= g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
548 //gtk_multivpaned_widget_move_up(GTK_MULTIVPANED(tab->multivpaned));
550 /* change the position in the vbox */
551 GtkWidget
*focus_widget
;
553 focus_widget
= viewer_container_focus(tab
->viewer_container
);
554 position
= viewer_container_position(tab
->viewer_container
, focus_widget
);
557 /* can move up one position */
558 gtk_box_reorder_child(GTK_BOX(tab
->viewer_container
),
565 void move_up_viewer(GtkWidget
* widget
, gpointer user_data
)
567 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
569 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
570 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
577 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
581 //gtk_multivpaned_widget_move_down(GTK_MULTIVPANED(tab->multivpaned));
582 /* change the position in the vbox */
583 GtkWidget
*focus_widget
;
585 focus_widget
= viewer_container_focus(tab
->viewer_container
);
586 position
= viewer_container_position(tab
->viewer_container
, focus_widget
);
590 g_list_length(gtk_container_get_children(
591 GTK_CONTAINER(tab
->viewer_container
)))-1
593 /* can move down one position */
594 gtk_box_reorder_child(GTK_BOX(tab
->viewer_container
),
602 /* delete_viewer deletes the selected viewer in the current tab
605 void delete_viewer(GtkWidget
* widget
, gpointer user_data
)
607 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
609 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
610 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
617 ptab
= g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
621 //gtk_multivpaned_widget_delete(GTK_MULTIVPANED(tab->multivpaned));
623 GtkWidget
*focus_widget
= viewer_container_focus(tab
->viewer_container
);
625 if(focus_widget
!= NULL
)
626 gtk_widget_destroy(focus_widget
);
628 g_object_set_data(G_OBJECT(tab
->viewer_container
), "focused_viewer", NULL
);
631 #if UNFINISHED_FEATURE
632 /* TODO ybrosseau 2012-03-15: Function is half implemented. Should be removed */
633 /* open_traceset will open a traceset saved in a file
634 * Right now, it is not finished yet, (not working)
638 void open_traceset(GtkWidget
* widget
, gpointer user_data
)
642 LttvTraceset
* traceset
;
643 MainWindow
* mw_data
= get_window_data_struct(widget
);
644 GtkFileSelection
* file_selector
=
645 (GtkFileSelection
*)gtk_file_selection_new("Select a traceset");
647 gtk_file_selection_hide_fileop_buttons(file_selector
);
649 gtk_window_set_transient_for(GTK_WINDOW(file_selector
),
650 GTK_WINDOW(mw_data
->mwindow
));
652 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
654 case GTK_RESPONSE_ACCEPT
:
655 case GTK_RESPONSE_OK
:
656 dir
= gtk_file_selection_get_selections (file_selector
);
657 traceset
= lttv_traceset_load(dir
[0]);
658 g_info("Open a trace set %s\n", dir
[0]);
661 case GTK_RESPONSE_REJECT
:
662 case GTK_RESPONSE_CANCEL
:
664 gtk_widget_destroy((GtkWidget
*)file_selector
);
670 /* lttvwindow_process_pending_requests
672 * Process requests for parts of the trace from viewers.
674 * These requests are made by lttvwindow_events_request().
676 * This internal function gets called by g_idle, taking care of the pending
677 * requests. It is responsible for concatenation of time intervals and position
678 * requests. It does it with the following algorithm organizing process traceset
679 * calls. Here is the detailed description of the way it works :
681 * - Events Requests Servicing Algorithm
683 * Data structures necessary :
685 * List of requests added to context : list_in
686 * List of requests not added to context : list_out
691 * list_out : many events requests
693 * FIXME : insert rest of algorithm here
697 #define list_out tab->events_requests
699 gboolean
lttvwindow_process_pending_requests(Tab
*tab
)
701 LttvTracesetContext
*tsc
;
702 LttvTracefileContext
*tfc
;
703 GSList
*list_in
= NULL
;
707 LttvTracesetContextPosition
*end_position
;
709 if(lttvwindow_preempt_count
> 0) return TRUE
;
712 g_critical("Foreground processing : tab does not exist. Processing removed.");
716 /* There is no events requests pending : we should never have been called! */
717 g_assert(g_slist_length(list_out
) != 0);
719 tsc
= LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
721 //set the cursor to be X shape, indicating that the computer is busy in doing its job
723 new = gdk_cursor_new(GDK_X_CURSOR
);
724 widget
= lookup_widget(tab
->mw
->mwindow
, "MToolbar1");
725 win
= gtk_widget_get_parent_window(widget
);
726 gdk_window_set_cursor(win
, new);
727 gdk_cursor_unref(new);
728 gdk_window_stick(win
);
729 gdk_window_unstick(win
);
732 g_debug("SIZE events req len : %d", g_slist_length(list_out
));
734 /* Preliminary check for no trace in traceset */
735 /* Unregister the routine if empty, empty list_out too */
736 if(lttv_traceset_number(tsc
->ts
) == 0) {
738 /* - For each req in list_out */
739 GSList
*iter
= list_out
;
741 while(iter
!= NULL
) {
743 gboolean remove
= FALSE
;
744 gboolean free_data
= FALSE
;
745 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
747 /* - Call end request for req */
748 if(events_request
->servicing
== TRUE
)
749 lttv_hooks_call(events_request
->after_request
, (gpointer
)tsc
);
751 /* - remove req from list_out */
752 /* Destroy the request */
759 GSList
*remove_iter
= iter
;
761 iter
= g_slist_next(iter
);
762 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
763 list_out
= g_slist_remove_link(list_out
, remove_iter
);
764 } else { // not remove
765 iter
= g_slist_next(iter
);
770 /* 0.1 Lock Traces */
775 iter_trace
<lttv_traceset_number(tsc
->ts
);
777 LttvTrace
*trace_v
= lttv_traceset_get(tsc
->ts
, iter_trace
);
779 if(lttvwindowtraces_lock(trace_v
) != 0) {
780 g_critical("Foreground processing : Unable to get trace lock");
781 return TRUE
; /* Cannot get lock, try later */
786 /* 0.2 Seek tracefiles positions to context position */
787 //g_assert(lttv_process_traceset_seek_position(tsc, sync_position) == 0);
788 lttv_process_traceset_synchronize_tracefiles(tsc
);
791 /* Events processing algorithm implementation */
792 /* Warning : the gtk_events_pending takes a LOT of cpu time. So what we do
793 * instead is to leave the control to GTK and take it back.
795 /* A. Servicing loop */
796 //while( (g_slist_length(list_in) != 0 || g_slist_length(list_out) != 0)) {
797 if((g_slist_length(list_in
) != 0 || g_slist_length(list_out
) != 0)) {
799 /* 1. If list_in is empty (need a seek) */
800 if( g_slist_length(list_in
) == 0 ) {
802 /* list in is empty, need a seek */
804 /* 1.1 Add requests to list_in */
805 GSList
*ltime
= NULL
;
809 /* 1.1.1 Find all time requests with the lowest start time in list_out
812 if(g_slist_length(list_out
) > 0)
813 ltime
= g_slist_append(ltime
, g_slist_nth_data(list_out
, 0));
814 for(iter
=g_slist_nth(list_out
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
815 /* Find all time requests with the lowest start time in list_out */
816 EventsRequest
*event_request_ltime
= (EventsRequest
*)g_slist_nth_data(ltime
, 0);
817 EventsRequest
*event_request_list_out
= (EventsRequest
*)iter
->data
;
820 comp
= ltt_time_compare(event_request_ltime
->start_time
,
821 event_request_list_out
->start_time
);
823 ltime
= g_slist_append(ltime
, event_request_list_out
);
825 /* Remove all elements from ltime, and add current */
827 ltime
= g_slist_delete_link(ltime
, g_slist_nth(ltime
, 0));
828 ltime
= g_slist_append(ltime
, event_request_list_out
);
832 /* 1.1.2 Find all position requests with the lowest position in list_out
835 if(g_slist_length(list_out
) > 0)
836 lpos
= g_slist_append(lpos
, g_slist_nth_data(list_out
, 0));
837 for(iter
=g_slist_nth(list_out
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
838 /* Find all position requests with the lowest position in list_out */
839 EventsRequest
*event_request_lpos
= (EventsRequest
*)g_slist_nth_data(lpos
, 0);
840 EventsRequest
*event_request_list_out
= (EventsRequest
*)iter
->data
;
843 if(event_request_lpos
->start_position
!= NULL
844 && event_request_list_out
->start_position
!= NULL
)
846 comp
= lttv_traceset_context_pos_pos_compare
847 (event_request_lpos
->start_position
,
848 event_request_list_out
->start_position
);
853 lpos
= g_slist_append(lpos
, event_request_list_out
);
855 /* Remove all elements from lpos, and add current */
857 lpos
= g_slist_delete_link(lpos
, g_slist_nth(lpos
, 0));
858 lpos
= g_slist_append(lpos
, event_request_list_out
);
863 EventsRequest
*event_request_lpos
= (EventsRequest
*)g_slist_nth_data(lpos
, 0);
864 EventsRequest
*event_request_ltime
= (EventsRequest
*)g_slist_nth_data(ltime
, 0);
865 LttTime lpos_start_time
;
867 if(event_request_lpos
!= NULL
868 && event_request_lpos
->start_position
!= NULL
) {
869 lpos_start_time
= lttv_traceset_context_position_get_time(
870 event_request_lpos
->start_position
);
873 /* 1.1.3 If lpos.start time < ltime */
874 if(event_request_lpos
!= NULL
875 && event_request_lpos
->start_position
!= NULL
876 && ltt_time_compare(lpos_start_time
,
877 event_request_ltime
->start_time
)<0) {
878 /* Add lpos to list_in, remove them from list_out */
879 for(iter
=lpos
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
881 EventsRequest
*event_request_lpos
=
882 (EventsRequest
*)iter
->data
;
884 list_in
= g_slist_append(list_in
, event_request_lpos
);
885 /* Remove from list_out */
886 list_out
= g_slist_remove(list_out
, event_request_lpos
);
889 /* 1.1.4 (lpos.start time >= ltime) */
890 /* Add ltime to list_in, remove them from list_out */
892 for(iter
=ltime
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
894 EventsRequest
*event_request_ltime
=
895 (EventsRequest
*)iter
->data
;
897 list_in
= g_slist_append(list_in
, event_request_ltime
);
898 /* Remove from list_out */
899 list_out
= g_slist_remove(list_out
, event_request_ltime
);
909 tfc
= lttv_traceset_context_get_current_tfc(tsc
);
910 g_assert(g_slist_length(list_in
)>0);
911 EventsRequest
*events_request
= g_slist_nth_data(list_in
, 0);
916 /* 1.2.1 If first request in list_in is a time request */
917 if(events_request
->start_position
== NULL
) {
918 /* - If first req in list_in start time != current time */
919 if(tfc
== NULL
|| ltt_time_compare(events_request
->start_time
,
920 tfc
->timestamp
) != 0)
921 /* - Seek to that time */
922 g_debug("SEEK TIME : %lu, %lu", events_request
->start_time
.tv_sec
,
923 events_request
->start_time
.tv_nsec
);
924 //lttv_process_traceset_seek_time(tsc, events_request->start_time);
925 lttv_state_traceset_seek_time_closest(LTTV_TRACESET_STATE(tsc
),
926 events_request
->start_time
);
928 /* Process the traceset with only state hooks */
932 lttv_process_traceset_middle(tsc
,
933 events_request
->start_time
,
936 g_assert(seek_count
< LTTV_STATE_SAVE_INTERVAL
);
942 LttvTracefileContext
*tfc
=
943 lttv_traceset_context_get_current_tfc(tsc
);
944 /* Else, the first request in list_in is a position request */
945 /* If first req in list_in pos != current pos */
946 g_assert(events_request
->start_position
!= NULL
);
947 g_debug("SEEK POS time : %lu, %lu",
948 lttv_traceset_context_position_get_time(
949 events_request
->start_position
).tv_sec
,
950 lttv_traceset_context_position_get_time(
951 events_request
->start_position
).tv_nsec
);
954 g_debug("SEEK POS context time : %lu, %lu",
955 tfc
->timestamp
.tv_sec
,
956 tfc
->timestamp
.tv_nsec
);
958 g_debug("SEEK POS context time : %lu, %lu",
959 ltt_time_infinite
.tv_sec
,
960 ltt_time_infinite
.tv_nsec
);
962 g_assert(events_request
->start_position
!= NULL
);
963 if(lttv_traceset_context_ctx_pos_compare(tsc
,
964 events_request
->start_position
) != 0) {
965 /* 1.2.2.1 Seek to that position */
966 g_debug("SEEK POSITION");
967 //lttv_process_traceset_seek_position(tsc, events_request->start_position);
968 pos_time
= lttv_traceset_context_position_get_time(
969 events_request
->start_position
);
971 lttv_state_traceset_seek_time_closest(LTTV_TRACESET_STATE(tsc
),
974 /* Process the traceset with only state hooks */
978 lttv_process_traceset_middle(tsc
,
981 events_request
->start_position
);
982 g_assert(lttv_traceset_context_ctx_pos_compare(tsc
,
983 events_request
->start_position
) == 0);
990 /* 1.3 Add hooks and call before request for all list_in members */
994 for(iter
=list_in
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
995 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
996 /* 1.3.1 If !servicing */
997 if(events_request
->servicing
== FALSE
) {
998 /* - begin request hooks called
1001 lttv_hooks_call(events_request
->before_request
, (gpointer
)tsc
);
1002 events_request
->servicing
= TRUE
;
1004 /* 1.3.2 call before chunk
1005 * 1.3.3 events hooks added
1007 if(events_request
->trace
== -1)
1008 lttv_process_traceset_begin(tsc
,
1009 events_request
->before_chunk_traceset
,
1010 events_request
->before_chunk_trace
,
1011 events_request
->before_chunk_tracefile
,
1012 events_request
->event
,
1013 events_request
->event_by_id_channel
);
1015 guint nb_trace
= lttv_traceset_number(tsc
->ts
);
1016 g_assert((guint
)events_request
->trace
< nb_trace
&&
1017 events_request
->trace
> -1);
1018 LttvTraceContext
*tc
= tsc
->traces
[events_request
->trace
];
1020 lttv_hooks_call(events_request
->before_chunk_traceset
, tsc
);
1022 lttv_trace_context_add_hooks(tc
,
1023 events_request
->before_chunk_trace
,
1024 events_request
->before_chunk_tracefile
,
1025 events_request
->event
,
1026 events_request
->event_by_id_channel
);
1031 /* 2. Else, list_in is not empty, we continue a read */
1034 /* 2.0 For each req of list_in */
1035 GSList
*iter
= list_in
;
1037 while(iter
!= NULL
) {
1039 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1041 /* - Call before chunk
1042 * - events hooks added
1044 if(events_request
->trace
== -1)
1045 lttv_process_traceset_begin(tsc
,
1046 events_request
->before_chunk_traceset
,
1047 events_request
->before_chunk_trace
,
1048 events_request
->before_chunk_tracefile
,
1049 events_request
->event
,
1050 events_request
->event_by_id_channel
);
1052 guint nb_trace
= lttv_traceset_number(tsc
->ts
);
1053 g_assert((guint
)events_request
->trace
< nb_trace
&&
1054 events_request
->trace
> -1);
1055 LttvTraceContext
*tc
= tsc
->traces
[events_request
->trace
];
1057 lttv_hooks_call(events_request
->before_chunk_traceset
, tsc
);
1059 lttv_trace_context_add_hooks(tc
,
1060 events_request
->before_chunk_trace
,
1061 events_request
->before_chunk_tracefile
,
1062 events_request
->event
,
1063 events_request
->event_by_id_channel
);
1066 iter
= g_slist_next(iter
);
1071 tfc
= lttv_traceset_context_get_current_tfc(tsc
);
1073 /* 2.1 For each req of list_out */
1074 GSList
*iter
= list_out
;
1076 while(iter
!= NULL
) {
1078 gboolean remove
= FALSE
;
1079 gboolean free_data
= FALSE
;
1080 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1082 /* if req.start time == current context time
1083 * or req.start position == current position*/
1084 if( ltt_time_compare(events_request
->start_time
,
1085 tfc
->timestamp
) == 0
1087 (events_request
->start_position
!= NULL
1089 lttv_traceset_context_ctx_pos_compare(tsc
,
1090 events_request
->start_position
) == 0)
1092 /* - Add to list_in, remove from list_out */
1093 list_in
= g_slist_append(list_in
, events_request
);
1097 /* - If !servicing */
1098 if(events_request
->servicing
== FALSE
) {
1099 /* - begin request hooks called
1100 * - servicing = TRUE
1102 lttv_hooks_call(events_request
->before_request
, (gpointer
)tsc
);
1103 events_request
->servicing
= TRUE
;
1105 /* call before chunk
1106 * events hooks added
1108 if(events_request
->trace
== -1)
1109 lttv_process_traceset_begin(tsc
,
1110 events_request
->before_chunk_traceset
,
1111 events_request
->before_chunk_trace
,
1112 events_request
->before_chunk_tracefile
,
1113 events_request
->event
,
1114 events_request
->event_by_id_channel
);
1116 guint nb_trace
= lttv_traceset_number(tsc
->ts
);
1117 g_assert((guint
)events_request
->trace
< nb_trace
&&
1118 events_request
->trace
> -1);
1119 LttvTraceContext
*tc
= tsc
->traces
[events_request
->trace
];
1121 lttv_hooks_call(events_request
->before_chunk_traceset
, tsc
);
1123 lttv_trace_context_add_hooks(tc
,
1124 events_request
->before_chunk_trace
,
1125 events_request
->before_chunk_tracefile
,
1126 events_request
->event
,
1127 events_request
->event_by_id_channel
);
1136 GSList
*remove_iter
= iter
;
1138 iter
= g_slist_next(iter
);
1139 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
1140 list_out
= g_slist_remove_link(list_out
, remove_iter
);
1141 } else { // not remove
1142 iter
= g_slist_next(iter
);
1148 /* 3. Find end criterions */
1153 /* 3.1.1 Find lowest end time in list_in */
1154 g_assert(g_slist_length(list_in
)>0);
1155 end_time
= ((EventsRequest
*)g_slist_nth_data(list_in
,0))->end_time
;
1157 for(iter
=g_slist_nth(list_in
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
1158 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1160 if(ltt_time_compare(events_request
->end_time
,
1162 end_time
= events_request
->end_time
;
1165 /* 3.1.2 Find lowest start time in list_out */
1166 for(iter
=list_out
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
1167 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1169 if(ltt_time_compare(events_request
->start_time
,
1171 end_time
= events_request
->start_time
;
1176 /* 3.2 Number of events */
1178 /* 3.2.1 Find lowest number of events in list_in */
1181 end_nb_events
= ((EventsRequest
*)g_slist_nth_data(list_in
,0))->num_events
;
1183 for(iter
=g_slist_nth(list_in
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
1184 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1186 if(events_request
->num_events
< end_nb_events
)
1187 end_nb_events
= events_request
->num_events
;
1190 /* 3.2.2 Use min(CHUNK_NUM_EVENTS, min num events in list_in) as
1193 end_nb_events
= MIN(CHUNK_NUM_EVENTS
, end_nb_events
);
1197 /* 3.3 End position */
1199 /* 3.3.1 Find lowest end position in list_in */
1202 end_position
=((EventsRequest
*)g_slist_nth_data(list_in
,0))->end_position
;
1204 for(iter
=g_slist_nth(list_in
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
1205 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1207 if(events_request
->end_position
!= NULL
&& end_position
!= NULL
&&
1208 lttv_traceset_context_pos_pos_compare(events_request
->end_position
,
1210 end_position
= events_request
->end_position
;
1215 /* 3.3.2 Find lowest start position in list_out */
1218 for(iter
=list_out
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
1219 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1221 if(events_request
->end_position
!= NULL
&& end_position
!= NULL
&&
1222 lttv_traceset_context_pos_pos_compare(events_request
->end_position
,
1224 end_position
= events_request
->end_position
;
1229 /* 4. Call process traceset middle */
1230 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
);
1231 count
= lttv_process_traceset_middle(tsc
, end_time
, end_nb_events
, end_position
);
1233 tfc
= lttv_traceset_context_get_current_tfc(tsc
);
1235 g_debug("Context time after middle : %lu, %lu", tfc
->timestamp
.tv_sec
,
1236 tfc
->timestamp
.tv_nsec
);
1238 g_debug("End of trace reached after middle.");
1242 /* 5. After process traceset middle */
1243 tfc
= lttv_traceset_context_get_current_tfc(tsc
);
1245 /* - if current context time > traceset.end time */
1246 if(tfc
== NULL
|| ltt_time_compare(tfc
->timestamp
,
1247 tsc
->time_span
.end_time
) > 0) {
1248 /* - For each req in list_in */
1249 GSList
*iter
= list_in
;
1251 while(iter
!= NULL
) {
1253 gboolean remove
= FALSE
;
1254 gboolean free_data
= FALSE
;
1255 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1257 /* - Remove events hooks for req
1258 * - Call end chunk for req
1261 if(events_request
->trace
== -1)
1262 lttv_process_traceset_end(tsc
,
1263 events_request
->after_chunk_traceset
,
1264 events_request
->after_chunk_trace
,
1265 events_request
->after_chunk_tracefile
,
1266 events_request
->event
,
1267 events_request
->event_by_id_channel
);
1270 guint nb_trace
= lttv_traceset_number(tsc
->ts
);
1271 g_assert(events_request
->trace
< nb_trace
&&
1272 events_request
->trace
> -1);
1273 LttvTraceContext
*tc
= tsc
->traces
[events_request
->trace
];
1275 lttv_trace_context_remove_hooks(tc
,
1276 events_request
->after_chunk_trace
,
1277 events_request
->after_chunk_tracefile
,
1278 events_request
->event
,
1279 events_request
->event_by_id_channel
);
1280 lttv_hooks_call(events_request
->after_chunk_traceset
, tsc
);
1285 /* - Call end request for req */
1286 lttv_hooks_call(events_request
->after_request
, (gpointer
)tsc
);
1288 /* - remove req from list_in */
1289 /* Destroy the request */
1296 GSList
*remove_iter
= iter
;
1298 iter
= g_slist_next(iter
);
1299 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
1300 list_in
= g_slist_remove_link(list_in
, remove_iter
);
1301 } else { // not remove
1302 iter
= g_slist_next(iter
);
1307 /* 5.1 For each req in list_in */
1308 GSList
*iter
= list_in
;
1310 while(iter
!= NULL
) {
1312 gboolean remove
= FALSE
;
1313 gboolean free_data
= FALSE
;
1314 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1316 /* - Remove events hooks for req
1317 * - Call end chunk for req
1319 if(events_request
->trace
== -1)
1320 lttv_process_traceset_end(tsc
,
1321 events_request
->after_chunk_traceset
,
1322 events_request
->after_chunk_trace
,
1323 events_request
->after_chunk_tracefile
,
1324 events_request
->event
,
1325 events_request
->event_by_id_channel
);
1328 guint nb_trace
= lttv_traceset_number(tsc
->ts
);
1329 g_assert(events_request
->trace
< nb_trace
&&
1330 events_request
->trace
> -1);
1331 LttvTraceContext
*tc
= tsc
->traces
[events_request
->trace
];
1333 lttv_trace_context_remove_hooks(tc
,
1334 events_request
->after_chunk_trace
,
1335 events_request
->after_chunk_tracefile
,
1336 events_request
->event
,
1337 events_request
->event_by_id_channel
);
1339 lttv_hooks_call(events_request
->after_chunk_traceset
, tsc
);
1342 /* - req.num -= count */
1343 g_assert(events_request
->num_events
>= count
);
1344 events_request
->num_events
-= count
;
1346 g_assert(tfc
!= NULL
);
1347 /* - if req.num == 0
1349 * current context time >= req.end time
1351 * req.end pos == current pos
1353 * req.stop_flag == TRUE
1355 if( events_request
->num_events
== 0
1357 events_request
->stop_flag
== TRUE
1359 ltt_time_compare(tfc
->timestamp
,
1360 events_request
->end_time
) >= 0
1362 (events_request
->end_position
!= NULL
1364 lttv_traceset_context_ctx_pos_compare(tsc
,
1365 events_request
->end_position
) == 0)
1368 g_assert(events_request
->servicing
== TRUE
);
1369 /* - Call end request for req
1370 * - remove req from list_in */
1371 lttv_hooks_call(events_request
->after_request
, (gpointer
)tsc
);
1372 /* - remove req from list_in */
1373 /* Destroy the request */
1381 GSList
*remove_iter
= iter
;
1383 iter
= g_slist_next(iter
);
1384 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
1385 list_in
= g_slist_remove_link(list_in
, remove_iter
);
1386 } else { // not remove
1387 iter
= g_slist_next(iter
);
1393 /* End of removed servicing loop : leave control to GTK instead. */
1394 // if(gtk_events_pending()) break;
1397 /* B. When interrupted between chunks */
1400 GSList
*iter
= list_in
;
1402 /* 1. for each request in list_in */
1403 while(iter
!= NULL
) {
1405 gboolean remove
= FALSE
;
1406 gboolean free_data
= FALSE
;
1407 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1409 /* 1.1. Use current postition as start position */
1410 if(events_request
->start_position
!= NULL
)
1411 lttv_traceset_context_position_destroy(events_request
->start_position
);
1412 events_request
->start_position
= lttv_traceset_context_position_new(tsc
);
1413 lttv_traceset_context_position_save(tsc
, events_request
->start_position
);
1415 /* 1.2. Remove start time */
1416 events_request
->start_time
= ltt_time_infinite
;
1418 /* 1.3. Move from list_in to list_out */
1421 list_out
= g_slist_append(list_out
, events_request
);
1426 GSList
*remove_iter
= iter
;
1428 iter
= g_slist_next(iter
);
1429 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
1430 list_in
= g_slist_remove_link(list_in
, remove_iter
);
1431 } else { // not remove
1432 iter
= g_slist_next(iter
);
1438 /* C Unlock Traces */
1440 lttv_process_traceset_get_sync_data(tsc
);
1441 //lttv_traceset_context_position_save(tsc, sync_position);
1446 iter_trace
<lttv_traceset_number(tsc
->ts
);
1448 LttvTrace
*trace_v
= lttv_traceset_get(tsc
->ts
, iter_trace
);
1450 lttvwindowtraces_unlock(trace_v
);
1454 //set the cursor back to normal
1455 gdk_window_set_cursor(win
, NULL
);
1458 g_assert(g_slist_length(list_in
) == 0);
1460 if( g_slist_length(list_out
) == 0 ) {
1461 /* Put tab's request pending flag back to normal */
1462 tab
->events_request_pending
= FALSE
;
1463 g_debug("remove the idle fct");
1464 return FALSE
; /* Remove the idle function */
1466 g_debug("leave the idle fct");
1467 return TRUE
; /* Leave the idle function */
1469 /* We do not use simili-round-robin, it may require to read 1 meg buffers
1470 * again and again if many tracesets use the same tracefiles. */
1471 /* Hack for round-robin idle functions */
1472 /* It will put the idle function at the end of the pool */
1473 /*g_idle_add_full((G_PRIORITY_HIGH_IDLE + 21),
1474 (GSourceFunc)execute_events_requests,
1483 Manage the periodic update of a live trace
1486 live_trace_update_handler(Tab
*tab
)
1488 unsigned int updated_count
;
1490 LttvTracesetContext
*tsc
= LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
1491 TimeInterval initial_time_span
= tsc
->time_span
;
1492 TimeInterval updated_time_span
;
1494 updated_count
= lttv_process_traceset_update(tsc
);
1496 /* TODO ybrosseau 2011-01-12: Add trace resynchronization */
1498 /* Get the changed period bounds */
1499 updated_time_span
= tsc
->time_span
;
1501 if(ltt_time_compare(updated_time_span
.start_time
,
1502 initial_time_span
.start_time
) != 0) {
1503 /* The initial time should not change on a live update */
1507 /* Notify viewers (only on updates) */
1508 if(ltt_time_compare(updated_time_span
.end_time
,
1509 initial_time_span
.end_time
) != 0) {
1511 notify_time_span_changed(tab
);
1512 /* TODO ybrosseau 2011-01-12: Change the timebar to register
1513 to the time_span hook */
1514 timebar_set_minmax_time(TIMEBAR(tab
->MTimebar
),
1515 &updated_time_span
.start_time
,
1516 &updated_time_span
.end_time
);
1518 /* To update the min max */
1519 time_change_manager(tab
, tab
->time_window
);
1522 /* Timer will be recalled as long as there is files to update */
1523 return (updated_count
> 0);
1526 static void lttvwindow_add_trace(Tab
*tab
, LttvTrace
*trace_v
)
1528 LttvTraceset
*traceset
= tab
->traceset_info
->traceset
;
1530 guint num_traces
= lttv_traceset_number(traceset
);
1532 //Verify if trace is already present.
1533 for(i
=0; i
<num_traces
; i
++)
1535 LttvTrace
* trace
= lttv_traceset_get(traceset
, i
);
1536 if(trace
== trace_v
)
1540 //Keep a reference to the traces so they are not freed.
1541 for(i
=0; i
<lttv_traceset_number(traceset
); i
++)
1543 LttvTrace
* trace
= lttv_traceset_get(traceset
, i
);
1544 lttv_trace_ref(trace
);
1547 //remove state update hooks
1548 lttv_state_remove_event_hooks(
1549 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1551 lttv_context_fini(LTTV_TRACESET_CONTEXT(
1552 tab
->traceset_info
->traceset_context
));
1553 g_object_unref(tab
->traceset_info
->traceset_context
);
1555 lttv_traceset_add(traceset
, trace_v
);
1556 lttv_trace_ref(trace_v
); /* local ref */
1558 /* Create new context */
1559 tab
->traceset_info
->traceset_context
=
1560 g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
1562 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->
1567 //add state update hooks
1568 lttv_state_add_event_hooks(
1569 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1570 //Remove local reference to the traces.
1571 for(i
=0; i
<lttv_traceset_number(traceset
); i
++)
1573 LttvTrace
* trace
= lttv_traceset_get(traceset
, i
);
1574 lttv_trace_unref(trace
);
1578 //add_trace_into_traceset_selector(GTK_MULTIVPANED(tab->multivpaned), lttv_trace(trace_v));
1581 if (lttv_trace(trace_v
)->is_live
) {
1582 /* Add timer for live update */
1583 /* TODO ybrosseau 2011-01-12: Parametrize the hardcoded 1 seconds */
1584 g_timeout_add_seconds (1,
1585 (GSourceFunc
) live_trace_update_handler
,
1591 /* add_trace adds a trace into the current traceset. It first displays a
1592 * directory selection dialogue to let user choose a trace, then recreates
1593 * tracset_context, and redraws all the viewer of the current tab
1596 void add_trace(GtkWidget
* widget
, gpointer user_data
)
1599 LttvTrace
* trace_v
;
1600 LttvTraceset
* traceset
;
1602 char abs_path
[PATH_MAX
];
1604 MainWindow
* mw_data
= get_window_data_struct(widget
);
1605 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
1607 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
1608 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
1609 LttvPluginTab
*ptab
;
1613 ptab
= create_new_tab(widget
, NULL
);
1616 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
1620 /* File open dialog management */
1621 GtkWidget
*extra_live_button
;
1622 GtkFileChooser
* file_chooser
=
1624 gtk_file_chooser_dialog_new ("Select a trace",
1625 GTK_WINDOW(mw_data
->mwindow
),
1626 GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER
,
1627 GTK_STOCK_CANCEL
, GTK_RESPONSE_CANCEL
,
1628 GTK_STOCK_OPEN
, GTK_RESPONSE_ACCEPT
,
1631 /* Button to indicate the opening of a live trace */
1632 extra_live_button
= gtk_check_button_new_with_mnemonic ("Trace is live (currently being writen)");
1633 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (extra_live_button
), FALSE
);
1634 gtk_file_chooser_set_extra_widget (GTK_FILE_CHOOSER (file_chooser
), extra_live_button
);
1636 gtk_file_chooser_set_show_hidden (file_chooser
, TRUE
);
1637 if(remember_trace_dir
[0] != '\0')
1638 gtk_file_chooser_set_filename(file_chooser
, remember_trace_dir
);
1640 id
= gtk_dialog_run(GTK_DIALOG(file_chooser
));
1643 case GTK_RESPONSE_ACCEPT
:
1644 case GTK_RESPONSE_OK
:
1645 dir
= gtk_file_chooser_get_filename (file_chooser
);
1647 strncpy(remember_trace_dir
, dir
, PATH_MAX
);
1648 strncat(remember_trace_dir
, "/", PATH_MAX
);
1649 if(!dir
|| strlen(dir
) == 0){
1652 get_absolute_pathname(dir
, abs_path
);
1653 trace_v
= lttvwindowtraces_get_trace_by_name(abs_path
);
1654 if(trace_v
== NULL
) {
1655 if(gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (extra_live_button
))) {
1656 trace
= ltt_trace_open_live(abs_path
);
1658 trace
= ltt_trace_open(abs_path
);
1662 g_warning("cannot open trace %s", abs_path
);
1664 GtkWidget
*dialogue
=
1665 gtk_message_dialog_new(
1666 GTK_WINDOW(gtk_widget_get_toplevel(widget
)),
1667 GTK_DIALOG_MODAL
|GTK_DIALOG_DESTROY_WITH_PARENT
,
1670 "Cannot open trace : maybe you should enter in the trace "
1671 "directory to select it ?");
1672 gtk_dialog_run(GTK_DIALOG(dialogue
));
1673 gtk_widget_destroy(dialogue
);
1676 trace_v
= lttv_trace_new(trace
);
1677 lttvwindowtraces_add_trace(trace_v
);
1678 lttvwindow_add_trace(tab
, trace_v
);
1681 lttvwindow_add_trace(tab
, trace_v
);
1685 //update current tab
1686 //update_traceset(mw_data);
1688 /* Call the updatetraceset hooks */
1690 traceset
= tab
->traceset_info
->traceset
;
1691 SetTraceset(tab
, traceset
);
1692 // in expose now call_pending_read_hooks(mw_data);
1694 //lttvwindow_report_current_time(mw_data,&(tab->current_time));
1696 case GTK_RESPONSE_REJECT
:
1697 case GTK_RESPONSE_CANCEL
:
1701 gtk_widget_destroy((GtkWidget
*)file_chooser
);
1705 /* remove_trace removes a trace from the current traceset if all viewers in
1706 * the current tab are not interested in the trace. It first displays a
1707 * dialogue, which shows all traces in the current traceset, to let user choose
1708 * a trace, then it checks if all viewers unselect the trace, if it is true,
1709 * it will remove the trace, recreate the traceset_contex,
1710 * and redraws all the viewer of the current tab. If there is on trace in the
1711 * current traceset, it will delete all viewers of the current tab
1713 * It destroys the filter tree. FIXME... we should request for an update
1717 void remove_trace(GtkWidget
*widget
, gpointer user_data
)
1720 LttvTrace
* trace_v
;
1721 LttvTraceset
* traceset
;
1722 gint i
, j
, nb_trace
, index
=-1;
1723 char ** name
, *remove_trace_name
;
1724 MainWindow
* mw_data
= get_window_data_struct(widget
);
1725 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
1727 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
1728 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
1734 LttvPluginTab
*ptab
;
1735 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
1739 nb_trace
=lttv_traceset_number(tab
->traceset_info
->traceset
);
1740 name
= g_new(char*,nb_trace
);
1741 for(i
= 0; i
< nb_trace
; i
++){
1742 trace_v
= lttv_traceset_get(tab
->traceset_info
->traceset
, i
);
1743 trace
= lttv_trace(trace_v
);
1744 name
[i
] = (char *) g_quark_to_string(ltt_trace_name(trace
));
1747 remove_trace_name
= get_remove_trace(mw_data
, name
, nb_trace
);
1750 if(remove_trace_name
){
1752 /* yuk, cut n paste from old code.. should be better (MD)*/
1753 for(i
= 0; i
<nb_trace
; i
++) {
1754 if(strcmp(remove_trace_name
,name
[i
]) == 0){
1759 traceset
= tab
->traceset_info
->traceset
;
1760 //Keep a reference to the traces so they are not freed.
1761 for(j
=0; j
<lttv_traceset_number(traceset
); j
++)
1763 LttvTrace
* trace
= lttv_traceset_get(traceset
, j
);
1764 lttv_trace_ref(trace
);
1767 //remove state update hooks
1768 lttv_state_remove_event_hooks(
1769 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1770 lttv_context_fini(LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
));
1771 g_object_unref(tab
->traceset_info
->traceset_context
);
1773 trace_v
= lttv_traceset_get(traceset
, index
);
1775 lttv_traceset_remove(traceset
, index
);
1776 lttv_trace_unref(trace_v
); // Remove local reference
1778 if(lttv_trace_get_ref_number(trace_v
) <= 1) {
1779 /* ref 1 : lttvwindowtraces only*/
1780 ltt_trace_close(lttv_trace(trace_v
));
1781 /* lttvwindowtraces_remove_trace takes care of destroying
1782 * the traceset linked with the trace_v and also of destroying
1783 * the trace_v at the same time.
1785 lttvwindowtraces_remove_trace(trace_v
);
1788 tab
->traceset_info
->traceset_context
=
1789 g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
1791 LTTV_TRACESET_CONTEXT(tab
->
1792 traceset_info
->traceset_context
),traceset
);
1793 //add state update hooks
1794 lttv_state_add_event_hooks(
1795 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1797 //Remove local reference to the traces.
1798 for(j
=0; j
<lttv_traceset_number(traceset
); j
++)
1800 LttvTrace
* trace
= lttv_traceset_get(traceset
, j
);
1801 lttv_trace_unref(trace
);
1804 SetTraceset(tab
, (gpointer
)traceset
);
1810 void remove_trace(GtkWidget
* widget
, gpointer user_data
)
1813 LttvTrace
* trace_v
;
1814 LttvTraceset
* traceset
;
1815 gint i
, j
, nb_trace
;
1816 char ** name
, *remove_trace_name
;
1817 MainWindow
* mw_data
= get_window_data_struct(widget
);
1818 LttvTracesetSelector
* s
;
1819 LttvTraceSelector
* t
;
1822 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
1824 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
1825 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
1831 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
1834 nb_trace
=lttv_traceset_number(tab
->traceset_info
->traceset
);
1835 name
= g_new(char*,nb_trace
);
1836 for(i
= 0; i
< nb_trace
; i
++){
1837 trace_v
= lttv_traceset_get(tab
->traceset_info
->traceset
, i
);
1838 trace
= lttv_trace(trace_v
);
1839 name
[i
] = ltt_trace_name(trace
);
1842 remove_trace_name
= get_remove_trace(name
, nb_trace
);
1844 if(remove_trace_name
){
1845 for(i
=0; i
<nb_trace
; i
++){
1846 if(strcmp(remove_trace_name
,name
[i
]) == 0){
1847 //unselect the trace from the current viewer
1849 w
= gtk_multivpaned_get_widget(GTK_MULTIVPANED(tab
->multivpaned
));
1851 s
= g_object_get_data(G_OBJECT(w
), "Traceset_Selector");
1853 t
= lttv_traceset_selector_trace_get(s
,i
);
1854 lttv_trace_selector_set_selected(t
, FALSE
);
1857 //check if other viewers select the trace
1858 w
= gtk_multivpaned_get_first_widget(GTK_MULTIVPANED(tab
->multivpaned
));
1860 s
= g_object_get_data(G_OBJECT(w
), "Traceset_Selector");
1862 t
= lttv_traceset_selector_trace_get(s
,i
);
1863 selected
= lttv_trace_selector_get_selected(t
);
1866 w
= gtk_multivpaned_get_next_widget(GTK_MULTIVPANED(tab
->multivpaned
));
1868 }else selected
= FALSE
;
1870 //if no viewer selects the trace, remove it
1872 remove_trace_from_traceset_selector(GTK_MULTIVPANED(tab
->multivpaned
), i
);
1874 traceset
= tab
->traceset_info
->traceset
;
1875 //Keep a reference to the traces so they are not freed.
1876 for(j
=0; j
<lttv_traceset_number(traceset
); j
++)
1878 LttvTrace
* trace
= lttv_traceset_get(traceset
, j
);
1879 lttv_trace_ref(trace
);
1882 //remove state update hooks
1883 lttv_state_remove_event_hooks(
1884 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1885 lttv_context_fini(LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
));
1886 g_object_unref(tab
->traceset_info
->traceset_context
);
1889 trace_v
= lttv_traceset_get(traceset
, i
);
1891 if(lttv_trace_get_ref_number(trace_v
) <= 2) {
1892 /* ref 2 : traceset, local */
1893 lttvwindowtraces_remove_trace(trace_v
);
1894 ltt_trace_close(lttv_trace(trace_v
));
1897 lttv_traceset_remove(traceset
, i
);
1898 lttv_trace_unref(trace_v
); // Remove local reference
1900 if(!lttv_trace_get_ref_number(trace_v
))
1901 lttv_trace_destroy(trace_v
);
1903 tab
->traceset_info
->traceset_context
=
1904 g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
1906 LTTV_TRACESET_CONTEXT(tab
->
1907 traceset_info
->traceset_context
),traceset
);
1908 //add state update hooks
1909 lttv_state_add_event_hooks(
1910 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1912 //Remove local reference to the traces.
1913 for(j
=0; j
<lttv_traceset_number(traceset
); j
++)
1915 LttvTrace
* trace
= lttv_traceset_get(traceset
, j
);
1916 lttv_trace_unref(trace
);
1920 //update current tab
1921 //update_traceset(mw_data);
1924 SetTraceset(tab
, (gpointer
)traceset
);
1925 // in expose now call_pending_read_hooks(mw_data);
1927 //lttvwindow_report_current_time(mw_data,&(tab->current_time));
1930 // while(tab->multi_vpaned->num_children){
1931 // gtk_multi_vpaned_widget_delete(tab->multi_vpaned);
1945 /* Redraw all the viewers in the current tab */
1946 void redraw(GtkWidget
*widget
, gpointer user_data
)
1948 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
1949 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
1950 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
1957 LttvPluginTab
*ptab
;
1958 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
1963 LttvAttributeValue value
;
1965 retval
= lttv_iattribute_find_by_path(tab
->attributes
, "hooks/redraw", LTTV_POINTER
, &value
);
1968 tmp
= (LttvHooks
*)*(value
.v_pointer
);
1970 lttv_hooks_call(tmp
,NULL
);
1974 void continue_processing(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/continue",
1994 LTTV_POINTER
, &value
);
1997 tmp
= (LttvHooks
*)*(value
.v_pointer
);
1999 lttv_hooks_call(tmp
,NULL
);
2002 /* Stop the processing for the calling main window's current tab.
2003 * It removes every processing requests that are in its list. It does not call
2004 * the end request hooks, because the request is not finished.
2007 void stop_processing(GtkWidget
*widget
, gpointer user_data
)
2009 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
2010 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2011 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2016 LttvPluginTab
*ptab
;
2017 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
2020 GSList
*iter
= tab
->events_requests
;
2022 while(iter
!= NULL
) {
2023 GSList
*remove_iter
= iter
;
2024 iter
= g_slist_next(iter
);
2026 g_free(remove_iter
->data
);
2027 tab
->events_requests
=
2028 g_slist_remove_link(tab
->events_requests
, remove_iter
);
2030 tab
->events_request_pending
= FALSE
;
2031 tab
->stop_foreground
= TRUE
;
2032 g_idle_remove_by_data(tab
);
2033 g_assert(g_slist_length(tab
->events_requests
) == 0);
2037 /* save will save the traceset to a file
2038 * Not implemented yet FIXME
2041 void save(GtkWidget
* widget
, gpointer user_data
)
2046 void save_as(GtkWidget
* widget
, gpointer user_data
)
2048 g_info("Save as\n");
2052 /* zoom will change the time_window of all the viewers of the
2053 * current tab, and redisplay them. The main functionality is to
2054 * determine the new time_window of the current tab
2057 void zoom(GtkWidget
* widget
, double size
)
2059 TimeInterval time_span
;
2060 TimeWindow new_time_window
;
2061 LttTime current_time
, time_delta
;
2062 LttvTracesetContext
*tsc
;
2063 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
2065 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2066 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2072 LttvPluginTab
*ptab
;
2073 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
2077 if(size
== 1) return;
2079 tsc
= LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
2080 time_span
= tsc
->time_span
;
2081 new_time_window
= tab
->time_window
;
2082 current_time
= tab
->current_time
;
2084 time_delta
= ltt_time_sub(time_span
.end_time
,time_span
.start_time
);
2086 new_time_window
.start_time
= time_span
.start_time
;
2087 new_time_window
.time_width
= time_delta
;
2088 new_time_window
.time_width_double
= ltt_time_to_double(time_delta
);
2089 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
2090 new_time_window
.time_width
) ;
2092 new_time_window
.time_width
= ltt_time_div(new_time_window
.time_width
, size
);
2093 new_time_window
.time_width_double
=
2094 ltt_time_to_double(new_time_window
.time_width
);
2095 if(ltt_time_compare(new_time_window
.time_width
,time_delta
) > 0)
2096 { /* Case where zoom out is bigger than trace length */
2097 new_time_window
.start_time
= time_span
.start_time
;
2098 new_time_window
.time_width
= time_delta
;
2099 new_time_window
.time_width_double
= ltt_time_to_double(time_delta
);
2100 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
2101 new_time_window
.time_width
) ;
2105 /* Center the image on the current time */
2106 new_time_window
.start_time
=
2107 ltt_time_sub(current_time
,
2108 ltt_time_from_double(new_time_window
.time_width_double
/2.0));
2109 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
2110 new_time_window
.time_width
) ;
2111 /* If on borders, don't fall off */
2112 if(ltt_time_compare(new_time_window
.start_time
, time_span
.start_time
) <0
2113 || ltt_time_compare(new_time_window
.start_time
, time_span
.end_time
) >0)
2115 new_time_window
.start_time
= time_span
.start_time
;
2116 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
2117 new_time_window
.time_width
) ;
2121 if(ltt_time_compare(new_time_window
.end_time
,
2122 time_span
.end_time
) > 0
2123 || ltt_time_compare(new_time_window
.end_time
,
2124 time_span
.start_time
) < 0)
2126 new_time_window
.start_time
=
2127 ltt_time_sub(time_span
.end_time
, new_time_window
.time_width
);
2129 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
2130 new_time_window
.time_width
) ;
2137 if(ltt_time_compare(new_time_window
.time_width
, ltt_time_zero
) == 0) {
2138 g_warning("Zoom more than 1 ns impossible");
2140 time_change_manager(tab
, new_time_window
);
2144 void zoom_in(GtkWidget
* widget
, gpointer user_data
)
2149 void zoom_out(GtkWidget
* widget
, gpointer user_data
)
2154 void zoom_extended(GtkWidget
* widget
, gpointer user_data
)
2159 void go_to_time(GtkWidget
* widget
, gpointer user_data
)
2161 g_info("Go to time\n");
2164 void show_time_frame(GtkWidget
* widget
, gpointer user_data
)
2166 g_info("Show time frame\n");
2170 /* callback function */
2173 on_empty_traceset_activate (GtkMenuItem
*menuitem
,
2176 create_new_window((GtkWidget
*)menuitem
, user_data
, FALSE
);
2181 on_clone_traceset_activate (GtkMenuItem
*menuitem
,
2184 create_new_window((GtkWidget
*)menuitem
, user_data
, TRUE
);
2188 /* create_new_tab calls create_tab to construct a new tab in the main window
2191 LttvPluginTab
*create_new_tab(GtkWidget
* widget
, gpointer user_data
)
2193 gchar label
[PATH_MAX
];
2194 MainWindow
* mw_data
= get_window_data_struct(widget
);
2196 GtkNotebook
* notebook
= (GtkNotebook
*)lookup_widget(widget
, "MNotebook");
2197 if(notebook
== NULL
){
2198 g_info("Notebook does not exist\n");
2201 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2202 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2208 LttvPluginTab
*ptab
;
2209 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
2210 copy_tab
= ptab
->tab
;
2213 strcpy(label
,"Page");
2214 if(get_label(mw_data
, label
,"Get the name of the tab","Please input tab's name")) {
2215 LttvPluginTab
*ptab
;
2217 ptab
= g_object_new(LTTV_TYPE_PLUGIN_TAB
, NULL
);
2218 init_tab (ptab
->tab
, mw_data
, copy_tab
, notebook
, label
);
2219 ptab
->parent
.top_widget
= ptab
->tab
->top_widget
;
2220 g_object_set_data_full(
2221 G_OBJECT(ptab
->tab
->vbox
),
2224 (GDestroyNotify
)tab_destructor
);
2231 on_tab_activate (GtkMenuItem
*menuitem
,
2234 create_new_tab((GtkWidget
*)menuitem
, user_data
);
2239 on_open_activate (GtkMenuItem
*menuitem
,
2242 #ifdef UNFINISHED_FEATURE
2243 open_traceset((GtkWidget
*)menuitem
, user_data
);
2249 on_close_activate (GtkMenuItem
*menuitem
,
2252 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2253 main_window_destructor(mw_data
);
2257 /* remove the current tab from the main window
2261 on_close_tab_activate (GtkWidget
*widget
,
2265 GtkWidget
* notebook
;
2266 notebook
= lookup_widget(widget
, "MNotebook");
2267 if(notebook
== NULL
){
2268 g_info("Notebook does not exist\n");
2272 page_num
= gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
));
2274 gtk_notebook_remove_page(GTK_NOTEBOOK(notebook
), page_num
);
2279 on_close_tab_X_clicked (GtkWidget
*widget
,
2283 GtkWidget
*notebook
= lookup_widget(widget
, "MNotebook");
2284 if(notebook
== NULL
){
2285 g_info("Notebook does not exist\n");
2289 if((page_num
= gtk_notebook_page_num(GTK_NOTEBOOK(notebook
), widget
)) != -1)
2290 gtk_notebook_remove_page(GTK_NOTEBOOK(notebook
), page_num
);
2296 on_add_trace_activate (GtkMenuItem
*menuitem
,
2299 add_trace((GtkWidget
*)menuitem
, user_data
);
2304 on_remove_trace_activate (GtkMenuItem
*menuitem
,
2307 remove_trace((GtkWidget
*)menuitem
, user_data
);
2312 on_save_activate (GtkMenuItem
*menuitem
,
2315 save((GtkWidget
*)menuitem
, user_data
);
2320 on_save_as_activate (GtkMenuItem
*menuitem
,
2323 save_as((GtkWidget
*)menuitem
, user_data
);
2328 on_quit_activate (GtkMenuItem
*menuitem
,
2331 while (g_slist_length(g_main_window_list
) != 0) {
2332 on_MWindow_destroy(((MainWindow
*)g_main_window_list
->data
)->mwindow
,
2339 on_cut_activate (GtkMenuItem
*menuitem
,
2347 on_copy_activate (GtkMenuItem
*menuitem
,
2355 on_paste_activate (GtkMenuItem
*menuitem
,
2363 on_delete_activate (GtkMenuItem
*menuitem
,
2371 on_zoom_in_activate (GtkMenuItem
*menuitem
,
2374 zoom_in((GtkWidget
*)menuitem
, user_data
);
2379 on_zoom_out_activate (GtkMenuItem
*menuitem
,
2382 zoom_out((GtkWidget
*)menuitem
, user_data
);
2387 on_zoom_extended_activate (GtkMenuItem
*menuitem
,
2390 zoom_extended((GtkWidget
*)menuitem
, user_data
);
2395 on_go_to_time_activate (GtkMenuItem
*menuitem
,
2398 go_to_time((GtkWidget
*)menuitem
, user_data
);
2403 on_show_time_frame_activate (GtkMenuItem
*menuitem
,
2406 show_time_frame((GtkWidget
*)menuitem
, user_data
);
2411 on_move_viewer_up_activate (GtkMenuItem
*menuitem
,
2414 move_up_viewer((GtkWidget
*)menuitem
, user_data
);
2419 on_move_viewer_down_activate (GtkMenuItem
*menuitem
,
2422 move_down_viewer((GtkWidget
*)menuitem
, user_data
);
2427 on_remove_viewer_activate (GtkMenuItem
*menuitem
,
2430 delete_viewer((GtkWidget
*)menuitem
, user_data
);
2434 on_trace_facility_activate (GtkMenuItem
*menuitem
,
2437 g_info("Trace facility selector: %s\n", "");
2441 /* Dispaly a file selection dialogue to let user select a library, then call
2442 * lttv_library_load().
2446 on_load_library_activate (GtkMenuItem
*menuitem
,
2449 GError
*error
= NULL
;
2450 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2452 gchar load_module_path_alter
[PATH_MAX
];
2456 gchar
*load_module_path
;
2457 name
= g_ptr_array_new();
2458 nb
= lttv_library_path_number();
2459 /* ask for the library path */
2463 path
= lttv_library_path_get(i
);
2464 g_ptr_array_add(name
, path
);
2467 load_module_path
= get_selection(mw_data
,
2468 (char **)(name
->pdata
), name
->len
,
2469 "Select a library path", "Library paths");
2470 if(load_module_path
!= NULL
)
2471 strncpy(load_module_path_alter
, load_module_path
, PATH_MAX
-1); // -1 for /
2473 g_ptr_array_free(name
, TRUE
);
2475 if(load_module_path
== NULL
) return;
2479 /* Make sure the module path ends with a / */
2480 gchar
*ptr
= load_module_path_alter
;
2482 ptr
= strchr(ptr
, '\0');
2484 if(*(ptr
-1) != '/') {
2491 /* Ask for the library to load : list files in the previously selected
2493 gchar str
[PATH_MAX
];
2496 GtkFileSelection
* file_selector
=
2497 (GtkFileSelection
*)gtk_file_selection_new("Select a module");
2498 gtk_file_selection_set_filename(file_selector
, load_module_path_alter
);
2499 gtk_file_selection_hide_fileop_buttons(file_selector
);
2501 gtk_window_set_transient_for(GTK_WINDOW(file_selector
),
2502 GTK_WINDOW(mw_data
->mwindow
));
2505 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
2507 case GTK_RESPONSE_ACCEPT
:
2508 case GTK_RESPONSE_OK
:
2509 dir
= gtk_file_selection_get_selections (file_selector
);
2510 strncpy(str
,dir
[0],PATH_MAX
);
2511 strncpy(remember_plugins_dir
,dir
[0],PATH_MAX
);
2512 /* only keep file name */
2514 str1
= strrchr(str
,'/');
2517 str1
= strrchr(str
,'\\');
2522 if(*str1
== 'l' && *(str1
+1)== 'i' && *(str1
+2)=='b')
2524 remove info after
. */
2528 str2
= strrchr(str2
, '.');
2529 if(str2
!= NULL
) *str2
= '\0';
2531 lttv_module_require(str1
, &error
);
2533 lttv_library_load(str1
, &error
);
2534 if(error
!= NULL
) g_warning("%s", error
->message
);
2535 else g_info("Load library: %s\n", str
);
2537 case GTK_RESPONSE_REJECT
:
2538 case GTK_RESPONSE_CANCEL
:
2540 gtk_widget_destroy((GtkWidget
*)file_selector
);
2551 /* Display all loaded modules, let user to select a module to unload
2552 * by calling lttv_module_unload
2556 on_unload_library_activate (GtkMenuItem
*menuitem
,
2559 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2561 LttvLibrary
*library
= NULL
;
2566 name
= g_ptr_array_new();
2567 nb
= lttv_library_number();
2568 LttvLibraryInfo
*lib_info
= g_new(LttvLibraryInfo
,nb
);
2569 /* ask for the library name */
2572 LttvLibrary
*iter_lib
= lttv_library_get(i
);
2573 lttv_library_info(iter_lib
, &lib_info
[i
]);
2575 gchar
*path
= lib_info
[i
].name
;
2576 g_ptr_array_add(name
, path
);
2578 lib_name
= get_selection(mw_data
, (char **)(name
->pdata
), name
->len
,
2579 "Select a library", "Libraries");
2580 if(lib_name
!= NULL
) {
2582 if(strcmp(lib_name
, lib_info
[i
].name
) == 0) {
2583 library
= lttv_library_get(i
);
2588 g_ptr_array_free(name
, TRUE
);
2591 if(lib_name
== NULL
) return;
2593 if(library
!= NULL
) lttv_library_unload(library
);
2597 /* Dispaly a file selection dialogue to let user select a module, then call
2598 * lttv_module_require().
2602 on_load_module_activate (GtkMenuItem
*menuitem
,
2605 GError
*error
= NULL
;
2606 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2608 LttvLibrary
*library
= NULL
;
2613 name
= g_ptr_array_new();
2614 nb
= lttv_library_number();
2615 LttvLibraryInfo
*lib_info
= g_new(LttvLibraryInfo
,nb
);
2616 /* ask for the library name */
2619 LttvLibrary
*iter_lib
= lttv_library_get(i
);
2620 lttv_library_info(iter_lib
, &lib_info
[i
]);
2622 gchar
*path
= lib_info
[i
].name
;
2623 g_ptr_array_add(name
, path
);
2625 lib_name
= get_selection(mw_data
,(char **)(name
->pdata
), name
->len
,
2626 "Select a library", "Libraries");
2627 if(lib_name
!= NULL
) {
2629 if(strcmp(lib_name
, lib_info
[i
].name
) == 0) {
2630 library
= lttv_library_get(i
);
2635 g_ptr_array_free(name
, TRUE
);
2638 if(lib_name
== NULL
) return;
2641 //LttvModule *module;
2642 gchar module_name_out
[PATH_MAX
];
2644 /* Ask for the module to load : list modules in the selected lib */
2648 nb
= lttv_library_module_number(library
);
2649 LttvModuleInfo
*module_info
= g_new(LttvModuleInfo
,nb
);
2650 name
= g_ptr_array_new();
2651 /* ask for the module name */
2654 LttvModule
*iter_module
= lttv_library_module_get(library
, i
);
2655 lttv_module_info(iter_module
, &module_info
[i
]);
2657 gchar
*path
= module_info
[i
].name
;
2658 g_ptr_array_add(name
, path
);
2660 module_name
= get_selection(mw_data
, (char **)(name
->pdata
), name
->len
,
2661 "Select a module", "Modules");
2662 if(module_name
!= NULL
) {
2664 if(strcmp(module_name
, module_info
[i
].name
) == 0) {
2665 strncpy(module_name_out
, module_name
, PATH_MAX
);
2666 //module = lttv_library_module_get(i);
2672 g_ptr_array_free(name
, TRUE
);
2673 g_free(module_info
);
2675 if(module_name
== NULL
) return;
2678 lttv_module_require(module_name_out
, &error
);
2679 if(error
!= NULL
) g_warning("%s", error
->message
);
2680 else g_info("Load module: %s", module_name_out
);
2687 gchar str
[PATH_MAX
];
2690 GtkFileSelection
* file_selector
=
2691 (GtkFileSelection
*)gtk_file_selection_new("Select a module");
2692 gtk_file_selection_set_filename(file_selector
, load_module_path_alter
);
2693 gtk_file_selection_hide_fileop_buttons(file_selector
);
2696 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
2698 case GTK_RESPONSE_ACCEPT
:
2699 case GTK_RESPONSE_OK
:
2700 dir
= gtk_file_selection_get_selections (file_selector
);
2701 strncpy(str
,dir
[0],PATH_MAX
);
2702 strncpy(remember_plugins_dir
,dir
[0],PATH_MAX
);
2704 /* only keep file name */
2706 str1
= strrchr(str
,'/');
2709 str1
= strrchr(str
,'\\');
2714 if(*str1
== 'l' && *(str1
+1)== 'i' && *(str1
+2)=='b')
2716 remove info after
. */
2720 str2
= strrchr(str2
, '.');
2721 if(str2
!= NULL
) *str2
= '\0';
2723 lttv_module_require(str1
, &error
);
2725 lttv_library_load(str1
, &error
);
2726 if(error
!= NULL
) g_warning(error
->message
);
2727 else g_info("Load library: %s\n", str
);
2729 case GTK_RESPONSE_REJECT
:
2730 case GTK_RESPONSE_CANCEL
:
2732 gtk_widget_destroy((GtkWidget
*)file_selector
);
2744 /* Display all loaded modules, let user to select a module to unload
2745 * by calling lttv_module_unload
2749 on_unload_module_activate (GtkMenuItem
*menuitem
,
2752 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2754 LttvLibrary
*library
= NULL
;
2759 name
= g_ptr_array_new();
2760 nb
= lttv_library_number();
2761 LttvLibraryInfo
*lib_info
= g_new(LttvLibraryInfo
,nb
);
2762 /* ask for the library name */
2765 LttvLibrary
*iter_lib
= lttv_library_get(i
);
2766 lttv_library_info(iter_lib
, &lib_info
[i
]);
2768 gchar
*path
= lib_info
[i
].name
;
2769 g_ptr_array_add(name
, path
);
2771 lib_name
= get_selection(mw_data
, (char **)(name
->pdata
), name
->len
,
2772 "Select a library", "Libraries");
2773 if(lib_name
!= NULL
) {
2775 if(strcmp(lib_name
, lib_info
[i
].name
) == 0) {
2776 library
= lttv_library_get(i
);
2781 g_ptr_array_free(name
, TRUE
);
2784 if(lib_name
== NULL
) return;
2787 LttvModule
*module
= NULL
;
2789 /* Ask for the module to load : list modules in the selected lib */
2793 nb
= lttv_library_module_number(library
);
2794 LttvModuleInfo
*module_info
= g_new(LttvModuleInfo
,nb
);
2795 name
= g_ptr_array_new();
2796 /* ask for the module name */
2799 LttvModule
*iter_module
= lttv_library_module_get(library
, i
);
2800 lttv_module_info(iter_module
, &module_info
[i
]);
2802 gchar
*path
= module_info
[i
].name
;
2803 if(module_info
[i
].use_count
> 0) g_ptr_array_add(name
, path
);
2805 module_name
= get_selection(mw_data
, (char **)(name
->pdata
), name
->len
,
2806 "Select a module", "Modules");
2807 if(module_name
!= NULL
) {
2809 if(strcmp(module_name
, module_info
[i
].name
) == 0) {
2810 module
= lttv_library_module_get(library
, i
);
2816 g_ptr_array_free(name
, TRUE
);
2817 g_free(module_info
);
2819 if(module_name
== NULL
) return;
2822 LttvModuleInfo module_info
;
2823 lttv_module_info(module
, &module_info
);
2824 g_info("Release module: %s\n", module_info
.name
);
2826 lttv_module_release(module
);
2830 /* Display a directory dialogue to let user select a path for library searching
2834 on_add_library_search_path_activate (GtkMenuItem
*menuitem
,
2837 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2838 //GtkDirSelection * file_selector = (GtkDirSelection *)gtk_dir_selection_new("Select library path");
2839 GtkFileSelection
* file_selector
= (GtkFileSelection
*)gtk_file_selection_new("Select a trace");
2840 gtk_widget_hide( (file_selector
)->file_list
->parent
) ;
2842 gtk_window_set_transient_for(GTK_WINDOW(file_selector
),
2843 GTK_WINDOW(mw_data
->mwindow
));
2848 if(remember_plugins_dir
[0] != '\0')
2849 gtk_file_selection_set_filename(file_selector
, remember_plugins_dir
);
2851 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
2853 case GTK_RESPONSE_ACCEPT
:
2854 case GTK_RESPONSE_OK
:
2855 dir
= gtk_file_selection_get_filename (file_selector
);
2856 strncpy(remember_plugins_dir
,dir
,PATH_MAX
);
2857 strncat(remember_plugins_dir
,"/",PATH_MAX
);
2858 lttv_library_path_add(dir
);
2859 case GTK_RESPONSE_REJECT
:
2860 case GTK_RESPONSE_CANCEL
:
2862 gtk_widget_destroy((GtkWidget
*)file_selector
);
2868 /* Display a directory dialogue to let user select a path for library searching
2872 on_remove_library_search_path_activate (GtkMenuItem
*menuitem
,
2875 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2877 const char *lib_path
;
2881 name
= g_ptr_array_new();
2882 nb
= lttv_library_path_number();
2883 /* ask for the library name */
2886 gchar
*path
= lttv_library_path_get(i
);
2887 g_ptr_array_add(name
, path
);
2889 lib_path
= get_selection(mw_data
, (char **)(name
->pdata
), name
->len
,
2890 "Select a library path", "Library paths");
2892 g_ptr_array_free(name
, TRUE
);
2894 if(lib_path
== NULL
) return;
2897 lttv_library_path_remove(lib_path
);
2901 on_color_activate (GtkMenuItem
*menuitem
,
2909 on_save_configuration_activate (GtkMenuItem
*menuitem
,
2912 g_info("Save configuration\n");
2917 on_content_activate (GtkMenuItem
*menuitem
,
2920 char* filename
= NULL
,
2923 const char* relativePath
= "doc/user/user_guide/html/index.html";
2924 filename
= g_build_filename (g_get_current_dir(), relativePath
, NULL
);
2925 path
= g_strdup_printf ("ghelp://%s", filename
);
2927 screen
= gdk_screen_get_default();
2928 gtk_show_uri (screen
, path
, gtk_get_current_event_time(), NULL
);
2932 g_info("Content\n");
2937 on_about_close_activate (GtkButton
*button
,
2940 GtkWidget
*about_widget
= GTK_WIDGET(user_data
);
2942 gtk_widget_destroy(about_widget
);
2946 on_about_activate (GtkMenuItem
*menuitem
,
2949 MainWindow
*main_window
= get_window_data_struct(GTK_WIDGET(menuitem
));
2950 GtkWidget
*window_widget
= main_window
->mwindow
;
2951 GtkWidget
*about_widget
= gtk_window_new(GTK_WINDOW_TOPLEVEL
);
2952 GtkWindow
*about_window
= GTK_WINDOW(about_widget
);
2954 gtk_window_set_title(about_window
, "About Linux Trace Toolkit");
2956 gtk_window_set_resizable(about_window
, FALSE
);
2957 gtk_window_set_transient_for(about_window
, GTK_WINDOW(window_widget
));
2958 gtk_window_set_destroy_with_parent(about_window
, TRUE
);
2959 gtk_window_set_modal(about_window
, FALSE
);
2961 /* Put the about window at the center of the screen */
2962 gtk_window_set_position(about_window
, GTK_WIN_POS_CENTER_ALWAYS
);
2964 GtkWidget
*vbox
= gtk_vbox_new(FALSE
, 1);
2966 gtk_container_add(GTK_CONTAINER(about_widget
), vbox
);
2969 GtkWidget
*label1
= gtk_label_new("");
2970 gtk_misc_set_padding(GTK_MISC(label1
), 10, 20);
2971 gtk_label_set_markup(GTK_LABEL(label1
), "\
2972 <big>Linux Trace Toolkit " VERSION
"</big>");
2973 gtk_label_set_justify(GTK_LABEL(label1
), GTK_JUSTIFY_CENTER
);
2975 GtkWidget
*label2
= gtk_label_new("");
2976 gtk_misc_set_padding(GTK_MISC(label2
), 10, 20);
2977 gtk_label_set_markup(GTK_LABEL(label2
), "\
2980 Michel Dagenais (New trace format, lttv main)\n\
2981 Mathieu Desnoyers (Kernel Tracer, Directory structure, build with automake/conf,\n\
2982 lttv gui, control flow view, gui cooperative trace reading\n\
2983 scheduler with interruptible foreground and background\n\
2984 computation, detailed event list (rewrite), trace reading\n\
2985 library (rewrite))\n\
2986 Benoit Des Ligneris, Eric Clement (Cluster adaptation, work in progress)\n\
2987 Xang-Xiu Yang (new trace reading library and converter, lttv gui, \n\
2988 detailed event list and statistics view)\n\
2989 Tom Zanussi (RelayFS)\n\
2991 Inspired from the original Linux Trace Toolkit Visualizer made by\n\
2994 GtkWidget
*label3
= gtk_label_new("");
2995 gtk_label_set_markup(GTK_LABEL(label3
), "\
2996 Linux Trace Toolkit Viewer, Copyright (C) 2004, 2005, 2006\n\
2998 Mathieu Desnoyers\n\
3000 Linux Trace Toolkit comes with ABSOLUTELY NO WARRANTY.\n\
3001 This is free software, and you are welcome to redistribute it\n\
3002 under certain conditions. See COPYING for details.");
3003 gtk_misc_set_padding(GTK_MISC(label3
), 10, 20);
3005 gtk_box_pack_start_defaults(GTK_BOX(vbox
), label1
);
3006 gtk_box_pack_start_defaults(GTK_BOX(vbox
), label2
);
3007 gtk_box_pack_start_defaults(GTK_BOX(vbox
), label3
);
3009 GtkWidget
*hbox
= gtk_hbox_new(TRUE
, 0);
3010 gtk_box_pack_end(GTK_BOX(vbox
), hbox
, FALSE
, FALSE
, 0);
3011 GtkWidget
*close_button
= gtk_button_new_with_mnemonic("_Close");
3012 gtk_box_pack_end(GTK_BOX(hbox
), close_button
, FALSE
, FALSE
, 0);
3013 gtk_container_set_border_width(GTK_CONTAINER(close_button
), 20);
3015 g_signal_connect(G_OBJECT(close_button
), "clicked",
3016 G_CALLBACK(on_about_close_activate
),
3017 (gpointer
)about_widget
);
3019 gtk_widget_show_all(about_widget
);
3024 on_button_new_clicked (GtkButton
*button
,
3027 create_new_window((GtkWidget
*)button
, user_data
, TRUE
);
3031 on_button_new_tab_clicked (GtkButton
*button
,
3034 create_new_tab((GtkWidget
*)button
, user_data
);
3038 on_button_open_clicked (GtkButton
*button
,
3041 #ifdef UNFINISHED_FEATURE
3042 open_traceset((GtkWidget
*)button
, user_data
);
3048 on_button_add_trace_clicked (GtkButton
*button
,
3051 add_trace((GtkWidget
*)button
, user_data
);
3056 on_button_remove_trace_clicked (GtkButton
*button
,
3059 remove_trace((GtkWidget
*)button
, user_data
);
3063 on_button_redraw_clicked (GtkButton
*button
,
3066 redraw((GtkWidget
*)button
, user_data
);
3070 on_button_continue_processing_clicked (GtkButton
*button
,
3073 continue_processing((GtkWidget
*)button
, user_data
);
3077 on_button_stop_processing_clicked (GtkButton
*button
,
3080 stop_processing((GtkWidget
*)button
, user_data
);
3086 on_button_save_clicked (GtkButton
*button
,
3089 save((GtkWidget
*)button
, user_data
);
3094 on_button_save_as_clicked (GtkButton
*button
,
3097 save_as((GtkWidget
*)button
, user_data
);
3102 on_button_zoom_in_clicked (GtkButton
*button
,
3105 zoom_in((GtkWidget
*)button
, user_data
);
3110 on_button_zoom_out_clicked (GtkButton
*button
,
3113 zoom_out((GtkWidget
*)button
, user_data
);
3118 on_button_zoom_extended_clicked (GtkButton
*button
,
3121 zoom_extended((GtkWidget
*)button
, user_data
);
3126 on_button_go_to_time_clicked (GtkButton
*button
,
3129 go_to_time((GtkWidget
*)button
, user_data
);
3134 on_button_show_time_frame_clicked (GtkButton
*button
,
3137 show_time_frame((GtkWidget
*)button
, user_data
);
3142 on_button_move_up_clicked (GtkButton
*button
,
3145 move_up_viewer((GtkWidget
*)button
, user_data
);
3150 on_button_move_down_clicked (GtkButton
*button
,
3153 move_down_viewer((GtkWidget
*)button
, user_data
);
3158 on_button_delete_viewer_clicked (GtkButton
*button
,
3161 delete_viewer((GtkWidget
*)button
, user_data
);
3165 on_MWindow_destroy (GtkWidget
*widget
,
3168 MainWindow
*main_window
= get_window_data_struct(widget
);
3169 LttvIAttribute
*attributes
= main_window
->attributes
;
3170 LttvAttributeValue value
;
3173 //This is unnecessary, since widgets will be destroyed
3174 //by the main window widget anyway.
3175 //remove_all_menu_toolbar_constructors(main_window, NULL);
3177 retval
= lttv_iattribute_find_by_path(attributes
, "viewers/menu",
3178 LTTV_POINTER
, &value
);
3180 lttv_menus_destroy((LttvMenus
*)*(value
.v_pointer
));
3182 retval
= lttv_iattribute_find_by_path(attributes
, "viewers/toolbar",
3183 LTTV_POINTER
, &value
);
3185 lttv_toolbars_destroy((LttvToolbars
*)*(value
.v_pointer
));
3187 g_object_unref(main_window
->attributes
);
3188 g_main_window_list
= g_slist_remove(g_main_window_list
, main_window
);
3190 g_info("There are now : %d windows\n",g_slist_length(g_main_window_list
));
3191 if(g_slist_length(g_main_window_list
) == 0)
3196 on_MWindow_configure (GtkWidget
*widget
,
3197 GdkEventConfigure
*event
,
3200 // MD : removed time width modification upon resizing of the main window.
3201 // The viewers will redraw themselves completely, without time interval
3204 if(mw_data->window_width){
3205 time_span = LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context)->Time_Span ;
3206 time_win = tab->time_window;
3207 ratio = width / mw_data->window_width;
3208 tab->time_window.time_width = ltt_time_mul(time_win.time_width,ratio);
3209 time = ltt_time_sub(time_span->endTime, time_win.start_time);
3210 if(ltt_time_compare(time, tab->time_window.time_width) < 0){
3211 tab->time_window.time_width = time;
3217 mw_data->window_width = (int)width;
3226 on_MNotebook_switch_page (GtkNotebook
*notebook
,
3227 GtkNotebookPage
*page
,
3235 void time_change_manager (Tab
*tab
,
3236 TimeWindow new_time_window
)
3238 /* Only one source of time change */
3239 if(tab
->time_manager_lock
== TRUE
) return;
3241 tab
->time_manager_lock
= TRUE
;
3243 LttvTracesetContext
*tsc
= LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3244 TimeInterval time_span
= tsc
->time_span
;
3245 LttTime start_time
= new_time_window
.start_time
;
3246 LttTime end_time
= new_time_window
.end_time
;
3248 g_assert(ltt_time_compare(start_time
, end_time
) < 0);
3251 GtkAdjustment
*adjustment
= gtk_range_get_adjustment(GTK_RANGE(tab
->scrollbar
));
3252 LttTime upper
= ltt_time_sub(time_span
.end_time
, time_span
.start_time
);
3254 gtk_range_set_increments(GTK_RANGE(tab
->scrollbar
),
3255 ltt_time_to_double(new_time_window
.time_width
)
3256 / SCROLL_STEP_PER_PAGE
3257 * NANOSECONDS_PER_SECOND
, /* step increment */
3258 ltt_time_to_double(new_time_window
.time_width
)
3259 * NANOSECONDS_PER_SECOND
); /* page increment */
3260 gtk_range_set_range(GTK_RANGE(tab
->scrollbar
),
3262 ltt_time_to_double(upper
)
3263 * NANOSECONDS_PER_SECOND
); /* upper */
3265 g_object_set(G_OBJECT(adjustment
),
3269 ltt_time_to_double(upper
), /* upper */
3271 new_time_window
.time_width_double
3272 / SCROLL_STEP_PER_PAGE
, /* step increment */
3274 new_time_window
.time_width_double
,
3275 /* page increment */
3277 new_time_window
.time_width_double
, /* page size */
3279 gtk_adjustment_changed(adjustment
);
3281 // g_object_set(G_OBJECT(adjustment),
3283 // ltt_time_to_double(
3284 // ltt_time_sub(start_time, time_span.start_time))
3287 //gtk_adjustment_value_changed(adjustment);
3288 gtk_range_set_value(GTK_RANGE(tab
->scrollbar
),
3290 ltt_time_sub(start_time
, time_span
.start_time
)) /* value */);
3292 /* set the time bar. */
3295 timebar_set_minmax_time(TIMEBAR(tab
->MTimebar
),
3296 &time_span
.start_time
,
3297 &time_span
.end_time
);
3298 timebar_set_start_time(TIMEBAR(tab
->MTimebar
),&start_time
);
3299 timebar_set_end_time(TIMEBAR(tab
->MTimebar
),&end_time
);
3303 /* call viewer hooks for new time window */
3304 set_time_window(tab
, &new_time_window
);
3306 tab
->time_manager_lock
= FALSE
;
3313 void current_time_change_manager (Tab
*tab
,
3314 LttTime new_current_time
)
3316 /* Only one source of time change */
3317 if(tab
->current_time_manager_lock
== TRUE
) return;
3319 tab
->current_time_manager_lock
= TRUE
;
3321 timebar_set_current_time(TIMEBAR(tab
->MTimebar
), &new_current_time
);
3323 set_current_time(tab
, &new_current_time
);
3325 tab
->current_time_manager_lock
= FALSE
;
3328 void current_position_change_manager(Tab
*tab
,
3329 LttvTracesetContextPosition
*pos
)
3331 LttvTracesetContext
*tsc
=
3332 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3335 retval
= lttv_process_traceset_seek_position(tsc
, pos
);
3336 g_assert_cmpint(retval
, ==, 0);
3337 LttTime new_time
= lttv_traceset_context_position_get_time(pos
);
3338 /* Put the context in a state coherent position */
3339 lttv_state_traceset_seek_time_closest((LttvTracesetState
*)tsc
, ltt_time_zero
);
3341 current_time_change_manager(tab
, new_time
);
3343 set_current_position(tab
, pos
);
3346 static void on_timebar_starttime_changed(Timebar
*timebar
,
3349 Tab
*tab
= (Tab
*)user_data
;
3350 LttvTracesetContext
* tsc
=
3351 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3352 TimeInterval time_span
= tsc
->time_span
;
3354 TimeWindow new_time_window
= tab
->time_window
;
3355 new_time_window
.start_time
= timebar_get_start_time(timebar
);
3357 LttTime end_time
= new_time_window
.end_time
;
3359 /* TODO ybrosseau 2010-12-02: This if should have been checked
3360 by the timebar already */
3361 if(ltt_time_compare(new_time_window
.start_time
, end_time
) >= 0) {
3362 /* Then, we must push back end time : keep the same time width
3363 * if possible, else end traceset time */
3364 end_time
= LTT_TIME_MIN(ltt_time_add(new_time_window
.start_time
,
3365 new_time_window
.time_width
),
3366 time_span
.end_time
);
3369 /* Fix the time width to fit start time and end time */
3370 new_time_window
.time_width
= ltt_time_sub(end_time
,
3371 new_time_window
.start_time
);
3373 new_time_window
.time_width_double
=
3374 ltt_time_to_double(new_time_window
.time_width
);
3376 new_time_window
.end_time
= end_time
;
3378 /* Notify the time_manager */
3379 time_change_manager(tab
, new_time_window
);
3383 static void on_timebar_endtime_changed(Timebar
*timebar
,
3386 Tab
*tab
= (Tab
*)user_data
;
3387 LttvTracesetContext
* tsc
=
3388 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3389 TimeInterval time_span
= tsc
->time_span
;
3391 TimeWindow new_time_window
= tab
->time_window
;
3393 LttTime end_time
= timebar_get_end_time(timebar
);
3395 /* TODO ybrosseau 2010-12-02: This if should have been
3396 checked by the timebar already */
3397 if(ltt_time_compare(new_time_window
.start_time
, end_time
) >= 0) {
3398 /* Then, we must push front start time : keep the same time
3399 width if possible, else end traceset time */
3400 new_time_window
.start_time
= LTT_TIME_MAX(
3401 ltt_time_sub(end_time
,
3402 new_time_window
.time_width
),
3403 time_span
.start_time
);
3406 /* Fix the time width to fit start time and end time */
3407 new_time_window
.time_width
= ltt_time_sub(end_time
,
3408 new_time_window
.start_time
);
3410 new_time_window
.time_width_double
=
3411 ltt_time_to_double(new_time_window
.time_width
);
3413 new_time_window
.end_time
= end_time
;
3415 /* Notify the time_manager */
3416 time_change_manager(tab
, new_time_window
);
3418 static void on_timebar_currenttime_changed(Timebar
*timebar
,
3421 Tab
*tab
= (Tab
*)user_data
;
3423 LttTime new_current_time
= timebar_get_current_time(timebar
);
3425 current_time_change_manager(tab
, new_current_time
);
3428 void scroll_value_changed_cb(GtkWidget
*scrollbar
,
3431 Tab
*tab
= (Tab
*)user_data
;
3432 TimeWindow new_time_window
;
3434 GtkAdjustment
*adjust
= gtk_range_get_adjustment(GTK_RANGE(scrollbar
));
3435 gdouble value
= gtk_adjustment_get_value(adjust
);
3436 // gdouble upper, lower, ratio, page_size;
3438 LttvTracesetContext
* tsc
=
3439 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3440 TimeInterval time_span
= tsc
->time_span
;
3442 time
= ltt_time_add(ltt_time_from_double(value
),
3443 time_span
.start_time
);
3445 new_time_window
.start_time
= time
;
3447 page_size
= adjust
->page_size
;
3449 new_time_window
.time_width
=
3450 ltt_time_from_double(page_size
);
3452 new_time_window
.time_width_double
=
3455 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
3456 new_time_window
.time_width
);
3459 time_change_manager(tab
, new_time_window
);
3461 //time_window = tab->time_window;
3463 lower
= adjust
->lower
;
3464 upper
= adjust
->upper
;
3465 ratio
= (value
- lower
) / (upper
- lower
);
3466 g_info("lower %lu, upper %lu, value %lu, ratio %lu", lower
, upper
, value
, ratio
);
3468 //time = ltt_time_sub(time_span->end_time, time_span->start_time);
3469 //time = ltt_time_mul(time, (float)ratio);
3470 //time = ltt_time_add(time_span->start_time, time);
3471 time
= ltt_time_add(ltt_time_from_double(value
),
3472 time_span
.start_time
);
3474 time_window
.start_time
= time
;
3476 page_size
= adjust
->page_size
;
3478 time_window
.time_width
=
3479 ltt_time_from_double(page_size
);
3480 //time = ltt_time_sub(time_span.end_time, time);
3481 //if(ltt_time_compare(time,time_window.time_width) < 0){
3482 // time_window.time_width = time;
3485 /* call viewer hooks for new time window */
3486 set_time_window(tab
, &time_window
);
3491 /* Display a dialogue showing all eventtypes and traces, let user to select the interested
3492 * eventtypes, tracefiles and traces (filter)
3495 /* Select a trace which will be removed from traceset
3498 char * get_remove_trace(MainWindow
*mw_data
,
3499 char ** all_trace_name
, int nb_trace
)
3501 return get_selection(mw_data
, all_trace_name
, nb_trace
,
3502 "Select a trace", "Trace pathname");
3506 /* Select a module which will be loaded
3509 char * get_load_module(MainWindow
*mw_data
,
3510 char ** load_module_name
, int nb_module
)
3512 return get_selection(mw_data
, load_module_name
, nb_module
,
3513 "Select a module to load", "Module name");
3519 /* Select a module which will be unloaded
3522 char * get_unload_module(MainWindow
*mw_data
,
3523 char ** loaded_module_name
, int nb_module
)
3525 return get_selection(mw_data
, loaded_module_name
, nb_module
,
3526 "Select a module to unload", "Module name");
3530 /* Display a dialogue which shows all selectable items, let user to
3531 * select one of them
3534 char * get_selection(MainWindow
*mw_data
,
3535 char ** loaded_module_name
, int nb_module
,
3536 char *title
, char * column_title
)
3538 GtkWidget
* dialogue
;
3539 GtkWidget
* scroll_win
;
3541 GtkListStore
* store
;
3542 GtkTreeViewColumn
* column
;
3543 GtkCellRenderer
* renderer
;
3544 GtkTreeSelection
* select
;
3547 char * unload_module_name
= NULL
;
3549 dialogue
= gtk_dialog_new_with_buttons(title
,
3552 GTK_STOCK_OK
,GTK_RESPONSE_ACCEPT
,
3553 GTK_STOCK_CANCEL
,GTK_RESPONSE_REJECT
,
3555 gtk_window_set_default_size((GtkWindow
*)dialogue
, 500, 200);
3556 gtk_window_set_transient_for(GTK_WINDOW(dialogue
),
3557 GTK_WINDOW(mw_data
->mwindow
));
3559 scroll_win
= gtk_scrolled_window_new (NULL
, NULL
);
3560 gtk_widget_show ( scroll_win
);
3561 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll_win
),
3562 GTK_POLICY_AUTOMATIC
, GTK_POLICY_AUTOMATIC
);
3564 store
= gtk_list_store_new (N_COLUMNS
,G_TYPE_STRING
);
3565 tree
= gtk_tree_view_new_with_model(GTK_TREE_MODEL (store
));
3566 gtk_widget_show ( tree
);
3567 g_object_unref (G_OBJECT (store
));
3569 renderer
= gtk_cell_renderer_text_new ();
3570 column
= gtk_tree_view_column_new_with_attributes (column_title
,
3572 "text", MODULE_COLUMN
,
3574 gtk_tree_view_column_set_alignment (column
, 0.5);
3575 gtk_tree_view_column_set_fixed_width (column
, 150);
3576 gtk_tree_view_append_column (GTK_TREE_VIEW (tree
), column
);
3578 select
= gtk_tree_view_get_selection (GTK_TREE_VIEW (tree
));
3579 gtk_tree_selection_set_mode (select
, GTK_SELECTION_SINGLE
);
3581 gtk_container_add (GTK_CONTAINER (scroll_win
), tree
);
3583 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialogue
)->vbox
), scroll_win
,TRUE
, TRUE
,0);
3585 for(i
=0;i
<nb_module
;i
++){
3586 gtk_list_store_append (store
, &iter
);
3587 gtk_list_store_set (store
, &iter
, MODULE_COLUMN
,loaded_module_name
[i
],-1);
3590 id
= gtk_dialog_run(GTK_DIALOG(dialogue
));
3591 GtkTreeModel
**store_model
= (GtkTreeModel
**)&store
;
3593 case GTK_RESPONSE_ACCEPT
:
3594 case GTK_RESPONSE_OK
:
3595 if (gtk_tree_selection_get_selected (select
, store_model
, &iter
)){
3596 gtk_tree_model_get ((GtkTreeModel
*)store
, &iter
, MODULE_COLUMN
, &unload_module_name
, -1);
3598 case GTK_RESPONSE_REJECT
:
3599 case GTK_RESPONSE_CANCEL
:
3601 gtk_widget_destroy(dialogue
);
3605 return unload_module_name
;
3609 /* Insert all menu entry and tool buttons into this main window
3614 void add_all_menu_toolbar_constructors(MainWindow
* mw
, gpointer user_data
)
3618 lttvwindow_viewer_constructor constructor
;
3619 LttvMenus
* global_menu
, * instance_menu
;
3620 LttvToolbars
* global_toolbar
, * instance_toolbar
;
3621 LttvMenuClosure
*menu_item
;
3622 LttvToolbarClosure
*toolbar_item
;
3623 LttvAttributeValue value
;
3624 LttvIAttribute
*global_attributes
= LTTV_IATTRIBUTE(lttv_global_attributes());
3625 LttvIAttribute
*attributes
= mw
->attributes
;
3626 GtkWidget
* tool_menu_title_menu
, *new_widget
, *pixmap
;
3629 retval
= lttv_iattribute_find_by_path(global_attributes
, "viewers/menu",
3630 LTTV_POINTER
, &value
);
3632 if(*(value
.v_pointer
) == NULL
)
3633 *(value
.v_pointer
) = lttv_menus_new();
3634 global_menu
= (LttvMenus
*)*(value
.v_pointer
);
3636 retval
= lttv_iattribute_find_by_path(attributes
, "viewers/menu",
3637 LTTV_POINTER
, &value
);
3639 if(*(value
.v_pointer
) == NULL
)
3640 *(value
.v_pointer
) = lttv_menus_new();
3641 instance_menu
= (LttvMenus
*)*(value
.v_pointer
);
3643 retval
= lttv_iattribute_find_by_path(global_attributes
, "viewers/toolbar",
3644 LTTV_POINTER
, &value
);
3646 if(*(value
.v_pointer
) == NULL
)
3647 *(value
.v_pointer
) = lttv_toolbars_new();
3648 global_toolbar
= (LttvToolbars
*)*(value
.v_pointer
);
3650 retval
= lttv_iattribute_find_by_path(attributes
, "viewers/toolbar",
3651 LTTV_POINTER
, &value
);
3653 if(*(value
.v_pointer
) == NULL
)
3654 *(value
.v_pointer
) = lttv_toolbars_new();
3655 instance_toolbar
= (LttvToolbars
*)*(value
.v_pointer
);
3657 /* Add missing menu entries to window instance */
3658 for(i
=0;i
<global_menu
->len
;i
++) {
3659 menu_item
= &g_array_index(global_menu
, LttvMenuClosure
, i
);
3661 //add menu_item to window instance;
3662 constructor
= menu_item
->con
;
3663 tool_menu_title_menu
= lookup_widget(mw
->mwindow
,"ToolMenuTitle_menu");
3665 gtk_menu_item_new_with_mnemonic (menu_item
->menu_text
);
3666 gtk_container_add (GTK_CONTAINER (tool_menu_title_menu
),
3668 g_signal_connect ((gpointer
) new_widget
, "activate",
3669 G_CALLBACK (insert_viewer_wrap
),
3671 gtk_widget_show (new_widget
);
3672 lttv_menus_add(instance_menu
, menu_item
->con
,
3673 menu_item
->menu_path
,
3674 menu_item
->menu_text
,
3679 /* Add missing toolbar entries to window instance */
3680 for(i
=0;i
<global_toolbar
->len
;i
++) {
3681 toolbar_item
= &g_array_index(global_toolbar
, LttvToolbarClosure
, i
);
3683 //add toolbar_item to window instance;
3684 constructor
= toolbar_item
->con
;
3685 tool_menu_title_menu
= lookup_widget(mw
->mwindow
,"MToolbar1");
3686 pixbuf
= gdk_pixbuf_new_from_xpm_data((const char**)toolbar_item
->pixmap
);
3687 pixmap
= gtk_image_new_from_pixbuf(pixbuf
);
3689 gtk_toolbar_append_element (GTK_TOOLBAR (tool_menu_title_menu
),
3690 GTK_TOOLBAR_CHILD_BUTTON
,
3693 toolbar_item
->tooltip
, NULL
,
3694 pixmap
, NULL
, NULL
);
3695 gtk_label_set_use_underline(
3696 GTK_LABEL (((GtkToolbarChild
*) (
3697 g_list_last (GTK_TOOLBAR
3698 (tool_menu_title_menu
)->children
)->data
))->label
),
3700 gtk_container_set_border_width (GTK_CONTAINER (new_widget
), 1);
3701 g_signal_connect ((gpointer
) new_widget
,
3703 G_CALLBACK (insert_viewer_wrap
),
3705 gtk_widget_show (new_widget
);
3707 lttv_toolbars_add(instance_toolbar
, toolbar_item
->con
,
3708 toolbar_item
->tooltip
,
3709 toolbar_item
->pixmap
,
3717 /* Create a main window
3720 MainWindow
*construct_main_window(MainWindow
* parent
)
3724 g_debug("construct_main_window()");
3725 GtkWidget
* new_window
; /* New generated main window */
3726 MainWindow
* new_m_window
;/* New main window structure */
3727 GtkNotebook
* notebook
;
3728 LttvIAttribute
*attributes
=
3729 LTTV_IATTRIBUTE(g_object_new(LTTV_ATTRIBUTE_TYPE
, NULL
));
3730 LttvAttributeValue value
;
3732 new_m_window
= g_new(MainWindow
, 1);
3734 // Add the object's information to the module's array
3735 g_main_window_list
= g_slist_append(g_main_window_list
, new_m_window
);
3737 new_window
= create_MWindow();
3738 gtk_widget_show (new_window
);
3740 new_m_window
->mwindow
= new_window
;
3741 new_m_window
->attributes
= attributes
;
3743 retval
= lttv_iattribute_find_by_path(attributes
, "viewers/menu",
3744 LTTV_POINTER
, &value
);
3746 *(value
.v_pointer
) = lttv_menus_new();
3748 retval
= lttv_iattribute_find_by_path(attributes
, "viewers/toolbar",
3749 LTTV_POINTER
, &value
);
3751 *(value
.v_pointer
) = lttv_toolbars_new();
3753 add_all_menu_toolbar_constructors(new_m_window
, NULL
);
3755 g_object_set_data_full(G_OBJECT(new_window
),
3757 (gpointer
)new_m_window
,
3758 (GDestroyNotify
)g_free
);
3759 //create a default tab
3760 notebook
= (GtkNotebook
*)lookup_widget(new_m_window
->mwindow
, "MNotebook");
3761 if(notebook
== NULL
){
3762 g_info("Notebook does not exist\n");
3763 /* FIXME : destroy partially created widgets */
3764 g_free(new_m_window
);
3767 //gtk_notebook_popup_enable (GTK_NOTEBOOK(notebook));
3768 //for now there is no name field in LttvTraceset structure
3769 //Use "Traceset" as the label for the default tab
3771 GtkWidget
* parent_notebook
= lookup_widget(parent
->mwindow
, "MNotebook");
3772 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(parent_notebook
),
3773 gtk_notebook_get_current_page(GTK_NOTEBOOK(parent_notebook
)));
3779 LttvPluginTab
*ptab
;
3780 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
3781 parent_tab
= ptab
->tab
;
3783 LttvPluginTab
*ptab
= g_object_new(LTTV_TYPE_PLUGIN_TAB
, NULL
);
3785 new_m_window
, parent_tab
, notebook
, "Traceset");
3786 ptab
->parent
.top_widget
= ptab
->tab
->top_widget
;
3787 g_object_set_data_full(
3788 G_OBJECT(ptab
->tab
->vbox
),
3791 (GDestroyNotify
)tab_destructor
);
3793 LttvPluginTab
*ptab
= g_object_new(LTTV_TYPE_PLUGIN_TAB
, NULL
);
3794 init_tab(ptab
->tab
, new_m_window
, NULL
, notebook
, "Traceset");
3795 ptab
->parent
.top_widget
= ptab
->tab
->top_widget
;
3796 g_object_set_data_full(
3797 G_OBJECT(ptab
->tab
->vbox
),
3800 (GDestroyNotify
)tab_destructor
);
3803 /* Insert default viewers */
3805 LttvAttributeType type
;
3806 LttvAttributeName name
;
3807 LttvAttributeValue value
;
3808 LttvAttribute
*attribute
;
3810 LttvIAttribute
*attributes_global
=
3811 LTTV_IATTRIBUTE(lttv_global_attributes());
3813 attribute
= LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
3814 LTTV_IATTRIBUTE(attributes_global
),
3815 LTTV_VIEWER_CONSTRUCTORS
));
3816 g_assert(attribute
);
3818 name
= g_quark_from_string("guievents");
3819 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
3821 if(type
== LTTV_POINTER
) {
3822 lttvwindow_viewer_constructor viewer_constructor
=
3823 (lttvwindow_viewer_constructor
)*value
.v_pointer
;
3824 insert_viewer(new_window
, viewer_constructor
);
3827 name
= g_quark_from_string("guicontrolflow");
3828 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
3830 if(type
== LTTV_POINTER
) {
3831 lttvwindow_viewer_constructor viewer_constructor
=
3832 (lttvwindow_viewer_constructor
)*value
.v_pointer
;
3833 insert_viewer(new_window
, viewer_constructor
);
3836 name
= g_quark_from_string("guistatistics");
3837 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
3839 if(type
== LTTV_POINTER
) {
3840 lttvwindow_viewer_constructor viewer_constructor
=
3841 (lttvwindow_viewer_constructor
)*value
.v_pointer
;
3842 insert_viewer(new_window
, viewer_constructor
);
3846 g_info("There are now : %d windows\n",g_slist_length(g_main_window_list
));
3848 return new_m_window
;
3852 /* Free the memory occupied by a tab structure
3856 void tab_destructor(LttvPluginTab
* ptab
)
3858 int i
, nb
, ref_count
;
3860 Tab
*tab
= ptab
->tab
;
3863 g_object_unref(tab
->attributes
);
3865 if(tab
->interrupted_state
)
3866 g_object_unref(tab
->interrupted_state
);
3869 if(tab
->traceset_info
->traceset_context
!= NULL
){
3870 //remove state update hooks
3871 lttv_state_remove_event_hooks(
3872 (LttvTracesetState
*)tab
->traceset_info
->
3874 lttv_context_fini(LTTV_TRACESET_CONTEXT(tab
->traceset_info
->
3876 g_object_unref(tab
->traceset_info
->traceset_context
);
3878 if(tab
->traceset_info
->traceset
!= NULL
) {
3879 nb
= lttv_traceset_number(tab
->traceset_info
->traceset
);
3880 for(i
= 0 ; i
< nb
; i
++) {
3881 trace
= lttv_traceset_get(tab
->traceset_info
->traceset
, i
);
3882 ref_count
= lttv_trace_get_ref_number(trace
);
3884 ltt_trace_close(lttv_trace(trace
));
3888 lttv_traceset_destroy(tab
->traceset_info
->traceset
);
3889 /* Remove the idle events requests processing function of the tab */
3890 g_idle_remove_by_data(tab
);
3892 g_slist_free(tab
->events_requests
);
3893 g_free(tab
->traceset_info
);
3895 g_object_unref(ptab
);
3899 /* Create a tab and insert it into the current main window
3902 void init_tab(Tab
*tab
, MainWindow
* mw
, Tab
*copy_tab
,
3903 GtkNotebook
* notebook
, char * label
)
3907 //LttvFilter *filter = NULL;
3909 //create a new tab data structure
3910 //tab = g_new(Tab,1);
3912 //construct and initialize the traceset_info
3913 tab
->traceset_info
= g_new(TracesetInfo
,1);
3916 tab
->traceset_info
->traceset
=
3917 lttv_traceset_copy(copy_tab
->traceset_info
->traceset
);
3919 /* Copy the previous tab's filter */
3920 /* We can clone the filter, as we copy the trace set also */
3921 /* The filter must always be in sync with the trace set */
3922 tab
->filter
= lttv_filter_clone(copy_tab
->filter
);
3924 tab
->traceset_info
->traceset
= lttv_traceset_new();
3928 lttv_attribute_write_xml(
3929 lttv_traceset_attribute(tab
->traceset_info
->traceset
),
3935 tab
->time_manager_lock
= FALSE
;
3936 tab
->current_time_manager_lock
= FALSE
;
3938 //FIXME copy not implemented in lower level
3939 tab
->traceset_info
->traceset_context
=
3940 g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
3941 g_assert(tab
->traceset_info
->traceset_context
!= NULL
);
3943 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
),
3944 tab
->traceset_info
->traceset
);
3945 //add state update hooks
3946 lttv_state_add_event_hooks(
3947 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
3949 //determine the current_time and time_window of the tab
3951 if(copy_tab
!= NULL
){
3952 tab
->time_window
= copy_tab
->time_window
;
3953 tab
->current_time
= copy_tab
->current_time
;
3955 tab
->time_window
.start_time
=
3956 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
3957 time_span
.start_time
;
3958 if(DEFAULT_TIME_WIDTH_S
<
3959 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
3960 time_span
.end_time
.tv_sec
)
3961 tmp_time
.tv_sec
= DEFAULT_TIME_WIDTH_S
;
3964 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
3965 time_span
.end_time
.tv_sec
;
3966 tmp_time
.tv_nsec
= 0;
3967 tab
->time_window
.time_width
= tmp_time
;
3968 tab
->current_time
.tv_sec
=
3969 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
3970 time_span
.start_time
.tv_sec
;
3971 tab
->current_time
.tv_nsec
=
3972 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
3973 time_span
.start_time
.tv_nsec
;
3976 tab
->attributes
= LTTV_IATTRIBUTE(g_object_new(LTTV_ATTRIBUTE_TYPE
, NULL
));
3977 tab
->interrupted_state
= g_object_new(LTTV_ATTRIBUTE_TYPE
, NULL
);
3979 tab
->vbox
= gtk_vbox_new(FALSE
, 2);
3980 tab
->top_widget
= tab
->vbox
;
3981 //g_object_set_data_full(G_OBJECT(tab->top_widget), "filter",
3982 // filter, (GDestroyNotify)lttv_filter_destroy);
3984 // g_signal_connect (G_OBJECT(tab->top_widget),
3986 // G_CALLBACK (on_top_notify),
3989 tab
->viewer_container
= gtk_vbox_new(TRUE
, 2);
3990 tab
->scrollbar
= gtk_hscrollbar_new(NULL
);
3991 //tab->multivpaned = gtk_multi_vpaned_new();
3993 gtk_box_pack_start(GTK_BOX(tab
->vbox
),
3994 tab
->viewer_container
,
3996 TRUE
, /* Give the extra space to the child */
3997 0); /* No padding */
4000 // tab->time_window = copy_tab->time_window;
4001 // tab->current_time = copy_tab->current_time;
4004 /* Create the timebar */
4006 tab
->MTimebar
= timebar_new();
4008 gtk_box_pack_end(GTK_BOX(tab
->vbox
),
4010 FALSE
, /* Do not expand */
4011 FALSE
, /* Fill has no effect here (expand false) */
4012 0); /* No padding */
4014 gtk_box_pack_end(GTK_BOX(tab
->vbox
),
4016 FALSE
, /* Do not expand */
4017 FALSE
, /* Fill has no effect here (expand false) */
4018 0); /* No padding */
4020 g_object_set_data(G_OBJECT(tab
->viewer_container
), "focused_viewer", NULL
);
4026 // Display a label with a X
4027 GtkWidget *w_hbox = gtk_hbox_new(FALSE, 4);
4028 GtkWidget *w_label = gtk_label_new (label);
4029 GtkWidget *pixmap = create_pixmap(GTK_WIDGET(notebook), "close.png");
4030 GtkWidget *w_button = gtk_button_new ();
4031 gtk_container_add(GTK_CONTAINER(w_button), pixmap);
4032 //GtkWidget *w_button = gtk_button_new_with_label("x");
4034 gtk_button_set_relief(GTK_BUTTON(w_button), GTK_RELIEF_NONE);
4036 gtk_box_pack_start(GTK_BOX(w_hbox), w_label, TRUE, TRUE, 0);
4037 gtk_box_pack_end(GTK_BOX(w_hbox), w_button, FALSE,
4040 g_signal_connect_swapped (w_button, "clicked",
4041 G_CALLBACK (on_close_tab_X_clicked),
4044 gtk_widget_set_state(w_button, GTK_STATE_ACTIVE);
4046 gtk_widget_show (w_label);
4047 gtk_widget_show (pixmap);
4048 gtk_widget_show (w_button);
4049 gtk_widget_show (w_hbox);
4051 tab->label = w_hbox;
4055 tab
->label
= gtk_label_new (label
);
4057 gtk_widget_show(tab
->label
);
4058 gtk_widget_show(tab
->scrollbar
);
4059 gtk_widget_show(tab
->MTimebar
);
4060 gtk_widget_show(tab
->viewer_container
);
4061 gtk_widget_show(tab
->vbox
);
4063 //gtk_widget_show(tab->multivpaned);
4066 /* Start with empty events requests list */
4067 tab
->events_requests
= NULL
;
4068 tab
->events_request_pending
= FALSE
;
4069 tab
->stop_foreground
= FALSE
;
4073 g_signal_connect(G_OBJECT(tab
->scrollbar
), "value-changed",
4074 G_CALLBACK(scroll_value_changed_cb
), tab
);
4077 /* Timebar signal handler */
4078 g_signal_connect(G_OBJECT(tab
->MTimebar
), "start-time-changed",
4079 G_CALLBACK(on_timebar_starttime_changed
), tab
);
4080 g_signal_connect(G_OBJECT(tab
->MTimebar
), "end-time-changed",
4081 G_CALLBACK(on_timebar_endtime_changed
), tab
);
4082 g_signal_connect(G_OBJECT(tab
->MTimebar
), "current-time-changed",
4083 G_CALLBACK(on_timebar_currenttime_changed
), tab
);
4085 //g_signal_connect(G_OBJECT(tab->scrollbar), "changed",
4086 // G_CALLBACK(scroll_value_changed_cb), tab);
4089 //insert tab into notebook
4090 gtk_notebook_append_page(notebook
,
4093 list
= gtk_container_get_children(GTK_CONTAINER(notebook
));
4094 gtk_notebook_set_current_page(notebook
,g_list_length(list
)-1);
4095 // always show : not if(g_list_length(list)>1)
4096 gtk_notebook_set_show_tabs(notebook
, TRUE
);
4099 lttvwindow_report_time_window(tab
, copy_tab
->time_window
);
4100 lttvwindow_report_current_time(tab
, copy_tab
->current_time
);
4102 TimeWindow time_window
;
4104 time_window
.start_time
= ltt_time_zero
;
4105 time_window
.end_time
= ltt_time_add(time_window
.start_time
,
4106 lttvwindow_default_time_width
);
4107 time_window
.time_width
= lttvwindow_default_time_width
;
4108 time_window
.time_width_double
= ltt_time_to_double(time_window
.time_width
);
4110 lttvwindow_report_time_window(tab
, time_window
);
4111 lttvwindow_report_current_time(tab
, ltt_time_zero
);
4114 LttvTraceset
*traceset
= tab
->traceset_info
->traceset
;
4115 SetTraceset(tab
, traceset
);
4119 * execute_events_requests
4121 * Idle function that executes the pending requests for a tab.
4123 * @return return value : TRUE : keep the idle function, FALSE : remove it.
4125 gboolean
execute_events_requests(Tab
*tab
)
4127 return ( lttvwindow_process_pending_requests(tab
) );
4131 __EXPORT
void create_main_window_with_trace_list(GSList
*traces
, gboolean is_live
)
4133 GSList
*iter
= NULL
;
4136 MainWindow
*mw
= construct_main_window(NULL
);
4137 GtkWidget
*widget
= mw
->mwindow
;
4139 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
4140 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
4141 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
4142 LttvPluginTab
*ptab
;
4146 ptab
= create_new_tab(widget
, NULL
);
4149 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
4153 for(iter
=traces
; iter
!=NULL
; iter
=g_slist_next(iter
)) {
4154 gchar
*path
= (gchar
*)iter
->data
;
4156 gchar abs_path
[PATH_MAX
];
4160 get_absolute_pathname(path
, abs_path
);
4161 trace_v
= lttvwindowtraces_get_trace_by_name(abs_path
);
4162 if(trace_v
== NULL
) {
4164 trace
= ltt_trace_open_live(abs_path
);
4166 trace
= ltt_trace_open(abs_path
);
4169 g_warning("cannot open trace %s", abs_path
);
4171 GtkWidget
*dialogue
=
4172 gtk_message_dialog_new(
4173 GTK_WINDOW(gtk_widget_get_toplevel(widget
)),
4174 GTK_DIALOG_MODAL
|GTK_DIALOG_DESTROY_WITH_PARENT
,
4177 "Cannot open trace : maybe you should enter in the directory "
4179 gtk_dialog_run(GTK_DIALOG(dialogue
));
4180 gtk_widget_destroy(dialogue
);
4182 trace_v
= lttv_trace_new(trace
);
4183 lttvwindowtraces_add_trace(trace_v
);
4184 lttvwindow_add_trace(tab
, trace_v
);
4187 lttvwindow_add_trace(tab
, trace_v
);
4191 LttvTraceset
*traceset
;
4193 traceset
= tab
->traceset_info
->traceset
;
4194 SetTraceset(tab
, traceset
);