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 <lttv/filter.h>
43 #include <lttvwindow/mainwindow.h>
44 #include <lttvwindow/mainwindow-private.h>
45 #include <lttvwindow/menu.h>
46 #include <lttvwindow/toolbar.h>
47 #include <lttvwindow/lttvwindow.h>
48 #include <lttvwindow/lttvwindowtraces.h>
49 #include <lttvwindow/gtkdirsel.h>
52 static LttTime lttvwindow_default_time_width
= { 1, 0 };
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 Tab
* create_tab(MainWindow
* mw
, Tab
*copy_tab
,
72 GtkNotebook
* notebook
, char * label
);
74 static void insert_viewer(GtkWidget
* widget
, lttvwindow_viewer_constructor constructor
);
76 Tab
*create_new_tab(GtkWidget
* widget
, gpointer user_data
);
78 static gboolean
lttvwindow_process_pending_requests(Tab
*tab
);
92 /* Pasting routines */
94 static void MEventBox1a_receive(GtkClipboard
*clipboard
,
98 if(text
== NULL
) return;
99 Tab
*tab
= (Tab
*)data
;
100 gchar buffer
[CLIP_BUF
];
101 gchar
*ptr
= buffer
, *ptr_ssec
, *ptr_snsec
, *ptr_esec
, *ptr_ensec
;
103 strncpy(buffer
, text
, CLIP_BUF
);
106 while(!isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
107 /* remove leading junk */
109 while(isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
110 /* read all the first number */
114 while(!isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
115 /* remove leading junk */
117 while(isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
118 /* read all the first number */
122 while(!isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
123 /* remove leading junk */
125 while(isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
126 /* read all the first number */
130 while(!isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
131 /* remove leading junk */
133 while(isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
134 /* read all the first number */
137 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry1
),
138 (double)strtoul(ptr_ssec
, NULL
, 10));
139 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry2
),
140 (double)strtoul(ptr_snsec
, NULL
, 10));
141 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry3
),
142 (double)strtoul(ptr_esec
, NULL
, 10));
143 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry4
),
144 (double)strtoul(ptr_ensec
, NULL
, 10));
147 static gboolean
on_MEventBox1a_paste(GtkWidget
*widget
, GdkEventButton
*event
,
150 Tab
*tab
= (Tab
*)data
;
152 GtkClipboard
*clip
= gtk_clipboard_get_for_display(gdk_display_get_default(),
153 GDK_SELECTION_PRIMARY
);
154 gtk_clipboard_request_text(clip
,
155 (GtkClipboardTextReceivedFunc
)MEventBox1a_receive
,
162 static void MEventBox1b_receive(GtkClipboard
*clipboard
,
166 if(text
== NULL
) return;
167 Tab
*tab
= (Tab
*)data
;
168 gchar buffer
[CLIP_BUF
];
169 gchar
*ptr
= buffer
, *ptr_sec
, *ptr_nsec
;
171 strncpy(buffer
, text
, CLIP_BUF
);
173 while(!isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
174 /* remove leading junk */
176 while(isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
177 /* read all the first number */
181 while(!isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
182 /* remove leading junk */
184 while(isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
185 /* read all the first number */
188 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry1
),
189 (double)strtoul(ptr_sec
, NULL
, 10));
190 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry2
),
191 (double)strtoul(ptr_nsec
, NULL
, 10));
195 static gboolean
on_MEventBox1b_paste(GtkWidget
*widget
, GdkEventButton
*event
,
198 Tab
*tab
= (Tab
*)data
;
200 GtkClipboard
*clip
= gtk_clipboard_get_for_display(gdk_display_get_default(),
201 GDK_SELECTION_PRIMARY
);
202 gtk_clipboard_request_text(clip
,
203 (GtkClipboardTextReceivedFunc
)MEventBox1b_receive
,
209 static void MEventBox3b_receive(GtkClipboard
*clipboard
,
213 if(text
== NULL
) return;
214 Tab
*tab
= (Tab
*)data
;
215 gchar buffer
[CLIP_BUF
];
216 gchar
*ptr
= buffer
, *ptr_sec
, *ptr_nsec
;
218 strncpy(buffer
, text
, CLIP_BUF
);
220 while(!isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
221 /* remove leading junk */
223 while(isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
224 /* read all the first number */
228 while(!isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
229 /* remove leading junk */
231 while(isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
232 /* read all the first number */
235 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry3
),
236 (double)strtoul(ptr_sec
, NULL
, 10));
237 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry4
),
238 (double)strtoul(ptr_nsec
, NULL
, 10));
242 static gboolean
on_MEventBox3b_paste(GtkWidget
*widget
, GdkEventButton
*event
,
245 Tab
*tab
= (Tab
*)data
;
247 GtkClipboard
*clip
= gtk_clipboard_get_for_display(gdk_display_get_default(),
248 GDK_SELECTION_PRIMARY
);
249 gtk_clipboard_request_text(clip
,
250 (GtkClipboardTextReceivedFunc
)MEventBox3b_receive
,
256 static void MEventBox5b_receive(GtkClipboard
*clipboard
,
260 if(text
== NULL
) return;
261 Tab
*tab
= (Tab
*)data
;
262 gchar buffer
[CLIP_BUF
];
263 gchar
*ptr
= buffer
, *ptr_sec
, *ptr_nsec
;
265 strncpy(buffer
, text
, CLIP_BUF
);
267 while(!isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
268 /* remove leading junk */
270 while(isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
271 /* read all the first number */
275 while(!isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
276 /* remove leading junk */
278 while(isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
279 /* read all the first number */
282 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry5
),
283 (double)strtoul(ptr_sec
, NULL
, 10));
284 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry6
),
285 (double)strtoul(ptr_nsec
, NULL
, 10));
289 static gboolean
on_MEventBox5b_paste(GtkWidget
*widget
, GdkEventButton
*event
,
292 Tab
*tab
= (Tab
*)data
;
294 GtkClipboard
*clip
= gtk_clipboard_get_for_display(gdk_display_get_default(),
295 GDK_SELECTION_PRIMARY
);
296 gtk_clipboard_request_text(clip
,
297 (GtkClipboardTextReceivedFunc
)MEventBox5b_receive
,
303 static gboolean
viewer_grab_focus(GtkWidget
*widget
, GdkEventButton
*event
,
306 GtkWidget
*viewer
= GTK_WIDGET(data
);
307 GtkWidget
*viewer_container
= gtk_widget_get_parent(viewer
);
309 g_debug("FOCUS GRABBED");
310 g_object_set_data(G_OBJECT(viewer_container
), "focused_viewer", viewer
);
315 static void connect_focus_recursive(GtkWidget
*widget
,
318 if(GTK_IS_CONTAINER(widget
)) {
319 gtk_container_forall(GTK_CONTAINER(widget
),
320 (GtkCallback
)connect_focus_recursive
,
324 if(GTK_IS_TREE_VIEW(widget
)) {
325 gtk_tree_view_set_headers_clickable(GTK_TREE_VIEW(widget
), TRUE
);
327 gtk_widget_add_events(widget
, GDK_BUTTON_PRESS_MASK
);
328 g_signal_connect (G_OBJECT(widget
),
329 "button-press-event",
330 G_CALLBACK (viewer_grab_focus
),
334 /* Stop all the processings and call gtk_main_quit() */
335 static void mainwindow_quit()
337 lttvwindowtraces_unregister_requests(g_quark_from_string("stats"));
338 lttvwindowtraces_unregister_requests(g_quark_from_string("state"));
339 lttvwindowtraces_unregister_computation_hooks(g_quark_from_string("stats"));
340 lttvwindowtraces_unregister_computation_hooks(g_quark_from_string("state"));
346 /* insert_viewer function constructs an instance of a viewer first,
347 * then inserts the widget of the instance into the container of the
352 insert_viewer_wrap(GtkWidget
*menuitem
, gpointer user_data
)
354 insert_viewer((GtkWidget
*)menuitem
, (lttvwindow_viewer_constructor
)user_data
);
358 /* internal functions */
359 void insert_viewer(GtkWidget
* widget
, lttvwindow_viewer_constructor constructor
)
361 GtkWidget
* viewer_container
;
362 MainWindow
* mw_data
= get_window_data_struct(widget
);
363 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
365 TimeInterval
* time_interval
;
366 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
367 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
371 tab
= create_new_tab(widget
, NULL
);
373 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
376 viewer_container
= tab
->viewer_container
;
378 viewer
= (GtkWidget
*)constructor(tab
);
381 //gtk_multivpaned_widget_add(GTK_MULTIVPANED(multivpaned), viewer);
383 gtk_box_pack_end(GTK_BOX(viewer_container
),
389 /* We want to connect the viewer_grab_focus to EVERY
390 * child of this widget. The little trick is to get each child
391 * of each GTK_CONTAINER, even subchildren.
393 connect_focus_recursive(viewer
, viewer
);
398 * Function to set/update traceset for the viewers
399 * @param tab viewer's tab
400 * @param traceset traceset of the main window.
402 * 0 : traceset updated
403 * 1 : no traceset hooks to update; not an error.
406 int SetTraceset(Tab
* tab
, LttvTraceset
*traceset
)
408 LttvTracesetContext
*tsc
=
409 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
410 TimeInterval time_span
= tsc
->time_span
;
411 TimeWindow new_time_window
= tab
->time_window
;
412 LttTime new_current_time
= tab
->current_time
;
414 /* Set the tab's time window and current time if
416 if(ltt_time_compare(tab
->time_window
.start_time
, time_span
.start_time
) < 0
417 || ltt_time_compare(tab
->time_window
.end_time
,
418 time_span
.end_time
) > 0) {
419 new_time_window
.start_time
= time_span
.start_time
;
421 new_current_time
= time_span
.start_time
;
425 if(ltt_time_compare(lttvwindow_default_time_width
,
426 ltt_time_sub(time_span
.end_time
, time_span
.start_time
)) < 0
428 ltt_time_compare(time_span
.end_time
, time_span
.start_time
) == 0)
429 tmp_time
= lttvwindow_default_time_width
;
431 tmp_time
= time_span
.end_time
;
433 new_time_window
.time_width
= tmp_time
;
434 new_time_window
.time_width_double
= ltt_time_to_double(tmp_time
);
435 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
436 new_time_window
.time_width
) ;
443 GtkAdjustment
*adjustment
= gtk_range_get_adjustment(GTK_RANGE(tab
->scrollbar
));
444 LttTime upper
= ltt_time_sub(time_span
.end_time
, time_span
.start_time
);
446 g_object_set(G_OBJECT(adjustment
),
450 ltt_time_to_double(upper
)
451 * NANOSECONDS_PER_SECOND
, /* upper */
453 ltt_time_to_double(tab
->time_window
.time_width
)
454 / SCROLL_STEP_PER_PAGE
455 * NANOSECONDS_PER_SECOND
, /* step increment */
457 ltt_time_to_double(tab
->time_window
.time_width
)
458 * NANOSECONDS_PER_SECOND
, /* page increment */
460 ltt_time_to_double(tab
->time_window
.time_width
)
461 * NANOSECONDS_PER_SECOND
, /* page size */
463 gtk_adjustment_changed(adjustment
);
465 g_object_set(G_OBJECT(adjustment
),
468 ltt_time_sub(tab
->time_window
.start_time
, time_span
.start_time
))
469 * NANOSECONDS_PER_SECOND
, /* value */
471 gtk_adjustment_value_changed(adjustment
);
473 /* set the time bar. The value callbacks will change their nsec themself */
475 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry1
),
476 (double)time_span
.start_time
.tv_sec
,
477 (double)time_span
.end_time
.tv_sec
);
480 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry3
),
481 (double)time_span
.start_time
.tv_sec
,
482 (double)time_span
.end_time
.tv_sec
);
484 /* current seconds */
485 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry5
),
486 (double)time_span
.start_time
.tv_sec
,
487 (double)time_span
.end_time
.tv_sec
);
490 /* Finally, call the update hooks of the viewers */
492 LttvAttributeValue value
;
496 g_assert( lttv_iattribute_find_by_path(tab
->attributes
,
497 "hooks/updatetraceset", LTTV_POINTER
, &value
));
499 tmp
= (LttvHooks
*)*(value
.v_pointer
);
500 if(tmp
== NULL
) retval
= 1;
501 else lttv_hooks_call(tmp
,traceset
);
503 time_change_manager(tab
, new_time_window
);
504 current_time_change_manager(tab
, new_current_time
);
510 * Function to set/update filter for the viewers
511 * @param tab viewer's tab
512 * @param filter filter of the main window.
515 * 0 : filters updated
516 * 1 : no filter hooks to update; not an error.
519 int SetFilter(Tab
* tab
, gpointer filter
)
522 LttvAttributeValue value
;
524 g_assert(lttv_iattribute_find_by_path(tab
->attributes
,
525 "hooks/updatefilter", LTTV_POINTER
, &value
));
527 tmp
= (LttvHooks
*)*(value
.v_pointer
);
529 if(tmp
== NULL
) return 1;
530 lttv_hooks_call(tmp
,filter
);
538 * Function to redraw each viewer belonging to the current tab
539 * @param tab viewer's tab
542 void update_traceset(Tab
*tab
)
544 LttvAttributeValue value
;
546 g_assert(lttv_iattribute_find_by_path(tab
->attributes
,
547 "hooks/updatetraceset", LTTV_POINTER
, &value
));
548 tmp
= (LttvHooks
*)*(value
.v_pointer
);
549 if(tmp
== NULL
) return;
550 lttv_hooks_call(tmp
, NULL
);
554 /* get_label function is used to get user input, it displays an input
555 * box, which allows user to input a string
558 void get_label_string (GtkWidget
* text
, gchar
* label
)
560 GtkEntry
* entry
= (GtkEntry
*)text
;
561 if(strlen(gtk_entry_get_text(entry
))!=0)
562 strcpy(label
,gtk_entry_get_text(entry
));
565 gboolean
get_label(MainWindow
* mw
, gchar
* str
, gchar
* dialogue_title
, gchar
* label_str
)
567 GtkWidget
* dialogue
;
572 dialogue
= gtk_dialog_new_with_buttons(dialogue_title
,NULL
,
574 GTK_STOCK_OK
,GTK_RESPONSE_ACCEPT
,
575 GTK_STOCK_CANCEL
,GTK_RESPONSE_REJECT
,
578 label
= gtk_label_new(label_str
);
579 gtk_widget_show(label
);
581 text
= gtk_entry_new();
582 gtk_widget_show(text
);
584 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialogue
)->vbox
), label
,TRUE
, TRUE
,0);
585 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialogue
)->vbox
), text
,FALSE
, FALSE
,0);
587 id
= gtk_dialog_run(GTK_DIALOG(dialogue
));
589 case GTK_RESPONSE_ACCEPT
:
590 get_label_string(text
,str
);
591 gtk_widget_destroy(dialogue
);
593 case GTK_RESPONSE_REJECT
:
595 gtk_widget_destroy(dialogue
);
602 /* get_window_data_struct function is actually a lookup function,
603 * given a widget which is in the tree of the main window, it will
604 * return the MainWindow data structure associated with main window
607 MainWindow
* get_window_data_struct(GtkWidget
* widget
)
610 MainWindow
* mw_data
;
612 mw
= lookup_widget(widget
, "MWindow");
614 g_info("Main window does not exist\n");
618 mw_data
= (MainWindow
*) g_object_get_data(G_OBJECT(mw
),"main_window_data");
620 g_warning("Main window data does not exist\n");
627 /* create_new_window function, just constructs a new main window
630 void create_new_window(GtkWidget
* widget
, gpointer user_data
, gboolean clone
)
632 MainWindow
* parent
= get_window_data_struct(widget
);
635 g_info("Clone : use the same traceset\n");
636 construct_main_window(parent
);
638 g_info("Empty : traceset is set to NULL\n");
639 construct_main_window(NULL
);
643 /* Get the currently focused viewer.
644 * If no viewer is focused, use the first one.
646 * If no viewer available, return NULL.
648 GtkWidget
*viewer_container_focus(GtkWidget
*container
)
652 widget
= (GtkWidget
*)g_object_get_data(G_OBJECT(container
),
656 g_debug("no widget focused");
657 GList
*children
= gtk_container_get_children(GTK_CONTAINER(container
));
660 widget
= GTK_WIDGET(children
->data
);
661 g_object_set_data(G_OBJECT(container
),
671 gint
viewer_container_position(GtkWidget
*container
, GtkWidget
*child
)
674 if(child
== NULL
) return -1;
678 memset(&value
, 0, sizeof(GValue
));
679 g_value_init(&value
, G_TYPE_INT
);
680 gtk_container_child_get_property(GTK_CONTAINER(container
),
684 pos
= g_value_get_int(&value
);
690 /* move_*_viewer functions move the selected view up/down in
694 void move_down_viewer(GtkWidget
* widget
, gpointer user_data
)
696 MainWindow
* mw
= get_window_data_struct(widget
);
697 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
699 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
700 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
706 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
709 //gtk_multivpaned_widget_move_up(GTK_MULTIVPANED(tab->multivpaned));
711 /* change the position in the vbox */
712 GtkWidget
*focus_widget
;
714 focus_widget
= viewer_container_focus(tab
->viewer_container
);
715 position
= viewer_container_position(tab
->viewer_container
, focus_widget
);
718 /* can move up one position */
719 gtk_box_reorder_child(GTK_BOX(tab
->viewer_container
),
726 void move_up_viewer(GtkWidget
* widget
, gpointer user_data
)
728 MainWindow
* mw
= get_window_data_struct(widget
);
729 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
731 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
732 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
738 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
741 //gtk_multivpaned_widget_move_down(GTK_MULTIVPANED(tab->multivpaned));
742 /* change the position in the vbox */
743 GtkWidget
*focus_widget
;
745 focus_widget
= viewer_container_focus(tab
->viewer_container
);
746 position
= viewer_container_position(tab
->viewer_container
, focus_widget
);
750 g_list_length(gtk_container_get_children(
751 GTK_CONTAINER(tab
->viewer_container
)))-1
753 /* can move down one position */
754 gtk_box_reorder_child(GTK_BOX(tab
->viewer_container
),
762 /* delete_viewer deletes the selected viewer in the current tab
765 void delete_viewer(GtkWidget
* widget
, gpointer user_data
)
767 MainWindow
* mw
= get_window_data_struct(widget
);
768 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
770 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
771 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
777 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
780 //gtk_multivpaned_widget_delete(GTK_MULTIVPANED(tab->multivpaned));
782 GtkWidget
*focus_widget
= viewer_container_focus(tab
->viewer_container
);
784 if(focus_widget
!= NULL
)
785 gtk_widget_destroy(focus_widget
);
787 g_object_set_data(G_OBJECT(tab
->viewer_container
), "focused_viewer", NULL
);
791 /* open_traceset will open a traceset saved in a file
792 * Right now, it is not finished yet, (not working)
796 void open_traceset(GtkWidget
* widget
, gpointer user_data
)
800 LttvTraceset
* traceset
;
801 MainWindow
* mw_data
= get_window_data_struct(widget
);
802 GtkFileSelection
* file_selector
=
803 (GtkFileSelection
*)gtk_file_selection_new("Select a traceset");
805 gtk_file_selection_hide_fileop_buttons(file_selector
);
807 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
809 case GTK_RESPONSE_ACCEPT
:
810 case GTK_RESPONSE_OK
:
811 dir
= gtk_file_selection_get_selections (file_selector
);
812 traceset
= lttv_traceset_load(dir
[0]);
813 g_info("Open a trace set %s\n", dir
[0]);
816 case GTK_RESPONSE_REJECT
:
817 case GTK_RESPONSE_CANCEL
:
819 gtk_widget_destroy((GtkWidget
*)file_selector
);
825 /* lttvwindow_process_pending_requests
827 * This internal function gets called by g_idle, taking care of the pending
828 * requests. It is responsible for concatenation of time intervals and position
829 * requests. It does it with the following algorithm organizing process traceset
830 * calls. Here is the detailed description of the way it works :
832 * - Events Requests Servicing Algorithm
834 * Data structures necessary :
836 * List of requests added to context : list_in
837 * List of requests not added to context : list_out
842 * list_out : many events requests
844 * FIXME : insert rest of algorithm here
848 #define list_out tab->events_requests
850 gboolean
lttvwindow_process_pending_requests(Tab
*tab
)
853 LttvTracesetContext
*tsc
;
854 LttvTracefileContext
*tfc
;
855 GSList
*list_in
= NULL
;
859 LttvTracesetContextPosition
*end_position
;
862 g_critical("Foreground processing : tab does not exist. Processing removed.");
866 /* There is no events requests pending : we should never have been called! */
867 g_assert(g_slist_length(list_out
) != 0);
869 tsc
= LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
871 //set the cursor to be X shape, indicating that the computer is busy in doing its job
873 new = gdk_cursor_new(GDK_X_CURSOR
);
874 widget
= lookup_widget(tab
->mw
->mwindow
, "MToolbar1");
875 win
= gtk_widget_get_parent_window(widget
);
876 gdk_window_set_cursor(win
, new);
877 gdk_cursor_unref(new);
878 gdk_window_stick(win
);
879 gdk_window_unstick(win
);
882 g_debug("SIZE events req len : %d", g_slist_length(list_out
));
884 /* Preliminary check for no trace in traceset */
885 /* Unregister the routine if empty, empty list_out too */
886 if(lttv_traceset_number(tsc
->ts
) == 0) {
888 /* - For each req in list_out */
889 GSList
*iter
= list_out
;
891 while(iter
!= NULL
) {
893 gboolean remove
= FALSE
;
894 gboolean free_data
= FALSE
;
895 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
897 /* - Call end request for req */
898 if(events_request
->servicing
== TRUE
)
899 lttv_hooks_call(events_request
->after_request
, (gpointer
)tsc
);
901 /* - remove req from list_out */
902 /* Destroy the request */
909 GSList
*remove_iter
= iter
;
911 iter
= g_slist_next(iter
);
912 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
913 list_out
= g_slist_remove_link(list_out
, remove_iter
);
914 } else { // not remove
915 iter
= g_slist_next(iter
);
920 /* 0.1 Lock Traces */
925 iter_trace
<lttv_traceset_number(tsc
->ts
);
927 LttvTrace
*trace_v
= lttv_traceset_get(tsc
->ts
, iter_trace
);
929 if(lttvwindowtraces_lock(trace_v
) != 0) {
930 g_critical("Foreground processing : Unable to get trace lock");
931 return TRUE
; /* Cannot get lock, try later */
936 /* 0.2 Seek tracefiles positions to context position */
937 //g_assert(lttv_process_traceset_seek_position(tsc, sync_position) == 0);
938 lttv_process_traceset_synchronize_tracefiles(tsc
);
941 /* Events processing algorithm implementation */
942 /* Warning : the gtk_events_pending takes a LOT of cpu time. So what we do
943 * instead is to leave the control to GTK and take it back.
945 /* A. Servicing loop */
946 //while( (g_slist_length(list_in) != 0 || g_slist_length(list_out) != 0)) {
947 if((g_slist_length(list_in
) != 0 || g_slist_length(list_out
) != 0)) {
949 /* 1. If list_in is empty (need a seek) */
950 if( g_slist_length(list_in
) == 0 ) {
952 /* list in is empty, need a seek */
954 /* 1.1 Add requests to list_in */
955 GSList
*ltime
= NULL
;
959 /* 1.1.1 Find all time requests with the lowest start time in list_out
962 if(g_slist_length(list_out
) > 0)
963 ltime
= g_slist_append(ltime
, g_slist_nth_data(list_out
, 0));
964 for(iter
=g_slist_nth(list_out
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
965 /* Find all time requests with the lowest start time in list_out */
966 EventsRequest
*event_request_ltime
= (EventsRequest
*)g_slist_nth_data(ltime
, 0);
967 EventsRequest
*event_request_list_out
= (EventsRequest
*)iter
->data
;
970 comp
= ltt_time_compare(event_request_ltime
->start_time
,
971 event_request_list_out
->start_time
);
973 ltime
= g_slist_append(ltime
, event_request_list_out
);
975 /* Remove all elements from ltime, and add current */
977 ltime
= g_slist_delete_link(ltime
, g_slist_nth(ltime
, 0));
978 ltime
= g_slist_append(ltime
, event_request_list_out
);
982 /* 1.1.2 Find all position requests with the lowest position in list_out
985 if(g_slist_length(list_out
) > 0)
986 lpos
= g_slist_append(lpos
, g_slist_nth_data(list_out
, 0));
987 for(iter
=g_slist_nth(list_out
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
988 /* Find all position requests with the lowest position in list_out */
989 EventsRequest
*event_request_lpos
= (EventsRequest
*)g_slist_nth_data(lpos
, 0);
990 EventsRequest
*event_request_list_out
= (EventsRequest
*)iter
->data
;
993 if(event_request_lpos
->start_position
!= NULL
994 && event_request_list_out
->start_position
!= NULL
)
996 comp
= lttv_traceset_context_pos_pos_compare
997 (event_request_lpos
->start_position
,
998 event_request_list_out
->start_position
);
1003 lpos
= g_slist_append(lpos
, event_request_list_out
);
1005 /* Remove all elements from lpos, and add current */
1007 lpos
= g_slist_delete_link(lpos
, g_slist_nth(lpos
, 0));
1008 lpos
= g_slist_append(lpos
, event_request_list_out
);
1013 EventsRequest
*event_request_lpos
= (EventsRequest
*)g_slist_nth_data(lpos
, 0);
1014 EventsRequest
*event_request_ltime
= (EventsRequest
*)g_slist_nth_data(ltime
, 0);
1015 LttTime lpos_start_time
;
1017 if(event_request_lpos
!= NULL
1018 && event_request_lpos
->start_position
!= NULL
) {
1019 lpos_start_time
= lttv_traceset_context_position_get_time(
1020 event_request_lpos
->start_position
);
1023 /* 1.1.3 If lpos.start time < ltime */
1024 if(event_request_lpos
!= NULL
1025 && event_request_lpos
->start_position
!= NULL
1026 && ltt_time_compare(lpos_start_time
,
1027 event_request_ltime
->start_time
)<0) {
1028 /* Add lpos to list_in, remove them from list_out */
1029 for(iter
=lpos
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
1030 /* Add to list_in */
1031 EventsRequest
*event_request_lpos
=
1032 (EventsRequest
*)iter
->data
;
1034 list_in
= g_slist_append(list_in
, event_request_lpos
);
1035 /* Remove from list_out */
1036 list_out
= g_slist_remove(list_out
, event_request_lpos
);
1039 /* 1.1.4 (lpos.start time >= ltime) */
1040 /* Add ltime to list_in, remove them from list_out */
1042 for(iter
=ltime
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
1043 /* Add to list_in */
1044 EventsRequest
*event_request_ltime
=
1045 (EventsRequest
*)iter
->data
;
1047 list_in
= g_slist_append(list_in
, event_request_ltime
);
1048 /* Remove from list_out */
1049 list_out
= g_slist_remove(list_out
, event_request_ltime
);
1054 g_slist_free(ltime
);
1059 tfc
= lttv_traceset_context_get_current_tfc(tsc
);
1060 g_assert(g_slist_length(list_in
)>0);
1061 EventsRequest
*events_request
= g_slist_nth_data(list_in
, 0);
1064 /* 1.2.1 If first request in list_in is a time request */
1065 if(events_request
->start_position
== NULL
) {
1066 /* - If first req in list_in start time != current time */
1067 if(tfc
== NULL
|| ltt_time_compare(events_request
->start_time
,
1068 tfc
->timestamp
) != 0)
1069 /* - Seek to that time */
1070 g_debug("SEEK TIME : %lu, %lu", events_request
->start_time
.tv_sec
,
1071 events_request
->start_time
.tv_nsec
);
1072 //lttv_process_traceset_seek_time(tsc, events_request->start_time);
1073 lttv_state_traceset_seek_time_closest(LTTV_TRACESET_STATE(tsc
),
1074 events_request
->start_time
);
1076 /* Process the traceset with only state hooks */
1078 lttv_process_traceset_middle(tsc
,
1079 events_request
->start_time
,
1082 g_assert(seek_count
< LTTV_STATE_SAVE_INTERVAL
);
1088 /* Else, the first request in list_in is a position request */
1089 /* If first req in list_in pos != current pos */
1090 g_assert(events_request
->start_position
!= NULL
);
1091 g_debug("SEEK POS time : %lu, %lu",
1092 lttv_traceset_context_position_get_time(
1093 events_request
->start_position
).tv_sec
,
1094 lttv_traceset_context_position_get_time(
1095 events_request
->start_position
).tv_nsec
);
1097 g_debug("SEEK POS context time : %lu, %lu",
1098 lttv_traceset_context_get_current_tfc(tsc
)->timestamp
.tv_sec
,
1099 lttv_traceset_context_get_current_tfc(tsc
)->timestamp
.tv_nsec
);
1100 g_assert(events_request
->start_position
!= NULL
);
1101 if(lttv_traceset_context_ctx_pos_compare(tsc
,
1102 events_request
->start_position
) != 0) {
1103 /* 1.2.2.1 Seek to that position */
1104 g_debug("SEEK POSITION");
1105 //lttv_process_traceset_seek_position(tsc, events_request->start_position);
1106 pos_time
= lttv_traceset_context_position_get_time(
1107 events_request
->start_position
);
1109 lttv_state_traceset_seek_time_closest(LTTV_TRACESET_STATE(tsc
),
1112 /* Process the traceset with only state hooks */
1114 lttv_process_traceset_middle(tsc
,
1117 events_request
->start_position
);
1118 g_assert(lttv_traceset_context_ctx_pos_compare(tsc
,
1119 events_request
->start_position
) == 0);
1126 /* 1.3 Add hooks and call before request for all list_in members */
1128 GSList
*iter
= NULL
;
1130 for(iter
=list_in
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
1131 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1132 /* 1.3.1 If !servicing */
1133 if(events_request
->servicing
== FALSE
) {
1134 /* - begin request hooks called
1135 * - servicing = TRUE
1137 lttv_hooks_call(events_request
->before_request
, (gpointer
)tsc
);
1138 events_request
->servicing
= TRUE
;
1140 /* 1.3.2 call before chunk
1141 * 1.3.3 events hooks added
1143 if(events_request
->trace
== -1)
1144 lttv_process_traceset_begin(tsc
,
1145 events_request
->before_chunk_traceset
,
1146 events_request
->before_chunk_trace
,
1147 events_request
->before_chunk_tracefile
,
1148 events_request
->event
,
1149 events_request
->event_by_id
);
1151 guint nb_trace
= lttv_traceset_number(tsc
->ts
);
1152 g_assert((guint
)events_request
->trace
< nb_trace
&&
1153 events_request
->trace
> -1);
1154 LttvTraceContext
*tc
= tsc
->traces
[events_request
->trace
];
1156 lttv_hooks_call(events_request
->before_chunk_traceset
, tsc
);
1158 lttv_trace_context_add_hooks(tc
,
1159 events_request
->before_chunk_trace
,
1160 events_request
->before_chunk_tracefile
,
1161 events_request
->event
,
1162 events_request
->event_by_id
);
1167 /* 2. Else, list_in is not empty, we continue a read */
1170 /* 2.0 For each req of list_in */
1171 GSList
*iter
= list_in
;
1173 while(iter
!= NULL
) {
1175 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1177 /* - Call before chunk
1178 * - events hooks added
1180 if(events_request
->trace
== -1)
1181 lttv_process_traceset_begin(tsc
,
1182 events_request
->before_chunk_traceset
,
1183 events_request
->before_chunk_trace
,
1184 events_request
->before_chunk_tracefile
,
1185 events_request
->event
,
1186 events_request
->event_by_id
);
1188 guint nb_trace
= lttv_traceset_number(tsc
->ts
);
1189 g_assert((guint
)events_request
->trace
< nb_trace
&&
1190 events_request
->trace
> -1);
1191 LttvTraceContext
*tc
= tsc
->traces
[events_request
->trace
];
1193 lttv_hooks_call(events_request
->before_chunk_traceset
, tsc
);
1195 lttv_trace_context_add_hooks(tc
,
1196 events_request
->before_chunk_trace
,
1197 events_request
->before_chunk_tracefile
,
1198 events_request
->event
,
1199 events_request
->event_by_id
);
1202 iter
= g_slist_next(iter
);
1207 tfc
= lttv_traceset_context_get_current_tfc(tsc
);
1209 /* 2.1 For each req of list_out */
1210 GSList
*iter
= list_out
;
1212 while(iter
!= NULL
) {
1214 gboolean remove
= FALSE
;
1215 gboolean free_data
= FALSE
;
1216 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1218 /* if req.start time == current context time
1219 * or req.start position == current position*/
1220 if( ltt_time_compare(events_request
->start_time
,
1221 tfc
->timestamp
) == 0
1223 (events_request
->start_position
!= NULL
1225 lttv_traceset_context_ctx_pos_compare(tsc
,
1226 events_request
->start_position
) == 0)
1228 /* - Add to list_in, remove from list_out */
1229 list_in
= g_slist_append(list_in
, events_request
);
1233 /* - If !servicing */
1234 if(events_request
->servicing
== FALSE
) {
1235 /* - begin request hooks called
1236 * - servicing = TRUE
1238 lttv_hooks_call(events_request
->before_request
, (gpointer
)tsc
);
1239 events_request
->servicing
= TRUE
;
1241 /* call before chunk
1242 * events hooks added
1244 if(events_request
->trace
== -1)
1245 lttv_process_traceset_begin(tsc
,
1246 events_request
->before_chunk_traceset
,
1247 events_request
->before_chunk_trace
,
1248 events_request
->before_chunk_tracefile
,
1249 events_request
->event
,
1250 events_request
->event_by_id
);
1252 guint nb_trace
= lttv_traceset_number(tsc
->ts
);
1253 g_assert((guint
)events_request
->trace
< nb_trace
&&
1254 events_request
->trace
> -1);
1255 LttvTraceContext
*tc
= tsc
->traces
[events_request
->trace
];
1257 lttv_hooks_call(events_request
->before_chunk_traceset
, tsc
);
1259 lttv_trace_context_add_hooks(tc
,
1260 events_request
->before_chunk_trace
,
1261 events_request
->before_chunk_tracefile
,
1262 events_request
->event
,
1263 events_request
->event_by_id
);
1272 GSList
*remove_iter
= iter
;
1274 iter
= g_slist_next(iter
);
1275 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
1276 list_out
= g_slist_remove_link(list_out
, remove_iter
);
1277 } else { // not remove
1278 iter
= g_slist_next(iter
);
1284 /* 3. Find end criterions */
1289 /* 3.1.1 Find lowest end time in list_in */
1290 g_assert(g_slist_length(list_in
)>0);
1291 end_time
= ((EventsRequest
*)g_slist_nth_data(list_in
,0))->end_time
;
1293 for(iter
=g_slist_nth(list_in
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
1294 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1296 if(ltt_time_compare(events_request
->end_time
,
1298 end_time
= events_request
->end_time
;
1301 /* 3.1.2 Find lowest start time in list_out */
1302 for(iter
=list_out
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
1303 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1305 if(ltt_time_compare(events_request
->start_time
,
1307 end_time
= events_request
->start_time
;
1312 /* 3.2 Number of events */
1314 /* 3.2.1 Find lowest number of events in list_in */
1317 end_nb_events
= ((EventsRequest
*)g_slist_nth_data(list_in
,0))->num_events
;
1319 for(iter
=g_slist_nth(list_in
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
1320 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1322 if(events_request
->num_events
< end_nb_events
)
1323 end_nb_events
= events_request
->num_events
;
1326 /* 3.2.2 Use min(CHUNK_NUM_EVENTS, min num events in list_in) as
1329 end_nb_events
= MIN(CHUNK_NUM_EVENTS
, end_nb_events
);
1333 /* 3.3 End position */
1335 /* 3.3.1 Find lowest end position in list_in */
1338 end_position
=((EventsRequest
*)g_slist_nth_data(list_in
,0))->end_position
;
1340 for(iter
=g_slist_nth(list_in
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
1341 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1343 if(events_request
->end_position
!= NULL
&& end_position
!= NULL
&&
1344 lttv_traceset_context_pos_pos_compare(events_request
->end_position
,
1346 end_position
= events_request
->end_position
;
1351 /* 3.3.2 Find lowest start position in list_out */
1354 for(iter
=list_out
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
1355 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1357 if(events_request
->end_position
!= NULL
&& end_position
!= NULL
&&
1358 lttv_traceset_context_pos_pos_compare(events_request
->end_position
,
1360 end_position
= events_request
->end_position
;
1365 /* 4. Call process traceset middle */
1366 g_debug("Calling process traceset middle with %p, %lu sec %lu nsec, %u nb ev, %p end pos", tsc
, end_time
.tv_sec
, end_time
.tv_nsec
, end_nb_events
, end_position
);
1367 count
= lttv_process_traceset_middle(tsc
, end_time
, end_nb_events
, end_position
);
1369 tfc
= lttv_traceset_context_get_current_tfc(tsc
);
1371 g_debug("Context time after middle : %lu, %lu", tfc
->timestamp
.tv_sec
,
1372 tfc
->timestamp
.tv_nsec
);
1374 g_debug("End of trace reached after middle.");
1378 /* 5. After process traceset middle */
1379 tfc
= lttv_traceset_context_get_current_tfc(tsc
);
1381 /* - if current context time > traceset.end time */
1382 if(tfc
== NULL
|| ltt_time_compare(tfc
->timestamp
,
1383 tsc
->time_span
.end_time
) > 0) {
1384 /* - For each req in list_in */
1385 GSList
*iter
= list_in
;
1387 while(iter
!= NULL
) {
1389 gboolean remove
= FALSE
;
1390 gboolean free_data
= FALSE
;
1391 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1393 /* - Remove events hooks for req
1394 * - Call end chunk for req
1397 if(events_request
->trace
== -1)
1398 lttv_process_traceset_end(tsc
,
1399 events_request
->after_chunk_traceset
,
1400 events_request
->after_chunk_trace
,
1401 events_request
->after_chunk_tracefile
,
1402 events_request
->event
,
1403 events_request
->event_by_id
);
1406 guint nb_trace
= lttv_traceset_number(tsc
->ts
);
1407 g_assert(events_request
->trace
< nb_trace
&&
1408 events_request
->trace
> -1);
1409 LttvTraceContext
*tc
= tsc
->traces
[events_request
->trace
];
1411 lttv_trace_context_remove_hooks(tc
,
1412 events_request
->after_chunk_trace
,
1413 events_request
->after_chunk_tracefile
,
1414 events_request
->event
,
1415 events_request
->event_by_id
);
1416 lttv_hooks_call(events_request
->after_chunk_traceset
, tsc
);
1421 /* - Call end request for req */
1422 lttv_hooks_call(events_request
->after_request
, (gpointer
)tsc
);
1424 /* - remove req from list_in */
1425 /* Destroy the request */
1432 GSList
*remove_iter
= iter
;
1434 iter
= g_slist_next(iter
);
1435 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
1436 list_in
= g_slist_remove_link(list_in
, remove_iter
);
1437 } else { // not remove
1438 iter
= g_slist_next(iter
);
1443 /* 5.1 For each req in list_in */
1444 GSList
*iter
= list_in
;
1446 while(iter
!= NULL
) {
1448 gboolean remove
= FALSE
;
1449 gboolean free_data
= FALSE
;
1450 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1452 /* - Remove events hooks for req
1453 * - Call end chunk for req
1455 if(events_request
->trace
== -1)
1456 lttv_process_traceset_end(tsc
,
1457 events_request
->after_chunk_traceset
,
1458 events_request
->after_chunk_trace
,
1459 events_request
->after_chunk_tracefile
,
1460 events_request
->event
,
1461 events_request
->event_by_id
);
1464 guint nb_trace
= lttv_traceset_number(tsc
->ts
);
1465 g_assert(events_request
->trace
< nb_trace
&&
1466 events_request
->trace
> -1);
1467 LttvTraceContext
*tc
= tsc
->traces
[events_request
->trace
];
1469 lttv_trace_context_remove_hooks(tc
,
1470 events_request
->after_chunk_trace
,
1471 events_request
->after_chunk_tracefile
,
1472 events_request
->event
,
1473 events_request
->event_by_id
);
1475 lttv_hooks_call(events_request
->after_chunk_traceset
, tsc
);
1478 /* - req.num -= count */
1479 g_assert(events_request
->num_events
>= count
);
1480 events_request
->num_events
-= count
;
1482 g_assert(tfc
!= NULL
);
1483 /* - if req.num == 0
1485 * current context time >= req.end time
1487 * req.end pos == current pos
1489 * req.stop_flag == TRUE
1491 if( events_request
->num_events
== 0
1493 events_request
->stop_flag
== TRUE
1495 ltt_time_compare(tfc
->timestamp
,
1496 events_request
->end_time
) >= 0
1498 (events_request
->end_position
!= NULL
1500 lttv_traceset_context_ctx_pos_compare(tsc
,
1501 events_request
->end_position
) == 0)
1504 g_assert(events_request
->servicing
== TRUE
);
1505 /* - Call end request for req
1506 * - remove req from list_in */
1507 lttv_hooks_call(events_request
->after_request
, (gpointer
)tsc
);
1508 /* - remove req from list_in */
1509 /* Destroy the request */
1517 GSList
*remove_iter
= iter
;
1519 iter
= g_slist_next(iter
);
1520 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
1521 list_in
= g_slist_remove_link(list_in
, remove_iter
);
1522 } else { // not remove
1523 iter
= g_slist_next(iter
);
1529 /* End of removed servicing loop : leave control to GTK instead. */
1530 // if(gtk_events_pending()) break;
1533 /* B. When interrupted between chunks */
1536 GSList
*iter
= list_in
;
1538 /* 1. for each request in list_in */
1539 while(iter
!= NULL
) {
1541 gboolean remove
= FALSE
;
1542 gboolean free_data
= FALSE
;
1543 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1545 /* 1.1. Use current postition as start position */
1546 if(events_request
->start_position
!= NULL
)
1547 lttv_traceset_context_position_destroy(events_request
->start_position
);
1548 events_request
->start_position
= lttv_traceset_context_position_new(tsc
);
1549 lttv_traceset_context_position_save(tsc
, events_request
->start_position
);
1551 /* 1.2. Remove start time */
1552 events_request
->start_time
= ltt_time_infinite
;
1554 /* 1.3. Move from list_in to list_out */
1557 list_out
= g_slist_append(list_out
, events_request
);
1562 GSList
*remove_iter
= iter
;
1564 iter
= g_slist_next(iter
);
1565 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
1566 list_in
= g_slist_remove_link(list_in
, remove_iter
);
1567 } else { // not remove
1568 iter
= g_slist_next(iter
);
1574 /* C Unlock Traces */
1576 lttv_process_traceset_get_sync_data(tsc
);
1577 //lttv_traceset_context_position_save(tsc, sync_position);
1582 iter_trace
<lttv_traceset_number(tsc
->ts
);
1584 LttvTrace
*trace_v
= lttv_traceset_get(tsc
->ts
, iter_trace
);
1586 lttvwindowtraces_unlock(trace_v
);
1590 //set the cursor back to normal
1591 gdk_window_set_cursor(win
, NULL
);
1594 g_assert(g_slist_length(list_in
) == 0);
1596 if( g_slist_length(list_out
) == 0 ) {
1597 /* Put tab's request pending flag back to normal */
1598 tab
->events_request_pending
= FALSE
;
1599 g_debug("remove the idle fct");
1600 return FALSE
; /* Remove the idle function */
1602 g_debug("leave the idle fct");
1603 return TRUE
; /* Leave the idle function */
1605 /* We do not use simili-round-robin, it may require to read 1 meg buffers
1606 * again and again if many tracesets use the same tracefiles. */
1607 /* Hack for round-robin idle functions */
1608 /* It will put the idle function at the end of the pool */
1609 /*g_idle_add_full((G_PRIORITY_HIGH_IDLE + 21),
1610 (GSourceFunc)execute_events_requests,
1620 static void lttvwindow_add_trace(Tab
*tab
, LttvTrace
*trace_v
)
1622 LttvTraceset
*traceset
= tab
->traceset_info
->traceset
;
1624 guint num_traces
= lttv_traceset_number(traceset
);
1626 //Verify if trace is already present.
1627 for(i
=0; i
<num_traces
; i
++)
1629 LttvTrace
* trace
= lttv_traceset_get(traceset
, i
);
1630 if(trace
== trace_v
)
1634 //Keep a reference to the traces so they are not freed.
1635 for(i
=0; i
<lttv_traceset_number(traceset
); i
++)
1637 LttvTrace
* trace
= lttv_traceset_get(traceset
, i
);
1638 lttv_trace_ref(trace
);
1641 //remove state update hooks
1642 lttv_state_remove_event_hooks(
1643 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1645 lttv_context_fini(LTTV_TRACESET_CONTEXT(
1646 tab
->traceset_info
->traceset_context
));
1647 g_object_unref(tab
->traceset_info
->traceset_context
);
1649 lttv_traceset_add(traceset
, trace_v
);
1650 lttv_trace_ref(trace_v
); /* local ref */
1652 /* Create new context */
1653 tab
->traceset_info
->traceset_context
=
1654 g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
1656 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->
1661 //add state update hooks
1662 lttv_state_add_event_hooks(
1663 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1664 //Remove local reference to the traces.
1665 for(i
=0; i
<lttv_traceset_number(traceset
); i
++)
1667 LttvTrace
* trace
= lttv_traceset_get(traceset
, i
);
1668 lttv_trace_unref(trace
);
1672 //add_trace_into_traceset_selector(GTK_MULTIVPANED(tab->multivpaned), lttv_trace(trace_v));
1675 /* add_trace adds a trace into the current traceset. It first displays a
1676 * directory selection dialogue to let user choose a trace, then recreates
1677 * tracset_context, and redraws all the viewer of the current tab
1680 void add_trace(GtkWidget
* widget
, gpointer user_data
)
1683 LttvTrace
* trace_v
;
1684 LttvTraceset
* traceset
;
1686 char abs_path
[PATH_MAX
];
1688 MainWindow
* mw_data
= get_window_data_struct(widget
);
1689 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
1691 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
1692 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
1696 tab
= create_new_tab(widget
, NULL
);
1698 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
1701 //GtkDirSelection * file_selector = (GtkDirSelection *)gtk_dir_selection_new("Select a trace");
1702 GtkFileSelection
* file_selector
= (GtkFileSelection
*)gtk_file_selection_new("Select a trace");
1703 gtk_widget_hide( (file_selector
)->file_list
->parent
) ;
1704 gtk_file_selection_hide_fileop_buttons(file_selector
);
1706 if(remember_trace_dir
[0] != '\0')
1707 gtk_file_selection_set_filename(file_selector
, remember_trace_dir
);
1709 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
1711 case GTK_RESPONSE_ACCEPT
:
1712 case GTK_RESPONSE_OK
:
1713 dir
= gtk_file_selection_get_filename (file_selector
);
1714 strncpy(remember_trace_dir
, dir
, PATH_MAX
);
1715 strncat(remember_trace_dir
, "/", PATH_MAX
);
1716 if(!dir
|| strlen(dir
) == 0){
1717 gtk_widget_destroy((GtkWidget
*)file_selector
);
1720 get_absolute_pathname(dir
, abs_path
);
1721 trace_v
= lttvwindowtraces_get_trace_by_name(abs_path
);
1722 if(trace_v
== NULL
) {
1723 trace
= ltt_trace_open(abs_path
);
1725 g_warning("cannot open trace %s", abs_path
);
1727 trace_v
= lttv_trace_new(trace
);
1728 lttvwindowtraces_add_trace(trace_v
);
1729 lttvwindow_add_trace(tab
, trace_v
);
1732 lttvwindow_add_trace(tab
, trace_v
);
1735 gtk_widget_destroy((GtkWidget
*)file_selector
);
1737 //update current tab
1738 //update_traceset(mw_data);
1740 /* Call the updatetraceset hooks */
1742 traceset
= tab
->traceset_info
->traceset
;
1743 SetTraceset(tab
, traceset
);
1744 // in expose now call_pending_read_hooks(mw_data);
1746 //lttvwindow_report_current_time(mw_data,&(tab->current_time));
1748 case GTK_RESPONSE_REJECT
:
1749 case GTK_RESPONSE_CANCEL
:
1751 gtk_widget_destroy((GtkWidget
*)file_selector
);
1756 /* remove_trace removes a trace from the current traceset if all viewers in
1757 * the current tab are not interested in the trace. It first displays a
1758 * dialogue, which shows all traces in the current traceset, to let user choose
1759 * a trace, then it checks if all viewers unselect the trace, if it is true,
1760 * it will remove the trace, recreate the traceset_contex,
1761 * and redraws all the viewer of the current tab. If there is on trace in the
1762 * current traceset, it will delete all viewers of the current tab
1764 * It destroys the filter tree. FIXME... we should request for an update
1768 void remove_trace(GtkWidget
*widget
, gpointer user_data
)
1771 LttvTrace
* trace_v
;
1772 LttvTraceset
* traceset
;
1773 gint i
, j
, nb_trace
, index
=-1;
1774 char ** name
, *remove_trace_name
;
1775 MainWindow
* mw_data
= get_window_data_struct(widget
);
1776 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
1778 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
1779 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
1785 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
1788 nb_trace
=lttv_traceset_number(tab
->traceset_info
->traceset
);
1789 name
= g_new(char*,nb_trace
);
1790 for(i
= 0; i
< nb_trace
; i
++){
1791 trace_v
= lttv_traceset_get(tab
->traceset_info
->traceset
, i
);
1792 trace
= lttv_trace(trace_v
);
1793 name
[i
] = g_quark_to_string(ltt_trace_name(trace
));
1796 remove_trace_name
= get_remove_trace(name
, nb_trace
);
1799 if(remove_trace_name
){
1801 /* yuk, cut n paste from old code.. should be better (MD)*/
1802 for(i
= 0; i
<nb_trace
; i
++) {
1803 if(strcmp(remove_trace_name
,name
[i
]) == 0){
1808 traceset
= tab
->traceset_info
->traceset
;
1809 //Keep a reference to the traces so they are not freed.
1810 for(j
=0; j
<lttv_traceset_number(traceset
); j
++)
1812 LttvTrace
* trace
= lttv_traceset_get(traceset
, j
);
1813 lttv_trace_ref(trace
);
1816 //remove state update hooks
1817 lttv_state_remove_event_hooks(
1818 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1819 lttv_context_fini(LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
));
1820 g_object_unref(tab
->traceset_info
->traceset_context
);
1822 trace_v
= lttv_traceset_get(traceset
, index
);
1824 lttv_traceset_remove(traceset
, index
);
1825 lttv_trace_unref(trace_v
); // Remove local reference
1827 if(lttv_trace_get_ref_number(trace_v
) <= 1) {
1828 /* ref 1 : lttvwindowtraces only*/
1829 ltt_trace_close(lttv_trace(trace_v
));
1830 /* lttvwindowtraces_remove_trace takes care of destroying
1831 * the traceset linked with the trace_v and also of destroying
1832 * the trace_v at the same time.
1834 lttvwindowtraces_remove_trace(trace_v
);
1837 tab
->traceset_info
->traceset_context
=
1838 g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
1840 LTTV_TRACESET_CONTEXT(tab
->
1841 traceset_info
->traceset_context
),traceset
);
1842 //add state update hooks
1843 lttv_state_add_event_hooks(
1844 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1846 //Remove local reference to the traces.
1847 for(j
=0; j
<lttv_traceset_number(traceset
); j
++)
1849 LttvTrace
* trace
= lttv_traceset_get(traceset
, j
);
1850 lttv_trace_unref(trace
);
1853 SetTraceset(tab
, (gpointer
)traceset
);
1859 void remove_trace(GtkWidget
* widget
, gpointer user_data
)
1862 LttvTrace
* trace_v
;
1863 LttvTraceset
* traceset
;
1864 gint i
, j
, nb_trace
;
1865 char ** name
, *remove_trace_name
;
1866 MainWindow
* mw_data
= get_window_data_struct(widget
);
1867 LttvTracesetSelector
* s
;
1868 LttvTraceSelector
* t
;
1871 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
1873 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
1874 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
1880 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
1883 nb_trace
=lttv_traceset_number(tab
->traceset_info
->traceset
);
1884 name
= g_new(char*,nb_trace
);
1885 for(i
= 0; i
< nb_trace
; i
++){
1886 trace_v
= lttv_traceset_get(tab
->traceset_info
->traceset
, i
);
1887 trace
= lttv_trace(trace_v
);
1888 name
[i
] = ltt_trace_name(trace
);
1891 remove_trace_name
= get_remove_trace(name
, nb_trace
);
1893 if(remove_trace_name
){
1894 for(i
=0; i
<nb_trace
; i
++){
1895 if(strcmp(remove_trace_name
,name
[i
]) == 0){
1896 //unselect the trace from the current viewer
1898 w
= gtk_multivpaned_get_widget(GTK_MULTIVPANED(tab
->multivpaned
));
1900 s
= g_object_get_data(G_OBJECT(w
), "Traceset_Selector");
1902 t
= lttv_traceset_selector_trace_get(s
,i
);
1903 lttv_trace_selector_set_selected(t
, FALSE
);
1906 //check if other viewers select the trace
1907 w
= gtk_multivpaned_get_first_widget(GTK_MULTIVPANED(tab
->multivpaned
));
1909 s
= g_object_get_data(G_OBJECT(w
), "Traceset_Selector");
1911 t
= lttv_traceset_selector_trace_get(s
,i
);
1912 selected
= lttv_trace_selector_get_selected(t
);
1915 w
= gtk_multivpaned_get_next_widget(GTK_MULTIVPANED(tab
->multivpaned
));
1917 }else selected
= FALSE
;
1919 //if no viewer selects the trace, remove it
1921 remove_trace_from_traceset_selector(GTK_MULTIVPANED(tab
->multivpaned
), i
);
1923 traceset
= tab
->traceset_info
->traceset
;
1924 //Keep a reference to the traces so they are not freed.
1925 for(j
=0; j
<lttv_traceset_number(traceset
); j
++)
1927 LttvTrace
* trace
= lttv_traceset_get(traceset
, j
);
1928 lttv_trace_ref(trace
);
1931 //remove state update hooks
1932 lttv_state_remove_event_hooks(
1933 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1934 lttv_context_fini(LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
));
1935 g_object_unref(tab
->traceset_info
->traceset_context
);
1938 trace_v
= lttv_traceset_get(traceset
, i
);
1940 if(lttv_trace_get_ref_number(trace_v
) <= 2) {
1941 /* ref 2 : traceset, local */
1942 lttvwindowtraces_remove_trace(trace_v
);
1943 ltt_trace_close(lttv_trace(trace_v
));
1946 lttv_traceset_remove(traceset
, i
);
1947 lttv_trace_unref(trace_v
); // Remove local reference
1949 if(!lttv_trace_get_ref_number(trace_v
))
1950 lttv_trace_destroy(trace_v
);
1952 tab
->traceset_info
->traceset_context
=
1953 g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
1955 LTTV_TRACESET_CONTEXT(tab
->
1956 traceset_info
->traceset_context
),traceset
);
1957 //add state update hooks
1958 lttv_state_add_event_hooks(
1959 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1961 //Remove local reference to the traces.
1962 for(j
=0; j
<lttv_traceset_number(traceset
); j
++)
1964 LttvTrace
* trace
= lttv_traceset_get(traceset
, j
);
1965 lttv_trace_unref(trace
);
1969 //update current tab
1970 //update_traceset(mw_data);
1973 SetTraceset(tab
, (gpointer
)traceset
);
1974 // in expose now call_pending_read_hooks(mw_data);
1976 //lttvwindow_report_current_time(mw_data,&(tab->current_time));
1979 // while(tab->multi_vpaned->num_children){
1980 // gtk_multi_vpaned_widget_delete(tab->multi_vpaned);
1994 /* Redraw all the viewers in the current tab */
1995 void redraw(GtkWidget
*widget
, gpointer user_data
)
1997 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
1998 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
1999 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2004 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
2008 LttvAttributeValue value
;
2010 g_assert(lttv_iattribute_find_by_path(tab
->attributes
, "hooks/redraw", LTTV_POINTER
, &value
));
2012 tmp
= (LttvHooks
*)*(value
.v_pointer
);
2014 lttv_hooks_call(tmp
,NULL
);
2018 void continue_processing(GtkWidget
*widget
, gpointer user_data
)
2020 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
2021 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2022 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2027 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
2031 LttvAttributeValue value
;
2033 g_assert(lttv_iattribute_find_by_path(tab
->attributes
,
2034 "hooks/continue", LTTV_POINTER
, &value
));
2036 tmp
= (LttvHooks
*)*(value
.v_pointer
);
2038 lttv_hooks_call(tmp
,NULL
);
2041 /* Stop the processing for the calling main window's current tab.
2042 * It removes every processing requests that are in its list. It does not call
2043 * the end request hooks, because the request is not finished.
2046 void stop_processing(GtkWidget
*widget
, gpointer user_data
)
2048 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
2049 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2050 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2055 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
2057 GSList
*iter
= tab
->events_requests
;
2059 while(iter
!= NULL
) {
2060 GSList
*remove_iter
= iter
;
2061 iter
= g_slist_next(iter
);
2063 g_free(remove_iter
->data
);
2064 tab
->events_requests
=
2065 g_slist_remove_link(tab
->events_requests
, remove_iter
);
2067 tab
->events_request_pending
= FALSE
;
2068 g_idle_remove_by_data(tab
);
2069 g_assert(g_slist_length(tab
->events_requests
) == 0);
2073 /* save will save the traceset to a file
2074 * Not implemented yet FIXME
2077 void save(GtkWidget
* widget
, gpointer user_data
)
2082 void save_as(GtkWidget
* widget
, gpointer user_data
)
2084 g_info("Save as\n");
2088 /* zoom will change the time_window of all the viewers of the
2089 * current tab, and redisplay them. The main functionality is to
2090 * determine the new time_window of the current tab
2093 void zoom(GtkWidget
* widget
, double size
)
2095 TimeInterval time_span
;
2096 TimeWindow new_time_window
;
2097 LttTime current_time
, time_delta
;
2098 MainWindow
* mw_data
= get_window_data_struct(widget
);
2099 LttvTracesetContext
*tsc
;
2100 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
2102 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2103 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2109 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
2112 if(size
== 1) return;
2114 tsc
= LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
2115 time_span
= tsc
->time_span
;
2116 new_time_window
= tab
->time_window
;
2117 current_time
= tab
->current_time
;
2119 time_delta
= ltt_time_sub(time_span
.end_time
,time_span
.start_time
);
2121 new_time_window
.start_time
= time_span
.start_time
;
2122 new_time_window
.time_width
= time_delta
;
2123 new_time_window
.time_width_double
= ltt_time_to_double(time_delta
);
2124 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
2125 new_time_window
.time_width
) ;
2127 new_time_window
.time_width
= ltt_time_div(new_time_window
.time_width
, size
);
2128 new_time_window
.time_width_double
=
2129 ltt_time_to_double(new_time_window
.time_width
);
2130 if(ltt_time_compare(new_time_window
.time_width
,time_delta
) > 0)
2131 { /* Case where zoom out is bigger than trace length */
2132 new_time_window
.start_time
= time_span
.start_time
;
2133 new_time_window
.time_width
= time_delta
;
2134 new_time_window
.time_width_double
= ltt_time_to_double(time_delta
);
2135 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
2136 new_time_window
.time_width
) ;
2140 /* Center the image on the current time */
2141 new_time_window
.start_time
=
2142 ltt_time_sub(current_time
,
2143 ltt_time_from_double(new_time_window
.time_width_double
/2.0));
2144 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
2145 new_time_window
.time_width
) ;
2146 /* If on borders, don't fall off */
2147 if(ltt_time_compare(new_time_window
.start_time
, time_span
.start_time
) <0)
2149 new_time_window
.start_time
= time_span
.start_time
;
2150 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
2151 new_time_window
.time_width
) ;
2155 if(ltt_time_compare(new_time_window
.end_time
,
2156 time_span
.end_time
) > 0)
2158 new_time_window
.start_time
=
2159 ltt_time_sub(time_span
.end_time
, new_time_window
.time_width
);
2161 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
2162 new_time_window
.time_width
) ;
2169 if(ltt_time_compare(new_time_window
.time_width
, ltt_time_zero
) == 0) {
2170 g_warning("Zoom more than 1 ns impossible");
2172 time_change_manager(tab
, new_time_window
);
2176 void zoom_in(GtkWidget
* widget
, gpointer user_data
)
2181 void zoom_out(GtkWidget
* widget
, gpointer user_data
)
2186 void zoom_extended(GtkWidget
* widget
, gpointer user_data
)
2191 void go_to_time(GtkWidget
* widget
, gpointer user_data
)
2193 g_info("Go to time\n");
2196 void show_time_frame(GtkWidget
* widget
, gpointer user_data
)
2198 g_info("Show time frame\n");
2202 /* callback function */
2205 on_empty_traceset_activate (GtkMenuItem
*menuitem
,
2208 create_new_window((GtkWidget
*)menuitem
, user_data
, FALSE
);
2213 on_clone_traceset_activate (GtkMenuItem
*menuitem
,
2216 create_new_window((GtkWidget
*)menuitem
, user_data
, TRUE
);
2220 /* create_new_tab calls create_tab to construct a new tab in the main window
2223 Tab
*create_new_tab(GtkWidget
* widget
, gpointer user_data
){
2224 gchar label
[PATH_MAX
];
2225 MainWindow
* mw_data
= get_window_data_struct(widget
);
2227 GtkNotebook
* notebook
= (GtkNotebook
*)lookup_widget(widget
, "MNotebook");
2228 if(notebook
== NULL
){
2229 g_info("Notebook does not exist\n");
2232 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2233 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2239 copy_tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
2242 strcpy(label
,"Page");
2243 if(get_label(mw_data
, label
,"Get the name of the tab","Please input tab's name"))
2244 return (create_tab (mw_data
, copy_tab
, notebook
, label
));
2250 on_tab_activate (GtkMenuItem
*menuitem
,
2253 create_new_tab((GtkWidget
*)menuitem
, user_data
);
2258 on_open_activate (GtkMenuItem
*menuitem
,
2261 open_traceset((GtkWidget
*)menuitem
, user_data
);
2266 on_close_activate (GtkMenuItem
*menuitem
,
2269 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2270 main_window_destructor(mw_data
);
2274 /* remove the current tab from the main window
2278 on_close_tab_activate (GtkWidget
*widget
,
2282 GtkWidget
* notebook
;
2284 MainWindow
* mw_data
= get_window_data_struct(widget
);
2285 notebook
= lookup_widget(widget
, "MNotebook");
2286 if(notebook
== NULL
){
2287 g_info("Notebook does not exist\n");
2291 page_num
= gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
));
2293 gtk_notebook_remove_page(GTK_NOTEBOOK(notebook
), page_num
);
2298 on_close_tab_X_clicked (GtkWidget
*widget
,
2302 GtkWidget
*notebook
= lookup_widget(widget
, "MNotebook");
2303 if(notebook
== NULL
){
2304 g_info("Notebook does not exist\n");
2308 if((page_num
= gtk_notebook_page_num(GTK_NOTEBOOK(notebook
), widget
)) != -1)
2309 gtk_notebook_remove_page(GTK_NOTEBOOK(notebook
), page_num
);
2315 on_add_trace_activate (GtkMenuItem
*menuitem
,
2318 add_trace((GtkWidget
*)menuitem
, user_data
);
2323 on_remove_trace_activate (GtkMenuItem
*menuitem
,
2326 remove_trace((GtkWidget
*)menuitem
, user_data
);
2331 on_save_activate (GtkMenuItem
*menuitem
,
2334 save((GtkWidget
*)menuitem
, user_data
);
2339 on_save_as_activate (GtkMenuItem
*menuitem
,
2342 save_as((GtkWidget
*)menuitem
, user_data
);
2347 on_quit_activate (GtkMenuItem
*menuitem
,
2355 on_cut_activate (GtkMenuItem
*menuitem
,
2363 on_copy_activate (GtkMenuItem
*menuitem
,
2371 on_paste_activate (GtkMenuItem
*menuitem
,
2379 on_delete_activate (GtkMenuItem
*menuitem
,
2387 on_zoom_in_activate (GtkMenuItem
*menuitem
,
2390 zoom_in((GtkWidget
*)menuitem
, user_data
);
2395 on_zoom_out_activate (GtkMenuItem
*menuitem
,
2398 zoom_out((GtkWidget
*)menuitem
, user_data
);
2403 on_zoom_extended_activate (GtkMenuItem
*menuitem
,
2406 zoom_extended((GtkWidget
*)menuitem
, user_data
);
2411 on_go_to_time_activate (GtkMenuItem
*menuitem
,
2414 go_to_time((GtkWidget
*)menuitem
, user_data
);
2419 on_show_time_frame_activate (GtkMenuItem
*menuitem
,
2422 show_time_frame((GtkWidget
*)menuitem
, user_data
);
2427 on_move_viewer_up_activate (GtkMenuItem
*menuitem
,
2430 move_up_viewer((GtkWidget
*)menuitem
, user_data
);
2435 on_move_viewer_down_activate (GtkMenuItem
*menuitem
,
2438 move_down_viewer((GtkWidget
*)menuitem
, user_data
);
2443 on_remove_viewer_activate (GtkMenuItem
*menuitem
,
2446 delete_viewer((GtkWidget
*)menuitem
, user_data
);
2450 on_trace_facility_activate (GtkMenuItem
*menuitem
,
2453 g_info("Trace facility selector: %s\n");
2457 /* Dispaly a file selection dialogue to let user select a library, then call
2458 * lttv_library_load().
2462 on_load_library_activate (GtkMenuItem
*menuitem
,
2465 GError
*error
= NULL
;
2466 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2468 gchar load_module_path_alter
[PATH_MAX
];
2472 gchar
*load_module_path
;
2473 name
= g_ptr_array_new();
2474 nb
= lttv_library_path_number();
2475 /* ask for the library path */
2479 path
= lttv_library_path_get(i
);
2480 g_ptr_array_add(name
, path
);
2483 load_module_path
= get_selection((char **)(name
->pdata
), name
->len
,
2484 "Select a library path", "Library paths");
2485 if(load_module_path
!= NULL
)
2486 strncpy(load_module_path_alter
, load_module_path
, PATH_MAX
-1); // -1 for /
2488 g_ptr_array_free(name
, TRUE
);
2490 if(load_module_path
== NULL
) return;
2494 /* Make sure the module path ends with a / */
2495 gchar
*ptr
= load_module_path_alter
;
2497 ptr
= strchr(ptr
, '\0');
2499 if(*(ptr
-1) != '/') {
2506 /* Ask for the library to load : list files in the previously selected
2508 gchar str
[PATH_MAX
];
2511 GtkFileSelection
* file_selector
=
2512 (GtkFileSelection
*)gtk_file_selection_new("Select a module");
2513 gtk_file_selection_set_filename(file_selector
, load_module_path_alter
);
2514 gtk_file_selection_hide_fileop_buttons(file_selector
);
2517 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
2519 case GTK_RESPONSE_ACCEPT
:
2520 case GTK_RESPONSE_OK
:
2521 dir
= gtk_file_selection_get_selections (file_selector
);
2522 strncpy(str
,dir
[0],PATH_MAX
);
2523 strncpy(remember_plugins_dir
,dir
[0],PATH_MAX
);
2524 /* only keep file name */
2526 str1
= strrchr(str
,'/');
2529 str1
= strrchr(str
,'\\');
2534 if(*str1
== 'l' && *(str1
+1)== 'i' && *(str1
+2)=='b')
2536 remove info after
. */
2540 str2
= strrchr(str2
, '.');
2541 if(str2
!= NULL
) *str2
= '\0';
2543 lttv_module_require(str1
, &error
);
2545 lttv_library_load(str1
, &error
);
2546 if(error
!= NULL
) g_warning("%s", error
->message
);
2547 else g_info("Load library: %s\n", str
);
2549 case GTK_RESPONSE_REJECT
:
2550 case GTK_RESPONSE_CANCEL
:
2552 gtk_widget_destroy((GtkWidget
*)file_selector
);
2563 /* Display all loaded modules, let user to select a module to unload
2564 * by calling lttv_module_unload
2568 on_unload_library_activate (GtkMenuItem
*menuitem
,
2571 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2573 LttvLibrary
*library
= NULL
;
2578 name
= g_ptr_array_new();
2579 nb
= lttv_library_number();
2580 LttvLibraryInfo
*lib_info
= g_new(LttvLibraryInfo
,nb
);
2581 /* ask for the library name */
2584 LttvLibrary
*iter_lib
= lttv_library_get(i
);
2585 lttv_library_info(iter_lib
, &lib_info
[i
]);
2587 gchar
*path
= lib_info
[i
].name
;
2588 g_ptr_array_add(name
, path
);
2590 lib_name
= get_selection((char **)(name
->pdata
), name
->len
,
2591 "Select a library", "Libraries");
2592 if(lib_name
!= NULL
) {
2594 if(strcmp(lib_name
, lib_info
[i
].name
) == 0) {
2595 library
= lttv_library_get(i
);
2600 g_ptr_array_free(name
, TRUE
);
2603 if(lib_name
== NULL
) return;
2605 if(library
!= NULL
) lttv_library_unload(library
);
2609 /* Dispaly a file selection dialogue to let user select a module, then call
2610 * lttv_module_require().
2614 on_load_module_activate (GtkMenuItem
*menuitem
,
2617 GError
*error
= NULL
;
2618 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2620 LttvLibrary
*library
= NULL
;
2625 name
= g_ptr_array_new();
2626 nb
= lttv_library_number();
2627 LttvLibraryInfo
*lib_info
= g_new(LttvLibraryInfo
,nb
);
2628 /* ask for the library name */
2631 LttvLibrary
*iter_lib
= lttv_library_get(i
);
2632 lttv_library_info(iter_lib
, &lib_info
[i
]);
2634 gchar
*path
= lib_info
[i
].name
;
2635 g_ptr_array_add(name
, path
);
2637 lib_name
= get_selection((char **)(name
->pdata
), name
->len
,
2638 "Select a library", "Libraries");
2639 if(lib_name
!= NULL
) {
2641 if(strcmp(lib_name
, lib_info
[i
].name
) == 0) {
2642 library
= lttv_library_get(i
);
2647 g_ptr_array_free(name
, TRUE
);
2650 if(lib_name
== NULL
) return;
2653 //LttvModule *module;
2654 gchar module_name_out
[PATH_MAX
];
2656 /* Ask for the module to load : list modules in the selected lib */
2660 nb
= lttv_library_module_number(library
);
2661 LttvModuleInfo
*module_info
= g_new(LttvModuleInfo
,nb
);
2662 name
= g_ptr_array_new();
2663 /* ask for the module name */
2666 LttvModule
*iter_module
= lttv_library_module_get(library
, i
);
2667 lttv_module_info(iter_module
, &module_info
[i
]);
2669 gchar
*path
= module_info
[i
].name
;
2670 g_ptr_array_add(name
, path
);
2672 module_name
= get_selection((char **)(name
->pdata
), name
->len
,
2673 "Select a module", "Modules");
2674 if(module_name
!= NULL
) {
2676 if(strcmp(module_name
, module_info
[i
].name
) == 0) {
2677 strncpy(module_name_out
, module_name
, PATH_MAX
);
2678 //module = lttv_library_module_get(i);
2684 g_ptr_array_free(name
, TRUE
);
2685 g_free(module_info
);
2687 if(module_name
== NULL
) return;
2690 lttv_module_require(module_name_out
, &error
);
2691 if(error
!= NULL
) g_warning("%s", error
->message
);
2692 else g_info("Load module: %s", module_name_out
);
2699 gchar str
[PATH_MAX
];
2702 GtkFileSelection
* file_selector
=
2703 (GtkFileSelection
*)gtk_file_selection_new("Select a module");
2704 gtk_file_selection_set_filename(file_selector
, load_module_path_alter
);
2705 gtk_file_selection_hide_fileop_buttons(file_selector
);
2708 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
2710 case GTK_RESPONSE_ACCEPT
:
2711 case GTK_RESPONSE_OK
:
2712 dir
= gtk_file_selection_get_selections (file_selector
);
2713 strncpy(str
,dir
[0],PATH_MAX
);
2714 strncpy(remember_plugins_dir
,dir
[0],PATH_MAX
);
2716 /* only keep file name */
2718 str1
= strrchr(str
,'/');
2721 str1
= strrchr(str
,'\\');
2726 if(*str1
== 'l' && *(str1
+1)== 'i' && *(str1
+2)=='b')
2728 remove info after
. */
2732 str2
= strrchr(str2
, '.');
2733 if(str2
!= NULL
) *str2
= '\0';
2735 lttv_module_require(str1
, &error
);
2737 lttv_library_load(str1
, &error
);
2738 if(error
!= NULL
) g_warning(error
->message
);
2739 else g_info("Load library: %s\n", str
);
2741 case GTK_RESPONSE_REJECT
:
2742 case GTK_RESPONSE_CANCEL
:
2744 gtk_widget_destroy((GtkWidget
*)file_selector
);
2756 /* Display all loaded modules, let user to select a module to unload
2757 * by calling lttv_module_unload
2761 on_unload_module_activate (GtkMenuItem
*menuitem
,
2764 GError
*error
= NULL
;
2765 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2767 LttvLibrary
*library
;
2772 name
= g_ptr_array_new();
2773 nb
= lttv_library_number();
2774 LttvLibraryInfo
*lib_info
= g_new(LttvLibraryInfo
,nb
);
2775 /* ask for the library name */
2778 LttvLibrary
*iter_lib
= lttv_library_get(i
);
2779 lttv_library_info(iter_lib
, &lib_info
[i
]);
2781 gchar
*path
= lib_info
[i
].name
;
2782 g_ptr_array_add(name
, path
);
2784 lib_name
= get_selection((char **)(name
->pdata
), name
->len
,
2785 "Select a library", "Libraries");
2786 if(lib_name
!= NULL
) {
2788 if(strcmp(lib_name
, lib_info
[i
].name
) == 0) {
2789 library
= lttv_library_get(i
);
2794 g_ptr_array_free(name
, TRUE
);
2797 if(lib_name
== NULL
) return;
2800 LttvModule
*module
= NULL
;
2802 /* Ask for the module to load : list modules in the selected lib */
2806 nb
= lttv_library_module_number(library
);
2807 LttvModuleInfo
*module_info
= g_new(LttvModuleInfo
,nb
);
2808 name
= g_ptr_array_new();
2809 /* ask for the module name */
2812 LttvModule
*iter_module
= lttv_library_module_get(library
, i
);
2813 lttv_module_info(iter_module
, &module_info
[i
]);
2815 gchar
*path
= module_info
[i
].name
;
2816 if(module_info
[i
].use_count
> 0) g_ptr_array_add(name
, path
);
2818 module_name
= get_selection((char **)(name
->pdata
), name
->len
,
2819 "Select a module", "Modules");
2820 if(module_name
!= NULL
) {
2822 if(strcmp(module_name
, module_info
[i
].name
) == 0) {
2823 module
= lttv_library_module_get(library
, i
);
2829 g_ptr_array_free(name
, TRUE
);
2830 g_free(module_info
);
2832 if(module_name
== NULL
) return;
2835 LttvModuleInfo module_info
;
2836 lttv_module_info(module
, &module_info
);
2837 g_info("Release module: %s\n", module_info
.name
);
2839 lttv_module_release(module
);
2843 /* Display a directory dialogue to let user select a path for library searching
2847 on_add_library_search_path_activate (GtkMenuItem
*menuitem
,
2850 //GtkDirSelection * file_selector = (GtkDirSelection *)gtk_dir_selection_new("Select library path");
2851 GtkFileSelection
* file_selector
= (GtkFileSelection
*)gtk_file_selection_new("Select a trace");
2852 gtk_widget_hide( (file_selector
)->file_list
->parent
) ;
2856 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2857 if(remember_plugins_dir
[0] != '\0')
2858 gtk_file_selection_set_filename(file_selector
, remember_plugins_dir
);
2860 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
2862 case GTK_RESPONSE_ACCEPT
:
2863 case GTK_RESPONSE_OK
:
2864 dir
= gtk_file_selection_get_filename (file_selector
);
2865 strncpy(remember_plugins_dir
,dir
,PATH_MAX
);
2866 strncat(remember_plugins_dir
,"/",PATH_MAX
);
2867 lttv_library_path_add(dir
);
2868 case GTK_RESPONSE_REJECT
:
2869 case GTK_RESPONSE_CANCEL
:
2871 gtk_widget_destroy((GtkWidget
*)file_selector
);
2877 /* Display a directory dialogue to let user select a path for library searching
2881 on_remove_library_search_path_activate (GtkMenuItem
*menuitem
,
2884 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2886 const char *lib_path
;
2891 name
= g_ptr_array_new();
2892 nb
= lttv_library_path_number();
2893 /* ask for the library name */
2896 gchar
*path
= lttv_library_path_get(i
);
2897 g_ptr_array_add(name
, path
);
2899 lib_path
= get_selection((char **)(name
->pdata
), name
->len
,
2900 "Select a library path", "Library paths");
2902 g_ptr_array_free(name
, TRUE
);
2904 if(lib_path
== NULL
) return;
2907 lttv_library_path_remove(lib_path
);
2911 on_color_activate (GtkMenuItem
*menuitem
,
2919 on_save_configuration_activate (GtkMenuItem
*menuitem
,
2922 g_info("Save configuration\n");
2927 on_content_activate (GtkMenuItem
*menuitem
,
2930 g_info("Content\n");
2935 on_about_close_activate (GtkButton
*button
,
2938 GtkWidget
*about_widget
= GTK_WIDGET(user_data
);
2940 gtk_widget_destroy(about_widget
);
2944 on_about_activate (GtkMenuItem
*menuitem
,
2947 MainWindow
*main_window
= get_window_data_struct(GTK_WIDGET(menuitem
));
2948 GtkWidget
*window_widget
= main_window
->mwindow
;
2949 GtkWidget
*about_widget
= gtk_window_new(GTK_WINDOW_TOPLEVEL
);
2950 GtkWindow
*about_window
= GTK_WINDOW(about_widget
);
2951 gint window_width
, window_height
;
2953 gtk_window_set_title(about_window
, "About Linux Trace Toolkit");
2955 gtk_window_set_resizable(about_window
, FALSE
);
2956 gtk_window_set_transient_for(GTK_WINDOW(window_widget
), about_window
);
2957 gtk_window_set_destroy_with_parent(about_window
, TRUE
);
2958 gtk_window_set_modal(about_window
, FALSE
);
2960 /* Put the about window at the center of the screen */
2961 gtk_window_get_size(about_window
, &window_width
, &window_height
);
2962 gtk_window_move (about_window
,
2963 (gdk_screen_width() - window_width
)/2,
2964 (gdk_screen_height() - window_height
)/2);
2966 GtkWidget
*vbox
= gtk_vbox_new(FALSE
, 1);
2968 gtk_container_add(GTK_CONTAINER(about_widget
), vbox
);
2972 GtkWidget
*label1
= gtk_label_new("");
2973 gtk_misc_set_padding(GTK_MISC(label1
), 10, 20);
2974 gtk_label_set_markup(GTK_LABEL(label1
), "\
2975 <big>Linux Trace Toolkit</big>");
2976 gtk_label_set_justify(GTK_LABEL(label1
), GTK_JUSTIFY_CENTER
);
2978 GtkWidget
*label2
= gtk_label_new("");
2979 gtk_misc_set_padding(GTK_MISC(label2
), 10, 20);
2980 gtk_label_set_markup(GTK_LABEL(label2
), "\
2983 Michel Dagenais (New trace format, lttv main)\n\
2984 Mathieu Desnoyers (Kernel Tracer, Directory structure, build with automake/conf,\n\
2985 lttv gui, control flow view, gui cooperative trace reading\n\
2986 scheduler with interruptible foreground and background\n\
2987 computation, detailed event list (rewrite), trace reading\n\
2988 library (rewrite))\n\
2989 Benoit Des Ligneris, Eric Clement (Cluster adaptation, work in progress)\n\
2990 Xang-Xiu Yang (new trace reading library and converter, lttv gui, \n\
2991 detailed event list and statistics view)\n\
2992 Tom Zanussi (RelayFS)\n\
2994 Strongly inspired from the original Linux Trace Toolkit Visualizer made by\n\
2997 GtkWidget
*label3
= gtk_label_new("");
2998 gtk_label_set_markup(GTK_LABEL(label3
), "\
2999 Linux Trace Toolkit Viewer, Copyright (C) 2004\n\
3001 Mathieu Desnoyers\n\
3003 Linux Trace Toolkit comes with ABSOLUTELY NO WARRANTY.\n\
3004 This is free software, and you are welcome to redistribute it\n\
3005 under certain conditions. See COPYING for details.");
3006 gtk_misc_set_padding(GTK_MISC(label3
), 10, 20);
3008 gtk_box_pack_start_defaults(GTK_BOX(vbox
), label1
);
3009 gtk_box_pack_start_defaults(GTK_BOX(vbox
), label2
);
3010 gtk_box_pack_start_defaults(GTK_BOX(vbox
), label3
);
3012 GtkWidget
*hbox
= gtk_hbox_new(TRUE
, 0);
3013 gtk_box_pack_end(GTK_BOX(vbox
), hbox
, FALSE
, FALSE
, 0);
3014 GtkWidget
*close_button
= gtk_button_new_with_mnemonic("_Close");
3015 gtk_box_pack_end(GTK_BOX(hbox
), close_button
, FALSE
, FALSE
, 0);
3016 gtk_container_set_border_width(GTK_CONTAINER(close_button
), 20);
3018 g_signal_connect(G_OBJECT(close_button
), "clicked",
3019 G_CALLBACK(on_about_close_activate
),
3020 (gpointer
)about_widget
);
3022 gtk_widget_show_all(about_widget
);
3027 on_button_new_clicked (GtkButton
*button
,
3030 create_new_window((GtkWidget
*)button
, user_data
, TRUE
);
3034 on_button_new_tab_clicked (GtkButton
*button
,
3037 create_new_tab((GtkWidget
*)button
, user_data
);
3041 on_button_open_clicked (GtkButton
*button
,
3044 open_traceset((GtkWidget
*)button
, user_data
);
3049 on_button_add_trace_clicked (GtkButton
*button
,
3052 add_trace((GtkWidget
*)button
, user_data
);
3057 on_button_remove_trace_clicked (GtkButton
*button
,
3060 remove_trace((GtkWidget
*)button
, user_data
);
3064 on_button_redraw_clicked (GtkButton
*button
,
3067 redraw((GtkWidget
*)button
, user_data
);
3071 on_button_continue_processing_clicked (GtkButton
*button
,
3074 continue_processing((GtkWidget
*)button
, user_data
);
3078 on_button_stop_processing_clicked (GtkButton
*button
,
3081 stop_processing((GtkWidget
*)button
, user_data
);
3087 on_button_save_clicked (GtkButton
*button
,
3090 save((GtkWidget
*)button
, user_data
);
3095 on_button_save_as_clicked (GtkButton
*button
,
3098 save_as((GtkWidget
*)button
, user_data
);
3103 on_button_zoom_in_clicked (GtkButton
*button
,
3106 zoom_in((GtkWidget
*)button
, user_data
);
3111 on_button_zoom_out_clicked (GtkButton
*button
,
3114 zoom_out((GtkWidget
*)button
, user_data
);
3119 on_button_zoom_extended_clicked (GtkButton
*button
,
3122 zoom_extended((GtkWidget
*)button
, user_data
);
3127 on_button_go_to_time_clicked (GtkButton
*button
,
3130 go_to_time((GtkWidget
*)button
, user_data
);
3135 on_button_show_time_frame_clicked (GtkButton
*button
,
3138 show_time_frame((GtkWidget
*)button
, user_data
);
3143 on_button_move_up_clicked (GtkButton
*button
,
3146 move_up_viewer((GtkWidget
*)button
, user_data
);
3151 on_button_move_down_clicked (GtkButton
*button
,
3154 move_down_viewer((GtkWidget
*)button
, user_data
);
3159 on_button_delete_viewer_clicked (GtkButton
*button
,
3162 delete_viewer((GtkWidget
*)button
, user_data
);
3166 on_MWindow_destroy (GtkWidget
*widget
,
3169 MainWindow
*main_window
= get_window_data_struct(widget
);
3170 LttvIAttribute
*attributes
= main_window
->attributes
;
3171 LttvAttributeValue value
;
3173 //This is unnecessary, since widgets will be destroyed
3174 //by the main window widget anyway.
3175 //remove_all_menu_toolbar_constructors(main_window, NULL);
3177 g_assert(lttv_iattribute_find_by_path(attributes
,
3178 "viewers/menu", LTTV_POINTER
, &value
));
3179 lttv_menus_destroy((LttvMenus
*)*(value
.v_pointer
));
3181 g_assert(lttv_iattribute_find_by_path(attributes
,
3182 "viewers/toolbar", LTTV_POINTER
, &value
));
3183 lttv_toolbars_destroy((LttvToolbars
*)*(value
.v_pointer
));
3185 g_object_unref(main_window
->attributes
);
3186 g_main_window_list
= g_slist_remove(g_main_window_list
, main_window
);
3188 g_info("There are now : %d windows\n",g_slist_length(g_main_window_list
));
3189 if(g_slist_length(g_main_window_list
) == 0)
3194 on_MWindow_configure (GtkWidget
*widget
,
3195 GdkEventConfigure
*event
,
3198 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)widget
);
3200 // MD : removed time width modification upon resizing of the main window.
3201 // The viewers will redraw themselves completely, without time interval
3204 if(mw_data->window_width){
3205 time_span = LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context)->Time_Span ;
3206 time_win = tab->time_window;
3207 ratio = width / mw_data->window_width;
3208 tab->time_window.time_width = ltt_time_mul(time_win.time_width,ratio);
3209 time = ltt_time_sub(time_span->endTime, time_win.start_time);
3210 if(ltt_time_compare(time, tab->time_window.time_width) < 0){
3211 tab->time_window.time_width = time;
3217 mw_data->window_width = (int)width;
3226 on_MNotebook_switch_page (GtkNotebook
*notebook
,
3227 GtkNotebookPage
*page
,
3235 void time_change_manager (Tab
*tab
,
3236 TimeWindow new_time_window
)
3238 /* Only one source of time change */
3239 if(tab
->time_manager_lock
== TRUE
) return;
3241 tab
->time_manager_lock
= TRUE
;
3243 LttvTracesetContext
*tsc
= LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3244 TimeInterval time_span
= tsc
->time_span
;
3245 LttTime start_time
= new_time_window
.start_time
;
3246 LttTime end_time
= new_time_window
.end_time
;
3248 g_assert(ltt_time_compare(start_time
, end_time
) < 0);
3251 GtkAdjustment
*adjustment
= gtk_range_get_adjustment(GTK_RANGE(tab
->scrollbar
));
3252 LttTime upper
= ltt_time_sub(time_span
.end_time
, time_span
.start_time
);
3254 gtk_range_set_increments(GTK_RANGE(tab
->scrollbar
),
3255 ltt_time_to_double(new_time_window
.time_width
)
3256 / SCROLL_STEP_PER_PAGE
3257 * NANOSECONDS_PER_SECOND
, /* step increment */
3258 ltt_time_to_double(new_time_window
.time_width
)
3259 * NANOSECONDS_PER_SECOND
); /* page increment */
3260 gtk_range_set_range(GTK_RANGE(tab
->scrollbar
),
3262 ltt_time_to_double(upper
)
3263 * NANOSECONDS_PER_SECOND
); /* upper */
3265 g_object_set(G_OBJECT(adjustment
),
3269 ltt_time_to_double(upper
), /* upper */
3271 new_time_window
.time_width_double
3272 / SCROLL_STEP_PER_PAGE
, /* step increment */
3274 new_time_window
.time_width_double
,
3275 /* page increment */
3277 new_time_window
.time_width_double
, /* page size */
3279 gtk_adjustment_changed(adjustment
);
3281 // g_object_set(G_OBJECT(adjustment),
3283 // ltt_time_to_double(
3284 // ltt_time_sub(start_time, time_span.start_time))
3287 //gtk_adjustment_value_changed(adjustment);
3288 gtk_range_set_value(GTK_RANGE(tab
->scrollbar
),
3290 ltt_time_sub(start_time
, time_span
.start_time
)) /* value */);
3292 /* set the time bar. */
3294 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry1
),
3295 (double)time_span
.start_time
.tv_sec
,
3296 (double)time_span
.end_time
.tv_sec
);
3297 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry1
),
3298 (double)start_time
.tv_sec
);
3300 /* start nanoseconds */
3301 if(start_time
.tv_sec
== time_span
.start_time
.tv_sec
) {
3302 /* can be both beginning and end at the same time. */
3303 if(start_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3304 /* If we are at the end, max nsec to end.. -1 (not zero length) */
3305 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry2
),
3306 (double)time_span
.start_time
.tv_nsec
,
3307 (double)time_span
.end_time
.tv_nsec
-1);
3309 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry2
),
3310 (double)time_span
.start_time
.tv_nsec
,
3311 (double)NANOSECONDS_PER_SECOND
-1);
3313 } else if(start_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3314 /* If we are at the end, max nsec to end.. -1 (not zero length) */
3315 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry2
),
3317 (double)time_span
.end_time
.tv_nsec
-1);
3318 } else /* anywhere else */
3319 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry2
),
3321 (double)NANOSECONDS_PER_SECOND
-1);
3322 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry2
),
3323 (double)start_time
.tv_nsec
);
3326 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry3
),
3327 (double)time_span
.start_time
.tv_sec
,
3328 (double)time_span
.end_time
.tv_sec
);
3329 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry3
),
3330 (double)end_time
.tv_sec
);
3332 /* end nanoseconds */
3333 if(end_time
.tv_sec
== time_span
.start_time
.tv_sec
) {
3334 /* can be both beginning and end at the same time. */
3335 if(end_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3336 /* If we are at the end, max nsec to end.. */
3337 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry4
),
3338 (double)time_span
.start_time
.tv_nsec
+1,
3339 (double)time_span
.end_time
.tv_nsec
);
3341 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry4
),
3342 (double)time_span
.start_time
.tv_nsec
+1,
3343 (double)NANOSECONDS_PER_SECOND
-1);
3346 else if(end_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3347 /* If we are at the end, max nsec to end.. */
3348 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry4
),
3350 (double)time_span
.end_time
.tv_nsec
);
3352 else /* anywhere else */
3353 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry4
),
3355 (double)NANOSECONDS_PER_SECOND
-1);
3356 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry4
),
3357 (double)end_time
.tv_nsec
);
3359 /* call viewer hooks for new time window */
3360 set_time_window(tab
, &new_time_window
);
3362 tab
->time_manager_lock
= FALSE
;
3366 /* value changed for frame start s
3368 * Check time span : if ns is out of range, clip it the nearest good value.
3371 on_MEntry1_value_changed (GtkSpinButton
*spinbutton
,
3374 Tab
*tab
=(Tab
*)user_data
;
3375 LttvTracesetContext
* tsc
=
3376 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3377 TimeInterval time_span
= tsc
->time_span
;
3378 gint value
= gtk_spin_button_get_value_as_int(spinbutton
);
3380 TimeWindow new_time_window
= tab
->time_window
;
3382 LttTime end_time
= new_time_window
.end_time
;
3384 new_time_window
.start_time
.tv_sec
= value
;
3386 /* start nanoseconds */
3387 if(new_time_window
.start_time
.tv_sec
== time_span
.start_time
.tv_sec
) {
3388 if(new_time_window
.start_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3389 if(new_time_window
.start_time
.tv_nsec
> time_span
.end_time
.tv_nsec
)
3390 new_time_window
.start_time
.tv_nsec
= time_span
.end_time
.tv_nsec
-1;
3391 if(new_time_window
.start_time
.tv_nsec
< time_span
.start_time
.tv_nsec
)
3392 new_time_window
.start_time
.tv_nsec
= time_span
.start_time
.tv_nsec
;
3394 if(new_time_window
.start_time
.tv_nsec
< time_span
.start_time
.tv_nsec
)
3395 new_time_window
.start_time
.tv_nsec
= time_span
.start_time
.tv_nsec
;
3398 else if(new_time_window
.start_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3399 if(new_time_window
.start_time
.tv_nsec
> time_span
.end_time
.tv_nsec
)
3400 new_time_window
.start_time
.tv_nsec
= time_span
.end_time
.tv_nsec
-1;
3403 if(ltt_time_compare(new_time_window
.start_time
, end_time
) >= 0) {
3404 /* Then, we must push back end time : keep the same time width
3405 * if possible, else end traceset time */
3406 end_time
= LTT_TIME_MIN(ltt_time_add(new_time_window
.start_time
,
3407 new_time_window
.time_width
),
3408 time_span
.end_time
);
3411 /* Fix the time width to fit start time and end time */
3412 new_time_window
.time_width
= ltt_time_sub(end_time
,
3413 new_time_window
.start_time
);
3414 new_time_window
.time_width_double
=
3415 ltt_time_to_double(new_time_window
.time_width
);
3417 new_time_window
.end_time
= end_time
;
3419 time_change_manager(tab
, new_time_window
);
3424 on_MEntry2_value_changed (GtkSpinButton
*spinbutton
,
3427 Tab
*tab
=(Tab
*)user_data
;
3428 LttvTracesetContext
* tsc
=
3429 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3430 TimeInterval time_span
= tsc
->time_span
;
3431 gint value
= gtk_spin_button_get_value_as_int(spinbutton
);
3433 TimeWindow new_time_window
= tab
->time_window
;
3435 LttTime end_time
= new_time_window
.end_time
;
3437 new_time_window
.start_time
.tv_nsec
= value
;
3439 if(ltt_time_compare(new_time_window
.start_time
, end_time
) >= 0) {
3440 /* Then, we must push back end time : keep the same time width
3441 * if possible, else end traceset time */
3442 end_time
= LTT_TIME_MIN(ltt_time_add(new_time_window
.start_time
,
3443 new_time_window
.time_width
),
3444 time_span
.end_time
);
3447 /* Fix the time width to fit start time and end time */
3448 new_time_window
.time_width
= ltt_time_sub(end_time
,
3449 new_time_window
.start_time
);
3450 new_time_window
.time_width_double
=
3451 ltt_time_to_double(new_time_window
.time_width
);
3453 new_time_window
.end_time
= end_time
;
3455 time_change_manager(tab
, new_time_window
);
3460 on_MEntry3_value_changed (GtkSpinButton
*spinbutton
,
3463 Tab
*tab
=(Tab
*)user_data
;
3464 LttvTracesetContext
* tsc
=
3465 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3466 TimeInterval time_span
= tsc
->time_span
;
3467 gint value
= gtk_spin_button_get_value_as_int(spinbutton
);
3469 TimeWindow new_time_window
= tab
->time_window
;
3471 LttTime end_time
= new_time_window
.end_time
;
3473 end_time
.tv_sec
= value
;
3475 /* end nanoseconds */
3476 if(end_time
.tv_sec
== time_span
.start_time
.tv_sec
) {
3477 if(end_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3478 if(end_time
.tv_nsec
> time_span
.end_time
.tv_nsec
)
3479 end_time
.tv_nsec
= time_span
.end_time
.tv_nsec
;
3480 if(end_time
.tv_nsec
< time_span
.start_time
.tv_nsec
)
3481 end_time
.tv_nsec
= time_span
.start_time
.tv_nsec
+1;
3483 if(end_time
.tv_nsec
< time_span
.start_time
.tv_nsec
)
3484 end_time
.tv_nsec
= time_span
.start_time
.tv_nsec
+1;
3487 else if(end_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3488 if(end_time
.tv_nsec
> time_span
.end_time
.tv_nsec
)
3489 end_time
.tv_nsec
= time_span
.end_time
.tv_nsec
;
3492 if(ltt_time_compare(new_time_window
.start_time
, end_time
) >= 0) {
3493 /* Then, we must push front start time : keep the same time width
3494 * if possible, else end traceset time */
3495 new_time_window
.start_time
= LTT_TIME_MAX(
3496 ltt_time_sub(end_time
,
3497 new_time_window
.time_width
),
3498 time_span
.start_time
);
3501 /* Fix the time width to fit start time and end time */
3502 new_time_window
.time_width
= ltt_time_sub(end_time
,
3503 new_time_window
.start_time
);
3504 new_time_window
.time_width_double
=
3505 ltt_time_to_double(new_time_window
.time_width
);
3507 new_time_window
.end_time
= end_time
;
3509 time_change_manager(tab
, new_time_window
);
3514 on_MEntry4_value_changed (GtkSpinButton
*spinbutton
,
3517 Tab
*tab
=(Tab
*)user_data
;
3518 LttvTracesetContext
* tsc
=
3519 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3520 TimeInterval time_span
= tsc
->time_span
;
3521 gint value
= gtk_spin_button_get_value_as_int(spinbutton
);
3523 TimeWindow new_time_window
= tab
->time_window
;
3525 LttTime end_time
= new_time_window
.end_time
;
3527 end_time
.tv_nsec
= value
;
3529 if(ltt_time_compare(new_time_window
.start_time
, end_time
) >= 0) {
3530 /* Then, we must push front start time : keep the same time width
3531 * if possible, else end traceset time */
3532 new_time_window
.start_time
= LTT_TIME_MAX(
3533 ltt_time_sub(end_time
,
3534 new_time_window
.time_width
),
3535 time_span
.start_time
);
3538 /* Fix the time width to fit start time and end time */
3539 new_time_window
.time_width
= ltt_time_sub(end_time
,
3540 new_time_window
.start_time
);
3541 new_time_window
.time_width_double
=
3542 ltt_time_to_double(new_time_window
.time_width
);
3543 new_time_window
.end_time
= end_time
;
3545 time_change_manager(tab
, new_time_window
);
3550 void current_time_change_manager (Tab
*tab
,
3551 LttTime new_current_time
)
3553 /* Only one source of time change */
3554 if(tab
->current_time_manager_lock
== TRUE
) return;
3556 tab
->current_time_manager_lock
= TRUE
;
3558 LttvTracesetContext
*tsc
= LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3559 TimeInterval time_span
= tsc
->time_span
;
3561 /* current seconds */
3562 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry5
),
3563 (double)time_span
.start_time
.tv_sec
,
3564 (double)time_span
.end_time
.tv_sec
);
3565 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry5
),
3566 (double)new_current_time
.tv_sec
);
3569 /* start nanoseconds */
3570 if(new_current_time
.tv_sec
== time_span
.start_time
.tv_sec
) {
3571 /* can be both beginning and end at the same time. */
3572 if(new_current_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3573 /* If we are at the end, max nsec to end.. */
3574 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry6
),
3575 (double)time_span
.start_time
.tv_nsec
,
3576 (double)time_span
.end_time
.tv_nsec
);
3578 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry6
),
3579 (double)time_span
.start_time
.tv_nsec
,
3580 (double)NANOSECONDS_PER_SECOND
-1);
3582 } else if(new_current_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3583 /* If we are at the end, max nsec to end.. */
3584 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry6
),
3586 (double)time_span
.end_time
.tv_nsec
);
3587 } else /* anywhere else */
3588 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry6
),
3590 (double)NANOSECONDS_PER_SECOND
-1);
3592 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry6
),
3593 (double)new_current_time
.tv_nsec
);
3595 set_current_time(tab
, &new_current_time
);
3597 tab
->current_time_manager_lock
= FALSE
;
3600 void current_position_change_manager(Tab
*tab
,
3601 LttvTracesetContextPosition
*pos
)
3603 LttvTracesetContext
*tsc
=
3604 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3605 TimeInterval time_span
= tsc
->time_span
;
3607 g_assert(lttv_process_traceset_seek_position(tsc
, pos
) == 0);
3608 LttTime new_time
= lttv_traceset_context_position_get_time(pos
);
3610 current_time_change_manager(tab
, new_time
);
3612 set_current_position(tab
, pos
);
3617 on_MEntry5_value_changed (GtkSpinButton
*spinbutton
,
3620 Tab
*tab
= (Tab
*)user_data
;
3621 LttvTracesetContext
* tsc
=
3622 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3623 TimeInterval time_span
= tsc
->time_span
;
3624 gint value
= gtk_spin_button_get_value_as_int(spinbutton
);
3625 LttTime new_current_time
= tab
->current_time
;
3626 new_current_time
.tv_sec
= value
;
3628 /* current nanoseconds */
3629 if(new_current_time
.tv_sec
== time_span
.start_time
.tv_sec
) {
3630 if(new_current_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3631 if(new_current_time
.tv_nsec
> time_span
.end_time
.tv_nsec
)
3632 new_current_time
.tv_nsec
= time_span
.end_time
.tv_nsec
;
3633 if(new_current_time
.tv_nsec
< time_span
.start_time
.tv_nsec
)
3634 new_current_time
.tv_nsec
= time_span
.start_time
.tv_nsec
;
3636 if(new_current_time
.tv_nsec
< time_span
.start_time
.tv_nsec
)
3637 new_current_time
.tv_nsec
= time_span
.start_time
.tv_nsec
;
3640 else if(new_current_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3641 if(new_current_time
.tv_nsec
> time_span
.end_time
.tv_nsec
)
3642 new_current_time
.tv_nsec
= time_span
.end_time
.tv_nsec
;
3645 current_time_change_manager(tab
, new_current_time
);
3649 on_MEntry6_value_changed (GtkSpinButton
*spinbutton
,
3652 Tab
*tab
= (Tab
*)user_data
;
3653 gint value
= gtk_spin_button_get_value_as_int(spinbutton
);
3654 LttTime new_current_time
= tab
->current_time
;
3655 new_current_time
.tv_nsec
= value
;
3657 current_time_change_manager(tab
, new_current_time
);
3661 void scroll_value_changed_cb(GtkWidget
*scrollbar
,
3664 Tab
*tab
= (Tab
*)user_data
;
3665 TimeWindow new_time_window
;
3667 GtkAdjustment
*adjust
= gtk_range_get_adjustment(GTK_RANGE(scrollbar
));
3668 gdouble value
= gtk_adjustment_get_value(adjust
);
3669 // gdouble upper, lower, ratio, page_size;
3671 LttvTracesetContext
* tsc
=
3672 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3673 TimeInterval time_span
= tsc
->time_span
;
3675 time
= ltt_time_add(ltt_time_from_double(value
),
3676 time_span
.start_time
);
3678 new_time_window
.start_time
= time
;
3680 page_size
= adjust
->page_size
;
3682 new_time_window
.time_width
=
3683 ltt_time_from_double(page_size
);
3685 new_time_window
.time_width_double
=
3688 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
3689 new_time_window
.time_width
);
3692 time_change_manager(tab
, new_time_window
);
3694 //time_window = tab->time_window;
3696 lower
= adjust
->lower
;
3697 upper
= adjust
->upper
;
3698 ratio
= (value
- lower
) / (upper
- lower
);
3699 g_info("lower %lu, upper %lu, value %lu, ratio %lu", lower
, upper
, value
, ratio
);
3701 //time = ltt_time_sub(time_span->end_time, time_span->start_time);
3702 //time = ltt_time_mul(time, (float)ratio);
3703 //time = ltt_time_add(time_span->start_time, time);
3704 time
= ltt_time_add(ltt_time_from_double(value
),
3705 time_span
.start_time
);
3707 time_window
.start_time
= time
;
3709 page_size
= adjust
->page_size
;
3711 time_window
.time_width
=
3712 ltt_time_from_double(page_size
);
3713 //time = ltt_time_sub(time_span.end_time, time);
3714 //if(ltt_time_compare(time,time_window.time_width) < 0){
3715 // time_window.time_width = time;
3718 /* call viewer hooks for new time window */
3719 set_time_window(tab
, &time_window
);
3724 /* Display a dialogue showing all eventtypes and traces, let user to select the interested
3725 * eventtypes, tracefiles and traces (filter)
3728 /* Select a trace which will be removed from traceset
3731 char * get_remove_trace(char ** all_trace_name
, int nb_trace
)
3733 return get_selection(all_trace_name
, nb_trace
,
3734 "Select a trace", "Trace pathname");
3738 /* Select a module which will be loaded
3741 char * get_load_module(char ** load_module_name
, int nb_module
)
3743 return get_selection(load_module_name
, nb_module
,
3744 "Select a module to load", "Module name");
3750 /* Select a module which will be unloaded
3753 char * get_unload_module(char ** loaded_module_name
, int nb_module
)
3755 return get_selection(loaded_module_name
, nb_module
,
3756 "Select a module to unload", "Module name");
3760 /* Display a dialogue which shows all selectable items, let user to
3761 * select one of them
3764 char * get_selection(char ** loaded_module_name
, int nb_module
,
3765 char *title
, char * column_title
)
3767 GtkWidget
* dialogue
;
3768 GtkWidget
* scroll_win
;
3770 GtkListStore
* store
;
3771 GtkTreeViewColumn
* column
;
3772 GtkCellRenderer
* renderer
;
3773 GtkTreeSelection
* select
;
3776 char * unload_module_name
= NULL
;
3778 dialogue
= gtk_dialog_new_with_buttons(title
,
3781 GTK_STOCK_OK
,GTK_RESPONSE_ACCEPT
,
3782 GTK_STOCK_CANCEL
,GTK_RESPONSE_REJECT
,
3784 gtk_window_set_default_size((GtkWindow
*)dialogue
, 500, 200);
3786 scroll_win
= gtk_scrolled_window_new (NULL
, NULL
);
3787 gtk_widget_show ( scroll_win
);
3788 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll_win
),
3789 GTK_POLICY_AUTOMATIC
, GTK_POLICY_AUTOMATIC
);
3791 store
= gtk_list_store_new (N_COLUMNS
,G_TYPE_STRING
);
3792 tree
= gtk_tree_view_new_with_model(GTK_TREE_MODEL (store
));
3793 gtk_widget_show ( tree
);
3794 g_object_unref (G_OBJECT (store
));
3796 renderer
= gtk_cell_renderer_text_new ();
3797 column
= gtk_tree_view_column_new_with_attributes (column_title
,
3799 "text", MODULE_COLUMN
,
3801 gtk_tree_view_column_set_alignment (column
, 0.5);
3802 gtk_tree_view_column_set_fixed_width (column
, 150);
3803 gtk_tree_view_append_column (GTK_TREE_VIEW (tree
), column
);
3805 select
= gtk_tree_view_get_selection (GTK_TREE_VIEW (tree
));
3806 gtk_tree_selection_set_mode (select
, GTK_SELECTION_SINGLE
);
3808 gtk_container_add (GTK_CONTAINER (scroll_win
), tree
);
3810 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialogue
)->vbox
), scroll_win
,TRUE
, TRUE
,0);
3812 for(i
=0;i
<nb_module
;i
++){
3813 gtk_list_store_append (store
, &iter
);
3814 gtk_list_store_set (store
, &iter
, MODULE_COLUMN
,loaded_module_name
[i
],-1);
3817 id
= gtk_dialog_run(GTK_DIALOG(dialogue
));
3818 GtkTreeModel
**store_model
= (GtkTreeModel
**)&store
;
3820 case GTK_RESPONSE_ACCEPT
:
3821 case GTK_RESPONSE_OK
:
3822 if (gtk_tree_selection_get_selected (select
, store_model
, &iter
)){
3823 gtk_tree_model_get ((GtkTreeModel
*)store
, &iter
, MODULE_COLUMN
, &unload_module_name
, -1);
3825 case GTK_RESPONSE_REJECT
:
3826 case GTK_RESPONSE_CANCEL
:
3828 gtk_widget_destroy(dialogue
);
3832 return unload_module_name
;
3836 /* Insert all menu entry and tool buttons into this main window
3841 void add_all_menu_toolbar_constructors(MainWindow
* mw
, gpointer user_data
)
3845 lttvwindow_viewer_constructor constructor
;
3846 LttvMenus
* global_menu
, * instance_menu
;
3847 LttvToolbars
* global_toolbar
, * instance_toolbar
;
3848 LttvMenuClosure
*menu_item
;
3849 LttvToolbarClosure
*toolbar_item
;
3850 LttvAttributeValue value
;
3851 LttvIAttribute
*global_attributes
= LTTV_IATTRIBUTE(lttv_global_attributes());
3852 LttvIAttribute
*attributes
= mw
->attributes
;
3853 GtkWidget
* tool_menu_title_menu
, *new_widget
, *pixmap
;
3855 g_assert(lttv_iattribute_find_by_path(global_attributes
,
3856 "viewers/menu", LTTV_POINTER
, &value
));
3857 if(*(value
.v_pointer
) == NULL
)
3858 *(value
.v_pointer
) = lttv_menus_new();
3859 global_menu
= (LttvMenus
*)*(value
.v_pointer
);
3861 g_assert(lttv_iattribute_find_by_path(attributes
,
3862 "viewers/menu", LTTV_POINTER
, &value
));
3863 if(*(value
.v_pointer
) == NULL
)
3864 *(value
.v_pointer
) = lttv_menus_new();
3865 instance_menu
= (LttvMenus
*)*(value
.v_pointer
);
3869 g_assert(lttv_iattribute_find_by_path(global_attributes
,
3870 "viewers/toolbar", LTTV_POINTER
, &value
));
3871 if(*(value
.v_pointer
) == NULL
)
3872 *(value
.v_pointer
) = lttv_toolbars_new();
3873 global_toolbar
= (LttvToolbars
*)*(value
.v_pointer
);
3875 g_assert(lttv_iattribute_find_by_path(attributes
,
3876 "viewers/toolbar", LTTV_POINTER
, &value
));
3877 if(*(value
.v_pointer
) == NULL
)
3878 *(value
.v_pointer
) = lttv_toolbars_new();
3879 instance_toolbar
= (LttvToolbars
*)*(value
.v_pointer
);
3881 /* Add missing menu entries to window instance */
3882 for(i
=0;i
<global_menu
->len
;i
++) {
3883 menu_item
= &g_array_index(global_menu
, LttvMenuClosure
, i
);
3885 //add menu_item to window instance;
3886 constructor
= menu_item
->con
;
3887 tool_menu_title_menu
= lookup_widget(mw
->mwindow
,"ToolMenuTitle_menu");
3889 gtk_menu_item_new_with_mnemonic (menu_item
->menu_text
);
3890 gtk_container_add (GTK_CONTAINER (tool_menu_title_menu
),
3892 g_signal_connect ((gpointer
) new_widget
, "activate",
3893 G_CALLBACK (insert_viewer_wrap
),
3895 gtk_widget_show (new_widget
);
3896 lttv_menus_add(instance_menu
, menu_item
->con
,
3897 menu_item
->menu_path
,
3898 menu_item
->menu_text
,
3903 /* Add missing toolbar entries to window instance */
3904 for(i
=0;i
<global_toolbar
->len
;i
++) {
3905 toolbar_item
= &g_array_index(global_toolbar
, LttvToolbarClosure
, i
);
3907 //add toolbar_item to window instance;
3908 constructor
= toolbar_item
->con
;
3909 tool_menu_title_menu
= lookup_widget(mw
->mwindow
,"MToolbar1");
3910 pixbuf
= gdk_pixbuf_new_from_xpm_data((const char**)toolbar_item
->pixmap
);
3911 pixmap
= gtk_image_new_from_pixbuf(pixbuf
);
3913 gtk_toolbar_append_element (GTK_TOOLBAR (tool_menu_title_menu
),
3914 GTK_TOOLBAR_CHILD_BUTTON
,
3917 toolbar_item
->tooltip
, NULL
,
3918 pixmap
, NULL
, NULL
);
3919 gtk_label_set_use_underline(
3920 GTK_LABEL (((GtkToolbarChild
*) (
3921 g_list_last (GTK_TOOLBAR
3922 (tool_menu_title_menu
)->children
)->data
))->label
),
3924 gtk_container_set_border_width (GTK_CONTAINER (new_widget
), 1);
3925 g_signal_connect ((gpointer
) new_widget
,
3927 G_CALLBACK (insert_viewer_wrap
),
3929 gtk_widget_show (new_widget
);
3931 lttv_toolbars_add(instance_toolbar
, toolbar_item
->con
,
3932 toolbar_item
->tooltip
,
3933 toolbar_item
->pixmap
,
3941 /* Create a main window
3944 void construct_main_window(MainWindow
* parent
)
3946 g_debug("construct_main_window()");
3947 GtkWidget
* new_window
; /* New generated main window */
3948 MainWindow
* new_m_window
;/* New main window structure */
3949 GtkNotebook
* notebook
;
3950 LttvIAttribute
*attributes
=
3951 LTTV_IATTRIBUTE(g_object_new(LTTV_ATTRIBUTE_TYPE
, NULL
));
3952 LttvAttributeValue value
;
3955 new_m_window
= g_new(MainWindow
, 1);
3957 // Add the object's information to the module's array
3958 g_main_window_list
= g_slist_append(g_main_window_list
, new_m_window
);
3960 new_window
= create_MWindow();
3961 gtk_widget_show (new_window
);
3963 new_m_window
->mwindow
= new_window
;
3964 new_m_window
->attributes
= attributes
;
3966 g_assert(lttv_iattribute_find_by_path(attributes
,
3967 "viewers/menu", LTTV_POINTER
, &value
));
3968 *(value
.v_pointer
) = lttv_menus_new();
3970 g_assert(lttv_iattribute_find_by_path(attributes
,
3971 "viewers/toolbar", LTTV_POINTER
, &value
));
3972 *(value
.v_pointer
) = lttv_toolbars_new();
3974 add_all_menu_toolbar_constructors(new_m_window
, NULL
);
3976 g_object_set_data_full(G_OBJECT(new_window
),
3978 (gpointer
)new_m_window
,
3979 (GDestroyNotify
)g_free
);
3980 //create a default tab
3981 notebook
= (GtkNotebook
*)lookup_widget(new_m_window
->mwindow
, "MNotebook");
3982 if(notebook
== NULL
){
3983 g_info("Notebook does not exist\n");
3986 //gtk_notebook_popup_enable (GTK_NOTEBOOK(notebook));
3987 //for now there is no name field in LttvTraceset structure
3988 //Use "Traceset" as the label for the default tab
3990 GtkWidget
* parent_notebook
= lookup_widget(parent
->mwindow
, "MNotebook");
3991 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(parent_notebook
),
3992 gtk_notebook_get_current_page(GTK_NOTEBOOK(parent_notebook
)));
3998 parent_tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
4000 new_tab
= create_tab(new_m_window
, parent_tab
, notebook
, "Traceset");
4002 new_tab
= create_tab(new_m_window
, NULL
, notebook
, "Traceset");
4003 /* First window, use command line trace */
4004 if(g_init_trace
!= NULL
){
4005 lttvwindow_add_trace(new_tab
,
4009 LttvTraceset
*traceset
= new_tab
->traceset_info
->traceset
;
4010 SetTraceset(new_tab
, traceset
);
4012 /* Insert default viewers */
4014 LttvAttributeType type
;
4015 LttvAttributeName name
;
4016 LttvAttributeValue value
;
4017 LttvAttribute
*attribute
;
4019 LttvIAttribute
*attributes_global
=
4020 LTTV_IATTRIBUTE(lttv_global_attributes());
4022 g_assert(attribute
=
4023 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
4024 LTTV_IATTRIBUTE(attributes_global
),
4025 LTTV_VIEWER_CONSTRUCTORS
)));
4027 name
= g_quark_from_string("guievents");
4028 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
4030 if(type
== LTTV_POINTER
) {
4031 lttvwindow_viewer_constructor viewer_constructor
=
4032 (lttvwindow_viewer_constructor
)*value
.v_pointer
;
4033 insert_viewer(new_window
, viewer_constructor
);
4036 name
= g_quark_from_string("guicontrolflow");
4037 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
4039 if(type
== LTTV_POINTER
) {
4040 lttvwindow_viewer_constructor viewer_constructor
=
4041 (lttvwindow_viewer_constructor
)*value
.v_pointer
;
4042 insert_viewer(new_window
, viewer_constructor
);
4045 name
= g_quark_from_string("guistatistics");
4046 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
4048 if(type
== LTTV_POINTER
) {
4049 lttvwindow_viewer_constructor viewer_constructor
=
4050 (lttvwindow_viewer_constructor
)*value
.v_pointer
;
4051 insert_viewer(new_window
, viewer_constructor
);
4057 g_info("There are now : %d windows\n",g_slist_length(g_main_window_list
));
4061 /* Free the memory occupied by a tab structure
4065 void tab_destructor(Tab
* tab
)
4067 int i
, nb
, ref_count
;
4070 gtk_object_destroy(GTK_OBJECT(tab
->tooltips
));
4073 g_object_unref(tab
->attributes
);
4075 if(tab
->interrupted_state
)
4076 g_object_unref(tab
->interrupted_state
);
4079 if(tab
->traceset_info
->traceset_context
!= NULL
){
4080 //remove state update hooks
4081 lttv_state_remove_event_hooks(
4082 (LttvTracesetState
*)tab
->traceset_info
->
4084 lttv_context_fini(LTTV_TRACESET_CONTEXT(tab
->traceset_info
->
4086 g_object_unref(tab
->traceset_info
->traceset_context
);
4088 if(tab
->traceset_info
->traceset
!= NULL
) {
4089 nb
= lttv_traceset_number(tab
->traceset_info
->traceset
);
4090 for(i
= 0 ; i
< nb
; i
++) {
4091 trace
= lttv_traceset_get(tab
->traceset_info
->traceset
, i
);
4092 ref_count
= lttv_trace_get_ref_number(trace
);
4094 ltt_trace_close(lttv_trace(trace
));
4098 lttv_filter_destroy(tab
->filter
);
4099 lttv_traceset_destroy(tab
->traceset_info
->traceset
);
4100 /* Remove the idle events requests processing function of the tab */
4101 g_idle_remove_by_data(tab
);
4103 g_slist_free(tab
->events_requests
);
4104 g_free(tab
->traceset_info
);
4109 /* Create a tab and insert it into the current main window
4112 Tab
* create_tab(MainWindow
* mw
, Tab
*copy_tab
,
4113 GtkNotebook
* notebook
, char * label
)
4118 //create a new tab data structure
4121 //construct and initialize the traceset_info
4122 tab
->traceset_info
= g_new(TracesetInfo
,1);
4125 tab
->traceset_info
->traceset
=
4126 lttv_traceset_copy(copy_tab
->traceset_info
->traceset
);
4128 /* Copy the previous tab's filter */
4129 /* We can clone the filter, as we copy the trace set also */
4130 /* The filter must always be in sync with the trace set */
4131 tab
->filter
= lttv_filter_clone(copy_tab
->filter
);
4133 tab
->traceset_info
->traceset
= lttv_traceset_new();
4137 lttv_attribute_write_xml(
4138 lttv_traceset_attribute(tab
->traceset_info
->traceset
),
4144 tab
->time_manager_lock
= FALSE
;
4145 tab
->current_time_manager_lock
= FALSE
;
4147 //FIXME copy not implemented in lower level
4148 tab
->traceset_info
->traceset_context
=
4149 g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
4150 g_assert(tab
->traceset_info
->traceset_context
!= NULL
);
4152 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
),
4153 tab
->traceset_info
->traceset
);
4154 //add state update hooks
4155 lttv_state_add_event_hooks(
4156 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
4158 //determine the current_time and time_window of the tab
4160 if(copy_tab
!= NULL
){
4161 tab
->time_window
= copy_tab
->time_window
;
4162 tab
->current_time
= copy_tab
->current_time
;
4164 tab
->time_window
.start_time
=
4165 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
4166 time_span
.start_time
;
4167 if(DEFAULT_TIME_WIDTH_S
<
4168 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
4169 time_span
.end_time
.tv_sec
)
4170 tmp_time
.tv_sec
= DEFAULT_TIME_WIDTH_S
;
4173 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
4174 time_span
.end_time
.tv_sec
;
4175 tmp_time
.tv_nsec
= 0;
4176 tab
->time_window
.time_width
= tmp_time
;
4177 tab
->current_time
.tv_sec
=
4178 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
4179 time_span
.start_time
.tv_sec
;
4180 tab
->current_time
.tv_nsec
=
4181 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
4182 time_span
.start_time
.tv_nsec
;
4185 tab
->attributes
= LTTV_IATTRIBUTE(g_object_new(LTTV_ATTRIBUTE_TYPE
, NULL
));
4186 tab
->interrupted_state
= g_object_new(LTTV_ATTRIBUTE_TYPE
, NULL
);
4188 tab
->vbox
= gtk_vbox_new(FALSE
, 2);
4189 tab
->viewer_container
= gtk_vbox_new(TRUE
, 2);
4190 tab
->scrollbar
= gtk_hscrollbar_new(NULL
);
4191 //tab->multivpaned = gtk_multi_vpaned_new();
4193 gtk_box_pack_start(GTK_BOX(tab
->vbox
),
4194 tab
->viewer_container
,
4196 TRUE
, /* Give the extra space to the child */
4197 0); /* No padding */
4200 // tab->time_window = copy_tab->time_window;
4201 // tab->current_time = copy_tab->current_time;
4204 /* Create the timebar */
4206 tab
->MTimebar
= gtk_hbox_new(FALSE
, 2);
4207 gtk_widget_show(tab
->MTimebar
);
4208 tab
->tooltips
= gtk_tooltips_new();
4210 tab
->MEventBox1a
= gtk_event_box_new();
4211 gtk_widget_show(tab
->MEventBox1a
);
4212 gtk_tooltips_set_tip(tab
->tooltips
, tab
->MEventBox1a
,
4213 "Paste Start and End Times Here", "");
4214 tab
->MText1a
= gtk_label_new("Time Frame ");
4215 gtk_widget_show(tab
->MText1a
);
4216 gtk_container_add(GTK_CONTAINER(tab
->MEventBox1a
), tab
->MText1a
);
4217 tab
->MEventBox1b
= gtk_event_box_new();
4218 gtk_widget_show(tab
->MEventBox1b
);
4219 gtk_tooltips_set_tip(tab
->tooltips
, tab
->MEventBox1b
,
4220 "Paste Start Time Here", "");
4221 tab
->MText1b
= gtk_label_new("start: ");
4222 gtk_widget_show(tab
->MText1b
);
4223 gtk_container_add(GTK_CONTAINER(tab
->MEventBox1b
), tab
->MText1b
);
4224 tab
->MText2
= gtk_label_new("s");
4225 gtk_widget_show(tab
->MText2
);
4226 tab
->MText3a
= gtk_label_new("ns");
4227 gtk_widget_show(tab
->MText3a
);
4228 tab
->MEventBox3b
= gtk_event_box_new();
4229 gtk_widget_show(tab
->MEventBox3b
);
4230 gtk_tooltips_set_tip(tab
->tooltips
, tab
->MEventBox3b
,
4231 "Paste End Time Here", "");
4232 tab
->MText3b
= gtk_label_new("end:");
4233 gtk_widget_show(tab
->MText3b
);
4234 gtk_container_add(GTK_CONTAINER(tab
->MEventBox3b
), tab
->MText3b
);
4235 tab
->MText4
= gtk_label_new("s");
4236 gtk_widget_show(tab
->MText4
);
4237 tab
->MText5a
= gtk_label_new("ns");
4238 gtk_widget_show(tab
->MText5a
);
4239 tab
->MEventBox5b
= gtk_event_box_new();
4240 gtk_widget_show(tab
->MEventBox5b
);
4241 gtk_tooltips_set_tip(tab
->tooltips
, tab
->MEventBox5b
,
4242 "Paste Current Time Here", "");
4243 tab
->MText5b
= gtk_label_new("Current Time:");
4244 gtk_widget_show(tab
->MText5b
);
4245 gtk_container_add(GTK_CONTAINER(tab
->MEventBox5b
), tab
->MText5b
);
4246 tab
->MText6
= gtk_label_new("s");
4247 gtk_widget_show(tab
->MText6
);
4248 tab
->MText7
= gtk_label_new("ns");
4249 gtk_widget_show(tab
->MText7
);
4251 tab
->MEntry1
= gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4252 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab
->MEntry1
),0);
4253 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab
->MEntry1
),TRUE
);
4254 gtk_widget_show(tab
->MEntry1
);
4255 tab
->MEntry2
= gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4256 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab
->MEntry2
),0);
4257 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab
->MEntry2
),TRUE
);
4258 gtk_widget_show(tab
->MEntry2
);
4259 tab
->MEntry3
= gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4260 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab
->MEntry3
),0);
4261 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab
->MEntry3
),TRUE
);
4262 gtk_widget_show(tab
->MEntry3
);
4263 tab
->MEntry4
= gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4264 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab
->MEntry4
),0);
4265 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab
->MEntry4
),TRUE
);
4266 gtk_widget_show(tab
->MEntry4
);
4267 tab
->MEntry5
= gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4268 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab
->MEntry5
),0);
4269 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab
->MEntry5
),TRUE
);
4270 gtk_widget_show(tab
->MEntry5
);
4271 tab
->MEntry6
= gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4272 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab
->MEntry6
),0);
4273 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab
->MEntry6
),TRUE
);
4274 gtk_widget_show(tab
->MEntry6
);
4277 GtkWidget
*temp_widget
;
4279 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEventBox1a
, FALSE
,
4281 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEventBox1b
, FALSE
,
4283 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEntry1
, FALSE
, FALSE
, 0);
4284 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MText2
, FALSE
, FALSE
, 0);
4285 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEntry2
, FALSE
, FALSE
, 0);
4286 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MText3a
, FALSE
, FALSE
, 0);
4287 temp_widget
= gtk_vseparator_new();
4288 gtk_widget_show(temp_widget
);
4289 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), temp_widget
, FALSE
, FALSE
, 0);
4290 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEventBox3b
, FALSE
,
4292 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEntry3
, FALSE
, FALSE
, 0);
4293 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MText4
, FALSE
, FALSE
, 0);
4294 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEntry4
, FALSE
, FALSE
, 0);
4295 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MText5a
, FALSE
, FALSE
, 0);
4296 temp_widget
= gtk_vseparator_new();
4297 gtk_widget_show(temp_widget
);
4298 gtk_box_pack_end (GTK_BOX (tab
->MTimebar
), tab
->MText7
, FALSE
, FALSE
, 0);
4299 gtk_box_pack_end (GTK_BOX (tab
->MTimebar
), tab
->MEntry6
, FALSE
, FALSE
, 0);
4300 gtk_box_pack_end (GTK_BOX (tab
->MTimebar
), tab
->MText6
, FALSE
, FALSE
, 0);
4301 gtk_box_pack_end (GTK_BOX (tab
->MTimebar
), tab
->MEntry5
, FALSE
, FALSE
, 0);
4302 gtk_box_pack_end (GTK_BOX (tab
->MTimebar
), tab
->MEventBox5b
, FALSE
,
4304 gtk_box_pack_end (GTK_BOX (tab
->MTimebar
), temp_widget
, FALSE
, FALSE
, 0);
4307 //GtkWidget *test = gtk_button_new_with_label("drop");
4308 //gtk_button_set_relief(GTK_BUTTON(test), GTK_RELIEF_NONE);
4309 //gtk_widget_show(test);
4310 //gtk_box_pack_end(GTK_BOX (tab->MTimebar), test, FALSE, FALSE, 0);
4311 //gtk_widget_add_events(tab->MText1, GDK_ALL_EVENTS_MASK);//GDK_BUTTON_PRESS_MASK);
4312 /*GtkWidget *event_box = gtk_event_box_new();
4313 gtk_widget_show(event_box);
4314 gtk_tooltips_set_tip(tooltips, event_box,
4315 "Paste Current Time Here", "");
4316 gtk_box_pack_end(GTK_BOX (tab->MTimebar), event_box, FALSE, FALSE, 0);
4317 GtkWidget *test = gtk_label_new("drop");
4318 gtk_container_add(GTK_CONTAINER(event_box), test);
4319 gtk_widget_show(test);
4320 g_signal_connect (G_OBJECT(event_box),
4321 "button-press-event",
4322 G_CALLBACK (on_MText1_paste),
4326 g_signal_connect (G_OBJECT(tab
->MEventBox1a
),
4327 "button-press-event",
4328 G_CALLBACK (on_MEventBox1a_paste
),
4331 g_signal_connect (G_OBJECT(tab
->MEventBox1b
),
4332 "button-press-event",
4333 G_CALLBACK (on_MEventBox1b_paste
),
4335 g_signal_connect (G_OBJECT(tab
->MEventBox3b
),
4336 "button-press-event",
4337 G_CALLBACK (on_MEventBox3b_paste
),
4339 g_signal_connect (G_OBJECT(tab
->MEventBox5b
),
4340 "button-press-event",
4341 G_CALLBACK (on_MEventBox5b_paste
),
4345 gtk_box_pack_end(GTK_BOX(tab
->vbox
),
4347 FALSE
, /* Do not expand */
4348 FALSE
, /* Fill has no effect here (expand false) */
4349 0); /* No padding */
4351 gtk_box_pack_end(GTK_BOX(tab
->vbox
),
4353 FALSE
, /* Do not expand */
4354 FALSE
, /* Fill has no effect here (expand false) */
4355 0); /* No padding */
4357 g_object_set_data(G_OBJECT(tab
->viewer_container
), "focused_viewer", NULL
);
4363 // Display a label with a X
4364 GtkWidget *w_hbox = gtk_hbox_new(FALSE, 4);
4365 GtkWidget *w_label = gtk_label_new (label);
4366 GtkWidget *pixmap = create_pixmap(GTK_WIDGET(notebook), "close.png");
4367 GtkWidget *w_button = gtk_button_new ();
4368 gtk_container_add(GTK_CONTAINER(w_button), pixmap);
4369 //GtkWidget *w_button = gtk_button_new_with_label("x");
4371 gtk_button_set_relief(GTK_BUTTON(w_button), GTK_RELIEF_NONE);
4373 gtk_box_pack_start(GTK_BOX(w_hbox), w_label, TRUE, TRUE, 0);
4374 gtk_box_pack_end(GTK_BOX(w_hbox), w_button, FALSE,
4377 g_signal_connect_swapped (w_button, "clicked",
4378 G_CALLBACK (on_close_tab_X_clicked),
4381 gtk_widget_set_state(w_button, GTK_STATE_ACTIVE);
4383 gtk_widget_show (w_label);
4384 gtk_widget_show (pixmap);
4385 gtk_widget_show (w_button);
4386 gtk_widget_show (w_hbox);
4388 tab->label = w_hbox;
4392 tab
->label
= gtk_label_new (label
);
4394 gtk_widget_show(tab
->label
);
4395 gtk_widget_show(tab
->scrollbar
);
4396 gtk_widget_show(tab
->viewer_container
);
4397 gtk_widget_show(tab
->vbox
);
4398 //gtk_widget_show(tab->multivpaned);
4401 /* Start with empty events requests list */
4402 tab
->events_requests
= NULL
;
4403 tab
->events_request_pending
= FALSE
;
4405 g_object_set_data_full(
4406 G_OBJECT(tab
->vbox
),
4409 (GDestroyNotify
)tab_destructor
);
4411 g_signal_connect(G_OBJECT(tab
->scrollbar
), "value-changed",
4412 G_CALLBACK(scroll_value_changed_cb
), tab
);
4414 g_signal_connect ((gpointer
) tab
->MEntry1
, "value-changed",
4415 G_CALLBACK (on_MEntry1_value_changed
),
4417 g_signal_connect ((gpointer
) tab
->MEntry2
, "value-changed",
4418 G_CALLBACK (on_MEntry2_value_changed
),
4420 g_signal_connect ((gpointer
) tab
->MEntry3
, "value-changed",
4421 G_CALLBACK (on_MEntry3_value_changed
),
4423 g_signal_connect ((gpointer
) tab
->MEntry4
, "value-changed",
4424 G_CALLBACK (on_MEntry4_value_changed
),
4426 g_signal_connect ((gpointer
) tab
->MEntry5
, "value-changed",
4427 G_CALLBACK (on_MEntry5_value_changed
),
4429 g_signal_connect ((gpointer
) tab
->MEntry6
, "value-changed",
4430 G_CALLBACK (on_MEntry6_value_changed
),
4433 //g_signal_connect(G_OBJECT(tab->scrollbar), "changed",
4434 // G_CALLBACK(scroll_value_changed_cb), tab);
4437 //insert tab into notebook
4438 gtk_notebook_append_page(notebook
,
4441 list
= gtk_container_get_children(GTK_CONTAINER(notebook
));
4442 gtk_notebook_set_current_page(notebook
,g_list_length(list
)-1);
4443 // always show : not if(g_list_length(list)>1)
4444 gtk_notebook_set_show_tabs(notebook
, TRUE
);
4447 lttvwindow_report_time_window(tab
, copy_tab
->time_window
);
4448 lttvwindow_report_current_time(tab
, copy_tab
->current_time
);
4450 TimeWindow time_window
;
4452 time_window
.start_time
= ltt_time_zero
;
4453 time_window
.end_time
= ltt_time_add(time_window
.start_time
,
4454 lttvwindow_default_time_width
);
4455 time_window
.time_width
= lttvwindow_default_time_width
;
4456 time_window
.time_width_double
= ltt_time_to_double(time_window
.time_width
);
4458 lttvwindow_report_time_window(tab
, time_window
);
4459 lttvwindow_report_current_time(tab
, ltt_time_zero
);
4462 LttvTraceset
*traceset
= tab
->traceset_info
->traceset
;
4463 SetTraceset(tab
, traceset
);
4469 * execute_events_requests
4471 * Idle function that executes the pending requests for a tab.
4473 * @return return value : TRUE : keep the idle function, FALSE : remove it.
4475 gboolean
execute_events_requests(Tab
*tab
)
4477 return ( lttvwindow_process_pending_requests(tab
) );