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( ltt_time_add(tab
->time_window
.start_time
,
475 tab
->time_window
.time_width
),
476 time_span
.end_time
) > 0) {
477 new_time_window
.start_time
= time_span
.start_time
;
479 new_current_time
= time_span
.start_time
;
483 if(DEFAULT_TIME_WIDTH_S
< time_span
.end_time
.tv_sec
)
484 tmp_time
.tv_sec
= DEFAULT_TIME_WIDTH_S
;
486 tmp_time
.tv_sec
= time_span
.end_time
.tv_sec
;
487 tmp_time
.tv_nsec
= 0;
488 new_time_window
.time_width
= tmp_time
;
490 time_change_manager(tab
, new_time_window
);
491 current_time_change_manager(tab
, new_current_time
);
495 GtkAdjustment
*adjustment
= gtk_range_get_adjustment(GTK_RANGE(tab
->scrollbar
));
496 LttTime upper
= ltt_time_sub(time_span
.end_time
, time_span
.start_time
);
498 g_object_set(G_OBJECT(adjustment
),
502 ltt_time_to_double(upper
)
503 * NANOSECONDS_PER_SECOND
, /* upper */
505 ltt_time_to_double(tab
->time_window
.time_width
)
506 / SCROLL_STEP_PER_PAGE
507 * NANOSECONDS_PER_SECOND
, /* step increment */
509 ltt_time_to_double(tab
->time_window
.time_width
)
510 * NANOSECONDS_PER_SECOND
, /* page increment */
512 ltt_time_to_double(tab
->time_window
.time_width
)
513 * NANOSECONDS_PER_SECOND
, /* page size */
515 gtk_adjustment_changed(adjustment
);
517 g_object_set(G_OBJECT(adjustment
),
520 ltt_time_sub(tab
->time_window
.start_time
, time_span
.start_time
))
521 * NANOSECONDS_PER_SECOND
, /* value */
523 gtk_adjustment_value_changed(adjustment
);
525 /* set the time bar. The value callbacks will change their nsec themself */
527 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry1
),
528 (double)time_span
.start_time
.tv_sec
,
529 (double)time_span
.end_time
.tv_sec
);
532 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry3
),
533 (double)time_span
.start_time
.tv_sec
,
534 (double)time_span
.end_time
.tv_sec
);
536 /* current seconds */
537 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry5
),
538 (double)time_span
.start_time
.tv_sec
,
539 (double)time_span
.end_time
.tv_sec
);
542 /* Finally, call the update hooks of the viewers */
544 LttvAttributeValue value
;
548 g_assert( lttv_iattribute_find_by_path(tab
->attributes
,
549 "hooks/updatetraceset", LTTV_POINTER
, &value
));
551 tmp
= (LttvHooks
*)*(value
.v_pointer
);
552 if(tmp
== NULL
) retval
= 1;
553 else lttv_hooks_call(tmp
,traceset
);
560 * Function to set/update filter for the viewers
561 * @param tab viewer's tab
562 * @param filter filter of the main window.
565 * 0 : filters updated
566 * 1 : no filter hooks to update; not an error.
569 int SetFilter(Tab
* tab
, gpointer filter
)
572 LttvAttributeValue value
;
574 g_assert(lttv_iattribute_find_by_path(tab
->attributes
,
575 "hooks/updatefilter", LTTV_POINTER
, &value
));
577 tmp
= (LttvHooks
*)*(value
.v_pointer
);
579 if(tmp
== NULL
) return 1;
580 lttv_hooks_call(tmp
,filter
);
588 * Function to redraw each viewer belonging to the current tab
589 * @param tab viewer's tab
592 void update_traceset(Tab
*tab
)
594 LttvAttributeValue value
;
596 g_assert(lttv_iattribute_find_by_path(tab
->attributes
,
597 "hooks/updatetraceset", LTTV_POINTER
, &value
));
598 tmp
= (LttvHooks
*)*(value
.v_pointer
);
599 if(tmp
== NULL
) return;
600 lttv_hooks_call(tmp
, NULL
);
604 /* get_label function is used to get user input, it displays an input
605 * box, which allows user to input a string
608 void get_label_string (GtkWidget
* text
, gchar
* label
)
610 GtkEntry
* entry
= (GtkEntry
*)text
;
611 if(strlen(gtk_entry_get_text(entry
))!=0)
612 strcpy(label
,gtk_entry_get_text(entry
));
615 gboolean
get_label(MainWindow
* mw
, gchar
* str
, gchar
* dialogue_title
, gchar
* label_str
)
617 GtkWidget
* dialogue
;
622 dialogue
= gtk_dialog_new_with_buttons(dialogue_title
,NULL
,
624 GTK_STOCK_OK
,GTK_RESPONSE_ACCEPT
,
625 GTK_STOCK_CANCEL
,GTK_RESPONSE_REJECT
,
628 label
= gtk_label_new(label_str
);
629 gtk_widget_show(label
);
631 text
= gtk_entry_new();
632 gtk_widget_show(text
);
634 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialogue
)->vbox
), label
,TRUE
, TRUE
,0);
635 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialogue
)->vbox
), text
,FALSE
, FALSE
,0);
637 id
= gtk_dialog_run(GTK_DIALOG(dialogue
));
639 case GTK_RESPONSE_ACCEPT
:
640 get_label_string(text
,str
);
641 gtk_widget_destroy(dialogue
);
643 case GTK_RESPONSE_REJECT
:
645 gtk_widget_destroy(dialogue
);
652 /* get_window_data_struct function is actually a lookup function,
653 * given a widget which is in the tree of the main window, it will
654 * return the MainWindow data structure associated with main window
657 MainWindow
* get_window_data_struct(GtkWidget
* widget
)
660 MainWindow
* mw_data
;
662 mw
= lookup_widget(widget
, "MWindow");
664 g_printf("Main window does not exist\n");
668 mw_data
= (MainWindow
*) g_object_get_data(G_OBJECT(mw
),"main_window_data");
670 g_printf("Main window data does not exist\n");
677 /* create_new_window function, just constructs a new main window
680 void create_new_window(GtkWidget
* widget
, gpointer user_data
, gboolean clone
)
682 MainWindow
* parent
= get_window_data_struct(widget
);
685 g_printf("Clone : use the same traceset\n");
686 construct_main_window(parent
);
688 g_printf("Empty : traceset is set to NULL\n");
689 construct_main_window(NULL
);
693 /* Get the currently focused viewer.
694 * If no viewer is focused, use the first one.
696 * If no viewer available, return NULL.
698 GtkWidget
*viewer_container_focus(GtkWidget
*container
)
702 widget
= (GtkWidget
*)g_object_get_data(G_OBJECT(container
),
706 g_debug("no widget focused");
707 GList
*children
= gtk_container_get_children(GTK_CONTAINER(container
));
710 widget
= GTK_WIDGET(children
->data
);
711 g_object_set_data(G_OBJECT(container
),
721 gint
viewer_container_position(GtkWidget
*container
, GtkWidget
*child
)
724 if(child
== NULL
) return -1;
727 GValue value
= { 0, };
728 g_value_init(&value
, G_TYPE_INT
);
729 gtk_container_child_get_property(GTK_CONTAINER(container
),
733 pos
= g_value_get_int(&value
);
739 /* move_*_viewer functions move the selected view up/down in
743 void move_down_viewer(GtkWidget
* widget
, gpointer user_data
)
745 MainWindow
* mw
= get_window_data_struct(widget
);
746 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
748 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
749 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
755 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
758 //gtk_multivpaned_widget_move_up(GTK_MULTIVPANED(tab->multivpaned));
760 /* change the position in the vbox */
761 GtkWidget
*focus_widget
;
763 focus_widget
= viewer_container_focus(tab
->viewer_container
);
764 position
= viewer_container_position(tab
->viewer_container
, focus_widget
);
767 /* can move up one position */
768 gtk_box_reorder_child(GTK_BOX(tab
->viewer_container
),
775 void move_up_viewer(GtkWidget
* widget
, gpointer user_data
)
777 MainWindow
* mw
= get_window_data_struct(widget
);
778 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
780 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
781 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
787 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
790 //gtk_multivpaned_widget_move_down(GTK_MULTIVPANED(tab->multivpaned));
791 /* change the position in the vbox */
792 GtkWidget
*focus_widget
;
794 focus_widget
= viewer_container_focus(tab
->viewer_container
);
795 position
= viewer_container_position(tab
->viewer_container
, focus_widget
);
799 g_list_length(gtk_container_get_children(
800 GTK_CONTAINER(tab
->viewer_container
)))-1
802 /* can move down one position */
803 gtk_box_reorder_child(GTK_BOX(tab
->viewer_container
),
811 /* delete_viewer deletes the selected viewer in the current tab
814 void delete_viewer(GtkWidget
* widget
, gpointer user_data
)
816 MainWindow
* mw
= get_window_data_struct(widget
);
817 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
819 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
820 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
826 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
829 //gtk_multivpaned_widget_delete(GTK_MULTIVPANED(tab->multivpaned));
831 GtkWidget
*focus_widget
= viewer_container_focus(tab
->viewer_container
);
833 if(focus_widget
!= NULL
)
834 gtk_widget_destroy(focus_widget
);
836 g_object_set_data(G_OBJECT(tab
->viewer_container
), "focused_viewer", NULL
);
840 /* open_traceset will open a traceset saved in a file
841 * Right now, it is not finished yet, (not working)
845 void open_traceset(GtkWidget
* widget
, gpointer user_data
)
849 LttvTraceset
* traceset
;
850 MainWindow
* mw_data
= get_window_data_struct(widget
);
851 GtkFileSelection
* file_selector
=
852 (GtkFileSelection
*)gtk_file_selection_new("Select a traceset");
854 gtk_file_selection_hide_fileop_buttons(file_selector
);
856 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
858 case GTK_RESPONSE_ACCEPT
:
859 case GTK_RESPONSE_OK
:
860 dir
= gtk_file_selection_get_selections (file_selector
);
861 traceset
= lttv_traceset_load(dir
[0]);
862 g_printf("Open a trace set %s\n", dir
[0]);
865 case GTK_RESPONSE_REJECT
:
866 case GTK_RESPONSE_CANCEL
:
868 gtk_widget_destroy((GtkWidget
*)file_selector
);
874 static void events_request_free(EventsRequest
*events_request
)
876 if(events_request
== NULL
) return;
878 if(events_request
->start_position
!= NULL
)
879 lttv_traceset_context_position_destroy(events_request
->start_position
);
880 if(events_request
->end_position
!= NULL
)
881 lttv_traceset_context_position_destroy(events_request
->end_position
);
882 if(events_request
->before_chunk_traceset
!= NULL
)
883 lttv_hooks_destroy(events_request
->before_chunk_traceset
);
884 if(events_request
->before_chunk_trace
!= NULL
)
885 lttv_hooks_destroy(events_request
->before_chunk_trace
);
886 if(events_request
->before_chunk_tracefile
!= NULL
)
887 lttv_hooks_destroy(events_request
->before_chunk_tracefile
);
888 if(events_request
->event
!= NULL
)
889 lttv_hooks_destroy(events_request
->event
);
890 if(events_request
->event_by_id
!= NULL
)
891 lttv_hooks_by_id_destroy(events_request
->event_by_id
);
892 if(events_request
->after_chunk_tracefile
!= NULL
)
893 lttv_hooks_destroy(events_request
->after_chunk_tracefile
);
894 if(events_request
->after_chunk_trace
!= NULL
)
895 lttv_hooks_destroy(events_request
->after_chunk_trace
);
896 if(events_request
->after_chunk_traceset
!= NULL
)
897 lttv_hooks_destroy(events_request
->after_chunk_traceset
);
898 if(events_request
->before_request
!= NULL
)
899 lttv_hooks_destroy(events_request
->before_request
);
900 if(events_request
->after_request
!= NULL
)
901 lttv_hooks_destroy(events_request
->after_request
);
903 g_free(events_request
);
908 /* lttvwindow_process_pending_requests
910 * This internal function gets called by g_idle, taking care of the pending
911 * requests. It is responsible for concatenation of time intervals and position
912 * requests. It does it with the following algorithm organizing process traceset
913 * calls. Here is the detailed description of the way it works :
915 * - Events Requests Servicing Algorithm
917 * Data structures necessary :
919 * List of requests added to context : list_in
920 * List of requests not added to context : list_out
925 * list_out : many events requests
927 * FIXME : insert rest of algorithm here
931 #define list_out tab->events_requests
933 gboolean
lttvwindow_process_pending_requests(Tab
*tab
)
935 unsigned max_nb_events
;
939 LttvTracesetContext
*tsc
;
940 LttvTracefileContext
*tfc
;
941 GSList
*list_in
= NULL
;
945 LttvTracesetContextPosition
*end_position
;
948 g_critical("Foreground processing : tab does not exist. Processing removed.");
952 /* There is no events requests pending : we should never have been called! */
953 g_assert(g_slist_length(list_out
) != 0);
955 tsc
= LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
957 //set the cursor to be X shape, indicating that the computer is busy in doing its job
959 new = gdk_cursor_new(GDK_X_CURSOR
);
960 widget
= lookup_widget(tab
->mw
->mwindow
, "MToolbar1");
961 win
= gtk_widget_get_parent_window(widget
);
962 gdk_window_set_cursor(win
, new);
963 gdk_cursor_unref(new);
964 gdk_window_stick(win
);
965 gdk_window_unstick(win
);
968 g_debug("SIZE events req len : %d", g_slist_length(list_out
));
970 /* Preliminary check for no trace in traceset */
971 /* Unregister the routine if empty, empty list_out too */
972 if(lttv_traceset_number(tsc
->ts
) == 0) {
974 /* - For each req in list_out */
975 GSList
*iter
= list_out
;
977 while(iter
!= NULL
) {
979 gboolean remove
= FALSE
;
980 gboolean free_data
= FALSE
;
981 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
983 /* - Call end request for req */
984 if(events_request
->servicing
== TRUE
)
985 lttv_hooks_call(events_request
->after_request
, (gpointer
)tsc
);
987 /* - remove req from list_out */
988 /* Destroy the request */
995 GSList
*remove_iter
= iter
;
997 iter
= g_slist_next(iter
);
998 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
999 list_out
= g_slist_remove_link(list_out
, remove_iter
);
1000 } else { // not remove
1001 iter
= g_slist_next(iter
);
1006 /* 0.1 Lock Traces */
1011 iter_trace
<lttv_traceset_number(tsc
->ts
);
1013 LttvTrace
*trace_v
= lttv_traceset_get(tsc
->ts
, iter_trace
);
1015 if(lttvwindowtraces_lock(trace_v
) != 0) {
1016 g_critical("Foreground processing : Unable to get trace lock");
1017 return TRUE
; /* Cannot get lock, try later */
1022 /* 0.2 Seek tracefiles positions to context position */
1023 lttv_process_traceset_synchronize_tracefiles(tsc
);
1026 /* Events processing algorithm implementation */
1027 /* Warning : the gtk_events_pending takes a LOT of cpu time. So what we do
1028 * instead is to leave the control to GTK and take it back.
1030 /* A. Servicing loop */
1031 //while( (g_slist_length(list_in) != 0 || g_slist_length(list_out) != 0)) {
1032 if((g_slist_length(list_in
) != 0 || g_slist_length(list_out
) != 0)) {
1034 /* 1. If list_in is empty (need a seek) */
1035 if( g_slist_length(list_in
) == 0 ) {
1037 /* list in is empty, need a seek */
1039 /* 1.1 Add requests to list_in */
1040 GSList
*ltime
= NULL
;
1041 GSList
*lpos
= NULL
;
1042 GSList
*iter
= NULL
;
1044 /* 1.1.1 Find all time requests with the lowest start time in list_out
1047 if(g_slist_length(list_out
) > 0)
1048 ltime
= g_slist_append(ltime
, g_slist_nth_data(list_out
, 0));
1049 for(iter
=g_slist_nth(list_out
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
1050 /* Find all time requests with the lowest start time in list_out */
1051 guint index_ltime
= g_array_index(ltime
, guint
, 0);
1052 EventsRequest
*event_request_ltime
= (EventsRequest
*)g_slist_nth_data(ltime
, 0);
1053 EventsRequest
*event_request_list_out
= (EventsRequest
*)iter
->data
;
1056 comp
= ltt_time_compare(event_request_ltime
->start_time
,
1057 event_request_list_out
->start_time
);
1059 ltime
= g_slist_append(ltime
, event_request_list_out
);
1061 /* Remove all elements from ltime, and add current */
1062 while(ltime
!= NULL
)
1063 ltime
= g_slist_delete_link(ltime
, g_slist_nth(ltime
, 0));
1064 ltime
= g_slist_append(ltime
, event_request_list_out
);
1068 /* 1.1.2 Find all position requests with the lowest position in list_out
1071 if(g_slist_length(list_out
) > 0)
1072 lpos
= g_slist_append(lpos
, g_slist_nth_data(list_out
, 0));
1073 for(iter
=g_slist_nth(list_out
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
1074 /* Find all position requests with the lowest position in list_out */
1075 EventsRequest
*event_request_lpos
= (EventsRequest
*)g_slist_nth_data(lpos
, 0);
1076 EventsRequest
*event_request_list_out
= (EventsRequest
*)iter
->data
;
1079 if(event_request_lpos
->start_position
!= NULL
1080 && event_request_list_out
->start_position
!= NULL
)
1082 comp
= lttv_traceset_context_pos_pos_compare
1083 (event_request_lpos
->start_position
,
1084 event_request_list_out
->start_position
);
1089 lpos
= g_slist_append(lpos
, event_request_list_out
);
1091 /* Remove all elements from lpos, and add current */
1093 lpos
= g_slist_delete_link(lpos
, g_slist_nth(lpos
, 0));
1094 lpos
= g_slist_append(lpos
, event_request_list_out
);
1099 EventsRequest
*event_request_lpos
= (EventsRequest
*)g_slist_nth_data(lpos
, 0);
1100 EventsRequest
*event_request_ltime
= (EventsRequest
*)g_slist_nth_data(ltime
, 0);
1101 LttTime lpos_start_time
;
1103 if(event_request_lpos
!= NULL
1104 && event_request_lpos
->start_position
!= NULL
) {
1105 lpos_start_time
= lttv_traceset_context_position_get_time(
1106 event_request_lpos
->start_position
);
1109 /* 1.1.3 If lpos.start time < ltime */
1110 if(event_request_lpos
!= NULL
1111 && event_request_lpos
->start_position
!= NULL
1112 && ltt_time_compare(lpos_start_time
,
1113 event_request_ltime
->start_time
)<0) {
1114 /* Add lpos to list_in, remove them from list_out */
1115 for(iter
=lpos
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
1116 /* Add to list_in */
1117 EventsRequest
*event_request_lpos
=
1118 (EventsRequest
*)iter
->data
;
1120 list_in
= g_slist_append(list_in
, event_request_lpos
);
1121 /* Remove from list_out */
1122 list_out
= g_slist_remove(list_out
, event_request_lpos
);
1125 /* 1.1.4 (lpos.start time >= ltime) */
1126 /* Add ltime to list_in, remove them from list_out */
1128 for(iter
=ltime
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
1129 /* Add to list_in */
1130 EventsRequest
*event_request_ltime
=
1131 (EventsRequest
*)iter
->data
;
1133 list_in
= g_slist_append(list_in
, event_request_ltime
);
1134 /* Remove from list_out */
1135 list_out
= g_slist_remove(list_out
, event_request_ltime
);
1140 g_slist_free(ltime
);
1145 tfc
= lttv_traceset_context_get_current_tfc(tsc
);
1146 g_assert(g_slist_length(list_in
)>0);
1147 EventsRequest
*events_request
= g_slist_nth_data(list_in
, 0);
1150 /* 1.2.1 If first request in list_in is a time request */
1151 if(events_request
->start_position
== NULL
) {
1152 /* - If first req in list_in start time != current time */
1153 if(tfc
== NULL
|| ltt_time_compare(events_request
->start_time
,
1154 tfc
->timestamp
) != 0)
1155 /* - Seek to that time */
1156 g_debug("SEEK TIME : %lu, %lu", events_request
->start_time
.tv_sec
,
1157 events_request
->start_time
.tv_nsec
);
1158 //lttv_process_traceset_seek_time(tsc, events_request->start_time);
1159 lttv_state_traceset_seek_time_closest(LTTV_TRACESET_STATE(tsc
),
1160 events_request
->start_time
);
1162 /* Process the traceset with only state hooks */
1164 lttv_process_traceset_middle(tsc
,
1165 events_request
->start_time
,
1171 /* Else, the first request in list_in is a position request */
1172 /* If first req in list_in pos != current pos */
1173 g_assert(events_request
->start_position
!= NULL
);
1174 g_debug("SEEK POS time : %lu, %lu",
1175 lttv_traceset_context_position_get_time(
1176 events_request
->start_position
).tv_sec
,
1177 lttv_traceset_context_position_get_time(
1178 events_request
->start_position
).tv_nsec
);
1180 g_debug("SEEK POS context time : %lu, %lu",
1181 lttv_traceset_context_get_current_tfc(tsc
)->timestamp
.tv_sec
,
1182 lttv_traceset_context_get_current_tfc(tsc
)->timestamp
.tv_nsec
);
1183 g_assert(events_request
->start_position
!= NULL
);
1184 if(lttv_traceset_context_ctx_pos_compare(tsc
,
1185 events_request
->start_position
) != 0) {
1186 /* 1.2.2.1 Seek to that position */
1187 g_debug("SEEK POSITION");
1188 //lttv_process_traceset_seek_position(tsc, events_request->start_position);
1189 pos_time
= lttv_traceset_context_position_get_time(
1190 events_request
->start_position
);
1192 lttv_state_traceset_seek_time_closest(LTTV_TRACESET_STATE(tsc
),
1195 /* Process the traceset with only state hooks */
1197 lttv_process_traceset_middle(tsc
,
1200 events_request
->start_position
);
1201 g_assert(lttv_traceset_context_ctx_pos_compare(tsc
,
1202 events_request
->start_position
) == 0);
1209 /* 1.3 Add hooks and call before request for all list_in members */
1211 GSList
*iter
= NULL
;
1213 for(iter
=list_in
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
1214 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1215 /* 1.3.1 If !servicing */
1216 if(events_request
->servicing
== FALSE
) {
1217 /* - begin request hooks called
1218 * - servicing = TRUE
1220 lttv_hooks_call(events_request
->before_request
, (gpointer
)tsc
);
1221 events_request
->servicing
= TRUE
;
1223 /* 1.3.2 call before chunk
1224 * 1.3.3 events hooks added
1226 if(events_request
->trace
== -1)
1227 lttv_process_traceset_begin(tsc
,
1228 events_request
->before_chunk_traceset
,
1229 events_request
->before_chunk_trace
,
1230 events_request
->before_chunk_tracefile
,
1231 events_request
->event
,
1232 events_request
->event_by_id
);
1234 guint nb_trace
= lttv_traceset_number(tsc
->ts
);
1235 g_assert(events_request
->trace
< nb_trace
&&
1236 events_request
->trace
> -1);
1237 LttvTraceContext
*tc
= tsc
->traces
[events_request
->trace
];
1239 lttv_hooks_call(events_request
->before_chunk_traceset
, tsc
);
1241 lttv_trace_context_add_hooks(tc
,
1242 events_request
->before_chunk_trace
,
1243 events_request
->before_chunk_tracefile
,
1244 events_request
->event
,
1245 events_request
->event_by_id
);
1250 /* 2. Else, list_in is not empty, we continue a read */
1253 /* 2.0 For each req of list_in */
1254 GSList
*iter
= list_in
;
1256 while(iter
!= NULL
) {
1258 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1260 /* - Call before chunk
1261 * - events hooks added
1263 if(events_request
->trace
== -1)
1264 lttv_process_traceset_begin(tsc
,
1265 events_request
->before_chunk_traceset
,
1266 events_request
->before_chunk_trace
,
1267 events_request
->before_chunk_tracefile
,
1268 events_request
->event
,
1269 events_request
->event_by_id
);
1271 guint nb_trace
= lttv_traceset_number(tsc
->ts
);
1272 g_assert(events_request
->trace
< nb_trace
&&
1273 events_request
->trace
> -1);
1274 LttvTraceContext
*tc
= tsc
->traces
[events_request
->trace
];
1276 lttv_hooks_call(events_request
->before_chunk_traceset
, tsc
);
1278 lttv_trace_context_add_hooks(tc
,
1279 events_request
->before_chunk_trace
,
1280 events_request
->before_chunk_tracefile
,
1281 events_request
->event
,
1282 events_request
->event_by_id
);
1285 iter
= g_slist_next(iter
);
1290 tfc
= lttv_traceset_context_get_current_tfc(tsc
);
1292 /* 2.1 For each req of list_out */
1293 GSList
*iter
= list_out
;
1295 while(iter
!= NULL
) {
1297 gboolean remove
= FALSE
;
1298 gboolean free_data
= FALSE
;
1299 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1301 /* if req.start time == current context time
1302 * or req.start position == current position*/
1303 if( ltt_time_compare(events_request
->start_time
,
1304 tfc
->timestamp
) == 0
1306 (events_request
->start_position
!= NULL
1308 lttv_traceset_context_ctx_pos_compare(tsc
,
1309 events_request
->start_position
) == 0)
1311 /* - Add to list_in, remove from list_out */
1312 list_in
= g_slist_append(list_in
, events_request
);
1316 /* - If !servicing */
1317 if(events_request
->servicing
== FALSE
) {
1318 /* - begin request hooks called
1319 * - servicing = TRUE
1321 lttv_hooks_call(events_request
->before_request
, (gpointer
)tsc
);
1322 events_request
->servicing
= TRUE
;
1324 /* call before chunk
1325 * events hooks added
1327 if(events_request
->trace
== -1)
1328 lttv_process_traceset_begin(tsc
,
1329 events_request
->before_chunk_traceset
,
1330 events_request
->before_chunk_trace
,
1331 events_request
->before_chunk_tracefile
,
1332 events_request
->event
,
1333 events_request
->event_by_id
);
1335 guint nb_trace
= lttv_traceset_number(tsc
->ts
);
1336 g_assert(events_request
->trace
< nb_trace
&&
1337 events_request
->trace
> -1);
1338 LttvTraceContext
*tc
= tsc
->traces
[events_request
->trace
];
1340 lttv_hooks_call(events_request
->before_chunk_traceset
, tsc
);
1342 lttv_trace_context_add_hooks(tc
,
1343 events_request
->before_chunk_trace
,
1344 events_request
->before_chunk_tracefile
,
1345 events_request
->event
,
1346 events_request
->event_by_id
);
1355 GSList
*remove_iter
= iter
;
1357 iter
= g_slist_next(iter
);
1358 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
1359 list_out
= g_slist_remove_link(list_out
, remove_iter
);
1360 } else { // not remove
1361 iter
= g_slist_next(iter
);
1367 /* 3. Find end criterions */
1372 /* 3.1.1 Find lowest end time in list_in */
1373 g_assert(g_slist_length(list_in
)>0);
1374 end_time
= ((EventsRequest
*)g_slist_nth_data(list_in
,0))->end_time
;
1376 for(iter
=g_slist_nth(list_in
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
1377 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1379 if(ltt_time_compare(events_request
->end_time
,
1381 end_time
= events_request
->end_time
;
1384 /* 3.1.2 Find lowest start time in list_out */
1385 for(iter
=list_out
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
1386 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1388 if(ltt_time_compare(events_request
->start_time
,
1390 end_time
= events_request
->start_time
;
1395 /* 3.2 Number of events */
1397 /* 3.2.1 Find lowest number of events in list_in */
1400 end_nb_events
= ((EventsRequest
*)g_slist_nth_data(list_in
,0))->num_events
;
1402 for(iter
=g_slist_nth(list_in
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
1403 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1405 if(events_request
->num_events
< end_nb_events
)
1406 end_nb_events
= events_request
->num_events
;
1409 /* 3.2.2 Use min(CHUNK_NUM_EVENTS, min num events in list_in) as
1412 end_nb_events
= MIN(CHUNK_NUM_EVENTS
, end_nb_events
);
1416 /* 3.3 End position */
1418 /* 3.3.1 Find lowest end position in list_in */
1421 end_position
=((EventsRequest
*)g_slist_nth_data(list_in
,0))->end_position
;
1423 for(iter
=g_slist_nth(list_in
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
1424 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1426 if(events_request
->end_position
!= NULL
&& end_position
!= NULL
&&
1427 lttv_traceset_context_pos_pos_compare(events_request
->end_position
,
1429 end_position
= events_request
->end_position
;
1434 /* 3.3.2 Find lowest start position in list_out */
1437 for(iter
=list_out
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
1438 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1440 if(events_request
->end_position
!= NULL
&& end_position
!= NULL
&&
1441 lttv_traceset_context_pos_pos_compare(events_request
->end_position
,
1443 end_position
= events_request
->end_position
;
1448 /* 4. Call process traceset middle */
1449 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
);
1450 count
= lttv_process_traceset_middle(tsc
, end_time
, end_nb_events
, end_position
);
1452 tfc
= lttv_traceset_context_get_current_tfc(tsc
);
1454 g_debug("Context time after middle : %lu, %lu", tfc
->timestamp
.tv_sec
,
1455 tfc
->timestamp
.tv_nsec
);
1457 g_debug("End of trace reached after middle.");
1461 /* 5. After process traceset middle */
1462 tfc
= lttv_traceset_context_get_current_tfc(tsc
);
1464 /* - if current context time > traceset.end time */
1465 if(tfc
== NULL
|| ltt_time_compare(tfc
->timestamp
,
1466 tsc
->time_span
.end_time
) > 0) {
1467 /* - For each req in list_in */
1468 GSList
*iter
= list_in
;
1470 while(iter
!= NULL
) {
1472 gboolean remove
= FALSE
;
1473 gboolean free_data
= FALSE
;
1474 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1476 /* - Remove events hooks for req
1477 * - Call end chunk for req
1480 if(events_request
->trace
== -1)
1481 lttv_process_traceset_end(tsc
,
1482 events_request
->after_chunk_traceset
,
1483 events_request
->after_chunk_trace
,
1484 events_request
->after_chunk_tracefile
,
1485 events_request
->event
,
1486 events_request
->event_by_id
);
1489 guint nb_trace
= lttv_traceset_number(tsc
->ts
);
1490 g_assert(events_request
->trace
< nb_trace
&&
1491 events_request
->trace
> -1);
1492 LttvTraceContext
*tc
= tsc
->traces
[events_request
->trace
];
1494 lttv_trace_context_remove_hooks(tc
,
1495 events_request
->after_chunk_trace
,
1496 events_request
->after_chunk_tracefile
,
1497 events_request
->event
,
1498 events_request
->event_by_id
);
1499 lttv_hooks_call(events_request
->after_chunk_traceset
, tsc
);
1504 /* - Call end request for req */
1505 lttv_hooks_call(events_request
->after_request
, (gpointer
)tsc
);
1507 /* - remove req from list_in */
1508 /* Destroy the request */
1515 GSList
*remove_iter
= iter
;
1517 iter
= g_slist_next(iter
);
1518 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
1519 list_in
= g_slist_remove_link(list_in
, remove_iter
);
1520 } else { // not remove
1521 iter
= g_slist_next(iter
);
1526 /* 5.1 For each req in list_in */
1527 GSList
*iter
= list_in
;
1529 while(iter
!= NULL
) {
1531 gboolean remove
= FALSE
;
1532 gboolean free_data
= FALSE
;
1533 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1535 /* - Remove events hooks for req
1536 * - Call end chunk for req
1538 if(events_request
->trace
== -1)
1539 lttv_process_traceset_end(tsc
,
1540 events_request
->after_chunk_traceset
,
1541 events_request
->after_chunk_trace
,
1542 events_request
->after_chunk_tracefile
,
1543 events_request
->event
,
1544 events_request
->event_by_id
);
1547 guint nb_trace
= lttv_traceset_number(tsc
->ts
);
1548 g_assert(events_request
->trace
< nb_trace
&&
1549 events_request
->trace
> -1);
1550 LttvTraceContext
*tc
= tsc
->traces
[events_request
->trace
];
1552 lttv_trace_context_remove_hooks(tc
,
1553 events_request
->after_chunk_trace
,
1554 events_request
->after_chunk_tracefile
,
1555 events_request
->event
,
1556 events_request
->event_by_id
);
1558 lttv_hooks_call(events_request
->after_chunk_traceset
, tsc
);
1561 /* - req.num -= count */
1562 g_assert(events_request
->num_events
>= count
);
1563 events_request
->num_events
-= count
;
1565 g_assert(tfc
!= NULL
);
1566 /* - if req.num == 0
1568 * current context time >= req.end time
1570 * req.end pos == current pos
1572 * req.stop_flag == TRUE
1574 if( events_request
->num_events
== 0
1576 events_request
->stop_flag
== TRUE
1578 ltt_time_compare(tfc
->timestamp
,
1579 events_request
->end_time
) >= 0
1581 (events_request
->end_position
!= NULL
1583 lttv_traceset_context_ctx_pos_compare(tsc
,
1584 events_request
->end_position
) == 0)
1587 g_assert(events_request
->servicing
== TRUE
);
1588 /* - Call end request for req
1589 * - remove req from list_in */
1590 lttv_hooks_call(events_request
->after_request
, (gpointer
)tsc
);
1591 /* - remove req from list_in */
1592 /* Destroy the request */
1600 GSList
*remove_iter
= iter
;
1602 iter
= g_slist_next(iter
);
1603 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
1604 list_in
= g_slist_remove_link(list_in
, remove_iter
);
1605 } else { // not remove
1606 iter
= g_slist_next(iter
);
1612 /* End of removed servicing loop : leave control to GTK instead. */
1613 // if(gtk_events_pending()) break;
1616 /* B. When interrupted between chunks */
1619 GSList
*iter
= list_in
;
1621 /* 1. for each request in list_in */
1622 while(iter
!= NULL
) {
1624 gboolean remove
= FALSE
;
1625 gboolean free_data
= FALSE
;
1626 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1628 /* 1.1. Use current postition as start position */
1629 if(events_request
->start_position
!= NULL
)
1630 lttv_traceset_context_position_destroy(events_request
->start_position
);
1631 events_request
->start_position
= lttv_traceset_context_position_new();
1632 lttv_traceset_context_position_save(tsc
, events_request
->start_position
);
1634 /* 1.2. Remove start time */
1635 events_request
->start_time
= ltt_time_infinite
;
1637 /* 1.3. Move from list_in to list_out */
1640 list_out
= g_slist_append(list_out
, events_request
);
1645 GSList
*remove_iter
= iter
;
1647 iter
= g_slist_next(iter
);
1648 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
1649 list_in
= g_slist_remove_link(list_in
, remove_iter
);
1650 } else { // not remove
1651 iter
= g_slist_next(iter
);
1658 /* C Unlock Traces */
1660 //lttv_process_traceset_get_sync_data(tsc);
1665 iter_trace
<lttv_traceset_number(tsc
->ts
);
1667 LttvTrace
*trace_v
= lttv_traceset_get(tsc
->ts
, iter_trace
);
1669 lttvwindowtraces_unlock(trace_v
);
1674 //set the cursor back to normal
1675 gdk_window_set_cursor(win
, NULL
);
1678 g_assert(g_slist_length(list_in
) == 0);
1680 if( g_slist_length(list_out
) == 0 ) {
1681 /* Put tab's request pending flag back to normal */
1682 tab
->events_request_pending
= FALSE
;
1683 g_debug("remove the idle fct");
1684 return FALSE
; /* Remove the idle function */
1686 g_debug("leave the idle fct");
1687 return TRUE
; /* Leave the idle function */
1689 /* We do not use simili-round-robin, it may require to read 1 meg buffers
1690 * again and again if many tracesets use the same tracefiles. */
1691 /* Hack for round-robin idle functions */
1692 /* It will put the idle function at the end of the pool */
1693 /*g_idle_add_full((G_PRIORITY_HIGH_IDLE + 21),
1694 (GSourceFunc)execute_events_requests,
1704 /* add_trace_into_traceset_selector, each instance of a viewer has an associated
1705 * selector (filter), when a trace is added into traceset, the selector should
1706 * reflect the change. The function is used to update the selector
1709 void add_trace_into_traceset_selector(GtkWidget
* paned
, LttTrace
* t
)
1711 int j
, k
, m
, nb_tracefile
, nb_control
, nb_per_cpu
, nb_facility
, nb_event
;
1712 LttvTracesetSelector
* s
;
1713 LttvTraceSelector
* trace
;
1714 LttvTracefileSelector
* tracefile
;
1715 LttvEventtypeSelector
* eventtype
;
1721 w
= gtk_multivpaned_get_first_widget(GTK_MULTIVPANED(paned
));
1723 s
= g_object_get_data(G_OBJECT(w
), "Traceset_Selector");
1726 trace
= lttv_trace_selector_new(t
);
1727 lttv_traceset_selector_trace_add(s
, trace
);
1729 nb_facility
= ltt_trace_facility_number(t
);
1730 for(k
=0;k
<nb_facility
;k
++){
1731 fac
= ltt_trace_facility_get(t
,k
);
1732 nb_event
= (int) ltt_facility_eventtype_number(fac
);
1733 for(m
=0;m
<nb_event
;m
++){
1734 et
= ltt_facility_eventtype_get(fac
,m
);
1735 eventtype
= lttv_eventtype_selector_new(et
);
1736 lttv_trace_selector_eventtype_add(trace
, eventtype
);
1740 nb_control
= ltt_trace_control_tracefile_number(t
);
1741 nb_per_cpu
= ltt_trace_per_cpu_tracefile_number(t
);
1742 nb_tracefile
= nb_control
+ nb_per_cpu
;
1744 for(j
= 0 ; j
< nb_tracefile
; j
++) {
1746 tf
= ltt_trace_control_tracefile_get(t
, j
);
1748 tf
= ltt_trace_per_cpu_tracefile_get(t
, j
- nb_control
);
1749 tracefile
= lttv_tracefile_selector_new(tf
);
1750 lttv_trace_selector_tracefile_add(trace
, tracefile
);
1751 lttv_eventtype_selector_copy(trace
, tracefile
);
1753 }else g_warning("Module does not support filtering\n");
1755 w
= gtk_multivpaned_get_next_widget(GTK_MULTIVPANED(paned
));
1760 static void lttvwindow_add_trace(Tab
*tab
, LttvTrace
*trace_v
)
1762 LttvTraceset
*traceset
= tab
->traceset_info
->traceset
;
1764 guint num_traces
= lttv_traceset_number(traceset
);
1766 //Verify if trace is already present.
1767 for(i
=0; i
<num_traces
; i
++)
1769 LttvTrace
* trace
= lttv_traceset_get(traceset
, i
);
1770 if(trace
== trace_v
)
1774 //Keep a reference to the traces so they are not freed.
1775 for(i
=0; i
<lttv_traceset_number(traceset
); i
++)
1777 LttvTrace
* trace
= lttv_traceset_get(traceset
, i
);
1778 lttv_trace_ref(trace
);
1781 //remove state update hooks
1782 lttv_state_remove_event_hooks(
1783 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1785 lttv_context_fini(LTTV_TRACESET_CONTEXT(
1786 tab
->traceset_info
->traceset_context
));
1787 g_object_unref(tab
->traceset_info
->traceset_context
);
1789 lttv_traceset_add(traceset
, trace_v
);
1790 lttv_trace_ref(trace_v
); /* local ref */
1792 /* Create new context */
1793 tab
->traceset_info
->traceset_context
=
1794 g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
1796 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->
1801 //add state update hooks
1802 lttv_state_add_event_hooks(
1803 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1804 //Remove local reference to the traces.
1805 for(i
=0; i
<lttv_traceset_number(traceset
); i
++)
1807 LttvTrace
* trace
= lttv_traceset_get(traceset
, i
);
1808 lttv_trace_unref(trace
);
1812 //add_trace_into_traceset_selector(GTK_MULTIVPANED(tab->multivpaned), lttv_trace(trace_v));
1815 /* add_trace adds a trace into the current traceset. It first displays a
1816 * directory selection dialogue to let user choose a trace, then recreates
1817 * tracset_context, and redraws all the viewer of the current tab
1820 void add_trace(GtkWidget
* widget
, gpointer user_data
)
1823 LttvTrace
* trace_v
;
1824 LttvTraceset
* traceset
;
1826 char abs_path
[PATH_MAX
];
1829 MainWindow
* mw_data
= get_window_data_struct(widget
);
1830 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
1832 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
1833 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
1837 tab
= create_new_tab(widget
, NULL
);
1839 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
1842 GtkDirSelection
* file_selector
= (GtkDirSelection
*)gtk_dir_selection_new("Select a trace");
1843 gtk_dir_selection_hide_fileop_buttons(file_selector
);
1845 if(remember_trace_dir
[0] != '\0')
1846 gtk_dir_selection_set_filename(file_selector
, remember_trace_dir
);
1848 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
1850 case GTK_RESPONSE_ACCEPT
:
1851 case GTK_RESPONSE_OK
:
1852 dir
= gtk_dir_selection_get_dir (file_selector
);
1853 strncpy(remember_trace_dir
, dir
, PATH_MAX
);
1854 if(!dir
|| strlen(dir
) == 0){
1855 gtk_widget_destroy((GtkWidget
*)file_selector
);
1858 get_absolute_pathname(dir
, abs_path
);
1859 trace_v
= lttvwindowtraces_get_trace_by_name(abs_path
);
1860 if(trace_v
== NULL
) {
1861 trace
= ltt_trace_open(abs_path
);
1863 g_warning("cannot open trace %s", abs_path
);
1865 trace_v
= lttv_trace_new(trace
);
1866 lttvwindowtraces_add_trace(trace_v
);
1867 lttvwindow_add_trace(tab
, trace_v
);
1870 lttvwindow_add_trace(tab
, trace_v
);
1873 gtk_widget_destroy((GtkWidget
*)file_selector
);
1875 //update current tab
1876 //update_traceset(mw_data);
1878 /* Call the updatetraceset hooks */
1880 traceset
= tab
->traceset_info
->traceset
;
1881 SetTraceset(tab
, traceset
);
1882 // in expose now call_pending_read_hooks(mw_data);
1884 //lttvwindow_report_current_time(mw_data,&(tab->current_time));
1886 case GTK_RESPONSE_REJECT
:
1887 case GTK_RESPONSE_CANCEL
:
1889 gtk_widget_destroy((GtkWidget
*)file_selector
);
1895 /* remove_trace_into_traceset_selector, each instance of a viewer has an associated
1896 * selector (filter), when a trace is remove from traceset, the selector should
1897 * reflect the change. The function is used to update the selector
1900 void remove_trace_from_traceset_selector(GtkWidget
* paned
, unsigned i
)
1902 LttvTracesetSelector
* s
;
1903 LttvTraceSelector
* t
;
1906 w
= gtk_multivpaned_get_first_widget(GTK_MULTIVPANED(paned
));
1908 s
= g_object_get_data(G_OBJECT(w
), "Traceset_Selector");
1910 t
= lttv_traceset_selector_trace_get(s
,i
);
1911 lttv_traceset_selector_trace_remove(s
, i
);
1912 lttv_trace_selector_destroy(t
);
1913 }g_warning("Module dose not support filtering\n");
1914 w
= gtk_multivpaned_get_next_widget(GTK_MULTIVPANED(paned
));
1919 /* remove_trace removes a trace from the current traceset if all viewers in
1920 * the current tab are not interested in the trace. It first displays a
1921 * dialogue, which shows all traces in the current traceset, to let user choose
1922 * a trace, then it checks if all viewers unselect the trace, if it is true,
1923 * it will remove the trace, recreate the traceset_contex,
1924 * and redraws all the viewer of the current tab. If there is on trace in the
1925 * current traceset, it will delete all viewers of the current tab
1928 // MD : no filter version.
1929 void remove_trace(GtkWidget
*widget
, gpointer user_data
)
1932 LttvTrace
* trace_v
;
1933 LttvTraceset
* traceset
;
1934 gint i
, j
, nb_trace
, index
=-1;
1935 char ** name
, *remove_trace_name
;
1936 MainWindow
* mw_data
= get_window_data_struct(widget
);
1937 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
1939 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
1940 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
1946 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
1949 nb_trace
=lttv_traceset_number(tab
->traceset_info
->traceset
);
1950 name
= g_new(char*,nb_trace
);
1951 for(i
= 0; i
< nb_trace
; i
++){
1952 trace_v
= lttv_traceset_get(tab
->traceset_info
->traceset
, i
);
1953 trace
= lttv_trace(trace_v
);
1954 name
[i
] = ltt_trace_name(trace
);
1957 remove_trace_name
= get_remove_trace(name
, nb_trace
);
1960 if(remove_trace_name
){
1962 /* yuk, cut n paste from old code.. should be better (MD)*/
1963 for(i
= 0; i
<nb_trace
; i
++) {
1964 if(strcmp(remove_trace_name
,name
[i
]) == 0){
1969 traceset
= tab
->traceset_info
->traceset
;
1970 //Keep a reference to the traces so they are not freed.
1971 for(j
=0; j
<lttv_traceset_number(traceset
); j
++)
1973 LttvTrace
* trace
= lttv_traceset_get(traceset
, j
);
1974 lttv_trace_ref(trace
);
1977 //remove state update hooks
1978 lttv_state_remove_event_hooks(
1979 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1980 lttv_context_fini(LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
));
1981 g_object_unref(tab
->traceset_info
->traceset_context
);
1983 trace_v
= lttv_traceset_get(traceset
, index
);
1985 lttv_traceset_remove(traceset
, index
);
1986 lttv_trace_unref(trace_v
); // Remove local reference
1988 if(lttv_trace_get_ref_number(trace_v
) <= 1) {
1989 /* ref 1 : lttvwindowtraces only*/
1990 ltt_trace_close(lttv_trace(trace_v
));
1991 /* lttvwindowtraces_remove_trace takes care of destroying
1992 * the traceset linked with the trace_v and also of destroying
1993 * the trace_v at the same time.
1995 lttvwindowtraces_remove_trace(trace_v
);
1998 tab
->traceset_info
->traceset_context
=
1999 g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
2001 LTTV_TRACESET_CONTEXT(tab
->
2002 traceset_info
->traceset_context
),traceset
);
2003 //add state update hooks
2004 lttv_state_add_event_hooks(
2005 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
2007 //Remove local reference to the traces.
2008 for(j
=0; j
<lttv_traceset_number(traceset
); j
++)
2010 LttvTrace
* trace
= lttv_traceset_get(traceset
, j
);
2011 lttv_trace_unref(trace
);
2014 SetTraceset(tab
, (gpointer
)traceset
);
2020 void remove_trace(GtkWidget
* widget
, gpointer user_data
)
2023 LttvTrace
* trace_v
;
2024 LttvTraceset
* traceset
;
2025 gint i
, j
, nb_trace
;
2026 char ** name
, *remove_trace_name
;
2027 MainWindow
* mw_data
= get_window_data_struct(widget
);
2028 LttvTracesetSelector
* s
;
2029 LttvTraceSelector
* t
;
2032 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
2034 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2035 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2041 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
2044 nb_trace
=lttv_traceset_number(tab
->traceset_info
->traceset
);
2045 name
= g_new(char*,nb_trace
);
2046 for(i
= 0; i
< nb_trace
; i
++){
2047 trace_v
= lttv_traceset_get(tab
->traceset_info
->traceset
, i
);
2048 trace
= lttv_trace(trace_v
);
2049 name
[i
] = ltt_trace_name(trace
);
2052 remove_trace_name
= get_remove_trace(name
, nb_trace
);
2054 if(remove_trace_name
){
2055 for(i
=0; i
<nb_trace
; i
++){
2056 if(strcmp(remove_trace_name
,name
[i
]) == 0){
2057 //unselect the trace from the current viewer
2059 w
= gtk_multivpaned_get_widget(GTK_MULTIVPANED(tab
->multivpaned
));
2061 s
= g_object_get_data(G_OBJECT(w
), "Traceset_Selector");
2063 t
= lttv_traceset_selector_trace_get(s
,i
);
2064 lttv_trace_selector_set_selected(t
, FALSE
);
2067 //check if other viewers select the trace
2068 w
= gtk_multivpaned_get_first_widget(GTK_MULTIVPANED(tab
->multivpaned
));
2070 s
= g_object_get_data(G_OBJECT(w
), "Traceset_Selector");
2072 t
= lttv_traceset_selector_trace_get(s
,i
);
2073 selected
= lttv_trace_selector_get_selected(t
);
2076 w
= gtk_multivpaned_get_next_widget(GTK_MULTIVPANED(tab
->multivpaned
));
2078 }else selected
= FALSE
;
2080 //if no viewer selects the trace, remove it
2082 remove_trace_from_traceset_selector(GTK_MULTIVPANED(tab
->multivpaned
), i
);
2084 traceset
= tab
->traceset_info
->traceset
;
2085 //Keep a reference to the traces so they are not freed.
2086 for(j
=0; j
<lttv_traceset_number(traceset
); j
++)
2088 LttvTrace
* trace
= lttv_traceset_get(traceset
, j
);
2089 lttv_trace_ref(trace
);
2092 //remove state update hooks
2093 lttv_state_remove_event_hooks(
2094 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
2095 lttv_context_fini(LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
));
2096 g_object_unref(tab
->traceset_info
->traceset_context
);
2099 trace_v
= lttv_traceset_get(traceset
, i
);
2101 if(lttv_trace_get_ref_number(trace_v
) <= 2) {
2102 /* ref 2 : traceset, local */
2103 lttvwindowtraces_remove_trace(trace_v
);
2104 ltt_trace_close(lttv_trace(trace_v
));
2107 lttv_traceset_remove(traceset
, i
);
2108 lttv_trace_unref(trace_v
); // Remove local reference
2110 if(!lttv_trace_get_ref_number(trace_v
))
2111 lttv_trace_destroy(trace_v
);
2113 tab
->traceset_info
->traceset_context
=
2114 g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
2116 LTTV_TRACESET_CONTEXT(tab
->
2117 traceset_info
->traceset_context
),traceset
);
2118 //add state update hooks
2119 lttv_state_add_event_hooks(
2120 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
2122 //Remove local reference to the traces.
2123 for(j
=0; j
<lttv_traceset_number(traceset
); j
++)
2125 LttvTrace
* trace
= lttv_traceset_get(traceset
, j
);
2126 lttv_trace_unref(trace
);
2130 //update current tab
2131 //update_traceset(mw_data);
2134 SetTraceset(tab
, (gpointer
)traceset
);
2135 // in expose now call_pending_read_hooks(mw_data);
2137 //lttvwindow_report_current_time(mw_data,&(tab->current_time));
2140 // while(tab->multi_vpaned->num_children){
2141 // gtk_multi_vpaned_widget_delete(tab->multi_vpaned);
2155 /* Redraw all the viewers in the current tab */
2156 void redraw(GtkWidget
*widget
, gpointer user_data
)
2158 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
2159 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2160 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2165 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
2169 LttvAttributeValue value
;
2171 g_assert(lttv_iattribute_find_by_path(tab
->attributes
, "hooks/redraw", LTTV_POINTER
, &value
));
2173 tmp
= (LttvHooks
*)*(value
.v_pointer
);
2175 lttv_hooks_call(tmp
,NULL
);
2179 void continue_processing(GtkWidget
*widget
, gpointer user_data
)
2181 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
2182 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2183 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2188 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
2192 LttvAttributeValue value
;
2194 g_assert(lttv_iattribute_find_by_path(tab
->attributes
,
2195 "hooks/continue", LTTV_POINTER
, &value
));
2197 tmp
= (LttvHooks
*)*(value
.v_pointer
);
2199 lttv_hooks_call(tmp
,NULL
);
2202 /* Stop the processing for the calling main window's current tab.
2203 * It removes every processing requests that are in its list. It does not call
2204 * the end request hooks, because the request is not finished.
2207 void stop_processing(GtkWidget
*widget
, gpointer user_data
)
2209 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
2210 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2211 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2216 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
2218 GSList
*iter
= tab
->events_requests
;
2220 while(iter
!= NULL
) {
2221 GSList
*remove_iter
= iter
;
2222 iter
= g_slist_next(iter
);
2224 g_free(remove_iter
->data
);
2225 tab
->events_requests
=
2226 g_slist_remove_link(tab
->events_requests
, remove_iter
);
2228 tab
->events_request_pending
= FALSE
;
2229 g_idle_remove_by_data(tab
);
2230 g_assert(g_slist_length(tab
->events_requests
) == 0);
2234 /* save will save the traceset to a file
2235 * Not implemented yet FIXME
2238 void save(GtkWidget
* widget
, gpointer user_data
)
2243 void save_as(GtkWidget
* widget
, gpointer user_data
)
2245 g_printf("Save as\n");
2249 /* zoom will change the time_window of all the viewers of the
2250 * current tab, and redisplay them. The main functionality is to
2251 * determine the new time_window of the current tab
2254 void zoom(GtkWidget
* widget
, double size
)
2256 TimeInterval time_span
;
2257 TimeWindow new_time_window
;
2258 LttTime current_time
, time_delta
, time_s
, time_e
, time_tmp
;
2259 MainWindow
* mw_data
= get_window_data_struct(widget
);
2260 LttvTracesetContext
*tsc
;
2261 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
2263 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2264 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2270 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
2273 if(size
== 1) return;
2275 tsc
= LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
2276 time_span
= tsc
->time_span
;
2277 new_time_window
= tab
->time_window
;
2278 current_time
= tab
->current_time
;
2280 time_delta
= ltt_time_sub(time_span
.end_time
,time_span
.start_time
);
2282 new_time_window
.start_time
= time_span
.start_time
;
2283 new_time_window
.time_width
= time_delta
;
2285 new_time_window
.time_width
= ltt_time_div(new_time_window
.time_width
, size
);
2286 if(ltt_time_compare(new_time_window
.time_width
,time_delta
) > 0)
2287 { /* Case where zoom out is bigger than trace length */
2288 new_time_window
.start_time
= time_span
.start_time
;
2289 new_time_window
.time_width
= time_delta
;
2293 /* Center the image on the current time */
2294 new_time_window
.start_time
=
2295 ltt_time_sub(current_time
, ltt_time_div(new_time_window
.time_width
, 2.0));
2296 /* If on borders, don't fall off */
2297 if(ltt_time_compare(new_time_window
.start_time
, time_span
.start_time
) <0)
2299 new_time_window
.start_time
= time_span
.start_time
;
2303 if(ltt_time_compare(
2304 ltt_time_add(new_time_window
.start_time
, new_time_window
.time_width
),
2305 time_span
.end_time
) > 0)
2307 new_time_window
.start_time
=
2308 ltt_time_sub(time_span
.end_time
, new_time_window
.time_width
);
2315 if(ltt_time_compare(new_time_window
.time_width
, ltt_time_zero
) == 0) {
2316 g_warning("Zoom more than 1 ns impossible");
2318 time_change_manager(tab
, new_time_window
);
2322 void zoom_in(GtkWidget
* widget
, gpointer user_data
)
2327 void zoom_out(GtkWidget
* widget
, gpointer user_data
)
2332 void zoom_extended(GtkWidget
* widget
, gpointer user_data
)
2337 void go_to_time(GtkWidget
* widget
, gpointer user_data
)
2339 g_printf("Go to time\n");
2342 void show_time_frame(GtkWidget
* widget
, gpointer user_data
)
2344 g_printf("Show time frame\n");
2348 /* callback function */
2351 on_empty_traceset_activate (GtkMenuItem
*menuitem
,
2354 create_new_window((GtkWidget
*)menuitem
, user_data
, FALSE
);
2359 on_clone_traceset_activate (GtkMenuItem
*menuitem
,
2362 create_new_window((GtkWidget
*)menuitem
, user_data
, TRUE
);
2366 /* create_new_tab calls create_tab to construct a new tab in the main window
2369 Tab
*create_new_tab(GtkWidget
* widget
, gpointer user_data
){
2370 gchar label
[PATH_MAX
];
2371 MainWindow
* mw_data
= get_window_data_struct(widget
);
2373 GtkNotebook
* notebook
= (GtkNotebook
*)lookup_widget(widget
, "MNotebook");
2374 if(notebook
== NULL
){
2375 g_printf("Notebook does not exist\n");
2378 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2379 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2385 copy_tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
2388 strcpy(label
,"Page");
2389 if(get_label(mw_data
, label
,"Get the name of the tab","Please input tab's name"))
2390 return (create_tab (mw_data
, copy_tab
, notebook
, label
));
2394 on_tab_activate (GtkMenuItem
*menuitem
,
2397 create_new_tab((GtkWidget
*)menuitem
, user_data
);
2402 on_open_activate (GtkMenuItem
*menuitem
,
2405 open_traceset((GtkWidget
*)menuitem
, user_data
);
2410 on_close_activate (GtkMenuItem
*menuitem
,
2413 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2414 main_window_destructor(mw_data
);
2418 /* remove the current tab from the main window
2422 on_close_tab_activate (GtkWidget
*widget
,
2426 GtkWidget
* notebook
;
2428 MainWindow
* mw_data
= get_window_data_struct(widget
);
2429 notebook
= lookup_widget(widget
, "MNotebook");
2430 if(notebook
== NULL
){
2431 g_printf("Notebook does not exist\n");
2435 page_num
= gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
));
2437 gtk_notebook_remove_page(GTK_NOTEBOOK(notebook
), page_num
);
2442 on_close_tab_X_clicked (GtkWidget
*widget
,
2446 GtkWidget
*notebook
= lookup_widget(widget
, "MNotebook");
2447 if(notebook
== NULL
){
2448 g_printf("Notebook does not exist\n");
2452 if((page_num
= gtk_notebook_page_num(GTK_NOTEBOOK(notebook
), widget
)) != -1)
2453 gtk_notebook_remove_page(GTK_NOTEBOOK(notebook
), page_num
);
2459 on_add_trace_activate (GtkMenuItem
*menuitem
,
2462 add_trace((GtkWidget
*)menuitem
, user_data
);
2467 on_remove_trace_activate (GtkMenuItem
*menuitem
,
2470 remove_trace((GtkWidget
*)menuitem
, user_data
);
2475 on_save_activate (GtkMenuItem
*menuitem
,
2478 save((GtkWidget
*)menuitem
, user_data
);
2483 on_save_as_activate (GtkMenuItem
*menuitem
,
2486 save_as((GtkWidget
*)menuitem
, user_data
);
2491 on_quit_activate (GtkMenuItem
*menuitem
,
2499 on_cut_activate (GtkMenuItem
*menuitem
,
2507 on_copy_activate (GtkMenuItem
*menuitem
,
2510 g_printf("Copye\n");
2515 on_paste_activate (GtkMenuItem
*menuitem
,
2518 g_printf("Paste\n");
2523 on_delete_activate (GtkMenuItem
*menuitem
,
2526 g_printf("Delete\n");
2531 on_zoom_in_activate (GtkMenuItem
*menuitem
,
2534 zoom_in((GtkWidget
*)menuitem
, user_data
);
2539 on_zoom_out_activate (GtkMenuItem
*menuitem
,
2542 zoom_out((GtkWidget
*)menuitem
, user_data
);
2547 on_zoom_extended_activate (GtkMenuItem
*menuitem
,
2550 zoom_extended((GtkWidget
*)menuitem
, user_data
);
2555 on_go_to_time_activate (GtkMenuItem
*menuitem
,
2558 go_to_time((GtkWidget
*)menuitem
, user_data
);
2563 on_show_time_frame_activate (GtkMenuItem
*menuitem
,
2566 show_time_frame((GtkWidget
*)menuitem
, user_data
);
2571 on_move_viewer_up_activate (GtkMenuItem
*menuitem
,
2574 move_up_viewer((GtkWidget
*)menuitem
, user_data
);
2579 on_move_viewer_down_activate (GtkMenuItem
*menuitem
,
2582 move_down_viewer((GtkWidget
*)menuitem
, user_data
);
2587 on_remove_viewer_activate (GtkMenuItem
*menuitem
,
2590 delete_viewer((GtkWidget
*)menuitem
, user_data
);
2595 on_trace_filter_activate (GtkMenuItem
*menuitem
,
2598 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2599 LttvTracesetSelector
* s
;
2601 GtkWidget
* notebook
= lookup_widget(GTK_WIDGET(menuitem
), "MNotebook");
2603 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2604 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2610 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
2613 w
= gtk_multivpaned_get_widget(GTK_MULTIVPANED(tab
->multivpaned
));
2615 s
= g_object_get_data(G_OBJECT(w
), "Traceset_Selector");
2617 g_printf("There is no viewer yet\n");
2620 if(get_filter_selection(s
, "Configure trace and tracefile filter", "Select traces and tracefiles")){
2621 //FIXME report filter change
2622 //update_traceset(mw_data);
2623 //call_pending_read_hooks(mw_data);
2624 //lttvwindow_report_current_time(mw_data,&(tab->current_time));
2630 on_trace_facility_activate (GtkMenuItem
*menuitem
,
2633 g_printf("Trace facility selector: %s\n");
2637 /* Dispaly a file selection dialogue to let user select a library, then call
2638 * lttv_library_load().
2642 on_load_library_activate (GtkMenuItem
*menuitem
,
2645 GError
*error
= NULL
;
2646 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2648 gchar load_module_path_alter
[PATH_MAX
];
2652 gchar
*load_module_path
;
2653 name
= g_ptr_array_new();
2654 nb
= lttv_library_path_number();
2655 /* ask for the library path */
2659 path
= lttv_library_path_get(i
);
2660 g_ptr_array_add(name
, path
);
2663 load_module_path
= get_selection((char **)(name
->pdata
), name
->len
,
2664 "Select a library path", "Library paths");
2665 if(load_module_path
!= NULL
)
2666 strncpy(load_module_path_alter
, load_module_path
, PATH_MAX
-1); // -1 for /
2668 g_ptr_array_free(name
, TRUE
);
2670 if(load_module_path
== NULL
) return;
2674 /* Make sure the module path ends with a / */
2675 gchar
*ptr
= load_module_path_alter
;
2677 ptr
= strchr(ptr
, '\0');
2679 if(*(ptr
-1) != '/') {
2686 /* Ask for the library to load : list files in the previously selected
2688 gchar str
[PATH_MAX
];
2691 GtkFileSelection
* file_selector
=
2692 (GtkFileSelection
*)gtk_file_selection_new("Select a module");
2693 gtk_file_selection_set_filename(file_selector
, load_module_path_alter
);
2694 gtk_file_selection_hide_fileop_buttons(file_selector
);
2697 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
2699 case GTK_RESPONSE_ACCEPT
:
2700 case GTK_RESPONSE_OK
:
2701 dir
= gtk_file_selection_get_selections (file_selector
);
2702 strncpy(str
,dir
[0],PATH_MAX
);
2703 strncpy(remember_plugins_dir
,dir
[0],PATH_MAX
);
2704 /* only keep file name */
2706 str1
= strrchr(str
,'/');
2709 str1
= strrchr(str
,'\\');
2714 if(*str1
== 'l' && *(str1
+1)== 'i' && *(str1
+2)=='b')
2716 remove info after
. */
2720 str2
= strrchr(str2
, '.');
2721 if(str2
!= NULL
) *str2
= '\0';
2723 lttv_module_require(str1
, &error
);
2725 lttv_library_load(str1
, &error
);
2726 if(error
!= NULL
) g_warning(error
->message
);
2727 else g_printf("Load library: %s\n", str
);
2729 case GTK_RESPONSE_REJECT
:
2730 case GTK_RESPONSE_CANCEL
:
2732 gtk_widget_destroy((GtkWidget
*)file_selector
);
2743 /* Display all loaded modules, let user to select a module to unload
2744 * by calling lttv_module_unload
2748 on_unload_library_activate (GtkMenuItem
*menuitem
,
2751 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2753 LttvLibrary
*library
;
2758 name
= g_ptr_array_new();
2759 nb
= lttv_library_number();
2760 LttvLibraryInfo
*lib_info
= g_new(LttvLibraryInfo
,nb
);
2761 /* ask for the library name */
2764 LttvLibrary
*iter_lib
= lttv_library_get(i
);
2765 lttv_library_info(iter_lib
, &lib_info
[i
]);
2767 gchar
*path
= lib_info
[i
].name
;
2768 g_ptr_array_add(name
, lib_info
[i
].name
);
2770 lib_name
= get_selection((char **)(name
->pdata
), name
->len
,
2771 "Select a library", "Libraries");
2772 if(lib_name
!= NULL
) {
2774 if(strcmp(lib_name
, lib_info
[i
].name
) == 0) {
2775 library
= lttv_library_get(i
);
2780 g_ptr_array_free(name
, TRUE
);
2783 if(lib_name
== NULL
) return;
2786 lttv_library_unload(library
);
2790 /* Dispaly a file selection dialogue to let user select a module, then call
2791 * lttv_module_require().
2795 on_load_module_activate (GtkMenuItem
*menuitem
,
2798 GError
*error
= NULL
;
2799 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2801 LttvLibrary
*library
;
2806 name
= g_ptr_array_new();
2807 nb
= lttv_library_number();
2808 LttvLibraryInfo
*lib_info
= g_new(LttvLibraryInfo
,nb
);
2809 /* ask for the library name */
2812 LttvLibrary
*iter_lib
= lttv_library_get(i
);
2813 lttv_library_info(iter_lib
, &lib_info
[i
]);
2815 gchar
*path
= lib_info
[i
].name
;
2816 g_ptr_array_add(name
, path
);
2818 lib_name
= get_selection((char **)(name
->pdata
), name
->len
,
2819 "Select a library", "Libraries");
2820 if(lib_name
!= NULL
) {
2822 if(strcmp(lib_name
, lib_info
[i
].name
) == 0) {
2823 library
= lttv_library_get(i
);
2828 g_ptr_array_free(name
, TRUE
);
2831 if(lib_name
== NULL
) return;
2834 //LttvModule *module;
2835 gchar module_name_out
[PATH_MAX
];
2837 /* Ask for the module to load : list modules in the selected lib */
2841 LttvModuleInfo
*module_info
= g_new(LttvModuleInfo
,nb
);
2842 name
= g_ptr_array_new();
2843 nb
= lttv_library_module_number(library
);
2844 /* ask for the module name */
2847 LttvModule
*iter_module
= lttv_library_module_get(library
, i
);
2848 lttv_module_info(iter_module
, &module_info
[i
]);
2850 gchar
*path
= module_info
[i
].name
;
2851 g_ptr_array_add(name
, path
);
2853 module_name
= get_selection((char **)(name
->pdata
), name
->len
,
2854 "Select a module", "Modules");
2855 if(module_name
!= NULL
) {
2857 if(strcmp(module_name
, module_info
[i
].name
) == 0) {
2858 strncpy(module_name_out
, module_name
, PATH_MAX
);
2859 //module = lttv_library_module_get(i);
2865 g_ptr_array_free(name
, TRUE
);
2866 g_free(module_info
);
2868 if(module_name
== NULL
) return;
2871 lttv_module_require(module_name_out
, &error
);
2872 if(error
!= NULL
) g_warning(error
->message
);
2873 else g_printf("Load module: %s\n", module_name_out
);
2880 gchar str
[PATH_MAX
];
2883 GtkFileSelection
* file_selector
=
2884 (GtkFileSelection
*)gtk_file_selection_new("Select a module");
2885 gtk_file_selection_set_filename(file_selector
, load_module_path_alter
);
2886 gtk_file_selection_hide_fileop_buttons(file_selector
);
2889 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
2891 case GTK_RESPONSE_ACCEPT
:
2892 case GTK_RESPONSE_OK
:
2893 dir
= gtk_file_selection_get_selections (file_selector
);
2894 strncpy(str
,dir
[0],PATH_MAX
);
2895 strncpy(remember_plugins_dir
,dir
[0],PATH_MAX
);
2897 /* only keep file name */
2899 str1
= strrchr(str
,'/');
2902 str1
= strrchr(str
,'\\');
2907 if(*str1
== 'l' && *(str1
+1)== 'i' && *(str1
+2)=='b')
2909 remove info after
. */
2913 str2
= strrchr(str2
, '.');
2914 if(str2
!= NULL
) *str2
= '\0';
2916 lttv_module_require(str1
, &error
);
2918 lttv_library_load(str1
, &error
);
2919 if(error
!= NULL
) g_warning(error
->message
);
2920 else g_printf("Load library: %s\n", str
);
2922 case GTK_RESPONSE_REJECT
:
2923 case GTK_RESPONSE_CANCEL
:
2925 gtk_widget_destroy((GtkWidget
*)file_selector
);
2937 /* Display all loaded modules, let user to select a module to unload
2938 * by calling lttv_module_unload
2942 on_unload_module_activate (GtkMenuItem
*menuitem
,
2945 GError
*error
= NULL
;
2946 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2948 LttvLibrary
*library
;
2953 name
= g_ptr_array_new();
2954 nb
= lttv_library_number();
2955 LttvLibraryInfo
*lib_info
= g_new(LttvLibraryInfo
,nb
);
2956 /* ask for the library name */
2959 LttvLibrary
*iter_lib
= lttv_library_get(i
);
2960 lttv_library_info(iter_lib
, &lib_info
[i
]);
2962 gchar
*path
= lib_info
[i
].name
;
2963 g_ptr_array_add(name
, path
);
2965 lib_name
= get_selection((char **)(name
->pdata
), name
->len
,
2966 "Select a library", "Libraries");
2967 if(lib_name
!= NULL
) {
2969 if(strcmp(lib_name
, lib_info
[i
].name
) == 0) {
2970 library
= lttv_library_get(i
);
2975 g_ptr_array_free(name
, TRUE
);
2978 if(lib_name
== NULL
) return;
2983 /* Ask for the module to load : list modules in the selected lib */
2987 nb
= lttv_library_module_number(library
);
2988 LttvModuleInfo
*module_info
= g_new(LttvModuleInfo
,nb
);
2989 name
= g_ptr_array_new();
2990 /* ask for the module name */
2993 LttvModule
*iter_module
= lttv_library_module_get(library
, i
);
2994 lttv_module_info(iter_module
, &module_info
[i
]);
2996 gchar
*path
= module_info
[i
].name
;
2997 if(module_info
[i
].use_count
> 0) g_ptr_array_add(name
, path
);
2999 module_name
= get_selection((char **)(name
->pdata
), name
->len
,
3000 "Select a module", "Modules");
3001 if(module_name
!= NULL
) {
3003 if(strcmp(module_name
, module_info
[i
].name
) == 0) {
3004 module
= lttv_library_module_get(library
, i
);
3010 g_ptr_array_free(name
, TRUE
);
3011 g_free(module_info
);
3013 if(module_name
== NULL
) return;
3016 LttvModuleInfo module_info
;
3017 lttv_module_info(module
, &module_info
);
3018 g_printf("Release module: %s\n", module_info
.name
);
3020 lttv_module_release(module
);
3024 /* Display a directory dialogue to let user select a path for library searching
3028 on_add_library_search_path_activate (GtkMenuItem
*menuitem
,
3031 GtkDirSelection
* file_selector
= (GtkDirSelection
*)gtk_dir_selection_new("Select library path");
3035 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
3036 if(remember_plugins_dir
[0] != '\0')
3037 gtk_dir_selection_set_filename(file_selector
, remember_plugins_dir
);
3039 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
3041 case GTK_RESPONSE_ACCEPT
:
3042 case GTK_RESPONSE_OK
:
3043 dir
= gtk_dir_selection_get_dir (file_selector
);
3044 strncpy(remember_plugins_dir
,dir
,PATH_MAX
);
3045 strncat(remember_plugins_dir
,"/",PATH_MAX
);
3046 lttv_library_path_add(dir
);
3047 case GTK_RESPONSE_REJECT
:
3048 case GTK_RESPONSE_CANCEL
:
3050 gtk_widget_destroy((GtkWidget
*)file_selector
);
3056 /* Display a directory dialogue to let user select a path for library searching
3060 on_remove_library_search_path_activate (GtkMenuItem
*menuitem
,
3063 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
3065 const char *lib_path
;
3070 name
= g_ptr_array_new();
3071 nb
= lttv_library_path_number();
3072 /* ask for the library name */
3075 gchar
*path
= lttv_library_path_get(i
);
3076 g_ptr_array_add(name
, path
);
3078 lib_path
= get_selection((char **)(name
->pdata
), name
->len
,
3079 "Select a library path", "Library paths");
3081 g_ptr_array_free(name
, TRUE
);
3083 if(lib_path
== NULL
) return;
3086 lttv_library_path_remove(lib_path
);
3090 on_color_activate (GtkMenuItem
*menuitem
,
3093 g_printf("Color\n");
3098 on_filter_activate (GtkMenuItem
*menuitem
,
3101 g_printf("Filter\n");
3106 on_save_configuration_activate (GtkMenuItem
*menuitem
,
3109 g_printf("Save configuration\n");
3114 on_content_activate (GtkMenuItem
*menuitem
,
3117 g_printf("Content\n");
3122 on_about_close_activate (GtkButton
*button
,
3125 GtkWidget
*about_widget
= GTK_WIDGET(user_data
);
3127 gtk_widget_destroy(about_widget
);
3131 on_about_activate (GtkMenuItem
*menuitem
,
3134 MainWindow
*main_window
= get_window_data_struct(GTK_WIDGET(menuitem
));
3135 GtkWidget
*window_widget
= main_window
->mwindow
;
3136 GtkWidget
*about_widget
= gtk_window_new(GTK_WINDOW_TOPLEVEL
);
3137 GtkWindow
*about_window
= GTK_WINDOW(about_widget
);
3138 gint window_width
, window_height
;
3140 gtk_window_set_title(about_window
, "About Linux Trace Toolkit");
3142 gtk_window_set_resizable(about_window
, FALSE
);
3143 gtk_window_set_transient_for(GTK_WINDOW(window_widget
), about_window
);
3144 gtk_window_set_destroy_with_parent(about_window
, TRUE
);
3145 gtk_window_set_modal(about_window
, FALSE
);
3147 /* Put the about window at the center of the screen */
3148 gtk_window_get_size(about_window
, &window_width
, &window_height
);
3149 gtk_window_move (about_window
,
3150 (gdk_screen_width() - window_width
)/2,
3151 (gdk_screen_height() - window_height
)/2);
3153 GtkWidget
*vbox
= gtk_vbox_new(FALSE
, 1);
3155 gtk_container_add(GTK_CONTAINER(about_widget
), vbox
);
3159 GtkWidget
*label1
= gtk_label_new("");
3160 gtk_misc_set_padding(GTK_MISC(label1
), 10, 20);
3161 gtk_label_set_markup(GTK_LABEL(label1
), "\
3162 <big>Linux Trace Toolkit</big>");
3163 gtk_label_set_justify(GTK_LABEL(label1
), GTK_JUSTIFY_CENTER
);
3165 GtkWidget
*label2
= gtk_label_new("");
3166 gtk_misc_set_padding(GTK_MISC(label2
), 10, 20);
3167 gtk_label_set_markup(GTK_LABEL(label2
), "\
3168 Project author: Karim Yaghmour\n\
3172 Michel Dagenais (New trace format, lttv main)\n\
3173 Mathieu Desnoyers (Directory structure, build with automake/conf,\n\
3174 lttv gui, control flow view, gui green threads\n\
3175 with interruptible foreground and background computation,\n\
3176 detailed event list)\n\
3177 Benoit Des Ligneris (Cluster adaptation)\n\
3178 Xang-Xiu Yang (new trace reading library and converter, lttv gui, \n\
3179 detailed event list and statistics view)\n\
3180 Tom Zanussi (RelayFS)");
3182 GtkWidget
*label3
= gtk_label_new("");
3183 gtk_label_set_markup(GTK_LABEL(label3
), "\
3184 Linux Trace Toolkit, Copyright (C) 2004 Karim Yaghmour\n\
3185 Linux Trace Toolkit comes with ABSOLUTELY NO WARRANTY.\n\
3186 This is free software, and you are welcome to redistribute it\n\
3187 under certain conditions. See COPYING for details.");
3188 gtk_misc_set_padding(GTK_MISC(label3
), 10, 20);
3190 gtk_box_pack_start_defaults(GTK_BOX(vbox
), label1
);
3191 gtk_box_pack_start_defaults(GTK_BOX(vbox
), label2
);
3192 gtk_box_pack_start_defaults(GTK_BOX(vbox
), label3
);
3194 GtkWidget
*hbox
= gtk_hbox_new(TRUE
, 0);
3195 gtk_box_pack_end(GTK_BOX(vbox
), hbox
, FALSE
, FALSE
, 0);
3196 GtkWidget
*close_button
= gtk_button_new_with_mnemonic("_Close");
3197 gtk_box_pack_end(GTK_BOX(hbox
), close_button
, FALSE
, FALSE
, 0);
3198 gtk_container_set_border_width(GTK_CONTAINER(close_button
), 20);
3200 g_signal_connect(G_OBJECT(close_button
), "clicked",
3201 G_CALLBACK(on_about_close_activate
),
3202 (gpointer
)about_widget
);
3204 gtk_widget_show_all(about_widget
);
3209 on_button_new_clicked (GtkButton
*button
,
3212 create_new_window((GtkWidget
*)button
, user_data
, TRUE
);
3216 on_button_new_tab_clicked (GtkButton
*button
,
3219 create_new_tab((GtkWidget
*)button
, user_data
);
3223 on_button_open_clicked (GtkButton
*button
,
3226 open_traceset((GtkWidget
*)button
, user_data
);
3231 on_button_add_trace_clicked (GtkButton
*button
,
3234 add_trace((GtkWidget
*)button
, user_data
);
3239 on_button_remove_trace_clicked (GtkButton
*button
,
3242 remove_trace((GtkWidget
*)button
, user_data
);
3246 on_button_redraw_clicked (GtkButton
*button
,
3249 redraw((GtkWidget
*)button
, user_data
);
3253 on_button_continue_processing_clicked (GtkButton
*button
,
3256 continue_processing((GtkWidget
*)button
, user_data
);
3260 on_button_stop_processing_clicked (GtkButton
*button
,
3263 stop_processing((GtkWidget
*)button
, user_data
);
3269 on_button_save_clicked (GtkButton
*button
,
3272 save((GtkWidget
*)button
, user_data
);
3277 on_button_save_as_clicked (GtkButton
*button
,
3280 save_as((GtkWidget
*)button
, user_data
);
3285 on_button_zoom_in_clicked (GtkButton
*button
,
3288 zoom_in((GtkWidget
*)button
, user_data
);
3293 on_button_zoom_out_clicked (GtkButton
*button
,
3296 zoom_out((GtkWidget
*)button
, user_data
);
3301 on_button_zoom_extended_clicked (GtkButton
*button
,
3304 zoom_extended((GtkWidget
*)button
, user_data
);
3309 on_button_go_to_time_clicked (GtkButton
*button
,
3312 go_to_time((GtkWidget
*)button
, user_data
);
3317 on_button_show_time_frame_clicked (GtkButton
*button
,
3320 show_time_frame((GtkWidget
*)button
, user_data
);
3325 on_button_move_up_clicked (GtkButton
*button
,
3328 move_up_viewer((GtkWidget
*)button
, user_data
);
3333 on_button_move_down_clicked (GtkButton
*button
,
3336 move_down_viewer((GtkWidget
*)button
, user_data
);
3341 on_button_delete_viewer_clicked (GtkButton
*button
,
3344 delete_viewer((GtkWidget
*)button
, user_data
);
3348 on_MWindow_destroy (GtkWidget
*widget
,
3351 MainWindow
*main_window
= get_window_data_struct(widget
);
3352 LttvIAttribute
*attributes
= main_window
->attributes
;
3353 LttvAttributeValue value
;
3355 //This is unnecessary, since widgets will be destroyed
3356 //by the main window widget anyway.
3357 //remove_all_menu_toolbar_constructors(main_window, NULL);
3359 g_assert(lttv_iattribute_find_by_path(attributes
,
3360 "viewers/menu", LTTV_POINTER
, &value
));
3361 lttv_menus_destroy((LttvMenus
*)*(value
.v_pointer
));
3363 g_assert(lttv_iattribute_find_by_path(attributes
,
3364 "viewers/toolbar", LTTV_POINTER
, &value
));
3365 lttv_toolbars_destroy((LttvToolbars
*)*(value
.v_pointer
));
3367 g_object_unref(main_window
->attributes
);
3368 g_main_window_list
= g_slist_remove(g_main_window_list
, main_window
);
3370 g_printf("There are now : %d windows\n",g_slist_length(g_main_window_list
));
3371 if(g_slist_length(g_main_window_list
) == 0)
3376 on_MWindow_configure (GtkWidget
*widget
,
3377 GdkEventConfigure
*event
,
3380 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)widget
);
3381 float width
= event
->width
;
3382 TimeWindow time_win
;
3384 TimeInterval
*time_span
;
3387 // MD : removed time width modification upon resizing of the main window.
3388 // The viewers will redraw themselves completely, without time interval
3391 if(mw_data->window_width){
3392 time_span = LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context)->Time_Span ;
3393 time_win = tab->time_window;
3394 ratio = width / mw_data->window_width;
3395 tab->time_window.time_width = ltt_time_mul(time_win.time_width,ratio);
3396 time = ltt_time_sub(time_span->endTime, time_win.start_time);
3397 if(ltt_time_compare(time, tab->time_window.time_width) < 0){
3398 tab->time_window.time_width = time;
3404 mw_data->window_width = (int)width;
3413 on_MNotebook_switch_page (GtkNotebook
*notebook
,
3414 GtkNotebookPage
*page
,
3422 void time_change_manager (Tab
*tab
,
3423 TimeWindow new_time_window
)
3425 /* Only one source of time change */
3426 if(tab
->time_manager_lock
== TRUE
) return;
3428 tab
->time_manager_lock
= TRUE
;
3430 LttvTracesetContext
*tsc
= LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3431 TimeInterval time_span
= tsc
->time_span
;
3432 LttTime start_time
= new_time_window
.start_time
;
3433 LttTime end_time
= ltt_time_add(new_time_window
.start_time
,
3434 new_time_window
.time_width
);
3437 GtkAdjustment
*adjustment
= gtk_range_get_adjustment(GTK_RANGE(tab
->scrollbar
));
3438 LttTime upper
= ltt_time_sub(time_span
.end_time
, time_span
.start_time
);
3440 gtk_range_set_increments(GTK_RANGE(tab
->scrollbar
),
3441 ltt_time_to_double(new_time_window
.time_width
)
3442 / SCROLL_STEP_PER_PAGE
3443 * NANOSECONDS_PER_SECOND
, /* step increment */
3444 ltt_time_to_double(new_time_window
.time_width
)
3445 * NANOSECONDS_PER_SECOND
); /* page increment */
3446 gtk_range_set_range(GTK_RANGE(tab
->scrollbar
),
3448 ltt_time_to_double(upper
)
3449 * NANOSECONDS_PER_SECOND
); /* upper */
3451 g_object_set(G_OBJECT(adjustment
),
3455 ltt_time_to_double(upper
)
3456 * NANOSECONDS_PER_SECOND
, /* upper */
3458 ltt_time_to_double(new_time_window
.time_width
)
3459 / SCROLL_STEP_PER_PAGE
3460 * NANOSECONDS_PER_SECOND
, /* step increment */
3462 ltt_time_to_double(new_time_window
.time_width
)
3463 * NANOSECONDS_PER_SECOND
, /* page increment */
3465 ltt_time_to_double(new_time_window
.time_width
)
3466 * NANOSECONDS_PER_SECOND
, /* page size */
3468 gtk_adjustment_changed(adjustment
);
3470 // g_object_set(G_OBJECT(adjustment),
3472 // ltt_time_to_double(
3473 // ltt_time_sub(start_time, time_span.start_time))
3474 // * NANOSECONDS_PER_SECOND, /* value */
3476 //gtk_adjustment_value_changed(adjustment);
3477 gtk_range_set_value(GTK_RANGE(tab
->scrollbar
),
3479 ltt_time_sub(start_time
, time_span
.start_time
))
3480 * NANOSECONDS_PER_SECOND
/* value */);
3482 /* set the time bar. */
3484 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry1
),
3485 (double)time_span
.start_time
.tv_sec
,
3486 (double)time_span
.end_time
.tv_sec
);
3487 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry1
),
3488 (double)start_time
.tv_sec
);
3490 /* start nanoseconds */
3491 if(start_time
.tv_sec
== time_span
.start_time
.tv_sec
) {
3492 /* can be both beginning and end at the same time. */
3493 if(start_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3494 /* If we are at the end, max nsec to end.. -1 (not zero length) */
3495 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry2
),
3496 (double)time_span
.start_time
.tv_nsec
,
3497 (double)time_span
.end_time
.tv_nsec
-1);
3499 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry2
),
3500 (double)time_span
.start_time
.tv_nsec
,
3501 (double)NANOSECONDS_PER_SECOND
-1);
3503 } else if(start_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3504 /* If we are at the end, max nsec to end.. -1 (not zero length) */
3505 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry2
),
3507 (double)time_span
.end_time
.tv_nsec
-1);
3508 } else /* anywhere else */
3509 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry2
),
3511 (double)NANOSECONDS_PER_SECOND
-1);
3512 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry2
),
3513 (double)start_time
.tv_nsec
);
3516 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry3
),
3517 (double)time_span
.start_time
.tv_sec
,
3518 (double)time_span
.end_time
.tv_sec
);
3519 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry3
),
3520 (double)end_time
.tv_sec
);
3522 /* end nanoseconds */
3523 if(end_time
.tv_sec
== time_span
.start_time
.tv_sec
) {
3524 /* can be both beginning and end at the same time. */
3525 if(end_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3526 /* If we are at the end, max nsec to end.. */
3527 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry4
),
3528 (double)time_span
.start_time
.tv_nsec
+1,
3529 (double)time_span
.end_time
.tv_nsec
);
3531 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry4
),
3532 (double)time_span
.start_time
.tv_nsec
+1,
3533 (double)NANOSECONDS_PER_SECOND
-1);
3536 else if(end_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3537 /* If we are at the end, max nsec to end.. */
3538 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry4
),
3540 (double)time_span
.end_time
.tv_nsec
);
3542 else /* anywhere else */
3543 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry4
),
3545 (double)NANOSECONDS_PER_SECOND
-1);
3546 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry4
),
3547 (double)end_time
.tv_nsec
);
3549 /* call viewer hooks for new time window */
3550 set_time_window(tab
, &new_time_window
);
3552 tab
->time_manager_lock
= FALSE
;
3556 /* value changed for frame start s
3558 * Check time span : if ns is out of range, clip it the nearest good value.
3561 on_MEntry1_value_changed (GtkSpinButton
*spinbutton
,
3564 Tab
*tab
=(Tab
*)user_data
;
3565 LttvTracesetContext
* tsc
=
3566 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3567 TimeInterval time_span
= tsc
->time_span
;
3568 gint value
= gtk_spin_button_get_value_as_int(spinbutton
);
3570 TimeWindow new_time_window
= tab
->time_window
;
3572 LttTime end_time
= ltt_time_add(new_time_window
.start_time
,
3573 new_time_window
.time_width
);
3575 new_time_window
.start_time
.tv_sec
= value
;
3577 /* start nanoseconds */
3578 if(new_time_window
.start_time
.tv_sec
== time_span
.start_time
.tv_sec
) {
3579 if(new_time_window
.start_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3580 if(new_time_window
.start_time
.tv_nsec
> time_span
.end_time
.tv_nsec
)
3581 new_time_window
.start_time
.tv_nsec
= time_span
.end_time
.tv_nsec
-1;
3582 if(new_time_window
.start_time
.tv_nsec
< time_span
.start_time
.tv_nsec
)
3583 new_time_window
.start_time
.tv_nsec
= time_span
.start_time
.tv_nsec
;
3585 if(new_time_window
.start_time
.tv_nsec
< time_span
.start_time
.tv_nsec
)
3586 new_time_window
.start_time
.tv_nsec
= time_span
.start_time
.tv_nsec
;
3589 else if(new_time_window
.start_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3590 if(new_time_window
.start_time
.tv_nsec
> time_span
.end_time
.tv_nsec
)
3591 new_time_window
.start_time
.tv_nsec
= time_span
.end_time
.tv_nsec
-1;
3594 /* check if end time selected is below or equal */
3595 if(ltt_time_compare(new_time_window
.start_time
, end_time
) >= 0) {
3596 /* Then, we must push back end time : keep the same time width
3597 * if possible, else end traceset time */
3598 end_time
= LTT_TIME_MIN(time_span
.end_time
,
3599 ltt_time_add(new_time_window
.start_time
,
3600 new_time_window
.time_width
)
3604 /* Fix the time width to fit start time and end time */
3605 new_time_window
.time_width
= ltt_time_sub(end_time
,
3606 new_time_window
.start_time
);
3608 time_change_manager(tab
, new_time_window
);
3613 on_MEntry2_value_changed (GtkSpinButton
*spinbutton
,
3616 Tab
*tab
=(Tab
*)user_data
;
3617 LttvTracesetContext
* tsc
=
3618 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3619 TimeInterval time_span
= tsc
->time_span
;
3620 gint value
= gtk_spin_button_get_value_as_int(spinbutton
);
3622 TimeWindow new_time_window
= tab
->time_window
;
3624 LttTime end_time
= ltt_time_add(new_time_window
.start_time
,
3625 new_time_window
.time_width
);
3627 new_time_window
.start_time
.tv_nsec
= value
;
3629 /* check if end time selected is below or equal */
3630 if(ltt_time_compare(new_time_window
.start_time
, end_time
) >= 0) {
3631 /* Then, we must push back end time : keep the same time width
3632 * if possible, else end traceset time */
3633 end_time
= LTT_TIME_MIN(time_span
.end_time
,
3634 ltt_time_add(new_time_window
.start_time
,
3635 new_time_window
.time_width
)
3639 /* Fix the time width to fit start time and end time */
3640 new_time_window
.time_width
= ltt_time_sub(end_time
,
3641 new_time_window
.start_time
);
3643 time_change_manager(tab
, new_time_window
);
3648 on_MEntry3_value_changed (GtkSpinButton
*spinbutton
,
3651 Tab
*tab
=(Tab
*)user_data
;
3652 LttvTracesetContext
* tsc
=
3653 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3654 TimeInterval time_span
= tsc
->time_span
;
3655 gint value
= gtk_spin_button_get_value_as_int(spinbutton
);
3657 TimeWindow new_time_window
= tab
->time_window
;
3659 LttTime end_time
= ltt_time_add(new_time_window
.start_time
,
3660 new_time_window
.time_width
);
3661 end_time
.tv_sec
= value
;
3663 /* end nanoseconds */
3664 if(end_time
.tv_sec
== time_span
.start_time
.tv_sec
) {
3665 if(end_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3666 if(end_time
.tv_nsec
> time_span
.end_time
.tv_nsec
)
3667 end_time
.tv_nsec
= time_span
.end_time
.tv_nsec
;
3668 if(end_time
.tv_nsec
< time_span
.start_time
.tv_nsec
)
3669 end_time
.tv_nsec
= time_span
.start_time
.tv_nsec
+1;
3671 if(end_time
.tv_nsec
< time_span
.start_time
.tv_nsec
)
3672 end_time
.tv_nsec
= time_span
.start_time
.tv_nsec
+1;
3675 else if(end_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3676 if(end_time
.tv_nsec
> time_span
.end_time
.tv_nsec
)
3677 end_time
.tv_nsec
= time_span
.end_time
.tv_nsec
;
3680 /* check if end time selected is below or equal */
3681 if(ltt_time_compare(new_time_window
.start_time
, end_time
) >= 0) {
3682 /* Then, we must push front start time : keep the same time width
3683 * if possible, else end traceset time */
3684 new_time_window
.start_time
= LTT_TIME_MAX(time_span
.start_time
,
3685 ltt_time_sub(end_time
,
3686 new_time_window
.time_width
)
3690 /* Fix the time width to fit start time and end time */
3691 new_time_window
.time_width
= ltt_time_sub(end_time
,
3692 new_time_window
.start_time
);
3694 time_change_manager(tab
, new_time_window
);
3699 on_MEntry4_value_changed (GtkSpinButton
*spinbutton
,
3702 Tab
*tab
=(Tab
*)user_data
;
3703 LttvTracesetContext
* tsc
=
3704 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3705 TimeInterval time_span
= tsc
->time_span
;
3706 gint value
= gtk_spin_button_get_value_as_int(spinbutton
);
3708 TimeWindow new_time_window
= tab
->time_window
;
3710 LttTime end_time
= ltt_time_add(new_time_window
.start_time
,
3711 new_time_window
.time_width
);
3712 end_time
.tv_nsec
= value
;
3714 /* check if end time selected is below or equal */
3715 if(ltt_time_compare(new_time_window
.start_time
, end_time
) >= 0) {
3716 /* Then, we must push front start time : keep the same time width
3717 * if possible, else end traceset time */
3718 new_time_window
.start_time
= LTT_TIME_MAX(time_span
.start_time
,
3719 ltt_time_sub(end_time
,
3720 new_time_window
.time_width
)
3724 /* Fix the time width to fit start time and end time */
3725 new_time_window
.time_width
= ltt_time_sub(end_time
,
3726 new_time_window
.start_time
);
3728 time_change_manager(tab
, new_time_window
);
3733 void current_time_change_manager (Tab
*tab
,
3734 LttTime new_current_time
)
3736 /* Only one source of time change */
3737 if(tab
->current_time_manager_lock
== TRUE
) return;
3739 tab
->current_time_manager_lock
= TRUE
;
3741 LttvTracesetContext
*tsc
= LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3742 TimeInterval time_span
= tsc
->time_span
;
3744 /* current seconds */
3745 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry5
),
3746 (double)time_span
.start_time
.tv_sec
,
3747 (double)time_span
.end_time
.tv_sec
);
3748 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry5
),
3749 (double)new_current_time
.tv_sec
);
3752 /* start nanoseconds */
3753 if(new_current_time
.tv_sec
== time_span
.start_time
.tv_sec
) {
3754 /* can be both beginning and end at the same time. */
3755 if(new_current_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3756 /* If we are at the end, max nsec to end.. */
3757 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry6
),
3758 (double)time_span
.start_time
.tv_nsec
,
3759 (double)time_span
.end_time
.tv_nsec
);
3761 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry6
),
3762 (double)time_span
.start_time
.tv_nsec
,
3763 (double)NANOSECONDS_PER_SECOND
-1);
3765 } else if(new_current_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3766 /* If we are at the end, max nsec to end.. */
3767 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry6
),
3769 (double)time_span
.end_time
.tv_nsec
);
3770 } else /* anywhere else */
3771 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry6
),
3773 (double)NANOSECONDS_PER_SECOND
-1);
3775 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry6
),
3776 (double)new_current_time
.tv_nsec
);
3778 set_current_time(tab
, &new_current_time
);
3780 tab
->current_time_manager_lock
= FALSE
;
3784 on_MEntry5_value_changed (GtkSpinButton
*spinbutton
,
3787 Tab
*tab
= (Tab
*)user_data
;
3788 LttvTracesetContext
* tsc
=
3789 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3790 TimeInterval time_span
= tsc
->time_span
;
3791 gint value
= gtk_spin_button_get_value_as_int(spinbutton
);
3792 LttTime new_current_time
= tab
->current_time
;
3793 new_current_time
.tv_sec
= value
;
3795 /* current nanoseconds */
3796 if(new_current_time
.tv_sec
== time_span
.start_time
.tv_sec
) {
3797 if(new_current_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3798 if(new_current_time
.tv_nsec
> time_span
.end_time
.tv_nsec
)
3799 new_current_time
.tv_nsec
= time_span
.end_time
.tv_nsec
;
3800 if(new_current_time
.tv_nsec
< time_span
.start_time
.tv_nsec
)
3801 new_current_time
.tv_nsec
= time_span
.start_time
.tv_nsec
;
3803 if(new_current_time
.tv_nsec
< time_span
.start_time
.tv_nsec
)
3804 new_current_time
.tv_nsec
= time_span
.start_time
.tv_nsec
;
3807 else if(new_current_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3808 if(new_current_time
.tv_nsec
> time_span
.end_time
.tv_nsec
)
3809 new_current_time
.tv_nsec
= time_span
.end_time
.tv_nsec
;
3812 current_time_change_manager(tab
, new_current_time
);
3816 on_MEntry6_value_changed (GtkSpinButton
*spinbutton
,
3819 Tab
*tab
= (Tab
*)user_data
;
3820 gint value
= gtk_spin_button_get_value_as_int(spinbutton
);
3821 LttTime new_current_time
= tab
->current_time
;
3822 new_current_time
.tv_nsec
= value
;
3824 current_time_change_manager(tab
, new_current_time
);
3828 void scroll_value_changed_cb(GtkWidget
*scrollbar
,
3831 Tab
*tab
= (Tab
*)user_data
;
3832 TimeWindow new_time_window
;
3834 GtkAdjustment
*adjust
= gtk_range_get_adjustment(GTK_RANGE(scrollbar
));
3835 gdouble value
= gtk_adjustment_get_value(adjust
);
3836 // gdouble upper, lower, ratio, page_size;
3838 LttvTracesetContext
* tsc
=
3839 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3840 TimeInterval time_span
= tsc
->time_span
;
3842 time
= ltt_time_add(ltt_time_from_double(value
/NANOSECONDS_PER_SECOND
),
3843 time_span
.start_time
);
3845 new_time_window
.start_time
= time
;
3847 page_size
= adjust
->page_size
;
3849 new_time_window
.time_width
=
3850 ltt_time_from_double(page_size
/NANOSECONDS_PER_SECOND
);
3853 time_change_manager(tab
, new_time_window
);
3855 //time_window = tab->time_window;
3857 lower
= adjust
->lower
;
3858 upper
= adjust
->upper
;
3859 ratio
= (value
- lower
) / (upper
- lower
);
3860 g_info("lower %lu, upper %lu, value %lu, ratio %lu", lower
, upper
, value
, ratio
);
3862 //time = ltt_time_sub(time_span->end_time, time_span->start_time);
3863 //time = ltt_time_mul(time, (float)ratio);
3864 //time = ltt_time_add(time_span->start_time, time);
3865 time
= ltt_time_add(ltt_time_from_double(value
/NANOSECONDS_PER_SECOND
),
3866 time_span
.start_time
);
3868 time_window
.start_time
= time
;
3870 page_size
= adjust
->page_size
;
3872 time_window
.time_width
=
3873 ltt_time_from_double(page_size
/NANOSECONDS_PER_SECOND
);
3874 //time = ltt_time_sub(time_span.end_time, time);
3875 //if(ltt_time_compare(time,time_window.time_width) < 0){
3876 // time_window.time_width = time;
3879 /* call viewer hooks for new time window */
3880 set_time_window(tab
, &time_window
);
3885 /* callback function to check or uncheck the check box (filter)
3888 void checkbox_changed(GtkTreeView
*treeview
,
3890 GtkTreeViewColumn
*arg2
,
3893 GtkTreeStore
* store
= (GtkTreeStore
*)gtk_tree_view_get_model (treeview
);
3897 if (gtk_tree_model_get_iter ((GtkTreeModel
*)store
, &iter
, arg1
)){
3898 gtk_tree_model_get ((GtkTreeModel
*)store
, &iter
, CHECKBOX_COLUMN
, &value
, -1);
3899 value
= value
? FALSE
: TRUE
;
3900 gtk_tree_store_set (GTK_TREE_STORE (store
), &iter
, CHECKBOX_COLUMN
, value
, -1);
3906 /* According to user's selection, update selector(filter)
3909 void update_filter(LttvTracesetSelector
*s
, GtkTreeStore
*store
)
3911 GtkTreeIter iter
, child_iter
, child_iter1
, child_iter2
;
3912 int i
, j
, k
, nb_eventtype
;
3913 LttvTraceSelector
* trace
;
3914 LttvTracefileSelector
* tracefile
;
3915 LttvEventtypeSelector
* eventtype
;
3916 gboolean value
, value1
, value2
;
3918 if(gtk_tree_model_get_iter_first((GtkTreeModel
*)store
, &iter
)){
3921 trace
= lttv_traceset_selector_trace_get(s
, i
);
3922 nb_eventtype
= lttv_trace_selector_eventtype_number(trace
);
3923 gtk_tree_model_get ((GtkTreeModel
*)store
, &iter
, CHECKBOX_COLUMN
, &value
,-1);
3926 if(gtk_tree_model_iter_children ((GtkTreeModel
*)store
, &child_iter
, &iter
)){
3928 if(j
<1){//eventtype selector for trace
3929 gtk_tree_model_get ((GtkTreeModel
*)store
, &child_iter
, CHECKBOX_COLUMN
, &value2
,-1);
3932 if(gtk_tree_model_iter_children ((GtkTreeModel
*)store
, &child_iter1
, &child_iter
)){
3934 eventtype
= lttv_trace_selector_eventtype_get(trace
,k
);
3935 gtk_tree_model_get ((GtkTreeModel
*)store
, &child_iter1
, CHECKBOX_COLUMN
, &value2
,-1);
3936 lttv_eventtype_selector_set_selected(eventtype
,value2
);
3938 }while(gtk_tree_model_iter_next((GtkTreeModel
*)store
, &child_iter1
));
3941 }else{ //tracefile selector
3942 tracefile
= lttv_trace_selector_tracefile_get(trace
, j
- 1);
3943 gtk_tree_model_get ((GtkTreeModel
*)store
, &child_iter
, CHECKBOX_COLUMN
, &value1
,-1);
3944 lttv_tracefile_selector_set_selected(tracefile
,value1
);
3946 gtk_tree_model_iter_children((GtkTreeModel
*)store
, &child_iter1
, &child_iter
); //eventtype selector
3947 gtk_tree_model_get ((GtkTreeModel
*)store
, &child_iter1
, CHECKBOX_COLUMN
, &value2
,-1);
3950 if(gtk_tree_model_iter_children ((GtkTreeModel
*)store
, &child_iter2
, &child_iter1
)){
3951 do{//eventtype selector for tracefile
3952 eventtype
= lttv_tracefile_selector_eventtype_get(tracefile
,k
);
3953 gtk_tree_model_get ((GtkTreeModel
*)store
, &child_iter2
, CHECKBOX_COLUMN
, &value2
,-1);
3954 lttv_eventtype_selector_set_selected(eventtype
,value2
);
3956 }while(gtk_tree_model_iter_next((GtkTreeModel
*)store
, &child_iter2
));
3962 }while(gtk_tree_model_iter_next((GtkTreeModel
*)store
, &child_iter
));
3965 lttv_trace_selector_set_selected(trace
,value
);
3967 }while(gtk_tree_model_iter_next((GtkTreeModel
*)store
, &iter
));
3972 /* Display a dialogue showing all eventtypes and traces, let user to select the interested
3973 * eventtypes, tracefiles and traces (filter)
3976 gboolean
get_filter_selection(LttvTracesetSelector
*s
,char *title
, char * column_title
)
3978 GtkWidget
* dialogue
;
3979 GtkTreeStore
* store
;
3981 GtkWidget
* scroll_win
;
3982 GtkCellRenderer
* renderer
;
3983 GtkTreeViewColumn
* column
;
3984 GtkTreeIter iter
, child_iter
, child_iter1
, child_iter2
;
3985 int i
, j
, k
, id
, nb_trace
, nb_tracefile
, nb_eventtype
;
3986 LttvTraceSelector
* trace
;
3987 LttvTracefileSelector
* tracefile
;
3988 LttvEventtypeSelector
* eventtype
;
3992 dialogue
= gtk_dialog_new_with_buttons(title
,
3995 GTK_STOCK_OK
,GTK_RESPONSE_ACCEPT
,
3996 GTK_STOCK_CANCEL
,GTK_RESPONSE_REJECT
,
3998 gtk_window_set_default_size((GtkWindow
*)dialogue
, 300, 500);
4000 store
= gtk_tree_store_new (TOTAL_COLUMNS
, G_TYPE_BOOLEAN
, G_TYPE_STRING
);
4001 tree
= gtk_tree_view_new_with_model (GTK_TREE_MODEL (store
));
4002 g_object_unref (G_OBJECT (store
));
4003 g_signal_connect (G_OBJECT (tree
), "row-activated",
4004 G_CALLBACK (checkbox_changed
),
4008 renderer
= gtk_cell_renderer_toggle_new ();
4009 gtk_cell_renderer_toggle_set_radio((GtkCellRendererToggle
*)renderer
, FALSE
);
4011 g_object_set (G_OBJECT (renderer
),"activatable", TRUE
, NULL
);
4013 column
= gtk_tree_view_column_new_with_attributes ("Checkbox",
4015 "active", CHECKBOX_COLUMN
,
4017 gtk_tree_view_column_set_alignment (column
, 0.5);
4018 gtk_tree_view_column_set_fixed_width (column
, 20);
4019 gtk_tree_view_append_column (GTK_TREE_VIEW (tree
), column
);
4021 renderer
= gtk_cell_renderer_text_new ();
4022 column
= gtk_tree_view_column_new_with_attributes (column_title
,
4024 "text", NAME_COLUMN
,
4026 gtk_tree_view_column_set_alignment (column
, 0.0);
4027 gtk_tree_view_append_column (GTK_TREE_VIEW (tree
), column
);
4028 gtk_tree_view_set_headers_visible(GTK_TREE_VIEW (tree
), FALSE
);
4030 scroll_win
= gtk_scrolled_window_new (NULL
, NULL
);
4031 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll_win
),
4032 GTK_POLICY_AUTOMATIC
,GTK_POLICY_AUTOMATIC
);
4033 gtk_container_add (GTK_CONTAINER (scroll_win
), tree
);
4035 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialogue
)->vbox
), scroll_win
,TRUE
, TRUE
,0);
4037 gtk_widget_show(scroll_win
);
4038 gtk_widget_show(tree
);
4040 nb_trace
= lttv_traceset_selector_trace_number(s
);
4041 for(i
=0;i
<nb_trace
;i
++){
4042 trace
= lttv_traceset_selector_trace_get(s
, i
);
4043 name
= lttv_trace_selector_get_name(trace
);
4044 gtk_tree_store_append (store
, &iter
, NULL
);
4045 checked
= lttv_trace_selector_get_selected(trace
);
4046 gtk_tree_store_set (store
, &iter
,
4047 CHECKBOX_COLUMN
,checked
,
4051 gtk_tree_store_append (store
, &child_iter
, &iter
);
4052 gtk_tree_store_set (store
, &child_iter
,
4053 CHECKBOX_COLUMN
, checked
,
4054 NAME_COLUMN
,"eventtype",
4057 nb_eventtype
= lttv_trace_selector_eventtype_number(trace
);
4058 for(j
=0;j
<nb_eventtype
;j
++){
4059 eventtype
= lttv_trace_selector_eventtype_get(trace
,j
);
4060 name
= lttv_eventtype_selector_get_name(eventtype
);
4061 checked
= lttv_eventtype_selector_get_selected(eventtype
);
4062 gtk_tree_store_append (store
, &child_iter1
, &child_iter
);
4063 gtk_tree_store_set (store
, &child_iter1
,
4064 CHECKBOX_COLUMN
, checked
,
4069 nb_tracefile
= lttv_trace_selector_tracefile_number(trace
);
4070 for(j
=0;j
<nb_tracefile
;j
++){
4071 tracefile
= lttv_trace_selector_tracefile_get(trace
, j
);
4072 name
= lttv_tracefile_selector_get_name(tracefile
);
4073 gtk_tree_store_append (store
, &child_iter
, &iter
);
4074 checked
= lttv_tracefile_selector_get_selected(tracefile
);
4075 gtk_tree_store_set (store
, &child_iter
,
4076 CHECKBOX_COLUMN
, checked
,
4080 gtk_tree_store_append (store
, &child_iter1
, &child_iter
);
4081 gtk_tree_store_set (store
, &child_iter1
,
4082 CHECKBOX_COLUMN
, checked
,
4083 NAME_COLUMN
,"eventtype",
4086 for(k
=0;k
<nb_eventtype
;k
++){
4087 eventtype
= lttv_tracefile_selector_eventtype_get(tracefile
,k
);
4088 name
= lttv_eventtype_selector_get_name(eventtype
);
4089 checked
= lttv_eventtype_selector_get_selected(eventtype
);
4090 gtk_tree_store_append (store
, &child_iter2
, &child_iter1
);
4091 gtk_tree_store_set (store
, &child_iter2
,
4092 CHECKBOX_COLUMN
, checked
,
4099 id
= gtk_dialog_run(GTK_DIALOG(dialogue
));
4101 case GTK_RESPONSE_ACCEPT
:
4102 case GTK_RESPONSE_OK
:
4103 update_filter(s
, store
);
4104 gtk_widget_destroy(dialogue
);
4106 case GTK_RESPONSE_REJECT
:
4107 case GTK_RESPONSE_CANCEL
:
4109 gtk_widget_destroy(dialogue
);
4116 /* Select a trace which will be removed from traceset
4119 char * get_remove_trace(char ** all_trace_name
, int nb_trace
)
4121 return get_selection(all_trace_name
, nb_trace
,
4122 "Select a trace", "Trace pathname");
4126 /* Select a module which will be loaded
4129 char * get_load_module(char ** load_module_name
, int nb_module
)
4131 return get_selection(load_module_name
, nb_module
,
4132 "Select a module to load", "Module name");
4138 /* Select a module which will be unloaded
4141 char * get_unload_module(char ** loaded_module_name
, int nb_module
)
4143 return get_selection(loaded_module_name
, nb_module
,
4144 "Select a module to unload", "Module name");
4148 /* Display a dialogue which shows all selectable items, let user to
4149 * select one of them
4152 char * get_selection(char ** loaded_module_name
, int nb_module
,
4153 char *title
, char * column_title
)
4155 GtkWidget
* dialogue
;
4156 GtkWidget
* scroll_win
;
4158 GtkListStore
* store
;
4159 GtkTreeViewColumn
* column
;
4160 GtkCellRenderer
* renderer
;
4161 GtkTreeSelection
* select
;
4164 char * unload_module_name
= NULL
;
4166 dialogue
= gtk_dialog_new_with_buttons(title
,
4169 GTK_STOCK_OK
,GTK_RESPONSE_ACCEPT
,
4170 GTK_STOCK_CANCEL
,GTK_RESPONSE_REJECT
,
4172 gtk_window_set_default_size((GtkWindow
*)dialogue
, 500, 200);
4174 scroll_win
= gtk_scrolled_window_new (NULL
, NULL
);
4175 gtk_widget_show ( scroll_win
);
4176 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll_win
),
4177 GTK_POLICY_AUTOMATIC
, GTK_POLICY_AUTOMATIC
);
4179 store
= gtk_list_store_new (N_COLUMNS
,G_TYPE_STRING
);
4180 tree
= gtk_tree_view_new_with_model(GTK_TREE_MODEL (store
));
4181 gtk_widget_show ( tree
);
4182 g_object_unref (G_OBJECT (store
));
4184 renderer
= gtk_cell_renderer_text_new ();
4185 column
= gtk_tree_view_column_new_with_attributes (column_title
,
4187 "text", MODULE_COLUMN
,
4189 gtk_tree_view_column_set_alignment (column
, 0.5);
4190 gtk_tree_view_column_set_fixed_width (column
, 150);
4191 gtk_tree_view_append_column (GTK_TREE_VIEW (tree
), column
);
4193 select
= gtk_tree_view_get_selection (GTK_TREE_VIEW (tree
));
4194 gtk_tree_selection_set_mode (select
, GTK_SELECTION_SINGLE
);
4196 gtk_container_add (GTK_CONTAINER (scroll_win
), tree
);
4198 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialogue
)->vbox
), scroll_win
,TRUE
, TRUE
,0);
4200 for(i
=0;i
<nb_module
;i
++){
4201 gtk_list_store_append (store
, &iter
);
4202 gtk_list_store_set (store
, &iter
, MODULE_COLUMN
,loaded_module_name
[i
],-1);
4205 id
= gtk_dialog_run(GTK_DIALOG(dialogue
));
4207 case GTK_RESPONSE_ACCEPT
:
4208 case GTK_RESPONSE_OK
:
4209 if (gtk_tree_selection_get_selected (select
, (GtkTreeModel
**)&store
, &iter
)){
4210 gtk_tree_model_get ((GtkTreeModel
*)store
, &iter
, MODULE_COLUMN
, &unload_module_name
, -1);
4212 case GTK_RESPONSE_REJECT
:
4213 case GTK_RESPONSE_CANCEL
:
4215 gtk_widget_destroy(dialogue
);
4219 return unload_module_name
;
4223 /* Insert all menu entry and tool buttons into this main window
4228 void add_all_menu_toolbar_constructors(MainWindow
* mw
, gpointer user_data
)
4232 lttvwindow_viewer_constructor constructor
;
4233 LttvMenus
* global_menu
, * instance_menu
;
4234 LttvToolbars
* global_toolbar
, * instance_toolbar
;
4235 LttvMenuClosure
*menu_item
;
4236 LttvToolbarClosure
*toolbar_item
;
4237 LttvAttributeValue value
;
4238 LttvIAttribute
*global_attributes
= LTTV_IATTRIBUTE(lttv_global_attributes());
4239 LttvIAttribute
*attributes
= mw
->attributes
;
4240 GtkWidget
* tool_menu_title_menu
, *new_widget
, *pixmap
;
4242 g_assert(lttv_iattribute_find_by_path(global_attributes
,
4243 "viewers/menu", LTTV_POINTER
, &value
));
4244 if(*(value
.v_pointer
) == NULL
)
4245 *(value
.v_pointer
) = lttv_menus_new();
4246 global_menu
= (LttvMenus
*)*(value
.v_pointer
);
4248 g_assert(lttv_iattribute_find_by_path(attributes
,
4249 "viewers/menu", LTTV_POINTER
, &value
));
4250 if(*(value
.v_pointer
) == NULL
)
4251 *(value
.v_pointer
) = lttv_menus_new();
4252 instance_menu
= (LttvMenus
*)*(value
.v_pointer
);
4256 g_assert(lttv_iattribute_find_by_path(global_attributes
,
4257 "viewers/toolbar", LTTV_POINTER
, &value
));
4258 if(*(value
.v_pointer
) == NULL
)
4259 *(value
.v_pointer
) = lttv_toolbars_new();
4260 global_toolbar
= (LttvToolbars
*)*(value
.v_pointer
);
4262 g_assert(lttv_iattribute_find_by_path(attributes
,
4263 "viewers/toolbar", LTTV_POINTER
, &value
));
4264 if(*(value
.v_pointer
) == NULL
)
4265 *(value
.v_pointer
) = lttv_toolbars_new();
4266 instance_toolbar
= (LttvToolbars
*)*(value
.v_pointer
);
4268 /* Add missing menu entries to window instance */
4269 for(i
=0;i
<global_menu
->len
;i
++) {
4270 menu_item
= &g_array_index(global_menu
, LttvMenuClosure
, i
);
4272 //add menu_item to window instance;
4273 constructor
= menu_item
->con
;
4274 tool_menu_title_menu
= lookup_widget(mw
->mwindow
,"ToolMenuTitle_menu");
4276 gtk_menu_item_new_with_mnemonic (menu_item
->menu_text
);
4277 gtk_container_add (GTK_CONTAINER (tool_menu_title_menu
),
4279 g_signal_connect ((gpointer
) new_widget
, "activate",
4280 G_CALLBACK (insert_viewer_wrap
),
4282 gtk_widget_show (new_widget
);
4283 lttv_menus_add(instance_menu
, menu_item
->con
,
4284 menu_item
->menu_path
,
4285 menu_item
->menu_text
,
4290 /* Add missing toolbar entries to window instance */
4291 for(i
=0;i
<global_toolbar
->len
;i
++) {
4292 toolbar_item
= &g_array_index(global_toolbar
, LttvToolbarClosure
, i
);
4294 //add toolbar_item to window instance;
4295 constructor
= toolbar_item
->con
;
4296 tool_menu_title_menu
= lookup_widget(mw
->mwindow
,"MToolbar1");
4297 pixbuf
= gdk_pixbuf_new_from_xpm_data((const char**)toolbar_item
->pixmap
);
4298 pixmap
= gtk_image_new_from_pixbuf(pixbuf
);
4300 gtk_toolbar_append_element (GTK_TOOLBAR (tool_menu_title_menu
),
4301 GTK_TOOLBAR_CHILD_BUTTON
,
4304 toolbar_item
->tooltip
, NULL
,
4305 pixmap
, NULL
, NULL
);
4306 gtk_label_set_use_underline(
4307 GTK_LABEL (((GtkToolbarChild
*) (
4308 g_list_last (GTK_TOOLBAR
4309 (tool_menu_title_menu
)->children
)->data
))->label
),
4311 gtk_container_set_border_width (GTK_CONTAINER (new_widget
), 1);
4312 g_signal_connect ((gpointer
) new_widget
,
4314 G_CALLBACK (insert_viewer_wrap
),
4316 gtk_widget_show (new_widget
);
4318 lttv_toolbars_add(instance_toolbar
, toolbar_item
->con
,
4319 toolbar_item
->tooltip
,
4320 toolbar_item
->pixmap
,
4328 /* Create a main window
4331 void construct_main_window(MainWindow
* parent
)
4333 g_debug("construct_main_window()");
4334 GtkWidget
* new_window
; /* New generated main window */
4335 MainWindow
* new_m_window
;/* New main window structure */
4336 GtkNotebook
* notebook
;
4337 LttvIAttribute
*attributes
=
4338 LTTV_IATTRIBUTE(g_object_new(LTTV_ATTRIBUTE_TYPE
, NULL
));
4339 LttvAttributeValue value
;
4342 new_m_window
= g_new(MainWindow
, 1);
4344 // Add the object's information to the module's array
4345 g_main_window_list
= g_slist_append(g_main_window_list
, new_m_window
);
4347 new_window
= create_MWindow();
4348 gtk_widget_show (new_window
);
4350 new_m_window
->mwindow
= new_window
;
4351 new_m_window
->attributes
= attributes
;
4353 g_assert(lttv_iattribute_find_by_path(attributes
,
4354 "viewers/menu", LTTV_POINTER
, &value
));
4355 *(value
.v_pointer
) = lttv_menus_new();
4357 g_assert(lttv_iattribute_find_by_path(attributes
,
4358 "viewers/toolbar", LTTV_POINTER
, &value
));
4359 *(value
.v_pointer
) = lttv_toolbars_new();
4361 add_all_menu_toolbar_constructors(new_m_window
, NULL
);
4363 g_object_set_data_full(G_OBJECT(new_window
),
4365 (gpointer
)new_m_window
,
4366 (GDestroyNotify
)g_free
);
4367 //create a default tab
4368 notebook
= (GtkNotebook
*)lookup_widget(new_m_window
->mwindow
, "MNotebook");
4369 if(notebook
== NULL
){
4370 g_printf("Notebook does not exist\n");
4373 //gtk_notebook_popup_enable (GTK_NOTEBOOK(notebook));
4374 //for now there is no name field in LttvTraceset structure
4375 //Use "Traceset" as the label for the default tab
4377 GtkWidget
* parent_notebook
= lookup_widget(parent
->mwindow
, "MNotebook");
4378 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(parent_notebook
),
4379 gtk_notebook_get_current_page(GTK_NOTEBOOK(parent_notebook
)));
4385 parent_tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
4387 new_tab
= create_tab(new_m_window
, parent_tab
, notebook
, "Traceset");
4389 new_tab
= create_tab(new_m_window
, NULL
, notebook
, "Traceset");
4390 /* First window, use command line trace */
4391 if(g_init_trace
!= NULL
){
4392 lttvwindow_add_trace(new_tab
,
4396 LttvTraceset
*traceset
= new_tab
->traceset_info
->traceset
;
4397 SetTraceset(new_tab
, traceset
);
4399 /* Insert default viewers */
4401 LttvAttributeType type
;
4402 LttvAttributeName name
;
4403 LttvAttributeValue value
;
4404 LttvAttribute
*attribute
;
4406 LttvIAttribute
*attributes_global
=
4407 LTTV_IATTRIBUTE(lttv_global_attributes());
4409 g_assert(attribute
=
4410 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
4411 LTTV_IATTRIBUTE(attributes_global
),
4412 LTTV_VIEWER_CONSTRUCTORS
)));
4414 name
= g_quark_from_string("guievents");
4415 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
4417 if(type
== LTTV_POINTER
) {
4418 lttvwindow_viewer_constructor viewer_constructor
=
4419 (lttvwindow_viewer_constructor
)*value
.v_pointer
;
4420 insert_viewer(new_window
, viewer_constructor
);
4423 name
= g_quark_from_string("guicontrolflow");
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("guistatistics");
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
);
4444 g_printf("There are now : %d windows\n",g_slist_length(g_main_window_list
));
4448 /* Free the memory occupied by a tab structure
4452 void tab_destructor(Tab
* tab
)
4454 int i
, nb
, ref_count
;
4457 gtk_object_destroy(GTK_OBJECT(tab
->tooltips
));
4460 g_object_unref(tab
->attributes
);
4462 if(tab
->interrupted_state
)
4463 g_object_unref(tab
->interrupted_state
);
4466 if(tab
->traceset_info
->traceset_context
!= NULL
){
4467 //remove state update hooks
4468 lttv_state_remove_event_hooks(
4469 (LttvTracesetState
*)tab
->traceset_info
->
4471 lttv_context_fini(LTTV_TRACESET_CONTEXT(tab
->traceset_info
->
4473 g_object_unref(tab
->traceset_info
->traceset_context
);
4475 if(tab
->traceset_info
->traceset
!= NULL
) {
4476 nb
= lttv_traceset_number(tab
->traceset_info
->traceset
);
4477 for(i
= 0 ; i
< nb
; i
++) {
4478 trace
= lttv_traceset_get(tab
->traceset_info
->traceset
, i
);
4479 ref_count
= lttv_trace_get_ref_number(trace
);
4481 ltt_trace_close(lttv_trace(trace
));
4485 lttv_traceset_destroy(tab
->traceset_info
->traceset
);
4486 /* Remove the idle events requests processing function of the tab */
4487 g_idle_remove_by_data(tab
);
4489 g_slist_free(tab
->events_requests
);
4490 g_free(tab
->traceset_info
);
4495 /* Create a tab and insert it into the current main window
4498 Tab
* create_tab(MainWindow
* mw
, Tab
*copy_tab
,
4499 GtkNotebook
* notebook
, char * label
)
4505 //create a new tab data structure
4508 //construct and initialize the traceset_info
4509 tab
->traceset_info
= g_new(TracesetInfo
,1);
4512 tab
->traceset_info
->traceset
=
4513 lttv_traceset_copy(copy_tab
->traceset_info
->traceset
);
4515 tab
->traceset_info
->traceset
= lttv_traceset_new();
4519 lttv_attribute_write_xml(
4520 lttv_traceset_attribute(tab
->traceset_info
->traceset
),
4526 tab
->time_manager_lock
= FALSE
;
4527 tab
->current_time_manager_lock
= FALSE
;
4529 //FIXME copy not implemented in lower level
4530 tab
->traceset_info
->traceset_context
=
4531 g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
4532 g_assert(tab
->traceset_info
->traceset_context
!= NULL
);
4534 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
),
4535 tab
->traceset_info
->traceset
);
4536 //add state update hooks
4537 lttv_state_add_event_hooks(
4538 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
4540 //determine the current_time and time_window of the tab
4542 if(copy_tab
!= NULL
){
4543 tab
->time_window
= copy_tab
->time_window
;
4544 tab
->current_time
= copy_tab
->current_time
;
4546 tab
->time_window
.start_time
=
4547 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
4548 time_span
.start_time
;
4549 if(DEFAULT_TIME_WIDTH_S
<
4550 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
4551 time_span
.end_time
.tv_sec
)
4552 tmp_time
.tv_sec
= DEFAULT_TIME_WIDTH_S
;
4555 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
4556 time_span
.end_time
.tv_sec
;
4557 tmp_time
.tv_nsec
= 0;
4558 tab
->time_window
.time_width
= tmp_time
;
4559 tab
->current_time
.tv_sec
=
4560 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
4561 time_span
.start_time
.tv_sec
;
4562 tab
->current_time
.tv_nsec
=
4563 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
4564 time_span
.start_time
.tv_nsec
;
4567 tab
->attributes
= LTTV_IATTRIBUTE(g_object_new(LTTV_ATTRIBUTE_TYPE
, NULL
));
4568 tab
->interrupted_state
= g_object_new(LTTV_ATTRIBUTE_TYPE
, NULL
);
4570 tab
->vbox
= gtk_vbox_new(FALSE
, 2);
4571 tab
->viewer_container
= gtk_vbox_new(TRUE
, 2);
4572 tab
->scrollbar
= gtk_hscrollbar_new(NULL
);
4573 //tab->multivpaned = gtk_multi_vpaned_new();
4575 gtk_box_pack_start(GTK_BOX(tab
->vbox
),
4576 tab
->viewer_container
,
4578 TRUE
, /* Give the extra space to the child */
4579 0); /* No padding */
4581 /* Create the timebar */
4583 tab
->MTimebar
= gtk_hbox_new(FALSE
, 2);
4584 gtk_widget_show(tab
->MTimebar
);
4585 tab
->tooltips
= gtk_tooltips_new();
4587 tab
->MEventBox1a
= gtk_event_box_new();
4588 gtk_widget_show(tab
->MEventBox1a
);
4589 gtk_tooltips_set_tip(tab
->tooltips
, tab
->MEventBox1a
,
4590 "Paste Start and End Times Here", "");
4591 tab
->MText1a
= gtk_label_new("Time Frame ");
4592 gtk_widget_show(tab
->MText1a
);
4593 gtk_container_add(GTK_CONTAINER(tab
->MEventBox1a
), tab
->MText1a
);
4594 tab
->MEventBox1b
= gtk_event_box_new();
4595 gtk_widget_show(tab
->MEventBox1b
);
4596 gtk_tooltips_set_tip(tab
->tooltips
, tab
->MEventBox1b
,
4597 "Paste Start Time Here", "");
4598 tab
->MText1b
= gtk_label_new("start: ");
4599 gtk_widget_show(tab
->MText1b
);
4600 gtk_container_add(GTK_CONTAINER(tab
->MEventBox1b
), tab
->MText1b
);
4601 tab
->MText2
= gtk_label_new("s");
4602 gtk_widget_show(tab
->MText2
);
4603 tab
->MText3a
= gtk_label_new("ns");
4604 gtk_widget_show(tab
->MText3a
);
4605 tab
->MEventBox3b
= gtk_event_box_new();
4606 gtk_widget_show(tab
->MEventBox3b
);
4607 gtk_tooltips_set_tip(tab
->tooltips
, tab
->MEventBox3b
,
4608 "Paste End Time Here", "");
4609 tab
->MText3b
= gtk_label_new("end:");
4610 gtk_widget_show(tab
->MText3b
);
4611 gtk_container_add(GTK_CONTAINER(tab
->MEventBox3b
), tab
->MText3b
);
4612 tab
->MText4
= gtk_label_new("s");
4613 gtk_widget_show(tab
->MText4
);
4614 tab
->MText5a
= gtk_label_new("ns");
4615 gtk_widget_show(tab
->MText5a
);
4616 tab
->MEventBox5b
= gtk_event_box_new();
4617 gtk_widget_show(tab
->MEventBox5b
);
4618 gtk_tooltips_set_tip(tab
->tooltips
, tab
->MEventBox5b
,
4619 "Paste Current Time Here", "");
4620 tab
->MText5b
= gtk_label_new("Current Time:");
4621 gtk_widget_show(tab
->MText5b
);
4622 gtk_container_add(GTK_CONTAINER(tab
->MEventBox5b
), tab
->MText5b
);
4623 tab
->MText6
= gtk_label_new("s");
4624 gtk_widget_show(tab
->MText6
);
4625 tab
->MText7
= gtk_label_new("ns");
4626 gtk_widget_show(tab
->MText7
);
4628 tab
->MEntry1
= gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4629 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab
->MEntry1
),0);
4630 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab
->MEntry1
),TRUE
);
4631 gtk_widget_show(tab
->MEntry1
);
4632 tab
->MEntry2
= gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4633 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab
->MEntry2
),0);
4634 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab
->MEntry2
),TRUE
);
4635 gtk_widget_show(tab
->MEntry2
);
4636 tab
->MEntry3
= gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4637 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab
->MEntry3
),0);
4638 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab
->MEntry3
),TRUE
);
4639 gtk_widget_show(tab
->MEntry3
);
4640 tab
->MEntry4
= gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4641 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab
->MEntry4
),0);
4642 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab
->MEntry4
),TRUE
);
4643 gtk_widget_show(tab
->MEntry4
);
4644 tab
->MEntry5
= gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4645 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab
->MEntry5
),0);
4646 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab
->MEntry5
),TRUE
);
4647 gtk_widget_show(tab
->MEntry5
);
4648 tab
->MEntry6
= gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4649 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab
->MEntry6
),0);
4650 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab
->MEntry6
),TRUE
);
4651 gtk_widget_show(tab
->MEntry6
);
4654 GtkWidget
*temp_widget
;
4656 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEventBox1a
, FALSE
,
4658 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEventBox1b
, FALSE
,
4660 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEntry1
, FALSE
, FALSE
, 0);
4661 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MText2
, FALSE
, FALSE
, 0);
4662 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEntry2
, FALSE
, FALSE
, 0);
4663 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MText3a
, FALSE
, FALSE
, 0);
4664 temp_widget
= gtk_vseparator_new();
4665 gtk_widget_show(temp_widget
);
4666 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), temp_widget
, FALSE
, FALSE
, 0);
4667 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEventBox3b
, FALSE
,
4669 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEntry3
, FALSE
, FALSE
, 0);
4670 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MText4
, FALSE
, FALSE
, 0);
4671 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEntry4
, FALSE
, FALSE
, 0);
4672 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MText5a
, FALSE
, FALSE
, 0);
4673 temp_widget
= gtk_vseparator_new();
4674 gtk_widget_show(temp_widget
);
4675 gtk_box_pack_end (GTK_BOX (tab
->MTimebar
), tab
->MText7
, FALSE
, FALSE
, 0);
4676 gtk_box_pack_end (GTK_BOX (tab
->MTimebar
), tab
->MEntry6
, FALSE
, FALSE
, 0);
4677 gtk_box_pack_end (GTK_BOX (tab
->MTimebar
), tab
->MText6
, FALSE
, FALSE
, 0);
4678 gtk_box_pack_end (GTK_BOX (tab
->MTimebar
), tab
->MEntry5
, FALSE
, FALSE
, 0);
4679 gtk_box_pack_end (GTK_BOX (tab
->MTimebar
), tab
->MEventBox5b
, FALSE
,
4681 gtk_box_pack_end (GTK_BOX (tab
->MTimebar
), temp_widget
, FALSE
, FALSE
, 0);
4684 //GtkWidget *test = gtk_button_new_with_label("drop");
4685 //gtk_button_set_relief(GTK_BUTTON(test), GTK_RELIEF_NONE);
4686 //gtk_widget_show(test);
4687 //gtk_box_pack_end(GTK_BOX (tab->MTimebar), test, FALSE, FALSE, 0);
4688 //gtk_widget_add_events(tab->MText1, GDK_ALL_EVENTS_MASK);//GDK_BUTTON_PRESS_MASK);
4689 /*GtkWidget *event_box = gtk_event_box_new();
4690 gtk_widget_show(event_box);
4691 gtk_tooltips_set_tip(tooltips, event_box,
4692 "Paste Current Time Here", "");
4693 gtk_box_pack_end(GTK_BOX (tab->MTimebar), event_box, FALSE, FALSE, 0);
4694 GtkWidget *test = gtk_label_new("drop");
4695 gtk_container_add(GTK_CONTAINER(event_box), test);
4696 gtk_widget_show(test);
4697 g_signal_connect (G_OBJECT(event_box),
4698 "button-press-event",
4699 G_CALLBACK (on_MText1_paste),
4703 g_signal_connect (G_OBJECT(tab
->MEventBox1a
),
4704 "button-press-event",
4705 G_CALLBACK (on_MEventBox1a_paste
),
4708 g_signal_connect (G_OBJECT(tab
->MEventBox1b
),
4709 "button-press-event",
4710 G_CALLBACK (on_MEventBox1b_paste
),
4712 g_signal_connect (G_OBJECT(tab
->MEventBox3b
),
4713 "button-press-event",
4714 G_CALLBACK (on_MEventBox3b_paste
),
4716 g_signal_connect (G_OBJECT(tab
->MEventBox5b
),
4717 "button-press-event",
4718 G_CALLBACK (on_MEventBox5b_paste
),
4722 gtk_box_pack_end(GTK_BOX(tab
->vbox
),
4724 FALSE
, /* Do not expand */
4725 FALSE
, /* Fill has no effect here (expand false) */
4726 0); /* No padding */
4728 gtk_box_pack_end(GTK_BOX(tab
->vbox
),
4730 FALSE
, /* Do not expand */
4731 FALSE
, /* Fill has no effect here (expand false) */
4732 0); /* No padding */
4734 g_object_set_data(G_OBJECT(tab
->viewer_container
), "focused_viewer", NULL
);
4740 // Display a label with a X
4741 GtkWidget *w_hbox = gtk_hbox_new(FALSE, 4);
4742 GtkWidget *w_label = gtk_label_new (label);
4743 GtkWidget *pixmap = create_pixmap(GTK_WIDGET(notebook), "close.png");
4744 GtkWidget *w_button = gtk_button_new ();
4745 gtk_container_add(GTK_CONTAINER(w_button), pixmap);
4746 //GtkWidget *w_button = gtk_button_new_with_label("x");
4748 gtk_button_set_relief(GTK_BUTTON(w_button), GTK_RELIEF_NONE);
4750 gtk_box_pack_start(GTK_BOX(w_hbox), w_label, TRUE, TRUE, 0);
4751 gtk_box_pack_end(GTK_BOX(w_hbox), w_button, FALSE,
4754 g_signal_connect_swapped (w_button, "clicked",
4755 G_CALLBACK (on_close_tab_X_clicked),
4758 gtk_widget_set_state(w_button, GTK_STATE_ACTIVE);
4760 gtk_widget_show (w_label);
4761 gtk_widget_show (pixmap);
4762 gtk_widget_show (w_button);
4763 gtk_widget_show (w_hbox);
4765 tab->label = w_hbox;
4769 tab
->label
= gtk_label_new (label
);
4771 gtk_widget_show(tab
->label
);
4772 gtk_widget_show(tab
->scrollbar
);
4773 gtk_widget_show(tab
->viewer_container
);
4774 gtk_widget_show(tab
->vbox
);
4775 //gtk_widget_show(tab->multivpaned);
4778 /* Start with empty events requests list */
4779 tab
->events_requests
= NULL
;
4780 tab
->events_request_pending
= FALSE
;
4782 g_object_set_data_full(
4783 G_OBJECT(tab
->vbox
),
4786 (GDestroyNotify
)tab_destructor
);
4788 g_signal_connect(G_OBJECT(tab
->scrollbar
), "value-changed",
4789 G_CALLBACK(scroll_value_changed_cb
), tab
);
4791 g_signal_connect ((gpointer
) tab
->MEntry1
, "value-changed",
4792 G_CALLBACK (on_MEntry1_value_changed
),
4794 g_signal_connect ((gpointer
) tab
->MEntry2
, "value-changed",
4795 G_CALLBACK (on_MEntry2_value_changed
),
4797 g_signal_connect ((gpointer
) tab
->MEntry3
, "value-changed",
4798 G_CALLBACK (on_MEntry3_value_changed
),
4800 g_signal_connect ((gpointer
) tab
->MEntry4
, "value-changed",
4801 G_CALLBACK (on_MEntry4_value_changed
),
4803 g_signal_connect ((gpointer
) tab
->MEntry5
, "value-changed",
4804 G_CALLBACK (on_MEntry5_value_changed
),
4806 g_signal_connect ((gpointer
) tab
->MEntry6
, "value-changed",
4807 G_CALLBACK (on_MEntry6_value_changed
),
4810 //g_signal_connect(G_OBJECT(tab->scrollbar), "changed",
4811 // G_CALLBACK(scroll_value_changed_cb), tab);
4814 //insert tab into notebook
4815 gtk_notebook_append_page(notebook
,
4818 list
= gtk_container_get_children(GTK_CONTAINER(notebook
));
4819 gtk_notebook_set_current_page(notebook
,g_list_length(list
)-1);
4820 // always show : not if(g_list_length(list)>1)
4821 gtk_notebook_set_show_tabs(notebook
, TRUE
);
4827 * execute_events_requests
4829 * Idle function that executes the pending requests for a tab.
4831 * @return return value : TRUE : keep the idle function, FALSE : remove it.
4833 gboolean
execute_events_requests(Tab
*tab
)
4835 return ( lttvwindow_process_pending_requests(tab
) );