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>
35 #include <ltt/facility.h>
37 #include <ltt/event.h>
38 #include <lttv/lttv.h>
39 #include <lttv/module.h>
40 #include <lttv/iattribute.h>
41 #include <lttv/stats.h>
42 #include <lttv/filter.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 MainWindow
* mw_data
= get_window_data_struct(widget
);
422 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
424 TimeInterval
* time_interval
;
425 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
426 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
431 ptab
= create_new_tab(widget
, NULL
);
433 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
437 viewer_container
= tab
->viewer_container
;
439 viewer
= (GtkWidget
*)constructor(ptab
);
442 //gtk_multivpaned_widget_add(GTK_MULTIVPANED(multivpaned), viewer);
444 gtk_box_pack_end(GTK_BOX(viewer_container
),
450 /* We want to connect the viewer_grab_focus to EVERY
451 * child of this widget. The little trick is to get each child
452 * of each GTK_CONTAINER, even subchildren.
454 connect_focus_recursive(viewer
, viewer
);
459 * Function to set/update traceset for the viewers
460 * @param tab viewer's tab
461 * @param traceset traceset of the main window.
463 * 0 : traceset updated
464 * 1 : no traceset hooks to update; not an error.
467 int SetTraceset(Tab
* tab
, LttvTraceset
*traceset
)
469 LttvTracesetContext
*tsc
=
470 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
471 TimeInterval time_span
= tsc
->time_span
;
472 TimeWindow new_time_window
= tab
->time_window
;
473 LttTime new_current_time
= tab
->current_time
;
475 /* Set the tab's time window and current time if
477 if(ltt_time_compare(tab
->time_window
.start_time
, time_span
.start_time
) < 0
478 || ltt_time_compare(tab
->time_window
.end_time
,
479 time_span
.end_time
) > 0) {
480 new_time_window
.start_time
= time_span
.start_time
;
482 new_current_time
= time_span
.start_time
;
486 if(ltt_time_compare(lttvwindow_default_time_width
,
487 ltt_time_sub(time_span
.end_time
, time_span
.start_time
)) < 0
489 ltt_time_compare(time_span
.end_time
, time_span
.start_time
) == 0)
490 tmp_time
= lttvwindow_default_time_width
;
492 tmp_time
= time_span
.end_time
;
494 new_time_window
.time_width
= tmp_time
;
495 new_time_window
.time_width_double
= ltt_time_to_double(tmp_time
);
496 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
497 new_time_window
.time_width
) ;
504 GtkAdjustment
*adjustment
= gtk_range_get_adjustment(GTK_RANGE(tab
->scrollbar
));
505 LttTime upper
= ltt_time_sub(time_span
.end_time
, time_span
.start_time
);
507 g_object_set(G_OBJECT(adjustment
),
511 ltt_time_to_double(upper
)
512 * NANOSECONDS_PER_SECOND
, /* upper */
514 ltt_time_to_double(tab
->time_window
.time_width
)
515 / SCROLL_STEP_PER_PAGE
516 * NANOSECONDS_PER_SECOND
, /* step increment */
518 ltt_time_to_double(tab
->time_window
.time_width
)
519 * NANOSECONDS_PER_SECOND
, /* page increment */
521 ltt_time_to_double(tab
->time_window
.time_width
)
522 * NANOSECONDS_PER_SECOND
, /* page size */
524 gtk_adjustment_changed(adjustment
);
526 g_object_set(G_OBJECT(adjustment
),
529 ltt_time_sub(tab
->time_window
.start_time
, time_span
.start_time
))
530 * NANOSECONDS_PER_SECOND
, /* value */
532 gtk_adjustment_value_changed(adjustment
);
534 /* set the time bar. The value callbacks will change their nsec themself */
536 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry1
),
537 (double)time_span
.start_time
.tv_sec
,
538 (double)time_span
.end_time
.tv_sec
);
541 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry3
),
542 (double)time_span
.start_time
.tv_sec
,
543 (double)time_span
.end_time
.tv_sec
);
545 /* current seconds */
546 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry5
),
547 (double)time_span
.start_time
.tv_sec
,
548 (double)time_span
.end_time
.tv_sec
);
551 /* Finally, call the update hooks of the viewers */
553 LttvAttributeValue value
;
557 g_assert( lttv_iattribute_find_by_path(tab
->attributes
,
558 "hooks/updatetraceset", LTTV_POINTER
, &value
));
560 tmp
= (LttvHooks
*)*(value
.v_pointer
);
561 if(tmp
== NULL
) retval
= 1;
562 else lttv_hooks_call(tmp
,traceset
);
564 time_change_manager(tab
, new_time_window
);
565 current_time_change_manager(tab
, new_current_time
);
571 * Function to set/update filter for the viewers
572 * @param tab viewer's tab
573 * @param filter filter of the main window.
576 * 0 : filters updated
577 * 1 : no filter hooks to update; not an error.
580 int SetFilter(Tab
* tab
, gpointer filter
)
583 LttvAttributeValue value
;
585 g_assert(lttv_iattribute_find_by_path(tab
->attributes
,
586 "hooks/updatefilter", LTTV_POINTER
, &value
));
588 tmp
= (LttvHooks
*)*(value
.v_pointer
);
590 if(tmp
== NULL
) return 1;
591 lttv_hooks_call(tmp
,filter
);
599 * Function to redraw each viewer belonging to the current tab
600 * @param tab viewer's tab
603 void update_traceset(Tab
*tab
)
605 LttvAttributeValue value
;
607 g_assert(lttv_iattribute_find_by_path(tab
->attributes
,
608 "hooks/updatetraceset", LTTV_POINTER
, &value
));
609 tmp
= (LttvHooks
*)*(value
.v_pointer
);
610 if(tmp
== NULL
) return;
611 lttv_hooks_call(tmp
, NULL
);
615 /* get_label function is used to get user input, it displays an input
616 * box, which allows user to input a string
619 void get_label_string (GtkWidget
* text
, gchar
* label
)
621 GtkEntry
* entry
= (GtkEntry
*)text
;
622 if(strlen(gtk_entry_get_text(entry
))!=0)
623 strcpy(label
,gtk_entry_get_text(entry
));
626 gboolean
get_label(MainWindow
* mw
, gchar
* str
, gchar
* dialogue_title
, gchar
* label_str
)
628 GtkWidget
* dialogue
;
633 dialogue
= gtk_dialog_new_with_buttons(dialogue_title
,NULL
,
635 GTK_STOCK_OK
,GTK_RESPONSE_ACCEPT
,
636 GTK_STOCK_CANCEL
,GTK_RESPONSE_REJECT
,
639 label
= gtk_label_new(label_str
);
640 gtk_widget_show(label
);
642 text
= gtk_entry_new();
643 gtk_widget_show(text
);
645 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialogue
)->vbox
), label
,TRUE
, TRUE
,0);
646 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialogue
)->vbox
), text
,FALSE
, FALSE
,0);
648 id
= gtk_dialog_run(GTK_DIALOG(dialogue
));
650 case GTK_RESPONSE_ACCEPT
:
651 get_label_string(text
,str
);
652 gtk_widget_destroy(dialogue
);
654 case GTK_RESPONSE_REJECT
:
656 gtk_widget_destroy(dialogue
);
663 /* get_window_data_struct function is actually a lookup function,
664 * given a widget which is in the tree of the main window, it will
665 * return the MainWindow data structure associated with main window
668 MainWindow
* get_window_data_struct(GtkWidget
* widget
)
671 MainWindow
* mw_data
;
673 mw
= lookup_widget(widget
, "MWindow");
675 g_info("Main window does not exist\n");
679 mw_data
= (MainWindow
*) g_object_get_data(G_OBJECT(mw
),"main_window_data");
681 g_warning("Main window data does not exist\n");
688 /* create_new_window function, just constructs a new main window
691 void create_new_window(GtkWidget
* widget
, gpointer user_data
, gboolean clone
)
693 MainWindow
* parent
= get_window_data_struct(widget
);
696 g_info("Clone : use the same traceset\n");
697 construct_main_window(parent
);
699 g_info("Empty : traceset is set to NULL\n");
700 construct_main_window(NULL
);
704 /* Get the currently focused viewer.
705 * If no viewer is focused, use the first one.
707 * If no viewer available, return NULL.
709 GtkWidget
*viewer_container_focus(GtkWidget
*container
)
713 widget
= (GtkWidget
*)g_object_get_data(G_OBJECT(container
),
717 g_debug("no widget focused");
718 GList
*children
= gtk_container_get_children(GTK_CONTAINER(container
));
721 widget
= GTK_WIDGET(children
->data
);
722 g_object_set_data(G_OBJECT(container
),
732 gint
viewer_container_position(GtkWidget
*container
, GtkWidget
*child
)
735 if(child
== NULL
) return -1;
739 memset(&value
, 0, sizeof(GValue
));
740 g_value_init(&value
, G_TYPE_INT
);
741 gtk_container_child_get_property(GTK_CONTAINER(container
),
745 pos
= g_value_get_int(&value
);
751 /* move_*_viewer functions move the selected view up/down in
755 void move_down_viewer(GtkWidget
* widget
, gpointer user_data
)
757 MainWindow
* mw
= get_window_data_struct(widget
);
758 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
760 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
761 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
768 ptab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
772 //gtk_multivpaned_widget_move_up(GTK_MULTIVPANED(tab->multivpaned));
774 /* change the position in the vbox */
775 GtkWidget
*focus_widget
;
777 focus_widget
= viewer_container_focus(tab
->viewer_container
);
778 position
= viewer_container_position(tab
->viewer_container
, focus_widget
);
781 /* can move up one position */
782 gtk_box_reorder_child(GTK_BOX(tab
->viewer_container
),
789 void move_up_viewer(GtkWidget
* widget
, gpointer user_data
)
791 MainWindow
* mw
= get_window_data_struct(widget
);
792 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
794 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
795 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
802 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
806 //gtk_multivpaned_widget_move_down(GTK_MULTIVPANED(tab->multivpaned));
807 /* change the position in the vbox */
808 GtkWidget
*focus_widget
;
810 focus_widget
= viewer_container_focus(tab
->viewer_container
);
811 position
= viewer_container_position(tab
->viewer_container
, focus_widget
);
815 g_list_length(gtk_container_get_children(
816 GTK_CONTAINER(tab
->viewer_container
)))-1
818 /* can move down one position */
819 gtk_box_reorder_child(GTK_BOX(tab
->viewer_container
),
827 /* delete_viewer deletes the selected viewer in the current tab
830 void delete_viewer(GtkWidget
* widget
, gpointer user_data
)
832 MainWindow
* mw
= get_window_data_struct(widget
);
833 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
835 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
836 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
843 ptab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
847 //gtk_multivpaned_widget_delete(GTK_MULTIVPANED(tab->multivpaned));
849 GtkWidget
*focus_widget
= viewer_container_focus(tab
->viewer_container
);
851 if(focus_widget
!= NULL
)
852 gtk_widget_destroy(focus_widget
);
854 g_object_set_data(G_OBJECT(tab
->viewer_container
), "focused_viewer", NULL
);
858 /* open_traceset will open a traceset saved in a file
859 * Right now, it is not finished yet, (not working)
863 void open_traceset(GtkWidget
* widget
, gpointer user_data
)
867 LttvTraceset
* traceset
;
868 MainWindow
* mw_data
= get_window_data_struct(widget
);
869 GtkFileSelection
* file_selector
=
870 (GtkFileSelection
*)gtk_file_selection_new("Select a traceset");
872 gtk_file_selection_hide_fileop_buttons(file_selector
);
874 gtk_window_set_transient_for(GTK_WINDOW(file_selector
),
875 GTK_WINDOW(mw_data
->mwindow
));
877 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
879 case GTK_RESPONSE_ACCEPT
:
880 case GTK_RESPONSE_OK
:
881 dir
= gtk_file_selection_get_selections (file_selector
);
882 traceset
= lttv_traceset_load(dir
[0]);
883 g_info("Open a trace set %s\n", dir
[0]);
886 case GTK_RESPONSE_REJECT
:
887 case GTK_RESPONSE_CANCEL
:
889 gtk_widget_destroy((GtkWidget
*)file_selector
);
895 /* lttvwindow_process_pending_requests
897 * This internal function gets called by g_idle, taking care of the pending
898 * requests. It is responsible for concatenation of time intervals and position
899 * requests. It does it with the following algorithm organizing process traceset
900 * calls. Here is the detailed description of the way it works :
902 * - Events Requests Servicing Algorithm
904 * Data structures necessary :
906 * List of requests added to context : list_in
907 * List of requests not added to context : list_out
912 * list_out : many events requests
914 * FIXME : insert rest of algorithm here
918 #define list_out tab->events_requests
920 gboolean
lttvwindow_process_pending_requests(Tab
*tab
)
923 LttvTracesetContext
*tsc
;
924 LttvTracefileContext
*tfc
;
925 GSList
*list_in
= NULL
;
929 LttvTracesetContextPosition
*end_position
;
932 g_critical("Foreground processing : tab does not exist. Processing removed.");
936 /* There is no events requests pending : we should never have been called! */
937 g_assert(g_slist_length(list_out
) != 0);
939 tsc
= LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
941 //set the cursor to be X shape, indicating that the computer is busy in doing its job
943 new = gdk_cursor_new(GDK_X_CURSOR
);
944 widget
= lookup_widget(tab
->mw
->mwindow
, "MToolbar1");
945 win
= gtk_widget_get_parent_window(widget
);
946 gdk_window_set_cursor(win
, new);
947 gdk_cursor_unref(new);
948 gdk_window_stick(win
);
949 gdk_window_unstick(win
);
952 g_debug("SIZE events req len : %d", g_slist_length(list_out
));
954 /* Preliminary check for no trace in traceset */
955 /* Unregister the routine if empty, empty list_out too */
956 if(lttv_traceset_number(tsc
->ts
) == 0) {
958 /* - For each req in list_out */
959 GSList
*iter
= list_out
;
961 while(iter
!= NULL
) {
963 gboolean remove
= FALSE
;
964 gboolean free_data
= FALSE
;
965 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
967 /* - Call end request for req */
968 if(events_request
->servicing
== TRUE
)
969 lttv_hooks_call(events_request
->after_request
, (gpointer
)tsc
);
971 /* - remove req from list_out */
972 /* Destroy the request */
979 GSList
*remove_iter
= iter
;
981 iter
= g_slist_next(iter
);
982 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
983 list_out
= g_slist_remove_link(list_out
, remove_iter
);
984 } else { // not remove
985 iter
= g_slist_next(iter
);
990 /* 0.1 Lock Traces */
995 iter_trace
<lttv_traceset_number(tsc
->ts
);
997 LttvTrace
*trace_v
= lttv_traceset_get(tsc
->ts
, iter_trace
);
999 if(lttvwindowtraces_lock(trace_v
) != 0) {
1000 g_critical("Foreground processing : Unable to get trace lock");
1001 return TRUE
; /* Cannot get lock, try later */
1006 /* 0.2 Seek tracefiles positions to context position */
1007 //g_assert(lttv_process_traceset_seek_position(tsc, sync_position) == 0);
1008 lttv_process_traceset_synchronize_tracefiles(tsc
);
1011 /* Events processing algorithm implementation */
1012 /* Warning : the gtk_events_pending takes a LOT of cpu time. So what we do
1013 * instead is to leave the control to GTK and take it back.
1015 /* A. Servicing loop */
1016 //while( (g_slist_length(list_in) != 0 || g_slist_length(list_out) != 0)) {
1017 if((g_slist_length(list_in
) != 0 || g_slist_length(list_out
) != 0)) {
1019 /* 1. If list_in is empty (need a seek) */
1020 if( g_slist_length(list_in
) == 0 ) {
1022 /* list in is empty, need a seek */
1024 /* 1.1 Add requests to list_in */
1025 GSList
*ltime
= NULL
;
1026 GSList
*lpos
= NULL
;
1027 GSList
*iter
= NULL
;
1029 /* 1.1.1 Find all time requests with the lowest start time in list_out
1032 if(g_slist_length(list_out
) > 0)
1033 ltime
= g_slist_append(ltime
, g_slist_nth_data(list_out
, 0));
1034 for(iter
=g_slist_nth(list_out
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
1035 /* Find all time requests with the lowest start time in list_out */
1036 EventsRequest
*event_request_ltime
= (EventsRequest
*)g_slist_nth_data(ltime
, 0);
1037 EventsRequest
*event_request_list_out
= (EventsRequest
*)iter
->data
;
1040 comp
= ltt_time_compare(event_request_ltime
->start_time
,
1041 event_request_list_out
->start_time
);
1043 ltime
= g_slist_append(ltime
, event_request_list_out
);
1045 /* Remove all elements from ltime, and add current */
1046 while(ltime
!= NULL
)
1047 ltime
= g_slist_delete_link(ltime
, g_slist_nth(ltime
, 0));
1048 ltime
= g_slist_append(ltime
, event_request_list_out
);
1052 /* 1.1.2 Find all position requests with the lowest position in list_out
1055 if(g_slist_length(list_out
) > 0)
1056 lpos
= g_slist_append(lpos
, g_slist_nth_data(list_out
, 0));
1057 for(iter
=g_slist_nth(list_out
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
1058 /* Find all position requests with the lowest position in list_out */
1059 EventsRequest
*event_request_lpos
= (EventsRequest
*)g_slist_nth_data(lpos
, 0);
1060 EventsRequest
*event_request_list_out
= (EventsRequest
*)iter
->data
;
1063 if(event_request_lpos
->start_position
!= NULL
1064 && event_request_list_out
->start_position
!= NULL
)
1066 comp
= lttv_traceset_context_pos_pos_compare
1067 (event_request_lpos
->start_position
,
1068 event_request_list_out
->start_position
);
1073 lpos
= g_slist_append(lpos
, event_request_list_out
);
1075 /* Remove all elements from lpos, and add current */
1077 lpos
= g_slist_delete_link(lpos
, g_slist_nth(lpos
, 0));
1078 lpos
= g_slist_append(lpos
, event_request_list_out
);
1083 EventsRequest
*event_request_lpos
= (EventsRequest
*)g_slist_nth_data(lpos
, 0);
1084 EventsRequest
*event_request_ltime
= (EventsRequest
*)g_slist_nth_data(ltime
, 0);
1085 LttTime lpos_start_time
;
1087 if(event_request_lpos
!= NULL
1088 && event_request_lpos
->start_position
!= NULL
) {
1089 lpos_start_time
= lttv_traceset_context_position_get_time(
1090 event_request_lpos
->start_position
);
1093 /* 1.1.3 If lpos.start time < ltime */
1094 if(event_request_lpos
!= NULL
1095 && event_request_lpos
->start_position
!= NULL
1096 && ltt_time_compare(lpos_start_time
,
1097 event_request_ltime
->start_time
)<0) {
1098 /* Add lpos to list_in, remove them from list_out */
1099 for(iter
=lpos
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
1100 /* Add to list_in */
1101 EventsRequest
*event_request_lpos
=
1102 (EventsRequest
*)iter
->data
;
1104 list_in
= g_slist_append(list_in
, event_request_lpos
);
1105 /* Remove from list_out */
1106 list_out
= g_slist_remove(list_out
, event_request_lpos
);
1109 /* 1.1.4 (lpos.start time >= ltime) */
1110 /* Add ltime to list_in, remove them from list_out */
1112 for(iter
=ltime
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
1113 /* Add to list_in */
1114 EventsRequest
*event_request_ltime
=
1115 (EventsRequest
*)iter
->data
;
1117 list_in
= g_slist_append(list_in
, event_request_ltime
);
1118 /* Remove from list_out */
1119 list_out
= g_slist_remove(list_out
, event_request_ltime
);
1124 g_slist_free(ltime
);
1129 tfc
= lttv_traceset_context_get_current_tfc(tsc
);
1130 g_assert(g_slist_length(list_in
)>0);
1131 EventsRequest
*events_request
= g_slist_nth_data(list_in
, 0);
1134 /* 1.2.1 If first request in list_in is a time request */
1135 if(events_request
->start_position
== NULL
) {
1136 /* - If first req in list_in start time != current time */
1137 if(tfc
== NULL
|| ltt_time_compare(events_request
->start_time
,
1138 tfc
->timestamp
) != 0)
1139 /* - Seek to that time */
1140 g_debug("SEEK TIME : %lu, %lu", events_request
->start_time
.tv_sec
,
1141 events_request
->start_time
.tv_nsec
);
1142 //lttv_process_traceset_seek_time(tsc, events_request->start_time);
1143 lttv_state_traceset_seek_time_closest(LTTV_TRACESET_STATE(tsc
),
1144 events_request
->start_time
);
1146 /* Process the traceset with only state hooks */
1148 lttv_process_traceset_middle(tsc
,
1149 events_request
->start_time
,
1152 g_assert(seek_count
< LTTV_STATE_SAVE_INTERVAL
);
1158 LttvTracefileContext
*tfc
=
1159 lttv_traceset_context_get_current_tfc(tsc
);
1160 /* Else, the first request in list_in is a position request */
1161 /* If first req in list_in pos != current pos */
1162 g_assert(events_request
->start_position
!= NULL
);
1163 g_debug("SEEK POS time : %lu, %lu",
1164 lttv_traceset_context_position_get_time(
1165 events_request
->start_position
).tv_sec
,
1166 lttv_traceset_context_position_get_time(
1167 events_request
->start_position
).tv_nsec
);
1170 g_debug("SEEK POS context time : %lu, %lu",
1171 tfc
->timestamp
.tv_sec
,
1172 tfc
->timestamp
.tv_nsec
);
1174 g_debug("SEEK POS context time : %lu, %lu",
1175 ltt_time_infinite
.tv_sec
,
1176 ltt_time_infinite
.tv_nsec
);
1178 g_assert(events_request
->start_position
!= NULL
);
1179 if(lttv_traceset_context_ctx_pos_compare(tsc
,
1180 events_request
->start_position
) != 0) {
1181 /* 1.2.2.1 Seek to that position */
1182 g_debug("SEEK POSITION");
1183 //lttv_process_traceset_seek_position(tsc, events_request->start_position);
1184 pos_time
= lttv_traceset_context_position_get_time(
1185 events_request
->start_position
);
1187 lttv_state_traceset_seek_time_closest(LTTV_TRACESET_STATE(tsc
),
1190 /* Process the traceset with only state hooks */
1192 lttv_process_traceset_middle(tsc
,
1195 events_request
->start_position
);
1196 g_assert(lttv_traceset_context_ctx_pos_compare(tsc
,
1197 events_request
->start_position
) == 0);
1204 /* 1.3 Add hooks and call before request for all list_in members */
1206 GSList
*iter
= NULL
;
1208 for(iter
=list_in
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
1209 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1210 /* 1.3.1 If !servicing */
1211 if(events_request
->servicing
== FALSE
) {
1212 /* - begin request hooks called
1213 * - servicing = TRUE
1215 lttv_hooks_call(events_request
->before_request
, (gpointer
)tsc
);
1216 events_request
->servicing
= TRUE
;
1218 /* 1.3.2 call before chunk
1219 * 1.3.3 events hooks added
1221 if(events_request
->trace
== -1)
1222 lttv_process_traceset_begin(tsc
,
1223 events_request
->before_chunk_traceset
,
1224 events_request
->before_chunk_trace
,
1225 events_request
->before_chunk_tracefile
,
1226 events_request
->event
,
1227 events_request
->event_by_id
);
1229 guint nb_trace
= lttv_traceset_number(tsc
->ts
);
1230 g_assert((guint
)events_request
->trace
< nb_trace
&&
1231 events_request
->trace
> -1);
1232 LttvTraceContext
*tc
= tsc
->traces
[events_request
->trace
];
1234 lttv_hooks_call(events_request
->before_chunk_traceset
, tsc
);
1236 lttv_trace_context_add_hooks(tc
,
1237 events_request
->before_chunk_trace
,
1238 events_request
->before_chunk_tracefile
,
1239 events_request
->event
,
1240 events_request
->event_by_id
);
1245 /* 2. Else, list_in is not empty, we continue a read */
1248 /* 2.0 For each req of list_in */
1249 GSList
*iter
= list_in
;
1251 while(iter
!= NULL
) {
1253 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1255 /* - Call before chunk
1256 * - events hooks added
1258 if(events_request
->trace
== -1)
1259 lttv_process_traceset_begin(tsc
,
1260 events_request
->before_chunk_traceset
,
1261 events_request
->before_chunk_trace
,
1262 events_request
->before_chunk_tracefile
,
1263 events_request
->event
,
1264 events_request
->event_by_id
);
1266 guint nb_trace
= lttv_traceset_number(tsc
->ts
);
1267 g_assert((guint
)events_request
->trace
< nb_trace
&&
1268 events_request
->trace
> -1);
1269 LttvTraceContext
*tc
= tsc
->traces
[events_request
->trace
];
1271 lttv_hooks_call(events_request
->before_chunk_traceset
, tsc
);
1273 lttv_trace_context_add_hooks(tc
,
1274 events_request
->before_chunk_trace
,
1275 events_request
->before_chunk_tracefile
,
1276 events_request
->event
,
1277 events_request
->event_by_id
);
1280 iter
= g_slist_next(iter
);
1285 tfc
= lttv_traceset_context_get_current_tfc(tsc
);
1287 /* 2.1 For each req of list_out */
1288 GSList
*iter
= list_out
;
1290 while(iter
!= NULL
) {
1292 gboolean remove
= FALSE
;
1293 gboolean free_data
= FALSE
;
1294 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1296 /* if req.start time == current context time
1297 * or req.start position == current position*/
1298 if( ltt_time_compare(events_request
->start_time
,
1299 tfc
->timestamp
) == 0
1301 (events_request
->start_position
!= NULL
1303 lttv_traceset_context_ctx_pos_compare(tsc
,
1304 events_request
->start_position
) == 0)
1306 /* - Add to list_in, remove from list_out */
1307 list_in
= g_slist_append(list_in
, events_request
);
1311 /* - If !servicing */
1312 if(events_request
->servicing
== FALSE
) {
1313 /* - begin request hooks called
1314 * - servicing = TRUE
1316 lttv_hooks_call(events_request
->before_request
, (gpointer
)tsc
);
1317 events_request
->servicing
= TRUE
;
1319 /* call before chunk
1320 * events hooks added
1322 if(events_request
->trace
== -1)
1323 lttv_process_traceset_begin(tsc
,
1324 events_request
->before_chunk_traceset
,
1325 events_request
->before_chunk_trace
,
1326 events_request
->before_chunk_tracefile
,
1327 events_request
->event
,
1328 events_request
->event_by_id
);
1330 guint nb_trace
= lttv_traceset_number(tsc
->ts
);
1331 g_assert((guint
)events_request
->trace
< nb_trace
&&
1332 events_request
->trace
> -1);
1333 LttvTraceContext
*tc
= tsc
->traces
[events_request
->trace
];
1335 lttv_hooks_call(events_request
->before_chunk_traceset
, tsc
);
1337 lttv_trace_context_add_hooks(tc
,
1338 events_request
->before_chunk_trace
,
1339 events_request
->before_chunk_tracefile
,
1340 events_request
->event
,
1341 events_request
->event_by_id
);
1350 GSList
*remove_iter
= iter
;
1352 iter
= g_slist_next(iter
);
1353 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
1354 list_out
= g_slist_remove_link(list_out
, remove_iter
);
1355 } else { // not remove
1356 iter
= g_slist_next(iter
);
1362 /* 3. Find end criterions */
1367 /* 3.1.1 Find lowest end time in list_in */
1368 g_assert(g_slist_length(list_in
)>0);
1369 end_time
= ((EventsRequest
*)g_slist_nth_data(list_in
,0))->end_time
;
1371 for(iter
=g_slist_nth(list_in
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
1372 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1374 if(ltt_time_compare(events_request
->end_time
,
1376 end_time
= events_request
->end_time
;
1379 /* 3.1.2 Find lowest start time in list_out */
1380 for(iter
=list_out
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
1381 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1383 if(ltt_time_compare(events_request
->start_time
,
1385 end_time
= events_request
->start_time
;
1390 /* 3.2 Number of events */
1392 /* 3.2.1 Find lowest number of events in list_in */
1395 end_nb_events
= ((EventsRequest
*)g_slist_nth_data(list_in
,0))->num_events
;
1397 for(iter
=g_slist_nth(list_in
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
1398 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1400 if(events_request
->num_events
< end_nb_events
)
1401 end_nb_events
= events_request
->num_events
;
1404 /* 3.2.2 Use min(CHUNK_NUM_EVENTS, min num events in list_in) as
1407 end_nb_events
= MIN(CHUNK_NUM_EVENTS
, end_nb_events
);
1411 /* 3.3 End position */
1413 /* 3.3.1 Find lowest end position in list_in */
1416 end_position
=((EventsRequest
*)g_slist_nth_data(list_in
,0))->end_position
;
1418 for(iter
=g_slist_nth(list_in
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
1419 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1421 if(events_request
->end_position
!= NULL
&& end_position
!= NULL
&&
1422 lttv_traceset_context_pos_pos_compare(events_request
->end_position
,
1424 end_position
= events_request
->end_position
;
1429 /* 3.3.2 Find lowest start position in list_out */
1432 for(iter
=list_out
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
1433 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1435 if(events_request
->end_position
!= NULL
&& end_position
!= NULL
&&
1436 lttv_traceset_context_pos_pos_compare(events_request
->end_position
,
1438 end_position
= events_request
->end_position
;
1443 /* 4. Call process traceset middle */
1444 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
);
1445 count
= lttv_process_traceset_middle(tsc
, end_time
, end_nb_events
, end_position
);
1447 tfc
= lttv_traceset_context_get_current_tfc(tsc
);
1449 g_debug("Context time after middle : %lu, %lu", tfc
->timestamp
.tv_sec
,
1450 tfc
->timestamp
.tv_nsec
);
1452 g_debug("End of trace reached after middle.");
1456 /* 5. After process traceset middle */
1457 tfc
= lttv_traceset_context_get_current_tfc(tsc
);
1459 /* - if current context time > traceset.end time */
1460 if(tfc
== NULL
|| ltt_time_compare(tfc
->timestamp
,
1461 tsc
->time_span
.end_time
) > 0) {
1462 /* - For each req in list_in */
1463 GSList
*iter
= list_in
;
1465 while(iter
!= NULL
) {
1467 gboolean remove
= FALSE
;
1468 gboolean free_data
= FALSE
;
1469 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1471 /* - Remove events hooks for req
1472 * - Call end chunk for req
1475 if(events_request
->trace
== -1)
1476 lttv_process_traceset_end(tsc
,
1477 events_request
->after_chunk_traceset
,
1478 events_request
->after_chunk_trace
,
1479 events_request
->after_chunk_tracefile
,
1480 events_request
->event
,
1481 events_request
->event_by_id
);
1484 guint nb_trace
= lttv_traceset_number(tsc
->ts
);
1485 g_assert(events_request
->trace
< nb_trace
&&
1486 events_request
->trace
> -1);
1487 LttvTraceContext
*tc
= tsc
->traces
[events_request
->trace
];
1489 lttv_trace_context_remove_hooks(tc
,
1490 events_request
->after_chunk_trace
,
1491 events_request
->after_chunk_tracefile
,
1492 events_request
->event
,
1493 events_request
->event_by_id
);
1494 lttv_hooks_call(events_request
->after_chunk_traceset
, tsc
);
1499 /* - Call end request for req */
1500 lttv_hooks_call(events_request
->after_request
, (gpointer
)tsc
);
1502 /* - remove req from list_in */
1503 /* Destroy the request */
1510 GSList
*remove_iter
= iter
;
1512 iter
= g_slist_next(iter
);
1513 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
1514 list_in
= g_slist_remove_link(list_in
, remove_iter
);
1515 } else { // not remove
1516 iter
= g_slist_next(iter
);
1521 /* 5.1 For each req in list_in */
1522 GSList
*iter
= list_in
;
1524 while(iter
!= NULL
) {
1526 gboolean remove
= FALSE
;
1527 gboolean free_data
= FALSE
;
1528 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1530 /* - Remove events hooks for req
1531 * - Call end chunk for req
1533 if(events_request
->trace
== -1)
1534 lttv_process_traceset_end(tsc
,
1535 events_request
->after_chunk_traceset
,
1536 events_request
->after_chunk_trace
,
1537 events_request
->after_chunk_tracefile
,
1538 events_request
->event
,
1539 events_request
->event_by_id
);
1542 guint nb_trace
= lttv_traceset_number(tsc
->ts
);
1543 g_assert(events_request
->trace
< nb_trace
&&
1544 events_request
->trace
> -1);
1545 LttvTraceContext
*tc
= tsc
->traces
[events_request
->trace
];
1547 lttv_trace_context_remove_hooks(tc
,
1548 events_request
->after_chunk_trace
,
1549 events_request
->after_chunk_tracefile
,
1550 events_request
->event
,
1551 events_request
->event_by_id
);
1553 lttv_hooks_call(events_request
->after_chunk_traceset
, tsc
);
1556 /* - req.num -= count */
1557 g_assert(events_request
->num_events
>= count
);
1558 events_request
->num_events
-= count
;
1560 g_assert(tfc
!= NULL
);
1561 /* - if req.num == 0
1563 * current context time >= req.end time
1565 * req.end pos == current pos
1567 * req.stop_flag == TRUE
1569 if( events_request
->num_events
== 0
1571 events_request
->stop_flag
== TRUE
1573 ltt_time_compare(tfc
->timestamp
,
1574 events_request
->end_time
) >= 0
1576 (events_request
->end_position
!= NULL
1578 lttv_traceset_context_ctx_pos_compare(tsc
,
1579 events_request
->end_position
) == 0)
1582 g_assert(events_request
->servicing
== TRUE
);
1583 /* - Call end request for req
1584 * - remove req from list_in */
1585 lttv_hooks_call(events_request
->after_request
, (gpointer
)tsc
);
1586 /* - remove req from list_in */
1587 /* Destroy the request */
1595 GSList
*remove_iter
= iter
;
1597 iter
= g_slist_next(iter
);
1598 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
1599 list_in
= g_slist_remove_link(list_in
, remove_iter
);
1600 } else { // not remove
1601 iter
= g_slist_next(iter
);
1607 /* End of removed servicing loop : leave control to GTK instead. */
1608 // if(gtk_events_pending()) break;
1611 /* B. When interrupted between chunks */
1614 GSList
*iter
= list_in
;
1616 /* 1. for each request in list_in */
1617 while(iter
!= NULL
) {
1619 gboolean remove
= FALSE
;
1620 gboolean free_data
= FALSE
;
1621 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1623 /* 1.1. Use current postition as start position */
1624 if(events_request
->start_position
!= NULL
)
1625 lttv_traceset_context_position_destroy(events_request
->start_position
);
1626 events_request
->start_position
= lttv_traceset_context_position_new(tsc
);
1627 lttv_traceset_context_position_save(tsc
, events_request
->start_position
);
1629 /* 1.2. Remove start time */
1630 events_request
->start_time
= ltt_time_infinite
;
1632 /* 1.3. Move from list_in to list_out */
1635 list_out
= g_slist_append(list_out
, events_request
);
1640 GSList
*remove_iter
= iter
;
1642 iter
= g_slist_next(iter
);
1643 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
1644 list_in
= g_slist_remove_link(list_in
, remove_iter
);
1645 } else { // not remove
1646 iter
= g_slist_next(iter
);
1652 /* C Unlock Traces */
1654 lttv_process_traceset_get_sync_data(tsc
);
1655 //lttv_traceset_context_position_save(tsc, sync_position);
1660 iter_trace
<lttv_traceset_number(tsc
->ts
);
1662 LttvTrace
*trace_v
= lttv_traceset_get(tsc
->ts
, iter_trace
);
1664 lttvwindowtraces_unlock(trace_v
);
1668 //set the cursor back to normal
1669 gdk_window_set_cursor(win
, NULL
);
1672 g_assert(g_slist_length(list_in
) == 0);
1674 if( g_slist_length(list_out
) == 0 ) {
1675 /* Put tab's request pending flag back to normal */
1676 tab
->events_request_pending
= FALSE
;
1677 g_debug("remove the idle fct");
1678 return FALSE
; /* Remove the idle function */
1680 g_debug("leave the idle fct");
1681 return TRUE
; /* Leave the idle function */
1683 /* We do not use simili-round-robin, it may require to read 1 meg buffers
1684 * again and again if many tracesets use the same tracefiles. */
1685 /* Hack for round-robin idle functions */
1686 /* It will put the idle function at the end of the pool */
1687 /*g_idle_add_full((G_PRIORITY_HIGH_IDLE + 21),
1688 (GSourceFunc)execute_events_requests,
1698 static void lttvwindow_add_trace(Tab
*tab
, LttvTrace
*trace_v
)
1700 LttvTraceset
*traceset
= tab
->traceset_info
->traceset
;
1702 guint num_traces
= lttv_traceset_number(traceset
);
1704 //Verify if trace is already present.
1705 for(i
=0; i
<num_traces
; i
++)
1707 LttvTrace
* trace
= lttv_traceset_get(traceset
, i
);
1708 if(trace
== trace_v
)
1712 //Keep a reference to the traces so they are not freed.
1713 for(i
=0; i
<lttv_traceset_number(traceset
); i
++)
1715 LttvTrace
* trace
= lttv_traceset_get(traceset
, i
);
1716 lttv_trace_ref(trace
);
1719 //remove state update hooks
1720 lttv_state_remove_event_hooks(
1721 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1723 lttv_context_fini(LTTV_TRACESET_CONTEXT(
1724 tab
->traceset_info
->traceset_context
));
1725 g_object_unref(tab
->traceset_info
->traceset_context
);
1727 lttv_traceset_add(traceset
, trace_v
);
1728 lttv_trace_ref(trace_v
); /* local ref */
1730 /* Create new context */
1731 tab
->traceset_info
->traceset_context
=
1732 g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
1734 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->
1739 //add state update hooks
1740 lttv_state_add_event_hooks(
1741 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1742 //Remove local reference to the traces.
1743 for(i
=0; i
<lttv_traceset_number(traceset
); i
++)
1745 LttvTrace
* trace
= lttv_traceset_get(traceset
, i
);
1746 lttv_trace_unref(trace
);
1750 //add_trace_into_traceset_selector(GTK_MULTIVPANED(tab->multivpaned), lttv_trace(trace_v));
1753 /* add_trace adds a trace into the current traceset. It first displays a
1754 * directory selection dialogue to let user choose a trace, then recreates
1755 * tracset_context, and redraws all the viewer of the current tab
1758 void add_trace(GtkWidget
* widget
, gpointer user_data
)
1761 LttvTrace
* trace_v
;
1762 LttvTraceset
* traceset
;
1764 char abs_path
[PATH_MAX
];
1766 MainWindow
* mw_data
= get_window_data_struct(widget
);
1767 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
1769 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
1770 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
1771 LttvPluginTab
*ptab
;
1775 ptab
= create_new_tab(widget
, NULL
);
1778 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
1782 //GtkDirSelection * file_selector = (GtkDirSelection *)gtk_dir_selection_new("Select a trace");
1783 GtkFileSelection
* file_selector
= (GtkFileSelection
*)gtk_file_selection_new("Select a trace");
1784 gtk_widget_hide( (file_selector
)->file_list
->parent
) ;
1785 gtk_file_selection_hide_fileop_buttons(file_selector
);
1786 gtk_window_set_transient_for(GTK_WINDOW(file_selector
),
1787 GTK_WINDOW(mw_data
->mwindow
));
1789 if(remember_trace_dir
[0] != '\0')
1790 gtk_file_selection_set_filename(file_selector
, remember_trace_dir
);
1792 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
1794 case GTK_RESPONSE_ACCEPT
:
1795 case GTK_RESPONSE_OK
:
1796 dir
= gtk_file_selection_get_filename (file_selector
);
1797 strncpy(remember_trace_dir
, dir
, PATH_MAX
);
1798 strncat(remember_trace_dir
, "/", PATH_MAX
);
1799 if(!dir
|| strlen(dir
) == 0){
1800 gtk_widget_destroy((GtkWidget
*)file_selector
);
1803 get_absolute_pathname(dir
, abs_path
);
1804 trace_v
= lttvwindowtraces_get_trace_by_name(abs_path
);
1805 if(trace_v
== NULL
) {
1806 trace
= ltt_trace_open(abs_path
);
1808 g_warning("cannot open trace %s", abs_path
);
1810 GtkWidget
*dialogue
=
1811 gtk_message_dialog_new(
1812 GTK_WINDOW(gtk_widget_get_toplevel(widget
)),
1813 GTK_DIALOG_MODAL
|GTK_DIALOG_DESTROY_WITH_PARENT
,
1816 "Cannot open trace : maybe you should enter in the trace "
1817 "directory to select it ?");
1818 gtk_dialog_run(GTK_DIALOG(dialogue
));
1819 gtk_widget_destroy(dialogue
);
1822 trace_v
= lttv_trace_new(trace
);
1823 lttvwindowtraces_add_trace(trace_v
);
1824 lttvwindow_add_trace(tab
, trace_v
);
1827 lttvwindow_add_trace(tab
, trace_v
);
1830 gtk_widget_destroy((GtkWidget
*)file_selector
);
1832 //update current tab
1833 //update_traceset(mw_data);
1835 /* Call the updatetraceset hooks */
1837 traceset
= tab
->traceset_info
->traceset
;
1838 SetTraceset(tab
, traceset
);
1839 // in expose now call_pending_read_hooks(mw_data);
1841 //lttvwindow_report_current_time(mw_data,&(tab->current_time));
1843 case GTK_RESPONSE_REJECT
:
1844 case GTK_RESPONSE_CANCEL
:
1846 gtk_widget_destroy((GtkWidget
*)file_selector
);
1851 /* remove_trace removes a trace from the current traceset if all viewers in
1852 * the current tab are not interested in the trace. It first displays a
1853 * dialogue, which shows all traces in the current traceset, to let user choose
1854 * a trace, then it checks if all viewers unselect the trace, if it is true,
1855 * it will remove the trace, recreate the traceset_contex,
1856 * and redraws all the viewer of the current tab. If there is on trace in the
1857 * current traceset, it will delete all viewers of the current tab
1859 * It destroys the filter tree. FIXME... we should request for an update
1863 void remove_trace(GtkWidget
*widget
, gpointer user_data
)
1866 LttvTrace
* trace_v
;
1867 LttvTraceset
* traceset
;
1868 gint i
, j
, nb_trace
, index
=-1;
1869 char ** name
, *remove_trace_name
;
1870 MainWindow
* mw_data
= get_window_data_struct(widget
);
1871 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
1873 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
1874 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
1880 LttvPluginTab
*ptab
;
1881 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
1885 nb_trace
=lttv_traceset_number(tab
->traceset_info
->traceset
);
1886 name
= g_new(char*,nb_trace
);
1887 for(i
= 0; i
< nb_trace
; i
++){
1888 trace_v
= lttv_traceset_get(tab
->traceset_info
->traceset
, i
);
1889 trace
= lttv_trace(trace_v
);
1890 name
[i
] = g_quark_to_string(ltt_trace_name(trace
));
1893 remove_trace_name
= get_remove_trace(mw_data
, name
, nb_trace
);
1896 if(remove_trace_name
){
1898 /* yuk, cut n paste from old code.. should be better (MD)*/
1899 for(i
= 0; i
<nb_trace
; i
++) {
1900 if(strcmp(remove_trace_name
,name
[i
]) == 0){
1905 traceset
= tab
->traceset_info
->traceset
;
1906 //Keep a reference to the traces so they are not freed.
1907 for(j
=0; j
<lttv_traceset_number(traceset
); j
++)
1909 LttvTrace
* trace
= lttv_traceset_get(traceset
, j
);
1910 lttv_trace_ref(trace
);
1913 //remove state update hooks
1914 lttv_state_remove_event_hooks(
1915 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1916 lttv_context_fini(LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
));
1917 g_object_unref(tab
->traceset_info
->traceset_context
);
1919 trace_v
= lttv_traceset_get(traceset
, index
);
1921 lttv_traceset_remove(traceset
, index
);
1922 lttv_trace_unref(trace_v
); // Remove local reference
1924 if(lttv_trace_get_ref_number(trace_v
) <= 1) {
1925 /* ref 1 : lttvwindowtraces only*/
1926 ltt_trace_close(lttv_trace(trace_v
));
1927 /* lttvwindowtraces_remove_trace takes care of destroying
1928 * the traceset linked with the trace_v and also of destroying
1929 * the trace_v at the same time.
1931 lttvwindowtraces_remove_trace(trace_v
);
1934 tab
->traceset_info
->traceset_context
=
1935 g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
1937 LTTV_TRACESET_CONTEXT(tab
->
1938 traceset_info
->traceset_context
),traceset
);
1939 //add state update hooks
1940 lttv_state_add_event_hooks(
1941 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1943 //Remove local reference to the traces.
1944 for(j
=0; j
<lttv_traceset_number(traceset
); j
++)
1946 LttvTrace
* trace
= lttv_traceset_get(traceset
, j
);
1947 lttv_trace_unref(trace
);
1950 SetTraceset(tab
, (gpointer
)traceset
);
1956 void remove_trace(GtkWidget
* widget
, gpointer user_data
)
1959 LttvTrace
* trace_v
;
1960 LttvTraceset
* traceset
;
1961 gint i
, j
, nb_trace
;
1962 char ** name
, *remove_trace_name
;
1963 MainWindow
* mw_data
= get_window_data_struct(widget
);
1964 LttvTracesetSelector
* s
;
1965 LttvTraceSelector
* t
;
1968 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
1970 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
1971 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
1977 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
1980 nb_trace
=lttv_traceset_number(tab
->traceset_info
->traceset
);
1981 name
= g_new(char*,nb_trace
);
1982 for(i
= 0; i
< nb_trace
; i
++){
1983 trace_v
= lttv_traceset_get(tab
->traceset_info
->traceset
, i
);
1984 trace
= lttv_trace(trace_v
);
1985 name
[i
] = ltt_trace_name(trace
);
1988 remove_trace_name
= get_remove_trace(name
, nb_trace
);
1990 if(remove_trace_name
){
1991 for(i
=0; i
<nb_trace
; i
++){
1992 if(strcmp(remove_trace_name
,name
[i
]) == 0){
1993 //unselect the trace from the current viewer
1995 w
= gtk_multivpaned_get_widget(GTK_MULTIVPANED(tab
->multivpaned
));
1997 s
= g_object_get_data(G_OBJECT(w
), "Traceset_Selector");
1999 t
= lttv_traceset_selector_trace_get(s
,i
);
2000 lttv_trace_selector_set_selected(t
, FALSE
);
2003 //check if other viewers select the trace
2004 w
= gtk_multivpaned_get_first_widget(GTK_MULTIVPANED(tab
->multivpaned
));
2006 s
= g_object_get_data(G_OBJECT(w
), "Traceset_Selector");
2008 t
= lttv_traceset_selector_trace_get(s
,i
);
2009 selected
= lttv_trace_selector_get_selected(t
);
2012 w
= gtk_multivpaned_get_next_widget(GTK_MULTIVPANED(tab
->multivpaned
));
2014 }else selected
= FALSE
;
2016 //if no viewer selects the trace, remove it
2018 remove_trace_from_traceset_selector(GTK_MULTIVPANED(tab
->multivpaned
), i
);
2020 traceset
= tab
->traceset_info
->traceset
;
2021 //Keep a reference to the traces so they are not freed.
2022 for(j
=0; j
<lttv_traceset_number(traceset
); j
++)
2024 LttvTrace
* trace
= lttv_traceset_get(traceset
, j
);
2025 lttv_trace_ref(trace
);
2028 //remove state update hooks
2029 lttv_state_remove_event_hooks(
2030 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
2031 lttv_context_fini(LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
));
2032 g_object_unref(tab
->traceset_info
->traceset_context
);
2035 trace_v
= lttv_traceset_get(traceset
, i
);
2037 if(lttv_trace_get_ref_number(trace_v
) <= 2) {
2038 /* ref 2 : traceset, local */
2039 lttvwindowtraces_remove_trace(trace_v
);
2040 ltt_trace_close(lttv_trace(trace_v
));
2043 lttv_traceset_remove(traceset
, i
);
2044 lttv_trace_unref(trace_v
); // Remove local reference
2046 if(!lttv_trace_get_ref_number(trace_v
))
2047 lttv_trace_destroy(trace_v
);
2049 tab
->traceset_info
->traceset_context
=
2050 g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
2052 LTTV_TRACESET_CONTEXT(tab
->
2053 traceset_info
->traceset_context
),traceset
);
2054 //add state update hooks
2055 lttv_state_add_event_hooks(
2056 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
2058 //Remove local reference to the traces.
2059 for(j
=0; j
<lttv_traceset_number(traceset
); j
++)
2061 LttvTrace
* trace
= lttv_traceset_get(traceset
, j
);
2062 lttv_trace_unref(trace
);
2066 //update current tab
2067 //update_traceset(mw_data);
2070 SetTraceset(tab
, (gpointer
)traceset
);
2071 // in expose now call_pending_read_hooks(mw_data);
2073 //lttvwindow_report_current_time(mw_data,&(tab->current_time));
2076 // while(tab->multi_vpaned->num_children){
2077 // gtk_multi_vpaned_widget_delete(tab->multi_vpaned);
2091 /* Redraw all the viewers in the current tab */
2092 void redraw(GtkWidget
*widget
, gpointer user_data
)
2094 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
2095 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2096 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2101 LttvPluginTab
*ptab
;
2102 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
2107 LttvAttributeValue value
;
2109 g_assert(lttv_iattribute_find_by_path(tab
->attributes
, "hooks/redraw", LTTV_POINTER
, &value
));
2111 tmp
= (LttvHooks
*)*(value
.v_pointer
);
2113 lttv_hooks_call(tmp
,NULL
);
2117 void continue_processing(GtkWidget
*widget
, gpointer user_data
)
2119 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
2120 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2121 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2126 LttvPluginTab
*ptab
;
2127 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
2132 LttvAttributeValue value
;
2134 g_assert(lttv_iattribute_find_by_path(tab
->attributes
,
2135 "hooks/continue", LTTV_POINTER
, &value
));
2137 tmp
= (LttvHooks
*)*(value
.v_pointer
);
2139 lttv_hooks_call(tmp
,NULL
);
2142 /* Stop the processing for the calling main window's current tab.
2143 * It removes every processing requests that are in its list. It does not call
2144 * the end request hooks, because the request is not finished.
2147 void stop_processing(GtkWidget
*widget
, gpointer user_data
)
2149 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
2150 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2151 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2156 LttvPluginTab
*ptab
;
2157 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
2160 GSList
*iter
= tab
->events_requests
;
2162 while(iter
!= NULL
) {
2163 GSList
*remove_iter
= iter
;
2164 iter
= g_slist_next(iter
);
2166 g_free(remove_iter
->data
);
2167 tab
->events_requests
=
2168 g_slist_remove_link(tab
->events_requests
, remove_iter
);
2170 tab
->events_request_pending
= FALSE
;
2171 tab
->stop_foreground
= TRUE
;
2172 g_idle_remove_by_data(tab
);
2173 g_assert(g_slist_length(tab
->events_requests
) == 0);
2177 /* save will save the traceset to a file
2178 * Not implemented yet FIXME
2181 void save(GtkWidget
* widget
, gpointer user_data
)
2186 void save_as(GtkWidget
* widget
, gpointer user_data
)
2188 g_info("Save as\n");
2192 /* zoom will change the time_window of all the viewers of the
2193 * current tab, and redisplay them. The main functionality is to
2194 * determine the new time_window of the current tab
2197 void zoom(GtkWidget
* widget
, double size
)
2199 TimeInterval time_span
;
2200 TimeWindow new_time_window
;
2201 LttTime current_time
, time_delta
;
2202 MainWindow
* mw_data
= get_window_data_struct(widget
);
2203 LttvTracesetContext
*tsc
;
2204 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
2206 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2207 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2213 LttvPluginTab
*ptab
;
2214 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
2218 if(size
== 1) return;
2220 tsc
= LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
2221 time_span
= tsc
->time_span
;
2222 new_time_window
= tab
->time_window
;
2223 current_time
= tab
->current_time
;
2225 time_delta
= ltt_time_sub(time_span
.end_time
,time_span
.start_time
);
2227 new_time_window
.start_time
= time_span
.start_time
;
2228 new_time_window
.time_width
= time_delta
;
2229 new_time_window
.time_width_double
= ltt_time_to_double(time_delta
);
2230 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
2231 new_time_window
.time_width
) ;
2233 new_time_window
.time_width
= ltt_time_div(new_time_window
.time_width
, size
);
2234 new_time_window
.time_width_double
=
2235 ltt_time_to_double(new_time_window
.time_width
);
2236 if(ltt_time_compare(new_time_window
.time_width
,time_delta
) > 0)
2237 { /* Case where zoom out is bigger than trace length */
2238 new_time_window
.start_time
= time_span
.start_time
;
2239 new_time_window
.time_width
= time_delta
;
2240 new_time_window
.time_width_double
= ltt_time_to_double(time_delta
);
2241 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
2242 new_time_window
.time_width
) ;
2246 /* Center the image on the current time */
2247 new_time_window
.start_time
=
2248 ltt_time_sub(current_time
,
2249 ltt_time_from_double(new_time_window
.time_width_double
/2.0));
2250 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
2251 new_time_window
.time_width
) ;
2252 /* If on borders, don't fall off */
2253 if(ltt_time_compare(new_time_window
.start_time
, time_span
.start_time
) <0
2254 || ltt_time_compare(new_time_window
.start_time
, time_span
.end_time
) >0)
2256 new_time_window
.start_time
= time_span
.start_time
;
2257 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
2258 new_time_window
.time_width
) ;
2262 if(ltt_time_compare(new_time_window
.end_time
,
2263 time_span
.end_time
) > 0
2264 || ltt_time_compare(new_time_window
.end_time
,
2265 time_span
.start_time
) < 0)
2267 new_time_window
.start_time
=
2268 ltt_time_sub(time_span
.end_time
, new_time_window
.time_width
);
2270 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
2271 new_time_window
.time_width
) ;
2278 if(ltt_time_compare(new_time_window
.time_width
, ltt_time_zero
) == 0) {
2279 g_warning("Zoom more than 1 ns impossible");
2281 time_change_manager(tab
, new_time_window
);
2285 void zoom_in(GtkWidget
* widget
, gpointer user_data
)
2290 void zoom_out(GtkWidget
* widget
, gpointer user_data
)
2295 void zoom_extended(GtkWidget
* widget
, gpointer user_data
)
2300 void go_to_time(GtkWidget
* widget
, gpointer user_data
)
2302 g_info("Go to time\n");
2305 void show_time_frame(GtkWidget
* widget
, gpointer user_data
)
2307 g_info("Show time frame\n");
2311 /* callback function */
2314 on_empty_traceset_activate (GtkMenuItem
*menuitem
,
2317 create_new_window((GtkWidget
*)menuitem
, user_data
, FALSE
);
2322 on_clone_traceset_activate (GtkMenuItem
*menuitem
,
2325 create_new_window((GtkWidget
*)menuitem
, user_data
, TRUE
);
2329 /* create_new_tab calls create_tab to construct a new tab in the main window
2332 LttvPluginTab
*create_new_tab(GtkWidget
* widget
, gpointer user_data
)
2334 gchar label
[PATH_MAX
];
2335 MainWindow
* mw_data
= get_window_data_struct(widget
);
2337 GtkNotebook
* notebook
= (GtkNotebook
*)lookup_widget(widget
, "MNotebook");
2338 if(notebook
== NULL
){
2339 g_info("Notebook does not exist\n");
2342 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2343 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2349 LttvPluginTab
*ptab
;
2350 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
2351 copy_tab
= ptab
->tab
;
2354 strcpy(label
,"Page");
2355 if(get_label(mw_data
, label
,"Get the name of the tab","Please input tab's name")) {
2356 LttvPluginTab
*ptab
;
2358 ptab
= g_object_new(LTTV_TYPE_PLUGIN_TAB
, NULL
);
2359 init_tab (ptab
->tab
, mw_data
, copy_tab
, notebook
, label
);
2360 ptab
->parent
.top_widget
= ptab
->tab
->top_widget
;
2361 g_object_set_data_full(
2362 G_OBJECT(ptab
->tab
->vbox
),
2365 (GDestroyNotify
)tab_destructor
);
2372 on_tab_activate (GtkMenuItem
*menuitem
,
2375 create_new_tab((GtkWidget
*)menuitem
, user_data
);
2380 on_open_activate (GtkMenuItem
*menuitem
,
2383 open_traceset((GtkWidget
*)menuitem
, user_data
);
2388 on_close_activate (GtkMenuItem
*menuitem
,
2391 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2392 main_window_destructor(mw_data
);
2396 /* remove the current tab from the main window
2400 on_close_tab_activate (GtkWidget
*widget
,
2404 GtkWidget
* notebook
;
2406 MainWindow
* mw_data
= get_window_data_struct(widget
);
2407 notebook
= lookup_widget(widget
, "MNotebook");
2408 if(notebook
== NULL
){
2409 g_info("Notebook does not exist\n");
2413 page_num
= gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
));
2415 gtk_notebook_remove_page(GTK_NOTEBOOK(notebook
), page_num
);
2420 on_close_tab_X_clicked (GtkWidget
*widget
,
2424 GtkWidget
*notebook
= lookup_widget(widget
, "MNotebook");
2425 if(notebook
== NULL
){
2426 g_info("Notebook does not exist\n");
2430 if((page_num
= gtk_notebook_page_num(GTK_NOTEBOOK(notebook
), widget
)) != -1)
2431 gtk_notebook_remove_page(GTK_NOTEBOOK(notebook
), page_num
);
2437 on_add_trace_activate (GtkMenuItem
*menuitem
,
2440 add_trace((GtkWidget
*)menuitem
, user_data
);
2445 on_remove_trace_activate (GtkMenuItem
*menuitem
,
2448 remove_trace((GtkWidget
*)menuitem
, user_data
);
2453 on_save_activate (GtkMenuItem
*menuitem
,
2456 save((GtkWidget
*)menuitem
, user_data
);
2461 on_save_as_activate (GtkMenuItem
*menuitem
,
2464 save_as((GtkWidget
*)menuitem
, user_data
);
2469 on_quit_activate (GtkMenuItem
*menuitem
,
2477 on_cut_activate (GtkMenuItem
*menuitem
,
2485 on_copy_activate (GtkMenuItem
*menuitem
,
2493 on_paste_activate (GtkMenuItem
*menuitem
,
2501 on_delete_activate (GtkMenuItem
*menuitem
,
2509 on_zoom_in_activate (GtkMenuItem
*menuitem
,
2512 zoom_in((GtkWidget
*)menuitem
, user_data
);
2517 on_zoom_out_activate (GtkMenuItem
*menuitem
,
2520 zoom_out((GtkWidget
*)menuitem
, user_data
);
2525 on_zoom_extended_activate (GtkMenuItem
*menuitem
,
2528 zoom_extended((GtkWidget
*)menuitem
, user_data
);
2533 on_go_to_time_activate (GtkMenuItem
*menuitem
,
2536 go_to_time((GtkWidget
*)menuitem
, user_data
);
2541 on_show_time_frame_activate (GtkMenuItem
*menuitem
,
2544 show_time_frame((GtkWidget
*)menuitem
, user_data
);
2549 on_move_viewer_up_activate (GtkMenuItem
*menuitem
,
2552 move_up_viewer((GtkWidget
*)menuitem
, user_data
);
2557 on_move_viewer_down_activate (GtkMenuItem
*menuitem
,
2560 move_down_viewer((GtkWidget
*)menuitem
, user_data
);
2565 on_remove_viewer_activate (GtkMenuItem
*menuitem
,
2568 delete_viewer((GtkWidget
*)menuitem
, user_data
);
2572 on_trace_facility_activate (GtkMenuItem
*menuitem
,
2575 g_info("Trace facility selector: %s\n");
2579 /* Dispaly a file selection dialogue to let user select a library, then call
2580 * lttv_library_load().
2584 on_load_library_activate (GtkMenuItem
*menuitem
,
2587 GError
*error
= NULL
;
2588 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2590 gchar load_module_path_alter
[PATH_MAX
];
2594 gchar
*load_module_path
;
2595 name
= g_ptr_array_new();
2596 nb
= lttv_library_path_number();
2597 /* ask for the library path */
2601 path
= lttv_library_path_get(i
);
2602 g_ptr_array_add(name
, path
);
2605 load_module_path
= get_selection(mw_data
,
2606 (char **)(name
->pdata
), name
->len
,
2607 "Select a library path", "Library paths");
2608 if(load_module_path
!= NULL
)
2609 strncpy(load_module_path_alter
, load_module_path
, PATH_MAX
-1); // -1 for /
2611 g_ptr_array_free(name
, TRUE
);
2613 if(load_module_path
== NULL
) return;
2617 /* Make sure the module path ends with a / */
2618 gchar
*ptr
= load_module_path_alter
;
2620 ptr
= strchr(ptr
, '\0');
2622 if(*(ptr
-1) != '/') {
2629 /* Ask for the library to load : list files in the previously selected
2631 gchar str
[PATH_MAX
];
2634 GtkFileSelection
* file_selector
=
2635 (GtkFileSelection
*)gtk_file_selection_new("Select a module");
2636 gtk_file_selection_set_filename(file_selector
, load_module_path_alter
);
2637 gtk_file_selection_hide_fileop_buttons(file_selector
);
2639 gtk_window_set_transient_for(GTK_WINDOW(file_selector
),
2640 GTK_WINDOW(mw_data
->mwindow
));
2643 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
2645 case GTK_RESPONSE_ACCEPT
:
2646 case GTK_RESPONSE_OK
:
2647 dir
= gtk_file_selection_get_selections (file_selector
);
2648 strncpy(str
,dir
[0],PATH_MAX
);
2649 strncpy(remember_plugins_dir
,dir
[0],PATH_MAX
);
2650 /* only keep file name */
2652 str1
= strrchr(str
,'/');
2655 str1
= strrchr(str
,'\\');
2660 if(*str1
== 'l' && *(str1
+1)== 'i' && *(str1
+2)=='b')
2662 remove info after
. */
2666 str2
= strrchr(str2
, '.');
2667 if(str2
!= NULL
) *str2
= '\0';
2669 lttv_module_require(str1
, &error
);
2671 lttv_library_load(str1
, &error
);
2672 if(error
!= NULL
) g_warning("%s", error
->message
);
2673 else g_info("Load library: %s\n", str
);
2675 case GTK_RESPONSE_REJECT
:
2676 case GTK_RESPONSE_CANCEL
:
2678 gtk_widget_destroy((GtkWidget
*)file_selector
);
2689 /* Display all loaded modules, let user to select a module to unload
2690 * by calling lttv_module_unload
2694 on_unload_library_activate (GtkMenuItem
*menuitem
,
2697 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2699 LttvLibrary
*library
= NULL
;
2704 name
= g_ptr_array_new();
2705 nb
= lttv_library_number();
2706 LttvLibraryInfo
*lib_info
= g_new(LttvLibraryInfo
,nb
);
2707 /* ask for the library name */
2710 LttvLibrary
*iter_lib
= lttv_library_get(i
);
2711 lttv_library_info(iter_lib
, &lib_info
[i
]);
2713 gchar
*path
= lib_info
[i
].name
;
2714 g_ptr_array_add(name
, path
);
2716 lib_name
= get_selection(mw_data
, (char **)(name
->pdata
), name
->len
,
2717 "Select a library", "Libraries");
2718 if(lib_name
!= NULL
) {
2720 if(strcmp(lib_name
, lib_info
[i
].name
) == 0) {
2721 library
= lttv_library_get(i
);
2726 g_ptr_array_free(name
, TRUE
);
2729 if(lib_name
== NULL
) return;
2731 if(library
!= NULL
) lttv_library_unload(library
);
2735 /* Dispaly a file selection dialogue to let user select a module, then call
2736 * lttv_module_require().
2740 on_load_module_activate (GtkMenuItem
*menuitem
,
2743 GError
*error
= NULL
;
2744 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2746 LttvLibrary
*library
= NULL
;
2751 name
= g_ptr_array_new();
2752 nb
= lttv_library_number();
2753 LttvLibraryInfo
*lib_info
= g_new(LttvLibraryInfo
,nb
);
2754 /* ask for the library name */
2757 LttvLibrary
*iter_lib
= lttv_library_get(i
);
2758 lttv_library_info(iter_lib
, &lib_info
[i
]);
2760 gchar
*path
= lib_info
[i
].name
;
2761 g_ptr_array_add(name
, path
);
2763 lib_name
= get_selection(mw_data
,(char **)(name
->pdata
), name
->len
,
2764 "Select a library", "Libraries");
2765 if(lib_name
!= NULL
) {
2767 if(strcmp(lib_name
, lib_info
[i
].name
) == 0) {
2768 library
= lttv_library_get(i
);
2773 g_ptr_array_free(name
, TRUE
);
2776 if(lib_name
== NULL
) return;
2779 //LttvModule *module;
2780 gchar module_name_out
[PATH_MAX
];
2782 /* Ask for the module to load : list modules in the selected lib */
2786 nb
= lttv_library_module_number(library
);
2787 LttvModuleInfo
*module_info
= g_new(LttvModuleInfo
,nb
);
2788 name
= g_ptr_array_new();
2789 /* ask for the module name */
2792 LttvModule
*iter_module
= lttv_library_module_get(library
, i
);
2793 lttv_module_info(iter_module
, &module_info
[i
]);
2795 gchar
*path
= module_info
[i
].name
;
2796 g_ptr_array_add(name
, path
);
2798 module_name
= get_selection(mw_data
, (char **)(name
->pdata
), name
->len
,
2799 "Select a module", "Modules");
2800 if(module_name
!= NULL
) {
2802 if(strcmp(module_name
, module_info
[i
].name
) == 0) {
2803 strncpy(module_name_out
, module_name
, PATH_MAX
);
2804 //module = lttv_library_module_get(i);
2810 g_ptr_array_free(name
, TRUE
);
2811 g_free(module_info
);
2813 if(module_name
== NULL
) return;
2816 lttv_module_require(module_name_out
, &error
);
2817 if(error
!= NULL
) g_warning("%s", error
->message
);
2818 else g_info("Load module: %s", module_name_out
);
2825 gchar str
[PATH_MAX
];
2828 GtkFileSelection
* file_selector
=
2829 (GtkFileSelection
*)gtk_file_selection_new("Select a module");
2830 gtk_file_selection_set_filename(file_selector
, load_module_path_alter
);
2831 gtk_file_selection_hide_fileop_buttons(file_selector
);
2834 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
2836 case GTK_RESPONSE_ACCEPT
:
2837 case GTK_RESPONSE_OK
:
2838 dir
= gtk_file_selection_get_selections (file_selector
);
2839 strncpy(str
,dir
[0],PATH_MAX
);
2840 strncpy(remember_plugins_dir
,dir
[0],PATH_MAX
);
2842 /* only keep file name */
2844 str1
= strrchr(str
,'/');
2847 str1
= strrchr(str
,'\\');
2852 if(*str1
== 'l' && *(str1
+1)== 'i' && *(str1
+2)=='b')
2854 remove info after
. */
2858 str2
= strrchr(str2
, '.');
2859 if(str2
!= NULL
) *str2
= '\0';
2861 lttv_module_require(str1
, &error
);
2863 lttv_library_load(str1
, &error
);
2864 if(error
!= NULL
) g_warning(error
->message
);
2865 else g_info("Load library: %s\n", str
);
2867 case GTK_RESPONSE_REJECT
:
2868 case GTK_RESPONSE_CANCEL
:
2870 gtk_widget_destroy((GtkWidget
*)file_selector
);
2882 /* Display all loaded modules, let user to select a module to unload
2883 * by calling lttv_module_unload
2887 on_unload_module_activate (GtkMenuItem
*menuitem
,
2890 GError
*error
= NULL
;
2891 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2893 LttvLibrary
*library
;
2898 name
= g_ptr_array_new();
2899 nb
= lttv_library_number();
2900 LttvLibraryInfo
*lib_info
= g_new(LttvLibraryInfo
,nb
);
2901 /* ask for the library name */
2904 LttvLibrary
*iter_lib
= lttv_library_get(i
);
2905 lttv_library_info(iter_lib
, &lib_info
[i
]);
2907 gchar
*path
= lib_info
[i
].name
;
2908 g_ptr_array_add(name
, path
);
2910 lib_name
= get_selection(mw_data
, (char **)(name
->pdata
), name
->len
,
2911 "Select a library", "Libraries");
2912 if(lib_name
!= NULL
) {
2914 if(strcmp(lib_name
, lib_info
[i
].name
) == 0) {
2915 library
= lttv_library_get(i
);
2920 g_ptr_array_free(name
, TRUE
);
2923 if(lib_name
== NULL
) return;
2926 LttvModule
*module
= NULL
;
2928 /* Ask for the module to load : list modules in the selected lib */
2932 nb
= lttv_library_module_number(library
);
2933 LttvModuleInfo
*module_info
= g_new(LttvModuleInfo
,nb
);
2934 name
= g_ptr_array_new();
2935 /* ask for the module name */
2938 LttvModule
*iter_module
= lttv_library_module_get(library
, i
);
2939 lttv_module_info(iter_module
, &module_info
[i
]);
2941 gchar
*path
= module_info
[i
].name
;
2942 if(module_info
[i
].use_count
> 0) g_ptr_array_add(name
, path
);
2944 module_name
= get_selection(mw_data
, (char **)(name
->pdata
), name
->len
,
2945 "Select a module", "Modules");
2946 if(module_name
!= NULL
) {
2948 if(strcmp(module_name
, module_info
[i
].name
) == 0) {
2949 module
= lttv_library_module_get(library
, i
);
2955 g_ptr_array_free(name
, TRUE
);
2956 g_free(module_info
);
2958 if(module_name
== NULL
) return;
2961 LttvModuleInfo module_info
;
2962 lttv_module_info(module
, &module_info
);
2963 g_info("Release module: %s\n", module_info
.name
);
2965 lttv_module_release(module
);
2969 /* Display a directory dialogue to let user select a path for library searching
2973 on_add_library_search_path_activate (GtkMenuItem
*menuitem
,
2976 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2977 //GtkDirSelection * file_selector = (GtkDirSelection *)gtk_dir_selection_new("Select library path");
2978 GtkFileSelection
* file_selector
= (GtkFileSelection
*)gtk_file_selection_new("Select a trace");
2979 gtk_widget_hide( (file_selector
)->file_list
->parent
) ;
2981 gtk_window_set_transient_for(GTK_WINDOW(file_selector
),
2982 GTK_WINDOW(mw_data
->mwindow
));
2987 if(remember_plugins_dir
[0] != '\0')
2988 gtk_file_selection_set_filename(file_selector
, remember_plugins_dir
);
2990 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
2992 case GTK_RESPONSE_ACCEPT
:
2993 case GTK_RESPONSE_OK
:
2994 dir
= gtk_file_selection_get_filename (file_selector
);
2995 strncpy(remember_plugins_dir
,dir
,PATH_MAX
);
2996 strncat(remember_plugins_dir
,"/",PATH_MAX
);
2997 lttv_library_path_add(dir
);
2998 case GTK_RESPONSE_REJECT
:
2999 case GTK_RESPONSE_CANCEL
:
3001 gtk_widget_destroy((GtkWidget
*)file_selector
);
3007 /* Display a directory dialogue to let user select a path for library searching
3011 on_remove_library_search_path_activate (GtkMenuItem
*menuitem
,
3014 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
3016 const char *lib_path
;
3021 name
= g_ptr_array_new();
3022 nb
= lttv_library_path_number();
3023 /* ask for the library name */
3026 gchar
*path
= lttv_library_path_get(i
);
3027 g_ptr_array_add(name
, path
);
3029 lib_path
= get_selection(mw_data
, (char **)(name
->pdata
), name
->len
,
3030 "Select a library path", "Library paths");
3032 g_ptr_array_free(name
, TRUE
);
3034 if(lib_path
== NULL
) return;
3037 lttv_library_path_remove(lib_path
);
3041 on_color_activate (GtkMenuItem
*menuitem
,
3049 on_save_configuration_activate (GtkMenuItem
*menuitem
,
3052 g_info("Save configuration\n");
3057 on_content_activate (GtkMenuItem
*menuitem
,
3060 g_info("Content\n");
3065 on_about_close_activate (GtkButton
*button
,
3068 GtkWidget
*about_widget
= GTK_WIDGET(user_data
);
3070 gtk_widget_destroy(about_widget
);
3074 on_about_activate (GtkMenuItem
*menuitem
,
3077 MainWindow
*main_window
= get_window_data_struct(GTK_WIDGET(menuitem
));
3078 GtkWidget
*window_widget
= main_window
->mwindow
;
3079 GtkWidget
*about_widget
= gtk_window_new(GTK_WINDOW_TOPLEVEL
);
3080 GtkWindow
*about_window
= GTK_WINDOW(about_widget
);
3081 gint window_width
, window_height
;
3083 gtk_window_set_title(about_window
, "About Linux Trace Toolkit");
3085 gtk_window_set_resizable(about_window
, FALSE
);
3086 gtk_window_set_transient_for(GTK_WINDOW(window_widget
), about_window
);
3087 gtk_window_set_destroy_with_parent(about_window
, TRUE
);
3088 gtk_window_set_modal(about_window
, FALSE
);
3090 /* Put the about window at the center of the screen */
3091 gtk_window_get_size(about_window
, &window_width
, &window_height
);
3092 gtk_window_move (about_window
,
3093 (gdk_screen_width() - window_width
)/2,
3094 (gdk_screen_height() - window_height
)/2);
3096 GtkWidget
*vbox
= gtk_vbox_new(FALSE
, 1);
3098 gtk_container_add(GTK_CONTAINER(about_widget
), vbox
);
3102 GtkWidget
*label1
= gtk_label_new("");
3103 gtk_misc_set_padding(GTK_MISC(label1
), 10, 20);
3104 gtk_label_set_markup(GTK_LABEL(label1
), "\
3105 <big>Linux Trace Toolkit</big>");
3106 gtk_label_set_justify(GTK_LABEL(label1
), GTK_JUSTIFY_CENTER
);
3108 GtkWidget
*label2
= gtk_label_new("");
3109 gtk_misc_set_padding(GTK_MISC(label2
), 10, 20);
3110 gtk_label_set_markup(GTK_LABEL(label2
), "\
3113 Michel Dagenais (New trace format, lttv main)\n\
3114 Mathieu Desnoyers (Kernel Tracer, Directory structure, build with automake/conf,\n\
3115 lttv gui, control flow view, gui cooperative trace reading\n\
3116 scheduler with interruptible foreground and background\n\
3117 computation, detailed event list (rewrite), trace reading\n\
3118 library (rewrite))\n\
3119 Benoit Des Ligneris, Eric Clement (Cluster adaptation, work in progress)\n\
3120 Xang-Xiu Yang (new trace reading library and converter, lttv gui, \n\
3121 detailed event list and statistics view)\n\
3122 Tom Zanussi (RelayFS)\n\
3124 Strongly inspired from the original Linux Trace Toolkit Visualizer made by\n\
3127 GtkWidget
*label3
= gtk_label_new("");
3128 gtk_label_set_markup(GTK_LABEL(label3
), "\
3129 Linux Trace Toolkit Viewer, Copyright (C) 2004\n\
3131 Mathieu Desnoyers\n\
3133 Linux Trace Toolkit comes with ABSOLUTELY NO WARRANTY.\n\
3134 This is free software, and you are welcome to redistribute it\n\
3135 under certain conditions. See COPYING for details.");
3136 gtk_misc_set_padding(GTK_MISC(label3
), 10, 20);
3138 gtk_box_pack_start_defaults(GTK_BOX(vbox
), label1
);
3139 gtk_box_pack_start_defaults(GTK_BOX(vbox
), label2
);
3140 gtk_box_pack_start_defaults(GTK_BOX(vbox
), label3
);
3142 GtkWidget
*hbox
= gtk_hbox_new(TRUE
, 0);
3143 gtk_box_pack_end(GTK_BOX(vbox
), hbox
, FALSE
, FALSE
, 0);
3144 GtkWidget
*close_button
= gtk_button_new_with_mnemonic("_Close");
3145 gtk_box_pack_end(GTK_BOX(hbox
), close_button
, FALSE
, FALSE
, 0);
3146 gtk_container_set_border_width(GTK_CONTAINER(close_button
), 20);
3148 g_signal_connect(G_OBJECT(close_button
), "clicked",
3149 G_CALLBACK(on_about_close_activate
),
3150 (gpointer
)about_widget
);
3152 gtk_widget_show_all(about_widget
);
3157 on_button_new_clicked (GtkButton
*button
,
3160 create_new_window((GtkWidget
*)button
, user_data
, TRUE
);
3164 on_button_new_tab_clicked (GtkButton
*button
,
3167 create_new_tab((GtkWidget
*)button
, user_data
);
3171 on_button_open_clicked (GtkButton
*button
,
3174 open_traceset((GtkWidget
*)button
, user_data
);
3179 on_button_add_trace_clicked (GtkButton
*button
,
3182 add_trace((GtkWidget
*)button
, user_data
);
3187 on_button_remove_trace_clicked (GtkButton
*button
,
3190 remove_trace((GtkWidget
*)button
, user_data
);
3194 on_button_redraw_clicked (GtkButton
*button
,
3197 redraw((GtkWidget
*)button
, user_data
);
3201 on_button_continue_processing_clicked (GtkButton
*button
,
3204 continue_processing((GtkWidget
*)button
, user_data
);
3208 on_button_stop_processing_clicked (GtkButton
*button
,
3211 stop_processing((GtkWidget
*)button
, user_data
);
3217 on_button_save_clicked (GtkButton
*button
,
3220 save((GtkWidget
*)button
, user_data
);
3225 on_button_save_as_clicked (GtkButton
*button
,
3228 save_as((GtkWidget
*)button
, user_data
);
3233 on_button_zoom_in_clicked (GtkButton
*button
,
3236 zoom_in((GtkWidget
*)button
, user_data
);
3241 on_button_zoom_out_clicked (GtkButton
*button
,
3244 zoom_out((GtkWidget
*)button
, user_data
);
3249 on_button_zoom_extended_clicked (GtkButton
*button
,
3252 zoom_extended((GtkWidget
*)button
, user_data
);
3257 on_button_go_to_time_clicked (GtkButton
*button
,
3260 go_to_time((GtkWidget
*)button
, user_data
);
3265 on_button_show_time_frame_clicked (GtkButton
*button
,
3268 show_time_frame((GtkWidget
*)button
, user_data
);
3273 on_button_move_up_clicked (GtkButton
*button
,
3276 move_up_viewer((GtkWidget
*)button
, user_data
);
3281 on_button_move_down_clicked (GtkButton
*button
,
3284 move_down_viewer((GtkWidget
*)button
, user_data
);
3289 on_button_delete_viewer_clicked (GtkButton
*button
,
3292 delete_viewer((GtkWidget
*)button
, user_data
);
3296 on_MWindow_destroy (GtkWidget
*widget
,
3299 MainWindow
*main_window
= get_window_data_struct(widget
);
3300 LttvIAttribute
*attributes
= main_window
->attributes
;
3301 LttvAttributeValue value
;
3303 //This is unnecessary, since widgets will be destroyed
3304 //by the main window widget anyway.
3305 //remove_all_menu_toolbar_constructors(main_window, NULL);
3307 g_assert(lttv_iattribute_find_by_path(attributes
,
3308 "viewers/menu", LTTV_POINTER
, &value
));
3309 lttv_menus_destroy((LttvMenus
*)*(value
.v_pointer
));
3311 g_assert(lttv_iattribute_find_by_path(attributes
,
3312 "viewers/toolbar", LTTV_POINTER
, &value
));
3313 lttv_toolbars_destroy((LttvToolbars
*)*(value
.v_pointer
));
3315 g_object_unref(main_window
->attributes
);
3316 g_main_window_list
= g_slist_remove(g_main_window_list
, main_window
);
3318 g_info("There are now : %d windows\n",g_slist_length(g_main_window_list
));
3319 if(g_slist_length(g_main_window_list
) == 0)
3324 on_MWindow_configure (GtkWidget
*widget
,
3325 GdkEventConfigure
*event
,
3328 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)widget
);
3330 // MD : removed time width modification upon resizing of the main window.
3331 // The viewers will redraw themselves completely, without time interval
3334 if(mw_data->window_width){
3335 time_span = LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context)->Time_Span ;
3336 time_win = tab->time_window;
3337 ratio = width / mw_data->window_width;
3338 tab->time_window.time_width = ltt_time_mul(time_win.time_width,ratio);
3339 time = ltt_time_sub(time_span->endTime, time_win.start_time);
3340 if(ltt_time_compare(time, tab->time_window.time_width) < 0){
3341 tab->time_window.time_width = time;
3347 mw_data->window_width = (int)width;
3356 on_MNotebook_switch_page (GtkNotebook
*notebook
,
3357 GtkNotebookPage
*page
,
3365 void time_change_manager (Tab
*tab
,
3366 TimeWindow new_time_window
)
3368 /* Only one source of time change */
3369 if(tab
->time_manager_lock
== TRUE
) return;
3371 tab
->time_manager_lock
= TRUE
;
3373 LttvTracesetContext
*tsc
= LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3374 TimeInterval time_span
= tsc
->time_span
;
3375 LttTime start_time
= new_time_window
.start_time
;
3376 LttTime end_time
= new_time_window
.end_time
;
3377 LttTime time_width
= new_time_window
.time_width
;
3379 g_assert(ltt_time_compare(start_time
, end_time
) < 0);
3382 GtkAdjustment
*adjustment
= gtk_range_get_adjustment(GTK_RANGE(tab
->scrollbar
));
3383 LttTime upper
= ltt_time_sub(time_span
.end_time
, time_span
.start_time
);
3385 gtk_range_set_increments(GTK_RANGE(tab
->scrollbar
),
3386 ltt_time_to_double(new_time_window
.time_width
)
3387 / SCROLL_STEP_PER_PAGE
3388 * NANOSECONDS_PER_SECOND
, /* step increment */
3389 ltt_time_to_double(new_time_window
.time_width
)
3390 * NANOSECONDS_PER_SECOND
); /* page increment */
3391 gtk_range_set_range(GTK_RANGE(tab
->scrollbar
),
3393 ltt_time_to_double(upper
)
3394 * NANOSECONDS_PER_SECOND
); /* upper */
3396 g_object_set(G_OBJECT(adjustment
),
3400 ltt_time_to_double(upper
), /* upper */
3402 new_time_window
.time_width_double
3403 / SCROLL_STEP_PER_PAGE
, /* step increment */
3405 new_time_window
.time_width_double
,
3406 /* page increment */
3408 new_time_window
.time_width_double
, /* page size */
3410 gtk_adjustment_changed(adjustment
);
3412 // g_object_set(G_OBJECT(adjustment),
3414 // ltt_time_to_double(
3415 // ltt_time_sub(start_time, time_span.start_time))
3418 //gtk_adjustment_value_changed(adjustment);
3419 gtk_range_set_value(GTK_RANGE(tab
->scrollbar
),
3421 ltt_time_sub(start_time
, time_span
.start_time
)) /* value */);
3423 /* set the time bar. */
3425 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry1
),
3426 (double)time_span
.start_time
.tv_sec
,
3427 (double)time_span
.end_time
.tv_sec
);
3428 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry1
),
3429 (double)start_time
.tv_sec
);
3431 /* start nanoseconds */
3432 if(start_time
.tv_sec
== time_span
.start_time
.tv_sec
) {
3433 /* can be both beginning and end at the same time. */
3434 if(start_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3435 /* If we are at the end, max nsec to end.. -1 (not zero length) */
3436 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry2
),
3437 (double)time_span
.start_time
.tv_nsec
,
3438 (double)time_span
.end_time
.tv_nsec
-1);
3440 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry2
),
3441 (double)time_span
.start_time
.tv_nsec
,
3442 (double)NANOSECONDS_PER_SECOND
-1);
3444 } else if(start_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3445 /* If we are at the end, max nsec to end.. -1 (not zero length) */
3446 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry2
),
3448 (double)time_span
.end_time
.tv_nsec
-1);
3449 } else /* anywhere else */
3450 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry2
),
3452 (double)NANOSECONDS_PER_SECOND
-1);
3453 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry2
),
3454 (double)start_time
.tv_nsec
);
3457 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry3
),
3458 (double)time_span
.start_time
.tv_sec
,
3459 (double)time_span
.end_time
.tv_sec
);
3460 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry3
),
3461 (double)end_time
.tv_sec
);
3463 /* end nanoseconds */
3464 if(end_time
.tv_sec
== time_span
.start_time
.tv_sec
) {
3465 /* can be both beginning and end at the same time. */
3466 if(end_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3467 /* If we are at the end, max nsec to end.. */
3468 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry4
),
3469 (double)time_span
.start_time
.tv_nsec
+1,
3470 (double)time_span
.end_time
.tv_nsec
);
3472 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry4
),
3473 (double)time_span
.start_time
.tv_nsec
+1,
3474 (double)NANOSECONDS_PER_SECOND
-1);
3477 else if(end_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3478 /* If we are at the end, max nsec to end.. */
3479 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry4
),
3481 (double)time_span
.end_time
.tv_nsec
);
3483 else /* anywhere else */
3484 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry4
),
3486 (double)NANOSECONDS_PER_SECOND
-1);
3487 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry4
),
3488 (double)end_time
.tv_nsec
);
3491 if(time_width
.tv_nsec
== 0) {
3492 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry7
),
3494 (double)upper
.tv_sec
);
3496 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry7
),
3498 (double)upper
.tv_sec
);
3500 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry7
),
3501 (double)time_width
.tv_sec
);
3503 /* width nanoseconds */
3504 if(time_width
.tv_sec
== upper
.tv_sec
) {
3505 if(time_width
.tv_sec
== 0) {
3506 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry8
),
3508 (double)upper
.tv_nsec
);
3510 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry8
),
3512 (double)upper
.tv_nsec
);
3515 else if(time_width
.tv_sec
== 0) {
3516 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry8
),
3518 (double)upper
.tv_nsec
);
3520 else /* anywhere else */
3521 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry8
),
3523 (double)NANOSECONDS_PER_SECOND
-1);
3524 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry8
),
3525 (double)time_width
.tv_nsec
);
3527 /* call viewer hooks for new time window */
3528 set_time_window(tab
, &new_time_window
);
3530 tab
->time_manager_lock
= FALSE
;
3534 /* value changed for frame start s
3536 * Check time span : if ns is out of range, clip it the nearest good value.
3539 on_MEntry1_value_changed (GtkSpinButton
*spinbutton
,
3542 Tab
*tab
=(Tab
*)user_data
;
3543 LttvTracesetContext
* tsc
=
3544 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3545 TimeInterval time_span
= tsc
->time_span
;
3546 gint value
= gtk_spin_button_get_value_as_int(spinbutton
);
3548 TimeWindow new_time_window
= tab
->time_window
;
3550 LttTime end_time
= new_time_window
.end_time
;
3552 new_time_window
.start_time
.tv_sec
= value
;
3554 /* start nanoseconds */
3555 if(new_time_window
.start_time
.tv_sec
== time_span
.start_time
.tv_sec
) {
3556 if(new_time_window
.start_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3557 if(new_time_window
.start_time
.tv_nsec
> time_span
.end_time
.tv_nsec
)
3558 new_time_window
.start_time
.tv_nsec
= time_span
.end_time
.tv_nsec
-1;
3559 if(new_time_window
.start_time
.tv_nsec
< time_span
.start_time
.tv_nsec
)
3560 new_time_window
.start_time
.tv_nsec
= time_span
.start_time
.tv_nsec
;
3562 if(new_time_window
.start_time
.tv_nsec
< time_span
.start_time
.tv_nsec
)
3563 new_time_window
.start_time
.tv_nsec
= time_span
.start_time
.tv_nsec
;
3566 else if(new_time_window
.start_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3567 if(new_time_window
.start_time
.tv_nsec
> time_span
.end_time
.tv_nsec
)
3568 new_time_window
.start_time
.tv_nsec
= time_span
.end_time
.tv_nsec
-1;
3571 if(ltt_time_compare(new_time_window
.start_time
, end_time
) >= 0) {
3572 /* Then, we must push back end time : keep the same time width
3573 * if possible, else end traceset time */
3574 end_time
= LTT_TIME_MIN(ltt_time_add(new_time_window
.start_time
,
3575 new_time_window
.time_width
),
3576 time_span
.end_time
);
3579 /* Fix the time width to fit start time and end time */
3580 new_time_window
.time_width
= ltt_time_sub(end_time
,
3581 new_time_window
.start_time
);
3582 new_time_window
.time_width_double
=
3583 ltt_time_to_double(new_time_window
.time_width
);
3585 new_time_window
.end_time
= end_time
;
3587 time_change_manager(tab
, new_time_window
);
3592 on_MEntry2_value_changed (GtkSpinButton
*spinbutton
,
3595 Tab
*tab
=(Tab
*)user_data
;
3596 LttvTracesetContext
* tsc
=
3597 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3598 TimeInterval time_span
= tsc
->time_span
;
3599 gint value
= gtk_spin_button_get_value_as_int(spinbutton
);
3601 TimeWindow new_time_window
= tab
->time_window
;
3603 LttTime end_time
= new_time_window
.end_time
;
3605 new_time_window
.start_time
.tv_nsec
= value
;
3607 if(ltt_time_compare(new_time_window
.start_time
, end_time
) >= 0) {
3608 /* Then, we must push back end time : keep the same time width
3609 * if possible, else end traceset time */
3610 end_time
= LTT_TIME_MIN(ltt_time_add(new_time_window
.start_time
,
3611 new_time_window
.time_width
),
3612 time_span
.end_time
);
3615 /* Fix the time width to fit start time and end time */
3616 new_time_window
.time_width
= ltt_time_sub(end_time
,
3617 new_time_window
.start_time
);
3618 new_time_window
.time_width_double
=
3619 ltt_time_to_double(new_time_window
.time_width
);
3621 new_time_window
.end_time
= end_time
;
3623 time_change_manager(tab
, new_time_window
);
3628 on_MEntry3_value_changed (GtkSpinButton
*spinbutton
,
3631 Tab
*tab
=(Tab
*)user_data
;
3632 LttvTracesetContext
* tsc
=
3633 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3634 TimeInterval time_span
= tsc
->time_span
;
3635 gint value
= gtk_spin_button_get_value_as_int(spinbutton
);
3637 TimeWindow new_time_window
= tab
->time_window
;
3639 LttTime end_time
= new_time_window
.end_time
;
3641 end_time
.tv_sec
= value
;
3643 /* end nanoseconds */
3644 if(end_time
.tv_sec
== time_span
.start_time
.tv_sec
) {
3645 if(end_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3646 if(end_time
.tv_nsec
> time_span
.end_time
.tv_nsec
)
3647 end_time
.tv_nsec
= time_span
.end_time
.tv_nsec
;
3648 if(end_time
.tv_nsec
< time_span
.start_time
.tv_nsec
)
3649 end_time
.tv_nsec
= time_span
.start_time
.tv_nsec
+1;
3651 if(end_time
.tv_nsec
< time_span
.start_time
.tv_nsec
)
3652 end_time
.tv_nsec
= time_span
.start_time
.tv_nsec
+1;
3655 else if(end_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3656 if(end_time
.tv_nsec
> time_span
.end_time
.tv_nsec
)
3657 end_time
.tv_nsec
= time_span
.end_time
.tv_nsec
;
3660 if(ltt_time_compare(new_time_window
.start_time
, end_time
) >= 0) {
3661 /* Then, we must push front start time : keep the same time width
3662 * if possible, else end traceset time */
3663 new_time_window
.start_time
= LTT_TIME_MAX(
3664 ltt_time_sub(end_time
,
3665 new_time_window
.time_width
),
3666 time_span
.start_time
);
3669 /* Fix the time width to fit start time and end time */
3670 new_time_window
.time_width
= ltt_time_sub(end_time
,
3671 new_time_window
.start_time
);
3672 new_time_window
.time_width_double
=
3673 ltt_time_to_double(new_time_window
.time_width
);
3675 new_time_window
.end_time
= end_time
;
3677 time_change_manager(tab
, new_time_window
);
3682 on_MEntry4_value_changed (GtkSpinButton
*spinbutton
,
3685 Tab
*tab
=(Tab
*)user_data
;
3686 LttvTracesetContext
* tsc
=
3687 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3688 TimeInterval time_span
= tsc
->time_span
;
3689 gint value
= gtk_spin_button_get_value_as_int(spinbutton
);
3691 TimeWindow new_time_window
= tab
->time_window
;
3693 LttTime end_time
= new_time_window
.end_time
;
3695 end_time
.tv_nsec
= value
;
3697 if(ltt_time_compare(new_time_window
.start_time
, end_time
) >= 0) {
3698 /* Then, we must push front start time : keep the same time width
3699 * if possible, else end traceset time */
3700 new_time_window
.start_time
= LTT_TIME_MAX(
3701 ltt_time_sub(end_time
,
3702 new_time_window
.time_width
),
3703 time_span
.start_time
);
3706 /* Fix the time width to fit start time and end time */
3707 new_time_window
.time_width
= ltt_time_sub(end_time
,
3708 new_time_window
.start_time
);
3709 new_time_window
.time_width_double
=
3710 ltt_time_to_double(new_time_window
.time_width
);
3711 new_time_window
.end_time
= end_time
;
3713 time_change_manager(tab
, new_time_window
);
3717 /* value changed for time frame interval s
3719 * Check time span : if ns is out of range, clip it the nearest good value.
3722 on_MEntry7_value_changed (GtkSpinButton
*spinbutton
,
3725 Tab
*tab
=(Tab
*)user_data
;
3726 LttvTracesetContext
* tsc
=
3727 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3728 TimeInterval time_span
= tsc
->time_span
;
3729 gint value
= gtk_spin_button_get_value_as_int(spinbutton
);
3730 LttTime current_time
, time_delta
;
3731 TimeWindow new_time_window
= tab
->time_window
;
3732 current_time
= tab
->current_time
;
3734 time_delta
= ltt_time_sub(time_span
.end_time
,time_span
.start_time
);
3735 new_time_window
.time_width
.tv_sec
= value
;
3736 new_time_window
.time_width_double
=
3737 ltt_time_to_double(new_time_window
.time_width
);
3738 if(ltt_time_compare(new_time_window
.time_width
,time_delta
) > 0)
3739 { /* Case where zoom out is bigger than trace length */
3740 new_time_window
.start_time
= time_span
.start_time
;
3741 new_time_window
.time_width
= time_delta
;
3742 new_time_window
.time_width_double
= ltt_time_to_double(time_delta
);
3743 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
3744 new_time_window
.time_width
) ;
3748 /* Center the image on the current time */
3749 new_time_window
.start_time
=
3750 ltt_time_sub(current_time
,
3751 ltt_time_from_double(new_time_window
.time_width_double
/2.0));
3752 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
3753 new_time_window
.time_width
) ;
3754 /* If on borders, don't fall off */
3755 if(ltt_time_compare(new_time_window
.start_time
, time_span
.start_time
) <0
3756 || ltt_time_compare(new_time_window
.start_time
, time_span
.end_time
) >0)
3758 new_time_window
.start_time
= time_span
.start_time
;
3759 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
3760 new_time_window
.time_width
) ;
3764 if(ltt_time_compare(new_time_window
.end_time
,
3765 time_span
.end_time
) > 0
3766 || ltt_time_compare(new_time_window
.end_time
,
3767 time_span
.start_time
) < 0)
3769 new_time_window
.start_time
=
3770 ltt_time_sub(time_span
.end_time
, new_time_window
.time_width
);
3772 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
3773 new_time_window
.time_width
) ;
3779 if(ltt_time_compare(new_time_window
.time_width
, ltt_time_zero
) == 0) {
3780 g_warning("Zoom more than 1 ns impossible");
3782 time_change_manager(tab
, new_time_window
);
3787 on_MEntry8_value_changed (GtkSpinButton
*spinbutton
,
3790 Tab
*tab
=(Tab
*)user_data
;
3791 LttvTracesetContext
* tsc
=
3792 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3793 TimeInterval time_span
= tsc
->time_span
;
3794 gint value
= gtk_spin_button_get_value_as_int(spinbutton
);
3795 LttTime current_time
, time_delta
;
3796 TimeWindow new_time_window
= tab
->time_window
;
3797 current_time
= tab
->current_time
;
3799 time_delta
= ltt_time_sub(time_span
.end_time
,time_span
.start_time
);
3800 new_time_window
.time_width
.tv_nsec
= value
;
3801 new_time_window
.time_width_double
=
3802 ltt_time_to_double(new_time_window
.time_width
);
3803 if(ltt_time_compare(new_time_window
.time_width
,time_delta
) > 0)
3804 { /* Case where zoom out is bigger than trace length */
3805 new_time_window
.start_time
= time_span
.start_time
;
3806 new_time_window
.time_width
= time_delta
;
3807 new_time_window
.time_width_double
= ltt_time_to_double(time_delta
);
3808 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
3809 new_time_window
.time_width
) ;
3813 /* Center the image on the current time */
3814 new_time_window
.start_time
=
3815 ltt_time_sub(current_time
,
3816 ltt_time_from_double(new_time_window
.time_width_double
/2.0));
3817 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
3818 new_time_window
.time_width
) ;
3819 /* If on borders, don't fall off */
3820 if(ltt_time_compare(new_time_window
.start_time
, time_span
.start_time
) <0
3821 || ltt_time_compare(new_time_window
.start_time
, time_span
.end_time
) >0)
3823 new_time_window
.start_time
= time_span
.start_time
;
3824 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
3825 new_time_window
.time_width
) ;
3829 if(ltt_time_compare(new_time_window
.end_time
,
3830 time_span
.end_time
) > 0
3831 || ltt_time_compare(new_time_window
.end_time
,
3832 time_span
.start_time
) < 0)
3834 new_time_window
.start_time
=
3835 ltt_time_sub(time_span
.end_time
, new_time_window
.time_width
);
3837 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
3838 new_time_window
.time_width
) ;
3844 if(ltt_time_compare(new_time_window
.time_width
, ltt_time_zero
) == 0) {
3845 g_warning("Zoom more than 1 ns impossible");
3847 time_change_manager(tab
, new_time_window
);
3853 void current_time_change_manager (Tab
*tab
,
3854 LttTime new_current_time
)
3856 /* Only one source of time change */
3857 if(tab
->current_time_manager_lock
== TRUE
) return;
3859 tab
->current_time_manager_lock
= TRUE
;
3861 LttvTracesetContext
*tsc
= LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3862 TimeInterval time_span
= tsc
->time_span
;
3864 /* current seconds */
3865 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry5
),
3866 (double)time_span
.start_time
.tv_sec
,
3867 (double)time_span
.end_time
.tv_sec
);
3868 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry5
),
3869 (double)new_current_time
.tv_sec
);
3872 /* start nanoseconds */
3873 if(new_current_time
.tv_sec
== time_span
.start_time
.tv_sec
) {
3874 /* can be both beginning and end at the same time. */
3875 if(new_current_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3876 /* If we are at the end, max nsec to end.. */
3877 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry6
),
3878 (double)time_span
.start_time
.tv_nsec
,
3879 (double)time_span
.end_time
.tv_nsec
);
3881 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry6
),
3882 (double)time_span
.start_time
.tv_nsec
,
3883 (double)NANOSECONDS_PER_SECOND
-1);
3885 } else if(new_current_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3886 /* If we are at the end, max nsec to end.. */
3887 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry6
),
3889 (double)time_span
.end_time
.tv_nsec
);
3890 } else /* anywhere else */
3891 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry6
),
3893 (double)NANOSECONDS_PER_SECOND
-1);
3895 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry6
),
3896 (double)new_current_time
.tv_nsec
);
3898 set_current_time(tab
, &new_current_time
);
3900 tab
->current_time_manager_lock
= FALSE
;
3903 void current_position_change_manager(Tab
*tab
,
3904 LttvTracesetContextPosition
*pos
)
3906 LttvTracesetContext
*tsc
=
3907 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3908 TimeInterval time_span
= tsc
->time_span
;
3910 g_assert(lttv_process_traceset_seek_position(tsc
, pos
) == 0);
3911 LttTime new_time
= lttv_traceset_context_position_get_time(pos
);
3912 /* Put the context in a state coherent position */
3913 lttv_state_traceset_seek_time_closest((LttvTracesetState
*)tsc
, ltt_time_zero
);
3915 current_time_change_manager(tab
, new_time
);
3917 set_current_position(tab
, pos
);
3922 on_MEntry5_value_changed (GtkSpinButton
*spinbutton
,
3925 Tab
*tab
= (Tab
*)user_data
;
3926 LttvTracesetContext
* tsc
=
3927 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3928 TimeInterval time_span
= tsc
->time_span
;
3929 gint value
= gtk_spin_button_get_value_as_int(spinbutton
);
3930 LttTime new_current_time
= tab
->current_time
;
3931 new_current_time
.tv_sec
= value
;
3933 /* current nanoseconds */
3934 if(new_current_time
.tv_sec
== time_span
.start_time
.tv_sec
) {
3935 if(new_current_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3936 if(new_current_time
.tv_nsec
> time_span
.end_time
.tv_nsec
)
3937 new_current_time
.tv_nsec
= time_span
.end_time
.tv_nsec
;
3938 if(new_current_time
.tv_nsec
< time_span
.start_time
.tv_nsec
)
3939 new_current_time
.tv_nsec
= time_span
.start_time
.tv_nsec
;
3941 if(new_current_time
.tv_nsec
< time_span
.start_time
.tv_nsec
)
3942 new_current_time
.tv_nsec
= time_span
.start_time
.tv_nsec
;
3945 else if(new_current_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3946 if(new_current_time
.tv_nsec
> time_span
.end_time
.tv_nsec
)
3947 new_current_time
.tv_nsec
= time_span
.end_time
.tv_nsec
;
3950 current_time_change_manager(tab
, new_current_time
);
3954 on_MEntry6_value_changed (GtkSpinButton
*spinbutton
,
3957 Tab
*tab
= (Tab
*)user_data
;
3958 gint value
= gtk_spin_button_get_value_as_int(spinbutton
);
3959 LttTime new_current_time
= tab
->current_time
;
3960 new_current_time
.tv_nsec
= value
;
3962 current_time_change_manager(tab
, new_current_time
);
3966 void scroll_value_changed_cb(GtkWidget
*scrollbar
,
3969 Tab
*tab
= (Tab
*)user_data
;
3970 TimeWindow new_time_window
;
3972 GtkAdjustment
*adjust
= gtk_range_get_adjustment(GTK_RANGE(scrollbar
));
3973 gdouble value
= gtk_adjustment_get_value(adjust
);
3974 // gdouble upper, lower, ratio, page_size;
3976 LttvTracesetContext
* tsc
=
3977 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3978 TimeInterval time_span
= tsc
->time_span
;
3980 time
= ltt_time_add(ltt_time_from_double(value
),
3981 time_span
.start_time
);
3983 new_time_window
.start_time
= time
;
3985 page_size
= adjust
->page_size
;
3987 new_time_window
.time_width
=
3988 ltt_time_from_double(page_size
);
3990 new_time_window
.time_width_double
=
3993 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
3994 new_time_window
.time_width
);
3997 time_change_manager(tab
, new_time_window
);
3999 //time_window = tab->time_window;
4001 lower
= adjust
->lower
;
4002 upper
= adjust
->upper
;
4003 ratio
= (value
- lower
) / (upper
- lower
);
4004 g_info("lower %lu, upper %lu, value %lu, ratio %lu", lower
, upper
, value
, ratio
);
4006 //time = ltt_time_sub(time_span->end_time, time_span->start_time);
4007 //time = ltt_time_mul(time, (float)ratio);
4008 //time = ltt_time_add(time_span->start_time, time);
4009 time
= ltt_time_add(ltt_time_from_double(value
),
4010 time_span
.start_time
);
4012 time_window
.start_time
= time
;
4014 page_size
= adjust
->page_size
;
4016 time_window
.time_width
=
4017 ltt_time_from_double(page_size
);
4018 //time = ltt_time_sub(time_span.end_time, time);
4019 //if(ltt_time_compare(time,time_window.time_width) < 0){
4020 // time_window.time_width = time;
4023 /* call viewer hooks for new time window */
4024 set_time_window(tab
, &time_window
);
4029 /* Display a dialogue showing all eventtypes and traces, let user to select the interested
4030 * eventtypes, tracefiles and traces (filter)
4033 /* Select a trace which will be removed from traceset
4036 char * get_remove_trace(MainWindow
*mw_data
,
4037 char ** all_trace_name
, int nb_trace
)
4039 return get_selection(mw_data
, all_trace_name
, nb_trace
,
4040 "Select a trace", "Trace pathname");
4044 /* Select a module which will be loaded
4047 char * get_load_module(MainWindow
*mw_data
,
4048 char ** load_module_name
, int nb_module
)
4050 return get_selection(mw_data
, load_module_name
, nb_module
,
4051 "Select a module to load", "Module name");
4057 /* Select a module which will be unloaded
4060 char * get_unload_module(MainWindow
*mw_data
,
4061 char ** loaded_module_name
, int nb_module
)
4063 return get_selection(mw_data
, loaded_module_name
, nb_module
,
4064 "Select a module to unload", "Module name");
4068 /* Display a dialogue which shows all selectable items, let user to
4069 * select one of them
4072 char * get_selection(MainWindow
*mw_data
,
4073 char ** loaded_module_name
, int nb_module
,
4074 char *title
, char * column_title
)
4076 GtkWidget
* dialogue
;
4077 GtkWidget
* scroll_win
;
4079 GtkListStore
* store
;
4080 GtkTreeViewColumn
* column
;
4081 GtkCellRenderer
* renderer
;
4082 GtkTreeSelection
* select
;
4085 char * unload_module_name
= NULL
;
4087 dialogue
= gtk_dialog_new_with_buttons(title
,
4090 GTK_STOCK_OK
,GTK_RESPONSE_ACCEPT
,
4091 GTK_STOCK_CANCEL
,GTK_RESPONSE_REJECT
,
4093 gtk_window_set_default_size((GtkWindow
*)dialogue
, 500, 200);
4094 gtk_window_set_transient_for(GTK_WINDOW(dialogue
),
4095 GTK_WINDOW(mw_data
->mwindow
));
4097 scroll_win
= gtk_scrolled_window_new (NULL
, NULL
);
4098 gtk_widget_show ( scroll_win
);
4099 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll_win
),
4100 GTK_POLICY_AUTOMATIC
, GTK_POLICY_AUTOMATIC
);
4102 store
= gtk_list_store_new (N_COLUMNS
,G_TYPE_STRING
);
4103 tree
= gtk_tree_view_new_with_model(GTK_TREE_MODEL (store
));
4104 gtk_widget_show ( tree
);
4105 g_object_unref (G_OBJECT (store
));
4107 renderer
= gtk_cell_renderer_text_new ();
4108 column
= gtk_tree_view_column_new_with_attributes (column_title
,
4110 "text", MODULE_COLUMN
,
4112 gtk_tree_view_column_set_alignment (column
, 0.5);
4113 gtk_tree_view_column_set_fixed_width (column
, 150);
4114 gtk_tree_view_append_column (GTK_TREE_VIEW (tree
), column
);
4116 select
= gtk_tree_view_get_selection (GTK_TREE_VIEW (tree
));
4117 gtk_tree_selection_set_mode (select
, GTK_SELECTION_SINGLE
);
4119 gtk_container_add (GTK_CONTAINER (scroll_win
), tree
);
4121 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialogue
)->vbox
), scroll_win
,TRUE
, TRUE
,0);
4123 for(i
=0;i
<nb_module
;i
++){
4124 gtk_list_store_append (store
, &iter
);
4125 gtk_list_store_set (store
, &iter
, MODULE_COLUMN
,loaded_module_name
[i
],-1);
4128 id
= gtk_dialog_run(GTK_DIALOG(dialogue
));
4129 GtkTreeModel
**store_model
= (GtkTreeModel
**)&store
;
4131 case GTK_RESPONSE_ACCEPT
:
4132 case GTK_RESPONSE_OK
:
4133 if (gtk_tree_selection_get_selected (select
, store_model
, &iter
)){
4134 gtk_tree_model_get ((GtkTreeModel
*)store
, &iter
, MODULE_COLUMN
, &unload_module_name
, -1);
4136 case GTK_RESPONSE_REJECT
:
4137 case GTK_RESPONSE_CANCEL
:
4139 gtk_widget_destroy(dialogue
);
4143 return unload_module_name
;
4147 /* Insert all menu entry and tool buttons into this main window
4152 void add_all_menu_toolbar_constructors(MainWindow
* mw
, gpointer user_data
)
4156 lttvwindow_viewer_constructor constructor
;
4157 LttvMenus
* global_menu
, * instance_menu
;
4158 LttvToolbars
* global_toolbar
, * instance_toolbar
;
4159 LttvMenuClosure
*menu_item
;
4160 LttvToolbarClosure
*toolbar_item
;
4161 LttvAttributeValue value
;
4162 LttvIAttribute
*global_attributes
= LTTV_IATTRIBUTE(lttv_global_attributes());
4163 LttvIAttribute
*attributes
= mw
->attributes
;
4164 GtkWidget
* tool_menu_title_menu
, *new_widget
, *pixmap
;
4166 g_assert(lttv_iattribute_find_by_path(global_attributes
,
4167 "viewers/menu", LTTV_POINTER
, &value
));
4168 if(*(value
.v_pointer
) == NULL
)
4169 *(value
.v_pointer
) = lttv_menus_new();
4170 global_menu
= (LttvMenus
*)*(value
.v_pointer
);
4172 g_assert(lttv_iattribute_find_by_path(attributes
,
4173 "viewers/menu", LTTV_POINTER
, &value
));
4174 if(*(value
.v_pointer
) == NULL
)
4175 *(value
.v_pointer
) = lttv_menus_new();
4176 instance_menu
= (LttvMenus
*)*(value
.v_pointer
);
4180 g_assert(lttv_iattribute_find_by_path(global_attributes
,
4181 "viewers/toolbar", LTTV_POINTER
, &value
));
4182 if(*(value
.v_pointer
) == NULL
)
4183 *(value
.v_pointer
) = lttv_toolbars_new();
4184 global_toolbar
= (LttvToolbars
*)*(value
.v_pointer
);
4186 g_assert(lttv_iattribute_find_by_path(attributes
,
4187 "viewers/toolbar", LTTV_POINTER
, &value
));
4188 if(*(value
.v_pointer
) == NULL
)
4189 *(value
.v_pointer
) = lttv_toolbars_new();
4190 instance_toolbar
= (LttvToolbars
*)*(value
.v_pointer
);
4192 /* Add missing menu entries to window instance */
4193 for(i
=0;i
<global_menu
->len
;i
++) {
4194 menu_item
= &g_array_index(global_menu
, LttvMenuClosure
, i
);
4196 //add menu_item to window instance;
4197 constructor
= menu_item
->con
;
4198 tool_menu_title_menu
= lookup_widget(mw
->mwindow
,"ToolMenuTitle_menu");
4200 gtk_menu_item_new_with_mnemonic (menu_item
->menu_text
);
4201 gtk_container_add (GTK_CONTAINER (tool_menu_title_menu
),
4203 g_signal_connect ((gpointer
) new_widget
, "activate",
4204 G_CALLBACK (insert_viewer_wrap
),
4206 gtk_widget_show (new_widget
);
4207 lttv_menus_add(instance_menu
, menu_item
->con
,
4208 menu_item
->menu_path
,
4209 menu_item
->menu_text
,
4214 /* Add missing toolbar entries to window instance */
4215 for(i
=0;i
<global_toolbar
->len
;i
++) {
4216 toolbar_item
= &g_array_index(global_toolbar
, LttvToolbarClosure
, i
);
4218 //add toolbar_item to window instance;
4219 constructor
= toolbar_item
->con
;
4220 tool_menu_title_menu
= lookup_widget(mw
->mwindow
,"MToolbar1");
4221 pixbuf
= gdk_pixbuf_new_from_xpm_data((const char**)toolbar_item
->pixmap
);
4222 pixmap
= gtk_image_new_from_pixbuf(pixbuf
);
4224 gtk_toolbar_append_element (GTK_TOOLBAR (tool_menu_title_menu
),
4225 GTK_TOOLBAR_CHILD_BUTTON
,
4228 toolbar_item
->tooltip
, NULL
,
4229 pixmap
, NULL
, NULL
);
4230 gtk_label_set_use_underline(
4231 GTK_LABEL (((GtkToolbarChild
*) (
4232 g_list_last (GTK_TOOLBAR
4233 (tool_menu_title_menu
)->children
)->data
))->label
),
4235 gtk_container_set_border_width (GTK_CONTAINER (new_widget
), 1);
4236 g_signal_connect ((gpointer
) new_widget
,
4238 G_CALLBACK (insert_viewer_wrap
),
4240 gtk_widget_show (new_widget
);
4242 lttv_toolbars_add(instance_toolbar
, toolbar_item
->con
,
4243 toolbar_item
->tooltip
,
4244 toolbar_item
->pixmap
,
4252 /* Create a main window
4255 MainWindow
*construct_main_window(MainWindow
* parent
)
4257 g_debug("construct_main_window()");
4258 GtkWidget
* new_window
; /* New generated main window */
4259 MainWindow
* new_m_window
;/* New main window structure */
4260 GtkNotebook
* notebook
;
4261 LttvIAttribute
*attributes
=
4262 LTTV_IATTRIBUTE(g_object_new(LTTV_ATTRIBUTE_TYPE
, NULL
));
4263 LttvAttributeValue value
;
4266 new_m_window
= g_new(MainWindow
, 1);
4268 // Add the object's information to the module's array
4269 g_main_window_list
= g_slist_append(g_main_window_list
, new_m_window
);
4271 new_window
= create_MWindow();
4272 gtk_widget_show (new_window
);
4274 new_m_window
->mwindow
= new_window
;
4275 new_m_window
->attributes
= attributes
;
4277 g_assert(lttv_iattribute_find_by_path(attributes
,
4278 "viewers/menu", LTTV_POINTER
, &value
));
4279 *(value
.v_pointer
) = lttv_menus_new();
4281 g_assert(lttv_iattribute_find_by_path(attributes
,
4282 "viewers/toolbar", LTTV_POINTER
, &value
));
4283 *(value
.v_pointer
) = lttv_toolbars_new();
4285 add_all_menu_toolbar_constructors(new_m_window
, NULL
);
4287 g_object_set_data_full(G_OBJECT(new_window
),
4289 (gpointer
)new_m_window
,
4290 (GDestroyNotify
)g_free
);
4291 //create a default tab
4292 notebook
= (GtkNotebook
*)lookup_widget(new_m_window
->mwindow
, "MNotebook");
4293 if(notebook
== NULL
){
4294 g_info("Notebook does not exist\n");
4295 /* FIXME : destroy partially created widgets */
4296 g_free(new_m_window
);
4299 //gtk_notebook_popup_enable (GTK_NOTEBOOK(notebook));
4300 //for now there is no name field in LttvTraceset structure
4301 //Use "Traceset" as the label for the default tab
4303 GtkWidget
* parent_notebook
= lookup_widget(parent
->mwindow
, "MNotebook");
4304 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(parent_notebook
),
4305 gtk_notebook_get_current_page(GTK_NOTEBOOK(parent_notebook
)));
4311 LttvPluginTab
*ptab
;
4312 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
4313 parent_tab
= ptab
->tab
;
4315 LttvPluginTab
*ptab
= g_object_new(LTTV_TYPE_PLUGIN_TAB
, NULL
);
4317 new_m_window
, parent_tab
, notebook
, "Traceset");
4318 ptab
->parent
.top_widget
= ptab
->tab
->top_widget
;
4319 g_object_set_data_full(
4320 G_OBJECT(ptab
->tab
->vbox
),
4323 (GDestroyNotify
)tab_destructor
);
4324 new_tab
= ptab
->tab
;
4326 LttvPluginTab
*ptab
= g_object_new(LTTV_TYPE_PLUGIN_TAB
, NULL
);
4327 init_tab(ptab
->tab
, new_m_window
, NULL
, notebook
, "Traceset");
4328 ptab
->parent
.top_widget
= ptab
->tab
->top_widget
;
4329 g_object_set_data_full(
4330 G_OBJECT(ptab
->tab
->vbox
),
4333 (GDestroyNotify
)tab_destructor
);
4334 new_tab
= ptab
->tab
;
4337 /* Insert default viewers */
4339 LttvAttributeType type
;
4340 LttvAttributeName name
;
4341 LttvAttributeValue value
;
4342 LttvAttribute
*attribute
;
4344 LttvIAttribute
*attributes_global
=
4345 LTTV_IATTRIBUTE(lttv_global_attributes());
4347 g_assert(attribute
=
4348 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
4349 LTTV_IATTRIBUTE(attributes_global
),
4350 LTTV_VIEWER_CONSTRUCTORS
)));
4352 name
= g_quark_from_string("guievents");
4353 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
4355 if(type
== LTTV_POINTER
) {
4356 lttvwindow_viewer_constructor viewer_constructor
=
4357 (lttvwindow_viewer_constructor
)*value
.v_pointer
;
4358 insert_viewer(new_window
, viewer_constructor
);
4361 name
= g_quark_from_string("guicontrolflow");
4362 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
4364 if(type
== LTTV_POINTER
) {
4365 lttvwindow_viewer_constructor viewer_constructor
=
4366 (lttvwindow_viewer_constructor
)*value
.v_pointer
;
4367 insert_viewer(new_window
, viewer_constructor
);
4370 name
= g_quark_from_string("guistatistics");
4371 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
4373 if(type
== LTTV_POINTER
) {
4374 lttvwindow_viewer_constructor viewer_constructor
=
4375 (lttvwindow_viewer_constructor
)*value
.v_pointer
;
4376 insert_viewer(new_window
, viewer_constructor
);
4380 g_info("There are now : %d windows\n",g_slist_length(g_main_window_list
));
4382 return new_m_window
;
4386 /* Free the memory occupied by a tab structure
4390 void tab_destructor(LttvPluginTab
* ptab
)
4392 int i
, nb
, ref_count
;
4394 Tab
*tab
= ptab
->tab
;
4396 gtk_object_destroy(GTK_OBJECT(tab
->tooltips
));
4399 g_object_unref(tab
->attributes
);
4401 if(tab
->interrupted_state
)
4402 g_object_unref(tab
->interrupted_state
);
4405 if(tab
->traceset_info
->traceset_context
!= NULL
){
4406 //remove state update hooks
4407 lttv_state_remove_event_hooks(
4408 (LttvTracesetState
*)tab
->traceset_info
->
4410 lttv_context_fini(LTTV_TRACESET_CONTEXT(tab
->traceset_info
->
4412 g_object_unref(tab
->traceset_info
->traceset_context
);
4414 if(tab
->traceset_info
->traceset
!= NULL
) {
4415 nb
= lttv_traceset_number(tab
->traceset_info
->traceset
);
4416 for(i
= 0 ; i
< nb
; i
++) {
4417 trace
= lttv_traceset_get(tab
->traceset_info
->traceset
, i
);
4418 ref_count
= lttv_trace_get_ref_number(trace
);
4420 ltt_trace_close(lttv_trace(trace
));
4424 lttv_traceset_destroy(tab
->traceset_info
->traceset
);
4425 /* Remove the idle events requests processing function of the tab */
4426 g_idle_remove_by_data(tab
);
4428 g_slist_free(tab
->events_requests
);
4429 g_free(tab
->traceset_info
);
4431 g_object_unref(ptab
);
4435 /* Create a tab and insert it into the current main window
4438 void init_tab(Tab
*tab
, MainWindow
* mw
, Tab
*copy_tab
,
4439 GtkNotebook
* notebook
, char * label
)
4443 //LttvFilter *filter = NULL;
4445 //create a new tab data structure
4446 //tab = g_new(Tab,1);
4448 //construct and initialize the traceset_info
4449 tab
->traceset_info
= g_new(TracesetInfo
,1);
4452 tab
->traceset_info
->traceset
=
4453 lttv_traceset_copy(copy_tab
->traceset_info
->traceset
);
4455 /* Copy the previous tab's filter */
4456 /* We can clone the filter, as we copy the trace set also */
4457 /* The filter must always be in sync with the trace set */
4458 tab
->filter
= lttv_filter_clone(copy_tab
->filter
);
4460 tab
->traceset_info
->traceset
= lttv_traceset_new();
4464 lttv_attribute_write_xml(
4465 lttv_traceset_attribute(tab
->traceset_info
->traceset
),
4471 tab
->time_manager_lock
= FALSE
;
4472 tab
->current_time_manager_lock
= FALSE
;
4474 //FIXME copy not implemented in lower level
4475 tab
->traceset_info
->traceset_context
=
4476 g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
4477 g_assert(tab
->traceset_info
->traceset_context
!= NULL
);
4479 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
),
4480 tab
->traceset_info
->traceset
);
4481 //add state update hooks
4482 lttv_state_add_event_hooks(
4483 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
4485 //determine the current_time and time_window of the tab
4487 if(copy_tab
!= NULL
){
4488 tab
->time_window
= copy_tab
->time_window
;
4489 tab
->current_time
= copy_tab
->current_time
;
4491 tab
->time_window
.start_time
=
4492 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
4493 time_span
.start_time
;
4494 if(DEFAULT_TIME_WIDTH_S
<
4495 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
4496 time_span
.end_time
.tv_sec
)
4497 tmp_time
.tv_sec
= DEFAULT_TIME_WIDTH_S
;
4500 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
4501 time_span
.end_time
.tv_sec
;
4502 tmp_time
.tv_nsec
= 0;
4503 tab
->time_window
.time_width
= tmp_time
;
4504 tab
->current_time
.tv_sec
=
4505 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
4506 time_span
.start_time
.tv_sec
;
4507 tab
->current_time
.tv_nsec
=
4508 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
4509 time_span
.start_time
.tv_nsec
;
4512 tab
->attributes
= LTTV_IATTRIBUTE(g_object_new(LTTV_ATTRIBUTE_TYPE
, NULL
));
4513 tab
->interrupted_state
= g_object_new(LTTV_ATTRIBUTE_TYPE
, NULL
);
4515 tab
->vbox
= gtk_vbox_new(FALSE
, 2);
4516 tab
->top_widget
= tab
->vbox
;
4517 //g_object_set_data_full(G_OBJECT(tab->top_widget), "filter",
4518 // filter, (GDestroyNotify)lttv_filter_destroy);
4520 // g_signal_connect (G_OBJECT(tab->top_widget),
4522 // G_CALLBACK (on_top_notify),
4525 tab
->viewer_container
= gtk_vbox_new(TRUE
, 2);
4526 tab
->scrollbar
= gtk_hscrollbar_new(NULL
);
4527 //tab->multivpaned = gtk_multi_vpaned_new();
4529 gtk_box_pack_start(GTK_BOX(tab
->vbox
),
4530 tab
->viewer_container
,
4532 TRUE
, /* Give the extra space to the child */
4533 0); /* No padding */
4536 // tab->time_window = copy_tab->time_window;
4537 // tab->current_time = copy_tab->current_time;
4540 /* Create the timebar */
4542 tab
->MTimebar
= gtk_hbox_new(FALSE
, 2);
4543 gtk_widget_show(tab
->MTimebar
);
4544 tab
->tooltips
= gtk_tooltips_new();
4546 tab
->MEventBox1a
= gtk_event_box_new();
4547 gtk_widget_show(tab
->MEventBox1a
);
4548 gtk_tooltips_set_tip(tab
->tooltips
, tab
->MEventBox1a
,
4549 "Paste Start and End Times Here", "");
4550 tab
->MText1a
= gtk_label_new("Time Frame ");
4551 gtk_widget_show(tab
->MText1a
);
4552 gtk_container_add(GTK_CONTAINER(tab
->MEventBox1a
), tab
->MText1a
);
4553 tab
->MEventBox1b
= gtk_event_box_new();
4554 gtk_widget_show(tab
->MEventBox1b
);
4555 gtk_tooltips_set_tip(tab
->tooltips
, tab
->MEventBox1b
,
4556 "Paste Start Time Here", "");
4557 tab
->MText1b
= gtk_label_new("start: ");
4558 gtk_widget_show(tab
->MText1b
);
4559 gtk_container_add(GTK_CONTAINER(tab
->MEventBox1b
), tab
->MText1b
);
4560 tab
->MText2
= gtk_label_new("s");
4561 gtk_widget_show(tab
->MText2
);
4562 tab
->MText3a
= gtk_label_new("ns");
4563 gtk_widget_show(tab
->MText3a
);
4565 tab
->MEventBox3b
= gtk_event_box_new();
4566 gtk_widget_show(tab
->MEventBox3b
);
4567 gtk_tooltips_set_tip(tab
->tooltips
, tab
->MEventBox3b
,
4568 "Paste End Time Here", "");
4569 tab
->MText3b
= gtk_label_new("end:");
4570 gtk_widget_show(tab
->MText3b
);
4571 gtk_container_add(GTK_CONTAINER(tab
->MEventBox3b
), tab
->MText3b
);
4572 tab
->MText4
= gtk_label_new("s");
4573 gtk_widget_show(tab
->MText4
);
4574 tab
->MText5a
= gtk_label_new("ns");
4575 gtk_widget_show(tab
->MText5a
);
4577 tab
->MEventBox8
= gtk_event_box_new();
4578 gtk_widget_show(tab
->MEventBox8
);
4579 gtk_tooltips_set_tip(tab
->tooltips
, tab
->MEventBox8
,
4580 "Paste Time Interval here", "");
4581 tab
->MText8
= gtk_label_new("Time Interval:");
4582 gtk_widget_show(tab
->MText8
);
4583 gtk_container_add(GTK_CONTAINER(tab
->MEventBox8
), tab
->MText8
);
4584 tab
->MText9
= gtk_label_new("s");
4585 gtk_widget_show(tab
->MText9
);
4586 tab
->MText10
= gtk_label_new("ns");
4587 gtk_widget_show(tab
->MText10
);
4589 tab
->MEventBox5b
= gtk_event_box_new();
4590 gtk_widget_show(tab
->MEventBox5b
);
4591 gtk_tooltips_set_tip(tab
->tooltips
, tab
->MEventBox5b
,
4592 "Paste Current Time Here", "");
4593 tab
->MText5b
= gtk_label_new("Current Time:");
4594 gtk_widget_show(tab
->MText5b
);
4595 gtk_container_add(GTK_CONTAINER(tab
->MEventBox5b
), tab
->MText5b
);
4596 tab
->MText6
= gtk_label_new("s");
4597 gtk_widget_show(tab
->MText6
);
4598 tab
->MText7
= gtk_label_new("ns");
4599 gtk_widget_show(tab
->MText7
);
4601 tab
->MEntry1
= gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4602 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab
->MEntry1
),0);
4603 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab
->MEntry1
),TRUE
);
4604 gtk_widget_show(tab
->MEntry1
);
4605 tab
->MEntry2
= gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4606 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab
->MEntry2
),0);
4607 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab
->MEntry2
),TRUE
);
4608 gtk_widget_show(tab
->MEntry2
);
4609 tab
->MEntry3
= gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4610 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab
->MEntry3
),0);
4611 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab
->MEntry3
),TRUE
);
4612 gtk_widget_show(tab
->MEntry3
);
4613 tab
->MEntry4
= gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4614 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab
->MEntry4
),0);
4615 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab
->MEntry4
),TRUE
);
4616 gtk_widget_show(tab
->MEntry4
);
4617 tab
->MEntry5
= gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4618 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab
->MEntry5
),0);
4619 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab
->MEntry5
),TRUE
);
4620 gtk_widget_show(tab
->MEntry5
);
4621 tab
->MEntry6
= gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4622 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab
->MEntry6
),0);
4623 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab
->MEntry6
),TRUE
);
4624 gtk_widget_show(tab
->MEntry6
);
4625 tab
->MEntry7
= gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4626 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab
->MEntry7
),0);
4627 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab
->MEntry7
),TRUE
);
4628 gtk_widget_show(tab
->MEntry7
);
4629 tab
->MEntry8
= gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4630 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab
->MEntry8
),0);
4631 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab
->MEntry8
),TRUE
);
4632 gtk_widget_show(tab
->MEntry8
);
4634 GtkWidget
*temp_widget
;
4636 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEventBox1a
, FALSE
,
4638 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEventBox1b
, FALSE
,
4640 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEntry1
, FALSE
, FALSE
, 0);
4641 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MText2
, FALSE
, FALSE
, 0);
4642 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEntry2
, FALSE
, FALSE
, 0);
4643 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MText3a
, FALSE
, FALSE
, 0);
4644 temp_widget
= gtk_vseparator_new();
4645 gtk_widget_show(temp_widget
);
4646 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), temp_widget
, FALSE
, FALSE
, 0);
4647 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEventBox3b
, FALSE
,
4649 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEntry3
, FALSE
, FALSE
, 0);
4650 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MText4
, FALSE
, FALSE
, 0);
4651 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEntry4
, FALSE
, FALSE
, 0);
4652 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MText5a
, FALSE
, FALSE
, 0);
4653 temp_widget
= gtk_vseparator_new();
4654 gtk_widget_show(temp_widget
);
4655 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), temp_widget
, FALSE
, FALSE
, 0);
4656 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEventBox8
, FALSE
,
4658 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEntry7
, FALSE
, FALSE
, 0);
4659 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MText9
, FALSE
, FALSE
, 0);
4660 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEntry8
, FALSE
, FALSE
, 0);
4661 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MText10
, FALSE
, FALSE
, 0);
4663 temp_widget
= gtk_vseparator_new();
4664 gtk_widget_show(temp_widget
);
4665 gtk_box_pack_end (GTK_BOX (tab
->MTimebar
), tab
->MText7
, FALSE
, FALSE
, 0);
4666 gtk_box_pack_end (GTK_BOX (tab
->MTimebar
), tab
->MEntry6
, FALSE
, FALSE
, 0);
4667 gtk_box_pack_end (GTK_BOX (tab
->MTimebar
), tab
->MText6
, FALSE
, FALSE
, 0);
4668 gtk_box_pack_end (GTK_BOX (tab
->MTimebar
), tab
->MEntry5
, FALSE
, FALSE
, 0);
4669 gtk_box_pack_end (GTK_BOX (tab
->MTimebar
), tab
->MEventBox5b
, FALSE
,
4671 gtk_box_pack_end (GTK_BOX (tab
->MTimebar
), temp_widget
, FALSE
, FALSE
, 0);
4674 //GtkWidget *test = gtk_button_new_with_label("drop");
4675 //gtk_button_set_relief(GTK_BUTTON(test), GTK_RELIEF_NONE);
4676 //gtk_widget_show(test);
4677 //gtk_box_pack_end(GTK_BOX (tab->MTimebar), test, FALSE, FALSE, 0);
4678 //gtk_widget_add_events(tab->MText1, GDK_ALL_EVENTS_MASK);//GDK_BUTTON_PRESS_MASK);
4679 /*GtkWidget *event_box = gtk_event_box_new();
4680 gtk_widget_show(event_box);
4681 gtk_tooltips_set_tip(tooltips, event_box,
4682 "Paste Current Time Here", "");
4683 gtk_box_pack_end(GTK_BOX (tab->MTimebar), event_box, FALSE, FALSE, 0);
4684 GtkWidget *test = gtk_label_new("drop");
4685 gtk_container_add(GTK_CONTAINER(event_box), test);
4686 gtk_widget_show(test);
4687 g_signal_connect (G_OBJECT(event_box),
4688 "button-press-event",
4689 G_CALLBACK (on_MText1_paste),
4693 g_signal_connect (G_OBJECT(tab
->MEventBox1a
),
4694 "button-press-event",
4695 G_CALLBACK (on_MEventBox1a_paste
),
4698 g_signal_connect (G_OBJECT(tab
->MEventBox1b
),
4699 "button-press-event",
4700 G_CALLBACK (on_MEventBox1b_paste
),
4702 g_signal_connect (G_OBJECT(tab
->MEventBox3b
),
4703 "button-press-event",
4704 G_CALLBACK (on_MEventBox3b_paste
),
4706 g_signal_connect (G_OBJECT(tab
->MEventBox5b
),
4707 "button-press-event",
4708 G_CALLBACK (on_MEventBox5b_paste
),
4710 g_signal_connect (G_OBJECT(tab
->MEventBox8
),
4711 "button-press-event",
4712 G_CALLBACK (on_MEventBox8_paste
),
4716 gtk_box_pack_end(GTK_BOX(tab
->vbox
),
4718 FALSE
, /* Do not expand */
4719 FALSE
, /* Fill has no effect here (expand false) */
4720 0); /* No padding */
4722 gtk_box_pack_end(GTK_BOX(tab
->vbox
),
4724 FALSE
, /* Do not expand */
4725 FALSE
, /* Fill has no effect here (expand false) */
4726 0); /* No padding */
4728 g_object_set_data(G_OBJECT(tab
->viewer_container
), "focused_viewer", NULL
);
4734 // Display a label with a X
4735 GtkWidget *w_hbox = gtk_hbox_new(FALSE, 4);
4736 GtkWidget *w_label = gtk_label_new (label);
4737 GtkWidget *pixmap = create_pixmap(GTK_WIDGET(notebook), "close.png");
4738 GtkWidget *w_button = gtk_button_new ();
4739 gtk_container_add(GTK_CONTAINER(w_button), pixmap);
4740 //GtkWidget *w_button = gtk_button_new_with_label("x");
4742 gtk_button_set_relief(GTK_BUTTON(w_button), GTK_RELIEF_NONE);
4744 gtk_box_pack_start(GTK_BOX(w_hbox), w_label, TRUE, TRUE, 0);
4745 gtk_box_pack_end(GTK_BOX(w_hbox), w_button, FALSE,
4748 g_signal_connect_swapped (w_button, "clicked",
4749 G_CALLBACK (on_close_tab_X_clicked),
4752 gtk_widget_set_state(w_button, GTK_STATE_ACTIVE);
4754 gtk_widget_show (w_label);
4755 gtk_widget_show (pixmap);
4756 gtk_widget_show (w_button);
4757 gtk_widget_show (w_hbox);
4759 tab->label = w_hbox;
4763 tab
->label
= gtk_label_new (label
);
4765 gtk_widget_show(tab
->label
);
4766 gtk_widget_show(tab
->scrollbar
);
4767 gtk_widget_show(tab
->viewer_container
);
4768 gtk_widget_show(tab
->vbox
);
4769 //gtk_widget_show(tab->multivpaned);
4772 /* Start with empty events requests list */
4773 tab
->events_requests
= NULL
;
4774 tab
->events_request_pending
= FALSE
;
4775 tab
->stop_foreground
= FALSE
;
4779 g_signal_connect(G_OBJECT(tab
->scrollbar
), "value-changed",
4780 G_CALLBACK(scroll_value_changed_cb
), tab
);
4782 g_signal_connect ((gpointer
) tab
->MEntry1
, "value-changed",
4783 G_CALLBACK (on_MEntry1_value_changed
),
4785 g_signal_connect ((gpointer
) tab
->MEntry2
, "value-changed",
4786 G_CALLBACK (on_MEntry2_value_changed
),
4788 g_signal_connect ((gpointer
) tab
->MEntry3
, "value-changed",
4789 G_CALLBACK (on_MEntry3_value_changed
),
4791 g_signal_connect ((gpointer
) tab
->MEntry4
, "value-changed",
4792 G_CALLBACK (on_MEntry4_value_changed
),
4794 g_signal_connect ((gpointer
) tab
->MEntry5
, "value-changed",
4795 G_CALLBACK (on_MEntry5_value_changed
),
4797 g_signal_connect ((gpointer
) tab
->MEntry6
, "value-changed",
4798 G_CALLBACK (on_MEntry6_value_changed
),
4800 g_signal_connect ((gpointer
) tab
->MEntry7
, "value-changed",
4801 G_CALLBACK (on_MEntry7_value_changed
),
4803 g_signal_connect ((gpointer
) tab
->MEntry8
, "value-changed",
4804 G_CALLBACK (on_MEntry8_value_changed
),
4807 //g_signal_connect(G_OBJECT(tab->scrollbar), "changed",
4808 // G_CALLBACK(scroll_value_changed_cb), tab);
4811 //insert tab into notebook
4812 gtk_notebook_append_page(notebook
,
4815 list
= gtk_container_get_children(GTK_CONTAINER(notebook
));
4816 gtk_notebook_set_current_page(notebook
,g_list_length(list
)-1);
4817 // always show : not if(g_list_length(list)>1)
4818 gtk_notebook_set_show_tabs(notebook
, TRUE
);
4821 lttvwindow_report_time_window(tab
, copy_tab
->time_window
);
4822 lttvwindow_report_current_time(tab
, copy_tab
->current_time
);
4824 TimeWindow time_window
;
4826 time_window
.start_time
= ltt_time_zero
;
4827 time_window
.end_time
= ltt_time_add(time_window
.start_time
,
4828 lttvwindow_default_time_width
);
4829 time_window
.time_width
= lttvwindow_default_time_width
;
4830 time_window
.time_width_double
= ltt_time_to_double(time_window
.time_width
);
4832 lttvwindow_report_time_window(tab
, time_window
);
4833 lttvwindow_report_current_time(tab
, ltt_time_zero
);
4836 LttvTraceset
*traceset
= tab
->traceset_info
->traceset
;
4837 SetTraceset(tab
, traceset
);
4841 * execute_events_requests
4843 * Idle function that executes the pending requests for a tab.
4845 * @return return value : TRUE : keep the idle function, FALSE : remove it.
4847 gboolean
execute_events_requests(Tab
*tab
)
4849 return ( lttvwindow_process_pending_requests(tab
) );
4853 void create_main_window_with_trace_list(GSList
*traces
)
4855 GSList
*iter
= NULL
;
4858 MainWindow
*mw
= construct_main_window(NULL
);
4859 GtkWidget
*widget
= mw
->mwindow
;
4861 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
4862 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
4863 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
4864 LttvPluginTab
*ptab
;
4868 ptab
= create_new_tab(widget
, NULL
);
4871 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
4875 for(iter
=traces
; iter
!=NULL
; iter
=g_slist_next(iter
)) {
4876 gchar
*path
= (gchar
*)iter
->data
;
4878 gchar abs_path
[PATH_MAX
];
4882 get_absolute_pathname(path
, abs_path
);
4883 trace_v
= lttvwindowtraces_get_trace_by_name(abs_path
);
4884 if(trace_v
== NULL
) {
4885 trace
= ltt_trace_open(abs_path
);
4887 g_warning("cannot open trace %s", abs_path
);
4889 GtkWidget
*dialogue
=
4890 gtk_message_dialog_new(
4891 GTK_WINDOW(gtk_widget_get_toplevel(widget
)),
4892 GTK_DIALOG_MODAL
|GTK_DIALOG_DESTROY_WITH_PARENT
,
4895 "Cannot open trace : maybe you should enter in the directory"
4897 gtk_dialog_run(GTK_DIALOG(dialogue
));
4898 gtk_widget_destroy(dialogue
);
4900 trace_v
= lttv_trace_new(trace
);
4901 lttvwindowtraces_add_trace(trace_v
);
4902 lttvwindow_add_trace(tab
, trace_v
);
4905 lttvwindow_add_trace(tab
, trace_v
);
4909 LttvTraceset
*traceset
;
4911 traceset
= tab
->traceset_info
->traceset
;
4912 SetTraceset(tab
, traceset
);