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(tsc
);
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
;
3241 g_assert(ltt_time_compare(start_time
, end_time
) < 0);
3244 GtkAdjustment
*adjustment
= gtk_range_get_adjustment(GTK_RANGE(tab
->scrollbar
));
3245 LttTime upper
= ltt_time_sub(time_span
.end_time
, time_span
.start_time
);
3247 gtk_range_set_increments(GTK_RANGE(tab
->scrollbar
),
3248 ltt_time_to_double(new_time_window
.time_width
)
3249 / SCROLL_STEP_PER_PAGE
3250 * NANOSECONDS_PER_SECOND
, /* step increment */
3251 ltt_time_to_double(new_time_window
.time_width
)
3252 * NANOSECONDS_PER_SECOND
); /* page increment */
3253 gtk_range_set_range(GTK_RANGE(tab
->scrollbar
),
3255 ltt_time_to_double(upper
)
3256 * NANOSECONDS_PER_SECOND
); /* upper */
3258 g_object_set(G_OBJECT(adjustment
),
3262 ltt_time_to_double(upper
), /* upper */
3264 new_time_window
.time_width_double
3265 / SCROLL_STEP_PER_PAGE
, /* step increment */
3267 new_time_window
.time_width_double
,
3268 /* page increment */
3270 new_time_window
.time_width_double
, /* page size */
3272 gtk_adjustment_changed(adjustment
);
3274 // g_object_set(G_OBJECT(adjustment),
3276 // ltt_time_to_double(
3277 // ltt_time_sub(start_time, time_span.start_time))
3280 //gtk_adjustment_value_changed(adjustment);
3281 gtk_range_set_value(GTK_RANGE(tab
->scrollbar
),
3283 ltt_time_sub(start_time
, time_span
.start_time
)) /* value */);
3285 /* set the time bar. */
3287 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry1
),
3288 (double)time_span
.start_time
.tv_sec
,
3289 (double)time_span
.end_time
.tv_sec
);
3290 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry1
),
3291 (double)start_time
.tv_sec
);
3293 /* start nanoseconds */
3294 if(start_time
.tv_sec
== time_span
.start_time
.tv_sec
) {
3295 /* can be both beginning and end at the same time. */
3296 if(start_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3297 /* If we are at the end, max nsec to end.. -1 (not zero length) */
3298 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry2
),
3299 (double)time_span
.start_time
.tv_nsec
,
3300 (double)time_span
.end_time
.tv_nsec
-1);
3302 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry2
),
3303 (double)time_span
.start_time
.tv_nsec
,
3304 (double)NANOSECONDS_PER_SECOND
-1);
3306 } else if(start_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3307 /* If we are at the end, max nsec to end.. -1 (not zero length) */
3308 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry2
),
3310 (double)time_span
.end_time
.tv_nsec
-1);
3311 } else /* anywhere else */
3312 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry2
),
3314 (double)NANOSECONDS_PER_SECOND
-1);
3315 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry2
),
3316 (double)start_time
.tv_nsec
);
3319 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry3
),
3320 (double)time_span
.start_time
.tv_sec
,
3321 (double)time_span
.end_time
.tv_sec
);
3322 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry3
),
3323 (double)end_time
.tv_sec
);
3325 /* end nanoseconds */
3326 if(end_time
.tv_sec
== time_span
.start_time
.tv_sec
) {
3327 /* can be both beginning and end at the same time. */
3328 if(end_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3329 /* If we are at the end, max nsec to end.. */
3330 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry4
),
3331 (double)time_span
.start_time
.tv_nsec
+1,
3332 (double)time_span
.end_time
.tv_nsec
);
3334 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry4
),
3335 (double)time_span
.start_time
.tv_nsec
+1,
3336 (double)NANOSECONDS_PER_SECOND
-1);
3339 else if(end_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3340 /* If we are at the end, max nsec to end.. */
3341 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry4
),
3343 (double)time_span
.end_time
.tv_nsec
);
3345 else /* anywhere else */
3346 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry4
),
3348 (double)NANOSECONDS_PER_SECOND
-1);
3349 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry4
),
3350 (double)end_time
.tv_nsec
);
3352 /* call viewer hooks for new time window */
3353 set_time_window(tab
, &new_time_window
);
3355 tab
->time_manager_lock
= FALSE
;
3359 /* value changed for frame start s
3361 * Check time span : if ns is out of range, clip it the nearest good value.
3364 on_MEntry1_value_changed (GtkSpinButton
*spinbutton
,
3367 Tab
*tab
=(Tab
*)user_data
;
3368 LttvTracesetContext
* tsc
=
3369 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3370 TimeInterval time_span
= tsc
->time_span
;
3371 gint value
= gtk_spin_button_get_value_as_int(spinbutton
);
3373 TimeWindow new_time_window
= tab
->time_window
;
3375 LttTime end_time
= new_time_window
.end_time
;
3377 new_time_window
.start_time
.tv_sec
= value
;
3379 /* start nanoseconds */
3380 if(new_time_window
.start_time
.tv_sec
== time_span
.start_time
.tv_sec
) {
3381 if(new_time_window
.start_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3382 if(new_time_window
.start_time
.tv_nsec
> time_span
.end_time
.tv_nsec
)
3383 new_time_window
.start_time
.tv_nsec
= time_span
.end_time
.tv_nsec
-1;
3384 if(new_time_window
.start_time
.tv_nsec
< time_span
.start_time
.tv_nsec
)
3385 new_time_window
.start_time
.tv_nsec
= time_span
.start_time
.tv_nsec
;
3387 if(new_time_window
.start_time
.tv_nsec
< time_span
.start_time
.tv_nsec
)
3388 new_time_window
.start_time
.tv_nsec
= time_span
.start_time
.tv_nsec
;
3391 else if(new_time_window
.start_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3392 if(new_time_window
.start_time
.tv_nsec
> time_span
.end_time
.tv_nsec
)
3393 new_time_window
.start_time
.tv_nsec
= time_span
.end_time
.tv_nsec
-1;
3396 if(ltt_time_compare(new_time_window
.start_time
, end_time
) >= 0) {
3397 /* Then, we must push back end time : keep the same time width
3398 * if possible, else end traceset time */
3399 end_time
= LTT_TIME_MIN(ltt_time_add(new_time_window
.start_time
,
3400 new_time_window
.time_width
),
3401 time_span
.end_time
);
3404 /* Fix the time width to fit start time and end time */
3405 new_time_window
.time_width
= ltt_time_sub(end_time
,
3406 new_time_window
.start_time
);
3407 new_time_window
.time_width_double
=
3408 ltt_time_to_double(new_time_window
.time_width
);
3410 new_time_window
.end_time
= end_time
;
3412 time_change_manager(tab
, new_time_window
);
3417 on_MEntry2_value_changed (GtkSpinButton
*spinbutton
,
3420 Tab
*tab
=(Tab
*)user_data
;
3421 LttvTracesetContext
* tsc
=
3422 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3423 TimeInterval time_span
= tsc
->time_span
;
3424 gint value
= gtk_spin_button_get_value_as_int(spinbutton
);
3426 TimeWindow new_time_window
= tab
->time_window
;
3428 LttTime end_time
= new_time_window
.end_time
;
3430 new_time_window
.start_time
.tv_nsec
= value
;
3432 if(ltt_time_compare(new_time_window
.start_time
, end_time
) >= 0) {
3433 /* Then, we must push back end time : keep the same time width
3434 * if possible, else end traceset time */
3435 end_time
= LTT_TIME_MIN(ltt_time_add(new_time_window
.start_time
,
3436 new_time_window
.time_width
),
3437 time_span
.end_time
);
3440 /* Fix the time width to fit start time and end time */
3441 new_time_window
.time_width
= ltt_time_sub(end_time
,
3442 new_time_window
.start_time
);
3443 new_time_window
.time_width_double
=
3444 ltt_time_to_double(new_time_window
.time_width
);
3446 new_time_window
.end_time
= end_time
;
3448 time_change_manager(tab
, new_time_window
);
3453 on_MEntry3_value_changed (GtkSpinButton
*spinbutton
,
3456 Tab
*tab
=(Tab
*)user_data
;
3457 LttvTracesetContext
* tsc
=
3458 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3459 TimeInterval time_span
= tsc
->time_span
;
3460 gint value
= gtk_spin_button_get_value_as_int(spinbutton
);
3462 TimeWindow new_time_window
= tab
->time_window
;
3464 LttTime end_time
= new_time_window
.end_time
;
3466 end_time
.tv_sec
= value
;
3468 /* end nanoseconds */
3469 if(end_time
.tv_sec
== time_span
.start_time
.tv_sec
) {
3470 if(end_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3471 if(end_time
.tv_nsec
> time_span
.end_time
.tv_nsec
)
3472 end_time
.tv_nsec
= time_span
.end_time
.tv_nsec
;
3473 if(end_time
.tv_nsec
< time_span
.start_time
.tv_nsec
)
3474 end_time
.tv_nsec
= time_span
.start_time
.tv_nsec
+1;
3476 if(end_time
.tv_nsec
< time_span
.start_time
.tv_nsec
)
3477 end_time
.tv_nsec
= time_span
.start_time
.tv_nsec
+1;
3480 else if(end_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3481 if(end_time
.tv_nsec
> time_span
.end_time
.tv_nsec
)
3482 end_time
.tv_nsec
= time_span
.end_time
.tv_nsec
;
3485 if(ltt_time_compare(new_time_window
.start_time
, end_time
) >= 0) {
3486 /* Then, we must push front start time : keep the same time width
3487 * if possible, else end traceset time */
3488 new_time_window
.start_time
= LTT_TIME_MAX(
3489 ltt_time_sub(end_time
,
3490 new_time_window
.time_width
),
3491 time_span
.start_time
);
3494 /* Fix the time width to fit start time and end time */
3495 new_time_window
.time_width
= ltt_time_sub(end_time
,
3496 new_time_window
.start_time
);
3497 new_time_window
.time_width_double
=
3498 ltt_time_to_double(new_time_window
.time_width
);
3500 new_time_window
.end_time
= end_time
;
3502 time_change_manager(tab
, new_time_window
);
3507 on_MEntry4_value_changed (GtkSpinButton
*spinbutton
,
3510 Tab
*tab
=(Tab
*)user_data
;
3511 LttvTracesetContext
* tsc
=
3512 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3513 TimeInterval time_span
= tsc
->time_span
;
3514 gint value
= gtk_spin_button_get_value_as_int(spinbutton
);
3516 TimeWindow new_time_window
= tab
->time_window
;
3518 LttTime end_time
= new_time_window
.end_time
;
3520 end_time
.tv_nsec
= value
;
3522 if(ltt_time_compare(new_time_window
.start_time
, end_time
) >= 0) {
3523 /* Then, we must push front start time : keep the same time width
3524 * if possible, else end traceset time */
3525 new_time_window
.start_time
= LTT_TIME_MAX(
3526 ltt_time_sub(end_time
,
3527 new_time_window
.time_width
),
3528 time_span
.start_time
);
3531 /* Fix the time width to fit start time and end time */
3532 new_time_window
.time_width
= ltt_time_sub(end_time
,
3533 new_time_window
.start_time
);
3534 new_time_window
.time_width_double
=
3535 ltt_time_to_double(new_time_window
.time_width
);
3536 new_time_window
.end_time
= end_time
;
3538 time_change_manager(tab
, new_time_window
);
3543 void current_time_change_manager (Tab
*tab
,
3544 LttTime new_current_time
)
3546 /* Only one source of time change */
3547 if(tab
->current_time_manager_lock
== TRUE
) return;
3549 tab
->current_time_manager_lock
= TRUE
;
3551 LttvTracesetContext
*tsc
= LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3552 TimeInterval time_span
= tsc
->time_span
;
3554 /* current seconds */
3555 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry5
),
3556 (double)time_span
.start_time
.tv_sec
,
3557 (double)time_span
.end_time
.tv_sec
);
3558 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry5
),
3559 (double)new_current_time
.tv_sec
);
3562 /* start nanoseconds */
3563 if(new_current_time
.tv_sec
== time_span
.start_time
.tv_sec
) {
3564 /* can be both beginning and end at the same time. */
3565 if(new_current_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3566 /* If we are at the end, max nsec to end.. */
3567 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry6
),
3568 (double)time_span
.start_time
.tv_nsec
,
3569 (double)time_span
.end_time
.tv_nsec
);
3571 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry6
),
3572 (double)time_span
.start_time
.tv_nsec
,
3573 (double)NANOSECONDS_PER_SECOND
-1);
3575 } else if(new_current_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3576 /* If we are at the end, max nsec to end.. */
3577 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry6
),
3579 (double)time_span
.end_time
.tv_nsec
);
3580 } else /* anywhere else */
3581 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry6
),
3583 (double)NANOSECONDS_PER_SECOND
-1);
3585 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry6
),
3586 (double)new_current_time
.tv_nsec
);
3588 set_current_time(tab
, &new_current_time
);
3590 tab
->current_time_manager_lock
= FALSE
;
3593 void current_position_change_manager(Tab
*tab
,
3594 LttvTracesetContextPosition
*pos
)
3596 LttvTracesetContext
*tsc
=
3597 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3598 TimeInterval time_span
= tsc
->time_span
;
3600 g_assert(lttv_process_traceset_seek_position(tsc
, pos
) == 0);
3601 LttTime new_time
= lttv_traceset_context_position_get_time(pos
);
3603 current_time_change_manager(tab
, new_time
);
3605 set_current_position(tab
, pos
);
3610 on_MEntry5_value_changed (GtkSpinButton
*spinbutton
,
3613 Tab
*tab
= (Tab
*)user_data
;
3614 LttvTracesetContext
* tsc
=
3615 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3616 TimeInterval time_span
= tsc
->time_span
;
3617 gint value
= gtk_spin_button_get_value_as_int(spinbutton
);
3618 LttTime new_current_time
= tab
->current_time
;
3619 new_current_time
.tv_sec
= value
;
3621 /* current nanoseconds */
3622 if(new_current_time
.tv_sec
== time_span
.start_time
.tv_sec
) {
3623 if(new_current_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3624 if(new_current_time
.tv_nsec
> time_span
.end_time
.tv_nsec
)
3625 new_current_time
.tv_nsec
= time_span
.end_time
.tv_nsec
;
3626 if(new_current_time
.tv_nsec
< time_span
.start_time
.tv_nsec
)
3627 new_current_time
.tv_nsec
= time_span
.start_time
.tv_nsec
;
3629 if(new_current_time
.tv_nsec
< time_span
.start_time
.tv_nsec
)
3630 new_current_time
.tv_nsec
= time_span
.start_time
.tv_nsec
;
3633 else if(new_current_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3634 if(new_current_time
.tv_nsec
> time_span
.end_time
.tv_nsec
)
3635 new_current_time
.tv_nsec
= time_span
.end_time
.tv_nsec
;
3638 current_time_change_manager(tab
, new_current_time
);
3642 on_MEntry6_value_changed (GtkSpinButton
*spinbutton
,
3645 Tab
*tab
= (Tab
*)user_data
;
3646 gint value
= gtk_spin_button_get_value_as_int(spinbutton
);
3647 LttTime new_current_time
= tab
->current_time
;
3648 new_current_time
.tv_nsec
= value
;
3650 current_time_change_manager(tab
, new_current_time
);
3654 void scroll_value_changed_cb(GtkWidget
*scrollbar
,
3657 Tab
*tab
= (Tab
*)user_data
;
3658 TimeWindow new_time_window
;
3660 GtkAdjustment
*adjust
= gtk_range_get_adjustment(GTK_RANGE(scrollbar
));
3661 gdouble value
= gtk_adjustment_get_value(adjust
);
3662 // gdouble upper, lower, ratio, page_size;
3664 LttvTracesetContext
* tsc
=
3665 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3666 TimeInterval time_span
= tsc
->time_span
;
3668 time
= ltt_time_add(ltt_time_from_double(value
),
3669 time_span
.start_time
);
3671 new_time_window
.start_time
= time
;
3673 page_size
= adjust
->page_size
;
3675 new_time_window
.time_width
=
3676 ltt_time_from_double(page_size
);
3678 new_time_window
.time_width_double
=
3681 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
3682 new_time_window
.time_width
);
3685 time_change_manager(tab
, new_time_window
);
3687 //time_window = tab->time_window;
3689 lower
= adjust
->lower
;
3690 upper
= adjust
->upper
;
3691 ratio
= (value
- lower
) / (upper
- lower
);
3692 g_info("lower %lu, upper %lu, value %lu, ratio %lu", lower
, upper
, value
, ratio
);
3694 //time = ltt_time_sub(time_span->end_time, time_span->start_time);
3695 //time = ltt_time_mul(time, (float)ratio);
3696 //time = ltt_time_add(time_span->start_time, time);
3697 time
= ltt_time_add(ltt_time_from_double(value
),
3698 time_span
.start_time
);
3700 time_window
.start_time
= time
;
3702 page_size
= adjust
->page_size
;
3704 time_window
.time_width
=
3705 ltt_time_from_double(page_size
);
3706 //time = ltt_time_sub(time_span.end_time, time);
3707 //if(ltt_time_compare(time,time_window.time_width) < 0){
3708 // time_window.time_width = time;
3711 /* call viewer hooks for new time window */
3712 set_time_window(tab
, &time_window
);
3717 /* Display a dialogue showing all eventtypes and traces, let user to select the interested
3718 * eventtypes, tracefiles and traces (filter)
3721 /* Select a trace which will be removed from traceset
3724 char * get_remove_trace(char ** all_trace_name
, int nb_trace
)
3726 return get_selection(all_trace_name
, nb_trace
,
3727 "Select a trace", "Trace pathname");
3731 /* Select a module which will be loaded
3734 char * get_load_module(char ** load_module_name
, int nb_module
)
3736 return get_selection(load_module_name
, nb_module
,
3737 "Select a module to load", "Module name");
3743 /* Select a module which will be unloaded
3746 char * get_unload_module(char ** loaded_module_name
, int nb_module
)
3748 return get_selection(loaded_module_name
, nb_module
,
3749 "Select a module to unload", "Module name");
3753 /* Display a dialogue which shows all selectable items, let user to
3754 * select one of them
3757 char * get_selection(char ** loaded_module_name
, int nb_module
,
3758 char *title
, char * column_title
)
3760 GtkWidget
* dialogue
;
3761 GtkWidget
* scroll_win
;
3763 GtkListStore
* store
;
3764 GtkTreeViewColumn
* column
;
3765 GtkCellRenderer
* renderer
;
3766 GtkTreeSelection
* select
;
3769 char * unload_module_name
= NULL
;
3771 dialogue
= gtk_dialog_new_with_buttons(title
,
3774 GTK_STOCK_OK
,GTK_RESPONSE_ACCEPT
,
3775 GTK_STOCK_CANCEL
,GTK_RESPONSE_REJECT
,
3777 gtk_window_set_default_size((GtkWindow
*)dialogue
, 500, 200);
3779 scroll_win
= gtk_scrolled_window_new (NULL
, NULL
);
3780 gtk_widget_show ( scroll_win
);
3781 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll_win
),
3782 GTK_POLICY_AUTOMATIC
, GTK_POLICY_AUTOMATIC
);
3784 store
= gtk_list_store_new (N_COLUMNS
,G_TYPE_STRING
);
3785 tree
= gtk_tree_view_new_with_model(GTK_TREE_MODEL (store
));
3786 gtk_widget_show ( tree
);
3787 g_object_unref (G_OBJECT (store
));
3789 renderer
= gtk_cell_renderer_text_new ();
3790 column
= gtk_tree_view_column_new_with_attributes (column_title
,
3792 "text", MODULE_COLUMN
,
3794 gtk_tree_view_column_set_alignment (column
, 0.5);
3795 gtk_tree_view_column_set_fixed_width (column
, 150);
3796 gtk_tree_view_append_column (GTK_TREE_VIEW (tree
), column
);
3798 select
= gtk_tree_view_get_selection (GTK_TREE_VIEW (tree
));
3799 gtk_tree_selection_set_mode (select
, GTK_SELECTION_SINGLE
);
3801 gtk_container_add (GTK_CONTAINER (scroll_win
), tree
);
3803 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialogue
)->vbox
), scroll_win
,TRUE
, TRUE
,0);
3805 for(i
=0;i
<nb_module
;i
++){
3806 gtk_list_store_append (store
, &iter
);
3807 gtk_list_store_set (store
, &iter
, MODULE_COLUMN
,loaded_module_name
[i
],-1);
3810 id
= gtk_dialog_run(GTK_DIALOG(dialogue
));
3811 GtkTreeModel
**store_model
= (GtkTreeModel
**)&store
;
3813 case GTK_RESPONSE_ACCEPT
:
3814 case GTK_RESPONSE_OK
:
3815 if (gtk_tree_selection_get_selected (select
, store_model
, &iter
)){
3816 gtk_tree_model_get ((GtkTreeModel
*)store
, &iter
, MODULE_COLUMN
, &unload_module_name
, -1);
3818 case GTK_RESPONSE_REJECT
:
3819 case GTK_RESPONSE_CANCEL
:
3821 gtk_widget_destroy(dialogue
);
3825 return unload_module_name
;
3829 /* Insert all menu entry and tool buttons into this main window
3834 void add_all_menu_toolbar_constructors(MainWindow
* mw
, gpointer user_data
)
3838 lttvwindow_viewer_constructor constructor
;
3839 LttvMenus
* global_menu
, * instance_menu
;
3840 LttvToolbars
* global_toolbar
, * instance_toolbar
;
3841 LttvMenuClosure
*menu_item
;
3842 LttvToolbarClosure
*toolbar_item
;
3843 LttvAttributeValue value
;
3844 LttvIAttribute
*global_attributes
= LTTV_IATTRIBUTE(lttv_global_attributes());
3845 LttvIAttribute
*attributes
= mw
->attributes
;
3846 GtkWidget
* tool_menu_title_menu
, *new_widget
, *pixmap
;
3848 g_assert(lttv_iattribute_find_by_path(global_attributes
,
3849 "viewers/menu", LTTV_POINTER
, &value
));
3850 if(*(value
.v_pointer
) == NULL
)
3851 *(value
.v_pointer
) = lttv_menus_new();
3852 global_menu
= (LttvMenus
*)*(value
.v_pointer
);
3854 g_assert(lttv_iattribute_find_by_path(attributes
,
3855 "viewers/menu", LTTV_POINTER
, &value
));
3856 if(*(value
.v_pointer
) == NULL
)
3857 *(value
.v_pointer
) = lttv_menus_new();
3858 instance_menu
= (LttvMenus
*)*(value
.v_pointer
);
3862 g_assert(lttv_iattribute_find_by_path(global_attributes
,
3863 "viewers/toolbar", LTTV_POINTER
, &value
));
3864 if(*(value
.v_pointer
) == NULL
)
3865 *(value
.v_pointer
) = lttv_toolbars_new();
3866 global_toolbar
= (LttvToolbars
*)*(value
.v_pointer
);
3868 g_assert(lttv_iattribute_find_by_path(attributes
,
3869 "viewers/toolbar", LTTV_POINTER
, &value
));
3870 if(*(value
.v_pointer
) == NULL
)
3871 *(value
.v_pointer
) = lttv_toolbars_new();
3872 instance_toolbar
= (LttvToolbars
*)*(value
.v_pointer
);
3874 /* Add missing menu entries to window instance */
3875 for(i
=0;i
<global_menu
->len
;i
++) {
3876 menu_item
= &g_array_index(global_menu
, LttvMenuClosure
, i
);
3878 //add menu_item to window instance;
3879 constructor
= menu_item
->con
;
3880 tool_menu_title_menu
= lookup_widget(mw
->mwindow
,"ToolMenuTitle_menu");
3882 gtk_menu_item_new_with_mnemonic (menu_item
->menu_text
);
3883 gtk_container_add (GTK_CONTAINER (tool_menu_title_menu
),
3885 g_signal_connect ((gpointer
) new_widget
, "activate",
3886 G_CALLBACK (insert_viewer_wrap
),
3888 gtk_widget_show (new_widget
);
3889 lttv_menus_add(instance_menu
, menu_item
->con
,
3890 menu_item
->menu_path
,
3891 menu_item
->menu_text
,
3896 /* Add missing toolbar entries to window instance */
3897 for(i
=0;i
<global_toolbar
->len
;i
++) {
3898 toolbar_item
= &g_array_index(global_toolbar
, LttvToolbarClosure
, i
);
3900 //add toolbar_item to window instance;
3901 constructor
= toolbar_item
->con
;
3902 tool_menu_title_menu
= lookup_widget(mw
->mwindow
,"MToolbar1");
3903 pixbuf
= gdk_pixbuf_new_from_xpm_data((const char**)toolbar_item
->pixmap
);
3904 pixmap
= gtk_image_new_from_pixbuf(pixbuf
);
3906 gtk_toolbar_append_element (GTK_TOOLBAR (tool_menu_title_menu
),
3907 GTK_TOOLBAR_CHILD_BUTTON
,
3910 toolbar_item
->tooltip
, NULL
,
3911 pixmap
, NULL
, NULL
);
3912 gtk_label_set_use_underline(
3913 GTK_LABEL (((GtkToolbarChild
*) (
3914 g_list_last (GTK_TOOLBAR
3915 (tool_menu_title_menu
)->children
)->data
))->label
),
3917 gtk_container_set_border_width (GTK_CONTAINER (new_widget
), 1);
3918 g_signal_connect ((gpointer
) new_widget
,
3920 G_CALLBACK (insert_viewer_wrap
),
3922 gtk_widget_show (new_widget
);
3924 lttv_toolbars_add(instance_toolbar
, toolbar_item
->con
,
3925 toolbar_item
->tooltip
,
3926 toolbar_item
->pixmap
,
3934 /* Create a main window
3937 void construct_main_window(MainWindow
* parent
)
3939 g_debug("construct_main_window()");
3940 GtkWidget
* new_window
; /* New generated main window */
3941 MainWindow
* new_m_window
;/* New main window structure */
3942 GtkNotebook
* notebook
;
3943 LttvIAttribute
*attributes
=
3944 LTTV_IATTRIBUTE(g_object_new(LTTV_ATTRIBUTE_TYPE
, NULL
));
3945 LttvAttributeValue value
;
3948 new_m_window
= g_new(MainWindow
, 1);
3950 // Add the object's information to the module's array
3951 g_main_window_list
= g_slist_append(g_main_window_list
, new_m_window
);
3953 new_window
= create_MWindow();
3954 gtk_widget_show (new_window
);
3956 new_m_window
->mwindow
= new_window
;
3957 new_m_window
->attributes
= attributes
;
3959 g_assert(lttv_iattribute_find_by_path(attributes
,
3960 "viewers/menu", LTTV_POINTER
, &value
));
3961 *(value
.v_pointer
) = lttv_menus_new();
3963 g_assert(lttv_iattribute_find_by_path(attributes
,
3964 "viewers/toolbar", LTTV_POINTER
, &value
));
3965 *(value
.v_pointer
) = lttv_toolbars_new();
3967 add_all_menu_toolbar_constructors(new_m_window
, NULL
);
3969 g_object_set_data_full(G_OBJECT(new_window
),
3971 (gpointer
)new_m_window
,
3972 (GDestroyNotify
)g_free
);
3973 //create a default tab
3974 notebook
= (GtkNotebook
*)lookup_widget(new_m_window
->mwindow
, "MNotebook");
3975 if(notebook
== NULL
){
3976 g_info("Notebook does not exist\n");
3979 //gtk_notebook_popup_enable (GTK_NOTEBOOK(notebook));
3980 //for now there is no name field in LttvTraceset structure
3981 //Use "Traceset" as the label for the default tab
3983 GtkWidget
* parent_notebook
= lookup_widget(parent
->mwindow
, "MNotebook");
3984 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(parent_notebook
),
3985 gtk_notebook_get_current_page(GTK_NOTEBOOK(parent_notebook
)));
3991 parent_tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
3993 new_tab
= create_tab(new_m_window
, parent_tab
, notebook
, "Traceset");
3995 new_tab
= create_tab(new_m_window
, NULL
, notebook
, "Traceset");
3996 /* First window, use command line trace */
3997 if(g_init_trace
!= NULL
){
3998 lttvwindow_add_trace(new_tab
,
4002 LttvTraceset
*traceset
= new_tab
->traceset_info
->traceset
;
4003 SetTraceset(new_tab
, traceset
);
4005 /* Insert default viewers */
4007 LttvAttributeType type
;
4008 LttvAttributeName name
;
4009 LttvAttributeValue value
;
4010 LttvAttribute
*attribute
;
4012 LttvIAttribute
*attributes_global
=
4013 LTTV_IATTRIBUTE(lttv_global_attributes());
4015 g_assert(attribute
=
4016 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
4017 LTTV_IATTRIBUTE(attributes_global
),
4018 LTTV_VIEWER_CONSTRUCTORS
)));
4020 name
= g_quark_from_string("guievents");
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
);
4029 name
= g_quark_from_string("guicontrolflow");
4030 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
4032 if(type
== LTTV_POINTER
) {
4033 lttvwindow_viewer_constructor viewer_constructor
=
4034 (lttvwindow_viewer_constructor
)*value
.v_pointer
;
4035 insert_viewer(new_window
, viewer_constructor
);
4038 name
= g_quark_from_string("guistatistics");
4039 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
4041 if(type
== LTTV_POINTER
) {
4042 lttvwindow_viewer_constructor viewer_constructor
=
4043 (lttvwindow_viewer_constructor
)*value
.v_pointer
;
4044 insert_viewer(new_window
, viewer_constructor
);
4050 g_info("There are now : %d windows\n",g_slist_length(g_main_window_list
));
4054 /* Free the memory occupied by a tab structure
4058 void tab_destructor(Tab
* tab
)
4060 int i
, nb
, ref_count
;
4063 gtk_object_destroy(GTK_OBJECT(tab
->tooltips
));
4066 g_object_unref(tab
->attributes
);
4068 if(tab
->interrupted_state
)
4069 g_object_unref(tab
->interrupted_state
);
4072 if(tab
->traceset_info
->traceset_context
!= NULL
){
4073 //remove state update hooks
4074 lttv_state_remove_event_hooks(
4075 (LttvTracesetState
*)tab
->traceset_info
->
4077 lttv_context_fini(LTTV_TRACESET_CONTEXT(tab
->traceset_info
->
4079 g_object_unref(tab
->traceset_info
->traceset_context
);
4081 if(tab
->traceset_info
->traceset
!= NULL
) {
4082 nb
= lttv_traceset_number(tab
->traceset_info
->traceset
);
4083 for(i
= 0 ; i
< nb
; i
++) {
4084 trace
= lttv_traceset_get(tab
->traceset_info
->traceset
, i
);
4085 ref_count
= lttv_trace_get_ref_number(trace
);
4087 ltt_trace_close(lttv_trace(trace
));
4091 lttv_filter_destroy(tab
->filter
);
4092 lttv_traceset_destroy(tab
->traceset_info
->traceset
);
4093 /* Remove the idle events requests processing function of the tab */
4094 g_idle_remove_by_data(tab
);
4096 g_slist_free(tab
->events_requests
);
4097 g_free(tab
->traceset_info
);
4102 /* Create a tab and insert it into the current main window
4105 Tab
* create_tab(MainWindow
* mw
, Tab
*copy_tab
,
4106 GtkNotebook
* notebook
, char * label
)
4111 //create a new tab data structure
4114 //construct and initialize the traceset_info
4115 tab
->traceset_info
= g_new(TracesetInfo
,1);
4118 tab
->traceset_info
->traceset
=
4119 lttv_traceset_copy(copy_tab
->traceset_info
->traceset
);
4121 /* Copy the previous tab's filter */
4122 /* We can clone the filter, as we copy the trace set also */
4123 /* The filter must always be in sync with the trace set */
4124 tab
->filter
= lttv_filter_clone(copy_tab
->filter
);
4127 tab
->traceset_info
->traceset
= lttv_traceset_new();
4132 lttv_attribute_write_xml(
4133 lttv_traceset_attribute(tab
->traceset_info
->traceset
),
4139 tab
->time_manager_lock
= FALSE
;
4140 tab
->current_time_manager_lock
= FALSE
;
4142 //FIXME copy not implemented in lower level
4143 tab
->traceset_info
->traceset_context
=
4144 g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
4145 g_assert(tab
->traceset_info
->traceset_context
!= NULL
);
4147 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
),
4148 tab
->traceset_info
->traceset
);
4149 //add state update hooks
4150 lttv_state_add_event_hooks(
4151 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
4153 //determine the current_time and time_window of the tab
4155 if(copy_tab
!= NULL
){
4156 tab
->time_window
= copy_tab
->time_window
;
4157 tab
->current_time
= copy_tab
->current_time
;
4159 tab
->time_window
.start_time
=
4160 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
4161 time_span
.start_time
;
4162 if(DEFAULT_TIME_WIDTH_S
<
4163 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
4164 time_span
.end_time
.tv_sec
)
4165 tmp_time
.tv_sec
= DEFAULT_TIME_WIDTH_S
;
4168 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
4169 time_span
.end_time
.tv_sec
;
4170 tmp_time
.tv_nsec
= 0;
4171 tab
->time_window
.time_width
= tmp_time
;
4172 tab
->current_time
.tv_sec
=
4173 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
4174 time_span
.start_time
.tv_sec
;
4175 tab
->current_time
.tv_nsec
=
4176 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
4177 time_span
.start_time
.tv_nsec
;
4180 tab
->attributes
= LTTV_IATTRIBUTE(g_object_new(LTTV_ATTRIBUTE_TYPE
, NULL
));
4181 tab
->interrupted_state
= g_object_new(LTTV_ATTRIBUTE_TYPE
, NULL
);
4183 tab
->vbox
= gtk_vbox_new(FALSE
, 2);
4184 tab
->viewer_container
= gtk_vbox_new(TRUE
, 2);
4185 tab
->scrollbar
= gtk_hscrollbar_new(NULL
);
4186 //tab->multivpaned = gtk_multi_vpaned_new();
4187 tab
->time_window
.start_time
= ltt_time_zero
;
4188 tab
->time_window
.end_time
= ltt_time_zero
;
4189 tab
->time_window
.time_width
= ltt_time_zero
;
4190 tab
->current_time
= ltt_time_zero
;
4192 gtk_box_pack_start(GTK_BOX(tab
->vbox
),
4193 tab
->viewer_container
,
4195 TRUE
, /* Give the extra space to the child */
4196 0); /* No padding */
4198 /* Create the timebar */
4200 tab
->MTimebar
= gtk_hbox_new(FALSE
, 2);
4201 gtk_widget_show(tab
->MTimebar
);
4202 tab
->tooltips
= gtk_tooltips_new();
4204 tab
->MEventBox1a
= gtk_event_box_new();
4205 gtk_widget_show(tab
->MEventBox1a
);
4206 gtk_tooltips_set_tip(tab
->tooltips
, tab
->MEventBox1a
,
4207 "Paste Start and End Times Here", "");
4208 tab
->MText1a
= gtk_label_new("Time Frame ");
4209 gtk_widget_show(tab
->MText1a
);
4210 gtk_container_add(GTK_CONTAINER(tab
->MEventBox1a
), tab
->MText1a
);
4211 tab
->MEventBox1b
= gtk_event_box_new();
4212 gtk_widget_show(tab
->MEventBox1b
);
4213 gtk_tooltips_set_tip(tab
->tooltips
, tab
->MEventBox1b
,
4214 "Paste Start Time Here", "");
4215 tab
->MText1b
= gtk_label_new("start: ");
4216 gtk_widget_show(tab
->MText1b
);
4217 gtk_container_add(GTK_CONTAINER(tab
->MEventBox1b
), tab
->MText1b
);
4218 tab
->MText2
= gtk_label_new("s");
4219 gtk_widget_show(tab
->MText2
);
4220 tab
->MText3a
= gtk_label_new("ns");
4221 gtk_widget_show(tab
->MText3a
);
4222 tab
->MEventBox3b
= gtk_event_box_new();
4223 gtk_widget_show(tab
->MEventBox3b
);
4224 gtk_tooltips_set_tip(tab
->tooltips
, tab
->MEventBox3b
,
4225 "Paste End Time Here", "");
4226 tab
->MText3b
= gtk_label_new("end:");
4227 gtk_widget_show(tab
->MText3b
);
4228 gtk_container_add(GTK_CONTAINER(tab
->MEventBox3b
), tab
->MText3b
);
4229 tab
->MText4
= gtk_label_new("s");
4230 gtk_widget_show(tab
->MText4
);
4231 tab
->MText5a
= gtk_label_new("ns");
4232 gtk_widget_show(tab
->MText5a
);
4233 tab
->MEventBox5b
= gtk_event_box_new();
4234 gtk_widget_show(tab
->MEventBox5b
);
4235 gtk_tooltips_set_tip(tab
->tooltips
, tab
->MEventBox5b
,
4236 "Paste Current Time Here", "");
4237 tab
->MText5b
= gtk_label_new("Current Time:");
4238 gtk_widget_show(tab
->MText5b
);
4239 gtk_container_add(GTK_CONTAINER(tab
->MEventBox5b
), tab
->MText5b
);
4240 tab
->MText6
= gtk_label_new("s");
4241 gtk_widget_show(tab
->MText6
);
4242 tab
->MText7
= gtk_label_new("ns");
4243 gtk_widget_show(tab
->MText7
);
4245 tab
->MEntry1
= gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4246 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab
->MEntry1
),0);
4247 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab
->MEntry1
),TRUE
);
4248 gtk_widget_show(tab
->MEntry1
);
4249 tab
->MEntry2
= gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4250 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab
->MEntry2
),0);
4251 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab
->MEntry2
),TRUE
);
4252 gtk_widget_show(tab
->MEntry2
);
4253 tab
->MEntry3
= gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4254 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab
->MEntry3
),0);
4255 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab
->MEntry3
),TRUE
);
4256 gtk_widget_show(tab
->MEntry3
);
4257 tab
->MEntry4
= gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4258 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab
->MEntry4
),0);
4259 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab
->MEntry4
),TRUE
);
4260 gtk_widget_show(tab
->MEntry4
);
4261 tab
->MEntry5
= gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4262 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab
->MEntry5
),0);
4263 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab
->MEntry5
),TRUE
);
4264 gtk_widget_show(tab
->MEntry5
);
4265 tab
->MEntry6
= gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4266 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab
->MEntry6
),0);
4267 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab
->MEntry6
),TRUE
);
4268 gtk_widget_show(tab
->MEntry6
);
4271 GtkWidget
*temp_widget
;
4273 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEventBox1a
, FALSE
,
4275 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEventBox1b
, FALSE
,
4277 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEntry1
, FALSE
, FALSE
, 0);
4278 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MText2
, FALSE
, FALSE
, 0);
4279 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEntry2
, FALSE
, FALSE
, 0);
4280 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MText3a
, FALSE
, FALSE
, 0);
4281 temp_widget
= gtk_vseparator_new();
4282 gtk_widget_show(temp_widget
);
4283 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), temp_widget
, FALSE
, FALSE
, 0);
4284 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEventBox3b
, FALSE
,
4286 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEntry3
, FALSE
, FALSE
, 0);
4287 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MText4
, FALSE
, FALSE
, 0);
4288 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEntry4
, FALSE
, FALSE
, 0);
4289 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MText5a
, FALSE
, FALSE
, 0);
4290 temp_widget
= gtk_vseparator_new();
4291 gtk_widget_show(temp_widget
);
4292 gtk_box_pack_end (GTK_BOX (tab
->MTimebar
), tab
->MText7
, FALSE
, FALSE
, 0);
4293 gtk_box_pack_end (GTK_BOX (tab
->MTimebar
), tab
->MEntry6
, FALSE
, FALSE
, 0);
4294 gtk_box_pack_end (GTK_BOX (tab
->MTimebar
), tab
->MText6
, FALSE
, FALSE
, 0);
4295 gtk_box_pack_end (GTK_BOX (tab
->MTimebar
), tab
->MEntry5
, FALSE
, FALSE
, 0);
4296 gtk_box_pack_end (GTK_BOX (tab
->MTimebar
), tab
->MEventBox5b
, FALSE
,
4298 gtk_box_pack_end (GTK_BOX (tab
->MTimebar
), temp_widget
, FALSE
, FALSE
, 0);
4301 //GtkWidget *test = gtk_button_new_with_label("drop");
4302 //gtk_button_set_relief(GTK_BUTTON(test), GTK_RELIEF_NONE);
4303 //gtk_widget_show(test);
4304 //gtk_box_pack_end(GTK_BOX (tab->MTimebar), test, FALSE, FALSE, 0);
4305 //gtk_widget_add_events(tab->MText1, GDK_ALL_EVENTS_MASK);//GDK_BUTTON_PRESS_MASK);
4306 /*GtkWidget *event_box = gtk_event_box_new();
4307 gtk_widget_show(event_box);
4308 gtk_tooltips_set_tip(tooltips, event_box,
4309 "Paste Current Time Here", "");
4310 gtk_box_pack_end(GTK_BOX (tab->MTimebar), event_box, FALSE, FALSE, 0);
4311 GtkWidget *test = gtk_label_new("drop");
4312 gtk_container_add(GTK_CONTAINER(event_box), test);
4313 gtk_widget_show(test);
4314 g_signal_connect (G_OBJECT(event_box),
4315 "button-press-event",
4316 G_CALLBACK (on_MText1_paste),
4320 g_signal_connect (G_OBJECT(tab
->MEventBox1a
),
4321 "button-press-event",
4322 G_CALLBACK (on_MEventBox1a_paste
),
4325 g_signal_connect (G_OBJECT(tab
->MEventBox1b
),
4326 "button-press-event",
4327 G_CALLBACK (on_MEventBox1b_paste
),
4329 g_signal_connect (G_OBJECT(tab
->MEventBox3b
),
4330 "button-press-event",
4331 G_CALLBACK (on_MEventBox3b_paste
),
4333 g_signal_connect (G_OBJECT(tab
->MEventBox5b
),
4334 "button-press-event",
4335 G_CALLBACK (on_MEventBox5b_paste
),
4339 gtk_box_pack_end(GTK_BOX(tab
->vbox
),
4341 FALSE
, /* Do not expand */
4342 FALSE
, /* Fill has no effect here (expand false) */
4343 0); /* No padding */
4345 gtk_box_pack_end(GTK_BOX(tab
->vbox
),
4347 FALSE
, /* Do not expand */
4348 FALSE
, /* Fill has no effect here (expand false) */
4349 0); /* No padding */
4351 g_object_set_data(G_OBJECT(tab
->viewer_container
), "focused_viewer", NULL
);
4357 // Display a label with a X
4358 GtkWidget *w_hbox = gtk_hbox_new(FALSE, 4);
4359 GtkWidget *w_label = gtk_label_new (label);
4360 GtkWidget *pixmap = create_pixmap(GTK_WIDGET(notebook), "close.png");
4361 GtkWidget *w_button = gtk_button_new ();
4362 gtk_container_add(GTK_CONTAINER(w_button), pixmap);
4363 //GtkWidget *w_button = gtk_button_new_with_label("x");
4365 gtk_button_set_relief(GTK_BUTTON(w_button), GTK_RELIEF_NONE);
4367 gtk_box_pack_start(GTK_BOX(w_hbox), w_label, TRUE, TRUE, 0);
4368 gtk_box_pack_end(GTK_BOX(w_hbox), w_button, FALSE,
4371 g_signal_connect_swapped (w_button, "clicked",
4372 G_CALLBACK (on_close_tab_X_clicked),
4375 gtk_widget_set_state(w_button, GTK_STATE_ACTIVE);
4377 gtk_widget_show (w_label);
4378 gtk_widget_show (pixmap);
4379 gtk_widget_show (w_button);
4380 gtk_widget_show (w_hbox);
4382 tab->label = w_hbox;
4386 tab
->label
= gtk_label_new (label
);
4388 gtk_widget_show(tab
->label
);
4389 gtk_widget_show(tab
->scrollbar
);
4390 gtk_widget_show(tab
->viewer_container
);
4391 gtk_widget_show(tab
->vbox
);
4392 //gtk_widget_show(tab->multivpaned);
4395 /* Start with empty events requests list */
4396 tab
->events_requests
= NULL
;
4397 tab
->events_request_pending
= FALSE
;
4399 g_object_set_data_full(
4400 G_OBJECT(tab
->vbox
),
4403 (GDestroyNotify
)tab_destructor
);
4405 g_signal_connect(G_OBJECT(tab
->scrollbar
), "value-changed",
4406 G_CALLBACK(scroll_value_changed_cb
), tab
);
4408 g_signal_connect ((gpointer
) tab
->MEntry1
, "value-changed",
4409 G_CALLBACK (on_MEntry1_value_changed
),
4411 g_signal_connect ((gpointer
) tab
->MEntry2
, "value-changed",
4412 G_CALLBACK (on_MEntry2_value_changed
),
4414 g_signal_connect ((gpointer
) tab
->MEntry3
, "value-changed",
4415 G_CALLBACK (on_MEntry3_value_changed
),
4417 g_signal_connect ((gpointer
) tab
->MEntry4
, "value-changed",
4418 G_CALLBACK (on_MEntry4_value_changed
),
4420 g_signal_connect ((gpointer
) tab
->MEntry5
, "value-changed",
4421 G_CALLBACK (on_MEntry5_value_changed
),
4423 g_signal_connect ((gpointer
) tab
->MEntry6
, "value-changed",
4424 G_CALLBACK (on_MEntry6_value_changed
),
4427 //g_signal_connect(G_OBJECT(tab->scrollbar), "changed",
4428 // G_CALLBACK(scroll_value_changed_cb), tab);
4431 //insert tab into notebook
4432 gtk_notebook_append_page(notebook
,
4435 list
= gtk_container_get_children(GTK_CONTAINER(notebook
));
4436 gtk_notebook_set_current_page(notebook
,g_list_length(list
)-1);
4437 // always show : not if(g_list_length(list)>1)
4438 gtk_notebook_set_show_tabs(notebook
, TRUE
);
4444 * execute_events_requests
4446 * Idle function that executes the pending requests for a tab.
4448 * @return return value : TRUE : keep the idle function, FALSE : remove it.
4450 gboolean
execute_events_requests(Tab
*tab
)
4452 return ( lttvwindow_process_pending_requests(tab
) );