1 /* This file is part of the Linux Trace Toolkit viewer
2 * Copyright (C) 2003-2004 XangXiu Yang, Mathieu Desnoyers
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License Version 2 as
6 * published by the Free Software Foundation;
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place - Suite 330, Boston,
23 #include <limits.h> // for PATH_MAX
31 #include "callbacks.h"
32 #include "interface.h"
34 #include <ltt/trace.h>
35 #include <ltt/facility.h>
37 #include <ltt/event.h>
38 #include <lttv/lttv.h>
39 #include <lttv/module.h>
40 #include <lttv/iattribute.h>
41 #include <lttv/stats.h>
42 #include <lttvwindow/mainwindow.h>
43 #include <lttvwindow/mainwindow-private.h>
44 #include <lttvwindow/menu.h>
45 #include <lttvwindow/toolbar.h>
46 #include <lttvwindow/lttvwindow.h>
47 #include <lttvwindow/lttvwindowtraces.h>
48 #include <lttvwindow/gtkdirsel.h>
49 #include <lttvwindow/lttvfilter.h>
52 #define DEFAULT_TIME_WIDTH_S 1
53 #define CLIP_BUF 256 // size of clipboard buffer
55 extern LttvTrace
*g_init_trace
;
58 /** Array containing instanced objects. */
59 extern GSList
* g_main_window_list
;
61 /** MD : keep old directory. */
62 static char remember_plugins_dir
[PATH_MAX
] = "";
63 static char remember_trace_dir
[PATH_MAX
] = "";
66 MainWindow
* get_window_data_struct(GtkWidget
* widget
);
67 char * get_load_module(char ** load_module_name
, int nb_module
);
68 char * get_unload_module(char ** loaded_module_name
, int nb_module
);
69 char * get_remove_trace(char ** all_trace_name
, int nb_trace
);
70 char * get_selection(char ** all_name
, int nb
, char *title
, char * column_title
);
71 gboolean
get_filter_selection(LttvTracesetSelector
*s
, char *title
, char * column_title
);
72 Tab
* create_tab(MainWindow
* mw
, Tab
*copy_tab
,
73 GtkNotebook
* notebook
, char * label
);
75 static void insert_viewer(GtkWidget
* widget
, lttvwindow_viewer_constructor constructor
);
76 void update_filter(LttvTracesetSelector
*s
, GtkTreeStore
*store
);
78 void checkbox_changed(GtkTreeView
*treeview
,
80 GtkTreeViewColumn
*arg2
,
82 void remove_trace_from_traceset_selector(GtkWidget
* paned
, unsigned i
);
83 void add_trace_into_traceset_selector(GtkWidget
* paned
, LttTrace
* trace
);
84 Tab
*create_new_tab(GtkWidget
* widget
, gpointer user_data
);
86 LttvTracesetSelector
* construct_traceset_selector(LttvTraceset
* traceset
);
88 static gboolean
lttvwindow_process_pending_requests(Tab
*tab
);
102 /* Construct a selector(filter), which will be associated with a viewer,
103 * and provides an interface for user to select interested events and traces
106 LttvTracesetSelector
* construct_traceset_selector(LttvTraceset
* traceset
)
108 LttvTracesetSelector
* s
;
109 LttvTraceSelector
* trace
;
110 LttvTracefileSelector
* tracefile
;
111 LttvEventtypeSelector
* eventtype
;
113 int nb_trace
, nb_tracefile
, nb_control
, nb_per_cpu
, nb_facility
, nb_event
;
120 s
= lttv_traceset_selector_new(lttv_traceset_name(traceset
));
121 nb_trace
= lttv_traceset_number(traceset
);
122 for(i
=0;i
<nb_trace
;i
++){
123 trace_v
= lttv_traceset_get(traceset
, i
);
124 t
= lttv_trace(trace_v
);
125 trace
= lttv_trace_selector_new(t
);
126 lttv_traceset_selector_trace_add(s
, trace
);
128 nb_facility
= ltt_trace_facility_number(t
);
129 for(k
=0;k
<nb_facility
;k
++){
130 fac
= ltt_trace_facility_get(t
,k
);
131 nb_event
= (int) ltt_facility_eventtype_number(fac
);
132 for(m
=0;m
<nb_event
;m
++){
133 et
= ltt_facility_eventtype_get(fac
,m
);
134 eventtype
= lttv_eventtype_selector_new(et
);
135 lttv_trace_selector_eventtype_add(trace
, eventtype
);
139 nb_control
= ltt_trace_control_tracefile_number(t
);
140 nb_per_cpu
= ltt_trace_per_cpu_tracefile_number(t
);
141 nb_tracefile
= nb_control
+ nb_per_cpu
;
143 for(j
= 0 ; j
< nb_tracefile
; j
++) {
145 tf
= ltt_trace_control_tracefile_get(t
, j
);
147 tf
= ltt_trace_per_cpu_tracefile_get(t
, j
- nb_control
);
148 tracefile
= lttv_tracefile_selector_new(tf
);
149 lttv_trace_selector_tracefile_add(trace
, tracefile
);
150 lttv_eventtype_selector_copy(trace
, tracefile
);
156 /* Pasting routines */
158 static void MEventBox1a_receive(GtkClipboard
*clipboard
,
162 if(text
== NULL
) return;
163 Tab
*tab
= (Tab
*)data
;
164 gchar buffer
[CLIP_BUF
];
165 gchar
*ptr
= buffer
, *ptr_ssec
, *ptr_snsec
, *ptr_esec
, *ptr_ensec
;
167 strncpy(buffer
, text
, CLIP_BUF
);
170 while(!isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
171 /* remove leading junk */
173 while(isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
174 /* read all the first number */
178 while(!isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
179 /* remove leading junk */
181 while(isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
182 /* read all the first number */
186 while(!isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
187 /* remove leading junk */
189 while(isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
190 /* read all the first number */
194 while(!isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
195 /* remove leading junk */
197 while(isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
198 /* read all the first number */
201 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry1
),
202 (double)strtoul(ptr_ssec
, NULL
, 10));
203 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry2
),
204 (double)strtoul(ptr_snsec
, NULL
, 10));
205 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry3
),
206 (double)strtoul(ptr_esec
, NULL
, 10));
207 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry4
),
208 (double)strtoul(ptr_ensec
, NULL
, 10));
211 static gboolean
on_MEventBox1a_paste(GtkWidget
*widget
, GdkEventButton
*event
,
214 Tab
*tab
= (Tab
*)data
;
216 GtkClipboard
*clip
= gtk_clipboard_get_for_display(gdk_display_get_default(),
217 GDK_SELECTION_PRIMARY
);
218 gtk_clipboard_request_text(clip
,
219 (GtkClipboardTextReceivedFunc
)MEventBox1a_receive
,
226 static void MEventBox1b_receive(GtkClipboard
*clipboard
,
230 if(text
== NULL
) return;
231 Tab
*tab
= (Tab
*)data
;
232 gchar buffer
[CLIP_BUF
];
233 gchar
*ptr
= buffer
, *ptr_sec
, *ptr_nsec
;
235 strncpy(buffer
, text
, CLIP_BUF
);
237 while(!isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
238 /* remove leading junk */
240 while(isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
241 /* read all the first number */
245 while(!isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
246 /* remove leading junk */
248 while(isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
249 /* read all the first number */
252 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry1
),
253 (double)strtoul(ptr_sec
, NULL
, 10));
254 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry2
),
255 (double)strtoul(ptr_nsec
, NULL
, 10));
259 static gboolean
on_MEventBox1b_paste(GtkWidget
*widget
, GdkEventButton
*event
,
262 Tab
*tab
= (Tab
*)data
;
264 GtkClipboard
*clip
= gtk_clipboard_get_for_display(gdk_display_get_default(),
265 GDK_SELECTION_PRIMARY
);
266 gtk_clipboard_request_text(clip
,
267 (GtkClipboardTextReceivedFunc
)MEventBox1b_receive
,
273 static void MEventBox3b_receive(GtkClipboard
*clipboard
,
277 if(text
== NULL
) return;
278 Tab
*tab
= (Tab
*)data
;
279 gchar buffer
[CLIP_BUF
];
280 gchar
*ptr
= buffer
, *ptr_sec
, *ptr_nsec
;
282 strncpy(buffer
, text
, CLIP_BUF
);
284 while(!isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
285 /* remove leading junk */
287 while(isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
288 /* read all the first number */
292 while(!isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
293 /* remove leading junk */
295 while(isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
296 /* read all the first number */
299 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry3
),
300 (double)strtoul(ptr_sec
, NULL
, 10));
301 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry4
),
302 (double)strtoul(ptr_nsec
, NULL
, 10));
306 static gboolean
on_MEventBox3b_paste(GtkWidget
*widget
, GdkEventButton
*event
,
309 Tab
*tab
= (Tab
*)data
;
311 GtkClipboard
*clip
= gtk_clipboard_get_for_display(gdk_display_get_default(),
312 GDK_SELECTION_PRIMARY
);
313 gtk_clipboard_request_text(clip
,
314 (GtkClipboardTextReceivedFunc
)MEventBox3b_receive
,
320 static void MEventBox5b_receive(GtkClipboard
*clipboard
,
324 if(text
== NULL
) return;
325 Tab
*tab
= (Tab
*)data
;
326 gchar buffer
[CLIP_BUF
];
327 gchar
*ptr
= buffer
, *ptr_sec
, *ptr_nsec
;
329 strncpy(buffer
, text
, CLIP_BUF
);
331 while(!isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
332 /* remove leading junk */
334 while(isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
335 /* read all the first number */
339 while(!isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
340 /* remove leading junk */
342 while(isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
343 /* read all the first number */
346 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry5
),
347 (double)strtoul(ptr_sec
, NULL
, 10));
348 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry6
),
349 (double)strtoul(ptr_nsec
, NULL
, 10));
353 static gboolean
on_MEventBox5b_paste(GtkWidget
*widget
, GdkEventButton
*event
,
356 Tab
*tab
= (Tab
*)data
;
358 GtkClipboard
*clip
= gtk_clipboard_get_for_display(gdk_display_get_default(),
359 GDK_SELECTION_PRIMARY
);
360 gtk_clipboard_request_text(clip
,
361 (GtkClipboardTextReceivedFunc
)MEventBox5b_receive
,
367 static gboolean
viewer_grab_focus(GtkWidget
*widget
, GdkEventButton
*event
,
370 GtkWidget
*viewer
= GTK_WIDGET(data
);
371 GtkWidget
*viewer_container
= gtk_widget_get_parent(viewer
);
373 g_debug("FOCUS GRABBED");
374 g_object_set_data(G_OBJECT(viewer_container
), "focused_viewer", viewer
);
379 static void connect_focus_recursive(GtkWidget
*widget
,
382 if(GTK_IS_CONTAINER(widget
)) {
383 gtk_container_forall(GTK_CONTAINER(widget
),
384 (GtkCallback
)connect_focus_recursive
,
388 if(GTK_IS_TREE_VIEW(widget
)) {
389 gtk_tree_view_set_headers_clickable(widget
, TRUE
);
391 gtk_widget_add_events(widget
, GDK_BUTTON_PRESS_MASK
);
392 g_signal_connect (G_OBJECT(widget
),
393 "button-press-event",
394 G_CALLBACK (viewer_grab_focus
),
398 /* insert_viewer function constructs an instance of a viewer first,
399 * then inserts the widget of the instance into the container of the
404 insert_viewer_wrap(GtkWidget
*menuitem
, gpointer user_data
)
408 insert_viewer((GtkWidget
*)menuitem
, (lttvwindow_viewer_constructor
)user_data
);
409 // selected_hook(&val);
413 /* internal functions */
414 void insert_viewer(GtkWidget
* widget
, lttvwindow_viewer_constructor constructor
)
416 GtkWidget
* viewer_container
;
417 MainWindow
* mw_data
= get_window_data_struct(widget
);
418 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
420 LttvTracesetSelector
* s
;
421 TimeInterval
* time_interval
;
422 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
423 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
427 tab
= create_new_tab(widget
, NULL
);
429 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
432 viewer_container
= tab
->viewer_container
;
434 s
= construct_traceset_selector(tab
->traceset_info
->traceset
);
435 viewer
= (GtkWidget
*)constructor(tab
);
438 //gtk_multivpaned_widget_add(GTK_MULTIVPANED(multivpaned), viewer);
440 gtk_box_pack_end(GTK_BOX(viewer_container
),
446 /* We want to connect the viewer_grab_focus to EVERY
447 * child of this widget. The little trick is to get each child
448 * of each GTK_CONTAINER, even subchildren.
450 connect_focus_recursive(viewer
, viewer
);
455 * Function to set/update traceset for the viewers
456 * @param tab viewer's tab
457 * @param traceset traceset of the main window.
459 * 0 : traceset updated
460 * 1 : no traceset hooks to update; not an error.
463 int SetTraceset(Tab
* tab
, LttvTraceset
*traceset
)
465 LttvTracesetContext
*tsc
=
466 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
467 TimeInterval time_span
= tsc
->time_span
;
468 TimeWindow new_time_window
;
469 LttTime new_current_time
;
471 /* Set the tab's time window and current time if
473 if(ltt_time_compare(tab
->time_window
.start_time
, time_span
.start_time
) < 0
474 || ltt_time_compare(tab
->time_window
.end_time
,
475 time_span
.end_time
) > 0) {
476 new_time_window
.start_time
= time_span
.start_time
;
478 new_current_time
= time_span
.start_time
;
482 if(DEFAULT_TIME_WIDTH_S
< time_span
.end_time
.tv_sec
)
483 tmp_time
.tv_sec
= DEFAULT_TIME_WIDTH_S
;
485 tmp_time
.tv_sec
= time_span
.end_time
.tv_sec
;
486 tmp_time
.tv_nsec
= 0;
487 new_time_window
.time_width
= tmp_time
;
488 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
489 new_time_window
.time_width
) ;
491 time_change_manager(tab
, new_time_window
);
492 current_time_change_manager(tab
, new_current_time
);
496 GtkAdjustment
*adjustment
= gtk_range_get_adjustment(GTK_RANGE(tab
->scrollbar
));
497 LttTime upper
= ltt_time_sub(time_span
.end_time
, time_span
.start_time
);
499 g_object_set(G_OBJECT(adjustment
),
503 ltt_time_to_double(upper
)
504 * NANOSECONDS_PER_SECOND
, /* upper */
506 ltt_time_to_double(tab
->time_window
.time_width
)
507 / SCROLL_STEP_PER_PAGE
508 * NANOSECONDS_PER_SECOND
, /* step increment */
510 ltt_time_to_double(tab
->time_window
.time_width
)
511 * NANOSECONDS_PER_SECOND
, /* page increment */
513 ltt_time_to_double(tab
->time_window
.time_width
)
514 * NANOSECONDS_PER_SECOND
, /* page size */
516 gtk_adjustment_changed(adjustment
);
518 g_object_set(G_OBJECT(adjustment
),
521 ltt_time_sub(tab
->time_window
.start_time
, time_span
.start_time
))
522 * NANOSECONDS_PER_SECOND
, /* value */
524 gtk_adjustment_value_changed(adjustment
);
526 /* set the time bar. The value callbacks will change their nsec themself */
528 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry1
),
529 (double)time_span
.start_time
.tv_sec
,
530 (double)time_span
.end_time
.tv_sec
);
533 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry3
),
534 (double)time_span
.start_time
.tv_sec
,
535 (double)time_span
.end_time
.tv_sec
);
537 /* current seconds */
538 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry5
),
539 (double)time_span
.start_time
.tv_sec
,
540 (double)time_span
.end_time
.tv_sec
);
543 /* Finally, call the update hooks of the viewers */
545 LttvAttributeValue value
;
549 g_assert( lttv_iattribute_find_by_path(tab
->attributes
,
550 "hooks/updatetraceset", LTTV_POINTER
, &value
));
552 tmp
= (LttvHooks
*)*(value
.v_pointer
);
553 if(tmp
== NULL
) retval
= 1;
554 else lttv_hooks_call(tmp
,traceset
);
561 * Function to set/update filter for the viewers
562 * @param tab viewer's tab
563 * @param filter filter of the main window.
566 * 0 : filters updated
567 * 1 : no filter hooks to update; not an error.
570 int SetFilter(Tab
* tab
, gpointer filter
)
573 LttvAttributeValue value
;
575 g_assert(lttv_iattribute_find_by_path(tab
->attributes
,
576 "hooks/updatefilter", LTTV_POINTER
, &value
));
578 tmp
= (LttvHooks
*)*(value
.v_pointer
);
580 if(tmp
== NULL
) return 1;
581 lttv_hooks_call(tmp
,filter
);
589 * Function to redraw each viewer belonging to the current tab
590 * @param tab viewer's tab
593 void update_traceset(Tab
*tab
)
595 LttvAttributeValue value
;
597 g_assert(lttv_iattribute_find_by_path(tab
->attributes
,
598 "hooks/updatetraceset", LTTV_POINTER
, &value
));
599 tmp
= (LttvHooks
*)*(value
.v_pointer
);
600 if(tmp
== NULL
) return;
601 lttv_hooks_call(tmp
, NULL
);
605 /* get_label function is used to get user input, it displays an input
606 * box, which allows user to input a string
609 void get_label_string (GtkWidget
* text
, gchar
* label
)
611 GtkEntry
* entry
= (GtkEntry
*)text
;
612 if(strlen(gtk_entry_get_text(entry
))!=0)
613 strcpy(label
,gtk_entry_get_text(entry
));
616 gboolean
get_label(MainWindow
* mw
, gchar
* str
, gchar
* dialogue_title
, gchar
* label_str
)
618 GtkWidget
* dialogue
;
623 dialogue
= gtk_dialog_new_with_buttons(dialogue_title
,NULL
,
625 GTK_STOCK_OK
,GTK_RESPONSE_ACCEPT
,
626 GTK_STOCK_CANCEL
,GTK_RESPONSE_REJECT
,
629 label
= gtk_label_new(label_str
);
630 gtk_widget_show(label
);
632 text
= gtk_entry_new();
633 gtk_widget_show(text
);
635 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialogue
)->vbox
), label
,TRUE
, TRUE
,0);
636 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialogue
)->vbox
), text
,FALSE
, FALSE
,0);
638 id
= gtk_dialog_run(GTK_DIALOG(dialogue
));
640 case GTK_RESPONSE_ACCEPT
:
641 get_label_string(text
,str
);
642 gtk_widget_destroy(dialogue
);
644 case GTK_RESPONSE_REJECT
:
646 gtk_widget_destroy(dialogue
);
653 /* get_window_data_struct function is actually a lookup function,
654 * given a widget which is in the tree of the main window, it will
655 * return the MainWindow data structure associated with main window
658 MainWindow
* get_window_data_struct(GtkWidget
* widget
)
661 MainWindow
* mw_data
;
663 mw
= lookup_widget(widget
, "MWindow");
665 g_printf("Main window does not exist\n");
669 mw_data
= (MainWindow
*) g_object_get_data(G_OBJECT(mw
),"main_window_data");
671 g_printf("Main window data does not exist\n");
678 /* create_new_window function, just constructs a new main window
681 void create_new_window(GtkWidget
* widget
, gpointer user_data
, gboolean clone
)
683 MainWindow
* parent
= get_window_data_struct(widget
);
686 g_printf("Clone : use the same traceset\n");
687 construct_main_window(parent
);
689 g_printf("Empty : traceset is set to NULL\n");
690 construct_main_window(NULL
);
694 /* Get the currently focused viewer.
695 * If no viewer is focused, use the first one.
697 * If no viewer available, return NULL.
699 GtkWidget
*viewer_container_focus(GtkWidget
*container
)
703 widget
= (GtkWidget
*)g_object_get_data(G_OBJECT(container
),
707 g_debug("no widget focused");
708 GList
*children
= gtk_container_get_children(GTK_CONTAINER(container
));
711 widget
= GTK_WIDGET(children
->data
);
712 g_object_set_data(G_OBJECT(container
),
722 gint
viewer_container_position(GtkWidget
*container
, GtkWidget
*child
)
725 if(child
== NULL
) return -1;
728 GValue value
= { 0, };
729 g_value_init(&value
, G_TYPE_INT
);
730 gtk_container_child_get_property(GTK_CONTAINER(container
),
734 pos
= g_value_get_int(&value
);
740 /* move_*_viewer functions move the selected view up/down in
744 void move_down_viewer(GtkWidget
* widget
, gpointer user_data
)
746 MainWindow
* mw
= get_window_data_struct(widget
);
747 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
749 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
750 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
756 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
759 //gtk_multivpaned_widget_move_up(GTK_MULTIVPANED(tab->multivpaned));
761 /* change the position in the vbox */
762 GtkWidget
*focus_widget
;
764 focus_widget
= viewer_container_focus(tab
->viewer_container
);
765 position
= viewer_container_position(tab
->viewer_container
, focus_widget
);
768 /* can move up one position */
769 gtk_box_reorder_child(GTK_BOX(tab
->viewer_container
),
776 void move_up_viewer(GtkWidget
* widget
, gpointer user_data
)
778 MainWindow
* mw
= get_window_data_struct(widget
);
779 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
781 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
782 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
788 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
791 //gtk_multivpaned_widget_move_down(GTK_MULTIVPANED(tab->multivpaned));
792 /* change the position in the vbox */
793 GtkWidget
*focus_widget
;
795 focus_widget
= viewer_container_focus(tab
->viewer_container
);
796 position
= viewer_container_position(tab
->viewer_container
, focus_widget
);
800 g_list_length(gtk_container_get_children(
801 GTK_CONTAINER(tab
->viewer_container
)))-1
803 /* can move down one position */
804 gtk_box_reorder_child(GTK_BOX(tab
->viewer_container
),
812 /* delete_viewer deletes the selected viewer in the current tab
815 void delete_viewer(GtkWidget
* widget
, gpointer user_data
)
817 MainWindow
* mw
= get_window_data_struct(widget
);
818 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
820 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
821 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
827 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
830 //gtk_multivpaned_widget_delete(GTK_MULTIVPANED(tab->multivpaned));
832 GtkWidget
*focus_widget
= viewer_container_focus(tab
->viewer_container
);
834 if(focus_widget
!= NULL
)
835 gtk_widget_destroy(focus_widget
);
837 g_object_set_data(G_OBJECT(tab
->viewer_container
), "focused_viewer", NULL
);
841 /* open_traceset will open a traceset saved in a file
842 * Right now, it is not finished yet, (not working)
846 void open_traceset(GtkWidget
* widget
, gpointer user_data
)
850 LttvTraceset
* traceset
;
851 MainWindow
* mw_data
= get_window_data_struct(widget
);
852 GtkFileSelection
* file_selector
=
853 (GtkFileSelection
*)gtk_file_selection_new("Select a traceset");
855 gtk_file_selection_hide_fileop_buttons(file_selector
);
857 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
859 case GTK_RESPONSE_ACCEPT
:
860 case GTK_RESPONSE_OK
:
861 dir
= gtk_file_selection_get_selections (file_selector
);
862 traceset
= lttv_traceset_load(dir
[0]);
863 g_printf("Open a trace set %s\n", dir
[0]);
866 case GTK_RESPONSE_REJECT
:
867 case GTK_RESPONSE_CANCEL
:
869 gtk_widget_destroy((GtkWidget
*)file_selector
);
875 static void events_request_free(EventsRequest
*events_request
)
877 if(events_request
== NULL
) return;
879 if(events_request
->start_position
!= NULL
)
880 lttv_traceset_context_position_destroy(events_request
->start_position
);
881 if(events_request
->end_position
!= NULL
)
882 lttv_traceset_context_position_destroy(events_request
->end_position
);
883 if(events_request
->hooks
!= NULL
)
884 g_array_free(events_request
->hooks
, TRUE
);
885 if(events_request
->before_chunk_traceset
!= NULL
)
886 lttv_hooks_destroy(events_request
->before_chunk_traceset
);
887 if(events_request
->before_chunk_trace
!= NULL
)
888 lttv_hooks_destroy(events_request
->before_chunk_trace
);
889 if(events_request
->before_chunk_tracefile
!= NULL
)
890 lttv_hooks_destroy(events_request
->before_chunk_tracefile
);
891 if(events_request
->event
!= NULL
)
892 lttv_hooks_destroy(events_request
->event
);
893 if(events_request
->event_by_id
!= NULL
)
894 lttv_hooks_by_id_destroy(events_request
->event_by_id
);
895 if(events_request
->after_chunk_tracefile
!= NULL
)
896 lttv_hooks_destroy(events_request
->after_chunk_tracefile
);
897 if(events_request
->after_chunk_trace
!= NULL
)
898 lttv_hooks_destroy(events_request
->after_chunk_trace
);
899 if(events_request
->after_chunk_traceset
!= NULL
)
900 lttv_hooks_destroy(events_request
->after_chunk_traceset
);
901 if(events_request
->before_request
!= NULL
)
902 lttv_hooks_destroy(events_request
->before_request
);
903 if(events_request
->after_request
!= NULL
)
904 lttv_hooks_destroy(events_request
->after_request
);
906 g_free(events_request
);
911 /* lttvwindow_process_pending_requests
913 * This internal function gets called by g_idle, taking care of the pending
914 * requests. It is responsible for concatenation of time intervals and position
915 * requests. It does it with the following algorithm organizing process traceset
916 * calls. Here is the detailed description of the way it works :
918 * - Events Requests Servicing Algorithm
920 * Data structures necessary :
922 * List of requests added to context : list_in
923 * List of requests not added to context : list_out
928 * list_out : many events requests
930 * FIXME : insert rest of algorithm here
934 #define list_out tab->events_requests
936 gboolean
lttvwindow_process_pending_requests(Tab
*tab
)
938 unsigned max_nb_events
;
942 LttvTracesetContext
*tsc
;
943 LttvTracefileContext
*tfc
;
944 GSList
*list_in
= NULL
;
948 LttvTracesetContextPosition
*end_position
;
951 g_critical("Foreground processing : tab does not exist. Processing removed.");
955 /* There is no events requests pending : we should never have been called! */
956 g_assert(g_slist_length(list_out
) != 0);
958 tsc
= LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
960 //set the cursor to be X shape, indicating that the computer is busy in doing its job
962 new = gdk_cursor_new(GDK_X_CURSOR
);
963 widget
= lookup_widget(tab
->mw
->mwindow
, "MToolbar1");
964 win
= gtk_widget_get_parent_window(widget
);
965 gdk_window_set_cursor(win
, new);
966 gdk_cursor_unref(new);
967 gdk_window_stick(win
);
968 gdk_window_unstick(win
);
971 g_debug("SIZE events req len : %d", g_slist_length(list_out
));
973 /* Preliminary check for no trace in traceset */
974 /* Unregister the routine if empty, empty list_out too */
975 if(lttv_traceset_number(tsc
->ts
) == 0) {
977 /* - For each req in list_out */
978 GSList
*iter
= list_out
;
980 while(iter
!= NULL
) {
982 gboolean remove
= FALSE
;
983 gboolean free_data
= FALSE
;
984 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
986 /* - Call end request for req */
987 if(events_request
->servicing
== TRUE
)
988 lttv_hooks_call(events_request
->after_request
, (gpointer
)tsc
);
990 /* - remove req from list_out */
991 /* Destroy the request */
998 GSList
*remove_iter
= iter
;
1000 iter
= g_slist_next(iter
);
1001 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
1002 list_out
= g_slist_remove_link(list_out
, remove_iter
);
1003 } else { // not remove
1004 iter
= g_slist_next(iter
);
1009 /* 0.1 Lock Traces */
1014 iter_trace
<lttv_traceset_number(tsc
->ts
);
1016 LttvTrace
*trace_v
= lttv_traceset_get(tsc
->ts
, iter_trace
);
1018 if(lttvwindowtraces_lock(trace_v
) != 0) {
1019 g_critical("Foreground processing : Unable to get trace lock");
1020 return TRUE
; /* Cannot get lock, try later */
1025 /* 0.2 Seek tracefiles positions to context position */
1026 lttv_process_traceset_synchronize_tracefiles(tsc
);
1029 /* Events processing algorithm implementation */
1030 /* Warning : the gtk_events_pending takes a LOT of cpu time. So what we do
1031 * instead is to leave the control to GTK and take it back.
1033 /* A. Servicing loop */
1034 //while( (g_slist_length(list_in) != 0 || g_slist_length(list_out) != 0)) {
1035 if((g_slist_length(list_in
) != 0 || g_slist_length(list_out
) != 0)) {
1037 /* 1. If list_in is empty (need a seek) */
1038 if( g_slist_length(list_in
) == 0 ) {
1040 /* list in is empty, need a seek */
1042 /* 1.1 Add requests to list_in */
1043 GSList
*ltime
= NULL
;
1044 GSList
*lpos
= NULL
;
1045 GSList
*iter
= NULL
;
1047 /* 1.1.1 Find all time requests with the lowest start time in list_out
1050 if(g_slist_length(list_out
) > 0)
1051 ltime
= g_slist_append(ltime
, g_slist_nth_data(list_out
, 0));
1052 for(iter
=g_slist_nth(list_out
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
1053 /* Find all time requests with the lowest start time in list_out */
1054 guint index_ltime
= g_array_index(ltime
, guint
, 0);
1055 EventsRequest
*event_request_ltime
= (EventsRequest
*)g_slist_nth_data(ltime
, 0);
1056 EventsRequest
*event_request_list_out
= (EventsRequest
*)iter
->data
;
1059 comp
= ltt_time_compare(event_request_ltime
->start_time
,
1060 event_request_list_out
->start_time
);
1062 ltime
= g_slist_append(ltime
, event_request_list_out
);
1064 /* Remove all elements from ltime, and add current */
1065 while(ltime
!= NULL
)
1066 ltime
= g_slist_delete_link(ltime
, g_slist_nth(ltime
, 0));
1067 ltime
= g_slist_append(ltime
, event_request_list_out
);
1071 /* 1.1.2 Find all position requests with the lowest position in list_out
1074 if(g_slist_length(list_out
) > 0)
1075 lpos
= g_slist_append(lpos
, g_slist_nth_data(list_out
, 0));
1076 for(iter
=g_slist_nth(list_out
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
1077 /* Find all position requests with the lowest position in list_out */
1078 EventsRequest
*event_request_lpos
= (EventsRequest
*)g_slist_nth_data(lpos
, 0);
1079 EventsRequest
*event_request_list_out
= (EventsRequest
*)iter
->data
;
1082 if(event_request_lpos
->start_position
!= NULL
1083 && event_request_list_out
->start_position
!= NULL
)
1085 comp
= lttv_traceset_context_pos_pos_compare
1086 (event_request_lpos
->start_position
,
1087 event_request_list_out
->start_position
);
1092 lpos
= g_slist_append(lpos
, event_request_list_out
);
1094 /* Remove all elements from lpos, and add current */
1096 lpos
= g_slist_delete_link(lpos
, g_slist_nth(lpos
, 0));
1097 lpos
= g_slist_append(lpos
, event_request_list_out
);
1102 EventsRequest
*event_request_lpos
= (EventsRequest
*)g_slist_nth_data(lpos
, 0);
1103 EventsRequest
*event_request_ltime
= (EventsRequest
*)g_slist_nth_data(ltime
, 0);
1104 LttTime lpos_start_time
;
1106 if(event_request_lpos
!= NULL
1107 && event_request_lpos
->start_position
!= NULL
) {
1108 lpos_start_time
= lttv_traceset_context_position_get_time(
1109 event_request_lpos
->start_position
);
1112 /* 1.1.3 If lpos.start time < ltime */
1113 if(event_request_lpos
!= NULL
1114 && event_request_lpos
->start_position
!= NULL
1115 && ltt_time_compare(lpos_start_time
,
1116 event_request_ltime
->start_time
)<0) {
1117 /* Add lpos to list_in, remove them from list_out */
1118 for(iter
=lpos
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
1119 /* Add to list_in */
1120 EventsRequest
*event_request_lpos
=
1121 (EventsRequest
*)iter
->data
;
1123 list_in
= g_slist_append(list_in
, event_request_lpos
);
1124 /* Remove from list_out */
1125 list_out
= g_slist_remove(list_out
, event_request_lpos
);
1128 /* 1.1.4 (lpos.start time >= ltime) */
1129 /* Add ltime to list_in, remove them from list_out */
1131 for(iter
=ltime
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
1132 /* Add to list_in */
1133 EventsRequest
*event_request_ltime
=
1134 (EventsRequest
*)iter
->data
;
1136 list_in
= g_slist_append(list_in
, event_request_ltime
);
1137 /* Remove from list_out */
1138 list_out
= g_slist_remove(list_out
, event_request_ltime
);
1143 g_slist_free(ltime
);
1148 tfc
= lttv_traceset_context_get_current_tfc(tsc
);
1149 g_assert(g_slist_length(list_in
)>0);
1150 EventsRequest
*events_request
= g_slist_nth_data(list_in
, 0);
1153 /* 1.2.1 If first request in list_in is a time request */
1154 if(events_request
->start_position
== NULL
) {
1155 /* - If first req in list_in start time != current time */
1156 if(tfc
== NULL
|| ltt_time_compare(events_request
->start_time
,
1157 tfc
->timestamp
) != 0)
1158 /* - Seek to that time */
1159 g_debug("SEEK TIME : %lu, %lu", events_request
->start_time
.tv_sec
,
1160 events_request
->start_time
.tv_nsec
);
1161 //lttv_process_traceset_seek_time(tsc, events_request->start_time);
1162 lttv_state_traceset_seek_time_closest(LTTV_TRACESET_STATE(tsc
),
1163 events_request
->start_time
);
1165 /* Process the traceset with only state hooks */
1167 lttv_process_traceset_middle(tsc
,
1168 events_request
->start_time
,
1174 /* Else, the first request in list_in is a position request */
1175 /* If first req in list_in pos != current pos */
1176 g_assert(events_request
->start_position
!= NULL
);
1177 g_debug("SEEK POS time : %lu, %lu",
1178 lttv_traceset_context_position_get_time(
1179 events_request
->start_position
).tv_sec
,
1180 lttv_traceset_context_position_get_time(
1181 events_request
->start_position
).tv_nsec
);
1183 g_debug("SEEK POS context time : %lu, %lu",
1184 lttv_traceset_context_get_current_tfc(tsc
)->timestamp
.tv_sec
,
1185 lttv_traceset_context_get_current_tfc(tsc
)->timestamp
.tv_nsec
);
1186 g_assert(events_request
->start_position
!= NULL
);
1187 if(lttv_traceset_context_ctx_pos_compare(tsc
,
1188 events_request
->start_position
) != 0) {
1189 /* 1.2.2.1 Seek to that position */
1190 g_debug("SEEK POSITION");
1191 //lttv_process_traceset_seek_position(tsc, events_request->start_position);
1192 pos_time
= lttv_traceset_context_position_get_time(
1193 events_request
->start_position
);
1195 lttv_state_traceset_seek_time_closest(LTTV_TRACESET_STATE(tsc
),
1198 /* Process the traceset with only state hooks */
1200 lttv_process_traceset_middle(tsc
,
1203 events_request
->start_position
);
1204 g_assert(lttv_traceset_context_ctx_pos_compare(tsc
,
1205 events_request
->start_position
) == 0);
1212 /* 1.3 Add hooks and call before request for all list_in members */
1214 GSList
*iter
= NULL
;
1216 for(iter
=list_in
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
1217 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1218 /* 1.3.1 If !servicing */
1219 if(events_request
->servicing
== FALSE
) {
1220 /* - begin request hooks called
1221 * - servicing = TRUE
1223 lttv_hooks_call(events_request
->before_request
, (gpointer
)tsc
);
1224 events_request
->servicing
= TRUE
;
1226 /* 1.3.2 call before chunk
1227 * 1.3.3 events hooks added
1229 if(events_request
->trace
== -1)
1230 lttv_process_traceset_begin(tsc
,
1231 events_request
->before_chunk_traceset
,
1232 events_request
->before_chunk_trace
,
1233 events_request
->before_chunk_tracefile
,
1234 events_request
->event
,
1235 events_request
->event_by_id
);
1237 guint nb_trace
= lttv_traceset_number(tsc
->ts
);
1238 g_assert(events_request
->trace
< nb_trace
&&
1239 events_request
->trace
> -1);
1240 LttvTraceContext
*tc
= tsc
->traces
[events_request
->trace
];
1242 lttv_hooks_call(events_request
->before_chunk_traceset
, tsc
);
1244 lttv_trace_context_add_hooks(tc
,
1245 events_request
->before_chunk_trace
,
1246 events_request
->before_chunk_tracefile
,
1247 events_request
->event
,
1248 events_request
->event_by_id
);
1253 /* 2. Else, list_in is not empty, we continue a read */
1256 /* 2.0 For each req of list_in */
1257 GSList
*iter
= list_in
;
1259 while(iter
!= NULL
) {
1261 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1263 /* - Call before chunk
1264 * - events hooks added
1266 if(events_request
->trace
== -1)
1267 lttv_process_traceset_begin(tsc
,
1268 events_request
->before_chunk_traceset
,
1269 events_request
->before_chunk_trace
,
1270 events_request
->before_chunk_tracefile
,
1271 events_request
->event
,
1272 events_request
->event_by_id
);
1274 guint nb_trace
= lttv_traceset_number(tsc
->ts
);
1275 g_assert(events_request
->trace
< nb_trace
&&
1276 events_request
->trace
> -1);
1277 LttvTraceContext
*tc
= tsc
->traces
[events_request
->trace
];
1279 lttv_hooks_call(events_request
->before_chunk_traceset
, tsc
);
1281 lttv_trace_context_add_hooks(tc
,
1282 events_request
->before_chunk_trace
,
1283 events_request
->before_chunk_tracefile
,
1284 events_request
->event
,
1285 events_request
->event_by_id
);
1288 iter
= g_slist_next(iter
);
1293 tfc
= lttv_traceset_context_get_current_tfc(tsc
);
1295 /* 2.1 For each req of list_out */
1296 GSList
*iter
= list_out
;
1298 while(iter
!= NULL
) {
1300 gboolean remove
= FALSE
;
1301 gboolean free_data
= FALSE
;
1302 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1304 /* if req.start time == current context time
1305 * or req.start position == current position*/
1306 if( ltt_time_compare(events_request
->start_time
,
1307 tfc
->timestamp
) == 0
1309 (events_request
->start_position
!= NULL
1311 lttv_traceset_context_ctx_pos_compare(tsc
,
1312 events_request
->start_position
) == 0)
1314 /* - Add to list_in, remove from list_out */
1315 list_in
= g_slist_append(list_in
, events_request
);
1319 /* - If !servicing */
1320 if(events_request
->servicing
== FALSE
) {
1321 /* - begin request hooks called
1322 * - servicing = TRUE
1324 lttv_hooks_call(events_request
->before_request
, (gpointer
)tsc
);
1325 events_request
->servicing
= TRUE
;
1327 /* call before chunk
1328 * events hooks added
1330 if(events_request
->trace
== -1)
1331 lttv_process_traceset_begin(tsc
,
1332 events_request
->before_chunk_traceset
,
1333 events_request
->before_chunk_trace
,
1334 events_request
->before_chunk_tracefile
,
1335 events_request
->event
,
1336 events_request
->event_by_id
);
1338 guint nb_trace
= lttv_traceset_number(tsc
->ts
);
1339 g_assert(events_request
->trace
< nb_trace
&&
1340 events_request
->trace
> -1);
1341 LttvTraceContext
*tc
= tsc
->traces
[events_request
->trace
];
1343 lttv_hooks_call(events_request
->before_chunk_traceset
, tsc
);
1345 lttv_trace_context_add_hooks(tc
,
1346 events_request
->before_chunk_trace
,
1347 events_request
->before_chunk_tracefile
,
1348 events_request
->event
,
1349 events_request
->event_by_id
);
1358 GSList
*remove_iter
= iter
;
1360 iter
= g_slist_next(iter
);
1361 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
1362 list_out
= g_slist_remove_link(list_out
, remove_iter
);
1363 } else { // not remove
1364 iter
= g_slist_next(iter
);
1370 /* 3. Find end criterions */
1375 /* 3.1.1 Find lowest end time in list_in */
1376 g_assert(g_slist_length(list_in
)>0);
1377 end_time
= ((EventsRequest
*)g_slist_nth_data(list_in
,0))->end_time
;
1379 for(iter
=g_slist_nth(list_in
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
1380 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1382 if(ltt_time_compare(events_request
->end_time
,
1384 end_time
= events_request
->end_time
;
1387 /* 3.1.2 Find lowest start time in list_out */
1388 for(iter
=list_out
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
1389 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1391 if(ltt_time_compare(events_request
->start_time
,
1393 end_time
= events_request
->start_time
;
1398 /* 3.2 Number of events */
1400 /* 3.2.1 Find lowest number of events in list_in */
1403 end_nb_events
= ((EventsRequest
*)g_slist_nth_data(list_in
,0))->num_events
;
1405 for(iter
=g_slist_nth(list_in
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
1406 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1408 if(events_request
->num_events
< end_nb_events
)
1409 end_nb_events
= events_request
->num_events
;
1412 /* 3.2.2 Use min(CHUNK_NUM_EVENTS, min num events in list_in) as
1415 end_nb_events
= MIN(CHUNK_NUM_EVENTS
, end_nb_events
);
1419 /* 3.3 End position */
1421 /* 3.3.1 Find lowest end position in list_in */
1424 end_position
=((EventsRequest
*)g_slist_nth_data(list_in
,0))->end_position
;
1426 for(iter
=g_slist_nth(list_in
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
1427 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1429 if(events_request
->end_position
!= NULL
&& end_position
!= NULL
&&
1430 lttv_traceset_context_pos_pos_compare(events_request
->end_position
,
1432 end_position
= events_request
->end_position
;
1437 /* 3.3.2 Find lowest start position in list_out */
1440 for(iter
=list_out
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
1441 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1443 if(events_request
->end_position
!= NULL
&& end_position
!= NULL
&&
1444 lttv_traceset_context_pos_pos_compare(events_request
->end_position
,
1446 end_position
= events_request
->end_position
;
1451 /* 4. Call process traceset middle */
1452 g_debug("Calling process traceset middle with %p, %lu sec %lu nsec, %lu nb ev, %p end pos", tsc
, end_time
.tv_sec
, end_time
.tv_nsec
, end_nb_events
, end_position
);
1453 count
= lttv_process_traceset_middle(tsc
, end_time
, end_nb_events
, end_position
);
1455 tfc
= lttv_traceset_context_get_current_tfc(tsc
);
1457 g_debug("Context time after middle : %lu, %lu", tfc
->timestamp
.tv_sec
,
1458 tfc
->timestamp
.tv_nsec
);
1460 g_debug("End of trace reached after middle.");
1464 /* 5. After process traceset middle */
1465 tfc
= lttv_traceset_context_get_current_tfc(tsc
);
1467 /* - if current context time > traceset.end time */
1468 if(tfc
== NULL
|| ltt_time_compare(tfc
->timestamp
,
1469 tsc
->time_span
.end_time
) > 0) {
1470 /* - For each req in list_in */
1471 GSList
*iter
= list_in
;
1473 while(iter
!= NULL
) {
1475 gboolean remove
= FALSE
;
1476 gboolean free_data
= FALSE
;
1477 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1479 /* - Remove events hooks for req
1480 * - Call end chunk for req
1483 if(events_request
->trace
== -1)
1484 lttv_process_traceset_end(tsc
,
1485 events_request
->after_chunk_traceset
,
1486 events_request
->after_chunk_trace
,
1487 events_request
->after_chunk_tracefile
,
1488 events_request
->event
,
1489 events_request
->event_by_id
);
1492 guint nb_trace
= lttv_traceset_number(tsc
->ts
);
1493 g_assert(events_request
->trace
< nb_trace
&&
1494 events_request
->trace
> -1);
1495 LttvTraceContext
*tc
= tsc
->traces
[events_request
->trace
];
1497 lttv_trace_context_remove_hooks(tc
,
1498 events_request
->after_chunk_trace
,
1499 events_request
->after_chunk_tracefile
,
1500 events_request
->event
,
1501 events_request
->event_by_id
);
1502 lttv_hooks_call(events_request
->after_chunk_traceset
, tsc
);
1507 /* - Call end request for req */
1508 lttv_hooks_call(events_request
->after_request
, (gpointer
)tsc
);
1510 /* - remove req from list_in */
1511 /* Destroy the request */
1518 GSList
*remove_iter
= iter
;
1520 iter
= g_slist_next(iter
);
1521 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
1522 list_in
= g_slist_remove_link(list_in
, remove_iter
);
1523 } else { // not remove
1524 iter
= g_slist_next(iter
);
1529 /* 5.1 For each req in list_in */
1530 GSList
*iter
= list_in
;
1532 while(iter
!= NULL
) {
1534 gboolean remove
= FALSE
;
1535 gboolean free_data
= FALSE
;
1536 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1538 /* - Remove events hooks for req
1539 * - Call end chunk for req
1541 if(events_request
->trace
== -1)
1542 lttv_process_traceset_end(tsc
,
1543 events_request
->after_chunk_traceset
,
1544 events_request
->after_chunk_trace
,
1545 events_request
->after_chunk_tracefile
,
1546 events_request
->event
,
1547 events_request
->event_by_id
);
1550 guint nb_trace
= lttv_traceset_number(tsc
->ts
);
1551 g_assert(events_request
->trace
< nb_trace
&&
1552 events_request
->trace
> -1);
1553 LttvTraceContext
*tc
= tsc
->traces
[events_request
->trace
];
1555 lttv_trace_context_remove_hooks(tc
,
1556 events_request
->after_chunk_trace
,
1557 events_request
->after_chunk_tracefile
,
1558 events_request
->event
,
1559 events_request
->event_by_id
);
1561 lttv_hooks_call(events_request
->after_chunk_traceset
, tsc
);
1564 /* - req.num -= count */
1565 g_assert(events_request
->num_events
>= count
);
1566 events_request
->num_events
-= count
;
1568 g_assert(tfc
!= NULL
);
1569 /* - if req.num == 0
1571 * current context time >= req.end time
1573 * req.end pos == current pos
1575 * req.stop_flag == TRUE
1577 if( events_request
->num_events
== 0
1579 events_request
->stop_flag
== TRUE
1581 ltt_time_compare(tfc
->timestamp
,
1582 events_request
->end_time
) >= 0
1584 (events_request
->end_position
!= NULL
1586 lttv_traceset_context_ctx_pos_compare(tsc
,
1587 events_request
->end_position
) == 0)
1590 g_assert(events_request
->servicing
== TRUE
);
1591 /* - Call end request for req
1592 * - remove req from list_in */
1593 lttv_hooks_call(events_request
->after_request
, (gpointer
)tsc
);
1594 /* - remove req from list_in */
1595 /* Destroy the request */
1603 GSList
*remove_iter
= iter
;
1605 iter
= g_slist_next(iter
);
1606 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
1607 list_in
= g_slist_remove_link(list_in
, remove_iter
);
1608 } else { // not remove
1609 iter
= g_slist_next(iter
);
1615 /* End of removed servicing loop : leave control to GTK instead. */
1616 // if(gtk_events_pending()) break;
1619 /* B. When interrupted between chunks */
1622 GSList
*iter
= list_in
;
1624 /* 1. for each request in list_in */
1625 while(iter
!= NULL
) {
1627 gboolean remove
= FALSE
;
1628 gboolean free_data
= FALSE
;
1629 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1631 /* 1.1. Use current postition as start position */
1632 if(events_request
->start_position
!= NULL
)
1633 lttv_traceset_context_position_destroy(events_request
->start_position
);
1634 events_request
->start_position
= lttv_traceset_context_position_new();
1635 lttv_traceset_context_position_save(tsc
, events_request
->start_position
);
1637 /* 1.2. Remove start time */
1638 events_request
->start_time
= ltt_time_infinite
;
1640 /* 1.3. Move from list_in to list_out */
1643 list_out
= g_slist_append(list_out
, events_request
);
1648 GSList
*remove_iter
= iter
;
1650 iter
= g_slist_next(iter
);
1651 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
1652 list_in
= g_slist_remove_link(list_in
, remove_iter
);
1653 } else { // not remove
1654 iter
= g_slist_next(iter
);
1661 /* C Unlock Traces */
1663 //lttv_process_traceset_get_sync_data(tsc);
1668 iter_trace
<lttv_traceset_number(tsc
->ts
);
1670 LttvTrace
*trace_v
= lttv_traceset_get(tsc
->ts
, iter_trace
);
1672 lttvwindowtraces_unlock(trace_v
);
1677 //set the cursor back to normal
1678 gdk_window_set_cursor(win
, NULL
);
1681 g_assert(g_slist_length(list_in
) == 0);
1683 if( g_slist_length(list_out
) == 0 ) {
1684 /* Put tab's request pending flag back to normal */
1685 tab
->events_request_pending
= FALSE
;
1686 g_debug("remove the idle fct");
1687 return FALSE
; /* Remove the idle function */
1689 g_debug("leave the idle fct");
1690 return TRUE
; /* Leave the idle function */
1692 /* We do not use simili-round-robin, it may require to read 1 meg buffers
1693 * again and again if many tracesets use the same tracefiles. */
1694 /* Hack for round-robin idle functions */
1695 /* It will put the idle function at the end of the pool */
1696 /*g_idle_add_full((G_PRIORITY_HIGH_IDLE + 21),
1697 (GSourceFunc)execute_events_requests,
1707 /* add_trace_into_traceset_selector, each instance of a viewer has an associated
1708 * selector (filter), when a trace is added into traceset, the selector should
1709 * reflect the change. The function is used to update the selector
1712 void add_trace_into_traceset_selector(GtkWidget
* paned
, LttTrace
* t
)
1714 int j
, k
, m
, nb_tracefile
, nb_control
, nb_per_cpu
, nb_facility
, nb_event
;
1715 LttvTracesetSelector
* s
;
1716 LttvTraceSelector
* trace
;
1717 LttvTracefileSelector
* tracefile
;
1718 LttvEventtypeSelector
* eventtype
;
1724 w
= gtk_multivpaned_get_first_widget(GTK_MULTIVPANED(paned
));
1726 s
= g_object_get_data(G_OBJECT(w
), "Traceset_Selector");
1729 trace
= lttv_trace_selector_new(t
);
1730 lttv_traceset_selector_trace_add(s
, trace
);
1732 nb_facility
= ltt_trace_facility_number(t
);
1733 for(k
=0;k
<nb_facility
;k
++){
1734 fac
= ltt_trace_facility_get(t
,k
);
1735 nb_event
= (int) ltt_facility_eventtype_number(fac
);
1736 for(m
=0;m
<nb_event
;m
++){
1737 et
= ltt_facility_eventtype_get(fac
,m
);
1738 eventtype
= lttv_eventtype_selector_new(et
);
1739 lttv_trace_selector_eventtype_add(trace
, eventtype
);
1743 nb_control
= ltt_trace_control_tracefile_number(t
);
1744 nb_per_cpu
= ltt_trace_per_cpu_tracefile_number(t
);
1745 nb_tracefile
= nb_control
+ nb_per_cpu
;
1747 for(j
= 0 ; j
< nb_tracefile
; j
++) {
1749 tf
= ltt_trace_control_tracefile_get(t
, j
);
1751 tf
= ltt_trace_per_cpu_tracefile_get(t
, j
- nb_control
);
1752 tracefile
= lttv_tracefile_selector_new(tf
);
1753 lttv_trace_selector_tracefile_add(trace
, tracefile
);
1754 lttv_eventtype_selector_copy(trace
, tracefile
);
1756 }else g_warning("Module does not support filtering\n");
1758 w
= gtk_multivpaned_get_next_widget(GTK_MULTIVPANED(paned
));
1763 static void lttvwindow_add_trace(Tab
*tab
, LttvTrace
*trace_v
)
1765 LttvTraceset
*traceset
= tab
->traceset_info
->traceset
;
1767 guint num_traces
= lttv_traceset_number(traceset
);
1769 //Verify if trace is already present.
1770 for(i
=0; i
<num_traces
; i
++)
1772 LttvTrace
* trace
= lttv_traceset_get(traceset
, i
);
1773 if(trace
== trace_v
)
1777 //Keep a reference to the traces so they are not freed.
1778 for(i
=0; i
<lttv_traceset_number(traceset
); i
++)
1780 LttvTrace
* trace
= lttv_traceset_get(traceset
, i
);
1781 lttv_trace_ref(trace
);
1784 //remove state update hooks
1785 lttv_state_remove_event_hooks(
1786 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1788 lttv_context_fini(LTTV_TRACESET_CONTEXT(
1789 tab
->traceset_info
->traceset_context
));
1790 g_object_unref(tab
->traceset_info
->traceset_context
);
1792 lttv_traceset_add(traceset
, trace_v
);
1793 lttv_trace_ref(trace_v
); /* local ref */
1795 /* Create new context */
1796 tab
->traceset_info
->traceset_context
=
1797 g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
1799 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->
1804 //add state update hooks
1805 lttv_state_add_event_hooks(
1806 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1807 //Remove local reference to the traces.
1808 for(i
=0; i
<lttv_traceset_number(traceset
); i
++)
1810 LttvTrace
* trace
= lttv_traceset_get(traceset
, i
);
1811 lttv_trace_unref(trace
);
1815 //add_trace_into_traceset_selector(GTK_MULTIVPANED(tab->multivpaned), lttv_trace(trace_v));
1818 /* add_trace adds a trace into the current traceset. It first displays a
1819 * directory selection dialogue to let user choose a trace, then recreates
1820 * tracset_context, and redraws all the viewer of the current tab
1823 void add_trace(GtkWidget
* widget
, gpointer user_data
)
1826 LttvTrace
* trace_v
;
1827 LttvTraceset
* traceset
;
1829 char abs_path
[PATH_MAX
];
1832 MainWindow
* mw_data
= get_window_data_struct(widget
);
1833 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
1835 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
1836 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
1840 tab
= create_new_tab(widget
, NULL
);
1842 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
1845 GtkDirSelection
* file_selector
= (GtkDirSelection
*)gtk_dir_selection_new("Select a trace");
1846 gtk_dir_selection_hide_fileop_buttons(file_selector
);
1848 if(remember_trace_dir
[0] != '\0')
1849 gtk_dir_selection_set_filename(file_selector
, remember_trace_dir
);
1851 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
1853 case GTK_RESPONSE_ACCEPT
:
1854 case GTK_RESPONSE_OK
:
1855 dir
= gtk_dir_selection_get_dir (file_selector
);
1856 strncpy(remember_trace_dir
, dir
, PATH_MAX
);
1857 if(!dir
|| strlen(dir
) == 0){
1858 gtk_widget_destroy((GtkWidget
*)file_selector
);
1861 get_absolute_pathname(dir
, abs_path
);
1862 trace_v
= lttvwindowtraces_get_trace_by_name(abs_path
);
1863 if(trace_v
== NULL
) {
1864 trace
= ltt_trace_open(abs_path
);
1866 g_warning("cannot open trace %s", abs_path
);
1868 trace_v
= lttv_trace_new(trace
);
1869 lttvwindowtraces_add_trace(trace_v
);
1870 lttvwindow_add_trace(tab
, trace_v
);
1873 lttvwindow_add_trace(tab
, trace_v
);
1876 gtk_widget_destroy((GtkWidget
*)file_selector
);
1878 //update current tab
1879 //update_traceset(mw_data);
1881 /* Call the updatetraceset hooks */
1883 traceset
= tab
->traceset_info
->traceset
;
1884 SetTraceset(tab
, traceset
);
1885 // in expose now call_pending_read_hooks(mw_data);
1887 //lttvwindow_report_current_time(mw_data,&(tab->current_time));
1889 case GTK_RESPONSE_REJECT
:
1890 case GTK_RESPONSE_CANCEL
:
1892 gtk_widget_destroy((GtkWidget
*)file_selector
);
1898 /* remove_trace_into_traceset_selector, each instance of a viewer has an associated
1899 * selector (filter), when a trace is remove from traceset, the selector should
1900 * reflect the change. The function is used to update the selector
1903 void remove_trace_from_traceset_selector(GtkWidget
* paned
, unsigned i
)
1905 LttvTracesetSelector
* s
;
1906 LttvTraceSelector
* t
;
1909 w
= gtk_multivpaned_get_first_widget(GTK_MULTIVPANED(paned
));
1911 s
= g_object_get_data(G_OBJECT(w
), "Traceset_Selector");
1913 t
= lttv_traceset_selector_trace_get(s
,i
);
1914 lttv_traceset_selector_trace_remove(s
, i
);
1915 lttv_trace_selector_destroy(t
);
1916 }g_warning("Module dose not support filtering\n");
1917 w
= gtk_multivpaned_get_next_widget(GTK_MULTIVPANED(paned
));
1922 /* remove_trace removes a trace from the current traceset if all viewers in
1923 * the current tab are not interested in the trace. It first displays a
1924 * dialogue, which shows all traces in the current traceset, to let user choose
1925 * a trace, then it checks if all viewers unselect the trace, if it is true,
1926 * it will remove the trace, recreate the traceset_contex,
1927 * and redraws all the viewer of the current tab. If there is on trace in the
1928 * current traceset, it will delete all viewers of the current tab
1931 // MD : no filter version.
1932 void remove_trace(GtkWidget
*widget
, gpointer user_data
)
1935 LttvTrace
* trace_v
;
1936 LttvTraceset
* traceset
;
1937 gint i
, j
, nb_trace
, index
=-1;
1938 char ** name
, *remove_trace_name
;
1939 MainWindow
* mw_data
= get_window_data_struct(widget
);
1940 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
1942 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
1943 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
1949 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
1952 nb_trace
=lttv_traceset_number(tab
->traceset_info
->traceset
);
1953 name
= g_new(char*,nb_trace
);
1954 for(i
= 0; i
< nb_trace
; i
++){
1955 trace_v
= lttv_traceset_get(tab
->traceset_info
->traceset
, i
);
1956 trace
= lttv_trace(trace_v
);
1957 name
[i
] = ltt_trace_name(trace
);
1960 remove_trace_name
= get_remove_trace(name
, nb_trace
);
1963 if(remove_trace_name
){
1965 /* yuk, cut n paste from old code.. should be better (MD)*/
1966 for(i
= 0; i
<nb_trace
; i
++) {
1967 if(strcmp(remove_trace_name
,name
[i
]) == 0){
1972 traceset
= tab
->traceset_info
->traceset
;
1973 //Keep a reference to the traces so they are not freed.
1974 for(j
=0; j
<lttv_traceset_number(traceset
); j
++)
1976 LttvTrace
* trace
= lttv_traceset_get(traceset
, j
);
1977 lttv_trace_ref(trace
);
1980 //remove state update hooks
1981 lttv_state_remove_event_hooks(
1982 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1983 lttv_context_fini(LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
));
1984 g_object_unref(tab
->traceset_info
->traceset_context
);
1986 trace_v
= lttv_traceset_get(traceset
, index
);
1988 lttv_traceset_remove(traceset
, index
);
1989 lttv_trace_unref(trace_v
); // Remove local reference
1991 if(lttv_trace_get_ref_number(trace_v
) <= 1) {
1992 /* ref 1 : lttvwindowtraces only*/
1993 ltt_trace_close(lttv_trace(trace_v
));
1994 /* lttvwindowtraces_remove_trace takes care of destroying
1995 * the traceset linked with the trace_v and also of destroying
1996 * the trace_v at the same time.
1998 lttvwindowtraces_remove_trace(trace_v
);
2001 tab
->traceset_info
->traceset_context
=
2002 g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
2004 LTTV_TRACESET_CONTEXT(tab
->
2005 traceset_info
->traceset_context
),traceset
);
2006 //add state update hooks
2007 lttv_state_add_event_hooks(
2008 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
2010 //Remove local reference to the traces.
2011 for(j
=0; j
<lttv_traceset_number(traceset
); j
++)
2013 LttvTrace
* trace
= lttv_traceset_get(traceset
, j
);
2014 lttv_trace_unref(trace
);
2017 SetTraceset(tab
, (gpointer
)traceset
);
2023 void remove_trace(GtkWidget
* widget
, gpointer user_data
)
2026 LttvTrace
* trace_v
;
2027 LttvTraceset
* traceset
;
2028 gint i
, j
, nb_trace
;
2029 char ** name
, *remove_trace_name
;
2030 MainWindow
* mw_data
= get_window_data_struct(widget
);
2031 LttvTracesetSelector
* s
;
2032 LttvTraceSelector
* t
;
2035 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
2037 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2038 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2044 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
2047 nb_trace
=lttv_traceset_number(tab
->traceset_info
->traceset
);
2048 name
= g_new(char*,nb_trace
);
2049 for(i
= 0; i
< nb_trace
; i
++){
2050 trace_v
= lttv_traceset_get(tab
->traceset_info
->traceset
, i
);
2051 trace
= lttv_trace(trace_v
);
2052 name
[i
] = ltt_trace_name(trace
);
2055 remove_trace_name
= get_remove_trace(name
, nb_trace
);
2057 if(remove_trace_name
){
2058 for(i
=0; i
<nb_trace
; i
++){
2059 if(strcmp(remove_trace_name
,name
[i
]) == 0){
2060 //unselect the trace from the current viewer
2062 w
= gtk_multivpaned_get_widget(GTK_MULTIVPANED(tab
->multivpaned
));
2064 s
= g_object_get_data(G_OBJECT(w
), "Traceset_Selector");
2066 t
= lttv_traceset_selector_trace_get(s
,i
);
2067 lttv_trace_selector_set_selected(t
, FALSE
);
2070 //check if other viewers select the trace
2071 w
= gtk_multivpaned_get_first_widget(GTK_MULTIVPANED(tab
->multivpaned
));
2073 s
= g_object_get_data(G_OBJECT(w
), "Traceset_Selector");
2075 t
= lttv_traceset_selector_trace_get(s
,i
);
2076 selected
= lttv_trace_selector_get_selected(t
);
2079 w
= gtk_multivpaned_get_next_widget(GTK_MULTIVPANED(tab
->multivpaned
));
2081 }else selected
= FALSE
;
2083 //if no viewer selects the trace, remove it
2085 remove_trace_from_traceset_selector(GTK_MULTIVPANED(tab
->multivpaned
), i
);
2087 traceset
= tab
->traceset_info
->traceset
;
2088 //Keep a reference to the traces so they are not freed.
2089 for(j
=0; j
<lttv_traceset_number(traceset
); j
++)
2091 LttvTrace
* trace
= lttv_traceset_get(traceset
, j
);
2092 lttv_trace_ref(trace
);
2095 //remove state update hooks
2096 lttv_state_remove_event_hooks(
2097 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
2098 lttv_context_fini(LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
));
2099 g_object_unref(tab
->traceset_info
->traceset_context
);
2102 trace_v
= lttv_traceset_get(traceset
, i
);
2104 if(lttv_trace_get_ref_number(trace_v
) <= 2) {
2105 /* ref 2 : traceset, local */
2106 lttvwindowtraces_remove_trace(trace_v
);
2107 ltt_trace_close(lttv_trace(trace_v
));
2110 lttv_traceset_remove(traceset
, i
);
2111 lttv_trace_unref(trace_v
); // Remove local reference
2113 if(!lttv_trace_get_ref_number(trace_v
))
2114 lttv_trace_destroy(trace_v
);
2116 tab
->traceset_info
->traceset_context
=
2117 g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
2119 LTTV_TRACESET_CONTEXT(tab
->
2120 traceset_info
->traceset_context
),traceset
);
2121 //add state update hooks
2122 lttv_state_add_event_hooks(
2123 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
2125 //Remove local reference to the traces.
2126 for(j
=0; j
<lttv_traceset_number(traceset
); j
++)
2128 LttvTrace
* trace
= lttv_traceset_get(traceset
, j
);
2129 lttv_trace_unref(trace
);
2133 //update current tab
2134 //update_traceset(mw_data);
2137 SetTraceset(tab
, (gpointer
)traceset
);
2138 // in expose now call_pending_read_hooks(mw_data);
2140 //lttvwindow_report_current_time(mw_data,&(tab->current_time));
2143 // while(tab->multi_vpaned->num_children){
2144 // gtk_multi_vpaned_widget_delete(tab->multi_vpaned);
2158 /* Redraw all the viewers in the current tab */
2159 void redraw(GtkWidget
*widget
, gpointer user_data
)
2161 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
2162 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2163 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2168 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
2172 LttvAttributeValue value
;
2174 g_assert(lttv_iattribute_find_by_path(tab
->attributes
, "hooks/redraw", LTTV_POINTER
, &value
));
2176 tmp
= (LttvHooks
*)*(value
.v_pointer
);
2178 lttv_hooks_call(tmp
,NULL
);
2182 void continue_processing(GtkWidget
*widget
, gpointer user_data
)
2184 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
2185 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2186 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2191 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
2195 LttvAttributeValue value
;
2197 g_assert(lttv_iattribute_find_by_path(tab
->attributes
,
2198 "hooks/continue", LTTV_POINTER
, &value
));
2200 tmp
= (LttvHooks
*)*(value
.v_pointer
);
2202 lttv_hooks_call(tmp
,NULL
);
2205 /* Stop the processing for the calling main window's current tab.
2206 * It removes every processing requests that are in its list. It does not call
2207 * the end request hooks, because the request is not finished.
2210 void stop_processing(GtkWidget
*widget
, gpointer user_data
)
2212 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
2213 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2214 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2219 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
2221 GSList
*iter
= tab
->events_requests
;
2223 while(iter
!= NULL
) {
2224 GSList
*remove_iter
= iter
;
2225 iter
= g_slist_next(iter
);
2227 g_free(remove_iter
->data
);
2228 tab
->events_requests
=
2229 g_slist_remove_link(tab
->events_requests
, remove_iter
);
2231 tab
->events_request_pending
= FALSE
;
2232 g_idle_remove_by_data(tab
);
2233 g_assert(g_slist_length(tab
->events_requests
) == 0);
2237 /* save will save the traceset to a file
2238 * Not implemented yet FIXME
2241 void save(GtkWidget
* widget
, gpointer user_data
)
2246 void save_as(GtkWidget
* widget
, gpointer user_data
)
2248 g_printf("Save as\n");
2252 /* zoom will change the time_window of all the viewers of the
2253 * current tab, and redisplay them. The main functionality is to
2254 * determine the new time_window of the current tab
2257 void zoom(GtkWidget
* widget
, double size
)
2259 TimeInterval time_span
;
2260 TimeWindow new_time_window
;
2261 LttTime current_time
, time_delta
, time_s
, time_e
, time_tmp
;
2262 MainWindow
* mw_data
= get_window_data_struct(widget
);
2263 LttvTracesetContext
*tsc
;
2264 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
2266 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2267 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2273 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
2276 if(size
== 1) return;
2278 tsc
= LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
2279 time_span
= tsc
->time_span
;
2280 new_time_window
= tab
->time_window
;
2281 current_time
= tab
->current_time
;
2283 time_delta
= ltt_time_sub(time_span
.end_time
,time_span
.start_time
);
2285 new_time_window
.start_time
= time_span
.start_time
;
2286 new_time_window
.time_width
= time_delta
;
2287 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
2288 new_time_window
.time_width
) ;
2290 new_time_window
.time_width
= ltt_time_div(new_time_window
.time_width
, size
);
2291 if(ltt_time_compare(new_time_window
.time_width
,time_delta
) > 0)
2292 { /* Case where zoom out is bigger than trace length */
2293 new_time_window
.start_time
= time_span
.start_time
;
2294 new_time_window
.time_width
= time_delta
;
2295 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
2296 new_time_window
.time_width
) ;
2300 /* Center the image on the current time */
2301 new_time_window
.start_time
=
2302 ltt_time_sub(current_time
, ltt_time_div(new_time_window
.time_width
, 2.0));
2303 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
2304 new_time_window
.time_width
) ;
2305 /* If on borders, don't fall off */
2306 if(ltt_time_compare(new_time_window
.start_time
, time_span
.start_time
) <0)
2308 new_time_window
.start_time
= time_span
.start_time
;
2309 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
2310 new_time_window
.time_width
) ;
2314 if(ltt_time_compare(new_time_window
.end_time
,
2315 time_span
.end_time
) > 0)
2317 new_time_window
.start_time
=
2318 ltt_time_sub(time_span
.end_time
, new_time_window
.time_width
);
2320 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
2321 new_time_window
.time_width
) ;
2328 if(ltt_time_compare(new_time_window
.time_width
, ltt_time_zero
) == 0) {
2329 g_warning("Zoom more than 1 ns impossible");
2331 time_change_manager(tab
, new_time_window
);
2335 void zoom_in(GtkWidget
* widget
, gpointer user_data
)
2340 void zoom_out(GtkWidget
* widget
, gpointer user_data
)
2345 void zoom_extended(GtkWidget
* widget
, gpointer user_data
)
2350 void go_to_time(GtkWidget
* widget
, gpointer user_data
)
2352 g_printf("Go to time\n");
2355 void show_time_frame(GtkWidget
* widget
, gpointer user_data
)
2357 g_printf("Show time frame\n");
2361 /* callback function */
2364 on_empty_traceset_activate (GtkMenuItem
*menuitem
,
2367 create_new_window((GtkWidget
*)menuitem
, user_data
, FALSE
);
2372 on_clone_traceset_activate (GtkMenuItem
*menuitem
,
2375 create_new_window((GtkWidget
*)menuitem
, user_data
, TRUE
);
2379 /* create_new_tab calls create_tab to construct a new tab in the main window
2382 Tab
*create_new_tab(GtkWidget
* widget
, gpointer user_data
){
2383 gchar label
[PATH_MAX
];
2384 MainWindow
* mw_data
= get_window_data_struct(widget
);
2386 GtkNotebook
* notebook
= (GtkNotebook
*)lookup_widget(widget
, "MNotebook");
2387 if(notebook
== NULL
){
2388 g_printf("Notebook does not exist\n");
2391 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2392 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2398 copy_tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
2401 strcpy(label
,"Page");
2402 if(get_label(mw_data
, label
,"Get the name of the tab","Please input tab's name"))
2403 return (create_tab (mw_data
, copy_tab
, notebook
, label
));
2407 on_tab_activate (GtkMenuItem
*menuitem
,
2410 create_new_tab((GtkWidget
*)menuitem
, user_data
);
2415 on_open_activate (GtkMenuItem
*menuitem
,
2418 open_traceset((GtkWidget
*)menuitem
, user_data
);
2423 on_close_activate (GtkMenuItem
*menuitem
,
2426 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2427 main_window_destructor(mw_data
);
2431 /* remove the current tab from the main window
2435 on_close_tab_activate (GtkWidget
*widget
,
2439 GtkWidget
* notebook
;
2441 MainWindow
* mw_data
= get_window_data_struct(widget
);
2442 notebook
= lookup_widget(widget
, "MNotebook");
2443 if(notebook
== NULL
){
2444 g_printf("Notebook does not exist\n");
2448 page_num
= gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
));
2450 gtk_notebook_remove_page(GTK_NOTEBOOK(notebook
), page_num
);
2455 on_close_tab_X_clicked (GtkWidget
*widget
,
2459 GtkWidget
*notebook
= lookup_widget(widget
, "MNotebook");
2460 if(notebook
== NULL
){
2461 g_printf("Notebook does not exist\n");
2465 if((page_num
= gtk_notebook_page_num(GTK_NOTEBOOK(notebook
), widget
)) != -1)
2466 gtk_notebook_remove_page(GTK_NOTEBOOK(notebook
), page_num
);
2472 on_add_trace_activate (GtkMenuItem
*menuitem
,
2475 add_trace((GtkWidget
*)menuitem
, user_data
);
2480 on_remove_trace_activate (GtkMenuItem
*menuitem
,
2483 remove_trace((GtkWidget
*)menuitem
, user_data
);
2488 on_save_activate (GtkMenuItem
*menuitem
,
2491 save((GtkWidget
*)menuitem
, user_data
);
2496 on_save_as_activate (GtkMenuItem
*menuitem
,
2499 save_as((GtkWidget
*)menuitem
, user_data
);
2504 on_quit_activate (GtkMenuItem
*menuitem
,
2512 on_cut_activate (GtkMenuItem
*menuitem
,
2520 on_copy_activate (GtkMenuItem
*menuitem
,
2523 g_printf("Copye\n");
2528 on_paste_activate (GtkMenuItem
*menuitem
,
2531 g_printf("Paste\n");
2536 on_delete_activate (GtkMenuItem
*menuitem
,
2539 g_printf("Delete\n");
2544 on_zoom_in_activate (GtkMenuItem
*menuitem
,
2547 zoom_in((GtkWidget
*)menuitem
, user_data
);
2552 on_zoom_out_activate (GtkMenuItem
*menuitem
,
2555 zoom_out((GtkWidget
*)menuitem
, user_data
);
2560 on_zoom_extended_activate (GtkMenuItem
*menuitem
,
2563 zoom_extended((GtkWidget
*)menuitem
, user_data
);
2568 on_go_to_time_activate (GtkMenuItem
*menuitem
,
2571 go_to_time((GtkWidget
*)menuitem
, user_data
);
2576 on_show_time_frame_activate (GtkMenuItem
*menuitem
,
2579 show_time_frame((GtkWidget
*)menuitem
, user_data
);
2584 on_move_viewer_up_activate (GtkMenuItem
*menuitem
,
2587 move_up_viewer((GtkWidget
*)menuitem
, user_data
);
2592 on_move_viewer_down_activate (GtkMenuItem
*menuitem
,
2595 move_down_viewer((GtkWidget
*)menuitem
, user_data
);
2600 on_remove_viewer_activate (GtkMenuItem
*menuitem
,
2603 delete_viewer((GtkWidget
*)menuitem
, user_data
);
2608 on_trace_filter_activate (GtkMenuItem
*menuitem
,
2611 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2612 LttvTracesetSelector
* s
;
2614 GtkWidget
* notebook
= lookup_widget(GTK_WIDGET(menuitem
), "MNotebook");
2616 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2617 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2623 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
2626 w
= gtk_multivpaned_get_widget(GTK_MULTIVPANED(tab
->multivpaned
));
2628 s
= g_object_get_data(G_OBJECT(w
), "Traceset_Selector");
2630 g_printf("There is no viewer yet\n");
2633 if(get_filter_selection(s
, "Configure trace and tracefile filter", "Select traces and tracefiles")){
2634 //FIXME report filter change
2635 //update_traceset(mw_data);
2636 //call_pending_read_hooks(mw_data);
2637 //lttvwindow_report_current_time(mw_data,&(tab->current_time));
2643 on_trace_facility_activate (GtkMenuItem
*menuitem
,
2646 g_printf("Trace facility selector: %s\n");
2650 /* Dispaly a file selection dialogue to let user select a library, then call
2651 * lttv_library_load().
2655 on_load_library_activate (GtkMenuItem
*menuitem
,
2658 GError
*error
= NULL
;
2659 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2661 gchar load_module_path_alter
[PATH_MAX
];
2665 gchar
*load_module_path
;
2666 name
= g_ptr_array_new();
2667 nb
= lttv_library_path_number();
2668 /* ask for the library path */
2672 path
= lttv_library_path_get(i
);
2673 g_ptr_array_add(name
, path
);
2676 load_module_path
= get_selection((char **)(name
->pdata
), name
->len
,
2677 "Select a library path", "Library paths");
2678 if(load_module_path
!= NULL
)
2679 strncpy(load_module_path_alter
, load_module_path
, PATH_MAX
-1); // -1 for /
2681 g_ptr_array_free(name
, TRUE
);
2683 if(load_module_path
== NULL
) return;
2687 /* Make sure the module path ends with a / */
2688 gchar
*ptr
= load_module_path_alter
;
2690 ptr
= strchr(ptr
, '\0');
2692 if(*(ptr
-1) != '/') {
2699 /* Ask for the library to load : list files in the previously selected
2701 gchar str
[PATH_MAX
];
2704 GtkFileSelection
* file_selector
=
2705 (GtkFileSelection
*)gtk_file_selection_new("Select a module");
2706 gtk_file_selection_set_filename(file_selector
, load_module_path_alter
);
2707 gtk_file_selection_hide_fileop_buttons(file_selector
);
2710 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
2712 case GTK_RESPONSE_ACCEPT
:
2713 case GTK_RESPONSE_OK
:
2714 dir
= gtk_file_selection_get_selections (file_selector
);
2715 strncpy(str
,dir
[0],PATH_MAX
);
2716 strncpy(remember_plugins_dir
,dir
[0],PATH_MAX
);
2717 /* only keep file name */
2719 str1
= strrchr(str
,'/');
2722 str1
= strrchr(str
,'\\');
2727 if(*str1
== 'l' && *(str1
+1)== 'i' && *(str1
+2)=='b')
2729 remove info after
. */
2733 str2
= strrchr(str2
, '.');
2734 if(str2
!= NULL
) *str2
= '\0';
2736 lttv_module_require(str1
, &error
);
2738 lttv_library_load(str1
, &error
);
2739 if(error
!= NULL
) g_warning(error
->message
);
2740 else g_printf("Load library: %s\n", str
);
2742 case GTK_RESPONSE_REJECT
:
2743 case GTK_RESPONSE_CANCEL
:
2745 gtk_widget_destroy((GtkWidget
*)file_selector
);
2756 /* Display all loaded modules, let user to select a module to unload
2757 * by calling lttv_module_unload
2761 on_unload_library_activate (GtkMenuItem
*menuitem
,
2764 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2766 LttvLibrary
*library
;
2771 name
= g_ptr_array_new();
2772 nb
= lttv_library_number();
2773 LttvLibraryInfo
*lib_info
= g_new(LttvLibraryInfo
,nb
);
2774 /* ask for the library name */
2777 LttvLibrary
*iter_lib
= lttv_library_get(i
);
2778 lttv_library_info(iter_lib
, &lib_info
[i
]);
2780 gchar
*path
= lib_info
[i
].name
;
2781 g_ptr_array_add(name
, lib_info
[i
].name
);
2783 lib_name
= get_selection((char **)(name
->pdata
), name
->len
,
2784 "Select a library", "Libraries");
2785 if(lib_name
!= NULL
) {
2787 if(strcmp(lib_name
, lib_info
[i
].name
) == 0) {
2788 library
= lttv_library_get(i
);
2793 g_ptr_array_free(name
, TRUE
);
2796 if(lib_name
== NULL
) return;
2799 lttv_library_unload(library
);
2803 /* Dispaly a file selection dialogue to let user select a module, then call
2804 * lttv_module_require().
2808 on_load_module_activate (GtkMenuItem
*menuitem
,
2811 GError
*error
= NULL
;
2812 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2814 LttvLibrary
*library
;
2819 name
= g_ptr_array_new();
2820 nb
= lttv_library_number();
2821 LttvLibraryInfo
*lib_info
= g_new(LttvLibraryInfo
,nb
);
2822 /* ask for the library name */
2825 LttvLibrary
*iter_lib
= lttv_library_get(i
);
2826 lttv_library_info(iter_lib
, &lib_info
[i
]);
2828 gchar
*path
= lib_info
[i
].name
;
2829 g_ptr_array_add(name
, path
);
2831 lib_name
= get_selection((char **)(name
->pdata
), name
->len
,
2832 "Select a library", "Libraries");
2833 if(lib_name
!= NULL
) {
2835 if(strcmp(lib_name
, lib_info
[i
].name
) == 0) {
2836 library
= lttv_library_get(i
);
2841 g_ptr_array_free(name
, TRUE
);
2844 if(lib_name
== NULL
) return;
2847 //LttvModule *module;
2848 gchar module_name_out
[PATH_MAX
];
2850 /* Ask for the module to load : list modules in the selected lib */
2854 LttvModuleInfo
*module_info
= g_new(LttvModuleInfo
,nb
);
2855 name
= g_ptr_array_new();
2856 nb
= lttv_library_module_number(library
);
2857 /* ask for the module name */
2860 LttvModule
*iter_module
= lttv_library_module_get(library
, i
);
2861 lttv_module_info(iter_module
, &module_info
[i
]);
2863 gchar
*path
= module_info
[i
].name
;
2864 g_ptr_array_add(name
, path
);
2866 module_name
= get_selection((char **)(name
->pdata
), name
->len
,
2867 "Select a module", "Modules");
2868 if(module_name
!= NULL
) {
2870 if(strcmp(module_name
, module_info
[i
].name
) == 0) {
2871 strncpy(module_name_out
, module_name
, PATH_MAX
);
2872 //module = lttv_library_module_get(i);
2878 g_ptr_array_free(name
, TRUE
);
2879 g_free(module_info
);
2881 if(module_name
== NULL
) return;
2884 lttv_module_require(module_name_out
, &error
);
2885 if(error
!= NULL
) g_warning(error
->message
);
2886 else g_printf("Load module: %s\n", module_name_out
);
2893 gchar str
[PATH_MAX
];
2896 GtkFileSelection
* file_selector
=
2897 (GtkFileSelection
*)gtk_file_selection_new("Select a module");
2898 gtk_file_selection_set_filename(file_selector
, load_module_path_alter
);
2899 gtk_file_selection_hide_fileop_buttons(file_selector
);
2902 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
2904 case GTK_RESPONSE_ACCEPT
:
2905 case GTK_RESPONSE_OK
:
2906 dir
= gtk_file_selection_get_selections (file_selector
);
2907 strncpy(str
,dir
[0],PATH_MAX
);
2908 strncpy(remember_plugins_dir
,dir
[0],PATH_MAX
);
2910 /* only keep file name */
2912 str1
= strrchr(str
,'/');
2915 str1
= strrchr(str
,'\\');
2920 if(*str1
== 'l' && *(str1
+1)== 'i' && *(str1
+2)=='b')
2922 remove info after
. */
2926 str2
= strrchr(str2
, '.');
2927 if(str2
!= NULL
) *str2
= '\0';
2929 lttv_module_require(str1
, &error
);
2931 lttv_library_load(str1
, &error
);
2932 if(error
!= NULL
) g_warning(error
->message
);
2933 else g_printf("Load library: %s\n", str
);
2935 case GTK_RESPONSE_REJECT
:
2936 case GTK_RESPONSE_CANCEL
:
2938 gtk_widget_destroy((GtkWidget
*)file_selector
);
2950 /* Display all loaded modules, let user to select a module to unload
2951 * by calling lttv_module_unload
2955 on_unload_module_activate (GtkMenuItem
*menuitem
,
2958 GError
*error
= NULL
;
2959 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2961 LttvLibrary
*library
;
2966 name
= g_ptr_array_new();
2967 nb
= lttv_library_number();
2968 LttvLibraryInfo
*lib_info
= g_new(LttvLibraryInfo
,nb
);
2969 /* ask for the library name */
2972 LttvLibrary
*iter_lib
= lttv_library_get(i
);
2973 lttv_library_info(iter_lib
, &lib_info
[i
]);
2975 gchar
*path
= lib_info
[i
].name
;
2976 g_ptr_array_add(name
, path
);
2978 lib_name
= get_selection((char **)(name
->pdata
), name
->len
,
2979 "Select a library", "Libraries");
2980 if(lib_name
!= NULL
) {
2982 if(strcmp(lib_name
, lib_info
[i
].name
) == 0) {
2983 library
= lttv_library_get(i
);
2988 g_ptr_array_free(name
, TRUE
);
2991 if(lib_name
== NULL
) return;
2996 /* Ask for the module to load : list modules in the selected lib */
3000 nb
= lttv_library_module_number(library
);
3001 LttvModuleInfo
*module_info
= g_new(LttvModuleInfo
,nb
);
3002 name
= g_ptr_array_new();
3003 /* ask for the module name */
3006 LttvModule
*iter_module
= lttv_library_module_get(library
, i
);
3007 lttv_module_info(iter_module
, &module_info
[i
]);
3009 gchar
*path
= module_info
[i
].name
;
3010 if(module_info
[i
].use_count
> 0) g_ptr_array_add(name
, path
);
3012 module_name
= get_selection((char **)(name
->pdata
), name
->len
,
3013 "Select a module", "Modules");
3014 if(module_name
!= NULL
) {
3016 if(strcmp(module_name
, module_info
[i
].name
) == 0) {
3017 module
= lttv_library_module_get(library
, i
);
3023 g_ptr_array_free(name
, TRUE
);
3024 g_free(module_info
);
3026 if(module_name
== NULL
) return;
3029 LttvModuleInfo module_info
;
3030 lttv_module_info(module
, &module_info
);
3031 g_printf("Release module: %s\n", module_info
.name
);
3033 lttv_module_release(module
);
3037 /* Display a directory dialogue to let user select a path for library searching
3041 on_add_library_search_path_activate (GtkMenuItem
*menuitem
,
3044 GtkDirSelection
* file_selector
= (GtkDirSelection
*)gtk_dir_selection_new("Select library path");
3048 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
3049 if(remember_plugins_dir
[0] != '\0')
3050 gtk_dir_selection_set_filename(file_selector
, remember_plugins_dir
);
3052 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
3054 case GTK_RESPONSE_ACCEPT
:
3055 case GTK_RESPONSE_OK
:
3056 dir
= gtk_dir_selection_get_dir (file_selector
);
3057 strncpy(remember_plugins_dir
,dir
,PATH_MAX
);
3058 strncat(remember_plugins_dir
,"/",PATH_MAX
);
3059 lttv_library_path_add(dir
);
3060 case GTK_RESPONSE_REJECT
:
3061 case GTK_RESPONSE_CANCEL
:
3063 gtk_widget_destroy((GtkWidget
*)file_selector
);
3069 /* Display a directory dialogue to let user select a path for library searching
3073 on_remove_library_search_path_activate (GtkMenuItem
*menuitem
,
3076 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
3078 const char *lib_path
;
3083 name
= g_ptr_array_new();
3084 nb
= lttv_library_path_number();
3085 /* ask for the library name */
3088 gchar
*path
= lttv_library_path_get(i
);
3089 g_ptr_array_add(name
, path
);
3091 lib_path
= get_selection((char **)(name
->pdata
), name
->len
,
3092 "Select a library path", "Library paths");
3094 g_ptr_array_free(name
, TRUE
);
3096 if(lib_path
== NULL
) return;
3099 lttv_library_path_remove(lib_path
);
3103 on_color_activate (GtkMenuItem
*menuitem
,
3106 g_printf("Color\n");
3111 on_filter_activate (GtkMenuItem
*menuitem
,
3114 g_printf("Filter\n");
3119 on_save_configuration_activate (GtkMenuItem
*menuitem
,
3122 g_printf("Save configuration\n");
3127 on_content_activate (GtkMenuItem
*menuitem
,
3130 g_printf("Content\n");
3135 on_about_close_activate (GtkButton
*button
,
3138 GtkWidget
*about_widget
= GTK_WIDGET(user_data
);
3140 gtk_widget_destroy(about_widget
);
3144 on_about_activate (GtkMenuItem
*menuitem
,
3147 MainWindow
*main_window
= get_window_data_struct(GTK_WIDGET(menuitem
));
3148 GtkWidget
*window_widget
= main_window
->mwindow
;
3149 GtkWidget
*about_widget
= gtk_window_new(GTK_WINDOW_TOPLEVEL
);
3150 GtkWindow
*about_window
= GTK_WINDOW(about_widget
);
3151 gint window_width
, window_height
;
3153 gtk_window_set_title(about_window
, "About Linux Trace Toolkit");
3155 gtk_window_set_resizable(about_window
, FALSE
);
3156 gtk_window_set_transient_for(GTK_WINDOW(window_widget
), about_window
);
3157 gtk_window_set_destroy_with_parent(about_window
, TRUE
);
3158 gtk_window_set_modal(about_window
, FALSE
);
3160 /* Put the about window at the center of the screen */
3161 gtk_window_get_size(about_window
, &window_width
, &window_height
);
3162 gtk_window_move (about_window
,
3163 (gdk_screen_width() - window_width
)/2,
3164 (gdk_screen_height() - window_height
)/2);
3166 GtkWidget
*vbox
= gtk_vbox_new(FALSE
, 1);
3168 gtk_container_add(GTK_CONTAINER(about_widget
), vbox
);
3172 GtkWidget
*label1
= gtk_label_new("");
3173 gtk_misc_set_padding(GTK_MISC(label1
), 10, 20);
3174 gtk_label_set_markup(GTK_LABEL(label1
), "\
3175 <big>Linux Trace Toolkit</big>");
3176 gtk_label_set_justify(GTK_LABEL(label1
), GTK_JUSTIFY_CENTER
);
3178 GtkWidget
*label2
= gtk_label_new("");
3179 gtk_misc_set_padding(GTK_MISC(label2
), 10, 20);
3180 gtk_label_set_markup(GTK_LABEL(label2
), "\
3181 Project author: Karim Yaghmour\n\
3185 Michel Dagenais (New trace format, lttv main)\n\
3186 Mathieu Desnoyers (Directory structure, build with automake/conf,\n\
3187 lttv gui, control flow view, gui green threads\n\
3188 with interruptible foreground and background computation,\n\
3189 detailed event list)\n\
3190 Benoit Des Ligneris (Cluster adaptation)\n\
3191 Xang-Xiu Yang (new trace reading library and converter, lttv gui, \n\
3192 detailed event list and statistics view)\n\
3193 Tom Zanussi (RelayFS)");
3195 GtkWidget
*label3
= gtk_label_new("");
3196 gtk_label_set_markup(GTK_LABEL(label3
), "\
3197 Linux Trace Toolkit, Copyright (C) 2004 Karim Yaghmour\n\
3198 Linux Trace Toolkit comes with ABSOLUTELY NO WARRANTY.\n\
3199 This is free software, and you are welcome to redistribute it\n\
3200 under certain conditions. See COPYING for details.");
3201 gtk_misc_set_padding(GTK_MISC(label3
), 10, 20);
3203 gtk_box_pack_start_defaults(GTK_BOX(vbox
), label1
);
3204 gtk_box_pack_start_defaults(GTK_BOX(vbox
), label2
);
3205 gtk_box_pack_start_defaults(GTK_BOX(vbox
), label3
);
3207 GtkWidget
*hbox
= gtk_hbox_new(TRUE
, 0);
3208 gtk_box_pack_end(GTK_BOX(vbox
), hbox
, FALSE
, FALSE
, 0);
3209 GtkWidget
*close_button
= gtk_button_new_with_mnemonic("_Close");
3210 gtk_box_pack_end(GTK_BOX(hbox
), close_button
, FALSE
, FALSE
, 0);
3211 gtk_container_set_border_width(GTK_CONTAINER(close_button
), 20);
3213 g_signal_connect(G_OBJECT(close_button
), "clicked",
3214 G_CALLBACK(on_about_close_activate
),
3215 (gpointer
)about_widget
);
3217 gtk_widget_show_all(about_widget
);
3222 on_button_new_clicked (GtkButton
*button
,
3225 create_new_window((GtkWidget
*)button
, user_data
, TRUE
);
3229 on_button_new_tab_clicked (GtkButton
*button
,
3232 create_new_tab((GtkWidget
*)button
, user_data
);
3236 on_button_open_clicked (GtkButton
*button
,
3239 open_traceset((GtkWidget
*)button
, user_data
);
3244 on_button_add_trace_clicked (GtkButton
*button
,
3247 add_trace((GtkWidget
*)button
, user_data
);
3252 on_button_remove_trace_clicked (GtkButton
*button
,
3255 remove_trace((GtkWidget
*)button
, user_data
);
3259 on_button_redraw_clicked (GtkButton
*button
,
3262 redraw((GtkWidget
*)button
, user_data
);
3266 on_button_continue_processing_clicked (GtkButton
*button
,
3269 continue_processing((GtkWidget
*)button
, user_data
);
3273 on_button_stop_processing_clicked (GtkButton
*button
,
3276 stop_processing((GtkWidget
*)button
, user_data
);
3282 on_button_save_clicked (GtkButton
*button
,
3285 save((GtkWidget
*)button
, user_data
);
3290 on_button_save_as_clicked (GtkButton
*button
,
3293 save_as((GtkWidget
*)button
, user_data
);
3298 on_button_zoom_in_clicked (GtkButton
*button
,
3301 zoom_in((GtkWidget
*)button
, user_data
);
3306 on_button_zoom_out_clicked (GtkButton
*button
,
3309 zoom_out((GtkWidget
*)button
, user_data
);
3314 on_button_zoom_extended_clicked (GtkButton
*button
,
3317 zoom_extended((GtkWidget
*)button
, user_data
);
3322 on_button_go_to_time_clicked (GtkButton
*button
,
3325 go_to_time((GtkWidget
*)button
, user_data
);
3330 on_button_show_time_frame_clicked (GtkButton
*button
,
3333 show_time_frame((GtkWidget
*)button
, user_data
);
3338 on_button_move_up_clicked (GtkButton
*button
,
3341 move_up_viewer((GtkWidget
*)button
, user_data
);
3346 on_button_move_down_clicked (GtkButton
*button
,
3349 move_down_viewer((GtkWidget
*)button
, user_data
);
3354 on_button_delete_viewer_clicked (GtkButton
*button
,
3357 delete_viewer((GtkWidget
*)button
, user_data
);
3361 on_MWindow_destroy (GtkWidget
*widget
,
3364 MainWindow
*main_window
= get_window_data_struct(widget
);
3365 LttvIAttribute
*attributes
= main_window
->attributes
;
3366 LttvAttributeValue value
;
3368 //This is unnecessary, since widgets will be destroyed
3369 //by the main window widget anyway.
3370 //remove_all_menu_toolbar_constructors(main_window, NULL);
3372 g_assert(lttv_iattribute_find_by_path(attributes
,
3373 "viewers/menu", LTTV_POINTER
, &value
));
3374 lttv_menus_destroy((LttvMenus
*)*(value
.v_pointer
));
3376 g_assert(lttv_iattribute_find_by_path(attributes
,
3377 "viewers/toolbar", LTTV_POINTER
, &value
));
3378 lttv_toolbars_destroy((LttvToolbars
*)*(value
.v_pointer
));
3380 g_object_unref(main_window
->attributes
);
3381 g_main_window_list
= g_slist_remove(g_main_window_list
, main_window
);
3383 g_printf("There are now : %d windows\n",g_slist_length(g_main_window_list
));
3384 if(g_slist_length(g_main_window_list
) == 0)
3389 on_MWindow_configure (GtkWidget
*widget
,
3390 GdkEventConfigure
*event
,
3393 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)widget
);
3394 float width
= event
->width
;
3395 TimeWindow time_win
;
3397 TimeInterval
*time_span
;
3400 // MD : removed time width modification upon resizing of the main window.
3401 // The viewers will redraw themselves completely, without time interval
3404 if(mw_data->window_width){
3405 time_span = LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context)->Time_Span ;
3406 time_win = tab->time_window;
3407 ratio = width / mw_data->window_width;
3408 tab->time_window.time_width = ltt_time_mul(time_win.time_width,ratio);
3409 time = ltt_time_sub(time_span->endTime, time_win.start_time);
3410 if(ltt_time_compare(time, tab->time_window.time_width) < 0){
3411 tab->time_window.time_width = time;
3417 mw_data->window_width = (int)width;
3426 on_MNotebook_switch_page (GtkNotebook
*notebook
,
3427 GtkNotebookPage
*page
,
3435 void time_change_manager (Tab
*tab
,
3436 TimeWindow new_time_window
)
3438 /* Only one source of time change */
3439 if(tab
->time_manager_lock
== TRUE
) return;
3441 tab
->time_manager_lock
= TRUE
;
3443 LttvTracesetContext
*tsc
= LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3444 TimeInterval time_span
= tsc
->time_span
;
3445 LttTime start_time
= new_time_window
.start_time
;
3446 LttTime end_time
= new_time_window
.end_time
;
3449 GtkAdjustment
*adjustment
= gtk_range_get_adjustment(GTK_RANGE(tab
->scrollbar
));
3450 LttTime upper
= ltt_time_sub(time_span
.end_time
, time_span
.start_time
);
3452 gtk_range_set_increments(GTK_RANGE(tab
->scrollbar
),
3453 ltt_time_to_double(new_time_window
.time_width
)
3454 / SCROLL_STEP_PER_PAGE
3455 * NANOSECONDS_PER_SECOND
, /* step increment */
3456 ltt_time_to_double(new_time_window
.time_width
)
3457 * NANOSECONDS_PER_SECOND
); /* page increment */
3458 gtk_range_set_range(GTK_RANGE(tab
->scrollbar
),
3460 ltt_time_to_double(upper
)
3461 * NANOSECONDS_PER_SECOND
); /* upper */
3463 g_object_set(G_OBJECT(adjustment
),
3467 ltt_time_to_double(upper
), /* upper */
3469 ltt_time_to_double(new_time_window
.time_width
)
3470 / SCROLL_STEP_PER_PAGE
, /* step increment */
3472 ltt_time_to_double(new_time_window
.time_width
),
3473 /* page increment */
3475 ltt_time_to_double(new_time_window
.time_width
), /* page size */
3477 gtk_adjustment_changed(adjustment
);
3479 // g_object_set(G_OBJECT(adjustment),
3481 // ltt_time_to_double(
3482 // ltt_time_sub(start_time, time_span.start_time))
3485 //gtk_adjustment_value_changed(adjustment);
3486 gtk_range_set_value(GTK_RANGE(tab
->scrollbar
),
3488 ltt_time_sub(start_time
, time_span
.start_time
)) /* value */);
3490 /* set the time bar. */
3492 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry1
),
3493 (double)time_span
.start_time
.tv_sec
,
3494 (double)time_span
.end_time
.tv_sec
);
3495 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry1
),
3496 (double)start_time
.tv_sec
);
3498 /* start nanoseconds */
3499 if(start_time
.tv_sec
== time_span
.start_time
.tv_sec
) {
3500 /* can be both beginning and end at the same time. */
3501 if(start_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3502 /* If we are at the end, max nsec to end.. -1 (not zero length) */
3503 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry2
),
3504 (double)time_span
.start_time
.tv_nsec
,
3505 (double)time_span
.end_time
.tv_nsec
-1);
3507 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry2
),
3508 (double)time_span
.start_time
.tv_nsec
,
3509 (double)NANOSECONDS_PER_SECOND
-1);
3511 } else if(start_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3512 /* If we are at the end, max nsec to end.. -1 (not zero length) */
3513 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry2
),
3515 (double)time_span
.end_time
.tv_nsec
-1);
3516 } else /* anywhere else */
3517 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry2
),
3519 (double)NANOSECONDS_PER_SECOND
-1);
3520 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry2
),
3521 (double)start_time
.tv_nsec
);
3524 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry3
),
3525 (double)time_span
.start_time
.tv_sec
,
3526 (double)time_span
.end_time
.tv_sec
);
3527 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry3
),
3528 (double)end_time
.tv_sec
);
3530 /* end nanoseconds */
3531 if(end_time
.tv_sec
== time_span
.start_time
.tv_sec
) {
3532 /* can be both beginning and end at the same time. */
3533 if(end_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3534 /* If we are at the end, max nsec to end.. */
3535 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry4
),
3536 (double)time_span
.start_time
.tv_nsec
+1,
3537 (double)time_span
.end_time
.tv_nsec
);
3539 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry4
),
3540 (double)time_span
.start_time
.tv_nsec
+1,
3541 (double)NANOSECONDS_PER_SECOND
-1);
3544 else if(end_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3545 /* If we are at the end, max nsec to end.. */
3546 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry4
),
3548 (double)time_span
.end_time
.tv_nsec
);
3550 else /* anywhere else */
3551 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry4
),
3553 (double)NANOSECONDS_PER_SECOND
-1);
3554 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry4
),
3555 (double)end_time
.tv_nsec
);
3557 /* call viewer hooks for new time window */
3558 set_time_window(tab
, &new_time_window
);
3560 tab
->time_manager_lock
= FALSE
;
3564 /* value changed for frame start s
3566 * Check time span : if ns is out of range, clip it the nearest good value.
3569 on_MEntry1_value_changed (GtkSpinButton
*spinbutton
,
3572 Tab
*tab
=(Tab
*)user_data
;
3573 LttvTracesetContext
* tsc
=
3574 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3575 TimeInterval time_span
= tsc
->time_span
;
3576 gint value
= gtk_spin_button_get_value_as_int(spinbutton
);
3578 TimeWindow new_time_window
= tab
->time_window
;
3580 LttTime end_time
= new_time_window
.end_time
;
3582 new_time_window
.start_time
.tv_sec
= value
;
3584 /* start nanoseconds */
3585 if(new_time_window
.start_time
.tv_sec
== time_span
.start_time
.tv_sec
) {
3586 if(new_time_window
.start_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3587 if(new_time_window
.start_time
.tv_nsec
> time_span
.end_time
.tv_nsec
)
3588 new_time_window
.start_time
.tv_nsec
= time_span
.end_time
.tv_nsec
-1;
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
;
3592 if(new_time_window
.start_time
.tv_nsec
< time_span
.start_time
.tv_nsec
)
3593 new_time_window
.start_time
.tv_nsec
= time_span
.start_time
.tv_nsec
;
3596 else if(new_time_window
.start_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3597 if(new_time_window
.start_time
.tv_nsec
> time_span
.end_time
.tv_nsec
)
3598 new_time_window
.start_time
.tv_nsec
= time_span
.end_time
.tv_nsec
-1;
3601 if(ltt_time_compare(new_time_window
.start_time
, end_time
) >= 0) {
3602 /* Then, we must push back end time : keep the same time width
3603 * if possible, else end traceset time */
3604 end_time
= LTT_TIME_MIN(ltt_time_add(new_time_window
.start_time
,
3605 new_time_window
.time_width
),
3606 time_span
.end_time
);
3609 /* Fix the time width to fit start time and end time */
3610 new_time_window
.time_width
= ltt_time_sub(end_time
,
3611 new_time_window
.start_time
);
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
);
3646 new_time_window
.end_time
= end_time
;
3648 time_change_manager(tab
, new_time_window
);
3653 on_MEntry3_value_changed (GtkSpinButton
*spinbutton
,
3656 Tab
*tab
=(Tab
*)user_data
;
3657 LttvTracesetContext
* tsc
=
3658 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3659 TimeInterval time_span
= tsc
->time_span
;
3660 gint value
= gtk_spin_button_get_value_as_int(spinbutton
);
3662 TimeWindow new_time_window
= tab
->time_window
;
3664 LttTime end_time
= new_time_window
.end_time
;
3666 end_time
.tv_sec
= value
;
3668 /* end nanoseconds */
3669 if(end_time
.tv_sec
== time_span
.start_time
.tv_sec
) {
3670 if(end_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3671 if(end_time
.tv_nsec
> time_span
.end_time
.tv_nsec
)
3672 end_time
.tv_nsec
= time_span
.end_time
.tv_nsec
;
3673 if(end_time
.tv_nsec
< time_span
.start_time
.tv_nsec
)
3674 end_time
.tv_nsec
= time_span
.start_time
.tv_nsec
+1;
3676 if(end_time
.tv_nsec
< time_span
.start_time
.tv_nsec
)
3677 end_time
.tv_nsec
= time_span
.start_time
.tv_nsec
+1;
3680 else if(end_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3681 if(end_time
.tv_nsec
> time_span
.end_time
.tv_nsec
)
3682 end_time
.tv_nsec
= time_span
.end_time
.tv_nsec
;
3685 if(ltt_time_compare(new_time_window
.start_time
, end_time
) >= 0) {
3686 /* Then, we must push front start time : keep the same time width
3687 * if possible, else end traceset time */
3688 new_time_window
.start_time
= LTT_TIME_MAX(
3689 ltt_time_sub(end_time
,
3690 new_time_window
.time_width
),
3691 time_span
.start_time
);
3694 /* Fix the time width to fit start time and end time */
3695 new_time_window
.time_width
= ltt_time_sub(end_time
,
3696 new_time_window
.start_time
);
3698 new_time_window
.end_time
= end_time
;
3700 time_change_manager(tab
, new_time_window
);
3705 on_MEntry4_value_changed (GtkSpinButton
*spinbutton
,
3708 Tab
*tab
=(Tab
*)user_data
;
3709 LttvTracesetContext
* tsc
=
3710 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3711 TimeInterval time_span
= tsc
->time_span
;
3712 gint value
= gtk_spin_button_get_value_as_int(spinbutton
);
3714 TimeWindow new_time_window
= tab
->time_window
;
3716 LttTime end_time
= new_time_window
.end_time
;
3718 end_time
.tv_nsec
= value
;
3720 if(ltt_time_compare(new_time_window
.start_time
, end_time
) >= 0) {
3721 /* Then, we must push front start time : keep the same time width
3722 * if possible, else end traceset time */
3723 new_time_window
.start_time
= LTT_TIME_MAX(
3724 ltt_time_sub(end_time
,
3725 new_time_window
.time_width
),
3726 time_span
.start_time
);
3729 /* Fix the time width to fit start time and end time */
3730 new_time_window
.time_width
= ltt_time_sub(end_time
,
3731 new_time_window
.start_time
);
3732 new_time_window
.end_time
= end_time
;
3734 time_change_manager(tab
, new_time_window
);
3739 void current_time_change_manager (Tab
*tab
,
3740 LttTime new_current_time
)
3742 /* Only one source of time change */
3743 if(tab
->current_time_manager_lock
== TRUE
) return;
3745 tab
->current_time_manager_lock
= TRUE
;
3747 LttvTracesetContext
*tsc
= LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3748 TimeInterval time_span
= tsc
->time_span
;
3750 /* current seconds */
3751 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry5
),
3752 (double)time_span
.start_time
.tv_sec
,
3753 (double)time_span
.end_time
.tv_sec
);
3754 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry5
),
3755 (double)new_current_time
.tv_sec
);
3758 /* start nanoseconds */
3759 if(new_current_time
.tv_sec
== time_span
.start_time
.tv_sec
) {
3760 /* can be both beginning and end at the same time. */
3761 if(new_current_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3762 /* If we are at the end, max nsec to end.. */
3763 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry6
),
3764 (double)time_span
.start_time
.tv_nsec
,
3765 (double)time_span
.end_time
.tv_nsec
);
3767 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry6
),
3768 (double)time_span
.start_time
.tv_nsec
,
3769 (double)NANOSECONDS_PER_SECOND
-1);
3771 } else if(new_current_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3772 /* If we are at the end, max nsec to end.. */
3773 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry6
),
3775 (double)time_span
.end_time
.tv_nsec
);
3776 } else /* anywhere else */
3777 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry6
),
3779 (double)NANOSECONDS_PER_SECOND
-1);
3781 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry6
),
3782 (double)new_current_time
.tv_nsec
);
3784 set_current_time(tab
, &new_current_time
);
3786 tab
->current_time_manager_lock
= FALSE
;
3790 on_MEntry5_value_changed (GtkSpinButton
*spinbutton
,
3793 Tab
*tab
= (Tab
*)user_data
;
3794 LttvTracesetContext
* tsc
=
3795 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3796 TimeInterval time_span
= tsc
->time_span
;
3797 gint value
= gtk_spin_button_get_value_as_int(spinbutton
);
3798 LttTime new_current_time
= tab
->current_time
;
3799 new_current_time
.tv_sec
= value
;
3801 /* current nanoseconds */
3802 if(new_current_time
.tv_sec
== time_span
.start_time
.tv_sec
) {
3803 if(new_current_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3804 if(new_current_time
.tv_nsec
> time_span
.end_time
.tv_nsec
)
3805 new_current_time
.tv_nsec
= time_span
.end_time
.tv_nsec
;
3806 if(new_current_time
.tv_nsec
< time_span
.start_time
.tv_nsec
)
3807 new_current_time
.tv_nsec
= time_span
.start_time
.tv_nsec
;
3809 if(new_current_time
.tv_nsec
< time_span
.start_time
.tv_nsec
)
3810 new_current_time
.tv_nsec
= time_span
.start_time
.tv_nsec
;
3813 else if(new_current_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3814 if(new_current_time
.tv_nsec
> time_span
.end_time
.tv_nsec
)
3815 new_current_time
.tv_nsec
= time_span
.end_time
.tv_nsec
;
3818 current_time_change_manager(tab
, new_current_time
);
3822 on_MEntry6_value_changed (GtkSpinButton
*spinbutton
,
3825 Tab
*tab
= (Tab
*)user_data
;
3826 gint value
= gtk_spin_button_get_value_as_int(spinbutton
);
3827 LttTime new_current_time
= tab
->current_time
;
3828 new_current_time
.tv_nsec
= value
;
3830 current_time_change_manager(tab
, new_current_time
);
3834 void scroll_value_changed_cb(GtkWidget
*scrollbar
,
3837 Tab
*tab
= (Tab
*)user_data
;
3838 TimeWindow new_time_window
;
3840 GtkAdjustment
*adjust
= gtk_range_get_adjustment(GTK_RANGE(scrollbar
));
3841 gdouble value
= gtk_adjustment_get_value(adjust
);
3842 // gdouble upper, lower, ratio, page_size;
3844 LttvTracesetContext
* tsc
=
3845 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3846 TimeInterval time_span
= tsc
->time_span
;
3848 time
= ltt_time_add(ltt_time_from_double(value
),
3849 time_span
.start_time
);
3851 new_time_window
.start_time
= time
;
3853 page_size
= adjust
->page_size
;
3855 new_time_window
.time_width
=
3856 ltt_time_from_double(page_size
);
3858 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
3859 new_time_window
.time_width
);
3862 time_change_manager(tab
, new_time_window
);
3864 //time_window = tab->time_window;
3866 lower
= adjust
->lower
;
3867 upper
= adjust
->upper
;
3868 ratio
= (value
- lower
) / (upper
- lower
);
3869 g_info("lower %lu, upper %lu, value %lu, ratio %lu", lower
, upper
, value
, ratio
);
3871 //time = ltt_time_sub(time_span->end_time, time_span->start_time);
3872 //time = ltt_time_mul(time, (float)ratio);
3873 //time = ltt_time_add(time_span->start_time, time);
3874 time
= ltt_time_add(ltt_time_from_double(value
),
3875 time_span
.start_time
);
3877 time_window
.start_time
= time
;
3879 page_size
= adjust
->page_size
;
3881 time_window
.time_width
=
3882 ltt_time_from_double(page_size
);
3883 //time = ltt_time_sub(time_span.end_time, time);
3884 //if(ltt_time_compare(time,time_window.time_width) < 0){
3885 // time_window.time_width = time;
3888 /* call viewer hooks for new time window */
3889 set_time_window(tab
, &time_window
);
3894 /* callback function to check or uncheck the check box (filter)
3897 void checkbox_changed(GtkTreeView
*treeview
,
3899 GtkTreeViewColumn
*arg2
,
3902 GtkTreeStore
* store
= (GtkTreeStore
*)gtk_tree_view_get_model (treeview
);
3906 if (gtk_tree_model_get_iter ((GtkTreeModel
*)store
, &iter
, arg1
)){
3907 gtk_tree_model_get ((GtkTreeModel
*)store
, &iter
, CHECKBOX_COLUMN
, &value
, -1);
3908 value
= value
? FALSE
: TRUE
;
3909 gtk_tree_store_set (GTK_TREE_STORE (store
), &iter
, CHECKBOX_COLUMN
, value
, -1);
3915 /* According to user's selection, update selector(filter)
3918 void update_filter(LttvTracesetSelector
*s
, GtkTreeStore
*store
)
3920 GtkTreeIter iter
, child_iter
, child_iter1
, child_iter2
;
3921 int i
, j
, k
, nb_eventtype
;
3922 LttvTraceSelector
* trace
;
3923 LttvTracefileSelector
* tracefile
;
3924 LttvEventtypeSelector
* eventtype
;
3925 gboolean value
, value1
, value2
;
3927 if(gtk_tree_model_get_iter_first((GtkTreeModel
*)store
, &iter
)){
3930 trace
= lttv_traceset_selector_trace_get(s
, i
);
3931 nb_eventtype
= lttv_trace_selector_eventtype_number(trace
);
3932 gtk_tree_model_get ((GtkTreeModel
*)store
, &iter
, CHECKBOX_COLUMN
, &value
,-1);
3935 if(gtk_tree_model_iter_children ((GtkTreeModel
*)store
, &child_iter
, &iter
)){
3937 if(j
<1){//eventtype selector for trace
3938 gtk_tree_model_get ((GtkTreeModel
*)store
, &child_iter
, CHECKBOX_COLUMN
, &value2
,-1);
3941 if(gtk_tree_model_iter_children ((GtkTreeModel
*)store
, &child_iter1
, &child_iter
)){
3943 eventtype
= lttv_trace_selector_eventtype_get(trace
,k
);
3944 gtk_tree_model_get ((GtkTreeModel
*)store
, &child_iter1
, CHECKBOX_COLUMN
, &value2
,-1);
3945 lttv_eventtype_selector_set_selected(eventtype
,value2
);
3947 }while(gtk_tree_model_iter_next((GtkTreeModel
*)store
, &child_iter1
));
3950 }else{ //tracefile selector
3951 tracefile
= lttv_trace_selector_tracefile_get(trace
, j
- 1);
3952 gtk_tree_model_get ((GtkTreeModel
*)store
, &child_iter
, CHECKBOX_COLUMN
, &value1
,-1);
3953 lttv_tracefile_selector_set_selected(tracefile
,value1
);
3955 gtk_tree_model_iter_children((GtkTreeModel
*)store
, &child_iter1
, &child_iter
); //eventtype selector
3956 gtk_tree_model_get ((GtkTreeModel
*)store
, &child_iter1
, CHECKBOX_COLUMN
, &value2
,-1);
3959 if(gtk_tree_model_iter_children ((GtkTreeModel
*)store
, &child_iter2
, &child_iter1
)){
3960 do{//eventtype selector for tracefile
3961 eventtype
= lttv_tracefile_selector_eventtype_get(tracefile
,k
);
3962 gtk_tree_model_get ((GtkTreeModel
*)store
, &child_iter2
, CHECKBOX_COLUMN
, &value2
,-1);
3963 lttv_eventtype_selector_set_selected(eventtype
,value2
);
3965 }while(gtk_tree_model_iter_next((GtkTreeModel
*)store
, &child_iter2
));
3971 }while(gtk_tree_model_iter_next((GtkTreeModel
*)store
, &child_iter
));
3974 lttv_trace_selector_set_selected(trace
,value
);
3976 }while(gtk_tree_model_iter_next((GtkTreeModel
*)store
, &iter
));
3981 /* Display a dialogue showing all eventtypes and traces, let user to select the interested
3982 * eventtypes, tracefiles and traces (filter)
3985 gboolean
get_filter_selection(LttvTracesetSelector
*s
,char *title
, char * column_title
)
3987 GtkWidget
* dialogue
;
3988 GtkTreeStore
* store
;
3990 GtkWidget
* scroll_win
;
3991 GtkCellRenderer
* renderer
;
3992 GtkTreeViewColumn
* column
;
3993 GtkTreeIter iter
, child_iter
, child_iter1
, child_iter2
;
3994 int i
, j
, k
, id
, nb_trace
, nb_tracefile
, nb_eventtype
;
3995 LttvTraceSelector
* trace
;
3996 LttvTracefileSelector
* tracefile
;
3997 LttvEventtypeSelector
* eventtype
;
4001 dialogue
= gtk_dialog_new_with_buttons(title
,
4004 GTK_STOCK_OK
,GTK_RESPONSE_ACCEPT
,
4005 GTK_STOCK_CANCEL
,GTK_RESPONSE_REJECT
,
4007 gtk_window_set_default_size((GtkWindow
*)dialogue
, 300, 500);
4009 store
= gtk_tree_store_new (TOTAL_COLUMNS
, G_TYPE_BOOLEAN
, G_TYPE_STRING
);
4010 tree
= gtk_tree_view_new_with_model (GTK_TREE_MODEL (store
));
4011 g_object_unref (G_OBJECT (store
));
4012 g_signal_connect (G_OBJECT (tree
), "row-activated",
4013 G_CALLBACK (checkbox_changed
),
4017 renderer
= gtk_cell_renderer_toggle_new ();
4018 gtk_cell_renderer_toggle_set_radio((GtkCellRendererToggle
*)renderer
, FALSE
);
4020 g_object_set (G_OBJECT (renderer
),"activatable", TRUE
, NULL
);
4022 column
= gtk_tree_view_column_new_with_attributes ("Checkbox",
4024 "active", CHECKBOX_COLUMN
,
4026 gtk_tree_view_column_set_alignment (column
, 0.5);
4027 gtk_tree_view_column_set_fixed_width (column
, 20);
4028 gtk_tree_view_append_column (GTK_TREE_VIEW (tree
), column
);
4030 renderer
= gtk_cell_renderer_text_new ();
4031 column
= gtk_tree_view_column_new_with_attributes (column_title
,
4033 "text", NAME_COLUMN
,
4035 gtk_tree_view_column_set_alignment (column
, 0.0);
4036 gtk_tree_view_append_column (GTK_TREE_VIEW (tree
), column
);
4037 gtk_tree_view_set_headers_visible(GTK_TREE_VIEW (tree
), FALSE
);
4039 scroll_win
= gtk_scrolled_window_new (NULL
, NULL
);
4040 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll_win
),
4041 GTK_POLICY_AUTOMATIC
,GTK_POLICY_AUTOMATIC
);
4042 gtk_container_add (GTK_CONTAINER (scroll_win
), tree
);
4044 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialogue
)->vbox
), scroll_win
,TRUE
, TRUE
,0);
4046 gtk_widget_show(scroll_win
);
4047 gtk_widget_show(tree
);
4049 nb_trace
= lttv_traceset_selector_trace_number(s
);
4050 for(i
=0;i
<nb_trace
;i
++){
4051 trace
= lttv_traceset_selector_trace_get(s
, i
);
4052 name
= lttv_trace_selector_get_name(trace
);
4053 gtk_tree_store_append (store
, &iter
, NULL
);
4054 checked
= lttv_trace_selector_get_selected(trace
);
4055 gtk_tree_store_set (store
, &iter
,
4056 CHECKBOX_COLUMN
,checked
,
4060 gtk_tree_store_append (store
, &child_iter
, &iter
);
4061 gtk_tree_store_set (store
, &child_iter
,
4062 CHECKBOX_COLUMN
, checked
,
4063 NAME_COLUMN
,"eventtype",
4066 nb_eventtype
= lttv_trace_selector_eventtype_number(trace
);
4067 for(j
=0;j
<nb_eventtype
;j
++){
4068 eventtype
= lttv_trace_selector_eventtype_get(trace
,j
);
4069 name
= lttv_eventtype_selector_get_name(eventtype
);
4070 checked
= lttv_eventtype_selector_get_selected(eventtype
);
4071 gtk_tree_store_append (store
, &child_iter1
, &child_iter
);
4072 gtk_tree_store_set (store
, &child_iter1
,
4073 CHECKBOX_COLUMN
, checked
,
4078 nb_tracefile
= lttv_trace_selector_tracefile_number(trace
);
4079 for(j
=0;j
<nb_tracefile
;j
++){
4080 tracefile
= lttv_trace_selector_tracefile_get(trace
, j
);
4081 name
= lttv_tracefile_selector_get_name(tracefile
);
4082 gtk_tree_store_append (store
, &child_iter
, &iter
);
4083 checked
= lttv_tracefile_selector_get_selected(tracefile
);
4084 gtk_tree_store_set (store
, &child_iter
,
4085 CHECKBOX_COLUMN
, checked
,
4089 gtk_tree_store_append (store
, &child_iter1
, &child_iter
);
4090 gtk_tree_store_set (store
, &child_iter1
,
4091 CHECKBOX_COLUMN
, checked
,
4092 NAME_COLUMN
,"eventtype",
4095 for(k
=0;k
<nb_eventtype
;k
++){
4096 eventtype
= lttv_tracefile_selector_eventtype_get(tracefile
,k
);
4097 name
= lttv_eventtype_selector_get_name(eventtype
);
4098 checked
= lttv_eventtype_selector_get_selected(eventtype
);
4099 gtk_tree_store_append (store
, &child_iter2
, &child_iter1
);
4100 gtk_tree_store_set (store
, &child_iter2
,
4101 CHECKBOX_COLUMN
, checked
,
4108 id
= gtk_dialog_run(GTK_DIALOG(dialogue
));
4110 case GTK_RESPONSE_ACCEPT
:
4111 case GTK_RESPONSE_OK
:
4112 update_filter(s
, store
);
4113 gtk_widget_destroy(dialogue
);
4115 case GTK_RESPONSE_REJECT
:
4116 case GTK_RESPONSE_CANCEL
:
4118 gtk_widget_destroy(dialogue
);
4125 /* Select a trace which will be removed from traceset
4128 char * get_remove_trace(char ** all_trace_name
, int nb_trace
)
4130 return get_selection(all_trace_name
, nb_trace
,
4131 "Select a trace", "Trace pathname");
4135 /* Select a module which will be loaded
4138 char * get_load_module(char ** load_module_name
, int nb_module
)
4140 return get_selection(load_module_name
, nb_module
,
4141 "Select a module to load", "Module name");
4147 /* Select a module which will be unloaded
4150 char * get_unload_module(char ** loaded_module_name
, int nb_module
)
4152 return get_selection(loaded_module_name
, nb_module
,
4153 "Select a module to unload", "Module name");
4157 /* Display a dialogue which shows all selectable items, let user to
4158 * select one of them
4161 char * get_selection(char ** loaded_module_name
, int nb_module
,
4162 char *title
, char * column_title
)
4164 GtkWidget
* dialogue
;
4165 GtkWidget
* scroll_win
;
4167 GtkListStore
* store
;
4168 GtkTreeViewColumn
* column
;
4169 GtkCellRenderer
* renderer
;
4170 GtkTreeSelection
* select
;
4173 char * unload_module_name
= NULL
;
4175 dialogue
= gtk_dialog_new_with_buttons(title
,
4178 GTK_STOCK_OK
,GTK_RESPONSE_ACCEPT
,
4179 GTK_STOCK_CANCEL
,GTK_RESPONSE_REJECT
,
4181 gtk_window_set_default_size((GtkWindow
*)dialogue
, 500, 200);
4183 scroll_win
= gtk_scrolled_window_new (NULL
, NULL
);
4184 gtk_widget_show ( scroll_win
);
4185 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll_win
),
4186 GTK_POLICY_AUTOMATIC
, GTK_POLICY_AUTOMATIC
);
4188 store
= gtk_list_store_new (N_COLUMNS
,G_TYPE_STRING
);
4189 tree
= gtk_tree_view_new_with_model(GTK_TREE_MODEL (store
));
4190 gtk_widget_show ( tree
);
4191 g_object_unref (G_OBJECT (store
));
4193 renderer
= gtk_cell_renderer_text_new ();
4194 column
= gtk_tree_view_column_new_with_attributes (column_title
,
4196 "text", MODULE_COLUMN
,
4198 gtk_tree_view_column_set_alignment (column
, 0.5);
4199 gtk_tree_view_column_set_fixed_width (column
, 150);
4200 gtk_tree_view_append_column (GTK_TREE_VIEW (tree
), column
);
4202 select
= gtk_tree_view_get_selection (GTK_TREE_VIEW (tree
));
4203 gtk_tree_selection_set_mode (select
, GTK_SELECTION_SINGLE
);
4205 gtk_container_add (GTK_CONTAINER (scroll_win
), tree
);
4207 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialogue
)->vbox
), scroll_win
,TRUE
, TRUE
,0);
4209 for(i
=0;i
<nb_module
;i
++){
4210 gtk_list_store_append (store
, &iter
);
4211 gtk_list_store_set (store
, &iter
, MODULE_COLUMN
,loaded_module_name
[i
],-1);
4214 id
= gtk_dialog_run(GTK_DIALOG(dialogue
));
4216 case GTK_RESPONSE_ACCEPT
:
4217 case GTK_RESPONSE_OK
:
4218 if (gtk_tree_selection_get_selected (select
, (GtkTreeModel
**)&store
, &iter
)){
4219 gtk_tree_model_get ((GtkTreeModel
*)store
, &iter
, MODULE_COLUMN
, &unload_module_name
, -1);
4221 case GTK_RESPONSE_REJECT
:
4222 case GTK_RESPONSE_CANCEL
:
4224 gtk_widget_destroy(dialogue
);
4228 return unload_module_name
;
4232 /* Insert all menu entry and tool buttons into this main window
4237 void add_all_menu_toolbar_constructors(MainWindow
* mw
, gpointer user_data
)
4241 lttvwindow_viewer_constructor constructor
;
4242 LttvMenus
* global_menu
, * instance_menu
;
4243 LttvToolbars
* global_toolbar
, * instance_toolbar
;
4244 LttvMenuClosure
*menu_item
;
4245 LttvToolbarClosure
*toolbar_item
;
4246 LttvAttributeValue value
;
4247 LttvIAttribute
*global_attributes
= LTTV_IATTRIBUTE(lttv_global_attributes());
4248 LttvIAttribute
*attributes
= mw
->attributes
;
4249 GtkWidget
* tool_menu_title_menu
, *new_widget
, *pixmap
;
4251 g_assert(lttv_iattribute_find_by_path(global_attributes
,
4252 "viewers/menu", LTTV_POINTER
, &value
));
4253 if(*(value
.v_pointer
) == NULL
)
4254 *(value
.v_pointer
) = lttv_menus_new();
4255 global_menu
= (LttvMenus
*)*(value
.v_pointer
);
4257 g_assert(lttv_iattribute_find_by_path(attributes
,
4258 "viewers/menu", LTTV_POINTER
, &value
));
4259 if(*(value
.v_pointer
) == NULL
)
4260 *(value
.v_pointer
) = lttv_menus_new();
4261 instance_menu
= (LttvMenus
*)*(value
.v_pointer
);
4265 g_assert(lttv_iattribute_find_by_path(global_attributes
,
4266 "viewers/toolbar", LTTV_POINTER
, &value
));
4267 if(*(value
.v_pointer
) == NULL
)
4268 *(value
.v_pointer
) = lttv_toolbars_new();
4269 global_toolbar
= (LttvToolbars
*)*(value
.v_pointer
);
4271 g_assert(lttv_iattribute_find_by_path(attributes
,
4272 "viewers/toolbar", LTTV_POINTER
, &value
));
4273 if(*(value
.v_pointer
) == NULL
)
4274 *(value
.v_pointer
) = lttv_toolbars_new();
4275 instance_toolbar
= (LttvToolbars
*)*(value
.v_pointer
);
4277 /* Add missing menu entries to window instance */
4278 for(i
=0;i
<global_menu
->len
;i
++) {
4279 menu_item
= &g_array_index(global_menu
, LttvMenuClosure
, i
);
4281 //add menu_item to window instance;
4282 constructor
= menu_item
->con
;
4283 tool_menu_title_menu
= lookup_widget(mw
->mwindow
,"ToolMenuTitle_menu");
4285 gtk_menu_item_new_with_mnemonic (menu_item
->menu_text
);
4286 gtk_container_add (GTK_CONTAINER (tool_menu_title_menu
),
4288 g_signal_connect ((gpointer
) new_widget
, "activate",
4289 G_CALLBACK (insert_viewer_wrap
),
4291 gtk_widget_show (new_widget
);
4292 lttv_menus_add(instance_menu
, menu_item
->con
,
4293 menu_item
->menu_path
,
4294 menu_item
->menu_text
,
4299 /* Add missing toolbar entries to window instance */
4300 for(i
=0;i
<global_toolbar
->len
;i
++) {
4301 toolbar_item
= &g_array_index(global_toolbar
, LttvToolbarClosure
, i
);
4303 //add toolbar_item to window instance;
4304 constructor
= toolbar_item
->con
;
4305 tool_menu_title_menu
= lookup_widget(mw
->mwindow
,"MToolbar1");
4306 pixbuf
= gdk_pixbuf_new_from_xpm_data((const char**)toolbar_item
->pixmap
);
4307 pixmap
= gtk_image_new_from_pixbuf(pixbuf
);
4309 gtk_toolbar_append_element (GTK_TOOLBAR (tool_menu_title_menu
),
4310 GTK_TOOLBAR_CHILD_BUTTON
,
4313 toolbar_item
->tooltip
, NULL
,
4314 pixmap
, NULL
, NULL
);
4315 gtk_label_set_use_underline(
4316 GTK_LABEL (((GtkToolbarChild
*) (
4317 g_list_last (GTK_TOOLBAR
4318 (tool_menu_title_menu
)->children
)->data
))->label
),
4320 gtk_container_set_border_width (GTK_CONTAINER (new_widget
), 1);
4321 g_signal_connect ((gpointer
) new_widget
,
4323 G_CALLBACK (insert_viewer_wrap
),
4325 gtk_widget_show (new_widget
);
4327 lttv_toolbars_add(instance_toolbar
, toolbar_item
->con
,
4328 toolbar_item
->tooltip
,
4329 toolbar_item
->pixmap
,
4337 /* Create a main window
4340 void construct_main_window(MainWindow
* parent
)
4342 g_debug("construct_main_window()");
4343 GtkWidget
* new_window
; /* New generated main window */
4344 MainWindow
* new_m_window
;/* New main window structure */
4345 GtkNotebook
* notebook
;
4346 LttvIAttribute
*attributes
=
4347 LTTV_IATTRIBUTE(g_object_new(LTTV_ATTRIBUTE_TYPE
, NULL
));
4348 LttvAttributeValue value
;
4351 new_m_window
= g_new(MainWindow
, 1);
4353 // Add the object's information to the module's array
4354 g_main_window_list
= g_slist_append(g_main_window_list
, new_m_window
);
4356 new_window
= create_MWindow();
4357 gtk_widget_show (new_window
);
4359 new_m_window
->mwindow
= new_window
;
4360 new_m_window
->attributes
= attributes
;
4362 g_assert(lttv_iattribute_find_by_path(attributes
,
4363 "viewers/menu", LTTV_POINTER
, &value
));
4364 *(value
.v_pointer
) = lttv_menus_new();
4366 g_assert(lttv_iattribute_find_by_path(attributes
,
4367 "viewers/toolbar", LTTV_POINTER
, &value
));
4368 *(value
.v_pointer
) = lttv_toolbars_new();
4370 add_all_menu_toolbar_constructors(new_m_window
, NULL
);
4372 g_object_set_data_full(G_OBJECT(new_window
),
4374 (gpointer
)new_m_window
,
4375 (GDestroyNotify
)g_free
);
4376 //create a default tab
4377 notebook
= (GtkNotebook
*)lookup_widget(new_m_window
->mwindow
, "MNotebook");
4378 if(notebook
== NULL
){
4379 g_printf("Notebook does not exist\n");
4382 //gtk_notebook_popup_enable (GTK_NOTEBOOK(notebook));
4383 //for now there is no name field in LttvTraceset structure
4384 //Use "Traceset" as the label for the default tab
4386 GtkWidget
* parent_notebook
= lookup_widget(parent
->mwindow
, "MNotebook");
4387 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(parent_notebook
),
4388 gtk_notebook_get_current_page(GTK_NOTEBOOK(parent_notebook
)));
4394 parent_tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
4396 new_tab
= create_tab(new_m_window
, parent_tab
, notebook
, "Traceset");
4398 new_tab
= create_tab(new_m_window
, NULL
, notebook
, "Traceset");
4399 /* First window, use command line trace */
4400 if(g_init_trace
!= NULL
){
4401 lttvwindow_add_trace(new_tab
,
4405 LttvTraceset
*traceset
= new_tab
->traceset_info
->traceset
;
4406 SetTraceset(new_tab
, traceset
);
4408 /* Insert default viewers */
4410 LttvAttributeType type
;
4411 LttvAttributeName name
;
4412 LttvAttributeValue value
;
4413 LttvAttribute
*attribute
;
4415 LttvIAttribute
*attributes_global
=
4416 LTTV_IATTRIBUTE(lttv_global_attributes());
4418 g_assert(attribute
=
4419 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
4420 LTTV_IATTRIBUTE(attributes_global
),
4421 LTTV_VIEWER_CONSTRUCTORS
)));
4423 name
= g_quark_from_string("guievents");
4424 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
4426 if(type
== LTTV_POINTER
) {
4427 lttvwindow_viewer_constructor viewer_constructor
=
4428 (lttvwindow_viewer_constructor
)*value
.v_pointer
;
4429 insert_viewer(new_window
, viewer_constructor
);
4432 name
= g_quark_from_string("guicontrolflow");
4433 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
4435 if(type
== LTTV_POINTER
) {
4436 lttvwindow_viewer_constructor viewer_constructor
=
4437 (lttvwindow_viewer_constructor
)*value
.v_pointer
;
4438 insert_viewer(new_window
, viewer_constructor
);
4441 name
= g_quark_from_string("guistatistics");
4442 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
4444 if(type
== LTTV_POINTER
) {
4445 lttvwindow_viewer_constructor viewer_constructor
=
4446 (lttvwindow_viewer_constructor
)*value
.v_pointer
;
4447 insert_viewer(new_window
, viewer_constructor
);
4453 g_printf("There are now : %d windows\n",g_slist_length(g_main_window_list
));
4457 /* Free the memory occupied by a tab structure
4461 void tab_destructor(Tab
* tab
)
4463 int i
, nb
, ref_count
;
4466 gtk_object_destroy(GTK_OBJECT(tab
->tooltips
));
4469 g_object_unref(tab
->attributes
);
4471 if(tab
->interrupted_state
)
4472 g_object_unref(tab
->interrupted_state
);
4475 if(tab
->traceset_info
->traceset_context
!= NULL
){
4476 //remove state update hooks
4477 lttv_state_remove_event_hooks(
4478 (LttvTracesetState
*)tab
->traceset_info
->
4480 lttv_context_fini(LTTV_TRACESET_CONTEXT(tab
->traceset_info
->
4482 g_object_unref(tab
->traceset_info
->traceset_context
);
4484 if(tab
->traceset_info
->traceset
!= NULL
) {
4485 nb
= lttv_traceset_number(tab
->traceset_info
->traceset
);
4486 for(i
= 0 ; i
< nb
; i
++) {
4487 trace
= lttv_traceset_get(tab
->traceset_info
->traceset
, i
);
4488 ref_count
= lttv_trace_get_ref_number(trace
);
4490 ltt_trace_close(lttv_trace(trace
));
4494 lttv_traceset_destroy(tab
->traceset_info
->traceset
);
4495 /* Remove the idle events requests processing function of the tab */
4496 g_idle_remove_by_data(tab
);
4498 g_slist_free(tab
->events_requests
);
4499 g_free(tab
->traceset_info
);
4504 /* Create a tab and insert it into the current main window
4507 Tab
* create_tab(MainWindow
* mw
, Tab
*copy_tab
,
4508 GtkNotebook
* notebook
, char * label
)
4514 //create a new tab data structure
4517 //construct and initialize the traceset_info
4518 tab
->traceset_info
= g_new(TracesetInfo
,1);
4521 tab
->traceset_info
->traceset
=
4522 lttv_traceset_copy(copy_tab
->traceset_info
->traceset
);
4524 tab
->traceset_info
->traceset
= lttv_traceset_new();
4528 lttv_attribute_write_xml(
4529 lttv_traceset_attribute(tab
->traceset_info
->traceset
),
4535 tab
->time_manager_lock
= FALSE
;
4536 tab
->current_time_manager_lock
= FALSE
;
4538 //FIXME copy not implemented in lower level
4539 tab
->traceset_info
->traceset_context
=
4540 g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
4541 g_assert(tab
->traceset_info
->traceset_context
!= NULL
);
4543 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
),
4544 tab
->traceset_info
->traceset
);
4545 //add state update hooks
4546 lttv_state_add_event_hooks(
4547 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
4549 //determine the current_time and time_window of the tab
4551 if(copy_tab
!= NULL
){
4552 tab
->time_window
= copy_tab
->time_window
;
4553 tab
->current_time
= copy_tab
->current_time
;
4555 tab
->time_window
.start_time
=
4556 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
4557 time_span
.start_time
;
4558 if(DEFAULT_TIME_WIDTH_S
<
4559 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
4560 time_span
.end_time
.tv_sec
)
4561 tmp_time
.tv_sec
= DEFAULT_TIME_WIDTH_S
;
4564 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
4565 time_span
.end_time
.tv_sec
;
4566 tmp_time
.tv_nsec
= 0;
4567 tab
->time_window
.time_width
= tmp_time
;
4568 tab
->current_time
.tv_sec
=
4569 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
4570 time_span
.start_time
.tv_sec
;
4571 tab
->current_time
.tv_nsec
=
4572 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
4573 time_span
.start_time
.tv_nsec
;
4576 tab
->attributes
= LTTV_IATTRIBUTE(g_object_new(LTTV_ATTRIBUTE_TYPE
, NULL
));
4577 tab
->interrupted_state
= g_object_new(LTTV_ATTRIBUTE_TYPE
, NULL
);
4579 tab
->vbox
= gtk_vbox_new(FALSE
, 2);
4580 tab
->viewer_container
= gtk_vbox_new(TRUE
, 2);
4581 tab
->scrollbar
= gtk_hscrollbar_new(NULL
);
4582 //tab->multivpaned = gtk_multi_vpaned_new();
4584 gtk_box_pack_start(GTK_BOX(tab
->vbox
),
4585 tab
->viewer_container
,
4587 TRUE
, /* Give the extra space to the child */
4588 0); /* No padding */
4590 /* Create the timebar */
4592 tab
->MTimebar
= gtk_hbox_new(FALSE
, 2);
4593 gtk_widget_show(tab
->MTimebar
);
4594 tab
->tooltips
= gtk_tooltips_new();
4596 tab
->MEventBox1a
= gtk_event_box_new();
4597 gtk_widget_show(tab
->MEventBox1a
);
4598 gtk_tooltips_set_tip(tab
->tooltips
, tab
->MEventBox1a
,
4599 "Paste Start and End Times Here", "");
4600 tab
->MText1a
= gtk_label_new("Time Frame ");
4601 gtk_widget_show(tab
->MText1a
);
4602 gtk_container_add(GTK_CONTAINER(tab
->MEventBox1a
), tab
->MText1a
);
4603 tab
->MEventBox1b
= gtk_event_box_new();
4604 gtk_widget_show(tab
->MEventBox1b
);
4605 gtk_tooltips_set_tip(tab
->tooltips
, tab
->MEventBox1b
,
4606 "Paste Start Time Here", "");
4607 tab
->MText1b
= gtk_label_new("start: ");
4608 gtk_widget_show(tab
->MText1b
);
4609 gtk_container_add(GTK_CONTAINER(tab
->MEventBox1b
), tab
->MText1b
);
4610 tab
->MText2
= gtk_label_new("s");
4611 gtk_widget_show(tab
->MText2
);
4612 tab
->MText3a
= gtk_label_new("ns");
4613 gtk_widget_show(tab
->MText3a
);
4614 tab
->MEventBox3b
= gtk_event_box_new();
4615 gtk_widget_show(tab
->MEventBox3b
);
4616 gtk_tooltips_set_tip(tab
->tooltips
, tab
->MEventBox3b
,
4617 "Paste End Time Here", "");
4618 tab
->MText3b
= gtk_label_new("end:");
4619 gtk_widget_show(tab
->MText3b
);
4620 gtk_container_add(GTK_CONTAINER(tab
->MEventBox3b
), tab
->MText3b
);
4621 tab
->MText4
= gtk_label_new("s");
4622 gtk_widget_show(tab
->MText4
);
4623 tab
->MText5a
= gtk_label_new("ns");
4624 gtk_widget_show(tab
->MText5a
);
4625 tab
->MEventBox5b
= gtk_event_box_new();
4626 gtk_widget_show(tab
->MEventBox5b
);
4627 gtk_tooltips_set_tip(tab
->tooltips
, tab
->MEventBox5b
,
4628 "Paste Current Time Here", "");
4629 tab
->MText5b
= gtk_label_new("Current Time:");
4630 gtk_widget_show(tab
->MText5b
);
4631 gtk_container_add(GTK_CONTAINER(tab
->MEventBox5b
), tab
->MText5b
);
4632 tab
->MText6
= gtk_label_new("s");
4633 gtk_widget_show(tab
->MText6
);
4634 tab
->MText7
= gtk_label_new("ns");
4635 gtk_widget_show(tab
->MText7
);
4637 tab
->MEntry1
= gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4638 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab
->MEntry1
),0);
4639 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab
->MEntry1
),TRUE
);
4640 gtk_widget_show(tab
->MEntry1
);
4641 tab
->MEntry2
= gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4642 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab
->MEntry2
),0);
4643 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab
->MEntry2
),TRUE
);
4644 gtk_widget_show(tab
->MEntry2
);
4645 tab
->MEntry3
= gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4646 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab
->MEntry3
),0);
4647 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab
->MEntry3
),TRUE
);
4648 gtk_widget_show(tab
->MEntry3
);
4649 tab
->MEntry4
= gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4650 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab
->MEntry4
),0);
4651 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab
->MEntry4
),TRUE
);
4652 gtk_widget_show(tab
->MEntry4
);
4653 tab
->MEntry5
= gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4654 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab
->MEntry5
),0);
4655 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab
->MEntry5
),TRUE
);
4656 gtk_widget_show(tab
->MEntry5
);
4657 tab
->MEntry6
= gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4658 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab
->MEntry6
),0);
4659 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab
->MEntry6
),TRUE
);
4660 gtk_widget_show(tab
->MEntry6
);
4663 GtkWidget
*temp_widget
;
4665 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEventBox1a
, FALSE
,
4667 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEventBox1b
, FALSE
,
4669 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEntry1
, FALSE
, FALSE
, 0);
4670 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MText2
, FALSE
, FALSE
, 0);
4671 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEntry2
, FALSE
, FALSE
, 0);
4672 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MText3a
, FALSE
, FALSE
, 0);
4673 temp_widget
= gtk_vseparator_new();
4674 gtk_widget_show(temp_widget
);
4675 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), temp_widget
, FALSE
, FALSE
, 0);
4676 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEventBox3b
, FALSE
,
4678 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEntry3
, FALSE
, FALSE
, 0);
4679 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MText4
, FALSE
, FALSE
, 0);
4680 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEntry4
, FALSE
, FALSE
, 0);
4681 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MText5a
, FALSE
, FALSE
, 0);
4682 temp_widget
= gtk_vseparator_new();
4683 gtk_widget_show(temp_widget
);
4684 gtk_box_pack_end (GTK_BOX (tab
->MTimebar
), tab
->MText7
, FALSE
, FALSE
, 0);
4685 gtk_box_pack_end (GTK_BOX (tab
->MTimebar
), tab
->MEntry6
, FALSE
, FALSE
, 0);
4686 gtk_box_pack_end (GTK_BOX (tab
->MTimebar
), tab
->MText6
, FALSE
, FALSE
, 0);
4687 gtk_box_pack_end (GTK_BOX (tab
->MTimebar
), tab
->MEntry5
, FALSE
, FALSE
, 0);
4688 gtk_box_pack_end (GTK_BOX (tab
->MTimebar
), tab
->MEventBox5b
, FALSE
,
4690 gtk_box_pack_end (GTK_BOX (tab
->MTimebar
), temp_widget
, FALSE
, FALSE
, 0);
4693 //GtkWidget *test = gtk_button_new_with_label("drop");
4694 //gtk_button_set_relief(GTK_BUTTON(test), GTK_RELIEF_NONE);
4695 //gtk_widget_show(test);
4696 //gtk_box_pack_end(GTK_BOX (tab->MTimebar), test, FALSE, FALSE, 0);
4697 //gtk_widget_add_events(tab->MText1, GDK_ALL_EVENTS_MASK);//GDK_BUTTON_PRESS_MASK);
4698 /*GtkWidget *event_box = gtk_event_box_new();
4699 gtk_widget_show(event_box);
4700 gtk_tooltips_set_tip(tooltips, event_box,
4701 "Paste Current Time Here", "");
4702 gtk_box_pack_end(GTK_BOX (tab->MTimebar), event_box, FALSE, FALSE, 0);
4703 GtkWidget *test = gtk_label_new("drop");
4704 gtk_container_add(GTK_CONTAINER(event_box), test);
4705 gtk_widget_show(test);
4706 g_signal_connect (G_OBJECT(event_box),
4707 "button-press-event",
4708 G_CALLBACK (on_MText1_paste),
4712 g_signal_connect (G_OBJECT(tab
->MEventBox1a
),
4713 "button-press-event",
4714 G_CALLBACK (on_MEventBox1a_paste
),
4717 g_signal_connect (G_OBJECT(tab
->MEventBox1b
),
4718 "button-press-event",
4719 G_CALLBACK (on_MEventBox1b_paste
),
4721 g_signal_connect (G_OBJECT(tab
->MEventBox3b
),
4722 "button-press-event",
4723 G_CALLBACK (on_MEventBox3b_paste
),
4725 g_signal_connect (G_OBJECT(tab
->MEventBox5b
),
4726 "button-press-event",
4727 G_CALLBACK (on_MEventBox5b_paste
),
4731 gtk_box_pack_end(GTK_BOX(tab
->vbox
),
4733 FALSE
, /* Do not expand */
4734 FALSE
, /* Fill has no effect here (expand false) */
4735 0); /* No padding */
4737 gtk_box_pack_end(GTK_BOX(tab
->vbox
),
4739 FALSE
, /* Do not expand */
4740 FALSE
, /* Fill has no effect here (expand false) */
4741 0); /* No padding */
4743 g_object_set_data(G_OBJECT(tab
->viewer_container
), "focused_viewer", NULL
);
4749 // Display a label with a X
4750 GtkWidget *w_hbox = gtk_hbox_new(FALSE, 4);
4751 GtkWidget *w_label = gtk_label_new (label);
4752 GtkWidget *pixmap = create_pixmap(GTK_WIDGET(notebook), "close.png");
4753 GtkWidget *w_button = gtk_button_new ();
4754 gtk_container_add(GTK_CONTAINER(w_button), pixmap);
4755 //GtkWidget *w_button = gtk_button_new_with_label("x");
4757 gtk_button_set_relief(GTK_BUTTON(w_button), GTK_RELIEF_NONE);
4759 gtk_box_pack_start(GTK_BOX(w_hbox), w_label, TRUE, TRUE, 0);
4760 gtk_box_pack_end(GTK_BOX(w_hbox), w_button, FALSE,
4763 g_signal_connect_swapped (w_button, "clicked",
4764 G_CALLBACK (on_close_tab_X_clicked),
4767 gtk_widget_set_state(w_button, GTK_STATE_ACTIVE);
4769 gtk_widget_show (w_label);
4770 gtk_widget_show (pixmap);
4771 gtk_widget_show (w_button);
4772 gtk_widget_show (w_hbox);
4774 tab->label = w_hbox;
4778 tab
->label
= gtk_label_new (label
);
4780 gtk_widget_show(tab
->label
);
4781 gtk_widget_show(tab
->scrollbar
);
4782 gtk_widget_show(tab
->viewer_container
);
4783 gtk_widget_show(tab
->vbox
);
4784 //gtk_widget_show(tab->multivpaned);
4787 /* Start with empty events requests list */
4788 tab
->events_requests
= NULL
;
4789 tab
->events_request_pending
= FALSE
;
4791 g_object_set_data_full(
4792 G_OBJECT(tab
->vbox
),
4795 (GDestroyNotify
)tab_destructor
);
4797 g_signal_connect(G_OBJECT(tab
->scrollbar
), "value-changed",
4798 G_CALLBACK(scroll_value_changed_cb
), tab
);
4800 g_signal_connect ((gpointer
) tab
->MEntry1
, "value-changed",
4801 G_CALLBACK (on_MEntry1_value_changed
),
4803 g_signal_connect ((gpointer
) tab
->MEntry2
, "value-changed",
4804 G_CALLBACK (on_MEntry2_value_changed
),
4806 g_signal_connect ((gpointer
) tab
->MEntry3
, "value-changed",
4807 G_CALLBACK (on_MEntry3_value_changed
),
4809 g_signal_connect ((gpointer
) tab
->MEntry4
, "value-changed",
4810 G_CALLBACK (on_MEntry4_value_changed
),
4812 g_signal_connect ((gpointer
) tab
->MEntry5
, "value-changed",
4813 G_CALLBACK (on_MEntry5_value_changed
),
4815 g_signal_connect ((gpointer
) tab
->MEntry6
, "value-changed",
4816 G_CALLBACK (on_MEntry6_value_changed
),
4819 //g_signal_connect(G_OBJECT(tab->scrollbar), "changed",
4820 // G_CALLBACK(scroll_value_changed_cb), tab);
4823 //insert tab into notebook
4824 gtk_notebook_append_page(notebook
,
4827 list
= gtk_container_get_children(GTK_CONTAINER(notebook
));
4828 gtk_notebook_set_current_page(notebook
,g_list_length(list
)-1);
4829 // always show : not if(g_list_length(list)>1)
4830 gtk_notebook_set_show_tabs(notebook
, TRUE
);
4836 * execute_events_requests
4838 * Idle function that executes the pending requests for a tab.
4840 * @return return value : TRUE : keep the idle function, FALSE : remove it.
4842 gboolean
execute_events_requests(Tab
*tab
)
4844 return ( lttvwindow_process_pending_requests(tab
) );