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
->hooks
!= NULL
)
883 g_array_free(events_request
->hooks
, TRUE
);
884 if(events_request
->before_chunk_traceset
!= NULL
)
885 lttv_hooks_destroy(events_request
->before_chunk_traceset
);
886 if(events_request
->before_chunk_trace
!= NULL
)
887 lttv_hooks_destroy(events_request
->before_chunk_trace
);
888 if(events_request
->before_chunk_tracefile
!= NULL
)
889 lttv_hooks_destroy(events_request
->before_chunk_tracefile
);
890 if(events_request
->event
!= NULL
)
891 lttv_hooks_destroy(events_request
->event
);
892 if(events_request
->event_by_id
!= NULL
)
893 lttv_hooks_by_id_destroy(events_request
->event_by_id
);
894 if(events_request
->after_chunk_tracefile
!= NULL
)
895 lttv_hooks_destroy(events_request
->after_chunk_tracefile
);
896 if(events_request
->after_chunk_trace
!= NULL
)
897 lttv_hooks_destroy(events_request
->after_chunk_trace
);
898 if(events_request
->after_chunk_traceset
!= NULL
)
899 lttv_hooks_destroy(events_request
->after_chunk_traceset
);
900 if(events_request
->before_request
!= NULL
)
901 lttv_hooks_destroy(events_request
->before_request
);
902 if(events_request
->after_request
!= NULL
)
903 lttv_hooks_destroy(events_request
->after_request
);
905 g_free(events_request
);
910 /* lttvwindow_process_pending_requests
912 * This internal function gets called by g_idle, taking care of the pending
913 * requests. It is responsible for concatenation of time intervals and position
914 * requests. It does it with the following algorithm organizing process traceset
915 * calls. Here is the detailed description of the way it works :
917 * - Events Requests Servicing Algorithm
919 * Data structures necessary :
921 * List of requests added to context : list_in
922 * List of requests not added to context : list_out
927 * list_out : many events requests
929 * FIXME : insert rest of algorithm here
933 #define list_out tab->events_requests
935 gboolean
lttvwindow_process_pending_requests(Tab
*tab
)
937 unsigned max_nb_events
;
941 LttvTracesetContext
*tsc
;
942 LttvTracefileContext
*tfc
;
943 GSList
*list_in
= NULL
;
947 LttvTracesetContextPosition
*end_position
;
950 g_critical("Foreground processing : tab does not exist. Processing removed.");
954 /* There is no events requests pending : we should never have been called! */
955 g_assert(g_slist_length(list_out
) != 0);
957 tsc
= LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
959 //set the cursor to be X shape, indicating that the computer is busy in doing its job
961 new = gdk_cursor_new(GDK_X_CURSOR
);
962 widget
= lookup_widget(tab
->mw
->mwindow
, "MToolbar1");
963 win
= gtk_widget_get_parent_window(widget
);
964 gdk_window_set_cursor(win
, new);
965 gdk_cursor_unref(new);
966 gdk_window_stick(win
);
967 gdk_window_unstick(win
);
970 g_debug("SIZE events req len : %d", g_slist_length(list_out
));
972 /* Preliminary check for no trace in traceset */
973 /* Unregister the routine if empty, empty list_out too */
974 if(lttv_traceset_number(tsc
->ts
) == 0) {
976 /* - For each req in list_out */
977 GSList
*iter
= list_out
;
979 while(iter
!= NULL
) {
981 gboolean remove
= FALSE
;
982 gboolean free_data
= FALSE
;
983 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
985 /* - Call end request for req */
986 if(events_request
->servicing
== TRUE
)
987 lttv_hooks_call(events_request
->after_request
, (gpointer
)tsc
);
989 /* - remove req from list_out */
990 /* Destroy the request */
997 GSList
*remove_iter
= iter
;
999 iter
= g_slist_next(iter
);
1000 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
1001 list_out
= g_slist_remove_link(list_out
, remove_iter
);
1002 } else { // not remove
1003 iter
= g_slist_next(iter
);
1008 /* 0.1 Lock Traces */
1013 iter_trace
<lttv_traceset_number(tsc
->ts
);
1015 LttvTrace
*trace_v
= lttv_traceset_get(tsc
->ts
, iter_trace
);
1017 if(lttvwindowtraces_lock(trace_v
) != 0) {
1018 g_critical("Foreground processing : Unable to get trace lock");
1019 return TRUE
; /* Cannot get lock, try later */
1024 /* 0.2 Seek tracefiles positions to context position */
1025 lttv_process_traceset_synchronize_tracefiles(tsc
);
1028 /* Events processing algorithm implementation */
1029 /* Warning : the gtk_events_pending takes a LOT of cpu time. So what we do
1030 * instead is to leave the control to GTK and take it back.
1032 /* A. Servicing loop */
1033 //while( (g_slist_length(list_in) != 0 || g_slist_length(list_out) != 0)) {
1034 if((g_slist_length(list_in
) != 0 || g_slist_length(list_out
) != 0)) {
1036 /* 1. If list_in is empty (need a seek) */
1037 if( g_slist_length(list_in
) == 0 ) {
1039 /* list in is empty, need a seek */
1041 /* 1.1 Add requests to list_in */
1042 GSList
*ltime
= NULL
;
1043 GSList
*lpos
= NULL
;
1044 GSList
*iter
= NULL
;
1046 /* 1.1.1 Find all time requests with the lowest start time in list_out
1049 if(g_slist_length(list_out
) > 0)
1050 ltime
= g_slist_append(ltime
, g_slist_nth_data(list_out
, 0));
1051 for(iter
=g_slist_nth(list_out
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
1052 /* Find all time requests with the lowest start time in list_out */
1053 guint index_ltime
= g_array_index(ltime
, guint
, 0);
1054 EventsRequest
*event_request_ltime
= (EventsRequest
*)g_slist_nth_data(ltime
, 0);
1055 EventsRequest
*event_request_list_out
= (EventsRequest
*)iter
->data
;
1058 comp
= ltt_time_compare(event_request_ltime
->start_time
,
1059 event_request_list_out
->start_time
);
1061 ltime
= g_slist_append(ltime
, event_request_list_out
);
1063 /* Remove all elements from ltime, and add current */
1064 while(ltime
!= NULL
)
1065 ltime
= g_slist_delete_link(ltime
, g_slist_nth(ltime
, 0));
1066 ltime
= g_slist_append(ltime
, event_request_list_out
);
1070 /* 1.1.2 Find all position requests with the lowest position in list_out
1073 if(g_slist_length(list_out
) > 0)
1074 lpos
= g_slist_append(lpos
, g_slist_nth_data(list_out
, 0));
1075 for(iter
=g_slist_nth(list_out
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
1076 /* Find all position requests with the lowest position in list_out */
1077 EventsRequest
*event_request_lpos
= (EventsRequest
*)g_slist_nth_data(lpos
, 0);
1078 EventsRequest
*event_request_list_out
= (EventsRequest
*)iter
->data
;
1081 if(event_request_lpos
->start_position
!= NULL
1082 && event_request_list_out
->start_position
!= NULL
)
1084 comp
= lttv_traceset_context_pos_pos_compare
1085 (event_request_lpos
->start_position
,
1086 event_request_list_out
->start_position
);
1091 lpos
= g_slist_append(lpos
, event_request_list_out
);
1093 /* Remove all elements from lpos, and add current */
1095 lpos
= g_slist_delete_link(lpos
, g_slist_nth(lpos
, 0));
1096 lpos
= g_slist_append(lpos
, event_request_list_out
);
1101 EventsRequest
*event_request_lpos
= (EventsRequest
*)g_slist_nth_data(lpos
, 0);
1102 EventsRequest
*event_request_ltime
= (EventsRequest
*)g_slist_nth_data(ltime
, 0);
1103 LttTime lpos_start_time
;
1105 if(event_request_lpos
!= NULL
1106 && event_request_lpos
->start_position
!= NULL
) {
1107 lpos_start_time
= lttv_traceset_context_position_get_time(
1108 event_request_lpos
->start_position
);
1111 /* 1.1.3 If lpos.start time < ltime */
1112 if(event_request_lpos
!= NULL
1113 && event_request_lpos
->start_position
!= NULL
1114 && ltt_time_compare(lpos_start_time
,
1115 event_request_ltime
->start_time
)<0) {
1116 /* Add lpos to list_in, remove them from list_out */
1117 for(iter
=lpos
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
1118 /* Add to list_in */
1119 EventsRequest
*event_request_lpos
=
1120 (EventsRequest
*)iter
->data
;
1122 list_in
= g_slist_append(list_in
, event_request_lpos
);
1123 /* Remove from list_out */
1124 list_out
= g_slist_remove(list_out
, event_request_lpos
);
1127 /* 1.1.4 (lpos.start time >= ltime) */
1128 /* Add ltime to list_in, remove them from list_out */
1130 for(iter
=ltime
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
1131 /* Add to list_in */
1132 EventsRequest
*event_request_ltime
=
1133 (EventsRequest
*)iter
->data
;
1135 list_in
= g_slist_append(list_in
, event_request_ltime
);
1136 /* Remove from list_out */
1137 list_out
= g_slist_remove(list_out
, event_request_ltime
);
1142 g_slist_free(ltime
);
1147 tfc
= lttv_traceset_context_get_current_tfc(tsc
);
1148 g_assert(g_slist_length(list_in
)>0);
1149 EventsRequest
*events_request
= g_slist_nth_data(list_in
, 0);
1152 /* 1.2.1 If first request in list_in is a time request */
1153 if(events_request
->start_position
== NULL
) {
1154 /* - If first req in list_in start time != current time */
1155 if(tfc
== NULL
|| ltt_time_compare(events_request
->start_time
,
1156 tfc
->timestamp
) != 0)
1157 /* - Seek to that time */
1158 g_debug("SEEK TIME : %lu, %lu", events_request
->start_time
.tv_sec
,
1159 events_request
->start_time
.tv_nsec
);
1160 //lttv_process_traceset_seek_time(tsc, events_request->start_time);
1161 lttv_state_traceset_seek_time_closest(LTTV_TRACESET_STATE(tsc
),
1162 events_request
->start_time
);
1164 /* Process the traceset with only state hooks */
1166 lttv_process_traceset_middle(tsc
,
1167 events_request
->start_time
,
1173 /* Else, the first request in list_in is a position request */
1174 /* If first req in list_in pos != current pos */
1175 g_assert(events_request
->start_position
!= NULL
);
1176 g_debug("SEEK POS time : %lu, %lu",
1177 lttv_traceset_context_position_get_time(
1178 events_request
->start_position
).tv_sec
,
1179 lttv_traceset_context_position_get_time(
1180 events_request
->start_position
).tv_nsec
);
1182 g_debug("SEEK POS context time : %lu, %lu",
1183 lttv_traceset_context_get_current_tfc(tsc
)->timestamp
.tv_sec
,
1184 lttv_traceset_context_get_current_tfc(tsc
)->timestamp
.tv_nsec
);
1185 g_assert(events_request
->start_position
!= NULL
);
1186 if(lttv_traceset_context_ctx_pos_compare(tsc
,
1187 events_request
->start_position
) != 0) {
1188 /* 1.2.2.1 Seek to that position */
1189 g_debug("SEEK POSITION");
1190 //lttv_process_traceset_seek_position(tsc, events_request->start_position);
1191 pos_time
= lttv_traceset_context_position_get_time(
1192 events_request
->start_position
);
1194 lttv_state_traceset_seek_time_closest(LTTV_TRACESET_STATE(tsc
),
1197 /* Process the traceset with only state hooks */
1199 lttv_process_traceset_middle(tsc
,
1202 events_request
->start_position
);
1203 g_assert(lttv_traceset_context_ctx_pos_compare(tsc
,
1204 events_request
->start_position
) == 0);
1211 /* 1.3 Add hooks and call before request for all list_in members */
1213 GSList
*iter
= NULL
;
1215 for(iter
=list_in
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
1216 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1217 /* 1.3.1 If !servicing */
1218 if(events_request
->servicing
== FALSE
) {
1219 /* - begin request hooks called
1220 * - servicing = TRUE
1222 lttv_hooks_call(events_request
->before_request
, (gpointer
)tsc
);
1223 events_request
->servicing
= TRUE
;
1225 /* 1.3.2 call before chunk
1226 * 1.3.3 events hooks added
1228 if(events_request
->trace
== -1)
1229 lttv_process_traceset_begin(tsc
,
1230 events_request
->before_chunk_traceset
,
1231 events_request
->before_chunk_trace
,
1232 events_request
->before_chunk_tracefile
,
1233 events_request
->event
,
1234 events_request
->event_by_id
);
1236 guint nb_trace
= lttv_traceset_number(tsc
->ts
);
1237 g_assert(events_request
->trace
< nb_trace
&&
1238 events_request
->trace
> -1);
1239 LttvTraceContext
*tc
= tsc
->traces
[events_request
->trace
];
1241 lttv_hooks_call(events_request
->before_chunk_traceset
, tsc
);
1243 lttv_trace_context_add_hooks(tc
,
1244 events_request
->before_chunk_trace
,
1245 events_request
->before_chunk_tracefile
,
1246 events_request
->event
,
1247 events_request
->event_by_id
);
1252 /* 2. Else, list_in is not empty, we continue a read */
1255 /* 2.0 For each req of list_in */
1256 GSList
*iter
= list_in
;
1258 while(iter
!= NULL
) {
1260 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1262 /* - Call before chunk
1263 * - events hooks added
1265 if(events_request
->trace
== -1)
1266 lttv_process_traceset_begin(tsc
,
1267 events_request
->before_chunk_traceset
,
1268 events_request
->before_chunk_trace
,
1269 events_request
->before_chunk_tracefile
,
1270 events_request
->event
,
1271 events_request
->event_by_id
);
1273 guint nb_trace
= lttv_traceset_number(tsc
->ts
);
1274 g_assert(events_request
->trace
< nb_trace
&&
1275 events_request
->trace
> -1);
1276 LttvTraceContext
*tc
= tsc
->traces
[events_request
->trace
];
1278 lttv_hooks_call(events_request
->before_chunk_traceset
, tsc
);
1280 lttv_trace_context_add_hooks(tc
,
1281 events_request
->before_chunk_trace
,
1282 events_request
->before_chunk_tracefile
,
1283 events_request
->event
,
1284 events_request
->event_by_id
);
1287 iter
= g_slist_next(iter
);
1292 tfc
= lttv_traceset_context_get_current_tfc(tsc
);
1294 /* 2.1 For each req of list_out */
1295 GSList
*iter
= list_out
;
1297 while(iter
!= NULL
) {
1299 gboolean remove
= FALSE
;
1300 gboolean free_data
= FALSE
;
1301 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1303 /* if req.start time == current context time
1304 * or req.start position == current position*/
1305 if( ltt_time_compare(events_request
->start_time
,
1306 tfc
->timestamp
) == 0
1308 (events_request
->start_position
!= NULL
1310 lttv_traceset_context_ctx_pos_compare(tsc
,
1311 events_request
->start_position
) == 0)
1313 /* - Add to list_in, remove from list_out */
1314 list_in
= g_slist_append(list_in
, events_request
);
1318 /* - If !servicing */
1319 if(events_request
->servicing
== FALSE
) {
1320 /* - begin request hooks called
1321 * - servicing = TRUE
1323 lttv_hooks_call(events_request
->before_request
, (gpointer
)tsc
);
1324 events_request
->servicing
= TRUE
;
1326 /* call before chunk
1327 * events hooks added
1329 if(events_request
->trace
== -1)
1330 lttv_process_traceset_begin(tsc
,
1331 events_request
->before_chunk_traceset
,
1332 events_request
->before_chunk_trace
,
1333 events_request
->before_chunk_tracefile
,
1334 events_request
->event
,
1335 events_request
->event_by_id
);
1337 guint nb_trace
= lttv_traceset_number(tsc
->ts
);
1338 g_assert(events_request
->trace
< nb_trace
&&
1339 events_request
->trace
> -1);
1340 LttvTraceContext
*tc
= tsc
->traces
[events_request
->trace
];
1342 lttv_hooks_call(events_request
->before_chunk_traceset
, tsc
);
1344 lttv_trace_context_add_hooks(tc
,
1345 events_request
->before_chunk_trace
,
1346 events_request
->before_chunk_tracefile
,
1347 events_request
->event
,
1348 events_request
->event_by_id
);
1357 GSList
*remove_iter
= iter
;
1359 iter
= g_slist_next(iter
);
1360 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
1361 list_out
= g_slist_remove_link(list_out
, remove_iter
);
1362 } else { // not remove
1363 iter
= g_slist_next(iter
);
1369 /* 3. Find end criterions */
1374 /* 3.1.1 Find lowest end time in list_in */
1375 g_assert(g_slist_length(list_in
)>0);
1376 end_time
= ((EventsRequest
*)g_slist_nth_data(list_in
,0))->end_time
;
1378 for(iter
=g_slist_nth(list_in
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
1379 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1381 if(ltt_time_compare(events_request
->end_time
,
1383 end_time
= events_request
->end_time
;
1386 /* 3.1.2 Find lowest start time in list_out */
1387 for(iter
=list_out
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
1388 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1390 if(ltt_time_compare(events_request
->start_time
,
1392 end_time
= events_request
->start_time
;
1397 /* 3.2 Number of events */
1399 /* 3.2.1 Find lowest number of events in list_in */
1402 end_nb_events
= ((EventsRequest
*)g_slist_nth_data(list_in
,0))->num_events
;
1404 for(iter
=g_slist_nth(list_in
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
1405 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1407 if(events_request
->num_events
< end_nb_events
)
1408 end_nb_events
= events_request
->num_events
;
1411 /* 3.2.2 Use min(CHUNK_NUM_EVENTS, min num events in list_in) as
1414 end_nb_events
= MIN(CHUNK_NUM_EVENTS
, end_nb_events
);
1418 /* 3.3 End position */
1420 /* 3.3.1 Find lowest end position in list_in */
1423 end_position
=((EventsRequest
*)g_slist_nth_data(list_in
,0))->end_position
;
1425 for(iter
=g_slist_nth(list_in
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
1426 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1428 if(events_request
->end_position
!= NULL
&& end_position
!= NULL
&&
1429 lttv_traceset_context_pos_pos_compare(events_request
->end_position
,
1431 end_position
= events_request
->end_position
;
1436 /* 3.3.2 Find lowest start position in list_out */
1439 for(iter
=list_out
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
1440 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1442 if(events_request
->end_position
!= NULL
&& end_position
!= NULL
&&
1443 lttv_traceset_context_pos_pos_compare(events_request
->end_position
,
1445 end_position
= events_request
->end_position
;
1450 /* 4. Call process traceset middle */
1451 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
);
1452 count
= lttv_process_traceset_middle(tsc
, end_time
, end_nb_events
, end_position
);
1454 tfc
= lttv_traceset_context_get_current_tfc(tsc
);
1456 g_debug("Context time after middle : %lu, %lu", tfc
->timestamp
.tv_sec
,
1457 tfc
->timestamp
.tv_nsec
);
1459 g_debug("End of trace reached after middle.");
1463 /* 5. After process traceset middle */
1464 tfc
= lttv_traceset_context_get_current_tfc(tsc
);
1466 /* - if current context time > traceset.end time */
1467 if(tfc
== NULL
|| ltt_time_compare(tfc
->timestamp
,
1468 tsc
->time_span
.end_time
) > 0) {
1469 /* - For each req in list_in */
1470 GSList
*iter
= list_in
;
1472 while(iter
!= NULL
) {
1474 gboolean remove
= FALSE
;
1475 gboolean free_data
= FALSE
;
1476 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1478 /* - Remove events hooks for req
1479 * - Call end chunk for req
1482 if(events_request
->trace
== -1)
1483 lttv_process_traceset_end(tsc
,
1484 events_request
->after_chunk_traceset
,
1485 events_request
->after_chunk_trace
,
1486 events_request
->after_chunk_tracefile
,
1487 events_request
->event
,
1488 events_request
->event_by_id
);
1491 guint nb_trace
= lttv_traceset_number(tsc
->ts
);
1492 g_assert(events_request
->trace
< nb_trace
&&
1493 events_request
->trace
> -1);
1494 LttvTraceContext
*tc
= tsc
->traces
[events_request
->trace
];
1496 lttv_trace_context_remove_hooks(tc
,
1497 events_request
->after_chunk_trace
,
1498 events_request
->after_chunk_tracefile
,
1499 events_request
->event
,
1500 events_request
->event_by_id
);
1501 lttv_hooks_call(events_request
->after_chunk_traceset
, tsc
);
1506 /* - Call end request for req */
1507 lttv_hooks_call(events_request
->after_request
, (gpointer
)tsc
);
1509 /* - remove req from list_in */
1510 /* Destroy the request */
1517 GSList
*remove_iter
= iter
;
1519 iter
= g_slist_next(iter
);
1520 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
1521 list_in
= g_slist_remove_link(list_in
, remove_iter
);
1522 } else { // not remove
1523 iter
= g_slist_next(iter
);
1528 /* 5.1 For each req in list_in */
1529 GSList
*iter
= list_in
;
1531 while(iter
!= NULL
) {
1533 gboolean remove
= FALSE
;
1534 gboolean free_data
= FALSE
;
1535 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1537 /* - Remove events hooks for req
1538 * - Call end chunk for req
1540 if(events_request
->trace
== -1)
1541 lttv_process_traceset_end(tsc
,
1542 events_request
->after_chunk_traceset
,
1543 events_request
->after_chunk_trace
,
1544 events_request
->after_chunk_tracefile
,
1545 events_request
->event
,
1546 events_request
->event_by_id
);
1549 guint nb_trace
= lttv_traceset_number(tsc
->ts
);
1550 g_assert(events_request
->trace
< nb_trace
&&
1551 events_request
->trace
> -1);
1552 LttvTraceContext
*tc
= tsc
->traces
[events_request
->trace
];
1554 lttv_trace_context_remove_hooks(tc
,
1555 events_request
->after_chunk_trace
,
1556 events_request
->after_chunk_tracefile
,
1557 events_request
->event
,
1558 events_request
->event_by_id
);
1560 lttv_hooks_call(events_request
->after_chunk_traceset
, tsc
);
1563 /* - req.num -= count */
1564 g_assert(events_request
->num_events
>= count
);
1565 events_request
->num_events
-= count
;
1567 g_assert(tfc
!= NULL
);
1568 /* - if req.num == 0
1570 * current context time >= req.end time
1572 * req.end pos == current pos
1574 * req.stop_flag == TRUE
1576 if( events_request
->num_events
== 0
1578 events_request
->stop_flag
== TRUE
1580 ltt_time_compare(tfc
->timestamp
,
1581 events_request
->end_time
) >= 0
1583 (events_request
->end_position
!= NULL
1585 lttv_traceset_context_ctx_pos_compare(tsc
,
1586 events_request
->end_position
) == 0)
1589 g_assert(events_request
->servicing
== TRUE
);
1590 /* - Call end request for req
1591 * - remove req from list_in */
1592 lttv_hooks_call(events_request
->after_request
, (gpointer
)tsc
);
1593 /* - remove req from list_in */
1594 /* Destroy the request */
1602 GSList
*remove_iter
= iter
;
1604 iter
= g_slist_next(iter
);
1605 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
1606 list_in
= g_slist_remove_link(list_in
, remove_iter
);
1607 } else { // not remove
1608 iter
= g_slist_next(iter
);
1614 /* End of removed servicing loop : leave control to GTK instead. */
1615 // if(gtk_events_pending()) break;
1618 /* B. When interrupted between chunks */
1621 GSList
*iter
= list_in
;
1623 /* 1. for each request in list_in */
1624 while(iter
!= NULL
) {
1626 gboolean remove
= FALSE
;
1627 gboolean free_data
= FALSE
;
1628 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1630 /* 1.1. Use current postition as start position */
1631 if(events_request
->start_position
!= NULL
)
1632 lttv_traceset_context_position_destroy(events_request
->start_position
);
1633 events_request
->start_position
= lttv_traceset_context_position_new();
1634 lttv_traceset_context_position_save(tsc
, events_request
->start_position
);
1636 /* 1.2. Remove start time */
1637 events_request
->start_time
= ltt_time_infinite
;
1639 /* 1.3. Move from list_in to list_out */
1642 list_out
= g_slist_append(list_out
, events_request
);
1647 GSList
*remove_iter
= iter
;
1649 iter
= g_slist_next(iter
);
1650 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
1651 list_in
= g_slist_remove_link(list_in
, remove_iter
);
1652 } else { // not remove
1653 iter
= g_slist_next(iter
);
1660 /* C Unlock Traces */
1662 //lttv_process_traceset_get_sync_data(tsc);
1667 iter_trace
<lttv_traceset_number(tsc
->ts
);
1669 LttvTrace
*trace_v
= lttv_traceset_get(tsc
->ts
, iter_trace
);
1671 lttvwindowtraces_unlock(trace_v
);
1676 //set the cursor back to normal
1677 gdk_window_set_cursor(win
, NULL
);
1680 g_assert(g_slist_length(list_in
) == 0);
1682 if( g_slist_length(list_out
) == 0 ) {
1683 /* Put tab's request pending flag back to normal */
1684 tab
->events_request_pending
= FALSE
;
1685 g_debug("remove the idle fct");
1686 return FALSE
; /* Remove the idle function */
1688 g_debug("leave the idle fct");
1689 return TRUE
; /* Leave the idle function */
1691 /* We do not use simili-round-robin, it may require to read 1 meg buffers
1692 * again and again if many tracesets use the same tracefiles. */
1693 /* Hack for round-robin idle functions */
1694 /* It will put the idle function at the end of the pool */
1695 /*g_idle_add_full((G_PRIORITY_HIGH_IDLE + 21),
1696 (GSourceFunc)execute_events_requests,
1706 /* add_trace_into_traceset_selector, each instance of a viewer has an associated
1707 * selector (filter), when a trace is added into traceset, the selector should
1708 * reflect the change. The function is used to update the selector
1711 void add_trace_into_traceset_selector(GtkWidget
* paned
, LttTrace
* t
)
1713 int j
, k
, m
, nb_tracefile
, nb_control
, nb_per_cpu
, nb_facility
, nb_event
;
1714 LttvTracesetSelector
* s
;
1715 LttvTraceSelector
* trace
;
1716 LttvTracefileSelector
* tracefile
;
1717 LttvEventtypeSelector
* eventtype
;
1723 w
= gtk_multivpaned_get_first_widget(GTK_MULTIVPANED(paned
));
1725 s
= g_object_get_data(G_OBJECT(w
), "Traceset_Selector");
1728 trace
= lttv_trace_selector_new(t
);
1729 lttv_traceset_selector_trace_add(s
, trace
);
1731 nb_facility
= ltt_trace_facility_number(t
);
1732 for(k
=0;k
<nb_facility
;k
++){
1733 fac
= ltt_trace_facility_get(t
,k
);
1734 nb_event
= (int) ltt_facility_eventtype_number(fac
);
1735 for(m
=0;m
<nb_event
;m
++){
1736 et
= ltt_facility_eventtype_get(fac
,m
);
1737 eventtype
= lttv_eventtype_selector_new(et
);
1738 lttv_trace_selector_eventtype_add(trace
, eventtype
);
1742 nb_control
= ltt_trace_control_tracefile_number(t
);
1743 nb_per_cpu
= ltt_trace_per_cpu_tracefile_number(t
);
1744 nb_tracefile
= nb_control
+ nb_per_cpu
;
1746 for(j
= 0 ; j
< nb_tracefile
; j
++) {
1748 tf
= ltt_trace_control_tracefile_get(t
, j
);
1750 tf
= ltt_trace_per_cpu_tracefile_get(t
, j
- nb_control
);
1751 tracefile
= lttv_tracefile_selector_new(tf
);
1752 lttv_trace_selector_tracefile_add(trace
, tracefile
);
1753 lttv_eventtype_selector_copy(trace
, tracefile
);
1755 }else g_warning("Module does not support filtering\n");
1757 w
= gtk_multivpaned_get_next_widget(GTK_MULTIVPANED(paned
));
1762 static void lttvwindow_add_trace(Tab
*tab
, LttvTrace
*trace_v
)
1764 LttvTraceset
*traceset
= tab
->traceset_info
->traceset
;
1766 guint num_traces
= lttv_traceset_number(traceset
);
1768 //Verify if trace is already present.
1769 for(i
=0; i
<num_traces
; i
++)
1771 LttvTrace
* trace
= lttv_traceset_get(traceset
, i
);
1772 if(trace
== trace_v
)
1776 //Keep a reference to the traces so they are not freed.
1777 for(i
=0; i
<lttv_traceset_number(traceset
); i
++)
1779 LttvTrace
* trace
= lttv_traceset_get(traceset
, i
);
1780 lttv_trace_ref(trace
);
1783 //remove state update hooks
1784 lttv_state_remove_event_hooks(
1785 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1787 lttv_context_fini(LTTV_TRACESET_CONTEXT(
1788 tab
->traceset_info
->traceset_context
));
1789 g_object_unref(tab
->traceset_info
->traceset_context
);
1791 lttv_traceset_add(traceset
, trace_v
);
1792 lttv_trace_ref(trace_v
); /* local ref */
1794 /* Create new context */
1795 tab
->traceset_info
->traceset_context
=
1796 g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
1798 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->
1803 //add state update hooks
1804 lttv_state_add_event_hooks(
1805 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1806 //Remove local reference to the traces.
1807 for(i
=0; i
<lttv_traceset_number(traceset
); i
++)
1809 LttvTrace
* trace
= lttv_traceset_get(traceset
, i
);
1810 lttv_trace_unref(trace
);
1814 //add_trace_into_traceset_selector(GTK_MULTIVPANED(tab->multivpaned), lttv_trace(trace_v));
1817 /* add_trace adds a trace into the current traceset. It first displays a
1818 * directory selection dialogue to let user choose a trace, then recreates
1819 * tracset_context, and redraws all the viewer of the current tab
1822 void add_trace(GtkWidget
* widget
, gpointer user_data
)
1825 LttvTrace
* trace_v
;
1826 LttvTraceset
* traceset
;
1828 char abs_path
[PATH_MAX
];
1831 MainWindow
* mw_data
= get_window_data_struct(widget
);
1832 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
1834 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
1835 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
1839 tab
= create_new_tab(widget
, NULL
);
1841 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
1844 GtkDirSelection
* file_selector
= (GtkDirSelection
*)gtk_dir_selection_new("Select a trace");
1845 gtk_dir_selection_hide_fileop_buttons(file_selector
);
1847 if(remember_trace_dir
[0] != '\0')
1848 gtk_dir_selection_set_filename(file_selector
, remember_trace_dir
);
1850 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
1852 case GTK_RESPONSE_ACCEPT
:
1853 case GTK_RESPONSE_OK
:
1854 dir
= gtk_dir_selection_get_dir (file_selector
);
1855 strncpy(remember_trace_dir
, dir
, PATH_MAX
);
1856 if(!dir
|| strlen(dir
) == 0){
1857 gtk_widget_destroy((GtkWidget
*)file_selector
);
1860 get_absolute_pathname(dir
, abs_path
);
1861 trace_v
= lttvwindowtraces_get_trace_by_name(abs_path
);
1862 if(trace_v
== NULL
) {
1863 trace
= ltt_trace_open(abs_path
);
1865 g_warning("cannot open trace %s", abs_path
);
1867 trace_v
= lttv_trace_new(trace
);
1868 lttvwindowtraces_add_trace(trace_v
);
1869 lttvwindow_add_trace(tab
, trace_v
);
1872 lttvwindow_add_trace(tab
, trace_v
);
1875 gtk_widget_destroy((GtkWidget
*)file_selector
);
1877 //update current tab
1878 //update_traceset(mw_data);
1880 /* Call the updatetraceset hooks */
1882 traceset
= tab
->traceset_info
->traceset
;
1883 SetTraceset(tab
, traceset
);
1884 // in expose now call_pending_read_hooks(mw_data);
1886 //lttvwindow_report_current_time(mw_data,&(tab->current_time));
1888 case GTK_RESPONSE_REJECT
:
1889 case GTK_RESPONSE_CANCEL
:
1891 gtk_widget_destroy((GtkWidget
*)file_selector
);
1897 /* remove_trace_into_traceset_selector, each instance of a viewer has an associated
1898 * selector (filter), when a trace is remove from traceset, the selector should
1899 * reflect the change. The function is used to update the selector
1902 void remove_trace_from_traceset_selector(GtkWidget
* paned
, unsigned i
)
1904 LttvTracesetSelector
* s
;
1905 LttvTraceSelector
* t
;
1908 w
= gtk_multivpaned_get_first_widget(GTK_MULTIVPANED(paned
));
1910 s
= g_object_get_data(G_OBJECT(w
), "Traceset_Selector");
1912 t
= lttv_traceset_selector_trace_get(s
,i
);
1913 lttv_traceset_selector_trace_remove(s
, i
);
1914 lttv_trace_selector_destroy(t
);
1915 }g_warning("Module dose not support filtering\n");
1916 w
= gtk_multivpaned_get_next_widget(GTK_MULTIVPANED(paned
));
1921 /* remove_trace removes a trace from the current traceset if all viewers in
1922 * the current tab are not interested in the trace. It first displays a
1923 * dialogue, which shows all traces in the current traceset, to let user choose
1924 * a trace, then it checks if all viewers unselect the trace, if it is true,
1925 * it will remove the trace, recreate the traceset_contex,
1926 * and redraws all the viewer of the current tab. If there is on trace in the
1927 * current traceset, it will delete all viewers of the current tab
1930 // MD : no filter version.
1931 void remove_trace(GtkWidget
*widget
, gpointer user_data
)
1934 LttvTrace
* trace_v
;
1935 LttvTraceset
* traceset
;
1936 gint i
, j
, nb_trace
, index
=-1;
1937 char ** name
, *remove_trace_name
;
1938 MainWindow
* mw_data
= get_window_data_struct(widget
);
1939 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
1941 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
1942 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
1948 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
1951 nb_trace
=lttv_traceset_number(tab
->traceset_info
->traceset
);
1952 name
= g_new(char*,nb_trace
);
1953 for(i
= 0; i
< nb_trace
; i
++){
1954 trace_v
= lttv_traceset_get(tab
->traceset_info
->traceset
, i
);
1955 trace
= lttv_trace(trace_v
);
1956 name
[i
] = ltt_trace_name(trace
);
1959 remove_trace_name
= get_remove_trace(name
, nb_trace
);
1962 if(remove_trace_name
){
1964 /* yuk, cut n paste from old code.. should be better (MD)*/
1965 for(i
= 0; i
<nb_trace
; i
++) {
1966 if(strcmp(remove_trace_name
,name
[i
]) == 0){
1971 traceset
= tab
->traceset_info
->traceset
;
1972 //Keep a reference to the traces so they are not freed.
1973 for(j
=0; j
<lttv_traceset_number(traceset
); j
++)
1975 LttvTrace
* trace
= lttv_traceset_get(traceset
, j
);
1976 lttv_trace_ref(trace
);
1979 //remove state update hooks
1980 lttv_state_remove_event_hooks(
1981 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1982 lttv_context_fini(LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
));
1983 g_object_unref(tab
->traceset_info
->traceset_context
);
1985 trace_v
= lttv_traceset_get(traceset
, index
);
1987 lttv_traceset_remove(traceset
, index
);
1988 lttv_trace_unref(trace_v
); // Remove local reference
1990 if(lttv_trace_get_ref_number(trace_v
) <= 1) {
1991 /* ref 1 : lttvwindowtraces only*/
1992 ltt_trace_close(lttv_trace(trace_v
));
1993 /* lttvwindowtraces_remove_trace takes care of destroying
1994 * the traceset linked with the trace_v and also of destroying
1995 * the trace_v at the same time.
1997 lttvwindowtraces_remove_trace(trace_v
);
2000 tab
->traceset_info
->traceset_context
=
2001 g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
2003 LTTV_TRACESET_CONTEXT(tab
->
2004 traceset_info
->traceset_context
),traceset
);
2005 //add state update hooks
2006 lttv_state_add_event_hooks(
2007 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
2009 //Remove local reference to the traces.
2010 for(j
=0; j
<lttv_traceset_number(traceset
); j
++)
2012 LttvTrace
* trace
= lttv_traceset_get(traceset
, j
);
2013 lttv_trace_unref(trace
);
2016 SetTraceset(tab
, (gpointer
)traceset
);
2022 void remove_trace(GtkWidget
* widget
, gpointer user_data
)
2025 LttvTrace
* trace_v
;
2026 LttvTraceset
* traceset
;
2027 gint i
, j
, nb_trace
;
2028 char ** name
, *remove_trace_name
;
2029 MainWindow
* mw_data
= get_window_data_struct(widget
);
2030 LttvTracesetSelector
* s
;
2031 LttvTraceSelector
* t
;
2034 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
2036 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2037 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2043 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
2046 nb_trace
=lttv_traceset_number(tab
->traceset_info
->traceset
);
2047 name
= g_new(char*,nb_trace
);
2048 for(i
= 0; i
< nb_trace
; i
++){
2049 trace_v
= lttv_traceset_get(tab
->traceset_info
->traceset
, i
);
2050 trace
= lttv_trace(trace_v
);
2051 name
[i
] = ltt_trace_name(trace
);
2054 remove_trace_name
= get_remove_trace(name
, nb_trace
);
2056 if(remove_trace_name
){
2057 for(i
=0; i
<nb_trace
; i
++){
2058 if(strcmp(remove_trace_name
,name
[i
]) == 0){
2059 //unselect the trace from the current viewer
2061 w
= gtk_multivpaned_get_widget(GTK_MULTIVPANED(tab
->multivpaned
));
2063 s
= g_object_get_data(G_OBJECT(w
), "Traceset_Selector");
2065 t
= lttv_traceset_selector_trace_get(s
,i
);
2066 lttv_trace_selector_set_selected(t
, FALSE
);
2069 //check if other viewers select the trace
2070 w
= gtk_multivpaned_get_first_widget(GTK_MULTIVPANED(tab
->multivpaned
));
2072 s
= g_object_get_data(G_OBJECT(w
), "Traceset_Selector");
2074 t
= lttv_traceset_selector_trace_get(s
,i
);
2075 selected
= lttv_trace_selector_get_selected(t
);
2078 w
= gtk_multivpaned_get_next_widget(GTK_MULTIVPANED(tab
->multivpaned
));
2080 }else selected
= FALSE
;
2082 //if no viewer selects the trace, remove it
2084 remove_trace_from_traceset_selector(GTK_MULTIVPANED(tab
->multivpaned
), i
);
2086 traceset
= tab
->traceset_info
->traceset
;
2087 //Keep a reference to the traces so they are not freed.
2088 for(j
=0; j
<lttv_traceset_number(traceset
); j
++)
2090 LttvTrace
* trace
= lttv_traceset_get(traceset
, j
);
2091 lttv_trace_ref(trace
);
2094 //remove state update hooks
2095 lttv_state_remove_event_hooks(
2096 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
2097 lttv_context_fini(LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
));
2098 g_object_unref(tab
->traceset_info
->traceset_context
);
2101 trace_v
= lttv_traceset_get(traceset
, i
);
2103 if(lttv_trace_get_ref_number(trace_v
) <= 2) {
2104 /* ref 2 : traceset, local */
2105 lttvwindowtraces_remove_trace(trace_v
);
2106 ltt_trace_close(lttv_trace(trace_v
));
2109 lttv_traceset_remove(traceset
, i
);
2110 lttv_trace_unref(trace_v
); // Remove local reference
2112 if(!lttv_trace_get_ref_number(trace_v
))
2113 lttv_trace_destroy(trace_v
);
2115 tab
->traceset_info
->traceset_context
=
2116 g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
2118 LTTV_TRACESET_CONTEXT(tab
->
2119 traceset_info
->traceset_context
),traceset
);
2120 //add state update hooks
2121 lttv_state_add_event_hooks(
2122 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
2124 //Remove local reference to the traces.
2125 for(j
=0; j
<lttv_traceset_number(traceset
); j
++)
2127 LttvTrace
* trace
= lttv_traceset_get(traceset
, j
);
2128 lttv_trace_unref(trace
);
2132 //update current tab
2133 //update_traceset(mw_data);
2136 SetTraceset(tab
, (gpointer
)traceset
);
2137 // in expose now call_pending_read_hooks(mw_data);
2139 //lttvwindow_report_current_time(mw_data,&(tab->current_time));
2142 // while(tab->multi_vpaned->num_children){
2143 // gtk_multi_vpaned_widget_delete(tab->multi_vpaned);
2157 /* Redraw all the viewers in the current tab */
2158 void redraw(GtkWidget
*widget
, gpointer user_data
)
2160 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
2161 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2162 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2167 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
2171 LttvAttributeValue value
;
2173 g_assert(lttv_iattribute_find_by_path(tab
->attributes
, "hooks/redraw", LTTV_POINTER
, &value
));
2175 tmp
= (LttvHooks
*)*(value
.v_pointer
);
2177 lttv_hooks_call(tmp
,NULL
);
2181 void continue_processing(GtkWidget
*widget
, gpointer user_data
)
2183 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
2184 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2185 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2190 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
2194 LttvAttributeValue value
;
2196 g_assert(lttv_iattribute_find_by_path(tab
->attributes
,
2197 "hooks/continue", LTTV_POINTER
, &value
));
2199 tmp
= (LttvHooks
*)*(value
.v_pointer
);
2201 lttv_hooks_call(tmp
,NULL
);
2204 /* Stop the processing for the calling main window's current tab.
2205 * It removes every processing requests that are in its list. It does not call
2206 * the end request hooks, because the request is not finished.
2209 void stop_processing(GtkWidget
*widget
, gpointer user_data
)
2211 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
2212 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2213 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2218 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
2220 GSList
*iter
= tab
->events_requests
;
2222 while(iter
!= NULL
) {
2223 GSList
*remove_iter
= iter
;
2224 iter
= g_slist_next(iter
);
2226 g_free(remove_iter
->data
);
2227 tab
->events_requests
=
2228 g_slist_remove_link(tab
->events_requests
, remove_iter
);
2230 tab
->events_request_pending
= FALSE
;
2231 g_idle_remove_by_data(tab
);
2232 g_assert(g_slist_length(tab
->events_requests
) == 0);
2236 /* save will save the traceset to a file
2237 * Not implemented yet FIXME
2240 void save(GtkWidget
* widget
, gpointer user_data
)
2245 void save_as(GtkWidget
* widget
, gpointer user_data
)
2247 g_printf("Save as\n");
2251 /* zoom will change the time_window of all the viewers of the
2252 * current tab, and redisplay them. The main functionality is to
2253 * determine the new time_window of the current tab
2256 void zoom(GtkWidget
* widget
, double size
)
2258 TimeInterval time_span
;
2259 TimeWindow new_time_window
;
2260 LttTime current_time
, time_delta
, time_s
, time_e
, time_tmp
;
2261 MainWindow
* mw_data
= get_window_data_struct(widget
);
2262 LttvTracesetContext
*tsc
;
2263 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
2265 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2266 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2272 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
2275 if(size
== 1) return;
2277 tsc
= LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
2278 time_span
= tsc
->time_span
;
2279 new_time_window
= tab
->time_window
;
2280 current_time
= tab
->current_time
;
2282 time_delta
= ltt_time_sub(time_span
.end_time
,time_span
.start_time
);
2284 new_time_window
.start_time
= time_span
.start_time
;
2285 new_time_window
.time_width
= time_delta
;
2287 new_time_window
.time_width
= ltt_time_div(new_time_window
.time_width
, size
);
2288 if(ltt_time_compare(new_time_window
.time_width
,time_delta
) > 0)
2289 { /* Case where zoom out is bigger than trace length */
2290 new_time_window
.start_time
= time_span
.start_time
;
2291 new_time_window
.time_width
= time_delta
;
2295 /* Center the image on the current time */
2296 new_time_window
.start_time
=
2297 ltt_time_sub(current_time
, ltt_time_div(new_time_window
.time_width
, 2.0));
2298 /* If on borders, don't fall off */
2299 if(ltt_time_compare(new_time_window
.start_time
, time_span
.start_time
) <0)
2301 new_time_window
.start_time
= time_span
.start_time
;
2305 if(ltt_time_compare(
2306 ltt_time_add(new_time_window
.start_time
, new_time_window
.time_width
),
2307 time_span
.end_time
) > 0)
2309 new_time_window
.start_time
=
2310 ltt_time_sub(time_span
.end_time
, new_time_window
.time_width
);
2317 if(ltt_time_compare(new_time_window
.time_width
, ltt_time_zero
) == 0) {
2318 g_warning("Zoom more than 1 ns impossible");
2320 time_change_manager(tab
, new_time_window
);
2324 void zoom_in(GtkWidget
* widget
, gpointer user_data
)
2329 void zoom_out(GtkWidget
* widget
, gpointer user_data
)
2334 void zoom_extended(GtkWidget
* widget
, gpointer user_data
)
2339 void go_to_time(GtkWidget
* widget
, gpointer user_data
)
2341 g_printf("Go to time\n");
2344 void show_time_frame(GtkWidget
* widget
, gpointer user_data
)
2346 g_printf("Show time frame\n");
2350 /* callback function */
2353 on_empty_traceset_activate (GtkMenuItem
*menuitem
,
2356 create_new_window((GtkWidget
*)menuitem
, user_data
, FALSE
);
2361 on_clone_traceset_activate (GtkMenuItem
*menuitem
,
2364 create_new_window((GtkWidget
*)menuitem
, user_data
, TRUE
);
2368 /* create_new_tab calls create_tab to construct a new tab in the main window
2371 Tab
*create_new_tab(GtkWidget
* widget
, gpointer user_data
){
2372 gchar label
[PATH_MAX
];
2373 MainWindow
* mw_data
= get_window_data_struct(widget
);
2375 GtkNotebook
* notebook
= (GtkNotebook
*)lookup_widget(widget
, "MNotebook");
2376 if(notebook
== NULL
){
2377 g_printf("Notebook does not exist\n");
2380 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2381 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2387 copy_tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
2390 strcpy(label
,"Page");
2391 if(get_label(mw_data
, label
,"Get the name of the tab","Please input tab's name"))
2392 return (create_tab (mw_data
, copy_tab
, notebook
, label
));
2396 on_tab_activate (GtkMenuItem
*menuitem
,
2399 create_new_tab((GtkWidget
*)menuitem
, user_data
);
2404 on_open_activate (GtkMenuItem
*menuitem
,
2407 open_traceset((GtkWidget
*)menuitem
, user_data
);
2412 on_close_activate (GtkMenuItem
*menuitem
,
2415 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2416 main_window_destructor(mw_data
);
2420 /* remove the current tab from the main window
2424 on_close_tab_activate (GtkWidget
*widget
,
2428 GtkWidget
* notebook
;
2430 MainWindow
* mw_data
= get_window_data_struct(widget
);
2431 notebook
= lookup_widget(widget
, "MNotebook");
2432 if(notebook
== NULL
){
2433 g_printf("Notebook does not exist\n");
2437 page_num
= gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
));
2439 gtk_notebook_remove_page(GTK_NOTEBOOK(notebook
), page_num
);
2444 on_close_tab_X_clicked (GtkWidget
*widget
,
2448 GtkWidget
*notebook
= lookup_widget(widget
, "MNotebook");
2449 if(notebook
== NULL
){
2450 g_printf("Notebook does not exist\n");
2454 if((page_num
= gtk_notebook_page_num(GTK_NOTEBOOK(notebook
), widget
)) != -1)
2455 gtk_notebook_remove_page(GTK_NOTEBOOK(notebook
), page_num
);
2461 on_add_trace_activate (GtkMenuItem
*menuitem
,
2464 add_trace((GtkWidget
*)menuitem
, user_data
);
2469 on_remove_trace_activate (GtkMenuItem
*menuitem
,
2472 remove_trace((GtkWidget
*)menuitem
, user_data
);
2477 on_save_activate (GtkMenuItem
*menuitem
,
2480 save((GtkWidget
*)menuitem
, user_data
);
2485 on_save_as_activate (GtkMenuItem
*menuitem
,
2488 save_as((GtkWidget
*)menuitem
, user_data
);
2493 on_quit_activate (GtkMenuItem
*menuitem
,
2501 on_cut_activate (GtkMenuItem
*menuitem
,
2509 on_copy_activate (GtkMenuItem
*menuitem
,
2512 g_printf("Copye\n");
2517 on_paste_activate (GtkMenuItem
*menuitem
,
2520 g_printf("Paste\n");
2525 on_delete_activate (GtkMenuItem
*menuitem
,
2528 g_printf("Delete\n");
2533 on_zoom_in_activate (GtkMenuItem
*menuitem
,
2536 zoom_in((GtkWidget
*)menuitem
, user_data
);
2541 on_zoom_out_activate (GtkMenuItem
*menuitem
,
2544 zoom_out((GtkWidget
*)menuitem
, user_data
);
2549 on_zoom_extended_activate (GtkMenuItem
*menuitem
,
2552 zoom_extended((GtkWidget
*)menuitem
, user_data
);
2557 on_go_to_time_activate (GtkMenuItem
*menuitem
,
2560 go_to_time((GtkWidget
*)menuitem
, user_data
);
2565 on_show_time_frame_activate (GtkMenuItem
*menuitem
,
2568 show_time_frame((GtkWidget
*)menuitem
, user_data
);
2573 on_move_viewer_up_activate (GtkMenuItem
*menuitem
,
2576 move_up_viewer((GtkWidget
*)menuitem
, user_data
);
2581 on_move_viewer_down_activate (GtkMenuItem
*menuitem
,
2584 move_down_viewer((GtkWidget
*)menuitem
, user_data
);
2589 on_remove_viewer_activate (GtkMenuItem
*menuitem
,
2592 delete_viewer((GtkWidget
*)menuitem
, user_data
);
2597 on_trace_filter_activate (GtkMenuItem
*menuitem
,
2600 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2601 LttvTracesetSelector
* s
;
2603 GtkWidget
* notebook
= lookup_widget(GTK_WIDGET(menuitem
), "MNotebook");
2605 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2606 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2612 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
2615 w
= gtk_multivpaned_get_widget(GTK_MULTIVPANED(tab
->multivpaned
));
2617 s
= g_object_get_data(G_OBJECT(w
), "Traceset_Selector");
2619 g_printf("There is no viewer yet\n");
2622 if(get_filter_selection(s
, "Configure trace and tracefile filter", "Select traces and tracefiles")){
2623 //FIXME report filter change
2624 //update_traceset(mw_data);
2625 //call_pending_read_hooks(mw_data);
2626 //lttvwindow_report_current_time(mw_data,&(tab->current_time));
2632 on_trace_facility_activate (GtkMenuItem
*menuitem
,
2635 g_printf("Trace facility selector: %s\n");
2639 /* Dispaly a file selection dialogue to let user select a library, then call
2640 * lttv_library_load().
2644 on_load_library_activate (GtkMenuItem
*menuitem
,
2647 GError
*error
= NULL
;
2648 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2650 gchar load_module_path_alter
[PATH_MAX
];
2654 gchar
*load_module_path
;
2655 name
= g_ptr_array_new();
2656 nb
= lttv_library_path_number();
2657 /* ask for the library path */
2661 path
= lttv_library_path_get(i
);
2662 g_ptr_array_add(name
, path
);
2665 load_module_path
= get_selection((char **)(name
->pdata
), name
->len
,
2666 "Select a library path", "Library paths");
2667 if(load_module_path
!= NULL
)
2668 strncpy(load_module_path_alter
, load_module_path
, PATH_MAX
-1); // -1 for /
2670 g_ptr_array_free(name
, TRUE
);
2672 if(load_module_path
== NULL
) return;
2676 /* Make sure the module path ends with a / */
2677 gchar
*ptr
= load_module_path_alter
;
2679 ptr
= strchr(ptr
, '\0');
2681 if(*(ptr
-1) != '/') {
2688 /* Ask for the library to load : list files in the previously selected
2690 gchar str
[PATH_MAX
];
2693 GtkFileSelection
* file_selector
=
2694 (GtkFileSelection
*)gtk_file_selection_new("Select a module");
2695 gtk_file_selection_set_filename(file_selector
, load_module_path_alter
);
2696 gtk_file_selection_hide_fileop_buttons(file_selector
);
2699 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
2701 case GTK_RESPONSE_ACCEPT
:
2702 case GTK_RESPONSE_OK
:
2703 dir
= gtk_file_selection_get_selections (file_selector
);
2704 strncpy(str
,dir
[0],PATH_MAX
);
2705 strncpy(remember_plugins_dir
,dir
[0],PATH_MAX
);
2706 /* only keep file name */
2708 str1
= strrchr(str
,'/');
2711 str1
= strrchr(str
,'\\');
2716 if(*str1
== 'l' && *(str1
+1)== 'i' && *(str1
+2)=='b')
2718 remove info after
. */
2722 str2
= strrchr(str2
, '.');
2723 if(str2
!= NULL
) *str2
= '\0';
2725 lttv_module_require(str1
, &error
);
2727 lttv_library_load(str1
, &error
);
2728 if(error
!= NULL
) g_warning(error
->message
);
2729 else g_printf("Load library: %s\n", str
);
2731 case GTK_RESPONSE_REJECT
:
2732 case GTK_RESPONSE_CANCEL
:
2734 gtk_widget_destroy((GtkWidget
*)file_selector
);
2745 /* Display all loaded modules, let user to select a module to unload
2746 * by calling lttv_module_unload
2750 on_unload_library_activate (GtkMenuItem
*menuitem
,
2753 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2755 LttvLibrary
*library
;
2760 name
= g_ptr_array_new();
2761 nb
= lttv_library_number();
2762 LttvLibraryInfo
*lib_info
= g_new(LttvLibraryInfo
,nb
);
2763 /* ask for the library name */
2766 LttvLibrary
*iter_lib
= lttv_library_get(i
);
2767 lttv_library_info(iter_lib
, &lib_info
[i
]);
2769 gchar
*path
= lib_info
[i
].name
;
2770 g_ptr_array_add(name
, lib_info
[i
].name
);
2772 lib_name
= get_selection((char **)(name
->pdata
), name
->len
,
2773 "Select a library", "Libraries");
2774 if(lib_name
!= NULL
) {
2776 if(strcmp(lib_name
, lib_info
[i
].name
) == 0) {
2777 library
= lttv_library_get(i
);
2782 g_ptr_array_free(name
, TRUE
);
2785 if(lib_name
== NULL
) return;
2788 lttv_library_unload(library
);
2792 /* Dispaly a file selection dialogue to let user select a module, then call
2793 * lttv_module_require().
2797 on_load_module_activate (GtkMenuItem
*menuitem
,
2800 GError
*error
= NULL
;
2801 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2803 LttvLibrary
*library
;
2808 name
= g_ptr_array_new();
2809 nb
= lttv_library_number();
2810 LttvLibraryInfo
*lib_info
= g_new(LttvLibraryInfo
,nb
);
2811 /* ask for the library name */
2814 LttvLibrary
*iter_lib
= lttv_library_get(i
);
2815 lttv_library_info(iter_lib
, &lib_info
[i
]);
2817 gchar
*path
= lib_info
[i
].name
;
2818 g_ptr_array_add(name
, path
);
2820 lib_name
= get_selection((char **)(name
->pdata
), name
->len
,
2821 "Select a library", "Libraries");
2822 if(lib_name
!= NULL
) {
2824 if(strcmp(lib_name
, lib_info
[i
].name
) == 0) {
2825 library
= lttv_library_get(i
);
2830 g_ptr_array_free(name
, TRUE
);
2833 if(lib_name
== NULL
) return;
2836 //LttvModule *module;
2837 gchar module_name_out
[PATH_MAX
];
2839 /* Ask for the module to load : list modules in the selected lib */
2843 LttvModuleInfo
*module_info
= g_new(LttvModuleInfo
,nb
);
2844 name
= g_ptr_array_new();
2845 nb
= lttv_library_module_number(library
);
2846 /* ask for the module name */
2849 LttvModule
*iter_module
= lttv_library_module_get(library
, i
);
2850 lttv_module_info(iter_module
, &module_info
[i
]);
2852 gchar
*path
= module_info
[i
].name
;
2853 g_ptr_array_add(name
, path
);
2855 module_name
= get_selection((char **)(name
->pdata
), name
->len
,
2856 "Select a module", "Modules");
2857 if(module_name
!= NULL
) {
2859 if(strcmp(module_name
, module_info
[i
].name
) == 0) {
2860 strncpy(module_name_out
, module_name
, PATH_MAX
);
2861 //module = lttv_library_module_get(i);
2867 g_ptr_array_free(name
, TRUE
);
2868 g_free(module_info
);
2870 if(module_name
== NULL
) return;
2873 lttv_module_require(module_name_out
, &error
);
2874 if(error
!= NULL
) g_warning(error
->message
);
2875 else g_printf("Load module: %s\n", module_name_out
);
2882 gchar str
[PATH_MAX
];
2885 GtkFileSelection
* file_selector
=
2886 (GtkFileSelection
*)gtk_file_selection_new("Select a module");
2887 gtk_file_selection_set_filename(file_selector
, load_module_path_alter
);
2888 gtk_file_selection_hide_fileop_buttons(file_selector
);
2891 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
2893 case GTK_RESPONSE_ACCEPT
:
2894 case GTK_RESPONSE_OK
:
2895 dir
= gtk_file_selection_get_selections (file_selector
);
2896 strncpy(str
,dir
[0],PATH_MAX
);
2897 strncpy(remember_plugins_dir
,dir
[0],PATH_MAX
);
2899 /* only keep file name */
2901 str1
= strrchr(str
,'/');
2904 str1
= strrchr(str
,'\\');
2909 if(*str1
== 'l' && *(str1
+1)== 'i' && *(str1
+2)=='b')
2911 remove info after
. */
2915 str2
= strrchr(str2
, '.');
2916 if(str2
!= NULL
) *str2
= '\0';
2918 lttv_module_require(str1
, &error
);
2920 lttv_library_load(str1
, &error
);
2921 if(error
!= NULL
) g_warning(error
->message
);
2922 else g_printf("Load library: %s\n", str
);
2924 case GTK_RESPONSE_REJECT
:
2925 case GTK_RESPONSE_CANCEL
:
2927 gtk_widget_destroy((GtkWidget
*)file_selector
);
2939 /* Display all loaded modules, let user to select a module to unload
2940 * by calling lttv_module_unload
2944 on_unload_module_activate (GtkMenuItem
*menuitem
,
2947 GError
*error
= NULL
;
2948 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2950 LttvLibrary
*library
;
2955 name
= g_ptr_array_new();
2956 nb
= lttv_library_number();
2957 LttvLibraryInfo
*lib_info
= g_new(LttvLibraryInfo
,nb
);
2958 /* ask for the library name */
2961 LttvLibrary
*iter_lib
= lttv_library_get(i
);
2962 lttv_library_info(iter_lib
, &lib_info
[i
]);
2964 gchar
*path
= lib_info
[i
].name
;
2965 g_ptr_array_add(name
, path
);
2967 lib_name
= get_selection((char **)(name
->pdata
), name
->len
,
2968 "Select a library", "Libraries");
2969 if(lib_name
!= NULL
) {
2971 if(strcmp(lib_name
, lib_info
[i
].name
) == 0) {
2972 library
= lttv_library_get(i
);
2977 g_ptr_array_free(name
, TRUE
);
2980 if(lib_name
== NULL
) return;
2985 /* Ask for the module to load : list modules in the selected lib */
2989 nb
= lttv_library_module_number(library
);
2990 LttvModuleInfo
*module_info
= g_new(LttvModuleInfo
,nb
);
2991 name
= g_ptr_array_new();
2992 /* ask for the module name */
2995 LttvModule
*iter_module
= lttv_library_module_get(library
, i
);
2996 lttv_module_info(iter_module
, &module_info
[i
]);
2998 gchar
*path
= module_info
[i
].name
;
2999 if(module_info
[i
].use_count
> 0) g_ptr_array_add(name
, path
);
3001 module_name
= get_selection((char **)(name
->pdata
), name
->len
,
3002 "Select a module", "Modules");
3003 if(module_name
!= NULL
) {
3005 if(strcmp(module_name
, module_info
[i
].name
) == 0) {
3006 module
= lttv_library_module_get(library
, i
);
3012 g_ptr_array_free(name
, TRUE
);
3013 g_free(module_info
);
3015 if(module_name
== NULL
) return;
3018 LttvModuleInfo module_info
;
3019 lttv_module_info(module
, &module_info
);
3020 g_printf("Release module: %s\n", module_info
.name
);
3022 lttv_module_release(module
);
3026 /* Display a directory dialogue to let user select a path for library searching
3030 on_add_library_search_path_activate (GtkMenuItem
*menuitem
,
3033 GtkDirSelection
* file_selector
= (GtkDirSelection
*)gtk_dir_selection_new("Select library path");
3037 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
3038 if(remember_plugins_dir
[0] != '\0')
3039 gtk_dir_selection_set_filename(file_selector
, remember_plugins_dir
);
3041 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
3043 case GTK_RESPONSE_ACCEPT
:
3044 case GTK_RESPONSE_OK
:
3045 dir
= gtk_dir_selection_get_dir (file_selector
);
3046 strncpy(remember_plugins_dir
,dir
,PATH_MAX
);
3047 strncat(remember_plugins_dir
,"/",PATH_MAX
);
3048 lttv_library_path_add(dir
);
3049 case GTK_RESPONSE_REJECT
:
3050 case GTK_RESPONSE_CANCEL
:
3052 gtk_widget_destroy((GtkWidget
*)file_selector
);
3058 /* Display a directory dialogue to let user select a path for library searching
3062 on_remove_library_search_path_activate (GtkMenuItem
*menuitem
,
3065 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
3067 const char *lib_path
;
3072 name
= g_ptr_array_new();
3073 nb
= lttv_library_path_number();
3074 /* ask for the library name */
3077 gchar
*path
= lttv_library_path_get(i
);
3078 g_ptr_array_add(name
, path
);
3080 lib_path
= get_selection((char **)(name
->pdata
), name
->len
,
3081 "Select a library path", "Library paths");
3083 g_ptr_array_free(name
, TRUE
);
3085 if(lib_path
== NULL
) return;
3088 lttv_library_path_remove(lib_path
);
3092 on_color_activate (GtkMenuItem
*menuitem
,
3095 g_printf("Color\n");
3100 on_filter_activate (GtkMenuItem
*menuitem
,
3103 g_printf("Filter\n");
3108 on_save_configuration_activate (GtkMenuItem
*menuitem
,
3111 g_printf("Save configuration\n");
3116 on_content_activate (GtkMenuItem
*menuitem
,
3119 g_printf("Content\n");
3124 on_about_close_activate (GtkButton
*button
,
3127 GtkWidget
*about_widget
= GTK_WIDGET(user_data
);
3129 gtk_widget_destroy(about_widget
);
3133 on_about_activate (GtkMenuItem
*menuitem
,
3136 MainWindow
*main_window
= get_window_data_struct(GTK_WIDGET(menuitem
));
3137 GtkWidget
*window_widget
= main_window
->mwindow
;
3138 GtkWidget
*about_widget
= gtk_window_new(GTK_WINDOW_TOPLEVEL
);
3139 GtkWindow
*about_window
= GTK_WINDOW(about_widget
);
3140 gint window_width
, window_height
;
3142 gtk_window_set_title(about_window
, "About Linux Trace Toolkit");
3144 gtk_window_set_resizable(about_window
, FALSE
);
3145 gtk_window_set_transient_for(GTK_WINDOW(window_widget
), about_window
);
3146 gtk_window_set_destroy_with_parent(about_window
, TRUE
);
3147 gtk_window_set_modal(about_window
, FALSE
);
3149 /* Put the about window at the center of the screen */
3150 gtk_window_get_size(about_window
, &window_width
, &window_height
);
3151 gtk_window_move (about_window
,
3152 (gdk_screen_width() - window_width
)/2,
3153 (gdk_screen_height() - window_height
)/2);
3155 GtkWidget
*vbox
= gtk_vbox_new(FALSE
, 1);
3157 gtk_container_add(GTK_CONTAINER(about_widget
), vbox
);
3161 GtkWidget
*label1
= gtk_label_new("");
3162 gtk_misc_set_padding(GTK_MISC(label1
), 10, 20);
3163 gtk_label_set_markup(GTK_LABEL(label1
), "\
3164 <big>Linux Trace Toolkit</big>");
3165 gtk_label_set_justify(GTK_LABEL(label1
), GTK_JUSTIFY_CENTER
);
3167 GtkWidget
*label2
= gtk_label_new("");
3168 gtk_misc_set_padding(GTK_MISC(label2
), 10, 20);
3169 gtk_label_set_markup(GTK_LABEL(label2
), "\
3170 Project author: Karim Yaghmour\n\
3174 Michel Dagenais (New trace format, lttv main)\n\
3175 Mathieu Desnoyers (Directory structure, build with automake/conf,\n\
3176 lttv gui, control flow view, gui green threads\n\
3177 with interruptible foreground and background computation,\n\
3178 detailed event list)\n\
3179 Benoit Des Ligneris (Cluster adaptation)\n\
3180 Xang-Xiu Yang (new trace reading library and converter, lttv gui, \n\
3181 detailed event list and statistics view)\n\
3182 Tom Zanussi (RelayFS)");
3184 GtkWidget
*label3
= gtk_label_new("");
3185 gtk_label_set_markup(GTK_LABEL(label3
), "\
3186 Linux Trace Toolkit, Copyright (C) 2004 Karim Yaghmour\n\
3187 Linux Trace Toolkit comes with ABSOLUTELY NO WARRANTY.\n\
3188 This is free software, and you are welcome to redistribute it\n\
3189 under certain conditions. See COPYING for details.");
3190 gtk_misc_set_padding(GTK_MISC(label3
), 10, 20);
3192 gtk_box_pack_start_defaults(GTK_BOX(vbox
), label1
);
3193 gtk_box_pack_start_defaults(GTK_BOX(vbox
), label2
);
3194 gtk_box_pack_start_defaults(GTK_BOX(vbox
), label3
);
3196 GtkWidget
*hbox
= gtk_hbox_new(TRUE
, 0);
3197 gtk_box_pack_end(GTK_BOX(vbox
), hbox
, FALSE
, FALSE
, 0);
3198 GtkWidget
*close_button
= gtk_button_new_with_mnemonic("_Close");
3199 gtk_box_pack_end(GTK_BOX(hbox
), close_button
, FALSE
, FALSE
, 0);
3200 gtk_container_set_border_width(GTK_CONTAINER(close_button
), 20);
3202 g_signal_connect(G_OBJECT(close_button
), "clicked",
3203 G_CALLBACK(on_about_close_activate
),
3204 (gpointer
)about_widget
);
3206 gtk_widget_show_all(about_widget
);
3211 on_button_new_clicked (GtkButton
*button
,
3214 create_new_window((GtkWidget
*)button
, user_data
, TRUE
);
3218 on_button_new_tab_clicked (GtkButton
*button
,
3221 create_new_tab((GtkWidget
*)button
, user_data
);
3225 on_button_open_clicked (GtkButton
*button
,
3228 open_traceset((GtkWidget
*)button
, user_data
);
3233 on_button_add_trace_clicked (GtkButton
*button
,
3236 add_trace((GtkWidget
*)button
, user_data
);
3241 on_button_remove_trace_clicked (GtkButton
*button
,
3244 remove_trace((GtkWidget
*)button
, user_data
);
3248 on_button_redraw_clicked (GtkButton
*button
,
3251 redraw((GtkWidget
*)button
, user_data
);
3255 on_button_continue_processing_clicked (GtkButton
*button
,
3258 continue_processing((GtkWidget
*)button
, user_data
);
3262 on_button_stop_processing_clicked (GtkButton
*button
,
3265 stop_processing((GtkWidget
*)button
, user_data
);
3271 on_button_save_clicked (GtkButton
*button
,
3274 save((GtkWidget
*)button
, user_data
);
3279 on_button_save_as_clicked (GtkButton
*button
,
3282 save_as((GtkWidget
*)button
, user_data
);
3287 on_button_zoom_in_clicked (GtkButton
*button
,
3290 zoom_in((GtkWidget
*)button
, user_data
);
3295 on_button_zoom_out_clicked (GtkButton
*button
,
3298 zoom_out((GtkWidget
*)button
, user_data
);
3303 on_button_zoom_extended_clicked (GtkButton
*button
,
3306 zoom_extended((GtkWidget
*)button
, user_data
);
3311 on_button_go_to_time_clicked (GtkButton
*button
,
3314 go_to_time((GtkWidget
*)button
, user_data
);
3319 on_button_show_time_frame_clicked (GtkButton
*button
,
3322 show_time_frame((GtkWidget
*)button
, user_data
);
3327 on_button_move_up_clicked (GtkButton
*button
,
3330 move_up_viewer((GtkWidget
*)button
, user_data
);
3335 on_button_move_down_clicked (GtkButton
*button
,
3338 move_down_viewer((GtkWidget
*)button
, user_data
);
3343 on_button_delete_viewer_clicked (GtkButton
*button
,
3346 delete_viewer((GtkWidget
*)button
, user_data
);
3350 on_MWindow_destroy (GtkWidget
*widget
,
3353 MainWindow
*main_window
= get_window_data_struct(widget
);
3354 LttvIAttribute
*attributes
= main_window
->attributes
;
3355 LttvAttributeValue value
;
3357 //This is unnecessary, since widgets will be destroyed
3358 //by the main window widget anyway.
3359 //remove_all_menu_toolbar_constructors(main_window, NULL);
3361 g_assert(lttv_iattribute_find_by_path(attributes
,
3362 "viewers/menu", LTTV_POINTER
, &value
));
3363 lttv_menus_destroy((LttvMenus
*)*(value
.v_pointer
));
3365 g_assert(lttv_iattribute_find_by_path(attributes
,
3366 "viewers/toolbar", LTTV_POINTER
, &value
));
3367 lttv_toolbars_destroy((LttvToolbars
*)*(value
.v_pointer
));
3369 g_object_unref(main_window
->attributes
);
3370 g_main_window_list
= g_slist_remove(g_main_window_list
, main_window
);
3372 g_printf("There are now : %d windows\n",g_slist_length(g_main_window_list
));
3373 if(g_slist_length(g_main_window_list
) == 0)
3378 on_MWindow_configure (GtkWidget
*widget
,
3379 GdkEventConfigure
*event
,
3382 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)widget
);
3383 float width
= event
->width
;
3384 TimeWindow time_win
;
3386 TimeInterval
*time_span
;
3389 // MD : removed time width modification upon resizing of the main window.
3390 // The viewers will redraw themselves completely, without time interval
3393 if(mw_data->window_width){
3394 time_span = LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context)->Time_Span ;
3395 time_win = tab->time_window;
3396 ratio = width / mw_data->window_width;
3397 tab->time_window.time_width = ltt_time_mul(time_win.time_width,ratio);
3398 time = ltt_time_sub(time_span->endTime, time_win.start_time);
3399 if(ltt_time_compare(time, tab->time_window.time_width) < 0){
3400 tab->time_window.time_width = time;
3406 mw_data->window_width = (int)width;
3415 on_MNotebook_switch_page (GtkNotebook
*notebook
,
3416 GtkNotebookPage
*page
,
3424 void time_change_manager (Tab
*tab
,
3425 TimeWindow new_time_window
)
3427 /* Only one source of time change */
3428 if(tab
->time_manager_lock
== TRUE
) return;
3430 tab
->time_manager_lock
= TRUE
;
3432 LttvTracesetContext
*tsc
= LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3433 TimeInterval time_span
= tsc
->time_span
;
3434 LttTime start_time
= new_time_window
.start_time
;
3435 LttTime end_time
= ltt_time_add(new_time_window
.start_time
,
3436 new_time_window
.time_width
);
3439 GtkAdjustment
*adjustment
= gtk_range_get_adjustment(GTK_RANGE(tab
->scrollbar
));
3440 LttTime upper
= ltt_time_sub(time_span
.end_time
, time_span
.start_time
);
3442 gtk_range_set_increments(GTK_RANGE(tab
->scrollbar
),
3443 ltt_time_to_double(new_time_window
.time_width
)
3444 / SCROLL_STEP_PER_PAGE
3445 * NANOSECONDS_PER_SECOND
, /* step increment */
3446 ltt_time_to_double(new_time_window
.time_width
)
3447 * NANOSECONDS_PER_SECOND
); /* page increment */
3448 gtk_range_set_range(GTK_RANGE(tab
->scrollbar
),
3450 ltt_time_to_double(upper
)
3451 * NANOSECONDS_PER_SECOND
); /* upper */
3453 g_object_set(G_OBJECT(adjustment
),
3457 ltt_time_to_double(upper
)
3458 * NANOSECONDS_PER_SECOND
, /* upper */
3460 ltt_time_to_double(new_time_window
.time_width
)
3461 / SCROLL_STEP_PER_PAGE
3462 * NANOSECONDS_PER_SECOND
, /* step increment */
3464 ltt_time_to_double(new_time_window
.time_width
)
3465 * NANOSECONDS_PER_SECOND
, /* page increment */
3467 ltt_time_to_double(new_time_window
.time_width
)
3468 * NANOSECONDS_PER_SECOND
, /* page size */
3470 gtk_adjustment_changed(adjustment
);
3472 // g_object_set(G_OBJECT(adjustment),
3474 // ltt_time_to_double(
3475 // ltt_time_sub(start_time, time_span.start_time))
3476 // * NANOSECONDS_PER_SECOND, /* value */
3478 //gtk_adjustment_value_changed(adjustment);
3479 gtk_range_set_value(GTK_RANGE(tab
->scrollbar
),
3481 ltt_time_sub(start_time
, time_span
.start_time
))
3482 * NANOSECONDS_PER_SECOND
/* value */);
3484 /* set the time bar. */
3486 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry1
),
3487 (double)time_span
.start_time
.tv_sec
,
3488 (double)time_span
.end_time
.tv_sec
);
3489 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry1
),
3490 (double)start_time
.tv_sec
);
3492 /* start nanoseconds */
3493 if(start_time
.tv_sec
== time_span
.start_time
.tv_sec
) {
3494 /* can be both beginning and end at the same time. */
3495 if(start_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3496 /* If we are at the end, max nsec to end.. -1 (not zero length) */
3497 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry2
),
3498 (double)time_span
.start_time
.tv_nsec
,
3499 (double)time_span
.end_time
.tv_nsec
-1);
3501 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry2
),
3502 (double)time_span
.start_time
.tv_nsec
,
3503 (double)NANOSECONDS_PER_SECOND
-1);
3505 } else if(start_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3506 /* If we are at the end, max nsec to end.. -1 (not zero length) */
3507 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry2
),
3509 (double)time_span
.end_time
.tv_nsec
-1);
3510 } else /* anywhere else */
3511 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry2
),
3513 (double)NANOSECONDS_PER_SECOND
-1);
3514 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry2
),
3515 (double)start_time
.tv_nsec
);
3518 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry3
),
3519 (double)time_span
.start_time
.tv_sec
,
3520 (double)time_span
.end_time
.tv_sec
);
3521 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry3
),
3522 (double)end_time
.tv_sec
);
3524 /* end nanoseconds */
3525 if(end_time
.tv_sec
== time_span
.start_time
.tv_sec
) {
3526 /* can be both beginning and end at the same time. */
3527 if(end_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3528 /* If we are at the end, max nsec to end.. */
3529 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry4
),
3530 (double)time_span
.start_time
.tv_nsec
+1,
3531 (double)time_span
.end_time
.tv_nsec
);
3533 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry4
),
3534 (double)time_span
.start_time
.tv_nsec
+1,
3535 (double)NANOSECONDS_PER_SECOND
-1);
3538 else if(end_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3539 /* If we are at the end, max nsec to end.. */
3540 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry4
),
3542 (double)time_span
.end_time
.tv_nsec
);
3544 else /* anywhere else */
3545 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry4
),
3547 (double)NANOSECONDS_PER_SECOND
-1);
3548 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry4
),
3549 (double)end_time
.tv_nsec
);
3551 /* call viewer hooks for new time window */
3552 set_time_window(tab
, &new_time_window
);
3554 tab
->time_manager_lock
= FALSE
;
3558 /* value changed for frame start s
3560 * Check time span : if ns is out of range, clip it the nearest good value.
3563 on_MEntry1_value_changed (GtkSpinButton
*spinbutton
,
3566 Tab
*tab
=(Tab
*)user_data
;
3567 LttvTracesetContext
* tsc
=
3568 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3569 TimeInterval time_span
= tsc
->time_span
;
3570 gint value
= gtk_spin_button_get_value_as_int(spinbutton
);
3572 TimeWindow new_time_window
= tab
->time_window
;
3574 LttTime end_time
= ltt_time_add(new_time_window
.start_time
,
3575 new_time_window
.time_width
);
3577 new_time_window
.start_time
.tv_sec
= value
;
3579 /* start nanoseconds */
3580 if(new_time_window
.start_time
.tv_sec
== time_span
.start_time
.tv_sec
) {
3581 if(new_time_window
.start_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3582 if(new_time_window
.start_time
.tv_nsec
> time_span
.end_time
.tv_nsec
)
3583 new_time_window
.start_time
.tv_nsec
= time_span
.end_time
.tv_nsec
-1;
3584 if(new_time_window
.start_time
.tv_nsec
< time_span
.start_time
.tv_nsec
)
3585 new_time_window
.start_time
.tv_nsec
= time_span
.start_time
.tv_nsec
;
3587 if(new_time_window
.start_time
.tv_nsec
< time_span
.start_time
.tv_nsec
)
3588 new_time_window
.start_time
.tv_nsec
= time_span
.start_time
.tv_nsec
;
3591 else if(new_time_window
.start_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3592 if(new_time_window
.start_time
.tv_nsec
> time_span
.end_time
.tv_nsec
)
3593 new_time_window
.start_time
.tv_nsec
= time_span
.end_time
.tv_nsec
-1;
3596 /* check if end time selected is below or equal */
3597 if(ltt_time_compare(new_time_window
.start_time
, end_time
) >= 0) {
3598 /* Then, we must push back end time : keep the same time width
3599 * if possible, else end traceset time */
3600 end_time
= LTT_TIME_MIN(time_span
.end_time
,
3601 ltt_time_add(new_time_window
.start_time
,
3602 new_time_window
.time_width
)
3606 /* Fix the time width to fit start time and end time */
3607 new_time_window
.time_width
= ltt_time_sub(end_time
,
3608 new_time_window
.start_time
);
3610 time_change_manager(tab
, new_time_window
);
3615 on_MEntry2_value_changed (GtkSpinButton
*spinbutton
,
3618 Tab
*tab
=(Tab
*)user_data
;
3619 LttvTracesetContext
* tsc
=
3620 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3621 TimeInterval time_span
= tsc
->time_span
;
3622 gint value
= gtk_spin_button_get_value_as_int(spinbutton
);
3624 TimeWindow new_time_window
= tab
->time_window
;
3626 LttTime end_time
= ltt_time_add(new_time_window
.start_time
,
3627 new_time_window
.time_width
);
3629 new_time_window
.start_time
.tv_nsec
= value
;
3631 /* check if end time selected is below or equal */
3632 if(ltt_time_compare(new_time_window
.start_time
, end_time
) >= 0) {
3633 /* Then, we must push back end time : keep the same time width
3634 * if possible, else end traceset time */
3635 end_time
= LTT_TIME_MIN(time_span
.end_time
,
3636 ltt_time_add(new_time_window
.start_time
,
3637 new_time_window
.time_width
)
3641 /* Fix the time width to fit start time and end time */
3642 new_time_window
.time_width
= ltt_time_sub(end_time
,
3643 new_time_window
.start_time
);
3645 time_change_manager(tab
, new_time_window
);
3650 on_MEntry3_value_changed (GtkSpinButton
*spinbutton
,
3653 Tab
*tab
=(Tab
*)user_data
;
3654 LttvTracesetContext
* tsc
=
3655 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3656 TimeInterval time_span
= tsc
->time_span
;
3657 gint value
= gtk_spin_button_get_value_as_int(spinbutton
);
3659 TimeWindow new_time_window
= tab
->time_window
;
3661 LttTime end_time
= ltt_time_add(new_time_window
.start_time
,
3662 new_time_window
.time_width
);
3663 end_time
.tv_sec
= value
;
3665 /* end nanoseconds */
3666 if(end_time
.tv_sec
== time_span
.start_time
.tv_sec
) {
3667 if(end_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3668 if(end_time
.tv_nsec
> time_span
.end_time
.tv_nsec
)
3669 end_time
.tv_nsec
= time_span
.end_time
.tv_nsec
;
3670 if(end_time
.tv_nsec
< time_span
.start_time
.tv_nsec
)
3671 end_time
.tv_nsec
= time_span
.start_time
.tv_nsec
+1;
3673 if(end_time
.tv_nsec
< time_span
.start_time
.tv_nsec
)
3674 end_time
.tv_nsec
= time_span
.start_time
.tv_nsec
+1;
3677 else if(end_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3678 if(end_time
.tv_nsec
> time_span
.end_time
.tv_nsec
)
3679 end_time
.tv_nsec
= time_span
.end_time
.tv_nsec
;
3682 /* check if end time selected is below or equal */
3683 if(ltt_time_compare(new_time_window
.start_time
, end_time
) >= 0) {
3684 /* Then, we must push front start time : keep the same time width
3685 * if possible, else end traceset time */
3686 new_time_window
.start_time
= LTT_TIME_MAX(time_span
.start_time
,
3687 ltt_time_sub(end_time
,
3688 new_time_window
.time_width
)
3692 /* Fix the time width to fit start time and end time */
3693 new_time_window
.time_width
= ltt_time_sub(end_time
,
3694 new_time_window
.start_time
);
3696 time_change_manager(tab
, new_time_window
);
3701 on_MEntry4_value_changed (GtkSpinButton
*spinbutton
,
3704 Tab
*tab
=(Tab
*)user_data
;
3705 LttvTracesetContext
* tsc
=
3706 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3707 TimeInterval time_span
= tsc
->time_span
;
3708 gint value
= gtk_spin_button_get_value_as_int(spinbutton
);
3710 TimeWindow new_time_window
= tab
->time_window
;
3712 LttTime end_time
= ltt_time_add(new_time_window
.start_time
,
3713 new_time_window
.time_width
);
3714 end_time
.tv_nsec
= value
;
3716 /* check if end time selected is below or equal */
3717 if(ltt_time_compare(new_time_window
.start_time
, end_time
) >= 0) {
3718 /* Then, we must push front start time : keep the same time width
3719 * if possible, else end traceset time */
3720 new_time_window
.start_time
= LTT_TIME_MAX(time_span
.start_time
,
3721 ltt_time_sub(end_time
,
3722 new_time_window
.time_width
)
3726 /* Fix the time width to fit start time and end time */
3727 new_time_window
.time_width
= ltt_time_sub(end_time
,
3728 new_time_window
.start_time
);
3730 time_change_manager(tab
, new_time_window
);
3735 void current_time_change_manager (Tab
*tab
,
3736 LttTime new_current_time
)
3738 /* Only one source of time change */
3739 if(tab
->current_time_manager_lock
== TRUE
) return;
3741 tab
->current_time_manager_lock
= TRUE
;
3743 LttvTracesetContext
*tsc
= LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3744 TimeInterval time_span
= tsc
->time_span
;
3746 /* current seconds */
3747 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry5
),
3748 (double)time_span
.start_time
.tv_sec
,
3749 (double)time_span
.end_time
.tv_sec
);
3750 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry5
),
3751 (double)new_current_time
.tv_sec
);
3754 /* start nanoseconds */
3755 if(new_current_time
.tv_sec
== time_span
.start_time
.tv_sec
) {
3756 /* can be both beginning and end at the same time. */
3757 if(new_current_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3758 /* If we are at the end, max nsec to end.. */
3759 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry6
),
3760 (double)time_span
.start_time
.tv_nsec
,
3761 (double)time_span
.end_time
.tv_nsec
);
3763 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry6
),
3764 (double)time_span
.start_time
.tv_nsec
,
3765 (double)NANOSECONDS_PER_SECOND
-1);
3767 } else if(new_current_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3768 /* If we are at the end, max nsec to end.. */
3769 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry6
),
3771 (double)time_span
.end_time
.tv_nsec
);
3772 } else /* anywhere else */
3773 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry6
),
3775 (double)NANOSECONDS_PER_SECOND
-1);
3777 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry6
),
3778 (double)new_current_time
.tv_nsec
);
3780 set_current_time(tab
, &new_current_time
);
3782 tab
->current_time_manager_lock
= FALSE
;
3786 on_MEntry5_value_changed (GtkSpinButton
*spinbutton
,
3789 Tab
*tab
= (Tab
*)user_data
;
3790 LttvTracesetContext
* tsc
=
3791 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3792 TimeInterval time_span
= tsc
->time_span
;
3793 gint value
= gtk_spin_button_get_value_as_int(spinbutton
);
3794 LttTime new_current_time
= tab
->current_time
;
3795 new_current_time
.tv_sec
= value
;
3797 /* current nanoseconds */
3798 if(new_current_time
.tv_sec
== time_span
.start_time
.tv_sec
) {
3799 if(new_current_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3800 if(new_current_time
.tv_nsec
> time_span
.end_time
.tv_nsec
)
3801 new_current_time
.tv_nsec
= time_span
.end_time
.tv_nsec
;
3802 if(new_current_time
.tv_nsec
< time_span
.start_time
.tv_nsec
)
3803 new_current_time
.tv_nsec
= time_span
.start_time
.tv_nsec
;
3805 if(new_current_time
.tv_nsec
< time_span
.start_time
.tv_nsec
)
3806 new_current_time
.tv_nsec
= time_span
.start_time
.tv_nsec
;
3809 else if(new_current_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3810 if(new_current_time
.tv_nsec
> time_span
.end_time
.tv_nsec
)
3811 new_current_time
.tv_nsec
= time_span
.end_time
.tv_nsec
;
3814 current_time_change_manager(tab
, new_current_time
);
3818 on_MEntry6_value_changed (GtkSpinButton
*spinbutton
,
3821 Tab
*tab
= (Tab
*)user_data
;
3822 gint value
= gtk_spin_button_get_value_as_int(spinbutton
);
3823 LttTime new_current_time
= tab
->current_time
;
3824 new_current_time
.tv_nsec
= value
;
3826 current_time_change_manager(tab
, new_current_time
);
3830 void scroll_value_changed_cb(GtkWidget
*scrollbar
,
3833 Tab
*tab
= (Tab
*)user_data
;
3834 TimeWindow new_time_window
;
3836 GtkAdjustment
*adjust
= gtk_range_get_adjustment(GTK_RANGE(scrollbar
));
3837 gdouble value
= gtk_adjustment_get_value(adjust
);
3838 // gdouble upper, lower, ratio, page_size;
3840 LttvTracesetContext
* tsc
=
3841 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3842 TimeInterval time_span
= tsc
->time_span
;
3844 time
= ltt_time_add(ltt_time_from_double(value
/NANOSECONDS_PER_SECOND
),
3845 time_span
.start_time
);
3847 new_time_window
.start_time
= time
;
3849 page_size
= adjust
->page_size
;
3851 new_time_window
.time_width
=
3852 ltt_time_from_double(page_size
/NANOSECONDS_PER_SECOND
);
3855 time_change_manager(tab
, new_time_window
);
3857 //time_window = tab->time_window;
3859 lower
= adjust
->lower
;
3860 upper
= adjust
->upper
;
3861 ratio
= (value
- lower
) / (upper
- lower
);
3862 g_info("lower %lu, upper %lu, value %lu, ratio %lu", lower
, upper
, value
, ratio
);
3864 //time = ltt_time_sub(time_span->end_time, time_span->start_time);
3865 //time = ltt_time_mul(time, (float)ratio);
3866 //time = ltt_time_add(time_span->start_time, time);
3867 time
= ltt_time_add(ltt_time_from_double(value
/NANOSECONDS_PER_SECOND
),
3868 time_span
.start_time
);
3870 time_window
.start_time
= time
;
3872 page_size
= adjust
->page_size
;
3874 time_window
.time_width
=
3875 ltt_time_from_double(page_size
/NANOSECONDS_PER_SECOND
);
3876 //time = ltt_time_sub(time_span.end_time, time);
3877 //if(ltt_time_compare(time,time_window.time_width) < 0){
3878 // time_window.time_width = time;
3881 /* call viewer hooks for new time window */
3882 set_time_window(tab
, &time_window
);
3887 /* callback function to check or uncheck the check box (filter)
3890 void checkbox_changed(GtkTreeView
*treeview
,
3892 GtkTreeViewColumn
*arg2
,
3895 GtkTreeStore
* store
= (GtkTreeStore
*)gtk_tree_view_get_model (treeview
);
3899 if (gtk_tree_model_get_iter ((GtkTreeModel
*)store
, &iter
, arg1
)){
3900 gtk_tree_model_get ((GtkTreeModel
*)store
, &iter
, CHECKBOX_COLUMN
, &value
, -1);
3901 value
= value
? FALSE
: TRUE
;
3902 gtk_tree_store_set (GTK_TREE_STORE (store
), &iter
, CHECKBOX_COLUMN
, value
, -1);
3908 /* According to user's selection, update selector(filter)
3911 void update_filter(LttvTracesetSelector
*s
, GtkTreeStore
*store
)
3913 GtkTreeIter iter
, child_iter
, child_iter1
, child_iter2
;
3914 int i
, j
, k
, nb_eventtype
;
3915 LttvTraceSelector
* trace
;
3916 LttvTracefileSelector
* tracefile
;
3917 LttvEventtypeSelector
* eventtype
;
3918 gboolean value
, value1
, value2
;
3920 if(gtk_tree_model_get_iter_first((GtkTreeModel
*)store
, &iter
)){
3923 trace
= lttv_traceset_selector_trace_get(s
, i
);
3924 nb_eventtype
= lttv_trace_selector_eventtype_number(trace
);
3925 gtk_tree_model_get ((GtkTreeModel
*)store
, &iter
, CHECKBOX_COLUMN
, &value
,-1);
3928 if(gtk_tree_model_iter_children ((GtkTreeModel
*)store
, &child_iter
, &iter
)){
3930 if(j
<1){//eventtype selector for trace
3931 gtk_tree_model_get ((GtkTreeModel
*)store
, &child_iter
, CHECKBOX_COLUMN
, &value2
,-1);
3934 if(gtk_tree_model_iter_children ((GtkTreeModel
*)store
, &child_iter1
, &child_iter
)){
3936 eventtype
= lttv_trace_selector_eventtype_get(trace
,k
);
3937 gtk_tree_model_get ((GtkTreeModel
*)store
, &child_iter1
, CHECKBOX_COLUMN
, &value2
,-1);
3938 lttv_eventtype_selector_set_selected(eventtype
,value2
);
3940 }while(gtk_tree_model_iter_next((GtkTreeModel
*)store
, &child_iter1
));
3943 }else{ //tracefile selector
3944 tracefile
= lttv_trace_selector_tracefile_get(trace
, j
- 1);
3945 gtk_tree_model_get ((GtkTreeModel
*)store
, &child_iter
, CHECKBOX_COLUMN
, &value1
,-1);
3946 lttv_tracefile_selector_set_selected(tracefile
,value1
);
3948 gtk_tree_model_iter_children((GtkTreeModel
*)store
, &child_iter1
, &child_iter
); //eventtype selector
3949 gtk_tree_model_get ((GtkTreeModel
*)store
, &child_iter1
, CHECKBOX_COLUMN
, &value2
,-1);
3952 if(gtk_tree_model_iter_children ((GtkTreeModel
*)store
, &child_iter2
, &child_iter1
)){
3953 do{//eventtype selector for tracefile
3954 eventtype
= lttv_tracefile_selector_eventtype_get(tracefile
,k
);
3955 gtk_tree_model_get ((GtkTreeModel
*)store
, &child_iter2
, CHECKBOX_COLUMN
, &value2
,-1);
3956 lttv_eventtype_selector_set_selected(eventtype
,value2
);
3958 }while(gtk_tree_model_iter_next((GtkTreeModel
*)store
, &child_iter2
));
3964 }while(gtk_tree_model_iter_next((GtkTreeModel
*)store
, &child_iter
));
3967 lttv_trace_selector_set_selected(trace
,value
);
3969 }while(gtk_tree_model_iter_next((GtkTreeModel
*)store
, &iter
));
3974 /* Display a dialogue showing all eventtypes and traces, let user to select the interested
3975 * eventtypes, tracefiles and traces (filter)
3978 gboolean
get_filter_selection(LttvTracesetSelector
*s
,char *title
, char * column_title
)
3980 GtkWidget
* dialogue
;
3981 GtkTreeStore
* store
;
3983 GtkWidget
* scroll_win
;
3984 GtkCellRenderer
* renderer
;
3985 GtkTreeViewColumn
* column
;
3986 GtkTreeIter iter
, child_iter
, child_iter1
, child_iter2
;
3987 int i
, j
, k
, id
, nb_trace
, nb_tracefile
, nb_eventtype
;
3988 LttvTraceSelector
* trace
;
3989 LttvTracefileSelector
* tracefile
;
3990 LttvEventtypeSelector
* eventtype
;
3994 dialogue
= gtk_dialog_new_with_buttons(title
,
3997 GTK_STOCK_OK
,GTK_RESPONSE_ACCEPT
,
3998 GTK_STOCK_CANCEL
,GTK_RESPONSE_REJECT
,
4000 gtk_window_set_default_size((GtkWindow
*)dialogue
, 300, 500);
4002 store
= gtk_tree_store_new (TOTAL_COLUMNS
, G_TYPE_BOOLEAN
, G_TYPE_STRING
);
4003 tree
= gtk_tree_view_new_with_model (GTK_TREE_MODEL (store
));
4004 g_object_unref (G_OBJECT (store
));
4005 g_signal_connect (G_OBJECT (tree
), "row-activated",
4006 G_CALLBACK (checkbox_changed
),
4010 renderer
= gtk_cell_renderer_toggle_new ();
4011 gtk_cell_renderer_toggle_set_radio((GtkCellRendererToggle
*)renderer
, FALSE
);
4013 g_object_set (G_OBJECT (renderer
),"activatable", TRUE
, NULL
);
4015 column
= gtk_tree_view_column_new_with_attributes ("Checkbox",
4017 "active", CHECKBOX_COLUMN
,
4019 gtk_tree_view_column_set_alignment (column
, 0.5);
4020 gtk_tree_view_column_set_fixed_width (column
, 20);
4021 gtk_tree_view_append_column (GTK_TREE_VIEW (tree
), column
);
4023 renderer
= gtk_cell_renderer_text_new ();
4024 column
= gtk_tree_view_column_new_with_attributes (column_title
,
4026 "text", NAME_COLUMN
,
4028 gtk_tree_view_column_set_alignment (column
, 0.0);
4029 gtk_tree_view_append_column (GTK_TREE_VIEW (tree
), column
);
4030 gtk_tree_view_set_headers_visible(GTK_TREE_VIEW (tree
), FALSE
);
4032 scroll_win
= gtk_scrolled_window_new (NULL
, NULL
);
4033 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll_win
),
4034 GTK_POLICY_AUTOMATIC
,GTK_POLICY_AUTOMATIC
);
4035 gtk_container_add (GTK_CONTAINER (scroll_win
), tree
);
4037 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialogue
)->vbox
), scroll_win
,TRUE
, TRUE
,0);
4039 gtk_widget_show(scroll_win
);
4040 gtk_widget_show(tree
);
4042 nb_trace
= lttv_traceset_selector_trace_number(s
);
4043 for(i
=0;i
<nb_trace
;i
++){
4044 trace
= lttv_traceset_selector_trace_get(s
, i
);
4045 name
= lttv_trace_selector_get_name(trace
);
4046 gtk_tree_store_append (store
, &iter
, NULL
);
4047 checked
= lttv_trace_selector_get_selected(trace
);
4048 gtk_tree_store_set (store
, &iter
,
4049 CHECKBOX_COLUMN
,checked
,
4053 gtk_tree_store_append (store
, &child_iter
, &iter
);
4054 gtk_tree_store_set (store
, &child_iter
,
4055 CHECKBOX_COLUMN
, checked
,
4056 NAME_COLUMN
,"eventtype",
4059 nb_eventtype
= lttv_trace_selector_eventtype_number(trace
);
4060 for(j
=0;j
<nb_eventtype
;j
++){
4061 eventtype
= lttv_trace_selector_eventtype_get(trace
,j
);
4062 name
= lttv_eventtype_selector_get_name(eventtype
);
4063 checked
= lttv_eventtype_selector_get_selected(eventtype
);
4064 gtk_tree_store_append (store
, &child_iter1
, &child_iter
);
4065 gtk_tree_store_set (store
, &child_iter1
,
4066 CHECKBOX_COLUMN
, checked
,
4071 nb_tracefile
= lttv_trace_selector_tracefile_number(trace
);
4072 for(j
=0;j
<nb_tracefile
;j
++){
4073 tracefile
= lttv_trace_selector_tracefile_get(trace
, j
);
4074 name
= lttv_tracefile_selector_get_name(tracefile
);
4075 gtk_tree_store_append (store
, &child_iter
, &iter
);
4076 checked
= lttv_tracefile_selector_get_selected(tracefile
);
4077 gtk_tree_store_set (store
, &child_iter
,
4078 CHECKBOX_COLUMN
, checked
,
4082 gtk_tree_store_append (store
, &child_iter1
, &child_iter
);
4083 gtk_tree_store_set (store
, &child_iter1
,
4084 CHECKBOX_COLUMN
, checked
,
4085 NAME_COLUMN
,"eventtype",
4088 for(k
=0;k
<nb_eventtype
;k
++){
4089 eventtype
= lttv_tracefile_selector_eventtype_get(tracefile
,k
);
4090 name
= lttv_eventtype_selector_get_name(eventtype
);
4091 checked
= lttv_eventtype_selector_get_selected(eventtype
);
4092 gtk_tree_store_append (store
, &child_iter2
, &child_iter1
);
4093 gtk_tree_store_set (store
, &child_iter2
,
4094 CHECKBOX_COLUMN
, checked
,
4101 id
= gtk_dialog_run(GTK_DIALOG(dialogue
));
4103 case GTK_RESPONSE_ACCEPT
:
4104 case GTK_RESPONSE_OK
:
4105 update_filter(s
, store
);
4106 gtk_widget_destroy(dialogue
);
4108 case GTK_RESPONSE_REJECT
:
4109 case GTK_RESPONSE_CANCEL
:
4111 gtk_widget_destroy(dialogue
);
4118 /* Select a trace which will be removed from traceset
4121 char * get_remove_trace(char ** all_trace_name
, int nb_trace
)
4123 return get_selection(all_trace_name
, nb_trace
,
4124 "Select a trace", "Trace pathname");
4128 /* Select a module which will be loaded
4131 char * get_load_module(char ** load_module_name
, int nb_module
)
4133 return get_selection(load_module_name
, nb_module
,
4134 "Select a module to load", "Module name");
4140 /* Select a module which will be unloaded
4143 char * get_unload_module(char ** loaded_module_name
, int nb_module
)
4145 return get_selection(loaded_module_name
, nb_module
,
4146 "Select a module to unload", "Module name");
4150 /* Display a dialogue which shows all selectable items, let user to
4151 * select one of them
4154 char * get_selection(char ** loaded_module_name
, int nb_module
,
4155 char *title
, char * column_title
)
4157 GtkWidget
* dialogue
;
4158 GtkWidget
* scroll_win
;
4160 GtkListStore
* store
;
4161 GtkTreeViewColumn
* column
;
4162 GtkCellRenderer
* renderer
;
4163 GtkTreeSelection
* select
;
4166 char * unload_module_name
= NULL
;
4168 dialogue
= gtk_dialog_new_with_buttons(title
,
4171 GTK_STOCK_OK
,GTK_RESPONSE_ACCEPT
,
4172 GTK_STOCK_CANCEL
,GTK_RESPONSE_REJECT
,
4174 gtk_window_set_default_size((GtkWindow
*)dialogue
, 500, 200);
4176 scroll_win
= gtk_scrolled_window_new (NULL
, NULL
);
4177 gtk_widget_show ( scroll_win
);
4178 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll_win
),
4179 GTK_POLICY_AUTOMATIC
, GTK_POLICY_AUTOMATIC
);
4181 store
= gtk_list_store_new (N_COLUMNS
,G_TYPE_STRING
);
4182 tree
= gtk_tree_view_new_with_model(GTK_TREE_MODEL (store
));
4183 gtk_widget_show ( tree
);
4184 g_object_unref (G_OBJECT (store
));
4186 renderer
= gtk_cell_renderer_text_new ();
4187 column
= gtk_tree_view_column_new_with_attributes (column_title
,
4189 "text", MODULE_COLUMN
,
4191 gtk_tree_view_column_set_alignment (column
, 0.5);
4192 gtk_tree_view_column_set_fixed_width (column
, 150);
4193 gtk_tree_view_append_column (GTK_TREE_VIEW (tree
), column
);
4195 select
= gtk_tree_view_get_selection (GTK_TREE_VIEW (tree
));
4196 gtk_tree_selection_set_mode (select
, GTK_SELECTION_SINGLE
);
4198 gtk_container_add (GTK_CONTAINER (scroll_win
), tree
);
4200 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialogue
)->vbox
), scroll_win
,TRUE
, TRUE
,0);
4202 for(i
=0;i
<nb_module
;i
++){
4203 gtk_list_store_append (store
, &iter
);
4204 gtk_list_store_set (store
, &iter
, MODULE_COLUMN
,loaded_module_name
[i
],-1);
4207 id
= gtk_dialog_run(GTK_DIALOG(dialogue
));
4209 case GTK_RESPONSE_ACCEPT
:
4210 case GTK_RESPONSE_OK
:
4211 if (gtk_tree_selection_get_selected (select
, (GtkTreeModel
**)&store
, &iter
)){
4212 gtk_tree_model_get ((GtkTreeModel
*)store
, &iter
, MODULE_COLUMN
, &unload_module_name
, -1);
4214 case GTK_RESPONSE_REJECT
:
4215 case GTK_RESPONSE_CANCEL
:
4217 gtk_widget_destroy(dialogue
);
4221 return unload_module_name
;
4225 /* Insert all menu entry and tool buttons into this main window
4230 void add_all_menu_toolbar_constructors(MainWindow
* mw
, gpointer user_data
)
4234 lttvwindow_viewer_constructor constructor
;
4235 LttvMenus
* global_menu
, * instance_menu
;
4236 LttvToolbars
* global_toolbar
, * instance_toolbar
;
4237 LttvMenuClosure
*menu_item
;
4238 LttvToolbarClosure
*toolbar_item
;
4239 LttvAttributeValue value
;
4240 LttvIAttribute
*global_attributes
= LTTV_IATTRIBUTE(lttv_global_attributes());
4241 LttvIAttribute
*attributes
= mw
->attributes
;
4242 GtkWidget
* tool_menu_title_menu
, *new_widget
, *pixmap
;
4244 g_assert(lttv_iattribute_find_by_path(global_attributes
,
4245 "viewers/menu", LTTV_POINTER
, &value
));
4246 if(*(value
.v_pointer
) == NULL
)
4247 *(value
.v_pointer
) = lttv_menus_new();
4248 global_menu
= (LttvMenus
*)*(value
.v_pointer
);
4250 g_assert(lttv_iattribute_find_by_path(attributes
,
4251 "viewers/menu", LTTV_POINTER
, &value
));
4252 if(*(value
.v_pointer
) == NULL
)
4253 *(value
.v_pointer
) = lttv_menus_new();
4254 instance_menu
= (LttvMenus
*)*(value
.v_pointer
);
4258 g_assert(lttv_iattribute_find_by_path(global_attributes
,
4259 "viewers/toolbar", LTTV_POINTER
, &value
));
4260 if(*(value
.v_pointer
) == NULL
)
4261 *(value
.v_pointer
) = lttv_toolbars_new();
4262 global_toolbar
= (LttvToolbars
*)*(value
.v_pointer
);
4264 g_assert(lttv_iattribute_find_by_path(attributes
,
4265 "viewers/toolbar", LTTV_POINTER
, &value
));
4266 if(*(value
.v_pointer
) == NULL
)
4267 *(value
.v_pointer
) = lttv_toolbars_new();
4268 instance_toolbar
= (LttvToolbars
*)*(value
.v_pointer
);
4270 /* Add missing menu entries to window instance */
4271 for(i
=0;i
<global_menu
->len
;i
++) {
4272 menu_item
= &g_array_index(global_menu
, LttvMenuClosure
, i
);
4274 //add menu_item to window instance;
4275 constructor
= menu_item
->con
;
4276 tool_menu_title_menu
= lookup_widget(mw
->mwindow
,"ToolMenuTitle_menu");
4278 gtk_menu_item_new_with_mnemonic (menu_item
->menu_text
);
4279 gtk_container_add (GTK_CONTAINER (tool_menu_title_menu
),
4281 g_signal_connect ((gpointer
) new_widget
, "activate",
4282 G_CALLBACK (insert_viewer_wrap
),
4284 gtk_widget_show (new_widget
);
4285 lttv_menus_add(instance_menu
, menu_item
->con
,
4286 menu_item
->menu_path
,
4287 menu_item
->menu_text
,
4292 /* Add missing toolbar entries to window instance */
4293 for(i
=0;i
<global_toolbar
->len
;i
++) {
4294 toolbar_item
= &g_array_index(global_toolbar
, LttvToolbarClosure
, i
);
4296 //add toolbar_item to window instance;
4297 constructor
= toolbar_item
->con
;
4298 tool_menu_title_menu
= lookup_widget(mw
->mwindow
,"MToolbar1");
4299 pixbuf
= gdk_pixbuf_new_from_xpm_data((const char**)toolbar_item
->pixmap
);
4300 pixmap
= gtk_image_new_from_pixbuf(pixbuf
);
4302 gtk_toolbar_append_element (GTK_TOOLBAR (tool_menu_title_menu
),
4303 GTK_TOOLBAR_CHILD_BUTTON
,
4306 toolbar_item
->tooltip
, NULL
,
4307 pixmap
, NULL
, NULL
);
4308 gtk_label_set_use_underline(
4309 GTK_LABEL (((GtkToolbarChild
*) (
4310 g_list_last (GTK_TOOLBAR
4311 (tool_menu_title_menu
)->children
)->data
))->label
),
4313 gtk_container_set_border_width (GTK_CONTAINER (new_widget
), 1);
4314 g_signal_connect ((gpointer
) new_widget
,
4316 G_CALLBACK (insert_viewer_wrap
),
4318 gtk_widget_show (new_widget
);
4320 lttv_toolbars_add(instance_toolbar
, toolbar_item
->con
,
4321 toolbar_item
->tooltip
,
4322 toolbar_item
->pixmap
,
4330 /* Create a main window
4333 void construct_main_window(MainWindow
* parent
)
4335 g_debug("construct_main_window()");
4336 GtkWidget
* new_window
; /* New generated main window */
4337 MainWindow
* new_m_window
;/* New main window structure */
4338 GtkNotebook
* notebook
;
4339 LttvIAttribute
*attributes
=
4340 LTTV_IATTRIBUTE(g_object_new(LTTV_ATTRIBUTE_TYPE
, NULL
));
4341 LttvAttributeValue value
;
4344 new_m_window
= g_new(MainWindow
, 1);
4346 // Add the object's information to the module's array
4347 g_main_window_list
= g_slist_append(g_main_window_list
, new_m_window
);
4349 new_window
= create_MWindow();
4350 gtk_widget_show (new_window
);
4352 new_m_window
->mwindow
= new_window
;
4353 new_m_window
->attributes
= attributes
;
4355 g_assert(lttv_iattribute_find_by_path(attributes
,
4356 "viewers/menu", LTTV_POINTER
, &value
));
4357 *(value
.v_pointer
) = lttv_menus_new();
4359 g_assert(lttv_iattribute_find_by_path(attributes
,
4360 "viewers/toolbar", LTTV_POINTER
, &value
));
4361 *(value
.v_pointer
) = lttv_toolbars_new();
4363 add_all_menu_toolbar_constructors(new_m_window
, NULL
);
4365 g_object_set_data_full(G_OBJECT(new_window
),
4367 (gpointer
)new_m_window
,
4368 (GDestroyNotify
)g_free
);
4369 //create a default tab
4370 notebook
= (GtkNotebook
*)lookup_widget(new_m_window
->mwindow
, "MNotebook");
4371 if(notebook
== NULL
){
4372 g_printf("Notebook does not exist\n");
4375 //gtk_notebook_popup_enable (GTK_NOTEBOOK(notebook));
4376 //for now there is no name field in LttvTraceset structure
4377 //Use "Traceset" as the label for the default tab
4379 GtkWidget
* parent_notebook
= lookup_widget(parent
->mwindow
, "MNotebook");
4380 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(parent_notebook
),
4381 gtk_notebook_get_current_page(GTK_NOTEBOOK(parent_notebook
)));
4387 parent_tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
4389 new_tab
= create_tab(new_m_window
, parent_tab
, notebook
, "Traceset");
4391 new_tab
= create_tab(new_m_window
, NULL
, notebook
, "Traceset");
4392 /* First window, use command line trace */
4393 if(g_init_trace
!= NULL
){
4394 lttvwindow_add_trace(new_tab
,
4398 LttvTraceset
*traceset
= new_tab
->traceset_info
->traceset
;
4399 SetTraceset(new_tab
, traceset
);
4401 /* Insert default viewers */
4403 LttvAttributeType type
;
4404 LttvAttributeName name
;
4405 LttvAttributeValue value
;
4406 LttvAttribute
*attribute
;
4408 LttvIAttribute
*attributes_global
=
4409 LTTV_IATTRIBUTE(lttv_global_attributes());
4411 g_assert(attribute
=
4412 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
4413 LTTV_IATTRIBUTE(attributes_global
),
4414 LTTV_VIEWER_CONSTRUCTORS
)));
4416 name
= g_quark_from_string("guievents");
4417 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
4419 if(type
== LTTV_POINTER
) {
4420 lttvwindow_viewer_constructor viewer_constructor
=
4421 (lttvwindow_viewer_constructor
)*value
.v_pointer
;
4422 insert_viewer(new_window
, viewer_constructor
);
4425 name
= g_quark_from_string("guicontrolflow");
4426 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
4428 if(type
== LTTV_POINTER
) {
4429 lttvwindow_viewer_constructor viewer_constructor
=
4430 (lttvwindow_viewer_constructor
)*value
.v_pointer
;
4431 insert_viewer(new_window
, viewer_constructor
);
4434 name
= g_quark_from_string("guistatistics");
4435 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
4437 if(type
== LTTV_POINTER
) {
4438 lttvwindow_viewer_constructor viewer_constructor
=
4439 (lttvwindow_viewer_constructor
)*value
.v_pointer
;
4440 insert_viewer(new_window
, viewer_constructor
);
4446 g_printf("There are now : %d windows\n",g_slist_length(g_main_window_list
));
4450 /* Free the memory occupied by a tab structure
4454 void tab_destructor(Tab
* tab
)
4456 int i
, nb
, ref_count
;
4459 gtk_object_destroy(GTK_OBJECT(tab
->tooltips
));
4462 g_object_unref(tab
->attributes
);
4464 if(tab
->interrupted_state
)
4465 g_object_unref(tab
->interrupted_state
);
4468 if(tab
->traceset_info
->traceset_context
!= NULL
){
4469 //remove state update hooks
4470 lttv_state_remove_event_hooks(
4471 (LttvTracesetState
*)tab
->traceset_info
->
4473 lttv_context_fini(LTTV_TRACESET_CONTEXT(tab
->traceset_info
->
4475 g_object_unref(tab
->traceset_info
->traceset_context
);
4477 if(tab
->traceset_info
->traceset
!= NULL
) {
4478 nb
= lttv_traceset_number(tab
->traceset_info
->traceset
);
4479 for(i
= 0 ; i
< nb
; i
++) {
4480 trace
= lttv_traceset_get(tab
->traceset_info
->traceset
, i
);
4481 ref_count
= lttv_trace_get_ref_number(trace
);
4483 ltt_trace_close(lttv_trace(trace
));
4487 lttv_traceset_destroy(tab
->traceset_info
->traceset
);
4488 /* Remove the idle events requests processing function of the tab */
4489 g_idle_remove_by_data(tab
);
4491 g_slist_free(tab
->events_requests
);
4492 g_free(tab
->traceset_info
);
4497 /* Create a tab and insert it into the current main window
4500 Tab
* create_tab(MainWindow
* mw
, Tab
*copy_tab
,
4501 GtkNotebook
* notebook
, char * label
)
4507 //create a new tab data structure
4510 //construct and initialize the traceset_info
4511 tab
->traceset_info
= g_new(TracesetInfo
,1);
4514 tab
->traceset_info
->traceset
=
4515 lttv_traceset_copy(copy_tab
->traceset_info
->traceset
);
4517 tab
->traceset_info
->traceset
= lttv_traceset_new();
4521 lttv_attribute_write_xml(
4522 lttv_traceset_attribute(tab
->traceset_info
->traceset
),
4528 tab
->time_manager_lock
= FALSE
;
4529 tab
->current_time_manager_lock
= FALSE
;
4531 //FIXME copy not implemented in lower level
4532 tab
->traceset_info
->traceset_context
=
4533 g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
4534 g_assert(tab
->traceset_info
->traceset_context
!= NULL
);
4536 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
),
4537 tab
->traceset_info
->traceset
);
4538 //add state update hooks
4539 lttv_state_add_event_hooks(
4540 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
4542 //determine the current_time and time_window of the tab
4544 if(copy_tab
!= NULL
){
4545 tab
->time_window
= copy_tab
->time_window
;
4546 tab
->current_time
= copy_tab
->current_time
;
4548 tab
->time_window
.start_time
=
4549 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
4550 time_span
.start_time
;
4551 if(DEFAULT_TIME_WIDTH_S
<
4552 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
4553 time_span
.end_time
.tv_sec
)
4554 tmp_time
.tv_sec
= DEFAULT_TIME_WIDTH_S
;
4557 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
4558 time_span
.end_time
.tv_sec
;
4559 tmp_time
.tv_nsec
= 0;
4560 tab
->time_window
.time_width
= tmp_time
;
4561 tab
->current_time
.tv_sec
=
4562 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
4563 time_span
.start_time
.tv_sec
;
4564 tab
->current_time
.tv_nsec
=
4565 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
4566 time_span
.start_time
.tv_nsec
;
4569 tab
->attributes
= LTTV_IATTRIBUTE(g_object_new(LTTV_ATTRIBUTE_TYPE
, NULL
));
4570 tab
->interrupted_state
= g_object_new(LTTV_ATTRIBUTE_TYPE
, NULL
);
4572 tab
->vbox
= gtk_vbox_new(FALSE
, 2);
4573 tab
->viewer_container
= gtk_vbox_new(TRUE
, 2);
4574 tab
->scrollbar
= gtk_hscrollbar_new(NULL
);
4575 //tab->multivpaned = gtk_multi_vpaned_new();
4577 gtk_box_pack_start(GTK_BOX(tab
->vbox
),
4578 tab
->viewer_container
,
4580 TRUE
, /* Give the extra space to the child */
4581 0); /* No padding */
4583 /* Create the timebar */
4585 tab
->MTimebar
= gtk_hbox_new(FALSE
, 2);
4586 gtk_widget_show(tab
->MTimebar
);
4587 tab
->tooltips
= gtk_tooltips_new();
4589 tab
->MEventBox1a
= gtk_event_box_new();
4590 gtk_widget_show(tab
->MEventBox1a
);
4591 gtk_tooltips_set_tip(tab
->tooltips
, tab
->MEventBox1a
,
4592 "Paste Start and End Times Here", "");
4593 tab
->MText1a
= gtk_label_new("Time Frame ");
4594 gtk_widget_show(tab
->MText1a
);
4595 gtk_container_add(GTK_CONTAINER(tab
->MEventBox1a
), tab
->MText1a
);
4596 tab
->MEventBox1b
= gtk_event_box_new();
4597 gtk_widget_show(tab
->MEventBox1b
);
4598 gtk_tooltips_set_tip(tab
->tooltips
, tab
->MEventBox1b
,
4599 "Paste Start Time Here", "");
4600 tab
->MText1b
= gtk_label_new("start: ");
4601 gtk_widget_show(tab
->MText1b
);
4602 gtk_container_add(GTK_CONTAINER(tab
->MEventBox1b
), tab
->MText1b
);
4603 tab
->MText2
= gtk_label_new("s");
4604 gtk_widget_show(tab
->MText2
);
4605 tab
->MText3a
= gtk_label_new("ns");
4606 gtk_widget_show(tab
->MText3a
);
4607 tab
->MEventBox3b
= gtk_event_box_new();
4608 gtk_widget_show(tab
->MEventBox3b
);
4609 gtk_tooltips_set_tip(tab
->tooltips
, tab
->MEventBox3b
,
4610 "Paste End Time Here", "");
4611 tab
->MText3b
= gtk_label_new("end:");
4612 gtk_widget_show(tab
->MText3b
);
4613 gtk_container_add(GTK_CONTAINER(tab
->MEventBox3b
), tab
->MText3b
);
4614 tab
->MText4
= gtk_label_new("s");
4615 gtk_widget_show(tab
->MText4
);
4616 tab
->MText5a
= gtk_label_new("ns");
4617 gtk_widget_show(tab
->MText5a
);
4618 tab
->MEventBox5b
= gtk_event_box_new();
4619 gtk_widget_show(tab
->MEventBox5b
);
4620 gtk_tooltips_set_tip(tab
->tooltips
, tab
->MEventBox5b
,
4621 "Paste Current Time Here", "");
4622 tab
->MText5b
= gtk_label_new("Current Time:");
4623 gtk_widget_show(tab
->MText5b
);
4624 gtk_container_add(GTK_CONTAINER(tab
->MEventBox5b
), tab
->MText5b
);
4625 tab
->MText6
= gtk_label_new("s");
4626 gtk_widget_show(tab
->MText6
);
4627 tab
->MText7
= gtk_label_new("ns");
4628 gtk_widget_show(tab
->MText7
);
4630 tab
->MEntry1
= gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4631 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab
->MEntry1
),0);
4632 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab
->MEntry1
),TRUE
);
4633 gtk_widget_show(tab
->MEntry1
);
4634 tab
->MEntry2
= gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4635 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab
->MEntry2
),0);
4636 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab
->MEntry2
),TRUE
);
4637 gtk_widget_show(tab
->MEntry2
);
4638 tab
->MEntry3
= gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4639 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab
->MEntry3
),0);
4640 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab
->MEntry3
),TRUE
);
4641 gtk_widget_show(tab
->MEntry3
);
4642 tab
->MEntry4
= gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4643 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab
->MEntry4
),0);
4644 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab
->MEntry4
),TRUE
);
4645 gtk_widget_show(tab
->MEntry4
);
4646 tab
->MEntry5
= gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4647 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab
->MEntry5
),0);
4648 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab
->MEntry5
),TRUE
);
4649 gtk_widget_show(tab
->MEntry5
);
4650 tab
->MEntry6
= gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4651 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab
->MEntry6
),0);
4652 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab
->MEntry6
),TRUE
);
4653 gtk_widget_show(tab
->MEntry6
);
4656 GtkWidget
*temp_widget
;
4658 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEventBox1a
, FALSE
,
4660 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEventBox1b
, FALSE
,
4662 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEntry1
, FALSE
, FALSE
, 0);
4663 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MText2
, FALSE
, FALSE
, 0);
4664 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEntry2
, FALSE
, FALSE
, 0);
4665 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MText3a
, FALSE
, FALSE
, 0);
4666 temp_widget
= gtk_vseparator_new();
4667 gtk_widget_show(temp_widget
);
4668 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), temp_widget
, FALSE
, FALSE
, 0);
4669 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEventBox3b
, FALSE
,
4671 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEntry3
, FALSE
, FALSE
, 0);
4672 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MText4
, FALSE
, FALSE
, 0);
4673 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEntry4
, FALSE
, FALSE
, 0);
4674 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MText5a
, FALSE
, FALSE
, 0);
4675 temp_widget
= gtk_vseparator_new();
4676 gtk_widget_show(temp_widget
);
4677 gtk_box_pack_end (GTK_BOX (tab
->MTimebar
), tab
->MText7
, FALSE
, FALSE
, 0);
4678 gtk_box_pack_end (GTK_BOX (tab
->MTimebar
), tab
->MEntry6
, FALSE
, FALSE
, 0);
4679 gtk_box_pack_end (GTK_BOX (tab
->MTimebar
), tab
->MText6
, FALSE
, FALSE
, 0);
4680 gtk_box_pack_end (GTK_BOX (tab
->MTimebar
), tab
->MEntry5
, FALSE
, FALSE
, 0);
4681 gtk_box_pack_end (GTK_BOX (tab
->MTimebar
), tab
->MEventBox5b
, FALSE
,
4683 gtk_box_pack_end (GTK_BOX (tab
->MTimebar
), temp_widget
, FALSE
, FALSE
, 0);
4686 //GtkWidget *test = gtk_button_new_with_label("drop");
4687 //gtk_button_set_relief(GTK_BUTTON(test), GTK_RELIEF_NONE);
4688 //gtk_widget_show(test);
4689 //gtk_box_pack_end(GTK_BOX (tab->MTimebar), test, FALSE, FALSE, 0);
4690 //gtk_widget_add_events(tab->MText1, GDK_ALL_EVENTS_MASK);//GDK_BUTTON_PRESS_MASK);
4691 /*GtkWidget *event_box = gtk_event_box_new();
4692 gtk_widget_show(event_box);
4693 gtk_tooltips_set_tip(tooltips, event_box,
4694 "Paste Current Time Here", "");
4695 gtk_box_pack_end(GTK_BOX (tab->MTimebar), event_box, FALSE, FALSE, 0);
4696 GtkWidget *test = gtk_label_new("drop");
4697 gtk_container_add(GTK_CONTAINER(event_box), test);
4698 gtk_widget_show(test);
4699 g_signal_connect (G_OBJECT(event_box),
4700 "button-press-event",
4701 G_CALLBACK (on_MText1_paste),
4705 g_signal_connect (G_OBJECT(tab
->MEventBox1a
),
4706 "button-press-event",
4707 G_CALLBACK (on_MEventBox1a_paste
),
4710 g_signal_connect (G_OBJECT(tab
->MEventBox1b
),
4711 "button-press-event",
4712 G_CALLBACK (on_MEventBox1b_paste
),
4714 g_signal_connect (G_OBJECT(tab
->MEventBox3b
),
4715 "button-press-event",
4716 G_CALLBACK (on_MEventBox3b_paste
),
4718 g_signal_connect (G_OBJECT(tab
->MEventBox5b
),
4719 "button-press-event",
4720 G_CALLBACK (on_MEventBox5b_paste
),
4724 gtk_box_pack_end(GTK_BOX(tab
->vbox
),
4726 FALSE
, /* Do not expand */
4727 FALSE
, /* Fill has no effect here (expand false) */
4728 0); /* No padding */
4730 gtk_box_pack_end(GTK_BOX(tab
->vbox
),
4732 FALSE
, /* Do not expand */
4733 FALSE
, /* Fill has no effect here (expand false) */
4734 0); /* No padding */
4736 g_object_set_data(G_OBJECT(tab
->viewer_container
), "focused_viewer", NULL
);
4742 // Display a label with a X
4743 GtkWidget *w_hbox = gtk_hbox_new(FALSE, 4);
4744 GtkWidget *w_label = gtk_label_new (label);
4745 GtkWidget *pixmap = create_pixmap(GTK_WIDGET(notebook), "close.png");
4746 GtkWidget *w_button = gtk_button_new ();
4747 gtk_container_add(GTK_CONTAINER(w_button), pixmap);
4748 //GtkWidget *w_button = gtk_button_new_with_label("x");
4750 gtk_button_set_relief(GTK_BUTTON(w_button), GTK_RELIEF_NONE);
4752 gtk_box_pack_start(GTK_BOX(w_hbox), w_label, TRUE, TRUE, 0);
4753 gtk_box_pack_end(GTK_BOX(w_hbox), w_button, FALSE,
4756 g_signal_connect_swapped (w_button, "clicked",
4757 G_CALLBACK (on_close_tab_X_clicked),
4760 gtk_widget_set_state(w_button, GTK_STATE_ACTIVE);
4762 gtk_widget_show (w_label);
4763 gtk_widget_show (pixmap);
4764 gtk_widget_show (w_button);
4765 gtk_widget_show (w_hbox);
4767 tab->label = w_hbox;
4771 tab
->label
= gtk_label_new (label
);
4773 gtk_widget_show(tab
->label
);
4774 gtk_widget_show(tab
->scrollbar
);
4775 gtk_widget_show(tab
->viewer_container
);
4776 gtk_widget_show(tab
->vbox
);
4777 //gtk_widget_show(tab->multivpaned);
4780 /* Start with empty events requests list */
4781 tab
->events_requests
= NULL
;
4782 tab
->events_request_pending
= FALSE
;
4784 g_object_set_data_full(
4785 G_OBJECT(tab
->vbox
),
4788 (GDestroyNotify
)tab_destructor
);
4790 g_signal_connect(G_OBJECT(tab
->scrollbar
), "value-changed",
4791 G_CALLBACK(scroll_value_changed_cb
), tab
);
4793 g_signal_connect ((gpointer
) tab
->MEntry1
, "value-changed",
4794 G_CALLBACK (on_MEntry1_value_changed
),
4796 g_signal_connect ((gpointer
) tab
->MEntry2
, "value-changed",
4797 G_CALLBACK (on_MEntry2_value_changed
),
4799 g_signal_connect ((gpointer
) tab
->MEntry3
, "value-changed",
4800 G_CALLBACK (on_MEntry3_value_changed
),
4802 g_signal_connect ((gpointer
) tab
->MEntry4
, "value-changed",
4803 G_CALLBACK (on_MEntry4_value_changed
),
4805 g_signal_connect ((gpointer
) tab
->MEntry5
, "value-changed",
4806 G_CALLBACK (on_MEntry5_value_changed
),
4808 g_signal_connect ((gpointer
) tab
->MEntry6
, "value-changed",
4809 G_CALLBACK (on_MEntry6_value_changed
),
4812 //g_signal_connect(G_OBJECT(tab->scrollbar), "changed",
4813 // G_CALLBACK(scroll_value_changed_cb), tab);
4816 //insert tab into notebook
4817 gtk_notebook_append_page(notebook
,
4820 list
= gtk_container_get_children(GTK_CONTAINER(notebook
));
4821 gtk_notebook_set_current_page(notebook
,g_list_length(list
)-1);
4822 // always show : not if(g_list_length(list)>1)
4823 gtk_notebook_set_show_tabs(notebook
, TRUE
);
4829 * execute_events_requests
4831 * Idle function that executes the pending requests for a tab.
4833 * @return return value : TRUE : keep the idle function, FALSE : remove it.
4835 gboolean
execute_events_requests(Tab
*tab
)
4837 return ( lttvwindow_process_pending_requests(tab
) );