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
);
632 /* open_traceset will open a traceset saved in a file
633 * Right now, it is not finished yet, (not working)
637 void open_traceset(GtkWidget
* widget
, gpointer user_data
)
641 LttvTraceset
* traceset
;
642 MainWindow
* mw_data
= get_window_data_struct(widget
);
643 GtkFileSelection
* file_selector
=
644 (GtkFileSelection
*)gtk_file_selection_new("Select a traceset");
646 gtk_file_selection_hide_fileop_buttons(file_selector
);
648 gtk_window_set_transient_for(GTK_WINDOW(file_selector
),
649 GTK_WINDOW(mw_data
->mwindow
));
651 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
653 case GTK_RESPONSE_ACCEPT
:
654 case GTK_RESPONSE_OK
:
655 dir
= gtk_file_selection_get_selections (file_selector
);
656 traceset
= lttv_traceset_load(dir
[0]);
657 g_info("Open a trace set %s\n", dir
[0]);
660 case GTK_RESPONSE_REJECT
:
661 case GTK_RESPONSE_CANCEL
:
663 gtk_widget_destroy((GtkWidget
*)file_selector
);
669 /* lttvwindow_process_pending_requests
671 * Process requests for parts of the trace from viewers.
673 * These requests are made by lttvwindow_events_request().
675 * This internal function gets called by g_idle, taking care of the pending
676 * requests. It is responsible for concatenation of time intervals and position
677 * requests. It does it with the following algorithm organizing process traceset
678 * calls. Here is the detailed description of the way it works :
680 * - Events Requests Servicing Algorithm
682 * Data structures necessary :
684 * List of requests added to context : list_in
685 * List of requests not added to context : list_out
690 * list_out : many events requests
692 * FIXME : insert rest of algorithm here
696 #define list_out tab->events_requests
698 gboolean
lttvwindow_process_pending_requests(Tab
*tab
)
700 LttvTracesetContext
*tsc
;
701 LttvTracefileContext
*tfc
;
702 GSList
*list_in
= NULL
;
706 LttvTracesetContextPosition
*end_position
;
708 if(lttvwindow_preempt_count
> 0) return TRUE
;
711 g_critical("Foreground processing : tab does not exist. Processing removed.");
715 /* There is no events requests pending : we should never have been called! */
716 g_assert(g_slist_length(list_out
) != 0);
718 tsc
= LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
720 //set the cursor to be X shape, indicating that the computer is busy in doing its job
722 new = gdk_cursor_new(GDK_X_CURSOR
);
723 widget
= lookup_widget(tab
->mw
->mwindow
, "MToolbar1");
724 win
= gtk_widget_get_parent_window(widget
);
725 gdk_window_set_cursor(win
, new);
726 gdk_cursor_unref(new);
727 gdk_window_stick(win
);
728 gdk_window_unstick(win
);
731 g_debug("SIZE events req len : %d", g_slist_length(list_out
));
733 /* Preliminary check for no trace in traceset */
734 /* Unregister the routine if empty, empty list_out too */
735 if(lttv_traceset_number(tsc
->ts
) == 0) {
737 /* - For each req in list_out */
738 GSList
*iter
= list_out
;
740 while(iter
!= NULL
) {
742 gboolean remove
= FALSE
;
743 gboolean free_data
= FALSE
;
744 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
746 /* - Call end request for req */
747 if(events_request
->servicing
== TRUE
)
748 lttv_hooks_call(events_request
->after_request
, (gpointer
)tsc
);
750 /* - remove req from list_out */
751 /* Destroy the request */
758 GSList
*remove_iter
= iter
;
760 iter
= g_slist_next(iter
);
761 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
762 list_out
= g_slist_remove_link(list_out
, remove_iter
);
763 } else { // not remove
764 iter
= g_slist_next(iter
);
769 /* 0.1 Lock Traces */
774 iter_trace
<lttv_traceset_number(tsc
->ts
);
776 LttvTrace
*trace_v
= lttv_traceset_get(tsc
->ts
, iter_trace
);
778 if(lttvwindowtraces_lock(trace_v
) != 0) {
779 g_critical("Foreground processing : Unable to get trace lock");
780 return TRUE
; /* Cannot get lock, try later */
785 /* 0.2 Seek tracefiles positions to context position */
786 //g_assert(lttv_process_traceset_seek_position(tsc, sync_position) == 0);
787 lttv_process_traceset_synchronize_tracefiles(tsc
);
790 /* Events processing algorithm implementation */
791 /* Warning : the gtk_events_pending takes a LOT of cpu time. So what we do
792 * instead is to leave the control to GTK and take it back.
794 /* A. Servicing loop */
795 //while( (g_slist_length(list_in) != 0 || g_slist_length(list_out) != 0)) {
796 if((g_slist_length(list_in
) != 0 || g_slist_length(list_out
) != 0)) {
798 /* 1. If list_in is empty (need a seek) */
799 if( g_slist_length(list_in
) == 0 ) {
801 /* list in is empty, need a seek */
803 /* 1.1 Add requests to list_in */
804 GSList
*ltime
= NULL
;
808 /* 1.1.1 Find all time requests with the lowest start time in list_out
811 if(g_slist_length(list_out
) > 0)
812 ltime
= g_slist_append(ltime
, g_slist_nth_data(list_out
, 0));
813 for(iter
=g_slist_nth(list_out
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
814 /* Find all time requests with the lowest start time in list_out */
815 EventsRequest
*event_request_ltime
= (EventsRequest
*)g_slist_nth_data(ltime
, 0);
816 EventsRequest
*event_request_list_out
= (EventsRequest
*)iter
->data
;
819 comp
= ltt_time_compare(event_request_ltime
->start_time
,
820 event_request_list_out
->start_time
);
822 ltime
= g_slist_append(ltime
, event_request_list_out
);
824 /* Remove all elements from ltime, and add current */
826 ltime
= g_slist_delete_link(ltime
, g_slist_nth(ltime
, 0));
827 ltime
= g_slist_append(ltime
, event_request_list_out
);
831 /* 1.1.2 Find all position requests with the lowest position in list_out
834 if(g_slist_length(list_out
) > 0)
835 lpos
= g_slist_append(lpos
, g_slist_nth_data(list_out
, 0));
836 for(iter
=g_slist_nth(list_out
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
837 /* Find all position requests with the lowest position in list_out */
838 EventsRequest
*event_request_lpos
= (EventsRequest
*)g_slist_nth_data(lpos
, 0);
839 EventsRequest
*event_request_list_out
= (EventsRequest
*)iter
->data
;
842 if(event_request_lpos
->start_position
!= NULL
843 && event_request_list_out
->start_position
!= NULL
)
845 comp
= lttv_traceset_context_pos_pos_compare
846 (event_request_lpos
->start_position
,
847 event_request_list_out
->start_position
);
852 lpos
= g_slist_append(lpos
, event_request_list_out
);
854 /* Remove all elements from lpos, and add current */
856 lpos
= g_slist_delete_link(lpos
, g_slist_nth(lpos
, 0));
857 lpos
= g_slist_append(lpos
, event_request_list_out
);
862 EventsRequest
*event_request_lpos
= (EventsRequest
*)g_slist_nth_data(lpos
, 0);
863 EventsRequest
*event_request_ltime
= (EventsRequest
*)g_slist_nth_data(ltime
, 0);
864 LttTime lpos_start_time
;
866 if(event_request_lpos
!= NULL
867 && event_request_lpos
->start_position
!= NULL
) {
868 lpos_start_time
= lttv_traceset_context_position_get_time(
869 event_request_lpos
->start_position
);
872 /* 1.1.3 If lpos.start time < ltime */
873 if(event_request_lpos
!= NULL
874 && event_request_lpos
->start_position
!= NULL
875 && ltt_time_compare(lpos_start_time
,
876 event_request_ltime
->start_time
)<0) {
877 /* Add lpos to list_in, remove them from list_out */
878 for(iter
=lpos
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
880 EventsRequest
*event_request_lpos
=
881 (EventsRequest
*)iter
->data
;
883 list_in
= g_slist_append(list_in
, event_request_lpos
);
884 /* Remove from list_out */
885 list_out
= g_slist_remove(list_out
, event_request_lpos
);
888 /* 1.1.4 (lpos.start time >= ltime) */
889 /* Add ltime to list_in, remove them from list_out */
891 for(iter
=ltime
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
893 EventsRequest
*event_request_ltime
=
894 (EventsRequest
*)iter
->data
;
896 list_in
= g_slist_append(list_in
, event_request_ltime
);
897 /* Remove from list_out */
898 list_out
= g_slist_remove(list_out
, event_request_ltime
);
908 tfc
= lttv_traceset_context_get_current_tfc(tsc
);
909 g_assert(g_slist_length(list_in
)>0);
910 EventsRequest
*events_request
= g_slist_nth_data(list_in
, 0);
913 /* 1.2.1 If first request in list_in is a time request */
914 if(events_request
->start_position
== NULL
) {
915 /* - If first req in list_in start time != current time */
916 if(tfc
== NULL
|| ltt_time_compare(events_request
->start_time
,
917 tfc
->timestamp
) != 0)
918 /* - Seek to that time */
919 g_debug("SEEK TIME : %lu, %lu", events_request
->start_time
.tv_sec
,
920 events_request
->start_time
.tv_nsec
);
921 //lttv_process_traceset_seek_time(tsc, events_request->start_time);
922 lttv_state_traceset_seek_time_closest(LTTV_TRACESET_STATE(tsc
),
923 events_request
->start_time
);
925 /* Process the traceset with only state hooks */
927 lttv_process_traceset_middle(tsc
,
928 events_request
->start_time
,
931 g_assert(seek_count
< LTTV_STATE_SAVE_INTERVAL
);
937 LttvTracefileContext
*tfc
=
938 lttv_traceset_context_get_current_tfc(tsc
);
939 /* Else, the first request in list_in is a position request */
940 /* If first req in list_in pos != current pos */
941 g_assert(events_request
->start_position
!= NULL
);
942 g_debug("SEEK POS time : %lu, %lu",
943 lttv_traceset_context_position_get_time(
944 events_request
->start_position
).tv_sec
,
945 lttv_traceset_context_position_get_time(
946 events_request
->start_position
).tv_nsec
);
949 g_debug("SEEK POS context time : %lu, %lu",
950 tfc
->timestamp
.tv_sec
,
951 tfc
->timestamp
.tv_nsec
);
953 g_debug("SEEK POS context time : %lu, %lu",
954 ltt_time_infinite
.tv_sec
,
955 ltt_time_infinite
.tv_nsec
);
957 g_assert(events_request
->start_position
!= NULL
);
958 if(lttv_traceset_context_ctx_pos_compare(tsc
,
959 events_request
->start_position
) != 0) {
960 /* 1.2.2.1 Seek to that position */
961 g_debug("SEEK POSITION");
962 //lttv_process_traceset_seek_position(tsc, events_request->start_position);
963 pos_time
= lttv_traceset_context_position_get_time(
964 events_request
->start_position
);
966 lttv_state_traceset_seek_time_closest(LTTV_TRACESET_STATE(tsc
),
969 /* Process the traceset with only state hooks */
971 lttv_process_traceset_middle(tsc
,
974 events_request
->start_position
);
975 g_assert(lttv_traceset_context_ctx_pos_compare(tsc
,
976 events_request
->start_position
) == 0);
983 /* 1.3 Add hooks and call before request for all list_in members */
987 for(iter
=list_in
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
988 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
989 /* 1.3.1 If !servicing */
990 if(events_request
->servicing
== FALSE
) {
991 /* - begin request hooks called
994 lttv_hooks_call(events_request
->before_request
, (gpointer
)tsc
);
995 events_request
->servicing
= TRUE
;
997 /* 1.3.2 call before chunk
998 * 1.3.3 events hooks added
1000 if(events_request
->trace
== -1)
1001 lttv_process_traceset_begin(tsc
,
1002 events_request
->before_chunk_traceset
,
1003 events_request
->before_chunk_trace
,
1004 events_request
->before_chunk_tracefile
,
1005 events_request
->event
,
1006 events_request
->event_by_id_channel
);
1008 guint nb_trace
= lttv_traceset_number(tsc
->ts
);
1009 g_assert((guint
)events_request
->trace
< nb_trace
&&
1010 events_request
->trace
> -1);
1011 LttvTraceContext
*tc
= tsc
->traces
[events_request
->trace
];
1013 lttv_hooks_call(events_request
->before_chunk_traceset
, tsc
);
1015 lttv_trace_context_add_hooks(tc
,
1016 events_request
->before_chunk_trace
,
1017 events_request
->before_chunk_tracefile
,
1018 events_request
->event
,
1019 events_request
->event_by_id_channel
);
1024 /* 2. Else, list_in is not empty, we continue a read */
1027 /* 2.0 For each req of list_in */
1028 GSList
*iter
= list_in
;
1030 while(iter
!= NULL
) {
1032 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1034 /* - Call before chunk
1035 * - events hooks added
1037 if(events_request
->trace
== -1)
1038 lttv_process_traceset_begin(tsc
,
1039 events_request
->before_chunk_traceset
,
1040 events_request
->before_chunk_trace
,
1041 events_request
->before_chunk_tracefile
,
1042 events_request
->event
,
1043 events_request
->event_by_id_channel
);
1045 guint nb_trace
= lttv_traceset_number(tsc
->ts
);
1046 g_assert((guint
)events_request
->trace
< nb_trace
&&
1047 events_request
->trace
> -1);
1048 LttvTraceContext
*tc
= tsc
->traces
[events_request
->trace
];
1050 lttv_hooks_call(events_request
->before_chunk_traceset
, tsc
);
1052 lttv_trace_context_add_hooks(tc
,
1053 events_request
->before_chunk_trace
,
1054 events_request
->before_chunk_tracefile
,
1055 events_request
->event
,
1056 events_request
->event_by_id_channel
);
1059 iter
= g_slist_next(iter
);
1064 tfc
= lttv_traceset_context_get_current_tfc(tsc
);
1066 /* 2.1 For each req of list_out */
1067 GSList
*iter
= list_out
;
1069 while(iter
!= NULL
) {
1071 gboolean remove
= FALSE
;
1072 gboolean free_data
= FALSE
;
1073 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1075 /* if req.start time == current context time
1076 * or req.start position == current position*/
1077 if( ltt_time_compare(events_request
->start_time
,
1078 tfc
->timestamp
) == 0
1080 (events_request
->start_position
!= NULL
1082 lttv_traceset_context_ctx_pos_compare(tsc
,
1083 events_request
->start_position
) == 0)
1085 /* - Add to list_in, remove from list_out */
1086 list_in
= g_slist_append(list_in
, events_request
);
1090 /* - If !servicing */
1091 if(events_request
->servicing
== FALSE
) {
1092 /* - begin request hooks called
1093 * - servicing = TRUE
1095 lttv_hooks_call(events_request
->before_request
, (gpointer
)tsc
);
1096 events_request
->servicing
= TRUE
;
1098 /* call before chunk
1099 * events hooks added
1101 if(events_request
->trace
== -1)
1102 lttv_process_traceset_begin(tsc
,
1103 events_request
->before_chunk_traceset
,
1104 events_request
->before_chunk_trace
,
1105 events_request
->before_chunk_tracefile
,
1106 events_request
->event
,
1107 events_request
->event_by_id_channel
);
1109 guint nb_trace
= lttv_traceset_number(tsc
->ts
);
1110 g_assert((guint
)events_request
->trace
< nb_trace
&&
1111 events_request
->trace
> -1);
1112 LttvTraceContext
*tc
= tsc
->traces
[events_request
->trace
];
1114 lttv_hooks_call(events_request
->before_chunk_traceset
, tsc
);
1116 lttv_trace_context_add_hooks(tc
,
1117 events_request
->before_chunk_trace
,
1118 events_request
->before_chunk_tracefile
,
1119 events_request
->event
,
1120 events_request
->event_by_id_channel
);
1129 GSList
*remove_iter
= iter
;
1131 iter
= g_slist_next(iter
);
1132 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
1133 list_out
= g_slist_remove_link(list_out
, remove_iter
);
1134 } else { // not remove
1135 iter
= g_slist_next(iter
);
1141 /* 3. Find end criterions */
1146 /* 3.1.1 Find lowest end time in list_in */
1147 g_assert(g_slist_length(list_in
)>0);
1148 end_time
= ((EventsRequest
*)g_slist_nth_data(list_in
,0))->end_time
;
1150 for(iter
=g_slist_nth(list_in
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
1151 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1153 if(ltt_time_compare(events_request
->end_time
,
1155 end_time
= events_request
->end_time
;
1158 /* 3.1.2 Find lowest start time in list_out */
1159 for(iter
=list_out
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
1160 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1162 if(ltt_time_compare(events_request
->start_time
,
1164 end_time
= events_request
->start_time
;
1169 /* 3.2 Number of events */
1171 /* 3.2.1 Find lowest number of events in list_in */
1174 end_nb_events
= ((EventsRequest
*)g_slist_nth_data(list_in
,0))->num_events
;
1176 for(iter
=g_slist_nth(list_in
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
1177 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1179 if(events_request
->num_events
< end_nb_events
)
1180 end_nb_events
= events_request
->num_events
;
1183 /* 3.2.2 Use min(CHUNK_NUM_EVENTS, min num events in list_in) as
1186 end_nb_events
= MIN(CHUNK_NUM_EVENTS
, end_nb_events
);
1190 /* 3.3 End position */
1192 /* 3.3.1 Find lowest end position in list_in */
1195 end_position
=((EventsRequest
*)g_slist_nth_data(list_in
,0))->end_position
;
1197 for(iter
=g_slist_nth(list_in
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
1198 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1200 if(events_request
->end_position
!= NULL
&& end_position
!= NULL
&&
1201 lttv_traceset_context_pos_pos_compare(events_request
->end_position
,
1203 end_position
= events_request
->end_position
;
1208 /* 3.3.2 Find lowest start position in list_out */
1211 for(iter
=list_out
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
1212 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1214 if(events_request
->end_position
!= NULL
&& end_position
!= NULL
&&
1215 lttv_traceset_context_pos_pos_compare(events_request
->end_position
,
1217 end_position
= events_request
->end_position
;
1222 /* 4. Call process traceset middle */
1223 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
);
1224 count
= lttv_process_traceset_middle(tsc
, end_time
, end_nb_events
, end_position
);
1226 tfc
= lttv_traceset_context_get_current_tfc(tsc
);
1228 g_debug("Context time after middle : %lu, %lu", tfc
->timestamp
.tv_sec
,
1229 tfc
->timestamp
.tv_nsec
);
1231 g_debug("End of trace reached after middle.");
1235 /* 5. After process traceset middle */
1236 tfc
= lttv_traceset_context_get_current_tfc(tsc
);
1238 /* - if current context time > traceset.end time */
1239 if(tfc
== NULL
|| ltt_time_compare(tfc
->timestamp
,
1240 tsc
->time_span
.end_time
) > 0) {
1241 /* - For each req in list_in */
1242 GSList
*iter
= list_in
;
1244 while(iter
!= NULL
) {
1246 gboolean remove
= FALSE
;
1247 gboolean free_data
= FALSE
;
1248 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1250 /* - Remove events hooks for req
1251 * - Call end chunk for req
1254 if(events_request
->trace
== -1)
1255 lttv_process_traceset_end(tsc
,
1256 events_request
->after_chunk_traceset
,
1257 events_request
->after_chunk_trace
,
1258 events_request
->after_chunk_tracefile
,
1259 events_request
->event
,
1260 events_request
->event_by_id_channel
);
1263 guint nb_trace
= lttv_traceset_number(tsc
->ts
);
1264 g_assert(events_request
->trace
< nb_trace
&&
1265 events_request
->trace
> -1);
1266 LttvTraceContext
*tc
= tsc
->traces
[events_request
->trace
];
1268 lttv_trace_context_remove_hooks(tc
,
1269 events_request
->after_chunk_trace
,
1270 events_request
->after_chunk_tracefile
,
1271 events_request
->event
,
1272 events_request
->event_by_id_channel
);
1273 lttv_hooks_call(events_request
->after_chunk_traceset
, tsc
);
1278 /* - Call end request for req */
1279 lttv_hooks_call(events_request
->after_request
, (gpointer
)tsc
);
1281 /* - remove req from list_in */
1282 /* Destroy the request */
1289 GSList
*remove_iter
= iter
;
1291 iter
= g_slist_next(iter
);
1292 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
1293 list_in
= g_slist_remove_link(list_in
, remove_iter
);
1294 } else { // not remove
1295 iter
= g_slist_next(iter
);
1300 /* 5.1 For each req in list_in */
1301 GSList
*iter
= list_in
;
1303 while(iter
!= NULL
) {
1305 gboolean remove
= FALSE
;
1306 gboolean free_data
= FALSE
;
1307 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1309 /* - Remove events hooks for req
1310 * - Call end chunk for req
1312 if(events_request
->trace
== -1)
1313 lttv_process_traceset_end(tsc
,
1314 events_request
->after_chunk_traceset
,
1315 events_request
->after_chunk_trace
,
1316 events_request
->after_chunk_tracefile
,
1317 events_request
->event
,
1318 events_request
->event_by_id_channel
);
1321 guint nb_trace
= lttv_traceset_number(tsc
->ts
);
1322 g_assert(events_request
->trace
< nb_trace
&&
1323 events_request
->trace
> -1);
1324 LttvTraceContext
*tc
= tsc
->traces
[events_request
->trace
];
1326 lttv_trace_context_remove_hooks(tc
,
1327 events_request
->after_chunk_trace
,
1328 events_request
->after_chunk_tracefile
,
1329 events_request
->event
,
1330 events_request
->event_by_id_channel
);
1332 lttv_hooks_call(events_request
->after_chunk_traceset
, tsc
);
1335 /* - req.num -= count */
1336 g_assert(events_request
->num_events
>= count
);
1337 events_request
->num_events
-= count
;
1339 g_assert(tfc
!= NULL
);
1340 /* - if req.num == 0
1342 * current context time >= req.end time
1344 * req.end pos == current pos
1346 * req.stop_flag == TRUE
1348 if( events_request
->num_events
== 0
1350 events_request
->stop_flag
== TRUE
1352 ltt_time_compare(tfc
->timestamp
,
1353 events_request
->end_time
) >= 0
1355 (events_request
->end_position
!= NULL
1357 lttv_traceset_context_ctx_pos_compare(tsc
,
1358 events_request
->end_position
) == 0)
1361 g_assert(events_request
->servicing
== TRUE
);
1362 /* - Call end request for req
1363 * - remove req from list_in */
1364 lttv_hooks_call(events_request
->after_request
, (gpointer
)tsc
);
1365 /* - remove req from list_in */
1366 /* Destroy the request */
1374 GSList
*remove_iter
= iter
;
1376 iter
= g_slist_next(iter
);
1377 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
1378 list_in
= g_slist_remove_link(list_in
, remove_iter
);
1379 } else { // not remove
1380 iter
= g_slist_next(iter
);
1386 /* End of removed servicing loop : leave control to GTK instead. */
1387 // if(gtk_events_pending()) break;
1390 /* B. When interrupted between chunks */
1393 GSList
*iter
= list_in
;
1395 /* 1. for each request in list_in */
1396 while(iter
!= NULL
) {
1398 gboolean remove
= FALSE
;
1399 gboolean free_data
= FALSE
;
1400 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1402 /* 1.1. Use current postition as start position */
1403 if(events_request
->start_position
!= NULL
)
1404 lttv_traceset_context_position_destroy(events_request
->start_position
);
1405 events_request
->start_position
= lttv_traceset_context_position_new(tsc
);
1406 lttv_traceset_context_position_save(tsc
, events_request
->start_position
);
1408 /* 1.2. Remove start time */
1409 events_request
->start_time
= ltt_time_infinite
;
1411 /* 1.3. Move from list_in to list_out */
1414 list_out
= g_slist_append(list_out
, events_request
);
1419 GSList
*remove_iter
= iter
;
1421 iter
= g_slist_next(iter
);
1422 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
1423 list_in
= g_slist_remove_link(list_in
, remove_iter
);
1424 } else { // not remove
1425 iter
= g_slist_next(iter
);
1431 /* C Unlock Traces */
1433 lttv_process_traceset_get_sync_data(tsc
);
1434 //lttv_traceset_context_position_save(tsc, sync_position);
1439 iter_trace
<lttv_traceset_number(tsc
->ts
);
1441 LttvTrace
*trace_v
= lttv_traceset_get(tsc
->ts
, iter_trace
);
1443 lttvwindowtraces_unlock(trace_v
);
1447 //set the cursor back to normal
1448 gdk_window_set_cursor(win
, NULL
);
1451 g_assert(g_slist_length(list_in
) == 0);
1453 if( g_slist_length(list_out
) == 0 ) {
1454 /* Put tab's request pending flag back to normal */
1455 tab
->events_request_pending
= FALSE
;
1456 g_debug("remove the idle fct");
1457 return FALSE
; /* Remove the idle function */
1459 g_debug("leave the idle fct");
1460 return TRUE
; /* Leave the idle function */
1462 /* We do not use simili-round-robin, it may require to read 1 meg buffers
1463 * again and again if many tracesets use the same tracefiles. */
1464 /* Hack for round-robin idle functions */
1465 /* It will put the idle function at the end of the pool */
1466 /*g_idle_add_full((G_PRIORITY_HIGH_IDLE + 21),
1467 (GSourceFunc)execute_events_requests,
1476 Manage the periodic update of a live trace
1479 live_trace_update_handler(Tab
*tab
)
1481 unsigned int updated_count
;
1483 LttvTracesetContext
*tsc
= LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
1484 TimeInterval initial_time_span
= tsc
->time_span
;
1485 TimeInterval updated_time_span
;
1487 updated_count
= lttv_process_traceset_update(tsc
);
1489 /* TODO ybrosseau 2011-01-12: Add trace resynchronization */
1491 /* Get the changed period bounds */
1492 updated_time_span
= tsc
->time_span
;
1494 if(ltt_time_compare(updated_time_span
.start_time
,
1495 initial_time_span
.start_time
) != 0) {
1496 /* The initial time should not change on a live update */
1500 /* Notify viewers (only on updates) */
1501 if(ltt_time_compare(updated_time_span
.end_time
,
1502 initial_time_span
.end_time
) != 0) {
1504 notify_time_span_changed(tab
);
1505 /* TODO ybrosseau 2011-01-12: Change the timebar to register
1506 to the time_span hook */
1507 timebar_set_minmax_time(TIMEBAR(tab
->MTimebar
),
1508 &updated_time_span
.start_time
,
1509 &updated_time_span
.end_time
);
1511 /* To update the min max */
1512 time_change_manager(tab
, tab
->time_window
);
1515 /* Timer will be recalled as long as there is files to update */
1516 return (updated_count
> 0);
1519 static void lttvwindow_add_trace(Tab
*tab
, LttvTrace
*trace_v
)
1521 LttvTraceset
*traceset
= tab
->traceset_info
->traceset
;
1523 guint num_traces
= lttv_traceset_number(traceset
);
1525 //Verify if trace is already present.
1526 for(i
=0; i
<num_traces
; i
++)
1528 LttvTrace
* trace
= lttv_traceset_get(traceset
, i
);
1529 if(trace
== trace_v
)
1533 //Keep a reference to the traces so they are not freed.
1534 for(i
=0; i
<lttv_traceset_number(traceset
); i
++)
1536 LttvTrace
* trace
= lttv_traceset_get(traceset
, i
);
1537 lttv_trace_ref(trace
);
1540 //remove state update hooks
1541 lttv_state_remove_event_hooks(
1542 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1544 lttv_context_fini(LTTV_TRACESET_CONTEXT(
1545 tab
->traceset_info
->traceset_context
));
1546 g_object_unref(tab
->traceset_info
->traceset_context
);
1548 lttv_traceset_add(traceset
, trace_v
);
1549 lttv_trace_ref(trace_v
); /* local ref */
1551 /* Create new context */
1552 tab
->traceset_info
->traceset_context
=
1553 g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
1555 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->
1560 //add state update hooks
1561 lttv_state_add_event_hooks(
1562 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1563 //Remove local reference to the traces.
1564 for(i
=0; i
<lttv_traceset_number(traceset
); i
++)
1566 LttvTrace
* trace
= lttv_traceset_get(traceset
, i
);
1567 lttv_trace_unref(trace
);
1571 //add_trace_into_traceset_selector(GTK_MULTIVPANED(tab->multivpaned), lttv_trace(trace_v));
1574 if (lttv_trace(trace_v
)->is_live
) {
1575 /* Add timer for live update */
1576 /* TODO ybrosseau 2011-01-12: Parametrize the hardcoded 1 seconds */
1577 g_timeout_add_seconds (1,
1578 (GSourceFunc
) live_trace_update_handler
,
1584 /* add_trace adds a trace into the current traceset. It first displays a
1585 * directory selection dialogue to let user choose a trace, then recreates
1586 * tracset_context, and redraws all the viewer of the current tab
1589 void add_trace(GtkWidget
* widget
, gpointer user_data
)
1592 LttvTrace
* trace_v
;
1593 LttvTraceset
* traceset
;
1595 char abs_path
[PATH_MAX
];
1597 MainWindow
* mw_data
= get_window_data_struct(widget
);
1598 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
1600 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
1601 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
1602 LttvPluginTab
*ptab
;
1606 ptab
= create_new_tab(widget
, NULL
);
1609 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
1613 /* File open dialog management */
1614 GtkWidget
*extra_live_button
;
1615 GtkFileChooser
* file_chooser
=
1617 gtk_file_chooser_dialog_new ("Select a trace",
1618 GTK_WINDOW(mw_data
->mwindow
),
1619 GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER
,
1620 GTK_STOCK_CANCEL
, GTK_RESPONSE_CANCEL
,
1621 GTK_STOCK_OPEN
, GTK_RESPONSE_ACCEPT
,
1624 /* Button to indicate the opening of a live trace */
1625 extra_live_button
= gtk_check_button_new_with_mnemonic ("Trace is live (currently being writen)");
1626 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (extra_live_button
), FALSE
);
1627 gtk_file_chooser_set_extra_widget (GTK_FILE_CHOOSER (file_chooser
), extra_live_button
);
1629 gtk_file_chooser_set_show_hidden (file_chooser
, TRUE
);
1630 if(remember_trace_dir
[0] != '\0')
1631 gtk_file_chooser_set_filename(file_chooser
, remember_trace_dir
);
1633 id
= gtk_dialog_run(GTK_DIALOG(file_chooser
));
1636 case GTK_RESPONSE_ACCEPT
:
1637 case GTK_RESPONSE_OK
:
1638 dir
= gtk_file_chooser_get_filename (file_chooser
);
1640 strncpy(remember_trace_dir
, dir
, PATH_MAX
);
1641 strncat(remember_trace_dir
, "/", PATH_MAX
);
1642 if(!dir
|| strlen(dir
) == 0){
1645 get_absolute_pathname(dir
, abs_path
);
1646 trace_v
= lttvwindowtraces_get_trace_by_name(abs_path
);
1647 if(trace_v
== NULL
) {
1648 if(gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (extra_live_button
))) {
1649 trace
= ltt_trace_open_live(abs_path
);
1651 trace
= ltt_trace_open(abs_path
);
1655 g_warning("cannot open trace %s", abs_path
);
1657 GtkWidget
*dialogue
=
1658 gtk_message_dialog_new(
1659 GTK_WINDOW(gtk_widget_get_toplevel(widget
)),
1660 GTK_DIALOG_MODAL
|GTK_DIALOG_DESTROY_WITH_PARENT
,
1663 "Cannot open trace : maybe you should enter in the trace "
1664 "directory to select it ?");
1665 gtk_dialog_run(GTK_DIALOG(dialogue
));
1666 gtk_widget_destroy(dialogue
);
1669 trace_v
= lttv_trace_new(trace
);
1670 lttvwindowtraces_add_trace(trace_v
);
1671 lttvwindow_add_trace(tab
, trace_v
);
1674 lttvwindow_add_trace(tab
, trace_v
);
1678 //update current tab
1679 //update_traceset(mw_data);
1681 /* Call the updatetraceset hooks */
1683 traceset
= tab
->traceset_info
->traceset
;
1684 SetTraceset(tab
, traceset
);
1685 // in expose now call_pending_read_hooks(mw_data);
1687 //lttvwindow_report_current_time(mw_data,&(tab->current_time));
1689 case GTK_RESPONSE_REJECT
:
1690 case GTK_RESPONSE_CANCEL
:
1694 gtk_widget_destroy((GtkWidget
*)file_chooser
);
1698 /* remove_trace removes a trace from the current traceset if all viewers in
1699 * the current tab are not interested in the trace. It first displays a
1700 * dialogue, which shows all traces in the current traceset, to let user choose
1701 * a trace, then it checks if all viewers unselect the trace, if it is true,
1702 * it will remove the trace, recreate the traceset_contex,
1703 * and redraws all the viewer of the current tab. If there is on trace in the
1704 * current traceset, it will delete all viewers of the current tab
1706 * It destroys the filter tree. FIXME... we should request for an update
1710 void remove_trace(GtkWidget
*widget
, gpointer user_data
)
1713 LttvTrace
* trace_v
;
1714 LttvTraceset
* traceset
;
1715 gint i
, j
, nb_trace
, index
=-1;
1716 char ** name
, *remove_trace_name
;
1717 MainWindow
* mw_data
= get_window_data_struct(widget
);
1718 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
1720 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
1721 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
1727 LttvPluginTab
*ptab
;
1728 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
1732 nb_trace
=lttv_traceset_number(tab
->traceset_info
->traceset
);
1733 name
= g_new(char*,nb_trace
);
1734 for(i
= 0; i
< nb_trace
; i
++){
1735 trace_v
= lttv_traceset_get(tab
->traceset_info
->traceset
, i
);
1736 trace
= lttv_trace(trace_v
);
1737 name
[i
] = (char *) g_quark_to_string(ltt_trace_name(trace
));
1740 remove_trace_name
= get_remove_trace(mw_data
, name
, nb_trace
);
1743 if(remove_trace_name
){
1745 /* yuk, cut n paste from old code.. should be better (MD)*/
1746 for(i
= 0; i
<nb_trace
; i
++) {
1747 if(strcmp(remove_trace_name
,name
[i
]) == 0){
1752 traceset
= tab
->traceset_info
->traceset
;
1753 //Keep a reference to the traces so they are not freed.
1754 for(j
=0; j
<lttv_traceset_number(traceset
); j
++)
1756 LttvTrace
* trace
= lttv_traceset_get(traceset
, j
);
1757 lttv_trace_ref(trace
);
1760 //remove state update hooks
1761 lttv_state_remove_event_hooks(
1762 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1763 lttv_context_fini(LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
));
1764 g_object_unref(tab
->traceset_info
->traceset_context
);
1766 trace_v
= lttv_traceset_get(traceset
, index
);
1768 lttv_traceset_remove(traceset
, index
);
1769 lttv_trace_unref(trace_v
); // Remove local reference
1771 if(lttv_trace_get_ref_number(trace_v
) <= 1) {
1772 /* ref 1 : lttvwindowtraces only*/
1773 ltt_trace_close(lttv_trace(trace_v
));
1774 /* lttvwindowtraces_remove_trace takes care of destroying
1775 * the traceset linked with the trace_v and also of destroying
1776 * the trace_v at the same time.
1778 lttvwindowtraces_remove_trace(trace_v
);
1781 tab
->traceset_info
->traceset_context
=
1782 g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
1784 LTTV_TRACESET_CONTEXT(tab
->
1785 traceset_info
->traceset_context
),traceset
);
1786 //add state update hooks
1787 lttv_state_add_event_hooks(
1788 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1790 //Remove local reference to the traces.
1791 for(j
=0; j
<lttv_traceset_number(traceset
); j
++)
1793 LttvTrace
* trace
= lttv_traceset_get(traceset
, j
);
1794 lttv_trace_unref(trace
);
1797 SetTraceset(tab
, (gpointer
)traceset
);
1803 void remove_trace(GtkWidget
* widget
, gpointer user_data
)
1806 LttvTrace
* trace_v
;
1807 LttvTraceset
* traceset
;
1808 gint i
, j
, nb_trace
;
1809 char ** name
, *remove_trace_name
;
1810 MainWindow
* mw_data
= get_window_data_struct(widget
);
1811 LttvTracesetSelector
* s
;
1812 LttvTraceSelector
* t
;
1815 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
1817 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
1818 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
1824 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
1827 nb_trace
=lttv_traceset_number(tab
->traceset_info
->traceset
);
1828 name
= g_new(char*,nb_trace
);
1829 for(i
= 0; i
< nb_trace
; i
++){
1830 trace_v
= lttv_traceset_get(tab
->traceset_info
->traceset
, i
);
1831 trace
= lttv_trace(trace_v
);
1832 name
[i
] = ltt_trace_name(trace
);
1835 remove_trace_name
= get_remove_trace(name
, nb_trace
);
1837 if(remove_trace_name
){
1838 for(i
=0; i
<nb_trace
; i
++){
1839 if(strcmp(remove_trace_name
,name
[i
]) == 0){
1840 //unselect the trace from the current viewer
1842 w
= gtk_multivpaned_get_widget(GTK_MULTIVPANED(tab
->multivpaned
));
1844 s
= g_object_get_data(G_OBJECT(w
), "Traceset_Selector");
1846 t
= lttv_traceset_selector_trace_get(s
,i
);
1847 lttv_trace_selector_set_selected(t
, FALSE
);
1850 //check if other viewers select the trace
1851 w
= gtk_multivpaned_get_first_widget(GTK_MULTIVPANED(tab
->multivpaned
));
1853 s
= g_object_get_data(G_OBJECT(w
), "Traceset_Selector");
1855 t
= lttv_traceset_selector_trace_get(s
,i
);
1856 selected
= lttv_trace_selector_get_selected(t
);
1859 w
= gtk_multivpaned_get_next_widget(GTK_MULTIVPANED(tab
->multivpaned
));
1861 }else selected
= FALSE
;
1863 //if no viewer selects the trace, remove it
1865 remove_trace_from_traceset_selector(GTK_MULTIVPANED(tab
->multivpaned
), i
);
1867 traceset
= tab
->traceset_info
->traceset
;
1868 //Keep a reference to the traces so they are not freed.
1869 for(j
=0; j
<lttv_traceset_number(traceset
); j
++)
1871 LttvTrace
* trace
= lttv_traceset_get(traceset
, j
);
1872 lttv_trace_ref(trace
);
1875 //remove state update hooks
1876 lttv_state_remove_event_hooks(
1877 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1878 lttv_context_fini(LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
));
1879 g_object_unref(tab
->traceset_info
->traceset_context
);
1882 trace_v
= lttv_traceset_get(traceset
, i
);
1884 if(lttv_trace_get_ref_number(trace_v
) <= 2) {
1885 /* ref 2 : traceset, local */
1886 lttvwindowtraces_remove_trace(trace_v
);
1887 ltt_trace_close(lttv_trace(trace_v
));
1890 lttv_traceset_remove(traceset
, i
);
1891 lttv_trace_unref(trace_v
); // Remove local reference
1893 if(!lttv_trace_get_ref_number(trace_v
))
1894 lttv_trace_destroy(trace_v
);
1896 tab
->traceset_info
->traceset_context
=
1897 g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
1899 LTTV_TRACESET_CONTEXT(tab
->
1900 traceset_info
->traceset_context
),traceset
);
1901 //add state update hooks
1902 lttv_state_add_event_hooks(
1903 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1905 //Remove local reference to the traces.
1906 for(j
=0; j
<lttv_traceset_number(traceset
); j
++)
1908 LttvTrace
* trace
= lttv_traceset_get(traceset
, j
);
1909 lttv_trace_unref(trace
);
1913 //update current tab
1914 //update_traceset(mw_data);
1917 SetTraceset(tab
, (gpointer
)traceset
);
1918 // in expose now call_pending_read_hooks(mw_data);
1920 //lttvwindow_report_current_time(mw_data,&(tab->current_time));
1923 // while(tab->multi_vpaned->num_children){
1924 // gtk_multi_vpaned_widget_delete(tab->multi_vpaned);
1938 /* Redraw all the viewers in the current tab */
1939 void redraw(GtkWidget
*widget
, gpointer user_data
)
1941 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
1942 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
1943 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
1950 LttvPluginTab
*ptab
;
1951 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
1956 LttvAttributeValue value
;
1958 retval
= lttv_iattribute_find_by_path(tab
->attributes
, "hooks/redraw", LTTV_POINTER
, &value
);
1961 tmp
= (LttvHooks
*)*(value
.v_pointer
);
1963 lttv_hooks_call(tmp
,NULL
);
1967 void continue_processing(GtkWidget
*widget
, gpointer user_data
)
1969 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
1970 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
1971 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
1978 LttvPluginTab
*ptab
;
1979 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
1984 LttvAttributeValue value
;
1986 retval
= lttv_iattribute_find_by_path(tab
->attributes
, "hooks/continue",
1987 LTTV_POINTER
, &value
);
1990 tmp
= (LttvHooks
*)*(value
.v_pointer
);
1992 lttv_hooks_call(tmp
,NULL
);
1995 /* Stop the processing for the calling main window's current tab.
1996 * It removes every processing requests that are in its list. It does not call
1997 * the end request hooks, because the request is not finished.
2000 void stop_processing(GtkWidget
*widget
, gpointer user_data
)
2002 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
2003 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2004 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2009 LttvPluginTab
*ptab
;
2010 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
2013 GSList
*iter
= tab
->events_requests
;
2015 while(iter
!= NULL
) {
2016 GSList
*remove_iter
= iter
;
2017 iter
= g_slist_next(iter
);
2019 g_free(remove_iter
->data
);
2020 tab
->events_requests
=
2021 g_slist_remove_link(tab
->events_requests
, remove_iter
);
2023 tab
->events_request_pending
= FALSE
;
2024 tab
->stop_foreground
= TRUE
;
2025 g_idle_remove_by_data(tab
);
2026 g_assert(g_slist_length(tab
->events_requests
) == 0);
2030 /* save will save the traceset to a file
2031 * Not implemented yet FIXME
2034 void save(GtkWidget
* widget
, gpointer user_data
)
2039 void save_as(GtkWidget
* widget
, gpointer user_data
)
2041 g_info("Save as\n");
2045 /* zoom will change the time_window of all the viewers of the
2046 * current tab, and redisplay them. The main functionality is to
2047 * determine the new time_window of the current tab
2050 void zoom(GtkWidget
* widget
, double size
)
2052 TimeInterval time_span
;
2053 TimeWindow new_time_window
;
2054 LttTime current_time
, time_delta
;
2055 LttvTracesetContext
*tsc
;
2056 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
2058 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2059 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2065 LttvPluginTab
*ptab
;
2066 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
2070 if(size
== 1) return;
2072 tsc
= LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
2073 time_span
= tsc
->time_span
;
2074 new_time_window
= tab
->time_window
;
2075 current_time
= tab
->current_time
;
2077 time_delta
= ltt_time_sub(time_span
.end_time
,time_span
.start_time
);
2079 new_time_window
.start_time
= time_span
.start_time
;
2080 new_time_window
.time_width
= time_delta
;
2081 new_time_window
.time_width_double
= ltt_time_to_double(time_delta
);
2082 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
2083 new_time_window
.time_width
) ;
2085 new_time_window
.time_width
= ltt_time_div(new_time_window
.time_width
, size
);
2086 new_time_window
.time_width_double
=
2087 ltt_time_to_double(new_time_window
.time_width
);
2088 if(ltt_time_compare(new_time_window
.time_width
,time_delta
) > 0)
2089 { /* Case where zoom out is bigger than trace length */
2090 new_time_window
.start_time
= time_span
.start_time
;
2091 new_time_window
.time_width
= time_delta
;
2092 new_time_window
.time_width_double
= ltt_time_to_double(time_delta
);
2093 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
2094 new_time_window
.time_width
) ;
2098 /* Center the image on the current time */
2099 new_time_window
.start_time
=
2100 ltt_time_sub(current_time
,
2101 ltt_time_from_double(new_time_window
.time_width_double
/2.0));
2102 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
2103 new_time_window
.time_width
) ;
2104 /* If on borders, don't fall off */
2105 if(ltt_time_compare(new_time_window
.start_time
, time_span
.start_time
) <0
2106 || ltt_time_compare(new_time_window
.start_time
, time_span
.end_time
) >0)
2108 new_time_window
.start_time
= time_span
.start_time
;
2109 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
2110 new_time_window
.time_width
) ;
2114 if(ltt_time_compare(new_time_window
.end_time
,
2115 time_span
.end_time
) > 0
2116 || ltt_time_compare(new_time_window
.end_time
,
2117 time_span
.start_time
) < 0)
2119 new_time_window
.start_time
=
2120 ltt_time_sub(time_span
.end_time
, new_time_window
.time_width
);
2122 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
2123 new_time_window
.time_width
) ;
2130 if(ltt_time_compare(new_time_window
.time_width
, ltt_time_zero
) == 0) {
2131 g_warning("Zoom more than 1 ns impossible");
2133 time_change_manager(tab
, new_time_window
);
2137 void zoom_in(GtkWidget
* widget
, gpointer user_data
)
2142 void zoom_out(GtkWidget
* widget
, gpointer user_data
)
2147 void zoom_extended(GtkWidget
* widget
, gpointer user_data
)
2152 void go_to_time(GtkWidget
* widget
, gpointer user_data
)
2154 g_info("Go to time\n");
2157 void show_time_frame(GtkWidget
* widget
, gpointer user_data
)
2159 g_info("Show time frame\n");
2163 /* callback function */
2166 on_empty_traceset_activate (GtkMenuItem
*menuitem
,
2169 create_new_window((GtkWidget
*)menuitem
, user_data
, FALSE
);
2174 on_clone_traceset_activate (GtkMenuItem
*menuitem
,
2177 create_new_window((GtkWidget
*)menuitem
, user_data
, TRUE
);
2181 /* create_new_tab calls create_tab to construct a new tab in the main window
2184 LttvPluginTab
*create_new_tab(GtkWidget
* widget
, gpointer user_data
)
2186 gchar label
[PATH_MAX
];
2187 MainWindow
* mw_data
= get_window_data_struct(widget
);
2189 GtkNotebook
* notebook
= (GtkNotebook
*)lookup_widget(widget
, "MNotebook");
2190 if(notebook
== NULL
){
2191 g_info("Notebook does not exist\n");
2194 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2195 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2201 LttvPluginTab
*ptab
;
2202 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
2203 copy_tab
= ptab
->tab
;
2206 strcpy(label
,"Page");
2207 if(get_label(mw_data
, label
,"Get the name of the tab","Please input tab's name")) {
2208 LttvPluginTab
*ptab
;
2210 ptab
= g_object_new(LTTV_TYPE_PLUGIN_TAB
, NULL
);
2211 init_tab (ptab
->tab
, mw_data
, copy_tab
, notebook
, label
);
2212 ptab
->parent
.top_widget
= ptab
->tab
->top_widget
;
2213 g_object_set_data_full(
2214 G_OBJECT(ptab
->tab
->vbox
),
2217 (GDestroyNotify
)tab_destructor
);
2224 on_tab_activate (GtkMenuItem
*menuitem
,
2227 create_new_tab((GtkWidget
*)menuitem
, user_data
);
2232 on_open_activate (GtkMenuItem
*menuitem
,
2235 open_traceset((GtkWidget
*)menuitem
, user_data
);
2240 on_close_activate (GtkMenuItem
*menuitem
,
2243 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2244 main_window_destructor(mw_data
);
2248 /* remove the current tab from the main window
2252 on_close_tab_activate (GtkWidget
*widget
,
2256 GtkWidget
* notebook
;
2257 notebook
= lookup_widget(widget
, "MNotebook");
2258 if(notebook
== NULL
){
2259 g_info("Notebook does not exist\n");
2263 page_num
= gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
));
2265 gtk_notebook_remove_page(GTK_NOTEBOOK(notebook
), page_num
);
2270 on_close_tab_X_clicked (GtkWidget
*widget
,
2274 GtkWidget
*notebook
= lookup_widget(widget
, "MNotebook");
2275 if(notebook
== NULL
){
2276 g_info("Notebook does not exist\n");
2280 if((page_num
= gtk_notebook_page_num(GTK_NOTEBOOK(notebook
), widget
)) != -1)
2281 gtk_notebook_remove_page(GTK_NOTEBOOK(notebook
), page_num
);
2287 on_add_trace_activate (GtkMenuItem
*menuitem
,
2290 add_trace((GtkWidget
*)menuitem
, user_data
);
2295 on_remove_trace_activate (GtkMenuItem
*menuitem
,
2298 remove_trace((GtkWidget
*)menuitem
, user_data
);
2303 on_save_activate (GtkMenuItem
*menuitem
,
2306 save((GtkWidget
*)menuitem
, user_data
);
2311 on_save_as_activate (GtkMenuItem
*menuitem
,
2314 save_as((GtkWidget
*)menuitem
, user_data
);
2319 on_quit_activate (GtkMenuItem
*menuitem
,
2322 while (g_slist_length(g_main_window_list
) != 0) {
2323 on_MWindow_destroy(((MainWindow
*)g_main_window_list
->data
)->mwindow
,
2330 on_cut_activate (GtkMenuItem
*menuitem
,
2338 on_copy_activate (GtkMenuItem
*menuitem
,
2346 on_paste_activate (GtkMenuItem
*menuitem
,
2354 on_delete_activate (GtkMenuItem
*menuitem
,
2362 on_zoom_in_activate (GtkMenuItem
*menuitem
,
2365 zoom_in((GtkWidget
*)menuitem
, user_data
);
2370 on_zoom_out_activate (GtkMenuItem
*menuitem
,
2373 zoom_out((GtkWidget
*)menuitem
, user_data
);
2378 on_zoom_extended_activate (GtkMenuItem
*menuitem
,
2381 zoom_extended((GtkWidget
*)menuitem
, user_data
);
2386 on_go_to_time_activate (GtkMenuItem
*menuitem
,
2389 go_to_time((GtkWidget
*)menuitem
, user_data
);
2394 on_show_time_frame_activate (GtkMenuItem
*menuitem
,
2397 show_time_frame((GtkWidget
*)menuitem
, user_data
);
2402 on_move_viewer_up_activate (GtkMenuItem
*menuitem
,
2405 move_up_viewer((GtkWidget
*)menuitem
, user_data
);
2410 on_move_viewer_down_activate (GtkMenuItem
*menuitem
,
2413 move_down_viewer((GtkWidget
*)menuitem
, user_data
);
2418 on_remove_viewer_activate (GtkMenuItem
*menuitem
,
2421 delete_viewer((GtkWidget
*)menuitem
, user_data
);
2425 on_trace_facility_activate (GtkMenuItem
*menuitem
,
2428 g_info("Trace facility selector: %s\n", "");
2432 /* Dispaly a file selection dialogue to let user select a library, then call
2433 * lttv_library_load().
2437 on_load_library_activate (GtkMenuItem
*menuitem
,
2440 GError
*error
= NULL
;
2441 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2443 gchar load_module_path_alter
[PATH_MAX
];
2447 gchar
*load_module_path
;
2448 name
= g_ptr_array_new();
2449 nb
= lttv_library_path_number();
2450 /* ask for the library path */
2454 path
= lttv_library_path_get(i
);
2455 g_ptr_array_add(name
, path
);
2458 load_module_path
= get_selection(mw_data
,
2459 (char **)(name
->pdata
), name
->len
,
2460 "Select a library path", "Library paths");
2461 if(load_module_path
!= NULL
)
2462 strncpy(load_module_path_alter
, load_module_path
, PATH_MAX
-1); // -1 for /
2464 g_ptr_array_free(name
, TRUE
);
2466 if(load_module_path
== NULL
) return;
2470 /* Make sure the module path ends with a / */
2471 gchar
*ptr
= load_module_path_alter
;
2473 ptr
= strchr(ptr
, '\0');
2475 if(*(ptr
-1) != '/') {
2482 /* Ask for the library to load : list files in the previously selected
2484 gchar str
[PATH_MAX
];
2487 GtkFileSelection
* file_selector
=
2488 (GtkFileSelection
*)gtk_file_selection_new("Select a module");
2489 gtk_file_selection_set_filename(file_selector
, load_module_path_alter
);
2490 gtk_file_selection_hide_fileop_buttons(file_selector
);
2492 gtk_window_set_transient_for(GTK_WINDOW(file_selector
),
2493 GTK_WINDOW(mw_data
->mwindow
));
2496 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
2498 case GTK_RESPONSE_ACCEPT
:
2499 case GTK_RESPONSE_OK
:
2500 dir
= gtk_file_selection_get_selections (file_selector
);
2501 strncpy(str
,dir
[0],PATH_MAX
);
2502 strncpy(remember_plugins_dir
,dir
[0],PATH_MAX
);
2503 /* only keep file name */
2505 str1
= strrchr(str
,'/');
2508 str1
= strrchr(str
,'\\');
2513 if(*str1
== 'l' && *(str1
+1)== 'i' && *(str1
+2)=='b')
2515 remove info after
. */
2519 str2
= strrchr(str2
, '.');
2520 if(str2
!= NULL
) *str2
= '\0';
2522 lttv_module_require(str1
, &error
);
2524 lttv_library_load(str1
, &error
);
2525 if(error
!= NULL
) g_warning("%s", error
->message
);
2526 else g_info("Load library: %s\n", str
);
2528 case GTK_RESPONSE_REJECT
:
2529 case GTK_RESPONSE_CANCEL
:
2531 gtk_widget_destroy((GtkWidget
*)file_selector
);
2542 /* Display all loaded modules, let user to select a module to unload
2543 * by calling lttv_module_unload
2547 on_unload_library_activate (GtkMenuItem
*menuitem
,
2550 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2552 LttvLibrary
*library
= NULL
;
2557 name
= g_ptr_array_new();
2558 nb
= lttv_library_number();
2559 LttvLibraryInfo
*lib_info
= g_new(LttvLibraryInfo
,nb
);
2560 /* ask for the library name */
2563 LttvLibrary
*iter_lib
= lttv_library_get(i
);
2564 lttv_library_info(iter_lib
, &lib_info
[i
]);
2566 gchar
*path
= lib_info
[i
].name
;
2567 g_ptr_array_add(name
, path
);
2569 lib_name
= get_selection(mw_data
, (char **)(name
->pdata
), name
->len
,
2570 "Select a library", "Libraries");
2571 if(lib_name
!= NULL
) {
2573 if(strcmp(lib_name
, lib_info
[i
].name
) == 0) {
2574 library
= lttv_library_get(i
);
2579 g_ptr_array_free(name
, TRUE
);
2582 if(lib_name
== NULL
) return;
2584 if(library
!= NULL
) lttv_library_unload(library
);
2588 /* Dispaly a file selection dialogue to let user select a module, then call
2589 * lttv_module_require().
2593 on_load_module_activate (GtkMenuItem
*menuitem
,
2596 GError
*error
= NULL
;
2597 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2599 LttvLibrary
*library
= NULL
;
2604 name
= g_ptr_array_new();
2605 nb
= lttv_library_number();
2606 LttvLibraryInfo
*lib_info
= g_new(LttvLibraryInfo
,nb
);
2607 /* ask for the library name */
2610 LttvLibrary
*iter_lib
= lttv_library_get(i
);
2611 lttv_library_info(iter_lib
, &lib_info
[i
]);
2613 gchar
*path
= lib_info
[i
].name
;
2614 g_ptr_array_add(name
, path
);
2616 lib_name
= get_selection(mw_data
,(char **)(name
->pdata
), name
->len
,
2617 "Select a library", "Libraries");
2618 if(lib_name
!= NULL
) {
2620 if(strcmp(lib_name
, lib_info
[i
].name
) == 0) {
2621 library
= lttv_library_get(i
);
2626 g_ptr_array_free(name
, TRUE
);
2629 if(lib_name
== NULL
) return;
2632 //LttvModule *module;
2633 gchar module_name_out
[PATH_MAX
];
2635 /* Ask for the module to load : list modules in the selected lib */
2639 nb
= lttv_library_module_number(library
);
2640 LttvModuleInfo
*module_info
= g_new(LttvModuleInfo
,nb
);
2641 name
= g_ptr_array_new();
2642 /* ask for the module name */
2645 LttvModule
*iter_module
= lttv_library_module_get(library
, i
);
2646 lttv_module_info(iter_module
, &module_info
[i
]);
2648 gchar
*path
= module_info
[i
].name
;
2649 g_ptr_array_add(name
, path
);
2651 module_name
= get_selection(mw_data
, (char **)(name
->pdata
), name
->len
,
2652 "Select a module", "Modules");
2653 if(module_name
!= NULL
) {
2655 if(strcmp(module_name
, module_info
[i
].name
) == 0) {
2656 strncpy(module_name_out
, module_name
, PATH_MAX
);
2657 //module = lttv_library_module_get(i);
2663 g_ptr_array_free(name
, TRUE
);
2664 g_free(module_info
);
2666 if(module_name
== NULL
) return;
2669 lttv_module_require(module_name_out
, &error
);
2670 if(error
!= NULL
) g_warning("%s", error
->message
);
2671 else g_info("Load module: %s", module_name_out
);
2678 gchar str
[PATH_MAX
];
2681 GtkFileSelection
* file_selector
=
2682 (GtkFileSelection
*)gtk_file_selection_new("Select a module");
2683 gtk_file_selection_set_filename(file_selector
, load_module_path_alter
);
2684 gtk_file_selection_hide_fileop_buttons(file_selector
);
2687 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
2689 case GTK_RESPONSE_ACCEPT
:
2690 case GTK_RESPONSE_OK
:
2691 dir
= gtk_file_selection_get_selections (file_selector
);
2692 strncpy(str
,dir
[0],PATH_MAX
);
2693 strncpy(remember_plugins_dir
,dir
[0],PATH_MAX
);
2695 /* only keep file name */
2697 str1
= strrchr(str
,'/');
2700 str1
= strrchr(str
,'\\');
2705 if(*str1
== 'l' && *(str1
+1)== 'i' && *(str1
+2)=='b')
2707 remove info after
. */
2711 str2
= strrchr(str2
, '.');
2712 if(str2
!= NULL
) *str2
= '\0';
2714 lttv_module_require(str1
, &error
);
2716 lttv_library_load(str1
, &error
);
2717 if(error
!= NULL
) g_warning(error
->message
);
2718 else g_info("Load library: %s\n", str
);
2720 case GTK_RESPONSE_REJECT
:
2721 case GTK_RESPONSE_CANCEL
:
2723 gtk_widget_destroy((GtkWidget
*)file_selector
);
2735 /* Display all loaded modules, let user to select a module to unload
2736 * by calling lttv_module_unload
2740 on_unload_module_activate (GtkMenuItem
*menuitem
,
2743 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2745 LttvLibrary
*library
= NULL
;
2750 name
= g_ptr_array_new();
2751 nb
= lttv_library_number();
2752 LttvLibraryInfo
*lib_info
= g_new(LttvLibraryInfo
,nb
);
2753 /* ask for the library name */
2756 LttvLibrary
*iter_lib
= lttv_library_get(i
);
2757 lttv_library_info(iter_lib
, &lib_info
[i
]);
2759 gchar
*path
= lib_info
[i
].name
;
2760 g_ptr_array_add(name
, path
);
2762 lib_name
= get_selection(mw_data
, (char **)(name
->pdata
), name
->len
,
2763 "Select a library", "Libraries");
2764 if(lib_name
!= NULL
) {
2766 if(strcmp(lib_name
, lib_info
[i
].name
) == 0) {
2767 library
= lttv_library_get(i
);
2772 g_ptr_array_free(name
, TRUE
);
2775 if(lib_name
== NULL
) return;
2778 LttvModule
*module
= NULL
;
2780 /* Ask for the module to load : list modules in the selected lib */
2784 nb
= lttv_library_module_number(library
);
2785 LttvModuleInfo
*module_info
= g_new(LttvModuleInfo
,nb
);
2786 name
= g_ptr_array_new();
2787 /* ask for the module name */
2790 LttvModule
*iter_module
= lttv_library_module_get(library
, i
);
2791 lttv_module_info(iter_module
, &module_info
[i
]);
2793 gchar
*path
= module_info
[i
].name
;
2794 if(module_info
[i
].use_count
> 0) g_ptr_array_add(name
, path
);
2796 module_name
= get_selection(mw_data
, (char **)(name
->pdata
), name
->len
,
2797 "Select a module", "Modules");
2798 if(module_name
!= NULL
) {
2800 if(strcmp(module_name
, module_info
[i
].name
) == 0) {
2801 module
= lttv_library_module_get(library
, i
);
2807 g_ptr_array_free(name
, TRUE
);
2808 g_free(module_info
);
2810 if(module_name
== NULL
) return;
2813 LttvModuleInfo module_info
;
2814 lttv_module_info(module
, &module_info
);
2815 g_info("Release module: %s\n", module_info
.name
);
2817 lttv_module_release(module
);
2821 /* Display a directory dialogue to let user select a path for library searching
2825 on_add_library_search_path_activate (GtkMenuItem
*menuitem
,
2828 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2829 //GtkDirSelection * file_selector = (GtkDirSelection *)gtk_dir_selection_new("Select library path");
2830 GtkFileSelection
* file_selector
= (GtkFileSelection
*)gtk_file_selection_new("Select a trace");
2831 gtk_widget_hide( (file_selector
)->file_list
->parent
) ;
2833 gtk_window_set_transient_for(GTK_WINDOW(file_selector
),
2834 GTK_WINDOW(mw_data
->mwindow
));
2839 if(remember_plugins_dir
[0] != '\0')
2840 gtk_file_selection_set_filename(file_selector
, remember_plugins_dir
);
2842 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
2844 case GTK_RESPONSE_ACCEPT
:
2845 case GTK_RESPONSE_OK
:
2846 dir
= gtk_file_selection_get_filename (file_selector
);
2847 strncpy(remember_plugins_dir
,dir
,PATH_MAX
);
2848 strncat(remember_plugins_dir
,"/",PATH_MAX
);
2849 lttv_library_path_add(dir
);
2850 case GTK_RESPONSE_REJECT
:
2851 case GTK_RESPONSE_CANCEL
:
2853 gtk_widget_destroy((GtkWidget
*)file_selector
);
2859 /* Display a directory dialogue to let user select a path for library searching
2863 on_remove_library_search_path_activate (GtkMenuItem
*menuitem
,
2866 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2868 const char *lib_path
;
2872 name
= g_ptr_array_new();
2873 nb
= lttv_library_path_number();
2874 /* ask for the library name */
2877 gchar
*path
= lttv_library_path_get(i
);
2878 g_ptr_array_add(name
, path
);
2880 lib_path
= get_selection(mw_data
, (char **)(name
->pdata
), name
->len
,
2881 "Select a library path", "Library paths");
2883 g_ptr_array_free(name
, TRUE
);
2885 if(lib_path
== NULL
) return;
2888 lttv_library_path_remove(lib_path
);
2892 on_color_activate (GtkMenuItem
*menuitem
,
2900 on_save_configuration_activate (GtkMenuItem
*menuitem
,
2903 g_info("Save configuration\n");
2908 on_content_activate (GtkMenuItem
*menuitem
,
2911 g_info("Content\n");
2916 on_about_close_activate (GtkButton
*button
,
2919 GtkWidget
*about_widget
= GTK_WIDGET(user_data
);
2921 gtk_widget_destroy(about_widget
);
2925 on_about_activate (GtkMenuItem
*menuitem
,
2928 MainWindow
*main_window
= get_window_data_struct(GTK_WIDGET(menuitem
));
2929 GtkWidget
*window_widget
= main_window
->mwindow
;
2930 GtkWidget
*about_widget
= gtk_window_new(GTK_WINDOW_TOPLEVEL
);
2931 GtkWindow
*about_window
= GTK_WINDOW(about_widget
);
2932 gint window_width
, window_height
;
2934 gtk_window_set_title(about_window
, "About Linux Trace Toolkit");
2936 gtk_window_set_resizable(about_window
, FALSE
);
2937 gtk_window_set_transient_for(about_window
, GTK_WINDOW(window_widget
));
2938 gtk_window_set_destroy_with_parent(about_window
, TRUE
);
2939 gtk_window_set_modal(about_window
, FALSE
);
2941 /* Put the about window at the center of the screen */
2942 gtk_window_get_size(about_window
, &window_width
, &window_height
);
2943 gtk_window_move (about_window
,
2944 (gdk_screen_width() - window_width
)/2,
2945 (gdk_screen_height() - window_height
)/2);
2947 GtkWidget
*vbox
= gtk_vbox_new(FALSE
, 1);
2949 gtk_container_add(GTK_CONTAINER(about_widget
), vbox
);
2953 GtkWidget
*label1
= gtk_label_new("");
2954 gtk_misc_set_padding(GTK_MISC(label1
), 10, 20);
2955 gtk_label_set_markup(GTK_LABEL(label1
), "\
2956 <big>Linux Trace Toolkit " VERSION
"</big>");
2957 gtk_label_set_justify(GTK_LABEL(label1
), GTK_JUSTIFY_CENTER
);
2959 GtkWidget
*label2
= gtk_label_new("");
2960 gtk_misc_set_padding(GTK_MISC(label2
), 10, 20);
2961 gtk_label_set_markup(GTK_LABEL(label2
), "\
2964 Michel Dagenais (New trace format, lttv main)\n\
2965 Mathieu Desnoyers (Kernel Tracer, Directory structure, build with automake/conf,\n\
2966 lttv gui, control flow view, gui cooperative trace reading\n\
2967 scheduler with interruptible foreground and background\n\
2968 computation, detailed event list (rewrite), trace reading\n\
2969 library (rewrite))\n\
2970 Benoit Des Ligneris, Eric Clement (Cluster adaptation, work in progress)\n\
2971 Xang-Xiu Yang (new trace reading library and converter, lttv gui, \n\
2972 detailed event list and statistics view)\n\
2973 Tom Zanussi (RelayFS)\n\
2975 Inspired from the original Linux Trace Toolkit Visualizer made by\n\
2978 GtkWidget
*label3
= gtk_label_new("");
2979 gtk_label_set_markup(GTK_LABEL(label3
), "\
2980 Linux Trace Toolkit Viewer, Copyright (C) 2004, 2005, 2006\n\
2982 Mathieu Desnoyers\n\
2984 Linux Trace Toolkit comes with ABSOLUTELY NO WARRANTY.\n\
2985 This is free software, and you are welcome to redistribute it\n\
2986 under certain conditions. See COPYING for details.");
2987 gtk_misc_set_padding(GTK_MISC(label3
), 10, 20);
2989 gtk_box_pack_start_defaults(GTK_BOX(vbox
), label1
);
2990 gtk_box_pack_start_defaults(GTK_BOX(vbox
), label2
);
2991 gtk_box_pack_start_defaults(GTK_BOX(vbox
), label3
);
2993 GtkWidget
*hbox
= gtk_hbox_new(TRUE
, 0);
2994 gtk_box_pack_end(GTK_BOX(vbox
), hbox
, FALSE
, FALSE
, 0);
2995 GtkWidget
*close_button
= gtk_button_new_with_mnemonic("_Close");
2996 gtk_box_pack_end(GTK_BOX(hbox
), close_button
, FALSE
, FALSE
, 0);
2997 gtk_container_set_border_width(GTK_CONTAINER(close_button
), 20);
2999 g_signal_connect(G_OBJECT(close_button
), "clicked",
3000 G_CALLBACK(on_about_close_activate
),
3001 (gpointer
)about_widget
);
3003 gtk_widget_show_all(about_widget
);
3008 on_button_new_clicked (GtkButton
*button
,
3011 create_new_window((GtkWidget
*)button
, user_data
, TRUE
);
3015 on_button_new_tab_clicked (GtkButton
*button
,
3018 create_new_tab((GtkWidget
*)button
, user_data
);
3022 on_button_open_clicked (GtkButton
*button
,
3025 open_traceset((GtkWidget
*)button
, user_data
);
3030 on_button_add_trace_clicked (GtkButton
*button
,
3033 add_trace((GtkWidget
*)button
, user_data
);
3038 on_button_remove_trace_clicked (GtkButton
*button
,
3041 remove_trace((GtkWidget
*)button
, user_data
);
3045 on_button_redraw_clicked (GtkButton
*button
,
3048 redraw((GtkWidget
*)button
, user_data
);
3052 on_button_continue_processing_clicked (GtkButton
*button
,
3055 continue_processing((GtkWidget
*)button
, user_data
);
3059 on_button_stop_processing_clicked (GtkButton
*button
,
3062 stop_processing((GtkWidget
*)button
, user_data
);
3068 on_button_save_clicked (GtkButton
*button
,
3071 save((GtkWidget
*)button
, user_data
);
3076 on_button_save_as_clicked (GtkButton
*button
,
3079 save_as((GtkWidget
*)button
, user_data
);
3084 on_button_zoom_in_clicked (GtkButton
*button
,
3087 zoom_in((GtkWidget
*)button
, user_data
);
3092 on_button_zoom_out_clicked (GtkButton
*button
,
3095 zoom_out((GtkWidget
*)button
, user_data
);
3100 on_button_zoom_extended_clicked (GtkButton
*button
,
3103 zoom_extended((GtkWidget
*)button
, user_data
);
3108 on_button_go_to_time_clicked (GtkButton
*button
,
3111 go_to_time((GtkWidget
*)button
, user_data
);
3116 on_button_show_time_frame_clicked (GtkButton
*button
,
3119 show_time_frame((GtkWidget
*)button
, user_data
);
3124 on_button_move_up_clicked (GtkButton
*button
,
3127 move_up_viewer((GtkWidget
*)button
, user_data
);
3132 on_button_move_down_clicked (GtkButton
*button
,
3135 move_down_viewer((GtkWidget
*)button
, user_data
);
3140 on_button_delete_viewer_clicked (GtkButton
*button
,
3143 delete_viewer((GtkWidget
*)button
, user_data
);
3147 on_MWindow_destroy (GtkWidget
*widget
,
3150 MainWindow
*main_window
= get_window_data_struct(widget
);
3151 LttvIAttribute
*attributes
= main_window
->attributes
;
3152 LttvAttributeValue value
;
3155 //This is unnecessary, since widgets will be destroyed
3156 //by the main window widget anyway.
3157 //remove_all_menu_toolbar_constructors(main_window, NULL);
3159 retval
= lttv_iattribute_find_by_path(attributes
, "viewers/menu",
3160 LTTV_POINTER
, &value
);
3162 lttv_menus_destroy((LttvMenus
*)*(value
.v_pointer
));
3164 retval
= lttv_iattribute_find_by_path(attributes
, "viewers/toolbar",
3165 LTTV_POINTER
, &value
);
3167 lttv_toolbars_destroy((LttvToolbars
*)*(value
.v_pointer
));
3169 g_object_unref(main_window
->attributes
);
3170 g_main_window_list
= g_slist_remove(g_main_window_list
, main_window
);
3172 g_info("There are now : %d windows\n",g_slist_length(g_main_window_list
));
3173 if(g_slist_length(g_main_window_list
) == 0)
3178 on_MWindow_configure (GtkWidget
*widget
,
3179 GdkEventConfigure
*event
,
3182 // MD : removed time width modification upon resizing of the main window.
3183 // The viewers will redraw themselves completely, without time interval
3186 if(mw_data->window_width){
3187 time_span = LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context)->Time_Span ;
3188 time_win = tab->time_window;
3189 ratio = width / mw_data->window_width;
3190 tab->time_window.time_width = ltt_time_mul(time_win.time_width,ratio);
3191 time = ltt_time_sub(time_span->endTime, time_win.start_time);
3192 if(ltt_time_compare(time, tab->time_window.time_width) < 0){
3193 tab->time_window.time_width = time;
3199 mw_data->window_width = (int)width;
3208 on_MNotebook_switch_page (GtkNotebook
*notebook
,
3209 GtkNotebookPage
*page
,
3217 void time_change_manager (Tab
*tab
,
3218 TimeWindow new_time_window
)
3220 /* Only one source of time change */
3221 if(tab
->time_manager_lock
== TRUE
) return;
3223 tab
->time_manager_lock
= TRUE
;
3225 LttvTracesetContext
*tsc
= LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3226 TimeInterval time_span
= tsc
->time_span
;
3227 LttTime start_time
= new_time_window
.start_time
;
3228 LttTime end_time
= new_time_window
.end_time
;
3230 g_assert(ltt_time_compare(start_time
, end_time
) < 0);
3233 GtkAdjustment
*adjustment
= gtk_range_get_adjustment(GTK_RANGE(tab
->scrollbar
));
3234 LttTime upper
= ltt_time_sub(time_span
.end_time
, time_span
.start_time
);
3236 gtk_range_set_increments(GTK_RANGE(tab
->scrollbar
),
3237 ltt_time_to_double(new_time_window
.time_width
)
3238 / SCROLL_STEP_PER_PAGE
3239 * NANOSECONDS_PER_SECOND
, /* step increment */
3240 ltt_time_to_double(new_time_window
.time_width
)
3241 * NANOSECONDS_PER_SECOND
); /* page increment */
3242 gtk_range_set_range(GTK_RANGE(tab
->scrollbar
),
3244 ltt_time_to_double(upper
)
3245 * NANOSECONDS_PER_SECOND
); /* upper */
3247 g_object_set(G_OBJECT(adjustment
),
3251 ltt_time_to_double(upper
), /* upper */
3253 new_time_window
.time_width_double
3254 / SCROLL_STEP_PER_PAGE
, /* step increment */
3256 new_time_window
.time_width_double
,
3257 /* page increment */
3259 new_time_window
.time_width_double
, /* page size */
3261 gtk_adjustment_changed(adjustment
);
3263 // g_object_set(G_OBJECT(adjustment),
3265 // ltt_time_to_double(
3266 // ltt_time_sub(start_time, time_span.start_time))
3269 //gtk_adjustment_value_changed(adjustment);
3270 gtk_range_set_value(GTK_RANGE(tab
->scrollbar
),
3272 ltt_time_sub(start_time
, time_span
.start_time
)) /* value */);
3274 /* set the time bar. */
3277 timebar_set_minmax_time(TIMEBAR(tab
->MTimebar
),
3278 &time_span
.start_time
,
3279 &time_span
.end_time
);
3280 timebar_set_start_time(TIMEBAR(tab
->MTimebar
),&start_time
);
3281 timebar_set_end_time(TIMEBAR(tab
->MTimebar
),&end_time
);
3285 /* call viewer hooks for new time window */
3286 set_time_window(tab
, &new_time_window
);
3288 tab
->time_manager_lock
= FALSE
;
3295 void current_time_change_manager (Tab
*tab
,
3296 LttTime new_current_time
)
3298 /* Only one source of time change */
3299 if(tab
->current_time_manager_lock
== TRUE
) return;
3301 tab
->current_time_manager_lock
= TRUE
;
3303 timebar_set_current_time(TIMEBAR(tab
->MTimebar
), &new_current_time
);
3305 set_current_time(tab
, &new_current_time
);
3307 tab
->current_time_manager_lock
= FALSE
;
3310 void current_position_change_manager(Tab
*tab
,
3311 LttvTracesetContextPosition
*pos
)
3313 LttvTracesetContext
*tsc
=
3314 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3317 retval
= lttv_process_traceset_seek_position(tsc
, pos
);
3318 g_assert_cmpint(retval
, ==, 0);
3319 LttTime new_time
= lttv_traceset_context_position_get_time(pos
);
3320 /* Put the context in a state coherent position */
3321 lttv_state_traceset_seek_time_closest((LttvTracesetState
*)tsc
, ltt_time_zero
);
3323 current_time_change_manager(tab
, new_time
);
3325 set_current_position(tab
, pos
);
3328 static void on_timebar_starttime_changed(Timebar
*timebar
,
3331 Tab
*tab
= (Tab
*)user_data
;
3332 LttvTracesetContext
* tsc
=
3333 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3334 TimeInterval time_span
= tsc
->time_span
;
3336 TimeWindow new_time_window
= tab
->time_window
;
3337 new_time_window
.start_time
= timebar_get_start_time(timebar
);
3339 LttTime end_time
= new_time_window
.end_time
;
3341 /* TODO ybrosseau 2010-12-02: This if should have been checked
3342 by the timebar already */
3343 if(ltt_time_compare(new_time_window
.start_time
, end_time
) >= 0) {
3344 /* Then, we must push back end time : keep the same time width
3345 * if possible, else end traceset time */
3346 end_time
= LTT_TIME_MIN(ltt_time_add(new_time_window
.start_time
,
3347 new_time_window
.time_width
),
3348 time_span
.end_time
);
3351 /* Fix the time width to fit start time and end time */
3352 new_time_window
.time_width
= ltt_time_sub(end_time
,
3353 new_time_window
.start_time
);
3355 new_time_window
.time_width_double
=
3356 ltt_time_to_double(new_time_window
.time_width
);
3358 new_time_window
.end_time
= end_time
;
3360 /* Notify the time_manager */
3361 time_change_manager(tab
, new_time_window
);
3365 static void on_timebar_endtime_changed(Timebar
*timebar
,
3368 Tab
*tab
= (Tab
*)user_data
;
3369 LttvTracesetContext
* tsc
=
3370 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3371 TimeInterval time_span
= tsc
->time_span
;
3373 TimeWindow new_time_window
= tab
->time_window
;
3375 LttTime end_time
= timebar_get_end_time(timebar
);
3377 /* TODO ybrosseau 2010-12-02: This if should have been
3378 checked by the timebar already */
3379 if(ltt_time_compare(new_time_window
.start_time
, end_time
) >= 0) {
3380 /* Then, we must push front start time : keep the same time
3381 width if possible, else end traceset time */
3382 new_time_window
.start_time
= LTT_TIME_MAX(
3383 ltt_time_sub(end_time
,
3384 new_time_window
.time_width
),
3385 time_span
.start_time
);
3388 /* Fix the time width to fit start time and end time */
3389 new_time_window
.time_width
= ltt_time_sub(end_time
,
3390 new_time_window
.start_time
);
3392 new_time_window
.time_width_double
=
3393 ltt_time_to_double(new_time_window
.time_width
);
3395 new_time_window
.end_time
= end_time
;
3397 /* Notify the time_manager */
3398 time_change_manager(tab
, new_time_window
);
3400 static void on_timebar_currenttime_changed(Timebar
*timebar
,
3403 Tab
*tab
= (Tab
*)user_data
;
3405 LttTime new_current_time
= timebar_get_current_time(timebar
);
3407 current_time_change_manager(tab
, new_current_time
);
3410 void scroll_value_changed_cb(GtkWidget
*scrollbar
,
3413 Tab
*tab
= (Tab
*)user_data
;
3414 TimeWindow new_time_window
;
3416 GtkAdjustment
*adjust
= gtk_range_get_adjustment(GTK_RANGE(scrollbar
));
3417 gdouble value
= gtk_adjustment_get_value(adjust
);
3418 // gdouble upper, lower, ratio, page_size;
3420 LttvTracesetContext
* tsc
=
3421 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3422 TimeInterval time_span
= tsc
->time_span
;
3424 time
= ltt_time_add(ltt_time_from_double(value
),
3425 time_span
.start_time
);
3427 new_time_window
.start_time
= time
;
3429 page_size
= adjust
->page_size
;
3431 new_time_window
.time_width
=
3432 ltt_time_from_double(page_size
);
3434 new_time_window
.time_width_double
=
3437 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
3438 new_time_window
.time_width
);
3441 time_change_manager(tab
, new_time_window
);
3443 //time_window = tab->time_window;
3445 lower
= adjust
->lower
;
3446 upper
= adjust
->upper
;
3447 ratio
= (value
- lower
) / (upper
- lower
);
3448 g_info("lower %lu, upper %lu, value %lu, ratio %lu", lower
, upper
, value
, ratio
);
3450 //time = ltt_time_sub(time_span->end_time, time_span->start_time);
3451 //time = ltt_time_mul(time, (float)ratio);
3452 //time = ltt_time_add(time_span->start_time, time);
3453 time
= ltt_time_add(ltt_time_from_double(value
),
3454 time_span
.start_time
);
3456 time_window
.start_time
= time
;
3458 page_size
= adjust
->page_size
;
3460 time_window
.time_width
=
3461 ltt_time_from_double(page_size
);
3462 //time = ltt_time_sub(time_span.end_time, time);
3463 //if(ltt_time_compare(time,time_window.time_width) < 0){
3464 // time_window.time_width = time;
3467 /* call viewer hooks for new time window */
3468 set_time_window(tab
, &time_window
);
3473 /* Display a dialogue showing all eventtypes and traces, let user to select the interested
3474 * eventtypes, tracefiles and traces (filter)
3477 /* Select a trace which will be removed from traceset
3480 char * get_remove_trace(MainWindow
*mw_data
,
3481 char ** all_trace_name
, int nb_trace
)
3483 return get_selection(mw_data
, all_trace_name
, nb_trace
,
3484 "Select a trace", "Trace pathname");
3488 /* Select a module which will be loaded
3491 char * get_load_module(MainWindow
*mw_data
,
3492 char ** load_module_name
, int nb_module
)
3494 return get_selection(mw_data
, load_module_name
, nb_module
,
3495 "Select a module to load", "Module name");
3501 /* Select a module which will be unloaded
3504 char * get_unload_module(MainWindow
*mw_data
,
3505 char ** loaded_module_name
, int nb_module
)
3507 return get_selection(mw_data
, loaded_module_name
, nb_module
,
3508 "Select a module to unload", "Module name");
3512 /* Display a dialogue which shows all selectable items, let user to
3513 * select one of them
3516 char * get_selection(MainWindow
*mw_data
,
3517 char ** loaded_module_name
, int nb_module
,
3518 char *title
, char * column_title
)
3520 GtkWidget
* dialogue
;
3521 GtkWidget
* scroll_win
;
3523 GtkListStore
* store
;
3524 GtkTreeViewColumn
* column
;
3525 GtkCellRenderer
* renderer
;
3526 GtkTreeSelection
* select
;
3529 char * unload_module_name
= NULL
;
3531 dialogue
= gtk_dialog_new_with_buttons(title
,
3534 GTK_STOCK_OK
,GTK_RESPONSE_ACCEPT
,
3535 GTK_STOCK_CANCEL
,GTK_RESPONSE_REJECT
,
3537 gtk_window_set_default_size((GtkWindow
*)dialogue
, 500, 200);
3538 gtk_window_set_transient_for(GTK_WINDOW(dialogue
),
3539 GTK_WINDOW(mw_data
->mwindow
));
3541 scroll_win
= gtk_scrolled_window_new (NULL
, NULL
);
3542 gtk_widget_show ( scroll_win
);
3543 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll_win
),
3544 GTK_POLICY_AUTOMATIC
, GTK_POLICY_AUTOMATIC
);
3546 store
= gtk_list_store_new (N_COLUMNS
,G_TYPE_STRING
);
3547 tree
= gtk_tree_view_new_with_model(GTK_TREE_MODEL (store
));
3548 gtk_widget_show ( tree
);
3549 g_object_unref (G_OBJECT (store
));
3551 renderer
= gtk_cell_renderer_text_new ();
3552 column
= gtk_tree_view_column_new_with_attributes (column_title
,
3554 "text", MODULE_COLUMN
,
3556 gtk_tree_view_column_set_alignment (column
, 0.5);
3557 gtk_tree_view_column_set_fixed_width (column
, 150);
3558 gtk_tree_view_append_column (GTK_TREE_VIEW (tree
), column
);
3560 select
= gtk_tree_view_get_selection (GTK_TREE_VIEW (tree
));
3561 gtk_tree_selection_set_mode (select
, GTK_SELECTION_SINGLE
);
3563 gtk_container_add (GTK_CONTAINER (scroll_win
), tree
);
3565 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialogue
)->vbox
), scroll_win
,TRUE
, TRUE
,0);
3567 for(i
=0;i
<nb_module
;i
++){
3568 gtk_list_store_append (store
, &iter
);
3569 gtk_list_store_set (store
, &iter
, MODULE_COLUMN
,loaded_module_name
[i
],-1);
3572 id
= gtk_dialog_run(GTK_DIALOG(dialogue
));
3573 GtkTreeModel
**store_model
= (GtkTreeModel
**)&store
;
3575 case GTK_RESPONSE_ACCEPT
:
3576 case GTK_RESPONSE_OK
:
3577 if (gtk_tree_selection_get_selected (select
, store_model
, &iter
)){
3578 gtk_tree_model_get ((GtkTreeModel
*)store
, &iter
, MODULE_COLUMN
, &unload_module_name
, -1);
3580 case GTK_RESPONSE_REJECT
:
3581 case GTK_RESPONSE_CANCEL
:
3583 gtk_widget_destroy(dialogue
);
3587 return unload_module_name
;
3591 /* Insert all menu entry and tool buttons into this main window
3596 void add_all_menu_toolbar_constructors(MainWindow
* mw
, gpointer user_data
)
3600 lttvwindow_viewer_constructor constructor
;
3601 LttvMenus
* global_menu
, * instance_menu
;
3602 LttvToolbars
* global_toolbar
, * instance_toolbar
;
3603 LttvMenuClosure
*menu_item
;
3604 LttvToolbarClosure
*toolbar_item
;
3605 LttvAttributeValue value
;
3606 LttvIAttribute
*global_attributes
= LTTV_IATTRIBUTE(lttv_global_attributes());
3607 LttvIAttribute
*attributes
= mw
->attributes
;
3608 GtkWidget
* tool_menu_title_menu
, *new_widget
, *pixmap
;
3611 retval
= lttv_iattribute_find_by_path(global_attributes
, "viewers/menu",
3612 LTTV_POINTER
, &value
);
3614 if(*(value
.v_pointer
) == NULL
)
3615 *(value
.v_pointer
) = lttv_menus_new();
3616 global_menu
= (LttvMenus
*)*(value
.v_pointer
);
3618 retval
= lttv_iattribute_find_by_path(attributes
, "viewers/menu",
3619 LTTV_POINTER
, &value
);
3621 if(*(value
.v_pointer
) == NULL
)
3622 *(value
.v_pointer
) = lttv_menus_new();
3623 instance_menu
= (LttvMenus
*)*(value
.v_pointer
);
3625 retval
= lttv_iattribute_find_by_path(global_attributes
, "viewers/toolbar",
3626 LTTV_POINTER
, &value
);
3628 if(*(value
.v_pointer
) == NULL
)
3629 *(value
.v_pointer
) = lttv_toolbars_new();
3630 global_toolbar
= (LttvToolbars
*)*(value
.v_pointer
);
3632 retval
= lttv_iattribute_find_by_path(attributes
, "viewers/toolbar",
3633 LTTV_POINTER
, &value
);
3635 if(*(value
.v_pointer
) == NULL
)
3636 *(value
.v_pointer
) = lttv_toolbars_new();
3637 instance_toolbar
= (LttvToolbars
*)*(value
.v_pointer
);
3639 /* Add missing menu entries to window instance */
3640 for(i
=0;i
<global_menu
->len
;i
++) {
3641 menu_item
= &g_array_index(global_menu
, LttvMenuClosure
, i
);
3643 //add menu_item to window instance;
3644 constructor
= menu_item
->con
;
3645 tool_menu_title_menu
= lookup_widget(mw
->mwindow
,"ToolMenuTitle_menu");
3647 gtk_menu_item_new_with_mnemonic (menu_item
->menu_text
);
3648 gtk_container_add (GTK_CONTAINER (tool_menu_title_menu
),
3650 g_signal_connect ((gpointer
) new_widget
, "activate",
3651 G_CALLBACK (insert_viewer_wrap
),
3653 gtk_widget_show (new_widget
);
3654 lttv_menus_add(instance_menu
, menu_item
->con
,
3655 menu_item
->menu_path
,
3656 menu_item
->menu_text
,
3661 /* Add missing toolbar entries to window instance */
3662 for(i
=0;i
<global_toolbar
->len
;i
++) {
3663 toolbar_item
= &g_array_index(global_toolbar
, LttvToolbarClosure
, i
);
3665 //add toolbar_item to window instance;
3666 constructor
= toolbar_item
->con
;
3667 tool_menu_title_menu
= lookup_widget(mw
->mwindow
,"MToolbar1");
3668 pixbuf
= gdk_pixbuf_new_from_xpm_data((const char**)toolbar_item
->pixmap
);
3669 pixmap
= gtk_image_new_from_pixbuf(pixbuf
);
3671 gtk_toolbar_append_element (GTK_TOOLBAR (tool_menu_title_menu
),
3672 GTK_TOOLBAR_CHILD_BUTTON
,
3675 toolbar_item
->tooltip
, NULL
,
3676 pixmap
, NULL
, NULL
);
3677 gtk_label_set_use_underline(
3678 GTK_LABEL (((GtkToolbarChild
*) (
3679 g_list_last (GTK_TOOLBAR
3680 (tool_menu_title_menu
)->children
)->data
))->label
),
3682 gtk_container_set_border_width (GTK_CONTAINER (new_widget
), 1);
3683 g_signal_connect ((gpointer
) new_widget
,
3685 G_CALLBACK (insert_viewer_wrap
),
3687 gtk_widget_show (new_widget
);
3689 lttv_toolbars_add(instance_toolbar
, toolbar_item
->con
,
3690 toolbar_item
->tooltip
,
3691 toolbar_item
->pixmap
,
3699 /* Create a main window
3702 MainWindow
*construct_main_window(MainWindow
* parent
)
3706 g_debug("construct_main_window()");
3707 GtkWidget
* new_window
; /* New generated main window */
3708 MainWindow
* new_m_window
;/* New main window structure */
3709 GtkNotebook
* notebook
;
3710 LttvIAttribute
*attributes
=
3711 LTTV_IATTRIBUTE(g_object_new(LTTV_ATTRIBUTE_TYPE
, NULL
));
3712 LttvAttributeValue value
;
3715 new_m_window
= g_new(MainWindow
, 1);
3717 // Add the object's information to the module's array
3718 g_main_window_list
= g_slist_append(g_main_window_list
, new_m_window
);
3720 new_window
= create_MWindow();
3721 gtk_widget_show (new_window
);
3723 new_m_window
->mwindow
= new_window
;
3724 new_m_window
->attributes
= attributes
;
3726 retval
= lttv_iattribute_find_by_path(attributes
, "viewers/menu",
3727 LTTV_POINTER
, &value
);
3729 *(value
.v_pointer
) = lttv_menus_new();
3731 retval
= lttv_iattribute_find_by_path(attributes
, "viewers/toolbar",
3732 LTTV_POINTER
, &value
);
3734 *(value
.v_pointer
) = lttv_toolbars_new();
3736 add_all_menu_toolbar_constructors(new_m_window
, NULL
);
3738 g_object_set_data_full(G_OBJECT(new_window
),
3740 (gpointer
)new_m_window
,
3741 (GDestroyNotify
)g_free
);
3742 //create a default tab
3743 notebook
= (GtkNotebook
*)lookup_widget(new_m_window
->mwindow
, "MNotebook");
3744 if(notebook
== NULL
){
3745 g_info("Notebook does not exist\n");
3746 /* FIXME : destroy partially created widgets */
3747 g_free(new_m_window
);
3750 //gtk_notebook_popup_enable (GTK_NOTEBOOK(notebook));
3751 //for now there is no name field in LttvTraceset structure
3752 //Use "Traceset" as the label for the default tab
3754 GtkWidget
* parent_notebook
= lookup_widget(parent
->mwindow
, "MNotebook");
3755 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(parent_notebook
),
3756 gtk_notebook_get_current_page(GTK_NOTEBOOK(parent_notebook
)));
3762 LttvPluginTab
*ptab
;
3763 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
3764 parent_tab
= ptab
->tab
;
3766 LttvPluginTab
*ptab
= g_object_new(LTTV_TYPE_PLUGIN_TAB
, NULL
);
3768 new_m_window
, parent_tab
, notebook
, "Traceset");
3769 ptab
->parent
.top_widget
= ptab
->tab
->top_widget
;
3770 g_object_set_data_full(
3771 G_OBJECT(ptab
->tab
->vbox
),
3774 (GDestroyNotify
)tab_destructor
);
3775 new_tab
= ptab
->tab
;
3777 LttvPluginTab
*ptab
= g_object_new(LTTV_TYPE_PLUGIN_TAB
, NULL
);
3778 init_tab(ptab
->tab
, new_m_window
, NULL
, notebook
, "Traceset");
3779 ptab
->parent
.top_widget
= ptab
->tab
->top_widget
;
3780 g_object_set_data_full(
3781 G_OBJECT(ptab
->tab
->vbox
),
3784 (GDestroyNotify
)tab_destructor
);
3785 new_tab
= ptab
->tab
;
3788 /* Insert default viewers */
3790 LttvAttributeType type
;
3791 LttvAttributeName name
;
3792 LttvAttributeValue value
;
3793 LttvAttribute
*attribute
;
3795 LttvIAttribute
*attributes_global
=
3796 LTTV_IATTRIBUTE(lttv_global_attributes());
3798 attribute
= LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
3799 LTTV_IATTRIBUTE(attributes_global
),
3800 LTTV_VIEWER_CONSTRUCTORS
));
3801 g_assert(attribute
);
3803 name
= g_quark_from_string("guievents");
3804 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
3806 if(type
== LTTV_POINTER
) {
3807 lttvwindow_viewer_constructor viewer_constructor
=
3808 (lttvwindow_viewer_constructor
)*value
.v_pointer
;
3809 insert_viewer(new_window
, viewer_constructor
);
3812 name
= g_quark_from_string("guicontrolflow");
3813 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
3815 if(type
== LTTV_POINTER
) {
3816 lttvwindow_viewer_constructor viewer_constructor
=
3817 (lttvwindow_viewer_constructor
)*value
.v_pointer
;
3818 insert_viewer(new_window
, viewer_constructor
);
3821 name
= g_quark_from_string("guistatistics");
3822 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
3824 if(type
== LTTV_POINTER
) {
3825 lttvwindow_viewer_constructor viewer_constructor
=
3826 (lttvwindow_viewer_constructor
)*value
.v_pointer
;
3827 insert_viewer(new_window
, viewer_constructor
);
3831 g_info("There are now : %d windows\n",g_slist_length(g_main_window_list
));
3833 return new_m_window
;
3837 /* Free the memory occupied by a tab structure
3841 void tab_destructor(LttvPluginTab
* ptab
)
3843 int i
, nb
, ref_count
;
3845 Tab
*tab
= ptab
->tab
;
3848 g_object_unref(tab
->attributes
);
3850 if(tab
->interrupted_state
)
3851 g_object_unref(tab
->interrupted_state
);
3854 if(tab
->traceset_info
->traceset_context
!= NULL
){
3855 //remove state update hooks
3856 lttv_state_remove_event_hooks(
3857 (LttvTracesetState
*)tab
->traceset_info
->
3859 lttv_context_fini(LTTV_TRACESET_CONTEXT(tab
->traceset_info
->
3861 g_object_unref(tab
->traceset_info
->traceset_context
);
3863 if(tab
->traceset_info
->traceset
!= NULL
) {
3864 nb
= lttv_traceset_number(tab
->traceset_info
->traceset
);
3865 for(i
= 0 ; i
< nb
; i
++) {
3866 trace
= lttv_traceset_get(tab
->traceset_info
->traceset
, i
);
3867 ref_count
= lttv_trace_get_ref_number(trace
);
3869 ltt_trace_close(lttv_trace(trace
));
3873 lttv_traceset_destroy(tab
->traceset_info
->traceset
);
3874 /* Remove the idle events requests processing function of the tab */
3875 g_idle_remove_by_data(tab
);
3877 g_slist_free(tab
->events_requests
);
3878 g_free(tab
->traceset_info
);
3880 g_object_unref(ptab
);
3884 /* Create a tab and insert it into the current main window
3887 void init_tab(Tab
*tab
, MainWindow
* mw
, Tab
*copy_tab
,
3888 GtkNotebook
* notebook
, char * label
)
3892 //LttvFilter *filter = NULL;
3894 //create a new tab data structure
3895 //tab = g_new(Tab,1);
3897 //construct and initialize the traceset_info
3898 tab
->traceset_info
= g_new(TracesetInfo
,1);
3901 tab
->traceset_info
->traceset
=
3902 lttv_traceset_copy(copy_tab
->traceset_info
->traceset
);
3904 /* Copy the previous tab's filter */
3905 /* We can clone the filter, as we copy the trace set also */
3906 /* The filter must always be in sync with the trace set */
3907 tab
->filter
= lttv_filter_clone(copy_tab
->filter
);
3909 tab
->traceset_info
->traceset
= lttv_traceset_new();
3913 lttv_attribute_write_xml(
3914 lttv_traceset_attribute(tab
->traceset_info
->traceset
),
3920 tab
->time_manager_lock
= FALSE
;
3921 tab
->current_time_manager_lock
= FALSE
;
3923 //FIXME copy not implemented in lower level
3924 tab
->traceset_info
->traceset_context
=
3925 g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
3926 g_assert(tab
->traceset_info
->traceset_context
!= NULL
);
3928 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
),
3929 tab
->traceset_info
->traceset
);
3930 //add state update hooks
3931 lttv_state_add_event_hooks(
3932 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
3934 //determine the current_time and time_window of the tab
3936 if(copy_tab
!= NULL
){
3937 tab
->time_window
= copy_tab
->time_window
;
3938 tab
->current_time
= copy_tab
->current_time
;
3940 tab
->time_window
.start_time
=
3941 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
3942 time_span
.start_time
;
3943 if(DEFAULT_TIME_WIDTH_S
<
3944 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
3945 time_span
.end_time
.tv_sec
)
3946 tmp_time
.tv_sec
= DEFAULT_TIME_WIDTH_S
;
3949 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
3950 time_span
.end_time
.tv_sec
;
3951 tmp_time
.tv_nsec
= 0;
3952 tab
->time_window
.time_width
= tmp_time
;
3953 tab
->current_time
.tv_sec
=
3954 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
3955 time_span
.start_time
.tv_sec
;
3956 tab
->current_time
.tv_nsec
=
3957 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
3958 time_span
.start_time
.tv_nsec
;
3961 tab
->attributes
= LTTV_IATTRIBUTE(g_object_new(LTTV_ATTRIBUTE_TYPE
, NULL
));
3962 tab
->interrupted_state
= g_object_new(LTTV_ATTRIBUTE_TYPE
, NULL
);
3964 tab
->vbox
= gtk_vbox_new(FALSE
, 2);
3965 tab
->top_widget
= tab
->vbox
;
3966 //g_object_set_data_full(G_OBJECT(tab->top_widget), "filter",
3967 // filter, (GDestroyNotify)lttv_filter_destroy);
3969 // g_signal_connect (G_OBJECT(tab->top_widget),
3971 // G_CALLBACK (on_top_notify),
3974 tab
->viewer_container
= gtk_vbox_new(TRUE
, 2);
3975 tab
->scrollbar
= gtk_hscrollbar_new(NULL
);
3976 //tab->multivpaned = gtk_multi_vpaned_new();
3978 gtk_box_pack_start(GTK_BOX(tab
->vbox
),
3979 tab
->viewer_container
,
3981 TRUE
, /* Give the extra space to the child */
3982 0); /* No padding */
3985 // tab->time_window = copy_tab->time_window;
3986 // tab->current_time = copy_tab->current_time;
3989 /* Create the timebar */
3991 tab
->MTimebar
= timebar_new();
3993 gtk_box_pack_end(GTK_BOX(tab
->vbox
),
3995 FALSE
, /* Do not expand */
3996 FALSE
, /* Fill has no effect here (expand false) */
3997 0); /* No padding */
3999 gtk_box_pack_end(GTK_BOX(tab
->vbox
),
4001 FALSE
, /* Do not expand */
4002 FALSE
, /* Fill has no effect here (expand false) */
4003 0); /* No padding */
4005 g_object_set_data(G_OBJECT(tab
->viewer_container
), "focused_viewer", NULL
);
4011 // Display a label with a X
4012 GtkWidget *w_hbox = gtk_hbox_new(FALSE, 4);
4013 GtkWidget *w_label = gtk_label_new (label);
4014 GtkWidget *pixmap = create_pixmap(GTK_WIDGET(notebook), "close.png");
4015 GtkWidget *w_button = gtk_button_new ();
4016 gtk_container_add(GTK_CONTAINER(w_button), pixmap);
4017 //GtkWidget *w_button = gtk_button_new_with_label("x");
4019 gtk_button_set_relief(GTK_BUTTON(w_button), GTK_RELIEF_NONE);
4021 gtk_box_pack_start(GTK_BOX(w_hbox), w_label, TRUE, TRUE, 0);
4022 gtk_box_pack_end(GTK_BOX(w_hbox), w_button, FALSE,
4025 g_signal_connect_swapped (w_button, "clicked",
4026 G_CALLBACK (on_close_tab_X_clicked),
4029 gtk_widget_set_state(w_button, GTK_STATE_ACTIVE);
4031 gtk_widget_show (w_label);
4032 gtk_widget_show (pixmap);
4033 gtk_widget_show (w_button);
4034 gtk_widget_show (w_hbox);
4036 tab->label = w_hbox;
4040 tab
->label
= gtk_label_new (label
);
4042 gtk_widget_show(tab
->label
);
4043 gtk_widget_show(tab
->scrollbar
);
4044 gtk_widget_show(tab
->MTimebar
);
4045 gtk_widget_show(tab
->viewer_container
);
4046 gtk_widget_show(tab
->vbox
);
4048 //gtk_widget_show(tab->multivpaned);
4051 /* Start with empty events requests list */
4052 tab
->events_requests
= NULL
;
4053 tab
->events_request_pending
= FALSE
;
4054 tab
->stop_foreground
= FALSE
;
4058 g_signal_connect(G_OBJECT(tab
->scrollbar
), "value-changed",
4059 G_CALLBACK(scroll_value_changed_cb
), tab
);
4062 /* Timebar signal handler */
4063 g_signal_connect(G_OBJECT(tab
->MTimebar
), "start-time-changed",
4064 G_CALLBACK(on_timebar_starttime_changed
), tab
);
4065 g_signal_connect(G_OBJECT(tab
->MTimebar
), "end-time-changed",
4066 G_CALLBACK(on_timebar_endtime_changed
), tab
);
4067 g_signal_connect(G_OBJECT(tab
->MTimebar
), "current-time-changed",
4068 G_CALLBACK(on_timebar_currenttime_changed
), tab
);
4070 //g_signal_connect(G_OBJECT(tab->scrollbar), "changed",
4071 // G_CALLBACK(scroll_value_changed_cb), tab);
4074 //insert tab into notebook
4075 gtk_notebook_append_page(notebook
,
4078 list
= gtk_container_get_children(GTK_CONTAINER(notebook
));
4079 gtk_notebook_set_current_page(notebook
,g_list_length(list
)-1);
4080 // always show : not if(g_list_length(list)>1)
4081 gtk_notebook_set_show_tabs(notebook
, TRUE
);
4084 lttvwindow_report_time_window(tab
, copy_tab
->time_window
);
4085 lttvwindow_report_current_time(tab
, copy_tab
->current_time
);
4087 TimeWindow time_window
;
4089 time_window
.start_time
= ltt_time_zero
;
4090 time_window
.end_time
= ltt_time_add(time_window
.start_time
,
4091 lttvwindow_default_time_width
);
4092 time_window
.time_width
= lttvwindow_default_time_width
;
4093 time_window
.time_width_double
= ltt_time_to_double(time_window
.time_width
);
4095 lttvwindow_report_time_window(tab
, time_window
);
4096 lttvwindow_report_current_time(tab
, ltt_time_zero
);
4099 LttvTraceset
*traceset
= tab
->traceset_info
->traceset
;
4100 SetTraceset(tab
, traceset
);
4104 * execute_events_requests
4106 * Idle function that executes the pending requests for a tab.
4108 * @return return value : TRUE : keep the idle function, FALSE : remove it.
4110 gboolean
execute_events_requests(Tab
*tab
)
4112 return ( lttvwindow_process_pending_requests(tab
) );
4116 __EXPORT
void create_main_window_with_trace_list(GSList
*traces
, gboolean is_live
)
4118 GSList
*iter
= NULL
;
4121 MainWindow
*mw
= construct_main_window(NULL
);
4122 GtkWidget
*widget
= mw
->mwindow
;
4124 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
4125 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
4126 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
4127 LttvPluginTab
*ptab
;
4131 ptab
= create_new_tab(widget
, NULL
);
4134 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
4138 for(iter
=traces
; iter
!=NULL
; iter
=g_slist_next(iter
)) {
4139 gchar
*path
= (gchar
*)iter
->data
;
4141 gchar abs_path
[PATH_MAX
];
4145 get_absolute_pathname(path
, abs_path
);
4146 trace_v
= lttvwindowtraces_get_trace_by_name(abs_path
);
4147 if(trace_v
== NULL
) {
4149 trace
= ltt_trace_open_live(abs_path
);
4151 trace
= ltt_trace_open(abs_path
);
4154 g_warning("cannot open trace %s", abs_path
);
4156 GtkWidget
*dialogue
=
4157 gtk_message_dialog_new(
4158 GTK_WINDOW(gtk_widget_get_toplevel(widget
)),
4159 GTK_DIALOG_MODAL
|GTK_DIALOG_DESTROY_WITH_PARENT
,
4162 "Cannot open trace : maybe you should enter in the directory "
4164 gtk_dialog_run(GTK_DIALOG(dialogue
));
4165 gtk_widget_destroy(dialogue
);
4167 trace_v
= lttv_trace_new(trace
);
4168 lttvwindowtraces_add_trace(trace_v
);
4169 lttvwindow_add_trace(tab
, trace_v
);
4172 lttvwindow_add_trace(tab
, trace_v
);
4176 LttvTraceset
*traceset
;
4178 traceset
= tab
->traceset_info
->traceset
;
4179 SetTraceset(tab
, traceset
);