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
,
1117 g_assert(seek_count
< LTTV_STATE_SAVE_INTERVAL
);
1123 /* Else, the first request in list_in is a position request */
1124 /* If first req in list_in pos != current pos */
1125 g_assert(events_request
->start_position
!= NULL
);
1126 g_debug("SEEK POS time : %lu, %lu",
1127 lttv_traceset_context_position_get_time(
1128 events_request
->start_position
).tv_sec
,
1129 lttv_traceset_context_position_get_time(
1130 events_request
->start_position
).tv_nsec
);
1132 g_debug("SEEK POS context time : %lu, %lu",
1133 lttv_traceset_context_get_current_tfc(tsc
)->timestamp
.tv_sec
,
1134 lttv_traceset_context_get_current_tfc(tsc
)->timestamp
.tv_nsec
);
1135 g_assert(events_request
->start_position
!= NULL
);
1136 if(lttv_traceset_context_ctx_pos_compare(tsc
,
1137 events_request
->start_position
) != 0) {
1138 /* 1.2.2.1 Seek to that position */
1139 g_debug("SEEK POSITION");
1140 //lttv_process_traceset_seek_position(tsc, events_request->start_position);
1141 pos_time
= lttv_traceset_context_position_get_time(
1142 events_request
->start_position
);
1144 lttv_state_traceset_seek_time_closest(LTTV_TRACESET_STATE(tsc
),
1147 /* Process the traceset with only state hooks */
1149 lttv_process_traceset_middle(tsc
,
1152 events_request
->start_position
);
1153 g_assert(lttv_traceset_context_ctx_pos_compare(tsc
,
1154 events_request
->start_position
) == 0);
1161 /* 1.3 Add hooks and call before request for all list_in members */
1163 GSList
*iter
= NULL
;
1165 for(iter
=list_in
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
1166 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1167 /* 1.3.1 If !servicing */
1168 if(events_request
->servicing
== FALSE
) {
1169 /* - begin request hooks called
1170 * - servicing = TRUE
1172 lttv_hooks_call(events_request
->before_request
, (gpointer
)tsc
);
1173 events_request
->servicing
= TRUE
;
1175 /* 1.3.2 call before chunk
1176 * 1.3.3 events hooks added
1178 if(events_request
->trace
== -1)
1179 lttv_process_traceset_begin(tsc
,
1180 events_request
->before_chunk_traceset
,
1181 events_request
->before_chunk_trace
,
1182 events_request
->before_chunk_tracefile
,
1183 events_request
->event
,
1184 events_request
->event_by_id
);
1186 guint nb_trace
= lttv_traceset_number(tsc
->ts
);
1187 g_assert((guint
)events_request
->trace
< nb_trace
&&
1188 events_request
->trace
> -1);
1189 LttvTraceContext
*tc
= tsc
->traces
[events_request
->trace
];
1191 lttv_hooks_call(events_request
->before_chunk_traceset
, tsc
);
1193 lttv_trace_context_add_hooks(tc
,
1194 events_request
->before_chunk_trace
,
1195 events_request
->before_chunk_tracefile
,
1196 events_request
->event
,
1197 events_request
->event_by_id
);
1202 /* 2. Else, list_in is not empty, we continue a read */
1205 /* 2.0 For each req of list_in */
1206 GSList
*iter
= list_in
;
1208 while(iter
!= NULL
) {
1210 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1212 /* - Call before chunk
1213 * - events hooks added
1215 if(events_request
->trace
== -1)
1216 lttv_process_traceset_begin(tsc
,
1217 events_request
->before_chunk_traceset
,
1218 events_request
->before_chunk_trace
,
1219 events_request
->before_chunk_tracefile
,
1220 events_request
->event
,
1221 events_request
->event_by_id
);
1223 guint nb_trace
= lttv_traceset_number(tsc
->ts
);
1224 g_assert((guint
)events_request
->trace
< nb_trace
&&
1225 events_request
->trace
> -1);
1226 LttvTraceContext
*tc
= tsc
->traces
[events_request
->trace
];
1228 lttv_hooks_call(events_request
->before_chunk_traceset
, tsc
);
1230 lttv_trace_context_add_hooks(tc
,
1231 events_request
->before_chunk_trace
,
1232 events_request
->before_chunk_tracefile
,
1233 events_request
->event
,
1234 events_request
->event_by_id
);
1237 iter
= g_slist_next(iter
);
1242 tfc
= lttv_traceset_context_get_current_tfc(tsc
);
1244 /* 2.1 For each req of list_out */
1245 GSList
*iter
= list_out
;
1247 while(iter
!= NULL
) {
1249 gboolean remove
= FALSE
;
1250 gboolean free_data
= FALSE
;
1251 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1253 /* if req.start time == current context time
1254 * or req.start position == current position*/
1255 if( ltt_time_compare(events_request
->start_time
,
1256 tfc
->timestamp
) == 0
1258 (events_request
->start_position
!= NULL
1260 lttv_traceset_context_ctx_pos_compare(tsc
,
1261 events_request
->start_position
) == 0)
1263 /* - Add to list_in, remove from list_out */
1264 list_in
= g_slist_append(list_in
, events_request
);
1268 /* - If !servicing */
1269 if(events_request
->servicing
== FALSE
) {
1270 /* - begin request hooks called
1271 * - servicing = TRUE
1273 lttv_hooks_call(events_request
->before_request
, (gpointer
)tsc
);
1274 events_request
->servicing
= TRUE
;
1276 /* call before chunk
1277 * events hooks added
1279 if(events_request
->trace
== -1)
1280 lttv_process_traceset_begin(tsc
,
1281 events_request
->before_chunk_traceset
,
1282 events_request
->before_chunk_trace
,
1283 events_request
->before_chunk_tracefile
,
1284 events_request
->event
,
1285 events_request
->event_by_id
);
1287 guint nb_trace
= lttv_traceset_number(tsc
->ts
);
1288 g_assert((guint
)events_request
->trace
< nb_trace
&&
1289 events_request
->trace
> -1);
1290 LttvTraceContext
*tc
= tsc
->traces
[events_request
->trace
];
1292 lttv_hooks_call(events_request
->before_chunk_traceset
, tsc
);
1294 lttv_trace_context_add_hooks(tc
,
1295 events_request
->before_chunk_trace
,
1296 events_request
->before_chunk_tracefile
,
1297 events_request
->event
,
1298 events_request
->event_by_id
);
1307 GSList
*remove_iter
= iter
;
1309 iter
= g_slist_next(iter
);
1310 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
1311 list_out
= g_slist_remove_link(list_out
, remove_iter
);
1312 } else { // not remove
1313 iter
= g_slist_next(iter
);
1319 /* 3. Find end criterions */
1324 /* 3.1.1 Find lowest end time in list_in */
1325 g_assert(g_slist_length(list_in
)>0);
1326 end_time
= ((EventsRequest
*)g_slist_nth_data(list_in
,0))->end_time
;
1328 for(iter
=g_slist_nth(list_in
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
1329 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1331 if(ltt_time_compare(events_request
->end_time
,
1333 end_time
= events_request
->end_time
;
1336 /* 3.1.2 Find lowest start time in list_out */
1337 for(iter
=list_out
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
1338 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1340 if(ltt_time_compare(events_request
->start_time
,
1342 end_time
= events_request
->start_time
;
1347 /* 3.2 Number of events */
1349 /* 3.2.1 Find lowest number of events in list_in */
1352 end_nb_events
= ((EventsRequest
*)g_slist_nth_data(list_in
,0))->num_events
;
1354 for(iter
=g_slist_nth(list_in
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
1355 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1357 if(events_request
->num_events
< end_nb_events
)
1358 end_nb_events
= events_request
->num_events
;
1361 /* 3.2.2 Use min(CHUNK_NUM_EVENTS, min num events in list_in) as
1364 end_nb_events
= MIN(CHUNK_NUM_EVENTS
, end_nb_events
);
1368 /* 3.3 End position */
1370 /* 3.3.1 Find lowest end position in list_in */
1373 end_position
=((EventsRequest
*)g_slist_nth_data(list_in
,0))->end_position
;
1375 for(iter
=g_slist_nth(list_in
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
1376 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1378 if(events_request
->end_position
!= NULL
&& end_position
!= NULL
&&
1379 lttv_traceset_context_pos_pos_compare(events_request
->end_position
,
1381 end_position
= events_request
->end_position
;
1386 /* 3.3.2 Find lowest start position in list_out */
1389 for(iter
=list_out
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
1390 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1392 if(events_request
->end_position
!= NULL
&& end_position
!= NULL
&&
1393 lttv_traceset_context_pos_pos_compare(events_request
->end_position
,
1395 end_position
= events_request
->end_position
;
1400 /* 4. Call process traceset middle */
1401 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
);
1402 count
= lttv_process_traceset_middle(tsc
, end_time
, end_nb_events
, end_position
);
1404 tfc
= lttv_traceset_context_get_current_tfc(tsc
);
1406 g_debug("Context time after middle : %lu, %lu", tfc
->timestamp
.tv_sec
,
1407 tfc
->timestamp
.tv_nsec
);
1409 g_debug("End of trace reached after middle.");
1413 /* 5. After process traceset middle */
1414 tfc
= lttv_traceset_context_get_current_tfc(tsc
);
1416 /* - if current context time > traceset.end time */
1417 if(tfc
== NULL
|| ltt_time_compare(tfc
->timestamp
,
1418 tsc
->time_span
.end_time
) > 0) {
1419 /* - For each req in list_in */
1420 GSList
*iter
= list_in
;
1422 while(iter
!= NULL
) {
1424 gboolean remove
= FALSE
;
1425 gboolean free_data
= FALSE
;
1426 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1428 /* - Remove events hooks for req
1429 * - Call end chunk for req
1432 if(events_request
->trace
== -1)
1433 lttv_process_traceset_end(tsc
,
1434 events_request
->after_chunk_traceset
,
1435 events_request
->after_chunk_trace
,
1436 events_request
->after_chunk_tracefile
,
1437 events_request
->event
,
1438 events_request
->event_by_id
);
1441 guint nb_trace
= lttv_traceset_number(tsc
->ts
);
1442 g_assert(events_request
->trace
< nb_trace
&&
1443 events_request
->trace
> -1);
1444 LttvTraceContext
*tc
= tsc
->traces
[events_request
->trace
];
1446 lttv_trace_context_remove_hooks(tc
,
1447 events_request
->after_chunk_trace
,
1448 events_request
->after_chunk_tracefile
,
1449 events_request
->event
,
1450 events_request
->event_by_id
);
1451 lttv_hooks_call(events_request
->after_chunk_traceset
, tsc
);
1456 /* - Call end request for req */
1457 lttv_hooks_call(events_request
->after_request
, (gpointer
)tsc
);
1459 /* - remove req from list_in */
1460 /* Destroy the request */
1467 GSList
*remove_iter
= iter
;
1469 iter
= g_slist_next(iter
);
1470 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
1471 list_in
= g_slist_remove_link(list_in
, remove_iter
);
1472 } else { // not remove
1473 iter
= g_slist_next(iter
);
1478 /* 5.1 For each req in list_in */
1479 GSList
*iter
= list_in
;
1481 while(iter
!= NULL
) {
1483 gboolean remove
= FALSE
;
1484 gboolean free_data
= FALSE
;
1485 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1487 /* - Remove events hooks for req
1488 * - Call end chunk for req
1490 if(events_request
->trace
== -1)
1491 lttv_process_traceset_end(tsc
,
1492 events_request
->after_chunk_traceset
,
1493 events_request
->after_chunk_trace
,
1494 events_request
->after_chunk_tracefile
,
1495 events_request
->event
,
1496 events_request
->event_by_id
);
1499 guint nb_trace
= lttv_traceset_number(tsc
->ts
);
1500 g_assert(events_request
->trace
< nb_trace
&&
1501 events_request
->trace
> -1);
1502 LttvTraceContext
*tc
= tsc
->traces
[events_request
->trace
];
1504 lttv_trace_context_remove_hooks(tc
,
1505 events_request
->after_chunk_trace
,
1506 events_request
->after_chunk_tracefile
,
1507 events_request
->event
,
1508 events_request
->event_by_id
);
1510 lttv_hooks_call(events_request
->after_chunk_traceset
, tsc
);
1513 /* - req.num -= count */
1514 g_assert(events_request
->num_events
>= count
);
1515 events_request
->num_events
-= count
;
1517 g_assert(tfc
!= NULL
);
1518 /* - if req.num == 0
1520 * current context time >= req.end time
1522 * req.end pos == current pos
1524 * req.stop_flag == TRUE
1526 if( events_request
->num_events
== 0
1528 events_request
->stop_flag
== TRUE
1530 ltt_time_compare(tfc
->timestamp
,
1531 events_request
->end_time
) >= 0
1533 (events_request
->end_position
!= NULL
1535 lttv_traceset_context_ctx_pos_compare(tsc
,
1536 events_request
->end_position
) == 0)
1539 g_assert(events_request
->servicing
== TRUE
);
1540 /* - Call end request for req
1541 * - remove req from list_in */
1542 lttv_hooks_call(events_request
->after_request
, (gpointer
)tsc
);
1543 /* - remove req from list_in */
1544 /* Destroy the request */
1552 GSList
*remove_iter
= iter
;
1554 iter
= g_slist_next(iter
);
1555 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
1556 list_in
= g_slist_remove_link(list_in
, remove_iter
);
1557 } else { // not remove
1558 iter
= g_slist_next(iter
);
1564 /* End of removed servicing loop : leave control to GTK instead. */
1565 // if(gtk_events_pending()) break;
1568 /* B. When interrupted between chunks */
1571 GSList
*iter
= list_in
;
1573 /* 1. for each request in list_in */
1574 while(iter
!= NULL
) {
1576 gboolean remove
= FALSE
;
1577 gboolean free_data
= FALSE
;
1578 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1580 /* 1.1. Use current postition as start position */
1581 if(events_request
->start_position
!= NULL
)
1582 lttv_traceset_context_position_destroy(events_request
->start_position
);
1583 events_request
->start_position
= lttv_traceset_context_position_new();
1584 lttv_traceset_context_position_save(tsc
, events_request
->start_position
);
1586 /* 1.2. Remove start time */
1587 events_request
->start_time
= ltt_time_infinite
;
1589 /* 1.3. Move from list_in to list_out */
1592 list_out
= g_slist_append(list_out
, events_request
);
1597 GSList
*remove_iter
= iter
;
1599 iter
= g_slist_next(iter
);
1600 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
1601 list_in
= g_slist_remove_link(list_in
, remove_iter
);
1602 } else { // not remove
1603 iter
= g_slist_next(iter
);
1609 /* C Unlock Traces */
1611 lttv_process_traceset_get_sync_data(tsc
);
1612 //lttv_traceset_context_position_save(tsc, sync_position);
1617 iter_trace
<lttv_traceset_number(tsc
->ts
);
1619 LttvTrace
*trace_v
= lttv_traceset_get(tsc
->ts
, iter_trace
);
1621 lttvwindowtraces_unlock(trace_v
);
1625 //set the cursor back to normal
1626 gdk_window_set_cursor(win
, NULL
);
1629 g_assert(g_slist_length(list_in
) == 0);
1631 if( g_slist_length(list_out
) == 0 ) {
1632 /* Put tab's request pending flag back to normal */
1633 tab
->events_request_pending
= FALSE
;
1634 g_debug("remove the idle fct");
1635 return FALSE
; /* Remove the idle function */
1637 g_debug("leave the idle fct");
1638 return TRUE
; /* Leave the idle function */
1640 /* We do not use simili-round-robin, it may require to read 1 meg buffers
1641 * again and again if many tracesets use the same tracefiles. */
1642 /* Hack for round-robin idle functions */
1643 /* It will put the idle function at the end of the pool */
1644 /*g_idle_add_full((G_PRIORITY_HIGH_IDLE + 21),
1645 (GSourceFunc)execute_events_requests,
1655 static void lttvwindow_add_trace(Tab
*tab
, LttvTrace
*trace_v
)
1657 LttvTraceset
*traceset
= tab
->traceset_info
->traceset
;
1659 guint num_traces
= lttv_traceset_number(traceset
);
1661 //Verify if trace is already present.
1662 for(i
=0; i
<num_traces
; i
++)
1664 LttvTrace
* trace
= lttv_traceset_get(traceset
, i
);
1665 if(trace
== trace_v
)
1669 //Keep a reference to the traces so they are not freed.
1670 for(i
=0; i
<lttv_traceset_number(traceset
); i
++)
1672 LttvTrace
* trace
= lttv_traceset_get(traceset
, i
);
1673 lttv_trace_ref(trace
);
1676 //remove state update hooks
1677 lttv_state_remove_event_hooks(
1678 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1680 lttv_context_fini(LTTV_TRACESET_CONTEXT(
1681 tab
->traceset_info
->traceset_context
));
1682 g_object_unref(tab
->traceset_info
->traceset_context
);
1684 lttv_traceset_add(traceset
, trace_v
);
1685 lttv_trace_ref(trace_v
); /* local ref */
1687 /* Create new context */
1688 tab
->traceset_info
->traceset_context
=
1689 g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
1691 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->
1696 //add state update hooks
1697 lttv_state_add_event_hooks(
1698 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1699 //Remove local reference to the traces.
1700 for(i
=0; i
<lttv_traceset_number(traceset
); i
++)
1702 LttvTrace
* trace
= lttv_traceset_get(traceset
, i
);
1703 lttv_trace_unref(trace
);
1707 //add_trace_into_traceset_selector(GTK_MULTIVPANED(tab->multivpaned), lttv_trace(trace_v));
1710 /* add_trace adds a trace into the current traceset. It first displays a
1711 * directory selection dialogue to let user choose a trace, then recreates
1712 * tracset_context, and redraws all the viewer of the current tab
1715 void add_trace(GtkWidget
* widget
, gpointer user_data
)
1718 LttvTrace
* trace_v
;
1719 LttvTraceset
* traceset
;
1721 char abs_path
[PATH_MAX
];
1723 MainWindow
* mw_data
= get_window_data_struct(widget
);
1724 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
1726 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
1727 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
1731 tab
= create_new_tab(widget
, NULL
);
1733 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
1736 GtkDirSelection
* file_selector
= (GtkDirSelection
*)gtk_dir_selection_new("Select a trace");
1737 gtk_dir_selection_hide_fileop_buttons(file_selector
);
1739 if(remember_trace_dir
[0] != '\0')
1740 gtk_dir_selection_set_filename(file_selector
, remember_trace_dir
);
1742 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
1744 case GTK_RESPONSE_ACCEPT
:
1745 case GTK_RESPONSE_OK
:
1746 dir
= gtk_dir_selection_get_dir (file_selector
);
1747 strncpy(remember_trace_dir
, dir
, PATH_MAX
);
1748 if(!dir
|| strlen(dir
) == 0){
1749 gtk_widget_destroy((GtkWidget
*)file_selector
);
1752 get_absolute_pathname(dir
, abs_path
);
1753 trace_v
= lttvwindowtraces_get_trace_by_name(abs_path
);
1754 if(trace_v
== NULL
) {
1755 trace
= ltt_trace_open(abs_path
);
1757 g_warning("cannot open trace %s", abs_path
);
1759 trace_v
= lttv_trace_new(trace
);
1760 lttvwindowtraces_add_trace(trace_v
);
1761 lttvwindow_add_trace(tab
, trace_v
);
1764 lttvwindow_add_trace(tab
, trace_v
);
1767 gtk_widget_destroy((GtkWidget
*)file_selector
);
1769 //update current tab
1770 //update_traceset(mw_data);
1772 /* Call the updatetraceset hooks */
1774 traceset
= tab
->traceset_info
->traceset
;
1775 SetTraceset(tab
, traceset
);
1776 // in expose now call_pending_read_hooks(mw_data);
1778 //lttvwindow_report_current_time(mw_data,&(tab->current_time));
1780 case GTK_RESPONSE_REJECT
:
1781 case GTK_RESPONSE_CANCEL
:
1783 gtk_widget_destroy((GtkWidget
*)file_selector
);
1788 /* remove_trace removes a trace from the current traceset if all viewers in
1789 * the current tab are not interested in the trace. It first displays a
1790 * dialogue, which shows all traces in the current traceset, to let user choose
1791 * a trace, then it checks if all viewers unselect the trace, if it is true,
1792 * it will remove the trace, recreate the traceset_contex,
1793 * and redraws all the viewer of the current tab. If there is on trace in the
1794 * current traceset, it will delete all viewers of the current tab
1796 * It destroys the filter tree. FIXME... we should request for an update
1800 void remove_trace(GtkWidget
*widget
, gpointer user_data
)
1803 LttvTrace
* trace_v
;
1804 LttvTraceset
* traceset
;
1805 gint i
, j
, nb_trace
, index
=-1;
1806 char ** name
, *remove_trace_name
;
1807 MainWindow
* mw_data
= get_window_data_struct(widget
);
1808 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
1810 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
1811 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
1817 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
1820 nb_trace
=lttv_traceset_number(tab
->traceset_info
->traceset
);
1821 name
= g_new(char*,nb_trace
);
1822 for(i
= 0; i
< nb_trace
; i
++){
1823 trace_v
= lttv_traceset_get(tab
->traceset_info
->traceset
, i
);
1824 trace
= lttv_trace(trace_v
);
1825 name
[i
] = ltt_trace_name(trace
);
1828 remove_trace_name
= get_remove_trace(name
, nb_trace
);
1831 if(remove_trace_name
){
1833 /* yuk, cut n paste from old code.. should be better (MD)*/
1834 for(i
= 0; i
<nb_trace
; i
++) {
1835 if(strcmp(remove_trace_name
,name
[i
]) == 0){
1840 traceset
= tab
->traceset_info
->traceset
;
1841 //Keep a reference to the traces so they are not freed.
1842 for(j
=0; j
<lttv_traceset_number(traceset
); j
++)
1844 LttvTrace
* trace
= lttv_traceset_get(traceset
, j
);
1845 lttv_trace_ref(trace
);
1848 //remove state update hooks
1849 lttv_state_remove_event_hooks(
1850 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1851 lttv_context_fini(LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
));
1852 g_object_unref(tab
->traceset_info
->traceset_context
);
1854 trace_v
= lttv_traceset_get(traceset
, index
);
1856 lttv_traceset_remove(traceset
, index
);
1857 lttv_trace_unref(trace_v
); // Remove local reference
1859 if(lttv_trace_get_ref_number(trace_v
) <= 1) {
1860 /* ref 1 : lttvwindowtraces only*/
1861 ltt_trace_close(lttv_trace(trace_v
));
1862 /* lttvwindowtraces_remove_trace takes care of destroying
1863 * the traceset linked with the trace_v and also of destroying
1864 * the trace_v at the same time.
1866 lttvwindowtraces_remove_trace(trace_v
);
1869 tab
->traceset_info
->traceset_context
=
1870 g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
1872 LTTV_TRACESET_CONTEXT(tab
->
1873 traceset_info
->traceset_context
),traceset
);
1874 //add state update hooks
1875 lttv_state_add_event_hooks(
1876 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1878 //Remove local reference to the traces.
1879 for(j
=0; j
<lttv_traceset_number(traceset
); j
++)
1881 LttvTrace
* trace
= lttv_traceset_get(traceset
, j
);
1882 lttv_trace_unref(trace
);
1885 SetTraceset(tab
, (gpointer
)traceset
);
1891 void remove_trace(GtkWidget
* widget
, gpointer user_data
)
1894 LttvTrace
* trace_v
;
1895 LttvTraceset
* traceset
;
1896 gint i
, j
, nb_trace
;
1897 char ** name
, *remove_trace_name
;
1898 MainWindow
* mw_data
= get_window_data_struct(widget
);
1899 LttvTracesetSelector
* s
;
1900 LttvTraceSelector
* t
;
1903 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
1905 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
1906 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
1912 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
1915 nb_trace
=lttv_traceset_number(tab
->traceset_info
->traceset
);
1916 name
= g_new(char*,nb_trace
);
1917 for(i
= 0; i
< nb_trace
; i
++){
1918 trace_v
= lttv_traceset_get(tab
->traceset_info
->traceset
, i
);
1919 trace
= lttv_trace(trace_v
);
1920 name
[i
] = ltt_trace_name(trace
);
1923 remove_trace_name
= get_remove_trace(name
, nb_trace
);
1925 if(remove_trace_name
){
1926 for(i
=0; i
<nb_trace
; i
++){
1927 if(strcmp(remove_trace_name
,name
[i
]) == 0){
1928 //unselect the trace from the current viewer
1930 w
= gtk_multivpaned_get_widget(GTK_MULTIVPANED(tab
->multivpaned
));
1932 s
= g_object_get_data(G_OBJECT(w
), "Traceset_Selector");
1934 t
= lttv_traceset_selector_trace_get(s
,i
);
1935 lttv_trace_selector_set_selected(t
, FALSE
);
1938 //check if other viewers select the trace
1939 w
= gtk_multivpaned_get_first_widget(GTK_MULTIVPANED(tab
->multivpaned
));
1941 s
= g_object_get_data(G_OBJECT(w
), "Traceset_Selector");
1943 t
= lttv_traceset_selector_trace_get(s
,i
);
1944 selected
= lttv_trace_selector_get_selected(t
);
1947 w
= gtk_multivpaned_get_next_widget(GTK_MULTIVPANED(tab
->multivpaned
));
1949 }else selected
= FALSE
;
1951 //if no viewer selects the trace, remove it
1953 remove_trace_from_traceset_selector(GTK_MULTIVPANED(tab
->multivpaned
), i
);
1955 traceset
= tab
->traceset_info
->traceset
;
1956 //Keep a reference to the traces so they are not freed.
1957 for(j
=0; j
<lttv_traceset_number(traceset
); j
++)
1959 LttvTrace
* trace
= lttv_traceset_get(traceset
, j
);
1960 lttv_trace_ref(trace
);
1963 //remove state update hooks
1964 lttv_state_remove_event_hooks(
1965 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1966 lttv_context_fini(LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
));
1967 g_object_unref(tab
->traceset_info
->traceset_context
);
1970 trace_v
= lttv_traceset_get(traceset
, i
);
1972 if(lttv_trace_get_ref_number(trace_v
) <= 2) {
1973 /* ref 2 : traceset, local */
1974 lttvwindowtraces_remove_trace(trace_v
);
1975 ltt_trace_close(lttv_trace(trace_v
));
1978 lttv_traceset_remove(traceset
, i
);
1979 lttv_trace_unref(trace_v
); // Remove local reference
1981 if(!lttv_trace_get_ref_number(trace_v
))
1982 lttv_trace_destroy(trace_v
);
1984 tab
->traceset_info
->traceset_context
=
1985 g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
1987 LTTV_TRACESET_CONTEXT(tab
->
1988 traceset_info
->traceset_context
),traceset
);
1989 //add state update hooks
1990 lttv_state_add_event_hooks(
1991 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1993 //Remove local reference to the traces.
1994 for(j
=0; j
<lttv_traceset_number(traceset
); j
++)
1996 LttvTrace
* trace
= lttv_traceset_get(traceset
, j
);
1997 lttv_trace_unref(trace
);
2001 //update current tab
2002 //update_traceset(mw_data);
2005 SetTraceset(tab
, (gpointer
)traceset
);
2006 // in expose now call_pending_read_hooks(mw_data);
2008 //lttvwindow_report_current_time(mw_data,&(tab->current_time));
2011 // while(tab->multi_vpaned->num_children){
2012 // gtk_multi_vpaned_widget_delete(tab->multi_vpaned);
2026 /* Redraw all the viewers in the current tab */
2027 void redraw(GtkWidget
*widget
, gpointer user_data
)
2029 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
2030 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2031 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2036 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
2040 LttvAttributeValue value
;
2042 g_assert(lttv_iattribute_find_by_path(tab
->attributes
, "hooks/redraw", LTTV_POINTER
, &value
));
2044 tmp
= (LttvHooks
*)*(value
.v_pointer
);
2046 lttv_hooks_call(tmp
,NULL
);
2050 void continue_processing(GtkWidget
*widget
, gpointer user_data
)
2052 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
2053 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2054 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2059 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
2063 LttvAttributeValue value
;
2065 g_assert(lttv_iattribute_find_by_path(tab
->attributes
,
2066 "hooks/continue", LTTV_POINTER
, &value
));
2068 tmp
= (LttvHooks
*)*(value
.v_pointer
);
2070 lttv_hooks_call(tmp
,NULL
);
2073 /* Stop the processing for the calling main window's current tab.
2074 * It removes every processing requests that are in its list. It does not call
2075 * the end request hooks, because the request is not finished.
2078 void stop_processing(GtkWidget
*widget
, gpointer user_data
)
2080 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
2081 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2082 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2087 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
2089 GSList
*iter
= tab
->events_requests
;
2091 while(iter
!= NULL
) {
2092 GSList
*remove_iter
= iter
;
2093 iter
= g_slist_next(iter
);
2095 g_free(remove_iter
->data
);
2096 tab
->events_requests
=
2097 g_slist_remove_link(tab
->events_requests
, remove_iter
);
2099 tab
->events_request_pending
= FALSE
;
2100 g_idle_remove_by_data(tab
);
2101 g_assert(g_slist_length(tab
->events_requests
) == 0);
2105 /* save will save the traceset to a file
2106 * Not implemented yet FIXME
2109 void save(GtkWidget
* widget
, gpointer user_data
)
2114 void save_as(GtkWidget
* widget
, gpointer user_data
)
2116 g_info("Save as\n");
2120 /* zoom will change the time_window of all the viewers of the
2121 * current tab, and redisplay them. The main functionality is to
2122 * determine the new time_window of the current tab
2125 void zoom(GtkWidget
* widget
, double size
)
2127 TimeInterval time_span
;
2128 TimeWindow new_time_window
;
2129 LttTime current_time
, time_delta
;
2130 MainWindow
* mw_data
= get_window_data_struct(widget
);
2131 LttvTracesetContext
*tsc
;
2132 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
2134 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2135 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2141 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
2144 if(size
== 1) return;
2146 tsc
= LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
2147 time_span
= tsc
->time_span
;
2148 new_time_window
= tab
->time_window
;
2149 current_time
= tab
->current_time
;
2151 time_delta
= ltt_time_sub(time_span
.end_time
,time_span
.start_time
);
2153 new_time_window
.start_time
= time_span
.start_time
;
2154 new_time_window
.time_width
= time_delta
;
2155 new_time_window
.time_width_double
= ltt_time_to_double(time_delta
);
2156 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
2157 new_time_window
.time_width
) ;
2159 new_time_window
.time_width
= ltt_time_div(new_time_window
.time_width
, size
);
2160 new_time_window
.time_width_double
=
2161 ltt_time_to_double(new_time_window
.time_width
);
2162 if(ltt_time_compare(new_time_window
.time_width
,time_delta
) > 0)
2163 { /* Case where zoom out is bigger than trace length */
2164 new_time_window
.start_time
= time_span
.start_time
;
2165 new_time_window
.time_width
= time_delta
;
2166 new_time_window
.time_width_double
= ltt_time_to_double(time_delta
);
2167 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
2168 new_time_window
.time_width
) ;
2172 /* Center the image on the current time */
2173 new_time_window
.start_time
=
2174 ltt_time_sub(current_time
,
2175 ltt_time_from_double(new_time_window
.time_width_double
/2.0));
2176 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
2177 new_time_window
.time_width
) ;
2178 /* If on borders, don't fall off */
2179 if(ltt_time_compare(new_time_window
.start_time
, time_span
.start_time
) <0)
2181 new_time_window
.start_time
= time_span
.start_time
;
2182 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
2183 new_time_window
.time_width
) ;
2187 if(ltt_time_compare(new_time_window
.end_time
,
2188 time_span
.end_time
) > 0)
2190 new_time_window
.start_time
=
2191 ltt_time_sub(time_span
.end_time
, new_time_window
.time_width
);
2193 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
2194 new_time_window
.time_width
) ;
2201 if(ltt_time_compare(new_time_window
.time_width
, ltt_time_zero
) == 0) {
2202 g_warning("Zoom more than 1 ns impossible");
2204 time_change_manager(tab
, new_time_window
);
2208 void zoom_in(GtkWidget
* widget
, gpointer user_data
)
2213 void zoom_out(GtkWidget
* widget
, gpointer user_data
)
2218 void zoom_extended(GtkWidget
* widget
, gpointer user_data
)
2223 void go_to_time(GtkWidget
* widget
, gpointer user_data
)
2225 g_info("Go to time\n");
2228 void show_time_frame(GtkWidget
* widget
, gpointer user_data
)
2230 g_info("Show time frame\n");
2234 /* callback function */
2237 on_empty_traceset_activate (GtkMenuItem
*menuitem
,
2240 create_new_window((GtkWidget
*)menuitem
, user_data
, FALSE
);
2245 on_clone_traceset_activate (GtkMenuItem
*menuitem
,
2248 create_new_window((GtkWidget
*)menuitem
, user_data
, TRUE
);
2252 /* create_new_tab calls create_tab to construct a new tab in the main window
2255 Tab
*create_new_tab(GtkWidget
* widget
, gpointer user_data
){
2256 gchar label
[PATH_MAX
];
2257 MainWindow
* mw_data
= get_window_data_struct(widget
);
2259 GtkNotebook
* notebook
= (GtkNotebook
*)lookup_widget(widget
, "MNotebook");
2260 if(notebook
== NULL
){
2261 g_info("Notebook does not exist\n");
2264 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2265 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2271 copy_tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
2274 strcpy(label
,"Page");
2275 if(get_label(mw_data
, label
,"Get the name of the tab","Please input tab's name"))
2276 return (create_tab (mw_data
, copy_tab
, notebook
, label
));
2282 on_tab_activate (GtkMenuItem
*menuitem
,
2285 create_new_tab((GtkWidget
*)menuitem
, user_data
);
2290 on_open_activate (GtkMenuItem
*menuitem
,
2293 open_traceset((GtkWidget
*)menuitem
, user_data
);
2298 on_close_activate (GtkMenuItem
*menuitem
,
2301 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2302 main_window_destructor(mw_data
);
2306 /* remove the current tab from the main window
2310 on_close_tab_activate (GtkWidget
*widget
,
2314 GtkWidget
* notebook
;
2316 MainWindow
* mw_data
= get_window_data_struct(widget
);
2317 notebook
= lookup_widget(widget
, "MNotebook");
2318 if(notebook
== NULL
){
2319 g_info("Notebook does not exist\n");
2323 page_num
= gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
));
2325 gtk_notebook_remove_page(GTK_NOTEBOOK(notebook
), page_num
);
2330 on_close_tab_X_clicked (GtkWidget
*widget
,
2334 GtkWidget
*notebook
= lookup_widget(widget
, "MNotebook");
2335 if(notebook
== NULL
){
2336 g_info("Notebook does not exist\n");
2340 if((page_num
= gtk_notebook_page_num(GTK_NOTEBOOK(notebook
), widget
)) != -1)
2341 gtk_notebook_remove_page(GTK_NOTEBOOK(notebook
), page_num
);
2347 on_add_trace_activate (GtkMenuItem
*menuitem
,
2350 add_trace((GtkWidget
*)menuitem
, user_data
);
2355 on_remove_trace_activate (GtkMenuItem
*menuitem
,
2358 remove_trace((GtkWidget
*)menuitem
, user_data
);
2363 on_save_activate (GtkMenuItem
*menuitem
,
2366 save((GtkWidget
*)menuitem
, user_data
);
2371 on_save_as_activate (GtkMenuItem
*menuitem
,
2374 save_as((GtkWidget
*)menuitem
, user_data
);
2379 on_quit_activate (GtkMenuItem
*menuitem
,
2387 on_cut_activate (GtkMenuItem
*menuitem
,
2395 on_copy_activate (GtkMenuItem
*menuitem
,
2403 on_paste_activate (GtkMenuItem
*menuitem
,
2411 on_delete_activate (GtkMenuItem
*menuitem
,
2419 on_zoom_in_activate (GtkMenuItem
*menuitem
,
2422 zoom_in((GtkWidget
*)menuitem
, user_data
);
2427 on_zoom_out_activate (GtkMenuItem
*menuitem
,
2430 zoom_out((GtkWidget
*)menuitem
, user_data
);
2435 on_zoom_extended_activate (GtkMenuItem
*menuitem
,
2438 zoom_extended((GtkWidget
*)menuitem
, user_data
);
2443 on_go_to_time_activate (GtkMenuItem
*menuitem
,
2446 go_to_time((GtkWidget
*)menuitem
, user_data
);
2451 on_show_time_frame_activate (GtkMenuItem
*menuitem
,
2454 show_time_frame((GtkWidget
*)menuitem
, user_data
);
2459 on_move_viewer_up_activate (GtkMenuItem
*menuitem
,
2462 move_up_viewer((GtkWidget
*)menuitem
, user_data
);
2467 on_move_viewer_down_activate (GtkMenuItem
*menuitem
,
2470 move_down_viewer((GtkWidget
*)menuitem
, user_data
);
2475 on_remove_viewer_activate (GtkMenuItem
*menuitem
,
2478 delete_viewer((GtkWidget
*)menuitem
, user_data
);
2482 on_trace_facility_activate (GtkMenuItem
*menuitem
,
2485 g_info("Trace facility selector: %s\n");
2489 /* Dispaly a file selection dialogue to let user select a library, then call
2490 * lttv_library_load().
2494 on_load_library_activate (GtkMenuItem
*menuitem
,
2497 GError
*error
= NULL
;
2498 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2500 gchar load_module_path_alter
[PATH_MAX
];
2504 gchar
*load_module_path
;
2505 name
= g_ptr_array_new();
2506 nb
= lttv_library_path_number();
2507 /* ask for the library path */
2511 path
= lttv_library_path_get(i
);
2512 g_ptr_array_add(name
, path
);
2515 load_module_path
= get_selection((char **)(name
->pdata
), name
->len
,
2516 "Select a library path", "Library paths");
2517 if(load_module_path
!= NULL
)
2518 strncpy(load_module_path_alter
, load_module_path
, PATH_MAX
-1); // -1 for /
2520 g_ptr_array_free(name
, TRUE
);
2522 if(load_module_path
== NULL
) return;
2526 /* Make sure the module path ends with a / */
2527 gchar
*ptr
= load_module_path_alter
;
2529 ptr
= strchr(ptr
, '\0');
2531 if(*(ptr
-1) != '/') {
2538 /* Ask for the library to load : list files in the previously selected
2540 gchar str
[PATH_MAX
];
2543 GtkFileSelection
* file_selector
=
2544 (GtkFileSelection
*)gtk_file_selection_new("Select a module");
2545 gtk_file_selection_set_filename(file_selector
, load_module_path_alter
);
2546 gtk_file_selection_hide_fileop_buttons(file_selector
);
2549 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
2551 case GTK_RESPONSE_ACCEPT
:
2552 case GTK_RESPONSE_OK
:
2553 dir
= gtk_file_selection_get_selections (file_selector
);
2554 strncpy(str
,dir
[0],PATH_MAX
);
2555 strncpy(remember_plugins_dir
,dir
[0],PATH_MAX
);
2556 /* only keep file name */
2558 str1
= strrchr(str
,'/');
2561 str1
= strrchr(str
,'\\');
2566 if(*str1
== 'l' && *(str1
+1)== 'i' && *(str1
+2)=='b')
2568 remove info after
. */
2572 str2
= strrchr(str2
, '.');
2573 if(str2
!= NULL
) *str2
= '\0';
2575 lttv_module_require(str1
, &error
);
2577 lttv_library_load(str1
, &error
);
2578 if(error
!= NULL
) g_warning("%s", error
->message
);
2579 else g_info("Load library: %s\n", str
);
2581 case GTK_RESPONSE_REJECT
:
2582 case GTK_RESPONSE_CANCEL
:
2584 gtk_widget_destroy((GtkWidget
*)file_selector
);
2595 /* Display all loaded modules, let user to select a module to unload
2596 * by calling lttv_module_unload
2600 on_unload_library_activate (GtkMenuItem
*menuitem
,
2603 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2605 LttvLibrary
*library
= NULL
;
2610 name
= g_ptr_array_new();
2611 nb
= lttv_library_number();
2612 LttvLibraryInfo
*lib_info
= g_new(LttvLibraryInfo
,nb
);
2613 /* ask for the library name */
2616 LttvLibrary
*iter_lib
= lttv_library_get(i
);
2617 lttv_library_info(iter_lib
, &lib_info
[i
]);
2619 gchar
*path
= lib_info
[i
].name
;
2620 g_ptr_array_add(name
, path
);
2622 lib_name
= get_selection((char **)(name
->pdata
), name
->len
,
2623 "Select a library", "Libraries");
2624 if(lib_name
!= NULL
) {
2626 if(strcmp(lib_name
, lib_info
[i
].name
) == 0) {
2627 library
= lttv_library_get(i
);
2632 g_ptr_array_free(name
, TRUE
);
2635 if(lib_name
== NULL
) return;
2637 if(library
!= NULL
) lttv_library_unload(library
);
2641 /* Dispaly a file selection dialogue to let user select a module, then call
2642 * lttv_module_require().
2646 on_load_module_activate (GtkMenuItem
*menuitem
,
2649 GError
*error
= NULL
;
2650 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2652 LttvLibrary
*library
= NULL
;
2657 name
= g_ptr_array_new();
2658 nb
= lttv_library_number();
2659 LttvLibraryInfo
*lib_info
= g_new(LttvLibraryInfo
,nb
);
2660 /* ask for the library name */
2663 LttvLibrary
*iter_lib
= lttv_library_get(i
);
2664 lttv_library_info(iter_lib
, &lib_info
[i
]);
2666 gchar
*path
= lib_info
[i
].name
;
2667 g_ptr_array_add(name
, path
);
2669 lib_name
= get_selection((char **)(name
->pdata
), name
->len
,
2670 "Select a library", "Libraries");
2671 if(lib_name
!= NULL
) {
2673 if(strcmp(lib_name
, lib_info
[i
].name
) == 0) {
2674 library
= lttv_library_get(i
);
2679 g_ptr_array_free(name
, TRUE
);
2682 if(lib_name
== NULL
) return;
2685 //LttvModule *module;
2686 gchar module_name_out
[PATH_MAX
];
2688 /* Ask for the module to load : list modules in the selected lib */
2692 nb
= lttv_library_module_number(library
);
2693 LttvModuleInfo
*module_info
= g_new(LttvModuleInfo
,nb
);
2694 name
= g_ptr_array_new();
2695 /* ask for the module name */
2698 LttvModule
*iter_module
= lttv_library_module_get(library
, i
);
2699 lttv_module_info(iter_module
, &module_info
[i
]);
2701 gchar
*path
= module_info
[i
].name
;
2702 g_ptr_array_add(name
, path
);
2704 module_name
= get_selection((char **)(name
->pdata
), name
->len
,
2705 "Select a module", "Modules");
2706 if(module_name
!= NULL
) {
2708 if(strcmp(module_name
, module_info
[i
].name
) == 0) {
2709 strncpy(module_name_out
, module_name
, PATH_MAX
);
2710 //module = lttv_library_module_get(i);
2716 g_ptr_array_free(name
, TRUE
);
2717 g_free(module_info
);
2719 if(module_name
== NULL
) return;
2722 lttv_module_require(module_name_out
, &error
);
2723 if(error
!= NULL
) g_warning("%s", error
->message
);
2724 else g_info("Load module: %s", module_name_out
);
2731 gchar str
[PATH_MAX
];
2734 GtkFileSelection
* file_selector
=
2735 (GtkFileSelection
*)gtk_file_selection_new("Select a module");
2736 gtk_file_selection_set_filename(file_selector
, load_module_path_alter
);
2737 gtk_file_selection_hide_fileop_buttons(file_selector
);
2740 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
2742 case GTK_RESPONSE_ACCEPT
:
2743 case GTK_RESPONSE_OK
:
2744 dir
= gtk_file_selection_get_selections (file_selector
);
2745 strncpy(str
,dir
[0],PATH_MAX
);
2746 strncpy(remember_plugins_dir
,dir
[0],PATH_MAX
);
2748 /* only keep file name */
2750 str1
= strrchr(str
,'/');
2753 str1
= strrchr(str
,'\\');
2758 if(*str1
== 'l' && *(str1
+1)== 'i' && *(str1
+2)=='b')
2760 remove info after
. */
2764 str2
= strrchr(str2
, '.');
2765 if(str2
!= NULL
) *str2
= '\0';
2767 lttv_module_require(str1
, &error
);
2769 lttv_library_load(str1
, &error
);
2770 if(error
!= NULL
) g_warning(error
->message
);
2771 else g_info("Load library: %s\n", str
);
2773 case GTK_RESPONSE_REJECT
:
2774 case GTK_RESPONSE_CANCEL
:
2776 gtk_widget_destroy((GtkWidget
*)file_selector
);
2788 /* Display all loaded modules, let user to select a module to unload
2789 * by calling lttv_module_unload
2793 on_unload_module_activate (GtkMenuItem
*menuitem
,
2796 GError
*error
= NULL
;
2797 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2799 LttvLibrary
*library
;
2804 name
= g_ptr_array_new();
2805 nb
= lttv_library_number();
2806 LttvLibraryInfo
*lib_info
= g_new(LttvLibraryInfo
,nb
);
2807 /* ask for the library name */
2810 LttvLibrary
*iter_lib
= lttv_library_get(i
);
2811 lttv_library_info(iter_lib
, &lib_info
[i
]);
2813 gchar
*path
= lib_info
[i
].name
;
2814 g_ptr_array_add(name
, path
);
2816 lib_name
= get_selection((char **)(name
->pdata
), name
->len
,
2817 "Select a library", "Libraries");
2818 if(lib_name
!= NULL
) {
2820 if(strcmp(lib_name
, lib_info
[i
].name
) == 0) {
2821 library
= lttv_library_get(i
);
2826 g_ptr_array_free(name
, TRUE
);
2829 if(lib_name
== NULL
) return;
2832 LttvModule
*module
= NULL
;
2834 /* Ask for the module to load : list modules in the selected lib */
2838 nb
= lttv_library_module_number(library
);
2839 LttvModuleInfo
*module_info
= g_new(LttvModuleInfo
,nb
);
2840 name
= g_ptr_array_new();
2841 /* ask for the module name */
2844 LttvModule
*iter_module
= lttv_library_module_get(library
, i
);
2845 lttv_module_info(iter_module
, &module_info
[i
]);
2847 gchar
*path
= module_info
[i
].name
;
2848 if(module_info
[i
].use_count
> 0) g_ptr_array_add(name
, path
);
2850 module_name
= get_selection((char **)(name
->pdata
), name
->len
,
2851 "Select a module", "Modules");
2852 if(module_name
!= NULL
) {
2854 if(strcmp(module_name
, module_info
[i
].name
) == 0) {
2855 module
= lttv_library_module_get(library
, i
);
2861 g_ptr_array_free(name
, TRUE
);
2862 g_free(module_info
);
2864 if(module_name
== NULL
) return;
2867 LttvModuleInfo module_info
;
2868 lttv_module_info(module
, &module_info
);
2869 g_info("Release module: %s\n", module_info
.name
);
2871 lttv_module_release(module
);
2875 /* Display a directory dialogue to let user select a path for library searching
2879 on_add_library_search_path_activate (GtkMenuItem
*menuitem
,
2882 GtkDirSelection
* file_selector
= (GtkDirSelection
*)gtk_dir_selection_new("Select library path");
2886 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2887 if(remember_plugins_dir
[0] != '\0')
2888 gtk_dir_selection_set_filename(file_selector
, remember_plugins_dir
);
2890 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
2892 case GTK_RESPONSE_ACCEPT
:
2893 case GTK_RESPONSE_OK
:
2894 dir
= gtk_dir_selection_get_dir (file_selector
);
2895 strncpy(remember_plugins_dir
,dir
,PATH_MAX
);
2896 strncat(remember_plugins_dir
,"/",PATH_MAX
);
2897 lttv_library_path_add(dir
);
2898 case GTK_RESPONSE_REJECT
:
2899 case GTK_RESPONSE_CANCEL
:
2901 gtk_widget_destroy((GtkWidget
*)file_selector
);
2907 /* Display a directory dialogue to let user select a path for library searching
2911 on_remove_library_search_path_activate (GtkMenuItem
*menuitem
,
2914 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2916 const char *lib_path
;
2921 name
= g_ptr_array_new();
2922 nb
= lttv_library_path_number();
2923 /* ask for the library name */
2926 gchar
*path
= lttv_library_path_get(i
);
2927 g_ptr_array_add(name
, path
);
2929 lib_path
= get_selection((char **)(name
->pdata
), name
->len
,
2930 "Select a library path", "Library paths");
2932 g_ptr_array_free(name
, TRUE
);
2934 if(lib_path
== NULL
) return;
2937 lttv_library_path_remove(lib_path
);
2941 on_color_activate (GtkMenuItem
*menuitem
,
2949 on_save_configuration_activate (GtkMenuItem
*menuitem
,
2952 g_info("Save configuration\n");
2957 on_content_activate (GtkMenuItem
*menuitem
,
2960 g_info("Content\n");
2965 on_about_close_activate (GtkButton
*button
,
2968 GtkWidget
*about_widget
= GTK_WIDGET(user_data
);
2970 gtk_widget_destroy(about_widget
);
2974 on_about_activate (GtkMenuItem
*menuitem
,
2977 MainWindow
*main_window
= get_window_data_struct(GTK_WIDGET(menuitem
));
2978 GtkWidget
*window_widget
= main_window
->mwindow
;
2979 GtkWidget
*about_widget
= gtk_window_new(GTK_WINDOW_TOPLEVEL
);
2980 GtkWindow
*about_window
= GTK_WINDOW(about_widget
);
2981 gint window_width
, window_height
;
2983 gtk_window_set_title(about_window
, "About Linux Trace Toolkit");
2985 gtk_window_set_resizable(about_window
, FALSE
);
2986 gtk_window_set_transient_for(GTK_WINDOW(window_widget
), about_window
);
2987 gtk_window_set_destroy_with_parent(about_window
, TRUE
);
2988 gtk_window_set_modal(about_window
, FALSE
);
2990 /* Put the about window at the center of the screen */
2991 gtk_window_get_size(about_window
, &window_width
, &window_height
);
2992 gtk_window_move (about_window
,
2993 (gdk_screen_width() - window_width
)/2,
2994 (gdk_screen_height() - window_height
)/2);
2996 GtkWidget
*vbox
= gtk_vbox_new(FALSE
, 1);
2998 gtk_container_add(GTK_CONTAINER(about_widget
), vbox
);
3002 GtkWidget
*label1
= gtk_label_new("");
3003 gtk_misc_set_padding(GTK_MISC(label1
), 10, 20);
3004 gtk_label_set_markup(GTK_LABEL(label1
), "\
3005 <big>Linux Trace Toolkit</big>");
3006 gtk_label_set_justify(GTK_LABEL(label1
), GTK_JUSTIFY_CENTER
);
3008 GtkWidget
*label2
= gtk_label_new("");
3009 gtk_misc_set_padding(GTK_MISC(label2
), 10, 20);
3010 gtk_label_set_markup(GTK_LABEL(label2
), "\
3013 Michel Dagenais (New trace format, lttv main)\n\
3014 Mathieu Desnoyers (Directory structure, build with automake/conf,\n\
3015 lttv gui, control flow view, gui cooperative trace reading\n\
3016 scheduler with interruptible foreground and background\n\
3017 computation, detailed event list)\n\
3018 Benoit Des Ligneris, Eric Clement (Cluster adaptation, work in progress)\n\
3019 Xang-Xiu Yang (new trace reading library and converter, lttv gui, \n\
3020 detailed event list and statistics view)\n\
3021 Tom Zanussi (RelayFS)\n\
3023 Strongly inspired from the original Linux Trace Toolkit Visualizer made by\n\
3026 GtkWidget
*label3
= gtk_label_new("");
3027 gtk_label_set_markup(GTK_LABEL(label3
), "\
3028 Linux Trace Toolkit Viewer, Copyright (C) 2004\n\
3030 Mathieu Desnoyers\n\
3032 Linux Trace Toolkit comes with ABSOLUTELY NO WARRANTY.\n\
3033 This is free software, and you are welcome to redistribute it\n\
3034 under certain conditions. See COPYING for details.");
3035 gtk_misc_set_padding(GTK_MISC(label3
), 10, 20);
3037 gtk_box_pack_start_defaults(GTK_BOX(vbox
), label1
);
3038 gtk_box_pack_start_defaults(GTK_BOX(vbox
), label2
);
3039 gtk_box_pack_start_defaults(GTK_BOX(vbox
), label3
);
3041 GtkWidget
*hbox
= gtk_hbox_new(TRUE
, 0);
3042 gtk_box_pack_end(GTK_BOX(vbox
), hbox
, FALSE
, FALSE
, 0);
3043 GtkWidget
*close_button
= gtk_button_new_with_mnemonic("_Close");
3044 gtk_box_pack_end(GTK_BOX(hbox
), close_button
, FALSE
, FALSE
, 0);
3045 gtk_container_set_border_width(GTK_CONTAINER(close_button
), 20);
3047 g_signal_connect(G_OBJECT(close_button
), "clicked",
3048 G_CALLBACK(on_about_close_activate
),
3049 (gpointer
)about_widget
);
3051 gtk_widget_show_all(about_widget
);
3056 on_button_new_clicked (GtkButton
*button
,
3059 create_new_window((GtkWidget
*)button
, user_data
, TRUE
);
3063 on_button_new_tab_clicked (GtkButton
*button
,
3066 create_new_tab((GtkWidget
*)button
, user_data
);
3070 on_button_open_clicked (GtkButton
*button
,
3073 open_traceset((GtkWidget
*)button
, user_data
);
3078 on_button_add_trace_clicked (GtkButton
*button
,
3081 add_trace((GtkWidget
*)button
, user_data
);
3086 on_button_remove_trace_clicked (GtkButton
*button
,
3089 remove_trace((GtkWidget
*)button
, user_data
);
3093 on_button_redraw_clicked (GtkButton
*button
,
3096 redraw((GtkWidget
*)button
, user_data
);
3100 on_button_continue_processing_clicked (GtkButton
*button
,
3103 continue_processing((GtkWidget
*)button
, user_data
);
3107 on_button_stop_processing_clicked (GtkButton
*button
,
3110 stop_processing((GtkWidget
*)button
, user_data
);
3116 on_button_save_clicked (GtkButton
*button
,
3119 save((GtkWidget
*)button
, user_data
);
3124 on_button_save_as_clicked (GtkButton
*button
,
3127 save_as((GtkWidget
*)button
, user_data
);
3132 on_button_zoom_in_clicked (GtkButton
*button
,
3135 zoom_in((GtkWidget
*)button
, user_data
);
3140 on_button_zoom_out_clicked (GtkButton
*button
,
3143 zoom_out((GtkWidget
*)button
, user_data
);
3148 on_button_zoom_extended_clicked (GtkButton
*button
,
3151 zoom_extended((GtkWidget
*)button
, user_data
);
3156 on_button_go_to_time_clicked (GtkButton
*button
,
3159 go_to_time((GtkWidget
*)button
, user_data
);
3164 on_button_show_time_frame_clicked (GtkButton
*button
,
3167 show_time_frame((GtkWidget
*)button
, user_data
);
3172 on_button_move_up_clicked (GtkButton
*button
,
3175 move_up_viewer((GtkWidget
*)button
, user_data
);
3180 on_button_move_down_clicked (GtkButton
*button
,
3183 move_down_viewer((GtkWidget
*)button
, user_data
);
3188 on_button_delete_viewer_clicked (GtkButton
*button
,
3191 delete_viewer((GtkWidget
*)button
, user_data
);
3195 on_MWindow_destroy (GtkWidget
*widget
,
3198 MainWindow
*main_window
= get_window_data_struct(widget
);
3199 LttvIAttribute
*attributes
= main_window
->attributes
;
3200 LttvAttributeValue value
;
3202 //This is unnecessary, since widgets will be destroyed
3203 //by the main window widget anyway.
3204 //remove_all_menu_toolbar_constructors(main_window, NULL);
3206 g_assert(lttv_iattribute_find_by_path(attributes
,
3207 "viewers/menu", LTTV_POINTER
, &value
));
3208 lttv_menus_destroy((LttvMenus
*)*(value
.v_pointer
));
3210 g_assert(lttv_iattribute_find_by_path(attributes
,
3211 "viewers/toolbar", LTTV_POINTER
, &value
));
3212 lttv_toolbars_destroy((LttvToolbars
*)*(value
.v_pointer
));
3214 g_object_unref(main_window
->attributes
);
3215 g_main_window_list
= g_slist_remove(g_main_window_list
, main_window
);
3217 g_info("There are now : %d windows\n",g_slist_length(g_main_window_list
));
3218 if(g_slist_length(g_main_window_list
) == 0)
3223 on_MWindow_configure (GtkWidget
*widget
,
3224 GdkEventConfigure
*event
,
3227 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)widget
);
3229 // MD : removed time width modification upon resizing of the main window.
3230 // The viewers will redraw themselves completely, without time interval
3233 if(mw_data->window_width){
3234 time_span = LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context)->Time_Span ;
3235 time_win = tab->time_window;
3236 ratio = width / mw_data->window_width;
3237 tab->time_window.time_width = ltt_time_mul(time_win.time_width,ratio);
3238 time = ltt_time_sub(time_span->endTime, time_win.start_time);
3239 if(ltt_time_compare(time, tab->time_window.time_width) < 0){
3240 tab->time_window.time_width = time;
3246 mw_data->window_width = (int)width;
3255 on_MNotebook_switch_page (GtkNotebook
*notebook
,
3256 GtkNotebookPage
*page
,
3264 void time_change_manager (Tab
*tab
,
3265 TimeWindow new_time_window
)
3267 /* Only one source of time change */
3268 if(tab
->time_manager_lock
== TRUE
) return;
3270 tab
->time_manager_lock
= TRUE
;
3272 LttvTracesetContext
*tsc
= LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3273 TimeInterval time_span
= tsc
->time_span
;
3274 LttTime start_time
= new_time_window
.start_time
;
3275 LttTime end_time
= new_time_window
.end_time
;
3278 GtkAdjustment
*adjustment
= gtk_range_get_adjustment(GTK_RANGE(tab
->scrollbar
));
3279 LttTime upper
= ltt_time_sub(time_span
.end_time
, time_span
.start_time
);
3281 gtk_range_set_increments(GTK_RANGE(tab
->scrollbar
),
3282 ltt_time_to_double(new_time_window
.time_width
)
3283 / SCROLL_STEP_PER_PAGE
3284 * NANOSECONDS_PER_SECOND
, /* step increment */
3285 ltt_time_to_double(new_time_window
.time_width
)
3286 * NANOSECONDS_PER_SECOND
); /* page increment */
3287 gtk_range_set_range(GTK_RANGE(tab
->scrollbar
),
3289 ltt_time_to_double(upper
)
3290 * NANOSECONDS_PER_SECOND
); /* upper */
3292 g_object_set(G_OBJECT(adjustment
),
3296 ltt_time_to_double(upper
), /* upper */
3298 new_time_window
.time_width_double
3299 / SCROLL_STEP_PER_PAGE
, /* step increment */
3301 new_time_window
.time_width_double
,
3302 /* page increment */
3304 new_time_window
.time_width_double
, /* page size */
3306 gtk_adjustment_changed(adjustment
);
3308 // g_object_set(G_OBJECT(adjustment),
3310 // ltt_time_to_double(
3311 // ltt_time_sub(start_time, time_span.start_time))
3314 //gtk_adjustment_value_changed(adjustment);
3315 gtk_range_set_value(GTK_RANGE(tab
->scrollbar
),
3317 ltt_time_sub(start_time
, time_span
.start_time
)) /* value */);
3319 /* set the time bar. */
3321 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry1
),
3322 (double)time_span
.start_time
.tv_sec
,
3323 (double)time_span
.end_time
.tv_sec
);
3324 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry1
),
3325 (double)start_time
.tv_sec
);
3327 /* start nanoseconds */
3328 if(start_time
.tv_sec
== time_span
.start_time
.tv_sec
) {
3329 /* can be both beginning and end at the same time. */
3330 if(start_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3331 /* If we are at the end, max nsec to end.. -1 (not zero length) */
3332 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry2
),
3333 (double)time_span
.start_time
.tv_nsec
,
3334 (double)time_span
.end_time
.tv_nsec
-1);
3336 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry2
),
3337 (double)time_span
.start_time
.tv_nsec
,
3338 (double)NANOSECONDS_PER_SECOND
-1);
3340 } else if(start_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3341 /* If we are at the end, max nsec to end.. -1 (not zero length) */
3342 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry2
),
3344 (double)time_span
.end_time
.tv_nsec
-1);
3345 } else /* anywhere else */
3346 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry2
),
3348 (double)NANOSECONDS_PER_SECOND
-1);
3349 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry2
),
3350 (double)start_time
.tv_nsec
);
3353 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry3
),
3354 (double)time_span
.start_time
.tv_sec
,
3355 (double)time_span
.end_time
.tv_sec
);
3356 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry3
),
3357 (double)end_time
.tv_sec
);
3359 /* end nanoseconds */
3360 if(end_time
.tv_sec
== time_span
.start_time
.tv_sec
) {
3361 /* can be both beginning and end at the same time. */
3362 if(end_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3363 /* If we are at the end, max nsec to end.. */
3364 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry4
),
3365 (double)time_span
.start_time
.tv_nsec
+1,
3366 (double)time_span
.end_time
.tv_nsec
);
3368 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry4
),
3369 (double)time_span
.start_time
.tv_nsec
+1,
3370 (double)NANOSECONDS_PER_SECOND
-1);
3373 else if(end_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3374 /* If we are at the end, max nsec to end.. */
3375 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry4
),
3377 (double)time_span
.end_time
.tv_nsec
);
3379 else /* anywhere else */
3380 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry4
),
3382 (double)NANOSECONDS_PER_SECOND
-1);
3383 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry4
),
3384 (double)end_time
.tv_nsec
);
3386 /* call viewer hooks for new time window */
3387 set_time_window(tab
, &new_time_window
);
3389 tab
->time_manager_lock
= FALSE
;
3393 /* value changed for frame start s
3395 * Check time span : if ns is out of range, clip it the nearest good value.
3398 on_MEntry1_value_changed (GtkSpinButton
*spinbutton
,
3401 Tab
*tab
=(Tab
*)user_data
;
3402 LttvTracesetContext
* tsc
=
3403 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3404 TimeInterval time_span
= tsc
->time_span
;
3405 gint value
= gtk_spin_button_get_value_as_int(spinbutton
);
3407 TimeWindow new_time_window
= tab
->time_window
;
3409 LttTime end_time
= new_time_window
.end_time
;
3411 new_time_window
.start_time
.tv_sec
= value
;
3413 /* start nanoseconds */
3414 if(new_time_window
.start_time
.tv_sec
== time_span
.start_time
.tv_sec
) {
3415 if(new_time_window
.start_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3416 if(new_time_window
.start_time
.tv_nsec
> time_span
.end_time
.tv_nsec
)
3417 new_time_window
.start_time
.tv_nsec
= time_span
.end_time
.tv_nsec
-1;
3418 if(new_time_window
.start_time
.tv_nsec
< time_span
.start_time
.tv_nsec
)
3419 new_time_window
.start_time
.tv_nsec
= time_span
.start_time
.tv_nsec
;
3421 if(new_time_window
.start_time
.tv_nsec
< time_span
.start_time
.tv_nsec
)
3422 new_time_window
.start_time
.tv_nsec
= time_span
.start_time
.tv_nsec
;
3425 else if(new_time_window
.start_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3426 if(new_time_window
.start_time
.tv_nsec
> time_span
.end_time
.tv_nsec
)
3427 new_time_window
.start_time
.tv_nsec
= time_span
.end_time
.tv_nsec
-1;
3430 if(ltt_time_compare(new_time_window
.start_time
, end_time
) >= 0) {
3431 /* Then, we must push back end time : keep the same time width
3432 * if possible, else end traceset time */
3433 end_time
= LTT_TIME_MIN(ltt_time_add(new_time_window
.start_time
,
3434 new_time_window
.time_width
),
3435 time_span
.end_time
);
3438 /* Fix the time width to fit start time and end time */
3439 new_time_window
.time_width
= ltt_time_sub(end_time
,
3440 new_time_window
.start_time
);
3441 new_time_window
.time_width_double
=
3442 ltt_time_to_double(new_time_window
.time_width
);
3444 new_time_window
.end_time
= end_time
;
3446 time_change_manager(tab
, new_time_window
);
3451 on_MEntry2_value_changed (GtkSpinButton
*spinbutton
,
3454 Tab
*tab
=(Tab
*)user_data
;
3455 LttvTracesetContext
* tsc
=
3456 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3457 TimeInterval time_span
= tsc
->time_span
;
3458 gint value
= gtk_spin_button_get_value_as_int(spinbutton
);
3460 TimeWindow new_time_window
= tab
->time_window
;
3462 LttTime end_time
= new_time_window
.end_time
;
3464 new_time_window
.start_time
.tv_nsec
= value
;
3466 if(ltt_time_compare(new_time_window
.start_time
, end_time
) >= 0) {
3467 /* Then, we must push back end time : keep the same time width
3468 * if possible, else end traceset time */
3469 end_time
= LTT_TIME_MIN(ltt_time_add(new_time_window
.start_time
,
3470 new_time_window
.time_width
),
3471 time_span
.end_time
);
3474 /* Fix the time width to fit start time and end time */
3475 new_time_window
.time_width
= ltt_time_sub(end_time
,
3476 new_time_window
.start_time
);
3477 new_time_window
.time_width_double
=
3478 ltt_time_to_double(new_time_window
.time_width
);
3480 new_time_window
.end_time
= end_time
;
3482 time_change_manager(tab
, new_time_window
);
3487 on_MEntry3_value_changed (GtkSpinButton
*spinbutton
,
3490 Tab
*tab
=(Tab
*)user_data
;
3491 LttvTracesetContext
* tsc
=
3492 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3493 TimeInterval time_span
= tsc
->time_span
;
3494 gint value
= gtk_spin_button_get_value_as_int(spinbutton
);
3496 TimeWindow new_time_window
= tab
->time_window
;
3498 LttTime end_time
= new_time_window
.end_time
;
3500 end_time
.tv_sec
= value
;
3502 /* end nanoseconds */
3503 if(end_time
.tv_sec
== time_span
.start_time
.tv_sec
) {
3504 if(end_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3505 if(end_time
.tv_nsec
> time_span
.end_time
.tv_nsec
)
3506 end_time
.tv_nsec
= time_span
.end_time
.tv_nsec
;
3507 if(end_time
.tv_nsec
< time_span
.start_time
.tv_nsec
)
3508 end_time
.tv_nsec
= time_span
.start_time
.tv_nsec
+1;
3510 if(end_time
.tv_nsec
< time_span
.start_time
.tv_nsec
)
3511 end_time
.tv_nsec
= time_span
.start_time
.tv_nsec
+1;
3514 else if(end_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3515 if(end_time
.tv_nsec
> time_span
.end_time
.tv_nsec
)
3516 end_time
.tv_nsec
= time_span
.end_time
.tv_nsec
;
3519 if(ltt_time_compare(new_time_window
.start_time
, end_time
) >= 0) {
3520 /* Then, we must push front start time : keep the same time width
3521 * if possible, else end traceset time */
3522 new_time_window
.start_time
= LTT_TIME_MAX(
3523 ltt_time_sub(end_time
,
3524 new_time_window
.time_width
),
3525 time_span
.start_time
);
3528 /* Fix the time width to fit start time and end time */
3529 new_time_window
.time_width
= ltt_time_sub(end_time
,
3530 new_time_window
.start_time
);
3531 new_time_window
.time_width_double
=
3532 ltt_time_to_double(new_time_window
.time_width
);
3534 new_time_window
.end_time
= end_time
;
3536 time_change_manager(tab
, new_time_window
);
3541 on_MEntry4_value_changed (GtkSpinButton
*spinbutton
,
3544 Tab
*tab
=(Tab
*)user_data
;
3545 LttvTracesetContext
* tsc
=
3546 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3547 TimeInterval time_span
= tsc
->time_span
;
3548 gint value
= gtk_spin_button_get_value_as_int(spinbutton
);
3550 TimeWindow new_time_window
= tab
->time_window
;
3552 LttTime end_time
= new_time_window
.end_time
;
3554 end_time
.tv_nsec
= value
;
3556 if(ltt_time_compare(new_time_window
.start_time
, end_time
) >= 0) {
3557 /* Then, we must push front start time : keep the same time width
3558 * if possible, else end traceset time */
3559 new_time_window
.start_time
= LTT_TIME_MAX(
3560 ltt_time_sub(end_time
,
3561 new_time_window
.time_width
),
3562 time_span
.start_time
);
3565 /* Fix the time width to fit start time and end time */
3566 new_time_window
.time_width
= ltt_time_sub(end_time
,
3567 new_time_window
.start_time
);
3568 new_time_window
.time_width_double
=
3569 ltt_time_to_double(new_time_window
.time_width
);
3570 new_time_window
.end_time
= end_time
;
3572 time_change_manager(tab
, new_time_window
);
3577 void current_time_change_manager (Tab
*tab
,
3578 LttTime new_current_time
)
3580 /* Only one source of time change */
3581 if(tab
->current_time_manager_lock
== TRUE
) return;
3583 tab
->current_time_manager_lock
= TRUE
;
3585 LttvTracesetContext
*tsc
= LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3586 TimeInterval time_span
= tsc
->time_span
;
3588 /* current seconds */
3589 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry5
),
3590 (double)time_span
.start_time
.tv_sec
,
3591 (double)time_span
.end_time
.tv_sec
);
3592 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry5
),
3593 (double)new_current_time
.tv_sec
);
3596 /* start nanoseconds */
3597 if(new_current_time
.tv_sec
== time_span
.start_time
.tv_sec
) {
3598 /* can be both beginning and end at the same time. */
3599 if(new_current_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3600 /* If we are at the end, max nsec to end.. */
3601 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry6
),
3602 (double)time_span
.start_time
.tv_nsec
,
3603 (double)time_span
.end_time
.tv_nsec
);
3605 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry6
),
3606 (double)time_span
.start_time
.tv_nsec
,
3607 (double)NANOSECONDS_PER_SECOND
-1);
3609 } else if(new_current_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3610 /* If we are at the end, max nsec to end.. */
3611 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry6
),
3613 (double)time_span
.end_time
.tv_nsec
);
3614 } else /* anywhere else */
3615 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry6
),
3617 (double)NANOSECONDS_PER_SECOND
-1);
3619 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry6
),
3620 (double)new_current_time
.tv_nsec
);
3622 set_current_time(tab
, &new_current_time
);
3624 tab
->current_time_manager_lock
= FALSE
;
3628 on_MEntry5_value_changed (GtkSpinButton
*spinbutton
,
3631 Tab
*tab
= (Tab
*)user_data
;
3632 LttvTracesetContext
* tsc
=
3633 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3634 TimeInterval time_span
= tsc
->time_span
;
3635 gint value
= gtk_spin_button_get_value_as_int(spinbutton
);
3636 LttTime new_current_time
= tab
->current_time
;
3637 new_current_time
.tv_sec
= value
;
3639 /* current nanoseconds */
3640 if(new_current_time
.tv_sec
== time_span
.start_time
.tv_sec
) {
3641 if(new_current_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3642 if(new_current_time
.tv_nsec
> time_span
.end_time
.tv_nsec
)
3643 new_current_time
.tv_nsec
= time_span
.end_time
.tv_nsec
;
3644 if(new_current_time
.tv_nsec
< time_span
.start_time
.tv_nsec
)
3645 new_current_time
.tv_nsec
= time_span
.start_time
.tv_nsec
;
3647 if(new_current_time
.tv_nsec
< time_span
.start_time
.tv_nsec
)
3648 new_current_time
.tv_nsec
= time_span
.start_time
.tv_nsec
;
3651 else if(new_current_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3652 if(new_current_time
.tv_nsec
> time_span
.end_time
.tv_nsec
)
3653 new_current_time
.tv_nsec
= time_span
.end_time
.tv_nsec
;
3656 current_time_change_manager(tab
, new_current_time
);
3660 on_MEntry6_value_changed (GtkSpinButton
*spinbutton
,
3663 Tab
*tab
= (Tab
*)user_data
;
3664 gint value
= gtk_spin_button_get_value_as_int(spinbutton
);
3665 LttTime new_current_time
= tab
->current_time
;
3666 new_current_time
.tv_nsec
= value
;
3668 current_time_change_manager(tab
, new_current_time
);
3672 void scroll_value_changed_cb(GtkWidget
*scrollbar
,
3675 Tab
*tab
= (Tab
*)user_data
;
3676 TimeWindow new_time_window
;
3678 GtkAdjustment
*adjust
= gtk_range_get_adjustment(GTK_RANGE(scrollbar
));
3679 gdouble value
= gtk_adjustment_get_value(adjust
);
3680 // gdouble upper, lower, ratio, page_size;
3682 LttvTracesetContext
* tsc
=
3683 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3684 TimeInterval time_span
= tsc
->time_span
;
3686 time
= ltt_time_add(ltt_time_from_double(value
),
3687 time_span
.start_time
);
3689 new_time_window
.start_time
= time
;
3691 page_size
= adjust
->page_size
;
3693 new_time_window
.time_width
=
3694 ltt_time_from_double(page_size
);
3696 new_time_window
.time_width_double
=
3699 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
3700 new_time_window
.time_width
);
3703 time_change_manager(tab
, new_time_window
);
3705 //time_window = tab->time_window;
3707 lower
= adjust
->lower
;
3708 upper
= adjust
->upper
;
3709 ratio
= (value
- lower
) / (upper
- lower
);
3710 g_info("lower %lu, upper %lu, value %lu, ratio %lu", lower
, upper
, value
, ratio
);
3712 //time = ltt_time_sub(time_span->end_time, time_span->start_time);
3713 //time = ltt_time_mul(time, (float)ratio);
3714 //time = ltt_time_add(time_span->start_time, time);
3715 time
= ltt_time_add(ltt_time_from_double(value
),
3716 time_span
.start_time
);
3718 time_window
.start_time
= time
;
3720 page_size
= adjust
->page_size
;
3722 time_window
.time_width
=
3723 ltt_time_from_double(page_size
);
3724 //time = ltt_time_sub(time_span.end_time, time);
3725 //if(ltt_time_compare(time,time_window.time_width) < 0){
3726 // time_window.time_width = time;
3729 /* call viewer hooks for new time window */
3730 set_time_window(tab
, &time_window
);
3735 /* Display a dialogue showing all eventtypes and traces, let user to select the interested
3736 * eventtypes, tracefiles and traces (filter)
3739 /* Select a trace which will be removed from traceset
3742 char * get_remove_trace(char ** all_trace_name
, int nb_trace
)
3744 return get_selection(all_trace_name
, nb_trace
,
3745 "Select a trace", "Trace pathname");
3749 /* Select a module which will be loaded
3752 char * get_load_module(char ** load_module_name
, int nb_module
)
3754 return get_selection(load_module_name
, nb_module
,
3755 "Select a module to load", "Module name");
3761 /* Select a module which will be unloaded
3764 char * get_unload_module(char ** loaded_module_name
, int nb_module
)
3766 return get_selection(loaded_module_name
, nb_module
,
3767 "Select a module to unload", "Module name");
3771 /* Display a dialogue which shows all selectable items, let user to
3772 * select one of them
3775 char * get_selection(char ** loaded_module_name
, int nb_module
,
3776 char *title
, char * column_title
)
3778 GtkWidget
* dialogue
;
3779 GtkWidget
* scroll_win
;
3781 GtkListStore
* store
;
3782 GtkTreeViewColumn
* column
;
3783 GtkCellRenderer
* renderer
;
3784 GtkTreeSelection
* select
;
3787 char * unload_module_name
= NULL
;
3789 dialogue
= gtk_dialog_new_with_buttons(title
,
3792 GTK_STOCK_OK
,GTK_RESPONSE_ACCEPT
,
3793 GTK_STOCK_CANCEL
,GTK_RESPONSE_REJECT
,
3795 gtk_window_set_default_size((GtkWindow
*)dialogue
, 500, 200);
3797 scroll_win
= gtk_scrolled_window_new (NULL
, NULL
);
3798 gtk_widget_show ( scroll_win
);
3799 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll_win
),
3800 GTK_POLICY_AUTOMATIC
, GTK_POLICY_AUTOMATIC
);
3802 store
= gtk_list_store_new (N_COLUMNS
,G_TYPE_STRING
);
3803 tree
= gtk_tree_view_new_with_model(GTK_TREE_MODEL (store
));
3804 gtk_widget_show ( tree
);
3805 g_object_unref (G_OBJECT (store
));
3807 renderer
= gtk_cell_renderer_text_new ();
3808 column
= gtk_tree_view_column_new_with_attributes (column_title
,
3810 "text", MODULE_COLUMN
,
3812 gtk_tree_view_column_set_alignment (column
, 0.5);
3813 gtk_tree_view_column_set_fixed_width (column
, 150);
3814 gtk_tree_view_append_column (GTK_TREE_VIEW (tree
), column
);
3816 select
= gtk_tree_view_get_selection (GTK_TREE_VIEW (tree
));
3817 gtk_tree_selection_set_mode (select
, GTK_SELECTION_SINGLE
);
3819 gtk_container_add (GTK_CONTAINER (scroll_win
), tree
);
3821 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialogue
)->vbox
), scroll_win
,TRUE
, TRUE
,0);
3823 for(i
=0;i
<nb_module
;i
++){
3824 gtk_list_store_append (store
, &iter
);
3825 gtk_list_store_set (store
, &iter
, MODULE_COLUMN
,loaded_module_name
[i
],-1);
3828 id
= gtk_dialog_run(GTK_DIALOG(dialogue
));
3829 GtkTreeModel
**store_model
= (GtkTreeModel
**)&store
;
3831 case GTK_RESPONSE_ACCEPT
:
3832 case GTK_RESPONSE_OK
:
3833 if (gtk_tree_selection_get_selected (select
, store_model
, &iter
)){
3834 gtk_tree_model_get ((GtkTreeModel
*)store
, &iter
, MODULE_COLUMN
, &unload_module_name
, -1);
3836 case GTK_RESPONSE_REJECT
:
3837 case GTK_RESPONSE_CANCEL
:
3839 gtk_widget_destroy(dialogue
);
3843 return unload_module_name
;
3847 /* Insert all menu entry and tool buttons into this main window
3852 void add_all_menu_toolbar_constructors(MainWindow
* mw
, gpointer user_data
)
3856 lttvwindow_viewer_constructor constructor
;
3857 LttvMenus
* global_menu
, * instance_menu
;
3858 LttvToolbars
* global_toolbar
, * instance_toolbar
;
3859 LttvMenuClosure
*menu_item
;
3860 LttvToolbarClosure
*toolbar_item
;
3861 LttvAttributeValue value
;
3862 LttvIAttribute
*global_attributes
= LTTV_IATTRIBUTE(lttv_global_attributes());
3863 LttvIAttribute
*attributes
= mw
->attributes
;
3864 GtkWidget
* tool_menu_title_menu
, *new_widget
, *pixmap
;
3866 g_assert(lttv_iattribute_find_by_path(global_attributes
,
3867 "viewers/menu", LTTV_POINTER
, &value
));
3868 if(*(value
.v_pointer
) == NULL
)
3869 *(value
.v_pointer
) = lttv_menus_new();
3870 global_menu
= (LttvMenus
*)*(value
.v_pointer
);
3872 g_assert(lttv_iattribute_find_by_path(attributes
,
3873 "viewers/menu", LTTV_POINTER
, &value
));
3874 if(*(value
.v_pointer
) == NULL
)
3875 *(value
.v_pointer
) = lttv_menus_new();
3876 instance_menu
= (LttvMenus
*)*(value
.v_pointer
);
3880 g_assert(lttv_iattribute_find_by_path(global_attributes
,
3881 "viewers/toolbar", LTTV_POINTER
, &value
));
3882 if(*(value
.v_pointer
) == NULL
)
3883 *(value
.v_pointer
) = lttv_toolbars_new();
3884 global_toolbar
= (LttvToolbars
*)*(value
.v_pointer
);
3886 g_assert(lttv_iattribute_find_by_path(attributes
,
3887 "viewers/toolbar", LTTV_POINTER
, &value
));
3888 if(*(value
.v_pointer
) == NULL
)
3889 *(value
.v_pointer
) = lttv_toolbars_new();
3890 instance_toolbar
= (LttvToolbars
*)*(value
.v_pointer
);
3892 /* Add missing menu entries to window instance */
3893 for(i
=0;i
<global_menu
->len
;i
++) {
3894 menu_item
= &g_array_index(global_menu
, LttvMenuClosure
, i
);
3896 //add menu_item to window instance;
3897 constructor
= menu_item
->con
;
3898 tool_menu_title_menu
= lookup_widget(mw
->mwindow
,"ToolMenuTitle_menu");
3900 gtk_menu_item_new_with_mnemonic (menu_item
->menu_text
);
3901 gtk_container_add (GTK_CONTAINER (tool_menu_title_menu
),
3903 g_signal_connect ((gpointer
) new_widget
, "activate",
3904 G_CALLBACK (insert_viewer_wrap
),
3906 gtk_widget_show (new_widget
);
3907 lttv_menus_add(instance_menu
, menu_item
->con
,
3908 menu_item
->menu_path
,
3909 menu_item
->menu_text
,
3914 /* Add missing toolbar entries to window instance */
3915 for(i
=0;i
<global_toolbar
->len
;i
++) {
3916 toolbar_item
= &g_array_index(global_toolbar
, LttvToolbarClosure
, i
);
3918 //add toolbar_item to window instance;
3919 constructor
= toolbar_item
->con
;
3920 tool_menu_title_menu
= lookup_widget(mw
->mwindow
,"MToolbar1");
3921 pixbuf
= gdk_pixbuf_new_from_xpm_data((const char**)toolbar_item
->pixmap
);
3922 pixmap
= gtk_image_new_from_pixbuf(pixbuf
);
3924 gtk_toolbar_append_element (GTK_TOOLBAR (tool_menu_title_menu
),
3925 GTK_TOOLBAR_CHILD_BUTTON
,
3928 toolbar_item
->tooltip
, NULL
,
3929 pixmap
, NULL
, NULL
);
3930 gtk_label_set_use_underline(
3931 GTK_LABEL (((GtkToolbarChild
*) (
3932 g_list_last (GTK_TOOLBAR
3933 (tool_menu_title_menu
)->children
)->data
))->label
),
3935 gtk_container_set_border_width (GTK_CONTAINER (new_widget
), 1);
3936 g_signal_connect ((gpointer
) new_widget
,
3938 G_CALLBACK (insert_viewer_wrap
),
3940 gtk_widget_show (new_widget
);
3942 lttv_toolbars_add(instance_toolbar
, toolbar_item
->con
,
3943 toolbar_item
->tooltip
,
3944 toolbar_item
->pixmap
,
3952 /* Create a main window
3955 void construct_main_window(MainWindow
* parent
)
3957 g_debug("construct_main_window()");
3958 GtkWidget
* new_window
; /* New generated main window */
3959 MainWindow
* new_m_window
;/* New main window structure */
3960 GtkNotebook
* notebook
;
3961 LttvIAttribute
*attributes
=
3962 LTTV_IATTRIBUTE(g_object_new(LTTV_ATTRIBUTE_TYPE
, NULL
));
3963 LttvAttributeValue value
;
3966 new_m_window
= g_new(MainWindow
, 1);
3968 // Add the object's information to the module's array
3969 g_main_window_list
= g_slist_append(g_main_window_list
, new_m_window
);
3971 new_window
= create_MWindow();
3972 gtk_widget_show (new_window
);
3974 new_m_window
->mwindow
= new_window
;
3975 new_m_window
->attributes
= attributes
;
3977 g_assert(lttv_iattribute_find_by_path(attributes
,
3978 "viewers/menu", LTTV_POINTER
, &value
));
3979 *(value
.v_pointer
) = lttv_menus_new();
3981 g_assert(lttv_iattribute_find_by_path(attributes
,
3982 "viewers/toolbar", LTTV_POINTER
, &value
));
3983 *(value
.v_pointer
) = lttv_toolbars_new();
3985 add_all_menu_toolbar_constructors(new_m_window
, NULL
);
3987 g_object_set_data_full(G_OBJECT(new_window
),
3989 (gpointer
)new_m_window
,
3990 (GDestroyNotify
)g_free
);
3991 //create a default tab
3992 notebook
= (GtkNotebook
*)lookup_widget(new_m_window
->mwindow
, "MNotebook");
3993 if(notebook
== NULL
){
3994 g_info("Notebook does not exist\n");
3997 //gtk_notebook_popup_enable (GTK_NOTEBOOK(notebook));
3998 //for now there is no name field in LttvTraceset structure
3999 //Use "Traceset" as the label for the default tab
4001 GtkWidget
* parent_notebook
= lookup_widget(parent
->mwindow
, "MNotebook");
4002 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(parent_notebook
),
4003 gtk_notebook_get_current_page(GTK_NOTEBOOK(parent_notebook
)));
4009 parent_tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
4011 new_tab
= create_tab(new_m_window
, parent_tab
, notebook
, "Traceset");
4013 new_tab
= create_tab(new_m_window
, NULL
, notebook
, "Traceset");
4014 /* First window, use command line trace */
4015 if(g_init_trace
!= NULL
){
4016 lttvwindow_add_trace(new_tab
,
4020 LttvTraceset
*traceset
= new_tab
->traceset_info
->traceset
;
4021 SetTraceset(new_tab
, traceset
);
4023 /* Insert default viewers */
4025 LttvAttributeType type
;
4026 LttvAttributeName name
;
4027 LttvAttributeValue value
;
4028 LttvAttribute
*attribute
;
4030 LttvIAttribute
*attributes_global
=
4031 LTTV_IATTRIBUTE(lttv_global_attributes());
4033 g_assert(attribute
=
4034 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
4035 LTTV_IATTRIBUTE(attributes_global
),
4036 LTTV_VIEWER_CONSTRUCTORS
)));
4038 name
= g_quark_from_string("guievents");
4039 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
4041 if(type
== LTTV_POINTER
) {
4042 lttvwindow_viewer_constructor viewer_constructor
=
4043 (lttvwindow_viewer_constructor
)*value
.v_pointer
;
4044 insert_viewer(new_window
, viewer_constructor
);
4047 name
= g_quark_from_string("guicontrolflow");
4048 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
4050 if(type
== LTTV_POINTER
) {
4051 lttvwindow_viewer_constructor viewer_constructor
=
4052 (lttvwindow_viewer_constructor
)*value
.v_pointer
;
4053 insert_viewer(new_window
, viewer_constructor
);
4056 name
= g_quark_from_string("guistatistics");
4057 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
4059 if(type
== LTTV_POINTER
) {
4060 lttvwindow_viewer_constructor viewer_constructor
=
4061 (lttvwindow_viewer_constructor
)*value
.v_pointer
;
4062 insert_viewer(new_window
, viewer_constructor
);
4068 g_info("There are now : %d windows\n",g_slist_length(g_main_window_list
));
4072 /* Free the memory occupied by a tab structure
4076 void tab_destructor(Tab
* tab
)
4078 int i
, nb
, ref_count
;
4081 gtk_object_destroy(GTK_OBJECT(tab
->tooltips
));
4084 g_object_unref(tab
->attributes
);
4086 if(tab
->interrupted_state
)
4087 g_object_unref(tab
->interrupted_state
);
4090 if(tab
->traceset_info
->traceset_context
!= NULL
){
4091 //remove state update hooks
4092 lttv_state_remove_event_hooks(
4093 (LttvTracesetState
*)tab
->traceset_info
->
4095 lttv_context_fini(LTTV_TRACESET_CONTEXT(tab
->traceset_info
->
4097 g_object_unref(tab
->traceset_info
->traceset_context
);
4099 if(tab
->traceset_info
->traceset
!= NULL
) {
4100 nb
= lttv_traceset_number(tab
->traceset_info
->traceset
);
4101 for(i
= 0 ; i
< nb
; i
++) {
4102 trace
= lttv_traceset_get(tab
->traceset_info
->traceset
, i
);
4103 ref_count
= lttv_trace_get_ref_number(trace
);
4105 ltt_trace_close(lttv_trace(trace
));
4109 lttv_filter_destroy(tab
->filter
);
4110 lttv_traceset_destroy(tab
->traceset_info
->traceset
);
4111 /* Remove the idle events requests processing function of the tab */
4112 g_idle_remove_by_data(tab
);
4114 g_slist_free(tab
->events_requests
);
4115 g_free(tab
->traceset_info
);
4120 /* Create a tab and insert it into the current main window
4123 Tab
* create_tab(MainWindow
* mw
, Tab
*copy_tab
,
4124 GtkNotebook
* notebook
, char * label
)
4129 //create a new tab data structure
4132 //construct and initialize the traceset_info
4133 tab
->traceset_info
= g_new(TracesetInfo
,1);
4136 tab
->traceset_info
->traceset
=
4137 lttv_traceset_copy(copy_tab
->traceset_info
->traceset
);
4139 /* Copy the previous tab's filter */
4140 /* We can clone the filter, as we copy the trace set also */
4141 /* The filter must always be in sync with the trace set */
4142 tab
->filter
= lttv_filter_clone(copy_tab
->filter
);
4145 tab
->traceset_info
->traceset
= lttv_traceset_new();
4150 lttv_attribute_write_xml(
4151 lttv_traceset_attribute(tab
->traceset_info
->traceset
),
4157 tab
->time_manager_lock
= FALSE
;
4158 tab
->current_time_manager_lock
= FALSE
;
4160 //FIXME copy not implemented in lower level
4161 tab
->traceset_info
->traceset_context
=
4162 g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
4163 g_assert(tab
->traceset_info
->traceset_context
!= NULL
);
4165 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
),
4166 tab
->traceset_info
->traceset
);
4167 //add state update hooks
4168 lttv_state_add_event_hooks(
4169 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
4171 //determine the current_time and time_window of the tab
4173 if(copy_tab
!= NULL
){
4174 tab
->time_window
= copy_tab
->time_window
;
4175 tab
->current_time
= copy_tab
->current_time
;
4177 tab
->time_window
.start_time
=
4178 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
4179 time_span
.start_time
;
4180 if(DEFAULT_TIME_WIDTH_S
<
4181 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
4182 time_span
.end_time
.tv_sec
)
4183 tmp_time
.tv_sec
= DEFAULT_TIME_WIDTH_S
;
4186 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
4187 time_span
.end_time
.tv_sec
;
4188 tmp_time
.tv_nsec
= 0;
4189 tab
->time_window
.time_width
= tmp_time
;
4190 tab
->current_time
.tv_sec
=
4191 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
4192 time_span
.start_time
.tv_sec
;
4193 tab
->current_time
.tv_nsec
=
4194 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
4195 time_span
.start_time
.tv_nsec
;
4198 tab
->attributes
= LTTV_IATTRIBUTE(g_object_new(LTTV_ATTRIBUTE_TYPE
, NULL
));
4199 tab
->interrupted_state
= g_object_new(LTTV_ATTRIBUTE_TYPE
, NULL
);
4201 tab
->vbox
= gtk_vbox_new(FALSE
, 2);
4202 tab
->viewer_container
= gtk_vbox_new(TRUE
, 2);
4203 tab
->scrollbar
= gtk_hscrollbar_new(NULL
);
4204 //tab->multivpaned = gtk_multi_vpaned_new();
4206 gtk_box_pack_start(GTK_BOX(tab
->vbox
),
4207 tab
->viewer_container
,
4209 TRUE
, /* Give the extra space to the child */
4210 0); /* No padding */
4212 /* Create the timebar */
4214 tab
->MTimebar
= gtk_hbox_new(FALSE
, 2);
4215 gtk_widget_show(tab
->MTimebar
);
4216 tab
->tooltips
= gtk_tooltips_new();
4218 tab
->MEventBox1a
= gtk_event_box_new();
4219 gtk_widget_show(tab
->MEventBox1a
);
4220 gtk_tooltips_set_tip(tab
->tooltips
, tab
->MEventBox1a
,
4221 "Paste Start and End Times Here", "");
4222 tab
->MText1a
= gtk_label_new("Time Frame ");
4223 gtk_widget_show(tab
->MText1a
);
4224 gtk_container_add(GTK_CONTAINER(tab
->MEventBox1a
), tab
->MText1a
);
4225 tab
->MEventBox1b
= gtk_event_box_new();
4226 gtk_widget_show(tab
->MEventBox1b
);
4227 gtk_tooltips_set_tip(tab
->tooltips
, tab
->MEventBox1b
,
4228 "Paste Start Time Here", "");
4229 tab
->MText1b
= gtk_label_new("start: ");
4230 gtk_widget_show(tab
->MText1b
);
4231 gtk_container_add(GTK_CONTAINER(tab
->MEventBox1b
), tab
->MText1b
);
4232 tab
->MText2
= gtk_label_new("s");
4233 gtk_widget_show(tab
->MText2
);
4234 tab
->MText3a
= gtk_label_new("ns");
4235 gtk_widget_show(tab
->MText3a
);
4236 tab
->MEventBox3b
= gtk_event_box_new();
4237 gtk_widget_show(tab
->MEventBox3b
);
4238 gtk_tooltips_set_tip(tab
->tooltips
, tab
->MEventBox3b
,
4239 "Paste End Time Here", "");
4240 tab
->MText3b
= gtk_label_new("end:");
4241 gtk_widget_show(tab
->MText3b
);
4242 gtk_container_add(GTK_CONTAINER(tab
->MEventBox3b
), tab
->MText3b
);
4243 tab
->MText4
= gtk_label_new("s");
4244 gtk_widget_show(tab
->MText4
);
4245 tab
->MText5a
= gtk_label_new("ns");
4246 gtk_widget_show(tab
->MText5a
);
4247 tab
->MEventBox5b
= gtk_event_box_new();
4248 gtk_widget_show(tab
->MEventBox5b
);
4249 gtk_tooltips_set_tip(tab
->tooltips
, tab
->MEventBox5b
,
4250 "Paste Current Time Here", "");
4251 tab
->MText5b
= gtk_label_new("Current Time:");
4252 gtk_widget_show(tab
->MText5b
);
4253 gtk_container_add(GTK_CONTAINER(tab
->MEventBox5b
), tab
->MText5b
);
4254 tab
->MText6
= gtk_label_new("s");
4255 gtk_widget_show(tab
->MText6
);
4256 tab
->MText7
= gtk_label_new("ns");
4257 gtk_widget_show(tab
->MText7
);
4259 tab
->MEntry1
= gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4260 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab
->MEntry1
),0);
4261 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab
->MEntry1
),TRUE
);
4262 gtk_widget_show(tab
->MEntry1
);
4263 tab
->MEntry2
= gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4264 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab
->MEntry2
),0);
4265 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab
->MEntry2
),TRUE
);
4266 gtk_widget_show(tab
->MEntry2
);
4267 tab
->MEntry3
= gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4268 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab
->MEntry3
),0);
4269 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab
->MEntry3
),TRUE
);
4270 gtk_widget_show(tab
->MEntry3
);
4271 tab
->MEntry4
= gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4272 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab
->MEntry4
),0);
4273 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab
->MEntry4
),TRUE
);
4274 gtk_widget_show(tab
->MEntry4
);
4275 tab
->MEntry5
= gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4276 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab
->MEntry5
),0);
4277 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab
->MEntry5
),TRUE
);
4278 gtk_widget_show(tab
->MEntry5
);
4279 tab
->MEntry6
= gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4280 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab
->MEntry6
),0);
4281 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab
->MEntry6
),TRUE
);
4282 gtk_widget_show(tab
->MEntry6
);
4285 GtkWidget
*temp_widget
;
4287 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEventBox1a
, FALSE
,
4289 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEventBox1b
, FALSE
,
4291 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEntry1
, FALSE
, FALSE
, 0);
4292 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MText2
, FALSE
, FALSE
, 0);
4293 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEntry2
, FALSE
, FALSE
, 0);
4294 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MText3a
, FALSE
, FALSE
, 0);
4295 temp_widget
= gtk_vseparator_new();
4296 gtk_widget_show(temp_widget
);
4297 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), temp_widget
, FALSE
, FALSE
, 0);
4298 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEventBox3b
, FALSE
,
4300 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEntry3
, FALSE
, FALSE
, 0);
4301 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MText4
, FALSE
, FALSE
, 0);
4302 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEntry4
, FALSE
, FALSE
, 0);
4303 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MText5a
, FALSE
, FALSE
, 0);
4304 temp_widget
= gtk_vseparator_new();
4305 gtk_widget_show(temp_widget
);
4306 gtk_box_pack_end (GTK_BOX (tab
->MTimebar
), tab
->MText7
, FALSE
, FALSE
, 0);
4307 gtk_box_pack_end (GTK_BOX (tab
->MTimebar
), tab
->MEntry6
, FALSE
, FALSE
, 0);
4308 gtk_box_pack_end (GTK_BOX (tab
->MTimebar
), tab
->MText6
, FALSE
, FALSE
, 0);
4309 gtk_box_pack_end (GTK_BOX (tab
->MTimebar
), tab
->MEntry5
, FALSE
, FALSE
, 0);
4310 gtk_box_pack_end (GTK_BOX (tab
->MTimebar
), tab
->MEventBox5b
, FALSE
,
4312 gtk_box_pack_end (GTK_BOX (tab
->MTimebar
), temp_widget
, FALSE
, FALSE
, 0);
4315 //GtkWidget *test = gtk_button_new_with_label("drop");
4316 //gtk_button_set_relief(GTK_BUTTON(test), GTK_RELIEF_NONE);
4317 //gtk_widget_show(test);
4318 //gtk_box_pack_end(GTK_BOX (tab->MTimebar), test, FALSE, FALSE, 0);
4319 //gtk_widget_add_events(tab->MText1, GDK_ALL_EVENTS_MASK);//GDK_BUTTON_PRESS_MASK);
4320 /*GtkWidget *event_box = gtk_event_box_new();
4321 gtk_widget_show(event_box);
4322 gtk_tooltips_set_tip(tooltips, event_box,
4323 "Paste Current Time Here", "");
4324 gtk_box_pack_end(GTK_BOX (tab->MTimebar), event_box, FALSE, FALSE, 0);
4325 GtkWidget *test = gtk_label_new("drop");
4326 gtk_container_add(GTK_CONTAINER(event_box), test);
4327 gtk_widget_show(test);
4328 g_signal_connect (G_OBJECT(event_box),
4329 "button-press-event",
4330 G_CALLBACK (on_MText1_paste),
4334 g_signal_connect (G_OBJECT(tab
->MEventBox1a
),
4335 "button-press-event",
4336 G_CALLBACK (on_MEventBox1a_paste
),
4339 g_signal_connect (G_OBJECT(tab
->MEventBox1b
),
4340 "button-press-event",
4341 G_CALLBACK (on_MEventBox1b_paste
),
4343 g_signal_connect (G_OBJECT(tab
->MEventBox3b
),
4344 "button-press-event",
4345 G_CALLBACK (on_MEventBox3b_paste
),
4347 g_signal_connect (G_OBJECT(tab
->MEventBox5b
),
4348 "button-press-event",
4349 G_CALLBACK (on_MEventBox5b_paste
),
4353 gtk_box_pack_end(GTK_BOX(tab
->vbox
),
4355 FALSE
, /* Do not expand */
4356 FALSE
, /* Fill has no effect here (expand false) */
4357 0); /* No padding */
4359 gtk_box_pack_end(GTK_BOX(tab
->vbox
),
4361 FALSE
, /* Do not expand */
4362 FALSE
, /* Fill has no effect here (expand false) */
4363 0); /* No padding */
4365 g_object_set_data(G_OBJECT(tab
->viewer_container
), "focused_viewer", NULL
);
4371 // Display a label with a X
4372 GtkWidget *w_hbox = gtk_hbox_new(FALSE, 4);
4373 GtkWidget *w_label = gtk_label_new (label);
4374 GtkWidget *pixmap = create_pixmap(GTK_WIDGET(notebook), "close.png");
4375 GtkWidget *w_button = gtk_button_new ();
4376 gtk_container_add(GTK_CONTAINER(w_button), pixmap);
4377 //GtkWidget *w_button = gtk_button_new_with_label("x");
4379 gtk_button_set_relief(GTK_BUTTON(w_button), GTK_RELIEF_NONE);
4381 gtk_box_pack_start(GTK_BOX(w_hbox), w_label, TRUE, TRUE, 0);
4382 gtk_box_pack_end(GTK_BOX(w_hbox), w_button, FALSE,
4385 g_signal_connect_swapped (w_button, "clicked",
4386 G_CALLBACK (on_close_tab_X_clicked),
4389 gtk_widget_set_state(w_button, GTK_STATE_ACTIVE);
4391 gtk_widget_show (w_label);
4392 gtk_widget_show (pixmap);
4393 gtk_widget_show (w_button);
4394 gtk_widget_show (w_hbox);
4396 tab->label = w_hbox;
4400 tab
->label
= gtk_label_new (label
);
4402 gtk_widget_show(tab
->label
);
4403 gtk_widget_show(tab
->scrollbar
);
4404 gtk_widget_show(tab
->viewer_container
);
4405 gtk_widget_show(tab
->vbox
);
4406 //gtk_widget_show(tab->multivpaned);
4409 /* Start with empty events requests list */
4410 tab
->events_requests
= NULL
;
4411 tab
->events_request_pending
= FALSE
;
4413 g_object_set_data_full(
4414 G_OBJECT(tab
->vbox
),
4417 (GDestroyNotify
)tab_destructor
);
4419 g_signal_connect(G_OBJECT(tab
->scrollbar
), "value-changed",
4420 G_CALLBACK(scroll_value_changed_cb
), tab
);
4422 g_signal_connect ((gpointer
) tab
->MEntry1
, "value-changed",
4423 G_CALLBACK (on_MEntry1_value_changed
),
4425 g_signal_connect ((gpointer
) tab
->MEntry2
, "value-changed",
4426 G_CALLBACK (on_MEntry2_value_changed
),
4428 g_signal_connect ((gpointer
) tab
->MEntry3
, "value-changed",
4429 G_CALLBACK (on_MEntry3_value_changed
),
4431 g_signal_connect ((gpointer
) tab
->MEntry4
, "value-changed",
4432 G_CALLBACK (on_MEntry4_value_changed
),
4434 g_signal_connect ((gpointer
) tab
->MEntry5
, "value-changed",
4435 G_CALLBACK (on_MEntry5_value_changed
),
4437 g_signal_connect ((gpointer
) tab
->MEntry6
, "value-changed",
4438 G_CALLBACK (on_MEntry6_value_changed
),
4441 //g_signal_connect(G_OBJECT(tab->scrollbar), "changed",
4442 // G_CALLBACK(scroll_value_changed_cb), tab);
4445 //insert tab into notebook
4446 gtk_notebook_append_page(notebook
,
4449 list
= gtk_container_get_children(GTK_CONTAINER(notebook
));
4450 gtk_notebook_set_current_page(notebook
,g_list_length(list
)-1);
4451 // always show : not if(g_list_length(list)>1)
4452 gtk_notebook_set_show_tabs(notebook
, TRUE
);
4458 * execute_events_requests
4460 * Idle function that executes the pending requests for a tab.
4462 * @return return value : TRUE : keep the idle function, FALSE : remove it.
4464 gboolean
execute_events_requests(Tab
*tab
)
4466 return ( lttvwindow_process_pending_requests(tab
) );