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 g_idle_remove_by_data(tab
);
2172 g_assert(g_slist_length(tab
->events_requests
) == 0);
2176 /* save will save the traceset to a file
2177 * Not implemented yet FIXME
2180 void save(GtkWidget
* widget
, gpointer user_data
)
2185 void save_as(GtkWidget
* widget
, gpointer user_data
)
2187 g_info("Save as\n");
2191 /* zoom will change the time_window of all the viewers of the
2192 * current tab, and redisplay them. The main functionality is to
2193 * determine the new time_window of the current tab
2196 void zoom(GtkWidget
* widget
, double size
)
2198 TimeInterval time_span
;
2199 TimeWindow new_time_window
;
2200 LttTime current_time
, time_delta
;
2201 MainWindow
* mw_data
= get_window_data_struct(widget
);
2202 LttvTracesetContext
*tsc
;
2203 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
2205 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2206 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2212 LttvPluginTab
*ptab
;
2213 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
2217 if(size
== 1) return;
2219 tsc
= LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
2220 time_span
= tsc
->time_span
;
2221 new_time_window
= tab
->time_window
;
2222 current_time
= tab
->current_time
;
2224 time_delta
= ltt_time_sub(time_span
.end_time
,time_span
.start_time
);
2226 new_time_window
.start_time
= time_span
.start_time
;
2227 new_time_window
.time_width
= time_delta
;
2228 new_time_window
.time_width_double
= ltt_time_to_double(time_delta
);
2229 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
2230 new_time_window
.time_width
) ;
2232 new_time_window
.time_width
= ltt_time_div(new_time_window
.time_width
, size
);
2233 new_time_window
.time_width_double
=
2234 ltt_time_to_double(new_time_window
.time_width
);
2235 if(ltt_time_compare(new_time_window
.time_width
,time_delta
) > 0)
2236 { /* Case where zoom out is bigger than trace length */
2237 new_time_window
.start_time
= time_span
.start_time
;
2238 new_time_window
.time_width
= time_delta
;
2239 new_time_window
.time_width_double
= ltt_time_to_double(time_delta
);
2240 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
2241 new_time_window
.time_width
) ;
2245 /* Center the image on the current time */
2246 new_time_window
.start_time
=
2247 ltt_time_sub(current_time
,
2248 ltt_time_from_double(new_time_window
.time_width_double
/2.0));
2249 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
2250 new_time_window
.time_width
) ;
2251 /* If on borders, don't fall off */
2252 if(ltt_time_compare(new_time_window
.start_time
, time_span
.start_time
) <0
2253 || ltt_time_compare(new_time_window
.start_time
, time_span
.end_time
) >0)
2255 new_time_window
.start_time
= time_span
.start_time
;
2256 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
2257 new_time_window
.time_width
) ;
2261 if(ltt_time_compare(new_time_window
.end_time
,
2262 time_span
.end_time
) > 0
2263 || ltt_time_compare(new_time_window
.end_time
,
2264 time_span
.start_time
) < 0)
2266 new_time_window
.start_time
=
2267 ltt_time_sub(time_span
.end_time
, new_time_window
.time_width
);
2269 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
2270 new_time_window
.time_width
) ;
2277 if(ltt_time_compare(new_time_window
.time_width
, ltt_time_zero
) == 0) {
2278 g_warning("Zoom more than 1 ns impossible");
2280 time_change_manager(tab
, new_time_window
);
2284 void zoom_in(GtkWidget
* widget
, gpointer user_data
)
2289 void zoom_out(GtkWidget
* widget
, gpointer user_data
)
2294 void zoom_extended(GtkWidget
* widget
, gpointer user_data
)
2299 void go_to_time(GtkWidget
* widget
, gpointer user_data
)
2301 g_info("Go to time\n");
2304 void show_time_frame(GtkWidget
* widget
, gpointer user_data
)
2306 g_info("Show time frame\n");
2310 /* callback function */
2313 on_empty_traceset_activate (GtkMenuItem
*menuitem
,
2316 create_new_window((GtkWidget
*)menuitem
, user_data
, FALSE
);
2321 on_clone_traceset_activate (GtkMenuItem
*menuitem
,
2324 create_new_window((GtkWidget
*)menuitem
, user_data
, TRUE
);
2328 /* create_new_tab calls create_tab to construct a new tab in the main window
2331 LttvPluginTab
*create_new_tab(GtkWidget
* widget
, gpointer user_data
)
2333 gchar label
[PATH_MAX
];
2334 MainWindow
* mw_data
= get_window_data_struct(widget
);
2336 GtkNotebook
* notebook
= (GtkNotebook
*)lookup_widget(widget
, "MNotebook");
2337 if(notebook
== NULL
){
2338 g_info("Notebook does not exist\n");
2341 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2342 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2348 LttvPluginTab
*ptab
;
2349 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
2350 copy_tab
= ptab
->tab
;
2353 strcpy(label
,"Page");
2354 if(get_label(mw_data
, label
,"Get the name of the tab","Please input tab's name")) {
2355 LttvPluginTab
*ptab
;
2357 ptab
= g_object_new(LTTV_TYPE_PLUGIN_TAB
, NULL
);
2358 init_tab (ptab
->tab
, mw_data
, copy_tab
, notebook
, label
);
2359 ptab
->parent
.top_widget
= ptab
->tab
->top_widget
;
2360 g_object_set_data_full(
2361 G_OBJECT(ptab
->tab
->vbox
),
2364 (GDestroyNotify
)tab_destructor
);
2371 on_tab_activate (GtkMenuItem
*menuitem
,
2374 create_new_tab((GtkWidget
*)menuitem
, user_data
);
2379 on_open_activate (GtkMenuItem
*menuitem
,
2382 open_traceset((GtkWidget
*)menuitem
, user_data
);
2387 on_close_activate (GtkMenuItem
*menuitem
,
2390 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2391 main_window_destructor(mw_data
);
2395 /* remove the current tab from the main window
2399 on_close_tab_activate (GtkWidget
*widget
,
2403 GtkWidget
* notebook
;
2405 MainWindow
* mw_data
= get_window_data_struct(widget
);
2406 notebook
= lookup_widget(widget
, "MNotebook");
2407 if(notebook
== NULL
){
2408 g_info("Notebook does not exist\n");
2412 page_num
= gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
));
2414 gtk_notebook_remove_page(GTK_NOTEBOOK(notebook
), page_num
);
2419 on_close_tab_X_clicked (GtkWidget
*widget
,
2423 GtkWidget
*notebook
= lookup_widget(widget
, "MNotebook");
2424 if(notebook
== NULL
){
2425 g_info("Notebook does not exist\n");
2429 if((page_num
= gtk_notebook_page_num(GTK_NOTEBOOK(notebook
), widget
)) != -1)
2430 gtk_notebook_remove_page(GTK_NOTEBOOK(notebook
), page_num
);
2436 on_add_trace_activate (GtkMenuItem
*menuitem
,
2439 add_trace((GtkWidget
*)menuitem
, user_data
);
2444 on_remove_trace_activate (GtkMenuItem
*menuitem
,
2447 remove_trace((GtkWidget
*)menuitem
, user_data
);
2452 on_save_activate (GtkMenuItem
*menuitem
,
2455 save((GtkWidget
*)menuitem
, user_data
);
2460 on_save_as_activate (GtkMenuItem
*menuitem
,
2463 save_as((GtkWidget
*)menuitem
, user_data
);
2468 on_quit_activate (GtkMenuItem
*menuitem
,
2476 on_cut_activate (GtkMenuItem
*menuitem
,
2484 on_copy_activate (GtkMenuItem
*menuitem
,
2492 on_paste_activate (GtkMenuItem
*menuitem
,
2500 on_delete_activate (GtkMenuItem
*menuitem
,
2508 on_zoom_in_activate (GtkMenuItem
*menuitem
,
2511 zoom_in((GtkWidget
*)menuitem
, user_data
);
2516 on_zoom_out_activate (GtkMenuItem
*menuitem
,
2519 zoom_out((GtkWidget
*)menuitem
, user_data
);
2524 on_zoom_extended_activate (GtkMenuItem
*menuitem
,
2527 zoom_extended((GtkWidget
*)menuitem
, user_data
);
2532 on_go_to_time_activate (GtkMenuItem
*menuitem
,
2535 go_to_time((GtkWidget
*)menuitem
, user_data
);
2540 on_show_time_frame_activate (GtkMenuItem
*menuitem
,
2543 show_time_frame((GtkWidget
*)menuitem
, user_data
);
2548 on_move_viewer_up_activate (GtkMenuItem
*menuitem
,
2551 move_up_viewer((GtkWidget
*)menuitem
, user_data
);
2556 on_move_viewer_down_activate (GtkMenuItem
*menuitem
,
2559 move_down_viewer((GtkWidget
*)menuitem
, user_data
);
2564 on_remove_viewer_activate (GtkMenuItem
*menuitem
,
2567 delete_viewer((GtkWidget
*)menuitem
, user_data
);
2571 on_trace_facility_activate (GtkMenuItem
*menuitem
,
2574 g_info("Trace facility selector: %s\n");
2578 /* Dispaly a file selection dialogue to let user select a library, then call
2579 * lttv_library_load().
2583 on_load_library_activate (GtkMenuItem
*menuitem
,
2586 GError
*error
= NULL
;
2587 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2589 gchar load_module_path_alter
[PATH_MAX
];
2593 gchar
*load_module_path
;
2594 name
= g_ptr_array_new();
2595 nb
= lttv_library_path_number();
2596 /* ask for the library path */
2600 path
= lttv_library_path_get(i
);
2601 g_ptr_array_add(name
, path
);
2604 load_module_path
= get_selection(mw_data
,
2605 (char **)(name
->pdata
), name
->len
,
2606 "Select a library path", "Library paths");
2607 if(load_module_path
!= NULL
)
2608 strncpy(load_module_path_alter
, load_module_path
, PATH_MAX
-1); // -1 for /
2610 g_ptr_array_free(name
, TRUE
);
2612 if(load_module_path
== NULL
) return;
2616 /* Make sure the module path ends with a / */
2617 gchar
*ptr
= load_module_path_alter
;
2619 ptr
= strchr(ptr
, '\0');
2621 if(*(ptr
-1) != '/') {
2628 /* Ask for the library to load : list files in the previously selected
2630 gchar str
[PATH_MAX
];
2633 GtkFileSelection
* file_selector
=
2634 (GtkFileSelection
*)gtk_file_selection_new("Select a module");
2635 gtk_file_selection_set_filename(file_selector
, load_module_path_alter
);
2636 gtk_file_selection_hide_fileop_buttons(file_selector
);
2638 gtk_window_set_transient_for(GTK_WINDOW(file_selector
),
2639 GTK_WINDOW(mw_data
->mwindow
));
2642 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
2644 case GTK_RESPONSE_ACCEPT
:
2645 case GTK_RESPONSE_OK
:
2646 dir
= gtk_file_selection_get_selections (file_selector
);
2647 strncpy(str
,dir
[0],PATH_MAX
);
2648 strncpy(remember_plugins_dir
,dir
[0],PATH_MAX
);
2649 /* only keep file name */
2651 str1
= strrchr(str
,'/');
2654 str1
= strrchr(str
,'\\');
2659 if(*str1
== 'l' && *(str1
+1)== 'i' && *(str1
+2)=='b')
2661 remove info after
. */
2665 str2
= strrchr(str2
, '.');
2666 if(str2
!= NULL
) *str2
= '\0';
2668 lttv_module_require(str1
, &error
);
2670 lttv_library_load(str1
, &error
);
2671 if(error
!= NULL
) g_warning("%s", error
->message
);
2672 else g_info("Load library: %s\n", str
);
2674 case GTK_RESPONSE_REJECT
:
2675 case GTK_RESPONSE_CANCEL
:
2677 gtk_widget_destroy((GtkWidget
*)file_selector
);
2688 /* Display all loaded modules, let user to select a module to unload
2689 * by calling lttv_module_unload
2693 on_unload_library_activate (GtkMenuItem
*menuitem
,
2696 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2698 LttvLibrary
*library
= NULL
;
2703 name
= g_ptr_array_new();
2704 nb
= lttv_library_number();
2705 LttvLibraryInfo
*lib_info
= g_new(LttvLibraryInfo
,nb
);
2706 /* ask for the library name */
2709 LttvLibrary
*iter_lib
= lttv_library_get(i
);
2710 lttv_library_info(iter_lib
, &lib_info
[i
]);
2712 gchar
*path
= lib_info
[i
].name
;
2713 g_ptr_array_add(name
, path
);
2715 lib_name
= get_selection(mw_data
, (char **)(name
->pdata
), name
->len
,
2716 "Select a library", "Libraries");
2717 if(lib_name
!= NULL
) {
2719 if(strcmp(lib_name
, lib_info
[i
].name
) == 0) {
2720 library
= lttv_library_get(i
);
2725 g_ptr_array_free(name
, TRUE
);
2728 if(lib_name
== NULL
) return;
2730 if(library
!= NULL
) lttv_library_unload(library
);
2734 /* Dispaly a file selection dialogue to let user select a module, then call
2735 * lttv_module_require().
2739 on_load_module_activate (GtkMenuItem
*menuitem
,
2742 GError
*error
= NULL
;
2743 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2745 LttvLibrary
*library
= NULL
;
2750 name
= g_ptr_array_new();
2751 nb
= lttv_library_number();
2752 LttvLibraryInfo
*lib_info
= g_new(LttvLibraryInfo
,nb
);
2753 /* ask for the library name */
2756 LttvLibrary
*iter_lib
= lttv_library_get(i
);
2757 lttv_library_info(iter_lib
, &lib_info
[i
]);
2759 gchar
*path
= lib_info
[i
].name
;
2760 g_ptr_array_add(name
, path
);
2762 lib_name
= get_selection(mw_data
,(char **)(name
->pdata
), name
->len
,
2763 "Select a library", "Libraries");
2764 if(lib_name
!= NULL
) {
2766 if(strcmp(lib_name
, lib_info
[i
].name
) == 0) {
2767 library
= lttv_library_get(i
);
2772 g_ptr_array_free(name
, TRUE
);
2775 if(lib_name
== NULL
) return;
2778 //LttvModule *module;
2779 gchar module_name_out
[PATH_MAX
];
2781 /* Ask for the module to load : list modules in the selected lib */
2785 nb
= lttv_library_module_number(library
);
2786 LttvModuleInfo
*module_info
= g_new(LttvModuleInfo
,nb
);
2787 name
= g_ptr_array_new();
2788 /* ask for the module name */
2791 LttvModule
*iter_module
= lttv_library_module_get(library
, i
);
2792 lttv_module_info(iter_module
, &module_info
[i
]);
2794 gchar
*path
= module_info
[i
].name
;
2795 g_ptr_array_add(name
, path
);
2797 module_name
= get_selection(mw_data
, (char **)(name
->pdata
), name
->len
,
2798 "Select a module", "Modules");
2799 if(module_name
!= NULL
) {
2801 if(strcmp(module_name
, module_info
[i
].name
) == 0) {
2802 strncpy(module_name_out
, module_name
, PATH_MAX
);
2803 //module = lttv_library_module_get(i);
2809 g_ptr_array_free(name
, TRUE
);
2810 g_free(module_info
);
2812 if(module_name
== NULL
) return;
2815 lttv_module_require(module_name_out
, &error
);
2816 if(error
!= NULL
) g_warning("%s", error
->message
);
2817 else g_info("Load module: %s", module_name_out
);
2824 gchar str
[PATH_MAX
];
2827 GtkFileSelection
* file_selector
=
2828 (GtkFileSelection
*)gtk_file_selection_new("Select a module");
2829 gtk_file_selection_set_filename(file_selector
, load_module_path_alter
);
2830 gtk_file_selection_hide_fileop_buttons(file_selector
);
2833 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
2835 case GTK_RESPONSE_ACCEPT
:
2836 case GTK_RESPONSE_OK
:
2837 dir
= gtk_file_selection_get_selections (file_selector
);
2838 strncpy(str
,dir
[0],PATH_MAX
);
2839 strncpy(remember_plugins_dir
,dir
[0],PATH_MAX
);
2841 /* only keep file name */
2843 str1
= strrchr(str
,'/');
2846 str1
= strrchr(str
,'\\');
2851 if(*str1
== 'l' && *(str1
+1)== 'i' && *(str1
+2)=='b')
2853 remove info after
. */
2857 str2
= strrchr(str2
, '.');
2858 if(str2
!= NULL
) *str2
= '\0';
2860 lttv_module_require(str1
, &error
);
2862 lttv_library_load(str1
, &error
);
2863 if(error
!= NULL
) g_warning(error
->message
);
2864 else g_info("Load library: %s\n", str
);
2866 case GTK_RESPONSE_REJECT
:
2867 case GTK_RESPONSE_CANCEL
:
2869 gtk_widget_destroy((GtkWidget
*)file_selector
);
2881 /* Display all loaded modules, let user to select a module to unload
2882 * by calling lttv_module_unload
2886 on_unload_module_activate (GtkMenuItem
*menuitem
,
2889 GError
*error
= NULL
;
2890 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2892 LttvLibrary
*library
;
2897 name
= g_ptr_array_new();
2898 nb
= lttv_library_number();
2899 LttvLibraryInfo
*lib_info
= g_new(LttvLibraryInfo
,nb
);
2900 /* ask for the library name */
2903 LttvLibrary
*iter_lib
= lttv_library_get(i
);
2904 lttv_library_info(iter_lib
, &lib_info
[i
]);
2906 gchar
*path
= lib_info
[i
].name
;
2907 g_ptr_array_add(name
, path
);
2909 lib_name
= get_selection(mw_data
, (char **)(name
->pdata
), name
->len
,
2910 "Select a library", "Libraries");
2911 if(lib_name
!= NULL
) {
2913 if(strcmp(lib_name
, lib_info
[i
].name
) == 0) {
2914 library
= lttv_library_get(i
);
2919 g_ptr_array_free(name
, TRUE
);
2922 if(lib_name
== NULL
) return;
2925 LttvModule
*module
= NULL
;
2927 /* Ask for the module to load : list modules in the selected lib */
2931 nb
= lttv_library_module_number(library
);
2932 LttvModuleInfo
*module_info
= g_new(LttvModuleInfo
,nb
);
2933 name
= g_ptr_array_new();
2934 /* ask for the module name */
2937 LttvModule
*iter_module
= lttv_library_module_get(library
, i
);
2938 lttv_module_info(iter_module
, &module_info
[i
]);
2940 gchar
*path
= module_info
[i
].name
;
2941 if(module_info
[i
].use_count
> 0) g_ptr_array_add(name
, path
);
2943 module_name
= get_selection(mw_data
, (char **)(name
->pdata
), name
->len
,
2944 "Select a module", "Modules");
2945 if(module_name
!= NULL
) {
2947 if(strcmp(module_name
, module_info
[i
].name
) == 0) {
2948 module
= lttv_library_module_get(library
, i
);
2954 g_ptr_array_free(name
, TRUE
);
2955 g_free(module_info
);
2957 if(module_name
== NULL
) return;
2960 LttvModuleInfo module_info
;
2961 lttv_module_info(module
, &module_info
);
2962 g_info("Release module: %s\n", module_info
.name
);
2964 lttv_module_release(module
);
2968 /* Display a directory dialogue to let user select a path for library searching
2972 on_add_library_search_path_activate (GtkMenuItem
*menuitem
,
2975 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2976 //GtkDirSelection * file_selector = (GtkDirSelection *)gtk_dir_selection_new("Select library path");
2977 GtkFileSelection
* file_selector
= (GtkFileSelection
*)gtk_file_selection_new("Select a trace");
2978 gtk_widget_hide( (file_selector
)->file_list
->parent
) ;
2980 gtk_window_set_transient_for(GTK_WINDOW(file_selector
),
2981 GTK_WINDOW(mw_data
->mwindow
));
2986 if(remember_plugins_dir
[0] != '\0')
2987 gtk_file_selection_set_filename(file_selector
, remember_plugins_dir
);
2989 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
2991 case GTK_RESPONSE_ACCEPT
:
2992 case GTK_RESPONSE_OK
:
2993 dir
= gtk_file_selection_get_filename (file_selector
);
2994 strncpy(remember_plugins_dir
,dir
,PATH_MAX
);
2995 strncat(remember_plugins_dir
,"/",PATH_MAX
);
2996 lttv_library_path_add(dir
);
2997 case GTK_RESPONSE_REJECT
:
2998 case GTK_RESPONSE_CANCEL
:
3000 gtk_widget_destroy((GtkWidget
*)file_selector
);
3006 /* Display a directory dialogue to let user select a path for library searching
3010 on_remove_library_search_path_activate (GtkMenuItem
*menuitem
,
3013 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
3015 const char *lib_path
;
3020 name
= g_ptr_array_new();
3021 nb
= lttv_library_path_number();
3022 /* ask for the library name */
3025 gchar
*path
= lttv_library_path_get(i
);
3026 g_ptr_array_add(name
, path
);
3028 lib_path
= get_selection(mw_data
, (char **)(name
->pdata
), name
->len
,
3029 "Select a library path", "Library paths");
3031 g_ptr_array_free(name
, TRUE
);
3033 if(lib_path
== NULL
) return;
3036 lttv_library_path_remove(lib_path
);
3040 on_color_activate (GtkMenuItem
*menuitem
,
3048 on_save_configuration_activate (GtkMenuItem
*menuitem
,
3051 g_info("Save configuration\n");
3056 on_content_activate (GtkMenuItem
*menuitem
,
3059 g_info("Content\n");
3064 on_about_close_activate (GtkButton
*button
,
3067 GtkWidget
*about_widget
= GTK_WIDGET(user_data
);
3069 gtk_widget_destroy(about_widget
);
3073 on_about_activate (GtkMenuItem
*menuitem
,
3076 MainWindow
*main_window
= get_window_data_struct(GTK_WIDGET(menuitem
));
3077 GtkWidget
*window_widget
= main_window
->mwindow
;
3078 GtkWidget
*about_widget
= gtk_window_new(GTK_WINDOW_TOPLEVEL
);
3079 GtkWindow
*about_window
= GTK_WINDOW(about_widget
);
3080 gint window_width
, window_height
;
3082 gtk_window_set_title(about_window
, "About Linux Trace Toolkit");
3084 gtk_window_set_resizable(about_window
, FALSE
);
3085 gtk_window_set_transient_for(GTK_WINDOW(window_widget
), about_window
);
3086 gtk_window_set_destroy_with_parent(about_window
, TRUE
);
3087 gtk_window_set_modal(about_window
, FALSE
);
3089 /* Put the about window at the center of the screen */
3090 gtk_window_get_size(about_window
, &window_width
, &window_height
);
3091 gtk_window_move (about_window
,
3092 (gdk_screen_width() - window_width
)/2,
3093 (gdk_screen_height() - window_height
)/2);
3095 GtkWidget
*vbox
= gtk_vbox_new(FALSE
, 1);
3097 gtk_container_add(GTK_CONTAINER(about_widget
), vbox
);
3101 GtkWidget
*label1
= gtk_label_new("");
3102 gtk_misc_set_padding(GTK_MISC(label1
), 10, 20);
3103 gtk_label_set_markup(GTK_LABEL(label1
), "\
3104 <big>Linux Trace Toolkit</big>");
3105 gtk_label_set_justify(GTK_LABEL(label1
), GTK_JUSTIFY_CENTER
);
3107 GtkWidget
*label2
= gtk_label_new("");
3108 gtk_misc_set_padding(GTK_MISC(label2
), 10, 20);
3109 gtk_label_set_markup(GTK_LABEL(label2
), "\
3112 Michel Dagenais (New trace format, lttv main)\n\
3113 Mathieu Desnoyers (Kernel Tracer, Directory structure, build with automake/conf,\n\
3114 lttv gui, control flow view, gui cooperative trace reading\n\
3115 scheduler with interruptible foreground and background\n\
3116 computation, detailed event list (rewrite), trace reading\n\
3117 library (rewrite))\n\
3118 Benoit Des Ligneris, Eric Clement (Cluster adaptation, work in progress)\n\
3119 Xang-Xiu Yang (new trace reading library and converter, lttv gui, \n\
3120 detailed event list and statistics view)\n\
3121 Tom Zanussi (RelayFS)\n\
3123 Strongly inspired from the original Linux Trace Toolkit Visualizer made by\n\
3126 GtkWidget
*label3
= gtk_label_new("");
3127 gtk_label_set_markup(GTK_LABEL(label3
), "\
3128 Linux Trace Toolkit Viewer, Copyright (C) 2004\n\
3130 Mathieu Desnoyers\n\
3132 Linux Trace Toolkit comes with ABSOLUTELY NO WARRANTY.\n\
3133 This is free software, and you are welcome to redistribute it\n\
3134 under certain conditions. See COPYING for details.");
3135 gtk_misc_set_padding(GTK_MISC(label3
), 10, 20);
3137 gtk_box_pack_start_defaults(GTK_BOX(vbox
), label1
);
3138 gtk_box_pack_start_defaults(GTK_BOX(vbox
), label2
);
3139 gtk_box_pack_start_defaults(GTK_BOX(vbox
), label3
);
3141 GtkWidget
*hbox
= gtk_hbox_new(TRUE
, 0);
3142 gtk_box_pack_end(GTK_BOX(vbox
), hbox
, FALSE
, FALSE
, 0);
3143 GtkWidget
*close_button
= gtk_button_new_with_mnemonic("_Close");
3144 gtk_box_pack_end(GTK_BOX(hbox
), close_button
, FALSE
, FALSE
, 0);
3145 gtk_container_set_border_width(GTK_CONTAINER(close_button
), 20);
3147 g_signal_connect(G_OBJECT(close_button
), "clicked",
3148 G_CALLBACK(on_about_close_activate
),
3149 (gpointer
)about_widget
);
3151 gtk_widget_show_all(about_widget
);
3156 on_button_new_clicked (GtkButton
*button
,
3159 create_new_window((GtkWidget
*)button
, user_data
, TRUE
);
3163 on_button_new_tab_clicked (GtkButton
*button
,
3166 create_new_tab((GtkWidget
*)button
, user_data
);
3170 on_button_open_clicked (GtkButton
*button
,
3173 open_traceset((GtkWidget
*)button
, user_data
);
3178 on_button_add_trace_clicked (GtkButton
*button
,
3181 add_trace((GtkWidget
*)button
, user_data
);
3186 on_button_remove_trace_clicked (GtkButton
*button
,
3189 remove_trace((GtkWidget
*)button
, user_data
);
3193 on_button_redraw_clicked (GtkButton
*button
,
3196 redraw((GtkWidget
*)button
, user_data
);
3200 on_button_continue_processing_clicked (GtkButton
*button
,
3203 continue_processing((GtkWidget
*)button
, user_data
);
3207 on_button_stop_processing_clicked (GtkButton
*button
,
3210 stop_processing((GtkWidget
*)button
, user_data
);
3216 on_button_save_clicked (GtkButton
*button
,
3219 save((GtkWidget
*)button
, user_data
);
3224 on_button_save_as_clicked (GtkButton
*button
,
3227 save_as((GtkWidget
*)button
, user_data
);
3232 on_button_zoom_in_clicked (GtkButton
*button
,
3235 zoom_in((GtkWidget
*)button
, user_data
);
3240 on_button_zoom_out_clicked (GtkButton
*button
,
3243 zoom_out((GtkWidget
*)button
, user_data
);
3248 on_button_zoom_extended_clicked (GtkButton
*button
,
3251 zoom_extended((GtkWidget
*)button
, user_data
);
3256 on_button_go_to_time_clicked (GtkButton
*button
,
3259 go_to_time((GtkWidget
*)button
, user_data
);
3264 on_button_show_time_frame_clicked (GtkButton
*button
,
3267 show_time_frame((GtkWidget
*)button
, user_data
);
3272 on_button_move_up_clicked (GtkButton
*button
,
3275 move_up_viewer((GtkWidget
*)button
, user_data
);
3280 on_button_move_down_clicked (GtkButton
*button
,
3283 move_down_viewer((GtkWidget
*)button
, user_data
);
3288 on_button_delete_viewer_clicked (GtkButton
*button
,
3291 delete_viewer((GtkWidget
*)button
, user_data
);
3295 on_MWindow_destroy (GtkWidget
*widget
,
3298 MainWindow
*main_window
= get_window_data_struct(widget
);
3299 LttvIAttribute
*attributes
= main_window
->attributes
;
3300 LttvAttributeValue value
;
3302 //This is unnecessary, since widgets will be destroyed
3303 //by the main window widget anyway.
3304 //remove_all_menu_toolbar_constructors(main_window, NULL);
3306 g_assert(lttv_iattribute_find_by_path(attributes
,
3307 "viewers/menu", LTTV_POINTER
, &value
));
3308 lttv_menus_destroy((LttvMenus
*)*(value
.v_pointer
));
3310 g_assert(lttv_iattribute_find_by_path(attributes
,
3311 "viewers/toolbar", LTTV_POINTER
, &value
));
3312 lttv_toolbars_destroy((LttvToolbars
*)*(value
.v_pointer
));
3314 g_object_unref(main_window
->attributes
);
3315 g_main_window_list
= g_slist_remove(g_main_window_list
, main_window
);
3317 g_info("There are now : %d windows\n",g_slist_length(g_main_window_list
));
3318 if(g_slist_length(g_main_window_list
) == 0)
3323 on_MWindow_configure (GtkWidget
*widget
,
3324 GdkEventConfigure
*event
,
3327 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)widget
);
3329 // MD : removed time width modification upon resizing of the main window.
3330 // The viewers will redraw themselves completely, without time interval
3333 if(mw_data->window_width){
3334 time_span = LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context)->Time_Span ;
3335 time_win = tab->time_window;
3336 ratio = width / mw_data->window_width;
3337 tab->time_window.time_width = ltt_time_mul(time_win.time_width,ratio);
3338 time = ltt_time_sub(time_span->endTime, time_win.start_time);
3339 if(ltt_time_compare(time, tab->time_window.time_width) < 0){
3340 tab->time_window.time_width = time;
3346 mw_data->window_width = (int)width;
3355 on_MNotebook_switch_page (GtkNotebook
*notebook
,
3356 GtkNotebookPage
*page
,
3364 void time_change_manager (Tab
*tab
,
3365 TimeWindow new_time_window
)
3367 /* Only one source of time change */
3368 if(tab
->time_manager_lock
== TRUE
) return;
3370 tab
->time_manager_lock
= TRUE
;
3372 LttvTracesetContext
*tsc
= LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3373 TimeInterval time_span
= tsc
->time_span
;
3374 LttTime start_time
= new_time_window
.start_time
;
3375 LttTime end_time
= new_time_window
.end_time
;
3376 LttTime time_width
= new_time_window
.time_width
;
3378 g_assert(ltt_time_compare(start_time
, end_time
) < 0);
3381 GtkAdjustment
*adjustment
= gtk_range_get_adjustment(GTK_RANGE(tab
->scrollbar
));
3382 LttTime upper
= ltt_time_sub(time_span
.end_time
, time_span
.start_time
);
3384 gtk_range_set_increments(GTK_RANGE(tab
->scrollbar
),
3385 ltt_time_to_double(new_time_window
.time_width
)
3386 / SCROLL_STEP_PER_PAGE
3387 * NANOSECONDS_PER_SECOND
, /* step increment */
3388 ltt_time_to_double(new_time_window
.time_width
)
3389 * NANOSECONDS_PER_SECOND
); /* page increment */
3390 gtk_range_set_range(GTK_RANGE(tab
->scrollbar
),
3392 ltt_time_to_double(upper
)
3393 * NANOSECONDS_PER_SECOND
); /* upper */
3395 g_object_set(G_OBJECT(adjustment
),
3399 ltt_time_to_double(upper
), /* upper */
3401 new_time_window
.time_width_double
3402 / SCROLL_STEP_PER_PAGE
, /* step increment */
3404 new_time_window
.time_width_double
,
3405 /* page increment */
3407 new_time_window
.time_width_double
, /* page size */
3409 gtk_adjustment_changed(adjustment
);
3411 // g_object_set(G_OBJECT(adjustment),
3413 // ltt_time_to_double(
3414 // ltt_time_sub(start_time, time_span.start_time))
3417 //gtk_adjustment_value_changed(adjustment);
3418 gtk_range_set_value(GTK_RANGE(tab
->scrollbar
),
3420 ltt_time_sub(start_time
, time_span
.start_time
)) /* value */);
3422 /* set the time bar. */
3424 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry1
),
3425 (double)time_span
.start_time
.tv_sec
,
3426 (double)time_span
.end_time
.tv_sec
);
3427 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry1
),
3428 (double)start_time
.tv_sec
);
3430 /* start nanoseconds */
3431 if(start_time
.tv_sec
== time_span
.start_time
.tv_sec
) {
3432 /* can be both beginning and end at the same time. */
3433 if(start_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3434 /* If we are at the end, max nsec to end.. -1 (not zero length) */
3435 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry2
),
3436 (double)time_span
.start_time
.tv_nsec
,
3437 (double)time_span
.end_time
.tv_nsec
-1);
3439 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry2
),
3440 (double)time_span
.start_time
.tv_nsec
,
3441 (double)NANOSECONDS_PER_SECOND
-1);
3443 } else if(start_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3444 /* If we are at the end, max nsec to end.. -1 (not zero length) */
3445 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry2
),
3447 (double)time_span
.end_time
.tv_nsec
-1);
3448 } else /* anywhere else */
3449 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry2
),
3451 (double)NANOSECONDS_PER_SECOND
-1);
3452 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry2
),
3453 (double)start_time
.tv_nsec
);
3456 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry3
),
3457 (double)time_span
.start_time
.tv_sec
,
3458 (double)time_span
.end_time
.tv_sec
);
3459 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry3
),
3460 (double)end_time
.tv_sec
);
3462 /* end nanoseconds */
3463 if(end_time
.tv_sec
== time_span
.start_time
.tv_sec
) {
3464 /* can be both beginning and end at the same time. */
3465 if(end_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3466 /* If we are at the end, max nsec to end.. */
3467 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry4
),
3468 (double)time_span
.start_time
.tv_nsec
+1,
3469 (double)time_span
.end_time
.tv_nsec
);
3471 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry4
),
3472 (double)time_span
.start_time
.tv_nsec
+1,
3473 (double)NANOSECONDS_PER_SECOND
-1);
3476 else if(end_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3477 /* If we are at the end, max nsec to end.. */
3478 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry4
),
3480 (double)time_span
.end_time
.tv_nsec
);
3482 else /* anywhere else */
3483 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry4
),
3485 (double)NANOSECONDS_PER_SECOND
-1);
3486 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry4
),
3487 (double)end_time
.tv_nsec
);
3490 if(time_width
.tv_nsec
== 0) {
3491 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry7
),
3493 (double)upper
.tv_sec
);
3495 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry7
),
3497 (double)upper
.tv_sec
);
3499 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry7
),
3500 (double)time_width
.tv_sec
);
3502 /* width nanoseconds */
3503 if(time_width
.tv_sec
== upper
.tv_sec
) {
3504 if(time_width
.tv_sec
== 0) {
3505 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry8
),
3507 (double)upper
.tv_nsec
);
3509 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry8
),
3511 (double)upper
.tv_nsec
);
3514 else if(time_width
.tv_sec
== 0) {
3515 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry8
),
3517 (double)upper
.tv_nsec
);
3519 else /* anywhere else */
3520 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry8
),
3522 (double)NANOSECONDS_PER_SECOND
-1);
3523 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry8
),
3524 (double)time_width
.tv_nsec
);
3526 /* call viewer hooks for new time window */
3527 set_time_window(tab
, &new_time_window
);
3529 tab
->time_manager_lock
= FALSE
;
3533 /* value changed for frame start s
3535 * Check time span : if ns is out of range, clip it the nearest good value.
3538 on_MEntry1_value_changed (GtkSpinButton
*spinbutton
,
3541 Tab
*tab
=(Tab
*)user_data
;
3542 LttvTracesetContext
* tsc
=
3543 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3544 TimeInterval time_span
= tsc
->time_span
;
3545 gint value
= gtk_spin_button_get_value_as_int(spinbutton
);
3547 TimeWindow new_time_window
= tab
->time_window
;
3549 LttTime end_time
= new_time_window
.end_time
;
3551 new_time_window
.start_time
.tv_sec
= value
;
3553 /* start nanoseconds */
3554 if(new_time_window
.start_time
.tv_sec
== time_span
.start_time
.tv_sec
) {
3555 if(new_time_window
.start_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3556 if(new_time_window
.start_time
.tv_nsec
> time_span
.end_time
.tv_nsec
)
3557 new_time_window
.start_time
.tv_nsec
= time_span
.end_time
.tv_nsec
-1;
3558 if(new_time_window
.start_time
.tv_nsec
< time_span
.start_time
.tv_nsec
)
3559 new_time_window
.start_time
.tv_nsec
= time_span
.start_time
.tv_nsec
;
3561 if(new_time_window
.start_time
.tv_nsec
< time_span
.start_time
.tv_nsec
)
3562 new_time_window
.start_time
.tv_nsec
= time_span
.start_time
.tv_nsec
;
3565 else if(new_time_window
.start_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3566 if(new_time_window
.start_time
.tv_nsec
> time_span
.end_time
.tv_nsec
)
3567 new_time_window
.start_time
.tv_nsec
= time_span
.end_time
.tv_nsec
-1;
3570 if(ltt_time_compare(new_time_window
.start_time
, end_time
) >= 0) {
3571 /* Then, we must push back end time : keep the same time width
3572 * if possible, else end traceset time */
3573 end_time
= LTT_TIME_MIN(ltt_time_add(new_time_window
.start_time
,
3574 new_time_window
.time_width
),
3575 time_span
.end_time
);
3578 /* Fix the time width to fit start time and end time */
3579 new_time_window
.time_width
= ltt_time_sub(end_time
,
3580 new_time_window
.start_time
);
3581 new_time_window
.time_width_double
=
3582 ltt_time_to_double(new_time_window
.time_width
);
3584 new_time_window
.end_time
= end_time
;
3586 time_change_manager(tab
, new_time_window
);
3591 on_MEntry2_value_changed (GtkSpinButton
*spinbutton
,
3594 Tab
*tab
=(Tab
*)user_data
;
3595 LttvTracesetContext
* tsc
=
3596 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3597 TimeInterval time_span
= tsc
->time_span
;
3598 gint value
= gtk_spin_button_get_value_as_int(spinbutton
);
3600 TimeWindow new_time_window
= tab
->time_window
;
3602 LttTime end_time
= new_time_window
.end_time
;
3604 new_time_window
.start_time
.tv_nsec
= value
;
3606 if(ltt_time_compare(new_time_window
.start_time
, end_time
) >= 0) {
3607 /* Then, we must push back end time : keep the same time width
3608 * if possible, else end traceset time */
3609 end_time
= LTT_TIME_MIN(ltt_time_add(new_time_window
.start_time
,
3610 new_time_window
.time_width
),
3611 time_span
.end_time
);
3614 /* Fix the time width to fit start time and end time */
3615 new_time_window
.time_width
= ltt_time_sub(end_time
,
3616 new_time_window
.start_time
);
3617 new_time_window
.time_width_double
=
3618 ltt_time_to_double(new_time_window
.time_width
);
3620 new_time_window
.end_time
= end_time
;
3622 time_change_manager(tab
, new_time_window
);
3627 on_MEntry3_value_changed (GtkSpinButton
*spinbutton
,
3630 Tab
*tab
=(Tab
*)user_data
;
3631 LttvTracesetContext
* tsc
=
3632 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3633 TimeInterval time_span
= tsc
->time_span
;
3634 gint value
= gtk_spin_button_get_value_as_int(spinbutton
);
3636 TimeWindow new_time_window
= tab
->time_window
;
3638 LttTime end_time
= new_time_window
.end_time
;
3640 end_time
.tv_sec
= value
;
3642 /* end nanoseconds */
3643 if(end_time
.tv_sec
== time_span
.start_time
.tv_sec
) {
3644 if(end_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3645 if(end_time
.tv_nsec
> time_span
.end_time
.tv_nsec
)
3646 end_time
.tv_nsec
= time_span
.end_time
.tv_nsec
;
3647 if(end_time
.tv_nsec
< time_span
.start_time
.tv_nsec
)
3648 end_time
.tv_nsec
= time_span
.start_time
.tv_nsec
+1;
3650 if(end_time
.tv_nsec
< time_span
.start_time
.tv_nsec
)
3651 end_time
.tv_nsec
= time_span
.start_time
.tv_nsec
+1;
3654 else if(end_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3655 if(end_time
.tv_nsec
> time_span
.end_time
.tv_nsec
)
3656 end_time
.tv_nsec
= time_span
.end_time
.tv_nsec
;
3659 if(ltt_time_compare(new_time_window
.start_time
, end_time
) >= 0) {
3660 /* Then, we must push front start time : keep the same time width
3661 * if possible, else end traceset time */
3662 new_time_window
.start_time
= LTT_TIME_MAX(
3663 ltt_time_sub(end_time
,
3664 new_time_window
.time_width
),
3665 time_span
.start_time
);
3668 /* Fix the time width to fit start time and end time */
3669 new_time_window
.time_width
= ltt_time_sub(end_time
,
3670 new_time_window
.start_time
);
3671 new_time_window
.time_width_double
=
3672 ltt_time_to_double(new_time_window
.time_width
);
3674 new_time_window
.end_time
= end_time
;
3676 time_change_manager(tab
, new_time_window
);
3681 on_MEntry4_value_changed (GtkSpinButton
*spinbutton
,
3684 Tab
*tab
=(Tab
*)user_data
;
3685 LttvTracesetContext
* tsc
=
3686 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3687 TimeInterval time_span
= tsc
->time_span
;
3688 gint value
= gtk_spin_button_get_value_as_int(spinbutton
);
3690 TimeWindow new_time_window
= tab
->time_window
;
3692 LttTime end_time
= new_time_window
.end_time
;
3694 end_time
.tv_nsec
= value
;
3696 if(ltt_time_compare(new_time_window
.start_time
, end_time
) >= 0) {
3697 /* Then, we must push front start time : keep the same time width
3698 * if possible, else end traceset time */
3699 new_time_window
.start_time
= LTT_TIME_MAX(
3700 ltt_time_sub(end_time
,
3701 new_time_window
.time_width
),
3702 time_span
.start_time
);
3705 /* Fix the time width to fit start time and end time */
3706 new_time_window
.time_width
= ltt_time_sub(end_time
,
3707 new_time_window
.start_time
);
3708 new_time_window
.time_width_double
=
3709 ltt_time_to_double(new_time_window
.time_width
);
3710 new_time_window
.end_time
= end_time
;
3712 time_change_manager(tab
, new_time_window
);
3716 /* value changed for time frame interval s
3718 * Check time span : if ns is out of range, clip it the nearest good value.
3721 on_MEntry7_value_changed (GtkSpinButton
*spinbutton
,
3724 Tab
*tab
=(Tab
*)user_data
;
3725 LttvTracesetContext
* tsc
=
3726 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3727 TimeInterval time_span
= tsc
->time_span
;
3728 gint value
= gtk_spin_button_get_value_as_int(spinbutton
);
3729 LttTime current_time
, time_delta
;
3730 TimeWindow new_time_window
= tab
->time_window
;
3731 current_time
= tab
->current_time
;
3733 time_delta
= ltt_time_sub(time_span
.end_time
,time_span
.start_time
);
3734 new_time_window
.time_width
.tv_sec
= value
;
3735 new_time_window
.time_width_double
=
3736 ltt_time_to_double(new_time_window
.time_width
);
3737 if(ltt_time_compare(new_time_window
.time_width
,time_delta
) > 0)
3738 { /* Case where zoom out is bigger than trace length */
3739 new_time_window
.start_time
= time_span
.start_time
;
3740 new_time_window
.time_width
= time_delta
;
3741 new_time_window
.time_width_double
= ltt_time_to_double(time_delta
);
3742 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
3743 new_time_window
.time_width
) ;
3747 /* Center the image on the current time */
3748 new_time_window
.start_time
=
3749 ltt_time_sub(current_time
,
3750 ltt_time_from_double(new_time_window
.time_width_double
/2.0));
3751 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
3752 new_time_window
.time_width
) ;
3753 /* If on borders, don't fall off */
3754 if(ltt_time_compare(new_time_window
.start_time
, time_span
.start_time
) <0
3755 || ltt_time_compare(new_time_window
.start_time
, time_span
.end_time
) >0)
3757 new_time_window
.start_time
= time_span
.start_time
;
3758 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
3759 new_time_window
.time_width
) ;
3763 if(ltt_time_compare(new_time_window
.end_time
,
3764 time_span
.end_time
) > 0
3765 || ltt_time_compare(new_time_window
.end_time
,
3766 time_span
.start_time
) < 0)
3768 new_time_window
.start_time
=
3769 ltt_time_sub(time_span
.end_time
, new_time_window
.time_width
);
3771 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
3772 new_time_window
.time_width
) ;
3778 if(ltt_time_compare(new_time_window
.time_width
, ltt_time_zero
) == 0) {
3779 g_warning("Zoom more than 1 ns impossible");
3781 time_change_manager(tab
, new_time_window
);
3786 on_MEntry8_value_changed (GtkSpinButton
*spinbutton
,
3789 Tab
*tab
=(Tab
*)user_data
;
3790 LttvTracesetContext
* tsc
=
3791 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3792 TimeInterval time_span
= tsc
->time_span
;
3793 gint value
= gtk_spin_button_get_value_as_int(spinbutton
);
3794 LttTime current_time
, time_delta
;
3795 TimeWindow new_time_window
= tab
->time_window
;
3796 current_time
= tab
->current_time
;
3798 time_delta
= ltt_time_sub(time_span
.end_time
,time_span
.start_time
);
3799 new_time_window
.time_width
.tv_nsec
= value
;
3800 new_time_window
.time_width_double
=
3801 ltt_time_to_double(new_time_window
.time_width
);
3802 if(ltt_time_compare(new_time_window
.time_width
,time_delta
) > 0)
3803 { /* Case where zoom out is bigger than trace length */
3804 new_time_window
.start_time
= time_span
.start_time
;
3805 new_time_window
.time_width
= time_delta
;
3806 new_time_window
.time_width_double
= ltt_time_to_double(time_delta
);
3807 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
3808 new_time_window
.time_width
) ;
3812 /* Center the image on the current time */
3813 new_time_window
.start_time
=
3814 ltt_time_sub(current_time
,
3815 ltt_time_from_double(new_time_window
.time_width_double
/2.0));
3816 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
3817 new_time_window
.time_width
) ;
3818 /* If on borders, don't fall off */
3819 if(ltt_time_compare(new_time_window
.start_time
, time_span
.start_time
) <0
3820 || ltt_time_compare(new_time_window
.start_time
, time_span
.end_time
) >0)
3822 new_time_window
.start_time
= time_span
.start_time
;
3823 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
3824 new_time_window
.time_width
) ;
3828 if(ltt_time_compare(new_time_window
.end_time
,
3829 time_span
.end_time
) > 0
3830 || ltt_time_compare(new_time_window
.end_time
,
3831 time_span
.start_time
) < 0)
3833 new_time_window
.start_time
=
3834 ltt_time_sub(time_span
.end_time
, new_time_window
.time_width
);
3836 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
3837 new_time_window
.time_width
) ;
3843 if(ltt_time_compare(new_time_window
.time_width
, ltt_time_zero
) == 0) {
3844 g_warning("Zoom more than 1 ns impossible");
3846 time_change_manager(tab
, new_time_window
);
3852 void current_time_change_manager (Tab
*tab
,
3853 LttTime new_current_time
)
3855 /* Only one source of time change */
3856 if(tab
->current_time_manager_lock
== TRUE
) return;
3858 tab
->current_time_manager_lock
= TRUE
;
3860 LttvTracesetContext
*tsc
= LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3861 TimeInterval time_span
= tsc
->time_span
;
3863 /* current seconds */
3864 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry5
),
3865 (double)time_span
.start_time
.tv_sec
,
3866 (double)time_span
.end_time
.tv_sec
);
3867 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry5
),
3868 (double)new_current_time
.tv_sec
);
3871 /* start nanoseconds */
3872 if(new_current_time
.tv_sec
== time_span
.start_time
.tv_sec
) {
3873 /* can be both beginning and end at the same time. */
3874 if(new_current_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3875 /* If we are at the end, max nsec to end.. */
3876 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry6
),
3877 (double)time_span
.start_time
.tv_nsec
,
3878 (double)time_span
.end_time
.tv_nsec
);
3880 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry6
),
3881 (double)time_span
.start_time
.tv_nsec
,
3882 (double)NANOSECONDS_PER_SECOND
-1);
3884 } else if(new_current_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3885 /* If we are at the end, max nsec to end.. */
3886 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry6
),
3888 (double)time_span
.end_time
.tv_nsec
);
3889 } else /* anywhere else */
3890 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry6
),
3892 (double)NANOSECONDS_PER_SECOND
-1);
3894 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry6
),
3895 (double)new_current_time
.tv_nsec
);
3897 set_current_time(tab
, &new_current_time
);
3899 tab
->current_time_manager_lock
= FALSE
;
3902 void current_position_change_manager(Tab
*tab
,
3903 LttvTracesetContextPosition
*pos
)
3905 LttvTracesetContext
*tsc
=
3906 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3907 TimeInterval time_span
= tsc
->time_span
;
3909 g_assert(lttv_process_traceset_seek_position(tsc
, pos
) == 0);
3910 LttTime new_time
= lttv_traceset_context_position_get_time(pos
);
3911 /* Put the context in a state coherent position */
3912 lttv_state_traceset_seek_time_closest((LttvTracesetState
*)tsc
, ltt_time_zero
);
3914 current_time_change_manager(tab
, new_time
);
3916 set_current_position(tab
, pos
);
3921 on_MEntry5_value_changed (GtkSpinButton
*spinbutton
,
3924 Tab
*tab
= (Tab
*)user_data
;
3925 LttvTracesetContext
* tsc
=
3926 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3927 TimeInterval time_span
= tsc
->time_span
;
3928 gint value
= gtk_spin_button_get_value_as_int(spinbutton
);
3929 LttTime new_current_time
= tab
->current_time
;
3930 new_current_time
.tv_sec
= value
;
3932 /* current nanoseconds */
3933 if(new_current_time
.tv_sec
== time_span
.start_time
.tv_sec
) {
3934 if(new_current_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3935 if(new_current_time
.tv_nsec
> time_span
.end_time
.tv_nsec
)
3936 new_current_time
.tv_nsec
= time_span
.end_time
.tv_nsec
;
3937 if(new_current_time
.tv_nsec
< time_span
.start_time
.tv_nsec
)
3938 new_current_time
.tv_nsec
= time_span
.start_time
.tv_nsec
;
3940 if(new_current_time
.tv_nsec
< time_span
.start_time
.tv_nsec
)
3941 new_current_time
.tv_nsec
= time_span
.start_time
.tv_nsec
;
3944 else if(new_current_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3945 if(new_current_time
.tv_nsec
> time_span
.end_time
.tv_nsec
)
3946 new_current_time
.tv_nsec
= time_span
.end_time
.tv_nsec
;
3949 current_time_change_manager(tab
, new_current_time
);
3953 on_MEntry6_value_changed (GtkSpinButton
*spinbutton
,
3956 Tab
*tab
= (Tab
*)user_data
;
3957 gint value
= gtk_spin_button_get_value_as_int(spinbutton
);
3958 LttTime new_current_time
= tab
->current_time
;
3959 new_current_time
.tv_nsec
= value
;
3961 current_time_change_manager(tab
, new_current_time
);
3965 void scroll_value_changed_cb(GtkWidget
*scrollbar
,
3968 Tab
*tab
= (Tab
*)user_data
;
3969 TimeWindow new_time_window
;
3971 GtkAdjustment
*adjust
= gtk_range_get_adjustment(GTK_RANGE(scrollbar
));
3972 gdouble value
= gtk_adjustment_get_value(adjust
);
3973 // gdouble upper, lower, ratio, page_size;
3975 LttvTracesetContext
* tsc
=
3976 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3977 TimeInterval time_span
= tsc
->time_span
;
3979 time
= ltt_time_add(ltt_time_from_double(value
),
3980 time_span
.start_time
);
3982 new_time_window
.start_time
= time
;
3984 page_size
= adjust
->page_size
;
3986 new_time_window
.time_width
=
3987 ltt_time_from_double(page_size
);
3989 new_time_window
.time_width_double
=
3992 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
3993 new_time_window
.time_width
);
3996 time_change_manager(tab
, new_time_window
);
3998 //time_window = tab->time_window;
4000 lower
= adjust
->lower
;
4001 upper
= adjust
->upper
;
4002 ratio
= (value
- lower
) / (upper
- lower
);
4003 g_info("lower %lu, upper %lu, value %lu, ratio %lu", lower
, upper
, value
, ratio
);
4005 //time = ltt_time_sub(time_span->end_time, time_span->start_time);
4006 //time = ltt_time_mul(time, (float)ratio);
4007 //time = ltt_time_add(time_span->start_time, time);
4008 time
= ltt_time_add(ltt_time_from_double(value
),
4009 time_span
.start_time
);
4011 time_window
.start_time
= time
;
4013 page_size
= adjust
->page_size
;
4015 time_window
.time_width
=
4016 ltt_time_from_double(page_size
);
4017 //time = ltt_time_sub(time_span.end_time, time);
4018 //if(ltt_time_compare(time,time_window.time_width) < 0){
4019 // time_window.time_width = time;
4022 /* call viewer hooks for new time window */
4023 set_time_window(tab
, &time_window
);
4028 /* Display a dialogue showing all eventtypes and traces, let user to select the interested
4029 * eventtypes, tracefiles and traces (filter)
4032 /* Select a trace which will be removed from traceset
4035 char * get_remove_trace(MainWindow
*mw_data
,
4036 char ** all_trace_name
, int nb_trace
)
4038 return get_selection(mw_data
, all_trace_name
, nb_trace
,
4039 "Select a trace", "Trace pathname");
4043 /* Select a module which will be loaded
4046 char * get_load_module(MainWindow
*mw_data
,
4047 char ** load_module_name
, int nb_module
)
4049 return get_selection(mw_data
, load_module_name
, nb_module
,
4050 "Select a module to load", "Module name");
4056 /* Select a module which will be unloaded
4059 char * get_unload_module(MainWindow
*mw_data
,
4060 char ** loaded_module_name
, int nb_module
)
4062 return get_selection(mw_data
, loaded_module_name
, nb_module
,
4063 "Select a module to unload", "Module name");
4067 /* Display a dialogue which shows all selectable items, let user to
4068 * select one of them
4071 char * get_selection(MainWindow
*mw_data
,
4072 char ** loaded_module_name
, int nb_module
,
4073 char *title
, char * column_title
)
4075 GtkWidget
* dialogue
;
4076 GtkWidget
* scroll_win
;
4078 GtkListStore
* store
;
4079 GtkTreeViewColumn
* column
;
4080 GtkCellRenderer
* renderer
;
4081 GtkTreeSelection
* select
;
4084 char * unload_module_name
= NULL
;
4086 dialogue
= gtk_dialog_new_with_buttons(title
,
4089 GTK_STOCK_OK
,GTK_RESPONSE_ACCEPT
,
4090 GTK_STOCK_CANCEL
,GTK_RESPONSE_REJECT
,
4092 gtk_window_set_default_size((GtkWindow
*)dialogue
, 500, 200);
4093 gtk_window_set_transient_for(GTK_WINDOW(dialogue
),
4094 GTK_WINDOW(mw_data
->mwindow
));
4096 scroll_win
= gtk_scrolled_window_new (NULL
, NULL
);
4097 gtk_widget_show ( scroll_win
);
4098 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll_win
),
4099 GTK_POLICY_AUTOMATIC
, GTK_POLICY_AUTOMATIC
);
4101 store
= gtk_list_store_new (N_COLUMNS
,G_TYPE_STRING
);
4102 tree
= gtk_tree_view_new_with_model(GTK_TREE_MODEL (store
));
4103 gtk_widget_show ( tree
);
4104 g_object_unref (G_OBJECT (store
));
4106 renderer
= gtk_cell_renderer_text_new ();
4107 column
= gtk_tree_view_column_new_with_attributes (column_title
,
4109 "text", MODULE_COLUMN
,
4111 gtk_tree_view_column_set_alignment (column
, 0.5);
4112 gtk_tree_view_column_set_fixed_width (column
, 150);
4113 gtk_tree_view_append_column (GTK_TREE_VIEW (tree
), column
);
4115 select
= gtk_tree_view_get_selection (GTK_TREE_VIEW (tree
));
4116 gtk_tree_selection_set_mode (select
, GTK_SELECTION_SINGLE
);
4118 gtk_container_add (GTK_CONTAINER (scroll_win
), tree
);
4120 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialogue
)->vbox
), scroll_win
,TRUE
, TRUE
,0);
4122 for(i
=0;i
<nb_module
;i
++){
4123 gtk_list_store_append (store
, &iter
);
4124 gtk_list_store_set (store
, &iter
, MODULE_COLUMN
,loaded_module_name
[i
],-1);
4127 id
= gtk_dialog_run(GTK_DIALOG(dialogue
));
4128 GtkTreeModel
**store_model
= (GtkTreeModel
**)&store
;
4130 case GTK_RESPONSE_ACCEPT
:
4131 case GTK_RESPONSE_OK
:
4132 if (gtk_tree_selection_get_selected (select
, store_model
, &iter
)){
4133 gtk_tree_model_get ((GtkTreeModel
*)store
, &iter
, MODULE_COLUMN
, &unload_module_name
, -1);
4135 case GTK_RESPONSE_REJECT
:
4136 case GTK_RESPONSE_CANCEL
:
4138 gtk_widget_destroy(dialogue
);
4142 return unload_module_name
;
4146 /* Insert all menu entry and tool buttons into this main window
4151 void add_all_menu_toolbar_constructors(MainWindow
* mw
, gpointer user_data
)
4155 lttvwindow_viewer_constructor constructor
;
4156 LttvMenus
* global_menu
, * instance_menu
;
4157 LttvToolbars
* global_toolbar
, * instance_toolbar
;
4158 LttvMenuClosure
*menu_item
;
4159 LttvToolbarClosure
*toolbar_item
;
4160 LttvAttributeValue value
;
4161 LttvIAttribute
*global_attributes
= LTTV_IATTRIBUTE(lttv_global_attributes());
4162 LttvIAttribute
*attributes
= mw
->attributes
;
4163 GtkWidget
* tool_menu_title_menu
, *new_widget
, *pixmap
;
4165 g_assert(lttv_iattribute_find_by_path(global_attributes
,
4166 "viewers/menu", LTTV_POINTER
, &value
));
4167 if(*(value
.v_pointer
) == NULL
)
4168 *(value
.v_pointer
) = lttv_menus_new();
4169 global_menu
= (LttvMenus
*)*(value
.v_pointer
);
4171 g_assert(lttv_iattribute_find_by_path(attributes
,
4172 "viewers/menu", LTTV_POINTER
, &value
));
4173 if(*(value
.v_pointer
) == NULL
)
4174 *(value
.v_pointer
) = lttv_menus_new();
4175 instance_menu
= (LttvMenus
*)*(value
.v_pointer
);
4179 g_assert(lttv_iattribute_find_by_path(global_attributes
,
4180 "viewers/toolbar", LTTV_POINTER
, &value
));
4181 if(*(value
.v_pointer
) == NULL
)
4182 *(value
.v_pointer
) = lttv_toolbars_new();
4183 global_toolbar
= (LttvToolbars
*)*(value
.v_pointer
);
4185 g_assert(lttv_iattribute_find_by_path(attributes
,
4186 "viewers/toolbar", LTTV_POINTER
, &value
));
4187 if(*(value
.v_pointer
) == NULL
)
4188 *(value
.v_pointer
) = lttv_toolbars_new();
4189 instance_toolbar
= (LttvToolbars
*)*(value
.v_pointer
);
4191 /* Add missing menu entries to window instance */
4192 for(i
=0;i
<global_menu
->len
;i
++) {
4193 menu_item
= &g_array_index(global_menu
, LttvMenuClosure
, i
);
4195 //add menu_item to window instance;
4196 constructor
= menu_item
->con
;
4197 tool_menu_title_menu
= lookup_widget(mw
->mwindow
,"ToolMenuTitle_menu");
4199 gtk_menu_item_new_with_mnemonic (menu_item
->menu_text
);
4200 gtk_container_add (GTK_CONTAINER (tool_menu_title_menu
),
4202 g_signal_connect ((gpointer
) new_widget
, "activate",
4203 G_CALLBACK (insert_viewer_wrap
),
4205 gtk_widget_show (new_widget
);
4206 lttv_menus_add(instance_menu
, menu_item
->con
,
4207 menu_item
->menu_path
,
4208 menu_item
->menu_text
,
4213 /* Add missing toolbar entries to window instance */
4214 for(i
=0;i
<global_toolbar
->len
;i
++) {
4215 toolbar_item
= &g_array_index(global_toolbar
, LttvToolbarClosure
, i
);
4217 //add toolbar_item to window instance;
4218 constructor
= toolbar_item
->con
;
4219 tool_menu_title_menu
= lookup_widget(mw
->mwindow
,"MToolbar1");
4220 pixbuf
= gdk_pixbuf_new_from_xpm_data((const char**)toolbar_item
->pixmap
);
4221 pixmap
= gtk_image_new_from_pixbuf(pixbuf
);
4223 gtk_toolbar_append_element (GTK_TOOLBAR (tool_menu_title_menu
),
4224 GTK_TOOLBAR_CHILD_BUTTON
,
4227 toolbar_item
->tooltip
, NULL
,
4228 pixmap
, NULL
, NULL
);
4229 gtk_label_set_use_underline(
4230 GTK_LABEL (((GtkToolbarChild
*) (
4231 g_list_last (GTK_TOOLBAR
4232 (tool_menu_title_menu
)->children
)->data
))->label
),
4234 gtk_container_set_border_width (GTK_CONTAINER (new_widget
), 1);
4235 g_signal_connect ((gpointer
) new_widget
,
4237 G_CALLBACK (insert_viewer_wrap
),
4239 gtk_widget_show (new_widget
);
4241 lttv_toolbars_add(instance_toolbar
, toolbar_item
->con
,
4242 toolbar_item
->tooltip
,
4243 toolbar_item
->pixmap
,
4251 /* Create a main window
4254 MainWindow
*construct_main_window(MainWindow
* parent
)
4256 g_debug("construct_main_window()");
4257 GtkWidget
* new_window
; /* New generated main window */
4258 MainWindow
* new_m_window
;/* New main window structure */
4259 GtkNotebook
* notebook
;
4260 LttvIAttribute
*attributes
=
4261 LTTV_IATTRIBUTE(g_object_new(LTTV_ATTRIBUTE_TYPE
, NULL
));
4262 LttvAttributeValue value
;
4265 new_m_window
= g_new(MainWindow
, 1);
4267 // Add the object's information to the module's array
4268 g_main_window_list
= g_slist_append(g_main_window_list
, new_m_window
);
4270 new_window
= create_MWindow();
4271 gtk_widget_show (new_window
);
4273 new_m_window
->mwindow
= new_window
;
4274 new_m_window
->attributes
= attributes
;
4276 g_assert(lttv_iattribute_find_by_path(attributes
,
4277 "viewers/menu", LTTV_POINTER
, &value
));
4278 *(value
.v_pointer
) = lttv_menus_new();
4280 g_assert(lttv_iattribute_find_by_path(attributes
,
4281 "viewers/toolbar", LTTV_POINTER
, &value
));
4282 *(value
.v_pointer
) = lttv_toolbars_new();
4284 add_all_menu_toolbar_constructors(new_m_window
, NULL
);
4286 g_object_set_data_full(G_OBJECT(new_window
),
4288 (gpointer
)new_m_window
,
4289 (GDestroyNotify
)g_free
);
4290 //create a default tab
4291 notebook
= (GtkNotebook
*)lookup_widget(new_m_window
->mwindow
, "MNotebook");
4292 if(notebook
== NULL
){
4293 g_info("Notebook does not exist\n");
4294 /* FIXME : destroy partially created widgets */
4295 g_free(new_m_window
);
4298 //gtk_notebook_popup_enable (GTK_NOTEBOOK(notebook));
4299 //for now there is no name field in LttvTraceset structure
4300 //Use "Traceset" as the label for the default tab
4302 GtkWidget
* parent_notebook
= lookup_widget(parent
->mwindow
, "MNotebook");
4303 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(parent_notebook
),
4304 gtk_notebook_get_current_page(GTK_NOTEBOOK(parent_notebook
)));
4310 LttvPluginTab
*ptab
;
4311 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
4312 parent_tab
= ptab
->tab
;
4314 LttvPluginTab
*ptab
= g_object_new(LTTV_TYPE_PLUGIN_TAB
, NULL
);
4316 new_m_window
, parent_tab
, notebook
, "Traceset");
4317 ptab
->parent
.top_widget
= ptab
->tab
->top_widget
;
4318 g_object_set_data_full(
4319 G_OBJECT(ptab
->tab
->vbox
),
4322 (GDestroyNotify
)tab_destructor
);
4323 new_tab
= ptab
->tab
;
4325 LttvPluginTab
*ptab
= g_object_new(LTTV_TYPE_PLUGIN_TAB
, NULL
);
4326 init_tab(ptab
->tab
, new_m_window
, NULL
, notebook
, "Traceset");
4327 ptab
->parent
.top_widget
= ptab
->tab
->top_widget
;
4328 g_object_set_data_full(
4329 G_OBJECT(ptab
->tab
->vbox
),
4332 (GDestroyNotify
)tab_destructor
);
4333 new_tab
= ptab
->tab
;
4336 /* Insert default viewers */
4338 LttvAttributeType type
;
4339 LttvAttributeName name
;
4340 LttvAttributeValue value
;
4341 LttvAttribute
*attribute
;
4343 LttvIAttribute
*attributes_global
=
4344 LTTV_IATTRIBUTE(lttv_global_attributes());
4346 g_assert(attribute
=
4347 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
4348 LTTV_IATTRIBUTE(attributes_global
),
4349 LTTV_VIEWER_CONSTRUCTORS
)));
4351 name
= g_quark_from_string("guievents");
4352 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
4354 if(type
== LTTV_POINTER
) {
4355 lttvwindow_viewer_constructor viewer_constructor
=
4356 (lttvwindow_viewer_constructor
)*value
.v_pointer
;
4357 insert_viewer(new_window
, viewer_constructor
);
4360 name
= g_quark_from_string("guicontrolflow");
4361 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
4363 if(type
== LTTV_POINTER
) {
4364 lttvwindow_viewer_constructor viewer_constructor
=
4365 (lttvwindow_viewer_constructor
)*value
.v_pointer
;
4366 insert_viewer(new_window
, viewer_constructor
);
4369 name
= g_quark_from_string("guistatistics");
4370 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
4372 if(type
== LTTV_POINTER
) {
4373 lttvwindow_viewer_constructor viewer_constructor
=
4374 (lttvwindow_viewer_constructor
)*value
.v_pointer
;
4375 insert_viewer(new_window
, viewer_constructor
);
4379 g_info("There are now : %d windows\n",g_slist_length(g_main_window_list
));
4381 return new_m_window
;
4385 /* Free the memory occupied by a tab structure
4389 void tab_destructor(LttvPluginTab
* ptab
)
4391 int i
, nb
, ref_count
;
4393 Tab
*tab
= ptab
->tab
;
4395 gtk_object_destroy(GTK_OBJECT(tab
->tooltips
));
4398 g_object_unref(tab
->attributes
);
4400 if(tab
->interrupted_state
)
4401 g_object_unref(tab
->interrupted_state
);
4404 if(tab
->traceset_info
->traceset_context
!= NULL
){
4405 //remove state update hooks
4406 lttv_state_remove_event_hooks(
4407 (LttvTracesetState
*)tab
->traceset_info
->
4409 lttv_context_fini(LTTV_TRACESET_CONTEXT(tab
->traceset_info
->
4411 g_object_unref(tab
->traceset_info
->traceset_context
);
4413 if(tab
->traceset_info
->traceset
!= NULL
) {
4414 nb
= lttv_traceset_number(tab
->traceset_info
->traceset
);
4415 for(i
= 0 ; i
< nb
; i
++) {
4416 trace
= lttv_traceset_get(tab
->traceset_info
->traceset
, i
);
4417 ref_count
= lttv_trace_get_ref_number(trace
);
4419 ltt_trace_close(lttv_trace(trace
));
4423 lttv_traceset_destroy(tab
->traceset_info
->traceset
);
4424 /* Remove the idle events requests processing function of the tab */
4425 g_idle_remove_by_data(tab
);
4427 g_slist_free(tab
->events_requests
);
4428 g_free(tab
->traceset_info
);
4430 g_object_unref(ptab
);
4434 /* Create a tab and insert it into the current main window
4437 void init_tab(Tab
*tab
, MainWindow
* mw
, Tab
*copy_tab
,
4438 GtkNotebook
* notebook
, char * label
)
4442 //LttvFilter *filter = NULL;
4444 //create a new tab data structure
4445 //tab = g_new(Tab,1);
4447 //construct and initialize the traceset_info
4448 tab
->traceset_info
= g_new(TracesetInfo
,1);
4451 tab
->traceset_info
->traceset
=
4452 lttv_traceset_copy(copy_tab
->traceset_info
->traceset
);
4454 /* Copy the previous tab's filter */
4455 /* We can clone the filter, as we copy the trace set also */
4456 /* The filter must always be in sync with the trace set */
4457 tab
->filter
= lttv_filter_clone(copy_tab
->filter
);
4459 tab
->traceset_info
->traceset
= lttv_traceset_new();
4463 lttv_attribute_write_xml(
4464 lttv_traceset_attribute(tab
->traceset_info
->traceset
),
4470 tab
->time_manager_lock
= FALSE
;
4471 tab
->current_time_manager_lock
= FALSE
;
4473 //FIXME copy not implemented in lower level
4474 tab
->traceset_info
->traceset_context
=
4475 g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
4476 g_assert(tab
->traceset_info
->traceset_context
!= NULL
);
4478 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
),
4479 tab
->traceset_info
->traceset
);
4480 //add state update hooks
4481 lttv_state_add_event_hooks(
4482 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
4484 //determine the current_time and time_window of the tab
4486 if(copy_tab
!= NULL
){
4487 tab
->time_window
= copy_tab
->time_window
;
4488 tab
->current_time
= copy_tab
->current_time
;
4490 tab
->time_window
.start_time
=
4491 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
4492 time_span
.start_time
;
4493 if(DEFAULT_TIME_WIDTH_S
<
4494 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
4495 time_span
.end_time
.tv_sec
)
4496 tmp_time
.tv_sec
= DEFAULT_TIME_WIDTH_S
;
4499 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
4500 time_span
.end_time
.tv_sec
;
4501 tmp_time
.tv_nsec
= 0;
4502 tab
->time_window
.time_width
= tmp_time
;
4503 tab
->current_time
.tv_sec
=
4504 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
4505 time_span
.start_time
.tv_sec
;
4506 tab
->current_time
.tv_nsec
=
4507 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
4508 time_span
.start_time
.tv_nsec
;
4511 tab
->attributes
= LTTV_IATTRIBUTE(g_object_new(LTTV_ATTRIBUTE_TYPE
, NULL
));
4512 tab
->interrupted_state
= g_object_new(LTTV_ATTRIBUTE_TYPE
, NULL
);
4514 tab
->vbox
= gtk_vbox_new(FALSE
, 2);
4515 tab
->top_widget
= tab
->vbox
;
4516 //g_object_set_data_full(G_OBJECT(tab->top_widget), "filter",
4517 // filter, (GDestroyNotify)lttv_filter_destroy);
4519 // g_signal_connect (G_OBJECT(tab->top_widget),
4521 // G_CALLBACK (on_top_notify),
4524 tab
->viewer_container
= gtk_vbox_new(TRUE
, 2);
4525 tab
->scrollbar
= gtk_hscrollbar_new(NULL
);
4526 //tab->multivpaned = gtk_multi_vpaned_new();
4528 gtk_box_pack_start(GTK_BOX(tab
->vbox
),
4529 tab
->viewer_container
,
4531 TRUE
, /* Give the extra space to the child */
4532 0); /* No padding */
4535 // tab->time_window = copy_tab->time_window;
4536 // tab->current_time = copy_tab->current_time;
4539 /* Create the timebar */
4541 tab
->MTimebar
= gtk_hbox_new(FALSE
, 2);
4542 gtk_widget_show(tab
->MTimebar
);
4543 tab
->tooltips
= gtk_tooltips_new();
4545 tab
->MEventBox1a
= gtk_event_box_new();
4546 gtk_widget_show(tab
->MEventBox1a
);
4547 gtk_tooltips_set_tip(tab
->tooltips
, tab
->MEventBox1a
,
4548 "Paste Start and End Times Here", "");
4549 tab
->MText1a
= gtk_label_new("Time Frame ");
4550 gtk_widget_show(tab
->MText1a
);
4551 gtk_container_add(GTK_CONTAINER(tab
->MEventBox1a
), tab
->MText1a
);
4552 tab
->MEventBox1b
= gtk_event_box_new();
4553 gtk_widget_show(tab
->MEventBox1b
);
4554 gtk_tooltips_set_tip(tab
->tooltips
, tab
->MEventBox1b
,
4555 "Paste Start Time Here", "");
4556 tab
->MText1b
= gtk_label_new("start: ");
4557 gtk_widget_show(tab
->MText1b
);
4558 gtk_container_add(GTK_CONTAINER(tab
->MEventBox1b
), tab
->MText1b
);
4559 tab
->MText2
= gtk_label_new("s");
4560 gtk_widget_show(tab
->MText2
);
4561 tab
->MText3a
= gtk_label_new("ns");
4562 gtk_widget_show(tab
->MText3a
);
4564 tab
->MEventBox3b
= gtk_event_box_new();
4565 gtk_widget_show(tab
->MEventBox3b
);
4566 gtk_tooltips_set_tip(tab
->tooltips
, tab
->MEventBox3b
,
4567 "Paste End Time Here", "");
4568 tab
->MText3b
= gtk_label_new("end:");
4569 gtk_widget_show(tab
->MText3b
);
4570 gtk_container_add(GTK_CONTAINER(tab
->MEventBox3b
), tab
->MText3b
);
4571 tab
->MText4
= gtk_label_new("s");
4572 gtk_widget_show(tab
->MText4
);
4573 tab
->MText5a
= gtk_label_new("ns");
4574 gtk_widget_show(tab
->MText5a
);
4576 tab
->MEventBox8
= gtk_event_box_new();
4577 gtk_widget_show(tab
->MEventBox8
);
4578 gtk_tooltips_set_tip(tab
->tooltips
, tab
->MEventBox8
,
4579 "Paste Time Interval here", "");
4580 tab
->MText8
= gtk_label_new("Time Interval:");
4581 gtk_widget_show(tab
->MText8
);
4582 gtk_container_add(GTK_CONTAINER(tab
->MEventBox8
), tab
->MText8
);
4583 tab
->MText9
= gtk_label_new("s");
4584 gtk_widget_show(tab
->MText9
);
4585 tab
->MText10
= gtk_label_new("ns");
4586 gtk_widget_show(tab
->MText10
);
4588 tab
->MEventBox5b
= gtk_event_box_new();
4589 gtk_widget_show(tab
->MEventBox5b
);
4590 gtk_tooltips_set_tip(tab
->tooltips
, tab
->MEventBox5b
,
4591 "Paste Current Time Here", "");
4592 tab
->MText5b
= gtk_label_new("Current Time:");
4593 gtk_widget_show(tab
->MText5b
);
4594 gtk_container_add(GTK_CONTAINER(tab
->MEventBox5b
), tab
->MText5b
);
4595 tab
->MText6
= gtk_label_new("s");
4596 gtk_widget_show(tab
->MText6
);
4597 tab
->MText7
= gtk_label_new("ns");
4598 gtk_widget_show(tab
->MText7
);
4600 tab
->MEntry1
= gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4601 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab
->MEntry1
),0);
4602 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab
->MEntry1
),TRUE
);
4603 gtk_widget_show(tab
->MEntry1
);
4604 tab
->MEntry2
= gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4605 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab
->MEntry2
),0);
4606 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab
->MEntry2
),TRUE
);
4607 gtk_widget_show(tab
->MEntry2
);
4608 tab
->MEntry3
= gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4609 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab
->MEntry3
),0);
4610 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab
->MEntry3
),TRUE
);
4611 gtk_widget_show(tab
->MEntry3
);
4612 tab
->MEntry4
= gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4613 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab
->MEntry4
),0);
4614 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab
->MEntry4
),TRUE
);
4615 gtk_widget_show(tab
->MEntry4
);
4616 tab
->MEntry5
= gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4617 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab
->MEntry5
),0);
4618 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab
->MEntry5
),TRUE
);
4619 gtk_widget_show(tab
->MEntry5
);
4620 tab
->MEntry6
= gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4621 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab
->MEntry6
),0);
4622 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab
->MEntry6
),TRUE
);
4623 gtk_widget_show(tab
->MEntry6
);
4624 tab
->MEntry7
= gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4625 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab
->MEntry7
),0);
4626 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab
->MEntry7
),TRUE
);
4627 gtk_widget_show(tab
->MEntry7
);
4628 tab
->MEntry8
= gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4629 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab
->MEntry8
),0);
4630 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab
->MEntry8
),TRUE
);
4631 gtk_widget_show(tab
->MEntry8
);
4633 GtkWidget
*temp_widget
;
4635 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEventBox1a
, FALSE
,
4637 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEventBox1b
, FALSE
,
4639 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEntry1
, FALSE
, FALSE
, 0);
4640 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MText2
, FALSE
, FALSE
, 0);
4641 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEntry2
, FALSE
, FALSE
, 0);
4642 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MText3a
, FALSE
, FALSE
, 0);
4643 temp_widget
= gtk_vseparator_new();
4644 gtk_widget_show(temp_widget
);
4645 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), temp_widget
, FALSE
, FALSE
, 0);
4646 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEventBox3b
, FALSE
,
4648 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEntry3
, FALSE
, FALSE
, 0);
4649 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MText4
, FALSE
, FALSE
, 0);
4650 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEntry4
, FALSE
, FALSE
, 0);
4651 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MText5a
, FALSE
, FALSE
, 0);
4652 temp_widget
= gtk_vseparator_new();
4653 gtk_widget_show(temp_widget
);
4654 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), temp_widget
, FALSE
, FALSE
, 0);
4655 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEventBox8
, FALSE
,
4657 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEntry7
, FALSE
, FALSE
, 0);
4658 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MText9
, FALSE
, FALSE
, 0);
4659 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEntry8
, FALSE
, FALSE
, 0);
4660 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MText10
, FALSE
, FALSE
, 0);
4662 temp_widget
= gtk_vseparator_new();
4663 gtk_widget_show(temp_widget
);
4664 gtk_box_pack_end (GTK_BOX (tab
->MTimebar
), tab
->MText7
, FALSE
, FALSE
, 0);
4665 gtk_box_pack_end (GTK_BOX (tab
->MTimebar
), tab
->MEntry6
, FALSE
, FALSE
, 0);
4666 gtk_box_pack_end (GTK_BOX (tab
->MTimebar
), tab
->MText6
, FALSE
, FALSE
, 0);
4667 gtk_box_pack_end (GTK_BOX (tab
->MTimebar
), tab
->MEntry5
, FALSE
, FALSE
, 0);
4668 gtk_box_pack_end (GTK_BOX (tab
->MTimebar
), tab
->MEventBox5b
, FALSE
,
4670 gtk_box_pack_end (GTK_BOX (tab
->MTimebar
), temp_widget
, FALSE
, FALSE
, 0);
4673 //GtkWidget *test = gtk_button_new_with_label("drop");
4674 //gtk_button_set_relief(GTK_BUTTON(test), GTK_RELIEF_NONE);
4675 //gtk_widget_show(test);
4676 //gtk_box_pack_end(GTK_BOX (tab->MTimebar), test, FALSE, FALSE, 0);
4677 //gtk_widget_add_events(tab->MText1, GDK_ALL_EVENTS_MASK);//GDK_BUTTON_PRESS_MASK);
4678 /*GtkWidget *event_box = gtk_event_box_new();
4679 gtk_widget_show(event_box);
4680 gtk_tooltips_set_tip(tooltips, event_box,
4681 "Paste Current Time Here", "");
4682 gtk_box_pack_end(GTK_BOX (tab->MTimebar), event_box, FALSE, FALSE, 0);
4683 GtkWidget *test = gtk_label_new("drop");
4684 gtk_container_add(GTK_CONTAINER(event_box), test);
4685 gtk_widget_show(test);
4686 g_signal_connect (G_OBJECT(event_box),
4687 "button-press-event",
4688 G_CALLBACK (on_MText1_paste),
4692 g_signal_connect (G_OBJECT(tab
->MEventBox1a
),
4693 "button-press-event",
4694 G_CALLBACK (on_MEventBox1a_paste
),
4697 g_signal_connect (G_OBJECT(tab
->MEventBox1b
),
4698 "button-press-event",
4699 G_CALLBACK (on_MEventBox1b_paste
),
4701 g_signal_connect (G_OBJECT(tab
->MEventBox3b
),
4702 "button-press-event",
4703 G_CALLBACK (on_MEventBox3b_paste
),
4705 g_signal_connect (G_OBJECT(tab
->MEventBox5b
),
4706 "button-press-event",
4707 G_CALLBACK (on_MEventBox5b_paste
),
4709 g_signal_connect (G_OBJECT(tab
->MEventBox8
),
4710 "button-press-event",
4711 G_CALLBACK (on_MEventBox8_paste
),
4715 gtk_box_pack_end(GTK_BOX(tab
->vbox
),
4717 FALSE
, /* Do not expand */
4718 FALSE
, /* Fill has no effect here (expand false) */
4719 0); /* No padding */
4721 gtk_box_pack_end(GTK_BOX(tab
->vbox
),
4723 FALSE
, /* Do not expand */
4724 FALSE
, /* Fill has no effect here (expand false) */
4725 0); /* No padding */
4727 g_object_set_data(G_OBJECT(tab
->viewer_container
), "focused_viewer", NULL
);
4733 // Display a label with a X
4734 GtkWidget *w_hbox = gtk_hbox_new(FALSE, 4);
4735 GtkWidget *w_label = gtk_label_new (label);
4736 GtkWidget *pixmap = create_pixmap(GTK_WIDGET(notebook), "close.png");
4737 GtkWidget *w_button = gtk_button_new ();
4738 gtk_container_add(GTK_CONTAINER(w_button), pixmap);
4739 //GtkWidget *w_button = gtk_button_new_with_label("x");
4741 gtk_button_set_relief(GTK_BUTTON(w_button), GTK_RELIEF_NONE);
4743 gtk_box_pack_start(GTK_BOX(w_hbox), w_label, TRUE, TRUE, 0);
4744 gtk_box_pack_end(GTK_BOX(w_hbox), w_button, FALSE,
4747 g_signal_connect_swapped (w_button, "clicked",
4748 G_CALLBACK (on_close_tab_X_clicked),
4751 gtk_widget_set_state(w_button, GTK_STATE_ACTIVE);
4753 gtk_widget_show (w_label);
4754 gtk_widget_show (pixmap);
4755 gtk_widget_show (w_button);
4756 gtk_widget_show (w_hbox);
4758 tab->label = w_hbox;
4762 tab
->label
= gtk_label_new (label
);
4764 gtk_widget_show(tab
->label
);
4765 gtk_widget_show(tab
->scrollbar
);
4766 gtk_widget_show(tab
->viewer_container
);
4767 gtk_widget_show(tab
->vbox
);
4768 //gtk_widget_show(tab->multivpaned);
4771 /* Start with empty events requests list */
4772 tab
->events_requests
= NULL
;
4773 tab
->events_request_pending
= FALSE
;
4776 g_signal_connect(G_OBJECT(tab
->scrollbar
), "value-changed",
4777 G_CALLBACK(scroll_value_changed_cb
), tab
);
4779 g_signal_connect ((gpointer
) tab
->MEntry1
, "value-changed",
4780 G_CALLBACK (on_MEntry1_value_changed
),
4782 g_signal_connect ((gpointer
) tab
->MEntry2
, "value-changed",
4783 G_CALLBACK (on_MEntry2_value_changed
),
4785 g_signal_connect ((gpointer
) tab
->MEntry3
, "value-changed",
4786 G_CALLBACK (on_MEntry3_value_changed
),
4788 g_signal_connect ((gpointer
) tab
->MEntry4
, "value-changed",
4789 G_CALLBACK (on_MEntry4_value_changed
),
4791 g_signal_connect ((gpointer
) tab
->MEntry5
, "value-changed",
4792 G_CALLBACK (on_MEntry5_value_changed
),
4794 g_signal_connect ((gpointer
) tab
->MEntry6
, "value-changed",
4795 G_CALLBACK (on_MEntry6_value_changed
),
4797 g_signal_connect ((gpointer
) tab
->MEntry7
, "value-changed",
4798 G_CALLBACK (on_MEntry7_value_changed
),
4800 g_signal_connect ((gpointer
) tab
->MEntry8
, "value-changed",
4801 G_CALLBACK (on_MEntry8_value_changed
),
4804 //g_signal_connect(G_OBJECT(tab->scrollbar), "changed",
4805 // G_CALLBACK(scroll_value_changed_cb), tab);
4808 //insert tab into notebook
4809 gtk_notebook_append_page(notebook
,
4812 list
= gtk_container_get_children(GTK_CONTAINER(notebook
));
4813 gtk_notebook_set_current_page(notebook
,g_list_length(list
)-1);
4814 // always show : not if(g_list_length(list)>1)
4815 gtk_notebook_set_show_tabs(notebook
, TRUE
);
4818 lttvwindow_report_time_window(tab
, copy_tab
->time_window
);
4819 lttvwindow_report_current_time(tab
, copy_tab
->current_time
);
4821 TimeWindow time_window
;
4823 time_window
.start_time
= ltt_time_zero
;
4824 time_window
.end_time
= ltt_time_add(time_window
.start_time
,
4825 lttvwindow_default_time_width
);
4826 time_window
.time_width
= lttvwindow_default_time_width
;
4827 time_window
.time_width_double
= ltt_time_to_double(time_window
.time_width
);
4829 lttvwindow_report_time_window(tab
, time_window
);
4830 lttvwindow_report_current_time(tab
, ltt_time_zero
);
4833 LttvTraceset
*traceset
= tab
->traceset_info
->traceset
;
4834 SetTraceset(tab
, traceset
);
4838 * execute_events_requests
4840 * Idle function that executes the pending requests for a tab.
4842 * @return return value : TRUE : keep the idle function, FALSE : remove it.
4844 gboolean
execute_events_requests(Tab
*tab
)
4846 return ( lttvwindow_process_pending_requests(tab
) );
4850 void create_main_window_with_trace_list(GSList
*traces
)
4852 GSList
*iter
= NULL
;
4855 MainWindow
*mw
= construct_main_window(NULL
);
4856 GtkWidget
*widget
= mw
->mwindow
;
4858 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
4859 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
4860 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
4861 LttvPluginTab
*ptab
;
4865 ptab
= create_new_tab(widget
, NULL
);
4868 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
4872 for(iter
=traces
; iter
!=NULL
; iter
=g_slist_next(iter
)) {
4873 gchar
*path
= (gchar
*)iter
->data
;
4875 gchar abs_path
[PATH_MAX
];
4879 get_absolute_pathname(path
, abs_path
);
4880 trace_v
= lttvwindowtraces_get_trace_by_name(abs_path
);
4881 if(trace_v
== NULL
) {
4882 trace
= ltt_trace_open(abs_path
);
4884 g_warning("cannot open trace %s", abs_path
);
4886 GtkWidget
*dialogue
=
4887 gtk_message_dialog_new(
4888 GTK_WINDOW(gtk_widget_get_toplevel(widget
)),
4889 GTK_DIALOG_MODAL
|GTK_DIALOG_DESTROY_WITH_PARENT
,
4892 "Cannot open trace : maybe you should enter in the directory"
4894 gtk_dialog_run(GTK_DIALOG(dialogue
));
4895 gtk_widget_destroy(dialogue
);
4897 trace_v
= lttv_trace_new(trace
);
4898 lttvwindowtraces_add_trace(trace_v
);
4899 lttvwindow_add_trace(tab
, trace_v
);
4902 lttvwindow_add_trace(tab
, trace_v
);
4906 LttvTraceset
*traceset
;
4908 traceset
= tab
->traceset_info
->traceset
;
4909 SetTraceset(tab
, traceset
);