1 /* This file is part of the Linux Trace Toolkit viewer
2 * Copyright (C) 2003-2004 XangXiu Yang, Mathieu Desnoyers
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License Version 2 as
6 * published by the Free Software Foundation;
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place - Suite 330, Boston,
23 #include <limits.h> // for PATH_MAX
31 #include "callbacks.h"
32 #include "interface.h"
34 #include <ltt/trace.h>
35 #include <ltt/facility.h>
37 #include <ltt/event.h>
38 #include <lttv/lttv.h>
39 #include <lttv/module.h>
40 #include <lttv/iattribute.h>
41 #include <lttv/stats.h>
42 #include <lttvwindow/mainwindow.h>
43 #include <lttvwindow/mainwindow-private.h>
44 #include <lttvwindow/menu.h>
45 #include <lttvwindow/toolbar.h>
46 #include <lttvwindow/lttvwindow.h>
47 #include <lttvwindow/lttvwindowtraces.h>
48 #include <lttvwindow/gtkdirsel.h>
49 #include <lttvwindow/lttvfilter.h>
52 #define DEFAULT_TIME_WIDTH_S 1
53 #define CLIP_BUF 256 // size of clipboard buffer
55 extern LttvTrace
*g_init_trace
;
58 /** Array containing instanced objects. */
59 extern GSList
* g_main_window_list
;
61 /** MD : keep old directory. */
62 static char remember_plugins_dir
[PATH_MAX
] = "";
63 static char remember_trace_dir
[PATH_MAX
] = "";
66 MainWindow
* get_window_data_struct(GtkWidget
* widget
);
67 char * get_load_module(char ** load_module_name
, int nb_module
);
68 char * get_unload_module(char ** loaded_module_name
, int nb_module
);
69 char * get_remove_trace(char ** all_trace_name
, int nb_trace
);
70 char * get_selection(char ** all_name
, int nb
, char *title
, char * column_title
);
71 gboolean
get_filter_selection(LttvTracesetSelector
*s
, char *title
, char * column_title
);
72 Tab
* create_tab(MainWindow
* mw
, Tab
*copy_tab
,
73 GtkNotebook
* notebook
, char * label
);
75 static void insert_viewer(GtkWidget
* widget
, lttvwindow_viewer_constructor constructor
);
76 void update_filter(LttvTracesetSelector
*s
, GtkTreeStore
*store
);
78 void checkbox_changed(GtkTreeView
*treeview
,
80 GtkTreeViewColumn
*arg2
,
82 void remove_trace_from_traceset_selector(GtkWidget
* paned
, unsigned i
);
83 void add_trace_into_traceset_selector(GtkWidget
* paned
, LttTrace
* trace
);
84 Tab
*create_new_tab(GtkWidget
* widget
, gpointer user_data
);
86 LttvTracesetSelector
* construct_traceset_selector(LttvTraceset
* traceset
);
88 static gboolean
lttvwindow_process_pending_requests(Tab
*tab
);
102 /* Construct a selector(filter), which will be associated with a viewer,
103 * and provides an interface for user to select interested events and traces
106 LttvTracesetSelector
* construct_traceset_selector(LttvTraceset
* traceset
)
108 LttvTracesetSelector
* s
;
109 LttvTraceSelector
* trace
;
110 LttvTracefileSelector
* tracefile
;
111 LttvEventtypeSelector
* eventtype
;
113 int nb_trace
, nb_tracefile
, nb_control
, nb_per_cpu
, nb_facility
, nb_event
;
120 s
= lttv_traceset_selector_new(lttv_traceset_name(traceset
));
121 nb_trace
= lttv_traceset_number(traceset
);
122 for(i
=0;i
<nb_trace
;i
++){
123 trace_v
= lttv_traceset_get(traceset
, i
);
124 t
= lttv_trace(trace_v
);
125 trace
= lttv_trace_selector_new(t
);
126 lttv_traceset_selector_trace_add(s
, trace
);
128 nb_facility
= ltt_trace_facility_number(t
);
129 for(k
=0;k
<nb_facility
;k
++){
130 fac
= ltt_trace_facility_get(t
,k
);
131 nb_event
= (int) ltt_facility_eventtype_number(fac
);
132 for(m
=0;m
<nb_event
;m
++){
133 et
= ltt_facility_eventtype_get(fac
,m
);
134 eventtype
= lttv_eventtype_selector_new(et
);
135 lttv_trace_selector_eventtype_add(trace
, eventtype
);
139 nb_control
= ltt_trace_control_tracefile_number(t
);
140 nb_per_cpu
= ltt_trace_per_cpu_tracefile_number(t
);
141 nb_tracefile
= nb_control
+ nb_per_cpu
;
143 for(j
= 0 ; j
< nb_tracefile
; j
++) {
145 tf
= ltt_trace_control_tracefile_get(t
, j
);
147 tf
= ltt_trace_per_cpu_tracefile_get(t
, j
- nb_control
);
148 tracefile
= lttv_tracefile_selector_new(tf
);
149 lttv_trace_selector_tracefile_add(trace
, tracefile
);
150 lttv_eventtype_selector_copy(trace
, tracefile
);
156 /* Pasting routines */
158 static void MEventBox1a_receive(GtkClipboard
*clipboard
,
162 if(text
== NULL
) return;
163 Tab
*tab
= (Tab
*)data
;
164 gchar buffer
[CLIP_BUF
];
165 gchar
*ptr
= buffer
, *ptr_ssec
, *ptr_snsec
, *ptr_esec
, *ptr_ensec
;
167 strncpy(buffer
, text
, CLIP_BUF
);
170 while(!isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
171 /* remove leading junk */
173 while(isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
174 /* read all the first number */
178 while(!isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
179 /* remove leading junk */
181 while(isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
182 /* read all the first number */
186 while(!isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
187 /* remove leading junk */
189 while(isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
190 /* read all the first number */
194 while(!isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
195 /* remove leading junk */
197 while(isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
198 /* read all the first number */
201 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry1
),
202 (double)strtoul(ptr_ssec
, NULL
, 10));
203 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry2
),
204 (double)strtoul(ptr_snsec
, NULL
, 10));
205 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry3
),
206 (double)strtoul(ptr_esec
, NULL
, 10));
207 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry4
),
208 (double)strtoul(ptr_ensec
, NULL
, 10));
211 static gboolean
on_MEventBox1a_paste(GtkWidget
*widget
, GdkEventButton
*event
,
214 Tab
*tab
= (Tab
*)data
;
216 GtkClipboard
*clip
= gtk_clipboard_get_for_display(gdk_display_get_default(),
217 GDK_SELECTION_PRIMARY
);
218 gtk_clipboard_request_text(clip
,
219 (GtkClipboardTextReceivedFunc
)MEventBox1a_receive
,
226 static void MEventBox1b_receive(GtkClipboard
*clipboard
,
230 if(text
== NULL
) return;
231 Tab
*tab
= (Tab
*)data
;
232 gchar buffer
[CLIP_BUF
];
233 gchar
*ptr
= buffer
, *ptr_sec
, *ptr_nsec
;
235 strncpy(buffer
, text
, CLIP_BUF
);
237 while(!isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
238 /* remove leading junk */
240 while(isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
241 /* read all the first number */
245 while(!isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
246 /* remove leading junk */
248 while(isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
249 /* read all the first number */
252 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry1
),
253 (double)strtoul(ptr_sec
, NULL
, 10));
254 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry2
),
255 (double)strtoul(ptr_nsec
, NULL
, 10));
259 static gboolean
on_MEventBox1b_paste(GtkWidget
*widget
, GdkEventButton
*event
,
262 Tab
*tab
= (Tab
*)data
;
264 GtkClipboard
*clip
= gtk_clipboard_get_for_display(gdk_display_get_default(),
265 GDK_SELECTION_PRIMARY
);
266 gtk_clipboard_request_text(clip
,
267 (GtkClipboardTextReceivedFunc
)MEventBox1b_receive
,
273 static void MEventBox3b_receive(GtkClipboard
*clipboard
,
277 if(text
== NULL
) return;
278 Tab
*tab
= (Tab
*)data
;
279 gchar buffer
[CLIP_BUF
];
280 gchar
*ptr
= buffer
, *ptr_sec
, *ptr_nsec
;
282 strncpy(buffer
, text
, CLIP_BUF
);
284 while(!isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
285 /* remove leading junk */
287 while(isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
288 /* read all the first number */
292 while(!isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
293 /* remove leading junk */
295 while(isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
296 /* read all the first number */
299 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry3
),
300 (double)strtoul(ptr_sec
, NULL
, 10));
301 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry4
),
302 (double)strtoul(ptr_nsec
, NULL
, 10));
306 static gboolean
on_MEventBox3b_paste(GtkWidget
*widget
, GdkEventButton
*event
,
309 Tab
*tab
= (Tab
*)data
;
311 GtkClipboard
*clip
= gtk_clipboard_get_for_display(gdk_display_get_default(),
312 GDK_SELECTION_PRIMARY
);
313 gtk_clipboard_request_text(clip
,
314 (GtkClipboardTextReceivedFunc
)MEventBox3b_receive
,
320 static void MEventBox5b_receive(GtkClipboard
*clipboard
,
324 if(text
== NULL
) return;
325 Tab
*tab
= (Tab
*)data
;
326 gchar buffer
[CLIP_BUF
];
327 gchar
*ptr
= buffer
, *ptr_sec
, *ptr_nsec
;
329 strncpy(buffer
, text
, CLIP_BUF
);
331 while(!isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
332 /* remove leading junk */
334 while(isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
335 /* read all the first number */
339 while(!isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
340 /* remove leading junk */
342 while(isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
343 /* read all the first number */
346 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry5
),
347 (double)strtoul(ptr_sec
, NULL
, 10));
348 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry6
),
349 (double)strtoul(ptr_nsec
, NULL
, 10));
353 static gboolean
on_MEventBox5b_paste(GtkWidget
*widget
, GdkEventButton
*event
,
356 Tab
*tab
= (Tab
*)data
;
358 GtkClipboard
*clip
= gtk_clipboard_get_for_display(gdk_display_get_default(),
359 GDK_SELECTION_PRIMARY
);
360 gtk_clipboard_request_text(clip
,
361 (GtkClipboardTextReceivedFunc
)MEventBox5b_receive
,
367 static gboolean
viewer_grab_focus(GtkWidget
*widget
, GdkEventButton
*event
,
370 GtkWidget
*viewer
= GTK_WIDGET(data
);
371 GtkWidget
*viewer_container
= gtk_widget_get_parent(viewer
);
373 g_debug("FOCUS GRABBED");
374 g_object_set_data(G_OBJECT(viewer_container
), "focused_viewer", viewer
);
379 static void connect_focus_recursive(GtkWidget
*widget
,
382 if(GTK_IS_CONTAINER(widget
)) {
383 gtk_container_forall(GTK_CONTAINER(widget
),
384 (GtkCallback
)connect_focus_recursive
,
388 if(GTK_IS_TREE_VIEW(widget
)) {
389 gtk_tree_view_set_headers_clickable(widget
, TRUE
);
391 gtk_widget_add_events(widget
, GDK_BUTTON_PRESS_MASK
);
392 g_signal_connect (G_OBJECT(widget
),
393 "button-press-event",
394 G_CALLBACK (viewer_grab_focus
),
398 /* insert_viewer function constructs an instance of a viewer first,
399 * then inserts the widget of the instance into the container of the
404 insert_viewer_wrap(GtkWidget
*menuitem
, gpointer user_data
)
408 insert_viewer((GtkWidget
*)menuitem
, (lttvwindow_viewer_constructor
)user_data
);
409 // selected_hook(&val);
413 /* internal functions */
414 void insert_viewer(GtkWidget
* widget
, lttvwindow_viewer_constructor constructor
)
416 GtkWidget
* viewer_container
;
417 MainWindow
* mw_data
= get_window_data_struct(widget
);
418 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
420 LttvTracesetSelector
* s
;
421 TimeInterval
* time_interval
;
422 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
423 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
427 tab
= create_new_tab(widget
, NULL
);
429 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
432 viewer_container
= tab
->viewer_container
;
434 s
= construct_traceset_selector(tab
->traceset_info
->traceset
);
435 viewer
= (GtkWidget
*)constructor(tab
);
438 //gtk_multivpaned_widget_add(GTK_MULTIVPANED(multivpaned), viewer);
440 gtk_box_pack_end(GTK_BOX(viewer_container
),
446 /* We want to connect the viewer_grab_focus to EVERY
447 * child of this widget. The little trick is to get each child
448 * of each GTK_CONTAINER, even subchildren.
450 connect_focus_recursive(viewer
, viewer
);
455 * Function to set/update traceset for the viewers
456 * @param tab viewer's tab
457 * @param traceset traceset of the main window.
459 * 0 : traceset updated
460 * 1 : no traceset hooks to update; not an error.
463 int SetTraceset(Tab
* tab
, LttvTraceset
*traceset
)
465 LttvTracesetContext
*tsc
=
466 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
467 TimeInterval time_span
= tsc
->time_span
;
468 TimeWindow new_time_window
;
469 LttTime new_current_time
;
471 /* Set the tab's time window and current time if
473 if(ltt_time_compare(tab
->time_window
.start_time
, time_span
.start_time
) < 0
474 || ltt_time_compare( ltt_time_add(tab
->time_window
.start_time
,
475 tab
->time_window
.time_width
),
476 time_span
.end_time
) > 0) {
477 new_time_window
.start_time
= time_span
.start_time
;
479 new_current_time
= time_span
.start_time
;
483 if(DEFAULT_TIME_WIDTH_S
< time_span
.end_time
.tv_sec
)
484 tmp_time
.tv_sec
= DEFAULT_TIME_WIDTH_S
;
486 tmp_time
.tv_sec
= time_span
.end_time
.tv_sec
;
487 tmp_time
.tv_nsec
= 0;
488 new_time_window
.time_width
= tmp_time
;
490 time_change_manager(tab
, new_time_window
);
491 current_time_change_manager(tab
, new_current_time
);
495 GtkAdjustment
*adjustment
= gtk_range_get_adjustment(GTK_RANGE(tab
->scrollbar
));
496 LttTime upper
= ltt_time_sub(time_span
.end_time
, time_span
.start_time
);
498 g_object_set(G_OBJECT(adjustment
),
502 ltt_time_to_double(upper
)
503 * NANOSECONDS_PER_SECOND
, /* upper */
505 ltt_time_to_double(tab
->time_window
.time_width
)
506 / SCROLL_STEP_PER_PAGE
507 * NANOSECONDS_PER_SECOND
, /* step increment */
509 ltt_time_to_double(tab
->time_window
.time_width
)
510 * NANOSECONDS_PER_SECOND
, /* page increment */
512 ltt_time_to_double(tab
->time_window
.time_width
)
513 * NANOSECONDS_PER_SECOND
, /* page size */
515 gtk_adjustment_changed(adjustment
);
517 g_object_set(G_OBJECT(adjustment
),
520 ltt_time_sub(tab
->time_window
.start_time
, time_span
.start_time
))
521 * NANOSECONDS_PER_SECOND
, /* value */
523 gtk_adjustment_value_changed(adjustment
);
525 /* set the time bar. The value callbacks will change their nsec themself */
527 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry1
),
528 (double)time_span
.start_time
.tv_sec
,
529 (double)time_span
.end_time
.tv_sec
);
532 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry3
),
533 (double)time_span
.start_time
.tv_sec
,
534 (double)time_span
.end_time
.tv_sec
);
536 /* current seconds */
537 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry5
),
538 (double)time_span
.start_time
.tv_sec
,
539 (double)time_span
.end_time
.tv_sec
);
542 /* Finally, call the update hooks of the viewers */
544 LttvAttributeValue value
;
548 g_assert( lttv_iattribute_find_by_path(tab
->attributes
,
549 "hooks/updatetraceset", LTTV_POINTER
, &value
));
551 tmp
= (LttvHooks
*)*(value
.v_pointer
);
552 if(tmp
== NULL
) retval
= 1;
553 else lttv_hooks_call(tmp
,traceset
);
560 * Function to set/update filter for the viewers
561 * @param tab viewer's tab
562 * @param filter filter of the main window.
565 * 0 : filters updated
566 * 1 : no filter hooks to update; not an error.
569 int SetFilter(Tab
* tab
, gpointer filter
)
572 LttvAttributeValue value
;
574 g_assert(lttv_iattribute_find_by_path(tab
->attributes
,
575 "hooks/updatefilter", LTTV_POINTER
, &value
));
577 tmp
= (LttvHooks
*)*(value
.v_pointer
);
579 if(tmp
== NULL
) return 1;
580 lttv_hooks_call(tmp
,filter
);
588 * Function to redraw each viewer belonging to the current tab
589 * @param tab viewer's tab
592 void update_traceset(Tab
*tab
)
594 LttvAttributeValue value
;
596 g_assert(lttv_iattribute_find_by_path(tab
->attributes
,
597 "hooks/updatetraceset", LTTV_POINTER
, &value
));
598 tmp
= (LttvHooks
*)*(value
.v_pointer
);
599 if(tmp
== NULL
) return;
600 lttv_hooks_call(tmp
, NULL
);
604 /* get_label function is used to get user input, it displays an input
605 * box, which allows user to input a string
608 void get_label_string (GtkWidget
* text
, gchar
* label
)
610 GtkEntry
* entry
= (GtkEntry
*)text
;
611 if(strlen(gtk_entry_get_text(entry
))!=0)
612 strcpy(label
,gtk_entry_get_text(entry
));
615 gboolean
get_label(MainWindow
* mw
, gchar
* str
, gchar
* dialogue_title
, gchar
* label_str
)
617 GtkWidget
* dialogue
;
622 dialogue
= gtk_dialog_new_with_buttons(dialogue_title
,NULL
,
624 GTK_STOCK_OK
,GTK_RESPONSE_ACCEPT
,
625 GTK_STOCK_CANCEL
,GTK_RESPONSE_REJECT
,
628 label
= gtk_label_new(label_str
);
629 gtk_widget_show(label
);
631 text
= gtk_entry_new();
632 gtk_widget_show(text
);
634 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialogue
)->vbox
), label
,TRUE
, TRUE
,0);
635 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialogue
)->vbox
), text
,FALSE
, FALSE
,0);
637 id
= gtk_dialog_run(GTK_DIALOG(dialogue
));
639 case GTK_RESPONSE_ACCEPT
:
640 get_label_string(text
,str
);
641 gtk_widget_destroy(dialogue
);
643 case GTK_RESPONSE_REJECT
:
645 gtk_widget_destroy(dialogue
);
652 /* get_window_data_struct function is actually a lookup function,
653 * given a widget which is in the tree of the main window, it will
654 * return the MainWindow data structure associated with main window
657 MainWindow
* get_window_data_struct(GtkWidget
* widget
)
660 MainWindow
* mw_data
;
662 mw
= lookup_widget(widget
, "MWindow");
664 g_printf("Main window does not exist\n");
668 mw_data
= (MainWindow
*) g_object_get_data(G_OBJECT(mw
),"main_window_data");
670 g_printf("Main window data does not exist\n");
677 /* create_new_window function, just constructs a new main window
680 void create_new_window(GtkWidget
* widget
, gpointer user_data
, gboolean clone
)
682 MainWindow
* parent
= get_window_data_struct(widget
);
685 g_printf("Clone : use the same traceset\n");
686 construct_main_window(parent
);
688 g_printf("Empty : traceset is set to NULL\n");
689 construct_main_window(NULL
);
693 /* Get the currently focused viewer.
694 * If no viewer is focused, use the first one.
696 * If no viewer available, return NULL.
698 GtkWidget
*viewer_container_focus(GtkWidget
*container
)
702 widget
= (GtkWidget
*)g_object_get_data(G_OBJECT(container
),
706 g_debug("no widget focused");
707 GList
*children
= gtk_container_get_children(GTK_CONTAINER(container
));
710 widget
= GTK_WIDGET(children
->data
);
711 g_object_set_data(G_OBJECT(container
),
721 gint
viewer_container_position(GtkWidget
*container
, GtkWidget
*child
)
724 if(child
== NULL
) return -1;
727 GValue value
= { 0, };
728 g_value_init(&value
, G_TYPE_INT
);
729 gtk_container_child_get_property(GTK_CONTAINER(container
),
733 pos
= g_value_get_int(&value
);
739 /* move_*_viewer functions move the selected view up/down in
743 void move_down_viewer(GtkWidget
* widget
, gpointer user_data
)
745 MainWindow
* mw
= get_window_data_struct(widget
);
746 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
748 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
749 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
755 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
758 //gtk_multivpaned_widget_move_up(GTK_MULTIVPANED(tab->multivpaned));
760 /* change the position in the vbox */
761 GtkWidget
*focus_widget
;
763 focus_widget
= viewer_container_focus(tab
->viewer_container
);
764 position
= viewer_container_position(tab
->viewer_container
, focus_widget
);
767 /* can move up one position */
768 gtk_box_reorder_child(GTK_BOX(tab
->viewer_container
),
775 void move_up_viewer(GtkWidget
* widget
, gpointer user_data
)
777 MainWindow
* mw
= get_window_data_struct(widget
);
778 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
780 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
781 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
787 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
790 //gtk_multivpaned_widget_move_down(GTK_MULTIVPANED(tab->multivpaned));
791 /* change the position in the vbox */
792 GtkWidget
*focus_widget
;
794 focus_widget
= viewer_container_focus(tab
->viewer_container
);
795 position
= viewer_container_position(tab
->viewer_container
, focus_widget
);
799 g_list_length(gtk_container_get_children(
800 GTK_CONTAINER(tab
->viewer_container
)))-1
802 /* can move down one position */
803 gtk_box_reorder_child(GTK_BOX(tab
->viewer_container
),
811 /* delete_viewer deletes the selected viewer in the current tab
814 void delete_viewer(GtkWidget
* widget
, gpointer user_data
)
816 MainWindow
* mw
= get_window_data_struct(widget
);
817 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
819 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
820 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
826 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
829 //gtk_multivpaned_widget_delete(GTK_MULTIVPANED(tab->multivpaned));
831 GtkWidget
*focus_widget
= viewer_container_focus(tab
->viewer_container
);
833 if(focus_widget
!= NULL
)
834 gtk_widget_destroy(focus_widget
);
836 g_object_set_data(G_OBJECT(tab
->viewer_container
), "focused_viewer", NULL
);
840 /* open_traceset will open a traceset saved in a file
841 * Right now, it is not finished yet, (not working)
845 void open_traceset(GtkWidget
* widget
, gpointer user_data
)
849 LttvTraceset
* traceset
;
850 MainWindow
* mw_data
= get_window_data_struct(widget
);
851 GtkFileSelection
* file_selector
=
852 (GtkFileSelection
*)gtk_file_selection_new("Select a traceset");
854 gtk_file_selection_hide_fileop_buttons(file_selector
);
856 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
858 case GTK_RESPONSE_ACCEPT
:
859 case GTK_RESPONSE_OK
:
860 dir
= gtk_file_selection_get_selections (file_selector
);
861 traceset
= lttv_traceset_load(dir
[0]);
862 g_printf("Open a trace set %s\n", dir
[0]);
865 case GTK_RESPONSE_REJECT
:
866 case GTK_RESPONSE_CANCEL
:
868 gtk_widget_destroy((GtkWidget
*)file_selector
);
874 static void events_request_free(EventsRequest
*events_request
)
876 if(events_request
== NULL
) return;
878 if(events_request
->start_position
!= NULL
)
879 lttv_traceset_context_position_destroy(events_request
->start_position
);
880 if(events_request
->end_position
!= NULL
)
881 lttv_traceset_context_position_destroy(events_request
->end_position
);
882 if(events_request
->before_chunk_traceset
!= NULL
)
883 lttv_hooks_destroy(events_request
->before_chunk_traceset
);
884 if(events_request
->before_chunk_trace
!= NULL
)
885 lttv_hooks_destroy(events_request
->before_chunk_trace
);
886 if(events_request
->before_chunk_tracefile
!= NULL
)
887 lttv_hooks_destroy(events_request
->before_chunk_tracefile
);
888 if(events_request
->event
!= NULL
)
889 lttv_hooks_destroy(events_request
->event
);
890 if(events_request
->event_by_id
!= NULL
)
891 lttv_hooks_by_id_destroy(events_request
->event_by_id
);
892 if(events_request
->after_chunk_tracefile
!= NULL
)
893 lttv_hooks_destroy(events_request
->after_chunk_tracefile
);
894 if(events_request
->after_chunk_trace
!= NULL
)
895 lttv_hooks_destroy(events_request
->after_chunk_trace
);
896 if(events_request
->after_chunk_traceset
!= NULL
)
897 lttv_hooks_destroy(events_request
->after_chunk_traceset
);
898 if(events_request
->before_request
!= NULL
)
899 lttv_hooks_destroy(events_request
->before_request
);
900 if(events_request
->after_request
!= NULL
)
901 lttv_hooks_destroy(events_request
->after_request
);
903 g_free(events_request
);
908 /* lttvwindow_process_pending_requests
910 * This internal function gets called by g_idle, taking care of the pending
911 * requests. It is responsible for concatenation of time intervals and position
912 * requests. It does it with the following algorithm organizing process traceset
913 * calls. Here is the detailed description of the way it works :
915 * - Events Requests Servicing Algorithm
917 * Data structures necessary :
919 * List of requests added to context : list_in
920 * List of requests not added to context : list_out
925 * list_out : many events requests
927 * FIXME : insert rest of algorithm here
931 #define list_out tab->events_requests
933 gboolean
lttvwindow_process_pending_requests(Tab
*tab
)
935 unsigned max_nb_events
;
939 LttvTracesetContext
*tsc
;
940 LttvTracefileContext
*tfc
;
941 GSList
*list_in
= NULL
;
945 LttvTracesetContextPosition
*end_position
;
948 g_critical("Foreground processing : tab does not exist. Processing removed.");
952 /* There is no events requests pending : we should never have been called! */
953 g_assert(g_slist_length(list_out
) != 0);
955 tsc
= LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
957 //set the cursor to be X shape, indicating that the computer is busy in doing its job
959 new = gdk_cursor_new(GDK_X_CURSOR
);
960 widget
= lookup_widget(tab
->mw
->mwindow
, "MToolbar1");
961 win
= gtk_widget_get_parent_window(widget
);
962 gdk_window_set_cursor(win
, new);
963 gdk_cursor_unref(new);
964 gdk_window_stick(win
);
965 gdk_window_unstick(win
);
968 g_debug("SIZE events req len : %d", g_slist_length(list_out
));
970 /* Preliminary check for no trace in traceset */
971 /* Unregister the routine if empty, empty list_out too */
972 if(lttv_traceset_number(tsc
->ts
) == 0) {
974 /* - For each req in list_out */
975 GSList
*iter
= list_out
;
977 while(iter
!= NULL
) {
979 gboolean remove
= FALSE
;
980 gboolean free_data
= FALSE
;
981 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
983 /* - Call end request for req */
984 if(events_request
->servicing
== TRUE
)
985 lttv_hooks_call(events_request
->after_request
, (gpointer
)tsc
);
987 /* - remove req from list_out */
988 /* Destroy the request */
995 GSList
*remove_iter
= iter
;
997 iter
= g_slist_next(iter
);
998 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
999 list_out
= g_slist_remove_link(list_out
, remove_iter
);
1000 } else { // not remove
1001 iter
= g_slist_next(iter
);
1006 /* 0.1 Lock Traces */
1011 iter_trace
<lttv_traceset_number(tsc
->ts
);
1013 LttvTrace
*trace_v
= lttv_traceset_get(tsc
->ts
, iter_trace
);
1015 if(lttvwindowtraces_lock(trace_v
) != 0) {
1016 g_critical("Foreground processing : Unable to get trace lock");
1017 return TRUE
; /* Cannot get lock, try later */
1022 /* 0.2 Seek tracefiles positions to context position */
1023 lttv_process_traceset_synchronize_tracefiles(tsc
);
1026 /* Events processing algorithm implementation */
1027 /* Warning : the gtk_events_pending takes a LOT of cpu time. So what we do
1028 * instead is to leave the control to GTK and take it back.
1030 /* A. Servicing loop */
1031 //while( (g_slist_length(list_in) != 0 || g_slist_length(list_out) != 0)) {
1032 if((g_slist_length(list_in
) != 0 || g_slist_length(list_out
) != 0)) {
1034 /* 1. If list_in is empty (need a seek) */
1035 if( g_slist_length(list_in
) == 0 ) {
1037 /* list in is empty, need a seek */
1039 /* 1.1 Add requests to list_in */
1040 GSList
*ltime
= NULL
;
1041 GSList
*lpos
= NULL
;
1042 GSList
*iter
= NULL
;
1044 /* 1.1.1 Find all time requests with the lowest start time in list_out
1047 if(g_slist_length(list_out
) > 0)
1048 ltime
= g_slist_append(ltime
, g_slist_nth_data(list_out
, 0));
1049 for(iter
=g_slist_nth(list_out
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
1050 /* Find all time requests with the lowest start time in list_out */
1051 guint index_ltime
= g_array_index(ltime
, guint
, 0);
1052 EventsRequest
*event_request_ltime
= (EventsRequest
*)g_slist_nth_data(ltime
, 0);
1053 EventsRequest
*event_request_list_out
= (EventsRequest
*)iter
->data
;
1056 comp
= ltt_time_compare(event_request_ltime
->start_time
,
1057 event_request_list_out
->start_time
);
1059 ltime
= g_slist_append(ltime
, event_request_list_out
);
1061 /* Remove all elements from ltime, and add current */
1062 while(ltime
!= NULL
)
1063 ltime
= g_slist_delete_link(ltime
, g_slist_nth(ltime
, 0));
1064 ltime
= g_slist_append(ltime
, event_request_list_out
);
1068 /* 1.1.2 Find all position requests with the lowest position in list_out
1071 if(g_slist_length(list_out
) > 0)
1072 lpos
= g_slist_append(lpos
, g_slist_nth_data(list_out
, 0));
1073 for(iter
=g_slist_nth(list_out
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
1074 /* Find all position requests with the lowest position in list_out */
1075 EventsRequest
*event_request_lpos
= (EventsRequest
*)g_slist_nth_data(lpos
, 0);
1076 EventsRequest
*event_request_list_out
= (EventsRequest
*)iter
->data
;
1079 if(event_request_lpos
->start_position
!= NULL
1080 && event_request_list_out
->start_position
!= NULL
)
1082 comp
= lttv_traceset_context_pos_pos_compare
1083 (event_request_lpos
->start_position
,
1084 event_request_list_out
->start_position
);
1089 lpos
= g_slist_append(lpos
, event_request_list_out
);
1091 /* Remove all elements from lpos, and add current */
1093 lpos
= g_slist_delete_link(lpos
, g_slist_nth(lpos
, 0));
1094 lpos
= g_slist_append(lpos
, event_request_list_out
);
1099 EventsRequest
*event_request_lpos
= (EventsRequest
*)g_slist_nth_data(lpos
, 0);
1100 EventsRequest
*event_request_ltime
= (EventsRequest
*)g_slist_nth_data(ltime
, 0);
1101 LttTime lpos_start_time
;
1103 if(event_request_lpos
!= NULL
1104 && event_request_lpos
->start_position
!= NULL
) {
1105 lpos_start_time
= lttv_traceset_context_position_get_time(
1106 event_request_lpos
->start_position
);
1109 /* 1.1.3 If lpos.start time < ltime */
1110 if(event_request_lpos
!= NULL
1111 && event_request_lpos
->start_position
!= NULL
1112 && ltt_time_compare(lpos_start_time
,
1113 event_request_ltime
->start_time
)<0) {
1114 /* Add lpos to list_in, remove them from list_out */
1115 for(iter
=lpos
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
1116 /* Add to list_in */
1117 EventsRequest
*event_request_lpos
=
1118 (EventsRequest
*)iter
->data
;
1120 list_in
= g_slist_append(list_in
, event_request_lpos
);
1121 /* Remove from list_out */
1122 list_out
= g_slist_remove(list_out
, event_request_lpos
);
1125 /* 1.1.4 (lpos.start time >= ltime) */
1126 /* Add ltime to list_in, remove them from list_out */
1128 for(iter
=ltime
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
1129 /* Add to list_in */
1130 EventsRequest
*event_request_ltime
=
1131 (EventsRequest
*)iter
->data
;
1133 list_in
= g_slist_append(list_in
, event_request_ltime
);
1134 /* Remove from list_out */
1135 list_out
= g_slist_remove(list_out
, event_request_ltime
);
1140 g_slist_free(ltime
);
1145 tfc
= lttv_traceset_context_get_current_tfc(tsc
);
1146 g_assert(g_slist_length(list_in
)>0);
1147 EventsRequest
*events_request
= g_slist_nth_data(list_in
, 0);
1150 /* 1.2.1 If first request in list_in is a time request */
1151 if(events_request
->start_position
== NULL
) {
1152 /* - If first req in list_in start time != current time */
1153 if(tfc
== NULL
|| ltt_time_compare(events_request
->start_time
,
1154 tfc
->timestamp
) != 0)
1155 /* - Seek to that time */
1156 g_debug("SEEK TIME : %lu, %lu", events_request
->start_time
.tv_sec
,
1157 events_request
->start_time
.tv_nsec
);
1158 //lttv_process_traceset_seek_time(tsc, events_request->start_time);
1159 lttv_state_traceset_seek_time_closest(LTTV_TRACESET_STATE(tsc
),
1160 events_request
->start_time
);
1162 /* Process the traceset with only state hooks */
1164 lttv_process_traceset_middle(tsc
,
1165 events_request
->start_time
,
1171 /* Else, the first request in list_in is a position request */
1172 /* If first req in list_in pos != current pos */
1173 g_assert(events_request
->start_position
!= NULL
);
1174 g_debug("SEEK POS time : %lu, %lu",
1175 lttv_traceset_context_position_get_time(
1176 events_request
->start_position
).tv_sec
,
1177 lttv_traceset_context_position_get_time(
1178 events_request
->start_position
).tv_nsec
);
1180 g_debug("SEEK POS context time : %lu, %lu",
1181 lttv_traceset_context_get_current_tfc(tsc
)->timestamp
.tv_sec
,
1182 lttv_traceset_context_get_current_tfc(tsc
)->timestamp
.tv_nsec
);
1183 g_assert(events_request
->start_position
!= NULL
);
1184 if(lttv_traceset_context_ctx_pos_compare(tsc
,
1185 events_request
->start_position
) != 0) {
1186 /* 1.2.2.1 Seek to that position */
1187 g_debug("SEEK POSITION");
1188 //lttv_process_traceset_seek_position(tsc, events_request->start_position);
1189 pos_time
= lttv_traceset_context_position_get_time(
1190 events_request
->start_position
);
1192 lttv_state_traceset_seek_time_closest(LTTV_TRACESET_STATE(tsc
),
1195 /* Process the traceset with only state hooks */
1197 lttv_process_traceset_middle(tsc
,
1200 events_request
->start_position
);
1201 g_assert(lttv_traceset_context_ctx_pos_compare(tsc
,
1202 events_request
->start_position
) == 0);
1209 /* 1.3 Add hooks and call before request for all list_in members */
1211 GSList
*iter
= NULL
;
1213 for(iter
=list_in
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
1214 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1215 /* 1.3.1 If !servicing */
1216 if(events_request
->servicing
== FALSE
) {
1217 /* - begin request hooks called
1218 * - servicing = TRUE
1220 lttv_hooks_call(events_request
->before_request
, (gpointer
)tsc
);
1221 events_request
->servicing
= TRUE
;
1223 /* 1.3.2 call before chunk
1224 * 1.3.3 events hooks added
1226 lttv_process_traceset_begin(tsc
, events_request
->before_chunk_traceset
,
1227 events_request
->before_chunk_trace
,
1228 events_request
->before_chunk_tracefile
,
1229 events_request
->event
,
1230 events_request
->event_by_id
);
1234 /* 2. Else, list_in is not empty, we continue a read */
1237 /* 2.0 For each req of list_in */
1238 GSList
*iter
= list_in
;
1240 while(iter
!= NULL
) {
1242 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1244 /* - Call before chunk
1245 * - events hooks added
1247 lttv_process_traceset_begin(tsc
, events_request
->before_chunk_traceset
,
1248 events_request
->before_chunk_trace
,
1249 events_request
->before_chunk_tracefile
,
1250 events_request
->event
,
1251 events_request
->event_by_id
);
1253 iter
= g_slist_next(iter
);
1258 tfc
= lttv_traceset_context_get_current_tfc(tsc
);
1260 /* 2.1 For each req of list_out */
1261 GSList
*iter
= list_out
;
1263 while(iter
!= NULL
) {
1265 gboolean remove
= FALSE
;
1266 gboolean free_data
= FALSE
;
1267 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1269 /* if req.start time == current context time
1270 * or req.start position == current position*/
1271 if( ltt_time_compare(events_request
->start_time
,
1272 tfc
->timestamp
) == 0
1274 (events_request
->start_position
!= NULL
1276 lttv_traceset_context_ctx_pos_compare(tsc
,
1277 events_request
->start_position
) == 0)
1279 /* - Add to list_in, remove from list_out */
1280 list_in
= g_slist_append(list_in
, events_request
);
1284 /* - If !servicing */
1285 if(events_request
->servicing
== FALSE
) {
1286 /* - begin request hooks called
1287 * - servicing = TRUE
1289 lttv_hooks_call(events_request
->before_request
, (gpointer
)tsc
);
1290 events_request
->servicing
= TRUE
;
1292 /* call before chunk
1293 * events hooks added
1295 lttv_process_traceset_begin(tsc
, events_request
->before_chunk_traceset
,
1296 events_request
->before_chunk_trace
,
1297 events_request
->before_chunk_tracefile
,
1298 events_request
->event
,
1299 events_request
->event_by_id
);
1305 GSList
*remove_iter
= iter
;
1307 iter
= g_slist_next(iter
);
1308 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
1309 list_out
= g_slist_remove_link(list_out
, remove_iter
);
1310 } else { // not remove
1311 iter
= g_slist_next(iter
);
1317 /* 3. Find end criterions */
1322 /* 3.1.1 Find lowest end time in list_in */
1323 g_assert(g_slist_length(list_in
)>0);
1324 end_time
= ((EventsRequest
*)g_slist_nth_data(list_in
,0))->end_time
;
1326 for(iter
=g_slist_nth(list_in
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
1327 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1329 if(ltt_time_compare(events_request
->end_time
,
1331 end_time
= events_request
->end_time
;
1334 /* 3.1.2 Find lowest start time in list_out */
1335 for(iter
=list_out
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
1336 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1338 if(ltt_time_compare(events_request
->start_time
,
1340 end_time
= events_request
->start_time
;
1345 /* 3.2 Number of events */
1347 /* 3.2.1 Find lowest number of events in list_in */
1350 end_nb_events
= ((EventsRequest
*)g_slist_nth_data(list_in
,0))->num_events
;
1352 for(iter
=g_slist_nth(list_in
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
1353 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1355 if(events_request
->num_events
< end_nb_events
)
1356 end_nb_events
= events_request
->num_events
;
1359 /* 3.2.2 Use min(CHUNK_NUM_EVENTS, min num events in list_in) as
1362 end_nb_events
= MIN(CHUNK_NUM_EVENTS
, end_nb_events
);
1366 /* 3.3 End position */
1368 /* 3.3.1 Find lowest end position in list_in */
1371 end_position
=((EventsRequest
*)g_slist_nth_data(list_in
,0))->end_position
;
1373 for(iter
=g_slist_nth(list_in
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
1374 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1376 if(events_request
->end_position
!= NULL
&& end_position
!= NULL
&&
1377 lttv_traceset_context_pos_pos_compare(events_request
->end_position
,
1379 end_position
= events_request
->end_position
;
1384 /* 3.3.2 Find lowest start position in list_out */
1387 for(iter
=list_out
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
1388 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1390 if(events_request
->end_position
!= NULL
&& end_position
!= NULL
&&
1391 lttv_traceset_context_pos_pos_compare(events_request
->end_position
,
1393 end_position
= events_request
->end_position
;
1398 /* 4. Call process traceset middle */
1399 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
);
1400 count
= lttv_process_traceset_middle(tsc
, end_time
, end_nb_events
, end_position
);
1402 tfc
= lttv_traceset_context_get_current_tfc(tsc
);
1404 g_debug("Context time after middle : %lu, %lu", tfc
->timestamp
.tv_sec
,
1405 tfc
->timestamp
.tv_nsec
);
1407 g_debug("End of trace reached after middle.");
1411 /* 5. After process traceset middle */
1412 tfc
= lttv_traceset_context_get_current_tfc(tsc
);
1414 /* - if current context time > traceset.end time */
1415 if(tfc
== NULL
|| ltt_time_compare(tfc
->timestamp
,
1416 tsc
->time_span
.end_time
) > 0) {
1417 /* - For each req in list_in */
1418 GSList
*iter
= list_in
;
1420 while(iter
!= NULL
) {
1422 gboolean remove
= FALSE
;
1423 gboolean free_data
= FALSE
;
1424 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1426 /* - Remove events hooks for req
1427 * - Call end chunk for req
1429 lttv_process_traceset_end(tsc
, events_request
->after_chunk_traceset
,
1430 events_request
->after_chunk_trace
,
1431 events_request
->after_chunk_tracefile
,
1432 events_request
->event
,
1433 events_request
->event_by_id
);
1434 /* - Call end request for req */
1435 lttv_hooks_call(events_request
->after_request
, (gpointer
)tsc
);
1437 /* - remove req from list_in */
1438 /* Destroy the request */
1445 GSList
*remove_iter
= iter
;
1447 iter
= g_slist_next(iter
);
1448 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
1449 list_in
= g_slist_remove_link(list_in
, remove_iter
);
1450 } else { // not remove
1451 iter
= g_slist_next(iter
);
1456 /* 5.1 For each req in list_in */
1457 GSList
*iter
= list_in
;
1459 while(iter
!= NULL
) {
1461 gboolean remove
= FALSE
;
1462 gboolean free_data
= FALSE
;
1463 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1465 /* - Remove events hooks for req
1466 * - Call end chunk for req
1468 lttv_process_traceset_end(tsc
, events_request
->after_chunk_traceset
,
1469 events_request
->after_chunk_trace
,
1470 events_request
->after_chunk_tracefile
,
1471 events_request
->event
,
1472 events_request
->event_by_id
);
1474 /* - req.num -= count */
1475 g_assert(events_request
->num_events
>= count
);
1476 events_request
->num_events
-= count
;
1478 g_assert(tfc
!= NULL
);
1479 /* - if req.num == 0
1481 * current context time >= req.end time
1483 * req.end pos == current pos
1485 * req.stop_flag == TRUE
1487 if( events_request
->num_events
== 0
1489 events_request
->stop_flag
== TRUE
1491 ltt_time_compare(tfc
->timestamp
,
1492 events_request
->end_time
) >= 0
1494 (events_request
->end_position
!= NULL
1496 lttv_traceset_context_ctx_pos_compare(tsc
,
1497 events_request
->end_position
) == 0)
1500 g_assert(events_request
->servicing
== TRUE
);
1501 /* - Call end request for req
1502 * - remove req from list_in */
1503 lttv_hooks_call(events_request
->after_request
, (gpointer
)tsc
);
1504 /* - remove req from list_in */
1505 /* Destroy the request */
1513 GSList
*remove_iter
= iter
;
1515 iter
= g_slist_next(iter
);
1516 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
1517 list_in
= g_slist_remove_link(list_in
, remove_iter
);
1518 } else { // not remove
1519 iter
= g_slist_next(iter
);
1525 /* End of removed servicing loop : leave control to GTK instead. */
1526 // if(gtk_events_pending()) break;
1529 /* B. When interrupted between chunks */
1532 GSList
*iter
= list_in
;
1534 /* 1. for each request in list_in */
1535 while(iter
!= NULL
) {
1537 gboolean remove
= FALSE
;
1538 gboolean free_data
= FALSE
;
1539 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1541 /* 1.1. Use current postition as start position */
1542 if(events_request
->start_position
!= NULL
)
1543 lttv_traceset_context_position_destroy(events_request
->start_position
);
1544 events_request
->start_position
= lttv_traceset_context_position_new();
1545 lttv_traceset_context_position_save(tsc
, events_request
->start_position
);
1547 /* 1.2. Remove start time */
1548 events_request
->start_time
= ltt_time_infinite
;
1550 /* 1.3. Move from list_in to list_out */
1553 list_out
= g_slist_append(list_out
, events_request
);
1558 GSList
*remove_iter
= iter
;
1560 iter
= g_slist_next(iter
);
1561 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
1562 list_in
= g_slist_remove_link(list_in
, remove_iter
);
1563 } else { // not remove
1564 iter
= g_slist_next(iter
);
1571 /* C Unlock Traces */
1573 //lttv_process_traceset_get_sync_data(tsc);
1578 iter_trace
<lttv_traceset_number(tsc
->ts
);
1580 LttvTrace
*trace_v
= lttv_traceset_get(tsc
->ts
, iter_trace
);
1582 lttvwindowtraces_unlock(trace_v
);
1587 //set the cursor back to normal
1588 gdk_window_set_cursor(win
, NULL
);
1591 g_assert(g_slist_length(list_in
) == 0);
1593 if( g_slist_length(list_out
) == 0 ) {
1594 /* Put tab's request pending flag back to normal */
1595 tab
->events_request_pending
= FALSE
;
1596 g_debug("remove the idle fct");
1597 return FALSE
; /* Remove the idle function */
1599 g_debug("leave the idle fct");
1600 return TRUE
; /* Leave the idle function */
1602 /* We do not use simili-round-robin, it may require to read 1 meg buffers
1603 * again and again if many tracesets use the same tracefiles. */
1604 /* Hack for round-robin idle functions */
1605 /* It will put the idle function at the end of the pool */
1606 /*g_idle_add_full((G_PRIORITY_HIGH_IDLE + 21),
1607 (GSourceFunc)execute_events_requests,
1617 /* add_trace_into_traceset_selector, each instance of a viewer has an associated
1618 * selector (filter), when a trace is added into traceset, the selector should
1619 * reflect the change. The function is used to update the selector
1622 void add_trace_into_traceset_selector(GtkWidget
* paned
, LttTrace
* t
)
1624 int j
, k
, m
, nb_tracefile
, nb_control
, nb_per_cpu
, nb_facility
, nb_event
;
1625 LttvTracesetSelector
* s
;
1626 LttvTraceSelector
* trace
;
1627 LttvTracefileSelector
* tracefile
;
1628 LttvEventtypeSelector
* eventtype
;
1634 w
= gtk_multivpaned_get_first_widget(GTK_MULTIVPANED(paned
));
1636 s
= g_object_get_data(G_OBJECT(w
), "Traceset_Selector");
1639 trace
= lttv_trace_selector_new(t
);
1640 lttv_traceset_selector_trace_add(s
, trace
);
1642 nb_facility
= ltt_trace_facility_number(t
);
1643 for(k
=0;k
<nb_facility
;k
++){
1644 fac
= ltt_trace_facility_get(t
,k
);
1645 nb_event
= (int) ltt_facility_eventtype_number(fac
);
1646 for(m
=0;m
<nb_event
;m
++){
1647 et
= ltt_facility_eventtype_get(fac
,m
);
1648 eventtype
= lttv_eventtype_selector_new(et
);
1649 lttv_trace_selector_eventtype_add(trace
, eventtype
);
1653 nb_control
= ltt_trace_control_tracefile_number(t
);
1654 nb_per_cpu
= ltt_trace_per_cpu_tracefile_number(t
);
1655 nb_tracefile
= nb_control
+ nb_per_cpu
;
1657 for(j
= 0 ; j
< nb_tracefile
; j
++) {
1659 tf
= ltt_trace_control_tracefile_get(t
, j
);
1661 tf
= ltt_trace_per_cpu_tracefile_get(t
, j
- nb_control
);
1662 tracefile
= lttv_tracefile_selector_new(tf
);
1663 lttv_trace_selector_tracefile_add(trace
, tracefile
);
1664 lttv_eventtype_selector_copy(trace
, tracefile
);
1666 }else g_warning("Module does not support filtering\n");
1668 w
= gtk_multivpaned_get_next_widget(GTK_MULTIVPANED(paned
));
1673 static void lttvwindow_add_trace(Tab
*tab
, LttvTrace
*trace_v
)
1675 LttvTraceset
*traceset
= tab
->traceset_info
->traceset
;
1677 guint num_traces
= lttv_traceset_number(traceset
);
1679 //Verify if trace is already present.
1680 for(i
=0; i
<num_traces
; i
++)
1682 LttvTrace
* trace
= lttv_traceset_get(traceset
, i
);
1683 if(trace
== trace_v
)
1687 //Keep a reference to the traces so they are not freed.
1688 for(i
=0; i
<lttv_traceset_number(traceset
); i
++)
1690 LttvTrace
* trace
= lttv_traceset_get(traceset
, i
);
1691 lttv_trace_ref(trace
);
1694 //remove state update hooks
1695 lttv_state_remove_event_hooks(
1696 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1698 lttv_context_fini(LTTV_TRACESET_CONTEXT(
1699 tab
->traceset_info
->traceset_context
));
1700 g_object_unref(tab
->traceset_info
->traceset_context
);
1702 lttv_traceset_add(traceset
, trace_v
);
1703 lttv_trace_ref(trace_v
); /* local ref */
1705 /* Create new context */
1706 tab
->traceset_info
->traceset_context
=
1707 g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
1709 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->
1714 //add state update hooks
1715 lttv_state_add_event_hooks(
1716 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1717 //Remove local reference to the traces.
1718 for(i
=0; i
<lttv_traceset_number(traceset
); i
++)
1720 LttvTrace
* trace
= lttv_traceset_get(traceset
, i
);
1721 lttv_trace_unref(trace
);
1725 //add_trace_into_traceset_selector(GTK_MULTIVPANED(tab->multivpaned), lttv_trace(trace_v));
1728 /* add_trace adds a trace into the current traceset. It first displays a
1729 * directory selection dialogue to let user choose a trace, then recreates
1730 * tracset_context, and redraws all the viewer of the current tab
1733 void add_trace(GtkWidget
* widget
, gpointer user_data
)
1736 LttvTrace
* trace_v
;
1737 LttvTraceset
* traceset
;
1739 char abs_path
[PATH_MAX
];
1742 MainWindow
* mw_data
= get_window_data_struct(widget
);
1743 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
1745 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
1746 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
1750 tab
= create_new_tab(widget
, NULL
);
1752 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
1755 GtkDirSelection
* file_selector
= (GtkDirSelection
*)gtk_dir_selection_new("Select a trace");
1756 gtk_dir_selection_hide_fileop_buttons(file_selector
);
1758 if(remember_trace_dir
[0] != '\0')
1759 gtk_dir_selection_set_filename(file_selector
, remember_trace_dir
);
1761 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
1763 case GTK_RESPONSE_ACCEPT
:
1764 case GTK_RESPONSE_OK
:
1765 dir
= gtk_dir_selection_get_dir (file_selector
);
1766 strncpy(remember_trace_dir
, dir
, PATH_MAX
);
1767 if(!dir
|| strlen(dir
) == 0){
1768 gtk_widget_destroy((GtkWidget
*)file_selector
);
1771 get_absolute_pathname(dir
, abs_path
);
1772 trace_v
= lttvwindowtraces_get_trace_by_name(abs_path
);
1773 if(trace_v
== NULL
) {
1774 trace
= ltt_trace_open(abs_path
);
1776 g_warning("cannot open trace %s", abs_path
);
1778 trace_v
= lttv_trace_new(trace
);
1779 lttvwindowtraces_add_trace(trace_v
);
1780 lttvwindow_add_trace(tab
, trace_v
);
1783 lttvwindow_add_trace(tab
, trace_v
);
1786 gtk_widget_destroy((GtkWidget
*)file_selector
);
1788 //update current tab
1789 //update_traceset(mw_data);
1791 /* Call the updatetraceset hooks */
1793 traceset
= tab
->traceset_info
->traceset
;
1794 SetTraceset(tab
, traceset
);
1795 // in expose now call_pending_read_hooks(mw_data);
1797 //lttvwindow_report_current_time(mw_data,&(tab->current_time));
1799 case GTK_RESPONSE_REJECT
:
1800 case GTK_RESPONSE_CANCEL
:
1802 gtk_widget_destroy((GtkWidget
*)file_selector
);
1808 /* remove_trace_into_traceset_selector, each instance of a viewer has an associated
1809 * selector (filter), when a trace is remove from traceset, the selector should
1810 * reflect the change. The function is used to update the selector
1813 void remove_trace_from_traceset_selector(GtkWidget
* paned
, unsigned i
)
1815 LttvTracesetSelector
* s
;
1816 LttvTraceSelector
* t
;
1819 w
= gtk_multivpaned_get_first_widget(GTK_MULTIVPANED(paned
));
1821 s
= g_object_get_data(G_OBJECT(w
), "Traceset_Selector");
1823 t
= lttv_traceset_selector_trace_get(s
,i
);
1824 lttv_traceset_selector_trace_remove(s
, i
);
1825 lttv_trace_selector_destroy(t
);
1826 }g_warning("Module dose not support filtering\n");
1827 w
= gtk_multivpaned_get_next_widget(GTK_MULTIVPANED(paned
));
1832 /* remove_trace removes a trace from the current traceset if all viewers in
1833 * the current tab are not interested in the trace. It first displays a
1834 * dialogue, which shows all traces in the current traceset, to let user choose
1835 * a trace, then it checks if all viewers unselect the trace, if it is true,
1836 * it will remove the trace, recreate the traceset_contex,
1837 * and redraws all the viewer of the current tab. If there is on trace in the
1838 * current traceset, it will delete all viewers of the current tab
1841 // MD : no filter version.
1842 void remove_trace(GtkWidget
*widget
, gpointer user_data
)
1845 LttvTrace
* trace_v
;
1846 LttvTraceset
* traceset
;
1847 gint i
, j
, nb_trace
, index
=-1;
1848 char ** name
, *remove_trace_name
;
1849 MainWindow
* mw_data
= get_window_data_struct(widget
);
1850 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
1852 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
1853 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
1859 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
1862 nb_trace
=lttv_traceset_number(tab
->traceset_info
->traceset
);
1863 name
= g_new(char*,nb_trace
);
1864 for(i
= 0; i
< nb_trace
; i
++){
1865 trace_v
= lttv_traceset_get(tab
->traceset_info
->traceset
, i
);
1866 trace
= lttv_trace(trace_v
);
1867 name
[i
] = ltt_trace_name(trace
);
1870 remove_trace_name
= get_remove_trace(name
, nb_trace
);
1873 if(remove_trace_name
){
1875 /* yuk, cut n paste from old code.. should be better (MD)*/
1876 for(i
= 0; i
<nb_trace
; i
++) {
1877 if(strcmp(remove_trace_name
,name
[i
]) == 0){
1882 traceset
= tab
->traceset_info
->traceset
;
1883 //Keep a reference to the traces so they are not freed.
1884 for(j
=0; j
<lttv_traceset_number(traceset
); j
++)
1886 LttvTrace
* trace
= lttv_traceset_get(traceset
, j
);
1887 lttv_trace_ref(trace
);
1890 //remove state update hooks
1891 lttv_state_remove_event_hooks(
1892 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1893 lttv_context_fini(LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
));
1894 g_object_unref(tab
->traceset_info
->traceset_context
);
1896 trace_v
= lttv_traceset_get(traceset
, index
);
1898 lttv_traceset_remove(traceset
, index
);
1899 lttv_trace_unref(trace_v
); // Remove local reference
1901 if(lttv_trace_get_ref_number(trace_v
) <= 1) {
1902 /* ref 1 : lttvwindowtraces only*/
1903 ltt_trace_close(lttv_trace(trace_v
));
1904 /* lttvwindowtraces_remove_trace takes care of destroying
1905 * the traceset linked with the trace_v and also of destroying
1906 * the trace_v at the same time.
1908 lttvwindowtraces_remove_trace(trace_v
);
1911 tab
->traceset_info
->traceset_context
=
1912 g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
1914 LTTV_TRACESET_CONTEXT(tab
->
1915 traceset_info
->traceset_context
),traceset
);
1916 //add state update hooks
1917 lttv_state_add_event_hooks(
1918 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1920 //Remove local reference to the traces.
1921 for(j
=0; j
<lttv_traceset_number(traceset
); j
++)
1923 LttvTrace
* trace
= lttv_traceset_get(traceset
, j
);
1924 lttv_trace_unref(trace
);
1927 SetTraceset(tab
, (gpointer
)traceset
);
1933 void remove_trace(GtkWidget
* widget
, gpointer user_data
)
1936 LttvTrace
* trace_v
;
1937 LttvTraceset
* traceset
;
1938 gint i
, j
, nb_trace
;
1939 char ** name
, *remove_trace_name
;
1940 MainWindow
* mw_data
= get_window_data_struct(widget
);
1941 LttvTracesetSelector
* s
;
1942 LttvTraceSelector
* t
;
1945 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
1947 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
1948 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
1954 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
1957 nb_trace
=lttv_traceset_number(tab
->traceset_info
->traceset
);
1958 name
= g_new(char*,nb_trace
);
1959 for(i
= 0; i
< nb_trace
; i
++){
1960 trace_v
= lttv_traceset_get(tab
->traceset_info
->traceset
, i
);
1961 trace
= lttv_trace(trace_v
);
1962 name
[i
] = ltt_trace_name(trace
);
1965 remove_trace_name
= get_remove_trace(name
, nb_trace
);
1967 if(remove_trace_name
){
1968 for(i
=0; i
<nb_trace
; i
++){
1969 if(strcmp(remove_trace_name
,name
[i
]) == 0){
1970 //unselect the trace from the current viewer
1972 w
= gtk_multivpaned_get_widget(GTK_MULTIVPANED(tab
->multivpaned
));
1974 s
= g_object_get_data(G_OBJECT(w
), "Traceset_Selector");
1976 t
= lttv_traceset_selector_trace_get(s
,i
);
1977 lttv_trace_selector_set_selected(t
, FALSE
);
1980 //check if other viewers select the trace
1981 w
= gtk_multivpaned_get_first_widget(GTK_MULTIVPANED(tab
->multivpaned
));
1983 s
= g_object_get_data(G_OBJECT(w
), "Traceset_Selector");
1985 t
= lttv_traceset_selector_trace_get(s
,i
);
1986 selected
= lttv_trace_selector_get_selected(t
);
1989 w
= gtk_multivpaned_get_next_widget(GTK_MULTIVPANED(tab
->multivpaned
));
1991 }else selected
= FALSE
;
1993 //if no viewer selects the trace, remove it
1995 remove_trace_from_traceset_selector(GTK_MULTIVPANED(tab
->multivpaned
), i
);
1997 traceset
= tab
->traceset_info
->traceset
;
1998 //Keep a reference to the traces so they are not freed.
1999 for(j
=0; j
<lttv_traceset_number(traceset
); j
++)
2001 LttvTrace
* trace
= lttv_traceset_get(traceset
, j
);
2002 lttv_trace_ref(trace
);
2005 //remove state update hooks
2006 lttv_state_remove_event_hooks(
2007 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
2008 lttv_context_fini(LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
));
2009 g_object_unref(tab
->traceset_info
->traceset_context
);
2012 trace_v
= lttv_traceset_get(traceset
, i
);
2014 if(lttv_trace_get_ref_number(trace_v
) <= 2) {
2015 /* ref 2 : traceset, local */
2016 lttvwindowtraces_remove_trace(trace_v
);
2017 ltt_trace_close(lttv_trace(trace_v
));
2020 lttv_traceset_remove(traceset
, i
);
2021 lttv_trace_unref(trace_v
); // Remove local reference
2023 if(!lttv_trace_get_ref_number(trace_v
))
2024 lttv_trace_destroy(trace_v
);
2026 tab
->traceset_info
->traceset_context
=
2027 g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
2029 LTTV_TRACESET_CONTEXT(tab
->
2030 traceset_info
->traceset_context
),traceset
);
2031 //add state update hooks
2032 lttv_state_add_event_hooks(
2033 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
2035 //Remove local reference to the traces.
2036 for(j
=0; j
<lttv_traceset_number(traceset
); j
++)
2038 LttvTrace
* trace
= lttv_traceset_get(traceset
, j
);
2039 lttv_trace_unref(trace
);
2043 //update current tab
2044 //update_traceset(mw_data);
2047 SetTraceset(tab
, (gpointer
)traceset
);
2048 // in expose now call_pending_read_hooks(mw_data);
2050 //lttvwindow_report_current_time(mw_data,&(tab->current_time));
2053 // while(tab->multi_vpaned->num_children){
2054 // gtk_multi_vpaned_widget_delete(tab->multi_vpaned);
2068 /* Redraw all the viewers in the current tab */
2069 void redraw(GtkWidget
*widget
, gpointer user_data
)
2071 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
2072 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2073 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2078 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
2082 LttvAttributeValue value
;
2084 g_assert(lttv_iattribute_find_by_path(tab
->attributes
, "hooks/redraw", LTTV_POINTER
, &value
));
2086 tmp
= (LttvHooks
*)*(value
.v_pointer
);
2088 lttv_hooks_call(tmp
,NULL
);
2092 void continue_processing(GtkWidget
*widget
, gpointer user_data
)
2094 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
2095 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2096 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2101 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
2105 LttvAttributeValue value
;
2107 g_assert(lttv_iattribute_find_by_path(tab
->attributes
,
2108 "hooks/continue", LTTV_POINTER
, &value
));
2110 tmp
= (LttvHooks
*)*(value
.v_pointer
);
2112 lttv_hooks_call(tmp
,NULL
);
2115 /* Stop the processing for the calling main window's current tab.
2116 * It removes every processing requests that are in its list. It does not call
2117 * the end request hooks, because the request is not finished.
2120 void stop_processing(GtkWidget
*widget
, gpointer user_data
)
2122 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
2123 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2124 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2129 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
2131 GSList
*iter
= tab
->events_requests
;
2133 while(iter
!= NULL
) {
2134 GSList
*remove_iter
= iter
;
2135 iter
= g_slist_next(iter
);
2137 g_free(remove_iter
->data
);
2138 tab
->events_requests
=
2139 g_slist_remove_link(tab
->events_requests
, remove_iter
);
2141 tab
->events_request_pending
= FALSE
;
2142 g_idle_remove_by_data(tab
);
2143 g_assert(g_slist_length(tab
->events_requests
) == 0);
2147 /* save will save the traceset to a file
2148 * Not implemented yet FIXME
2151 void save(GtkWidget
* widget
, gpointer user_data
)
2156 void save_as(GtkWidget
* widget
, gpointer user_data
)
2158 g_printf("Save as\n");
2162 /* zoom will change the time_window of all the viewers of the
2163 * current tab, and redisplay them. The main functionality is to
2164 * determine the new time_window of the current tab
2167 void zoom(GtkWidget
* widget
, double size
)
2169 TimeInterval time_span
;
2170 TimeWindow new_time_window
;
2171 LttTime current_time
, time_delta
, time_s
, time_e
, time_tmp
;
2172 MainWindow
* mw_data
= get_window_data_struct(widget
);
2173 LttvTracesetContext
*tsc
;
2174 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
2176 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2177 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2183 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
2186 if(size
== 1) return;
2188 tsc
= LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
2189 time_span
= tsc
->time_span
;
2190 new_time_window
= tab
->time_window
;
2191 current_time
= tab
->current_time
;
2193 time_delta
= ltt_time_sub(time_span
.end_time
,time_span
.start_time
);
2195 new_time_window
.start_time
= time_span
.start_time
;
2196 new_time_window
.time_width
= time_delta
;
2198 new_time_window
.time_width
= ltt_time_div(new_time_window
.time_width
, size
);
2199 if(ltt_time_compare(new_time_window
.time_width
,time_delta
) > 0)
2200 { /* Case where zoom out is bigger than trace length */
2201 new_time_window
.start_time
= time_span
.start_time
;
2202 new_time_window
.time_width
= time_delta
;
2206 /* Center the image on the current time */
2207 new_time_window
.start_time
=
2208 ltt_time_sub(current_time
, ltt_time_div(new_time_window
.time_width
, 2.0));
2209 /* If on borders, don't fall off */
2210 if(ltt_time_compare(new_time_window
.start_time
, time_span
.start_time
) <0)
2212 new_time_window
.start_time
= time_span
.start_time
;
2216 if(ltt_time_compare(
2217 ltt_time_add(new_time_window
.start_time
, new_time_window
.time_width
),
2218 time_span
.end_time
) > 0)
2220 new_time_window
.start_time
=
2221 ltt_time_sub(time_span
.end_time
, new_time_window
.time_width
);
2228 if(ltt_time_compare(new_time_window
.time_width
, ltt_time_zero
) == 0) {
2229 g_warning("Zoom more than 1 ns impossible");
2231 time_change_manager(tab
, new_time_window
);
2235 void zoom_in(GtkWidget
* widget
, gpointer user_data
)
2240 void zoom_out(GtkWidget
* widget
, gpointer user_data
)
2245 void zoom_extended(GtkWidget
* widget
, gpointer user_data
)
2250 void go_to_time(GtkWidget
* widget
, gpointer user_data
)
2252 g_printf("Go to time\n");
2255 void show_time_frame(GtkWidget
* widget
, gpointer user_data
)
2257 g_printf("Show time frame\n");
2261 /* callback function */
2264 on_empty_traceset_activate (GtkMenuItem
*menuitem
,
2267 create_new_window((GtkWidget
*)menuitem
, user_data
, FALSE
);
2272 on_clone_traceset_activate (GtkMenuItem
*menuitem
,
2275 create_new_window((GtkWidget
*)menuitem
, user_data
, TRUE
);
2279 /* create_new_tab calls create_tab to construct a new tab in the main window
2282 Tab
*create_new_tab(GtkWidget
* widget
, gpointer user_data
){
2283 gchar label
[PATH_MAX
];
2284 MainWindow
* mw_data
= get_window_data_struct(widget
);
2286 GtkNotebook
* notebook
= (GtkNotebook
*)lookup_widget(widget
, "MNotebook");
2287 if(notebook
== NULL
){
2288 g_printf("Notebook does not exist\n");
2291 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2292 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2298 copy_tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
2301 strcpy(label
,"Page");
2302 if(get_label(mw_data
, label
,"Get the name of the tab","Please input tab's name"))
2303 return (create_tab (mw_data
, copy_tab
, notebook
, label
));
2307 on_tab_activate (GtkMenuItem
*menuitem
,
2310 create_new_tab((GtkWidget
*)menuitem
, user_data
);
2315 on_open_activate (GtkMenuItem
*menuitem
,
2318 open_traceset((GtkWidget
*)menuitem
, user_data
);
2323 on_close_activate (GtkMenuItem
*menuitem
,
2326 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2327 main_window_destructor(mw_data
);
2331 /* remove the current tab from the main window
2335 on_close_tab_activate (GtkWidget
*widget
,
2339 GtkWidget
* notebook
;
2341 MainWindow
* mw_data
= get_window_data_struct(widget
);
2342 notebook
= lookup_widget(widget
, "MNotebook");
2343 if(notebook
== NULL
){
2344 g_printf("Notebook does not exist\n");
2348 page_num
= gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
));
2350 gtk_notebook_remove_page(GTK_NOTEBOOK(notebook
), page_num
);
2355 on_close_tab_X_clicked (GtkWidget
*widget
,
2359 GtkWidget
*notebook
= lookup_widget(widget
, "MNotebook");
2360 if(notebook
== NULL
){
2361 g_printf("Notebook does not exist\n");
2365 if((page_num
= gtk_notebook_page_num(GTK_NOTEBOOK(notebook
), widget
)) != -1)
2366 gtk_notebook_remove_page(GTK_NOTEBOOK(notebook
), page_num
);
2372 on_add_trace_activate (GtkMenuItem
*menuitem
,
2375 add_trace((GtkWidget
*)menuitem
, user_data
);
2380 on_remove_trace_activate (GtkMenuItem
*menuitem
,
2383 remove_trace((GtkWidget
*)menuitem
, user_data
);
2388 on_save_activate (GtkMenuItem
*menuitem
,
2391 save((GtkWidget
*)menuitem
, user_data
);
2396 on_save_as_activate (GtkMenuItem
*menuitem
,
2399 save_as((GtkWidget
*)menuitem
, user_data
);
2404 on_quit_activate (GtkMenuItem
*menuitem
,
2412 on_cut_activate (GtkMenuItem
*menuitem
,
2420 on_copy_activate (GtkMenuItem
*menuitem
,
2423 g_printf("Copye\n");
2428 on_paste_activate (GtkMenuItem
*menuitem
,
2431 g_printf("Paste\n");
2436 on_delete_activate (GtkMenuItem
*menuitem
,
2439 g_printf("Delete\n");
2444 on_zoom_in_activate (GtkMenuItem
*menuitem
,
2447 zoom_in((GtkWidget
*)menuitem
, user_data
);
2452 on_zoom_out_activate (GtkMenuItem
*menuitem
,
2455 zoom_out((GtkWidget
*)menuitem
, user_data
);
2460 on_zoom_extended_activate (GtkMenuItem
*menuitem
,
2463 zoom_extended((GtkWidget
*)menuitem
, user_data
);
2468 on_go_to_time_activate (GtkMenuItem
*menuitem
,
2471 go_to_time((GtkWidget
*)menuitem
, user_data
);
2476 on_show_time_frame_activate (GtkMenuItem
*menuitem
,
2479 show_time_frame((GtkWidget
*)menuitem
, user_data
);
2484 on_move_viewer_up_activate (GtkMenuItem
*menuitem
,
2487 move_up_viewer((GtkWidget
*)menuitem
, user_data
);
2492 on_move_viewer_down_activate (GtkMenuItem
*menuitem
,
2495 move_down_viewer((GtkWidget
*)menuitem
, user_data
);
2500 on_remove_viewer_activate (GtkMenuItem
*menuitem
,
2503 delete_viewer((GtkWidget
*)menuitem
, user_data
);
2508 on_trace_filter_activate (GtkMenuItem
*menuitem
,
2511 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2512 LttvTracesetSelector
* s
;
2514 GtkWidget
* notebook
= lookup_widget(GTK_WIDGET(menuitem
), "MNotebook");
2516 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2517 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2523 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
2526 w
= gtk_multivpaned_get_widget(GTK_MULTIVPANED(tab
->multivpaned
));
2528 s
= g_object_get_data(G_OBJECT(w
), "Traceset_Selector");
2530 g_printf("There is no viewer yet\n");
2533 if(get_filter_selection(s
, "Configure trace and tracefile filter", "Select traces and tracefiles")){
2534 //FIXME report filter change
2535 //update_traceset(mw_data);
2536 //call_pending_read_hooks(mw_data);
2537 //lttvwindow_report_current_time(mw_data,&(tab->current_time));
2543 on_trace_facility_activate (GtkMenuItem
*menuitem
,
2546 g_printf("Trace facility selector: %s\n");
2550 /* Dispaly a file selection dialogue to let user select a library, then call
2551 * lttv_library_load().
2555 on_load_library_activate (GtkMenuItem
*menuitem
,
2558 GError
*error
= NULL
;
2559 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2561 gchar load_module_path_alter
[PATH_MAX
];
2565 gchar
*load_module_path
;
2566 name
= g_ptr_array_new();
2567 nb
= lttv_library_path_number();
2568 /* ask for the library path */
2572 path
= lttv_library_path_get(i
);
2573 g_ptr_array_add(name
, path
);
2576 load_module_path
= get_selection((char **)(name
->pdata
), name
->len
,
2577 "Select a library path", "Library paths");
2578 if(load_module_path
!= NULL
)
2579 strncpy(load_module_path_alter
, load_module_path
, PATH_MAX
-1); // -1 for /
2581 g_ptr_array_free(name
, TRUE
);
2583 if(load_module_path
== NULL
) return;
2587 /* Make sure the module path ends with a / */
2588 gchar
*ptr
= load_module_path_alter
;
2590 ptr
= strchr(ptr
, '\0');
2592 if(*(ptr
-1) != '/') {
2599 /* Ask for the library to load : list files in the previously selected
2601 gchar str
[PATH_MAX
];
2604 GtkFileSelection
* file_selector
=
2605 (GtkFileSelection
*)gtk_file_selection_new("Select a module");
2606 gtk_file_selection_set_filename(file_selector
, load_module_path_alter
);
2607 gtk_file_selection_hide_fileop_buttons(file_selector
);
2610 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
2612 case GTK_RESPONSE_ACCEPT
:
2613 case GTK_RESPONSE_OK
:
2614 dir
= gtk_file_selection_get_selections (file_selector
);
2615 strncpy(str
,dir
[0],PATH_MAX
);
2616 strncpy(remember_plugins_dir
,dir
[0],PATH_MAX
);
2617 /* only keep file name */
2619 str1
= strrchr(str
,'/');
2622 str1
= strrchr(str
,'\\');
2627 if(*str1
== 'l' && *(str1
+1)== 'i' && *(str1
+2)=='b')
2629 remove info after
. */
2633 str2
= strrchr(str2
, '.');
2634 if(str2
!= NULL
) *str2
= '\0';
2636 lttv_module_require(str1
, &error
);
2638 lttv_library_load(str1
, &error
);
2639 if(error
!= NULL
) g_warning(error
->message
);
2640 else g_printf("Load library: %s\n", str
);
2642 case GTK_RESPONSE_REJECT
:
2643 case GTK_RESPONSE_CANCEL
:
2645 gtk_widget_destroy((GtkWidget
*)file_selector
);
2656 /* Display all loaded modules, let user to select a module to unload
2657 * by calling lttv_module_unload
2661 on_unload_library_activate (GtkMenuItem
*menuitem
,
2664 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2666 LttvLibrary
*library
;
2671 name
= g_ptr_array_new();
2672 nb
= lttv_library_number();
2673 LttvLibraryInfo
*lib_info
= g_new(LttvLibraryInfo
,nb
);
2674 /* ask for the library name */
2677 LttvLibrary
*iter_lib
= lttv_library_get(i
);
2678 lttv_library_info(iter_lib
, &lib_info
[i
]);
2680 gchar
*path
= lib_info
[i
].name
;
2681 g_ptr_array_add(name
, lib_info
[i
].name
);
2683 lib_name
= get_selection((char **)(name
->pdata
), name
->len
,
2684 "Select a library", "Libraries");
2685 if(lib_name
!= NULL
) {
2687 if(strcmp(lib_name
, lib_info
[i
].name
) == 0) {
2688 library
= lttv_library_get(i
);
2693 g_ptr_array_free(name
, TRUE
);
2696 if(lib_name
== NULL
) return;
2699 lttv_library_unload(library
);
2703 /* Dispaly a file selection dialogue to let user select a module, then call
2704 * lttv_module_require().
2708 on_load_module_activate (GtkMenuItem
*menuitem
,
2711 GError
*error
= NULL
;
2712 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2714 LttvLibrary
*library
;
2719 name
= g_ptr_array_new();
2720 nb
= lttv_library_number();
2721 LttvLibraryInfo
*lib_info
= g_new(LttvLibraryInfo
,nb
);
2722 /* ask for the library name */
2725 LttvLibrary
*iter_lib
= lttv_library_get(i
);
2726 lttv_library_info(iter_lib
, &lib_info
[i
]);
2728 gchar
*path
= lib_info
[i
].name
;
2729 g_ptr_array_add(name
, path
);
2731 lib_name
= get_selection((char **)(name
->pdata
), name
->len
,
2732 "Select a library", "Libraries");
2733 if(lib_name
!= NULL
) {
2735 if(strcmp(lib_name
, lib_info
[i
].name
) == 0) {
2736 library
= lttv_library_get(i
);
2741 g_ptr_array_free(name
, TRUE
);
2744 if(lib_name
== NULL
) return;
2747 //LttvModule *module;
2748 gchar module_name_out
[PATH_MAX
];
2750 /* Ask for the module to load : list modules in the selected lib */
2754 LttvModuleInfo
*module_info
= g_new(LttvModuleInfo
,nb
);
2755 name
= g_ptr_array_new();
2756 nb
= lttv_library_module_number(library
);
2757 /* ask for the module name */
2760 LttvModule
*iter_module
= lttv_library_module_get(library
, i
);
2761 lttv_module_info(iter_module
, &module_info
[i
]);
2763 gchar
*path
= module_info
[i
].name
;
2764 g_ptr_array_add(name
, path
);
2766 module_name
= get_selection((char **)(name
->pdata
), name
->len
,
2767 "Select a module", "Modules");
2768 if(module_name
!= NULL
) {
2770 if(strcmp(module_name
, module_info
[i
].name
) == 0) {
2771 strncpy(module_name_out
, module_name
, PATH_MAX
);
2772 //module = lttv_library_module_get(i);
2778 g_ptr_array_free(name
, TRUE
);
2779 g_free(module_info
);
2781 if(module_name
== NULL
) return;
2784 lttv_module_require(module_name_out
, &error
);
2785 if(error
!= NULL
) g_warning(error
->message
);
2786 else g_printf("Load module: %s\n", module_name_out
);
2793 gchar str
[PATH_MAX
];
2796 GtkFileSelection
* file_selector
=
2797 (GtkFileSelection
*)gtk_file_selection_new("Select a module");
2798 gtk_file_selection_set_filename(file_selector
, load_module_path_alter
);
2799 gtk_file_selection_hide_fileop_buttons(file_selector
);
2802 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
2804 case GTK_RESPONSE_ACCEPT
:
2805 case GTK_RESPONSE_OK
:
2806 dir
= gtk_file_selection_get_selections (file_selector
);
2807 strncpy(str
,dir
[0],PATH_MAX
);
2808 strncpy(remember_plugins_dir
,dir
[0],PATH_MAX
);
2810 /* only keep file name */
2812 str1
= strrchr(str
,'/');
2815 str1
= strrchr(str
,'\\');
2820 if(*str1
== 'l' && *(str1
+1)== 'i' && *(str1
+2)=='b')
2822 remove info after
. */
2826 str2
= strrchr(str2
, '.');
2827 if(str2
!= NULL
) *str2
= '\0';
2829 lttv_module_require(str1
, &error
);
2831 lttv_library_load(str1
, &error
);
2832 if(error
!= NULL
) g_warning(error
->message
);
2833 else g_printf("Load library: %s\n", str
);
2835 case GTK_RESPONSE_REJECT
:
2836 case GTK_RESPONSE_CANCEL
:
2838 gtk_widget_destroy((GtkWidget
*)file_selector
);
2850 /* Display all loaded modules, let user to select a module to unload
2851 * by calling lttv_module_unload
2855 on_unload_module_activate (GtkMenuItem
*menuitem
,
2858 GError
*error
= NULL
;
2859 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2861 LttvLibrary
*library
;
2866 name
= g_ptr_array_new();
2867 nb
= lttv_library_number();
2868 LttvLibraryInfo
*lib_info
= g_new(LttvLibraryInfo
,nb
);
2869 /* ask for the library name */
2872 LttvLibrary
*iter_lib
= lttv_library_get(i
);
2873 lttv_library_info(iter_lib
, &lib_info
[i
]);
2875 gchar
*path
= lib_info
[i
].name
;
2876 g_ptr_array_add(name
, path
);
2878 lib_name
= get_selection((char **)(name
->pdata
), name
->len
,
2879 "Select a library", "Libraries");
2880 if(lib_name
!= NULL
) {
2882 if(strcmp(lib_name
, lib_info
[i
].name
) == 0) {
2883 library
= lttv_library_get(i
);
2888 g_ptr_array_free(name
, TRUE
);
2891 if(lib_name
== NULL
) return;
2896 /* Ask for the module to load : list modules in the selected lib */
2900 nb
= lttv_library_module_number(library
);
2901 LttvModuleInfo
*module_info
= g_new(LttvModuleInfo
,nb
);
2902 name
= g_ptr_array_new();
2903 /* ask for the module name */
2906 LttvModule
*iter_module
= lttv_library_module_get(library
, i
);
2907 lttv_module_info(iter_module
, &module_info
[i
]);
2909 gchar
*path
= module_info
[i
].name
;
2910 if(module_info
[i
].use_count
> 0) g_ptr_array_add(name
, path
);
2912 module_name
= get_selection((char **)(name
->pdata
), name
->len
,
2913 "Select a module", "Modules");
2914 if(module_name
!= NULL
) {
2916 if(strcmp(module_name
, module_info
[i
].name
) == 0) {
2917 module
= lttv_library_module_get(library
, i
);
2923 g_ptr_array_free(name
, TRUE
);
2924 g_free(module_info
);
2926 if(module_name
== NULL
) return;
2929 LttvModuleInfo module_info
;
2930 lttv_module_info(module
, &module_info
);
2931 g_printf("Release module: %s\n", module_info
.name
);
2933 lttv_module_release(module
);
2937 /* Display a directory dialogue to let user select a path for library searching
2941 on_add_library_search_path_activate (GtkMenuItem
*menuitem
,
2944 GtkDirSelection
* file_selector
= (GtkDirSelection
*)gtk_dir_selection_new("Select library path");
2948 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2949 if(remember_plugins_dir
[0] != '\0')
2950 gtk_dir_selection_set_filename(file_selector
, remember_plugins_dir
);
2952 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
2954 case GTK_RESPONSE_ACCEPT
:
2955 case GTK_RESPONSE_OK
:
2956 dir
= gtk_dir_selection_get_dir (file_selector
);
2957 strncpy(remember_plugins_dir
,dir
,PATH_MAX
);
2958 strncat(remember_plugins_dir
,"/",PATH_MAX
);
2959 lttv_library_path_add(dir
);
2960 case GTK_RESPONSE_REJECT
:
2961 case GTK_RESPONSE_CANCEL
:
2963 gtk_widget_destroy((GtkWidget
*)file_selector
);
2969 /* Display a directory dialogue to let user select a path for library searching
2973 on_remove_library_search_path_activate (GtkMenuItem
*menuitem
,
2976 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2978 const char *lib_path
;
2983 name
= g_ptr_array_new();
2984 nb
= lttv_library_path_number();
2985 /* ask for the library name */
2988 gchar
*path
= lttv_library_path_get(i
);
2989 g_ptr_array_add(name
, path
);
2991 lib_path
= get_selection((char **)(name
->pdata
), name
->len
,
2992 "Select a library path", "Library paths");
2994 g_ptr_array_free(name
, TRUE
);
2996 if(lib_path
== NULL
) return;
2999 lttv_library_path_remove(lib_path
);
3003 on_color_activate (GtkMenuItem
*menuitem
,
3006 g_printf("Color\n");
3011 on_filter_activate (GtkMenuItem
*menuitem
,
3014 g_printf("Filter\n");
3019 on_save_configuration_activate (GtkMenuItem
*menuitem
,
3022 g_printf("Save configuration\n");
3027 on_content_activate (GtkMenuItem
*menuitem
,
3030 g_printf("Content\n");
3035 on_about_close_activate (GtkButton
*button
,
3038 GtkWidget
*about_widget
= GTK_WIDGET(user_data
);
3040 gtk_widget_destroy(about_widget
);
3044 on_about_activate (GtkMenuItem
*menuitem
,
3047 MainWindow
*main_window
= get_window_data_struct(GTK_WIDGET(menuitem
));
3048 GtkWidget
*window_widget
= main_window
->mwindow
;
3049 GtkWidget
*about_widget
= gtk_window_new(GTK_WINDOW_TOPLEVEL
);
3050 GtkWindow
*about_window
= GTK_WINDOW(about_widget
);
3051 gint window_width
, window_height
;
3053 gtk_window_set_title(about_window
, "About Linux Trace Toolkit");
3055 gtk_window_set_resizable(about_window
, FALSE
);
3056 gtk_window_set_transient_for(GTK_WINDOW(window_widget
), about_window
);
3057 gtk_window_set_destroy_with_parent(about_window
, TRUE
);
3058 gtk_window_set_modal(about_window
, FALSE
);
3060 /* Put the about window at the center of the screen */
3061 gtk_window_get_size(about_window
, &window_width
, &window_height
);
3062 gtk_window_move (about_window
,
3063 (gdk_screen_width() - window_width
)/2,
3064 (gdk_screen_height() - window_height
)/2);
3066 GtkWidget
*vbox
= gtk_vbox_new(FALSE
, 1);
3068 gtk_container_add(GTK_CONTAINER(about_widget
), vbox
);
3072 GtkWidget
*label1
= gtk_label_new("");
3073 gtk_misc_set_padding(GTK_MISC(label1
), 10, 20);
3074 gtk_label_set_markup(GTK_LABEL(label1
), "\
3075 <big>Linux Trace Toolkit</big>");
3076 gtk_label_set_justify(GTK_LABEL(label1
), GTK_JUSTIFY_CENTER
);
3078 GtkWidget
*label2
= gtk_label_new("");
3079 gtk_misc_set_padding(GTK_MISC(label2
), 10, 20);
3080 gtk_label_set_markup(GTK_LABEL(label2
), "\
3081 Project author: Karim Yaghmour\n\
3085 Michel Dagenais (New trace format, lttv main)\n\
3086 Mathieu Desnoyers (Directory structure, build with automake/conf,\n\
3087 lttv gui, control flow view, gui green threads\n\
3088 with interruptible foreground and background computation,\n\
3089 detailed event list)\n\
3090 Benoit Des Ligneris (Cluster adaptation)\n\
3091 Xang-Xiu Yang (new trace reading library and converter, lttv gui, \n\
3092 detailed event list and statistics view)\n\
3093 Tom Zanussi (RelayFS)");
3095 GtkWidget
*label3
= gtk_label_new("");
3096 gtk_label_set_markup(GTK_LABEL(label3
), "\
3097 Linux Trace Toolkit, Copyright (C) 2004 Karim Yaghmour\n\
3098 Linux Trace Toolkit comes with ABSOLUTELY NO WARRANTY.\n\
3099 This is free software, and you are welcome to redistribute it\n\
3100 under certain conditions. See COPYING for details.");
3101 gtk_misc_set_padding(GTK_MISC(label3
), 10, 20);
3103 gtk_box_pack_start_defaults(GTK_BOX(vbox
), label1
);
3104 gtk_box_pack_start_defaults(GTK_BOX(vbox
), label2
);
3105 gtk_box_pack_start_defaults(GTK_BOX(vbox
), label3
);
3107 GtkWidget
*hbox
= gtk_hbox_new(TRUE
, 0);
3108 gtk_box_pack_end(GTK_BOX(vbox
), hbox
, FALSE
, FALSE
, 0);
3109 GtkWidget
*close_button
= gtk_button_new_with_mnemonic("_Close");
3110 gtk_box_pack_end(GTK_BOX(hbox
), close_button
, FALSE
, FALSE
, 0);
3111 gtk_container_set_border_width(GTK_CONTAINER(close_button
), 20);
3113 g_signal_connect(G_OBJECT(close_button
), "clicked",
3114 G_CALLBACK(on_about_close_activate
),
3115 (gpointer
)about_widget
);
3117 gtk_widget_show_all(about_widget
);
3122 on_button_new_clicked (GtkButton
*button
,
3125 create_new_window((GtkWidget
*)button
, user_data
, TRUE
);
3129 on_button_new_tab_clicked (GtkButton
*button
,
3132 create_new_tab((GtkWidget
*)button
, user_data
);
3136 on_button_open_clicked (GtkButton
*button
,
3139 open_traceset((GtkWidget
*)button
, user_data
);
3144 on_button_add_trace_clicked (GtkButton
*button
,
3147 add_trace((GtkWidget
*)button
, user_data
);
3152 on_button_remove_trace_clicked (GtkButton
*button
,
3155 remove_trace((GtkWidget
*)button
, user_data
);
3159 on_button_redraw_clicked (GtkButton
*button
,
3162 redraw((GtkWidget
*)button
, user_data
);
3166 on_button_continue_processing_clicked (GtkButton
*button
,
3169 continue_processing((GtkWidget
*)button
, user_data
);
3173 on_button_stop_processing_clicked (GtkButton
*button
,
3176 stop_processing((GtkWidget
*)button
, user_data
);
3182 on_button_save_clicked (GtkButton
*button
,
3185 save((GtkWidget
*)button
, user_data
);
3190 on_button_save_as_clicked (GtkButton
*button
,
3193 save_as((GtkWidget
*)button
, user_data
);
3198 on_button_zoom_in_clicked (GtkButton
*button
,
3201 zoom_in((GtkWidget
*)button
, user_data
);
3206 on_button_zoom_out_clicked (GtkButton
*button
,
3209 zoom_out((GtkWidget
*)button
, user_data
);
3214 on_button_zoom_extended_clicked (GtkButton
*button
,
3217 zoom_extended((GtkWidget
*)button
, user_data
);
3222 on_button_go_to_time_clicked (GtkButton
*button
,
3225 go_to_time((GtkWidget
*)button
, user_data
);
3230 on_button_show_time_frame_clicked (GtkButton
*button
,
3233 show_time_frame((GtkWidget
*)button
, user_data
);
3238 on_button_move_up_clicked (GtkButton
*button
,
3241 move_up_viewer((GtkWidget
*)button
, user_data
);
3246 on_button_move_down_clicked (GtkButton
*button
,
3249 move_down_viewer((GtkWidget
*)button
, user_data
);
3254 on_button_delete_viewer_clicked (GtkButton
*button
,
3257 delete_viewer((GtkWidget
*)button
, user_data
);
3261 on_MWindow_destroy (GtkWidget
*widget
,
3264 MainWindow
*main_window
= get_window_data_struct(widget
);
3265 LttvIAttribute
*attributes
= main_window
->attributes
;
3266 LttvAttributeValue value
;
3268 //This is unnecessary, since widgets will be destroyed
3269 //by the main window widget anyway.
3270 //remove_all_menu_toolbar_constructors(main_window, NULL);
3272 g_assert(lttv_iattribute_find_by_path(attributes
,
3273 "viewers/menu", LTTV_POINTER
, &value
));
3274 lttv_menus_destroy((LttvMenus
*)*(value
.v_pointer
));
3276 g_assert(lttv_iattribute_find_by_path(attributes
,
3277 "viewers/toolbar", LTTV_POINTER
, &value
));
3278 lttv_toolbars_destroy((LttvToolbars
*)*(value
.v_pointer
));
3280 g_object_unref(main_window
->attributes
);
3281 g_main_window_list
= g_slist_remove(g_main_window_list
, main_window
);
3283 g_printf("There are now : %d windows\n",g_slist_length(g_main_window_list
));
3284 if(g_slist_length(g_main_window_list
) == 0)
3289 on_MWindow_configure (GtkWidget
*widget
,
3290 GdkEventConfigure
*event
,
3293 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)widget
);
3294 float width
= event
->width
;
3295 TimeWindow time_win
;
3297 TimeInterval
*time_span
;
3300 // MD : removed time width modification upon resizing of the main window.
3301 // The viewers will redraw themselves completely, without time interval
3304 if(mw_data->window_width){
3305 time_span = LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context)->Time_Span ;
3306 time_win = tab->time_window;
3307 ratio = width / mw_data->window_width;
3308 tab->time_window.time_width = ltt_time_mul(time_win.time_width,ratio);
3309 time = ltt_time_sub(time_span->endTime, time_win.start_time);
3310 if(ltt_time_compare(time, tab->time_window.time_width) < 0){
3311 tab->time_window.time_width = time;
3317 mw_data->window_width = (int)width;
3326 on_MNotebook_switch_page (GtkNotebook
*notebook
,
3327 GtkNotebookPage
*page
,
3335 void time_change_manager (Tab
*tab
,
3336 TimeWindow new_time_window
)
3338 /* Only one source of time change */
3339 if(tab
->time_manager_lock
== TRUE
) return;
3341 tab
->time_manager_lock
= TRUE
;
3343 LttvTracesetContext
*tsc
= LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3344 TimeInterval time_span
= tsc
->time_span
;
3345 LttTime start_time
= new_time_window
.start_time
;
3346 LttTime end_time
= ltt_time_add(new_time_window
.start_time
,
3347 new_time_window
.time_width
);
3350 GtkAdjustment
*adjustment
= gtk_range_get_adjustment(GTK_RANGE(tab
->scrollbar
));
3351 LttTime upper
= ltt_time_sub(time_span
.end_time
, time_span
.start_time
);
3353 gtk_range_set_increments(GTK_RANGE(tab
->scrollbar
),
3354 ltt_time_to_double(new_time_window
.time_width
)
3355 / SCROLL_STEP_PER_PAGE
3356 * NANOSECONDS_PER_SECOND
, /* step increment */
3357 ltt_time_to_double(new_time_window
.time_width
)
3358 * NANOSECONDS_PER_SECOND
); /* page increment */
3359 gtk_range_set_range(GTK_RANGE(tab
->scrollbar
),
3361 ltt_time_to_double(upper
)
3362 * NANOSECONDS_PER_SECOND
); /* upper */
3364 g_object_set(G_OBJECT(adjustment
),
3368 ltt_time_to_double(upper
)
3369 * NANOSECONDS_PER_SECOND
, /* upper */
3371 ltt_time_to_double(new_time_window
.time_width
)
3372 / SCROLL_STEP_PER_PAGE
3373 * NANOSECONDS_PER_SECOND
, /* step increment */
3375 ltt_time_to_double(new_time_window
.time_width
)
3376 * NANOSECONDS_PER_SECOND
, /* page increment */
3378 ltt_time_to_double(new_time_window
.time_width
)
3379 * NANOSECONDS_PER_SECOND
, /* page size */
3381 gtk_adjustment_changed(adjustment
);
3383 // g_object_set(G_OBJECT(adjustment),
3385 // ltt_time_to_double(
3386 // ltt_time_sub(start_time, time_span.start_time))
3387 // * NANOSECONDS_PER_SECOND, /* value */
3389 //gtk_adjustment_value_changed(adjustment);
3390 gtk_range_set_value(GTK_RANGE(tab
->scrollbar
),
3392 ltt_time_sub(start_time
, time_span
.start_time
))
3393 * NANOSECONDS_PER_SECOND
/* value */);
3395 /* set the time bar. */
3397 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry1
),
3398 (double)time_span
.start_time
.tv_sec
,
3399 (double)time_span
.end_time
.tv_sec
);
3400 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry1
),
3401 (double)start_time
.tv_sec
);
3403 /* start nanoseconds */
3404 if(start_time
.tv_sec
== time_span
.start_time
.tv_sec
) {
3405 /* can be both beginning and end at the same time. */
3406 if(start_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3407 /* If we are at the end, max nsec to end.. -1 (not zero length) */
3408 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry2
),
3409 (double)time_span
.start_time
.tv_nsec
,
3410 (double)time_span
.end_time
.tv_nsec
-1);
3412 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry2
),
3413 (double)time_span
.start_time
.tv_nsec
,
3414 (double)NANOSECONDS_PER_SECOND
-1);
3416 } else if(start_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3417 /* If we are at the end, max nsec to end.. -1 (not zero length) */
3418 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry2
),
3420 (double)time_span
.end_time
.tv_nsec
-1);
3421 } else /* anywhere else */
3422 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry2
),
3424 (double)NANOSECONDS_PER_SECOND
-1);
3425 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry2
),
3426 (double)start_time
.tv_nsec
);
3429 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry3
),
3430 (double)time_span
.start_time
.tv_sec
,
3431 (double)time_span
.end_time
.tv_sec
);
3432 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry3
),
3433 (double)end_time
.tv_sec
);
3435 /* end nanoseconds */
3436 if(end_time
.tv_sec
== time_span
.start_time
.tv_sec
) {
3437 /* can be both beginning and end at the same time. */
3438 if(end_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3439 /* If we are at the end, max nsec to end.. */
3440 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry4
),
3441 (double)time_span
.start_time
.tv_nsec
+1,
3442 (double)time_span
.end_time
.tv_nsec
);
3444 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry4
),
3445 (double)time_span
.start_time
.tv_nsec
+1,
3446 (double)NANOSECONDS_PER_SECOND
-1);
3449 else if(end_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3450 /* If we are at the end, max nsec to end.. */
3451 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry4
),
3453 (double)time_span
.end_time
.tv_nsec
);
3455 else /* anywhere else */
3456 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry4
),
3458 (double)NANOSECONDS_PER_SECOND
-1);
3459 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry4
),
3460 (double)end_time
.tv_nsec
);
3462 /* call viewer hooks for new time window */
3463 set_time_window(tab
, &new_time_window
);
3465 tab
->time_manager_lock
= FALSE
;
3469 /* value changed for frame start s
3471 * Check time span : if ns is out of range, clip it the nearest good value.
3474 on_MEntry1_value_changed (GtkSpinButton
*spinbutton
,
3477 Tab
*tab
=(Tab
*)user_data
;
3478 LttvTracesetContext
* tsc
=
3479 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3480 TimeInterval time_span
= tsc
->time_span
;
3481 gint value
= gtk_spin_button_get_value_as_int(spinbutton
);
3483 TimeWindow new_time_window
= tab
->time_window
;
3485 LttTime end_time
= ltt_time_add(new_time_window
.start_time
,
3486 new_time_window
.time_width
);
3488 new_time_window
.start_time
.tv_sec
= value
;
3490 /* start nanoseconds */
3491 if(new_time_window
.start_time
.tv_sec
== time_span
.start_time
.tv_sec
) {
3492 if(new_time_window
.start_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3493 if(new_time_window
.start_time
.tv_nsec
> time_span
.end_time
.tv_nsec
)
3494 new_time_window
.start_time
.tv_nsec
= time_span
.end_time
.tv_nsec
-1;
3495 if(new_time_window
.start_time
.tv_nsec
< time_span
.start_time
.tv_nsec
)
3496 new_time_window
.start_time
.tv_nsec
= time_span
.start_time
.tv_nsec
;
3498 if(new_time_window
.start_time
.tv_nsec
< time_span
.start_time
.tv_nsec
)
3499 new_time_window
.start_time
.tv_nsec
= time_span
.start_time
.tv_nsec
;
3502 else if(new_time_window
.start_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3503 if(new_time_window
.start_time
.tv_nsec
> time_span
.end_time
.tv_nsec
)
3504 new_time_window
.start_time
.tv_nsec
= time_span
.end_time
.tv_nsec
-1;
3507 /* check if end time selected is below or equal */
3508 if(ltt_time_compare(new_time_window
.start_time
, end_time
) >= 0) {
3509 /* Then, we must push back end time : keep the same time width
3510 * if possible, else end traceset time */
3511 end_time
= LTT_TIME_MIN(time_span
.end_time
,
3512 ltt_time_add(new_time_window
.start_time
,
3513 new_time_window
.time_width
)
3517 /* Fix the time width to fit start time and end time */
3518 new_time_window
.time_width
= ltt_time_sub(end_time
,
3519 new_time_window
.start_time
);
3521 time_change_manager(tab
, new_time_window
);
3526 on_MEntry2_value_changed (GtkSpinButton
*spinbutton
,
3529 Tab
*tab
=(Tab
*)user_data
;
3530 LttvTracesetContext
* tsc
=
3531 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3532 TimeInterval time_span
= tsc
->time_span
;
3533 gint value
= gtk_spin_button_get_value_as_int(spinbutton
);
3535 TimeWindow new_time_window
= tab
->time_window
;
3537 LttTime end_time
= ltt_time_add(new_time_window
.start_time
,
3538 new_time_window
.time_width
);
3540 new_time_window
.start_time
.tv_nsec
= value
;
3542 /* check if end time selected is below or equal */
3543 if(ltt_time_compare(new_time_window
.start_time
, end_time
) >= 0) {
3544 /* Then, we must push back end time : keep the same time width
3545 * if possible, else end traceset time */
3546 end_time
= LTT_TIME_MIN(time_span
.end_time
,
3547 ltt_time_add(new_time_window
.start_time
,
3548 new_time_window
.time_width
)
3552 /* Fix the time width to fit start time and end time */
3553 new_time_window
.time_width
= ltt_time_sub(end_time
,
3554 new_time_window
.start_time
);
3556 time_change_manager(tab
, new_time_window
);
3561 on_MEntry3_value_changed (GtkSpinButton
*spinbutton
,
3564 Tab
*tab
=(Tab
*)user_data
;
3565 LttvTracesetContext
* tsc
=
3566 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3567 TimeInterval time_span
= tsc
->time_span
;
3568 gint value
= gtk_spin_button_get_value_as_int(spinbutton
);
3570 TimeWindow new_time_window
= tab
->time_window
;
3572 LttTime end_time
= ltt_time_add(new_time_window
.start_time
,
3573 new_time_window
.time_width
);
3574 end_time
.tv_sec
= value
;
3576 /* end nanoseconds */
3577 if(end_time
.tv_sec
== time_span
.start_time
.tv_sec
) {
3578 if(end_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3579 if(end_time
.tv_nsec
> time_span
.end_time
.tv_nsec
)
3580 end_time
.tv_nsec
= time_span
.end_time
.tv_nsec
;
3581 if(end_time
.tv_nsec
< time_span
.start_time
.tv_nsec
)
3582 end_time
.tv_nsec
= time_span
.start_time
.tv_nsec
+1;
3584 if(end_time
.tv_nsec
< time_span
.start_time
.tv_nsec
)
3585 end_time
.tv_nsec
= time_span
.start_time
.tv_nsec
+1;
3588 else if(end_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3589 if(end_time
.tv_nsec
> time_span
.end_time
.tv_nsec
)
3590 end_time
.tv_nsec
= time_span
.end_time
.tv_nsec
;
3593 /* check if end time selected is below or equal */
3594 if(ltt_time_compare(new_time_window
.start_time
, end_time
) >= 0) {
3595 /* Then, we must push front start time : keep the same time width
3596 * if possible, else end traceset time */
3597 new_time_window
.start_time
= LTT_TIME_MAX(time_span
.start_time
,
3598 ltt_time_sub(end_time
,
3599 new_time_window
.time_width
)
3603 /* Fix the time width to fit start time and end time */
3604 new_time_window
.time_width
= ltt_time_sub(end_time
,
3605 new_time_window
.start_time
);
3607 time_change_manager(tab
, new_time_window
);
3612 on_MEntry4_value_changed (GtkSpinButton
*spinbutton
,
3615 Tab
*tab
=(Tab
*)user_data
;
3616 LttvTracesetContext
* tsc
=
3617 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3618 TimeInterval time_span
= tsc
->time_span
;
3619 gint value
= gtk_spin_button_get_value_as_int(spinbutton
);
3621 TimeWindow new_time_window
= tab
->time_window
;
3623 LttTime end_time
= ltt_time_add(new_time_window
.start_time
,
3624 new_time_window
.time_width
);
3625 end_time
.tv_nsec
= value
;
3627 /* check if end time selected is below or equal */
3628 if(ltt_time_compare(new_time_window
.start_time
, end_time
) >= 0) {
3629 /* Then, we must push front start time : keep the same time width
3630 * if possible, else end traceset time */
3631 new_time_window
.start_time
= LTT_TIME_MAX(time_span
.start_time
,
3632 ltt_time_sub(end_time
,
3633 new_time_window
.time_width
)
3637 /* Fix the time width to fit start time and end time */
3638 new_time_window
.time_width
= ltt_time_sub(end_time
,
3639 new_time_window
.start_time
);
3641 time_change_manager(tab
, new_time_window
);
3646 void current_time_change_manager (Tab
*tab
,
3647 LttTime new_current_time
)
3649 /* Only one source of time change */
3650 if(tab
->current_time_manager_lock
== TRUE
) return;
3652 tab
->current_time_manager_lock
= TRUE
;
3654 LttvTracesetContext
*tsc
= LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3655 TimeInterval time_span
= tsc
->time_span
;
3657 /* current seconds */
3658 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry5
),
3659 (double)time_span
.start_time
.tv_sec
,
3660 (double)time_span
.end_time
.tv_sec
);
3661 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry5
),
3662 (double)new_current_time
.tv_sec
);
3665 /* start nanoseconds */
3666 if(new_current_time
.tv_sec
== time_span
.start_time
.tv_sec
) {
3667 /* can be both beginning and end at the same time. */
3668 if(new_current_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3669 /* If we are at the end, max nsec to end.. */
3670 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry6
),
3671 (double)time_span
.start_time
.tv_nsec
,
3672 (double)time_span
.end_time
.tv_nsec
);
3674 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry6
),
3675 (double)time_span
.start_time
.tv_nsec
,
3676 (double)NANOSECONDS_PER_SECOND
-1);
3678 } else if(new_current_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3679 /* If we are at the end, max nsec to end.. */
3680 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry6
),
3682 (double)time_span
.end_time
.tv_nsec
);
3683 } else /* anywhere else */
3684 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry6
),
3686 (double)NANOSECONDS_PER_SECOND
-1);
3688 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry6
),
3689 (double)new_current_time
.tv_nsec
);
3691 set_current_time(tab
, &new_current_time
);
3693 tab
->current_time_manager_lock
= FALSE
;
3697 on_MEntry5_value_changed (GtkSpinButton
*spinbutton
,
3700 Tab
*tab
= (Tab
*)user_data
;
3701 LttvTracesetContext
* tsc
=
3702 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3703 TimeInterval time_span
= tsc
->time_span
;
3704 gint value
= gtk_spin_button_get_value_as_int(spinbutton
);
3705 LttTime new_current_time
= tab
->current_time
;
3706 new_current_time
.tv_sec
= value
;
3708 /* current nanoseconds */
3709 if(new_current_time
.tv_sec
== time_span
.start_time
.tv_sec
) {
3710 if(new_current_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3711 if(new_current_time
.tv_nsec
> time_span
.end_time
.tv_nsec
)
3712 new_current_time
.tv_nsec
= time_span
.end_time
.tv_nsec
;
3713 if(new_current_time
.tv_nsec
< time_span
.start_time
.tv_nsec
)
3714 new_current_time
.tv_nsec
= time_span
.start_time
.tv_nsec
;
3716 if(new_current_time
.tv_nsec
< time_span
.start_time
.tv_nsec
)
3717 new_current_time
.tv_nsec
= time_span
.start_time
.tv_nsec
;
3720 else if(new_current_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3721 if(new_current_time
.tv_nsec
> time_span
.end_time
.tv_nsec
)
3722 new_current_time
.tv_nsec
= time_span
.end_time
.tv_nsec
;
3725 current_time_change_manager(tab
, new_current_time
);
3729 on_MEntry6_value_changed (GtkSpinButton
*spinbutton
,
3732 Tab
*tab
= (Tab
*)user_data
;
3733 gint value
= gtk_spin_button_get_value_as_int(spinbutton
);
3734 LttTime new_current_time
= tab
->current_time
;
3735 new_current_time
.tv_nsec
= value
;
3737 current_time_change_manager(tab
, new_current_time
);
3741 void scroll_value_changed_cb(GtkWidget
*scrollbar
,
3744 Tab
*tab
= (Tab
*)user_data
;
3745 TimeWindow new_time_window
;
3747 GtkAdjustment
*adjust
= gtk_range_get_adjustment(GTK_RANGE(scrollbar
));
3748 gdouble value
= gtk_adjustment_get_value(adjust
);
3749 // gdouble upper, lower, ratio, page_size;
3751 LttvTracesetContext
* tsc
=
3752 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3753 TimeInterval time_span
= tsc
->time_span
;
3755 time
= ltt_time_add(ltt_time_from_double(value
/NANOSECONDS_PER_SECOND
),
3756 time_span
.start_time
);
3758 new_time_window
.start_time
= time
;
3760 page_size
= adjust
->page_size
;
3762 new_time_window
.time_width
=
3763 ltt_time_from_double(page_size
/NANOSECONDS_PER_SECOND
);
3766 time_change_manager(tab
, new_time_window
);
3768 //time_window = tab->time_window;
3770 lower
= adjust
->lower
;
3771 upper
= adjust
->upper
;
3772 ratio
= (value
- lower
) / (upper
- lower
);
3773 g_info("lower %lu, upper %lu, value %lu, ratio %lu", lower
, upper
, value
, ratio
);
3775 //time = ltt_time_sub(time_span->end_time, time_span->start_time);
3776 //time = ltt_time_mul(time, (float)ratio);
3777 //time = ltt_time_add(time_span->start_time, time);
3778 time
= ltt_time_add(ltt_time_from_double(value
/NANOSECONDS_PER_SECOND
),
3779 time_span
.start_time
);
3781 time_window
.start_time
= time
;
3783 page_size
= adjust
->page_size
;
3785 time_window
.time_width
=
3786 ltt_time_from_double(page_size
/NANOSECONDS_PER_SECOND
);
3787 //time = ltt_time_sub(time_span.end_time, time);
3788 //if(ltt_time_compare(time,time_window.time_width) < 0){
3789 // time_window.time_width = time;
3792 /* call viewer hooks for new time window */
3793 set_time_window(tab
, &time_window
);
3798 /* callback function to check or uncheck the check box (filter)
3801 void checkbox_changed(GtkTreeView
*treeview
,
3803 GtkTreeViewColumn
*arg2
,
3806 GtkTreeStore
* store
= (GtkTreeStore
*)gtk_tree_view_get_model (treeview
);
3810 if (gtk_tree_model_get_iter ((GtkTreeModel
*)store
, &iter
, arg1
)){
3811 gtk_tree_model_get ((GtkTreeModel
*)store
, &iter
, CHECKBOX_COLUMN
, &value
, -1);
3812 value
= value
? FALSE
: TRUE
;
3813 gtk_tree_store_set (GTK_TREE_STORE (store
), &iter
, CHECKBOX_COLUMN
, value
, -1);
3819 /* According to user's selection, update selector(filter)
3822 void update_filter(LttvTracesetSelector
*s
, GtkTreeStore
*store
)
3824 GtkTreeIter iter
, child_iter
, child_iter1
, child_iter2
;
3825 int i
, j
, k
, nb_eventtype
;
3826 LttvTraceSelector
* trace
;
3827 LttvTracefileSelector
* tracefile
;
3828 LttvEventtypeSelector
* eventtype
;
3829 gboolean value
, value1
, value2
;
3831 if(gtk_tree_model_get_iter_first((GtkTreeModel
*)store
, &iter
)){
3834 trace
= lttv_traceset_selector_trace_get(s
, i
);
3835 nb_eventtype
= lttv_trace_selector_eventtype_number(trace
);
3836 gtk_tree_model_get ((GtkTreeModel
*)store
, &iter
, CHECKBOX_COLUMN
, &value
,-1);
3839 if(gtk_tree_model_iter_children ((GtkTreeModel
*)store
, &child_iter
, &iter
)){
3841 if(j
<1){//eventtype selector for trace
3842 gtk_tree_model_get ((GtkTreeModel
*)store
, &child_iter
, CHECKBOX_COLUMN
, &value2
,-1);
3845 if(gtk_tree_model_iter_children ((GtkTreeModel
*)store
, &child_iter1
, &child_iter
)){
3847 eventtype
= lttv_trace_selector_eventtype_get(trace
,k
);
3848 gtk_tree_model_get ((GtkTreeModel
*)store
, &child_iter1
, CHECKBOX_COLUMN
, &value2
,-1);
3849 lttv_eventtype_selector_set_selected(eventtype
,value2
);
3851 }while(gtk_tree_model_iter_next((GtkTreeModel
*)store
, &child_iter1
));
3854 }else{ //tracefile selector
3855 tracefile
= lttv_trace_selector_tracefile_get(trace
, j
- 1);
3856 gtk_tree_model_get ((GtkTreeModel
*)store
, &child_iter
, CHECKBOX_COLUMN
, &value1
,-1);
3857 lttv_tracefile_selector_set_selected(tracefile
,value1
);
3859 gtk_tree_model_iter_children((GtkTreeModel
*)store
, &child_iter1
, &child_iter
); //eventtype selector
3860 gtk_tree_model_get ((GtkTreeModel
*)store
, &child_iter1
, CHECKBOX_COLUMN
, &value2
,-1);
3863 if(gtk_tree_model_iter_children ((GtkTreeModel
*)store
, &child_iter2
, &child_iter1
)){
3864 do{//eventtype selector for tracefile
3865 eventtype
= lttv_tracefile_selector_eventtype_get(tracefile
,k
);
3866 gtk_tree_model_get ((GtkTreeModel
*)store
, &child_iter2
, CHECKBOX_COLUMN
, &value2
,-1);
3867 lttv_eventtype_selector_set_selected(eventtype
,value2
);
3869 }while(gtk_tree_model_iter_next((GtkTreeModel
*)store
, &child_iter2
));
3875 }while(gtk_tree_model_iter_next((GtkTreeModel
*)store
, &child_iter
));
3878 lttv_trace_selector_set_selected(trace
,value
);
3880 }while(gtk_tree_model_iter_next((GtkTreeModel
*)store
, &iter
));
3885 /* Display a dialogue showing all eventtypes and traces, let user to select the interested
3886 * eventtypes, tracefiles and traces (filter)
3889 gboolean
get_filter_selection(LttvTracesetSelector
*s
,char *title
, char * column_title
)
3891 GtkWidget
* dialogue
;
3892 GtkTreeStore
* store
;
3894 GtkWidget
* scroll_win
;
3895 GtkCellRenderer
* renderer
;
3896 GtkTreeViewColumn
* column
;
3897 GtkTreeIter iter
, child_iter
, child_iter1
, child_iter2
;
3898 int i
, j
, k
, id
, nb_trace
, nb_tracefile
, nb_eventtype
;
3899 LttvTraceSelector
* trace
;
3900 LttvTracefileSelector
* tracefile
;
3901 LttvEventtypeSelector
* eventtype
;
3905 dialogue
= gtk_dialog_new_with_buttons(title
,
3908 GTK_STOCK_OK
,GTK_RESPONSE_ACCEPT
,
3909 GTK_STOCK_CANCEL
,GTK_RESPONSE_REJECT
,
3911 gtk_window_set_default_size((GtkWindow
*)dialogue
, 300, 500);
3913 store
= gtk_tree_store_new (TOTAL_COLUMNS
, G_TYPE_BOOLEAN
, G_TYPE_STRING
);
3914 tree
= gtk_tree_view_new_with_model (GTK_TREE_MODEL (store
));
3915 g_object_unref (G_OBJECT (store
));
3916 g_signal_connect (G_OBJECT (tree
), "row-activated",
3917 G_CALLBACK (checkbox_changed
),
3921 renderer
= gtk_cell_renderer_toggle_new ();
3922 gtk_cell_renderer_toggle_set_radio((GtkCellRendererToggle
*)renderer
, FALSE
);
3924 g_object_set (G_OBJECT (renderer
),"activatable", TRUE
, NULL
);
3926 column
= gtk_tree_view_column_new_with_attributes ("Checkbox",
3928 "active", CHECKBOX_COLUMN
,
3930 gtk_tree_view_column_set_alignment (column
, 0.5);
3931 gtk_tree_view_column_set_fixed_width (column
, 20);
3932 gtk_tree_view_append_column (GTK_TREE_VIEW (tree
), column
);
3934 renderer
= gtk_cell_renderer_text_new ();
3935 column
= gtk_tree_view_column_new_with_attributes (column_title
,
3937 "text", NAME_COLUMN
,
3939 gtk_tree_view_column_set_alignment (column
, 0.0);
3940 gtk_tree_view_append_column (GTK_TREE_VIEW (tree
), column
);
3941 gtk_tree_view_set_headers_visible(GTK_TREE_VIEW (tree
), FALSE
);
3943 scroll_win
= gtk_scrolled_window_new (NULL
, NULL
);
3944 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll_win
),
3945 GTK_POLICY_AUTOMATIC
,GTK_POLICY_AUTOMATIC
);
3946 gtk_container_add (GTK_CONTAINER (scroll_win
), tree
);
3948 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialogue
)->vbox
), scroll_win
,TRUE
, TRUE
,0);
3950 gtk_widget_show(scroll_win
);
3951 gtk_widget_show(tree
);
3953 nb_trace
= lttv_traceset_selector_trace_number(s
);
3954 for(i
=0;i
<nb_trace
;i
++){
3955 trace
= lttv_traceset_selector_trace_get(s
, i
);
3956 name
= lttv_trace_selector_get_name(trace
);
3957 gtk_tree_store_append (store
, &iter
, NULL
);
3958 checked
= lttv_trace_selector_get_selected(trace
);
3959 gtk_tree_store_set (store
, &iter
,
3960 CHECKBOX_COLUMN
,checked
,
3964 gtk_tree_store_append (store
, &child_iter
, &iter
);
3965 gtk_tree_store_set (store
, &child_iter
,
3966 CHECKBOX_COLUMN
, checked
,
3967 NAME_COLUMN
,"eventtype",
3970 nb_eventtype
= lttv_trace_selector_eventtype_number(trace
);
3971 for(j
=0;j
<nb_eventtype
;j
++){
3972 eventtype
= lttv_trace_selector_eventtype_get(trace
,j
);
3973 name
= lttv_eventtype_selector_get_name(eventtype
);
3974 checked
= lttv_eventtype_selector_get_selected(eventtype
);
3975 gtk_tree_store_append (store
, &child_iter1
, &child_iter
);
3976 gtk_tree_store_set (store
, &child_iter1
,
3977 CHECKBOX_COLUMN
, checked
,
3982 nb_tracefile
= lttv_trace_selector_tracefile_number(trace
);
3983 for(j
=0;j
<nb_tracefile
;j
++){
3984 tracefile
= lttv_trace_selector_tracefile_get(trace
, j
);
3985 name
= lttv_tracefile_selector_get_name(tracefile
);
3986 gtk_tree_store_append (store
, &child_iter
, &iter
);
3987 checked
= lttv_tracefile_selector_get_selected(tracefile
);
3988 gtk_tree_store_set (store
, &child_iter
,
3989 CHECKBOX_COLUMN
, checked
,
3993 gtk_tree_store_append (store
, &child_iter1
, &child_iter
);
3994 gtk_tree_store_set (store
, &child_iter1
,
3995 CHECKBOX_COLUMN
, checked
,
3996 NAME_COLUMN
,"eventtype",
3999 for(k
=0;k
<nb_eventtype
;k
++){
4000 eventtype
= lttv_tracefile_selector_eventtype_get(tracefile
,k
);
4001 name
= lttv_eventtype_selector_get_name(eventtype
);
4002 checked
= lttv_eventtype_selector_get_selected(eventtype
);
4003 gtk_tree_store_append (store
, &child_iter2
, &child_iter1
);
4004 gtk_tree_store_set (store
, &child_iter2
,
4005 CHECKBOX_COLUMN
, checked
,
4012 id
= gtk_dialog_run(GTK_DIALOG(dialogue
));
4014 case GTK_RESPONSE_ACCEPT
:
4015 case GTK_RESPONSE_OK
:
4016 update_filter(s
, store
);
4017 gtk_widget_destroy(dialogue
);
4019 case GTK_RESPONSE_REJECT
:
4020 case GTK_RESPONSE_CANCEL
:
4022 gtk_widget_destroy(dialogue
);
4029 /* Select a trace which will be removed from traceset
4032 char * get_remove_trace(char ** all_trace_name
, int nb_trace
)
4034 return get_selection(all_trace_name
, nb_trace
,
4035 "Select a trace", "Trace pathname");
4039 /* Select a module which will be loaded
4042 char * get_load_module(char ** load_module_name
, int nb_module
)
4044 return get_selection(load_module_name
, nb_module
,
4045 "Select a module to load", "Module name");
4051 /* Select a module which will be unloaded
4054 char * get_unload_module(char ** loaded_module_name
, int nb_module
)
4056 return get_selection(loaded_module_name
, nb_module
,
4057 "Select a module to unload", "Module name");
4061 /* Display a dialogue which shows all selectable items, let user to
4062 * select one of them
4065 char * get_selection(char ** loaded_module_name
, int nb_module
,
4066 char *title
, char * column_title
)
4068 GtkWidget
* dialogue
;
4069 GtkWidget
* scroll_win
;
4071 GtkListStore
* store
;
4072 GtkTreeViewColumn
* column
;
4073 GtkCellRenderer
* renderer
;
4074 GtkTreeSelection
* select
;
4077 char * unload_module_name
= NULL
;
4079 dialogue
= gtk_dialog_new_with_buttons(title
,
4082 GTK_STOCK_OK
,GTK_RESPONSE_ACCEPT
,
4083 GTK_STOCK_CANCEL
,GTK_RESPONSE_REJECT
,
4085 gtk_window_set_default_size((GtkWindow
*)dialogue
, 500, 200);
4087 scroll_win
= gtk_scrolled_window_new (NULL
, NULL
);
4088 gtk_widget_show ( scroll_win
);
4089 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll_win
),
4090 GTK_POLICY_AUTOMATIC
, GTK_POLICY_AUTOMATIC
);
4092 store
= gtk_list_store_new (N_COLUMNS
,G_TYPE_STRING
);
4093 tree
= gtk_tree_view_new_with_model(GTK_TREE_MODEL (store
));
4094 gtk_widget_show ( tree
);
4095 g_object_unref (G_OBJECT (store
));
4097 renderer
= gtk_cell_renderer_text_new ();
4098 column
= gtk_tree_view_column_new_with_attributes (column_title
,
4100 "text", MODULE_COLUMN
,
4102 gtk_tree_view_column_set_alignment (column
, 0.5);
4103 gtk_tree_view_column_set_fixed_width (column
, 150);
4104 gtk_tree_view_append_column (GTK_TREE_VIEW (tree
), column
);
4106 select
= gtk_tree_view_get_selection (GTK_TREE_VIEW (tree
));
4107 gtk_tree_selection_set_mode (select
, GTK_SELECTION_SINGLE
);
4109 gtk_container_add (GTK_CONTAINER (scroll_win
), tree
);
4111 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialogue
)->vbox
), scroll_win
,TRUE
, TRUE
,0);
4113 for(i
=0;i
<nb_module
;i
++){
4114 gtk_list_store_append (store
, &iter
);
4115 gtk_list_store_set (store
, &iter
, MODULE_COLUMN
,loaded_module_name
[i
],-1);
4118 id
= gtk_dialog_run(GTK_DIALOG(dialogue
));
4120 case GTK_RESPONSE_ACCEPT
:
4121 case GTK_RESPONSE_OK
:
4122 if (gtk_tree_selection_get_selected (select
, (GtkTreeModel
**)&store
, &iter
)){
4123 gtk_tree_model_get ((GtkTreeModel
*)store
, &iter
, MODULE_COLUMN
, &unload_module_name
, -1);
4125 case GTK_RESPONSE_REJECT
:
4126 case GTK_RESPONSE_CANCEL
:
4128 gtk_widget_destroy(dialogue
);
4132 return unload_module_name
;
4136 /* Insert all menu entry and tool buttons into this main window
4141 void add_all_menu_toolbar_constructors(MainWindow
* mw
, gpointer user_data
)
4145 lttvwindow_viewer_constructor constructor
;
4146 LttvMenus
* global_menu
, * instance_menu
;
4147 LttvToolbars
* global_toolbar
, * instance_toolbar
;
4148 LttvMenuClosure
*menu_item
;
4149 LttvToolbarClosure
*toolbar_item
;
4150 LttvAttributeValue value
;
4151 LttvIAttribute
*global_attributes
= LTTV_IATTRIBUTE(lttv_global_attributes());
4152 LttvIAttribute
*attributes
= mw
->attributes
;
4153 GtkWidget
* tool_menu_title_menu
, *new_widget
, *pixmap
;
4155 g_assert(lttv_iattribute_find_by_path(global_attributes
,
4156 "viewers/menu", LTTV_POINTER
, &value
));
4157 if(*(value
.v_pointer
) == NULL
)
4158 *(value
.v_pointer
) = lttv_menus_new();
4159 global_menu
= (LttvMenus
*)*(value
.v_pointer
);
4161 g_assert(lttv_iattribute_find_by_path(attributes
,
4162 "viewers/menu", LTTV_POINTER
, &value
));
4163 if(*(value
.v_pointer
) == NULL
)
4164 *(value
.v_pointer
) = lttv_menus_new();
4165 instance_menu
= (LttvMenus
*)*(value
.v_pointer
);
4169 g_assert(lttv_iattribute_find_by_path(global_attributes
,
4170 "viewers/toolbar", LTTV_POINTER
, &value
));
4171 if(*(value
.v_pointer
) == NULL
)
4172 *(value
.v_pointer
) = lttv_toolbars_new();
4173 global_toolbar
= (LttvToolbars
*)*(value
.v_pointer
);
4175 g_assert(lttv_iattribute_find_by_path(attributes
,
4176 "viewers/toolbar", LTTV_POINTER
, &value
));
4177 if(*(value
.v_pointer
) == NULL
)
4178 *(value
.v_pointer
) = lttv_toolbars_new();
4179 instance_toolbar
= (LttvToolbars
*)*(value
.v_pointer
);
4181 /* Add missing menu entries to window instance */
4182 for(i
=0;i
<global_menu
->len
;i
++) {
4183 menu_item
= &g_array_index(global_menu
, LttvMenuClosure
, i
);
4185 //add menu_item to window instance;
4186 constructor
= menu_item
->con
;
4187 tool_menu_title_menu
= lookup_widget(mw
->mwindow
,"ToolMenuTitle_menu");
4189 gtk_menu_item_new_with_mnemonic (menu_item
->menu_text
);
4190 gtk_container_add (GTK_CONTAINER (tool_menu_title_menu
),
4192 g_signal_connect ((gpointer
) new_widget
, "activate",
4193 G_CALLBACK (insert_viewer_wrap
),
4195 gtk_widget_show (new_widget
);
4196 lttv_menus_add(instance_menu
, menu_item
->con
,
4197 menu_item
->menu_path
,
4198 menu_item
->menu_text
,
4203 /* Add missing toolbar entries to window instance */
4204 for(i
=0;i
<global_toolbar
->len
;i
++) {
4205 toolbar_item
= &g_array_index(global_toolbar
, LttvToolbarClosure
, i
);
4207 //add toolbar_item to window instance;
4208 constructor
= toolbar_item
->con
;
4209 tool_menu_title_menu
= lookup_widget(mw
->mwindow
,"MToolbar1");
4210 pixbuf
= gdk_pixbuf_new_from_xpm_data((const char**)toolbar_item
->pixmap
);
4211 pixmap
= gtk_image_new_from_pixbuf(pixbuf
);
4213 gtk_toolbar_append_element (GTK_TOOLBAR (tool_menu_title_menu
),
4214 GTK_TOOLBAR_CHILD_BUTTON
,
4217 toolbar_item
->tooltip
, NULL
,
4218 pixmap
, NULL
, NULL
);
4219 gtk_label_set_use_underline(
4220 GTK_LABEL (((GtkToolbarChild
*) (
4221 g_list_last (GTK_TOOLBAR
4222 (tool_menu_title_menu
)->children
)->data
))->label
),
4224 gtk_container_set_border_width (GTK_CONTAINER (new_widget
), 1);
4225 g_signal_connect ((gpointer
) new_widget
,
4227 G_CALLBACK (insert_viewer_wrap
),
4229 gtk_widget_show (new_widget
);
4231 lttv_toolbars_add(instance_toolbar
, toolbar_item
->con
,
4232 toolbar_item
->tooltip
,
4233 toolbar_item
->pixmap
,
4241 /* Create a main window
4244 void construct_main_window(MainWindow
* parent
)
4246 g_debug("construct_main_window()");
4247 GtkWidget
* new_window
; /* New generated main window */
4248 MainWindow
* new_m_window
;/* New main window structure */
4249 GtkNotebook
* notebook
;
4250 LttvIAttribute
*attributes
=
4251 LTTV_IATTRIBUTE(g_object_new(LTTV_ATTRIBUTE_TYPE
, NULL
));
4252 LttvAttributeValue value
;
4255 new_m_window
= g_new(MainWindow
, 1);
4257 // Add the object's information to the module's array
4258 g_main_window_list
= g_slist_append(g_main_window_list
, new_m_window
);
4260 new_window
= create_MWindow();
4261 gtk_widget_show (new_window
);
4263 new_m_window
->mwindow
= new_window
;
4264 new_m_window
->attributes
= attributes
;
4266 g_assert(lttv_iattribute_find_by_path(attributes
,
4267 "viewers/menu", LTTV_POINTER
, &value
));
4268 *(value
.v_pointer
) = lttv_menus_new();
4270 g_assert(lttv_iattribute_find_by_path(attributes
,
4271 "viewers/toolbar", LTTV_POINTER
, &value
));
4272 *(value
.v_pointer
) = lttv_toolbars_new();
4274 add_all_menu_toolbar_constructors(new_m_window
, NULL
);
4276 g_object_set_data_full(G_OBJECT(new_window
),
4278 (gpointer
)new_m_window
,
4279 (GDestroyNotify
)g_free
);
4280 //create a default tab
4281 notebook
= (GtkNotebook
*)lookup_widget(new_m_window
->mwindow
, "MNotebook");
4282 if(notebook
== NULL
){
4283 g_printf("Notebook does not exist\n");
4286 //gtk_notebook_popup_enable (GTK_NOTEBOOK(notebook));
4287 //for now there is no name field in LttvTraceset structure
4288 //Use "Traceset" as the label for the default tab
4290 GtkWidget
* parent_notebook
= lookup_widget(parent
->mwindow
, "MNotebook");
4291 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(parent_notebook
),
4292 gtk_notebook_get_current_page(GTK_NOTEBOOK(parent_notebook
)));
4298 parent_tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
4300 new_tab
= create_tab(new_m_window
, parent_tab
, notebook
, "Traceset");
4302 new_tab
= create_tab(new_m_window
, NULL
, notebook
, "Traceset");
4303 /* First window, use command line trace */
4304 if(g_init_trace
!= NULL
){
4305 lttvwindow_add_trace(new_tab
,
4309 LttvTraceset
*traceset
= new_tab
->traceset_info
->traceset
;
4310 SetTraceset(new_tab
, traceset
);
4312 /* Insert default viewers */
4314 LttvAttributeType type
;
4315 LttvAttributeName name
;
4316 LttvAttributeValue value
;
4317 LttvAttribute
*attribute
;
4319 LttvIAttribute
*attributes_global
=
4320 LTTV_IATTRIBUTE(lttv_global_attributes());
4322 g_assert(attribute
=
4323 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
4324 LTTV_IATTRIBUTE(attributes_global
),
4325 LTTV_VIEWER_CONSTRUCTORS
)));
4327 name
= g_quark_from_string("guievents");
4328 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
4330 if(type
== LTTV_POINTER
) {
4331 lttvwindow_viewer_constructor viewer_constructor
=
4332 (lttvwindow_viewer_constructor
)*value
.v_pointer
;
4333 insert_viewer(new_window
, viewer_constructor
);
4336 name
= g_quark_from_string("guicontrolflow");
4337 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
4339 if(type
== LTTV_POINTER
) {
4340 lttvwindow_viewer_constructor viewer_constructor
=
4341 (lttvwindow_viewer_constructor
)*value
.v_pointer
;
4342 insert_viewer(new_window
, viewer_constructor
);
4345 name
= g_quark_from_string("guistatistics");
4346 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
4348 if(type
== LTTV_POINTER
) {
4349 lttvwindow_viewer_constructor viewer_constructor
=
4350 (lttvwindow_viewer_constructor
)*value
.v_pointer
;
4351 insert_viewer(new_window
, viewer_constructor
);
4357 g_printf("There are now : %d windows\n",g_slist_length(g_main_window_list
));
4361 /* Free the memory occupied by a tab structure
4365 void tab_destructor(Tab
* tab
)
4367 int i
, nb
, ref_count
;
4370 gtk_object_destroy(GTK_OBJECT(tab
->tooltips
));
4373 g_object_unref(tab
->attributes
);
4375 if(tab
->interrupted_state
)
4376 g_object_unref(tab
->interrupted_state
);
4379 if(tab
->traceset_info
->traceset_context
!= NULL
){
4380 //remove state update hooks
4381 lttv_state_remove_event_hooks(
4382 (LttvTracesetState
*)tab
->traceset_info
->
4384 lttv_context_fini(LTTV_TRACESET_CONTEXT(tab
->traceset_info
->
4386 g_object_unref(tab
->traceset_info
->traceset_context
);
4388 if(tab
->traceset_info
->traceset
!= NULL
) {
4389 nb
= lttv_traceset_number(tab
->traceset_info
->traceset
);
4390 for(i
= 0 ; i
< nb
; i
++) {
4391 trace
= lttv_traceset_get(tab
->traceset_info
->traceset
, i
);
4392 ref_count
= lttv_trace_get_ref_number(trace
);
4394 ltt_trace_close(lttv_trace(trace
));
4398 lttv_traceset_destroy(tab
->traceset_info
->traceset
);
4399 /* Remove the idle events requests processing function of the tab */
4400 g_idle_remove_by_data(tab
);
4402 g_slist_free(tab
->events_requests
);
4403 g_free(tab
->traceset_info
);
4408 /* Create a tab and insert it into the current main window
4411 Tab
* create_tab(MainWindow
* mw
, Tab
*copy_tab
,
4412 GtkNotebook
* notebook
, char * label
)
4418 //create a new tab data structure
4421 //construct and initialize the traceset_info
4422 tab
->traceset_info
= g_new(TracesetInfo
,1);
4425 tab
->traceset_info
->traceset
=
4426 lttv_traceset_copy(copy_tab
->traceset_info
->traceset
);
4428 tab
->traceset_info
->traceset
= lttv_traceset_new();
4432 lttv_attribute_write_xml(
4433 lttv_traceset_attribute(tab
->traceset_info
->traceset
),
4439 tab
->time_manager_lock
= FALSE
;
4440 tab
->current_time_manager_lock
= FALSE
;
4442 //FIXME copy not implemented in lower level
4443 tab
->traceset_info
->traceset_context
=
4444 g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
4445 g_assert(tab
->traceset_info
->traceset_context
!= NULL
);
4447 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
),
4448 tab
->traceset_info
->traceset
);
4449 //add state update hooks
4450 lttv_state_add_event_hooks(
4451 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
4453 //determine the current_time and time_window of the tab
4455 if(copy_tab
!= NULL
){
4456 tab
->time_window
= copy_tab
->time_window
;
4457 tab
->current_time
= copy_tab
->current_time
;
4459 tab
->time_window
.start_time
=
4460 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
4461 time_span
.start_time
;
4462 if(DEFAULT_TIME_WIDTH_S
<
4463 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
4464 time_span
.end_time
.tv_sec
)
4465 tmp_time
.tv_sec
= DEFAULT_TIME_WIDTH_S
;
4468 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
4469 time_span
.end_time
.tv_sec
;
4470 tmp_time
.tv_nsec
= 0;
4471 tab
->time_window
.time_width
= tmp_time
;
4472 tab
->current_time
.tv_sec
=
4473 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
4474 time_span
.start_time
.tv_sec
;
4475 tab
->current_time
.tv_nsec
=
4476 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
4477 time_span
.start_time
.tv_nsec
;
4480 tab
->attributes
= LTTV_IATTRIBUTE(g_object_new(LTTV_ATTRIBUTE_TYPE
, NULL
));
4481 tab
->interrupted_state
= g_object_new(LTTV_ATTRIBUTE_TYPE
, NULL
);
4483 tab
->vbox
= gtk_vbox_new(FALSE
, 2);
4484 tab
->viewer_container
= gtk_vbox_new(TRUE
, 2);
4485 tab
->scrollbar
= gtk_hscrollbar_new(NULL
);
4486 //tab->multivpaned = gtk_multi_vpaned_new();
4488 gtk_box_pack_start(GTK_BOX(tab
->vbox
),
4489 tab
->viewer_container
,
4491 TRUE
, /* Give the extra space to the child */
4492 0); /* No padding */
4494 /* Create the timebar */
4496 tab
->MTimebar
= gtk_hbox_new(FALSE
, 2);
4497 gtk_widget_show(tab
->MTimebar
);
4498 tab
->tooltips
= gtk_tooltips_new();
4500 tab
->MEventBox1a
= gtk_event_box_new();
4501 gtk_widget_show(tab
->MEventBox1a
);
4502 gtk_tooltips_set_tip(tab
->tooltips
, tab
->MEventBox1a
,
4503 "Paste Start and End Times Here", "");
4504 tab
->MText1a
= gtk_label_new("Time Frame ");
4505 gtk_widget_show(tab
->MText1a
);
4506 gtk_container_add(GTK_CONTAINER(tab
->MEventBox1a
), tab
->MText1a
);
4507 tab
->MEventBox1b
= gtk_event_box_new();
4508 gtk_widget_show(tab
->MEventBox1b
);
4509 gtk_tooltips_set_tip(tab
->tooltips
, tab
->MEventBox1b
,
4510 "Paste Start Time Here", "");
4511 tab
->MText1b
= gtk_label_new("start: ");
4512 gtk_widget_show(tab
->MText1b
);
4513 gtk_container_add(GTK_CONTAINER(tab
->MEventBox1b
), tab
->MText1b
);
4514 tab
->MText2
= gtk_label_new("s");
4515 gtk_widget_show(tab
->MText2
);
4516 tab
->MText3a
= gtk_label_new("ns");
4517 gtk_widget_show(tab
->MText3a
);
4518 tab
->MEventBox3b
= gtk_event_box_new();
4519 gtk_widget_show(tab
->MEventBox3b
);
4520 gtk_tooltips_set_tip(tab
->tooltips
, tab
->MEventBox3b
,
4521 "Paste End Time Here", "");
4522 tab
->MText3b
= gtk_label_new("end:");
4523 gtk_widget_show(tab
->MText3b
);
4524 gtk_container_add(GTK_CONTAINER(tab
->MEventBox3b
), tab
->MText3b
);
4525 tab
->MText4
= gtk_label_new("s");
4526 gtk_widget_show(tab
->MText4
);
4527 tab
->MText5a
= gtk_label_new("ns");
4528 gtk_widget_show(tab
->MText5a
);
4529 tab
->MEventBox5b
= gtk_event_box_new();
4530 gtk_widget_show(tab
->MEventBox5b
);
4531 gtk_tooltips_set_tip(tab
->tooltips
, tab
->MEventBox5b
,
4532 "Paste Current Time Here", "");
4533 tab
->MText5b
= gtk_label_new("Current Time:");
4534 gtk_widget_show(tab
->MText5b
);
4535 gtk_container_add(GTK_CONTAINER(tab
->MEventBox5b
), tab
->MText5b
);
4536 tab
->MText6
= gtk_label_new("s");
4537 gtk_widget_show(tab
->MText6
);
4538 tab
->MText7
= gtk_label_new("ns");
4539 gtk_widget_show(tab
->MText7
);
4541 tab
->MEntry1
= gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4542 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab
->MEntry1
),0);
4543 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab
->MEntry1
),TRUE
);
4544 gtk_widget_show(tab
->MEntry1
);
4545 tab
->MEntry2
= gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4546 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab
->MEntry2
),0);
4547 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab
->MEntry2
),TRUE
);
4548 gtk_widget_show(tab
->MEntry2
);
4549 tab
->MEntry3
= gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4550 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab
->MEntry3
),0);
4551 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab
->MEntry3
),TRUE
);
4552 gtk_widget_show(tab
->MEntry3
);
4553 tab
->MEntry4
= gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4554 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab
->MEntry4
),0);
4555 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab
->MEntry4
),TRUE
);
4556 gtk_widget_show(tab
->MEntry4
);
4557 tab
->MEntry5
= gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4558 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab
->MEntry5
),0);
4559 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab
->MEntry5
),TRUE
);
4560 gtk_widget_show(tab
->MEntry5
);
4561 tab
->MEntry6
= gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4562 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab
->MEntry6
),0);
4563 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab
->MEntry6
),TRUE
);
4564 gtk_widget_show(tab
->MEntry6
);
4567 GtkWidget
*temp_widget
;
4569 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEventBox1a
, FALSE
,
4571 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEventBox1b
, FALSE
,
4573 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEntry1
, FALSE
, FALSE
, 0);
4574 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MText2
, FALSE
, FALSE
, 0);
4575 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEntry2
, FALSE
, FALSE
, 0);
4576 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MText3a
, FALSE
, FALSE
, 0);
4577 temp_widget
= gtk_vseparator_new();
4578 gtk_widget_show(temp_widget
);
4579 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), temp_widget
, FALSE
, FALSE
, 0);
4580 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEventBox3b
, FALSE
,
4582 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEntry3
, FALSE
, FALSE
, 0);
4583 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MText4
, FALSE
, FALSE
, 0);
4584 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEntry4
, FALSE
, FALSE
, 0);
4585 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MText5a
, FALSE
, FALSE
, 0);
4586 temp_widget
= gtk_vseparator_new();
4587 gtk_widget_show(temp_widget
);
4588 gtk_box_pack_end (GTK_BOX (tab
->MTimebar
), tab
->MText7
, FALSE
, FALSE
, 0);
4589 gtk_box_pack_end (GTK_BOX (tab
->MTimebar
), tab
->MEntry6
, FALSE
, FALSE
, 0);
4590 gtk_box_pack_end (GTK_BOX (tab
->MTimebar
), tab
->MText6
, FALSE
, FALSE
, 0);
4591 gtk_box_pack_end (GTK_BOX (tab
->MTimebar
), tab
->MEntry5
, FALSE
, FALSE
, 0);
4592 gtk_box_pack_end (GTK_BOX (tab
->MTimebar
), tab
->MEventBox5b
, FALSE
,
4594 gtk_box_pack_end (GTK_BOX (tab
->MTimebar
), temp_widget
, FALSE
, FALSE
, 0);
4597 //GtkWidget *test = gtk_button_new_with_label("drop");
4598 //gtk_button_set_relief(GTK_BUTTON(test), GTK_RELIEF_NONE);
4599 //gtk_widget_show(test);
4600 //gtk_box_pack_end(GTK_BOX (tab->MTimebar), test, FALSE, FALSE, 0);
4601 //gtk_widget_add_events(tab->MText1, GDK_ALL_EVENTS_MASK);//GDK_BUTTON_PRESS_MASK);
4602 /*GtkWidget *event_box = gtk_event_box_new();
4603 gtk_widget_show(event_box);
4604 gtk_tooltips_set_tip(tooltips, event_box,
4605 "Paste Current Time Here", "");
4606 gtk_box_pack_end(GTK_BOX (tab->MTimebar), event_box, FALSE, FALSE, 0);
4607 GtkWidget *test = gtk_label_new("drop");
4608 gtk_container_add(GTK_CONTAINER(event_box), test);
4609 gtk_widget_show(test);
4610 g_signal_connect (G_OBJECT(event_box),
4611 "button-press-event",
4612 G_CALLBACK (on_MText1_paste),
4616 g_signal_connect (G_OBJECT(tab
->MEventBox1a
),
4617 "button-press-event",
4618 G_CALLBACK (on_MEventBox1a_paste
),
4621 g_signal_connect (G_OBJECT(tab
->MEventBox1b
),
4622 "button-press-event",
4623 G_CALLBACK (on_MEventBox1b_paste
),
4625 g_signal_connect (G_OBJECT(tab
->MEventBox3b
),
4626 "button-press-event",
4627 G_CALLBACK (on_MEventBox3b_paste
),
4629 g_signal_connect (G_OBJECT(tab
->MEventBox5b
),
4630 "button-press-event",
4631 G_CALLBACK (on_MEventBox5b_paste
),
4635 gtk_box_pack_end(GTK_BOX(tab
->vbox
),
4637 FALSE
, /* Do not expand */
4638 FALSE
, /* Fill has no effect here (expand false) */
4639 0); /* No padding */
4641 gtk_box_pack_end(GTK_BOX(tab
->vbox
),
4643 FALSE
, /* Do not expand */
4644 FALSE
, /* Fill has no effect here (expand false) */
4645 0); /* No padding */
4647 g_object_set_data(G_OBJECT(tab
->viewer_container
), "focused_viewer", NULL
);
4653 // Display a label with a X
4654 GtkWidget *w_hbox = gtk_hbox_new(FALSE, 4);
4655 GtkWidget *w_label = gtk_label_new (label);
4656 GtkWidget *pixmap = create_pixmap(GTK_WIDGET(notebook), "close.png");
4657 GtkWidget *w_button = gtk_button_new ();
4658 gtk_container_add(GTK_CONTAINER(w_button), pixmap);
4659 //GtkWidget *w_button = gtk_button_new_with_label("x");
4661 gtk_button_set_relief(GTK_BUTTON(w_button), GTK_RELIEF_NONE);
4663 gtk_box_pack_start(GTK_BOX(w_hbox), w_label, TRUE, TRUE, 0);
4664 gtk_box_pack_end(GTK_BOX(w_hbox), w_button, FALSE,
4667 g_signal_connect_swapped (w_button, "clicked",
4668 G_CALLBACK (on_close_tab_X_clicked),
4671 gtk_widget_set_state(w_button, GTK_STATE_ACTIVE);
4673 gtk_widget_show (w_label);
4674 gtk_widget_show (pixmap);
4675 gtk_widget_show (w_button);
4676 gtk_widget_show (w_hbox);
4678 tab->label = w_hbox;
4682 tab
->label
= gtk_label_new (label
);
4684 gtk_widget_show(tab
->label
);
4685 gtk_widget_show(tab
->scrollbar
);
4686 gtk_widget_show(tab
->viewer_container
);
4687 gtk_widget_show(tab
->vbox
);
4688 //gtk_widget_show(tab->multivpaned);
4691 /* Start with empty events requests list */
4692 tab
->events_requests
= NULL
;
4693 tab
->events_request_pending
= FALSE
;
4695 g_object_set_data_full(
4696 G_OBJECT(tab
->vbox
),
4699 (GDestroyNotify
)tab_destructor
);
4701 g_signal_connect(G_OBJECT(tab
->scrollbar
), "value-changed",
4702 G_CALLBACK(scroll_value_changed_cb
), tab
);
4704 g_signal_connect ((gpointer
) tab
->MEntry1
, "value-changed",
4705 G_CALLBACK (on_MEntry1_value_changed
),
4707 g_signal_connect ((gpointer
) tab
->MEntry2
, "value-changed",
4708 G_CALLBACK (on_MEntry2_value_changed
),
4710 g_signal_connect ((gpointer
) tab
->MEntry3
, "value-changed",
4711 G_CALLBACK (on_MEntry3_value_changed
),
4713 g_signal_connect ((gpointer
) tab
->MEntry4
, "value-changed",
4714 G_CALLBACK (on_MEntry4_value_changed
),
4716 g_signal_connect ((gpointer
) tab
->MEntry5
, "value-changed",
4717 G_CALLBACK (on_MEntry5_value_changed
),
4719 g_signal_connect ((gpointer
) tab
->MEntry6
, "value-changed",
4720 G_CALLBACK (on_MEntry6_value_changed
),
4723 //g_signal_connect(G_OBJECT(tab->scrollbar), "changed",
4724 // G_CALLBACK(scroll_value_changed_cb), tab);
4727 //insert tab into notebook
4728 gtk_notebook_append_page(notebook
,
4731 list
= gtk_container_get_children(GTK_CONTAINER(notebook
));
4732 gtk_notebook_set_current_page(notebook
,g_list_length(list
)-1);
4733 // always show : not if(g_list_length(list)>1)
4734 gtk_notebook_set_show_tabs(notebook
, TRUE
);
4740 * execute_events_requests
4742 * Idle function that executes the pending requests for a tab.
4744 * @return return value : TRUE : keep the idle function, FALSE : remove it.
4746 gboolean
execute_events_requests(Tab
*tab
)
4748 return ( lttvwindow_process_pending_requests(tab
) );