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 /* Stop all the processings and call gtk_main_quit() */
335 static void mainwindow_quit()
337 lttvwindowtraces_unregister_requests(g_quark_from_string("stats"));
338 lttvwindowtraces_unregister_requests(g_quark_from_string("state"));
339 lttvwindowtraces_unregister_computation_hooks(g_quark_from_string("stats"));
340 lttvwindowtraces_unregister_computation_hooks(g_quark_from_string("state"));
346 /* insert_viewer function constructs an instance of a viewer first,
347 * then inserts the widget of the instance into the container of the
352 insert_viewer_wrap(GtkWidget
*menuitem
, gpointer user_data
)
354 insert_viewer((GtkWidget
*)menuitem
, (lttvwindow_viewer_constructor
)user_data
);
358 /* internal functions */
359 void insert_viewer(GtkWidget
* widget
, lttvwindow_viewer_constructor constructor
)
361 GtkWidget
* viewer_container
;
362 MainWindow
* mw_data
= get_window_data_struct(widget
);
363 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
365 TimeInterval
* time_interval
;
366 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
367 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
371 tab
= create_new_tab(widget
, NULL
);
373 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
376 viewer_container
= tab
->viewer_container
;
378 viewer
= (GtkWidget
*)constructor(tab
);
381 //gtk_multivpaned_widget_add(GTK_MULTIVPANED(multivpaned), viewer);
383 gtk_box_pack_end(GTK_BOX(viewer_container
),
389 /* We want to connect the viewer_grab_focus to EVERY
390 * child of this widget. The little trick is to get each child
391 * of each GTK_CONTAINER, even subchildren.
393 connect_focus_recursive(viewer
, viewer
);
398 * Function to set/update traceset for the viewers
399 * @param tab viewer's tab
400 * @param traceset traceset of the main window.
402 * 0 : traceset updated
403 * 1 : no traceset hooks to update; not an error.
406 int SetTraceset(Tab
* tab
, LttvTraceset
*traceset
)
408 LttvTracesetContext
*tsc
=
409 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
410 TimeInterval time_span
= tsc
->time_span
;
411 TimeWindow new_time_window
;
412 LttTime new_current_time
;
414 /* Set the tab's time window and current time if
416 if(ltt_time_compare(tab
->time_window
.start_time
, time_span
.start_time
) < 0
417 || ltt_time_compare(tab
->time_window
.end_time
,
418 time_span
.end_time
) > 0) {
419 new_time_window
.start_time
= time_span
.start_time
;
421 new_current_time
= time_span
.start_time
;
425 if(DEFAULT_TIME_WIDTH_S
< time_span
.end_time
.tv_sec
)
426 tmp_time
.tv_sec
= DEFAULT_TIME_WIDTH_S
;
428 tmp_time
.tv_sec
= time_span
.end_time
.tv_sec
;
429 tmp_time
.tv_nsec
= 0;
430 new_time_window
.time_width
= tmp_time
;
431 new_time_window
.time_width_double
= ltt_time_to_double(tmp_time
);
432 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
433 new_time_window
.time_width
) ;
435 time_change_manager(tab
, new_time_window
);
436 current_time_change_manager(tab
, new_current_time
);
438 //FIXME : we delete the filter tree, when it should be updated.
439 lttv_filter_destroy(tab
->filter
);
444 GtkAdjustment
*adjustment
= gtk_range_get_adjustment(GTK_RANGE(tab
->scrollbar
));
445 LttTime upper
= ltt_time_sub(time_span
.end_time
, time_span
.start_time
);
447 g_object_set(G_OBJECT(adjustment
),
451 ltt_time_to_double(upper
)
452 * NANOSECONDS_PER_SECOND
, /* upper */
454 ltt_time_to_double(tab
->time_window
.time_width
)
455 / SCROLL_STEP_PER_PAGE
456 * NANOSECONDS_PER_SECOND
, /* step increment */
458 ltt_time_to_double(tab
->time_window
.time_width
)
459 * NANOSECONDS_PER_SECOND
, /* page increment */
461 ltt_time_to_double(tab
->time_window
.time_width
)
462 * NANOSECONDS_PER_SECOND
, /* page size */
464 gtk_adjustment_changed(adjustment
);
466 g_object_set(G_OBJECT(adjustment
),
469 ltt_time_sub(tab
->time_window
.start_time
, time_span
.start_time
))
470 * NANOSECONDS_PER_SECOND
, /* value */
472 gtk_adjustment_value_changed(adjustment
);
474 /* set the time bar. The value callbacks will change their nsec themself */
476 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry1
),
477 (double)time_span
.start_time
.tv_sec
,
478 (double)time_span
.end_time
.tv_sec
);
481 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry3
),
482 (double)time_span
.start_time
.tv_sec
,
483 (double)time_span
.end_time
.tv_sec
);
485 /* current seconds */
486 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry5
),
487 (double)time_span
.start_time
.tv_sec
,
488 (double)time_span
.end_time
.tv_sec
);
491 /* Finally, call the update hooks of the viewers */
493 LttvAttributeValue value
;
497 g_assert( lttv_iattribute_find_by_path(tab
->attributes
,
498 "hooks/updatetraceset", LTTV_POINTER
, &value
));
500 tmp
= (LttvHooks
*)*(value
.v_pointer
);
501 if(tmp
== NULL
) retval
= 1;
502 else lttv_hooks_call(tmp
,traceset
);
509 * Function to set/update filter for the viewers
510 * @param tab viewer's tab
511 * @param filter filter of the main window.
514 * 0 : filters updated
515 * 1 : no filter hooks to update; not an error.
518 int SetFilter(Tab
* tab
, gpointer filter
)
521 LttvAttributeValue value
;
523 g_assert(lttv_iattribute_find_by_path(tab
->attributes
,
524 "hooks/updatefilter", LTTV_POINTER
, &value
));
526 tmp
= (LttvHooks
*)*(value
.v_pointer
);
528 if(tmp
== NULL
) return 1;
529 lttv_hooks_call(tmp
,filter
);
537 * Function to redraw each viewer belonging to the current tab
538 * @param tab viewer's tab
541 void update_traceset(Tab
*tab
)
543 LttvAttributeValue value
;
545 g_assert(lttv_iattribute_find_by_path(tab
->attributes
,
546 "hooks/updatetraceset", LTTV_POINTER
, &value
));
547 tmp
= (LttvHooks
*)*(value
.v_pointer
);
548 if(tmp
== NULL
) return;
549 lttv_hooks_call(tmp
, NULL
);
553 /* get_label function is used to get user input, it displays an input
554 * box, which allows user to input a string
557 void get_label_string (GtkWidget
* text
, gchar
* label
)
559 GtkEntry
* entry
= (GtkEntry
*)text
;
560 if(strlen(gtk_entry_get_text(entry
))!=0)
561 strcpy(label
,gtk_entry_get_text(entry
));
564 gboolean
get_label(MainWindow
* mw
, gchar
* str
, gchar
* dialogue_title
, gchar
* label_str
)
566 GtkWidget
* dialogue
;
571 dialogue
= gtk_dialog_new_with_buttons(dialogue_title
,NULL
,
573 GTK_STOCK_OK
,GTK_RESPONSE_ACCEPT
,
574 GTK_STOCK_CANCEL
,GTK_RESPONSE_REJECT
,
577 label
= gtk_label_new(label_str
);
578 gtk_widget_show(label
);
580 text
= gtk_entry_new();
581 gtk_widget_show(text
);
583 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialogue
)->vbox
), label
,TRUE
, TRUE
,0);
584 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialogue
)->vbox
), text
,FALSE
, FALSE
,0);
586 id
= gtk_dialog_run(GTK_DIALOG(dialogue
));
588 case GTK_RESPONSE_ACCEPT
:
589 get_label_string(text
,str
);
590 gtk_widget_destroy(dialogue
);
592 case GTK_RESPONSE_REJECT
:
594 gtk_widget_destroy(dialogue
);
601 /* get_window_data_struct function is actually a lookup function,
602 * given a widget which is in the tree of the main window, it will
603 * return the MainWindow data structure associated with main window
606 MainWindow
* get_window_data_struct(GtkWidget
* widget
)
609 MainWindow
* mw_data
;
611 mw
= lookup_widget(widget
, "MWindow");
613 g_info("Main window does not exist\n");
617 mw_data
= (MainWindow
*) g_object_get_data(G_OBJECT(mw
),"main_window_data");
619 g_warning("Main window data does not exist\n");
626 /* create_new_window function, just constructs a new main window
629 void create_new_window(GtkWidget
* widget
, gpointer user_data
, gboolean clone
)
631 MainWindow
* parent
= get_window_data_struct(widget
);
634 g_info("Clone : use the same traceset\n");
635 construct_main_window(parent
);
637 g_info("Empty : traceset is set to NULL\n");
638 construct_main_window(NULL
);
642 /* Get the currently focused viewer.
643 * If no viewer is focused, use the first one.
645 * If no viewer available, return NULL.
647 GtkWidget
*viewer_container_focus(GtkWidget
*container
)
651 widget
= (GtkWidget
*)g_object_get_data(G_OBJECT(container
),
655 g_debug("no widget focused");
656 GList
*children
= gtk_container_get_children(GTK_CONTAINER(container
));
659 widget
= GTK_WIDGET(children
->data
);
660 g_object_set_data(G_OBJECT(container
),
670 gint
viewer_container_position(GtkWidget
*container
, GtkWidget
*child
)
673 if(child
== NULL
) return -1;
677 memset(&value
, 0, sizeof(GValue
));
678 g_value_init(&value
, G_TYPE_INT
);
679 gtk_container_child_get_property(GTK_CONTAINER(container
),
683 pos
= g_value_get_int(&value
);
689 /* move_*_viewer functions move the selected view up/down in
693 void move_down_viewer(GtkWidget
* widget
, gpointer user_data
)
695 MainWindow
* mw
= get_window_data_struct(widget
);
696 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
698 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
699 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
705 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
708 //gtk_multivpaned_widget_move_up(GTK_MULTIVPANED(tab->multivpaned));
710 /* change the position in the vbox */
711 GtkWidget
*focus_widget
;
713 focus_widget
= viewer_container_focus(tab
->viewer_container
);
714 position
= viewer_container_position(tab
->viewer_container
, focus_widget
);
717 /* can move up one position */
718 gtk_box_reorder_child(GTK_BOX(tab
->viewer_container
),
725 void move_up_viewer(GtkWidget
* widget
, gpointer user_data
)
727 MainWindow
* mw
= get_window_data_struct(widget
);
728 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
730 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
731 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
737 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
740 //gtk_multivpaned_widget_move_down(GTK_MULTIVPANED(tab->multivpaned));
741 /* change the position in the vbox */
742 GtkWidget
*focus_widget
;
744 focus_widget
= viewer_container_focus(tab
->viewer_container
);
745 position
= viewer_container_position(tab
->viewer_container
, focus_widget
);
749 g_list_length(gtk_container_get_children(
750 GTK_CONTAINER(tab
->viewer_container
)))-1
752 /* can move down one position */
753 gtk_box_reorder_child(GTK_BOX(tab
->viewer_container
),
761 /* delete_viewer deletes the selected viewer in the current tab
764 void delete_viewer(GtkWidget
* widget
, gpointer user_data
)
766 MainWindow
* mw
= get_window_data_struct(widget
);
767 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
769 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
770 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
776 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
779 //gtk_multivpaned_widget_delete(GTK_MULTIVPANED(tab->multivpaned));
781 GtkWidget
*focus_widget
= viewer_container_focus(tab
->viewer_container
);
783 if(focus_widget
!= NULL
)
784 gtk_widget_destroy(focus_widget
);
786 g_object_set_data(G_OBJECT(tab
->viewer_container
), "focused_viewer", NULL
);
790 /* open_traceset will open a traceset saved in a file
791 * Right now, it is not finished yet, (not working)
795 void open_traceset(GtkWidget
* widget
, gpointer user_data
)
799 LttvTraceset
* traceset
;
800 MainWindow
* mw_data
= get_window_data_struct(widget
);
801 GtkFileSelection
* file_selector
=
802 (GtkFileSelection
*)gtk_file_selection_new("Select a traceset");
804 gtk_file_selection_hide_fileop_buttons(file_selector
);
806 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
808 case GTK_RESPONSE_ACCEPT
:
809 case GTK_RESPONSE_OK
:
810 dir
= gtk_file_selection_get_selections (file_selector
);
811 traceset
= lttv_traceset_load(dir
[0]);
812 g_info("Open a trace set %s\n", dir
[0]);
815 case GTK_RESPONSE_REJECT
:
816 case GTK_RESPONSE_CANCEL
:
818 gtk_widget_destroy((GtkWidget
*)file_selector
);
824 /* lttvwindow_process_pending_requests
826 * This internal function gets called by g_idle, taking care of the pending
827 * requests. It is responsible for concatenation of time intervals and position
828 * requests. It does it with the following algorithm organizing process traceset
829 * calls. Here is the detailed description of the way it works :
831 * - Events Requests Servicing Algorithm
833 * Data structures necessary :
835 * List of requests added to context : list_in
836 * List of requests not added to context : list_out
841 * list_out : many events requests
843 * FIXME : insert rest of algorithm here
847 #define list_out tab->events_requests
849 gboolean
lttvwindow_process_pending_requests(Tab
*tab
)
852 LttvTracesetContext
*tsc
;
853 LttvTracefileContext
*tfc
;
854 GSList
*list_in
= NULL
;
858 LttvTracesetContextPosition
*end_position
;
861 g_critical("Foreground processing : tab does not exist. Processing removed.");
865 /* There is no events requests pending : we should never have been called! */
866 g_assert(g_slist_length(list_out
) != 0);
868 tsc
= LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
870 //set the cursor to be X shape, indicating that the computer is busy in doing its job
872 new = gdk_cursor_new(GDK_X_CURSOR
);
873 widget
= lookup_widget(tab
->mw
->mwindow
, "MToolbar1");
874 win
= gtk_widget_get_parent_window(widget
);
875 gdk_window_set_cursor(win
, new);
876 gdk_cursor_unref(new);
877 gdk_window_stick(win
);
878 gdk_window_unstick(win
);
881 g_debug("SIZE events req len : %d", g_slist_length(list_out
));
883 /* Preliminary check for no trace in traceset */
884 /* Unregister the routine if empty, empty list_out too */
885 if(lttv_traceset_number(tsc
->ts
) == 0) {
887 /* - For each req in list_out */
888 GSList
*iter
= list_out
;
890 while(iter
!= NULL
) {
892 gboolean remove
= FALSE
;
893 gboolean free_data
= FALSE
;
894 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
896 /* - Call end request for req */
897 if(events_request
->servicing
== TRUE
)
898 lttv_hooks_call(events_request
->after_request
, (gpointer
)tsc
);
900 /* - remove req from list_out */
901 /* Destroy the request */
908 GSList
*remove_iter
= iter
;
910 iter
= g_slist_next(iter
);
911 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
912 list_out
= g_slist_remove_link(list_out
, remove_iter
);
913 } else { // not remove
914 iter
= g_slist_next(iter
);
919 /* 0.1 Lock Traces */
924 iter_trace
<lttv_traceset_number(tsc
->ts
);
926 LttvTrace
*trace_v
= lttv_traceset_get(tsc
->ts
, iter_trace
);
928 if(lttvwindowtraces_lock(trace_v
) != 0) {
929 g_critical("Foreground processing : Unable to get trace lock");
930 return TRUE
; /* Cannot get lock, try later */
935 /* 0.2 Seek tracefiles positions to context position */
936 //g_assert(lttv_process_traceset_seek_position(tsc, sync_position) == 0);
937 lttv_process_traceset_synchronize_tracefiles(tsc
);
940 /* Events processing algorithm implementation */
941 /* Warning : the gtk_events_pending takes a LOT of cpu time. So what we do
942 * instead is to leave the control to GTK and take it back.
944 /* A. Servicing loop */
945 //while( (g_slist_length(list_in) != 0 || g_slist_length(list_out) != 0)) {
946 if((g_slist_length(list_in
) != 0 || g_slist_length(list_out
) != 0)) {
948 /* 1. If list_in is empty (need a seek) */
949 if( g_slist_length(list_in
) == 0 ) {
951 /* list in is empty, need a seek */
953 /* 1.1 Add requests to list_in */
954 GSList
*ltime
= NULL
;
958 /* 1.1.1 Find all time requests with the lowest start time in list_out
961 if(g_slist_length(list_out
) > 0)
962 ltime
= g_slist_append(ltime
, g_slist_nth_data(list_out
, 0));
963 for(iter
=g_slist_nth(list_out
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
964 /* Find all time requests with the lowest start time in list_out */
965 EventsRequest
*event_request_ltime
= (EventsRequest
*)g_slist_nth_data(ltime
, 0);
966 EventsRequest
*event_request_list_out
= (EventsRequest
*)iter
->data
;
969 comp
= ltt_time_compare(event_request_ltime
->start_time
,
970 event_request_list_out
->start_time
);
972 ltime
= g_slist_append(ltime
, event_request_list_out
);
974 /* Remove all elements from ltime, and add current */
976 ltime
= g_slist_delete_link(ltime
, g_slist_nth(ltime
, 0));
977 ltime
= g_slist_append(ltime
, event_request_list_out
);
981 /* 1.1.2 Find all position requests with the lowest position in list_out
984 if(g_slist_length(list_out
) > 0)
985 lpos
= g_slist_append(lpos
, 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 position requests with the lowest position in list_out */
988 EventsRequest
*event_request_lpos
= (EventsRequest
*)g_slist_nth_data(lpos
, 0);
989 EventsRequest
*event_request_list_out
= (EventsRequest
*)iter
->data
;
992 if(event_request_lpos
->start_position
!= NULL
993 && event_request_list_out
->start_position
!= NULL
)
995 comp
= lttv_traceset_context_pos_pos_compare
996 (event_request_lpos
->start_position
,
997 event_request_list_out
->start_position
);
1002 lpos
= g_slist_append(lpos
, event_request_list_out
);
1004 /* Remove all elements from lpos, and add current */
1006 lpos
= g_slist_delete_link(lpos
, g_slist_nth(lpos
, 0));
1007 lpos
= g_slist_append(lpos
, event_request_list_out
);
1012 EventsRequest
*event_request_lpos
= (EventsRequest
*)g_slist_nth_data(lpos
, 0);
1013 EventsRequest
*event_request_ltime
= (EventsRequest
*)g_slist_nth_data(ltime
, 0);
1014 LttTime lpos_start_time
;
1016 if(event_request_lpos
!= NULL
1017 && event_request_lpos
->start_position
!= NULL
) {
1018 lpos_start_time
= lttv_traceset_context_position_get_time(
1019 event_request_lpos
->start_position
);
1022 /* 1.1.3 If lpos.start time < ltime */
1023 if(event_request_lpos
!= NULL
1024 && event_request_lpos
->start_position
!= NULL
1025 && ltt_time_compare(lpos_start_time
,
1026 event_request_ltime
->start_time
)<0) {
1027 /* Add lpos to list_in, remove them from list_out */
1028 for(iter
=lpos
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
1029 /* Add to list_in */
1030 EventsRequest
*event_request_lpos
=
1031 (EventsRequest
*)iter
->data
;
1033 list_in
= g_slist_append(list_in
, event_request_lpos
);
1034 /* Remove from list_out */
1035 list_out
= g_slist_remove(list_out
, event_request_lpos
);
1038 /* 1.1.4 (lpos.start time >= ltime) */
1039 /* Add ltime to list_in, remove them from list_out */
1041 for(iter
=ltime
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
1042 /* Add to list_in */
1043 EventsRequest
*event_request_ltime
=
1044 (EventsRequest
*)iter
->data
;
1046 list_in
= g_slist_append(list_in
, event_request_ltime
);
1047 /* Remove from list_out */
1048 list_out
= g_slist_remove(list_out
, event_request_ltime
);
1053 g_slist_free(ltime
);
1058 tfc
= lttv_traceset_context_get_current_tfc(tsc
);
1059 g_assert(g_slist_length(list_in
)>0);
1060 EventsRequest
*events_request
= g_slist_nth_data(list_in
, 0);
1063 /* 1.2.1 If first request in list_in is a time request */
1064 if(events_request
->start_position
== NULL
) {
1065 /* - If first req in list_in start time != current time */
1066 if(tfc
== NULL
|| ltt_time_compare(events_request
->start_time
,
1067 tfc
->timestamp
) != 0)
1068 /* - Seek to that time */
1069 g_debug("SEEK TIME : %lu, %lu", events_request
->start_time
.tv_sec
,
1070 events_request
->start_time
.tv_nsec
);
1071 //lttv_process_traceset_seek_time(tsc, events_request->start_time);
1072 lttv_state_traceset_seek_time_closest(LTTV_TRACESET_STATE(tsc
),
1073 events_request
->start_time
);
1075 /* Process the traceset with only state hooks */
1077 lttv_process_traceset_middle(tsc
,
1078 events_request
->start_time
,
1081 g_assert(seek_count
< LTTV_STATE_SAVE_INTERVAL
);
1087 /* Else, the first request in list_in is a position request */
1088 /* If first req in list_in pos != current pos */
1089 g_assert(events_request
->start_position
!= NULL
);
1090 g_debug("SEEK POS time : %lu, %lu",
1091 lttv_traceset_context_position_get_time(
1092 events_request
->start_position
).tv_sec
,
1093 lttv_traceset_context_position_get_time(
1094 events_request
->start_position
).tv_nsec
);
1096 g_debug("SEEK POS context time : %lu, %lu",
1097 lttv_traceset_context_get_current_tfc(tsc
)->timestamp
.tv_sec
,
1098 lttv_traceset_context_get_current_tfc(tsc
)->timestamp
.tv_nsec
);
1099 g_assert(events_request
->start_position
!= NULL
);
1100 if(lttv_traceset_context_ctx_pos_compare(tsc
,
1101 events_request
->start_position
) != 0) {
1102 /* 1.2.2.1 Seek to that position */
1103 g_debug("SEEK POSITION");
1104 //lttv_process_traceset_seek_position(tsc, events_request->start_position);
1105 pos_time
= lttv_traceset_context_position_get_time(
1106 events_request
->start_position
);
1108 lttv_state_traceset_seek_time_closest(LTTV_TRACESET_STATE(tsc
),
1111 /* Process the traceset with only state hooks */
1113 lttv_process_traceset_middle(tsc
,
1116 events_request
->start_position
);
1117 g_assert(lttv_traceset_context_ctx_pos_compare(tsc
,
1118 events_request
->start_position
) == 0);
1125 /* 1.3 Add hooks and call before request for all list_in members */
1127 GSList
*iter
= NULL
;
1129 for(iter
=list_in
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
1130 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1131 /* 1.3.1 If !servicing */
1132 if(events_request
->servicing
== FALSE
) {
1133 /* - begin request hooks called
1134 * - servicing = TRUE
1136 lttv_hooks_call(events_request
->before_request
, (gpointer
)tsc
);
1137 events_request
->servicing
= TRUE
;
1139 /* 1.3.2 call before chunk
1140 * 1.3.3 events hooks added
1142 if(events_request
->trace
== -1)
1143 lttv_process_traceset_begin(tsc
,
1144 events_request
->before_chunk_traceset
,
1145 events_request
->before_chunk_trace
,
1146 events_request
->before_chunk_tracefile
,
1147 events_request
->event
,
1148 events_request
->event_by_id
);
1150 guint nb_trace
= lttv_traceset_number(tsc
->ts
);
1151 g_assert((guint
)events_request
->trace
< nb_trace
&&
1152 events_request
->trace
> -1);
1153 LttvTraceContext
*tc
= tsc
->traces
[events_request
->trace
];
1155 lttv_hooks_call(events_request
->before_chunk_traceset
, tsc
);
1157 lttv_trace_context_add_hooks(tc
,
1158 events_request
->before_chunk_trace
,
1159 events_request
->before_chunk_tracefile
,
1160 events_request
->event
,
1161 events_request
->event_by_id
);
1166 /* 2. Else, list_in is not empty, we continue a read */
1169 /* 2.0 For each req of list_in */
1170 GSList
*iter
= list_in
;
1172 while(iter
!= NULL
) {
1174 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1176 /* - Call before chunk
1177 * - events hooks added
1179 if(events_request
->trace
== -1)
1180 lttv_process_traceset_begin(tsc
,
1181 events_request
->before_chunk_traceset
,
1182 events_request
->before_chunk_trace
,
1183 events_request
->before_chunk_tracefile
,
1184 events_request
->event
,
1185 events_request
->event_by_id
);
1187 guint nb_trace
= lttv_traceset_number(tsc
->ts
);
1188 g_assert((guint
)events_request
->trace
< nb_trace
&&
1189 events_request
->trace
> -1);
1190 LttvTraceContext
*tc
= tsc
->traces
[events_request
->trace
];
1192 lttv_hooks_call(events_request
->before_chunk_traceset
, tsc
);
1194 lttv_trace_context_add_hooks(tc
,
1195 events_request
->before_chunk_trace
,
1196 events_request
->before_chunk_tracefile
,
1197 events_request
->event
,
1198 events_request
->event_by_id
);
1201 iter
= g_slist_next(iter
);
1206 tfc
= lttv_traceset_context_get_current_tfc(tsc
);
1208 /* 2.1 For each req of list_out */
1209 GSList
*iter
= list_out
;
1211 while(iter
!= NULL
) {
1213 gboolean remove
= FALSE
;
1214 gboolean free_data
= FALSE
;
1215 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1217 /* if req.start time == current context time
1218 * or req.start position == current position*/
1219 if( ltt_time_compare(events_request
->start_time
,
1220 tfc
->timestamp
) == 0
1222 (events_request
->start_position
!= NULL
1224 lttv_traceset_context_ctx_pos_compare(tsc
,
1225 events_request
->start_position
) == 0)
1227 /* - Add to list_in, remove from list_out */
1228 list_in
= g_slist_append(list_in
, events_request
);
1232 /* - If !servicing */
1233 if(events_request
->servicing
== FALSE
) {
1234 /* - begin request hooks called
1235 * - servicing = TRUE
1237 lttv_hooks_call(events_request
->before_request
, (gpointer
)tsc
);
1238 events_request
->servicing
= TRUE
;
1240 /* call before chunk
1241 * events hooks added
1243 if(events_request
->trace
== -1)
1244 lttv_process_traceset_begin(tsc
,
1245 events_request
->before_chunk_traceset
,
1246 events_request
->before_chunk_trace
,
1247 events_request
->before_chunk_tracefile
,
1248 events_request
->event
,
1249 events_request
->event_by_id
);
1251 guint nb_trace
= lttv_traceset_number(tsc
->ts
);
1252 g_assert((guint
)events_request
->trace
< nb_trace
&&
1253 events_request
->trace
> -1);
1254 LttvTraceContext
*tc
= tsc
->traces
[events_request
->trace
];
1256 lttv_hooks_call(events_request
->before_chunk_traceset
, tsc
);
1258 lttv_trace_context_add_hooks(tc
,
1259 events_request
->before_chunk_trace
,
1260 events_request
->before_chunk_tracefile
,
1261 events_request
->event
,
1262 events_request
->event_by_id
);
1271 GSList
*remove_iter
= iter
;
1273 iter
= g_slist_next(iter
);
1274 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
1275 list_out
= g_slist_remove_link(list_out
, remove_iter
);
1276 } else { // not remove
1277 iter
= g_slist_next(iter
);
1283 /* 3. Find end criterions */
1288 /* 3.1.1 Find lowest end time in list_in */
1289 g_assert(g_slist_length(list_in
)>0);
1290 end_time
= ((EventsRequest
*)g_slist_nth_data(list_in
,0))->end_time
;
1292 for(iter
=g_slist_nth(list_in
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
1293 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1295 if(ltt_time_compare(events_request
->end_time
,
1297 end_time
= events_request
->end_time
;
1300 /* 3.1.2 Find lowest start time in list_out */
1301 for(iter
=list_out
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
1302 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1304 if(ltt_time_compare(events_request
->start_time
,
1306 end_time
= events_request
->start_time
;
1311 /* 3.2 Number of events */
1313 /* 3.2.1 Find lowest number of events in list_in */
1316 end_nb_events
= ((EventsRequest
*)g_slist_nth_data(list_in
,0))->num_events
;
1318 for(iter
=g_slist_nth(list_in
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
1319 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1321 if(events_request
->num_events
< end_nb_events
)
1322 end_nb_events
= events_request
->num_events
;
1325 /* 3.2.2 Use min(CHUNK_NUM_EVENTS, min num events in list_in) as
1328 end_nb_events
= MIN(CHUNK_NUM_EVENTS
, end_nb_events
);
1332 /* 3.3 End position */
1334 /* 3.3.1 Find lowest end position in list_in */
1337 end_position
=((EventsRequest
*)g_slist_nth_data(list_in
,0))->end_position
;
1339 for(iter
=g_slist_nth(list_in
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
1340 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1342 if(events_request
->end_position
!= NULL
&& end_position
!= NULL
&&
1343 lttv_traceset_context_pos_pos_compare(events_request
->end_position
,
1345 end_position
= events_request
->end_position
;
1350 /* 3.3.2 Find lowest start position in list_out */
1353 for(iter
=list_out
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
1354 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1356 if(events_request
->end_position
!= NULL
&& end_position
!= NULL
&&
1357 lttv_traceset_context_pos_pos_compare(events_request
->end_position
,
1359 end_position
= events_request
->end_position
;
1364 /* 4. Call process traceset middle */
1365 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
);
1366 count
= lttv_process_traceset_middle(tsc
, end_time
, end_nb_events
, end_position
);
1368 tfc
= lttv_traceset_context_get_current_tfc(tsc
);
1370 g_debug("Context time after middle : %lu, %lu", tfc
->timestamp
.tv_sec
,
1371 tfc
->timestamp
.tv_nsec
);
1373 g_debug("End of trace reached after middle.");
1377 /* 5. After process traceset middle */
1378 tfc
= lttv_traceset_context_get_current_tfc(tsc
);
1380 /* - if current context time > traceset.end time */
1381 if(tfc
== NULL
|| ltt_time_compare(tfc
->timestamp
,
1382 tsc
->time_span
.end_time
) > 0) {
1383 /* - For each req in list_in */
1384 GSList
*iter
= list_in
;
1386 while(iter
!= NULL
) {
1388 gboolean remove
= FALSE
;
1389 gboolean free_data
= FALSE
;
1390 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1392 /* - Remove events hooks for req
1393 * - Call end chunk for req
1396 if(events_request
->trace
== -1)
1397 lttv_process_traceset_end(tsc
,
1398 events_request
->after_chunk_traceset
,
1399 events_request
->after_chunk_trace
,
1400 events_request
->after_chunk_tracefile
,
1401 events_request
->event
,
1402 events_request
->event_by_id
);
1405 guint nb_trace
= lttv_traceset_number(tsc
->ts
);
1406 g_assert(events_request
->trace
< nb_trace
&&
1407 events_request
->trace
> -1);
1408 LttvTraceContext
*tc
= tsc
->traces
[events_request
->trace
];
1410 lttv_trace_context_remove_hooks(tc
,
1411 events_request
->after_chunk_trace
,
1412 events_request
->after_chunk_tracefile
,
1413 events_request
->event
,
1414 events_request
->event_by_id
);
1415 lttv_hooks_call(events_request
->after_chunk_traceset
, tsc
);
1420 /* - Call end request for req */
1421 lttv_hooks_call(events_request
->after_request
, (gpointer
)tsc
);
1423 /* - remove req from list_in */
1424 /* Destroy the request */
1431 GSList
*remove_iter
= iter
;
1433 iter
= g_slist_next(iter
);
1434 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
1435 list_in
= g_slist_remove_link(list_in
, remove_iter
);
1436 } else { // not remove
1437 iter
= g_slist_next(iter
);
1442 /* 5.1 For each req in list_in */
1443 GSList
*iter
= list_in
;
1445 while(iter
!= NULL
) {
1447 gboolean remove
= FALSE
;
1448 gboolean free_data
= FALSE
;
1449 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1451 /* - Remove events hooks for req
1452 * - Call end chunk for req
1454 if(events_request
->trace
== -1)
1455 lttv_process_traceset_end(tsc
,
1456 events_request
->after_chunk_traceset
,
1457 events_request
->after_chunk_trace
,
1458 events_request
->after_chunk_tracefile
,
1459 events_request
->event
,
1460 events_request
->event_by_id
);
1463 guint nb_trace
= lttv_traceset_number(tsc
->ts
);
1464 g_assert(events_request
->trace
< nb_trace
&&
1465 events_request
->trace
> -1);
1466 LttvTraceContext
*tc
= tsc
->traces
[events_request
->trace
];
1468 lttv_trace_context_remove_hooks(tc
,
1469 events_request
->after_chunk_trace
,
1470 events_request
->after_chunk_tracefile
,
1471 events_request
->event
,
1472 events_request
->event_by_id
);
1474 lttv_hooks_call(events_request
->after_chunk_traceset
, tsc
);
1477 /* - req.num -= count */
1478 g_assert(events_request
->num_events
>= count
);
1479 events_request
->num_events
-= count
;
1481 g_assert(tfc
!= NULL
);
1482 /* - if req.num == 0
1484 * current context time >= req.end time
1486 * req.end pos == current pos
1488 * req.stop_flag == TRUE
1490 if( events_request
->num_events
== 0
1492 events_request
->stop_flag
== TRUE
1494 ltt_time_compare(tfc
->timestamp
,
1495 events_request
->end_time
) >= 0
1497 (events_request
->end_position
!= NULL
1499 lttv_traceset_context_ctx_pos_compare(tsc
,
1500 events_request
->end_position
) == 0)
1503 g_assert(events_request
->servicing
== TRUE
);
1504 /* - Call end request for req
1505 * - remove req from list_in */
1506 lttv_hooks_call(events_request
->after_request
, (gpointer
)tsc
);
1507 /* - remove req from list_in */
1508 /* Destroy the request */
1516 GSList
*remove_iter
= iter
;
1518 iter
= g_slist_next(iter
);
1519 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
1520 list_in
= g_slist_remove_link(list_in
, remove_iter
);
1521 } else { // not remove
1522 iter
= g_slist_next(iter
);
1528 /* End of removed servicing loop : leave control to GTK instead. */
1529 // if(gtk_events_pending()) break;
1532 /* B. When interrupted between chunks */
1535 GSList
*iter
= list_in
;
1537 /* 1. for each request in list_in */
1538 while(iter
!= NULL
) {
1540 gboolean remove
= FALSE
;
1541 gboolean free_data
= FALSE
;
1542 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1544 /* 1.1. Use current postition as start position */
1545 if(events_request
->start_position
!= NULL
)
1546 lttv_traceset_context_position_destroy(events_request
->start_position
);
1547 events_request
->start_position
= lttv_traceset_context_position_new();
1548 lttv_traceset_context_position_save(tsc
, events_request
->start_position
);
1550 /* 1.2. Remove start time */
1551 events_request
->start_time
= ltt_time_infinite
;
1553 /* 1.3. Move from list_in to list_out */
1556 list_out
= g_slist_append(list_out
, events_request
);
1561 GSList
*remove_iter
= iter
;
1563 iter
= g_slist_next(iter
);
1564 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
1565 list_in
= g_slist_remove_link(list_in
, remove_iter
);
1566 } else { // not remove
1567 iter
= g_slist_next(iter
);
1573 /* C Unlock Traces */
1575 lttv_process_traceset_get_sync_data(tsc
);
1576 //lttv_traceset_context_position_save(tsc, sync_position);
1581 iter_trace
<lttv_traceset_number(tsc
->ts
);
1583 LttvTrace
*trace_v
= lttv_traceset_get(tsc
->ts
, iter_trace
);
1585 lttvwindowtraces_unlock(trace_v
);
1589 //set the cursor back to normal
1590 gdk_window_set_cursor(win
, NULL
);
1593 g_assert(g_slist_length(list_in
) == 0);
1595 if( g_slist_length(list_out
) == 0 ) {
1596 /* Put tab's request pending flag back to normal */
1597 tab
->events_request_pending
= FALSE
;
1598 g_debug("remove the idle fct");
1599 return FALSE
; /* Remove the idle function */
1601 g_debug("leave the idle fct");
1602 return TRUE
; /* Leave the idle function */
1604 /* We do not use simili-round-robin, it may require to read 1 meg buffers
1605 * again and again if many tracesets use the same tracefiles. */
1606 /* Hack for round-robin idle functions */
1607 /* It will put the idle function at the end of the pool */
1608 /*g_idle_add_full((G_PRIORITY_HIGH_IDLE + 21),
1609 (GSourceFunc)execute_events_requests,
1619 static void lttvwindow_add_trace(Tab
*tab
, LttvTrace
*trace_v
)
1621 LttvTraceset
*traceset
= tab
->traceset_info
->traceset
;
1623 guint num_traces
= lttv_traceset_number(traceset
);
1625 //Verify if trace is already present.
1626 for(i
=0; i
<num_traces
; i
++)
1628 LttvTrace
* trace
= lttv_traceset_get(traceset
, i
);
1629 if(trace
== trace_v
)
1633 //Keep a reference to the traces so they are not freed.
1634 for(i
=0; i
<lttv_traceset_number(traceset
); i
++)
1636 LttvTrace
* trace
= lttv_traceset_get(traceset
, i
);
1637 lttv_trace_ref(trace
);
1640 //remove state update hooks
1641 lttv_state_remove_event_hooks(
1642 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1644 lttv_context_fini(LTTV_TRACESET_CONTEXT(
1645 tab
->traceset_info
->traceset_context
));
1646 g_object_unref(tab
->traceset_info
->traceset_context
);
1648 lttv_traceset_add(traceset
, trace_v
);
1649 lttv_trace_ref(trace_v
); /* local ref */
1651 /* Create new context */
1652 tab
->traceset_info
->traceset_context
=
1653 g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
1655 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->
1660 //add state update hooks
1661 lttv_state_add_event_hooks(
1662 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1663 //Remove local reference to the traces.
1664 for(i
=0; i
<lttv_traceset_number(traceset
); i
++)
1666 LttvTrace
* trace
= lttv_traceset_get(traceset
, i
);
1667 lttv_trace_unref(trace
);
1671 //add_trace_into_traceset_selector(GTK_MULTIVPANED(tab->multivpaned), lttv_trace(trace_v));
1674 /* add_trace adds a trace into the current traceset. It first displays a
1675 * directory selection dialogue to let user choose a trace, then recreates
1676 * tracset_context, and redraws all the viewer of the current tab
1679 void add_trace(GtkWidget
* widget
, gpointer user_data
)
1682 LttvTrace
* trace_v
;
1683 LttvTraceset
* traceset
;
1685 char abs_path
[PATH_MAX
];
1687 MainWindow
* mw_data
= get_window_data_struct(widget
);
1688 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
1690 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
1691 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
1695 tab
= create_new_tab(widget
, NULL
);
1697 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
1700 GtkDirSelection
* file_selector
= (GtkDirSelection
*)gtk_dir_selection_new("Select a trace");
1701 gtk_dir_selection_hide_fileop_buttons(file_selector
);
1703 if(remember_trace_dir
[0] != '\0')
1704 gtk_dir_selection_set_filename(file_selector
, remember_trace_dir
);
1706 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
1708 case GTK_RESPONSE_ACCEPT
:
1709 case GTK_RESPONSE_OK
:
1710 dir
= gtk_dir_selection_get_dir (file_selector
);
1711 strncpy(remember_trace_dir
, dir
, PATH_MAX
);
1712 if(!dir
|| strlen(dir
) == 0){
1713 gtk_widget_destroy((GtkWidget
*)file_selector
);
1716 get_absolute_pathname(dir
, abs_path
);
1717 trace_v
= lttvwindowtraces_get_trace_by_name(abs_path
);
1718 if(trace_v
== NULL
) {
1719 trace
= ltt_trace_open(abs_path
);
1721 g_warning("cannot open trace %s", abs_path
);
1723 trace_v
= lttv_trace_new(trace
);
1724 lttvwindowtraces_add_trace(trace_v
);
1725 lttvwindow_add_trace(tab
, trace_v
);
1728 lttvwindow_add_trace(tab
, trace_v
);
1731 gtk_widget_destroy((GtkWidget
*)file_selector
);
1733 //update current tab
1734 //update_traceset(mw_data);
1736 /* Call the updatetraceset hooks */
1738 traceset
= tab
->traceset_info
->traceset
;
1739 SetTraceset(tab
, traceset
);
1740 // in expose now call_pending_read_hooks(mw_data);
1742 //lttvwindow_report_current_time(mw_data,&(tab->current_time));
1744 case GTK_RESPONSE_REJECT
:
1745 case GTK_RESPONSE_CANCEL
:
1747 gtk_widget_destroy((GtkWidget
*)file_selector
);
1752 /* remove_trace removes a trace from the current traceset if all viewers in
1753 * the current tab are not interested in the trace. It first displays a
1754 * dialogue, which shows all traces in the current traceset, to let user choose
1755 * a trace, then it checks if all viewers unselect the trace, if it is true,
1756 * it will remove the trace, recreate the traceset_contex,
1757 * and redraws all the viewer of the current tab. If there is on trace in the
1758 * current traceset, it will delete all viewers of the current tab
1760 * It destroys the filter tree. FIXME... we should request for an update
1764 void remove_trace(GtkWidget
*widget
, gpointer user_data
)
1767 LttvTrace
* trace_v
;
1768 LttvTraceset
* traceset
;
1769 gint i
, j
, nb_trace
, index
=-1;
1770 char ** name
, *remove_trace_name
;
1771 MainWindow
* mw_data
= get_window_data_struct(widget
);
1772 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
1774 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
1775 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
1781 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
1784 nb_trace
=lttv_traceset_number(tab
->traceset_info
->traceset
);
1785 name
= g_new(char*,nb_trace
);
1786 for(i
= 0; i
< nb_trace
; i
++){
1787 trace_v
= lttv_traceset_get(tab
->traceset_info
->traceset
, i
);
1788 trace
= lttv_trace(trace_v
);
1789 name
[i
] = ltt_trace_name(trace
);
1792 remove_trace_name
= get_remove_trace(name
, nb_trace
);
1795 if(remove_trace_name
){
1797 /* yuk, cut n paste from old code.. should be better (MD)*/
1798 for(i
= 0; i
<nb_trace
; i
++) {
1799 if(strcmp(remove_trace_name
,name
[i
]) == 0){
1804 traceset
= tab
->traceset_info
->traceset
;
1805 //Keep a reference to the traces so they are not freed.
1806 for(j
=0; j
<lttv_traceset_number(traceset
); j
++)
1808 LttvTrace
* trace
= lttv_traceset_get(traceset
, j
);
1809 lttv_trace_ref(trace
);
1812 //remove state update hooks
1813 lttv_state_remove_event_hooks(
1814 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1815 lttv_context_fini(LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
));
1816 g_object_unref(tab
->traceset_info
->traceset_context
);
1818 trace_v
= lttv_traceset_get(traceset
, index
);
1820 lttv_traceset_remove(traceset
, index
);
1821 lttv_trace_unref(trace_v
); // Remove local reference
1823 if(lttv_trace_get_ref_number(trace_v
) <= 1) {
1824 /* ref 1 : lttvwindowtraces only*/
1825 ltt_trace_close(lttv_trace(trace_v
));
1826 /* lttvwindowtraces_remove_trace takes care of destroying
1827 * the traceset linked with the trace_v and also of destroying
1828 * the trace_v at the same time.
1830 lttvwindowtraces_remove_trace(trace_v
);
1833 tab
->traceset_info
->traceset_context
=
1834 g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
1836 LTTV_TRACESET_CONTEXT(tab
->
1837 traceset_info
->traceset_context
),traceset
);
1838 //add state update hooks
1839 lttv_state_add_event_hooks(
1840 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1842 //Remove local reference to the traces.
1843 for(j
=0; j
<lttv_traceset_number(traceset
); j
++)
1845 LttvTrace
* trace
= lttv_traceset_get(traceset
, j
);
1846 lttv_trace_unref(trace
);
1849 SetTraceset(tab
, (gpointer
)traceset
);
1855 void remove_trace(GtkWidget
* widget
, gpointer user_data
)
1858 LttvTrace
* trace_v
;
1859 LttvTraceset
* traceset
;
1860 gint i
, j
, nb_trace
;
1861 char ** name
, *remove_trace_name
;
1862 MainWindow
* mw_data
= get_window_data_struct(widget
);
1863 LttvTracesetSelector
* s
;
1864 LttvTraceSelector
* t
;
1867 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
1869 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
1870 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
1876 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
1879 nb_trace
=lttv_traceset_number(tab
->traceset_info
->traceset
);
1880 name
= g_new(char*,nb_trace
);
1881 for(i
= 0; i
< nb_trace
; i
++){
1882 trace_v
= lttv_traceset_get(tab
->traceset_info
->traceset
, i
);
1883 trace
= lttv_trace(trace_v
);
1884 name
[i
] = ltt_trace_name(trace
);
1887 remove_trace_name
= get_remove_trace(name
, nb_trace
);
1889 if(remove_trace_name
){
1890 for(i
=0; i
<nb_trace
; i
++){
1891 if(strcmp(remove_trace_name
,name
[i
]) == 0){
1892 //unselect the trace from the current viewer
1894 w
= gtk_multivpaned_get_widget(GTK_MULTIVPANED(tab
->multivpaned
));
1896 s
= g_object_get_data(G_OBJECT(w
), "Traceset_Selector");
1898 t
= lttv_traceset_selector_trace_get(s
,i
);
1899 lttv_trace_selector_set_selected(t
, FALSE
);
1902 //check if other viewers select the trace
1903 w
= gtk_multivpaned_get_first_widget(GTK_MULTIVPANED(tab
->multivpaned
));
1905 s
= g_object_get_data(G_OBJECT(w
), "Traceset_Selector");
1907 t
= lttv_traceset_selector_trace_get(s
,i
);
1908 selected
= lttv_trace_selector_get_selected(t
);
1911 w
= gtk_multivpaned_get_next_widget(GTK_MULTIVPANED(tab
->multivpaned
));
1913 }else selected
= FALSE
;
1915 //if no viewer selects the trace, remove it
1917 remove_trace_from_traceset_selector(GTK_MULTIVPANED(tab
->multivpaned
), i
);
1919 traceset
= tab
->traceset_info
->traceset
;
1920 //Keep a reference to the traces so they are not freed.
1921 for(j
=0; j
<lttv_traceset_number(traceset
); j
++)
1923 LttvTrace
* trace
= lttv_traceset_get(traceset
, j
);
1924 lttv_trace_ref(trace
);
1927 //remove state update hooks
1928 lttv_state_remove_event_hooks(
1929 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1930 lttv_context_fini(LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
));
1931 g_object_unref(tab
->traceset_info
->traceset_context
);
1934 trace_v
= lttv_traceset_get(traceset
, i
);
1936 if(lttv_trace_get_ref_number(trace_v
) <= 2) {
1937 /* ref 2 : traceset, local */
1938 lttvwindowtraces_remove_trace(trace_v
);
1939 ltt_trace_close(lttv_trace(trace_v
));
1942 lttv_traceset_remove(traceset
, i
);
1943 lttv_trace_unref(trace_v
); // Remove local reference
1945 if(!lttv_trace_get_ref_number(trace_v
))
1946 lttv_trace_destroy(trace_v
);
1948 tab
->traceset_info
->traceset_context
=
1949 g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
1951 LTTV_TRACESET_CONTEXT(tab
->
1952 traceset_info
->traceset_context
),traceset
);
1953 //add state update hooks
1954 lttv_state_add_event_hooks(
1955 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1957 //Remove local reference to the traces.
1958 for(j
=0; j
<lttv_traceset_number(traceset
); j
++)
1960 LttvTrace
* trace
= lttv_traceset_get(traceset
, j
);
1961 lttv_trace_unref(trace
);
1965 //update current tab
1966 //update_traceset(mw_data);
1969 SetTraceset(tab
, (gpointer
)traceset
);
1970 // in expose now call_pending_read_hooks(mw_data);
1972 //lttvwindow_report_current_time(mw_data,&(tab->current_time));
1975 // while(tab->multi_vpaned->num_children){
1976 // gtk_multi_vpaned_widget_delete(tab->multi_vpaned);
1990 /* Redraw all the viewers in the current tab */
1991 void redraw(GtkWidget
*widget
, gpointer user_data
)
1993 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
1994 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
1995 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2000 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
2004 LttvAttributeValue value
;
2006 g_assert(lttv_iattribute_find_by_path(tab
->attributes
, "hooks/redraw", LTTV_POINTER
, &value
));
2008 tmp
= (LttvHooks
*)*(value
.v_pointer
);
2010 lttv_hooks_call(tmp
,NULL
);
2014 void continue_processing(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
,
2030 "hooks/continue", LTTV_POINTER
, &value
));
2032 tmp
= (LttvHooks
*)*(value
.v_pointer
);
2034 lttv_hooks_call(tmp
,NULL
);
2037 /* Stop the processing for the calling main window's current tab.
2038 * It removes every processing requests that are in its list. It does not call
2039 * the end request hooks, because the request is not finished.
2042 void stop_processing(GtkWidget
*widget
, gpointer user_data
)
2044 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
2045 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2046 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2051 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
2053 GSList
*iter
= tab
->events_requests
;
2055 while(iter
!= NULL
) {
2056 GSList
*remove_iter
= iter
;
2057 iter
= g_slist_next(iter
);
2059 g_free(remove_iter
->data
);
2060 tab
->events_requests
=
2061 g_slist_remove_link(tab
->events_requests
, remove_iter
);
2063 tab
->events_request_pending
= FALSE
;
2064 g_idle_remove_by_data(tab
);
2065 g_assert(g_slist_length(tab
->events_requests
) == 0);
2069 /* save will save the traceset to a file
2070 * Not implemented yet FIXME
2073 void save(GtkWidget
* widget
, gpointer user_data
)
2078 void save_as(GtkWidget
* widget
, gpointer user_data
)
2080 g_info("Save as\n");
2084 /* zoom will change the time_window of all the viewers of the
2085 * current tab, and redisplay them. The main functionality is to
2086 * determine the new time_window of the current tab
2089 void zoom(GtkWidget
* widget
, double size
)
2091 TimeInterval time_span
;
2092 TimeWindow new_time_window
;
2093 LttTime current_time
, time_delta
;
2094 MainWindow
* mw_data
= get_window_data_struct(widget
);
2095 LttvTracesetContext
*tsc
;
2096 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
2098 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2099 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2105 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
2108 if(size
== 1) return;
2110 tsc
= LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
2111 time_span
= tsc
->time_span
;
2112 new_time_window
= tab
->time_window
;
2113 current_time
= tab
->current_time
;
2115 time_delta
= ltt_time_sub(time_span
.end_time
,time_span
.start_time
);
2117 new_time_window
.start_time
= time_span
.start_time
;
2118 new_time_window
.time_width
= time_delta
;
2119 new_time_window
.time_width_double
= ltt_time_to_double(time_delta
);
2120 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
2121 new_time_window
.time_width
) ;
2123 new_time_window
.time_width
= ltt_time_div(new_time_window
.time_width
, size
);
2124 new_time_window
.time_width_double
=
2125 ltt_time_to_double(new_time_window
.time_width
);
2126 if(ltt_time_compare(new_time_window
.time_width
,time_delta
) > 0)
2127 { /* Case where zoom out is bigger than trace length */
2128 new_time_window
.start_time
= time_span
.start_time
;
2129 new_time_window
.time_width
= time_delta
;
2130 new_time_window
.time_width_double
= ltt_time_to_double(time_delta
);
2131 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
2132 new_time_window
.time_width
) ;
2136 /* Center the image on the current time */
2137 new_time_window
.start_time
=
2138 ltt_time_sub(current_time
,
2139 ltt_time_from_double(new_time_window
.time_width_double
/2.0));
2140 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
2141 new_time_window
.time_width
) ;
2142 /* If on borders, don't fall off */
2143 if(ltt_time_compare(new_time_window
.start_time
, time_span
.start_time
) <0)
2145 new_time_window
.start_time
= time_span
.start_time
;
2146 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
2147 new_time_window
.time_width
) ;
2151 if(ltt_time_compare(new_time_window
.end_time
,
2152 time_span
.end_time
) > 0)
2154 new_time_window
.start_time
=
2155 ltt_time_sub(time_span
.end_time
, new_time_window
.time_width
);
2157 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
2158 new_time_window
.time_width
) ;
2165 if(ltt_time_compare(new_time_window
.time_width
, ltt_time_zero
) == 0) {
2166 g_warning("Zoom more than 1 ns impossible");
2168 time_change_manager(tab
, new_time_window
);
2172 void zoom_in(GtkWidget
* widget
, gpointer user_data
)
2177 void zoom_out(GtkWidget
* widget
, gpointer user_data
)
2182 void zoom_extended(GtkWidget
* widget
, gpointer user_data
)
2187 void go_to_time(GtkWidget
* widget
, gpointer user_data
)
2189 g_info("Go to time\n");
2192 void show_time_frame(GtkWidget
* widget
, gpointer user_data
)
2194 g_info("Show time frame\n");
2198 /* callback function */
2201 on_empty_traceset_activate (GtkMenuItem
*menuitem
,
2204 create_new_window((GtkWidget
*)menuitem
, user_data
, FALSE
);
2209 on_clone_traceset_activate (GtkMenuItem
*menuitem
,
2212 create_new_window((GtkWidget
*)menuitem
, user_data
, TRUE
);
2216 /* create_new_tab calls create_tab to construct a new tab in the main window
2219 Tab
*create_new_tab(GtkWidget
* widget
, gpointer user_data
){
2220 gchar label
[PATH_MAX
];
2221 MainWindow
* mw_data
= get_window_data_struct(widget
);
2223 GtkNotebook
* notebook
= (GtkNotebook
*)lookup_widget(widget
, "MNotebook");
2224 if(notebook
== NULL
){
2225 g_info("Notebook does not exist\n");
2228 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2229 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2235 copy_tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
2238 strcpy(label
,"Page");
2239 if(get_label(mw_data
, label
,"Get the name of the tab","Please input tab's name"))
2240 return (create_tab (mw_data
, copy_tab
, notebook
, label
));
2246 on_tab_activate (GtkMenuItem
*menuitem
,
2249 create_new_tab((GtkWidget
*)menuitem
, user_data
);
2254 on_open_activate (GtkMenuItem
*menuitem
,
2257 open_traceset((GtkWidget
*)menuitem
, user_data
);
2262 on_close_activate (GtkMenuItem
*menuitem
,
2265 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2266 main_window_destructor(mw_data
);
2270 /* remove the current tab from the main window
2274 on_close_tab_activate (GtkWidget
*widget
,
2278 GtkWidget
* notebook
;
2280 MainWindow
* mw_data
= get_window_data_struct(widget
);
2281 notebook
= lookup_widget(widget
, "MNotebook");
2282 if(notebook
== NULL
){
2283 g_info("Notebook does not exist\n");
2287 page_num
= gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
));
2289 gtk_notebook_remove_page(GTK_NOTEBOOK(notebook
), page_num
);
2294 on_close_tab_X_clicked (GtkWidget
*widget
,
2298 GtkWidget
*notebook
= lookup_widget(widget
, "MNotebook");
2299 if(notebook
== NULL
){
2300 g_info("Notebook does not exist\n");
2304 if((page_num
= gtk_notebook_page_num(GTK_NOTEBOOK(notebook
), widget
)) != -1)
2305 gtk_notebook_remove_page(GTK_NOTEBOOK(notebook
), page_num
);
2311 on_add_trace_activate (GtkMenuItem
*menuitem
,
2314 add_trace((GtkWidget
*)menuitem
, user_data
);
2319 on_remove_trace_activate (GtkMenuItem
*menuitem
,
2322 remove_trace((GtkWidget
*)menuitem
, user_data
);
2327 on_save_activate (GtkMenuItem
*menuitem
,
2330 save((GtkWidget
*)menuitem
, user_data
);
2335 on_save_as_activate (GtkMenuItem
*menuitem
,
2338 save_as((GtkWidget
*)menuitem
, user_data
);
2343 on_quit_activate (GtkMenuItem
*menuitem
,
2351 on_cut_activate (GtkMenuItem
*menuitem
,
2359 on_copy_activate (GtkMenuItem
*menuitem
,
2367 on_paste_activate (GtkMenuItem
*menuitem
,
2375 on_delete_activate (GtkMenuItem
*menuitem
,
2383 on_zoom_in_activate (GtkMenuItem
*menuitem
,
2386 zoom_in((GtkWidget
*)menuitem
, user_data
);
2391 on_zoom_out_activate (GtkMenuItem
*menuitem
,
2394 zoom_out((GtkWidget
*)menuitem
, user_data
);
2399 on_zoom_extended_activate (GtkMenuItem
*menuitem
,
2402 zoom_extended((GtkWidget
*)menuitem
, user_data
);
2407 on_go_to_time_activate (GtkMenuItem
*menuitem
,
2410 go_to_time((GtkWidget
*)menuitem
, user_data
);
2415 on_show_time_frame_activate (GtkMenuItem
*menuitem
,
2418 show_time_frame((GtkWidget
*)menuitem
, user_data
);
2423 on_move_viewer_up_activate (GtkMenuItem
*menuitem
,
2426 move_up_viewer((GtkWidget
*)menuitem
, user_data
);
2431 on_move_viewer_down_activate (GtkMenuItem
*menuitem
,
2434 move_down_viewer((GtkWidget
*)menuitem
, user_data
);
2439 on_remove_viewer_activate (GtkMenuItem
*menuitem
,
2442 delete_viewer((GtkWidget
*)menuitem
, user_data
);
2446 on_trace_facility_activate (GtkMenuItem
*menuitem
,
2449 g_info("Trace facility selector: %s\n");
2453 /* Dispaly a file selection dialogue to let user select a library, then call
2454 * lttv_library_load().
2458 on_load_library_activate (GtkMenuItem
*menuitem
,
2461 GError
*error
= NULL
;
2462 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2464 gchar load_module_path_alter
[PATH_MAX
];
2468 gchar
*load_module_path
;
2469 name
= g_ptr_array_new();
2470 nb
= lttv_library_path_number();
2471 /* ask for the library path */
2475 path
= lttv_library_path_get(i
);
2476 g_ptr_array_add(name
, path
);
2479 load_module_path
= get_selection((char **)(name
->pdata
), name
->len
,
2480 "Select a library path", "Library paths");
2481 if(load_module_path
!= NULL
)
2482 strncpy(load_module_path_alter
, load_module_path
, PATH_MAX
-1); // -1 for /
2484 g_ptr_array_free(name
, TRUE
);
2486 if(load_module_path
== NULL
) return;
2490 /* Make sure the module path ends with a / */
2491 gchar
*ptr
= load_module_path_alter
;
2493 ptr
= strchr(ptr
, '\0');
2495 if(*(ptr
-1) != '/') {
2502 /* Ask for the library to load : list files in the previously selected
2504 gchar str
[PATH_MAX
];
2507 GtkFileSelection
* file_selector
=
2508 (GtkFileSelection
*)gtk_file_selection_new("Select a module");
2509 gtk_file_selection_set_filename(file_selector
, load_module_path_alter
);
2510 gtk_file_selection_hide_fileop_buttons(file_selector
);
2513 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
2515 case GTK_RESPONSE_ACCEPT
:
2516 case GTK_RESPONSE_OK
:
2517 dir
= gtk_file_selection_get_selections (file_selector
);
2518 strncpy(str
,dir
[0],PATH_MAX
);
2519 strncpy(remember_plugins_dir
,dir
[0],PATH_MAX
);
2520 /* only keep file name */
2522 str1
= strrchr(str
,'/');
2525 str1
= strrchr(str
,'\\');
2530 if(*str1
== 'l' && *(str1
+1)== 'i' && *(str1
+2)=='b')
2532 remove info after
. */
2536 str2
= strrchr(str2
, '.');
2537 if(str2
!= NULL
) *str2
= '\0';
2539 lttv_module_require(str1
, &error
);
2541 lttv_library_load(str1
, &error
);
2542 if(error
!= NULL
) g_warning("%s", error
->message
);
2543 else g_info("Load library: %s\n", str
);
2545 case GTK_RESPONSE_REJECT
:
2546 case GTK_RESPONSE_CANCEL
:
2548 gtk_widget_destroy((GtkWidget
*)file_selector
);
2559 /* Display all loaded modules, let user to select a module to unload
2560 * by calling lttv_module_unload
2564 on_unload_library_activate (GtkMenuItem
*menuitem
,
2567 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2569 LttvLibrary
*library
= NULL
;
2574 name
= g_ptr_array_new();
2575 nb
= lttv_library_number();
2576 LttvLibraryInfo
*lib_info
= g_new(LttvLibraryInfo
,nb
);
2577 /* ask for the library name */
2580 LttvLibrary
*iter_lib
= lttv_library_get(i
);
2581 lttv_library_info(iter_lib
, &lib_info
[i
]);
2583 gchar
*path
= lib_info
[i
].name
;
2584 g_ptr_array_add(name
, path
);
2586 lib_name
= get_selection((char **)(name
->pdata
), name
->len
,
2587 "Select a library", "Libraries");
2588 if(lib_name
!= NULL
) {
2590 if(strcmp(lib_name
, lib_info
[i
].name
) == 0) {
2591 library
= lttv_library_get(i
);
2596 g_ptr_array_free(name
, TRUE
);
2599 if(lib_name
== NULL
) return;
2601 if(library
!= NULL
) lttv_library_unload(library
);
2605 /* Dispaly a file selection dialogue to let user select a module, then call
2606 * lttv_module_require().
2610 on_load_module_activate (GtkMenuItem
*menuitem
,
2613 GError
*error
= NULL
;
2614 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2616 LttvLibrary
*library
= NULL
;
2621 name
= g_ptr_array_new();
2622 nb
= lttv_library_number();
2623 LttvLibraryInfo
*lib_info
= g_new(LttvLibraryInfo
,nb
);
2624 /* ask for the library name */
2627 LttvLibrary
*iter_lib
= lttv_library_get(i
);
2628 lttv_library_info(iter_lib
, &lib_info
[i
]);
2630 gchar
*path
= lib_info
[i
].name
;
2631 g_ptr_array_add(name
, path
);
2633 lib_name
= get_selection((char **)(name
->pdata
), name
->len
,
2634 "Select a library", "Libraries");
2635 if(lib_name
!= NULL
) {
2637 if(strcmp(lib_name
, lib_info
[i
].name
) == 0) {
2638 library
= lttv_library_get(i
);
2643 g_ptr_array_free(name
, TRUE
);
2646 if(lib_name
== NULL
) return;
2649 //LttvModule *module;
2650 gchar module_name_out
[PATH_MAX
];
2652 /* Ask for the module to load : list modules in the selected lib */
2656 nb
= lttv_library_module_number(library
);
2657 LttvModuleInfo
*module_info
= g_new(LttvModuleInfo
,nb
);
2658 name
= g_ptr_array_new();
2659 /* ask for the module name */
2662 LttvModule
*iter_module
= lttv_library_module_get(library
, i
);
2663 lttv_module_info(iter_module
, &module_info
[i
]);
2665 gchar
*path
= module_info
[i
].name
;
2666 g_ptr_array_add(name
, path
);
2668 module_name
= get_selection((char **)(name
->pdata
), name
->len
,
2669 "Select a module", "Modules");
2670 if(module_name
!= NULL
) {
2672 if(strcmp(module_name
, module_info
[i
].name
) == 0) {
2673 strncpy(module_name_out
, module_name
, PATH_MAX
);
2674 //module = lttv_library_module_get(i);
2680 g_ptr_array_free(name
, TRUE
);
2681 g_free(module_info
);
2683 if(module_name
== NULL
) return;
2686 lttv_module_require(module_name_out
, &error
);
2687 if(error
!= NULL
) g_warning("%s", error
->message
);
2688 else g_info("Load module: %s", module_name_out
);
2695 gchar str
[PATH_MAX
];
2698 GtkFileSelection
* file_selector
=
2699 (GtkFileSelection
*)gtk_file_selection_new("Select a module");
2700 gtk_file_selection_set_filename(file_selector
, load_module_path_alter
);
2701 gtk_file_selection_hide_fileop_buttons(file_selector
);
2704 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
2706 case GTK_RESPONSE_ACCEPT
:
2707 case GTK_RESPONSE_OK
:
2708 dir
= gtk_file_selection_get_selections (file_selector
);
2709 strncpy(str
,dir
[0],PATH_MAX
);
2710 strncpy(remember_plugins_dir
,dir
[0],PATH_MAX
);
2712 /* only keep file name */
2714 str1
= strrchr(str
,'/');
2717 str1
= strrchr(str
,'\\');
2722 if(*str1
== 'l' && *(str1
+1)== 'i' && *(str1
+2)=='b')
2724 remove info after
. */
2728 str2
= strrchr(str2
, '.');
2729 if(str2
!= NULL
) *str2
= '\0';
2731 lttv_module_require(str1
, &error
);
2733 lttv_library_load(str1
, &error
);
2734 if(error
!= NULL
) g_warning(error
->message
);
2735 else g_info("Load library: %s\n", str
);
2737 case GTK_RESPONSE_REJECT
:
2738 case GTK_RESPONSE_CANCEL
:
2740 gtk_widget_destroy((GtkWidget
*)file_selector
);
2752 /* Display all loaded modules, let user to select a module to unload
2753 * by calling lttv_module_unload
2757 on_unload_module_activate (GtkMenuItem
*menuitem
,
2760 GError
*error
= NULL
;
2761 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2763 LttvLibrary
*library
;
2768 name
= g_ptr_array_new();
2769 nb
= lttv_library_number();
2770 LttvLibraryInfo
*lib_info
= g_new(LttvLibraryInfo
,nb
);
2771 /* ask for the library name */
2774 LttvLibrary
*iter_lib
= lttv_library_get(i
);
2775 lttv_library_info(iter_lib
, &lib_info
[i
]);
2777 gchar
*path
= lib_info
[i
].name
;
2778 g_ptr_array_add(name
, path
);
2780 lib_name
= get_selection((char **)(name
->pdata
), name
->len
,
2781 "Select a library", "Libraries");
2782 if(lib_name
!= NULL
) {
2784 if(strcmp(lib_name
, lib_info
[i
].name
) == 0) {
2785 library
= lttv_library_get(i
);
2790 g_ptr_array_free(name
, TRUE
);
2793 if(lib_name
== NULL
) return;
2796 LttvModule
*module
= NULL
;
2798 /* Ask for the module to load : list modules in the selected lib */
2802 nb
= lttv_library_module_number(library
);
2803 LttvModuleInfo
*module_info
= g_new(LttvModuleInfo
,nb
);
2804 name
= g_ptr_array_new();
2805 /* ask for the module name */
2808 LttvModule
*iter_module
= lttv_library_module_get(library
, i
);
2809 lttv_module_info(iter_module
, &module_info
[i
]);
2811 gchar
*path
= module_info
[i
].name
;
2812 if(module_info
[i
].use_count
> 0) g_ptr_array_add(name
, path
);
2814 module_name
= get_selection((char **)(name
->pdata
), name
->len
,
2815 "Select a module", "Modules");
2816 if(module_name
!= NULL
) {
2818 if(strcmp(module_name
, module_info
[i
].name
) == 0) {
2819 module
= lttv_library_module_get(library
, i
);
2825 g_ptr_array_free(name
, TRUE
);
2826 g_free(module_info
);
2828 if(module_name
== NULL
) return;
2831 LttvModuleInfo module_info
;
2832 lttv_module_info(module
, &module_info
);
2833 g_info("Release module: %s\n", module_info
.name
);
2835 lttv_module_release(module
);
2839 /* Display a directory dialogue to let user select a path for library searching
2843 on_add_library_search_path_activate (GtkMenuItem
*menuitem
,
2846 GtkDirSelection
* file_selector
= (GtkDirSelection
*)gtk_dir_selection_new("Select library path");
2850 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2851 if(remember_plugins_dir
[0] != '\0')
2852 gtk_dir_selection_set_filename(file_selector
, remember_plugins_dir
);
2854 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
2856 case GTK_RESPONSE_ACCEPT
:
2857 case GTK_RESPONSE_OK
:
2858 dir
= gtk_dir_selection_get_dir (file_selector
);
2859 strncpy(remember_plugins_dir
,dir
,PATH_MAX
);
2860 strncat(remember_plugins_dir
,"/",PATH_MAX
);
2861 lttv_library_path_add(dir
);
2862 case GTK_RESPONSE_REJECT
:
2863 case GTK_RESPONSE_CANCEL
:
2865 gtk_widget_destroy((GtkWidget
*)file_selector
);
2871 /* Display a directory dialogue to let user select a path for library searching
2875 on_remove_library_search_path_activate (GtkMenuItem
*menuitem
,
2878 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2880 const char *lib_path
;
2885 name
= g_ptr_array_new();
2886 nb
= lttv_library_path_number();
2887 /* ask for the library name */
2890 gchar
*path
= lttv_library_path_get(i
);
2891 g_ptr_array_add(name
, path
);
2893 lib_path
= get_selection((char **)(name
->pdata
), name
->len
,
2894 "Select a library path", "Library paths");
2896 g_ptr_array_free(name
, TRUE
);
2898 if(lib_path
== NULL
) return;
2901 lttv_library_path_remove(lib_path
);
2905 on_color_activate (GtkMenuItem
*menuitem
,
2913 on_save_configuration_activate (GtkMenuItem
*menuitem
,
2916 g_info("Save configuration\n");
2921 on_content_activate (GtkMenuItem
*menuitem
,
2924 g_info("Content\n");
2929 on_about_close_activate (GtkButton
*button
,
2932 GtkWidget
*about_widget
= GTK_WIDGET(user_data
);
2934 gtk_widget_destroy(about_widget
);
2938 on_about_activate (GtkMenuItem
*menuitem
,
2941 MainWindow
*main_window
= get_window_data_struct(GTK_WIDGET(menuitem
));
2942 GtkWidget
*window_widget
= main_window
->mwindow
;
2943 GtkWidget
*about_widget
= gtk_window_new(GTK_WINDOW_TOPLEVEL
);
2944 GtkWindow
*about_window
= GTK_WINDOW(about_widget
);
2945 gint window_width
, window_height
;
2947 gtk_window_set_title(about_window
, "About Linux Trace Toolkit");
2949 gtk_window_set_resizable(about_window
, FALSE
);
2950 gtk_window_set_transient_for(GTK_WINDOW(window_widget
), about_window
);
2951 gtk_window_set_destroy_with_parent(about_window
, TRUE
);
2952 gtk_window_set_modal(about_window
, FALSE
);
2954 /* Put the about window at the center of the screen */
2955 gtk_window_get_size(about_window
, &window_width
, &window_height
);
2956 gtk_window_move (about_window
,
2957 (gdk_screen_width() - window_width
)/2,
2958 (gdk_screen_height() - window_height
)/2);
2960 GtkWidget
*vbox
= gtk_vbox_new(FALSE
, 1);
2962 gtk_container_add(GTK_CONTAINER(about_widget
), vbox
);
2966 GtkWidget
*label1
= gtk_label_new("");
2967 gtk_misc_set_padding(GTK_MISC(label1
), 10, 20);
2968 gtk_label_set_markup(GTK_LABEL(label1
), "\
2969 <big>Linux Trace Toolkit</big>");
2970 gtk_label_set_justify(GTK_LABEL(label1
), GTK_JUSTIFY_CENTER
);
2972 GtkWidget
*label2
= gtk_label_new("");
2973 gtk_misc_set_padding(GTK_MISC(label2
), 10, 20);
2974 gtk_label_set_markup(GTK_LABEL(label2
), "\
2977 Michel Dagenais (New trace format, lttv main)\n\
2978 Mathieu Desnoyers (Directory structure, build with automake/conf,\n\
2979 lttv gui, control flow view, gui cooperative trace reading\n\
2980 scheduler with interruptible foreground and background\n\
2981 computation, detailed event list)\n\
2982 Benoit Des Ligneris, Eric Clement (Cluster adaptation, work in progress)\n\
2983 Xang-Xiu Yang (new trace reading library and converter, lttv gui, \n\
2984 detailed event list and statistics view)\n\
2985 Tom Zanussi (RelayFS)\n\
2987 Strongly inspired from the original Linux Trace Toolkit Visualizer made by\n\
2990 GtkWidget
*label3
= gtk_label_new("");
2991 gtk_label_set_markup(GTK_LABEL(label3
), "\
2992 Linux Trace Toolkit Viewer, Copyright (C) 2004\n\
2994 Mathieu Desnoyers\n\
2996 Linux Trace Toolkit comes with ABSOLUTELY NO WARRANTY.\n\
2997 This is free software, and you are welcome to redistribute it\n\
2998 under certain conditions. See COPYING for details.");
2999 gtk_misc_set_padding(GTK_MISC(label3
), 10, 20);
3001 gtk_box_pack_start_defaults(GTK_BOX(vbox
), label1
);
3002 gtk_box_pack_start_defaults(GTK_BOX(vbox
), label2
);
3003 gtk_box_pack_start_defaults(GTK_BOX(vbox
), label3
);
3005 GtkWidget
*hbox
= gtk_hbox_new(TRUE
, 0);
3006 gtk_box_pack_end(GTK_BOX(vbox
), hbox
, FALSE
, FALSE
, 0);
3007 GtkWidget
*close_button
= gtk_button_new_with_mnemonic("_Close");
3008 gtk_box_pack_end(GTK_BOX(hbox
), close_button
, FALSE
, FALSE
, 0);
3009 gtk_container_set_border_width(GTK_CONTAINER(close_button
), 20);
3011 g_signal_connect(G_OBJECT(close_button
), "clicked",
3012 G_CALLBACK(on_about_close_activate
),
3013 (gpointer
)about_widget
);
3015 gtk_widget_show_all(about_widget
);
3020 on_button_new_clicked (GtkButton
*button
,
3023 create_new_window((GtkWidget
*)button
, user_data
, TRUE
);
3027 on_button_new_tab_clicked (GtkButton
*button
,
3030 create_new_tab((GtkWidget
*)button
, user_data
);
3034 on_button_open_clicked (GtkButton
*button
,
3037 open_traceset((GtkWidget
*)button
, user_data
);
3042 on_button_add_trace_clicked (GtkButton
*button
,
3045 add_trace((GtkWidget
*)button
, user_data
);
3050 on_button_remove_trace_clicked (GtkButton
*button
,
3053 remove_trace((GtkWidget
*)button
, user_data
);
3057 on_button_redraw_clicked (GtkButton
*button
,
3060 redraw((GtkWidget
*)button
, user_data
);
3064 on_button_continue_processing_clicked (GtkButton
*button
,
3067 continue_processing((GtkWidget
*)button
, user_data
);
3071 on_button_stop_processing_clicked (GtkButton
*button
,
3074 stop_processing((GtkWidget
*)button
, user_data
);
3080 on_button_save_clicked (GtkButton
*button
,
3083 save((GtkWidget
*)button
, user_data
);
3088 on_button_save_as_clicked (GtkButton
*button
,
3091 save_as((GtkWidget
*)button
, user_data
);
3096 on_button_zoom_in_clicked (GtkButton
*button
,
3099 zoom_in((GtkWidget
*)button
, user_data
);
3104 on_button_zoom_out_clicked (GtkButton
*button
,
3107 zoom_out((GtkWidget
*)button
, user_data
);
3112 on_button_zoom_extended_clicked (GtkButton
*button
,
3115 zoom_extended((GtkWidget
*)button
, user_data
);
3120 on_button_go_to_time_clicked (GtkButton
*button
,
3123 go_to_time((GtkWidget
*)button
, user_data
);
3128 on_button_show_time_frame_clicked (GtkButton
*button
,
3131 show_time_frame((GtkWidget
*)button
, user_data
);
3136 on_button_move_up_clicked (GtkButton
*button
,
3139 move_up_viewer((GtkWidget
*)button
, user_data
);
3144 on_button_move_down_clicked (GtkButton
*button
,
3147 move_down_viewer((GtkWidget
*)button
, user_data
);
3152 on_button_delete_viewer_clicked (GtkButton
*button
,
3155 delete_viewer((GtkWidget
*)button
, user_data
);
3159 on_MWindow_destroy (GtkWidget
*widget
,
3162 MainWindow
*main_window
= get_window_data_struct(widget
);
3163 LttvIAttribute
*attributes
= main_window
->attributes
;
3164 LttvAttributeValue value
;
3166 //This is unnecessary, since widgets will be destroyed
3167 //by the main window widget anyway.
3168 //remove_all_menu_toolbar_constructors(main_window, NULL);
3170 g_assert(lttv_iattribute_find_by_path(attributes
,
3171 "viewers/menu", LTTV_POINTER
, &value
));
3172 lttv_menus_destroy((LttvMenus
*)*(value
.v_pointer
));
3174 g_assert(lttv_iattribute_find_by_path(attributes
,
3175 "viewers/toolbar", LTTV_POINTER
, &value
));
3176 lttv_toolbars_destroy((LttvToolbars
*)*(value
.v_pointer
));
3178 g_object_unref(main_window
->attributes
);
3179 g_main_window_list
= g_slist_remove(g_main_window_list
, main_window
);
3181 g_info("There are now : %d windows\n",g_slist_length(g_main_window_list
));
3182 if(g_slist_length(g_main_window_list
) == 0)
3187 on_MWindow_configure (GtkWidget
*widget
,
3188 GdkEventConfigure
*event
,
3191 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)widget
);
3193 // MD : removed time width modification upon resizing of the main window.
3194 // The viewers will redraw themselves completely, without time interval
3197 if(mw_data->window_width){
3198 time_span = LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context)->Time_Span ;
3199 time_win = tab->time_window;
3200 ratio = width / mw_data->window_width;
3201 tab->time_window.time_width = ltt_time_mul(time_win.time_width,ratio);
3202 time = ltt_time_sub(time_span->endTime, time_win.start_time);
3203 if(ltt_time_compare(time, tab->time_window.time_width) < 0){
3204 tab->time_window.time_width = time;
3210 mw_data->window_width = (int)width;
3219 on_MNotebook_switch_page (GtkNotebook
*notebook
,
3220 GtkNotebookPage
*page
,
3228 void time_change_manager (Tab
*tab
,
3229 TimeWindow new_time_window
)
3231 /* Only one source of time change */
3232 if(tab
->time_manager_lock
== TRUE
) return;
3234 tab
->time_manager_lock
= TRUE
;
3236 LttvTracesetContext
*tsc
= LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3237 TimeInterval time_span
= tsc
->time_span
;
3238 LttTime start_time
= new_time_window
.start_time
;
3239 LttTime end_time
= new_time_window
.end_time
;
3242 GtkAdjustment
*adjustment
= gtk_range_get_adjustment(GTK_RANGE(tab
->scrollbar
));
3243 LttTime upper
= ltt_time_sub(time_span
.end_time
, time_span
.start_time
);
3245 gtk_range_set_increments(GTK_RANGE(tab
->scrollbar
),
3246 ltt_time_to_double(new_time_window
.time_width
)
3247 / SCROLL_STEP_PER_PAGE
3248 * NANOSECONDS_PER_SECOND
, /* step increment */
3249 ltt_time_to_double(new_time_window
.time_width
)
3250 * NANOSECONDS_PER_SECOND
); /* page increment */
3251 gtk_range_set_range(GTK_RANGE(tab
->scrollbar
),
3253 ltt_time_to_double(upper
)
3254 * NANOSECONDS_PER_SECOND
); /* upper */
3256 g_object_set(G_OBJECT(adjustment
),
3260 ltt_time_to_double(upper
), /* upper */
3262 new_time_window
.time_width_double
3263 / SCROLL_STEP_PER_PAGE
, /* step increment */
3265 new_time_window
.time_width_double
,
3266 /* page increment */
3268 new_time_window
.time_width_double
, /* page size */
3270 gtk_adjustment_changed(adjustment
);
3272 // g_object_set(G_OBJECT(adjustment),
3274 // ltt_time_to_double(
3275 // ltt_time_sub(start_time, time_span.start_time))
3278 //gtk_adjustment_value_changed(adjustment);
3279 gtk_range_set_value(GTK_RANGE(tab
->scrollbar
),
3281 ltt_time_sub(start_time
, time_span
.start_time
)) /* value */);
3283 /* set the time bar. */
3285 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry1
),
3286 (double)time_span
.start_time
.tv_sec
,
3287 (double)time_span
.end_time
.tv_sec
);
3288 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry1
),
3289 (double)start_time
.tv_sec
);
3291 /* start nanoseconds */
3292 if(start_time
.tv_sec
== time_span
.start_time
.tv_sec
) {
3293 /* can be both beginning and end at the same time. */
3294 if(start_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3295 /* If we are at the end, max nsec to end.. -1 (not zero length) */
3296 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry2
),
3297 (double)time_span
.start_time
.tv_nsec
,
3298 (double)time_span
.end_time
.tv_nsec
-1);
3300 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry2
),
3301 (double)time_span
.start_time
.tv_nsec
,
3302 (double)NANOSECONDS_PER_SECOND
-1);
3304 } else if(start_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3305 /* If we are at the end, max nsec to end.. -1 (not zero length) */
3306 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry2
),
3308 (double)time_span
.end_time
.tv_nsec
-1);
3309 } else /* anywhere else */
3310 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry2
),
3312 (double)NANOSECONDS_PER_SECOND
-1);
3313 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry2
),
3314 (double)start_time
.tv_nsec
);
3317 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry3
),
3318 (double)time_span
.start_time
.tv_sec
,
3319 (double)time_span
.end_time
.tv_sec
);
3320 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry3
),
3321 (double)end_time
.tv_sec
);
3323 /* end nanoseconds */
3324 if(end_time
.tv_sec
== time_span
.start_time
.tv_sec
) {
3325 /* can be both beginning and end at the same time. */
3326 if(end_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3327 /* If we are at the end, max nsec to end.. */
3328 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry4
),
3329 (double)time_span
.start_time
.tv_nsec
+1,
3330 (double)time_span
.end_time
.tv_nsec
);
3332 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry4
),
3333 (double)time_span
.start_time
.tv_nsec
+1,
3334 (double)NANOSECONDS_PER_SECOND
-1);
3337 else if(end_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3338 /* If we are at the end, max nsec to end.. */
3339 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry4
),
3341 (double)time_span
.end_time
.tv_nsec
);
3343 else /* anywhere else */
3344 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry4
),
3346 (double)NANOSECONDS_PER_SECOND
-1);
3347 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry4
),
3348 (double)end_time
.tv_nsec
);
3350 /* call viewer hooks for new time window */
3351 set_time_window(tab
, &new_time_window
);
3353 tab
->time_manager_lock
= FALSE
;
3357 /* value changed for frame start s
3359 * Check time span : if ns is out of range, clip it the nearest good value.
3362 on_MEntry1_value_changed (GtkSpinButton
*spinbutton
,
3365 Tab
*tab
=(Tab
*)user_data
;
3366 LttvTracesetContext
* tsc
=
3367 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3368 TimeInterval time_span
= tsc
->time_span
;
3369 gint value
= gtk_spin_button_get_value_as_int(spinbutton
);
3371 TimeWindow new_time_window
= tab
->time_window
;
3373 LttTime end_time
= new_time_window
.end_time
;
3375 new_time_window
.start_time
.tv_sec
= value
;
3377 /* start nanoseconds */
3378 if(new_time_window
.start_time
.tv_sec
== time_span
.start_time
.tv_sec
) {
3379 if(new_time_window
.start_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3380 if(new_time_window
.start_time
.tv_nsec
> time_span
.end_time
.tv_nsec
)
3381 new_time_window
.start_time
.tv_nsec
= time_span
.end_time
.tv_nsec
-1;
3382 if(new_time_window
.start_time
.tv_nsec
< time_span
.start_time
.tv_nsec
)
3383 new_time_window
.start_time
.tv_nsec
= time_span
.start_time
.tv_nsec
;
3385 if(new_time_window
.start_time
.tv_nsec
< time_span
.start_time
.tv_nsec
)
3386 new_time_window
.start_time
.tv_nsec
= time_span
.start_time
.tv_nsec
;
3389 else if(new_time_window
.start_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3390 if(new_time_window
.start_time
.tv_nsec
> time_span
.end_time
.tv_nsec
)
3391 new_time_window
.start_time
.tv_nsec
= time_span
.end_time
.tv_nsec
-1;
3394 if(ltt_time_compare(new_time_window
.start_time
, end_time
) >= 0) {
3395 /* Then, we must push back end time : keep the same time width
3396 * if possible, else end traceset time */
3397 end_time
= LTT_TIME_MIN(ltt_time_add(new_time_window
.start_time
,
3398 new_time_window
.time_width
),
3399 time_span
.end_time
);
3402 /* Fix the time width to fit start time and end time */
3403 new_time_window
.time_width
= ltt_time_sub(end_time
,
3404 new_time_window
.start_time
);
3405 new_time_window
.time_width_double
=
3406 ltt_time_to_double(new_time_window
.time_width
);
3408 new_time_window
.end_time
= end_time
;
3410 time_change_manager(tab
, new_time_window
);
3415 on_MEntry2_value_changed (GtkSpinButton
*spinbutton
,
3418 Tab
*tab
=(Tab
*)user_data
;
3419 LttvTracesetContext
* tsc
=
3420 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3421 TimeInterval time_span
= tsc
->time_span
;
3422 gint value
= gtk_spin_button_get_value_as_int(spinbutton
);
3424 TimeWindow new_time_window
= tab
->time_window
;
3426 LttTime end_time
= new_time_window
.end_time
;
3428 new_time_window
.start_time
.tv_nsec
= value
;
3430 if(ltt_time_compare(new_time_window
.start_time
, end_time
) >= 0) {
3431 /* Then, we must push back end time : keep the same time width
3432 * if possible, else end traceset time */
3433 end_time
= LTT_TIME_MIN(ltt_time_add(new_time_window
.start_time
,
3434 new_time_window
.time_width
),
3435 time_span
.end_time
);
3438 /* Fix the time width to fit start time and end time */
3439 new_time_window
.time_width
= ltt_time_sub(end_time
,
3440 new_time_window
.start_time
);
3441 new_time_window
.time_width_double
=
3442 ltt_time_to_double(new_time_window
.time_width
);
3444 new_time_window
.end_time
= end_time
;
3446 time_change_manager(tab
, new_time_window
);
3451 on_MEntry3_value_changed (GtkSpinButton
*spinbutton
,
3454 Tab
*tab
=(Tab
*)user_data
;
3455 LttvTracesetContext
* tsc
=
3456 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3457 TimeInterval time_span
= tsc
->time_span
;
3458 gint value
= gtk_spin_button_get_value_as_int(spinbutton
);
3460 TimeWindow new_time_window
= tab
->time_window
;
3462 LttTime end_time
= new_time_window
.end_time
;
3464 end_time
.tv_sec
= value
;
3466 /* end nanoseconds */
3467 if(end_time
.tv_sec
== time_span
.start_time
.tv_sec
) {
3468 if(end_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3469 if(end_time
.tv_nsec
> time_span
.end_time
.tv_nsec
)
3470 end_time
.tv_nsec
= time_span
.end_time
.tv_nsec
;
3471 if(end_time
.tv_nsec
< time_span
.start_time
.tv_nsec
)
3472 end_time
.tv_nsec
= time_span
.start_time
.tv_nsec
+1;
3474 if(end_time
.tv_nsec
< time_span
.start_time
.tv_nsec
)
3475 end_time
.tv_nsec
= time_span
.start_time
.tv_nsec
+1;
3478 else if(end_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3479 if(end_time
.tv_nsec
> time_span
.end_time
.tv_nsec
)
3480 end_time
.tv_nsec
= time_span
.end_time
.tv_nsec
;
3483 if(ltt_time_compare(new_time_window
.start_time
, end_time
) >= 0) {
3484 /* Then, we must push front start time : keep the same time width
3485 * if possible, else end traceset time */
3486 new_time_window
.start_time
= LTT_TIME_MAX(
3487 ltt_time_sub(end_time
,
3488 new_time_window
.time_width
),
3489 time_span
.start_time
);
3492 /* Fix the time width to fit start time and end time */
3493 new_time_window
.time_width
= ltt_time_sub(end_time
,
3494 new_time_window
.start_time
);
3495 new_time_window
.time_width_double
=
3496 ltt_time_to_double(new_time_window
.time_width
);
3498 new_time_window
.end_time
= end_time
;
3500 time_change_manager(tab
, new_time_window
);
3505 on_MEntry4_value_changed (GtkSpinButton
*spinbutton
,
3508 Tab
*tab
=(Tab
*)user_data
;
3509 LttvTracesetContext
* tsc
=
3510 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3511 TimeInterval time_span
= tsc
->time_span
;
3512 gint value
= gtk_spin_button_get_value_as_int(spinbutton
);
3514 TimeWindow new_time_window
= tab
->time_window
;
3516 LttTime end_time
= new_time_window
.end_time
;
3518 end_time
.tv_nsec
= value
;
3520 if(ltt_time_compare(new_time_window
.start_time
, end_time
) >= 0) {
3521 /* Then, we must push front start time : keep the same time width
3522 * if possible, else end traceset time */
3523 new_time_window
.start_time
= LTT_TIME_MAX(
3524 ltt_time_sub(end_time
,
3525 new_time_window
.time_width
),
3526 time_span
.start_time
);
3529 /* Fix the time width to fit start time and end time */
3530 new_time_window
.time_width
= ltt_time_sub(end_time
,
3531 new_time_window
.start_time
);
3532 new_time_window
.time_width_double
=
3533 ltt_time_to_double(new_time_window
.time_width
);
3534 new_time_window
.end_time
= end_time
;
3536 time_change_manager(tab
, new_time_window
);
3541 void current_time_change_manager (Tab
*tab
,
3542 LttTime new_current_time
)
3544 /* Only one source of time change */
3545 if(tab
->current_time_manager_lock
== TRUE
) return;
3547 tab
->current_time_manager_lock
= TRUE
;
3549 LttvTracesetContext
*tsc
= LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3550 TimeInterval time_span
= tsc
->time_span
;
3552 /* current seconds */
3553 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry5
),
3554 (double)time_span
.start_time
.tv_sec
,
3555 (double)time_span
.end_time
.tv_sec
);
3556 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry5
),
3557 (double)new_current_time
.tv_sec
);
3560 /* start nanoseconds */
3561 if(new_current_time
.tv_sec
== time_span
.start_time
.tv_sec
) {
3562 /* can be both beginning and end at the same time. */
3563 if(new_current_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3564 /* If we are at the end, max nsec to end.. */
3565 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry6
),
3566 (double)time_span
.start_time
.tv_nsec
,
3567 (double)time_span
.end_time
.tv_nsec
);
3569 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry6
),
3570 (double)time_span
.start_time
.tv_nsec
,
3571 (double)NANOSECONDS_PER_SECOND
-1);
3573 } else if(new_current_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3574 /* If we are at the end, max nsec to end.. */
3575 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry6
),
3577 (double)time_span
.end_time
.tv_nsec
);
3578 } else /* anywhere else */
3579 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry6
),
3581 (double)NANOSECONDS_PER_SECOND
-1);
3583 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry6
),
3584 (double)new_current_time
.tv_nsec
);
3586 set_current_time(tab
, &new_current_time
);
3588 tab
->current_time_manager_lock
= FALSE
;
3592 on_MEntry5_value_changed (GtkSpinButton
*spinbutton
,
3595 Tab
*tab
= (Tab
*)user_data
;
3596 LttvTracesetContext
* tsc
=
3597 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3598 TimeInterval time_span
= tsc
->time_span
;
3599 gint value
= gtk_spin_button_get_value_as_int(spinbutton
);
3600 LttTime new_current_time
= tab
->current_time
;
3601 new_current_time
.tv_sec
= value
;
3603 /* current nanoseconds */
3604 if(new_current_time
.tv_sec
== time_span
.start_time
.tv_sec
) {
3605 if(new_current_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3606 if(new_current_time
.tv_nsec
> time_span
.end_time
.tv_nsec
)
3607 new_current_time
.tv_nsec
= time_span
.end_time
.tv_nsec
;
3608 if(new_current_time
.tv_nsec
< time_span
.start_time
.tv_nsec
)
3609 new_current_time
.tv_nsec
= time_span
.start_time
.tv_nsec
;
3611 if(new_current_time
.tv_nsec
< time_span
.start_time
.tv_nsec
)
3612 new_current_time
.tv_nsec
= time_span
.start_time
.tv_nsec
;
3615 else if(new_current_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3616 if(new_current_time
.tv_nsec
> time_span
.end_time
.tv_nsec
)
3617 new_current_time
.tv_nsec
= time_span
.end_time
.tv_nsec
;
3620 current_time_change_manager(tab
, new_current_time
);
3624 on_MEntry6_value_changed (GtkSpinButton
*spinbutton
,
3627 Tab
*tab
= (Tab
*)user_data
;
3628 gint value
= gtk_spin_button_get_value_as_int(spinbutton
);
3629 LttTime new_current_time
= tab
->current_time
;
3630 new_current_time
.tv_nsec
= value
;
3632 current_time_change_manager(tab
, new_current_time
);
3636 void scroll_value_changed_cb(GtkWidget
*scrollbar
,
3639 Tab
*tab
= (Tab
*)user_data
;
3640 TimeWindow new_time_window
;
3642 GtkAdjustment
*adjust
= gtk_range_get_adjustment(GTK_RANGE(scrollbar
));
3643 gdouble value
= gtk_adjustment_get_value(adjust
);
3644 // gdouble upper, lower, ratio, page_size;
3646 LttvTracesetContext
* tsc
=
3647 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3648 TimeInterval time_span
= tsc
->time_span
;
3650 time
= ltt_time_add(ltt_time_from_double(value
),
3651 time_span
.start_time
);
3653 new_time_window
.start_time
= time
;
3655 page_size
= adjust
->page_size
;
3657 new_time_window
.time_width
=
3658 ltt_time_from_double(page_size
);
3660 new_time_window
.time_width_double
=
3663 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
3664 new_time_window
.time_width
);
3667 time_change_manager(tab
, new_time_window
);
3669 //time_window = tab->time_window;
3671 lower
= adjust
->lower
;
3672 upper
= adjust
->upper
;
3673 ratio
= (value
- lower
) / (upper
- lower
);
3674 g_info("lower %lu, upper %lu, value %lu, ratio %lu", lower
, upper
, value
, ratio
);
3676 //time = ltt_time_sub(time_span->end_time, time_span->start_time);
3677 //time = ltt_time_mul(time, (float)ratio);
3678 //time = ltt_time_add(time_span->start_time, time);
3679 time
= ltt_time_add(ltt_time_from_double(value
),
3680 time_span
.start_time
);
3682 time_window
.start_time
= time
;
3684 page_size
= adjust
->page_size
;
3686 time_window
.time_width
=
3687 ltt_time_from_double(page_size
);
3688 //time = ltt_time_sub(time_span.end_time, time);
3689 //if(ltt_time_compare(time,time_window.time_width) < 0){
3690 // time_window.time_width = time;
3693 /* call viewer hooks for new time window */
3694 set_time_window(tab
, &time_window
);
3699 /* Display a dialogue showing all eventtypes and traces, let user to select the interested
3700 * eventtypes, tracefiles and traces (filter)
3703 /* Select a trace which will be removed from traceset
3706 char * get_remove_trace(char ** all_trace_name
, int nb_trace
)
3708 return get_selection(all_trace_name
, nb_trace
,
3709 "Select a trace", "Trace pathname");
3713 /* Select a module which will be loaded
3716 char * get_load_module(char ** load_module_name
, int nb_module
)
3718 return get_selection(load_module_name
, nb_module
,
3719 "Select a module to load", "Module name");
3725 /* Select a module which will be unloaded
3728 char * get_unload_module(char ** loaded_module_name
, int nb_module
)
3730 return get_selection(loaded_module_name
, nb_module
,
3731 "Select a module to unload", "Module name");
3735 /* Display a dialogue which shows all selectable items, let user to
3736 * select one of them
3739 char * get_selection(char ** loaded_module_name
, int nb_module
,
3740 char *title
, char * column_title
)
3742 GtkWidget
* dialogue
;
3743 GtkWidget
* scroll_win
;
3745 GtkListStore
* store
;
3746 GtkTreeViewColumn
* column
;
3747 GtkCellRenderer
* renderer
;
3748 GtkTreeSelection
* select
;
3751 char * unload_module_name
= NULL
;
3753 dialogue
= gtk_dialog_new_with_buttons(title
,
3756 GTK_STOCK_OK
,GTK_RESPONSE_ACCEPT
,
3757 GTK_STOCK_CANCEL
,GTK_RESPONSE_REJECT
,
3759 gtk_window_set_default_size((GtkWindow
*)dialogue
, 500, 200);
3761 scroll_win
= gtk_scrolled_window_new (NULL
, NULL
);
3762 gtk_widget_show ( scroll_win
);
3763 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll_win
),
3764 GTK_POLICY_AUTOMATIC
, GTK_POLICY_AUTOMATIC
);
3766 store
= gtk_list_store_new (N_COLUMNS
,G_TYPE_STRING
);
3767 tree
= gtk_tree_view_new_with_model(GTK_TREE_MODEL (store
));
3768 gtk_widget_show ( tree
);
3769 g_object_unref (G_OBJECT (store
));
3771 renderer
= gtk_cell_renderer_text_new ();
3772 column
= gtk_tree_view_column_new_with_attributes (column_title
,
3774 "text", MODULE_COLUMN
,
3776 gtk_tree_view_column_set_alignment (column
, 0.5);
3777 gtk_tree_view_column_set_fixed_width (column
, 150);
3778 gtk_tree_view_append_column (GTK_TREE_VIEW (tree
), column
);
3780 select
= gtk_tree_view_get_selection (GTK_TREE_VIEW (tree
));
3781 gtk_tree_selection_set_mode (select
, GTK_SELECTION_SINGLE
);
3783 gtk_container_add (GTK_CONTAINER (scroll_win
), tree
);
3785 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialogue
)->vbox
), scroll_win
,TRUE
, TRUE
,0);
3787 for(i
=0;i
<nb_module
;i
++){
3788 gtk_list_store_append (store
, &iter
);
3789 gtk_list_store_set (store
, &iter
, MODULE_COLUMN
,loaded_module_name
[i
],-1);
3792 id
= gtk_dialog_run(GTK_DIALOG(dialogue
));
3793 GtkTreeModel
**store_model
= (GtkTreeModel
**)&store
;
3795 case GTK_RESPONSE_ACCEPT
:
3796 case GTK_RESPONSE_OK
:
3797 if (gtk_tree_selection_get_selected (select
, store_model
, &iter
)){
3798 gtk_tree_model_get ((GtkTreeModel
*)store
, &iter
, MODULE_COLUMN
, &unload_module_name
, -1);
3800 case GTK_RESPONSE_REJECT
:
3801 case GTK_RESPONSE_CANCEL
:
3803 gtk_widget_destroy(dialogue
);
3807 return unload_module_name
;
3811 /* Insert all menu entry and tool buttons into this main window
3816 void add_all_menu_toolbar_constructors(MainWindow
* mw
, gpointer user_data
)
3820 lttvwindow_viewer_constructor constructor
;
3821 LttvMenus
* global_menu
, * instance_menu
;
3822 LttvToolbars
* global_toolbar
, * instance_toolbar
;
3823 LttvMenuClosure
*menu_item
;
3824 LttvToolbarClosure
*toolbar_item
;
3825 LttvAttributeValue value
;
3826 LttvIAttribute
*global_attributes
= LTTV_IATTRIBUTE(lttv_global_attributes());
3827 LttvIAttribute
*attributes
= mw
->attributes
;
3828 GtkWidget
* tool_menu_title_menu
, *new_widget
, *pixmap
;
3830 g_assert(lttv_iattribute_find_by_path(global_attributes
,
3831 "viewers/menu", LTTV_POINTER
, &value
));
3832 if(*(value
.v_pointer
) == NULL
)
3833 *(value
.v_pointer
) = lttv_menus_new();
3834 global_menu
= (LttvMenus
*)*(value
.v_pointer
);
3836 g_assert(lttv_iattribute_find_by_path(attributes
,
3837 "viewers/menu", LTTV_POINTER
, &value
));
3838 if(*(value
.v_pointer
) == NULL
)
3839 *(value
.v_pointer
) = lttv_menus_new();
3840 instance_menu
= (LttvMenus
*)*(value
.v_pointer
);
3844 g_assert(lttv_iattribute_find_by_path(global_attributes
,
3845 "viewers/toolbar", LTTV_POINTER
, &value
));
3846 if(*(value
.v_pointer
) == NULL
)
3847 *(value
.v_pointer
) = lttv_toolbars_new();
3848 global_toolbar
= (LttvToolbars
*)*(value
.v_pointer
);
3850 g_assert(lttv_iattribute_find_by_path(attributes
,
3851 "viewers/toolbar", LTTV_POINTER
, &value
));
3852 if(*(value
.v_pointer
) == NULL
)
3853 *(value
.v_pointer
) = lttv_toolbars_new();
3854 instance_toolbar
= (LttvToolbars
*)*(value
.v_pointer
);
3856 /* Add missing menu entries to window instance */
3857 for(i
=0;i
<global_menu
->len
;i
++) {
3858 menu_item
= &g_array_index(global_menu
, LttvMenuClosure
, i
);
3860 //add menu_item to window instance;
3861 constructor
= menu_item
->con
;
3862 tool_menu_title_menu
= lookup_widget(mw
->mwindow
,"ToolMenuTitle_menu");
3864 gtk_menu_item_new_with_mnemonic (menu_item
->menu_text
);
3865 gtk_container_add (GTK_CONTAINER (tool_menu_title_menu
),
3867 g_signal_connect ((gpointer
) new_widget
, "activate",
3868 G_CALLBACK (insert_viewer_wrap
),
3870 gtk_widget_show (new_widget
);
3871 lttv_menus_add(instance_menu
, menu_item
->con
,
3872 menu_item
->menu_path
,
3873 menu_item
->menu_text
,
3878 /* Add missing toolbar entries to window instance */
3879 for(i
=0;i
<global_toolbar
->len
;i
++) {
3880 toolbar_item
= &g_array_index(global_toolbar
, LttvToolbarClosure
, i
);
3882 //add toolbar_item to window instance;
3883 constructor
= toolbar_item
->con
;
3884 tool_menu_title_menu
= lookup_widget(mw
->mwindow
,"MToolbar1");
3885 pixbuf
= gdk_pixbuf_new_from_xpm_data((const char**)toolbar_item
->pixmap
);
3886 pixmap
= gtk_image_new_from_pixbuf(pixbuf
);
3888 gtk_toolbar_append_element (GTK_TOOLBAR (tool_menu_title_menu
),
3889 GTK_TOOLBAR_CHILD_BUTTON
,
3892 toolbar_item
->tooltip
, NULL
,
3893 pixmap
, NULL
, NULL
);
3894 gtk_label_set_use_underline(
3895 GTK_LABEL (((GtkToolbarChild
*) (
3896 g_list_last (GTK_TOOLBAR
3897 (tool_menu_title_menu
)->children
)->data
))->label
),
3899 gtk_container_set_border_width (GTK_CONTAINER (new_widget
), 1);
3900 g_signal_connect ((gpointer
) new_widget
,
3902 G_CALLBACK (insert_viewer_wrap
),
3904 gtk_widget_show (new_widget
);
3906 lttv_toolbars_add(instance_toolbar
, toolbar_item
->con
,
3907 toolbar_item
->tooltip
,
3908 toolbar_item
->pixmap
,
3916 /* Create a main window
3919 void construct_main_window(MainWindow
* parent
)
3921 g_debug("construct_main_window()");
3922 GtkWidget
* new_window
; /* New generated main window */
3923 MainWindow
* new_m_window
;/* New main window structure */
3924 GtkNotebook
* notebook
;
3925 LttvIAttribute
*attributes
=
3926 LTTV_IATTRIBUTE(g_object_new(LTTV_ATTRIBUTE_TYPE
, NULL
));
3927 LttvAttributeValue value
;
3930 new_m_window
= g_new(MainWindow
, 1);
3932 // Add the object's information to the module's array
3933 g_main_window_list
= g_slist_append(g_main_window_list
, new_m_window
);
3935 new_window
= create_MWindow();
3936 gtk_widget_show (new_window
);
3938 new_m_window
->mwindow
= new_window
;
3939 new_m_window
->attributes
= attributes
;
3941 g_assert(lttv_iattribute_find_by_path(attributes
,
3942 "viewers/menu", LTTV_POINTER
, &value
));
3943 *(value
.v_pointer
) = lttv_menus_new();
3945 g_assert(lttv_iattribute_find_by_path(attributes
,
3946 "viewers/toolbar", LTTV_POINTER
, &value
));
3947 *(value
.v_pointer
) = lttv_toolbars_new();
3949 add_all_menu_toolbar_constructors(new_m_window
, NULL
);
3951 g_object_set_data_full(G_OBJECT(new_window
),
3953 (gpointer
)new_m_window
,
3954 (GDestroyNotify
)g_free
);
3955 //create a default tab
3956 notebook
= (GtkNotebook
*)lookup_widget(new_m_window
->mwindow
, "MNotebook");
3957 if(notebook
== NULL
){
3958 g_info("Notebook does not exist\n");
3961 //gtk_notebook_popup_enable (GTK_NOTEBOOK(notebook));
3962 //for now there is no name field in LttvTraceset structure
3963 //Use "Traceset" as the label for the default tab
3965 GtkWidget
* parent_notebook
= lookup_widget(parent
->mwindow
, "MNotebook");
3966 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(parent_notebook
),
3967 gtk_notebook_get_current_page(GTK_NOTEBOOK(parent_notebook
)));
3973 parent_tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
3975 new_tab
= create_tab(new_m_window
, parent_tab
, notebook
, "Traceset");
3977 new_tab
= create_tab(new_m_window
, NULL
, notebook
, "Traceset");
3978 /* First window, use command line trace */
3979 if(g_init_trace
!= NULL
){
3980 lttvwindow_add_trace(new_tab
,
3984 LttvTraceset
*traceset
= new_tab
->traceset_info
->traceset
;
3985 SetTraceset(new_tab
, traceset
);
3987 /* Insert default viewers */
3989 LttvAttributeType type
;
3990 LttvAttributeName name
;
3991 LttvAttributeValue value
;
3992 LttvAttribute
*attribute
;
3994 LttvIAttribute
*attributes_global
=
3995 LTTV_IATTRIBUTE(lttv_global_attributes());
3997 g_assert(attribute
=
3998 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
3999 LTTV_IATTRIBUTE(attributes_global
),
4000 LTTV_VIEWER_CONSTRUCTORS
)));
4002 name
= g_quark_from_string("guievents");
4003 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
4005 if(type
== LTTV_POINTER
) {
4006 lttvwindow_viewer_constructor viewer_constructor
=
4007 (lttvwindow_viewer_constructor
)*value
.v_pointer
;
4008 insert_viewer(new_window
, viewer_constructor
);
4011 name
= g_quark_from_string("guicontrolflow");
4012 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
4014 if(type
== LTTV_POINTER
) {
4015 lttvwindow_viewer_constructor viewer_constructor
=
4016 (lttvwindow_viewer_constructor
)*value
.v_pointer
;
4017 insert_viewer(new_window
, viewer_constructor
);
4020 name
= g_quark_from_string("guistatistics");
4021 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
4023 if(type
== LTTV_POINTER
) {
4024 lttvwindow_viewer_constructor viewer_constructor
=
4025 (lttvwindow_viewer_constructor
)*value
.v_pointer
;
4026 insert_viewer(new_window
, viewer_constructor
);
4032 g_info("There are now : %d windows\n",g_slist_length(g_main_window_list
));
4036 /* Free the memory occupied by a tab structure
4040 void tab_destructor(Tab
* tab
)
4042 int i
, nb
, ref_count
;
4045 gtk_object_destroy(GTK_OBJECT(tab
->tooltips
));
4048 g_object_unref(tab
->attributes
);
4050 if(tab
->interrupted_state
)
4051 g_object_unref(tab
->interrupted_state
);
4054 if(tab
->traceset_info
->traceset_context
!= NULL
){
4055 //remove state update hooks
4056 lttv_state_remove_event_hooks(
4057 (LttvTracesetState
*)tab
->traceset_info
->
4059 lttv_context_fini(LTTV_TRACESET_CONTEXT(tab
->traceset_info
->
4061 g_object_unref(tab
->traceset_info
->traceset_context
);
4063 if(tab
->traceset_info
->traceset
!= NULL
) {
4064 nb
= lttv_traceset_number(tab
->traceset_info
->traceset
);
4065 for(i
= 0 ; i
< nb
; i
++) {
4066 trace
= lttv_traceset_get(tab
->traceset_info
->traceset
, i
);
4067 ref_count
= lttv_trace_get_ref_number(trace
);
4069 ltt_trace_close(lttv_trace(trace
));
4073 lttv_filter_destroy(tab
->filter
);
4074 lttv_traceset_destroy(tab
->traceset_info
->traceset
);
4075 /* Remove the idle events requests processing function of the tab */
4076 g_idle_remove_by_data(tab
);
4078 g_slist_free(tab
->events_requests
);
4079 g_free(tab
->traceset_info
);
4084 /* Create a tab and insert it into the current main window
4087 Tab
* create_tab(MainWindow
* mw
, Tab
*copy_tab
,
4088 GtkNotebook
* notebook
, char * label
)
4093 //create a new tab data structure
4096 //construct and initialize the traceset_info
4097 tab
->traceset_info
= g_new(TracesetInfo
,1);
4100 tab
->traceset_info
->traceset
=
4101 lttv_traceset_copy(copy_tab
->traceset_info
->traceset
);
4103 /* Copy the previous tab's filter */
4104 /* We can clone the filter, as we copy the trace set also */
4105 /* The filter must always be in sync with the trace set */
4106 tab
->filter
= lttv_filter_clone(copy_tab
->filter
);
4109 tab
->traceset_info
->traceset
= lttv_traceset_new();
4114 lttv_attribute_write_xml(
4115 lttv_traceset_attribute(tab
->traceset_info
->traceset
),
4121 tab
->time_manager_lock
= FALSE
;
4122 tab
->current_time_manager_lock
= FALSE
;
4124 //FIXME copy not implemented in lower level
4125 tab
->traceset_info
->traceset_context
=
4126 g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
4127 g_assert(tab
->traceset_info
->traceset_context
!= NULL
);
4129 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
),
4130 tab
->traceset_info
->traceset
);
4131 //add state update hooks
4132 lttv_state_add_event_hooks(
4133 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
4135 //determine the current_time and time_window of the tab
4137 if(copy_tab
!= NULL
){
4138 tab
->time_window
= copy_tab
->time_window
;
4139 tab
->current_time
= copy_tab
->current_time
;
4141 tab
->time_window
.start_time
=
4142 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
4143 time_span
.start_time
;
4144 if(DEFAULT_TIME_WIDTH_S
<
4145 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
4146 time_span
.end_time
.tv_sec
)
4147 tmp_time
.tv_sec
= DEFAULT_TIME_WIDTH_S
;
4150 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
4151 time_span
.end_time
.tv_sec
;
4152 tmp_time
.tv_nsec
= 0;
4153 tab
->time_window
.time_width
= tmp_time
;
4154 tab
->current_time
.tv_sec
=
4155 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
4156 time_span
.start_time
.tv_sec
;
4157 tab
->current_time
.tv_nsec
=
4158 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
4159 time_span
.start_time
.tv_nsec
;
4162 tab
->attributes
= LTTV_IATTRIBUTE(g_object_new(LTTV_ATTRIBUTE_TYPE
, NULL
));
4163 tab
->interrupted_state
= g_object_new(LTTV_ATTRIBUTE_TYPE
, NULL
);
4165 tab
->vbox
= gtk_vbox_new(FALSE
, 2);
4166 tab
->viewer_container
= gtk_vbox_new(TRUE
, 2);
4167 tab
->scrollbar
= gtk_hscrollbar_new(NULL
);
4168 //tab->multivpaned = gtk_multi_vpaned_new();
4169 tab
->time_window
.start_time
= ltt_time_zero
;
4170 tab
->time_window
.end_time
= ltt_time_zero
;
4171 tab
->time_window
.time_width
= ltt_time_zero
;
4172 tab
->current_time
= ltt_time_zero
;
4174 gtk_box_pack_start(GTK_BOX(tab
->vbox
),
4175 tab
->viewer_container
,
4177 TRUE
, /* Give the extra space to the child */
4178 0); /* No padding */
4180 /* Create the timebar */
4182 tab
->MTimebar
= gtk_hbox_new(FALSE
, 2);
4183 gtk_widget_show(tab
->MTimebar
);
4184 tab
->tooltips
= gtk_tooltips_new();
4186 tab
->MEventBox1a
= gtk_event_box_new();
4187 gtk_widget_show(tab
->MEventBox1a
);
4188 gtk_tooltips_set_tip(tab
->tooltips
, tab
->MEventBox1a
,
4189 "Paste Start and End Times Here", "");
4190 tab
->MText1a
= gtk_label_new("Time Frame ");
4191 gtk_widget_show(tab
->MText1a
);
4192 gtk_container_add(GTK_CONTAINER(tab
->MEventBox1a
), tab
->MText1a
);
4193 tab
->MEventBox1b
= gtk_event_box_new();
4194 gtk_widget_show(tab
->MEventBox1b
);
4195 gtk_tooltips_set_tip(tab
->tooltips
, tab
->MEventBox1b
,
4196 "Paste Start Time Here", "");
4197 tab
->MText1b
= gtk_label_new("start: ");
4198 gtk_widget_show(tab
->MText1b
);
4199 gtk_container_add(GTK_CONTAINER(tab
->MEventBox1b
), tab
->MText1b
);
4200 tab
->MText2
= gtk_label_new("s");
4201 gtk_widget_show(tab
->MText2
);
4202 tab
->MText3a
= gtk_label_new("ns");
4203 gtk_widget_show(tab
->MText3a
);
4204 tab
->MEventBox3b
= gtk_event_box_new();
4205 gtk_widget_show(tab
->MEventBox3b
);
4206 gtk_tooltips_set_tip(tab
->tooltips
, tab
->MEventBox3b
,
4207 "Paste End Time Here", "");
4208 tab
->MText3b
= gtk_label_new("end:");
4209 gtk_widget_show(tab
->MText3b
);
4210 gtk_container_add(GTK_CONTAINER(tab
->MEventBox3b
), tab
->MText3b
);
4211 tab
->MText4
= gtk_label_new("s");
4212 gtk_widget_show(tab
->MText4
);
4213 tab
->MText5a
= gtk_label_new("ns");
4214 gtk_widget_show(tab
->MText5a
);
4215 tab
->MEventBox5b
= gtk_event_box_new();
4216 gtk_widget_show(tab
->MEventBox5b
);
4217 gtk_tooltips_set_tip(tab
->tooltips
, tab
->MEventBox5b
,
4218 "Paste Current Time Here", "");
4219 tab
->MText5b
= gtk_label_new("Current Time:");
4220 gtk_widget_show(tab
->MText5b
);
4221 gtk_container_add(GTK_CONTAINER(tab
->MEventBox5b
), tab
->MText5b
);
4222 tab
->MText6
= gtk_label_new("s");
4223 gtk_widget_show(tab
->MText6
);
4224 tab
->MText7
= gtk_label_new("ns");
4225 gtk_widget_show(tab
->MText7
);
4227 tab
->MEntry1
= gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4228 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab
->MEntry1
),0);
4229 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab
->MEntry1
),TRUE
);
4230 gtk_widget_show(tab
->MEntry1
);
4231 tab
->MEntry2
= gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4232 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab
->MEntry2
),0);
4233 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab
->MEntry2
),TRUE
);
4234 gtk_widget_show(tab
->MEntry2
);
4235 tab
->MEntry3
= gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4236 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab
->MEntry3
),0);
4237 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab
->MEntry3
),TRUE
);
4238 gtk_widget_show(tab
->MEntry3
);
4239 tab
->MEntry4
= gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4240 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab
->MEntry4
),0);
4241 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab
->MEntry4
),TRUE
);
4242 gtk_widget_show(tab
->MEntry4
);
4243 tab
->MEntry5
= gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4244 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab
->MEntry5
),0);
4245 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab
->MEntry5
),TRUE
);
4246 gtk_widget_show(tab
->MEntry5
);
4247 tab
->MEntry6
= gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4248 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab
->MEntry6
),0);
4249 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab
->MEntry6
),TRUE
);
4250 gtk_widget_show(tab
->MEntry6
);
4253 GtkWidget
*temp_widget
;
4255 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEventBox1a
, FALSE
,
4257 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEventBox1b
, FALSE
,
4259 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEntry1
, FALSE
, FALSE
, 0);
4260 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MText2
, FALSE
, FALSE
, 0);
4261 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEntry2
, FALSE
, FALSE
, 0);
4262 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MText3a
, FALSE
, FALSE
, 0);
4263 temp_widget
= gtk_vseparator_new();
4264 gtk_widget_show(temp_widget
);
4265 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), temp_widget
, FALSE
, FALSE
, 0);
4266 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEventBox3b
, FALSE
,
4268 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEntry3
, FALSE
, FALSE
, 0);
4269 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MText4
, FALSE
, FALSE
, 0);
4270 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEntry4
, FALSE
, FALSE
, 0);
4271 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MText5a
, FALSE
, FALSE
, 0);
4272 temp_widget
= gtk_vseparator_new();
4273 gtk_widget_show(temp_widget
);
4274 gtk_box_pack_end (GTK_BOX (tab
->MTimebar
), tab
->MText7
, FALSE
, FALSE
, 0);
4275 gtk_box_pack_end (GTK_BOX (tab
->MTimebar
), tab
->MEntry6
, FALSE
, FALSE
, 0);
4276 gtk_box_pack_end (GTK_BOX (tab
->MTimebar
), tab
->MText6
, FALSE
, FALSE
, 0);
4277 gtk_box_pack_end (GTK_BOX (tab
->MTimebar
), tab
->MEntry5
, FALSE
, FALSE
, 0);
4278 gtk_box_pack_end (GTK_BOX (tab
->MTimebar
), tab
->MEventBox5b
, FALSE
,
4280 gtk_box_pack_end (GTK_BOX (tab
->MTimebar
), temp_widget
, FALSE
, FALSE
, 0);
4283 //GtkWidget *test = gtk_button_new_with_label("drop");
4284 //gtk_button_set_relief(GTK_BUTTON(test), GTK_RELIEF_NONE);
4285 //gtk_widget_show(test);
4286 //gtk_box_pack_end(GTK_BOX (tab->MTimebar), test, FALSE, FALSE, 0);
4287 //gtk_widget_add_events(tab->MText1, GDK_ALL_EVENTS_MASK);//GDK_BUTTON_PRESS_MASK);
4288 /*GtkWidget *event_box = gtk_event_box_new();
4289 gtk_widget_show(event_box);
4290 gtk_tooltips_set_tip(tooltips, event_box,
4291 "Paste Current Time Here", "");
4292 gtk_box_pack_end(GTK_BOX (tab->MTimebar), event_box, FALSE, FALSE, 0);
4293 GtkWidget *test = gtk_label_new("drop");
4294 gtk_container_add(GTK_CONTAINER(event_box), test);
4295 gtk_widget_show(test);
4296 g_signal_connect (G_OBJECT(event_box),
4297 "button-press-event",
4298 G_CALLBACK (on_MText1_paste),
4302 g_signal_connect (G_OBJECT(tab
->MEventBox1a
),
4303 "button-press-event",
4304 G_CALLBACK (on_MEventBox1a_paste
),
4307 g_signal_connect (G_OBJECT(tab
->MEventBox1b
),
4308 "button-press-event",
4309 G_CALLBACK (on_MEventBox1b_paste
),
4311 g_signal_connect (G_OBJECT(tab
->MEventBox3b
),
4312 "button-press-event",
4313 G_CALLBACK (on_MEventBox3b_paste
),
4315 g_signal_connect (G_OBJECT(tab
->MEventBox5b
),
4316 "button-press-event",
4317 G_CALLBACK (on_MEventBox5b_paste
),
4321 gtk_box_pack_end(GTK_BOX(tab
->vbox
),
4323 FALSE
, /* Do not expand */
4324 FALSE
, /* Fill has no effect here (expand false) */
4325 0); /* No padding */
4327 gtk_box_pack_end(GTK_BOX(tab
->vbox
),
4329 FALSE
, /* Do not expand */
4330 FALSE
, /* Fill has no effect here (expand false) */
4331 0); /* No padding */
4333 g_object_set_data(G_OBJECT(tab
->viewer_container
), "focused_viewer", NULL
);
4339 // Display a label with a X
4340 GtkWidget *w_hbox = gtk_hbox_new(FALSE, 4);
4341 GtkWidget *w_label = gtk_label_new (label);
4342 GtkWidget *pixmap = create_pixmap(GTK_WIDGET(notebook), "close.png");
4343 GtkWidget *w_button = gtk_button_new ();
4344 gtk_container_add(GTK_CONTAINER(w_button), pixmap);
4345 //GtkWidget *w_button = gtk_button_new_with_label("x");
4347 gtk_button_set_relief(GTK_BUTTON(w_button), GTK_RELIEF_NONE);
4349 gtk_box_pack_start(GTK_BOX(w_hbox), w_label, TRUE, TRUE, 0);
4350 gtk_box_pack_end(GTK_BOX(w_hbox), w_button, FALSE,
4353 g_signal_connect_swapped (w_button, "clicked",
4354 G_CALLBACK (on_close_tab_X_clicked),
4357 gtk_widget_set_state(w_button, GTK_STATE_ACTIVE);
4359 gtk_widget_show (w_label);
4360 gtk_widget_show (pixmap);
4361 gtk_widget_show (w_button);
4362 gtk_widget_show (w_hbox);
4364 tab->label = w_hbox;
4368 tab
->label
= gtk_label_new (label
);
4370 gtk_widget_show(tab
->label
);
4371 gtk_widget_show(tab
->scrollbar
);
4372 gtk_widget_show(tab
->viewer_container
);
4373 gtk_widget_show(tab
->vbox
);
4374 //gtk_widget_show(tab->multivpaned);
4377 /* Start with empty events requests list */
4378 tab
->events_requests
= NULL
;
4379 tab
->events_request_pending
= FALSE
;
4381 g_object_set_data_full(
4382 G_OBJECT(tab
->vbox
),
4385 (GDestroyNotify
)tab_destructor
);
4387 g_signal_connect(G_OBJECT(tab
->scrollbar
), "value-changed",
4388 G_CALLBACK(scroll_value_changed_cb
), tab
);
4390 g_signal_connect ((gpointer
) tab
->MEntry1
, "value-changed",
4391 G_CALLBACK (on_MEntry1_value_changed
),
4393 g_signal_connect ((gpointer
) tab
->MEntry2
, "value-changed",
4394 G_CALLBACK (on_MEntry2_value_changed
),
4396 g_signal_connect ((gpointer
) tab
->MEntry3
, "value-changed",
4397 G_CALLBACK (on_MEntry3_value_changed
),
4399 g_signal_connect ((gpointer
) tab
->MEntry4
, "value-changed",
4400 G_CALLBACK (on_MEntry4_value_changed
),
4402 g_signal_connect ((gpointer
) tab
->MEntry5
, "value-changed",
4403 G_CALLBACK (on_MEntry5_value_changed
),
4405 g_signal_connect ((gpointer
) tab
->MEntry6
, "value-changed",
4406 G_CALLBACK (on_MEntry6_value_changed
),
4409 //g_signal_connect(G_OBJECT(tab->scrollbar), "changed",
4410 // G_CALLBACK(scroll_value_changed_cb), tab);
4413 //insert tab into notebook
4414 gtk_notebook_append_page(notebook
,
4417 list
= gtk_container_get_children(GTK_CONTAINER(notebook
));
4418 gtk_notebook_set_current_page(notebook
,g_list_length(list
)-1);
4419 // always show : not if(g_list_length(list)>1)
4420 gtk_notebook_set_show_tabs(notebook
, TRUE
);
4426 * execute_events_requests
4428 * Idle function that executes the pending requests for a tab.
4430 * @return return value : TRUE : keep the idle function, FALSE : remove it.
4432 gboolean
execute_events_requests(Tab
*tab
)
4434 return ( lttvwindow_process_pending_requests(tab
) );