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>
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
] = "";
65 MainWindow
* get_window_data_struct(GtkWidget
* widget
);
66 char * get_load_module(MainWindow
*mw
,
67 char ** load_module_name
, int nb_module
);
68 char * get_unload_module(MainWindow
*mw
,
69 char ** loaded_module_name
, int nb_module
);
70 char * get_remove_trace(MainWindow
*mw
, char ** all_trace_name
, int nb_trace
);
71 char * get_selection(MainWindow
*mw
,
72 char ** all_name
, int nb
, char *title
, char * column_title
);
73 Tab
* create_tab(MainWindow
* mw
, Tab
*copy_tab
,
74 GtkNotebook
* notebook
, char * label
);
76 static void insert_viewer(GtkWidget
* widget
, lttvwindow_viewer_constructor constructor
);
78 Tab
*create_new_tab(GtkWidget
* widget
, gpointer user_data
);
80 static gboolean
lttvwindow_process_pending_requests(Tab
*tab
);
94 /* Pasting routines */
96 static void MEventBox1a_receive(GtkClipboard
*clipboard
,
100 if(text
== NULL
) return;
101 Tab
*tab
= (Tab
*)data
;
102 gchar buffer
[CLIP_BUF
];
103 gchar
*ptr
= buffer
, *ptr_ssec
, *ptr_snsec
, *ptr_esec
, *ptr_ensec
;
105 strncpy(buffer
, text
, CLIP_BUF
);
108 while(!isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
109 /* remove leading junk */
111 while(isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
112 /* read all the first number */
116 while(!isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
117 /* remove leading junk */
119 while(isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
120 /* read all the first number */
124 while(!isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
125 /* remove leading junk */
127 while(isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
128 /* read all the first number */
132 while(!isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
133 /* remove leading junk */
135 while(isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
136 /* read all the first number */
139 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry1
),
140 (double)strtoul(ptr_ssec
, NULL
, 10));
141 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry2
),
142 (double)strtoul(ptr_snsec
, NULL
, 10));
143 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry3
),
144 (double)strtoul(ptr_esec
, NULL
, 10));
145 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry4
),
146 (double)strtoul(ptr_ensec
, NULL
, 10));
149 static gboolean
on_MEventBox1a_paste(GtkWidget
*widget
, GdkEventButton
*event
,
152 Tab
*tab
= (Tab
*)data
;
154 GtkClipboard
*clip
= gtk_clipboard_get_for_display(gdk_display_get_default(),
155 GDK_SELECTION_PRIMARY
);
156 gtk_clipboard_request_text(clip
,
157 (GtkClipboardTextReceivedFunc
)MEventBox1a_receive
,
164 static void MEventBox1b_receive(GtkClipboard
*clipboard
,
168 if(text
== NULL
) return;
169 Tab
*tab
= (Tab
*)data
;
170 gchar buffer
[CLIP_BUF
];
171 gchar
*ptr
= buffer
, *ptr_sec
, *ptr_nsec
;
173 strncpy(buffer
, text
, CLIP_BUF
);
175 while(!isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
176 /* remove leading junk */
178 while(isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
179 /* read all the first number */
183 while(!isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
184 /* remove leading junk */
186 while(isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
187 /* read all the first number */
190 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry1
),
191 (double)strtoul(ptr_sec
, NULL
, 10));
192 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry2
),
193 (double)strtoul(ptr_nsec
, NULL
, 10));
197 static gboolean
on_MEventBox1b_paste(GtkWidget
*widget
, GdkEventButton
*event
,
200 Tab
*tab
= (Tab
*)data
;
202 GtkClipboard
*clip
= gtk_clipboard_get_for_display(gdk_display_get_default(),
203 GDK_SELECTION_PRIMARY
);
204 gtk_clipboard_request_text(clip
,
205 (GtkClipboardTextReceivedFunc
)MEventBox1b_receive
,
211 static void MEventBox3b_receive(GtkClipboard
*clipboard
,
215 if(text
== NULL
) return;
216 Tab
*tab
= (Tab
*)data
;
217 gchar buffer
[CLIP_BUF
];
218 gchar
*ptr
= buffer
, *ptr_sec
, *ptr_nsec
;
220 strncpy(buffer
, text
, CLIP_BUF
);
222 while(!isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
223 /* remove leading junk */
225 while(isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
226 /* read all the first number */
230 while(!isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
231 /* remove leading junk */
233 while(isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
234 /* read all the first number */
237 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry3
),
238 (double)strtoul(ptr_sec
, NULL
, 10));
239 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry4
),
240 (double)strtoul(ptr_nsec
, NULL
, 10));
244 static gboolean
on_MEventBox3b_paste(GtkWidget
*widget
, GdkEventButton
*event
,
247 Tab
*tab
= (Tab
*)data
;
249 GtkClipboard
*clip
= gtk_clipboard_get_for_display(gdk_display_get_default(),
250 GDK_SELECTION_PRIMARY
);
251 gtk_clipboard_request_text(clip
,
252 (GtkClipboardTextReceivedFunc
)MEventBox3b_receive
,
258 static void MEventBox5b_receive(GtkClipboard
*clipboard
,
262 if(text
== NULL
) return;
263 Tab
*tab
= (Tab
*)data
;
264 gchar buffer
[CLIP_BUF
];
265 gchar
*ptr
= buffer
, *ptr_sec
, *ptr_nsec
;
267 strncpy(buffer
, text
, CLIP_BUF
);
269 while(!isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
270 /* remove leading junk */
272 while(isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
273 /* read all the first number */
277 while(!isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
278 /* remove leading junk */
280 while(isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
281 /* read all the first number */
284 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry5
),
285 (double)strtoul(ptr_sec
, NULL
, 10));
286 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry6
),
287 (double)strtoul(ptr_nsec
, NULL
, 10));
291 static gboolean
on_MEventBox5b_paste(GtkWidget
*widget
, GdkEventButton
*event
,
294 Tab
*tab
= (Tab
*)data
;
296 GtkClipboard
*clip
= gtk_clipboard_get_for_display(gdk_display_get_default(),
297 GDK_SELECTION_PRIMARY
);
298 gtk_clipboard_request_text(clip
,
299 (GtkClipboardTextReceivedFunc
)MEventBox5b_receive
,
305 static void MEventBox8_receive(GtkClipboard
*clipboard
,
309 if(text
== NULL
) return;
310 Tab
*tab
= (Tab
*)data
;
311 gchar buffer
[CLIP_BUF
];
312 gchar
*ptr
= buffer
, *ptr_sec
, *ptr_nsec
;
314 strncpy(buffer
, text
, CLIP_BUF
);
316 while(!isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
317 /* remove leading junk */
319 while(isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
320 /* read all the first number */
324 while(!isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
325 /* remove leading junk */
327 while(isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
328 /* read all the first number */
331 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry7
),
332 (double)strtoul(ptr_sec
, NULL
, 10));
333 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry8
),
334 (double)strtoul(ptr_nsec
, NULL
, 10));
338 static gboolean
on_MEventBox8_paste(GtkWidget
*widget
, GdkEventButton
*event
,
341 Tab
*tab
= (Tab
*)data
;
343 GtkClipboard
*clip
= gtk_clipboard_get_for_display(gdk_display_get_default(),
344 GDK_SELECTION_PRIMARY
);
345 gtk_clipboard_request_text(clip
,
346 (GtkClipboardTextReceivedFunc
)MEventBox8_receive
,
352 static gboolean
viewer_grab_focus(GtkWidget
*widget
, GdkEventButton
*event
,
355 GtkWidget
*viewer
= GTK_WIDGET(data
);
356 GtkWidget
*viewer_container
= gtk_widget_get_parent(viewer
);
358 g_debug("FOCUS GRABBED");
359 g_object_set_data(G_OBJECT(viewer_container
), "focused_viewer", viewer
);
364 static void connect_focus_recursive(GtkWidget
*widget
,
367 if(GTK_IS_CONTAINER(widget
)) {
368 gtk_container_forall(GTK_CONTAINER(widget
),
369 (GtkCallback
)connect_focus_recursive
,
373 if(GTK_IS_TREE_VIEW(widget
)) {
374 gtk_tree_view_set_headers_clickable(GTK_TREE_VIEW(widget
), TRUE
);
376 gtk_widget_add_events(widget
, GDK_BUTTON_PRESS_MASK
);
377 g_signal_connect (G_OBJECT(widget
),
378 "button-press-event",
379 G_CALLBACK (viewer_grab_focus
),
383 /* Stop all the processings and call gtk_main_quit() */
384 static void mainwindow_quit()
386 lttvwindowtraces_unregister_requests(g_quark_from_string("stats"));
387 lttvwindowtraces_unregister_requests(g_quark_from_string("state"));
388 lttvwindowtraces_unregister_computation_hooks(g_quark_from_string("stats"));
389 lttvwindowtraces_unregister_computation_hooks(g_quark_from_string("state"));
395 /* insert_viewer function constructs an instance of a viewer first,
396 * then inserts the widget of the instance into the container of the
401 insert_viewer_wrap(GtkWidget
*menuitem
, gpointer user_data
)
403 insert_viewer((GtkWidget
*)menuitem
, (lttvwindow_viewer_constructor
)user_data
);
407 /* internal functions */
408 void insert_viewer(GtkWidget
* widget
, lttvwindow_viewer_constructor constructor
)
410 GtkWidget
* viewer_container
;
411 MainWindow
* mw_data
= get_window_data_struct(widget
);
412 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
414 TimeInterval
* time_interval
;
415 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
416 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
420 tab
= create_new_tab(widget
, NULL
);
422 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
425 viewer_container
= tab
->viewer_container
;
427 viewer
= (GtkWidget
*)constructor(tab
);
430 //gtk_multivpaned_widget_add(GTK_MULTIVPANED(multivpaned), viewer);
432 gtk_box_pack_end(GTK_BOX(viewer_container
),
438 /* We want to connect the viewer_grab_focus to EVERY
439 * child of this widget. The little trick is to get each child
440 * of each GTK_CONTAINER, even subchildren.
442 connect_focus_recursive(viewer
, viewer
);
447 * Function to set/update traceset for the viewers
448 * @param tab viewer's tab
449 * @param traceset traceset of the main window.
451 * 0 : traceset updated
452 * 1 : no traceset hooks to update; not an error.
455 int SetTraceset(Tab
* tab
, LttvTraceset
*traceset
)
457 LttvTracesetContext
*tsc
=
458 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
459 TimeInterval time_span
= tsc
->time_span
;
460 TimeWindow new_time_window
= tab
->time_window
;
461 LttTime new_current_time
= tab
->current_time
;
463 /* Set the tab's time window and current time if
465 if(ltt_time_compare(tab
->time_window
.start_time
, time_span
.start_time
) < 0
466 || ltt_time_compare(tab
->time_window
.end_time
,
467 time_span
.end_time
) > 0) {
468 new_time_window
.start_time
= time_span
.start_time
;
470 new_current_time
= time_span
.start_time
;
474 if(ltt_time_compare(lttvwindow_default_time_width
,
475 ltt_time_sub(time_span
.end_time
, time_span
.start_time
)) < 0
477 ltt_time_compare(time_span
.end_time
, time_span
.start_time
) == 0)
478 tmp_time
= lttvwindow_default_time_width
;
480 tmp_time
= time_span
.end_time
;
482 new_time_window
.time_width
= tmp_time
;
483 new_time_window
.time_width_double
= ltt_time_to_double(tmp_time
);
484 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
485 new_time_window
.time_width
) ;
492 GtkAdjustment
*adjustment
= gtk_range_get_adjustment(GTK_RANGE(tab
->scrollbar
));
493 LttTime upper
= ltt_time_sub(time_span
.end_time
, time_span
.start_time
);
495 g_object_set(G_OBJECT(adjustment
),
499 ltt_time_to_double(upper
)
500 * NANOSECONDS_PER_SECOND
, /* upper */
502 ltt_time_to_double(tab
->time_window
.time_width
)
503 / SCROLL_STEP_PER_PAGE
504 * NANOSECONDS_PER_SECOND
, /* step increment */
506 ltt_time_to_double(tab
->time_window
.time_width
)
507 * NANOSECONDS_PER_SECOND
, /* page increment */
509 ltt_time_to_double(tab
->time_window
.time_width
)
510 * NANOSECONDS_PER_SECOND
, /* page size */
512 gtk_adjustment_changed(adjustment
);
514 g_object_set(G_OBJECT(adjustment
),
517 ltt_time_sub(tab
->time_window
.start_time
, time_span
.start_time
))
518 * NANOSECONDS_PER_SECOND
, /* value */
520 gtk_adjustment_value_changed(adjustment
);
522 /* set the time bar. The value callbacks will change their nsec themself */
524 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry1
),
525 (double)time_span
.start_time
.tv_sec
,
526 (double)time_span
.end_time
.tv_sec
);
529 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry3
),
530 (double)time_span
.start_time
.tv_sec
,
531 (double)time_span
.end_time
.tv_sec
);
533 /* current seconds */
534 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry5
),
535 (double)time_span
.start_time
.tv_sec
,
536 (double)time_span
.end_time
.tv_sec
);
539 /* Finally, call the update hooks of the viewers */
541 LttvAttributeValue value
;
545 g_assert( lttv_iattribute_find_by_path(tab
->attributes
,
546 "hooks/updatetraceset", LTTV_POINTER
, &value
));
548 tmp
= (LttvHooks
*)*(value
.v_pointer
);
549 if(tmp
== NULL
) retval
= 1;
550 else lttv_hooks_call(tmp
,traceset
);
552 time_change_manager(tab
, new_time_window
);
553 current_time_change_manager(tab
, new_current_time
);
559 * Function to set/update filter for the viewers
560 * @param tab viewer's tab
561 * @param filter filter of the main window.
564 * 0 : filters updated
565 * 1 : no filter hooks to update; not an error.
568 int SetFilter(Tab
* tab
, gpointer filter
)
571 LttvAttributeValue value
;
573 g_assert(lttv_iattribute_find_by_path(tab
->attributes
,
574 "hooks/updatefilter", LTTV_POINTER
, &value
));
576 tmp
= (LttvHooks
*)*(value
.v_pointer
);
578 if(tmp
== NULL
) return 1;
579 lttv_hooks_call(tmp
,filter
);
587 * Function to redraw each viewer belonging to the current tab
588 * @param tab viewer's tab
591 void update_traceset(Tab
*tab
)
593 LttvAttributeValue value
;
595 g_assert(lttv_iattribute_find_by_path(tab
->attributes
,
596 "hooks/updatetraceset", LTTV_POINTER
, &value
));
597 tmp
= (LttvHooks
*)*(value
.v_pointer
);
598 if(tmp
== NULL
) return;
599 lttv_hooks_call(tmp
, NULL
);
603 /* get_label function is used to get user input, it displays an input
604 * box, which allows user to input a string
607 void get_label_string (GtkWidget
* text
, gchar
* label
)
609 GtkEntry
* entry
= (GtkEntry
*)text
;
610 if(strlen(gtk_entry_get_text(entry
))!=0)
611 strcpy(label
,gtk_entry_get_text(entry
));
614 gboolean
get_label(MainWindow
* mw
, gchar
* str
, gchar
* dialogue_title
, gchar
* label_str
)
616 GtkWidget
* dialogue
;
621 dialogue
= gtk_dialog_new_with_buttons(dialogue_title
,NULL
,
623 GTK_STOCK_OK
,GTK_RESPONSE_ACCEPT
,
624 GTK_STOCK_CANCEL
,GTK_RESPONSE_REJECT
,
627 label
= gtk_label_new(label_str
);
628 gtk_widget_show(label
);
630 text
= gtk_entry_new();
631 gtk_widget_show(text
);
633 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialogue
)->vbox
), label
,TRUE
, TRUE
,0);
634 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialogue
)->vbox
), text
,FALSE
, FALSE
,0);
636 id
= gtk_dialog_run(GTK_DIALOG(dialogue
));
638 case GTK_RESPONSE_ACCEPT
:
639 get_label_string(text
,str
);
640 gtk_widget_destroy(dialogue
);
642 case GTK_RESPONSE_REJECT
:
644 gtk_widget_destroy(dialogue
);
651 /* get_window_data_struct function is actually a lookup function,
652 * given a widget which is in the tree of the main window, it will
653 * return the MainWindow data structure associated with main window
656 MainWindow
* get_window_data_struct(GtkWidget
* widget
)
659 MainWindow
* mw_data
;
661 mw
= lookup_widget(widget
, "MWindow");
663 g_info("Main window does not exist\n");
667 mw_data
= (MainWindow
*) g_object_get_data(G_OBJECT(mw
),"main_window_data");
669 g_warning("Main window data does not exist\n");
676 /* create_new_window function, just constructs a new main window
679 void create_new_window(GtkWidget
* widget
, gpointer user_data
, gboolean clone
)
681 MainWindow
* parent
= get_window_data_struct(widget
);
684 g_info("Clone : use the same traceset\n");
685 construct_main_window(parent
);
687 g_info("Empty : traceset is set to NULL\n");
688 construct_main_window(NULL
);
692 /* Get the currently focused viewer.
693 * If no viewer is focused, use the first one.
695 * If no viewer available, return NULL.
697 GtkWidget
*viewer_container_focus(GtkWidget
*container
)
701 widget
= (GtkWidget
*)g_object_get_data(G_OBJECT(container
),
705 g_debug("no widget focused");
706 GList
*children
= gtk_container_get_children(GTK_CONTAINER(container
));
709 widget
= GTK_WIDGET(children
->data
);
710 g_object_set_data(G_OBJECT(container
),
720 gint
viewer_container_position(GtkWidget
*container
, GtkWidget
*child
)
723 if(child
== NULL
) return -1;
727 memset(&value
, 0, sizeof(GValue
));
728 g_value_init(&value
, G_TYPE_INT
);
729 gtk_container_child_get_property(GTK_CONTAINER(container
),
733 pos
= g_value_get_int(&value
);
739 /* move_*_viewer functions move the selected view up/down in
743 void move_down_viewer(GtkWidget
* widget
, gpointer user_data
)
745 MainWindow
* mw
= get_window_data_struct(widget
);
746 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
748 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
749 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
755 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
758 //gtk_multivpaned_widget_move_up(GTK_MULTIVPANED(tab->multivpaned));
760 /* change the position in the vbox */
761 GtkWidget
*focus_widget
;
763 focus_widget
= viewer_container_focus(tab
->viewer_container
);
764 position
= viewer_container_position(tab
->viewer_container
, focus_widget
);
767 /* can move up one position */
768 gtk_box_reorder_child(GTK_BOX(tab
->viewer_container
),
775 void move_up_viewer(GtkWidget
* widget
, gpointer user_data
)
777 MainWindow
* mw
= get_window_data_struct(widget
);
778 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
780 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
781 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
787 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
790 //gtk_multivpaned_widget_move_down(GTK_MULTIVPANED(tab->multivpaned));
791 /* change the position in the vbox */
792 GtkWidget
*focus_widget
;
794 focus_widget
= viewer_container_focus(tab
->viewer_container
);
795 position
= viewer_container_position(tab
->viewer_container
, focus_widget
);
799 g_list_length(gtk_container_get_children(
800 GTK_CONTAINER(tab
->viewer_container
)))-1
802 /* can move down one position */
803 gtk_box_reorder_child(GTK_BOX(tab
->viewer_container
),
811 /* delete_viewer deletes the selected viewer in the current tab
814 void delete_viewer(GtkWidget
* widget
, gpointer user_data
)
816 MainWindow
* mw
= get_window_data_struct(widget
);
817 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
819 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
820 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
826 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
829 //gtk_multivpaned_widget_delete(GTK_MULTIVPANED(tab->multivpaned));
831 GtkWidget
*focus_widget
= viewer_container_focus(tab
->viewer_container
);
833 if(focus_widget
!= NULL
)
834 gtk_widget_destroy(focus_widget
);
836 g_object_set_data(G_OBJECT(tab
->viewer_container
), "focused_viewer", NULL
);
840 /* open_traceset will open a traceset saved in a file
841 * Right now, it is not finished yet, (not working)
845 void open_traceset(GtkWidget
* widget
, gpointer user_data
)
849 LttvTraceset
* traceset
;
850 MainWindow
* mw_data
= get_window_data_struct(widget
);
851 GtkFileSelection
* file_selector
=
852 (GtkFileSelection
*)gtk_file_selection_new("Select a traceset");
854 gtk_file_selection_hide_fileop_buttons(file_selector
);
856 gtk_window_set_transient_for(GTK_WINDOW(file_selector
),
857 GTK_WINDOW(mw_data
->mwindow
));
859 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
861 case GTK_RESPONSE_ACCEPT
:
862 case GTK_RESPONSE_OK
:
863 dir
= gtk_file_selection_get_selections (file_selector
);
864 traceset
= lttv_traceset_load(dir
[0]);
865 g_info("Open a trace set %s\n", dir
[0]);
868 case GTK_RESPONSE_REJECT
:
869 case GTK_RESPONSE_CANCEL
:
871 gtk_widget_destroy((GtkWidget
*)file_selector
);
877 /* lttvwindow_process_pending_requests
879 * This internal function gets called by g_idle, taking care of the pending
880 * requests. It is responsible for concatenation of time intervals and position
881 * requests. It does it with the following algorithm organizing process traceset
882 * calls. Here is the detailed description of the way it works :
884 * - Events Requests Servicing Algorithm
886 * Data structures necessary :
888 * List of requests added to context : list_in
889 * List of requests not added to context : list_out
894 * list_out : many events requests
896 * FIXME : insert rest of algorithm here
900 #define list_out tab->events_requests
902 gboolean
lttvwindow_process_pending_requests(Tab
*tab
)
905 LttvTracesetContext
*tsc
;
906 LttvTracefileContext
*tfc
;
907 GSList
*list_in
= NULL
;
911 LttvTracesetContextPosition
*end_position
;
914 g_critical("Foreground processing : tab does not exist. Processing removed.");
918 /* There is no events requests pending : we should never have been called! */
919 g_assert(g_slist_length(list_out
) != 0);
921 tsc
= LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
923 //set the cursor to be X shape, indicating that the computer is busy in doing its job
925 new = gdk_cursor_new(GDK_X_CURSOR
);
926 widget
= lookup_widget(tab
->mw
->mwindow
, "MToolbar1");
927 win
= gtk_widget_get_parent_window(widget
);
928 gdk_window_set_cursor(win
, new);
929 gdk_cursor_unref(new);
930 gdk_window_stick(win
);
931 gdk_window_unstick(win
);
934 g_debug("SIZE events req len : %d", g_slist_length(list_out
));
936 /* Preliminary check for no trace in traceset */
937 /* Unregister the routine if empty, empty list_out too */
938 if(lttv_traceset_number(tsc
->ts
) == 0) {
940 /* - For each req in list_out */
941 GSList
*iter
= list_out
;
943 while(iter
!= NULL
) {
945 gboolean remove
= FALSE
;
946 gboolean free_data
= FALSE
;
947 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
949 /* - Call end request for req */
950 if(events_request
->servicing
== TRUE
)
951 lttv_hooks_call(events_request
->after_request
, (gpointer
)tsc
);
953 /* - remove req from list_out */
954 /* Destroy the request */
961 GSList
*remove_iter
= iter
;
963 iter
= g_slist_next(iter
);
964 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
965 list_out
= g_slist_remove_link(list_out
, remove_iter
);
966 } else { // not remove
967 iter
= g_slist_next(iter
);
972 /* 0.1 Lock Traces */
977 iter_trace
<lttv_traceset_number(tsc
->ts
);
979 LttvTrace
*trace_v
= lttv_traceset_get(tsc
->ts
, iter_trace
);
981 if(lttvwindowtraces_lock(trace_v
) != 0) {
982 g_critical("Foreground processing : Unable to get trace lock");
983 return TRUE
; /* Cannot get lock, try later */
988 /* 0.2 Seek tracefiles positions to context position */
989 //g_assert(lttv_process_traceset_seek_position(tsc, sync_position) == 0);
990 lttv_process_traceset_synchronize_tracefiles(tsc
);
993 /* Events processing algorithm implementation */
994 /* Warning : the gtk_events_pending takes a LOT of cpu time. So what we do
995 * instead is to leave the control to GTK and take it back.
997 /* A. Servicing loop */
998 //while( (g_slist_length(list_in) != 0 || g_slist_length(list_out) != 0)) {
999 if((g_slist_length(list_in
) != 0 || g_slist_length(list_out
) != 0)) {
1001 /* 1. If list_in is empty (need a seek) */
1002 if( g_slist_length(list_in
) == 0 ) {
1004 /* list in is empty, need a seek */
1006 /* 1.1 Add requests to list_in */
1007 GSList
*ltime
= NULL
;
1008 GSList
*lpos
= NULL
;
1009 GSList
*iter
= NULL
;
1011 /* 1.1.1 Find all time requests with the lowest start time in list_out
1014 if(g_slist_length(list_out
) > 0)
1015 ltime
= g_slist_append(ltime
, g_slist_nth_data(list_out
, 0));
1016 for(iter
=g_slist_nth(list_out
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
1017 /* Find all time requests with the lowest start time in list_out */
1018 EventsRequest
*event_request_ltime
= (EventsRequest
*)g_slist_nth_data(ltime
, 0);
1019 EventsRequest
*event_request_list_out
= (EventsRequest
*)iter
->data
;
1022 comp
= ltt_time_compare(event_request_ltime
->start_time
,
1023 event_request_list_out
->start_time
);
1025 ltime
= g_slist_append(ltime
, event_request_list_out
);
1027 /* Remove all elements from ltime, and add current */
1028 while(ltime
!= NULL
)
1029 ltime
= g_slist_delete_link(ltime
, g_slist_nth(ltime
, 0));
1030 ltime
= g_slist_append(ltime
, event_request_list_out
);
1034 /* 1.1.2 Find all position requests with the lowest position in list_out
1037 if(g_slist_length(list_out
) > 0)
1038 lpos
= g_slist_append(lpos
, g_slist_nth_data(list_out
, 0));
1039 for(iter
=g_slist_nth(list_out
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
1040 /* Find all position requests with the lowest position in list_out */
1041 EventsRequest
*event_request_lpos
= (EventsRequest
*)g_slist_nth_data(lpos
, 0);
1042 EventsRequest
*event_request_list_out
= (EventsRequest
*)iter
->data
;
1045 if(event_request_lpos
->start_position
!= NULL
1046 && event_request_list_out
->start_position
!= NULL
)
1048 comp
= lttv_traceset_context_pos_pos_compare
1049 (event_request_lpos
->start_position
,
1050 event_request_list_out
->start_position
);
1055 lpos
= g_slist_append(lpos
, event_request_list_out
);
1057 /* Remove all elements from lpos, and add current */
1059 lpos
= g_slist_delete_link(lpos
, g_slist_nth(lpos
, 0));
1060 lpos
= g_slist_append(lpos
, event_request_list_out
);
1065 EventsRequest
*event_request_lpos
= (EventsRequest
*)g_slist_nth_data(lpos
, 0);
1066 EventsRequest
*event_request_ltime
= (EventsRequest
*)g_slist_nth_data(ltime
, 0);
1067 LttTime lpos_start_time
;
1069 if(event_request_lpos
!= NULL
1070 && event_request_lpos
->start_position
!= NULL
) {
1071 lpos_start_time
= lttv_traceset_context_position_get_time(
1072 event_request_lpos
->start_position
);
1075 /* 1.1.3 If lpos.start time < ltime */
1076 if(event_request_lpos
!= NULL
1077 && event_request_lpos
->start_position
!= NULL
1078 && ltt_time_compare(lpos_start_time
,
1079 event_request_ltime
->start_time
)<0) {
1080 /* Add lpos to list_in, remove them from list_out */
1081 for(iter
=lpos
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
1082 /* Add to list_in */
1083 EventsRequest
*event_request_lpos
=
1084 (EventsRequest
*)iter
->data
;
1086 list_in
= g_slist_append(list_in
, event_request_lpos
);
1087 /* Remove from list_out */
1088 list_out
= g_slist_remove(list_out
, event_request_lpos
);
1091 /* 1.1.4 (lpos.start time >= ltime) */
1092 /* Add ltime to list_in, remove them from list_out */
1094 for(iter
=ltime
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
1095 /* Add to list_in */
1096 EventsRequest
*event_request_ltime
=
1097 (EventsRequest
*)iter
->data
;
1099 list_in
= g_slist_append(list_in
, event_request_ltime
);
1100 /* Remove from list_out */
1101 list_out
= g_slist_remove(list_out
, event_request_ltime
);
1106 g_slist_free(ltime
);
1111 tfc
= lttv_traceset_context_get_current_tfc(tsc
);
1112 g_assert(g_slist_length(list_in
)>0);
1113 EventsRequest
*events_request
= g_slist_nth_data(list_in
, 0);
1116 /* 1.2.1 If first request in list_in is a time request */
1117 if(events_request
->start_position
== NULL
) {
1118 /* - If first req in list_in start time != current time */
1119 if(tfc
== NULL
|| ltt_time_compare(events_request
->start_time
,
1120 tfc
->timestamp
) != 0)
1121 /* - Seek to that time */
1122 g_debug("SEEK TIME : %lu, %lu", events_request
->start_time
.tv_sec
,
1123 events_request
->start_time
.tv_nsec
);
1124 //lttv_process_traceset_seek_time(tsc, events_request->start_time);
1125 lttv_state_traceset_seek_time_closest(LTTV_TRACESET_STATE(tsc
),
1126 events_request
->start_time
);
1128 /* Process the traceset with only state hooks */
1130 lttv_process_traceset_middle(tsc
,
1131 events_request
->start_time
,
1134 g_assert(seek_count
< LTTV_STATE_SAVE_INTERVAL
);
1140 LttvTracefileContext
*tfc
=
1141 lttv_traceset_context_get_current_tfc(tsc
);
1142 /* Else, the first request in list_in is a position request */
1143 /* If first req in list_in pos != current pos */
1144 g_assert(events_request
->start_position
!= NULL
);
1145 g_debug("SEEK POS time : %lu, %lu",
1146 lttv_traceset_context_position_get_time(
1147 events_request
->start_position
).tv_sec
,
1148 lttv_traceset_context_position_get_time(
1149 events_request
->start_position
).tv_nsec
);
1152 g_debug("SEEK POS context time : %lu, %lu",
1153 tfc
->timestamp
.tv_sec
,
1154 tfc
->timestamp
.tv_nsec
);
1156 g_debug("SEEK POS context time : %lu, %lu",
1157 ltt_time_infinite
.tv_sec
,
1158 ltt_time_infinite
.tv_nsec
);
1160 g_assert(events_request
->start_position
!= NULL
);
1161 if(lttv_traceset_context_ctx_pos_compare(tsc
,
1162 events_request
->start_position
) != 0) {
1163 /* 1.2.2.1 Seek to that position */
1164 g_debug("SEEK POSITION");
1165 //lttv_process_traceset_seek_position(tsc, events_request->start_position);
1166 pos_time
= lttv_traceset_context_position_get_time(
1167 events_request
->start_position
);
1169 lttv_state_traceset_seek_time_closest(LTTV_TRACESET_STATE(tsc
),
1172 /* Process the traceset with only state hooks */
1174 lttv_process_traceset_middle(tsc
,
1177 events_request
->start_position
);
1178 g_assert(lttv_traceset_context_ctx_pos_compare(tsc
,
1179 events_request
->start_position
) == 0);
1186 /* 1.3 Add hooks and call before request for all list_in members */
1188 GSList
*iter
= NULL
;
1190 for(iter
=list_in
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
1191 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1192 /* 1.3.1 If !servicing */
1193 if(events_request
->servicing
== FALSE
) {
1194 /* - begin request hooks called
1195 * - servicing = TRUE
1197 lttv_hooks_call(events_request
->before_request
, (gpointer
)tsc
);
1198 events_request
->servicing
= TRUE
;
1200 /* 1.3.2 call before chunk
1201 * 1.3.3 events hooks added
1203 if(events_request
->trace
== -1)
1204 lttv_process_traceset_begin(tsc
,
1205 events_request
->before_chunk_traceset
,
1206 events_request
->before_chunk_trace
,
1207 events_request
->before_chunk_tracefile
,
1208 events_request
->event
,
1209 events_request
->event_by_id
);
1211 guint nb_trace
= lttv_traceset_number(tsc
->ts
);
1212 g_assert((guint
)events_request
->trace
< nb_trace
&&
1213 events_request
->trace
> -1);
1214 LttvTraceContext
*tc
= tsc
->traces
[events_request
->trace
];
1216 lttv_hooks_call(events_request
->before_chunk_traceset
, tsc
);
1218 lttv_trace_context_add_hooks(tc
,
1219 events_request
->before_chunk_trace
,
1220 events_request
->before_chunk_tracefile
,
1221 events_request
->event
,
1222 events_request
->event_by_id
);
1227 /* 2. Else, list_in is not empty, we continue a read */
1230 /* 2.0 For each req of list_in */
1231 GSList
*iter
= list_in
;
1233 while(iter
!= NULL
) {
1235 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1237 /* - Call before chunk
1238 * - events hooks added
1240 if(events_request
->trace
== -1)
1241 lttv_process_traceset_begin(tsc
,
1242 events_request
->before_chunk_traceset
,
1243 events_request
->before_chunk_trace
,
1244 events_request
->before_chunk_tracefile
,
1245 events_request
->event
,
1246 events_request
->event_by_id
);
1248 guint nb_trace
= lttv_traceset_number(tsc
->ts
);
1249 g_assert((guint
)events_request
->trace
< nb_trace
&&
1250 events_request
->trace
> -1);
1251 LttvTraceContext
*tc
= tsc
->traces
[events_request
->trace
];
1253 lttv_hooks_call(events_request
->before_chunk_traceset
, tsc
);
1255 lttv_trace_context_add_hooks(tc
,
1256 events_request
->before_chunk_trace
,
1257 events_request
->before_chunk_tracefile
,
1258 events_request
->event
,
1259 events_request
->event_by_id
);
1262 iter
= g_slist_next(iter
);
1267 tfc
= lttv_traceset_context_get_current_tfc(tsc
);
1269 /* 2.1 For each req of list_out */
1270 GSList
*iter
= list_out
;
1272 while(iter
!= NULL
) {
1274 gboolean remove
= FALSE
;
1275 gboolean free_data
= FALSE
;
1276 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1278 /* if req.start time == current context time
1279 * or req.start position == current position*/
1280 if( ltt_time_compare(events_request
->start_time
,
1281 tfc
->timestamp
) == 0
1283 (events_request
->start_position
!= NULL
1285 lttv_traceset_context_ctx_pos_compare(tsc
,
1286 events_request
->start_position
) == 0)
1288 /* - Add to list_in, remove from list_out */
1289 list_in
= g_slist_append(list_in
, events_request
);
1293 /* - If !servicing */
1294 if(events_request
->servicing
== FALSE
) {
1295 /* - begin request hooks called
1296 * - servicing = TRUE
1298 lttv_hooks_call(events_request
->before_request
, (gpointer
)tsc
);
1299 events_request
->servicing
= TRUE
;
1301 /* call before chunk
1302 * events hooks added
1304 if(events_request
->trace
== -1)
1305 lttv_process_traceset_begin(tsc
,
1306 events_request
->before_chunk_traceset
,
1307 events_request
->before_chunk_trace
,
1308 events_request
->before_chunk_tracefile
,
1309 events_request
->event
,
1310 events_request
->event_by_id
);
1312 guint nb_trace
= lttv_traceset_number(tsc
->ts
);
1313 g_assert((guint
)events_request
->trace
< nb_trace
&&
1314 events_request
->trace
> -1);
1315 LttvTraceContext
*tc
= tsc
->traces
[events_request
->trace
];
1317 lttv_hooks_call(events_request
->before_chunk_traceset
, tsc
);
1319 lttv_trace_context_add_hooks(tc
,
1320 events_request
->before_chunk_trace
,
1321 events_request
->before_chunk_tracefile
,
1322 events_request
->event
,
1323 events_request
->event_by_id
);
1332 GSList
*remove_iter
= iter
;
1334 iter
= g_slist_next(iter
);
1335 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
1336 list_out
= g_slist_remove_link(list_out
, remove_iter
);
1337 } else { // not remove
1338 iter
= g_slist_next(iter
);
1344 /* 3. Find end criterions */
1349 /* 3.1.1 Find lowest end time in list_in */
1350 g_assert(g_slist_length(list_in
)>0);
1351 end_time
= ((EventsRequest
*)g_slist_nth_data(list_in
,0))->end_time
;
1353 for(iter
=g_slist_nth(list_in
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
1354 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1356 if(ltt_time_compare(events_request
->end_time
,
1358 end_time
= events_request
->end_time
;
1361 /* 3.1.2 Find lowest start time in list_out */
1362 for(iter
=list_out
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
1363 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1365 if(ltt_time_compare(events_request
->start_time
,
1367 end_time
= events_request
->start_time
;
1372 /* 3.2 Number of events */
1374 /* 3.2.1 Find lowest number of events in list_in */
1377 end_nb_events
= ((EventsRequest
*)g_slist_nth_data(list_in
,0))->num_events
;
1379 for(iter
=g_slist_nth(list_in
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
1380 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1382 if(events_request
->num_events
< end_nb_events
)
1383 end_nb_events
= events_request
->num_events
;
1386 /* 3.2.2 Use min(CHUNK_NUM_EVENTS, min num events in list_in) as
1389 end_nb_events
= MIN(CHUNK_NUM_EVENTS
, end_nb_events
);
1393 /* 3.3 End position */
1395 /* 3.3.1 Find lowest end position in list_in */
1398 end_position
=((EventsRequest
*)g_slist_nth_data(list_in
,0))->end_position
;
1400 for(iter
=g_slist_nth(list_in
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
1401 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1403 if(events_request
->end_position
!= NULL
&& end_position
!= NULL
&&
1404 lttv_traceset_context_pos_pos_compare(events_request
->end_position
,
1406 end_position
= events_request
->end_position
;
1411 /* 3.3.2 Find lowest start position in list_out */
1414 for(iter
=list_out
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
1415 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1417 if(events_request
->end_position
!= NULL
&& end_position
!= NULL
&&
1418 lttv_traceset_context_pos_pos_compare(events_request
->end_position
,
1420 end_position
= events_request
->end_position
;
1425 /* 4. Call process traceset middle */
1426 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
);
1427 count
= lttv_process_traceset_middle(tsc
, end_time
, end_nb_events
, end_position
);
1429 tfc
= lttv_traceset_context_get_current_tfc(tsc
);
1431 g_debug("Context time after middle : %lu, %lu", tfc
->timestamp
.tv_sec
,
1432 tfc
->timestamp
.tv_nsec
);
1434 g_debug("End of trace reached after middle.");
1438 /* 5. After process traceset middle */
1439 tfc
= lttv_traceset_context_get_current_tfc(tsc
);
1441 /* - if current context time > traceset.end time */
1442 if(tfc
== NULL
|| ltt_time_compare(tfc
->timestamp
,
1443 tsc
->time_span
.end_time
) > 0) {
1444 /* - For each req in list_in */
1445 GSList
*iter
= list_in
;
1447 while(iter
!= NULL
) {
1449 gboolean remove
= FALSE
;
1450 gboolean free_data
= FALSE
;
1451 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1453 /* - Remove events hooks for req
1454 * - Call end chunk for req
1457 if(events_request
->trace
== -1)
1458 lttv_process_traceset_end(tsc
,
1459 events_request
->after_chunk_traceset
,
1460 events_request
->after_chunk_trace
,
1461 events_request
->after_chunk_tracefile
,
1462 events_request
->event
,
1463 events_request
->event_by_id
);
1466 guint nb_trace
= lttv_traceset_number(tsc
->ts
);
1467 g_assert(events_request
->trace
< nb_trace
&&
1468 events_request
->trace
> -1);
1469 LttvTraceContext
*tc
= tsc
->traces
[events_request
->trace
];
1471 lttv_trace_context_remove_hooks(tc
,
1472 events_request
->after_chunk_trace
,
1473 events_request
->after_chunk_tracefile
,
1474 events_request
->event
,
1475 events_request
->event_by_id
);
1476 lttv_hooks_call(events_request
->after_chunk_traceset
, tsc
);
1481 /* - Call end request for req */
1482 lttv_hooks_call(events_request
->after_request
, (gpointer
)tsc
);
1484 /* - remove req from list_in */
1485 /* Destroy the request */
1492 GSList
*remove_iter
= iter
;
1494 iter
= g_slist_next(iter
);
1495 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
1496 list_in
= g_slist_remove_link(list_in
, remove_iter
);
1497 } else { // not remove
1498 iter
= g_slist_next(iter
);
1503 /* 5.1 For each req in list_in */
1504 GSList
*iter
= list_in
;
1506 while(iter
!= NULL
) {
1508 gboolean remove
= FALSE
;
1509 gboolean free_data
= FALSE
;
1510 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1512 /* - Remove events hooks for req
1513 * - Call end chunk for req
1515 if(events_request
->trace
== -1)
1516 lttv_process_traceset_end(tsc
,
1517 events_request
->after_chunk_traceset
,
1518 events_request
->after_chunk_trace
,
1519 events_request
->after_chunk_tracefile
,
1520 events_request
->event
,
1521 events_request
->event_by_id
);
1524 guint nb_trace
= lttv_traceset_number(tsc
->ts
);
1525 g_assert(events_request
->trace
< nb_trace
&&
1526 events_request
->trace
> -1);
1527 LttvTraceContext
*tc
= tsc
->traces
[events_request
->trace
];
1529 lttv_trace_context_remove_hooks(tc
,
1530 events_request
->after_chunk_trace
,
1531 events_request
->after_chunk_tracefile
,
1532 events_request
->event
,
1533 events_request
->event_by_id
);
1535 lttv_hooks_call(events_request
->after_chunk_traceset
, tsc
);
1538 /* - req.num -= count */
1539 g_assert(events_request
->num_events
>= count
);
1540 events_request
->num_events
-= count
;
1542 g_assert(tfc
!= NULL
);
1543 /* - if req.num == 0
1545 * current context time >= req.end time
1547 * req.end pos == current pos
1549 * req.stop_flag == TRUE
1551 if( events_request
->num_events
== 0
1553 events_request
->stop_flag
== TRUE
1555 ltt_time_compare(tfc
->timestamp
,
1556 events_request
->end_time
) >= 0
1558 (events_request
->end_position
!= NULL
1560 lttv_traceset_context_ctx_pos_compare(tsc
,
1561 events_request
->end_position
) == 0)
1564 g_assert(events_request
->servicing
== TRUE
);
1565 /* - Call end request for req
1566 * - remove req from list_in */
1567 lttv_hooks_call(events_request
->after_request
, (gpointer
)tsc
);
1568 /* - remove req from list_in */
1569 /* Destroy the request */
1577 GSList
*remove_iter
= iter
;
1579 iter
= g_slist_next(iter
);
1580 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
1581 list_in
= g_slist_remove_link(list_in
, remove_iter
);
1582 } else { // not remove
1583 iter
= g_slist_next(iter
);
1589 /* End of removed servicing loop : leave control to GTK instead. */
1590 // if(gtk_events_pending()) break;
1593 /* B. When interrupted between chunks */
1596 GSList
*iter
= list_in
;
1598 /* 1. for each request in list_in */
1599 while(iter
!= NULL
) {
1601 gboolean remove
= FALSE
;
1602 gboolean free_data
= FALSE
;
1603 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1605 /* 1.1. Use current postition as start position */
1606 if(events_request
->start_position
!= NULL
)
1607 lttv_traceset_context_position_destroy(events_request
->start_position
);
1608 events_request
->start_position
= lttv_traceset_context_position_new(tsc
);
1609 lttv_traceset_context_position_save(tsc
, events_request
->start_position
);
1611 /* 1.2. Remove start time */
1612 events_request
->start_time
= ltt_time_infinite
;
1614 /* 1.3. Move from list_in to list_out */
1617 list_out
= g_slist_append(list_out
, events_request
);
1622 GSList
*remove_iter
= iter
;
1624 iter
= g_slist_next(iter
);
1625 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
1626 list_in
= g_slist_remove_link(list_in
, remove_iter
);
1627 } else { // not remove
1628 iter
= g_slist_next(iter
);
1634 /* C Unlock Traces */
1636 lttv_process_traceset_get_sync_data(tsc
);
1637 //lttv_traceset_context_position_save(tsc, sync_position);
1642 iter_trace
<lttv_traceset_number(tsc
->ts
);
1644 LttvTrace
*trace_v
= lttv_traceset_get(tsc
->ts
, iter_trace
);
1646 lttvwindowtraces_unlock(trace_v
);
1650 //set the cursor back to normal
1651 gdk_window_set_cursor(win
, NULL
);
1654 g_assert(g_slist_length(list_in
) == 0);
1656 if( g_slist_length(list_out
) == 0 ) {
1657 /* Put tab's request pending flag back to normal */
1658 tab
->events_request_pending
= FALSE
;
1659 g_debug("remove the idle fct");
1660 return FALSE
; /* Remove the idle function */
1662 g_debug("leave the idle fct");
1663 return TRUE
; /* Leave the idle function */
1665 /* We do not use simili-round-robin, it may require to read 1 meg buffers
1666 * again and again if many tracesets use the same tracefiles. */
1667 /* Hack for round-robin idle functions */
1668 /* It will put the idle function at the end of the pool */
1669 /*g_idle_add_full((G_PRIORITY_HIGH_IDLE + 21),
1670 (GSourceFunc)execute_events_requests,
1680 static void lttvwindow_add_trace(Tab
*tab
, LttvTrace
*trace_v
)
1682 LttvTraceset
*traceset
= tab
->traceset_info
->traceset
;
1684 guint num_traces
= lttv_traceset_number(traceset
);
1686 //Verify if trace is already present.
1687 for(i
=0; i
<num_traces
; i
++)
1689 LttvTrace
* trace
= lttv_traceset_get(traceset
, i
);
1690 if(trace
== trace_v
)
1694 //Keep a reference to the traces so they are not freed.
1695 for(i
=0; i
<lttv_traceset_number(traceset
); i
++)
1697 LttvTrace
* trace
= lttv_traceset_get(traceset
, i
);
1698 lttv_trace_ref(trace
);
1701 //remove state update hooks
1702 lttv_state_remove_event_hooks(
1703 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1705 lttv_context_fini(LTTV_TRACESET_CONTEXT(
1706 tab
->traceset_info
->traceset_context
));
1707 g_object_unref(tab
->traceset_info
->traceset_context
);
1709 lttv_traceset_add(traceset
, trace_v
);
1710 lttv_trace_ref(trace_v
); /* local ref */
1712 /* Create new context */
1713 tab
->traceset_info
->traceset_context
=
1714 g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
1716 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->
1721 //add state update hooks
1722 lttv_state_add_event_hooks(
1723 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1724 //Remove local reference to the traces.
1725 for(i
=0; i
<lttv_traceset_number(traceset
); i
++)
1727 LttvTrace
* trace
= lttv_traceset_get(traceset
, i
);
1728 lttv_trace_unref(trace
);
1732 //add_trace_into_traceset_selector(GTK_MULTIVPANED(tab->multivpaned), lttv_trace(trace_v));
1735 /* add_trace adds a trace into the current traceset. It first displays a
1736 * directory selection dialogue to let user choose a trace, then recreates
1737 * tracset_context, and redraws all the viewer of the current tab
1740 void add_trace(GtkWidget
* widget
, gpointer user_data
)
1743 LttvTrace
* trace_v
;
1744 LttvTraceset
* traceset
;
1746 char abs_path
[PATH_MAX
];
1748 MainWindow
* mw_data
= get_window_data_struct(widget
);
1749 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
1751 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
1752 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
1756 tab
= create_new_tab(widget
, NULL
);
1758 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
1761 //GtkDirSelection * file_selector = (GtkDirSelection *)gtk_dir_selection_new("Select a trace");
1762 GtkFileSelection
* file_selector
= (GtkFileSelection
*)gtk_file_selection_new("Select a trace");
1763 gtk_widget_hide( (file_selector
)->file_list
->parent
) ;
1764 gtk_file_selection_hide_fileop_buttons(file_selector
);
1765 gtk_window_set_transient_for(GTK_WINDOW(file_selector
),
1766 GTK_WINDOW(mw_data
->mwindow
));
1768 if(remember_trace_dir
[0] != '\0')
1769 gtk_file_selection_set_filename(file_selector
, remember_trace_dir
);
1771 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
1773 case GTK_RESPONSE_ACCEPT
:
1774 case GTK_RESPONSE_OK
:
1775 dir
= gtk_file_selection_get_filename (file_selector
);
1776 strncpy(remember_trace_dir
, dir
, PATH_MAX
);
1777 strncat(remember_trace_dir
, "/", PATH_MAX
);
1778 if(!dir
|| strlen(dir
) == 0){
1779 gtk_widget_destroy((GtkWidget
*)file_selector
);
1782 get_absolute_pathname(dir
, abs_path
);
1783 trace_v
= lttvwindowtraces_get_trace_by_name(abs_path
);
1784 if(trace_v
== NULL
) {
1785 trace
= ltt_trace_open(abs_path
);
1787 g_warning("cannot open trace %s", abs_path
);
1789 GtkWidget
*dialogue
=
1790 gtk_message_dialog_new(
1791 GTK_WINDOW(gtk_widget_get_toplevel(widget
)),
1792 GTK_DIALOG_MODAL
|GTK_DIALOG_DESTROY_WITH_PARENT
,
1795 "Cannot open trace : maybe you should enter in the trace "
1796 "directory to select it ?");
1797 gtk_dialog_run(GTK_DIALOG(dialogue
));
1798 gtk_widget_destroy(dialogue
);
1801 trace_v
= lttv_trace_new(trace
);
1802 lttvwindowtraces_add_trace(trace_v
);
1803 lttvwindow_add_trace(tab
, trace_v
);
1806 lttvwindow_add_trace(tab
, trace_v
);
1809 gtk_widget_destroy((GtkWidget
*)file_selector
);
1811 //update current tab
1812 //update_traceset(mw_data);
1814 /* Call the updatetraceset hooks */
1816 traceset
= tab
->traceset_info
->traceset
;
1817 SetTraceset(tab
, traceset
);
1818 // in expose now call_pending_read_hooks(mw_data);
1820 //lttvwindow_report_current_time(mw_data,&(tab->current_time));
1822 case GTK_RESPONSE_REJECT
:
1823 case GTK_RESPONSE_CANCEL
:
1825 gtk_widget_destroy((GtkWidget
*)file_selector
);
1830 /* remove_trace removes a trace from the current traceset if all viewers in
1831 * the current tab are not interested in the trace. It first displays a
1832 * dialogue, which shows all traces in the current traceset, to let user choose
1833 * a trace, then it checks if all viewers unselect the trace, if it is true,
1834 * it will remove the trace, recreate the traceset_contex,
1835 * and redraws all the viewer of the current tab. If there is on trace in the
1836 * current traceset, it will delete all viewers of the current tab
1838 * It destroys the filter tree. FIXME... we should request for an update
1842 void remove_trace(GtkWidget
*widget
, gpointer user_data
)
1845 LttvTrace
* trace_v
;
1846 LttvTraceset
* traceset
;
1847 gint i
, j
, nb_trace
, index
=-1;
1848 char ** name
, *remove_trace_name
;
1849 MainWindow
* mw_data
= get_window_data_struct(widget
);
1850 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
1852 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
1853 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
1859 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
1862 nb_trace
=lttv_traceset_number(tab
->traceset_info
->traceset
);
1863 name
= g_new(char*,nb_trace
);
1864 for(i
= 0; i
< nb_trace
; i
++){
1865 trace_v
= lttv_traceset_get(tab
->traceset_info
->traceset
, i
);
1866 trace
= lttv_trace(trace_v
);
1867 name
[i
] = g_quark_to_string(ltt_trace_name(trace
));
1870 remove_trace_name
= get_remove_trace(mw_data
, name
, nb_trace
);
1873 if(remove_trace_name
){
1875 /* yuk, cut n paste from old code.. should be better (MD)*/
1876 for(i
= 0; i
<nb_trace
; i
++) {
1877 if(strcmp(remove_trace_name
,name
[i
]) == 0){
1882 traceset
= tab
->traceset_info
->traceset
;
1883 //Keep a reference to the traces so they are not freed.
1884 for(j
=0; j
<lttv_traceset_number(traceset
); j
++)
1886 LttvTrace
* trace
= lttv_traceset_get(traceset
, j
);
1887 lttv_trace_ref(trace
);
1890 //remove state update hooks
1891 lttv_state_remove_event_hooks(
1892 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1893 lttv_context_fini(LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
));
1894 g_object_unref(tab
->traceset_info
->traceset_context
);
1896 trace_v
= lttv_traceset_get(traceset
, index
);
1898 lttv_traceset_remove(traceset
, index
);
1899 lttv_trace_unref(trace_v
); // Remove local reference
1901 if(lttv_trace_get_ref_number(trace_v
) <= 1) {
1902 /* ref 1 : lttvwindowtraces only*/
1903 ltt_trace_close(lttv_trace(trace_v
));
1904 /* lttvwindowtraces_remove_trace takes care of destroying
1905 * the traceset linked with the trace_v and also of destroying
1906 * the trace_v at the same time.
1908 lttvwindowtraces_remove_trace(trace_v
);
1911 tab
->traceset_info
->traceset_context
=
1912 g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
1914 LTTV_TRACESET_CONTEXT(tab
->
1915 traceset_info
->traceset_context
),traceset
);
1916 //add state update hooks
1917 lttv_state_add_event_hooks(
1918 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1920 //Remove local reference to the traces.
1921 for(j
=0; j
<lttv_traceset_number(traceset
); j
++)
1923 LttvTrace
* trace
= lttv_traceset_get(traceset
, j
);
1924 lttv_trace_unref(trace
);
1927 SetTraceset(tab
, (gpointer
)traceset
);
1933 void remove_trace(GtkWidget
* widget
, gpointer user_data
)
1936 LttvTrace
* trace_v
;
1937 LttvTraceset
* traceset
;
1938 gint i
, j
, nb_trace
;
1939 char ** name
, *remove_trace_name
;
1940 MainWindow
* mw_data
= get_window_data_struct(widget
);
1941 LttvTracesetSelector
* s
;
1942 LttvTraceSelector
* t
;
1945 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
1947 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
1948 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
1954 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
1957 nb_trace
=lttv_traceset_number(tab
->traceset_info
->traceset
);
1958 name
= g_new(char*,nb_trace
);
1959 for(i
= 0; i
< nb_trace
; i
++){
1960 trace_v
= lttv_traceset_get(tab
->traceset_info
->traceset
, i
);
1961 trace
= lttv_trace(trace_v
);
1962 name
[i
] = ltt_trace_name(trace
);
1965 remove_trace_name
= get_remove_trace(name
, nb_trace
);
1967 if(remove_trace_name
){
1968 for(i
=0; i
<nb_trace
; i
++){
1969 if(strcmp(remove_trace_name
,name
[i
]) == 0){
1970 //unselect the trace from the current viewer
1972 w
= gtk_multivpaned_get_widget(GTK_MULTIVPANED(tab
->multivpaned
));
1974 s
= g_object_get_data(G_OBJECT(w
), "Traceset_Selector");
1976 t
= lttv_traceset_selector_trace_get(s
,i
);
1977 lttv_trace_selector_set_selected(t
, FALSE
);
1980 //check if other viewers select the trace
1981 w
= gtk_multivpaned_get_first_widget(GTK_MULTIVPANED(tab
->multivpaned
));
1983 s
= g_object_get_data(G_OBJECT(w
), "Traceset_Selector");
1985 t
= lttv_traceset_selector_trace_get(s
,i
);
1986 selected
= lttv_trace_selector_get_selected(t
);
1989 w
= gtk_multivpaned_get_next_widget(GTK_MULTIVPANED(tab
->multivpaned
));
1991 }else selected
= FALSE
;
1993 //if no viewer selects the trace, remove it
1995 remove_trace_from_traceset_selector(GTK_MULTIVPANED(tab
->multivpaned
), i
);
1997 traceset
= tab
->traceset_info
->traceset
;
1998 //Keep a reference to the traces so they are not freed.
1999 for(j
=0; j
<lttv_traceset_number(traceset
); j
++)
2001 LttvTrace
* trace
= lttv_traceset_get(traceset
, j
);
2002 lttv_trace_ref(trace
);
2005 //remove state update hooks
2006 lttv_state_remove_event_hooks(
2007 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
2008 lttv_context_fini(LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
));
2009 g_object_unref(tab
->traceset_info
->traceset_context
);
2012 trace_v
= lttv_traceset_get(traceset
, i
);
2014 if(lttv_trace_get_ref_number(trace_v
) <= 2) {
2015 /* ref 2 : traceset, local */
2016 lttvwindowtraces_remove_trace(trace_v
);
2017 ltt_trace_close(lttv_trace(trace_v
));
2020 lttv_traceset_remove(traceset
, i
);
2021 lttv_trace_unref(trace_v
); // Remove local reference
2023 if(!lttv_trace_get_ref_number(trace_v
))
2024 lttv_trace_destroy(trace_v
);
2026 tab
->traceset_info
->traceset_context
=
2027 g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
2029 LTTV_TRACESET_CONTEXT(tab
->
2030 traceset_info
->traceset_context
),traceset
);
2031 //add state update hooks
2032 lttv_state_add_event_hooks(
2033 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
2035 //Remove local reference to the traces.
2036 for(j
=0; j
<lttv_traceset_number(traceset
); j
++)
2038 LttvTrace
* trace
= lttv_traceset_get(traceset
, j
);
2039 lttv_trace_unref(trace
);
2043 //update current tab
2044 //update_traceset(mw_data);
2047 SetTraceset(tab
, (gpointer
)traceset
);
2048 // in expose now call_pending_read_hooks(mw_data);
2050 //lttvwindow_report_current_time(mw_data,&(tab->current_time));
2053 // while(tab->multi_vpaned->num_children){
2054 // gtk_multi_vpaned_widget_delete(tab->multi_vpaned);
2068 /* Redraw all the viewers in the current tab */
2069 void redraw(GtkWidget
*widget
, gpointer user_data
)
2071 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
2072 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2073 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2078 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
2082 LttvAttributeValue value
;
2084 g_assert(lttv_iattribute_find_by_path(tab
->attributes
, "hooks/redraw", LTTV_POINTER
, &value
));
2086 tmp
= (LttvHooks
*)*(value
.v_pointer
);
2088 lttv_hooks_call(tmp
,NULL
);
2092 void continue_processing(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 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
2105 LttvAttributeValue value
;
2107 g_assert(lttv_iattribute_find_by_path(tab
->attributes
,
2108 "hooks/continue", LTTV_POINTER
, &value
));
2110 tmp
= (LttvHooks
*)*(value
.v_pointer
);
2112 lttv_hooks_call(tmp
,NULL
);
2115 /* Stop the processing for the calling main window's current tab.
2116 * It removes every processing requests that are in its list. It does not call
2117 * the end request hooks, because the request is not finished.
2120 void stop_processing(GtkWidget
*widget
, gpointer user_data
)
2122 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
2123 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2124 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2129 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
2131 GSList
*iter
= tab
->events_requests
;
2133 while(iter
!= NULL
) {
2134 GSList
*remove_iter
= iter
;
2135 iter
= g_slist_next(iter
);
2137 g_free(remove_iter
->data
);
2138 tab
->events_requests
=
2139 g_slist_remove_link(tab
->events_requests
, remove_iter
);
2141 tab
->events_request_pending
= FALSE
;
2142 g_idle_remove_by_data(tab
);
2143 g_assert(g_slist_length(tab
->events_requests
) == 0);
2147 /* save will save the traceset to a file
2148 * Not implemented yet FIXME
2151 void save(GtkWidget
* widget
, gpointer user_data
)
2156 void save_as(GtkWidget
* widget
, gpointer user_data
)
2158 g_info("Save as\n");
2162 /* zoom will change the time_window of all the viewers of the
2163 * current tab, and redisplay them. The main functionality is to
2164 * determine the new time_window of the current tab
2167 void zoom(GtkWidget
* widget
, double size
)
2169 TimeInterval time_span
;
2170 TimeWindow new_time_window
;
2171 LttTime current_time
, time_delta
;
2172 MainWindow
* mw_data
= get_window_data_struct(widget
);
2173 LttvTracesetContext
*tsc
;
2174 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
2176 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2177 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2183 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
2186 if(size
== 1) return;
2188 tsc
= LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
2189 time_span
= tsc
->time_span
;
2190 new_time_window
= tab
->time_window
;
2191 current_time
= tab
->current_time
;
2193 time_delta
= ltt_time_sub(time_span
.end_time
,time_span
.start_time
);
2195 new_time_window
.start_time
= time_span
.start_time
;
2196 new_time_window
.time_width
= time_delta
;
2197 new_time_window
.time_width_double
= ltt_time_to_double(time_delta
);
2198 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
2199 new_time_window
.time_width
) ;
2201 new_time_window
.time_width
= ltt_time_div(new_time_window
.time_width
, size
);
2202 new_time_window
.time_width_double
=
2203 ltt_time_to_double(new_time_window
.time_width
);
2204 if(ltt_time_compare(new_time_window
.time_width
,time_delta
) > 0)
2205 { /* Case where zoom out is bigger than trace length */
2206 new_time_window
.start_time
= time_span
.start_time
;
2207 new_time_window
.time_width
= time_delta
;
2208 new_time_window
.time_width_double
= ltt_time_to_double(time_delta
);
2209 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
2210 new_time_window
.time_width
) ;
2214 /* Center the image on the current time */
2215 new_time_window
.start_time
=
2216 ltt_time_sub(current_time
,
2217 ltt_time_from_double(new_time_window
.time_width_double
/2.0));
2218 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
2219 new_time_window
.time_width
) ;
2220 /* If on borders, don't fall off */
2221 if(ltt_time_compare(new_time_window
.start_time
, time_span
.start_time
) <0
2222 || ltt_time_compare(new_time_window
.start_time
, time_span
.end_time
) >0)
2224 new_time_window
.start_time
= time_span
.start_time
;
2225 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
2226 new_time_window
.time_width
) ;
2230 if(ltt_time_compare(new_time_window
.end_time
,
2231 time_span
.end_time
) > 0
2232 || ltt_time_compare(new_time_window
.end_time
,
2233 time_span
.start_time
) < 0)
2235 new_time_window
.start_time
=
2236 ltt_time_sub(time_span
.end_time
, new_time_window
.time_width
);
2238 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
2239 new_time_window
.time_width
) ;
2246 if(ltt_time_compare(new_time_window
.time_width
, ltt_time_zero
) == 0) {
2247 g_warning("Zoom more than 1 ns impossible");
2249 time_change_manager(tab
, new_time_window
);
2253 void zoom_in(GtkWidget
* widget
, gpointer user_data
)
2258 void zoom_out(GtkWidget
* widget
, gpointer user_data
)
2263 void zoom_extended(GtkWidget
* widget
, gpointer user_data
)
2268 void go_to_time(GtkWidget
* widget
, gpointer user_data
)
2270 g_info("Go to time\n");
2273 void show_time_frame(GtkWidget
* widget
, gpointer user_data
)
2275 g_info("Show time frame\n");
2279 /* callback function */
2282 on_empty_traceset_activate (GtkMenuItem
*menuitem
,
2285 create_new_window((GtkWidget
*)menuitem
, user_data
, FALSE
);
2290 on_clone_traceset_activate (GtkMenuItem
*menuitem
,
2293 create_new_window((GtkWidget
*)menuitem
, user_data
, TRUE
);
2297 /* create_new_tab calls create_tab to construct a new tab in the main window
2300 Tab
*create_new_tab(GtkWidget
* widget
, gpointer user_data
){
2301 gchar label
[PATH_MAX
];
2302 MainWindow
* mw_data
= get_window_data_struct(widget
);
2304 GtkNotebook
* notebook
= (GtkNotebook
*)lookup_widget(widget
, "MNotebook");
2305 if(notebook
== NULL
){
2306 g_info("Notebook does not exist\n");
2309 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2310 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2316 copy_tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
2319 strcpy(label
,"Page");
2320 if(get_label(mw_data
, label
,"Get the name of the tab","Please input tab's name"))
2321 return (create_tab (mw_data
, copy_tab
, notebook
, label
));
2327 on_tab_activate (GtkMenuItem
*menuitem
,
2330 create_new_tab((GtkWidget
*)menuitem
, user_data
);
2335 on_open_activate (GtkMenuItem
*menuitem
,
2338 open_traceset((GtkWidget
*)menuitem
, user_data
);
2343 on_close_activate (GtkMenuItem
*menuitem
,
2346 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2347 main_window_destructor(mw_data
);
2351 /* remove the current tab from the main window
2355 on_close_tab_activate (GtkWidget
*widget
,
2359 GtkWidget
* notebook
;
2361 MainWindow
* mw_data
= get_window_data_struct(widget
);
2362 notebook
= lookup_widget(widget
, "MNotebook");
2363 if(notebook
== NULL
){
2364 g_info("Notebook does not exist\n");
2368 page_num
= gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
));
2370 gtk_notebook_remove_page(GTK_NOTEBOOK(notebook
), page_num
);
2375 on_close_tab_X_clicked (GtkWidget
*widget
,
2379 GtkWidget
*notebook
= lookup_widget(widget
, "MNotebook");
2380 if(notebook
== NULL
){
2381 g_info("Notebook does not exist\n");
2385 if((page_num
= gtk_notebook_page_num(GTK_NOTEBOOK(notebook
), widget
)) != -1)
2386 gtk_notebook_remove_page(GTK_NOTEBOOK(notebook
), page_num
);
2392 on_add_trace_activate (GtkMenuItem
*menuitem
,
2395 add_trace((GtkWidget
*)menuitem
, user_data
);
2400 on_remove_trace_activate (GtkMenuItem
*menuitem
,
2403 remove_trace((GtkWidget
*)menuitem
, user_data
);
2408 on_save_activate (GtkMenuItem
*menuitem
,
2411 save((GtkWidget
*)menuitem
, user_data
);
2416 on_save_as_activate (GtkMenuItem
*menuitem
,
2419 save_as((GtkWidget
*)menuitem
, user_data
);
2424 on_quit_activate (GtkMenuItem
*menuitem
,
2432 on_cut_activate (GtkMenuItem
*menuitem
,
2440 on_copy_activate (GtkMenuItem
*menuitem
,
2448 on_paste_activate (GtkMenuItem
*menuitem
,
2456 on_delete_activate (GtkMenuItem
*menuitem
,
2464 on_zoom_in_activate (GtkMenuItem
*menuitem
,
2467 zoom_in((GtkWidget
*)menuitem
, user_data
);
2472 on_zoom_out_activate (GtkMenuItem
*menuitem
,
2475 zoom_out((GtkWidget
*)menuitem
, user_data
);
2480 on_zoom_extended_activate (GtkMenuItem
*menuitem
,
2483 zoom_extended((GtkWidget
*)menuitem
, user_data
);
2488 on_go_to_time_activate (GtkMenuItem
*menuitem
,
2491 go_to_time((GtkWidget
*)menuitem
, user_data
);
2496 on_show_time_frame_activate (GtkMenuItem
*menuitem
,
2499 show_time_frame((GtkWidget
*)menuitem
, user_data
);
2504 on_move_viewer_up_activate (GtkMenuItem
*menuitem
,
2507 move_up_viewer((GtkWidget
*)menuitem
, user_data
);
2512 on_move_viewer_down_activate (GtkMenuItem
*menuitem
,
2515 move_down_viewer((GtkWidget
*)menuitem
, user_data
);
2520 on_remove_viewer_activate (GtkMenuItem
*menuitem
,
2523 delete_viewer((GtkWidget
*)menuitem
, user_data
);
2527 on_trace_facility_activate (GtkMenuItem
*menuitem
,
2530 g_info("Trace facility selector: %s\n");
2534 /* Dispaly a file selection dialogue to let user select a library, then call
2535 * lttv_library_load().
2539 on_load_library_activate (GtkMenuItem
*menuitem
,
2542 GError
*error
= NULL
;
2543 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2545 gchar load_module_path_alter
[PATH_MAX
];
2549 gchar
*load_module_path
;
2550 name
= g_ptr_array_new();
2551 nb
= lttv_library_path_number();
2552 /* ask for the library path */
2556 path
= lttv_library_path_get(i
);
2557 g_ptr_array_add(name
, path
);
2560 load_module_path
= get_selection(mw_data
,
2561 (char **)(name
->pdata
), name
->len
,
2562 "Select a library path", "Library paths");
2563 if(load_module_path
!= NULL
)
2564 strncpy(load_module_path_alter
, load_module_path
, PATH_MAX
-1); // -1 for /
2566 g_ptr_array_free(name
, TRUE
);
2568 if(load_module_path
== NULL
) return;
2572 /* Make sure the module path ends with a / */
2573 gchar
*ptr
= load_module_path_alter
;
2575 ptr
= strchr(ptr
, '\0');
2577 if(*(ptr
-1) != '/') {
2584 /* Ask for the library to load : list files in the previously selected
2586 gchar str
[PATH_MAX
];
2589 GtkFileSelection
* file_selector
=
2590 (GtkFileSelection
*)gtk_file_selection_new("Select a module");
2591 gtk_file_selection_set_filename(file_selector
, load_module_path_alter
);
2592 gtk_file_selection_hide_fileop_buttons(file_selector
);
2594 gtk_window_set_transient_for(GTK_WINDOW(file_selector
),
2595 GTK_WINDOW(mw_data
->mwindow
));
2598 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
2600 case GTK_RESPONSE_ACCEPT
:
2601 case GTK_RESPONSE_OK
:
2602 dir
= gtk_file_selection_get_selections (file_selector
);
2603 strncpy(str
,dir
[0],PATH_MAX
);
2604 strncpy(remember_plugins_dir
,dir
[0],PATH_MAX
);
2605 /* only keep file name */
2607 str1
= strrchr(str
,'/');
2610 str1
= strrchr(str
,'\\');
2615 if(*str1
== 'l' && *(str1
+1)== 'i' && *(str1
+2)=='b')
2617 remove info after
. */
2621 str2
= strrchr(str2
, '.');
2622 if(str2
!= NULL
) *str2
= '\0';
2624 lttv_module_require(str1
, &error
);
2626 lttv_library_load(str1
, &error
);
2627 if(error
!= NULL
) g_warning("%s", error
->message
);
2628 else g_info("Load library: %s\n", str
);
2630 case GTK_RESPONSE_REJECT
:
2631 case GTK_RESPONSE_CANCEL
:
2633 gtk_widget_destroy((GtkWidget
*)file_selector
);
2644 /* Display all loaded modules, let user to select a module to unload
2645 * by calling lttv_module_unload
2649 on_unload_library_activate (GtkMenuItem
*menuitem
,
2652 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2654 LttvLibrary
*library
= NULL
;
2659 name
= g_ptr_array_new();
2660 nb
= lttv_library_number();
2661 LttvLibraryInfo
*lib_info
= g_new(LttvLibraryInfo
,nb
);
2662 /* ask for the library name */
2665 LttvLibrary
*iter_lib
= lttv_library_get(i
);
2666 lttv_library_info(iter_lib
, &lib_info
[i
]);
2668 gchar
*path
= lib_info
[i
].name
;
2669 g_ptr_array_add(name
, path
);
2671 lib_name
= get_selection(mw_data
, (char **)(name
->pdata
), name
->len
,
2672 "Select a library", "Libraries");
2673 if(lib_name
!= NULL
) {
2675 if(strcmp(lib_name
, lib_info
[i
].name
) == 0) {
2676 library
= lttv_library_get(i
);
2681 g_ptr_array_free(name
, TRUE
);
2684 if(lib_name
== NULL
) return;
2686 if(library
!= NULL
) lttv_library_unload(library
);
2690 /* Dispaly a file selection dialogue to let user select a module, then call
2691 * lttv_module_require().
2695 on_load_module_activate (GtkMenuItem
*menuitem
,
2698 GError
*error
= NULL
;
2699 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2701 LttvLibrary
*library
= NULL
;
2706 name
= g_ptr_array_new();
2707 nb
= lttv_library_number();
2708 LttvLibraryInfo
*lib_info
= g_new(LttvLibraryInfo
,nb
);
2709 /* ask for the library name */
2712 LttvLibrary
*iter_lib
= lttv_library_get(i
);
2713 lttv_library_info(iter_lib
, &lib_info
[i
]);
2715 gchar
*path
= lib_info
[i
].name
;
2716 g_ptr_array_add(name
, path
);
2718 lib_name
= get_selection(mw_data
,(char **)(name
->pdata
), name
->len
,
2719 "Select a library", "Libraries");
2720 if(lib_name
!= NULL
) {
2722 if(strcmp(lib_name
, lib_info
[i
].name
) == 0) {
2723 library
= lttv_library_get(i
);
2728 g_ptr_array_free(name
, TRUE
);
2731 if(lib_name
== NULL
) return;
2734 //LttvModule *module;
2735 gchar module_name_out
[PATH_MAX
];
2737 /* Ask for the module to load : list modules in the selected lib */
2741 nb
= lttv_library_module_number(library
);
2742 LttvModuleInfo
*module_info
= g_new(LttvModuleInfo
,nb
);
2743 name
= g_ptr_array_new();
2744 /* ask for the module name */
2747 LttvModule
*iter_module
= lttv_library_module_get(library
, i
);
2748 lttv_module_info(iter_module
, &module_info
[i
]);
2750 gchar
*path
= module_info
[i
].name
;
2751 g_ptr_array_add(name
, path
);
2753 module_name
= get_selection(mw_data
, (char **)(name
->pdata
), name
->len
,
2754 "Select a module", "Modules");
2755 if(module_name
!= NULL
) {
2757 if(strcmp(module_name
, module_info
[i
].name
) == 0) {
2758 strncpy(module_name_out
, module_name
, PATH_MAX
);
2759 //module = lttv_library_module_get(i);
2765 g_ptr_array_free(name
, TRUE
);
2766 g_free(module_info
);
2768 if(module_name
== NULL
) return;
2771 lttv_module_require(module_name_out
, &error
);
2772 if(error
!= NULL
) g_warning("%s", error
->message
);
2773 else g_info("Load module: %s", module_name_out
);
2780 gchar str
[PATH_MAX
];
2783 GtkFileSelection
* file_selector
=
2784 (GtkFileSelection
*)gtk_file_selection_new("Select a module");
2785 gtk_file_selection_set_filename(file_selector
, load_module_path_alter
);
2786 gtk_file_selection_hide_fileop_buttons(file_selector
);
2789 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
2791 case GTK_RESPONSE_ACCEPT
:
2792 case GTK_RESPONSE_OK
:
2793 dir
= gtk_file_selection_get_selections (file_selector
);
2794 strncpy(str
,dir
[0],PATH_MAX
);
2795 strncpy(remember_plugins_dir
,dir
[0],PATH_MAX
);
2797 /* only keep file name */
2799 str1
= strrchr(str
,'/');
2802 str1
= strrchr(str
,'\\');
2807 if(*str1
== 'l' && *(str1
+1)== 'i' && *(str1
+2)=='b')
2809 remove info after
. */
2813 str2
= strrchr(str2
, '.');
2814 if(str2
!= NULL
) *str2
= '\0';
2816 lttv_module_require(str1
, &error
);
2818 lttv_library_load(str1
, &error
);
2819 if(error
!= NULL
) g_warning(error
->message
);
2820 else g_info("Load library: %s\n", str
);
2822 case GTK_RESPONSE_REJECT
:
2823 case GTK_RESPONSE_CANCEL
:
2825 gtk_widget_destroy((GtkWidget
*)file_selector
);
2837 /* Display all loaded modules, let user to select a module to unload
2838 * by calling lttv_module_unload
2842 on_unload_module_activate (GtkMenuItem
*menuitem
,
2845 GError
*error
= NULL
;
2846 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2848 LttvLibrary
*library
;
2853 name
= g_ptr_array_new();
2854 nb
= lttv_library_number();
2855 LttvLibraryInfo
*lib_info
= g_new(LttvLibraryInfo
,nb
);
2856 /* ask for the library name */
2859 LttvLibrary
*iter_lib
= lttv_library_get(i
);
2860 lttv_library_info(iter_lib
, &lib_info
[i
]);
2862 gchar
*path
= lib_info
[i
].name
;
2863 g_ptr_array_add(name
, path
);
2865 lib_name
= get_selection(mw_data
, (char **)(name
->pdata
), name
->len
,
2866 "Select a library", "Libraries");
2867 if(lib_name
!= NULL
) {
2869 if(strcmp(lib_name
, lib_info
[i
].name
) == 0) {
2870 library
= lttv_library_get(i
);
2875 g_ptr_array_free(name
, TRUE
);
2878 if(lib_name
== NULL
) return;
2881 LttvModule
*module
= NULL
;
2883 /* Ask for the module to load : list modules in the selected lib */
2887 nb
= lttv_library_module_number(library
);
2888 LttvModuleInfo
*module_info
= g_new(LttvModuleInfo
,nb
);
2889 name
= g_ptr_array_new();
2890 /* ask for the module name */
2893 LttvModule
*iter_module
= lttv_library_module_get(library
, i
);
2894 lttv_module_info(iter_module
, &module_info
[i
]);
2896 gchar
*path
= module_info
[i
].name
;
2897 if(module_info
[i
].use_count
> 0) g_ptr_array_add(name
, path
);
2899 module_name
= get_selection(mw_data
, (char **)(name
->pdata
), name
->len
,
2900 "Select a module", "Modules");
2901 if(module_name
!= NULL
) {
2903 if(strcmp(module_name
, module_info
[i
].name
) == 0) {
2904 module
= lttv_library_module_get(library
, i
);
2910 g_ptr_array_free(name
, TRUE
);
2911 g_free(module_info
);
2913 if(module_name
== NULL
) return;
2916 LttvModuleInfo module_info
;
2917 lttv_module_info(module
, &module_info
);
2918 g_info("Release module: %s\n", module_info
.name
);
2920 lttv_module_release(module
);
2924 /* Display a directory dialogue to let user select a path for library searching
2928 on_add_library_search_path_activate (GtkMenuItem
*menuitem
,
2931 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2932 //GtkDirSelection * file_selector = (GtkDirSelection *)gtk_dir_selection_new("Select library path");
2933 GtkFileSelection
* file_selector
= (GtkFileSelection
*)gtk_file_selection_new("Select a trace");
2934 gtk_widget_hide( (file_selector
)->file_list
->parent
) ;
2936 gtk_window_set_transient_for(GTK_WINDOW(file_selector
),
2937 GTK_WINDOW(mw_data
->mwindow
));
2942 if(remember_plugins_dir
[0] != '\0')
2943 gtk_file_selection_set_filename(file_selector
, remember_plugins_dir
);
2945 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
2947 case GTK_RESPONSE_ACCEPT
:
2948 case GTK_RESPONSE_OK
:
2949 dir
= gtk_file_selection_get_filename (file_selector
);
2950 strncpy(remember_plugins_dir
,dir
,PATH_MAX
);
2951 strncat(remember_plugins_dir
,"/",PATH_MAX
);
2952 lttv_library_path_add(dir
);
2953 case GTK_RESPONSE_REJECT
:
2954 case GTK_RESPONSE_CANCEL
:
2956 gtk_widget_destroy((GtkWidget
*)file_selector
);
2962 /* Display a directory dialogue to let user select a path for library searching
2966 on_remove_library_search_path_activate (GtkMenuItem
*menuitem
,
2969 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2971 const char *lib_path
;
2976 name
= g_ptr_array_new();
2977 nb
= lttv_library_path_number();
2978 /* ask for the library name */
2981 gchar
*path
= lttv_library_path_get(i
);
2982 g_ptr_array_add(name
, path
);
2984 lib_path
= get_selection(mw_data
, (char **)(name
->pdata
), name
->len
,
2985 "Select a library path", "Library paths");
2987 g_ptr_array_free(name
, TRUE
);
2989 if(lib_path
== NULL
) return;
2992 lttv_library_path_remove(lib_path
);
2996 on_color_activate (GtkMenuItem
*menuitem
,
3004 on_save_configuration_activate (GtkMenuItem
*menuitem
,
3007 g_info("Save configuration\n");
3012 on_content_activate (GtkMenuItem
*menuitem
,
3015 g_info("Content\n");
3020 on_about_close_activate (GtkButton
*button
,
3023 GtkWidget
*about_widget
= GTK_WIDGET(user_data
);
3025 gtk_widget_destroy(about_widget
);
3029 on_about_activate (GtkMenuItem
*menuitem
,
3032 MainWindow
*main_window
= get_window_data_struct(GTK_WIDGET(menuitem
));
3033 GtkWidget
*window_widget
= main_window
->mwindow
;
3034 GtkWidget
*about_widget
= gtk_window_new(GTK_WINDOW_TOPLEVEL
);
3035 GtkWindow
*about_window
= GTK_WINDOW(about_widget
);
3036 gint window_width
, window_height
;
3038 gtk_window_set_title(about_window
, "About Linux Trace Toolkit");
3040 gtk_window_set_resizable(about_window
, FALSE
);
3041 gtk_window_set_transient_for(GTK_WINDOW(window_widget
), about_window
);
3042 gtk_window_set_destroy_with_parent(about_window
, TRUE
);
3043 gtk_window_set_modal(about_window
, FALSE
);
3045 /* Put the about window at the center of the screen */
3046 gtk_window_get_size(about_window
, &window_width
, &window_height
);
3047 gtk_window_move (about_window
,
3048 (gdk_screen_width() - window_width
)/2,
3049 (gdk_screen_height() - window_height
)/2);
3051 GtkWidget
*vbox
= gtk_vbox_new(FALSE
, 1);
3053 gtk_container_add(GTK_CONTAINER(about_widget
), vbox
);
3057 GtkWidget
*label1
= gtk_label_new("");
3058 gtk_misc_set_padding(GTK_MISC(label1
), 10, 20);
3059 gtk_label_set_markup(GTK_LABEL(label1
), "\
3060 <big>Linux Trace Toolkit</big>");
3061 gtk_label_set_justify(GTK_LABEL(label1
), GTK_JUSTIFY_CENTER
);
3063 GtkWidget
*label2
= gtk_label_new("");
3064 gtk_misc_set_padding(GTK_MISC(label2
), 10, 20);
3065 gtk_label_set_markup(GTK_LABEL(label2
), "\
3068 Michel Dagenais (New trace format, lttv main)\n\
3069 Mathieu Desnoyers (Kernel Tracer, Directory structure, build with automake/conf,\n\
3070 lttv gui, control flow view, gui cooperative trace reading\n\
3071 scheduler with interruptible foreground and background\n\
3072 computation, detailed event list (rewrite), trace reading\n\
3073 library (rewrite))\n\
3074 Benoit Des Ligneris, Eric Clement (Cluster adaptation, work in progress)\n\
3075 Xang-Xiu Yang (new trace reading library and converter, lttv gui, \n\
3076 detailed event list and statistics view)\n\
3077 Tom Zanussi (RelayFS)\n\
3079 Strongly inspired from the original Linux Trace Toolkit Visualizer made by\n\
3082 GtkWidget
*label3
= gtk_label_new("");
3083 gtk_label_set_markup(GTK_LABEL(label3
), "\
3084 Linux Trace Toolkit Viewer, Copyright (C) 2004\n\
3086 Mathieu Desnoyers\n\
3088 Linux Trace Toolkit comes with ABSOLUTELY NO WARRANTY.\n\
3089 This is free software, and you are welcome to redistribute it\n\
3090 under certain conditions. See COPYING for details.");
3091 gtk_misc_set_padding(GTK_MISC(label3
), 10, 20);
3093 gtk_box_pack_start_defaults(GTK_BOX(vbox
), label1
);
3094 gtk_box_pack_start_defaults(GTK_BOX(vbox
), label2
);
3095 gtk_box_pack_start_defaults(GTK_BOX(vbox
), label3
);
3097 GtkWidget
*hbox
= gtk_hbox_new(TRUE
, 0);
3098 gtk_box_pack_end(GTK_BOX(vbox
), hbox
, FALSE
, FALSE
, 0);
3099 GtkWidget
*close_button
= gtk_button_new_with_mnemonic("_Close");
3100 gtk_box_pack_end(GTK_BOX(hbox
), close_button
, FALSE
, FALSE
, 0);
3101 gtk_container_set_border_width(GTK_CONTAINER(close_button
), 20);
3103 g_signal_connect(G_OBJECT(close_button
), "clicked",
3104 G_CALLBACK(on_about_close_activate
),
3105 (gpointer
)about_widget
);
3107 gtk_widget_show_all(about_widget
);
3112 on_button_new_clicked (GtkButton
*button
,
3115 create_new_window((GtkWidget
*)button
, user_data
, TRUE
);
3119 on_button_new_tab_clicked (GtkButton
*button
,
3122 create_new_tab((GtkWidget
*)button
, user_data
);
3126 on_button_open_clicked (GtkButton
*button
,
3129 open_traceset((GtkWidget
*)button
, user_data
);
3134 on_button_add_trace_clicked (GtkButton
*button
,
3137 add_trace((GtkWidget
*)button
, user_data
);
3142 on_button_remove_trace_clicked (GtkButton
*button
,
3145 remove_trace((GtkWidget
*)button
, user_data
);
3149 on_button_redraw_clicked (GtkButton
*button
,
3152 redraw((GtkWidget
*)button
, user_data
);
3156 on_button_continue_processing_clicked (GtkButton
*button
,
3159 continue_processing((GtkWidget
*)button
, user_data
);
3163 on_button_stop_processing_clicked (GtkButton
*button
,
3166 stop_processing((GtkWidget
*)button
, user_data
);
3172 on_button_save_clicked (GtkButton
*button
,
3175 save((GtkWidget
*)button
, user_data
);
3180 on_button_save_as_clicked (GtkButton
*button
,
3183 save_as((GtkWidget
*)button
, user_data
);
3188 on_button_zoom_in_clicked (GtkButton
*button
,
3191 zoom_in((GtkWidget
*)button
, user_data
);
3196 on_button_zoom_out_clicked (GtkButton
*button
,
3199 zoom_out((GtkWidget
*)button
, user_data
);
3204 on_button_zoom_extended_clicked (GtkButton
*button
,
3207 zoom_extended((GtkWidget
*)button
, user_data
);
3212 on_button_go_to_time_clicked (GtkButton
*button
,
3215 go_to_time((GtkWidget
*)button
, user_data
);
3220 on_button_show_time_frame_clicked (GtkButton
*button
,
3223 show_time_frame((GtkWidget
*)button
, user_data
);
3228 on_button_move_up_clicked (GtkButton
*button
,
3231 move_up_viewer((GtkWidget
*)button
, user_data
);
3236 on_button_move_down_clicked (GtkButton
*button
,
3239 move_down_viewer((GtkWidget
*)button
, user_data
);
3244 on_button_delete_viewer_clicked (GtkButton
*button
,
3247 delete_viewer((GtkWidget
*)button
, user_data
);
3251 on_MWindow_destroy (GtkWidget
*widget
,
3254 MainWindow
*main_window
= get_window_data_struct(widget
);
3255 LttvIAttribute
*attributes
= main_window
->attributes
;
3256 LttvAttributeValue value
;
3258 //This is unnecessary, since widgets will be destroyed
3259 //by the main window widget anyway.
3260 //remove_all_menu_toolbar_constructors(main_window, NULL);
3262 g_assert(lttv_iattribute_find_by_path(attributes
,
3263 "viewers/menu", LTTV_POINTER
, &value
));
3264 lttv_menus_destroy((LttvMenus
*)*(value
.v_pointer
));
3266 g_assert(lttv_iattribute_find_by_path(attributes
,
3267 "viewers/toolbar", LTTV_POINTER
, &value
));
3268 lttv_toolbars_destroy((LttvToolbars
*)*(value
.v_pointer
));
3270 g_object_unref(main_window
->attributes
);
3271 g_main_window_list
= g_slist_remove(g_main_window_list
, main_window
);
3273 g_info("There are now : %d windows\n",g_slist_length(g_main_window_list
));
3274 if(g_slist_length(g_main_window_list
) == 0)
3279 on_MWindow_configure (GtkWidget
*widget
,
3280 GdkEventConfigure
*event
,
3283 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)widget
);
3285 // MD : removed time width modification upon resizing of the main window.
3286 // The viewers will redraw themselves completely, without time interval
3289 if(mw_data->window_width){
3290 time_span = LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context)->Time_Span ;
3291 time_win = tab->time_window;
3292 ratio = width / mw_data->window_width;
3293 tab->time_window.time_width = ltt_time_mul(time_win.time_width,ratio);
3294 time = ltt_time_sub(time_span->endTime, time_win.start_time);
3295 if(ltt_time_compare(time, tab->time_window.time_width) < 0){
3296 tab->time_window.time_width = time;
3302 mw_data->window_width = (int)width;
3311 on_MNotebook_switch_page (GtkNotebook
*notebook
,
3312 GtkNotebookPage
*page
,
3320 void time_change_manager (Tab
*tab
,
3321 TimeWindow new_time_window
)
3323 /* Only one source of time change */
3324 if(tab
->time_manager_lock
== TRUE
) return;
3326 tab
->time_manager_lock
= TRUE
;
3328 LttvTracesetContext
*tsc
= LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3329 TimeInterval time_span
= tsc
->time_span
;
3330 LttTime start_time
= new_time_window
.start_time
;
3331 LttTime end_time
= new_time_window
.end_time
;
3332 LttTime time_width
= new_time_window
.time_width
;
3334 g_assert(ltt_time_compare(start_time
, end_time
) < 0);
3337 GtkAdjustment
*adjustment
= gtk_range_get_adjustment(GTK_RANGE(tab
->scrollbar
));
3338 LttTime upper
= ltt_time_sub(time_span
.end_time
, time_span
.start_time
);
3340 gtk_range_set_increments(GTK_RANGE(tab
->scrollbar
),
3341 ltt_time_to_double(new_time_window
.time_width
)
3342 / SCROLL_STEP_PER_PAGE
3343 * NANOSECONDS_PER_SECOND
, /* step increment */
3344 ltt_time_to_double(new_time_window
.time_width
)
3345 * NANOSECONDS_PER_SECOND
); /* page increment */
3346 gtk_range_set_range(GTK_RANGE(tab
->scrollbar
),
3348 ltt_time_to_double(upper
)
3349 * NANOSECONDS_PER_SECOND
); /* upper */
3351 g_object_set(G_OBJECT(adjustment
),
3355 ltt_time_to_double(upper
), /* upper */
3357 new_time_window
.time_width_double
3358 / SCROLL_STEP_PER_PAGE
, /* step increment */
3360 new_time_window
.time_width_double
,
3361 /* page increment */
3363 new_time_window
.time_width_double
, /* page size */
3365 gtk_adjustment_changed(adjustment
);
3367 // g_object_set(G_OBJECT(adjustment),
3369 // ltt_time_to_double(
3370 // ltt_time_sub(start_time, time_span.start_time))
3373 //gtk_adjustment_value_changed(adjustment);
3374 gtk_range_set_value(GTK_RANGE(tab
->scrollbar
),
3376 ltt_time_sub(start_time
, time_span
.start_time
)) /* value */);
3378 /* set the time bar. */
3380 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry1
),
3381 (double)time_span
.start_time
.tv_sec
,
3382 (double)time_span
.end_time
.tv_sec
);
3383 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry1
),
3384 (double)start_time
.tv_sec
);
3386 /* start nanoseconds */
3387 if(start_time
.tv_sec
== time_span
.start_time
.tv_sec
) {
3388 /* can be both beginning and end at the same time. */
3389 if(start_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3390 /* If we are at the end, max nsec to end.. -1 (not zero length) */
3391 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry2
),
3392 (double)time_span
.start_time
.tv_nsec
,
3393 (double)time_span
.end_time
.tv_nsec
-1);
3395 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry2
),
3396 (double)time_span
.start_time
.tv_nsec
,
3397 (double)NANOSECONDS_PER_SECOND
-1);
3399 } else if(start_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3400 /* If we are at the end, max nsec to end.. -1 (not zero length) */
3401 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry2
),
3403 (double)time_span
.end_time
.tv_nsec
-1);
3404 } else /* anywhere else */
3405 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry2
),
3407 (double)NANOSECONDS_PER_SECOND
-1);
3408 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry2
),
3409 (double)start_time
.tv_nsec
);
3412 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry3
),
3413 (double)time_span
.start_time
.tv_sec
,
3414 (double)time_span
.end_time
.tv_sec
);
3415 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry3
),
3416 (double)end_time
.tv_sec
);
3418 /* end nanoseconds */
3419 if(end_time
.tv_sec
== time_span
.start_time
.tv_sec
) {
3420 /* can be both beginning and end at the same time. */
3421 if(end_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3422 /* If we are at the end, max nsec to end.. */
3423 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry4
),
3424 (double)time_span
.start_time
.tv_nsec
+1,
3425 (double)time_span
.end_time
.tv_nsec
);
3427 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry4
),
3428 (double)time_span
.start_time
.tv_nsec
+1,
3429 (double)NANOSECONDS_PER_SECOND
-1);
3432 else if(end_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3433 /* If we are at the end, max nsec to end.. */
3434 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry4
),
3436 (double)time_span
.end_time
.tv_nsec
);
3438 else /* anywhere else */
3439 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry4
),
3441 (double)NANOSECONDS_PER_SECOND
-1);
3442 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry4
),
3443 (double)end_time
.tv_nsec
);
3446 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry7
),
3448 (double)upper
.tv_sec
);
3449 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry7
),
3450 (double)time_width
.tv_sec
);
3452 /* width nanoseconds */
3453 if(time_width
.tv_sec
== upper
.tv_sec
) {
3454 if(time_width
.tv_sec
== 0) {
3455 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry8
),
3457 (double)upper
.tv_nsec
);
3459 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry8
),
3461 (double)upper
.tv_nsec
);
3464 else if(time_width
.tv_sec
== 0) {
3465 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry8
),
3467 (double)upper
.tv_nsec
);
3469 else /* anywhere else */
3470 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry8
),
3472 (double)NANOSECONDS_PER_SECOND
-1);
3473 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry8
),
3474 (double)time_width
.tv_nsec
);
3476 /* call viewer hooks for new time window */
3477 set_time_window(tab
, &new_time_window
);
3479 tab
->time_manager_lock
= FALSE
;
3483 /* value changed for frame start s
3485 * Check time span : if ns is out of range, clip it the nearest good value.
3488 on_MEntry1_value_changed (GtkSpinButton
*spinbutton
,
3491 Tab
*tab
=(Tab
*)user_data
;
3492 LttvTracesetContext
* tsc
=
3493 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3494 TimeInterval time_span
= tsc
->time_span
;
3495 gint value
= gtk_spin_button_get_value_as_int(spinbutton
);
3497 TimeWindow new_time_window
= tab
->time_window
;
3499 LttTime end_time
= new_time_window
.end_time
;
3501 new_time_window
.start_time
.tv_sec
= value
;
3503 /* start nanoseconds */
3504 if(new_time_window
.start_time
.tv_sec
== time_span
.start_time
.tv_sec
) {
3505 if(new_time_window
.start_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3506 if(new_time_window
.start_time
.tv_nsec
> time_span
.end_time
.tv_nsec
)
3507 new_time_window
.start_time
.tv_nsec
= time_span
.end_time
.tv_nsec
-1;
3508 if(new_time_window
.start_time
.tv_nsec
< time_span
.start_time
.tv_nsec
)
3509 new_time_window
.start_time
.tv_nsec
= time_span
.start_time
.tv_nsec
;
3511 if(new_time_window
.start_time
.tv_nsec
< time_span
.start_time
.tv_nsec
)
3512 new_time_window
.start_time
.tv_nsec
= time_span
.start_time
.tv_nsec
;
3515 else if(new_time_window
.start_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3516 if(new_time_window
.start_time
.tv_nsec
> time_span
.end_time
.tv_nsec
)
3517 new_time_window
.start_time
.tv_nsec
= time_span
.end_time
.tv_nsec
-1;
3520 if(ltt_time_compare(new_time_window
.start_time
, end_time
) >= 0) {
3521 /* Then, we must push back end time : keep the same time width
3522 * if possible, else end traceset time */
3523 end_time
= LTT_TIME_MIN(ltt_time_add(new_time_window
.start_time
,
3524 new_time_window
.time_width
),
3525 time_span
.end_time
);
3528 /* Fix the time width to fit start time and end time */
3529 new_time_window
.time_width
= ltt_time_sub(end_time
,
3530 new_time_window
.start_time
);
3531 new_time_window
.time_width_double
=
3532 ltt_time_to_double(new_time_window
.time_width
);
3534 new_time_window
.end_time
= end_time
;
3536 time_change_manager(tab
, new_time_window
);
3541 on_MEntry2_value_changed (GtkSpinButton
*spinbutton
,
3544 Tab
*tab
=(Tab
*)user_data
;
3545 LttvTracesetContext
* tsc
=
3546 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3547 TimeInterval time_span
= tsc
->time_span
;
3548 gint value
= gtk_spin_button_get_value_as_int(spinbutton
);
3550 TimeWindow new_time_window
= tab
->time_window
;
3552 LttTime end_time
= new_time_window
.end_time
;
3554 new_time_window
.start_time
.tv_nsec
= value
;
3556 if(ltt_time_compare(new_time_window
.start_time
, end_time
) >= 0) {
3557 /* Then, we must push back end time : keep the same time width
3558 * if possible, else end traceset time */
3559 end_time
= LTT_TIME_MIN(ltt_time_add(new_time_window
.start_time
,
3560 new_time_window
.time_width
),
3561 time_span
.end_time
);
3564 /* Fix the time width to fit start time and end time */
3565 new_time_window
.time_width
= ltt_time_sub(end_time
,
3566 new_time_window
.start_time
);
3567 new_time_window
.time_width_double
=
3568 ltt_time_to_double(new_time_window
.time_width
);
3570 new_time_window
.end_time
= end_time
;
3572 time_change_manager(tab
, new_time_window
);
3577 on_MEntry3_value_changed (GtkSpinButton
*spinbutton
,
3580 Tab
*tab
=(Tab
*)user_data
;
3581 LttvTracesetContext
* tsc
=
3582 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3583 TimeInterval time_span
= tsc
->time_span
;
3584 gint value
= gtk_spin_button_get_value_as_int(spinbutton
);
3586 TimeWindow new_time_window
= tab
->time_window
;
3588 LttTime end_time
= new_time_window
.end_time
;
3590 end_time
.tv_sec
= value
;
3592 /* end nanoseconds */
3593 if(end_time
.tv_sec
== time_span
.start_time
.tv_sec
) {
3594 if(end_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3595 if(end_time
.tv_nsec
> time_span
.end_time
.tv_nsec
)
3596 end_time
.tv_nsec
= time_span
.end_time
.tv_nsec
;
3597 if(end_time
.tv_nsec
< time_span
.start_time
.tv_nsec
)
3598 end_time
.tv_nsec
= time_span
.start_time
.tv_nsec
+1;
3600 if(end_time
.tv_nsec
< time_span
.start_time
.tv_nsec
)
3601 end_time
.tv_nsec
= time_span
.start_time
.tv_nsec
+1;
3604 else if(end_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3605 if(end_time
.tv_nsec
> time_span
.end_time
.tv_nsec
)
3606 end_time
.tv_nsec
= time_span
.end_time
.tv_nsec
;
3609 if(ltt_time_compare(new_time_window
.start_time
, end_time
) >= 0) {
3610 /* Then, we must push front start time : keep the same time width
3611 * if possible, else end traceset time */
3612 new_time_window
.start_time
= LTT_TIME_MAX(
3613 ltt_time_sub(end_time
,
3614 new_time_window
.time_width
),
3615 time_span
.start_time
);
3618 /* Fix the time width to fit start time and end time */
3619 new_time_window
.time_width
= ltt_time_sub(end_time
,
3620 new_time_window
.start_time
);
3621 new_time_window
.time_width_double
=
3622 ltt_time_to_double(new_time_window
.time_width
);
3624 new_time_window
.end_time
= end_time
;
3626 time_change_manager(tab
, new_time_window
);
3631 on_MEntry4_value_changed (GtkSpinButton
*spinbutton
,
3634 Tab
*tab
=(Tab
*)user_data
;
3635 LttvTracesetContext
* tsc
=
3636 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3637 TimeInterval time_span
= tsc
->time_span
;
3638 gint value
= gtk_spin_button_get_value_as_int(spinbutton
);
3640 TimeWindow new_time_window
= tab
->time_window
;
3642 LttTime end_time
= new_time_window
.end_time
;
3644 end_time
.tv_nsec
= value
;
3646 if(ltt_time_compare(new_time_window
.start_time
, end_time
) >= 0) {
3647 /* Then, we must push front start time : keep the same time width
3648 * if possible, else end traceset time */
3649 new_time_window
.start_time
= LTT_TIME_MAX(
3650 ltt_time_sub(end_time
,
3651 new_time_window
.time_width
),
3652 time_span
.start_time
);
3655 /* Fix the time width to fit start time and end time */
3656 new_time_window
.time_width
= ltt_time_sub(end_time
,
3657 new_time_window
.start_time
);
3658 new_time_window
.time_width_double
=
3659 ltt_time_to_double(new_time_window
.time_width
);
3660 new_time_window
.end_time
= end_time
;
3662 time_change_manager(tab
, new_time_window
);
3666 /* value changed for time frame interval s
3668 * Check time span : if ns is out of range, clip it the nearest good value.
3671 on_MEntry7_value_changed (GtkSpinButton
*spinbutton
,
3674 Tab
*tab
=(Tab
*)user_data
;
3675 LttvTracesetContext
* tsc
=
3676 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3677 TimeInterval time_span
= tsc
->time_span
;
3678 gint value
= gtk_spin_button_get_value_as_int(spinbutton
);
3679 LttTime current_time
, time_delta
;
3680 TimeWindow new_time_window
= tab
->time_window
;
3681 current_time
= tab
->current_time
;
3683 time_delta
= ltt_time_sub(time_span
.end_time
,time_span
.start_time
);
3684 new_time_window
.time_width
.tv_sec
= value
;
3685 new_time_window
.time_width_double
=
3686 ltt_time_to_double(new_time_window
.time_width
);
3687 if(ltt_time_compare(new_time_window
.time_width
,time_delta
) > 0)
3688 { /* Case where zoom out is bigger than trace length */
3689 new_time_window
.start_time
= time_span
.start_time
;
3690 new_time_window
.time_width
= time_delta
;
3691 new_time_window
.time_width_double
= ltt_time_to_double(time_delta
);
3692 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
3693 new_time_window
.time_width
) ;
3697 /* Center the image on the current time */
3698 new_time_window
.start_time
=
3699 ltt_time_sub(current_time
,
3700 ltt_time_from_double(new_time_window
.time_width_double
/2.0));
3701 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
3702 new_time_window
.time_width
) ;
3703 /* If on borders, don't fall off */
3704 if(ltt_time_compare(new_time_window
.start_time
, time_span
.start_time
) <0
3705 || ltt_time_compare(new_time_window
.start_time
, time_span
.end_time
) >0)
3707 new_time_window
.start_time
= time_span
.start_time
;
3708 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
3709 new_time_window
.time_width
) ;
3713 if(ltt_time_compare(new_time_window
.end_time
,
3714 time_span
.end_time
) > 0
3715 || ltt_time_compare(new_time_window
.end_time
,
3716 time_span
.start_time
) < 0)
3718 new_time_window
.start_time
=
3719 ltt_time_sub(time_span
.end_time
, new_time_window
.time_width
);
3721 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
3722 new_time_window
.time_width
) ;
3728 if(ltt_time_compare(new_time_window
.time_width
, ltt_time_zero
) == 0) {
3729 g_warning("Zoom more than 1 ns impossible");
3731 time_change_manager(tab
, new_time_window
);
3736 on_MEntry8_value_changed (GtkSpinButton
*spinbutton
,
3739 Tab
*tab
=(Tab
*)user_data
;
3740 LttvTracesetContext
* tsc
=
3741 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3742 TimeInterval time_span
= tsc
->time_span
;
3743 gint value
= gtk_spin_button_get_value_as_int(spinbutton
);
3744 LttTime current_time
, time_delta
;
3745 TimeWindow new_time_window
= tab
->time_window
;
3746 current_time
= tab
->current_time
;
3748 time_delta
= ltt_time_sub(time_span
.end_time
,time_span
.start_time
);
3749 new_time_window
.time_width
.tv_nsec
= value
;
3750 new_time_window
.time_width_double
=
3751 ltt_time_to_double(new_time_window
.time_width
);
3752 if(ltt_time_compare(new_time_window
.time_width
,time_delta
) > 0)
3753 { /* Case where zoom out is bigger than trace length */
3754 new_time_window
.start_time
= time_span
.start_time
;
3755 new_time_window
.time_width
= time_delta
;
3756 new_time_window
.time_width_double
= ltt_time_to_double(time_delta
);
3757 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
3758 new_time_window
.time_width
) ;
3762 /* Center the image on the current time */
3763 new_time_window
.start_time
=
3764 ltt_time_sub(current_time
,
3765 ltt_time_from_double(new_time_window
.time_width_double
/2.0));
3766 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
3767 new_time_window
.time_width
) ;
3768 /* If on borders, don't fall off */
3769 if(ltt_time_compare(new_time_window
.start_time
, time_span
.start_time
) <0
3770 || ltt_time_compare(new_time_window
.start_time
, time_span
.end_time
) >0)
3772 new_time_window
.start_time
= time_span
.start_time
;
3773 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
3774 new_time_window
.time_width
) ;
3778 if(ltt_time_compare(new_time_window
.end_time
,
3779 time_span
.end_time
) > 0
3780 || ltt_time_compare(new_time_window
.end_time
,
3781 time_span
.start_time
) < 0)
3783 new_time_window
.start_time
=
3784 ltt_time_sub(time_span
.end_time
, new_time_window
.time_width
);
3786 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
3787 new_time_window
.time_width
) ;
3793 if(ltt_time_compare(new_time_window
.time_width
, ltt_time_zero
) == 0) {
3794 g_warning("Zoom more than 1 ns impossible");
3796 time_change_manager(tab
, new_time_window
);
3802 void current_time_change_manager (Tab
*tab
,
3803 LttTime new_current_time
)
3805 /* Only one source of time change */
3806 if(tab
->current_time_manager_lock
== TRUE
) return;
3808 tab
->current_time_manager_lock
= TRUE
;
3810 LttvTracesetContext
*tsc
= LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3811 TimeInterval time_span
= tsc
->time_span
;
3813 /* current seconds */
3814 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry5
),
3815 (double)time_span
.start_time
.tv_sec
,
3816 (double)time_span
.end_time
.tv_sec
);
3817 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry5
),
3818 (double)new_current_time
.tv_sec
);
3821 /* start nanoseconds */
3822 if(new_current_time
.tv_sec
== time_span
.start_time
.tv_sec
) {
3823 /* can be both beginning and end at the same time. */
3824 if(new_current_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3825 /* If we are at the end, max nsec to end.. */
3826 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry6
),
3827 (double)time_span
.start_time
.tv_nsec
,
3828 (double)time_span
.end_time
.tv_nsec
);
3830 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry6
),
3831 (double)time_span
.start_time
.tv_nsec
,
3832 (double)NANOSECONDS_PER_SECOND
-1);
3834 } else if(new_current_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3835 /* If we are at the end, max nsec to end.. */
3836 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry6
),
3838 (double)time_span
.end_time
.tv_nsec
);
3839 } else /* anywhere else */
3840 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry6
),
3842 (double)NANOSECONDS_PER_SECOND
-1);
3844 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry6
),
3845 (double)new_current_time
.tv_nsec
);
3847 set_current_time(tab
, &new_current_time
);
3849 tab
->current_time_manager_lock
= FALSE
;
3852 void current_position_change_manager(Tab
*tab
,
3853 LttvTracesetContextPosition
*pos
)
3855 LttvTracesetContext
*tsc
=
3856 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3857 TimeInterval time_span
= tsc
->time_span
;
3859 g_assert(lttv_process_traceset_seek_position(tsc
, pos
) == 0);
3860 LttTime new_time
= lttv_traceset_context_position_get_time(pos
);
3861 /* Put the context in a state coherent position */
3862 lttv_state_traceset_seek_time_closest((LttvTracesetState
*)tsc
, ltt_time_zero
);
3864 current_time_change_manager(tab
, new_time
);
3866 set_current_position(tab
, pos
);
3871 on_MEntry5_value_changed (GtkSpinButton
*spinbutton
,
3874 Tab
*tab
= (Tab
*)user_data
;
3875 LttvTracesetContext
* tsc
=
3876 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3877 TimeInterval time_span
= tsc
->time_span
;
3878 gint value
= gtk_spin_button_get_value_as_int(spinbutton
);
3879 LttTime new_current_time
= tab
->current_time
;
3880 new_current_time
.tv_sec
= value
;
3882 /* current nanoseconds */
3883 if(new_current_time
.tv_sec
== time_span
.start_time
.tv_sec
) {
3884 if(new_current_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3885 if(new_current_time
.tv_nsec
> time_span
.end_time
.tv_nsec
)
3886 new_current_time
.tv_nsec
= time_span
.end_time
.tv_nsec
;
3887 if(new_current_time
.tv_nsec
< time_span
.start_time
.tv_nsec
)
3888 new_current_time
.tv_nsec
= time_span
.start_time
.tv_nsec
;
3890 if(new_current_time
.tv_nsec
< time_span
.start_time
.tv_nsec
)
3891 new_current_time
.tv_nsec
= time_span
.start_time
.tv_nsec
;
3894 else if(new_current_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3895 if(new_current_time
.tv_nsec
> time_span
.end_time
.tv_nsec
)
3896 new_current_time
.tv_nsec
= time_span
.end_time
.tv_nsec
;
3899 current_time_change_manager(tab
, new_current_time
);
3903 on_MEntry6_value_changed (GtkSpinButton
*spinbutton
,
3906 Tab
*tab
= (Tab
*)user_data
;
3907 gint value
= gtk_spin_button_get_value_as_int(spinbutton
);
3908 LttTime new_current_time
= tab
->current_time
;
3909 new_current_time
.tv_nsec
= value
;
3911 current_time_change_manager(tab
, new_current_time
);
3915 void scroll_value_changed_cb(GtkWidget
*scrollbar
,
3918 Tab
*tab
= (Tab
*)user_data
;
3919 TimeWindow new_time_window
;
3921 GtkAdjustment
*adjust
= gtk_range_get_adjustment(GTK_RANGE(scrollbar
));
3922 gdouble value
= gtk_adjustment_get_value(adjust
);
3923 // gdouble upper, lower, ratio, page_size;
3925 LttvTracesetContext
* tsc
=
3926 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3927 TimeInterval time_span
= tsc
->time_span
;
3929 time
= ltt_time_add(ltt_time_from_double(value
),
3930 time_span
.start_time
);
3932 new_time_window
.start_time
= time
;
3934 page_size
= adjust
->page_size
;
3936 new_time_window
.time_width
=
3937 ltt_time_from_double(page_size
);
3939 new_time_window
.time_width_double
=
3942 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
3943 new_time_window
.time_width
);
3946 time_change_manager(tab
, new_time_window
);
3948 //time_window = tab->time_window;
3950 lower
= adjust
->lower
;
3951 upper
= adjust
->upper
;
3952 ratio
= (value
- lower
) / (upper
- lower
);
3953 g_info("lower %lu, upper %lu, value %lu, ratio %lu", lower
, upper
, value
, ratio
);
3955 //time = ltt_time_sub(time_span->end_time, time_span->start_time);
3956 //time = ltt_time_mul(time, (float)ratio);
3957 //time = ltt_time_add(time_span->start_time, time);
3958 time
= ltt_time_add(ltt_time_from_double(value
),
3959 time_span
.start_time
);
3961 time_window
.start_time
= time
;
3963 page_size
= adjust
->page_size
;
3965 time_window
.time_width
=
3966 ltt_time_from_double(page_size
);
3967 //time = ltt_time_sub(time_span.end_time, time);
3968 //if(ltt_time_compare(time,time_window.time_width) < 0){
3969 // time_window.time_width = time;
3972 /* call viewer hooks for new time window */
3973 set_time_window(tab
, &time_window
);
3978 /* Display a dialogue showing all eventtypes and traces, let user to select the interested
3979 * eventtypes, tracefiles and traces (filter)
3982 /* Select a trace which will be removed from traceset
3985 char * get_remove_trace(MainWindow
*mw_data
,
3986 char ** all_trace_name
, int nb_trace
)
3988 return get_selection(mw_data
, all_trace_name
, nb_trace
,
3989 "Select a trace", "Trace pathname");
3993 /* Select a module which will be loaded
3996 char * get_load_module(MainWindow
*mw_data
,
3997 char ** load_module_name
, int nb_module
)
3999 return get_selection(mw_data
, load_module_name
, nb_module
,
4000 "Select a module to load", "Module name");
4006 /* Select a module which will be unloaded
4009 char * get_unload_module(MainWindow
*mw_data
,
4010 char ** loaded_module_name
, int nb_module
)
4012 return get_selection(mw_data
, loaded_module_name
, nb_module
,
4013 "Select a module to unload", "Module name");
4017 /* Display a dialogue which shows all selectable items, let user to
4018 * select one of them
4021 char * get_selection(MainWindow
*mw_data
,
4022 char ** loaded_module_name
, int nb_module
,
4023 char *title
, char * column_title
)
4025 GtkWidget
* dialogue
;
4026 GtkWidget
* scroll_win
;
4028 GtkListStore
* store
;
4029 GtkTreeViewColumn
* column
;
4030 GtkCellRenderer
* renderer
;
4031 GtkTreeSelection
* select
;
4034 char * unload_module_name
= NULL
;
4036 dialogue
= gtk_dialog_new_with_buttons(title
,
4039 GTK_STOCK_OK
,GTK_RESPONSE_ACCEPT
,
4040 GTK_STOCK_CANCEL
,GTK_RESPONSE_REJECT
,
4042 gtk_window_set_default_size((GtkWindow
*)dialogue
, 500, 200);
4043 gtk_window_set_transient_for(GTK_WINDOW(dialogue
),
4044 GTK_WINDOW(mw_data
->mwindow
));
4046 scroll_win
= gtk_scrolled_window_new (NULL
, NULL
);
4047 gtk_widget_show ( scroll_win
);
4048 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll_win
),
4049 GTK_POLICY_AUTOMATIC
, GTK_POLICY_AUTOMATIC
);
4051 store
= gtk_list_store_new (N_COLUMNS
,G_TYPE_STRING
);
4052 tree
= gtk_tree_view_new_with_model(GTK_TREE_MODEL (store
));
4053 gtk_widget_show ( tree
);
4054 g_object_unref (G_OBJECT (store
));
4056 renderer
= gtk_cell_renderer_text_new ();
4057 column
= gtk_tree_view_column_new_with_attributes (column_title
,
4059 "text", MODULE_COLUMN
,
4061 gtk_tree_view_column_set_alignment (column
, 0.5);
4062 gtk_tree_view_column_set_fixed_width (column
, 150);
4063 gtk_tree_view_append_column (GTK_TREE_VIEW (tree
), column
);
4065 select
= gtk_tree_view_get_selection (GTK_TREE_VIEW (tree
));
4066 gtk_tree_selection_set_mode (select
, GTK_SELECTION_SINGLE
);
4068 gtk_container_add (GTK_CONTAINER (scroll_win
), tree
);
4070 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialogue
)->vbox
), scroll_win
,TRUE
, TRUE
,0);
4072 for(i
=0;i
<nb_module
;i
++){
4073 gtk_list_store_append (store
, &iter
);
4074 gtk_list_store_set (store
, &iter
, MODULE_COLUMN
,loaded_module_name
[i
],-1);
4077 id
= gtk_dialog_run(GTK_DIALOG(dialogue
));
4078 GtkTreeModel
**store_model
= (GtkTreeModel
**)&store
;
4080 case GTK_RESPONSE_ACCEPT
:
4081 case GTK_RESPONSE_OK
:
4082 if (gtk_tree_selection_get_selected (select
, store_model
, &iter
)){
4083 gtk_tree_model_get ((GtkTreeModel
*)store
, &iter
, MODULE_COLUMN
, &unload_module_name
, -1);
4085 case GTK_RESPONSE_REJECT
:
4086 case GTK_RESPONSE_CANCEL
:
4088 gtk_widget_destroy(dialogue
);
4092 return unload_module_name
;
4096 /* Insert all menu entry and tool buttons into this main window
4101 void add_all_menu_toolbar_constructors(MainWindow
* mw
, gpointer user_data
)
4105 lttvwindow_viewer_constructor constructor
;
4106 LttvMenus
* global_menu
, * instance_menu
;
4107 LttvToolbars
* global_toolbar
, * instance_toolbar
;
4108 LttvMenuClosure
*menu_item
;
4109 LttvToolbarClosure
*toolbar_item
;
4110 LttvAttributeValue value
;
4111 LttvIAttribute
*global_attributes
= LTTV_IATTRIBUTE(lttv_global_attributes());
4112 LttvIAttribute
*attributes
= mw
->attributes
;
4113 GtkWidget
* tool_menu_title_menu
, *new_widget
, *pixmap
;
4115 g_assert(lttv_iattribute_find_by_path(global_attributes
,
4116 "viewers/menu", LTTV_POINTER
, &value
));
4117 if(*(value
.v_pointer
) == NULL
)
4118 *(value
.v_pointer
) = lttv_menus_new();
4119 global_menu
= (LttvMenus
*)*(value
.v_pointer
);
4121 g_assert(lttv_iattribute_find_by_path(attributes
,
4122 "viewers/menu", LTTV_POINTER
, &value
));
4123 if(*(value
.v_pointer
) == NULL
)
4124 *(value
.v_pointer
) = lttv_menus_new();
4125 instance_menu
= (LttvMenus
*)*(value
.v_pointer
);
4129 g_assert(lttv_iattribute_find_by_path(global_attributes
,
4130 "viewers/toolbar", LTTV_POINTER
, &value
));
4131 if(*(value
.v_pointer
) == NULL
)
4132 *(value
.v_pointer
) = lttv_toolbars_new();
4133 global_toolbar
= (LttvToolbars
*)*(value
.v_pointer
);
4135 g_assert(lttv_iattribute_find_by_path(attributes
,
4136 "viewers/toolbar", LTTV_POINTER
, &value
));
4137 if(*(value
.v_pointer
) == NULL
)
4138 *(value
.v_pointer
) = lttv_toolbars_new();
4139 instance_toolbar
= (LttvToolbars
*)*(value
.v_pointer
);
4141 /* Add missing menu entries to window instance */
4142 for(i
=0;i
<global_menu
->len
;i
++) {
4143 menu_item
= &g_array_index(global_menu
, LttvMenuClosure
, i
);
4145 //add menu_item to window instance;
4146 constructor
= menu_item
->con
;
4147 tool_menu_title_menu
= lookup_widget(mw
->mwindow
,"ToolMenuTitle_menu");
4149 gtk_menu_item_new_with_mnemonic (menu_item
->menu_text
);
4150 gtk_container_add (GTK_CONTAINER (tool_menu_title_menu
),
4152 g_signal_connect ((gpointer
) new_widget
, "activate",
4153 G_CALLBACK (insert_viewer_wrap
),
4155 gtk_widget_show (new_widget
);
4156 lttv_menus_add(instance_menu
, menu_item
->con
,
4157 menu_item
->menu_path
,
4158 menu_item
->menu_text
,
4163 /* Add missing toolbar entries to window instance */
4164 for(i
=0;i
<global_toolbar
->len
;i
++) {
4165 toolbar_item
= &g_array_index(global_toolbar
, LttvToolbarClosure
, i
);
4167 //add toolbar_item to window instance;
4168 constructor
= toolbar_item
->con
;
4169 tool_menu_title_menu
= lookup_widget(mw
->mwindow
,"MToolbar1");
4170 pixbuf
= gdk_pixbuf_new_from_xpm_data((const char**)toolbar_item
->pixmap
);
4171 pixmap
= gtk_image_new_from_pixbuf(pixbuf
);
4173 gtk_toolbar_append_element (GTK_TOOLBAR (tool_menu_title_menu
),
4174 GTK_TOOLBAR_CHILD_BUTTON
,
4177 toolbar_item
->tooltip
, NULL
,
4178 pixmap
, NULL
, NULL
);
4179 gtk_label_set_use_underline(
4180 GTK_LABEL (((GtkToolbarChild
*) (
4181 g_list_last (GTK_TOOLBAR
4182 (tool_menu_title_menu
)->children
)->data
))->label
),
4184 gtk_container_set_border_width (GTK_CONTAINER (new_widget
), 1);
4185 g_signal_connect ((gpointer
) new_widget
,
4187 G_CALLBACK (insert_viewer_wrap
),
4189 gtk_widget_show (new_widget
);
4191 lttv_toolbars_add(instance_toolbar
, toolbar_item
->con
,
4192 toolbar_item
->tooltip
,
4193 toolbar_item
->pixmap
,
4201 /* Create a main window
4204 MainWindow
*construct_main_window(MainWindow
* parent
)
4206 g_debug("construct_main_window()");
4207 GtkWidget
* new_window
; /* New generated main window */
4208 MainWindow
* new_m_window
;/* New main window structure */
4209 GtkNotebook
* notebook
;
4210 LttvIAttribute
*attributes
=
4211 LTTV_IATTRIBUTE(g_object_new(LTTV_ATTRIBUTE_TYPE
, NULL
));
4212 LttvAttributeValue value
;
4215 new_m_window
= g_new(MainWindow
, 1);
4217 // Add the object's information to the module's array
4218 g_main_window_list
= g_slist_append(g_main_window_list
, new_m_window
);
4220 new_window
= create_MWindow();
4221 gtk_widget_show (new_window
);
4223 new_m_window
->mwindow
= new_window
;
4224 new_m_window
->attributes
= attributes
;
4226 g_assert(lttv_iattribute_find_by_path(attributes
,
4227 "viewers/menu", LTTV_POINTER
, &value
));
4228 *(value
.v_pointer
) = lttv_menus_new();
4230 g_assert(lttv_iattribute_find_by_path(attributes
,
4231 "viewers/toolbar", LTTV_POINTER
, &value
));
4232 *(value
.v_pointer
) = lttv_toolbars_new();
4234 add_all_menu_toolbar_constructors(new_m_window
, NULL
);
4236 g_object_set_data_full(G_OBJECT(new_window
),
4238 (gpointer
)new_m_window
,
4239 (GDestroyNotify
)g_free
);
4240 //create a default tab
4241 notebook
= (GtkNotebook
*)lookup_widget(new_m_window
->mwindow
, "MNotebook");
4242 if(notebook
== NULL
){
4243 g_info("Notebook does not exist\n");
4244 /* FIXME : destroy partially created widgets */
4245 g_free(new_m_window
);
4248 //gtk_notebook_popup_enable (GTK_NOTEBOOK(notebook));
4249 //for now there is no name field in LttvTraceset structure
4250 //Use "Traceset" as the label for the default tab
4252 GtkWidget
* parent_notebook
= lookup_widget(parent
->mwindow
, "MNotebook");
4253 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(parent_notebook
),
4254 gtk_notebook_get_current_page(GTK_NOTEBOOK(parent_notebook
)));
4260 parent_tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
4262 new_tab
= create_tab(new_m_window
, parent_tab
, notebook
, "Traceset");
4264 new_tab
= create_tab(new_m_window
, NULL
, notebook
, "Traceset");
4267 /* Insert default viewers */
4269 LttvAttributeType type
;
4270 LttvAttributeName name
;
4271 LttvAttributeValue value
;
4272 LttvAttribute
*attribute
;
4274 LttvIAttribute
*attributes_global
=
4275 LTTV_IATTRIBUTE(lttv_global_attributes());
4277 g_assert(attribute
=
4278 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
4279 LTTV_IATTRIBUTE(attributes_global
),
4280 LTTV_VIEWER_CONSTRUCTORS
)));
4282 name
= g_quark_from_string("guievents");
4283 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
4285 if(type
== LTTV_POINTER
) {
4286 lttvwindow_viewer_constructor viewer_constructor
=
4287 (lttvwindow_viewer_constructor
)*value
.v_pointer
;
4288 insert_viewer(new_window
, viewer_constructor
);
4291 name
= g_quark_from_string("guicontrolflow");
4292 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
4294 if(type
== LTTV_POINTER
) {
4295 lttvwindow_viewer_constructor viewer_constructor
=
4296 (lttvwindow_viewer_constructor
)*value
.v_pointer
;
4297 insert_viewer(new_window
, viewer_constructor
);
4300 name
= g_quark_from_string("guistatistics");
4301 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
4303 if(type
== LTTV_POINTER
) {
4304 lttvwindow_viewer_constructor viewer_constructor
=
4305 (lttvwindow_viewer_constructor
)*value
.v_pointer
;
4306 insert_viewer(new_window
, viewer_constructor
);
4310 g_info("There are now : %d windows\n",g_slist_length(g_main_window_list
));
4312 return new_m_window
;
4316 /* Free the memory occupied by a tab structure
4320 void tab_destructor(Tab
* tab
)
4322 int i
, nb
, ref_count
;
4325 gtk_object_destroy(GTK_OBJECT(tab
->tooltips
));
4328 g_object_unref(tab
->attributes
);
4330 if(tab
->interrupted_state
)
4331 g_object_unref(tab
->interrupted_state
);
4334 if(tab
->traceset_info
->traceset_context
!= NULL
){
4335 //remove state update hooks
4336 lttv_state_remove_event_hooks(
4337 (LttvTracesetState
*)tab
->traceset_info
->
4339 lttv_context_fini(LTTV_TRACESET_CONTEXT(tab
->traceset_info
->
4341 g_object_unref(tab
->traceset_info
->traceset_context
);
4343 if(tab
->traceset_info
->traceset
!= NULL
) {
4344 nb
= lttv_traceset_number(tab
->traceset_info
->traceset
);
4345 for(i
= 0 ; i
< nb
; i
++) {
4346 trace
= lttv_traceset_get(tab
->traceset_info
->traceset
, i
);
4347 ref_count
= lttv_trace_get_ref_number(trace
);
4349 ltt_trace_close(lttv_trace(trace
));
4353 lttv_filter_destroy(tab
->filter
);
4354 lttv_traceset_destroy(tab
->traceset_info
->traceset
);
4355 /* Remove the idle events requests processing function of the tab */
4356 g_idle_remove_by_data(tab
);
4358 g_slist_free(tab
->events_requests
);
4359 g_free(tab
->traceset_info
);
4364 /* Create a tab and insert it into the current main window
4367 Tab
* create_tab(MainWindow
* mw
, Tab
*copy_tab
,
4368 GtkNotebook
* notebook
, char * label
)
4373 //create a new tab data structure
4376 //construct and initialize the traceset_info
4377 tab
->traceset_info
= g_new(TracesetInfo
,1);
4380 tab
->traceset_info
->traceset
=
4381 lttv_traceset_copy(copy_tab
->traceset_info
->traceset
);
4383 /* Copy the previous tab's filter */
4384 /* We can clone the filter, as we copy the trace set also */
4385 /* The filter must always be in sync with the trace set */
4386 tab
->filter
= lttv_filter_clone(copy_tab
->filter
);
4388 tab
->traceset_info
->traceset
= lttv_traceset_new();
4392 lttv_attribute_write_xml(
4393 lttv_traceset_attribute(tab
->traceset_info
->traceset
),
4399 tab
->time_manager_lock
= FALSE
;
4400 tab
->current_time_manager_lock
= FALSE
;
4402 //FIXME copy not implemented in lower level
4403 tab
->traceset_info
->traceset_context
=
4404 g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
4405 g_assert(tab
->traceset_info
->traceset_context
!= NULL
);
4407 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
),
4408 tab
->traceset_info
->traceset
);
4409 //add state update hooks
4410 lttv_state_add_event_hooks(
4411 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
4413 //determine the current_time and time_window of the tab
4415 if(copy_tab
!= NULL
){
4416 tab
->time_window
= copy_tab
->time_window
;
4417 tab
->current_time
= copy_tab
->current_time
;
4419 tab
->time_window
.start_time
=
4420 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
4421 time_span
.start_time
;
4422 if(DEFAULT_TIME_WIDTH_S
<
4423 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
4424 time_span
.end_time
.tv_sec
)
4425 tmp_time
.tv_sec
= DEFAULT_TIME_WIDTH_S
;
4428 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
4429 time_span
.end_time
.tv_sec
;
4430 tmp_time
.tv_nsec
= 0;
4431 tab
->time_window
.time_width
= tmp_time
;
4432 tab
->current_time
.tv_sec
=
4433 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
4434 time_span
.start_time
.tv_sec
;
4435 tab
->current_time
.tv_nsec
=
4436 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
4437 time_span
.start_time
.tv_nsec
;
4440 tab
->attributes
= LTTV_IATTRIBUTE(g_object_new(LTTV_ATTRIBUTE_TYPE
, NULL
));
4441 tab
->interrupted_state
= g_object_new(LTTV_ATTRIBUTE_TYPE
, NULL
);
4443 tab
->vbox
= gtk_vbox_new(FALSE
, 2);
4444 tab
->viewer_container
= gtk_vbox_new(TRUE
, 2);
4445 tab
->scrollbar
= gtk_hscrollbar_new(NULL
);
4446 //tab->multivpaned = gtk_multi_vpaned_new();
4448 gtk_box_pack_start(GTK_BOX(tab
->vbox
),
4449 tab
->viewer_container
,
4451 TRUE
, /* Give the extra space to the child */
4452 0); /* No padding */
4455 // tab->time_window = copy_tab->time_window;
4456 // tab->current_time = copy_tab->current_time;
4459 /* Create the timebar */
4461 tab
->MTimebar
= gtk_hbox_new(FALSE
, 2);
4462 gtk_widget_show(tab
->MTimebar
);
4463 tab
->tooltips
= gtk_tooltips_new();
4465 tab
->MEventBox1a
= gtk_event_box_new();
4466 gtk_widget_show(tab
->MEventBox1a
);
4467 gtk_tooltips_set_tip(tab
->tooltips
, tab
->MEventBox1a
,
4468 "Paste Start and End Times Here", "");
4469 tab
->MText1a
= gtk_label_new("Time Frame ");
4470 gtk_widget_show(tab
->MText1a
);
4471 gtk_container_add(GTK_CONTAINER(tab
->MEventBox1a
), tab
->MText1a
);
4472 tab
->MEventBox1b
= gtk_event_box_new();
4473 gtk_widget_show(tab
->MEventBox1b
);
4474 gtk_tooltips_set_tip(tab
->tooltips
, tab
->MEventBox1b
,
4475 "Paste Start Time Here", "");
4476 tab
->MText1b
= gtk_label_new("start: ");
4477 gtk_widget_show(tab
->MText1b
);
4478 gtk_container_add(GTK_CONTAINER(tab
->MEventBox1b
), tab
->MText1b
);
4479 tab
->MText2
= gtk_label_new("s");
4480 gtk_widget_show(tab
->MText2
);
4481 tab
->MText3a
= gtk_label_new("ns");
4482 gtk_widget_show(tab
->MText3a
);
4484 tab
->MEventBox3b
= gtk_event_box_new();
4485 gtk_widget_show(tab
->MEventBox3b
);
4486 gtk_tooltips_set_tip(tab
->tooltips
, tab
->MEventBox3b
,
4487 "Paste End Time Here", "");
4488 tab
->MText3b
= gtk_label_new("end:");
4489 gtk_widget_show(tab
->MText3b
);
4490 gtk_container_add(GTK_CONTAINER(tab
->MEventBox3b
), tab
->MText3b
);
4491 tab
->MText4
= gtk_label_new("s");
4492 gtk_widget_show(tab
->MText4
);
4493 tab
->MText5a
= gtk_label_new("ns");
4494 gtk_widget_show(tab
->MText5a
);
4496 tab
->MEventBox8
= gtk_event_box_new();
4497 gtk_widget_show(tab
->MEventBox8
);
4498 gtk_tooltips_set_tip(tab
->tooltips
, tab
->MEventBox8
,
4499 "Paste Time Interval here", "");
4500 tab
->MText8
= gtk_label_new("Time Interval:");
4501 gtk_widget_show(tab
->MText8
);
4502 gtk_container_add(GTK_CONTAINER(tab
->MEventBox8
), tab
->MText8
);
4503 tab
->MText9
= gtk_label_new("s");
4504 gtk_widget_show(tab
->MText9
);
4505 tab
->MText10
= gtk_label_new("ns");
4506 gtk_widget_show(tab
->MText10
);
4508 tab
->MEventBox5b
= gtk_event_box_new();
4509 gtk_widget_show(tab
->MEventBox5b
);
4510 gtk_tooltips_set_tip(tab
->tooltips
, tab
->MEventBox5b
,
4511 "Paste Current Time Here", "");
4512 tab
->MText5b
= gtk_label_new("Current Time:");
4513 gtk_widget_show(tab
->MText5b
);
4514 gtk_container_add(GTK_CONTAINER(tab
->MEventBox5b
), tab
->MText5b
);
4515 tab
->MText6
= gtk_label_new("s");
4516 gtk_widget_show(tab
->MText6
);
4517 tab
->MText7
= gtk_label_new("ns");
4518 gtk_widget_show(tab
->MText7
);
4520 tab
->MEntry1
= gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4521 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab
->MEntry1
),0);
4522 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab
->MEntry1
),TRUE
);
4523 gtk_widget_show(tab
->MEntry1
);
4524 tab
->MEntry2
= gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4525 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab
->MEntry2
),0);
4526 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab
->MEntry2
),TRUE
);
4527 gtk_widget_show(tab
->MEntry2
);
4528 tab
->MEntry3
= gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4529 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab
->MEntry3
),0);
4530 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab
->MEntry3
),TRUE
);
4531 gtk_widget_show(tab
->MEntry3
);
4532 tab
->MEntry4
= gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4533 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab
->MEntry4
),0);
4534 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab
->MEntry4
),TRUE
);
4535 gtk_widget_show(tab
->MEntry4
);
4536 tab
->MEntry5
= gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4537 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab
->MEntry5
),0);
4538 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab
->MEntry5
),TRUE
);
4539 gtk_widget_show(tab
->MEntry5
);
4540 tab
->MEntry6
= gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4541 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab
->MEntry6
),0);
4542 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab
->MEntry6
),TRUE
);
4543 gtk_widget_show(tab
->MEntry6
);
4544 tab
->MEntry7
= gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4545 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab
->MEntry7
),0);
4546 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab
->MEntry7
),TRUE
);
4547 gtk_widget_show(tab
->MEntry7
);
4548 tab
->MEntry8
= gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4549 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab
->MEntry8
),0);
4550 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab
->MEntry8
),TRUE
);
4551 gtk_widget_show(tab
->MEntry8
);
4553 GtkWidget
*temp_widget
;
4555 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEventBox1a
, FALSE
,
4557 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEventBox1b
, FALSE
,
4559 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEntry1
, FALSE
, FALSE
, 0);
4560 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MText2
, FALSE
, FALSE
, 0);
4561 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEntry2
, FALSE
, FALSE
, 0);
4562 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MText3a
, FALSE
, FALSE
, 0);
4563 temp_widget
= gtk_vseparator_new();
4564 gtk_widget_show(temp_widget
);
4565 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), temp_widget
, FALSE
, FALSE
, 0);
4566 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEventBox3b
, FALSE
,
4568 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEntry3
, FALSE
, FALSE
, 0);
4569 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MText4
, FALSE
, FALSE
, 0);
4570 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEntry4
, FALSE
, FALSE
, 0);
4571 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MText5a
, FALSE
, FALSE
, 0);
4572 temp_widget
= gtk_vseparator_new();
4573 gtk_widget_show(temp_widget
);
4574 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), temp_widget
, FALSE
, FALSE
, 0);
4575 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEventBox8
, FALSE
,
4577 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEntry7
, FALSE
, FALSE
, 0);
4578 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MText9
, FALSE
, FALSE
, 0);
4579 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEntry8
, FALSE
, FALSE
, 0);
4580 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MText10
, FALSE
, FALSE
, 0);
4582 temp_widget
= gtk_vseparator_new();
4583 gtk_widget_show(temp_widget
);
4584 gtk_box_pack_end (GTK_BOX (tab
->MTimebar
), tab
->MText7
, FALSE
, FALSE
, 0);
4585 gtk_box_pack_end (GTK_BOX (tab
->MTimebar
), tab
->MEntry6
, FALSE
, FALSE
, 0);
4586 gtk_box_pack_end (GTK_BOX (tab
->MTimebar
), tab
->MText6
, FALSE
, FALSE
, 0);
4587 gtk_box_pack_end (GTK_BOX (tab
->MTimebar
), tab
->MEntry5
, FALSE
, FALSE
, 0);
4588 gtk_box_pack_end (GTK_BOX (tab
->MTimebar
), tab
->MEventBox5b
, FALSE
,
4590 gtk_box_pack_end (GTK_BOX (tab
->MTimebar
), temp_widget
, FALSE
, FALSE
, 0);
4593 //GtkWidget *test = gtk_button_new_with_label("drop");
4594 //gtk_button_set_relief(GTK_BUTTON(test), GTK_RELIEF_NONE);
4595 //gtk_widget_show(test);
4596 //gtk_box_pack_end(GTK_BOX (tab->MTimebar), test, FALSE, FALSE, 0);
4597 //gtk_widget_add_events(tab->MText1, GDK_ALL_EVENTS_MASK);//GDK_BUTTON_PRESS_MASK);
4598 /*GtkWidget *event_box = gtk_event_box_new();
4599 gtk_widget_show(event_box);
4600 gtk_tooltips_set_tip(tooltips, event_box,
4601 "Paste Current Time Here", "");
4602 gtk_box_pack_end(GTK_BOX (tab->MTimebar), event_box, FALSE, FALSE, 0);
4603 GtkWidget *test = gtk_label_new("drop");
4604 gtk_container_add(GTK_CONTAINER(event_box), test);
4605 gtk_widget_show(test);
4606 g_signal_connect (G_OBJECT(event_box),
4607 "button-press-event",
4608 G_CALLBACK (on_MText1_paste),
4612 g_signal_connect (G_OBJECT(tab
->MEventBox1a
),
4613 "button-press-event",
4614 G_CALLBACK (on_MEventBox1a_paste
),
4617 g_signal_connect (G_OBJECT(tab
->MEventBox1b
),
4618 "button-press-event",
4619 G_CALLBACK (on_MEventBox1b_paste
),
4621 g_signal_connect (G_OBJECT(tab
->MEventBox3b
),
4622 "button-press-event",
4623 G_CALLBACK (on_MEventBox3b_paste
),
4625 g_signal_connect (G_OBJECT(tab
->MEventBox5b
),
4626 "button-press-event",
4627 G_CALLBACK (on_MEventBox5b_paste
),
4629 g_signal_connect (G_OBJECT(tab
->MEventBox8
),
4630 "button-press-event",
4631 G_CALLBACK (on_MEventBox8_paste
),
4635 gtk_box_pack_end(GTK_BOX(tab
->vbox
),
4637 FALSE
, /* Do not expand */
4638 FALSE
, /* Fill has no effect here (expand false) */
4639 0); /* No padding */
4641 gtk_box_pack_end(GTK_BOX(tab
->vbox
),
4643 FALSE
, /* Do not expand */
4644 FALSE
, /* Fill has no effect here (expand false) */
4645 0); /* No padding */
4647 g_object_set_data(G_OBJECT(tab
->viewer_container
), "focused_viewer", NULL
);
4653 // Display a label with a X
4654 GtkWidget *w_hbox = gtk_hbox_new(FALSE, 4);
4655 GtkWidget *w_label = gtk_label_new (label);
4656 GtkWidget *pixmap = create_pixmap(GTK_WIDGET(notebook), "close.png");
4657 GtkWidget *w_button = gtk_button_new ();
4658 gtk_container_add(GTK_CONTAINER(w_button), pixmap);
4659 //GtkWidget *w_button = gtk_button_new_with_label("x");
4661 gtk_button_set_relief(GTK_BUTTON(w_button), GTK_RELIEF_NONE);
4663 gtk_box_pack_start(GTK_BOX(w_hbox), w_label, TRUE, TRUE, 0);
4664 gtk_box_pack_end(GTK_BOX(w_hbox), w_button, FALSE,
4667 g_signal_connect_swapped (w_button, "clicked",
4668 G_CALLBACK (on_close_tab_X_clicked),
4671 gtk_widget_set_state(w_button, GTK_STATE_ACTIVE);
4673 gtk_widget_show (w_label);
4674 gtk_widget_show (pixmap);
4675 gtk_widget_show (w_button);
4676 gtk_widget_show (w_hbox);
4678 tab->label = w_hbox;
4682 tab
->label
= gtk_label_new (label
);
4684 gtk_widget_show(tab
->label
);
4685 gtk_widget_show(tab
->scrollbar
);
4686 gtk_widget_show(tab
->viewer_container
);
4687 gtk_widget_show(tab
->vbox
);
4688 //gtk_widget_show(tab->multivpaned);
4691 /* Start with empty events requests list */
4692 tab
->events_requests
= NULL
;
4693 tab
->events_request_pending
= FALSE
;
4695 g_object_set_data_full(
4696 G_OBJECT(tab
->vbox
),
4699 (GDestroyNotify
)tab_destructor
);
4701 g_signal_connect(G_OBJECT(tab
->scrollbar
), "value-changed",
4702 G_CALLBACK(scroll_value_changed_cb
), tab
);
4704 g_signal_connect ((gpointer
) tab
->MEntry1
, "value-changed",
4705 G_CALLBACK (on_MEntry1_value_changed
),
4707 g_signal_connect ((gpointer
) tab
->MEntry2
, "value-changed",
4708 G_CALLBACK (on_MEntry2_value_changed
),
4710 g_signal_connect ((gpointer
) tab
->MEntry3
, "value-changed",
4711 G_CALLBACK (on_MEntry3_value_changed
),
4713 g_signal_connect ((gpointer
) tab
->MEntry4
, "value-changed",
4714 G_CALLBACK (on_MEntry4_value_changed
),
4716 g_signal_connect ((gpointer
) tab
->MEntry5
, "value-changed",
4717 G_CALLBACK (on_MEntry5_value_changed
),
4719 g_signal_connect ((gpointer
) tab
->MEntry6
, "value-changed",
4720 G_CALLBACK (on_MEntry6_value_changed
),
4722 g_signal_connect ((gpointer
) tab
->MEntry7
, "value-changed",
4723 G_CALLBACK (on_MEntry7_value_changed
),
4725 g_signal_connect ((gpointer
) tab
->MEntry8
, "value-changed",
4726 G_CALLBACK (on_MEntry8_value_changed
),
4729 //g_signal_connect(G_OBJECT(tab->scrollbar), "changed",
4730 // G_CALLBACK(scroll_value_changed_cb), tab);
4733 //insert tab into notebook
4734 gtk_notebook_append_page(notebook
,
4737 list
= gtk_container_get_children(GTK_CONTAINER(notebook
));
4738 gtk_notebook_set_current_page(notebook
,g_list_length(list
)-1);
4739 // always show : not if(g_list_length(list)>1)
4740 gtk_notebook_set_show_tabs(notebook
, TRUE
);
4743 lttvwindow_report_time_window(tab
, copy_tab
->time_window
);
4744 lttvwindow_report_current_time(tab
, copy_tab
->current_time
);
4746 TimeWindow time_window
;
4748 time_window
.start_time
= ltt_time_zero
;
4749 time_window
.end_time
= ltt_time_add(time_window
.start_time
,
4750 lttvwindow_default_time_width
);
4751 time_window
.time_width
= lttvwindow_default_time_width
;
4752 time_window
.time_width_double
= ltt_time_to_double(time_window
.time_width
);
4754 lttvwindow_report_time_window(tab
, time_window
);
4755 lttvwindow_report_current_time(tab
, ltt_time_zero
);
4758 LttvTraceset
*traceset
= tab
->traceset_info
->traceset
;
4759 SetTraceset(tab
, traceset
);
4765 * execute_events_requests
4767 * Idle function that executes the pending requests for a tab.
4769 * @return return value : TRUE : keep the idle function, FALSE : remove it.
4771 gboolean
execute_events_requests(Tab
*tab
)
4773 return ( lttvwindow_process_pending_requests(tab
) );
4777 void create_main_window_with_trace(const gchar
*path
)
4779 if(path
== NULL
) return;
4782 MainWindow
*mw
= construct_main_window(NULL
);
4783 GtkWidget
*widget
= mw
->mwindow
;
4785 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
4786 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
4787 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
4791 tab
= create_new_tab(widget
, NULL
);
4793 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
4797 gchar abs_path
[PATH_MAX
];
4801 get_absolute_pathname(path
, abs_path
);
4802 trace_v
= lttvwindowtraces_get_trace_by_name(abs_path
);
4803 if(trace_v
== NULL
) {
4804 trace
= ltt_trace_open(abs_path
);
4806 g_warning("cannot open trace %s", abs_path
);
4808 GtkWidget
*dialogue
=
4809 gtk_message_dialog_new(
4810 GTK_WINDOW(gtk_widget_get_toplevel(widget
)),
4811 GTK_DIALOG_MODAL
|GTK_DIALOG_DESTROY_WITH_PARENT
,
4814 "Cannot open trace : maybe you should enter in the directory"
4816 gtk_dialog_run(GTK_DIALOG(dialogue
));
4817 gtk_widget_destroy(dialogue
);
4819 trace_v
= lttv_trace_new(trace
);
4820 lttvwindowtraces_add_trace(trace_v
);
4821 lttvwindow_add_trace(tab
, trace_v
);
4824 lttvwindow_add_trace(tab
, trace_v
);
4827 LttvTraceset
*traceset
;
4829 traceset
= tab
->traceset_info
->traceset
;
4830 SetTraceset(tab
, traceset
);