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 static void events_request_free(EventsRequest
*events_request
)
826 if(events_request
== NULL
) return;
828 if(events_request
->start_position
!= NULL
)
829 lttv_traceset_context_position_destroy(events_request
->start_position
);
830 if(events_request
->end_position
!= NULL
)
831 lttv_traceset_context_position_destroy(events_request
->end_position
);
832 if(events_request
->hooks
!= NULL
)
833 g_array_free(events_request
->hooks
, TRUE
);
834 if(events_request
->before_chunk_traceset
!= NULL
)
835 lttv_hooks_destroy(events_request
->before_chunk_traceset
);
836 if(events_request
->before_chunk_trace
!= NULL
)
837 lttv_hooks_destroy(events_request
->before_chunk_trace
);
838 if(events_request
->before_chunk_tracefile
!= NULL
)
839 lttv_hooks_destroy(events_request
->before_chunk_tracefile
);
840 if(events_request
->event
!= NULL
)
841 lttv_hooks_destroy(events_request
->event
);
842 if(events_request
->event_by_id
!= NULL
)
843 lttv_hooks_by_id_destroy(events_request
->event_by_id
);
844 if(events_request
->after_chunk_tracefile
!= NULL
)
845 lttv_hooks_destroy(events_request
->after_chunk_tracefile
);
846 if(events_request
->after_chunk_trace
!= NULL
)
847 lttv_hooks_destroy(events_request
->after_chunk_trace
);
848 if(events_request
->after_chunk_traceset
!= NULL
)
849 lttv_hooks_destroy(events_request
->after_chunk_traceset
);
850 if(events_request
->before_request
!= NULL
)
851 lttv_hooks_destroy(events_request
->before_request
);
852 if(events_request
->after_request
!= NULL
)
853 lttv_hooks_destroy(events_request
->after_request
);
855 g_free(events_request
);
860 /* lttvwindow_process_pending_requests
862 * This internal function gets called by g_idle, taking care of the pending
863 * requests. It is responsible for concatenation of time intervals and position
864 * requests. It does it with the following algorithm organizing process traceset
865 * calls. Here is the detailed description of the way it works :
867 * - Events Requests Servicing Algorithm
869 * Data structures necessary :
871 * List of requests added to context : list_in
872 * List of requests not added to context : list_out
877 * list_out : many events requests
879 * FIXME : insert rest of algorithm here
883 #define list_out tab->events_requests
885 gboolean
lttvwindow_process_pending_requests(Tab
*tab
)
888 LttvTracesetContext
*tsc
;
889 LttvTracefileContext
*tfc
;
890 GSList
*list_in
= NULL
;
894 LttvTracesetContextPosition
*end_position
;
897 g_critical("Foreground processing : tab does not exist. Processing removed.");
901 /* There is no events requests pending : we should never have been called! */
902 g_assert(g_slist_length(list_out
) != 0);
904 tsc
= LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
906 //set the cursor to be X shape, indicating that the computer is busy in doing its job
908 new = gdk_cursor_new(GDK_X_CURSOR
);
909 widget
= lookup_widget(tab
->mw
->mwindow
, "MToolbar1");
910 win
= gtk_widget_get_parent_window(widget
);
911 gdk_window_set_cursor(win
, new);
912 gdk_cursor_unref(new);
913 gdk_window_stick(win
);
914 gdk_window_unstick(win
);
917 g_debug("SIZE events req len : %d", g_slist_length(list_out
));
919 /* Preliminary check for no trace in traceset */
920 /* Unregister the routine if empty, empty list_out too */
921 if(lttv_traceset_number(tsc
->ts
) == 0) {
923 /* - For each req in list_out */
924 GSList
*iter
= list_out
;
926 while(iter
!= NULL
) {
928 gboolean remove
= FALSE
;
929 gboolean free_data
= FALSE
;
930 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
932 /* - Call end request for req */
933 if(events_request
->servicing
== TRUE
)
934 lttv_hooks_call(events_request
->after_request
, (gpointer
)tsc
);
936 /* - remove req from list_out */
937 /* Destroy the request */
944 GSList
*remove_iter
= iter
;
946 iter
= g_slist_next(iter
);
947 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
948 list_out
= g_slist_remove_link(list_out
, remove_iter
);
949 } else { // not remove
950 iter
= g_slist_next(iter
);
955 /* 0.1 Lock Traces */
960 iter_trace
<lttv_traceset_number(tsc
->ts
);
962 LttvTrace
*trace_v
= lttv_traceset_get(tsc
->ts
, iter_trace
);
964 if(lttvwindowtraces_lock(trace_v
) != 0) {
965 g_critical("Foreground processing : Unable to get trace lock");
966 return TRUE
; /* Cannot get lock, try later */
971 /* 0.2 Seek tracefiles positions to context position */
972 //g_assert(lttv_process_traceset_seek_position(tsc, sync_position) == 0);
973 lttv_process_traceset_synchronize_tracefiles(tsc
);
976 /* Events processing algorithm implementation */
977 /* Warning : the gtk_events_pending takes a LOT of cpu time. So what we do
978 * instead is to leave the control to GTK and take it back.
980 /* A. Servicing loop */
981 //while( (g_slist_length(list_in) != 0 || g_slist_length(list_out) != 0)) {
982 if((g_slist_length(list_in
) != 0 || g_slist_length(list_out
) != 0)) {
984 /* 1. If list_in is empty (need a seek) */
985 if( g_slist_length(list_in
) == 0 ) {
987 /* list in is empty, need a seek */
989 /* 1.1 Add requests to list_in */
990 GSList
*ltime
= NULL
;
994 /* 1.1.1 Find all time requests with the lowest start time in list_out
997 if(g_slist_length(list_out
) > 0)
998 ltime
= g_slist_append(ltime
, g_slist_nth_data(list_out
, 0));
999 for(iter
=g_slist_nth(list_out
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
1000 /* Find all time requests with the lowest start time in list_out */
1001 EventsRequest
*event_request_ltime
= (EventsRequest
*)g_slist_nth_data(ltime
, 0);
1002 EventsRequest
*event_request_list_out
= (EventsRequest
*)iter
->data
;
1005 comp
= ltt_time_compare(event_request_ltime
->start_time
,
1006 event_request_list_out
->start_time
);
1008 ltime
= g_slist_append(ltime
, event_request_list_out
);
1010 /* Remove all elements from ltime, and add current */
1011 while(ltime
!= NULL
)
1012 ltime
= g_slist_delete_link(ltime
, g_slist_nth(ltime
, 0));
1013 ltime
= g_slist_append(ltime
, event_request_list_out
);
1017 /* 1.1.2 Find all position requests with the lowest position in list_out
1020 if(g_slist_length(list_out
) > 0)
1021 lpos
= g_slist_append(lpos
, g_slist_nth_data(list_out
, 0));
1022 for(iter
=g_slist_nth(list_out
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
1023 /* Find all position requests with the lowest position in list_out */
1024 EventsRequest
*event_request_lpos
= (EventsRequest
*)g_slist_nth_data(lpos
, 0);
1025 EventsRequest
*event_request_list_out
= (EventsRequest
*)iter
->data
;
1028 if(event_request_lpos
->start_position
!= NULL
1029 && event_request_list_out
->start_position
!= NULL
)
1031 comp
= lttv_traceset_context_pos_pos_compare
1032 (event_request_lpos
->start_position
,
1033 event_request_list_out
->start_position
);
1038 lpos
= g_slist_append(lpos
, event_request_list_out
);
1040 /* Remove all elements from lpos, and add current */
1042 lpos
= g_slist_delete_link(lpos
, g_slist_nth(lpos
, 0));
1043 lpos
= g_slist_append(lpos
, event_request_list_out
);
1048 EventsRequest
*event_request_lpos
= (EventsRequest
*)g_slist_nth_data(lpos
, 0);
1049 EventsRequest
*event_request_ltime
= (EventsRequest
*)g_slist_nth_data(ltime
, 0);
1050 LttTime lpos_start_time
;
1052 if(event_request_lpos
!= NULL
1053 && event_request_lpos
->start_position
!= NULL
) {
1054 lpos_start_time
= lttv_traceset_context_position_get_time(
1055 event_request_lpos
->start_position
);
1058 /* 1.1.3 If lpos.start time < ltime */
1059 if(event_request_lpos
!= NULL
1060 && event_request_lpos
->start_position
!= NULL
1061 && ltt_time_compare(lpos_start_time
,
1062 event_request_ltime
->start_time
)<0) {
1063 /* Add lpos to list_in, remove them from list_out */
1064 for(iter
=lpos
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
1065 /* Add to list_in */
1066 EventsRequest
*event_request_lpos
=
1067 (EventsRequest
*)iter
->data
;
1069 list_in
= g_slist_append(list_in
, event_request_lpos
);
1070 /* Remove from list_out */
1071 list_out
= g_slist_remove(list_out
, event_request_lpos
);
1074 /* 1.1.4 (lpos.start time >= ltime) */
1075 /* Add ltime to list_in, remove them from list_out */
1077 for(iter
=ltime
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
1078 /* Add to list_in */
1079 EventsRequest
*event_request_ltime
=
1080 (EventsRequest
*)iter
->data
;
1082 list_in
= g_slist_append(list_in
, event_request_ltime
);
1083 /* Remove from list_out */
1084 list_out
= g_slist_remove(list_out
, event_request_ltime
);
1089 g_slist_free(ltime
);
1094 tfc
= lttv_traceset_context_get_current_tfc(tsc
);
1095 g_assert(g_slist_length(list_in
)>0);
1096 EventsRequest
*events_request
= g_slist_nth_data(list_in
, 0);
1099 /* 1.2.1 If first request in list_in is a time request */
1100 if(events_request
->start_position
== NULL
) {
1101 /* - If first req in list_in start time != current time */
1102 if(tfc
== NULL
|| ltt_time_compare(events_request
->start_time
,
1103 tfc
->timestamp
) != 0)
1104 /* - Seek to that time */
1105 g_debug("SEEK TIME : %lu, %lu", events_request
->start_time
.tv_sec
,
1106 events_request
->start_time
.tv_nsec
);
1107 //lttv_process_traceset_seek_time(tsc, events_request->start_time);
1108 lttv_state_traceset_seek_time_closest(LTTV_TRACESET_STATE(tsc
),
1109 events_request
->start_time
);
1111 /* Process the traceset with only state hooks */
1113 lttv_process_traceset_middle(tsc
,
1114 events_request
->start_time
,
1116 // g_assert(seek_count < 50000);
1121 /* Else, the first request in list_in is a position request */
1122 /* If first req in list_in pos != current pos */
1123 g_assert(events_request
->start_position
!= NULL
);
1124 g_debug("SEEK POS time : %lu, %lu",
1125 lttv_traceset_context_position_get_time(
1126 events_request
->start_position
).tv_sec
,
1127 lttv_traceset_context_position_get_time(
1128 events_request
->start_position
).tv_nsec
);
1130 g_debug("SEEK POS context time : %lu, %lu",
1131 lttv_traceset_context_get_current_tfc(tsc
)->timestamp
.tv_sec
,
1132 lttv_traceset_context_get_current_tfc(tsc
)->timestamp
.tv_nsec
);
1133 g_assert(events_request
->start_position
!= NULL
);
1134 if(lttv_traceset_context_ctx_pos_compare(tsc
,
1135 events_request
->start_position
) != 0) {
1136 /* 1.2.2.1 Seek to that position */
1137 g_debug("SEEK POSITION");
1138 //lttv_process_traceset_seek_position(tsc, events_request->start_position);
1139 pos_time
= lttv_traceset_context_position_get_time(
1140 events_request
->start_position
);
1142 lttv_state_traceset_seek_time_closest(LTTV_TRACESET_STATE(tsc
),
1145 /* Process the traceset with only state hooks */
1147 lttv_process_traceset_middle(tsc
,
1150 events_request
->start_position
);
1151 g_assert(lttv_traceset_context_ctx_pos_compare(tsc
,
1152 events_request
->start_position
) == 0);
1159 /* 1.3 Add hooks and call before request for all list_in members */
1161 GSList
*iter
= NULL
;
1163 for(iter
=list_in
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
1164 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1165 /* 1.3.1 If !servicing */
1166 if(events_request
->servicing
== FALSE
) {
1167 /* - begin request hooks called
1168 * - servicing = TRUE
1170 lttv_hooks_call(events_request
->before_request
, (gpointer
)tsc
);
1171 events_request
->servicing
= TRUE
;
1173 /* 1.3.2 call before chunk
1174 * 1.3.3 events hooks added
1176 if(events_request
->trace
== -1)
1177 lttv_process_traceset_begin(tsc
,
1178 events_request
->before_chunk_traceset
,
1179 events_request
->before_chunk_trace
,
1180 events_request
->before_chunk_tracefile
,
1181 events_request
->event
,
1182 events_request
->event_by_id
);
1184 guint nb_trace
= lttv_traceset_number(tsc
->ts
);
1185 g_assert((guint
)events_request
->trace
< nb_trace
&&
1186 events_request
->trace
> -1);
1187 LttvTraceContext
*tc
= tsc
->traces
[events_request
->trace
];
1189 lttv_hooks_call(events_request
->before_chunk_traceset
, tsc
);
1191 lttv_trace_context_add_hooks(tc
,
1192 events_request
->before_chunk_trace
,
1193 events_request
->before_chunk_tracefile
,
1194 events_request
->event
,
1195 events_request
->event_by_id
);
1200 /* 2. Else, list_in is not empty, we continue a read */
1203 /* 2.0 For each req of list_in */
1204 GSList
*iter
= list_in
;
1206 while(iter
!= NULL
) {
1208 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1210 /* - Call before chunk
1211 * - events hooks added
1213 if(events_request
->trace
== -1)
1214 lttv_process_traceset_begin(tsc
,
1215 events_request
->before_chunk_traceset
,
1216 events_request
->before_chunk_trace
,
1217 events_request
->before_chunk_tracefile
,
1218 events_request
->event
,
1219 events_request
->event_by_id
);
1221 guint nb_trace
= lttv_traceset_number(tsc
->ts
);
1222 g_assert((guint
)events_request
->trace
< nb_trace
&&
1223 events_request
->trace
> -1);
1224 LttvTraceContext
*tc
= tsc
->traces
[events_request
->trace
];
1226 lttv_hooks_call(events_request
->before_chunk_traceset
, tsc
);
1228 lttv_trace_context_add_hooks(tc
,
1229 events_request
->before_chunk_trace
,
1230 events_request
->before_chunk_tracefile
,
1231 events_request
->event
,
1232 events_request
->event_by_id
);
1235 iter
= g_slist_next(iter
);
1240 tfc
= lttv_traceset_context_get_current_tfc(tsc
);
1242 /* 2.1 For each req of list_out */
1243 GSList
*iter
= list_out
;
1245 while(iter
!= NULL
) {
1247 gboolean remove
= FALSE
;
1248 gboolean free_data
= FALSE
;
1249 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1251 /* if req.start time == current context time
1252 * or req.start position == current position*/
1253 if( ltt_time_compare(events_request
->start_time
,
1254 tfc
->timestamp
) == 0
1256 (events_request
->start_position
!= NULL
1258 lttv_traceset_context_ctx_pos_compare(tsc
,
1259 events_request
->start_position
) == 0)
1261 /* - Add to list_in, remove from list_out */
1262 list_in
= g_slist_append(list_in
, events_request
);
1266 /* - If !servicing */
1267 if(events_request
->servicing
== FALSE
) {
1268 /* - begin request hooks called
1269 * - servicing = TRUE
1271 lttv_hooks_call(events_request
->before_request
, (gpointer
)tsc
);
1272 events_request
->servicing
= TRUE
;
1274 /* call before chunk
1275 * events hooks added
1277 if(events_request
->trace
== -1)
1278 lttv_process_traceset_begin(tsc
,
1279 events_request
->before_chunk_traceset
,
1280 events_request
->before_chunk_trace
,
1281 events_request
->before_chunk_tracefile
,
1282 events_request
->event
,
1283 events_request
->event_by_id
);
1285 guint nb_trace
= lttv_traceset_number(tsc
->ts
);
1286 g_assert((guint
)events_request
->trace
< nb_trace
&&
1287 events_request
->trace
> -1);
1288 LttvTraceContext
*tc
= tsc
->traces
[events_request
->trace
];
1290 lttv_hooks_call(events_request
->before_chunk_traceset
, tsc
);
1292 lttv_trace_context_add_hooks(tc
,
1293 events_request
->before_chunk_trace
,
1294 events_request
->before_chunk_tracefile
,
1295 events_request
->event
,
1296 events_request
->event_by_id
);
1305 GSList
*remove_iter
= iter
;
1307 iter
= g_slist_next(iter
);
1308 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
1309 list_out
= g_slist_remove_link(list_out
, remove_iter
);
1310 } else { // not remove
1311 iter
= g_slist_next(iter
);
1317 /* 3. Find end criterions */
1322 /* 3.1.1 Find lowest end time in list_in */
1323 g_assert(g_slist_length(list_in
)>0);
1324 end_time
= ((EventsRequest
*)g_slist_nth_data(list_in
,0))->end_time
;
1326 for(iter
=g_slist_nth(list_in
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
1327 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1329 if(ltt_time_compare(events_request
->end_time
,
1331 end_time
= events_request
->end_time
;
1334 /* 3.1.2 Find lowest start time in list_out */
1335 for(iter
=list_out
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
1336 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1338 if(ltt_time_compare(events_request
->start_time
,
1340 end_time
= events_request
->start_time
;
1345 /* 3.2 Number of events */
1347 /* 3.2.1 Find lowest number of events in list_in */
1350 end_nb_events
= ((EventsRequest
*)g_slist_nth_data(list_in
,0))->num_events
;
1352 for(iter
=g_slist_nth(list_in
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
1353 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1355 if(events_request
->num_events
< end_nb_events
)
1356 end_nb_events
= events_request
->num_events
;
1359 /* 3.2.2 Use min(CHUNK_NUM_EVENTS, min num events in list_in) as
1362 end_nb_events
= MIN(CHUNK_NUM_EVENTS
, end_nb_events
);
1366 /* 3.3 End position */
1368 /* 3.3.1 Find lowest end position in list_in */
1371 end_position
=((EventsRequest
*)g_slist_nth_data(list_in
,0))->end_position
;
1373 for(iter
=g_slist_nth(list_in
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
1374 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1376 if(events_request
->end_position
!= NULL
&& end_position
!= NULL
&&
1377 lttv_traceset_context_pos_pos_compare(events_request
->end_position
,
1379 end_position
= events_request
->end_position
;
1384 /* 3.3.2 Find lowest start position in list_out */
1387 for(iter
=list_out
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
1388 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1390 if(events_request
->end_position
!= NULL
&& end_position
!= NULL
&&
1391 lttv_traceset_context_pos_pos_compare(events_request
->end_position
,
1393 end_position
= events_request
->end_position
;
1398 /* 4. Call process traceset middle */
1399 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
);
1400 count
= lttv_process_traceset_middle(tsc
, end_time
, end_nb_events
, end_position
);
1402 tfc
= lttv_traceset_context_get_current_tfc(tsc
);
1404 g_debug("Context time after middle : %lu, %lu", tfc
->timestamp
.tv_sec
,
1405 tfc
->timestamp
.tv_nsec
);
1407 g_debug("End of trace reached after middle.");
1411 /* 5. After process traceset middle */
1412 tfc
= lttv_traceset_context_get_current_tfc(tsc
);
1414 /* - if current context time > traceset.end time */
1415 if(tfc
== NULL
|| ltt_time_compare(tfc
->timestamp
,
1416 tsc
->time_span
.end_time
) > 0) {
1417 /* - For each req in list_in */
1418 GSList
*iter
= list_in
;
1420 while(iter
!= NULL
) {
1422 gboolean remove
= FALSE
;
1423 gboolean free_data
= FALSE
;
1424 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1426 /* - Remove events hooks for req
1427 * - Call end chunk for req
1430 if(events_request
->trace
== -1)
1431 lttv_process_traceset_end(tsc
,
1432 events_request
->after_chunk_traceset
,
1433 events_request
->after_chunk_trace
,
1434 events_request
->after_chunk_tracefile
,
1435 events_request
->event
,
1436 events_request
->event_by_id
);
1439 guint nb_trace
= lttv_traceset_number(tsc
->ts
);
1440 g_assert(events_request
->trace
< nb_trace
&&
1441 events_request
->trace
> -1);
1442 LttvTraceContext
*tc
= tsc
->traces
[events_request
->trace
];
1444 lttv_trace_context_remove_hooks(tc
,
1445 events_request
->after_chunk_trace
,
1446 events_request
->after_chunk_tracefile
,
1447 events_request
->event
,
1448 events_request
->event_by_id
);
1449 lttv_hooks_call(events_request
->after_chunk_traceset
, tsc
);
1454 /* - Call end request for req */
1455 lttv_hooks_call(events_request
->after_request
, (gpointer
)tsc
);
1457 /* - remove req from list_in */
1458 /* Destroy the request */
1465 GSList
*remove_iter
= iter
;
1467 iter
= g_slist_next(iter
);
1468 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
1469 list_in
= g_slist_remove_link(list_in
, remove_iter
);
1470 } else { // not remove
1471 iter
= g_slist_next(iter
);
1476 /* 5.1 For each req in list_in */
1477 GSList
*iter
= list_in
;
1479 while(iter
!= NULL
) {
1481 gboolean remove
= FALSE
;
1482 gboolean free_data
= FALSE
;
1483 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1485 /* - Remove events hooks for req
1486 * - Call end chunk for req
1488 if(events_request
->trace
== -1)
1489 lttv_process_traceset_end(tsc
,
1490 events_request
->after_chunk_traceset
,
1491 events_request
->after_chunk_trace
,
1492 events_request
->after_chunk_tracefile
,
1493 events_request
->event
,
1494 events_request
->event_by_id
);
1497 guint nb_trace
= lttv_traceset_number(tsc
->ts
);
1498 g_assert(events_request
->trace
< nb_trace
&&
1499 events_request
->trace
> -1);
1500 LttvTraceContext
*tc
= tsc
->traces
[events_request
->trace
];
1502 lttv_trace_context_remove_hooks(tc
,
1503 events_request
->after_chunk_trace
,
1504 events_request
->after_chunk_tracefile
,
1505 events_request
->event
,
1506 events_request
->event_by_id
);
1508 lttv_hooks_call(events_request
->after_chunk_traceset
, tsc
);
1511 /* - req.num -= count */
1512 g_assert(events_request
->num_events
>= count
);
1513 events_request
->num_events
-= count
;
1515 g_assert(tfc
!= NULL
);
1516 /* - if req.num == 0
1518 * current context time >= req.end time
1520 * req.end pos == current pos
1522 * req.stop_flag == TRUE
1524 if( events_request
->num_events
== 0
1526 events_request
->stop_flag
== TRUE
1528 ltt_time_compare(tfc
->timestamp
,
1529 events_request
->end_time
) >= 0
1531 (events_request
->end_position
!= NULL
1533 lttv_traceset_context_ctx_pos_compare(tsc
,
1534 events_request
->end_position
) == 0)
1537 g_assert(events_request
->servicing
== TRUE
);
1538 /* - Call end request for req
1539 * - remove req from list_in */
1540 lttv_hooks_call(events_request
->after_request
, (gpointer
)tsc
);
1541 /* - remove req from list_in */
1542 /* Destroy the request */
1550 GSList
*remove_iter
= iter
;
1552 iter
= g_slist_next(iter
);
1553 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
1554 list_in
= g_slist_remove_link(list_in
, remove_iter
);
1555 } else { // not remove
1556 iter
= g_slist_next(iter
);
1562 /* End of removed servicing loop : leave control to GTK instead. */
1563 // if(gtk_events_pending()) break;
1566 /* B. When interrupted between chunks */
1569 GSList
*iter
= list_in
;
1571 /* 1. for each request in list_in */
1572 while(iter
!= NULL
) {
1574 gboolean remove
= FALSE
;
1575 gboolean free_data
= FALSE
;
1576 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1578 /* 1.1. Use current postition as start position */
1579 if(events_request
->start_position
!= NULL
)
1580 lttv_traceset_context_position_destroy(events_request
->start_position
);
1581 events_request
->start_position
= lttv_traceset_context_position_new();
1582 lttv_traceset_context_position_save(tsc
, events_request
->start_position
);
1584 /* 1.2. Remove start time */
1585 events_request
->start_time
= ltt_time_infinite
;
1587 /* 1.3. Move from list_in to list_out */
1590 list_out
= g_slist_append(list_out
, events_request
);
1595 GSList
*remove_iter
= iter
;
1597 iter
= g_slist_next(iter
);
1598 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
1599 list_in
= g_slist_remove_link(list_in
, remove_iter
);
1600 } else { // not remove
1601 iter
= g_slist_next(iter
);
1607 /* C Unlock Traces */
1609 lttv_process_traceset_get_sync_data(tsc
);
1610 //lttv_traceset_context_position_save(tsc, sync_position);
1615 iter_trace
<lttv_traceset_number(tsc
->ts
);
1617 LttvTrace
*trace_v
= lttv_traceset_get(tsc
->ts
, iter_trace
);
1619 lttvwindowtraces_unlock(trace_v
);
1623 //set the cursor back to normal
1624 gdk_window_set_cursor(win
, NULL
);
1627 g_assert(g_slist_length(list_in
) == 0);
1629 if( g_slist_length(list_out
) == 0 ) {
1630 /* Put tab's request pending flag back to normal */
1631 tab
->events_request_pending
= FALSE
;
1632 g_debug("remove the idle fct");
1633 return FALSE
; /* Remove the idle function */
1635 g_debug("leave the idle fct");
1636 return TRUE
; /* Leave the idle function */
1638 /* We do not use simili-round-robin, it may require to read 1 meg buffers
1639 * again and again if many tracesets use the same tracefiles. */
1640 /* Hack for round-robin idle functions */
1641 /* It will put the idle function at the end of the pool */
1642 /*g_idle_add_full((G_PRIORITY_HIGH_IDLE + 21),
1643 (GSourceFunc)execute_events_requests,
1653 static void lttvwindow_add_trace(Tab
*tab
, LttvTrace
*trace_v
)
1655 LttvTraceset
*traceset
= tab
->traceset_info
->traceset
;
1657 guint num_traces
= lttv_traceset_number(traceset
);
1659 //Verify if trace is already present.
1660 for(i
=0; i
<num_traces
; i
++)
1662 LttvTrace
* trace
= lttv_traceset_get(traceset
, i
);
1663 if(trace
== trace_v
)
1667 //Keep a reference to the traces so they are not freed.
1668 for(i
=0; i
<lttv_traceset_number(traceset
); i
++)
1670 LttvTrace
* trace
= lttv_traceset_get(traceset
, i
);
1671 lttv_trace_ref(trace
);
1674 //remove state update hooks
1675 lttv_state_remove_event_hooks(
1676 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1678 lttv_context_fini(LTTV_TRACESET_CONTEXT(
1679 tab
->traceset_info
->traceset_context
));
1680 g_object_unref(tab
->traceset_info
->traceset_context
);
1682 lttv_traceset_add(traceset
, trace_v
);
1683 lttv_trace_ref(trace_v
); /* local ref */
1685 /* Create new context */
1686 tab
->traceset_info
->traceset_context
=
1687 g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
1689 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->
1694 //add state update hooks
1695 lttv_state_add_event_hooks(
1696 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1697 //Remove local reference to the traces.
1698 for(i
=0; i
<lttv_traceset_number(traceset
); i
++)
1700 LttvTrace
* trace
= lttv_traceset_get(traceset
, i
);
1701 lttv_trace_unref(trace
);
1705 //add_trace_into_traceset_selector(GTK_MULTIVPANED(tab->multivpaned), lttv_trace(trace_v));
1708 /* add_trace adds a trace into the current traceset. It first displays a
1709 * directory selection dialogue to let user choose a trace, then recreates
1710 * tracset_context, and redraws all the viewer of the current tab
1713 void add_trace(GtkWidget
* widget
, gpointer user_data
)
1716 LttvTrace
* trace_v
;
1717 LttvTraceset
* traceset
;
1719 char abs_path
[PATH_MAX
];
1721 MainWindow
* mw_data
= get_window_data_struct(widget
);
1722 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
1724 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
1725 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
1729 tab
= create_new_tab(widget
, NULL
);
1731 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
1734 GtkDirSelection
* file_selector
= (GtkDirSelection
*)gtk_dir_selection_new("Select a trace");
1735 gtk_dir_selection_hide_fileop_buttons(file_selector
);
1737 if(remember_trace_dir
[0] != '\0')
1738 gtk_dir_selection_set_filename(file_selector
, remember_trace_dir
);
1740 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
1742 case GTK_RESPONSE_ACCEPT
:
1743 case GTK_RESPONSE_OK
:
1744 dir
= gtk_dir_selection_get_dir (file_selector
);
1745 strncpy(remember_trace_dir
, dir
, PATH_MAX
);
1746 if(!dir
|| strlen(dir
) == 0){
1747 gtk_widget_destroy((GtkWidget
*)file_selector
);
1750 get_absolute_pathname(dir
, abs_path
);
1751 trace_v
= lttvwindowtraces_get_trace_by_name(abs_path
);
1752 if(trace_v
== NULL
) {
1753 trace
= ltt_trace_open(abs_path
);
1755 g_warning("cannot open trace %s", abs_path
);
1757 trace_v
= lttv_trace_new(trace
);
1758 lttvwindowtraces_add_trace(trace_v
);
1759 lttvwindow_add_trace(tab
, trace_v
);
1762 lttvwindow_add_trace(tab
, trace_v
);
1765 gtk_widget_destroy((GtkWidget
*)file_selector
);
1767 //update current tab
1768 //update_traceset(mw_data);
1770 /* Call the updatetraceset hooks */
1772 traceset
= tab
->traceset_info
->traceset
;
1773 SetTraceset(tab
, traceset
);
1774 // in expose now call_pending_read_hooks(mw_data);
1776 //lttvwindow_report_current_time(mw_data,&(tab->current_time));
1778 case GTK_RESPONSE_REJECT
:
1779 case GTK_RESPONSE_CANCEL
:
1781 gtk_widget_destroy((GtkWidget
*)file_selector
);
1786 /* remove_trace removes a trace from the current traceset if all viewers in
1787 * the current tab are not interested in the trace. It first displays a
1788 * dialogue, which shows all traces in the current traceset, to let user choose
1789 * a trace, then it checks if all viewers unselect the trace, if it is true,
1790 * it will remove the trace, recreate the traceset_contex,
1791 * and redraws all the viewer of the current tab. If there is on trace in the
1792 * current traceset, it will delete all viewers of the current tab
1794 * It destroys the filter tree. FIXME... we should request for an update
1798 void remove_trace(GtkWidget
*widget
, gpointer user_data
)
1801 LttvTrace
* trace_v
;
1802 LttvTraceset
* traceset
;
1803 gint i
, j
, nb_trace
, index
=-1;
1804 char ** name
, *remove_trace_name
;
1805 MainWindow
* mw_data
= get_window_data_struct(widget
);
1806 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
1808 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
1809 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
1815 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
1818 nb_trace
=lttv_traceset_number(tab
->traceset_info
->traceset
);
1819 name
= g_new(char*,nb_trace
);
1820 for(i
= 0; i
< nb_trace
; i
++){
1821 trace_v
= lttv_traceset_get(tab
->traceset_info
->traceset
, i
);
1822 trace
= lttv_trace(trace_v
);
1823 name
[i
] = ltt_trace_name(trace
);
1826 remove_trace_name
= get_remove_trace(name
, nb_trace
);
1829 if(remove_trace_name
){
1831 /* yuk, cut n paste from old code.. should be better (MD)*/
1832 for(i
= 0; i
<nb_trace
; i
++) {
1833 if(strcmp(remove_trace_name
,name
[i
]) == 0){
1838 traceset
= tab
->traceset_info
->traceset
;
1839 //Keep a reference to the traces so they are not freed.
1840 for(j
=0; j
<lttv_traceset_number(traceset
); j
++)
1842 LttvTrace
* trace
= lttv_traceset_get(traceset
, j
);
1843 lttv_trace_ref(trace
);
1846 //remove state update hooks
1847 lttv_state_remove_event_hooks(
1848 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1849 lttv_context_fini(LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
));
1850 g_object_unref(tab
->traceset_info
->traceset_context
);
1852 trace_v
= lttv_traceset_get(traceset
, index
);
1854 lttv_traceset_remove(traceset
, index
);
1855 lttv_trace_unref(trace_v
); // Remove local reference
1857 if(lttv_trace_get_ref_number(trace_v
) <= 1) {
1858 /* ref 1 : lttvwindowtraces only*/
1859 ltt_trace_close(lttv_trace(trace_v
));
1860 /* lttvwindowtraces_remove_trace takes care of destroying
1861 * the traceset linked with the trace_v and also of destroying
1862 * the trace_v at the same time.
1864 lttvwindowtraces_remove_trace(trace_v
);
1867 tab
->traceset_info
->traceset_context
=
1868 g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
1870 LTTV_TRACESET_CONTEXT(tab
->
1871 traceset_info
->traceset_context
),traceset
);
1872 //add state update hooks
1873 lttv_state_add_event_hooks(
1874 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1876 //Remove local reference to the traces.
1877 for(j
=0; j
<lttv_traceset_number(traceset
); j
++)
1879 LttvTrace
* trace
= lttv_traceset_get(traceset
, j
);
1880 lttv_trace_unref(trace
);
1883 SetTraceset(tab
, (gpointer
)traceset
);
1889 void remove_trace(GtkWidget
* widget
, gpointer user_data
)
1892 LttvTrace
* trace_v
;
1893 LttvTraceset
* traceset
;
1894 gint i
, j
, nb_trace
;
1895 char ** name
, *remove_trace_name
;
1896 MainWindow
* mw_data
= get_window_data_struct(widget
);
1897 LttvTracesetSelector
* s
;
1898 LttvTraceSelector
* t
;
1901 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
1903 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
1904 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
1910 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
1913 nb_trace
=lttv_traceset_number(tab
->traceset_info
->traceset
);
1914 name
= g_new(char*,nb_trace
);
1915 for(i
= 0; i
< nb_trace
; i
++){
1916 trace_v
= lttv_traceset_get(tab
->traceset_info
->traceset
, i
);
1917 trace
= lttv_trace(trace_v
);
1918 name
[i
] = ltt_trace_name(trace
);
1921 remove_trace_name
= get_remove_trace(name
, nb_trace
);
1923 if(remove_trace_name
){
1924 for(i
=0; i
<nb_trace
; i
++){
1925 if(strcmp(remove_trace_name
,name
[i
]) == 0){
1926 //unselect the trace from the current viewer
1928 w
= gtk_multivpaned_get_widget(GTK_MULTIVPANED(tab
->multivpaned
));
1930 s
= g_object_get_data(G_OBJECT(w
), "Traceset_Selector");
1932 t
= lttv_traceset_selector_trace_get(s
,i
);
1933 lttv_trace_selector_set_selected(t
, FALSE
);
1936 //check if other viewers select the trace
1937 w
= gtk_multivpaned_get_first_widget(GTK_MULTIVPANED(tab
->multivpaned
));
1939 s
= g_object_get_data(G_OBJECT(w
), "Traceset_Selector");
1941 t
= lttv_traceset_selector_trace_get(s
,i
);
1942 selected
= lttv_trace_selector_get_selected(t
);
1945 w
= gtk_multivpaned_get_next_widget(GTK_MULTIVPANED(tab
->multivpaned
));
1947 }else selected
= FALSE
;
1949 //if no viewer selects the trace, remove it
1951 remove_trace_from_traceset_selector(GTK_MULTIVPANED(tab
->multivpaned
), i
);
1953 traceset
= tab
->traceset_info
->traceset
;
1954 //Keep a reference to the traces so they are not freed.
1955 for(j
=0; j
<lttv_traceset_number(traceset
); j
++)
1957 LttvTrace
* trace
= lttv_traceset_get(traceset
, j
);
1958 lttv_trace_ref(trace
);
1961 //remove state update hooks
1962 lttv_state_remove_event_hooks(
1963 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1964 lttv_context_fini(LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
));
1965 g_object_unref(tab
->traceset_info
->traceset_context
);
1968 trace_v
= lttv_traceset_get(traceset
, i
);
1970 if(lttv_trace_get_ref_number(trace_v
) <= 2) {
1971 /* ref 2 : traceset, local */
1972 lttvwindowtraces_remove_trace(trace_v
);
1973 ltt_trace_close(lttv_trace(trace_v
));
1976 lttv_traceset_remove(traceset
, i
);
1977 lttv_trace_unref(trace_v
); // Remove local reference
1979 if(!lttv_trace_get_ref_number(trace_v
))
1980 lttv_trace_destroy(trace_v
);
1982 tab
->traceset_info
->traceset_context
=
1983 g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
1985 LTTV_TRACESET_CONTEXT(tab
->
1986 traceset_info
->traceset_context
),traceset
);
1987 //add state update hooks
1988 lttv_state_add_event_hooks(
1989 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1991 //Remove local reference to the traces.
1992 for(j
=0; j
<lttv_traceset_number(traceset
); j
++)
1994 LttvTrace
* trace
= lttv_traceset_get(traceset
, j
);
1995 lttv_trace_unref(trace
);
1999 //update current tab
2000 //update_traceset(mw_data);
2003 SetTraceset(tab
, (gpointer
)traceset
);
2004 // in expose now call_pending_read_hooks(mw_data);
2006 //lttvwindow_report_current_time(mw_data,&(tab->current_time));
2009 // while(tab->multi_vpaned->num_children){
2010 // gtk_multi_vpaned_widget_delete(tab->multi_vpaned);
2024 /* Redraw all the viewers in the current tab */
2025 void redraw(GtkWidget
*widget
, gpointer user_data
)
2027 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
2028 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2029 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2034 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
2038 LttvAttributeValue value
;
2040 g_assert(lttv_iattribute_find_by_path(tab
->attributes
, "hooks/redraw", LTTV_POINTER
, &value
));
2042 tmp
= (LttvHooks
*)*(value
.v_pointer
);
2044 lttv_hooks_call(tmp
,NULL
);
2048 void continue_processing(GtkWidget
*widget
, gpointer user_data
)
2050 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
2051 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2052 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2057 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
2061 LttvAttributeValue value
;
2063 g_assert(lttv_iattribute_find_by_path(tab
->attributes
,
2064 "hooks/continue", LTTV_POINTER
, &value
));
2066 tmp
= (LttvHooks
*)*(value
.v_pointer
);
2068 lttv_hooks_call(tmp
,NULL
);
2071 /* Stop the processing for the calling main window's current tab.
2072 * It removes every processing requests that are in its list. It does not call
2073 * the end request hooks, because the request is not finished.
2076 void stop_processing(GtkWidget
*widget
, gpointer user_data
)
2078 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
2079 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2080 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2085 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
2087 GSList
*iter
= tab
->events_requests
;
2089 while(iter
!= NULL
) {
2090 GSList
*remove_iter
= iter
;
2091 iter
= g_slist_next(iter
);
2093 g_free(remove_iter
->data
);
2094 tab
->events_requests
=
2095 g_slist_remove_link(tab
->events_requests
, remove_iter
);
2097 tab
->events_request_pending
= FALSE
;
2098 g_idle_remove_by_data(tab
);
2099 g_assert(g_slist_length(tab
->events_requests
) == 0);
2103 /* save will save the traceset to a file
2104 * Not implemented yet FIXME
2107 void save(GtkWidget
* widget
, gpointer user_data
)
2112 void save_as(GtkWidget
* widget
, gpointer user_data
)
2114 g_info("Save as\n");
2118 /* zoom will change the time_window of all the viewers of the
2119 * current tab, and redisplay them. The main functionality is to
2120 * determine the new time_window of the current tab
2123 void zoom(GtkWidget
* widget
, double size
)
2125 TimeInterval time_span
;
2126 TimeWindow new_time_window
;
2127 LttTime current_time
, time_delta
;
2128 MainWindow
* mw_data
= get_window_data_struct(widget
);
2129 LttvTracesetContext
*tsc
;
2130 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
2132 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2133 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2139 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
2142 if(size
== 1) return;
2144 tsc
= LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
2145 time_span
= tsc
->time_span
;
2146 new_time_window
= tab
->time_window
;
2147 current_time
= tab
->current_time
;
2149 time_delta
= ltt_time_sub(time_span
.end_time
,time_span
.start_time
);
2151 new_time_window
.start_time
= time_span
.start_time
;
2152 new_time_window
.time_width
= time_delta
;
2153 new_time_window
.time_width_double
= ltt_time_to_double(time_delta
);
2154 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
2155 new_time_window
.time_width
) ;
2157 new_time_window
.time_width
= ltt_time_div(new_time_window
.time_width
, size
);
2158 new_time_window
.time_width_double
=
2159 ltt_time_to_double(new_time_window
.time_width
);
2160 if(ltt_time_compare(new_time_window
.time_width
,time_delta
) > 0)
2161 { /* Case where zoom out is bigger than trace length */
2162 new_time_window
.start_time
= time_span
.start_time
;
2163 new_time_window
.time_width
= time_delta
;
2164 new_time_window
.time_width_double
= ltt_time_to_double(time_delta
);
2165 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
2166 new_time_window
.time_width
) ;
2170 /* Center the image on the current time */
2171 new_time_window
.start_time
=
2172 ltt_time_sub(current_time
,
2173 ltt_time_from_double(new_time_window
.time_width_double
/2.0));
2174 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
2175 new_time_window
.time_width
) ;
2176 /* If on borders, don't fall off */
2177 if(ltt_time_compare(new_time_window
.start_time
, time_span
.start_time
) <0)
2179 new_time_window
.start_time
= time_span
.start_time
;
2180 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
2181 new_time_window
.time_width
) ;
2185 if(ltt_time_compare(new_time_window
.end_time
,
2186 time_span
.end_time
) > 0)
2188 new_time_window
.start_time
=
2189 ltt_time_sub(time_span
.end_time
, new_time_window
.time_width
);
2191 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
2192 new_time_window
.time_width
) ;
2199 if(ltt_time_compare(new_time_window
.time_width
, ltt_time_zero
) == 0) {
2200 g_warning("Zoom more than 1 ns impossible");
2202 time_change_manager(tab
, new_time_window
);
2206 void zoom_in(GtkWidget
* widget
, gpointer user_data
)
2211 void zoom_out(GtkWidget
* widget
, gpointer user_data
)
2216 void zoom_extended(GtkWidget
* widget
, gpointer user_data
)
2221 void go_to_time(GtkWidget
* widget
, gpointer user_data
)
2223 g_info("Go to time\n");
2226 void show_time_frame(GtkWidget
* widget
, gpointer user_data
)
2228 g_info("Show time frame\n");
2232 /* callback function */
2235 on_empty_traceset_activate (GtkMenuItem
*menuitem
,
2238 create_new_window((GtkWidget
*)menuitem
, user_data
, FALSE
);
2243 on_clone_traceset_activate (GtkMenuItem
*menuitem
,
2246 create_new_window((GtkWidget
*)menuitem
, user_data
, TRUE
);
2250 /* create_new_tab calls create_tab to construct a new tab in the main window
2253 Tab
*create_new_tab(GtkWidget
* widget
, gpointer user_data
){
2254 gchar label
[PATH_MAX
];
2255 MainWindow
* mw_data
= get_window_data_struct(widget
);
2257 GtkNotebook
* notebook
= (GtkNotebook
*)lookup_widget(widget
, "MNotebook");
2258 if(notebook
== NULL
){
2259 g_info("Notebook does not exist\n");
2262 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2263 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2269 copy_tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
2272 strcpy(label
,"Page");
2273 if(get_label(mw_data
, label
,"Get the name of the tab","Please input tab's name"))
2274 return (create_tab (mw_data
, copy_tab
, notebook
, label
));
2280 on_tab_activate (GtkMenuItem
*menuitem
,
2283 create_new_tab((GtkWidget
*)menuitem
, user_data
);
2288 on_open_activate (GtkMenuItem
*menuitem
,
2291 open_traceset((GtkWidget
*)menuitem
, user_data
);
2296 on_close_activate (GtkMenuItem
*menuitem
,
2299 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2300 main_window_destructor(mw_data
);
2304 /* remove the current tab from the main window
2308 on_close_tab_activate (GtkWidget
*widget
,
2312 GtkWidget
* notebook
;
2314 MainWindow
* mw_data
= get_window_data_struct(widget
);
2315 notebook
= lookup_widget(widget
, "MNotebook");
2316 if(notebook
== NULL
){
2317 g_info("Notebook does not exist\n");
2321 page_num
= gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
));
2323 gtk_notebook_remove_page(GTK_NOTEBOOK(notebook
), page_num
);
2328 on_close_tab_X_clicked (GtkWidget
*widget
,
2332 GtkWidget
*notebook
= lookup_widget(widget
, "MNotebook");
2333 if(notebook
== NULL
){
2334 g_info("Notebook does not exist\n");
2338 if((page_num
= gtk_notebook_page_num(GTK_NOTEBOOK(notebook
), widget
)) != -1)
2339 gtk_notebook_remove_page(GTK_NOTEBOOK(notebook
), page_num
);
2345 on_add_trace_activate (GtkMenuItem
*menuitem
,
2348 add_trace((GtkWidget
*)menuitem
, user_data
);
2353 on_remove_trace_activate (GtkMenuItem
*menuitem
,
2356 remove_trace((GtkWidget
*)menuitem
, user_data
);
2361 on_save_activate (GtkMenuItem
*menuitem
,
2364 save((GtkWidget
*)menuitem
, user_data
);
2369 on_save_as_activate (GtkMenuItem
*menuitem
,
2372 save_as((GtkWidget
*)menuitem
, user_data
);
2377 on_quit_activate (GtkMenuItem
*menuitem
,
2385 on_cut_activate (GtkMenuItem
*menuitem
,
2393 on_copy_activate (GtkMenuItem
*menuitem
,
2401 on_paste_activate (GtkMenuItem
*menuitem
,
2409 on_delete_activate (GtkMenuItem
*menuitem
,
2417 on_zoom_in_activate (GtkMenuItem
*menuitem
,
2420 zoom_in((GtkWidget
*)menuitem
, user_data
);
2425 on_zoom_out_activate (GtkMenuItem
*menuitem
,
2428 zoom_out((GtkWidget
*)menuitem
, user_data
);
2433 on_zoom_extended_activate (GtkMenuItem
*menuitem
,
2436 zoom_extended((GtkWidget
*)menuitem
, user_data
);
2441 on_go_to_time_activate (GtkMenuItem
*menuitem
,
2444 go_to_time((GtkWidget
*)menuitem
, user_data
);
2449 on_show_time_frame_activate (GtkMenuItem
*menuitem
,
2452 show_time_frame((GtkWidget
*)menuitem
, user_data
);
2457 on_move_viewer_up_activate (GtkMenuItem
*menuitem
,
2460 move_up_viewer((GtkWidget
*)menuitem
, user_data
);
2465 on_move_viewer_down_activate (GtkMenuItem
*menuitem
,
2468 move_down_viewer((GtkWidget
*)menuitem
, user_data
);
2473 on_remove_viewer_activate (GtkMenuItem
*menuitem
,
2476 delete_viewer((GtkWidget
*)menuitem
, user_data
);
2480 on_trace_facility_activate (GtkMenuItem
*menuitem
,
2483 g_info("Trace facility selector: %s\n");
2487 /* Dispaly a file selection dialogue to let user select a library, then call
2488 * lttv_library_load().
2492 on_load_library_activate (GtkMenuItem
*menuitem
,
2495 GError
*error
= NULL
;
2496 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2498 gchar load_module_path_alter
[PATH_MAX
];
2502 gchar
*load_module_path
;
2503 name
= g_ptr_array_new();
2504 nb
= lttv_library_path_number();
2505 /* ask for the library path */
2509 path
= lttv_library_path_get(i
);
2510 g_ptr_array_add(name
, path
);
2513 load_module_path
= get_selection((char **)(name
->pdata
), name
->len
,
2514 "Select a library path", "Library paths");
2515 if(load_module_path
!= NULL
)
2516 strncpy(load_module_path_alter
, load_module_path
, PATH_MAX
-1); // -1 for /
2518 g_ptr_array_free(name
, TRUE
);
2520 if(load_module_path
== NULL
) return;
2524 /* Make sure the module path ends with a / */
2525 gchar
*ptr
= load_module_path_alter
;
2527 ptr
= strchr(ptr
, '\0');
2529 if(*(ptr
-1) != '/') {
2536 /* Ask for the library to load : list files in the previously selected
2538 gchar str
[PATH_MAX
];
2541 GtkFileSelection
* file_selector
=
2542 (GtkFileSelection
*)gtk_file_selection_new("Select a module");
2543 gtk_file_selection_set_filename(file_selector
, load_module_path_alter
);
2544 gtk_file_selection_hide_fileop_buttons(file_selector
);
2547 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
2549 case GTK_RESPONSE_ACCEPT
:
2550 case GTK_RESPONSE_OK
:
2551 dir
= gtk_file_selection_get_selections (file_selector
);
2552 strncpy(str
,dir
[0],PATH_MAX
);
2553 strncpy(remember_plugins_dir
,dir
[0],PATH_MAX
);
2554 /* only keep file name */
2556 str1
= strrchr(str
,'/');
2559 str1
= strrchr(str
,'\\');
2564 if(*str1
== 'l' && *(str1
+1)== 'i' && *(str1
+2)=='b')
2566 remove info after
. */
2570 str2
= strrchr(str2
, '.');
2571 if(str2
!= NULL
) *str2
= '\0';
2573 lttv_module_require(str1
, &error
);
2575 lttv_library_load(str1
, &error
);
2576 if(error
!= NULL
) g_warning("%s", error
->message
);
2577 else g_info("Load library: %s\n", str
);
2579 case GTK_RESPONSE_REJECT
:
2580 case GTK_RESPONSE_CANCEL
:
2582 gtk_widget_destroy((GtkWidget
*)file_selector
);
2593 /* Display all loaded modules, let user to select a module to unload
2594 * by calling lttv_module_unload
2598 on_unload_library_activate (GtkMenuItem
*menuitem
,
2601 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2603 LttvLibrary
*library
= NULL
;
2608 name
= g_ptr_array_new();
2609 nb
= lttv_library_number();
2610 LttvLibraryInfo
*lib_info
= g_new(LttvLibraryInfo
,nb
);
2611 /* ask for the library name */
2614 LttvLibrary
*iter_lib
= lttv_library_get(i
);
2615 lttv_library_info(iter_lib
, &lib_info
[i
]);
2617 gchar
*path
= lib_info
[i
].name
;
2618 g_ptr_array_add(name
, path
);
2620 lib_name
= get_selection((char **)(name
->pdata
), name
->len
,
2621 "Select a library", "Libraries");
2622 if(lib_name
!= NULL
) {
2624 if(strcmp(lib_name
, lib_info
[i
].name
) == 0) {
2625 library
= lttv_library_get(i
);
2630 g_ptr_array_free(name
, TRUE
);
2633 if(lib_name
== NULL
) return;
2635 if(library
!= NULL
) lttv_library_unload(library
);
2639 /* Dispaly a file selection dialogue to let user select a module, then call
2640 * lttv_module_require().
2644 on_load_module_activate (GtkMenuItem
*menuitem
,
2647 GError
*error
= NULL
;
2648 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2650 LttvLibrary
*library
= NULL
;
2655 name
= g_ptr_array_new();
2656 nb
= lttv_library_number();
2657 LttvLibraryInfo
*lib_info
= g_new(LttvLibraryInfo
,nb
);
2658 /* ask for the library name */
2661 LttvLibrary
*iter_lib
= lttv_library_get(i
);
2662 lttv_library_info(iter_lib
, &lib_info
[i
]);
2664 gchar
*path
= lib_info
[i
].name
;
2665 g_ptr_array_add(name
, path
);
2667 lib_name
= get_selection((char **)(name
->pdata
), name
->len
,
2668 "Select a library", "Libraries");
2669 if(lib_name
!= NULL
) {
2671 if(strcmp(lib_name
, lib_info
[i
].name
) == 0) {
2672 library
= lttv_library_get(i
);
2677 g_ptr_array_free(name
, TRUE
);
2680 if(lib_name
== NULL
) return;
2683 //LttvModule *module;
2684 gchar module_name_out
[PATH_MAX
];
2686 /* Ask for the module to load : list modules in the selected lib */
2690 nb
= lttv_library_module_number(library
);
2691 LttvModuleInfo
*module_info
= g_new(LttvModuleInfo
,nb
);
2692 name
= g_ptr_array_new();
2693 /* ask for the module name */
2696 LttvModule
*iter_module
= lttv_library_module_get(library
, i
);
2697 lttv_module_info(iter_module
, &module_info
[i
]);
2699 gchar
*path
= module_info
[i
].name
;
2700 g_ptr_array_add(name
, path
);
2702 module_name
= get_selection((char **)(name
->pdata
), name
->len
,
2703 "Select a module", "Modules");
2704 if(module_name
!= NULL
) {
2706 if(strcmp(module_name
, module_info
[i
].name
) == 0) {
2707 strncpy(module_name_out
, module_name
, PATH_MAX
);
2708 //module = lttv_library_module_get(i);
2714 g_ptr_array_free(name
, TRUE
);
2715 g_free(module_info
);
2717 if(module_name
== NULL
) return;
2720 lttv_module_require(module_name_out
, &error
);
2721 if(error
!= NULL
) g_warning("%s", error
->message
);
2722 else g_info("Load module: %s", module_name_out
);
2729 gchar str
[PATH_MAX
];
2732 GtkFileSelection
* file_selector
=
2733 (GtkFileSelection
*)gtk_file_selection_new("Select a module");
2734 gtk_file_selection_set_filename(file_selector
, load_module_path_alter
);
2735 gtk_file_selection_hide_fileop_buttons(file_selector
);
2738 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
2740 case GTK_RESPONSE_ACCEPT
:
2741 case GTK_RESPONSE_OK
:
2742 dir
= gtk_file_selection_get_selections (file_selector
);
2743 strncpy(str
,dir
[0],PATH_MAX
);
2744 strncpy(remember_plugins_dir
,dir
[0],PATH_MAX
);
2746 /* only keep file name */
2748 str1
= strrchr(str
,'/');
2751 str1
= strrchr(str
,'\\');
2756 if(*str1
== 'l' && *(str1
+1)== 'i' && *(str1
+2)=='b')
2758 remove info after
. */
2762 str2
= strrchr(str2
, '.');
2763 if(str2
!= NULL
) *str2
= '\0';
2765 lttv_module_require(str1
, &error
);
2767 lttv_library_load(str1
, &error
);
2768 if(error
!= NULL
) g_warning(error
->message
);
2769 else g_info("Load library: %s\n", str
);
2771 case GTK_RESPONSE_REJECT
:
2772 case GTK_RESPONSE_CANCEL
:
2774 gtk_widget_destroy((GtkWidget
*)file_selector
);
2786 /* Display all loaded modules, let user to select a module to unload
2787 * by calling lttv_module_unload
2791 on_unload_module_activate (GtkMenuItem
*menuitem
,
2794 GError
*error
= NULL
;
2795 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2797 LttvLibrary
*library
;
2802 name
= g_ptr_array_new();
2803 nb
= lttv_library_number();
2804 LttvLibraryInfo
*lib_info
= g_new(LttvLibraryInfo
,nb
);
2805 /* ask for the library name */
2808 LttvLibrary
*iter_lib
= lttv_library_get(i
);
2809 lttv_library_info(iter_lib
, &lib_info
[i
]);
2811 gchar
*path
= lib_info
[i
].name
;
2812 g_ptr_array_add(name
, path
);
2814 lib_name
= get_selection((char **)(name
->pdata
), name
->len
,
2815 "Select a library", "Libraries");
2816 if(lib_name
!= NULL
) {
2818 if(strcmp(lib_name
, lib_info
[i
].name
) == 0) {
2819 library
= lttv_library_get(i
);
2824 g_ptr_array_free(name
, TRUE
);
2827 if(lib_name
== NULL
) return;
2830 LttvModule
*module
= NULL
;
2832 /* Ask for the module to load : list modules in the selected lib */
2836 nb
= lttv_library_module_number(library
);
2837 LttvModuleInfo
*module_info
= g_new(LttvModuleInfo
,nb
);
2838 name
= g_ptr_array_new();
2839 /* ask for the module name */
2842 LttvModule
*iter_module
= lttv_library_module_get(library
, i
);
2843 lttv_module_info(iter_module
, &module_info
[i
]);
2845 gchar
*path
= module_info
[i
].name
;
2846 if(module_info
[i
].use_count
> 0) g_ptr_array_add(name
, path
);
2848 module_name
= get_selection((char **)(name
->pdata
), name
->len
,
2849 "Select a module", "Modules");
2850 if(module_name
!= NULL
) {
2852 if(strcmp(module_name
, module_info
[i
].name
) == 0) {
2853 module
= lttv_library_module_get(library
, i
);
2859 g_ptr_array_free(name
, TRUE
);
2860 g_free(module_info
);
2862 if(module_name
== NULL
) return;
2865 LttvModuleInfo module_info
;
2866 lttv_module_info(module
, &module_info
);
2867 g_info("Release module: %s\n", module_info
.name
);
2869 lttv_module_release(module
);
2873 /* Display a directory dialogue to let user select a path for library searching
2877 on_add_library_search_path_activate (GtkMenuItem
*menuitem
,
2880 GtkDirSelection
* file_selector
= (GtkDirSelection
*)gtk_dir_selection_new("Select library path");
2884 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2885 if(remember_plugins_dir
[0] != '\0')
2886 gtk_dir_selection_set_filename(file_selector
, remember_plugins_dir
);
2888 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
2890 case GTK_RESPONSE_ACCEPT
:
2891 case GTK_RESPONSE_OK
:
2892 dir
= gtk_dir_selection_get_dir (file_selector
);
2893 strncpy(remember_plugins_dir
,dir
,PATH_MAX
);
2894 strncat(remember_plugins_dir
,"/",PATH_MAX
);
2895 lttv_library_path_add(dir
);
2896 case GTK_RESPONSE_REJECT
:
2897 case GTK_RESPONSE_CANCEL
:
2899 gtk_widget_destroy((GtkWidget
*)file_selector
);
2905 /* Display a directory dialogue to let user select a path for library searching
2909 on_remove_library_search_path_activate (GtkMenuItem
*menuitem
,
2912 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2914 const char *lib_path
;
2919 name
= g_ptr_array_new();
2920 nb
= lttv_library_path_number();
2921 /* ask for the library name */
2924 gchar
*path
= lttv_library_path_get(i
);
2925 g_ptr_array_add(name
, path
);
2927 lib_path
= get_selection((char **)(name
->pdata
), name
->len
,
2928 "Select a library path", "Library paths");
2930 g_ptr_array_free(name
, TRUE
);
2932 if(lib_path
== NULL
) return;
2935 lttv_library_path_remove(lib_path
);
2939 on_color_activate (GtkMenuItem
*menuitem
,
2947 on_save_configuration_activate (GtkMenuItem
*menuitem
,
2950 g_info("Save configuration\n");
2955 on_content_activate (GtkMenuItem
*menuitem
,
2958 g_info("Content\n");
2963 on_about_close_activate (GtkButton
*button
,
2966 GtkWidget
*about_widget
= GTK_WIDGET(user_data
);
2968 gtk_widget_destroy(about_widget
);
2972 on_about_activate (GtkMenuItem
*menuitem
,
2975 MainWindow
*main_window
= get_window_data_struct(GTK_WIDGET(menuitem
));
2976 GtkWidget
*window_widget
= main_window
->mwindow
;
2977 GtkWidget
*about_widget
= gtk_window_new(GTK_WINDOW_TOPLEVEL
);
2978 GtkWindow
*about_window
= GTK_WINDOW(about_widget
);
2979 gint window_width
, window_height
;
2981 gtk_window_set_title(about_window
, "About Linux Trace Toolkit");
2983 gtk_window_set_resizable(about_window
, FALSE
);
2984 gtk_window_set_transient_for(GTK_WINDOW(window_widget
), about_window
);
2985 gtk_window_set_destroy_with_parent(about_window
, TRUE
);
2986 gtk_window_set_modal(about_window
, FALSE
);
2988 /* Put the about window at the center of the screen */
2989 gtk_window_get_size(about_window
, &window_width
, &window_height
);
2990 gtk_window_move (about_window
,
2991 (gdk_screen_width() - window_width
)/2,
2992 (gdk_screen_height() - window_height
)/2);
2994 GtkWidget
*vbox
= gtk_vbox_new(FALSE
, 1);
2996 gtk_container_add(GTK_CONTAINER(about_widget
), vbox
);
3000 GtkWidget
*label1
= gtk_label_new("");
3001 gtk_misc_set_padding(GTK_MISC(label1
), 10, 20);
3002 gtk_label_set_markup(GTK_LABEL(label1
), "\
3003 <big>Linux Trace Toolkit</big>");
3004 gtk_label_set_justify(GTK_LABEL(label1
), GTK_JUSTIFY_CENTER
);
3006 GtkWidget
*label2
= gtk_label_new("");
3007 gtk_misc_set_padding(GTK_MISC(label2
), 10, 20);
3008 gtk_label_set_markup(GTK_LABEL(label2
), "\
3011 Michel Dagenais (New trace format, lttv main)\n\
3012 Mathieu Desnoyers (Directory structure, build with automake/conf,\n\
3013 lttv gui, control flow view, gui cooperative trace reading\n\
3014 scheduler with interruptible foreground and background\n\
3015 computation, detailed event list)\n\
3016 Benoit Des Ligneris, Eric Clement (Cluster adaptation, work in progress)\n\
3017 Xang-Xiu Yang (new trace reading library and converter, lttv gui, \n\
3018 detailed event list and statistics view)\n\
3019 Tom Zanussi (RelayFS)\n\
3021 Strongly inspired from the original Linux Trace Toolkit Visualizer made by\n\
3024 GtkWidget
*label3
= gtk_label_new("");
3025 gtk_label_set_markup(GTK_LABEL(label3
), "\
3026 Linux Trace Toolkit Viewer, Copyright (C) 2004\n\
3028 Mathieu Desnoyers\n\
3030 Linux Trace Toolkit comes with ABSOLUTELY NO WARRANTY.\n\
3031 This is free software, and you are welcome to redistribute it\n\
3032 under certain conditions. See COPYING for details.");
3033 gtk_misc_set_padding(GTK_MISC(label3
), 10, 20);
3035 gtk_box_pack_start_defaults(GTK_BOX(vbox
), label1
);
3036 gtk_box_pack_start_defaults(GTK_BOX(vbox
), label2
);
3037 gtk_box_pack_start_defaults(GTK_BOX(vbox
), label3
);
3039 GtkWidget
*hbox
= gtk_hbox_new(TRUE
, 0);
3040 gtk_box_pack_end(GTK_BOX(vbox
), hbox
, FALSE
, FALSE
, 0);
3041 GtkWidget
*close_button
= gtk_button_new_with_mnemonic("_Close");
3042 gtk_box_pack_end(GTK_BOX(hbox
), close_button
, FALSE
, FALSE
, 0);
3043 gtk_container_set_border_width(GTK_CONTAINER(close_button
), 20);
3045 g_signal_connect(G_OBJECT(close_button
), "clicked",
3046 G_CALLBACK(on_about_close_activate
),
3047 (gpointer
)about_widget
);
3049 gtk_widget_show_all(about_widget
);
3054 on_button_new_clicked (GtkButton
*button
,
3057 create_new_window((GtkWidget
*)button
, user_data
, TRUE
);
3061 on_button_new_tab_clicked (GtkButton
*button
,
3064 create_new_tab((GtkWidget
*)button
, user_data
);
3068 on_button_open_clicked (GtkButton
*button
,
3071 open_traceset((GtkWidget
*)button
, user_data
);
3076 on_button_add_trace_clicked (GtkButton
*button
,
3079 add_trace((GtkWidget
*)button
, user_data
);
3084 on_button_remove_trace_clicked (GtkButton
*button
,
3087 remove_trace((GtkWidget
*)button
, user_data
);
3091 on_button_redraw_clicked (GtkButton
*button
,
3094 redraw((GtkWidget
*)button
, user_data
);
3098 on_button_continue_processing_clicked (GtkButton
*button
,
3101 continue_processing((GtkWidget
*)button
, user_data
);
3105 on_button_stop_processing_clicked (GtkButton
*button
,
3108 stop_processing((GtkWidget
*)button
, user_data
);
3114 on_button_save_clicked (GtkButton
*button
,
3117 save((GtkWidget
*)button
, user_data
);
3122 on_button_save_as_clicked (GtkButton
*button
,
3125 save_as((GtkWidget
*)button
, user_data
);
3130 on_button_zoom_in_clicked (GtkButton
*button
,
3133 zoom_in((GtkWidget
*)button
, user_data
);
3138 on_button_zoom_out_clicked (GtkButton
*button
,
3141 zoom_out((GtkWidget
*)button
, user_data
);
3146 on_button_zoom_extended_clicked (GtkButton
*button
,
3149 zoom_extended((GtkWidget
*)button
, user_data
);
3154 on_button_go_to_time_clicked (GtkButton
*button
,
3157 go_to_time((GtkWidget
*)button
, user_data
);
3162 on_button_show_time_frame_clicked (GtkButton
*button
,
3165 show_time_frame((GtkWidget
*)button
, user_data
);
3170 on_button_move_up_clicked (GtkButton
*button
,
3173 move_up_viewer((GtkWidget
*)button
, user_data
);
3178 on_button_move_down_clicked (GtkButton
*button
,
3181 move_down_viewer((GtkWidget
*)button
, user_data
);
3186 on_button_delete_viewer_clicked (GtkButton
*button
,
3189 delete_viewer((GtkWidget
*)button
, user_data
);
3193 on_MWindow_destroy (GtkWidget
*widget
,
3196 MainWindow
*main_window
= get_window_data_struct(widget
);
3197 LttvIAttribute
*attributes
= main_window
->attributes
;
3198 LttvAttributeValue value
;
3200 //This is unnecessary, since widgets will be destroyed
3201 //by the main window widget anyway.
3202 //remove_all_menu_toolbar_constructors(main_window, NULL);
3204 g_assert(lttv_iattribute_find_by_path(attributes
,
3205 "viewers/menu", LTTV_POINTER
, &value
));
3206 lttv_menus_destroy((LttvMenus
*)*(value
.v_pointer
));
3208 g_assert(lttv_iattribute_find_by_path(attributes
,
3209 "viewers/toolbar", LTTV_POINTER
, &value
));
3210 lttv_toolbars_destroy((LttvToolbars
*)*(value
.v_pointer
));
3212 g_object_unref(main_window
->attributes
);
3213 g_main_window_list
= g_slist_remove(g_main_window_list
, main_window
);
3215 g_info("There are now : %d windows\n",g_slist_length(g_main_window_list
));
3216 if(g_slist_length(g_main_window_list
) == 0)
3221 on_MWindow_configure (GtkWidget
*widget
,
3222 GdkEventConfigure
*event
,
3225 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)widget
);
3227 // MD : removed time width modification upon resizing of the main window.
3228 // The viewers will redraw themselves completely, without time interval
3231 if(mw_data->window_width){
3232 time_span = LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context)->Time_Span ;
3233 time_win = tab->time_window;
3234 ratio = width / mw_data->window_width;
3235 tab->time_window.time_width = ltt_time_mul(time_win.time_width,ratio);
3236 time = ltt_time_sub(time_span->endTime, time_win.start_time);
3237 if(ltt_time_compare(time, tab->time_window.time_width) < 0){
3238 tab->time_window.time_width = time;
3244 mw_data->window_width = (int)width;
3253 on_MNotebook_switch_page (GtkNotebook
*notebook
,
3254 GtkNotebookPage
*page
,
3262 void time_change_manager (Tab
*tab
,
3263 TimeWindow new_time_window
)
3265 /* Only one source of time change */
3266 if(tab
->time_manager_lock
== TRUE
) return;
3268 tab
->time_manager_lock
= TRUE
;
3270 LttvTracesetContext
*tsc
= LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3271 TimeInterval time_span
= tsc
->time_span
;
3272 LttTime start_time
= new_time_window
.start_time
;
3273 LttTime end_time
= new_time_window
.end_time
;
3276 GtkAdjustment
*adjustment
= gtk_range_get_adjustment(GTK_RANGE(tab
->scrollbar
));
3277 LttTime upper
= ltt_time_sub(time_span
.end_time
, time_span
.start_time
);
3279 gtk_range_set_increments(GTK_RANGE(tab
->scrollbar
),
3280 ltt_time_to_double(new_time_window
.time_width
)
3281 / SCROLL_STEP_PER_PAGE
3282 * NANOSECONDS_PER_SECOND
, /* step increment */
3283 ltt_time_to_double(new_time_window
.time_width
)
3284 * NANOSECONDS_PER_SECOND
); /* page increment */
3285 gtk_range_set_range(GTK_RANGE(tab
->scrollbar
),
3287 ltt_time_to_double(upper
)
3288 * NANOSECONDS_PER_SECOND
); /* upper */
3290 g_object_set(G_OBJECT(adjustment
),
3294 ltt_time_to_double(upper
), /* upper */
3296 new_time_window
.time_width_double
3297 / SCROLL_STEP_PER_PAGE
, /* step increment */
3299 new_time_window
.time_width_double
,
3300 /* page increment */
3302 new_time_window
.time_width_double
, /* page size */
3304 gtk_adjustment_changed(adjustment
);
3306 // g_object_set(G_OBJECT(adjustment),
3308 // ltt_time_to_double(
3309 // ltt_time_sub(start_time, time_span.start_time))
3312 //gtk_adjustment_value_changed(adjustment);
3313 gtk_range_set_value(GTK_RANGE(tab
->scrollbar
),
3315 ltt_time_sub(start_time
, time_span
.start_time
)) /* value */);
3317 /* set the time bar. */
3319 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry1
),
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
->MEntry1
),
3323 (double)start_time
.tv_sec
);
3325 /* start nanoseconds */
3326 if(start_time
.tv_sec
== time_span
.start_time
.tv_sec
) {
3327 /* can be both beginning and end at the same time. */
3328 if(start_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3329 /* If we are at the end, max nsec to end.. -1 (not zero length) */
3330 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry2
),
3331 (double)time_span
.start_time
.tv_nsec
,
3332 (double)time_span
.end_time
.tv_nsec
-1);
3334 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry2
),
3335 (double)time_span
.start_time
.tv_nsec
,
3336 (double)NANOSECONDS_PER_SECOND
-1);
3338 } else if(start_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3339 /* If we are at the end, max nsec to end.. -1 (not zero length) */
3340 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry2
),
3342 (double)time_span
.end_time
.tv_nsec
-1);
3343 } else /* anywhere else */
3344 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry2
),
3346 (double)NANOSECONDS_PER_SECOND
-1);
3347 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry2
),
3348 (double)start_time
.tv_nsec
);
3351 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry3
),
3352 (double)time_span
.start_time
.tv_sec
,
3353 (double)time_span
.end_time
.tv_sec
);
3354 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry3
),
3355 (double)end_time
.tv_sec
);
3357 /* end nanoseconds */
3358 if(end_time
.tv_sec
== time_span
.start_time
.tv_sec
) {
3359 /* can be both beginning and end at the same time. */
3360 if(end_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3361 /* If we are at the end, max nsec to end.. */
3362 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry4
),
3363 (double)time_span
.start_time
.tv_nsec
+1,
3364 (double)time_span
.end_time
.tv_nsec
);
3366 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry4
),
3367 (double)time_span
.start_time
.tv_nsec
+1,
3368 (double)NANOSECONDS_PER_SECOND
-1);
3371 else if(end_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3372 /* If we are at the end, max nsec to end.. */
3373 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry4
),
3375 (double)time_span
.end_time
.tv_nsec
);
3377 else /* anywhere else */
3378 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry4
),
3380 (double)NANOSECONDS_PER_SECOND
-1);
3381 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry4
),
3382 (double)end_time
.tv_nsec
);
3384 /* call viewer hooks for new time window */
3385 set_time_window(tab
, &new_time_window
);
3387 tab
->time_manager_lock
= FALSE
;
3391 /* value changed for frame start s
3393 * Check time span : if ns is out of range, clip it the nearest good value.
3396 on_MEntry1_value_changed (GtkSpinButton
*spinbutton
,
3399 Tab
*tab
=(Tab
*)user_data
;
3400 LttvTracesetContext
* tsc
=
3401 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3402 TimeInterval time_span
= tsc
->time_span
;
3403 gint value
= gtk_spin_button_get_value_as_int(spinbutton
);
3405 TimeWindow new_time_window
= tab
->time_window
;
3407 LttTime end_time
= new_time_window
.end_time
;
3409 new_time_window
.start_time
.tv_sec
= value
;
3411 /* start nanoseconds */
3412 if(new_time_window
.start_time
.tv_sec
== time_span
.start_time
.tv_sec
) {
3413 if(new_time_window
.start_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3414 if(new_time_window
.start_time
.tv_nsec
> time_span
.end_time
.tv_nsec
)
3415 new_time_window
.start_time
.tv_nsec
= time_span
.end_time
.tv_nsec
-1;
3416 if(new_time_window
.start_time
.tv_nsec
< time_span
.start_time
.tv_nsec
)
3417 new_time_window
.start_time
.tv_nsec
= time_span
.start_time
.tv_nsec
;
3419 if(new_time_window
.start_time
.tv_nsec
< time_span
.start_time
.tv_nsec
)
3420 new_time_window
.start_time
.tv_nsec
= time_span
.start_time
.tv_nsec
;
3423 else if(new_time_window
.start_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3424 if(new_time_window
.start_time
.tv_nsec
> time_span
.end_time
.tv_nsec
)
3425 new_time_window
.start_time
.tv_nsec
= time_span
.end_time
.tv_nsec
-1;
3428 if(ltt_time_compare(new_time_window
.start_time
, end_time
) >= 0) {
3429 /* Then, we must push back end time : keep the same time width
3430 * if possible, else end traceset time */
3431 end_time
= LTT_TIME_MIN(ltt_time_add(new_time_window
.start_time
,
3432 new_time_window
.time_width
),
3433 time_span
.end_time
);
3436 /* Fix the time width to fit start time and end time */
3437 new_time_window
.time_width
= ltt_time_sub(end_time
,
3438 new_time_window
.start_time
);
3439 new_time_window
.time_width_double
=
3440 ltt_time_to_double(new_time_window
.time_width
);
3442 new_time_window
.end_time
= end_time
;
3444 time_change_manager(tab
, new_time_window
);
3449 on_MEntry2_value_changed (GtkSpinButton
*spinbutton
,
3452 Tab
*tab
=(Tab
*)user_data
;
3453 LttvTracesetContext
* tsc
=
3454 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3455 TimeInterval time_span
= tsc
->time_span
;
3456 gint value
= gtk_spin_button_get_value_as_int(spinbutton
);
3458 TimeWindow new_time_window
= tab
->time_window
;
3460 LttTime end_time
= new_time_window
.end_time
;
3462 new_time_window
.start_time
.tv_nsec
= value
;
3464 if(ltt_time_compare(new_time_window
.start_time
, end_time
) >= 0) {
3465 /* Then, we must push back end time : keep the same time width
3466 * if possible, else end traceset time */
3467 end_time
= LTT_TIME_MIN(ltt_time_add(new_time_window
.start_time
,
3468 new_time_window
.time_width
),
3469 time_span
.end_time
);
3472 /* Fix the time width to fit start time and end time */
3473 new_time_window
.time_width
= ltt_time_sub(end_time
,
3474 new_time_window
.start_time
);
3475 new_time_window
.time_width_double
=
3476 ltt_time_to_double(new_time_window
.time_width
);
3478 new_time_window
.end_time
= end_time
;
3480 time_change_manager(tab
, new_time_window
);
3485 on_MEntry3_value_changed (GtkSpinButton
*spinbutton
,
3488 Tab
*tab
=(Tab
*)user_data
;
3489 LttvTracesetContext
* tsc
=
3490 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3491 TimeInterval time_span
= tsc
->time_span
;
3492 gint value
= gtk_spin_button_get_value_as_int(spinbutton
);
3494 TimeWindow new_time_window
= tab
->time_window
;
3496 LttTime end_time
= new_time_window
.end_time
;
3498 end_time
.tv_sec
= value
;
3500 /* end nanoseconds */
3501 if(end_time
.tv_sec
== time_span
.start_time
.tv_sec
) {
3502 if(end_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3503 if(end_time
.tv_nsec
> time_span
.end_time
.tv_nsec
)
3504 end_time
.tv_nsec
= time_span
.end_time
.tv_nsec
;
3505 if(end_time
.tv_nsec
< time_span
.start_time
.tv_nsec
)
3506 end_time
.tv_nsec
= time_span
.start_time
.tv_nsec
+1;
3508 if(end_time
.tv_nsec
< time_span
.start_time
.tv_nsec
)
3509 end_time
.tv_nsec
= time_span
.start_time
.tv_nsec
+1;
3512 else if(end_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3513 if(end_time
.tv_nsec
> time_span
.end_time
.tv_nsec
)
3514 end_time
.tv_nsec
= time_span
.end_time
.tv_nsec
;
3517 if(ltt_time_compare(new_time_window
.start_time
, end_time
) >= 0) {
3518 /* Then, we must push front start time : keep the same time width
3519 * if possible, else end traceset time */
3520 new_time_window
.start_time
= LTT_TIME_MAX(
3521 ltt_time_sub(end_time
,
3522 new_time_window
.time_width
),
3523 time_span
.start_time
);
3526 /* Fix the time width to fit start time and end time */
3527 new_time_window
.time_width
= ltt_time_sub(end_time
,
3528 new_time_window
.start_time
);
3529 new_time_window
.time_width_double
=
3530 ltt_time_to_double(new_time_window
.time_width
);
3532 new_time_window
.end_time
= end_time
;
3534 time_change_manager(tab
, new_time_window
);
3539 on_MEntry4_value_changed (GtkSpinButton
*spinbutton
,
3542 Tab
*tab
=(Tab
*)user_data
;
3543 LttvTracesetContext
* tsc
=
3544 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3545 TimeInterval time_span
= tsc
->time_span
;
3546 gint value
= gtk_spin_button_get_value_as_int(spinbutton
);
3548 TimeWindow new_time_window
= tab
->time_window
;
3550 LttTime end_time
= new_time_window
.end_time
;
3552 end_time
.tv_nsec
= value
;
3554 if(ltt_time_compare(new_time_window
.start_time
, end_time
) >= 0) {
3555 /* Then, we must push front start time : keep the same time width
3556 * if possible, else end traceset time */
3557 new_time_window
.start_time
= LTT_TIME_MAX(
3558 ltt_time_sub(end_time
,
3559 new_time_window
.time_width
),
3560 time_span
.start_time
);
3563 /* Fix the time width to fit start time and end time */
3564 new_time_window
.time_width
= ltt_time_sub(end_time
,
3565 new_time_window
.start_time
);
3566 new_time_window
.time_width_double
=
3567 ltt_time_to_double(new_time_window
.time_width
);
3568 new_time_window
.end_time
= end_time
;
3570 time_change_manager(tab
, new_time_window
);
3575 void current_time_change_manager (Tab
*tab
,
3576 LttTime new_current_time
)
3578 /* Only one source of time change */
3579 if(tab
->current_time_manager_lock
== TRUE
) return;
3581 tab
->current_time_manager_lock
= TRUE
;
3583 LttvTracesetContext
*tsc
= LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3584 TimeInterval time_span
= tsc
->time_span
;
3586 /* current seconds */
3587 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry5
),
3588 (double)time_span
.start_time
.tv_sec
,
3589 (double)time_span
.end_time
.tv_sec
);
3590 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry5
),
3591 (double)new_current_time
.tv_sec
);
3594 /* start nanoseconds */
3595 if(new_current_time
.tv_sec
== time_span
.start_time
.tv_sec
) {
3596 /* can be both beginning and end at the same time. */
3597 if(new_current_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3598 /* If we are at the end, max nsec to end.. */
3599 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry6
),
3600 (double)time_span
.start_time
.tv_nsec
,
3601 (double)time_span
.end_time
.tv_nsec
);
3603 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry6
),
3604 (double)time_span
.start_time
.tv_nsec
,
3605 (double)NANOSECONDS_PER_SECOND
-1);
3607 } else if(new_current_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3608 /* If we are at the end, max nsec to end.. */
3609 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry6
),
3611 (double)time_span
.end_time
.tv_nsec
);
3612 } else /* anywhere else */
3613 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry6
),
3615 (double)NANOSECONDS_PER_SECOND
-1);
3617 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry6
),
3618 (double)new_current_time
.tv_nsec
);
3620 set_current_time(tab
, &new_current_time
);
3622 tab
->current_time_manager_lock
= FALSE
;
3626 on_MEntry5_value_changed (GtkSpinButton
*spinbutton
,
3629 Tab
*tab
= (Tab
*)user_data
;
3630 LttvTracesetContext
* tsc
=
3631 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3632 TimeInterval time_span
= tsc
->time_span
;
3633 gint value
= gtk_spin_button_get_value_as_int(spinbutton
);
3634 LttTime new_current_time
= tab
->current_time
;
3635 new_current_time
.tv_sec
= value
;
3637 /* current nanoseconds */
3638 if(new_current_time
.tv_sec
== time_span
.start_time
.tv_sec
) {
3639 if(new_current_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3640 if(new_current_time
.tv_nsec
> time_span
.end_time
.tv_nsec
)
3641 new_current_time
.tv_nsec
= time_span
.end_time
.tv_nsec
;
3642 if(new_current_time
.tv_nsec
< time_span
.start_time
.tv_nsec
)
3643 new_current_time
.tv_nsec
= time_span
.start_time
.tv_nsec
;
3645 if(new_current_time
.tv_nsec
< time_span
.start_time
.tv_nsec
)
3646 new_current_time
.tv_nsec
= time_span
.start_time
.tv_nsec
;
3649 else if(new_current_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3650 if(new_current_time
.tv_nsec
> time_span
.end_time
.tv_nsec
)
3651 new_current_time
.tv_nsec
= time_span
.end_time
.tv_nsec
;
3654 current_time_change_manager(tab
, new_current_time
);
3658 on_MEntry6_value_changed (GtkSpinButton
*spinbutton
,
3661 Tab
*tab
= (Tab
*)user_data
;
3662 gint value
= gtk_spin_button_get_value_as_int(spinbutton
);
3663 LttTime new_current_time
= tab
->current_time
;
3664 new_current_time
.tv_nsec
= value
;
3666 current_time_change_manager(tab
, new_current_time
);
3670 void scroll_value_changed_cb(GtkWidget
*scrollbar
,
3673 Tab
*tab
= (Tab
*)user_data
;
3674 TimeWindow new_time_window
;
3676 GtkAdjustment
*adjust
= gtk_range_get_adjustment(GTK_RANGE(scrollbar
));
3677 gdouble value
= gtk_adjustment_get_value(adjust
);
3678 // gdouble upper, lower, ratio, page_size;
3680 LttvTracesetContext
* tsc
=
3681 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3682 TimeInterval time_span
= tsc
->time_span
;
3684 time
= ltt_time_add(ltt_time_from_double(value
),
3685 time_span
.start_time
);
3687 new_time_window
.start_time
= time
;
3689 page_size
= adjust
->page_size
;
3691 new_time_window
.time_width
=
3692 ltt_time_from_double(page_size
);
3694 new_time_window
.time_width_double
=
3697 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
3698 new_time_window
.time_width
);
3701 time_change_manager(tab
, new_time_window
);
3703 //time_window = tab->time_window;
3705 lower
= adjust
->lower
;
3706 upper
= adjust
->upper
;
3707 ratio
= (value
- lower
) / (upper
- lower
);
3708 g_info("lower %lu, upper %lu, value %lu, ratio %lu", lower
, upper
, value
, ratio
);
3710 //time = ltt_time_sub(time_span->end_time, time_span->start_time);
3711 //time = ltt_time_mul(time, (float)ratio);
3712 //time = ltt_time_add(time_span->start_time, time);
3713 time
= ltt_time_add(ltt_time_from_double(value
),
3714 time_span
.start_time
);
3716 time_window
.start_time
= time
;
3718 page_size
= adjust
->page_size
;
3720 time_window
.time_width
=
3721 ltt_time_from_double(page_size
);
3722 //time = ltt_time_sub(time_span.end_time, time);
3723 //if(ltt_time_compare(time,time_window.time_width) < 0){
3724 // time_window.time_width = time;
3727 /* call viewer hooks for new time window */
3728 set_time_window(tab
, &time_window
);
3733 /* Display a dialogue showing all eventtypes and traces, let user to select the interested
3734 * eventtypes, tracefiles and traces (filter)
3737 /* Select a trace which will be removed from traceset
3740 char * get_remove_trace(char ** all_trace_name
, int nb_trace
)
3742 return get_selection(all_trace_name
, nb_trace
,
3743 "Select a trace", "Trace pathname");
3747 /* Select a module which will be loaded
3750 char * get_load_module(char ** load_module_name
, int nb_module
)
3752 return get_selection(load_module_name
, nb_module
,
3753 "Select a module to load", "Module name");
3759 /* Select a module which will be unloaded
3762 char * get_unload_module(char ** loaded_module_name
, int nb_module
)
3764 return get_selection(loaded_module_name
, nb_module
,
3765 "Select a module to unload", "Module name");
3769 /* Display a dialogue which shows all selectable items, let user to
3770 * select one of them
3773 char * get_selection(char ** loaded_module_name
, int nb_module
,
3774 char *title
, char * column_title
)
3776 GtkWidget
* dialogue
;
3777 GtkWidget
* scroll_win
;
3779 GtkListStore
* store
;
3780 GtkTreeViewColumn
* column
;
3781 GtkCellRenderer
* renderer
;
3782 GtkTreeSelection
* select
;
3785 char * unload_module_name
= NULL
;
3787 dialogue
= gtk_dialog_new_with_buttons(title
,
3790 GTK_STOCK_OK
,GTK_RESPONSE_ACCEPT
,
3791 GTK_STOCK_CANCEL
,GTK_RESPONSE_REJECT
,
3793 gtk_window_set_default_size((GtkWindow
*)dialogue
, 500, 200);
3795 scroll_win
= gtk_scrolled_window_new (NULL
, NULL
);
3796 gtk_widget_show ( scroll_win
);
3797 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll_win
),
3798 GTK_POLICY_AUTOMATIC
, GTK_POLICY_AUTOMATIC
);
3800 store
= gtk_list_store_new (N_COLUMNS
,G_TYPE_STRING
);
3801 tree
= gtk_tree_view_new_with_model(GTK_TREE_MODEL (store
));
3802 gtk_widget_show ( tree
);
3803 g_object_unref (G_OBJECT (store
));
3805 renderer
= gtk_cell_renderer_text_new ();
3806 column
= gtk_tree_view_column_new_with_attributes (column_title
,
3808 "text", MODULE_COLUMN
,
3810 gtk_tree_view_column_set_alignment (column
, 0.5);
3811 gtk_tree_view_column_set_fixed_width (column
, 150);
3812 gtk_tree_view_append_column (GTK_TREE_VIEW (tree
), column
);
3814 select
= gtk_tree_view_get_selection (GTK_TREE_VIEW (tree
));
3815 gtk_tree_selection_set_mode (select
, GTK_SELECTION_SINGLE
);
3817 gtk_container_add (GTK_CONTAINER (scroll_win
), tree
);
3819 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialogue
)->vbox
), scroll_win
,TRUE
, TRUE
,0);
3821 for(i
=0;i
<nb_module
;i
++){
3822 gtk_list_store_append (store
, &iter
);
3823 gtk_list_store_set (store
, &iter
, MODULE_COLUMN
,loaded_module_name
[i
],-1);
3826 id
= gtk_dialog_run(GTK_DIALOG(dialogue
));
3827 GtkTreeModel
**store_model
= (GtkTreeModel
**)&store
;
3829 case GTK_RESPONSE_ACCEPT
:
3830 case GTK_RESPONSE_OK
:
3831 if (gtk_tree_selection_get_selected (select
, store_model
, &iter
)){
3832 gtk_tree_model_get ((GtkTreeModel
*)store
, &iter
, MODULE_COLUMN
, &unload_module_name
, -1);
3834 case GTK_RESPONSE_REJECT
:
3835 case GTK_RESPONSE_CANCEL
:
3837 gtk_widget_destroy(dialogue
);
3841 return unload_module_name
;
3845 /* Insert all menu entry and tool buttons into this main window
3850 void add_all_menu_toolbar_constructors(MainWindow
* mw
, gpointer user_data
)
3854 lttvwindow_viewer_constructor constructor
;
3855 LttvMenus
* global_menu
, * instance_menu
;
3856 LttvToolbars
* global_toolbar
, * instance_toolbar
;
3857 LttvMenuClosure
*menu_item
;
3858 LttvToolbarClosure
*toolbar_item
;
3859 LttvAttributeValue value
;
3860 LttvIAttribute
*global_attributes
= LTTV_IATTRIBUTE(lttv_global_attributes());
3861 LttvIAttribute
*attributes
= mw
->attributes
;
3862 GtkWidget
* tool_menu_title_menu
, *new_widget
, *pixmap
;
3864 g_assert(lttv_iattribute_find_by_path(global_attributes
,
3865 "viewers/menu", LTTV_POINTER
, &value
));
3866 if(*(value
.v_pointer
) == NULL
)
3867 *(value
.v_pointer
) = lttv_menus_new();
3868 global_menu
= (LttvMenus
*)*(value
.v_pointer
);
3870 g_assert(lttv_iattribute_find_by_path(attributes
,
3871 "viewers/menu", LTTV_POINTER
, &value
));
3872 if(*(value
.v_pointer
) == NULL
)
3873 *(value
.v_pointer
) = lttv_menus_new();
3874 instance_menu
= (LttvMenus
*)*(value
.v_pointer
);
3878 g_assert(lttv_iattribute_find_by_path(global_attributes
,
3879 "viewers/toolbar", LTTV_POINTER
, &value
));
3880 if(*(value
.v_pointer
) == NULL
)
3881 *(value
.v_pointer
) = lttv_toolbars_new();
3882 global_toolbar
= (LttvToolbars
*)*(value
.v_pointer
);
3884 g_assert(lttv_iattribute_find_by_path(attributes
,
3885 "viewers/toolbar", LTTV_POINTER
, &value
));
3886 if(*(value
.v_pointer
) == NULL
)
3887 *(value
.v_pointer
) = lttv_toolbars_new();
3888 instance_toolbar
= (LttvToolbars
*)*(value
.v_pointer
);
3890 /* Add missing menu entries to window instance */
3891 for(i
=0;i
<global_menu
->len
;i
++) {
3892 menu_item
= &g_array_index(global_menu
, LttvMenuClosure
, i
);
3894 //add menu_item to window instance;
3895 constructor
= menu_item
->con
;
3896 tool_menu_title_menu
= lookup_widget(mw
->mwindow
,"ToolMenuTitle_menu");
3898 gtk_menu_item_new_with_mnemonic (menu_item
->menu_text
);
3899 gtk_container_add (GTK_CONTAINER (tool_menu_title_menu
),
3901 g_signal_connect ((gpointer
) new_widget
, "activate",
3902 G_CALLBACK (insert_viewer_wrap
),
3904 gtk_widget_show (new_widget
);
3905 lttv_menus_add(instance_menu
, menu_item
->con
,
3906 menu_item
->menu_path
,
3907 menu_item
->menu_text
,
3912 /* Add missing toolbar entries to window instance */
3913 for(i
=0;i
<global_toolbar
->len
;i
++) {
3914 toolbar_item
= &g_array_index(global_toolbar
, LttvToolbarClosure
, i
);
3916 //add toolbar_item to window instance;
3917 constructor
= toolbar_item
->con
;
3918 tool_menu_title_menu
= lookup_widget(mw
->mwindow
,"MToolbar1");
3919 pixbuf
= gdk_pixbuf_new_from_xpm_data((const char**)toolbar_item
->pixmap
);
3920 pixmap
= gtk_image_new_from_pixbuf(pixbuf
);
3922 gtk_toolbar_append_element (GTK_TOOLBAR (tool_menu_title_menu
),
3923 GTK_TOOLBAR_CHILD_BUTTON
,
3926 toolbar_item
->tooltip
, NULL
,
3927 pixmap
, NULL
, NULL
);
3928 gtk_label_set_use_underline(
3929 GTK_LABEL (((GtkToolbarChild
*) (
3930 g_list_last (GTK_TOOLBAR
3931 (tool_menu_title_menu
)->children
)->data
))->label
),
3933 gtk_container_set_border_width (GTK_CONTAINER (new_widget
), 1);
3934 g_signal_connect ((gpointer
) new_widget
,
3936 G_CALLBACK (insert_viewer_wrap
),
3938 gtk_widget_show (new_widget
);
3940 lttv_toolbars_add(instance_toolbar
, toolbar_item
->con
,
3941 toolbar_item
->tooltip
,
3942 toolbar_item
->pixmap
,
3950 /* Create a main window
3953 void construct_main_window(MainWindow
* parent
)
3955 g_debug("construct_main_window()");
3956 GtkWidget
* new_window
; /* New generated main window */
3957 MainWindow
* new_m_window
;/* New main window structure */
3958 GtkNotebook
* notebook
;
3959 LttvIAttribute
*attributes
=
3960 LTTV_IATTRIBUTE(g_object_new(LTTV_ATTRIBUTE_TYPE
, NULL
));
3961 LttvAttributeValue value
;
3964 new_m_window
= g_new(MainWindow
, 1);
3966 // Add the object's information to the module's array
3967 g_main_window_list
= g_slist_append(g_main_window_list
, new_m_window
);
3969 new_window
= create_MWindow();
3970 gtk_widget_show (new_window
);
3972 new_m_window
->mwindow
= new_window
;
3973 new_m_window
->attributes
= attributes
;
3975 g_assert(lttv_iattribute_find_by_path(attributes
,
3976 "viewers/menu", LTTV_POINTER
, &value
));
3977 *(value
.v_pointer
) = lttv_menus_new();
3979 g_assert(lttv_iattribute_find_by_path(attributes
,
3980 "viewers/toolbar", LTTV_POINTER
, &value
));
3981 *(value
.v_pointer
) = lttv_toolbars_new();
3983 add_all_menu_toolbar_constructors(new_m_window
, NULL
);
3985 g_object_set_data_full(G_OBJECT(new_window
),
3987 (gpointer
)new_m_window
,
3988 (GDestroyNotify
)g_free
);
3989 //create a default tab
3990 notebook
= (GtkNotebook
*)lookup_widget(new_m_window
->mwindow
, "MNotebook");
3991 if(notebook
== NULL
){
3992 g_info("Notebook does not exist\n");
3995 //gtk_notebook_popup_enable (GTK_NOTEBOOK(notebook));
3996 //for now there is no name field in LttvTraceset structure
3997 //Use "Traceset" as the label for the default tab
3999 GtkWidget
* parent_notebook
= lookup_widget(parent
->mwindow
, "MNotebook");
4000 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(parent_notebook
),
4001 gtk_notebook_get_current_page(GTK_NOTEBOOK(parent_notebook
)));
4007 parent_tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
4009 new_tab
= create_tab(new_m_window
, parent_tab
, notebook
, "Traceset");
4011 new_tab
= create_tab(new_m_window
, NULL
, notebook
, "Traceset");
4012 /* First window, use command line trace */
4013 if(g_init_trace
!= NULL
){
4014 lttvwindow_add_trace(new_tab
,
4018 LttvTraceset
*traceset
= new_tab
->traceset_info
->traceset
;
4019 SetTraceset(new_tab
, traceset
);
4021 /* Insert default viewers */
4023 LttvAttributeType type
;
4024 LttvAttributeName name
;
4025 LttvAttributeValue value
;
4026 LttvAttribute
*attribute
;
4028 LttvIAttribute
*attributes_global
=
4029 LTTV_IATTRIBUTE(lttv_global_attributes());
4031 g_assert(attribute
=
4032 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
4033 LTTV_IATTRIBUTE(attributes_global
),
4034 LTTV_VIEWER_CONSTRUCTORS
)));
4036 name
= g_quark_from_string("guievents");
4037 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
4039 if(type
== LTTV_POINTER
) {
4040 lttvwindow_viewer_constructor viewer_constructor
=
4041 (lttvwindow_viewer_constructor
)*value
.v_pointer
;
4042 insert_viewer(new_window
, viewer_constructor
);
4045 name
= g_quark_from_string("guicontrolflow");
4046 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
4048 if(type
== LTTV_POINTER
) {
4049 lttvwindow_viewer_constructor viewer_constructor
=
4050 (lttvwindow_viewer_constructor
)*value
.v_pointer
;
4051 insert_viewer(new_window
, viewer_constructor
);
4054 name
= g_quark_from_string("guistatistics");
4055 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
4057 if(type
== LTTV_POINTER
) {
4058 lttvwindow_viewer_constructor viewer_constructor
=
4059 (lttvwindow_viewer_constructor
)*value
.v_pointer
;
4060 insert_viewer(new_window
, viewer_constructor
);
4066 g_info("There are now : %d windows\n",g_slist_length(g_main_window_list
));
4070 /* Free the memory occupied by a tab structure
4074 void tab_destructor(Tab
* tab
)
4076 int i
, nb
, ref_count
;
4079 gtk_object_destroy(GTK_OBJECT(tab
->tooltips
));
4082 g_object_unref(tab
->attributes
);
4084 if(tab
->interrupted_state
)
4085 g_object_unref(tab
->interrupted_state
);
4088 if(tab
->traceset_info
->traceset_context
!= NULL
){
4089 //remove state update hooks
4090 lttv_state_remove_event_hooks(
4091 (LttvTracesetState
*)tab
->traceset_info
->
4093 lttv_context_fini(LTTV_TRACESET_CONTEXT(tab
->traceset_info
->
4095 g_object_unref(tab
->traceset_info
->traceset_context
);
4097 if(tab
->traceset_info
->traceset
!= NULL
) {
4098 nb
= lttv_traceset_number(tab
->traceset_info
->traceset
);
4099 for(i
= 0 ; i
< nb
; i
++) {
4100 trace
= lttv_traceset_get(tab
->traceset_info
->traceset
, i
);
4101 ref_count
= lttv_trace_get_ref_number(trace
);
4103 ltt_trace_close(lttv_trace(trace
));
4107 lttv_filter_destroy(tab
->filter
);
4108 lttv_traceset_destroy(tab
->traceset_info
->traceset
);
4109 /* Remove the idle events requests processing function of the tab */
4110 g_idle_remove_by_data(tab
);
4112 g_slist_free(tab
->events_requests
);
4113 g_free(tab
->traceset_info
);
4118 /* Create a tab and insert it into the current main window
4121 Tab
* create_tab(MainWindow
* mw
, Tab
*copy_tab
,
4122 GtkNotebook
* notebook
, char * label
)
4127 //create a new tab data structure
4130 //construct and initialize the traceset_info
4131 tab
->traceset_info
= g_new(TracesetInfo
,1);
4134 tab
->traceset_info
->traceset
=
4135 lttv_traceset_copy(copy_tab
->traceset_info
->traceset
);
4137 /* Copy the previous tab's filter */
4138 /* We can clone the filter, as we copy the trace set also */
4139 /* The filter must always be in sync with the trace set */
4140 tab
->filter
= lttv_filter_clone(copy_tab
->filter
);
4143 tab
->traceset_info
->traceset
= lttv_traceset_new();
4148 lttv_attribute_write_xml(
4149 lttv_traceset_attribute(tab
->traceset_info
->traceset
),
4155 tab
->time_manager_lock
= FALSE
;
4156 tab
->current_time_manager_lock
= FALSE
;
4158 //FIXME copy not implemented in lower level
4159 tab
->traceset_info
->traceset_context
=
4160 g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
4161 g_assert(tab
->traceset_info
->traceset_context
!= NULL
);
4163 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
),
4164 tab
->traceset_info
->traceset
);
4165 //add state update hooks
4166 lttv_state_add_event_hooks(
4167 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
4169 //determine the current_time and time_window of the tab
4171 if(copy_tab
!= NULL
){
4172 tab
->time_window
= copy_tab
->time_window
;
4173 tab
->current_time
= copy_tab
->current_time
;
4175 tab
->time_window
.start_time
=
4176 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
4177 time_span
.start_time
;
4178 if(DEFAULT_TIME_WIDTH_S
<
4179 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
4180 time_span
.end_time
.tv_sec
)
4181 tmp_time
.tv_sec
= DEFAULT_TIME_WIDTH_S
;
4184 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
4185 time_span
.end_time
.tv_sec
;
4186 tmp_time
.tv_nsec
= 0;
4187 tab
->time_window
.time_width
= tmp_time
;
4188 tab
->current_time
.tv_sec
=
4189 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
4190 time_span
.start_time
.tv_sec
;
4191 tab
->current_time
.tv_nsec
=
4192 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
4193 time_span
.start_time
.tv_nsec
;
4196 tab
->attributes
= LTTV_IATTRIBUTE(g_object_new(LTTV_ATTRIBUTE_TYPE
, NULL
));
4197 tab
->interrupted_state
= g_object_new(LTTV_ATTRIBUTE_TYPE
, NULL
);
4199 tab
->vbox
= gtk_vbox_new(FALSE
, 2);
4200 tab
->viewer_container
= gtk_vbox_new(TRUE
, 2);
4201 tab
->scrollbar
= gtk_hscrollbar_new(NULL
);
4202 //tab->multivpaned = gtk_multi_vpaned_new();
4204 gtk_box_pack_start(GTK_BOX(tab
->vbox
),
4205 tab
->viewer_container
,
4207 TRUE
, /* Give the extra space to the child */
4208 0); /* No padding */
4210 /* Create the timebar */
4212 tab
->MTimebar
= gtk_hbox_new(FALSE
, 2);
4213 gtk_widget_show(tab
->MTimebar
);
4214 tab
->tooltips
= gtk_tooltips_new();
4216 tab
->MEventBox1a
= gtk_event_box_new();
4217 gtk_widget_show(tab
->MEventBox1a
);
4218 gtk_tooltips_set_tip(tab
->tooltips
, tab
->MEventBox1a
,
4219 "Paste Start and End Times Here", "");
4220 tab
->MText1a
= gtk_label_new("Time Frame ");
4221 gtk_widget_show(tab
->MText1a
);
4222 gtk_container_add(GTK_CONTAINER(tab
->MEventBox1a
), tab
->MText1a
);
4223 tab
->MEventBox1b
= gtk_event_box_new();
4224 gtk_widget_show(tab
->MEventBox1b
);
4225 gtk_tooltips_set_tip(tab
->tooltips
, tab
->MEventBox1b
,
4226 "Paste Start Time Here", "");
4227 tab
->MText1b
= gtk_label_new("start: ");
4228 gtk_widget_show(tab
->MText1b
);
4229 gtk_container_add(GTK_CONTAINER(tab
->MEventBox1b
), tab
->MText1b
);
4230 tab
->MText2
= gtk_label_new("s");
4231 gtk_widget_show(tab
->MText2
);
4232 tab
->MText3a
= gtk_label_new("ns");
4233 gtk_widget_show(tab
->MText3a
);
4234 tab
->MEventBox3b
= gtk_event_box_new();
4235 gtk_widget_show(tab
->MEventBox3b
);
4236 gtk_tooltips_set_tip(tab
->tooltips
, tab
->MEventBox3b
,
4237 "Paste End Time Here", "");
4238 tab
->MText3b
= gtk_label_new("end:");
4239 gtk_widget_show(tab
->MText3b
);
4240 gtk_container_add(GTK_CONTAINER(tab
->MEventBox3b
), tab
->MText3b
);
4241 tab
->MText4
= gtk_label_new("s");
4242 gtk_widget_show(tab
->MText4
);
4243 tab
->MText5a
= gtk_label_new("ns");
4244 gtk_widget_show(tab
->MText5a
);
4245 tab
->MEventBox5b
= gtk_event_box_new();
4246 gtk_widget_show(tab
->MEventBox5b
);
4247 gtk_tooltips_set_tip(tab
->tooltips
, tab
->MEventBox5b
,
4248 "Paste Current Time Here", "");
4249 tab
->MText5b
= gtk_label_new("Current Time:");
4250 gtk_widget_show(tab
->MText5b
);
4251 gtk_container_add(GTK_CONTAINER(tab
->MEventBox5b
), tab
->MText5b
);
4252 tab
->MText6
= gtk_label_new("s");
4253 gtk_widget_show(tab
->MText6
);
4254 tab
->MText7
= gtk_label_new("ns");
4255 gtk_widget_show(tab
->MText7
);
4257 tab
->MEntry1
= gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4258 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab
->MEntry1
),0);
4259 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab
->MEntry1
),TRUE
);
4260 gtk_widget_show(tab
->MEntry1
);
4261 tab
->MEntry2
= gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4262 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab
->MEntry2
),0);
4263 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab
->MEntry2
),TRUE
);
4264 gtk_widget_show(tab
->MEntry2
);
4265 tab
->MEntry3
= gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4266 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab
->MEntry3
),0);
4267 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab
->MEntry3
),TRUE
);
4268 gtk_widget_show(tab
->MEntry3
);
4269 tab
->MEntry4
= gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4270 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab
->MEntry4
),0);
4271 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab
->MEntry4
),TRUE
);
4272 gtk_widget_show(tab
->MEntry4
);
4273 tab
->MEntry5
= gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4274 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab
->MEntry5
),0);
4275 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab
->MEntry5
),TRUE
);
4276 gtk_widget_show(tab
->MEntry5
);
4277 tab
->MEntry6
= gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4278 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab
->MEntry6
),0);
4279 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab
->MEntry6
),TRUE
);
4280 gtk_widget_show(tab
->MEntry6
);
4283 GtkWidget
*temp_widget
;
4285 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEventBox1a
, FALSE
,
4287 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEventBox1b
, FALSE
,
4289 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEntry1
, FALSE
, FALSE
, 0);
4290 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MText2
, FALSE
, FALSE
, 0);
4291 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEntry2
, FALSE
, FALSE
, 0);
4292 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MText3a
, FALSE
, FALSE
, 0);
4293 temp_widget
= gtk_vseparator_new();
4294 gtk_widget_show(temp_widget
);
4295 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), temp_widget
, FALSE
, FALSE
, 0);
4296 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEventBox3b
, FALSE
,
4298 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEntry3
, FALSE
, FALSE
, 0);
4299 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MText4
, FALSE
, FALSE
, 0);
4300 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEntry4
, FALSE
, FALSE
, 0);
4301 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MText5a
, FALSE
, FALSE
, 0);
4302 temp_widget
= gtk_vseparator_new();
4303 gtk_widget_show(temp_widget
);
4304 gtk_box_pack_end (GTK_BOX (tab
->MTimebar
), tab
->MText7
, FALSE
, FALSE
, 0);
4305 gtk_box_pack_end (GTK_BOX (tab
->MTimebar
), tab
->MEntry6
, FALSE
, FALSE
, 0);
4306 gtk_box_pack_end (GTK_BOX (tab
->MTimebar
), tab
->MText6
, FALSE
, FALSE
, 0);
4307 gtk_box_pack_end (GTK_BOX (tab
->MTimebar
), tab
->MEntry5
, FALSE
, FALSE
, 0);
4308 gtk_box_pack_end (GTK_BOX (tab
->MTimebar
), tab
->MEventBox5b
, FALSE
,
4310 gtk_box_pack_end (GTK_BOX (tab
->MTimebar
), temp_widget
, FALSE
, FALSE
, 0);
4313 //GtkWidget *test = gtk_button_new_with_label("drop");
4314 //gtk_button_set_relief(GTK_BUTTON(test), GTK_RELIEF_NONE);
4315 //gtk_widget_show(test);
4316 //gtk_box_pack_end(GTK_BOX (tab->MTimebar), test, FALSE, FALSE, 0);
4317 //gtk_widget_add_events(tab->MText1, GDK_ALL_EVENTS_MASK);//GDK_BUTTON_PRESS_MASK);
4318 /*GtkWidget *event_box = gtk_event_box_new();
4319 gtk_widget_show(event_box);
4320 gtk_tooltips_set_tip(tooltips, event_box,
4321 "Paste Current Time Here", "");
4322 gtk_box_pack_end(GTK_BOX (tab->MTimebar), event_box, FALSE, FALSE, 0);
4323 GtkWidget *test = gtk_label_new("drop");
4324 gtk_container_add(GTK_CONTAINER(event_box), test);
4325 gtk_widget_show(test);
4326 g_signal_connect (G_OBJECT(event_box),
4327 "button-press-event",
4328 G_CALLBACK (on_MText1_paste),
4332 g_signal_connect (G_OBJECT(tab
->MEventBox1a
),
4333 "button-press-event",
4334 G_CALLBACK (on_MEventBox1a_paste
),
4337 g_signal_connect (G_OBJECT(tab
->MEventBox1b
),
4338 "button-press-event",
4339 G_CALLBACK (on_MEventBox1b_paste
),
4341 g_signal_connect (G_OBJECT(tab
->MEventBox3b
),
4342 "button-press-event",
4343 G_CALLBACK (on_MEventBox3b_paste
),
4345 g_signal_connect (G_OBJECT(tab
->MEventBox5b
),
4346 "button-press-event",
4347 G_CALLBACK (on_MEventBox5b_paste
),
4351 gtk_box_pack_end(GTK_BOX(tab
->vbox
),
4353 FALSE
, /* Do not expand */
4354 FALSE
, /* Fill has no effect here (expand false) */
4355 0); /* No padding */
4357 gtk_box_pack_end(GTK_BOX(tab
->vbox
),
4359 FALSE
, /* Do not expand */
4360 FALSE
, /* Fill has no effect here (expand false) */
4361 0); /* No padding */
4363 g_object_set_data(G_OBJECT(tab
->viewer_container
), "focused_viewer", NULL
);
4369 // Display a label with a X
4370 GtkWidget *w_hbox = gtk_hbox_new(FALSE, 4);
4371 GtkWidget *w_label = gtk_label_new (label);
4372 GtkWidget *pixmap = create_pixmap(GTK_WIDGET(notebook), "close.png");
4373 GtkWidget *w_button = gtk_button_new ();
4374 gtk_container_add(GTK_CONTAINER(w_button), pixmap);
4375 //GtkWidget *w_button = gtk_button_new_with_label("x");
4377 gtk_button_set_relief(GTK_BUTTON(w_button), GTK_RELIEF_NONE);
4379 gtk_box_pack_start(GTK_BOX(w_hbox), w_label, TRUE, TRUE, 0);
4380 gtk_box_pack_end(GTK_BOX(w_hbox), w_button, FALSE,
4383 g_signal_connect_swapped (w_button, "clicked",
4384 G_CALLBACK (on_close_tab_X_clicked),
4387 gtk_widget_set_state(w_button, GTK_STATE_ACTIVE);
4389 gtk_widget_show (w_label);
4390 gtk_widget_show (pixmap);
4391 gtk_widget_show (w_button);
4392 gtk_widget_show (w_hbox);
4394 tab->label = w_hbox;
4398 tab
->label
= gtk_label_new (label
);
4400 gtk_widget_show(tab
->label
);
4401 gtk_widget_show(tab
->scrollbar
);
4402 gtk_widget_show(tab
->viewer_container
);
4403 gtk_widget_show(tab
->vbox
);
4404 //gtk_widget_show(tab->multivpaned);
4407 /* Start with empty events requests list */
4408 tab
->events_requests
= NULL
;
4409 tab
->events_request_pending
= FALSE
;
4411 g_object_set_data_full(
4412 G_OBJECT(tab
->vbox
),
4415 (GDestroyNotify
)tab_destructor
);
4417 g_signal_connect(G_OBJECT(tab
->scrollbar
), "value-changed",
4418 G_CALLBACK(scroll_value_changed_cb
), tab
);
4420 g_signal_connect ((gpointer
) tab
->MEntry1
, "value-changed",
4421 G_CALLBACK (on_MEntry1_value_changed
),
4423 g_signal_connect ((gpointer
) tab
->MEntry2
, "value-changed",
4424 G_CALLBACK (on_MEntry2_value_changed
),
4426 g_signal_connect ((gpointer
) tab
->MEntry3
, "value-changed",
4427 G_CALLBACK (on_MEntry3_value_changed
),
4429 g_signal_connect ((gpointer
) tab
->MEntry4
, "value-changed",
4430 G_CALLBACK (on_MEntry4_value_changed
),
4432 g_signal_connect ((gpointer
) tab
->MEntry5
, "value-changed",
4433 G_CALLBACK (on_MEntry5_value_changed
),
4435 g_signal_connect ((gpointer
) tab
->MEntry6
, "value-changed",
4436 G_CALLBACK (on_MEntry6_value_changed
),
4439 //g_signal_connect(G_OBJECT(tab->scrollbar), "changed",
4440 // G_CALLBACK(scroll_value_changed_cb), tab);
4443 //insert tab into notebook
4444 gtk_notebook_append_page(notebook
,
4447 list
= gtk_container_get_children(GTK_CONTAINER(notebook
));
4448 gtk_notebook_set_current_page(notebook
,g_list_length(list
)-1);
4449 // always show : not if(g_list_length(list)>1)
4450 gtk_notebook_set_show_tabs(notebook
, TRUE
);
4456 * execute_events_requests
4458 * Idle function that executes the pending requests for a tab.
4460 * @return return value : TRUE : keep the idle function, FALSE : remove it.
4462 gboolean
execute_events_requests(Tab
*tab
)
4464 return ( lttvwindow_process_pending_requests(tab
) );