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 Tab
*create_new_tab(GtkWidget
* widget
, gpointer user_data
);
78 static gboolean
lttvwindow_process_pending_requests(Tab
*tab
);
92 /* Pasting routines */
94 static void MEventBox1a_receive(GtkClipboard
*clipboard
,
98 if(text
== NULL
) return;
99 Tab
*tab
= (Tab
*)data
;
100 gchar buffer
[CLIP_BUF
];
101 gchar
*ptr
= buffer
, *ptr_ssec
, *ptr_snsec
, *ptr_esec
, *ptr_ensec
;
103 strncpy(buffer
, text
, CLIP_BUF
);
106 while(!isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
107 /* remove leading junk */
109 while(isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
110 /* read all the first number */
114 while(!isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
115 /* remove leading junk */
117 while(isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
118 /* read all the first number */
122 while(!isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
123 /* remove leading junk */
125 while(isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
126 /* read all the first number */
130 while(!isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
131 /* remove leading junk */
133 while(isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
134 /* read all the first number */
137 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry1
),
138 (double)strtoul(ptr_ssec
, NULL
, 10));
139 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry2
),
140 (double)strtoul(ptr_snsec
, NULL
, 10));
141 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry3
),
142 (double)strtoul(ptr_esec
, NULL
, 10));
143 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry4
),
144 (double)strtoul(ptr_ensec
, NULL
, 10));
147 static gboolean
on_MEventBox1a_paste(GtkWidget
*widget
, GdkEventButton
*event
,
150 Tab
*tab
= (Tab
*)data
;
152 GtkClipboard
*clip
= gtk_clipboard_get_for_display(gdk_display_get_default(),
153 GDK_SELECTION_PRIMARY
);
154 gtk_clipboard_request_text(clip
,
155 (GtkClipboardTextReceivedFunc
)MEventBox1a_receive
,
162 static void MEventBox1b_receive(GtkClipboard
*clipboard
,
166 if(text
== NULL
) return;
167 Tab
*tab
= (Tab
*)data
;
168 gchar buffer
[CLIP_BUF
];
169 gchar
*ptr
= buffer
, *ptr_sec
, *ptr_nsec
;
171 strncpy(buffer
, text
, CLIP_BUF
);
173 while(!isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
174 /* remove leading junk */
176 while(isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
177 /* read all the first number */
181 while(!isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
182 /* remove leading junk */
184 while(isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
185 /* read all the first number */
188 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry1
),
189 (double)strtoul(ptr_sec
, NULL
, 10));
190 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry2
),
191 (double)strtoul(ptr_nsec
, NULL
, 10));
195 static gboolean
on_MEventBox1b_paste(GtkWidget
*widget
, GdkEventButton
*event
,
198 Tab
*tab
= (Tab
*)data
;
200 GtkClipboard
*clip
= gtk_clipboard_get_for_display(gdk_display_get_default(),
201 GDK_SELECTION_PRIMARY
);
202 gtk_clipboard_request_text(clip
,
203 (GtkClipboardTextReceivedFunc
)MEventBox1b_receive
,
209 static void MEventBox3b_receive(GtkClipboard
*clipboard
,
213 if(text
== NULL
) return;
214 Tab
*tab
= (Tab
*)data
;
215 gchar buffer
[CLIP_BUF
];
216 gchar
*ptr
= buffer
, *ptr_sec
, *ptr_nsec
;
218 strncpy(buffer
, text
, CLIP_BUF
);
220 while(!isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
221 /* remove leading junk */
223 while(isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
224 /* read all the first number */
228 while(!isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
229 /* remove leading junk */
231 while(isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
232 /* read all the first number */
235 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry3
),
236 (double)strtoul(ptr_sec
, NULL
, 10));
237 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry4
),
238 (double)strtoul(ptr_nsec
, NULL
, 10));
242 static gboolean
on_MEventBox3b_paste(GtkWidget
*widget
, GdkEventButton
*event
,
245 Tab
*tab
= (Tab
*)data
;
247 GtkClipboard
*clip
= gtk_clipboard_get_for_display(gdk_display_get_default(),
248 GDK_SELECTION_PRIMARY
);
249 gtk_clipboard_request_text(clip
,
250 (GtkClipboardTextReceivedFunc
)MEventBox3b_receive
,
256 static void MEventBox5b_receive(GtkClipboard
*clipboard
,
260 if(text
== NULL
) return;
261 Tab
*tab
= (Tab
*)data
;
262 gchar buffer
[CLIP_BUF
];
263 gchar
*ptr
= buffer
, *ptr_sec
, *ptr_nsec
;
265 strncpy(buffer
, text
, CLIP_BUF
);
267 while(!isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
268 /* remove leading junk */
270 while(isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
271 /* read all the first number */
275 while(!isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
276 /* remove leading junk */
278 while(isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
279 /* read all the first number */
282 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry5
),
283 (double)strtoul(ptr_sec
, NULL
, 10));
284 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry6
),
285 (double)strtoul(ptr_nsec
, NULL
, 10));
289 static gboolean
on_MEventBox5b_paste(GtkWidget
*widget
, GdkEventButton
*event
,
292 Tab
*tab
= (Tab
*)data
;
294 GtkClipboard
*clip
= gtk_clipboard_get_for_display(gdk_display_get_default(),
295 GDK_SELECTION_PRIMARY
);
296 gtk_clipboard_request_text(clip
,
297 (GtkClipboardTextReceivedFunc
)MEventBox5b_receive
,
303 static gboolean
viewer_grab_focus(GtkWidget
*widget
, GdkEventButton
*event
,
306 GtkWidget
*viewer
= GTK_WIDGET(data
);
307 GtkWidget
*viewer_container
= gtk_widget_get_parent(viewer
);
309 g_debug("FOCUS GRABBED");
310 g_object_set_data(G_OBJECT(viewer_container
), "focused_viewer", viewer
);
315 static void connect_focus_recursive(GtkWidget
*widget
,
318 if(GTK_IS_CONTAINER(widget
)) {
319 gtk_container_forall(GTK_CONTAINER(widget
),
320 (GtkCallback
)connect_focus_recursive
,
324 if(GTK_IS_TREE_VIEW(widget
)) {
325 gtk_tree_view_set_headers_clickable(GTK_TREE_VIEW(widget
), TRUE
);
327 gtk_widget_add_events(widget
, GDK_BUTTON_PRESS_MASK
);
328 g_signal_connect (G_OBJECT(widget
),
329 "button-press-event",
330 G_CALLBACK (viewer_grab_focus
),
334 /* insert_viewer function constructs an instance of a viewer first,
335 * then inserts the widget of the instance into the container of the
340 insert_viewer_wrap(GtkWidget
*menuitem
, gpointer user_data
)
342 insert_viewer((GtkWidget
*)menuitem
, (lttvwindow_viewer_constructor
)user_data
);
346 /* internal functions */
347 void insert_viewer(GtkWidget
* widget
, lttvwindow_viewer_constructor constructor
)
349 GtkWidget
* viewer_container
;
350 MainWindow
* mw_data
= get_window_data_struct(widget
);
351 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
353 TimeInterval
* time_interval
;
354 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
355 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
359 tab
= create_new_tab(widget
, NULL
);
361 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
364 viewer_container
= tab
->viewer_container
;
366 viewer
= (GtkWidget
*)constructor(tab
);
369 //gtk_multivpaned_widget_add(GTK_MULTIVPANED(multivpaned), viewer);
371 gtk_box_pack_end(GTK_BOX(viewer_container
),
377 /* We want to connect the viewer_grab_focus to EVERY
378 * child of this widget. The little trick is to get each child
379 * of each GTK_CONTAINER, even subchildren.
381 connect_focus_recursive(viewer
, viewer
);
386 * Function to set/update traceset for the viewers
387 * @param tab viewer's tab
388 * @param traceset traceset of the main window.
390 * 0 : traceset updated
391 * 1 : no traceset hooks to update; not an error.
394 int SetTraceset(Tab
* tab
, LttvTraceset
*traceset
)
396 LttvTracesetContext
*tsc
=
397 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
398 TimeInterval time_span
= tsc
->time_span
;
399 TimeWindow new_time_window
;
400 LttTime new_current_time
;
402 /* Set the tab's time window and current time if
404 if(ltt_time_compare(tab
->time_window
.start_time
, time_span
.start_time
) < 0
405 || ltt_time_compare(tab
->time_window
.end_time
,
406 time_span
.end_time
) > 0) {
407 new_time_window
.start_time
= time_span
.start_time
;
409 new_current_time
= time_span
.start_time
;
413 if(DEFAULT_TIME_WIDTH_S
< time_span
.end_time
.tv_sec
)
414 tmp_time
.tv_sec
= DEFAULT_TIME_WIDTH_S
;
416 tmp_time
.tv_sec
= time_span
.end_time
.tv_sec
;
417 tmp_time
.tv_nsec
= 0;
418 new_time_window
.time_width
= tmp_time
;
419 new_time_window
.time_width_double
= ltt_time_to_double(tmp_time
);
420 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
421 new_time_window
.time_width
) ;
423 time_change_manager(tab
, new_time_window
);
424 current_time_change_manager(tab
, new_current_time
);
426 //FIXME : we delete the filter tree, when it should be updated.
427 lttv_filter_destroy(tab
->filter
);
432 GtkAdjustment
*adjustment
= gtk_range_get_adjustment(GTK_RANGE(tab
->scrollbar
));
433 LttTime upper
= ltt_time_sub(time_span
.end_time
, time_span
.start_time
);
435 g_object_set(G_OBJECT(adjustment
),
439 ltt_time_to_double(upper
)
440 * NANOSECONDS_PER_SECOND
, /* upper */
442 ltt_time_to_double(tab
->time_window
.time_width
)
443 / SCROLL_STEP_PER_PAGE
444 * NANOSECONDS_PER_SECOND
, /* step increment */
446 ltt_time_to_double(tab
->time_window
.time_width
)
447 * NANOSECONDS_PER_SECOND
, /* page increment */
449 ltt_time_to_double(tab
->time_window
.time_width
)
450 * NANOSECONDS_PER_SECOND
, /* page size */
452 gtk_adjustment_changed(adjustment
);
454 g_object_set(G_OBJECT(adjustment
),
457 ltt_time_sub(tab
->time_window
.start_time
, time_span
.start_time
))
458 * NANOSECONDS_PER_SECOND
, /* value */
460 gtk_adjustment_value_changed(adjustment
);
462 /* set the time bar. The value callbacks will change their nsec themself */
464 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry1
),
465 (double)time_span
.start_time
.tv_sec
,
466 (double)time_span
.end_time
.tv_sec
);
469 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry3
),
470 (double)time_span
.start_time
.tv_sec
,
471 (double)time_span
.end_time
.tv_sec
);
473 /* current seconds */
474 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry5
),
475 (double)time_span
.start_time
.tv_sec
,
476 (double)time_span
.end_time
.tv_sec
);
479 /* Finally, call the update hooks of the viewers */
481 LttvAttributeValue value
;
485 g_assert( lttv_iattribute_find_by_path(tab
->attributes
,
486 "hooks/updatetraceset", LTTV_POINTER
, &value
));
488 tmp
= (LttvHooks
*)*(value
.v_pointer
);
489 if(tmp
== NULL
) retval
= 1;
490 else lttv_hooks_call(tmp
,traceset
);
497 * Function to set/update filter for the viewers
498 * @param tab viewer's tab
499 * @param filter filter of the main window.
502 * 0 : filters updated
503 * 1 : no filter hooks to update; not an error.
506 int SetFilter(Tab
* tab
, gpointer filter
)
509 LttvAttributeValue value
;
511 g_assert(lttv_iattribute_find_by_path(tab
->attributes
,
512 "hooks/updatefilter", LTTV_POINTER
, &value
));
514 tmp
= (LttvHooks
*)*(value
.v_pointer
);
516 if(tmp
== NULL
) return 1;
517 lttv_hooks_call(tmp
,filter
);
525 * Function to redraw each viewer belonging to the current tab
526 * @param tab viewer's tab
529 void update_traceset(Tab
*tab
)
531 LttvAttributeValue value
;
533 g_assert(lttv_iattribute_find_by_path(tab
->attributes
,
534 "hooks/updatetraceset", LTTV_POINTER
, &value
));
535 tmp
= (LttvHooks
*)*(value
.v_pointer
);
536 if(tmp
== NULL
) return;
537 lttv_hooks_call(tmp
, NULL
);
541 /* get_label function is used to get user input, it displays an input
542 * box, which allows user to input a string
545 void get_label_string (GtkWidget
* text
, gchar
* label
)
547 GtkEntry
* entry
= (GtkEntry
*)text
;
548 if(strlen(gtk_entry_get_text(entry
))!=0)
549 strcpy(label
,gtk_entry_get_text(entry
));
552 gboolean
get_label(MainWindow
* mw
, gchar
* str
, gchar
* dialogue_title
, gchar
* label_str
)
554 GtkWidget
* dialogue
;
559 dialogue
= gtk_dialog_new_with_buttons(dialogue_title
,NULL
,
561 GTK_STOCK_OK
,GTK_RESPONSE_ACCEPT
,
562 GTK_STOCK_CANCEL
,GTK_RESPONSE_REJECT
,
565 label
= gtk_label_new(label_str
);
566 gtk_widget_show(label
);
568 text
= gtk_entry_new();
569 gtk_widget_show(text
);
571 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialogue
)->vbox
), label
,TRUE
, TRUE
,0);
572 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialogue
)->vbox
), text
,FALSE
, FALSE
,0);
574 id
= gtk_dialog_run(GTK_DIALOG(dialogue
));
576 case GTK_RESPONSE_ACCEPT
:
577 get_label_string(text
,str
);
578 gtk_widget_destroy(dialogue
);
580 case GTK_RESPONSE_REJECT
:
582 gtk_widget_destroy(dialogue
);
589 /* get_window_data_struct function is actually a lookup function,
590 * given a widget which is in the tree of the main window, it will
591 * return the MainWindow data structure associated with main window
594 MainWindow
* get_window_data_struct(GtkWidget
* widget
)
597 MainWindow
* mw_data
;
599 mw
= lookup_widget(widget
, "MWindow");
601 g_info("Main window does not exist\n");
605 mw_data
= (MainWindow
*) g_object_get_data(G_OBJECT(mw
),"main_window_data");
607 g_warning("Main window data does not exist\n");
614 /* create_new_window function, just constructs a new main window
617 void create_new_window(GtkWidget
* widget
, gpointer user_data
, gboolean clone
)
619 MainWindow
* parent
= get_window_data_struct(widget
);
622 g_info("Clone : use the same traceset\n");
623 construct_main_window(parent
);
625 g_info("Empty : traceset is set to NULL\n");
626 construct_main_window(NULL
);
630 /* Get the currently focused viewer.
631 * If no viewer is focused, use the first one.
633 * If no viewer available, return NULL.
635 GtkWidget
*viewer_container_focus(GtkWidget
*container
)
639 widget
= (GtkWidget
*)g_object_get_data(G_OBJECT(container
),
643 g_debug("no widget focused");
644 GList
*children
= gtk_container_get_children(GTK_CONTAINER(container
));
647 widget
= GTK_WIDGET(children
->data
);
648 g_object_set_data(G_OBJECT(container
),
658 gint
viewer_container_position(GtkWidget
*container
, GtkWidget
*child
)
661 if(child
== NULL
) return -1;
665 memset(&value
, 0, sizeof(GValue
));
666 g_value_init(&value
, G_TYPE_INT
);
667 gtk_container_child_get_property(GTK_CONTAINER(container
),
671 pos
= g_value_get_int(&value
);
677 /* move_*_viewer functions move the selected view up/down in
681 void move_down_viewer(GtkWidget
* widget
, gpointer user_data
)
683 MainWindow
* mw
= get_window_data_struct(widget
);
684 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
686 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
687 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
693 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
696 //gtk_multivpaned_widget_move_up(GTK_MULTIVPANED(tab->multivpaned));
698 /* change the position in the vbox */
699 GtkWidget
*focus_widget
;
701 focus_widget
= viewer_container_focus(tab
->viewer_container
);
702 position
= viewer_container_position(tab
->viewer_container
, focus_widget
);
705 /* can move up one position */
706 gtk_box_reorder_child(GTK_BOX(tab
->viewer_container
),
713 void move_up_viewer(GtkWidget
* widget
, gpointer user_data
)
715 MainWindow
* mw
= get_window_data_struct(widget
);
716 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
718 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
719 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
725 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
728 //gtk_multivpaned_widget_move_down(GTK_MULTIVPANED(tab->multivpaned));
729 /* change the position in the vbox */
730 GtkWidget
*focus_widget
;
732 focus_widget
= viewer_container_focus(tab
->viewer_container
);
733 position
= viewer_container_position(tab
->viewer_container
, focus_widget
);
737 g_list_length(gtk_container_get_children(
738 GTK_CONTAINER(tab
->viewer_container
)))-1
740 /* can move down one position */
741 gtk_box_reorder_child(GTK_BOX(tab
->viewer_container
),
749 /* delete_viewer deletes the selected viewer in the current tab
752 void delete_viewer(GtkWidget
* widget
, gpointer user_data
)
754 MainWindow
* mw
= get_window_data_struct(widget
);
755 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
757 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
758 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
764 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
767 //gtk_multivpaned_widget_delete(GTK_MULTIVPANED(tab->multivpaned));
769 GtkWidget
*focus_widget
= viewer_container_focus(tab
->viewer_container
);
771 if(focus_widget
!= NULL
)
772 gtk_widget_destroy(focus_widget
);
774 g_object_set_data(G_OBJECT(tab
->viewer_container
), "focused_viewer", NULL
);
778 /* open_traceset will open a traceset saved in a file
779 * Right now, it is not finished yet, (not working)
783 void open_traceset(GtkWidget
* widget
, gpointer user_data
)
787 LttvTraceset
* traceset
;
788 MainWindow
* mw_data
= get_window_data_struct(widget
);
789 GtkFileSelection
* file_selector
=
790 (GtkFileSelection
*)gtk_file_selection_new("Select a traceset");
792 gtk_file_selection_hide_fileop_buttons(file_selector
);
794 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
796 case GTK_RESPONSE_ACCEPT
:
797 case GTK_RESPONSE_OK
:
798 dir
= gtk_file_selection_get_selections (file_selector
);
799 traceset
= lttv_traceset_load(dir
[0]);
800 g_info("Open a trace set %s\n", dir
[0]);
803 case GTK_RESPONSE_REJECT
:
804 case GTK_RESPONSE_CANCEL
:
806 gtk_widget_destroy((GtkWidget
*)file_selector
);
812 static void events_request_free(EventsRequest
*events_request
)
814 if(events_request
== NULL
) return;
816 if(events_request
->start_position
!= NULL
)
817 lttv_traceset_context_position_destroy(events_request
->start_position
);
818 if(events_request
->end_position
!= NULL
)
819 lttv_traceset_context_position_destroy(events_request
->end_position
);
820 if(events_request
->hooks
!= NULL
)
821 g_array_free(events_request
->hooks
, TRUE
);
822 if(events_request
->before_chunk_traceset
!= NULL
)
823 lttv_hooks_destroy(events_request
->before_chunk_traceset
);
824 if(events_request
->before_chunk_trace
!= NULL
)
825 lttv_hooks_destroy(events_request
->before_chunk_trace
);
826 if(events_request
->before_chunk_tracefile
!= NULL
)
827 lttv_hooks_destroy(events_request
->before_chunk_tracefile
);
828 if(events_request
->event
!= NULL
)
829 lttv_hooks_destroy(events_request
->event
);
830 if(events_request
->event_by_id
!= NULL
)
831 lttv_hooks_by_id_destroy(events_request
->event_by_id
);
832 if(events_request
->after_chunk_tracefile
!= NULL
)
833 lttv_hooks_destroy(events_request
->after_chunk_tracefile
);
834 if(events_request
->after_chunk_trace
!= NULL
)
835 lttv_hooks_destroy(events_request
->after_chunk_trace
);
836 if(events_request
->after_chunk_traceset
!= NULL
)
837 lttv_hooks_destroy(events_request
->after_chunk_traceset
);
838 if(events_request
->before_request
!= NULL
)
839 lttv_hooks_destroy(events_request
->before_request
);
840 if(events_request
->after_request
!= NULL
)
841 lttv_hooks_destroy(events_request
->after_request
);
843 g_free(events_request
);
848 /* lttvwindow_process_pending_requests
850 * This internal function gets called by g_idle, taking care of the pending
851 * requests. It is responsible for concatenation of time intervals and position
852 * requests. It does it with the following algorithm organizing process traceset
853 * calls. Here is the detailed description of the way it works :
855 * - Events Requests Servicing Algorithm
857 * Data structures necessary :
859 * List of requests added to context : list_in
860 * List of requests not added to context : list_out
865 * list_out : many events requests
867 * FIXME : insert rest of algorithm here
871 #define list_out tab->events_requests
873 gboolean
lttvwindow_process_pending_requests(Tab
*tab
)
876 LttvTracesetContext
*tsc
;
877 LttvTracefileContext
*tfc
;
878 GSList
*list_in
= NULL
;
882 LttvTracesetContextPosition
*end_position
;
885 g_critical("Foreground processing : tab does not exist. Processing removed.");
889 /* There is no events requests pending : we should never have been called! */
890 g_assert(g_slist_length(list_out
) != 0);
892 tsc
= LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
894 //set the cursor to be X shape, indicating that the computer is busy in doing its job
896 new = gdk_cursor_new(GDK_X_CURSOR
);
897 widget
= lookup_widget(tab
->mw
->mwindow
, "MToolbar1");
898 win
= gtk_widget_get_parent_window(widget
);
899 gdk_window_set_cursor(win
, new);
900 gdk_cursor_unref(new);
901 gdk_window_stick(win
);
902 gdk_window_unstick(win
);
905 g_debug("SIZE events req len : %d", g_slist_length(list_out
));
907 /* Preliminary check for no trace in traceset */
908 /* Unregister the routine if empty, empty list_out too */
909 if(lttv_traceset_number(tsc
->ts
) == 0) {
911 /* - For each req in list_out */
912 GSList
*iter
= list_out
;
914 while(iter
!= NULL
) {
916 gboolean remove
= FALSE
;
917 gboolean free_data
= FALSE
;
918 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
920 /* - Call end request for req */
921 if(events_request
->servicing
== TRUE
)
922 lttv_hooks_call(events_request
->after_request
, (gpointer
)tsc
);
924 /* - remove req from list_out */
925 /* Destroy the request */
932 GSList
*remove_iter
= iter
;
934 iter
= g_slist_next(iter
);
935 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
936 list_out
= g_slist_remove_link(list_out
, remove_iter
);
937 } else { // not remove
938 iter
= g_slist_next(iter
);
943 /* 0.1 Lock Traces */
948 iter_trace
<lttv_traceset_number(tsc
->ts
);
950 LttvTrace
*trace_v
= lttv_traceset_get(tsc
->ts
, iter_trace
);
952 if(lttvwindowtraces_lock(trace_v
) != 0) {
953 g_critical("Foreground processing : Unable to get trace lock");
954 return TRUE
; /* Cannot get lock, try later */
959 /* 0.2 Seek tracefiles positions to context position */
960 lttv_process_traceset_synchronize_tracefiles(tsc
);
963 /* Events processing algorithm implementation */
964 /* Warning : the gtk_events_pending takes a LOT of cpu time. So what we do
965 * instead is to leave the control to GTK and take it back.
967 /* A. Servicing loop */
968 //while( (g_slist_length(list_in) != 0 || g_slist_length(list_out) != 0)) {
969 if((g_slist_length(list_in
) != 0 || g_slist_length(list_out
) != 0)) {
971 /* 1. If list_in is empty (need a seek) */
972 if( g_slist_length(list_in
) == 0 ) {
974 /* list in is empty, need a seek */
976 /* 1.1 Add requests to list_in */
977 GSList
*ltime
= NULL
;
981 /* 1.1.1 Find all time requests with the lowest start time in list_out
984 if(g_slist_length(list_out
) > 0)
985 ltime
= g_slist_append(ltime
, g_slist_nth_data(list_out
, 0));
986 for(iter
=g_slist_nth(list_out
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
987 /* Find all time requests with the lowest start time in list_out */
988 EventsRequest
*event_request_ltime
= (EventsRequest
*)g_slist_nth_data(ltime
, 0);
989 EventsRequest
*event_request_list_out
= (EventsRequest
*)iter
->data
;
992 comp
= ltt_time_compare(event_request_ltime
->start_time
,
993 event_request_list_out
->start_time
);
995 ltime
= g_slist_append(ltime
, event_request_list_out
);
997 /* Remove all elements from ltime, and add current */
999 ltime
= g_slist_delete_link(ltime
, g_slist_nth(ltime
, 0));
1000 ltime
= g_slist_append(ltime
, event_request_list_out
);
1004 /* 1.1.2 Find all position requests with the lowest position in list_out
1007 if(g_slist_length(list_out
) > 0)
1008 lpos
= g_slist_append(lpos
, g_slist_nth_data(list_out
, 0));
1009 for(iter
=g_slist_nth(list_out
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
1010 /* Find all position requests with the lowest position in list_out */
1011 EventsRequest
*event_request_lpos
= (EventsRequest
*)g_slist_nth_data(lpos
, 0);
1012 EventsRequest
*event_request_list_out
= (EventsRequest
*)iter
->data
;
1015 if(event_request_lpos
->start_position
!= NULL
1016 && event_request_list_out
->start_position
!= NULL
)
1018 comp
= lttv_traceset_context_pos_pos_compare
1019 (event_request_lpos
->start_position
,
1020 event_request_list_out
->start_position
);
1025 lpos
= g_slist_append(lpos
, event_request_list_out
);
1027 /* Remove all elements from lpos, and add current */
1029 lpos
= g_slist_delete_link(lpos
, g_slist_nth(lpos
, 0));
1030 lpos
= g_slist_append(lpos
, event_request_list_out
);
1035 EventsRequest
*event_request_lpos
= (EventsRequest
*)g_slist_nth_data(lpos
, 0);
1036 EventsRequest
*event_request_ltime
= (EventsRequest
*)g_slist_nth_data(ltime
, 0);
1037 LttTime lpos_start_time
;
1039 if(event_request_lpos
!= NULL
1040 && event_request_lpos
->start_position
!= NULL
) {
1041 lpos_start_time
= lttv_traceset_context_position_get_time(
1042 event_request_lpos
->start_position
);
1045 /* 1.1.3 If lpos.start time < ltime */
1046 if(event_request_lpos
!= NULL
1047 && event_request_lpos
->start_position
!= NULL
1048 && ltt_time_compare(lpos_start_time
,
1049 event_request_ltime
->start_time
)<0) {
1050 /* Add lpos to list_in, remove them from list_out */
1051 for(iter
=lpos
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
1052 /* Add to list_in */
1053 EventsRequest
*event_request_lpos
=
1054 (EventsRequest
*)iter
->data
;
1056 list_in
= g_slist_append(list_in
, event_request_lpos
);
1057 /* Remove from list_out */
1058 list_out
= g_slist_remove(list_out
, event_request_lpos
);
1061 /* 1.1.4 (lpos.start time >= ltime) */
1062 /* Add ltime to list_in, remove them from list_out */
1064 for(iter
=ltime
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
1065 /* Add to list_in */
1066 EventsRequest
*event_request_ltime
=
1067 (EventsRequest
*)iter
->data
;
1069 list_in
= g_slist_append(list_in
, event_request_ltime
);
1070 /* Remove from list_out */
1071 list_out
= g_slist_remove(list_out
, event_request_ltime
);
1076 g_slist_free(ltime
);
1081 tfc
= lttv_traceset_context_get_current_tfc(tsc
);
1082 g_assert(g_slist_length(list_in
)>0);
1083 EventsRequest
*events_request
= g_slist_nth_data(list_in
, 0);
1086 /* 1.2.1 If first request in list_in is a time request */
1087 if(events_request
->start_position
== NULL
) {
1088 /* - If first req in list_in start time != current time */
1089 if(tfc
== NULL
|| ltt_time_compare(events_request
->start_time
,
1090 tfc
->timestamp
) != 0)
1091 /* - Seek to that time */
1092 g_debug("SEEK TIME : %lu, %lu", events_request
->start_time
.tv_sec
,
1093 events_request
->start_time
.tv_nsec
);
1094 //lttv_process_traceset_seek_time(tsc, events_request->start_time);
1095 lttv_state_traceset_seek_time_closest(LTTV_TRACESET_STATE(tsc
),
1096 events_request
->start_time
);
1098 /* Process the traceset with only state hooks */
1100 lttv_process_traceset_middle(tsc
,
1101 events_request
->start_time
,
1107 /* Else, the first request in list_in is a position request */
1108 /* If first req in list_in pos != current pos */
1109 g_assert(events_request
->start_position
!= NULL
);
1110 g_debug("SEEK POS time : %lu, %lu",
1111 lttv_traceset_context_position_get_time(
1112 events_request
->start_position
).tv_sec
,
1113 lttv_traceset_context_position_get_time(
1114 events_request
->start_position
).tv_nsec
);
1116 g_debug("SEEK POS context time : %lu, %lu",
1117 lttv_traceset_context_get_current_tfc(tsc
)->timestamp
.tv_sec
,
1118 lttv_traceset_context_get_current_tfc(tsc
)->timestamp
.tv_nsec
);
1119 g_assert(events_request
->start_position
!= NULL
);
1120 if(lttv_traceset_context_ctx_pos_compare(tsc
,
1121 events_request
->start_position
) != 0) {
1122 /* 1.2.2.1 Seek to that position */
1123 g_debug("SEEK POSITION");
1124 //lttv_process_traceset_seek_position(tsc, events_request->start_position);
1125 pos_time
= lttv_traceset_context_position_get_time(
1126 events_request
->start_position
);
1128 lttv_state_traceset_seek_time_closest(LTTV_TRACESET_STATE(tsc
),
1131 /* Process the traceset with only state hooks */
1133 lttv_process_traceset_middle(tsc
,
1136 events_request
->start_position
);
1137 g_assert(lttv_traceset_context_ctx_pos_compare(tsc
,
1138 events_request
->start_position
) == 0);
1145 /* 1.3 Add hooks and call before request for all list_in members */
1147 GSList
*iter
= NULL
;
1149 for(iter
=list_in
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
1150 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1151 /* 1.3.1 If !servicing */
1152 if(events_request
->servicing
== FALSE
) {
1153 /* - begin request hooks called
1154 * - servicing = TRUE
1156 lttv_hooks_call(events_request
->before_request
, (gpointer
)tsc
);
1157 events_request
->servicing
= TRUE
;
1159 /* 1.3.2 call before chunk
1160 * 1.3.3 events hooks added
1162 if(events_request
->trace
== -1)
1163 lttv_process_traceset_begin(tsc
,
1164 events_request
->before_chunk_traceset
,
1165 events_request
->before_chunk_trace
,
1166 events_request
->before_chunk_tracefile
,
1167 events_request
->event
,
1168 events_request
->event_by_id
);
1170 guint nb_trace
= lttv_traceset_number(tsc
->ts
);
1171 g_assert((guint
)events_request
->trace
< nb_trace
&&
1172 events_request
->trace
> -1);
1173 LttvTraceContext
*tc
= tsc
->traces
[events_request
->trace
];
1175 lttv_hooks_call(events_request
->before_chunk_traceset
, tsc
);
1177 lttv_trace_context_add_hooks(tc
,
1178 events_request
->before_chunk_trace
,
1179 events_request
->before_chunk_tracefile
,
1180 events_request
->event
,
1181 events_request
->event_by_id
);
1186 /* 2. Else, list_in is not empty, we continue a read */
1189 /* 2.0 For each req of list_in */
1190 GSList
*iter
= list_in
;
1192 while(iter
!= NULL
) {
1194 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1196 /* - Call before chunk
1197 * - events hooks added
1199 if(events_request
->trace
== -1)
1200 lttv_process_traceset_begin(tsc
,
1201 events_request
->before_chunk_traceset
,
1202 events_request
->before_chunk_trace
,
1203 events_request
->before_chunk_tracefile
,
1204 events_request
->event
,
1205 events_request
->event_by_id
);
1207 guint nb_trace
= lttv_traceset_number(tsc
->ts
);
1208 g_assert((guint
)events_request
->trace
< nb_trace
&&
1209 events_request
->trace
> -1);
1210 LttvTraceContext
*tc
= tsc
->traces
[events_request
->trace
];
1212 lttv_hooks_call(events_request
->before_chunk_traceset
, tsc
);
1214 lttv_trace_context_add_hooks(tc
,
1215 events_request
->before_chunk_trace
,
1216 events_request
->before_chunk_tracefile
,
1217 events_request
->event
,
1218 events_request
->event_by_id
);
1221 iter
= g_slist_next(iter
);
1226 tfc
= lttv_traceset_context_get_current_tfc(tsc
);
1228 /* 2.1 For each req of list_out */
1229 GSList
*iter
= list_out
;
1231 while(iter
!= NULL
) {
1233 gboolean remove
= FALSE
;
1234 gboolean free_data
= FALSE
;
1235 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1237 /* if req.start time == current context time
1238 * or req.start position == current position*/
1239 if( ltt_time_compare(events_request
->start_time
,
1240 tfc
->timestamp
) == 0
1242 (events_request
->start_position
!= NULL
1244 lttv_traceset_context_ctx_pos_compare(tsc
,
1245 events_request
->start_position
) == 0)
1247 /* - Add to list_in, remove from list_out */
1248 list_in
= g_slist_append(list_in
, events_request
);
1252 /* - If !servicing */
1253 if(events_request
->servicing
== FALSE
) {
1254 /* - begin request hooks called
1255 * - servicing = TRUE
1257 lttv_hooks_call(events_request
->before_request
, (gpointer
)tsc
);
1258 events_request
->servicing
= TRUE
;
1260 /* call before chunk
1261 * events hooks added
1263 if(events_request
->trace
== -1)
1264 lttv_process_traceset_begin(tsc
,
1265 events_request
->before_chunk_traceset
,
1266 events_request
->before_chunk_trace
,
1267 events_request
->before_chunk_tracefile
,
1268 events_request
->event
,
1269 events_request
->event_by_id
);
1271 guint nb_trace
= lttv_traceset_number(tsc
->ts
);
1272 g_assert((guint
)events_request
->trace
< nb_trace
&&
1273 events_request
->trace
> -1);
1274 LttvTraceContext
*tc
= tsc
->traces
[events_request
->trace
];
1276 lttv_hooks_call(events_request
->before_chunk_traceset
, tsc
);
1278 lttv_trace_context_add_hooks(tc
,
1279 events_request
->before_chunk_trace
,
1280 events_request
->before_chunk_tracefile
,
1281 events_request
->event
,
1282 events_request
->event_by_id
);
1291 GSList
*remove_iter
= iter
;
1293 iter
= g_slist_next(iter
);
1294 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
1295 list_out
= g_slist_remove_link(list_out
, remove_iter
);
1296 } else { // not remove
1297 iter
= g_slist_next(iter
);
1303 /* 3. Find end criterions */
1308 /* 3.1.1 Find lowest end time in list_in */
1309 g_assert(g_slist_length(list_in
)>0);
1310 end_time
= ((EventsRequest
*)g_slist_nth_data(list_in
,0))->end_time
;
1312 for(iter
=g_slist_nth(list_in
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
1313 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1315 if(ltt_time_compare(events_request
->end_time
,
1317 end_time
= events_request
->end_time
;
1320 /* 3.1.2 Find lowest start time in list_out */
1321 for(iter
=list_out
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
1322 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1324 if(ltt_time_compare(events_request
->start_time
,
1326 end_time
= events_request
->start_time
;
1331 /* 3.2 Number of events */
1333 /* 3.2.1 Find lowest number of events in list_in */
1336 end_nb_events
= ((EventsRequest
*)g_slist_nth_data(list_in
,0))->num_events
;
1338 for(iter
=g_slist_nth(list_in
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
1339 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1341 if(events_request
->num_events
< end_nb_events
)
1342 end_nb_events
= events_request
->num_events
;
1345 /* 3.2.2 Use min(CHUNK_NUM_EVENTS, min num events in list_in) as
1348 end_nb_events
= MIN(CHUNK_NUM_EVENTS
, end_nb_events
);
1352 /* 3.3 End position */
1354 /* 3.3.1 Find lowest end position in list_in */
1357 end_position
=((EventsRequest
*)g_slist_nth_data(list_in
,0))->end_position
;
1359 for(iter
=g_slist_nth(list_in
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
1360 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1362 if(events_request
->end_position
!= NULL
&& end_position
!= NULL
&&
1363 lttv_traceset_context_pos_pos_compare(events_request
->end_position
,
1365 end_position
= events_request
->end_position
;
1370 /* 3.3.2 Find lowest start position in list_out */
1373 for(iter
=list_out
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
1374 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1376 if(events_request
->end_position
!= NULL
&& end_position
!= NULL
&&
1377 lttv_traceset_context_pos_pos_compare(events_request
->end_position
,
1379 end_position
= events_request
->end_position
;
1384 /* 4. Call process traceset middle */
1385 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
);
1386 count
= lttv_process_traceset_middle(tsc
, end_time
, end_nb_events
, end_position
);
1388 tfc
= lttv_traceset_context_get_current_tfc(tsc
);
1390 g_debug("Context time after middle : %lu, %lu", tfc
->timestamp
.tv_sec
,
1391 tfc
->timestamp
.tv_nsec
);
1393 g_debug("End of trace reached after middle.");
1397 /* 5. After process traceset middle */
1398 tfc
= lttv_traceset_context_get_current_tfc(tsc
);
1400 /* - if current context time > traceset.end time */
1401 if(tfc
== NULL
|| ltt_time_compare(tfc
->timestamp
,
1402 tsc
->time_span
.end_time
) > 0) {
1403 /* - For each req in list_in */
1404 GSList
*iter
= list_in
;
1406 while(iter
!= NULL
) {
1408 gboolean remove
= FALSE
;
1409 gboolean free_data
= FALSE
;
1410 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1412 /* - Remove events hooks for req
1413 * - Call end chunk for req
1416 if(events_request
->trace
== -1)
1417 lttv_process_traceset_end(tsc
,
1418 events_request
->after_chunk_traceset
,
1419 events_request
->after_chunk_trace
,
1420 events_request
->after_chunk_tracefile
,
1421 events_request
->event
,
1422 events_request
->event_by_id
);
1425 guint nb_trace
= lttv_traceset_number(tsc
->ts
);
1426 g_assert(events_request
->trace
< nb_trace
&&
1427 events_request
->trace
> -1);
1428 LttvTraceContext
*tc
= tsc
->traces
[events_request
->trace
];
1430 lttv_trace_context_remove_hooks(tc
,
1431 events_request
->after_chunk_trace
,
1432 events_request
->after_chunk_tracefile
,
1433 events_request
->event
,
1434 events_request
->event_by_id
);
1435 lttv_hooks_call(events_request
->after_chunk_traceset
, tsc
);
1440 /* - Call end request for req */
1441 lttv_hooks_call(events_request
->after_request
, (gpointer
)tsc
);
1443 /* - remove req from list_in */
1444 /* Destroy the request */
1451 GSList
*remove_iter
= iter
;
1453 iter
= g_slist_next(iter
);
1454 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
1455 list_in
= g_slist_remove_link(list_in
, remove_iter
);
1456 } else { // not remove
1457 iter
= g_slist_next(iter
);
1462 /* 5.1 For each req in list_in */
1463 GSList
*iter
= list_in
;
1465 while(iter
!= NULL
) {
1467 gboolean remove
= FALSE
;
1468 gboolean free_data
= FALSE
;
1469 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1471 /* - Remove events hooks for req
1472 * - Call end chunk for req
1474 if(events_request
->trace
== -1)
1475 lttv_process_traceset_end(tsc
,
1476 events_request
->after_chunk_traceset
,
1477 events_request
->after_chunk_trace
,
1478 events_request
->after_chunk_tracefile
,
1479 events_request
->event
,
1480 events_request
->event_by_id
);
1483 guint nb_trace
= lttv_traceset_number(tsc
->ts
);
1484 g_assert(events_request
->trace
< nb_trace
&&
1485 events_request
->trace
> -1);
1486 LttvTraceContext
*tc
= tsc
->traces
[events_request
->trace
];
1488 lttv_trace_context_remove_hooks(tc
,
1489 events_request
->after_chunk_trace
,
1490 events_request
->after_chunk_tracefile
,
1491 events_request
->event
,
1492 events_request
->event_by_id
);
1494 lttv_hooks_call(events_request
->after_chunk_traceset
, tsc
);
1497 /* - req.num -= count */
1498 g_assert(events_request
->num_events
>= count
);
1499 events_request
->num_events
-= count
;
1501 g_assert(tfc
!= NULL
);
1502 /* - if req.num == 0
1504 * current context time >= req.end time
1506 * req.end pos == current pos
1508 * req.stop_flag == TRUE
1510 if( events_request
->num_events
== 0
1512 events_request
->stop_flag
== TRUE
1514 ltt_time_compare(tfc
->timestamp
,
1515 events_request
->end_time
) >= 0
1517 (events_request
->end_position
!= NULL
1519 lttv_traceset_context_ctx_pos_compare(tsc
,
1520 events_request
->end_position
) == 0)
1523 g_assert(events_request
->servicing
== TRUE
);
1524 /* - Call end request for req
1525 * - remove req from list_in */
1526 lttv_hooks_call(events_request
->after_request
, (gpointer
)tsc
);
1527 /* - remove req from list_in */
1528 /* Destroy the request */
1536 GSList
*remove_iter
= iter
;
1538 iter
= g_slist_next(iter
);
1539 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
1540 list_in
= g_slist_remove_link(list_in
, remove_iter
);
1541 } else { // not remove
1542 iter
= g_slist_next(iter
);
1548 /* End of removed servicing loop : leave control to GTK instead. */
1549 // if(gtk_events_pending()) break;
1552 /* B. When interrupted between chunks */
1555 GSList
*iter
= list_in
;
1557 /* 1. for each request in list_in */
1558 while(iter
!= NULL
) {
1560 gboolean remove
= FALSE
;
1561 gboolean free_data
= FALSE
;
1562 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1564 /* 1.1. Use current postition as start position */
1565 if(events_request
->start_position
!= NULL
)
1566 lttv_traceset_context_position_destroy(events_request
->start_position
);
1567 events_request
->start_position
= lttv_traceset_context_position_new();
1568 lttv_traceset_context_position_save(tsc
, events_request
->start_position
);
1570 /* 1.2. Remove start time */
1571 events_request
->start_time
= ltt_time_infinite
;
1573 /* 1.3. Move from list_in to list_out */
1576 list_out
= g_slist_append(list_out
, events_request
);
1581 GSList
*remove_iter
= iter
;
1583 iter
= g_slist_next(iter
);
1584 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
1585 list_in
= g_slist_remove_link(list_in
, remove_iter
);
1586 } else { // not remove
1587 iter
= g_slist_next(iter
);
1594 /* C Unlock Traces */
1596 //lttv_process_traceset_get_sync_data(tsc);
1601 iter_trace
<lttv_traceset_number(tsc
->ts
);
1603 LttvTrace
*trace_v
= lttv_traceset_get(tsc
->ts
, iter_trace
);
1605 lttvwindowtraces_unlock(trace_v
);
1610 //set the cursor back to normal
1611 gdk_window_set_cursor(win
, NULL
);
1614 g_assert(g_slist_length(list_in
) == 0);
1616 if( g_slist_length(list_out
) == 0 ) {
1617 /* Put tab's request pending flag back to normal */
1618 tab
->events_request_pending
= FALSE
;
1619 g_debug("remove the idle fct");
1620 return FALSE
; /* Remove the idle function */
1622 g_debug("leave the idle fct");
1623 return TRUE
; /* Leave the idle function */
1625 /* We do not use simili-round-robin, it may require to read 1 meg buffers
1626 * again and again if many tracesets use the same tracefiles. */
1627 /* Hack for round-robin idle functions */
1628 /* It will put the idle function at the end of the pool */
1629 /*g_idle_add_full((G_PRIORITY_HIGH_IDLE + 21),
1630 (GSourceFunc)execute_events_requests,
1640 static void lttvwindow_add_trace(Tab
*tab
, LttvTrace
*trace_v
)
1642 LttvTraceset
*traceset
= tab
->traceset_info
->traceset
;
1644 guint num_traces
= lttv_traceset_number(traceset
);
1646 //Verify if trace is already present.
1647 for(i
=0; i
<num_traces
; i
++)
1649 LttvTrace
* trace
= lttv_traceset_get(traceset
, i
);
1650 if(trace
== trace_v
)
1654 //Keep a reference to the traces so they are not freed.
1655 for(i
=0; i
<lttv_traceset_number(traceset
); i
++)
1657 LttvTrace
* trace
= lttv_traceset_get(traceset
, i
);
1658 lttv_trace_ref(trace
);
1661 //remove state update hooks
1662 lttv_state_remove_event_hooks(
1663 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1665 lttv_context_fini(LTTV_TRACESET_CONTEXT(
1666 tab
->traceset_info
->traceset_context
));
1667 g_object_unref(tab
->traceset_info
->traceset_context
);
1669 lttv_traceset_add(traceset
, trace_v
);
1670 lttv_trace_ref(trace_v
); /* local ref */
1672 /* Create new context */
1673 tab
->traceset_info
->traceset_context
=
1674 g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
1676 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->
1681 //add state update hooks
1682 lttv_state_add_event_hooks(
1683 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1684 //Remove local reference to the traces.
1685 for(i
=0; i
<lttv_traceset_number(traceset
); i
++)
1687 LttvTrace
* trace
= lttv_traceset_get(traceset
, i
);
1688 lttv_trace_unref(trace
);
1692 //add_trace_into_traceset_selector(GTK_MULTIVPANED(tab->multivpaned), lttv_trace(trace_v));
1695 /* add_trace adds a trace into the current traceset. It first displays a
1696 * directory selection dialogue to let user choose a trace, then recreates
1697 * tracset_context, and redraws all the viewer of the current tab
1700 void add_trace(GtkWidget
* widget
, gpointer user_data
)
1703 LttvTrace
* trace_v
;
1704 LttvTraceset
* traceset
;
1706 char abs_path
[PATH_MAX
];
1708 MainWindow
* mw_data
= get_window_data_struct(widget
);
1709 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
1711 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
1712 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
1716 tab
= create_new_tab(widget
, NULL
);
1718 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
1721 GtkDirSelection
* file_selector
= (GtkDirSelection
*)gtk_dir_selection_new("Select a trace");
1722 gtk_dir_selection_hide_fileop_buttons(file_selector
);
1724 if(remember_trace_dir
[0] != '\0')
1725 gtk_dir_selection_set_filename(file_selector
, remember_trace_dir
);
1727 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
1729 case GTK_RESPONSE_ACCEPT
:
1730 case GTK_RESPONSE_OK
:
1731 dir
= gtk_dir_selection_get_dir (file_selector
);
1732 strncpy(remember_trace_dir
, dir
, PATH_MAX
);
1733 if(!dir
|| strlen(dir
) == 0){
1734 gtk_widget_destroy((GtkWidget
*)file_selector
);
1737 get_absolute_pathname(dir
, abs_path
);
1738 // Mathieu : modify to not share traces anymore : mmap uses so much less
1739 // memory than a full buffer read...
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
1783 * It destroys the filter tree. FIXME... we should request for an update
1787 void remove_trace(GtkWidget
*widget
, gpointer user_data
)
1790 LttvTrace
* trace_v
;
1791 LttvTraceset
* traceset
;
1792 gint i
, j
, nb_trace
, index
=-1;
1793 char ** name
, *remove_trace_name
;
1794 MainWindow
* mw_data
= get_window_data_struct(widget
);
1795 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
1797 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
1798 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
1804 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
1807 nb_trace
=lttv_traceset_number(tab
->traceset_info
->traceset
);
1808 name
= g_new(char*,nb_trace
);
1809 for(i
= 0; i
< nb_trace
; i
++){
1810 trace_v
= lttv_traceset_get(tab
->traceset_info
->traceset
, i
);
1811 trace
= lttv_trace(trace_v
);
1812 name
[i
] = ltt_trace_name(trace
);
1815 remove_trace_name
= get_remove_trace(name
, nb_trace
);
1818 if(remove_trace_name
){
1820 /* yuk, cut n paste from old code.. should be better (MD)*/
1821 for(i
= 0; i
<nb_trace
; i
++) {
1822 if(strcmp(remove_trace_name
,name
[i
]) == 0){
1827 traceset
= tab
->traceset_info
->traceset
;
1828 //Keep a reference to the traces so they are not freed.
1829 for(j
=0; j
<lttv_traceset_number(traceset
); j
++)
1831 LttvTrace
* trace
= lttv_traceset_get(traceset
, j
);
1832 lttv_trace_ref(trace
);
1835 //remove state update hooks
1836 lttv_state_remove_event_hooks(
1837 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1838 lttv_context_fini(LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
));
1839 g_object_unref(tab
->traceset_info
->traceset_context
);
1841 trace_v
= lttv_traceset_get(traceset
, index
);
1843 lttv_traceset_remove(traceset
, index
);
1844 lttv_trace_unref(trace_v
); // Remove local reference
1846 // if(lttv_trace_get_ref_number(trace_v) <= 1) {
1847 /* ref 1 : lttvwindowtraces only*/
1848 ltt_trace_close(lttv_trace(trace_v
));
1849 /* lttvwindowtraces_remove_trace takes care of destroying
1850 * the traceset linked with the trace_v and also of destroying
1851 * the trace_v at the same time.
1853 // lttvwindowtraces_remove_trace(trace_v);
1856 tab
->traceset_info
->traceset_context
=
1857 g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
1859 LTTV_TRACESET_CONTEXT(tab
->
1860 traceset_info
->traceset_context
),traceset
);
1861 //add state update hooks
1862 lttv_state_add_event_hooks(
1863 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1865 //Remove local reference to the traces.
1866 for(j
=0; j
<lttv_traceset_number(traceset
); j
++)
1868 LttvTrace
* trace
= lttv_traceset_get(traceset
, j
);
1869 lttv_trace_unref(trace
);
1872 SetTraceset(tab
, (gpointer
)traceset
);
1878 void remove_trace(GtkWidget
* widget
, gpointer user_data
)
1881 LttvTrace
* trace_v
;
1882 LttvTraceset
* traceset
;
1883 gint i
, j
, nb_trace
;
1884 char ** name
, *remove_trace_name
;
1885 MainWindow
* mw_data
= get_window_data_struct(widget
);
1886 LttvTracesetSelector
* s
;
1887 LttvTraceSelector
* t
;
1890 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
1892 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
1893 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
1899 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
1902 nb_trace
=lttv_traceset_number(tab
->traceset_info
->traceset
);
1903 name
= g_new(char*,nb_trace
);
1904 for(i
= 0; i
< nb_trace
; i
++){
1905 trace_v
= lttv_traceset_get(tab
->traceset_info
->traceset
, i
);
1906 trace
= lttv_trace(trace_v
);
1907 name
[i
] = ltt_trace_name(trace
);
1910 remove_trace_name
= get_remove_trace(name
, nb_trace
);
1912 if(remove_trace_name
){
1913 for(i
=0; i
<nb_trace
; i
++){
1914 if(strcmp(remove_trace_name
,name
[i
]) == 0){
1915 //unselect the trace from the current viewer
1917 w
= gtk_multivpaned_get_widget(GTK_MULTIVPANED(tab
->multivpaned
));
1919 s
= g_object_get_data(G_OBJECT(w
), "Traceset_Selector");
1921 t
= lttv_traceset_selector_trace_get(s
,i
);
1922 lttv_trace_selector_set_selected(t
, FALSE
);
1925 //check if other viewers select the trace
1926 w
= gtk_multivpaned_get_first_widget(GTK_MULTIVPANED(tab
->multivpaned
));
1928 s
= g_object_get_data(G_OBJECT(w
), "Traceset_Selector");
1930 t
= lttv_traceset_selector_trace_get(s
,i
);
1931 selected
= lttv_trace_selector_get_selected(t
);
1934 w
= gtk_multivpaned_get_next_widget(GTK_MULTIVPANED(tab
->multivpaned
));
1936 }else selected
= FALSE
;
1938 //if no viewer selects the trace, remove it
1940 remove_trace_from_traceset_selector(GTK_MULTIVPANED(tab
->multivpaned
), i
);
1942 traceset
= tab
->traceset_info
->traceset
;
1943 //Keep a reference to the traces so they are not freed.
1944 for(j
=0; j
<lttv_traceset_number(traceset
); j
++)
1946 LttvTrace
* trace
= lttv_traceset_get(traceset
, j
);
1947 lttv_trace_ref(trace
);
1950 //remove state update hooks
1951 lttv_state_remove_event_hooks(
1952 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1953 lttv_context_fini(LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
));
1954 g_object_unref(tab
->traceset_info
->traceset_context
);
1957 trace_v
= lttv_traceset_get(traceset
, i
);
1959 if(lttv_trace_get_ref_number(trace_v
) <= 2) {
1960 /* ref 2 : traceset, local */
1961 lttvwindowtraces_remove_trace(trace_v
);
1962 ltt_trace_close(lttv_trace(trace_v
));
1965 lttv_traceset_remove(traceset
, i
);
1966 lttv_trace_unref(trace_v
); // Remove local reference
1968 if(!lttv_trace_get_ref_number(trace_v
))
1969 lttv_trace_destroy(trace_v
);
1971 tab
->traceset_info
->traceset_context
=
1972 g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
1974 LTTV_TRACESET_CONTEXT(tab
->
1975 traceset_info
->traceset_context
),traceset
);
1976 //add state update hooks
1977 lttv_state_add_event_hooks(
1978 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1980 //Remove local reference to the traces.
1981 for(j
=0; j
<lttv_traceset_number(traceset
); j
++)
1983 LttvTrace
* trace
= lttv_traceset_get(traceset
, j
);
1984 lttv_trace_unref(trace
);
1988 //update current tab
1989 //update_traceset(mw_data);
1992 SetTraceset(tab
, (gpointer
)traceset
);
1993 // in expose now call_pending_read_hooks(mw_data);
1995 //lttvwindow_report_current_time(mw_data,&(tab->current_time));
1998 // while(tab->multi_vpaned->num_children){
1999 // gtk_multi_vpaned_widget_delete(tab->multi_vpaned);
2013 /* Redraw all the viewers in the current tab */
2014 void redraw(GtkWidget
*widget
, gpointer user_data
)
2016 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
2017 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2018 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2023 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
2027 LttvAttributeValue value
;
2029 g_assert(lttv_iattribute_find_by_path(tab
->attributes
, "hooks/redraw", LTTV_POINTER
, &value
));
2031 tmp
= (LttvHooks
*)*(value
.v_pointer
);
2033 lttv_hooks_call(tmp
,NULL
);
2037 void continue_processing(GtkWidget
*widget
, gpointer user_data
)
2039 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
2040 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2041 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2046 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
2050 LttvAttributeValue value
;
2052 g_assert(lttv_iattribute_find_by_path(tab
->attributes
,
2053 "hooks/continue", LTTV_POINTER
, &value
));
2055 tmp
= (LttvHooks
*)*(value
.v_pointer
);
2057 lttv_hooks_call(tmp
,NULL
);
2060 /* Stop the processing for the calling main window's current tab.
2061 * It removes every processing requests that are in its list. It does not call
2062 * the end request hooks, because the request is not finished.
2065 void stop_processing(GtkWidget
*widget
, gpointer user_data
)
2067 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
2068 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2069 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2074 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
2076 GSList
*iter
= tab
->events_requests
;
2078 while(iter
!= NULL
) {
2079 GSList
*remove_iter
= iter
;
2080 iter
= g_slist_next(iter
);
2082 g_free(remove_iter
->data
);
2083 tab
->events_requests
=
2084 g_slist_remove_link(tab
->events_requests
, remove_iter
);
2086 tab
->events_request_pending
= FALSE
;
2087 g_idle_remove_by_data(tab
);
2088 g_assert(g_slist_length(tab
->events_requests
) == 0);
2092 /* save will save the traceset to a file
2093 * Not implemented yet FIXME
2096 void save(GtkWidget
* widget
, gpointer user_data
)
2101 void save_as(GtkWidget
* widget
, gpointer user_data
)
2103 g_info("Save as\n");
2107 /* zoom will change the time_window of all the viewers of the
2108 * current tab, and redisplay them. The main functionality is to
2109 * determine the new time_window of the current tab
2112 void zoom(GtkWidget
* widget
, double size
)
2114 TimeInterval time_span
;
2115 TimeWindow new_time_window
;
2116 LttTime current_time
, time_delta
;
2117 MainWindow
* mw_data
= get_window_data_struct(widget
);
2118 LttvTracesetContext
*tsc
;
2119 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
2121 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2122 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2128 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
2131 if(size
== 1) return;
2133 tsc
= LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
2134 time_span
= tsc
->time_span
;
2135 new_time_window
= tab
->time_window
;
2136 current_time
= tab
->current_time
;
2138 time_delta
= ltt_time_sub(time_span
.end_time
,time_span
.start_time
);
2140 new_time_window
.start_time
= time_span
.start_time
;
2141 new_time_window
.time_width
= time_delta
;
2142 new_time_window
.time_width_double
= ltt_time_to_double(time_delta
);
2143 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
2144 new_time_window
.time_width
) ;
2146 new_time_window
.time_width
= ltt_time_div(new_time_window
.time_width
, size
);
2147 new_time_window
.time_width_double
=
2148 ltt_time_to_double(new_time_window
.time_width
);
2149 if(ltt_time_compare(new_time_window
.time_width
,time_delta
) > 0)
2150 { /* Case where zoom out is bigger than trace length */
2151 new_time_window
.start_time
= time_span
.start_time
;
2152 new_time_window
.time_width
= time_delta
;
2153 new_time_window
.time_width_double
= ltt_time_to_double(time_delta
);
2154 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
2155 new_time_window
.time_width
) ;
2159 /* Center the image on the current time */
2160 new_time_window
.start_time
=
2161 ltt_time_sub(current_time
,
2162 ltt_time_from_double(new_time_window
.time_width_double
/2.0));
2163 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
2164 new_time_window
.time_width
) ;
2165 /* If on borders, don't fall off */
2166 if(ltt_time_compare(new_time_window
.start_time
, time_span
.start_time
) <0)
2168 new_time_window
.start_time
= time_span
.start_time
;
2169 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
2170 new_time_window
.time_width
) ;
2174 if(ltt_time_compare(new_time_window
.end_time
,
2175 time_span
.end_time
) > 0)
2177 new_time_window
.start_time
=
2178 ltt_time_sub(time_span
.end_time
, new_time_window
.time_width
);
2180 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
2181 new_time_window
.time_width
) ;
2188 if(ltt_time_compare(new_time_window
.time_width
, ltt_time_zero
) == 0) {
2189 g_warning("Zoom more than 1 ns impossible");
2191 time_change_manager(tab
, new_time_window
);
2195 void zoom_in(GtkWidget
* widget
, gpointer user_data
)
2200 void zoom_out(GtkWidget
* widget
, gpointer user_data
)
2205 void zoom_extended(GtkWidget
* widget
, gpointer user_data
)
2210 void go_to_time(GtkWidget
* widget
, gpointer user_data
)
2212 g_info("Go to time\n");
2215 void show_time_frame(GtkWidget
* widget
, gpointer user_data
)
2217 g_info("Show time frame\n");
2221 /* callback function */
2224 on_empty_traceset_activate (GtkMenuItem
*menuitem
,
2227 create_new_window((GtkWidget
*)menuitem
, user_data
, FALSE
);
2232 on_clone_traceset_activate (GtkMenuItem
*menuitem
,
2235 create_new_window((GtkWidget
*)menuitem
, user_data
, TRUE
);
2239 /* create_new_tab calls create_tab to construct a new tab in the main window
2242 Tab
*create_new_tab(GtkWidget
* widget
, gpointer user_data
){
2243 gchar label
[PATH_MAX
];
2244 MainWindow
* mw_data
= get_window_data_struct(widget
);
2246 GtkNotebook
* notebook
= (GtkNotebook
*)lookup_widget(widget
, "MNotebook");
2247 if(notebook
== NULL
){
2248 g_info("Notebook does not exist\n");
2251 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2252 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2258 copy_tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
2261 strcpy(label
,"Page");
2262 if(get_label(mw_data
, label
,"Get the name of the tab","Please input tab's name"))
2263 return (create_tab (mw_data
, copy_tab
, notebook
, label
));
2269 on_tab_activate (GtkMenuItem
*menuitem
,
2272 create_new_tab((GtkWidget
*)menuitem
, user_data
);
2277 on_open_activate (GtkMenuItem
*menuitem
,
2280 open_traceset((GtkWidget
*)menuitem
, user_data
);
2285 on_close_activate (GtkMenuItem
*menuitem
,
2288 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2289 main_window_destructor(mw_data
);
2293 /* remove the current tab from the main window
2297 on_close_tab_activate (GtkWidget
*widget
,
2301 GtkWidget
* notebook
;
2303 MainWindow
* mw_data
= get_window_data_struct(widget
);
2304 notebook
= lookup_widget(widget
, "MNotebook");
2305 if(notebook
== NULL
){
2306 g_info("Notebook does not exist\n");
2310 page_num
= gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
));
2312 gtk_notebook_remove_page(GTK_NOTEBOOK(notebook
), page_num
);
2317 on_close_tab_X_clicked (GtkWidget
*widget
,
2321 GtkWidget
*notebook
= lookup_widget(widget
, "MNotebook");
2322 if(notebook
== NULL
){
2323 g_info("Notebook does not exist\n");
2327 if((page_num
= gtk_notebook_page_num(GTK_NOTEBOOK(notebook
), widget
)) != -1)
2328 gtk_notebook_remove_page(GTK_NOTEBOOK(notebook
), page_num
);
2334 on_add_trace_activate (GtkMenuItem
*menuitem
,
2337 add_trace((GtkWidget
*)menuitem
, user_data
);
2342 on_remove_trace_activate (GtkMenuItem
*menuitem
,
2345 remove_trace((GtkWidget
*)menuitem
, user_data
);
2350 on_save_activate (GtkMenuItem
*menuitem
,
2353 save((GtkWidget
*)menuitem
, user_data
);
2358 on_save_as_activate (GtkMenuItem
*menuitem
,
2361 save_as((GtkWidget
*)menuitem
, user_data
);
2366 on_quit_activate (GtkMenuItem
*menuitem
,
2374 on_cut_activate (GtkMenuItem
*menuitem
,
2382 on_copy_activate (GtkMenuItem
*menuitem
,
2390 on_paste_activate (GtkMenuItem
*menuitem
,
2398 on_delete_activate (GtkMenuItem
*menuitem
,
2406 on_zoom_in_activate (GtkMenuItem
*menuitem
,
2409 zoom_in((GtkWidget
*)menuitem
, user_data
);
2414 on_zoom_out_activate (GtkMenuItem
*menuitem
,
2417 zoom_out((GtkWidget
*)menuitem
, user_data
);
2422 on_zoom_extended_activate (GtkMenuItem
*menuitem
,
2425 zoom_extended((GtkWidget
*)menuitem
, user_data
);
2430 on_go_to_time_activate (GtkMenuItem
*menuitem
,
2433 go_to_time((GtkWidget
*)menuitem
, user_data
);
2438 on_show_time_frame_activate (GtkMenuItem
*menuitem
,
2441 show_time_frame((GtkWidget
*)menuitem
, user_data
);
2446 on_move_viewer_up_activate (GtkMenuItem
*menuitem
,
2449 move_up_viewer((GtkWidget
*)menuitem
, user_data
);
2454 on_move_viewer_down_activate (GtkMenuItem
*menuitem
,
2457 move_down_viewer((GtkWidget
*)menuitem
, user_data
);
2462 on_remove_viewer_activate (GtkMenuItem
*menuitem
,
2465 delete_viewer((GtkWidget
*)menuitem
, user_data
);
2469 on_trace_facility_activate (GtkMenuItem
*menuitem
,
2472 g_info("Trace facility selector: %s\n");
2476 /* Dispaly a file selection dialogue to let user select a library, then call
2477 * lttv_library_load().
2481 on_load_library_activate (GtkMenuItem
*menuitem
,
2484 GError
*error
= NULL
;
2485 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2487 gchar load_module_path_alter
[PATH_MAX
];
2491 gchar
*load_module_path
;
2492 name
= g_ptr_array_new();
2493 nb
= lttv_library_path_number();
2494 /* ask for the library path */
2498 path
= lttv_library_path_get(i
);
2499 g_ptr_array_add(name
, path
);
2502 load_module_path
= get_selection((char **)(name
->pdata
), name
->len
,
2503 "Select a library path", "Library paths");
2504 if(load_module_path
!= NULL
)
2505 strncpy(load_module_path_alter
, load_module_path
, PATH_MAX
-1); // -1 for /
2507 g_ptr_array_free(name
, TRUE
);
2509 if(load_module_path
== NULL
) return;
2513 /* Make sure the module path ends with a / */
2514 gchar
*ptr
= load_module_path_alter
;
2516 ptr
= strchr(ptr
, '\0');
2518 if(*(ptr
-1) != '/') {
2525 /* Ask for the library to load : list files in the previously selected
2527 gchar str
[PATH_MAX
];
2530 GtkFileSelection
* file_selector
=
2531 (GtkFileSelection
*)gtk_file_selection_new("Select a module");
2532 gtk_file_selection_set_filename(file_selector
, load_module_path_alter
);
2533 gtk_file_selection_hide_fileop_buttons(file_selector
);
2536 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
2538 case GTK_RESPONSE_ACCEPT
:
2539 case GTK_RESPONSE_OK
:
2540 dir
= gtk_file_selection_get_selections (file_selector
);
2541 strncpy(str
,dir
[0],PATH_MAX
);
2542 strncpy(remember_plugins_dir
,dir
[0],PATH_MAX
);
2543 /* only keep file name */
2545 str1
= strrchr(str
,'/');
2548 str1
= strrchr(str
,'\\');
2553 if(*str1
== 'l' && *(str1
+1)== 'i' && *(str1
+2)=='b')
2555 remove info after
. */
2559 str2
= strrchr(str2
, '.');
2560 if(str2
!= NULL
) *str2
= '\0';
2562 lttv_module_require(str1
, &error
);
2564 lttv_library_load(str1
, &error
);
2565 if(error
!= NULL
) g_warning("%s", error
->message
);
2566 else g_info("Load library: %s\n", str
);
2568 case GTK_RESPONSE_REJECT
:
2569 case GTK_RESPONSE_CANCEL
:
2571 gtk_widget_destroy((GtkWidget
*)file_selector
);
2582 /* Display all loaded modules, let user to select a module to unload
2583 * by calling lttv_module_unload
2587 on_unload_library_activate (GtkMenuItem
*menuitem
,
2590 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2592 LttvLibrary
*library
= NULL
;
2597 name
= g_ptr_array_new();
2598 nb
= lttv_library_number();
2599 LttvLibraryInfo
*lib_info
= g_new(LttvLibraryInfo
,nb
);
2600 /* ask for the library name */
2603 LttvLibrary
*iter_lib
= lttv_library_get(i
);
2604 lttv_library_info(iter_lib
, &lib_info
[i
]);
2606 gchar
*path
= lib_info
[i
].name
;
2607 g_ptr_array_add(name
, path
);
2609 lib_name
= get_selection((char **)(name
->pdata
), name
->len
,
2610 "Select a library", "Libraries");
2611 if(lib_name
!= NULL
) {
2613 if(strcmp(lib_name
, lib_info
[i
].name
) == 0) {
2614 library
= lttv_library_get(i
);
2619 g_ptr_array_free(name
, TRUE
);
2622 if(lib_name
== NULL
) return;
2624 if(library
!= NULL
) lttv_library_unload(library
);
2628 /* Dispaly a file selection dialogue to let user select a module, then call
2629 * lttv_module_require().
2633 on_load_module_activate (GtkMenuItem
*menuitem
,
2636 GError
*error
= NULL
;
2637 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2639 LttvLibrary
*library
= NULL
;
2644 name
= g_ptr_array_new();
2645 nb
= lttv_library_number();
2646 LttvLibraryInfo
*lib_info
= g_new(LttvLibraryInfo
,nb
);
2647 /* ask for the library name */
2650 LttvLibrary
*iter_lib
= lttv_library_get(i
);
2651 lttv_library_info(iter_lib
, &lib_info
[i
]);
2653 gchar
*path
= lib_info
[i
].name
;
2654 g_ptr_array_add(name
, path
);
2656 lib_name
= get_selection((char **)(name
->pdata
), name
->len
,
2657 "Select a library", "Libraries");
2658 if(lib_name
!= NULL
) {
2660 if(strcmp(lib_name
, lib_info
[i
].name
) == 0) {
2661 library
= lttv_library_get(i
);
2666 g_ptr_array_free(name
, TRUE
);
2669 if(lib_name
== NULL
) return;
2672 //LttvModule *module;
2673 gchar module_name_out
[PATH_MAX
];
2675 /* Ask for the module to load : list modules in the selected lib */
2679 nb
= lttv_library_module_number(library
);
2680 LttvModuleInfo
*module_info
= g_new(LttvModuleInfo
,nb
);
2681 name
= g_ptr_array_new();
2682 /* ask for the module name */
2685 LttvModule
*iter_module
= lttv_library_module_get(library
, i
);
2686 lttv_module_info(iter_module
, &module_info
[i
]);
2688 gchar
*path
= module_info
[i
].name
;
2689 g_ptr_array_add(name
, path
);
2691 module_name
= get_selection((char **)(name
->pdata
), name
->len
,
2692 "Select a module", "Modules");
2693 if(module_name
!= NULL
) {
2695 if(strcmp(module_name
, module_info
[i
].name
) == 0) {
2696 strncpy(module_name_out
, module_name
, PATH_MAX
);
2697 //module = lttv_library_module_get(i);
2703 g_ptr_array_free(name
, TRUE
);
2704 g_free(module_info
);
2706 if(module_name
== NULL
) return;
2709 lttv_module_require(module_name_out
, &error
);
2710 if(error
!= NULL
) g_warning("%s", error
->message
);
2711 else g_info("Load module: %s", module_name_out
);
2718 gchar str
[PATH_MAX
];
2721 GtkFileSelection
* file_selector
=
2722 (GtkFileSelection
*)gtk_file_selection_new("Select a module");
2723 gtk_file_selection_set_filename(file_selector
, load_module_path_alter
);
2724 gtk_file_selection_hide_fileop_buttons(file_selector
);
2727 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
2729 case GTK_RESPONSE_ACCEPT
:
2730 case GTK_RESPONSE_OK
:
2731 dir
= gtk_file_selection_get_selections (file_selector
);
2732 strncpy(str
,dir
[0],PATH_MAX
);
2733 strncpy(remember_plugins_dir
,dir
[0],PATH_MAX
);
2735 /* only keep file name */
2737 str1
= strrchr(str
,'/');
2740 str1
= strrchr(str
,'\\');
2745 if(*str1
== 'l' && *(str1
+1)== 'i' && *(str1
+2)=='b')
2747 remove info after
. */
2751 str2
= strrchr(str2
, '.');
2752 if(str2
!= NULL
) *str2
= '\0';
2754 lttv_module_require(str1
, &error
);
2756 lttv_library_load(str1
, &error
);
2757 if(error
!= NULL
) g_warning(error
->message
);
2758 else g_info("Load library: %s\n", str
);
2760 case GTK_RESPONSE_REJECT
:
2761 case GTK_RESPONSE_CANCEL
:
2763 gtk_widget_destroy((GtkWidget
*)file_selector
);
2775 /* Display all loaded modules, let user to select a module to unload
2776 * by calling lttv_module_unload
2780 on_unload_module_activate (GtkMenuItem
*menuitem
,
2783 GError
*error
= NULL
;
2784 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2786 LttvLibrary
*library
;
2791 name
= g_ptr_array_new();
2792 nb
= lttv_library_number();
2793 LttvLibraryInfo
*lib_info
= g_new(LttvLibraryInfo
,nb
);
2794 /* ask for the library name */
2797 LttvLibrary
*iter_lib
= lttv_library_get(i
);
2798 lttv_library_info(iter_lib
, &lib_info
[i
]);
2800 gchar
*path
= lib_info
[i
].name
;
2801 g_ptr_array_add(name
, path
);
2803 lib_name
= get_selection((char **)(name
->pdata
), name
->len
,
2804 "Select a library", "Libraries");
2805 if(lib_name
!= NULL
) {
2807 if(strcmp(lib_name
, lib_info
[i
].name
) == 0) {
2808 library
= lttv_library_get(i
);
2813 g_ptr_array_free(name
, TRUE
);
2816 if(lib_name
== NULL
) return;
2819 LttvModule
*module
= NULL
;
2821 /* Ask for the module to load : list modules in the selected lib */
2825 nb
= lttv_library_module_number(library
);
2826 LttvModuleInfo
*module_info
= g_new(LttvModuleInfo
,nb
);
2827 name
= g_ptr_array_new();
2828 /* ask for the module name */
2831 LttvModule
*iter_module
= lttv_library_module_get(library
, i
);
2832 lttv_module_info(iter_module
, &module_info
[i
]);
2834 gchar
*path
= module_info
[i
].name
;
2835 if(module_info
[i
].use_count
> 0) g_ptr_array_add(name
, path
);
2837 module_name
= get_selection((char **)(name
->pdata
), name
->len
,
2838 "Select a module", "Modules");
2839 if(module_name
!= NULL
) {
2841 if(strcmp(module_name
, module_info
[i
].name
) == 0) {
2842 module
= lttv_library_module_get(library
, i
);
2848 g_ptr_array_free(name
, TRUE
);
2849 g_free(module_info
);
2851 if(module_name
== NULL
) return;
2854 LttvModuleInfo module_info
;
2855 lttv_module_info(module
, &module_info
);
2856 g_info("Release module: %s\n", module_info
.name
);
2858 lttv_module_release(module
);
2862 /* Display a directory dialogue to let user select a path for library searching
2866 on_add_library_search_path_activate (GtkMenuItem
*menuitem
,
2869 GtkDirSelection
* file_selector
= (GtkDirSelection
*)gtk_dir_selection_new("Select library path");
2873 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2874 if(remember_plugins_dir
[0] != '\0')
2875 gtk_dir_selection_set_filename(file_selector
, remember_plugins_dir
);
2877 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
2879 case GTK_RESPONSE_ACCEPT
:
2880 case GTK_RESPONSE_OK
:
2881 dir
= gtk_dir_selection_get_dir (file_selector
);
2882 strncpy(remember_plugins_dir
,dir
,PATH_MAX
);
2883 strncat(remember_plugins_dir
,"/",PATH_MAX
);
2884 lttv_library_path_add(dir
);
2885 case GTK_RESPONSE_REJECT
:
2886 case GTK_RESPONSE_CANCEL
:
2888 gtk_widget_destroy((GtkWidget
*)file_selector
);
2894 /* Display a directory dialogue to let user select a path for library searching
2898 on_remove_library_search_path_activate (GtkMenuItem
*menuitem
,
2901 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2903 const char *lib_path
;
2908 name
= g_ptr_array_new();
2909 nb
= lttv_library_path_number();
2910 /* ask for the library name */
2913 gchar
*path
= lttv_library_path_get(i
);
2914 g_ptr_array_add(name
, path
);
2916 lib_path
= get_selection((char **)(name
->pdata
), name
->len
,
2917 "Select a library path", "Library paths");
2919 g_ptr_array_free(name
, TRUE
);
2921 if(lib_path
== NULL
) return;
2924 lttv_library_path_remove(lib_path
);
2928 on_color_activate (GtkMenuItem
*menuitem
,
2936 on_save_configuration_activate (GtkMenuItem
*menuitem
,
2939 g_info("Save configuration\n");
2944 on_content_activate (GtkMenuItem
*menuitem
,
2947 g_info("Content\n");
2952 on_about_close_activate (GtkButton
*button
,
2955 GtkWidget
*about_widget
= GTK_WIDGET(user_data
);
2957 gtk_widget_destroy(about_widget
);
2961 on_about_activate (GtkMenuItem
*menuitem
,
2964 MainWindow
*main_window
= get_window_data_struct(GTK_WIDGET(menuitem
));
2965 GtkWidget
*window_widget
= main_window
->mwindow
;
2966 GtkWidget
*about_widget
= gtk_window_new(GTK_WINDOW_TOPLEVEL
);
2967 GtkWindow
*about_window
= GTK_WINDOW(about_widget
);
2968 gint window_width
, window_height
;
2970 gtk_window_set_title(about_window
, "About Linux Trace Toolkit");
2972 gtk_window_set_resizable(about_window
, FALSE
);
2973 gtk_window_set_transient_for(GTK_WINDOW(window_widget
), about_window
);
2974 gtk_window_set_destroy_with_parent(about_window
, TRUE
);
2975 gtk_window_set_modal(about_window
, FALSE
);
2977 /* Put the about window at the center of the screen */
2978 gtk_window_get_size(about_window
, &window_width
, &window_height
);
2979 gtk_window_move (about_window
,
2980 (gdk_screen_width() - window_width
)/2,
2981 (gdk_screen_height() - window_height
)/2);
2983 GtkWidget
*vbox
= gtk_vbox_new(FALSE
, 1);
2985 gtk_container_add(GTK_CONTAINER(about_widget
), vbox
);
2989 GtkWidget
*label1
= gtk_label_new("");
2990 gtk_misc_set_padding(GTK_MISC(label1
), 10, 20);
2991 gtk_label_set_markup(GTK_LABEL(label1
), "\
2992 <big>Linux Trace Toolkit</big>");
2993 gtk_label_set_justify(GTK_LABEL(label1
), GTK_JUSTIFY_CENTER
);
2995 GtkWidget
*label2
= gtk_label_new("");
2996 gtk_misc_set_padding(GTK_MISC(label2
), 10, 20);
2997 gtk_label_set_markup(GTK_LABEL(label2
), "\
3000 Michel Dagenais (New trace format, lttv main)\n\
3001 Mathieu Desnoyers (Directory structure, build with automake/conf,\n\
3002 lttv gui, control flow view, gui cooperative trace reading\n\
3003 scheduler with interruptible foreground and background\n\
3004 computation, detailed event list)\n\
3005 Benoit Des Ligneris, Eric Clement (Cluster adaptation, work in progress)\n\
3006 Xang-Xiu Yang (new trace reading library and converter, lttv gui, \n\
3007 detailed event list and statistics view)\n\
3008 Tom Zanussi (RelayFS)\n\
3010 Strongly inspired from the original Linux Trace Toolkit Visualizer made by\n\
3013 GtkWidget
*label3
= gtk_label_new("");
3014 gtk_label_set_markup(GTK_LABEL(label3
), "\
3015 Linux Trace Toolkit Viewer, Copyright (C) 2004\n\
3017 Mathieu Desnoyers\n\
3019 Linux Trace Toolkit comes with ABSOLUTELY NO WARRANTY.\n\
3020 This is free software, and you are welcome to redistribute it\n\
3021 under certain conditions. See COPYING for details.");
3022 gtk_misc_set_padding(GTK_MISC(label3
), 10, 20);
3024 gtk_box_pack_start_defaults(GTK_BOX(vbox
), label1
);
3025 gtk_box_pack_start_defaults(GTK_BOX(vbox
), label2
);
3026 gtk_box_pack_start_defaults(GTK_BOX(vbox
), label3
);
3028 GtkWidget
*hbox
= gtk_hbox_new(TRUE
, 0);
3029 gtk_box_pack_end(GTK_BOX(vbox
), hbox
, FALSE
, FALSE
, 0);
3030 GtkWidget
*close_button
= gtk_button_new_with_mnemonic("_Close");
3031 gtk_box_pack_end(GTK_BOX(hbox
), close_button
, FALSE
, FALSE
, 0);
3032 gtk_container_set_border_width(GTK_CONTAINER(close_button
), 20);
3034 g_signal_connect(G_OBJECT(close_button
), "clicked",
3035 G_CALLBACK(on_about_close_activate
),
3036 (gpointer
)about_widget
);
3038 gtk_widget_show_all(about_widget
);
3043 on_button_new_clicked (GtkButton
*button
,
3046 create_new_window((GtkWidget
*)button
, user_data
, TRUE
);
3050 on_button_new_tab_clicked (GtkButton
*button
,
3053 create_new_tab((GtkWidget
*)button
, user_data
);
3057 on_button_open_clicked (GtkButton
*button
,
3060 open_traceset((GtkWidget
*)button
, user_data
);
3065 on_button_add_trace_clicked (GtkButton
*button
,
3068 add_trace((GtkWidget
*)button
, user_data
);
3073 on_button_remove_trace_clicked (GtkButton
*button
,
3076 remove_trace((GtkWidget
*)button
, user_data
);
3080 on_button_redraw_clicked (GtkButton
*button
,
3083 redraw((GtkWidget
*)button
, user_data
);
3087 on_button_continue_processing_clicked (GtkButton
*button
,
3090 continue_processing((GtkWidget
*)button
, user_data
);
3094 on_button_stop_processing_clicked (GtkButton
*button
,
3097 stop_processing((GtkWidget
*)button
, user_data
);
3103 on_button_save_clicked (GtkButton
*button
,
3106 save((GtkWidget
*)button
, user_data
);
3111 on_button_save_as_clicked (GtkButton
*button
,
3114 save_as((GtkWidget
*)button
, user_data
);
3119 on_button_zoom_in_clicked (GtkButton
*button
,
3122 zoom_in((GtkWidget
*)button
, user_data
);
3127 on_button_zoom_out_clicked (GtkButton
*button
,
3130 zoom_out((GtkWidget
*)button
, user_data
);
3135 on_button_zoom_extended_clicked (GtkButton
*button
,
3138 zoom_extended((GtkWidget
*)button
, user_data
);
3143 on_button_go_to_time_clicked (GtkButton
*button
,
3146 go_to_time((GtkWidget
*)button
, user_data
);
3151 on_button_show_time_frame_clicked (GtkButton
*button
,
3154 show_time_frame((GtkWidget
*)button
, user_data
);
3159 on_button_move_up_clicked (GtkButton
*button
,
3162 move_up_viewer((GtkWidget
*)button
, user_data
);
3167 on_button_move_down_clicked (GtkButton
*button
,
3170 move_down_viewer((GtkWidget
*)button
, user_data
);
3175 on_button_delete_viewer_clicked (GtkButton
*button
,
3178 delete_viewer((GtkWidget
*)button
, user_data
);
3182 on_MWindow_destroy (GtkWidget
*widget
,
3185 MainWindow
*main_window
= get_window_data_struct(widget
);
3186 LttvIAttribute
*attributes
= main_window
->attributes
;
3187 LttvAttributeValue value
;
3189 //This is unnecessary, since widgets will be destroyed
3190 //by the main window widget anyway.
3191 //remove_all_menu_toolbar_constructors(main_window, NULL);
3193 g_assert(lttv_iattribute_find_by_path(attributes
,
3194 "viewers/menu", LTTV_POINTER
, &value
));
3195 lttv_menus_destroy((LttvMenus
*)*(value
.v_pointer
));
3197 g_assert(lttv_iattribute_find_by_path(attributes
,
3198 "viewers/toolbar", LTTV_POINTER
, &value
));
3199 lttv_toolbars_destroy((LttvToolbars
*)*(value
.v_pointer
));
3201 g_object_unref(main_window
->attributes
);
3202 g_main_window_list
= g_slist_remove(g_main_window_list
, main_window
);
3204 g_info("There are now : %d windows\n",g_slist_length(g_main_window_list
));
3205 if(g_slist_length(g_main_window_list
) == 0)
3210 on_MWindow_configure (GtkWidget
*widget
,
3211 GdkEventConfigure
*event
,
3214 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)widget
);
3216 // MD : removed time width modification upon resizing of the main window.
3217 // The viewers will redraw themselves completely, without time interval
3220 if(mw_data->window_width){
3221 time_span = LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context)->Time_Span ;
3222 time_win = tab->time_window;
3223 ratio = width / mw_data->window_width;
3224 tab->time_window.time_width = ltt_time_mul(time_win.time_width,ratio);
3225 time = ltt_time_sub(time_span->endTime, time_win.start_time);
3226 if(ltt_time_compare(time, tab->time_window.time_width) < 0){
3227 tab->time_window.time_width = time;
3233 mw_data->window_width = (int)width;
3242 on_MNotebook_switch_page (GtkNotebook
*notebook
,
3243 GtkNotebookPage
*page
,
3251 void time_change_manager (Tab
*tab
,
3252 TimeWindow new_time_window
)
3254 /* Only one source of time change */
3255 if(tab
->time_manager_lock
== TRUE
) return;
3257 tab
->time_manager_lock
= TRUE
;
3259 LttvTracesetContext
*tsc
= LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3260 TimeInterval time_span
= tsc
->time_span
;
3261 LttTime start_time
= new_time_window
.start_time
;
3262 LttTime end_time
= new_time_window
.end_time
;
3265 GtkAdjustment
*adjustment
= gtk_range_get_adjustment(GTK_RANGE(tab
->scrollbar
));
3266 LttTime upper
= ltt_time_sub(time_span
.end_time
, time_span
.start_time
);
3268 gtk_range_set_increments(GTK_RANGE(tab
->scrollbar
),
3269 ltt_time_to_double(new_time_window
.time_width
)
3270 / SCROLL_STEP_PER_PAGE
3271 * NANOSECONDS_PER_SECOND
, /* step increment */
3272 ltt_time_to_double(new_time_window
.time_width
)
3273 * NANOSECONDS_PER_SECOND
); /* page increment */
3274 gtk_range_set_range(GTK_RANGE(tab
->scrollbar
),
3276 ltt_time_to_double(upper
)
3277 * NANOSECONDS_PER_SECOND
); /* upper */
3279 g_object_set(G_OBJECT(adjustment
),
3283 ltt_time_to_double(upper
), /* upper */
3285 new_time_window
.time_width_double
3286 / SCROLL_STEP_PER_PAGE
, /* step increment */
3288 new_time_window
.time_width_double
,
3289 /* page increment */
3291 new_time_window
.time_width_double
, /* page size */
3293 gtk_adjustment_changed(adjustment
);
3295 // g_object_set(G_OBJECT(adjustment),
3297 // ltt_time_to_double(
3298 // ltt_time_sub(start_time, time_span.start_time))
3301 //gtk_adjustment_value_changed(adjustment);
3302 gtk_range_set_value(GTK_RANGE(tab
->scrollbar
),
3304 ltt_time_sub(start_time
, time_span
.start_time
)) /* value */);
3306 /* set the time bar. */
3308 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry1
),
3309 (double)time_span
.start_time
.tv_sec
,
3310 (double)time_span
.end_time
.tv_sec
);
3311 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry1
),
3312 (double)start_time
.tv_sec
);
3314 /* start nanoseconds */
3315 if(start_time
.tv_sec
== time_span
.start_time
.tv_sec
) {
3316 /* can be both beginning and end at the same time. */
3317 if(start_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3318 /* If we are at the end, max nsec to end.. -1 (not zero length) */
3319 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry2
),
3320 (double)time_span
.start_time
.tv_nsec
,
3321 (double)time_span
.end_time
.tv_nsec
-1);
3323 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry2
),
3324 (double)time_span
.start_time
.tv_nsec
,
3325 (double)NANOSECONDS_PER_SECOND
-1);
3327 } else if(start_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3328 /* If we are at the end, max nsec to end.. -1 (not zero length) */
3329 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry2
),
3331 (double)time_span
.end_time
.tv_nsec
-1);
3332 } else /* anywhere else */
3333 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry2
),
3335 (double)NANOSECONDS_PER_SECOND
-1);
3336 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry2
),
3337 (double)start_time
.tv_nsec
);
3340 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry3
),
3341 (double)time_span
.start_time
.tv_sec
,
3342 (double)time_span
.end_time
.tv_sec
);
3343 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry3
),
3344 (double)end_time
.tv_sec
);
3346 /* end nanoseconds */
3347 if(end_time
.tv_sec
== time_span
.start_time
.tv_sec
) {
3348 /* can be both beginning and end at the same time. */
3349 if(end_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3350 /* If we are at the end, max nsec to end.. */
3351 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry4
),
3352 (double)time_span
.start_time
.tv_nsec
+1,
3353 (double)time_span
.end_time
.tv_nsec
);
3355 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry4
),
3356 (double)time_span
.start_time
.tv_nsec
+1,
3357 (double)NANOSECONDS_PER_SECOND
-1);
3360 else if(end_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3361 /* If we are at the end, max nsec to end.. */
3362 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry4
),
3364 (double)time_span
.end_time
.tv_nsec
);
3366 else /* anywhere else */
3367 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry4
),
3369 (double)NANOSECONDS_PER_SECOND
-1);
3370 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry4
),
3371 (double)end_time
.tv_nsec
);
3373 /* call viewer hooks for new time window */
3374 set_time_window(tab
, &new_time_window
);
3376 tab
->time_manager_lock
= FALSE
;
3380 /* value changed for frame start s
3382 * Check time span : if ns is out of range, clip it the nearest good value.
3385 on_MEntry1_value_changed (GtkSpinButton
*spinbutton
,
3388 Tab
*tab
=(Tab
*)user_data
;
3389 LttvTracesetContext
* tsc
=
3390 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3391 TimeInterval time_span
= tsc
->time_span
;
3392 gint value
= gtk_spin_button_get_value_as_int(spinbutton
);
3394 TimeWindow new_time_window
= tab
->time_window
;
3396 LttTime end_time
= new_time_window
.end_time
;
3398 new_time_window
.start_time
.tv_sec
= value
;
3400 /* start nanoseconds */
3401 if(new_time_window
.start_time
.tv_sec
== time_span
.start_time
.tv_sec
) {
3402 if(new_time_window
.start_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3403 if(new_time_window
.start_time
.tv_nsec
> time_span
.end_time
.tv_nsec
)
3404 new_time_window
.start_time
.tv_nsec
= time_span
.end_time
.tv_nsec
-1;
3405 if(new_time_window
.start_time
.tv_nsec
< time_span
.start_time
.tv_nsec
)
3406 new_time_window
.start_time
.tv_nsec
= time_span
.start_time
.tv_nsec
;
3408 if(new_time_window
.start_time
.tv_nsec
< time_span
.start_time
.tv_nsec
)
3409 new_time_window
.start_time
.tv_nsec
= time_span
.start_time
.tv_nsec
;
3412 else if(new_time_window
.start_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3413 if(new_time_window
.start_time
.tv_nsec
> time_span
.end_time
.tv_nsec
)
3414 new_time_window
.start_time
.tv_nsec
= time_span
.end_time
.tv_nsec
-1;
3417 if(ltt_time_compare(new_time_window
.start_time
, end_time
) >= 0) {
3418 /* Then, we must push back end time : keep the same time width
3419 * if possible, else end traceset time */
3420 end_time
= LTT_TIME_MIN(ltt_time_add(new_time_window
.start_time
,
3421 new_time_window
.time_width
),
3422 time_span
.end_time
);
3425 /* Fix the time width to fit start time and end time */
3426 new_time_window
.time_width
= ltt_time_sub(end_time
,
3427 new_time_window
.start_time
);
3428 new_time_window
.time_width_double
=
3429 ltt_time_to_double(new_time_window
.time_width
);
3431 new_time_window
.end_time
= end_time
;
3433 time_change_manager(tab
, new_time_window
);
3438 on_MEntry2_value_changed (GtkSpinButton
*spinbutton
,
3441 Tab
*tab
=(Tab
*)user_data
;
3442 LttvTracesetContext
* tsc
=
3443 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3444 TimeInterval time_span
= tsc
->time_span
;
3445 gint value
= gtk_spin_button_get_value_as_int(spinbutton
);
3447 TimeWindow new_time_window
= tab
->time_window
;
3449 LttTime end_time
= new_time_window
.end_time
;
3451 new_time_window
.start_time
.tv_nsec
= value
;
3453 if(ltt_time_compare(new_time_window
.start_time
, end_time
) >= 0) {
3454 /* Then, we must push back end time : keep the same time width
3455 * if possible, else end traceset time */
3456 end_time
= LTT_TIME_MIN(ltt_time_add(new_time_window
.start_time
,
3457 new_time_window
.time_width
),
3458 time_span
.end_time
);
3461 /* Fix the time width to fit start time and end time */
3462 new_time_window
.time_width
= ltt_time_sub(end_time
,
3463 new_time_window
.start_time
);
3464 new_time_window
.time_width_double
=
3465 ltt_time_to_double(new_time_window
.time_width
);
3467 new_time_window
.end_time
= end_time
;
3469 time_change_manager(tab
, new_time_window
);
3474 on_MEntry3_value_changed (GtkSpinButton
*spinbutton
,
3477 Tab
*tab
=(Tab
*)user_data
;
3478 LttvTracesetContext
* tsc
=
3479 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3480 TimeInterval time_span
= tsc
->time_span
;
3481 gint value
= gtk_spin_button_get_value_as_int(spinbutton
);
3483 TimeWindow new_time_window
= tab
->time_window
;
3485 LttTime end_time
= new_time_window
.end_time
;
3487 end_time
.tv_sec
= value
;
3489 /* end nanoseconds */
3490 if(end_time
.tv_sec
== time_span
.start_time
.tv_sec
) {
3491 if(end_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3492 if(end_time
.tv_nsec
> time_span
.end_time
.tv_nsec
)
3493 end_time
.tv_nsec
= time_span
.end_time
.tv_nsec
;
3494 if(end_time
.tv_nsec
< time_span
.start_time
.tv_nsec
)
3495 end_time
.tv_nsec
= time_span
.start_time
.tv_nsec
+1;
3497 if(end_time
.tv_nsec
< time_span
.start_time
.tv_nsec
)
3498 end_time
.tv_nsec
= time_span
.start_time
.tv_nsec
+1;
3501 else if(end_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3502 if(end_time
.tv_nsec
> time_span
.end_time
.tv_nsec
)
3503 end_time
.tv_nsec
= time_span
.end_time
.tv_nsec
;
3506 if(ltt_time_compare(new_time_window
.start_time
, end_time
) >= 0) {
3507 /* Then, we must push front start time : keep the same time width
3508 * if possible, else end traceset time */
3509 new_time_window
.start_time
= LTT_TIME_MAX(
3510 ltt_time_sub(end_time
,
3511 new_time_window
.time_width
),
3512 time_span
.start_time
);
3515 /* Fix the time width to fit start time and end time */
3516 new_time_window
.time_width
= ltt_time_sub(end_time
,
3517 new_time_window
.start_time
);
3518 new_time_window
.time_width_double
=
3519 ltt_time_to_double(new_time_window
.time_width
);
3521 new_time_window
.end_time
= end_time
;
3523 time_change_manager(tab
, new_time_window
);
3528 on_MEntry4_value_changed (GtkSpinButton
*spinbutton
,
3531 Tab
*tab
=(Tab
*)user_data
;
3532 LttvTracesetContext
* tsc
=
3533 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3534 TimeInterval time_span
= tsc
->time_span
;
3535 gint value
= gtk_spin_button_get_value_as_int(spinbutton
);
3537 TimeWindow new_time_window
= tab
->time_window
;
3539 LttTime end_time
= new_time_window
.end_time
;
3541 end_time
.tv_nsec
= value
;
3543 if(ltt_time_compare(new_time_window
.start_time
, end_time
) >= 0) {
3544 /* Then, we must push front start time : keep the same time width
3545 * if possible, else end traceset time */
3546 new_time_window
.start_time
= LTT_TIME_MAX(
3547 ltt_time_sub(end_time
,
3548 new_time_window
.time_width
),
3549 time_span
.start_time
);
3552 /* Fix the time width to fit start time and end time */
3553 new_time_window
.time_width
= ltt_time_sub(end_time
,
3554 new_time_window
.start_time
);
3555 new_time_window
.time_width_double
=
3556 ltt_time_to_double(new_time_window
.time_width
);
3557 new_time_window
.end_time
= end_time
;
3559 time_change_manager(tab
, new_time_window
);
3564 void current_time_change_manager (Tab
*tab
,
3565 LttTime new_current_time
)
3567 /* Only one source of time change */
3568 if(tab
->current_time_manager_lock
== TRUE
) return;
3570 tab
->current_time_manager_lock
= TRUE
;
3572 LttvTracesetContext
*tsc
= LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3573 TimeInterval time_span
= tsc
->time_span
;
3575 /* current seconds */
3576 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry5
),
3577 (double)time_span
.start_time
.tv_sec
,
3578 (double)time_span
.end_time
.tv_sec
);
3579 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry5
),
3580 (double)new_current_time
.tv_sec
);
3583 /* start nanoseconds */
3584 if(new_current_time
.tv_sec
== time_span
.start_time
.tv_sec
) {
3585 /* can be both beginning and end at the same time. */
3586 if(new_current_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3587 /* If we are at the end, max nsec to end.. */
3588 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry6
),
3589 (double)time_span
.start_time
.tv_nsec
,
3590 (double)time_span
.end_time
.tv_nsec
);
3592 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry6
),
3593 (double)time_span
.start_time
.tv_nsec
,
3594 (double)NANOSECONDS_PER_SECOND
-1);
3596 } else if(new_current_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3597 /* If we are at the end, max nsec to end.. */
3598 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry6
),
3600 (double)time_span
.end_time
.tv_nsec
);
3601 } else /* anywhere else */
3602 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry6
),
3604 (double)NANOSECONDS_PER_SECOND
-1);
3606 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry6
),
3607 (double)new_current_time
.tv_nsec
);
3609 set_current_time(tab
, &new_current_time
);
3611 tab
->current_time_manager_lock
= FALSE
;
3615 on_MEntry5_value_changed (GtkSpinButton
*spinbutton
,
3618 Tab
*tab
= (Tab
*)user_data
;
3619 LttvTracesetContext
* tsc
=
3620 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3621 TimeInterval time_span
= tsc
->time_span
;
3622 gint value
= gtk_spin_button_get_value_as_int(spinbutton
);
3623 LttTime new_current_time
= tab
->current_time
;
3624 new_current_time
.tv_sec
= value
;
3626 /* current nanoseconds */
3627 if(new_current_time
.tv_sec
== time_span
.start_time
.tv_sec
) {
3628 if(new_current_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3629 if(new_current_time
.tv_nsec
> time_span
.end_time
.tv_nsec
)
3630 new_current_time
.tv_nsec
= time_span
.end_time
.tv_nsec
;
3631 if(new_current_time
.tv_nsec
< time_span
.start_time
.tv_nsec
)
3632 new_current_time
.tv_nsec
= time_span
.start_time
.tv_nsec
;
3634 if(new_current_time
.tv_nsec
< time_span
.start_time
.tv_nsec
)
3635 new_current_time
.tv_nsec
= time_span
.start_time
.tv_nsec
;
3638 else if(new_current_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3639 if(new_current_time
.tv_nsec
> time_span
.end_time
.tv_nsec
)
3640 new_current_time
.tv_nsec
= time_span
.end_time
.tv_nsec
;
3643 current_time_change_manager(tab
, new_current_time
);
3647 on_MEntry6_value_changed (GtkSpinButton
*spinbutton
,
3650 Tab
*tab
= (Tab
*)user_data
;
3651 gint value
= gtk_spin_button_get_value_as_int(spinbutton
);
3652 LttTime new_current_time
= tab
->current_time
;
3653 new_current_time
.tv_nsec
= value
;
3655 current_time_change_manager(tab
, new_current_time
);
3659 void scroll_value_changed_cb(GtkWidget
*scrollbar
,
3662 Tab
*tab
= (Tab
*)user_data
;
3663 TimeWindow new_time_window
;
3665 GtkAdjustment
*adjust
= gtk_range_get_adjustment(GTK_RANGE(scrollbar
));
3666 gdouble value
= gtk_adjustment_get_value(adjust
);
3667 // gdouble upper, lower, ratio, page_size;
3669 LttvTracesetContext
* tsc
=
3670 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3671 TimeInterval time_span
= tsc
->time_span
;
3673 time
= ltt_time_add(ltt_time_from_double(value
),
3674 time_span
.start_time
);
3676 new_time_window
.start_time
= time
;
3678 page_size
= adjust
->page_size
;
3680 new_time_window
.time_width
=
3681 ltt_time_from_double(page_size
);
3683 new_time_window
.time_width_double
=
3686 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
3687 new_time_window
.time_width
);
3690 time_change_manager(tab
, new_time_window
);
3692 //time_window = tab->time_window;
3694 lower
= adjust
->lower
;
3695 upper
= adjust
->upper
;
3696 ratio
= (value
- lower
) / (upper
- lower
);
3697 g_info("lower %lu, upper %lu, value %lu, ratio %lu", lower
, upper
, value
, ratio
);
3699 //time = ltt_time_sub(time_span->end_time, time_span->start_time);
3700 //time = ltt_time_mul(time, (float)ratio);
3701 //time = ltt_time_add(time_span->start_time, time);
3702 time
= ltt_time_add(ltt_time_from_double(value
),
3703 time_span
.start_time
);
3705 time_window
.start_time
= time
;
3707 page_size
= adjust
->page_size
;
3709 time_window
.time_width
=
3710 ltt_time_from_double(page_size
);
3711 //time = ltt_time_sub(time_span.end_time, time);
3712 //if(ltt_time_compare(time,time_window.time_width) < 0){
3713 // time_window.time_width = time;
3716 /* call viewer hooks for new time window */
3717 set_time_window(tab
, &time_window
);
3722 /* Display a dialogue showing all eventtypes and traces, let user to select the interested
3723 * eventtypes, tracefiles and traces (filter)
3726 /* Select a trace which will be removed from traceset
3729 char * get_remove_trace(char ** all_trace_name
, int nb_trace
)
3731 return get_selection(all_trace_name
, nb_trace
,
3732 "Select a trace", "Trace pathname");
3736 /* Select a module which will be loaded
3739 char * get_load_module(char ** load_module_name
, int nb_module
)
3741 return get_selection(load_module_name
, nb_module
,
3742 "Select a module to load", "Module name");
3748 /* Select a module which will be unloaded
3751 char * get_unload_module(char ** loaded_module_name
, int nb_module
)
3753 return get_selection(loaded_module_name
, nb_module
,
3754 "Select a module to unload", "Module name");
3758 /* Display a dialogue which shows all selectable items, let user to
3759 * select one of them
3762 char * get_selection(char ** loaded_module_name
, int nb_module
,
3763 char *title
, char * column_title
)
3765 GtkWidget
* dialogue
;
3766 GtkWidget
* scroll_win
;
3768 GtkListStore
* store
;
3769 GtkTreeViewColumn
* column
;
3770 GtkCellRenderer
* renderer
;
3771 GtkTreeSelection
* select
;
3774 char * unload_module_name
= NULL
;
3776 dialogue
= gtk_dialog_new_with_buttons(title
,
3779 GTK_STOCK_OK
,GTK_RESPONSE_ACCEPT
,
3780 GTK_STOCK_CANCEL
,GTK_RESPONSE_REJECT
,
3782 gtk_window_set_default_size((GtkWindow
*)dialogue
, 500, 200);
3784 scroll_win
= gtk_scrolled_window_new (NULL
, NULL
);
3785 gtk_widget_show ( scroll_win
);
3786 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll_win
),
3787 GTK_POLICY_AUTOMATIC
, GTK_POLICY_AUTOMATIC
);
3789 store
= gtk_list_store_new (N_COLUMNS
,G_TYPE_STRING
);
3790 tree
= gtk_tree_view_new_with_model(GTK_TREE_MODEL (store
));
3791 gtk_widget_show ( tree
);
3792 g_object_unref (G_OBJECT (store
));
3794 renderer
= gtk_cell_renderer_text_new ();
3795 column
= gtk_tree_view_column_new_with_attributes (column_title
,
3797 "text", MODULE_COLUMN
,
3799 gtk_tree_view_column_set_alignment (column
, 0.5);
3800 gtk_tree_view_column_set_fixed_width (column
, 150);
3801 gtk_tree_view_append_column (GTK_TREE_VIEW (tree
), column
);
3803 select
= gtk_tree_view_get_selection (GTK_TREE_VIEW (tree
));
3804 gtk_tree_selection_set_mode (select
, GTK_SELECTION_SINGLE
);
3806 gtk_container_add (GTK_CONTAINER (scroll_win
), tree
);
3808 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialogue
)->vbox
), scroll_win
,TRUE
, TRUE
,0);
3810 for(i
=0;i
<nb_module
;i
++){
3811 gtk_list_store_append (store
, &iter
);
3812 gtk_list_store_set (store
, &iter
, MODULE_COLUMN
,loaded_module_name
[i
],-1);
3815 id
= gtk_dialog_run(GTK_DIALOG(dialogue
));
3816 GtkTreeModel
**store_model
= (GtkTreeModel
*)store
;
3818 case GTK_RESPONSE_ACCEPT
:
3819 case GTK_RESPONSE_OK
:
3820 if (gtk_tree_selection_get_selected (select
, store_model
, &iter
)){
3821 gtk_tree_model_get ((GtkTreeModel
*)store
, &iter
, MODULE_COLUMN
, &unload_module_name
, -1);
3823 case GTK_RESPONSE_REJECT
:
3824 case GTK_RESPONSE_CANCEL
:
3826 gtk_widget_destroy(dialogue
);
3830 return unload_module_name
;
3834 /* Insert all menu entry and tool buttons into this main window
3839 void add_all_menu_toolbar_constructors(MainWindow
* mw
, gpointer user_data
)
3843 lttvwindow_viewer_constructor constructor
;
3844 LttvMenus
* global_menu
, * instance_menu
;
3845 LttvToolbars
* global_toolbar
, * instance_toolbar
;
3846 LttvMenuClosure
*menu_item
;
3847 LttvToolbarClosure
*toolbar_item
;
3848 LttvAttributeValue value
;
3849 LttvIAttribute
*global_attributes
= LTTV_IATTRIBUTE(lttv_global_attributes());
3850 LttvIAttribute
*attributes
= mw
->attributes
;
3851 GtkWidget
* tool_menu_title_menu
, *new_widget
, *pixmap
;
3853 g_assert(lttv_iattribute_find_by_path(global_attributes
,
3854 "viewers/menu", LTTV_POINTER
, &value
));
3855 if(*(value
.v_pointer
) == NULL
)
3856 *(value
.v_pointer
) = lttv_menus_new();
3857 global_menu
= (LttvMenus
*)*(value
.v_pointer
);
3859 g_assert(lttv_iattribute_find_by_path(attributes
,
3860 "viewers/menu", LTTV_POINTER
, &value
));
3861 if(*(value
.v_pointer
) == NULL
)
3862 *(value
.v_pointer
) = lttv_menus_new();
3863 instance_menu
= (LttvMenus
*)*(value
.v_pointer
);
3867 g_assert(lttv_iattribute_find_by_path(global_attributes
,
3868 "viewers/toolbar", LTTV_POINTER
, &value
));
3869 if(*(value
.v_pointer
) == NULL
)
3870 *(value
.v_pointer
) = lttv_toolbars_new();
3871 global_toolbar
= (LttvToolbars
*)*(value
.v_pointer
);
3873 g_assert(lttv_iattribute_find_by_path(attributes
,
3874 "viewers/toolbar", LTTV_POINTER
, &value
));
3875 if(*(value
.v_pointer
) == NULL
)
3876 *(value
.v_pointer
) = lttv_toolbars_new();
3877 instance_toolbar
= (LttvToolbars
*)*(value
.v_pointer
);
3879 /* Add missing menu entries to window instance */
3880 for(i
=0;i
<global_menu
->len
;i
++) {
3881 menu_item
= &g_array_index(global_menu
, LttvMenuClosure
, i
);
3883 //add menu_item to window instance;
3884 constructor
= menu_item
->con
;
3885 tool_menu_title_menu
= lookup_widget(mw
->mwindow
,"ToolMenuTitle_menu");
3887 gtk_menu_item_new_with_mnemonic (menu_item
->menu_text
);
3888 gtk_container_add (GTK_CONTAINER (tool_menu_title_menu
),
3890 g_signal_connect ((gpointer
) new_widget
, "activate",
3891 G_CALLBACK (insert_viewer_wrap
),
3893 gtk_widget_show (new_widget
);
3894 lttv_menus_add(instance_menu
, menu_item
->con
,
3895 menu_item
->menu_path
,
3896 menu_item
->menu_text
,
3901 /* Add missing toolbar entries to window instance */
3902 for(i
=0;i
<global_toolbar
->len
;i
++) {
3903 toolbar_item
= &g_array_index(global_toolbar
, LttvToolbarClosure
, i
);
3905 //add toolbar_item to window instance;
3906 constructor
= toolbar_item
->con
;
3907 tool_menu_title_menu
= lookup_widget(mw
->mwindow
,"MToolbar1");
3908 pixbuf
= gdk_pixbuf_new_from_xpm_data((const char**)toolbar_item
->pixmap
);
3909 pixmap
= gtk_image_new_from_pixbuf(pixbuf
);
3911 gtk_toolbar_append_element (GTK_TOOLBAR (tool_menu_title_menu
),
3912 GTK_TOOLBAR_CHILD_BUTTON
,
3915 toolbar_item
->tooltip
, NULL
,
3916 pixmap
, NULL
, NULL
);
3917 gtk_label_set_use_underline(
3918 GTK_LABEL (((GtkToolbarChild
*) (
3919 g_list_last (GTK_TOOLBAR
3920 (tool_menu_title_menu
)->children
)->data
))->label
),
3922 gtk_container_set_border_width (GTK_CONTAINER (new_widget
), 1);
3923 g_signal_connect ((gpointer
) new_widget
,
3925 G_CALLBACK (insert_viewer_wrap
),
3927 gtk_widget_show (new_widget
);
3929 lttv_toolbars_add(instance_toolbar
, toolbar_item
->con
,
3930 toolbar_item
->tooltip
,
3931 toolbar_item
->pixmap
,
3939 /* Create a main window
3942 void construct_main_window(MainWindow
* parent
)
3944 g_debug("construct_main_window()");
3945 GtkWidget
* new_window
; /* New generated main window */
3946 MainWindow
* new_m_window
;/* New main window structure */
3947 GtkNotebook
* notebook
;
3948 LttvIAttribute
*attributes
=
3949 LTTV_IATTRIBUTE(g_object_new(LTTV_ATTRIBUTE_TYPE
, NULL
));
3950 LttvAttributeValue value
;
3953 new_m_window
= g_new(MainWindow
, 1);
3955 // Add the object's information to the module's array
3956 g_main_window_list
= g_slist_append(g_main_window_list
, new_m_window
);
3958 new_window
= create_MWindow();
3959 gtk_widget_show (new_window
);
3961 new_m_window
->mwindow
= new_window
;
3962 new_m_window
->attributes
= attributes
;
3964 g_assert(lttv_iattribute_find_by_path(attributes
,
3965 "viewers/menu", LTTV_POINTER
, &value
));
3966 *(value
.v_pointer
) = lttv_menus_new();
3968 g_assert(lttv_iattribute_find_by_path(attributes
,
3969 "viewers/toolbar", LTTV_POINTER
, &value
));
3970 *(value
.v_pointer
) = lttv_toolbars_new();
3972 add_all_menu_toolbar_constructors(new_m_window
, NULL
);
3974 g_object_set_data_full(G_OBJECT(new_window
),
3976 (gpointer
)new_m_window
,
3977 (GDestroyNotify
)g_free
);
3978 //create a default tab
3979 notebook
= (GtkNotebook
*)lookup_widget(new_m_window
->mwindow
, "MNotebook");
3980 if(notebook
== NULL
){
3981 g_info("Notebook does not exist\n");
3984 //gtk_notebook_popup_enable (GTK_NOTEBOOK(notebook));
3985 //for now there is no name field in LttvTraceset structure
3986 //Use "Traceset" as the label for the default tab
3988 GtkWidget
* parent_notebook
= lookup_widget(parent
->mwindow
, "MNotebook");
3989 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(parent_notebook
),
3990 gtk_notebook_get_current_page(GTK_NOTEBOOK(parent_notebook
)));
3996 parent_tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
3998 new_tab
= create_tab(new_m_window
, parent_tab
, notebook
, "Traceset");
4000 new_tab
= create_tab(new_m_window
, NULL
, notebook
, "Traceset");
4001 /* First window, use command line trace */
4002 if(g_init_trace
!= NULL
){
4003 lttvwindow_add_trace(new_tab
,
4007 LttvTraceset
*traceset
= new_tab
->traceset_info
->traceset
;
4008 SetTraceset(new_tab
, traceset
);
4010 /* Insert default viewers */
4012 LttvAttributeType type
;
4013 LttvAttributeName name
;
4014 LttvAttributeValue value
;
4015 LttvAttribute
*attribute
;
4017 LttvIAttribute
*attributes_global
=
4018 LTTV_IATTRIBUTE(lttv_global_attributes());
4020 g_assert(attribute
=
4021 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
4022 LTTV_IATTRIBUTE(attributes_global
),
4023 LTTV_VIEWER_CONSTRUCTORS
)));
4025 name
= g_quark_from_string("guievents");
4026 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
4028 if(type
== LTTV_POINTER
) {
4029 lttvwindow_viewer_constructor viewer_constructor
=
4030 (lttvwindow_viewer_constructor
)*value
.v_pointer
;
4031 insert_viewer(new_window
, viewer_constructor
);
4034 name
= g_quark_from_string("guicontrolflow");
4035 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
4037 if(type
== LTTV_POINTER
) {
4038 lttvwindow_viewer_constructor viewer_constructor
=
4039 (lttvwindow_viewer_constructor
)*value
.v_pointer
;
4040 insert_viewer(new_window
, viewer_constructor
);
4043 name
= g_quark_from_string("guistatistics");
4044 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
4046 if(type
== LTTV_POINTER
) {
4047 lttvwindow_viewer_constructor viewer_constructor
=
4048 (lttvwindow_viewer_constructor
)*value
.v_pointer
;
4049 insert_viewer(new_window
, viewer_constructor
);
4055 g_info("There are now : %d windows\n",g_slist_length(g_main_window_list
));
4059 /* Free the memory occupied by a tab structure
4063 void tab_destructor(Tab
* tab
)
4065 int i
, nb
, ref_count
;
4068 gtk_object_destroy(GTK_OBJECT(tab
->tooltips
));
4071 g_object_unref(tab
->attributes
);
4073 if(tab
->interrupted_state
)
4074 g_object_unref(tab
->interrupted_state
);
4077 if(tab
->traceset_info
->traceset_context
!= NULL
){
4078 //remove state update hooks
4079 lttv_state_remove_event_hooks(
4080 (LttvTracesetState
*)tab
->traceset_info
->
4082 lttv_context_fini(LTTV_TRACESET_CONTEXT(tab
->traceset_info
->
4084 g_object_unref(tab
->traceset_info
->traceset_context
);
4086 if(tab
->traceset_info
->traceset
!= NULL
) {
4087 nb
= lttv_traceset_number(tab
->traceset_info
->traceset
);
4088 for(i
= 0 ; i
< nb
; i
++) {
4089 trace
= lttv_traceset_get(tab
->traceset_info
->traceset
, i
);
4090 ref_count
= lttv_trace_get_ref_number(trace
);
4092 ltt_trace_close(lttv_trace(trace
));
4096 lttv_filter_destroy(tab
->filter
);
4097 lttv_traceset_destroy(tab
->traceset_info
->traceset
);
4098 /* Remove the idle events requests processing function of the tab */
4099 g_idle_remove_by_data(tab
);
4101 g_slist_free(tab
->events_requests
);
4102 g_free(tab
->traceset_info
);
4107 /* Create a tab and insert it into the current main window
4110 Tab
* create_tab(MainWindow
* mw
, Tab
*copy_tab
,
4111 GtkNotebook
* notebook
, char * label
)
4116 //create a new tab data structure
4119 //construct and initialize the traceset_info
4120 tab
->traceset_info
= g_new(TracesetInfo
,1);
4123 tab
->traceset_info
->traceset
=
4124 lttv_traceset_copy(copy_tab
->traceset_info
->traceset
);
4126 /* Copy the previous tab's filter */
4127 /* We can clone the filter, as we copy the trace set also */
4128 /* The filter must always be in sync with the trace set */
4129 tab
->filter
= lttv_filter_clone(copy_tab
->filter
);
4132 tab
->traceset_info
->traceset
= lttv_traceset_new();
4137 lttv_attribute_write_xml(
4138 lttv_traceset_attribute(tab
->traceset_info
->traceset
),
4144 tab
->time_manager_lock
= FALSE
;
4145 tab
->current_time_manager_lock
= FALSE
;
4147 //FIXME copy not implemented in lower level
4148 tab
->traceset_info
->traceset_context
=
4149 g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
4150 g_assert(tab
->traceset_info
->traceset_context
!= NULL
);
4152 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
),
4153 tab
->traceset_info
->traceset
);
4154 //add state update hooks
4155 lttv_state_add_event_hooks(
4156 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
4158 //determine the current_time and time_window of the tab
4160 if(copy_tab
!= NULL
){
4161 tab
->time_window
= copy_tab
->time_window
;
4162 tab
->current_time
= copy_tab
->current_time
;
4164 tab
->time_window
.start_time
=
4165 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
4166 time_span
.start_time
;
4167 if(DEFAULT_TIME_WIDTH_S
<
4168 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
4169 time_span
.end_time
.tv_sec
)
4170 tmp_time
.tv_sec
= DEFAULT_TIME_WIDTH_S
;
4173 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
4174 time_span
.end_time
.tv_sec
;
4175 tmp_time
.tv_nsec
= 0;
4176 tab
->time_window
.time_width
= tmp_time
;
4177 tab
->current_time
.tv_sec
=
4178 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
4179 time_span
.start_time
.tv_sec
;
4180 tab
->current_time
.tv_nsec
=
4181 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
4182 time_span
.start_time
.tv_nsec
;
4185 tab
->attributes
= LTTV_IATTRIBUTE(g_object_new(LTTV_ATTRIBUTE_TYPE
, NULL
));
4186 tab
->interrupted_state
= g_object_new(LTTV_ATTRIBUTE_TYPE
, NULL
);
4188 tab
->vbox
= gtk_vbox_new(FALSE
, 2);
4189 tab
->viewer_container
= gtk_vbox_new(TRUE
, 2);
4190 tab
->scrollbar
= gtk_hscrollbar_new(NULL
);
4191 //tab->multivpaned = gtk_multi_vpaned_new();
4193 gtk_box_pack_start(GTK_BOX(tab
->vbox
),
4194 tab
->viewer_container
,
4196 TRUE
, /* Give the extra space to the child */
4197 0); /* No padding */
4199 /* Create the timebar */
4201 tab
->MTimebar
= gtk_hbox_new(FALSE
, 2);
4202 gtk_widget_show(tab
->MTimebar
);
4203 tab
->tooltips
= gtk_tooltips_new();
4205 tab
->MEventBox1a
= gtk_event_box_new();
4206 gtk_widget_show(tab
->MEventBox1a
);
4207 gtk_tooltips_set_tip(tab
->tooltips
, tab
->MEventBox1a
,
4208 "Paste Start and End Times Here", "");
4209 tab
->MText1a
= gtk_label_new("Time Frame ");
4210 gtk_widget_show(tab
->MText1a
);
4211 gtk_container_add(GTK_CONTAINER(tab
->MEventBox1a
), tab
->MText1a
);
4212 tab
->MEventBox1b
= gtk_event_box_new();
4213 gtk_widget_show(tab
->MEventBox1b
);
4214 gtk_tooltips_set_tip(tab
->tooltips
, tab
->MEventBox1b
,
4215 "Paste Start Time Here", "");
4216 tab
->MText1b
= gtk_label_new("start: ");
4217 gtk_widget_show(tab
->MText1b
);
4218 gtk_container_add(GTK_CONTAINER(tab
->MEventBox1b
), tab
->MText1b
);
4219 tab
->MText2
= gtk_label_new("s");
4220 gtk_widget_show(tab
->MText2
);
4221 tab
->MText3a
= gtk_label_new("ns");
4222 gtk_widget_show(tab
->MText3a
);
4223 tab
->MEventBox3b
= gtk_event_box_new();
4224 gtk_widget_show(tab
->MEventBox3b
);
4225 gtk_tooltips_set_tip(tab
->tooltips
, tab
->MEventBox3b
,
4226 "Paste End Time Here", "");
4227 tab
->MText3b
= gtk_label_new("end:");
4228 gtk_widget_show(tab
->MText3b
);
4229 gtk_container_add(GTK_CONTAINER(tab
->MEventBox3b
), tab
->MText3b
);
4230 tab
->MText4
= gtk_label_new("s");
4231 gtk_widget_show(tab
->MText4
);
4232 tab
->MText5a
= gtk_label_new("ns");
4233 gtk_widget_show(tab
->MText5a
);
4234 tab
->MEventBox5b
= gtk_event_box_new();
4235 gtk_widget_show(tab
->MEventBox5b
);
4236 gtk_tooltips_set_tip(tab
->tooltips
, tab
->MEventBox5b
,
4237 "Paste Current Time Here", "");
4238 tab
->MText5b
= gtk_label_new("Current Time:");
4239 gtk_widget_show(tab
->MText5b
);
4240 gtk_container_add(GTK_CONTAINER(tab
->MEventBox5b
), tab
->MText5b
);
4241 tab
->MText6
= gtk_label_new("s");
4242 gtk_widget_show(tab
->MText6
);
4243 tab
->MText7
= gtk_label_new("ns");
4244 gtk_widget_show(tab
->MText7
);
4246 tab
->MEntry1
= gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4247 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab
->MEntry1
),0);
4248 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab
->MEntry1
),TRUE
);
4249 gtk_widget_show(tab
->MEntry1
);
4250 tab
->MEntry2
= gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4251 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab
->MEntry2
),0);
4252 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab
->MEntry2
),TRUE
);
4253 gtk_widget_show(tab
->MEntry2
);
4254 tab
->MEntry3
= gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4255 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab
->MEntry3
),0);
4256 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab
->MEntry3
),TRUE
);
4257 gtk_widget_show(tab
->MEntry3
);
4258 tab
->MEntry4
= gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4259 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab
->MEntry4
),0);
4260 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab
->MEntry4
),TRUE
);
4261 gtk_widget_show(tab
->MEntry4
);
4262 tab
->MEntry5
= gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4263 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab
->MEntry5
),0);
4264 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab
->MEntry5
),TRUE
);
4265 gtk_widget_show(tab
->MEntry5
);
4266 tab
->MEntry6
= gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4267 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab
->MEntry6
),0);
4268 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab
->MEntry6
),TRUE
);
4269 gtk_widget_show(tab
->MEntry6
);
4272 GtkWidget
*temp_widget
;
4274 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEventBox1a
, FALSE
,
4276 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEventBox1b
, FALSE
,
4278 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEntry1
, FALSE
, FALSE
, 0);
4279 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MText2
, FALSE
, FALSE
, 0);
4280 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEntry2
, FALSE
, FALSE
, 0);
4281 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MText3a
, FALSE
, FALSE
, 0);
4282 temp_widget
= gtk_vseparator_new();
4283 gtk_widget_show(temp_widget
);
4284 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), temp_widget
, FALSE
, FALSE
, 0);
4285 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEventBox3b
, FALSE
,
4287 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEntry3
, FALSE
, FALSE
, 0);
4288 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MText4
, FALSE
, FALSE
, 0);
4289 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEntry4
, FALSE
, FALSE
, 0);
4290 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MText5a
, FALSE
, FALSE
, 0);
4291 temp_widget
= gtk_vseparator_new();
4292 gtk_widget_show(temp_widget
);
4293 gtk_box_pack_end (GTK_BOX (tab
->MTimebar
), tab
->MText7
, FALSE
, FALSE
, 0);
4294 gtk_box_pack_end (GTK_BOX (tab
->MTimebar
), tab
->MEntry6
, FALSE
, FALSE
, 0);
4295 gtk_box_pack_end (GTK_BOX (tab
->MTimebar
), tab
->MText6
, FALSE
, FALSE
, 0);
4296 gtk_box_pack_end (GTK_BOX (tab
->MTimebar
), tab
->MEntry5
, FALSE
, FALSE
, 0);
4297 gtk_box_pack_end (GTK_BOX (tab
->MTimebar
), tab
->MEventBox5b
, FALSE
,
4299 gtk_box_pack_end (GTK_BOX (tab
->MTimebar
), temp_widget
, FALSE
, FALSE
, 0);
4302 //GtkWidget *test = gtk_button_new_with_label("drop");
4303 //gtk_button_set_relief(GTK_BUTTON(test), GTK_RELIEF_NONE);
4304 //gtk_widget_show(test);
4305 //gtk_box_pack_end(GTK_BOX (tab->MTimebar), test, FALSE, FALSE, 0);
4306 //gtk_widget_add_events(tab->MText1, GDK_ALL_EVENTS_MASK);//GDK_BUTTON_PRESS_MASK);
4307 /*GtkWidget *event_box = gtk_event_box_new();
4308 gtk_widget_show(event_box);
4309 gtk_tooltips_set_tip(tooltips, event_box,
4310 "Paste Current Time Here", "");
4311 gtk_box_pack_end(GTK_BOX (tab->MTimebar), event_box, FALSE, FALSE, 0);
4312 GtkWidget *test = gtk_label_new("drop");
4313 gtk_container_add(GTK_CONTAINER(event_box), test);
4314 gtk_widget_show(test);
4315 g_signal_connect (G_OBJECT(event_box),
4316 "button-press-event",
4317 G_CALLBACK (on_MText1_paste),
4321 g_signal_connect (G_OBJECT(tab
->MEventBox1a
),
4322 "button-press-event",
4323 G_CALLBACK (on_MEventBox1a_paste
),
4326 g_signal_connect (G_OBJECT(tab
->MEventBox1b
),
4327 "button-press-event",
4328 G_CALLBACK (on_MEventBox1b_paste
),
4330 g_signal_connect (G_OBJECT(tab
->MEventBox3b
),
4331 "button-press-event",
4332 G_CALLBACK (on_MEventBox3b_paste
),
4334 g_signal_connect (G_OBJECT(tab
->MEventBox5b
),
4335 "button-press-event",
4336 G_CALLBACK (on_MEventBox5b_paste
),
4340 gtk_box_pack_end(GTK_BOX(tab
->vbox
),
4342 FALSE
, /* Do not expand */
4343 FALSE
, /* Fill has no effect here (expand false) */
4344 0); /* No padding */
4346 gtk_box_pack_end(GTK_BOX(tab
->vbox
),
4348 FALSE
, /* Do not expand */
4349 FALSE
, /* Fill has no effect here (expand false) */
4350 0); /* No padding */
4352 g_object_set_data(G_OBJECT(tab
->viewer_container
), "focused_viewer", NULL
);
4358 // Display a label with a X
4359 GtkWidget *w_hbox = gtk_hbox_new(FALSE, 4);
4360 GtkWidget *w_label = gtk_label_new (label);
4361 GtkWidget *pixmap = create_pixmap(GTK_WIDGET(notebook), "close.png");
4362 GtkWidget *w_button = gtk_button_new ();
4363 gtk_container_add(GTK_CONTAINER(w_button), pixmap);
4364 //GtkWidget *w_button = gtk_button_new_with_label("x");
4366 gtk_button_set_relief(GTK_BUTTON(w_button), GTK_RELIEF_NONE);
4368 gtk_box_pack_start(GTK_BOX(w_hbox), w_label, TRUE, TRUE, 0);
4369 gtk_box_pack_end(GTK_BOX(w_hbox), w_button, FALSE,
4372 g_signal_connect_swapped (w_button, "clicked",
4373 G_CALLBACK (on_close_tab_X_clicked),
4376 gtk_widget_set_state(w_button, GTK_STATE_ACTIVE);
4378 gtk_widget_show (w_label);
4379 gtk_widget_show (pixmap);
4380 gtk_widget_show (w_button);
4381 gtk_widget_show (w_hbox);
4383 tab->label = w_hbox;
4387 tab
->label
= gtk_label_new (label
);
4389 gtk_widget_show(tab
->label
);
4390 gtk_widget_show(tab
->scrollbar
);
4391 gtk_widget_show(tab
->viewer_container
);
4392 gtk_widget_show(tab
->vbox
);
4393 //gtk_widget_show(tab->multivpaned);
4396 /* Start with empty events requests list */
4397 tab
->events_requests
= NULL
;
4398 tab
->events_request_pending
= FALSE
;
4400 g_object_set_data_full(
4401 G_OBJECT(tab
->vbox
),
4404 (GDestroyNotify
)tab_destructor
);
4406 g_signal_connect(G_OBJECT(tab
->scrollbar
), "value-changed",
4407 G_CALLBACK(scroll_value_changed_cb
), tab
);
4409 g_signal_connect ((gpointer
) tab
->MEntry1
, "value-changed",
4410 G_CALLBACK (on_MEntry1_value_changed
),
4412 g_signal_connect ((gpointer
) tab
->MEntry2
, "value-changed",
4413 G_CALLBACK (on_MEntry2_value_changed
),
4415 g_signal_connect ((gpointer
) tab
->MEntry3
, "value-changed",
4416 G_CALLBACK (on_MEntry3_value_changed
),
4418 g_signal_connect ((gpointer
) tab
->MEntry4
, "value-changed",
4419 G_CALLBACK (on_MEntry4_value_changed
),
4421 g_signal_connect ((gpointer
) tab
->MEntry5
, "value-changed",
4422 G_CALLBACK (on_MEntry5_value_changed
),
4424 g_signal_connect ((gpointer
) tab
->MEntry6
, "value-changed",
4425 G_CALLBACK (on_MEntry6_value_changed
),
4428 //g_signal_connect(G_OBJECT(tab->scrollbar), "changed",
4429 // G_CALLBACK(scroll_value_changed_cb), tab);
4432 //insert tab into notebook
4433 gtk_notebook_append_page(notebook
,
4436 list
= gtk_container_get_children(GTK_CONTAINER(notebook
));
4437 gtk_notebook_set_current_page(notebook
,g_list_length(list
)-1);
4438 // always show : not if(g_list_length(list)>1)
4439 gtk_notebook_set_show_tabs(notebook
, TRUE
);
4445 * execute_events_requests
4447 * Idle function that executes the pending requests for a tab.
4449 * @return return value : TRUE : keep the idle function, FALSE : remove it.
4451 gboolean
execute_events_requests(Tab
*tab
)
4453 return ( lttvwindow_process_pending_requests(tab
) );