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(GTK_TREE_VIEW(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
)
406 insert_viewer((GtkWidget
*)menuitem
, (lttvwindow_viewer_constructor
)user_data
);
410 /* internal functions */
411 void insert_viewer(GtkWidget
* widget
, lttvwindow_viewer_constructor constructor
)
413 GtkWidget
* viewer_container
;
414 MainWindow
* mw_data
= get_window_data_struct(widget
);
415 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
417 LttvTracesetSelector
* s
;
418 TimeInterval
* time_interval
;
419 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
420 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
424 tab
= create_new_tab(widget
, NULL
);
426 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
429 viewer_container
= tab
->viewer_container
;
431 s
= construct_traceset_selector(tab
->traceset_info
->traceset
);
432 viewer
= (GtkWidget
*)constructor(tab
);
435 //gtk_multivpaned_widget_add(GTK_MULTIVPANED(multivpaned), viewer);
437 gtk_box_pack_end(GTK_BOX(viewer_container
),
443 /* We want to connect the viewer_grab_focus to EVERY
444 * child of this widget. The little trick is to get each child
445 * of each GTK_CONTAINER, even subchildren.
447 connect_focus_recursive(viewer
, viewer
);
452 * Function to set/update traceset for the viewers
453 * @param tab viewer's tab
454 * @param traceset traceset of the main window.
456 * 0 : traceset updated
457 * 1 : no traceset hooks to update; not an error.
460 int SetTraceset(Tab
* tab
, LttvTraceset
*traceset
)
462 LttvTracesetContext
*tsc
=
463 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
464 TimeInterval time_span
= tsc
->time_span
;
465 TimeWindow new_time_window
;
466 LttTime new_current_time
;
468 /* Set the tab's time window and current time if
470 if(ltt_time_compare(tab
->time_window
.start_time
, time_span
.start_time
) < 0
471 || ltt_time_compare(tab
->time_window
.end_time
,
472 time_span
.end_time
) > 0) {
473 new_time_window
.start_time
= time_span
.start_time
;
475 new_current_time
= time_span
.start_time
;
479 if(DEFAULT_TIME_WIDTH_S
< time_span
.end_time
.tv_sec
)
480 tmp_time
.tv_sec
= DEFAULT_TIME_WIDTH_S
;
482 tmp_time
.tv_sec
= time_span
.end_time
.tv_sec
;
483 tmp_time
.tv_nsec
= 0;
484 new_time_window
.time_width
= tmp_time
;
485 new_time_window
.time_width_double
= ltt_time_to_double(tmp_time
);
486 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
487 new_time_window
.time_width
) ;
489 time_change_manager(tab
, new_time_window
);
490 current_time_change_manager(tab
, new_current_time
);
494 GtkAdjustment
*adjustment
= gtk_range_get_adjustment(GTK_RANGE(tab
->scrollbar
));
495 LttTime upper
= ltt_time_sub(time_span
.end_time
, time_span
.start_time
);
497 g_object_set(G_OBJECT(adjustment
),
501 ltt_time_to_double(upper
)
502 * NANOSECONDS_PER_SECOND
, /* upper */
504 ltt_time_to_double(tab
->time_window
.time_width
)
505 / SCROLL_STEP_PER_PAGE
506 * NANOSECONDS_PER_SECOND
, /* step increment */
508 ltt_time_to_double(tab
->time_window
.time_width
)
509 * NANOSECONDS_PER_SECOND
, /* page increment */
511 ltt_time_to_double(tab
->time_window
.time_width
)
512 * NANOSECONDS_PER_SECOND
, /* page size */
514 gtk_adjustment_changed(adjustment
);
516 g_object_set(G_OBJECT(adjustment
),
519 ltt_time_sub(tab
->time_window
.start_time
, time_span
.start_time
))
520 * NANOSECONDS_PER_SECOND
, /* value */
522 gtk_adjustment_value_changed(adjustment
);
524 /* set the time bar. The value callbacks will change their nsec themself */
526 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry1
),
527 (double)time_span
.start_time
.tv_sec
,
528 (double)time_span
.end_time
.tv_sec
);
531 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry3
),
532 (double)time_span
.start_time
.tv_sec
,
533 (double)time_span
.end_time
.tv_sec
);
535 /* current seconds */
536 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry5
),
537 (double)time_span
.start_time
.tv_sec
,
538 (double)time_span
.end_time
.tv_sec
);
541 /* Finally, call the update hooks of the viewers */
543 LttvAttributeValue value
;
547 g_assert( lttv_iattribute_find_by_path(tab
->attributes
,
548 "hooks/updatetraceset", LTTV_POINTER
, &value
));
550 tmp
= (LttvHooks
*)*(value
.v_pointer
);
551 if(tmp
== NULL
) retval
= 1;
552 else lttv_hooks_call(tmp
,traceset
);
559 * Function to set/update filter for the viewers
560 * @param tab viewer's tab
561 * @param filter filter of the main window.
564 * 0 : filters updated
565 * 1 : no filter hooks to update; not an error.
568 int SetFilter(Tab
* tab
, gpointer filter
)
571 LttvAttributeValue value
;
573 g_assert(lttv_iattribute_find_by_path(tab
->attributes
,
574 "hooks/updatefilter", LTTV_POINTER
, &value
));
576 tmp
= (LttvHooks
*)*(value
.v_pointer
);
578 if(tmp
== NULL
) return 1;
579 lttv_hooks_call(tmp
,filter
);
587 * Function to redraw each viewer belonging to the current tab
588 * @param tab viewer's tab
591 void update_traceset(Tab
*tab
)
593 LttvAttributeValue value
;
595 g_assert(lttv_iattribute_find_by_path(tab
->attributes
,
596 "hooks/updatetraceset", LTTV_POINTER
, &value
));
597 tmp
= (LttvHooks
*)*(value
.v_pointer
);
598 if(tmp
== NULL
) return;
599 lttv_hooks_call(tmp
, NULL
);
603 /* get_label function is used to get user input, it displays an input
604 * box, which allows user to input a string
607 void get_label_string (GtkWidget
* text
, gchar
* label
)
609 GtkEntry
* entry
= (GtkEntry
*)text
;
610 if(strlen(gtk_entry_get_text(entry
))!=0)
611 strcpy(label
,gtk_entry_get_text(entry
));
614 gboolean
get_label(MainWindow
* mw
, gchar
* str
, gchar
* dialogue_title
, gchar
* label_str
)
616 GtkWidget
* dialogue
;
621 dialogue
= gtk_dialog_new_with_buttons(dialogue_title
,NULL
,
623 GTK_STOCK_OK
,GTK_RESPONSE_ACCEPT
,
624 GTK_STOCK_CANCEL
,GTK_RESPONSE_REJECT
,
627 label
= gtk_label_new(label_str
);
628 gtk_widget_show(label
);
630 text
= gtk_entry_new();
631 gtk_widget_show(text
);
633 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialogue
)->vbox
), label
,TRUE
, TRUE
,0);
634 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialogue
)->vbox
), text
,FALSE
, FALSE
,0);
636 id
= gtk_dialog_run(GTK_DIALOG(dialogue
));
638 case GTK_RESPONSE_ACCEPT
:
639 get_label_string(text
,str
);
640 gtk_widget_destroy(dialogue
);
642 case GTK_RESPONSE_REJECT
:
644 gtk_widget_destroy(dialogue
);
651 /* get_window_data_struct function is actually a lookup function,
652 * given a widget which is in the tree of the main window, it will
653 * return the MainWindow data structure associated with main window
656 MainWindow
* get_window_data_struct(GtkWidget
* widget
)
659 MainWindow
* mw_data
;
661 mw
= lookup_widget(widget
, "MWindow");
663 g_info("Main window does not exist\n");
667 mw_data
= (MainWindow
*) g_object_get_data(G_OBJECT(mw
),"main_window_data");
669 g_warning("Main window data does not exist\n");
676 /* create_new_window function, just constructs a new main window
679 void create_new_window(GtkWidget
* widget
, gpointer user_data
, gboolean clone
)
681 MainWindow
* parent
= get_window_data_struct(widget
);
684 g_info("Clone : use the same traceset\n");
685 construct_main_window(parent
);
687 g_info("Empty : traceset is set to NULL\n");
688 construct_main_window(NULL
);
692 /* Get the currently focused viewer.
693 * If no viewer is focused, use the first one.
695 * If no viewer available, return NULL.
697 GtkWidget
*viewer_container_focus(GtkWidget
*container
)
701 widget
= (GtkWidget
*)g_object_get_data(G_OBJECT(container
),
705 g_debug("no widget focused");
706 GList
*children
= gtk_container_get_children(GTK_CONTAINER(container
));
709 widget
= GTK_WIDGET(children
->data
);
710 g_object_set_data(G_OBJECT(container
),
720 gint
viewer_container_position(GtkWidget
*container
, GtkWidget
*child
)
723 if(child
== NULL
) return -1;
727 memset(&value
, 0, sizeof(GValue
));
728 g_value_init(&value
, G_TYPE_INT
);
729 gtk_container_child_get_property(GTK_CONTAINER(container
),
733 pos
= g_value_get_int(&value
);
739 /* move_*_viewer functions move the selected view up/down in
743 void move_down_viewer(GtkWidget
* widget
, gpointer user_data
)
745 MainWindow
* mw
= get_window_data_struct(widget
);
746 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
748 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
749 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
755 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
758 //gtk_multivpaned_widget_move_up(GTK_MULTIVPANED(tab->multivpaned));
760 /* change the position in the vbox */
761 GtkWidget
*focus_widget
;
763 focus_widget
= viewer_container_focus(tab
->viewer_container
);
764 position
= viewer_container_position(tab
->viewer_container
, focus_widget
);
767 /* can move up one position */
768 gtk_box_reorder_child(GTK_BOX(tab
->viewer_container
),
775 void move_up_viewer(GtkWidget
* widget
, gpointer user_data
)
777 MainWindow
* mw
= get_window_data_struct(widget
);
778 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
780 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
781 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
787 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
790 //gtk_multivpaned_widget_move_down(GTK_MULTIVPANED(tab->multivpaned));
791 /* change the position in the vbox */
792 GtkWidget
*focus_widget
;
794 focus_widget
= viewer_container_focus(tab
->viewer_container
);
795 position
= viewer_container_position(tab
->viewer_container
, focus_widget
);
799 g_list_length(gtk_container_get_children(
800 GTK_CONTAINER(tab
->viewer_container
)))-1
802 /* can move down one position */
803 gtk_box_reorder_child(GTK_BOX(tab
->viewer_container
),
811 /* delete_viewer deletes the selected viewer in the current tab
814 void delete_viewer(GtkWidget
* widget
, gpointer user_data
)
816 MainWindow
* mw
= get_window_data_struct(widget
);
817 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
819 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
820 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
826 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
829 //gtk_multivpaned_widget_delete(GTK_MULTIVPANED(tab->multivpaned));
831 GtkWidget
*focus_widget
= viewer_container_focus(tab
->viewer_container
);
833 if(focus_widget
!= NULL
)
834 gtk_widget_destroy(focus_widget
);
836 g_object_set_data(G_OBJECT(tab
->viewer_container
), "focused_viewer", NULL
);
840 /* open_traceset will open a traceset saved in a file
841 * Right now, it is not finished yet, (not working)
845 void open_traceset(GtkWidget
* widget
, gpointer user_data
)
849 LttvTraceset
* traceset
;
850 MainWindow
* mw_data
= get_window_data_struct(widget
);
851 GtkFileSelection
* file_selector
=
852 (GtkFileSelection
*)gtk_file_selection_new("Select a traceset");
854 gtk_file_selection_hide_fileop_buttons(file_selector
);
856 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
858 case GTK_RESPONSE_ACCEPT
:
859 case GTK_RESPONSE_OK
:
860 dir
= gtk_file_selection_get_selections (file_selector
);
861 traceset
= lttv_traceset_load(dir
[0]);
862 g_info("Open a trace set %s\n", dir
[0]);
865 case GTK_RESPONSE_REJECT
:
866 case GTK_RESPONSE_CANCEL
:
868 gtk_widget_destroy((GtkWidget
*)file_selector
);
874 static void events_request_free(EventsRequest
*events_request
)
876 if(events_request
== NULL
) return;
878 if(events_request
->start_position
!= NULL
)
879 lttv_traceset_context_position_destroy(events_request
->start_position
);
880 if(events_request
->end_position
!= NULL
)
881 lttv_traceset_context_position_destroy(events_request
->end_position
);
882 if(events_request
->hooks
!= NULL
)
883 g_array_free(events_request
->hooks
, TRUE
);
884 if(events_request
->before_chunk_traceset
!= NULL
)
885 lttv_hooks_destroy(events_request
->before_chunk_traceset
);
886 if(events_request
->before_chunk_trace
!= NULL
)
887 lttv_hooks_destroy(events_request
->before_chunk_trace
);
888 if(events_request
->before_chunk_tracefile
!= NULL
)
889 lttv_hooks_destroy(events_request
->before_chunk_tracefile
);
890 if(events_request
->event
!= NULL
)
891 lttv_hooks_destroy(events_request
->event
);
892 if(events_request
->event_by_id
!= NULL
)
893 lttv_hooks_by_id_destroy(events_request
->event_by_id
);
894 if(events_request
->after_chunk_tracefile
!= NULL
)
895 lttv_hooks_destroy(events_request
->after_chunk_tracefile
);
896 if(events_request
->after_chunk_trace
!= NULL
)
897 lttv_hooks_destroy(events_request
->after_chunk_trace
);
898 if(events_request
->after_chunk_traceset
!= NULL
)
899 lttv_hooks_destroy(events_request
->after_chunk_traceset
);
900 if(events_request
->before_request
!= NULL
)
901 lttv_hooks_destroy(events_request
->before_request
);
902 if(events_request
->after_request
!= NULL
)
903 lttv_hooks_destroy(events_request
->after_request
);
905 g_free(events_request
);
910 /* lttvwindow_process_pending_requests
912 * This internal function gets called by g_idle, taking care of the pending
913 * requests. It is responsible for concatenation of time intervals and position
914 * requests. It does it with the following algorithm organizing process traceset
915 * calls. Here is the detailed description of the way it works :
917 * - Events Requests Servicing Algorithm
919 * Data structures necessary :
921 * List of requests added to context : list_in
922 * List of requests not added to context : list_out
927 * list_out : many events requests
929 * FIXME : insert rest of algorithm here
933 #define list_out tab->events_requests
935 gboolean
lttvwindow_process_pending_requests(Tab
*tab
)
938 LttvTracesetContext
*tsc
;
939 LttvTracefileContext
*tfc
;
940 GSList
*list_in
= NULL
;
944 LttvTracesetContextPosition
*end_position
;
947 g_critical("Foreground processing : tab does not exist. Processing removed.");
951 /* There is no events requests pending : we should never have been called! */
952 g_assert(g_slist_length(list_out
) != 0);
954 tsc
= LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
956 //set the cursor to be X shape, indicating that the computer is busy in doing its job
958 new = gdk_cursor_new(GDK_X_CURSOR
);
959 widget
= lookup_widget(tab
->mw
->mwindow
, "MToolbar1");
960 win
= gtk_widget_get_parent_window(widget
);
961 gdk_window_set_cursor(win
, new);
962 gdk_cursor_unref(new);
963 gdk_window_stick(win
);
964 gdk_window_unstick(win
);
967 g_debug("SIZE events req len : %d", g_slist_length(list_out
));
969 /* Preliminary check for no trace in traceset */
970 /* Unregister the routine if empty, empty list_out too */
971 if(lttv_traceset_number(tsc
->ts
) == 0) {
973 /* - For each req in list_out */
974 GSList
*iter
= list_out
;
976 while(iter
!= NULL
) {
978 gboolean remove
= FALSE
;
979 gboolean free_data
= FALSE
;
980 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
982 /* - Call end request for req */
983 if(events_request
->servicing
== TRUE
)
984 lttv_hooks_call(events_request
->after_request
, (gpointer
)tsc
);
986 /* - remove req from list_out */
987 /* Destroy the request */
994 GSList
*remove_iter
= iter
;
996 iter
= g_slist_next(iter
);
997 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
998 list_out
= g_slist_remove_link(list_out
, remove_iter
);
999 } else { // not remove
1000 iter
= g_slist_next(iter
);
1005 /* 0.1 Lock Traces */
1010 iter_trace
<lttv_traceset_number(tsc
->ts
);
1012 LttvTrace
*trace_v
= lttv_traceset_get(tsc
->ts
, iter_trace
);
1014 if(lttvwindowtraces_lock(trace_v
) != 0) {
1015 g_critical("Foreground processing : Unable to get trace lock");
1016 return TRUE
; /* Cannot get lock, try later */
1021 /* 0.2 Seek tracefiles positions to context position */
1022 lttv_process_traceset_synchronize_tracefiles(tsc
);
1025 /* Events processing algorithm implementation */
1026 /* Warning : the gtk_events_pending takes a LOT of cpu time. So what we do
1027 * instead is to leave the control to GTK and take it back.
1029 /* A. Servicing loop */
1030 //while( (g_slist_length(list_in) != 0 || g_slist_length(list_out) != 0)) {
1031 if((g_slist_length(list_in
) != 0 || g_slist_length(list_out
) != 0)) {
1033 /* 1. If list_in is empty (need a seek) */
1034 if( g_slist_length(list_in
) == 0 ) {
1036 /* list in is empty, need a seek */
1038 /* 1.1 Add requests to list_in */
1039 GSList
*ltime
= NULL
;
1040 GSList
*lpos
= NULL
;
1041 GSList
*iter
= NULL
;
1043 /* 1.1.1 Find all time requests with the lowest start time in list_out
1046 if(g_slist_length(list_out
) > 0)
1047 ltime
= g_slist_append(ltime
, g_slist_nth_data(list_out
, 0));
1048 for(iter
=g_slist_nth(list_out
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
1049 /* Find all time requests with the lowest start time in list_out */
1050 EventsRequest
*event_request_ltime
= (EventsRequest
*)g_slist_nth_data(ltime
, 0);
1051 EventsRequest
*event_request_list_out
= (EventsRequest
*)iter
->data
;
1054 comp
= ltt_time_compare(event_request_ltime
->start_time
,
1055 event_request_list_out
->start_time
);
1057 ltime
= g_slist_append(ltime
, event_request_list_out
);
1059 /* Remove all elements from ltime, and add current */
1060 while(ltime
!= NULL
)
1061 ltime
= g_slist_delete_link(ltime
, g_slist_nth(ltime
, 0));
1062 ltime
= g_slist_append(ltime
, event_request_list_out
);
1066 /* 1.1.2 Find all position requests with the lowest position in list_out
1069 if(g_slist_length(list_out
) > 0)
1070 lpos
= g_slist_append(lpos
, g_slist_nth_data(list_out
, 0));
1071 for(iter
=g_slist_nth(list_out
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
1072 /* Find all position requests with the lowest position in list_out */
1073 EventsRequest
*event_request_lpos
= (EventsRequest
*)g_slist_nth_data(lpos
, 0);
1074 EventsRequest
*event_request_list_out
= (EventsRequest
*)iter
->data
;
1077 if(event_request_lpos
->start_position
!= NULL
1078 && event_request_list_out
->start_position
!= NULL
)
1080 comp
= lttv_traceset_context_pos_pos_compare
1081 (event_request_lpos
->start_position
,
1082 event_request_list_out
->start_position
);
1087 lpos
= g_slist_append(lpos
, event_request_list_out
);
1089 /* Remove all elements from lpos, and add current */
1091 lpos
= g_slist_delete_link(lpos
, g_slist_nth(lpos
, 0));
1092 lpos
= g_slist_append(lpos
, event_request_list_out
);
1097 EventsRequest
*event_request_lpos
= (EventsRequest
*)g_slist_nth_data(lpos
, 0);
1098 EventsRequest
*event_request_ltime
= (EventsRequest
*)g_slist_nth_data(ltime
, 0);
1099 LttTime lpos_start_time
;
1101 if(event_request_lpos
!= NULL
1102 && event_request_lpos
->start_position
!= NULL
) {
1103 lpos_start_time
= lttv_traceset_context_position_get_time(
1104 event_request_lpos
->start_position
);
1107 /* 1.1.3 If lpos.start time < ltime */
1108 if(event_request_lpos
!= NULL
1109 && event_request_lpos
->start_position
!= NULL
1110 && ltt_time_compare(lpos_start_time
,
1111 event_request_ltime
->start_time
)<0) {
1112 /* Add lpos to list_in, remove them from list_out */
1113 for(iter
=lpos
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
1114 /* Add to list_in */
1115 EventsRequest
*event_request_lpos
=
1116 (EventsRequest
*)iter
->data
;
1118 list_in
= g_slist_append(list_in
, event_request_lpos
);
1119 /* Remove from list_out */
1120 list_out
= g_slist_remove(list_out
, event_request_lpos
);
1123 /* 1.1.4 (lpos.start time >= ltime) */
1124 /* Add ltime to list_in, remove them from list_out */
1126 for(iter
=ltime
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
1127 /* Add to list_in */
1128 EventsRequest
*event_request_ltime
=
1129 (EventsRequest
*)iter
->data
;
1131 list_in
= g_slist_append(list_in
, event_request_ltime
);
1132 /* Remove from list_out */
1133 list_out
= g_slist_remove(list_out
, event_request_ltime
);
1138 g_slist_free(ltime
);
1143 tfc
= lttv_traceset_context_get_current_tfc(tsc
);
1144 g_assert(g_slist_length(list_in
)>0);
1145 EventsRequest
*events_request
= g_slist_nth_data(list_in
, 0);
1148 /* 1.2.1 If first request in list_in is a time request */
1149 if(events_request
->start_position
== NULL
) {
1150 /* - If first req in list_in start time != current time */
1151 if(tfc
== NULL
|| ltt_time_compare(events_request
->start_time
,
1152 tfc
->timestamp
) != 0)
1153 /* - Seek to that time */
1154 g_debug("SEEK TIME : %lu, %lu", events_request
->start_time
.tv_sec
,
1155 events_request
->start_time
.tv_nsec
);
1156 //lttv_process_traceset_seek_time(tsc, events_request->start_time);
1157 lttv_state_traceset_seek_time_closest(LTTV_TRACESET_STATE(tsc
),
1158 events_request
->start_time
);
1160 /* Process the traceset with only state hooks */
1162 lttv_process_traceset_middle(tsc
,
1163 events_request
->start_time
,
1169 /* Else, the first request in list_in is a position request */
1170 /* If first req in list_in pos != current pos */
1171 g_assert(events_request
->start_position
!= NULL
);
1172 g_debug("SEEK POS time : %lu, %lu",
1173 lttv_traceset_context_position_get_time(
1174 events_request
->start_position
).tv_sec
,
1175 lttv_traceset_context_position_get_time(
1176 events_request
->start_position
).tv_nsec
);
1178 g_debug("SEEK POS context time : %lu, %lu",
1179 lttv_traceset_context_get_current_tfc(tsc
)->timestamp
.tv_sec
,
1180 lttv_traceset_context_get_current_tfc(tsc
)->timestamp
.tv_nsec
);
1181 g_assert(events_request
->start_position
!= NULL
);
1182 if(lttv_traceset_context_ctx_pos_compare(tsc
,
1183 events_request
->start_position
) != 0) {
1184 /* 1.2.2.1 Seek to that position */
1185 g_debug("SEEK POSITION");
1186 //lttv_process_traceset_seek_position(tsc, events_request->start_position);
1187 pos_time
= lttv_traceset_context_position_get_time(
1188 events_request
->start_position
);
1190 lttv_state_traceset_seek_time_closest(LTTV_TRACESET_STATE(tsc
),
1193 /* Process the traceset with only state hooks */
1195 lttv_process_traceset_middle(tsc
,
1198 events_request
->start_position
);
1199 g_assert(lttv_traceset_context_ctx_pos_compare(tsc
,
1200 events_request
->start_position
) == 0);
1207 /* 1.3 Add hooks and call before request for all list_in members */
1209 GSList
*iter
= NULL
;
1211 for(iter
=list_in
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
1212 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1213 /* 1.3.1 If !servicing */
1214 if(events_request
->servicing
== FALSE
) {
1215 /* - begin request hooks called
1216 * - servicing = TRUE
1218 lttv_hooks_call(events_request
->before_request
, (gpointer
)tsc
);
1219 events_request
->servicing
= TRUE
;
1221 /* 1.3.2 call before chunk
1222 * 1.3.3 events hooks added
1224 if(events_request
->trace
== -1)
1225 lttv_process_traceset_begin(tsc
,
1226 events_request
->before_chunk_traceset
,
1227 events_request
->before_chunk_trace
,
1228 events_request
->before_chunk_tracefile
,
1229 events_request
->event
,
1230 events_request
->event_by_id
);
1232 guint nb_trace
= lttv_traceset_number(tsc
->ts
);
1233 g_assert((guint
)events_request
->trace
< nb_trace
&&
1234 events_request
->trace
> -1);
1235 LttvTraceContext
*tc
= tsc
->traces
[events_request
->trace
];
1237 lttv_hooks_call(events_request
->before_chunk_traceset
, tsc
);
1239 lttv_trace_context_add_hooks(tc
,
1240 events_request
->before_chunk_trace
,
1241 events_request
->before_chunk_tracefile
,
1242 events_request
->event
,
1243 events_request
->event_by_id
);
1248 /* 2. Else, list_in is not empty, we continue a read */
1251 /* 2.0 For each req of list_in */
1252 GSList
*iter
= list_in
;
1254 while(iter
!= NULL
) {
1256 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1258 /* - Call before chunk
1259 * - events hooks added
1261 if(events_request
->trace
== -1)
1262 lttv_process_traceset_begin(tsc
,
1263 events_request
->before_chunk_traceset
,
1264 events_request
->before_chunk_trace
,
1265 events_request
->before_chunk_tracefile
,
1266 events_request
->event
,
1267 events_request
->event_by_id
);
1269 guint nb_trace
= lttv_traceset_number(tsc
->ts
);
1270 g_assert((guint
)events_request
->trace
< nb_trace
&&
1271 events_request
->trace
> -1);
1272 LttvTraceContext
*tc
= tsc
->traces
[events_request
->trace
];
1274 lttv_hooks_call(events_request
->before_chunk_traceset
, tsc
);
1276 lttv_trace_context_add_hooks(tc
,
1277 events_request
->before_chunk_trace
,
1278 events_request
->before_chunk_tracefile
,
1279 events_request
->event
,
1280 events_request
->event_by_id
);
1283 iter
= g_slist_next(iter
);
1288 tfc
= lttv_traceset_context_get_current_tfc(tsc
);
1290 /* 2.1 For each req of list_out */
1291 GSList
*iter
= list_out
;
1293 while(iter
!= NULL
) {
1295 gboolean remove
= FALSE
;
1296 gboolean free_data
= FALSE
;
1297 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1299 /* if req.start time == current context time
1300 * or req.start position == current position*/
1301 if( ltt_time_compare(events_request
->start_time
,
1302 tfc
->timestamp
) == 0
1304 (events_request
->start_position
!= NULL
1306 lttv_traceset_context_ctx_pos_compare(tsc
,
1307 events_request
->start_position
) == 0)
1309 /* - Add to list_in, remove from list_out */
1310 list_in
= g_slist_append(list_in
, events_request
);
1314 /* - If !servicing */
1315 if(events_request
->servicing
== FALSE
) {
1316 /* - begin request hooks called
1317 * - servicing = TRUE
1319 lttv_hooks_call(events_request
->before_request
, (gpointer
)tsc
);
1320 events_request
->servicing
= TRUE
;
1322 /* call before chunk
1323 * events hooks added
1325 if(events_request
->trace
== -1)
1326 lttv_process_traceset_begin(tsc
,
1327 events_request
->before_chunk_traceset
,
1328 events_request
->before_chunk_trace
,
1329 events_request
->before_chunk_tracefile
,
1330 events_request
->event
,
1331 events_request
->event_by_id
);
1333 guint nb_trace
= lttv_traceset_number(tsc
->ts
);
1334 g_assert((guint
)events_request
->trace
< nb_trace
&&
1335 events_request
->trace
> -1);
1336 LttvTraceContext
*tc
= tsc
->traces
[events_request
->trace
];
1338 lttv_hooks_call(events_request
->before_chunk_traceset
, tsc
);
1340 lttv_trace_context_add_hooks(tc
,
1341 events_request
->before_chunk_trace
,
1342 events_request
->before_chunk_tracefile
,
1343 events_request
->event
,
1344 events_request
->event_by_id
);
1353 GSList
*remove_iter
= iter
;
1355 iter
= g_slist_next(iter
);
1356 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
1357 list_out
= g_slist_remove_link(list_out
, remove_iter
);
1358 } else { // not remove
1359 iter
= g_slist_next(iter
);
1365 /* 3. Find end criterions */
1370 /* 3.1.1 Find lowest end time in list_in */
1371 g_assert(g_slist_length(list_in
)>0);
1372 end_time
= ((EventsRequest
*)g_slist_nth_data(list_in
,0))->end_time
;
1374 for(iter
=g_slist_nth(list_in
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
1375 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1377 if(ltt_time_compare(events_request
->end_time
,
1379 end_time
= events_request
->end_time
;
1382 /* 3.1.2 Find lowest start time in list_out */
1383 for(iter
=list_out
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
1384 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1386 if(ltt_time_compare(events_request
->start_time
,
1388 end_time
= events_request
->start_time
;
1393 /* 3.2 Number of events */
1395 /* 3.2.1 Find lowest number of events in list_in */
1398 end_nb_events
= ((EventsRequest
*)g_slist_nth_data(list_in
,0))->num_events
;
1400 for(iter
=g_slist_nth(list_in
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
1401 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1403 if(events_request
->num_events
< end_nb_events
)
1404 end_nb_events
= events_request
->num_events
;
1407 /* 3.2.2 Use min(CHUNK_NUM_EVENTS, min num events in list_in) as
1410 end_nb_events
= MIN(CHUNK_NUM_EVENTS
, end_nb_events
);
1414 /* 3.3 End position */
1416 /* 3.3.1 Find lowest end position in list_in */
1419 end_position
=((EventsRequest
*)g_slist_nth_data(list_in
,0))->end_position
;
1421 for(iter
=g_slist_nth(list_in
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
1422 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1424 if(events_request
->end_position
!= NULL
&& end_position
!= NULL
&&
1425 lttv_traceset_context_pos_pos_compare(events_request
->end_position
,
1427 end_position
= events_request
->end_position
;
1432 /* 3.3.2 Find lowest start position in list_out */
1435 for(iter
=list_out
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
1436 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1438 if(events_request
->end_position
!= NULL
&& end_position
!= NULL
&&
1439 lttv_traceset_context_pos_pos_compare(events_request
->end_position
,
1441 end_position
= events_request
->end_position
;
1446 /* 4. Call process traceset middle */
1447 g_debug("Calling process traceset middle with %p, %lu sec %lu nsec, %u nb ev, %p end pos", tsc
, end_time
.tv_sec
, end_time
.tv_nsec
, end_nb_events
, end_position
);
1448 count
= lttv_process_traceset_middle(tsc
, end_time
, end_nb_events
, end_position
);
1450 tfc
= lttv_traceset_context_get_current_tfc(tsc
);
1452 g_debug("Context time after middle : %lu, %lu", tfc
->timestamp
.tv_sec
,
1453 tfc
->timestamp
.tv_nsec
);
1455 g_debug("End of trace reached after middle.");
1459 /* 5. After process traceset middle */
1460 tfc
= lttv_traceset_context_get_current_tfc(tsc
);
1462 /* - if current context time > traceset.end time */
1463 if(tfc
== NULL
|| ltt_time_compare(tfc
->timestamp
,
1464 tsc
->time_span
.end_time
) > 0) {
1465 /* - For each req in list_in */
1466 GSList
*iter
= list_in
;
1468 while(iter
!= NULL
) {
1470 gboolean remove
= FALSE
;
1471 gboolean free_data
= FALSE
;
1472 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1474 /* - Remove events hooks for req
1475 * - Call end chunk for req
1478 if(events_request
->trace
== -1)
1479 lttv_process_traceset_end(tsc
,
1480 events_request
->after_chunk_traceset
,
1481 events_request
->after_chunk_trace
,
1482 events_request
->after_chunk_tracefile
,
1483 events_request
->event
,
1484 events_request
->event_by_id
);
1487 guint nb_trace
= lttv_traceset_number(tsc
->ts
);
1488 g_assert(events_request
->trace
< nb_trace
&&
1489 events_request
->trace
> -1);
1490 LttvTraceContext
*tc
= tsc
->traces
[events_request
->trace
];
1492 lttv_trace_context_remove_hooks(tc
,
1493 events_request
->after_chunk_trace
,
1494 events_request
->after_chunk_tracefile
,
1495 events_request
->event
,
1496 events_request
->event_by_id
);
1497 lttv_hooks_call(events_request
->after_chunk_traceset
, tsc
);
1502 /* - Call end request for req */
1503 lttv_hooks_call(events_request
->after_request
, (gpointer
)tsc
);
1505 /* - remove req from list_in */
1506 /* Destroy the request */
1513 GSList
*remove_iter
= iter
;
1515 iter
= g_slist_next(iter
);
1516 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
1517 list_in
= g_slist_remove_link(list_in
, remove_iter
);
1518 } else { // not remove
1519 iter
= g_slist_next(iter
);
1524 /* 5.1 For each req in list_in */
1525 GSList
*iter
= list_in
;
1527 while(iter
!= NULL
) {
1529 gboolean remove
= FALSE
;
1530 gboolean free_data
= FALSE
;
1531 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1533 /* - Remove events hooks for req
1534 * - Call end chunk for req
1536 if(events_request
->trace
== -1)
1537 lttv_process_traceset_end(tsc
,
1538 events_request
->after_chunk_traceset
,
1539 events_request
->after_chunk_trace
,
1540 events_request
->after_chunk_tracefile
,
1541 events_request
->event
,
1542 events_request
->event_by_id
);
1545 guint nb_trace
= lttv_traceset_number(tsc
->ts
);
1546 g_assert(events_request
->trace
< nb_trace
&&
1547 events_request
->trace
> -1);
1548 LttvTraceContext
*tc
= tsc
->traces
[events_request
->trace
];
1550 lttv_trace_context_remove_hooks(tc
,
1551 events_request
->after_chunk_trace
,
1552 events_request
->after_chunk_tracefile
,
1553 events_request
->event
,
1554 events_request
->event_by_id
);
1556 lttv_hooks_call(events_request
->after_chunk_traceset
, tsc
);
1559 /* - req.num -= count */
1560 g_assert(events_request
->num_events
>= count
);
1561 events_request
->num_events
-= count
;
1563 g_assert(tfc
!= NULL
);
1564 /* - if req.num == 0
1566 * current context time >= req.end time
1568 * req.end pos == current pos
1570 * req.stop_flag == TRUE
1572 if( events_request
->num_events
== 0
1574 events_request
->stop_flag
== TRUE
1576 ltt_time_compare(tfc
->timestamp
,
1577 events_request
->end_time
) >= 0
1579 (events_request
->end_position
!= NULL
1581 lttv_traceset_context_ctx_pos_compare(tsc
,
1582 events_request
->end_position
) == 0)
1585 g_assert(events_request
->servicing
== TRUE
);
1586 /* - Call end request for req
1587 * - remove req from list_in */
1588 lttv_hooks_call(events_request
->after_request
, (gpointer
)tsc
);
1589 /* - remove req from list_in */
1590 /* Destroy the request */
1598 GSList
*remove_iter
= iter
;
1600 iter
= g_slist_next(iter
);
1601 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
1602 list_in
= g_slist_remove_link(list_in
, remove_iter
);
1603 } else { // not remove
1604 iter
= g_slist_next(iter
);
1610 /* End of removed servicing loop : leave control to GTK instead. */
1611 // if(gtk_events_pending()) break;
1614 /* B. When interrupted between chunks */
1617 GSList
*iter
= list_in
;
1619 /* 1. for each request in list_in */
1620 while(iter
!= NULL
) {
1622 gboolean remove
= FALSE
;
1623 gboolean free_data
= FALSE
;
1624 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1626 /* 1.1. Use current postition as start position */
1627 if(events_request
->start_position
!= NULL
)
1628 lttv_traceset_context_position_destroy(events_request
->start_position
);
1629 events_request
->start_position
= lttv_traceset_context_position_new();
1630 lttv_traceset_context_position_save(tsc
, events_request
->start_position
);
1632 /* 1.2. Remove start time */
1633 events_request
->start_time
= ltt_time_infinite
;
1635 /* 1.3. Move from list_in to list_out */
1638 list_out
= g_slist_append(list_out
, events_request
);
1643 GSList
*remove_iter
= iter
;
1645 iter
= g_slist_next(iter
);
1646 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
1647 list_in
= g_slist_remove_link(list_in
, remove_iter
);
1648 } else { // not remove
1649 iter
= g_slist_next(iter
);
1656 /* C Unlock Traces */
1658 //lttv_process_traceset_get_sync_data(tsc);
1663 iter_trace
<lttv_traceset_number(tsc
->ts
);
1665 LttvTrace
*trace_v
= lttv_traceset_get(tsc
->ts
, iter_trace
);
1667 lttvwindowtraces_unlock(trace_v
);
1672 //set the cursor back to normal
1673 gdk_window_set_cursor(win
, NULL
);
1676 g_assert(g_slist_length(list_in
) == 0);
1678 if( g_slist_length(list_out
) == 0 ) {
1679 /* Put tab's request pending flag back to normal */
1680 tab
->events_request_pending
= FALSE
;
1681 g_debug("remove the idle fct");
1682 return FALSE
; /* Remove the idle function */
1684 g_debug("leave the idle fct");
1685 return TRUE
; /* Leave the idle function */
1687 /* We do not use simili-round-robin, it may require to read 1 meg buffers
1688 * again and again if many tracesets use the same tracefiles. */
1689 /* Hack for round-robin idle functions */
1690 /* It will put the idle function at the end of the pool */
1691 /*g_idle_add_full((G_PRIORITY_HIGH_IDLE + 21),
1692 (GSourceFunc)execute_events_requests,
1702 /* add_trace_into_traceset_selector, each instance of a viewer has an associated
1703 * selector (filter), when a trace is added into traceset, the selector should
1704 * reflect the change. The function is used to update the selector
1707 void add_trace_into_traceset_selector(GtkWidget
* paned
, LttTrace
* t
)
1709 int j
, k
, m
, nb_tracefile
, nb_control
, nb_per_cpu
, nb_facility
, nb_event
;
1710 LttvTracesetSelector
* s
;
1711 LttvTraceSelector
* trace
;
1712 LttvTracefileSelector
* tracefile
;
1713 LttvEventtypeSelector
* eventtype
;
1719 w
= gtk_multivpaned_get_first_widget(GTK_MULTIVPANED(paned
));
1721 s
= g_object_get_data(G_OBJECT(w
), "Traceset_Selector");
1724 trace
= lttv_trace_selector_new(t
);
1725 lttv_traceset_selector_trace_add(s
, trace
);
1727 nb_facility
= ltt_trace_facility_number(t
);
1728 for(k
=0;k
<nb_facility
;k
++){
1729 fac
= ltt_trace_facility_get(t
,k
);
1730 nb_event
= (int) ltt_facility_eventtype_number(fac
);
1731 for(m
=0;m
<nb_event
;m
++){
1732 et
= ltt_facility_eventtype_get(fac
,m
);
1733 eventtype
= lttv_eventtype_selector_new(et
);
1734 lttv_trace_selector_eventtype_add(trace
, eventtype
);
1738 nb_control
= ltt_trace_control_tracefile_number(t
);
1739 nb_per_cpu
= ltt_trace_per_cpu_tracefile_number(t
);
1740 nb_tracefile
= nb_control
+ nb_per_cpu
;
1742 for(j
= 0 ; j
< nb_tracefile
; j
++) {
1744 tf
= ltt_trace_control_tracefile_get(t
, j
);
1746 tf
= ltt_trace_per_cpu_tracefile_get(t
, j
- nb_control
);
1747 tracefile
= lttv_tracefile_selector_new(tf
);
1748 lttv_trace_selector_tracefile_add(trace
, tracefile
);
1749 lttv_eventtype_selector_copy(trace
, tracefile
);
1751 }else g_warning("Module does not support filtering\n");
1753 w
= gtk_multivpaned_get_next_widget(GTK_MULTIVPANED(paned
));
1758 static void lttvwindow_add_trace(Tab
*tab
, LttvTrace
*trace_v
)
1760 LttvTraceset
*traceset
= tab
->traceset_info
->traceset
;
1762 guint num_traces
= lttv_traceset_number(traceset
);
1764 //Verify if trace is already present.
1765 for(i
=0; i
<num_traces
; i
++)
1767 LttvTrace
* trace
= lttv_traceset_get(traceset
, i
);
1768 if(trace
== trace_v
)
1772 //Keep a reference to the traces so they are not freed.
1773 for(i
=0; i
<lttv_traceset_number(traceset
); i
++)
1775 LttvTrace
* trace
= lttv_traceset_get(traceset
, i
);
1776 lttv_trace_ref(trace
);
1779 //remove state update hooks
1780 lttv_state_remove_event_hooks(
1781 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1783 lttv_context_fini(LTTV_TRACESET_CONTEXT(
1784 tab
->traceset_info
->traceset_context
));
1785 g_object_unref(tab
->traceset_info
->traceset_context
);
1787 lttv_traceset_add(traceset
, trace_v
);
1788 lttv_trace_ref(trace_v
); /* local ref */
1790 /* Create new context */
1791 tab
->traceset_info
->traceset_context
=
1792 g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
1794 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->
1799 //add state update hooks
1800 lttv_state_add_event_hooks(
1801 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1802 //Remove local reference to the traces.
1803 for(i
=0; i
<lttv_traceset_number(traceset
); i
++)
1805 LttvTrace
* trace
= lttv_traceset_get(traceset
, i
);
1806 lttv_trace_unref(trace
);
1810 //add_trace_into_traceset_selector(GTK_MULTIVPANED(tab->multivpaned), lttv_trace(trace_v));
1813 /* add_trace adds a trace into the current traceset. It first displays a
1814 * directory selection dialogue to let user choose a trace, then recreates
1815 * tracset_context, and redraws all the viewer of the current tab
1818 void add_trace(GtkWidget
* widget
, gpointer user_data
)
1821 LttvTrace
* trace_v
;
1822 LttvTraceset
* traceset
;
1824 char abs_path
[PATH_MAX
];
1826 MainWindow
* mw_data
= get_window_data_struct(widget
);
1827 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
1829 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
1830 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
1834 tab
= create_new_tab(widget
, NULL
);
1836 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
1839 GtkDirSelection
* file_selector
= (GtkDirSelection
*)gtk_dir_selection_new("Select a trace");
1840 gtk_dir_selection_hide_fileop_buttons(file_selector
);
1842 if(remember_trace_dir
[0] != '\0')
1843 gtk_dir_selection_set_filename(file_selector
, remember_trace_dir
);
1845 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
1847 case GTK_RESPONSE_ACCEPT
:
1848 case GTK_RESPONSE_OK
:
1849 dir
= gtk_dir_selection_get_dir (file_selector
);
1850 strncpy(remember_trace_dir
, dir
, PATH_MAX
);
1851 if(!dir
|| strlen(dir
) == 0){
1852 gtk_widget_destroy((GtkWidget
*)file_selector
);
1855 get_absolute_pathname(dir
, abs_path
);
1856 trace_v
= lttvwindowtraces_get_trace_by_name(abs_path
);
1857 if(trace_v
== NULL
) {
1858 trace
= ltt_trace_open(abs_path
);
1860 g_warning("cannot open trace %s", abs_path
);
1862 trace_v
= lttv_trace_new(trace
);
1863 lttvwindowtraces_add_trace(trace_v
);
1864 lttvwindow_add_trace(tab
, trace_v
);
1867 lttvwindow_add_trace(tab
, trace_v
);
1870 gtk_widget_destroy((GtkWidget
*)file_selector
);
1872 //update current tab
1873 //update_traceset(mw_data);
1875 /* Call the updatetraceset hooks */
1877 traceset
= tab
->traceset_info
->traceset
;
1878 SetTraceset(tab
, traceset
);
1879 // in expose now call_pending_read_hooks(mw_data);
1881 //lttvwindow_report_current_time(mw_data,&(tab->current_time));
1883 case GTK_RESPONSE_REJECT
:
1884 case GTK_RESPONSE_CANCEL
:
1886 gtk_widget_destroy((GtkWidget
*)file_selector
);
1892 /* remove_trace_into_traceset_selector, each instance of a viewer has an associated
1893 * selector (filter), when a trace is remove from traceset, the selector should
1894 * reflect the change. The function is used to update the selector
1897 void remove_trace_from_traceset_selector(GtkWidget
* paned
, unsigned i
)
1899 LttvTracesetSelector
* s
;
1900 LttvTraceSelector
* t
;
1903 w
= gtk_multivpaned_get_first_widget(GTK_MULTIVPANED(paned
));
1905 s
= g_object_get_data(G_OBJECT(w
), "Traceset_Selector");
1907 t
= lttv_traceset_selector_trace_get(s
,i
);
1908 lttv_traceset_selector_trace_remove(s
, i
);
1909 lttv_trace_selector_destroy(t
);
1910 }g_warning("Module dose not support filtering\n");
1911 w
= gtk_multivpaned_get_next_widget(GTK_MULTIVPANED(paned
));
1916 /* remove_trace removes a trace from the current traceset if all viewers in
1917 * the current tab are not interested in the trace. It first displays a
1918 * dialogue, which shows all traces in the current traceset, to let user choose
1919 * a trace, then it checks if all viewers unselect the trace, if it is true,
1920 * it will remove the trace, recreate the traceset_contex,
1921 * and redraws all the viewer of the current tab. If there is on trace in the
1922 * current traceset, it will delete all viewers of the current tab
1925 // MD : no filter version.
1926 void remove_trace(GtkWidget
*widget
, gpointer user_data
)
1929 LttvTrace
* trace_v
;
1930 LttvTraceset
* traceset
;
1931 gint i
, j
, nb_trace
, index
=-1;
1932 char ** name
, *remove_trace_name
;
1933 MainWindow
* mw_data
= get_window_data_struct(widget
);
1934 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
1936 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
1937 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
1943 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
1946 nb_trace
=lttv_traceset_number(tab
->traceset_info
->traceset
);
1947 name
= g_new(char*,nb_trace
);
1948 for(i
= 0; i
< nb_trace
; i
++){
1949 trace_v
= lttv_traceset_get(tab
->traceset_info
->traceset
, i
);
1950 trace
= lttv_trace(trace_v
);
1951 name
[i
] = ltt_trace_name(trace
);
1954 remove_trace_name
= get_remove_trace(name
, nb_trace
);
1957 if(remove_trace_name
){
1959 /* yuk, cut n paste from old code.. should be better (MD)*/
1960 for(i
= 0; i
<nb_trace
; i
++) {
1961 if(strcmp(remove_trace_name
,name
[i
]) == 0){
1966 traceset
= tab
->traceset_info
->traceset
;
1967 //Keep a reference to the traces so they are not freed.
1968 for(j
=0; j
<lttv_traceset_number(traceset
); j
++)
1970 LttvTrace
* trace
= lttv_traceset_get(traceset
, j
);
1971 lttv_trace_ref(trace
);
1974 //remove state update hooks
1975 lttv_state_remove_event_hooks(
1976 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1977 lttv_context_fini(LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
));
1978 g_object_unref(tab
->traceset_info
->traceset_context
);
1980 trace_v
= lttv_traceset_get(traceset
, index
);
1982 lttv_traceset_remove(traceset
, index
);
1983 lttv_trace_unref(trace_v
); // Remove local reference
1985 if(lttv_trace_get_ref_number(trace_v
) <= 1) {
1986 /* ref 1 : lttvwindowtraces only*/
1987 ltt_trace_close(lttv_trace(trace_v
));
1988 /* lttvwindowtraces_remove_trace takes care of destroying
1989 * the traceset linked with the trace_v and also of destroying
1990 * the trace_v at the same time.
1992 lttvwindowtraces_remove_trace(trace_v
);
1995 tab
->traceset_info
->traceset_context
=
1996 g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
1998 LTTV_TRACESET_CONTEXT(tab
->
1999 traceset_info
->traceset_context
),traceset
);
2000 //add state update hooks
2001 lttv_state_add_event_hooks(
2002 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
2004 //Remove local reference to the traces.
2005 for(j
=0; j
<lttv_traceset_number(traceset
); j
++)
2007 LttvTrace
* trace
= lttv_traceset_get(traceset
, j
);
2008 lttv_trace_unref(trace
);
2011 SetTraceset(tab
, (gpointer
)traceset
);
2017 void remove_trace(GtkWidget
* widget
, gpointer user_data
)
2020 LttvTrace
* trace_v
;
2021 LttvTraceset
* traceset
;
2022 gint i
, j
, nb_trace
;
2023 char ** name
, *remove_trace_name
;
2024 MainWindow
* mw_data
= get_window_data_struct(widget
);
2025 LttvTracesetSelector
* s
;
2026 LttvTraceSelector
* t
;
2029 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
2031 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2032 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2038 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
2041 nb_trace
=lttv_traceset_number(tab
->traceset_info
->traceset
);
2042 name
= g_new(char*,nb_trace
);
2043 for(i
= 0; i
< nb_trace
; i
++){
2044 trace_v
= lttv_traceset_get(tab
->traceset_info
->traceset
, i
);
2045 trace
= lttv_trace(trace_v
);
2046 name
[i
] = ltt_trace_name(trace
);
2049 remove_trace_name
= get_remove_trace(name
, nb_trace
);
2051 if(remove_trace_name
){
2052 for(i
=0; i
<nb_trace
; i
++){
2053 if(strcmp(remove_trace_name
,name
[i
]) == 0){
2054 //unselect the trace from the current viewer
2056 w
= gtk_multivpaned_get_widget(GTK_MULTIVPANED(tab
->multivpaned
));
2058 s
= g_object_get_data(G_OBJECT(w
), "Traceset_Selector");
2060 t
= lttv_traceset_selector_trace_get(s
,i
);
2061 lttv_trace_selector_set_selected(t
, FALSE
);
2064 //check if other viewers select the trace
2065 w
= gtk_multivpaned_get_first_widget(GTK_MULTIVPANED(tab
->multivpaned
));
2067 s
= g_object_get_data(G_OBJECT(w
), "Traceset_Selector");
2069 t
= lttv_traceset_selector_trace_get(s
,i
);
2070 selected
= lttv_trace_selector_get_selected(t
);
2073 w
= gtk_multivpaned_get_next_widget(GTK_MULTIVPANED(tab
->multivpaned
));
2075 }else selected
= FALSE
;
2077 //if no viewer selects the trace, remove it
2079 remove_trace_from_traceset_selector(GTK_MULTIVPANED(tab
->multivpaned
), i
);
2081 traceset
= tab
->traceset_info
->traceset
;
2082 //Keep a reference to the traces so they are not freed.
2083 for(j
=0; j
<lttv_traceset_number(traceset
); j
++)
2085 LttvTrace
* trace
= lttv_traceset_get(traceset
, j
);
2086 lttv_trace_ref(trace
);
2089 //remove state update hooks
2090 lttv_state_remove_event_hooks(
2091 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
2092 lttv_context_fini(LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
));
2093 g_object_unref(tab
->traceset_info
->traceset_context
);
2096 trace_v
= lttv_traceset_get(traceset
, i
);
2098 if(lttv_trace_get_ref_number(trace_v
) <= 2) {
2099 /* ref 2 : traceset, local */
2100 lttvwindowtraces_remove_trace(trace_v
);
2101 ltt_trace_close(lttv_trace(trace_v
));
2104 lttv_traceset_remove(traceset
, i
);
2105 lttv_trace_unref(trace_v
); // Remove local reference
2107 if(!lttv_trace_get_ref_number(trace_v
))
2108 lttv_trace_destroy(trace_v
);
2110 tab
->traceset_info
->traceset_context
=
2111 g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
2113 LTTV_TRACESET_CONTEXT(tab
->
2114 traceset_info
->traceset_context
),traceset
);
2115 //add state update hooks
2116 lttv_state_add_event_hooks(
2117 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
2119 //Remove local reference to the traces.
2120 for(j
=0; j
<lttv_traceset_number(traceset
); j
++)
2122 LttvTrace
* trace
= lttv_traceset_get(traceset
, j
);
2123 lttv_trace_unref(trace
);
2127 //update current tab
2128 //update_traceset(mw_data);
2131 SetTraceset(tab
, (gpointer
)traceset
);
2132 // in expose now call_pending_read_hooks(mw_data);
2134 //lttvwindow_report_current_time(mw_data,&(tab->current_time));
2137 // while(tab->multi_vpaned->num_children){
2138 // gtk_multi_vpaned_widget_delete(tab->multi_vpaned);
2152 /* Redraw all the viewers in the current tab */
2153 void redraw(GtkWidget
*widget
, gpointer user_data
)
2155 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
2156 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2157 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2162 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
2166 LttvAttributeValue value
;
2168 g_assert(lttv_iattribute_find_by_path(tab
->attributes
, "hooks/redraw", LTTV_POINTER
, &value
));
2170 tmp
= (LttvHooks
*)*(value
.v_pointer
);
2172 lttv_hooks_call(tmp
,NULL
);
2176 void continue_processing(GtkWidget
*widget
, gpointer user_data
)
2178 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
2179 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2180 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2185 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
2189 LttvAttributeValue value
;
2191 g_assert(lttv_iattribute_find_by_path(tab
->attributes
,
2192 "hooks/continue", LTTV_POINTER
, &value
));
2194 tmp
= (LttvHooks
*)*(value
.v_pointer
);
2196 lttv_hooks_call(tmp
,NULL
);
2199 /* Stop the processing for the calling main window's current tab.
2200 * It removes every processing requests that are in its list. It does not call
2201 * the end request hooks, because the request is not finished.
2204 void stop_processing(GtkWidget
*widget
, gpointer user_data
)
2206 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
2207 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2208 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2213 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
2215 GSList
*iter
= tab
->events_requests
;
2217 while(iter
!= NULL
) {
2218 GSList
*remove_iter
= iter
;
2219 iter
= g_slist_next(iter
);
2221 g_free(remove_iter
->data
);
2222 tab
->events_requests
=
2223 g_slist_remove_link(tab
->events_requests
, remove_iter
);
2225 tab
->events_request_pending
= FALSE
;
2226 g_idle_remove_by_data(tab
);
2227 g_assert(g_slist_length(tab
->events_requests
) == 0);
2231 /* save will save the traceset to a file
2232 * Not implemented yet FIXME
2235 void save(GtkWidget
* widget
, gpointer user_data
)
2240 void save_as(GtkWidget
* widget
, gpointer user_data
)
2242 g_info("Save as\n");
2246 /* zoom will change the time_window of all the viewers of the
2247 * current tab, and redisplay them. The main functionality is to
2248 * determine the new time_window of the current tab
2251 void zoom(GtkWidget
* widget
, double size
)
2253 TimeInterval time_span
;
2254 TimeWindow new_time_window
;
2255 LttTime current_time
, time_delta
;
2256 MainWindow
* mw_data
= get_window_data_struct(widget
);
2257 LttvTracesetContext
*tsc
;
2258 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
2260 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2261 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2267 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
2270 if(size
== 1) return;
2272 tsc
= LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
2273 time_span
= tsc
->time_span
;
2274 new_time_window
= tab
->time_window
;
2275 current_time
= tab
->current_time
;
2277 time_delta
= ltt_time_sub(time_span
.end_time
,time_span
.start_time
);
2279 new_time_window
.start_time
= time_span
.start_time
;
2280 new_time_window
.time_width
= time_delta
;
2281 new_time_window
.time_width_double
= ltt_time_to_double(time_delta
);
2282 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
2283 new_time_window
.time_width
) ;
2285 new_time_window
.time_width
= ltt_time_div(new_time_window
.time_width
, size
);
2286 new_time_window
.time_width_double
=
2287 ltt_time_to_double(new_time_window
.time_width
);
2288 if(ltt_time_compare(new_time_window
.time_width
,time_delta
) > 0)
2289 { /* Case where zoom out is bigger than trace length */
2290 new_time_window
.start_time
= time_span
.start_time
;
2291 new_time_window
.time_width
= time_delta
;
2292 new_time_window
.time_width_double
= ltt_time_to_double(time_delta
);
2293 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
2294 new_time_window
.time_width
) ;
2298 /* Center the image on the current time */
2299 new_time_window
.start_time
=
2300 ltt_time_sub(current_time
,
2301 ltt_time_from_double(new_time_window
.time_width_double
/2.0));
2302 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
2303 new_time_window
.time_width
) ;
2304 /* If on borders, don't fall off */
2305 if(ltt_time_compare(new_time_window
.start_time
, time_span
.start_time
) <0)
2307 new_time_window
.start_time
= time_span
.start_time
;
2308 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
2309 new_time_window
.time_width
) ;
2313 if(ltt_time_compare(new_time_window
.end_time
,
2314 time_span
.end_time
) > 0)
2316 new_time_window
.start_time
=
2317 ltt_time_sub(time_span
.end_time
, new_time_window
.time_width
);
2319 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
2320 new_time_window
.time_width
) ;
2327 if(ltt_time_compare(new_time_window
.time_width
, ltt_time_zero
) == 0) {
2328 g_warning("Zoom more than 1 ns impossible");
2330 time_change_manager(tab
, new_time_window
);
2334 void zoom_in(GtkWidget
* widget
, gpointer user_data
)
2339 void zoom_out(GtkWidget
* widget
, gpointer user_data
)
2344 void zoom_extended(GtkWidget
* widget
, gpointer user_data
)
2349 void go_to_time(GtkWidget
* widget
, gpointer user_data
)
2351 g_info("Go to time\n");
2354 void show_time_frame(GtkWidget
* widget
, gpointer user_data
)
2356 g_info("Show time frame\n");
2360 /* callback function */
2363 on_empty_traceset_activate (GtkMenuItem
*menuitem
,
2366 create_new_window((GtkWidget
*)menuitem
, user_data
, FALSE
);
2371 on_clone_traceset_activate (GtkMenuItem
*menuitem
,
2374 create_new_window((GtkWidget
*)menuitem
, user_data
, TRUE
);
2378 /* create_new_tab calls create_tab to construct a new tab in the main window
2381 Tab
*create_new_tab(GtkWidget
* widget
, gpointer user_data
){
2382 gchar label
[PATH_MAX
];
2383 MainWindow
* mw_data
= get_window_data_struct(widget
);
2385 GtkNotebook
* notebook
= (GtkNotebook
*)lookup_widget(widget
, "MNotebook");
2386 if(notebook
== NULL
){
2387 g_info("Notebook does not exist\n");
2390 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2391 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2397 copy_tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
2400 strcpy(label
,"Page");
2401 if(get_label(mw_data
, label
,"Get the name of the tab","Please input tab's name"))
2402 return (create_tab (mw_data
, copy_tab
, notebook
, label
));
2406 on_tab_activate (GtkMenuItem
*menuitem
,
2409 create_new_tab((GtkWidget
*)menuitem
, user_data
);
2414 on_open_activate (GtkMenuItem
*menuitem
,
2417 open_traceset((GtkWidget
*)menuitem
, user_data
);
2422 on_close_activate (GtkMenuItem
*menuitem
,
2425 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2426 main_window_destructor(mw_data
);
2430 /* remove the current tab from the main window
2434 on_close_tab_activate (GtkWidget
*widget
,
2438 GtkWidget
* notebook
;
2440 MainWindow
* mw_data
= get_window_data_struct(widget
);
2441 notebook
= lookup_widget(widget
, "MNotebook");
2442 if(notebook
== NULL
){
2443 g_info("Notebook does not exist\n");
2447 page_num
= gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
));
2449 gtk_notebook_remove_page(GTK_NOTEBOOK(notebook
), page_num
);
2454 on_close_tab_X_clicked (GtkWidget
*widget
,
2458 GtkWidget
*notebook
= lookup_widget(widget
, "MNotebook");
2459 if(notebook
== NULL
){
2460 g_info("Notebook does not exist\n");
2464 if((page_num
= gtk_notebook_page_num(GTK_NOTEBOOK(notebook
), widget
)) != -1)
2465 gtk_notebook_remove_page(GTK_NOTEBOOK(notebook
), page_num
);
2471 on_add_trace_activate (GtkMenuItem
*menuitem
,
2474 add_trace((GtkWidget
*)menuitem
, user_data
);
2479 on_remove_trace_activate (GtkMenuItem
*menuitem
,
2482 remove_trace((GtkWidget
*)menuitem
, user_data
);
2487 on_save_activate (GtkMenuItem
*menuitem
,
2490 save((GtkWidget
*)menuitem
, user_data
);
2495 on_save_as_activate (GtkMenuItem
*menuitem
,
2498 save_as((GtkWidget
*)menuitem
, user_data
);
2503 on_quit_activate (GtkMenuItem
*menuitem
,
2511 on_cut_activate (GtkMenuItem
*menuitem
,
2519 on_copy_activate (GtkMenuItem
*menuitem
,
2527 on_paste_activate (GtkMenuItem
*menuitem
,
2535 on_delete_activate (GtkMenuItem
*menuitem
,
2543 on_zoom_in_activate (GtkMenuItem
*menuitem
,
2546 zoom_in((GtkWidget
*)menuitem
, user_data
);
2551 on_zoom_out_activate (GtkMenuItem
*menuitem
,
2554 zoom_out((GtkWidget
*)menuitem
, user_data
);
2559 on_zoom_extended_activate (GtkMenuItem
*menuitem
,
2562 zoom_extended((GtkWidget
*)menuitem
, user_data
);
2567 on_go_to_time_activate (GtkMenuItem
*menuitem
,
2570 go_to_time((GtkWidget
*)menuitem
, user_data
);
2575 on_show_time_frame_activate (GtkMenuItem
*menuitem
,
2578 show_time_frame((GtkWidget
*)menuitem
, user_data
);
2583 on_move_viewer_up_activate (GtkMenuItem
*menuitem
,
2586 move_up_viewer((GtkWidget
*)menuitem
, user_data
);
2591 on_move_viewer_down_activate (GtkMenuItem
*menuitem
,
2594 move_down_viewer((GtkWidget
*)menuitem
, user_data
);
2599 on_remove_viewer_activate (GtkMenuItem
*menuitem
,
2602 delete_viewer((GtkWidget
*)menuitem
, user_data
);
2607 on_trace_filter_activate (GtkMenuItem
*menuitem
,
2610 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2611 LttvTracesetSelector
* s
;
2613 GtkWidget
* notebook
= lookup_widget(GTK_WIDGET(menuitem
), "MNotebook");
2615 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2616 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2622 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
2625 w
= gtk_multivpaned_get_widget(GTK_MULTIVPANED(tab
->multivpaned
));
2627 s
= g_object_get_data(G_OBJECT(w
), "Traceset_Selector");
2629 g_info("There is no viewer yet\n");
2632 if(get_filter_selection(s
, "Configure trace and tracefile filter", "Select traces and tracefiles")){
2633 //FIXME report filter change
2634 //update_traceset(mw_data);
2635 //call_pending_read_hooks(mw_data);
2636 //lttvwindow_report_current_time(mw_data,&(tab->current_time));
2642 on_trace_facility_activate (GtkMenuItem
*menuitem
,
2645 g_info("Trace facility selector: %s\n");
2649 /* Dispaly a file selection dialogue to let user select a library, then call
2650 * lttv_library_load().
2654 on_load_library_activate (GtkMenuItem
*menuitem
,
2657 GError
*error
= NULL
;
2658 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2660 gchar load_module_path_alter
[PATH_MAX
];
2664 gchar
*load_module_path
;
2665 name
= g_ptr_array_new();
2666 nb
= lttv_library_path_number();
2667 /* ask for the library path */
2671 path
= lttv_library_path_get(i
);
2672 g_ptr_array_add(name
, path
);
2675 load_module_path
= get_selection((char **)(name
->pdata
), name
->len
,
2676 "Select a library path", "Library paths");
2677 if(load_module_path
!= NULL
)
2678 strncpy(load_module_path_alter
, load_module_path
, PATH_MAX
-1); // -1 for /
2680 g_ptr_array_free(name
, TRUE
);
2682 if(load_module_path
== NULL
) return;
2686 /* Make sure the module path ends with a / */
2687 gchar
*ptr
= load_module_path_alter
;
2689 ptr
= strchr(ptr
, '\0');
2691 if(*(ptr
-1) != '/') {
2698 /* Ask for the library to load : list files in the previously selected
2700 gchar str
[PATH_MAX
];
2703 GtkFileSelection
* file_selector
=
2704 (GtkFileSelection
*)gtk_file_selection_new("Select a module");
2705 gtk_file_selection_set_filename(file_selector
, load_module_path_alter
);
2706 gtk_file_selection_hide_fileop_buttons(file_selector
);
2709 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
2711 case GTK_RESPONSE_ACCEPT
:
2712 case GTK_RESPONSE_OK
:
2713 dir
= gtk_file_selection_get_selections (file_selector
);
2714 strncpy(str
,dir
[0],PATH_MAX
);
2715 strncpy(remember_plugins_dir
,dir
[0],PATH_MAX
);
2716 /* only keep file name */
2718 str1
= strrchr(str
,'/');
2721 str1
= strrchr(str
,'\\');
2726 if(*str1
== 'l' && *(str1
+1)== 'i' && *(str1
+2)=='b')
2728 remove info after
. */
2732 str2
= strrchr(str2
, '.');
2733 if(str2
!= NULL
) *str2
= '\0';
2735 lttv_module_require(str1
, &error
);
2737 lttv_library_load(str1
, &error
);
2738 if(error
!= NULL
) g_warning("%s", error
->message
);
2739 else g_info("Load library: %s\n", str
);
2741 case GTK_RESPONSE_REJECT
:
2742 case GTK_RESPONSE_CANCEL
:
2744 gtk_widget_destroy((GtkWidget
*)file_selector
);
2755 /* Display all loaded modules, let user to select a module to unload
2756 * by calling lttv_module_unload
2760 on_unload_library_activate (GtkMenuItem
*menuitem
,
2763 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2765 LttvLibrary
*library
= NULL
;
2770 name
= g_ptr_array_new();
2771 nb
= lttv_library_number();
2772 LttvLibraryInfo
*lib_info
= g_new(LttvLibraryInfo
,nb
);
2773 /* ask for the library name */
2776 LttvLibrary
*iter_lib
= lttv_library_get(i
);
2777 lttv_library_info(iter_lib
, &lib_info
[i
]);
2779 gchar
*path
= lib_info
[i
].name
;
2780 g_ptr_array_add(name
, path
);
2782 lib_name
= get_selection((char **)(name
->pdata
), name
->len
,
2783 "Select a library", "Libraries");
2784 if(lib_name
!= NULL
) {
2786 if(strcmp(lib_name
, lib_info
[i
].name
) == 0) {
2787 library
= lttv_library_get(i
);
2792 g_ptr_array_free(name
, TRUE
);
2795 if(lib_name
== NULL
) return;
2797 if(library
!= NULL
) lttv_library_unload(library
);
2801 /* Dispaly a file selection dialogue to let user select a module, then call
2802 * lttv_module_require().
2806 on_load_module_activate (GtkMenuItem
*menuitem
,
2809 GError
*error
= NULL
;
2810 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2812 LttvLibrary
*library
= NULL
;
2817 name
= g_ptr_array_new();
2818 nb
= lttv_library_number();
2819 LttvLibraryInfo
*lib_info
= g_new(LttvLibraryInfo
,nb
);
2820 /* ask for the library name */
2823 LttvLibrary
*iter_lib
= lttv_library_get(i
);
2824 lttv_library_info(iter_lib
, &lib_info
[i
]);
2826 gchar
*path
= lib_info
[i
].name
;
2827 g_ptr_array_add(name
, path
);
2829 lib_name
= get_selection((char **)(name
->pdata
), name
->len
,
2830 "Select a library", "Libraries");
2831 if(lib_name
!= NULL
) {
2833 if(strcmp(lib_name
, lib_info
[i
].name
) == 0) {
2834 library
= lttv_library_get(i
);
2839 g_ptr_array_free(name
, TRUE
);
2842 if(lib_name
== NULL
) return;
2845 //LttvModule *module;
2846 gchar module_name_out
[PATH_MAX
];
2848 /* Ask for the module to load : list modules in the selected lib */
2852 nb
= lttv_library_module_number(library
);
2853 LttvModuleInfo
*module_info
= g_new(LttvModuleInfo
,nb
);
2854 name
= g_ptr_array_new();
2855 /* ask for the module name */
2858 LttvModule
*iter_module
= lttv_library_module_get(library
, i
);
2859 lttv_module_info(iter_module
, &module_info
[i
]);
2861 gchar
*path
= module_info
[i
].name
;
2862 g_ptr_array_add(name
, path
);
2864 module_name
= get_selection((char **)(name
->pdata
), name
->len
,
2865 "Select a module", "Modules");
2866 if(module_name
!= NULL
) {
2868 if(strcmp(module_name
, module_info
[i
].name
) == 0) {
2869 strncpy(module_name_out
, module_name
, PATH_MAX
);
2870 //module = lttv_library_module_get(i);
2876 g_ptr_array_free(name
, TRUE
);
2877 g_free(module_info
);
2879 if(module_name
== NULL
) return;
2882 lttv_module_require(module_name_out
, &error
);
2883 if(error
!= NULL
) g_warning("%s", error
->message
);
2884 else g_info("Load module: %s", module_name_out
);
2891 gchar str
[PATH_MAX
];
2894 GtkFileSelection
* file_selector
=
2895 (GtkFileSelection
*)gtk_file_selection_new("Select a module");
2896 gtk_file_selection_set_filename(file_selector
, load_module_path_alter
);
2897 gtk_file_selection_hide_fileop_buttons(file_selector
);
2900 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
2902 case GTK_RESPONSE_ACCEPT
:
2903 case GTK_RESPONSE_OK
:
2904 dir
= gtk_file_selection_get_selections (file_selector
);
2905 strncpy(str
,dir
[0],PATH_MAX
);
2906 strncpy(remember_plugins_dir
,dir
[0],PATH_MAX
);
2908 /* only keep file name */
2910 str1
= strrchr(str
,'/');
2913 str1
= strrchr(str
,'\\');
2918 if(*str1
== 'l' && *(str1
+1)== 'i' && *(str1
+2)=='b')
2920 remove info after
. */
2924 str2
= strrchr(str2
, '.');
2925 if(str2
!= NULL
) *str2
= '\0';
2927 lttv_module_require(str1
, &error
);
2929 lttv_library_load(str1
, &error
);
2930 if(error
!= NULL
) g_warning(error
->message
);
2931 else g_info("Load library: %s\n", str
);
2933 case GTK_RESPONSE_REJECT
:
2934 case GTK_RESPONSE_CANCEL
:
2936 gtk_widget_destroy((GtkWidget
*)file_selector
);
2948 /* Display all loaded modules, let user to select a module to unload
2949 * by calling lttv_module_unload
2953 on_unload_module_activate (GtkMenuItem
*menuitem
,
2956 GError
*error
= NULL
;
2957 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2959 LttvLibrary
*library
;
2964 name
= g_ptr_array_new();
2965 nb
= lttv_library_number();
2966 LttvLibraryInfo
*lib_info
= g_new(LttvLibraryInfo
,nb
);
2967 /* ask for the library name */
2970 LttvLibrary
*iter_lib
= lttv_library_get(i
);
2971 lttv_library_info(iter_lib
, &lib_info
[i
]);
2973 gchar
*path
= lib_info
[i
].name
;
2974 g_ptr_array_add(name
, path
);
2976 lib_name
= get_selection((char **)(name
->pdata
), name
->len
,
2977 "Select a library", "Libraries");
2978 if(lib_name
!= NULL
) {
2980 if(strcmp(lib_name
, lib_info
[i
].name
) == 0) {
2981 library
= lttv_library_get(i
);
2986 g_ptr_array_free(name
, TRUE
);
2989 if(lib_name
== NULL
) return;
2992 LttvModule
*module
= NULL
;
2994 /* Ask for the module to load : list modules in the selected lib */
2998 nb
= lttv_library_module_number(library
);
2999 LttvModuleInfo
*module_info
= g_new(LttvModuleInfo
,nb
);
3000 name
= g_ptr_array_new();
3001 /* ask for the module name */
3004 LttvModule
*iter_module
= lttv_library_module_get(library
, i
);
3005 lttv_module_info(iter_module
, &module_info
[i
]);
3007 gchar
*path
= module_info
[i
].name
;
3008 if(module_info
[i
].use_count
> 0) g_ptr_array_add(name
, path
);
3010 module_name
= get_selection((char **)(name
->pdata
), name
->len
,
3011 "Select a module", "Modules");
3012 if(module_name
!= NULL
) {
3014 if(strcmp(module_name
, module_info
[i
].name
) == 0) {
3015 module
= lttv_library_module_get(library
, i
);
3021 g_ptr_array_free(name
, TRUE
);
3022 g_free(module_info
);
3024 if(module_name
== NULL
) return;
3027 LttvModuleInfo module_info
;
3028 lttv_module_info(module
, &module_info
);
3029 g_info("Release module: %s\n", module_info
.name
);
3031 lttv_module_release(module
);
3035 /* Display a directory dialogue to let user select a path for library searching
3039 on_add_library_search_path_activate (GtkMenuItem
*menuitem
,
3042 GtkDirSelection
* file_selector
= (GtkDirSelection
*)gtk_dir_selection_new("Select library path");
3046 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
3047 if(remember_plugins_dir
[0] != '\0')
3048 gtk_dir_selection_set_filename(file_selector
, remember_plugins_dir
);
3050 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
3052 case GTK_RESPONSE_ACCEPT
:
3053 case GTK_RESPONSE_OK
:
3054 dir
= gtk_dir_selection_get_dir (file_selector
);
3055 strncpy(remember_plugins_dir
,dir
,PATH_MAX
);
3056 strncat(remember_plugins_dir
,"/",PATH_MAX
);
3057 lttv_library_path_add(dir
);
3058 case GTK_RESPONSE_REJECT
:
3059 case GTK_RESPONSE_CANCEL
:
3061 gtk_widget_destroy((GtkWidget
*)file_selector
);
3067 /* Display a directory dialogue to let user select a path for library searching
3071 on_remove_library_search_path_activate (GtkMenuItem
*menuitem
,
3074 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
3076 const char *lib_path
;
3081 name
= g_ptr_array_new();
3082 nb
= lttv_library_path_number();
3083 /* ask for the library name */
3086 gchar
*path
= lttv_library_path_get(i
);
3087 g_ptr_array_add(name
, path
);
3089 lib_path
= get_selection((char **)(name
->pdata
), name
->len
,
3090 "Select a library path", "Library paths");
3092 g_ptr_array_free(name
, TRUE
);
3094 if(lib_path
== NULL
) return;
3097 lttv_library_path_remove(lib_path
);
3101 on_color_activate (GtkMenuItem
*menuitem
,
3109 on_filter_activate (GtkMenuItem
*menuitem
,
3117 on_save_configuration_activate (GtkMenuItem
*menuitem
,
3120 g_info("Save configuration\n");
3125 on_content_activate (GtkMenuItem
*menuitem
,
3128 g_info("Content\n");
3133 on_about_close_activate (GtkButton
*button
,
3136 GtkWidget
*about_widget
= GTK_WIDGET(user_data
);
3138 gtk_widget_destroy(about_widget
);
3142 on_about_activate (GtkMenuItem
*menuitem
,
3145 MainWindow
*main_window
= get_window_data_struct(GTK_WIDGET(menuitem
));
3146 GtkWidget
*window_widget
= main_window
->mwindow
;
3147 GtkWidget
*about_widget
= gtk_window_new(GTK_WINDOW_TOPLEVEL
);
3148 GtkWindow
*about_window
= GTK_WINDOW(about_widget
);
3149 gint window_width
, window_height
;
3151 gtk_window_set_title(about_window
, "About Linux Trace Toolkit");
3153 gtk_window_set_resizable(about_window
, FALSE
);
3154 gtk_window_set_transient_for(GTK_WINDOW(window_widget
), about_window
);
3155 gtk_window_set_destroy_with_parent(about_window
, TRUE
);
3156 gtk_window_set_modal(about_window
, FALSE
);
3158 /* Put the about window at the center of the screen */
3159 gtk_window_get_size(about_window
, &window_width
, &window_height
);
3160 gtk_window_move (about_window
,
3161 (gdk_screen_width() - window_width
)/2,
3162 (gdk_screen_height() - window_height
)/2);
3164 GtkWidget
*vbox
= gtk_vbox_new(FALSE
, 1);
3166 gtk_container_add(GTK_CONTAINER(about_widget
), vbox
);
3170 GtkWidget
*label1
= gtk_label_new("");
3171 gtk_misc_set_padding(GTK_MISC(label1
), 10, 20);
3172 gtk_label_set_markup(GTK_LABEL(label1
), "\
3173 <big>Linux Trace Toolkit</big>");
3174 gtk_label_set_justify(GTK_LABEL(label1
), GTK_JUSTIFY_CENTER
);
3176 GtkWidget
*label2
= gtk_label_new("");
3177 gtk_misc_set_padding(GTK_MISC(label2
), 10, 20);
3178 gtk_label_set_markup(GTK_LABEL(label2
), "\
3181 Michel Dagenais (New trace format, lttv main)\n\
3182 Mathieu Desnoyers (Directory structure, build with automake/conf,\n\
3183 lttv gui, control flow view, gui cooperative trace reading\n\
3184 scheduler with interruptible foreground and background\n\
3185 computation, detailed event list)\n\
3186 Benoit Des Ligneris, Eric Clement (Cluster adaptation, work in progress)\n\
3187 Xang-Xiu Yang (new trace reading library and converter, lttv gui, \n\
3188 detailed event list and statistics view)\n\
3189 Tom Zanussi (RelayFS)\n\
3191 Strongly inspired from the original Linux Trace Toolkit Visualizer made by\n\
3194 GtkWidget
*label3
= gtk_label_new("");
3195 gtk_label_set_markup(GTK_LABEL(label3
), "\
3196 Linux Trace Toolkit Viewer, Copyright (C) 2004\n\
3198 Mathieu Desnoyers\n\
3200 Linux Trace Toolkit comes with ABSOLUTELY NO WARRANTY.\n\
3201 This is free software, and you are welcome to redistribute it\n\
3202 under certain conditions. See COPYING for details.");
3203 gtk_misc_set_padding(GTK_MISC(label3
), 10, 20);
3205 gtk_box_pack_start_defaults(GTK_BOX(vbox
), label1
);
3206 gtk_box_pack_start_defaults(GTK_BOX(vbox
), label2
);
3207 gtk_box_pack_start_defaults(GTK_BOX(vbox
), label3
);
3209 GtkWidget
*hbox
= gtk_hbox_new(TRUE
, 0);
3210 gtk_box_pack_end(GTK_BOX(vbox
), hbox
, FALSE
, FALSE
, 0);
3211 GtkWidget
*close_button
= gtk_button_new_with_mnemonic("_Close");
3212 gtk_box_pack_end(GTK_BOX(hbox
), close_button
, FALSE
, FALSE
, 0);
3213 gtk_container_set_border_width(GTK_CONTAINER(close_button
), 20);
3215 g_signal_connect(G_OBJECT(close_button
), "clicked",
3216 G_CALLBACK(on_about_close_activate
),
3217 (gpointer
)about_widget
);
3219 gtk_widget_show_all(about_widget
);
3224 on_button_new_clicked (GtkButton
*button
,
3227 create_new_window((GtkWidget
*)button
, user_data
, TRUE
);
3231 on_button_new_tab_clicked (GtkButton
*button
,
3234 create_new_tab((GtkWidget
*)button
, user_data
);
3238 on_button_open_clicked (GtkButton
*button
,
3241 open_traceset((GtkWidget
*)button
, user_data
);
3246 on_button_add_trace_clicked (GtkButton
*button
,
3249 add_trace((GtkWidget
*)button
, user_data
);
3254 on_button_remove_trace_clicked (GtkButton
*button
,
3257 remove_trace((GtkWidget
*)button
, user_data
);
3261 on_button_redraw_clicked (GtkButton
*button
,
3264 redraw((GtkWidget
*)button
, user_data
);
3268 on_button_continue_processing_clicked (GtkButton
*button
,
3271 continue_processing((GtkWidget
*)button
, user_data
);
3275 on_button_stop_processing_clicked (GtkButton
*button
,
3278 stop_processing((GtkWidget
*)button
, user_data
);
3284 on_button_save_clicked (GtkButton
*button
,
3287 save((GtkWidget
*)button
, user_data
);
3292 on_button_save_as_clicked (GtkButton
*button
,
3295 save_as((GtkWidget
*)button
, user_data
);
3300 on_button_zoom_in_clicked (GtkButton
*button
,
3303 zoom_in((GtkWidget
*)button
, user_data
);
3308 on_button_zoom_out_clicked (GtkButton
*button
,
3311 zoom_out((GtkWidget
*)button
, user_data
);
3316 on_button_zoom_extended_clicked (GtkButton
*button
,
3319 zoom_extended((GtkWidget
*)button
, user_data
);
3324 on_button_go_to_time_clicked (GtkButton
*button
,
3327 go_to_time((GtkWidget
*)button
, user_data
);
3332 on_button_show_time_frame_clicked (GtkButton
*button
,
3335 show_time_frame((GtkWidget
*)button
, user_data
);
3340 on_button_move_up_clicked (GtkButton
*button
,
3343 move_up_viewer((GtkWidget
*)button
, user_data
);
3348 on_button_move_down_clicked (GtkButton
*button
,
3351 move_down_viewer((GtkWidget
*)button
, user_data
);
3356 on_button_delete_viewer_clicked (GtkButton
*button
,
3359 delete_viewer((GtkWidget
*)button
, user_data
);
3363 on_MWindow_destroy (GtkWidget
*widget
,
3366 MainWindow
*main_window
= get_window_data_struct(widget
);
3367 LttvIAttribute
*attributes
= main_window
->attributes
;
3368 LttvAttributeValue value
;
3370 //This is unnecessary, since widgets will be destroyed
3371 //by the main window widget anyway.
3372 //remove_all_menu_toolbar_constructors(main_window, NULL);
3374 g_assert(lttv_iattribute_find_by_path(attributes
,
3375 "viewers/menu", LTTV_POINTER
, &value
));
3376 lttv_menus_destroy((LttvMenus
*)*(value
.v_pointer
));
3378 g_assert(lttv_iattribute_find_by_path(attributes
,
3379 "viewers/toolbar", LTTV_POINTER
, &value
));
3380 lttv_toolbars_destroy((LttvToolbars
*)*(value
.v_pointer
));
3382 g_object_unref(main_window
->attributes
);
3383 g_main_window_list
= g_slist_remove(g_main_window_list
, main_window
);
3385 g_info("There are now : %d windows\n",g_slist_length(g_main_window_list
));
3386 if(g_slist_length(g_main_window_list
) == 0)
3391 on_MWindow_configure (GtkWidget
*widget
,
3392 GdkEventConfigure
*event
,
3395 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)widget
);
3397 // MD : removed time width modification upon resizing of the main window.
3398 // The viewers will redraw themselves completely, without time interval
3401 if(mw_data->window_width){
3402 time_span = LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context)->Time_Span ;
3403 time_win = tab->time_window;
3404 ratio = width / mw_data->window_width;
3405 tab->time_window.time_width = ltt_time_mul(time_win.time_width,ratio);
3406 time = ltt_time_sub(time_span->endTime, time_win.start_time);
3407 if(ltt_time_compare(time, tab->time_window.time_width) < 0){
3408 tab->time_window.time_width = time;
3414 mw_data->window_width = (int)width;
3423 on_MNotebook_switch_page (GtkNotebook
*notebook
,
3424 GtkNotebookPage
*page
,
3432 void time_change_manager (Tab
*tab
,
3433 TimeWindow new_time_window
)
3435 /* Only one source of time change */
3436 if(tab
->time_manager_lock
== TRUE
) return;
3438 tab
->time_manager_lock
= TRUE
;
3440 LttvTracesetContext
*tsc
= LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3441 TimeInterval time_span
= tsc
->time_span
;
3442 LttTime start_time
= new_time_window
.start_time
;
3443 LttTime end_time
= new_time_window
.end_time
;
3446 GtkAdjustment
*adjustment
= gtk_range_get_adjustment(GTK_RANGE(tab
->scrollbar
));
3447 LttTime upper
= ltt_time_sub(time_span
.end_time
, time_span
.start_time
);
3449 gtk_range_set_increments(GTK_RANGE(tab
->scrollbar
),
3450 ltt_time_to_double(new_time_window
.time_width
)
3451 / SCROLL_STEP_PER_PAGE
3452 * NANOSECONDS_PER_SECOND
, /* step increment */
3453 ltt_time_to_double(new_time_window
.time_width
)
3454 * NANOSECONDS_PER_SECOND
); /* page increment */
3455 gtk_range_set_range(GTK_RANGE(tab
->scrollbar
),
3457 ltt_time_to_double(upper
)
3458 * NANOSECONDS_PER_SECOND
); /* upper */
3460 g_object_set(G_OBJECT(adjustment
),
3464 ltt_time_to_double(upper
), /* upper */
3466 new_time_window
.time_width_double
3467 / SCROLL_STEP_PER_PAGE
, /* step increment */
3469 new_time_window
.time_width_double
,
3470 /* page increment */
3472 new_time_window
.time_width_double
, /* page size */
3474 gtk_adjustment_changed(adjustment
);
3476 // g_object_set(G_OBJECT(adjustment),
3478 // ltt_time_to_double(
3479 // ltt_time_sub(start_time, time_span.start_time))
3482 //gtk_adjustment_value_changed(adjustment);
3483 gtk_range_set_value(GTK_RANGE(tab
->scrollbar
),
3485 ltt_time_sub(start_time
, time_span
.start_time
)) /* value */);
3487 /* set the time bar. */
3489 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry1
),
3490 (double)time_span
.start_time
.tv_sec
,
3491 (double)time_span
.end_time
.tv_sec
);
3492 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry1
),
3493 (double)start_time
.tv_sec
);
3495 /* start nanoseconds */
3496 if(start_time
.tv_sec
== time_span
.start_time
.tv_sec
) {
3497 /* can be both beginning and end at the same time. */
3498 if(start_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3499 /* If we are at the end, max nsec to end.. -1 (not zero length) */
3500 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry2
),
3501 (double)time_span
.start_time
.tv_nsec
,
3502 (double)time_span
.end_time
.tv_nsec
-1);
3504 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry2
),
3505 (double)time_span
.start_time
.tv_nsec
,
3506 (double)NANOSECONDS_PER_SECOND
-1);
3508 } else if(start_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3509 /* If we are at the end, max nsec to end.. -1 (not zero length) */
3510 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry2
),
3512 (double)time_span
.end_time
.tv_nsec
-1);
3513 } else /* anywhere else */
3514 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry2
),
3516 (double)NANOSECONDS_PER_SECOND
-1);
3517 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry2
),
3518 (double)start_time
.tv_nsec
);
3521 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry3
),
3522 (double)time_span
.start_time
.tv_sec
,
3523 (double)time_span
.end_time
.tv_sec
);
3524 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry3
),
3525 (double)end_time
.tv_sec
);
3527 /* end nanoseconds */
3528 if(end_time
.tv_sec
== time_span
.start_time
.tv_sec
) {
3529 /* can be both beginning and end at the same time. */
3530 if(end_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3531 /* If we are at the end, max nsec to end.. */
3532 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry4
),
3533 (double)time_span
.start_time
.tv_nsec
+1,
3534 (double)time_span
.end_time
.tv_nsec
);
3536 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry4
),
3537 (double)time_span
.start_time
.tv_nsec
+1,
3538 (double)NANOSECONDS_PER_SECOND
-1);
3541 else if(end_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3542 /* If we are at the end, max nsec to end.. */
3543 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry4
),
3545 (double)time_span
.end_time
.tv_nsec
);
3547 else /* anywhere else */
3548 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry4
),
3550 (double)NANOSECONDS_PER_SECOND
-1);
3551 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry4
),
3552 (double)end_time
.tv_nsec
);
3554 /* call viewer hooks for new time window */
3555 set_time_window(tab
, &new_time_window
);
3557 tab
->time_manager_lock
= FALSE
;
3561 /* value changed for frame start s
3563 * Check time span : if ns is out of range, clip it the nearest good value.
3566 on_MEntry1_value_changed (GtkSpinButton
*spinbutton
,
3569 Tab
*tab
=(Tab
*)user_data
;
3570 LttvTracesetContext
* tsc
=
3571 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3572 TimeInterval time_span
= tsc
->time_span
;
3573 gint value
= gtk_spin_button_get_value_as_int(spinbutton
);
3575 TimeWindow new_time_window
= tab
->time_window
;
3577 LttTime end_time
= new_time_window
.end_time
;
3579 new_time_window
.start_time
.tv_sec
= value
;
3581 /* start nanoseconds */
3582 if(new_time_window
.start_time
.tv_sec
== time_span
.start_time
.tv_sec
) {
3583 if(new_time_window
.start_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3584 if(new_time_window
.start_time
.tv_nsec
> time_span
.end_time
.tv_nsec
)
3585 new_time_window
.start_time
.tv_nsec
= time_span
.end_time
.tv_nsec
-1;
3586 if(new_time_window
.start_time
.tv_nsec
< time_span
.start_time
.tv_nsec
)
3587 new_time_window
.start_time
.tv_nsec
= time_span
.start_time
.tv_nsec
;
3589 if(new_time_window
.start_time
.tv_nsec
< time_span
.start_time
.tv_nsec
)
3590 new_time_window
.start_time
.tv_nsec
= time_span
.start_time
.tv_nsec
;
3593 else if(new_time_window
.start_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3594 if(new_time_window
.start_time
.tv_nsec
> time_span
.end_time
.tv_nsec
)
3595 new_time_window
.start_time
.tv_nsec
= time_span
.end_time
.tv_nsec
-1;
3598 if(ltt_time_compare(new_time_window
.start_time
, end_time
) >= 0) {
3599 /* Then, we must push back end time : keep the same time width
3600 * if possible, else end traceset time */
3601 end_time
= LTT_TIME_MIN(ltt_time_add(new_time_window
.start_time
,
3602 new_time_window
.time_width
),
3603 time_span
.end_time
);
3606 /* Fix the time width to fit start time and end time */
3607 new_time_window
.time_width
= ltt_time_sub(end_time
,
3608 new_time_window
.start_time
);
3609 new_time_window
.time_width_double
=
3610 ltt_time_to_double(new_time_window
.time_width
);
3612 new_time_window
.end_time
= end_time
;
3614 time_change_manager(tab
, new_time_window
);
3619 on_MEntry2_value_changed (GtkSpinButton
*spinbutton
,
3622 Tab
*tab
=(Tab
*)user_data
;
3623 LttvTracesetContext
* tsc
=
3624 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3625 TimeInterval time_span
= tsc
->time_span
;
3626 gint value
= gtk_spin_button_get_value_as_int(spinbutton
);
3628 TimeWindow new_time_window
= tab
->time_window
;
3630 LttTime end_time
= new_time_window
.end_time
;
3632 new_time_window
.start_time
.tv_nsec
= value
;
3634 if(ltt_time_compare(new_time_window
.start_time
, end_time
) >= 0) {
3635 /* Then, we must push back end time : keep the same time width
3636 * if possible, else end traceset time */
3637 end_time
= LTT_TIME_MIN(ltt_time_add(new_time_window
.start_time
,
3638 new_time_window
.time_width
),
3639 time_span
.end_time
);
3642 /* Fix the time width to fit start time and end time */
3643 new_time_window
.time_width
= ltt_time_sub(end_time
,
3644 new_time_window
.start_time
);
3645 new_time_window
.time_width_double
=
3646 ltt_time_to_double(new_time_window
.time_width
);
3648 new_time_window
.end_time
= end_time
;
3650 time_change_manager(tab
, new_time_window
);
3655 on_MEntry3_value_changed (GtkSpinButton
*spinbutton
,
3658 Tab
*tab
=(Tab
*)user_data
;
3659 LttvTracesetContext
* tsc
=
3660 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3661 TimeInterval time_span
= tsc
->time_span
;
3662 gint value
= gtk_spin_button_get_value_as_int(spinbutton
);
3664 TimeWindow new_time_window
= tab
->time_window
;
3666 LttTime end_time
= new_time_window
.end_time
;
3668 end_time
.tv_sec
= value
;
3670 /* end nanoseconds */
3671 if(end_time
.tv_sec
== time_span
.start_time
.tv_sec
) {
3672 if(end_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3673 if(end_time
.tv_nsec
> time_span
.end_time
.tv_nsec
)
3674 end_time
.tv_nsec
= time_span
.end_time
.tv_nsec
;
3675 if(end_time
.tv_nsec
< time_span
.start_time
.tv_nsec
)
3676 end_time
.tv_nsec
= time_span
.start_time
.tv_nsec
+1;
3678 if(end_time
.tv_nsec
< time_span
.start_time
.tv_nsec
)
3679 end_time
.tv_nsec
= time_span
.start_time
.tv_nsec
+1;
3682 else if(end_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3683 if(end_time
.tv_nsec
> time_span
.end_time
.tv_nsec
)
3684 end_time
.tv_nsec
= time_span
.end_time
.tv_nsec
;
3687 if(ltt_time_compare(new_time_window
.start_time
, end_time
) >= 0) {
3688 /* Then, we must push front start time : keep the same time width
3689 * if possible, else end traceset time */
3690 new_time_window
.start_time
= LTT_TIME_MAX(
3691 ltt_time_sub(end_time
,
3692 new_time_window
.time_width
),
3693 time_span
.start_time
);
3696 /* Fix the time width to fit start time and end time */
3697 new_time_window
.time_width
= ltt_time_sub(end_time
,
3698 new_time_window
.start_time
);
3699 new_time_window
.time_width_double
=
3700 ltt_time_to_double(new_time_window
.time_width
);
3702 new_time_window
.end_time
= end_time
;
3704 time_change_manager(tab
, new_time_window
);
3709 on_MEntry4_value_changed (GtkSpinButton
*spinbutton
,
3712 Tab
*tab
=(Tab
*)user_data
;
3713 LttvTracesetContext
* tsc
=
3714 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3715 TimeInterval time_span
= tsc
->time_span
;
3716 gint value
= gtk_spin_button_get_value_as_int(spinbutton
);
3718 TimeWindow new_time_window
= tab
->time_window
;
3720 LttTime end_time
= new_time_window
.end_time
;
3722 end_time
.tv_nsec
= value
;
3724 if(ltt_time_compare(new_time_window
.start_time
, end_time
) >= 0) {
3725 /* Then, we must push front start time : keep the same time width
3726 * if possible, else end traceset time */
3727 new_time_window
.start_time
= LTT_TIME_MAX(
3728 ltt_time_sub(end_time
,
3729 new_time_window
.time_width
),
3730 time_span
.start_time
);
3733 /* Fix the time width to fit start time and end time */
3734 new_time_window
.time_width
= ltt_time_sub(end_time
,
3735 new_time_window
.start_time
);
3736 new_time_window
.time_width_double
=
3737 ltt_time_to_double(new_time_window
.time_width
);
3738 new_time_window
.end_time
= end_time
;
3740 time_change_manager(tab
, new_time_window
);
3745 void current_time_change_manager (Tab
*tab
,
3746 LttTime new_current_time
)
3748 /* Only one source of time change */
3749 if(tab
->current_time_manager_lock
== TRUE
) return;
3751 tab
->current_time_manager_lock
= TRUE
;
3753 LttvTracesetContext
*tsc
= LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3754 TimeInterval time_span
= tsc
->time_span
;
3756 /* current seconds */
3757 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry5
),
3758 (double)time_span
.start_time
.tv_sec
,
3759 (double)time_span
.end_time
.tv_sec
);
3760 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry5
),
3761 (double)new_current_time
.tv_sec
);
3764 /* start nanoseconds */
3765 if(new_current_time
.tv_sec
== time_span
.start_time
.tv_sec
) {
3766 /* can be both beginning and end at the same time. */
3767 if(new_current_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3768 /* If we are at the end, max nsec to end.. */
3769 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry6
),
3770 (double)time_span
.start_time
.tv_nsec
,
3771 (double)time_span
.end_time
.tv_nsec
);
3773 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry6
),
3774 (double)time_span
.start_time
.tv_nsec
,
3775 (double)NANOSECONDS_PER_SECOND
-1);
3777 } else if(new_current_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3778 /* If we are at the end, max nsec to end.. */
3779 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry6
),
3781 (double)time_span
.end_time
.tv_nsec
);
3782 } else /* anywhere else */
3783 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry6
),
3785 (double)NANOSECONDS_PER_SECOND
-1);
3787 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry6
),
3788 (double)new_current_time
.tv_nsec
);
3790 set_current_time(tab
, &new_current_time
);
3792 tab
->current_time_manager_lock
= FALSE
;
3796 on_MEntry5_value_changed (GtkSpinButton
*spinbutton
,
3799 Tab
*tab
= (Tab
*)user_data
;
3800 LttvTracesetContext
* tsc
=
3801 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3802 TimeInterval time_span
= tsc
->time_span
;
3803 gint value
= gtk_spin_button_get_value_as_int(spinbutton
);
3804 LttTime new_current_time
= tab
->current_time
;
3805 new_current_time
.tv_sec
= value
;
3807 /* current nanoseconds */
3808 if(new_current_time
.tv_sec
== time_span
.start_time
.tv_sec
) {
3809 if(new_current_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3810 if(new_current_time
.tv_nsec
> time_span
.end_time
.tv_nsec
)
3811 new_current_time
.tv_nsec
= time_span
.end_time
.tv_nsec
;
3812 if(new_current_time
.tv_nsec
< time_span
.start_time
.tv_nsec
)
3813 new_current_time
.tv_nsec
= time_span
.start_time
.tv_nsec
;
3815 if(new_current_time
.tv_nsec
< time_span
.start_time
.tv_nsec
)
3816 new_current_time
.tv_nsec
= time_span
.start_time
.tv_nsec
;
3819 else if(new_current_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3820 if(new_current_time
.tv_nsec
> time_span
.end_time
.tv_nsec
)
3821 new_current_time
.tv_nsec
= time_span
.end_time
.tv_nsec
;
3824 current_time_change_manager(tab
, new_current_time
);
3828 on_MEntry6_value_changed (GtkSpinButton
*spinbutton
,
3831 Tab
*tab
= (Tab
*)user_data
;
3832 gint value
= gtk_spin_button_get_value_as_int(spinbutton
);
3833 LttTime new_current_time
= tab
->current_time
;
3834 new_current_time
.tv_nsec
= value
;
3836 current_time_change_manager(tab
, new_current_time
);
3840 void scroll_value_changed_cb(GtkWidget
*scrollbar
,
3843 Tab
*tab
= (Tab
*)user_data
;
3844 TimeWindow new_time_window
;
3846 GtkAdjustment
*adjust
= gtk_range_get_adjustment(GTK_RANGE(scrollbar
));
3847 gdouble value
= gtk_adjustment_get_value(adjust
);
3848 // gdouble upper, lower, ratio, page_size;
3850 LttvTracesetContext
* tsc
=
3851 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3852 TimeInterval time_span
= tsc
->time_span
;
3854 time
= ltt_time_add(ltt_time_from_double(value
),
3855 time_span
.start_time
);
3857 new_time_window
.start_time
= time
;
3859 page_size
= adjust
->page_size
;
3861 new_time_window
.time_width
=
3862 ltt_time_from_double(page_size
);
3864 new_time_window
.time_width_double
=
3867 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
3868 new_time_window
.time_width
);
3871 time_change_manager(tab
, new_time_window
);
3873 //time_window = tab->time_window;
3875 lower
= adjust
->lower
;
3876 upper
= adjust
->upper
;
3877 ratio
= (value
- lower
) / (upper
- lower
);
3878 g_info("lower %lu, upper %lu, value %lu, ratio %lu", lower
, upper
, value
, ratio
);
3880 //time = ltt_time_sub(time_span->end_time, time_span->start_time);
3881 //time = ltt_time_mul(time, (float)ratio);
3882 //time = ltt_time_add(time_span->start_time, time);
3883 time
= ltt_time_add(ltt_time_from_double(value
),
3884 time_span
.start_time
);
3886 time_window
.start_time
= time
;
3888 page_size
= adjust
->page_size
;
3890 time_window
.time_width
=
3891 ltt_time_from_double(page_size
);
3892 //time = ltt_time_sub(time_span.end_time, time);
3893 //if(ltt_time_compare(time,time_window.time_width) < 0){
3894 // time_window.time_width = time;
3897 /* call viewer hooks for new time window */
3898 set_time_window(tab
, &time_window
);
3903 /* callback function to check or uncheck the check box (filter)
3906 void checkbox_changed(GtkTreeView
*treeview
,
3908 GtkTreeViewColumn
*arg2
,
3911 GtkTreeStore
* store
= (GtkTreeStore
*)gtk_tree_view_get_model (treeview
);
3915 if (gtk_tree_model_get_iter ((GtkTreeModel
*)store
, &iter
, arg1
)){
3916 gtk_tree_model_get ((GtkTreeModel
*)store
, &iter
, CHECKBOX_COLUMN
, &value
, -1);
3917 value
= value
? FALSE
: TRUE
;
3918 gtk_tree_store_set (GTK_TREE_STORE (store
), &iter
, CHECKBOX_COLUMN
, value
, -1);
3924 /* According to user's selection, update selector(filter)
3927 void update_filter(LttvTracesetSelector
*s
, GtkTreeStore
*store
)
3929 GtkTreeIter iter
, child_iter
, child_iter1
, child_iter2
;
3930 int i
, j
, k
, nb_eventtype
;
3931 LttvTraceSelector
* trace
;
3932 LttvTracefileSelector
* tracefile
;
3933 LttvEventtypeSelector
* eventtype
;
3934 gboolean value
, value1
, value2
;
3936 if(gtk_tree_model_get_iter_first((GtkTreeModel
*)store
, &iter
)){
3939 trace
= lttv_traceset_selector_trace_get(s
, i
);
3940 nb_eventtype
= lttv_trace_selector_eventtype_number(trace
);
3941 gtk_tree_model_get ((GtkTreeModel
*)store
, &iter
, CHECKBOX_COLUMN
, &value
,-1);
3944 if(gtk_tree_model_iter_children ((GtkTreeModel
*)store
, &child_iter
, &iter
)){
3946 if(j
<1){//eventtype selector for trace
3947 gtk_tree_model_get ((GtkTreeModel
*)store
, &child_iter
, CHECKBOX_COLUMN
, &value2
,-1);
3950 if(gtk_tree_model_iter_children ((GtkTreeModel
*)store
, &child_iter1
, &child_iter
)){
3952 eventtype
= lttv_trace_selector_eventtype_get(trace
,k
);
3953 gtk_tree_model_get ((GtkTreeModel
*)store
, &child_iter1
, CHECKBOX_COLUMN
, &value2
,-1);
3954 lttv_eventtype_selector_set_selected(eventtype
,value2
);
3956 }while(gtk_tree_model_iter_next((GtkTreeModel
*)store
, &child_iter1
));
3959 }else{ //tracefile selector
3960 tracefile
= lttv_trace_selector_tracefile_get(trace
, j
- 1);
3961 gtk_tree_model_get ((GtkTreeModel
*)store
, &child_iter
, CHECKBOX_COLUMN
, &value1
,-1);
3962 lttv_tracefile_selector_set_selected(tracefile
,value1
);
3964 gtk_tree_model_iter_children((GtkTreeModel
*)store
, &child_iter1
, &child_iter
); //eventtype selector
3965 gtk_tree_model_get ((GtkTreeModel
*)store
, &child_iter1
, CHECKBOX_COLUMN
, &value2
,-1);
3968 if(gtk_tree_model_iter_children ((GtkTreeModel
*)store
, &child_iter2
, &child_iter1
)){
3969 do{//eventtype selector for tracefile
3970 eventtype
= lttv_tracefile_selector_eventtype_get(tracefile
,k
);
3971 gtk_tree_model_get ((GtkTreeModel
*)store
, &child_iter2
, CHECKBOX_COLUMN
, &value2
,-1);
3972 lttv_eventtype_selector_set_selected(eventtype
,value2
);
3974 }while(gtk_tree_model_iter_next((GtkTreeModel
*)store
, &child_iter2
));
3980 }while(gtk_tree_model_iter_next((GtkTreeModel
*)store
, &child_iter
));
3983 lttv_trace_selector_set_selected(trace
,value
);
3985 }while(gtk_tree_model_iter_next((GtkTreeModel
*)store
, &iter
));
3990 /* Display a dialogue showing all eventtypes and traces, let user to select the interested
3991 * eventtypes, tracefiles and traces (filter)
3994 gboolean
get_filter_selection(LttvTracesetSelector
*s
,char *title
, char * column_title
)
3996 GtkWidget
* dialogue
;
3997 GtkTreeStore
* store
;
3999 GtkWidget
* scroll_win
;
4000 GtkCellRenderer
* renderer
;
4001 GtkTreeViewColumn
* column
;
4002 GtkTreeIter iter
, child_iter
, child_iter1
, child_iter2
;
4003 int i
, j
, k
, id
, nb_trace
, nb_tracefile
, nb_eventtype
;
4004 LttvTraceSelector
* trace
;
4005 LttvTracefileSelector
* tracefile
;
4006 LttvEventtypeSelector
* eventtype
;
4010 dialogue
= gtk_dialog_new_with_buttons(title
,
4013 GTK_STOCK_OK
,GTK_RESPONSE_ACCEPT
,
4014 GTK_STOCK_CANCEL
,GTK_RESPONSE_REJECT
,
4016 gtk_window_set_default_size((GtkWindow
*)dialogue
, 300, 500);
4018 store
= gtk_tree_store_new (TOTAL_COLUMNS
, G_TYPE_BOOLEAN
, G_TYPE_STRING
);
4019 tree
= gtk_tree_view_new_with_model (GTK_TREE_MODEL (store
));
4020 g_object_unref (G_OBJECT (store
));
4021 g_signal_connect (G_OBJECT (tree
), "row-activated",
4022 G_CALLBACK (checkbox_changed
),
4026 renderer
= gtk_cell_renderer_toggle_new ();
4027 gtk_cell_renderer_toggle_set_radio((GtkCellRendererToggle
*)renderer
, FALSE
);
4029 g_object_set (G_OBJECT (renderer
),"activatable", TRUE
, NULL
);
4031 column
= gtk_tree_view_column_new_with_attributes ("Checkbox",
4033 "active", CHECKBOX_COLUMN
,
4035 gtk_tree_view_column_set_alignment (column
, 0.5);
4036 gtk_tree_view_column_set_fixed_width (column
, 20);
4037 gtk_tree_view_append_column (GTK_TREE_VIEW (tree
), column
);
4039 renderer
= gtk_cell_renderer_text_new ();
4040 column
= gtk_tree_view_column_new_with_attributes (column_title
,
4042 "text", NAME_COLUMN
,
4044 gtk_tree_view_column_set_alignment (column
, 0.0);
4045 gtk_tree_view_append_column (GTK_TREE_VIEW (tree
), column
);
4046 gtk_tree_view_set_headers_visible(GTK_TREE_VIEW (tree
), FALSE
);
4048 scroll_win
= gtk_scrolled_window_new (NULL
, NULL
);
4049 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll_win
),
4050 GTK_POLICY_AUTOMATIC
,GTK_POLICY_AUTOMATIC
);
4051 gtk_container_add (GTK_CONTAINER (scroll_win
), tree
);
4053 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialogue
)->vbox
), scroll_win
,TRUE
, TRUE
,0);
4055 gtk_widget_show(scroll_win
);
4056 gtk_widget_show(tree
);
4058 nb_trace
= lttv_traceset_selector_trace_number(s
);
4059 for(i
=0;i
<nb_trace
;i
++){
4060 trace
= lttv_traceset_selector_trace_get(s
, i
);
4061 name
= lttv_trace_selector_get_name(trace
);
4062 gtk_tree_store_append (store
, &iter
, NULL
);
4063 checked
= lttv_trace_selector_get_selected(trace
);
4064 gtk_tree_store_set (store
, &iter
,
4065 CHECKBOX_COLUMN
,checked
,
4069 gtk_tree_store_append (store
, &child_iter
, &iter
);
4070 gtk_tree_store_set (store
, &child_iter
,
4071 CHECKBOX_COLUMN
, checked
,
4072 NAME_COLUMN
,"eventtype",
4075 nb_eventtype
= lttv_trace_selector_eventtype_number(trace
);
4076 for(j
=0;j
<nb_eventtype
;j
++){
4077 eventtype
= lttv_trace_selector_eventtype_get(trace
,j
);
4078 name
= lttv_eventtype_selector_get_name(eventtype
);
4079 checked
= lttv_eventtype_selector_get_selected(eventtype
);
4080 gtk_tree_store_append (store
, &child_iter1
, &child_iter
);
4081 gtk_tree_store_set (store
, &child_iter1
,
4082 CHECKBOX_COLUMN
, checked
,
4087 nb_tracefile
= lttv_trace_selector_tracefile_number(trace
);
4088 for(j
=0;j
<nb_tracefile
;j
++){
4089 tracefile
= lttv_trace_selector_tracefile_get(trace
, j
);
4090 name
= lttv_tracefile_selector_get_name(tracefile
);
4091 gtk_tree_store_append (store
, &child_iter
, &iter
);
4092 checked
= lttv_tracefile_selector_get_selected(tracefile
);
4093 gtk_tree_store_set (store
, &child_iter
,
4094 CHECKBOX_COLUMN
, checked
,
4098 gtk_tree_store_append (store
, &child_iter1
, &child_iter
);
4099 gtk_tree_store_set (store
, &child_iter1
,
4100 CHECKBOX_COLUMN
, checked
,
4101 NAME_COLUMN
,"eventtype",
4104 for(k
=0;k
<nb_eventtype
;k
++){
4105 eventtype
= lttv_tracefile_selector_eventtype_get(tracefile
,k
);
4106 name
= lttv_eventtype_selector_get_name(eventtype
);
4107 checked
= lttv_eventtype_selector_get_selected(eventtype
);
4108 gtk_tree_store_append (store
, &child_iter2
, &child_iter1
);
4109 gtk_tree_store_set (store
, &child_iter2
,
4110 CHECKBOX_COLUMN
, checked
,
4117 id
= gtk_dialog_run(GTK_DIALOG(dialogue
));
4119 case GTK_RESPONSE_ACCEPT
:
4120 case GTK_RESPONSE_OK
:
4121 update_filter(s
, store
);
4122 gtk_widget_destroy(dialogue
);
4124 case GTK_RESPONSE_REJECT
:
4125 case GTK_RESPONSE_CANCEL
:
4127 gtk_widget_destroy(dialogue
);
4134 /* Select a trace which will be removed from traceset
4137 char * get_remove_trace(char ** all_trace_name
, int nb_trace
)
4139 return get_selection(all_trace_name
, nb_trace
,
4140 "Select a trace", "Trace pathname");
4144 /* Select a module which will be loaded
4147 char * get_load_module(char ** load_module_name
, int nb_module
)
4149 return get_selection(load_module_name
, nb_module
,
4150 "Select a module to load", "Module name");
4156 /* Select a module which will be unloaded
4159 char * get_unload_module(char ** loaded_module_name
, int nb_module
)
4161 return get_selection(loaded_module_name
, nb_module
,
4162 "Select a module to unload", "Module name");
4166 /* Display a dialogue which shows all selectable items, let user to
4167 * select one of them
4170 char * get_selection(char ** loaded_module_name
, int nb_module
,
4171 char *title
, char * column_title
)
4173 GtkWidget
* dialogue
;
4174 GtkWidget
* scroll_win
;
4176 GtkListStore
* store
;
4177 GtkTreeViewColumn
* column
;
4178 GtkCellRenderer
* renderer
;
4179 GtkTreeSelection
* select
;
4182 char * unload_module_name
= NULL
;
4184 dialogue
= gtk_dialog_new_with_buttons(title
,
4187 GTK_STOCK_OK
,GTK_RESPONSE_ACCEPT
,
4188 GTK_STOCK_CANCEL
,GTK_RESPONSE_REJECT
,
4190 gtk_window_set_default_size((GtkWindow
*)dialogue
, 500, 200);
4192 scroll_win
= gtk_scrolled_window_new (NULL
, NULL
);
4193 gtk_widget_show ( scroll_win
);
4194 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll_win
),
4195 GTK_POLICY_AUTOMATIC
, GTK_POLICY_AUTOMATIC
);
4197 store
= gtk_list_store_new (N_COLUMNS
,G_TYPE_STRING
);
4198 tree
= gtk_tree_view_new_with_model(GTK_TREE_MODEL (store
));
4199 gtk_widget_show ( tree
);
4200 g_object_unref (G_OBJECT (store
));
4202 renderer
= gtk_cell_renderer_text_new ();
4203 column
= gtk_tree_view_column_new_with_attributes (column_title
,
4205 "text", MODULE_COLUMN
,
4207 gtk_tree_view_column_set_alignment (column
, 0.5);
4208 gtk_tree_view_column_set_fixed_width (column
, 150);
4209 gtk_tree_view_append_column (GTK_TREE_VIEW (tree
), column
);
4211 select
= gtk_tree_view_get_selection (GTK_TREE_VIEW (tree
));
4212 gtk_tree_selection_set_mode (select
, GTK_SELECTION_SINGLE
);
4214 gtk_container_add (GTK_CONTAINER (scroll_win
), tree
);
4216 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialogue
)->vbox
), scroll_win
,TRUE
, TRUE
,0);
4218 for(i
=0;i
<nb_module
;i
++){
4219 gtk_list_store_append (store
, &iter
);
4220 gtk_list_store_set (store
, &iter
, MODULE_COLUMN
,loaded_module_name
[i
],-1);
4223 id
= gtk_dialog_run(GTK_DIALOG(dialogue
));
4224 GtkTreeModel
**store_model
= (GtkTreeModel
**)&store
; /* for strict aliasing */
4226 case GTK_RESPONSE_ACCEPT
:
4227 case GTK_RESPONSE_OK
:
4228 if (gtk_tree_selection_get_selected (select
, store_model
, &iter
)){
4229 gtk_tree_model_get ((GtkTreeModel
*)store
, &iter
, MODULE_COLUMN
, &unload_module_name
, -1);
4231 case GTK_RESPONSE_REJECT
:
4232 case GTK_RESPONSE_CANCEL
:
4234 gtk_widget_destroy(dialogue
);
4238 return unload_module_name
;
4242 /* Insert all menu entry and tool buttons into this main window
4247 void add_all_menu_toolbar_constructors(MainWindow
* mw
, gpointer user_data
)
4251 lttvwindow_viewer_constructor constructor
;
4252 LttvMenus
* global_menu
, * instance_menu
;
4253 LttvToolbars
* global_toolbar
, * instance_toolbar
;
4254 LttvMenuClosure
*menu_item
;
4255 LttvToolbarClosure
*toolbar_item
;
4256 LttvAttributeValue value
;
4257 LttvIAttribute
*global_attributes
= LTTV_IATTRIBUTE(lttv_global_attributes());
4258 LttvIAttribute
*attributes
= mw
->attributes
;
4259 GtkWidget
* tool_menu_title_menu
, *new_widget
, *pixmap
;
4261 g_assert(lttv_iattribute_find_by_path(global_attributes
,
4262 "viewers/menu", LTTV_POINTER
, &value
));
4263 if(*(value
.v_pointer
) == NULL
)
4264 *(value
.v_pointer
) = lttv_menus_new();
4265 global_menu
= (LttvMenus
*)*(value
.v_pointer
);
4267 g_assert(lttv_iattribute_find_by_path(attributes
,
4268 "viewers/menu", LTTV_POINTER
, &value
));
4269 if(*(value
.v_pointer
) == NULL
)
4270 *(value
.v_pointer
) = lttv_menus_new();
4271 instance_menu
= (LttvMenus
*)*(value
.v_pointer
);
4275 g_assert(lttv_iattribute_find_by_path(global_attributes
,
4276 "viewers/toolbar", LTTV_POINTER
, &value
));
4277 if(*(value
.v_pointer
) == NULL
)
4278 *(value
.v_pointer
) = lttv_toolbars_new();
4279 global_toolbar
= (LttvToolbars
*)*(value
.v_pointer
);
4281 g_assert(lttv_iattribute_find_by_path(attributes
,
4282 "viewers/toolbar", LTTV_POINTER
, &value
));
4283 if(*(value
.v_pointer
) == NULL
)
4284 *(value
.v_pointer
) = lttv_toolbars_new();
4285 instance_toolbar
= (LttvToolbars
*)*(value
.v_pointer
);
4287 /* Add missing menu entries to window instance */
4288 for(i
=0;i
<global_menu
->len
;i
++) {
4289 menu_item
= &g_array_index(global_menu
, LttvMenuClosure
, i
);
4291 //add menu_item to window instance;
4292 constructor
= menu_item
->con
;
4293 tool_menu_title_menu
= lookup_widget(mw
->mwindow
,"ToolMenuTitle_menu");
4295 gtk_menu_item_new_with_mnemonic (menu_item
->menu_text
);
4296 gtk_container_add (GTK_CONTAINER (tool_menu_title_menu
),
4298 g_signal_connect ((gpointer
) new_widget
, "activate",
4299 G_CALLBACK (insert_viewer_wrap
),
4301 gtk_widget_show (new_widget
);
4302 lttv_menus_add(instance_menu
, menu_item
->con
,
4303 menu_item
->menu_path
,
4304 menu_item
->menu_text
,
4309 /* Add missing toolbar entries to window instance */
4310 for(i
=0;i
<global_toolbar
->len
;i
++) {
4311 toolbar_item
= &g_array_index(global_toolbar
, LttvToolbarClosure
, i
);
4313 //add toolbar_item to window instance;
4314 constructor
= toolbar_item
->con
;
4315 tool_menu_title_menu
= lookup_widget(mw
->mwindow
,"MToolbar1");
4316 pixbuf
= gdk_pixbuf_new_from_xpm_data((const char**)toolbar_item
->pixmap
);
4317 pixmap
= gtk_image_new_from_pixbuf(pixbuf
);
4319 gtk_toolbar_append_element (GTK_TOOLBAR (tool_menu_title_menu
),
4320 GTK_TOOLBAR_CHILD_BUTTON
,
4323 toolbar_item
->tooltip
, NULL
,
4324 pixmap
, NULL
, NULL
);
4325 gtk_label_set_use_underline(
4326 GTK_LABEL (((GtkToolbarChild
*) (
4327 g_list_last (GTK_TOOLBAR
4328 (tool_menu_title_menu
)->children
)->data
))->label
),
4330 gtk_container_set_border_width (GTK_CONTAINER (new_widget
), 1);
4331 g_signal_connect ((gpointer
) new_widget
,
4333 G_CALLBACK (insert_viewer_wrap
),
4335 gtk_widget_show (new_widget
);
4337 lttv_toolbars_add(instance_toolbar
, toolbar_item
->con
,
4338 toolbar_item
->tooltip
,
4339 toolbar_item
->pixmap
,
4347 /* Create a main window
4350 void construct_main_window(MainWindow
* parent
)
4352 g_debug("construct_main_window()");
4353 GtkWidget
* new_window
; /* New generated main window */
4354 MainWindow
* new_m_window
;/* New main window structure */
4355 GtkNotebook
* notebook
;
4356 LttvIAttribute
*attributes
=
4357 LTTV_IATTRIBUTE(g_object_new(LTTV_ATTRIBUTE_TYPE
, NULL
));
4358 LttvAttributeValue value
;
4361 new_m_window
= g_new(MainWindow
, 1);
4363 // Add the object's information to the module's array
4364 g_main_window_list
= g_slist_append(g_main_window_list
, new_m_window
);
4366 new_window
= create_MWindow();
4367 gtk_widget_show (new_window
);
4369 new_m_window
->mwindow
= new_window
;
4370 new_m_window
->attributes
= attributes
;
4372 g_assert(lttv_iattribute_find_by_path(attributes
,
4373 "viewers/menu", LTTV_POINTER
, &value
));
4374 *(value
.v_pointer
) = lttv_menus_new();
4376 g_assert(lttv_iattribute_find_by_path(attributes
,
4377 "viewers/toolbar", LTTV_POINTER
, &value
));
4378 *(value
.v_pointer
) = lttv_toolbars_new();
4380 add_all_menu_toolbar_constructors(new_m_window
, NULL
);
4382 g_object_set_data_full(G_OBJECT(new_window
),
4384 (gpointer
)new_m_window
,
4385 (GDestroyNotify
)g_free
);
4386 //create a default tab
4387 notebook
= (GtkNotebook
*)lookup_widget(new_m_window
->mwindow
, "MNotebook");
4388 if(notebook
== NULL
){
4389 g_info("Notebook does not exist\n");
4392 //gtk_notebook_popup_enable (GTK_NOTEBOOK(notebook));
4393 //for now there is no name field in LttvTraceset structure
4394 //Use "Traceset" as the label for the default tab
4396 GtkWidget
* parent_notebook
= lookup_widget(parent
->mwindow
, "MNotebook");
4397 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(parent_notebook
),
4398 gtk_notebook_get_current_page(GTK_NOTEBOOK(parent_notebook
)));
4404 parent_tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
4406 new_tab
= create_tab(new_m_window
, parent_tab
, notebook
, "Traceset");
4408 new_tab
= create_tab(new_m_window
, NULL
, notebook
, "Traceset");
4409 /* First window, use command line trace */
4410 if(g_init_trace
!= NULL
){
4411 lttvwindow_add_trace(new_tab
,
4415 LttvTraceset
*traceset
= new_tab
->traceset_info
->traceset
;
4416 SetTraceset(new_tab
, traceset
);
4418 /* Insert default viewers */
4420 LttvAttributeType type
;
4421 LttvAttributeName name
;
4422 LttvAttributeValue value
;
4423 LttvAttribute
*attribute
;
4425 LttvIAttribute
*attributes_global
=
4426 LTTV_IATTRIBUTE(lttv_global_attributes());
4428 g_assert(attribute
=
4429 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
4430 LTTV_IATTRIBUTE(attributes_global
),
4431 LTTV_VIEWER_CONSTRUCTORS
)));
4433 name
= g_quark_from_string("guievents");
4434 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
4436 if(type
== LTTV_POINTER
) {
4437 lttvwindow_viewer_constructor viewer_constructor
=
4438 (lttvwindow_viewer_constructor
)*value
.v_pointer
;
4439 insert_viewer(new_window
, viewer_constructor
);
4442 name
= g_quark_from_string("guicontrolflow");
4443 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
4445 if(type
== LTTV_POINTER
) {
4446 lttvwindow_viewer_constructor viewer_constructor
=
4447 (lttvwindow_viewer_constructor
)*value
.v_pointer
;
4448 insert_viewer(new_window
, viewer_constructor
);
4451 name
= g_quark_from_string("guistatistics");
4452 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
4454 if(type
== LTTV_POINTER
) {
4455 lttvwindow_viewer_constructor viewer_constructor
=
4456 (lttvwindow_viewer_constructor
)*value
.v_pointer
;
4457 insert_viewer(new_window
, viewer_constructor
);
4463 g_info("There are now : %d windows\n",g_slist_length(g_main_window_list
));
4467 /* Free the memory occupied by a tab structure
4471 void tab_destructor(Tab
* tab
)
4473 int i
, nb
, ref_count
;
4476 gtk_object_destroy(GTK_OBJECT(tab
->tooltips
));
4479 g_object_unref(tab
->attributes
);
4481 if(tab
->interrupted_state
)
4482 g_object_unref(tab
->interrupted_state
);
4485 if(tab
->traceset_info
->traceset_context
!= NULL
){
4486 //remove state update hooks
4487 lttv_state_remove_event_hooks(
4488 (LttvTracesetState
*)tab
->traceset_info
->
4490 lttv_context_fini(LTTV_TRACESET_CONTEXT(tab
->traceset_info
->
4492 g_object_unref(tab
->traceset_info
->traceset_context
);
4494 if(tab
->traceset_info
->traceset
!= NULL
) {
4495 nb
= lttv_traceset_number(tab
->traceset_info
->traceset
);
4496 for(i
= 0 ; i
< nb
; i
++) {
4497 trace
= lttv_traceset_get(tab
->traceset_info
->traceset
, i
);
4498 ref_count
= lttv_trace_get_ref_number(trace
);
4500 ltt_trace_close(lttv_trace(trace
));
4504 lttv_traceset_destroy(tab
->traceset_info
->traceset
);
4505 /* Remove the idle events requests processing function of the tab */
4506 g_idle_remove_by_data(tab
);
4508 g_slist_free(tab
->events_requests
);
4509 g_free(tab
->traceset_info
);
4514 /* Create a tab and insert it into the current main window
4517 Tab
* create_tab(MainWindow
* mw
, Tab
*copy_tab
,
4518 GtkNotebook
* notebook
, char * label
)
4523 //create a new tab data structure
4526 //construct and initialize the traceset_info
4527 tab
->traceset_info
= g_new(TracesetInfo
,1);
4530 tab
->traceset_info
->traceset
=
4531 lttv_traceset_copy(copy_tab
->traceset_info
->traceset
);
4533 tab
->traceset_info
->traceset
= lttv_traceset_new();
4537 lttv_attribute_write_xml(
4538 lttv_traceset_attribute(tab
->traceset_info
->traceset
),
4544 tab
->time_manager_lock
= FALSE
;
4545 tab
->current_time_manager_lock
= FALSE
;
4547 //FIXME copy not implemented in lower level
4548 tab
->traceset_info
->traceset_context
=
4549 g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
4550 g_assert(tab
->traceset_info
->traceset_context
!= NULL
);
4552 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
),
4553 tab
->traceset_info
->traceset
);
4554 //add state update hooks
4555 lttv_state_add_event_hooks(
4556 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
4558 //determine the current_time and time_window of the tab
4560 if(copy_tab
!= NULL
){
4561 tab
->time_window
= copy_tab
->time_window
;
4562 tab
->current_time
= copy_tab
->current_time
;
4564 tab
->time_window
.start_time
=
4565 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
4566 time_span
.start_time
;
4567 if(DEFAULT_TIME_WIDTH_S
<
4568 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
4569 time_span
.end_time
.tv_sec
)
4570 tmp_time
.tv_sec
= DEFAULT_TIME_WIDTH_S
;
4573 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
4574 time_span
.end_time
.tv_sec
;
4575 tmp_time
.tv_nsec
= 0;
4576 tab
->time_window
.time_width
= tmp_time
;
4577 tab
->current_time
.tv_sec
=
4578 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
4579 time_span
.start_time
.tv_sec
;
4580 tab
->current_time
.tv_nsec
=
4581 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
4582 time_span
.start_time
.tv_nsec
;
4585 tab
->attributes
= LTTV_IATTRIBUTE(g_object_new(LTTV_ATTRIBUTE_TYPE
, NULL
));
4586 tab
->interrupted_state
= g_object_new(LTTV_ATTRIBUTE_TYPE
, NULL
);
4588 tab
->vbox
= gtk_vbox_new(FALSE
, 2);
4589 tab
->viewer_container
= gtk_vbox_new(TRUE
, 2);
4590 tab
->scrollbar
= gtk_hscrollbar_new(NULL
);
4591 //tab->multivpaned = gtk_multi_vpaned_new();
4593 gtk_box_pack_start(GTK_BOX(tab
->vbox
),
4594 tab
->viewer_container
,
4596 TRUE
, /* Give the extra space to the child */
4597 0); /* No padding */
4599 /* Create the timebar */
4601 tab
->MTimebar
= gtk_hbox_new(FALSE
, 2);
4602 gtk_widget_show(tab
->MTimebar
);
4603 tab
->tooltips
= gtk_tooltips_new();
4605 tab
->MEventBox1a
= gtk_event_box_new();
4606 gtk_widget_show(tab
->MEventBox1a
);
4607 gtk_tooltips_set_tip(tab
->tooltips
, tab
->MEventBox1a
,
4608 "Paste Start and End Times Here", "");
4609 tab
->MText1a
= gtk_label_new("Time Frame ");
4610 gtk_widget_show(tab
->MText1a
);
4611 gtk_container_add(GTK_CONTAINER(tab
->MEventBox1a
), tab
->MText1a
);
4612 tab
->MEventBox1b
= gtk_event_box_new();
4613 gtk_widget_show(tab
->MEventBox1b
);
4614 gtk_tooltips_set_tip(tab
->tooltips
, tab
->MEventBox1b
,
4615 "Paste Start Time Here", "");
4616 tab
->MText1b
= gtk_label_new("start: ");
4617 gtk_widget_show(tab
->MText1b
);
4618 gtk_container_add(GTK_CONTAINER(tab
->MEventBox1b
), tab
->MText1b
);
4619 tab
->MText2
= gtk_label_new("s");
4620 gtk_widget_show(tab
->MText2
);
4621 tab
->MText3a
= gtk_label_new("ns");
4622 gtk_widget_show(tab
->MText3a
);
4623 tab
->MEventBox3b
= gtk_event_box_new();
4624 gtk_widget_show(tab
->MEventBox3b
);
4625 gtk_tooltips_set_tip(tab
->tooltips
, tab
->MEventBox3b
,
4626 "Paste End Time Here", "");
4627 tab
->MText3b
= gtk_label_new("end:");
4628 gtk_widget_show(tab
->MText3b
);
4629 gtk_container_add(GTK_CONTAINER(tab
->MEventBox3b
), tab
->MText3b
);
4630 tab
->MText4
= gtk_label_new("s");
4631 gtk_widget_show(tab
->MText4
);
4632 tab
->MText5a
= gtk_label_new("ns");
4633 gtk_widget_show(tab
->MText5a
);
4634 tab
->MEventBox5b
= gtk_event_box_new();
4635 gtk_widget_show(tab
->MEventBox5b
);
4636 gtk_tooltips_set_tip(tab
->tooltips
, tab
->MEventBox5b
,
4637 "Paste Current Time Here", "");
4638 tab
->MText5b
= gtk_label_new("Current Time:");
4639 gtk_widget_show(tab
->MText5b
);
4640 gtk_container_add(GTK_CONTAINER(tab
->MEventBox5b
), tab
->MText5b
);
4641 tab
->MText6
= gtk_label_new("s");
4642 gtk_widget_show(tab
->MText6
);
4643 tab
->MText7
= gtk_label_new("ns");
4644 gtk_widget_show(tab
->MText7
);
4646 tab
->MEntry1
= gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4647 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab
->MEntry1
),0);
4648 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab
->MEntry1
),TRUE
);
4649 gtk_widget_show(tab
->MEntry1
);
4650 tab
->MEntry2
= gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4651 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab
->MEntry2
),0);
4652 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab
->MEntry2
),TRUE
);
4653 gtk_widget_show(tab
->MEntry2
);
4654 tab
->MEntry3
= gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4655 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab
->MEntry3
),0);
4656 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab
->MEntry3
),TRUE
);
4657 gtk_widget_show(tab
->MEntry3
);
4658 tab
->MEntry4
= gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4659 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab
->MEntry4
),0);
4660 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab
->MEntry4
),TRUE
);
4661 gtk_widget_show(tab
->MEntry4
);
4662 tab
->MEntry5
= gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4663 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab
->MEntry5
),0);
4664 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab
->MEntry5
),TRUE
);
4665 gtk_widget_show(tab
->MEntry5
);
4666 tab
->MEntry6
= gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4667 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab
->MEntry6
),0);
4668 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab
->MEntry6
),TRUE
);
4669 gtk_widget_show(tab
->MEntry6
);
4672 GtkWidget
*temp_widget
;
4674 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEventBox1a
, FALSE
,
4676 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEventBox1b
, FALSE
,
4678 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEntry1
, FALSE
, FALSE
, 0);
4679 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MText2
, FALSE
, FALSE
, 0);
4680 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEntry2
, FALSE
, FALSE
, 0);
4681 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MText3a
, FALSE
, FALSE
, 0);
4682 temp_widget
= gtk_vseparator_new();
4683 gtk_widget_show(temp_widget
);
4684 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), temp_widget
, FALSE
, FALSE
, 0);
4685 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEventBox3b
, FALSE
,
4687 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEntry3
, FALSE
, FALSE
, 0);
4688 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MText4
, FALSE
, FALSE
, 0);
4689 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEntry4
, FALSE
, FALSE
, 0);
4690 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MText5a
, FALSE
, FALSE
, 0);
4691 temp_widget
= gtk_vseparator_new();
4692 gtk_widget_show(temp_widget
);
4693 gtk_box_pack_end (GTK_BOX (tab
->MTimebar
), tab
->MText7
, FALSE
, FALSE
, 0);
4694 gtk_box_pack_end (GTK_BOX (tab
->MTimebar
), tab
->MEntry6
, FALSE
, FALSE
, 0);
4695 gtk_box_pack_end (GTK_BOX (tab
->MTimebar
), tab
->MText6
, FALSE
, FALSE
, 0);
4696 gtk_box_pack_end (GTK_BOX (tab
->MTimebar
), tab
->MEntry5
, FALSE
, FALSE
, 0);
4697 gtk_box_pack_end (GTK_BOX (tab
->MTimebar
), tab
->MEventBox5b
, FALSE
,
4699 gtk_box_pack_end (GTK_BOX (tab
->MTimebar
), temp_widget
, FALSE
, FALSE
, 0);
4702 //GtkWidget *test = gtk_button_new_with_label("drop");
4703 //gtk_button_set_relief(GTK_BUTTON(test), GTK_RELIEF_NONE);
4704 //gtk_widget_show(test);
4705 //gtk_box_pack_end(GTK_BOX (tab->MTimebar), test, FALSE, FALSE, 0);
4706 //gtk_widget_add_events(tab->MText1, GDK_ALL_EVENTS_MASK);//GDK_BUTTON_PRESS_MASK);
4707 /*GtkWidget *event_box = gtk_event_box_new();
4708 gtk_widget_show(event_box);
4709 gtk_tooltips_set_tip(tooltips, event_box,
4710 "Paste Current Time Here", "");
4711 gtk_box_pack_end(GTK_BOX (tab->MTimebar), event_box, FALSE, FALSE, 0);
4712 GtkWidget *test = gtk_label_new("drop");
4713 gtk_container_add(GTK_CONTAINER(event_box), test);
4714 gtk_widget_show(test);
4715 g_signal_connect (G_OBJECT(event_box),
4716 "button-press-event",
4717 G_CALLBACK (on_MText1_paste),
4721 g_signal_connect (G_OBJECT(tab
->MEventBox1a
),
4722 "button-press-event",
4723 G_CALLBACK (on_MEventBox1a_paste
),
4726 g_signal_connect (G_OBJECT(tab
->MEventBox1b
),
4727 "button-press-event",
4728 G_CALLBACK (on_MEventBox1b_paste
),
4730 g_signal_connect (G_OBJECT(tab
->MEventBox3b
),
4731 "button-press-event",
4732 G_CALLBACK (on_MEventBox3b_paste
),
4734 g_signal_connect (G_OBJECT(tab
->MEventBox5b
),
4735 "button-press-event",
4736 G_CALLBACK (on_MEventBox5b_paste
),
4740 gtk_box_pack_end(GTK_BOX(tab
->vbox
),
4742 FALSE
, /* Do not expand */
4743 FALSE
, /* Fill has no effect here (expand false) */
4744 0); /* No padding */
4746 gtk_box_pack_end(GTK_BOX(tab
->vbox
),
4748 FALSE
, /* Do not expand */
4749 FALSE
, /* Fill has no effect here (expand false) */
4750 0); /* No padding */
4752 g_object_set_data(G_OBJECT(tab
->viewer_container
), "focused_viewer", NULL
);
4758 // Display a label with a X
4759 GtkWidget *w_hbox = gtk_hbox_new(FALSE, 4);
4760 GtkWidget *w_label = gtk_label_new (label);
4761 GtkWidget *pixmap = create_pixmap(GTK_WIDGET(notebook), "close.png");
4762 GtkWidget *w_button = gtk_button_new ();
4763 gtk_container_add(GTK_CONTAINER(w_button), pixmap);
4764 //GtkWidget *w_button = gtk_button_new_with_label("x");
4766 gtk_button_set_relief(GTK_BUTTON(w_button), GTK_RELIEF_NONE);
4768 gtk_box_pack_start(GTK_BOX(w_hbox), w_label, TRUE, TRUE, 0);
4769 gtk_box_pack_end(GTK_BOX(w_hbox), w_button, FALSE,
4772 g_signal_connect_swapped (w_button, "clicked",
4773 G_CALLBACK (on_close_tab_X_clicked),
4776 gtk_widget_set_state(w_button, GTK_STATE_ACTIVE);
4778 gtk_widget_show (w_label);
4779 gtk_widget_show (pixmap);
4780 gtk_widget_show (w_button);
4781 gtk_widget_show (w_hbox);
4783 tab->label = w_hbox;
4787 tab
->label
= gtk_label_new (label
);
4789 gtk_widget_show(tab
->label
);
4790 gtk_widget_show(tab
->scrollbar
);
4791 gtk_widget_show(tab
->viewer_container
);
4792 gtk_widget_show(tab
->vbox
);
4793 //gtk_widget_show(tab->multivpaned);
4796 /* Start with empty events requests list */
4797 tab
->events_requests
= NULL
;
4798 tab
->events_request_pending
= FALSE
;
4800 g_object_set_data_full(
4801 G_OBJECT(tab
->vbox
),
4804 (GDestroyNotify
)tab_destructor
);
4806 g_signal_connect(G_OBJECT(tab
->scrollbar
), "value-changed",
4807 G_CALLBACK(scroll_value_changed_cb
), tab
);
4809 g_signal_connect ((gpointer
) tab
->MEntry1
, "value-changed",
4810 G_CALLBACK (on_MEntry1_value_changed
),
4812 g_signal_connect ((gpointer
) tab
->MEntry2
, "value-changed",
4813 G_CALLBACK (on_MEntry2_value_changed
),
4815 g_signal_connect ((gpointer
) tab
->MEntry3
, "value-changed",
4816 G_CALLBACK (on_MEntry3_value_changed
),
4818 g_signal_connect ((gpointer
) tab
->MEntry4
, "value-changed",
4819 G_CALLBACK (on_MEntry4_value_changed
),
4821 g_signal_connect ((gpointer
) tab
->MEntry5
, "value-changed",
4822 G_CALLBACK (on_MEntry5_value_changed
),
4824 g_signal_connect ((gpointer
) tab
->MEntry6
, "value-changed",
4825 G_CALLBACK (on_MEntry6_value_changed
),
4828 //g_signal_connect(G_OBJECT(tab->scrollbar), "changed",
4829 // G_CALLBACK(scroll_value_changed_cb), tab);
4832 //insert tab into notebook
4833 gtk_notebook_append_page(notebook
,
4836 list
= gtk_container_get_children(GTK_CONTAINER(notebook
));
4837 gtk_notebook_set_current_page(notebook
,g_list_length(list
)-1);
4838 // always show : not if(g_list_length(list)>1)
4839 gtk_notebook_set_show_tabs(notebook
, TRUE
);
4845 * execute_events_requests
4847 * Idle function that executes the pending requests for a tab.
4849 * @return return value : TRUE : keep the idle function, FALSE : remove it.
4851 gboolean
execute_events_requests(Tab
*tab
)
4853 return ( lttvwindow_process_pending_requests(tab
) );