1 /* This file is part of the Linux Trace Toolkit viewer
2 * Copyright (C) 2003-2004 XangXiu Yang, Mathieu Desnoyers
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License Version 2 as
6 * published by the Free Software Foundation;
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place - Suite 330, Boston,
23 #include <limits.h> // for PATH_MAX
31 #include "callbacks.h"
32 #include "interface.h"
34 #include <ltt/trace.h>
35 #include <ltt/facility.h>
37 #include <ltt/event.h>
38 #include <lttv/lttv.h>
39 #include <lttv/module.h>
40 #include <lttv/iattribute.h>
41 #include <lttv/stats.h>
42 #include <lttv/filter.h>
43 #include <lttvwindow/mainwindow.h>
44 #include <lttvwindow/mainwindow-private.h>
45 #include <lttvwindow/menu.h>
46 #include <lttvwindow/toolbar.h>
47 #include <lttvwindow/lttvwindow.h>
48 #include <lttvwindow/lttvwindowtraces.h>
49 #include <lttvwindow/gtkdirsel.h>
52 #define DEFAULT_TIME_WIDTH_S 1
53 #define CLIP_BUF 256 // size of clipboard buffer
55 extern LttvTrace
*g_init_trace
;
58 /** Array containing instanced objects. */
59 extern GSList
* g_main_window_list
;
61 /** MD : keep old directory. */
62 static char remember_plugins_dir
[PATH_MAX
] = "";
63 static char remember_trace_dir
[PATH_MAX
] = "";
66 MainWindow
* get_window_data_struct(GtkWidget
* widget
);
67 char * get_load_module(char ** load_module_name
, int nb_module
);
68 char * get_unload_module(char ** loaded_module_name
, int nb_module
);
69 char * get_remove_trace(char ** all_trace_name
, int nb_trace
);
70 char * get_selection(char ** all_name
, int nb
, char *title
, char * column_title
);
71 Tab
* create_tab(MainWindow
* mw
, Tab
*copy_tab
,
72 GtkNotebook
* notebook
, char * label
);
74 static void insert_viewer(GtkWidget
* widget
, lttvwindow_viewer_constructor constructor
);
76 void checkbox_changed(GtkTreeView
*treeview
,
78 GtkTreeViewColumn
*arg2
,
80 void remove_trace_from_traceset_selector(GtkWidget
* paned
, unsigned i
);
81 void add_trace_into_traceset_selector(GtkWidget
* paned
, LttTrace
* trace
);
82 Tab
*create_new_tab(GtkWidget
* widget
, gpointer user_data
);
84 static gboolean
lttvwindow_process_pending_requests(Tab
*tab
);
98 /* Pasting routines */
100 static void MEventBox1a_receive(GtkClipboard
*clipboard
,
104 if(text
== NULL
) return;
105 Tab
*tab
= (Tab
*)data
;
106 gchar buffer
[CLIP_BUF
];
107 gchar
*ptr
= buffer
, *ptr_ssec
, *ptr_snsec
, *ptr_esec
, *ptr_ensec
;
109 strncpy(buffer
, text
, CLIP_BUF
);
112 while(!isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
113 /* remove leading junk */
115 while(isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
116 /* read all the first number */
120 while(!isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
121 /* remove leading junk */
123 while(isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
124 /* read all the first number */
128 while(!isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
129 /* remove leading junk */
131 while(isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
132 /* read all the first number */
136 while(!isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
137 /* remove leading junk */
139 while(isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
140 /* read all the first number */
143 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry1
),
144 (double)strtoul(ptr_ssec
, NULL
, 10));
145 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry2
),
146 (double)strtoul(ptr_snsec
, NULL
, 10));
147 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry3
),
148 (double)strtoul(ptr_esec
, NULL
, 10));
149 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry4
),
150 (double)strtoul(ptr_ensec
, NULL
, 10));
153 static gboolean
on_MEventBox1a_paste(GtkWidget
*widget
, GdkEventButton
*event
,
156 Tab
*tab
= (Tab
*)data
;
158 GtkClipboard
*clip
= gtk_clipboard_get_for_display(gdk_display_get_default(),
159 GDK_SELECTION_PRIMARY
);
160 gtk_clipboard_request_text(clip
,
161 (GtkClipboardTextReceivedFunc
)MEventBox1a_receive
,
168 static void MEventBox1b_receive(GtkClipboard
*clipboard
,
172 if(text
== NULL
) return;
173 Tab
*tab
= (Tab
*)data
;
174 gchar buffer
[CLIP_BUF
];
175 gchar
*ptr
= buffer
, *ptr_sec
, *ptr_nsec
;
177 strncpy(buffer
, text
, CLIP_BUF
);
179 while(!isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
180 /* remove leading junk */
182 while(isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
183 /* read all the first number */
187 while(!isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
188 /* remove leading junk */
190 while(isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
191 /* read all the first number */
194 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry1
),
195 (double)strtoul(ptr_sec
, NULL
, 10));
196 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry2
),
197 (double)strtoul(ptr_nsec
, NULL
, 10));
201 static gboolean
on_MEventBox1b_paste(GtkWidget
*widget
, GdkEventButton
*event
,
204 Tab
*tab
= (Tab
*)data
;
206 GtkClipboard
*clip
= gtk_clipboard_get_for_display(gdk_display_get_default(),
207 GDK_SELECTION_PRIMARY
);
208 gtk_clipboard_request_text(clip
,
209 (GtkClipboardTextReceivedFunc
)MEventBox1b_receive
,
215 static void MEventBox3b_receive(GtkClipboard
*clipboard
,
219 if(text
== NULL
) return;
220 Tab
*tab
= (Tab
*)data
;
221 gchar buffer
[CLIP_BUF
];
222 gchar
*ptr
= buffer
, *ptr_sec
, *ptr_nsec
;
224 strncpy(buffer
, text
, CLIP_BUF
);
226 while(!isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
227 /* remove leading junk */
229 while(isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
230 /* read all the first number */
234 while(!isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
235 /* remove leading junk */
237 while(isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
238 /* read all the first number */
241 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry3
),
242 (double)strtoul(ptr_sec
, NULL
, 10));
243 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry4
),
244 (double)strtoul(ptr_nsec
, NULL
, 10));
248 static gboolean
on_MEventBox3b_paste(GtkWidget
*widget
, GdkEventButton
*event
,
251 Tab
*tab
= (Tab
*)data
;
253 GtkClipboard
*clip
= gtk_clipboard_get_for_display(gdk_display_get_default(),
254 GDK_SELECTION_PRIMARY
);
255 gtk_clipboard_request_text(clip
,
256 (GtkClipboardTextReceivedFunc
)MEventBox3b_receive
,
262 static void MEventBox5b_receive(GtkClipboard
*clipboard
,
266 if(text
== NULL
) return;
267 Tab
*tab
= (Tab
*)data
;
268 gchar buffer
[CLIP_BUF
];
269 gchar
*ptr
= buffer
, *ptr_sec
, *ptr_nsec
;
271 strncpy(buffer
, text
, CLIP_BUF
);
273 while(!isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
274 /* remove leading junk */
276 while(isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
277 /* read all the first number */
281 while(!isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
282 /* remove leading junk */
284 while(isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
285 /* read all the first number */
288 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry5
),
289 (double)strtoul(ptr_sec
, NULL
, 10));
290 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry6
),
291 (double)strtoul(ptr_nsec
, NULL
, 10));
295 static gboolean
on_MEventBox5b_paste(GtkWidget
*widget
, GdkEventButton
*event
,
298 Tab
*tab
= (Tab
*)data
;
300 GtkClipboard
*clip
= gtk_clipboard_get_for_display(gdk_display_get_default(),
301 GDK_SELECTION_PRIMARY
);
302 gtk_clipboard_request_text(clip
,
303 (GtkClipboardTextReceivedFunc
)MEventBox5b_receive
,
309 static gboolean
viewer_grab_focus(GtkWidget
*widget
, GdkEventButton
*event
,
312 GtkWidget
*viewer
= GTK_WIDGET(data
);
313 GtkWidget
*viewer_container
= gtk_widget_get_parent(viewer
);
315 g_debug("FOCUS GRABBED");
316 g_object_set_data(G_OBJECT(viewer_container
), "focused_viewer", viewer
);
321 static void connect_focus_recursive(GtkWidget
*widget
,
324 if(GTK_IS_CONTAINER(widget
)) {
325 gtk_container_forall(GTK_CONTAINER(widget
),
326 (GtkCallback
)connect_focus_recursive
,
330 if(GTK_IS_TREE_VIEW(widget
)) {
331 gtk_tree_view_set_headers_clickable(GTK_TREE_VIEW(widget
), TRUE
);
333 gtk_widget_add_events(widget
, GDK_BUTTON_PRESS_MASK
);
334 g_signal_connect (G_OBJECT(widget
),
335 "button-press-event",
336 G_CALLBACK (viewer_grab_focus
),
340 /* insert_viewer function constructs an instance of a viewer first,
341 * then inserts the widget of the instance into the container of the
346 insert_viewer_wrap(GtkWidget
*menuitem
, gpointer user_data
)
348 insert_viewer((GtkWidget
*)menuitem
, (lttvwindow_viewer_constructor
)user_data
);
352 /* internal functions */
353 void insert_viewer(GtkWidget
* widget
, lttvwindow_viewer_constructor constructor
)
355 GtkWidget
* viewer_container
;
356 MainWindow
* mw_data
= get_window_data_struct(widget
);
357 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
359 TimeInterval
* time_interval
;
360 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
361 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
365 tab
= create_new_tab(widget
, NULL
);
367 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
370 viewer_container
= tab
->viewer_container
;
372 viewer
= (GtkWidget
*)constructor(tab
);
375 //gtk_multivpaned_widget_add(GTK_MULTIVPANED(multivpaned), viewer);
377 gtk_box_pack_end(GTK_BOX(viewer_container
),
383 /* We want to connect the viewer_grab_focus to EVERY
384 * child of this widget. The little trick is to get each child
385 * of each GTK_CONTAINER, even subchildren.
387 connect_focus_recursive(viewer
, viewer
);
392 * Function to set/update traceset for the viewers
393 * @param tab viewer's tab
394 * @param traceset traceset of the main window.
396 * 0 : traceset updated
397 * 1 : no traceset hooks to update; not an error.
400 int SetTraceset(Tab
* tab
, LttvTraceset
*traceset
)
402 LttvTracesetContext
*tsc
=
403 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
404 TimeInterval time_span
= tsc
->time_span
;
405 TimeWindow new_time_window
;
406 LttTime new_current_time
;
408 /* Set the tab's time window and current time if
410 if(ltt_time_compare(tab
->time_window
.start_time
, time_span
.start_time
) < 0
411 || ltt_time_compare(tab
->time_window
.end_time
,
412 time_span
.end_time
) > 0) {
413 new_time_window
.start_time
= time_span
.start_time
;
415 new_current_time
= time_span
.start_time
;
419 if(DEFAULT_TIME_WIDTH_S
< time_span
.end_time
.tv_sec
)
420 tmp_time
.tv_sec
= DEFAULT_TIME_WIDTH_S
;
422 tmp_time
.tv_sec
= time_span
.end_time
.tv_sec
;
423 tmp_time
.tv_nsec
= 0;
424 new_time_window
.time_width
= tmp_time
;
425 new_time_window
.time_width_double
= ltt_time_to_double(tmp_time
);
426 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
427 new_time_window
.time_width
) ;
429 time_change_manager(tab
, new_time_window
);
430 current_time_change_manager(tab
, new_current_time
);
434 GtkAdjustment
*adjustment
= gtk_range_get_adjustment(GTK_RANGE(tab
->scrollbar
));
435 LttTime upper
= ltt_time_sub(time_span
.end_time
, time_span
.start_time
);
437 g_object_set(G_OBJECT(adjustment
),
441 ltt_time_to_double(upper
)
442 * NANOSECONDS_PER_SECOND
, /* upper */
444 ltt_time_to_double(tab
->time_window
.time_width
)
445 / SCROLL_STEP_PER_PAGE
446 * NANOSECONDS_PER_SECOND
, /* step increment */
448 ltt_time_to_double(tab
->time_window
.time_width
)
449 * NANOSECONDS_PER_SECOND
, /* page increment */
451 ltt_time_to_double(tab
->time_window
.time_width
)
452 * NANOSECONDS_PER_SECOND
, /* page size */
454 gtk_adjustment_changed(adjustment
);
456 g_object_set(G_OBJECT(adjustment
),
459 ltt_time_sub(tab
->time_window
.start_time
, time_span
.start_time
))
460 * NANOSECONDS_PER_SECOND
, /* value */
462 gtk_adjustment_value_changed(adjustment
);
464 /* set the time bar. The value callbacks will change their nsec themself */
466 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry1
),
467 (double)time_span
.start_time
.tv_sec
,
468 (double)time_span
.end_time
.tv_sec
);
471 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry3
),
472 (double)time_span
.start_time
.tv_sec
,
473 (double)time_span
.end_time
.tv_sec
);
475 /* current seconds */
476 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry5
),
477 (double)time_span
.start_time
.tv_sec
,
478 (double)time_span
.end_time
.tv_sec
);
481 /* Finally, call the update hooks of the viewers */
483 LttvAttributeValue value
;
487 g_assert( lttv_iattribute_find_by_path(tab
->attributes
,
488 "hooks/updatetraceset", LTTV_POINTER
, &value
));
490 tmp
= (LttvHooks
*)*(value
.v_pointer
);
491 if(tmp
== NULL
) retval
= 1;
492 else lttv_hooks_call(tmp
,traceset
);
499 * Function to set/update filter for the viewers
500 * @param tab viewer's tab
501 * @param filter filter of the main window.
504 * 0 : filters updated
505 * 1 : no filter hooks to update; not an error.
508 int SetFilter(Tab
* tab
, gpointer filter
)
511 LttvAttributeValue value
;
513 g_assert(lttv_iattribute_find_by_path(tab
->attributes
,
514 "hooks/updatefilter", LTTV_POINTER
, &value
));
516 tmp
= (LttvHooks
*)*(value
.v_pointer
);
518 if(tmp
== NULL
) return 1;
519 lttv_hooks_call(tmp
,filter
);
527 * Function to redraw each viewer belonging to the current tab
528 * @param tab viewer's tab
531 void update_traceset(Tab
*tab
)
533 LttvAttributeValue value
;
535 g_assert(lttv_iattribute_find_by_path(tab
->attributes
,
536 "hooks/updatetraceset", LTTV_POINTER
, &value
));
537 tmp
= (LttvHooks
*)*(value
.v_pointer
);
538 if(tmp
== NULL
) return;
539 lttv_hooks_call(tmp
, NULL
);
543 /* get_label function is used to get user input, it displays an input
544 * box, which allows user to input a string
547 void get_label_string (GtkWidget
* text
, gchar
* label
)
549 GtkEntry
* entry
= (GtkEntry
*)text
;
550 if(strlen(gtk_entry_get_text(entry
))!=0)
551 strcpy(label
,gtk_entry_get_text(entry
));
554 gboolean
get_label(MainWindow
* mw
, gchar
* str
, gchar
* dialogue_title
, gchar
* label_str
)
556 GtkWidget
* dialogue
;
561 dialogue
= gtk_dialog_new_with_buttons(dialogue_title
,NULL
,
563 GTK_STOCK_OK
,GTK_RESPONSE_ACCEPT
,
564 GTK_STOCK_CANCEL
,GTK_RESPONSE_REJECT
,
567 label
= gtk_label_new(label_str
);
568 gtk_widget_show(label
);
570 text
= gtk_entry_new();
571 gtk_widget_show(text
);
573 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialogue
)->vbox
), label
,TRUE
, TRUE
,0);
574 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialogue
)->vbox
), text
,FALSE
, FALSE
,0);
576 id
= gtk_dialog_run(GTK_DIALOG(dialogue
));
578 case GTK_RESPONSE_ACCEPT
:
579 get_label_string(text
,str
);
580 gtk_widget_destroy(dialogue
);
582 case GTK_RESPONSE_REJECT
:
584 gtk_widget_destroy(dialogue
);
591 /* get_window_data_struct function is actually a lookup function,
592 * given a widget which is in the tree of the main window, it will
593 * return the MainWindow data structure associated with main window
596 MainWindow
* get_window_data_struct(GtkWidget
* widget
)
599 MainWindow
* mw_data
;
601 mw
= lookup_widget(widget
, "MWindow");
603 g_info("Main window does not exist\n");
607 mw_data
= (MainWindow
*) g_object_get_data(G_OBJECT(mw
),"main_window_data");
609 g_warning("Main window data does not exist\n");
616 /* create_new_window function, just constructs a new main window
619 void create_new_window(GtkWidget
* widget
, gpointer user_data
, gboolean clone
)
621 MainWindow
* parent
= get_window_data_struct(widget
);
624 g_info("Clone : use the same traceset\n");
625 construct_main_window(parent
);
627 g_info("Empty : traceset is set to NULL\n");
628 construct_main_window(NULL
);
632 /* Get the currently focused viewer.
633 * If no viewer is focused, use the first one.
635 * If no viewer available, return NULL.
637 GtkWidget
*viewer_container_focus(GtkWidget
*container
)
641 widget
= (GtkWidget
*)g_object_get_data(G_OBJECT(container
),
645 g_debug("no widget focused");
646 GList
*children
= gtk_container_get_children(GTK_CONTAINER(container
));
649 widget
= GTK_WIDGET(children
->data
);
650 g_object_set_data(G_OBJECT(container
),
660 gint
viewer_container_position(GtkWidget
*container
, GtkWidget
*child
)
663 if(child
== NULL
) return -1;
667 memset(&value
, 0, sizeof(GValue
));
668 g_value_init(&value
, G_TYPE_INT
);
669 gtk_container_child_get_property(GTK_CONTAINER(container
),
673 pos
= g_value_get_int(&value
);
679 /* move_*_viewer functions move the selected view up/down in
683 void move_down_viewer(GtkWidget
* widget
, gpointer user_data
)
685 MainWindow
* mw
= get_window_data_struct(widget
);
686 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
688 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
689 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
695 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
698 //gtk_multivpaned_widget_move_up(GTK_MULTIVPANED(tab->multivpaned));
700 /* change the position in the vbox */
701 GtkWidget
*focus_widget
;
703 focus_widget
= viewer_container_focus(tab
->viewer_container
);
704 position
= viewer_container_position(tab
->viewer_container
, focus_widget
);
707 /* can move up one position */
708 gtk_box_reorder_child(GTK_BOX(tab
->viewer_container
),
715 void move_up_viewer(GtkWidget
* widget
, gpointer user_data
)
717 MainWindow
* mw
= get_window_data_struct(widget
);
718 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
720 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
721 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
727 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
730 //gtk_multivpaned_widget_move_down(GTK_MULTIVPANED(tab->multivpaned));
731 /* change the position in the vbox */
732 GtkWidget
*focus_widget
;
734 focus_widget
= viewer_container_focus(tab
->viewer_container
);
735 position
= viewer_container_position(tab
->viewer_container
, focus_widget
);
739 g_list_length(gtk_container_get_children(
740 GTK_CONTAINER(tab
->viewer_container
)))-1
742 /* can move down one position */
743 gtk_box_reorder_child(GTK_BOX(tab
->viewer_container
),
751 /* delete_viewer deletes the selected viewer in the current tab
754 void delete_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
)));
766 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
769 //gtk_multivpaned_widget_delete(GTK_MULTIVPANED(tab->multivpaned));
771 GtkWidget
*focus_widget
= viewer_container_focus(tab
->viewer_container
);
773 if(focus_widget
!= NULL
)
774 gtk_widget_destroy(focus_widget
);
776 g_object_set_data(G_OBJECT(tab
->viewer_container
), "focused_viewer", NULL
);
780 /* open_traceset will open a traceset saved in a file
781 * Right now, it is not finished yet, (not working)
785 void open_traceset(GtkWidget
* widget
, gpointer user_data
)
789 LttvTraceset
* traceset
;
790 MainWindow
* mw_data
= get_window_data_struct(widget
);
791 GtkFileSelection
* file_selector
=
792 (GtkFileSelection
*)gtk_file_selection_new("Select a traceset");
794 gtk_file_selection_hide_fileop_buttons(file_selector
);
796 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
798 case GTK_RESPONSE_ACCEPT
:
799 case GTK_RESPONSE_OK
:
800 dir
= gtk_file_selection_get_selections (file_selector
);
801 traceset
= lttv_traceset_load(dir
[0]);
802 g_info("Open a trace set %s\n", dir
[0]);
805 case GTK_RESPONSE_REJECT
:
806 case GTK_RESPONSE_CANCEL
:
808 gtk_widget_destroy((GtkWidget
*)file_selector
);
814 static void events_request_free(EventsRequest
*events_request
)
816 if(events_request
== NULL
) return;
818 if(events_request
->start_position
!= NULL
)
819 lttv_traceset_context_position_destroy(events_request
->start_position
);
820 if(events_request
->end_position
!= NULL
)
821 lttv_traceset_context_position_destroy(events_request
->end_position
);
822 if(events_request
->hooks
!= NULL
)
823 g_array_free(events_request
->hooks
, TRUE
);
824 if(events_request
->before_chunk_traceset
!= NULL
)
825 lttv_hooks_destroy(events_request
->before_chunk_traceset
);
826 if(events_request
->before_chunk_trace
!= NULL
)
827 lttv_hooks_destroy(events_request
->before_chunk_trace
);
828 if(events_request
->before_chunk_tracefile
!= NULL
)
829 lttv_hooks_destroy(events_request
->before_chunk_tracefile
);
830 if(events_request
->event
!= NULL
)
831 lttv_hooks_destroy(events_request
->event
);
832 if(events_request
->event_by_id
!= NULL
)
833 lttv_hooks_by_id_destroy(events_request
->event_by_id
);
834 if(events_request
->after_chunk_tracefile
!= NULL
)
835 lttv_hooks_destroy(events_request
->after_chunk_tracefile
);
836 if(events_request
->after_chunk_trace
!= NULL
)
837 lttv_hooks_destroy(events_request
->after_chunk_trace
);
838 if(events_request
->after_chunk_traceset
!= NULL
)
839 lttv_hooks_destroy(events_request
->after_chunk_traceset
);
840 if(events_request
->before_request
!= NULL
)
841 lttv_hooks_destroy(events_request
->before_request
);
842 if(events_request
->after_request
!= NULL
)
843 lttv_hooks_destroy(events_request
->after_request
);
845 g_free(events_request
);
850 /* lttvwindow_process_pending_requests
852 * This internal function gets called by g_idle, taking care of the pending
853 * requests. It is responsible for concatenation of time intervals and position
854 * requests. It does it with the following algorithm organizing process traceset
855 * calls. Here is the detailed description of the way it works :
857 * - Events Requests Servicing Algorithm
859 * Data structures necessary :
861 * List of requests added to context : list_in
862 * List of requests not added to context : list_out
867 * list_out : many events requests
869 * FIXME : insert rest of algorithm here
873 #define list_out tab->events_requests
875 gboolean
lttvwindow_process_pending_requests(Tab
*tab
)
878 LttvTracesetContext
*tsc
;
879 LttvTracefileContext
*tfc
;
880 GSList
*list_in
= NULL
;
884 LttvTracesetContextPosition
*end_position
;
887 g_critical("Foreground processing : tab does not exist. Processing removed.");
891 /* There is no events requests pending : we should never have been called! */
892 g_assert(g_slist_length(list_out
) != 0);
894 tsc
= LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
896 //set the cursor to be X shape, indicating that the computer is busy in doing its job
898 new = gdk_cursor_new(GDK_X_CURSOR
);
899 widget
= lookup_widget(tab
->mw
->mwindow
, "MToolbar1");
900 win
= gtk_widget_get_parent_window(widget
);
901 gdk_window_set_cursor(win
, new);
902 gdk_cursor_unref(new);
903 gdk_window_stick(win
);
904 gdk_window_unstick(win
);
907 g_debug("SIZE events req len : %d", g_slist_length(list_out
));
909 /* Preliminary check for no trace in traceset */
910 /* Unregister the routine if empty, empty list_out too */
911 if(lttv_traceset_number(tsc
->ts
) == 0) {
913 /* - For each req in list_out */
914 GSList
*iter
= list_out
;
916 while(iter
!= NULL
) {
918 gboolean remove
= FALSE
;
919 gboolean free_data
= FALSE
;
920 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
922 /* - Call end request for req */
923 if(events_request
->servicing
== TRUE
)
924 lttv_hooks_call(events_request
->after_request
, (gpointer
)tsc
);
926 /* - remove req from list_out */
927 /* Destroy the request */
934 GSList
*remove_iter
= iter
;
936 iter
= g_slist_next(iter
);
937 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
938 list_out
= g_slist_remove_link(list_out
, remove_iter
);
939 } else { // not remove
940 iter
= g_slist_next(iter
);
945 /* 0.1 Lock Traces */
950 iter_trace
<lttv_traceset_number(tsc
->ts
);
952 LttvTrace
*trace_v
= lttv_traceset_get(tsc
->ts
, iter_trace
);
954 if(lttvwindowtraces_lock(trace_v
) != 0) {
955 g_critical("Foreground processing : Unable to get trace lock");
956 return TRUE
; /* Cannot get lock, try later */
961 /* 0.2 Seek tracefiles positions to context position */
962 lttv_process_traceset_synchronize_tracefiles(tsc
);
965 /* Events processing algorithm implementation */
966 /* Warning : the gtk_events_pending takes a LOT of cpu time. So what we do
967 * instead is to leave the control to GTK and take it back.
969 /* A. Servicing loop */
970 //while( (g_slist_length(list_in) != 0 || g_slist_length(list_out) != 0)) {
971 if((g_slist_length(list_in
) != 0 || g_slist_length(list_out
) != 0)) {
973 /* 1. If list_in is empty (need a seek) */
974 if( g_slist_length(list_in
) == 0 ) {
976 /* list in is empty, need a seek */
978 /* 1.1 Add requests to list_in */
979 GSList
*ltime
= NULL
;
983 /* 1.1.1 Find all time requests with the lowest start time in list_out
986 if(g_slist_length(list_out
) > 0)
987 ltime
= g_slist_append(ltime
, g_slist_nth_data(list_out
, 0));
988 for(iter
=g_slist_nth(list_out
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
989 /* Find all time requests with the lowest start time in list_out */
990 EventsRequest
*event_request_ltime
= (EventsRequest
*)g_slist_nth_data(ltime
, 0);
991 EventsRequest
*event_request_list_out
= (EventsRequest
*)iter
->data
;
994 comp
= ltt_time_compare(event_request_ltime
->start_time
,
995 event_request_list_out
->start_time
);
997 ltime
= g_slist_append(ltime
, event_request_list_out
);
999 /* Remove all elements from ltime, and add current */
1000 while(ltime
!= NULL
)
1001 ltime
= g_slist_delete_link(ltime
, g_slist_nth(ltime
, 0));
1002 ltime
= g_slist_append(ltime
, event_request_list_out
);
1006 /* 1.1.2 Find all position requests with the lowest position in list_out
1009 if(g_slist_length(list_out
) > 0)
1010 lpos
= g_slist_append(lpos
, g_slist_nth_data(list_out
, 0));
1011 for(iter
=g_slist_nth(list_out
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
1012 /* Find all position requests with the lowest position in list_out */
1013 EventsRequest
*event_request_lpos
= (EventsRequest
*)g_slist_nth_data(lpos
, 0);
1014 EventsRequest
*event_request_list_out
= (EventsRequest
*)iter
->data
;
1017 if(event_request_lpos
->start_position
!= NULL
1018 && event_request_list_out
->start_position
!= NULL
)
1020 comp
= lttv_traceset_context_pos_pos_compare
1021 (event_request_lpos
->start_position
,
1022 event_request_list_out
->start_position
);
1027 lpos
= g_slist_append(lpos
, event_request_list_out
);
1029 /* Remove all elements from lpos, and add current */
1031 lpos
= g_slist_delete_link(lpos
, g_slist_nth(lpos
, 0));
1032 lpos
= g_slist_append(lpos
, event_request_list_out
);
1037 EventsRequest
*event_request_lpos
= (EventsRequest
*)g_slist_nth_data(lpos
, 0);
1038 EventsRequest
*event_request_ltime
= (EventsRequest
*)g_slist_nth_data(ltime
, 0);
1039 LttTime lpos_start_time
;
1041 if(event_request_lpos
!= NULL
1042 && event_request_lpos
->start_position
!= NULL
) {
1043 lpos_start_time
= lttv_traceset_context_position_get_time(
1044 event_request_lpos
->start_position
);
1047 /* 1.1.3 If lpos.start time < ltime */
1048 if(event_request_lpos
!= NULL
1049 && event_request_lpos
->start_position
!= NULL
1050 && ltt_time_compare(lpos_start_time
,
1051 event_request_ltime
->start_time
)<0) {
1052 /* Add lpos to list_in, remove them from list_out */
1053 for(iter
=lpos
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
1054 /* Add to list_in */
1055 EventsRequest
*event_request_lpos
=
1056 (EventsRequest
*)iter
->data
;
1058 list_in
= g_slist_append(list_in
, event_request_lpos
);
1059 /* Remove from list_out */
1060 list_out
= g_slist_remove(list_out
, event_request_lpos
);
1063 /* 1.1.4 (lpos.start time >= ltime) */
1064 /* Add ltime to list_in, remove them from list_out */
1066 for(iter
=ltime
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
1067 /* Add to list_in */
1068 EventsRequest
*event_request_ltime
=
1069 (EventsRequest
*)iter
->data
;
1071 list_in
= g_slist_append(list_in
, event_request_ltime
);
1072 /* Remove from list_out */
1073 list_out
= g_slist_remove(list_out
, event_request_ltime
);
1078 g_slist_free(ltime
);
1083 tfc
= lttv_traceset_context_get_current_tfc(tsc
);
1084 g_assert(g_slist_length(list_in
)>0);
1085 EventsRequest
*events_request
= g_slist_nth_data(list_in
, 0);
1088 /* 1.2.1 If first request in list_in is a time request */
1089 if(events_request
->start_position
== NULL
) {
1090 /* - If first req in list_in start time != current time */
1091 if(tfc
== NULL
|| ltt_time_compare(events_request
->start_time
,
1092 tfc
->timestamp
) != 0)
1093 /* - Seek to that time */
1094 g_debug("SEEK TIME : %lu, %lu", events_request
->start_time
.tv_sec
,
1095 events_request
->start_time
.tv_nsec
);
1096 //lttv_process_traceset_seek_time(tsc, events_request->start_time);
1097 lttv_state_traceset_seek_time_closest(LTTV_TRACESET_STATE(tsc
),
1098 events_request
->start_time
);
1100 /* Process the traceset with only state hooks */
1102 lttv_process_traceset_middle(tsc
,
1103 events_request
->start_time
,
1109 /* Else, the first request in list_in is a position request */
1110 /* If first req in list_in pos != current pos */
1111 g_assert(events_request
->start_position
!= NULL
);
1112 g_debug("SEEK POS time : %lu, %lu",
1113 lttv_traceset_context_position_get_time(
1114 events_request
->start_position
).tv_sec
,
1115 lttv_traceset_context_position_get_time(
1116 events_request
->start_position
).tv_nsec
);
1118 g_debug("SEEK POS context time : %lu, %lu",
1119 lttv_traceset_context_get_current_tfc(tsc
)->timestamp
.tv_sec
,
1120 lttv_traceset_context_get_current_tfc(tsc
)->timestamp
.tv_nsec
);
1121 g_assert(events_request
->start_position
!= NULL
);
1122 if(lttv_traceset_context_ctx_pos_compare(tsc
,
1123 events_request
->start_position
) != 0) {
1124 /* 1.2.2.1 Seek to that position */
1125 g_debug("SEEK POSITION");
1126 //lttv_process_traceset_seek_position(tsc, events_request->start_position);
1127 pos_time
= lttv_traceset_context_position_get_time(
1128 events_request
->start_position
);
1130 lttv_state_traceset_seek_time_closest(LTTV_TRACESET_STATE(tsc
),
1133 /* Process the traceset with only state hooks */
1135 lttv_process_traceset_middle(tsc
,
1138 events_request
->start_position
);
1139 g_assert(lttv_traceset_context_ctx_pos_compare(tsc
,
1140 events_request
->start_position
) == 0);
1147 /* 1.3 Add hooks and call before request for all list_in members */
1149 GSList
*iter
= NULL
;
1151 for(iter
=list_in
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
1152 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1153 /* 1.3.1 If !servicing */
1154 if(events_request
->servicing
== FALSE
) {
1155 /* - begin request hooks called
1156 * - servicing = TRUE
1158 lttv_hooks_call(events_request
->before_request
, (gpointer
)tsc
);
1159 events_request
->servicing
= TRUE
;
1161 /* 1.3.2 call before chunk
1162 * 1.3.3 events hooks added
1164 if(events_request
->trace
== -1)
1165 lttv_process_traceset_begin(tsc
,
1166 events_request
->before_chunk_traceset
,
1167 events_request
->before_chunk_trace
,
1168 events_request
->before_chunk_tracefile
,
1169 events_request
->event
,
1170 events_request
->event_by_id
);
1172 guint nb_trace
= lttv_traceset_number(tsc
->ts
);
1173 g_assert((guint
)events_request
->trace
< nb_trace
&&
1174 events_request
->trace
> -1);
1175 LttvTraceContext
*tc
= tsc
->traces
[events_request
->trace
];
1177 lttv_hooks_call(events_request
->before_chunk_traceset
, tsc
);
1179 lttv_trace_context_add_hooks(tc
,
1180 events_request
->before_chunk_trace
,
1181 events_request
->before_chunk_tracefile
,
1182 events_request
->event
,
1183 events_request
->event_by_id
);
1188 /* 2. Else, list_in is not empty, we continue a read */
1191 /* 2.0 For each req of list_in */
1192 GSList
*iter
= list_in
;
1194 while(iter
!= NULL
) {
1196 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1198 /* - Call before chunk
1199 * - events hooks added
1201 if(events_request
->trace
== -1)
1202 lttv_process_traceset_begin(tsc
,
1203 events_request
->before_chunk_traceset
,
1204 events_request
->before_chunk_trace
,
1205 events_request
->before_chunk_tracefile
,
1206 events_request
->event
,
1207 events_request
->event_by_id
);
1209 guint nb_trace
= lttv_traceset_number(tsc
->ts
);
1210 g_assert((guint
)events_request
->trace
< nb_trace
&&
1211 events_request
->trace
> -1);
1212 LttvTraceContext
*tc
= tsc
->traces
[events_request
->trace
];
1214 lttv_hooks_call(events_request
->before_chunk_traceset
, tsc
);
1216 lttv_trace_context_add_hooks(tc
,
1217 events_request
->before_chunk_trace
,
1218 events_request
->before_chunk_tracefile
,
1219 events_request
->event
,
1220 events_request
->event_by_id
);
1223 iter
= g_slist_next(iter
);
1228 tfc
= lttv_traceset_context_get_current_tfc(tsc
);
1230 /* 2.1 For each req of list_out */
1231 GSList
*iter
= list_out
;
1233 while(iter
!= NULL
) {
1235 gboolean remove
= FALSE
;
1236 gboolean free_data
= FALSE
;
1237 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1239 /* if req.start time == current context time
1240 * or req.start position == current position*/
1241 if( ltt_time_compare(events_request
->start_time
,
1242 tfc
->timestamp
) == 0
1244 (events_request
->start_position
!= NULL
1246 lttv_traceset_context_ctx_pos_compare(tsc
,
1247 events_request
->start_position
) == 0)
1249 /* - Add to list_in, remove from list_out */
1250 list_in
= g_slist_append(list_in
, events_request
);
1254 /* - If !servicing */
1255 if(events_request
->servicing
== FALSE
) {
1256 /* - begin request hooks called
1257 * - servicing = TRUE
1259 lttv_hooks_call(events_request
->before_request
, (gpointer
)tsc
);
1260 events_request
->servicing
= TRUE
;
1262 /* call before chunk
1263 * events hooks added
1265 if(events_request
->trace
== -1)
1266 lttv_process_traceset_begin(tsc
,
1267 events_request
->before_chunk_traceset
,
1268 events_request
->before_chunk_trace
,
1269 events_request
->before_chunk_tracefile
,
1270 events_request
->event
,
1271 events_request
->event_by_id
);
1273 guint nb_trace
= lttv_traceset_number(tsc
->ts
);
1274 g_assert((guint
)events_request
->trace
< nb_trace
&&
1275 events_request
->trace
> -1);
1276 LttvTraceContext
*tc
= tsc
->traces
[events_request
->trace
];
1278 lttv_hooks_call(events_request
->before_chunk_traceset
, tsc
);
1280 lttv_trace_context_add_hooks(tc
,
1281 events_request
->before_chunk_trace
,
1282 events_request
->before_chunk_tracefile
,
1283 events_request
->event
,
1284 events_request
->event_by_id
);
1293 GSList
*remove_iter
= iter
;
1295 iter
= g_slist_next(iter
);
1296 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
1297 list_out
= g_slist_remove_link(list_out
, remove_iter
);
1298 } else { // not remove
1299 iter
= g_slist_next(iter
);
1305 /* 3. Find end criterions */
1310 /* 3.1.1 Find lowest end time in list_in */
1311 g_assert(g_slist_length(list_in
)>0);
1312 end_time
= ((EventsRequest
*)g_slist_nth_data(list_in
,0))->end_time
;
1314 for(iter
=g_slist_nth(list_in
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
1315 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1317 if(ltt_time_compare(events_request
->end_time
,
1319 end_time
= events_request
->end_time
;
1322 /* 3.1.2 Find lowest start time in list_out */
1323 for(iter
=list_out
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
1324 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1326 if(ltt_time_compare(events_request
->start_time
,
1328 end_time
= events_request
->start_time
;
1333 /* 3.2 Number of events */
1335 /* 3.2.1 Find lowest number of events in list_in */
1338 end_nb_events
= ((EventsRequest
*)g_slist_nth_data(list_in
,0))->num_events
;
1340 for(iter
=g_slist_nth(list_in
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
1341 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1343 if(events_request
->num_events
< end_nb_events
)
1344 end_nb_events
= events_request
->num_events
;
1347 /* 3.2.2 Use min(CHUNK_NUM_EVENTS, min num events in list_in) as
1350 end_nb_events
= MIN(CHUNK_NUM_EVENTS
, end_nb_events
);
1354 /* 3.3 End position */
1356 /* 3.3.1 Find lowest end position in list_in */
1359 end_position
=((EventsRequest
*)g_slist_nth_data(list_in
,0))->end_position
;
1361 for(iter
=g_slist_nth(list_in
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
1362 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1364 if(events_request
->end_position
!= NULL
&& end_position
!= NULL
&&
1365 lttv_traceset_context_pos_pos_compare(events_request
->end_position
,
1367 end_position
= events_request
->end_position
;
1372 /* 3.3.2 Find lowest start position in list_out */
1375 for(iter
=list_out
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
1376 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1378 if(events_request
->end_position
!= NULL
&& end_position
!= NULL
&&
1379 lttv_traceset_context_pos_pos_compare(events_request
->end_position
,
1381 end_position
= events_request
->end_position
;
1386 /* 4. Call process traceset middle */
1387 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
);
1388 count
= lttv_process_traceset_middle(tsc
, end_time
, end_nb_events
, end_position
);
1390 tfc
= lttv_traceset_context_get_current_tfc(tsc
);
1392 g_debug("Context time after middle : %lu, %lu", tfc
->timestamp
.tv_sec
,
1393 tfc
->timestamp
.tv_nsec
);
1395 g_debug("End of trace reached after middle.");
1399 /* 5. After process traceset middle */
1400 tfc
= lttv_traceset_context_get_current_tfc(tsc
);
1402 /* - if current context time > traceset.end time */
1403 if(tfc
== NULL
|| ltt_time_compare(tfc
->timestamp
,
1404 tsc
->time_span
.end_time
) > 0) {
1405 /* - For each req in list_in */
1406 GSList
*iter
= list_in
;
1408 while(iter
!= NULL
) {
1410 gboolean remove
= FALSE
;
1411 gboolean free_data
= FALSE
;
1412 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1414 /* - Remove events hooks for req
1415 * - Call end chunk for req
1418 if(events_request
->trace
== -1)
1419 lttv_process_traceset_end(tsc
,
1420 events_request
->after_chunk_traceset
,
1421 events_request
->after_chunk_trace
,
1422 events_request
->after_chunk_tracefile
,
1423 events_request
->event
,
1424 events_request
->event_by_id
);
1427 guint nb_trace
= lttv_traceset_number(tsc
->ts
);
1428 g_assert(events_request
->trace
< nb_trace
&&
1429 events_request
->trace
> -1);
1430 LttvTraceContext
*tc
= tsc
->traces
[events_request
->trace
];
1432 lttv_trace_context_remove_hooks(tc
,
1433 events_request
->after_chunk_trace
,
1434 events_request
->after_chunk_tracefile
,
1435 events_request
->event
,
1436 events_request
->event_by_id
);
1437 lttv_hooks_call(events_request
->after_chunk_traceset
, tsc
);
1442 /* - Call end request for req */
1443 lttv_hooks_call(events_request
->after_request
, (gpointer
)tsc
);
1445 /* - remove req from list_in */
1446 /* Destroy the request */
1453 GSList
*remove_iter
= iter
;
1455 iter
= g_slist_next(iter
);
1456 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
1457 list_in
= g_slist_remove_link(list_in
, remove_iter
);
1458 } else { // not remove
1459 iter
= g_slist_next(iter
);
1464 /* 5.1 For each req in list_in */
1465 GSList
*iter
= list_in
;
1467 while(iter
!= NULL
) {
1469 gboolean remove
= FALSE
;
1470 gboolean free_data
= FALSE
;
1471 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1473 /* - Remove events hooks for req
1474 * - Call end chunk for req
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
);
1496 lttv_hooks_call(events_request
->after_chunk_traceset
, tsc
);
1499 /* - req.num -= count */
1500 g_assert(events_request
->num_events
>= count
);
1501 events_request
->num_events
-= count
;
1503 g_assert(tfc
!= NULL
);
1504 /* - if req.num == 0
1506 * current context time >= req.end time
1508 * req.end pos == current pos
1510 * req.stop_flag == TRUE
1512 if( events_request
->num_events
== 0
1514 events_request
->stop_flag
== TRUE
1516 ltt_time_compare(tfc
->timestamp
,
1517 events_request
->end_time
) >= 0
1519 (events_request
->end_position
!= NULL
1521 lttv_traceset_context_ctx_pos_compare(tsc
,
1522 events_request
->end_position
) == 0)
1525 g_assert(events_request
->servicing
== TRUE
);
1526 /* - Call end request for req
1527 * - remove req from list_in */
1528 lttv_hooks_call(events_request
->after_request
, (gpointer
)tsc
);
1529 /* - remove req from list_in */
1530 /* Destroy the request */
1538 GSList
*remove_iter
= iter
;
1540 iter
= g_slist_next(iter
);
1541 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
1542 list_in
= g_slist_remove_link(list_in
, remove_iter
);
1543 } else { // not remove
1544 iter
= g_slist_next(iter
);
1550 /* End of removed servicing loop : leave control to GTK instead. */
1551 // if(gtk_events_pending()) break;
1554 /* B. When interrupted between chunks */
1557 GSList
*iter
= list_in
;
1559 /* 1. for each request in list_in */
1560 while(iter
!= NULL
) {
1562 gboolean remove
= FALSE
;
1563 gboolean free_data
= FALSE
;
1564 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1566 /* 1.1. Use current postition as start position */
1567 if(events_request
->start_position
!= NULL
)
1568 lttv_traceset_context_position_destroy(events_request
->start_position
);
1569 events_request
->start_position
= lttv_traceset_context_position_new();
1570 lttv_traceset_context_position_save(tsc
, events_request
->start_position
);
1572 /* 1.2. Remove start time */
1573 events_request
->start_time
= ltt_time_infinite
;
1575 /* 1.3. Move from list_in to list_out */
1578 list_out
= g_slist_append(list_out
, events_request
);
1583 GSList
*remove_iter
= iter
;
1585 iter
= g_slist_next(iter
);
1586 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
1587 list_in
= g_slist_remove_link(list_in
, remove_iter
);
1588 } else { // not remove
1589 iter
= g_slist_next(iter
);
1596 /* C Unlock Traces */
1598 //lttv_process_traceset_get_sync_data(tsc);
1603 iter_trace
<lttv_traceset_number(tsc
->ts
);
1605 LttvTrace
*trace_v
= lttv_traceset_get(tsc
->ts
, iter_trace
);
1607 lttvwindowtraces_unlock(trace_v
);
1612 //set the cursor back to normal
1613 gdk_window_set_cursor(win
, NULL
);
1616 g_assert(g_slist_length(list_in
) == 0);
1618 if( g_slist_length(list_out
) == 0 ) {
1619 /* Put tab's request pending flag back to normal */
1620 tab
->events_request_pending
= FALSE
;
1621 g_debug("remove the idle fct");
1622 return FALSE
; /* Remove the idle function */
1624 g_debug("leave the idle fct");
1625 return TRUE
; /* Leave the idle function */
1627 /* We do not use simili-round-robin, it may require to read 1 meg buffers
1628 * again and again if many tracesets use the same tracefiles. */
1629 /* Hack for round-robin idle functions */
1630 /* It will put the idle function at the end of the pool */
1631 /*g_idle_add_full((G_PRIORITY_HIGH_IDLE + 21),
1632 (GSourceFunc)execute_events_requests,
1642 static void lttvwindow_add_trace(Tab
*tab
, LttvTrace
*trace_v
)
1644 LttvTraceset
*traceset
= tab
->traceset_info
->traceset
;
1646 guint num_traces
= lttv_traceset_number(traceset
);
1648 //Verify if trace is already present.
1649 for(i
=0; i
<num_traces
; i
++)
1651 LttvTrace
* trace
= lttv_traceset_get(traceset
, i
);
1652 if(trace
== trace_v
)
1656 //Keep a reference to the traces so they are not freed.
1657 for(i
=0; i
<lttv_traceset_number(traceset
); i
++)
1659 LttvTrace
* trace
= lttv_traceset_get(traceset
, i
);
1660 lttv_trace_ref(trace
);
1663 //remove state update hooks
1664 lttv_state_remove_event_hooks(
1665 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1667 lttv_context_fini(LTTV_TRACESET_CONTEXT(
1668 tab
->traceset_info
->traceset_context
));
1669 g_object_unref(tab
->traceset_info
->traceset_context
);
1671 lttv_traceset_add(traceset
, trace_v
);
1672 lttv_trace_ref(trace_v
); /* local ref */
1674 /* Create new context */
1675 tab
->traceset_info
->traceset_context
=
1676 g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
1678 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->
1683 //add state update hooks
1684 lttv_state_add_event_hooks(
1685 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1686 //Remove local reference to the traces.
1687 for(i
=0; i
<lttv_traceset_number(traceset
); i
++)
1689 LttvTrace
* trace
= lttv_traceset_get(traceset
, i
);
1690 lttv_trace_unref(trace
);
1694 //add_trace_into_traceset_selector(GTK_MULTIVPANED(tab->multivpaned), lttv_trace(trace_v));
1697 /* add_trace adds a trace into the current traceset. It first displays a
1698 * directory selection dialogue to let user choose a trace, then recreates
1699 * tracset_context, and redraws all the viewer of the current tab
1702 void add_trace(GtkWidget
* widget
, gpointer user_data
)
1705 LttvTrace
* trace_v
;
1706 LttvTraceset
* traceset
;
1708 char abs_path
[PATH_MAX
];
1710 MainWindow
* mw_data
= get_window_data_struct(widget
);
1711 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
1713 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
1714 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
1718 tab
= create_new_tab(widget
, NULL
);
1720 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
1723 GtkDirSelection
* file_selector
= (GtkDirSelection
*)gtk_dir_selection_new("Select a trace");
1724 gtk_dir_selection_hide_fileop_buttons(file_selector
);
1726 if(remember_trace_dir
[0] != '\0')
1727 gtk_dir_selection_set_filename(file_selector
, remember_trace_dir
);
1729 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
1731 case GTK_RESPONSE_ACCEPT
:
1732 case GTK_RESPONSE_OK
:
1733 dir
= gtk_dir_selection_get_dir (file_selector
);
1734 strncpy(remember_trace_dir
, dir
, PATH_MAX
);
1735 if(!dir
|| strlen(dir
) == 0){
1736 gtk_widget_destroy((GtkWidget
*)file_selector
);
1739 get_absolute_pathname(dir
, abs_path
);
1740 trace_v
= lttvwindowtraces_get_trace_by_name(abs_path
);
1741 if(trace_v
== NULL
) {
1742 trace
= ltt_trace_open(abs_path
);
1744 g_warning("cannot open trace %s", abs_path
);
1746 trace_v
= lttv_trace_new(trace
);
1747 lttvwindowtraces_add_trace(trace_v
);
1748 lttvwindow_add_trace(tab
, trace_v
);
1751 lttvwindow_add_trace(tab
, trace_v
);
1754 gtk_widget_destroy((GtkWidget
*)file_selector
);
1756 //update current tab
1757 //update_traceset(mw_data);
1759 /* Call the updatetraceset hooks */
1761 traceset
= tab
->traceset_info
->traceset
;
1762 SetTraceset(tab
, traceset
);
1763 // in expose now call_pending_read_hooks(mw_data);
1765 //lttvwindow_report_current_time(mw_data,&(tab->current_time));
1767 case GTK_RESPONSE_REJECT
:
1768 case GTK_RESPONSE_CANCEL
:
1770 gtk_widget_destroy((GtkWidget
*)file_selector
);
1775 /* remove_trace removes a trace from the current traceset if all viewers in
1776 * the current tab are not interested in the trace. It first displays a
1777 * dialogue, which shows all traces in the current traceset, to let user choose
1778 * a trace, then it checks if all viewers unselect the trace, if it is true,
1779 * it will remove the trace, recreate the traceset_contex,
1780 * and redraws all the viewer of the current tab. If there is on trace in the
1781 * current traceset, it will delete all viewers of the current tab
1784 // MD : no filter version.
1785 void remove_trace(GtkWidget
*widget
, gpointer user_data
)
1788 LttvTrace
* trace_v
;
1789 LttvTraceset
* traceset
;
1790 gint i
, j
, nb_trace
, index
=-1;
1791 char ** name
, *remove_trace_name
;
1792 MainWindow
* mw_data
= get_window_data_struct(widget
);
1793 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
1795 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
1796 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
1802 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
1805 nb_trace
=lttv_traceset_number(tab
->traceset_info
->traceset
);
1806 name
= g_new(char*,nb_trace
);
1807 for(i
= 0; i
< nb_trace
; i
++){
1808 trace_v
= lttv_traceset_get(tab
->traceset_info
->traceset
, i
);
1809 trace
= lttv_trace(trace_v
);
1810 name
[i
] = ltt_trace_name(trace
);
1813 remove_trace_name
= get_remove_trace(name
, nb_trace
);
1816 if(remove_trace_name
){
1818 /* yuk, cut n paste from old code.. should be better (MD)*/
1819 for(i
= 0; i
<nb_trace
; i
++) {
1820 if(strcmp(remove_trace_name
,name
[i
]) == 0){
1825 traceset
= tab
->traceset_info
->traceset
;
1826 //Keep a reference to the traces so they are not freed.
1827 for(j
=0; j
<lttv_traceset_number(traceset
); j
++)
1829 LttvTrace
* trace
= lttv_traceset_get(traceset
, j
);
1830 lttv_trace_ref(trace
);
1833 //remove state update hooks
1834 lttv_state_remove_event_hooks(
1835 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1836 lttv_context_fini(LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
));
1837 g_object_unref(tab
->traceset_info
->traceset_context
);
1839 trace_v
= lttv_traceset_get(traceset
, index
);
1841 lttv_traceset_remove(traceset
, index
);
1842 lttv_trace_unref(trace_v
); // Remove local reference
1844 if(lttv_trace_get_ref_number(trace_v
) <= 1) {
1845 /* ref 1 : lttvwindowtraces only*/
1846 ltt_trace_close(lttv_trace(trace_v
));
1847 /* lttvwindowtraces_remove_trace takes care of destroying
1848 * the traceset linked with the trace_v and also of destroying
1849 * the trace_v at the same time.
1851 lttvwindowtraces_remove_trace(trace_v
);
1854 tab
->traceset_info
->traceset_context
=
1855 g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
1857 LTTV_TRACESET_CONTEXT(tab
->
1858 traceset_info
->traceset_context
),traceset
);
1859 //add state update hooks
1860 lttv_state_add_event_hooks(
1861 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1863 //Remove local reference to the traces.
1864 for(j
=0; j
<lttv_traceset_number(traceset
); j
++)
1866 LttvTrace
* trace
= lttv_traceset_get(traceset
, j
);
1867 lttv_trace_unref(trace
);
1870 SetTraceset(tab
, (gpointer
)traceset
);
1876 void remove_trace(GtkWidget
* widget
, gpointer user_data
)
1879 LttvTrace
* trace_v
;
1880 LttvTraceset
* traceset
;
1881 gint i
, j
, nb_trace
;
1882 char ** name
, *remove_trace_name
;
1883 MainWindow
* mw_data
= get_window_data_struct(widget
);
1884 LttvTracesetSelector
* s
;
1885 LttvTraceSelector
* t
;
1888 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
1890 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
1891 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
1897 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
1900 nb_trace
=lttv_traceset_number(tab
->traceset_info
->traceset
);
1901 name
= g_new(char*,nb_trace
);
1902 for(i
= 0; i
< nb_trace
; i
++){
1903 trace_v
= lttv_traceset_get(tab
->traceset_info
->traceset
, i
);
1904 trace
= lttv_trace(trace_v
);
1905 name
[i
] = ltt_trace_name(trace
);
1908 remove_trace_name
= get_remove_trace(name
, nb_trace
);
1910 if(remove_trace_name
){
1911 for(i
=0; i
<nb_trace
; i
++){
1912 if(strcmp(remove_trace_name
,name
[i
]) == 0){
1913 //unselect the trace from the current viewer
1915 w
= gtk_multivpaned_get_widget(GTK_MULTIVPANED(tab
->multivpaned
));
1917 s
= g_object_get_data(G_OBJECT(w
), "Traceset_Selector");
1919 t
= lttv_traceset_selector_trace_get(s
,i
);
1920 lttv_trace_selector_set_selected(t
, FALSE
);
1923 //check if other viewers select the trace
1924 w
= gtk_multivpaned_get_first_widget(GTK_MULTIVPANED(tab
->multivpaned
));
1926 s
= g_object_get_data(G_OBJECT(w
), "Traceset_Selector");
1928 t
= lttv_traceset_selector_trace_get(s
,i
);
1929 selected
= lttv_trace_selector_get_selected(t
);
1932 w
= gtk_multivpaned_get_next_widget(GTK_MULTIVPANED(tab
->multivpaned
));
1934 }else selected
= FALSE
;
1936 //if no viewer selects the trace, remove it
1938 remove_trace_from_traceset_selector(GTK_MULTIVPANED(tab
->multivpaned
), i
);
1940 traceset
= tab
->traceset_info
->traceset
;
1941 //Keep a reference to the traces so they are not freed.
1942 for(j
=0; j
<lttv_traceset_number(traceset
); j
++)
1944 LttvTrace
* trace
= lttv_traceset_get(traceset
, j
);
1945 lttv_trace_ref(trace
);
1948 //remove state update hooks
1949 lttv_state_remove_event_hooks(
1950 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1951 lttv_context_fini(LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
));
1952 g_object_unref(tab
->traceset_info
->traceset_context
);
1955 trace_v
= lttv_traceset_get(traceset
, i
);
1957 if(lttv_trace_get_ref_number(trace_v
) <= 2) {
1958 /* ref 2 : traceset, local */
1959 lttvwindowtraces_remove_trace(trace_v
);
1960 ltt_trace_close(lttv_trace(trace_v
));
1963 lttv_traceset_remove(traceset
, i
);
1964 lttv_trace_unref(trace_v
); // Remove local reference
1966 if(!lttv_trace_get_ref_number(trace_v
))
1967 lttv_trace_destroy(trace_v
);
1969 tab
->traceset_info
->traceset_context
=
1970 g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
1972 LTTV_TRACESET_CONTEXT(tab
->
1973 traceset_info
->traceset_context
),traceset
);
1974 //add state update hooks
1975 lttv_state_add_event_hooks(
1976 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1978 //Remove local reference to the traces.
1979 for(j
=0; j
<lttv_traceset_number(traceset
); j
++)
1981 LttvTrace
* trace
= lttv_traceset_get(traceset
, j
);
1982 lttv_trace_unref(trace
);
1986 //update current tab
1987 //update_traceset(mw_data);
1990 SetTraceset(tab
, (gpointer
)traceset
);
1991 // in expose now call_pending_read_hooks(mw_data);
1993 //lttvwindow_report_current_time(mw_data,&(tab->current_time));
1996 // while(tab->multi_vpaned->num_children){
1997 // gtk_multi_vpaned_widget_delete(tab->multi_vpaned);
2011 /* Redraw all the viewers in the current tab */
2012 void redraw(GtkWidget
*widget
, gpointer user_data
)
2014 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
2015 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2016 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2021 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
2025 LttvAttributeValue value
;
2027 g_assert(lttv_iattribute_find_by_path(tab
->attributes
, "hooks/redraw", LTTV_POINTER
, &value
));
2029 tmp
= (LttvHooks
*)*(value
.v_pointer
);
2031 lttv_hooks_call(tmp
,NULL
);
2035 void continue_processing(GtkWidget
*widget
, gpointer user_data
)
2037 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
2038 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2039 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2044 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
2048 LttvAttributeValue value
;
2050 g_assert(lttv_iattribute_find_by_path(tab
->attributes
,
2051 "hooks/continue", LTTV_POINTER
, &value
));
2053 tmp
= (LttvHooks
*)*(value
.v_pointer
);
2055 lttv_hooks_call(tmp
,NULL
);
2058 /* Stop the processing for the calling main window's current tab.
2059 * It removes every processing requests that are in its list. It does not call
2060 * the end request hooks, because the request is not finished.
2063 void stop_processing(GtkWidget
*widget
, gpointer user_data
)
2065 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
2066 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2067 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2072 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
2074 GSList
*iter
= tab
->events_requests
;
2076 while(iter
!= NULL
) {
2077 GSList
*remove_iter
= iter
;
2078 iter
= g_slist_next(iter
);
2080 g_free(remove_iter
->data
);
2081 tab
->events_requests
=
2082 g_slist_remove_link(tab
->events_requests
, remove_iter
);
2084 tab
->events_request_pending
= FALSE
;
2085 g_idle_remove_by_data(tab
);
2086 g_assert(g_slist_length(tab
->events_requests
) == 0);
2090 /* save will save the traceset to a file
2091 * Not implemented yet FIXME
2094 void save(GtkWidget
* widget
, gpointer user_data
)
2099 void save_as(GtkWidget
* widget
, gpointer user_data
)
2101 g_info("Save as\n");
2105 /* zoom will change the time_window of all the viewers of the
2106 * current tab, and redisplay them. The main functionality is to
2107 * determine the new time_window of the current tab
2110 void zoom(GtkWidget
* widget
, double size
)
2112 TimeInterval time_span
;
2113 TimeWindow new_time_window
;
2114 LttTime current_time
, time_delta
;
2115 MainWindow
* mw_data
= get_window_data_struct(widget
);
2116 LttvTracesetContext
*tsc
;
2117 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
2119 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2120 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2126 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
2129 if(size
== 1) return;
2131 tsc
= LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
2132 time_span
= tsc
->time_span
;
2133 new_time_window
= tab
->time_window
;
2134 current_time
= tab
->current_time
;
2136 time_delta
= ltt_time_sub(time_span
.end_time
,time_span
.start_time
);
2138 new_time_window
.start_time
= time_span
.start_time
;
2139 new_time_window
.time_width
= time_delta
;
2140 new_time_window
.time_width_double
= ltt_time_to_double(time_delta
);
2141 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
2142 new_time_window
.time_width
) ;
2144 new_time_window
.time_width
= ltt_time_div(new_time_window
.time_width
, size
);
2145 new_time_window
.time_width_double
=
2146 ltt_time_to_double(new_time_window
.time_width
);
2147 if(ltt_time_compare(new_time_window
.time_width
,time_delta
) > 0)
2148 { /* Case where zoom out is bigger than trace length */
2149 new_time_window
.start_time
= time_span
.start_time
;
2150 new_time_window
.time_width
= time_delta
;
2151 new_time_window
.time_width_double
= ltt_time_to_double(time_delta
);
2152 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
2153 new_time_window
.time_width
) ;
2157 /* Center the image on the current time */
2158 new_time_window
.start_time
=
2159 ltt_time_sub(current_time
,
2160 ltt_time_from_double(new_time_window
.time_width_double
/2.0));
2161 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
2162 new_time_window
.time_width
) ;
2163 /* If on borders, don't fall off */
2164 if(ltt_time_compare(new_time_window
.start_time
, time_span
.start_time
) <0)
2166 new_time_window
.start_time
= time_span
.start_time
;
2167 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
2168 new_time_window
.time_width
) ;
2172 if(ltt_time_compare(new_time_window
.end_time
,
2173 time_span
.end_time
) > 0)
2175 new_time_window
.start_time
=
2176 ltt_time_sub(time_span
.end_time
, new_time_window
.time_width
);
2178 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
2179 new_time_window
.time_width
) ;
2186 if(ltt_time_compare(new_time_window
.time_width
, ltt_time_zero
) == 0) {
2187 g_warning("Zoom more than 1 ns impossible");
2189 time_change_manager(tab
, new_time_window
);
2193 void zoom_in(GtkWidget
* widget
, gpointer user_data
)
2198 void zoom_out(GtkWidget
* widget
, gpointer user_data
)
2203 void zoom_extended(GtkWidget
* widget
, gpointer user_data
)
2208 void go_to_time(GtkWidget
* widget
, gpointer user_data
)
2210 g_info("Go to time\n");
2213 void show_time_frame(GtkWidget
* widget
, gpointer user_data
)
2215 g_info("Show time frame\n");
2219 /* callback function */
2222 on_empty_traceset_activate (GtkMenuItem
*menuitem
,
2225 create_new_window((GtkWidget
*)menuitem
, user_data
, FALSE
);
2230 on_clone_traceset_activate (GtkMenuItem
*menuitem
,
2233 create_new_window((GtkWidget
*)menuitem
, user_data
, TRUE
);
2237 /* create_new_tab calls create_tab to construct a new tab in the main window
2240 Tab
*create_new_tab(GtkWidget
* widget
, gpointer user_data
){
2241 gchar label
[PATH_MAX
];
2242 MainWindow
* mw_data
= get_window_data_struct(widget
);
2244 GtkNotebook
* notebook
= (GtkNotebook
*)lookup_widget(widget
, "MNotebook");
2245 if(notebook
== NULL
){
2246 g_info("Notebook does not exist\n");
2249 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2250 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2256 copy_tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
2259 strcpy(label
,"Page");
2260 if(get_label(mw_data
, label
,"Get the name of the tab","Please input tab's name"))
2261 return (create_tab (mw_data
, copy_tab
, notebook
, label
));
2265 on_tab_activate (GtkMenuItem
*menuitem
,
2268 create_new_tab((GtkWidget
*)menuitem
, user_data
);
2273 on_open_activate (GtkMenuItem
*menuitem
,
2276 open_traceset((GtkWidget
*)menuitem
, user_data
);
2281 on_close_activate (GtkMenuItem
*menuitem
,
2284 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2285 main_window_destructor(mw_data
);
2289 /* remove the current tab from the main window
2293 on_close_tab_activate (GtkWidget
*widget
,
2297 GtkWidget
* notebook
;
2299 MainWindow
* mw_data
= get_window_data_struct(widget
);
2300 notebook
= lookup_widget(widget
, "MNotebook");
2301 if(notebook
== NULL
){
2302 g_info("Notebook does not exist\n");
2306 page_num
= gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
));
2308 gtk_notebook_remove_page(GTK_NOTEBOOK(notebook
), page_num
);
2313 on_close_tab_X_clicked (GtkWidget
*widget
,
2317 GtkWidget
*notebook
= lookup_widget(widget
, "MNotebook");
2318 if(notebook
== NULL
){
2319 g_info("Notebook does not exist\n");
2323 if((page_num
= gtk_notebook_page_num(GTK_NOTEBOOK(notebook
), widget
)) != -1)
2324 gtk_notebook_remove_page(GTK_NOTEBOOK(notebook
), page_num
);
2330 on_add_trace_activate (GtkMenuItem
*menuitem
,
2333 add_trace((GtkWidget
*)menuitem
, user_data
);
2338 on_remove_trace_activate (GtkMenuItem
*menuitem
,
2341 remove_trace((GtkWidget
*)menuitem
, user_data
);
2346 on_save_activate (GtkMenuItem
*menuitem
,
2349 save((GtkWidget
*)menuitem
, user_data
);
2354 on_save_as_activate (GtkMenuItem
*menuitem
,
2357 save_as((GtkWidget
*)menuitem
, user_data
);
2362 on_quit_activate (GtkMenuItem
*menuitem
,
2370 on_cut_activate (GtkMenuItem
*menuitem
,
2378 on_copy_activate (GtkMenuItem
*menuitem
,
2386 on_paste_activate (GtkMenuItem
*menuitem
,
2394 on_delete_activate (GtkMenuItem
*menuitem
,
2402 on_zoom_in_activate (GtkMenuItem
*menuitem
,
2405 zoom_in((GtkWidget
*)menuitem
, user_data
);
2410 on_zoom_out_activate (GtkMenuItem
*menuitem
,
2413 zoom_out((GtkWidget
*)menuitem
, user_data
);
2418 on_zoom_extended_activate (GtkMenuItem
*menuitem
,
2421 zoom_extended((GtkWidget
*)menuitem
, user_data
);
2426 on_go_to_time_activate (GtkMenuItem
*menuitem
,
2429 go_to_time((GtkWidget
*)menuitem
, user_data
);
2434 on_show_time_frame_activate (GtkMenuItem
*menuitem
,
2437 show_time_frame((GtkWidget
*)menuitem
, user_data
);
2442 on_move_viewer_up_activate (GtkMenuItem
*menuitem
,
2445 move_up_viewer((GtkWidget
*)menuitem
, user_data
);
2450 on_move_viewer_down_activate (GtkMenuItem
*menuitem
,
2453 move_down_viewer((GtkWidget
*)menuitem
, user_data
);
2458 on_remove_viewer_activate (GtkMenuItem
*menuitem
,
2461 delete_viewer((GtkWidget
*)menuitem
, user_data
);
2465 on_trace_facility_activate (GtkMenuItem
*menuitem
,
2468 g_info("Trace facility selector: %s\n");
2472 /* Dispaly a file selection dialogue to let user select a library, then call
2473 * lttv_library_load().
2477 on_load_library_activate (GtkMenuItem
*menuitem
,
2480 GError
*error
= NULL
;
2481 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2483 gchar load_module_path_alter
[PATH_MAX
];
2487 gchar
*load_module_path
;
2488 name
= g_ptr_array_new();
2489 nb
= lttv_library_path_number();
2490 /* ask for the library path */
2494 path
= lttv_library_path_get(i
);
2495 g_ptr_array_add(name
, path
);
2498 load_module_path
= get_selection((char **)(name
->pdata
), name
->len
,
2499 "Select a library path", "Library paths");
2500 if(load_module_path
!= NULL
)
2501 strncpy(load_module_path_alter
, load_module_path
, PATH_MAX
-1); // -1 for /
2503 g_ptr_array_free(name
, TRUE
);
2505 if(load_module_path
== NULL
) return;
2509 /* Make sure the module path ends with a / */
2510 gchar
*ptr
= load_module_path_alter
;
2512 ptr
= strchr(ptr
, '\0');
2514 if(*(ptr
-1) != '/') {
2521 /* Ask for the library to load : list files in the previously selected
2523 gchar str
[PATH_MAX
];
2526 GtkFileSelection
* file_selector
=
2527 (GtkFileSelection
*)gtk_file_selection_new("Select a module");
2528 gtk_file_selection_set_filename(file_selector
, load_module_path_alter
);
2529 gtk_file_selection_hide_fileop_buttons(file_selector
);
2532 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
2534 case GTK_RESPONSE_ACCEPT
:
2535 case GTK_RESPONSE_OK
:
2536 dir
= gtk_file_selection_get_selections (file_selector
);
2537 strncpy(str
,dir
[0],PATH_MAX
);
2538 strncpy(remember_plugins_dir
,dir
[0],PATH_MAX
);
2539 /* only keep file name */
2541 str1
= strrchr(str
,'/');
2544 str1
= strrchr(str
,'\\');
2549 if(*str1
== 'l' && *(str1
+1)== 'i' && *(str1
+2)=='b')
2551 remove info after
. */
2555 str2
= strrchr(str2
, '.');
2556 if(str2
!= NULL
) *str2
= '\0';
2558 lttv_module_require(str1
, &error
);
2560 lttv_library_load(str1
, &error
);
2561 if(error
!= NULL
) g_warning("%s", error
->message
);
2562 else g_info("Load library: %s\n", str
);
2564 case GTK_RESPONSE_REJECT
:
2565 case GTK_RESPONSE_CANCEL
:
2567 gtk_widget_destroy((GtkWidget
*)file_selector
);
2578 /* Display all loaded modules, let user to select a module to unload
2579 * by calling lttv_module_unload
2583 on_unload_library_activate (GtkMenuItem
*menuitem
,
2586 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2588 LttvLibrary
*library
= NULL
;
2593 name
= g_ptr_array_new();
2594 nb
= lttv_library_number();
2595 LttvLibraryInfo
*lib_info
= g_new(LttvLibraryInfo
,nb
);
2596 /* ask for the library name */
2599 LttvLibrary
*iter_lib
= lttv_library_get(i
);
2600 lttv_library_info(iter_lib
, &lib_info
[i
]);
2602 gchar
*path
= lib_info
[i
].name
;
2603 g_ptr_array_add(name
, path
);
2605 lib_name
= get_selection((char **)(name
->pdata
), name
->len
,
2606 "Select a library", "Libraries");
2607 if(lib_name
!= NULL
) {
2609 if(strcmp(lib_name
, lib_info
[i
].name
) == 0) {
2610 library
= lttv_library_get(i
);
2615 g_ptr_array_free(name
, TRUE
);
2618 if(lib_name
== NULL
) return;
2620 if(library
!= NULL
) lttv_library_unload(library
);
2624 /* Dispaly a file selection dialogue to let user select a module, then call
2625 * lttv_module_require().
2629 on_load_module_activate (GtkMenuItem
*menuitem
,
2632 GError
*error
= NULL
;
2633 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2635 LttvLibrary
*library
= NULL
;
2640 name
= g_ptr_array_new();
2641 nb
= lttv_library_number();
2642 LttvLibraryInfo
*lib_info
= g_new(LttvLibraryInfo
,nb
);
2643 /* ask for the library name */
2646 LttvLibrary
*iter_lib
= lttv_library_get(i
);
2647 lttv_library_info(iter_lib
, &lib_info
[i
]);
2649 gchar
*path
= lib_info
[i
].name
;
2650 g_ptr_array_add(name
, path
);
2652 lib_name
= get_selection((char **)(name
->pdata
), name
->len
,
2653 "Select a library", "Libraries");
2654 if(lib_name
!= NULL
) {
2656 if(strcmp(lib_name
, lib_info
[i
].name
) == 0) {
2657 library
= lttv_library_get(i
);
2662 g_ptr_array_free(name
, TRUE
);
2665 if(lib_name
== NULL
) return;
2668 //LttvModule *module;
2669 gchar module_name_out
[PATH_MAX
];
2671 /* Ask for the module to load : list modules in the selected lib */
2675 nb
= lttv_library_module_number(library
);
2676 LttvModuleInfo
*module_info
= g_new(LttvModuleInfo
,nb
);
2677 name
= g_ptr_array_new();
2678 /* ask for the module name */
2681 LttvModule
*iter_module
= lttv_library_module_get(library
, i
);
2682 lttv_module_info(iter_module
, &module_info
[i
]);
2684 gchar
*path
= module_info
[i
].name
;
2685 g_ptr_array_add(name
, path
);
2687 module_name
= get_selection((char **)(name
->pdata
), name
->len
,
2688 "Select a module", "Modules");
2689 if(module_name
!= NULL
) {
2691 if(strcmp(module_name
, module_info
[i
].name
) == 0) {
2692 strncpy(module_name_out
, module_name
, PATH_MAX
);
2693 //module = lttv_library_module_get(i);
2699 g_ptr_array_free(name
, TRUE
);
2700 g_free(module_info
);
2702 if(module_name
== NULL
) return;
2705 lttv_module_require(module_name_out
, &error
);
2706 if(error
!= NULL
) g_warning("%s", error
->message
);
2707 else g_info("Load module: %s", module_name_out
);
2714 gchar str
[PATH_MAX
];
2717 GtkFileSelection
* file_selector
=
2718 (GtkFileSelection
*)gtk_file_selection_new("Select a module");
2719 gtk_file_selection_set_filename(file_selector
, load_module_path_alter
);
2720 gtk_file_selection_hide_fileop_buttons(file_selector
);
2723 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
2725 case GTK_RESPONSE_ACCEPT
:
2726 case GTK_RESPONSE_OK
:
2727 dir
= gtk_file_selection_get_selections (file_selector
);
2728 strncpy(str
,dir
[0],PATH_MAX
);
2729 strncpy(remember_plugins_dir
,dir
[0],PATH_MAX
);
2731 /* only keep file name */
2733 str1
= strrchr(str
,'/');
2736 str1
= strrchr(str
,'\\');
2741 if(*str1
== 'l' && *(str1
+1)== 'i' && *(str1
+2)=='b')
2743 remove info after
. */
2747 str2
= strrchr(str2
, '.');
2748 if(str2
!= NULL
) *str2
= '\0';
2750 lttv_module_require(str1
, &error
);
2752 lttv_library_load(str1
, &error
);
2753 if(error
!= NULL
) g_warning(error
->message
);
2754 else g_info("Load library: %s\n", str
);
2756 case GTK_RESPONSE_REJECT
:
2757 case GTK_RESPONSE_CANCEL
:
2759 gtk_widget_destroy((GtkWidget
*)file_selector
);
2771 /* Display all loaded modules, let user to select a module to unload
2772 * by calling lttv_module_unload
2776 on_unload_module_activate (GtkMenuItem
*menuitem
,
2779 GError
*error
= NULL
;
2780 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2782 LttvLibrary
*library
;
2787 name
= g_ptr_array_new();
2788 nb
= lttv_library_number();
2789 LttvLibraryInfo
*lib_info
= g_new(LttvLibraryInfo
,nb
);
2790 /* ask for the library name */
2793 LttvLibrary
*iter_lib
= lttv_library_get(i
);
2794 lttv_library_info(iter_lib
, &lib_info
[i
]);
2796 gchar
*path
= lib_info
[i
].name
;
2797 g_ptr_array_add(name
, path
);
2799 lib_name
= get_selection((char **)(name
->pdata
), name
->len
,
2800 "Select a library", "Libraries");
2801 if(lib_name
!= NULL
) {
2803 if(strcmp(lib_name
, lib_info
[i
].name
) == 0) {
2804 library
= lttv_library_get(i
);
2809 g_ptr_array_free(name
, TRUE
);
2812 if(lib_name
== NULL
) return;
2815 LttvModule
*module
= NULL
;
2817 /* Ask for the module to load : list modules in the selected lib */
2821 nb
= lttv_library_module_number(library
);
2822 LttvModuleInfo
*module_info
= g_new(LttvModuleInfo
,nb
);
2823 name
= g_ptr_array_new();
2824 /* ask for the module name */
2827 LttvModule
*iter_module
= lttv_library_module_get(library
, i
);
2828 lttv_module_info(iter_module
, &module_info
[i
]);
2830 gchar
*path
= module_info
[i
].name
;
2831 if(module_info
[i
].use_count
> 0) g_ptr_array_add(name
, path
);
2833 module_name
= get_selection((char **)(name
->pdata
), name
->len
,
2834 "Select a module", "Modules");
2835 if(module_name
!= NULL
) {
2837 if(strcmp(module_name
, module_info
[i
].name
) == 0) {
2838 module
= lttv_library_module_get(library
, i
);
2844 g_ptr_array_free(name
, TRUE
);
2845 g_free(module_info
);
2847 if(module_name
== NULL
) return;
2850 LttvModuleInfo module_info
;
2851 lttv_module_info(module
, &module_info
);
2852 g_info("Release module: %s\n", module_info
.name
);
2854 lttv_module_release(module
);
2858 /* Display a directory dialogue to let user select a path for library searching
2862 on_add_library_search_path_activate (GtkMenuItem
*menuitem
,
2865 GtkDirSelection
* file_selector
= (GtkDirSelection
*)gtk_dir_selection_new("Select library path");
2869 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2870 if(remember_plugins_dir
[0] != '\0')
2871 gtk_dir_selection_set_filename(file_selector
, remember_plugins_dir
);
2873 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
2875 case GTK_RESPONSE_ACCEPT
:
2876 case GTK_RESPONSE_OK
:
2877 dir
= gtk_dir_selection_get_dir (file_selector
);
2878 strncpy(remember_plugins_dir
,dir
,PATH_MAX
);
2879 strncat(remember_plugins_dir
,"/",PATH_MAX
);
2880 lttv_library_path_add(dir
);
2881 case GTK_RESPONSE_REJECT
:
2882 case GTK_RESPONSE_CANCEL
:
2884 gtk_widget_destroy((GtkWidget
*)file_selector
);
2890 /* Display a directory dialogue to let user select a path for library searching
2894 on_remove_library_search_path_activate (GtkMenuItem
*menuitem
,
2897 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2899 const char *lib_path
;
2904 name
= g_ptr_array_new();
2905 nb
= lttv_library_path_number();
2906 /* ask for the library name */
2909 gchar
*path
= lttv_library_path_get(i
);
2910 g_ptr_array_add(name
, path
);
2912 lib_path
= get_selection((char **)(name
->pdata
), name
->len
,
2913 "Select a library path", "Library paths");
2915 g_ptr_array_free(name
, TRUE
);
2917 if(lib_path
== NULL
) return;
2920 lttv_library_path_remove(lib_path
);
2924 on_color_activate (GtkMenuItem
*menuitem
,
2932 on_save_configuration_activate (GtkMenuItem
*menuitem
,
2935 g_info("Save configuration\n");
2940 on_content_activate (GtkMenuItem
*menuitem
,
2943 g_info("Content\n");
2948 on_about_close_activate (GtkButton
*button
,
2951 GtkWidget
*about_widget
= GTK_WIDGET(user_data
);
2953 gtk_widget_destroy(about_widget
);
2957 on_about_activate (GtkMenuItem
*menuitem
,
2960 MainWindow
*main_window
= get_window_data_struct(GTK_WIDGET(menuitem
));
2961 GtkWidget
*window_widget
= main_window
->mwindow
;
2962 GtkWidget
*about_widget
= gtk_window_new(GTK_WINDOW_TOPLEVEL
);
2963 GtkWindow
*about_window
= GTK_WINDOW(about_widget
);
2964 gint window_width
, window_height
;
2966 gtk_window_set_title(about_window
, "About Linux Trace Toolkit");
2968 gtk_window_set_resizable(about_window
, FALSE
);
2969 gtk_window_set_transient_for(GTK_WINDOW(window_widget
), about_window
);
2970 gtk_window_set_destroy_with_parent(about_window
, TRUE
);
2971 gtk_window_set_modal(about_window
, FALSE
);
2973 /* Put the about window at the center of the screen */
2974 gtk_window_get_size(about_window
, &window_width
, &window_height
);
2975 gtk_window_move (about_window
,
2976 (gdk_screen_width() - window_width
)/2,
2977 (gdk_screen_height() - window_height
)/2);
2979 GtkWidget
*vbox
= gtk_vbox_new(FALSE
, 1);
2981 gtk_container_add(GTK_CONTAINER(about_widget
), vbox
);
2985 GtkWidget
*label1
= gtk_label_new("");
2986 gtk_misc_set_padding(GTK_MISC(label1
), 10, 20);
2987 gtk_label_set_markup(GTK_LABEL(label1
), "\
2988 <big>Linux Trace Toolkit</big>");
2989 gtk_label_set_justify(GTK_LABEL(label1
), GTK_JUSTIFY_CENTER
);
2991 GtkWidget
*label2
= gtk_label_new("");
2992 gtk_misc_set_padding(GTK_MISC(label2
), 10, 20);
2993 gtk_label_set_markup(GTK_LABEL(label2
), "\
2996 Michel Dagenais (New trace format, lttv main)\n\
2997 Mathieu Desnoyers (Directory structure, build with automake/conf,\n\
2998 lttv gui, control flow view, gui cooperative trace reading\n\
2999 scheduler with interruptible foreground and background\n\
3000 computation, detailed event list)\n\
3001 Benoit Des Ligneris, Eric Clement (Cluster adaptation, work in progress)\n\
3002 Xang-Xiu Yang (new trace reading library and converter, lttv gui, \n\
3003 detailed event list and statistics view)\n\
3004 Tom Zanussi (RelayFS)\n\
3006 Strongly inspired from the original Linux Trace Toolkit Visualizer made by\n\
3009 GtkWidget
*label3
= gtk_label_new("");
3010 gtk_label_set_markup(GTK_LABEL(label3
), "\
3011 Linux Trace Toolkit Viewer, Copyright (C) 2004\n\
3013 Mathieu Desnoyers\n\
3015 Linux Trace Toolkit comes with ABSOLUTELY NO WARRANTY.\n\
3016 This is free software, and you are welcome to redistribute it\n\
3017 under certain conditions. See COPYING for details.");
3018 gtk_misc_set_padding(GTK_MISC(label3
), 10, 20);
3020 gtk_box_pack_start_defaults(GTK_BOX(vbox
), label1
);
3021 gtk_box_pack_start_defaults(GTK_BOX(vbox
), label2
);
3022 gtk_box_pack_start_defaults(GTK_BOX(vbox
), label3
);
3024 GtkWidget
*hbox
= gtk_hbox_new(TRUE
, 0);
3025 gtk_box_pack_end(GTK_BOX(vbox
), hbox
, FALSE
, FALSE
, 0);
3026 GtkWidget
*close_button
= gtk_button_new_with_mnemonic("_Close");
3027 gtk_box_pack_end(GTK_BOX(hbox
), close_button
, FALSE
, FALSE
, 0);
3028 gtk_container_set_border_width(GTK_CONTAINER(close_button
), 20);
3030 g_signal_connect(G_OBJECT(close_button
), "clicked",
3031 G_CALLBACK(on_about_close_activate
),
3032 (gpointer
)about_widget
);
3034 gtk_widget_show_all(about_widget
);
3039 on_button_new_clicked (GtkButton
*button
,
3042 create_new_window((GtkWidget
*)button
, user_data
, TRUE
);
3046 on_button_new_tab_clicked (GtkButton
*button
,
3049 create_new_tab((GtkWidget
*)button
, user_data
);
3053 on_button_open_clicked (GtkButton
*button
,
3056 open_traceset((GtkWidget
*)button
, user_data
);
3061 on_button_add_trace_clicked (GtkButton
*button
,
3064 add_trace((GtkWidget
*)button
, user_data
);
3069 on_button_remove_trace_clicked (GtkButton
*button
,
3072 remove_trace((GtkWidget
*)button
, user_data
);
3076 on_button_redraw_clicked (GtkButton
*button
,
3079 redraw((GtkWidget
*)button
, user_data
);
3083 on_button_continue_processing_clicked (GtkButton
*button
,
3086 continue_processing((GtkWidget
*)button
, user_data
);
3090 on_button_stop_processing_clicked (GtkButton
*button
,
3093 stop_processing((GtkWidget
*)button
, user_data
);
3099 on_button_save_clicked (GtkButton
*button
,
3102 save((GtkWidget
*)button
, user_data
);
3107 on_button_save_as_clicked (GtkButton
*button
,
3110 save_as((GtkWidget
*)button
, user_data
);
3115 on_button_zoom_in_clicked (GtkButton
*button
,
3118 zoom_in((GtkWidget
*)button
, user_data
);
3123 on_button_zoom_out_clicked (GtkButton
*button
,
3126 zoom_out((GtkWidget
*)button
, user_data
);
3131 on_button_zoom_extended_clicked (GtkButton
*button
,
3134 zoom_extended((GtkWidget
*)button
, user_data
);
3139 on_button_go_to_time_clicked (GtkButton
*button
,
3142 go_to_time((GtkWidget
*)button
, user_data
);
3147 on_button_show_time_frame_clicked (GtkButton
*button
,
3150 show_time_frame((GtkWidget
*)button
, user_data
);
3155 on_button_move_up_clicked (GtkButton
*button
,
3158 move_up_viewer((GtkWidget
*)button
, user_data
);
3163 on_button_move_down_clicked (GtkButton
*button
,
3166 move_down_viewer((GtkWidget
*)button
, user_data
);
3171 on_button_delete_viewer_clicked (GtkButton
*button
,
3174 delete_viewer((GtkWidget
*)button
, user_data
);
3178 on_MWindow_destroy (GtkWidget
*widget
,
3181 MainWindow
*main_window
= get_window_data_struct(widget
);
3182 LttvIAttribute
*attributes
= main_window
->attributes
;
3183 LttvAttributeValue value
;
3185 //This is unnecessary, since widgets will be destroyed
3186 //by the main window widget anyway.
3187 //remove_all_menu_toolbar_constructors(main_window, NULL);
3189 g_assert(lttv_iattribute_find_by_path(attributes
,
3190 "viewers/menu", LTTV_POINTER
, &value
));
3191 lttv_menus_destroy((LttvMenus
*)*(value
.v_pointer
));
3193 g_assert(lttv_iattribute_find_by_path(attributes
,
3194 "viewers/toolbar", LTTV_POINTER
, &value
));
3195 lttv_toolbars_destroy((LttvToolbars
*)*(value
.v_pointer
));
3197 g_object_unref(main_window
->attributes
);
3198 g_main_window_list
= g_slist_remove(g_main_window_list
, main_window
);
3200 g_info("There are now : %d windows\n",g_slist_length(g_main_window_list
));
3201 if(g_slist_length(g_main_window_list
) == 0)
3206 on_MWindow_configure (GtkWidget
*widget
,
3207 GdkEventConfigure
*event
,
3210 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)widget
);
3212 // MD : removed time width modification upon resizing of the main window.
3213 // The viewers will redraw themselves completely, without time interval
3216 if(mw_data->window_width){
3217 time_span = LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context)->Time_Span ;
3218 time_win = tab->time_window;
3219 ratio = width / mw_data->window_width;
3220 tab->time_window.time_width = ltt_time_mul(time_win.time_width,ratio);
3221 time = ltt_time_sub(time_span->endTime, time_win.start_time);
3222 if(ltt_time_compare(time, tab->time_window.time_width) < 0){
3223 tab->time_window.time_width = time;
3229 mw_data->window_width = (int)width;
3238 on_MNotebook_switch_page (GtkNotebook
*notebook
,
3239 GtkNotebookPage
*page
,
3247 void time_change_manager (Tab
*tab
,
3248 TimeWindow new_time_window
)
3250 /* Only one source of time change */
3251 if(tab
->time_manager_lock
== TRUE
) return;
3253 tab
->time_manager_lock
= TRUE
;
3255 LttvTracesetContext
*tsc
= LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3256 TimeInterval time_span
= tsc
->time_span
;
3257 LttTime start_time
= new_time_window
.start_time
;
3258 LttTime end_time
= new_time_window
.end_time
;
3261 GtkAdjustment
*adjustment
= gtk_range_get_adjustment(GTK_RANGE(tab
->scrollbar
));
3262 LttTime upper
= ltt_time_sub(time_span
.end_time
, time_span
.start_time
);
3264 gtk_range_set_increments(GTK_RANGE(tab
->scrollbar
),
3265 ltt_time_to_double(new_time_window
.time_width
)
3266 / SCROLL_STEP_PER_PAGE
3267 * NANOSECONDS_PER_SECOND
, /* step increment */
3268 ltt_time_to_double(new_time_window
.time_width
)
3269 * NANOSECONDS_PER_SECOND
); /* page increment */
3270 gtk_range_set_range(GTK_RANGE(tab
->scrollbar
),
3272 ltt_time_to_double(upper
)
3273 * NANOSECONDS_PER_SECOND
); /* upper */
3275 g_object_set(G_OBJECT(adjustment
),
3279 ltt_time_to_double(upper
), /* upper */
3281 new_time_window
.time_width_double
3282 / SCROLL_STEP_PER_PAGE
, /* step increment */
3284 new_time_window
.time_width_double
,
3285 /* page increment */
3287 new_time_window
.time_width_double
, /* page size */
3289 gtk_adjustment_changed(adjustment
);
3291 // g_object_set(G_OBJECT(adjustment),
3293 // ltt_time_to_double(
3294 // ltt_time_sub(start_time, time_span.start_time))
3297 //gtk_adjustment_value_changed(adjustment);
3298 gtk_range_set_value(GTK_RANGE(tab
->scrollbar
),
3300 ltt_time_sub(start_time
, time_span
.start_time
)) /* value */);
3302 /* set the time bar. */
3304 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry1
),
3305 (double)time_span
.start_time
.tv_sec
,
3306 (double)time_span
.end_time
.tv_sec
);
3307 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry1
),
3308 (double)start_time
.tv_sec
);
3310 /* start nanoseconds */
3311 if(start_time
.tv_sec
== time_span
.start_time
.tv_sec
) {
3312 /* can be both beginning and end at the same time. */
3313 if(start_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3314 /* If we are at the end, max nsec to end.. -1 (not zero length) */
3315 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry2
),
3316 (double)time_span
.start_time
.tv_nsec
,
3317 (double)time_span
.end_time
.tv_nsec
-1);
3319 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry2
),
3320 (double)time_span
.start_time
.tv_nsec
,
3321 (double)NANOSECONDS_PER_SECOND
-1);
3323 } else if(start_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3324 /* If we are at the end, max nsec to end.. -1 (not zero length) */
3325 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry2
),
3327 (double)time_span
.end_time
.tv_nsec
-1);
3328 } else /* anywhere else */
3329 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry2
),
3331 (double)NANOSECONDS_PER_SECOND
-1);
3332 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry2
),
3333 (double)start_time
.tv_nsec
);
3336 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry3
),
3337 (double)time_span
.start_time
.tv_sec
,
3338 (double)time_span
.end_time
.tv_sec
);
3339 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry3
),
3340 (double)end_time
.tv_sec
);
3342 /* end nanoseconds */
3343 if(end_time
.tv_sec
== time_span
.start_time
.tv_sec
) {
3344 /* can be both beginning and end at the same time. */
3345 if(end_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3346 /* If we are at the end, max nsec to end.. */
3347 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry4
),
3348 (double)time_span
.start_time
.tv_nsec
+1,
3349 (double)time_span
.end_time
.tv_nsec
);
3351 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry4
),
3352 (double)time_span
.start_time
.tv_nsec
+1,
3353 (double)NANOSECONDS_PER_SECOND
-1);
3356 else if(end_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3357 /* If we are at the end, max nsec to end.. */
3358 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry4
),
3360 (double)time_span
.end_time
.tv_nsec
);
3362 else /* anywhere else */
3363 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry4
),
3365 (double)NANOSECONDS_PER_SECOND
-1);
3366 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry4
),
3367 (double)end_time
.tv_nsec
);
3369 /* call viewer hooks for new time window */
3370 set_time_window(tab
, &new_time_window
);
3372 tab
->time_manager_lock
= FALSE
;
3376 /* value changed for frame start s
3378 * Check time span : if ns is out of range, clip it the nearest good value.
3381 on_MEntry1_value_changed (GtkSpinButton
*spinbutton
,
3384 Tab
*tab
=(Tab
*)user_data
;
3385 LttvTracesetContext
* tsc
=
3386 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3387 TimeInterval time_span
= tsc
->time_span
;
3388 gint value
= gtk_spin_button_get_value_as_int(spinbutton
);
3390 TimeWindow new_time_window
= tab
->time_window
;
3392 LttTime end_time
= new_time_window
.end_time
;
3394 new_time_window
.start_time
.tv_sec
= value
;
3396 /* start nanoseconds */
3397 if(new_time_window
.start_time
.tv_sec
== time_span
.start_time
.tv_sec
) {
3398 if(new_time_window
.start_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3399 if(new_time_window
.start_time
.tv_nsec
> time_span
.end_time
.tv_nsec
)
3400 new_time_window
.start_time
.tv_nsec
= time_span
.end_time
.tv_nsec
-1;
3401 if(new_time_window
.start_time
.tv_nsec
< time_span
.start_time
.tv_nsec
)
3402 new_time_window
.start_time
.tv_nsec
= time_span
.start_time
.tv_nsec
;
3404 if(new_time_window
.start_time
.tv_nsec
< time_span
.start_time
.tv_nsec
)
3405 new_time_window
.start_time
.tv_nsec
= time_span
.start_time
.tv_nsec
;
3408 else if(new_time_window
.start_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3409 if(new_time_window
.start_time
.tv_nsec
> time_span
.end_time
.tv_nsec
)
3410 new_time_window
.start_time
.tv_nsec
= time_span
.end_time
.tv_nsec
-1;
3413 if(ltt_time_compare(new_time_window
.start_time
, end_time
) >= 0) {
3414 /* Then, we must push back end time : keep the same time width
3415 * if possible, else end traceset time */
3416 end_time
= LTT_TIME_MIN(ltt_time_add(new_time_window
.start_time
,
3417 new_time_window
.time_width
),
3418 time_span
.end_time
);
3421 /* Fix the time width to fit start time and end time */
3422 new_time_window
.time_width
= ltt_time_sub(end_time
,
3423 new_time_window
.start_time
);
3424 new_time_window
.time_width_double
=
3425 ltt_time_to_double(new_time_window
.time_width
);
3427 new_time_window
.end_time
= end_time
;
3429 time_change_manager(tab
, new_time_window
);
3434 on_MEntry2_value_changed (GtkSpinButton
*spinbutton
,
3437 Tab
*tab
=(Tab
*)user_data
;
3438 LttvTracesetContext
* tsc
=
3439 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3440 TimeInterval time_span
= tsc
->time_span
;
3441 gint value
= gtk_spin_button_get_value_as_int(spinbutton
);
3443 TimeWindow new_time_window
= tab
->time_window
;
3445 LttTime end_time
= new_time_window
.end_time
;
3447 new_time_window
.start_time
.tv_nsec
= value
;
3449 if(ltt_time_compare(new_time_window
.start_time
, end_time
) >= 0) {
3450 /* Then, we must push back end time : keep the same time width
3451 * if possible, else end traceset time */
3452 end_time
= LTT_TIME_MIN(ltt_time_add(new_time_window
.start_time
,
3453 new_time_window
.time_width
),
3454 time_span
.end_time
);
3457 /* Fix the time width to fit start time and end time */
3458 new_time_window
.time_width
= ltt_time_sub(end_time
,
3459 new_time_window
.start_time
);
3460 new_time_window
.time_width_double
=
3461 ltt_time_to_double(new_time_window
.time_width
);
3463 new_time_window
.end_time
= end_time
;
3465 time_change_manager(tab
, new_time_window
);
3470 on_MEntry3_value_changed (GtkSpinButton
*spinbutton
,
3473 Tab
*tab
=(Tab
*)user_data
;
3474 LttvTracesetContext
* tsc
=
3475 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3476 TimeInterval time_span
= tsc
->time_span
;
3477 gint value
= gtk_spin_button_get_value_as_int(spinbutton
);
3479 TimeWindow new_time_window
= tab
->time_window
;
3481 LttTime end_time
= new_time_window
.end_time
;
3483 end_time
.tv_sec
= value
;
3485 /* end nanoseconds */
3486 if(end_time
.tv_sec
== time_span
.start_time
.tv_sec
) {
3487 if(end_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3488 if(end_time
.tv_nsec
> time_span
.end_time
.tv_nsec
)
3489 end_time
.tv_nsec
= time_span
.end_time
.tv_nsec
;
3490 if(end_time
.tv_nsec
< time_span
.start_time
.tv_nsec
)
3491 end_time
.tv_nsec
= time_span
.start_time
.tv_nsec
+1;
3493 if(end_time
.tv_nsec
< time_span
.start_time
.tv_nsec
)
3494 end_time
.tv_nsec
= time_span
.start_time
.tv_nsec
+1;
3497 else if(end_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3498 if(end_time
.tv_nsec
> time_span
.end_time
.tv_nsec
)
3499 end_time
.tv_nsec
= time_span
.end_time
.tv_nsec
;
3502 if(ltt_time_compare(new_time_window
.start_time
, end_time
) >= 0) {
3503 /* Then, we must push front start time : keep the same time width
3504 * if possible, else end traceset time */
3505 new_time_window
.start_time
= LTT_TIME_MAX(
3506 ltt_time_sub(end_time
,
3507 new_time_window
.time_width
),
3508 time_span
.start_time
);
3511 /* Fix the time width to fit start time and end time */
3512 new_time_window
.time_width
= ltt_time_sub(end_time
,
3513 new_time_window
.start_time
);
3514 new_time_window
.time_width_double
=
3515 ltt_time_to_double(new_time_window
.time_width
);
3517 new_time_window
.end_time
= end_time
;
3519 time_change_manager(tab
, new_time_window
);
3524 on_MEntry4_value_changed (GtkSpinButton
*spinbutton
,
3527 Tab
*tab
=(Tab
*)user_data
;
3528 LttvTracesetContext
* tsc
=
3529 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3530 TimeInterval time_span
= tsc
->time_span
;
3531 gint value
= gtk_spin_button_get_value_as_int(spinbutton
);
3533 TimeWindow new_time_window
= tab
->time_window
;
3535 LttTime end_time
= new_time_window
.end_time
;
3537 end_time
.tv_nsec
= value
;
3539 if(ltt_time_compare(new_time_window
.start_time
, end_time
) >= 0) {
3540 /* Then, we must push front start time : keep the same time width
3541 * if possible, else end traceset time */
3542 new_time_window
.start_time
= LTT_TIME_MAX(
3543 ltt_time_sub(end_time
,
3544 new_time_window
.time_width
),
3545 time_span
.start_time
);
3548 /* Fix the time width to fit start time and end time */
3549 new_time_window
.time_width
= ltt_time_sub(end_time
,
3550 new_time_window
.start_time
);
3551 new_time_window
.time_width_double
=
3552 ltt_time_to_double(new_time_window
.time_width
);
3553 new_time_window
.end_time
= end_time
;
3555 time_change_manager(tab
, new_time_window
);
3560 void current_time_change_manager (Tab
*tab
,
3561 LttTime new_current_time
)
3563 /* Only one source of time change */
3564 if(tab
->current_time_manager_lock
== TRUE
) return;
3566 tab
->current_time_manager_lock
= TRUE
;
3568 LttvTracesetContext
*tsc
= LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3569 TimeInterval time_span
= tsc
->time_span
;
3571 /* current seconds */
3572 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry5
),
3573 (double)time_span
.start_time
.tv_sec
,
3574 (double)time_span
.end_time
.tv_sec
);
3575 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry5
),
3576 (double)new_current_time
.tv_sec
);
3579 /* start nanoseconds */
3580 if(new_current_time
.tv_sec
== time_span
.start_time
.tv_sec
) {
3581 /* can be both beginning and end at the same time. */
3582 if(new_current_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3583 /* If we are at the end, max nsec to end.. */
3584 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry6
),
3585 (double)time_span
.start_time
.tv_nsec
,
3586 (double)time_span
.end_time
.tv_nsec
);
3588 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry6
),
3589 (double)time_span
.start_time
.tv_nsec
,
3590 (double)NANOSECONDS_PER_SECOND
-1);
3592 } else if(new_current_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3593 /* If we are at the end, max nsec to end.. */
3594 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry6
),
3596 (double)time_span
.end_time
.tv_nsec
);
3597 } else /* anywhere else */
3598 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry6
),
3600 (double)NANOSECONDS_PER_SECOND
-1);
3602 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry6
),
3603 (double)new_current_time
.tv_nsec
);
3605 set_current_time(tab
, &new_current_time
);
3607 tab
->current_time_manager_lock
= FALSE
;
3611 on_MEntry5_value_changed (GtkSpinButton
*spinbutton
,
3614 Tab
*tab
= (Tab
*)user_data
;
3615 LttvTracesetContext
* tsc
=
3616 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3617 TimeInterval time_span
= tsc
->time_span
;
3618 gint value
= gtk_spin_button_get_value_as_int(spinbutton
);
3619 LttTime new_current_time
= tab
->current_time
;
3620 new_current_time
.tv_sec
= value
;
3622 /* current nanoseconds */
3623 if(new_current_time
.tv_sec
== time_span
.start_time
.tv_sec
) {
3624 if(new_current_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3625 if(new_current_time
.tv_nsec
> time_span
.end_time
.tv_nsec
)
3626 new_current_time
.tv_nsec
= time_span
.end_time
.tv_nsec
;
3627 if(new_current_time
.tv_nsec
< time_span
.start_time
.tv_nsec
)
3628 new_current_time
.tv_nsec
= time_span
.start_time
.tv_nsec
;
3630 if(new_current_time
.tv_nsec
< time_span
.start_time
.tv_nsec
)
3631 new_current_time
.tv_nsec
= time_span
.start_time
.tv_nsec
;
3634 else if(new_current_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3635 if(new_current_time
.tv_nsec
> time_span
.end_time
.tv_nsec
)
3636 new_current_time
.tv_nsec
= time_span
.end_time
.tv_nsec
;
3639 current_time_change_manager(tab
, new_current_time
);
3643 on_MEntry6_value_changed (GtkSpinButton
*spinbutton
,
3646 Tab
*tab
= (Tab
*)user_data
;
3647 gint value
= gtk_spin_button_get_value_as_int(spinbutton
);
3648 LttTime new_current_time
= tab
->current_time
;
3649 new_current_time
.tv_nsec
= value
;
3651 current_time_change_manager(tab
, new_current_time
);
3655 void scroll_value_changed_cb(GtkWidget
*scrollbar
,
3658 Tab
*tab
= (Tab
*)user_data
;
3659 TimeWindow new_time_window
;
3661 GtkAdjustment
*adjust
= gtk_range_get_adjustment(GTK_RANGE(scrollbar
));
3662 gdouble value
= gtk_adjustment_get_value(adjust
);
3663 // gdouble upper, lower, ratio, page_size;
3665 LttvTracesetContext
* tsc
=
3666 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3667 TimeInterval time_span
= tsc
->time_span
;
3669 time
= ltt_time_add(ltt_time_from_double(value
),
3670 time_span
.start_time
);
3672 new_time_window
.start_time
= time
;
3674 page_size
= adjust
->page_size
;
3676 new_time_window
.time_width
=
3677 ltt_time_from_double(page_size
);
3679 new_time_window
.time_width_double
=
3682 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
3683 new_time_window
.time_width
);
3686 time_change_manager(tab
, new_time_window
);
3688 //time_window = tab->time_window;
3690 lower
= adjust
->lower
;
3691 upper
= adjust
->upper
;
3692 ratio
= (value
- lower
) / (upper
- lower
);
3693 g_info("lower %lu, upper %lu, value %lu, ratio %lu", lower
, upper
, value
, ratio
);
3695 //time = ltt_time_sub(time_span->end_time, time_span->start_time);
3696 //time = ltt_time_mul(time, (float)ratio);
3697 //time = ltt_time_add(time_span->start_time, time);
3698 time
= ltt_time_add(ltt_time_from_double(value
),
3699 time_span
.start_time
);
3701 time_window
.start_time
= time
;
3703 page_size
= adjust
->page_size
;
3705 time_window
.time_width
=
3706 ltt_time_from_double(page_size
);
3707 //time = ltt_time_sub(time_span.end_time, time);
3708 //if(ltt_time_compare(time,time_window.time_width) < 0){
3709 // time_window.time_width = time;
3712 /* call viewer hooks for new time window */
3713 set_time_window(tab
, &time_window
);
3718 /* Display a dialogue showing all eventtypes and traces, let user to select the interested
3719 * eventtypes, tracefiles and traces (filter)
3722 /* Select a trace which will be removed from traceset
3725 char * get_remove_trace(char ** all_trace_name
, int nb_trace
)
3727 return get_selection(all_trace_name
, nb_trace
,
3728 "Select a trace", "Trace pathname");
3732 /* Select a module which will be loaded
3735 char * get_load_module(char ** load_module_name
, int nb_module
)
3737 return get_selection(load_module_name
, nb_module
,
3738 "Select a module to load", "Module name");
3744 /* Select a module which will be unloaded
3747 char * get_unload_module(char ** loaded_module_name
, int nb_module
)
3749 return get_selection(loaded_module_name
, nb_module
,
3750 "Select a module to unload", "Module name");
3754 /* Display a dialogue which shows all selectable items, let user to
3755 * select one of them
3758 char * get_selection(char ** loaded_module_name
, int nb_module
,
3759 char *title
, char * column_title
)
3761 GtkWidget
* dialogue
;
3762 GtkWidget
* scroll_win
;
3764 GtkListStore
* store
;
3765 GtkTreeViewColumn
* column
;
3766 GtkCellRenderer
* renderer
;
3767 GtkTreeSelection
* select
;
3770 char * unload_module_name
= NULL
;
3772 dialogue
= gtk_dialog_new_with_buttons(title
,
3775 GTK_STOCK_OK
,GTK_RESPONSE_ACCEPT
,
3776 GTK_STOCK_CANCEL
,GTK_RESPONSE_REJECT
,
3778 gtk_window_set_default_size((GtkWindow
*)dialogue
, 500, 200);
3780 scroll_win
= gtk_scrolled_window_new (NULL
, NULL
);
3781 gtk_widget_show ( scroll_win
);
3782 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll_win
),
3783 GTK_POLICY_AUTOMATIC
, GTK_POLICY_AUTOMATIC
);
3785 store
= gtk_list_store_new (N_COLUMNS
,G_TYPE_STRING
);
3786 tree
= gtk_tree_view_new_with_model(GTK_TREE_MODEL (store
));
3787 gtk_widget_show ( tree
);
3788 g_object_unref (G_OBJECT (store
));
3790 renderer
= gtk_cell_renderer_text_new ();
3791 column
= gtk_tree_view_column_new_with_attributes (column_title
,
3793 "text", MODULE_COLUMN
,
3795 gtk_tree_view_column_set_alignment (column
, 0.5);
3796 gtk_tree_view_column_set_fixed_width (column
, 150);
3797 gtk_tree_view_append_column (GTK_TREE_VIEW (tree
), column
);
3799 select
= gtk_tree_view_get_selection (GTK_TREE_VIEW (tree
));
3800 gtk_tree_selection_set_mode (select
, GTK_SELECTION_SINGLE
);
3802 gtk_container_add (GTK_CONTAINER (scroll_win
), tree
);
3804 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialogue
)->vbox
), scroll_win
,TRUE
, TRUE
,0);
3806 for(i
=0;i
<nb_module
;i
++){
3807 gtk_list_store_append (store
, &iter
);
3808 gtk_list_store_set (store
, &iter
, MODULE_COLUMN
,loaded_module_name
[i
],-1);
3811 id
= gtk_dialog_run(GTK_DIALOG(dialogue
));
3812 GtkTreeModel
**store_model
= (GtkTreeModel
**)&store
; /* for strict aliasing */
3814 case GTK_RESPONSE_ACCEPT
:
3815 case GTK_RESPONSE_OK
:
3816 if (gtk_tree_selection_get_selected (select
, store_model
, &iter
)){
3817 gtk_tree_model_get ((GtkTreeModel
*)store
, &iter
, MODULE_COLUMN
, &unload_module_name
, -1);
3819 case GTK_RESPONSE_REJECT
:
3820 case GTK_RESPONSE_CANCEL
:
3822 gtk_widget_destroy(dialogue
);
3826 return unload_module_name
;
3830 /* Insert all menu entry and tool buttons into this main window
3835 void add_all_menu_toolbar_constructors(MainWindow
* mw
, gpointer user_data
)
3839 lttvwindow_viewer_constructor constructor
;
3840 LttvMenus
* global_menu
, * instance_menu
;
3841 LttvToolbars
* global_toolbar
, * instance_toolbar
;
3842 LttvMenuClosure
*menu_item
;
3843 LttvToolbarClosure
*toolbar_item
;
3844 LttvAttributeValue value
;
3845 LttvIAttribute
*global_attributes
= LTTV_IATTRIBUTE(lttv_global_attributes());
3846 LttvIAttribute
*attributes
= mw
->attributes
;
3847 GtkWidget
* tool_menu_title_menu
, *new_widget
, *pixmap
;
3849 g_assert(lttv_iattribute_find_by_path(global_attributes
,
3850 "viewers/menu", LTTV_POINTER
, &value
));
3851 if(*(value
.v_pointer
) == NULL
)
3852 *(value
.v_pointer
) = lttv_menus_new();
3853 global_menu
= (LttvMenus
*)*(value
.v_pointer
);
3855 g_assert(lttv_iattribute_find_by_path(attributes
,
3856 "viewers/menu", LTTV_POINTER
, &value
));
3857 if(*(value
.v_pointer
) == NULL
)
3858 *(value
.v_pointer
) = lttv_menus_new();
3859 instance_menu
= (LttvMenus
*)*(value
.v_pointer
);
3863 g_assert(lttv_iattribute_find_by_path(global_attributes
,
3864 "viewers/toolbar", LTTV_POINTER
, &value
));
3865 if(*(value
.v_pointer
) == NULL
)
3866 *(value
.v_pointer
) = lttv_toolbars_new();
3867 global_toolbar
= (LttvToolbars
*)*(value
.v_pointer
);
3869 g_assert(lttv_iattribute_find_by_path(attributes
,
3870 "viewers/toolbar", LTTV_POINTER
, &value
));
3871 if(*(value
.v_pointer
) == NULL
)
3872 *(value
.v_pointer
) = lttv_toolbars_new();
3873 instance_toolbar
= (LttvToolbars
*)*(value
.v_pointer
);
3875 /* Add missing menu entries to window instance */
3876 for(i
=0;i
<global_menu
->len
;i
++) {
3877 menu_item
= &g_array_index(global_menu
, LttvMenuClosure
, i
);
3879 //add menu_item to window instance;
3880 constructor
= menu_item
->con
;
3881 tool_menu_title_menu
= lookup_widget(mw
->mwindow
,"ToolMenuTitle_menu");
3883 gtk_menu_item_new_with_mnemonic (menu_item
->menu_text
);
3884 gtk_container_add (GTK_CONTAINER (tool_menu_title_menu
),
3886 g_signal_connect ((gpointer
) new_widget
, "activate",
3887 G_CALLBACK (insert_viewer_wrap
),
3889 gtk_widget_show (new_widget
);
3890 lttv_menus_add(instance_menu
, menu_item
->con
,
3891 menu_item
->menu_path
,
3892 menu_item
->menu_text
,
3897 /* Add missing toolbar entries to window instance */
3898 for(i
=0;i
<global_toolbar
->len
;i
++) {
3899 toolbar_item
= &g_array_index(global_toolbar
, LttvToolbarClosure
, i
);
3901 //add toolbar_item to window instance;
3902 constructor
= toolbar_item
->con
;
3903 tool_menu_title_menu
= lookup_widget(mw
->mwindow
,"MToolbar1");
3904 pixbuf
= gdk_pixbuf_new_from_xpm_data((const char**)toolbar_item
->pixmap
);
3905 pixmap
= gtk_image_new_from_pixbuf(pixbuf
);
3907 gtk_toolbar_append_element (GTK_TOOLBAR (tool_menu_title_menu
),
3908 GTK_TOOLBAR_CHILD_BUTTON
,
3911 toolbar_item
->tooltip
, NULL
,
3912 pixmap
, NULL
, NULL
);
3913 gtk_label_set_use_underline(
3914 GTK_LABEL (((GtkToolbarChild
*) (
3915 g_list_last (GTK_TOOLBAR
3916 (tool_menu_title_menu
)->children
)->data
))->label
),
3918 gtk_container_set_border_width (GTK_CONTAINER (new_widget
), 1);
3919 g_signal_connect ((gpointer
) new_widget
,
3921 G_CALLBACK (insert_viewer_wrap
),
3923 gtk_widget_show (new_widget
);
3925 lttv_toolbars_add(instance_toolbar
, toolbar_item
->con
,
3926 toolbar_item
->tooltip
,
3927 toolbar_item
->pixmap
,
3935 /* Create a main window
3938 void construct_main_window(MainWindow
* parent
)
3940 g_debug("construct_main_window()");
3941 GtkWidget
* new_window
; /* New generated main window */
3942 MainWindow
* new_m_window
;/* New main window structure */
3943 GtkNotebook
* notebook
;
3944 LttvIAttribute
*attributes
=
3945 LTTV_IATTRIBUTE(g_object_new(LTTV_ATTRIBUTE_TYPE
, NULL
));
3946 LttvAttributeValue value
;
3949 new_m_window
= g_new(MainWindow
, 1);
3951 // Add the object's information to the module's array
3952 g_main_window_list
= g_slist_append(g_main_window_list
, new_m_window
);
3954 new_window
= create_MWindow();
3955 gtk_widget_show (new_window
);
3957 new_m_window
->mwindow
= new_window
;
3958 new_m_window
->attributes
= attributes
;
3960 g_assert(lttv_iattribute_find_by_path(attributes
,
3961 "viewers/menu", LTTV_POINTER
, &value
));
3962 *(value
.v_pointer
) = lttv_menus_new();
3964 g_assert(lttv_iattribute_find_by_path(attributes
,
3965 "viewers/toolbar", LTTV_POINTER
, &value
));
3966 *(value
.v_pointer
) = lttv_toolbars_new();
3968 add_all_menu_toolbar_constructors(new_m_window
, NULL
);
3970 g_object_set_data_full(G_OBJECT(new_window
),
3972 (gpointer
)new_m_window
,
3973 (GDestroyNotify
)g_free
);
3974 //create a default tab
3975 notebook
= (GtkNotebook
*)lookup_widget(new_m_window
->mwindow
, "MNotebook");
3976 if(notebook
== NULL
){
3977 g_info("Notebook does not exist\n");
3980 //gtk_notebook_popup_enable (GTK_NOTEBOOK(notebook));
3981 //for now there is no name field in LttvTraceset structure
3982 //Use "Traceset" as the label for the default tab
3984 GtkWidget
* parent_notebook
= lookup_widget(parent
->mwindow
, "MNotebook");
3985 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(parent_notebook
),
3986 gtk_notebook_get_current_page(GTK_NOTEBOOK(parent_notebook
)));
3992 parent_tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
3994 new_tab
= create_tab(new_m_window
, parent_tab
, notebook
, "Traceset");
3996 new_tab
= create_tab(new_m_window
, NULL
, notebook
, "Traceset");
3997 /* First window, use command line trace */
3998 if(g_init_trace
!= NULL
){
3999 lttvwindow_add_trace(new_tab
,
4003 LttvTraceset
*traceset
= new_tab
->traceset_info
->traceset
;
4004 SetTraceset(new_tab
, traceset
);
4006 /* Insert default viewers */
4008 LttvAttributeType type
;
4009 LttvAttributeName name
;
4010 LttvAttributeValue value
;
4011 LttvAttribute
*attribute
;
4013 LttvIAttribute
*attributes_global
=
4014 LTTV_IATTRIBUTE(lttv_global_attributes());
4016 g_assert(attribute
=
4017 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
4018 LTTV_IATTRIBUTE(attributes_global
),
4019 LTTV_VIEWER_CONSTRUCTORS
)));
4021 name
= g_quark_from_string("guievents");
4022 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
4024 if(type
== LTTV_POINTER
) {
4025 lttvwindow_viewer_constructor viewer_constructor
=
4026 (lttvwindow_viewer_constructor
)*value
.v_pointer
;
4027 insert_viewer(new_window
, viewer_constructor
);
4030 name
= g_quark_from_string("guicontrolflow");
4031 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
4033 if(type
== LTTV_POINTER
) {
4034 lttvwindow_viewer_constructor viewer_constructor
=
4035 (lttvwindow_viewer_constructor
)*value
.v_pointer
;
4036 insert_viewer(new_window
, viewer_constructor
);
4039 name
= g_quark_from_string("guistatistics");
4040 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
4042 if(type
== LTTV_POINTER
) {
4043 lttvwindow_viewer_constructor viewer_constructor
=
4044 (lttvwindow_viewer_constructor
)*value
.v_pointer
;
4045 insert_viewer(new_window
, viewer_constructor
);
4051 g_info("There are now : %d windows\n",g_slist_length(g_main_window_list
));
4055 /* Free the memory occupied by a tab structure
4059 void tab_destructor(Tab
* tab
)
4061 int i
, nb
, ref_count
;
4064 gtk_object_destroy(GTK_OBJECT(tab
->tooltips
));
4067 g_object_unref(tab
->attributes
);
4069 if(tab
->interrupted_state
)
4070 g_object_unref(tab
->interrupted_state
);
4073 if(tab
->traceset_info
->traceset_context
!= NULL
){
4074 //remove state update hooks
4075 lttv_state_remove_event_hooks(
4076 (LttvTracesetState
*)tab
->traceset_info
->
4078 lttv_context_fini(LTTV_TRACESET_CONTEXT(tab
->traceset_info
->
4080 g_object_unref(tab
->traceset_info
->traceset_context
);
4082 if(tab
->traceset_info
->traceset
!= NULL
) {
4083 nb
= lttv_traceset_number(tab
->traceset_info
->traceset
);
4084 for(i
= 0 ; i
< nb
; i
++) {
4085 trace
= lttv_traceset_get(tab
->traceset_info
->traceset
, i
);
4086 ref_count
= lttv_trace_get_ref_number(trace
);
4088 ltt_trace_close(lttv_trace(trace
));
4092 lttv_filter_destroy(tab
->filter
);
4093 lttv_traceset_destroy(tab
->traceset_info
->traceset
);
4094 /* Remove the idle events requests processing function of the tab */
4095 g_idle_remove_by_data(tab
);
4097 g_slist_free(tab
->events_requests
);
4098 g_free(tab
->traceset_info
);
4103 /* Create a tab and insert it into the current main window
4106 Tab
* create_tab(MainWindow
* mw
, Tab
*copy_tab
,
4107 GtkNotebook
* notebook
, char * label
)
4112 //create a new tab data structure
4115 //construct and initialize the traceset_info
4116 tab
->traceset_info
= g_new(TracesetInfo
,1);
4119 tab
->traceset_info
->traceset
=
4120 lttv_traceset_copy(copy_tab
->traceset_info
->traceset
);
4122 /* Copy the previous tab's filter */
4123 /* We can clone the filter, as we copy the trace set also */
4124 /* The filter must always be in sync with the trace set */
4125 tab
->filter
= lttv_filter_clone(copy_tab
->filter
);
4128 tab
->traceset_info
->traceset
= lttv_traceset_new();
4133 lttv_attribute_write_xml(
4134 lttv_traceset_attribute(tab
->traceset_info
->traceset
),
4140 tab
->time_manager_lock
= FALSE
;
4141 tab
->current_time_manager_lock
= FALSE
;
4143 //FIXME copy not implemented in lower level
4144 tab
->traceset_info
->traceset_context
=
4145 g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
4146 g_assert(tab
->traceset_info
->traceset_context
!= NULL
);
4148 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
),
4149 tab
->traceset_info
->traceset
);
4150 //add state update hooks
4151 lttv_state_add_event_hooks(
4152 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
4154 //determine the current_time and time_window of the tab
4156 if(copy_tab
!= NULL
){
4157 tab
->time_window
= copy_tab
->time_window
;
4158 tab
->current_time
= copy_tab
->current_time
;
4160 tab
->time_window
.start_time
=
4161 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
4162 time_span
.start_time
;
4163 if(DEFAULT_TIME_WIDTH_S
<
4164 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
4165 time_span
.end_time
.tv_sec
)
4166 tmp_time
.tv_sec
= DEFAULT_TIME_WIDTH_S
;
4169 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
4170 time_span
.end_time
.tv_sec
;
4171 tmp_time
.tv_nsec
= 0;
4172 tab
->time_window
.time_width
= tmp_time
;
4173 tab
->current_time
.tv_sec
=
4174 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
4175 time_span
.start_time
.tv_sec
;
4176 tab
->current_time
.tv_nsec
=
4177 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
4178 time_span
.start_time
.tv_nsec
;
4181 tab
->attributes
= LTTV_IATTRIBUTE(g_object_new(LTTV_ATTRIBUTE_TYPE
, NULL
));
4182 tab
->interrupted_state
= g_object_new(LTTV_ATTRIBUTE_TYPE
, NULL
);
4184 tab
->vbox
= gtk_vbox_new(FALSE
, 2);
4185 tab
->viewer_container
= gtk_vbox_new(TRUE
, 2);
4186 tab
->scrollbar
= gtk_hscrollbar_new(NULL
);
4187 //tab->multivpaned = gtk_multi_vpaned_new();
4189 gtk_box_pack_start(GTK_BOX(tab
->vbox
),
4190 tab
->viewer_container
,
4192 TRUE
, /* Give the extra space to the child */
4193 0); /* No padding */
4195 /* Create the timebar */
4197 tab
->MTimebar
= gtk_hbox_new(FALSE
, 2);
4198 gtk_widget_show(tab
->MTimebar
);
4199 tab
->tooltips
= gtk_tooltips_new();
4201 tab
->MEventBox1a
= gtk_event_box_new();
4202 gtk_widget_show(tab
->MEventBox1a
);
4203 gtk_tooltips_set_tip(tab
->tooltips
, tab
->MEventBox1a
,
4204 "Paste Start and End Times Here", "");
4205 tab
->MText1a
= gtk_label_new("Time Frame ");
4206 gtk_widget_show(tab
->MText1a
);
4207 gtk_container_add(GTK_CONTAINER(tab
->MEventBox1a
), tab
->MText1a
);
4208 tab
->MEventBox1b
= gtk_event_box_new();
4209 gtk_widget_show(tab
->MEventBox1b
);
4210 gtk_tooltips_set_tip(tab
->tooltips
, tab
->MEventBox1b
,
4211 "Paste Start Time Here", "");
4212 tab
->MText1b
= gtk_label_new("start: ");
4213 gtk_widget_show(tab
->MText1b
);
4214 gtk_container_add(GTK_CONTAINER(tab
->MEventBox1b
), tab
->MText1b
);
4215 tab
->MText2
= gtk_label_new("s");
4216 gtk_widget_show(tab
->MText2
);
4217 tab
->MText3a
= gtk_label_new("ns");
4218 gtk_widget_show(tab
->MText3a
);
4219 tab
->MEventBox3b
= gtk_event_box_new();
4220 gtk_widget_show(tab
->MEventBox3b
);
4221 gtk_tooltips_set_tip(tab
->tooltips
, tab
->MEventBox3b
,
4222 "Paste End Time Here", "");
4223 tab
->MText3b
= gtk_label_new("end:");
4224 gtk_widget_show(tab
->MText3b
);
4225 gtk_container_add(GTK_CONTAINER(tab
->MEventBox3b
), tab
->MText3b
);
4226 tab
->MText4
= gtk_label_new("s");
4227 gtk_widget_show(tab
->MText4
);
4228 tab
->MText5a
= gtk_label_new("ns");
4229 gtk_widget_show(tab
->MText5a
);
4230 tab
->MEventBox5b
= gtk_event_box_new();
4231 gtk_widget_show(tab
->MEventBox5b
);
4232 gtk_tooltips_set_tip(tab
->tooltips
, tab
->MEventBox5b
,
4233 "Paste Current Time Here", "");
4234 tab
->MText5b
= gtk_label_new("Current Time:");
4235 gtk_widget_show(tab
->MText5b
);
4236 gtk_container_add(GTK_CONTAINER(tab
->MEventBox5b
), tab
->MText5b
);
4237 tab
->MText6
= gtk_label_new("s");
4238 gtk_widget_show(tab
->MText6
);
4239 tab
->MText7
= gtk_label_new("ns");
4240 gtk_widget_show(tab
->MText7
);
4242 tab
->MEntry1
= gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4243 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab
->MEntry1
),0);
4244 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab
->MEntry1
),TRUE
);
4245 gtk_widget_show(tab
->MEntry1
);
4246 tab
->MEntry2
= gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4247 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab
->MEntry2
),0);
4248 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab
->MEntry2
),TRUE
);
4249 gtk_widget_show(tab
->MEntry2
);
4250 tab
->MEntry3
= gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4251 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab
->MEntry3
),0);
4252 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab
->MEntry3
),TRUE
);
4253 gtk_widget_show(tab
->MEntry3
);
4254 tab
->MEntry4
= gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4255 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab
->MEntry4
),0);
4256 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab
->MEntry4
),TRUE
);
4257 gtk_widget_show(tab
->MEntry4
);
4258 tab
->MEntry5
= gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4259 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab
->MEntry5
),0);
4260 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab
->MEntry5
),TRUE
);
4261 gtk_widget_show(tab
->MEntry5
);
4262 tab
->MEntry6
= gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4263 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab
->MEntry6
),0);
4264 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab
->MEntry6
),TRUE
);
4265 gtk_widget_show(tab
->MEntry6
);
4268 GtkWidget
*temp_widget
;
4270 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEventBox1a
, FALSE
,
4272 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEventBox1b
, FALSE
,
4274 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEntry1
, FALSE
, FALSE
, 0);
4275 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MText2
, FALSE
, FALSE
, 0);
4276 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEntry2
, FALSE
, FALSE
, 0);
4277 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MText3a
, FALSE
, FALSE
, 0);
4278 temp_widget
= gtk_vseparator_new();
4279 gtk_widget_show(temp_widget
);
4280 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), temp_widget
, FALSE
, FALSE
, 0);
4281 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEventBox3b
, FALSE
,
4283 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEntry3
, FALSE
, FALSE
, 0);
4284 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MText4
, FALSE
, FALSE
, 0);
4285 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEntry4
, FALSE
, FALSE
, 0);
4286 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MText5a
, FALSE
, FALSE
, 0);
4287 temp_widget
= gtk_vseparator_new();
4288 gtk_widget_show(temp_widget
);
4289 gtk_box_pack_end (GTK_BOX (tab
->MTimebar
), tab
->MText7
, FALSE
, FALSE
, 0);
4290 gtk_box_pack_end (GTK_BOX (tab
->MTimebar
), tab
->MEntry6
, FALSE
, FALSE
, 0);
4291 gtk_box_pack_end (GTK_BOX (tab
->MTimebar
), tab
->MText6
, FALSE
, FALSE
, 0);
4292 gtk_box_pack_end (GTK_BOX (tab
->MTimebar
), tab
->MEntry5
, FALSE
, FALSE
, 0);
4293 gtk_box_pack_end (GTK_BOX (tab
->MTimebar
), tab
->MEventBox5b
, FALSE
,
4295 gtk_box_pack_end (GTK_BOX (tab
->MTimebar
), temp_widget
, FALSE
, FALSE
, 0);
4298 //GtkWidget *test = gtk_button_new_with_label("drop");
4299 //gtk_button_set_relief(GTK_BUTTON(test), GTK_RELIEF_NONE);
4300 //gtk_widget_show(test);
4301 //gtk_box_pack_end(GTK_BOX (tab->MTimebar), test, FALSE, FALSE, 0);
4302 //gtk_widget_add_events(tab->MText1, GDK_ALL_EVENTS_MASK);//GDK_BUTTON_PRESS_MASK);
4303 /*GtkWidget *event_box = gtk_event_box_new();
4304 gtk_widget_show(event_box);
4305 gtk_tooltips_set_tip(tooltips, event_box,
4306 "Paste Current Time Here", "");
4307 gtk_box_pack_end(GTK_BOX (tab->MTimebar), event_box, FALSE, FALSE, 0);
4308 GtkWidget *test = gtk_label_new("drop");
4309 gtk_container_add(GTK_CONTAINER(event_box), test);
4310 gtk_widget_show(test);
4311 g_signal_connect (G_OBJECT(event_box),
4312 "button-press-event",
4313 G_CALLBACK (on_MText1_paste),
4317 g_signal_connect (G_OBJECT(tab
->MEventBox1a
),
4318 "button-press-event",
4319 G_CALLBACK (on_MEventBox1a_paste
),
4322 g_signal_connect (G_OBJECT(tab
->MEventBox1b
),
4323 "button-press-event",
4324 G_CALLBACK (on_MEventBox1b_paste
),
4326 g_signal_connect (G_OBJECT(tab
->MEventBox3b
),
4327 "button-press-event",
4328 G_CALLBACK (on_MEventBox3b_paste
),
4330 g_signal_connect (G_OBJECT(tab
->MEventBox5b
),
4331 "button-press-event",
4332 G_CALLBACK (on_MEventBox5b_paste
),
4336 gtk_box_pack_end(GTK_BOX(tab
->vbox
),
4338 FALSE
, /* Do not expand */
4339 FALSE
, /* Fill has no effect here (expand false) */
4340 0); /* No padding */
4342 gtk_box_pack_end(GTK_BOX(tab
->vbox
),
4344 FALSE
, /* Do not expand */
4345 FALSE
, /* Fill has no effect here (expand false) */
4346 0); /* No padding */
4348 g_object_set_data(G_OBJECT(tab
->viewer_container
), "focused_viewer", NULL
);
4354 // Display a label with a X
4355 GtkWidget *w_hbox = gtk_hbox_new(FALSE, 4);
4356 GtkWidget *w_label = gtk_label_new (label);
4357 GtkWidget *pixmap = create_pixmap(GTK_WIDGET(notebook), "close.png");
4358 GtkWidget *w_button = gtk_button_new ();
4359 gtk_container_add(GTK_CONTAINER(w_button), pixmap);
4360 //GtkWidget *w_button = gtk_button_new_with_label("x");
4362 gtk_button_set_relief(GTK_BUTTON(w_button), GTK_RELIEF_NONE);
4364 gtk_box_pack_start(GTK_BOX(w_hbox), w_label, TRUE, TRUE, 0);
4365 gtk_box_pack_end(GTK_BOX(w_hbox), w_button, FALSE,
4368 g_signal_connect_swapped (w_button, "clicked",
4369 G_CALLBACK (on_close_tab_X_clicked),
4372 gtk_widget_set_state(w_button, GTK_STATE_ACTIVE);
4374 gtk_widget_show (w_label);
4375 gtk_widget_show (pixmap);
4376 gtk_widget_show (w_button);
4377 gtk_widget_show (w_hbox);
4379 tab->label = w_hbox;
4383 tab
->label
= gtk_label_new (label
);
4385 gtk_widget_show(tab
->label
);
4386 gtk_widget_show(tab
->scrollbar
);
4387 gtk_widget_show(tab
->viewer_container
);
4388 gtk_widget_show(tab
->vbox
);
4389 //gtk_widget_show(tab->multivpaned);
4392 /* Start with empty events requests list */
4393 tab
->events_requests
= NULL
;
4394 tab
->events_request_pending
= FALSE
;
4396 g_object_set_data_full(
4397 G_OBJECT(tab
->vbox
),
4400 (GDestroyNotify
)tab_destructor
);
4402 g_signal_connect(G_OBJECT(tab
->scrollbar
), "value-changed",
4403 G_CALLBACK(scroll_value_changed_cb
), tab
);
4405 g_signal_connect ((gpointer
) tab
->MEntry1
, "value-changed",
4406 G_CALLBACK (on_MEntry1_value_changed
),
4408 g_signal_connect ((gpointer
) tab
->MEntry2
, "value-changed",
4409 G_CALLBACK (on_MEntry2_value_changed
),
4411 g_signal_connect ((gpointer
) tab
->MEntry3
, "value-changed",
4412 G_CALLBACK (on_MEntry3_value_changed
),
4414 g_signal_connect ((gpointer
) tab
->MEntry4
, "value-changed",
4415 G_CALLBACK (on_MEntry4_value_changed
),
4417 g_signal_connect ((gpointer
) tab
->MEntry5
, "value-changed",
4418 G_CALLBACK (on_MEntry5_value_changed
),
4420 g_signal_connect ((gpointer
) tab
->MEntry6
, "value-changed",
4421 G_CALLBACK (on_MEntry6_value_changed
),
4424 //g_signal_connect(G_OBJECT(tab->scrollbar), "changed",
4425 // G_CALLBACK(scroll_value_changed_cb), tab);
4428 //insert tab into notebook
4429 gtk_notebook_append_page(notebook
,
4432 list
= gtk_container_get_children(GTK_CONTAINER(notebook
));
4433 gtk_notebook_set_current_page(notebook
,g_list_length(list
)-1);
4434 // always show : not if(g_list_length(list)>1)
4435 gtk_notebook_set_show_tabs(notebook
, TRUE
);
4441 * execute_events_requests
4443 * Idle function that executes the pending requests for a tab.
4445 * @return return value : TRUE : keep the idle function, FALSE : remove it.
4447 gboolean
execute_events_requests(Tab
*tab
)
4449 return ( lttvwindow_process_pending_requests(tab
) );