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., 51 Franklin Street, Fifth Floor, Boston,
23 #include <limits.h> // for PATH_MAX
31 #include "callbacks.h"
32 #include "interface.h"
34 #include <lttv/time.h>
35 #include <lttv/lttv.h>
36 #include <lttv/module.h>
37 #include <lttv/iattribute.h>
38 #include <lttv/traceset.h>
39 #include <lttv/state.h>
41 #include <lttv/stats.h>
42 #include <lttv/sync/sync_chain_lttv.h>
43 #endif /* BABEL_CLEANUP */
44 #include <lttv/filter.h>
45 #include <lttvwindow/mainwindow.h>
46 #include <lttvwindow/mainwindow-private.h>
47 #include <lttvwindow/menu.h>
48 #include <lttvwindow/timebar.h>
49 #include <lttvwindow/toolbar.h>
50 #include <lttvwindow/lttvwindow.h>
51 #include <lttvwindow/lttvwindowtraces.h>
52 #include <lttvwindow/lttv_plugin_tab.h>
54 #include <babeltrace/babeltrace.h>
55 #include <babeltrace/ctf/events.h>
56 #include <babeltrace/ctf/iterator.h>
58 static LttTime lttvwindow_default_time_width
= { 1, 0 };
59 #define CLIP_BUF 256 // size of clipboard buffer
61 extern LttvTrace
*g_init_trace
;
64 /** Array containing instanced objects. */
65 extern GSList
* g_main_window_list
;
67 /** MD : keep old directory. */
68 static char remember_plugins_dir
[PATH_MAX
] = "";
69 static char remember_trace_dir
[PATH_MAX
] = "";
71 void tab_destructor(LttvPluginTab
* ptab
);
73 MainWindow
* get_window_data_struct(GtkWidget
* widget
);
74 char * get_load_module(MainWindow
*mw
,
75 char ** load_module_name
, int nb_module
);
76 char * get_unload_module(MainWindow
*mw
,
77 char ** loaded_module_name
, int nb_module
);
78 char * get_remove_trace(MainWindow
*mw
, char ** all_trace_name
, int nb_trace
);
79 char * get_selection(MainWindow
*mw
,
80 char ** all_name
, int nb
, char *title
, char * column_title
);
81 void init_tab(Tab
*tab
, MainWindow
* mw
, Tab
*copy_tab
,
82 GtkNotebook
* notebook
, char * label
);
84 int update_traceset(Tab
*tab
, LttvTraceset
*traceset
);
86 static void insert_viewer(GtkWidget
* widget
, lttvwindow_viewer_constructor constructor
);
88 LttvPluginTab
*create_new_tab(GtkWidget
* widget
, gpointer user_data
);
90 static gboolean
lttvwindow_process_pending_requests(Tab
*tab
);
92 static void on_timebar_starttime_changed(Timebar
*timebar
,
94 static void on_timebar_endtime_changed(Timebar
*timebar
,
96 static void on_timebar_currenttime_changed(Timebar
*timebar
,
113 static void on_top_notify(GObject
*gobject
,
117 Tab
*tab
= (Tab
*)user_data
;
118 g_message("in on_top_notify.\n");
122 static gboolean
viewer_grab_focus(GtkWidget
*widget
, GdkEventButton
*event
,
125 GtkWidget
*viewer
= GTK_WIDGET(data
);
126 GtkWidget
*viewer_container
= gtk_widget_get_parent(viewer
);
128 g_debug("FOCUS GRABBED");
129 g_object_set_data(G_OBJECT(viewer_container
), "focused_viewer", viewer
);
134 static void connect_focus_recursive(GtkWidget
*widget
,
137 if(GTK_IS_CONTAINER(widget
)) {
138 gtk_container_forall(GTK_CONTAINER(widget
),
139 (GtkCallback
)connect_focus_recursive
,
143 if(GTK_IS_TREE_VIEW(widget
)) {
144 gtk_tree_view_set_headers_clickable(GTK_TREE_VIEW(widget
), TRUE
);
146 gtk_widget_add_events(widget
, GDK_BUTTON_PRESS_MASK
);
147 g_signal_connect (G_OBJECT(widget
),
148 "button-press-event",
149 G_CALLBACK (viewer_grab_focus
),
153 /* Stop all the processings and call gtk_main_quit() */
154 static void mainwindow_quit()
156 lttvwindowtraces_unregister_requests(g_quark_from_string("stats"));
157 lttvwindowtraces_unregister_requests(g_quark_from_string("state"));
158 lttvwindowtraces_unregister_computation_hooks(g_quark_from_string("stats"));
159 lttvwindowtraces_unregister_computation_hooks(g_quark_from_string("state"));
165 /* insert_viewer function constructs an instance of a viewer first,
166 * then inserts the widget of the instance into the container of the
171 insert_viewer_wrap(GtkWidget
*menuitem
, gpointer user_data
)
173 insert_viewer((GtkWidget
*)menuitem
, (lttvwindow_viewer_constructor
)user_data
);
177 /* internal functions */
178 void insert_viewer(GtkWidget
* widget
, lttvwindow_viewer_constructor constructor
)
180 GtkWidget
* viewer_container
;
181 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
183 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
184 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
189 ptab
= create_new_tab(widget
, NULL
);
191 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
195 viewer_container
= tab
->viewer_container
;
197 viewer
= (GtkWidget
*)constructor(&ptab
->parent
);
200 //gtk_multivpaned_widget_add(GTK_MULTIVPANED(multivpaned), viewer);
202 gtk_box_pack_end(GTK_BOX(viewer_container
),
208 /* We want to connect the viewer_grab_focus to EVERY
209 * child of this widget. The little trick is to get each child
210 * of each GTK_CONTAINER, even subchildren.
212 connect_focus_recursive(viewer
, viewer
);
217 * Function to set/update traceset for the viewers
218 * @param tab viewer's tab
219 * @param traceset traceset of the main window.
221 * 0 : traceset updated
222 * 1 : no traceset hooks to update; not an error.
225 int SetTraceset(Tab
* tab
, LttvTraceset
*traceset
)
228 TimeInterval time_span
;
229 TimeWindow new_time_window
;
230 LttTime new_current_time
;
233 // Perform time synchronization on the traces
234 if (syncTraceset(tsc
))
236 /* There is some time-dependant information that was calculated during
237 * context initialization. Destroy the old contexts and initialize new
239 * Modified from lttvwindow_add_trace()
241 // Keep a reference to the traces so they are not freed
242 for(i
= 0; i
< lttv_traceset_number(traceset
); i
++)
244 LttvTrace
*trace
= lttv_traceset_get(traceset
, i
);
245 lttv_trace_ref(trace
);
248 // Remove state update hooks
249 lttv_state_remove_event_hooks(
250 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
252 lttv_context_fini(LTTV_TRACESET_CONTEXT(
253 tab
->traceset_info
->traceset_context
));
254 g_object_unref(tab
->traceset_info
->traceset_context
);
256 for(i
= 0; i
< lttv_traceset_number(traceset
); i
++)
258 LttvTrace
*trace
= lttv_traceset_get(traceset
, i
);
259 lttvwindowtraces_remove_trace(trace
);
260 lttvwindowtraces_add_trace(trace
);
263 // Create new context
264 tab
->traceset_info
->traceset_context
=
265 g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
266 lttv_context_init(LTTV_TRACESET_CONTEXT(tab
->traceset_info
->
267 traceset_context
), traceset
);
269 // Add state update hooks
270 lttv_state_add_event_hooks(
271 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
273 // Remove local reference to the traces
274 for(i
=0; i
<lttv_traceset_number(traceset
); i
++)
276 LttvTrace
*trace
= lttv_traceset_get(traceset
, i
);
277 lttv_trace_unref(trace
);
280 tsc
= LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
282 #endif /*BABEL_CLEANUP*/
284 time_span
= lttv_traceset_get_time_span_real(traceset
);
286 tab
->traceset_info
->traceset
= traceset
;
288 new_time_window
= tab
->time_window
;
289 new_current_time
= tab
->current_time
;
291 /* Set the tab's time window and current time if
293 if(ltt_time_compare(tab
->time_window
.start_time
, time_span
.start_time
) < 0
294 || ltt_time_compare(tab
->time_window
.end_time
,
295 time_span
.end_time
) > 0) {
296 new_time_window
.start_time
= time_span
.start_time
;
298 new_current_time
= time_span
.start_time
;
302 if(ltt_time_compare(lttvwindow_default_time_width
,
303 ltt_time_sub(time_span
.end_time
, time_span
.start_time
)) < 0
305 ltt_time_compare(time_span
.end_time
, time_span
.start_time
) == 0)
306 tmp_time
= lttvwindow_default_time_width
;
308 tmp_time
= time_span
.end_time
;
310 new_time_window
.time_width
= tmp_time
;
311 new_time_window
.time_width_double
= ltt_time_to_double(tmp_time
);
312 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
313 new_time_window
.time_width
) ;
315 lttv_state_add_event_hooks(traceset
);
317 //TODO ybrosseau 2012-08-03 Temporarly compute checkpoints right at the adding
319 //Compute the traceset state checkpoint
322 EventsRequest
*events_request
= g_new(EventsRequest
, 1);
324 LttvHooks
*hook_adder
= lttv_hooks_new();
325 lttv_hooks_add(hook_adder
, lttv_state_save_hook_add_event_hooks
, NULL
,
327 LttvHooks
*hook_remover
= lttv_hooks_new();
328 lttv_hooks_add(hook_remover
, lttv_state_save_hook_remove_event_hooks
,
329 NULL
, LTTV_PRIO_DEFAULT
);
331 // Fill the events request
332 events_request
->owner
= NULL
;
333 events_request
->viewer_data
= NULL
;
334 events_request
->servicing
= FALSE
;
335 events_request
->start_time
= ltt_time_zero
;
336 events_request
->start_position
= NULL
;
337 events_request
->stop_flag
= FALSE
;
338 events_request
->end_time
= ltt_time_infinite
;
339 events_request
->num_events
= G_MAXUINT
;
340 events_request
->end_position
= NULL
;
341 events_request
->trace
= 1; //fixed /* FIXME */
342 events_request
->before_chunk_traceset
= NULL
;
343 events_request
->before_chunk_trace
= NULL
;
344 events_request
->before_chunk_tracefile
= NULL
;
345 events_request
->event
= NULL
;
346 events_request
->after_chunk_tracefile
= NULL
;
347 events_request
->after_chunk_trace
= NULL
;
348 events_request
->after_chunk_traceset
= NULL
;
349 events_request
->before_request
= hook_adder
;
350 events_request
->after_request
= hook_remover
;
352 lttvwindow_events_request(tab
, events_request
);
355 /* Finally, call the update hooks of the viewers */
356 gint retval
= update_traceset(tab
, traceset
);
358 time_change_manager(tab
, new_time_window
);
359 current_time_change_manager(tab
, new_current_time
);
366 * Function to set/update filter for the viewers
367 * @param tab viewer's tab
368 * @param filter filter of the main window.
371 * 0 : filters updated
372 * 1 : no filter hooks to update; not an error.
375 int SetFilter(Tab
* tab
, gpointer filter
)
378 LttvAttributeValue value
;
380 g_assert(lttv_iattribute_find_by_path(tab
->attributes
,
381 "hooks/updatefilter", LTTV_POINTER
, &value
));
383 tmp
= (LttvHooks
*)*(value
.v_pointer
);
385 if(tmp
== NULL
) return 1;
386 lttv_hooks_call(tmp
,filter
);
394 * Function to redraw each viewer belonging to the current tab
395 * @param tab viewer's tab
398 int update_traceset(Tab
*tab
, LttvTraceset
*traceset
)
400 LttvAttributeValue value
;
404 retval
= lttv_iattribute_find_by_path(tab
->attributes
,
405 "hooks/updatetraceset",
409 tmp
= (LttvHooks
*)*(value
.v_pointer
);
413 lttv_hooks_call(tmp
, traceset
);
419 Call hooks register to get update on traceset time span changes
421 int notify_time_span_changed(Tab
*tab
)
423 LttvAttributeValue value
;
427 retval
= lttv_iattribute_find_by_path(tab
->attributes
,
428 "hooks/updatetimespan",
432 tmp
= (LttvHooks
*)*(value
.v_pointer
);
436 lttv_hooks_call(tmp
, NULL
);
441 /* get_label function is used to get user input, it displays an input
442 * box, which allows user to input a string
445 void get_label_string (GtkWidget
* text
, gchar
* label
)
447 GtkEntry
* entry
= (GtkEntry
*)text
;
448 if(strlen(gtk_entry_get_text(entry
))!=0)
449 strcpy(label
,gtk_entry_get_text(entry
));
452 gboolean
get_label(MainWindow
* mw
, gchar
* str
, gchar
* dialogue_title
, gchar
* label_str
)
454 GtkWidget
* dialogue
;
459 dialogue
= gtk_dialog_new_with_buttons(dialogue_title
,NULL
,
461 GTK_STOCK_OK
,GTK_RESPONSE_ACCEPT
,
462 GTK_STOCK_CANCEL
,GTK_RESPONSE_REJECT
,
465 label
= gtk_label_new(label_str
);
466 gtk_widget_show(label
);
468 text
= gtk_entry_new();
469 gtk_widget_show(text
);
471 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialogue
)->vbox
), label
,TRUE
, TRUE
,0);
472 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialogue
)->vbox
), text
,FALSE
, FALSE
,0);
474 id
= gtk_dialog_run(GTK_DIALOG(dialogue
));
476 case GTK_RESPONSE_ACCEPT
:
477 get_label_string(text
,str
);
478 gtk_widget_destroy(dialogue
);
480 case GTK_RESPONSE_REJECT
:
482 gtk_widget_destroy(dialogue
);
489 /* get_window_data_struct function is actually a lookup function,
490 * given a widget which is in the tree of the main window, it will
491 * return the MainWindow data structure associated with main window
494 MainWindow
* get_window_data_struct(GtkWidget
* widget
)
497 MainWindow
* mw_data
;
499 mw
= lookup_widget(widget
, "MWindow");
501 g_info("Main window does not exist\n");
505 mw_data
= (MainWindow
*) g_object_get_data(G_OBJECT(mw
),"main_window_data");
507 g_warning("Main window data does not exist\n");
514 /* create_new_window function, just constructs a new main window
517 void create_new_window(GtkWidget
* widget
, gpointer user_data
, gboolean clone
)
519 MainWindow
* parent
= get_window_data_struct(widget
);
522 g_info("Clone : use the same traceset\n");
523 construct_main_window(parent
);
525 g_info("Empty : traceset is set to NULL\n");
526 construct_main_window(NULL
);
530 /* Get the currently focused viewer.
531 * If no viewer is focused, use the first one.
533 * If no viewer available, return NULL.
535 GtkWidget
*viewer_container_focus(GtkWidget
*container
)
539 widget
= (GtkWidget
*)g_object_get_data(G_OBJECT(container
),
543 g_debug("no widget focused");
544 GList
*children
= gtk_container_get_children(GTK_CONTAINER(container
));
547 widget
= GTK_WIDGET(children
->data
);
548 g_object_set_data(G_OBJECT(container
),
558 gint
viewer_container_position(GtkWidget
*container
, GtkWidget
*child
)
561 if(child
== NULL
) return -1;
565 memset(&value
, 0, sizeof(GValue
));
566 g_value_init(&value
, G_TYPE_INT
);
567 gtk_container_child_get_property(GTK_CONTAINER(container
),
571 pos
= g_value_get_int(&value
);
577 /* move_*_viewer functions move the selected view up/down in
581 void move_down_viewer(GtkWidget
* widget
, gpointer user_data
)
583 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
585 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
586 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
593 ptab
= g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
597 //gtk_multivpaned_widget_move_up(GTK_MULTIVPANED(tab->multivpaned));
599 /* change the position in the vbox */
600 GtkWidget
*focus_widget
;
602 focus_widget
= viewer_container_focus(tab
->viewer_container
);
603 position
= viewer_container_position(tab
->viewer_container
, focus_widget
);
606 /* can move up one position */
607 gtk_box_reorder_child(GTK_BOX(tab
->viewer_container
),
614 void move_up_viewer(GtkWidget
* widget
, gpointer user_data
)
616 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
618 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
619 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
626 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
630 //gtk_multivpaned_widget_move_down(GTK_MULTIVPANED(tab->multivpaned));
631 /* change the position in the vbox */
632 GtkWidget
*focus_widget
;
634 focus_widget
= viewer_container_focus(tab
->viewer_container
);
635 position
= viewer_container_position(tab
->viewer_container
, focus_widget
);
639 g_list_length(gtk_container_get_children(
640 GTK_CONTAINER(tab
->viewer_container
)))-1
642 /* can move down one position */
643 gtk_box_reorder_child(GTK_BOX(tab
->viewer_container
),
651 /* delete_viewer deletes the selected viewer in the current tab
654 void delete_viewer(GtkWidget
* widget
, gpointer user_data
)
656 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
658 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
659 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
666 ptab
= g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
670 //gtk_multivpaned_widget_delete(GTK_MULTIVPANED(tab->multivpaned));
672 GtkWidget
*focus_widget
= viewer_container_focus(tab
->viewer_container
);
674 if(focus_widget
!= NULL
)
675 gtk_widget_destroy(focus_widget
);
677 g_object_set_data(G_OBJECT(tab
->viewer_container
), "focused_viewer", NULL
);
680 #if UNFINISHED_FEATURE
681 /* TODO ybrosseau 2012-03-15: Function is half implemented. Should be removed */
682 /* open_traceset will open a traceset saved in a file
683 * Right now, it is not finished yet, (not working)
687 void open_traceset(GtkWidget
* widget
, gpointer user_data
)
691 LttvTraceset
* traceset
;
692 MainWindow
* mw_data
= get_window_data_struct(widget
);
693 GtkFileSelection
* file_selector
=
694 (GtkFileSelection
*)gtk_file_selection_new("Select a traceset");
696 gtk_file_selection_hide_fileop_buttons(file_selector
);
698 gtk_window_set_transient_for(GTK_WINDOW(file_selector
),
699 GTK_WINDOW(mw_data
->mwindow
));
701 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
703 case GTK_RESPONSE_ACCEPT
:
704 case GTK_RESPONSE_OK
:
705 dir
= gtk_file_selection_get_selections (file_selector
);
706 traceset
= lttv_traceset_load(dir
[0]);
707 g_info("Open a trace set %s\n", dir
[0]);
710 case GTK_RESPONSE_REJECT
:
711 case GTK_RESPONSE_CANCEL
:
713 gtk_widget_destroy((GtkWidget
*)file_selector
);
719 /* lttvwindow_process_pending_requests
721 * Process requests for parts of the trace from viewers.
723 * These requests are made by lttvwindow_events_request().
725 * This internal function gets called by g_idle, taking care of the pending
726 * requests. It is responsible for concatenation of time intervals and position
727 * requests. It does it with the following algorithm organizing process traceset
728 * calls. Here is the detailed description of the way it works :
730 * - Events Requests Servicing Algorithm
732 * Data structures necessary :
734 * List of requests added to context : list_in
735 * List of requests not added to context : list_out
740 * list_out : many events requests
742 * FIXME : insert rest of algorithm here
746 #define list_out tab->events_requests
748 gboolean
lttvwindow_process_pending_requests(Tab
*tab
)
753 GSList
*list_in
= NULL
;
757 LttvTracesetPosition
*end_position
;
759 if(lttvwindow_preempt_count
> 0) return TRUE
;
762 g_critical("Foreground processing : tab does not exist. Processing removed.");
766 /* There is no events requests pending : we should never have been called! */
767 g_assert(g_slist_length(list_out
) != 0);
769 ts
= tab
->traceset_info
->traceset
;
771 //set the cursor to be X shape, indicating that the computer is busy in doing its job
773 new = gdk_cursor_new(GDK_X_CURSOR
);
774 widget
= lookup_widget(tab
->mw
->mwindow
, "MToolbar1");
775 win
= gtk_widget_get_parent_window(widget
);
776 gdk_window_set_cursor(win
, new);
777 gdk_cursor_unref(new);
778 gdk_window_stick(win
);
779 gdk_window_unstick(win
);
782 g_debug("SIZE events req len : %d", g_slist_length(list_out
));
784 /* Preliminary check for no trace in traceset */
785 /* Unregister the routine if empty, empty list_out too */
786 if(lttv_traceset_number(ts
) == 0) {
788 /* - For each req in list_out */
789 GSList
*iter
= list_out
;
791 while(iter
!= NULL
) {
793 gboolean remove
= FALSE
;
794 gboolean free_data
= FALSE
;
795 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
797 /* - Call end request for req */
798 if(events_request
->servicing
== TRUE
)
799 lttv_hooks_call(events_request
->after_request
, (gpointer
)ts
);
801 /* - remove req from list_out */
802 /* Destroy the request */
805 //TODO ybrosseau: This if is always true
809 GSList
*remove_iter
= iter
;
811 iter
= g_slist_next(iter
);
812 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
813 list_out
= g_slist_remove_link(list_out
, remove_iter
);
814 } else { // not remove
815 iter
= g_slist_next(iter
);
820 /* 0.1 Lock Traces */
825 iter_trace
<lttv_traceset_number(ts
);
827 LttvTrace
*trace_v
= lttv_traceset_get(ts
, iter_trace
);
829 if(lttvwindowtraces_lock(trace_v
) != 0) {
830 g_critical("Foreground processing : Unable to get trace lock");
831 return TRUE
; /* Cannot get lock, try later */
836 /* 0.2 Seek tracefiles positions to context position */
838 //g_assert(lttv_process_traceset_seek_position(tsc, sync_position) == 0);
839 lttv_process_traceset_synchronize_tracefiles(tsc
);
842 /* Events processing algorithm implementation */
843 /* Warning : the gtk_events_pending takes a LOT of cpu time. So what we do
844 * instead is to leave the control to GTK and take it back.
846 /* A. Servicing loop */
847 //while( (g_slist_length(list_in) != 0 || g_slist_length(list_out) != 0)) {
848 if((g_slist_length(list_in
) != 0 || g_slist_length(list_out
) != 0)) {
850 /* 1. If list_in is empty (need a seek) */
851 if( g_slist_length(list_in
) == 0 ) {
853 /* list in is empty, need a seek */
855 /* 1.1 Add requests to list_in */
856 GSList
*ltime
= NULL
;
860 /* 1.1.1 Find all time requests with the lowest start time in list_out
863 if(g_slist_length(list_out
) > 0)
864 ltime
= g_slist_append(ltime
, g_slist_nth_data(list_out
, 0));
865 for(iter
=g_slist_nth(list_out
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
866 /* Find all time requests with the lowest start time in list_out */
867 EventsRequest
*event_request_ltime
= (EventsRequest
*)g_slist_nth_data(ltime
, 0);
868 EventsRequest
*event_request_list_out
= (EventsRequest
*)iter
->data
;
871 comp
= ltt_time_compare(event_request_ltime
->start_time
,
872 event_request_list_out
->start_time
);
874 ltime
= g_slist_append(ltime
, event_request_list_out
);
876 /* Remove all elements from ltime, and add current */
878 ltime
= g_slist_delete_link(ltime
, g_slist_nth(ltime
, 0));
879 ltime
= g_slist_append(ltime
, event_request_list_out
);
883 /* 1.1.2 Find all position requests with the lowest position in list_out
886 if(g_slist_length(list_out
) > 0)
887 lpos
= g_slist_append(lpos
, g_slist_nth_data(list_out
, 0));
888 for(iter
=g_slist_nth(list_out
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
889 /* Find all position requests with the lowest position in list_out */
890 EventsRequest
*event_request_lpos
= (EventsRequest
*)g_slist_nth_data(lpos
, 0);
891 EventsRequest
*event_request_list_out
= (EventsRequest
*)iter
->data
;
894 if(event_request_lpos
->start_position
!= NULL
895 && event_request_list_out
->start_position
!= NULL
)
897 //TODO ybrosseau: this compare is in fact an equal, so the behavior might not be right.
898 comp
= lttv_traceset_position_time_compare
899 (event_request_lpos
->start_position
,
900 event_request_list_out
->start_position
);
905 lpos
= g_slist_append(lpos
, event_request_list_out
);
907 /* Remove all elements from lpos, and add current */
909 lpos
= g_slist_delete_link(lpos
, g_slist_nth(lpos
, 0));
910 lpos
= g_slist_append(lpos
, event_request_list_out
);
915 EventsRequest
*event_request_lpos
= (EventsRequest
*)g_slist_nth_data(lpos
, 0);
916 EventsRequest
*event_request_ltime
= (EventsRequest
*)g_slist_nth_data(ltime
, 0);
917 LttTime lpos_start_time
;
919 if(event_request_lpos
!= NULL
920 && event_request_lpos
->start_position
!= NULL
) {
921 lpos_start_time
= lttv_traceset_position_get_time(
922 event_request_lpos
->start_position
);
925 /* 1.1.3 If lpos.start time < ltime */
926 if(event_request_lpos
!= NULL
927 && event_request_lpos
->start_position
!= NULL
928 && ltt_time_compare(lpos_start_time
,
929 event_request_ltime
->start_time
)<0) {
930 /* Add lpos to list_in, remove them from list_out */
931 for(iter
=lpos
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
933 EventsRequest
*event_request_lpos
=
934 (EventsRequest
*)iter
->data
;
936 list_in
= g_slist_append(list_in
, event_request_lpos
);
937 /* Remove from list_out */
938 list_out
= g_slist_remove(list_out
, event_request_lpos
);
941 /* 1.1.4 (lpos.start time >= ltime) */
942 /* Add ltime to list_in, remove them from list_out */
944 for(iter
=ltime
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
946 EventsRequest
*event_request_ltime
=
947 (EventsRequest
*)iter
->data
;
949 list_in
= g_slist_append(list_in
, event_request_ltime
);
950 /* Remove from list_out */
951 list_out
= g_slist_remove(list_out
, event_request_ltime
);
962 g_assert(g_slist_length(list_in
)>0);
963 EventsRequest
*events_request
= g_slist_nth_data(list_in
, 0);
968 /* 1.2.1 If first request in list_in is a time request */
969 if(events_request
->start_position
== NULL
) {
970 /* - If first req in list_in start time != current time */
971 //TODO ybrosseau: if commented out, since it was only affecting the g_debug
972 //if(tfc == NULL || ltt_time_compare(events_request->start_time,
973 // tfc->timestamp) != 0)
974 /* - Seek to that time */
975 g_debug("SEEK TIME : %lu, %lu", events_request
->start_time
.tv_sec
,
976 events_request
->start_time
.tv_nsec
);
977 lttv_state_traceset_seek_time_closest(ts
,
978 events_request
->start_time
);
980 /* Process the traceset with only state hooks */
984 lttv_process_traceset_middle(ts
,
985 events_request
->start_time
,
988 g_assert(seek_count
< LTTV_STATE_SAVE_INTERVAL
);
994 //LttvTracefileContext *tfc =
995 // lttv_traceset_context_get_current_tfc(tsc);
996 /* Else, the first request in list_in is a position request */
997 /* If first req in list_in pos != current pos */
998 g_assert(events_request
->start_position
!= NULL
);
999 g_debug("SEEK POS time : %lu, %lu",
1000 lttv_traceset_position_get_time(
1001 events_request
->start_position
).tv_sec
,
1002 lttv_traceset_position_get_time(
1003 events_request
->start_position
).tv_nsec
);
1005 /*if(tfc) {*/ if(0) {
1006 /* g_debug("SEEK POS context time : %lu, %lu",
1007 tfc->timestamp.tv_sec,
1008 tfc->timestamp.tv_nsec); */
1010 g_debug("SEEK POS context time : %lu, %lu",
1011 ltt_time_infinite
.tv_sec
,
1012 ltt_time_infinite
.tv_nsec
);
1014 g_assert(events_request
->start_position
!= NULL
);
1015 //TODO ybrosseau: for now, always seek
1016 if(/*lttv_traceset_context_ctx_pos_compare(tsc,
1017 events_request->start_position) != 0*/1) {
1018 /* 1.2.2.1 Seek to that position */
1019 g_debug("SEEK POSITION");
1020 //lttv_process_traceset_seek_position(tsc, events_request->start_position);
1021 pos_time
= lttv_traceset_position_get_time(
1022 events_request
->start_position
);
1024 lttv_state_traceset_seek_time_closest(ts
,
1026 //lttv_traceset_seek_to_position( events_request->start_position);
1028 /* Process the traceset with only state hooks */
1032 lttv_process_traceset_middle(ts
,
1035 events_request
->start_position
);
1037 //g_assert(lttv_traceset_context_ctx_pos_compare(tsc,
1038 // events_request->start_position) == 0);
1045 /* 1.3 Add hooks and call before request for all list_in members */
1047 GSList
*iter
= NULL
;
1048 for(iter
=list_in
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
1049 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1050 /* 1.3.1 If !servicing */
1051 if(events_request
->servicing
== FALSE
) {
1052 /* - begin request hooks called
1053 * - servicing = TRUE
1055 lttv_hooks_call(events_request
->before_request
, (gpointer
)ts
);
1056 events_request
->servicing
= TRUE
;
1058 /* 1.3.2 call before chunk
1059 * 1.3.3 events hooks added
1061 //TODO ybrosseau 2012-07-10: || TRUE added since we only support
1062 // traceset wide requests
1063 if(events_request
->trace
== -1 || TRUE
) {
1065 lttv_process_traceset_begin(ts
,
1066 events_request
->before_chunk_traceset
,
1067 events_request
->before_chunk_trace
,
1068 events_request
->event
1071 guint nb_trace
= lttv_traceset_number(ts
);
1072 g_assert((guint
)events_request
->trace
< nb_trace
&&
1073 events_request
->trace
> -1);
1074 LttvTrace
*trace
= lttv_traceset_get(ts
, events_request
->trace
);
1076 lttv_hooks_call(events_request
->before_chunk_traceset
, ts
);
1078 lttv_trace_add_hooks(trace
, events_request
->before_chunk_trace
,
1079 events_request
->event
);
1084 /* 2. Else, list_in is not empty, we continue a read */
1087 /* 2.0 For each req of list_in */
1088 GSList
*iter
= list_in
;
1090 while(iter
!= NULL
) {
1092 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1094 /* - Call before chunk
1095 * - events hooks added
1097 //TODO ybrosseau 2012-07-10: || TRUE added since we only support
1098 // traceset wide requests
1099 if(events_request
->trace
== -1 || TRUE
)
1100 lttv_process_traceset_begin(ts
,
1101 events_request
->before_chunk_traceset
,
1102 events_request
->before_chunk_trace
,
1103 events_request
->event
1106 guint nb_trace
= lttv_traceset_number(ts
);
1107 g_assert((guint
)events_request
->trace
< nb_trace
&&
1108 events_request
->trace
> -1);
1109 LttvTrace
*trace
= lttv_traceset_get(ts
, events_request
->trace
);
1111 lttv_hooks_call(events_request
->before_chunk_traceset
, ts
);
1113 lttv_trace_add_hooks(trace
,
1114 events_request
->before_chunk_trace
,
1115 events_request
->event
1119 iter
= g_slist_next(iter
);
1126 /* 2.1 For each req of list_out */
1127 GSList
*iter
= list_out
;
1129 while(iter
!= NULL
) {
1131 gboolean remove
= FALSE
;
1132 gboolean free_data
= FALSE
;
1133 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1135 /* if req.start time == current context time
1136 * or req.start position == current position*/
1137 /* if( ltt_time_compare(events_request->start_time,
1138 tfc->timestamp) == 0
1140 (events_request->start_position != NULL
1142 lttv_traceset_context_ctx_pos_compare(tsc,
1143 events_request->start_position) == 0)
1146 if(lttv_traceset_position_compare_current(ts
, events_request
->start_position
) == 0) {
1148 /* - Add to list_in, remove from list_out */
1149 list_in
= g_slist_append(list_in
, events_request
);
1153 /* - If !servicing */
1154 if(events_request
->servicing
== FALSE
) {
1155 /* - begin request hooks called
1156 * - servicing = TRUE
1158 lttv_hooks_call(events_request
->before_request
, (gpointer
)ts
);
1159 events_request
->servicing
= TRUE
;
1161 /* call before chunk
1162 * events hooks added
1164 //TODO ybrosseau 2012-07-10: || TRUE added since we only support
1165 // traceset wide requests
1166 if(events_request
->trace
== -1 || TRUE
)
1167 lttv_process_traceset_begin(ts
,
1168 events_request
->before_chunk_traceset
,
1169 events_request
->before_chunk_trace
,
1170 events_request
->event
1173 guint nb_trace
= lttv_traceset_number(ts
);
1174 g_assert((guint
)events_request
->trace
< nb_trace
&&
1175 events_request
->trace
> -1);
1176 LttvTrace
* trace
= lttv_traceset_get(ts
,events_request
->trace
);
1178 lttv_hooks_call(events_request
->before_chunk_traceset
, ts
);
1180 lttv_trace_add_hooks(trace
,
1181 events_request
->before_chunk_trace
,
1183 events_request
->event
);
1193 GSList
*remove_iter
= iter
;
1195 iter
= g_slist_next(iter
);
1196 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
1197 list_out
= g_slist_remove_link(list_out
, remove_iter
);
1198 } else { // not remove
1199 iter
= g_slist_next(iter
);
1205 /* 3. Find end criterions */
1210 /* 3.1.1 Find lowest end time in list_in */
1211 g_assert(g_slist_length(list_in
)>0);
1212 end_time
= ((EventsRequest
*)g_slist_nth_data(list_in
,0))->end_time
;
1214 for(iter
=g_slist_nth(list_in
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
1215 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1217 if(ltt_time_compare(events_request
->end_time
,
1219 end_time
= events_request
->end_time
;
1222 /* 3.1.2 Find lowest start time in list_out */
1223 for(iter
=list_out
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
1224 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1226 if(ltt_time_compare(events_request
->start_time
,
1228 end_time
= events_request
->start_time
;
1233 /* 3.2 Number of events */
1235 /* 3.2.1 Find lowest number of events in list_in */
1238 end_nb_events
= ((EventsRequest
*)g_slist_nth_data(list_in
,0))->num_events
;
1240 for(iter
=g_slist_nth(list_in
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
1241 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1243 if(events_request
->num_events
< end_nb_events
)
1244 end_nb_events
= events_request
->num_events
;
1247 /* 3.2.2 Use min(CHUNK_NUM_EVENTS, min num events in list_in) as
1250 end_nb_events
= MIN(CHUNK_NUM_EVENTS
, end_nb_events
);
1254 /* 3.3 End position */
1256 /* 3.3.1 Find lowest end position in list_in */
1259 end_position
=((EventsRequest
*)g_slist_nth_data(list_in
,0))->end_position
;
1261 for(iter
=g_slist_nth(list_in
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
1262 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1264 if(events_request
->end_position
!= NULL
&& end_position
!= NULL
&&
1265 lttv_traceset_position_time_compare(events_request
->end_position
,
1267 end_position
= events_request
->end_position
;
1272 /* 3.3.2 Find lowest start position in list_out */
1275 for(iter
=list_out
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
1276 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1278 if(events_request
->end_position
!= NULL
&& end_position
!= NULL
&&
1279 lttv_traceset_position_time_compare(events_request
->end_position
,
1281 end_position
= events_request
->end_position
;
1286 /* 4. Call process traceset middle */
1287 g_debug("Calling process traceset middle with %p, %lu sec %lu nsec, %u nb ev, %p end pos", ts
, end_time
.tv_sec
, end_time
.tv_nsec
, end_nb_events
, end_position
);
1288 count
= lttv_process_traceset_middle(ts
, end_time
, end_nb_events
, end_position
);
1290 #ifdef BABEL_CLEANUP
1291 tfc
= lttv_traceset_context_get_current_tfc(tsc
);
1293 g_debug("Context time after middle : %lu, %lu", tfc
->timestamp
.tv_sec
,
1294 tfc
->timestamp
.tv_nsec
);
1296 g_debug("End of trace reached after middle.");
1301 /* 5. After process traceset middle */
1303 /* - if the iterator is not valid anymore (got to the end) */
1304 if(bt_ctf_iter_read_event(ts
->iter
) == NULL
) {
1305 /* - For each req in list_in */
1306 GSList
*iter
= list_in
;
1308 while(iter
!= NULL
) {
1310 gboolean remove
= FALSE
;
1311 gboolean free_data
= FALSE
;
1312 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1314 /* - Remove events hooks for req
1315 * - Call end chunk for req
1317 //TODO ybrosseau 2012-07-10: || TRUE added since we only support
1318 // traceset wide requests
1319 if(events_request
->trace
== -1 || TRUE
)
1320 lttv_process_traceset_end(ts
,
1321 events_request
->after_chunk_traceset
,
1322 events_request
->after_chunk_trace
,
1324 events_request
->event
);
1327 guint nb_trace
= lttv_traceset_number(ts
);
1328 g_assert(events_request
->trace
< nb_trace
&&
1329 events_request
->trace
> -1);
1330 LttvTrace
*trace
= lttv_traceset_get(ts
,events_request
->trace
);
1332 lttv_trace_remove_hooks(trace
,
1333 events_request
->after_chunk_trace
,
1335 events_request
->event
);
1337 lttv_hooks_call(events_request
->after_chunk_traceset
, ts
);
1342 /* - Call end request for req */
1343 lttv_hooks_call(events_request
->after_request
, (gpointer
)ts
);
1345 /* - remove req from list_in */
1346 /* Destroy the request */
1353 GSList
*remove_iter
= iter
;
1355 iter
= g_slist_next(iter
);
1356 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
1357 list_in
= g_slist_remove_link(list_in
, remove_iter
);
1358 } else { // not remove
1359 iter
= g_slist_next(iter
);
1364 /* 5.1 For each req in list_in */
1365 GSList
*iter
= list_in
;
1367 while(iter
!= NULL
) {
1369 gboolean remove
= FALSE
;
1370 gboolean free_data
= FALSE
;
1371 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1373 /* - Remove events hooks for req
1374 * - Call end chunk for req
1376 //TODO ybrosseau 2012-07-10: || TRUE added since we only support
1377 // traceset wide requests
1378 if(events_request
->trace
== -1 || TRUE
) {
1379 lttv_process_traceset_end(ts
,
1380 events_request
->after_chunk_traceset
,
1381 events_request
->after_chunk_trace
,
1382 events_request
->event
);
1384 guint nb_trace
= lttv_traceset_number(ts
);
1385 g_assert(events_request
->trace
< nb_trace
&&
1386 events_request
->trace
> -1);
1387 LttvTrace
*trace
= lttv_traceset_get(ts
, events_request
->trace
);
1389 lttv_trace_remove_hooks(trace
,
1390 events_request
->after_chunk_trace
,
1392 events_request
->event
);
1395 lttv_hooks_call(events_request
->after_chunk_traceset
, ts
);
1398 /* - req.num -= count */
1399 g_assert(events_request
->num_events
>= count
);
1400 events_request
->num_events
-= count
;
1402 //g_assert(tfc != NULL);
1403 /* - if req.num == 0
1405 * current context time >= req.end time
1407 * req.end pos == current pos
1409 * req.stop_flag == TRUE
1411 if( events_request
->num_events
== 0
1413 events_request
->stop_flag
== TRUE
1415 ltt_time_compare(lttv_traceset_get_current_time(ts
),
1416 events_request
->end_time
) >= 0
1418 (events_request
->end_position
!= NULL
1420 lttv_traceset_position_compare_current(ts
,
1421 events_request
->end_position
) == 0)
1424 g_assert(events_request
->servicing
== TRUE
);
1425 /* - Call end request for req
1426 * - remove req from list_in */
1427 lttv_hooks_call(events_request
->after_request
, (gpointer
)ts
);
1428 /* - remove req from list_in */
1429 /* Destroy the request */
1437 GSList
*remove_iter
= iter
;
1439 iter
= g_slist_next(iter
);
1440 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
1441 list_in
= g_slist_remove_link(list_in
, remove_iter
);
1442 } else { // not remove
1443 iter
= g_slist_next(iter
);
1449 /* End of removed servicing loop : leave control to GTK instead. */
1450 // if(gtk_events_pending()) break;
1453 /* B. When interrupted between chunks */
1456 GSList
*iter
= list_in
;
1458 /* 1. for each request in list_in */
1459 while(iter
!= NULL
) {
1461 gboolean remove
= FALSE
;
1462 gboolean free_data
= FALSE
;
1463 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1465 /* 1.1. Use current postition as start position */
1466 if(events_request
->start_position
!= NULL
)
1467 lttv_traceset_destroy_position(events_request
->start_position
);
1468 events_request
->start_position
= lttv_traceset_create_current_position(ts
);
1471 /* 1.2. Remove start time */
1472 events_request
->start_time
= ltt_time_infinite
;
1474 /* 1.3. Move from list_in to list_out */
1477 list_out
= g_slist_append(list_out
, events_request
);
1482 GSList
*remove_iter
= iter
;
1484 iter
= g_slist_next(iter
);
1485 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
1486 list_in
= g_slist_remove_link(list_in
, remove_iter
);
1487 } else { // not remove
1488 iter
= g_slist_next(iter
);
1494 /* C Unlock Traces */
1496 #ifdef BABEL_CLEANUP
1497 lttv_process_traceset_get_sync_data(tsc
);
1499 //lttv_traceset_context_position_save(tsc, sync_position);
1504 iter_trace
<lttv_traceset_number(ts
);
1506 LttvTrace
*trace_v
= lttv_traceset_get(ts
, iter_trace
);
1508 lttvwindowtraces_unlock(trace_v
);
1512 //set the cursor back to normal
1513 gdk_window_set_cursor(win
, NULL
);
1516 g_assert(g_slist_length(list_in
) == 0);
1518 if( g_slist_length(list_out
) == 0 ) {
1519 /* Put tab's request pending flag back to normal */
1520 tab
->events_request_pending
= FALSE
;
1521 g_debug("remove the idle fct");
1522 return FALSE
; /* Remove the idle function */
1524 g_debug("leave the idle fct");
1525 return TRUE
; /* Leave the idle function */
1527 /* We do not use simili-round-robin, it may require to read 1 meg buffers
1528 * again and again if many tracesets use the same tracefiles. */
1529 /* Hack for round-robin idle functions */
1530 /* It will put the idle function at the end of the pool */
1531 /*g_idle_add_full((G_PRIORITY_HIGH_IDLE + 21),
1532 (GSourceFunc)execute_events_requests,
1542 #ifdef BABEL_CLEANUP
1544 Manage the periodic update of a live trace
1547 live_trace_update_handler(Tab
*tab
)
1550 unsigned int updated_count
;
1551 LttvTracesetContext
*tsc
= LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
1552 TimeInterval initial_time_span
= tsc
->time_span
;
1553 TimeInterval updated_time_span
;
1555 updated_count
= lttv_process_traceset_update(tsc
);
1557 /* TODO ybrosseau 2011-01-12: Add trace resynchronization */
1559 /* Get the changed period bounds */
1560 updated_time_span
= tsc
->time_span
;
1562 if(ltt_time_compare(updated_time_span
.start_time
,
1563 initial_time_span
.start_time
) != 0) {
1564 /* The initial time should not change on a live update */
1568 /* Notify viewers (only on updates) */
1569 if(ltt_time_compare(updated_time_span
.end_time
,
1570 initial_time_span
.end_time
) != 0) {
1572 notify_time_span_changed(tab
);
1573 /* TODO ybrosseau 2011-01-12: Change the timebar to register
1574 to the time_span hook */
1575 timebar_set_minmax_time(TIMEBAR(tab
->MTimebar
),
1576 &updated_time_span
.start_time
,
1577 &updated_time_span
.end_time
);
1579 /* To update the min max */
1580 time_change_manager(tab
, tab
->time_window
);
1583 /* Timer will be recalled as long as there is files to update */
1584 return (updated_count
> 0);
1586 #endif /* BABEL_CLEANUP */
1587 #ifdef BABEL_CLEANUP
1588 static void lttvwindow_add_trace(Tab
*tab
, LttvTrace
*trace_v
)
1591 LttvTraceset
*traceset
= tab
->traceset_info
->traceset
;
1593 guint num_traces
= lttv_traceset_number(traceset
);
1595 //Verify if trace is already present.
1596 for(i
=0; i
<num_traces
; i
++)
1598 LttvTrace
* trace
= lttv_traceset_get(traceset
, i
);
1599 if(trace
== trace_v
)
1603 //Keep a reference to the traces so they are not freed.
1604 for(i
=0; i
<lttv_traceset_number(traceset
); i
++)
1606 LttvTrace
* trace
= lttv_traceset_get(traceset
, i
);
1607 lttv_trace_ref(trace
);
1610 //remove state update hooks
1611 lttv_state_remove_event_hooks(
1612 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1614 lttv_context_fini(LTTV_TRACESET_CONTEXT(
1615 tab
->traceset_info
->traceset_context
));
1616 g_object_unref(tab
->traceset_info
->traceset_context
);
1618 lttv_traceset_add(traceset
, trace_v
);
1619 lttv_trace_ref(trace_v
); /* local ref */
1621 /* Create new context */
1622 tab
->traceset_info
->traceset_context
=
1623 g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
1625 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->
1630 //add state update hooks
1631 lttv_state_add_event_hooks(
1632 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1633 //Remove local reference to the traces.
1634 for(i
=0; i
<lttv_traceset_number(traceset
); i
++)
1636 LttvTrace
* trace
= lttv_traceset_get(traceset
, i
);
1637 lttv_trace_unref(trace
);
1641 //add_trace_into_traceset_selector(GTK_MULTIVPANED(tab->multivpaned), lttv_trace(trace_v));
1644 if (lttv_trace(trace_v
)->is_live
) {
1645 /* Add timer for live update */
1646 /* TODO ybrosseau 2011-01-12: Parametrize the hardcoded 1 seconds */
1647 g_timeout_add_seconds (1,
1648 (GSourceFunc
) live_trace_update_handler
,
1653 #endif /* BABEL_CLEANUP */
1654 /* add_trace adds a trace into the current traceset. It first displays a
1655 * directory selection dialogue to let user choose a trace, then recreates
1656 * tracset_context, and redraws all the viewer of the current tab
1659 void add_trace(GtkWidget
* widget
, gpointer user_data
)
1662 LttvTraceset
* traceset
= NULL
;
1664 char abs_path
[PATH_MAX
];
1666 MainWindow
* mw_data
= get_window_data_struct(widget
);
1667 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
1669 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
1670 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
1671 LttvPluginTab
*ptab
;
1675 ptab
= create_new_tab(widget
, NULL
);
1678 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
1682 /* Create a new traceset*/
1683 traceset
= tab
->traceset_info
->traceset
;
1684 if(traceset
== NULL
) {
1685 traceset
= lttv_traceset_new();
1687 /* File open dialog management */
1688 #ifdef BABEL_CLEANUP
1689 GtkWidget
*extra_live_button
;
1690 #endif //babel_cleanup
1691 GtkFileChooser
* file_chooser
=
1693 gtk_file_chooser_dialog_new ("Select a trace",
1694 GTK_WINDOW(mw_data
->mwindow
),
1695 GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER
,
1696 GTK_STOCK_CANCEL
, GTK_RESPONSE_CANCEL
,
1697 GTK_STOCK_OPEN
, GTK_RESPONSE_ACCEPT
,
1699 #ifdef BABEL_CLEANUP
1700 /* Button to indicate the opening of a live trace */
1701 extra_live_button
= gtk_check_button_new_with_mnemonic ("Trace is live (currently being writen)");
1702 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (extra_live_button
), FALSE
);
1703 gtk_file_chooser_set_extra_widget (GTK_FILE_CHOOSER (file_chooser
), extra_live_button
);
1704 #endif //babel_cleanup
1705 gtk_file_chooser_set_show_hidden (file_chooser
, TRUE
);
1706 if(remember_trace_dir
[0] != '\0')
1707 gtk_file_chooser_set_filename(file_chooser
, remember_trace_dir
);
1709 gboolean closeFileChooserDialog
= TRUE
;
1713 id
= gtk_dialog_run(GTK_DIALOG(file_chooser
));
1715 case GTK_RESPONSE_ACCEPT
:
1716 case GTK_RESPONSE_OK
:
1717 path
= gtk_file_chooser_get_filename (file_chooser
);
1719 strncpy(remember_trace_dir
, path
, PATH_MAX
);
1720 strncat(remember_trace_dir
, "/", PATH_MAX
);
1721 if(!path
|| strlen(path
) == 0){
1724 get_absolute_pathname(path
, abs_path
);
1726 if(lttv_traceset_add_path(traceset
,abs_path
) != 0 ){ /*failure*/
1728 g_warning("cannot open trace %s", abs_path
);
1729 strncpy(remember_trace_dir
, "\0", PATH_MAX
);
1730 GtkWidget
*dialogue
=
1731 gtk_message_dialog_new(
1732 GTK_WINDOW(gtk_widget_get_toplevel(widget
)),
1733 GTK_DIALOG_MODAL
|GTK_DIALOG_DESTROY_WITH_PARENT
,
1736 "Cannot open trace : maybe you should enter in the directory "
1738 gtk_dialog_run(GTK_DIALOG(dialogue
));
1739 gtk_widget_destroy(dialogue
);
1740 closeFileChooserDialog
= FALSE
;
1743 closeFileChooserDialog
= TRUE
;
1744 SetTraceset(tab
, traceset
);
1747 //update current tab
1748 //update_traceset(mw_data);
1750 // in expose now call_pending_read_hooks(mw_data);
1752 //lttvwindow_report_current_time(mw_data,&(tab->current_time));
1754 case GTK_RESPONSE_REJECT
:
1755 case GTK_RESPONSE_CANCEL
:
1757 closeFileChooserDialog
= TRUE
;
1760 }while(!closeFileChooserDialog
);
1762 gtk_widget_destroy((GtkWidget
*)file_chooser
);
1766 /* remove_trace removes a trace from the current traceset if all viewers in
1767 * the current tab are not interested in the trace. It first displays a
1768 * dialogue, which shows all traces in the current traceset, to let user choose
1769 * a trace, then it checks if all viewers unselect the trace, if it is true,
1770 * it will remove the trace, recreate the traceset_contex,
1771 * and redraws all the viewer of the current tab. If there is on trace in the
1772 * current traceset, it will delete all viewers of the current tab
1774 * It destroys the filter tree. FIXME... we should request for an update
1778 void remove_trace(GtkWidget
*widget
, gpointer user_data
)
1780 #ifdef BABEL_CLEANUP
1782 LttvTrace
* trace_v
;
1783 LttvTraceset
* traceset
;
1784 gint i
, j
, nb_trace
, index
=-1;
1785 char ** name
, *remove_trace_name
;
1786 MainWindow
* mw_data
= get_window_data_struct(widget
);
1787 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
1789 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
1790 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
1796 LttvPluginTab
*ptab
;
1797 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
1801 nb_trace
=lttv_traceset_number(tab
->traceset_info
->traceset
);
1802 name
= g_new(char*,nb_trace
);
1803 for(i
= 0; i
< nb_trace
; i
++){
1804 trace_v
= lttv_traceset_get(tab
->traceset_info
->traceset
, i
);
1805 trace
= lttv_trace(trace_v
);
1806 name
[i
] = (char *) g_quark_to_string(ltt_trace_name(trace
));
1809 remove_trace_name
= get_remove_trace(mw_data
, name
, nb_trace
);
1812 if(remove_trace_name
){
1814 /* yuk, cut n paste from old code.. should be better (MD)*/
1815 for(i
= 0; i
<nb_trace
; i
++) {
1816 if(strcmp(remove_trace_name
,name
[i
]) == 0){
1821 traceset
= tab
->traceset_info
->traceset
;
1822 //Keep a reference to the traces so they are not freed.
1823 for(j
=0; j
<lttv_traceset_number(traceset
); j
++)
1825 LttvTrace
* trace
= lttv_traceset_get(traceset
, j
);
1826 lttv_trace_ref(trace
);
1829 //remove state update hooks
1830 lttv_state_remove_event_hooks(
1831 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1832 lttv_context_fini(LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
));
1833 g_object_unref(tab
->traceset_info
->traceset_context
);
1835 trace_v
= lttv_traceset_get(traceset
, index
);
1837 lttv_traceset_remove(traceset
, index
);
1838 lttv_trace_unref(trace_v
); // Remove local reference
1840 if(lttv_trace_get_ref_number(trace_v
) <= 1) {
1841 /* ref 1 : lttvwindowtraces only*/
1842 ltt_trace_close(lttv_trace(trace_v
));
1843 /* lttvwindowtraces_remove_trace takes care of destroying
1844 * the traceset linked with the trace_v and also of destroying
1845 * the trace_v at the same time.
1847 lttvwindowtraces_remove_trace(trace_v
);
1850 tab
->traceset_info
->traceset_context
=
1851 g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
1853 LTTV_TRACESET_CONTEXT(tab
->
1854 traceset_info
->traceset_context
),traceset
);
1855 //add state update hooks
1856 lttv_state_add_event_hooks(
1857 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1859 //Remove local reference to the traces.
1860 for(j
=0; j
<lttv_traceset_number(traceset
); j
++)
1862 LttvTrace
* trace
= lttv_traceset_get(traceset
, j
);
1863 lttv_trace_unref(trace
);
1866 SetTraceset(tab
, (gpointer
)traceset
);
1869 #endif /* BABEL_CLEANUP */
1873 void remove_trace(GtkWidget
* widget
, gpointer user_data
)
1876 LttvTrace
* trace_v
;
1877 LttvTraceset
* traceset
;
1878 gint i
, j
, nb_trace
;
1879 char ** name
, *remove_trace_name
;
1880 MainWindow
* mw_data
= get_window_data_struct(widget
);
1881 LttvTracesetSelector
* s
;
1882 LttvTraceSelector
* t
;
1885 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
1887 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
1888 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
1894 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
1897 nb_trace
=lttv_traceset_number(tab
->traceset_info
->traceset
);
1898 name
= g_new(char*,nb_trace
);
1899 for(i
= 0; i
< nb_trace
; i
++){
1900 trace_v
= lttv_traceset_get(tab
->traceset_info
->traceset
, i
);
1901 trace
= lttv_trace(trace_v
);
1902 name
[i
] = ltt_trace_name(trace
);
1905 remove_trace_name
= get_remove_trace(name
, nb_trace
);
1907 if(remove_trace_name
){
1908 for(i
=0; i
<nb_trace
; i
++){
1909 if(strcmp(remove_trace_name
,name
[i
]) == 0){
1910 //unselect the trace from the current viewer
1912 w
= gtk_multivpaned_get_widget(GTK_MULTIVPANED(tab
->multivpaned
));
1914 s
= g_object_get_data(G_OBJECT(w
), "Traceset_Selector");
1916 t
= lttv_traceset_selector_trace_get(s
,i
);
1917 lttv_trace_selector_set_selected(t
, FALSE
);
1920 //check if other viewers select the trace
1921 w
= gtk_multivpaned_get_first_widget(GTK_MULTIVPANED(tab
->multivpaned
));
1923 s
= g_object_get_data(G_OBJECT(w
), "Traceset_Selector");
1925 t
= lttv_traceset_selector_trace_get(s
,i
);
1926 selected
= lttv_trace_selector_get_selected(t
);
1929 w
= gtk_multivpaned_get_next_widget(GTK_MULTIVPANED(tab
->multivpaned
));
1931 }else selected
= FALSE
;
1933 //if no viewer selects the trace, remove it
1935 remove_trace_from_traceset_selector(GTK_MULTIVPANED(tab
->multivpaned
), i
);
1937 traceset
= tab
->traceset_info
->traceset
;
1938 //Keep a reference to the traces so they are not freed.
1939 for(j
=0; j
<lttv_traceset_number(traceset
); j
++)
1941 LttvTrace
* trace
= lttv_traceset_get(traceset
, j
);
1942 lttv_trace_ref(trace
);
1945 //remove state update hooks
1946 lttv_state_remove_event_hooks(
1947 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1948 lttv_context_fini(LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
));
1949 g_object_unref(tab
->traceset_info
->traceset_context
);
1952 trace_v
= lttv_traceset_get(traceset
, i
);
1954 if(lttv_trace_get_ref_number(trace_v
) <= 2) {
1955 /* ref 2 : traceset, local */
1956 lttvwindowtraces_remove_trace(trace_v
);
1957 ltt_trace_close(lttv_trace(trace_v
));
1960 lttv_traceset_remove(traceset
, i
);
1961 lttv_trace_unref(trace_v
); // Remove local reference
1963 if(!lttv_trace_get_ref_number(trace_v
))
1964 lttv_trace_destroy(trace_v
);
1966 tab
->traceset_info
->traceset_context
=
1967 g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
1969 LTTV_TRACESET_CONTEXT(tab
->
1970 traceset_info
->traceset_context
),traceset
);
1971 //add state update hooks
1972 lttv_state_add_event_hooks(
1973 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1975 //Remove local reference to the traces.
1976 for(j
=0; j
<lttv_traceset_number(traceset
); j
++)
1978 LttvTrace
* trace
= lttv_traceset_get(traceset
, j
);
1979 lttv_trace_unref(trace
);
1983 //update current tab
1984 //update_traceset(mw_data);
1987 SetTraceset(tab
, (gpointer
)traceset
);
1988 // in expose now call_pending_read_hooks(mw_data);
1990 //lttvwindow_report_current_time(mw_data,&(tab->current_time));
1993 // while(tab->multi_vpaned->num_children){
1994 // gtk_multi_vpaned_widget_delete(tab->multi_vpaned);
2008 /* Redraw all the viewers in the current tab */
2009 void redraw(GtkWidget
*widget
, gpointer user_data
)
2011 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
2012 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2013 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2020 LttvPluginTab
*ptab
;
2021 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
2026 LttvAttributeValue value
;
2028 retval
= lttv_iattribute_find_by_path(tab
->attributes
, "hooks/redraw", LTTV_POINTER
, &value
);
2031 tmp
= (LttvHooks
*)*(value
.v_pointer
);
2033 lttv_hooks_call(tmp
,NULL
);
2037 void continue_processing(GtkWidget
*widget
, gpointer user_data
)
2039 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
2040 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2041 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2048 LttvPluginTab
*ptab
;
2049 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
2054 LttvAttributeValue value
;
2056 retval
= lttv_iattribute_find_by_path(tab
->attributes
, "hooks/continue",
2057 LTTV_POINTER
, &value
);
2060 tmp
= (LttvHooks
*)*(value
.v_pointer
);
2062 lttv_hooks_call(tmp
,NULL
);
2065 /* Stop the processing for the calling main window's current tab.
2066 * It removes every processing requests that are in its list. It does not call
2067 * the end request hooks, because the request is not finished.
2070 void stop_processing(GtkWidget
*widget
, gpointer user_data
)
2072 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
2073 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2074 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2079 LttvPluginTab
*ptab
;
2080 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
2083 GSList
*iter
= tab
->events_requests
;
2085 while(iter
!= NULL
) {
2086 GSList
*remove_iter
= iter
;
2087 iter
= g_slist_next(iter
);
2089 g_free(remove_iter
->data
);
2090 tab
->events_requests
=
2091 g_slist_remove_link(tab
->events_requests
, remove_iter
);
2093 tab
->events_request_pending
= FALSE
;
2094 tab
->stop_foreground
= TRUE
;
2095 g_idle_remove_by_data(tab
);
2096 g_assert(g_slist_length(tab
->events_requests
) == 0);
2100 /* save will save the traceset to a file
2101 * Not implemented yet FIXME
2104 void save(GtkWidget
* widget
, gpointer user_data
)
2109 void save_as(GtkWidget
* widget
, gpointer user_data
)
2111 g_info("Save as\n");
2115 /* zoom will change the time_window of all the viewers of the
2116 * current tab, and redisplay them. The main functionality is to
2117 * determine the new time_window of the current tab
2120 void zoom(GtkWidget
* widget
, double size
)
2123 TimeInterval time_span
;
2124 TimeWindow new_time_window
;
2125 LttTime current_time
, time_delta
;
2127 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
2129 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2130 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2136 LttvPluginTab
*ptab
;
2137 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
2141 if(size
== 1) return;
2143 ts
= lttvwindow_get_traceset(tab
);
2144 time_span
= lttv_traceset_get_time_span_real(ts
);
2145 new_time_window
= tab
->time_window
;
2146 current_time
= tab
->current_time
;
2148 time_delta
= ltt_time_sub(time_span
.end_time
,time_span
.start_time
);
2150 new_time_window
.start_time
= time_span
.start_time
;
2151 new_time_window
.time_width
= time_delta
;
2152 new_time_window
.time_width_double
= ltt_time_to_double(time_delta
);
2153 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
2154 new_time_window
.time_width
) ;
2156 new_time_window
.time_width
= ltt_time_div(new_time_window
.time_width
, size
);
2157 new_time_window
.time_width_double
=
2158 ltt_time_to_double(new_time_window
.time_width
);
2159 if(ltt_time_compare(new_time_window
.time_width
,time_delta
) > 0)
2160 { /* Case where zoom out is bigger than trace length */
2161 new_time_window
.start_time
= time_span
.start_time
;
2162 new_time_window
.time_width
= time_delta
;
2163 new_time_window
.time_width_double
= ltt_time_to_double(time_delta
);
2164 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
2165 new_time_window
.time_width
) ;
2169 /* Center the image on the current time */
2170 new_time_window
.start_time
=
2171 ltt_time_sub(current_time
,
2172 ltt_time_from_double(new_time_window
.time_width_double
/2.0));
2173 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
2174 new_time_window
.time_width
) ;
2175 /* If on borders, don't fall off */
2176 if(ltt_time_compare(new_time_window
.start_time
, time_span
.start_time
) <0
2177 || ltt_time_compare(new_time_window
.start_time
, time_span
.end_time
) >0)
2179 new_time_window
.start_time
= time_span
.start_time
;
2180 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
2181 new_time_window
.time_width
) ;
2185 if(ltt_time_compare(new_time_window
.end_time
,
2186 time_span
.end_time
) > 0
2187 || ltt_time_compare(new_time_window
.end_time
,
2188 time_span
.start_time
) < 0)
2190 new_time_window
.start_time
=
2191 ltt_time_sub(time_span
.end_time
, new_time_window
.time_width
);
2193 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
2194 new_time_window
.time_width
) ;
2201 if(ltt_time_compare(new_time_window
.time_width
, ltt_time_zero
) == 0) {
2202 g_warning("Zoom more than 1 ns impossible");
2204 time_change_manager(tab
, new_time_window
);
2208 void zoom_in(GtkWidget
* widget
, gpointer user_data
)
2213 void zoom_out(GtkWidget
* widget
, gpointer user_data
)
2218 void zoom_extended(GtkWidget
* widget
, gpointer user_data
)
2223 void go_to_time(GtkWidget
* widget
, gpointer user_data
)
2225 g_info("Go to time\n");
2228 void show_time_frame(GtkWidget
* widget
, gpointer user_data
)
2230 g_info("Show time frame\n");
2234 /* callback function */
2237 on_empty_traceset_activate (GtkMenuItem
*menuitem
,
2240 create_new_window((GtkWidget
*)menuitem
, user_data
, FALSE
);
2245 on_clone_traceset_activate (GtkMenuItem
*menuitem
,
2248 create_new_window((GtkWidget
*)menuitem
, user_data
, TRUE
);
2252 /* create_new_tab calls create_tab to construct a new tab in the main window
2255 LttvPluginTab
*create_new_tab(GtkWidget
* widget
, gpointer user_data
)
2257 gchar label
[PATH_MAX
];
2258 MainWindow
* mw_data
= get_window_data_struct(widget
);
2260 GtkNotebook
* notebook
= (GtkNotebook
*)lookup_widget(widget
, "MNotebook");
2261 if(notebook
== NULL
){
2262 g_info("Notebook does not exist\n");
2265 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2266 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2269 if(!page
|| TRUE
) {
2272 LttvPluginTab
*ptab
;
2273 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
2274 copy_tab
= ptab
->tab
;
2277 strcpy(label
,"Page");
2278 if(get_label(mw_data
, label
,"Get the name of the tab","Please input tab's name")) {
2279 LttvPluginTab
*ptab
;
2281 ptab
= g_object_new(LTTV_TYPE_PLUGIN_TAB
, NULL
);
2282 init_tab (ptab
->tab
, mw_data
, copy_tab
, notebook
, label
);
2283 ptab
->parent
.top_widget
= ptab
->tab
->top_widget
;
2284 g_object_set_data_full(
2285 G_OBJECT(ptab
->tab
->vbox
),
2288 (GDestroyNotify
)tab_destructor
);
2295 on_tab_activate (GtkMenuItem
*menuitem
,
2298 create_new_tab((GtkWidget
*)menuitem
, user_data
);
2303 on_open_activate (GtkMenuItem
*menuitem
,
2306 #ifdef UNFINISHED_FEATURE
2307 open_traceset((GtkWidget
*)menuitem
, user_data
);
2313 on_close_activate (GtkMenuItem
*menuitem
,
2316 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2317 main_window_destructor(mw_data
);
2321 /* remove the current tab from the main window
2325 on_close_tab_activate (GtkWidget
*widget
,
2329 GtkWidget
* notebook
;
2330 notebook
= lookup_widget(widget
, "MNotebook");
2331 if(notebook
== NULL
){
2332 g_info("Notebook does not exist\n");
2336 page_num
= gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
));
2338 gtk_notebook_remove_page(GTK_NOTEBOOK(notebook
), page_num
);
2343 on_close_tab_X_clicked (GtkWidget
*widget
,
2347 GtkWidget
*notebook
= lookup_widget(widget
, "MNotebook");
2348 if(notebook
== NULL
){
2349 g_info("Notebook does not exist\n");
2353 if((page_num
= gtk_notebook_page_num(GTK_NOTEBOOK(notebook
), widget
)) != -1)
2354 gtk_notebook_remove_page(GTK_NOTEBOOK(notebook
), page_num
);
2360 on_add_trace_activate (GtkMenuItem
*menuitem
,
2363 add_trace((GtkWidget
*)menuitem
, user_data
);
2368 on_remove_trace_activate (GtkMenuItem
*menuitem
,
2371 remove_trace((GtkWidget
*)menuitem
, user_data
);
2376 on_save_activate (GtkMenuItem
*menuitem
,
2379 save((GtkWidget
*)menuitem
, user_data
);
2384 on_save_as_activate (GtkMenuItem
*menuitem
,
2387 save_as((GtkWidget
*)menuitem
, user_data
);
2392 on_quit_activate (GtkMenuItem
*menuitem
,
2395 while (g_slist_length(g_main_window_list
) != 0) {
2396 on_MWindow_destroy(((MainWindow
*)g_main_window_list
->data
)->mwindow
,
2403 on_cut_activate (GtkMenuItem
*menuitem
,
2411 on_copy_activate (GtkMenuItem
*menuitem
,
2419 on_paste_activate (GtkMenuItem
*menuitem
,
2427 on_delete_activate (GtkMenuItem
*menuitem
,
2435 on_zoom_in_activate (GtkMenuItem
*menuitem
,
2438 zoom_in((GtkWidget
*)menuitem
, user_data
);
2443 on_zoom_out_activate (GtkMenuItem
*menuitem
,
2446 zoom_out((GtkWidget
*)menuitem
, user_data
);
2451 on_zoom_extended_activate (GtkMenuItem
*menuitem
,
2454 zoom_extended((GtkWidget
*)menuitem
, user_data
);
2459 on_go_to_time_activate (GtkMenuItem
*menuitem
,
2462 go_to_time((GtkWidget
*)menuitem
, user_data
);
2467 on_show_time_frame_activate (GtkMenuItem
*menuitem
,
2470 show_time_frame((GtkWidget
*)menuitem
, user_data
);
2475 on_move_viewer_up_activate (GtkMenuItem
*menuitem
,
2478 move_up_viewer((GtkWidget
*)menuitem
, user_data
);
2483 on_move_viewer_down_activate (GtkMenuItem
*menuitem
,
2486 move_down_viewer((GtkWidget
*)menuitem
, user_data
);
2491 on_remove_viewer_activate (GtkMenuItem
*menuitem
,
2494 delete_viewer((GtkWidget
*)menuitem
, user_data
);
2498 on_trace_facility_activate (GtkMenuItem
*menuitem
,
2501 g_info("Trace facility selector: %s\n", "");
2505 /* Dispaly a file selection dialogue to let user select a library, then call
2506 * lttv_library_load().
2510 on_load_library_activate (GtkMenuItem
*menuitem
,
2513 GError
*error
= NULL
;
2514 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2516 gchar load_module_path_alter
[PATH_MAX
];
2520 gchar
*load_module_path
;
2521 name
= g_ptr_array_new();
2522 nb
= lttv_library_path_number();
2523 /* ask for the library path */
2527 path
= lttv_library_path_get(i
);
2528 g_ptr_array_add(name
, path
);
2531 load_module_path
= get_selection(mw_data
,
2532 (char **)(name
->pdata
), name
->len
,
2533 "Select a library path", "Library paths");
2534 if(load_module_path
!= NULL
)
2535 strncpy(load_module_path_alter
, load_module_path
, PATH_MAX
-1); // -1 for /
2537 g_ptr_array_free(name
, TRUE
);
2539 if(load_module_path
== NULL
) return;
2543 /* Make sure the module path ends with a / */
2544 gchar
*ptr
= load_module_path_alter
;
2546 ptr
= strchr(ptr
, '\0');
2548 if(*(ptr
-1) != '/') {
2555 /* Ask for the library to load : list files in the previously selected
2557 gchar str
[PATH_MAX
];
2560 GtkFileSelection
* file_selector
=
2561 (GtkFileSelection
*)gtk_file_selection_new("Select a module");
2562 gtk_file_selection_set_filename(file_selector
, load_module_path_alter
);
2563 gtk_file_selection_hide_fileop_buttons(file_selector
);
2565 gtk_window_set_transient_for(GTK_WINDOW(file_selector
),
2566 GTK_WINDOW(mw_data
->mwindow
));
2569 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
2571 case GTK_RESPONSE_ACCEPT
:
2572 case GTK_RESPONSE_OK
:
2573 dir
= gtk_file_selection_get_selections (file_selector
);
2574 strncpy(str
,dir
[0],PATH_MAX
);
2575 strncpy(remember_plugins_dir
,dir
[0],PATH_MAX
);
2576 /* only keep file name */
2578 str1
= strrchr(str
,'/');
2581 str1
= strrchr(str
,'\\');
2586 if(*str1
== 'l' && *(str1
+1)== 'i' && *(str1
+2)=='b')
2588 remove info after
. */
2592 str2
= strrchr(str2
, '.');
2593 if(str2
!= NULL
) *str2
= '\0';
2595 lttv_module_require(str1
, &error
);
2597 lttv_library_load(str1
, &error
);
2598 if(error
!= NULL
) g_warning("%s", error
->message
);
2599 else g_info("Load library: %s\n", str
);
2601 case GTK_RESPONSE_REJECT
:
2602 case GTK_RESPONSE_CANCEL
:
2604 gtk_widget_destroy((GtkWidget
*)file_selector
);
2615 /* Display all loaded modules, let user to select a module to unload
2616 * by calling lttv_module_unload
2620 on_unload_library_activate (GtkMenuItem
*menuitem
,
2623 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2625 LttvLibrary
*library
= NULL
;
2630 name
= g_ptr_array_new();
2631 nb
= lttv_library_number();
2632 LttvLibraryInfo
*lib_info
= g_new(LttvLibraryInfo
,nb
);
2633 /* ask for the library name */
2636 LttvLibrary
*iter_lib
= lttv_library_get(i
);
2637 lttv_library_info(iter_lib
, &lib_info
[i
]);
2639 gchar
*path
= lib_info
[i
].name
;
2640 g_ptr_array_add(name
, path
);
2642 lib_name
= get_selection(mw_data
, (char **)(name
->pdata
), name
->len
,
2643 "Select a library", "Libraries");
2644 if(lib_name
!= NULL
) {
2646 if(strcmp(lib_name
, lib_info
[i
].name
) == 0) {
2647 library
= lttv_library_get(i
);
2652 g_ptr_array_free(name
, TRUE
);
2655 if(lib_name
== NULL
) return;
2657 if(library
!= NULL
) lttv_library_unload(library
);
2661 /* Dispaly a file selection dialogue to let user select a module, then call
2662 * lttv_module_require().
2666 on_load_module_activate (GtkMenuItem
*menuitem
,
2669 GError
*error
= NULL
;
2670 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2672 LttvLibrary
*library
= NULL
;
2677 name
= g_ptr_array_new();
2678 nb
= lttv_library_number();
2679 LttvLibraryInfo
*lib_info
= g_new(LttvLibraryInfo
,nb
);
2680 /* ask for the library name */
2683 LttvLibrary
*iter_lib
= lttv_library_get(i
);
2684 lttv_library_info(iter_lib
, &lib_info
[i
]);
2686 gchar
*path
= lib_info
[i
].name
;
2687 g_ptr_array_add(name
, path
);
2689 lib_name
= get_selection(mw_data
,(char **)(name
->pdata
), name
->len
,
2690 "Select a library", "Libraries");
2691 if(lib_name
!= NULL
) {
2693 if(strcmp(lib_name
, lib_info
[i
].name
) == 0) {
2694 library
= lttv_library_get(i
);
2699 g_ptr_array_free(name
, TRUE
);
2702 if(lib_name
== NULL
) return;
2705 //LttvModule *module;
2706 gchar module_name_out
[PATH_MAX
];
2708 /* Ask for the module to load : list modules in the selected lib */
2712 nb
= lttv_library_module_number(library
);
2713 LttvModuleInfo
*module_info
= g_new(LttvModuleInfo
,nb
);
2714 name
= g_ptr_array_new();
2715 /* ask for the module name */
2718 LttvModule
*iter_module
= lttv_library_module_get(library
, i
);
2719 lttv_module_info(iter_module
, &module_info
[i
]);
2721 gchar
*path
= module_info
[i
].name
;
2722 g_ptr_array_add(name
, path
);
2724 module_name
= get_selection(mw_data
, (char **)(name
->pdata
), name
->len
,
2725 "Select a module", "Modules");
2726 if(module_name
!= NULL
) {
2728 if(strcmp(module_name
, module_info
[i
].name
) == 0) {
2729 strncpy(module_name_out
, module_name
, PATH_MAX
);
2730 //module = lttv_library_module_get(i);
2736 g_ptr_array_free(name
, TRUE
);
2737 g_free(module_info
);
2739 if(module_name
== NULL
) return;
2742 lttv_module_require(module_name_out
, &error
);
2743 if(error
!= NULL
) g_warning("%s", error
->message
);
2744 else g_info("Load module: %s", module_name_out
);
2751 gchar str
[PATH_MAX
];
2754 GtkFileSelection
* file_selector
=
2755 (GtkFileSelection
*)gtk_file_selection_new("Select a module");
2756 gtk_file_selection_set_filename(file_selector
, load_module_path_alter
);
2757 gtk_file_selection_hide_fileop_buttons(file_selector
);
2760 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
2762 case GTK_RESPONSE_ACCEPT
:
2763 case GTK_RESPONSE_OK
:
2764 dir
= gtk_file_selection_get_selections (file_selector
);
2765 strncpy(str
,dir
[0],PATH_MAX
);
2766 strncpy(remember_plugins_dir
,dir
[0],PATH_MAX
);
2768 /* only keep file name */
2770 str1
= strrchr(str
,'/');
2773 str1
= strrchr(str
,'\\');
2778 if(*str1
== 'l' && *(str1
+1)== 'i' && *(str1
+2)=='b')
2780 remove info after
. */
2784 str2
= strrchr(str2
, '.');
2785 if(str2
!= NULL
) *str2
= '\0';
2787 lttv_module_require(str1
, &error
);
2789 lttv_library_load(str1
, &error
);
2790 if(error
!= NULL
) g_warning(error
->message
);
2791 else g_info("Load library: %s\n", str
);
2793 case GTK_RESPONSE_REJECT
:
2794 case GTK_RESPONSE_CANCEL
:
2796 gtk_widget_destroy((GtkWidget
*)file_selector
);
2808 /* Display all loaded modules, let user to select a module to unload
2809 * by calling lttv_module_unload
2813 on_unload_module_activate (GtkMenuItem
*menuitem
,
2816 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2818 LttvLibrary
*library
= NULL
;
2823 name
= g_ptr_array_new();
2824 nb
= lttv_library_number();
2825 LttvLibraryInfo
*lib_info
= g_new(LttvLibraryInfo
,nb
);
2826 /* ask for the library name */
2829 LttvLibrary
*iter_lib
= lttv_library_get(i
);
2830 lttv_library_info(iter_lib
, &lib_info
[i
]);
2832 gchar
*path
= lib_info
[i
].name
;
2833 g_ptr_array_add(name
, path
);
2835 lib_name
= get_selection(mw_data
, (char **)(name
->pdata
), name
->len
,
2836 "Select a library", "Libraries");
2837 if(lib_name
!= NULL
) {
2839 if(strcmp(lib_name
, lib_info
[i
].name
) == 0) {
2840 library
= lttv_library_get(i
);
2845 g_ptr_array_free(name
, TRUE
);
2848 if(lib_name
== NULL
) return;
2851 LttvModule
*module
= NULL
;
2853 /* Ask for the module to load : list modules in the selected lib */
2857 nb
= lttv_library_module_number(library
);
2858 LttvModuleInfo
*module_info
= g_new(LttvModuleInfo
,nb
);
2859 name
= g_ptr_array_new();
2860 /* ask for the module name */
2863 LttvModule
*iter_module
= lttv_library_module_get(library
, i
);
2864 lttv_module_info(iter_module
, &module_info
[i
]);
2866 gchar
*path
= module_info
[i
].name
;
2867 if(module_info
[i
].use_count
> 0) g_ptr_array_add(name
, path
);
2869 module_name
= get_selection(mw_data
, (char **)(name
->pdata
), name
->len
,
2870 "Select a module", "Modules");
2871 if(module_name
!= NULL
) {
2873 if(strcmp(module_name
, module_info
[i
].name
) == 0) {
2874 module
= lttv_library_module_get(library
, i
);
2880 g_ptr_array_free(name
, TRUE
);
2881 g_free(module_info
);
2883 if(module_name
== NULL
) return;
2886 LttvModuleInfo module_info
;
2887 lttv_module_info(module
, &module_info
);
2888 g_info("Release module: %s\n", module_info
.name
);
2890 lttv_module_release(module
);
2894 /* Display a directory dialogue to let user select a path for library searching
2898 on_add_library_search_path_activate (GtkMenuItem
*menuitem
,
2901 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2902 //GtkDirSelection * file_selector = (GtkDirSelection *)gtk_dir_selection_new("Select library path");
2903 GtkFileSelection
* file_selector
= (GtkFileSelection
*)gtk_file_selection_new("Select a trace");
2904 gtk_widget_hide( (file_selector
)->file_list
->parent
) ;
2906 gtk_window_set_transient_for(GTK_WINDOW(file_selector
),
2907 GTK_WINDOW(mw_data
->mwindow
));
2912 if(remember_plugins_dir
[0] != '\0')
2913 gtk_file_selection_set_filename(file_selector
, remember_plugins_dir
);
2915 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
2917 case GTK_RESPONSE_ACCEPT
:
2918 case GTK_RESPONSE_OK
:
2919 dir
= gtk_file_selection_get_filename (file_selector
);
2920 strncpy(remember_plugins_dir
,dir
,PATH_MAX
);
2921 strncat(remember_plugins_dir
,"/",PATH_MAX
);
2922 lttv_library_path_add(dir
);
2923 case GTK_RESPONSE_REJECT
:
2924 case GTK_RESPONSE_CANCEL
:
2926 gtk_widget_destroy((GtkWidget
*)file_selector
);
2932 /* Display a directory dialogue to let user select a path for library searching
2936 on_remove_library_search_path_activate (GtkMenuItem
*menuitem
,
2939 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2941 const char *lib_path
;
2945 name
= g_ptr_array_new();
2946 nb
= lttv_library_path_number();
2947 /* ask for the library name */
2950 gchar
*path
= lttv_library_path_get(i
);
2951 g_ptr_array_add(name
, path
);
2953 lib_path
= get_selection(mw_data
, (char **)(name
->pdata
), name
->len
,
2954 "Select a library path", "Library paths");
2956 g_ptr_array_free(name
, TRUE
);
2958 if(lib_path
== NULL
) return;
2961 lttv_library_path_remove(lib_path
);
2965 on_color_activate (GtkMenuItem
*menuitem
,
2973 on_save_configuration_activate (GtkMenuItem
*menuitem
,
2976 g_info("Save configuration\n");
2981 on_content_activate (GtkMenuItem
*menuitem
,
2984 char* filename
= NULL
,
2987 const char* relativePath
= "doc/user/user_guide/html/index.html";
2988 filename
= g_build_filename (g_get_current_dir(), relativePath
, NULL
);
2989 path
= g_strdup_printf ("ghelp://%s", filename
);
2991 screen
= gdk_screen_get_default();
2992 gtk_show_uri (screen
, path
, gtk_get_current_event_time(), NULL
);
2996 g_info("Content\n");
3001 on_about_activate (GtkMenuItem
*menuitem
,
3004 MainWindow
*main_window
= get_window_data_struct(GTK_WIDGET(menuitem
));
3006 gchar
* authors
[] = { "Yannick Brosseau",
3007 "Francis Deslauriers",
3010 "Benoit Des Ligneris",
3016 static const gchar
*comments
= "Trace visualiser for LTTng 2.x data\
3017 \nInspired from the original Linux Trace Toolkit Visualizer made by Karim Yaghmour";
3019 static const gchar
*copyright
= "Copyright \xc2\xa9 2004-2013";
3021 gtk_show_about_dialog((GtkWindow
*)main_window
->mwindow
,
3023 "comments", comments
,
3025 "program-name", "LTTV",
3026 "license", "GPLv2, see COPYING file for details",
3027 "website", "http://lttng.org/lttv/",
3028 "copyright", copyright
,
3034 on_button_new_clicked (GtkButton
*button
,
3037 #ifdef BABEL_CLEANUP
3038 create_new_window((GtkWidget
*)button
, user_data
, TRUE
);
3040 GtkWidget
*dialogue
=
3041 gtk_message_dialog_new(
3042 GTK_WINDOW(gtk_widget_get_toplevel((GtkWidget
*)button
)),
3043 GTK_DIALOG_MODAL
|GTK_DIALOG_DESTROY_WITH_PARENT
,
3046 "Opening multiple windows is disabled.");
3047 gtk_dialog_run(GTK_DIALOG(dialogue
));
3048 gtk_widget_destroy(dialogue
);
3053 on_button_new_tab_clicked (GtkButton
*button
,
3056 create_new_tab((GtkWidget
*)button
, user_data
);
3060 on_button_open_clicked (GtkButton
*button
,
3063 #ifdef UNFINISHED_FEATURE
3064 open_traceset((GtkWidget
*)button
, user_data
);
3070 on_button_add_trace_clicked (GtkButton
*button
,
3073 add_trace((GtkWidget
*)button
, user_data
);
3078 on_button_remove_trace_clicked (GtkButton
*button
,
3081 remove_trace((GtkWidget
*)button
, user_data
);
3085 on_button_redraw_clicked (GtkButton
*button
,
3088 redraw((GtkWidget
*)button
, user_data
);
3092 on_button_continue_processing_clicked (GtkButton
*button
,
3095 continue_processing((GtkWidget
*)button
, user_data
);
3099 on_button_stop_processing_clicked (GtkButton
*button
,
3102 stop_processing((GtkWidget
*)button
, user_data
);
3108 on_button_save_clicked (GtkButton
*button
,
3111 save((GtkWidget
*)button
, user_data
);
3116 on_button_save_as_clicked (GtkButton
*button
,
3119 save_as((GtkWidget
*)button
, user_data
);
3124 on_button_zoom_in_clicked (GtkButton
*button
,
3127 zoom_in((GtkWidget
*)button
, user_data
);
3132 on_button_zoom_out_clicked (GtkButton
*button
,
3135 zoom_out((GtkWidget
*)button
, user_data
);
3140 on_button_zoom_extended_clicked (GtkButton
*button
,
3143 zoom_extended((GtkWidget
*)button
, user_data
);
3148 on_button_go_to_time_clicked (GtkButton
*button
,
3151 go_to_time((GtkWidget
*)button
, user_data
);
3156 on_button_show_time_frame_clicked (GtkButton
*button
,
3159 show_time_frame((GtkWidget
*)button
, user_data
);
3164 on_button_move_up_clicked (GtkButton
*button
,
3167 move_up_viewer((GtkWidget
*)button
, user_data
);
3172 on_button_move_down_clicked (GtkButton
*button
,
3175 move_down_viewer((GtkWidget
*)button
, user_data
);
3180 on_button_delete_viewer_clicked (GtkButton
*button
,
3183 delete_viewer((GtkWidget
*)button
, user_data
);
3187 on_MWindow_destroy (GtkWidget
*widget
,
3190 MainWindow
*main_window
= get_window_data_struct(widget
);
3191 LttvIAttribute
*attributes
= main_window
->attributes
;
3192 LttvAttributeValue value
;
3195 //This is unnecessary, since widgets will be destroyed
3196 //by the main window widget anyway.
3197 //remove_all_menu_toolbar_constructors(main_window, NULL);
3199 retval
= lttv_iattribute_find_by_path(attributes
, "viewers/menu",
3200 LTTV_POINTER
, &value
);
3202 lttv_menus_destroy((LttvMenus
*)*(value
.v_pointer
));
3204 retval
= lttv_iattribute_find_by_path(attributes
, "viewers/toolbar",
3205 LTTV_POINTER
, &value
);
3207 lttv_toolbars_destroy((LttvToolbars
*)*(value
.v_pointer
));
3209 g_object_unref(main_window
->attributes
);
3210 g_main_window_list
= g_slist_remove(g_main_window_list
, main_window
);
3212 g_info("There are now : %d windows\n",g_slist_length(g_main_window_list
));
3213 if(g_slist_length(g_main_window_list
) == 0)
3218 on_MWindow_configure (GtkWidget
*widget
,
3219 GdkEventConfigure
*event
,
3222 // MD : removed time width modification upon resizing of the main window.
3223 // The viewers will redraw themselves completely, without time interval
3226 if(mw_data->window_width){
3227 time_span = LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context)->Time_Span ;
3228 time_win = tab->time_window;
3229 ratio = width / mw_data->window_width;
3230 tab->time_window.time_width = ltt_time_mul(time_win.time_width,ratio);
3231 time = ltt_time_sub(time_span->endTime, time_win.start_time);
3232 if(ltt_time_compare(time, tab->time_window.time_width) < 0){
3233 tab->time_window.time_width = time;
3239 mw_data->window_width = (int)width;
3248 on_MNotebook_switch_page (GtkNotebook
*notebook
,
3249 GtkNotebookPage
*page
,
3257 void time_change_manager (Tab
*tab
,
3258 TimeWindow new_time_window
)
3261 /* Only one source of time change */
3262 if(tab
->time_manager_lock
== TRUE
) return;
3264 tab
->time_manager_lock
= TRUE
;
3265 TimeInterval time_span
;
3267 LttvTraceset
*ts
= tab
->traceset_info
->traceset
;
3269 time_span
= lttv_traceset_get_time_span_real(ts
);
3271 LttTime start_time
= new_time_window
.start_time
;
3272 LttTime end_time
= new_time_window
.end_time
;
3274 g_assert(ltt_time_compare(start_time
, end_time
) < 0);
3277 GtkAdjustment
*adjustment
= gtk_range_get_adjustment(GTK_RANGE(tab
->scrollbar
));
3278 LttTime upper
= ltt_time_sub(time_span
.end_time
, time_span
.start_time
);
3281 gtk_range_set_increments(GTK_RANGE(tab
->scrollbar
),
3282 ltt_time_to_double(new_time_window
.time_width
)
3283 / SCROLL_STEP_PER_PAGE
3284 * NANOSECONDS_PER_SECOND
, /* step increment */
3285 ltt_time_to_double(new_time_window
.time_width
)
3286 * NANOSECONDS_PER_SECOND
); /* page increment */
3287 gtk_range_set_range(GTK_RANGE(tab
->scrollbar
),
3289 ltt_time_to_double(upper
)
3290 * NANOSECONDS_PER_SECOND
); /* upper */
3292 g_object_set(G_OBJECT(adjustment
),
3296 ltt_time_to_double(upper
), /* upper */
3298 new_time_window
.time_width_double
3299 / SCROLL_STEP_PER_PAGE
, /* step increment */
3301 new_time_window
.time_width_double
,
3302 /* page increment */
3304 new_time_window
.time_width_double
, /* page size */
3306 gtk_adjustment_changed(adjustment
);
3308 // g_object_set(G_OBJECT(adjustment),
3310 // ltt_time_to_double(
3311 // ltt_time_sub(start_time, time_span.start_time))
3314 //gtk_adjustment_value_changed(adjustment);
3315 gtk_range_set_value(GTK_RANGE(tab
->scrollbar
),
3317 ltt_time_sub(start_time
, time_span
.start_time
)) /* value */);
3319 /* set the time bar. */
3322 timebar_set_minmax_time(TIMEBAR(tab
->MTimebar
),
3323 &time_span
.start_time
,
3324 &time_span
.end_time
);
3325 timebar_set_start_time(TIMEBAR(tab
->MTimebar
),&start_time
);
3326 timebar_set_end_time(TIMEBAR(tab
->MTimebar
),&end_time
);
3330 /* call viewer hooks for new time window */
3331 set_time_window(tab
, &new_time_window
);
3333 tab
->time_manager_lock
= FALSE
;
3342 void current_time_change_manager (Tab
*tab
,
3343 LttTime new_current_time
)
3345 /* Only one source of time change */
3346 if(tab
->current_time_manager_lock
== TRUE
) return;
3348 tab
->current_time_manager_lock
= TRUE
;
3350 timebar_set_current_time(TIMEBAR(tab
->MTimebar
), &new_current_time
);
3352 set_current_time(tab
, &new_current_time
);
3354 tab
->current_time_manager_lock
= FALSE
;
3357 void current_position_change_manager(Tab
*tab
, LttvTracesetPosition
*pos
)
3359 lttv_traceset_seek_to_position( pos
);
3361 LttTime new_time
= lttv_traceset_position_get_time(pos
);
3362 /* Put the context in a state coherent position */
3364 lttv_state_traceset_seek_time_closest(tab
->traceset_info
->traceset
, ltt_time_zero
);
3366 current_time_change_manager(tab
, new_time
);
3368 set_current_position(tab
, pos
);
3371 static void on_timebar_starttime_changed(Timebar
*timebar
,
3374 Tab
*tab
= (Tab
*)user_data
;
3375 LttvTraceset
* ts
=tab
->traceset_info
->traceset
;
3376 TimeInterval time_span
= lttv_traceset_get_time_span_real(ts
);
3378 TimeWindow new_time_window
= tab
->time_window
;
3379 new_time_window
.start_time
= timebar_get_start_time(timebar
);
3381 LttTime end_time
= new_time_window
.end_time
;
3383 /* TODO ybrosseau 2010-12-02: This if should have been checked
3384 by the timebar already */
3385 if(ltt_time_compare(new_time_window
.start_time
, end_time
) >= 0) {
3386 /* Then, we must push back end time : keep the same time width
3387 * if possible, else end traceset time */
3388 end_time
= LTT_TIME_MIN(ltt_time_add(new_time_window
.start_time
,
3389 new_time_window
.time_width
),
3390 time_span
.end_time
);
3393 /* Fix the time width to fit start time and end time */
3394 new_time_window
.time_width
= ltt_time_sub(end_time
,
3395 new_time_window
.start_time
);
3397 new_time_window
.time_width_double
=
3398 ltt_time_to_double(new_time_window
.time_width
);
3400 new_time_window
.end_time
= end_time
;
3402 /* Notify the time_manager */
3403 time_change_manager(tab
, new_time_window
);
3407 static void on_timebar_endtime_changed(Timebar
*timebar
,
3410 Tab
*tab
= (Tab
*)user_data
;
3411 LttvTraceset
* ts
=tab
->traceset_info
->traceset
;
3412 TimeInterval time_span
= lttv_traceset_get_time_span_real(ts
);
3414 TimeWindow new_time_window
= tab
->time_window
;
3416 LttTime end_time
= timebar_get_end_time(timebar
);
3418 /* TODO ybrosseau 2010-12-02: This if should have been
3419 checked by the timebar already */
3420 if(ltt_time_compare(new_time_window
.start_time
, end_time
) >= 0) {
3421 /* Then, we must push front start time : keep the same time
3422 width if possible, else end traceset time */
3423 new_time_window
.start_time
= LTT_TIME_MAX(
3424 ltt_time_sub(end_time
,
3425 new_time_window
.time_width
),
3426 time_span
.start_time
);
3429 /* Fix the time width to fit start time and end time */
3430 new_time_window
.time_width
= ltt_time_sub(end_time
,
3431 new_time_window
.start_time
);
3433 new_time_window
.time_width_double
=
3434 ltt_time_to_double(new_time_window
.time_width
);
3436 new_time_window
.end_time
= end_time
;
3438 /* Notify the time_manager */
3439 time_change_manager(tab
, new_time_window
);
3441 static void on_timebar_currenttime_changed(Timebar
*timebar
,
3444 Tab
*tab
= (Tab
*)user_data
;
3446 LttTime new_current_time
= timebar_get_current_time(timebar
);
3448 current_time_change_manager(tab
, new_current_time
);
3451 void scroll_value_changed_cb(GtkWidget
*scrollbar
,
3454 Tab
*tab
= (Tab
*)user_data
;
3455 TimeWindow new_time_window
;
3457 GtkAdjustment
*adjust
= gtk_range_get_adjustment(GTK_RANGE(scrollbar
));
3458 gdouble value
= gtk_adjustment_get_value(adjust
);
3459 // gdouble upper, lower, ratio, page_size;
3462 LttvTraceset
* ts
= tab
->traceset_info
->traceset
;
3463 TimeInterval time_span
= lttv_traceset_get_time_span_real(ts
);
3465 time
= ltt_time_add(ltt_time_from_double(value
),
3466 time_span
.start_time
);
3468 new_time_window
.start_time
= time
;
3470 page_size
= adjust
->page_size
;
3472 new_time_window
.time_width
=
3473 ltt_time_from_double(page_size
);
3475 new_time_window
.time_width_double
=
3478 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
3479 new_time_window
.time_width
);
3482 time_change_manager(tab
, new_time_window
);
3485 //time_window = tab->time_window;
3487 lower
= adjust
->lower
;
3488 upper
= adjust
->upper
;
3489 ratio
= (value
- lower
) / (upper
- lower
);
3490 g_info("lower %lu, upper %lu, value %lu, ratio %lu", lower
, upper
, value
, ratio
);
3492 //time = ltt_time_sub(time_span->end_time, time_span->start_time);
3493 //time = ltt_time_mul(time, (float)ratio);
3494 //time = ltt_time_add(time_span->start_time, time);
3495 time
= ltt_time_add(ltt_time_from_double(value
),
3496 time_span
.start_time
);
3498 time_window
.start_time
= time
;
3500 page_size
= adjust
->page_size
;
3502 time_window
.time_width
=
3503 ltt_time_from_double(page_size
);
3504 //time = ltt_time_sub(time_span.end_time, time);
3505 //if(ltt_time_compare(time,time_window.time_width) < 0){
3506 // time_window.time_width = time;
3509 /* call viewer hooks for new time window */
3510 set_time_window(tab
, &time_window
);
3516 /* Display a dialogue showing all eventtypes and traces, let user to select the interested
3517 * eventtypes, tracefiles and traces (filter)
3520 /* Select a trace which will be removed from traceset
3523 char * get_remove_trace(MainWindow
*mw_data
,
3524 char ** all_trace_name
, int nb_trace
)
3526 return get_selection(mw_data
, all_trace_name
, nb_trace
,
3527 "Select a trace", "Trace pathname");
3531 /* Select a module which will be loaded
3534 char * get_load_module(MainWindow
*mw_data
,
3535 char ** load_module_name
, int nb_module
)
3537 return get_selection(mw_data
, load_module_name
, nb_module
,
3538 "Select a module to load", "Module name");
3544 /* Select a module which will be unloaded
3547 char * get_unload_module(MainWindow
*mw_data
,
3548 char ** loaded_module_name
, int nb_module
)
3550 return get_selection(mw_data
, loaded_module_name
, nb_module
,
3551 "Select a module to unload", "Module name");
3555 /* Display a dialogue which shows all selectable items, let user to
3556 * select one of them
3559 char * get_selection(MainWindow
*mw_data
,
3560 char ** loaded_module_name
, int nb_module
,
3561 char *title
, char * column_title
)
3563 GtkWidget
* dialogue
;
3564 GtkWidget
* scroll_win
;
3566 GtkListStore
* store
;
3567 GtkTreeViewColumn
* column
;
3568 GtkCellRenderer
* renderer
;
3569 GtkTreeSelection
* select
;
3572 char * unload_module_name
= NULL
;
3574 dialogue
= gtk_dialog_new_with_buttons(title
,
3577 GTK_STOCK_OK
,GTK_RESPONSE_ACCEPT
,
3578 GTK_STOCK_CANCEL
,GTK_RESPONSE_REJECT
,
3580 gtk_window_set_default_size((GtkWindow
*)dialogue
, 500, 200);
3581 gtk_window_set_transient_for(GTK_WINDOW(dialogue
),
3582 GTK_WINDOW(mw_data
->mwindow
));
3584 scroll_win
= gtk_scrolled_window_new (NULL
, NULL
);
3585 gtk_widget_show ( scroll_win
);
3586 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll_win
),
3587 GTK_POLICY_AUTOMATIC
, GTK_POLICY_AUTOMATIC
);
3589 store
= gtk_list_store_new (N_COLUMNS
,G_TYPE_STRING
);
3590 tree
= gtk_tree_view_new_with_model(GTK_TREE_MODEL (store
));
3591 gtk_widget_show ( tree
);
3592 g_object_unref (G_OBJECT (store
));
3594 renderer
= gtk_cell_renderer_text_new ();
3595 column
= gtk_tree_view_column_new_with_attributes (column_title
,
3597 "text", MODULE_COLUMN
,
3599 gtk_tree_view_column_set_alignment (column
, 0.5);
3600 gtk_tree_view_column_set_fixed_width (column
, 150);
3601 gtk_tree_view_append_column (GTK_TREE_VIEW (tree
), column
);
3603 select
= gtk_tree_view_get_selection (GTK_TREE_VIEW (tree
));
3604 gtk_tree_selection_set_mode (select
, GTK_SELECTION_SINGLE
);
3606 gtk_container_add (GTK_CONTAINER (scroll_win
), tree
);
3608 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialogue
)->vbox
), scroll_win
,TRUE
, TRUE
,0);
3610 for(i
=0;i
<nb_module
;i
++){
3611 gtk_list_store_append (store
, &iter
);
3612 gtk_list_store_set (store
, &iter
, MODULE_COLUMN
,loaded_module_name
[i
],-1);
3615 id
= gtk_dialog_run(GTK_DIALOG(dialogue
));
3616 GtkTreeModel
**store_model
= (GtkTreeModel
**)&store
;
3618 case GTK_RESPONSE_ACCEPT
:
3619 case GTK_RESPONSE_OK
:
3620 if (gtk_tree_selection_get_selected (select
, store_model
, &iter
)){
3621 gtk_tree_model_get ((GtkTreeModel
*)store
, &iter
, MODULE_COLUMN
, &unload_module_name
, -1);
3623 case GTK_RESPONSE_REJECT
:
3624 case GTK_RESPONSE_CANCEL
:
3626 gtk_widget_destroy(dialogue
);
3630 return unload_module_name
;
3634 /* Insert all menu entry and tool buttons into this main window
3639 void add_all_menu_toolbar_constructors(MainWindow
* mw
, gpointer user_data
)
3643 lttvwindow_viewer_constructor constructor
;
3644 LttvMenus
* global_menu
, * instance_menu
;
3645 LttvToolbars
* global_toolbar
, * instance_toolbar
;
3646 LttvMenuClosure
*menu_item
;
3647 LttvToolbarClosure
*toolbar_item
;
3648 LttvAttributeValue value
;
3649 LttvIAttribute
*global_attributes
= LTTV_IATTRIBUTE(lttv_global_attributes());
3650 LttvIAttribute
*attributes
= mw
->attributes
;
3651 GtkWidget
* tool_menu_title_menu
, *new_widget
, *pixmap
;
3654 retval
= lttv_iattribute_find_by_path(global_attributes
, "viewers/menu",
3655 LTTV_POINTER
, &value
);
3657 if(*(value
.v_pointer
) == NULL
)
3658 *(value
.v_pointer
) = lttv_menus_new();
3659 global_menu
= (LttvMenus
*)*(value
.v_pointer
);
3661 retval
= lttv_iattribute_find_by_path(attributes
, "viewers/menu",
3662 LTTV_POINTER
, &value
);
3664 if(*(value
.v_pointer
) == NULL
)
3665 *(value
.v_pointer
) = lttv_menus_new();
3666 instance_menu
= (LttvMenus
*)*(value
.v_pointer
);
3668 retval
= lttv_iattribute_find_by_path(global_attributes
, "viewers/toolbar",
3669 LTTV_POINTER
, &value
);
3671 if(*(value
.v_pointer
) == NULL
)
3672 *(value
.v_pointer
) = lttv_toolbars_new();
3673 global_toolbar
= (LttvToolbars
*)*(value
.v_pointer
);
3675 retval
= lttv_iattribute_find_by_path(attributes
, "viewers/toolbar",
3676 LTTV_POINTER
, &value
);
3678 if(*(value
.v_pointer
) == NULL
)
3679 *(value
.v_pointer
) = lttv_toolbars_new();
3680 instance_toolbar
= (LttvToolbars
*)*(value
.v_pointer
);
3682 /* Add missing menu entries to window instance */
3683 for(i
=0;i
<global_menu
->len
;i
++) {
3684 menu_item
= &g_array_index(global_menu
, LttvMenuClosure
, i
);
3686 //add menu_item to window instance;
3687 constructor
= menu_item
->con
;
3688 tool_menu_title_menu
= lookup_widget(mw
->mwindow
,"ToolMenuTitle_menu");
3690 gtk_menu_item_new_with_mnemonic (menu_item
->menu_text
);
3691 gtk_container_add (GTK_CONTAINER (tool_menu_title_menu
),
3693 g_signal_connect ((gpointer
) new_widget
, "activate",
3694 G_CALLBACK (insert_viewer_wrap
),
3696 gtk_widget_show (new_widget
);
3697 lttv_menus_add(instance_menu
, menu_item
->con
,
3698 menu_item
->menu_path
,
3699 menu_item
->menu_text
,
3704 /* Add missing toolbar entries to window instance */
3705 for(i
=0;i
<global_toolbar
->len
;i
++) {
3706 toolbar_item
= &g_array_index(global_toolbar
, LttvToolbarClosure
, i
);
3708 //add toolbar_item to window instance;
3709 constructor
= toolbar_item
->con
;
3710 tool_menu_title_menu
= lookup_widget(mw
->mwindow
,"MToolbar1");
3711 pixbuf
= gdk_pixbuf_new_from_xpm_data((const char**)toolbar_item
->pixmap
);
3712 pixmap
= gtk_image_new_from_pixbuf(pixbuf
);
3714 gtk_toolbar_append_element (GTK_TOOLBAR (tool_menu_title_menu
),
3715 GTK_TOOLBAR_CHILD_BUTTON
,
3718 toolbar_item
->tooltip
, NULL
,
3719 pixmap
, NULL
, NULL
);
3720 gtk_label_set_use_underline(
3721 GTK_LABEL (((GtkToolbarChild
*) (
3722 g_list_last (GTK_TOOLBAR
3723 (tool_menu_title_menu
)->children
)->data
))->label
),
3725 gtk_container_set_border_width (GTK_CONTAINER (new_widget
), 1);
3726 g_signal_connect ((gpointer
) new_widget
,
3728 G_CALLBACK (insert_viewer_wrap
),
3730 gtk_widget_show (new_widget
);
3732 lttv_toolbars_add(instance_toolbar
, toolbar_item
->con
,
3733 toolbar_item
->tooltip
,
3734 toolbar_item
->pixmap
,
3742 /* Create a main window
3745 MainWindow
*construct_main_window(MainWindow
* parent
)
3749 g_debug("construct_main_window()");
3750 GtkWidget
* new_window
; /* New generated main window */
3751 MainWindow
* new_m_window
;/* New main window structure */
3752 GtkNotebook
* notebook
;
3753 LttvIAttribute
*attributes
=
3754 LTTV_IATTRIBUTE(g_object_new(LTTV_ATTRIBUTE_TYPE
, NULL
));
3755 LttvAttributeValue value
;
3757 new_m_window
= g_new(MainWindow
, 1);
3759 // Add the object's information to the module's array
3760 g_main_window_list
= g_slist_append(g_main_window_list
, new_m_window
);
3762 new_window
= create_MWindow();
3763 gtk_widget_show (new_window
);
3765 new_m_window
->mwindow
= new_window
;
3766 new_m_window
->attributes
= attributes
;
3768 retval
= lttv_iattribute_find_by_path(attributes
, "viewers/menu",
3769 LTTV_POINTER
, &value
);
3771 *(value
.v_pointer
) = lttv_menus_new();
3773 retval
= lttv_iattribute_find_by_path(attributes
, "viewers/toolbar",
3774 LTTV_POINTER
, &value
);
3776 *(value
.v_pointer
) = lttv_toolbars_new();
3778 add_all_menu_toolbar_constructors(new_m_window
, NULL
);
3780 g_object_set_data_full(G_OBJECT(new_window
),
3782 (gpointer
)new_m_window
,
3783 (GDestroyNotify
)g_free
);
3784 //create a default tab
3785 notebook
= (GtkNotebook
*)lookup_widget(new_m_window
->mwindow
, "MNotebook");
3786 if(notebook
== NULL
){
3787 g_info("Notebook does not exist\n");
3788 /* FIXME : destroy partially created widgets */
3789 g_free(new_m_window
);
3792 //gtk_notebook_popup_enable (GTK_NOTEBOOK(notebook));
3793 //for now there is no name field in LttvTraceset structure
3794 //Use "Traceset" as the label for the default tab
3796 GtkWidget
* parent_notebook
= lookup_widget(parent
->mwindow
, "MNotebook");
3797 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(parent_notebook
),
3798 gtk_notebook_get_current_page(GTK_NOTEBOOK(parent_notebook
)));
3804 LttvPluginTab
*ptab
;
3805 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
3806 parent_tab
= ptab
->tab
;
3808 LttvPluginTab
*ptab
= g_object_new(LTTV_TYPE_PLUGIN_TAB
, NULL
);
3810 new_m_window
, parent_tab
, notebook
, "Traceset");
3811 ptab
->parent
.top_widget
= ptab
->tab
->top_widget
;
3812 g_object_set_data_full(
3813 G_OBJECT(ptab
->tab
->vbox
),
3816 (GDestroyNotify
)tab_destructor
);
3818 LttvPluginTab
*ptab
= g_object_new(LTTV_TYPE_PLUGIN_TAB
, NULL
);
3819 init_tab(ptab
->tab
, new_m_window
, NULL
, notebook
, "Traceset");
3820 ptab
->parent
.top_widget
= ptab
->tab
->top_widget
;
3821 g_object_set_data_full(
3822 G_OBJECT(ptab
->tab
->vbox
),
3825 (GDestroyNotify
)tab_destructor
);
3828 /* Insert default viewers */
3830 LttvAttributeType type
;
3831 LttvAttributeName name
;
3832 LttvAttributeValue value
;
3833 LttvAttribute
*attribute
;
3835 LttvIAttribute
*attributes_global
=
3836 LTTV_IATTRIBUTE(lttv_global_attributes());
3838 attribute
= LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
3839 LTTV_IATTRIBUTE(attributes_global
),
3840 LTTV_VIEWER_CONSTRUCTORS
));
3841 g_assert(attribute
);
3843 name
= g_quark_from_string("guievents");
3844 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
3846 if(type
== LTTV_POINTER
) {
3847 lttvwindow_viewer_constructor viewer_constructor
=
3848 (lttvwindow_viewer_constructor
)*value
.v_pointer
;
3849 insert_viewer(new_window
, viewer_constructor
);
3852 name
= g_quark_from_string("guicontrolflow");
3853 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
3855 if(type
== LTTV_POINTER
) {
3856 lttvwindow_viewer_constructor viewer_constructor
=
3857 (lttvwindow_viewer_constructor
)*value
.v_pointer
;
3858 insert_viewer(new_window
, viewer_constructor
);
3861 name
= g_quark_from_string("guistatistics");
3862 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
3864 if(type
== LTTV_POINTER
) {
3865 lttvwindow_viewer_constructor viewer_constructor
=
3866 (lttvwindow_viewer_constructor
)*value
.v_pointer
;
3867 insert_viewer(new_window
, viewer_constructor
);
3871 g_info("There are now : %d windows\n",g_slist_length(g_main_window_list
));
3873 return new_m_window
;
3877 /* Free the memory occupied by a tab structure
3881 void tab_destructor(LttvPluginTab
* ptab
)
3883 #ifdef BABEL_CLEANUP
3884 int i
, nb
, ref_count
;
3886 Tab
*tab
= ptab
->tab
;
3889 g_object_unref(tab
->attributes
);
3891 if(tab
->interrupted_state
)
3892 g_object_unref(tab
->interrupted_state
);
3895 if(tab
->traceset_info
->traceset_context
!= NULL
){
3896 //remove state update hooks
3897 lttv_state_remove_event_hooks(
3898 (LttvTracesetState
*)tab
->traceset_info
->
3900 lttv_context_fini(LTTV_TRACESET_CONTEXT(tab
->traceset_info
->
3902 g_object_unref(tab
->traceset_info
->traceset_context
);
3904 if(tab
->traceset_info
->traceset
!= NULL
) {
3905 nb
= lttv_traceset_number(tab
->traceset_info
->traceset
);
3906 for(i
= 0 ; i
< nb
; i
++) {
3907 trace
= lttv_traceset_get(tab
->traceset_info
->traceset
, i
);
3908 ref_count
= lttv_trace_get_ref_number(trace
);
3910 ltt_trace_close(lttv_trace(trace
));
3914 lttv_traceset_destroy(tab
->traceset_info
->traceset
);
3915 /* Remove the idle events requests processing function of the tab */
3916 g_idle_remove_by_data(tab
);
3918 g_slist_free(tab
->events_requests
);
3919 g_free(tab
->traceset_info
);
3921 g_object_unref(ptab
);
3922 #endif /* BABEL_CLEANUP */
3926 /* Create a tab and insert it into the current main window
3929 void init_tab(Tab
*tab
, MainWindow
* mw
, Tab
*copy_tab
,
3930 GtkNotebook
* notebook
, char * label
)
3935 //LttvFilter *filter = NULL;
3937 //create a new tab data structure
3938 //tab = g_new(Tab,1);
3940 //construct and initialize the traceset_info
3941 tab
->traceset_info
= g_new(TracesetInfo
,1);
3944 tab
->traceset_info
->traceset
=
3945 lttv_traceset_copy(copy_tab
->traceset_info
->traceset
);
3947 /* Copy the previous tab's filter */
3948 /* We can clone the filter, as we copy the trace set also */
3949 /* The filter must always be in sync with the trace set */
3951 #ifdef BABEL_CLEANUP
3952 tab
->filter
= lttv_filter_clone(copy_tab
->filter
);
3953 #endif /* BABEL_CLEANUP */
3955 tab
->traceset_info
->traceset
= lttv_traceset_new();
3960 lttv_attribute_write_xml(
3961 lttv_traceset_attribute(tab
->traceset_info
->traceset
),
3967 tab
->time_manager_lock
= FALSE
;
3968 tab
->current_time_manager_lock
= FALSE
;
3969 #ifdef BABEL_CLEANUP
3970 //FIXME copy not implemented in lower level
3971 tab
->traceset_info
->traceset_context
=
3972 g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
3973 //add state update hooks
3974 #endif //BABEL_CLEANUP
3975 lttv_state_add_event_hooks(
3976 tab
->traceset_info
->traceset
);
3978 //determine the current_time and time_window of the tab
3980 if(copy_tab
!= NULL
){
3981 tab
->time_window
= copy_tab
->time_window
;
3982 tab
->current_time
= copy_tab
->current_time
;
3984 tab
->time_window
.start_time
=
3985 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
3986 time_span
.start_time
;
3987 if(DEFAULT_TIME_WIDTH_S
<
3988 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
3989 time_span
.end_time
.tv_sec
)
3990 tmp_time
.tv_sec
= DEFAULT_TIME_WIDTH_S
;
3993 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
3994 time_span
.end_time
.tv_sec
;
3995 tmp_time
.tv_nsec
= 0;
3996 tab
->time_window
.time_width
= tmp_time
;
3997 tab
->current_time
.tv_sec
=
3998 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
3999 time_span
.start_time
.tv_sec
;
4000 tab
->current_time
.tv_nsec
=
4001 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
4002 time_span
.start_time
.tv_nsec
;
4005 tab
->attributes
= LTTV_IATTRIBUTE(g_object_new(LTTV_ATTRIBUTE_TYPE
, NULL
));
4006 tab
->interrupted_state
= g_object_new(LTTV_ATTRIBUTE_TYPE
, NULL
);
4008 tab
->vbox
= gtk_vbox_new(FALSE
, 2);
4009 tab
->top_widget
= tab
->vbox
;
4010 //g_object_set_data_full(G_OBJECT(tab->top_widget), "filter",
4011 // filter, (GDestroyNotify)lttv_filter_destroy);
4013 // g_signal_connect (G_OBJECT(tab->top_widget),
4015 // G_CALLBACK (on_top_notify),
4018 tab
->viewer_container
= gtk_vbox_new(TRUE
, 2);
4019 tab
->scrollbar
= gtk_hscrollbar_new(NULL
);
4020 //tab->multivpaned = gtk_multi_vpaned_new();
4022 gtk_box_pack_start(GTK_BOX(tab
->vbox
),
4023 tab
->viewer_container
,
4025 TRUE
, /* Give the extra space to the child */
4026 0); /* No padding */
4029 // tab->time_window = copy_tab->time_window;
4030 // tab->current_time = copy_tab->current_time;
4033 /* Create the timebar */
4035 tab
->MTimebar
= timebar_new();
4037 gtk_box_pack_end(GTK_BOX(tab
->vbox
),
4039 FALSE
, /* Do not expand */
4040 FALSE
, /* Fill has no effect here (expand false) */
4041 0); /* No padding */
4043 gtk_box_pack_end(GTK_BOX(tab
->vbox
),
4045 FALSE
, /* Do not expand */
4046 FALSE
, /* Fill has no effect here (expand false) */
4047 0); /* No padding */
4049 g_object_set_data(G_OBJECT(tab
->viewer_container
), "focused_viewer", NULL
);
4055 // Display a label with a X
4056 GtkWidget *w_hbox = gtk_hbox_new(FALSE, 4);
4057 GtkWidget *w_label = gtk_label_new (label);
4058 GtkWidget *pixmap = create_pixmap(GTK_WIDGET(notebook), "close.png");
4059 GtkWidget *w_button = gtk_button_new ();
4060 gtk_container_add(GTK_CONTAINER(w_button), pixmap);
4061 //GtkWidget *w_button = gtk_button_new_with_label("x");
4063 gtk_button_set_relief(GTK_BUTTON(w_button), GTK_RELIEF_NONE);
4065 gtk_box_pack_start(GTK_BOX(w_hbox), w_label, TRUE, TRUE, 0);
4066 gtk_box_pack_end(GTK_BOX(w_hbox), w_button, FALSE,
4069 g_signal_connect_swapped (w_button, "clicked",
4070 G_CALLBACK (on_close_tab_X_clicked),
4073 gtk_widget_set_state(w_button, GTK_STATE_ACTIVE);
4075 gtk_widget_show (w_label);
4076 gtk_widget_show (pixmap);
4077 gtk_widget_show (w_button);
4078 gtk_widget_show (w_hbox);
4080 tab->label = w_hbox;
4084 tab
->label
= gtk_label_new (label
);
4086 gtk_widget_show(tab
->label
);
4087 gtk_widget_show(tab
->scrollbar
);
4088 gtk_widget_show(tab
->MTimebar
);
4089 gtk_widget_show(tab
->viewer_container
);
4090 gtk_widget_show(tab
->vbox
);
4092 //gtk_widget_show(tab->multivpaned);
4095 /* Start with empty events requests list */
4096 tab
->events_requests
= NULL
;
4097 tab
->events_request_pending
= FALSE
;
4098 tab
->stop_foreground
= FALSE
;
4102 g_signal_connect(G_OBJECT(tab
->scrollbar
), "value-changed",
4103 G_CALLBACK(scroll_value_changed_cb
), tab
);
4106 /* Timebar signal handler */
4107 g_signal_connect(G_OBJECT(tab
->MTimebar
), "start-time-changed",
4108 G_CALLBACK(on_timebar_starttime_changed
), tab
);
4109 g_signal_connect(G_OBJECT(tab
->MTimebar
), "end-time-changed",
4110 G_CALLBACK(on_timebar_endtime_changed
), tab
);
4111 g_signal_connect(G_OBJECT(tab
->MTimebar
), "current-time-changed",
4112 G_CALLBACK(on_timebar_currenttime_changed
), tab
);
4114 //g_signal_connect(G_OBJECT(tab->scrollbar), "changed",
4115 // G_CALLBACK(scroll_value_changed_cb), tab);
4118 //insert tab into notebook
4119 gtk_notebook_append_page(notebook
,
4122 list
= gtk_container_get_children(GTK_CONTAINER(notebook
));
4123 gtk_notebook_set_current_page(notebook
,g_list_length(list
)-1);
4124 // always show : not if(g_list_length(list)>1)
4125 gtk_notebook_set_show_tabs(notebook
, TRUE
);
4128 lttvwindow_report_time_window(tab
, copy_tab
->time_window
);
4129 lttvwindow_report_current_time(tab
, copy_tab
->current_time
);
4131 TimeWindow time_window
;
4133 time_window
.start_time
= ltt_time_zero
;
4134 time_window
.end_time
= ltt_time_add(time_window
.start_time
,
4135 lttvwindow_default_time_width
);
4136 time_window
.time_width
= lttvwindow_default_time_width
;
4137 time_window
.time_width_double
= ltt_time_to_double(time_window
.time_width
);
4139 lttvwindow_report_time_window(tab
, time_window
);
4140 lttvwindow_report_current_time(tab
, ltt_time_zero
);
4143 LttvTraceset
*traceset
= tab
->traceset_info
->traceset
;
4144 SetTraceset(tab
, traceset
);
4148 * execute_events_requests
4150 * Idle function that executes the pending requests for a tab.
4152 * @return return value : TRUE : keep the idle function, FALSE : remove it.
4154 gboolean
execute_events_requests(Tab
*tab
)
4156 return ( lttvwindow_process_pending_requests(tab
) );
4160 __EXPORT
void create_main_window_with_trace_list(GSList
*traces
)
4163 GSList
*iter
= NULL
;
4166 MainWindow
*mw
= construct_main_window(NULL
);
4167 GtkWidget
*widget
= mw
->mwindow
;
4169 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
4170 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
4171 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
4172 LttvPluginTab
*ptab
;
4176 ptab
= create_new_tab(widget
, NULL
);
4179 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
4183 LttvTraceset
* traceset
= lttv_traceset_new();
4184 for(iter
=traces
; iter
!=NULL
; iter
=g_slist_next(iter
)) {
4185 gchar
*path
= (gchar
*)iter
->data
;
4187 gchar abs_path
[PATH_MAX
];
4190 get_absolute_pathname(path
, abs_path
);
4192 if(lttv_traceset_add_path(traceset
,abs_path
) != 0 ){ /*failure*/
4194 g_warning("cannot open trace %s", abs_path
);
4196 GtkWidget
*dialogue
=
4197 gtk_message_dialog_new(
4198 GTK_WINDOW(gtk_widget_get_toplevel(widget
)),
4199 GTK_DIALOG_MODAL
|GTK_DIALOG_DESTROY_WITH_PARENT
,
4202 "Cannot open trace : maybe you should enter in the directory "
4204 gtk_dialog_run(GTK_DIALOG(dialogue
));
4205 gtk_widget_destroy(dialogue
);
4208 SetTraceset(tab
, traceset
);