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/toolbar.h>
47 #include <lttvwindow/lttvwindow.h>
48 #include <lttvwindow/lttvwindowtraces.h>
49 #include <lttvwindow/lttv_plugin_tab.h>
51 static LttTime lttvwindow_default_time_width
= { 1, 0 };
52 #define CLIP_BUF 256 // size of clipboard buffer
54 extern LttvTrace
*g_init_trace
;
57 /** Array containing instanced objects. */
58 extern GSList
* g_main_window_list
;
60 /** MD : keep old directory. */
61 static char remember_plugins_dir
[PATH_MAX
] = "";
62 static char remember_trace_dir
[PATH_MAX
] = "";
64 void tab_destructor(LttvPluginTab
* ptab
);
66 MainWindow
* get_window_data_struct(GtkWidget
* widget
);
67 char * get_load_module(MainWindow
*mw
,
68 char ** load_module_name
, int nb_module
);
69 char * get_unload_module(MainWindow
*mw
,
70 char ** loaded_module_name
, int nb_module
);
71 char * get_remove_trace(MainWindow
*mw
, char ** all_trace_name
, int nb_trace
);
72 char * get_selection(MainWindow
*mw
,
73 char ** all_name
, int nb
, char *title
, char * column_title
);
74 void init_tab(Tab
*tab
, MainWindow
* mw
, Tab
*copy_tab
,
75 GtkNotebook
* notebook
, char * label
);
77 static void insert_viewer(GtkWidget
* widget
, lttvwindow_viewer_constructor constructor
);
79 LttvPluginTab
*create_new_tab(GtkWidget
* widget
, gpointer user_data
);
81 static gboolean
lttvwindow_process_pending_requests(Tab
*tab
);
95 /* Pasting routines */
97 static void MEventBox1a_receive(GtkClipboard
*clipboard
,
101 if(text
== NULL
) return;
102 Tab
*tab
= (Tab
*)data
;
103 gchar buffer
[CLIP_BUF
];
104 gchar
*ptr
= buffer
, *ptr_ssec
, *ptr_snsec
, *ptr_esec
, *ptr_ensec
;
106 strncpy(buffer
, text
, CLIP_BUF
);
109 while(!isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
110 /* remove leading junk */
112 while(isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
113 /* read all the first number */
117 while(!isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
118 /* remove leading junk */
120 while(isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
121 /* read all the first number */
125 while(!isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
126 /* remove leading junk */
128 while(isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
129 /* read all the first number */
133 while(!isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
134 /* remove leading junk */
136 while(isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
137 /* read all the first number */
140 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry1
),
141 (double)strtoul(ptr_ssec
, NULL
, 10));
142 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry2
),
143 (double)strtoul(ptr_snsec
, NULL
, 10));
144 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry3
),
145 (double)strtoul(ptr_esec
, NULL
, 10));
146 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry4
),
147 (double)strtoul(ptr_ensec
, NULL
, 10));
150 static gboolean
on_MEventBox1a_paste(GtkWidget
*widget
, GdkEventButton
*event
,
153 Tab
*tab
= (Tab
*)data
;
155 GtkClipboard
*clip
= gtk_clipboard_get_for_display(gdk_display_get_default(),
156 GDK_SELECTION_PRIMARY
);
157 gtk_clipboard_request_text(clip
,
158 (GtkClipboardTextReceivedFunc
)MEventBox1a_receive
,
165 static void MEventBox1b_receive(GtkClipboard
*clipboard
,
169 if(text
== NULL
) return;
170 Tab
*tab
= (Tab
*)data
;
171 gchar buffer
[CLIP_BUF
];
172 gchar
*ptr
= buffer
, *ptr_sec
, *ptr_nsec
;
174 strncpy(buffer
, text
, CLIP_BUF
);
176 while(!isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
177 /* remove leading junk */
179 while(isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
180 /* read all the first number */
184 while(!isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
185 /* remove leading junk */
187 while(isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
188 /* read all the first number */
191 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry1
),
192 (double)strtoul(ptr_sec
, NULL
, 10));
193 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry2
),
194 (double)strtoul(ptr_nsec
, NULL
, 10));
198 static gboolean
on_MEventBox1b_paste(GtkWidget
*widget
, GdkEventButton
*event
,
201 Tab
*tab
= (Tab
*)data
;
203 GtkClipboard
*clip
= gtk_clipboard_get_for_display(gdk_display_get_default(),
204 GDK_SELECTION_PRIMARY
);
205 gtk_clipboard_request_text(clip
,
206 (GtkClipboardTextReceivedFunc
)MEventBox1b_receive
,
212 static void MEventBox3b_receive(GtkClipboard
*clipboard
,
216 if(text
== NULL
) return;
217 Tab
*tab
= (Tab
*)data
;
218 gchar buffer
[CLIP_BUF
];
219 gchar
*ptr
= buffer
, *ptr_sec
, *ptr_nsec
;
221 strncpy(buffer
, text
, CLIP_BUF
);
223 while(!isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
224 /* remove leading junk */
226 while(isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
227 /* read all the first number */
231 while(!isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
232 /* remove leading junk */
234 while(isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
235 /* read all the first number */
238 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry3
),
239 (double)strtoul(ptr_sec
, NULL
, 10));
240 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry4
),
241 (double)strtoul(ptr_nsec
, NULL
, 10));
245 static gboolean
on_MEventBox3b_paste(GtkWidget
*widget
, GdkEventButton
*event
,
248 Tab
*tab
= (Tab
*)data
;
250 GtkClipboard
*clip
= gtk_clipboard_get_for_display(gdk_display_get_default(),
251 GDK_SELECTION_PRIMARY
);
252 gtk_clipboard_request_text(clip
,
253 (GtkClipboardTextReceivedFunc
)MEventBox3b_receive
,
259 static void MEventBox5b_receive(GtkClipboard
*clipboard
,
263 if(text
== NULL
) return;
264 Tab
*tab
= (Tab
*)data
;
265 gchar buffer
[CLIP_BUF
];
266 gchar
*ptr
= buffer
, *ptr_sec
, *ptr_nsec
;
268 strncpy(buffer
, text
, CLIP_BUF
);
270 while(!isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
271 /* remove leading junk */
273 while(isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
274 /* read all the first number */
278 while(!isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
279 /* remove leading junk */
281 while(isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
282 /* read all the first number */
285 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry5
),
286 (double)strtoul(ptr_sec
, NULL
, 10));
287 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry6
),
288 (double)strtoul(ptr_nsec
, NULL
, 10));
292 static gboolean
on_MEventBox5b_paste(GtkWidget
*widget
, GdkEventButton
*event
,
295 Tab
*tab
= (Tab
*)data
;
297 GtkClipboard
*clip
= gtk_clipboard_get_for_display(gdk_display_get_default(),
298 GDK_SELECTION_PRIMARY
);
299 gtk_clipboard_request_text(clip
,
300 (GtkClipboardTextReceivedFunc
)MEventBox5b_receive
,
306 static void MEventBox8_receive(GtkClipboard
*clipboard
,
310 if(text
== NULL
) return;
311 Tab
*tab
= (Tab
*)data
;
312 gchar buffer
[CLIP_BUF
];
313 gchar
*ptr
= buffer
, *ptr_sec
, *ptr_nsec
;
315 strncpy(buffer
, text
, CLIP_BUF
);
317 while(!isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
318 /* remove leading junk */
320 while(isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
321 /* read all the first number */
325 while(!isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
326 /* remove leading junk */
328 while(isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
329 /* read all the first number */
332 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry7
),
333 (double)strtoul(ptr_sec
, NULL
, 10));
334 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry8
),
335 (double)strtoul(ptr_nsec
, NULL
, 10));
339 static gboolean
on_MEventBox8_paste(GtkWidget
*widget
, GdkEventButton
*event
,
342 Tab
*tab
= (Tab
*)data
;
344 GtkClipboard
*clip
= gtk_clipboard_get_for_display(gdk_display_get_default(),
345 GDK_SELECTION_PRIMARY
);
346 gtk_clipboard_request_text(clip
,
347 (GtkClipboardTextReceivedFunc
)MEventBox8_receive
,
353 static void on_top_notify(GObject
*gobject
,
357 Tab
*tab
= (Tab
*)user_data
;
358 g_message("in on_top_notify.\n");
362 static gboolean
viewer_grab_focus(GtkWidget
*widget
, GdkEventButton
*event
,
365 GtkWidget
*viewer
= GTK_WIDGET(data
);
366 GtkWidget
*viewer_container
= gtk_widget_get_parent(viewer
);
368 g_debug("FOCUS GRABBED");
369 g_object_set_data(G_OBJECT(viewer_container
), "focused_viewer", viewer
);
374 static void connect_focus_recursive(GtkWidget
*widget
,
377 if(GTK_IS_CONTAINER(widget
)) {
378 gtk_container_forall(GTK_CONTAINER(widget
),
379 (GtkCallback
)connect_focus_recursive
,
383 if(GTK_IS_TREE_VIEW(widget
)) {
384 gtk_tree_view_set_headers_clickable(GTK_TREE_VIEW(widget
), TRUE
);
386 gtk_widget_add_events(widget
, GDK_BUTTON_PRESS_MASK
);
387 g_signal_connect (G_OBJECT(widget
),
388 "button-press-event",
389 G_CALLBACK (viewer_grab_focus
),
393 /* Stop all the processings and call gtk_main_quit() */
394 static void mainwindow_quit()
396 lttvwindowtraces_unregister_requests(g_quark_from_string("stats"));
397 lttvwindowtraces_unregister_requests(g_quark_from_string("state"));
398 lttvwindowtraces_unregister_computation_hooks(g_quark_from_string("stats"));
399 lttvwindowtraces_unregister_computation_hooks(g_quark_from_string("state"));
405 /* insert_viewer function constructs an instance of a viewer first,
406 * then inserts the widget of the instance into the container of the
411 insert_viewer_wrap(GtkWidget
*menuitem
, gpointer user_data
)
413 insert_viewer((GtkWidget
*)menuitem
, (lttvwindow_viewer_constructor
)user_data
);
417 /* internal functions */
418 void insert_viewer(GtkWidget
* widget
, lttvwindow_viewer_constructor constructor
)
420 GtkWidget
* viewer_container
;
421 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
423 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
424 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
429 ptab
= create_new_tab(widget
, NULL
);
431 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
435 viewer_container
= tab
->viewer_container
;
437 viewer
= (GtkWidget
*)constructor(ptab
);
440 //gtk_multivpaned_widget_add(GTK_MULTIVPANED(multivpaned), viewer);
442 gtk_box_pack_end(GTK_BOX(viewer_container
),
448 /* We want to connect the viewer_grab_focus to EVERY
449 * child of this widget. The little trick is to get each child
450 * of each GTK_CONTAINER, even subchildren.
452 connect_focus_recursive(viewer
, viewer
);
457 * Function to set/update traceset for the viewers
458 * @param tab viewer's tab
459 * @param traceset traceset of the main window.
461 * 0 : traceset updated
462 * 1 : no traceset hooks to update; not an error.
465 int SetTraceset(Tab
* tab
, LttvTraceset
*traceset
)
468 TimeInterval time_span
;
469 TimeWindow new_time_window
;
470 LttTime new_current_time
;
471 LttvTracesetContext
*tsc
=
472 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
474 // Perform time synchronization on the traces
475 if (syncTraceset(tsc
))
477 /* There is some time-dependant information that was calculated during
478 * context initialization. Destroy the old contexts and initialize new
480 * Modified from lttvwindow_add_trace()
482 // Keep a reference to the traces so they are not freed
483 for(i
= 0; i
< lttv_traceset_number(traceset
); i
++)
485 LttvTrace
*trace
= lttv_traceset_get(traceset
, i
);
486 lttv_trace_ref(trace
);
489 // Remove state update hooks
490 lttv_state_remove_event_hooks(
491 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
493 lttv_context_fini(LTTV_TRACESET_CONTEXT(
494 tab
->traceset_info
->traceset_context
));
495 g_object_unref(tab
->traceset_info
->traceset_context
);
497 for(i
= 0; i
< lttv_traceset_number(traceset
); i
++)
499 LttvTrace
*trace
= lttv_traceset_get(traceset
, i
);
500 lttvwindowtraces_remove_trace(trace
);
501 lttvwindowtraces_add_trace(trace
);
504 // Create new context
505 tab
->traceset_info
->traceset_context
=
506 g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
507 lttv_context_init(LTTV_TRACESET_CONTEXT(tab
->traceset_info
->
508 traceset_context
), traceset
);
510 // Add state update hooks
511 lttv_state_add_event_hooks(
512 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
514 // Remove local reference to the traces
515 for(i
=0; i
<lttv_traceset_number(traceset
); i
++)
517 LttvTrace
*trace
= lttv_traceset_get(traceset
, i
);
518 lttv_trace_unref(trace
);
521 tsc
= LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
524 time_span
= tsc
->time_span
;
525 new_time_window
= tab
->time_window
;
526 new_current_time
= tab
->current_time
;
528 /* Set the tab's time window and current time if
530 if(ltt_time_compare(tab
->time_window
.start_time
, time_span
.start_time
) < 0
531 || ltt_time_compare(tab
->time_window
.end_time
,
532 time_span
.end_time
) > 0) {
533 new_time_window
.start_time
= time_span
.start_time
;
535 new_current_time
= time_span
.start_time
;
539 if(ltt_time_compare(lttvwindow_default_time_width
,
540 ltt_time_sub(time_span
.end_time
, time_span
.start_time
)) < 0
542 ltt_time_compare(time_span
.end_time
, time_span
.start_time
) == 0)
543 tmp_time
= lttvwindow_default_time_width
;
545 tmp_time
= time_span
.end_time
;
547 new_time_window
.time_width
= tmp_time
;
548 new_time_window
.time_width_double
= ltt_time_to_double(tmp_time
);
549 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
550 new_time_window
.time_width
) ;
557 GtkAdjustment
*adjustment
= gtk_range_get_adjustment(GTK_RANGE(tab
->scrollbar
));
558 LttTime upper
= ltt_time_sub(time_span
.end_time
, time_span
.start_time
);
560 g_object_set(G_OBJECT(adjustment
),
564 ltt_time_to_double(upper
)
565 * NANOSECONDS_PER_SECOND
, /* upper */
567 ltt_time_to_double(tab
->time_window
.time_width
)
568 / SCROLL_STEP_PER_PAGE
569 * NANOSECONDS_PER_SECOND
, /* step increment */
571 ltt_time_to_double(tab
->time_window
.time_width
)
572 * NANOSECONDS_PER_SECOND
, /* page increment */
574 ltt_time_to_double(tab
->time_window
.time_width
)
575 * NANOSECONDS_PER_SECOND
, /* page size */
577 gtk_adjustment_changed(adjustment
);
579 g_object_set(G_OBJECT(adjustment
),
582 ltt_time_sub(tab
->time_window
.start_time
, time_span
.start_time
))
583 * NANOSECONDS_PER_SECOND
, /* value */
585 gtk_adjustment_value_changed(adjustment
);
587 /* set the time bar. The value callbacks will change their nsec themself */
589 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry1
),
590 (double)time_span
.start_time
.tv_sec
,
591 (double)time_span
.end_time
.tv_sec
);
594 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry3
),
595 (double)time_span
.start_time
.tv_sec
,
596 (double)time_span
.end_time
.tv_sec
);
598 /* current seconds */
599 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry5
),
600 (double)time_span
.start_time
.tv_sec
,
601 (double)time_span
.end_time
.tv_sec
);
604 /* Finally, call the update hooks of the viewers */
606 LttvAttributeValue value
;
609 retval
= lttv_iattribute_find_by_path(tab
->attributes
,
610 "hooks/updatetraceset", LTTV_POINTER
, &value
);
613 tmp
= (LttvHooks
*)*(value
.v_pointer
);
617 lttv_hooks_call(tmp
,traceset
);
619 time_change_manager(tab
, new_time_window
);
620 current_time_change_manager(tab
, new_current_time
);
626 * Function to set/update filter for the viewers
627 * @param tab viewer's tab
628 * @param filter filter of the main window.
631 * 0 : filters updated
632 * 1 : no filter hooks to update; not an error.
635 int SetFilter(Tab
* tab
, gpointer filter
)
638 LttvAttributeValue value
;
640 g_assert(lttv_iattribute_find_by_path(tab
->attributes
,
641 "hooks/updatefilter", LTTV_POINTER
, &value
));
643 tmp
= (LttvHooks
*)*(value
.v_pointer
);
645 if(tmp
== NULL
) return 1;
646 lttv_hooks_call(tmp
,filter
);
654 * Function to redraw each viewer belonging to the current tab
655 * @param tab viewer's tab
658 void update_traceset(Tab
*tab
)
660 LttvAttributeValue value
;
664 retval
= lttv_iattribute_find_by_path(tab
->attributes
,
665 "hooks/updatetraceset", LTTV_POINTER
, &value
);
667 tmp
= (LttvHooks
*)*(value
.v_pointer
);
668 if(tmp
== NULL
) return;
669 lttv_hooks_call(tmp
, NULL
);
673 /* get_label function is used to get user input, it displays an input
674 * box, which allows user to input a string
677 void get_label_string (GtkWidget
* text
, gchar
* label
)
679 GtkEntry
* entry
= (GtkEntry
*)text
;
680 if(strlen(gtk_entry_get_text(entry
))!=0)
681 strcpy(label
,gtk_entry_get_text(entry
));
684 gboolean
get_label(MainWindow
* mw
, gchar
* str
, gchar
* dialogue_title
, gchar
* label_str
)
686 GtkWidget
* dialogue
;
691 dialogue
= gtk_dialog_new_with_buttons(dialogue_title
,NULL
,
693 GTK_STOCK_OK
,GTK_RESPONSE_ACCEPT
,
694 GTK_STOCK_CANCEL
,GTK_RESPONSE_REJECT
,
697 label
= gtk_label_new(label_str
);
698 gtk_widget_show(label
);
700 text
= gtk_entry_new();
701 gtk_widget_show(text
);
703 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialogue
)->vbox
), label
,TRUE
, TRUE
,0);
704 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialogue
)->vbox
), text
,FALSE
, FALSE
,0);
706 id
= gtk_dialog_run(GTK_DIALOG(dialogue
));
708 case GTK_RESPONSE_ACCEPT
:
709 get_label_string(text
,str
);
710 gtk_widget_destroy(dialogue
);
712 case GTK_RESPONSE_REJECT
:
714 gtk_widget_destroy(dialogue
);
721 /* get_window_data_struct function is actually a lookup function,
722 * given a widget which is in the tree of the main window, it will
723 * return the MainWindow data structure associated with main window
726 MainWindow
* get_window_data_struct(GtkWidget
* widget
)
729 MainWindow
* mw_data
;
731 mw
= lookup_widget(widget
, "MWindow");
733 g_info("Main window does not exist\n");
737 mw_data
= (MainWindow
*) g_object_get_data(G_OBJECT(mw
),"main_window_data");
739 g_warning("Main window data does not exist\n");
746 /* create_new_window function, just constructs a new main window
749 void create_new_window(GtkWidget
* widget
, gpointer user_data
, gboolean clone
)
751 MainWindow
* parent
= get_window_data_struct(widget
);
754 g_info("Clone : use the same traceset\n");
755 construct_main_window(parent
);
757 g_info("Empty : traceset is set to NULL\n");
758 construct_main_window(NULL
);
762 /* Get the currently focused viewer.
763 * If no viewer is focused, use the first one.
765 * If no viewer available, return NULL.
767 GtkWidget
*viewer_container_focus(GtkWidget
*container
)
771 widget
= (GtkWidget
*)g_object_get_data(G_OBJECT(container
),
775 g_debug("no widget focused");
776 GList
*children
= gtk_container_get_children(GTK_CONTAINER(container
));
779 widget
= GTK_WIDGET(children
->data
);
780 g_object_set_data(G_OBJECT(container
),
790 gint
viewer_container_position(GtkWidget
*container
, GtkWidget
*child
)
793 if(child
== NULL
) return -1;
797 memset(&value
, 0, sizeof(GValue
));
798 g_value_init(&value
, G_TYPE_INT
);
799 gtk_container_child_get_property(GTK_CONTAINER(container
),
803 pos
= g_value_get_int(&value
);
809 /* move_*_viewer functions move the selected view up/down in
813 void move_down_viewer(GtkWidget
* widget
, gpointer user_data
)
815 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
817 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
818 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
825 ptab
= g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
829 //gtk_multivpaned_widget_move_up(GTK_MULTIVPANED(tab->multivpaned));
831 /* change the position in the vbox */
832 GtkWidget
*focus_widget
;
834 focus_widget
= viewer_container_focus(tab
->viewer_container
);
835 position
= viewer_container_position(tab
->viewer_container
, focus_widget
);
838 /* can move up one position */
839 gtk_box_reorder_child(GTK_BOX(tab
->viewer_container
),
846 void move_up_viewer(GtkWidget
* widget
, gpointer user_data
)
848 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
850 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
851 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
858 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
862 //gtk_multivpaned_widget_move_down(GTK_MULTIVPANED(tab->multivpaned));
863 /* change the position in the vbox */
864 GtkWidget
*focus_widget
;
866 focus_widget
= viewer_container_focus(tab
->viewer_container
);
867 position
= viewer_container_position(tab
->viewer_container
, focus_widget
);
871 g_list_length(gtk_container_get_children(
872 GTK_CONTAINER(tab
->viewer_container
)))-1
874 /* can move down one position */
875 gtk_box_reorder_child(GTK_BOX(tab
->viewer_container
),
883 /* delete_viewer deletes the selected viewer in the current tab
886 void delete_viewer(GtkWidget
* widget
, gpointer user_data
)
888 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
890 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
891 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
898 ptab
= g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
902 //gtk_multivpaned_widget_delete(GTK_MULTIVPANED(tab->multivpaned));
904 GtkWidget
*focus_widget
= viewer_container_focus(tab
->viewer_container
);
906 if(focus_widget
!= NULL
)
907 gtk_widget_destroy(focus_widget
);
909 g_object_set_data(G_OBJECT(tab
->viewer_container
), "focused_viewer", NULL
);
913 /* open_traceset will open a traceset saved in a file
914 * Right now, it is not finished yet, (not working)
918 void open_traceset(GtkWidget
* widget
, gpointer user_data
)
922 LttvTraceset
* traceset
;
923 MainWindow
* mw_data
= get_window_data_struct(widget
);
924 GtkFileSelection
* file_selector
=
925 (GtkFileSelection
*)gtk_file_selection_new("Select a traceset");
927 gtk_file_selection_hide_fileop_buttons(file_selector
);
929 gtk_window_set_transient_for(GTK_WINDOW(file_selector
),
930 GTK_WINDOW(mw_data
->mwindow
));
932 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
934 case GTK_RESPONSE_ACCEPT
:
935 case GTK_RESPONSE_OK
:
936 dir
= gtk_file_selection_get_selections (file_selector
);
937 traceset
= lttv_traceset_load(dir
[0]);
938 g_info("Open a trace set %s\n", dir
[0]);
941 case GTK_RESPONSE_REJECT
:
942 case GTK_RESPONSE_CANCEL
:
944 gtk_widget_destroy((GtkWidget
*)file_selector
);
950 /* lttvwindow_process_pending_requests
952 * Process requests for parts of the trace from viewers.
954 * These requests are made by lttvwindow_events_request().
956 * This internal function gets called by g_idle, taking care of the pending
957 * requests. It is responsible for concatenation of time intervals and position
958 * requests. It does it with the following algorithm organizing process traceset
959 * calls. Here is the detailed description of the way it works :
961 * - Events Requests Servicing Algorithm
963 * Data structures necessary :
965 * List of requests added to context : list_in
966 * List of requests not added to context : list_out
971 * list_out : many events requests
973 * FIXME : insert rest of algorithm here
977 #define list_out tab->events_requests
979 gboolean
lttvwindow_process_pending_requests(Tab
*tab
)
981 LttvTracesetContext
*tsc
;
982 LttvTracefileContext
*tfc
;
983 GSList
*list_in
= NULL
;
987 LttvTracesetContextPosition
*end_position
;
989 if(lttvwindow_preempt_count
> 0) return TRUE
;
992 g_critical("Foreground processing : tab does not exist. Processing removed.");
996 /* There is no events requests pending : we should never have been called! */
997 g_assert(g_slist_length(list_out
) != 0);
999 tsc
= LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
1001 //set the cursor to be X shape, indicating that the computer is busy in doing its job
1003 new = gdk_cursor_new(GDK_X_CURSOR
);
1004 widget
= lookup_widget(tab
->mw
->mwindow
, "MToolbar1");
1005 win
= gtk_widget_get_parent_window(widget
);
1006 gdk_window_set_cursor(win
, new);
1007 gdk_cursor_unref(new);
1008 gdk_window_stick(win
);
1009 gdk_window_unstick(win
);
1012 g_debug("SIZE events req len : %d", g_slist_length(list_out
));
1014 /* Preliminary check for no trace in traceset */
1015 /* Unregister the routine if empty, empty list_out too */
1016 if(lttv_traceset_number(tsc
->ts
) == 0) {
1018 /* - For each req in list_out */
1019 GSList
*iter
= list_out
;
1021 while(iter
!= NULL
) {
1023 gboolean remove
= FALSE
;
1024 gboolean free_data
= FALSE
;
1025 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1027 /* - Call end request for req */
1028 if(events_request
->servicing
== TRUE
)
1029 lttv_hooks_call(events_request
->after_request
, (gpointer
)tsc
);
1031 /* - remove req from list_out */
1032 /* Destroy the request */
1039 GSList
*remove_iter
= iter
;
1041 iter
= g_slist_next(iter
);
1042 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
1043 list_out
= g_slist_remove_link(list_out
, remove_iter
);
1044 } else { // not remove
1045 iter
= g_slist_next(iter
);
1050 /* 0.1 Lock Traces */
1055 iter_trace
<lttv_traceset_number(tsc
->ts
);
1057 LttvTrace
*trace_v
= lttv_traceset_get(tsc
->ts
, iter_trace
);
1059 if(lttvwindowtraces_lock(trace_v
) != 0) {
1060 g_critical("Foreground processing : Unable to get trace lock");
1061 return TRUE
; /* Cannot get lock, try later */
1066 /* 0.2 Seek tracefiles positions to context position */
1067 //g_assert(lttv_process_traceset_seek_position(tsc, sync_position) == 0);
1068 lttv_process_traceset_synchronize_tracefiles(tsc
);
1071 /* Events processing algorithm implementation */
1072 /* Warning : the gtk_events_pending takes a LOT of cpu time. So what we do
1073 * instead is to leave the control to GTK and take it back.
1075 /* A. Servicing loop */
1076 //while( (g_slist_length(list_in) != 0 || g_slist_length(list_out) != 0)) {
1077 if((g_slist_length(list_in
) != 0 || g_slist_length(list_out
) != 0)) {
1079 /* 1. If list_in is empty (need a seek) */
1080 if( g_slist_length(list_in
) == 0 ) {
1082 /* list in is empty, need a seek */
1084 /* 1.1 Add requests to list_in */
1085 GSList
*ltime
= NULL
;
1086 GSList
*lpos
= NULL
;
1087 GSList
*iter
= NULL
;
1089 /* 1.1.1 Find all time requests with the lowest start time in list_out
1092 if(g_slist_length(list_out
) > 0)
1093 ltime
= g_slist_append(ltime
, g_slist_nth_data(list_out
, 0));
1094 for(iter
=g_slist_nth(list_out
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
1095 /* Find all time requests with the lowest start time in list_out */
1096 EventsRequest
*event_request_ltime
= (EventsRequest
*)g_slist_nth_data(ltime
, 0);
1097 EventsRequest
*event_request_list_out
= (EventsRequest
*)iter
->data
;
1100 comp
= ltt_time_compare(event_request_ltime
->start_time
,
1101 event_request_list_out
->start_time
);
1103 ltime
= g_slist_append(ltime
, event_request_list_out
);
1105 /* Remove all elements from ltime, and add current */
1106 while(ltime
!= NULL
)
1107 ltime
= g_slist_delete_link(ltime
, g_slist_nth(ltime
, 0));
1108 ltime
= g_slist_append(ltime
, event_request_list_out
);
1112 /* 1.1.2 Find all position requests with the lowest position in list_out
1115 if(g_slist_length(list_out
) > 0)
1116 lpos
= g_slist_append(lpos
, g_slist_nth_data(list_out
, 0));
1117 for(iter
=g_slist_nth(list_out
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
1118 /* Find all position requests with the lowest position in list_out */
1119 EventsRequest
*event_request_lpos
= (EventsRequest
*)g_slist_nth_data(lpos
, 0);
1120 EventsRequest
*event_request_list_out
= (EventsRequest
*)iter
->data
;
1123 if(event_request_lpos
->start_position
!= NULL
1124 && event_request_list_out
->start_position
!= NULL
)
1126 comp
= lttv_traceset_context_pos_pos_compare
1127 (event_request_lpos
->start_position
,
1128 event_request_list_out
->start_position
);
1133 lpos
= g_slist_append(lpos
, event_request_list_out
);
1135 /* Remove all elements from lpos, and add current */
1137 lpos
= g_slist_delete_link(lpos
, g_slist_nth(lpos
, 0));
1138 lpos
= g_slist_append(lpos
, event_request_list_out
);
1143 EventsRequest
*event_request_lpos
= (EventsRequest
*)g_slist_nth_data(lpos
, 0);
1144 EventsRequest
*event_request_ltime
= (EventsRequest
*)g_slist_nth_data(ltime
, 0);
1145 LttTime lpos_start_time
;
1147 if(event_request_lpos
!= NULL
1148 && event_request_lpos
->start_position
!= NULL
) {
1149 lpos_start_time
= lttv_traceset_context_position_get_time(
1150 event_request_lpos
->start_position
);
1153 /* 1.1.3 If lpos.start time < ltime */
1154 if(event_request_lpos
!= NULL
1155 && event_request_lpos
->start_position
!= NULL
1156 && ltt_time_compare(lpos_start_time
,
1157 event_request_ltime
->start_time
)<0) {
1158 /* Add lpos to list_in, remove them from list_out */
1159 for(iter
=lpos
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
1160 /* Add to list_in */
1161 EventsRequest
*event_request_lpos
=
1162 (EventsRequest
*)iter
->data
;
1164 list_in
= g_slist_append(list_in
, event_request_lpos
);
1165 /* Remove from list_out */
1166 list_out
= g_slist_remove(list_out
, event_request_lpos
);
1169 /* 1.1.4 (lpos.start time >= ltime) */
1170 /* Add ltime to list_in, remove them from list_out */
1172 for(iter
=ltime
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
1173 /* Add to list_in */
1174 EventsRequest
*event_request_ltime
=
1175 (EventsRequest
*)iter
->data
;
1177 list_in
= g_slist_append(list_in
, event_request_ltime
);
1178 /* Remove from list_out */
1179 list_out
= g_slist_remove(list_out
, event_request_ltime
);
1184 g_slist_free(ltime
);
1189 tfc
= lttv_traceset_context_get_current_tfc(tsc
);
1190 g_assert(g_slist_length(list_in
)>0);
1191 EventsRequest
*events_request
= g_slist_nth_data(list_in
, 0);
1194 /* 1.2.1 If first request in list_in is a time request */
1195 if(events_request
->start_position
== NULL
) {
1196 /* - If first req in list_in start time != current time */
1197 if(tfc
== NULL
|| ltt_time_compare(events_request
->start_time
,
1198 tfc
->timestamp
) != 0)
1199 /* - Seek to that time */
1200 g_debug("SEEK TIME : %lu, %lu", events_request
->start_time
.tv_sec
,
1201 events_request
->start_time
.tv_nsec
);
1202 //lttv_process_traceset_seek_time(tsc, events_request->start_time);
1203 lttv_state_traceset_seek_time_closest(LTTV_TRACESET_STATE(tsc
),
1204 events_request
->start_time
);
1206 /* Process the traceset with only state hooks */
1208 lttv_process_traceset_middle(tsc
,
1209 events_request
->start_time
,
1212 g_assert(seek_count
< LTTV_STATE_SAVE_INTERVAL
);
1218 LttvTracefileContext
*tfc
=
1219 lttv_traceset_context_get_current_tfc(tsc
);
1220 /* Else, the first request in list_in is a position request */
1221 /* If first req in list_in pos != current pos */
1222 g_assert(events_request
->start_position
!= NULL
);
1223 g_debug("SEEK POS time : %lu, %lu",
1224 lttv_traceset_context_position_get_time(
1225 events_request
->start_position
).tv_sec
,
1226 lttv_traceset_context_position_get_time(
1227 events_request
->start_position
).tv_nsec
);
1230 g_debug("SEEK POS context time : %lu, %lu",
1231 tfc
->timestamp
.tv_sec
,
1232 tfc
->timestamp
.tv_nsec
);
1234 g_debug("SEEK POS context time : %lu, %lu",
1235 ltt_time_infinite
.tv_sec
,
1236 ltt_time_infinite
.tv_nsec
);
1238 g_assert(events_request
->start_position
!= NULL
);
1239 if(lttv_traceset_context_ctx_pos_compare(tsc
,
1240 events_request
->start_position
) != 0) {
1241 /* 1.2.2.1 Seek to that position */
1242 g_debug("SEEK POSITION");
1243 //lttv_process_traceset_seek_position(tsc, events_request->start_position);
1244 pos_time
= lttv_traceset_context_position_get_time(
1245 events_request
->start_position
);
1247 lttv_state_traceset_seek_time_closest(LTTV_TRACESET_STATE(tsc
),
1250 /* Process the traceset with only state hooks */
1252 lttv_process_traceset_middle(tsc
,
1255 events_request
->start_position
);
1256 g_assert(lttv_traceset_context_ctx_pos_compare(tsc
,
1257 events_request
->start_position
) == 0);
1264 /* 1.3 Add hooks and call before request for all list_in members */
1266 GSList
*iter
= NULL
;
1268 for(iter
=list_in
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
1269 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1270 /* 1.3.1 If !servicing */
1271 if(events_request
->servicing
== FALSE
) {
1272 /* - begin request hooks called
1273 * - servicing = TRUE
1275 lttv_hooks_call(events_request
->before_request
, (gpointer
)tsc
);
1276 events_request
->servicing
= TRUE
;
1278 /* 1.3.2 call before chunk
1279 * 1.3.3 events hooks added
1281 if(events_request
->trace
== -1)
1282 lttv_process_traceset_begin(tsc
,
1283 events_request
->before_chunk_traceset
,
1284 events_request
->before_chunk_trace
,
1285 events_request
->before_chunk_tracefile
,
1286 events_request
->event
,
1287 events_request
->event_by_id_channel
);
1289 guint nb_trace
= lttv_traceset_number(tsc
->ts
);
1290 g_assert((guint
)events_request
->trace
< nb_trace
&&
1291 events_request
->trace
> -1);
1292 LttvTraceContext
*tc
= tsc
->traces
[events_request
->trace
];
1294 lttv_hooks_call(events_request
->before_chunk_traceset
, tsc
);
1296 lttv_trace_context_add_hooks(tc
,
1297 events_request
->before_chunk_trace
,
1298 events_request
->before_chunk_tracefile
,
1299 events_request
->event
,
1300 events_request
->event_by_id_channel
);
1305 /* 2. Else, list_in is not empty, we continue a read */
1308 /* 2.0 For each req of list_in */
1309 GSList
*iter
= list_in
;
1311 while(iter
!= NULL
) {
1313 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1315 /* - Call before chunk
1316 * - events hooks added
1318 if(events_request
->trace
== -1)
1319 lttv_process_traceset_begin(tsc
,
1320 events_request
->before_chunk_traceset
,
1321 events_request
->before_chunk_trace
,
1322 events_request
->before_chunk_tracefile
,
1323 events_request
->event
,
1324 events_request
->event_by_id_channel
);
1326 guint nb_trace
= lttv_traceset_number(tsc
->ts
);
1327 g_assert((guint
)events_request
->trace
< nb_trace
&&
1328 events_request
->trace
> -1);
1329 LttvTraceContext
*tc
= tsc
->traces
[events_request
->trace
];
1331 lttv_hooks_call(events_request
->before_chunk_traceset
, tsc
);
1333 lttv_trace_context_add_hooks(tc
,
1334 events_request
->before_chunk_trace
,
1335 events_request
->before_chunk_tracefile
,
1336 events_request
->event
,
1337 events_request
->event_by_id_channel
);
1340 iter
= g_slist_next(iter
);
1345 tfc
= lttv_traceset_context_get_current_tfc(tsc
);
1347 /* 2.1 For each req of list_out */
1348 GSList
*iter
= list_out
;
1350 while(iter
!= NULL
) {
1352 gboolean remove
= FALSE
;
1353 gboolean free_data
= FALSE
;
1354 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1356 /* if req.start time == current context time
1357 * or req.start position == current position*/
1358 if( ltt_time_compare(events_request
->start_time
,
1359 tfc
->timestamp
) == 0
1361 (events_request
->start_position
!= NULL
1363 lttv_traceset_context_ctx_pos_compare(tsc
,
1364 events_request
->start_position
) == 0)
1366 /* - Add to list_in, remove from list_out */
1367 list_in
= g_slist_append(list_in
, events_request
);
1371 /* - If !servicing */
1372 if(events_request
->servicing
== FALSE
) {
1373 /* - begin request hooks called
1374 * - servicing = TRUE
1376 lttv_hooks_call(events_request
->before_request
, (gpointer
)tsc
);
1377 events_request
->servicing
= TRUE
;
1379 /* call before chunk
1380 * events hooks added
1382 if(events_request
->trace
== -1)
1383 lttv_process_traceset_begin(tsc
,
1384 events_request
->before_chunk_traceset
,
1385 events_request
->before_chunk_trace
,
1386 events_request
->before_chunk_tracefile
,
1387 events_request
->event
,
1388 events_request
->event_by_id_channel
);
1390 guint nb_trace
= lttv_traceset_number(tsc
->ts
);
1391 g_assert((guint
)events_request
->trace
< nb_trace
&&
1392 events_request
->trace
> -1);
1393 LttvTraceContext
*tc
= tsc
->traces
[events_request
->trace
];
1395 lttv_hooks_call(events_request
->before_chunk_traceset
, tsc
);
1397 lttv_trace_context_add_hooks(tc
,
1398 events_request
->before_chunk_trace
,
1399 events_request
->before_chunk_tracefile
,
1400 events_request
->event
,
1401 events_request
->event_by_id_channel
);
1410 GSList
*remove_iter
= iter
;
1412 iter
= g_slist_next(iter
);
1413 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
1414 list_out
= g_slist_remove_link(list_out
, remove_iter
);
1415 } else { // not remove
1416 iter
= g_slist_next(iter
);
1422 /* 3. Find end criterions */
1427 /* 3.1.1 Find lowest end time in list_in */
1428 g_assert(g_slist_length(list_in
)>0);
1429 end_time
= ((EventsRequest
*)g_slist_nth_data(list_in
,0))->end_time
;
1431 for(iter
=g_slist_nth(list_in
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
1432 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1434 if(ltt_time_compare(events_request
->end_time
,
1436 end_time
= events_request
->end_time
;
1439 /* 3.1.2 Find lowest start time in list_out */
1440 for(iter
=list_out
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
1441 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1443 if(ltt_time_compare(events_request
->start_time
,
1445 end_time
= events_request
->start_time
;
1450 /* 3.2 Number of events */
1452 /* 3.2.1 Find lowest number of events in list_in */
1455 end_nb_events
= ((EventsRequest
*)g_slist_nth_data(list_in
,0))->num_events
;
1457 for(iter
=g_slist_nth(list_in
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
1458 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1460 if(events_request
->num_events
< end_nb_events
)
1461 end_nb_events
= events_request
->num_events
;
1464 /* 3.2.2 Use min(CHUNK_NUM_EVENTS, min num events in list_in) as
1467 end_nb_events
= MIN(CHUNK_NUM_EVENTS
, end_nb_events
);
1471 /* 3.3 End position */
1473 /* 3.3.1 Find lowest end position in list_in */
1476 end_position
=((EventsRequest
*)g_slist_nth_data(list_in
,0))->end_position
;
1478 for(iter
=g_slist_nth(list_in
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
1479 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1481 if(events_request
->end_position
!= NULL
&& end_position
!= NULL
&&
1482 lttv_traceset_context_pos_pos_compare(events_request
->end_position
,
1484 end_position
= events_request
->end_position
;
1489 /* 3.3.2 Find lowest start position in list_out */
1492 for(iter
=list_out
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
1493 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1495 if(events_request
->end_position
!= NULL
&& end_position
!= NULL
&&
1496 lttv_traceset_context_pos_pos_compare(events_request
->end_position
,
1498 end_position
= events_request
->end_position
;
1503 /* 4. Call process traceset middle */
1504 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
);
1505 count
= lttv_process_traceset_middle(tsc
, end_time
, end_nb_events
, end_position
);
1507 tfc
= lttv_traceset_context_get_current_tfc(tsc
);
1509 g_debug("Context time after middle : %lu, %lu", tfc
->timestamp
.tv_sec
,
1510 tfc
->timestamp
.tv_nsec
);
1512 g_debug("End of trace reached after middle.");
1516 /* 5. After process traceset middle */
1517 tfc
= lttv_traceset_context_get_current_tfc(tsc
);
1519 /* - if current context time > traceset.end time */
1520 if(tfc
== NULL
|| ltt_time_compare(tfc
->timestamp
,
1521 tsc
->time_span
.end_time
) > 0) {
1522 /* - For each req in list_in */
1523 GSList
*iter
= list_in
;
1525 while(iter
!= NULL
) {
1527 gboolean remove
= FALSE
;
1528 gboolean free_data
= FALSE
;
1529 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1531 /* - Remove events hooks for req
1532 * - Call end chunk for req
1535 if(events_request
->trace
== -1)
1536 lttv_process_traceset_end(tsc
,
1537 events_request
->after_chunk_traceset
,
1538 events_request
->after_chunk_trace
,
1539 events_request
->after_chunk_tracefile
,
1540 events_request
->event
,
1541 events_request
->event_by_id_channel
);
1544 guint nb_trace
= lttv_traceset_number(tsc
->ts
);
1545 g_assert(events_request
->trace
< nb_trace
&&
1546 events_request
->trace
> -1);
1547 LttvTraceContext
*tc
= tsc
->traces
[events_request
->trace
];
1549 lttv_trace_context_remove_hooks(tc
,
1550 events_request
->after_chunk_trace
,
1551 events_request
->after_chunk_tracefile
,
1552 events_request
->event
,
1553 events_request
->event_by_id_channel
);
1554 lttv_hooks_call(events_request
->after_chunk_traceset
, tsc
);
1559 /* - Call end request for req */
1560 lttv_hooks_call(events_request
->after_request
, (gpointer
)tsc
);
1562 /* - remove req from list_in */
1563 /* Destroy the request */
1570 GSList
*remove_iter
= iter
;
1572 iter
= g_slist_next(iter
);
1573 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
1574 list_in
= g_slist_remove_link(list_in
, remove_iter
);
1575 } else { // not remove
1576 iter
= g_slist_next(iter
);
1581 /* 5.1 For each req in list_in */
1582 GSList
*iter
= list_in
;
1584 while(iter
!= NULL
) {
1586 gboolean remove
= FALSE
;
1587 gboolean free_data
= FALSE
;
1588 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1590 /* - Remove events hooks for req
1591 * - Call end chunk for req
1593 if(events_request
->trace
== -1)
1594 lttv_process_traceset_end(tsc
,
1595 events_request
->after_chunk_traceset
,
1596 events_request
->after_chunk_trace
,
1597 events_request
->after_chunk_tracefile
,
1598 events_request
->event
,
1599 events_request
->event_by_id_channel
);
1602 guint nb_trace
= lttv_traceset_number(tsc
->ts
);
1603 g_assert(events_request
->trace
< nb_trace
&&
1604 events_request
->trace
> -1);
1605 LttvTraceContext
*tc
= tsc
->traces
[events_request
->trace
];
1607 lttv_trace_context_remove_hooks(tc
,
1608 events_request
->after_chunk_trace
,
1609 events_request
->after_chunk_tracefile
,
1610 events_request
->event
,
1611 events_request
->event_by_id_channel
);
1613 lttv_hooks_call(events_request
->after_chunk_traceset
, tsc
);
1616 /* - req.num -= count */
1617 g_assert(events_request
->num_events
>= count
);
1618 events_request
->num_events
-= count
;
1620 g_assert(tfc
!= NULL
);
1621 /* - if req.num == 0
1623 * current context time >= req.end time
1625 * req.end pos == current pos
1627 * req.stop_flag == TRUE
1629 if( events_request
->num_events
== 0
1631 events_request
->stop_flag
== TRUE
1633 ltt_time_compare(tfc
->timestamp
,
1634 events_request
->end_time
) >= 0
1636 (events_request
->end_position
!= NULL
1638 lttv_traceset_context_ctx_pos_compare(tsc
,
1639 events_request
->end_position
) == 0)
1642 g_assert(events_request
->servicing
== TRUE
);
1643 /* - Call end request for req
1644 * - remove req from list_in */
1645 lttv_hooks_call(events_request
->after_request
, (gpointer
)tsc
);
1646 /* - remove req from list_in */
1647 /* Destroy the request */
1655 GSList
*remove_iter
= iter
;
1657 iter
= g_slist_next(iter
);
1658 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
1659 list_in
= g_slist_remove_link(list_in
, remove_iter
);
1660 } else { // not remove
1661 iter
= g_slist_next(iter
);
1667 /* End of removed servicing loop : leave control to GTK instead. */
1668 // if(gtk_events_pending()) break;
1671 /* B. When interrupted between chunks */
1674 GSList
*iter
= list_in
;
1676 /* 1. for each request in list_in */
1677 while(iter
!= NULL
) {
1679 gboolean remove
= FALSE
;
1680 gboolean free_data
= FALSE
;
1681 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1683 /* 1.1. Use current postition as start position */
1684 if(events_request
->start_position
!= NULL
)
1685 lttv_traceset_context_position_destroy(events_request
->start_position
);
1686 events_request
->start_position
= lttv_traceset_context_position_new(tsc
);
1687 lttv_traceset_context_position_save(tsc
, events_request
->start_position
);
1689 /* 1.2. Remove start time */
1690 events_request
->start_time
= ltt_time_infinite
;
1692 /* 1.3. Move from list_in to list_out */
1695 list_out
= g_slist_append(list_out
, events_request
);
1700 GSList
*remove_iter
= iter
;
1702 iter
= g_slist_next(iter
);
1703 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
1704 list_in
= g_slist_remove_link(list_in
, remove_iter
);
1705 } else { // not remove
1706 iter
= g_slist_next(iter
);
1712 /* C Unlock Traces */
1714 lttv_process_traceset_get_sync_data(tsc
);
1715 //lttv_traceset_context_position_save(tsc, sync_position);
1720 iter_trace
<lttv_traceset_number(tsc
->ts
);
1722 LttvTrace
*trace_v
= lttv_traceset_get(tsc
->ts
, iter_trace
);
1724 lttvwindowtraces_unlock(trace_v
);
1728 //set the cursor back to normal
1729 gdk_window_set_cursor(win
, NULL
);
1732 g_assert(g_slist_length(list_in
) == 0);
1734 if( g_slist_length(list_out
) == 0 ) {
1735 /* Put tab's request pending flag back to normal */
1736 tab
->events_request_pending
= FALSE
;
1737 g_debug("remove the idle fct");
1738 return FALSE
; /* Remove the idle function */
1740 g_debug("leave the idle fct");
1741 return TRUE
; /* Leave the idle function */
1743 /* We do not use simili-round-robin, it may require to read 1 meg buffers
1744 * again and again if many tracesets use the same tracefiles. */
1745 /* Hack for round-robin idle functions */
1746 /* It will put the idle function at the end of the pool */
1747 /*g_idle_add_full((G_PRIORITY_HIGH_IDLE + 21),
1748 (GSourceFunc)execute_events_requests,
1758 static void lttvwindow_add_trace(Tab
*tab
, LttvTrace
*trace_v
)
1760 LttvTraceset
*traceset
= tab
->traceset_info
->traceset
;
1762 guint num_traces
= lttv_traceset_number(traceset
);
1764 //Verify if trace is already present.
1765 for(i
=0; i
<num_traces
; i
++)
1767 LttvTrace
* trace
= lttv_traceset_get(traceset
, i
);
1768 if(trace
== trace_v
)
1772 //Keep a reference to the traces so they are not freed.
1773 for(i
=0; i
<lttv_traceset_number(traceset
); i
++)
1775 LttvTrace
* trace
= lttv_traceset_get(traceset
, i
);
1776 lttv_trace_ref(trace
);
1779 //remove state update hooks
1780 lttv_state_remove_event_hooks(
1781 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1783 lttv_context_fini(LTTV_TRACESET_CONTEXT(
1784 tab
->traceset_info
->traceset_context
));
1785 g_object_unref(tab
->traceset_info
->traceset_context
);
1787 lttv_traceset_add(traceset
, trace_v
);
1788 lttv_trace_ref(trace_v
); /* local ref */
1790 /* Create new context */
1791 tab
->traceset_info
->traceset_context
=
1792 g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
1794 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->
1799 //add state update hooks
1800 lttv_state_add_event_hooks(
1801 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1802 //Remove local reference to the traces.
1803 for(i
=0; i
<lttv_traceset_number(traceset
); i
++)
1805 LttvTrace
* trace
= lttv_traceset_get(traceset
, i
);
1806 lttv_trace_unref(trace
);
1810 //add_trace_into_traceset_selector(GTK_MULTIVPANED(tab->multivpaned), lttv_trace(trace_v));
1813 /* add_trace adds a trace into the current traceset. It first displays a
1814 * directory selection dialogue to let user choose a trace, then recreates
1815 * tracset_context, and redraws all the viewer of the current tab
1818 void add_trace(GtkWidget
* widget
, gpointer user_data
)
1821 LttvTrace
* trace_v
;
1822 LttvTraceset
* traceset
;
1824 char abs_path
[PATH_MAX
];
1826 MainWindow
* mw_data
= get_window_data_struct(widget
);
1827 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
1829 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
1830 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
1831 LttvPluginTab
*ptab
;
1835 ptab
= create_new_tab(widget
, NULL
);
1838 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
1842 /* File open dialog management */
1843 GtkFileChooser
* file_chooser
=
1845 gtk_file_chooser_dialog_new ("Select a trace",
1846 GTK_WINDOW(mw_data
->mwindow
),
1847 GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER
,
1848 GTK_STOCK_CANCEL
, GTK_RESPONSE_CANCEL
,
1849 GTK_STOCK_OPEN
, GTK_RESPONSE_ACCEPT
,
1852 gtk_file_chooser_set_show_hidden (file_chooser
, TRUE
);
1853 if(remember_trace_dir
[0] != '\0')
1854 gtk_file_chooser_set_filename(file_chooser
, remember_trace_dir
);
1856 id
= gtk_dialog_run(GTK_DIALOG(file_chooser
));
1859 case GTK_RESPONSE_ACCEPT
:
1860 case GTK_RESPONSE_OK
:
1861 dir
= gtk_file_chooser_get_filename (file_chooser
);
1862 strncpy(remember_trace_dir
, dir
, PATH_MAX
);
1863 strncat(remember_trace_dir
, "/", PATH_MAX
);
1864 if(!dir
|| strlen(dir
) == 0){
1867 get_absolute_pathname(dir
, abs_path
);
1868 trace_v
= lttvwindowtraces_get_trace_by_name(abs_path
);
1869 if(trace_v
== NULL
) {
1870 trace
= ltt_trace_open(abs_path
);
1872 g_warning("cannot open trace %s", abs_path
);
1874 GtkWidget
*dialogue
=
1875 gtk_message_dialog_new(
1876 GTK_WINDOW(gtk_widget_get_toplevel(widget
)),
1877 GTK_DIALOG_MODAL
|GTK_DIALOG_DESTROY_WITH_PARENT
,
1880 "Cannot open trace : maybe you should enter in the trace "
1881 "directory to select it ?");
1882 gtk_dialog_run(GTK_DIALOG(dialogue
));
1883 gtk_widget_destroy(dialogue
);
1886 trace_v
= lttv_trace_new(trace
);
1887 lttvwindowtraces_add_trace(trace_v
);
1888 lttvwindow_add_trace(tab
, trace_v
);
1891 lttvwindow_add_trace(tab
, trace_v
);
1895 //update current tab
1896 //update_traceset(mw_data);
1898 /* Call the updatetraceset hooks */
1900 traceset
= tab
->traceset_info
->traceset
;
1901 SetTraceset(tab
, traceset
);
1902 // in expose now call_pending_read_hooks(mw_data);
1904 //lttvwindow_report_current_time(mw_data,&(tab->current_time));
1906 case GTK_RESPONSE_REJECT
:
1907 case GTK_RESPONSE_CANCEL
:
1911 gtk_widget_destroy((GtkWidget
*)file_chooser
);
1915 /* remove_trace removes a trace from the current traceset if all viewers in
1916 * the current tab are not interested in the trace. It first displays a
1917 * dialogue, which shows all traces in the current traceset, to let user choose
1918 * a trace, then it checks if all viewers unselect the trace, if it is true,
1919 * it will remove the trace, recreate the traceset_contex,
1920 * and redraws all the viewer of the current tab. If there is on trace in the
1921 * current traceset, it will delete all viewers of the current tab
1923 * It destroys the filter tree. FIXME... we should request for an update
1927 void remove_trace(GtkWidget
*widget
, gpointer user_data
)
1930 LttvTrace
* trace_v
;
1931 LttvTraceset
* traceset
;
1932 gint i
, j
, nb_trace
, index
=-1;
1933 char ** name
, *remove_trace_name
;
1934 MainWindow
* mw_data
= get_window_data_struct(widget
);
1935 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
1937 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
1938 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
1944 LttvPluginTab
*ptab
;
1945 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
1949 nb_trace
=lttv_traceset_number(tab
->traceset_info
->traceset
);
1950 name
= g_new(char*,nb_trace
);
1951 for(i
= 0; i
< nb_trace
; i
++){
1952 trace_v
= lttv_traceset_get(tab
->traceset_info
->traceset
, i
);
1953 trace
= lttv_trace(trace_v
);
1954 name
[i
] = (char *) g_quark_to_string(ltt_trace_name(trace
));
1957 remove_trace_name
= get_remove_trace(mw_data
, name
, nb_trace
);
1960 if(remove_trace_name
){
1962 /* yuk, cut n paste from old code.. should be better (MD)*/
1963 for(i
= 0; i
<nb_trace
; i
++) {
1964 if(strcmp(remove_trace_name
,name
[i
]) == 0){
1969 traceset
= tab
->traceset_info
->traceset
;
1970 //Keep a reference to the traces so they are not freed.
1971 for(j
=0; j
<lttv_traceset_number(traceset
); j
++)
1973 LttvTrace
* trace
= lttv_traceset_get(traceset
, j
);
1974 lttv_trace_ref(trace
);
1977 //remove state update hooks
1978 lttv_state_remove_event_hooks(
1979 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1980 lttv_context_fini(LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
));
1981 g_object_unref(tab
->traceset_info
->traceset_context
);
1983 trace_v
= lttv_traceset_get(traceset
, index
);
1985 lttv_traceset_remove(traceset
, index
);
1986 lttv_trace_unref(trace_v
); // Remove local reference
1988 if(lttv_trace_get_ref_number(trace_v
) <= 1) {
1989 /* ref 1 : lttvwindowtraces only*/
1990 ltt_trace_close(lttv_trace(trace_v
));
1991 /* lttvwindowtraces_remove_trace takes care of destroying
1992 * the traceset linked with the trace_v and also of destroying
1993 * the trace_v at the same time.
1995 lttvwindowtraces_remove_trace(trace_v
);
1998 tab
->traceset_info
->traceset_context
=
1999 g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
2001 LTTV_TRACESET_CONTEXT(tab
->
2002 traceset_info
->traceset_context
),traceset
);
2003 //add state update hooks
2004 lttv_state_add_event_hooks(
2005 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
2007 //Remove local reference to the traces.
2008 for(j
=0; j
<lttv_traceset_number(traceset
); j
++)
2010 LttvTrace
* trace
= lttv_traceset_get(traceset
, j
);
2011 lttv_trace_unref(trace
);
2014 SetTraceset(tab
, (gpointer
)traceset
);
2020 void remove_trace(GtkWidget
* widget
, gpointer user_data
)
2023 LttvTrace
* trace_v
;
2024 LttvTraceset
* traceset
;
2025 gint i
, j
, nb_trace
;
2026 char ** name
, *remove_trace_name
;
2027 MainWindow
* mw_data
= get_window_data_struct(widget
);
2028 LttvTracesetSelector
* s
;
2029 LttvTraceSelector
* t
;
2032 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
2034 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2035 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2041 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
2044 nb_trace
=lttv_traceset_number(tab
->traceset_info
->traceset
);
2045 name
= g_new(char*,nb_trace
);
2046 for(i
= 0; i
< nb_trace
; i
++){
2047 trace_v
= lttv_traceset_get(tab
->traceset_info
->traceset
, i
);
2048 trace
= lttv_trace(trace_v
);
2049 name
[i
] = ltt_trace_name(trace
);
2052 remove_trace_name
= get_remove_trace(name
, nb_trace
);
2054 if(remove_trace_name
){
2055 for(i
=0; i
<nb_trace
; i
++){
2056 if(strcmp(remove_trace_name
,name
[i
]) == 0){
2057 //unselect the trace from the current viewer
2059 w
= gtk_multivpaned_get_widget(GTK_MULTIVPANED(tab
->multivpaned
));
2061 s
= g_object_get_data(G_OBJECT(w
), "Traceset_Selector");
2063 t
= lttv_traceset_selector_trace_get(s
,i
);
2064 lttv_trace_selector_set_selected(t
, FALSE
);
2067 //check if other viewers select the trace
2068 w
= gtk_multivpaned_get_first_widget(GTK_MULTIVPANED(tab
->multivpaned
));
2070 s
= g_object_get_data(G_OBJECT(w
), "Traceset_Selector");
2072 t
= lttv_traceset_selector_trace_get(s
,i
);
2073 selected
= lttv_trace_selector_get_selected(t
);
2076 w
= gtk_multivpaned_get_next_widget(GTK_MULTIVPANED(tab
->multivpaned
));
2078 }else selected
= FALSE
;
2080 //if no viewer selects the trace, remove it
2082 remove_trace_from_traceset_selector(GTK_MULTIVPANED(tab
->multivpaned
), i
);
2084 traceset
= tab
->traceset_info
->traceset
;
2085 //Keep a reference to the traces so they are not freed.
2086 for(j
=0; j
<lttv_traceset_number(traceset
); j
++)
2088 LttvTrace
* trace
= lttv_traceset_get(traceset
, j
);
2089 lttv_trace_ref(trace
);
2092 //remove state update hooks
2093 lttv_state_remove_event_hooks(
2094 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
2095 lttv_context_fini(LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
));
2096 g_object_unref(tab
->traceset_info
->traceset_context
);
2099 trace_v
= lttv_traceset_get(traceset
, i
);
2101 if(lttv_trace_get_ref_number(trace_v
) <= 2) {
2102 /* ref 2 : traceset, local */
2103 lttvwindowtraces_remove_trace(trace_v
);
2104 ltt_trace_close(lttv_trace(trace_v
));
2107 lttv_traceset_remove(traceset
, i
);
2108 lttv_trace_unref(trace_v
); // Remove local reference
2110 if(!lttv_trace_get_ref_number(trace_v
))
2111 lttv_trace_destroy(trace_v
);
2113 tab
->traceset_info
->traceset_context
=
2114 g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
2116 LTTV_TRACESET_CONTEXT(tab
->
2117 traceset_info
->traceset_context
),traceset
);
2118 //add state update hooks
2119 lttv_state_add_event_hooks(
2120 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
2122 //Remove local reference to the traces.
2123 for(j
=0; j
<lttv_traceset_number(traceset
); j
++)
2125 LttvTrace
* trace
= lttv_traceset_get(traceset
, j
);
2126 lttv_trace_unref(trace
);
2130 //update current tab
2131 //update_traceset(mw_data);
2134 SetTraceset(tab
, (gpointer
)traceset
);
2135 // in expose now call_pending_read_hooks(mw_data);
2137 //lttvwindow_report_current_time(mw_data,&(tab->current_time));
2140 // while(tab->multi_vpaned->num_children){
2141 // gtk_multi_vpaned_widget_delete(tab->multi_vpaned);
2155 /* Redraw all the viewers in the current tab */
2156 void redraw(GtkWidget
*widget
, gpointer user_data
)
2158 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
2159 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2160 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2167 LttvPluginTab
*ptab
;
2168 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
2173 LttvAttributeValue value
;
2175 retval
= lttv_iattribute_find_by_path(tab
->attributes
, "hooks/redraw", LTTV_POINTER
, &value
);
2178 tmp
= (LttvHooks
*)*(value
.v_pointer
);
2180 lttv_hooks_call(tmp
,NULL
);
2184 void continue_processing(GtkWidget
*widget
, gpointer user_data
)
2186 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
2187 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2188 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2195 LttvPluginTab
*ptab
;
2196 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
2201 LttvAttributeValue value
;
2203 retval
= lttv_iattribute_find_by_path(tab
->attributes
, "hooks/continue",
2204 LTTV_POINTER
, &value
);
2207 tmp
= (LttvHooks
*)*(value
.v_pointer
);
2209 lttv_hooks_call(tmp
,NULL
);
2212 /* Stop the processing for the calling main window's current tab.
2213 * It removes every processing requests that are in its list. It does not call
2214 * the end request hooks, because the request is not finished.
2217 void stop_processing(GtkWidget
*widget
, gpointer user_data
)
2219 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
2220 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2221 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2226 LttvPluginTab
*ptab
;
2227 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
2230 GSList
*iter
= tab
->events_requests
;
2232 while(iter
!= NULL
) {
2233 GSList
*remove_iter
= iter
;
2234 iter
= g_slist_next(iter
);
2236 g_free(remove_iter
->data
);
2237 tab
->events_requests
=
2238 g_slist_remove_link(tab
->events_requests
, remove_iter
);
2240 tab
->events_request_pending
= FALSE
;
2241 tab
->stop_foreground
= TRUE
;
2242 g_idle_remove_by_data(tab
);
2243 g_assert(g_slist_length(tab
->events_requests
) == 0);
2247 /* save will save the traceset to a file
2248 * Not implemented yet FIXME
2251 void save(GtkWidget
* widget
, gpointer user_data
)
2256 void save_as(GtkWidget
* widget
, gpointer user_data
)
2258 g_info("Save as\n");
2262 /* zoom will change the time_window of all the viewers of the
2263 * current tab, and redisplay them. The main functionality is to
2264 * determine the new time_window of the current tab
2267 void zoom(GtkWidget
* widget
, double size
)
2269 TimeInterval time_span
;
2270 TimeWindow new_time_window
;
2271 LttTime current_time
, time_delta
;
2272 LttvTracesetContext
*tsc
;
2273 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
2275 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2276 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2282 LttvPluginTab
*ptab
;
2283 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
2287 if(size
== 1) return;
2289 tsc
= LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
2290 time_span
= tsc
->time_span
;
2291 new_time_window
= tab
->time_window
;
2292 current_time
= tab
->current_time
;
2294 time_delta
= ltt_time_sub(time_span
.end_time
,time_span
.start_time
);
2296 new_time_window
.start_time
= time_span
.start_time
;
2297 new_time_window
.time_width
= time_delta
;
2298 new_time_window
.time_width_double
= ltt_time_to_double(time_delta
);
2299 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
2300 new_time_window
.time_width
) ;
2302 new_time_window
.time_width
= ltt_time_div(new_time_window
.time_width
, size
);
2303 new_time_window
.time_width_double
=
2304 ltt_time_to_double(new_time_window
.time_width
);
2305 if(ltt_time_compare(new_time_window
.time_width
,time_delta
) > 0)
2306 { /* Case where zoom out is bigger than trace length */
2307 new_time_window
.start_time
= time_span
.start_time
;
2308 new_time_window
.time_width
= time_delta
;
2309 new_time_window
.time_width_double
= ltt_time_to_double(time_delta
);
2310 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
2311 new_time_window
.time_width
) ;
2315 /* Center the image on the current time */
2316 new_time_window
.start_time
=
2317 ltt_time_sub(current_time
,
2318 ltt_time_from_double(new_time_window
.time_width_double
/2.0));
2319 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
2320 new_time_window
.time_width
) ;
2321 /* If on borders, don't fall off */
2322 if(ltt_time_compare(new_time_window
.start_time
, time_span
.start_time
) <0
2323 || ltt_time_compare(new_time_window
.start_time
, time_span
.end_time
) >0)
2325 new_time_window
.start_time
= time_span
.start_time
;
2326 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
2327 new_time_window
.time_width
) ;
2331 if(ltt_time_compare(new_time_window
.end_time
,
2332 time_span
.end_time
) > 0
2333 || ltt_time_compare(new_time_window
.end_time
,
2334 time_span
.start_time
) < 0)
2336 new_time_window
.start_time
=
2337 ltt_time_sub(time_span
.end_time
, new_time_window
.time_width
);
2339 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
2340 new_time_window
.time_width
) ;
2347 if(ltt_time_compare(new_time_window
.time_width
, ltt_time_zero
) == 0) {
2348 g_warning("Zoom more than 1 ns impossible");
2350 time_change_manager(tab
, new_time_window
);
2354 void zoom_in(GtkWidget
* widget
, gpointer user_data
)
2359 void zoom_out(GtkWidget
* widget
, gpointer user_data
)
2364 void zoom_extended(GtkWidget
* widget
, gpointer user_data
)
2369 void go_to_time(GtkWidget
* widget
, gpointer user_data
)
2371 g_info("Go to time\n");
2374 void show_time_frame(GtkWidget
* widget
, gpointer user_data
)
2376 g_info("Show time frame\n");
2380 /* callback function */
2383 on_empty_traceset_activate (GtkMenuItem
*menuitem
,
2386 create_new_window((GtkWidget
*)menuitem
, user_data
, FALSE
);
2391 on_clone_traceset_activate (GtkMenuItem
*menuitem
,
2394 create_new_window((GtkWidget
*)menuitem
, user_data
, TRUE
);
2398 /* create_new_tab calls create_tab to construct a new tab in the main window
2401 LttvPluginTab
*create_new_tab(GtkWidget
* widget
, gpointer user_data
)
2403 gchar label
[PATH_MAX
];
2404 MainWindow
* mw_data
= get_window_data_struct(widget
);
2406 GtkNotebook
* notebook
= (GtkNotebook
*)lookup_widget(widget
, "MNotebook");
2407 if(notebook
== NULL
){
2408 g_info("Notebook does not exist\n");
2411 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2412 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2418 LttvPluginTab
*ptab
;
2419 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
2420 copy_tab
= ptab
->tab
;
2423 strcpy(label
,"Page");
2424 if(get_label(mw_data
, label
,"Get the name of the tab","Please input tab's name")) {
2425 LttvPluginTab
*ptab
;
2427 ptab
= g_object_new(LTTV_TYPE_PLUGIN_TAB
, NULL
);
2428 init_tab (ptab
->tab
, mw_data
, copy_tab
, notebook
, label
);
2429 ptab
->parent
.top_widget
= ptab
->tab
->top_widget
;
2430 g_object_set_data_full(
2431 G_OBJECT(ptab
->tab
->vbox
),
2434 (GDestroyNotify
)tab_destructor
);
2441 on_tab_activate (GtkMenuItem
*menuitem
,
2444 create_new_tab((GtkWidget
*)menuitem
, user_data
);
2449 on_open_activate (GtkMenuItem
*menuitem
,
2452 open_traceset((GtkWidget
*)menuitem
, user_data
);
2457 on_close_activate (GtkMenuItem
*menuitem
,
2460 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2461 main_window_destructor(mw_data
);
2465 /* remove the current tab from the main window
2469 on_close_tab_activate (GtkWidget
*widget
,
2473 GtkWidget
* notebook
;
2474 notebook
= lookup_widget(widget
, "MNotebook");
2475 if(notebook
== NULL
){
2476 g_info("Notebook does not exist\n");
2480 page_num
= gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
));
2482 gtk_notebook_remove_page(GTK_NOTEBOOK(notebook
), page_num
);
2487 on_close_tab_X_clicked (GtkWidget
*widget
,
2491 GtkWidget
*notebook
= lookup_widget(widget
, "MNotebook");
2492 if(notebook
== NULL
){
2493 g_info("Notebook does not exist\n");
2497 if((page_num
= gtk_notebook_page_num(GTK_NOTEBOOK(notebook
), widget
)) != -1)
2498 gtk_notebook_remove_page(GTK_NOTEBOOK(notebook
), page_num
);
2504 on_add_trace_activate (GtkMenuItem
*menuitem
,
2507 add_trace((GtkWidget
*)menuitem
, user_data
);
2512 on_remove_trace_activate (GtkMenuItem
*menuitem
,
2515 remove_trace((GtkWidget
*)menuitem
, user_data
);
2520 on_save_activate (GtkMenuItem
*menuitem
,
2523 save((GtkWidget
*)menuitem
, user_data
);
2528 on_save_as_activate (GtkMenuItem
*menuitem
,
2531 save_as((GtkWidget
*)menuitem
, user_data
);
2536 on_quit_activate (GtkMenuItem
*menuitem
,
2539 while (g_slist_length(g_main_window_list
) != 0) {
2540 on_MWindow_destroy(((MainWindow
*)g_main_window_list
->data
)->mwindow
,
2547 on_cut_activate (GtkMenuItem
*menuitem
,
2555 on_copy_activate (GtkMenuItem
*menuitem
,
2563 on_paste_activate (GtkMenuItem
*menuitem
,
2571 on_delete_activate (GtkMenuItem
*menuitem
,
2579 on_zoom_in_activate (GtkMenuItem
*menuitem
,
2582 zoom_in((GtkWidget
*)menuitem
, user_data
);
2587 on_zoom_out_activate (GtkMenuItem
*menuitem
,
2590 zoom_out((GtkWidget
*)menuitem
, user_data
);
2595 on_zoom_extended_activate (GtkMenuItem
*menuitem
,
2598 zoom_extended((GtkWidget
*)menuitem
, user_data
);
2603 on_go_to_time_activate (GtkMenuItem
*menuitem
,
2606 go_to_time((GtkWidget
*)menuitem
, user_data
);
2611 on_show_time_frame_activate (GtkMenuItem
*menuitem
,
2614 show_time_frame((GtkWidget
*)menuitem
, user_data
);
2619 on_move_viewer_up_activate (GtkMenuItem
*menuitem
,
2622 move_up_viewer((GtkWidget
*)menuitem
, user_data
);
2627 on_move_viewer_down_activate (GtkMenuItem
*menuitem
,
2630 move_down_viewer((GtkWidget
*)menuitem
, user_data
);
2635 on_remove_viewer_activate (GtkMenuItem
*menuitem
,
2638 delete_viewer((GtkWidget
*)menuitem
, user_data
);
2642 on_trace_facility_activate (GtkMenuItem
*menuitem
,
2645 g_info("Trace facility selector: %s\n", "");
2649 /* Dispaly a file selection dialogue to let user select a library, then call
2650 * lttv_library_load().
2654 on_load_library_activate (GtkMenuItem
*menuitem
,
2657 GError
*error
= NULL
;
2658 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2660 gchar load_module_path_alter
[PATH_MAX
];
2664 gchar
*load_module_path
;
2665 name
= g_ptr_array_new();
2666 nb
= lttv_library_path_number();
2667 /* ask for the library path */
2671 path
= lttv_library_path_get(i
);
2672 g_ptr_array_add(name
, path
);
2675 load_module_path
= get_selection(mw_data
,
2676 (char **)(name
->pdata
), name
->len
,
2677 "Select a library path", "Library paths");
2678 if(load_module_path
!= NULL
)
2679 strncpy(load_module_path_alter
, load_module_path
, PATH_MAX
-1); // -1 for /
2681 g_ptr_array_free(name
, TRUE
);
2683 if(load_module_path
== NULL
) return;
2687 /* Make sure the module path ends with a / */
2688 gchar
*ptr
= load_module_path_alter
;
2690 ptr
= strchr(ptr
, '\0');
2692 if(*(ptr
-1) != '/') {
2699 /* Ask for the library to load : list files in the previously selected
2701 gchar str
[PATH_MAX
];
2704 GtkFileSelection
* file_selector
=
2705 (GtkFileSelection
*)gtk_file_selection_new("Select a module");
2706 gtk_file_selection_set_filename(file_selector
, load_module_path_alter
);
2707 gtk_file_selection_hide_fileop_buttons(file_selector
);
2709 gtk_window_set_transient_for(GTK_WINDOW(file_selector
),
2710 GTK_WINDOW(mw_data
->mwindow
));
2713 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
2715 case GTK_RESPONSE_ACCEPT
:
2716 case GTK_RESPONSE_OK
:
2717 dir
= gtk_file_selection_get_selections (file_selector
);
2718 strncpy(str
,dir
[0],PATH_MAX
);
2719 strncpy(remember_plugins_dir
,dir
[0],PATH_MAX
);
2720 /* only keep file name */
2722 str1
= strrchr(str
,'/');
2725 str1
= strrchr(str
,'\\');
2730 if(*str1
== 'l' && *(str1
+1)== 'i' && *(str1
+2)=='b')
2732 remove info after
. */
2736 str2
= strrchr(str2
, '.');
2737 if(str2
!= NULL
) *str2
= '\0';
2739 lttv_module_require(str1
, &error
);
2741 lttv_library_load(str1
, &error
);
2742 if(error
!= NULL
) g_warning("%s", error
->message
);
2743 else g_info("Load library: %s\n", str
);
2745 case GTK_RESPONSE_REJECT
:
2746 case GTK_RESPONSE_CANCEL
:
2748 gtk_widget_destroy((GtkWidget
*)file_selector
);
2759 /* Display all loaded modules, let user to select a module to unload
2760 * by calling lttv_module_unload
2764 on_unload_library_activate (GtkMenuItem
*menuitem
,
2767 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2769 LttvLibrary
*library
= NULL
;
2774 name
= g_ptr_array_new();
2775 nb
= lttv_library_number();
2776 LttvLibraryInfo
*lib_info
= g_new(LttvLibraryInfo
,nb
);
2777 /* ask for the library name */
2780 LttvLibrary
*iter_lib
= lttv_library_get(i
);
2781 lttv_library_info(iter_lib
, &lib_info
[i
]);
2783 gchar
*path
= lib_info
[i
].name
;
2784 g_ptr_array_add(name
, path
);
2786 lib_name
= get_selection(mw_data
, (char **)(name
->pdata
), name
->len
,
2787 "Select a library", "Libraries");
2788 if(lib_name
!= NULL
) {
2790 if(strcmp(lib_name
, lib_info
[i
].name
) == 0) {
2791 library
= lttv_library_get(i
);
2796 g_ptr_array_free(name
, TRUE
);
2799 if(lib_name
== NULL
) return;
2801 if(library
!= NULL
) lttv_library_unload(library
);
2805 /* Dispaly a file selection dialogue to let user select a module, then call
2806 * lttv_module_require().
2810 on_load_module_activate (GtkMenuItem
*menuitem
,
2813 GError
*error
= NULL
;
2814 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2816 LttvLibrary
*library
= NULL
;
2821 name
= g_ptr_array_new();
2822 nb
= lttv_library_number();
2823 LttvLibraryInfo
*lib_info
= g_new(LttvLibraryInfo
,nb
);
2824 /* ask for the library name */
2827 LttvLibrary
*iter_lib
= lttv_library_get(i
);
2828 lttv_library_info(iter_lib
, &lib_info
[i
]);
2830 gchar
*path
= lib_info
[i
].name
;
2831 g_ptr_array_add(name
, path
);
2833 lib_name
= get_selection(mw_data
,(char **)(name
->pdata
), name
->len
,
2834 "Select a library", "Libraries");
2835 if(lib_name
!= NULL
) {
2837 if(strcmp(lib_name
, lib_info
[i
].name
) == 0) {
2838 library
= lttv_library_get(i
);
2843 g_ptr_array_free(name
, TRUE
);
2846 if(lib_name
== NULL
) return;
2849 //LttvModule *module;
2850 gchar module_name_out
[PATH_MAX
];
2852 /* Ask for the module to load : list modules in the selected lib */
2856 nb
= lttv_library_module_number(library
);
2857 LttvModuleInfo
*module_info
= g_new(LttvModuleInfo
,nb
);
2858 name
= g_ptr_array_new();
2859 /* ask for the module name */
2862 LttvModule
*iter_module
= lttv_library_module_get(library
, i
);
2863 lttv_module_info(iter_module
, &module_info
[i
]);
2865 gchar
*path
= module_info
[i
].name
;
2866 g_ptr_array_add(name
, path
);
2868 module_name
= get_selection(mw_data
, (char **)(name
->pdata
), name
->len
,
2869 "Select a module", "Modules");
2870 if(module_name
!= NULL
) {
2872 if(strcmp(module_name
, module_info
[i
].name
) == 0) {
2873 strncpy(module_name_out
, module_name
, PATH_MAX
);
2874 //module = lttv_library_module_get(i);
2880 g_ptr_array_free(name
, TRUE
);
2881 g_free(module_info
);
2883 if(module_name
== NULL
) return;
2886 lttv_module_require(module_name_out
, &error
);
2887 if(error
!= NULL
) g_warning("%s", error
->message
);
2888 else g_info("Load module: %s", module_name_out
);
2895 gchar str
[PATH_MAX
];
2898 GtkFileSelection
* file_selector
=
2899 (GtkFileSelection
*)gtk_file_selection_new("Select a module");
2900 gtk_file_selection_set_filename(file_selector
, load_module_path_alter
);
2901 gtk_file_selection_hide_fileop_buttons(file_selector
);
2904 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
2906 case GTK_RESPONSE_ACCEPT
:
2907 case GTK_RESPONSE_OK
:
2908 dir
= gtk_file_selection_get_selections (file_selector
);
2909 strncpy(str
,dir
[0],PATH_MAX
);
2910 strncpy(remember_plugins_dir
,dir
[0],PATH_MAX
);
2912 /* only keep file name */
2914 str1
= strrchr(str
,'/');
2917 str1
= strrchr(str
,'\\');
2922 if(*str1
== 'l' && *(str1
+1)== 'i' && *(str1
+2)=='b')
2924 remove info after
. */
2928 str2
= strrchr(str2
, '.');
2929 if(str2
!= NULL
) *str2
= '\0';
2931 lttv_module_require(str1
, &error
);
2933 lttv_library_load(str1
, &error
);
2934 if(error
!= NULL
) g_warning(error
->message
);
2935 else g_info("Load library: %s\n", str
);
2937 case GTK_RESPONSE_REJECT
:
2938 case GTK_RESPONSE_CANCEL
:
2940 gtk_widget_destroy((GtkWidget
*)file_selector
);
2952 /* Display all loaded modules, let user to select a module to unload
2953 * by calling lttv_module_unload
2957 on_unload_module_activate (GtkMenuItem
*menuitem
,
2960 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2962 LttvLibrary
*library
= NULL
;
2967 name
= g_ptr_array_new();
2968 nb
= lttv_library_number();
2969 LttvLibraryInfo
*lib_info
= g_new(LttvLibraryInfo
,nb
);
2970 /* ask for the library name */
2973 LttvLibrary
*iter_lib
= lttv_library_get(i
);
2974 lttv_library_info(iter_lib
, &lib_info
[i
]);
2976 gchar
*path
= lib_info
[i
].name
;
2977 g_ptr_array_add(name
, path
);
2979 lib_name
= get_selection(mw_data
, (char **)(name
->pdata
), name
->len
,
2980 "Select a library", "Libraries");
2981 if(lib_name
!= NULL
) {
2983 if(strcmp(lib_name
, lib_info
[i
].name
) == 0) {
2984 library
= lttv_library_get(i
);
2989 g_ptr_array_free(name
, TRUE
);
2992 if(lib_name
== NULL
) return;
2995 LttvModule
*module
= NULL
;
2997 /* Ask for the module to load : list modules in the selected lib */
3001 nb
= lttv_library_module_number(library
);
3002 LttvModuleInfo
*module_info
= g_new(LttvModuleInfo
,nb
);
3003 name
= g_ptr_array_new();
3004 /* ask for the module name */
3007 LttvModule
*iter_module
= lttv_library_module_get(library
, i
);
3008 lttv_module_info(iter_module
, &module_info
[i
]);
3010 gchar
*path
= module_info
[i
].name
;
3011 if(module_info
[i
].use_count
> 0) g_ptr_array_add(name
, path
);
3013 module_name
= get_selection(mw_data
, (char **)(name
->pdata
), name
->len
,
3014 "Select a module", "Modules");
3015 if(module_name
!= NULL
) {
3017 if(strcmp(module_name
, module_info
[i
].name
) == 0) {
3018 module
= lttv_library_module_get(library
, i
);
3024 g_ptr_array_free(name
, TRUE
);
3025 g_free(module_info
);
3027 if(module_name
== NULL
) return;
3030 LttvModuleInfo module_info
;
3031 lttv_module_info(module
, &module_info
);
3032 g_info("Release module: %s\n", module_info
.name
);
3034 lttv_module_release(module
);
3038 /* Display a directory dialogue to let user select a path for library searching
3042 on_add_library_search_path_activate (GtkMenuItem
*menuitem
,
3045 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
3046 //GtkDirSelection * file_selector = (GtkDirSelection *)gtk_dir_selection_new("Select library path");
3047 GtkFileSelection
* file_selector
= (GtkFileSelection
*)gtk_file_selection_new("Select a trace");
3048 gtk_widget_hide( (file_selector
)->file_list
->parent
) ;
3050 gtk_window_set_transient_for(GTK_WINDOW(file_selector
),
3051 GTK_WINDOW(mw_data
->mwindow
));
3056 if(remember_plugins_dir
[0] != '\0')
3057 gtk_file_selection_set_filename(file_selector
, remember_plugins_dir
);
3059 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
3061 case GTK_RESPONSE_ACCEPT
:
3062 case GTK_RESPONSE_OK
:
3063 dir
= gtk_file_selection_get_filename (file_selector
);
3064 strncpy(remember_plugins_dir
,dir
,PATH_MAX
);
3065 strncat(remember_plugins_dir
,"/",PATH_MAX
);
3066 lttv_library_path_add(dir
);
3067 case GTK_RESPONSE_REJECT
:
3068 case GTK_RESPONSE_CANCEL
:
3070 gtk_widget_destroy((GtkWidget
*)file_selector
);
3076 /* Display a directory dialogue to let user select a path for library searching
3080 on_remove_library_search_path_activate (GtkMenuItem
*menuitem
,
3083 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
3085 const char *lib_path
;
3089 name
= g_ptr_array_new();
3090 nb
= lttv_library_path_number();
3091 /* ask for the library name */
3094 gchar
*path
= lttv_library_path_get(i
);
3095 g_ptr_array_add(name
, path
);
3097 lib_path
= get_selection(mw_data
, (char **)(name
->pdata
), name
->len
,
3098 "Select a library path", "Library paths");
3100 g_ptr_array_free(name
, TRUE
);
3102 if(lib_path
== NULL
) return;
3105 lttv_library_path_remove(lib_path
);
3109 on_color_activate (GtkMenuItem
*menuitem
,
3117 on_save_configuration_activate (GtkMenuItem
*menuitem
,
3120 g_info("Save configuration\n");
3125 on_content_activate (GtkMenuItem
*menuitem
,
3128 g_info("Content\n");
3133 on_about_close_activate (GtkButton
*button
,
3136 GtkWidget
*about_widget
= GTK_WIDGET(user_data
);
3138 gtk_widget_destroy(about_widget
);
3142 on_about_activate (GtkMenuItem
*menuitem
,
3145 MainWindow
*main_window
= get_window_data_struct(GTK_WIDGET(menuitem
));
3146 GtkWidget
*window_widget
= main_window
->mwindow
;
3147 GtkWidget
*about_widget
= gtk_window_new(GTK_WINDOW_TOPLEVEL
);
3148 GtkWindow
*about_window
= GTK_WINDOW(about_widget
);
3149 gint window_width
, window_height
;
3151 gtk_window_set_title(about_window
, "About Linux Trace Toolkit");
3153 gtk_window_set_resizable(about_window
, FALSE
);
3154 gtk_window_set_transient_for(about_window
, GTK_WINDOW(window_widget
));
3155 gtk_window_set_destroy_with_parent(about_window
, TRUE
);
3156 gtk_window_set_modal(about_window
, FALSE
);
3158 /* Put the about window at the center of the screen */
3159 gtk_window_get_size(about_window
, &window_width
, &window_height
);
3160 gtk_window_move (about_window
,
3161 (gdk_screen_width() - window_width
)/2,
3162 (gdk_screen_height() - window_height
)/2);
3164 GtkWidget
*vbox
= gtk_vbox_new(FALSE
, 1);
3166 gtk_container_add(GTK_CONTAINER(about_widget
), vbox
);
3170 GtkWidget
*label1
= gtk_label_new("");
3171 gtk_misc_set_padding(GTK_MISC(label1
), 10, 20);
3172 gtk_label_set_markup(GTK_LABEL(label1
), "\
3173 <big>Linux Trace Toolkit " VERSION
"</big>");
3174 gtk_label_set_justify(GTK_LABEL(label1
), GTK_JUSTIFY_CENTER
);
3176 GtkWidget
*label2
= gtk_label_new("");
3177 gtk_misc_set_padding(GTK_MISC(label2
), 10, 20);
3178 gtk_label_set_markup(GTK_LABEL(label2
), "\
3181 Michel Dagenais (New trace format, lttv main)\n\
3182 Mathieu Desnoyers (Kernel Tracer, Directory structure, build with automake/conf,\n\
3183 lttv gui, control flow view, gui cooperative trace reading\n\
3184 scheduler with interruptible foreground and background\n\
3185 computation, detailed event list (rewrite), trace reading\n\
3186 library (rewrite))\n\
3187 Benoit Des Ligneris, Eric Clement (Cluster adaptation, work in progress)\n\
3188 Xang-Xiu Yang (new trace reading library and converter, lttv gui, \n\
3189 detailed event list and statistics view)\n\
3190 Tom Zanussi (RelayFS)\n\
3192 Inspired from the original Linux Trace Toolkit Visualizer made by\n\
3195 GtkWidget
*label3
= gtk_label_new("");
3196 gtk_label_set_markup(GTK_LABEL(label3
), "\
3197 Linux Trace Toolkit Viewer, Copyright (C) 2004, 2005, 2006\n\
3199 Mathieu Desnoyers\n\
3201 Linux Trace Toolkit comes with ABSOLUTELY NO WARRANTY.\n\
3202 This is free software, and you are welcome to redistribute it\n\
3203 under certain conditions. See COPYING for details.");
3204 gtk_misc_set_padding(GTK_MISC(label3
), 10, 20);
3206 gtk_box_pack_start_defaults(GTK_BOX(vbox
), label1
);
3207 gtk_box_pack_start_defaults(GTK_BOX(vbox
), label2
);
3208 gtk_box_pack_start_defaults(GTK_BOX(vbox
), label3
);
3210 GtkWidget
*hbox
= gtk_hbox_new(TRUE
, 0);
3211 gtk_box_pack_end(GTK_BOX(vbox
), hbox
, FALSE
, FALSE
, 0);
3212 GtkWidget
*close_button
= gtk_button_new_with_mnemonic("_Close");
3213 gtk_box_pack_end(GTK_BOX(hbox
), close_button
, FALSE
, FALSE
, 0);
3214 gtk_container_set_border_width(GTK_CONTAINER(close_button
), 20);
3216 g_signal_connect(G_OBJECT(close_button
), "clicked",
3217 G_CALLBACK(on_about_close_activate
),
3218 (gpointer
)about_widget
);
3220 gtk_widget_show_all(about_widget
);
3225 on_button_new_clicked (GtkButton
*button
,
3228 create_new_window((GtkWidget
*)button
, user_data
, TRUE
);
3232 on_button_new_tab_clicked (GtkButton
*button
,
3235 create_new_tab((GtkWidget
*)button
, user_data
);
3239 on_button_open_clicked (GtkButton
*button
,
3242 open_traceset((GtkWidget
*)button
, user_data
);
3247 on_button_add_trace_clicked (GtkButton
*button
,
3250 add_trace((GtkWidget
*)button
, user_data
);
3255 on_button_remove_trace_clicked (GtkButton
*button
,
3258 remove_trace((GtkWidget
*)button
, user_data
);
3262 on_button_redraw_clicked (GtkButton
*button
,
3265 redraw((GtkWidget
*)button
, user_data
);
3269 on_button_continue_processing_clicked (GtkButton
*button
,
3272 continue_processing((GtkWidget
*)button
, user_data
);
3276 on_button_stop_processing_clicked (GtkButton
*button
,
3279 stop_processing((GtkWidget
*)button
, user_data
);
3285 on_button_save_clicked (GtkButton
*button
,
3288 save((GtkWidget
*)button
, user_data
);
3293 on_button_save_as_clicked (GtkButton
*button
,
3296 save_as((GtkWidget
*)button
, user_data
);
3301 on_button_zoom_in_clicked (GtkButton
*button
,
3304 zoom_in((GtkWidget
*)button
, user_data
);
3309 on_button_zoom_out_clicked (GtkButton
*button
,
3312 zoom_out((GtkWidget
*)button
, user_data
);
3317 on_button_zoom_extended_clicked (GtkButton
*button
,
3320 zoom_extended((GtkWidget
*)button
, user_data
);
3325 on_button_go_to_time_clicked (GtkButton
*button
,
3328 go_to_time((GtkWidget
*)button
, user_data
);
3333 on_button_show_time_frame_clicked (GtkButton
*button
,
3336 show_time_frame((GtkWidget
*)button
, user_data
);
3341 on_button_move_up_clicked (GtkButton
*button
,
3344 move_up_viewer((GtkWidget
*)button
, user_data
);
3349 on_button_move_down_clicked (GtkButton
*button
,
3352 move_down_viewer((GtkWidget
*)button
, user_data
);
3357 on_button_delete_viewer_clicked (GtkButton
*button
,
3360 delete_viewer((GtkWidget
*)button
, user_data
);
3364 on_MWindow_destroy (GtkWidget
*widget
,
3367 MainWindow
*main_window
= get_window_data_struct(widget
);
3368 LttvIAttribute
*attributes
= main_window
->attributes
;
3369 LttvAttributeValue value
;
3372 //This is unnecessary, since widgets will be destroyed
3373 //by the main window widget anyway.
3374 //remove_all_menu_toolbar_constructors(main_window, NULL);
3376 retval
= lttv_iattribute_find_by_path(attributes
, "viewers/menu",
3377 LTTV_POINTER
, &value
);
3379 lttv_menus_destroy((LttvMenus
*)*(value
.v_pointer
));
3381 retval
= lttv_iattribute_find_by_path(attributes
, "viewers/toolbar",
3382 LTTV_POINTER
, &value
);
3384 lttv_toolbars_destroy((LttvToolbars
*)*(value
.v_pointer
));
3386 g_object_unref(main_window
->attributes
);
3387 g_main_window_list
= g_slist_remove(g_main_window_list
, main_window
);
3389 g_info("There are now : %d windows\n",g_slist_length(g_main_window_list
));
3390 if(g_slist_length(g_main_window_list
) == 0)
3395 on_MWindow_configure (GtkWidget
*widget
,
3396 GdkEventConfigure
*event
,
3399 // MD : removed time width modification upon resizing of the main window.
3400 // The viewers will redraw themselves completely, without time interval
3403 if(mw_data->window_width){
3404 time_span = LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context)->Time_Span ;
3405 time_win = tab->time_window;
3406 ratio = width / mw_data->window_width;
3407 tab->time_window.time_width = ltt_time_mul(time_win.time_width,ratio);
3408 time = ltt_time_sub(time_span->endTime, time_win.start_time);
3409 if(ltt_time_compare(time, tab->time_window.time_width) < 0){
3410 tab->time_window.time_width = time;
3416 mw_data->window_width = (int)width;
3425 on_MNotebook_switch_page (GtkNotebook
*notebook
,
3426 GtkNotebookPage
*page
,
3434 void time_change_manager (Tab
*tab
,
3435 TimeWindow new_time_window
)
3437 /* Only one source of time change */
3438 if(tab
->time_manager_lock
== TRUE
) return;
3440 tab
->time_manager_lock
= TRUE
;
3442 LttvTracesetContext
*tsc
= LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3443 TimeInterval time_span
= tsc
->time_span
;
3444 LttTime start_time
= new_time_window
.start_time
;
3445 LttTime end_time
= new_time_window
.end_time
;
3446 LttTime time_width
= new_time_window
.time_width
;
3448 g_assert(ltt_time_compare(start_time
, end_time
) < 0);
3451 GtkAdjustment
*adjustment
= gtk_range_get_adjustment(GTK_RANGE(tab
->scrollbar
));
3452 LttTime upper
= ltt_time_sub(time_span
.end_time
, time_span
.start_time
);
3454 gtk_range_set_increments(GTK_RANGE(tab
->scrollbar
),
3455 ltt_time_to_double(new_time_window
.time_width
)
3456 / SCROLL_STEP_PER_PAGE
3457 * NANOSECONDS_PER_SECOND
, /* step increment */
3458 ltt_time_to_double(new_time_window
.time_width
)
3459 * NANOSECONDS_PER_SECOND
); /* page increment */
3460 gtk_range_set_range(GTK_RANGE(tab
->scrollbar
),
3462 ltt_time_to_double(upper
)
3463 * NANOSECONDS_PER_SECOND
); /* upper */
3465 g_object_set(G_OBJECT(adjustment
),
3469 ltt_time_to_double(upper
), /* upper */
3471 new_time_window
.time_width_double
3472 / SCROLL_STEP_PER_PAGE
, /* step increment */
3474 new_time_window
.time_width_double
,
3475 /* page increment */
3477 new_time_window
.time_width_double
, /* page size */
3479 gtk_adjustment_changed(adjustment
);
3481 // g_object_set(G_OBJECT(adjustment),
3483 // ltt_time_to_double(
3484 // ltt_time_sub(start_time, time_span.start_time))
3487 //gtk_adjustment_value_changed(adjustment);
3488 gtk_range_set_value(GTK_RANGE(tab
->scrollbar
),
3490 ltt_time_sub(start_time
, time_span
.start_time
)) /* value */);
3492 /* set the time bar. */
3494 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry1
),
3495 (double)time_span
.start_time
.tv_sec
,
3496 (double)time_span
.end_time
.tv_sec
);
3497 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry1
),
3498 (double)start_time
.tv_sec
);
3500 /* start nanoseconds */
3501 if(start_time
.tv_sec
== time_span
.start_time
.tv_sec
) {
3502 /* can be both beginning and end at the same time. */
3503 if(start_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3504 /* If we are at the end, max nsec to end.. -1 (not zero length) */
3505 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry2
),
3506 (double)time_span
.start_time
.tv_nsec
,
3507 (double)time_span
.end_time
.tv_nsec
-1);
3509 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry2
),
3510 (double)time_span
.start_time
.tv_nsec
,
3511 (double)NANOSECONDS_PER_SECOND
-1);
3513 } else if(start_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3514 /* If we are at the end, max nsec to end.. -1 (not zero length) */
3515 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry2
),
3517 (double)time_span
.end_time
.tv_nsec
-1);
3518 } else /* anywhere else */
3519 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry2
),
3521 (double)NANOSECONDS_PER_SECOND
-1);
3522 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry2
),
3523 (double)start_time
.tv_nsec
);
3526 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry3
),
3527 (double)time_span
.start_time
.tv_sec
,
3528 (double)time_span
.end_time
.tv_sec
);
3529 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry3
),
3530 (double)end_time
.tv_sec
);
3532 /* end nanoseconds */
3533 if(end_time
.tv_sec
== time_span
.start_time
.tv_sec
) {
3534 /* can be both beginning and end at the same time. */
3535 if(end_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3536 /* If we are at the end, max nsec to end.. */
3537 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry4
),
3538 (double)time_span
.start_time
.tv_nsec
+1,
3539 (double)time_span
.end_time
.tv_nsec
);
3541 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry4
),
3542 (double)time_span
.start_time
.tv_nsec
+1,
3543 (double)NANOSECONDS_PER_SECOND
-1);
3546 else if(end_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3547 /* If we are at the end, max nsec to end.. */
3548 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry4
),
3550 (double)time_span
.end_time
.tv_nsec
);
3552 else /* anywhere else */
3553 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry4
),
3555 (double)NANOSECONDS_PER_SECOND
-1);
3556 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry4
),
3557 (double)end_time
.tv_nsec
);
3560 if(time_width
.tv_nsec
== 0) {
3561 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry7
),
3563 (double)upper
.tv_sec
);
3565 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry7
),
3567 (double)upper
.tv_sec
);
3569 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry7
),
3570 (double)time_width
.tv_sec
);
3572 /* width nanoseconds */
3573 if(time_width
.tv_sec
== upper
.tv_sec
) {
3574 if(time_width
.tv_sec
== 0) {
3575 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry8
),
3577 (double)upper
.tv_nsec
);
3579 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry8
),
3581 (double)upper
.tv_nsec
);
3584 else if(time_width
.tv_sec
== 0) {
3585 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry8
),
3587 (double)upper
.tv_nsec
);
3589 else /* anywhere else */
3590 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry8
),
3592 (double)NANOSECONDS_PER_SECOND
-1);
3593 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry8
),
3594 (double)time_width
.tv_nsec
);
3596 /* call viewer hooks for new time window */
3597 set_time_window(tab
, &new_time_window
);
3599 tab
->time_manager_lock
= FALSE
;
3603 /* value changed for frame start s
3605 * Check time span : if ns is out of range, clip it the nearest good value.
3608 on_MEntry1_value_changed (GtkSpinButton
*spinbutton
,
3611 Tab
*tab
=(Tab
*)user_data
;
3612 LttvTracesetContext
* tsc
=
3613 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3614 TimeInterval time_span
= tsc
->time_span
;
3615 gint value
= gtk_spin_button_get_value_as_int(spinbutton
);
3617 TimeWindow new_time_window
= tab
->time_window
;
3619 LttTime end_time
= new_time_window
.end_time
;
3621 new_time_window
.start_time
.tv_sec
= value
;
3623 /* start nanoseconds */
3624 if(new_time_window
.start_time
.tv_sec
== time_span
.start_time
.tv_sec
) {
3625 if(new_time_window
.start_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3626 if(new_time_window
.start_time
.tv_nsec
> time_span
.end_time
.tv_nsec
)
3627 new_time_window
.start_time
.tv_nsec
= time_span
.end_time
.tv_nsec
-1;
3628 if(new_time_window
.start_time
.tv_nsec
< time_span
.start_time
.tv_nsec
)
3629 new_time_window
.start_time
.tv_nsec
= time_span
.start_time
.tv_nsec
;
3631 if(new_time_window
.start_time
.tv_nsec
< time_span
.start_time
.tv_nsec
)
3632 new_time_window
.start_time
.tv_nsec
= time_span
.start_time
.tv_nsec
;
3635 else if(new_time_window
.start_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3636 if(new_time_window
.start_time
.tv_nsec
> time_span
.end_time
.tv_nsec
)
3637 new_time_window
.start_time
.tv_nsec
= time_span
.end_time
.tv_nsec
-1;
3640 if(ltt_time_compare(new_time_window
.start_time
, end_time
) >= 0) {
3641 /* Then, we must push back end time : keep the same time width
3642 * if possible, else end traceset time */
3643 end_time
= LTT_TIME_MIN(ltt_time_add(new_time_window
.start_time
,
3644 new_time_window
.time_width
),
3645 time_span
.end_time
);
3648 /* Fix the time width to fit start time and end time */
3649 new_time_window
.time_width
= ltt_time_sub(end_time
,
3650 new_time_window
.start_time
);
3651 new_time_window
.time_width_double
=
3652 ltt_time_to_double(new_time_window
.time_width
);
3654 new_time_window
.end_time
= end_time
;
3656 time_change_manager(tab
, new_time_window
);
3661 on_MEntry2_value_changed (GtkSpinButton
*spinbutton
,
3664 Tab
*tab
=(Tab
*)user_data
;
3665 LttvTracesetContext
* tsc
=
3666 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3667 TimeInterval time_span
= tsc
->time_span
;
3668 gint value
= gtk_spin_button_get_value_as_int(spinbutton
);
3670 TimeWindow new_time_window
= tab
->time_window
;
3672 LttTime end_time
= new_time_window
.end_time
;
3674 new_time_window
.start_time
.tv_nsec
= value
;
3676 if(ltt_time_compare(new_time_window
.start_time
, end_time
) >= 0) {
3677 /* Then, we must push back end time : keep the same time width
3678 * if possible, else end traceset time */
3679 end_time
= LTT_TIME_MIN(ltt_time_add(new_time_window
.start_time
,
3680 new_time_window
.time_width
),
3681 time_span
.end_time
);
3684 /* Fix the time width to fit start time and end time */
3685 new_time_window
.time_width
= ltt_time_sub(end_time
,
3686 new_time_window
.start_time
);
3687 new_time_window
.time_width_double
=
3688 ltt_time_to_double(new_time_window
.time_width
);
3690 new_time_window
.end_time
= end_time
;
3692 time_change_manager(tab
, new_time_window
);
3697 on_MEntry3_value_changed (GtkSpinButton
*spinbutton
,
3700 Tab
*tab
=(Tab
*)user_data
;
3701 LttvTracesetContext
* tsc
=
3702 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3703 TimeInterval time_span
= tsc
->time_span
;
3704 gint value
= gtk_spin_button_get_value_as_int(spinbutton
);
3706 TimeWindow new_time_window
= tab
->time_window
;
3708 LttTime end_time
= new_time_window
.end_time
;
3710 end_time
.tv_sec
= value
;
3712 /* end nanoseconds */
3713 if(end_time
.tv_sec
== time_span
.start_time
.tv_sec
) {
3714 if(end_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3715 if(end_time
.tv_nsec
> time_span
.end_time
.tv_nsec
)
3716 end_time
.tv_nsec
= time_span
.end_time
.tv_nsec
;
3717 if(end_time
.tv_nsec
< time_span
.start_time
.tv_nsec
)
3718 end_time
.tv_nsec
= time_span
.start_time
.tv_nsec
+1;
3720 if(end_time
.tv_nsec
< time_span
.start_time
.tv_nsec
)
3721 end_time
.tv_nsec
= time_span
.start_time
.tv_nsec
+1;
3724 else if(end_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3725 if(end_time
.tv_nsec
> time_span
.end_time
.tv_nsec
)
3726 end_time
.tv_nsec
= time_span
.end_time
.tv_nsec
;
3729 if(ltt_time_compare(new_time_window
.start_time
, end_time
) >= 0) {
3730 /* Then, we must push front start time : keep the same time width
3731 * if possible, else end traceset time */
3732 new_time_window
.start_time
= LTT_TIME_MAX(
3733 ltt_time_sub(end_time
,
3734 new_time_window
.time_width
),
3735 time_span
.start_time
);
3738 /* Fix the time width to fit start time and end time */
3739 new_time_window
.time_width
= ltt_time_sub(end_time
,
3740 new_time_window
.start_time
);
3741 new_time_window
.time_width_double
=
3742 ltt_time_to_double(new_time_window
.time_width
);
3744 new_time_window
.end_time
= end_time
;
3746 time_change_manager(tab
, new_time_window
);
3751 on_MEntry4_value_changed (GtkSpinButton
*spinbutton
,
3754 Tab
*tab
=(Tab
*)user_data
;
3755 LttvTracesetContext
* tsc
=
3756 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3757 TimeInterval time_span
= tsc
->time_span
;
3758 gint value
= gtk_spin_button_get_value_as_int(spinbutton
);
3760 TimeWindow new_time_window
= tab
->time_window
;
3762 LttTime end_time
= new_time_window
.end_time
;
3764 end_time
.tv_nsec
= value
;
3766 if(ltt_time_compare(new_time_window
.start_time
, end_time
) >= 0) {
3767 /* Then, we must push front start time : keep the same time width
3768 * if possible, else end traceset time */
3769 new_time_window
.start_time
= LTT_TIME_MAX(
3770 ltt_time_sub(end_time
,
3771 new_time_window
.time_width
),
3772 time_span
.start_time
);
3775 /* Fix the time width to fit start time and end time */
3776 new_time_window
.time_width
= ltt_time_sub(end_time
,
3777 new_time_window
.start_time
);
3778 new_time_window
.time_width_double
=
3779 ltt_time_to_double(new_time_window
.time_width
);
3780 new_time_window
.end_time
= end_time
;
3782 time_change_manager(tab
, new_time_window
);
3786 /* value changed for time frame interval s
3788 * Check time span : if ns is out of range, clip it the nearest good value.
3791 on_MEntry7_value_changed (GtkSpinButton
*spinbutton
,
3794 Tab
*tab
=(Tab
*)user_data
;
3795 LttvTracesetContext
* tsc
=
3796 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3797 TimeInterval time_span
= tsc
->time_span
;
3798 gint value
= gtk_spin_button_get_value_as_int(spinbutton
);
3799 LttTime current_time
, time_delta
;
3800 TimeWindow new_time_window
= tab
->time_window
;
3801 current_time
= tab
->current_time
;
3803 time_delta
= ltt_time_sub(time_span
.end_time
,time_span
.start_time
);
3804 new_time_window
.time_width
.tv_sec
= value
;
3805 new_time_window
.time_width_double
=
3806 ltt_time_to_double(new_time_window
.time_width
);
3807 if(ltt_time_compare(new_time_window
.time_width
,time_delta
) > 0)
3808 { /* Case where zoom out is bigger than trace length */
3809 new_time_window
.start_time
= time_span
.start_time
;
3810 new_time_window
.time_width
= time_delta
;
3811 new_time_window
.time_width_double
= ltt_time_to_double(time_delta
);
3812 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
3813 new_time_window
.time_width
) ;
3817 /* Center the image on the current time */
3818 new_time_window
.start_time
=
3819 ltt_time_sub(current_time
,
3820 ltt_time_from_double(new_time_window
.time_width_double
/2.0));
3821 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
3822 new_time_window
.time_width
) ;
3823 /* If on borders, don't fall off */
3824 if(ltt_time_compare(new_time_window
.start_time
, time_span
.start_time
) <0
3825 || ltt_time_compare(new_time_window
.start_time
, time_span
.end_time
) >0)
3827 new_time_window
.start_time
= time_span
.start_time
;
3828 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
3829 new_time_window
.time_width
) ;
3833 if(ltt_time_compare(new_time_window
.end_time
,
3834 time_span
.end_time
) > 0
3835 || ltt_time_compare(new_time_window
.end_time
,
3836 time_span
.start_time
) < 0)
3838 new_time_window
.start_time
=
3839 ltt_time_sub(time_span
.end_time
, new_time_window
.time_width
);
3841 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
3842 new_time_window
.time_width
) ;
3848 if(ltt_time_compare(new_time_window
.time_width
, ltt_time_zero
) == 0) {
3849 g_warning("Zoom more than 1 ns impossible");
3851 time_change_manager(tab
, new_time_window
);
3856 on_MEntry8_value_changed (GtkSpinButton
*spinbutton
,
3859 Tab
*tab
=(Tab
*)user_data
;
3860 LttvTracesetContext
* tsc
=
3861 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3862 TimeInterval time_span
= tsc
->time_span
;
3863 gint value
= gtk_spin_button_get_value_as_int(spinbutton
);
3864 LttTime current_time
, time_delta
;
3865 TimeWindow new_time_window
= tab
->time_window
;
3866 current_time
= tab
->current_time
;
3868 time_delta
= ltt_time_sub(time_span
.end_time
,time_span
.start_time
);
3869 new_time_window
.time_width
.tv_nsec
= value
;
3870 new_time_window
.time_width_double
=
3871 ltt_time_to_double(new_time_window
.time_width
);
3872 if(ltt_time_compare(new_time_window
.time_width
,time_delta
) > 0)
3873 { /* Case where zoom out is bigger than trace length */
3874 new_time_window
.start_time
= time_span
.start_time
;
3875 new_time_window
.time_width
= time_delta
;
3876 new_time_window
.time_width_double
= ltt_time_to_double(time_delta
);
3877 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
3878 new_time_window
.time_width
) ;
3882 /* Center the image on the current time */
3883 new_time_window
.start_time
=
3884 ltt_time_sub(current_time
,
3885 ltt_time_from_double(new_time_window
.time_width_double
/2.0));
3886 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
3887 new_time_window
.time_width
) ;
3888 /* If on borders, don't fall off */
3889 if(ltt_time_compare(new_time_window
.start_time
, time_span
.start_time
) <0
3890 || ltt_time_compare(new_time_window
.start_time
, time_span
.end_time
) >0)
3892 new_time_window
.start_time
= time_span
.start_time
;
3893 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
3894 new_time_window
.time_width
) ;
3898 if(ltt_time_compare(new_time_window
.end_time
,
3899 time_span
.end_time
) > 0
3900 || ltt_time_compare(new_time_window
.end_time
,
3901 time_span
.start_time
) < 0)
3903 new_time_window
.start_time
=
3904 ltt_time_sub(time_span
.end_time
, new_time_window
.time_width
);
3906 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
3907 new_time_window
.time_width
) ;
3913 if(ltt_time_compare(new_time_window
.time_width
, ltt_time_zero
) == 0) {
3914 g_warning("Zoom more than 1 ns impossible");
3916 time_change_manager(tab
, new_time_window
);
3922 void current_time_change_manager (Tab
*tab
,
3923 LttTime new_current_time
)
3925 /* Only one source of time change */
3926 if(tab
->current_time_manager_lock
== TRUE
) return;
3928 tab
->current_time_manager_lock
= TRUE
;
3930 LttvTracesetContext
*tsc
= LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3931 TimeInterval time_span
= tsc
->time_span
;
3933 /* current seconds */
3934 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry5
),
3935 (double)time_span
.start_time
.tv_sec
,
3936 (double)time_span
.end_time
.tv_sec
);
3937 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry5
),
3938 (double)new_current_time
.tv_sec
);
3941 /* start nanoseconds */
3942 if(new_current_time
.tv_sec
== time_span
.start_time
.tv_sec
) {
3943 /* can be both beginning and end at the same time. */
3944 if(new_current_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3945 /* If we are at the end, max nsec to end.. */
3946 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry6
),
3947 (double)time_span
.start_time
.tv_nsec
,
3948 (double)time_span
.end_time
.tv_nsec
);
3950 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry6
),
3951 (double)time_span
.start_time
.tv_nsec
,
3952 (double)NANOSECONDS_PER_SECOND
-1);
3954 } else if(new_current_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3955 /* If we are at the end, max nsec to end.. */
3956 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry6
),
3958 (double)time_span
.end_time
.tv_nsec
);
3959 } else /* anywhere else */
3960 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry6
),
3962 (double)NANOSECONDS_PER_SECOND
-1);
3964 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry6
),
3965 (double)new_current_time
.tv_nsec
);
3967 set_current_time(tab
, &new_current_time
);
3969 tab
->current_time_manager_lock
= FALSE
;
3972 void current_position_change_manager(Tab
*tab
,
3973 LttvTracesetContextPosition
*pos
)
3975 LttvTracesetContext
*tsc
=
3976 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3979 retval
= lttv_process_traceset_seek_position(tsc
, pos
);
3980 g_assert_cmpint(retval
, ==, 0);
3981 LttTime new_time
= lttv_traceset_context_position_get_time(pos
);
3982 /* Put the context in a state coherent position */
3983 lttv_state_traceset_seek_time_closest((LttvTracesetState
*)tsc
, ltt_time_zero
);
3985 current_time_change_manager(tab
, new_time
);
3987 set_current_position(tab
, pos
);
3992 on_MEntry5_value_changed (GtkSpinButton
*spinbutton
,
3995 Tab
*tab
= (Tab
*)user_data
;
3996 LttvTracesetContext
* tsc
=
3997 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3998 TimeInterval time_span
= tsc
->time_span
;
3999 gint value
= gtk_spin_button_get_value_as_int(spinbutton
);
4000 LttTime new_current_time
= tab
->current_time
;
4001 new_current_time
.tv_sec
= value
;
4003 /* current nanoseconds */
4004 if(new_current_time
.tv_sec
== time_span
.start_time
.tv_sec
) {
4005 if(new_current_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
4006 if(new_current_time
.tv_nsec
> time_span
.end_time
.tv_nsec
)
4007 new_current_time
.tv_nsec
= time_span
.end_time
.tv_nsec
;
4008 if(new_current_time
.tv_nsec
< time_span
.start_time
.tv_nsec
)
4009 new_current_time
.tv_nsec
= time_span
.start_time
.tv_nsec
;
4011 if(new_current_time
.tv_nsec
< time_span
.start_time
.tv_nsec
)
4012 new_current_time
.tv_nsec
= time_span
.start_time
.tv_nsec
;
4015 else if(new_current_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
4016 if(new_current_time
.tv_nsec
> time_span
.end_time
.tv_nsec
)
4017 new_current_time
.tv_nsec
= time_span
.end_time
.tv_nsec
;
4020 current_time_change_manager(tab
, new_current_time
);
4024 on_MEntry6_value_changed (GtkSpinButton
*spinbutton
,
4027 Tab
*tab
= (Tab
*)user_data
;
4028 gint value
= gtk_spin_button_get_value_as_int(spinbutton
);
4029 LttTime new_current_time
= tab
->current_time
;
4030 new_current_time
.tv_nsec
= value
;
4032 current_time_change_manager(tab
, new_current_time
);
4036 void scroll_value_changed_cb(GtkWidget
*scrollbar
,
4039 Tab
*tab
= (Tab
*)user_data
;
4040 TimeWindow new_time_window
;
4042 GtkAdjustment
*adjust
= gtk_range_get_adjustment(GTK_RANGE(scrollbar
));
4043 gdouble value
= gtk_adjustment_get_value(adjust
);
4044 // gdouble upper, lower, ratio, page_size;
4046 LttvTracesetContext
* tsc
=
4047 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
4048 TimeInterval time_span
= tsc
->time_span
;
4050 time
= ltt_time_add(ltt_time_from_double(value
),
4051 time_span
.start_time
);
4053 new_time_window
.start_time
= time
;
4055 page_size
= adjust
->page_size
;
4057 new_time_window
.time_width
=
4058 ltt_time_from_double(page_size
);
4060 new_time_window
.time_width_double
=
4063 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
4064 new_time_window
.time_width
);
4067 time_change_manager(tab
, new_time_window
);
4069 //time_window = tab->time_window;
4071 lower
= adjust
->lower
;
4072 upper
= adjust
->upper
;
4073 ratio
= (value
- lower
) / (upper
- lower
);
4074 g_info("lower %lu, upper %lu, value %lu, ratio %lu", lower
, upper
, value
, ratio
);
4076 //time = ltt_time_sub(time_span->end_time, time_span->start_time);
4077 //time = ltt_time_mul(time, (float)ratio);
4078 //time = ltt_time_add(time_span->start_time, time);
4079 time
= ltt_time_add(ltt_time_from_double(value
),
4080 time_span
.start_time
);
4082 time_window
.start_time
= time
;
4084 page_size
= adjust
->page_size
;
4086 time_window
.time_width
=
4087 ltt_time_from_double(page_size
);
4088 //time = ltt_time_sub(time_span.end_time, time);
4089 //if(ltt_time_compare(time,time_window.time_width) < 0){
4090 // time_window.time_width = time;
4093 /* call viewer hooks for new time window */
4094 set_time_window(tab
, &time_window
);
4099 /* Display a dialogue showing all eventtypes and traces, let user to select the interested
4100 * eventtypes, tracefiles and traces (filter)
4103 /* Select a trace which will be removed from traceset
4106 char * get_remove_trace(MainWindow
*mw_data
,
4107 char ** all_trace_name
, int nb_trace
)
4109 return get_selection(mw_data
, all_trace_name
, nb_trace
,
4110 "Select a trace", "Trace pathname");
4114 /* Select a module which will be loaded
4117 char * get_load_module(MainWindow
*mw_data
,
4118 char ** load_module_name
, int nb_module
)
4120 return get_selection(mw_data
, load_module_name
, nb_module
,
4121 "Select a module to load", "Module name");
4127 /* Select a module which will be unloaded
4130 char * get_unload_module(MainWindow
*mw_data
,
4131 char ** loaded_module_name
, int nb_module
)
4133 return get_selection(mw_data
, loaded_module_name
, nb_module
,
4134 "Select a module to unload", "Module name");
4138 /* Display a dialogue which shows all selectable items, let user to
4139 * select one of them
4142 char * get_selection(MainWindow
*mw_data
,
4143 char ** loaded_module_name
, int nb_module
,
4144 char *title
, char * column_title
)
4146 GtkWidget
* dialogue
;
4147 GtkWidget
* scroll_win
;
4149 GtkListStore
* store
;
4150 GtkTreeViewColumn
* column
;
4151 GtkCellRenderer
* renderer
;
4152 GtkTreeSelection
* select
;
4155 char * unload_module_name
= NULL
;
4157 dialogue
= gtk_dialog_new_with_buttons(title
,
4160 GTK_STOCK_OK
,GTK_RESPONSE_ACCEPT
,
4161 GTK_STOCK_CANCEL
,GTK_RESPONSE_REJECT
,
4163 gtk_window_set_default_size((GtkWindow
*)dialogue
, 500, 200);
4164 gtk_window_set_transient_for(GTK_WINDOW(dialogue
),
4165 GTK_WINDOW(mw_data
->mwindow
));
4167 scroll_win
= gtk_scrolled_window_new (NULL
, NULL
);
4168 gtk_widget_show ( scroll_win
);
4169 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll_win
),
4170 GTK_POLICY_AUTOMATIC
, GTK_POLICY_AUTOMATIC
);
4172 store
= gtk_list_store_new (N_COLUMNS
,G_TYPE_STRING
);
4173 tree
= gtk_tree_view_new_with_model(GTK_TREE_MODEL (store
));
4174 gtk_widget_show ( tree
);
4175 g_object_unref (G_OBJECT (store
));
4177 renderer
= gtk_cell_renderer_text_new ();
4178 column
= gtk_tree_view_column_new_with_attributes (column_title
,
4180 "text", MODULE_COLUMN
,
4182 gtk_tree_view_column_set_alignment (column
, 0.5);
4183 gtk_tree_view_column_set_fixed_width (column
, 150);
4184 gtk_tree_view_append_column (GTK_TREE_VIEW (tree
), column
);
4186 select
= gtk_tree_view_get_selection (GTK_TREE_VIEW (tree
));
4187 gtk_tree_selection_set_mode (select
, GTK_SELECTION_SINGLE
);
4189 gtk_container_add (GTK_CONTAINER (scroll_win
), tree
);
4191 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialogue
)->vbox
), scroll_win
,TRUE
, TRUE
,0);
4193 for(i
=0;i
<nb_module
;i
++){
4194 gtk_list_store_append (store
, &iter
);
4195 gtk_list_store_set (store
, &iter
, MODULE_COLUMN
,loaded_module_name
[i
],-1);
4198 id
= gtk_dialog_run(GTK_DIALOG(dialogue
));
4199 GtkTreeModel
**store_model
= (GtkTreeModel
**)&store
;
4201 case GTK_RESPONSE_ACCEPT
:
4202 case GTK_RESPONSE_OK
:
4203 if (gtk_tree_selection_get_selected (select
, store_model
, &iter
)){
4204 gtk_tree_model_get ((GtkTreeModel
*)store
, &iter
, MODULE_COLUMN
, &unload_module_name
, -1);
4206 case GTK_RESPONSE_REJECT
:
4207 case GTK_RESPONSE_CANCEL
:
4209 gtk_widget_destroy(dialogue
);
4213 return unload_module_name
;
4217 /* Insert all menu entry and tool buttons into this main window
4222 void add_all_menu_toolbar_constructors(MainWindow
* mw
, gpointer user_data
)
4226 lttvwindow_viewer_constructor constructor
;
4227 LttvMenus
* global_menu
, * instance_menu
;
4228 LttvToolbars
* global_toolbar
, * instance_toolbar
;
4229 LttvMenuClosure
*menu_item
;
4230 LttvToolbarClosure
*toolbar_item
;
4231 LttvAttributeValue value
;
4232 LttvIAttribute
*global_attributes
= LTTV_IATTRIBUTE(lttv_global_attributes());
4233 LttvIAttribute
*attributes
= mw
->attributes
;
4234 GtkWidget
* tool_menu_title_menu
, *new_widget
, *pixmap
;
4237 retval
= lttv_iattribute_find_by_path(global_attributes
, "viewers/menu",
4238 LTTV_POINTER
, &value
);
4240 if(*(value
.v_pointer
) == NULL
)
4241 *(value
.v_pointer
) = lttv_menus_new();
4242 global_menu
= (LttvMenus
*)*(value
.v_pointer
);
4244 retval
= lttv_iattribute_find_by_path(attributes
, "viewers/menu",
4245 LTTV_POINTER
, &value
);
4247 if(*(value
.v_pointer
) == NULL
)
4248 *(value
.v_pointer
) = lttv_menus_new();
4249 instance_menu
= (LttvMenus
*)*(value
.v_pointer
);
4251 retval
= lttv_iattribute_find_by_path(global_attributes
, "viewers/toolbar",
4252 LTTV_POINTER
, &value
);
4254 if(*(value
.v_pointer
) == NULL
)
4255 *(value
.v_pointer
) = lttv_toolbars_new();
4256 global_toolbar
= (LttvToolbars
*)*(value
.v_pointer
);
4258 retval
= lttv_iattribute_find_by_path(attributes
, "viewers/toolbar",
4259 LTTV_POINTER
, &value
);
4261 if(*(value
.v_pointer
) == NULL
)
4262 *(value
.v_pointer
) = lttv_toolbars_new();
4263 instance_toolbar
= (LttvToolbars
*)*(value
.v_pointer
);
4265 /* Add missing menu entries to window instance */
4266 for(i
=0;i
<global_menu
->len
;i
++) {
4267 menu_item
= &g_array_index(global_menu
, LttvMenuClosure
, i
);
4269 //add menu_item to window instance;
4270 constructor
= menu_item
->con
;
4271 tool_menu_title_menu
= lookup_widget(mw
->mwindow
,"ToolMenuTitle_menu");
4273 gtk_menu_item_new_with_mnemonic (menu_item
->menu_text
);
4274 gtk_container_add (GTK_CONTAINER (tool_menu_title_menu
),
4276 g_signal_connect ((gpointer
) new_widget
, "activate",
4277 G_CALLBACK (insert_viewer_wrap
),
4279 gtk_widget_show (new_widget
);
4280 lttv_menus_add(instance_menu
, menu_item
->con
,
4281 menu_item
->menu_path
,
4282 menu_item
->menu_text
,
4287 /* Add missing toolbar entries to window instance */
4288 for(i
=0;i
<global_toolbar
->len
;i
++) {
4289 toolbar_item
= &g_array_index(global_toolbar
, LttvToolbarClosure
, i
);
4291 //add toolbar_item to window instance;
4292 constructor
= toolbar_item
->con
;
4293 tool_menu_title_menu
= lookup_widget(mw
->mwindow
,"MToolbar1");
4294 pixbuf
= gdk_pixbuf_new_from_xpm_data((const char**)toolbar_item
->pixmap
);
4295 pixmap
= gtk_image_new_from_pixbuf(pixbuf
);
4297 gtk_toolbar_append_element (GTK_TOOLBAR (tool_menu_title_menu
),
4298 GTK_TOOLBAR_CHILD_BUTTON
,
4301 toolbar_item
->tooltip
, NULL
,
4302 pixmap
, NULL
, NULL
);
4303 gtk_label_set_use_underline(
4304 GTK_LABEL (((GtkToolbarChild
*) (
4305 g_list_last (GTK_TOOLBAR
4306 (tool_menu_title_menu
)->children
)->data
))->label
),
4308 gtk_container_set_border_width (GTK_CONTAINER (new_widget
), 1);
4309 g_signal_connect ((gpointer
) new_widget
,
4311 G_CALLBACK (insert_viewer_wrap
),
4313 gtk_widget_show (new_widget
);
4315 lttv_toolbars_add(instance_toolbar
, toolbar_item
->con
,
4316 toolbar_item
->tooltip
,
4317 toolbar_item
->pixmap
,
4325 /* Create a main window
4328 MainWindow
*construct_main_window(MainWindow
* parent
)
4332 g_debug("construct_main_window()");
4333 GtkWidget
* new_window
; /* New generated main window */
4334 MainWindow
* new_m_window
;/* New main window structure */
4335 GtkNotebook
* notebook
;
4336 LttvIAttribute
*attributes
=
4337 LTTV_IATTRIBUTE(g_object_new(LTTV_ATTRIBUTE_TYPE
, NULL
));
4338 LttvAttributeValue value
;
4341 new_m_window
= g_new(MainWindow
, 1);
4343 // Add the object's information to the module's array
4344 g_main_window_list
= g_slist_append(g_main_window_list
, new_m_window
);
4346 new_window
= create_MWindow();
4347 gtk_widget_show (new_window
);
4349 new_m_window
->mwindow
= new_window
;
4350 new_m_window
->attributes
= attributes
;
4352 retval
= lttv_iattribute_find_by_path(attributes
, "viewers/menu",
4353 LTTV_POINTER
, &value
);
4355 *(value
.v_pointer
) = lttv_menus_new();
4357 retval
= lttv_iattribute_find_by_path(attributes
, "viewers/toolbar",
4358 LTTV_POINTER
, &value
);
4360 *(value
.v_pointer
) = lttv_toolbars_new();
4362 add_all_menu_toolbar_constructors(new_m_window
, NULL
);
4364 g_object_set_data_full(G_OBJECT(new_window
),
4366 (gpointer
)new_m_window
,
4367 (GDestroyNotify
)g_free
);
4368 //create a default tab
4369 notebook
= (GtkNotebook
*)lookup_widget(new_m_window
->mwindow
, "MNotebook");
4370 if(notebook
== NULL
){
4371 g_info("Notebook does not exist\n");
4372 /* FIXME : destroy partially created widgets */
4373 g_free(new_m_window
);
4376 //gtk_notebook_popup_enable (GTK_NOTEBOOK(notebook));
4377 //for now there is no name field in LttvTraceset structure
4378 //Use "Traceset" as the label for the default tab
4380 GtkWidget
* parent_notebook
= lookup_widget(parent
->mwindow
, "MNotebook");
4381 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(parent_notebook
),
4382 gtk_notebook_get_current_page(GTK_NOTEBOOK(parent_notebook
)));
4388 LttvPluginTab
*ptab
;
4389 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
4390 parent_tab
= ptab
->tab
;
4392 LttvPluginTab
*ptab
= g_object_new(LTTV_TYPE_PLUGIN_TAB
, NULL
);
4394 new_m_window
, parent_tab
, notebook
, "Traceset");
4395 ptab
->parent
.top_widget
= ptab
->tab
->top_widget
;
4396 g_object_set_data_full(
4397 G_OBJECT(ptab
->tab
->vbox
),
4400 (GDestroyNotify
)tab_destructor
);
4401 new_tab
= ptab
->tab
;
4403 LttvPluginTab
*ptab
= g_object_new(LTTV_TYPE_PLUGIN_TAB
, NULL
);
4404 init_tab(ptab
->tab
, new_m_window
, NULL
, notebook
, "Traceset");
4405 ptab
->parent
.top_widget
= ptab
->tab
->top_widget
;
4406 g_object_set_data_full(
4407 G_OBJECT(ptab
->tab
->vbox
),
4410 (GDestroyNotify
)tab_destructor
);
4411 new_tab
= ptab
->tab
;
4414 /* Insert default viewers */
4416 LttvAttributeType type
;
4417 LttvAttributeName name
;
4418 LttvAttributeValue value
;
4419 LttvAttribute
*attribute
;
4421 LttvIAttribute
*attributes_global
=
4422 LTTV_IATTRIBUTE(lttv_global_attributes());
4424 attribute
= LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
4425 LTTV_IATTRIBUTE(attributes_global
),
4426 LTTV_VIEWER_CONSTRUCTORS
));
4427 g_assert(attribute
);
4429 name
= g_quark_from_string("guievents");
4430 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
4432 if(type
== LTTV_POINTER
) {
4433 lttvwindow_viewer_constructor viewer_constructor
=
4434 (lttvwindow_viewer_constructor
)*value
.v_pointer
;
4435 insert_viewer(new_window
, viewer_constructor
);
4438 name
= g_quark_from_string("guicontrolflow");
4439 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
4441 if(type
== LTTV_POINTER
) {
4442 lttvwindow_viewer_constructor viewer_constructor
=
4443 (lttvwindow_viewer_constructor
)*value
.v_pointer
;
4444 insert_viewer(new_window
, viewer_constructor
);
4447 name
= g_quark_from_string("guistatistics");
4448 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
4450 if(type
== LTTV_POINTER
) {
4451 lttvwindow_viewer_constructor viewer_constructor
=
4452 (lttvwindow_viewer_constructor
)*value
.v_pointer
;
4453 insert_viewer(new_window
, viewer_constructor
);
4457 g_info("There are now : %d windows\n",g_slist_length(g_main_window_list
));
4459 return new_m_window
;
4463 /* Free the memory occupied by a tab structure
4467 void tab_destructor(LttvPluginTab
* ptab
)
4469 int i
, nb
, ref_count
;
4471 Tab
*tab
= ptab
->tab
;
4473 gtk_object_destroy(GTK_OBJECT(tab
->tooltips
));
4476 g_object_unref(tab
->attributes
);
4478 if(tab
->interrupted_state
)
4479 g_object_unref(tab
->interrupted_state
);
4482 if(tab
->traceset_info
->traceset_context
!= NULL
){
4483 //remove state update hooks
4484 lttv_state_remove_event_hooks(
4485 (LttvTracesetState
*)tab
->traceset_info
->
4487 lttv_context_fini(LTTV_TRACESET_CONTEXT(tab
->traceset_info
->
4489 g_object_unref(tab
->traceset_info
->traceset_context
);
4491 if(tab
->traceset_info
->traceset
!= NULL
) {
4492 nb
= lttv_traceset_number(tab
->traceset_info
->traceset
);
4493 for(i
= 0 ; i
< nb
; i
++) {
4494 trace
= lttv_traceset_get(tab
->traceset_info
->traceset
, i
);
4495 ref_count
= lttv_trace_get_ref_number(trace
);
4497 ltt_trace_close(lttv_trace(trace
));
4501 lttv_traceset_destroy(tab
->traceset_info
->traceset
);
4502 /* Remove the idle events requests processing function of the tab */
4503 g_idle_remove_by_data(tab
);
4505 g_slist_free(tab
->events_requests
);
4506 g_free(tab
->traceset_info
);
4508 g_object_unref(ptab
);
4512 /* Create a tab and insert it into the current main window
4515 void init_tab(Tab
*tab
, MainWindow
* mw
, Tab
*copy_tab
,
4516 GtkNotebook
* notebook
, char * label
)
4520 //LttvFilter *filter = NULL;
4522 //create a new tab data structure
4523 //tab = g_new(Tab,1);
4525 //construct and initialize the traceset_info
4526 tab
->traceset_info
= g_new(TracesetInfo
,1);
4529 tab
->traceset_info
->traceset
=
4530 lttv_traceset_copy(copy_tab
->traceset_info
->traceset
);
4532 /* Copy the previous tab's filter */
4533 /* We can clone the filter, as we copy the trace set also */
4534 /* The filter must always be in sync with the trace set */
4535 tab
->filter
= lttv_filter_clone(copy_tab
->filter
);
4537 tab
->traceset_info
->traceset
= lttv_traceset_new();
4541 lttv_attribute_write_xml(
4542 lttv_traceset_attribute(tab
->traceset_info
->traceset
),
4548 tab
->time_manager_lock
= FALSE
;
4549 tab
->current_time_manager_lock
= FALSE
;
4551 //FIXME copy not implemented in lower level
4552 tab
->traceset_info
->traceset_context
=
4553 g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
4554 g_assert(tab
->traceset_info
->traceset_context
!= NULL
);
4556 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
),
4557 tab
->traceset_info
->traceset
);
4558 //add state update hooks
4559 lttv_state_add_event_hooks(
4560 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
4562 //determine the current_time and time_window of the tab
4564 if(copy_tab
!= NULL
){
4565 tab
->time_window
= copy_tab
->time_window
;
4566 tab
->current_time
= copy_tab
->current_time
;
4568 tab
->time_window
.start_time
=
4569 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
4570 time_span
.start_time
;
4571 if(DEFAULT_TIME_WIDTH_S
<
4572 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
4573 time_span
.end_time
.tv_sec
)
4574 tmp_time
.tv_sec
= DEFAULT_TIME_WIDTH_S
;
4577 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
4578 time_span
.end_time
.tv_sec
;
4579 tmp_time
.tv_nsec
= 0;
4580 tab
->time_window
.time_width
= tmp_time
;
4581 tab
->current_time
.tv_sec
=
4582 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
4583 time_span
.start_time
.tv_sec
;
4584 tab
->current_time
.tv_nsec
=
4585 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
4586 time_span
.start_time
.tv_nsec
;
4589 tab
->attributes
= LTTV_IATTRIBUTE(g_object_new(LTTV_ATTRIBUTE_TYPE
, NULL
));
4590 tab
->interrupted_state
= g_object_new(LTTV_ATTRIBUTE_TYPE
, NULL
);
4592 tab
->vbox
= gtk_vbox_new(FALSE
, 2);
4593 tab
->top_widget
= tab
->vbox
;
4594 //g_object_set_data_full(G_OBJECT(tab->top_widget), "filter",
4595 // filter, (GDestroyNotify)lttv_filter_destroy);
4597 // g_signal_connect (G_OBJECT(tab->top_widget),
4599 // G_CALLBACK (on_top_notify),
4602 tab
->viewer_container
= gtk_vbox_new(TRUE
, 2);
4603 tab
->scrollbar
= gtk_hscrollbar_new(NULL
);
4604 //tab->multivpaned = gtk_multi_vpaned_new();
4606 gtk_box_pack_start(GTK_BOX(tab
->vbox
),
4607 tab
->viewer_container
,
4609 TRUE
, /* Give the extra space to the child */
4610 0); /* No padding */
4613 // tab->time_window = copy_tab->time_window;
4614 // tab->current_time = copy_tab->current_time;
4617 /* Create the timebar */
4619 tab
->MTimebar
= gtk_hbox_new(FALSE
, 2);
4620 gtk_widget_show(tab
->MTimebar
);
4621 tab
->tooltips
= gtk_tooltips_new();
4623 tab
->MEventBox1a
= gtk_event_box_new();
4624 gtk_widget_show(tab
->MEventBox1a
);
4625 gtk_tooltips_set_tip(tab
->tooltips
, tab
->MEventBox1a
,
4626 "Paste Start and End Times Here", "");
4627 tab
->MText1a
= gtk_label_new("Time Frame ");
4628 gtk_widget_show(tab
->MText1a
);
4629 gtk_container_add(GTK_CONTAINER(tab
->MEventBox1a
), tab
->MText1a
);
4630 tab
->MEventBox1b
= gtk_event_box_new();
4631 gtk_widget_show(tab
->MEventBox1b
);
4632 gtk_tooltips_set_tip(tab
->tooltips
, tab
->MEventBox1b
,
4633 "Paste Start Time Here", "");
4634 tab
->MText1b
= gtk_label_new("start: ");
4635 gtk_widget_show(tab
->MText1b
);
4636 gtk_container_add(GTK_CONTAINER(tab
->MEventBox1b
), tab
->MText1b
);
4637 tab
->MText2
= gtk_label_new("s");
4638 gtk_widget_show(tab
->MText2
);
4639 tab
->MText3a
= gtk_label_new("ns");
4640 gtk_widget_show(tab
->MText3a
);
4642 tab
->MEventBox3b
= gtk_event_box_new();
4643 gtk_widget_show(tab
->MEventBox3b
);
4644 gtk_tooltips_set_tip(tab
->tooltips
, tab
->MEventBox3b
,
4645 "Paste End Time Here", "");
4646 tab
->MText3b
= gtk_label_new("end:");
4647 gtk_widget_show(tab
->MText3b
);
4648 gtk_container_add(GTK_CONTAINER(tab
->MEventBox3b
), tab
->MText3b
);
4649 tab
->MText4
= gtk_label_new("s");
4650 gtk_widget_show(tab
->MText4
);
4651 tab
->MText5a
= gtk_label_new("ns");
4652 gtk_widget_show(tab
->MText5a
);
4654 tab
->MEventBox8
= gtk_event_box_new();
4655 gtk_widget_show(tab
->MEventBox8
);
4656 gtk_tooltips_set_tip(tab
->tooltips
, tab
->MEventBox8
,
4657 "Paste Time Interval here", "");
4658 tab
->MText8
= gtk_label_new("Time Interval:");
4659 gtk_widget_show(tab
->MText8
);
4660 gtk_container_add(GTK_CONTAINER(tab
->MEventBox8
), tab
->MText8
);
4661 tab
->MText9
= gtk_label_new("s");
4662 gtk_widget_show(tab
->MText9
);
4663 tab
->MText10
= gtk_label_new("ns");
4664 gtk_widget_show(tab
->MText10
);
4666 tab
->MEventBox5b
= gtk_event_box_new();
4667 gtk_widget_show(tab
->MEventBox5b
);
4668 gtk_tooltips_set_tip(tab
->tooltips
, tab
->MEventBox5b
,
4669 "Paste Current Time Here", "");
4670 tab
->MText5b
= gtk_label_new("Current Time:");
4671 gtk_widget_show(tab
->MText5b
);
4672 gtk_container_add(GTK_CONTAINER(tab
->MEventBox5b
), tab
->MText5b
);
4673 tab
->MText6
= gtk_label_new("s");
4674 gtk_widget_show(tab
->MText6
);
4675 tab
->MText7
= gtk_label_new("ns");
4676 gtk_widget_show(tab
->MText7
);
4678 tab
->MEntry1
= gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4679 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab
->MEntry1
),0);
4680 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab
->MEntry1
),TRUE
);
4681 gtk_widget_show(tab
->MEntry1
);
4682 tab
->MEntry2
= gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4683 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab
->MEntry2
),0);
4684 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab
->MEntry2
),TRUE
);
4685 gtk_widget_show(tab
->MEntry2
);
4686 tab
->MEntry3
= gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4687 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab
->MEntry3
),0);
4688 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab
->MEntry3
),TRUE
);
4689 gtk_widget_show(tab
->MEntry3
);
4690 tab
->MEntry4
= gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4691 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab
->MEntry4
),0);
4692 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab
->MEntry4
),TRUE
);
4693 gtk_widget_show(tab
->MEntry4
);
4694 tab
->MEntry5
= gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4695 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab
->MEntry5
),0);
4696 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab
->MEntry5
),TRUE
);
4697 gtk_widget_show(tab
->MEntry5
);
4698 tab
->MEntry6
= gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4699 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab
->MEntry6
),0);
4700 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab
->MEntry6
),TRUE
);
4701 gtk_widget_show(tab
->MEntry6
);
4702 tab
->MEntry7
= gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4703 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab
->MEntry7
),0);
4704 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab
->MEntry7
),TRUE
);
4705 gtk_widget_show(tab
->MEntry7
);
4706 tab
->MEntry8
= gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4707 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab
->MEntry8
),0);
4708 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab
->MEntry8
),TRUE
);
4709 gtk_widget_show(tab
->MEntry8
);
4711 GtkWidget
*temp_widget
;
4713 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEventBox1a
, FALSE
,
4715 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEventBox1b
, FALSE
,
4717 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEntry1
, FALSE
, FALSE
, 0);
4718 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MText2
, FALSE
, FALSE
, 0);
4719 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEntry2
, FALSE
, FALSE
, 0);
4720 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MText3a
, FALSE
, FALSE
, 0);
4721 temp_widget
= gtk_vseparator_new();
4722 gtk_widget_show(temp_widget
);
4723 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), temp_widget
, FALSE
, FALSE
, 0);
4724 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEventBox3b
, FALSE
,
4726 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEntry3
, FALSE
, FALSE
, 0);
4727 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MText4
, FALSE
, FALSE
, 0);
4728 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEntry4
, FALSE
, FALSE
, 0);
4729 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MText5a
, FALSE
, FALSE
, 0);
4730 temp_widget
= gtk_vseparator_new();
4731 gtk_widget_show(temp_widget
);
4732 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), temp_widget
, FALSE
, FALSE
, 0);
4733 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEventBox8
, FALSE
,
4735 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEntry7
, FALSE
, FALSE
, 0);
4736 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MText9
, FALSE
, FALSE
, 0);
4737 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEntry8
, FALSE
, FALSE
, 0);
4738 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MText10
, FALSE
, FALSE
, 0);
4740 temp_widget
= gtk_vseparator_new();
4741 gtk_widget_show(temp_widget
);
4742 gtk_box_pack_end (GTK_BOX (tab
->MTimebar
), tab
->MText7
, FALSE
, FALSE
, 0);
4743 gtk_box_pack_end (GTK_BOX (tab
->MTimebar
), tab
->MEntry6
, FALSE
, FALSE
, 0);
4744 gtk_box_pack_end (GTK_BOX (tab
->MTimebar
), tab
->MText6
, FALSE
, FALSE
, 0);
4745 gtk_box_pack_end (GTK_BOX (tab
->MTimebar
), tab
->MEntry5
, FALSE
, FALSE
, 0);
4746 gtk_box_pack_end (GTK_BOX (tab
->MTimebar
), tab
->MEventBox5b
, FALSE
,
4748 gtk_box_pack_end (GTK_BOX (tab
->MTimebar
), temp_widget
, FALSE
, FALSE
, 0);
4751 //GtkWidget *test = gtk_button_new_with_label("drop");
4752 //gtk_button_set_relief(GTK_BUTTON(test), GTK_RELIEF_NONE);
4753 //gtk_widget_show(test);
4754 //gtk_box_pack_end(GTK_BOX (tab->MTimebar), test, FALSE, FALSE, 0);
4755 //gtk_widget_add_events(tab->MText1, GDK_ALL_EVENTS_MASK);//GDK_BUTTON_PRESS_MASK);
4756 /*GtkWidget *event_box = gtk_event_box_new();
4757 gtk_widget_show(event_box);
4758 gtk_tooltips_set_tip(tooltips, event_box,
4759 "Paste Current Time Here", "");
4760 gtk_box_pack_end(GTK_BOX (tab->MTimebar), event_box, FALSE, FALSE, 0);
4761 GtkWidget *test = gtk_label_new("drop");
4762 gtk_container_add(GTK_CONTAINER(event_box), test);
4763 gtk_widget_show(test);
4764 g_signal_connect (G_OBJECT(event_box),
4765 "button-press-event",
4766 G_CALLBACK (on_MText1_paste),
4770 g_signal_connect (G_OBJECT(tab
->MEventBox1a
),
4771 "button-press-event",
4772 G_CALLBACK (on_MEventBox1a_paste
),
4775 g_signal_connect (G_OBJECT(tab
->MEventBox1b
),
4776 "button-press-event",
4777 G_CALLBACK (on_MEventBox1b_paste
),
4779 g_signal_connect (G_OBJECT(tab
->MEventBox3b
),
4780 "button-press-event",
4781 G_CALLBACK (on_MEventBox3b_paste
),
4783 g_signal_connect (G_OBJECT(tab
->MEventBox5b
),
4784 "button-press-event",
4785 G_CALLBACK (on_MEventBox5b_paste
),
4787 g_signal_connect (G_OBJECT(tab
->MEventBox8
),
4788 "button-press-event",
4789 G_CALLBACK (on_MEventBox8_paste
),
4793 gtk_box_pack_end(GTK_BOX(tab
->vbox
),
4795 FALSE
, /* Do not expand */
4796 FALSE
, /* Fill has no effect here (expand false) */
4797 0); /* No padding */
4799 gtk_box_pack_end(GTK_BOX(tab
->vbox
),
4801 FALSE
, /* Do not expand */
4802 FALSE
, /* Fill has no effect here (expand false) */
4803 0); /* No padding */
4805 g_object_set_data(G_OBJECT(tab
->viewer_container
), "focused_viewer", NULL
);
4811 // Display a label with a X
4812 GtkWidget *w_hbox = gtk_hbox_new(FALSE, 4);
4813 GtkWidget *w_label = gtk_label_new (label);
4814 GtkWidget *pixmap = create_pixmap(GTK_WIDGET(notebook), "close.png");
4815 GtkWidget *w_button = gtk_button_new ();
4816 gtk_container_add(GTK_CONTAINER(w_button), pixmap);
4817 //GtkWidget *w_button = gtk_button_new_with_label("x");
4819 gtk_button_set_relief(GTK_BUTTON(w_button), GTK_RELIEF_NONE);
4821 gtk_box_pack_start(GTK_BOX(w_hbox), w_label, TRUE, TRUE, 0);
4822 gtk_box_pack_end(GTK_BOX(w_hbox), w_button, FALSE,
4825 g_signal_connect_swapped (w_button, "clicked",
4826 G_CALLBACK (on_close_tab_X_clicked),
4829 gtk_widget_set_state(w_button, GTK_STATE_ACTIVE);
4831 gtk_widget_show (w_label);
4832 gtk_widget_show (pixmap);
4833 gtk_widget_show (w_button);
4834 gtk_widget_show (w_hbox);
4836 tab->label = w_hbox;
4840 tab
->label
= gtk_label_new (label
);
4842 gtk_widget_show(tab
->label
);
4843 gtk_widget_show(tab
->scrollbar
);
4844 gtk_widget_show(tab
->viewer_container
);
4845 gtk_widget_show(tab
->vbox
);
4846 //gtk_widget_show(tab->multivpaned);
4849 /* Start with empty events requests list */
4850 tab
->events_requests
= NULL
;
4851 tab
->events_request_pending
= FALSE
;
4852 tab
->stop_foreground
= FALSE
;
4856 g_signal_connect(G_OBJECT(tab
->scrollbar
), "value-changed",
4857 G_CALLBACK(scroll_value_changed_cb
), tab
);
4859 g_signal_connect ((gpointer
) tab
->MEntry1
, "value-changed",
4860 G_CALLBACK (on_MEntry1_value_changed
),
4862 g_signal_connect ((gpointer
) tab
->MEntry2
, "value-changed",
4863 G_CALLBACK (on_MEntry2_value_changed
),
4865 g_signal_connect ((gpointer
) tab
->MEntry3
, "value-changed",
4866 G_CALLBACK (on_MEntry3_value_changed
),
4868 g_signal_connect ((gpointer
) tab
->MEntry4
, "value-changed",
4869 G_CALLBACK (on_MEntry4_value_changed
),
4871 g_signal_connect ((gpointer
) tab
->MEntry5
, "value-changed",
4872 G_CALLBACK (on_MEntry5_value_changed
),
4874 g_signal_connect ((gpointer
) tab
->MEntry6
, "value-changed",
4875 G_CALLBACK (on_MEntry6_value_changed
),
4877 g_signal_connect ((gpointer
) tab
->MEntry7
, "value-changed",
4878 G_CALLBACK (on_MEntry7_value_changed
),
4880 g_signal_connect ((gpointer
) tab
->MEntry8
, "value-changed",
4881 G_CALLBACK (on_MEntry8_value_changed
),
4884 //g_signal_connect(G_OBJECT(tab->scrollbar), "changed",
4885 // G_CALLBACK(scroll_value_changed_cb), tab);
4888 //insert tab into notebook
4889 gtk_notebook_append_page(notebook
,
4892 list
= gtk_container_get_children(GTK_CONTAINER(notebook
));
4893 gtk_notebook_set_current_page(notebook
,g_list_length(list
)-1);
4894 // always show : not if(g_list_length(list)>1)
4895 gtk_notebook_set_show_tabs(notebook
, TRUE
);
4898 lttvwindow_report_time_window(tab
, copy_tab
->time_window
);
4899 lttvwindow_report_current_time(tab
, copy_tab
->current_time
);
4901 TimeWindow time_window
;
4903 time_window
.start_time
= ltt_time_zero
;
4904 time_window
.end_time
= ltt_time_add(time_window
.start_time
,
4905 lttvwindow_default_time_width
);
4906 time_window
.time_width
= lttvwindow_default_time_width
;
4907 time_window
.time_width_double
= ltt_time_to_double(time_window
.time_width
);
4909 lttvwindow_report_time_window(tab
, time_window
);
4910 lttvwindow_report_current_time(tab
, ltt_time_zero
);
4913 LttvTraceset
*traceset
= tab
->traceset_info
->traceset
;
4914 SetTraceset(tab
, traceset
);
4918 * execute_events_requests
4920 * Idle function that executes the pending requests for a tab.
4922 * @return return value : TRUE : keep the idle function, FALSE : remove it.
4924 gboolean
execute_events_requests(Tab
*tab
)
4926 return ( lttvwindow_process_pending_requests(tab
) );
4930 __EXPORT
void create_main_window_with_trace_list(GSList
*traces
)
4932 GSList
*iter
= NULL
;
4935 MainWindow
*mw
= construct_main_window(NULL
);
4936 GtkWidget
*widget
= mw
->mwindow
;
4938 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
4939 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
4940 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
4941 LttvPluginTab
*ptab
;
4945 ptab
= create_new_tab(widget
, NULL
);
4948 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
4952 for(iter
=traces
; iter
!=NULL
; iter
=g_slist_next(iter
)) {
4953 gchar
*path
= (gchar
*)iter
->data
;
4955 gchar abs_path
[PATH_MAX
];
4959 get_absolute_pathname(path
, abs_path
);
4960 trace_v
= lttvwindowtraces_get_trace_by_name(abs_path
);
4961 if(trace_v
== NULL
) {
4962 trace
= ltt_trace_open(abs_path
);
4964 g_warning("cannot open trace %s", abs_path
);
4966 GtkWidget
*dialogue
=
4967 gtk_message_dialog_new(
4968 GTK_WINDOW(gtk_widget_get_toplevel(widget
)),
4969 GTK_DIALOG_MODAL
|GTK_DIALOG_DESTROY_WITH_PARENT
,
4972 "Cannot open trace : maybe you should enter in the directory "
4974 gtk_dialog_run(GTK_DIALOG(dialogue
));
4975 gtk_widget_destroy(dialogue
);
4977 trace_v
= lttv_trace_new(trace
);
4978 lttvwindowtraces_add_trace(trace_v
);
4979 lttvwindow_add_trace(tab
, trace_v
);
4982 lttvwindow_add_trace(tab
, trace_v
);
4986 LttvTraceset
*traceset
;
4988 traceset
= tab
->traceset_info
->traceset
;
4989 SetTraceset(tab
, traceset
);