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/lttv_plugin_tab.h>
51 static LttTime lttvwindow_default_time_width = { 1, 0 };
52 #define CLIP_BUF 256 // size of clipboard buffer
54 extern LttvTrace *g_init_trace ;
57 /** Array containing instanced objects. */
58 extern GSList * g_main_window_list;
60 /** MD : keep old directory. */
61 static char remember_plugins_dir[PATH_MAX] = "";
62 static char remember_trace_dir[PATH_MAX] = "";
64 void tab_destructor(LttvPluginTab * ptab);
66 MainWindow * get_window_data_struct(GtkWidget * widget);
67 char * get_load_module(MainWindow *mw,
68 char ** load_module_name, int nb_module);
69 char * get_unload_module(MainWindow *mw,
70 char ** loaded_module_name, int nb_module);
71 char * get_remove_trace(MainWindow *mw, char ** all_trace_name, int nb_trace);
72 char * get_selection(MainWindow *mw,
73 char ** all_name, int nb, char *title, char * column_title);
74 void init_tab(Tab *tab, MainWindow * mw, Tab *copy_tab,
75 GtkNotebook * notebook, char * label);
77 static void insert_viewer(GtkWidget* widget, lttvwindow_viewer_constructor constructor);
79 LttvPluginTab *create_new_tab(GtkWidget* widget, gpointer user_data);
81 static gboolean lttvwindow_process_pending_requests(Tab *tab);
95 /* Pasting routines */
97 static void MEventBox1a_receive(GtkClipboard *clipboard,
101 if(text == NULL) return;
102 Tab *tab = (Tab *)data;
103 gchar buffer[CLIP_BUF];
104 gchar *ptr = buffer, *ptr_ssec, *ptr_snsec, *ptr_esec, *ptr_ensec;
106 strncpy(buffer, text, CLIP_BUF);
109 while(!isdigit(*ptr) && ptr < buffer+CLIP_BUF-1) ptr++;
110 /* remove leading junk */
112 while(isdigit(*ptr) && ptr < buffer+CLIP_BUF-1) ptr++;
113 /* read all the first number */
117 while(!isdigit(*ptr) && ptr < buffer+CLIP_BUF-1) ptr++;
118 /* remove leading junk */
120 while(isdigit(*ptr) && ptr < buffer+CLIP_BUF-1) ptr++;
121 /* read all the first number */
125 while(!isdigit(*ptr) && ptr < buffer+CLIP_BUF-1) ptr++;
126 /* remove leading junk */
128 while(isdigit(*ptr) && ptr < buffer+CLIP_BUF-1) ptr++;
129 /* read all the first number */
133 while(!isdigit(*ptr) && ptr < buffer+CLIP_BUF-1) ptr++;
134 /* remove leading junk */
136 while(isdigit(*ptr) && ptr < buffer+CLIP_BUF-1) ptr++;
137 /* read all the first number */
140 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab->MEntry1),
141 (double)strtoul(ptr_ssec, NULL, 10));
142 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab->MEntry2),
143 (double)strtoul(ptr_snsec, NULL, 10));
144 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab->MEntry3),
145 (double)strtoul(ptr_esec, NULL, 10));
146 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab->MEntry4),
147 (double)strtoul(ptr_ensec, NULL, 10));
150 static gboolean on_MEventBox1a_paste(GtkWidget *widget, GdkEventButton *event,
153 Tab *tab = (Tab*)data;
155 GtkClipboard *clip = gtk_clipboard_get_for_display(gdk_display_get_default(),
156 GDK_SELECTION_PRIMARY);
157 gtk_clipboard_request_text(clip,
158 (GtkClipboardTextReceivedFunc)MEventBox1a_receive,
165 static void MEventBox1b_receive(GtkClipboard *clipboard,
169 if(text == NULL) return;
170 Tab *tab = (Tab *)data;
171 gchar buffer[CLIP_BUF];
172 gchar *ptr = buffer, *ptr_sec, *ptr_nsec;
174 strncpy(buffer, text, CLIP_BUF);
176 while(!isdigit(*ptr) && ptr < buffer+CLIP_BUF-1) ptr++;
177 /* remove leading junk */
179 while(isdigit(*ptr) && ptr < buffer+CLIP_BUF-1) ptr++;
180 /* read all the first number */
184 while(!isdigit(*ptr) && ptr < buffer+CLIP_BUF-1) ptr++;
185 /* remove leading junk */
187 while(isdigit(*ptr) && ptr < buffer+CLIP_BUF-1) ptr++;
188 /* read all the first number */
191 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab->MEntry1),
192 (double)strtoul(ptr_sec, NULL, 10));
193 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab->MEntry2),
194 (double)strtoul(ptr_nsec, NULL, 10));
198 static gboolean on_MEventBox1b_paste(GtkWidget *widget, GdkEventButton *event,
201 Tab *tab = (Tab*)data;
203 GtkClipboard *clip = gtk_clipboard_get_for_display(gdk_display_get_default(),
204 GDK_SELECTION_PRIMARY);
205 gtk_clipboard_request_text(clip,
206 (GtkClipboardTextReceivedFunc)MEventBox1b_receive,
212 static void MEventBox3b_receive(GtkClipboard *clipboard,
216 if(text == NULL) return;
217 Tab *tab = (Tab *)data;
218 gchar buffer[CLIP_BUF];
219 gchar *ptr = buffer, *ptr_sec, *ptr_nsec;
221 strncpy(buffer, text, CLIP_BUF);
223 while(!isdigit(*ptr) && ptr < buffer+CLIP_BUF-1) ptr++;
224 /* remove leading junk */
226 while(isdigit(*ptr) && ptr < buffer+CLIP_BUF-1) ptr++;
227 /* read all the first number */
231 while(!isdigit(*ptr) && ptr < buffer+CLIP_BUF-1) ptr++;
232 /* remove leading junk */
234 while(isdigit(*ptr) && ptr < buffer+CLIP_BUF-1) ptr++;
235 /* read all the first number */
238 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab->MEntry3),
239 (double)strtoul(ptr_sec, NULL, 10));
240 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab->MEntry4),
241 (double)strtoul(ptr_nsec, NULL, 10));
245 static gboolean on_MEventBox3b_paste(GtkWidget *widget, GdkEventButton *event,
248 Tab *tab = (Tab*)data;
250 GtkClipboard *clip = gtk_clipboard_get_for_display(gdk_display_get_default(),
251 GDK_SELECTION_PRIMARY);
252 gtk_clipboard_request_text(clip,
253 (GtkClipboardTextReceivedFunc)MEventBox3b_receive,
259 static void MEventBox5b_receive(GtkClipboard *clipboard,
263 if(text == NULL) return;
264 Tab *tab = (Tab *)data;
265 gchar buffer[CLIP_BUF];
266 gchar *ptr = buffer, *ptr_sec, *ptr_nsec;
268 strncpy(buffer, text, CLIP_BUF);
270 while(!isdigit(*ptr) && ptr < buffer+CLIP_BUF-1) ptr++;
271 /* remove leading junk */
273 while(isdigit(*ptr) && ptr < buffer+CLIP_BUF-1) ptr++;
274 /* read all the first number */
278 while(!isdigit(*ptr) && ptr < buffer+CLIP_BUF-1) ptr++;
279 /* remove leading junk */
281 while(isdigit(*ptr) && ptr < buffer+CLIP_BUF-1) ptr++;
282 /* read all the first number */
285 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab->MEntry5),
286 (double)strtoul(ptr_sec, NULL, 10));
287 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab->MEntry6),
288 (double)strtoul(ptr_nsec, NULL, 10));
292 static gboolean on_MEventBox5b_paste(GtkWidget *widget, GdkEventButton *event,
295 Tab *tab = (Tab*)data;
297 GtkClipboard *clip = gtk_clipboard_get_for_display(gdk_display_get_default(),
298 GDK_SELECTION_PRIMARY);
299 gtk_clipboard_request_text(clip,
300 (GtkClipboardTextReceivedFunc)MEventBox5b_receive,
306 static void MEventBox8_receive(GtkClipboard *clipboard,
310 if(text == NULL) return;
311 Tab *tab = (Tab *)data;
312 gchar buffer[CLIP_BUF];
313 gchar *ptr = buffer, *ptr_sec, *ptr_nsec;
315 strncpy(buffer, text, CLIP_BUF);
317 while(!isdigit(*ptr) && ptr < buffer+CLIP_BUF-1) ptr++;
318 /* remove leading junk */
320 while(isdigit(*ptr) && ptr < buffer+CLIP_BUF-1) ptr++;
321 /* read all the first number */
325 while(!isdigit(*ptr) && ptr < buffer+CLIP_BUF-1) ptr++;
326 /* remove leading junk */
328 while(isdigit(*ptr) && ptr < buffer+CLIP_BUF-1) ptr++;
329 /* read all the first number */
332 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab->MEntry7),
333 (double)strtoul(ptr_sec, NULL, 10));
334 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab->MEntry8),
335 (double)strtoul(ptr_nsec, NULL, 10));
339 static gboolean on_MEventBox8_paste(GtkWidget *widget, GdkEventButton *event,
342 Tab *tab = (Tab*)data;
344 GtkClipboard *clip = gtk_clipboard_get_for_display(gdk_display_get_default(),
345 GDK_SELECTION_PRIMARY);
346 gtk_clipboard_request_text(clip,
347 (GtkClipboardTextReceivedFunc)MEventBox8_receive,
353 static void on_top_notify(GObject *gobject,
357 Tab *tab = (Tab*)user_data;
358 g_message("in on_top_notify.\n");
362 static gboolean viewer_grab_focus(GtkWidget *widget, GdkEventButton *event,
365 GtkWidget *viewer = GTK_WIDGET(data);
366 GtkWidget *viewer_container = gtk_widget_get_parent(viewer);
368 g_debug("FOCUS GRABBED");
369 g_object_set_data(G_OBJECT(viewer_container), "focused_viewer", viewer);
374 static void connect_focus_recursive(GtkWidget *widget,
377 if(GTK_IS_CONTAINER(widget)) {
378 gtk_container_forall(GTK_CONTAINER(widget),
379 (GtkCallback)connect_focus_recursive,
383 if(GTK_IS_TREE_VIEW(widget)) {
384 gtk_tree_view_set_headers_clickable(GTK_TREE_VIEW(widget), TRUE);
386 gtk_widget_add_events(widget, GDK_BUTTON_PRESS_MASK);
387 g_signal_connect (G_OBJECT(widget),
388 "button-press-event",
389 G_CALLBACK (viewer_grab_focus),
393 /* Stop all the processings and call gtk_main_quit() */
394 static void mainwindow_quit()
396 lttvwindowtraces_unregister_requests(g_quark_from_string("stats"));
397 lttvwindowtraces_unregister_requests(g_quark_from_string("state"));
398 lttvwindowtraces_unregister_computation_hooks(g_quark_from_string("stats"));
399 lttvwindowtraces_unregister_computation_hooks(g_quark_from_string("state"));
405 /* insert_viewer function constructs an instance of a viewer first,
406 * then inserts the widget of the instance into the container of the
411 insert_viewer_wrap(GtkWidget *menuitem, gpointer user_data)
413 insert_viewer((GtkWidget*)menuitem, (lttvwindow_viewer_constructor)user_data);
417 /* internal functions */
418 void insert_viewer(GtkWidget* widget, lttvwindow_viewer_constructor constructor)
420 GtkWidget * viewer_container;
421 MainWindow * mw_data = get_window_data_struct(widget);
422 GtkWidget * notebook = lookup_widget(widget, "MNotebook");
424 TimeInterval * time_interval;
425 GtkWidget *page = gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook),
426 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook)));
431 ptab = create_new_tab(widget, NULL);
433 ptab = (LttvPluginTab *)g_object_get_data(G_OBJECT(page), "Tab_Plugin");
437 viewer_container = tab->viewer_container;
439 viewer = (GtkWidget*)constructor(ptab);
442 //gtk_multivpaned_widget_add(GTK_MULTIVPANED(multivpaned), viewer);
444 gtk_box_pack_end(GTK_BOX(viewer_container),
450 /* We want to connect the viewer_grab_focus to EVERY
451 * child of this widget. The little trick is to get each child
452 * of each GTK_CONTAINER, even subchildren.
454 connect_focus_recursive(viewer, viewer);
459 * Function to set/update traceset for the viewers
460 * @param tab viewer's tab
461 * @param traceset traceset of the main window.
463 * 0 : traceset updated
464 * 1 : no traceset hooks to update; not an error.
467 int SetTraceset(Tab * tab, LttvTraceset *traceset)
469 LttvTracesetContext *tsc =
470 LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context);
471 TimeInterval time_span = tsc->time_span;
472 TimeWindow new_time_window = tab->time_window;
473 LttTime new_current_time = tab->current_time;
475 /* Set the tab's time window and current time if
477 if(ltt_time_compare(tab->time_window.start_time, time_span.start_time) < 0
478 || ltt_time_compare(tab->time_window.end_time,
479 time_span.end_time) > 0) {
480 new_time_window.start_time = time_span.start_time;
482 new_current_time = time_span.start_time;
486 if(ltt_time_compare(lttvwindow_default_time_width,
487 ltt_time_sub(time_span.end_time, time_span.start_time)) < 0
489 ltt_time_compare(time_span.end_time, time_span.start_time) == 0)
490 tmp_time = lttvwindow_default_time_width;
492 tmp_time = time_span.end_time;
494 new_time_window.time_width = tmp_time ;
495 new_time_window.time_width_double = ltt_time_to_double(tmp_time);
496 new_time_window.end_time = ltt_time_add(new_time_window.start_time,
497 new_time_window.time_width) ;
504 GtkAdjustment *adjustment = gtk_range_get_adjustment(GTK_RANGE(tab->scrollbar));
505 LttTime upper = ltt_time_sub(time_span.end_time, time_span.start_time);
507 g_object_set(G_OBJECT(adjustment),
511 ltt_time_to_double(upper)
512 * NANOSECONDS_PER_SECOND, /* upper */
514 ltt_time_to_double(tab->time_window.time_width)
515 / SCROLL_STEP_PER_PAGE
516 * NANOSECONDS_PER_SECOND, /* step increment */
518 ltt_time_to_double(tab->time_window.time_width)
519 * NANOSECONDS_PER_SECOND, /* page increment */
521 ltt_time_to_double(tab->time_window.time_width)
522 * NANOSECONDS_PER_SECOND, /* page size */
524 gtk_adjustment_changed(adjustment);
526 g_object_set(G_OBJECT(adjustment),
529 ltt_time_sub(tab->time_window.start_time, time_span.start_time))
530 * NANOSECONDS_PER_SECOND, /* value */
532 gtk_adjustment_value_changed(adjustment);
534 /* set the time bar. The value callbacks will change their nsec themself */
536 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab->MEntry1),
537 (double)time_span.start_time.tv_sec,
538 (double)time_span.end_time.tv_sec);
541 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab->MEntry3),
542 (double)time_span.start_time.tv_sec,
543 (double)time_span.end_time.tv_sec);
545 /* current seconds */
546 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab->MEntry5),
547 (double)time_span.start_time.tv_sec,
548 (double)time_span.end_time.tv_sec);
551 /* Finally, call the update hooks of the viewers */
553 LttvAttributeValue value;
557 g_assert( lttv_iattribute_find_by_path(tab->attributes,
558 "hooks/updatetraceset", LTTV_POINTER, &value));
560 tmp = (LttvHooks*)*(value.v_pointer);
561 if(tmp == NULL) retval = 1;
562 else lttv_hooks_call(tmp,traceset);
564 time_change_manager(tab, new_time_window);
565 current_time_change_manager(tab, new_current_time);
571 * Function to set/update filter for the viewers
572 * @param tab viewer's tab
573 * @param filter filter of the main window.
576 * 0 : filters updated
577 * 1 : no filter hooks to update; not an error.
580 int SetFilter(Tab * tab, gpointer filter)
583 LttvAttributeValue value;
585 g_assert(lttv_iattribute_find_by_path(tab->attributes,
586 "hooks/updatefilter", LTTV_POINTER, &value));
588 tmp = (LttvHooks*)*(value.v_pointer);
590 if(tmp == NULL) return 1;
591 lttv_hooks_call(tmp,filter);
599 * Function to redraw each viewer belonging to the current tab
600 * @param tab viewer's tab
603 void update_traceset(Tab *tab)
605 LttvAttributeValue value;
607 g_assert(lttv_iattribute_find_by_path(tab->attributes,
608 "hooks/updatetraceset", LTTV_POINTER, &value));
609 tmp = (LttvHooks*)*(value.v_pointer);
610 if(tmp == NULL) return;
611 lttv_hooks_call(tmp, NULL);
615 /* get_label function is used to get user input, it displays an input
616 * box, which allows user to input a string
619 void get_label_string (GtkWidget * text, gchar * label)
621 GtkEntry * entry = (GtkEntry*)text;
622 if(strlen(gtk_entry_get_text(entry))!=0)
623 strcpy(label,gtk_entry_get_text(entry));
626 gboolean get_label(MainWindow * mw, gchar * str, gchar* dialogue_title, gchar * label_str)
628 GtkWidget * dialogue;
633 dialogue = gtk_dialog_new_with_buttons(dialogue_title,NULL,
635 GTK_STOCK_OK,GTK_RESPONSE_ACCEPT,
636 GTK_STOCK_CANCEL,GTK_RESPONSE_REJECT,
639 label = gtk_label_new(label_str);
640 gtk_widget_show(label);
642 text = gtk_entry_new();
643 gtk_widget_show(text);
645 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialogue)->vbox), label,TRUE, TRUE,0);
646 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialogue)->vbox), text,FALSE, FALSE,0);
648 id = gtk_dialog_run(GTK_DIALOG(dialogue));
650 case GTK_RESPONSE_ACCEPT:
651 get_label_string(text,str);
652 gtk_widget_destroy(dialogue);
654 case GTK_RESPONSE_REJECT:
656 gtk_widget_destroy(dialogue);
663 /* get_window_data_struct function is actually a lookup function,
664 * given a widget which is in the tree of the main window, it will
665 * return the MainWindow data structure associated with main window
668 MainWindow * get_window_data_struct(GtkWidget * widget)
671 MainWindow * mw_data;
673 mw = lookup_widget(widget, "MWindow");
675 g_info("Main window does not exist\n");
679 mw_data = (MainWindow *) g_object_get_data(G_OBJECT(mw),"main_window_data");
681 g_warning("Main window data does not exist\n");
688 /* create_new_window function, just constructs a new main window
691 void create_new_window(GtkWidget* widget, gpointer user_data, gboolean clone)
693 MainWindow * parent = get_window_data_struct(widget);
696 g_info("Clone : use the same traceset\n");
697 construct_main_window(parent);
699 g_info("Empty : traceset is set to NULL\n");
700 construct_main_window(NULL);
704 /* Get the currently focused viewer.
705 * If no viewer is focused, use the first one.
707 * If no viewer available, return NULL.
709 GtkWidget *viewer_container_focus(GtkWidget *container)
713 widget = (GtkWidget*)g_object_get_data(G_OBJECT(container),
717 g_debug("no widget focused");
718 GList *children = gtk_container_get_children(GTK_CONTAINER(container));
721 widget = GTK_WIDGET(children->data);
722 g_object_set_data(G_OBJECT(container),
732 gint viewer_container_position(GtkWidget *container, GtkWidget *child)
735 if(child == NULL) return -1;
739 memset(&value, 0, sizeof(GValue));
740 g_value_init(&value, G_TYPE_INT);
741 gtk_container_child_get_property(GTK_CONTAINER(container),
745 pos = g_value_get_int(&value);
751 /* move_*_viewer functions move the selected view up/down in
755 void move_down_viewer(GtkWidget * widget, gpointer user_data)
757 MainWindow * mw = get_window_data_struct(widget);
758 GtkWidget * notebook = lookup_widget(widget, "MNotebook");
760 GtkWidget *page = gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook),
761 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook)));
768 ptab = (Tab *)g_object_get_data(G_OBJECT(page), "Tab_Plugin");
772 //gtk_multivpaned_widget_move_up(GTK_MULTIVPANED(tab->multivpaned));
774 /* change the position in the vbox */
775 GtkWidget *focus_widget;
777 focus_widget = viewer_container_focus(tab->viewer_container);
778 position = viewer_container_position(tab->viewer_container, focus_widget);
781 /* can move up one position */
782 gtk_box_reorder_child(GTK_BOX(tab->viewer_container),
789 void move_up_viewer(GtkWidget * widget, gpointer user_data)
791 MainWindow * mw = get_window_data_struct(widget);
792 GtkWidget * notebook = lookup_widget(widget, "MNotebook");
794 GtkWidget *page = gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook),
795 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook)));
802 ptab = (LttvPluginTab *)g_object_get_data(G_OBJECT(page), "Tab_Plugin");
806 //gtk_multivpaned_widget_move_down(GTK_MULTIVPANED(tab->multivpaned));
807 /* change the position in the vbox */
808 GtkWidget *focus_widget;
810 focus_widget = viewer_container_focus(tab->viewer_container);
811 position = viewer_container_position(tab->viewer_container, focus_widget);
815 g_list_length(gtk_container_get_children(
816 GTK_CONTAINER(tab->viewer_container)))-1
818 /* can move down one position */
819 gtk_box_reorder_child(GTK_BOX(tab->viewer_container),
827 /* delete_viewer deletes the selected viewer in the current tab
830 void delete_viewer(GtkWidget * widget, gpointer user_data)
832 MainWindow * mw = get_window_data_struct(widget);
833 GtkWidget * notebook = lookup_widget(widget, "MNotebook");
835 GtkWidget *page = gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook),
836 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook)));
843 ptab = (Tab *)g_object_get_data(G_OBJECT(page), "Tab_Plugin");
847 //gtk_multivpaned_widget_delete(GTK_MULTIVPANED(tab->multivpaned));
849 GtkWidget *focus_widget = viewer_container_focus(tab->viewer_container);
851 if(focus_widget != NULL)
852 gtk_widget_destroy(focus_widget);
854 g_object_set_data(G_OBJECT(tab->viewer_container), "focused_viewer", NULL);
858 /* open_traceset will open a traceset saved in a file
859 * Right now, it is not finished yet, (not working)
863 void open_traceset(GtkWidget * widget, gpointer user_data)
867 LttvTraceset * traceset;
868 MainWindow * mw_data = get_window_data_struct(widget);
869 GtkFileSelection * file_selector =
870 (GtkFileSelection *)gtk_file_selection_new("Select a traceset");
872 gtk_file_selection_hide_fileop_buttons(file_selector);
874 gtk_window_set_transient_for(GTK_WINDOW(file_selector),
875 GTK_WINDOW(mw_data->mwindow));
877 id = gtk_dialog_run(GTK_DIALOG(file_selector));
879 case GTK_RESPONSE_ACCEPT:
880 case GTK_RESPONSE_OK:
881 dir = gtk_file_selection_get_selections (file_selector);
882 traceset = lttv_traceset_load(dir[0]);
883 g_info("Open a trace set %s\n", dir[0]);
886 case GTK_RESPONSE_REJECT:
887 case GTK_RESPONSE_CANCEL:
889 gtk_widget_destroy((GtkWidget*)file_selector);
895 /* lttvwindow_process_pending_requests
897 * This internal function gets called by g_idle, taking care of the pending
898 * requests. It is responsible for concatenation of time intervals and position
899 * requests. It does it with the following algorithm organizing process traceset
900 * calls. Here is the detailed description of the way it works :
902 * - Events Requests Servicing Algorithm
904 * Data structures necessary :
906 * List of requests added to context : list_in
907 * List of requests not added to context : list_out
912 * list_out : many events requests
914 * FIXME : insert rest of algorithm here
918 #define list_out tab->events_requests
920 gboolean lttvwindow_process_pending_requests(Tab *tab)
923 LttvTracesetContext *tsc;
924 LttvTracefileContext *tfc;
925 GSList *list_in = NULL;
929 LttvTracesetContextPosition *end_position;
931 if(lttvwindow_preempt_count > 0) return TRUE;
934 g_critical("Foreground processing : tab does not exist. Processing removed.");
938 /* There is no events requests pending : we should never have been called! */
939 g_assert(g_slist_length(list_out) != 0);
941 tsc = LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context);
943 //set the cursor to be X shape, indicating that the computer is busy in doing its job
945 new = gdk_cursor_new(GDK_X_CURSOR);
946 widget = lookup_widget(tab->mw->mwindow, "MToolbar1");
947 win = gtk_widget_get_parent_window(widget);
948 gdk_window_set_cursor(win, new);
949 gdk_cursor_unref(new);
950 gdk_window_stick(win);
951 gdk_window_unstick(win);
954 g_debug("SIZE events req len : %d", g_slist_length(list_out));
956 /* Preliminary check for no trace in traceset */
957 /* Unregister the routine if empty, empty list_out too */
958 if(lttv_traceset_number(tsc->ts) == 0) {
960 /* - For each req in list_out */
961 GSList *iter = list_out;
963 while(iter != NULL) {
965 gboolean remove = FALSE;
966 gboolean free_data = FALSE;
967 EventsRequest *events_request = (EventsRequest *)iter->data;
969 /* - Call end request for req */
970 if(events_request->servicing == TRUE)
971 lttv_hooks_call(events_request->after_request, (gpointer)tsc);
973 /* - remove req from list_out */
974 /* Destroy the request */
981 GSList *remove_iter = iter;
983 iter = g_slist_next(iter);
984 if(free_data) events_request_free((EventsRequest*)remove_iter->data);
985 list_out = g_slist_remove_link(list_out, remove_iter);
986 } else { // not remove
987 iter = g_slist_next(iter);
992 /* 0.1 Lock Traces */
997 iter_trace<lttv_traceset_number(tsc->ts);
999 LttvTrace *trace_v = lttv_traceset_get(tsc->ts, iter_trace);
1001 if(lttvwindowtraces_lock(trace_v) != 0) {
1002 g_critical("Foreground processing : Unable to get trace lock");
1003 return TRUE; /* Cannot get lock, try later */
1008 /* 0.2 Seek tracefiles positions to context position */
1009 //g_assert(lttv_process_traceset_seek_position(tsc, sync_position) == 0);
1010 lttv_process_traceset_synchronize_tracefiles(tsc);
1013 /* Events processing algorithm implementation */
1014 /* Warning : the gtk_events_pending takes a LOT of cpu time. So what we do
1015 * instead is to leave the control to GTK and take it back.
1017 /* A. Servicing loop */
1018 //while( (g_slist_length(list_in) != 0 || g_slist_length(list_out) != 0)) {
1019 if((g_slist_length(list_in) != 0 || g_slist_length(list_out) != 0)) {
1021 /* 1. If list_in is empty (need a seek) */
1022 if( g_slist_length(list_in) == 0 ) {
1024 /* list in is empty, need a seek */
1026 /* 1.1 Add requests to list_in */
1027 GSList *ltime = NULL;
1028 GSList *lpos = NULL;
1029 GSList *iter = NULL;
1031 /* 1.1.1 Find all time requests with the lowest start time in list_out
1034 if(g_slist_length(list_out) > 0)
1035 ltime = g_slist_append(ltime, g_slist_nth_data(list_out, 0));
1036 for(iter=g_slist_nth(list_out,1);iter!=NULL;iter=g_slist_next(iter)) {
1037 /* Find all time requests with the lowest start time in list_out */
1038 EventsRequest *event_request_ltime = (EventsRequest*)g_slist_nth_data(ltime, 0);
1039 EventsRequest *event_request_list_out = (EventsRequest*)iter->data;
1042 comp = ltt_time_compare(event_request_ltime->start_time,
1043 event_request_list_out->start_time);
1045 ltime = g_slist_append(ltime, event_request_list_out);
1047 /* Remove all elements from ltime, and add current */
1048 while(ltime != NULL)
1049 ltime = g_slist_delete_link(ltime, g_slist_nth(ltime, 0));
1050 ltime = g_slist_append(ltime, event_request_list_out);
1054 /* 1.1.2 Find all position requests with the lowest position in list_out
1057 if(g_slist_length(list_out) > 0)
1058 lpos = g_slist_append(lpos, g_slist_nth_data(list_out, 0));
1059 for(iter=g_slist_nth(list_out,1);iter!=NULL;iter=g_slist_next(iter)) {
1060 /* Find all position requests with the lowest position in list_out */
1061 EventsRequest *event_request_lpos = (EventsRequest*)g_slist_nth_data(lpos, 0);
1062 EventsRequest *event_request_list_out = (EventsRequest*)iter->data;
1065 if(event_request_lpos->start_position != NULL
1066 && event_request_list_out->start_position != NULL)
1068 comp = lttv_traceset_context_pos_pos_compare
1069 (event_request_lpos->start_position,
1070 event_request_list_out->start_position);
1075 lpos = g_slist_append(lpos, event_request_list_out);
1077 /* Remove all elements from lpos, and add current */
1079 lpos = g_slist_delete_link(lpos, g_slist_nth(lpos, 0));
1080 lpos = g_slist_append(lpos, event_request_list_out);
1085 EventsRequest *event_request_lpos = (EventsRequest*)g_slist_nth_data(lpos, 0);
1086 EventsRequest *event_request_ltime = (EventsRequest*)g_slist_nth_data(ltime, 0);
1087 LttTime lpos_start_time;
1089 if(event_request_lpos != NULL
1090 && event_request_lpos->start_position != NULL) {
1091 lpos_start_time = lttv_traceset_context_position_get_time(
1092 event_request_lpos->start_position);
1095 /* 1.1.3 If lpos.start time < ltime */
1096 if(event_request_lpos != NULL
1097 && event_request_lpos->start_position != NULL
1098 && ltt_time_compare(lpos_start_time,
1099 event_request_ltime->start_time)<0) {
1100 /* Add lpos to list_in, remove them from list_out */
1101 for(iter=lpos;iter!=NULL;iter=g_slist_next(iter)) {
1102 /* Add to list_in */
1103 EventsRequest *event_request_lpos =
1104 (EventsRequest*)iter->data;
1106 list_in = g_slist_append(list_in, event_request_lpos);
1107 /* Remove from list_out */
1108 list_out = g_slist_remove(list_out, event_request_lpos);
1111 /* 1.1.4 (lpos.start time >= ltime) */
1112 /* Add ltime to list_in, remove them from list_out */
1114 for(iter=ltime;iter!=NULL;iter=g_slist_next(iter)) {
1115 /* Add to list_in */
1116 EventsRequest *event_request_ltime =
1117 (EventsRequest*)iter->data;
1119 list_in = g_slist_append(list_in, event_request_ltime);
1120 /* Remove from list_out */
1121 list_out = g_slist_remove(list_out, event_request_ltime);
1126 g_slist_free(ltime);
1131 tfc = lttv_traceset_context_get_current_tfc(tsc);
1132 g_assert(g_slist_length(list_in)>0);
1133 EventsRequest *events_request = g_slist_nth_data(list_in, 0);
1136 /* 1.2.1 If first request in list_in is a time request */
1137 if(events_request->start_position == NULL) {
1138 /* - If first req in list_in start time != current time */
1139 if(tfc == NULL || ltt_time_compare(events_request->start_time,
1140 tfc->timestamp) != 0)
1141 /* - Seek to that time */
1142 g_debug("SEEK TIME : %lu, %lu", events_request->start_time.tv_sec,
1143 events_request->start_time.tv_nsec);
1144 //lttv_process_traceset_seek_time(tsc, events_request->start_time);
1145 lttv_state_traceset_seek_time_closest(LTTV_TRACESET_STATE(tsc),
1146 events_request->start_time);
1148 /* Process the traceset with only state hooks */
1150 lttv_process_traceset_middle(tsc,
1151 events_request->start_time,
1154 g_assert(seek_count < LTTV_STATE_SAVE_INTERVAL);
1160 LttvTracefileContext *tfc =
1161 lttv_traceset_context_get_current_tfc(tsc);
1162 /* Else, the first request in list_in is a position request */
1163 /* If first req in list_in pos != current pos */
1164 g_assert(events_request->start_position != NULL);
1165 g_debug("SEEK POS time : %lu, %lu",
1166 lttv_traceset_context_position_get_time(
1167 events_request->start_position).tv_sec,
1168 lttv_traceset_context_position_get_time(
1169 events_request->start_position).tv_nsec);
1172 g_debug("SEEK POS context time : %lu, %lu",
1173 tfc->timestamp.tv_sec,
1174 tfc->timestamp.tv_nsec);
1176 g_debug("SEEK POS context time : %lu, %lu",
1177 ltt_time_infinite.tv_sec,
1178 ltt_time_infinite.tv_nsec);
1180 g_assert(events_request->start_position != NULL);
1181 if(lttv_traceset_context_ctx_pos_compare(tsc,
1182 events_request->start_position) != 0) {
1183 /* 1.2.2.1 Seek to that position */
1184 g_debug("SEEK POSITION");
1185 //lttv_process_traceset_seek_position(tsc, events_request->start_position);
1186 pos_time = lttv_traceset_context_position_get_time(
1187 events_request->start_position);
1189 lttv_state_traceset_seek_time_closest(LTTV_TRACESET_STATE(tsc),
1192 /* Process the traceset with only state hooks */
1194 lttv_process_traceset_middle(tsc,
1197 events_request->start_position);
1198 g_assert(lttv_traceset_context_ctx_pos_compare(tsc,
1199 events_request->start_position) == 0);
1206 /* 1.3 Add hooks and call before request for all list_in members */
1208 GSList *iter = NULL;
1210 for(iter=list_in;iter!=NULL;iter=g_slist_next(iter)) {
1211 EventsRequest *events_request = (EventsRequest*)iter->data;
1212 /* 1.3.1 If !servicing */
1213 if(events_request->servicing == FALSE) {
1214 /* - begin request hooks called
1215 * - servicing = TRUE
1217 lttv_hooks_call(events_request->before_request, (gpointer)tsc);
1218 events_request->servicing = TRUE;
1220 /* 1.3.2 call before chunk
1221 * 1.3.3 events hooks added
1223 if(events_request->trace == -1)
1224 lttv_process_traceset_begin(tsc,
1225 events_request->before_chunk_traceset,
1226 events_request->before_chunk_trace,
1227 events_request->before_chunk_tracefile,
1228 events_request->event,
1229 events_request->event_by_id);
1231 guint nb_trace = lttv_traceset_number(tsc->ts);
1232 g_assert((guint)events_request->trace < nb_trace &&
1233 events_request->trace > -1);
1234 LttvTraceContext *tc = tsc->traces[events_request->trace];
1236 lttv_hooks_call(events_request->before_chunk_traceset, tsc);
1238 lttv_trace_context_add_hooks(tc,
1239 events_request->before_chunk_trace,
1240 events_request->before_chunk_tracefile,
1241 events_request->event,
1242 events_request->event_by_id);
1247 /* 2. Else, list_in is not empty, we continue a read */
1250 /* 2.0 For each req of list_in */
1251 GSList *iter = list_in;
1253 while(iter != NULL) {
1255 EventsRequest *events_request = (EventsRequest *)iter->data;
1257 /* - Call before chunk
1258 * - events hooks added
1260 if(events_request->trace == -1)
1261 lttv_process_traceset_begin(tsc,
1262 events_request->before_chunk_traceset,
1263 events_request->before_chunk_trace,
1264 events_request->before_chunk_tracefile,
1265 events_request->event,
1266 events_request->event_by_id);
1268 guint nb_trace = lttv_traceset_number(tsc->ts);
1269 g_assert((guint)events_request->trace < nb_trace &&
1270 events_request->trace > -1);
1271 LttvTraceContext *tc = tsc->traces[events_request->trace];
1273 lttv_hooks_call(events_request->before_chunk_traceset, tsc);
1275 lttv_trace_context_add_hooks(tc,
1276 events_request->before_chunk_trace,
1277 events_request->before_chunk_tracefile,
1278 events_request->event,
1279 events_request->event_by_id);
1282 iter = g_slist_next(iter);
1287 tfc = lttv_traceset_context_get_current_tfc(tsc);
1289 /* 2.1 For each req of list_out */
1290 GSList *iter = list_out;
1292 while(iter != NULL) {
1294 gboolean remove = FALSE;
1295 gboolean free_data = FALSE;
1296 EventsRequest *events_request = (EventsRequest *)iter->data;
1298 /* if req.start time == current context time
1299 * or req.start position == current position*/
1300 if( ltt_time_compare(events_request->start_time,
1301 tfc->timestamp) == 0
1303 (events_request->start_position != NULL
1305 lttv_traceset_context_ctx_pos_compare(tsc,
1306 events_request->start_position) == 0)
1308 /* - Add to list_in, remove from list_out */
1309 list_in = g_slist_append(list_in, events_request);
1313 /* - If !servicing */
1314 if(events_request->servicing == FALSE) {
1315 /* - begin request hooks called
1316 * - servicing = TRUE
1318 lttv_hooks_call(events_request->before_request, (gpointer)tsc);
1319 events_request->servicing = TRUE;
1321 /* call before chunk
1322 * events hooks added
1324 if(events_request->trace == -1)
1325 lttv_process_traceset_begin(tsc,
1326 events_request->before_chunk_traceset,
1327 events_request->before_chunk_trace,
1328 events_request->before_chunk_tracefile,
1329 events_request->event,
1330 events_request->event_by_id);
1332 guint nb_trace = lttv_traceset_number(tsc->ts);
1333 g_assert((guint)events_request->trace < nb_trace &&
1334 events_request->trace > -1);
1335 LttvTraceContext *tc = tsc->traces[events_request->trace];
1337 lttv_hooks_call(events_request->before_chunk_traceset, tsc);
1339 lttv_trace_context_add_hooks(tc,
1340 events_request->before_chunk_trace,
1341 events_request->before_chunk_tracefile,
1342 events_request->event,
1343 events_request->event_by_id);
1352 GSList *remove_iter = iter;
1354 iter = g_slist_next(iter);
1355 if(free_data) events_request_free((EventsRequest*)remove_iter->data);
1356 list_out = g_slist_remove_link(list_out, remove_iter);
1357 } else { // not remove
1358 iter = g_slist_next(iter);
1364 /* 3. Find end criterions */
1369 /* 3.1.1 Find lowest end time in list_in */
1370 g_assert(g_slist_length(list_in)>0);
1371 end_time = ((EventsRequest*)g_slist_nth_data(list_in,0))->end_time;
1373 for(iter=g_slist_nth(list_in,1);iter!=NULL;iter=g_slist_next(iter)) {
1374 EventsRequest *events_request = (EventsRequest*)iter->data;
1376 if(ltt_time_compare(events_request->end_time,
1378 end_time = events_request->end_time;
1381 /* 3.1.2 Find lowest start time in list_out */
1382 for(iter=list_out;iter!=NULL;iter=g_slist_next(iter)) {
1383 EventsRequest *events_request = (EventsRequest*)iter->data;
1385 if(ltt_time_compare(events_request->start_time,
1387 end_time = events_request->start_time;
1392 /* 3.2 Number of events */
1394 /* 3.2.1 Find lowest number of events in list_in */
1397 end_nb_events = ((EventsRequest*)g_slist_nth_data(list_in,0))->num_events;
1399 for(iter=g_slist_nth(list_in,1);iter!=NULL;iter=g_slist_next(iter)) {
1400 EventsRequest *events_request = (EventsRequest*)iter->data;
1402 if(events_request->num_events < end_nb_events)
1403 end_nb_events = events_request->num_events;
1406 /* 3.2.2 Use min(CHUNK_NUM_EVENTS, min num events in list_in) as
1409 end_nb_events = MIN(CHUNK_NUM_EVENTS, end_nb_events);
1413 /* 3.3 End position */
1415 /* 3.3.1 Find lowest end position in list_in */
1418 end_position =((EventsRequest*)g_slist_nth_data(list_in,0))->end_position;
1420 for(iter=g_slist_nth(list_in,1);iter!=NULL;iter=g_slist_next(iter)) {
1421 EventsRequest *events_request = (EventsRequest*)iter->data;
1423 if(events_request->end_position != NULL && end_position != NULL &&
1424 lttv_traceset_context_pos_pos_compare(events_request->end_position,
1426 end_position = events_request->end_position;
1431 /* 3.3.2 Find lowest start position in list_out */
1434 for(iter=list_out;iter!=NULL;iter=g_slist_next(iter)) {
1435 EventsRequest *events_request = (EventsRequest*)iter->data;
1437 if(events_request->end_position != NULL && end_position != NULL &&
1438 lttv_traceset_context_pos_pos_compare(events_request->end_position,
1440 end_position = events_request->end_position;
1445 /* 4. Call process traceset middle */
1446 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);
1447 count = lttv_process_traceset_middle(tsc, end_time, end_nb_events, end_position);
1449 tfc = lttv_traceset_context_get_current_tfc(tsc);
1451 g_debug("Context time after middle : %lu, %lu", tfc->timestamp.tv_sec,
1452 tfc->timestamp.tv_nsec);
1454 g_debug("End of trace reached after middle.");
1458 /* 5. After process traceset middle */
1459 tfc = lttv_traceset_context_get_current_tfc(tsc);
1461 /* - if current context time > traceset.end time */
1462 if(tfc == NULL || ltt_time_compare(tfc->timestamp,
1463 tsc->time_span.end_time) > 0) {
1464 /* - For each req in list_in */
1465 GSList *iter = list_in;
1467 while(iter != NULL) {
1469 gboolean remove = FALSE;
1470 gboolean free_data = FALSE;
1471 EventsRequest *events_request = (EventsRequest *)iter->data;
1473 /* - Remove events hooks for req
1474 * - Call end chunk for req
1477 if(events_request->trace == -1)
1478 lttv_process_traceset_end(tsc,
1479 events_request->after_chunk_traceset,
1480 events_request->after_chunk_trace,
1481 events_request->after_chunk_tracefile,
1482 events_request->event,
1483 events_request->event_by_id);
1486 guint nb_trace = lttv_traceset_number(tsc->ts);
1487 g_assert(events_request->trace < nb_trace &&
1488 events_request->trace > -1);
1489 LttvTraceContext *tc = tsc->traces[events_request->trace];
1491 lttv_trace_context_remove_hooks(tc,
1492 events_request->after_chunk_trace,
1493 events_request->after_chunk_tracefile,
1494 events_request->event,
1495 events_request->event_by_id);
1496 lttv_hooks_call(events_request->after_chunk_traceset, tsc);
1501 /* - Call end request for req */
1502 lttv_hooks_call(events_request->after_request, (gpointer)tsc);
1504 /* - remove req from list_in */
1505 /* Destroy the request */
1512 GSList *remove_iter = iter;
1514 iter = g_slist_next(iter);
1515 if(free_data) events_request_free((EventsRequest*)remove_iter->data);
1516 list_in = g_slist_remove_link(list_in, remove_iter);
1517 } else { // not remove
1518 iter = g_slist_next(iter);
1523 /* 5.1 For each req in list_in */
1524 GSList *iter = list_in;
1526 while(iter != NULL) {
1528 gboolean remove = FALSE;
1529 gboolean free_data = FALSE;
1530 EventsRequest *events_request = (EventsRequest *)iter->data;
1532 /* - Remove events hooks for req
1533 * - Call end chunk for req
1535 if(events_request->trace == -1)
1536 lttv_process_traceset_end(tsc,
1537 events_request->after_chunk_traceset,
1538 events_request->after_chunk_trace,
1539 events_request->after_chunk_tracefile,
1540 events_request->event,
1541 events_request->event_by_id);
1544 guint nb_trace = lttv_traceset_number(tsc->ts);
1545 g_assert(events_request->trace < nb_trace &&
1546 events_request->trace > -1);
1547 LttvTraceContext *tc = tsc->traces[events_request->trace];
1549 lttv_trace_context_remove_hooks(tc,
1550 events_request->after_chunk_trace,
1551 events_request->after_chunk_tracefile,
1552 events_request->event,
1553 events_request->event_by_id);
1555 lttv_hooks_call(events_request->after_chunk_traceset, tsc);
1558 /* - req.num -= count */
1559 g_assert(events_request->num_events >= count);
1560 events_request->num_events -= count;
1562 g_assert(tfc != NULL);
1563 /* - if req.num == 0
1565 * current context time >= req.end time
1567 * req.end pos == current pos
1569 * req.stop_flag == TRUE
1571 if( events_request->num_events == 0
1573 events_request->stop_flag == TRUE
1575 ltt_time_compare(tfc->timestamp,
1576 events_request->end_time) >= 0
1578 (events_request->end_position != NULL
1580 lttv_traceset_context_ctx_pos_compare(tsc,
1581 events_request->end_position) == 0)
1584 g_assert(events_request->servicing == TRUE);
1585 /* - Call end request for req
1586 * - remove req from list_in */
1587 lttv_hooks_call(events_request->after_request, (gpointer)tsc);
1588 /* - remove req from list_in */
1589 /* Destroy the request */
1597 GSList *remove_iter = iter;
1599 iter = g_slist_next(iter);
1600 if(free_data) events_request_free((EventsRequest*)remove_iter->data);
1601 list_in = g_slist_remove_link(list_in, remove_iter);
1602 } else { // not remove
1603 iter = g_slist_next(iter);
1609 /* End of removed servicing loop : leave control to GTK instead. */
1610 // if(gtk_events_pending()) break;
1613 /* B. When interrupted between chunks */
1616 GSList *iter = list_in;
1618 /* 1. for each request in list_in */
1619 while(iter != NULL) {
1621 gboolean remove = FALSE;
1622 gboolean free_data = FALSE;
1623 EventsRequest *events_request = (EventsRequest *)iter->data;
1625 /* 1.1. Use current postition as start position */
1626 if(events_request->start_position != NULL)
1627 lttv_traceset_context_position_destroy(events_request->start_position);
1628 events_request->start_position = lttv_traceset_context_position_new(tsc);
1629 lttv_traceset_context_position_save(tsc, events_request->start_position);
1631 /* 1.2. Remove start time */
1632 events_request->start_time = ltt_time_infinite;
1634 /* 1.3. Move from list_in to list_out */
1637 list_out = g_slist_append(list_out, events_request);
1642 GSList *remove_iter = iter;
1644 iter = g_slist_next(iter);
1645 if(free_data) events_request_free((EventsRequest*)remove_iter->data);
1646 list_in = g_slist_remove_link(list_in, remove_iter);
1647 } else { // not remove
1648 iter = g_slist_next(iter);
1654 /* C Unlock Traces */
1656 lttv_process_traceset_get_sync_data(tsc);
1657 //lttv_traceset_context_position_save(tsc, sync_position);
1662 iter_trace<lttv_traceset_number(tsc->ts);
1664 LttvTrace *trace_v = lttv_traceset_get(tsc->ts, iter_trace);
1666 lttvwindowtraces_unlock(trace_v);
1670 //set the cursor back to normal
1671 gdk_window_set_cursor(win, NULL);
1674 g_assert(g_slist_length(list_in) == 0);
1676 if( g_slist_length(list_out) == 0 ) {
1677 /* Put tab's request pending flag back to normal */
1678 tab->events_request_pending = FALSE;
1679 g_debug("remove the idle fct");
1680 return FALSE; /* Remove the idle function */
1682 g_debug("leave the idle fct");
1683 return TRUE; /* Leave the idle function */
1685 /* We do not use simili-round-robin, it may require to read 1 meg buffers
1686 * again and again if many tracesets use the same tracefiles. */
1687 /* Hack for round-robin idle functions */
1688 /* It will put the idle function at the end of the pool */
1689 /*g_idle_add_full((G_PRIORITY_HIGH_IDLE + 21),
1690 (GSourceFunc)execute_events_requests,
1700 static void lttvwindow_add_trace(Tab *tab, LttvTrace *trace_v)
1702 LttvTraceset *traceset = tab->traceset_info->traceset;
1704 guint num_traces = lttv_traceset_number(traceset);
1706 //Verify if trace is already present.
1707 for(i=0; i<num_traces; i++)
1709 LttvTrace * trace = lttv_traceset_get(traceset, i);
1710 if(trace == trace_v)
1714 //Keep a reference to the traces so they are not freed.
1715 for(i=0; i<lttv_traceset_number(traceset); i++)
1717 LttvTrace * trace = lttv_traceset_get(traceset, i);
1718 lttv_trace_ref(trace);
1721 //remove state update hooks
1722 lttv_state_remove_event_hooks(
1723 (LttvTracesetState*)tab->traceset_info->traceset_context);
1725 lttv_context_fini(LTTV_TRACESET_CONTEXT(
1726 tab->traceset_info->traceset_context));
1727 g_object_unref(tab->traceset_info->traceset_context);
1729 lttv_traceset_add(traceset, trace_v);
1730 lttv_trace_ref(trace_v); /* local ref */
1732 /* Create new context */
1733 tab->traceset_info->traceset_context =
1734 g_object_new(LTTV_TRACESET_STATS_TYPE, NULL);
1736 LTTV_TRACESET_CONTEXT(tab->traceset_info->
1741 //add state update hooks
1742 lttv_state_add_event_hooks(
1743 (LttvTracesetState*)tab->traceset_info->traceset_context);
1744 //Remove local reference to the traces.
1745 for(i=0; i<lttv_traceset_number(traceset); i++)
1747 LttvTrace * trace = lttv_traceset_get(traceset, i);
1748 lttv_trace_unref(trace);
1752 //add_trace_into_traceset_selector(GTK_MULTIVPANED(tab->multivpaned), lttv_trace(trace_v));
1755 /* add_trace adds a trace into the current traceset. It first displays a
1756 * directory selection dialogue to let user choose a trace, then recreates
1757 * tracset_context, and redraws all the viewer of the current tab
1760 void add_trace(GtkWidget * widget, gpointer user_data)
1763 LttvTrace * trace_v;
1764 LttvTraceset * traceset;
1766 char abs_path[PATH_MAX];
1768 MainWindow * mw_data = get_window_data_struct(widget);
1769 GtkWidget * notebook = lookup_widget(widget, "MNotebook");
1771 GtkWidget *page = gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook),
1772 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook)));
1773 LttvPluginTab *ptab;
1777 ptab = create_new_tab(widget, NULL);
1780 ptab = (LttvPluginTab *)g_object_get_data(G_OBJECT(page), "Tab_Plugin");
1784 //GtkDirSelection * file_selector = (GtkDirSelection *)gtk_dir_selection_new("Select a trace");
1785 GtkFileSelection * file_selector = (GtkFileSelection *)gtk_file_selection_new("Select a trace");
1786 gtk_widget_hide( (file_selector)->file_list->parent) ;
1787 gtk_file_selection_hide_fileop_buttons(file_selector);
1788 gtk_window_set_transient_for(GTK_WINDOW(file_selector),
1789 GTK_WINDOW(mw_data->mwindow));
1791 if(remember_trace_dir[0] != '\0')
1792 gtk_file_selection_set_filename(file_selector, remember_trace_dir);
1794 id = gtk_dialog_run(GTK_DIALOG(file_selector));
1796 case GTK_RESPONSE_ACCEPT:
1797 case GTK_RESPONSE_OK:
1798 dir = gtk_file_selection_get_filename (file_selector);
1799 strncpy(remember_trace_dir, dir, PATH_MAX);
1800 strncat(remember_trace_dir, "/", PATH_MAX);
1801 if(!dir || strlen(dir) == 0){
1802 gtk_widget_destroy((GtkWidget*)file_selector);
1805 get_absolute_pathname(dir, abs_path);
1806 trace_v = lttvwindowtraces_get_trace_by_name(abs_path);
1807 if(trace_v == NULL) {
1808 trace = ltt_trace_open(abs_path);
1810 g_warning("cannot open trace %s", abs_path);
1812 GtkWidget *dialogue =
1813 gtk_message_dialog_new(
1814 GTK_WINDOW(gtk_widget_get_toplevel(widget)),
1815 GTK_DIALOG_MODAL|GTK_DIALOG_DESTROY_WITH_PARENT,
1818 "Cannot open trace : maybe you should enter in the trace "
1819 "directory to select it ?");
1820 gtk_dialog_run(GTK_DIALOG(dialogue));
1821 gtk_widget_destroy(dialogue);
1824 trace_v = lttv_trace_new(trace);
1825 lttvwindowtraces_add_trace(trace_v);
1826 lttvwindow_add_trace(tab, trace_v);
1829 lttvwindow_add_trace(tab, trace_v);
1832 gtk_widget_destroy((GtkWidget*)file_selector);
1834 //update current tab
1835 //update_traceset(mw_data);
1837 /* Call the updatetraceset hooks */
1839 traceset = tab->traceset_info->traceset;
1840 SetTraceset(tab, traceset);
1841 // in expose now call_pending_read_hooks(mw_data);
1843 //lttvwindow_report_current_time(mw_data,&(tab->current_time));
1845 case GTK_RESPONSE_REJECT:
1846 case GTK_RESPONSE_CANCEL:
1848 gtk_widget_destroy((GtkWidget*)file_selector);
1853 /* remove_trace removes a trace from the current traceset if all viewers in
1854 * the current tab are not interested in the trace. It first displays a
1855 * dialogue, which shows all traces in the current traceset, to let user choose
1856 * a trace, then it checks if all viewers unselect the trace, if it is true,
1857 * it will remove the trace, recreate the traceset_contex,
1858 * and redraws all the viewer of the current tab. If there is on trace in the
1859 * current traceset, it will delete all viewers of the current tab
1861 * It destroys the filter tree. FIXME... we should request for an update
1865 void remove_trace(GtkWidget *widget, gpointer user_data)
1868 LttvTrace * trace_v;
1869 LttvTraceset * traceset;
1870 gint i, j, nb_trace, index=-1;
1871 char ** name, *remove_trace_name;
1872 MainWindow * mw_data = get_window_data_struct(widget);
1873 GtkWidget * notebook = lookup_widget(widget, "MNotebook");
1875 GtkWidget *page = gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook),
1876 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook)));
1882 LttvPluginTab *ptab;
1883 ptab = (LttvPluginTab *)g_object_get_data(G_OBJECT(page), "Tab_Plugin");
1887 nb_trace =lttv_traceset_number(tab->traceset_info->traceset);
1888 name = g_new(char*,nb_trace);
1889 for(i = 0; i < nb_trace; i++){
1890 trace_v = lttv_traceset_get(tab->traceset_info->traceset, i);
1891 trace = lttv_trace(trace_v);
1892 name[i] = g_quark_to_string(ltt_trace_name(trace));
1895 remove_trace_name = get_remove_trace(mw_data, name, nb_trace);
1898 if(remove_trace_name){
1900 /* yuk, cut n paste from old code.. should be better (MD)*/
1901 for(i = 0; i<nb_trace; i++) {
1902 if(strcmp(remove_trace_name,name[i]) == 0){
1907 traceset = tab->traceset_info->traceset;
1908 //Keep a reference to the traces so they are not freed.
1909 for(j=0; j<lttv_traceset_number(traceset); j++)
1911 LttvTrace * trace = lttv_traceset_get(traceset, j);
1912 lttv_trace_ref(trace);
1915 //remove state update hooks
1916 lttv_state_remove_event_hooks(
1917 (LttvTracesetState*)tab->traceset_info->traceset_context);
1918 lttv_context_fini(LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context));
1919 g_object_unref(tab->traceset_info->traceset_context);
1921 trace_v = lttv_traceset_get(traceset, index);
1923 lttv_traceset_remove(traceset, index);
1924 lttv_trace_unref(trace_v); // Remove local reference
1926 if(lttv_trace_get_ref_number(trace_v) <= 1) {
1927 /* ref 1 : lttvwindowtraces only*/
1928 ltt_trace_close(lttv_trace(trace_v));
1929 /* lttvwindowtraces_remove_trace takes care of destroying
1930 * the traceset linked with the trace_v and also of destroying
1931 * the trace_v at the same time.
1933 lttvwindowtraces_remove_trace(trace_v);
1936 tab->traceset_info->traceset_context =
1937 g_object_new(LTTV_TRACESET_STATS_TYPE, NULL);
1939 LTTV_TRACESET_CONTEXT(tab->
1940 traceset_info->traceset_context),traceset);
1941 //add state update hooks
1942 lttv_state_add_event_hooks(
1943 (LttvTracesetState*)tab->traceset_info->traceset_context);
1945 //Remove local reference to the traces.
1946 for(j=0; j<lttv_traceset_number(traceset); j++)
1948 LttvTrace * trace = lttv_traceset_get(traceset, j);
1949 lttv_trace_unref(trace);
1952 SetTraceset(tab, (gpointer)traceset);
1958 void remove_trace(GtkWidget * widget, gpointer user_data)
1961 LttvTrace * trace_v;
1962 LttvTraceset * traceset;
1963 gint i, j, nb_trace;
1964 char ** name, *remove_trace_name;
1965 MainWindow * mw_data = get_window_data_struct(widget);
1966 LttvTracesetSelector * s;
1967 LttvTraceSelector * t;
1970 GtkWidget * notebook = lookup_widget(widget, "MNotebook");
1972 GtkWidget *page = gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook),
1973 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook)));
1979 tab = (Tab *)g_object_get_data(G_OBJECT(page), "Tab_Info");
1982 nb_trace =lttv_traceset_number(tab->traceset_info->traceset);
1983 name = g_new(char*,nb_trace);
1984 for(i = 0; i < nb_trace; i++){
1985 trace_v = lttv_traceset_get(tab->traceset_info->traceset, i);
1986 trace = lttv_trace(trace_v);
1987 name[i] = ltt_trace_name(trace);
1990 remove_trace_name = get_remove_trace(name, nb_trace);
1992 if(remove_trace_name){
1993 for(i=0; i<nb_trace; i++){
1994 if(strcmp(remove_trace_name,name[i]) == 0){
1995 //unselect the trace from the current viewer
1997 w = gtk_multivpaned_get_widget(GTK_MULTIVPANED(tab->multivpaned));
1999 s = g_object_get_data(G_OBJECT(w), "Traceset_Selector");
2001 t = lttv_traceset_selector_trace_get(s,i);
2002 lttv_trace_selector_set_selected(t, FALSE);
2005 //check if other viewers select the trace
2006 w = gtk_multivpaned_get_first_widget(GTK_MULTIVPANED(tab->multivpaned));
2008 s = g_object_get_data(G_OBJECT(w), "Traceset_Selector");
2010 t = lttv_traceset_selector_trace_get(s,i);
2011 selected = lttv_trace_selector_get_selected(t);
2014 w = gtk_multivpaned_get_next_widget(GTK_MULTIVPANED(tab->multivpaned));
2016 }else selected = FALSE;
2018 //if no viewer selects the trace, remove it
2020 remove_trace_from_traceset_selector(GTK_MULTIVPANED(tab->multivpaned), i);
2022 traceset = tab->traceset_info->traceset;
2023 //Keep a reference to the traces so they are not freed.
2024 for(j=0; j<lttv_traceset_number(traceset); j++)
2026 LttvTrace * trace = lttv_traceset_get(traceset, j);
2027 lttv_trace_ref(trace);
2030 //remove state update hooks
2031 lttv_state_remove_event_hooks(
2032 (LttvTracesetState*)tab->traceset_info->traceset_context);
2033 lttv_context_fini(LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context));
2034 g_object_unref(tab->traceset_info->traceset_context);
2037 trace_v = lttv_traceset_get(traceset, i);
2039 if(lttv_trace_get_ref_number(trace_v) <= 2) {
2040 /* ref 2 : traceset, local */
2041 lttvwindowtraces_remove_trace(trace_v);
2042 ltt_trace_close(lttv_trace(trace_v));
2045 lttv_traceset_remove(traceset, i);
2046 lttv_trace_unref(trace_v); // Remove local reference
2048 if(!lttv_trace_get_ref_number(trace_v))
2049 lttv_trace_destroy(trace_v);
2051 tab->traceset_info->traceset_context =
2052 g_object_new(LTTV_TRACESET_STATS_TYPE, NULL);
2054 LTTV_TRACESET_CONTEXT(tab->
2055 traceset_info->traceset_context),traceset);
2056 //add state update hooks
2057 lttv_state_add_event_hooks(
2058 (LttvTracesetState*)tab->traceset_info->traceset_context);
2060 //Remove local reference to the traces.
2061 for(j=0; j<lttv_traceset_number(traceset); j++)
2063 LttvTrace * trace = lttv_traceset_get(traceset, j);
2064 lttv_trace_unref(trace);
2068 //update current tab
2069 //update_traceset(mw_data);
2072 SetTraceset(tab, (gpointer)traceset);
2073 // in expose now call_pending_read_hooks(mw_data);
2075 //lttvwindow_report_current_time(mw_data,&(tab->current_time));
2078 // while(tab->multi_vpaned->num_children){
2079 // gtk_multi_vpaned_widget_delete(tab->multi_vpaned);
2093 /* Redraw all the viewers in the current tab */
2094 void redraw(GtkWidget *widget, gpointer user_data)
2096 GtkWidget * notebook = lookup_widget(widget, "MNotebook");
2097 GtkWidget *page = gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook),
2098 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook)));
2103 LttvPluginTab *ptab;
2104 ptab = (LttvPluginTab *)g_object_get_data(G_OBJECT(page), "Tab_Plugin");
2109 LttvAttributeValue value;
2111 g_assert(lttv_iattribute_find_by_path(tab->attributes, "hooks/redraw", LTTV_POINTER, &value));
2113 tmp = (LttvHooks*)*(value.v_pointer);
2115 lttv_hooks_call(tmp,NULL);
2119 void continue_processing(GtkWidget *widget, gpointer user_data)
2121 GtkWidget * notebook = lookup_widget(widget, "MNotebook");
2122 GtkWidget *page = gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook),
2123 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook)));
2128 LttvPluginTab *ptab;
2129 ptab = (LttvPluginTab *)g_object_get_data(G_OBJECT(page), "Tab_Plugin");
2134 LttvAttributeValue value;
2136 g_assert(lttv_iattribute_find_by_path(tab->attributes,
2137 "hooks/continue", LTTV_POINTER, &value));
2139 tmp = (LttvHooks*)*(value.v_pointer);
2141 lttv_hooks_call(tmp,NULL);
2144 /* Stop the processing for the calling main window's current tab.
2145 * It removes every processing requests that are in its list. It does not call
2146 * the end request hooks, because the request is not finished.
2149 void stop_processing(GtkWidget *widget, gpointer user_data)
2151 GtkWidget * notebook = lookup_widget(widget, "MNotebook");
2152 GtkWidget *page = gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook),
2153 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook)));
2158 LttvPluginTab *ptab;
2159 ptab = (LttvPluginTab *)g_object_get_data(G_OBJECT(page), "Tab_Plugin");
2162 GSList *iter = tab->events_requests;
2164 while(iter != NULL) {
2165 GSList *remove_iter = iter;
2166 iter = g_slist_next(iter);
2168 g_free(remove_iter->data);
2169 tab->events_requests =
2170 g_slist_remove_link(tab->events_requests, remove_iter);
2172 tab->events_request_pending = FALSE;
2173 tab->stop_foreground = TRUE;
2174 g_idle_remove_by_data(tab);
2175 g_assert(g_slist_length(tab->events_requests) == 0);
2179 /* save will save the traceset to a file
2180 * Not implemented yet FIXME
2183 void save(GtkWidget * widget, gpointer user_data)
2188 void save_as(GtkWidget * widget, gpointer user_data)
2190 g_info("Save as\n");
2194 /* zoom will change the time_window of all the viewers of the
2195 * current tab, and redisplay them. The main functionality is to
2196 * determine the new time_window of the current tab
2199 void zoom(GtkWidget * widget, double size)
2201 TimeInterval time_span;
2202 TimeWindow new_time_window;
2203 LttTime current_time, time_delta;
2204 MainWindow * mw_data = get_window_data_struct(widget);
2205 LttvTracesetContext *tsc;
2206 GtkWidget * notebook = lookup_widget(widget, "MNotebook");
2208 GtkWidget *page = gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook),
2209 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook)));
2215 LttvPluginTab *ptab;
2216 ptab = (LttvPluginTab *)g_object_get_data(G_OBJECT(page), "Tab_Plugin");
2220 if(size == 1) return;
2222 tsc = LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context);
2223 time_span = tsc->time_span;
2224 new_time_window = tab->time_window;
2225 current_time = tab->current_time;
2227 time_delta = ltt_time_sub(time_span.end_time,time_span.start_time);
2229 new_time_window.start_time = time_span.start_time;
2230 new_time_window.time_width = time_delta;
2231 new_time_window.time_width_double = ltt_time_to_double(time_delta);
2232 new_time_window.end_time = ltt_time_add(new_time_window.start_time,
2233 new_time_window.time_width) ;
2235 new_time_window.time_width = ltt_time_div(new_time_window.time_width, size);
2236 new_time_window.time_width_double =
2237 ltt_time_to_double(new_time_window.time_width);
2238 if(ltt_time_compare(new_time_window.time_width,time_delta) > 0)
2239 { /* Case where zoom out is bigger than trace length */
2240 new_time_window.start_time = time_span.start_time;
2241 new_time_window.time_width = time_delta;
2242 new_time_window.time_width_double = ltt_time_to_double(time_delta);
2243 new_time_window.end_time = ltt_time_add(new_time_window.start_time,
2244 new_time_window.time_width) ;
2248 /* Center the image on the current time */
2249 new_time_window.start_time =
2250 ltt_time_sub(current_time,
2251 ltt_time_from_double(new_time_window.time_width_double/2.0));
2252 new_time_window.end_time = ltt_time_add(new_time_window.start_time,
2253 new_time_window.time_width) ;
2254 /* If on borders, don't fall off */
2255 if(ltt_time_compare(new_time_window.start_time, time_span.start_time) <0
2256 || ltt_time_compare(new_time_window.start_time, time_span.end_time) >0)
2258 new_time_window.start_time = time_span.start_time;
2259 new_time_window.end_time = ltt_time_add(new_time_window.start_time,
2260 new_time_window.time_width) ;
2264 if(ltt_time_compare(new_time_window.end_time,
2265 time_span.end_time) > 0
2266 || ltt_time_compare(new_time_window.end_time,
2267 time_span.start_time) < 0)
2269 new_time_window.start_time =
2270 ltt_time_sub(time_span.end_time, new_time_window.time_width);
2272 new_time_window.end_time = ltt_time_add(new_time_window.start_time,
2273 new_time_window.time_width) ;
2280 if(ltt_time_compare(new_time_window.time_width, ltt_time_zero) == 0) {
2281 g_warning("Zoom more than 1 ns impossible");
2283 time_change_manager(tab, new_time_window);
2287 void zoom_in(GtkWidget * widget, gpointer user_data)
2292 void zoom_out(GtkWidget * widget, gpointer user_data)
2297 void zoom_extended(GtkWidget * widget, gpointer user_data)
2302 void go_to_time(GtkWidget * widget, gpointer user_data)
2304 g_info("Go to time\n");
2307 void show_time_frame(GtkWidget * widget, gpointer user_data)
2309 g_info("Show time frame\n");
2313 /* callback function */
2316 on_empty_traceset_activate (GtkMenuItem *menuitem,
2319 create_new_window((GtkWidget*)menuitem, user_data, FALSE);
2324 on_clone_traceset_activate (GtkMenuItem *menuitem,
2327 create_new_window((GtkWidget*)menuitem, user_data, TRUE);
2331 /* create_new_tab calls create_tab to construct a new tab in the main window
2334 LttvPluginTab *create_new_tab(GtkWidget* widget, gpointer user_data)
2336 gchar label[PATH_MAX];
2337 MainWindow * mw_data = get_window_data_struct(widget);
2339 GtkNotebook * notebook = (GtkNotebook *)lookup_widget(widget, "MNotebook");
2340 if(notebook == NULL){
2341 g_info("Notebook does not exist\n");
2344 GtkWidget *page = gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook),
2345 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook)));
2351 LttvPluginTab *ptab;
2352 ptab = (LttvPluginTab *)g_object_get_data(G_OBJECT(page), "Tab_Plugin");
2353 copy_tab = ptab->tab;
2356 strcpy(label,"Page");
2357 if(get_label(mw_data, label,"Get the name of the tab","Please input tab's name")) {
2358 LttvPluginTab *ptab;
2360 ptab = g_object_new(LTTV_TYPE_PLUGIN_TAB, NULL);
2361 init_tab (ptab->tab, mw_data, copy_tab, notebook, label);
2362 ptab->parent.top_widget = ptab->tab->top_widget;
2363 g_object_set_data_full(
2364 G_OBJECT(ptab->tab->vbox),
2367 (GDestroyNotify)tab_destructor);
2374 on_tab_activate (GtkMenuItem *menuitem,
2377 create_new_tab((GtkWidget*)menuitem, user_data);
2382 on_open_activate (GtkMenuItem *menuitem,
2385 open_traceset((GtkWidget*)menuitem, user_data);
2390 on_close_activate (GtkMenuItem *menuitem,
2393 MainWindow * mw_data = get_window_data_struct((GtkWidget*)menuitem);
2394 main_window_destructor(mw_data);
2398 /* remove the current tab from the main window
2402 on_close_tab_activate (GtkWidget *widget,
2406 GtkWidget * notebook;
2408 MainWindow * mw_data = get_window_data_struct(widget);
2409 notebook = lookup_widget(widget, "MNotebook");
2410 if(notebook == NULL){
2411 g_info("Notebook does not exist\n");
2415 page_num = gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook));
2417 gtk_notebook_remove_page(GTK_NOTEBOOK(notebook), page_num);
2422 on_close_tab_X_clicked (GtkWidget *widget,
2426 GtkWidget *notebook = lookup_widget(widget, "MNotebook");
2427 if(notebook == NULL){
2428 g_info("Notebook does not exist\n");
2432 if((page_num = gtk_notebook_page_num(GTK_NOTEBOOK(notebook), widget)) != -1)
2433 gtk_notebook_remove_page(GTK_NOTEBOOK(notebook), page_num);
2439 on_add_trace_activate (GtkMenuItem *menuitem,
2442 add_trace((GtkWidget*)menuitem, user_data);
2447 on_remove_trace_activate (GtkMenuItem *menuitem,
2450 remove_trace((GtkWidget*)menuitem, user_data);
2455 on_save_activate (GtkMenuItem *menuitem,
2458 save((GtkWidget*)menuitem, user_data);
2463 on_save_as_activate (GtkMenuItem *menuitem,
2466 save_as((GtkWidget*)menuitem, user_data);
2471 on_quit_activate (GtkMenuItem *menuitem,
2479 on_cut_activate (GtkMenuItem *menuitem,
2487 on_copy_activate (GtkMenuItem *menuitem,
2495 on_paste_activate (GtkMenuItem *menuitem,
2503 on_delete_activate (GtkMenuItem *menuitem,
2511 on_zoom_in_activate (GtkMenuItem *menuitem,
2514 zoom_in((GtkWidget*)menuitem, user_data);
2519 on_zoom_out_activate (GtkMenuItem *menuitem,
2522 zoom_out((GtkWidget*)menuitem, user_data);
2527 on_zoom_extended_activate (GtkMenuItem *menuitem,
2530 zoom_extended((GtkWidget*)menuitem, user_data);
2535 on_go_to_time_activate (GtkMenuItem *menuitem,
2538 go_to_time((GtkWidget*)menuitem, user_data);
2543 on_show_time_frame_activate (GtkMenuItem *menuitem,
2546 show_time_frame((GtkWidget*)menuitem, user_data);
2551 on_move_viewer_up_activate (GtkMenuItem *menuitem,
2554 move_up_viewer((GtkWidget*)menuitem, user_data);
2559 on_move_viewer_down_activate (GtkMenuItem *menuitem,
2562 move_down_viewer((GtkWidget*)menuitem, user_data);
2567 on_remove_viewer_activate (GtkMenuItem *menuitem,
2570 delete_viewer((GtkWidget*)menuitem, user_data);
2574 on_trace_facility_activate (GtkMenuItem *menuitem,
2577 g_info("Trace facility selector: %s\n");
2581 /* Dispaly a file selection dialogue to let user select a library, then call
2582 * lttv_library_load().
2586 on_load_library_activate (GtkMenuItem *menuitem,
2589 GError *error = NULL;
2590 MainWindow * mw_data = get_window_data_struct((GtkWidget*)menuitem);
2592 gchar load_module_path_alter[PATH_MAX];
2596 gchar *load_module_path;
2597 name = g_ptr_array_new();
2598 nb = lttv_library_path_number();
2599 /* ask for the library path */
2603 path = lttv_library_path_get(i);
2604 g_ptr_array_add(name, path);
2607 load_module_path = get_selection(mw_data,
2608 (char **)(name->pdata), name->len,
2609 "Select a library path", "Library paths");
2610 if(load_module_path != NULL)
2611 strncpy(load_module_path_alter, load_module_path, PATH_MAX-1); // -1 for /
2613 g_ptr_array_free(name, TRUE);
2615 if(load_module_path == NULL) return;
2619 /* Make sure the module path ends with a / */
2620 gchar *ptr = load_module_path_alter;
2622 ptr = strchr(ptr, '\0');
2624 if(*(ptr-1) != '/') {
2631 /* Ask for the library to load : list files in the previously selected
2633 gchar str[PATH_MAX];
2636 GtkFileSelection * file_selector =
2637 (GtkFileSelection *)gtk_file_selection_new("Select a module");
2638 gtk_file_selection_set_filename(file_selector, load_module_path_alter);
2639 gtk_file_selection_hide_fileop_buttons(file_selector);
2641 gtk_window_set_transient_for(GTK_WINDOW(file_selector),
2642 GTK_WINDOW(mw_data->mwindow));
2645 id = gtk_dialog_run(GTK_DIALOG(file_selector));
2647 case GTK_RESPONSE_ACCEPT:
2648 case GTK_RESPONSE_OK:
2649 dir = gtk_file_selection_get_selections (file_selector);
2650 strncpy(str,dir[0],PATH_MAX);
2651 strncpy(remember_plugins_dir,dir[0],PATH_MAX);
2652 /* only keep file name */
2654 str1 = strrchr(str,'/');
2657 str1 = strrchr(str,'\\');
2662 if(*str1 == 'l' && *(str1+1)== 'i' && *(str1+2)=='b')
2664 remove info after . */
2668 str2 = strrchr(str2, '.');
2669 if(str2 != NULL) *str2 = '\0';
2671 lttv_module_require(str1, &error);
2673 lttv_library_load(str1, &error);
2674 if(error != NULL) g_warning("%s", error->message);
2675 else g_info("Load library: %s\n", str);
2677 case GTK_RESPONSE_REJECT:
2678 case GTK_RESPONSE_CANCEL:
2680 gtk_widget_destroy((GtkWidget*)file_selector);
2691 /* Display all loaded modules, let user to select a module to unload
2692 * by calling lttv_module_unload
2696 on_unload_library_activate (GtkMenuItem *menuitem,
2699 MainWindow * mw_data = get_window_data_struct((GtkWidget*)menuitem);
2701 LttvLibrary *library = NULL;
2706 name = g_ptr_array_new();
2707 nb = lttv_library_number();
2708 LttvLibraryInfo *lib_info = g_new(LttvLibraryInfo,nb);
2709 /* ask for the library name */
2712 LttvLibrary *iter_lib = lttv_library_get(i);
2713 lttv_library_info(iter_lib, &lib_info[i]);
2715 gchar *path = lib_info[i].name;
2716 g_ptr_array_add(name, path);
2718 lib_name = get_selection(mw_data, (char **)(name->pdata), name->len,
2719 "Select a library", "Libraries");
2720 if(lib_name != NULL) {
2722 if(strcmp(lib_name, lib_info[i].name) == 0) {
2723 library = lttv_library_get(i);
2728 g_ptr_array_free(name, TRUE);
2731 if(lib_name == NULL) return;
2733 if(library != NULL) lttv_library_unload(library);
2737 /* Dispaly a file selection dialogue to let user select a module, then call
2738 * lttv_module_require().
2742 on_load_module_activate (GtkMenuItem *menuitem,
2745 GError *error = NULL;
2746 MainWindow * mw_data = get_window_data_struct((GtkWidget*)menuitem);
2748 LttvLibrary *library = NULL;
2753 name = g_ptr_array_new();
2754 nb = lttv_library_number();
2755 LttvLibraryInfo *lib_info = g_new(LttvLibraryInfo,nb);
2756 /* ask for the library name */
2759 LttvLibrary *iter_lib = lttv_library_get(i);
2760 lttv_library_info(iter_lib, &lib_info[i]);
2762 gchar *path = lib_info[i].name;
2763 g_ptr_array_add(name, path);
2765 lib_name = get_selection(mw_data,(char **)(name->pdata), name->len,
2766 "Select a library", "Libraries");
2767 if(lib_name != NULL) {
2769 if(strcmp(lib_name, lib_info[i].name) == 0) {
2770 library = lttv_library_get(i);
2775 g_ptr_array_free(name, TRUE);
2778 if(lib_name == NULL) return;
2781 //LttvModule *module;
2782 gchar module_name_out[PATH_MAX];
2784 /* Ask for the module to load : list modules in the selected lib */
2788 nb = lttv_library_module_number(library);
2789 LttvModuleInfo *module_info = g_new(LttvModuleInfo,nb);
2790 name = g_ptr_array_new();
2791 /* ask for the module name */
2794 LttvModule *iter_module = lttv_library_module_get(library, i);
2795 lttv_module_info(iter_module, &module_info[i]);
2797 gchar *path = module_info[i].name;
2798 g_ptr_array_add(name, path);
2800 module_name = get_selection(mw_data, (char **)(name->pdata), name->len,
2801 "Select a module", "Modules");
2802 if(module_name != NULL) {
2804 if(strcmp(module_name, module_info[i].name) == 0) {
2805 strncpy(module_name_out, module_name, PATH_MAX);
2806 //module = lttv_library_module_get(i);
2812 g_ptr_array_free(name, TRUE);
2813 g_free(module_info);
2815 if(module_name == NULL) return;
2818 lttv_module_require(module_name_out, &error);
2819 if(error != NULL) g_warning("%s", error->message);
2820 else g_info("Load module: %s", module_name_out);
2827 gchar str[PATH_MAX];
2830 GtkFileSelection * file_selector =
2831 (GtkFileSelection *)gtk_file_selection_new("Select a module");
2832 gtk_file_selection_set_filename(file_selector, load_module_path_alter);
2833 gtk_file_selection_hide_fileop_buttons(file_selector);
2836 id = gtk_dialog_run(GTK_DIALOG(file_selector));
2838 case GTK_RESPONSE_ACCEPT:
2839 case GTK_RESPONSE_OK:
2840 dir = gtk_file_selection_get_selections (file_selector);
2841 strncpy(str,dir[0],PATH_MAX);
2842 strncpy(remember_plugins_dir,dir[0],PATH_MAX);
2844 /* only keep file name */
2846 str1 = strrchr(str,'/');
2849 str1 = strrchr(str,'\\');
2854 if(*str1 == 'l' && *(str1+1)== 'i' && *(str1+2)=='b')
2856 remove info after . */
2860 str2 = strrchr(str2, '.');
2861 if(str2 != NULL) *str2 = '\0';
2863 lttv_module_require(str1, &error);
2865 lttv_library_load(str1, &error);
2866 if(error != NULL) g_warning(error->message);
2867 else g_info("Load library: %s\n", str);
2869 case GTK_RESPONSE_REJECT:
2870 case GTK_RESPONSE_CANCEL:
2872 gtk_widget_destroy((GtkWidget*)file_selector);
2884 /* Display all loaded modules, let user to select a module to unload
2885 * by calling lttv_module_unload
2889 on_unload_module_activate (GtkMenuItem *menuitem,
2892 GError *error = NULL;
2893 MainWindow * mw_data = get_window_data_struct((GtkWidget*)menuitem);
2895 LttvLibrary *library;
2900 name = g_ptr_array_new();
2901 nb = lttv_library_number();
2902 LttvLibraryInfo *lib_info = g_new(LttvLibraryInfo,nb);
2903 /* ask for the library name */
2906 LttvLibrary *iter_lib = lttv_library_get(i);
2907 lttv_library_info(iter_lib, &lib_info[i]);
2909 gchar *path = lib_info[i].name;
2910 g_ptr_array_add(name, path);
2912 lib_name = get_selection(mw_data, (char **)(name->pdata), name->len,
2913 "Select a library", "Libraries");
2914 if(lib_name != NULL) {
2916 if(strcmp(lib_name, lib_info[i].name) == 0) {
2917 library = lttv_library_get(i);
2922 g_ptr_array_free(name, TRUE);
2925 if(lib_name == NULL) return;
2928 LttvModule *module = NULL;
2930 /* Ask for the module to load : list modules in the selected lib */
2934 nb = lttv_library_module_number(library);
2935 LttvModuleInfo *module_info = g_new(LttvModuleInfo,nb);
2936 name = g_ptr_array_new();
2937 /* ask for the module name */
2940 LttvModule *iter_module = lttv_library_module_get(library, i);
2941 lttv_module_info(iter_module, &module_info[i]);
2943 gchar *path = module_info[i].name;
2944 if(module_info[i].use_count > 0) g_ptr_array_add(name, path);
2946 module_name = get_selection(mw_data, (char **)(name->pdata), name->len,
2947 "Select a module", "Modules");
2948 if(module_name != NULL) {
2950 if(strcmp(module_name, module_info[i].name) == 0) {
2951 module = lttv_library_module_get(library, i);
2957 g_ptr_array_free(name, TRUE);
2958 g_free(module_info);
2960 if(module_name == NULL) return;
2963 LttvModuleInfo module_info;
2964 lttv_module_info(module, &module_info);
2965 g_info("Release module: %s\n", module_info.name);
2967 lttv_module_release(module);
2971 /* Display a directory dialogue to let user select a path for library searching
2975 on_add_library_search_path_activate (GtkMenuItem *menuitem,
2978 MainWindow * mw_data = get_window_data_struct((GtkWidget*)menuitem);
2979 //GtkDirSelection * file_selector = (GtkDirSelection *)gtk_dir_selection_new("Select library path");
2980 GtkFileSelection * file_selector = (GtkFileSelection *)gtk_file_selection_new("Select a trace");
2981 gtk_widget_hide( (file_selector)->file_list->parent) ;
2983 gtk_window_set_transient_for(GTK_WINDOW(file_selector),
2984 GTK_WINDOW(mw_data->mwindow));
2989 if(remember_plugins_dir[0] != '\0')
2990 gtk_file_selection_set_filename(file_selector, remember_plugins_dir);
2992 id = gtk_dialog_run(GTK_DIALOG(file_selector));
2994 case GTK_RESPONSE_ACCEPT:
2995 case GTK_RESPONSE_OK:
2996 dir = gtk_file_selection_get_filename (file_selector);
2997 strncpy(remember_plugins_dir,dir,PATH_MAX);
2998 strncat(remember_plugins_dir,"/",PATH_MAX);
2999 lttv_library_path_add(dir);
3000 case GTK_RESPONSE_REJECT:
3001 case GTK_RESPONSE_CANCEL:
3003 gtk_widget_destroy((GtkWidget*)file_selector);
3009 /* Display a directory dialogue to let user select a path for library searching
3013 on_remove_library_search_path_activate (GtkMenuItem *menuitem,
3016 MainWindow * mw_data = get_window_data_struct((GtkWidget*)menuitem);
3018 const char *lib_path;
3023 name = g_ptr_array_new();
3024 nb = lttv_library_path_number();
3025 /* ask for the library name */
3028 gchar *path = lttv_library_path_get(i);
3029 g_ptr_array_add(name, path);
3031 lib_path = get_selection(mw_data, (char **)(name->pdata), name->len,
3032 "Select a library path", "Library paths");
3034 g_ptr_array_free(name, TRUE);
3036 if(lib_path == NULL) return;
3039 lttv_library_path_remove(lib_path);
3043 on_color_activate (GtkMenuItem *menuitem,
3051 on_save_configuration_activate (GtkMenuItem *menuitem,
3054 g_info("Save configuration\n");
3059 on_content_activate (GtkMenuItem *menuitem,
3062 g_info("Content\n");
3067 on_about_close_activate (GtkButton *button,
3070 GtkWidget *about_widget = GTK_WIDGET(user_data);
3072 gtk_widget_destroy(about_widget);
3076 on_about_activate (GtkMenuItem *menuitem,
3079 MainWindow *main_window = get_window_data_struct(GTK_WIDGET(menuitem));
3080 GtkWidget *window_widget = main_window->mwindow;
3081 GtkWidget *about_widget = gtk_window_new(GTK_WINDOW_TOPLEVEL);
3082 GtkWindow *about_window = GTK_WINDOW(about_widget);
3083 gint window_width, window_height;
3085 gtk_window_set_title(about_window, "About Linux Trace Toolkit");
3087 gtk_window_set_resizable(about_window, FALSE);
3088 gtk_window_set_transient_for(GTK_WINDOW(window_widget), about_window);
3089 gtk_window_set_destroy_with_parent(about_window, TRUE);
3090 gtk_window_set_modal(about_window, FALSE);
3092 /* Put the about window at the center of the screen */
3093 gtk_window_get_size(about_window, &window_width, &window_height);
3094 gtk_window_move (about_window,
3095 (gdk_screen_width() - window_width)/2,
3096 (gdk_screen_height() - window_height)/2);
3098 GtkWidget *vbox = gtk_vbox_new(FALSE, 1);
3100 gtk_container_add(GTK_CONTAINER(about_widget), vbox);
3104 GtkWidget *label1 = gtk_label_new("");
3105 gtk_misc_set_padding(GTK_MISC(label1), 10, 20);
3106 gtk_label_set_markup(GTK_LABEL(label1), "\
3107 <big>Linux Trace Toolkit</big>");
3108 gtk_label_set_justify(GTK_LABEL(label1), GTK_JUSTIFY_CENTER);
3110 GtkWidget *label2 = gtk_label_new("");
3111 gtk_misc_set_padding(GTK_MISC(label2), 10, 20);
3112 gtk_label_set_markup(GTK_LABEL(label2), "\
3115 Michel Dagenais (New trace format, lttv main)\n\
3116 Mathieu Desnoyers (Kernel Tracer, Directory structure, build with automake/conf,\n\
3117 lttv gui, control flow view, gui cooperative trace reading\n\
3118 scheduler with interruptible foreground and background\n\
3119 computation, detailed event list (rewrite), trace reading\n\
3120 library (rewrite))\n\
3121 Benoit Des Ligneris, Eric Clement (Cluster adaptation, work in progress)\n\
3122 Xang-Xiu Yang (new trace reading library and converter, lttv gui, \n\
3123 detailed event list and statistics view)\n\
3124 Tom Zanussi (RelayFS)\n\
3126 Strongly inspired from the original Linux Trace Toolkit Visualizer made by\n\
3129 GtkWidget *label3 = gtk_label_new("");
3130 gtk_label_set_markup(GTK_LABEL(label3), "\
3131 Linux Trace Toolkit Viewer, Copyright (C) 2004\n\
3133 Mathieu Desnoyers\n\
3135 Linux Trace Toolkit comes with ABSOLUTELY NO WARRANTY.\n\
3136 This is free software, and you are welcome to redistribute it\n\
3137 under certain conditions. See COPYING for details.");
3138 gtk_misc_set_padding(GTK_MISC(label3), 10, 20);
3140 gtk_box_pack_start_defaults(GTK_BOX(vbox), label1);
3141 gtk_box_pack_start_defaults(GTK_BOX(vbox), label2);
3142 gtk_box_pack_start_defaults(GTK_BOX(vbox), label3);
3144 GtkWidget *hbox = gtk_hbox_new(TRUE, 0);
3145 gtk_box_pack_end(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
3146 GtkWidget *close_button = gtk_button_new_with_mnemonic("_Close");
3147 gtk_box_pack_end(GTK_BOX(hbox), close_button, FALSE, FALSE, 0);
3148 gtk_container_set_border_width(GTK_CONTAINER(close_button), 20);
3150 g_signal_connect(G_OBJECT(close_button), "clicked",
3151 G_CALLBACK(on_about_close_activate),
3152 (gpointer)about_widget);
3154 gtk_widget_show_all(about_widget);
3159 on_button_new_clicked (GtkButton *button,
3162 create_new_window((GtkWidget*)button, user_data, TRUE);
3166 on_button_new_tab_clicked (GtkButton *button,
3169 create_new_tab((GtkWidget*)button, user_data);
3173 on_button_open_clicked (GtkButton *button,
3176 open_traceset((GtkWidget*)button, user_data);
3181 on_button_add_trace_clicked (GtkButton *button,
3184 add_trace((GtkWidget*)button, user_data);
3189 on_button_remove_trace_clicked (GtkButton *button,
3192 remove_trace((GtkWidget*)button, user_data);
3196 on_button_redraw_clicked (GtkButton *button,
3199 redraw((GtkWidget*)button, user_data);
3203 on_button_continue_processing_clicked (GtkButton *button,
3206 continue_processing((GtkWidget*)button, user_data);
3210 on_button_stop_processing_clicked (GtkButton *button,
3213 stop_processing((GtkWidget*)button, user_data);
3219 on_button_save_clicked (GtkButton *button,
3222 save((GtkWidget*)button, user_data);
3227 on_button_save_as_clicked (GtkButton *button,
3230 save_as((GtkWidget*)button, user_data);
3235 on_button_zoom_in_clicked (GtkButton *button,
3238 zoom_in((GtkWidget*)button, user_data);
3243 on_button_zoom_out_clicked (GtkButton *button,
3246 zoom_out((GtkWidget*)button, user_data);
3251 on_button_zoom_extended_clicked (GtkButton *button,
3254 zoom_extended((GtkWidget*)button, user_data);
3259 on_button_go_to_time_clicked (GtkButton *button,
3262 go_to_time((GtkWidget*)button, user_data);
3267 on_button_show_time_frame_clicked (GtkButton *button,
3270 show_time_frame((GtkWidget*)button, user_data);
3275 on_button_move_up_clicked (GtkButton *button,
3278 move_up_viewer((GtkWidget*)button, user_data);
3283 on_button_move_down_clicked (GtkButton *button,
3286 move_down_viewer((GtkWidget*)button, user_data);
3291 on_button_delete_viewer_clicked (GtkButton *button,
3294 delete_viewer((GtkWidget*)button, user_data);
3298 on_MWindow_destroy (GtkWidget *widget,
3301 MainWindow *main_window = get_window_data_struct(widget);
3302 LttvIAttribute *attributes = main_window->attributes;
3303 LttvAttributeValue value;
3305 //This is unnecessary, since widgets will be destroyed
3306 //by the main window widget anyway.
3307 //remove_all_menu_toolbar_constructors(main_window, NULL);
3309 g_assert(lttv_iattribute_find_by_path(attributes,
3310 "viewers/menu", LTTV_POINTER, &value));
3311 lttv_menus_destroy((LttvMenus*)*(value.v_pointer));
3313 g_assert(lttv_iattribute_find_by_path(attributes,
3314 "viewers/toolbar", LTTV_POINTER, &value));
3315 lttv_toolbars_destroy((LttvToolbars*)*(value.v_pointer));
3317 g_object_unref(main_window->attributes);
3318 g_main_window_list = g_slist_remove(g_main_window_list, main_window);
3320 g_info("There are now : %d windows\n",g_slist_length(g_main_window_list));
3321 if(g_slist_length(g_main_window_list) == 0)
3326 on_MWindow_configure (GtkWidget *widget,
3327 GdkEventConfigure *event,
3330 MainWindow * mw_data = get_window_data_struct((GtkWidget*)widget);
3332 // MD : removed time width modification upon resizing of the main window.
3333 // The viewers will redraw themselves completely, without time interval
3336 if(mw_data->window_width){
3337 time_span = LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context)->Time_Span ;
3338 time_win = tab->time_window;
3339 ratio = width / mw_data->window_width;
3340 tab->time_window.time_width = ltt_time_mul(time_win.time_width,ratio);
3341 time = ltt_time_sub(time_span->endTime, time_win.start_time);
3342 if(ltt_time_compare(time, tab->time_window.time_width) < 0){
3343 tab->time_window.time_width = time;
3349 mw_data->window_width = (int)width;
3358 on_MNotebook_switch_page (GtkNotebook *notebook,
3359 GtkNotebookPage *page,
3367 void time_change_manager (Tab *tab,
3368 TimeWindow new_time_window)
3370 /* Only one source of time change */
3371 if(tab->time_manager_lock == TRUE) return;
3373 tab->time_manager_lock = TRUE;
3375 LttvTracesetContext *tsc = LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context);
3376 TimeInterval time_span = tsc->time_span;
3377 LttTime start_time = new_time_window.start_time;
3378 LttTime end_time = new_time_window.end_time;
3379 LttTime time_width = new_time_window.time_width;
3381 g_assert(ltt_time_compare(start_time, end_time) < 0);
3384 GtkAdjustment *adjustment = gtk_range_get_adjustment(GTK_RANGE(tab->scrollbar));
3385 LttTime upper = ltt_time_sub(time_span.end_time, time_span.start_time);
3387 gtk_range_set_increments(GTK_RANGE(tab->scrollbar),
3388 ltt_time_to_double(new_time_window.time_width)
3389 / SCROLL_STEP_PER_PAGE
3390 * NANOSECONDS_PER_SECOND, /* step increment */
3391 ltt_time_to_double(new_time_window.time_width)
3392 * NANOSECONDS_PER_SECOND); /* page increment */
3393 gtk_range_set_range(GTK_RANGE(tab->scrollbar),
3395 ltt_time_to_double(upper)
3396 * NANOSECONDS_PER_SECOND); /* upper */
3398 g_object_set(G_OBJECT(adjustment),
3402 ltt_time_to_double(upper), /* upper */
3404 new_time_window.time_width_double
3405 / SCROLL_STEP_PER_PAGE, /* step increment */
3407 new_time_window.time_width_double,
3408 /* page increment */
3410 new_time_window.time_width_double, /* page size */
3412 gtk_adjustment_changed(adjustment);
3414 // g_object_set(G_OBJECT(adjustment),
3416 // ltt_time_to_double(
3417 // ltt_time_sub(start_time, time_span.start_time))
3420 //gtk_adjustment_value_changed(adjustment);
3421 gtk_range_set_value(GTK_RANGE(tab->scrollbar),
3423 ltt_time_sub(start_time, time_span.start_time)) /* value */);
3425 /* set the time bar. */
3427 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab->MEntry1),
3428 (double)time_span.start_time.tv_sec,
3429 (double)time_span.end_time.tv_sec);
3430 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab->MEntry1),
3431 (double)start_time.tv_sec);
3433 /* start nanoseconds */
3434 if(start_time.tv_sec == time_span.start_time.tv_sec) {
3435 /* can be both beginning and end at the same time. */
3436 if(start_time.tv_sec == time_span.end_time.tv_sec) {
3437 /* If we are at the end, max nsec to end.. -1 (not zero length) */
3438 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab->MEntry2),
3439 (double)time_span.start_time.tv_nsec,
3440 (double)time_span.end_time.tv_nsec-1);
3442 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab->MEntry2),
3443 (double)time_span.start_time.tv_nsec,
3444 (double)NANOSECONDS_PER_SECOND-1);
3446 } else if(start_time.tv_sec == time_span.end_time.tv_sec) {
3447 /* If we are at the end, max nsec to end.. -1 (not zero length) */
3448 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab->MEntry2),
3450 (double)time_span.end_time.tv_nsec-1);
3451 } else /* anywhere else */
3452 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab->MEntry2),
3454 (double)NANOSECONDS_PER_SECOND-1);
3455 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab->MEntry2),
3456 (double)start_time.tv_nsec);
3459 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab->MEntry3),
3460 (double)time_span.start_time.tv_sec,
3461 (double)time_span.end_time.tv_sec);
3462 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab->MEntry3),
3463 (double)end_time.tv_sec);
3465 /* end nanoseconds */
3466 if(end_time.tv_sec == time_span.start_time.tv_sec) {
3467 /* can be both beginning and end at the same time. */
3468 if(end_time.tv_sec == time_span.end_time.tv_sec) {
3469 /* If we are at the end, max nsec to end.. */
3470 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab->MEntry4),
3471 (double)time_span.start_time.tv_nsec+1,
3472 (double)time_span.end_time.tv_nsec);
3474 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab->MEntry4),
3475 (double)time_span.start_time.tv_nsec+1,
3476 (double)NANOSECONDS_PER_SECOND-1);
3479 else if(end_time.tv_sec == time_span.end_time.tv_sec) {
3480 /* If we are at the end, max nsec to end.. */
3481 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab->MEntry4),
3483 (double)time_span.end_time.tv_nsec);
3485 else /* anywhere else */
3486 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab->MEntry4),
3488 (double)NANOSECONDS_PER_SECOND-1);
3489 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab->MEntry4),
3490 (double)end_time.tv_nsec);
3493 if(time_width.tv_nsec == 0) {
3494 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab->MEntry7),
3496 (double)upper.tv_sec);
3498 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab->MEntry7),
3500 (double)upper.tv_sec);
3502 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab->MEntry7),
3503 (double)time_width.tv_sec);
3505 /* width nanoseconds */
3506 if(time_width.tv_sec == upper.tv_sec) {
3507 if(time_width.tv_sec == 0) {
3508 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab->MEntry8),
3510 (double)upper.tv_nsec);
3512 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab->MEntry8),
3514 (double)upper.tv_nsec);
3517 else if(time_width.tv_sec == 0) {
3518 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab->MEntry8),
3520 (double)upper.tv_nsec);
3522 else /* anywhere else */
3523 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab->MEntry8),
3525 (double)NANOSECONDS_PER_SECOND-1);
3526 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab->MEntry8),
3527 (double)time_width.tv_nsec);
3529 /* call viewer hooks for new time window */
3530 set_time_window(tab, &new_time_window);
3532 tab->time_manager_lock = FALSE;
3536 /* value changed for frame start s
3538 * Check time span : if ns is out of range, clip it the nearest good value.
3541 on_MEntry1_value_changed (GtkSpinButton *spinbutton,
3544 Tab *tab =(Tab *)user_data;
3545 LttvTracesetContext * tsc =
3546 LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context);
3547 TimeInterval time_span = tsc->time_span;
3548 gint value = gtk_spin_button_get_value_as_int(spinbutton);
3550 TimeWindow new_time_window = tab->time_window;
3552 LttTime end_time = new_time_window.end_time;
3554 new_time_window.start_time.tv_sec = value;
3556 /* start nanoseconds */
3557 if(new_time_window.start_time.tv_sec == time_span.start_time.tv_sec) {
3558 if(new_time_window.start_time.tv_sec == time_span.end_time.tv_sec) {
3559 if(new_time_window.start_time.tv_nsec > time_span.end_time.tv_nsec)
3560 new_time_window.start_time.tv_nsec = time_span.end_time.tv_nsec-1;
3561 if(new_time_window.start_time.tv_nsec < time_span.start_time.tv_nsec)
3562 new_time_window.start_time.tv_nsec = time_span.start_time.tv_nsec;
3564 if(new_time_window.start_time.tv_nsec < time_span.start_time.tv_nsec)
3565 new_time_window.start_time.tv_nsec = time_span.start_time.tv_nsec;
3568 else if(new_time_window.start_time.tv_sec == time_span.end_time.tv_sec) {
3569 if(new_time_window.start_time.tv_nsec > time_span.end_time.tv_nsec)
3570 new_time_window.start_time.tv_nsec = time_span.end_time.tv_nsec-1;
3573 if(ltt_time_compare(new_time_window.start_time, end_time) >= 0) {
3574 /* Then, we must push back end time : keep the same time width
3575 * if possible, else end traceset time */
3576 end_time = LTT_TIME_MIN(ltt_time_add(new_time_window.start_time,
3577 new_time_window.time_width),
3578 time_span.end_time);
3581 /* Fix the time width to fit start time and end time */
3582 new_time_window.time_width = ltt_time_sub(end_time,
3583 new_time_window.start_time);
3584 new_time_window.time_width_double =
3585 ltt_time_to_double(new_time_window.time_width);
3587 new_time_window.end_time = end_time;
3589 time_change_manager(tab, new_time_window);
3594 on_MEntry2_value_changed (GtkSpinButton *spinbutton,
3597 Tab *tab =(Tab *)user_data;
3598 LttvTracesetContext * tsc =
3599 LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context);
3600 TimeInterval time_span = tsc->time_span;
3601 gint value = gtk_spin_button_get_value_as_int(spinbutton);
3603 TimeWindow new_time_window = tab->time_window;
3605 LttTime end_time = new_time_window.end_time;
3607 new_time_window.start_time.tv_nsec = value;
3609 if(ltt_time_compare(new_time_window.start_time, end_time) >= 0) {
3610 /* Then, we must push back end time : keep the same time width
3611 * if possible, else end traceset time */
3612 end_time = LTT_TIME_MIN(ltt_time_add(new_time_window.start_time,
3613 new_time_window.time_width),
3614 time_span.end_time);
3617 /* Fix the time width to fit start time and end time */
3618 new_time_window.time_width = ltt_time_sub(end_time,
3619 new_time_window.start_time);
3620 new_time_window.time_width_double =
3621 ltt_time_to_double(new_time_window.time_width);
3623 new_time_window.end_time = end_time;
3625 time_change_manager(tab, new_time_window);
3630 on_MEntry3_value_changed (GtkSpinButton *spinbutton,
3633 Tab *tab =(Tab *)user_data;
3634 LttvTracesetContext * tsc =
3635 LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context);
3636 TimeInterval time_span = tsc->time_span;
3637 gint value = gtk_spin_button_get_value_as_int(spinbutton);
3639 TimeWindow new_time_window = tab->time_window;
3641 LttTime end_time = new_time_window.end_time;
3643 end_time.tv_sec = value;
3645 /* end nanoseconds */
3646 if(end_time.tv_sec == time_span.start_time.tv_sec) {
3647 if(end_time.tv_sec == time_span.end_time.tv_sec) {
3648 if(end_time.tv_nsec > time_span.end_time.tv_nsec)
3649 end_time.tv_nsec = time_span.end_time.tv_nsec;
3650 if(end_time.tv_nsec < time_span.start_time.tv_nsec)
3651 end_time.tv_nsec = time_span.start_time.tv_nsec+1;
3653 if(end_time.tv_nsec < time_span.start_time.tv_nsec)
3654 end_time.tv_nsec = time_span.start_time.tv_nsec+1;
3657 else if(end_time.tv_sec == time_span.end_time.tv_sec) {
3658 if(end_time.tv_nsec > time_span.end_time.tv_nsec)
3659 end_time.tv_nsec = time_span.end_time.tv_nsec;
3662 if(ltt_time_compare(new_time_window.start_time, end_time) >= 0) {
3663 /* Then, we must push front start time : keep the same time width
3664 * if possible, else end traceset time */
3665 new_time_window.start_time = LTT_TIME_MAX(
3666 ltt_time_sub(end_time,
3667 new_time_window.time_width),
3668 time_span.start_time);
3671 /* Fix the time width to fit start time and end time */
3672 new_time_window.time_width = ltt_time_sub(end_time,
3673 new_time_window.start_time);
3674 new_time_window.time_width_double =
3675 ltt_time_to_double(new_time_window.time_width);
3677 new_time_window.end_time = end_time;
3679 time_change_manager(tab, new_time_window);
3684 on_MEntry4_value_changed (GtkSpinButton *spinbutton,
3687 Tab *tab =(Tab *)user_data;
3688 LttvTracesetContext * tsc =
3689 LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context);
3690 TimeInterval time_span = tsc->time_span;
3691 gint value = gtk_spin_button_get_value_as_int(spinbutton);
3693 TimeWindow new_time_window = tab->time_window;
3695 LttTime end_time = new_time_window.end_time;
3697 end_time.tv_nsec = value;
3699 if(ltt_time_compare(new_time_window.start_time, end_time) >= 0) {
3700 /* Then, we must push front start time : keep the same time width
3701 * if possible, else end traceset time */
3702 new_time_window.start_time = LTT_TIME_MAX(
3703 ltt_time_sub(end_time,
3704 new_time_window.time_width),
3705 time_span.start_time);
3708 /* Fix the time width to fit start time and end time */
3709 new_time_window.time_width = ltt_time_sub(end_time,
3710 new_time_window.start_time);
3711 new_time_window.time_width_double =
3712 ltt_time_to_double(new_time_window.time_width);
3713 new_time_window.end_time = end_time;
3715 time_change_manager(tab, new_time_window);
3719 /* value changed for time frame interval s
3721 * Check time span : if ns is out of range, clip it the nearest good value.
3724 on_MEntry7_value_changed (GtkSpinButton *spinbutton,
3727 Tab *tab =(Tab *)user_data;
3728 LttvTracesetContext * tsc =
3729 LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context);
3730 TimeInterval time_span = tsc->time_span;
3731 gint value = gtk_spin_button_get_value_as_int(spinbutton);
3732 LttTime current_time, time_delta;
3733 TimeWindow new_time_window = tab->time_window;
3734 current_time = tab->current_time;
3736 time_delta = ltt_time_sub(time_span.end_time,time_span.start_time);
3737 new_time_window.time_width.tv_sec = value;
3738 new_time_window.time_width_double =
3739 ltt_time_to_double(new_time_window.time_width);
3740 if(ltt_time_compare(new_time_window.time_width,time_delta) > 0)
3741 { /* Case where zoom out is bigger than trace length */
3742 new_time_window.start_time = time_span.start_time;
3743 new_time_window.time_width = time_delta;
3744 new_time_window.time_width_double = ltt_time_to_double(time_delta);
3745 new_time_window.end_time = ltt_time_add(new_time_window.start_time,
3746 new_time_window.time_width) ;
3750 /* Center the image on the current time */
3751 new_time_window.start_time =
3752 ltt_time_sub(current_time,
3753 ltt_time_from_double(new_time_window.time_width_double/2.0));
3754 new_time_window.end_time = ltt_time_add(new_time_window.start_time,
3755 new_time_window.time_width) ;
3756 /* If on borders, don't fall off */
3757 if(ltt_time_compare(new_time_window.start_time, time_span.start_time) <0
3758 || ltt_time_compare(new_time_window.start_time, time_span.end_time) >0)
3760 new_time_window.start_time = time_span.start_time;
3761 new_time_window.end_time = ltt_time_add(new_time_window.start_time,
3762 new_time_window.time_width) ;
3766 if(ltt_time_compare(new_time_window.end_time,
3767 time_span.end_time) > 0
3768 || ltt_time_compare(new_time_window.end_time,
3769 time_span.start_time) < 0)
3771 new_time_window.start_time =
3772 ltt_time_sub(time_span.end_time, new_time_window.time_width);
3774 new_time_window.end_time = ltt_time_add(new_time_window.start_time,
3775 new_time_window.time_width) ;
3781 if(ltt_time_compare(new_time_window.time_width, ltt_time_zero) == 0) {
3782 g_warning("Zoom more than 1 ns impossible");
3784 time_change_manager(tab, new_time_window);
3789 on_MEntry8_value_changed (GtkSpinButton *spinbutton,
3792 Tab *tab =(Tab *)user_data;
3793 LttvTracesetContext * tsc =
3794 LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context);
3795 TimeInterval time_span = tsc->time_span;
3796 gint value = gtk_spin_button_get_value_as_int(spinbutton);
3797 LttTime current_time, time_delta;
3798 TimeWindow new_time_window = tab->time_window;
3799 current_time = tab->current_time;
3801 time_delta = ltt_time_sub(time_span.end_time,time_span.start_time);
3802 new_time_window.time_width.tv_nsec = value;
3803 new_time_window.time_width_double =
3804 ltt_time_to_double(new_time_window.time_width);
3805 if(ltt_time_compare(new_time_window.time_width,time_delta) > 0)
3806 { /* Case where zoom out is bigger than trace length */
3807 new_time_window.start_time = time_span.start_time;
3808 new_time_window.time_width = time_delta;
3809 new_time_window.time_width_double = ltt_time_to_double(time_delta);
3810 new_time_window.end_time = ltt_time_add(new_time_window.start_time,
3811 new_time_window.time_width) ;
3815 /* Center the image on the current time */
3816 new_time_window.start_time =
3817 ltt_time_sub(current_time,
3818 ltt_time_from_double(new_time_window.time_width_double/2.0));
3819 new_time_window.end_time = ltt_time_add(new_time_window.start_time,
3820 new_time_window.time_width) ;
3821 /* If on borders, don't fall off */
3822 if(ltt_time_compare(new_time_window.start_time, time_span.start_time) <0
3823 || ltt_time_compare(new_time_window.start_time, time_span.end_time) >0)
3825 new_time_window.start_time = time_span.start_time;
3826 new_time_window.end_time = ltt_time_add(new_time_window.start_time,
3827 new_time_window.time_width) ;
3831 if(ltt_time_compare(new_time_window.end_time,
3832 time_span.end_time) > 0
3833 || ltt_time_compare(new_time_window.end_time,
3834 time_span.start_time) < 0)
3836 new_time_window.start_time =
3837 ltt_time_sub(time_span.end_time, new_time_window.time_width);
3839 new_time_window.end_time = ltt_time_add(new_time_window.start_time,
3840 new_time_window.time_width) ;
3846 if(ltt_time_compare(new_time_window.time_width, ltt_time_zero) == 0) {
3847 g_warning("Zoom more than 1 ns impossible");
3849 time_change_manager(tab, new_time_window);
3855 void current_time_change_manager (Tab *tab,
3856 LttTime new_current_time)
3858 /* Only one source of time change */
3859 if(tab->current_time_manager_lock == TRUE) return;
3861 tab->current_time_manager_lock = TRUE;
3863 LttvTracesetContext *tsc = LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context);
3864 TimeInterval time_span = tsc->time_span;
3866 /* current seconds */
3867 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab->MEntry5),
3868 (double)time_span.start_time.tv_sec,
3869 (double)time_span.end_time.tv_sec);
3870 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab->MEntry5),
3871 (double)new_current_time.tv_sec);
3874 /* start nanoseconds */
3875 if(new_current_time.tv_sec == time_span.start_time.tv_sec) {
3876 /* can be both beginning and end at the same time. */
3877 if(new_current_time.tv_sec == time_span.end_time.tv_sec) {
3878 /* If we are at the end, max nsec to end.. */
3879 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab->MEntry6),
3880 (double)time_span.start_time.tv_nsec,
3881 (double)time_span.end_time.tv_nsec);
3883 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab->MEntry6),
3884 (double)time_span.start_time.tv_nsec,
3885 (double)NANOSECONDS_PER_SECOND-1);
3887 } else if(new_current_time.tv_sec == time_span.end_time.tv_sec) {
3888 /* If we are at the end, max nsec to end.. */
3889 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab->MEntry6),
3891 (double)time_span.end_time.tv_nsec);
3892 } else /* anywhere else */
3893 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab->MEntry6),
3895 (double)NANOSECONDS_PER_SECOND-1);
3897 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab->MEntry6),
3898 (double)new_current_time.tv_nsec);
3900 set_current_time(tab, &new_current_time);
3902 tab->current_time_manager_lock = FALSE;
3905 void current_position_change_manager(Tab *tab,
3906 LttvTracesetContextPosition *pos)
3908 LttvTracesetContext *tsc =
3909 LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context);
3910 TimeInterval time_span = tsc->time_span;
3912 g_assert(lttv_process_traceset_seek_position(tsc, pos) == 0);
3913 LttTime new_time = lttv_traceset_context_position_get_time(pos);
3914 /* Put the context in a state coherent position */
3915 lttv_state_traceset_seek_time_closest((LttvTracesetState*)tsc, ltt_time_zero);
3917 current_time_change_manager(tab, new_time);
3919 set_current_position(tab, pos);
3924 on_MEntry5_value_changed (GtkSpinButton *spinbutton,
3927 Tab *tab = (Tab*)user_data;
3928 LttvTracesetContext * tsc =
3929 LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context);
3930 TimeInterval time_span = tsc->time_span;
3931 gint value = gtk_spin_button_get_value_as_int(spinbutton);
3932 LttTime new_current_time = tab->current_time;
3933 new_current_time.tv_sec = value;
3935 /* current nanoseconds */
3936 if(new_current_time.tv_sec == time_span.start_time.tv_sec) {
3937 if(new_current_time.tv_sec == time_span.end_time.tv_sec) {
3938 if(new_current_time.tv_nsec > time_span.end_time.tv_nsec)
3939 new_current_time.tv_nsec = time_span.end_time.tv_nsec;
3940 if(new_current_time.tv_nsec < time_span.start_time.tv_nsec)
3941 new_current_time.tv_nsec = time_span.start_time.tv_nsec;
3943 if(new_current_time.tv_nsec < time_span.start_time.tv_nsec)
3944 new_current_time.tv_nsec = time_span.start_time.tv_nsec;
3947 else if(new_current_time.tv_sec == time_span.end_time.tv_sec) {
3948 if(new_current_time.tv_nsec > time_span.end_time.tv_nsec)
3949 new_current_time.tv_nsec = time_span.end_time.tv_nsec;
3952 current_time_change_manager(tab, new_current_time);
3956 on_MEntry6_value_changed (GtkSpinButton *spinbutton,
3959 Tab *tab = (Tab*)user_data;
3960 gint value = gtk_spin_button_get_value_as_int(spinbutton);
3961 LttTime new_current_time = tab->current_time;
3962 new_current_time.tv_nsec = value;
3964 current_time_change_manager(tab, new_current_time);
3968 void scroll_value_changed_cb(GtkWidget *scrollbar,
3971 Tab *tab = (Tab *)user_data;
3972 TimeWindow new_time_window;
3974 GtkAdjustment *adjust = gtk_range_get_adjustment(GTK_RANGE(scrollbar));
3975 gdouble value = gtk_adjustment_get_value(adjust);
3976 // gdouble upper, lower, ratio, page_size;
3978 LttvTracesetContext * tsc =
3979 LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context);
3980 TimeInterval time_span = tsc->time_span;
3982 time = ltt_time_add(ltt_time_from_double(value),
3983 time_span.start_time);
3985 new_time_window.start_time = time;
3987 page_size = adjust->page_size;
3989 new_time_window.time_width =
3990 ltt_time_from_double(page_size);
3992 new_time_window.time_width_double =
3995 new_time_window.end_time = ltt_time_add(new_time_window.start_time,
3996 new_time_window.time_width);
3999 time_change_manager(tab, new_time_window);
4001 //time_window = tab->time_window;
4003 lower = adjust->lower;
4004 upper = adjust->upper;
4005 ratio = (value - lower) / (upper - lower);
4006 g_info("lower %lu, upper %lu, value %lu, ratio %lu", lower, upper, value, ratio);
4008 //time = ltt_time_sub(time_span->end_time, time_span->start_time);
4009 //time = ltt_time_mul(time, (float)ratio);
4010 //time = ltt_time_add(time_span->start_time, time);
4011 time = ltt_time_add(ltt_time_from_double(value),
4012 time_span.start_time);
4014 time_window.start_time = time;
4016 page_size = adjust->page_size;
4018 time_window.time_width =
4019 ltt_time_from_double(page_size);
4020 //time = ltt_time_sub(time_span.end_time, time);
4021 //if(ltt_time_compare(time,time_window.time_width) < 0){
4022 // time_window.time_width = time;
4025 /* call viewer hooks for new time window */
4026 set_time_window(tab, &time_window);
4031 /* Display a dialogue showing all eventtypes and traces, let user to select the interested
4032 * eventtypes, tracefiles and traces (filter)
4035 /* Select a trace which will be removed from traceset
4038 char * get_remove_trace(MainWindow *mw_data,
4039 char ** all_trace_name, int nb_trace)
4041 return get_selection(mw_data, all_trace_name, nb_trace,
4042 "Select a trace", "Trace pathname");
4046 /* Select a module which will be loaded
4049 char * get_load_module(MainWindow *mw_data,
4050 char ** load_module_name, int nb_module)
4052 return get_selection(mw_data, load_module_name, nb_module,
4053 "Select a module to load", "Module name");
4059 /* Select a module which will be unloaded
4062 char * get_unload_module(MainWindow *mw_data,
4063 char ** loaded_module_name, int nb_module)
4065 return get_selection(mw_data, loaded_module_name, nb_module,
4066 "Select a module to unload", "Module name");
4070 /* Display a dialogue which shows all selectable items, let user to
4071 * select one of them
4074 char * get_selection(MainWindow *mw_data,
4075 char ** loaded_module_name, int nb_module,
4076 char *title, char * column_title)
4078 GtkWidget * dialogue;
4079 GtkWidget * scroll_win;
4081 GtkListStore * store;
4082 GtkTreeViewColumn * column;
4083 GtkCellRenderer * renderer;
4084 GtkTreeSelection * select;
4087 char * unload_module_name = NULL;
4089 dialogue = gtk_dialog_new_with_buttons(title,
4092 GTK_STOCK_OK,GTK_RESPONSE_ACCEPT,
4093 GTK_STOCK_CANCEL,GTK_RESPONSE_REJECT,
4095 gtk_window_set_default_size((GtkWindow*)dialogue, 500, 200);
4096 gtk_window_set_transient_for(GTK_WINDOW(dialogue),
4097 GTK_WINDOW(mw_data->mwindow));
4099 scroll_win = gtk_scrolled_window_new (NULL, NULL);
4100 gtk_widget_show ( scroll_win);
4101 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll_win),
4102 GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
4104 store = gtk_list_store_new (N_COLUMNS,G_TYPE_STRING);
4105 tree = gtk_tree_view_new_with_model(GTK_TREE_MODEL (store));
4106 gtk_widget_show ( tree);
4107 g_object_unref (G_OBJECT (store));
4109 renderer = gtk_cell_renderer_text_new ();
4110 column = gtk_tree_view_column_new_with_attributes (column_title,
4112 "text", MODULE_COLUMN,
4114 gtk_tree_view_column_set_alignment (column, 0.5);
4115 gtk_tree_view_column_set_fixed_width (column, 150);
4116 gtk_tree_view_append_column (GTK_TREE_VIEW (tree), column);
4118 select = gtk_tree_view_get_selection (GTK_TREE_VIEW (tree));
4119 gtk_tree_selection_set_mode (select, GTK_SELECTION_SINGLE);
4121 gtk_container_add (GTK_CONTAINER (scroll_win), tree);
4123 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialogue)->vbox), scroll_win,TRUE, TRUE,0);
4125 for(i=0;i<nb_module;i++){
4126 gtk_list_store_append (store, &iter);
4127 gtk_list_store_set (store, &iter, MODULE_COLUMN,loaded_module_name[i],-1);
4130 id = gtk_dialog_run(GTK_DIALOG(dialogue));
4131 GtkTreeModel **store_model = (GtkTreeModel**)&store;
4133 case GTK_RESPONSE_ACCEPT:
4134 case GTK_RESPONSE_OK:
4135 if (gtk_tree_selection_get_selected (select, store_model, &iter)){
4136 gtk_tree_model_get ((GtkTreeModel*)store, &iter, MODULE_COLUMN, &unload_module_name, -1);
4138 case GTK_RESPONSE_REJECT:
4139 case GTK_RESPONSE_CANCEL:
4141 gtk_widget_destroy(dialogue);
4145 return unload_module_name;
4149 /* Insert all menu entry and tool buttons into this main window
4154 void add_all_menu_toolbar_constructors(MainWindow * mw, gpointer user_data)
4158 lttvwindow_viewer_constructor constructor;
4159 LttvMenus * global_menu, * instance_menu;
4160 LttvToolbars * global_toolbar, * instance_toolbar;
4161 LttvMenuClosure *menu_item;
4162 LttvToolbarClosure *toolbar_item;
4163 LttvAttributeValue value;
4164 LttvIAttribute *global_attributes = LTTV_IATTRIBUTE(lttv_global_attributes());
4165 LttvIAttribute *attributes = mw->attributes;
4166 GtkWidget * tool_menu_title_menu, *new_widget, *pixmap;
4168 g_assert(lttv_iattribute_find_by_path(global_attributes,
4169 "viewers/menu", LTTV_POINTER, &value));
4170 if(*(value.v_pointer) == NULL)
4171 *(value.v_pointer) = lttv_menus_new();
4172 global_menu = (LttvMenus*)*(value.v_pointer);
4174 g_assert(lttv_iattribute_find_by_path(attributes,
4175 "viewers/menu", LTTV_POINTER, &value));
4176 if(*(value.v_pointer) == NULL)
4177 *(value.v_pointer) = lttv_menus_new();
4178 instance_menu = (LttvMenus*)*(value.v_pointer);
4182 g_assert(lttv_iattribute_find_by_path(global_attributes,
4183 "viewers/toolbar", LTTV_POINTER, &value));
4184 if(*(value.v_pointer) == NULL)
4185 *(value.v_pointer) = lttv_toolbars_new();
4186 global_toolbar = (LttvToolbars*)*(value.v_pointer);
4188 g_assert(lttv_iattribute_find_by_path(attributes,
4189 "viewers/toolbar", LTTV_POINTER, &value));
4190 if(*(value.v_pointer) == NULL)
4191 *(value.v_pointer) = lttv_toolbars_new();
4192 instance_toolbar = (LttvToolbars*)*(value.v_pointer);
4194 /* Add missing menu entries to window instance */
4195 for(i=0;i<global_menu->len;i++) {
4196 menu_item = &g_array_index(global_menu, LttvMenuClosure, i);
4198 //add menu_item to window instance;
4199 constructor = menu_item->con;
4200 tool_menu_title_menu = lookup_widget(mw->mwindow,"ToolMenuTitle_menu");
4202 gtk_menu_item_new_with_mnemonic (menu_item->menu_text);
4203 gtk_container_add (GTK_CONTAINER (tool_menu_title_menu),
4205 g_signal_connect ((gpointer) new_widget, "activate",
4206 G_CALLBACK (insert_viewer_wrap),
4208 gtk_widget_show (new_widget);
4209 lttv_menus_add(instance_menu, menu_item->con,
4210 menu_item->menu_path,
4211 menu_item->menu_text,
4216 /* Add missing toolbar entries to window instance */
4217 for(i=0;i<global_toolbar->len;i++) {
4218 toolbar_item = &g_array_index(global_toolbar, LttvToolbarClosure, i);
4220 //add toolbar_item to window instance;
4221 constructor = toolbar_item->con;
4222 tool_menu_title_menu = lookup_widget(mw->mwindow,"MToolbar1");
4223 pixbuf = gdk_pixbuf_new_from_xpm_data((const char**)toolbar_item->pixmap);
4224 pixmap = gtk_image_new_from_pixbuf(pixbuf);
4226 gtk_toolbar_append_element (GTK_TOOLBAR (tool_menu_title_menu),
4227 GTK_TOOLBAR_CHILD_BUTTON,
4230 toolbar_item->tooltip, NULL,
4231 pixmap, NULL, NULL);
4232 gtk_label_set_use_underline(
4233 GTK_LABEL (((GtkToolbarChild*) (
4234 g_list_last (GTK_TOOLBAR
4235 (tool_menu_title_menu)->children)->data))->label),
4237 gtk_container_set_border_width (GTK_CONTAINER (new_widget), 1);
4238 g_signal_connect ((gpointer) new_widget,
4240 G_CALLBACK (insert_viewer_wrap),
4242 gtk_widget_show (new_widget);
4244 lttv_toolbars_add(instance_toolbar, toolbar_item->con,
4245 toolbar_item->tooltip,
4246 toolbar_item->pixmap,
4254 /* Create a main window
4257 MainWindow *construct_main_window(MainWindow * parent)
4259 g_debug("construct_main_window()");
4260 GtkWidget * new_window; /* New generated main window */
4261 MainWindow * new_m_window;/* New main window structure */
4262 GtkNotebook * notebook;
4263 LttvIAttribute *attributes =
4264 LTTV_IATTRIBUTE(g_object_new(LTTV_ATTRIBUTE_TYPE, NULL));
4265 LttvAttributeValue value;
4268 new_m_window = g_new(MainWindow, 1);
4270 // Add the object's information to the module's array
4271 g_main_window_list = g_slist_append(g_main_window_list, new_m_window);
4273 new_window = create_MWindow();
4274 gtk_widget_show (new_window);
4276 new_m_window->mwindow = new_window;
4277 new_m_window->attributes = attributes;
4279 g_assert(lttv_iattribute_find_by_path(attributes,
4280 "viewers/menu", LTTV_POINTER, &value));
4281 *(value.v_pointer) = lttv_menus_new();
4283 g_assert(lttv_iattribute_find_by_path(attributes,
4284 "viewers/toolbar", LTTV_POINTER, &value));
4285 *(value.v_pointer) = lttv_toolbars_new();
4287 add_all_menu_toolbar_constructors(new_m_window, NULL);
4289 g_object_set_data_full(G_OBJECT(new_window),
4291 (gpointer)new_m_window,
4292 (GDestroyNotify)g_free);
4293 //create a default tab
4294 notebook = (GtkNotebook *)lookup_widget(new_m_window->mwindow, "MNotebook");
4295 if(notebook == NULL){
4296 g_info("Notebook does not exist\n");
4297 /* FIXME : destroy partially created widgets */
4298 g_free(new_m_window);
4301 //gtk_notebook_popup_enable (GTK_NOTEBOOK(notebook));
4302 //for now there is no name field in LttvTraceset structure
4303 //Use "Traceset" as the label for the default tab
4305 GtkWidget * parent_notebook = lookup_widget(parent->mwindow, "MNotebook");
4306 GtkWidget *page = gtk_notebook_get_nth_page(GTK_NOTEBOOK(parent_notebook),
4307 gtk_notebook_get_current_page(GTK_NOTEBOOK(parent_notebook)));
4313 LttvPluginTab *ptab;
4314 ptab = (LttvPluginTab *)g_object_get_data(G_OBJECT(page), "Tab_Plugin");
4315 parent_tab = ptab->tab;
4317 LttvPluginTab *ptab = g_object_new(LTTV_TYPE_PLUGIN_TAB, NULL);
4319 new_m_window, parent_tab, notebook, "Traceset");
4320 ptab->parent.top_widget = ptab->tab->top_widget;
4321 g_object_set_data_full(
4322 G_OBJECT(ptab->tab->vbox),
4325 (GDestroyNotify)tab_destructor);
4326 new_tab = ptab->tab;
4328 LttvPluginTab *ptab = g_object_new(LTTV_TYPE_PLUGIN_TAB, NULL);
4329 init_tab(ptab->tab, new_m_window, NULL, notebook, "Traceset");
4330 ptab->parent.top_widget = ptab->tab->top_widget;
4331 g_object_set_data_full(
4332 G_OBJECT(ptab->tab->vbox),
4335 (GDestroyNotify)tab_destructor);
4336 new_tab = ptab->tab;
4339 /* Insert default viewers */
4341 LttvAttributeType type;
4342 LttvAttributeName name;
4343 LttvAttributeValue value;
4344 LttvAttribute *attribute;
4346 LttvIAttribute *attributes_global =
4347 LTTV_IATTRIBUTE(lttv_global_attributes());
4349 g_assert(attribute =
4350 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
4351 LTTV_IATTRIBUTE(attributes_global),
4352 LTTV_VIEWER_CONSTRUCTORS)));
4354 name = g_quark_from_string("guievents");
4355 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute),
4357 if(type == LTTV_POINTER) {
4358 lttvwindow_viewer_constructor viewer_constructor =
4359 (lttvwindow_viewer_constructor)*value.v_pointer;
4360 insert_viewer(new_window, viewer_constructor);
4363 name = g_quark_from_string("guicontrolflow");
4364 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute),
4366 if(type == LTTV_POINTER) {
4367 lttvwindow_viewer_constructor viewer_constructor =
4368 (lttvwindow_viewer_constructor)*value.v_pointer;
4369 insert_viewer(new_window, viewer_constructor);
4372 name = g_quark_from_string("guistatistics");
4373 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute),
4375 if(type == LTTV_POINTER) {
4376 lttvwindow_viewer_constructor viewer_constructor =
4377 (lttvwindow_viewer_constructor)*value.v_pointer;
4378 insert_viewer(new_window, viewer_constructor);
4382 g_info("There are now : %d windows\n",g_slist_length(g_main_window_list));
4384 return new_m_window;
4388 /* Free the memory occupied by a tab structure
4392 void tab_destructor(LttvPluginTab * ptab)
4394 int i, nb, ref_count;
4396 Tab *tab = ptab->tab;
4398 gtk_object_destroy(GTK_OBJECT(tab->tooltips));
4401 g_object_unref(tab->attributes);
4403 if(tab->interrupted_state)
4404 g_object_unref(tab->interrupted_state);
4407 if(tab->traceset_info->traceset_context != NULL){
4408 //remove state update hooks
4409 lttv_state_remove_event_hooks(
4410 (LttvTracesetState*)tab->traceset_info->
4412 lttv_context_fini(LTTV_TRACESET_CONTEXT(tab->traceset_info->
4414 g_object_unref(tab->traceset_info->traceset_context);
4416 if(tab->traceset_info->traceset != NULL) {
4417 nb = lttv_traceset_number(tab->traceset_info->traceset);
4418 for(i = 0 ; i < nb ; i++) {
4419 trace = lttv_traceset_get(tab->traceset_info->traceset, i);
4420 ref_count = lttv_trace_get_ref_number(trace);
4422 ltt_trace_close(lttv_trace(trace));
4426 lttv_traceset_destroy(tab->traceset_info->traceset);
4427 /* Remove the idle events requests processing function of the tab */
4428 g_idle_remove_by_data(tab);
4430 g_slist_free(tab->events_requests);
4431 g_free(tab->traceset_info);
4433 g_object_unref(ptab);
4437 /* Create a tab and insert it into the current main window
4440 void init_tab(Tab *tab, MainWindow * mw, Tab *copy_tab,
4441 GtkNotebook * notebook, char * label)
4445 //LttvFilter *filter = NULL;
4447 //create a new tab data structure
4448 //tab = g_new(Tab,1);
4450 //construct and initialize the traceset_info
4451 tab->traceset_info = g_new(TracesetInfo,1);
4454 tab->traceset_info->traceset =
4455 lttv_traceset_copy(copy_tab->traceset_info->traceset);
4457 /* Copy the previous tab's filter */
4458 /* We can clone the filter, as we copy the trace set also */
4459 /* The filter must always be in sync with the trace set */
4460 tab->filter = lttv_filter_clone(copy_tab->filter);
4462 tab->traceset_info->traceset = lttv_traceset_new();
4466 lttv_attribute_write_xml(
4467 lttv_traceset_attribute(tab->traceset_info->traceset),
4473 tab->time_manager_lock = FALSE;
4474 tab->current_time_manager_lock = FALSE;
4476 //FIXME copy not implemented in lower level
4477 tab->traceset_info->traceset_context =
4478 g_object_new(LTTV_TRACESET_STATS_TYPE, NULL);
4479 g_assert(tab->traceset_info->traceset_context != NULL);
4481 LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context),
4482 tab->traceset_info->traceset);
4483 //add state update hooks
4484 lttv_state_add_event_hooks(
4485 (LttvTracesetState*)tab->traceset_info->traceset_context);
4487 //determine the current_time and time_window of the tab
4489 if(copy_tab != NULL){
4490 tab->time_window = copy_tab->time_window;
4491 tab->current_time = copy_tab->current_time;
4493 tab->time_window.start_time =
4494 LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context)->
4495 time_span.start_time;
4496 if(DEFAULT_TIME_WIDTH_S <
4497 LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context)->
4498 time_span.end_time.tv_sec)
4499 tmp_time.tv_sec = DEFAULT_TIME_WIDTH_S;
4502 LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context)->
4503 time_span.end_time.tv_sec;
4504 tmp_time.tv_nsec = 0;
4505 tab->time_window.time_width = tmp_time ;
4506 tab->current_time.tv_sec =
4507 LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context)->
4508 time_span.start_time.tv_sec;
4509 tab->current_time.tv_nsec =
4510 LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context)->
4511 time_span.start_time.tv_nsec;
4514 tab->attributes = LTTV_IATTRIBUTE(g_object_new(LTTV_ATTRIBUTE_TYPE, NULL));
4515 tab->interrupted_state = g_object_new(LTTV_ATTRIBUTE_TYPE, NULL);
4517 tab->vbox = gtk_vbox_new(FALSE, 2);
4518 tab->top_widget = tab->vbox;
4519 //g_object_set_data_full(G_OBJECT(tab->top_widget), "filter",
4520 // filter, (GDestroyNotify)lttv_filter_destroy);
4522 // g_signal_connect (G_OBJECT(tab->top_widget),
4524 // G_CALLBACK (on_top_notify),
4527 tab->viewer_container = gtk_vbox_new(TRUE, 2);
4528 tab->scrollbar = gtk_hscrollbar_new(NULL);
4529 //tab->multivpaned = gtk_multi_vpaned_new();
4531 gtk_box_pack_start(GTK_BOX(tab->vbox),
4532 tab->viewer_container,
4534 TRUE, /* Give the extra space to the child */
4535 0); /* No padding */
4538 // tab->time_window = copy_tab->time_window;
4539 // tab->current_time = copy_tab->current_time;
4542 /* Create the timebar */
4544 tab->MTimebar = gtk_hbox_new(FALSE, 2);
4545 gtk_widget_show(tab->MTimebar);
4546 tab->tooltips = gtk_tooltips_new();
4548 tab->MEventBox1a = gtk_event_box_new();
4549 gtk_widget_show(tab->MEventBox1a);
4550 gtk_tooltips_set_tip(tab->tooltips, tab->MEventBox1a,
4551 "Paste Start and End Times Here", "");
4552 tab->MText1a = gtk_label_new("Time Frame ");
4553 gtk_widget_show(tab->MText1a);
4554 gtk_container_add(GTK_CONTAINER(tab->MEventBox1a), tab->MText1a);
4555 tab->MEventBox1b = gtk_event_box_new();
4556 gtk_widget_show(tab->MEventBox1b);
4557 gtk_tooltips_set_tip(tab->tooltips, tab->MEventBox1b,
4558 "Paste Start Time Here", "");
4559 tab->MText1b = gtk_label_new("start: ");
4560 gtk_widget_show(tab->MText1b);
4561 gtk_container_add(GTK_CONTAINER(tab->MEventBox1b), tab->MText1b);
4562 tab->MText2 = gtk_label_new("s");
4563 gtk_widget_show(tab->MText2);
4564 tab->MText3a = gtk_label_new("ns");
4565 gtk_widget_show(tab->MText3a);
4567 tab->MEventBox3b = gtk_event_box_new();
4568 gtk_widget_show(tab->MEventBox3b);
4569 gtk_tooltips_set_tip(tab->tooltips, tab->MEventBox3b,
4570 "Paste End Time Here", "");
4571 tab->MText3b = gtk_label_new("end:");
4572 gtk_widget_show(tab->MText3b);
4573 gtk_container_add(GTK_CONTAINER(tab->MEventBox3b), tab->MText3b);
4574 tab->MText4 = gtk_label_new("s");
4575 gtk_widget_show(tab->MText4);
4576 tab->MText5a = gtk_label_new("ns");
4577 gtk_widget_show(tab->MText5a);
4579 tab->MEventBox8 = gtk_event_box_new();
4580 gtk_widget_show(tab->MEventBox8);
4581 gtk_tooltips_set_tip(tab->tooltips, tab->MEventBox8,
4582 "Paste Time Interval here", "");
4583 tab->MText8 = gtk_label_new("Time Interval:");
4584 gtk_widget_show(tab->MText8);
4585 gtk_container_add(GTK_CONTAINER(tab->MEventBox8), tab->MText8);
4586 tab->MText9 = gtk_label_new("s");
4587 gtk_widget_show(tab->MText9);
4588 tab->MText10 = gtk_label_new("ns");
4589 gtk_widget_show(tab->MText10);
4591 tab->MEventBox5b = gtk_event_box_new();
4592 gtk_widget_show(tab->MEventBox5b);
4593 gtk_tooltips_set_tip(tab->tooltips, tab->MEventBox5b,
4594 "Paste Current Time Here", "");
4595 tab->MText5b = gtk_label_new("Current Time:");
4596 gtk_widget_show(tab->MText5b);
4597 gtk_container_add(GTK_CONTAINER(tab->MEventBox5b), tab->MText5b);
4598 tab->MText6 = gtk_label_new("s");
4599 gtk_widget_show(tab->MText6);
4600 tab->MText7 = gtk_label_new("ns");
4601 gtk_widget_show(tab->MText7);
4603 tab->MEntry1 = gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4604 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab->MEntry1),0);
4605 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab->MEntry1),TRUE);
4606 gtk_widget_show(tab->MEntry1);
4607 tab->MEntry2 = gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4608 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab->MEntry2),0);
4609 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab->MEntry2),TRUE);
4610 gtk_widget_show(tab->MEntry2);
4611 tab->MEntry3 = gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4612 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab->MEntry3),0);
4613 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab->MEntry3),TRUE);
4614 gtk_widget_show(tab->MEntry3);
4615 tab->MEntry4 = gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4616 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab->MEntry4),0);
4617 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab->MEntry4),TRUE);
4618 gtk_widget_show(tab->MEntry4);
4619 tab->MEntry5 = gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4620 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab->MEntry5),0);
4621 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab->MEntry5),TRUE);
4622 gtk_widget_show(tab->MEntry5);
4623 tab->MEntry6 = gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4624 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab->MEntry6),0);
4625 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab->MEntry6),TRUE);
4626 gtk_widget_show(tab->MEntry6);
4627 tab->MEntry7 = gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4628 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab->MEntry7),0);
4629 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab->MEntry7),TRUE);
4630 gtk_widget_show(tab->MEntry7);
4631 tab->MEntry8 = gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4632 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab->MEntry8),0);
4633 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab->MEntry8),TRUE);
4634 gtk_widget_show(tab->MEntry8);
4636 GtkWidget *temp_widget;
4638 gtk_box_pack_start (GTK_BOX (tab->MTimebar), tab->MEventBox1a, FALSE,
4640 gtk_box_pack_start (GTK_BOX (tab->MTimebar), tab->MEventBox1b, FALSE,
4642 gtk_box_pack_start (GTK_BOX (tab->MTimebar), tab->MEntry1, FALSE, FALSE, 0);
4643 gtk_box_pack_start (GTK_BOX (tab->MTimebar), tab->MText2, FALSE, FALSE, 0);
4644 gtk_box_pack_start (GTK_BOX (tab->MTimebar), tab->MEntry2, FALSE, FALSE, 0);
4645 gtk_box_pack_start (GTK_BOX (tab->MTimebar), tab->MText3a, FALSE, FALSE, 0);
4646 temp_widget = gtk_vseparator_new();
4647 gtk_widget_show(temp_widget);
4648 gtk_box_pack_start (GTK_BOX (tab->MTimebar), temp_widget, FALSE, FALSE, 0);
4649 gtk_box_pack_start (GTK_BOX (tab->MTimebar), tab->MEventBox3b, FALSE,
4651 gtk_box_pack_start (GTK_BOX (tab->MTimebar), tab->MEntry3, FALSE, FALSE, 0);
4652 gtk_box_pack_start (GTK_BOX (tab->MTimebar), tab->MText4, FALSE, FALSE, 0);
4653 gtk_box_pack_start (GTK_BOX (tab->MTimebar), tab->MEntry4, FALSE, FALSE, 0);
4654 gtk_box_pack_start (GTK_BOX (tab->MTimebar), tab->MText5a, FALSE, FALSE, 0);
4655 temp_widget = gtk_vseparator_new();
4656 gtk_widget_show(temp_widget);
4657 gtk_box_pack_start (GTK_BOX (tab->MTimebar), temp_widget, FALSE, FALSE, 0);
4658 gtk_box_pack_start (GTK_BOX (tab->MTimebar), tab->MEventBox8, FALSE,
4660 gtk_box_pack_start (GTK_BOX (tab->MTimebar), tab->MEntry7, FALSE, FALSE, 0);
4661 gtk_box_pack_start (GTK_BOX (tab->MTimebar), tab->MText9, FALSE, FALSE, 0);
4662 gtk_box_pack_start (GTK_BOX (tab->MTimebar), tab->MEntry8, FALSE, FALSE, 0);
4663 gtk_box_pack_start (GTK_BOX (tab->MTimebar), tab->MText10, FALSE, FALSE, 0);
4665 temp_widget = gtk_vseparator_new();
4666 gtk_widget_show(temp_widget);
4667 gtk_box_pack_end (GTK_BOX (tab->MTimebar), tab->MText7, FALSE, FALSE, 0);
4668 gtk_box_pack_end (GTK_BOX (tab->MTimebar), tab->MEntry6, FALSE, FALSE, 0);
4669 gtk_box_pack_end (GTK_BOX (tab->MTimebar), tab->MText6, FALSE, FALSE, 0);
4670 gtk_box_pack_end (GTK_BOX (tab->MTimebar), tab->MEntry5, FALSE, FALSE, 0);
4671 gtk_box_pack_end (GTK_BOX (tab->MTimebar), tab->MEventBox5b, FALSE,
4673 gtk_box_pack_end (GTK_BOX (tab->MTimebar), temp_widget, FALSE, FALSE, 0);
4676 //GtkWidget *test = gtk_button_new_with_label("drop");
4677 //gtk_button_set_relief(GTK_BUTTON(test), GTK_RELIEF_NONE);
4678 //gtk_widget_show(test);
4679 //gtk_box_pack_end(GTK_BOX (tab->MTimebar), test, FALSE, FALSE, 0);
4680 //gtk_widget_add_events(tab->MText1, GDK_ALL_EVENTS_MASK);//GDK_BUTTON_PRESS_MASK);
4681 /*GtkWidget *event_box = gtk_event_box_new();
4682 gtk_widget_show(event_box);
4683 gtk_tooltips_set_tip(tooltips, event_box,
4684 "Paste Current Time Here", "");
4685 gtk_box_pack_end(GTK_BOX (tab->MTimebar), event_box, FALSE, FALSE, 0);
4686 GtkWidget *test = gtk_label_new("drop");
4687 gtk_container_add(GTK_CONTAINER(event_box), test);
4688 gtk_widget_show(test);
4689 g_signal_connect (G_OBJECT(event_box),
4690 "button-press-event",
4691 G_CALLBACK (on_MText1_paste),
4695 g_signal_connect (G_OBJECT(tab->MEventBox1a),
4696 "button-press-event",
4697 G_CALLBACK (on_MEventBox1a_paste),
4700 g_signal_connect (G_OBJECT(tab->MEventBox1b),
4701 "button-press-event",
4702 G_CALLBACK (on_MEventBox1b_paste),
4704 g_signal_connect (G_OBJECT(tab->MEventBox3b),
4705 "button-press-event",
4706 G_CALLBACK (on_MEventBox3b_paste),
4708 g_signal_connect (G_OBJECT(tab->MEventBox5b),
4709 "button-press-event",
4710 G_CALLBACK (on_MEventBox5b_paste),
4712 g_signal_connect (G_OBJECT(tab->MEventBox8),
4713 "button-press-event",
4714 G_CALLBACK (on_MEventBox8_paste),
4718 gtk_box_pack_end(GTK_BOX(tab->vbox),
4720 FALSE, /* Do not expand */
4721 FALSE, /* Fill has no effect here (expand false) */
4722 0); /* No padding */
4724 gtk_box_pack_end(GTK_BOX(tab->vbox),
4726 FALSE, /* Do not expand */
4727 FALSE, /* Fill has no effect here (expand false) */
4728 0); /* No padding */
4730 g_object_set_data(G_OBJECT(tab->viewer_container), "focused_viewer", NULL);
4736 // Display a label with a X
4737 GtkWidget *w_hbox = gtk_hbox_new(FALSE, 4);
4738 GtkWidget *w_label = gtk_label_new (label);
4739 GtkWidget *pixmap = create_pixmap(GTK_WIDGET(notebook), "close.png");
4740 GtkWidget *w_button = gtk_button_new ();
4741 gtk_container_add(GTK_CONTAINER(w_button), pixmap);
4742 //GtkWidget *w_button = gtk_button_new_with_label("x");
4744 gtk_button_set_relief(GTK_BUTTON(w_button), GTK_RELIEF_NONE);
4746 gtk_box_pack_start(GTK_BOX(w_hbox), w_label, TRUE, TRUE, 0);
4747 gtk_box_pack_end(GTK_BOX(w_hbox), w_button, FALSE,
4750 g_signal_connect_swapped (w_button, "clicked",
4751 G_CALLBACK (on_close_tab_X_clicked),
4754 gtk_widget_set_state(w_button, GTK_STATE_ACTIVE);
4756 gtk_widget_show (w_label);
4757 gtk_widget_show (pixmap);
4758 gtk_widget_show (w_button);
4759 gtk_widget_show (w_hbox);
4761 tab->label = w_hbox;
4765 tab->label = gtk_label_new (label);
4767 gtk_widget_show(tab->label);
4768 gtk_widget_show(tab->scrollbar);
4769 gtk_widget_show(tab->viewer_container);
4770 gtk_widget_show(tab->vbox);
4771 //gtk_widget_show(tab->multivpaned);
4774 /* Start with empty events requests list */
4775 tab->events_requests = NULL;
4776 tab->events_request_pending = FALSE;
4777 tab->stop_foreground = FALSE;
4781 g_signal_connect(G_OBJECT(tab->scrollbar), "value-changed",
4782 G_CALLBACK(scroll_value_changed_cb), tab);
4784 g_signal_connect ((gpointer) tab->MEntry1, "value-changed",
4785 G_CALLBACK (on_MEntry1_value_changed),
4787 g_signal_connect ((gpointer) tab->MEntry2, "value-changed",
4788 G_CALLBACK (on_MEntry2_value_changed),
4790 g_signal_connect ((gpointer) tab->MEntry3, "value-changed",
4791 G_CALLBACK (on_MEntry3_value_changed),
4793 g_signal_connect ((gpointer) tab->MEntry4, "value-changed",
4794 G_CALLBACK (on_MEntry4_value_changed),
4796 g_signal_connect ((gpointer) tab->MEntry5, "value-changed",
4797 G_CALLBACK (on_MEntry5_value_changed),
4799 g_signal_connect ((gpointer) tab->MEntry6, "value-changed",
4800 G_CALLBACK (on_MEntry6_value_changed),
4802 g_signal_connect ((gpointer) tab->MEntry7, "value-changed",
4803 G_CALLBACK (on_MEntry7_value_changed),
4805 g_signal_connect ((gpointer) tab->MEntry8, "value-changed",
4806 G_CALLBACK (on_MEntry8_value_changed),
4809 //g_signal_connect(G_OBJECT(tab->scrollbar), "changed",
4810 // G_CALLBACK(scroll_value_changed_cb), tab);
4813 //insert tab into notebook
4814 gtk_notebook_append_page(notebook,
4817 list = gtk_container_get_children(GTK_CONTAINER(notebook));
4818 gtk_notebook_set_current_page(notebook,g_list_length(list)-1);
4819 // always show : not if(g_list_length(list)>1)
4820 gtk_notebook_set_show_tabs(notebook, TRUE);
4823 lttvwindow_report_time_window(tab, copy_tab->time_window);
4824 lttvwindow_report_current_time(tab, copy_tab->current_time);
4826 TimeWindow time_window;
4828 time_window.start_time = ltt_time_zero;
4829 time_window.end_time = ltt_time_add(time_window.start_time,
4830 lttvwindow_default_time_width);
4831 time_window.time_width = lttvwindow_default_time_width;
4832 time_window.time_width_double = ltt_time_to_double(time_window.time_width);
4834 lttvwindow_report_time_window(tab, time_window);
4835 lttvwindow_report_current_time(tab, ltt_time_zero);
4838 LttvTraceset *traceset = tab->traceset_info->traceset;
4839 SetTraceset(tab, traceset);
4843 * execute_events_requests
4845 * Idle function that executes the pending requests for a tab.
4847 * @return return value : TRUE : keep the idle function, FALSE : remove it.
4849 gboolean execute_events_requests(Tab *tab)
4851 return ( lttvwindow_process_pending_requests(tab) );
4855 void create_main_window_with_trace_list(GSList *traces)
4857 GSList *iter = NULL;
4860 MainWindow *mw = construct_main_window(NULL);
4861 GtkWidget *widget = mw->mwindow;
4863 GtkWidget * notebook = lookup_widget(widget, "MNotebook");
4864 GtkWidget *page = gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook),
4865 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook)));
4866 LttvPluginTab *ptab;
4870 ptab = create_new_tab(widget, NULL);
4873 ptab = (LttvPluginTab *)g_object_get_data(G_OBJECT(page), "Tab_Plugin");
4877 for(iter=traces; iter!=NULL; iter=g_slist_next(iter)) {
4878 gchar *path = (gchar*)iter->data;
4880 gchar abs_path[PATH_MAX];
4884 get_absolute_pathname(path, abs_path);
4885 trace_v = lttvwindowtraces_get_trace_by_name(abs_path);
4886 if(trace_v == NULL) {
4887 trace = ltt_trace_open(abs_path);
4889 g_warning("cannot open trace %s", abs_path);
4891 GtkWidget *dialogue =
4892 gtk_message_dialog_new(
4893 GTK_WINDOW(gtk_widget_get_toplevel(widget)),
4894 GTK_DIALOG_MODAL|GTK_DIALOG_DESTROY_WITH_PARENT,
4897 "Cannot open trace : maybe you should enter in the directory"
4899 gtk_dialog_run(GTK_DIALOG(dialogue));
4900 gtk_widget_destroy(dialogue);
4902 trace_v = lttv_trace_new(trace);
4903 lttvwindowtraces_add_trace(trace_v);
4904 lttvwindow_add_trace(tab, trace_v);
4907 lttvwindow_add_trace(tab, trace_v);
4911 LttvTraceset *traceset;
4913 traceset = tab->traceset_info->traceset;
4914 SetTraceset(tab, traceset);