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 <lttvwindow/mainwindow.h>
43 #include <lttvwindow/mainwindow-private.h>
44 #include <lttvwindow/menu.h>
45 #include <lttvwindow/toolbar.h>
46 #include <lttvwindow/lttvwindow.h>
47 #include <lttvwindow/lttvwindowtraces.h>
48 #include <lttvwindow/gtkdirsel.h>
49 #include <lttvwindow/lttvfilter.h>
52 #define DEFAULT_TIME_WIDTH_S 1
53 #define CLIP_BUF 256 // size of clipboard buffer
55 extern LttvTrace
*g_init_trace
;
58 /** Array containing instanced objects. */
59 extern GSList
* g_main_window_list
;
61 /** MD : keep old directory. */
62 static char remember_plugins_dir
[PATH_MAX
] = "";
63 static char remember_trace_dir
[PATH_MAX
] = "";
66 MainWindow
* get_window_data_struct(GtkWidget
* widget
);
67 char * get_load_module(char ** load_module_name
, int nb_module
);
68 char * get_unload_module(char ** loaded_module_name
, int nb_module
);
69 char * get_remove_trace(char ** all_trace_name
, int nb_trace
);
70 char * get_selection(char ** all_name
, int nb
, char *title
, char * column_title
);
71 gboolean
get_filter_selection(LttvTracesetSelector
*s
, char *title
, char * column_title
);
72 Tab
* create_tab(MainWindow
* mw
, Tab
*copy_tab
,
73 GtkNotebook
* notebook
, char * label
);
75 static void insert_viewer(GtkWidget
* widget
, lttvwindow_viewer_constructor constructor
);
76 void update_filter(LttvTracesetSelector
*s
, GtkTreeStore
*store
);
78 void checkbox_changed(GtkTreeView
*treeview
,
80 GtkTreeViewColumn
*arg2
,
82 void remove_trace_from_traceset_selector(GtkWidget
* paned
, unsigned i
);
83 void add_trace_into_traceset_selector(GtkWidget
* paned
, LttTrace
* trace
);
84 Tab
*create_new_tab(GtkWidget
* widget
, gpointer user_data
);
86 LttvTracesetSelector
* construct_traceset_selector(LttvTraceset
* traceset
);
88 static gboolean
lttvwindow_process_pending_requests(Tab
*tab
);
102 /* Construct a selector(filter), which will be associated with a viewer,
103 * and provides an interface for user to select interested events and traces
106 LttvTracesetSelector
* construct_traceset_selector(LttvTraceset
* traceset
)
108 LttvTracesetSelector
* s
;
109 LttvTraceSelector
* trace
;
110 LttvTracefileSelector
* tracefile
;
111 LttvEventtypeSelector
* eventtype
;
113 int nb_trace
, nb_tracefile
, nb_control
, nb_per_cpu
, nb_facility
, nb_event
;
120 s
= lttv_traceset_selector_new(lttv_traceset_name(traceset
));
121 nb_trace
= lttv_traceset_number(traceset
);
122 for(i
=0;i
<nb_trace
;i
++){
123 trace_v
= lttv_traceset_get(traceset
, i
);
124 t
= lttv_trace(trace_v
);
125 trace
= lttv_trace_selector_new(t
);
126 lttv_traceset_selector_trace_add(s
, trace
);
128 nb_facility
= ltt_trace_facility_number(t
);
129 for(k
=0;k
<nb_facility
;k
++){
130 fac
= ltt_trace_facility_get(t
,k
);
131 nb_event
= (int) ltt_facility_eventtype_number(fac
);
132 for(m
=0;m
<nb_event
;m
++){
133 et
= ltt_facility_eventtype_get(fac
,m
);
134 eventtype
= lttv_eventtype_selector_new(et
);
135 lttv_trace_selector_eventtype_add(trace
, eventtype
);
139 nb_control
= ltt_trace_control_tracefile_number(t
);
140 nb_per_cpu
= ltt_trace_per_cpu_tracefile_number(t
);
141 nb_tracefile
= nb_control
+ nb_per_cpu
;
143 for(j
= 0 ; j
< nb_tracefile
; j
++) {
145 tf
= ltt_trace_control_tracefile_get(t
, j
);
147 tf
= ltt_trace_per_cpu_tracefile_get(t
, j
- nb_control
);
148 tracefile
= lttv_tracefile_selector_new(tf
);
149 lttv_trace_selector_tracefile_add(trace
, tracefile
);
150 lttv_eventtype_selector_copy(trace
, tracefile
);
156 /* Pasting routines */
158 static void MEventBox1a_receive(GtkClipboard
*clipboard
,
162 if(text
== NULL
) return;
163 Tab
*tab
= (Tab
*)data
;
164 gchar buffer
[CLIP_BUF
];
165 gchar
*ptr
= buffer
, *ptr_ssec
, *ptr_snsec
, *ptr_esec
, *ptr_ensec
;
167 strncpy(buffer
, text
, CLIP_BUF
);
170 while(!isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
171 /* remove leading junk */
173 while(isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
174 /* read all the first number */
178 while(!isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
179 /* remove leading junk */
181 while(isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
182 /* read all the first number */
186 while(!isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
187 /* remove leading junk */
189 while(isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
190 /* read all the first number */
194 while(!isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
195 /* remove leading junk */
197 while(isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
198 /* read all the first number */
201 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry1
),
202 (double)strtoul(ptr_ssec
, NULL
, 10));
203 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry2
),
204 (double)strtoul(ptr_snsec
, NULL
, 10));
205 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry3
),
206 (double)strtoul(ptr_esec
, NULL
, 10));
207 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry4
),
208 (double)strtoul(ptr_ensec
, NULL
, 10));
211 static gboolean
on_MEventBox1a_paste(GtkWidget
*widget
, GdkEventButton
*event
,
214 Tab
*tab
= (Tab
*)data
;
216 GtkClipboard
*clip
= gtk_clipboard_get_for_display(gdk_display_get_default(),
217 GDK_SELECTION_PRIMARY
);
218 gtk_clipboard_request_text(clip
,
219 (GtkClipboardTextReceivedFunc
)MEventBox1a_receive
,
226 static void MEventBox1b_receive(GtkClipboard
*clipboard
,
230 if(text
== NULL
) return;
231 Tab
*tab
= (Tab
*)data
;
232 gchar buffer
[CLIP_BUF
];
233 gchar
*ptr
= buffer
, *ptr_sec
, *ptr_nsec
;
235 strncpy(buffer
, text
, CLIP_BUF
);
237 while(!isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
238 /* remove leading junk */
240 while(isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
241 /* read all the first number */
245 while(!isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
246 /* remove leading junk */
248 while(isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
249 /* read all the first number */
252 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry1
),
253 (double)strtoul(ptr_sec
, NULL
, 10));
254 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry2
),
255 (double)strtoul(ptr_nsec
, NULL
, 10));
259 static gboolean
on_MEventBox1b_paste(GtkWidget
*widget
, GdkEventButton
*event
,
262 Tab
*tab
= (Tab
*)data
;
264 GtkClipboard
*clip
= gtk_clipboard_get_for_display(gdk_display_get_default(),
265 GDK_SELECTION_PRIMARY
);
266 gtk_clipboard_request_text(clip
,
267 (GtkClipboardTextReceivedFunc
)MEventBox1b_receive
,
273 static void MEventBox3b_receive(GtkClipboard
*clipboard
,
277 if(text
== NULL
) return;
278 Tab
*tab
= (Tab
*)data
;
279 gchar buffer
[CLIP_BUF
];
280 gchar
*ptr
= buffer
, *ptr_sec
, *ptr_nsec
;
282 strncpy(buffer
, text
, CLIP_BUF
);
284 while(!isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
285 /* remove leading junk */
287 while(isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
288 /* read all the first number */
292 while(!isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
293 /* remove leading junk */
295 while(isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
296 /* read all the first number */
299 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry3
),
300 (double)strtoul(ptr_sec
, NULL
, 10));
301 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry4
),
302 (double)strtoul(ptr_nsec
, NULL
, 10));
306 static gboolean
on_MEventBox3b_paste(GtkWidget
*widget
, GdkEventButton
*event
,
309 Tab
*tab
= (Tab
*)data
;
311 GtkClipboard
*clip
= gtk_clipboard_get_for_display(gdk_display_get_default(),
312 GDK_SELECTION_PRIMARY
);
313 gtk_clipboard_request_text(clip
,
314 (GtkClipboardTextReceivedFunc
)MEventBox3b_receive
,
320 static void MEventBox5b_receive(GtkClipboard
*clipboard
,
324 if(text
== NULL
) return;
325 Tab
*tab
= (Tab
*)data
;
326 gchar buffer
[CLIP_BUF
];
327 gchar
*ptr
= buffer
, *ptr_sec
, *ptr_nsec
;
329 strncpy(buffer
, text
, CLIP_BUF
);
331 while(!isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
332 /* remove leading junk */
334 while(isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
335 /* read all the first number */
339 while(!isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
340 /* remove leading junk */
342 while(isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
343 /* read all the first number */
346 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry5
),
347 (double)strtoul(ptr_sec
, NULL
, 10));
348 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry6
),
349 (double)strtoul(ptr_nsec
, NULL
, 10));
353 static gboolean
on_MEventBox5b_paste(GtkWidget
*widget
, GdkEventButton
*event
,
356 Tab
*tab
= (Tab
*)data
;
358 GtkClipboard
*clip
= gtk_clipboard_get_for_display(gdk_display_get_default(),
359 GDK_SELECTION_PRIMARY
);
360 gtk_clipboard_request_text(clip
,
361 (GtkClipboardTextReceivedFunc
)MEventBox5b_receive
,
367 static gboolean
viewer_grab_focus(GtkWidget
*widget
, GdkEventButton
*event
,
370 GtkWidget
*viewer
= GTK_WIDGET(data
);
371 GtkWidget
*viewer_container
= gtk_widget_get_parent(viewer
);
373 g_debug("FOCUS GRABBED");
374 g_object_set_data(G_OBJECT(viewer_container
), "focused_viewer", viewer
);
379 static void connect_focus_recursive(GtkWidget
*widget
,
382 if(GTK_IS_CONTAINER(widget
)) {
383 gtk_container_forall(GTK_CONTAINER(widget
),
384 (GtkCallback
)connect_focus_recursive
,
388 if(GTK_IS_TREE_VIEW(widget
)) {
389 gtk_tree_view_set_headers_clickable(widget
, TRUE
);
391 gtk_widget_add_events(widget
, GDK_BUTTON_PRESS_MASK
);
392 g_signal_connect (G_OBJECT(widget
),
393 "button-press-event",
394 G_CALLBACK (viewer_grab_focus
),
398 /* insert_viewer function constructs an instance of a viewer first,
399 * then inserts the widget of the instance into the container of the
404 insert_viewer_wrap(GtkWidget
*menuitem
, gpointer user_data
)
408 insert_viewer((GtkWidget
*)menuitem
, (lttvwindow_viewer_constructor
)user_data
);
409 // selected_hook(&val);
413 /* internal functions */
414 void insert_viewer(GtkWidget
* widget
, lttvwindow_viewer_constructor constructor
)
416 GtkWidget
* viewer_container
;
417 MainWindow
* mw_data
= get_window_data_struct(widget
);
418 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
420 LttvTracesetSelector
* s
;
421 TimeInterval
* time_interval
;
422 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
423 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
427 tab
= create_new_tab(widget
, NULL
);
429 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
432 viewer_container
= tab
->viewer_container
;
434 s
= construct_traceset_selector(tab
->traceset_info
->traceset
);
435 viewer
= (GtkWidget
*)constructor(tab
);
438 //gtk_multivpaned_widget_add(GTK_MULTIVPANED(multivpaned), viewer);
440 gtk_box_pack_end(GTK_BOX(viewer_container
),
446 /* We want to connect the viewer_grab_focus to EVERY
447 * child of this widget. The little trick is to get each child
448 * of each GTK_CONTAINER, even subchildren.
450 connect_focus_recursive(viewer
, viewer
);
455 * Function to set/update traceset for the viewers
456 * @param tab viewer's tab
457 * @param traceset traceset of the main window.
459 * 0 : traceset updated
460 * 1 : no traceset hooks to update; not an error.
463 int SetTraceset(Tab
* tab
, LttvTraceset
*traceset
)
465 LttvTracesetContext
*tsc
=
466 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
467 TimeInterval time_span
= tsc
->time_span
;
468 TimeWindow new_time_window
;
469 LttTime new_current_time
;
471 /* Set the tab's time window and current time if
473 if(ltt_time_compare(tab
->time_window
.start_time
, time_span
.start_time
) < 0
474 || ltt_time_compare(tab
->time_window
.end_time
,
475 time_span
.end_time
) > 0) {
476 new_time_window
.start_time
= time_span
.start_time
;
478 new_current_time
= time_span
.start_time
;
482 if(DEFAULT_TIME_WIDTH_S
< time_span
.end_time
.tv_sec
)
483 tmp_time
.tv_sec
= DEFAULT_TIME_WIDTH_S
;
485 tmp_time
.tv_sec
= time_span
.end_time
.tv_sec
;
486 tmp_time
.tv_nsec
= 0;
487 new_time_window
.time_width
= tmp_time
;
488 new_time_window
.time_width_double
= ltt_time_to_double(tmp_time
);
489 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
490 new_time_window
.time_width
) ;
492 time_change_manager(tab
, new_time_window
);
493 current_time_change_manager(tab
, new_current_time
);
497 GtkAdjustment
*adjustment
= gtk_range_get_adjustment(GTK_RANGE(tab
->scrollbar
));
498 LttTime upper
= ltt_time_sub(time_span
.end_time
, time_span
.start_time
);
500 g_object_set(G_OBJECT(adjustment
),
504 ltt_time_to_double(upper
)
505 * NANOSECONDS_PER_SECOND
, /* upper */
507 ltt_time_to_double(tab
->time_window
.time_width
)
508 / SCROLL_STEP_PER_PAGE
509 * NANOSECONDS_PER_SECOND
, /* step increment */
511 ltt_time_to_double(tab
->time_window
.time_width
)
512 * NANOSECONDS_PER_SECOND
, /* page increment */
514 ltt_time_to_double(tab
->time_window
.time_width
)
515 * NANOSECONDS_PER_SECOND
, /* page size */
517 gtk_adjustment_changed(adjustment
);
519 g_object_set(G_OBJECT(adjustment
),
522 ltt_time_sub(tab
->time_window
.start_time
, time_span
.start_time
))
523 * NANOSECONDS_PER_SECOND
, /* value */
525 gtk_adjustment_value_changed(adjustment
);
527 /* set the time bar. The value callbacks will change their nsec themself */
529 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry1
),
530 (double)time_span
.start_time
.tv_sec
,
531 (double)time_span
.end_time
.tv_sec
);
534 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry3
),
535 (double)time_span
.start_time
.tv_sec
,
536 (double)time_span
.end_time
.tv_sec
);
538 /* current seconds */
539 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry5
),
540 (double)time_span
.start_time
.tv_sec
,
541 (double)time_span
.end_time
.tv_sec
);
544 /* Finally, call the update hooks of the viewers */
546 LttvAttributeValue value
;
550 g_assert( lttv_iattribute_find_by_path(tab
->attributes
,
551 "hooks/updatetraceset", LTTV_POINTER
, &value
));
553 tmp
= (LttvHooks
*)*(value
.v_pointer
);
554 if(tmp
== NULL
) retval
= 1;
555 else lttv_hooks_call(tmp
,traceset
);
562 * Function to set/update filter for the viewers
563 * @param tab viewer's tab
564 * @param filter filter of the main window.
567 * 0 : filters updated
568 * 1 : no filter hooks to update; not an error.
571 int SetFilter(Tab
* tab
, gpointer filter
)
574 LttvAttributeValue value
;
576 g_assert(lttv_iattribute_find_by_path(tab
->attributes
,
577 "hooks/updatefilter", LTTV_POINTER
, &value
));
579 tmp
= (LttvHooks
*)*(value
.v_pointer
);
581 if(tmp
== NULL
) return 1;
582 lttv_hooks_call(tmp
,filter
);
590 * Function to redraw each viewer belonging to the current tab
591 * @param tab viewer's tab
594 void update_traceset(Tab
*tab
)
596 LttvAttributeValue value
;
598 g_assert(lttv_iattribute_find_by_path(tab
->attributes
,
599 "hooks/updatetraceset", LTTV_POINTER
, &value
));
600 tmp
= (LttvHooks
*)*(value
.v_pointer
);
601 if(tmp
== NULL
) return;
602 lttv_hooks_call(tmp
, NULL
);
606 /* get_label function is used to get user input, it displays an input
607 * box, which allows user to input a string
610 void get_label_string (GtkWidget
* text
, gchar
* label
)
612 GtkEntry
* entry
= (GtkEntry
*)text
;
613 if(strlen(gtk_entry_get_text(entry
))!=0)
614 strcpy(label
,gtk_entry_get_text(entry
));
617 gboolean
get_label(MainWindow
* mw
, gchar
* str
, gchar
* dialogue_title
, gchar
* label_str
)
619 GtkWidget
* dialogue
;
624 dialogue
= gtk_dialog_new_with_buttons(dialogue_title
,NULL
,
626 GTK_STOCK_OK
,GTK_RESPONSE_ACCEPT
,
627 GTK_STOCK_CANCEL
,GTK_RESPONSE_REJECT
,
630 label
= gtk_label_new(label_str
);
631 gtk_widget_show(label
);
633 text
= gtk_entry_new();
634 gtk_widget_show(text
);
636 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialogue
)->vbox
), label
,TRUE
, TRUE
,0);
637 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialogue
)->vbox
), text
,FALSE
, FALSE
,0);
639 id
= gtk_dialog_run(GTK_DIALOG(dialogue
));
641 case GTK_RESPONSE_ACCEPT
:
642 get_label_string(text
,str
);
643 gtk_widget_destroy(dialogue
);
645 case GTK_RESPONSE_REJECT
:
647 gtk_widget_destroy(dialogue
);
654 /* get_window_data_struct function is actually a lookup function,
655 * given a widget which is in the tree of the main window, it will
656 * return the MainWindow data structure associated with main window
659 MainWindow
* get_window_data_struct(GtkWidget
* widget
)
662 MainWindow
* mw_data
;
664 mw
= lookup_widget(widget
, "MWindow");
666 g_printf("Main window does not exist\n");
670 mw_data
= (MainWindow
*) g_object_get_data(G_OBJECT(mw
),"main_window_data");
672 g_printf("Main window data does not exist\n");
679 /* create_new_window function, just constructs a new main window
682 void create_new_window(GtkWidget
* widget
, gpointer user_data
, gboolean clone
)
684 MainWindow
* parent
= get_window_data_struct(widget
);
687 g_printf("Clone : use the same traceset\n");
688 construct_main_window(parent
);
690 g_printf("Empty : traceset is set to NULL\n");
691 construct_main_window(NULL
);
695 /* Get the currently focused viewer.
696 * If no viewer is focused, use the first one.
698 * If no viewer available, return NULL.
700 GtkWidget
*viewer_container_focus(GtkWidget
*container
)
704 widget
= (GtkWidget
*)g_object_get_data(G_OBJECT(container
),
708 g_debug("no widget focused");
709 GList
*children
= gtk_container_get_children(GTK_CONTAINER(container
));
712 widget
= GTK_WIDGET(children
->data
);
713 g_object_set_data(G_OBJECT(container
),
723 gint
viewer_container_position(GtkWidget
*container
, GtkWidget
*child
)
726 if(child
== NULL
) return -1;
729 GValue value
= { 0, };
730 g_value_init(&value
, G_TYPE_INT
);
731 gtk_container_child_get_property(GTK_CONTAINER(container
),
735 pos
= g_value_get_int(&value
);
741 /* move_*_viewer functions move the selected view up/down in
745 void move_down_viewer(GtkWidget
* widget
, gpointer user_data
)
747 MainWindow
* mw
= get_window_data_struct(widget
);
748 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
750 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
751 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
757 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
760 //gtk_multivpaned_widget_move_up(GTK_MULTIVPANED(tab->multivpaned));
762 /* change the position in the vbox */
763 GtkWidget
*focus_widget
;
765 focus_widget
= viewer_container_focus(tab
->viewer_container
);
766 position
= viewer_container_position(tab
->viewer_container
, focus_widget
);
769 /* can move up one position */
770 gtk_box_reorder_child(GTK_BOX(tab
->viewer_container
),
777 void move_up_viewer(GtkWidget
* widget
, gpointer user_data
)
779 MainWindow
* mw
= get_window_data_struct(widget
);
780 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
782 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
783 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
789 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
792 //gtk_multivpaned_widget_move_down(GTK_MULTIVPANED(tab->multivpaned));
793 /* change the position in the vbox */
794 GtkWidget
*focus_widget
;
796 focus_widget
= viewer_container_focus(tab
->viewer_container
);
797 position
= viewer_container_position(tab
->viewer_container
, focus_widget
);
801 g_list_length(gtk_container_get_children(
802 GTK_CONTAINER(tab
->viewer_container
)))-1
804 /* can move down one position */
805 gtk_box_reorder_child(GTK_BOX(tab
->viewer_container
),
813 /* delete_viewer deletes the selected viewer in the current tab
816 void delete_viewer(GtkWidget
* widget
, gpointer user_data
)
818 MainWindow
* mw
= get_window_data_struct(widget
);
819 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
821 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
822 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
828 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
831 //gtk_multivpaned_widget_delete(GTK_MULTIVPANED(tab->multivpaned));
833 GtkWidget
*focus_widget
= viewer_container_focus(tab
->viewer_container
);
835 if(focus_widget
!= NULL
)
836 gtk_widget_destroy(focus_widget
);
838 g_object_set_data(G_OBJECT(tab
->viewer_container
), "focused_viewer", NULL
);
842 /* open_traceset will open a traceset saved in a file
843 * Right now, it is not finished yet, (not working)
847 void open_traceset(GtkWidget
* widget
, gpointer user_data
)
851 LttvTraceset
* traceset
;
852 MainWindow
* mw_data
= get_window_data_struct(widget
);
853 GtkFileSelection
* file_selector
=
854 (GtkFileSelection
*)gtk_file_selection_new("Select a traceset");
856 gtk_file_selection_hide_fileop_buttons(file_selector
);
858 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
860 case GTK_RESPONSE_ACCEPT
:
861 case GTK_RESPONSE_OK
:
862 dir
= gtk_file_selection_get_selections (file_selector
);
863 traceset
= lttv_traceset_load(dir
[0]);
864 g_printf("Open a trace set %s\n", dir
[0]);
867 case GTK_RESPONSE_REJECT
:
868 case GTK_RESPONSE_CANCEL
:
870 gtk_widget_destroy((GtkWidget
*)file_selector
);
876 static void events_request_free(EventsRequest
*events_request
)
878 if(events_request
== NULL
) return;
880 if(events_request
->start_position
!= NULL
)
881 lttv_traceset_context_position_destroy(events_request
->start_position
);
882 if(events_request
->end_position
!= NULL
)
883 lttv_traceset_context_position_destroy(events_request
->end_position
);
884 if(events_request
->hooks
!= NULL
)
885 g_array_free(events_request
->hooks
, TRUE
);
886 if(events_request
->before_chunk_traceset
!= NULL
)
887 lttv_hooks_destroy(events_request
->before_chunk_traceset
);
888 if(events_request
->before_chunk_trace
!= NULL
)
889 lttv_hooks_destroy(events_request
->before_chunk_trace
);
890 if(events_request
->before_chunk_tracefile
!= NULL
)
891 lttv_hooks_destroy(events_request
->before_chunk_tracefile
);
892 if(events_request
->event
!= NULL
)
893 lttv_hooks_destroy(events_request
->event
);
894 if(events_request
->event_by_id
!= NULL
)
895 lttv_hooks_by_id_destroy(events_request
->event_by_id
);
896 if(events_request
->after_chunk_tracefile
!= NULL
)
897 lttv_hooks_destroy(events_request
->after_chunk_tracefile
);
898 if(events_request
->after_chunk_trace
!= NULL
)
899 lttv_hooks_destroy(events_request
->after_chunk_trace
);
900 if(events_request
->after_chunk_traceset
!= NULL
)
901 lttv_hooks_destroy(events_request
->after_chunk_traceset
);
902 if(events_request
->before_request
!= NULL
)
903 lttv_hooks_destroy(events_request
->before_request
);
904 if(events_request
->after_request
!= NULL
)
905 lttv_hooks_destroy(events_request
->after_request
);
907 g_free(events_request
);
912 /* lttvwindow_process_pending_requests
914 * This internal function gets called by g_idle, taking care of the pending
915 * requests. It is responsible for concatenation of time intervals and position
916 * requests. It does it with the following algorithm organizing process traceset
917 * calls. Here is the detailed description of the way it works :
919 * - Events Requests Servicing Algorithm
921 * Data structures necessary :
923 * List of requests added to context : list_in
924 * List of requests not added to context : list_out
929 * list_out : many events requests
931 * FIXME : insert rest of algorithm here
935 #define list_out tab->events_requests
937 gboolean
lttvwindow_process_pending_requests(Tab
*tab
)
939 unsigned max_nb_events
;
943 LttvTracesetContext
*tsc
;
944 LttvTracefileContext
*tfc
;
945 GSList
*list_in
= NULL
;
949 LttvTracesetContextPosition
*end_position
;
952 g_critical("Foreground processing : tab does not exist. Processing removed.");
956 /* There is no events requests pending : we should never have been called! */
957 g_assert(g_slist_length(list_out
) != 0);
959 tsc
= LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
961 //set the cursor to be X shape, indicating that the computer is busy in doing its job
963 new = gdk_cursor_new(GDK_X_CURSOR
);
964 widget
= lookup_widget(tab
->mw
->mwindow
, "MToolbar1");
965 win
= gtk_widget_get_parent_window(widget
);
966 gdk_window_set_cursor(win
, new);
967 gdk_cursor_unref(new);
968 gdk_window_stick(win
);
969 gdk_window_unstick(win
);
972 g_debug("SIZE events req len : %d", g_slist_length(list_out
));
974 /* Preliminary check for no trace in traceset */
975 /* Unregister the routine if empty, empty list_out too */
976 if(lttv_traceset_number(tsc
->ts
) == 0) {
978 /* - For each req in list_out */
979 GSList
*iter
= list_out
;
981 while(iter
!= NULL
) {
983 gboolean remove
= FALSE
;
984 gboolean free_data
= FALSE
;
985 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
987 /* - Call end request for req */
988 if(events_request
->servicing
== TRUE
)
989 lttv_hooks_call(events_request
->after_request
, (gpointer
)tsc
);
991 /* - remove req from list_out */
992 /* Destroy the request */
999 GSList
*remove_iter
= iter
;
1001 iter
= g_slist_next(iter
);
1002 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
1003 list_out
= g_slist_remove_link(list_out
, remove_iter
);
1004 } else { // not remove
1005 iter
= g_slist_next(iter
);
1010 /* 0.1 Lock Traces */
1015 iter_trace
<lttv_traceset_number(tsc
->ts
);
1017 LttvTrace
*trace_v
= lttv_traceset_get(tsc
->ts
, iter_trace
);
1019 if(lttvwindowtraces_lock(trace_v
) != 0) {
1020 g_critical("Foreground processing : Unable to get trace lock");
1021 return TRUE
; /* Cannot get lock, try later */
1026 /* 0.2 Seek tracefiles positions to context position */
1027 lttv_process_traceset_synchronize_tracefiles(tsc
);
1030 /* Events processing algorithm implementation */
1031 /* Warning : the gtk_events_pending takes a LOT of cpu time. So what we do
1032 * instead is to leave the control to GTK and take it back.
1034 /* A. Servicing loop */
1035 //while( (g_slist_length(list_in) != 0 || g_slist_length(list_out) != 0)) {
1036 if((g_slist_length(list_in
) != 0 || g_slist_length(list_out
) != 0)) {
1038 /* 1. If list_in is empty (need a seek) */
1039 if( g_slist_length(list_in
) == 0 ) {
1041 /* list in is empty, need a seek */
1043 /* 1.1 Add requests to list_in */
1044 GSList
*ltime
= NULL
;
1045 GSList
*lpos
= NULL
;
1046 GSList
*iter
= NULL
;
1048 /* 1.1.1 Find all time requests with the lowest start time in list_out
1051 if(g_slist_length(list_out
) > 0)
1052 ltime
= g_slist_append(ltime
, g_slist_nth_data(list_out
, 0));
1053 for(iter
=g_slist_nth(list_out
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
1054 /* Find all time requests with the lowest start time in list_out */
1055 guint index_ltime
= g_array_index(ltime
, guint
, 0);
1056 EventsRequest
*event_request_ltime
= (EventsRequest
*)g_slist_nth_data(ltime
, 0);
1057 EventsRequest
*event_request_list_out
= (EventsRequest
*)iter
->data
;
1060 comp
= ltt_time_compare(event_request_ltime
->start_time
,
1061 event_request_list_out
->start_time
);
1063 ltime
= g_slist_append(ltime
, event_request_list_out
);
1065 /* Remove all elements from ltime, and add current */
1066 while(ltime
!= NULL
)
1067 ltime
= g_slist_delete_link(ltime
, g_slist_nth(ltime
, 0));
1068 ltime
= g_slist_append(ltime
, event_request_list_out
);
1072 /* 1.1.2 Find all position requests with the lowest position in list_out
1075 if(g_slist_length(list_out
) > 0)
1076 lpos
= g_slist_append(lpos
, g_slist_nth_data(list_out
, 0));
1077 for(iter
=g_slist_nth(list_out
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
1078 /* Find all position requests with the lowest position in list_out */
1079 EventsRequest
*event_request_lpos
= (EventsRequest
*)g_slist_nth_data(lpos
, 0);
1080 EventsRequest
*event_request_list_out
= (EventsRequest
*)iter
->data
;
1083 if(event_request_lpos
->start_position
!= NULL
1084 && event_request_list_out
->start_position
!= NULL
)
1086 comp
= lttv_traceset_context_pos_pos_compare
1087 (event_request_lpos
->start_position
,
1088 event_request_list_out
->start_position
);
1093 lpos
= g_slist_append(lpos
, event_request_list_out
);
1095 /* Remove all elements from lpos, and add current */
1097 lpos
= g_slist_delete_link(lpos
, g_slist_nth(lpos
, 0));
1098 lpos
= g_slist_append(lpos
, event_request_list_out
);
1103 EventsRequest
*event_request_lpos
= (EventsRequest
*)g_slist_nth_data(lpos
, 0);
1104 EventsRequest
*event_request_ltime
= (EventsRequest
*)g_slist_nth_data(ltime
, 0);
1105 LttTime lpos_start_time
;
1107 if(event_request_lpos
!= NULL
1108 && event_request_lpos
->start_position
!= NULL
) {
1109 lpos_start_time
= lttv_traceset_context_position_get_time(
1110 event_request_lpos
->start_position
);
1113 /* 1.1.3 If lpos.start time < ltime */
1114 if(event_request_lpos
!= NULL
1115 && event_request_lpos
->start_position
!= NULL
1116 && ltt_time_compare(lpos_start_time
,
1117 event_request_ltime
->start_time
)<0) {
1118 /* Add lpos to list_in, remove them from list_out */
1119 for(iter
=lpos
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
1120 /* Add to list_in */
1121 EventsRequest
*event_request_lpos
=
1122 (EventsRequest
*)iter
->data
;
1124 list_in
= g_slist_append(list_in
, event_request_lpos
);
1125 /* Remove from list_out */
1126 list_out
= g_slist_remove(list_out
, event_request_lpos
);
1129 /* 1.1.4 (lpos.start time >= ltime) */
1130 /* Add ltime to list_in, remove them from list_out */
1132 for(iter
=ltime
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
1133 /* Add to list_in */
1134 EventsRequest
*event_request_ltime
=
1135 (EventsRequest
*)iter
->data
;
1137 list_in
= g_slist_append(list_in
, event_request_ltime
);
1138 /* Remove from list_out */
1139 list_out
= g_slist_remove(list_out
, event_request_ltime
);
1144 g_slist_free(ltime
);
1149 tfc
= lttv_traceset_context_get_current_tfc(tsc
);
1150 g_assert(g_slist_length(list_in
)>0);
1151 EventsRequest
*events_request
= g_slist_nth_data(list_in
, 0);
1154 /* 1.2.1 If first request in list_in is a time request */
1155 if(events_request
->start_position
== NULL
) {
1156 /* - If first req in list_in start time != current time */
1157 if(tfc
== NULL
|| ltt_time_compare(events_request
->start_time
,
1158 tfc
->timestamp
) != 0)
1159 /* - Seek to that time */
1160 g_debug("SEEK TIME : %lu, %lu", events_request
->start_time
.tv_sec
,
1161 events_request
->start_time
.tv_nsec
);
1162 //lttv_process_traceset_seek_time(tsc, events_request->start_time);
1163 lttv_state_traceset_seek_time_closest(LTTV_TRACESET_STATE(tsc
),
1164 events_request
->start_time
);
1166 /* Process the traceset with only state hooks */
1168 lttv_process_traceset_middle(tsc
,
1169 events_request
->start_time
,
1175 /* Else, the first request in list_in is a position request */
1176 /* If first req in list_in pos != current pos */
1177 g_assert(events_request
->start_position
!= NULL
);
1178 g_debug("SEEK POS time : %lu, %lu",
1179 lttv_traceset_context_position_get_time(
1180 events_request
->start_position
).tv_sec
,
1181 lttv_traceset_context_position_get_time(
1182 events_request
->start_position
).tv_nsec
);
1184 g_debug("SEEK POS context time : %lu, %lu",
1185 lttv_traceset_context_get_current_tfc(tsc
)->timestamp
.tv_sec
,
1186 lttv_traceset_context_get_current_tfc(tsc
)->timestamp
.tv_nsec
);
1187 g_assert(events_request
->start_position
!= NULL
);
1188 if(lttv_traceset_context_ctx_pos_compare(tsc
,
1189 events_request
->start_position
) != 0) {
1190 /* 1.2.2.1 Seek to that position */
1191 g_debug("SEEK POSITION");
1192 //lttv_process_traceset_seek_position(tsc, events_request->start_position);
1193 pos_time
= lttv_traceset_context_position_get_time(
1194 events_request
->start_position
);
1196 lttv_state_traceset_seek_time_closest(LTTV_TRACESET_STATE(tsc
),
1199 /* Process the traceset with only state hooks */
1201 lttv_process_traceset_middle(tsc
,
1204 events_request
->start_position
);
1205 g_assert(lttv_traceset_context_ctx_pos_compare(tsc
,
1206 events_request
->start_position
) == 0);
1213 /* 1.3 Add hooks and call before request for all list_in members */
1215 GSList
*iter
= NULL
;
1217 for(iter
=list_in
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
1218 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1219 /* 1.3.1 If !servicing */
1220 if(events_request
->servicing
== FALSE
) {
1221 /* - begin request hooks called
1222 * - servicing = TRUE
1224 lttv_hooks_call(events_request
->before_request
, (gpointer
)tsc
);
1225 events_request
->servicing
= TRUE
;
1227 /* 1.3.2 call before chunk
1228 * 1.3.3 events hooks added
1230 if(events_request
->trace
== -1)
1231 lttv_process_traceset_begin(tsc
,
1232 events_request
->before_chunk_traceset
,
1233 events_request
->before_chunk_trace
,
1234 events_request
->before_chunk_tracefile
,
1235 events_request
->event
,
1236 events_request
->event_by_id
);
1238 guint nb_trace
= lttv_traceset_number(tsc
->ts
);
1239 g_assert(events_request
->trace
< nb_trace
&&
1240 events_request
->trace
> -1);
1241 LttvTraceContext
*tc
= tsc
->traces
[events_request
->trace
];
1243 lttv_hooks_call(events_request
->before_chunk_traceset
, tsc
);
1245 lttv_trace_context_add_hooks(tc
,
1246 events_request
->before_chunk_trace
,
1247 events_request
->before_chunk_tracefile
,
1248 events_request
->event
,
1249 events_request
->event_by_id
);
1254 /* 2. Else, list_in is not empty, we continue a read */
1257 /* 2.0 For each req of list_in */
1258 GSList
*iter
= list_in
;
1260 while(iter
!= NULL
) {
1262 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1264 /* - Call before chunk
1265 * - events hooks added
1267 if(events_request
->trace
== -1)
1268 lttv_process_traceset_begin(tsc
,
1269 events_request
->before_chunk_traceset
,
1270 events_request
->before_chunk_trace
,
1271 events_request
->before_chunk_tracefile
,
1272 events_request
->event
,
1273 events_request
->event_by_id
);
1275 guint nb_trace
= lttv_traceset_number(tsc
->ts
);
1276 g_assert(events_request
->trace
< nb_trace
&&
1277 events_request
->trace
> -1);
1278 LttvTraceContext
*tc
= tsc
->traces
[events_request
->trace
];
1280 lttv_hooks_call(events_request
->before_chunk_traceset
, tsc
);
1282 lttv_trace_context_add_hooks(tc
,
1283 events_request
->before_chunk_trace
,
1284 events_request
->before_chunk_tracefile
,
1285 events_request
->event
,
1286 events_request
->event_by_id
);
1289 iter
= g_slist_next(iter
);
1294 tfc
= lttv_traceset_context_get_current_tfc(tsc
);
1296 /* 2.1 For each req of list_out */
1297 GSList
*iter
= list_out
;
1299 while(iter
!= NULL
) {
1301 gboolean remove
= FALSE
;
1302 gboolean free_data
= FALSE
;
1303 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1305 /* if req.start time == current context time
1306 * or req.start position == current position*/
1307 if( ltt_time_compare(events_request
->start_time
,
1308 tfc
->timestamp
) == 0
1310 (events_request
->start_position
!= NULL
1312 lttv_traceset_context_ctx_pos_compare(tsc
,
1313 events_request
->start_position
) == 0)
1315 /* - Add to list_in, remove from list_out */
1316 list_in
= g_slist_append(list_in
, events_request
);
1320 /* - If !servicing */
1321 if(events_request
->servicing
== FALSE
) {
1322 /* - begin request hooks called
1323 * - servicing = TRUE
1325 lttv_hooks_call(events_request
->before_request
, (gpointer
)tsc
);
1326 events_request
->servicing
= TRUE
;
1328 /* call before chunk
1329 * events hooks added
1331 if(events_request
->trace
== -1)
1332 lttv_process_traceset_begin(tsc
,
1333 events_request
->before_chunk_traceset
,
1334 events_request
->before_chunk_trace
,
1335 events_request
->before_chunk_tracefile
,
1336 events_request
->event
,
1337 events_request
->event_by_id
);
1339 guint nb_trace
= lttv_traceset_number(tsc
->ts
);
1340 g_assert(events_request
->trace
< nb_trace
&&
1341 events_request
->trace
> -1);
1342 LttvTraceContext
*tc
= tsc
->traces
[events_request
->trace
];
1344 lttv_hooks_call(events_request
->before_chunk_traceset
, tsc
);
1346 lttv_trace_context_add_hooks(tc
,
1347 events_request
->before_chunk_trace
,
1348 events_request
->before_chunk_tracefile
,
1349 events_request
->event
,
1350 events_request
->event_by_id
);
1359 GSList
*remove_iter
= iter
;
1361 iter
= g_slist_next(iter
);
1362 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
1363 list_out
= g_slist_remove_link(list_out
, remove_iter
);
1364 } else { // not remove
1365 iter
= g_slist_next(iter
);
1371 /* 3. Find end criterions */
1376 /* 3.1.1 Find lowest end time in list_in */
1377 g_assert(g_slist_length(list_in
)>0);
1378 end_time
= ((EventsRequest
*)g_slist_nth_data(list_in
,0))->end_time
;
1380 for(iter
=g_slist_nth(list_in
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
1381 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1383 if(ltt_time_compare(events_request
->end_time
,
1385 end_time
= events_request
->end_time
;
1388 /* 3.1.2 Find lowest start time in list_out */
1389 for(iter
=list_out
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
1390 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1392 if(ltt_time_compare(events_request
->start_time
,
1394 end_time
= events_request
->start_time
;
1399 /* 3.2 Number of events */
1401 /* 3.2.1 Find lowest number of events in list_in */
1404 end_nb_events
= ((EventsRequest
*)g_slist_nth_data(list_in
,0))->num_events
;
1406 for(iter
=g_slist_nth(list_in
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
1407 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1409 if(events_request
->num_events
< end_nb_events
)
1410 end_nb_events
= events_request
->num_events
;
1413 /* 3.2.2 Use min(CHUNK_NUM_EVENTS, min num events in list_in) as
1416 end_nb_events
= MIN(CHUNK_NUM_EVENTS
, end_nb_events
);
1420 /* 3.3 End position */
1422 /* 3.3.1 Find lowest end position in list_in */
1425 end_position
=((EventsRequest
*)g_slist_nth_data(list_in
,0))->end_position
;
1427 for(iter
=g_slist_nth(list_in
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
1428 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1430 if(events_request
->end_position
!= NULL
&& end_position
!= NULL
&&
1431 lttv_traceset_context_pos_pos_compare(events_request
->end_position
,
1433 end_position
= events_request
->end_position
;
1438 /* 3.3.2 Find lowest start position in list_out */
1441 for(iter
=list_out
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
1442 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1444 if(events_request
->end_position
!= NULL
&& end_position
!= NULL
&&
1445 lttv_traceset_context_pos_pos_compare(events_request
->end_position
,
1447 end_position
= events_request
->end_position
;
1452 /* 4. Call process traceset middle */
1453 g_debug("Calling process traceset middle with %p, %lu sec %lu nsec, %lu nb ev, %p end pos", tsc
, end_time
.tv_sec
, end_time
.tv_nsec
, end_nb_events
, end_position
);
1454 count
= lttv_process_traceset_middle(tsc
, end_time
, end_nb_events
, end_position
);
1456 tfc
= lttv_traceset_context_get_current_tfc(tsc
);
1458 g_debug("Context time after middle : %lu, %lu", tfc
->timestamp
.tv_sec
,
1459 tfc
->timestamp
.tv_nsec
);
1461 g_debug("End of trace reached after middle.");
1465 /* 5. After process traceset middle */
1466 tfc
= lttv_traceset_context_get_current_tfc(tsc
);
1468 /* - if current context time > traceset.end time */
1469 if(tfc
== NULL
|| ltt_time_compare(tfc
->timestamp
,
1470 tsc
->time_span
.end_time
) > 0) {
1471 /* - For each req in list_in */
1472 GSList
*iter
= list_in
;
1474 while(iter
!= NULL
) {
1476 gboolean remove
= FALSE
;
1477 gboolean free_data
= FALSE
;
1478 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1480 /* - Remove events hooks for req
1481 * - Call end chunk for req
1484 if(events_request
->trace
== -1)
1485 lttv_process_traceset_end(tsc
,
1486 events_request
->after_chunk_traceset
,
1487 events_request
->after_chunk_trace
,
1488 events_request
->after_chunk_tracefile
,
1489 events_request
->event
,
1490 events_request
->event_by_id
);
1493 guint nb_trace
= lttv_traceset_number(tsc
->ts
);
1494 g_assert(events_request
->trace
< nb_trace
&&
1495 events_request
->trace
> -1);
1496 LttvTraceContext
*tc
= tsc
->traces
[events_request
->trace
];
1498 lttv_trace_context_remove_hooks(tc
,
1499 events_request
->after_chunk_trace
,
1500 events_request
->after_chunk_tracefile
,
1501 events_request
->event
,
1502 events_request
->event_by_id
);
1503 lttv_hooks_call(events_request
->after_chunk_traceset
, tsc
);
1508 /* - Call end request for req */
1509 lttv_hooks_call(events_request
->after_request
, (gpointer
)tsc
);
1511 /* - remove req from list_in */
1512 /* Destroy the request */
1519 GSList
*remove_iter
= iter
;
1521 iter
= g_slist_next(iter
);
1522 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
1523 list_in
= g_slist_remove_link(list_in
, remove_iter
);
1524 } else { // not remove
1525 iter
= g_slist_next(iter
);
1530 /* 5.1 For each req in list_in */
1531 GSList
*iter
= list_in
;
1533 while(iter
!= NULL
) {
1535 gboolean remove
= FALSE
;
1536 gboolean free_data
= FALSE
;
1537 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1539 /* - Remove events hooks for req
1540 * - Call end chunk for req
1542 if(events_request
->trace
== -1)
1543 lttv_process_traceset_end(tsc
,
1544 events_request
->after_chunk_traceset
,
1545 events_request
->after_chunk_trace
,
1546 events_request
->after_chunk_tracefile
,
1547 events_request
->event
,
1548 events_request
->event_by_id
);
1551 guint nb_trace
= lttv_traceset_number(tsc
->ts
);
1552 g_assert(events_request
->trace
< nb_trace
&&
1553 events_request
->trace
> -1);
1554 LttvTraceContext
*tc
= tsc
->traces
[events_request
->trace
];
1556 lttv_trace_context_remove_hooks(tc
,
1557 events_request
->after_chunk_trace
,
1558 events_request
->after_chunk_tracefile
,
1559 events_request
->event
,
1560 events_request
->event_by_id
);
1562 lttv_hooks_call(events_request
->after_chunk_traceset
, tsc
);
1565 /* - req.num -= count */
1566 g_assert(events_request
->num_events
>= count
);
1567 events_request
->num_events
-= count
;
1569 g_assert(tfc
!= NULL
);
1570 /* - if req.num == 0
1572 * current context time >= req.end time
1574 * req.end pos == current pos
1576 * req.stop_flag == TRUE
1578 if( events_request
->num_events
== 0
1580 events_request
->stop_flag
== TRUE
1582 ltt_time_compare(tfc
->timestamp
,
1583 events_request
->end_time
) >= 0
1585 (events_request
->end_position
!= NULL
1587 lttv_traceset_context_ctx_pos_compare(tsc
,
1588 events_request
->end_position
) == 0)
1591 g_assert(events_request
->servicing
== TRUE
);
1592 /* - Call end request for req
1593 * - remove req from list_in */
1594 lttv_hooks_call(events_request
->after_request
, (gpointer
)tsc
);
1595 /* - remove req from list_in */
1596 /* Destroy the request */
1604 GSList
*remove_iter
= iter
;
1606 iter
= g_slist_next(iter
);
1607 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
1608 list_in
= g_slist_remove_link(list_in
, remove_iter
);
1609 } else { // not remove
1610 iter
= g_slist_next(iter
);
1616 /* End of removed servicing loop : leave control to GTK instead. */
1617 // if(gtk_events_pending()) break;
1620 /* B. When interrupted between chunks */
1623 GSList
*iter
= list_in
;
1625 /* 1. for each request in list_in */
1626 while(iter
!= NULL
) {
1628 gboolean remove
= FALSE
;
1629 gboolean free_data
= FALSE
;
1630 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1632 /* 1.1. Use current postition as start position */
1633 if(events_request
->start_position
!= NULL
)
1634 lttv_traceset_context_position_destroy(events_request
->start_position
);
1635 events_request
->start_position
= lttv_traceset_context_position_new();
1636 lttv_traceset_context_position_save(tsc
, events_request
->start_position
);
1638 /* 1.2. Remove start time */
1639 events_request
->start_time
= ltt_time_infinite
;
1641 /* 1.3. Move from list_in to list_out */
1644 list_out
= g_slist_append(list_out
, events_request
);
1649 GSList
*remove_iter
= iter
;
1651 iter
= g_slist_next(iter
);
1652 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
1653 list_in
= g_slist_remove_link(list_in
, remove_iter
);
1654 } else { // not remove
1655 iter
= g_slist_next(iter
);
1662 /* C Unlock Traces */
1664 //lttv_process_traceset_get_sync_data(tsc);
1669 iter_trace
<lttv_traceset_number(tsc
->ts
);
1671 LttvTrace
*trace_v
= lttv_traceset_get(tsc
->ts
, iter_trace
);
1673 lttvwindowtraces_unlock(trace_v
);
1678 //set the cursor back to normal
1679 gdk_window_set_cursor(win
, NULL
);
1682 g_assert(g_slist_length(list_in
) == 0);
1684 if( g_slist_length(list_out
) == 0 ) {
1685 /* Put tab's request pending flag back to normal */
1686 tab
->events_request_pending
= FALSE
;
1687 g_debug("remove the idle fct");
1688 return FALSE
; /* Remove the idle function */
1690 g_debug("leave the idle fct");
1691 return TRUE
; /* Leave the idle function */
1693 /* We do not use simili-round-robin, it may require to read 1 meg buffers
1694 * again and again if many tracesets use the same tracefiles. */
1695 /* Hack for round-robin idle functions */
1696 /* It will put the idle function at the end of the pool */
1697 /*g_idle_add_full((G_PRIORITY_HIGH_IDLE + 21),
1698 (GSourceFunc)execute_events_requests,
1708 /* add_trace_into_traceset_selector, each instance of a viewer has an associated
1709 * selector (filter), when a trace is added into traceset, the selector should
1710 * reflect the change. The function is used to update the selector
1713 void add_trace_into_traceset_selector(GtkWidget
* paned
, LttTrace
* t
)
1715 int j
, k
, m
, nb_tracefile
, nb_control
, nb_per_cpu
, nb_facility
, nb_event
;
1716 LttvTracesetSelector
* s
;
1717 LttvTraceSelector
* trace
;
1718 LttvTracefileSelector
* tracefile
;
1719 LttvEventtypeSelector
* eventtype
;
1725 w
= gtk_multivpaned_get_first_widget(GTK_MULTIVPANED(paned
));
1727 s
= g_object_get_data(G_OBJECT(w
), "Traceset_Selector");
1730 trace
= lttv_trace_selector_new(t
);
1731 lttv_traceset_selector_trace_add(s
, trace
);
1733 nb_facility
= ltt_trace_facility_number(t
);
1734 for(k
=0;k
<nb_facility
;k
++){
1735 fac
= ltt_trace_facility_get(t
,k
);
1736 nb_event
= (int) ltt_facility_eventtype_number(fac
);
1737 for(m
=0;m
<nb_event
;m
++){
1738 et
= ltt_facility_eventtype_get(fac
,m
);
1739 eventtype
= lttv_eventtype_selector_new(et
);
1740 lttv_trace_selector_eventtype_add(trace
, eventtype
);
1744 nb_control
= ltt_trace_control_tracefile_number(t
);
1745 nb_per_cpu
= ltt_trace_per_cpu_tracefile_number(t
);
1746 nb_tracefile
= nb_control
+ nb_per_cpu
;
1748 for(j
= 0 ; j
< nb_tracefile
; j
++) {
1750 tf
= ltt_trace_control_tracefile_get(t
, j
);
1752 tf
= ltt_trace_per_cpu_tracefile_get(t
, j
- nb_control
);
1753 tracefile
= lttv_tracefile_selector_new(tf
);
1754 lttv_trace_selector_tracefile_add(trace
, tracefile
);
1755 lttv_eventtype_selector_copy(trace
, tracefile
);
1757 }else g_warning("Module does not support filtering\n");
1759 w
= gtk_multivpaned_get_next_widget(GTK_MULTIVPANED(paned
));
1764 static void lttvwindow_add_trace(Tab
*tab
, LttvTrace
*trace_v
)
1766 LttvTraceset
*traceset
= tab
->traceset_info
->traceset
;
1768 guint num_traces
= lttv_traceset_number(traceset
);
1770 //Verify if trace is already present.
1771 for(i
=0; i
<num_traces
; i
++)
1773 LttvTrace
* trace
= lttv_traceset_get(traceset
, i
);
1774 if(trace
== trace_v
)
1778 //Keep a reference to the traces so they are not freed.
1779 for(i
=0; i
<lttv_traceset_number(traceset
); i
++)
1781 LttvTrace
* trace
= lttv_traceset_get(traceset
, i
);
1782 lttv_trace_ref(trace
);
1785 //remove state update hooks
1786 lttv_state_remove_event_hooks(
1787 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1789 lttv_context_fini(LTTV_TRACESET_CONTEXT(
1790 tab
->traceset_info
->traceset_context
));
1791 g_object_unref(tab
->traceset_info
->traceset_context
);
1793 lttv_traceset_add(traceset
, trace_v
);
1794 lttv_trace_ref(trace_v
); /* local ref */
1796 /* Create new context */
1797 tab
->traceset_info
->traceset_context
=
1798 g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
1800 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->
1805 //add state update hooks
1806 lttv_state_add_event_hooks(
1807 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1808 //Remove local reference to the traces.
1809 for(i
=0; i
<lttv_traceset_number(traceset
); i
++)
1811 LttvTrace
* trace
= lttv_traceset_get(traceset
, i
);
1812 lttv_trace_unref(trace
);
1816 //add_trace_into_traceset_selector(GTK_MULTIVPANED(tab->multivpaned), lttv_trace(trace_v));
1819 /* add_trace adds a trace into the current traceset. It first displays a
1820 * directory selection dialogue to let user choose a trace, then recreates
1821 * tracset_context, and redraws all the viewer of the current tab
1824 void add_trace(GtkWidget
* widget
, gpointer user_data
)
1827 LttvTrace
* trace_v
;
1828 LttvTraceset
* traceset
;
1830 char abs_path
[PATH_MAX
];
1833 MainWindow
* mw_data
= get_window_data_struct(widget
);
1834 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
1836 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
1837 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
1841 tab
= create_new_tab(widget
, NULL
);
1843 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
1846 GtkDirSelection
* file_selector
= (GtkDirSelection
*)gtk_dir_selection_new("Select a trace");
1847 gtk_dir_selection_hide_fileop_buttons(file_selector
);
1849 if(remember_trace_dir
[0] != '\0')
1850 gtk_dir_selection_set_filename(file_selector
, remember_trace_dir
);
1852 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
1854 case GTK_RESPONSE_ACCEPT
:
1855 case GTK_RESPONSE_OK
:
1856 dir
= gtk_dir_selection_get_dir (file_selector
);
1857 strncpy(remember_trace_dir
, dir
, PATH_MAX
);
1858 if(!dir
|| strlen(dir
) == 0){
1859 gtk_widget_destroy((GtkWidget
*)file_selector
);
1862 get_absolute_pathname(dir
, abs_path
);
1863 trace_v
= lttvwindowtraces_get_trace_by_name(abs_path
);
1864 if(trace_v
== NULL
) {
1865 trace
= ltt_trace_open(abs_path
);
1867 g_warning("cannot open trace %s", abs_path
);
1869 trace_v
= lttv_trace_new(trace
);
1870 lttvwindowtraces_add_trace(trace_v
);
1871 lttvwindow_add_trace(tab
, trace_v
);
1874 lttvwindow_add_trace(tab
, trace_v
);
1877 gtk_widget_destroy((GtkWidget
*)file_selector
);
1879 //update current tab
1880 //update_traceset(mw_data);
1882 /* Call the updatetraceset hooks */
1884 traceset
= tab
->traceset_info
->traceset
;
1885 SetTraceset(tab
, traceset
);
1886 // in expose now call_pending_read_hooks(mw_data);
1888 //lttvwindow_report_current_time(mw_data,&(tab->current_time));
1890 case GTK_RESPONSE_REJECT
:
1891 case GTK_RESPONSE_CANCEL
:
1893 gtk_widget_destroy((GtkWidget
*)file_selector
);
1899 /* remove_trace_into_traceset_selector, each instance of a viewer has an associated
1900 * selector (filter), when a trace is remove from traceset, the selector should
1901 * reflect the change. The function is used to update the selector
1904 void remove_trace_from_traceset_selector(GtkWidget
* paned
, unsigned i
)
1906 LttvTracesetSelector
* s
;
1907 LttvTraceSelector
* t
;
1910 w
= gtk_multivpaned_get_first_widget(GTK_MULTIVPANED(paned
));
1912 s
= g_object_get_data(G_OBJECT(w
), "Traceset_Selector");
1914 t
= lttv_traceset_selector_trace_get(s
,i
);
1915 lttv_traceset_selector_trace_remove(s
, i
);
1916 lttv_trace_selector_destroy(t
);
1917 }g_warning("Module dose not support filtering\n");
1918 w
= gtk_multivpaned_get_next_widget(GTK_MULTIVPANED(paned
));
1923 /* remove_trace removes a trace from the current traceset if all viewers in
1924 * the current tab are not interested in the trace. It first displays a
1925 * dialogue, which shows all traces in the current traceset, to let user choose
1926 * a trace, then it checks if all viewers unselect the trace, if it is true,
1927 * it will remove the trace, recreate the traceset_contex,
1928 * and redraws all the viewer of the current tab. If there is on trace in the
1929 * current traceset, it will delete all viewers of the current tab
1932 // MD : no filter version.
1933 void remove_trace(GtkWidget
*widget
, gpointer user_data
)
1936 LttvTrace
* trace_v
;
1937 LttvTraceset
* traceset
;
1938 gint i
, j
, nb_trace
, index
=-1;
1939 char ** name
, *remove_trace_name
;
1940 MainWindow
* mw_data
= get_window_data_struct(widget
);
1941 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
1943 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
1944 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
1950 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
1953 nb_trace
=lttv_traceset_number(tab
->traceset_info
->traceset
);
1954 name
= g_new(char*,nb_trace
);
1955 for(i
= 0; i
< nb_trace
; i
++){
1956 trace_v
= lttv_traceset_get(tab
->traceset_info
->traceset
, i
);
1957 trace
= lttv_trace(trace_v
);
1958 name
[i
] = ltt_trace_name(trace
);
1961 remove_trace_name
= get_remove_trace(name
, nb_trace
);
1964 if(remove_trace_name
){
1966 /* yuk, cut n paste from old code.. should be better (MD)*/
1967 for(i
= 0; i
<nb_trace
; i
++) {
1968 if(strcmp(remove_trace_name
,name
[i
]) == 0){
1973 traceset
= tab
->traceset_info
->traceset
;
1974 //Keep a reference to the traces so they are not freed.
1975 for(j
=0; j
<lttv_traceset_number(traceset
); j
++)
1977 LttvTrace
* trace
= lttv_traceset_get(traceset
, j
);
1978 lttv_trace_ref(trace
);
1981 //remove state update hooks
1982 lttv_state_remove_event_hooks(
1983 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1984 lttv_context_fini(LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
));
1985 g_object_unref(tab
->traceset_info
->traceset_context
);
1987 trace_v
= lttv_traceset_get(traceset
, index
);
1989 lttv_traceset_remove(traceset
, index
);
1990 lttv_trace_unref(trace_v
); // Remove local reference
1992 if(lttv_trace_get_ref_number(trace_v
) <= 1) {
1993 /* ref 1 : lttvwindowtraces only*/
1994 ltt_trace_close(lttv_trace(trace_v
));
1995 /* lttvwindowtraces_remove_trace takes care of destroying
1996 * the traceset linked with the trace_v and also of destroying
1997 * the trace_v at the same time.
1999 lttvwindowtraces_remove_trace(trace_v
);
2002 tab
->traceset_info
->traceset_context
=
2003 g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
2005 LTTV_TRACESET_CONTEXT(tab
->
2006 traceset_info
->traceset_context
),traceset
);
2007 //add state update hooks
2008 lttv_state_add_event_hooks(
2009 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
2011 //Remove local reference to the traces.
2012 for(j
=0; j
<lttv_traceset_number(traceset
); j
++)
2014 LttvTrace
* trace
= lttv_traceset_get(traceset
, j
);
2015 lttv_trace_unref(trace
);
2018 SetTraceset(tab
, (gpointer
)traceset
);
2024 void remove_trace(GtkWidget
* widget
, gpointer user_data
)
2027 LttvTrace
* trace_v
;
2028 LttvTraceset
* traceset
;
2029 gint i
, j
, nb_trace
;
2030 char ** name
, *remove_trace_name
;
2031 MainWindow
* mw_data
= get_window_data_struct(widget
);
2032 LttvTracesetSelector
* s
;
2033 LttvTraceSelector
* t
;
2036 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
2038 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2039 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2045 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
2048 nb_trace
=lttv_traceset_number(tab
->traceset_info
->traceset
);
2049 name
= g_new(char*,nb_trace
);
2050 for(i
= 0; i
< nb_trace
; i
++){
2051 trace_v
= lttv_traceset_get(tab
->traceset_info
->traceset
, i
);
2052 trace
= lttv_trace(trace_v
);
2053 name
[i
] = ltt_trace_name(trace
);
2056 remove_trace_name
= get_remove_trace(name
, nb_trace
);
2058 if(remove_trace_name
){
2059 for(i
=0; i
<nb_trace
; i
++){
2060 if(strcmp(remove_trace_name
,name
[i
]) == 0){
2061 //unselect the trace from the current viewer
2063 w
= gtk_multivpaned_get_widget(GTK_MULTIVPANED(tab
->multivpaned
));
2065 s
= g_object_get_data(G_OBJECT(w
), "Traceset_Selector");
2067 t
= lttv_traceset_selector_trace_get(s
,i
);
2068 lttv_trace_selector_set_selected(t
, FALSE
);
2071 //check if other viewers select the trace
2072 w
= gtk_multivpaned_get_first_widget(GTK_MULTIVPANED(tab
->multivpaned
));
2074 s
= g_object_get_data(G_OBJECT(w
), "Traceset_Selector");
2076 t
= lttv_traceset_selector_trace_get(s
,i
);
2077 selected
= lttv_trace_selector_get_selected(t
);
2080 w
= gtk_multivpaned_get_next_widget(GTK_MULTIVPANED(tab
->multivpaned
));
2082 }else selected
= FALSE
;
2084 //if no viewer selects the trace, remove it
2086 remove_trace_from_traceset_selector(GTK_MULTIVPANED(tab
->multivpaned
), i
);
2088 traceset
= tab
->traceset_info
->traceset
;
2089 //Keep a reference to the traces so they are not freed.
2090 for(j
=0; j
<lttv_traceset_number(traceset
); j
++)
2092 LttvTrace
* trace
= lttv_traceset_get(traceset
, j
);
2093 lttv_trace_ref(trace
);
2096 //remove state update hooks
2097 lttv_state_remove_event_hooks(
2098 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
2099 lttv_context_fini(LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
));
2100 g_object_unref(tab
->traceset_info
->traceset_context
);
2103 trace_v
= lttv_traceset_get(traceset
, i
);
2105 if(lttv_trace_get_ref_number(trace_v
) <= 2) {
2106 /* ref 2 : traceset, local */
2107 lttvwindowtraces_remove_trace(trace_v
);
2108 ltt_trace_close(lttv_trace(trace_v
));
2111 lttv_traceset_remove(traceset
, i
);
2112 lttv_trace_unref(trace_v
); // Remove local reference
2114 if(!lttv_trace_get_ref_number(trace_v
))
2115 lttv_trace_destroy(trace_v
);
2117 tab
->traceset_info
->traceset_context
=
2118 g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
2120 LTTV_TRACESET_CONTEXT(tab
->
2121 traceset_info
->traceset_context
),traceset
);
2122 //add state update hooks
2123 lttv_state_add_event_hooks(
2124 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
2126 //Remove local reference to the traces.
2127 for(j
=0; j
<lttv_traceset_number(traceset
); j
++)
2129 LttvTrace
* trace
= lttv_traceset_get(traceset
, j
);
2130 lttv_trace_unref(trace
);
2134 //update current tab
2135 //update_traceset(mw_data);
2138 SetTraceset(tab
, (gpointer
)traceset
);
2139 // in expose now call_pending_read_hooks(mw_data);
2141 //lttvwindow_report_current_time(mw_data,&(tab->current_time));
2144 // while(tab->multi_vpaned->num_children){
2145 // gtk_multi_vpaned_widget_delete(tab->multi_vpaned);
2159 /* Redraw all the viewers in the current tab */
2160 void redraw(GtkWidget
*widget
, gpointer user_data
)
2162 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
2163 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2164 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2169 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
2173 LttvAttributeValue value
;
2175 g_assert(lttv_iattribute_find_by_path(tab
->attributes
, "hooks/redraw", LTTV_POINTER
, &value
));
2177 tmp
= (LttvHooks
*)*(value
.v_pointer
);
2179 lttv_hooks_call(tmp
,NULL
);
2183 void continue_processing(GtkWidget
*widget
, gpointer user_data
)
2185 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
2186 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2187 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2192 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
2196 LttvAttributeValue value
;
2198 g_assert(lttv_iattribute_find_by_path(tab
->attributes
,
2199 "hooks/continue", LTTV_POINTER
, &value
));
2201 tmp
= (LttvHooks
*)*(value
.v_pointer
);
2203 lttv_hooks_call(tmp
,NULL
);
2206 /* Stop the processing for the calling main window's current tab.
2207 * It removes every processing requests that are in its list. It does not call
2208 * the end request hooks, because the request is not finished.
2211 void stop_processing(GtkWidget
*widget
, gpointer user_data
)
2213 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
2214 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2215 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2220 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
2222 GSList
*iter
= tab
->events_requests
;
2224 while(iter
!= NULL
) {
2225 GSList
*remove_iter
= iter
;
2226 iter
= g_slist_next(iter
);
2228 g_free(remove_iter
->data
);
2229 tab
->events_requests
=
2230 g_slist_remove_link(tab
->events_requests
, remove_iter
);
2232 tab
->events_request_pending
= FALSE
;
2233 g_idle_remove_by_data(tab
);
2234 g_assert(g_slist_length(tab
->events_requests
) == 0);
2238 /* save will save the traceset to a file
2239 * Not implemented yet FIXME
2242 void save(GtkWidget
* widget
, gpointer user_data
)
2247 void save_as(GtkWidget
* widget
, gpointer user_data
)
2249 g_printf("Save as\n");
2253 /* zoom will change the time_window of all the viewers of the
2254 * current tab, and redisplay them. The main functionality is to
2255 * determine the new time_window of the current tab
2258 void zoom(GtkWidget
* widget
, double size
)
2260 TimeInterval time_span
;
2261 TimeWindow new_time_window
;
2262 LttTime current_time
, time_delta
, time_s
, time_e
, time_tmp
;
2263 MainWindow
* mw_data
= get_window_data_struct(widget
);
2264 LttvTracesetContext
*tsc
;
2265 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
2267 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2268 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2274 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
2277 if(size
== 1) return;
2279 tsc
= LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
2280 time_span
= tsc
->time_span
;
2281 new_time_window
= tab
->time_window
;
2282 current_time
= tab
->current_time
;
2284 time_delta
= ltt_time_sub(time_span
.end_time
,time_span
.start_time
);
2286 new_time_window
.start_time
= time_span
.start_time
;
2287 new_time_window
.time_width
= time_delta
;
2288 new_time_window
.time_width_double
= ltt_time_to_double(time_delta
);
2289 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
2290 new_time_window
.time_width
) ;
2292 new_time_window
.time_width
= ltt_time_div(new_time_window
.time_width
, size
);
2293 new_time_window
.time_width_double
=
2294 ltt_time_to_double(new_time_window
.time_width
);
2295 if(ltt_time_compare(new_time_window
.time_width
,time_delta
) > 0)
2296 { /* Case where zoom out is bigger than trace length */
2297 new_time_window
.start_time
= time_span
.start_time
;
2298 new_time_window
.time_width
= time_delta
;
2299 new_time_window
.time_width_double
= ltt_time_to_double(time_delta
);
2300 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
2301 new_time_window
.time_width
) ;
2305 /* Center the image on the current time */
2306 new_time_window
.start_time
=
2307 ltt_time_sub(current_time
,
2308 ltt_time_from_double(new_time_window
.time_width_double
/2.0));
2309 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
2310 new_time_window
.time_width
) ;
2311 /* If on borders, don't fall off */
2312 if(ltt_time_compare(new_time_window
.start_time
, time_span
.start_time
) <0)
2314 new_time_window
.start_time
= time_span
.start_time
;
2315 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
2316 new_time_window
.time_width
) ;
2320 if(ltt_time_compare(new_time_window
.end_time
,
2321 time_span
.end_time
) > 0)
2323 new_time_window
.start_time
=
2324 ltt_time_sub(time_span
.end_time
, new_time_window
.time_width
);
2326 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
2327 new_time_window
.time_width
) ;
2334 if(ltt_time_compare(new_time_window
.time_width
, ltt_time_zero
) == 0) {
2335 g_warning("Zoom more than 1 ns impossible");
2337 time_change_manager(tab
, new_time_window
);
2341 void zoom_in(GtkWidget
* widget
, gpointer user_data
)
2346 void zoom_out(GtkWidget
* widget
, gpointer user_data
)
2351 void zoom_extended(GtkWidget
* widget
, gpointer user_data
)
2356 void go_to_time(GtkWidget
* widget
, gpointer user_data
)
2358 g_printf("Go to time\n");
2361 void show_time_frame(GtkWidget
* widget
, gpointer user_data
)
2363 g_printf("Show time frame\n");
2367 /* callback function */
2370 on_empty_traceset_activate (GtkMenuItem
*menuitem
,
2373 create_new_window((GtkWidget
*)menuitem
, user_data
, FALSE
);
2378 on_clone_traceset_activate (GtkMenuItem
*menuitem
,
2381 create_new_window((GtkWidget
*)menuitem
, user_data
, TRUE
);
2385 /* create_new_tab calls create_tab to construct a new tab in the main window
2388 Tab
*create_new_tab(GtkWidget
* widget
, gpointer user_data
){
2389 gchar label
[PATH_MAX
];
2390 MainWindow
* mw_data
= get_window_data_struct(widget
);
2392 GtkNotebook
* notebook
= (GtkNotebook
*)lookup_widget(widget
, "MNotebook");
2393 if(notebook
== NULL
){
2394 g_printf("Notebook does not exist\n");
2397 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2398 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2404 copy_tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
2407 strcpy(label
,"Page");
2408 if(get_label(mw_data
, label
,"Get the name of the tab","Please input tab's name"))
2409 return (create_tab (mw_data
, copy_tab
, notebook
, label
));
2413 on_tab_activate (GtkMenuItem
*menuitem
,
2416 create_new_tab((GtkWidget
*)menuitem
, user_data
);
2421 on_open_activate (GtkMenuItem
*menuitem
,
2424 open_traceset((GtkWidget
*)menuitem
, user_data
);
2429 on_close_activate (GtkMenuItem
*menuitem
,
2432 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2433 main_window_destructor(mw_data
);
2437 /* remove the current tab from the main window
2441 on_close_tab_activate (GtkWidget
*widget
,
2445 GtkWidget
* notebook
;
2447 MainWindow
* mw_data
= get_window_data_struct(widget
);
2448 notebook
= lookup_widget(widget
, "MNotebook");
2449 if(notebook
== NULL
){
2450 g_printf("Notebook does not exist\n");
2454 page_num
= gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
));
2456 gtk_notebook_remove_page(GTK_NOTEBOOK(notebook
), page_num
);
2461 on_close_tab_X_clicked (GtkWidget
*widget
,
2465 GtkWidget
*notebook
= lookup_widget(widget
, "MNotebook");
2466 if(notebook
== NULL
){
2467 g_printf("Notebook does not exist\n");
2471 if((page_num
= gtk_notebook_page_num(GTK_NOTEBOOK(notebook
), widget
)) != -1)
2472 gtk_notebook_remove_page(GTK_NOTEBOOK(notebook
), page_num
);
2478 on_add_trace_activate (GtkMenuItem
*menuitem
,
2481 add_trace((GtkWidget
*)menuitem
, user_data
);
2486 on_remove_trace_activate (GtkMenuItem
*menuitem
,
2489 remove_trace((GtkWidget
*)menuitem
, user_data
);
2494 on_save_activate (GtkMenuItem
*menuitem
,
2497 save((GtkWidget
*)menuitem
, user_data
);
2502 on_save_as_activate (GtkMenuItem
*menuitem
,
2505 save_as((GtkWidget
*)menuitem
, user_data
);
2510 on_quit_activate (GtkMenuItem
*menuitem
,
2518 on_cut_activate (GtkMenuItem
*menuitem
,
2526 on_copy_activate (GtkMenuItem
*menuitem
,
2529 g_printf("Copye\n");
2534 on_paste_activate (GtkMenuItem
*menuitem
,
2537 g_printf("Paste\n");
2542 on_delete_activate (GtkMenuItem
*menuitem
,
2545 g_printf("Delete\n");
2550 on_zoom_in_activate (GtkMenuItem
*menuitem
,
2553 zoom_in((GtkWidget
*)menuitem
, user_data
);
2558 on_zoom_out_activate (GtkMenuItem
*menuitem
,
2561 zoom_out((GtkWidget
*)menuitem
, user_data
);
2566 on_zoom_extended_activate (GtkMenuItem
*menuitem
,
2569 zoom_extended((GtkWidget
*)menuitem
, user_data
);
2574 on_go_to_time_activate (GtkMenuItem
*menuitem
,
2577 go_to_time((GtkWidget
*)menuitem
, user_data
);
2582 on_show_time_frame_activate (GtkMenuItem
*menuitem
,
2585 show_time_frame((GtkWidget
*)menuitem
, user_data
);
2590 on_move_viewer_up_activate (GtkMenuItem
*menuitem
,
2593 move_up_viewer((GtkWidget
*)menuitem
, user_data
);
2598 on_move_viewer_down_activate (GtkMenuItem
*menuitem
,
2601 move_down_viewer((GtkWidget
*)menuitem
, user_data
);
2606 on_remove_viewer_activate (GtkMenuItem
*menuitem
,
2609 delete_viewer((GtkWidget
*)menuitem
, user_data
);
2614 on_trace_filter_activate (GtkMenuItem
*menuitem
,
2617 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2618 LttvTracesetSelector
* s
;
2620 GtkWidget
* notebook
= lookup_widget(GTK_WIDGET(menuitem
), "MNotebook");
2622 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2623 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2629 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
2632 w
= gtk_multivpaned_get_widget(GTK_MULTIVPANED(tab
->multivpaned
));
2634 s
= g_object_get_data(G_OBJECT(w
), "Traceset_Selector");
2636 g_printf("There is no viewer yet\n");
2639 if(get_filter_selection(s
, "Configure trace and tracefile filter", "Select traces and tracefiles")){
2640 //FIXME report filter change
2641 //update_traceset(mw_data);
2642 //call_pending_read_hooks(mw_data);
2643 //lttvwindow_report_current_time(mw_data,&(tab->current_time));
2649 on_trace_facility_activate (GtkMenuItem
*menuitem
,
2652 g_printf("Trace facility selector: %s\n");
2656 /* Dispaly a file selection dialogue to let user select a library, then call
2657 * lttv_library_load().
2661 on_load_library_activate (GtkMenuItem
*menuitem
,
2664 GError
*error
= NULL
;
2665 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2667 gchar load_module_path_alter
[PATH_MAX
];
2671 gchar
*load_module_path
;
2672 name
= g_ptr_array_new();
2673 nb
= lttv_library_path_number();
2674 /* ask for the library path */
2678 path
= lttv_library_path_get(i
);
2679 g_ptr_array_add(name
, path
);
2682 load_module_path
= get_selection((char **)(name
->pdata
), name
->len
,
2683 "Select a library path", "Library paths");
2684 if(load_module_path
!= NULL
)
2685 strncpy(load_module_path_alter
, load_module_path
, PATH_MAX
-1); // -1 for /
2687 g_ptr_array_free(name
, TRUE
);
2689 if(load_module_path
== NULL
) return;
2693 /* Make sure the module path ends with a / */
2694 gchar
*ptr
= load_module_path_alter
;
2696 ptr
= strchr(ptr
, '\0');
2698 if(*(ptr
-1) != '/') {
2705 /* Ask for the library to load : list files in the previously selected
2707 gchar str
[PATH_MAX
];
2710 GtkFileSelection
* file_selector
=
2711 (GtkFileSelection
*)gtk_file_selection_new("Select a module");
2712 gtk_file_selection_set_filename(file_selector
, load_module_path_alter
);
2713 gtk_file_selection_hide_fileop_buttons(file_selector
);
2716 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
2718 case GTK_RESPONSE_ACCEPT
:
2719 case GTK_RESPONSE_OK
:
2720 dir
= gtk_file_selection_get_selections (file_selector
);
2721 strncpy(str
,dir
[0],PATH_MAX
);
2722 strncpy(remember_plugins_dir
,dir
[0],PATH_MAX
);
2723 /* only keep file name */
2725 str1
= strrchr(str
,'/');
2728 str1
= strrchr(str
,'\\');
2733 if(*str1
== 'l' && *(str1
+1)== 'i' && *(str1
+2)=='b')
2735 remove info after
. */
2739 str2
= strrchr(str2
, '.');
2740 if(str2
!= NULL
) *str2
= '\0';
2742 lttv_module_require(str1
, &error
);
2744 lttv_library_load(str1
, &error
);
2745 if(error
!= NULL
) g_warning(error
->message
);
2746 else g_printf("Load library: %s\n", str
);
2748 case GTK_RESPONSE_REJECT
:
2749 case GTK_RESPONSE_CANCEL
:
2751 gtk_widget_destroy((GtkWidget
*)file_selector
);
2762 /* Display all loaded modules, let user to select a module to unload
2763 * by calling lttv_module_unload
2767 on_unload_library_activate (GtkMenuItem
*menuitem
,
2770 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2772 LttvLibrary
*library
;
2777 name
= g_ptr_array_new();
2778 nb
= lttv_library_number();
2779 LttvLibraryInfo
*lib_info
= g_new(LttvLibraryInfo
,nb
);
2780 /* ask for the library name */
2783 LttvLibrary
*iter_lib
= lttv_library_get(i
);
2784 lttv_library_info(iter_lib
, &lib_info
[i
]);
2786 gchar
*path
= lib_info
[i
].name
;
2787 g_ptr_array_add(name
, lib_info
[i
].name
);
2789 lib_name
= get_selection((char **)(name
->pdata
), name
->len
,
2790 "Select a library", "Libraries");
2791 if(lib_name
!= NULL
) {
2793 if(strcmp(lib_name
, lib_info
[i
].name
) == 0) {
2794 library
= lttv_library_get(i
);
2799 g_ptr_array_free(name
, TRUE
);
2802 if(lib_name
== NULL
) return;
2805 lttv_library_unload(library
);
2809 /* Dispaly a file selection dialogue to let user select a module, then call
2810 * lttv_module_require().
2814 on_load_module_activate (GtkMenuItem
*menuitem
,
2817 GError
*error
= NULL
;
2818 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2820 LttvLibrary
*library
;
2825 name
= g_ptr_array_new();
2826 nb
= lttv_library_number();
2827 LttvLibraryInfo
*lib_info
= g_new(LttvLibraryInfo
,nb
);
2828 /* ask for the library name */
2831 LttvLibrary
*iter_lib
= lttv_library_get(i
);
2832 lttv_library_info(iter_lib
, &lib_info
[i
]);
2834 gchar
*path
= lib_info
[i
].name
;
2835 g_ptr_array_add(name
, path
);
2837 lib_name
= get_selection((char **)(name
->pdata
), name
->len
,
2838 "Select a library", "Libraries");
2839 if(lib_name
!= NULL
) {
2841 if(strcmp(lib_name
, lib_info
[i
].name
) == 0) {
2842 library
= lttv_library_get(i
);
2847 g_ptr_array_free(name
, TRUE
);
2850 if(lib_name
== NULL
) return;
2853 //LttvModule *module;
2854 gchar module_name_out
[PATH_MAX
];
2856 /* Ask for the module to load : list modules in the selected lib */
2860 LttvModuleInfo
*module_info
= g_new(LttvModuleInfo
,nb
);
2861 name
= g_ptr_array_new();
2862 nb
= lttv_library_module_number(library
);
2863 /* ask for the module name */
2866 LttvModule
*iter_module
= lttv_library_module_get(library
, i
);
2867 lttv_module_info(iter_module
, &module_info
[i
]);
2869 gchar
*path
= module_info
[i
].name
;
2870 g_ptr_array_add(name
, path
);
2872 module_name
= get_selection((char **)(name
->pdata
), name
->len
,
2873 "Select a module", "Modules");
2874 if(module_name
!= NULL
) {
2876 if(strcmp(module_name
, module_info
[i
].name
) == 0) {
2877 strncpy(module_name_out
, module_name
, PATH_MAX
);
2878 //module = lttv_library_module_get(i);
2884 g_ptr_array_free(name
, TRUE
);
2885 g_free(module_info
);
2887 if(module_name
== NULL
) return;
2890 lttv_module_require(module_name_out
, &error
);
2891 if(error
!= NULL
) g_warning(error
->message
);
2892 else g_printf("Load module: %s\n", module_name_out
);
2899 gchar str
[PATH_MAX
];
2902 GtkFileSelection
* file_selector
=
2903 (GtkFileSelection
*)gtk_file_selection_new("Select a module");
2904 gtk_file_selection_set_filename(file_selector
, load_module_path_alter
);
2905 gtk_file_selection_hide_fileop_buttons(file_selector
);
2908 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
2910 case GTK_RESPONSE_ACCEPT
:
2911 case GTK_RESPONSE_OK
:
2912 dir
= gtk_file_selection_get_selections (file_selector
);
2913 strncpy(str
,dir
[0],PATH_MAX
);
2914 strncpy(remember_plugins_dir
,dir
[0],PATH_MAX
);
2916 /* only keep file name */
2918 str1
= strrchr(str
,'/');
2921 str1
= strrchr(str
,'\\');
2926 if(*str1
== 'l' && *(str1
+1)== 'i' && *(str1
+2)=='b')
2928 remove info after
. */
2932 str2
= strrchr(str2
, '.');
2933 if(str2
!= NULL
) *str2
= '\0';
2935 lttv_module_require(str1
, &error
);
2937 lttv_library_load(str1
, &error
);
2938 if(error
!= NULL
) g_warning(error
->message
);
2939 else g_printf("Load library: %s\n", str
);
2941 case GTK_RESPONSE_REJECT
:
2942 case GTK_RESPONSE_CANCEL
:
2944 gtk_widget_destroy((GtkWidget
*)file_selector
);
2956 /* Display all loaded modules, let user to select a module to unload
2957 * by calling lttv_module_unload
2961 on_unload_module_activate (GtkMenuItem
*menuitem
,
2964 GError
*error
= NULL
;
2965 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2967 LttvLibrary
*library
;
2972 name
= g_ptr_array_new();
2973 nb
= lttv_library_number();
2974 LttvLibraryInfo
*lib_info
= g_new(LttvLibraryInfo
,nb
);
2975 /* ask for the library name */
2978 LttvLibrary
*iter_lib
= lttv_library_get(i
);
2979 lttv_library_info(iter_lib
, &lib_info
[i
]);
2981 gchar
*path
= lib_info
[i
].name
;
2982 g_ptr_array_add(name
, path
);
2984 lib_name
= get_selection((char **)(name
->pdata
), name
->len
,
2985 "Select a library", "Libraries");
2986 if(lib_name
!= NULL
) {
2988 if(strcmp(lib_name
, lib_info
[i
].name
) == 0) {
2989 library
= lttv_library_get(i
);
2994 g_ptr_array_free(name
, TRUE
);
2997 if(lib_name
== NULL
) return;
3002 /* Ask for the module to load : list modules in the selected lib */
3006 nb
= lttv_library_module_number(library
);
3007 LttvModuleInfo
*module_info
= g_new(LttvModuleInfo
,nb
);
3008 name
= g_ptr_array_new();
3009 /* ask for the module name */
3012 LttvModule
*iter_module
= lttv_library_module_get(library
, i
);
3013 lttv_module_info(iter_module
, &module_info
[i
]);
3015 gchar
*path
= module_info
[i
].name
;
3016 if(module_info
[i
].use_count
> 0) g_ptr_array_add(name
, path
);
3018 module_name
= get_selection((char **)(name
->pdata
), name
->len
,
3019 "Select a module", "Modules");
3020 if(module_name
!= NULL
) {
3022 if(strcmp(module_name
, module_info
[i
].name
) == 0) {
3023 module
= lttv_library_module_get(library
, i
);
3029 g_ptr_array_free(name
, TRUE
);
3030 g_free(module_info
);
3032 if(module_name
== NULL
) return;
3035 LttvModuleInfo module_info
;
3036 lttv_module_info(module
, &module_info
);
3037 g_printf("Release module: %s\n", module_info
.name
);
3039 lttv_module_release(module
);
3043 /* Display a directory dialogue to let user select a path for library searching
3047 on_add_library_search_path_activate (GtkMenuItem
*menuitem
,
3050 GtkDirSelection
* file_selector
= (GtkDirSelection
*)gtk_dir_selection_new("Select library path");
3054 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
3055 if(remember_plugins_dir
[0] != '\0')
3056 gtk_dir_selection_set_filename(file_selector
, remember_plugins_dir
);
3058 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
3060 case GTK_RESPONSE_ACCEPT
:
3061 case GTK_RESPONSE_OK
:
3062 dir
= gtk_dir_selection_get_dir (file_selector
);
3063 strncpy(remember_plugins_dir
,dir
,PATH_MAX
);
3064 strncat(remember_plugins_dir
,"/",PATH_MAX
);
3065 lttv_library_path_add(dir
);
3066 case GTK_RESPONSE_REJECT
:
3067 case GTK_RESPONSE_CANCEL
:
3069 gtk_widget_destroy((GtkWidget
*)file_selector
);
3075 /* Display a directory dialogue to let user select a path for library searching
3079 on_remove_library_search_path_activate (GtkMenuItem
*menuitem
,
3082 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
3084 const char *lib_path
;
3089 name
= g_ptr_array_new();
3090 nb
= lttv_library_path_number();
3091 /* ask for the library name */
3094 gchar
*path
= lttv_library_path_get(i
);
3095 g_ptr_array_add(name
, path
);
3097 lib_path
= get_selection((char **)(name
->pdata
), name
->len
,
3098 "Select a library path", "Library paths");
3100 g_ptr_array_free(name
, TRUE
);
3102 if(lib_path
== NULL
) return;
3105 lttv_library_path_remove(lib_path
);
3109 on_color_activate (GtkMenuItem
*menuitem
,
3112 g_printf("Color\n");
3117 on_filter_activate (GtkMenuItem
*menuitem
,
3120 g_printf("Filter\n");
3125 on_save_configuration_activate (GtkMenuItem
*menuitem
,
3128 g_printf("Save configuration\n");
3133 on_content_activate (GtkMenuItem
*menuitem
,
3136 g_printf("Content\n");
3141 on_about_close_activate (GtkButton
*button
,
3144 GtkWidget
*about_widget
= GTK_WIDGET(user_data
);
3146 gtk_widget_destroy(about_widget
);
3150 on_about_activate (GtkMenuItem
*menuitem
,
3153 MainWindow
*main_window
= get_window_data_struct(GTK_WIDGET(menuitem
));
3154 GtkWidget
*window_widget
= main_window
->mwindow
;
3155 GtkWidget
*about_widget
= gtk_window_new(GTK_WINDOW_TOPLEVEL
);
3156 GtkWindow
*about_window
= GTK_WINDOW(about_widget
);
3157 gint window_width
, window_height
;
3159 gtk_window_set_title(about_window
, "About Linux Trace Toolkit");
3161 gtk_window_set_resizable(about_window
, FALSE
);
3162 gtk_window_set_transient_for(GTK_WINDOW(window_widget
), about_window
);
3163 gtk_window_set_destroy_with_parent(about_window
, TRUE
);
3164 gtk_window_set_modal(about_window
, FALSE
);
3166 /* Put the about window at the center of the screen */
3167 gtk_window_get_size(about_window
, &window_width
, &window_height
);
3168 gtk_window_move (about_window
,
3169 (gdk_screen_width() - window_width
)/2,
3170 (gdk_screen_height() - window_height
)/2);
3172 GtkWidget
*vbox
= gtk_vbox_new(FALSE
, 1);
3174 gtk_container_add(GTK_CONTAINER(about_widget
), vbox
);
3178 GtkWidget
*label1
= gtk_label_new("");
3179 gtk_misc_set_padding(GTK_MISC(label1
), 10, 20);
3180 gtk_label_set_markup(GTK_LABEL(label1
), "\
3181 <big>Linux Trace Toolkit</big>");
3182 gtk_label_set_justify(GTK_LABEL(label1
), GTK_JUSTIFY_CENTER
);
3184 GtkWidget
*label2
= gtk_label_new("");
3185 gtk_misc_set_padding(GTK_MISC(label2
), 10, 20);
3186 gtk_label_set_markup(GTK_LABEL(label2
), "\
3187 Project author: Karim Yaghmour\n\
3191 Michel Dagenais (New trace format, lttv main)\n\
3192 Mathieu Desnoyers (Directory structure, build with automake/conf,\n\
3193 lttv gui, control flow view, gui green threads\n\
3194 with interruptible foreground and background computation,\n\
3195 detailed event list)\n\
3196 Benoit Des Ligneris (Cluster adaptation)\n\
3197 Xang-Xiu Yang (new trace reading library and converter, lttv gui, \n\
3198 detailed event list and statistics view)\n\
3199 Tom Zanussi (RelayFS)");
3201 GtkWidget
*label3
= gtk_label_new("");
3202 gtk_label_set_markup(GTK_LABEL(label3
), "\
3203 Linux Trace Toolkit, Copyright (C) 2004 Karim Yaghmour\n\
3204 Linux Trace Toolkit comes with ABSOLUTELY NO WARRANTY.\n\
3205 This is free software, and you are welcome to redistribute it\n\
3206 under certain conditions. See COPYING for details.");
3207 gtk_misc_set_padding(GTK_MISC(label3
), 10, 20);
3209 gtk_box_pack_start_defaults(GTK_BOX(vbox
), label1
);
3210 gtk_box_pack_start_defaults(GTK_BOX(vbox
), label2
);
3211 gtk_box_pack_start_defaults(GTK_BOX(vbox
), label3
);
3213 GtkWidget
*hbox
= gtk_hbox_new(TRUE
, 0);
3214 gtk_box_pack_end(GTK_BOX(vbox
), hbox
, FALSE
, FALSE
, 0);
3215 GtkWidget
*close_button
= gtk_button_new_with_mnemonic("_Close");
3216 gtk_box_pack_end(GTK_BOX(hbox
), close_button
, FALSE
, FALSE
, 0);
3217 gtk_container_set_border_width(GTK_CONTAINER(close_button
), 20);
3219 g_signal_connect(G_OBJECT(close_button
), "clicked",
3220 G_CALLBACK(on_about_close_activate
),
3221 (gpointer
)about_widget
);
3223 gtk_widget_show_all(about_widget
);
3228 on_button_new_clicked (GtkButton
*button
,
3231 create_new_window((GtkWidget
*)button
, user_data
, TRUE
);
3235 on_button_new_tab_clicked (GtkButton
*button
,
3238 create_new_tab((GtkWidget
*)button
, user_data
);
3242 on_button_open_clicked (GtkButton
*button
,
3245 open_traceset((GtkWidget
*)button
, user_data
);
3250 on_button_add_trace_clicked (GtkButton
*button
,
3253 add_trace((GtkWidget
*)button
, user_data
);
3258 on_button_remove_trace_clicked (GtkButton
*button
,
3261 remove_trace((GtkWidget
*)button
, user_data
);
3265 on_button_redraw_clicked (GtkButton
*button
,
3268 redraw((GtkWidget
*)button
, user_data
);
3272 on_button_continue_processing_clicked (GtkButton
*button
,
3275 continue_processing((GtkWidget
*)button
, user_data
);
3279 on_button_stop_processing_clicked (GtkButton
*button
,
3282 stop_processing((GtkWidget
*)button
, user_data
);
3288 on_button_save_clicked (GtkButton
*button
,
3291 save((GtkWidget
*)button
, user_data
);
3296 on_button_save_as_clicked (GtkButton
*button
,
3299 save_as((GtkWidget
*)button
, user_data
);
3304 on_button_zoom_in_clicked (GtkButton
*button
,
3307 zoom_in((GtkWidget
*)button
, user_data
);
3312 on_button_zoom_out_clicked (GtkButton
*button
,
3315 zoom_out((GtkWidget
*)button
, user_data
);
3320 on_button_zoom_extended_clicked (GtkButton
*button
,
3323 zoom_extended((GtkWidget
*)button
, user_data
);
3328 on_button_go_to_time_clicked (GtkButton
*button
,
3331 go_to_time((GtkWidget
*)button
, user_data
);
3336 on_button_show_time_frame_clicked (GtkButton
*button
,
3339 show_time_frame((GtkWidget
*)button
, user_data
);
3344 on_button_move_up_clicked (GtkButton
*button
,
3347 move_up_viewer((GtkWidget
*)button
, user_data
);
3352 on_button_move_down_clicked (GtkButton
*button
,
3355 move_down_viewer((GtkWidget
*)button
, user_data
);
3360 on_button_delete_viewer_clicked (GtkButton
*button
,
3363 delete_viewer((GtkWidget
*)button
, user_data
);
3367 on_MWindow_destroy (GtkWidget
*widget
,
3370 MainWindow
*main_window
= get_window_data_struct(widget
);
3371 LttvIAttribute
*attributes
= main_window
->attributes
;
3372 LttvAttributeValue value
;
3374 //This is unnecessary, since widgets will be destroyed
3375 //by the main window widget anyway.
3376 //remove_all_menu_toolbar_constructors(main_window, NULL);
3378 g_assert(lttv_iattribute_find_by_path(attributes
,
3379 "viewers/menu", LTTV_POINTER
, &value
));
3380 lttv_menus_destroy((LttvMenus
*)*(value
.v_pointer
));
3382 g_assert(lttv_iattribute_find_by_path(attributes
,
3383 "viewers/toolbar", LTTV_POINTER
, &value
));
3384 lttv_toolbars_destroy((LttvToolbars
*)*(value
.v_pointer
));
3386 g_object_unref(main_window
->attributes
);
3387 g_main_window_list
= g_slist_remove(g_main_window_list
, main_window
);
3389 g_printf("There are now : %d windows\n",g_slist_length(g_main_window_list
));
3390 if(g_slist_length(g_main_window_list
) == 0)
3395 on_MWindow_configure (GtkWidget
*widget
,
3396 GdkEventConfigure
*event
,
3399 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)widget
);
3400 float width
= event
->width
;
3401 TimeWindow time_win
;
3403 TimeInterval
*time_span
;
3406 // MD : removed time width modification upon resizing of the main window.
3407 // The viewers will redraw themselves completely, without time interval
3410 if(mw_data->window_width){
3411 time_span = LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context)->Time_Span ;
3412 time_win = tab->time_window;
3413 ratio = width / mw_data->window_width;
3414 tab->time_window.time_width = ltt_time_mul(time_win.time_width,ratio);
3415 time = ltt_time_sub(time_span->endTime, time_win.start_time);
3416 if(ltt_time_compare(time, tab->time_window.time_width) < 0){
3417 tab->time_window.time_width = time;
3423 mw_data->window_width = (int)width;
3432 on_MNotebook_switch_page (GtkNotebook
*notebook
,
3433 GtkNotebookPage
*page
,
3441 void time_change_manager (Tab
*tab
,
3442 TimeWindow new_time_window
)
3444 /* Only one source of time change */
3445 if(tab
->time_manager_lock
== TRUE
) return;
3447 tab
->time_manager_lock
= TRUE
;
3449 LttvTracesetContext
*tsc
= LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3450 TimeInterval time_span
= tsc
->time_span
;
3451 LttTime start_time
= new_time_window
.start_time
;
3452 LttTime end_time
= new_time_window
.end_time
;
3455 GtkAdjustment
*adjustment
= gtk_range_get_adjustment(GTK_RANGE(tab
->scrollbar
));
3456 LttTime upper
= ltt_time_sub(time_span
.end_time
, time_span
.start_time
);
3458 gtk_range_set_increments(GTK_RANGE(tab
->scrollbar
),
3459 ltt_time_to_double(new_time_window
.time_width
)
3460 / SCROLL_STEP_PER_PAGE
3461 * NANOSECONDS_PER_SECOND
, /* step increment */
3462 ltt_time_to_double(new_time_window
.time_width
)
3463 * NANOSECONDS_PER_SECOND
); /* page increment */
3464 gtk_range_set_range(GTK_RANGE(tab
->scrollbar
),
3466 ltt_time_to_double(upper
)
3467 * NANOSECONDS_PER_SECOND
); /* upper */
3469 g_object_set(G_OBJECT(adjustment
),
3473 ltt_time_to_double(upper
), /* upper */
3475 new_time_window
.time_width_double
3476 / SCROLL_STEP_PER_PAGE
, /* step increment */
3478 new_time_window
.time_width_double
,
3479 /* page increment */
3481 new_time_window
.time_width_double
, /* page size */
3483 gtk_adjustment_changed(adjustment
);
3485 // g_object_set(G_OBJECT(adjustment),
3487 // ltt_time_to_double(
3488 // ltt_time_sub(start_time, time_span.start_time))
3491 //gtk_adjustment_value_changed(adjustment);
3492 gtk_range_set_value(GTK_RANGE(tab
->scrollbar
),
3494 ltt_time_sub(start_time
, time_span
.start_time
)) /* value */);
3496 /* set the time bar. */
3498 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry1
),
3499 (double)time_span
.start_time
.tv_sec
,
3500 (double)time_span
.end_time
.tv_sec
);
3501 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry1
),
3502 (double)start_time
.tv_sec
);
3504 /* start nanoseconds */
3505 if(start_time
.tv_sec
== time_span
.start_time
.tv_sec
) {
3506 /* can be both beginning and end at the same time. */
3507 if(start_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3508 /* If we are at the end, max nsec to end.. -1 (not zero length) */
3509 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry2
),
3510 (double)time_span
.start_time
.tv_nsec
,
3511 (double)time_span
.end_time
.tv_nsec
-1);
3513 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry2
),
3514 (double)time_span
.start_time
.tv_nsec
,
3515 (double)NANOSECONDS_PER_SECOND
-1);
3517 } else if(start_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3518 /* If we are at the end, max nsec to end.. -1 (not zero length) */
3519 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry2
),
3521 (double)time_span
.end_time
.tv_nsec
-1);
3522 } else /* anywhere else */
3523 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry2
),
3525 (double)NANOSECONDS_PER_SECOND
-1);
3526 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry2
),
3527 (double)start_time
.tv_nsec
);
3530 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry3
),
3531 (double)time_span
.start_time
.tv_sec
,
3532 (double)time_span
.end_time
.tv_sec
);
3533 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry3
),
3534 (double)end_time
.tv_sec
);
3536 /* end nanoseconds */
3537 if(end_time
.tv_sec
== time_span
.start_time
.tv_sec
) {
3538 /* can be both beginning and end at the same time. */
3539 if(end_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3540 /* If we are at the end, max nsec to end.. */
3541 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry4
),
3542 (double)time_span
.start_time
.tv_nsec
+1,
3543 (double)time_span
.end_time
.tv_nsec
);
3545 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry4
),
3546 (double)time_span
.start_time
.tv_nsec
+1,
3547 (double)NANOSECONDS_PER_SECOND
-1);
3550 else if(end_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3551 /* If we are at the end, max nsec to end.. */
3552 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry4
),
3554 (double)time_span
.end_time
.tv_nsec
);
3556 else /* anywhere else */
3557 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry4
),
3559 (double)NANOSECONDS_PER_SECOND
-1);
3560 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry4
),
3561 (double)end_time
.tv_nsec
);
3563 /* call viewer hooks for new time window */
3564 set_time_window(tab
, &new_time_window
);
3566 tab
->time_manager_lock
= FALSE
;
3570 /* value changed for frame start s
3572 * Check time span : if ns is out of range, clip it the nearest good value.
3575 on_MEntry1_value_changed (GtkSpinButton
*spinbutton
,
3578 Tab
*tab
=(Tab
*)user_data
;
3579 LttvTracesetContext
* tsc
=
3580 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3581 TimeInterval time_span
= tsc
->time_span
;
3582 gint value
= gtk_spin_button_get_value_as_int(spinbutton
);
3584 TimeWindow new_time_window
= tab
->time_window
;
3586 LttTime end_time
= new_time_window
.end_time
;
3588 new_time_window
.start_time
.tv_sec
= value
;
3590 /* start nanoseconds */
3591 if(new_time_window
.start_time
.tv_sec
== time_span
.start_time
.tv_sec
) {
3592 if(new_time_window
.start_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3593 if(new_time_window
.start_time
.tv_nsec
> time_span
.end_time
.tv_nsec
)
3594 new_time_window
.start_time
.tv_nsec
= time_span
.end_time
.tv_nsec
-1;
3595 if(new_time_window
.start_time
.tv_nsec
< time_span
.start_time
.tv_nsec
)
3596 new_time_window
.start_time
.tv_nsec
= time_span
.start_time
.tv_nsec
;
3598 if(new_time_window
.start_time
.tv_nsec
< time_span
.start_time
.tv_nsec
)
3599 new_time_window
.start_time
.tv_nsec
= time_span
.start_time
.tv_nsec
;
3602 else if(new_time_window
.start_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3603 if(new_time_window
.start_time
.tv_nsec
> time_span
.end_time
.tv_nsec
)
3604 new_time_window
.start_time
.tv_nsec
= time_span
.end_time
.tv_nsec
-1;
3607 if(ltt_time_compare(new_time_window
.start_time
, end_time
) >= 0) {
3608 /* Then, we must push back end time : keep the same time width
3609 * if possible, else end traceset time */
3610 end_time
= LTT_TIME_MIN(ltt_time_add(new_time_window
.start_time
,
3611 new_time_window
.time_width
),
3612 time_span
.end_time
);
3615 /* Fix the time width to fit start time and end time */
3616 new_time_window
.time_width
= ltt_time_sub(end_time
,
3617 new_time_window
.start_time
);
3618 new_time_window
.time_width_double
=
3619 ltt_time_to_double(new_time_window
.time_width
);
3621 new_time_window
.end_time
= end_time
;
3623 time_change_manager(tab
, new_time_window
);
3628 on_MEntry2_value_changed (GtkSpinButton
*spinbutton
,
3631 Tab
*tab
=(Tab
*)user_data
;
3632 LttvTracesetContext
* tsc
=
3633 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3634 TimeInterval time_span
= tsc
->time_span
;
3635 gint value
= gtk_spin_button_get_value_as_int(spinbutton
);
3637 TimeWindow new_time_window
= tab
->time_window
;
3639 LttTime end_time
= new_time_window
.end_time
;
3641 new_time_window
.start_time
.tv_nsec
= value
;
3643 if(ltt_time_compare(new_time_window
.start_time
, end_time
) >= 0) {
3644 /* Then, we must push back end time : keep the same time width
3645 * if possible, else end traceset time */
3646 end_time
= LTT_TIME_MIN(ltt_time_add(new_time_window
.start_time
,
3647 new_time_window
.time_width
),
3648 time_span
.end_time
);
3651 /* Fix the time width to fit start time and end time */
3652 new_time_window
.time_width
= ltt_time_sub(end_time
,
3653 new_time_window
.start_time
);
3654 new_time_window
.time_width_double
=
3655 ltt_time_to_double(new_time_window
.time_width
);
3657 new_time_window
.end_time
= end_time
;
3659 time_change_manager(tab
, new_time_window
);
3664 on_MEntry3_value_changed (GtkSpinButton
*spinbutton
,
3667 Tab
*tab
=(Tab
*)user_data
;
3668 LttvTracesetContext
* tsc
=
3669 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3670 TimeInterval time_span
= tsc
->time_span
;
3671 gint value
= gtk_spin_button_get_value_as_int(spinbutton
);
3673 TimeWindow new_time_window
= tab
->time_window
;
3675 LttTime end_time
= new_time_window
.end_time
;
3677 end_time
.tv_sec
= value
;
3679 /* end nanoseconds */
3680 if(end_time
.tv_sec
== time_span
.start_time
.tv_sec
) {
3681 if(end_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3682 if(end_time
.tv_nsec
> time_span
.end_time
.tv_nsec
)
3683 end_time
.tv_nsec
= time_span
.end_time
.tv_nsec
;
3684 if(end_time
.tv_nsec
< time_span
.start_time
.tv_nsec
)
3685 end_time
.tv_nsec
= time_span
.start_time
.tv_nsec
+1;
3687 if(end_time
.tv_nsec
< time_span
.start_time
.tv_nsec
)
3688 end_time
.tv_nsec
= time_span
.start_time
.tv_nsec
+1;
3691 else if(end_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3692 if(end_time
.tv_nsec
> time_span
.end_time
.tv_nsec
)
3693 end_time
.tv_nsec
= time_span
.end_time
.tv_nsec
;
3696 if(ltt_time_compare(new_time_window
.start_time
, end_time
) >= 0) {
3697 /* Then, we must push front start time : keep the same time width
3698 * if possible, else end traceset time */
3699 new_time_window
.start_time
= LTT_TIME_MAX(
3700 ltt_time_sub(end_time
,
3701 new_time_window
.time_width
),
3702 time_span
.start_time
);
3705 /* Fix the time width to fit start time and end time */
3706 new_time_window
.time_width
= ltt_time_sub(end_time
,
3707 new_time_window
.start_time
);
3708 new_time_window
.time_width_double
=
3709 ltt_time_to_double(new_time_window
.time_width
);
3711 new_time_window
.end_time
= end_time
;
3713 time_change_manager(tab
, new_time_window
);
3718 on_MEntry4_value_changed (GtkSpinButton
*spinbutton
,
3721 Tab
*tab
=(Tab
*)user_data
;
3722 LttvTracesetContext
* tsc
=
3723 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3724 TimeInterval time_span
= tsc
->time_span
;
3725 gint value
= gtk_spin_button_get_value_as_int(spinbutton
);
3727 TimeWindow new_time_window
= tab
->time_window
;
3729 LttTime end_time
= new_time_window
.end_time
;
3731 end_time
.tv_nsec
= value
;
3733 if(ltt_time_compare(new_time_window
.start_time
, end_time
) >= 0) {
3734 /* Then, we must push front start time : keep the same time width
3735 * if possible, else end traceset time */
3736 new_time_window
.start_time
= LTT_TIME_MAX(
3737 ltt_time_sub(end_time
,
3738 new_time_window
.time_width
),
3739 time_span
.start_time
);
3742 /* Fix the time width to fit start time and end time */
3743 new_time_window
.time_width
= ltt_time_sub(end_time
,
3744 new_time_window
.start_time
);
3745 new_time_window
.time_width_double
=
3746 ltt_time_to_double(new_time_window
.time_width
);
3747 new_time_window
.end_time
= end_time
;
3749 time_change_manager(tab
, new_time_window
);
3754 void current_time_change_manager (Tab
*tab
,
3755 LttTime new_current_time
)
3757 /* Only one source of time change */
3758 if(tab
->current_time_manager_lock
== TRUE
) return;
3760 tab
->current_time_manager_lock
= TRUE
;
3762 LttvTracesetContext
*tsc
= LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3763 TimeInterval time_span
= tsc
->time_span
;
3765 /* current seconds */
3766 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry5
),
3767 (double)time_span
.start_time
.tv_sec
,
3768 (double)time_span
.end_time
.tv_sec
);
3769 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry5
),
3770 (double)new_current_time
.tv_sec
);
3773 /* start nanoseconds */
3774 if(new_current_time
.tv_sec
== time_span
.start_time
.tv_sec
) {
3775 /* can be both beginning and end at the same time. */
3776 if(new_current_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3777 /* If we are at the end, max nsec to end.. */
3778 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry6
),
3779 (double)time_span
.start_time
.tv_nsec
,
3780 (double)time_span
.end_time
.tv_nsec
);
3782 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry6
),
3783 (double)time_span
.start_time
.tv_nsec
,
3784 (double)NANOSECONDS_PER_SECOND
-1);
3786 } else if(new_current_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3787 /* If we are at the end, max nsec to end.. */
3788 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry6
),
3790 (double)time_span
.end_time
.tv_nsec
);
3791 } else /* anywhere else */
3792 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry6
),
3794 (double)NANOSECONDS_PER_SECOND
-1);
3796 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry6
),
3797 (double)new_current_time
.tv_nsec
);
3799 set_current_time(tab
, &new_current_time
);
3801 tab
->current_time_manager_lock
= FALSE
;
3805 on_MEntry5_value_changed (GtkSpinButton
*spinbutton
,
3808 Tab
*tab
= (Tab
*)user_data
;
3809 LttvTracesetContext
* tsc
=
3810 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3811 TimeInterval time_span
= tsc
->time_span
;
3812 gint value
= gtk_spin_button_get_value_as_int(spinbutton
);
3813 LttTime new_current_time
= tab
->current_time
;
3814 new_current_time
.tv_sec
= value
;
3816 /* current nanoseconds */
3817 if(new_current_time
.tv_sec
== time_span
.start_time
.tv_sec
) {
3818 if(new_current_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3819 if(new_current_time
.tv_nsec
> time_span
.end_time
.tv_nsec
)
3820 new_current_time
.tv_nsec
= time_span
.end_time
.tv_nsec
;
3821 if(new_current_time
.tv_nsec
< time_span
.start_time
.tv_nsec
)
3822 new_current_time
.tv_nsec
= time_span
.start_time
.tv_nsec
;
3824 if(new_current_time
.tv_nsec
< time_span
.start_time
.tv_nsec
)
3825 new_current_time
.tv_nsec
= time_span
.start_time
.tv_nsec
;
3828 else if(new_current_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3829 if(new_current_time
.tv_nsec
> time_span
.end_time
.tv_nsec
)
3830 new_current_time
.tv_nsec
= time_span
.end_time
.tv_nsec
;
3833 current_time_change_manager(tab
, new_current_time
);
3837 on_MEntry6_value_changed (GtkSpinButton
*spinbutton
,
3840 Tab
*tab
= (Tab
*)user_data
;
3841 gint value
= gtk_spin_button_get_value_as_int(spinbutton
);
3842 LttTime new_current_time
= tab
->current_time
;
3843 new_current_time
.tv_nsec
= value
;
3845 current_time_change_manager(tab
, new_current_time
);
3849 void scroll_value_changed_cb(GtkWidget
*scrollbar
,
3852 Tab
*tab
= (Tab
*)user_data
;
3853 TimeWindow new_time_window
;
3855 GtkAdjustment
*adjust
= gtk_range_get_adjustment(GTK_RANGE(scrollbar
));
3856 gdouble value
= gtk_adjustment_get_value(adjust
);
3857 // gdouble upper, lower, ratio, page_size;
3859 LttvTracesetContext
* tsc
=
3860 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3861 TimeInterval time_span
= tsc
->time_span
;
3863 time
= ltt_time_add(ltt_time_from_double(value
),
3864 time_span
.start_time
);
3866 new_time_window
.start_time
= time
;
3868 page_size
= adjust
->page_size
;
3870 new_time_window
.time_width
=
3871 ltt_time_from_double(page_size
);
3873 new_time_window
.time_width_double
=
3876 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
3877 new_time_window
.time_width
);
3880 time_change_manager(tab
, new_time_window
);
3882 //time_window = tab->time_window;
3884 lower
= adjust
->lower
;
3885 upper
= adjust
->upper
;
3886 ratio
= (value
- lower
) / (upper
- lower
);
3887 g_info("lower %lu, upper %lu, value %lu, ratio %lu", lower
, upper
, value
, ratio
);
3889 //time = ltt_time_sub(time_span->end_time, time_span->start_time);
3890 //time = ltt_time_mul(time, (float)ratio);
3891 //time = ltt_time_add(time_span->start_time, time);
3892 time
= ltt_time_add(ltt_time_from_double(value
),
3893 time_span
.start_time
);
3895 time_window
.start_time
= time
;
3897 page_size
= adjust
->page_size
;
3899 time_window
.time_width
=
3900 ltt_time_from_double(page_size
);
3901 //time = ltt_time_sub(time_span.end_time, time);
3902 //if(ltt_time_compare(time,time_window.time_width) < 0){
3903 // time_window.time_width = time;
3906 /* call viewer hooks for new time window */
3907 set_time_window(tab
, &time_window
);
3912 /* callback function to check or uncheck the check box (filter)
3915 void checkbox_changed(GtkTreeView
*treeview
,
3917 GtkTreeViewColumn
*arg2
,
3920 GtkTreeStore
* store
= (GtkTreeStore
*)gtk_tree_view_get_model (treeview
);
3924 if (gtk_tree_model_get_iter ((GtkTreeModel
*)store
, &iter
, arg1
)){
3925 gtk_tree_model_get ((GtkTreeModel
*)store
, &iter
, CHECKBOX_COLUMN
, &value
, -1);
3926 value
= value
? FALSE
: TRUE
;
3927 gtk_tree_store_set (GTK_TREE_STORE (store
), &iter
, CHECKBOX_COLUMN
, value
, -1);
3933 /* According to user's selection, update selector(filter)
3936 void update_filter(LttvTracesetSelector
*s
, GtkTreeStore
*store
)
3938 GtkTreeIter iter
, child_iter
, child_iter1
, child_iter2
;
3939 int i
, j
, k
, nb_eventtype
;
3940 LttvTraceSelector
* trace
;
3941 LttvTracefileSelector
* tracefile
;
3942 LttvEventtypeSelector
* eventtype
;
3943 gboolean value
, value1
, value2
;
3945 if(gtk_tree_model_get_iter_first((GtkTreeModel
*)store
, &iter
)){
3948 trace
= lttv_traceset_selector_trace_get(s
, i
);
3949 nb_eventtype
= lttv_trace_selector_eventtype_number(trace
);
3950 gtk_tree_model_get ((GtkTreeModel
*)store
, &iter
, CHECKBOX_COLUMN
, &value
,-1);
3953 if(gtk_tree_model_iter_children ((GtkTreeModel
*)store
, &child_iter
, &iter
)){
3955 if(j
<1){//eventtype selector for trace
3956 gtk_tree_model_get ((GtkTreeModel
*)store
, &child_iter
, CHECKBOX_COLUMN
, &value2
,-1);
3959 if(gtk_tree_model_iter_children ((GtkTreeModel
*)store
, &child_iter1
, &child_iter
)){
3961 eventtype
= lttv_trace_selector_eventtype_get(trace
,k
);
3962 gtk_tree_model_get ((GtkTreeModel
*)store
, &child_iter1
, CHECKBOX_COLUMN
, &value2
,-1);
3963 lttv_eventtype_selector_set_selected(eventtype
,value2
);
3965 }while(gtk_tree_model_iter_next((GtkTreeModel
*)store
, &child_iter1
));
3968 }else{ //tracefile selector
3969 tracefile
= lttv_trace_selector_tracefile_get(trace
, j
- 1);
3970 gtk_tree_model_get ((GtkTreeModel
*)store
, &child_iter
, CHECKBOX_COLUMN
, &value1
,-1);
3971 lttv_tracefile_selector_set_selected(tracefile
,value1
);
3973 gtk_tree_model_iter_children((GtkTreeModel
*)store
, &child_iter1
, &child_iter
); //eventtype selector
3974 gtk_tree_model_get ((GtkTreeModel
*)store
, &child_iter1
, CHECKBOX_COLUMN
, &value2
,-1);
3977 if(gtk_tree_model_iter_children ((GtkTreeModel
*)store
, &child_iter2
, &child_iter1
)){
3978 do{//eventtype selector for tracefile
3979 eventtype
= lttv_tracefile_selector_eventtype_get(tracefile
,k
);
3980 gtk_tree_model_get ((GtkTreeModel
*)store
, &child_iter2
, CHECKBOX_COLUMN
, &value2
,-1);
3981 lttv_eventtype_selector_set_selected(eventtype
,value2
);
3983 }while(gtk_tree_model_iter_next((GtkTreeModel
*)store
, &child_iter2
));
3989 }while(gtk_tree_model_iter_next((GtkTreeModel
*)store
, &child_iter
));
3992 lttv_trace_selector_set_selected(trace
,value
);
3994 }while(gtk_tree_model_iter_next((GtkTreeModel
*)store
, &iter
));
3999 /* Display a dialogue showing all eventtypes and traces, let user to select the interested
4000 * eventtypes, tracefiles and traces (filter)
4003 gboolean
get_filter_selection(LttvTracesetSelector
*s
,char *title
, char * column_title
)
4005 GtkWidget
* dialogue
;
4006 GtkTreeStore
* store
;
4008 GtkWidget
* scroll_win
;
4009 GtkCellRenderer
* renderer
;
4010 GtkTreeViewColumn
* column
;
4011 GtkTreeIter iter
, child_iter
, child_iter1
, child_iter2
;
4012 int i
, j
, k
, id
, nb_trace
, nb_tracefile
, nb_eventtype
;
4013 LttvTraceSelector
* trace
;
4014 LttvTracefileSelector
* tracefile
;
4015 LttvEventtypeSelector
* eventtype
;
4019 dialogue
= gtk_dialog_new_with_buttons(title
,
4022 GTK_STOCK_OK
,GTK_RESPONSE_ACCEPT
,
4023 GTK_STOCK_CANCEL
,GTK_RESPONSE_REJECT
,
4025 gtk_window_set_default_size((GtkWindow
*)dialogue
, 300, 500);
4027 store
= gtk_tree_store_new (TOTAL_COLUMNS
, G_TYPE_BOOLEAN
, G_TYPE_STRING
);
4028 tree
= gtk_tree_view_new_with_model (GTK_TREE_MODEL (store
));
4029 g_object_unref (G_OBJECT (store
));
4030 g_signal_connect (G_OBJECT (tree
), "row-activated",
4031 G_CALLBACK (checkbox_changed
),
4035 renderer
= gtk_cell_renderer_toggle_new ();
4036 gtk_cell_renderer_toggle_set_radio((GtkCellRendererToggle
*)renderer
, FALSE
);
4038 g_object_set (G_OBJECT (renderer
),"activatable", TRUE
, NULL
);
4040 column
= gtk_tree_view_column_new_with_attributes ("Checkbox",
4042 "active", CHECKBOX_COLUMN
,
4044 gtk_tree_view_column_set_alignment (column
, 0.5);
4045 gtk_tree_view_column_set_fixed_width (column
, 20);
4046 gtk_tree_view_append_column (GTK_TREE_VIEW (tree
), column
);
4048 renderer
= gtk_cell_renderer_text_new ();
4049 column
= gtk_tree_view_column_new_with_attributes (column_title
,
4051 "text", NAME_COLUMN
,
4053 gtk_tree_view_column_set_alignment (column
, 0.0);
4054 gtk_tree_view_append_column (GTK_TREE_VIEW (tree
), column
);
4055 gtk_tree_view_set_headers_visible(GTK_TREE_VIEW (tree
), FALSE
);
4057 scroll_win
= gtk_scrolled_window_new (NULL
, NULL
);
4058 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll_win
),
4059 GTK_POLICY_AUTOMATIC
,GTK_POLICY_AUTOMATIC
);
4060 gtk_container_add (GTK_CONTAINER (scroll_win
), tree
);
4062 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialogue
)->vbox
), scroll_win
,TRUE
, TRUE
,0);
4064 gtk_widget_show(scroll_win
);
4065 gtk_widget_show(tree
);
4067 nb_trace
= lttv_traceset_selector_trace_number(s
);
4068 for(i
=0;i
<nb_trace
;i
++){
4069 trace
= lttv_traceset_selector_trace_get(s
, i
);
4070 name
= lttv_trace_selector_get_name(trace
);
4071 gtk_tree_store_append (store
, &iter
, NULL
);
4072 checked
= lttv_trace_selector_get_selected(trace
);
4073 gtk_tree_store_set (store
, &iter
,
4074 CHECKBOX_COLUMN
,checked
,
4078 gtk_tree_store_append (store
, &child_iter
, &iter
);
4079 gtk_tree_store_set (store
, &child_iter
,
4080 CHECKBOX_COLUMN
, checked
,
4081 NAME_COLUMN
,"eventtype",
4084 nb_eventtype
= lttv_trace_selector_eventtype_number(trace
);
4085 for(j
=0;j
<nb_eventtype
;j
++){
4086 eventtype
= lttv_trace_selector_eventtype_get(trace
,j
);
4087 name
= lttv_eventtype_selector_get_name(eventtype
);
4088 checked
= lttv_eventtype_selector_get_selected(eventtype
);
4089 gtk_tree_store_append (store
, &child_iter1
, &child_iter
);
4090 gtk_tree_store_set (store
, &child_iter1
,
4091 CHECKBOX_COLUMN
, checked
,
4096 nb_tracefile
= lttv_trace_selector_tracefile_number(trace
);
4097 for(j
=0;j
<nb_tracefile
;j
++){
4098 tracefile
= lttv_trace_selector_tracefile_get(trace
, j
);
4099 name
= lttv_tracefile_selector_get_name(tracefile
);
4100 gtk_tree_store_append (store
, &child_iter
, &iter
);
4101 checked
= lttv_tracefile_selector_get_selected(tracefile
);
4102 gtk_tree_store_set (store
, &child_iter
,
4103 CHECKBOX_COLUMN
, checked
,
4107 gtk_tree_store_append (store
, &child_iter1
, &child_iter
);
4108 gtk_tree_store_set (store
, &child_iter1
,
4109 CHECKBOX_COLUMN
, checked
,
4110 NAME_COLUMN
,"eventtype",
4113 for(k
=0;k
<nb_eventtype
;k
++){
4114 eventtype
= lttv_tracefile_selector_eventtype_get(tracefile
,k
);
4115 name
= lttv_eventtype_selector_get_name(eventtype
);
4116 checked
= lttv_eventtype_selector_get_selected(eventtype
);
4117 gtk_tree_store_append (store
, &child_iter2
, &child_iter1
);
4118 gtk_tree_store_set (store
, &child_iter2
,
4119 CHECKBOX_COLUMN
, checked
,
4126 id
= gtk_dialog_run(GTK_DIALOG(dialogue
));
4128 case GTK_RESPONSE_ACCEPT
:
4129 case GTK_RESPONSE_OK
:
4130 update_filter(s
, store
);
4131 gtk_widget_destroy(dialogue
);
4133 case GTK_RESPONSE_REJECT
:
4134 case GTK_RESPONSE_CANCEL
:
4136 gtk_widget_destroy(dialogue
);
4143 /* Select a trace which will be removed from traceset
4146 char * get_remove_trace(char ** all_trace_name
, int nb_trace
)
4148 return get_selection(all_trace_name
, nb_trace
,
4149 "Select a trace", "Trace pathname");
4153 /* Select a module which will be loaded
4156 char * get_load_module(char ** load_module_name
, int nb_module
)
4158 return get_selection(load_module_name
, nb_module
,
4159 "Select a module to load", "Module name");
4165 /* Select a module which will be unloaded
4168 char * get_unload_module(char ** loaded_module_name
, int nb_module
)
4170 return get_selection(loaded_module_name
, nb_module
,
4171 "Select a module to unload", "Module name");
4175 /* Display a dialogue which shows all selectable items, let user to
4176 * select one of them
4179 char * get_selection(char ** loaded_module_name
, int nb_module
,
4180 char *title
, char * column_title
)
4182 GtkWidget
* dialogue
;
4183 GtkWidget
* scroll_win
;
4185 GtkListStore
* store
;
4186 GtkTreeViewColumn
* column
;
4187 GtkCellRenderer
* renderer
;
4188 GtkTreeSelection
* select
;
4191 char * unload_module_name
= NULL
;
4193 dialogue
= gtk_dialog_new_with_buttons(title
,
4196 GTK_STOCK_OK
,GTK_RESPONSE_ACCEPT
,
4197 GTK_STOCK_CANCEL
,GTK_RESPONSE_REJECT
,
4199 gtk_window_set_default_size((GtkWindow
*)dialogue
, 500, 200);
4201 scroll_win
= gtk_scrolled_window_new (NULL
, NULL
);
4202 gtk_widget_show ( scroll_win
);
4203 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll_win
),
4204 GTK_POLICY_AUTOMATIC
, GTK_POLICY_AUTOMATIC
);
4206 store
= gtk_list_store_new (N_COLUMNS
,G_TYPE_STRING
);
4207 tree
= gtk_tree_view_new_with_model(GTK_TREE_MODEL (store
));
4208 gtk_widget_show ( tree
);
4209 g_object_unref (G_OBJECT (store
));
4211 renderer
= gtk_cell_renderer_text_new ();
4212 column
= gtk_tree_view_column_new_with_attributes (column_title
,
4214 "text", MODULE_COLUMN
,
4216 gtk_tree_view_column_set_alignment (column
, 0.5);
4217 gtk_tree_view_column_set_fixed_width (column
, 150);
4218 gtk_tree_view_append_column (GTK_TREE_VIEW (tree
), column
);
4220 select
= gtk_tree_view_get_selection (GTK_TREE_VIEW (tree
));
4221 gtk_tree_selection_set_mode (select
, GTK_SELECTION_SINGLE
);
4223 gtk_container_add (GTK_CONTAINER (scroll_win
), tree
);
4225 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialogue
)->vbox
), scroll_win
,TRUE
, TRUE
,0);
4227 for(i
=0;i
<nb_module
;i
++){
4228 gtk_list_store_append (store
, &iter
);
4229 gtk_list_store_set (store
, &iter
, MODULE_COLUMN
,loaded_module_name
[i
],-1);
4232 id
= gtk_dialog_run(GTK_DIALOG(dialogue
));
4234 case GTK_RESPONSE_ACCEPT
:
4235 case GTK_RESPONSE_OK
:
4236 if (gtk_tree_selection_get_selected (select
, (GtkTreeModel
**)&store
, &iter
)){
4237 gtk_tree_model_get ((GtkTreeModel
*)store
, &iter
, MODULE_COLUMN
, &unload_module_name
, -1);
4239 case GTK_RESPONSE_REJECT
:
4240 case GTK_RESPONSE_CANCEL
:
4242 gtk_widget_destroy(dialogue
);
4246 return unload_module_name
;
4250 /* Insert all menu entry and tool buttons into this main window
4255 void add_all_menu_toolbar_constructors(MainWindow
* mw
, gpointer user_data
)
4259 lttvwindow_viewer_constructor constructor
;
4260 LttvMenus
* global_menu
, * instance_menu
;
4261 LttvToolbars
* global_toolbar
, * instance_toolbar
;
4262 LttvMenuClosure
*menu_item
;
4263 LttvToolbarClosure
*toolbar_item
;
4264 LttvAttributeValue value
;
4265 LttvIAttribute
*global_attributes
= LTTV_IATTRIBUTE(lttv_global_attributes());
4266 LttvIAttribute
*attributes
= mw
->attributes
;
4267 GtkWidget
* tool_menu_title_menu
, *new_widget
, *pixmap
;
4269 g_assert(lttv_iattribute_find_by_path(global_attributes
,
4270 "viewers/menu", LTTV_POINTER
, &value
));
4271 if(*(value
.v_pointer
) == NULL
)
4272 *(value
.v_pointer
) = lttv_menus_new();
4273 global_menu
= (LttvMenus
*)*(value
.v_pointer
);
4275 g_assert(lttv_iattribute_find_by_path(attributes
,
4276 "viewers/menu", LTTV_POINTER
, &value
));
4277 if(*(value
.v_pointer
) == NULL
)
4278 *(value
.v_pointer
) = lttv_menus_new();
4279 instance_menu
= (LttvMenus
*)*(value
.v_pointer
);
4283 g_assert(lttv_iattribute_find_by_path(global_attributes
,
4284 "viewers/toolbar", LTTV_POINTER
, &value
));
4285 if(*(value
.v_pointer
) == NULL
)
4286 *(value
.v_pointer
) = lttv_toolbars_new();
4287 global_toolbar
= (LttvToolbars
*)*(value
.v_pointer
);
4289 g_assert(lttv_iattribute_find_by_path(attributes
,
4290 "viewers/toolbar", LTTV_POINTER
, &value
));
4291 if(*(value
.v_pointer
) == NULL
)
4292 *(value
.v_pointer
) = lttv_toolbars_new();
4293 instance_toolbar
= (LttvToolbars
*)*(value
.v_pointer
);
4295 /* Add missing menu entries to window instance */
4296 for(i
=0;i
<global_menu
->len
;i
++) {
4297 menu_item
= &g_array_index(global_menu
, LttvMenuClosure
, i
);
4299 //add menu_item to window instance;
4300 constructor
= menu_item
->con
;
4301 tool_menu_title_menu
= lookup_widget(mw
->mwindow
,"ToolMenuTitle_menu");
4303 gtk_menu_item_new_with_mnemonic (menu_item
->menu_text
);
4304 gtk_container_add (GTK_CONTAINER (tool_menu_title_menu
),
4306 g_signal_connect ((gpointer
) new_widget
, "activate",
4307 G_CALLBACK (insert_viewer_wrap
),
4309 gtk_widget_show (new_widget
);
4310 lttv_menus_add(instance_menu
, menu_item
->con
,
4311 menu_item
->menu_path
,
4312 menu_item
->menu_text
,
4317 /* Add missing toolbar entries to window instance */
4318 for(i
=0;i
<global_toolbar
->len
;i
++) {
4319 toolbar_item
= &g_array_index(global_toolbar
, LttvToolbarClosure
, i
);
4321 //add toolbar_item to window instance;
4322 constructor
= toolbar_item
->con
;
4323 tool_menu_title_menu
= lookup_widget(mw
->mwindow
,"MToolbar1");
4324 pixbuf
= gdk_pixbuf_new_from_xpm_data((const char**)toolbar_item
->pixmap
);
4325 pixmap
= gtk_image_new_from_pixbuf(pixbuf
);
4327 gtk_toolbar_append_element (GTK_TOOLBAR (tool_menu_title_menu
),
4328 GTK_TOOLBAR_CHILD_BUTTON
,
4331 toolbar_item
->tooltip
, NULL
,
4332 pixmap
, NULL
, NULL
);
4333 gtk_label_set_use_underline(
4334 GTK_LABEL (((GtkToolbarChild
*) (
4335 g_list_last (GTK_TOOLBAR
4336 (tool_menu_title_menu
)->children
)->data
))->label
),
4338 gtk_container_set_border_width (GTK_CONTAINER (new_widget
), 1);
4339 g_signal_connect ((gpointer
) new_widget
,
4341 G_CALLBACK (insert_viewer_wrap
),
4343 gtk_widget_show (new_widget
);
4345 lttv_toolbars_add(instance_toolbar
, toolbar_item
->con
,
4346 toolbar_item
->tooltip
,
4347 toolbar_item
->pixmap
,
4355 /* Create a main window
4358 void construct_main_window(MainWindow
* parent
)
4360 g_debug("construct_main_window()");
4361 GtkWidget
* new_window
; /* New generated main window */
4362 MainWindow
* new_m_window
;/* New main window structure */
4363 GtkNotebook
* notebook
;
4364 LttvIAttribute
*attributes
=
4365 LTTV_IATTRIBUTE(g_object_new(LTTV_ATTRIBUTE_TYPE
, NULL
));
4366 LttvAttributeValue value
;
4369 new_m_window
= g_new(MainWindow
, 1);
4371 // Add the object's information to the module's array
4372 g_main_window_list
= g_slist_append(g_main_window_list
, new_m_window
);
4374 new_window
= create_MWindow();
4375 gtk_widget_show (new_window
);
4377 new_m_window
->mwindow
= new_window
;
4378 new_m_window
->attributes
= attributes
;
4380 g_assert(lttv_iattribute_find_by_path(attributes
,
4381 "viewers/menu", LTTV_POINTER
, &value
));
4382 *(value
.v_pointer
) = lttv_menus_new();
4384 g_assert(lttv_iattribute_find_by_path(attributes
,
4385 "viewers/toolbar", LTTV_POINTER
, &value
));
4386 *(value
.v_pointer
) = lttv_toolbars_new();
4388 add_all_menu_toolbar_constructors(new_m_window
, NULL
);
4390 g_object_set_data_full(G_OBJECT(new_window
),
4392 (gpointer
)new_m_window
,
4393 (GDestroyNotify
)g_free
);
4394 //create a default tab
4395 notebook
= (GtkNotebook
*)lookup_widget(new_m_window
->mwindow
, "MNotebook");
4396 if(notebook
== NULL
){
4397 g_printf("Notebook does not exist\n");
4400 //gtk_notebook_popup_enable (GTK_NOTEBOOK(notebook));
4401 //for now there is no name field in LttvTraceset structure
4402 //Use "Traceset" as the label for the default tab
4404 GtkWidget
* parent_notebook
= lookup_widget(parent
->mwindow
, "MNotebook");
4405 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(parent_notebook
),
4406 gtk_notebook_get_current_page(GTK_NOTEBOOK(parent_notebook
)));
4412 parent_tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
4414 new_tab
= create_tab(new_m_window
, parent_tab
, notebook
, "Traceset");
4416 new_tab
= create_tab(new_m_window
, NULL
, notebook
, "Traceset");
4417 /* First window, use command line trace */
4418 if(g_init_trace
!= NULL
){
4419 lttvwindow_add_trace(new_tab
,
4423 LttvTraceset
*traceset
= new_tab
->traceset_info
->traceset
;
4424 SetTraceset(new_tab
, traceset
);
4426 /* Insert default viewers */
4428 LttvAttributeType type
;
4429 LttvAttributeName name
;
4430 LttvAttributeValue value
;
4431 LttvAttribute
*attribute
;
4433 LttvIAttribute
*attributes_global
=
4434 LTTV_IATTRIBUTE(lttv_global_attributes());
4436 g_assert(attribute
=
4437 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
4438 LTTV_IATTRIBUTE(attributes_global
),
4439 LTTV_VIEWER_CONSTRUCTORS
)));
4441 name
= g_quark_from_string("guievents");
4442 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
4444 if(type
== LTTV_POINTER
) {
4445 lttvwindow_viewer_constructor viewer_constructor
=
4446 (lttvwindow_viewer_constructor
)*value
.v_pointer
;
4447 insert_viewer(new_window
, viewer_constructor
);
4450 name
= g_quark_from_string("guicontrolflow");
4451 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
4453 if(type
== LTTV_POINTER
) {
4454 lttvwindow_viewer_constructor viewer_constructor
=
4455 (lttvwindow_viewer_constructor
)*value
.v_pointer
;
4456 insert_viewer(new_window
, viewer_constructor
);
4459 name
= g_quark_from_string("guistatistics");
4460 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
4462 if(type
== LTTV_POINTER
) {
4463 lttvwindow_viewer_constructor viewer_constructor
=
4464 (lttvwindow_viewer_constructor
)*value
.v_pointer
;
4465 insert_viewer(new_window
, viewer_constructor
);
4471 g_printf("There are now : %d windows\n",g_slist_length(g_main_window_list
));
4475 /* Free the memory occupied by a tab structure
4479 void tab_destructor(Tab
* tab
)
4481 int i
, nb
, ref_count
;
4484 gtk_object_destroy(GTK_OBJECT(tab
->tooltips
));
4487 g_object_unref(tab
->attributes
);
4489 if(tab
->interrupted_state
)
4490 g_object_unref(tab
->interrupted_state
);
4493 if(tab
->traceset_info
->traceset_context
!= NULL
){
4494 //remove state update hooks
4495 lttv_state_remove_event_hooks(
4496 (LttvTracesetState
*)tab
->traceset_info
->
4498 lttv_context_fini(LTTV_TRACESET_CONTEXT(tab
->traceset_info
->
4500 g_object_unref(tab
->traceset_info
->traceset_context
);
4502 if(tab
->traceset_info
->traceset
!= NULL
) {
4503 nb
= lttv_traceset_number(tab
->traceset_info
->traceset
);
4504 for(i
= 0 ; i
< nb
; i
++) {
4505 trace
= lttv_traceset_get(tab
->traceset_info
->traceset
, i
);
4506 ref_count
= lttv_trace_get_ref_number(trace
);
4508 ltt_trace_close(lttv_trace(trace
));
4512 lttv_traceset_destroy(tab
->traceset_info
->traceset
);
4513 /* Remove the idle events requests processing function of the tab */
4514 g_idle_remove_by_data(tab
);
4516 g_slist_free(tab
->events_requests
);
4517 g_free(tab
->traceset_info
);
4522 /* Create a tab and insert it into the current main window
4525 Tab
* create_tab(MainWindow
* mw
, Tab
*copy_tab
,
4526 GtkNotebook
* notebook
, char * label
)
4532 //create a new tab data structure
4535 //construct and initialize the traceset_info
4536 tab
->traceset_info
= g_new(TracesetInfo
,1);
4539 tab
->traceset_info
->traceset
=
4540 lttv_traceset_copy(copy_tab
->traceset_info
->traceset
);
4542 tab
->traceset_info
->traceset
= lttv_traceset_new();
4546 lttv_attribute_write_xml(
4547 lttv_traceset_attribute(tab
->traceset_info
->traceset
),
4553 tab
->time_manager_lock
= FALSE
;
4554 tab
->current_time_manager_lock
= FALSE
;
4556 //FIXME copy not implemented in lower level
4557 tab
->traceset_info
->traceset_context
=
4558 g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
4559 g_assert(tab
->traceset_info
->traceset_context
!= NULL
);
4561 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
),
4562 tab
->traceset_info
->traceset
);
4563 //add state update hooks
4564 lttv_state_add_event_hooks(
4565 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
4567 //determine the current_time and time_window of the tab
4569 if(copy_tab
!= NULL
){
4570 tab
->time_window
= copy_tab
->time_window
;
4571 tab
->current_time
= copy_tab
->current_time
;
4573 tab
->time_window
.start_time
=
4574 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
4575 time_span
.start_time
;
4576 if(DEFAULT_TIME_WIDTH_S
<
4577 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
4578 time_span
.end_time
.tv_sec
)
4579 tmp_time
.tv_sec
= DEFAULT_TIME_WIDTH_S
;
4582 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
4583 time_span
.end_time
.tv_sec
;
4584 tmp_time
.tv_nsec
= 0;
4585 tab
->time_window
.time_width
= tmp_time
;
4586 tab
->current_time
.tv_sec
=
4587 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
4588 time_span
.start_time
.tv_sec
;
4589 tab
->current_time
.tv_nsec
=
4590 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
4591 time_span
.start_time
.tv_nsec
;
4594 tab
->attributes
= LTTV_IATTRIBUTE(g_object_new(LTTV_ATTRIBUTE_TYPE
, NULL
));
4595 tab
->interrupted_state
= g_object_new(LTTV_ATTRIBUTE_TYPE
, NULL
);
4597 tab
->vbox
= gtk_vbox_new(FALSE
, 2);
4598 tab
->viewer_container
= gtk_vbox_new(TRUE
, 2);
4599 tab
->scrollbar
= gtk_hscrollbar_new(NULL
);
4600 //tab->multivpaned = gtk_multi_vpaned_new();
4602 gtk_box_pack_start(GTK_BOX(tab
->vbox
),
4603 tab
->viewer_container
,
4605 TRUE
, /* Give the extra space to the child */
4606 0); /* No padding */
4608 /* Create the timebar */
4610 tab
->MTimebar
= gtk_hbox_new(FALSE
, 2);
4611 gtk_widget_show(tab
->MTimebar
);
4612 tab
->tooltips
= gtk_tooltips_new();
4614 tab
->MEventBox1a
= gtk_event_box_new();
4615 gtk_widget_show(tab
->MEventBox1a
);
4616 gtk_tooltips_set_tip(tab
->tooltips
, tab
->MEventBox1a
,
4617 "Paste Start and End Times Here", "");
4618 tab
->MText1a
= gtk_label_new("Time Frame ");
4619 gtk_widget_show(tab
->MText1a
);
4620 gtk_container_add(GTK_CONTAINER(tab
->MEventBox1a
), tab
->MText1a
);
4621 tab
->MEventBox1b
= gtk_event_box_new();
4622 gtk_widget_show(tab
->MEventBox1b
);
4623 gtk_tooltips_set_tip(tab
->tooltips
, tab
->MEventBox1b
,
4624 "Paste Start Time Here", "");
4625 tab
->MText1b
= gtk_label_new("start: ");
4626 gtk_widget_show(tab
->MText1b
);
4627 gtk_container_add(GTK_CONTAINER(tab
->MEventBox1b
), tab
->MText1b
);
4628 tab
->MText2
= gtk_label_new("s");
4629 gtk_widget_show(tab
->MText2
);
4630 tab
->MText3a
= gtk_label_new("ns");
4631 gtk_widget_show(tab
->MText3a
);
4632 tab
->MEventBox3b
= gtk_event_box_new();
4633 gtk_widget_show(tab
->MEventBox3b
);
4634 gtk_tooltips_set_tip(tab
->tooltips
, tab
->MEventBox3b
,
4635 "Paste End Time Here", "");
4636 tab
->MText3b
= gtk_label_new("end:");
4637 gtk_widget_show(tab
->MText3b
);
4638 gtk_container_add(GTK_CONTAINER(tab
->MEventBox3b
), tab
->MText3b
);
4639 tab
->MText4
= gtk_label_new("s");
4640 gtk_widget_show(tab
->MText4
);
4641 tab
->MText5a
= gtk_label_new("ns");
4642 gtk_widget_show(tab
->MText5a
);
4643 tab
->MEventBox5b
= gtk_event_box_new();
4644 gtk_widget_show(tab
->MEventBox5b
);
4645 gtk_tooltips_set_tip(tab
->tooltips
, tab
->MEventBox5b
,
4646 "Paste Current Time Here", "");
4647 tab
->MText5b
= gtk_label_new("Current Time:");
4648 gtk_widget_show(tab
->MText5b
);
4649 gtk_container_add(GTK_CONTAINER(tab
->MEventBox5b
), tab
->MText5b
);
4650 tab
->MText6
= gtk_label_new("s");
4651 gtk_widget_show(tab
->MText6
);
4652 tab
->MText7
= gtk_label_new("ns");
4653 gtk_widget_show(tab
->MText7
);
4655 tab
->MEntry1
= gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4656 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab
->MEntry1
),0);
4657 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab
->MEntry1
),TRUE
);
4658 gtk_widget_show(tab
->MEntry1
);
4659 tab
->MEntry2
= gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4660 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab
->MEntry2
),0);
4661 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab
->MEntry2
),TRUE
);
4662 gtk_widget_show(tab
->MEntry2
);
4663 tab
->MEntry3
= gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4664 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab
->MEntry3
),0);
4665 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab
->MEntry3
),TRUE
);
4666 gtk_widget_show(tab
->MEntry3
);
4667 tab
->MEntry4
= gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4668 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab
->MEntry4
),0);
4669 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab
->MEntry4
),TRUE
);
4670 gtk_widget_show(tab
->MEntry4
);
4671 tab
->MEntry5
= gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4672 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab
->MEntry5
),0);
4673 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab
->MEntry5
),TRUE
);
4674 gtk_widget_show(tab
->MEntry5
);
4675 tab
->MEntry6
= gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4676 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab
->MEntry6
),0);
4677 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab
->MEntry6
),TRUE
);
4678 gtk_widget_show(tab
->MEntry6
);
4681 GtkWidget
*temp_widget
;
4683 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEventBox1a
, FALSE
,
4685 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEventBox1b
, FALSE
,
4687 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEntry1
, FALSE
, FALSE
, 0);
4688 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MText2
, FALSE
, FALSE
, 0);
4689 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEntry2
, FALSE
, FALSE
, 0);
4690 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MText3a
, FALSE
, FALSE
, 0);
4691 temp_widget
= gtk_vseparator_new();
4692 gtk_widget_show(temp_widget
);
4693 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), temp_widget
, FALSE
, FALSE
, 0);
4694 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEventBox3b
, FALSE
,
4696 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEntry3
, FALSE
, FALSE
, 0);
4697 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MText4
, FALSE
, FALSE
, 0);
4698 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEntry4
, FALSE
, FALSE
, 0);
4699 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MText5a
, FALSE
, FALSE
, 0);
4700 temp_widget
= gtk_vseparator_new();
4701 gtk_widget_show(temp_widget
);
4702 gtk_box_pack_end (GTK_BOX (tab
->MTimebar
), tab
->MText7
, FALSE
, FALSE
, 0);
4703 gtk_box_pack_end (GTK_BOX (tab
->MTimebar
), tab
->MEntry6
, FALSE
, FALSE
, 0);
4704 gtk_box_pack_end (GTK_BOX (tab
->MTimebar
), tab
->MText6
, FALSE
, FALSE
, 0);
4705 gtk_box_pack_end (GTK_BOX (tab
->MTimebar
), tab
->MEntry5
, FALSE
, FALSE
, 0);
4706 gtk_box_pack_end (GTK_BOX (tab
->MTimebar
), tab
->MEventBox5b
, FALSE
,
4708 gtk_box_pack_end (GTK_BOX (tab
->MTimebar
), temp_widget
, FALSE
, FALSE
, 0);
4711 //GtkWidget *test = gtk_button_new_with_label("drop");
4712 //gtk_button_set_relief(GTK_BUTTON(test), GTK_RELIEF_NONE);
4713 //gtk_widget_show(test);
4714 //gtk_box_pack_end(GTK_BOX (tab->MTimebar), test, FALSE, FALSE, 0);
4715 //gtk_widget_add_events(tab->MText1, GDK_ALL_EVENTS_MASK);//GDK_BUTTON_PRESS_MASK);
4716 /*GtkWidget *event_box = gtk_event_box_new();
4717 gtk_widget_show(event_box);
4718 gtk_tooltips_set_tip(tooltips, event_box,
4719 "Paste Current Time Here", "");
4720 gtk_box_pack_end(GTK_BOX (tab->MTimebar), event_box, FALSE, FALSE, 0);
4721 GtkWidget *test = gtk_label_new("drop");
4722 gtk_container_add(GTK_CONTAINER(event_box), test);
4723 gtk_widget_show(test);
4724 g_signal_connect (G_OBJECT(event_box),
4725 "button-press-event",
4726 G_CALLBACK (on_MText1_paste),
4730 g_signal_connect (G_OBJECT(tab
->MEventBox1a
),
4731 "button-press-event",
4732 G_CALLBACK (on_MEventBox1a_paste
),
4735 g_signal_connect (G_OBJECT(tab
->MEventBox1b
),
4736 "button-press-event",
4737 G_CALLBACK (on_MEventBox1b_paste
),
4739 g_signal_connect (G_OBJECT(tab
->MEventBox3b
),
4740 "button-press-event",
4741 G_CALLBACK (on_MEventBox3b_paste
),
4743 g_signal_connect (G_OBJECT(tab
->MEventBox5b
),
4744 "button-press-event",
4745 G_CALLBACK (on_MEventBox5b_paste
),
4749 gtk_box_pack_end(GTK_BOX(tab
->vbox
),
4751 FALSE
, /* Do not expand */
4752 FALSE
, /* Fill has no effect here (expand false) */
4753 0); /* No padding */
4755 gtk_box_pack_end(GTK_BOX(tab
->vbox
),
4757 FALSE
, /* Do not expand */
4758 FALSE
, /* Fill has no effect here (expand false) */
4759 0); /* No padding */
4761 g_object_set_data(G_OBJECT(tab
->viewer_container
), "focused_viewer", NULL
);
4767 // Display a label with a X
4768 GtkWidget *w_hbox = gtk_hbox_new(FALSE, 4);
4769 GtkWidget *w_label = gtk_label_new (label);
4770 GtkWidget *pixmap = create_pixmap(GTK_WIDGET(notebook), "close.png");
4771 GtkWidget *w_button = gtk_button_new ();
4772 gtk_container_add(GTK_CONTAINER(w_button), pixmap);
4773 //GtkWidget *w_button = gtk_button_new_with_label("x");
4775 gtk_button_set_relief(GTK_BUTTON(w_button), GTK_RELIEF_NONE);
4777 gtk_box_pack_start(GTK_BOX(w_hbox), w_label, TRUE, TRUE, 0);
4778 gtk_box_pack_end(GTK_BOX(w_hbox), w_button, FALSE,
4781 g_signal_connect_swapped (w_button, "clicked",
4782 G_CALLBACK (on_close_tab_X_clicked),
4785 gtk_widget_set_state(w_button, GTK_STATE_ACTIVE);
4787 gtk_widget_show (w_label);
4788 gtk_widget_show (pixmap);
4789 gtk_widget_show (w_button);
4790 gtk_widget_show (w_hbox);
4792 tab->label = w_hbox;
4796 tab
->label
= gtk_label_new (label
);
4798 gtk_widget_show(tab
->label
);
4799 gtk_widget_show(tab
->scrollbar
);
4800 gtk_widget_show(tab
->viewer_container
);
4801 gtk_widget_show(tab
->vbox
);
4802 //gtk_widget_show(tab->multivpaned);
4805 /* Start with empty events requests list */
4806 tab
->events_requests
= NULL
;
4807 tab
->events_request_pending
= FALSE
;
4809 g_object_set_data_full(
4810 G_OBJECT(tab
->vbox
),
4813 (GDestroyNotify
)tab_destructor
);
4815 g_signal_connect(G_OBJECT(tab
->scrollbar
), "value-changed",
4816 G_CALLBACK(scroll_value_changed_cb
), tab
);
4818 g_signal_connect ((gpointer
) tab
->MEntry1
, "value-changed",
4819 G_CALLBACK (on_MEntry1_value_changed
),
4821 g_signal_connect ((gpointer
) tab
->MEntry2
, "value-changed",
4822 G_CALLBACK (on_MEntry2_value_changed
),
4824 g_signal_connect ((gpointer
) tab
->MEntry3
, "value-changed",
4825 G_CALLBACK (on_MEntry3_value_changed
),
4827 g_signal_connect ((gpointer
) tab
->MEntry4
, "value-changed",
4828 G_CALLBACK (on_MEntry4_value_changed
),
4830 g_signal_connect ((gpointer
) tab
->MEntry5
, "value-changed",
4831 G_CALLBACK (on_MEntry5_value_changed
),
4833 g_signal_connect ((gpointer
) tab
->MEntry6
, "value-changed",
4834 G_CALLBACK (on_MEntry6_value_changed
),
4837 //g_signal_connect(G_OBJECT(tab->scrollbar), "changed",
4838 // G_CALLBACK(scroll_value_changed_cb), tab);
4841 //insert tab into notebook
4842 gtk_notebook_append_page(notebook
,
4845 list
= gtk_container_get_children(GTK_CONTAINER(notebook
));
4846 gtk_notebook_set_current_page(notebook
,g_list_length(list
)-1);
4847 // always show : not if(g_list_length(list)>1)
4848 gtk_notebook_set_show_tabs(notebook
, TRUE
);
4854 * execute_events_requests
4856 * Idle function that executes the pending requests for a tab.
4858 * @return return value : TRUE : keep the idle function, FALSE : remove it.
4860 gboolean
execute_events_requests(Tab
*tab
)
4862 return ( lttvwindow_process_pending_requests(tab
) );