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 static void insert_viewer(GtkWidget
* widget
, lttvwindow_viewer_constructor constructor
);
80 LttvPluginTab
*create_new_tab(GtkWidget
* widget
, gpointer user_data
);
82 static gboolean
lttvwindow_process_pending_requests(Tab
*tab
);
84 static void on_timebar_starttime_changed(Timebar
*timebar
,
86 static void on_timebar_endtime_changed(Timebar
*timebar
,
88 static void on_timebar_currenttime_changed(Timebar
*timebar
,
105 static void on_top_notify(GObject
*gobject
,
109 Tab
*tab
= (Tab
*)user_data
;
110 g_message("in on_top_notify.\n");
114 static gboolean
viewer_grab_focus(GtkWidget
*widget
, GdkEventButton
*event
,
117 GtkWidget
*viewer
= GTK_WIDGET(data
);
118 GtkWidget
*viewer_container
= gtk_widget_get_parent(viewer
);
120 g_debug("FOCUS GRABBED");
121 g_object_set_data(G_OBJECT(viewer_container
), "focused_viewer", viewer
);
126 static void connect_focus_recursive(GtkWidget
*widget
,
129 if(GTK_IS_CONTAINER(widget
)) {
130 gtk_container_forall(GTK_CONTAINER(widget
),
131 (GtkCallback
)connect_focus_recursive
,
135 if(GTK_IS_TREE_VIEW(widget
)) {
136 gtk_tree_view_set_headers_clickable(GTK_TREE_VIEW(widget
), TRUE
);
138 gtk_widget_add_events(widget
, GDK_BUTTON_PRESS_MASK
);
139 g_signal_connect (G_OBJECT(widget
),
140 "button-press-event",
141 G_CALLBACK (viewer_grab_focus
),
145 /* Stop all the processings and call gtk_main_quit() */
146 static void mainwindow_quit()
148 lttvwindowtraces_unregister_requests(g_quark_from_string("stats"));
149 lttvwindowtraces_unregister_requests(g_quark_from_string("state"));
150 lttvwindowtraces_unregister_computation_hooks(g_quark_from_string("stats"));
151 lttvwindowtraces_unregister_computation_hooks(g_quark_from_string("state"));
157 /* insert_viewer function constructs an instance of a viewer first,
158 * then inserts the widget of the instance into the container of the
163 insert_viewer_wrap(GtkWidget
*menuitem
, gpointer user_data
)
165 insert_viewer((GtkWidget
*)menuitem
, (lttvwindow_viewer_constructor
)user_data
);
169 /* internal functions */
170 void insert_viewer(GtkWidget
* widget
, lttvwindow_viewer_constructor constructor
)
172 GtkWidget
* viewer_container
;
173 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
175 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
176 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
181 ptab
= create_new_tab(widget
, NULL
);
183 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
187 viewer_container
= tab
->viewer_container
;
189 viewer
= (GtkWidget
*)constructor(&ptab
->parent
);
192 //gtk_multivpaned_widget_add(GTK_MULTIVPANED(multivpaned), viewer);
194 gtk_box_pack_end(GTK_BOX(viewer_container
),
200 /* We want to connect the viewer_grab_focus to EVERY
201 * child of this widget. The little trick is to get each child
202 * of each GTK_CONTAINER, even subchildren.
204 connect_focus_recursive(viewer
, viewer
);
209 * Function to set/update traceset for the viewers
210 * @param tab viewer's tab
211 * @param traceset traceset of the main window.
213 * 0 : traceset updated
214 * 1 : no traceset hooks to update; not an error.
217 int SetTraceset(Tab
* tab
, LttvTraceset
*traceset
)
220 TimeInterval time_span
;
221 TimeWindow new_time_window
;
222 LttTime new_current_time
;
223 LttvTracesetContext
*tsc
=
224 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
226 // Perform time synchronization on the traces
227 if (syncTraceset(tsc
))
229 /* There is some time-dependant information that was calculated during
230 * context initialization. Destroy the old contexts and initialize new
232 * Modified from lttvwindow_add_trace()
234 // Keep a reference to the traces so they are not freed
235 for(i
= 0; i
< lttv_traceset_number(traceset
); i
++)
237 LttvTrace
*trace
= lttv_traceset_get(traceset
, i
);
238 lttv_trace_ref(trace
);
241 // Remove state update hooks
242 lttv_state_remove_event_hooks(
243 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
245 lttv_context_fini(LTTV_TRACESET_CONTEXT(
246 tab
->traceset_info
->traceset_context
));
247 g_object_unref(tab
->traceset_info
->traceset_context
);
249 for(i
= 0; i
< lttv_traceset_number(traceset
); i
++)
251 LttvTrace
*trace
= lttv_traceset_get(traceset
, i
);
252 lttvwindowtraces_remove_trace(trace
);
253 lttvwindowtraces_add_trace(trace
);
256 // Create new context
257 tab
->traceset_info
->traceset_context
=
258 g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
259 lttv_context_init(LTTV_TRACESET_CONTEXT(tab
->traceset_info
->
260 traceset_context
), traceset
);
262 // Add state update hooks
263 lttv_state_add_event_hooks(
264 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
266 // Remove local reference to the traces
267 for(i
=0; i
<lttv_traceset_number(traceset
); i
++)
269 LttvTrace
*trace
= lttv_traceset_get(traceset
, i
);
270 lttv_trace_unref(trace
);
273 tsc
= LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
276 time_span
= tsc
->time_span
;
277 new_time_window
= tab
->time_window
;
278 new_current_time
= tab
->current_time
;
280 /* Set the tab's time window and current time if
282 if(ltt_time_compare(tab
->time_window
.start_time
, time_span
.start_time
) < 0
283 || ltt_time_compare(tab
->time_window
.end_time
,
284 time_span
.end_time
) > 0) {
285 new_time_window
.start_time
= time_span
.start_time
;
287 new_current_time
= time_span
.start_time
;
291 if(ltt_time_compare(lttvwindow_default_time_width
,
292 ltt_time_sub(time_span
.end_time
, time_span
.start_time
)) < 0
294 ltt_time_compare(time_span
.end_time
, time_span
.start_time
) == 0)
295 tmp_time
= lttvwindow_default_time_width
;
297 tmp_time
= time_span
.end_time
;
299 new_time_window
.time_width
= tmp_time
;
300 new_time_window
.time_width_double
= ltt_time_to_double(tmp_time
);
301 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
302 new_time_window
.time_width
) ;
305 /* Finally, call the update hooks of the viewers */
306 gint retval
= update_traceset(tab
,traceset
);
308 time_change_manager(tab
, new_time_window
);
309 current_time_change_manager(tab
, new_current_time
);
315 * Function to set/update filter for the viewers
316 * @param tab viewer's tab
317 * @param filter filter of the main window.
320 * 0 : filters updated
321 * 1 : no filter hooks to update; not an error.
324 int SetFilter(Tab
* tab
, gpointer filter
)
327 LttvAttributeValue value
;
329 g_assert(lttv_iattribute_find_by_path(tab
->attributes
,
330 "hooks/updatefilter", LTTV_POINTER
, &value
));
332 tmp
= (LttvHooks
*)*(value
.v_pointer
);
334 if(tmp
== NULL
) return 1;
335 lttv_hooks_call(tmp
,filter
);
343 * Function to redraw each viewer belonging to the current tab
344 * @param tab viewer's tab
347 int update_traceset(Tab
*tab
, LttvTraceset
*traceset
)
349 LttvAttributeValue value
;
353 retval
= lttv_iattribute_find_by_path(tab
->attributes
,
354 "hooks/updatetraceset",
358 tmp
= (LttvHooks
*)*(value
.v_pointer
);
362 lttv_hooks_call(tmp
, traceset
);
368 Call hooks register to get update on traceset time span changes
370 int notify_time_span_changed(Tab
*tab
)
372 LttvAttributeValue value
;
376 retval
= lttv_iattribute_find_by_path(tab
->attributes
,
377 "hooks/updatetimespan",
381 tmp
= (LttvHooks
*)*(value
.v_pointer
);
385 lttv_hooks_call(tmp
, NULL
);
390 /* get_label function is used to get user input, it displays an input
391 * box, which allows user to input a string
394 void get_label_string (GtkWidget
* text
, gchar
* label
)
396 GtkEntry
* entry
= (GtkEntry
*)text
;
397 if(strlen(gtk_entry_get_text(entry
))!=0)
398 strcpy(label
,gtk_entry_get_text(entry
));
401 gboolean
get_label(MainWindow
* mw
, gchar
* str
, gchar
* dialogue_title
, gchar
* label_str
)
403 GtkWidget
* dialogue
;
408 dialogue
= gtk_dialog_new_with_buttons(dialogue_title
,NULL
,
410 GTK_STOCK_OK
,GTK_RESPONSE_ACCEPT
,
411 GTK_STOCK_CANCEL
,GTK_RESPONSE_REJECT
,
414 label
= gtk_label_new(label_str
);
415 gtk_widget_show(label
);
417 text
= gtk_entry_new();
418 gtk_widget_show(text
);
420 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialogue
)->vbox
), label
,TRUE
, TRUE
,0);
421 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialogue
)->vbox
), text
,FALSE
, FALSE
,0);
423 id
= gtk_dialog_run(GTK_DIALOG(dialogue
));
425 case GTK_RESPONSE_ACCEPT
:
426 get_label_string(text
,str
);
427 gtk_widget_destroy(dialogue
);
429 case GTK_RESPONSE_REJECT
:
431 gtk_widget_destroy(dialogue
);
438 /* get_window_data_struct function is actually a lookup function,
439 * given a widget which is in the tree of the main window, it will
440 * return the MainWindow data structure associated with main window
443 MainWindow
* get_window_data_struct(GtkWidget
* widget
)
446 MainWindow
* mw_data
;
448 mw
= lookup_widget(widget
, "MWindow");
450 g_info("Main window does not exist\n");
454 mw_data
= (MainWindow
*) g_object_get_data(G_OBJECT(mw
),"main_window_data");
456 g_warning("Main window data does not exist\n");
463 /* create_new_window function, just constructs a new main window
466 void create_new_window(GtkWidget
* widget
, gpointer user_data
, gboolean clone
)
468 MainWindow
* parent
= get_window_data_struct(widget
);
471 g_info("Clone : use the same traceset\n");
472 construct_main_window(parent
);
474 g_info("Empty : traceset is set to NULL\n");
475 construct_main_window(NULL
);
479 /* Get the currently focused viewer.
480 * If no viewer is focused, use the first one.
482 * If no viewer available, return NULL.
484 GtkWidget
*viewer_container_focus(GtkWidget
*container
)
488 widget
= (GtkWidget
*)g_object_get_data(G_OBJECT(container
),
492 g_debug("no widget focused");
493 GList
*children
= gtk_container_get_children(GTK_CONTAINER(container
));
496 widget
= GTK_WIDGET(children
->data
);
497 g_object_set_data(G_OBJECT(container
),
507 gint
viewer_container_position(GtkWidget
*container
, GtkWidget
*child
)
510 if(child
== NULL
) return -1;
514 memset(&value
, 0, sizeof(GValue
));
515 g_value_init(&value
, G_TYPE_INT
);
516 gtk_container_child_get_property(GTK_CONTAINER(container
),
520 pos
= g_value_get_int(&value
);
526 /* move_*_viewer functions move the selected view up/down in
530 void move_down_viewer(GtkWidget
* widget
, gpointer user_data
)
532 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
534 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
535 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
542 ptab
= g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
546 //gtk_multivpaned_widget_move_up(GTK_MULTIVPANED(tab->multivpaned));
548 /* change the position in the vbox */
549 GtkWidget
*focus_widget
;
551 focus_widget
= viewer_container_focus(tab
->viewer_container
);
552 position
= viewer_container_position(tab
->viewer_container
, focus_widget
);
555 /* can move up one position */
556 gtk_box_reorder_child(GTK_BOX(tab
->viewer_container
),
563 void move_up_viewer(GtkWidget
* widget
, gpointer user_data
)
565 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
567 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
568 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
575 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
579 //gtk_multivpaned_widget_move_down(GTK_MULTIVPANED(tab->multivpaned));
580 /* change the position in the vbox */
581 GtkWidget
*focus_widget
;
583 focus_widget
= viewer_container_focus(tab
->viewer_container
);
584 position
= viewer_container_position(tab
->viewer_container
, focus_widget
);
588 g_list_length(gtk_container_get_children(
589 GTK_CONTAINER(tab
->viewer_container
)))-1
591 /* can move down one position */
592 gtk_box_reorder_child(GTK_BOX(tab
->viewer_container
),
600 /* delete_viewer deletes the selected viewer in the current tab
603 void delete_viewer(GtkWidget
* widget
, gpointer user_data
)
605 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
607 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
608 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
615 ptab
= g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
619 //gtk_multivpaned_widget_delete(GTK_MULTIVPANED(tab->multivpaned));
621 GtkWidget
*focus_widget
= viewer_container_focus(tab
->viewer_container
);
623 if(focus_widget
!= NULL
)
624 gtk_widget_destroy(focus_widget
);
626 g_object_set_data(G_OBJECT(tab
->viewer_container
), "focused_viewer", NULL
);
630 /* open_traceset will open a traceset saved in a file
631 * Right now, it is not finished yet, (not working)
635 void open_traceset(GtkWidget
* widget
, gpointer user_data
)
639 LttvTraceset
* traceset
;
640 MainWindow
* mw_data
= get_window_data_struct(widget
);
641 GtkFileSelection
* file_selector
=
642 (GtkFileSelection
*)gtk_file_selection_new("Select a traceset");
644 gtk_file_selection_hide_fileop_buttons(file_selector
);
646 gtk_window_set_transient_for(GTK_WINDOW(file_selector
),
647 GTK_WINDOW(mw_data
->mwindow
));
649 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
651 case GTK_RESPONSE_ACCEPT
:
652 case GTK_RESPONSE_OK
:
653 dir
= gtk_file_selection_get_selections (file_selector
);
654 traceset
= lttv_traceset_load(dir
[0]);
655 g_info("Open a trace set %s\n", dir
[0]);
658 case GTK_RESPONSE_REJECT
:
659 case GTK_RESPONSE_CANCEL
:
661 gtk_widget_destroy((GtkWidget
*)file_selector
);
667 /* lttvwindow_process_pending_requests
669 * Process requests for parts of the trace from viewers.
671 * These requests are made by lttvwindow_events_request().
673 * This internal function gets called by g_idle, taking care of the pending
674 * requests. It is responsible for concatenation of time intervals and position
675 * requests. It does it with the following algorithm organizing process traceset
676 * calls. Here is the detailed description of the way it works :
678 * - Events Requests Servicing Algorithm
680 * Data structures necessary :
682 * List of requests added to context : list_in
683 * List of requests not added to context : list_out
688 * list_out : many events requests
690 * FIXME : insert rest of algorithm here
694 #define list_out tab->events_requests
696 gboolean
lttvwindow_process_pending_requests(Tab
*tab
)
698 LttvTracesetContext
*tsc
;
699 LttvTracefileContext
*tfc
;
700 GSList
*list_in
= NULL
;
704 LttvTracesetContextPosition
*end_position
;
706 if(lttvwindow_preempt_count
> 0) return TRUE
;
709 g_critical("Foreground processing : tab does not exist. Processing removed.");
713 /* There is no events requests pending : we should never have been called! */
714 g_assert(g_slist_length(list_out
) != 0);
716 tsc
= LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
718 //set the cursor to be X shape, indicating that the computer is busy in doing its job
720 new = gdk_cursor_new(GDK_X_CURSOR
);
721 widget
= lookup_widget(tab
->mw
->mwindow
, "MToolbar1");
722 win
= gtk_widget_get_parent_window(widget
);
723 gdk_window_set_cursor(win
, new);
724 gdk_cursor_unref(new);
725 gdk_window_stick(win
);
726 gdk_window_unstick(win
);
729 g_debug("SIZE events req len : %d", g_slist_length(list_out
));
731 /* Preliminary check for no trace in traceset */
732 /* Unregister the routine if empty, empty list_out too */
733 if(lttv_traceset_number(tsc
->ts
) == 0) {
735 /* - For each req in list_out */
736 GSList
*iter
= list_out
;
738 while(iter
!= NULL
) {
740 gboolean remove
= FALSE
;
741 gboolean free_data
= FALSE
;
742 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
744 /* - Call end request for req */
745 if(events_request
->servicing
== TRUE
)
746 lttv_hooks_call(events_request
->after_request
, (gpointer
)tsc
);
748 /* - remove req from list_out */
749 /* Destroy the request */
756 GSList
*remove_iter
= iter
;
758 iter
= g_slist_next(iter
);
759 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
760 list_out
= g_slist_remove_link(list_out
, remove_iter
);
761 } else { // not remove
762 iter
= g_slist_next(iter
);
767 /* 0.1 Lock Traces */
772 iter_trace
<lttv_traceset_number(tsc
->ts
);
774 LttvTrace
*trace_v
= lttv_traceset_get(tsc
->ts
, iter_trace
);
776 if(lttvwindowtraces_lock(trace_v
) != 0) {
777 g_critical("Foreground processing : Unable to get trace lock");
778 return TRUE
; /* Cannot get lock, try later */
783 /* 0.2 Seek tracefiles positions to context position */
784 //g_assert(lttv_process_traceset_seek_position(tsc, sync_position) == 0);
785 lttv_process_traceset_synchronize_tracefiles(tsc
);
788 /* Events processing algorithm implementation */
789 /* Warning : the gtk_events_pending takes a LOT of cpu time. So what we do
790 * instead is to leave the control to GTK and take it back.
792 /* A. Servicing loop */
793 //while( (g_slist_length(list_in) != 0 || g_slist_length(list_out) != 0)) {
794 if((g_slist_length(list_in
) != 0 || g_slist_length(list_out
) != 0)) {
796 /* 1. If list_in is empty (need a seek) */
797 if( g_slist_length(list_in
) == 0 ) {
799 /* list in is empty, need a seek */
801 /* 1.1 Add requests to list_in */
802 GSList
*ltime
= NULL
;
806 /* 1.1.1 Find all time requests with the lowest start time in list_out
809 if(g_slist_length(list_out
) > 0)
810 ltime
= g_slist_append(ltime
, g_slist_nth_data(list_out
, 0));
811 for(iter
=g_slist_nth(list_out
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
812 /* Find all time requests with the lowest start time in list_out */
813 EventsRequest
*event_request_ltime
= (EventsRequest
*)g_slist_nth_data(ltime
, 0);
814 EventsRequest
*event_request_list_out
= (EventsRequest
*)iter
->data
;
817 comp
= ltt_time_compare(event_request_ltime
->start_time
,
818 event_request_list_out
->start_time
);
820 ltime
= g_slist_append(ltime
, event_request_list_out
);
822 /* Remove all elements from ltime, and add current */
824 ltime
= g_slist_delete_link(ltime
, g_slist_nth(ltime
, 0));
825 ltime
= g_slist_append(ltime
, event_request_list_out
);
829 /* 1.1.2 Find all position requests with the lowest position in list_out
832 if(g_slist_length(list_out
) > 0)
833 lpos
= g_slist_append(lpos
, g_slist_nth_data(list_out
, 0));
834 for(iter
=g_slist_nth(list_out
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
835 /* Find all position requests with the lowest position in list_out */
836 EventsRequest
*event_request_lpos
= (EventsRequest
*)g_slist_nth_data(lpos
, 0);
837 EventsRequest
*event_request_list_out
= (EventsRequest
*)iter
->data
;
840 if(event_request_lpos
->start_position
!= NULL
841 && event_request_list_out
->start_position
!= NULL
)
843 comp
= lttv_traceset_context_pos_pos_compare
844 (event_request_lpos
->start_position
,
845 event_request_list_out
->start_position
);
850 lpos
= g_slist_append(lpos
, event_request_list_out
);
852 /* Remove all elements from lpos, and add current */
854 lpos
= g_slist_delete_link(lpos
, g_slist_nth(lpos
, 0));
855 lpos
= g_slist_append(lpos
, event_request_list_out
);
860 EventsRequest
*event_request_lpos
= (EventsRequest
*)g_slist_nth_data(lpos
, 0);
861 EventsRequest
*event_request_ltime
= (EventsRequest
*)g_slist_nth_data(ltime
, 0);
862 LttTime lpos_start_time
;
864 if(event_request_lpos
!= NULL
865 && event_request_lpos
->start_position
!= NULL
) {
866 lpos_start_time
= lttv_traceset_context_position_get_time(
867 event_request_lpos
->start_position
);
870 /* 1.1.3 If lpos.start time < ltime */
871 if(event_request_lpos
!= NULL
872 && event_request_lpos
->start_position
!= NULL
873 && ltt_time_compare(lpos_start_time
,
874 event_request_ltime
->start_time
)<0) {
875 /* Add lpos to list_in, remove them from list_out */
876 for(iter
=lpos
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
878 EventsRequest
*event_request_lpos
=
879 (EventsRequest
*)iter
->data
;
881 list_in
= g_slist_append(list_in
, event_request_lpos
);
882 /* Remove from list_out */
883 list_out
= g_slist_remove(list_out
, event_request_lpos
);
886 /* 1.1.4 (lpos.start time >= ltime) */
887 /* Add ltime to list_in, remove them from list_out */
889 for(iter
=ltime
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
891 EventsRequest
*event_request_ltime
=
892 (EventsRequest
*)iter
->data
;
894 list_in
= g_slist_append(list_in
, event_request_ltime
);
895 /* Remove from list_out */
896 list_out
= g_slist_remove(list_out
, event_request_ltime
);
906 tfc
= lttv_traceset_context_get_current_tfc(tsc
);
907 g_assert(g_slist_length(list_in
)>0);
908 EventsRequest
*events_request
= g_slist_nth_data(list_in
, 0);
911 /* 1.2.1 If first request in list_in is a time request */
912 if(events_request
->start_position
== NULL
) {
913 /* - If first req in list_in start time != current time */
914 if(tfc
== NULL
|| ltt_time_compare(events_request
->start_time
,
915 tfc
->timestamp
) != 0)
916 /* - Seek to that time */
917 g_debug("SEEK TIME : %lu, %lu", events_request
->start_time
.tv_sec
,
918 events_request
->start_time
.tv_nsec
);
919 //lttv_process_traceset_seek_time(tsc, events_request->start_time);
920 lttv_state_traceset_seek_time_closest(LTTV_TRACESET_STATE(tsc
),
921 events_request
->start_time
);
923 /* Process the traceset with only state hooks */
925 lttv_process_traceset_middle(tsc
,
926 events_request
->start_time
,
929 g_assert(seek_count
< LTTV_STATE_SAVE_INTERVAL
);
935 LttvTracefileContext
*tfc
=
936 lttv_traceset_context_get_current_tfc(tsc
);
937 /* Else, the first request in list_in is a position request */
938 /* If first req in list_in pos != current pos */
939 g_assert(events_request
->start_position
!= NULL
);
940 g_debug("SEEK POS time : %lu, %lu",
941 lttv_traceset_context_position_get_time(
942 events_request
->start_position
).tv_sec
,
943 lttv_traceset_context_position_get_time(
944 events_request
->start_position
).tv_nsec
);
947 g_debug("SEEK POS context time : %lu, %lu",
948 tfc
->timestamp
.tv_sec
,
949 tfc
->timestamp
.tv_nsec
);
951 g_debug("SEEK POS context time : %lu, %lu",
952 ltt_time_infinite
.tv_sec
,
953 ltt_time_infinite
.tv_nsec
);
955 g_assert(events_request
->start_position
!= NULL
);
956 if(lttv_traceset_context_ctx_pos_compare(tsc
,
957 events_request
->start_position
) != 0) {
958 /* 1.2.2.1 Seek to that position */
959 g_debug("SEEK POSITION");
960 //lttv_process_traceset_seek_position(tsc, events_request->start_position);
961 pos_time
= lttv_traceset_context_position_get_time(
962 events_request
->start_position
);
964 lttv_state_traceset_seek_time_closest(LTTV_TRACESET_STATE(tsc
),
967 /* Process the traceset with only state hooks */
969 lttv_process_traceset_middle(tsc
,
972 events_request
->start_position
);
973 g_assert(lttv_traceset_context_ctx_pos_compare(tsc
,
974 events_request
->start_position
) == 0);
981 /* 1.3 Add hooks and call before request for all list_in members */
985 for(iter
=list_in
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
986 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
987 /* 1.3.1 If !servicing */
988 if(events_request
->servicing
== FALSE
) {
989 /* - begin request hooks called
992 lttv_hooks_call(events_request
->before_request
, (gpointer
)tsc
);
993 events_request
->servicing
= TRUE
;
995 /* 1.3.2 call before chunk
996 * 1.3.3 events hooks added
998 if(events_request
->trace
== -1)
999 lttv_process_traceset_begin(tsc
,
1000 events_request
->before_chunk_traceset
,
1001 events_request
->before_chunk_trace
,
1002 events_request
->before_chunk_tracefile
,
1003 events_request
->event
,
1004 events_request
->event_by_id_channel
);
1006 guint nb_trace
= lttv_traceset_number(tsc
->ts
);
1007 g_assert((guint
)events_request
->trace
< nb_trace
&&
1008 events_request
->trace
> -1);
1009 LttvTraceContext
*tc
= tsc
->traces
[events_request
->trace
];
1011 lttv_hooks_call(events_request
->before_chunk_traceset
, tsc
);
1013 lttv_trace_context_add_hooks(tc
,
1014 events_request
->before_chunk_trace
,
1015 events_request
->before_chunk_tracefile
,
1016 events_request
->event
,
1017 events_request
->event_by_id_channel
);
1022 /* 2. Else, list_in is not empty, we continue a read */
1025 /* 2.0 For each req of list_in */
1026 GSList
*iter
= list_in
;
1028 while(iter
!= NULL
) {
1030 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1032 /* - Call before chunk
1033 * - events hooks added
1035 if(events_request
->trace
== -1)
1036 lttv_process_traceset_begin(tsc
,
1037 events_request
->before_chunk_traceset
,
1038 events_request
->before_chunk_trace
,
1039 events_request
->before_chunk_tracefile
,
1040 events_request
->event
,
1041 events_request
->event_by_id_channel
);
1043 guint nb_trace
= lttv_traceset_number(tsc
->ts
);
1044 g_assert((guint
)events_request
->trace
< nb_trace
&&
1045 events_request
->trace
> -1);
1046 LttvTraceContext
*tc
= tsc
->traces
[events_request
->trace
];
1048 lttv_hooks_call(events_request
->before_chunk_traceset
, tsc
);
1050 lttv_trace_context_add_hooks(tc
,
1051 events_request
->before_chunk_trace
,
1052 events_request
->before_chunk_tracefile
,
1053 events_request
->event
,
1054 events_request
->event_by_id_channel
);
1057 iter
= g_slist_next(iter
);
1062 tfc
= lttv_traceset_context_get_current_tfc(tsc
);
1064 /* 2.1 For each req of list_out */
1065 GSList
*iter
= list_out
;
1067 while(iter
!= NULL
) {
1069 gboolean remove
= FALSE
;
1070 gboolean free_data
= FALSE
;
1071 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1073 /* if req.start time == current context time
1074 * or req.start position == current position*/
1075 if( ltt_time_compare(events_request
->start_time
,
1076 tfc
->timestamp
) == 0
1078 (events_request
->start_position
!= NULL
1080 lttv_traceset_context_ctx_pos_compare(tsc
,
1081 events_request
->start_position
) == 0)
1083 /* - Add to list_in, remove from list_out */
1084 list_in
= g_slist_append(list_in
, events_request
);
1088 /* - If !servicing */
1089 if(events_request
->servicing
== FALSE
) {
1090 /* - begin request hooks called
1091 * - servicing = TRUE
1093 lttv_hooks_call(events_request
->before_request
, (gpointer
)tsc
);
1094 events_request
->servicing
= TRUE
;
1096 /* call before chunk
1097 * events hooks added
1099 if(events_request
->trace
== -1)
1100 lttv_process_traceset_begin(tsc
,
1101 events_request
->before_chunk_traceset
,
1102 events_request
->before_chunk_trace
,
1103 events_request
->before_chunk_tracefile
,
1104 events_request
->event
,
1105 events_request
->event_by_id_channel
);
1107 guint nb_trace
= lttv_traceset_number(tsc
->ts
);
1108 g_assert((guint
)events_request
->trace
< nb_trace
&&
1109 events_request
->trace
> -1);
1110 LttvTraceContext
*tc
= tsc
->traces
[events_request
->trace
];
1112 lttv_hooks_call(events_request
->before_chunk_traceset
, tsc
);
1114 lttv_trace_context_add_hooks(tc
,
1115 events_request
->before_chunk_trace
,
1116 events_request
->before_chunk_tracefile
,
1117 events_request
->event
,
1118 events_request
->event_by_id_channel
);
1127 GSList
*remove_iter
= iter
;
1129 iter
= g_slist_next(iter
);
1130 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
1131 list_out
= g_slist_remove_link(list_out
, remove_iter
);
1132 } else { // not remove
1133 iter
= g_slist_next(iter
);
1139 /* 3. Find end criterions */
1144 /* 3.1.1 Find lowest end time in list_in */
1145 g_assert(g_slist_length(list_in
)>0);
1146 end_time
= ((EventsRequest
*)g_slist_nth_data(list_in
,0))->end_time
;
1148 for(iter
=g_slist_nth(list_in
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
1149 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1151 if(ltt_time_compare(events_request
->end_time
,
1153 end_time
= events_request
->end_time
;
1156 /* 3.1.2 Find lowest start time in list_out */
1157 for(iter
=list_out
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
1158 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1160 if(ltt_time_compare(events_request
->start_time
,
1162 end_time
= events_request
->start_time
;
1167 /* 3.2 Number of events */
1169 /* 3.2.1 Find lowest number of events in list_in */
1172 end_nb_events
= ((EventsRequest
*)g_slist_nth_data(list_in
,0))->num_events
;
1174 for(iter
=g_slist_nth(list_in
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
1175 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1177 if(events_request
->num_events
< end_nb_events
)
1178 end_nb_events
= events_request
->num_events
;
1181 /* 3.2.2 Use min(CHUNK_NUM_EVENTS, min num events in list_in) as
1184 end_nb_events
= MIN(CHUNK_NUM_EVENTS
, end_nb_events
);
1188 /* 3.3 End position */
1190 /* 3.3.1 Find lowest end position in list_in */
1193 end_position
=((EventsRequest
*)g_slist_nth_data(list_in
,0))->end_position
;
1195 for(iter
=g_slist_nth(list_in
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
1196 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1198 if(events_request
->end_position
!= NULL
&& end_position
!= NULL
&&
1199 lttv_traceset_context_pos_pos_compare(events_request
->end_position
,
1201 end_position
= events_request
->end_position
;
1206 /* 3.3.2 Find lowest start position in list_out */
1209 for(iter
=list_out
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
1210 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1212 if(events_request
->end_position
!= NULL
&& end_position
!= NULL
&&
1213 lttv_traceset_context_pos_pos_compare(events_request
->end_position
,
1215 end_position
= events_request
->end_position
;
1220 /* 4. Call process traceset middle */
1221 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
);
1222 count
= lttv_process_traceset_middle(tsc
, end_time
, end_nb_events
, end_position
);
1224 tfc
= lttv_traceset_context_get_current_tfc(tsc
);
1226 g_debug("Context time after middle : %lu, %lu", tfc
->timestamp
.tv_sec
,
1227 tfc
->timestamp
.tv_nsec
);
1229 g_debug("End of trace reached after middle.");
1233 /* 5. After process traceset middle */
1234 tfc
= lttv_traceset_context_get_current_tfc(tsc
);
1236 /* - if current context time > traceset.end time */
1237 if(tfc
== NULL
|| ltt_time_compare(tfc
->timestamp
,
1238 tsc
->time_span
.end_time
) > 0) {
1239 /* - For each req in list_in */
1240 GSList
*iter
= list_in
;
1242 while(iter
!= NULL
) {
1244 gboolean remove
= FALSE
;
1245 gboolean free_data
= FALSE
;
1246 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1248 /* - Remove events hooks for req
1249 * - Call end chunk for req
1252 if(events_request
->trace
== -1)
1253 lttv_process_traceset_end(tsc
,
1254 events_request
->after_chunk_traceset
,
1255 events_request
->after_chunk_trace
,
1256 events_request
->after_chunk_tracefile
,
1257 events_request
->event
,
1258 events_request
->event_by_id_channel
);
1261 guint nb_trace
= lttv_traceset_number(tsc
->ts
);
1262 g_assert(events_request
->trace
< nb_trace
&&
1263 events_request
->trace
> -1);
1264 LttvTraceContext
*tc
= tsc
->traces
[events_request
->trace
];
1266 lttv_trace_context_remove_hooks(tc
,
1267 events_request
->after_chunk_trace
,
1268 events_request
->after_chunk_tracefile
,
1269 events_request
->event
,
1270 events_request
->event_by_id_channel
);
1271 lttv_hooks_call(events_request
->after_chunk_traceset
, tsc
);
1276 /* - Call end request for req */
1277 lttv_hooks_call(events_request
->after_request
, (gpointer
)tsc
);
1279 /* - remove req from list_in */
1280 /* Destroy the request */
1287 GSList
*remove_iter
= iter
;
1289 iter
= g_slist_next(iter
);
1290 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
1291 list_in
= g_slist_remove_link(list_in
, remove_iter
);
1292 } else { // not remove
1293 iter
= g_slist_next(iter
);
1298 /* 5.1 For each req in list_in */
1299 GSList
*iter
= list_in
;
1301 while(iter
!= NULL
) {
1303 gboolean remove
= FALSE
;
1304 gboolean free_data
= FALSE
;
1305 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1307 /* - Remove events hooks for req
1308 * - Call end chunk for req
1310 if(events_request
->trace
== -1)
1311 lttv_process_traceset_end(tsc
,
1312 events_request
->after_chunk_traceset
,
1313 events_request
->after_chunk_trace
,
1314 events_request
->after_chunk_tracefile
,
1315 events_request
->event
,
1316 events_request
->event_by_id_channel
);
1319 guint nb_trace
= lttv_traceset_number(tsc
->ts
);
1320 g_assert(events_request
->trace
< nb_trace
&&
1321 events_request
->trace
> -1);
1322 LttvTraceContext
*tc
= tsc
->traces
[events_request
->trace
];
1324 lttv_trace_context_remove_hooks(tc
,
1325 events_request
->after_chunk_trace
,
1326 events_request
->after_chunk_tracefile
,
1327 events_request
->event
,
1328 events_request
->event_by_id_channel
);
1330 lttv_hooks_call(events_request
->after_chunk_traceset
, tsc
);
1333 /* - req.num -= count */
1334 g_assert(events_request
->num_events
>= count
);
1335 events_request
->num_events
-= count
;
1337 g_assert(tfc
!= NULL
);
1338 /* - if req.num == 0
1340 * current context time >= req.end time
1342 * req.end pos == current pos
1344 * req.stop_flag == TRUE
1346 if( events_request
->num_events
== 0
1348 events_request
->stop_flag
== TRUE
1350 ltt_time_compare(tfc
->timestamp
,
1351 events_request
->end_time
) >= 0
1353 (events_request
->end_position
!= NULL
1355 lttv_traceset_context_ctx_pos_compare(tsc
,
1356 events_request
->end_position
) == 0)
1359 g_assert(events_request
->servicing
== TRUE
);
1360 /* - Call end request for req
1361 * - remove req from list_in */
1362 lttv_hooks_call(events_request
->after_request
, (gpointer
)tsc
);
1363 /* - remove req from list_in */
1364 /* Destroy the request */
1372 GSList
*remove_iter
= iter
;
1374 iter
= g_slist_next(iter
);
1375 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
1376 list_in
= g_slist_remove_link(list_in
, remove_iter
);
1377 } else { // not remove
1378 iter
= g_slist_next(iter
);
1384 /* End of removed servicing loop : leave control to GTK instead. */
1385 // if(gtk_events_pending()) break;
1388 /* B. When interrupted between chunks */
1391 GSList
*iter
= list_in
;
1393 /* 1. for each request in list_in */
1394 while(iter
!= NULL
) {
1396 gboolean remove
= FALSE
;
1397 gboolean free_data
= FALSE
;
1398 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1400 /* 1.1. Use current postition as start position */
1401 if(events_request
->start_position
!= NULL
)
1402 lttv_traceset_context_position_destroy(events_request
->start_position
);
1403 events_request
->start_position
= lttv_traceset_context_position_new(tsc
);
1404 lttv_traceset_context_position_save(tsc
, events_request
->start_position
);
1406 /* 1.2. Remove start time */
1407 events_request
->start_time
= ltt_time_infinite
;
1409 /* 1.3. Move from list_in to list_out */
1412 list_out
= g_slist_append(list_out
, events_request
);
1417 GSList
*remove_iter
= iter
;
1419 iter
= g_slist_next(iter
);
1420 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
1421 list_in
= g_slist_remove_link(list_in
, remove_iter
);
1422 } else { // not remove
1423 iter
= g_slist_next(iter
);
1429 /* C Unlock Traces */
1431 lttv_process_traceset_get_sync_data(tsc
);
1432 //lttv_traceset_context_position_save(tsc, sync_position);
1437 iter_trace
<lttv_traceset_number(tsc
->ts
);
1439 LttvTrace
*trace_v
= lttv_traceset_get(tsc
->ts
, iter_trace
);
1441 lttvwindowtraces_unlock(trace_v
);
1445 //set the cursor back to normal
1446 gdk_window_set_cursor(win
, NULL
);
1449 g_assert(g_slist_length(list_in
) == 0);
1451 if( g_slist_length(list_out
) == 0 ) {
1452 /* Put tab's request pending flag back to normal */
1453 tab
->events_request_pending
= FALSE
;
1454 g_debug("remove the idle fct");
1455 return FALSE
; /* Remove the idle function */
1457 g_debug("leave the idle fct");
1458 return TRUE
; /* Leave the idle function */
1460 /* We do not use simili-round-robin, it may require to read 1 meg buffers
1461 * again and again if many tracesets use the same tracefiles. */
1462 /* Hack for round-robin idle functions */
1463 /* It will put the idle function at the end of the pool */
1464 /*g_idle_add_full((G_PRIORITY_HIGH_IDLE + 21),
1465 (GSourceFunc)execute_events_requests,
1474 Manage the periodic update of a live trace
1477 live_trace_update_handler(Tab
*tab
)
1479 unsigned int updated_count
;
1481 LttvTracesetContext
*tsc
= LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
1482 TimeInterval initial_time_span
= tsc
->time_span
;
1483 TimeInterval updated_time_span
;
1485 updated_count
= lttv_process_traceset_update(tsc
);
1487 /* TODO ybrosseau 2011-01-12: Add trace resynchronization */
1489 /* Get the changed period bounds */
1490 updated_time_span
= tsc
->time_span
;
1492 if(ltt_time_compare(updated_time_span
.start_time
,
1493 initial_time_span
.start_time
) != 0) {
1494 /* The initial time should not change on a live update */
1498 /* Notify viewers (only on updates) */
1499 if(ltt_time_compare(updated_time_span
.end_time
,
1500 initial_time_span
.end_time
) != 0) {
1502 notify_time_span_changed(tab
);
1503 /* TODO ybrosseau 2011-01-12: Change the timebar to register
1504 to the time_span hook */
1505 timebar_set_minmax_time(TIMEBAR(tab
->MTimebar
),
1506 &updated_time_span
.start_time
,
1507 &updated_time_span
.end_time
);
1509 /* To update the min max */
1510 time_change_manager(tab
, tab
->time_window
);
1513 /* Timer will be recalled as long as there is files to update */
1514 return (updated_count
> 0);
1517 static void lttvwindow_add_trace(Tab
*tab
, LttvTrace
*trace_v
)
1519 LttvTraceset
*traceset
= tab
->traceset_info
->traceset
;
1521 guint num_traces
= lttv_traceset_number(traceset
);
1523 //Verify if trace is already present.
1524 for(i
=0; i
<num_traces
; i
++)
1526 LttvTrace
* trace
= lttv_traceset_get(traceset
, i
);
1527 if(trace
== trace_v
)
1531 //Keep a reference to the traces so they are not freed.
1532 for(i
=0; i
<lttv_traceset_number(traceset
); i
++)
1534 LttvTrace
* trace
= lttv_traceset_get(traceset
, i
);
1535 lttv_trace_ref(trace
);
1538 //remove state update hooks
1539 lttv_state_remove_event_hooks(
1540 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1542 lttv_context_fini(LTTV_TRACESET_CONTEXT(
1543 tab
->traceset_info
->traceset_context
));
1544 g_object_unref(tab
->traceset_info
->traceset_context
);
1546 lttv_traceset_add(traceset
, trace_v
);
1547 lttv_trace_ref(trace_v
); /* local ref */
1549 /* Create new context */
1550 tab
->traceset_info
->traceset_context
=
1551 g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
1553 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->
1558 //add state update hooks
1559 lttv_state_add_event_hooks(
1560 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1561 //Remove local reference to the traces.
1562 for(i
=0; i
<lttv_traceset_number(traceset
); i
++)
1564 LttvTrace
* trace
= lttv_traceset_get(traceset
, i
);
1565 lttv_trace_unref(trace
);
1569 //add_trace_into_traceset_selector(GTK_MULTIVPANED(tab->multivpaned), lttv_trace(trace_v));
1572 if (lttv_trace(trace_v
)->is_live
) {
1573 /* Add timer for live update */
1574 /* TODO ybrosseau 2011-01-12: Parametrize the hardcoded 1 seconds */
1575 g_timeout_add_seconds (1,
1576 (GSourceFunc
) live_trace_update_handler
,
1582 /* add_trace adds a trace into the current traceset. It first displays a
1583 * directory selection dialogue to let user choose a trace, then recreates
1584 * tracset_context, and redraws all the viewer of the current tab
1587 void add_trace(GtkWidget
* widget
, gpointer user_data
)
1590 LttvTrace
* trace_v
;
1591 LttvTraceset
* traceset
;
1593 char abs_path
[PATH_MAX
];
1595 MainWindow
* mw_data
= get_window_data_struct(widget
);
1596 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
1598 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
1599 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
1600 LttvPluginTab
*ptab
;
1604 ptab
= create_new_tab(widget
, NULL
);
1607 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
1611 /* File open dialog management */
1612 GtkWidget
*extra_live_button
;
1613 GtkFileChooser
* file_chooser
=
1615 gtk_file_chooser_dialog_new ("Select a trace",
1616 GTK_WINDOW(mw_data
->mwindow
),
1617 GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER
,
1618 GTK_STOCK_CANCEL
, GTK_RESPONSE_CANCEL
,
1619 GTK_STOCK_OPEN
, GTK_RESPONSE_ACCEPT
,
1622 /* Button to indicate the opening of a live trace */
1623 extra_live_button
= gtk_check_button_new_with_mnemonic ("Trace is live (currently being writen)");
1624 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (extra_live_button
), FALSE
);
1625 gtk_file_chooser_set_extra_widget (GTK_FILE_CHOOSER (file_chooser
), extra_live_button
);
1627 gtk_file_chooser_set_show_hidden (file_chooser
, TRUE
);
1628 if(remember_trace_dir
[0] != '\0')
1629 gtk_file_chooser_set_filename(file_chooser
, remember_trace_dir
);
1631 id
= gtk_dialog_run(GTK_DIALOG(file_chooser
));
1634 case GTK_RESPONSE_ACCEPT
:
1635 case GTK_RESPONSE_OK
:
1636 dir
= gtk_file_chooser_get_filename (file_chooser
);
1638 strncpy(remember_trace_dir
, dir
, PATH_MAX
);
1639 strncat(remember_trace_dir
, "/", PATH_MAX
);
1640 if(!dir
|| strlen(dir
) == 0){
1643 get_absolute_pathname(dir
, abs_path
);
1644 trace_v
= lttvwindowtraces_get_trace_by_name(abs_path
);
1645 if(trace_v
== NULL
) {
1646 if(gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (extra_live_button
))) {
1647 trace
= ltt_trace_open_live(abs_path
);
1649 trace
= ltt_trace_open(abs_path
);
1653 g_warning("cannot open trace %s", abs_path
);
1655 GtkWidget
*dialogue
=
1656 gtk_message_dialog_new(
1657 GTK_WINDOW(gtk_widget_get_toplevel(widget
)),
1658 GTK_DIALOG_MODAL
|GTK_DIALOG_DESTROY_WITH_PARENT
,
1661 "Cannot open trace : maybe you should enter in the trace "
1662 "directory to select it ?");
1663 gtk_dialog_run(GTK_DIALOG(dialogue
));
1664 gtk_widget_destroy(dialogue
);
1667 trace_v
= lttv_trace_new(trace
);
1668 lttvwindowtraces_add_trace(trace_v
);
1669 lttvwindow_add_trace(tab
, trace_v
);
1672 lttvwindow_add_trace(tab
, trace_v
);
1676 //update current tab
1677 //update_traceset(mw_data);
1679 /* Call the updatetraceset hooks */
1681 traceset
= tab
->traceset_info
->traceset
;
1682 SetTraceset(tab
, traceset
);
1683 // in expose now call_pending_read_hooks(mw_data);
1685 //lttvwindow_report_current_time(mw_data,&(tab->current_time));
1687 case GTK_RESPONSE_REJECT
:
1688 case GTK_RESPONSE_CANCEL
:
1692 gtk_widget_destroy((GtkWidget
*)file_chooser
);
1696 /* remove_trace removes a trace from the current traceset if all viewers in
1697 * the current tab are not interested in the trace. It first displays a
1698 * dialogue, which shows all traces in the current traceset, to let user choose
1699 * a trace, then it checks if all viewers unselect the trace, if it is true,
1700 * it will remove the trace, recreate the traceset_contex,
1701 * and redraws all the viewer of the current tab. If there is on trace in the
1702 * current traceset, it will delete all viewers of the current tab
1704 * It destroys the filter tree. FIXME... we should request for an update
1708 void remove_trace(GtkWidget
*widget
, gpointer user_data
)
1711 LttvTrace
* trace_v
;
1712 LttvTraceset
* traceset
;
1713 gint i
, j
, nb_trace
, index
=-1;
1714 char ** name
, *remove_trace_name
;
1715 MainWindow
* mw_data
= get_window_data_struct(widget
);
1716 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
1718 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
1719 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
1725 LttvPluginTab
*ptab
;
1726 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
1730 nb_trace
=lttv_traceset_number(tab
->traceset_info
->traceset
);
1731 name
= g_new(char*,nb_trace
);
1732 for(i
= 0; i
< nb_trace
; i
++){
1733 trace_v
= lttv_traceset_get(tab
->traceset_info
->traceset
, i
);
1734 trace
= lttv_trace(trace_v
);
1735 name
[i
] = (char *) g_quark_to_string(ltt_trace_name(trace
));
1738 remove_trace_name
= get_remove_trace(mw_data
, name
, nb_trace
);
1741 if(remove_trace_name
){
1743 /* yuk, cut n paste from old code.. should be better (MD)*/
1744 for(i
= 0; i
<nb_trace
; i
++) {
1745 if(strcmp(remove_trace_name
,name
[i
]) == 0){
1750 traceset
= tab
->traceset_info
->traceset
;
1751 //Keep a reference to the traces so they are not freed.
1752 for(j
=0; j
<lttv_traceset_number(traceset
); j
++)
1754 LttvTrace
* trace
= lttv_traceset_get(traceset
, j
);
1755 lttv_trace_ref(trace
);
1758 //remove state update hooks
1759 lttv_state_remove_event_hooks(
1760 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1761 lttv_context_fini(LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
));
1762 g_object_unref(tab
->traceset_info
->traceset_context
);
1764 trace_v
= lttv_traceset_get(traceset
, index
);
1766 lttv_traceset_remove(traceset
, index
);
1767 lttv_trace_unref(trace_v
); // Remove local reference
1769 if(lttv_trace_get_ref_number(trace_v
) <= 1) {
1770 /* ref 1 : lttvwindowtraces only*/
1771 ltt_trace_close(lttv_trace(trace_v
));
1772 /* lttvwindowtraces_remove_trace takes care of destroying
1773 * the traceset linked with the trace_v and also of destroying
1774 * the trace_v at the same time.
1776 lttvwindowtraces_remove_trace(trace_v
);
1779 tab
->traceset_info
->traceset_context
=
1780 g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
1782 LTTV_TRACESET_CONTEXT(tab
->
1783 traceset_info
->traceset_context
),traceset
);
1784 //add state update hooks
1785 lttv_state_add_event_hooks(
1786 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1788 //Remove local reference to the traces.
1789 for(j
=0; j
<lttv_traceset_number(traceset
); j
++)
1791 LttvTrace
* trace
= lttv_traceset_get(traceset
, j
);
1792 lttv_trace_unref(trace
);
1795 SetTraceset(tab
, (gpointer
)traceset
);
1801 void remove_trace(GtkWidget
* widget
, gpointer user_data
)
1804 LttvTrace
* trace_v
;
1805 LttvTraceset
* traceset
;
1806 gint i
, j
, nb_trace
;
1807 char ** name
, *remove_trace_name
;
1808 MainWindow
* mw_data
= get_window_data_struct(widget
);
1809 LttvTracesetSelector
* s
;
1810 LttvTraceSelector
* t
;
1813 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
1815 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
1816 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
1822 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
1825 nb_trace
=lttv_traceset_number(tab
->traceset_info
->traceset
);
1826 name
= g_new(char*,nb_trace
);
1827 for(i
= 0; i
< nb_trace
; i
++){
1828 trace_v
= lttv_traceset_get(tab
->traceset_info
->traceset
, i
);
1829 trace
= lttv_trace(trace_v
);
1830 name
[i
] = ltt_trace_name(trace
);
1833 remove_trace_name
= get_remove_trace(name
, nb_trace
);
1835 if(remove_trace_name
){
1836 for(i
=0; i
<nb_trace
; i
++){
1837 if(strcmp(remove_trace_name
,name
[i
]) == 0){
1838 //unselect the trace from the current viewer
1840 w
= gtk_multivpaned_get_widget(GTK_MULTIVPANED(tab
->multivpaned
));
1842 s
= g_object_get_data(G_OBJECT(w
), "Traceset_Selector");
1844 t
= lttv_traceset_selector_trace_get(s
,i
);
1845 lttv_trace_selector_set_selected(t
, FALSE
);
1848 //check if other viewers select the trace
1849 w
= gtk_multivpaned_get_first_widget(GTK_MULTIVPANED(tab
->multivpaned
));
1851 s
= g_object_get_data(G_OBJECT(w
), "Traceset_Selector");
1853 t
= lttv_traceset_selector_trace_get(s
,i
);
1854 selected
= lttv_trace_selector_get_selected(t
);
1857 w
= gtk_multivpaned_get_next_widget(GTK_MULTIVPANED(tab
->multivpaned
));
1859 }else selected
= FALSE
;
1861 //if no viewer selects the trace, remove it
1863 remove_trace_from_traceset_selector(GTK_MULTIVPANED(tab
->multivpaned
), i
);
1865 traceset
= tab
->traceset_info
->traceset
;
1866 //Keep a reference to the traces so they are not freed.
1867 for(j
=0; j
<lttv_traceset_number(traceset
); j
++)
1869 LttvTrace
* trace
= lttv_traceset_get(traceset
, j
);
1870 lttv_trace_ref(trace
);
1873 //remove state update hooks
1874 lttv_state_remove_event_hooks(
1875 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1876 lttv_context_fini(LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
));
1877 g_object_unref(tab
->traceset_info
->traceset_context
);
1880 trace_v
= lttv_traceset_get(traceset
, i
);
1882 if(lttv_trace_get_ref_number(trace_v
) <= 2) {
1883 /* ref 2 : traceset, local */
1884 lttvwindowtraces_remove_trace(trace_v
);
1885 ltt_trace_close(lttv_trace(trace_v
));
1888 lttv_traceset_remove(traceset
, i
);
1889 lttv_trace_unref(trace_v
); // Remove local reference
1891 if(!lttv_trace_get_ref_number(trace_v
))
1892 lttv_trace_destroy(trace_v
);
1894 tab
->traceset_info
->traceset_context
=
1895 g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
1897 LTTV_TRACESET_CONTEXT(tab
->
1898 traceset_info
->traceset_context
),traceset
);
1899 //add state update hooks
1900 lttv_state_add_event_hooks(
1901 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1903 //Remove local reference to the traces.
1904 for(j
=0; j
<lttv_traceset_number(traceset
); j
++)
1906 LttvTrace
* trace
= lttv_traceset_get(traceset
, j
);
1907 lttv_trace_unref(trace
);
1911 //update current tab
1912 //update_traceset(mw_data);
1915 SetTraceset(tab
, (gpointer
)traceset
);
1916 // in expose now call_pending_read_hooks(mw_data);
1918 //lttvwindow_report_current_time(mw_data,&(tab->current_time));
1921 // while(tab->multi_vpaned->num_children){
1922 // gtk_multi_vpaned_widget_delete(tab->multi_vpaned);
1936 /* Redraw all the viewers in the current tab */
1937 void redraw(GtkWidget
*widget
, gpointer user_data
)
1939 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
1940 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
1941 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
1948 LttvPluginTab
*ptab
;
1949 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
1954 LttvAttributeValue value
;
1956 retval
= lttv_iattribute_find_by_path(tab
->attributes
, "hooks/redraw", LTTV_POINTER
, &value
);
1959 tmp
= (LttvHooks
*)*(value
.v_pointer
);
1961 lttv_hooks_call(tmp
,NULL
);
1965 void continue_processing(GtkWidget
*widget
, gpointer user_data
)
1967 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
1968 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
1969 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
1976 LttvPluginTab
*ptab
;
1977 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
1982 LttvAttributeValue value
;
1984 retval
= lttv_iattribute_find_by_path(tab
->attributes
, "hooks/continue",
1985 LTTV_POINTER
, &value
);
1988 tmp
= (LttvHooks
*)*(value
.v_pointer
);
1990 lttv_hooks_call(tmp
,NULL
);
1993 /* Stop the processing for the calling main window's current tab.
1994 * It removes every processing requests that are in its list. It does not call
1995 * the end request hooks, because the request is not finished.
1998 void stop_processing(GtkWidget
*widget
, gpointer user_data
)
2000 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
2001 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2002 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2007 LttvPluginTab
*ptab
;
2008 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
2011 GSList
*iter
= tab
->events_requests
;
2013 while(iter
!= NULL
) {
2014 GSList
*remove_iter
= iter
;
2015 iter
= g_slist_next(iter
);
2017 g_free(remove_iter
->data
);
2018 tab
->events_requests
=
2019 g_slist_remove_link(tab
->events_requests
, remove_iter
);
2021 tab
->events_request_pending
= FALSE
;
2022 tab
->stop_foreground
= TRUE
;
2023 g_idle_remove_by_data(tab
);
2024 g_assert(g_slist_length(tab
->events_requests
) == 0);
2028 /* save will save the traceset to a file
2029 * Not implemented yet FIXME
2032 void save(GtkWidget
* widget
, gpointer user_data
)
2037 void save_as(GtkWidget
* widget
, gpointer user_data
)
2039 g_info("Save as\n");
2043 /* zoom will change the time_window of all the viewers of the
2044 * current tab, and redisplay them. The main functionality is to
2045 * determine the new time_window of the current tab
2048 void zoom(GtkWidget
* widget
, double size
)
2050 TimeInterval time_span
;
2051 TimeWindow new_time_window
;
2052 LttTime current_time
, time_delta
;
2053 LttvTracesetContext
*tsc
;
2054 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
2056 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2057 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2063 LttvPluginTab
*ptab
;
2064 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
2068 if(size
== 1) return;
2070 tsc
= LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
2071 time_span
= tsc
->time_span
;
2072 new_time_window
= tab
->time_window
;
2073 current_time
= tab
->current_time
;
2075 time_delta
= ltt_time_sub(time_span
.end_time
,time_span
.start_time
);
2077 new_time_window
.start_time
= time_span
.start_time
;
2078 new_time_window
.time_width
= time_delta
;
2079 new_time_window
.time_width_double
= ltt_time_to_double(time_delta
);
2080 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
2081 new_time_window
.time_width
) ;
2083 new_time_window
.time_width
= ltt_time_div(new_time_window
.time_width
, size
);
2084 new_time_window
.time_width_double
=
2085 ltt_time_to_double(new_time_window
.time_width
);
2086 if(ltt_time_compare(new_time_window
.time_width
,time_delta
) > 0)
2087 { /* Case where zoom out is bigger than trace length */
2088 new_time_window
.start_time
= time_span
.start_time
;
2089 new_time_window
.time_width
= time_delta
;
2090 new_time_window
.time_width_double
= ltt_time_to_double(time_delta
);
2091 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
2092 new_time_window
.time_width
) ;
2096 /* Center the image on the current time */
2097 new_time_window
.start_time
=
2098 ltt_time_sub(current_time
,
2099 ltt_time_from_double(new_time_window
.time_width_double
/2.0));
2100 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
2101 new_time_window
.time_width
) ;
2102 /* If on borders, don't fall off */
2103 if(ltt_time_compare(new_time_window
.start_time
, time_span
.start_time
) <0
2104 || ltt_time_compare(new_time_window
.start_time
, time_span
.end_time
) >0)
2106 new_time_window
.start_time
= time_span
.start_time
;
2107 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
2108 new_time_window
.time_width
) ;
2112 if(ltt_time_compare(new_time_window
.end_time
,
2113 time_span
.end_time
) > 0
2114 || ltt_time_compare(new_time_window
.end_time
,
2115 time_span
.start_time
) < 0)
2117 new_time_window
.start_time
=
2118 ltt_time_sub(time_span
.end_time
, new_time_window
.time_width
);
2120 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
2121 new_time_window
.time_width
) ;
2128 if(ltt_time_compare(new_time_window
.time_width
, ltt_time_zero
) == 0) {
2129 g_warning("Zoom more than 1 ns impossible");
2131 time_change_manager(tab
, new_time_window
);
2135 void zoom_in(GtkWidget
* widget
, gpointer user_data
)
2140 void zoom_out(GtkWidget
* widget
, gpointer user_data
)
2145 void zoom_extended(GtkWidget
* widget
, gpointer user_data
)
2150 void go_to_time(GtkWidget
* widget
, gpointer user_data
)
2152 g_info("Go to time\n");
2155 void show_time_frame(GtkWidget
* widget
, gpointer user_data
)
2157 g_info("Show time frame\n");
2161 /* callback function */
2164 on_empty_traceset_activate (GtkMenuItem
*menuitem
,
2167 create_new_window((GtkWidget
*)menuitem
, user_data
, FALSE
);
2172 on_clone_traceset_activate (GtkMenuItem
*menuitem
,
2175 create_new_window((GtkWidget
*)menuitem
, user_data
, TRUE
);
2179 /* create_new_tab calls create_tab to construct a new tab in the main window
2182 LttvPluginTab
*create_new_tab(GtkWidget
* widget
, gpointer user_data
)
2184 gchar label
[PATH_MAX
];
2185 MainWindow
* mw_data
= get_window_data_struct(widget
);
2187 GtkNotebook
* notebook
= (GtkNotebook
*)lookup_widget(widget
, "MNotebook");
2188 if(notebook
== NULL
){
2189 g_info("Notebook does not exist\n");
2192 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2193 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2199 LttvPluginTab
*ptab
;
2200 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
2201 copy_tab
= ptab
->tab
;
2204 strcpy(label
,"Page");
2205 if(get_label(mw_data
, label
,"Get the name of the tab","Please input tab's name")) {
2206 LttvPluginTab
*ptab
;
2208 ptab
= g_object_new(LTTV_TYPE_PLUGIN_TAB
, NULL
);
2209 init_tab (ptab
->tab
, mw_data
, copy_tab
, notebook
, label
);
2210 ptab
->parent
.top_widget
= ptab
->tab
->top_widget
;
2211 g_object_set_data_full(
2212 G_OBJECT(ptab
->tab
->vbox
),
2215 (GDestroyNotify
)tab_destructor
);
2222 on_tab_activate (GtkMenuItem
*menuitem
,
2225 create_new_tab((GtkWidget
*)menuitem
, user_data
);
2230 on_open_activate (GtkMenuItem
*menuitem
,
2233 open_traceset((GtkWidget
*)menuitem
, user_data
);
2238 on_close_activate (GtkMenuItem
*menuitem
,
2241 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2242 main_window_destructor(mw_data
);
2246 /* remove the current tab from the main window
2250 on_close_tab_activate (GtkWidget
*widget
,
2254 GtkWidget
* notebook
;
2255 notebook
= lookup_widget(widget
, "MNotebook");
2256 if(notebook
== NULL
){
2257 g_info("Notebook does not exist\n");
2261 page_num
= gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
));
2263 gtk_notebook_remove_page(GTK_NOTEBOOK(notebook
), page_num
);
2268 on_close_tab_X_clicked (GtkWidget
*widget
,
2272 GtkWidget
*notebook
= lookup_widget(widget
, "MNotebook");
2273 if(notebook
== NULL
){
2274 g_info("Notebook does not exist\n");
2278 if((page_num
= gtk_notebook_page_num(GTK_NOTEBOOK(notebook
), widget
)) != -1)
2279 gtk_notebook_remove_page(GTK_NOTEBOOK(notebook
), page_num
);
2285 on_add_trace_activate (GtkMenuItem
*menuitem
,
2288 add_trace((GtkWidget
*)menuitem
, user_data
);
2293 on_remove_trace_activate (GtkMenuItem
*menuitem
,
2296 remove_trace((GtkWidget
*)menuitem
, user_data
);
2301 on_save_activate (GtkMenuItem
*menuitem
,
2304 save((GtkWidget
*)menuitem
, user_data
);
2309 on_save_as_activate (GtkMenuItem
*menuitem
,
2312 save_as((GtkWidget
*)menuitem
, user_data
);
2317 on_quit_activate (GtkMenuItem
*menuitem
,
2320 while (g_slist_length(g_main_window_list
) != 0) {
2321 on_MWindow_destroy(((MainWindow
*)g_main_window_list
->data
)->mwindow
,
2328 on_cut_activate (GtkMenuItem
*menuitem
,
2336 on_copy_activate (GtkMenuItem
*menuitem
,
2344 on_paste_activate (GtkMenuItem
*menuitem
,
2352 on_delete_activate (GtkMenuItem
*menuitem
,
2360 on_zoom_in_activate (GtkMenuItem
*menuitem
,
2363 zoom_in((GtkWidget
*)menuitem
, user_data
);
2368 on_zoom_out_activate (GtkMenuItem
*menuitem
,
2371 zoom_out((GtkWidget
*)menuitem
, user_data
);
2376 on_zoom_extended_activate (GtkMenuItem
*menuitem
,
2379 zoom_extended((GtkWidget
*)menuitem
, user_data
);
2384 on_go_to_time_activate (GtkMenuItem
*menuitem
,
2387 go_to_time((GtkWidget
*)menuitem
, user_data
);
2392 on_show_time_frame_activate (GtkMenuItem
*menuitem
,
2395 show_time_frame((GtkWidget
*)menuitem
, user_data
);
2400 on_move_viewer_up_activate (GtkMenuItem
*menuitem
,
2403 move_up_viewer((GtkWidget
*)menuitem
, user_data
);
2408 on_move_viewer_down_activate (GtkMenuItem
*menuitem
,
2411 move_down_viewer((GtkWidget
*)menuitem
, user_data
);
2416 on_remove_viewer_activate (GtkMenuItem
*menuitem
,
2419 delete_viewer((GtkWidget
*)menuitem
, user_data
);
2423 on_trace_facility_activate (GtkMenuItem
*menuitem
,
2426 g_info("Trace facility selector: %s\n", "");
2430 /* Dispaly a file selection dialogue to let user select a library, then call
2431 * lttv_library_load().
2435 on_load_library_activate (GtkMenuItem
*menuitem
,
2438 GError
*error
= NULL
;
2439 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2441 gchar load_module_path_alter
[PATH_MAX
];
2445 gchar
*load_module_path
;
2446 name
= g_ptr_array_new();
2447 nb
= lttv_library_path_number();
2448 /* ask for the library path */
2452 path
= lttv_library_path_get(i
);
2453 g_ptr_array_add(name
, path
);
2456 load_module_path
= get_selection(mw_data
,
2457 (char **)(name
->pdata
), name
->len
,
2458 "Select a library path", "Library paths");
2459 if(load_module_path
!= NULL
)
2460 strncpy(load_module_path_alter
, load_module_path
, PATH_MAX
-1); // -1 for /
2462 g_ptr_array_free(name
, TRUE
);
2464 if(load_module_path
== NULL
) return;
2468 /* Make sure the module path ends with a / */
2469 gchar
*ptr
= load_module_path_alter
;
2471 ptr
= strchr(ptr
, '\0');
2473 if(*(ptr
-1) != '/') {
2480 /* Ask for the library to load : list files in the previously selected
2482 gchar str
[PATH_MAX
];
2485 GtkFileSelection
* file_selector
=
2486 (GtkFileSelection
*)gtk_file_selection_new("Select a module");
2487 gtk_file_selection_set_filename(file_selector
, load_module_path_alter
);
2488 gtk_file_selection_hide_fileop_buttons(file_selector
);
2490 gtk_window_set_transient_for(GTK_WINDOW(file_selector
),
2491 GTK_WINDOW(mw_data
->mwindow
));
2494 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
2496 case GTK_RESPONSE_ACCEPT
:
2497 case GTK_RESPONSE_OK
:
2498 dir
= gtk_file_selection_get_selections (file_selector
);
2499 strncpy(str
,dir
[0],PATH_MAX
);
2500 strncpy(remember_plugins_dir
,dir
[0],PATH_MAX
);
2501 /* only keep file name */
2503 str1
= strrchr(str
,'/');
2506 str1
= strrchr(str
,'\\');
2511 if(*str1
== 'l' && *(str1
+1)== 'i' && *(str1
+2)=='b')
2513 remove info after
. */
2517 str2
= strrchr(str2
, '.');
2518 if(str2
!= NULL
) *str2
= '\0';
2520 lttv_module_require(str1
, &error
);
2522 lttv_library_load(str1
, &error
);
2523 if(error
!= NULL
) g_warning("%s", error
->message
);
2524 else g_info("Load library: %s\n", str
);
2526 case GTK_RESPONSE_REJECT
:
2527 case GTK_RESPONSE_CANCEL
:
2529 gtk_widget_destroy((GtkWidget
*)file_selector
);
2540 /* Display all loaded modules, let user to select a module to unload
2541 * by calling lttv_module_unload
2545 on_unload_library_activate (GtkMenuItem
*menuitem
,
2548 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2550 LttvLibrary
*library
= NULL
;
2555 name
= g_ptr_array_new();
2556 nb
= lttv_library_number();
2557 LttvLibraryInfo
*lib_info
= g_new(LttvLibraryInfo
,nb
);
2558 /* ask for the library name */
2561 LttvLibrary
*iter_lib
= lttv_library_get(i
);
2562 lttv_library_info(iter_lib
, &lib_info
[i
]);
2564 gchar
*path
= lib_info
[i
].name
;
2565 g_ptr_array_add(name
, path
);
2567 lib_name
= get_selection(mw_data
, (char **)(name
->pdata
), name
->len
,
2568 "Select a library", "Libraries");
2569 if(lib_name
!= NULL
) {
2571 if(strcmp(lib_name
, lib_info
[i
].name
) == 0) {
2572 library
= lttv_library_get(i
);
2577 g_ptr_array_free(name
, TRUE
);
2580 if(lib_name
== NULL
) return;
2582 if(library
!= NULL
) lttv_library_unload(library
);
2586 /* Dispaly a file selection dialogue to let user select a module, then call
2587 * lttv_module_require().
2591 on_load_module_activate (GtkMenuItem
*menuitem
,
2594 GError
*error
= NULL
;
2595 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2597 LttvLibrary
*library
= NULL
;
2602 name
= g_ptr_array_new();
2603 nb
= lttv_library_number();
2604 LttvLibraryInfo
*lib_info
= g_new(LttvLibraryInfo
,nb
);
2605 /* ask for the library name */
2608 LttvLibrary
*iter_lib
= lttv_library_get(i
);
2609 lttv_library_info(iter_lib
, &lib_info
[i
]);
2611 gchar
*path
= lib_info
[i
].name
;
2612 g_ptr_array_add(name
, path
);
2614 lib_name
= get_selection(mw_data
,(char **)(name
->pdata
), name
->len
,
2615 "Select a library", "Libraries");
2616 if(lib_name
!= NULL
) {
2618 if(strcmp(lib_name
, lib_info
[i
].name
) == 0) {
2619 library
= lttv_library_get(i
);
2624 g_ptr_array_free(name
, TRUE
);
2627 if(lib_name
== NULL
) return;
2630 //LttvModule *module;
2631 gchar module_name_out
[PATH_MAX
];
2633 /* Ask for the module to load : list modules in the selected lib */
2637 nb
= lttv_library_module_number(library
);
2638 LttvModuleInfo
*module_info
= g_new(LttvModuleInfo
,nb
);
2639 name
= g_ptr_array_new();
2640 /* ask for the module name */
2643 LttvModule
*iter_module
= lttv_library_module_get(library
, i
);
2644 lttv_module_info(iter_module
, &module_info
[i
]);
2646 gchar
*path
= module_info
[i
].name
;
2647 g_ptr_array_add(name
, path
);
2649 module_name
= get_selection(mw_data
, (char **)(name
->pdata
), name
->len
,
2650 "Select a module", "Modules");
2651 if(module_name
!= NULL
) {
2653 if(strcmp(module_name
, module_info
[i
].name
) == 0) {
2654 strncpy(module_name_out
, module_name
, PATH_MAX
);
2655 //module = lttv_library_module_get(i);
2661 g_ptr_array_free(name
, TRUE
);
2662 g_free(module_info
);
2664 if(module_name
== NULL
) return;
2667 lttv_module_require(module_name_out
, &error
);
2668 if(error
!= NULL
) g_warning("%s", error
->message
);
2669 else g_info("Load module: %s", module_name_out
);
2676 gchar str
[PATH_MAX
];
2679 GtkFileSelection
* file_selector
=
2680 (GtkFileSelection
*)gtk_file_selection_new("Select a module");
2681 gtk_file_selection_set_filename(file_selector
, load_module_path_alter
);
2682 gtk_file_selection_hide_fileop_buttons(file_selector
);
2685 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
2687 case GTK_RESPONSE_ACCEPT
:
2688 case GTK_RESPONSE_OK
:
2689 dir
= gtk_file_selection_get_selections (file_selector
);
2690 strncpy(str
,dir
[0],PATH_MAX
);
2691 strncpy(remember_plugins_dir
,dir
[0],PATH_MAX
);
2693 /* only keep file name */
2695 str1
= strrchr(str
,'/');
2698 str1
= strrchr(str
,'\\');
2703 if(*str1
== 'l' && *(str1
+1)== 'i' && *(str1
+2)=='b')
2705 remove info after
. */
2709 str2
= strrchr(str2
, '.');
2710 if(str2
!= NULL
) *str2
= '\0';
2712 lttv_module_require(str1
, &error
);
2714 lttv_library_load(str1
, &error
);
2715 if(error
!= NULL
) g_warning(error
->message
);
2716 else g_info("Load library: %s\n", str
);
2718 case GTK_RESPONSE_REJECT
:
2719 case GTK_RESPONSE_CANCEL
:
2721 gtk_widget_destroy((GtkWidget
*)file_selector
);
2733 /* Display all loaded modules, let user to select a module to unload
2734 * by calling lttv_module_unload
2738 on_unload_module_activate (GtkMenuItem
*menuitem
,
2741 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2743 LttvLibrary
*library
= NULL
;
2748 name
= g_ptr_array_new();
2749 nb
= lttv_library_number();
2750 LttvLibraryInfo
*lib_info
= g_new(LttvLibraryInfo
,nb
);
2751 /* ask for the library name */
2754 LttvLibrary
*iter_lib
= lttv_library_get(i
);
2755 lttv_library_info(iter_lib
, &lib_info
[i
]);
2757 gchar
*path
= lib_info
[i
].name
;
2758 g_ptr_array_add(name
, path
);
2760 lib_name
= get_selection(mw_data
, (char **)(name
->pdata
), name
->len
,
2761 "Select a library", "Libraries");
2762 if(lib_name
!= NULL
) {
2764 if(strcmp(lib_name
, lib_info
[i
].name
) == 0) {
2765 library
= lttv_library_get(i
);
2770 g_ptr_array_free(name
, TRUE
);
2773 if(lib_name
== NULL
) return;
2776 LttvModule
*module
= NULL
;
2778 /* Ask for the module to load : list modules in the selected lib */
2782 nb
= lttv_library_module_number(library
);
2783 LttvModuleInfo
*module_info
= g_new(LttvModuleInfo
,nb
);
2784 name
= g_ptr_array_new();
2785 /* ask for the module name */
2788 LttvModule
*iter_module
= lttv_library_module_get(library
, i
);
2789 lttv_module_info(iter_module
, &module_info
[i
]);
2791 gchar
*path
= module_info
[i
].name
;
2792 if(module_info
[i
].use_count
> 0) g_ptr_array_add(name
, path
);
2794 module_name
= get_selection(mw_data
, (char **)(name
->pdata
), name
->len
,
2795 "Select a module", "Modules");
2796 if(module_name
!= NULL
) {
2798 if(strcmp(module_name
, module_info
[i
].name
) == 0) {
2799 module
= lttv_library_module_get(library
, i
);
2805 g_ptr_array_free(name
, TRUE
);
2806 g_free(module_info
);
2808 if(module_name
== NULL
) return;
2811 LttvModuleInfo module_info
;
2812 lttv_module_info(module
, &module_info
);
2813 g_info("Release module: %s\n", module_info
.name
);
2815 lttv_module_release(module
);
2819 /* Display a directory dialogue to let user select a path for library searching
2823 on_add_library_search_path_activate (GtkMenuItem
*menuitem
,
2826 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2827 //GtkDirSelection * file_selector = (GtkDirSelection *)gtk_dir_selection_new("Select library path");
2828 GtkFileSelection
* file_selector
= (GtkFileSelection
*)gtk_file_selection_new("Select a trace");
2829 gtk_widget_hide( (file_selector
)->file_list
->parent
) ;
2831 gtk_window_set_transient_for(GTK_WINDOW(file_selector
),
2832 GTK_WINDOW(mw_data
->mwindow
));
2837 if(remember_plugins_dir
[0] != '\0')
2838 gtk_file_selection_set_filename(file_selector
, remember_plugins_dir
);
2840 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
2842 case GTK_RESPONSE_ACCEPT
:
2843 case GTK_RESPONSE_OK
:
2844 dir
= gtk_file_selection_get_filename (file_selector
);
2845 strncpy(remember_plugins_dir
,dir
,PATH_MAX
);
2846 strncat(remember_plugins_dir
,"/",PATH_MAX
);
2847 lttv_library_path_add(dir
);
2848 case GTK_RESPONSE_REJECT
:
2849 case GTK_RESPONSE_CANCEL
:
2851 gtk_widget_destroy((GtkWidget
*)file_selector
);
2857 /* Display a directory dialogue to let user select a path for library searching
2861 on_remove_library_search_path_activate (GtkMenuItem
*menuitem
,
2864 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2866 const char *lib_path
;
2870 name
= g_ptr_array_new();
2871 nb
= lttv_library_path_number();
2872 /* ask for the library name */
2875 gchar
*path
= lttv_library_path_get(i
);
2876 g_ptr_array_add(name
, path
);
2878 lib_path
= get_selection(mw_data
, (char **)(name
->pdata
), name
->len
,
2879 "Select a library path", "Library paths");
2881 g_ptr_array_free(name
, TRUE
);
2883 if(lib_path
== NULL
) return;
2886 lttv_library_path_remove(lib_path
);
2890 on_color_activate (GtkMenuItem
*menuitem
,
2898 on_save_configuration_activate (GtkMenuItem
*menuitem
,
2901 g_info("Save configuration\n");
2906 on_content_activate (GtkMenuItem
*menuitem
,
2909 g_info("Content\n");
2914 on_about_close_activate (GtkButton
*button
,
2917 GtkWidget
*about_widget
= GTK_WIDGET(user_data
);
2919 gtk_widget_destroy(about_widget
);
2923 on_about_activate (GtkMenuItem
*menuitem
,
2926 MainWindow
*main_window
= get_window_data_struct(GTK_WIDGET(menuitem
));
2927 GtkWidget
*window_widget
= main_window
->mwindow
;
2928 GtkWidget
*about_widget
= gtk_window_new(GTK_WINDOW_TOPLEVEL
);
2929 GtkWindow
*about_window
= GTK_WINDOW(about_widget
);
2930 gint window_width
, window_height
;
2932 gtk_window_set_title(about_window
, "About Linux Trace Toolkit");
2934 gtk_window_set_resizable(about_window
, FALSE
);
2935 gtk_window_set_transient_for(about_window
, GTK_WINDOW(window_widget
));
2936 gtk_window_set_destroy_with_parent(about_window
, TRUE
);
2937 gtk_window_set_modal(about_window
, FALSE
);
2939 /* Put the about window at the center of the screen */
2940 gtk_window_get_size(about_window
, &window_width
, &window_height
);
2941 gtk_window_move (about_window
,
2942 (gdk_screen_width() - window_width
)/2,
2943 (gdk_screen_height() - window_height
)/2);
2945 GtkWidget
*vbox
= gtk_vbox_new(FALSE
, 1);
2947 gtk_container_add(GTK_CONTAINER(about_widget
), vbox
);
2951 GtkWidget
*label1
= gtk_label_new("");
2952 gtk_misc_set_padding(GTK_MISC(label1
), 10, 20);
2953 gtk_label_set_markup(GTK_LABEL(label1
), "\
2954 <big>Linux Trace Toolkit " VERSION
"</big>");
2955 gtk_label_set_justify(GTK_LABEL(label1
), GTK_JUSTIFY_CENTER
);
2957 GtkWidget
*label2
= gtk_label_new("");
2958 gtk_misc_set_padding(GTK_MISC(label2
), 10, 20);
2959 gtk_label_set_markup(GTK_LABEL(label2
), "\
2962 Michel Dagenais (New trace format, lttv main)\n\
2963 Mathieu Desnoyers (Kernel Tracer, Directory structure, build with automake/conf,\n\
2964 lttv gui, control flow view, gui cooperative trace reading\n\
2965 scheduler with interruptible foreground and background\n\
2966 computation, detailed event list (rewrite), trace reading\n\
2967 library (rewrite))\n\
2968 Benoit Des Ligneris, Eric Clement (Cluster adaptation, work in progress)\n\
2969 Xang-Xiu Yang (new trace reading library and converter, lttv gui, \n\
2970 detailed event list and statistics view)\n\
2971 Tom Zanussi (RelayFS)\n\
2973 Inspired from the original Linux Trace Toolkit Visualizer made by\n\
2976 GtkWidget
*label3
= gtk_label_new("");
2977 gtk_label_set_markup(GTK_LABEL(label3
), "\
2978 Linux Trace Toolkit Viewer, Copyright (C) 2004, 2005, 2006\n\
2980 Mathieu Desnoyers\n\
2982 Linux Trace Toolkit comes with ABSOLUTELY NO WARRANTY.\n\
2983 This is free software, and you are welcome to redistribute it\n\
2984 under certain conditions. See COPYING for details.");
2985 gtk_misc_set_padding(GTK_MISC(label3
), 10, 20);
2987 gtk_box_pack_start_defaults(GTK_BOX(vbox
), label1
);
2988 gtk_box_pack_start_defaults(GTK_BOX(vbox
), label2
);
2989 gtk_box_pack_start_defaults(GTK_BOX(vbox
), label3
);
2991 GtkWidget
*hbox
= gtk_hbox_new(TRUE
, 0);
2992 gtk_box_pack_end(GTK_BOX(vbox
), hbox
, FALSE
, FALSE
, 0);
2993 GtkWidget
*close_button
= gtk_button_new_with_mnemonic("_Close");
2994 gtk_box_pack_end(GTK_BOX(hbox
), close_button
, FALSE
, FALSE
, 0);
2995 gtk_container_set_border_width(GTK_CONTAINER(close_button
), 20);
2997 g_signal_connect(G_OBJECT(close_button
), "clicked",
2998 G_CALLBACK(on_about_close_activate
),
2999 (gpointer
)about_widget
);
3001 gtk_widget_show_all(about_widget
);
3006 on_button_new_clicked (GtkButton
*button
,
3009 create_new_window((GtkWidget
*)button
, user_data
, TRUE
);
3013 on_button_new_tab_clicked (GtkButton
*button
,
3016 create_new_tab((GtkWidget
*)button
, user_data
);
3020 on_button_open_clicked (GtkButton
*button
,
3023 open_traceset((GtkWidget
*)button
, user_data
);
3028 on_button_add_trace_clicked (GtkButton
*button
,
3031 add_trace((GtkWidget
*)button
, user_data
);
3036 on_button_remove_trace_clicked (GtkButton
*button
,
3039 remove_trace((GtkWidget
*)button
, user_data
);
3043 on_button_redraw_clicked (GtkButton
*button
,
3046 redraw((GtkWidget
*)button
, user_data
);
3050 on_button_continue_processing_clicked (GtkButton
*button
,
3053 continue_processing((GtkWidget
*)button
, user_data
);
3057 on_button_stop_processing_clicked (GtkButton
*button
,
3060 stop_processing((GtkWidget
*)button
, user_data
);
3066 on_button_save_clicked (GtkButton
*button
,
3069 save((GtkWidget
*)button
, user_data
);
3074 on_button_save_as_clicked (GtkButton
*button
,
3077 save_as((GtkWidget
*)button
, user_data
);
3082 on_button_zoom_in_clicked (GtkButton
*button
,
3085 zoom_in((GtkWidget
*)button
, user_data
);
3090 on_button_zoom_out_clicked (GtkButton
*button
,
3093 zoom_out((GtkWidget
*)button
, user_data
);
3098 on_button_zoom_extended_clicked (GtkButton
*button
,
3101 zoom_extended((GtkWidget
*)button
, user_data
);
3106 on_button_go_to_time_clicked (GtkButton
*button
,
3109 go_to_time((GtkWidget
*)button
, user_data
);
3114 on_button_show_time_frame_clicked (GtkButton
*button
,
3117 show_time_frame((GtkWidget
*)button
, user_data
);
3122 on_button_move_up_clicked (GtkButton
*button
,
3125 move_up_viewer((GtkWidget
*)button
, user_data
);
3130 on_button_move_down_clicked (GtkButton
*button
,
3133 move_down_viewer((GtkWidget
*)button
, user_data
);
3138 on_button_delete_viewer_clicked (GtkButton
*button
,
3141 delete_viewer((GtkWidget
*)button
, user_data
);
3145 on_MWindow_destroy (GtkWidget
*widget
,
3148 MainWindow
*main_window
= get_window_data_struct(widget
);
3149 LttvIAttribute
*attributes
= main_window
->attributes
;
3150 LttvAttributeValue value
;
3153 //This is unnecessary, since widgets will be destroyed
3154 //by the main window widget anyway.
3155 //remove_all_menu_toolbar_constructors(main_window, NULL);
3157 retval
= lttv_iattribute_find_by_path(attributes
, "viewers/menu",
3158 LTTV_POINTER
, &value
);
3160 lttv_menus_destroy((LttvMenus
*)*(value
.v_pointer
));
3162 retval
= lttv_iattribute_find_by_path(attributes
, "viewers/toolbar",
3163 LTTV_POINTER
, &value
);
3165 lttv_toolbars_destroy((LttvToolbars
*)*(value
.v_pointer
));
3167 g_object_unref(main_window
->attributes
);
3168 g_main_window_list
= g_slist_remove(g_main_window_list
, main_window
);
3170 g_info("There are now : %d windows\n",g_slist_length(g_main_window_list
));
3171 if(g_slist_length(g_main_window_list
) == 0)
3176 on_MWindow_configure (GtkWidget
*widget
,
3177 GdkEventConfigure
*event
,
3180 // MD : removed time width modification upon resizing of the main window.
3181 // The viewers will redraw themselves completely, without time interval
3184 if(mw_data->window_width){
3185 time_span = LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context)->Time_Span ;
3186 time_win = tab->time_window;
3187 ratio = width / mw_data->window_width;
3188 tab->time_window.time_width = ltt_time_mul(time_win.time_width,ratio);
3189 time = ltt_time_sub(time_span->endTime, time_win.start_time);
3190 if(ltt_time_compare(time, tab->time_window.time_width) < 0){
3191 tab->time_window.time_width = time;
3197 mw_data->window_width = (int)width;
3206 on_MNotebook_switch_page (GtkNotebook
*notebook
,
3207 GtkNotebookPage
*page
,
3215 void time_change_manager (Tab
*tab
,
3216 TimeWindow new_time_window
)
3218 /* Only one source of time change */
3219 if(tab
->time_manager_lock
== TRUE
) return;
3221 tab
->time_manager_lock
= TRUE
;
3223 LttvTracesetContext
*tsc
= LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3224 TimeInterval time_span
= tsc
->time_span
;
3225 LttTime start_time
= new_time_window
.start_time
;
3226 LttTime end_time
= new_time_window
.end_time
;
3228 g_assert(ltt_time_compare(start_time
, end_time
) < 0);
3231 GtkAdjustment
*adjustment
= gtk_range_get_adjustment(GTK_RANGE(tab
->scrollbar
));
3232 LttTime upper
= ltt_time_sub(time_span
.end_time
, time_span
.start_time
);
3234 gtk_range_set_increments(GTK_RANGE(tab
->scrollbar
),
3235 ltt_time_to_double(new_time_window
.time_width
)
3236 / SCROLL_STEP_PER_PAGE
3237 * NANOSECONDS_PER_SECOND
, /* step increment */
3238 ltt_time_to_double(new_time_window
.time_width
)
3239 * NANOSECONDS_PER_SECOND
); /* page increment */
3240 gtk_range_set_range(GTK_RANGE(tab
->scrollbar
),
3242 ltt_time_to_double(upper
)
3243 * NANOSECONDS_PER_SECOND
); /* upper */
3245 g_object_set(G_OBJECT(adjustment
),
3249 ltt_time_to_double(upper
), /* upper */
3251 new_time_window
.time_width_double
3252 / SCROLL_STEP_PER_PAGE
, /* step increment */
3254 new_time_window
.time_width_double
,
3255 /* page increment */
3257 new_time_window
.time_width_double
, /* page size */
3259 gtk_adjustment_changed(adjustment
);
3261 // g_object_set(G_OBJECT(adjustment),
3263 // ltt_time_to_double(
3264 // ltt_time_sub(start_time, time_span.start_time))
3267 //gtk_adjustment_value_changed(adjustment);
3268 gtk_range_set_value(GTK_RANGE(tab
->scrollbar
),
3270 ltt_time_sub(start_time
, time_span
.start_time
)) /* value */);
3272 /* set the time bar. */
3275 timebar_set_minmax_time(TIMEBAR(tab
->MTimebar
),
3276 &time_span
.start_time
,
3277 &time_span
.end_time
);
3278 timebar_set_start_time(TIMEBAR(tab
->MTimebar
),&start_time
);
3279 timebar_set_end_time(TIMEBAR(tab
->MTimebar
),&end_time
);
3283 /* call viewer hooks for new time window */
3284 set_time_window(tab
, &new_time_window
);
3286 tab
->time_manager_lock
= FALSE
;
3293 void current_time_change_manager (Tab
*tab
,
3294 LttTime new_current_time
)
3296 /* Only one source of time change */
3297 if(tab
->current_time_manager_lock
== TRUE
) return;
3299 tab
->current_time_manager_lock
= TRUE
;
3301 timebar_set_current_time(TIMEBAR(tab
->MTimebar
), &new_current_time
);
3303 set_current_time(tab
, &new_current_time
);
3305 tab
->current_time_manager_lock
= FALSE
;
3308 void current_position_change_manager(Tab
*tab
,
3309 LttvTracesetContextPosition
*pos
)
3311 LttvTracesetContext
*tsc
=
3312 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3315 retval
= lttv_process_traceset_seek_position(tsc
, pos
);
3316 g_assert_cmpint(retval
, ==, 0);
3317 LttTime new_time
= lttv_traceset_context_position_get_time(pos
);
3318 /* Put the context in a state coherent position */
3319 lttv_state_traceset_seek_time_closest((LttvTracesetState
*)tsc
, ltt_time_zero
);
3321 current_time_change_manager(tab
, new_time
);
3323 set_current_position(tab
, pos
);
3326 static void on_timebar_starttime_changed(Timebar
*timebar
,
3329 Tab
*tab
= (Tab
*)user_data
;
3330 LttvTracesetContext
* tsc
=
3331 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3332 TimeInterval time_span
= tsc
->time_span
;
3334 TimeWindow new_time_window
= tab
->time_window
;
3335 new_time_window
.start_time
= timebar_get_start_time(timebar
);
3337 LttTime end_time
= new_time_window
.end_time
;
3339 /* TODO ybrosseau 2010-12-02: This if should have been checked
3340 by the timebar already */
3341 if(ltt_time_compare(new_time_window
.start_time
, end_time
) >= 0) {
3342 /* Then, we must push back end time : keep the same time width
3343 * if possible, else end traceset time */
3344 end_time
= LTT_TIME_MIN(ltt_time_add(new_time_window
.start_time
,
3345 new_time_window
.time_width
),
3346 time_span
.end_time
);
3349 /* Fix the time width to fit start time and end time */
3350 new_time_window
.time_width
= ltt_time_sub(end_time
,
3351 new_time_window
.start_time
);
3353 new_time_window
.time_width_double
=
3354 ltt_time_to_double(new_time_window
.time_width
);
3356 new_time_window
.end_time
= end_time
;
3358 /* Notify the time_manager */
3359 time_change_manager(tab
, new_time_window
);
3363 static void on_timebar_endtime_changed(Timebar
*timebar
,
3366 Tab
*tab
= (Tab
*)user_data
;
3367 LttvTracesetContext
* tsc
=
3368 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3369 TimeInterval time_span
= tsc
->time_span
;
3371 TimeWindow new_time_window
= tab
->time_window
;
3373 LttTime end_time
= timebar_get_end_time(timebar
);
3375 /* TODO ybrosseau 2010-12-02: This if should have been
3376 checked by the timebar already */
3377 if(ltt_time_compare(new_time_window
.start_time
, end_time
) >= 0) {
3378 /* Then, we must push front start time : keep the same time
3379 width if possible, else end traceset time */
3380 new_time_window
.start_time
= LTT_TIME_MAX(
3381 ltt_time_sub(end_time
,
3382 new_time_window
.time_width
),
3383 time_span
.start_time
);
3386 /* Fix the time width to fit start time and end time */
3387 new_time_window
.time_width
= ltt_time_sub(end_time
,
3388 new_time_window
.start_time
);
3390 new_time_window
.time_width_double
=
3391 ltt_time_to_double(new_time_window
.time_width
);
3393 new_time_window
.end_time
= end_time
;
3395 /* Notify the time_manager */
3396 time_change_manager(tab
, new_time_window
);
3398 static void on_timebar_currenttime_changed(Timebar
*timebar
,
3401 Tab
*tab
= (Tab
*)user_data
;
3403 LttTime new_current_time
= timebar_get_current_time(timebar
);
3405 current_time_change_manager(tab
, new_current_time
);
3408 void scroll_value_changed_cb(GtkWidget
*scrollbar
,
3411 Tab
*tab
= (Tab
*)user_data
;
3412 TimeWindow new_time_window
;
3414 GtkAdjustment
*adjust
= gtk_range_get_adjustment(GTK_RANGE(scrollbar
));
3415 gdouble value
= gtk_adjustment_get_value(adjust
);
3416 // gdouble upper, lower, ratio, page_size;
3418 LttvTracesetContext
* tsc
=
3419 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3420 TimeInterval time_span
= tsc
->time_span
;
3422 time
= ltt_time_add(ltt_time_from_double(value
),
3423 time_span
.start_time
);
3425 new_time_window
.start_time
= time
;
3427 page_size
= adjust
->page_size
;
3429 new_time_window
.time_width
=
3430 ltt_time_from_double(page_size
);
3432 new_time_window
.time_width_double
=
3435 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
3436 new_time_window
.time_width
);
3439 time_change_manager(tab
, new_time_window
);
3441 //time_window = tab->time_window;
3443 lower
= adjust
->lower
;
3444 upper
= adjust
->upper
;
3445 ratio
= (value
- lower
) / (upper
- lower
);
3446 g_info("lower %lu, upper %lu, value %lu, ratio %lu", lower
, upper
, value
, ratio
);
3448 //time = ltt_time_sub(time_span->end_time, time_span->start_time);
3449 //time = ltt_time_mul(time, (float)ratio);
3450 //time = ltt_time_add(time_span->start_time, time);
3451 time
= ltt_time_add(ltt_time_from_double(value
),
3452 time_span
.start_time
);
3454 time_window
.start_time
= time
;
3456 page_size
= adjust
->page_size
;
3458 time_window
.time_width
=
3459 ltt_time_from_double(page_size
);
3460 //time = ltt_time_sub(time_span.end_time, time);
3461 //if(ltt_time_compare(time,time_window.time_width) < 0){
3462 // time_window.time_width = time;
3465 /* call viewer hooks for new time window */
3466 set_time_window(tab
, &time_window
);
3471 /* Display a dialogue showing all eventtypes and traces, let user to select the interested
3472 * eventtypes, tracefiles and traces (filter)
3475 /* Select a trace which will be removed from traceset
3478 char * get_remove_trace(MainWindow
*mw_data
,
3479 char ** all_trace_name
, int nb_trace
)
3481 return get_selection(mw_data
, all_trace_name
, nb_trace
,
3482 "Select a trace", "Trace pathname");
3486 /* Select a module which will be loaded
3489 char * get_load_module(MainWindow
*mw_data
,
3490 char ** load_module_name
, int nb_module
)
3492 return get_selection(mw_data
, load_module_name
, nb_module
,
3493 "Select a module to load", "Module name");
3499 /* Select a module which will be unloaded
3502 char * get_unload_module(MainWindow
*mw_data
,
3503 char ** loaded_module_name
, int nb_module
)
3505 return get_selection(mw_data
, loaded_module_name
, nb_module
,
3506 "Select a module to unload", "Module name");
3510 /* Display a dialogue which shows all selectable items, let user to
3511 * select one of them
3514 char * get_selection(MainWindow
*mw_data
,
3515 char ** loaded_module_name
, int nb_module
,
3516 char *title
, char * column_title
)
3518 GtkWidget
* dialogue
;
3519 GtkWidget
* scroll_win
;
3521 GtkListStore
* store
;
3522 GtkTreeViewColumn
* column
;
3523 GtkCellRenderer
* renderer
;
3524 GtkTreeSelection
* select
;
3527 char * unload_module_name
= NULL
;
3529 dialogue
= gtk_dialog_new_with_buttons(title
,
3532 GTK_STOCK_OK
,GTK_RESPONSE_ACCEPT
,
3533 GTK_STOCK_CANCEL
,GTK_RESPONSE_REJECT
,
3535 gtk_window_set_default_size((GtkWindow
*)dialogue
, 500, 200);
3536 gtk_window_set_transient_for(GTK_WINDOW(dialogue
),
3537 GTK_WINDOW(mw_data
->mwindow
));
3539 scroll_win
= gtk_scrolled_window_new (NULL
, NULL
);
3540 gtk_widget_show ( scroll_win
);
3541 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll_win
),
3542 GTK_POLICY_AUTOMATIC
, GTK_POLICY_AUTOMATIC
);
3544 store
= gtk_list_store_new (N_COLUMNS
,G_TYPE_STRING
);
3545 tree
= gtk_tree_view_new_with_model(GTK_TREE_MODEL (store
));
3546 gtk_widget_show ( tree
);
3547 g_object_unref (G_OBJECT (store
));
3549 renderer
= gtk_cell_renderer_text_new ();
3550 column
= gtk_tree_view_column_new_with_attributes (column_title
,
3552 "text", MODULE_COLUMN
,
3554 gtk_tree_view_column_set_alignment (column
, 0.5);
3555 gtk_tree_view_column_set_fixed_width (column
, 150);
3556 gtk_tree_view_append_column (GTK_TREE_VIEW (tree
), column
);
3558 select
= gtk_tree_view_get_selection (GTK_TREE_VIEW (tree
));
3559 gtk_tree_selection_set_mode (select
, GTK_SELECTION_SINGLE
);
3561 gtk_container_add (GTK_CONTAINER (scroll_win
), tree
);
3563 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialogue
)->vbox
), scroll_win
,TRUE
, TRUE
,0);
3565 for(i
=0;i
<nb_module
;i
++){
3566 gtk_list_store_append (store
, &iter
);
3567 gtk_list_store_set (store
, &iter
, MODULE_COLUMN
,loaded_module_name
[i
],-1);
3570 id
= gtk_dialog_run(GTK_DIALOG(dialogue
));
3571 GtkTreeModel
**store_model
= (GtkTreeModel
**)&store
;
3573 case GTK_RESPONSE_ACCEPT
:
3574 case GTK_RESPONSE_OK
:
3575 if (gtk_tree_selection_get_selected (select
, store_model
, &iter
)){
3576 gtk_tree_model_get ((GtkTreeModel
*)store
, &iter
, MODULE_COLUMN
, &unload_module_name
, -1);
3578 case GTK_RESPONSE_REJECT
:
3579 case GTK_RESPONSE_CANCEL
:
3581 gtk_widget_destroy(dialogue
);
3585 return unload_module_name
;
3589 /* Insert all menu entry and tool buttons into this main window
3594 void add_all_menu_toolbar_constructors(MainWindow
* mw
, gpointer user_data
)
3598 lttvwindow_viewer_constructor constructor
;
3599 LttvMenus
* global_menu
, * instance_menu
;
3600 LttvToolbars
* global_toolbar
, * instance_toolbar
;
3601 LttvMenuClosure
*menu_item
;
3602 LttvToolbarClosure
*toolbar_item
;
3603 LttvAttributeValue value
;
3604 LttvIAttribute
*global_attributes
= LTTV_IATTRIBUTE(lttv_global_attributes());
3605 LttvIAttribute
*attributes
= mw
->attributes
;
3606 GtkWidget
* tool_menu_title_menu
, *new_widget
, *pixmap
;
3609 retval
= lttv_iattribute_find_by_path(global_attributes
, "viewers/menu",
3610 LTTV_POINTER
, &value
);
3612 if(*(value
.v_pointer
) == NULL
)
3613 *(value
.v_pointer
) = lttv_menus_new();
3614 global_menu
= (LttvMenus
*)*(value
.v_pointer
);
3616 retval
= lttv_iattribute_find_by_path(attributes
, "viewers/menu",
3617 LTTV_POINTER
, &value
);
3619 if(*(value
.v_pointer
) == NULL
)
3620 *(value
.v_pointer
) = lttv_menus_new();
3621 instance_menu
= (LttvMenus
*)*(value
.v_pointer
);
3623 retval
= lttv_iattribute_find_by_path(global_attributes
, "viewers/toolbar",
3624 LTTV_POINTER
, &value
);
3626 if(*(value
.v_pointer
) == NULL
)
3627 *(value
.v_pointer
) = lttv_toolbars_new();
3628 global_toolbar
= (LttvToolbars
*)*(value
.v_pointer
);
3630 retval
= lttv_iattribute_find_by_path(attributes
, "viewers/toolbar",
3631 LTTV_POINTER
, &value
);
3633 if(*(value
.v_pointer
) == NULL
)
3634 *(value
.v_pointer
) = lttv_toolbars_new();
3635 instance_toolbar
= (LttvToolbars
*)*(value
.v_pointer
);
3637 /* Add missing menu entries to window instance */
3638 for(i
=0;i
<global_menu
->len
;i
++) {
3639 menu_item
= &g_array_index(global_menu
, LttvMenuClosure
, i
);
3641 //add menu_item to window instance;
3642 constructor
= menu_item
->con
;
3643 tool_menu_title_menu
= lookup_widget(mw
->mwindow
,"ToolMenuTitle_menu");
3645 gtk_menu_item_new_with_mnemonic (menu_item
->menu_text
);
3646 gtk_container_add (GTK_CONTAINER (tool_menu_title_menu
),
3648 g_signal_connect ((gpointer
) new_widget
, "activate",
3649 G_CALLBACK (insert_viewer_wrap
),
3651 gtk_widget_show (new_widget
);
3652 lttv_menus_add(instance_menu
, menu_item
->con
,
3653 menu_item
->menu_path
,
3654 menu_item
->menu_text
,
3659 /* Add missing toolbar entries to window instance */
3660 for(i
=0;i
<global_toolbar
->len
;i
++) {
3661 toolbar_item
= &g_array_index(global_toolbar
, LttvToolbarClosure
, i
);
3663 //add toolbar_item to window instance;
3664 constructor
= toolbar_item
->con
;
3665 tool_menu_title_menu
= lookup_widget(mw
->mwindow
,"MToolbar1");
3666 pixbuf
= gdk_pixbuf_new_from_xpm_data((const char**)toolbar_item
->pixmap
);
3667 pixmap
= gtk_image_new_from_pixbuf(pixbuf
);
3669 gtk_toolbar_append_element (GTK_TOOLBAR (tool_menu_title_menu
),
3670 GTK_TOOLBAR_CHILD_BUTTON
,
3673 toolbar_item
->tooltip
, NULL
,
3674 pixmap
, NULL
, NULL
);
3675 gtk_label_set_use_underline(
3676 GTK_LABEL (((GtkToolbarChild
*) (
3677 g_list_last (GTK_TOOLBAR
3678 (tool_menu_title_menu
)->children
)->data
))->label
),
3680 gtk_container_set_border_width (GTK_CONTAINER (new_widget
), 1);
3681 g_signal_connect ((gpointer
) new_widget
,
3683 G_CALLBACK (insert_viewer_wrap
),
3685 gtk_widget_show (new_widget
);
3687 lttv_toolbars_add(instance_toolbar
, toolbar_item
->con
,
3688 toolbar_item
->tooltip
,
3689 toolbar_item
->pixmap
,
3697 /* Create a main window
3700 MainWindow
*construct_main_window(MainWindow
* parent
)
3704 g_debug("construct_main_window()");
3705 GtkWidget
* new_window
; /* New generated main window */
3706 MainWindow
* new_m_window
;/* New main window structure */
3707 GtkNotebook
* notebook
;
3708 LttvIAttribute
*attributes
=
3709 LTTV_IATTRIBUTE(g_object_new(LTTV_ATTRIBUTE_TYPE
, NULL
));
3710 LttvAttributeValue value
;
3713 new_m_window
= g_new(MainWindow
, 1);
3715 // Add the object's information to the module's array
3716 g_main_window_list
= g_slist_append(g_main_window_list
, new_m_window
);
3718 new_window
= create_MWindow();
3719 gtk_widget_show (new_window
);
3721 new_m_window
->mwindow
= new_window
;
3722 new_m_window
->attributes
= attributes
;
3724 retval
= lttv_iattribute_find_by_path(attributes
, "viewers/menu",
3725 LTTV_POINTER
, &value
);
3727 *(value
.v_pointer
) = lttv_menus_new();
3729 retval
= lttv_iattribute_find_by_path(attributes
, "viewers/toolbar",
3730 LTTV_POINTER
, &value
);
3732 *(value
.v_pointer
) = lttv_toolbars_new();
3734 add_all_menu_toolbar_constructors(new_m_window
, NULL
);
3736 g_object_set_data_full(G_OBJECT(new_window
),
3738 (gpointer
)new_m_window
,
3739 (GDestroyNotify
)g_free
);
3740 //create a default tab
3741 notebook
= (GtkNotebook
*)lookup_widget(new_m_window
->mwindow
, "MNotebook");
3742 if(notebook
== NULL
){
3743 g_info("Notebook does not exist\n");
3744 /* FIXME : destroy partially created widgets */
3745 g_free(new_m_window
);
3748 //gtk_notebook_popup_enable (GTK_NOTEBOOK(notebook));
3749 //for now there is no name field in LttvTraceset structure
3750 //Use "Traceset" as the label for the default tab
3752 GtkWidget
* parent_notebook
= lookup_widget(parent
->mwindow
, "MNotebook");
3753 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(parent_notebook
),
3754 gtk_notebook_get_current_page(GTK_NOTEBOOK(parent_notebook
)));
3760 LttvPluginTab
*ptab
;
3761 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
3762 parent_tab
= ptab
->tab
;
3764 LttvPluginTab
*ptab
= g_object_new(LTTV_TYPE_PLUGIN_TAB
, NULL
);
3766 new_m_window
, parent_tab
, notebook
, "Traceset");
3767 ptab
->parent
.top_widget
= ptab
->tab
->top_widget
;
3768 g_object_set_data_full(
3769 G_OBJECT(ptab
->tab
->vbox
),
3772 (GDestroyNotify
)tab_destructor
);
3773 new_tab
= ptab
->tab
;
3775 LttvPluginTab
*ptab
= g_object_new(LTTV_TYPE_PLUGIN_TAB
, NULL
);
3776 init_tab(ptab
->tab
, new_m_window
, NULL
, notebook
, "Traceset");
3777 ptab
->parent
.top_widget
= ptab
->tab
->top_widget
;
3778 g_object_set_data_full(
3779 G_OBJECT(ptab
->tab
->vbox
),
3782 (GDestroyNotify
)tab_destructor
);
3783 new_tab
= ptab
->tab
;
3786 /* Insert default viewers */
3788 LttvAttributeType type
;
3789 LttvAttributeName name
;
3790 LttvAttributeValue value
;
3791 LttvAttribute
*attribute
;
3793 LttvIAttribute
*attributes_global
=
3794 LTTV_IATTRIBUTE(lttv_global_attributes());
3796 attribute
= LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
3797 LTTV_IATTRIBUTE(attributes_global
),
3798 LTTV_VIEWER_CONSTRUCTORS
));
3799 g_assert(attribute
);
3801 name
= g_quark_from_string("guievents");
3802 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
3804 if(type
== LTTV_POINTER
) {
3805 lttvwindow_viewer_constructor viewer_constructor
=
3806 (lttvwindow_viewer_constructor
)*value
.v_pointer
;
3807 insert_viewer(new_window
, viewer_constructor
);
3810 name
= g_quark_from_string("guicontrolflow");
3811 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
3813 if(type
== LTTV_POINTER
) {
3814 lttvwindow_viewer_constructor viewer_constructor
=
3815 (lttvwindow_viewer_constructor
)*value
.v_pointer
;
3816 insert_viewer(new_window
, viewer_constructor
);
3819 name
= g_quark_from_string("guistatistics");
3820 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
3822 if(type
== LTTV_POINTER
) {
3823 lttvwindow_viewer_constructor viewer_constructor
=
3824 (lttvwindow_viewer_constructor
)*value
.v_pointer
;
3825 insert_viewer(new_window
, viewer_constructor
);
3829 g_info("There are now : %d windows\n",g_slist_length(g_main_window_list
));
3831 return new_m_window
;
3835 /* Free the memory occupied by a tab structure
3839 void tab_destructor(LttvPluginTab
* ptab
)
3841 int i
, nb
, ref_count
;
3843 Tab
*tab
= ptab
->tab
;
3846 g_object_unref(tab
->attributes
);
3848 if(tab
->interrupted_state
)
3849 g_object_unref(tab
->interrupted_state
);
3852 if(tab
->traceset_info
->traceset_context
!= NULL
){
3853 //remove state update hooks
3854 lttv_state_remove_event_hooks(
3855 (LttvTracesetState
*)tab
->traceset_info
->
3857 lttv_context_fini(LTTV_TRACESET_CONTEXT(tab
->traceset_info
->
3859 g_object_unref(tab
->traceset_info
->traceset_context
);
3861 if(tab
->traceset_info
->traceset
!= NULL
) {
3862 nb
= lttv_traceset_number(tab
->traceset_info
->traceset
);
3863 for(i
= 0 ; i
< nb
; i
++) {
3864 trace
= lttv_traceset_get(tab
->traceset_info
->traceset
, i
);
3865 ref_count
= lttv_trace_get_ref_number(trace
);
3867 ltt_trace_close(lttv_trace(trace
));
3871 lttv_traceset_destroy(tab
->traceset_info
->traceset
);
3872 /* Remove the idle events requests processing function of the tab */
3873 g_idle_remove_by_data(tab
);
3875 g_slist_free(tab
->events_requests
);
3876 g_free(tab
->traceset_info
);
3878 g_object_unref(ptab
);
3882 /* Create a tab and insert it into the current main window
3885 void init_tab(Tab
*tab
, MainWindow
* mw
, Tab
*copy_tab
,
3886 GtkNotebook
* notebook
, char * label
)
3890 //LttvFilter *filter = NULL;
3892 //create a new tab data structure
3893 //tab = g_new(Tab,1);
3895 //construct and initialize the traceset_info
3896 tab
->traceset_info
= g_new(TracesetInfo
,1);
3899 tab
->traceset_info
->traceset
=
3900 lttv_traceset_copy(copy_tab
->traceset_info
->traceset
);
3902 /* Copy the previous tab's filter */
3903 /* We can clone the filter, as we copy the trace set also */
3904 /* The filter must always be in sync with the trace set */
3905 tab
->filter
= lttv_filter_clone(copy_tab
->filter
);
3907 tab
->traceset_info
->traceset
= lttv_traceset_new();
3911 lttv_attribute_write_xml(
3912 lttv_traceset_attribute(tab
->traceset_info
->traceset
),
3918 tab
->time_manager_lock
= FALSE
;
3919 tab
->current_time_manager_lock
= FALSE
;
3921 //FIXME copy not implemented in lower level
3922 tab
->traceset_info
->traceset_context
=
3923 g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
3924 g_assert(tab
->traceset_info
->traceset_context
!= NULL
);
3926 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
),
3927 tab
->traceset_info
->traceset
);
3928 //add state update hooks
3929 lttv_state_add_event_hooks(
3930 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
3932 //determine the current_time and time_window of the tab
3934 if(copy_tab
!= NULL
){
3935 tab
->time_window
= copy_tab
->time_window
;
3936 tab
->current_time
= copy_tab
->current_time
;
3938 tab
->time_window
.start_time
=
3939 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
3940 time_span
.start_time
;
3941 if(DEFAULT_TIME_WIDTH_S
<
3942 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
3943 time_span
.end_time
.tv_sec
)
3944 tmp_time
.tv_sec
= DEFAULT_TIME_WIDTH_S
;
3947 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
3948 time_span
.end_time
.tv_sec
;
3949 tmp_time
.tv_nsec
= 0;
3950 tab
->time_window
.time_width
= tmp_time
;
3951 tab
->current_time
.tv_sec
=
3952 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
3953 time_span
.start_time
.tv_sec
;
3954 tab
->current_time
.tv_nsec
=
3955 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
3956 time_span
.start_time
.tv_nsec
;
3959 tab
->attributes
= LTTV_IATTRIBUTE(g_object_new(LTTV_ATTRIBUTE_TYPE
, NULL
));
3960 tab
->interrupted_state
= g_object_new(LTTV_ATTRIBUTE_TYPE
, NULL
);
3962 tab
->vbox
= gtk_vbox_new(FALSE
, 2);
3963 tab
->top_widget
= tab
->vbox
;
3964 //g_object_set_data_full(G_OBJECT(tab->top_widget), "filter",
3965 // filter, (GDestroyNotify)lttv_filter_destroy);
3967 // g_signal_connect (G_OBJECT(tab->top_widget),
3969 // G_CALLBACK (on_top_notify),
3972 tab
->viewer_container
= gtk_vbox_new(TRUE
, 2);
3973 tab
->scrollbar
= gtk_hscrollbar_new(NULL
);
3974 //tab->multivpaned = gtk_multi_vpaned_new();
3976 gtk_box_pack_start(GTK_BOX(tab
->vbox
),
3977 tab
->viewer_container
,
3979 TRUE
, /* Give the extra space to the child */
3980 0); /* No padding */
3983 // tab->time_window = copy_tab->time_window;
3984 // tab->current_time = copy_tab->current_time;
3987 /* Create the timebar */
3989 tab
->MTimebar
= timebar_new();
3991 gtk_box_pack_end(GTK_BOX(tab
->vbox
),
3993 FALSE
, /* Do not expand */
3994 FALSE
, /* Fill has no effect here (expand false) */
3995 0); /* No padding */
3997 gtk_box_pack_end(GTK_BOX(tab
->vbox
),
3999 FALSE
, /* Do not expand */
4000 FALSE
, /* Fill has no effect here (expand false) */
4001 0); /* No padding */
4003 g_object_set_data(G_OBJECT(tab
->viewer_container
), "focused_viewer", NULL
);
4009 // Display a label with a X
4010 GtkWidget *w_hbox = gtk_hbox_new(FALSE, 4);
4011 GtkWidget *w_label = gtk_label_new (label);
4012 GtkWidget *pixmap = create_pixmap(GTK_WIDGET(notebook), "close.png");
4013 GtkWidget *w_button = gtk_button_new ();
4014 gtk_container_add(GTK_CONTAINER(w_button), pixmap);
4015 //GtkWidget *w_button = gtk_button_new_with_label("x");
4017 gtk_button_set_relief(GTK_BUTTON(w_button), GTK_RELIEF_NONE);
4019 gtk_box_pack_start(GTK_BOX(w_hbox), w_label, TRUE, TRUE, 0);
4020 gtk_box_pack_end(GTK_BOX(w_hbox), w_button, FALSE,
4023 g_signal_connect_swapped (w_button, "clicked",
4024 G_CALLBACK (on_close_tab_X_clicked),
4027 gtk_widget_set_state(w_button, GTK_STATE_ACTIVE);
4029 gtk_widget_show (w_label);
4030 gtk_widget_show (pixmap);
4031 gtk_widget_show (w_button);
4032 gtk_widget_show (w_hbox);
4034 tab->label = w_hbox;
4038 tab
->label
= gtk_label_new (label
);
4040 gtk_widget_show(tab
->label
);
4041 gtk_widget_show(tab
->scrollbar
);
4042 gtk_widget_show(tab
->MTimebar
);
4043 gtk_widget_show(tab
->viewer_container
);
4044 gtk_widget_show(tab
->vbox
);
4046 //gtk_widget_show(tab->multivpaned);
4049 /* Start with empty events requests list */
4050 tab
->events_requests
= NULL
;
4051 tab
->events_request_pending
= FALSE
;
4052 tab
->stop_foreground
= FALSE
;
4056 g_signal_connect(G_OBJECT(tab
->scrollbar
), "value-changed",
4057 G_CALLBACK(scroll_value_changed_cb
), tab
);
4060 /* Timebar signal handler */
4061 g_signal_connect(G_OBJECT(tab
->MTimebar
), "start-time-changed",
4062 G_CALLBACK(on_timebar_starttime_changed
), tab
);
4063 g_signal_connect(G_OBJECT(tab
->MTimebar
), "end-time-changed",
4064 G_CALLBACK(on_timebar_endtime_changed
), tab
);
4065 g_signal_connect(G_OBJECT(tab
->MTimebar
), "current-time-changed",
4066 G_CALLBACK(on_timebar_currenttime_changed
), tab
);
4068 //g_signal_connect(G_OBJECT(tab->scrollbar), "changed",
4069 // G_CALLBACK(scroll_value_changed_cb), tab);
4072 //insert tab into notebook
4073 gtk_notebook_append_page(notebook
,
4076 list
= gtk_container_get_children(GTK_CONTAINER(notebook
));
4077 gtk_notebook_set_current_page(notebook
,g_list_length(list
)-1);
4078 // always show : not if(g_list_length(list)>1)
4079 gtk_notebook_set_show_tabs(notebook
, TRUE
);
4082 lttvwindow_report_time_window(tab
, copy_tab
->time_window
);
4083 lttvwindow_report_current_time(tab
, copy_tab
->current_time
);
4085 TimeWindow time_window
;
4087 time_window
.start_time
= ltt_time_zero
;
4088 time_window
.end_time
= ltt_time_add(time_window
.start_time
,
4089 lttvwindow_default_time_width
);
4090 time_window
.time_width
= lttvwindow_default_time_width
;
4091 time_window
.time_width_double
= ltt_time_to_double(time_window
.time_width
);
4093 lttvwindow_report_time_window(tab
, time_window
);
4094 lttvwindow_report_current_time(tab
, ltt_time_zero
);
4097 LttvTraceset
*traceset
= tab
->traceset_info
->traceset
;
4098 SetTraceset(tab
, traceset
);
4102 * execute_events_requests
4104 * Idle function that executes the pending requests for a tab.
4106 * @return return value : TRUE : keep the idle function, FALSE : remove it.
4108 gboolean
execute_events_requests(Tab
*tab
)
4110 return ( lttvwindow_process_pending_requests(tab
) );
4114 __EXPORT
void create_main_window_with_trace_list(GSList
*traces
, gboolean is_live
)
4116 GSList
*iter
= NULL
;
4119 MainWindow
*mw
= construct_main_window(NULL
);
4120 GtkWidget
*widget
= mw
->mwindow
;
4122 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
4123 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
4124 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
4125 LttvPluginTab
*ptab
;
4129 ptab
= create_new_tab(widget
, NULL
);
4132 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
4136 for(iter
=traces
; iter
!=NULL
; iter
=g_slist_next(iter
)) {
4137 gchar
*path
= (gchar
*)iter
->data
;
4139 gchar abs_path
[PATH_MAX
];
4143 get_absolute_pathname(path
, abs_path
);
4144 trace_v
= lttvwindowtraces_get_trace_by_name(abs_path
);
4145 if(trace_v
== NULL
) {
4147 trace
= ltt_trace_open_live(abs_path
);
4149 trace
= ltt_trace_open(abs_path
);
4152 g_warning("cannot open trace %s", abs_path
);
4154 GtkWidget
*dialogue
=
4155 gtk_message_dialog_new(
4156 GTK_WINDOW(gtk_widget_get_toplevel(widget
)),
4157 GTK_DIALOG_MODAL
|GTK_DIALOG_DESTROY_WITH_PARENT
,
4160 "Cannot open trace : maybe you should enter in the directory "
4162 gtk_dialog_run(GTK_DIALOG(dialogue
));
4163 gtk_widget_destroy(dialogue
);
4165 trace_v
= lttv_trace_new(trace
);
4166 lttvwindowtraces_add_trace(trace_v
);
4167 lttvwindow_add_trace(tab
, trace_v
);
4170 lttvwindow_add_trace(tab
, trace_v
);
4174 LttvTraceset
*traceset
;
4176 traceset
= tab
->traceset_info
->traceset
;
4177 SetTraceset(tab
, traceset
);