1 /* This file is part of the Linux Trace Toolkit viewer
2 * Copyright (C) 2003-2004 XangXiu Yang, Mathieu Desnoyers
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License Version 2 as
6 * published by the Free Software Foundation;
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place - Suite 330, Boston,
23 #include <limits.h> // for PATH_MAX
31 #include "callbacks.h"
32 #include "interface.h"
34 #include <ltt/trace.h>
36 #include <ltt/event.h>
37 #include <lttv/lttv.h>
38 #include <lttv/module.h>
39 #include <lttv/iattribute.h>
40 #include <lttv/stats.h>
41 #include <lttv/filter.h>
42 #include <lttv/sync/sync_chain_lttv.h>
43 #include <lttvwindow/mainwindow.h>
44 #include <lttvwindow/mainwindow-private.h>
45 #include <lttvwindow/menu.h>
46 #include <lttvwindow/timebar.h>
47 #include <lttvwindow/toolbar.h>
48 #include <lttvwindow/lttvwindow.h>
49 #include <lttvwindow/lttvwindowtraces.h>
50 #include <lttvwindow/lttv_plugin_tab.h>
52 static LttTime lttvwindow_default_time_width
= { 1, 0 };
53 #define CLIP_BUF 256 // size of clipboard buffer
55 extern LttvTrace
*g_init_trace
;
58 /** Array containing instanced objects. */
59 extern GSList
* g_main_window_list
;
61 /** MD : keep old directory. */
62 static char remember_plugins_dir
[PATH_MAX
] = "";
63 static char remember_trace_dir
[PATH_MAX
] = "";
65 void tab_destructor(LttvPluginTab
* ptab
);
67 MainWindow
* get_window_data_struct(GtkWidget
* widget
);
68 char * get_load_module(MainWindow
*mw
,
69 char ** load_module_name
, int nb_module
);
70 char * get_unload_module(MainWindow
*mw
,
71 char ** loaded_module_name
, int nb_module
);
72 char * get_remove_trace(MainWindow
*mw
, char ** all_trace_name
, int nb_trace
);
73 char * get_selection(MainWindow
*mw
,
74 char ** all_name
, int nb
, char *title
, char * column_title
);
75 void init_tab(Tab
*tab
, MainWindow
* mw
, Tab
*copy_tab
,
76 GtkNotebook
* notebook
, char * label
);
78 static void insert_viewer(GtkWidget
* widget
, lttvwindow_viewer_constructor constructor
);
80 LttvPluginTab
*create_new_tab(GtkWidget
* widget
, gpointer user_data
);
82 static gboolean
lttvwindow_process_pending_requests(Tab
*tab
);
84 static void on_timebar_starttime_changed(Timebar
*timebar
,
86 static void on_timebar_endtime_changed(Timebar
*timebar
,
88 static void on_timebar_currenttime_changed(Timebar
*timebar
,
106 static void on_top_notify(GObject
*gobject
,
110 Tab
*tab
= (Tab
*)user_data
;
111 g_message("in on_top_notify.\n");
115 static gboolean
viewer_grab_focus(GtkWidget
*widget
, GdkEventButton
*event
,
118 GtkWidget
*viewer
= GTK_WIDGET(data
);
119 GtkWidget
*viewer_container
= gtk_widget_get_parent(viewer
);
121 g_debug("FOCUS GRABBED");
122 g_object_set_data(G_OBJECT(viewer_container
), "focused_viewer", viewer
);
127 static void connect_focus_recursive(GtkWidget
*widget
,
130 if(GTK_IS_CONTAINER(widget
)) {
131 gtk_container_forall(GTK_CONTAINER(widget
),
132 (GtkCallback
)connect_focus_recursive
,
136 if(GTK_IS_TREE_VIEW(widget
)) {
137 gtk_tree_view_set_headers_clickable(GTK_TREE_VIEW(widget
), TRUE
);
139 gtk_widget_add_events(widget
, GDK_BUTTON_PRESS_MASK
);
140 g_signal_connect (G_OBJECT(widget
),
141 "button-press-event",
142 G_CALLBACK (viewer_grab_focus
),
146 /* Stop all the processings and call gtk_main_quit() */
147 static void mainwindow_quit()
149 lttvwindowtraces_unregister_requests(g_quark_from_string("stats"));
150 lttvwindowtraces_unregister_requests(g_quark_from_string("state"));
151 lttvwindowtraces_unregister_computation_hooks(g_quark_from_string("stats"));
152 lttvwindowtraces_unregister_computation_hooks(g_quark_from_string("state"));
158 /* insert_viewer function constructs an instance of a viewer first,
159 * then inserts the widget of the instance into the container of the
164 insert_viewer_wrap(GtkWidget
*menuitem
, gpointer user_data
)
166 insert_viewer((GtkWidget
*)menuitem
, (lttvwindow_viewer_constructor
)user_data
);
170 /* internal functions */
171 void insert_viewer(GtkWidget
* widget
, lttvwindow_viewer_constructor constructor
)
173 GtkWidget
* viewer_container
;
174 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
176 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
177 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
182 ptab
= create_new_tab(widget
, NULL
);
184 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
188 viewer_container
= tab
->viewer_container
;
190 viewer
= (GtkWidget
*)constructor(&ptab
->parent
);
193 //gtk_multivpaned_widget_add(GTK_MULTIVPANED(multivpaned), viewer);
195 gtk_box_pack_end(GTK_BOX(viewer_container
),
201 /* We want to connect the viewer_grab_focus to EVERY
202 * child of this widget. The little trick is to get each child
203 * of each GTK_CONTAINER, even subchildren.
205 connect_focus_recursive(viewer
, viewer
);
210 * Function to set/update traceset for the viewers
211 * @param tab viewer's tab
212 * @param traceset traceset of the main window.
214 * 0 : traceset updated
215 * 1 : no traceset hooks to update; not an error.
218 int SetTraceset(Tab
* tab
, LttvTraceset
*traceset
)
221 TimeInterval time_span
;
222 TimeWindow new_time_window
;
223 LttTime new_current_time
;
224 LttvTracesetContext
*tsc
=
225 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
227 // Perform time synchronization on the traces
228 if (syncTraceset(tsc
))
230 /* There is some time-dependant information that was calculated during
231 * context initialization. Destroy the old contexts and initialize new
233 * Modified from lttvwindow_add_trace()
235 // Keep a reference to the traces so they are not freed
236 for(i
= 0; i
< lttv_traceset_number(traceset
); i
++)
238 LttvTrace
*trace
= lttv_traceset_get(traceset
, i
);
239 lttv_trace_ref(trace
);
242 // Remove state update hooks
243 lttv_state_remove_event_hooks(
244 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
246 lttv_context_fini(LTTV_TRACESET_CONTEXT(
247 tab
->traceset_info
->traceset_context
));
248 g_object_unref(tab
->traceset_info
->traceset_context
);
250 for(i
= 0; i
< lttv_traceset_number(traceset
); i
++)
252 LttvTrace
*trace
= lttv_traceset_get(traceset
, i
);
253 lttvwindowtraces_remove_trace(trace
);
254 lttvwindowtraces_add_trace(trace
);
257 // Create new context
258 tab
->traceset_info
->traceset_context
=
259 g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
260 lttv_context_init(LTTV_TRACESET_CONTEXT(tab
->traceset_info
->
261 traceset_context
), traceset
);
263 // Add state update hooks
264 lttv_state_add_event_hooks(
265 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
267 // Remove local reference to the traces
268 for(i
=0; i
<lttv_traceset_number(traceset
); i
++)
270 LttvTrace
*trace
= lttv_traceset_get(traceset
, i
);
271 lttv_trace_unref(trace
);
274 tsc
= LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
277 time_span
= tsc
->time_span
;
278 new_time_window
= tab
->time_window
;
279 new_current_time
= tab
->current_time
;
281 /* Set the tab's time window and current time if
283 if(ltt_time_compare(tab
->time_window
.start_time
, time_span
.start_time
) < 0
284 || ltt_time_compare(tab
->time_window
.end_time
,
285 time_span
.end_time
) > 0) {
286 new_time_window
.start_time
= time_span
.start_time
;
288 new_current_time
= time_span
.start_time
;
292 if(ltt_time_compare(lttvwindow_default_time_width
,
293 ltt_time_sub(time_span
.end_time
, time_span
.start_time
)) < 0
295 ltt_time_compare(time_span
.end_time
, time_span
.start_time
) == 0)
296 tmp_time
= lttvwindow_default_time_width
;
298 tmp_time
= time_span
.end_time
;
300 new_time_window
.time_width
= tmp_time
;
301 new_time_window
.time_width_double
= ltt_time_to_double(tmp_time
);
302 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
303 new_time_window
.time_width
) ;
310 GtkAdjustment
*adjustment
= gtk_range_get_adjustment(GTK_RANGE(tab
->scrollbar
));
311 LttTime upper
= ltt_time_sub(time_span
.end_time
, time_span
.start_time
);
313 g_object_set(G_OBJECT(adjustment
),
317 ltt_time_to_double(upper
)
318 * NANOSECONDS_PER_SECOND
, /* upper */
320 ltt_time_to_double(tab
->time_window
.time_width
)
321 / SCROLL_STEP_PER_PAGE
322 * NANOSECONDS_PER_SECOND
, /* step increment */
324 ltt_time_to_double(tab
->time_window
.time_width
)
325 * NANOSECONDS_PER_SECOND
, /* page increment */
327 ltt_time_to_double(tab
->time_window
.time_width
)
328 * NANOSECONDS_PER_SECOND
, /* page size */
330 gtk_adjustment_changed(adjustment
);
332 g_object_set(G_OBJECT(adjustment
),
335 ltt_time_sub(tab
->time_window
.start_time
, time_span
.start_time
))
336 * NANOSECONDS_PER_SECOND
, /* value */
338 gtk_adjustment_value_changed(adjustment
);
340 /* set the time bar. The value callbacks will change their nsec themself */
342 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry1
),
343 (double)time_span
.start_time
.tv_sec
,
344 (double)time_span
.end_time
.tv_sec
);
347 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry3
),
348 (double)time_span
.start_time
.tv_sec
,
349 (double)time_span
.end_time
.tv_sec
);
351 /* current seconds */
352 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry5
),
353 (double)time_span
.start_time
.tv_sec
,
354 (double)time_span
.end_time
.tv_sec
);
357 /* Finally, call the update hooks of the viewers */
359 LttvAttributeValue value
;
362 retval
= lttv_iattribute_find_by_path(tab
->attributes
,
363 "hooks/updatetraceset", LTTV_POINTER
, &value
);
366 tmp
= (LttvHooks
*)*(value
.v_pointer
);
370 lttv_hooks_call(tmp
,traceset
);
372 time_change_manager(tab
, new_time_window
);
373 current_time_change_manager(tab
, new_current_time
);
379 * Function to set/update filter for the viewers
380 * @param tab viewer's tab
381 * @param filter filter of the main window.
384 * 0 : filters updated
385 * 1 : no filter hooks to update; not an error.
388 int SetFilter(Tab
* tab
, gpointer filter
)
391 LttvAttributeValue value
;
393 g_assert(lttv_iattribute_find_by_path(tab
->attributes
,
394 "hooks/updatefilter", LTTV_POINTER
, &value
));
396 tmp
= (LttvHooks
*)*(value
.v_pointer
);
398 if(tmp
== NULL
) return 1;
399 lttv_hooks_call(tmp
,filter
);
407 * Function to redraw each viewer belonging to the current tab
408 * @param tab viewer's tab
411 void update_traceset(Tab
*tab
)
413 LttvAttributeValue value
;
417 retval
= lttv_iattribute_find_by_path(tab
->attributes
,
418 "hooks/updatetraceset", LTTV_POINTER
, &value
);
420 tmp
= (LttvHooks
*)*(value
.v_pointer
);
421 if(tmp
== NULL
) return;
422 lttv_hooks_call(tmp
, NULL
);
426 /* get_label function is used to get user input, it displays an input
427 * box, which allows user to input a string
430 void get_label_string (GtkWidget
* text
, gchar
* label
)
432 GtkEntry
* entry
= (GtkEntry
*)text
;
433 if(strlen(gtk_entry_get_text(entry
))!=0)
434 strcpy(label
,gtk_entry_get_text(entry
));
437 gboolean
get_label(MainWindow
* mw
, gchar
* str
, gchar
* dialogue_title
, gchar
* label_str
)
439 GtkWidget
* dialogue
;
444 dialogue
= gtk_dialog_new_with_buttons(dialogue_title
,NULL
,
446 GTK_STOCK_OK
,GTK_RESPONSE_ACCEPT
,
447 GTK_STOCK_CANCEL
,GTK_RESPONSE_REJECT
,
450 label
= gtk_label_new(label_str
);
451 gtk_widget_show(label
);
453 text
= gtk_entry_new();
454 gtk_widget_show(text
);
456 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialogue
)->vbox
), label
,TRUE
, TRUE
,0);
457 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialogue
)->vbox
), text
,FALSE
, FALSE
,0);
459 id
= gtk_dialog_run(GTK_DIALOG(dialogue
));
461 case GTK_RESPONSE_ACCEPT
:
462 get_label_string(text
,str
);
463 gtk_widget_destroy(dialogue
);
465 case GTK_RESPONSE_REJECT
:
467 gtk_widget_destroy(dialogue
);
474 /* get_window_data_struct function is actually a lookup function,
475 * given a widget which is in the tree of the main window, it will
476 * return the MainWindow data structure associated with main window
479 MainWindow
* get_window_data_struct(GtkWidget
* widget
)
482 MainWindow
* mw_data
;
484 mw
= lookup_widget(widget
, "MWindow");
486 g_info("Main window does not exist\n");
490 mw_data
= (MainWindow
*) g_object_get_data(G_OBJECT(mw
),"main_window_data");
492 g_warning("Main window data does not exist\n");
499 /* create_new_window function, just constructs a new main window
502 void create_new_window(GtkWidget
* widget
, gpointer user_data
, gboolean clone
)
504 MainWindow
* parent
= get_window_data_struct(widget
);
507 g_info("Clone : use the same traceset\n");
508 construct_main_window(parent
);
510 g_info("Empty : traceset is set to NULL\n");
511 construct_main_window(NULL
);
515 /* Get the currently focused viewer.
516 * If no viewer is focused, use the first one.
518 * If no viewer available, return NULL.
520 GtkWidget
*viewer_container_focus(GtkWidget
*container
)
524 widget
= (GtkWidget
*)g_object_get_data(G_OBJECT(container
),
528 g_debug("no widget focused");
529 GList
*children
= gtk_container_get_children(GTK_CONTAINER(container
));
532 widget
= GTK_WIDGET(children
->data
);
533 g_object_set_data(G_OBJECT(container
),
543 gint
viewer_container_position(GtkWidget
*container
, GtkWidget
*child
)
546 if(child
== NULL
) return -1;
550 memset(&value
, 0, sizeof(GValue
));
551 g_value_init(&value
, G_TYPE_INT
);
552 gtk_container_child_get_property(GTK_CONTAINER(container
),
556 pos
= g_value_get_int(&value
);
562 /* move_*_viewer functions move the selected view up/down in
566 void move_down_viewer(GtkWidget
* widget
, gpointer user_data
)
568 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
570 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
571 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
578 ptab
= g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
582 //gtk_multivpaned_widget_move_up(GTK_MULTIVPANED(tab->multivpaned));
584 /* change the position in the vbox */
585 GtkWidget
*focus_widget
;
587 focus_widget
= viewer_container_focus(tab
->viewer_container
);
588 position
= viewer_container_position(tab
->viewer_container
, focus_widget
);
591 /* can move up one position */
592 gtk_box_reorder_child(GTK_BOX(tab
->viewer_container
),
599 void move_up_viewer(GtkWidget
* widget
, gpointer user_data
)
601 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
603 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
604 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
611 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
615 //gtk_multivpaned_widget_move_down(GTK_MULTIVPANED(tab->multivpaned));
616 /* change the position in the vbox */
617 GtkWidget
*focus_widget
;
619 focus_widget
= viewer_container_focus(tab
->viewer_container
);
620 position
= viewer_container_position(tab
->viewer_container
, focus_widget
);
624 g_list_length(gtk_container_get_children(
625 GTK_CONTAINER(tab
->viewer_container
)))-1
627 /* can move down one position */
628 gtk_box_reorder_child(GTK_BOX(tab
->viewer_container
),
636 /* delete_viewer deletes the selected viewer in the current tab
639 void delete_viewer(GtkWidget
* widget
, gpointer user_data
)
641 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
643 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
644 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
651 ptab
= g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
655 //gtk_multivpaned_widget_delete(GTK_MULTIVPANED(tab->multivpaned));
657 GtkWidget
*focus_widget
= viewer_container_focus(tab
->viewer_container
);
659 if(focus_widget
!= NULL
)
660 gtk_widget_destroy(focus_widget
);
662 g_object_set_data(G_OBJECT(tab
->viewer_container
), "focused_viewer", NULL
);
666 /* open_traceset will open a traceset saved in a file
667 * Right now, it is not finished yet, (not working)
671 void open_traceset(GtkWidget
* widget
, gpointer user_data
)
675 LttvTraceset
* traceset
;
676 MainWindow
* mw_data
= get_window_data_struct(widget
);
677 GtkFileSelection
* file_selector
=
678 (GtkFileSelection
*)gtk_file_selection_new("Select a traceset");
680 gtk_file_selection_hide_fileop_buttons(file_selector
);
682 gtk_window_set_transient_for(GTK_WINDOW(file_selector
),
683 GTK_WINDOW(mw_data
->mwindow
));
685 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
687 case GTK_RESPONSE_ACCEPT
:
688 case GTK_RESPONSE_OK
:
689 dir
= gtk_file_selection_get_selections (file_selector
);
690 traceset
= lttv_traceset_load(dir
[0]);
691 g_info("Open a trace set %s\n", dir
[0]);
694 case GTK_RESPONSE_REJECT
:
695 case GTK_RESPONSE_CANCEL
:
697 gtk_widget_destroy((GtkWidget
*)file_selector
);
703 /* lttvwindow_process_pending_requests
705 * Process requests for parts of the trace from viewers.
707 * These requests are made by lttvwindow_events_request().
709 * This internal function gets called by g_idle, taking care of the pending
710 * requests. It is responsible for concatenation of time intervals and position
711 * requests. It does it with the following algorithm organizing process traceset
712 * calls. Here is the detailed description of the way it works :
714 * - Events Requests Servicing Algorithm
716 * Data structures necessary :
718 * List of requests added to context : list_in
719 * List of requests not added to context : list_out
724 * list_out : many events requests
726 * FIXME : insert rest of algorithm here
730 #define list_out tab->events_requests
732 gboolean
lttvwindow_process_pending_requests(Tab
*tab
)
734 LttvTracesetContext
*tsc
;
735 LttvTracefileContext
*tfc
;
736 GSList
*list_in
= NULL
;
740 LttvTracesetContextPosition
*end_position
;
742 if(lttvwindow_preempt_count
> 0) return TRUE
;
745 g_critical("Foreground processing : tab does not exist. Processing removed.");
749 /* There is no events requests pending : we should never have been called! */
750 g_assert(g_slist_length(list_out
) != 0);
752 tsc
= LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
754 //set the cursor to be X shape, indicating that the computer is busy in doing its job
756 new = gdk_cursor_new(GDK_X_CURSOR
);
757 widget
= lookup_widget(tab
->mw
->mwindow
, "MToolbar1");
758 win
= gtk_widget_get_parent_window(widget
);
759 gdk_window_set_cursor(win
, new);
760 gdk_cursor_unref(new);
761 gdk_window_stick(win
);
762 gdk_window_unstick(win
);
765 g_debug("SIZE events req len : %d", g_slist_length(list_out
));
767 /* Preliminary check for no trace in traceset */
768 /* Unregister the routine if empty, empty list_out too */
769 if(lttv_traceset_number(tsc
->ts
) == 0) {
771 /* - For each req in list_out */
772 GSList
*iter
= list_out
;
774 while(iter
!= NULL
) {
776 gboolean remove
= FALSE
;
777 gboolean free_data
= FALSE
;
778 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
780 /* - Call end request for req */
781 if(events_request
->servicing
== TRUE
)
782 lttv_hooks_call(events_request
->after_request
, (gpointer
)tsc
);
784 /* - remove req from list_out */
785 /* Destroy the request */
792 GSList
*remove_iter
= iter
;
794 iter
= g_slist_next(iter
);
795 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
796 list_out
= g_slist_remove_link(list_out
, remove_iter
);
797 } else { // not remove
798 iter
= g_slist_next(iter
);
803 /* 0.1 Lock Traces */
808 iter_trace
<lttv_traceset_number(tsc
->ts
);
810 LttvTrace
*trace_v
= lttv_traceset_get(tsc
->ts
, iter_trace
);
812 if(lttvwindowtraces_lock(trace_v
) != 0) {
813 g_critical("Foreground processing : Unable to get trace lock");
814 return TRUE
; /* Cannot get lock, try later */
819 /* 0.2 Seek tracefiles positions to context position */
820 //g_assert(lttv_process_traceset_seek_position(tsc, sync_position) == 0);
821 lttv_process_traceset_synchronize_tracefiles(tsc
);
824 /* Events processing algorithm implementation */
825 /* Warning : the gtk_events_pending takes a LOT of cpu time. So what we do
826 * instead is to leave the control to GTK and take it back.
828 /* A. Servicing loop */
829 //while( (g_slist_length(list_in) != 0 || g_slist_length(list_out) != 0)) {
830 if((g_slist_length(list_in
) != 0 || g_slist_length(list_out
) != 0)) {
832 /* 1. If list_in is empty (need a seek) */
833 if( g_slist_length(list_in
) == 0 ) {
835 /* list in is empty, need a seek */
837 /* 1.1 Add requests to list_in */
838 GSList
*ltime
= NULL
;
842 /* 1.1.1 Find all time requests with the lowest start time in list_out
845 if(g_slist_length(list_out
) > 0)
846 ltime
= g_slist_append(ltime
, g_slist_nth_data(list_out
, 0));
847 for(iter
=g_slist_nth(list_out
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
848 /* Find all time requests with the lowest start time in list_out */
849 EventsRequest
*event_request_ltime
= (EventsRequest
*)g_slist_nth_data(ltime
, 0);
850 EventsRequest
*event_request_list_out
= (EventsRequest
*)iter
->data
;
853 comp
= ltt_time_compare(event_request_ltime
->start_time
,
854 event_request_list_out
->start_time
);
856 ltime
= g_slist_append(ltime
, event_request_list_out
);
858 /* Remove all elements from ltime, and add current */
860 ltime
= g_slist_delete_link(ltime
, g_slist_nth(ltime
, 0));
861 ltime
= g_slist_append(ltime
, event_request_list_out
);
865 /* 1.1.2 Find all position requests with the lowest position in list_out
868 if(g_slist_length(list_out
) > 0)
869 lpos
= g_slist_append(lpos
, g_slist_nth_data(list_out
, 0));
870 for(iter
=g_slist_nth(list_out
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
871 /* Find all position requests with the lowest position in list_out */
872 EventsRequest
*event_request_lpos
= (EventsRequest
*)g_slist_nth_data(lpos
, 0);
873 EventsRequest
*event_request_list_out
= (EventsRequest
*)iter
->data
;
876 if(event_request_lpos
->start_position
!= NULL
877 && event_request_list_out
->start_position
!= NULL
)
879 comp
= lttv_traceset_context_pos_pos_compare
880 (event_request_lpos
->start_position
,
881 event_request_list_out
->start_position
);
886 lpos
= g_slist_append(lpos
, event_request_list_out
);
888 /* Remove all elements from lpos, and add current */
890 lpos
= g_slist_delete_link(lpos
, g_slist_nth(lpos
, 0));
891 lpos
= g_slist_append(lpos
, event_request_list_out
);
896 EventsRequest
*event_request_lpos
= (EventsRequest
*)g_slist_nth_data(lpos
, 0);
897 EventsRequest
*event_request_ltime
= (EventsRequest
*)g_slist_nth_data(ltime
, 0);
898 LttTime lpos_start_time
;
900 if(event_request_lpos
!= NULL
901 && event_request_lpos
->start_position
!= NULL
) {
902 lpos_start_time
= lttv_traceset_context_position_get_time(
903 event_request_lpos
->start_position
);
906 /* 1.1.3 If lpos.start time < ltime */
907 if(event_request_lpos
!= NULL
908 && event_request_lpos
->start_position
!= NULL
909 && ltt_time_compare(lpos_start_time
,
910 event_request_ltime
->start_time
)<0) {
911 /* Add lpos to list_in, remove them from list_out */
912 for(iter
=lpos
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
914 EventsRequest
*event_request_lpos
=
915 (EventsRequest
*)iter
->data
;
917 list_in
= g_slist_append(list_in
, event_request_lpos
);
918 /* Remove from list_out */
919 list_out
= g_slist_remove(list_out
, event_request_lpos
);
922 /* 1.1.4 (lpos.start time >= ltime) */
923 /* Add ltime to list_in, remove them from list_out */
925 for(iter
=ltime
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
927 EventsRequest
*event_request_ltime
=
928 (EventsRequest
*)iter
->data
;
930 list_in
= g_slist_append(list_in
, event_request_ltime
);
931 /* Remove from list_out */
932 list_out
= g_slist_remove(list_out
, event_request_ltime
);
942 tfc
= lttv_traceset_context_get_current_tfc(tsc
);
943 g_assert(g_slist_length(list_in
)>0);
944 EventsRequest
*events_request
= g_slist_nth_data(list_in
, 0);
947 /* 1.2.1 If first request in list_in is a time request */
948 if(events_request
->start_position
== NULL
) {
949 /* - If first req in list_in start time != current time */
950 if(tfc
== NULL
|| ltt_time_compare(events_request
->start_time
,
951 tfc
->timestamp
) != 0)
952 /* - Seek to that time */
953 g_debug("SEEK TIME : %lu, %lu", events_request
->start_time
.tv_sec
,
954 events_request
->start_time
.tv_nsec
);
955 //lttv_process_traceset_seek_time(tsc, events_request->start_time);
956 lttv_state_traceset_seek_time_closest(LTTV_TRACESET_STATE(tsc
),
957 events_request
->start_time
);
959 /* Process the traceset with only state hooks */
961 lttv_process_traceset_middle(tsc
,
962 events_request
->start_time
,
965 g_assert(seek_count
< LTTV_STATE_SAVE_INTERVAL
);
971 LttvTracefileContext
*tfc
=
972 lttv_traceset_context_get_current_tfc(tsc
);
973 /* Else, the first request in list_in is a position request */
974 /* If first req in list_in pos != current pos */
975 g_assert(events_request
->start_position
!= NULL
);
976 g_debug("SEEK POS time : %lu, %lu",
977 lttv_traceset_context_position_get_time(
978 events_request
->start_position
).tv_sec
,
979 lttv_traceset_context_position_get_time(
980 events_request
->start_position
).tv_nsec
);
983 g_debug("SEEK POS context time : %lu, %lu",
984 tfc
->timestamp
.tv_sec
,
985 tfc
->timestamp
.tv_nsec
);
987 g_debug("SEEK POS context time : %lu, %lu",
988 ltt_time_infinite
.tv_sec
,
989 ltt_time_infinite
.tv_nsec
);
991 g_assert(events_request
->start_position
!= NULL
);
992 if(lttv_traceset_context_ctx_pos_compare(tsc
,
993 events_request
->start_position
) != 0) {
994 /* 1.2.2.1 Seek to that position */
995 g_debug("SEEK POSITION");
996 //lttv_process_traceset_seek_position(tsc, events_request->start_position);
997 pos_time
= lttv_traceset_context_position_get_time(
998 events_request
->start_position
);
1000 lttv_state_traceset_seek_time_closest(LTTV_TRACESET_STATE(tsc
),
1003 /* Process the traceset with only state hooks */
1005 lttv_process_traceset_middle(tsc
,
1008 events_request
->start_position
);
1009 g_assert(lttv_traceset_context_ctx_pos_compare(tsc
,
1010 events_request
->start_position
) == 0);
1017 /* 1.3 Add hooks and call before request for all list_in members */
1019 GSList
*iter
= NULL
;
1021 for(iter
=list_in
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
1022 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1023 /* 1.3.1 If !servicing */
1024 if(events_request
->servicing
== FALSE
) {
1025 /* - begin request hooks called
1026 * - servicing = TRUE
1028 lttv_hooks_call(events_request
->before_request
, (gpointer
)tsc
);
1029 events_request
->servicing
= TRUE
;
1031 /* 1.3.2 call before chunk
1032 * 1.3.3 events hooks added
1034 if(events_request
->trace
== -1)
1035 lttv_process_traceset_begin(tsc
,
1036 events_request
->before_chunk_traceset
,
1037 events_request
->before_chunk_trace
,
1038 events_request
->before_chunk_tracefile
,
1039 events_request
->event
,
1040 events_request
->event_by_id_channel
);
1042 guint nb_trace
= lttv_traceset_number(tsc
->ts
);
1043 g_assert((guint
)events_request
->trace
< nb_trace
&&
1044 events_request
->trace
> -1);
1045 LttvTraceContext
*tc
= tsc
->traces
[events_request
->trace
];
1047 lttv_hooks_call(events_request
->before_chunk_traceset
, tsc
);
1049 lttv_trace_context_add_hooks(tc
,
1050 events_request
->before_chunk_trace
,
1051 events_request
->before_chunk_tracefile
,
1052 events_request
->event
,
1053 events_request
->event_by_id_channel
);
1058 /* 2. Else, list_in is not empty, we continue a read */
1061 /* 2.0 For each req of list_in */
1062 GSList
*iter
= list_in
;
1064 while(iter
!= NULL
) {
1066 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1068 /* - Call before chunk
1069 * - events hooks added
1071 if(events_request
->trace
== -1)
1072 lttv_process_traceset_begin(tsc
,
1073 events_request
->before_chunk_traceset
,
1074 events_request
->before_chunk_trace
,
1075 events_request
->before_chunk_tracefile
,
1076 events_request
->event
,
1077 events_request
->event_by_id_channel
);
1079 guint nb_trace
= lttv_traceset_number(tsc
->ts
);
1080 g_assert((guint
)events_request
->trace
< nb_trace
&&
1081 events_request
->trace
> -1);
1082 LttvTraceContext
*tc
= tsc
->traces
[events_request
->trace
];
1084 lttv_hooks_call(events_request
->before_chunk_traceset
, tsc
);
1086 lttv_trace_context_add_hooks(tc
,
1087 events_request
->before_chunk_trace
,
1088 events_request
->before_chunk_tracefile
,
1089 events_request
->event
,
1090 events_request
->event_by_id_channel
);
1093 iter
= g_slist_next(iter
);
1098 tfc
= lttv_traceset_context_get_current_tfc(tsc
);
1100 /* 2.1 For each req of list_out */
1101 GSList
*iter
= list_out
;
1103 while(iter
!= NULL
) {
1105 gboolean remove
= FALSE
;
1106 gboolean free_data
= FALSE
;
1107 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1109 /* if req.start time == current context time
1110 * or req.start position == current position*/
1111 if( ltt_time_compare(events_request
->start_time
,
1112 tfc
->timestamp
) == 0
1114 (events_request
->start_position
!= NULL
1116 lttv_traceset_context_ctx_pos_compare(tsc
,
1117 events_request
->start_position
) == 0)
1119 /* - Add to list_in, remove from list_out */
1120 list_in
= g_slist_append(list_in
, events_request
);
1124 /* - If !servicing */
1125 if(events_request
->servicing
== FALSE
) {
1126 /* - begin request hooks called
1127 * - servicing = TRUE
1129 lttv_hooks_call(events_request
->before_request
, (gpointer
)tsc
);
1130 events_request
->servicing
= TRUE
;
1132 /* call before chunk
1133 * events hooks added
1135 if(events_request
->trace
== -1)
1136 lttv_process_traceset_begin(tsc
,
1137 events_request
->before_chunk_traceset
,
1138 events_request
->before_chunk_trace
,
1139 events_request
->before_chunk_tracefile
,
1140 events_request
->event
,
1141 events_request
->event_by_id_channel
);
1143 guint nb_trace
= lttv_traceset_number(tsc
->ts
);
1144 g_assert((guint
)events_request
->trace
< nb_trace
&&
1145 events_request
->trace
> -1);
1146 LttvTraceContext
*tc
= tsc
->traces
[events_request
->trace
];
1148 lttv_hooks_call(events_request
->before_chunk_traceset
, tsc
);
1150 lttv_trace_context_add_hooks(tc
,
1151 events_request
->before_chunk_trace
,
1152 events_request
->before_chunk_tracefile
,
1153 events_request
->event
,
1154 events_request
->event_by_id_channel
);
1163 GSList
*remove_iter
= iter
;
1165 iter
= g_slist_next(iter
);
1166 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
1167 list_out
= g_slist_remove_link(list_out
, remove_iter
);
1168 } else { // not remove
1169 iter
= g_slist_next(iter
);
1175 /* 3. Find end criterions */
1180 /* 3.1.1 Find lowest end time in list_in */
1181 g_assert(g_slist_length(list_in
)>0);
1182 end_time
= ((EventsRequest
*)g_slist_nth_data(list_in
,0))->end_time
;
1184 for(iter
=g_slist_nth(list_in
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
1185 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1187 if(ltt_time_compare(events_request
->end_time
,
1189 end_time
= events_request
->end_time
;
1192 /* 3.1.2 Find lowest start time in list_out */
1193 for(iter
=list_out
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
1194 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1196 if(ltt_time_compare(events_request
->start_time
,
1198 end_time
= events_request
->start_time
;
1203 /* 3.2 Number of events */
1205 /* 3.2.1 Find lowest number of events in list_in */
1208 end_nb_events
= ((EventsRequest
*)g_slist_nth_data(list_in
,0))->num_events
;
1210 for(iter
=g_slist_nth(list_in
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
1211 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1213 if(events_request
->num_events
< end_nb_events
)
1214 end_nb_events
= events_request
->num_events
;
1217 /* 3.2.2 Use min(CHUNK_NUM_EVENTS, min num events in list_in) as
1220 end_nb_events
= MIN(CHUNK_NUM_EVENTS
, end_nb_events
);
1224 /* 3.3 End position */
1226 /* 3.3.1 Find lowest end position in list_in */
1229 end_position
=((EventsRequest
*)g_slist_nth_data(list_in
,0))->end_position
;
1231 for(iter
=g_slist_nth(list_in
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
1232 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1234 if(events_request
->end_position
!= NULL
&& end_position
!= NULL
&&
1235 lttv_traceset_context_pos_pos_compare(events_request
->end_position
,
1237 end_position
= events_request
->end_position
;
1242 /* 3.3.2 Find lowest start position in list_out */
1245 for(iter
=list_out
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
1246 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1248 if(events_request
->end_position
!= NULL
&& end_position
!= NULL
&&
1249 lttv_traceset_context_pos_pos_compare(events_request
->end_position
,
1251 end_position
= events_request
->end_position
;
1256 /* 4. Call process traceset middle */
1257 g_debug("Calling process traceset middle with %p, %lu sec %lu nsec, %u nb ev, %p end pos", tsc
, end_time
.tv_sec
, end_time
.tv_nsec
, end_nb_events
, end_position
);
1258 count
= lttv_process_traceset_middle(tsc
, end_time
, end_nb_events
, end_position
);
1260 tfc
= lttv_traceset_context_get_current_tfc(tsc
);
1262 g_debug("Context time after middle : %lu, %lu", tfc
->timestamp
.tv_sec
,
1263 tfc
->timestamp
.tv_nsec
);
1265 g_debug("End of trace reached after middle.");
1269 /* 5. After process traceset middle */
1270 tfc
= lttv_traceset_context_get_current_tfc(tsc
);
1272 /* - if current context time > traceset.end time */
1273 if(tfc
== NULL
|| ltt_time_compare(tfc
->timestamp
,
1274 tsc
->time_span
.end_time
) > 0) {
1275 /* - For each req in list_in */
1276 GSList
*iter
= list_in
;
1278 while(iter
!= NULL
) {
1280 gboolean remove
= FALSE
;
1281 gboolean free_data
= FALSE
;
1282 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1284 /* - Remove events hooks for req
1285 * - Call end chunk for req
1288 if(events_request
->trace
== -1)
1289 lttv_process_traceset_end(tsc
,
1290 events_request
->after_chunk_traceset
,
1291 events_request
->after_chunk_trace
,
1292 events_request
->after_chunk_tracefile
,
1293 events_request
->event
,
1294 events_request
->event_by_id_channel
);
1297 guint nb_trace
= lttv_traceset_number(tsc
->ts
);
1298 g_assert(events_request
->trace
< nb_trace
&&
1299 events_request
->trace
> -1);
1300 LttvTraceContext
*tc
= tsc
->traces
[events_request
->trace
];
1302 lttv_trace_context_remove_hooks(tc
,
1303 events_request
->after_chunk_trace
,
1304 events_request
->after_chunk_tracefile
,
1305 events_request
->event
,
1306 events_request
->event_by_id_channel
);
1307 lttv_hooks_call(events_request
->after_chunk_traceset
, tsc
);
1312 /* - Call end request for req */
1313 lttv_hooks_call(events_request
->after_request
, (gpointer
)tsc
);
1315 /* - remove req from list_in */
1316 /* Destroy the request */
1323 GSList
*remove_iter
= iter
;
1325 iter
= g_slist_next(iter
);
1326 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
1327 list_in
= g_slist_remove_link(list_in
, remove_iter
);
1328 } else { // not remove
1329 iter
= g_slist_next(iter
);
1334 /* 5.1 For each req in list_in */
1335 GSList
*iter
= list_in
;
1337 while(iter
!= NULL
) {
1339 gboolean remove
= FALSE
;
1340 gboolean free_data
= FALSE
;
1341 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1343 /* - Remove events hooks for req
1344 * - Call end chunk for req
1346 if(events_request
->trace
== -1)
1347 lttv_process_traceset_end(tsc
,
1348 events_request
->after_chunk_traceset
,
1349 events_request
->after_chunk_trace
,
1350 events_request
->after_chunk_tracefile
,
1351 events_request
->event
,
1352 events_request
->event_by_id_channel
);
1355 guint nb_trace
= lttv_traceset_number(tsc
->ts
);
1356 g_assert(events_request
->trace
< nb_trace
&&
1357 events_request
->trace
> -1);
1358 LttvTraceContext
*tc
= tsc
->traces
[events_request
->trace
];
1360 lttv_trace_context_remove_hooks(tc
,
1361 events_request
->after_chunk_trace
,
1362 events_request
->after_chunk_tracefile
,
1363 events_request
->event
,
1364 events_request
->event_by_id_channel
);
1366 lttv_hooks_call(events_request
->after_chunk_traceset
, tsc
);
1369 /* - req.num -= count */
1370 g_assert(events_request
->num_events
>= count
);
1371 events_request
->num_events
-= count
;
1373 g_assert(tfc
!= NULL
);
1374 /* - if req.num == 0
1376 * current context time >= req.end time
1378 * req.end pos == current pos
1380 * req.stop_flag == TRUE
1382 if( events_request
->num_events
== 0
1384 events_request
->stop_flag
== TRUE
1386 ltt_time_compare(tfc
->timestamp
,
1387 events_request
->end_time
) >= 0
1389 (events_request
->end_position
!= NULL
1391 lttv_traceset_context_ctx_pos_compare(tsc
,
1392 events_request
->end_position
) == 0)
1395 g_assert(events_request
->servicing
== TRUE
);
1396 /* - Call end request for req
1397 * - remove req from list_in */
1398 lttv_hooks_call(events_request
->after_request
, (gpointer
)tsc
);
1399 /* - remove req from list_in */
1400 /* Destroy the request */
1408 GSList
*remove_iter
= iter
;
1410 iter
= g_slist_next(iter
);
1411 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
1412 list_in
= g_slist_remove_link(list_in
, remove_iter
);
1413 } else { // not remove
1414 iter
= g_slist_next(iter
);
1420 /* End of removed servicing loop : leave control to GTK instead. */
1421 // if(gtk_events_pending()) break;
1424 /* B. When interrupted between chunks */
1427 GSList
*iter
= list_in
;
1429 /* 1. for each request in list_in */
1430 while(iter
!= NULL
) {
1432 gboolean remove
= FALSE
;
1433 gboolean free_data
= FALSE
;
1434 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1436 /* 1.1. Use current postition as start position */
1437 if(events_request
->start_position
!= NULL
)
1438 lttv_traceset_context_position_destroy(events_request
->start_position
);
1439 events_request
->start_position
= lttv_traceset_context_position_new(tsc
);
1440 lttv_traceset_context_position_save(tsc
, events_request
->start_position
);
1442 /* 1.2. Remove start time */
1443 events_request
->start_time
= ltt_time_infinite
;
1445 /* 1.3. Move from list_in to list_out */
1448 list_out
= g_slist_append(list_out
, events_request
);
1453 GSList
*remove_iter
= iter
;
1455 iter
= g_slist_next(iter
);
1456 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
1457 list_in
= g_slist_remove_link(list_in
, remove_iter
);
1458 } else { // not remove
1459 iter
= g_slist_next(iter
);
1465 /* C Unlock Traces */
1467 lttv_process_traceset_get_sync_data(tsc
);
1468 //lttv_traceset_context_position_save(tsc, sync_position);
1473 iter_trace
<lttv_traceset_number(tsc
->ts
);
1475 LttvTrace
*trace_v
= lttv_traceset_get(tsc
->ts
, iter_trace
);
1477 lttvwindowtraces_unlock(trace_v
);
1481 //set the cursor back to normal
1482 gdk_window_set_cursor(win
, NULL
);
1485 g_assert(g_slist_length(list_in
) == 0);
1487 if( g_slist_length(list_out
) == 0 ) {
1488 /* Put tab's request pending flag back to normal */
1489 tab
->events_request_pending
= FALSE
;
1490 g_debug("remove the idle fct");
1491 return FALSE
; /* Remove the idle function */
1493 g_debug("leave the idle fct");
1494 return TRUE
; /* Leave the idle function */
1496 /* We do not use simili-round-robin, it may require to read 1 meg buffers
1497 * again and again if many tracesets use the same tracefiles. */
1498 /* Hack for round-robin idle functions */
1499 /* It will put the idle function at the end of the pool */
1500 /*g_idle_add_full((G_PRIORITY_HIGH_IDLE + 21),
1501 (GSourceFunc)execute_events_requests,
1511 static void lttvwindow_add_trace(Tab
*tab
, LttvTrace
*trace_v
)
1513 LttvTraceset
*traceset
= tab
->traceset_info
->traceset
;
1515 guint num_traces
= lttv_traceset_number(traceset
);
1517 //Verify if trace is already present.
1518 for(i
=0; i
<num_traces
; i
++)
1520 LttvTrace
* trace
= lttv_traceset_get(traceset
, i
);
1521 if(trace
== trace_v
)
1525 //Keep a reference to the traces so they are not freed.
1526 for(i
=0; i
<lttv_traceset_number(traceset
); i
++)
1528 LttvTrace
* trace
= lttv_traceset_get(traceset
, i
);
1529 lttv_trace_ref(trace
);
1532 //remove state update hooks
1533 lttv_state_remove_event_hooks(
1534 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1536 lttv_context_fini(LTTV_TRACESET_CONTEXT(
1537 tab
->traceset_info
->traceset_context
));
1538 g_object_unref(tab
->traceset_info
->traceset_context
);
1540 lttv_traceset_add(traceset
, trace_v
);
1541 lttv_trace_ref(trace_v
); /* local ref */
1543 /* Create new context */
1544 tab
->traceset_info
->traceset_context
=
1545 g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
1547 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->
1552 //add state update hooks
1553 lttv_state_add_event_hooks(
1554 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1555 //Remove local reference to the traces.
1556 for(i
=0; i
<lttv_traceset_number(traceset
); i
++)
1558 LttvTrace
* trace
= lttv_traceset_get(traceset
, i
);
1559 lttv_trace_unref(trace
);
1563 //add_trace_into_traceset_selector(GTK_MULTIVPANED(tab->multivpaned), lttv_trace(trace_v));
1566 /* add_trace adds a trace into the current traceset. It first displays a
1567 * directory selection dialogue to let user choose a trace, then recreates
1568 * tracset_context, and redraws all the viewer of the current tab
1571 void add_trace(GtkWidget
* widget
, gpointer user_data
)
1574 LttvTrace
* trace_v
;
1575 LttvTraceset
* traceset
;
1577 char abs_path
[PATH_MAX
];
1579 MainWindow
* mw_data
= get_window_data_struct(widget
);
1580 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
1582 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
1583 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
1584 LttvPluginTab
*ptab
;
1588 ptab
= create_new_tab(widget
, NULL
);
1591 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
1595 /* File open dialog management */
1596 GtkFileChooser
* file_chooser
=
1598 gtk_file_chooser_dialog_new ("Select a trace",
1599 GTK_WINDOW(mw_data
->mwindow
),
1600 GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER
,
1601 GTK_STOCK_CANCEL
, GTK_RESPONSE_CANCEL
,
1602 GTK_STOCK_OPEN
, GTK_RESPONSE_ACCEPT
,
1605 gtk_file_chooser_set_show_hidden (file_chooser
, TRUE
);
1606 if(remember_trace_dir
[0] != '\0')
1607 gtk_file_chooser_set_filename(file_chooser
, remember_trace_dir
);
1609 id
= gtk_dialog_run(GTK_DIALOG(file_chooser
));
1612 case GTK_RESPONSE_ACCEPT
:
1613 case GTK_RESPONSE_OK
:
1614 dir
= gtk_file_chooser_get_filename (file_chooser
);
1615 strncpy(remember_trace_dir
, dir
, PATH_MAX
);
1616 strncat(remember_trace_dir
, "/", PATH_MAX
);
1617 if(!dir
|| strlen(dir
) == 0){
1620 get_absolute_pathname(dir
, abs_path
);
1621 trace_v
= lttvwindowtraces_get_trace_by_name(abs_path
);
1622 if(trace_v
== NULL
) {
1623 trace
= ltt_trace_open(abs_path
);
1625 g_warning("cannot open trace %s", abs_path
);
1627 GtkWidget
*dialogue
=
1628 gtk_message_dialog_new(
1629 GTK_WINDOW(gtk_widget_get_toplevel(widget
)),
1630 GTK_DIALOG_MODAL
|GTK_DIALOG_DESTROY_WITH_PARENT
,
1633 "Cannot open trace : maybe you should enter in the trace "
1634 "directory to select it ?");
1635 gtk_dialog_run(GTK_DIALOG(dialogue
));
1636 gtk_widget_destroy(dialogue
);
1639 trace_v
= lttv_trace_new(trace
);
1640 lttvwindowtraces_add_trace(trace_v
);
1641 lttvwindow_add_trace(tab
, trace_v
);
1644 lttvwindow_add_trace(tab
, trace_v
);
1648 //update current tab
1649 //update_traceset(mw_data);
1651 /* Call the updatetraceset hooks */
1653 traceset
= tab
->traceset_info
->traceset
;
1654 SetTraceset(tab
, traceset
);
1655 // in expose now call_pending_read_hooks(mw_data);
1657 //lttvwindow_report_current_time(mw_data,&(tab->current_time));
1659 case GTK_RESPONSE_REJECT
:
1660 case GTK_RESPONSE_CANCEL
:
1664 gtk_widget_destroy((GtkWidget
*)file_chooser
);
1668 /* remove_trace removes a trace from the current traceset if all viewers in
1669 * the current tab are not interested in the trace. It first displays a
1670 * dialogue, which shows all traces in the current traceset, to let user choose
1671 * a trace, then it checks if all viewers unselect the trace, if it is true,
1672 * it will remove the trace, recreate the traceset_contex,
1673 * and redraws all the viewer of the current tab. If there is on trace in the
1674 * current traceset, it will delete all viewers of the current tab
1676 * It destroys the filter tree. FIXME... we should request for an update
1680 void remove_trace(GtkWidget
*widget
, gpointer user_data
)
1683 LttvTrace
* trace_v
;
1684 LttvTraceset
* traceset
;
1685 gint i
, j
, nb_trace
, index
=-1;
1686 char ** name
, *remove_trace_name
;
1687 MainWindow
* mw_data
= get_window_data_struct(widget
);
1688 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
1690 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
1691 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
1697 LttvPluginTab
*ptab
;
1698 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
1702 nb_trace
=lttv_traceset_number(tab
->traceset_info
->traceset
);
1703 name
= g_new(char*,nb_trace
);
1704 for(i
= 0; i
< nb_trace
; i
++){
1705 trace_v
= lttv_traceset_get(tab
->traceset_info
->traceset
, i
);
1706 trace
= lttv_trace(trace_v
);
1707 name
[i
] = (char *) g_quark_to_string(ltt_trace_name(trace
));
1710 remove_trace_name
= get_remove_trace(mw_data
, name
, nb_trace
);
1713 if(remove_trace_name
){
1715 /* yuk, cut n paste from old code.. should be better (MD)*/
1716 for(i
= 0; i
<nb_trace
; i
++) {
1717 if(strcmp(remove_trace_name
,name
[i
]) == 0){
1722 traceset
= tab
->traceset_info
->traceset
;
1723 //Keep a reference to the traces so they are not freed.
1724 for(j
=0; j
<lttv_traceset_number(traceset
); j
++)
1726 LttvTrace
* trace
= lttv_traceset_get(traceset
, j
);
1727 lttv_trace_ref(trace
);
1730 //remove state update hooks
1731 lttv_state_remove_event_hooks(
1732 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1733 lttv_context_fini(LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
));
1734 g_object_unref(tab
->traceset_info
->traceset_context
);
1736 trace_v
= lttv_traceset_get(traceset
, index
);
1738 lttv_traceset_remove(traceset
, index
);
1739 lttv_trace_unref(trace_v
); // Remove local reference
1741 if(lttv_trace_get_ref_number(trace_v
) <= 1) {
1742 /* ref 1 : lttvwindowtraces only*/
1743 ltt_trace_close(lttv_trace(trace_v
));
1744 /* lttvwindowtraces_remove_trace takes care of destroying
1745 * the traceset linked with the trace_v and also of destroying
1746 * the trace_v at the same time.
1748 lttvwindowtraces_remove_trace(trace_v
);
1751 tab
->traceset_info
->traceset_context
=
1752 g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
1754 LTTV_TRACESET_CONTEXT(tab
->
1755 traceset_info
->traceset_context
),traceset
);
1756 //add state update hooks
1757 lttv_state_add_event_hooks(
1758 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1760 //Remove local reference to the traces.
1761 for(j
=0; j
<lttv_traceset_number(traceset
); j
++)
1763 LttvTrace
* trace
= lttv_traceset_get(traceset
, j
);
1764 lttv_trace_unref(trace
);
1767 SetTraceset(tab
, (gpointer
)traceset
);
1773 void remove_trace(GtkWidget
* widget
, gpointer user_data
)
1776 LttvTrace
* trace_v
;
1777 LttvTraceset
* traceset
;
1778 gint i
, j
, nb_trace
;
1779 char ** name
, *remove_trace_name
;
1780 MainWindow
* mw_data
= get_window_data_struct(widget
);
1781 LttvTracesetSelector
* s
;
1782 LttvTraceSelector
* t
;
1785 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
1787 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
1788 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
1794 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
1797 nb_trace
=lttv_traceset_number(tab
->traceset_info
->traceset
);
1798 name
= g_new(char*,nb_trace
);
1799 for(i
= 0; i
< nb_trace
; i
++){
1800 trace_v
= lttv_traceset_get(tab
->traceset_info
->traceset
, i
);
1801 trace
= lttv_trace(trace_v
);
1802 name
[i
] = ltt_trace_name(trace
);
1805 remove_trace_name
= get_remove_trace(name
, nb_trace
);
1807 if(remove_trace_name
){
1808 for(i
=0; i
<nb_trace
; i
++){
1809 if(strcmp(remove_trace_name
,name
[i
]) == 0){
1810 //unselect the trace from the current viewer
1812 w
= gtk_multivpaned_get_widget(GTK_MULTIVPANED(tab
->multivpaned
));
1814 s
= g_object_get_data(G_OBJECT(w
), "Traceset_Selector");
1816 t
= lttv_traceset_selector_trace_get(s
,i
);
1817 lttv_trace_selector_set_selected(t
, FALSE
);
1820 //check if other viewers select the trace
1821 w
= gtk_multivpaned_get_first_widget(GTK_MULTIVPANED(tab
->multivpaned
));
1823 s
= g_object_get_data(G_OBJECT(w
), "Traceset_Selector");
1825 t
= lttv_traceset_selector_trace_get(s
,i
);
1826 selected
= lttv_trace_selector_get_selected(t
);
1829 w
= gtk_multivpaned_get_next_widget(GTK_MULTIVPANED(tab
->multivpaned
));
1831 }else selected
= FALSE
;
1833 //if no viewer selects the trace, remove it
1835 remove_trace_from_traceset_selector(GTK_MULTIVPANED(tab
->multivpaned
), i
);
1837 traceset
= tab
->traceset_info
->traceset
;
1838 //Keep a reference to the traces so they are not freed.
1839 for(j
=0; j
<lttv_traceset_number(traceset
); j
++)
1841 LttvTrace
* trace
= lttv_traceset_get(traceset
, j
);
1842 lttv_trace_ref(trace
);
1845 //remove state update hooks
1846 lttv_state_remove_event_hooks(
1847 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1848 lttv_context_fini(LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
));
1849 g_object_unref(tab
->traceset_info
->traceset_context
);
1852 trace_v
= lttv_traceset_get(traceset
, i
);
1854 if(lttv_trace_get_ref_number(trace_v
) <= 2) {
1855 /* ref 2 : traceset, local */
1856 lttvwindowtraces_remove_trace(trace_v
);
1857 ltt_trace_close(lttv_trace(trace_v
));
1860 lttv_traceset_remove(traceset
, i
);
1861 lttv_trace_unref(trace_v
); // Remove local reference
1863 if(!lttv_trace_get_ref_number(trace_v
))
1864 lttv_trace_destroy(trace_v
);
1866 tab
->traceset_info
->traceset_context
=
1867 g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
1869 LTTV_TRACESET_CONTEXT(tab
->
1870 traceset_info
->traceset_context
),traceset
);
1871 //add state update hooks
1872 lttv_state_add_event_hooks(
1873 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1875 //Remove local reference to the traces.
1876 for(j
=0; j
<lttv_traceset_number(traceset
); j
++)
1878 LttvTrace
* trace
= lttv_traceset_get(traceset
, j
);
1879 lttv_trace_unref(trace
);
1883 //update current tab
1884 //update_traceset(mw_data);
1887 SetTraceset(tab
, (gpointer
)traceset
);
1888 // in expose now call_pending_read_hooks(mw_data);
1890 //lttvwindow_report_current_time(mw_data,&(tab->current_time));
1893 // while(tab->multi_vpaned->num_children){
1894 // gtk_multi_vpaned_widget_delete(tab->multi_vpaned);
1908 /* Redraw all the viewers in the current tab */
1909 void redraw(GtkWidget
*widget
, gpointer user_data
)
1911 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
1912 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
1913 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
1920 LttvPluginTab
*ptab
;
1921 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
1926 LttvAttributeValue value
;
1928 retval
= lttv_iattribute_find_by_path(tab
->attributes
, "hooks/redraw", LTTV_POINTER
, &value
);
1931 tmp
= (LttvHooks
*)*(value
.v_pointer
);
1933 lttv_hooks_call(tmp
,NULL
);
1937 void continue_processing(GtkWidget
*widget
, gpointer user_data
)
1939 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
1940 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
1941 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
1948 LttvPluginTab
*ptab
;
1949 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
1954 LttvAttributeValue value
;
1956 retval
= lttv_iattribute_find_by_path(tab
->attributes
, "hooks/continue",
1957 LTTV_POINTER
, &value
);
1960 tmp
= (LttvHooks
*)*(value
.v_pointer
);
1962 lttv_hooks_call(tmp
,NULL
);
1965 /* Stop the processing for the calling main window's current tab.
1966 * It removes every processing requests that are in its list. It does not call
1967 * the end request hooks, because the request is not finished.
1970 void stop_processing(GtkWidget
*widget
, gpointer user_data
)
1972 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
1973 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
1974 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
1979 LttvPluginTab
*ptab
;
1980 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
1983 GSList
*iter
= tab
->events_requests
;
1985 while(iter
!= NULL
) {
1986 GSList
*remove_iter
= iter
;
1987 iter
= g_slist_next(iter
);
1989 g_free(remove_iter
->data
);
1990 tab
->events_requests
=
1991 g_slist_remove_link(tab
->events_requests
, remove_iter
);
1993 tab
->events_request_pending
= FALSE
;
1994 tab
->stop_foreground
= TRUE
;
1995 g_idle_remove_by_data(tab
);
1996 g_assert(g_slist_length(tab
->events_requests
) == 0);
2000 /* save will save the traceset to a file
2001 * Not implemented yet FIXME
2004 void save(GtkWidget
* widget
, gpointer user_data
)
2009 void save_as(GtkWidget
* widget
, gpointer user_data
)
2011 g_info("Save as\n");
2015 /* zoom will change the time_window of all the viewers of the
2016 * current tab, and redisplay them. The main functionality is to
2017 * determine the new time_window of the current tab
2020 void zoom(GtkWidget
* widget
, double size
)
2022 TimeInterval time_span
;
2023 TimeWindow new_time_window
;
2024 LttTime current_time
, time_delta
;
2025 LttvTracesetContext
*tsc
;
2026 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
2028 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2029 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2035 LttvPluginTab
*ptab
;
2036 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
2040 if(size
== 1) return;
2042 tsc
= LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
2043 time_span
= tsc
->time_span
;
2044 new_time_window
= tab
->time_window
;
2045 current_time
= tab
->current_time
;
2047 time_delta
= ltt_time_sub(time_span
.end_time
,time_span
.start_time
);
2049 new_time_window
.start_time
= time_span
.start_time
;
2050 new_time_window
.time_width
= time_delta
;
2051 new_time_window
.time_width_double
= ltt_time_to_double(time_delta
);
2052 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
2053 new_time_window
.time_width
) ;
2055 new_time_window
.time_width
= ltt_time_div(new_time_window
.time_width
, size
);
2056 new_time_window
.time_width_double
=
2057 ltt_time_to_double(new_time_window
.time_width
);
2058 if(ltt_time_compare(new_time_window
.time_width
,time_delta
) > 0)
2059 { /* Case where zoom out is bigger than trace length */
2060 new_time_window
.start_time
= time_span
.start_time
;
2061 new_time_window
.time_width
= time_delta
;
2062 new_time_window
.time_width_double
= ltt_time_to_double(time_delta
);
2063 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
2064 new_time_window
.time_width
) ;
2068 /* Center the image on the current time */
2069 new_time_window
.start_time
=
2070 ltt_time_sub(current_time
,
2071 ltt_time_from_double(new_time_window
.time_width_double
/2.0));
2072 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
2073 new_time_window
.time_width
) ;
2074 /* If on borders, don't fall off */
2075 if(ltt_time_compare(new_time_window
.start_time
, time_span
.start_time
) <0
2076 || ltt_time_compare(new_time_window
.start_time
, time_span
.end_time
) >0)
2078 new_time_window
.start_time
= time_span
.start_time
;
2079 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
2080 new_time_window
.time_width
) ;
2084 if(ltt_time_compare(new_time_window
.end_time
,
2085 time_span
.end_time
) > 0
2086 || ltt_time_compare(new_time_window
.end_time
,
2087 time_span
.start_time
) < 0)
2089 new_time_window
.start_time
=
2090 ltt_time_sub(time_span
.end_time
, new_time_window
.time_width
);
2092 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
2093 new_time_window
.time_width
) ;
2100 if(ltt_time_compare(new_time_window
.time_width
, ltt_time_zero
) == 0) {
2101 g_warning("Zoom more than 1 ns impossible");
2103 time_change_manager(tab
, new_time_window
);
2107 void zoom_in(GtkWidget
* widget
, gpointer user_data
)
2112 void zoom_out(GtkWidget
* widget
, gpointer user_data
)
2117 void zoom_extended(GtkWidget
* widget
, gpointer user_data
)
2122 void go_to_time(GtkWidget
* widget
, gpointer user_data
)
2124 g_info("Go to time\n");
2127 void show_time_frame(GtkWidget
* widget
, gpointer user_data
)
2129 g_info("Show time frame\n");
2133 /* callback function */
2136 on_empty_traceset_activate (GtkMenuItem
*menuitem
,
2139 create_new_window((GtkWidget
*)menuitem
, user_data
, FALSE
);
2144 on_clone_traceset_activate (GtkMenuItem
*menuitem
,
2147 create_new_window((GtkWidget
*)menuitem
, user_data
, TRUE
);
2151 /* create_new_tab calls create_tab to construct a new tab in the main window
2154 LttvPluginTab
*create_new_tab(GtkWidget
* widget
, gpointer user_data
)
2156 gchar label
[PATH_MAX
];
2157 MainWindow
* mw_data
= get_window_data_struct(widget
);
2159 GtkNotebook
* notebook
= (GtkNotebook
*)lookup_widget(widget
, "MNotebook");
2160 if(notebook
== NULL
){
2161 g_info("Notebook does not exist\n");
2164 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2165 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2171 LttvPluginTab
*ptab
;
2172 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
2173 copy_tab
= ptab
->tab
;
2176 strcpy(label
,"Page");
2177 if(get_label(mw_data
, label
,"Get the name of the tab","Please input tab's name")) {
2178 LttvPluginTab
*ptab
;
2180 ptab
= g_object_new(LTTV_TYPE_PLUGIN_TAB
, NULL
);
2181 init_tab (ptab
->tab
, mw_data
, copy_tab
, notebook
, label
);
2182 ptab
->parent
.top_widget
= ptab
->tab
->top_widget
;
2183 g_object_set_data_full(
2184 G_OBJECT(ptab
->tab
->vbox
),
2187 (GDestroyNotify
)tab_destructor
);
2194 on_tab_activate (GtkMenuItem
*menuitem
,
2197 create_new_tab((GtkWidget
*)menuitem
, user_data
);
2202 on_open_activate (GtkMenuItem
*menuitem
,
2205 open_traceset((GtkWidget
*)menuitem
, user_data
);
2210 on_close_activate (GtkMenuItem
*menuitem
,
2213 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2214 main_window_destructor(mw_data
);
2218 /* remove the current tab from the main window
2222 on_close_tab_activate (GtkWidget
*widget
,
2226 GtkWidget
* notebook
;
2227 notebook
= lookup_widget(widget
, "MNotebook");
2228 if(notebook
== NULL
){
2229 g_info("Notebook does not exist\n");
2233 page_num
= gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
));
2235 gtk_notebook_remove_page(GTK_NOTEBOOK(notebook
), page_num
);
2240 on_close_tab_X_clicked (GtkWidget
*widget
,
2244 GtkWidget
*notebook
= lookup_widget(widget
, "MNotebook");
2245 if(notebook
== NULL
){
2246 g_info("Notebook does not exist\n");
2250 if((page_num
= gtk_notebook_page_num(GTK_NOTEBOOK(notebook
), widget
)) != -1)
2251 gtk_notebook_remove_page(GTK_NOTEBOOK(notebook
), page_num
);
2257 on_add_trace_activate (GtkMenuItem
*menuitem
,
2260 add_trace((GtkWidget
*)menuitem
, user_data
);
2265 on_remove_trace_activate (GtkMenuItem
*menuitem
,
2268 remove_trace((GtkWidget
*)menuitem
, user_data
);
2273 on_save_activate (GtkMenuItem
*menuitem
,
2276 save((GtkWidget
*)menuitem
, user_data
);
2281 on_save_as_activate (GtkMenuItem
*menuitem
,
2284 save_as((GtkWidget
*)menuitem
, user_data
);
2289 on_quit_activate (GtkMenuItem
*menuitem
,
2292 while (g_slist_length(g_main_window_list
) != 0) {
2293 on_MWindow_destroy(((MainWindow
*)g_main_window_list
->data
)->mwindow
,
2300 on_cut_activate (GtkMenuItem
*menuitem
,
2308 on_copy_activate (GtkMenuItem
*menuitem
,
2316 on_paste_activate (GtkMenuItem
*menuitem
,
2324 on_delete_activate (GtkMenuItem
*menuitem
,
2332 on_zoom_in_activate (GtkMenuItem
*menuitem
,
2335 zoom_in((GtkWidget
*)menuitem
, user_data
);
2340 on_zoom_out_activate (GtkMenuItem
*menuitem
,
2343 zoom_out((GtkWidget
*)menuitem
, user_data
);
2348 on_zoom_extended_activate (GtkMenuItem
*menuitem
,
2351 zoom_extended((GtkWidget
*)menuitem
, user_data
);
2356 on_go_to_time_activate (GtkMenuItem
*menuitem
,
2359 go_to_time((GtkWidget
*)menuitem
, user_data
);
2364 on_show_time_frame_activate (GtkMenuItem
*menuitem
,
2367 show_time_frame((GtkWidget
*)menuitem
, user_data
);
2372 on_move_viewer_up_activate (GtkMenuItem
*menuitem
,
2375 move_up_viewer((GtkWidget
*)menuitem
, user_data
);
2380 on_move_viewer_down_activate (GtkMenuItem
*menuitem
,
2383 move_down_viewer((GtkWidget
*)menuitem
, user_data
);
2388 on_remove_viewer_activate (GtkMenuItem
*menuitem
,
2391 delete_viewer((GtkWidget
*)menuitem
, user_data
);
2395 on_trace_facility_activate (GtkMenuItem
*menuitem
,
2398 g_info("Trace facility selector: %s\n", "");
2402 /* Dispaly a file selection dialogue to let user select a library, then call
2403 * lttv_library_load().
2407 on_load_library_activate (GtkMenuItem
*menuitem
,
2410 GError
*error
= NULL
;
2411 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2413 gchar load_module_path_alter
[PATH_MAX
];
2417 gchar
*load_module_path
;
2418 name
= g_ptr_array_new();
2419 nb
= lttv_library_path_number();
2420 /* ask for the library path */
2424 path
= lttv_library_path_get(i
);
2425 g_ptr_array_add(name
, path
);
2428 load_module_path
= get_selection(mw_data
,
2429 (char **)(name
->pdata
), name
->len
,
2430 "Select a library path", "Library paths");
2431 if(load_module_path
!= NULL
)
2432 strncpy(load_module_path_alter
, load_module_path
, PATH_MAX
-1); // -1 for /
2434 g_ptr_array_free(name
, TRUE
);
2436 if(load_module_path
== NULL
) return;
2440 /* Make sure the module path ends with a / */
2441 gchar
*ptr
= load_module_path_alter
;
2443 ptr
= strchr(ptr
, '\0');
2445 if(*(ptr
-1) != '/') {
2452 /* Ask for the library to load : list files in the previously selected
2454 gchar str
[PATH_MAX
];
2457 GtkFileSelection
* file_selector
=
2458 (GtkFileSelection
*)gtk_file_selection_new("Select a module");
2459 gtk_file_selection_set_filename(file_selector
, load_module_path_alter
);
2460 gtk_file_selection_hide_fileop_buttons(file_selector
);
2462 gtk_window_set_transient_for(GTK_WINDOW(file_selector
),
2463 GTK_WINDOW(mw_data
->mwindow
));
2466 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
2468 case GTK_RESPONSE_ACCEPT
:
2469 case GTK_RESPONSE_OK
:
2470 dir
= gtk_file_selection_get_selections (file_selector
);
2471 strncpy(str
,dir
[0],PATH_MAX
);
2472 strncpy(remember_plugins_dir
,dir
[0],PATH_MAX
);
2473 /* only keep file name */
2475 str1
= strrchr(str
,'/');
2478 str1
= strrchr(str
,'\\');
2483 if(*str1
== 'l' && *(str1
+1)== 'i' && *(str1
+2)=='b')
2485 remove info after
. */
2489 str2
= strrchr(str2
, '.');
2490 if(str2
!= NULL
) *str2
= '\0';
2492 lttv_module_require(str1
, &error
);
2494 lttv_library_load(str1
, &error
);
2495 if(error
!= NULL
) g_warning("%s", error
->message
);
2496 else g_info("Load library: %s\n", str
);
2498 case GTK_RESPONSE_REJECT
:
2499 case GTK_RESPONSE_CANCEL
:
2501 gtk_widget_destroy((GtkWidget
*)file_selector
);
2512 /* Display all loaded modules, let user to select a module to unload
2513 * by calling lttv_module_unload
2517 on_unload_library_activate (GtkMenuItem
*menuitem
,
2520 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2522 LttvLibrary
*library
= NULL
;
2527 name
= g_ptr_array_new();
2528 nb
= lttv_library_number();
2529 LttvLibraryInfo
*lib_info
= g_new(LttvLibraryInfo
,nb
);
2530 /* ask for the library name */
2533 LttvLibrary
*iter_lib
= lttv_library_get(i
);
2534 lttv_library_info(iter_lib
, &lib_info
[i
]);
2536 gchar
*path
= lib_info
[i
].name
;
2537 g_ptr_array_add(name
, path
);
2539 lib_name
= get_selection(mw_data
, (char **)(name
->pdata
), name
->len
,
2540 "Select a library", "Libraries");
2541 if(lib_name
!= NULL
) {
2543 if(strcmp(lib_name
, lib_info
[i
].name
) == 0) {
2544 library
= lttv_library_get(i
);
2549 g_ptr_array_free(name
, TRUE
);
2552 if(lib_name
== NULL
) return;
2554 if(library
!= NULL
) lttv_library_unload(library
);
2558 /* Dispaly a file selection dialogue to let user select a module, then call
2559 * lttv_module_require().
2563 on_load_module_activate (GtkMenuItem
*menuitem
,
2566 GError
*error
= NULL
;
2567 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2569 LttvLibrary
*library
= NULL
;
2574 name
= g_ptr_array_new();
2575 nb
= lttv_library_number();
2576 LttvLibraryInfo
*lib_info
= g_new(LttvLibraryInfo
,nb
);
2577 /* ask for the library name */
2580 LttvLibrary
*iter_lib
= lttv_library_get(i
);
2581 lttv_library_info(iter_lib
, &lib_info
[i
]);
2583 gchar
*path
= lib_info
[i
].name
;
2584 g_ptr_array_add(name
, path
);
2586 lib_name
= get_selection(mw_data
,(char **)(name
->pdata
), name
->len
,
2587 "Select a library", "Libraries");
2588 if(lib_name
!= NULL
) {
2590 if(strcmp(lib_name
, lib_info
[i
].name
) == 0) {
2591 library
= lttv_library_get(i
);
2596 g_ptr_array_free(name
, TRUE
);
2599 if(lib_name
== NULL
) return;
2602 //LttvModule *module;
2603 gchar module_name_out
[PATH_MAX
];
2605 /* Ask for the module to load : list modules in the selected lib */
2609 nb
= lttv_library_module_number(library
);
2610 LttvModuleInfo
*module_info
= g_new(LttvModuleInfo
,nb
);
2611 name
= g_ptr_array_new();
2612 /* ask for the module name */
2615 LttvModule
*iter_module
= lttv_library_module_get(library
, i
);
2616 lttv_module_info(iter_module
, &module_info
[i
]);
2618 gchar
*path
= module_info
[i
].name
;
2619 g_ptr_array_add(name
, path
);
2621 module_name
= get_selection(mw_data
, (char **)(name
->pdata
), name
->len
,
2622 "Select a module", "Modules");
2623 if(module_name
!= NULL
) {
2625 if(strcmp(module_name
, module_info
[i
].name
) == 0) {
2626 strncpy(module_name_out
, module_name
, PATH_MAX
);
2627 //module = lttv_library_module_get(i);
2633 g_ptr_array_free(name
, TRUE
);
2634 g_free(module_info
);
2636 if(module_name
== NULL
) return;
2639 lttv_module_require(module_name_out
, &error
);
2640 if(error
!= NULL
) g_warning("%s", error
->message
);
2641 else g_info("Load module: %s", module_name_out
);
2648 gchar str
[PATH_MAX
];
2651 GtkFileSelection
* file_selector
=
2652 (GtkFileSelection
*)gtk_file_selection_new("Select a module");
2653 gtk_file_selection_set_filename(file_selector
, load_module_path_alter
);
2654 gtk_file_selection_hide_fileop_buttons(file_selector
);
2657 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
2659 case GTK_RESPONSE_ACCEPT
:
2660 case GTK_RESPONSE_OK
:
2661 dir
= gtk_file_selection_get_selections (file_selector
);
2662 strncpy(str
,dir
[0],PATH_MAX
);
2663 strncpy(remember_plugins_dir
,dir
[0],PATH_MAX
);
2665 /* only keep file name */
2667 str1
= strrchr(str
,'/');
2670 str1
= strrchr(str
,'\\');
2675 if(*str1
== 'l' && *(str1
+1)== 'i' && *(str1
+2)=='b')
2677 remove info after
. */
2681 str2
= strrchr(str2
, '.');
2682 if(str2
!= NULL
) *str2
= '\0';
2684 lttv_module_require(str1
, &error
);
2686 lttv_library_load(str1
, &error
);
2687 if(error
!= NULL
) g_warning(error
->message
);
2688 else g_info("Load library: %s\n", str
);
2690 case GTK_RESPONSE_REJECT
:
2691 case GTK_RESPONSE_CANCEL
:
2693 gtk_widget_destroy((GtkWidget
*)file_selector
);
2705 /* Display all loaded modules, let user to select a module to unload
2706 * by calling lttv_module_unload
2710 on_unload_module_activate (GtkMenuItem
*menuitem
,
2713 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2715 LttvLibrary
*library
= NULL
;
2720 name
= g_ptr_array_new();
2721 nb
= lttv_library_number();
2722 LttvLibraryInfo
*lib_info
= g_new(LttvLibraryInfo
,nb
);
2723 /* ask for the library name */
2726 LttvLibrary
*iter_lib
= lttv_library_get(i
);
2727 lttv_library_info(iter_lib
, &lib_info
[i
]);
2729 gchar
*path
= lib_info
[i
].name
;
2730 g_ptr_array_add(name
, path
);
2732 lib_name
= get_selection(mw_data
, (char **)(name
->pdata
), name
->len
,
2733 "Select a library", "Libraries");
2734 if(lib_name
!= NULL
) {
2736 if(strcmp(lib_name
, lib_info
[i
].name
) == 0) {
2737 library
= lttv_library_get(i
);
2742 g_ptr_array_free(name
, TRUE
);
2745 if(lib_name
== NULL
) return;
2748 LttvModule
*module
= NULL
;
2750 /* Ask for the module to load : list modules in the selected lib */
2754 nb
= lttv_library_module_number(library
);
2755 LttvModuleInfo
*module_info
= g_new(LttvModuleInfo
,nb
);
2756 name
= g_ptr_array_new();
2757 /* ask for the module name */
2760 LttvModule
*iter_module
= lttv_library_module_get(library
, i
);
2761 lttv_module_info(iter_module
, &module_info
[i
]);
2763 gchar
*path
= module_info
[i
].name
;
2764 if(module_info
[i
].use_count
> 0) g_ptr_array_add(name
, path
);
2766 module_name
= get_selection(mw_data
, (char **)(name
->pdata
), name
->len
,
2767 "Select a module", "Modules");
2768 if(module_name
!= NULL
) {
2770 if(strcmp(module_name
, module_info
[i
].name
) == 0) {
2771 module
= lttv_library_module_get(library
, i
);
2777 g_ptr_array_free(name
, TRUE
);
2778 g_free(module_info
);
2780 if(module_name
== NULL
) return;
2783 LttvModuleInfo module_info
;
2784 lttv_module_info(module
, &module_info
);
2785 g_info("Release module: %s\n", module_info
.name
);
2787 lttv_module_release(module
);
2791 /* Display a directory dialogue to let user select a path for library searching
2795 on_add_library_search_path_activate (GtkMenuItem
*menuitem
,
2798 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2799 //GtkDirSelection * file_selector = (GtkDirSelection *)gtk_dir_selection_new("Select library path");
2800 GtkFileSelection
* file_selector
= (GtkFileSelection
*)gtk_file_selection_new("Select a trace");
2801 gtk_widget_hide( (file_selector
)->file_list
->parent
) ;
2803 gtk_window_set_transient_for(GTK_WINDOW(file_selector
),
2804 GTK_WINDOW(mw_data
->mwindow
));
2809 if(remember_plugins_dir
[0] != '\0')
2810 gtk_file_selection_set_filename(file_selector
, remember_plugins_dir
);
2812 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
2814 case GTK_RESPONSE_ACCEPT
:
2815 case GTK_RESPONSE_OK
:
2816 dir
= gtk_file_selection_get_filename (file_selector
);
2817 strncpy(remember_plugins_dir
,dir
,PATH_MAX
);
2818 strncat(remember_plugins_dir
,"/",PATH_MAX
);
2819 lttv_library_path_add(dir
);
2820 case GTK_RESPONSE_REJECT
:
2821 case GTK_RESPONSE_CANCEL
:
2823 gtk_widget_destroy((GtkWidget
*)file_selector
);
2829 /* Display a directory dialogue to let user select a path for library searching
2833 on_remove_library_search_path_activate (GtkMenuItem
*menuitem
,
2836 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2838 const char *lib_path
;
2842 name
= g_ptr_array_new();
2843 nb
= lttv_library_path_number();
2844 /* ask for the library name */
2847 gchar
*path
= lttv_library_path_get(i
);
2848 g_ptr_array_add(name
, path
);
2850 lib_path
= get_selection(mw_data
, (char **)(name
->pdata
), name
->len
,
2851 "Select a library path", "Library paths");
2853 g_ptr_array_free(name
, TRUE
);
2855 if(lib_path
== NULL
) return;
2858 lttv_library_path_remove(lib_path
);
2862 on_color_activate (GtkMenuItem
*menuitem
,
2870 on_save_configuration_activate (GtkMenuItem
*menuitem
,
2873 g_info("Save configuration\n");
2878 on_content_activate (GtkMenuItem
*menuitem
,
2881 g_info("Content\n");
2886 on_about_close_activate (GtkButton
*button
,
2889 GtkWidget
*about_widget
= GTK_WIDGET(user_data
);
2891 gtk_widget_destroy(about_widget
);
2895 on_about_activate (GtkMenuItem
*menuitem
,
2898 MainWindow
*main_window
= get_window_data_struct(GTK_WIDGET(menuitem
));
2899 GtkWidget
*window_widget
= main_window
->mwindow
;
2900 GtkWidget
*about_widget
= gtk_window_new(GTK_WINDOW_TOPLEVEL
);
2901 GtkWindow
*about_window
= GTK_WINDOW(about_widget
);
2902 gint window_width
, window_height
;
2904 gtk_window_set_title(about_window
, "About Linux Trace Toolkit");
2906 gtk_window_set_resizable(about_window
, FALSE
);
2907 gtk_window_set_transient_for(about_window
, GTK_WINDOW(window_widget
));
2908 gtk_window_set_destroy_with_parent(about_window
, TRUE
);
2909 gtk_window_set_modal(about_window
, FALSE
);
2911 /* Put the about window at the center of the screen */
2912 gtk_window_get_size(about_window
, &window_width
, &window_height
);
2913 gtk_window_move (about_window
,
2914 (gdk_screen_width() - window_width
)/2,
2915 (gdk_screen_height() - window_height
)/2);
2917 GtkWidget
*vbox
= gtk_vbox_new(FALSE
, 1);
2919 gtk_container_add(GTK_CONTAINER(about_widget
), vbox
);
2923 GtkWidget
*label1
= gtk_label_new("");
2924 gtk_misc_set_padding(GTK_MISC(label1
), 10, 20);
2925 gtk_label_set_markup(GTK_LABEL(label1
), "\
2926 <big>Linux Trace Toolkit " VERSION
"</big>");
2927 gtk_label_set_justify(GTK_LABEL(label1
), GTK_JUSTIFY_CENTER
);
2929 GtkWidget
*label2
= gtk_label_new("");
2930 gtk_misc_set_padding(GTK_MISC(label2
), 10, 20);
2931 gtk_label_set_markup(GTK_LABEL(label2
), "\
2934 Michel Dagenais (New trace format, lttv main)\n\
2935 Mathieu Desnoyers (Kernel Tracer, Directory structure, build with automake/conf,\n\
2936 lttv gui, control flow view, gui cooperative trace reading\n\
2937 scheduler with interruptible foreground and background\n\
2938 computation, detailed event list (rewrite), trace reading\n\
2939 library (rewrite))\n\
2940 Benoit Des Ligneris, Eric Clement (Cluster adaptation, work in progress)\n\
2941 Xang-Xiu Yang (new trace reading library and converter, lttv gui, \n\
2942 detailed event list and statistics view)\n\
2943 Tom Zanussi (RelayFS)\n\
2945 Inspired from the original Linux Trace Toolkit Visualizer made by\n\
2948 GtkWidget
*label3
= gtk_label_new("");
2949 gtk_label_set_markup(GTK_LABEL(label3
), "\
2950 Linux Trace Toolkit Viewer, Copyright (C) 2004, 2005, 2006\n\
2952 Mathieu Desnoyers\n\
2954 Linux Trace Toolkit comes with ABSOLUTELY NO WARRANTY.\n\
2955 This is free software, and you are welcome to redistribute it\n\
2956 under certain conditions. See COPYING for details.");
2957 gtk_misc_set_padding(GTK_MISC(label3
), 10, 20);
2959 gtk_box_pack_start_defaults(GTK_BOX(vbox
), label1
);
2960 gtk_box_pack_start_defaults(GTK_BOX(vbox
), label2
);
2961 gtk_box_pack_start_defaults(GTK_BOX(vbox
), label3
);
2963 GtkWidget
*hbox
= gtk_hbox_new(TRUE
, 0);
2964 gtk_box_pack_end(GTK_BOX(vbox
), hbox
, FALSE
, FALSE
, 0);
2965 GtkWidget
*close_button
= gtk_button_new_with_mnemonic("_Close");
2966 gtk_box_pack_end(GTK_BOX(hbox
), close_button
, FALSE
, FALSE
, 0);
2967 gtk_container_set_border_width(GTK_CONTAINER(close_button
), 20);
2969 g_signal_connect(G_OBJECT(close_button
), "clicked",
2970 G_CALLBACK(on_about_close_activate
),
2971 (gpointer
)about_widget
);
2973 gtk_widget_show_all(about_widget
);
2978 on_button_new_clicked (GtkButton
*button
,
2981 create_new_window((GtkWidget
*)button
, user_data
, TRUE
);
2985 on_button_new_tab_clicked (GtkButton
*button
,
2988 create_new_tab((GtkWidget
*)button
, user_data
);
2992 on_button_open_clicked (GtkButton
*button
,
2995 open_traceset((GtkWidget
*)button
, user_data
);
3000 on_button_add_trace_clicked (GtkButton
*button
,
3003 add_trace((GtkWidget
*)button
, user_data
);
3008 on_button_remove_trace_clicked (GtkButton
*button
,
3011 remove_trace((GtkWidget
*)button
, user_data
);
3015 on_button_redraw_clicked (GtkButton
*button
,
3018 redraw((GtkWidget
*)button
, user_data
);
3022 on_button_continue_processing_clicked (GtkButton
*button
,
3025 continue_processing((GtkWidget
*)button
, user_data
);
3029 on_button_stop_processing_clicked (GtkButton
*button
,
3032 stop_processing((GtkWidget
*)button
, user_data
);
3038 on_button_save_clicked (GtkButton
*button
,
3041 save((GtkWidget
*)button
, user_data
);
3046 on_button_save_as_clicked (GtkButton
*button
,
3049 save_as((GtkWidget
*)button
, user_data
);
3054 on_button_zoom_in_clicked (GtkButton
*button
,
3057 zoom_in((GtkWidget
*)button
, user_data
);
3062 on_button_zoom_out_clicked (GtkButton
*button
,
3065 zoom_out((GtkWidget
*)button
, user_data
);
3070 on_button_zoom_extended_clicked (GtkButton
*button
,
3073 zoom_extended((GtkWidget
*)button
, user_data
);
3078 on_button_go_to_time_clicked (GtkButton
*button
,
3081 go_to_time((GtkWidget
*)button
, user_data
);
3086 on_button_show_time_frame_clicked (GtkButton
*button
,
3089 show_time_frame((GtkWidget
*)button
, user_data
);
3094 on_button_move_up_clicked (GtkButton
*button
,
3097 move_up_viewer((GtkWidget
*)button
, user_data
);
3102 on_button_move_down_clicked (GtkButton
*button
,
3105 move_down_viewer((GtkWidget
*)button
, user_data
);
3110 on_button_delete_viewer_clicked (GtkButton
*button
,
3113 delete_viewer((GtkWidget
*)button
, user_data
);
3117 on_MWindow_destroy (GtkWidget
*widget
,
3120 MainWindow
*main_window
= get_window_data_struct(widget
);
3121 LttvIAttribute
*attributes
= main_window
->attributes
;
3122 LttvAttributeValue value
;
3125 //This is unnecessary, since widgets will be destroyed
3126 //by the main window widget anyway.
3127 //remove_all_menu_toolbar_constructors(main_window, NULL);
3129 retval
= lttv_iattribute_find_by_path(attributes
, "viewers/menu",
3130 LTTV_POINTER
, &value
);
3132 lttv_menus_destroy((LttvMenus
*)*(value
.v_pointer
));
3134 retval
= lttv_iattribute_find_by_path(attributes
, "viewers/toolbar",
3135 LTTV_POINTER
, &value
);
3137 lttv_toolbars_destroy((LttvToolbars
*)*(value
.v_pointer
));
3139 g_object_unref(main_window
->attributes
);
3140 g_main_window_list
= g_slist_remove(g_main_window_list
, main_window
);
3142 g_info("There are now : %d windows\n",g_slist_length(g_main_window_list
));
3143 if(g_slist_length(g_main_window_list
) == 0)
3148 on_MWindow_configure (GtkWidget
*widget
,
3149 GdkEventConfigure
*event
,
3152 // MD : removed time width modification upon resizing of the main window.
3153 // The viewers will redraw themselves completely, without time interval
3156 if(mw_data->window_width){
3157 time_span = LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context)->Time_Span ;
3158 time_win = tab->time_window;
3159 ratio = width / mw_data->window_width;
3160 tab->time_window.time_width = ltt_time_mul(time_win.time_width,ratio);
3161 time = ltt_time_sub(time_span->endTime, time_win.start_time);
3162 if(ltt_time_compare(time, tab->time_window.time_width) < 0){
3163 tab->time_window.time_width = time;
3169 mw_data->window_width = (int)width;
3178 on_MNotebook_switch_page (GtkNotebook
*notebook
,
3179 GtkNotebookPage
*page
,
3187 void time_change_manager (Tab
*tab
,
3188 TimeWindow new_time_window
)
3190 /* Only one source of time change */
3191 if(tab
->time_manager_lock
== TRUE
) return;
3193 tab
->time_manager_lock
= TRUE
;
3195 LttvTracesetContext
*tsc
= LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3196 TimeInterval time_span
= tsc
->time_span
;
3197 LttTime start_time
= new_time_window
.start_time
;
3198 LttTime end_time
= new_time_window
.end_time
;
3199 LttTime time_width
= new_time_window
.time_width
;
3201 g_assert(ltt_time_compare(start_time
, end_time
) < 0);
3204 GtkAdjustment
*adjustment
= gtk_range_get_adjustment(GTK_RANGE(tab
->scrollbar
));
3205 LttTime upper
= ltt_time_sub(time_span
.end_time
, time_span
.start_time
);
3207 gtk_range_set_increments(GTK_RANGE(tab
->scrollbar
),
3208 ltt_time_to_double(new_time_window
.time_width
)
3209 / SCROLL_STEP_PER_PAGE
3210 * NANOSECONDS_PER_SECOND
, /* step increment */
3211 ltt_time_to_double(new_time_window
.time_width
)
3212 * NANOSECONDS_PER_SECOND
); /* page increment */
3213 gtk_range_set_range(GTK_RANGE(tab
->scrollbar
),
3215 ltt_time_to_double(upper
)
3216 * NANOSECONDS_PER_SECOND
); /* upper */
3218 g_object_set(G_OBJECT(adjustment
),
3222 ltt_time_to_double(upper
), /* upper */
3224 new_time_window
.time_width_double
3225 / SCROLL_STEP_PER_PAGE
, /* step increment */
3227 new_time_window
.time_width_double
,
3228 /* page increment */
3230 new_time_window
.time_width_double
, /* page size */
3232 gtk_adjustment_changed(adjustment
);
3234 // g_object_set(G_OBJECT(adjustment),
3236 // ltt_time_to_double(
3237 // ltt_time_sub(start_time, time_span.start_time))
3240 //gtk_adjustment_value_changed(adjustment);
3241 gtk_range_set_value(GTK_RANGE(tab
->scrollbar
),
3243 ltt_time_sub(start_time
, time_span
.start_time
)) /* value */);
3245 /* set the time bar. */
3248 timebar_set_minmax_time(TIMEBAR(tab
->MTimebar
),
3249 &time_span
.start_time
,
3250 &time_span
.end_time
);
3251 timebar_set_start_time(TIMEBAR(tab
->MTimebar
),&start_time
);
3252 timebar_set_end_time(TIMEBAR(tab
->MTimebar
),&end_time
);
3256 /* call viewer hooks for new time window */
3257 set_time_window(tab
, &new_time_window
);
3259 tab
->time_manager_lock
= FALSE
;
3266 void current_time_change_manager (Tab
*tab
,
3267 LttTime new_current_time
)
3269 /* Only one source of time change */
3270 if(tab
->current_time_manager_lock
== TRUE
) return;
3272 tab
->current_time_manager_lock
= TRUE
;
3274 LttvTracesetContext
*tsc
= LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3275 TimeInterval time_span
= tsc
->time_span
;
3277 timebar_set_current_time(TIMEBAR(tab
->MTimebar
), &new_current_time
);
3279 set_current_time(tab
, &new_current_time
);
3281 tab
->current_time_manager_lock
= FALSE
;
3284 void current_position_change_manager(Tab
*tab
,
3285 LttvTracesetContextPosition
*pos
)
3287 LttvTracesetContext
*tsc
=
3288 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3291 retval
= lttv_process_traceset_seek_position(tsc
, pos
);
3292 g_assert_cmpint(retval
, ==, 0);
3293 LttTime new_time
= lttv_traceset_context_position_get_time(pos
);
3294 /* Put the context in a state coherent position */
3295 lttv_state_traceset_seek_time_closest((LttvTracesetState
*)tsc
, ltt_time_zero
);
3297 current_time_change_manager(tab
, new_time
);
3299 set_current_position(tab
, pos
);
3303 static void on_timebar_starttime_changed(Timebar
*timebar
,
3306 Tab
*tab
= (Tab
*)user_data
;
3307 LttvTracesetContext
* tsc
=
3308 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3309 TimeInterval time_span
= tsc
->time_span
;
3311 TimeWindow new_time_window
= tab
->time_window
;
3312 new_time_window
.start_time
= timebar_get_start_time(timebar
);
3314 LttTime end_time
= new_time_window
.end_time
;
3316 /* TODO ybrosseau 2010-12-02: This if should have been checked
3317 by the timebar already */
3318 if(ltt_time_compare(new_time_window
.start_time
, end_time
) >= 0) {
3319 /* Then, we must push back end time : keep the same time width
3320 * if possible, else end traceset time */
3321 end_time
= LTT_TIME_MIN(ltt_time_add(new_time_window
.start_time
,
3322 new_time_window
.time_width
),
3323 time_span
.end_time
);
3326 /* Fix the time width to fit start time and end time */
3327 new_time_window
.time_width
= ltt_time_sub(end_time
,
3328 new_time_window
.start_time
);
3330 new_time_window
.time_width_double
=
3331 ltt_time_to_double(new_time_window
.time_width
);
3333 new_time_window
.end_time
= end_time
;
3335 /* Notify the time_manager */
3336 time_change_manager(tab
, new_time_window
);
3340 static void on_timebar_endtime_changed(Timebar
*timebar
,
3343 Tab
*tab
= (Tab
*)user_data
;
3344 LttvTracesetContext
* tsc
=
3345 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3346 TimeInterval time_span
= tsc
->time_span
;
3348 TimeWindow new_time_window
= tab
->time_window
;
3350 LttTime end_time
= timebar_get_end_time(timebar
);
3352 /* TODO ybrosseau 2010-12-02: This if should have been
3353 checked by the timebar already */
3354 if(ltt_time_compare(new_time_window
.start_time
, end_time
) >= 0) {
3355 /* Then, we must push front start time : keep the same time
3356 width if possible, else end traceset time */
3357 new_time_window
.start_time
= LTT_TIME_MAX(
3358 ltt_time_sub(end_time
,
3359 new_time_window
.time_width
),
3360 time_span
.start_time
);
3363 /* Fix the time width to fit start time and end time */
3364 new_time_window
.time_width
= ltt_time_sub(end_time
,
3365 new_time_window
.start_time
);
3367 new_time_window
.time_width_double
=
3368 ltt_time_to_double(new_time_window
.time_width
);
3370 new_time_window
.end_time
= end_time
;
3372 /* Notify the time_manager */
3373 time_change_manager(tab
, new_time_window
);
3375 static void on_timebar_currenttime_changed(Timebar
*timebar
,
3378 Tab
*tab
= (Tab
*)user_data
;
3380 LttTime new_current_time
= timebar_get_current_time(timebar
);
3382 current_time_change_manager(tab
, new_current_time
);
3385 void scroll_value_changed_cb(GtkWidget
*scrollbar
,
3388 Tab
*tab
= (Tab
*)user_data
;
3389 TimeWindow new_time_window
;
3391 GtkAdjustment
*adjust
= gtk_range_get_adjustment(GTK_RANGE(scrollbar
));
3392 gdouble value
= gtk_adjustment_get_value(adjust
);
3393 // gdouble upper, lower, ratio, page_size;
3395 LttvTracesetContext
* tsc
=
3396 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3397 TimeInterval time_span
= tsc
->time_span
;
3399 time
= ltt_time_add(ltt_time_from_double(value
),
3400 time_span
.start_time
);
3402 new_time_window
.start_time
= time
;
3404 page_size
= adjust
->page_size
;
3406 new_time_window
.time_width
=
3407 ltt_time_from_double(page_size
);
3409 new_time_window
.time_width_double
=
3412 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
3413 new_time_window
.time_width
);
3416 time_change_manager(tab
, new_time_window
);
3418 //time_window = tab->time_window;
3420 lower
= adjust
->lower
;
3421 upper
= adjust
->upper
;
3422 ratio
= (value
- lower
) / (upper
- lower
);
3423 g_info("lower %lu, upper %lu, value %lu, ratio %lu", lower
, upper
, value
, ratio
);
3425 //time = ltt_time_sub(time_span->end_time, time_span->start_time);
3426 //time = ltt_time_mul(time, (float)ratio);
3427 //time = ltt_time_add(time_span->start_time, time);
3428 time
= ltt_time_add(ltt_time_from_double(value
),
3429 time_span
.start_time
);
3431 time_window
.start_time
= time
;
3433 page_size
= adjust
->page_size
;
3435 time_window
.time_width
=
3436 ltt_time_from_double(page_size
);
3437 //time = ltt_time_sub(time_span.end_time, time);
3438 //if(ltt_time_compare(time,time_window.time_width) < 0){
3439 // time_window.time_width = time;
3442 /* call viewer hooks for new time window */
3443 set_time_window(tab
, &time_window
);
3448 /* Display a dialogue showing all eventtypes and traces, let user to select the interested
3449 * eventtypes, tracefiles and traces (filter)
3452 /* Select a trace which will be removed from traceset
3455 char * get_remove_trace(MainWindow
*mw_data
,
3456 char ** all_trace_name
, int nb_trace
)
3458 return get_selection(mw_data
, all_trace_name
, nb_trace
,
3459 "Select a trace", "Trace pathname");
3463 /* Select a module which will be loaded
3466 char * get_load_module(MainWindow
*mw_data
,
3467 char ** load_module_name
, int nb_module
)
3469 return get_selection(mw_data
, load_module_name
, nb_module
,
3470 "Select a module to load", "Module name");
3476 /* Select a module which will be unloaded
3479 char * get_unload_module(MainWindow
*mw_data
,
3480 char ** loaded_module_name
, int nb_module
)
3482 return get_selection(mw_data
, loaded_module_name
, nb_module
,
3483 "Select a module to unload", "Module name");
3487 /* Display a dialogue which shows all selectable items, let user to
3488 * select one of them
3491 char * get_selection(MainWindow
*mw_data
,
3492 char ** loaded_module_name
, int nb_module
,
3493 char *title
, char * column_title
)
3495 GtkWidget
* dialogue
;
3496 GtkWidget
* scroll_win
;
3498 GtkListStore
* store
;
3499 GtkTreeViewColumn
* column
;
3500 GtkCellRenderer
* renderer
;
3501 GtkTreeSelection
* select
;
3504 char * unload_module_name
= NULL
;
3506 dialogue
= gtk_dialog_new_with_buttons(title
,
3509 GTK_STOCK_OK
,GTK_RESPONSE_ACCEPT
,
3510 GTK_STOCK_CANCEL
,GTK_RESPONSE_REJECT
,
3512 gtk_window_set_default_size((GtkWindow
*)dialogue
, 500, 200);
3513 gtk_window_set_transient_for(GTK_WINDOW(dialogue
),
3514 GTK_WINDOW(mw_data
->mwindow
));
3516 scroll_win
= gtk_scrolled_window_new (NULL
, NULL
);
3517 gtk_widget_show ( scroll_win
);
3518 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll_win
),
3519 GTK_POLICY_AUTOMATIC
, GTK_POLICY_AUTOMATIC
);
3521 store
= gtk_list_store_new (N_COLUMNS
,G_TYPE_STRING
);
3522 tree
= gtk_tree_view_new_with_model(GTK_TREE_MODEL (store
));
3523 gtk_widget_show ( tree
);
3524 g_object_unref (G_OBJECT (store
));
3526 renderer
= gtk_cell_renderer_text_new ();
3527 column
= gtk_tree_view_column_new_with_attributes (column_title
,
3529 "text", MODULE_COLUMN
,
3531 gtk_tree_view_column_set_alignment (column
, 0.5);
3532 gtk_tree_view_column_set_fixed_width (column
, 150);
3533 gtk_tree_view_append_column (GTK_TREE_VIEW (tree
), column
);
3535 select
= gtk_tree_view_get_selection (GTK_TREE_VIEW (tree
));
3536 gtk_tree_selection_set_mode (select
, GTK_SELECTION_SINGLE
);
3538 gtk_container_add (GTK_CONTAINER (scroll_win
), tree
);
3540 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialogue
)->vbox
), scroll_win
,TRUE
, TRUE
,0);
3542 for(i
=0;i
<nb_module
;i
++){
3543 gtk_list_store_append (store
, &iter
);
3544 gtk_list_store_set (store
, &iter
, MODULE_COLUMN
,loaded_module_name
[i
],-1);
3547 id
= gtk_dialog_run(GTK_DIALOG(dialogue
));
3548 GtkTreeModel
**store_model
= (GtkTreeModel
**)&store
;
3550 case GTK_RESPONSE_ACCEPT
:
3551 case GTK_RESPONSE_OK
:
3552 if (gtk_tree_selection_get_selected (select
, store_model
, &iter
)){
3553 gtk_tree_model_get ((GtkTreeModel
*)store
, &iter
, MODULE_COLUMN
, &unload_module_name
, -1);
3555 case GTK_RESPONSE_REJECT
:
3556 case GTK_RESPONSE_CANCEL
:
3558 gtk_widget_destroy(dialogue
);
3562 return unload_module_name
;
3566 /* Insert all menu entry and tool buttons into this main window
3571 void add_all_menu_toolbar_constructors(MainWindow
* mw
, gpointer user_data
)
3575 lttvwindow_viewer_constructor constructor
;
3576 LttvMenus
* global_menu
, * instance_menu
;
3577 LttvToolbars
* global_toolbar
, * instance_toolbar
;
3578 LttvMenuClosure
*menu_item
;
3579 LttvToolbarClosure
*toolbar_item
;
3580 LttvAttributeValue value
;
3581 LttvIAttribute
*global_attributes
= LTTV_IATTRIBUTE(lttv_global_attributes());
3582 LttvIAttribute
*attributes
= mw
->attributes
;
3583 GtkWidget
* tool_menu_title_menu
, *new_widget
, *pixmap
;
3586 retval
= lttv_iattribute_find_by_path(global_attributes
, "viewers/menu",
3587 LTTV_POINTER
, &value
);
3589 if(*(value
.v_pointer
) == NULL
)
3590 *(value
.v_pointer
) = lttv_menus_new();
3591 global_menu
= (LttvMenus
*)*(value
.v_pointer
);
3593 retval
= lttv_iattribute_find_by_path(attributes
, "viewers/menu",
3594 LTTV_POINTER
, &value
);
3596 if(*(value
.v_pointer
) == NULL
)
3597 *(value
.v_pointer
) = lttv_menus_new();
3598 instance_menu
= (LttvMenus
*)*(value
.v_pointer
);
3600 retval
= lttv_iattribute_find_by_path(global_attributes
, "viewers/toolbar",
3601 LTTV_POINTER
, &value
);
3603 if(*(value
.v_pointer
) == NULL
)
3604 *(value
.v_pointer
) = lttv_toolbars_new();
3605 global_toolbar
= (LttvToolbars
*)*(value
.v_pointer
);
3607 retval
= lttv_iattribute_find_by_path(attributes
, "viewers/toolbar",
3608 LTTV_POINTER
, &value
);
3610 if(*(value
.v_pointer
) == NULL
)
3611 *(value
.v_pointer
) = lttv_toolbars_new();
3612 instance_toolbar
= (LttvToolbars
*)*(value
.v_pointer
);
3614 /* Add missing menu entries to window instance */
3615 for(i
=0;i
<global_menu
->len
;i
++) {
3616 menu_item
= &g_array_index(global_menu
, LttvMenuClosure
, i
);
3618 //add menu_item to window instance;
3619 constructor
= menu_item
->con
;
3620 tool_menu_title_menu
= lookup_widget(mw
->mwindow
,"ToolMenuTitle_menu");
3622 gtk_menu_item_new_with_mnemonic (menu_item
->menu_text
);
3623 gtk_container_add (GTK_CONTAINER (tool_menu_title_menu
),
3625 g_signal_connect ((gpointer
) new_widget
, "activate",
3626 G_CALLBACK (insert_viewer_wrap
),
3628 gtk_widget_show (new_widget
);
3629 lttv_menus_add(instance_menu
, menu_item
->con
,
3630 menu_item
->menu_path
,
3631 menu_item
->menu_text
,
3636 /* Add missing toolbar entries to window instance */
3637 for(i
=0;i
<global_toolbar
->len
;i
++) {
3638 toolbar_item
= &g_array_index(global_toolbar
, LttvToolbarClosure
, i
);
3640 //add toolbar_item to window instance;
3641 constructor
= toolbar_item
->con
;
3642 tool_menu_title_menu
= lookup_widget(mw
->mwindow
,"MToolbar1");
3643 pixbuf
= gdk_pixbuf_new_from_xpm_data((const char**)toolbar_item
->pixmap
);
3644 pixmap
= gtk_image_new_from_pixbuf(pixbuf
);
3646 gtk_toolbar_append_element (GTK_TOOLBAR (tool_menu_title_menu
),
3647 GTK_TOOLBAR_CHILD_BUTTON
,
3650 toolbar_item
->tooltip
, NULL
,
3651 pixmap
, NULL
, NULL
);
3652 gtk_label_set_use_underline(
3653 GTK_LABEL (((GtkToolbarChild
*) (
3654 g_list_last (GTK_TOOLBAR
3655 (tool_menu_title_menu
)->children
)->data
))->label
),
3657 gtk_container_set_border_width (GTK_CONTAINER (new_widget
), 1);
3658 g_signal_connect ((gpointer
) new_widget
,
3660 G_CALLBACK (insert_viewer_wrap
),
3662 gtk_widget_show (new_widget
);
3664 lttv_toolbars_add(instance_toolbar
, toolbar_item
->con
,
3665 toolbar_item
->tooltip
,
3666 toolbar_item
->pixmap
,
3674 /* Create a main window
3677 MainWindow
*construct_main_window(MainWindow
* parent
)
3681 g_debug("construct_main_window()");
3682 GtkWidget
* new_window
; /* New generated main window */
3683 MainWindow
* new_m_window
;/* New main window structure */
3684 GtkNotebook
* notebook
;
3685 LttvIAttribute
*attributes
=
3686 LTTV_IATTRIBUTE(g_object_new(LTTV_ATTRIBUTE_TYPE
, NULL
));
3687 LttvAttributeValue value
;
3690 new_m_window
= g_new(MainWindow
, 1);
3692 // Add the object's information to the module's array
3693 g_main_window_list
= g_slist_append(g_main_window_list
, new_m_window
);
3695 new_window
= create_MWindow();
3696 gtk_widget_show (new_window
);
3698 new_m_window
->mwindow
= new_window
;
3699 new_m_window
->attributes
= attributes
;
3701 retval
= lttv_iattribute_find_by_path(attributes
, "viewers/menu",
3702 LTTV_POINTER
, &value
);
3704 *(value
.v_pointer
) = lttv_menus_new();
3706 retval
= lttv_iattribute_find_by_path(attributes
, "viewers/toolbar",
3707 LTTV_POINTER
, &value
);
3709 *(value
.v_pointer
) = lttv_toolbars_new();
3711 add_all_menu_toolbar_constructors(new_m_window
, NULL
);
3713 g_object_set_data_full(G_OBJECT(new_window
),
3715 (gpointer
)new_m_window
,
3716 (GDestroyNotify
)g_free
);
3717 //create a default tab
3718 notebook
= (GtkNotebook
*)lookup_widget(new_m_window
->mwindow
, "MNotebook");
3719 if(notebook
== NULL
){
3720 g_info("Notebook does not exist\n");
3721 /* FIXME : destroy partially created widgets */
3722 g_free(new_m_window
);
3725 //gtk_notebook_popup_enable (GTK_NOTEBOOK(notebook));
3726 //for now there is no name field in LttvTraceset structure
3727 //Use "Traceset" as the label for the default tab
3729 GtkWidget
* parent_notebook
= lookup_widget(parent
->mwindow
, "MNotebook");
3730 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(parent_notebook
),
3731 gtk_notebook_get_current_page(GTK_NOTEBOOK(parent_notebook
)));
3737 LttvPluginTab
*ptab
;
3738 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
3739 parent_tab
= ptab
->tab
;
3741 LttvPluginTab
*ptab
= g_object_new(LTTV_TYPE_PLUGIN_TAB
, NULL
);
3743 new_m_window
, parent_tab
, notebook
, "Traceset");
3744 ptab
->parent
.top_widget
= ptab
->tab
->top_widget
;
3745 g_object_set_data_full(
3746 G_OBJECT(ptab
->tab
->vbox
),
3749 (GDestroyNotify
)tab_destructor
);
3750 new_tab
= ptab
->tab
;
3752 LttvPluginTab
*ptab
= g_object_new(LTTV_TYPE_PLUGIN_TAB
, NULL
);
3753 init_tab(ptab
->tab
, new_m_window
, NULL
, notebook
, "Traceset");
3754 ptab
->parent
.top_widget
= ptab
->tab
->top_widget
;
3755 g_object_set_data_full(
3756 G_OBJECT(ptab
->tab
->vbox
),
3759 (GDestroyNotify
)tab_destructor
);
3760 new_tab
= ptab
->tab
;
3763 /* Insert default viewers */
3765 LttvAttributeType type
;
3766 LttvAttributeName name
;
3767 LttvAttributeValue value
;
3768 LttvAttribute
*attribute
;
3770 LttvIAttribute
*attributes_global
=
3771 LTTV_IATTRIBUTE(lttv_global_attributes());
3773 attribute
= LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
3774 LTTV_IATTRIBUTE(attributes_global
),
3775 LTTV_VIEWER_CONSTRUCTORS
));
3776 g_assert(attribute
);
3778 name
= g_quark_from_string("guievents");
3779 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
3781 if(type
== LTTV_POINTER
) {
3782 lttvwindow_viewer_constructor viewer_constructor
=
3783 (lttvwindow_viewer_constructor
)*value
.v_pointer
;
3784 insert_viewer(new_window
, viewer_constructor
);
3787 name
= g_quark_from_string("guicontrolflow");
3788 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
3790 if(type
== LTTV_POINTER
) {
3791 lttvwindow_viewer_constructor viewer_constructor
=
3792 (lttvwindow_viewer_constructor
)*value
.v_pointer
;
3793 insert_viewer(new_window
, viewer_constructor
);
3796 name
= g_quark_from_string("guistatistics");
3797 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
3799 if(type
== LTTV_POINTER
) {
3800 lttvwindow_viewer_constructor viewer_constructor
=
3801 (lttvwindow_viewer_constructor
)*value
.v_pointer
;
3802 insert_viewer(new_window
, viewer_constructor
);
3806 g_info("There are now : %d windows\n",g_slist_length(g_main_window_list
));
3808 return new_m_window
;
3812 /* Free the memory occupied by a tab structure
3816 void tab_destructor(LttvPluginTab
* ptab
)
3818 int i
, nb
, ref_count
;
3820 Tab
*tab
= ptab
->tab
;
3823 g_object_unref(tab
->attributes
);
3825 if(tab
->interrupted_state
)
3826 g_object_unref(tab
->interrupted_state
);
3829 if(tab
->traceset_info
->traceset_context
!= NULL
){
3830 //remove state update hooks
3831 lttv_state_remove_event_hooks(
3832 (LttvTracesetState
*)tab
->traceset_info
->
3834 lttv_context_fini(LTTV_TRACESET_CONTEXT(tab
->traceset_info
->
3836 g_object_unref(tab
->traceset_info
->traceset_context
);
3838 if(tab
->traceset_info
->traceset
!= NULL
) {
3839 nb
= lttv_traceset_number(tab
->traceset_info
->traceset
);
3840 for(i
= 0 ; i
< nb
; i
++) {
3841 trace
= lttv_traceset_get(tab
->traceset_info
->traceset
, i
);
3842 ref_count
= lttv_trace_get_ref_number(trace
);
3844 ltt_trace_close(lttv_trace(trace
));
3848 lttv_traceset_destroy(tab
->traceset_info
->traceset
);
3849 /* Remove the idle events requests processing function of the tab */
3850 g_idle_remove_by_data(tab
);
3852 g_slist_free(tab
->events_requests
);
3853 g_free(tab
->traceset_info
);
3855 g_object_unref(ptab
);
3859 /* Create a tab and insert it into the current main window
3862 void init_tab(Tab
*tab
, MainWindow
* mw
, Tab
*copy_tab
,
3863 GtkNotebook
* notebook
, char * label
)
3867 //LttvFilter *filter = NULL;
3869 //create a new tab data structure
3870 //tab = g_new(Tab,1);
3872 //construct and initialize the traceset_info
3873 tab
->traceset_info
= g_new(TracesetInfo
,1);
3876 tab
->traceset_info
->traceset
=
3877 lttv_traceset_copy(copy_tab
->traceset_info
->traceset
);
3879 /* Copy the previous tab's filter */
3880 /* We can clone the filter, as we copy the trace set also */
3881 /* The filter must always be in sync with the trace set */
3882 tab
->filter
= lttv_filter_clone(copy_tab
->filter
);
3884 tab
->traceset_info
->traceset
= lttv_traceset_new();
3888 lttv_attribute_write_xml(
3889 lttv_traceset_attribute(tab
->traceset_info
->traceset
),
3895 tab
->time_manager_lock
= FALSE
;
3896 tab
->current_time_manager_lock
= FALSE
;
3898 //FIXME copy not implemented in lower level
3899 tab
->traceset_info
->traceset_context
=
3900 g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
3901 g_assert(tab
->traceset_info
->traceset_context
!= NULL
);
3903 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
),
3904 tab
->traceset_info
->traceset
);
3905 //add state update hooks
3906 lttv_state_add_event_hooks(
3907 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
3909 //determine the current_time and time_window of the tab
3911 if(copy_tab
!= NULL
){
3912 tab
->time_window
= copy_tab
->time_window
;
3913 tab
->current_time
= copy_tab
->current_time
;
3915 tab
->time_window
.start_time
=
3916 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
3917 time_span
.start_time
;
3918 if(DEFAULT_TIME_WIDTH_S
<
3919 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
3920 time_span
.end_time
.tv_sec
)
3921 tmp_time
.tv_sec
= DEFAULT_TIME_WIDTH_S
;
3924 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
3925 time_span
.end_time
.tv_sec
;
3926 tmp_time
.tv_nsec
= 0;
3927 tab
->time_window
.time_width
= tmp_time
;
3928 tab
->current_time
.tv_sec
=
3929 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
3930 time_span
.start_time
.tv_sec
;
3931 tab
->current_time
.tv_nsec
=
3932 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
3933 time_span
.start_time
.tv_nsec
;
3936 tab
->attributes
= LTTV_IATTRIBUTE(g_object_new(LTTV_ATTRIBUTE_TYPE
, NULL
));
3937 tab
->interrupted_state
= g_object_new(LTTV_ATTRIBUTE_TYPE
, NULL
);
3939 tab
->vbox
= gtk_vbox_new(FALSE
, 2);
3940 tab
->top_widget
= tab
->vbox
;
3941 //g_object_set_data_full(G_OBJECT(tab->top_widget), "filter",
3942 // filter, (GDestroyNotify)lttv_filter_destroy);
3944 // g_signal_connect (G_OBJECT(tab->top_widget),
3946 // G_CALLBACK (on_top_notify),
3949 tab
->viewer_container
= gtk_vbox_new(TRUE
, 2);
3950 tab
->scrollbar
= gtk_hscrollbar_new(NULL
);
3951 //tab->multivpaned = gtk_multi_vpaned_new();
3953 gtk_box_pack_start(GTK_BOX(tab
->vbox
),
3954 tab
->viewer_container
,
3956 TRUE
, /* Give the extra space to the child */
3957 0); /* No padding */
3960 // tab->time_window = copy_tab->time_window;
3961 // tab->current_time = copy_tab->current_time;
3964 /* Create the timebar */
3966 tab
->MTimebar
= timebar_new();
3968 gtk_box_pack_end(GTK_BOX(tab
->vbox
),
3970 FALSE
, /* Do not expand */
3971 FALSE
, /* Fill has no effect here (expand false) */
3972 0); /* No padding */
3974 gtk_box_pack_end(GTK_BOX(tab
->vbox
),
3976 FALSE
, /* Do not expand */
3977 FALSE
, /* Fill has no effect here (expand false) */
3978 0); /* No padding */
3980 g_object_set_data(G_OBJECT(tab
->viewer_container
), "focused_viewer", NULL
);
3986 // Display a label with a X
3987 GtkWidget *w_hbox = gtk_hbox_new(FALSE, 4);
3988 GtkWidget *w_label = gtk_label_new (label);
3989 GtkWidget *pixmap = create_pixmap(GTK_WIDGET(notebook), "close.png");
3990 GtkWidget *w_button = gtk_button_new ();
3991 gtk_container_add(GTK_CONTAINER(w_button), pixmap);
3992 //GtkWidget *w_button = gtk_button_new_with_label("x");
3994 gtk_button_set_relief(GTK_BUTTON(w_button), GTK_RELIEF_NONE);
3996 gtk_box_pack_start(GTK_BOX(w_hbox), w_label, TRUE, TRUE, 0);
3997 gtk_box_pack_end(GTK_BOX(w_hbox), w_button, FALSE,
4000 g_signal_connect_swapped (w_button, "clicked",
4001 G_CALLBACK (on_close_tab_X_clicked),
4004 gtk_widget_set_state(w_button, GTK_STATE_ACTIVE);
4006 gtk_widget_show (w_label);
4007 gtk_widget_show (pixmap);
4008 gtk_widget_show (w_button);
4009 gtk_widget_show (w_hbox);
4011 tab->label = w_hbox;
4015 tab
->label
= gtk_label_new (label
);
4017 gtk_widget_show(tab
->label
);
4018 gtk_widget_show(tab
->scrollbar
);
4019 gtk_widget_show(tab
->MTimebar
);
4020 gtk_widget_show(tab
->viewer_container
);
4021 gtk_widget_show(tab
->vbox
);
4023 //gtk_widget_show(tab->multivpaned);
4026 /* Start with empty events requests list */
4027 tab
->events_requests
= NULL
;
4028 tab
->events_request_pending
= FALSE
;
4029 tab
->stop_foreground
= FALSE
;
4033 g_signal_connect(G_OBJECT(tab
->scrollbar
), "value-changed",
4034 G_CALLBACK(scroll_value_changed_cb
), tab
);
4037 /* Timebar signal handler */
4038 g_signal_connect(G_OBJECT(tab
->MTimebar
), "start-time-changed",
4039 G_CALLBACK(on_timebar_starttime_changed
), tab
);
4040 g_signal_connect(G_OBJECT(tab
->MTimebar
), "end-time-changed",
4041 G_CALLBACK(on_timebar_endtime_changed
), tab
);
4042 g_signal_connect(G_OBJECT(tab
->MTimebar
), "current-time-changed",
4043 G_CALLBACK(on_timebar_currenttime_changed
), tab
);
4045 //g_signal_connect(G_OBJECT(tab->scrollbar), "changed",
4046 // G_CALLBACK(scroll_value_changed_cb), tab);
4049 //insert tab into notebook
4050 gtk_notebook_append_page(notebook
,
4053 list
= gtk_container_get_children(GTK_CONTAINER(notebook
));
4054 gtk_notebook_set_current_page(notebook
,g_list_length(list
)-1);
4055 // always show : not if(g_list_length(list)>1)
4056 gtk_notebook_set_show_tabs(notebook
, TRUE
);
4059 lttvwindow_report_time_window(tab
, copy_tab
->time_window
);
4060 lttvwindow_report_current_time(tab
, copy_tab
->current_time
);
4062 TimeWindow time_window
;
4064 time_window
.start_time
= ltt_time_zero
;
4065 time_window
.end_time
= ltt_time_add(time_window
.start_time
,
4066 lttvwindow_default_time_width
);
4067 time_window
.time_width
= lttvwindow_default_time_width
;
4068 time_window
.time_width_double
= ltt_time_to_double(time_window
.time_width
);
4070 lttvwindow_report_time_window(tab
, time_window
);
4071 lttvwindow_report_current_time(tab
, ltt_time_zero
);
4074 LttvTraceset
*traceset
= tab
->traceset_info
->traceset
;
4075 SetTraceset(tab
, traceset
);
4079 * execute_events_requests
4081 * Idle function that executes the pending requests for a tab.
4083 * @return return value : TRUE : keep the idle function, FALSE : remove it.
4085 gboolean
execute_events_requests(Tab
*tab
)
4087 return ( lttvwindow_process_pending_requests(tab
) );
4091 __EXPORT
void create_main_window_with_trace_list(GSList
*traces
)
4093 GSList
*iter
= NULL
;
4096 MainWindow
*mw
= construct_main_window(NULL
);
4097 GtkWidget
*widget
= mw
->mwindow
;
4099 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
4100 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
4101 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
4102 LttvPluginTab
*ptab
;
4106 ptab
= create_new_tab(widget
, NULL
);
4109 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
4113 for(iter
=traces
; iter
!=NULL
; iter
=g_slist_next(iter
)) {
4114 gchar
*path
= (gchar
*)iter
->data
;
4116 gchar abs_path
[PATH_MAX
];
4120 get_absolute_pathname(path
, abs_path
);
4121 trace_v
= lttvwindowtraces_get_trace_by_name(abs_path
);
4122 if(trace_v
== NULL
) {
4123 trace
= ltt_trace_open(abs_path
);
4125 g_warning("cannot open trace %s", abs_path
);
4127 GtkWidget
*dialogue
=
4128 gtk_message_dialog_new(
4129 GTK_WINDOW(gtk_widget_get_toplevel(widget
)),
4130 GTK_DIALOG_MODAL
|GTK_DIALOG_DESTROY_WITH_PARENT
,
4133 "Cannot open trace : maybe you should enter in the directory "
4135 gtk_dialog_run(GTK_DIALOG(dialogue
));
4136 gtk_widget_destroy(dialogue
);
4138 trace_v
= lttv_trace_new(trace
);
4139 lttvwindowtraces_add_trace(trace_v
);
4140 lttvwindow_add_trace(tab
, trace_v
);
4143 lttvwindow_add_trace(tab
, trace_v
);
4147 LttvTraceset
*traceset
;
4149 traceset
= tab
->traceset_info
->traceset
;
4150 SetTraceset(tab
, traceset
);