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>
36 #include <ltt/event.h>
37 #include <lttv/lttv.h>
38 #include <lttv/module.h>
39 #include <lttv/iattribute.h>
40 #include <lttv/stats.h>
41 #include <lttv/filter.h>
42 #include <lttvwindow/mainwindow.h>
43 #include <lttvwindow/mainwindow-private.h>
44 #include <lttvwindow/menu.h>
45 #include <lttvwindow/toolbar.h>
46 #include <lttvwindow/lttvwindow.h>
47 #include <lttvwindow/lttvwindowtraces.h>
48 #include <lttvwindow/lttv_plugin_tab.h>
50 static LttTime lttvwindow_default_time_width = { 1, 0 };
51 #define CLIP_BUF 256 // size of clipboard buffer
53 extern LttvTrace *g_init_trace ;
56 /** Array containing instanced objects. */
57 extern GSList * g_main_window_list;
59 /** MD : keep old directory. */
60 static char remember_plugins_dir[PATH_MAX] = "";
61 static char remember_trace_dir[PATH_MAX] = "";
63 void tab_destructor(LttvPluginTab * ptab);
65 MainWindow * get_window_data_struct(GtkWidget * widget);
66 char * get_load_module(MainWindow *mw,
67 char ** load_module_name, int nb_module);
68 char * get_unload_module(MainWindow *mw,
69 char ** loaded_module_name, int nb_module);
70 char * get_remove_trace(MainWindow *mw, char ** all_trace_name, int nb_trace);
71 char * get_selection(MainWindow *mw,
72 char ** all_name, int nb, char *title, char * column_title);
73 void init_tab(Tab *tab, MainWindow * mw, Tab *copy_tab,
74 GtkNotebook * notebook, char * label);
76 static void insert_viewer(GtkWidget* widget, lttvwindow_viewer_constructor constructor);
78 LttvPluginTab *create_new_tab(GtkWidget* widget, gpointer user_data);
80 static gboolean lttvwindow_process_pending_requests(Tab *tab);
94 /* Pasting routines */
96 static void MEventBox1a_receive(GtkClipboard *clipboard,
100 if(text == NULL) return;
101 Tab *tab = (Tab *)data;
102 gchar buffer[CLIP_BUF];
103 gchar *ptr = buffer, *ptr_ssec, *ptr_snsec, *ptr_esec, *ptr_ensec;
105 strncpy(buffer, text, CLIP_BUF);
108 while(!isdigit(*ptr) && ptr < buffer+CLIP_BUF-1) ptr++;
109 /* remove leading junk */
111 while(isdigit(*ptr) && ptr < buffer+CLIP_BUF-1) ptr++;
112 /* read all the first number */
116 while(!isdigit(*ptr) && ptr < buffer+CLIP_BUF-1) ptr++;
117 /* remove leading junk */
119 while(isdigit(*ptr) && ptr < buffer+CLIP_BUF-1) ptr++;
120 /* read all the first number */
124 while(!isdigit(*ptr) && ptr < buffer+CLIP_BUF-1) ptr++;
125 /* remove leading junk */
127 while(isdigit(*ptr) && ptr < buffer+CLIP_BUF-1) ptr++;
128 /* read all the first number */
132 while(!isdigit(*ptr) && ptr < buffer+CLIP_BUF-1) ptr++;
133 /* remove leading junk */
135 while(isdigit(*ptr) && ptr < buffer+CLIP_BUF-1) ptr++;
136 /* read all the first number */
139 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab->MEntry1),
140 (double)strtoul(ptr_ssec, NULL, 10));
141 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab->MEntry2),
142 (double)strtoul(ptr_snsec, NULL, 10));
143 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab->MEntry3),
144 (double)strtoul(ptr_esec, NULL, 10));
145 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab->MEntry4),
146 (double)strtoul(ptr_ensec, NULL, 10));
149 static gboolean on_MEventBox1a_paste(GtkWidget *widget, GdkEventButton *event,
152 Tab *tab = (Tab*)data;
154 GtkClipboard *clip = gtk_clipboard_get_for_display(gdk_display_get_default(),
155 GDK_SELECTION_PRIMARY);
156 gtk_clipboard_request_text(clip,
157 (GtkClipboardTextReceivedFunc)MEventBox1a_receive,
164 static void MEventBox1b_receive(GtkClipboard *clipboard,
168 if(text == NULL) return;
169 Tab *tab = (Tab *)data;
170 gchar buffer[CLIP_BUF];
171 gchar *ptr = buffer, *ptr_sec, *ptr_nsec;
173 strncpy(buffer, text, CLIP_BUF);
175 while(!isdigit(*ptr) && ptr < buffer+CLIP_BUF-1) ptr++;
176 /* remove leading junk */
178 while(isdigit(*ptr) && ptr < buffer+CLIP_BUF-1) ptr++;
179 /* read all the first number */
183 while(!isdigit(*ptr) && ptr < buffer+CLIP_BUF-1) ptr++;
184 /* remove leading junk */
186 while(isdigit(*ptr) && ptr < buffer+CLIP_BUF-1) ptr++;
187 /* read all the first number */
190 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab->MEntry1),
191 (double)strtoul(ptr_sec, NULL, 10));
192 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab->MEntry2),
193 (double)strtoul(ptr_nsec, NULL, 10));
197 static gboolean on_MEventBox1b_paste(GtkWidget *widget, GdkEventButton *event,
200 Tab *tab = (Tab*)data;
202 GtkClipboard *clip = gtk_clipboard_get_for_display(gdk_display_get_default(),
203 GDK_SELECTION_PRIMARY);
204 gtk_clipboard_request_text(clip,
205 (GtkClipboardTextReceivedFunc)MEventBox1b_receive,
211 static void MEventBox3b_receive(GtkClipboard *clipboard,
215 if(text == NULL) return;
216 Tab *tab = (Tab *)data;
217 gchar buffer[CLIP_BUF];
218 gchar *ptr = buffer, *ptr_sec, *ptr_nsec;
220 strncpy(buffer, text, CLIP_BUF);
222 while(!isdigit(*ptr) && ptr < buffer+CLIP_BUF-1) ptr++;
223 /* remove leading junk */
225 while(isdigit(*ptr) && ptr < buffer+CLIP_BUF-1) ptr++;
226 /* read all the first number */
230 while(!isdigit(*ptr) && ptr < buffer+CLIP_BUF-1) ptr++;
231 /* remove leading junk */
233 while(isdigit(*ptr) && ptr < buffer+CLIP_BUF-1) ptr++;
234 /* read all the first number */
237 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab->MEntry3),
238 (double)strtoul(ptr_sec, NULL, 10));
239 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab->MEntry4),
240 (double)strtoul(ptr_nsec, NULL, 10));
244 static gboolean on_MEventBox3b_paste(GtkWidget *widget, GdkEventButton *event,
247 Tab *tab = (Tab*)data;
249 GtkClipboard *clip = gtk_clipboard_get_for_display(gdk_display_get_default(),
250 GDK_SELECTION_PRIMARY);
251 gtk_clipboard_request_text(clip,
252 (GtkClipboardTextReceivedFunc)MEventBox3b_receive,
258 static void MEventBox5b_receive(GtkClipboard *clipboard,
262 if(text == NULL) return;
263 Tab *tab = (Tab *)data;
264 gchar buffer[CLIP_BUF];
265 gchar *ptr = buffer, *ptr_sec, *ptr_nsec;
267 strncpy(buffer, text, CLIP_BUF);
269 while(!isdigit(*ptr) && ptr < buffer+CLIP_BUF-1) ptr++;
270 /* remove leading junk */
272 while(isdigit(*ptr) && ptr < buffer+CLIP_BUF-1) ptr++;
273 /* read all the first number */
277 while(!isdigit(*ptr) && ptr < buffer+CLIP_BUF-1) ptr++;
278 /* remove leading junk */
280 while(isdigit(*ptr) && ptr < buffer+CLIP_BUF-1) ptr++;
281 /* read all the first number */
284 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab->MEntry5),
285 (double)strtoul(ptr_sec, NULL, 10));
286 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab->MEntry6),
287 (double)strtoul(ptr_nsec, NULL, 10));
291 static gboolean on_MEventBox5b_paste(GtkWidget *widget, GdkEventButton *event,
294 Tab *tab = (Tab*)data;
296 GtkClipboard *clip = gtk_clipboard_get_for_display(gdk_display_get_default(),
297 GDK_SELECTION_PRIMARY);
298 gtk_clipboard_request_text(clip,
299 (GtkClipboardTextReceivedFunc)MEventBox5b_receive,
305 static void MEventBox8_receive(GtkClipboard *clipboard,
309 if(text == NULL) return;
310 Tab *tab = (Tab *)data;
311 gchar buffer[CLIP_BUF];
312 gchar *ptr = buffer, *ptr_sec, *ptr_nsec;
314 strncpy(buffer, text, CLIP_BUF);
316 while(!isdigit(*ptr) && ptr < buffer+CLIP_BUF-1) ptr++;
317 /* remove leading junk */
319 while(isdigit(*ptr) && ptr < buffer+CLIP_BUF-1) ptr++;
320 /* read all the first number */
324 while(!isdigit(*ptr) && ptr < buffer+CLIP_BUF-1) ptr++;
325 /* remove leading junk */
327 while(isdigit(*ptr) && ptr < buffer+CLIP_BUF-1) ptr++;
328 /* read all the first number */
331 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab->MEntry7),
332 (double)strtoul(ptr_sec, NULL, 10));
333 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab->MEntry8),
334 (double)strtoul(ptr_nsec, NULL, 10));
338 static gboolean on_MEventBox8_paste(GtkWidget *widget, GdkEventButton *event,
341 Tab *tab = (Tab*)data;
343 GtkClipboard *clip = gtk_clipboard_get_for_display(gdk_display_get_default(),
344 GDK_SELECTION_PRIMARY);
345 gtk_clipboard_request_text(clip,
346 (GtkClipboardTextReceivedFunc)MEventBox8_receive,
352 static void on_top_notify(GObject *gobject,
356 Tab *tab = (Tab*)user_data;
357 g_message("in on_top_notify.\n");
361 static gboolean viewer_grab_focus(GtkWidget *widget, GdkEventButton *event,
364 GtkWidget *viewer = GTK_WIDGET(data);
365 GtkWidget *viewer_container = gtk_widget_get_parent(viewer);
367 g_debug("FOCUS GRABBED");
368 g_object_set_data(G_OBJECT(viewer_container), "focused_viewer", viewer);
373 static void connect_focus_recursive(GtkWidget *widget,
376 if(GTK_IS_CONTAINER(widget)) {
377 gtk_container_forall(GTK_CONTAINER(widget),
378 (GtkCallback)connect_focus_recursive,
382 if(GTK_IS_TREE_VIEW(widget)) {
383 gtk_tree_view_set_headers_clickable(GTK_TREE_VIEW(widget), TRUE);
385 gtk_widget_add_events(widget, GDK_BUTTON_PRESS_MASK);
386 g_signal_connect (G_OBJECT(widget),
387 "button-press-event",
388 G_CALLBACK (viewer_grab_focus),
392 /* Stop all the processings and call gtk_main_quit() */
393 static void mainwindow_quit()
395 lttvwindowtraces_unregister_requests(g_quark_from_string("stats"));
396 lttvwindowtraces_unregister_requests(g_quark_from_string("state"));
397 lttvwindowtraces_unregister_computation_hooks(g_quark_from_string("stats"));
398 lttvwindowtraces_unregister_computation_hooks(g_quark_from_string("state"));
404 /* insert_viewer function constructs an instance of a viewer first,
405 * then inserts the widget of the instance into the container of the
410 insert_viewer_wrap(GtkWidget *menuitem, gpointer user_data)
412 insert_viewer((GtkWidget*)menuitem, (lttvwindow_viewer_constructor)user_data);
416 /* internal functions */
417 void insert_viewer(GtkWidget* widget, lttvwindow_viewer_constructor constructor)
419 GtkWidget * viewer_container;
420 MainWindow * mw_data = get_window_data_struct(widget);
421 GtkWidget * notebook = lookup_widget(widget, "MNotebook");
423 TimeInterval * time_interval;
424 GtkWidget *page = gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook),
425 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook)));
430 ptab = create_new_tab(widget, NULL);
432 ptab = (LttvPluginTab *)g_object_get_data(G_OBJECT(page), "Tab_Plugin");
436 viewer_container = tab->viewer_container;
438 viewer = (GtkWidget*)constructor(ptab);
441 //gtk_multivpaned_widget_add(GTK_MULTIVPANED(multivpaned), viewer);
443 gtk_box_pack_end(GTK_BOX(viewer_container),
449 /* We want to connect the viewer_grab_focus to EVERY
450 * child of this widget. The little trick is to get each child
451 * of each GTK_CONTAINER, even subchildren.
453 connect_focus_recursive(viewer, viewer);
458 * Function to set/update traceset for the viewers
459 * @param tab viewer's tab
460 * @param traceset traceset of the main window.
462 * 0 : traceset updated
463 * 1 : no traceset hooks to update; not an error.
466 int SetTraceset(Tab * tab, LttvTraceset *traceset)
468 LttvTracesetContext *tsc =
469 LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context);
470 TimeInterval time_span = tsc->time_span;
471 TimeWindow new_time_window = tab->time_window;
472 LttTime new_current_time = tab->current_time;
474 /* Set the tab's time window and current time if
476 if(ltt_time_compare(tab->time_window.start_time, time_span.start_time) < 0
477 || ltt_time_compare(tab->time_window.end_time,
478 time_span.end_time) > 0) {
479 new_time_window.start_time = time_span.start_time;
481 new_current_time = time_span.start_time;
485 if(ltt_time_compare(lttvwindow_default_time_width,
486 ltt_time_sub(time_span.end_time, time_span.start_time)) < 0
488 ltt_time_compare(time_span.end_time, time_span.start_time) == 0)
489 tmp_time = lttvwindow_default_time_width;
491 tmp_time = time_span.end_time;
493 new_time_window.time_width = tmp_time ;
494 new_time_window.time_width_double = ltt_time_to_double(tmp_time);
495 new_time_window.end_time = ltt_time_add(new_time_window.start_time,
496 new_time_window.time_width) ;
503 GtkAdjustment *adjustment = gtk_range_get_adjustment(GTK_RANGE(tab->scrollbar));
504 LttTime upper = ltt_time_sub(time_span.end_time, time_span.start_time);
506 g_object_set(G_OBJECT(adjustment),
510 ltt_time_to_double(upper)
511 * NANOSECONDS_PER_SECOND, /* upper */
513 ltt_time_to_double(tab->time_window.time_width)
514 / SCROLL_STEP_PER_PAGE
515 * NANOSECONDS_PER_SECOND, /* step increment */
517 ltt_time_to_double(tab->time_window.time_width)
518 * NANOSECONDS_PER_SECOND, /* page increment */
520 ltt_time_to_double(tab->time_window.time_width)
521 * NANOSECONDS_PER_SECOND, /* page size */
523 gtk_adjustment_changed(adjustment);
525 g_object_set(G_OBJECT(adjustment),
528 ltt_time_sub(tab->time_window.start_time, time_span.start_time))
529 * NANOSECONDS_PER_SECOND, /* value */
531 gtk_adjustment_value_changed(adjustment);
533 /* set the time bar. The value callbacks will change their nsec themself */
535 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab->MEntry1),
536 (double)time_span.start_time.tv_sec,
537 (double)time_span.end_time.tv_sec);
540 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab->MEntry3),
541 (double)time_span.start_time.tv_sec,
542 (double)time_span.end_time.tv_sec);
544 /* current seconds */
545 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab->MEntry5),
546 (double)time_span.start_time.tv_sec,
547 (double)time_span.end_time.tv_sec);
550 /* Finally, call the update hooks of the viewers */
552 LttvAttributeValue value;
556 g_assert( lttv_iattribute_find_by_path(tab->attributes,
557 "hooks/updatetraceset", LTTV_POINTER, &value));
559 tmp = (LttvHooks*)*(value.v_pointer);
560 if(tmp == NULL) retval = 1;
561 else lttv_hooks_call(tmp,traceset);
563 time_change_manager(tab, new_time_window);
564 current_time_change_manager(tab, new_current_time);
570 * Function to set/update filter for the viewers
571 * @param tab viewer's tab
572 * @param filter filter of the main window.
575 * 0 : filters updated
576 * 1 : no filter hooks to update; not an error.
579 int SetFilter(Tab * tab, gpointer filter)
582 LttvAttributeValue value;
584 g_assert(lttv_iattribute_find_by_path(tab->attributes,
585 "hooks/updatefilter", LTTV_POINTER, &value));
587 tmp = (LttvHooks*)*(value.v_pointer);
589 if(tmp == NULL) return 1;
590 lttv_hooks_call(tmp,filter);
598 * Function to redraw each viewer belonging to the current tab
599 * @param tab viewer's tab
602 void update_traceset(Tab *tab)
604 LttvAttributeValue value;
606 g_assert(lttv_iattribute_find_by_path(tab->attributes,
607 "hooks/updatetraceset", LTTV_POINTER, &value));
608 tmp = (LttvHooks*)*(value.v_pointer);
609 if(tmp == NULL) return;
610 lttv_hooks_call(tmp, NULL);
614 /* get_label function is used to get user input, it displays an input
615 * box, which allows user to input a string
618 void get_label_string (GtkWidget * text, gchar * label)
620 GtkEntry * entry = (GtkEntry*)text;
621 if(strlen(gtk_entry_get_text(entry))!=0)
622 strcpy(label,gtk_entry_get_text(entry));
625 gboolean get_label(MainWindow * mw, gchar * str, gchar* dialogue_title, gchar * label_str)
627 GtkWidget * dialogue;
632 dialogue = gtk_dialog_new_with_buttons(dialogue_title,NULL,
634 GTK_STOCK_OK,GTK_RESPONSE_ACCEPT,
635 GTK_STOCK_CANCEL,GTK_RESPONSE_REJECT,
638 label = gtk_label_new(label_str);
639 gtk_widget_show(label);
641 text = gtk_entry_new();
642 gtk_widget_show(text);
644 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialogue)->vbox), label,TRUE, TRUE,0);
645 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialogue)->vbox), text,FALSE, FALSE,0);
647 id = gtk_dialog_run(GTK_DIALOG(dialogue));
649 case GTK_RESPONSE_ACCEPT:
650 get_label_string(text,str);
651 gtk_widget_destroy(dialogue);
653 case GTK_RESPONSE_REJECT:
655 gtk_widget_destroy(dialogue);
662 /* get_window_data_struct function is actually a lookup function,
663 * given a widget which is in the tree of the main window, it will
664 * return the MainWindow data structure associated with main window
667 MainWindow * get_window_data_struct(GtkWidget * widget)
670 MainWindow * mw_data;
672 mw = lookup_widget(widget, "MWindow");
674 g_info("Main window does not exist\n");
678 mw_data = (MainWindow *) g_object_get_data(G_OBJECT(mw),"main_window_data");
680 g_warning("Main window data does not exist\n");
687 /* create_new_window function, just constructs a new main window
690 void create_new_window(GtkWidget* widget, gpointer user_data, gboolean clone)
692 MainWindow * parent = get_window_data_struct(widget);
695 g_info("Clone : use the same traceset\n");
696 construct_main_window(parent);
698 g_info("Empty : traceset is set to NULL\n");
699 construct_main_window(NULL);
703 /* Get the currently focused viewer.
704 * If no viewer is focused, use the first one.
706 * If no viewer available, return NULL.
708 GtkWidget *viewer_container_focus(GtkWidget *container)
712 widget = (GtkWidget*)g_object_get_data(G_OBJECT(container),
716 g_debug("no widget focused");
717 GList *children = gtk_container_get_children(GTK_CONTAINER(container));
720 widget = GTK_WIDGET(children->data);
721 g_object_set_data(G_OBJECT(container),
731 gint viewer_container_position(GtkWidget *container, GtkWidget *child)
734 if(child == NULL) return -1;
738 memset(&value, 0, sizeof(GValue));
739 g_value_init(&value, G_TYPE_INT);
740 gtk_container_child_get_property(GTK_CONTAINER(container),
744 pos = g_value_get_int(&value);
750 /* move_*_viewer functions move the selected view up/down in
754 void move_down_viewer(GtkWidget * widget, gpointer user_data)
756 MainWindow * mw = get_window_data_struct(widget);
757 GtkWidget * notebook = lookup_widget(widget, "MNotebook");
759 GtkWidget *page = gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook),
760 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook)));
767 ptab = (Tab *)g_object_get_data(G_OBJECT(page), "Tab_Plugin");
771 //gtk_multivpaned_widget_move_up(GTK_MULTIVPANED(tab->multivpaned));
773 /* change the position in the vbox */
774 GtkWidget *focus_widget;
776 focus_widget = viewer_container_focus(tab->viewer_container);
777 position = viewer_container_position(tab->viewer_container, focus_widget);
780 /* can move up one position */
781 gtk_box_reorder_child(GTK_BOX(tab->viewer_container),
788 void move_up_viewer(GtkWidget * widget, gpointer user_data)
790 MainWindow * mw = get_window_data_struct(widget);
791 GtkWidget * notebook = lookup_widget(widget, "MNotebook");
793 GtkWidget *page = gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook),
794 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook)));
801 ptab = (LttvPluginTab *)g_object_get_data(G_OBJECT(page), "Tab_Plugin");
805 //gtk_multivpaned_widget_move_down(GTK_MULTIVPANED(tab->multivpaned));
806 /* change the position in the vbox */
807 GtkWidget *focus_widget;
809 focus_widget = viewer_container_focus(tab->viewer_container);
810 position = viewer_container_position(tab->viewer_container, focus_widget);
814 g_list_length(gtk_container_get_children(
815 GTK_CONTAINER(tab->viewer_container)))-1
817 /* can move down one position */
818 gtk_box_reorder_child(GTK_BOX(tab->viewer_container),
826 /* delete_viewer deletes the selected viewer in the current tab
829 void delete_viewer(GtkWidget * widget, gpointer user_data)
831 MainWindow * mw = get_window_data_struct(widget);
832 GtkWidget * notebook = lookup_widget(widget, "MNotebook");
834 GtkWidget *page = gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook),
835 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook)));
842 ptab = (Tab *)g_object_get_data(G_OBJECT(page), "Tab_Plugin");
846 //gtk_multivpaned_widget_delete(GTK_MULTIVPANED(tab->multivpaned));
848 GtkWidget *focus_widget = viewer_container_focus(tab->viewer_container);
850 if(focus_widget != NULL)
851 gtk_widget_destroy(focus_widget);
853 g_object_set_data(G_OBJECT(tab->viewer_container), "focused_viewer", NULL);
857 /* open_traceset will open a traceset saved in a file
858 * Right now, it is not finished yet, (not working)
862 void open_traceset(GtkWidget * widget, gpointer user_data)
866 LttvTraceset * traceset;
867 MainWindow * mw_data = get_window_data_struct(widget);
868 GtkFileSelection * file_selector =
869 (GtkFileSelection *)gtk_file_selection_new("Select a traceset");
871 gtk_file_selection_hide_fileop_buttons(file_selector);
873 gtk_window_set_transient_for(GTK_WINDOW(file_selector),
874 GTK_WINDOW(mw_data->mwindow));
876 id = gtk_dialog_run(GTK_DIALOG(file_selector));
878 case GTK_RESPONSE_ACCEPT:
879 case GTK_RESPONSE_OK:
880 dir = gtk_file_selection_get_selections (file_selector);
881 traceset = lttv_traceset_load(dir[0]);
882 g_info("Open a trace set %s\n", dir[0]);
885 case GTK_RESPONSE_REJECT:
886 case GTK_RESPONSE_CANCEL:
888 gtk_widget_destroy((GtkWidget*)file_selector);
894 /* lttvwindow_process_pending_requests
896 * This internal function gets called by g_idle, taking care of the pending
897 * requests. It is responsible for concatenation of time intervals and position
898 * requests. It does it with the following algorithm organizing process traceset
899 * calls. Here is the detailed description of the way it works :
901 * - Events Requests Servicing Algorithm
903 * Data structures necessary :
905 * List of requests added to context : list_in
906 * List of requests not added to context : list_out
911 * list_out : many events requests
913 * FIXME : insert rest of algorithm here
917 #define list_out tab->events_requests
919 gboolean lttvwindow_process_pending_requests(Tab *tab)
922 LttvTracesetContext *tsc;
923 LttvTracefileContext *tfc;
924 GSList *list_in = NULL;
928 LttvTracesetContextPosition *end_position;
930 if(lttvwindow_preempt_count > 0) return TRUE;
933 g_critical("Foreground processing : tab does not exist. Processing removed.");
937 /* There is no events requests pending : we should never have been called! */
938 g_assert(g_slist_length(list_out) != 0);
940 tsc = LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context);
942 //set the cursor to be X shape, indicating that the computer is busy in doing its job
944 new = gdk_cursor_new(GDK_X_CURSOR);
945 widget = lookup_widget(tab->mw->mwindow, "MToolbar1");
946 win = gtk_widget_get_parent_window(widget);
947 gdk_window_set_cursor(win, new);
948 gdk_cursor_unref(new);
949 gdk_window_stick(win);
950 gdk_window_unstick(win);
953 g_debug("SIZE events req len : %d", g_slist_length(list_out));
955 /* Preliminary check for no trace in traceset */
956 /* Unregister the routine if empty, empty list_out too */
957 if(lttv_traceset_number(tsc->ts) == 0) {
959 /* - For each req in list_out */
960 GSList *iter = list_out;
962 while(iter != NULL) {
964 gboolean remove = FALSE;
965 gboolean free_data = FALSE;
966 EventsRequest *events_request = (EventsRequest *)iter->data;
968 /* - Call end request for req */
969 if(events_request->servicing == TRUE)
970 lttv_hooks_call(events_request->after_request, (gpointer)tsc);
972 /* - remove req from list_out */
973 /* Destroy the request */
980 GSList *remove_iter = iter;
982 iter = g_slist_next(iter);
983 if(free_data) events_request_free((EventsRequest*)remove_iter->data);
984 list_out = g_slist_remove_link(list_out, remove_iter);
985 } else { // not remove
986 iter = g_slist_next(iter);
991 /* 0.1 Lock Traces */
996 iter_trace<lttv_traceset_number(tsc->ts);
998 LttvTrace *trace_v = lttv_traceset_get(tsc->ts, iter_trace);
1000 if(lttvwindowtraces_lock(trace_v) != 0) {
1001 g_critical("Foreground processing : Unable to get trace lock");
1002 return TRUE; /* Cannot get lock, try later */
1007 /* 0.2 Seek tracefiles positions to context position */
1008 //g_assert(lttv_process_traceset_seek_position(tsc, sync_position) == 0);
1009 lttv_process_traceset_synchronize_tracefiles(tsc);
1012 /* Events processing algorithm implementation */
1013 /* Warning : the gtk_events_pending takes a LOT of cpu time. So what we do
1014 * instead is to leave the control to GTK and take it back.
1016 /* A. Servicing loop */
1017 //while( (g_slist_length(list_in) != 0 || g_slist_length(list_out) != 0)) {
1018 if((g_slist_length(list_in) != 0 || g_slist_length(list_out) != 0)) {
1020 /* 1. If list_in is empty (need a seek) */
1021 if( g_slist_length(list_in) == 0 ) {
1023 /* list in is empty, need a seek */
1025 /* 1.1 Add requests to list_in */
1026 GSList *ltime = NULL;
1027 GSList *lpos = NULL;
1028 GSList *iter = NULL;
1030 /* 1.1.1 Find all time requests with the lowest start time in list_out
1033 if(g_slist_length(list_out) > 0)
1034 ltime = g_slist_append(ltime, g_slist_nth_data(list_out, 0));
1035 for(iter=g_slist_nth(list_out,1);iter!=NULL;iter=g_slist_next(iter)) {
1036 /* Find all time requests with the lowest start time in list_out */
1037 EventsRequest *event_request_ltime = (EventsRequest*)g_slist_nth_data(ltime, 0);
1038 EventsRequest *event_request_list_out = (EventsRequest*)iter->data;
1041 comp = ltt_time_compare(event_request_ltime->start_time,
1042 event_request_list_out->start_time);
1044 ltime = g_slist_append(ltime, event_request_list_out);
1046 /* Remove all elements from ltime, and add current */
1047 while(ltime != NULL)
1048 ltime = g_slist_delete_link(ltime, g_slist_nth(ltime, 0));
1049 ltime = g_slist_append(ltime, event_request_list_out);
1053 /* 1.1.2 Find all position requests with the lowest position in list_out
1056 if(g_slist_length(list_out) > 0)
1057 lpos = g_slist_append(lpos, g_slist_nth_data(list_out, 0));
1058 for(iter=g_slist_nth(list_out,1);iter!=NULL;iter=g_slist_next(iter)) {
1059 /* Find all position requests with the lowest position in list_out */
1060 EventsRequest *event_request_lpos = (EventsRequest*)g_slist_nth_data(lpos, 0);
1061 EventsRequest *event_request_list_out = (EventsRequest*)iter->data;
1064 if(event_request_lpos->start_position != NULL
1065 && event_request_list_out->start_position != NULL)
1067 comp = lttv_traceset_context_pos_pos_compare
1068 (event_request_lpos->start_position,
1069 event_request_list_out->start_position);
1074 lpos = g_slist_append(lpos, event_request_list_out);
1076 /* Remove all elements from lpos, and add current */
1078 lpos = g_slist_delete_link(lpos, g_slist_nth(lpos, 0));
1079 lpos = g_slist_append(lpos, event_request_list_out);
1084 EventsRequest *event_request_lpos = (EventsRequest*)g_slist_nth_data(lpos, 0);
1085 EventsRequest *event_request_ltime = (EventsRequest*)g_slist_nth_data(ltime, 0);
1086 LttTime lpos_start_time;
1088 if(event_request_lpos != NULL
1089 && event_request_lpos->start_position != NULL) {
1090 lpos_start_time = lttv_traceset_context_position_get_time(
1091 event_request_lpos->start_position);
1094 /* 1.1.3 If lpos.start time < ltime */
1095 if(event_request_lpos != NULL
1096 && event_request_lpos->start_position != NULL
1097 && ltt_time_compare(lpos_start_time,
1098 event_request_ltime->start_time)<0) {
1099 /* Add lpos to list_in, remove them from list_out */
1100 for(iter=lpos;iter!=NULL;iter=g_slist_next(iter)) {
1101 /* Add to list_in */
1102 EventsRequest *event_request_lpos =
1103 (EventsRequest*)iter->data;
1105 list_in = g_slist_append(list_in, event_request_lpos);
1106 /* Remove from list_out */
1107 list_out = g_slist_remove(list_out, event_request_lpos);
1110 /* 1.1.4 (lpos.start time >= ltime) */
1111 /* Add ltime to list_in, remove them from list_out */
1113 for(iter=ltime;iter!=NULL;iter=g_slist_next(iter)) {
1114 /* Add to list_in */
1115 EventsRequest *event_request_ltime =
1116 (EventsRequest*)iter->data;
1118 list_in = g_slist_append(list_in, event_request_ltime);
1119 /* Remove from list_out */
1120 list_out = g_slist_remove(list_out, event_request_ltime);
1125 g_slist_free(ltime);
1130 tfc = lttv_traceset_context_get_current_tfc(tsc);
1131 g_assert(g_slist_length(list_in)>0);
1132 EventsRequest *events_request = g_slist_nth_data(list_in, 0);
1135 /* 1.2.1 If first request in list_in is a time request */
1136 if(events_request->start_position == NULL) {
1137 /* - If first req in list_in start time != current time */
1138 if(tfc == NULL || ltt_time_compare(events_request->start_time,
1139 tfc->timestamp) != 0)
1140 /* - Seek to that time */
1141 g_debug("SEEK TIME : %lu, %lu", events_request->start_time.tv_sec,
1142 events_request->start_time.tv_nsec);
1143 //lttv_process_traceset_seek_time(tsc, events_request->start_time);
1144 lttv_state_traceset_seek_time_closest(LTTV_TRACESET_STATE(tsc),
1145 events_request->start_time);
1147 /* Process the traceset with only state hooks */
1149 lttv_process_traceset_middle(tsc,
1150 events_request->start_time,
1153 g_assert(seek_count < LTTV_STATE_SAVE_INTERVAL);
1159 LttvTracefileContext *tfc =
1160 lttv_traceset_context_get_current_tfc(tsc);
1161 /* Else, the first request in list_in is a position request */
1162 /* If first req in list_in pos != current pos */
1163 g_assert(events_request->start_position != NULL);
1164 g_debug("SEEK POS time : %lu, %lu",
1165 lttv_traceset_context_position_get_time(
1166 events_request->start_position).tv_sec,
1167 lttv_traceset_context_position_get_time(
1168 events_request->start_position).tv_nsec);
1171 g_debug("SEEK POS context time : %lu, %lu",
1172 tfc->timestamp.tv_sec,
1173 tfc->timestamp.tv_nsec);
1175 g_debug("SEEK POS context time : %lu, %lu",
1176 ltt_time_infinite.tv_sec,
1177 ltt_time_infinite.tv_nsec);
1179 g_assert(events_request->start_position != NULL);
1180 if(lttv_traceset_context_ctx_pos_compare(tsc,
1181 events_request->start_position) != 0) {
1182 /* 1.2.2.1 Seek to that position */
1183 g_debug("SEEK POSITION");
1184 //lttv_process_traceset_seek_position(tsc, events_request->start_position);
1185 pos_time = lttv_traceset_context_position_get_time(
1186 events_request->start_position);
1188 lttv_state_traceset_seek_time_closest(LTTV_TRACESET_STATE(tsc),
1191 /* Process the traceset with only state hooks */
1193 lttv_process_traceset_middle(tsc,
1196 events_request->start_position);
1197 g_assert(lttv_traceset_context_ctx_pos_compare(tsc,
1198 events_request->start_position) == 0);
1205 /* 1.3 Add hooks and call before request for all list_in members */
1207 GSList *iter = NULL;
1209 for(iter=list_in;iter!=NULL;iter=g_slist_next(iter)) {
1210 EventsRequest *events_request = (EventsRequest*)iter->data;
1211 /* 1.3.1 If !servicing */
1212 if(events_request->servicing == FALSE) {
1213 /* - begin request hooks called
1214 * - servicing = TRUE
1216 lttv_hooks_call(events_request->before_request, (gpointer)tsc);
1217 events_request->servicing = TRUE;
1219 /* 1.3.2 call before chunk
1220 * 1.3.3 events hooks added
1222 if(events_request->trace == -1)
1223 lttv_process_traceset_begin(tsc,
1224 events_request->before_chunk_traceset,
1225 events_request->before_chunk_trace,
1226 events_request->before_chunk_tracefile,
1227 events_request->event,
1228 events_request->event_by_id);
1230 guint nb_trace = lttv_traceset_number(tsc->ts);
1231 g_assert((guint)events_request->trace < nb_trace &&
1232 events_request->trace > -1);
1233 LttvTraceContext *tc = tsc->traces[events_request->trace];
1235 lttv_hooks_call(events_request->before_chunk_traceset, tsc);
1237 lttv_trace_context_add_hooks(tc,
1238 events_request->before_chunk_trace,
1239 events_request->before_chunk_tracefile,
1240 events_request->event,
1241 events_request->event_by_id);
1246 /* 2. Else, list_in is not empty, we continue a read */
1249 /* 2.0 For each req of list_in */
1250 GSList *iter = list_in;
1252 while(iter != NULL) {
1254 EventsRequest *events_request = (EventsRequest *)iter->data;
1256 /* - Call before chunk
1257 * - events hooks added
1259 if(events_request->trace == -1)
1260 lttv_process_traceset_begin(tsc,
1261 events_request->before_chunk_traceset,
1262 events_request->before_chunk_trace,
1263 events_request->before_chunk_tracefile,
1264 events_request->event,
1265 events_request->event_by_id);
1267 guint nb_trace = lttv_traceset_number(tsc->ts);
1268 g_assert((guint)events_request->trace < nb_trace &&
1269 events_request->trace > -1);
1270 LttvTraceContext *tc = tsc->traces[events_request->trace];
1272 lttv_hooks_call(events_request->before_chunk_traceset, tsc);
1274 lttv_trace_context_add_hooks(tc,
1275 events_request->before_chunk_trace,
1276 events_request->before_chunk_tracefile,
1277 events_request->event,
1278 events_request->event_by_id);
1281 iter = g_slist_next(iter);
1286 tfc = lttv_traceset_context_get_current_tfc(tsc);
1288 /* 2.1 For each req of list_out */
1289 GSList *iter = list_out;
1291 while(iter != NULL) {
1293 gboolean remove = FALSE;
1294 gboolean free_data = FALSE;
1295 EventsRequest *events_request = (EventsRequest *)iter->data;
1297 /* if req.start time == current context time
1298 * or req.start position == current position*/
1299 if( ltt_time_compare(events_request->start_time,
1300 tfc->timestamp) == 0
1302 (events_request->start_position != NULL
1304 lttv_traceset_context_ctx_pos_compare(tsc,
1305 events_request->start_position) == 0)
1307 /* - Add to list_in, remove from list_out */
1308 list_in = g_slist_append(list_in, events_request);
1312 /* - If !servicing */
1313 if(events_request->servicing == FALSE) {
1314 /* - begin request hooks called
1315 * - servicing = TRUE
1317 lttv_hooks_call(events_request->before_request, (gpointer)tsc);
1318 events_request->servicing = TRUE;
1320 /* call before chunk
1321 * events hooks added
1323 if(events_request->trace == -1)
1324 lttv_process_traceset_begin(tsc,
1325 events_request->before_chunk_traceset,
1326 events_request->before_chunk_trace,
1327 events_request->before_chunk_tracefile,
1328 events_request->event,
1329 events_request->event_by_id);
1331 guint nb_trace = lttv_traceset_number(tsc->ts);
1332 g_assert((guint)events_request->trace < nb_trace &&
1333 events_request->trace > -1);
1334 LttvTraceContext *tc = tsc->traces[events_request->trace];
1336 lttv_hooks_call(events_request->before_chunk_traceset, tsc);
1338 lttv_trace_context_add_hooks(tc,
1339 events_request->before_chunk_trace,
1340 events_request->before_chunk_tracefile,
1341 events_request->event,
1342 events_request->event_by_id);
1351 GSList *remove_iter = iter;
1353 iter = g_slist_next(iter);
1354 if(free_data) events_request_free((EventsRequest*)remove_iter->data);
1355 list_out = g_slist_remove_link(list_out, remove_iter);
1356 } else { // not remove
1357 iter = g_slist_next(iter);
1363 /* 3. Find end criterions */
1368 /* 3.1.1 Find lowest end time in list_in */
1369 g_assert(g_slist_length(list_in)>0);
1370 end_time = ((EventsRequest*)g_slist_nth_data(list_in,0))->end_time;
1372 for(iter=g_slist_nth(list_in,1);iter!=NULL;iter=g_slist_next(iter)) {
1373 EventsRequest *events_request = (EventsRequest*)iter->data;
1375 if(ltt_time_compare(events_request->end_time,
1377 end_time = events_request->end_time;
1380 /* 3.1.2 Find lowest start time in list_out */
1381 for(iter=list_out;iter!=NULL;iter=g_slist_next(iter)) {
1382 EventsRequest *events_request = (EventsRequest*)iter->data;
1384 if(ltt_time_compare(events_request->start_time,
1386 end_time = events_request->start_time;
1391 /* 3.2 Number of events */
1393 /* 3.2.1 Find lowest number of events in list_in */
1396 end_nb_events = ((EventsRequest*)g_slist_nth_data(list_in,0))->num_events;
1398 for(iter=g_slist_nth(list_in,1);iter!=NULL;iter=g_slist_next(iter)) {
1399 EventsRequest *events_request = (EventsRequest*)iter->data;
1401 if(events_request->num_events < end_nb_events)
1402 end_nb_events = events_request->num_events;
1405 /* 3.2.2 Use min(CHUNK_NUM_EVENTS, min num events in list_in) as
1408 end_nb_events = MIN(CHUNK_NUM_EVENTS, end_nb_events);
1412 /* 3.3 End position */
1414 /* 3.3.1 Find lowest end position in list_in */
1417 end_position =((EventsRequest*)g_slist_nth_data(list_in,0))->end_position;
1419 for(iter=g_slist_nth(list_in,1);iter!=NULL;iter=g_slist_next(iter)) {
1420 EventsRequest *events_request = (EventsRequest*)iter->data;
1422 if(events_request->end_position != NULL && end_position != NULL &&
1423 lttv_traceset_context_pos_pos_compare(events_request->end_position,
1425 end_position = events_request->end_position;
1430 /* 3.3.2 Find lowest start position in list_out */
1433 for(iter=list_out;iter!=NULL;iter=g_slist_next(iter)) {
1434 EventsRequest *events_request = (EventsRequest*)iter->data;
1436 if(events_request->end_position != NULL && end_position != NULL &&
1437 lttv_traceset_context_pos_pos_compare(events_request->end_position,
1439 end_position = events_request->end_position;
1444 /* 4. Call process traceset middle */
1445 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);
1446 count = lttv_process_traceset_middle(tsc, end_time, end_nb_events, end_position);
1448 tfc = lttv_traceset_context_get_current_tfc(tsc);
1450 g_debug("Context time after middle : %lu, %lu", tfc->timestamp.tv_sec,
1451 tfc->timestamp.tv_nsec);
1453 g_debug("End of trace reached after middle.");
1457 /* 5. After process traceset middle */
1458 tfc = lttv_traceset_context_get_current_tfc(tsc);
1460 /* - if current context time > traceset.end time */
1461 if(tfc == NULL || ltt_time_compare(tfc->timestamp,
1462 tsc->time_span.end_time) > 0) {
1463 /* - For each req in list_in */
1464 GSList *iter = list_in;
1466 while(iter != NULL) {
1468 gboolean remove = FALSE;
1469 gboolean free_data = FALSE;
1470 EventsRequest *events_request = (EventsRequest *)iter->data;
1472 /* - Remove events hooks for req
1473 * - Call end chunk for req
1476 if(events_request->trace == -1)
1477 lttv_process_traceset_end(tsc,
1478 events_request->after_chunk_traceset,
1479 events_request->after_chunk_trace,
1480 events_request->after_chunk_tracefile,
1481 events_request->event,
1482 events_request->event_by_id);
1485 guint nb_trace = lttv_traceset_number(tsc->ts);
1486 g_assert(events_request->trace < nb_trace &&
1487 events_request->trace > -1);
1488 LttvTraceContext *tc = tsc->traces[events_request->trace];
1490 lttv_trace_context_remove_hooks(tc,
1491 events_request->after_chunk_trace,
1492 events_request->after_chunk_tracefile,
1493 events_request->event,
1494 events_request->event_by_id);
1495 lttv_hooks_call(events_request->after_chunk_traceset, tsc);
1500 /* - Call end request for req */
1501 lttv_hooks_call(events_request->after_request, (gpointer)tsc);
1503 /* - remove req from list_in */
1504 /* Destroy the request */
1511 GSList *remove_iter = iter;
1513 iter = g_slist_next(iter);
1514 if(free_data) events_request_free((EventsRequest*)remove_iter->data);
1515 list_in = g_slist_remove_link(list_in, remove_iter);
1516 } else { // not remove
1517 iter = g_slist_next(iter);
1522 /* 5.1 For each req in list_in */
1523 GSList *iter = list_in;
1525 while(iter != NULL) {
1527 gboolean remove = FALSE;
1528 gboolean free_data = FALSE;
1529 EventsRequest *events_request = (EventsRequest *)iter->data;
1531 /* - Remove events hooks for req
1532 * - Call end chunk for req
1534 if(events_request->trace == -1)
1535 lttv_process_traceset_end(tsc,
1536 events_request->after_chunk_traceset,
1537 events_request->after_chunk_trace,
1538 events_request->after_chunk_tracefile,
1539 events_request->event,
1540 events_request->event_by_id);
1543 guint nb_trace = lttv_traceset_number(tsc->ts);
1544 g_assert(events_request->trace < nb_trace &&
1545 events_request->trace > -1);
1546 LttvTraceContext *tc = tsc->traces[events_request->trace];
1548 lttv_trace_context_remove_hooks(tc,
1549 events_request->after_chunk_trace,
1550 events_request->after_chunk_tracefile,
1551 events_request->event,
1552 events_request->event_by_id);
1554 lttv_hooks_call(events_request->after_chunk_traceset, tsc);
1557 /* - req.num -= count */
1558 g_assert(events_request->num_events >= count);
1559 events_request->num_events -= count;
1561 g_assert(tfc != NULL);
1562 /* - if req.num == 0
1564 * current context time >= req.end time
1566 * req.end pos == current pos
1568 * req.stop_flag == TRUE
1570 if( events_request->num_events == 0
1572 events_request->stop_flag == TRUE
1574 ltt_time_compare(tfc->timestamp,
1575 events_request->end_time) >= 0
1577 (events_request->end_position != NULL
1579 lttv_traceset_context_ctx_pos_compare(tsc,
1580 events_request->end_position) == 0)
1583 g_assert(events_request->servicing == TRUE);
1584 /* - Call end request for req
1585 * - remove req from list_in */
1586 lttv_hooks_call(events_request->after_request, (gpointer)tsc);
1587 /* - remove req from list_in */
1588 /* Destroy the request */
1596 GSList *remove_iter = iter;
1598 iter = g_slist_next(iter);
1599 if(free_data) events_request_free((EventsRequest*)remove_iter->data);
1600 list_in = g_slist_remove_link(list_in, remove_iter);
1601 } else { // not remove
1602 iter = g_slist_next(iter);
1608 /* End of removed servicing loop : leave control to GTK instead. */
1609 // if(gtk_events_pending()) break;
1612 /* B. When interrupted between chunks */
1615 GSList *iter = list_in;
1617 /* 1. for each request in list_in */
1618 while(iter != NULL) {
1620 gboolean remove = FALSE;
1621 gboolean free_data = FALSE;
1622 EventsRequest *events_request = (EventsRequest *)iter->data;
1624 /* 1.1. Use current postition as start position */
1625 if(events_request->start_position != NULL)
1626 lttv_traceset_context_position_destroy(events_request->start_position);
1627 events_request->start_position = lttv_traceset_context_position_new(tsc);
1628 lttv_traceset_context_position_save(tsc, events_request->start_position);
1630 /* 1.2. Remove start time */
1631 events_request->start_time = ltt_time_infinite;
1633 /* 1.3. Move from list_in to list_out */
1636 list_out = g_slist_append(list_out, events_request);
1641 GSList *remove_iter = iter;
1643 iter = g_slist_next(iter);
1644 if(free_data) events_request_free((EventsRequest*)remove_iter->data);
1645 list_in = g_slist_remove_link(list_in, remove_iter);
1646 } else { // not remove
1647 iter = g_slist_next(iter);
1653 /* C Unlock Traces */
1655 lttv_process_traceset_get_sync_data(tsc);
1656 //lttv_traceset_context_position_save(tsc, sync_position);
1661 iter_trace<lttv_traceset_number(tsc->ts);
1663 LttvTrace *trace_v = lttv_traceset_get(tsc->ts, iter_trace);
1665 lttvwindowtraces_unlock(trace_v);
1669 //set the cursor back to normal
1670 gdk_window_set_cursor(win, NULL);
1673 g_assert(g_slist_length(list_in) == 0);
1675 if( g_slist_length(list_out) == 0 ) {
1676 /* Put tab's request pending flag back to normal */
1677 tab->events_request_pending = FALSE;
1678 g_debug("remove the idle fct");
1679 return FALSE; /* Remove the idle function */
1681 g_debug("leave the idle fct");
1682 return TRUE; /* Leave the idle function */
1684 /* We do not use simili-round-robin, it may require to read 1 meg buffers
1685 * again and again if many tracesets use the same tracefiles. */
1686 /* Hack for round-robin idle functions */
1687 /* It will put the idle function at the end of the pool */
1688 /*g_idle_add_full((G_PRIORITY_HIGH_IDLE + 21),
1689 (GSourceFunc)execute_events_requests,
1699 static void lttvwindow_add_trace(Tab *tab, LttvTrace *trace_v)
1701 LttvTraceset *traceset = tab->traceset_info->traceset;
1703 guint num_traces = lttv_traceset_number(traceset);
1705 //Verify if trace is already present.
1706 for(i=0; i<num_traces; i++)
1708 LttvTrace * trace = lttv_traceset_get(traceset, i);
1709 if(trace == trace_v)
1713 //Keep a reference to the traces so they are not freed.
1714 for(i=0; i<lttv_traceset_number(traceset); i++)
1716 LttvTrace * trace = lttv_traceset_get(traceset, i);
1717 lttv_trace_ref(trace);
1720 //remove state update hooks
1721 lttv_state_remove_event_hooks(
1722 (LttvTracesetState*)tab->traceset_info->traceset_context);
1724 lttv_context_fini(LTTV_TRACESET_CONTEXT(
1725 tab->traceset_info->traceset_context));
1726 g_object_unref(tab->traceset_info->traceset_context);
1728 lttv_traceset_add(traceset, trace_v);
1729 lttv_trace_ref(trace_v); /* local ref */
1731 /* Create new context */
1732 tab->traceset_info->traceset_context =
1733 g_object_new(LTTV_TRACESET_STATS_TYPE, NULL);
1735 LTTV_TRACESET_CONTEXT(tab->traceset_info->
1740 //add state update hooks
1741 lttv_state_add_event_hooks(
1742 (LttvTracesetState*)tab->traceset_info->traceset_context);
1743 //Remove local reference to the traces.
1744 for(i=0; i<lttv_traceset_number(traceset); i++)
1746 LttvTrace * trace = lttv_traceset_get(traceset, i);
1747 lttv_trace_unref(trace);
1751 //add_trace_into_traceset_selector(GTK_MULTIVPANED(tab->multivpaned), lttv_trace(trace_v));
1754 /* add_trace adds a trace into the current traceset. It first displays a
1755 * directory selection dialogue to let user choose a trace, then recreates
1756 * tracset_context, and redraws all the viewer of the current tab
1759 void add_trace(GtkWidget * widget, gpointer user_data)
1762 LttvTrace * trace_v;
1763 LttvTraceset * traceset;
1765 char abs_path[PATH_MAX];
1767 MainWindow * mw_data = get_window_data_struct(widget);
1768 GtkWidget * notebook = lookup_widget(widget, "MNotebook");
1770 GtkWidget *page = gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook),
1771 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook)));
1772 LttvPluginTab *ptab;
1776 ptab = create_new_tab(widget, NULL);
1779 ptab = (LttvPluginTab *)g_object_get_data(G_OBJECT(page), "Tab_Plugin");
1783 //GtkDirSelection * file_selector = (GtkDirSelection *)gtk_dir_selection_new("Select a trace");
1784 GtkFileSelection * file_selector = (GtkFileSelection *)gtk_file_selection_new("Select a trace");
1785 gtk_widget_hide( (file_selector)->file_list->parent) ;
1786 gtk_file_selection_hide_fileop_buttons(file_selector);
1787 gtk_window_set_transient_for(GTK_WINDOW(file_selector),
1788 GTK_WINDOW(mw_data->mwindow));
1790 if(remember_trace_dir[0] != '\0')
1791 gtk_file_selection_set_filename(file_selector, remember_trace_dir);
1793 id = gtk_dialog_run(GTK_DIALOG(file_selector));
1795 case GTK_RESPONSE_ACCEPT:
1796 case GTK_RESPONSE_OK:
1797 dir = gtk_file_selection_get_filename (file_selector);
1798 strncpy(remember_trace_dir, dir, PATH_MAX);
1799 strncat(remember_trace_dir, "/", PATH_MAX);
1800 if(!dir || strlen(dir) == 0){
1801 gtk_widget_destroy((GtkWidget*)file_selector);
1804 get_absolute_pathname(dir, abs_path);
1805 trace_v = lttvwindowtraces_get_trace_by_name(abs_path);
1806 if(trace_v == NULL) {
1807 trace = ltt_trace_open(abs_path);
1809 g_warning("cannot open trace %s", abs_path);
1811 GtkWidget *dialogue =
1812 gtk_message_dialog_new(
1813 GTK_WINDOW(gtk_widget_get_toplevel(widget)),
1814 GTK_DIALOG_MODAL|GTK_DIALOG_DESTROY_WITH_PARENT,
1817 "Cannot open trace : maybe you should enter in the trace "
1818 "directory to select it ?");
1819 gtk_dialog_run(GTK_DIALOG(dialogue));
1820 gtk_widget_destroy(dialogue);
1823 trace_v = lttv_trace_new(trace);
1824 lttvwindowtraces_add_trace(trace_v);
1825 lttvwindow_add_trace(tab, trace_v);
1828 lttvwindow_add_trace(tab, trace_v);
1831 gtk_widget_destroy((GtkWidget*)file_selector);
1833 //update current tab
1834 //update_traceset(mw_data);
1836 /* Call the updatetraceset hooks */
1838 traceset = tab->traceset_info->traceset;
1839 SetTraceset(tab, traceset);
1840 // in expose now call_pending_read_hooks(mw_data);
1842 //lttvwindow_report_current_time(mw_data,&(tab->current_time));
1844 case GTK_RESPONSE_REJECT:
1845 case GTK_RESPONSE_CANCEL:
1847 gtk_widget_destroy((GtkWidget*)file_selector);
1852 /* remove_trace removes a trace from the current traceset if all viewers in
1853 * the current tab are not interested in the trace. It first displays a
1854 * dialogue, which shows all traces in the current traceset, to let user choose
1855 * a trace, then it checks if all viewers unselect the trace, if it is true,
1856 * it will remove the trace, recreate the traceset_contex,
1857 * and redraws all the viewer of the current tab. If there is on trace in the
1858 * current traceset, it will delete all viewers of the current tab
1860 * It destroys the filter tree. FIXME... we should request for an update
1864 void remove_trace(GtkWidget *widget, gpointer user_data)
1867 LttvTrace * trace_v;
1868 LttvTraceset * traceset;
1869 gint i, j, nb_trace, index=-1;
1870 char ** name, *remove_trace_name;
1871 MainWindow * mw_data = get_window_data_struct(widget);
1872 GtkWidget * notebook = lookup_widget(widget, "MNotebook");
1874 GtkWidget *page = gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook),
1875 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook)));
1881 LttvPluginTab *ptab;
1882 ptab = (LttvPluginTab *)g_object_get_data(G_OBJECT(page), "Tab_Plugin");
1886 nb_trace =lttv_traceset_number(tab->traceset_info->traceset);
1887 name = g_new(char*,nb_trace);
1888 for(i = 0; i < nb_trace; i++){
1889 trace_v = lttv_traceset_get(tab->traceset_info->traceset, i);
1890 trace = lttv_trace(trace_v);
1891 name[i] = g_quark_to_string(ltt_trace_name(trace));
1894 remove_trace_name = get_remove_trace(mw_data, name, nb_trace);
1897 if(remove_trace_name){
1899 /* yuk, cut n paste from old code.. should be better (MD)*/
1900 for(i = 0; i<nb_trace; i++) {
1901 if(strcmp(remove_trace_name,name[i]) == 0){
1906 traceset = tab->traceset_info->traceset;
1907 //Keep a reference to the traces so they are not freed.
1908 for(j=0; j<lttv_traceset_number(traceset); j++)
1910 LttvTrace * trace = lttv_traceset_get(traceset, j);
1911 lttv_trace_ref(trace);
1914 //remove state update hooks
1915 lttv_state_remove_event_hooks(
1916 (LttvTracesetState*)tab->traceset_info->traceset_context);
1917 lttv_context_fini(LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context));
1918 g_object_unref(tab->traceset_info->traceset_context);
1920 trace_v = lttv_traceset_get(traceset, index);
1922 lttv_traceset_remove(traceset, index);
1923 lttv_trace_unref(trace_v); // Remove local reference
1925 if(lttv_trace_get_ref_number(trace_v) <= 1) {
1926 /* ref 1 : lttvwindowtraces only*/
1927 ltt_trace_close(lttv_trace(trace_v));
1928 /* lttvwindowtraces_remove_trace takes care of destroying
1929 * the traceset linked with the trace_v and also of destroying
1930 * the trace_v at the same time.
1932 lttvwindowtraces_remove_trace(trace_v);
1935 tab->traceset_info->traceset_context =
1936 g_object_new(LTTV_TRACESET_STATS_TYPE, NULL);
1938 LTTV_TRACESET_CONTEXT(tab->
1939 traceset_info->traceset_context),traceset);
1940 //add state update hooks
1941 lttv_state_add_event_hooks(
1942 (LttvTracesetState*)tab->traceset_info->traceset_context);
1944 //Remove local reference to the traces.
1945 for(j=0; j<lttv_traceset_number(traceset); j++)
1947 LttvTrace * trace = lttv_traceset_get(traceset, j);
1948 lttv_trace_unref(trace);
1951 SetTraceset(tab, (gpointer)traceset);
1957 void remove_trace(GtkWidget * widget, gpointer user_data)
1960 LttvTrace * trace_v;
1961 LttvTraceset * traceset;
1962 gint i, j, nb_trace;
1963 char ** name, *remove_trace_name;
1964 MainWindow * mw_data = get_window_data_struct(widget);
1965 LttvTracesetSelector * s;
1966 LttvTraceSelector * t;
1969 GtkWidget * notebook = lookup_widget(widget, "MNotebook");
1971 GtkWidget *page = gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook),
1972 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook)));
1978 tab = (Tab *)g_object_get_data(G_OBJECT(page), "Tab_Info");
1981 nb_trace =lttv_traceset_number(tab->traceset_info->traceset);
1982 name = g_new(char*,nb_trace);
1983 for(i = 0; i < nb_trace; i++){
1984 trace_v = lttv_traceset_get(tab->traceset_info->traceset, i);
1985 trace = lttv_trace(trace_v);
1986 name[i] = ltt_trace_name(trace);
1989 remove_trace_name = get_remove_trace(name, nb_trace);
1991 if(remove_trace_name){
1992 for(i=0; i<nb_trace; i++){
1993 if(strcmp(remove_trace_name,name[i]) == 0){
1994 //unselect the trace from the current viewer
1996 w = gtk_multivpaned_get_widget(GTK_MULTIVPANED(tab->multivpaned));
1998 s = g_object_get_data(G_OBJECT(w), "Traceset_Selector");
2000 t = lttv_traceset_selector_trace_get(s,i);
2001 lttv_trace_selector_set_selected(t, FALSE);
2004 //check if other viewers select the trace
2005 w = gtk_multivpaned_get_first_widget(GTK_MULTIVPANED(tab->multivpaned));
2007 s = g_object_get_data(G_OBJECT(w), "Traceset_Selector");
2009 t = lttv_traceset_selector_trace_get(s,i);
2010 selected = lttv_trace_selector_get_selected(t);
2013 w = gtk_multivpaned_get_next_widget(GTK_MULTIVPANED(tab->multivpaned));
2015 }else selected = FALSE;
2017 //if no viewer selects the trace, remove it
2019 remove_trace_from_traceset_selector(GTK_MULTIVPANED(tab->multivpaned), i);
2021 traceset = tab->traceset_info->traceset;
2022 //Keep a reference to the traces so they are not freed.
2023 for(j=0; j<lttv_traceset_number(traceset); j++)
2025 LttvTrace * trace = lttv_traceset_get(traceset, j);
2026 lttv_trace_ref(trace);
2029 //remove state update hooks
2030 lttv_state_remove_event_hooks(
2031 (LttvTracesetState*)tab->traceset_info->traceset_context);
2032 lttv_context_fini(LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context));
2033 g_object_unref(tab->traceset_info->traceset_context);
2036 trace_v = lttv_traceset_get(traceset, i);
2038 if(lttv_trace_get_ref_number(trace_v) <= 2) {
2039 /* ref 2 : traceset, local */
2040 lttvwindowtraces_remove_trace(trace_v);
2041 ltt_trace_close(lttv_trace(trace_v));
2044 lttv_traceset_remove(traceset, i);
2045 lttv_trace_unref(trace_v); // Remove local reference
2047 if(!lttv_trace_get_ref_number(trace_v))
2048 lttv_trace_destroy(trace_v);
2050 tab->traceset_info->traceset_context =
2051 g_object_new(LTTV_TRACESET_STATS_TYPE, NULL);
2053 LTTV_TRACESET_CONTEXT(tab->
2054 traceset_info->traceset_context),traceset);
2055 //add state update hooks
2056 lttv_state_add_event_hooks(
2057 (LttvTracesetState*)tab->traceset_info->traceset_context);
2059 //Remove local reference to the traces.
2060 for(j=0; j<lttv_traceset_number(traceset); j++)
2062 LttvTrace * trace = lttv_traceset_get(traceset, j);
2063 lttv_trace_unref(trace);
2067 //update current tab
2068 //update_traceset(mw_data);
2071 SetTraceset(tab, (gpointer)traceset);
2072 // in expose now call_pending_read_hooks(mw_data);
2074 //lttvwindow_report_current_time(mw_data,&(tab->current_time));
2077 // while(tab->multi_vpaned->num_children){
2078 // gtk_multi_vpaned_widget_delete(tab->multi_vpaned);
2092 /* Redraw all the viewers in the current tab */
2093 void redraw(GtkWidget *widget, gpointer user_data)
2095 GtkWidget * notebook = lookup_widget(widget, "MNotebook");
2096 GtkWidget *page = gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook),
2097 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook)));
2102 LttvPluginTab *ptab;
2103 ptab = (LttvPluginTab *)g_object_get_data(G_OBJECT(page), "Tab_Plugin");
2108 LttvAttributeValue value;
2110 g_assert(lttv_iattribute_find_by_path(tab->attributes, "hooks/redraw", LTTV_POINTER, &value));
2112 tmp = (LttvHooks*)*(value.v_pointer);
2114 lttv_hooks_call(tmp,NULL);
2118 void continue_processing(GtkWidget *widget, gpointer user_data)
2120 GtkWidget * notebook = lookup_widget(widget, "MNotebook");
2121 GtkWidget *page = gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook),
2122 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook)));
2127 LttvPluginTab *ptab;
2128 ptab = (LttvPluginTab *)g_object_get_data(G_OBJECT(page), "Tab_Plugin");
2133 LttvAttributeValue value;
2135 g_assert(lttv_iattribute_find_by_path(tab->attributes,
2136 "hooks/continue", LTTV_POINTER, &value));
2138 tmp = (LttvHooks*)*(value.v_pointer);
2140 lttv_hooks_call(tmp,NULL);
2143 /* Stop the processing for the calling main window's current tab.
2144 * It removes every processing requests that are in its list. It does not call
2145 * the end request hooks, because the request is not finished.
2148 void stop_processing(GtkWidget *widget, gpointer user_data)
2150 GtkWidget * notebook = lookup_widget(widget, "MNotebook");
2151 GtkWidget *page = gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook),
2152 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook)));
2157 LttvPluginTab *ptab;
2158 ptab = (LttvPluginTab *)g_object_get_data(G_OBJECT(page), "Tab_Plugin");
2161 GSList *iter = tab->events_requests;
2163 while(iter != NULL) {
2164 GSList *remove_iter = iter;
2165 iter = g_slist_next(iter);
2167 g_free(remove_iter->data);
2168 tab->events_requests =
2169 g_slist_remove_link(tab->events_requests, remove_iter);
2171 tab->events_request_pending = FALSE;
2172 tab->stop_foreground = TRUE;
2173 g_idle_remove_by_data(tab);
2174 g_assert(g_slist_length(tab->events_requests) == 0);
2178 /* save will save the traceset to a file
2179 * Not implemented yet FIXME
2182 void save(GtkWidget * widget, gpointer user_data)
2187 void save_as(GtkWidget * widget, gpointer user_data)
2189 g_info("Save as\n");
2193 /* zoom will change the time_window of all the viewers of the
2194 * current tab, and redisplay them. The main functionality is to
2195 * determine the new time_window of the current tab
2198 void zoom(GtkWidget * widget, double size)
2200 TimeInterval time_span;
2201 TimeWindow new_time_window;
2202 LttTime current_time, time_delta;
2203 MainWindow * mw_data = get_window_data_struct(widget);
2204 LttvTracesetContext *tsc;
2205 GtkWidget * notebook = lookup_widget(widget, "MNotebook");
2207 GtkWidget *page = gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook),
2208 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook)));
2214 LttvPluginTab *ptab;
2215 ptab = (LttvPluginTab *)g_object_get_data(G_OBJECT(page), "Tab_Plugin");
2219 if(size == 1) return;
2221 tsc = LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context);
2222 time_span = tsc->time_span;
2223 new_time_window = tab->time_window;
2224 current_time = tab->current_time;
2226 time_delta = ltt_time_sub(time_span.end_time,time_span.start_time);
2228 new_time_window.start_time = time_span.start_time;
2229 new_time_window.time_width = time_delta;
2230 new_time_window.time_width_double = ltt_time_to_double(time_delta);
2231 new_time_window.end_time = ltt_time_add(new_time_window.start_time,
2232 new_time_window.time_width) ;
2234 new_time_window.time_width = ltt_time_div(new_time_window.time_width, size);
2235 new_time_window.time_width_double =
2236 ltt_time_to_double(new_time_window.time_width);
2237 if(ltt_time_compare(new_time_window.time_width,time_delta) > 0)
2238 { /* Case where zoom out is bigger than trace length */
2239 new_time_window.start_time = time_span.start_time;
2240 new_time_window.time_width = time_delta;
2241 new_time_window.time_width_double = ltt_time_to_double(time_delta);
2242 new_time_window.end_time = ltt_time_add(new_time_window.start_time,
2243 new_time_window.time_width) ;
2247 /* Center the image on the current time */
2248 new_time_window.start_time =
2249 ltt_time_sub(current_time,
2250 ltt_time_from_double(new_time_window.time_width_double/2.0));
2251 new_time_window.end_time = ltt_time_add(new_time_window.start_time,
2252 new_time_window.time_width) ;
2253 /* If on borders, don't fall off */
2254 if(ltt_time_compare(new_time_window.start_time, time_span.start_time) <0
2255 || ltt_time_compare(new_time_window.start_time, time_span.end_time) >0)
2257 new_time_window.start_time = time_span.start_time;
2258 new_time_window.end_time = ltt_time_add(new_time_window.start_time,
2259 new_time_window.time_width) ;
2263 if(ltt_time_compare(new_time_window.end_time,
2264 time_span.end_time) > 0
2265 || ltt_time_compare(new_time_window.end_time,
2266 time_span.start_time) < 0)
2268 new_time_window.start_time =
2269 ltt_time_sub(time_span.end_time, new_time_window.time_width);
2271 new_time_window.end_time = ltt_time_add(new_time_window.start_time,
2272 new_time_window.time_width) ;
2279 if(ltt_time_compare(new_time_window.time_width, ltt_time_zero) == 0) {
2280 g_warning("Zoom more than 1 ns impossible");
2282 time_change_manager(tab, new_time_window);
2286 void zoom_in(GtkWidget * widget, gpointer user_data)
2291 void zoom_out(GtkWidget * widget, gpointer user_data)
2296 void zoom_extended(GtkWidget * widget, gpointer user_data)
2301 void go_to_time(GtkWidget * widget, gpointer user_data)
2303 g_info("Go to time\n");
2306 void show_time_frame(GtkWidget * widget, gpointer user_data)
2308 g_info("Show time frame\n");
2312 /* callback function */
2315 on_empty_traceset_activate (GtkMenuItem *menuitem,
2318 create_new_window((GtkWidget*)menuitem, user_data, FALSE);
2323 on_clone_traceset_activate (GtkMenuItem *menuitem,
2326 create_new_window((GtkWidget*)menuitem, user_data, TRUE);
2330 /* create_new_tab calls create_tab to construct a new tab in the main window
2333 LttvPluginTab *create_new_tab(GtkWidget* widget, gpointer user_data)
2335 gchar label[PATH_MAX];
2336 MainWindow * mw_data = get_window_data_struct(widget);
2338 GtkNotebook * notebook = (GtkNotebook *)lookup_widget(widget, "MNotebook");
2339 if(notebook == NULL){
2340 g_info("Notebook does not exist\n");
2343 GtkWidget *page = gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook),
2344 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook)));
2350 LttvPluginTab *ptab;
2351 ptab = (LttvPluginTab *)g_object_get_data(G_OBJECT(page), "Tab_Plugin");
2352 copy_tab = ptab->tab;
2355 strcpy(label,"Page");
2356 if(get_label(mw_data, label,"Get the name of the tab","Please input tab's name")) {
2357 LttvPluginTab *ptab;
2359 ptab = g_object_new(LTTV_TYPE_PLUGIN_TAB, NULL);
2360 init_tab (ptab->tab, mw_data, copy_tab, notebook, label);
2361 ptab->parent.top_widget = ptab->tab->top_widget;
2362 g_object_set_data_full(
2363 G_OBJECT(ptab->tab->vbox),
2366 (GDestroyNotify)tab_destructor);
2373 on_tab_activate (GtkMenuItem *menuitem,
2376 create_new_tab((GtkWidget*)menuitem, user_data);
2381 on_open_activate (GtkMenuItem *menuitem,
2384 open_traceset((GtkWidget*)menuitem, user_data);
2389 on_close_activate (GtkMenuItem *menuitem,
2392 MainWindow * mw_data = get_window_data_struct((GtkWidget*)menuitem);
2393 main_window_destructor(mw_data);
2397 /* remove the current tab from the main window
2401 on_close_tab_activate (GtkWidget *widget,
2405 GtkWidget * notebook;
2407 MainWindow * mw_data = get_window_data_struct(widget);
2408 notebook = lookup_widget(widget, "MNotebook");
2409 if(notebook == NULL){
2410 g_info("Notebook does not exist\n");
2414 page_num = gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook));
2416 gtk_notebook_remove_page(GTK_NOTEBOOK(notebook), page_num);
2421 on_close_tab_X_clicked (GtkWidget *widget,
2425 GtkWidget *notebook = lookup_widget(widget, "MNotebook");
2426 if(notebook == NULL){
2427 g_info("Notebook does not exist\n");
2431 if((page_num = gtk_notebook_page_num(GTK_NOTEBOOK(notebook), widget)) != -1)
2432 gtk_notebook_remove_page(GTK_NOTEBOOK(notebook), page_num);
2438 on_add_trace_activate (GtkMenuItem *menuitem,
2441 add_trace((GtkWidget*)menuitem, user_data);
2446 on_remove_trace_activate (GtkMenuItem *menuitem,
2449 remove_trace((GtkWidget*)menuitem, user_data);
2454 on_save_activate (GtkMenuItem *menuitem,
2457 save((GtkWidget*)menuitem, user_data);
2462 on_save_as_activate (GtkMenuItem *menuitem,
2465 save_as((GtkWidget*)menuitem, user_data);
2470 on_quit_activate (GtkMenuItem *menuitem,
2478 on_cut_activate (GtkMenuItem *menuitem,
2486 on_copy_activate (GtkMenuItem *menuitem,
2494 on_paste_activate (GtkMenuItem *menuitem,
2502 on_delete_activate (GtkMenuItem *menuitem,
2510 on_zoom_in_activate (GtkMenuItem *menuitem,
2513 zoom_in((GtkWidget*)menuitem, user_data);
2518 on_zoom_out_activate (GtkMenuItem *menuitem,
2521 zoom_out((GtkWidget*)menuitem, user_data);
2526 on_zoom_extended_activate (GtkMenuItem *menuitem,
2529 zoom_extended((GtkWidget*)menuitem, user_data);
2534 on_go_to_time_activate (GtkMenuItem *menuitem,
2537 go_to_time((GtkWidget*)menuitem, user_data);
2542 on_show_time_frame_activate (GtkMenuItem *menuitem,
2545 show_time_frame((GtkWidget*)menuitem, user_data);
2550 on_move_viewer_up_activate (GtkMenuItem *menuitem,
2553 move_up_viewer((GtkWidget*)menuitem, user_data);
2558 on_move_viewer_down_activate (GtkMenuItem *menuitem,
2561 move_down_viewer((GtkWidget*)menuitem, user_data);
2566 on_remove_viewer_activate (GtkMenuItem *menuitem,
2569 delete_viewer((GtkWidget*)menuitem, user_data);
2573 on_trace_facility_activate (GtkMenuItem *menuitem,
2576 g_info("Trace facility selector: %s\n");
2580 /* Dispaly a file selection dialogue to let user select a library, then call
2581 * lttv_library_load().
2585 on_load_library_activate (GtkMenuItem *menuitem,
2588 GError *error = NULL;
2589 MainWindow * mw_data = get_window_data_struct((GtkWidget*)menuitem);
2591 gchar load_module_path_alter[PATH_MAX];
2595 gchar *load_module_path;
2596 name = g_ptr_array_new();
2597 nb = lttv_library_path_number();
2598 /* ask for the library path */
2602 path = lttv_library_path_get(i);
2603 g_ptr_array_add(name, path);
2606 load_module_path = get_selection(mw_data,
2607 (char **)(name->pdata), name->len,
2608 "Select a library path", "Library paths");
2609 if(load_module_path != NULL)
2610 strncpy(load_module_path_alter, load_module_path, PATH_MAX-1); // -1 for /
2612 g_ptr_array_free(name, TRUE);
2614 if(load_module_path == NULL) return;
2618 /* Make sure the module path ends with a / */
2619 gchar *ptr = load_module_path_alter;
2621 ptr = strchr(ptr, '\0');
2623 if(*(ptr-1) != '/') {
2630 /* Ask for the library to load : list files in the previously selected
2632 gchar str[PATH_MAX];
2635 GtkFileSelection * file_selector =
2636 (GtkFileSelection *)gtk_file_selection_new("Select a module");
2637 gtk_file_selection_set_filename(file_selector, load_module_path_alter);
2638 gtk_file_selection_hide_fileop_buttons(file_selector);
2640 gtk_window_set_transient_for(GTK_WINDOW(file_selector),
2641 GTK_WINDOW(mw_data->mwindow));
2644 id = gtk_dialog_run(GTK_DIALOG(file_selector));
2646 case GTK_RESPONSE_ACCEPT:
2647 case GTK_RESPONSE_OK:
2648 dir = gtk_file_selection_get_selections (file_selector);
2649 strncpy(str,dir[0],PATH_MAX);
2650 strncpy(remember_plugins_dir,dir[0],PATH_MAX);
2651 /* only keep file name */
2653 str1 = strrchr(str,'/');
2656 str1 = strrchr(str,'\\');
2661 if(*str1 == 'l' && *(str1+1)== 'i' && *(str1+2)=='b')
2663 remove info after . */
2667 str2 = strrchr(str2, '.');
2668 if(str2 != NULL) *str2 = '\0';
2670 lttv_module_require(str1, &error);
2672 lttv_library_load(str1, &error);
2673 if(error != NULL) g_warning("%s", error->message);
2674 else g_info("Load library: %s\n", str);
2676 case GTK_RESPONSE_REJECT:
2677 case GTK_RESPONSE_CANCEL:
2679 gtk_widget_destroy((GtkWidget*)file_selector);
2690 /* Display all loaded modules, let user to select a module to unload
2691 * by calling lttv_module_unload
2695 on_unload_library_activate (GtkMenuItem *menuitem,
2698 MainWindow * mw_data = get_window_data_struct((GtkWidget*)menuitem);
2700 LttvLibrary *library = NULL;
2705 name = g_ptr_array_new();
2706 nb = lttv_library_number();
2707 LttvLibraryInfo *lib_info = g_new(LttvLibraryInfo,nb);
2708 /* ask for the library name */
2711 LttvLibrary *iter_lib = lttv_library_get(i);
2712 lttv_library_info(iter_lib, &lib_info[i]);
2714 gchar *path = lib_info[i].name;
2715 g_ptr_array_add(name, path);
2717 lib_name = get_selection(mw_data, (char **)(name->pdata), name->len,
2718 "Select a library", "Libraries");
2719 if(lib_name != NULL) {
2721 if(strcmp(lib_name, lib_info[i].name) == 0) {
2722 library = lttv_library_get(i);
2727 g_ptr_array_free(name, TRUE);
2730 if(lib_name == NULL) return;
2732 if(library != NULL) lttv_library_unload(library);
2736 /* Dispaly a file selection dialogue to let user select a module, then call
2737 * lttv_module_require().
2741 on_load_module_activate (GtkMenuItem *menuitem,
2744 GError *error = NULL;
2745 MainWindow * mw_data = get_window_data_struct((GtkWidget*)menuitem);
2747 LttvLibrary *library = NULL;
2752 name = g_ptr_array_new();
2753 nb = lttv_library_number();
2754 LttvLibraryInfo *lib_info = g_new(LttvLibraryInfo,nb);
2755 /* ask for the library name */
2758 LttvLibrary *iter_lib = lttv_library_get(i);
2759 lttv_library_info(iter_lib, &lib_info[i]);
2761 gchar *path = lib_info[i].name;
2762 g_ptr_array_add(name, path);
2764 lib_name = get_selection(mw_data,(char **)(name->pdata), name->len,
2765 "Select a library", "Libraries");
2766 if(lib_name != NULL) {
2768 if(strcmp(lib_name, lib_info[i].name) == 0) {
2769 library = lttv_library_get(i);
2774 g_ptr_array_free(name, TRUE);
2777 if(lib_name == NULL) return;
2780 //LttvModule *module;
2781 gchar module_name_out[PATH_MAX];
2783 /* Ask for the module to load : list modules in the selected lib */
2787 nb = lttv_library_module_number(library);
2788 LttvModuleInfo *module_info = g_new(LttvModuleInfo,nb);
2789 name = g_ptr_array_new();
2790 /* ask for the module name */
2793 LttvModule *iter_module = lttv_library_module_get(library, i);
2794 lttv_module_info(iter_module, &module_info[i]);
2796 gchar *path = module_info[i].name;
2797 g_ptr_array_add(name, path);
2799 module_name = get_selection(mw_data, (char **)(name->pdata), name->len,
2800 "Select a module", "Modules");
2801 if(module_name != NULL) {
2803 if(strcmp(module_name, module_info[i].name) == 0) {
2804 strncpy(module_name_out, module_name, PATH_MAX);
2805 //module = lttv_library_module_get(i);
2811 g_ptr_array_free(name, TRUE);
2812 g_free(module_info);
2814 if(module_name == NULL) return;
2817 lttv_module_require(module_name_out, &error);
2818 if(error != NULL) g_warning("%s", error->message);
2819 else g_info("Load module: %s", module_name_out);
2826 gchar str[PATH_MAX];
2829 GtkFileSelection * file_selector =
2830 (GtkFileSelection *)gtk_file_selection_new("Select a module");
2831 gtk_file_selection_set_filename(file_selector, load_module_path_alter);
2832 gtk_file_selection_hide_fileop_buttons(file_selector);
2835 id = gtk_dialog_run(GTK_DIALOG(file_selector));
2837 case GTK_RESPONSE_ACCEPT:
2838 case GTK_RESPONSE_OK:
2839 dir = gtk_file_selection_get_selections (file_selector);
2840 strncpy(str,dir[0],PATH_MAX);
2841 strncpy(remember_plugins_dir,dir[0],PATH_MAX);
2843 /* only keep file name */
2845 str1 = strrchr(str,'/');
2848 str1 = strrchr(str,'\\');
2853 if(*str1 == 'l' && *(str1+1)== 'i' && *(str1+2)=='b')
2855 remove info after . */
2859 str2 = strrchr(str2, '.');
2860 if(str2 != NULL) *str2 = '\0';
2862 lttv_module_require(str1, &error);
2864 lttv_library_load(str1, &error);
2865 if(error != NULL) g_warning(error->message);
2866 else g_info("Load library: %s\n", str);
2868 case GTK_RESPONSE_REJECT:
2869 case GTK_RESPONSE_CANCEL:
2871 gtk_widget_destroy((GtkWidget*)file_selector);
2883 /* Display all loaded modules, let user to select a module to unload
2884 * by calling lttv_module_unload
2888 on_unload_module_activate (GtkMenuItem *menuitem,
2891 GError *error = NULL;
2892 MainWindow * mw_data = get_window_data_struct((GtkWidget*)menuitem);
2894 LttvLibrary *library;
2899 name = g_ptr_array_new();
2900 nb = lttv_library_number();
2901 LttvLibraryInfo *lib_info = g_new(LttvLibraryInfo,nb);
2902 /* ask for the library name */
2905 LttvLibrary *iter_lib = lttv_library_get(i);
2906 lttv_library_info(iter_lib, &lib_info[i]);
2908 gchar *path = lib_info[i].name;
2909 g_ptr_array_add(name, path);
2911 lib_name = get_selection(mw_data, (char **)(name->pdata), name->len,
2912 "Select a library", "Libraries");
2913 if(lib_name != NULL) {
2915 if(strcmp(lib_name, lib_info[i].name) == 0) {
2916 library = lttv_library_get(i);
2921 g_ptr_array_free(name, TRUE);
2924 if(lib_name == NULL) return;
2927 LttvModule *module = NULL;
2929 /* Ask for the module to load : list modules in the selected lib */
2933 nb = lttv_library_module_number(library);
2934 LttvModuleInfo *module_info = g_new(LttvModuleInfo,nb);
2935 name = g_ptr_array_new();
2936 /* ask for the module name */
2939 LttvModule *iter_module = lttv_library_module_get(library, i);
2940 lttv_module_info(iter_module, &module_info[i]);
2942 gchar *path = module_info[i].name;
2943 if(module_info[i].use_count > 0) g_ptr_array_add(name, path);
2945 module_name = get_selection(mw_data, (char **)(name->pdata), name->len,
2946 "Select a module", "Modules");
2947 if(module_name != NULL) {
2949 if(strcmp(module_name, module_info[i].name) == 0) {
2950 module = lttv_library_module_get(library, i);
2956 g_ptr_array_free(name, TRUE);
2957 g_free(module_info);
2959 if(module_name == NULL) return;
2962 LttvModuleInfo module_info;
2963 lttv_module_info(module, &module_info);
2964 g_info("Release module: %s\n", module_info.name);
2966 lttv_module_release(module);
2970 /* Display a directory dialogue to let user select a path for library searching
2974 on_add_library_search_path_activate (GtkMenuItem *menuitem,
2977 MainWindow * mw_data = get_window_data_struct((GtkWidget*)menuitem);
2978 //GtkDirSelection * file_selector = (GtkDirSelection *)gtk_dir_selection_new("Select library path");
2979 GtkFileSelection * file_selector = (GtkFileSelection *)gtk_file_selection_new("Select a trace");
2980 gtk_widget_hide( (file_selector)->file_list->parent) ;
2982 gtk_window_set_transient_for(GTK_WINDOW(file_selector),
2983 GTK_WINDOW(mw_data->mwindow));
2988 if(remember_plugins_dir[0] != '\0')
2989 gtk_file_selection_set_filename(file_selector, remember_plugins_dir);
2991 id = gtk_dialog_run(GTK_DIALOG(file_selector));
2993 case GTK_RESPONSE_ACCEPT:
2994 case GTK_RESPONSE_OK:
2995 dir = gtk_file_selection_get_filename (file_selector);
2996 strncpy(remember_plugins_dir,dir,PATH_MAX);
2997 strncat(remember_plugins_dir,"/",PATH_MAX);
2998 lttv_library_path_add(dir);
2999 case GTK_RESPONSE_REJECT:
3000 case GTK_RESPONSE_CANCEL:
3002 gtk_widget_destroy((GtkWidget*)file_selector);
3008 /* Display a directory dialogue to let user select a path for library searching
3012 on_remove_library_search_path_activate (GtkMenuItem *menuitem,
3015 MainWindow * mw_data = get_window_data_struct((GtkWidget*)menuitem);
3017 const char *lib_path;
3022 name = g_ptr_array_new();
3023 nb = lttv_library_path_number();
3024 /* ask for the library name */
3027 gchar *path = lttv_library_path_get(i);
3028 g_ptr_array_add(name, path);
3030 lib_path = get_selection(mw_data, (char **)(name->pdata), name->len,
3031 "Select a library path", "Library paths");
3033 g_ptr_array_free(name, TRUE);
3035 if(lib_path == NULL) return;
3038 lttv_library_path_remove(lib_path);
3042 on_color_activate (GtkMenuItem *menuitem,
3050 on_save_configuration_activate (GtkMenuItem *menuitem,
3053 g_info("Save configuration\n");
3058 on_content_activate (GtkMenuItem *menuitem,
3061 g_info("Content\n");
3066 on_about_close_activate (GtkButton *button,
3069 GtkWidget *about_widget = GTK_WIDGET(user_data);
3071 gtk_widget_destroy(about_widget);
3075 on_about_activate (GtkMenuItem *menuitem,
3078 MainWindow *main_window = get_window_data_struct(GTK_WIDGET(menuitem));
3079 GtkWidget *window_widget = main_window->mwindow;
3080 GtkWidget *about_widget = gtk_window_new(GTK_WINDOW_TOPLEVEL);
3081 GtkWindow *about_window = GTK_WINDOW(about_widget);
3082 gint window_width, window_height;
3084 gtk_window_set_title(about_window, "About Linux Trace Toolkit");
3086 gtk_window_set_resizable(about_window, FALSE);
3087 gtk_window_set_transient_for(about_window, GTK_WINDOW(window_widget));
3088 gtk_window_set_destroy_with_parent(about_window, TRUE);
3089 gtk_window_set_modal(about_window, FALSE);
3091 /* Put the about window at the center of the screen */
3092 gtk_window_get_size(about_window, &window_width, &window_height);
3093 gtk_window_move (about_window,
3094 (gdk_screen_width() - window_width)/2,
3095 (gdk_screen_height() - window_height)/2);
3097 GtkWidget *vbox = gtk_vbox_new(FALSE, 1);
3099 gtk_container_add(GTK_CONTAINER(about_widget), vbox);
3103 GtkWidget *label1 = gtk_label_new("");
3104 gtk_misc_set_padding(GTK_MISC(label1), 10, 20);
3105 gtk_label_set_markup(GTK_LABEL(label1), "\
3106 <big>Linux Trace Toolkit " VERSION "</big>");
3107 gtk_label_set_justify(GTK_LABEL(label1), GTK_JUSTIFY_CENTER);
3109 GtkWidget *label2 = gtk_label_new("");
3110 gtk_misc_set_padding(GTK_MISC(label2), 10, 20);
3111 gtk_label_set_markup(GTK_LABEL(label2), "\
3114 Michel Dagenais (New trace format, lttv main)\n\
3115 Mathieu Desnoyers (Kernel Tracer, Directory structure, build with automake/conf,\n\
3116 lttv gui, control flow view, gui cooperative trace reading\n\
3117 scheduler with interruptible foreground and background\n\
3118 computation, detailed event list (rewrite), trace reading\n\
3119 library (rewrite))\n\
3120 Benoit Des Ligneris, Eric Clement (Cluster adaptation, work in progress)\n\
3121 Xang-Xiu Yang (new trace reading library and converter, lttv gui, \n\
3122 detailed event list and statistics view)\n\
3123 Tom Zanussi (RelayFS)\n\
3125 Inspired from the original Linux Trace Toolkit Visualizer made by\n\
3128 GtkWidget *label3 = gtk_label_new("");
3129 gtk_label_set_markup(GTK_LABEL(label3), "\
3130 Linux Trace Toolkit Viewer, Copyright (C) 2004, 2005, 2006\n\
3132 Mathieu Desnoyers\n\
3134 Linux Trace Toolkit comes with ABSOLUTELY NO WARRANTY.\n\
3135 This is free software, and you are welcome to redistribute it\n\
3136 under certain conditions. See COPYING for details.");
3137 gtk_misc_set_padding(GTK_MISC(label3), 10, 20);
3139 gtk_box_pack_start_defaults(GTK_BOX(vbox), label1);
3140 gtk_box_pack_start_defaults(GTK_BOX(vbox), label2);
3141 gtk_box_pack_start_defaults(GTK_BOX(vbox), label3);
3143 GtkWidget *hbox = gtk_hbox_new(TRUE, 0);
3144 gtk_box_pack_end(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
3145 GtkWidget *close_button = gtk_button_new_with_mnemonic("_Close");
3146 gtk_box_pack_end(GTK_BOX(hbox), close_button, FALSE, FALSE, 0);
3147 gtk_container_set_border_width(GTK_CONTAINER(close_button), 20);
3149 g_signal_connect(G_OBJECT(close_button), "clicked",
3150 G_CALLBACK(on_about_close_activate),
3151 (gpointer)about_widget);
3153 gtk_widget_show_all(about_widget);
3158 on_button_new_clicked (GtkButton *button,
3161 create_new_window((GtkWidget*)button, user_data, TRUE);
3165 on_button_new_tab_clicked (GtkButton *button,
3168 create_new_tab((GtkWidget*)button, user_data);
3172 on_button_open_clicked (GtkButton *button,
3175 open_traceset((GtkWidget*)button, user_data);
3180 on_button_add_trace_clicked (GtkButton *button,
3183 add_trace((GtkWidget*)button, user_data);
3188 on_button_remove_trace_clicked (GtkButton *button,
3191 remove_trace((GtkWidget*)button, user_data);
3195 on_button_redraw_clicked (GtkButton *button,
3198 redraw((GtkWidget*)button, user_data);
3202 on_button_continue_processing_clicked (GtkButton *button,
3205 continue_processing((GtkWidget*)button, user_data);
3209 on_button_stop_processing_clicked (GtkButton *button,
3212 stop_processing((GtkWidget*)button, user_data);
3218 on_button_save_clicked (GtkButton *button,
3221 save((GtkWidget*)button, user_data);
3226 on_button_save_as_clicked (GtkButton *button,
3229 save_as((GtkWidget*)button, user_data);
3234 on_button_zoom_in_clicked (GtkButton *button,
3237 zoom_in((GtkWidget*)button, user_data);
3242 on_button_zoom_out_clicked (GtkButton *button,
3245 zoom_out((GtkWidget*)button, user_data);
3250 on_button_zoom_extended_clicked (GtkButton *button,
3253 zoom_extended((GtkWidget*)button, user_data);
3258 on_button_go_to_time_clicked (GtkButton *button,
3261 go_to_time((GtkWidget*)button, user_data);
3266 on_button_show_time_frame_clicked (GtkButton *button,
3269 show_time_frame((GtkWidget*)button, user_data);
3274 on_button_move_up_clicked (GtkButton *button,
3277 move_up_viewer((GtkWidget*)button, user_data);
3282 on_button_move_down_clicked (GtkButton *button,
3285 move_down_viewer((GtkWidget*)button, user_data);
3290 on_button_delete_viewer_clicked (GtkButton *button,
3293 delete_viewer((GtkWidget*)button, user_data);
3297 on_MWindow_destroy (GtkWidget *widget,
3300 MainWindow *main_window = get_window_data_struct(widget);
3301 LttvIAttribute *attributes = main_window->attributes;
3302 LttvAttributeValue value;
3304 //This is unnecessary, since widgets will be destroyed
3305 //by the main window widget anyway.
3306 //remove_all_menu_toolbar_constructors(main_window, NULL);
3308 g_assert(lttv_iattribute_find_by_path(attributes,
3309 "viewers/menu", LTTV_POINTER, &value));
3310 lttv_menus_destroy((LttvMenus*)*(value.v_pointer));
3312 g_assert(lttv_iattribute_find_by_path(attributes,
3313 "viewers/toolbar", LTTV_POINTER, &value));
3314 lttv_toolbars_destroy((LttvToolbars*)*(value.v_pointer));
3316 g_object_unref(main_window->attributes);
3317 g_main_window_list = g_slist_remove(g_main_window_list, main_window);
3319 g_info("There are now : %d windows\n",g_slist_length(g_main_window_list));
3320 if(g_slist_length(g_main_window_list) == 0)
3325 on_MWindow_configure (GtkWidget *widget,
3326 GdkEventConfigure *event,
3329 MainWindow * mw_data = get_window_data_struct((GtkWidget*)widget);
3331 // MD : removed time width modification upon resizing of the main window.
3332 // The viewers will redraw themselves completely, without time interval
3335 if(mw_data->window_width){
3336 time_span = LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context)->Time_Span ;
3337 time_win = tab->time_window;
3338 ratio = width / mw_data->window_width;
3339 tab->time_window.time_width = ltt_time_mul(time_win.time_width,ratio);
3340 time = ltt_time_sub(time_span->endTime, time_win.start_time);
3341 if(ltt_time_compare(time, tab->time_window.time_width) < 0){
3342 tab->time_window.time_width = time;
3348 mw_data->window_width = (int)width;
3357 on_MNotebook_switch_page (GtkNotebook *notebook,
3358 GtkNotebookPage *page,
3366 void time_change_manager (Tab *tab,
3367 TimeWindow new_time_window)
3369 /* Only one source of time change */
3370 if(tab->time_manager_lock == TRUE) return;
3372 tab->time_manager_lock = TRUE;
3374 LttvTracesetContext *tsc = LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context);
3375 TimeInterval time_span = tsc->time_span;
3376 LttTime start_time = new_time_window.start_time;
3377 LttTime end_time = new_time_window.end_time;
3378 LttTime time_width = new_time_window.time_width;
3380 g_assert(ltt_time_compare(start_time, end_time) < 0);
3383 GtkAdjustment *adjustment = gtk_range_get_adjustment(GTK_RANGE(tab->scrollbar));
3384 LttTime upper = ltt_time_sub(time_span.end_time, time_span.start_time);
3386 gtk_range_set_increments(GTK_RANGE(tab->scrollbar),
3387 ltt_time_to_double(new_time_window.time_width)
3388 / SCROLL_STEP_PER_PAGE
3389 * NANOSECONDS_PER_SECOND, /* step increment */
3390 ltt_time_to_double(new_time_window.time_width)
3391 * NANOSECONDS_PER_SECOND); /* page increment */
3392 gtk_range_set_range(GTK_RANGE(tab->scrollbar),
3394 ltt_time_to_double(upper)
3395 * NANOSECONDS_PER_SECOND); /* upper */
3397 g_object_set(G_OBJECT(adjustment),
3401 ltt_time_to_double(upper), /* upper */
3403 new_time_window.time_width_double
3404 / SCROLL_STEP_PER_PAGE, /* step increment */
3406 new_time_window.time_width_double,
3407 /* page increment */
3409 new_time_window.time_width_double, /* page size */
3411 gtk_adjustment_changed(adjustment);
3413 // g_object_set(G_OBJECT(adjustment),
3415 // ltt_time_to_double(
3416 // ltt_time_sub(start_time, time_span.start_time))
3419 //gtk_adjustment_value_changed(adjustment);
3420 gtk_range_set_value(GTK_RANGE(tab->scrollbar),
3422 ltt_time_sub(start_time, time_span.start_time)) /* value */);
3424 /* set the time bar. */
3426 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab->MEntry1),
3427 (double)time_span.start_time.tv_sec,
3428 (double)time_span.end_time.tv_sec);
3429 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab->MEntry1),
3430 (double)start_time.tv_sec);
3432 /* start nanoseconds */
3433 if(start_time.tv_sec == time_span.start_time.tv_sec) {
3434 /* can be both beginning and end at the same time. */
3435 if(start_time.tv_sec == time_span.end_time.tv_sec) {
3436 /* If we are at the end, max nsec to end.. -1 (not zero length) */
3437 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab->MEntry2),
3438 (double)time_span.start_time.tv_nsec,
3439 (double)time_span.end_time.tv_nsec-1);
3441 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab->MEntry2),
3442 (double)time_span.start_time.tv_nsec,
3443 (double)NANOSECONDS_PER_SECOND-1);
3445 } else if(start_time.tv_sec == time_span.end_time.tv_sec) {
3446 /* If we are at the end, max nsec to end.. -1 (not zero length) */
3447 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab->MEntry2),
3449 (double)time_span.end_time.tv_nsec-1);
3450 } else /* anywhere else */
3451 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab->MEntry2),
3453 (double)NANOSECONDS_PER_SECOND-1);
3454 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab->MEntry2),
3455 (double)start_time.tv_nsec);
3458 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab->MEntry3),
3459 (double)time_span.start_time.tv_sec,
3460 (double)time_span.end_time.tv_sec);
3461 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab->MEntry3),
3462 (double)end_time.tv_sec);
3464 /* end nanoseconds */
3465 if(end_time.tv_sec == time_span.start_time.tv_sec) {
3466 /* can be both beginning and end at the same time. */
3467 if(end_time.tv_sec == time_span.end_time.tv_sec) {
3468 /* If we are at the end, max nsec to end.. */
3469 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab->MEntry4),
3470 (double)time_span.start_time.tv_nsec+1,
3471 (double)time_span.end_time.tv_nsec);
3473 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab->MEntry4),
3474 (double)time_span.start_time.tv_nsec+1,
3475 (double)NANOSECONDS_PER_SECOND-1);
3478 else if(end_time.tv_sec == time_span.end_time.tv_sec) {
3479 /* If we are at the end, max nsec to end.. */
3480 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab->MEntry4),
3482 (double)time_span.end_time.tv_nsec);
3484 else /* anywhere else */
3485 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab->MEntry4),
3487 (double)NANOSECONDS_PER_SECOND-1);
3488 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab->MEntry4),
3489 (double)end_time.tv_nsec);
3492 if(time_width.tv_nsec == 0) {
3493 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab->MEntry7),
3495 (double)upper.tv_sec);
3497 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab->MEntry7),
3499 (double)upper.tv_sec);
3501 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab->MEntry7),
3502 (double)time_width.tv_sec);
3504 /* width nanoseconds */
3505 if(time_width.tv_sec == upper.tv_sec) {
3506 if(time_width.tv_sec == 0) {
3507 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab->MEntry8),
3509 (double)upper.tv_nsec);
3511 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab->MEntry8),
3513 (double)upper.tv_nsec);
3516 else if(time_width.tv_sec == 0) {
3517 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab->MEntry8),
3519 (double)upper.tv_nsec);
3521 else /* anywhere else */
3522 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab->MEntry8),
3524 (double)NANOSECONDS_PER_SECOND-1);
3525 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab->MEntry8),
3526 (double)time_width.tv_nsec);
3528 /* call viewer hooks for new time window */
3529 set_time_window(tab, &new_time_window);
3531 tab->time_manager_lock = FALSE;
3535 /* value changed for frame start s
3537 * Check time span : if ns is out of range, clip it the nearest good value.
3540 on_MEntry1_value_changed (GtkSpinButton *spinbutton,
3543 Tab *tab =(Tab *)user_data;
3544 LttvTracesetContext * tsc =
3545 LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context);
3546 TimeInterval time_span = tsc->time_span;
3547 gint value = gtk_spin_button_get_value_as_int(spinbutton);
3549 TimeWindow new_time_window = tab->time_window;
3551 LttTime end_time = new_time_window.end_time;
3553 new_time_window.start_time.tv_sec = value;
3555 /* start nanoseconds */
3556 if(new_time_window.start_time.tv_sec == time_span.start_time.tv_sec) {
3557 if(new_time_window.start_time.tv_sec == time_span.end_time.tv_sec) {
3558 if(new_time_window.start_time.tv_nsec > time_span.end_time.tv_nsec)
3559 new_time_window.start_time.tv_nsec = time_span.end_time.tv_nsec-1;
3560 if(new_time_window.start_time.tv_nsec < time_span.start_time.tv_nsec)
3561 new_time_window.start_time.tv_nsec = time_span.start_time.tv_nsec;
3563 if(new_time_window.start_time.tv_nsec < time_span.start_time.tv_nsec)
3564 new_time_window.start_time.tv_nsec = time_span.start_time.tv_nsec;
3567 else if(new_time_window.start_time.tv_sec == time_span.end_time.tv_sec) {
3568 if(new_time_window.start_time.tv_nsec > time_span.end_time.tv_nsec)
3569 new_time_window.start_time.tv_nsec = time_span.end_time.tv_nsec-1;
3572 if(ltt_time_compare(new_time_window.start_time, end_time) >= 0) {
3573 /* Then, we must push back end time : keep the same time width
3574 * if possible, else end traceset time */
3575 end_time = LTT_TIME_MIN(ltt_time_add(new_time_window.start_time,
3576 new_time_window.time_width),
3577 time_span.end_time);
3580 /* Fix the time width to fit start time and end time */
3581 new_time_window.time_width = ltt_time_sub(end_time,
3582 new_time_window.start_time);
3583 new_time_window.time_width_double =
3584 ltt_time_to_double(new_time_window.time_width);
3586 new_time_window.end_time = end_time;
3588 time_change_manager(tab, new_time_window);
3593 on_MEntry2_value_changed (GtkSpinButton *spinbutton,
3596 Tab *tab =(Tab *)user_data;
3597 LttvTracesetContext * tsc =
3598 LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context);
3599 TimeInterval time_span = tsc->time_span;
3600 gint value = gtk_spin_button_get_value_as_int(spinbutton);
3602 TimeWindow new_time_window = tab->time_window;
3604 LttTime end_time = new_time_window.end_time;
3606 new_time_window.start_time.tv_nsec = value;
3608 if(ltt_time_compare(new_time_window.start_time, end_time) >= 0) {
3609 /* Then, we must push back end time : keep the same time width
3610 * if possible, else end traceset time */
3611 end_time = LTT_TIME_MIN(ltt_time_add(new_time_window.start_time,
3612 new_time_window.time_width),
3613 time_span.end_time);
3616 /* Fix the time width to fit start time and end time */
3617 new_time_window.time_width = ltt_time_sub(end_time,
3618 new_time_window.start_time);
3619 new_time_window.time_width_double =
3620 ltt_time_to_double(new_time_window.time_width);
3622 new_time_window.end_time = end_time;
3624 time_change_manager(tab, new_time_window);
3629 on_MEntry3_value_changed (GtkSpinButton *spinbutton,
3632 Tab *tab =(Tab *)user_data;
3633 LttvTracesetContext * tsc =
3634 LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context);
3635 TimeInterval time_span = tsc->time_span;
3636 gint value = gtk_spin_button_get_value_as_int(spinbutton);
3638 TimeWindow new_time_window = tab->time_window;
3640 LttTime end_time = new_time_window.end_time;
3642 end_time.tv_sec = value;
3644 /* end nanoseconds */
3645 if(end_time.tv_sec == time_span.start_time.tv_sec) {
3646 if(end_time.tv_sec == time_span.end_time.tv_sec) {
3647 if(end_time.tv_nsec > time_span.end_time.tv_nsec)
3648 end_time.tv_nsec = time_span.end_time.tv_nsec;
3649 if(end_time.tv_nsec < time_span.start_time.tv_nsec)
3650 end_time.tv_nsec = time_span.start_time.tv_nsec+1;
3652 if(end_time.tv_nsec < time_span.start_time.tv_nsec)
3653 end_time.tv_nsec = time_span.start_time.tv_nsec+1;
3656 else if(end_time.tv_sec == time_span.end_time.tv_sec) {
3657 if(end_time.tv_nsec > time_span.end_time.tv_nsec)
3658 end_time.tv_nsec = time_span.end_time.tv_nsec;
3661 if(ltt_time_compare(new_time_window.start_time, end_time) >= 0) {
3662 /* Then, we must push front start time : keep the same time width
3663 * if possible, else end traceset time */
3664 new_time_window.start_time = LTT_TIME_MAX(
3665 ltt_time_sub(end_time,
3666 new_time_window.time_width),
3667 time_span.start_time);
3670 /* Fix the time width to fit start time and end time */
3671 new_time_window.time_width = ltt_time_sub(end_time,
3672 new_time_window.start_time);
3673 new_time_window.time_width_double =
3674 ltt_time_to_double(new_time_window.time_width);
3676 new_time_window.end_time = end_time;
3678 time_change_manager(tab, new_time_window);
3683 on_MEntry4_value_changed (GtkSpinButton *spinbutton,
3686 Tab *tab =(Tab *)user_data;
3687 LttvTracesetContext * tsc =
3688 LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context);
3689 TimeInterval time_span = tsc->time_span;
3690 gint value = gtk_spin_button_get_value_as_int(spinbutton);
3692 TimeWindow new_time_window = tab->time_window;
3694 LttTime end_time = new_time_window.end_time;
3696 end_time.tv_nsec = value;
3698 if(ltt_time_compare(new_time_window.start_time, end_time) >= 0) {
3699 /* Then, we must push front start time : keep the same time width
3700 * if possible, else end traceset time */
3701 new_time_window.start_time = LTT_TIME_MAX(
3702 ltt_time_sub(end_time,
3703 new_time_window.time_width),
3704 time_span.start_time);
3707 /* Fix the time width to fit start time and end time */
3708 new_time_window.time_width = ltt_time_sub(end_time,
3709 new_time_window.start_time);
3710 new_time_window.time_width_double =
3711 ltt_time_to_double(new_time_window.time_width);
3712 new_time_window.end_time = end_time;
3714 time_change_manager(tab, new_time_window);
3718 /* value changed for time frame interval s
3720 * Check time span : if ns is out of range, clip it the nearest good value.
3723 on_MEntry7_value_changed (GtkSpinButton *spinbutton,
3726 Tab *tab =(Tab *)user_data;
3727 LttvTracesetContext * tsc =
3728 LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context);
3729 TimeInterval time_span = tsc->time_span;
3730 gint value = gtk_spin_button_get_value_as_int(spinbutton);
3731 LttTime current_time, time_delta;
3732 TimeWindow new_time_window = tab->time_window;
3733 current_time = tab->current_time;
3735 time_delta = ltt_time_sub(time_span.end_time,time_span.start_time);
3736 new_time_window.time_width.tv_sec = value;
3737 new_time_window.time_width_double =
3738 ltt_time_to_double(new_time_window.time_width);
3739 if(ltt_time_compare(new_time_window.time_width,time_delta) > 0)
3740 { /* Case where zoom out is bigger than trace length */
3741 new_time_window.start_time = time_span.start_time;
3742 new_time_window.time_width = time_delta;
3743 new_time_window.time_width_double = ltt_time_to_double(time_delta);
3744 new_time_window.end_time = ltt_time_add(new_time_window.start_time,
3745 new_time_window.time_width) ;
3749 /* Center the image on the current time */
3750 new_time_window.start_time =
3751 ltt_time_sub(current_time,
3752 ltt_time_from_double(new_time_window.time_width_double/2.0));
3753 new_time_window.end_time = ltt_time_add(new_time_window.start_time,
3754 new_time_window.time_width) ;
3755 /* If on borders, don't fall off */
3756 if(ltt_time_compare(new_time_window.start_time, time_span.start_time) <0
3757 || ltt_time_compare(new_time_window.start_time, time_span.end_time) >0)
3759 new_time_window.start_time = time_span.start_time;
3760 new_time_window.end_time = ltt_time_add(new_time_window.start_time,
3761 new_time_window.time_width) ;
3765 if(ltt_time_compare(new_time_window.end_time,
3766 time_span.end_time) > 0
3767 || ltt_time_compare(new_time_window.end_time,
3768 time_span.start_time) < 0)
3770 new_time_window.start_time =
3771 ltt_time_sub(time_span.end_time, new_time_window.time_width);
3773 new_time_window.end_time = ltt_time_add(new_time_window.start_time,
3774 new_time_window.time_width) ;
3780 if(ltt_time_compare(new_time_window.time_width, ltt_time_zero) == 0) {
3781 g_warning("Zoom more than 1 ns impossible");
3783 time_change_manager(tab, new_time_window);
3788 on_MEntry8_value_changed (GtkSpinButton *spinbutton,
3791 Tab *tab =(Tab *)user_data;
3792 LttvTracesetContext * tsc =
3793 LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context);
3794 TimeInterval time_span = tsc->time_span;
3795 gint value = gtk_spin_button_get_value_as_int(spinbutton);
3796 LttTime current_time, time_delta;
3797 TimeWindow new_time_window = tab->time_window;
3798 current_time = tab->current_time;
3800 time_delta = ltt_time_sub(time_span.end_time,time_span.start_time);
3801 new_time_window.time_width.tv_nsec = value;
3802 new_time_window.time_width_double =
3803 ltt_time_to_double(new_time_window.time_width);
3804 if(ltt_time_compare(new_time_window.time_width,time_delta) > 0)
3805 { /* Case where zoom out is bigger than trace length */
3806 new_time_window.start_time = time_span.start_time;
3807 new_time_window.time_width = time_delta;
3808 new_time_window.time_width_double = ltt_time_to_double(time_delta);
3809 new_time_window.end_time = ltt_time_add(new_time_window.start_time,
3810 new_time_window.time_width) ;
3814 /* Center the image on the current time */
3815 new_time_window.start_time =
3816 ltt_time_sub(current_time,
3817 ltt_time_from_double(new_time_window.time_width_double/2.0));
3818 new_time_window.end_time = ltt_time_add(new_time_window.start_time,
3819 new_time_window.time_width) ;
3820 /* If on borders, don't fall off */
3821 if(ltt_time_compare(new_time_window.start_time, time_span.start_time) <0
3822 || ltt_time_compare(new_time_window.start_time, time_span.end_time) >0)
3824 new_time_window.start_time = time_span.start_time;
3825 new_time_window.end_time = ltt_time_add(new_time_window.start_time,
3826 new_time_window.time_width) ;
3830 if(ltt_time_compare(new_time_window.end_time,
3831 time_span.end_time) > 0
3832 || ltt_time_compare(new_time_window.end_time,
3833 time_span.start_time) < 0)
3835 new_time_window.start_time =
3836 ltt_time_sub(time_span.end_time, new_time_window.time_width);
3838 new_time_window.end_time = ltt_time_add(new_time_window.start_time,
3839 new_time_window.time_width) ;
3845 if(ltt_time_compare(new_time_window.time_width, ltt_time_zero) == 0) {
3846 g_warning("Zoom more than 1 ns impossible");
3848 time_change_manager(tab, new_time_window);
3854 void current_time_change_manager (Tab *tab,
3855 LttTime new_current_time)
3857 /* Only one source of time change */
3858 if(tab->current_time_manager_lock == TRUE) return;
3860 tab->current_time_manager_lock = TRUE;
3862 LttvTracesetContext *tsc = LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context);
3863 TimeInterval time_span = tsc->time_span;
3865 /* current seconds */
3866 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab->MEntry5),
3867 (double)time_span.start_time.tv_sec,
3868 (double)time_span.end_time.tv_sec);
3869 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab->MEntry5),
3870 (double)new_current_time.tv_sec);
3873 /* start nanoseconds */
3874 if(new_current_time.tv_sec == time_span.start_time.tv_sec) {
3875 /* can be both beginning and end at the same time. */
3876 if(new_current_time.tv_sec == time_span.end_time.tv_sec) {
3877 /* If we are at the end, max nsec to end.. */
3878 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab->MEntry6),
3879 (double)time_span.start_time.tv_nsec,
3880 (double)time_span.end_time.tv_nsec);
3882 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab->MEntry6),
3883 (double)time_span.start_time.tv_nsec,
3884 (double)NANOSECONDS_PER_SECOND-1);
3886 } else if(new_current_time.tv_sec == time_span.end_time.tv_sec) {
3887 /* If we are at the end, max nsec to end.. */
3888 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab->MEntry6),
3890 (double)time_span.end_time.tv_nsec);
3891 } else /* anywhere else */
3892 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab->MEntry6),
3894 (double)NANOSECONDS_PER_SECOND-1);
3896 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab->MEntry6),
3897 (double)new_current_time.tv_nsec);
3899 set_current_time(tab, &new_current_time);
3901 tab->current_time_manager_lock = FALSE;
3904 void current_position_change_manager(Tab *tab,
3905 LttvTracesetContextPosition *pos)
3907 LttvTracesetContext *tsc =
3908 LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context);
3909 TimeInterval time_span = tsc->time_span;
3911 g_assert(lttv_process_traceset_seek_position(tsc, pos) == 0);
3912 LttTime new_time = lttv_traceset_context_position_get_time(pos);
3913 /* Put the context in a state coherent position */
3914 lttv_state_traceset_seek_time_closest((LttvTracesetState*)tsc, ltt_time_zero);
3916 current_time_change_manager(tab, new_time);
3918 set_current_position(tab, pos);
3923 on_MEntry5_value_changed (GtkSpinButton *spinbutton,
3926 Tab *tab = (Tab*)user_data;
3927 LttvTracesetContext * tsc =
3928 LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context);
3929 TimeInterval time_span = tsc->time_span;
3930 gint value = gtk_spin_button_get_value_as_int(spinbutton);
3931 LttTime new_current_time = tab->current_time;
3932 new_current_time.tv_sec = value;
3934 /* current nanoseconds */
3935 if(new_current_time.tv_sec == time_span.start_time.tv_sec) {
3936 if(new_current_time.tv_sec == time_span.end_time.tv_sec) {
3937 if(new_current_time.tv_nsec > time_span.end_time.tv_nsec)
3938 new_current_time.tv_nsec = time_span.end_time.tv_nsec;
3939 if(new_current_time.tv_nsec < time_span.start_time.tv_nsec)
3940 new_current_time.tv_nsec = time_span.start_time.tv_nsec;
3942 if(new_current_time.tv_nsec < time_span.start_time.tv_nsec)
3943 new_current_time.tv_nsec = time_span.start_time.tv_nsec;
3946 else if(new_current_time.tv_sec == time_span.end_time.tv_sec) {
3947 if(new_current_time.tv_nsec > time_span.end_time.tv_nsec)
3948 new_current_time.tv_nsec = time_span.end_time.tv_nsec;
3951 current_time_change_manager(tab, new_current_time);
3955 on_MEntry6_value_changed (GtkSpinButton *spinbutton,
3958 Tab *tab = (Tab*)user_data;
3959 gint value = gtk_spin_button_get_value_as_int(spinbutton);
3960 LttTime new_current_time = tab->current_time;
3961 new_current_time.tv_nsec = value;
3963 current_time_change_manager(tab, new_current_time);
3967 void scroll_value_changed_cb(GtkWidget *scrollbar,
3970 Tab *tab = (Tab *)user_data;
3971 TimeWindow new_time_window;
3973 GtkAdjustment *adjust = gtk_range_get_adjustment(GTK_RANGE(scrollbar));
3974 gdouble value = gtk_adjustment_get_value(adjust);
3975 // gdouble upper, lower, ratio, page_size;
3977 LttvTracesetContext * tsc =
3978 LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context);
3979 TimeInterval time_span = tsc->time_span;
3981 time = ltt_time_add(ltt_time_from_double(value),
3982 time_span.start_time);
3984 new_time_window.start_time = time;
3986 page_size = adjust->page_size;
3988 new_time_window.time_width =
3989 ltt_time_from_double(page_size);
3991 new_time_window.time_width_double =
3994 new_time_window.end_time = ltt_time_add(new_time_window.start_time,
3995 new_time_window.time_width);
3998 time_change_manager(tab, new_time_window);
4000 //time_window = tab->time_window;
4002 lower = adjust->lower;
4003 upper = adjust->upper;
4004 ratio = (value - lower) / (upper - lower);
4005 g_info("lower %lu, upper %lu, value %lu, ratio %lu", lower, upper, value, ratio);
4007 //time = ltt_time_sub(time_span->end_time, time_span->start_time);
4008 //time = ltt_time_mul(time, (float)ratio);
4009 //time = ltt_time_add(time_span->start_time, time);
4010 time = ltt_time_add(ltt_time_from_double(value),
4011 time_span.start_time);
4013 time_window.start_time = time;
4015 page_size = adjust->page_size;
4017 time_window.time_width =
4018 ltt_time_from_double(page_size);
4019 //time = ltt_time_sub(time_span.end_time, time);
4020 //if(ltt_time_compare(time,time_window.time_width) < 0){
4021 // time_window.time_width = time;
4024 /* call viewer hooks for new time window */
4025 set_time_window(tab, &time_window);
4030 /* Display a dialogue showing all eventtypes and traces, let user to select the interested
4031 * eventtypes, tracefiles and traces (filter)
4034 /* Select a trace which will be removed from traceset
4037 char * get_remove_trace(MainWindow *mw_data,
4038 char ** all_trace_name, int nb_trace)
4040 return get_selection(mw_data, all_trace_name, nb_trace,
4041 "Select a trace", "Trace pathname");
4045 /* Select a module which will be loaded
4048 char * get_load_module(MainWindow *mw_data,
4049 char ** load_module_name, int nb_module)
4051 return get_selection(mw_data, load_module_name, nb_module,
4052 "Select a module to load", "Module name");
4058 /* Select a module which will be unloaded
4061 char * get_unload_module(MainWindow *mw_data,
4062 char ** loaded_module_name, int nb_module)
4064 return get_selection(mw_data, loaded_module_name, nb_module,
4065 "Select a module to unload", "Module name");
4069 /* Display a dialogue which shows all selectable items, let user to
4070 * select one of them
4073 char * get_selection(MainWindow *mw_data,
4074 char ** loaded_module_name, int nb_module,
4075 char *title, char * column_title)
4077 GtkWidget * dialogue;
4078 GtkWidget * scroll_win;
4080 GtkListStore * store;
4081 GtkTreeViewColumn * column;
4082 GtkCellRenderer * renderer;
4083 GtkTreeSelection * select;
4086 char * unload_module_name = NULL;
4088 dialogue = gtk_dialog_new_with_buttons(title,
4091 GTK_STOCK_OK,GTK_RESPONSE_ACCEPT,
4092 GTK_STOCK_CANCEL,GTK_RESPONSE_REJECT,
4094 gtk_window_set_default_size((GtkWindow*)dialogue, 500, 200);
4095 gtk_window_set_transient_for(GTK_WINDOW(dialogue),
4096 GTK_WINDOW(mw_data->mwindow));
4098 scroll_win = gtk_scrolled_window_new (NULL, NULL);
4099 gtk_widget_show ( scroll_win);
4100 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll_win),
4101 GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
4103 store = gtk_list_store_new (N_COLUMNS,G_TYPE_STRING);
4104 tree = gtk_tree_view_new_with_model(GTK_TREE_MODEL (store));
4105 gtk_widget_show ( tree);
4106 g_object_unref (G_OBJECT (store));
4108 renderer = gtk_cell_renderer_text_new ();
4109 column = gtk_tree_view_column_new_with_attributes (column_title,
4111 "text", MODULE_COLUMN,
4113 gtk_tree_view_column_set_alignment (column, 0.5);
4114 gtk_tree_view_column_set_fixed_width (column, 150);
4115 gtk_tree_view_append_column (GTK_TREE_VIEW (tree), column);
4117 select = gtk_tree_view_get_selection (GTK_TREE_VIEW (tree));
4118 gtk_tree_selection_set_mode (select, GTK_SELECTION_SINGLE);
4120 gtk_container_add (GTK_CONTAINER (scroll_win), tree);
4122 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialogue)->vbox), scroll_win,TRUE, TRUE,0);
4124 for(i=0;i<nb_module;i++){
4125 gtk_list_store_append (store, &iter);
4126 gtk_list_store_set (store, &iter, MODULE_COLUMN,loaded_module_name[i],-1);
4129 id = gtk_dialog_run(GTK_DIALOG(dialogue));
4130 GtkTreeModel **store_model = (GtkTreeModel**)&store;
4132 case GTK_RESPONSE_ACCEPT:
4133 case GTK_RESPONSE_OK:
4134 if (gtk_tree_selection_get_selected (select, store_model, &iter)){
4135 gtk_tree_model_get ((GtkTreeModel*)store, &iter, MODULE_COLUMN, &unload_module_name, -1);
4137 case GTK_RESPONSE_REJECT:
4138 case GTK_RESPONSE_CANCEL:
4140 gtk_widget_destroy(dialogue);
4144 return unload_module_name;
4148 /* Insert all menu entry and tool buttons into this main window
4153 void add_all_menu_toolbar_constructors(MainWindow * mw, gpointer user_data)
4157 lttvwindow_viewer_constructor constructor;
4158 LttvMenus * global_menu, * instance_menu;
4159 LttvToolbars * global_toolbar, * instance_toolbar;
4160 LttvMenuClosure *menu_item;
4161 LttvToolbarClosure *toolbar_item;
4162 LttvAttributeValue value;
4163 LttvIAttribute *global_attributes = LTTV_IATTRIBUTE(lttv_global_attributes());
4164 LttvIAttribute *attributes = mw->attributes;
4165 GtkWidget * tool_menu_title_menu, *new_widget, *pixmap;
4167 g_assert(lttv_iattribute_find_by_path(global_attributes,
4168 "viewers/menu", LTTV_POINTER, &value));
4169 if(*(value.v_pointer) == NULL)
4170 *(value.v_pointer) = lttv_menus_new();
4171 global_menu = (LttvMenus*)*(value.v_pointer);
4173 g_assert(lttv_iattribute_find_by_path(attributes,
4174 "viewers/menu", LTTV_POINTER, &value));
4175 if(*(value.v_pointer) == NULL)
4176 *(value.v_pointer) = lttv_menus_new();
4177 instance_menu = (LttvMenus*)*(value.v_pointer);
4181 g_assert(lttv_iattribute_find_by_path(global_attributes,
4182 "viewers/toolbar", LTTV_POINTER, &value));
4183 if(*(value.v_pointer) == NULL)
4184 *(value.v_pointer) = lttv_toolbars_new();
4185 global_toolbar = (LttvToolbars*)*(value.v_pointer);
4187 g_assert(lttv_iattribute_find_by_path(attributes,
4188 "viewers/toolbar", LTTV_POINTER, &value));
4189 if(*(value.v_pointer) == NULL)
4190 *(value.v_pointer) = lttv_toolbars_new();
4191 instance_toolbar = (LttvToolbars*)*(value.v_pointer);
4193 /* Add missing menu entries to window instance */
4194 for(i=0;i<global_menu->len;i++) {
4195 menu_item = &g_array_index(global_menu, LttvMenuClosure, i);
4197 //add menu_item to window instance;
4198 constructor = menu_item->con;
4199 tool_menu_title_menu = lookup_widget(mw->mwindow,"ToolMenuTitle_menu");
4201 gtk_menu_item_new_with_mnemonic (menu_item->menu_text);
4202 gtk_container_add (GTK_CONTAINER (tool_menu_title_menu),
4204 g_signal_connect ((gpointer) new_widget, "activate",
4205 G_CALLBACK (insert_viewer_wrap),
4207 gtk_widget_show (new_widget);
4208 lttv_menus_add(instance_menu, menu_item->con,
4209 menu_item->menu_path,
4210 menu_item->menu_text,
4215 /* Add missing toolbar entries to window instance */
4216 for(i=0;i<global_toolbar->len;i++) {
4217 toolbar_item = &g_array_index(global_toolbar, LttvToolbarClosure, i);
4219 //add toolbar_item to window instance;
4220 constructor = toolbar_item->con;
4221 tool_menu_title_menu = lookup_widget(mw->mwindow,"MToolbar1");
4222 pixbuf = gdk_pixbuf_new_from_xpm_data((const char**)toolbar_item->pixmap);
4223 pixmap = gtk_image_new_from_pixbuf(pixbuf);
4225 gtk_toolbar_append_element (GTK_TOOLBAR (tool_menu_title_menu),
4226 GTK_TOOLBAR_CHILD_BUTTON,
4229 toolbar_item->tooltip, NULL,
4230 pixmap, NULL, NULL);
4231 gtk_label_set_use_underline(
4232 GTK_LABEL (((GtkToolbarChild*) (
4233 g_list_last (GTK_TOOLBAR
4234 (tool_menu_title_menu)->children)->data))->label),
4236 gtk_container_set_border_width (GTK_CONTAINER (new_widget), 1);
4237 g_signal_connect ((gpointer) new_widget,
4239 G_CALLBACK (insert_viewer_wrap),
4241 gtk_widget_show (new_widget);
4243 lttv_toolbars_add(instance_toolbar, toolbar_item->con,
4244 toolbar_item->tooltip,
4245 toolbar_item->pixmap,
4253 /* Create a main window
4256 MainWindow *construct_main_window(MainWindow * parent)
4258 g_debug("construct_main_window()");
4259 GtkWidget * new_window; /* New generated main window */
4260 MainWindow * new_m_window;/* New main window structure */
4261 GtkNotebook * notebook;
4262 LttvIAttribute *attributes =
4263 LTTV_IATTRIBUTE(g_object_new(LTTV_ATTRIBUTE_TYPE, NULL));
4264 LttvAttributeValue value;
4267 new_m_window = g_new(MainWindow, 1);
4269 // Add the object's information to the module's array
4270 g_main_window_list = g_slist_append(g_main_window_list, new_m_window);
4272 new_window = create_MWindow();
4273 gtk_widget_show (new_window);
4275 new_m_window->mwindow = new_window;
4276 new_m_window->attributes = attributes;
4278 g_assert(lttv_iattribute_find_by_path(attributes,
4279 "viewers/menu", LTTV_POINTER, &value));
4280 *(value.v_pointer) = lttv_menus_new();
4282 g_assert(lttv_iattribute_find_by_path(attributes,
4283 "viewers/toolbar", LTTV_POINTER, &value));
4284 *(value.v_pointer) = lttv_toolbars_new();
4286 add_all_menu_toolbar_constructors(new_m_window, NULL);
4288 g_object_set_data_full(G_OBJECT(new_window),
4290 (gpointer)new_m_window,
4291 (GDestroyNotify)g_free);
4292 //create a default tab
4293 notebook = (GtkNotebook *)lookup_widget(new_m_window->mwindow, "MNotebook");
4294 if(notebook == NULL){
4295 g_info("Notebook does not exist\n");
4296 /* FIXME : destroy partially created widgets */
4297 g_free(new_m_window);
4300 //gtk_notebook_popup_enable (GTK_NOTEBOOK(notebook));
4301 //for now there is no name field in LttvTraceset structure
4302 //Use "Traceset" as the label for the default tab
4304 GtkWidget * parent_notebook = lookup_widget(parent->mwindow, "MNotebook");
4305 GtkWidget *page = gtk_notebook_get_nth_page(GTK_NOTEBOOK(parent_notebook),
4306 gtk_notebook_get_current_page(GTK_NOTEBOOK(parent_notebook)));
4312 LttvPluginTab *ptab;
4313 ptab = (LttvPluginTab *)g_object_get_data(G_OBJECT(page), "Tab_Plugin");
4314 parent_tab = ptab->tab;
4316 LttvPluginTab *ptab = g_object_new(LTTV_TYPE_PLUGIN_TAB, NULL);
4318 new_m_window, parent_tab, notebook, "Traceset");
4319 ptab->parent.top_widget = ptab->tab->top_widget;
4320 g_object_set_data_full(
4321 G_OBJECT(ptab->tab->vbox),
4324 (GDestroyNotify)tab_destructor);
4325 new_tab = ptab->tab;
4327 LttvPluginTab *ptab = g_object_new(LTTV_TYPE_PLUGIN_TAB, NULL);
4328 init_tab(ptab->tab, new_m_window, NULL, notebook, "Traceset");
4329 ptab->parent.top_widget = ptab->tab->top_widget;
4330 g_object_set_data_full(
4331 G_OBJECT(ptab->tab->vbox),
4334 (GDestroyNotify)tab_destructor);
4335 new_tab = ptab->tab;
4338 /* Insert default viewers */
4340 LttvAttributeType type;
4341 LttvAttributeName name;
4342 LttvAttributeValue value;
4343 LttvAttribute *attribute;
4345 LttvIAttribute *attributes_global =
4346 LTTV_IATTRIBUTE(lttv_global_attributes());
4348 g_assert(attribute =
4349 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
4350 LTTV_IATTRIBUTE(attributes_global),
4351 LTTV_VIEWER_CONSTRUCTORS)));
4353 name = g_quark_from_string("guievents");
4354 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute),
4356 if(type == LTTV_POINTER) {
4357 lttvwindow_viewer_constructor viewer_constructor =
4358 (lttvwindow_viewer_constructor)*value.v_pointer;
4359 insert_viewer(new_window, viewer_constructor);
4362 name = g_quark_from_string("guicontrolflow");
4363 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute),
4365 if(type == LTTV_POINTER) {
4366 lttvwindow_viewer_constructor viewer_constructor =
4367 (lttvwindow_viewer_constructor)*value.v_pointer;
4368 insert_viewer(new_window, viewer_constructor);
4371 name = g_quark_from_string("guistatistics");
4372 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute),
4374 if(type == LTTV_POINTER) {
4375 lttvwindow_viewer_constructor viewer_constructor =
4376 (lttvwindow_viewer_constructor)*value.v_pointer;
4377 insert_viewer(new_window, viewer_constructor);
4381 g_info("There are now : %d windows\n",g_slist_length(g_main_window_list));
4383 return new_m_window;
4387 /* Free the memory occupied by a tab structure
4391 void tab_destructor(LttvPluginTab * ptab)
4393 int i, nb, ref_count;
4395 Tab *tab = ptab->tab;
4397 gtk_object_destroy(GTK_OBJECT(tab->tooltips));
4400 g_object_unref(tab->attributes);
4402 if(tab->interrupted_state)
4403 g_object_unref(tab->interrupted_state);
4406 if(tab->traceset_info->traceset_context != NULL){
4407 //remove state update hooks
4408 lttv_state_remove_event_hooks(
4409 (LttvTracesetState*)tab->traceset_info->
4411 lttv_context_fini(LTTV_TRACESET_CONTEXT(tab->traceset_info->
4413 g_object_unref(tab->traceset_info->traceset_context);
4415 if(tab->traceset_info->traceset != NULL) {
4416 nb = lttv_traceset_number(tab->traceset_info->traceset);
4417 for(i = 0 ; i < nb ; i++) {
4418 trace = lttv_traceset_get(tab->traceset_info->traceset, i);
4419 ref_count = lttv_trace_get_ref_number(trace);
4421 ltt_trace_close(lttv_trace(trace));
4425 lttv_traceset_destroy(tab->traceset_info->traceset);
4426 /* Remove the idle events requests processing function of the tab */
4427 g_idle_remove_by_data(tab);
4429 g_slist_free(tab->events_requests);
4430 g_free(tab->traceset_info);
4432 g_object_unref(ptab);
4436 /* Create a tab and insert it into the current main window
4439 void init_tab(Tab *tab, MainWindow * mw, Tab *copy_tab,
4440 GtkNotebook * notebook, char * label)
4444 //LttvFilter *filter = NULL;
4446 //create a new tab data structure
4447 //tab = g_new(Tab,1);
4449 //construct and initialize the traceset_info
4450 tab->traceset_info = g_new(TracesetInfo,1);
4453 tab->traceset_info->traceset =
4454 lttv_traceset_copy(copy_tab->traceset_info->traceset);
4456 /* Copy the previous tab's filter */
4457 /* We can clone the filter, as we copy the trace set also */
4458 /* The filter must always be in sync with the trace set */
4459 tab->filter = lttv_filter_clone(copy_tab->filter);
4461 tab->traceset_info->traceset = lttv_traceset_new();
4465 lttv_attribute_write_xml(
4466 lttv_traceset_attribute(tab->traceset_info->traceset),
4472 tab->time_manager_lock = FALSE;
4473 tab->current_time_manager_lock = FALSE;
4475 //FIXME copy not implemented in lower level
4476 tab->traceset_info->traceset_context =
4477 g_object_new(LTTV_TRACESET_STATS_TYPE, NULL);
4478 g_assert(tab->traceset_info->traceset_context != NULL);
4480 LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context),
4481 tab->traceset_info->traceset);
4482 //add state update hooks
4483 lttv_state_add_event_hooks(
4484 (LttvTracesetState*)tab->traceset_info->traceset_context);
4486 //determine the current_time and time_window of the tab
4488 if(copy_tab != NULL){
4489 tab->time_window = copy_tab->time_window;
4490 tab->current_time = copy_tab->current_time;
4492 tab->time_window.start_time =
4493 LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context)->
4494 time_span.start_time;
4495 if(DEFAULT_TIME_WIDTH_S <
4496 LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context)->
4497 time_span.end_time.tv_sec)
4498 tmp_time.tv_sec = DEFAULT_TIME_WIDTH_S;
4501 LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context)->
4502 time_span.end_time.tv_sec;
4503 tmp_time.tv_nsec = 0;
4504 tab->time_window.time_width = tmp_time ;
4505 tab->current_time.tv_sec =
4506 LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context)->
4507 time_span.start_time.tv_sec;
4508 tab->current_time.tv_nsec =
4509 LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context)->
4510 time_span.start_time.tv_nsec;
4513 tab->attributes = LTTV_IATTRIBUTE(g_object_new(LTTV_ATTRIBUTE_TYPE, NULL));
4514 tab->interrupted_state = g_object_new(LTTV_ATTRIBUTE_TYPE, NULL);
4516 tab->vbox = gtk_vbox_new(FALSE, 2);
4517 tab->top_widget = tab->vbox;
4518 //g_object_set_data_full(G_OBJECT(tab->top_widget), "filter",
4519 // filter, (GDestroyNotify)lttv_filter_destroy);
4521 // g_signal_connect (G_OBJECT(tab->top_widget),
4523 // G_CALLBACK (on_top_notify),
4526 tab->viewer_container = gtk_vbox_new(TRUE, 2);
4527 tab->scrollbar = gtk_hscrollbar_new(NULL);
4528 //tab->multivpaned = gtk_multi_vpaned_new();
4530 gtk_box_pack_start(GTK_BOX(tab->vbox),
4531 tab->viewer_container,
4533 TRUE, /* Give the extra space to the child */
4534 0); /* No padding */
4537 // tab->time_window = copy_tab->time_window;
4538 // tab->current_time = copy_tab->current_time;
4541 /* Create the timebar */
4543 tab->MTimebar = gtk_hbox_new(FALSE, 2);
4544 gtk_widget_show(tab->MTimebar);
4545 tab->tooltips = gtk_tooltips_new();
4547 tab->MEventBox1a = gtk_event_box_new();
4548 gtk_widget_show(tab->MEventBox1a);
4549 gtk_tooltips_set_tip(tab->tooltips, tab->MEventBox1a,
4550 "Paste Start and End Times Here", "");
4551 tab->MText1a = gtk_label_new("Time Frame ");
4552 gtk_widget_show(tab->MText1a);
4553 gtk_container_add(GTK_CONTAINER(tab->MEventBox1a), tab->MText1a);
4554 tab->MEventBox1b = gtk_event_box_new();
4555 gtk_widget_show(tab->MEventBox1b);
4556 gtk_tooltips_set_tip(tab->tooltips, tab->MEventBox1b,
4557 "Paste Start Time Here", "");
4558 tab->MText1b = gtk_label_new("start: ");
4559 gtk_widget_show(tab->MText1b);
4560 gtk_container_add(GTK_CONTAINER(tab->MEventBox1b), tab->MText1b);
4561 tab->MText2 = gtk_label_new("s");
4562 gtk_widget_show(tab->MText2);
4563 tab->MText3a = gtk_label_new("ns");
4564 gtk_widget_show(tab->MText3a);
4566 tab->MEventBox3b = gtk_event_box_new();
4567 gtk_widget_show(tab->MEventBox3b);
4568 gtk_tooltips_set_tip(tab->tooltips, tab->MEventBox3b,
4569 "Paste End Time Here", "");
4570 tab->MText3b = gtk_label_new("end:");
4571 gtk_widget_show(tab->MText3b);
4572 gtk_container_add(GTK_CONTAINER(tab->MEventBox3b), tab->MText3b);
4573 tab->MText4 = gtk_label_new("s");
4574 gtk_widget_show(tab->MText4);
4575 tab->MText5a = gtk_label_new("ns");
4576 gtk_widget_show(tab->MText5a);
4578 tab->MEventBox8 = gtk_event_box_new();
4579 gtk_widget_show(tab->MEventBox8);
4580 gtk_tooltips_set_tip(tab->tooltips, tab->MEventBox8,
4581 "Paste Time Interval here", "");
4582 tab->MText8 = gtk_label_new("Time Interval:");
4583 gtk_widget_show(tab->MText8);
4584 gtk_container_add(GTK_CONTAINER(tab->MEventBox8), tab->MText8);
4585 tab->MText9 = gtk_label_new("s");
4586 gtk_widget_show(tab->MText9);
4587 tab->MText10 = gtk_label_new("ns");
4588 gtk_widget_show(tab->MText10);
4590 tab->MEventBox5b = gtk_event_box_new();
4591 gtk_widget_show(tab->MEventBox5b);
4592 gtk_tooltips_set_tip(tab->tooltips, tab->MEventBox5b,
4593 "Paste Current Time Here", "");
4594 tab->MText5b = gtk_label_new("Current Time:");
4595 gtk_widget_show(tab->MText5b);
4596 gtk_container_add(GTK_CONTAINER(tab->MEventBox5b), tab->MText5b);
4597 tab->MText6 = gtk_label_new("s");
4598 gtk_widget_show(tab->MText6);
4599 tab->MText7 = gtk_label_new("ns");
4600 gtk_widget_show(tab->MText7);
4602 tab->MEntry1 = gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4603 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab->MEntry1),0);
4604 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab->MEntry1),TRUE);
4605 gtk_widget_show(tab->MEntry1);
4606 tab->MEntry2 = gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4607 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab->MEntry2),0);
4608 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab->MEntry2),TRUE);
4609 gtk_widget_show(tab->MEntry2);
4610 tab->MEntry3 = gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4611 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab->MEntry3),0);
4612 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab->MEntry3),TRUE);
4613 gtk_widget_show(tab->MEntry3);
4614 tab->MEntry4 = gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4615 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab->MEntry4),0);
4616 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab->MEntry4),TRUE);
4617 gtk_widget_show(tab->MEntry4);
4618 tab->MEntry5 = gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4619 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab->MEntry5),0);
4620 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab->MEntry5),TRUE);
4621 gtk_widget_show(tab->MEntry5);
4622 tab->MEntry6 = gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4623 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab->MEntry6),0);
4624 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab->MEntry6),TRUE);
4625 gtk_widget_show(tab->MEntry6);
4626 tab->MEntry7 = gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4627 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab->MEntry7),0);
4628 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab->MEntry7),TRUE);
4629 gtk_widget_show(tab->MEntry7);
4630 tab->MEntry8 = gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4631 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab->MEntry8),0);
4632 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab->MEntry8),TRUE);
4633 gtk_widget_show(tab->MEntry8);
4635 GtkWidget *temp_widget;
4637 gtk_box_pack_start (GTK_BOX (tab->MTimebar), tab->MEventBox1a, FALSE,
4639 gtk_box_pack_start (GTK_BOX (tab->MTimebar), tab->MEventBox1b, FALSE,
4641 gtk_box_pack_start (GTK_BOX (tab->MTimebar), tab->MEntry1, FALSE, FALSE, 0);
4642 gtk_box_pack_start (GTK_BOX (tab->MTimebar), tab->MText2, FALSE, FALSE, 0);
4643 gtk_box_pack_start (GTK_BOX (tab->MTimebar), tab->MEntry2, FALSE, FALSE, 0);
4644 gtk_box_pack_start (GTK_BOX (tab->MTimebar), tab->MText3a, FALSE, FALSE, 0);
4645 temp_widget = gtk_vseparator_new();
4646 gtk_widget_show(temp_widget);
4647 gtk_box_pack_start (GTK_BOX (tab->MTimebar), temp_widget, FALSE, FALSE, 0);
4648 gtk_box_pack_start (GTK_BOX (tab->MTimebar), tab->MEventBox3b, FALSE,
4650 gtk_box_pack_start (GTK_BOX (tab->MTimebar), tab->MEntry3, FALSE, FALSE, 0);
4651 gtk_box_pack_start (GTK_BOX (tab->MTimebar), tab->MText4, FALSE, FALSE, 0);
4652 gtk_box_pack_start (GTK_BOX (tab->MTimebar), tab->MEntry4, FALSE, FALSE, 0);
4653 gtk_box_pack_start (GTK_BOX (tab->MTimebar), tab->MText5a, FALSE, FALSE, 0);
4654 temp_widget = gtk_vseparator_new();
4655 gtk_widget_show(temp_widget);
4656 gtk_box_pack_start (GTK_BOX (tab->MTimebar), temp_widget, FALSE, FALSE, 0);
4657 gtk_box_pack_start (GTK_BOX (tab->MTimebar), tab->MEventBox8, FALSE,
4659 gtk_box_pack_start (GTK_BOX (tab->MTimebar), tab->MEntry7, FALSE, FALSE, 0);
4660 gtk_box_pack_start (GTK_BOX (tab->MTimebar), tab->MText9, FALSE, FALSE, 0);
4661 gtk_box_pack_start (GTK_BOX (tab->MTimebar), tab->MEntry8, FALSE, FALSE, 0);
4662 gtk_box_pack_start (GTK_BOX (tab->MTimebar), tab->MText10, FALSE, FALSE, 0);
4664 temp_widget = gtk_vseparator_new();
4665 gtk_widget_show(temp_widget);
4666 gtk_box_pack_end (GTK_BOX (tab->MTimebar), tab->MText7, FALSE, FALSE, 0);
4667 gtk_box_pack_end (GTK_BOX (tab->MTimebar), tab->MEntry6, FALSE, FALSE, 0);
4668 gtk_box_pack_end (GTK_BOX (tab->MTimebar), tab->MText6, FALSE, FALSE, 0);
4669 gtk_box_pack_end (GTK_BOX (tab->MTimebar), tab->MEntry5, FALSE, FALSE, 0);
4670 gtk_box_pack_end (GTK_BOX (tab->MTimebar), tab->MEventBox5b, FALSE,
4672 gtk_box_pack_end (GTK_BOX (tab->MTimebar), temp_widget, FALSE, FALSE, 0);
4675 //GtkWidget *test = gtk_button_new_with_label("drop");
4676 //gtk_button_set_relief(GTK_BUTTON(test), GTK_RELIEF_NONE);
4677 //gtk_widget_show(test);
4678 //gtk_box_pack_end(GTK_BOX (tab->MTimebar), test, FALSE, FALSE, 0);
4679 //gtk_widget_add_events(tab->MText1, GDK_ALL_EVENTS_MASK);//GDK_BUTTON_PRESS_MASK);
4680 /*GtkWidget *event_box = gtk_event_box_new();
4681 gtk_widget_show(event_box);
4682 gtk_tooltips_set_tip(tooltips, event_box,
4683 "Paste Current Time Here", "");
4684 gtk_box_pack_end(GTK_BOX (tab->MTimebar), event_box, FALSE, FALSE, 0);
4685 GtkWidget *test = gtk_label_new("drop");
4686 gtk_container_add(GTK_CONTAINER(event_box), test);
4687 gtk_widget_show(test);
4688 g_signal_connect (G_OBJECT(event_box),
4689 "button-press-event",
4690 G_CALLBACK (on_MText1_paste),
4694 g_signal_connect (G_OBJECT(tab->MEventBox1a),
4695 "button-press-event",
4696 G_CALLBACK (on_MEventBox1a_paste),
4699 g_signal_connect (G_OBJECT(tab->MEventBox1b),
4700 "button-press-event",
4701 G_CALLBACK (on_MEventBox1b_paste),
4703 g_signal_connect (G_OBJECT(tab->MEventBox3b),
4704 "button-press-event",
4705 G_CALLBACK (on_MEventBox3b_paste),
4707 g_signal_connect (G_OBJECT(tab->MEventBox5b),
4708 "button-press-event",
4709 G_CALLBACK (on_MEventBox5b_paste),
4711 g_signal_connect (G_OBJECT(tab->MEventBox8),
4712 "button-press-event",
4713 G_CALLBACK (on_MEventBox8_paste),
4717 gtk_box_pack_end(GTK_BOX(tab->vbox),
4719 FALSE, /* Do not expand */
4720 FALSE, /* Fill has no effect here (expand false) */
4721 0); /* No padding */
4723 gtk_box_pack_end(GTK_BOX(tab->vbox),
4725 FALSE, /* Do not expand */
4726 FALSE, /* Fill has no effect here (expand false) */
4727 0); /* No padding */
4729 g_object_set_data(G_OBJECT(tab->viewer_container), "focused_viewer", NULL);
4735 // Display a label with a X
4736 GtkWidget *w_hbox = gtk_hbox_new(FALSE, 4);
4737 GtkWidget *w_label = gtk_label_new (label);
4738 GtkWidget *pixmap = create_pixmap(GTK_WIDGET(notebook), "close.png");
4739 GtkWidget *w_button = gtk_button_new ();
4740 gtk_container_add(GTK_CONTAINER(w_button), pixmap);
4741 //GtkWidget *w_button = gtk_button_new_with_label("x");
4743 gtk_button_set_relief(GTK_BUTTON(w_button), GTK_RELIEF_NONE);
4745 gtk_box_pack_start(GTK_BOX(w_hbox), w_label, TRUE, TRUE, 0);
4746 gtk_box_pack_end(GTK_BOX(w_hbox), w_button, FALSE,
4749 g_signal_connect_swapped (w_button, "clicked",
4750 G_CALLBACK (on_close_tab_X_clicked),
4753 gtk_widget_set_state(w_button, GTK_STATE_ACTIVE);
4755 gtk_widget_show (w_label);
4756 gtk_widget_show (pixmap);
4757 gtk_widget_show (w_button);
4758 gtk_widget_show (w_hbox);
4760 tab->label = w_hbox;
4764 tab->label = gtk_label_new (label);
4766 gtk_widget_show(tab->label);
4767 gtk_widget_show(tab->scrollbar);
4768 gtk_widget_show(tab->viewer_container);
4769 gtk_widget_show(tab->vbox);
4770 //gtk_widget_show(tab->multivpaned);
4773 /* Start with empty events requests list */
4774 tab->events_requests = NULL;
4775 tab->events_request_pending = FALSE;
4776 tab->stop_foreground = FALSE;
4780 g_signal_connect(G_OBJECT(tab->scrollbar), "value-changed",
4781 G_CALLBACK(scroll_value_changed_cb), tab);
4783 g_signal_connect ((gpointer) tab->MEntry1, "value-changed",
4784 G_CALLBACK (on_MEntry1_value_changed),
4786 g_signal_connect ((gpointer) tab->MEntry2, "value-changed",
4787 G_CALLBACK (on_MEntry2_value_changed),
4789 g_signal_connect ((gpointer) tab->MEntry3, "value-changed",
4790 G_CALLBACK (on_MEntry3_value_changed),
4792 g_signal_connect ((gpointer) tab->MEntry4, "value-changed",
4793 G_CALLBACK (on_MEntry4_value_changed),
4795 g_signal_connect ((gpointer) tab->MEntry5, "value-changed",
4796 G_CALLBACK (on_MEntry5_value_changed),
4798 g_signal_connect ((gpointer) tab->MEntry6, "value-changed",
4799 G_CALLBACK (on_MEntry6_value_changed),
4801 g_signal_connect ((gpointer) tab->MEntry7, "value-changed",
4802 G_CALLBACK (on_MEntry7_value_changed),
4804 g_signal_connect ((gpointer) tab->MEntry8, "value-changed",
4805 G_CALLBACK (on_MEntry8_value_changed),
4808 //g_signal_connect(G_OBJECT(tab->scrollbar), "changed",
4809 // G_CALLBACK(scroll_value_changed_cb), tab);
4812 //insert tab into notebook
4813 gtk_notebook_append_page(notebook,
4816 list = gtk_container_get_children(GTK_CONTAINER(notebook));
4817 gtk_notebook_set_current_page(notebook,g_list_length(list)-1);
4818 // always show : not if(g_list_length(list)>1)
4819 gtk_notebook_set_show_tabs(notebook, TRUE);
4822 lttvwindow_report_time_window(tab, copy_tab->time_window);
4823 lttvwindow_report_current_time(tab, copy_tab->current_time);
4825 TimeWindow time_window;
4827 time_window.start_time = ltt_time_zero;
4828 time_window.end_time = ltt_time_add(time_window.start_time,
4829 lttvwindow_default_time_width);
4830 time_window.time_width = lttvwindow_default_time_width;
4831 time_window.time_width_double = ltt_time_to_double(time_window.time_width);
4833 lttvwindow_report_time_window(tab, time_window);
4834 lttvwindow_report_current_time(tab, ltt_time_zero);
4837 LttvTraceset *traceset = tab->traceset_info->traceset;
4838 SetTraceset(tab, traceset);
4842 * execute_events_requests
4844 * Idle function that executes the pending requests for a tab.
4846 * @return return value : TRUE : keep the idle function, FALSE : remove it.
4848 gboolean execute_events_requests(Tab *tab)
4850 return ( lttvwindow_process_pending_requests(tab) );
4854 __EXPORT void create_main_window_with_trace_list(GSList *traces)
4856 GSList *iter = NULL;
4859 MainWindow *mw = construct_main_window(NULL);
4860 GtkWidget *widget = mw->mwindow;
4862 GtkWidget * notebook = lookup_widget(widget, "MNotebook");
4863 GtkWidget *page = gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook),
4864 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook)));
4865 LttvPluginTab *ptab;
4869 ptab = create_new_tab(widget, NULL);
4872 ptab = (LttvPluginTab *)g_object_get_data(G_OBJECT(page), "Tab_Plugin");
4876 for(iter=traces; iter!=NULL; iter=g_slist_next(iter)) {
4877 gchar *path = (gchar*)iter->data;
4879 gchar abs_path[PATH_MAX];
4883 get_absolute_pathname(path, abs_path);
4884 trace_v = lttvwindowtraces_get_trace_by_name(abs_path);
4885 if(trace_v == NULL) {
4886 trace = ltt_trace_open(abs_path);
4888 g_warning("cannot open trace %s", abs_path);
4890 GtkWidget *dialogue =
4891 gtk_message_dialog_new(
4892 GTK_WINDOW(gtk_widget_get_toplevel(widget)),
4893 GTK_DIALOG_MODAL|GTK_DIALOG_DESTROY_WITH_PARENT,
4896 "Cannot open trace : maybe you should enter in the directory "
4898 gtk_dialog_run(GTK_DIALOG(dialogue));
4899 gtk_widget_destroy(dialogue);
4901 trace_v = lttv_trace_new(trace);
4902 lttvwindowtraces_add_trace(trace_v);
4903 lttvwindow_add_trace(tab, trace_v);
4906 lttvwindow_add_trace(tab, trace_v);
4910 LttvTraceset *traceset;
4912 traceset = tab->traceset_info->traceset;
4913 SetTraceset(tab, traceset);