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 lttv_process_traceset_synchronize_tracefiles(tsc
);
975 /* Events processing algorithm implementation */
976 /* Warning : the gtk_events_pending takes a LOT of cpu time. So what we do
977 * instead is to leave the control to GTK and take it back.
979 /* A. Servicing loop */
980 //while( (g_slist_length(list_in) != 0 || g_slist_length(list_out) != 0)) {
981 if((g_slist_length(list_in
) != 0 || g_slist_length(list_out
) != 0)) {
983 /* 1. If list_in is empty (need a seek) */
984 if( g_slist_length(list_in
) == 0 ) {
986 /* list in is empty, need a seek */
988 /* 1.1 Add requests to list_in */
989 GSList
*ltime
= NULL
;
993 /* 1.1.1 Find all time requests with the lowest start time in list_out
996 if(g_slist_length(list_out
) > 0)
997 ltime
= g_slist_append(ltime
, g_slist_nth_data(list_out
, 0));
998 for(iter
=g_slist_nth(list_out
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
999 /* Find all time requests with the lowest start time in list_out */
1000 EventsRequest
*event_request_ltime
= (EventsRequest
*)g_slist_nth_data(ltime
, 0);
1001 EventsRequest
*event_request_list_out
= (EventsRequest
*)iter
->data
;
1004 comp
= ltt_time_compare(event_request_ltime
->start_time
,
1005 event_request_list_out
->start_time
);
1007 ltime
= g_slist_append(ltime
, event_request_list_out
);
1009 /* Remove all elements from ltime, and add current */
1010 while(ltime
!= NULL
)
1011 ltime
= g_slist_delete_link(ltime
, g_slist_nth(ltime
, 0));
1012 ltime
= g_slist_append(ltime
, event_request_list_out
);
1016 /* 1.1.2 Find all position requests with the lowest position in list_out
1019 if(g_slist_length(list_out
) > 0)
1020 lpos
= g_slist_append(lpos
, g_slist_nth_data(list_out
, 0));
1021 for(iter
=g_slist_nth(list_out
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
1022 /* Find all position requests with the lowest position in list_out */
1023 EventsRequest
*event_request_lpos
= (EventsRequest
*)g_slist_nth_data(lpos
, 0);
1024 EventsRequest
*event_request_list_out
= (EventsRequest
*)iter
->data
;
1027 if(event_request_lpos
->start_position
!= NULL
1028 && event_request_list_out
->start_position
!= NULL
)
1030 comp
= lttv_traceset_context_pos_pos_compare
1031 (event_request_lpos
->start_position
,
1032 event_request_list_out
->start_position
);
1037 lpos
= g_slist_append(lpos
, event_request_list_out
);
1039 /* Remove all elements from lpos, and add current */
1041 lpos
= g_slist_delete_link(lpos
, g_slist_nth(lpos
, 0));
1042 lpos
= g_slist_append(lpos
, event_request_list_out
);
1047 EventsRequest
*event_request_lpos
= (EventsRequest
*)g_slist_nth_data(lpos
, 0);
1048 EventsRequest
*event_request_ltime
= (EventsRequest
*)g_slist_nth_data(ltime
, 0);
1049 LttTime lpos_start_time
;
1051 if(event_request_lpos
!= NULL
1052 && event_request_lpos
->start_position
!= NULL
) {
1053 lpos_start_time
= lttv_traceset_context_position_get_time(
1054 event_request_lpos
->start_position
);
1057 /* 1.1.3 If lpos.start time < ltime */
1058 if(event_request_lpos
!= NULL
1059 && event_request_lpos
->start_position
!= NULL
1060 && ltt_time_compare(lpos_start_time
,
1061 event_request_ltime
->start_time
)<0) {
1062 /* Add lpos to list_in, remove them from list_out */
1063 for(iter
=lpos
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
1064 /* Add to list_in */
1065 EventsRequest
*event_request_lpos
=
1066 (EventsRequest
*)iter
->data
;
1068 list_in
= g_slist_append(list_in
, event_request_lpos
);
1069 /* Remove from list_out */
1070 list_out
= g_slist_remove(list_out
, event_request_lpos
);
1073 /* 1.1.4 (lpos.start time >= ltime) */
1074 /* Add ltime to list_in, remove them from list_out */
1076 for(iter
=ltime
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
1077 /* Add to list_in */
1078 EventsRequest
*event_request_ltime
=
1079 (EventsRequest
*)iter
->data
;
1081 list_in
= g_slist_append(list_in
, event_request_ltime
);
1082 /* Remove from list_out */
1083 list_out
= g_slist_remove(list_out
, event_request_ltime
);
1088 g_slist_free(ltime
);
1093 tfc
= lttv_traceset_context_get_current_tfc(tsc
);
1094 g_assert(g_slist_length(list_in
)>0);
1095 EventsRequest
*events_request
= g_slist_nth_data(list_in
, 0);
1098 /* 1.2.1 If first request in list_in is a time request */
1099 if(events_request
->start_position
== NULL
) {
1100 /* - If first req in list_in start time != current time */
1101 if(tfc
== NULL
|| ltt_time_compare(events_request
->start_time
,
1102 tfc
->timestamp
) != 0)
1103 /* - Seek to that time */
1104 g_debug("SEEK TIME : %lu, %lu", events_request
->start_time
.tv_sec
,
1105 events_request
->start_time
.tv_nsec
);
1106 //lttv_process_traceset_seek_time(tsc, events_request->start_time);
1107 lttv_state_traceset_seek_time_closest(LTTV_TRACESET_STATE(tsc
),
1108 events_request
->start_time
);
1110 /* Process the traceset with only state hooks */
1112 lttv_process_traceset_middle(tsc
,
1113 events_request
->start_time
,
1119 /* Else, the first request in list_in is a position request */
1120 /* If first req in list_in pos != current pos */
1121 g_assert(events_request
->start_position
!= NULL
);
1122 g_debug("SEEK POS time : %lu, %lu",
1123 lttv_traceset_context_position_get_time(
1124 events_request
->start_position
).tv_sec
,
1125 lttv_traceset_context_position_get_time(
1126 events_request
->start_position
).tv_nsec
);
1128 g_debug("SEEK POS context time : %lu, %lu",
1129 lttv_traceset_context_get_current_tfc(tsc
)->timestamp
.tv_sec
,
1130 lttv_traceset_context_get_current_tfc(tsc
)->timestamp
.tv_nsec
);
1131 g_assert(events_request
->start_position
!= NULL
);
1132 if(lttv_traceset_context_ctx_pos_compare(tsc
,
1133 events_request
->start_position
) != 0) {
1134 /* 1.2.2.1 Seek to that position */
1135 g_debug("SEEK POSITION");
1136 //lttv_process_traceset_seek_position(tsc, events_request->start_position);
1137 pos_time
= lttv_traceset_context_position_get_time(
1138 events_request
->start_position
);
1140 lttv_state_traceset_seek_time_closest(LTTV_TRACESET_STATE(tsc
),
1143 /* Process the traceset with only state hooks */
1145 lttv_process_traceset_middle(tsc
,
1148 events_request
->start_position
);
1149 g_assert(lttv_traceset_context_ctx_pos_compare(tsc
,
1150 events_request
->start_position
) == 0);
1157 /* 1.3 Add hooks and call before request for all list_in members */
1159 GSList
*iter
= NULL
;
1161 for(iter
=list_in
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
1162 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1163 /* 1.3.1 If !servicing */
1164 if(events_request
->servicing
== FALSE
) {
1165 /* - begin request hooks called
1166 * - servicing = TRUE
1168 lttv_hooks_call(events_request
->before_request
, (gpointer
)tsc
);
1169 events_request
->servicing
= TRUE
;
1171 /* 1.3.2 call before chunk
1172 * 1.3.3 events hooks added
1174 if(events_request
->trace
== -1)
1175 lttv_process_traceset_begin(tsc
,
1176 events_request
->before_chunk_traceset
,
1177 events_request
->before_chunk_trace
,
1178 events_request
->before_chunk_tracefile
,
1179 events_request
->event
,
1180 events_request
->event_by_id
);
1182 guint nb_trace
= lttv_traceset_number(tsc
->ts
);
1183 g_assert((guint
)events_request
->trace
< nb_trace
&&
1184 events_request
->trace
> -1);
1185 LttvTraceContext
*tc
= tsc
->traces
[events_request
->trace
];
1187 lttv_hooks_call(events_request
->before_chunk_traceset
, tsc
);
1189 lttv_trace_context_add_hooks(tc
,
1190 events_request
->before_chunk_trace
,
1191 events_request
->before_chunk_tracefile
,
1192 events_request
->event
,
1193 events_request
->event_by_id
);
1198 /* 2. Else, list_in is not empty, we continue a read */
1201 /* 2.0 For each req of list_in */
1202 GSList
*iter
= list_in
;
1204 while(iter
!= NULL
) {
1206 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1208 /* - Call before chunk
1209 * - events hooks added
1211 if(events_request
->trace
== -1)
1212 lttv_process_traceset_begin(tsc
,
1213 events_request
->before_chunk_traceset
,
1214 events_request
->before_chunk_trace
,
1215 events_request
->before_chunk_tracefile
,
1216 events_request
->event
,
1217 events_request
->event_by_id
);
1219 guint nb_trace
= lttv_traceset_number(tsc
->ts
);
1220 g_assert((guint
)events_request
->trace
< nb_trace
&&
1221 events_request
->trace
> -1);
1222 LttvTraceContext
*tc
= tsc
->traces
[events_request
->trace
];
1224 lttv_hooks_call(events_request
->before_chunk_traceset
, tsc
);
1226 lttv_trace_context_add_hooks(tc
,
1227 events_request
->before_chunk_trace
,
1228 events_request
->before_chunk_tracefile
,
1229 events_request
->event
,
1230 events_request
->event_by_id
);
1233 iter
= g_slist_next(iter
);
1238 tfc
= lttv_traceset_context_get_current_tfc(tsc
);
1240 /* 2.1 For each req of list_out */
1241 GSList
*iter
= list_out
;
1243 while(iter
!= NULL
) {
1245 gboolean remove
= FALSE
;
1246 gboolean free_data
= FALSE
;
1247 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1249 /* if req.start time == current context time
1250 * or req.start position == current position*/
1251 if( ltt_time_compare(events_request
->start_time
,
1252 tfc
->timestamp
) == 0
1254 (events_request
->start_position
!= NULL
1256 lttv_traceset_context_ctx_pos_compare(tsc
,
1257 events_request
->start_position
) == 0)
1259 /* - Add to list_in, remove from list_out */
1260 list_in
= g_slist_append(list_in
, events_request
);
1264 /* - If !servicing */
1265 if(events_request
->servicing
== FALSE
) {
1266 /* - begin request hooks called
1267 * - servicing = TRUE
1269 lttv_hooks_call(events_request
->before_request
, (gpointer
)tsc
);
1270 events_request
->servicing
= TRUE
;
1272 /* call before chunk
1273 * events hooks added
1275 if(events_request
->trace
== -1)
1276 lttv_process_traceset_begin(tsc
,
1277 events_request
->before_chunk_traceset
,
1278 events_request
->before_chunk_trace
,
1279 events_request
->before_chunk_tracefile
,
1280 events_request
->event
,
1281 events_request
->event_by_id
);
1283 guint nb_trace
= lttv_traceset_number(tsc
->ts
);
1284 g_assert((guint
)events_request
->trace
< nb_trace
&&
1285 events_request
->trace
> -1);
1286 LttvTraceContext
*tc
= tsc
->traces
[events_request
->trace
];
1288 lttv_hooks_call(events_request
->before_chunk_traceset
, tsc
);
1290 lttv_trace_context_add_hooks(tc
,
1291 events_request
->before_chunk_trace
,
1292 events_request
->before_chunk_tracefile
,
1293 events_request
->event
,
1294 events_request
->event_by_id
);
1303 GSList
*remove_iter
= iter
;
1305 iter
= g_slist_next(iter
);
1306 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
1307 list_out
= g_slist_remove_link(list_out
, remove_iter
);
1308 } else { // not remove
1309 iter
= g_slist_next(iter
);
1315 /* 3. Find end criterions */
1320 /* 3.1.1 Find lowest end time in list_in */
1321 g_assert(g_slist_length(list_in
)>0);
1322 end_time
= ((EventsRequest
*)g_slist_nth_data(list_in
,0))->end_time
;
1324 for(iter
=g_slist_nth(list_in
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
1325 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1327 if(ltt_time_compare(events_request
->end_time
,
1329 end_time
= events_request
->end_time
;
1332 /* 3.1.2 Find lowest start time in list_out */
1333 for(iter
=list_out
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
1334 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1336 if(ltt_time_compare(events_request
->start_time
,
1338 end_time
= events_request
->start_time
;
1343 /* 3.2 Number of events */
1345 /* 3.2.1 Find lowest number of events in list_in */
1348 end_nb_events
= ((EventsRequest
*)g_slist_nth_data(list_in
,0))->num_events
;
1350 for(iter
=g_slist_nth(list_in
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
1351 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1353 if(events_request
->num_events
< end_nb_events
)
1354 end_nb_events
= events_request
->num_events
;
1357 /* 3.2.2 Use min(CHUNK_NUM_EVENTS, min num events in list_in) as
1360 end_nb_events
= MIN(CHUNK_NUM_EVENTS
, end_nb_events
);
1364 /* 3.3 End position */
1366 /* 3.3.1 Find lowest end position in list_in */
1369 end_position
=((EventsRequest
*)g_slist_nth_data(list_in
,0))->end_position
;
1371 for(iter
=g_slist_nth(list_in
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
1372 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1374 if(events_request
->end_position
!= NULL
&& end_position
!= NULL
&&
1375 lttv_traceset_context_pos_pos_compare(events_request
->end_position
,
1377 end_position
= events_request
->end_position
;
1382 /* 3.3.2 Find lowest start position in list_out */
1385 for(iter
=list_out
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
1386 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1388 if(events_request
->end_position
!= NULL
&& end_position
!= NULL
&&
1389 lttv_traceset_context_pos_pos_compare(events_request
->end_position
,
1391 end_position
= events_request
->end_position
;
1396 /* 4. Call process traceset middle */
1397 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
);
1398 count
= lttv_process_traceset_middle(tsc
, end_time
, end_nb_events
, end_position
);
1400 tfc
= lttv_traceset_context_get_current_tfc(tsc
);
1402 g_debug("Context time after middle : %lu, %lu", tfc
->timestamp
.tv_sec
,
1403 tfc
->timestamp
.tv_nsec
);
1405 g_debug("End of trace reached after middle.");
1409 /* 5. After process traceset middle */
1410 tfc
= lttv_traceset_context_get_current_tfc(tsc
);
1412 /* - if current context time > traceset.end time */
1413 if(tfc
== NULL
|| ltt_time_compare(tfc
->timestamp
,
1414 tsc
->time_span
.end_time
) > 0) {
1415 /* - For each req in list_in */
1416 GSList
*iter
= list_in
;
1418 while(iter
!= NULL
) {
1420 gboolean remove
= FALSE
;
1421 gboolean free_data
= FALSE
;
1422 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1424 /* - Remove events hooks for req
1425 * - Call end chunk for req
1428 if(events_request
->trace
== -1)
1429 lttv_process_traceset_end(tsc
,
1430 events_request
->after_chunk_traceset
,
1431 events_request
->after_chunk_trace
,
1432 events_request
->after_chunk_tracefile
,
1433 events_request
->event
,
1434 events_request
->event_by_id
);
1437 guint nb_trace
= lttv_traceset_number(tsc
->ts
);
1438 g_assert(events_request
->trace
< nb_trace
&&
1439 events_request
->trace
> -1);
1440 LttvTraceContext
*tc
= tsc
->traces
[events_request
->trace
];
1442 lttv_trace_context_remove_hooks(tc
,
1443 events_request
->after_chunk_trace
,
1444 events_request
->after_chunk_tracefile
,
1445 events_request
->event
,
1446 events_request
->event_by_id
);
1447 lttv_hooks_call(events_request
->after_chunk_traceset
, tsc
);
1452 /* - Call end request for req */
1453 lttv_hooks_call(events_request
->after_request
, (gpointer
)tsc
);
1455 /* - remove req from list_in */
1456 /* Destroy the request */
1463 GSList
*remove_iter
= iter
;
1465 iter
= g_slist_next(iter
);
1466 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
1467 list_in
= g_slist_remove_link(list_in
, remove_iter
);
1468 } else { // not remove
1469 iter
= g_slist_next(iter
);
1474 /* 5.1 For each req in list_in */
1475 GSList
*iter
= list_in
;
1477 while(iter
!= NULL
) {
1479 gboolean remove
= FALSE
;
1480 gboolean free_data
= FALSE
;
1481 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1483 /* - Remove events hooks for req
1484 * - Call end chunk for req
1486 if(events_request
->trace
== -1)
1487 lttv_process_traceset_end(tsc
,
1488 events_request
->after_chunk_traceset
,
1489 events_request
->after_chunk_trace
,
1490 events_request
->after_chunk_tracefile
,
1491 events_request
->event
,
1492 events_request
->event_by_id
);
1495 guint nb_trace
= lttv_traceset_number(tsc
->ts
);
1496 g_assert(events_request
->trace
< nb_trace
&&
1497 events_request
->trace
> -1);
1498 LttvTraceContext
*tc
= tsc
->traces
[events_request
->trace
];
1500 lttv_trace_context_remove_hooks(tc
,
1501 events_request
->after_chunk_trace
,
1502 events_request
->after_chunk_tracefile
,
1503 events_request
->event
,
1504 events_request
->event_by_id
);
1506 lttv_hooks_call(events_request
->after_chunk_traceset
, tsc
);
1509 /* - req.num -= count */
1510 g_assert(events_request
->num_events
>= count
);
1511 events_request
->num_events
-= count
;
1513 g_assert(tfc
!= NULL
);
1514 /* - if req.num == 0
1516 * current context time >= req.end time
1518 * req.end pos == current pos
1520 * req.stop_flag == TRUE
1522 if( events_request
->num_events
== 0
1524 events_request
->stop_flag
== TRUE
1526 ltt_time_compare(tfc
->timestamp
,
1527 events_request
->end_time
) >= 0
1529 (events_request
->end_position
!= NULL
1531 lttv_traceset_context_ctx_pos_compare(tsc
,
1532 events_request
->end_position
) == 0)
1535 g_assert(events_request
->servicing
== TRUE
);
1536 /* - Call end request for req
1537 * - remove req from list_in */
1538 lttv_hooks_call(events_request
->after_request
, (gpointer
)tsc
);
1539 /* - remove req from list_in */
1540 /* Destroy the request */
1548 GSList
*remove_iter
= iter
;
1550 iter
= g_slist_next(iter
);
1551 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
1552 list_in
= g_slist_remove_link(list_in
, remove_iter
);
1553 } else { // not remove
1554 iter
= g_slist_next(iter
);
1560 /* End of removed servicing loop : leave control to GTK instead. */
1561 // if(gtk_events_pending()) break;
1564 /* B. When interrupted between chunks */
1567 GSList
*iter
= list_in
;
1569 /* 1. for each request in list_in */
1570 while(iter
!= NULL
) {
1572 gboolean remove
= FALSE
;
1573 gboolean free_data
= FALSE
;
1574 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1576 /* 1.1. Use current postition as start position */
1577 if(events_request
->start_position
!= NULL
)
1578 lttv_traceset_context_position_destroy(events_request
->start_position
);
1579 events_request
->start_position
= lttv_traceset_context_position_new();
1580 lttv_traceset_context_position_save(tsc
, events_request
->start_position
);
1582 /* 1.2. Remove start time */
1583 events_request
->start_time
= ltt_time_infinite
;
1585 /* 1.3. Move from list_in to list_out */
1588 list_out
= g_slist_append(list_out
, events_request
);
1593 GSList
*remove_iter
= iter
;
1595 iter
= g_slist_next(iter
);
1596 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
1597 list_in
= g_slist_remove_link(list_in
, remove_iter
);
1598 } else { // not remove
1599 iter
= g_slist_next(iter
);
1606 /* C Unlock Traces */
1608 //lttv_process_traceset_get_sync_data(tsc);
1613 iter_trace
<lttv_traceset_number(tsc
->ts
);
1615 LttvTrace
*trace_v
= lttv_traceset_get(tsc
->ts
, iter_trace
);
1617 lttvwindowtraces_unlock(trace_v
);
1622 //set the cursor back to normal
1623 gdk_window_set_cursor(win
, NULL
);
1626 g_assert(g_slist_length(list_in
) == 0);
1628 if( g_slist_length(list_out
) == 0 ) {
1629 /* Put tab's request pending flag back to normal */
1630 tab
->events_request_pending
= FALSE
;
1631 g_debug("remove the idle fct");
1632 return FALSE
; /* Remove the idle function */
1634 g_debug("leave the idle fct");
1635 return TRUE
; /* Leave the idle function */
1637 /* We do not use simili-round-robin, it may require to read 1 meg buffers
1638 * again and again if many tracesets use the same tracefiles. */
1639 /* Hack for round-robin idle functions */
1640 /* It will put the idle function at the end of the pool */
1641 /*g_idle_add_full((G_PRIORITY_HIGH_IDLE + 21),
1642 (GSourceFunc)execute_events_requests,
1652 static void lttvwindow_add_trace(Tab
*tab
, LttvTrace
*trace_v
)
1654 LttvTraceset
*traceset
= tab
->traceset_info
->traceset
;
1656 guint num_traces
= lttv_traceset_number(traceset
);
1658 //Verify if trace is already present.
1659 for(i
=0; i
<num_traces
; i
++)
1661 LttvTrace
* trace
= lttv_traceset_get(traceset
, i
);
1662 if(trace
== trace_v
)
1666 //Keep a reference to the traces so they are not freed.
1667 for(i
=0; i
<lttv_traceset_number(traceset
); i
++)
1669 LttvTrace
* trace
= lttv_traceset_get(traceset
, i
);
1670 lttv_trace_ref(trace
);
1673 //remove state update hooks
1674 lttv_state_remove_event_hooks(
1675 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1677 lttv_context_fini(LTTV_TRACESET_CONTEXT(
1678 tab
->traceset_info
->traceset_context
));
1679 g_object_unref(tab
->traceset_info
->traceset_context
);
1681 lttv_traceset_add(traceset
, trace_v
);
1682 lttv_trace_ref(trace_v
); /* local ref */
1684 /* Create new context */
1685 tab
->traceset_info
->traceset_context
=
1686 g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
1688 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->
1693 //add state update hooks
1694 lttv_state_add_event_hooks(
1695 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1696 //Remove local reference to the traces.
1697 for(i
=0; i
<lttv_traceset_number(traceset
); i
++)
1699 LttvTrace
* trace
= lttv_traceset_get(traceset
, i
);
1700 lttv_trace_unref(trace
);
1704 //add_trace_into_traceset_selector(GTK_MULTIVPANED(tab->multivpaned), lttv_trace(trace_v));
1707 /* add_trace adds a trace into the current traceset. It first displays a
1708 * directory selection dialogue to let user choose a trace, then recreates
1709 * tracset_context, and redraws all the viewer of the current tab
1712 void add_trace(GtkWidget
* widget
, gpointer user_data
)
1715 LttvTrace
* trace_v
;
1716 LttvTraceset
* traceset
;
1718 char abs_path
[PATH_MAX
];
1720 MainWindow
* mw_data
= get_window_data_struct(widget
);
1721 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
1723 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
1724 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
1728 tab
= create_new_tab(widget
, NULL
);
1730 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
1733 GtkDirSelection
* file_selector
= (GtkDirSelection
*)gtk_dir_selection_new("Select a trace");
1734 gtk_dir_selection_hide_fileop_buttons(file_selector
);
1736 if(remember_trace_dir
[0] != '\0')
1737 gtk_dir_selection_set_filename(file_selector
, remember_trace_dir
);
1739 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
1741 case GTK_RESPONSE_ACCEPT
:
1742 case GTK_RESPONSE_OK
:
1743 dir
= gtk_dir_selection_get_dir (file_selector
);
1744 strncpy(remember_trace_dir
, dir
, PATH_MAX
);
1745 if(!dir
|| strlen(dir
) == 0){
1746 gtk_widget_destroy((GtkWidget
*)file_selector
);
1749 get_absolute_pathname(dir
, abs_path
);
1750 trace_v
= lttvwindowtraces_get_trace_by_name(abs_path
);
1751 if(trace_v
== NULL
) {
1752 trace
= ltt_trace_open(abs_path
);
1754 g_warning("cannot open trace %s", abs_path
);
1756 trace_v
= lttv_trace_new(trace
);
1757 lttvwindowtraces_add_trace(trace_v
);
1758 lttvwindow_add_trace(tab
, trace_v
);
1761 lttvwindow_add_trace(tab
, trace_v
);
1764 gtk_widget_destroy((GtkWidget
*)file_selector
);
1766 //update current tab
1767 //update_traceset(mw_data);
1769 /* Call the updatetraceset hooks */
1771 traceset
= tab
->traceset_info
->traceset
;
1772 SetTraceset(tab
, traceset
);
1773 // in expose now call_pending_read_hooks(mw_data);
1775 //lttvwindow_report_current_time(mw_data,&(tab->current_time));
1777 case GTK_RESPONSE_REJECT
:
1778 case GTK_RESPONSE_CANCEL
:
1780 gtk_widget_destroy((GtkWidget
*)file_selector
);
1785 /* remove_trace removes a trace from the current traceset if all viewers in
1786 * the current tab are not interested in the trace. It first displays a
1787 * dialogue, which shows all traces in the current traceset, to let user choose
1788 * a trace, then it checks if all viewers unselect the trace, if it is true,
1789 * it will remove the trace, recreate the traceset_contex,
1790 * and redraws all the viewer of the current tab. If there is on trace in the
1791 * current traceset, it will delete all viewers of the current tab
1793 * It destroys the filter tree. FIXME... we should request for an update
1797 void remove_trace(GtkWidget
*widget
, gpointer user_data
)
1800 LttvTrace
* trace_v
;
1801 LttvTraceset
* traceset
;
1802 gint i
, j
, nb_trace
, index
=-1;
1803 char ** name
, *remove_trace_name
;
1804 MainWindow
* mw_data
= get_window_data_struct(widget
);
1805 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
1807 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
1808 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
1814 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
1817 nb_trace
=lttv_traceset_number(tab
->traceset_info
->traceset
);
1818 name
= g_new(char*,nb_trace
);
1819 for(i
= 0; i
< nb_trace
; i
++){
1820 trace_v
= lttv_traceset_get(tab
->traceset_info
->traceset
, i
);
1821 trace
= lttv_trace(trace_v
);
1822 name
[i
] = ltt_trace_name(trace
);
1825 remove_trace_name
= get_remove_trace(name
, nb_trace
);
1828 if(remove_trace_name
){
1830 /* yuk, cut n paste from old code.. should be better (MD)*/
1831 for(i
= 0; i
<nb_trace
; i
++) {
1832 if(strcmp(remove_trace_name
,name
[i
]) == 0){
1837 traceset
= tab
->traceset_info
->traceset
;
1838 //Keep a reference to the traces so they are not freed.
1839 for(j
=0; j
<lttv_traceset_number(traceset
); j
++)
1841 LttvTrace
* trace
= lttv_traceset_get(traceset
, j
);
1842 lttv_trace_ref(trace
);
1845 //remove state update hooks
1846 lttv_state_remove_event_hooks(
1847 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1848 lttv_context_fini(LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
));
1849 g_object_unref(tab
->traceset_info
->traceset_context
);
1851 trace_v
= lttv_traceset_get(traceset
, index
);
1853 lttv_traceset_remove(traceset
, index
);
1854 lttv_trace_unref(trace_v
); // Remove local reference
1856 if(lttv_trace_get_ref_number(trace_v
) <= 1) {
1857 /* ref 1 : lttvwindowtraces only*/
1858 ltt_trace_close(lttv_trace(trace_v
));
1859 /* lttvwindowtraces_remove_trace takes care of destroying
1860 * the traceset linked with the trace_v and also of destroying
1861 * the trace_v at the same time.
1863 lttvwindowtraces_remove_trace(trace_v
);
1866 tab
->traceset_info
->traceset_context
=
1867 g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
1869 LTTV_TRACESET_CONTEXT(tab
->
1870 traceset_info
->traceset_context
),traceset
);
1871 //add state update hooks
1872 lttv_state_add_event_hooks(
1873 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1875 //Remove local reference to the traces.
1876 for(j
=0; j
<lttv_traceset_number(traceset
); j
++)
1878 LttvTrace
* trace
= lttv_traceset_get(traceset
, j
);
1879 lttv_trace_unref(trace
);
1882 SetTraceset(tab
, (gpointer
)traceset
);
1888 void remove_trace(GtkWidget
* widget
, gpointer user_data
)
1891 LttvTrace
* trace_v
;
1892 LttvTraceset
* traceset
;
1893 gint i
, j
, nb_trace
;
1894 char ** name
, *remove_trace_name
;
1895 MainWindow
* mw_data
= get_window_data_struct(widget
);
1896 LttvTracesetSelector
* s
;
1897 LttvTraceSelector
* t
;
1900 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
1902 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
1903 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
1909 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
1912 nb_trace
=lttv_traceset_number(tab
->traceset_info
->traceset
);
1913 name
= g_new(char*,nb_trace
);
1914 for(i
= 0; i
< nb_trace
; i
++){
1915 trace_v
= lttv_traceset_get(tab
->traceset_info
->traceset
, i
);
1916 trace
= lttv_trace(trace_v
);
1917 name
[i
] = ltt_trace_name(trace
);
1920 remove_trace_name
= get_remove_trace(name
, nb_trace
);
1922 if(remove_trace_name
){
1923 for(i
=0; i
<nb_trace
; i
++){
1924 if(strcmp(remove_trace_name
,name
[i
]) == 0){
1925 //unselect the trace from the current viewer
1927 w
= gtk_multivpaned_get_widget(GTK_MULTIVPANED(tab
->multivpaned
));
1929 s
= g_object_get_data(G_OBJECT(w
), "Traceset_Selector");
1931 t
= lttv_traceset_selector_trace_get(s
,i
);
1932 lttv_trace_selector_set_selected(t
, FALSE
);
1935 //check if other viewers select the trace
1936 w
= gtk_multivpaned_get_first_widget(GTK_MULTIVPANED(tab
->multivpaned
));
1938 s
= g_object_get_data(G_OBJECT(w
), "Traceset_Selector");
1940 t
= lttv_traceset_selector_trace_get(s
,i
);
1941 selected
= lttv_trace_selector_get_selected(t
);
1944 w
= gtk_multivpaned_get_next_widget(GTK_MULTIVPANED(tab
->multivpaned
));
1946 }else selected
= FALSE
;
1948 //if no viewer selects the trace, remove it
1950 remove_trace_from_traceset_selector(GTK_MULTIVPANED(tab
->multivpaned
), i
);
1952 traceset
= tab
->traceset_info
->traceset
;
1953 //Keep a reference to the traces so they are not freed.
1954 for(j
=0; j
<lttv_traceset_number(traceset
); j
++)
1956 LttvTrace
* trace
= lttv_traceset_get(traceset
, j
);
1957 lttv_trace_ref(trace
);
1960 //remove state update hooks
1961 lttv_state_remove_event_hooks(
1962 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1963 lttv_context_fini(LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
));
1964 g_object_unref(tab
->traceset_info
->traceset_context
);
1967 trace_v
= lttv_traceset_get(traceset
, i
);
1969 if(lttv_trace_get_ref_number(trace_v
) <= 2) {
1970 /* ref 2 : traceset, local */
1971 lttvwindowtraces_remove_trace(trace_v
);
1972 ltt_trace_close(lttv_trace(trace_v
));
1975 lttv_traceset_remove(traceset
, i
);
1976 lttv_trace_unref(trace_v
); // Remove local reference
1978 if(!lttv_trace_get_ref_number(trace_v
))
1979 lttv_trace_destroy(trace_v
);
1981 tab
->traceset_info
->traceset_context
=
1982 g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
1984 LTTV_TRACESET_CONTEXT(tab
->
1985 traceset_info
->traceset_context
),traceset
);
1986 //add state update hooks
1987 lttv_state_add_event_hooks(
1988 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1990 //Remove local reference to the traces.
1991 for(j
=0; j
<lttv_traceset_number(traceset
); j
++)
1993 LttvTrace
* trace
= lttv_traceset_get(traceset
, j
);
1994 lttv_trace_unref(trace
);
1998 //update current tab
1999 //update_traceset(mw_data);
2002 SetTraceset(tab
, (gpointer
)traceset
);
2003 // in expose now call_pending_read_hooks(mw_data);
2005 //lttvwindow_report_current_time(mw_data,&(tab->current_time));
2008 // while(tab->multi_vpaned->num_children){
2009 // gtk_multi_vpaned_widget_delete(tab->multi_vpaned);
2023 /* Redraw all the viewers in the current tab */
2024 void redraw(GtkWidget
*widget
, gpointer user_data
)
2026 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
2027 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2028 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2033 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
2037 LttvAttributeValue value
;
2039 g_assert(lttv_iattribute_find_by_path(tab
->attributes
, "hooks/redraw", LTTV_POINTER
, &value
));
2041 tmp
= (LttvHooks
*)*(value
.v_pointer
);
2043 lttv_hooks_call(tmp
,NULL
);
2047 void continue_processing(GtkWidget
*widget
, gpointer user_data
)
2049 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
2050 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2051 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2056 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
2060 LttvAttributeValue value
;
2062 g_assert(lttv_iattribute_find_by_path(tab
->attributes
,
2063 "hooks/continue", LTTV_POINTER
, &value
));
2065 tmp
= (LttvHooks
*)*(value
.v_pointer
);
2067 lttv_hooks_call(tmp
,NULL
);
2070 /* Stop the processing for the calling main window's current tab.
2071 * It removes every processing requests that are in its list. It does not call
2072 * the end request hooks, because the request is not finished.
2075 void stop_processing(GtkWidget
*widget
, gpointer user_data
)
2077 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
2078 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2079 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2084 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
2086 GSList
*iter
= tab
->events_requests
;
2088 while(iter
!= NULL
) {
2089 GSList
*remove_iter
= iter
;
2090 iter
= g_slist_next(iter
);
2092 g_free(remove_iter
->data
);
2093 tab
->events_requests
=
2094 g_slist_remove_link(tab
->events_requests
, remove_iter
);
2096 tab
->events_request_pending
= FALSE
;
2097 g_idle_remove_by_data(tab
);
2098 g_assert(g_slist_length(tab
->events_requests
) == 0);
2102 /* save will save the traceset to a file
2103 * Not implemented yet FIXME
2106 void save(GtkWidget
* widget
, gpointer user_data
)
2111 void save_as(GtkWidget
* widget
, gpointer user_data
)
2113 g_info("Save as\n");
2117 /* zoom will change the time_window of all the viewers of the
2118 * current tab, and redisplay them. The main functionality is to
2119 * determine the new time_window of the current tab
2122 void zoom(GtkWidget
* widget
, double size
)
2124 TimeInterval time_span
;
2125 TimeWindow new_time_window
;
2126 LttTime current_time
, time_delta
;
2127 MainWindow
* mw_data
= get_window_data_struct(widget
);
2128 LttvTracesetContext
*tsc
;
2129 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
2131 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2132 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2138 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
2141 if(size
== 1) return;
2143 tsc
= LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
2144 time_span
= tsc
->time_span
;
2145 new_time_window
= tab
->time_window
;
2146 current_time
= tab
->current_time
;
2148 time_delta
= ltt_time_sub(time_span
.end_time
,time_span
.start_time
);
2150 new_time_window
.start_time
= time_span
.start_time
;
2151 new_time_window
.time_width
= time_delta
;
2152 new_time_window
.time_width_double
= ltt_time_to_double(time_delta
);
2153 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
2154 new_time_window
.time_width
) ;
2156 new_time_window
.time_width
= ltt_time_div(new_time_window
.time_width
, size
);
2157 new_time_window
.time_width_double
=
2158 ltt_time_to_double(new_time_window
.time_width
);
2159 if(ltt_time_compare(new_time_window
.time_width
,time_delta
) > 0)
2160 { /* Case where zoom out is bigger than trace length */
2161 new_time_window
.start_time
= time_span
.start_time
;
2162 new_time_window
.time_width
= time_delta
;
2163 new_time_window
.time_width_double
= ltt_time_to_double(time_delta
);
2164 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
2165 new_time_window
.time_width
) ;
2169 /* Center the image on the current time */
2170 new_time_window
.start_time
=
2171 ltt_time_sub(current_time
,
2172 ltt_time_from_double(new_time_window
.time_width_double
/2.0));
2173 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
2174 new_time_window
.time_width
) ;
2175 /* If on borders, don't fall off */
2176 if(ltt_time_compare(new_time_window
.start_time
, time_span
.start_time
) <0)
2178 new_time_window
.start_time
= time_span
.start_time
;
2179 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
2180 new_time_window
.time_width
) ;
2184 if(ltt_time_compare(new_time_window
.end_time
,
2185 time_span
.end_time
) > 0)
2187 new_time_window
.start_time
=
2188 ltt_time_sub(time_span
.end_time
, new_time_window
.time_width
);
2190 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
2191 new_time_window
.time_width
) ;
2198 if(ltt_time_compare(new_time_window
.time_width
, ltt_time_zero
) == 0) {
2199 g_warning("Zoom more than 1 ns impossible");
2201 time_change_manager(tab
, new_time_window
);
2205 void zoom_in(GtkWidget
* widget
, gpointer user_data
)
2210 void zoom_out(GtkWidget
* widget
, gpointer user_data
)
2215 void zoom_extended(GtkWidget
* widget
, gpointer user_data
)
2220 void go_to_time(GtkWidget
* widget
, gpointer user_data
)
2222 g_info("Go to time\n");
2225 void show_time_frame(GtkWidget
* widget
, gpointer user_data
)
2227 g_info("Show time frame\n");
2231 /* callback function */
2234 on_empty_traceset_activate (GtkMenuItem
*menuitem
,
2237 create_new_window((GtkWidget
*)menuitem
, user_data
, FALSE
);
2242 on_clone_traceset_activate (GtkMenuItem
*menuitem
,
2245 create_new_window((GtkWidget
*)menuitem
, user_data
, TRUE
);
2249 /* create_new_tab calls create_tab to construct a new tab in the main window
2252 Tab
*create_new_tab(GtkWidget
* widget
, gpointer user_data
){
2253 gchar label
[PATH_MAX
];
2254 MainWindow
* mw_data
= get_window_data_struct(widget
);
2256 GtkNotebook
* notebook
= (GtkNotebook
*)lookup_widget(widget
, "MNotebook");
2257 if(notebook
== NULL
){
2258 g_info("Notebook does not exist\n");
2261 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2262 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2268 copy_tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
2271 strcpy(label
,"Page");
2272 if(get_label(mw_data
, label
,"Get the name of the tab","Please input tab's name"))
2273 return (create_tab (mw_data
, copy_tab
, notebook
, label
));
2279 on_tab_activate (GtkMenuItem
*menuitem
,
2282 create_new_tab((GtkWidget
*)menuitem
, user_data
);
2287 on_open_activate (GtkMenuItem
*menuitem
,
2290 open_traceset((GtkWidget
*)menuitem
, user_data
);
2295 on_close_activate (GtkMenuItem
*menuitem
,
2298 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2299 main_window_destructor(mw_data
);
2303 /* remove the current tab from the main window
2307 on_close_tab_activate (GtkWidget
*widget
,
2311 GtkWidget
* notebook
;
2313 MainWindow
* mw_data
= get_window_data_struct(widget
);
2314 notebook
= lookup_widget(widget
, "MNotebook");
2315 if(notebook
== NULL
){
2316 g_info("Notebook does not exist\n");
2320 page_num
= gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
));
2322 gtk_notebook_remove_page(GTK_NOTEBOOK(notebook
), page_num
);
2327 on_close_tab_X_clicked (GtkWidget
*widget
,
2331 GtkWidget
*notebook
= lookup_widget(widget
, "MNotebook");
2332 if(notebook
== NULL
){
2333 g_info("Notebook does not exist\n");
2337 if((page_num
= gtk_notebook_page_num(GTK_NOTEBOOK(notebook
), widget
)) != -1)
2338 gtk_notebook_remove_page(GTK_NOTEBOOK(notebook
), page_num
);
2344 on_add_trace_activate (GtkMenuItem
*menuitem
,
2347 add_trace((GtkWidget
*)menuitem
, user_data
);
2352 on_remove_trace_activate (GtkMenuItem
*menuitem
,
2355 remove_trace((GtkWidget
*)menuitem
, user_data
);
2360 on_save_activate (GtkMenuItem
*menuitem
,
2363 save((GtkWidget
*)menuitem
, user_data
);
2368 on_save_as_activate (GtkMenuItem
*menuitem
,
2371 save_as((GtkWidget
*)menuitem
, user_data
);
2376 on_quit_activate (GtkMenuItem
*menuitem
,
2384 on_cut_activate (GtkMenuItem
*menuitem
,
2392 on_copy_activate (GtkMenuItem
*menuitem
,
2400 on_paste_activate (GtkMenuItem
*menuitem
,
2408 on_delete_activate (GtkMenuItem
*menuitem
,
2416 on_zoom_in_activate (GtkMenuItem
*menuitem
,
2419 zoom_in((GtkWidget
*)menuitem
, user_data
);
2424 on_zoom_out_activate (GtkMenuItem
*menuitem
,
2427 zoom_out((GtkWidget
*)menuitem
, user_data
);
2432 on_zoom_extended_activate (GtkMenuItem
*menuitem
,
2435 zoom_extended((GtkWidget
*)menuitem
, user_data
);
2440 on_go_to_time_activate (GtkMenuItem
*menuitem
,
2443 go_to_time((GtkWidget
*)menuitem
, user_data
);
2448 on_show_time_frame_activate (GtkMenuItem
*menuitem
,
2451 show_time_frame((GtkWidget
*)menuitem
, user_data
);
2456 on_move_viewer_up_activate (GtkMenuItem
*menuitem
,
2459 move_up_viewer((GtkWidget
*)menuitem
, user_data
);
2464 on_move_viewer_down_activate (GtkMenuItem
*menuitem
,
2467 move_down_viewer((GtkWidget
*)menuitem
, user_data
);
2472 on_remove_viewer_activate (GtkMenuItem
*menuitem
,
2475 delete_viewer((GtkWidget
*)menuitem
, user_data
);
2479 on_trace_facility_activate (GtkMenuItem
*menuitem
,
2482 g_info("Trace facility selector: %s\n");
2486 /* Dispaly a file selection dialogue to let user select a library, then call
2487 * lttv_library_load().
2491 on_load_library_activate (GtkMenuItem
*menuitem
,
2494 GError
*error
= NULL
;
2495 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2497 gchar load_module_path_alter
[PATH_MAX
];
2501 gchar
*load_module_path
;
2502 name
= g_ptr_array_new();
2503 nb
= lttv_library_path_number();
2504 /* ask for the library path */
2508 path
= lttv_library_path_get(i
);
2509 g_ptr_array_add(name
, path
);
2512 load_module_path
= get_selection((char **)(name
->pdata
), name
->len
,
2513 "Select a library path", "Library paths");
2514 if(load_module_path
!= NULL
)
2515 strncpy(load_module_path_alter
, load_module_path
, PATH_MAX
-1); // -1 for /
2517 g_ptr_array_free(name
, TRUE
);
2519 if(load_module_path
== NULL
) return;
2523 /* Make sure the module path ends with a / */
2524 gchar
*ptr
= load_module_path_alter
;
2526 ptr
= strchr(ptr
, '\0');
2528 if(*(ptr
-1) != '/') {
2535 /* Ask for the library to load : list files in the previously selected
2537 gchar str
[PATH_MAX
];
2540 GtkFileSelection
* file_selector
=
2541 (GtkFileSelection
*)gtk_file_selection_new("Select a module");
2542 gtk_file_selection_set_filename(file_selector
, load_module_path_alter
);
2543 gtk_file_selection_hide_fileop_buttons(file_selector
);
2546 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
2548 case GTK_RESPONSE_ACCEPT
:
2549 case GTK_RESPONSE_OK
:
2550 dir
= gtk_file_selection_get_selections (file_selector
);
2551 strncpy(str
,dir
[0],PATH_MAX
);
2552 strncpy(remember_plugins_dir
,dir
[0],PATH_MAX
);
2553 /* only keep file name */
2555 str1
= strrchr(str
,'/');
2558 str1
= strrchr(str
,'\\');
2563 if(*str1
== 'l' && *(str1
+1)== 'i' && *(str1
+2)=='b')
2565 remove info after
. */
2569 str2
= strrchr(str2
, '.');
2570 if(str2
!= NULL
) *str2
= '\0';
2572 lttv_module_require(str1
, &error
);
2574 lttv_library_load(str1
, &error
);
2575 if(error
!= NULL
) g_warning("%s", error
->message
);
2576 else g_info("Load library: %s\n", str
);
2578 case GTK_RESPONSE_REJECT
:
2579 case GTK_RESPONSE_CANCEL
:
2581 gtk_widget_destroy((GtkWidget
*)file_selector
);
2592 /* Display all loaded modules, let user to select a module to unload
2593 * by calling lttv_module_unload
2597 on_unload_library_activate (GtkMenuItem
*menuitem
,
2600 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2602 LttvLibrary
*library
= NULL
;
2607 name
= g_ptr_array_new();
2608 nb
= lttv_library_number();
2609 LttvLibraryInfo
*lib_info
= g_new(LttvLibraryInfo
,nb
);
2610 /* ask for the library name */
2613 LttvLibrary
*iter_lib
= lttv_library_get(i
);
2614 lttv_library_info(iter_lib
, &lib_info
[i
]);
2616 gchar
*path
= lib_info
[i
].name
;
2617 g_ptr_array_add(name
, path
);
2619 lib_name
= get_selection((char **)(name
->pdata
), name
->len
,
2620 "Select a library", "Libraries");
2621 if(lib_name
!= NULL
) {
2623 if(strcmp(lib_name
, lib_info
[i
].name
) == 0) {
2624 library
= lttv_library_get(i
);
2629 g_ptr_array_free(name
, TRUE
);
2632 if(lib_name
== NULL
) return;
2634 if(library
!= NULL
) lttv_library_unload(library
);
2638 /* Dispaly a file selection dialogue to let user select a module, then call
2639 * lttv_module_require().
2643 on_load_module_activate (GtkMenuItem
*menuitem
,
2646 GError
*error
= NULL
;
2647 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2649 LttvLibrary
*library
= NULL
;
2654 name
= g_ptr_array_new();
2655 nb
= lttv_library_number();
2656 LttvLibraryInfo
*lib_info
= g_new(LttvLibraryInfo
,nb
);
2657 /* ask for the library name */
2660 LttvLibrary
*iter_lib
= lttv_library_get(i
);
2661 lttv_library_info(iter_lib
, &lib_info
[i
]);
2663 gchar
*path
= lib_info
[i
].name
;
2664 g_ptr_array_add(name
, path
);
2666 lib_name
= get_selection((char **)(name
->pdata
), name
->len
,
2667 "Select a library", "Libraries");
2668 if(lib_name
!= NULL
) {
2670 if(strcmp(lib_name
, lib_info
[i
].name
) == 0) {
2671 library
= lttv_library_get(i
);
2676 g_ptr_array_free(name
, TRUE
);
2679 if(lib_name
== NULL
) return;
2682 //LttvModule *module;
2683 gchar module_name_out
[PATH_MAX
];
2685 /* Ask for the module to load : list modules in the selected lib */
2689 nb
= lttv_library_module_number(library
);
2690 LttvModuleInfo
*module_info
= g_new(LttvModuleInfo
,nb
);
2691 name
= g_ptr_array_new();
2692 /* ask for the module name */
2695 LttvModule
*iter_module
= lttv_library_module_get(library
, i
);
2696 lttv_module_info(iter_module
, &module_info
[i
]);
2698 gchar
*path
= module_info
[i
].name
;
2699 g_ptr_array_add(name
, path
);
2701 module_name
= get_selection((char **)(name
->pdata
), name
->len
,
2702 "Select a module", "Modules");
2703 if(module_name
!= NULL
) {
2705 if(strcmp(module_name
, module_info
[i
].name
) == 0) {
2706 strncpy(module_name_out
, module_name
, PATH_MAX
);
2707 //module = lttv_library_module_get(i);
2713 g_ptr_array_free(name
, TRUE
);
2714 g_free(module_info
);
2716 if(module_name
== NULL
) return;
2719 lttv_module_require(module_name_out
, &error
);
2720 if(error
!= NULL
) g_warning("%s", error
->message
);
2721 else g_info("Load module: %s", module_name_out
);
2728 gchar str
[PATH_MAX
];
2731 GtkFileSelection
* file_selector
=
2732 (GtkFileSelection
*)gtk_file_selection_new("Select a module");
2733 gtk_file_selection_set_filename(file_selector
, load_module_path_alter
);
2734 gtk_file_selection_hide_fileop_buttons(file_selector
);
2737 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
2739 case GTK_RESPONSE_ACCEPT
:
2740 case GTK_RESPONSE_OK
:
2741 dir
= gtk_file_selection_get_selections (file_selector
);
2742 strncpy(str
,dir
[0],PATH_MAX
);
2743 strncpy(remember_plugins_dir
,dir
[0],PATH_MAX
);
2745 /* only keep file name */
2747 str1
= strrchr(str
,'/');
2750 str1
= strrchr(str
,'\\');
2755 if(*str1
== 'l' && *(str1
+1)== 'i' && *(str1
+2)=='b')
2757 remove info after
. */
2761 str2
= strrchr(str2
, '.');
2762 if(str2
!= NULL
) *str2
= '\0';
2764 lttv_module_require(str1
, &error
);
2766 lttv_library_load(str1
, &error
);
2767 if(error
!= NULL
) g_warning(error
->message
);
2768 else g_info("Load library: %s\n", str
);
2770 case GTK_RESPONSE_REJECT
:
2771 case GTK_RESPONSE_CANCEL
:
2773 gtk_widget_destroy((GtkWidget
*)file_selector
);
2785 /* Display all loaded modules, let user to select a module to unload
2786 * by calling lttv_module_unload
2790 on_unload_module_activate (GtkMenuItem
*menuitem
,
2793 GError
*error
= NULL
;
2794 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2796 LttvLibrary
*library
;
2801 name
= g_ptr_array_new();
2802 nb
= lttv_library_number();
2803 LttvLibraryInfo
*lib_info
= g_new(LttvLibraryInfo
,nb
);
2804 /* ask for the library name */
2807 LttvLibrary
*iter_lib
= lttv_library_get(i
);
2808 lttv_library_info(iter_lib
, &lib_info
[i
]);
2810 gchar
*path
= lib_info
[i
].name
;
2811 g_ptr_array_add(name
, path
);
2813 lib_name
= get_selection((char **)(name
->pdata
), name
->len
,
2814 "Select a library", "Libraries");
2815 if(lib_name
!= NULL
) {
2817 if(strcmp(lib_name
, lib_info
[i
].name
) == 0) {
2818 library
= lttv_library_get(i
);
2823 g_ptr_array_free(name
, TRUE
);
2826 if(lib_name
== NULL
) return;
2829 LttvModule
*module
= NULL
;
2831 /* Ask for the module to load : list modules in the selected lib */
2835 nb
= lttv_library_module_number(library
);
2836 LttvModuleInfo
*module_info
= g_new(LttvModuleInfo
,nb
);
2837 name
= g_ptr_array_new();
2838 /* ask for the module name */
2841 LttvModule
*iter_module
= lttv_library_module_get(library
, i
);
2842 lttv_module_info(iter_module
, &module_info
[i
]);
2844 gchar
*path
= module_info
[i
].name
;
2845 if(module_info
[i
].use_count
> 0) g_ptr_array_add(name
, path
);
2847 module_name
= get_selection((char **)(name
->pdata
), name
->len
,
2848 "Select a module", "Modules");
2849 if(module_name
!= NULL
) {
2851 if(strcmp(module_name
, module_info
[i
].name
) == 0) {
2852 module
= lttv_library_module_get(library
, i
);
2858 g_ptr_array_free(name
, TRUE
);
2859 g_free(module_info
);
2861 if(module_name
== NULL
) return;
2864 LttvModuleInfo module_info
;
2865 lttv_module_info(module
, &module_info
);
2866 g_info("Release module: %s\n", module_info
.name
);
2868 lttv_module_release(module
);
2872 /* Display a directory dialogue to let user select a path for library searching
2876 on_add_library_search_path_activate (GtkMenuItem
*menuitem
,
2879 GtkDirSelection
* file_selector
= (GtkDirSelection
*)gtk_dir_selection_new("Select library path");
2883 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2884 if(remember_plugins_dir
[0] != '\0')
2885 gtk_dir_selection_set_filename(file_selector
, remember_plugins_dir
);
2887 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
2889 case GTK_RESPONSE_ACCEPT
:
2890 case GTK_RESPONSE_OK
:
2891 dir
= gtk_dir_selection_get_dir (file_selector
);
2892 strncpy(remember_plugins_dir
,dir
,PATH_MAX
);
2893 strncat(remember_plugins_dir
,"/",PATH_MAX
);
2894 lttv_library_path_add(dir
);
2895 case GTK_RESPONSE_REJECT
:
2896 case GTK_RESPONSE_CANCEL
:
2898 gtk_widget_destroy((GtkWidget
*)file_selector
);
2904 /* Display a directory dialogue to let user select a path for library searching
2908 on_remove_library_search_path_activate (GtkMenuItem
*menuitem
,
2911 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2913 const char *lib_path
;
2918 name
= g_ptr_array_new();
2919 nb
= lttv_library_path_number();
2920 /* ask for the library name */
2923 gchar
*path
= lttv_library_path_get(i
);
2924 g_ptr_array_add(name
, path
);
2926 lib_path
= get_selection((char **)(name
->pdata
), name
->len
,
2927 "Select a library path", "Library paths");
2929 g_ptr_array_free(name
, TRUE
);
2931 if(lib_path
== NULL
) return;
2934 lttv_library_path_remove(lib_path
);
2938 on_color_activate (GtkMenuItem
*menuitem
,
2946 on_save_configuration_activate (GtkMenuItem
*menuitem
,
2949 g_info("Save configuration\n");
2954 on_content_activate (GtkMenuItem
*menuitem
,
2957 g_info("Content\n");
2962 on_about_close_activate (GtkButton
*button
,
2965 GtkWidget
*about_widget
= GTK_WIDGET(user_data
);
2967 gtk_widget_destroy(about_widget
);
2971 on_about_activate (GtkMenuItem
*menuitem
,
2974 MainWindow
*main_window
= get_window_data_struct(GTK_WIDGET(menuitem
));
2975 GtkWidget
*window_widget
= main_window
->mwindow
;
2976 GtkWidget
*about_widget
= gtk_window_new(GTK_WINDOW_TOPLEVEL
);
2977 GtkWindow
*about_window
= GTK_WINDOW(about_widget
);
2978 gint window_width
, window_height
;
2980 gtk_window_set_title(about_window
, "About Linux Trace Toolkit");
2982 gtk_window_set_resizable(about_window
, FALSE
);
2983 gtk_window_set_transient_for(GTK_WINDOW(window_widget
), about_window
);
2984 gtk_window_set_destroy_with_parent(about_window
, TRUE
);
2985 gtk_window_set_modal(about_window
, FALSE
);
2987 /* Put the about window at the center of the screen */
2988 gtk_window_get_size(about_window
, &window_width
, &window_height
);
2989 gtk_window_move (about_window
,
2990 (gdk_screen_width() - window_width
)/2,
2991 (gdk_screen_height() - window_height
)/2);
2993 GtkWidget
*vbox
= gtk_vbox_new(FALSE
, 1);
2995 gtk_container_add(GTK_CONTAINER(about_widget
), vbox
);
2999 GtkWidget
*label1
= gtk_label_new("");
3000 gtk_misc_set_padding(GTK_MISC(label1
), 10, 20);
3001 gtk_label_set_markup(GTK_LABEL(label1
), "\
3002 <big>Linux Trace Toolkit</big>");
3003 gtk_label_set_justify(GTK_LABEL(label1
), GTK_JUSTIFY_CENTER
);
3005 GtkWidget
*label2
= gtk_label_new("");
3006 gtk_misc_set_padding(GTK_MISC(label2
), 10, 20);
3007 gtk_label_set_markup(GTK_LABEL(label2
), "\
3010 Michel Dagenais (New trace format, lttv main)\n\
3011 Mathieu Desnoyers (Directory structure, build with automake/conf,\n\
3012 lttv gui, control flow view, gui cooperative trace reading\n\
3013 scheduler with interruptible foreground and background\n\
3014 computation, detailed event list)\n\
3015 Benoit Des Ligneris, Eric Clement (Cluster adaptation, work in progress)\n\
3016 Xang-Xiu Yang (new trace reading library and converter, lttv gui, \n\
3017 detailed event list and statistics view)\n\
3018 Tom Zanussi (RelayFS)\n\
3020 Strongly inspired from the original Linux Trace Toolkit Visualizer made by\n\
3023 GtkWidget
*label3
= gtk_label_new("");
3024 gtk_label_set_markup(GTK_LABEL(label3
), "\
3025 Linux Trace Toolkit Viewer, Copyright (C) 2004\n\
3027 Mathieu Desnoyers\n\
3029 Linux Trace Toolkit comes with ABSOLUTELY NO WARRANTY.\n\
3030 This is free software, and you are welcome to redistribute it\n\
3031 under certain conditions. See COPYING for details.");
3032 gtk_misc_set_padding(GTK_MISC(label3
), 10, 20);
3034 gtk_box_pack_start_defaults(GTK_BOX(vbox
), label1
);
3035 gtk_box_pack_start_defaults(GTK_BOX(vbox
), label2
);
3036 gtk_box_pack_start_defaults(GTK_BOX(vbox
), label3
);
3038 GtkWidget
*hbox
= gtk_hbox_new(TRUE
, 0);
3039 gtk_box_pack_end(GTK_BOX(vbox
), hbox
, FALSE
, FALSE
, 0);
3040 GtkWidget
*close_button
= gtk_button_new_with_mnemonic("_Close");
3041 gtk_box_pack_end(GTK_BOX(hbox
), close_button
, FALSE
, FALSE
, 0);
3042 gtk_container_set_border_width(GTK_CONTAINER(close_button
), 20);
3044 g_signal_connect(G_OBJECT(close_button
), "clicked",
3045 G_CALLBACK(on_about_close_activate
),
3046 (gpointer
)about_widget
);
3048 gtk_widget_show_all(about_widget
);
3053 on_button_new_clicked (GtkButton
*button
,
3056 create_new_window((GtkWidget
*)button
, user_data
, TRUE
);
3060 on_button_new_tab_clicked (GtkButton
*button
,
3063 create_new_tab((GtkWidget
*)button
, user_data
);
3067 on_button_open_clicked (GtkButton
*button
,
3070 open_traceset((GtkWidget
*)button
, user_data
);
3075 on_button_add_trace_clicked (GtkButton
*button
,
3078 add_trace((GtkWidget
*)button
, user_data
);
3083 on_button_remove_trace_clicked (GtkButton
*button
,
3086 remove_trace((GtkWidget
*)button
, user_data
);
3090 on_button_redraw_clicked (GtkButton
*button
,
3093 redraw((GtkWidget
*)button
, user_data
);
3097 on_button_continue_processing_clicked (GtkButton
*button
,
3100 continue_processing((GtkWidget
*)button
, user_data
);
3104 on_button_stop_processing_clicked (GtkButton
*button
,
3107 stop_processing((GtkWidget
*)button
, user_data
);
3113 on_button_save_clicked (GtkButton
*button
,
3116 save((GtkWidget
*)button
, user_data
);
3121 on_button_save_as_clicked (GtkButton
*button
,
3124 save_as((GtkWidget
*)button
, user_data
);
3129 on_button_zoom_in_clicked (GtkButton
*button
,
3132 zoom_in((GtkWidget
*)button
, user_data
);
3137 on_button_zoom_out_clicked (GtkButton
*button
,
3140 zoom_out((GtkWidget
*)button
, user_data
);
3145 on_button_zoom_extended_clicked (GtkButton
*button
,
3148 zoom_extended((GtkWidget
*)button
, user_data
);
3153 on_button_go_to_time_clicked (GtkButton
*button
,
3156 go_to_time((GtkWidget
*)button
, user_data
);
3161 on_button_show_time_frame_clicked (GtkButton
*button
,
3164 show_time_frame((GtkWidget
*)button
, user_data
);
3169 on_button_move_up_clicked (GtkButton
*button
,
3172 move_up_viewer((GtkWidget
*)button
, user_data
);
3177 on_button_move_down_clicked (GtkButton
*button
,
3180 move_down_viewer((GtkWidget
*)button
, user_data
);
3185 on_button_delete_viewer_clicked (GtkButton
*button
,
3188 delete_viewer((GtkWidget
*)button
, user_data
);
3192 on_MWindow_destroy (GtkWidget
*widget
,
3195 MainWindow
*main_window
= get_window_data_struct(widget
);
3196 LttvIAttribute
*attributes
= main_window
->attributes
;
3197 LttvAttributeValue value
;
3199 //This is unnecessary, since widgets will be destroyed
3200 //by the main window widget anyway.
3201 //remove_all_menu_toolbar_constructors(main_window, NULL);
3203 g_assert(lttv_iattribute_find_by_path(attributes
,
3204 "viewers/menu", LTTV_POINTER
, &value
));
3205 lttv_menus_destroy((LttvMenus
*)*(value
.v_pointer
));
3207 g_assert(lttv_iattribute_find_by_path(attributes
,
3208 "viewers/toolbar", LTTV_POINTER
, &value
));
3209 lttv_toolbars_destroy((LttvToolbars
*)*(value
.v_pointer
));
3211 g_object_unref(main_window
->attributes
);
3212 g_main_window_list
= g_slist_remove(g_main_window_list
, main_window
);
3214 g_info("There are now : %d windows\n",g_slist_length(g_main_window_list
));
3215 if(g_slist_length(g_main_window_list
) == 0)
3220 on_MWindow_configure (GtkWidget
*widget
,
3221 GdkEventConfigure
*event
,
3224 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)widget
);
3226 // MD : removed time width modification upon resizing of the main window.
3227 // The viewers will redraw themselves completely, without time interval
3230 if(mw_data->window_width){
3231 time_span = LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context)->Time_Span ;
3232 time_win = tab->time_window;
3233 ratio = width / mw_data->window_width;
3234 tab->time_window.time_width = ltt_time_mul(time_win.time_width,ratio);
3235 time = ltt_time_sub(time_span->endTime, time_win.start_time);
3236 if(ltt_time_compare(time, tab->time_window.time_width) < 0){
3237 tab->time_window.time_width = time;
3243 mw_data->window_width = (int)width;
3252 on_MNotebook_switch_page (GtkNotebook
*notebook
,
3253 GtkNotebookPage
*page
,
3261 void time_change_manager (Tab
*tab
,
3262 TimeWindow new_time_window
)
3264 /* Only one source of time change */
3265 if(tab
->time_manager_lock
== TRUE
) return;
3267 tab
->time_manager_lock
= TRUE
;
3269 LttvTracesetContext
*tsc
= LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3270 TimeInterval time_span
= tsc
->time_span
;
3271 LttTime start_time
= new_time_window
.start_time
;
3272 LttTime end_time
= new_time_window
.end_time
;
3275 GtkAdjustment
*adjustment
= gtk_range_get_adjustment(GTK_RANGE(tab
->scrollbar
));
3276 LttTime upper
= ltt_time_sub(time_span
.end_time
, time_span
.start_time
);
3278 gtk_range_set_increments(GTK_RANGE(tab
->scrollbar
),
3279 ltt_time_to_double(new_time_window
.time_width
)
3280 / SCROLL_STEP_PER_PAGE
3281 * NANOSECONDS_PER_SECOND
, /* step increment */
3282 ltt_time_to_double(new_time_window
.time_width
)
3283 * NANOSECONDS_PER_SECOND
); /* page increment */
3284 gtk_range_set_range(GTK_RANGE(tab
->scrollbar
),
3286 ltt_time_to_double(upper
)
3287 * NANOSECONDS_PER_SECOND
); /* upper */
3289 g_object_set(G_OBJECT(adjustment
),
3293 ltt_time_to_double(upper
), /* upper */
3295 new_time_window
.time_width_double
3296 / SCROLL_STEP_PER_PAGE
, /* step increment */
3298 new_time_window
.time_width_double
,
3299 /* page increment */
3301 new_time_window
.time_width_double
, /* page size */
3303 gtk_adjustment_changed(adjustment
);
3305 // g_object_set(G_OBJECT(adjustment),
3307 // ltt_time_to_double(
3308 // ltt_time_sub(start_time, time_span.start_time))
3311 //gtk_adjustment_value_changed(adjustment);
3312 gtk_range_set_value(GTK_RANGE(tab
->scrollbar
),
3314 ltt_time_sub(start_time
, time_span
.start_time
)) /* value */);
3316 /* set the time bar. */
3318 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry1
),
3319 (double)time_span
.start_time
.tv_sec
,
3320 (double)time_span
.end_time
.tv_sec
);
3321 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry1
),
3322 (double)start_time
.tv_sec
);
3324 /* start nanoseconds */
3325 if(start_time
.tv_sec
== time_span
.start_time
.tv_sec
) {
3326 /* can be both beginning and end at the same time. */
3327 if(start_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3328 /* If we are at the end, max nsec to end.. -1 (not zero length) */
3329 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry2
),
3330 (double)time_span
.start_time
.tv_nsec
,
3331 (double)time_span
.end_time
.tv_nsec
-1);
3333 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry2
),
3334 (double)time_span
.start_time
.tv_nsec
,
3335 (double)NANOSECONDS_PER_SECOND
-1);
3337 } else if(start_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3338 /* If we are at the end, max nsec to end.. -1 (not zero length) */
3339 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry2
),
3341 (double)time_span
.end_time
.tv_nsec
-1);
3342 } else /* anywhere else */
3343 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry2
),
3345 (double)NANOSECONDS_PER_SECOND
-1);
3346 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry2
),
3347 (double)start_time
.tv_nsec
);
3350 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry3
),
3351 (double)time_span
.start_time
.tv_sec
,
3352 (double)time_span
.end_time
.tv_sec
);
3353 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry3
),
3354 (double)end_time
.tv_sec
);
3356 /* end nanoseconds */
3357 if(end_time
.tv_sec
== time_span
.start_time
.tv_sec
) {
3358 /* can be both beginning and end at the same time. */
3359 if(end_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3360 /* If we are at the end, max nsec to end.. */
3361 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry4
),
3362 (double)time_span
.start_time
.tv_nsec
+1,
3363 (double)time_span
.end_time
.tv_nsec
);
3365 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry4
),
3366 (double)time_span
.start_time
.tv_nsec
+1,
3367 (double)NANOSECONDS_PER_SECOND
-1);
3370 else if(end_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3371 /* If we are at the end, max nsec to end.. */
3372 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry4
),
3374 (double)time_span
.end_time
.tv_nsec
);
3376 else /* anywhere else */
3377 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry4
),
3379 (double)NANOSECONDS_PER_SECOND
-1);
3380 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry4
),
3381 (double)end_time
.tv_nsec
);
3383 /* call viewer hooks for new time window */
3384 set_time_window(tab
, &new_time_window
);
3386 tab
->time_manager_lock
= FALSE
;
3390 /* value changed for frame start s
3392 * Check time span : if ns is out of range, clip it the nearest good value.
3395 on_MEntry1_value_changed (GtkSpinButton
*spinbutton
,
3398 Tab
*tab
=(Tab
*)user_data
;
3399 LttvTracesetContext
* tsc
=
3400 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3401 TimeInterval time_span
= tsc
->time_span
;
3402 gint value
= gtk_spin_button_get_value_as_int(spinbutton
);
3404 TimeWindow new_time_window
= tab
->time_window
;
3406 LttTime end_time
= new_time_window
.end_time
;
3408 new_time_window
.start_time
.tv_sec
= value
;
3410 /* start nanoseconds */
3411 if(new_time_window
.start_time
.tv_sec
== time_span
.start_time
.tv_sec
) {
3412 if(new_time_window
.start_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3413 if(new_time_window
.start_time
.tv_nsec
> time_span
.end_time
.tv_nsec
)
3414 new_time_window
.start_time
.tv_nsec
= time_span
.end_time
.tv_nsec
-1;
3415 if(new_time_window
.start_time
.tv_nsec
< time_span
.start_time
.tv_nsec
)
3416 new_time_window
.start_time
.tv_nsec
= time_span
.start_time
.tv_nsec
;
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
;
3422 else if(new_time_window
.start_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3423 if(new_time_window
.start_time
.tv_nsec
> time_span
.end_time
.tv_nsec
)
3424 new_time_window
.start_time
.tv_nsec
= time_span
.end_time
.tv_nsec
-1;
3427 if(ltt_time_compare(new_time_window
.start_time
, end_time
) >= 0) {
3428 /* Then, we must push back end time : keep the same time width
3429 * if possible, else end traceset time */
3430 end_time
= LTT_TIME_MIN(ltt_time_add(new_time_window
.start_time
,
3431 new_time_window
.time_width
),
3432 time_span
.end_time
);
3435 /* Fix the time width to fit start time and end time */
3436 new_time_window
.time_width
= ltt_time_sub(end_time
,
3437 new_time_window
.start_time
);
3438 new_time_window
.time_width_double
=
3439 ltt_time_to_double(new_time_window
.time_width
);
3441 new_time_window
.end_time
= end_time
;
3443 time_change_manager(tab
, new_time_window
);
3448 on_MEntry2_value_changed (GtkSpinButton
*spinbutton
,
3451 Tab
*tab
=(Tab
*)user_data
;
3452 LttvTracesetContext
* tsc
=
3453 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3454 TimeInterval time_span
= tsc
->time_span
;
3455 gint value
= gtk_spin_button_get_value_as_int(spinbutton
);
3457 TimeWindow new_time_window
= tab
->time_window
;
3459 LttTime end_time
= new_time_window
.end_time
;
3461 new_time_window
.start_time
.tv_nsec
= value
;
3463 if(ltt_time_compare(new_time_window
.start_time
, end_time
) >= 0) {
3464 /* Then, we must push back end time : keep the same time width
3465 * if possible, else end traceset time */
3466 end_time
= LTT_TIME_MIN(ltt_time_add(new_time_window
.start_time
,
3467 new_time_window
.time_width
),
3468 time_span
.end_time
);
3471 /* Fix the time width to fit start time and end time */
3472 new_time_window
.time_width
= ltt_time_sub(end_time
,
3473 new_time_window
.start_time
);
3474 new_time_window
.time_width_double
=
3475 ltt_time_to_double(new_time_window
.time_width
);
3477 new_time_window
.end_time
= end_time
;
3479 time_change_manager(tab
, new_time_window
);
3484 on_MEntry3_value_changed (GtkSpinButton
*spinbutton
,
3487 Tab
*tab
=(Tab
*)user_data
;
3488 LttvTracesetContext
* tsc
=
3489 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3490 TimeInterval time_span
= tsc
->time_span
;
3491 gint value
= gtk_spin_button_get_value_as_int(spinbutton
);
3493 TimeWindow new_time_window
= tab
->time_window
;
3495 LttTime end_time
= new_time_window
.end_time
;
3497 end_time
.tv_sec
= value
;
3499 /* end nanoseconds */
3500 if(end_time
.tv_sec
== time_span
.start_time
.tv_sec
) {
3501 if(end_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3502 if(end_time
.tv_nsec
> time_span
.end_time
.tv_nsec
)
3503 end_time
.tv_nsec
= time_span
.end_time
.tv_nsec
;
3504 if(end_time
.tv_nsec
< time_span
.start_time
.tv_nsec
)
3505 end_time
.tv_nsec
= time_span
.start_time
.tv_nsec
+1;
3507 if(end_time
.tv_nsec
< time_span
.start_time
.tv_nsec
)
3508 end_time
.tv_nsec
= time_span
.start_time
.tv_nsec
+1;
3511 else if(end_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3512 if(end_time
.tv_nsec
> time_span
.end_time
.tv_nsec
)
3513 end_time
.tv_nsec
= time_span
.end_time
.tv_nsec
;
3516 if(ltt_time_compare(new_time_window
.start_time
, end_time
) >= 0) {
3517 /* Then, we must push front start time : keep the same time width
3518 * if possible, else end traceset time */
3519 new_time_window
.start_time
= LTT_TIME_MAX(
3520 ltt_time_sub(end_time
,
3521 new_time_window
.time_width
),
3522 time_span
.start_time
);
3525 /* Fix the time width to fit start time and end time */
3526 new_time_window
.time_width
= ltt_time_sub(end_time
,
3527 new_time_window
.start_time
);
3528 new_time_window
.time_width_double
=
3529 ltt_time_to_double(new_time_window
.time_width
);
3531 new_time_window
.end_time
= end_time
;
3533 time_change_manager(tab
, new_time_window
);
3538 on_MEntry4_value_changed (GtkSpinButton
*spinbutton
,
3541 Tab
*tab
=(Tab
*)user_data
;
3542 LttvTracesetContext
* tsc
=
3543 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3544 TimeInterval time_span
= tsc
->time_span
;
3545 gint value
= gtk_spin_button_get_value_as_int(spinbutton
);
3547 TimeWindow new_time_window
= tab
->time_window
;
3549 LttTime end_time
= new_time_window
.end_time
;
3551 end_time
.tv_nsec
= value
;
3553 if(ltt_time_compare(new_time_window
.start_time
, end_time
) >= 0) {
3554 /* Then, we must push front start time : keep the same time width
3555 * if possible, else end traceset time */
3556 new_time_window
.start_time
= LTT_TIME_MAX(
3557 ltt_time_sub(end_time
,
3558 new_time_window
.time_width
),
3559 time_span
.start_time
);
3562 /* Fix the time width to fit start time and end time */
3563 new_time_window
.time_width
= ltt_time_sub(end_time
,
3564 new_time_window
.start_time
);
3565 new_time_window
.time_width_double
=
3566 ltt_time_to_double(new_time_window
.time_width
);
3567 new_time_window
.end_time
= end_time
;
3569 time_change_manager(tab
, new_time_window
);
3574 void current_time_change_manager (Tab
*tab
,
3575 LttTime new_current_time
)
3577 /* Only one source of time change */
3578 if(tab
->current_time_manager_lock
== TRUE
) return;
3580 tab
->current_time_manager_lock
= TRUE
;
3582 LttvTracesetContext
*tsc
= LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3583 TimeInterval time_span
= tsc
->time_span
;
3585 /* current seconds */
3586 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry5
),
3587 (double)time_span
.start_time
.tv_sec
,
3588 (double)time_span
.end_time
.tv_sec
);
3589 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry5
),
3590 (double)new_current_time
.tv_sec
);
3593 /* start nanoseconds */
3594 if(new_current_time
.tv_sec
== time_span
.start_time
.tv_sec
) {
3595 /* can be both beginning and end at the same time. */
3596 if(new_current_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3597 /* If we are at the end, max nsec to end.. */
3598 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry6
),
3599 (double)time_span
.start_time
.tv_nsec
,
3600 (double)time_span
.end_time
.tv_nsec
);
3602 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry6
),
3603 (double)time_span
.start_time
.tv_nsec
,
3604 (double)NANOSECONDS_PER_SECOND
-1);
3606 } else if(new_current_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3607 /* If we are at the end, max nsec to end.. */
3608 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry6
),
3610 (double)time_span
.end_time
.tv_nsec
);
3611 } else /* anywhere else */
3612 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry6
),
3614 (double)NANOSECONDS_PER_SECOND
-1);
3616 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry6
),
3617 (double)new_current_time
.tv_nsec
);
3619 set_current_time(tab
, &new_current_time
);
3621 tab
->current_time_manager_lock
= FALSE
;
3625 on_MEntry5_value_changed (GtkSpinButton
*spinbutton
,
3628 Tab
*tab
= (Tab
*)user_data
;
3629 LttvTracesetContext
* tsc
=
3630 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3631 TimeInterval time_span
= tsc
->time_span
;
3632 gint value
= gtk_spin_button_get_value_as_int(spinbutton
);
3633 LttTime new_current_time
= tab
->current_time
;
3634 new_current_time
.tv_sec
= value
;
3636 /* current nanoseconds */
3637 if(new_current_time
.tv_sec
== time_span
.start_time
.tv_sec
) {
3638 if(new_current_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3639 if(new_current_time
.tv_nsec
> time_span
.end_time
.tv_nsec
)
3640 new_current_time
.tv_nsec
= time_span
.end_time
.tv_nsec
;
3641 if(new_current_time
.tv_nsec
< time_span
.start_time
.tv_nsec
)
3642 new_current_time
.tv_nsec
= time_span
.start_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
;
3648 else if(new_current_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3649 if(new_current_time
.tv_nsec
> time_span
.end_time
.tv_nsec
)
3650 new_current_time
.tv_nsec
= time_span
.end_time
.tv_nsec
;
3653 current_time_change_manager(tab
, new_current_time
);
3657 on_MEntry6_value_changed (GtkSpinButton
*spinbutton
,
3660 Tab
*tab
= (Tab
*)user_data
;
3661 gint value
= gtk_spin_button_get_value_as_int(spinbutton
);
3662 LttTime new_current_time
= tab
->current_time
;
3663 new_current_time
.tv_nsec
= value
;
3665 current_time_change_manager(tab
, new_current_time
);
3669 void scroll_value_changed_cb(GtkWidget
*scrollbar
,
3672 Tab
*tab
= (Tab
*)user_data
;
3673 TimeWindow new_time_window
;
3675 GtkAdjustment
*adjust
= gtk_range_get_adjustment(GTK_RANGE(scrollbar
));
3676 gdouble value
= gtk_adjustment_get_value(adjust
);
3677 // gdouble upper, lower, ratio, page_size;
3679 LttvTracesetContext
* tsc
=
3680 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3681 TimeInterval time_span
= tsc
->time_span
;
3683 time
= ltt_time_add(ltt_time_from_double(value
),
3684 time_span
.start_time
);
3686 new_time_window
.start_time
= time
;
3688 page_size
= adjust
->page_size
;
3690 new_time_window
.time_width
=
3691 ltt_time_from_double(page_size
);
3693 new_time_window
.time_width_double
=
3696 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
3697 new_time_window
.time_width
);
3700 time_change_manager(tab
, new_time_window
);
3702 //time_window = tab->time_window;
3704 lower
= adjust
->lower
;
3705 upper
= adjust
->upper
;
3706 ratio
= (value
- lower
) / (upper
- lower
);
3707 g_info("lower %lu, upper %lu, value %lu, ratio %lu", lower
, upper
, value
, ratio
);
3709 //time = ltt_time_sub(time_span->end_time, time_span->start_time);
3710 //time = ltt_time_mul(time, (float)ratio);
3711 //time = ltt_time_add(time_span->start_time, time);
3712 time
= ltt_time_add(ltt_time_from_double(value
),
3713 time_span
.start_time
);
3715 time_window
.start_time
= time
;
3717 page_size
= adjust
->page_size
;
3719 time_window
.time_width
=
3720 ltt_time_from_double(page_size
);
3721 //time = ltt_time_sub(time_span.end_time, time);
3722 //if(ltt_time_compare(time,time_window.time_width) < 0){
3723 // time_window.time_width = time;
3726 /* call viewer hooks for new time window */
3727 set_time_window(tab
, &time_window
);
3732 /* Display a dialogue showing all eventtypes and traces, let user to select the interested
3733 * eventtypes, tracefiles and traces (filter)
3736 /* Select a trace which will be removed from traceset
3739 char * get_remove_trace(char ** all_trace_name
, int nb_trace
)
3741 return get_selection(all_trace_name
, nb_trace
,
3742 "Select a trace", "Trace pathname");
3746 /* Select a module which will be loaded
3749 char * get_load_module(char ** load_module_name
, int nb_module
)
3751 return get_selection(load_module_name
, nb_module
,
3752 "Select a module to load", "Module name");
3758 /* Select a module which will be unloaded
3761 char * get_unload_module(char ** loaded_module_name
, int nb_module
)
3763 return get_selection(loaded_module_name
, nb_module
,
3764 "Select a module to unload", "Module name");
3768 /* Display a dialogue which shows all selectable items, let user to
3769 * select one of them
3772 char * get_selection(char ** loaded_module_name
, int nb_module
,
3773 char *title
, char * column_title
)
3775 GtkWidget
* dialogue
;
3776 GtkWidget
* scroll_win
;
3778 GtkListStore
* store
;
3779 GtkTreeViewColumn
* column
;
3780 GtkCellRenderer
* renderer
;
3781 GtkTreeSelection
* select
;
3784 char * unload_module_name
= NULL
;
3786 dialogue
= gtk_dialog_new_with_buttons(title
,
3789 GTK_STOCK_OK
,GTK_RESPONSE_ACCEPT
,
3790 GTK_STOCK_CANCEL
,GTK_RESPONSE_REJECT
,
3792 gtk_window_set_default_size((GtkWindow
*)dialogue
, 500, 200);
3794 scroll_win
= gtk_scrolled_window_new (NULL
, NULL
);
3795 gtk_widget_show ( scroll_win
);
3796 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll_win
),
3797 GTK_POLICY_AUTOMATIC
, GTK_POLICY_AUTOMATIC
);
3799 store
= gtk_list_store_new (N_COLUMNS
,G_TYPE_STRING
);
3800 tree
= gtk_tree_view_new_with_model(GTK_TREE_MODEL (store
));
3801 gtk_widget_show ( tree
);
3802 g_object_unref (G_OBJECT (store
));
3804 renderer
= gtk_cell_renderer_text_new ();
3805 column
= gtk_tree_view_column_new_with_attributes (column_title
,
3807 "text", MODULE_COLUMN
,
3809 gtk_tree_view_column_set_alignment (column
, 0.5);
3810 gtk_tree_view_column_set_fixed_width (column
, 150);
3811 gtk_tree_view_append_column (GTK_TREE_VIEW (tree
), column
);
3813 select
= gtk_tree_view_get_selection (GTK_TREE_VIEW (tree
));
3814 gtk_tree_selection_set_mode (select
, GTK_SELECTION_SINGLE
);
3816 gtk_container_add (GTK_CONTAINER (scroll_win
), tree
);
3818 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialogue
)->vbox
), scroll_win
,TRUE
, TRUE
,0);
3820 for(i
=0;i
<nb_module
;i
++){
3821 gtk_list_store_append (store
, &iter
);
3822 gtk_list_store_set (store
, &iter
, MODULE_COLUMN
,loaded_module_name
[i
],-1);
3825 id
= gtk_dialog_run(GTK_DIALOG(dialogue
));
3826 GtkTreeModel
**store_model
= (GtkTreeModel
**)&store
;
3828 case GTK_RESPONSE_ACCEPT
:
3829 case GTK_RESPONSE_OK
:
3830 if (gtk_tree_selection_get_selected (select
, store_model
, &iter
)){
3831 gtk_tree_model_get ((GtkTreeModel
*)store
, &iter
, MODULE_COLUMN
, &unload_module_name
, -1);
3833 case GTK_RESPONSE_REJECT
:
3834 case GTK_RESPONSE_CANCEL
:
3836 gtk_widget_destroy(dialogue
);
3840 return unload_module_name
;
3844 /* Insert all menu entry and tool buttons into this main window
3849 void add_all_menu_toolbar_constructors(MainWindow
* mw
, gpointer user_data
)
3853 lttvwindow_viewer_constructor constructor
;
3854 LttvMenus
* global_menu
, * instance_menu
;
3855 LttvToolbars
* global_toolbar
, * instance_toolbar
;
3856 LttvMenuClosure
*menu_item
;
3857 LttvToolbarClosure
*toolbar_item
;
3858 LttvAttributeValue value
;
3859 LttvIAttribute
*global_attributes
= LTTV_IATTRIBUTE(lttv_global_attributes());
3860 LttvIAttribute
*attributes
= mw
->attributes
;
3861 GtkWidget
* tool_menu_title_menu
, *new_widget
, *pixmap
;
3863 g_assert(lttv_iattribute_find_by_path(global_attributes
,
3864 "viewers/menu", LTTV_POINTER
, &value
));
3865 if(*(value
.v_pointer
) == NULL
)
3866 *(value
.v_pointer
) = lttv_menus_new();
3867 global_menu
= (LttvMenus
*)*(value
.v_pointer
);
3869 g_assert(lttv_iattribute_find_by_path(attributes
,
3870 "viewers/menu", LTTV_POINTER
, &value
));
3871 if(*(value
.v_pointer
) == NULL
)
3872 *(value
.v_pointer
) = lttv_menus_new();
3873 instance_menu
= (LttvMenus
*)*(value
.v_pointer
);
3877 g_assert(lttv_iattribute_find_by_path(global_attributes
,
3878 "viewers/toolbar", LTTV_POINTER
, &value
));
3879 if(*(value
.v_pointer
) == NULL
)
3880 *(value
.v_pointer
) = lttv_toolbars_new();
3881 global_toolbar
= (LttvToolbars
*)*(value
.v_pointer
);
3883 g_assert(lttv_iattribute_find_by_path(attributes
,
3884 "viewers/toolbar", LTTV_POINTER
, &value
));
3885 if(*(value
.v_pointer
) == NULL
)
3886 *(value
.v_pointer
) = lttv_toolbars_new();
3887 instance_toolbar
= (LttvToolbars
*)*(value
.v_pointer
);
3889 /* Add missing menu entries to window instance */
3890 for(i
=0;i
<global_menu
->len
;i
++) {
3891 menu_item
= &g_array_index(global_menu
, LttvMenuClosure
, i
);
3893 //add menu_item to window instance;
3894 constructor
= menu_item
->con
;
3895 tool_menu_title_menu
= lookup_widget(mw
->mwindow
,"ToolMenuTitle_menu");
3897 gtk_menu_item_new_with_mnemonic (menu_item
->menu_text
);
3898 gtk_container_add (GTK_CONTAINER (tool_menu_title_menu
),
3900 g_signal_connect ((gpointer
) new_widget
, "activate",
3901 G_CALLBACK (insert_viewer_wrap
),
3903 gtk_widget_show (new_widget
);
3904 lttv_menus_add(instance_menu
, menu_item
->con
,
3905 menu_item
->menu_path
,
3906 menu_item
->menu_text
,
3911 /* Add missing toolbar entries to window instance */
3912 for(i
=0;i
<global_toolbar
->len
;i
++) {
3913 toolbar_item
= &g_array_index(global_toolbar
, LttvToolbarClosure
, i
);
3915 //add toolbar_item to window instance;
3916 constructor
= toolbar_item
->con
;
3917 tool_menu_title_menu
= lookup_widget(mw
->mwindow
,"MToolbar1");
3918 pixbuf
= gdk_pixbuf_new_from_xpm_data((const char**)toolbar_item
->pixmap
);
3919 pixmap
= gtk_image_new_from_pixbuf(pixbuf
);
3921 gtk_toolbar_append_element (GTK_TOOLBAR (tool_menu_title_menu
),
3922 GTK_TOOLBAR_CHILD_BUTTON
,
3925 toolbar_item
->tooltip
, NULL
,
3926 pixmap
, NULL
, NULL
);
3927 gtk_label_set_use_underline(
3928 GTK_LABEL (((GtkToolbarChild
*) (
3929 g_list_last (GTK_TOOLBAR
3930 (tool_menu_title_menu
)->children
)->data
))->label
),
3932 gtk_container_set_border_width (GTK_CONTAINER (new_widget
), 1);
3933 g_signal_connect ((gpointer
) new_widget
,
3935 G_CALLBACK (insert_viewer_wrap
),
3937 gtk_widget_show (new_widget
);
3939 lttv_toolbars_add(instance_toolbar
, toolbar_item
->con
,
3940 toolbar_item
->tooltip
,
3941 toolbar_item
->pixmap
,
3949 /* Create a main window
3952 void construct_main_window(MainWindow
* parent
)
3954 g_debug("construct_main_window()");
3955 GtkWidget
* new_window
; /* New generated main window */
3956 MainWindow
* new_m_window
;/* New main window structure */
3957 GtkNotebook
* notebook
;
3958 LttvIAttribute
*attributes
=
3959 LTTV_IATTRIBUTE(g_object_new(LTTV_ATTRIBUTE_TYPE
, NULL
));
3960 LttvAttributeValue value
;
3963 new_m_window
= g_new(MainWindow
, 1);
3965 // Add the object's information to the module's array
3966 g_main_window_list
= g_slist_append(g_main_window_list
, new_m_window
);
3968 new_window
= create_MWindow();
3969 gtk_widget_show (new_window
);
3971 new_m_window
->mwindow
= new_window
;
3972 new_m_window
->attributes
= attributes
;
3974 g_assert(lttv_iattribute_find_by_path(attributes
,
3975 "viewers/menu", LTTV_POINTER
, &value
));
3976 *(value
.v_pointer
) = lttv_menus_new();
3978 g_assert(lttv_iattribute_find_by_path(attributes
,
3979 "viewers/toolbar", LTTV_POINTER
, &value
));
3980 *(value
.v_pointer
) = lttv_toolbars_new();
3982 add_all_menu_toolbar_constructors(new_m_window
, NULL
);
3984 g_object_set_data_full(G_OBJECT(new_window
),
3986 (gpointer
)new_m_window
,
3987 (GDestroyNotify
)g_free
);
3988 //create a default tab
3989 notebook
= (GtkNotebook
*)lookup_widget(new_m_window
->mwindow
, "MNotebook");
3990 if(notebook
== NULL
){
3991 g_info("Notebook does not exist\n");
3994 //gtk_notebook_popup_enable (GTK_NOTEBOOK(notebook));
3995 //for now there is no name field in LttvTraceset structure
3996 //Use "Traceset" as the label for the default tab
3998 GtkWidget
* parent_notebook
= lookup_widget(parent
->mwindow
, "MNotebook");
3999 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(parent_notebook
),
4000 gtk_notebook_get_current_page(GTK_NOTEBOOK(parent_notebook
)));
4006 parent_tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
4008 new_tab
= create_tab(new_m_window
, parent_tab
, notebook
, "Traceset");
4010 new_tab
= create_tab(new_m_window
, NULL
, notebook
, "Traceset");
4011 /* First window, use command line trace */
4012 if(g_init_trace
!= NULL
){
4013 lttvwindow_add_trace(new_tab
,
4017 LttvTraceset
*traceset
= new_tab
->traceset_info
->traceset
;
4018 SetTraceset(new_tab
, traceset
);
4020 /* Insert default viewers */
4022 LttvAttributeType type
;
4023 LttvAttributeName name
;
4024 LttvAttributeValue value
;
4025 LttvAttribute
*attribute
;
4027 LttvIAttribute
*attributes_global
=
4028 LTTV_IATTRIBUTE(lttv_global_attributes());
4030 g_assert(attribute
=
4031 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
4032 LTTV_IATTRIBUTE(attributes_global
),
4033 LTTV_VIEWER_CONSTRUCTORS
)));
4035 name
= g_quark_from_string("guievents");
4036 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
4038 if(type
== LTTV_POINTER
) {
4039 lttvwindow_viewer_constructor viewer_constructor
=
4040 (lttvwindow_viewer_constructor
)*value
.v_pointer
;
4041 insert_viewer(new_window
, viewer_constructor
);
4044 name
= g_quark_from_string("guicontrolflow");
4045 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
4047 if(type
== LTTV_POINTER
) {
4048 lttvwindow_viewer_constructor viewer_constructor
=
4049 (lttvwindow_viewer_constructor
)*value
.v_pointer
;
4050 insert_viewer(new_window
, viewer_constructor
);
4053 name
= g_quark_from_string("guistatistics");
4054 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
4056 if(type
== LTTV_POINTER
) {
4057 lttvwindow_viewer_constructor viewer_constructor
=
4058 (lttvwindow_viewer_constructor
)*value
.v_pointer
;
4059 insert_viewer(new_window
, viewer_constructor
);
4065 g_info("There are now : %d windows\n",g_slist_length(g_main_window_list
));
4069 /* Free the memory occupied by a tab structure
4073 void tab_destructor(Tab
* tab
)
4075 int i
, nb
, ref_count
;
4078 gtk_object_destroy(GTK_OBJECT(tab
->tooltips
));
4081 g_object_unref(tab
->attributes
);
4083 if(tab
->interrupted_state
)
4084 g_object_unref(tab
->interrupted_state
);
4087 if(tab
->traceset_info
->traceset_context
!= NULL
){
4088 //remove state update hooks
4089 lttv_state_remove_event_hooks(
4090 (LttvTracesetState
*)tab
->traceset_info
->
4092 lttv_context_fini(LTTV_TRACESET_CONTEXT(tab
->traceset_info
->
4094 g_object_unref(tab
->traceset_info
->traceset_context
);
4096 if(tab
->traceset_info
->traceset
!= NULL
) {
4097 nb
= lttv_traceset_number(tab
->traceset_info
->traceset
);
4098 for(i
= 0 ; i
< nb
; i
++) {
4099 trace
= lttv_traceset_get(tab
->traceset_info
->traceset
, i
);
4100 ref_count
= lttv_trace_get_ref_number(trace
);
4102 ltt_trace_close(lttv_trace(trace
));
4106 lttv_filter_destroy(tab
->filter
);
4107 lttv_traceset_destroy(tab
->traceset_info
->traceset
);
4108 /* Remove the idle events requests processing function of the tab */
4109 g_idle_remove_by_data(tab
);
4111 g_slist_free(tab
->events_requests
);
4112 g_free(tab
->traceset_info
);
4117 /* Create a tab and insert it into the current main window
4120 Tab
* create_tab(MainWindow
* mw
, Tab
*copy_tab
,
4121 GtkNotebook
* notebook
, char * label
)
4126 //create a new tab data structure
4129 //construct and initialize the traceset_info
4130 tab
->traceset_info
= g_new(TracesetInfo
,1);
4133 tab
->traceset_info
->traceset
=
4134 lttv_traceset_copy(copy_tab
->traceset_info
->traceset
);
4136 /* Copy the previous tab's filter */
4137 /* We can clone the filter, as we copy the trace set also */
4138 /* The filter must always be in sync with the trace set */
4139 tab
->filter
= lttv_filter_clone(copy_tab
->filter
);
4142 tab
->traceset_info
->traceset
= lttv_traceset_new();
4147 lttv_attribute_write_xml(
4148 lttv_traceset_attribute(tab
->traceset_info
->traceset
),
4154 tab
->time_manager_lock
= FALSE
;
4155 tab
->current_time_manager_lock
= FALSE
;
4157 //FIXME copy not implemented in lower level
4158 tab
->traceset_info
->traceset_context
=
4159 g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
4160 g_assert(tab
->traceset_info
->traceset_context
!= NULL
);
4162 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
),
4163 tab
->traceset_info
->traceset
);
4164 //add state update hooks
4165 lttv_state_add_event_hooks(
4166 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
4168 //determine the current_time and time_window of the tab
4170 if(copy_tab
!= NULL
){
4171 tab
->time_window
= copy_tab
->time_window
;
4172 tab
->current_time
= copy_tab
->current_time
;
4174 tab
->time_window
.start_time
=
4175 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
4176 time_span
.start_time
;
4177 if(DEFAULT_TIME_WIDTH_S
<
4178 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
4179 time_span
.end_time
.tv_sec
)
4180 tmp_time
.tv_sec
= DEFAULT_TIME_WIDTH_S
;
4183 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
4184 time_span
.end_time
.tv_sec
;
4185 tmp_time
.tv_nsec
= 0;
4186 tab
->time_window
.time_width
= tmp_time
;
4187 tab
->current_time
.tv_sec
=
4188 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
4189 time_span
.start_time
.tv_sec
;
4190 tab
->current_time
.tv_nsec
=
4191 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
4192 time_span
.start_time
.tv_nsec
;
4195 tab
->attributes
= LTTV_IATTRIBUTE(g_object_new(LTTV_ATTRIBUTE_TYPE
, NULL
));
4196 tab
->interrupted_state
= g_object_new(LTTV_ATTRIBUTE_TYPE
, NULL
);
4198 tab
->vbox
= gtk_vbox_new(FALSE
, 2);
4199 tab
->viewer_container
= gtk_vbox_new(TRUE
, 2);
4200 tab
->scrollbar
= gtk_hscrollbar_new(NULL
);
4201 //tab->multivpaned = gtk_multi_vpaned_new();
4203 gtk_box_pack_start(GTK_BOX(tab
->vbox
),
4204 tab
->viewer_container
,
4206 TRUE
, /* Give the extra space to the child */
4207 0); /* No padding */
4209 /* Create the timebar */
4211 tab
->MTimebar
= gtk_hbox_new(FALSE
, 2);
4212 gtk_widget_show(tab
->MTimebar
);
4213 tab
->tooltips
= gtk_tooltips_new();
4215 tab
->MEventBox1a
= gtk_event_box_new();
4216 gtk_widget_show(tab
->MEventBox1a
);
4217 gtk_tooltips_set_tip(tab
->tooltips
, tab
->MEventBox1a
,
4218 "Paste Start and End Times Here", "");
4219 tab
->MText1a
= gtk_label_new("Time Frame ");
4220 gtk_widget_show(tab
->MText1a
);
4221 gtk_container_add(GTK_CONTAINER(tab
->MEventBox1a
), tab
->MText1a
);
4222 tab
->MEventBox1b
= gtk_event_box_new();
4223 gtk_widget_show(tab
->MEventBox1b
);
4224 gtk_tooltips_set_tip(tab
->tooltips
, tab
->MEventBox1b
,
4225 "Paste Start Time Here", "");
4226 tab
->MText1b
= gtk_label_new("start: ");
4227 gtk_widget_show(tab
->MText1b
);
4228 gtk_container_add(GTK_CONTAINER(tab
->MEventBox1b
), tab
->MText1b
);
4229 tab
->MText2
= gtk_label_new("s");
4230 gtk_widget_show(tab
->MText2
);
4231 tab
->MText3a
= gtk_label_new("ns");
4232 gtk_widget_show(tab
->MText3a
);
4233 tab
->MEventBox3b
= gtk_event_box_new();
4234 gtk_widget_show(tab
->MEventBox3b
);
4235 gtk_tooltips_set_tip(tab
->tooltips
, tab
->MEventBox3b
,
4236 "Paste End Time Here", "");
4237 tab
->MText3b
= gtk_label_new("end:");
4238 gtk_widget_show(tab
->MText3b
);
4239 gtk_container_add(GTK_CONTAINER(tab
->MEventBox3b
), tab
->MText3b
);
4240 tab
->MText4
= gtk_label_new("s");
4241 gtk_widget_show(tab
->MText4
);
4242 tab
->MText5a
= gtk_label_new("ns");
4243 gtk_widget_show(tab
->MText5a
);
4244 tab
->MEventBox5b
= gtk_event_box_new();
4245 gtk_widget_show(tab
->MEventBox5b
);
4246 gtk_tooltips_set_tip(tab
->tooltips
, tab
->MEventBox5b
,
4247 "Paste Current Time Here", "");
4248 tab
->MText5b
= gtk_label_new("Current Time:");
4249 gtk_widget_show(tab
->MText5b
);
4250 gtk_container_add(GTK_CONTAINER(tab
->MEventBox5b
), tab
->MText5b
);
4251 tab
->MText6
= gtk_label_new("s");
4252 gtk_widget_show(tab
->MText6
);
4253 tab
->MText7
= gtk_label_new("ns");
4254 gtk_widget_show(tab
->MText7
);
4256 tab
->MEntry1
= gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4257 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab
->MEntry1
),0);
4258 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab
->MEntry1
),TRUE
);
4259 gtk_widget_show(tab
->MEntry1
);
4260 tab
->MEntry2
= gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4261 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab
->MEntry2
),0);
4262 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab
->MEntry2
),TRUE
);
4263 gtk_widget_show(tab
->MEntry2
);
4264 tab
->MEntry3
= gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4265 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab
->MEntry3
),0);
4266 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab
->MEntry3
),TRUE
);
4267 gtk_widget_show(tab
->MEntry3
);
4268 tab
->MEntry4
= gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4269 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab
->MEntry4
),0);
4270 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab
->MEntry4
),TRUE
);
4271 gtk_widget_show(tab
->MEntry4
);
4272 tab
->MEntry5
= gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4273 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab
->MEntry5
),0);
4274 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab
->MEntry5
),TRUE
);
4275 gtk_widget_show(tab
->MEntry5
);
4276 tab
->MEntry6
= gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4277 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab
->MEntry6
),0);
4278 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab
->MEntry6
),TRUE
);
4279 gtk_widget_show(tab
->MEntry6
);
4282 GtkWidget
*temp_widget
;
4284 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEventBox1a
, FALSE
,
4286 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEventBox1b
, FALSE
,
4288 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEntry1
, FALSE
, FALSE
, 0);
4289 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MText2
, FALSE
, FALSE
, 0);
4290 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEntry2
, FALSE
, FALSE
, 0);
4291 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MText3a
, FALSE
, FALSE
, 0);
4292 temp_widget
= gtk_vseparator_new();
4293 gtk_widget_show(temp_widget
);
4294 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), temp_widget
, FALSE
, FALSE
, 0);
4295 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEventBox3b
, FALSE
,
4297 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEntry3
, FALSE
, FALSE
, 0);
4298 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MText4
, FALSE
, FALSE
, 0);
4299 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEntry4
, FALSE
, FALSE
, 0);
4300 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MText5a
, FALSE
, FALSE
, 0);
4301 temp_widget
= gtk_vseparator_new();
4302 gtk_widget_show(temp_widget
);
4303 gtk_box_pack_end (GTK_BOX (tab
->MTimebar
), tab
->MText7
, FALSE
, FALSE
, 0);
4304 gtk_box_pack_end (GTK_BOX (tab
->MTimebar
), tab
->MEntry6
, FALSE
, FALSE
, 0);
4305 gtk_box_pack_end (GTK_BOX (tab
->MTimebar
), tab
->MText6
, FALSE
, FALSE
, 0);
4306 gtk_box_pack_end (GTK_BOX (tab
->MTimebar
), tab
->MEntry5
, FALSE
, FALSE
, 0);
4307 gtk_box_pack_end (GTK_BOX (tab
->MTimebar
), tab
->MEventBox5b
, FALSE
,
4309 gtk_box_pack_end (GTK_BOX (tab
->MTimebar
), temp_widget
, FALSE
, FALSE
, 0);
4312 //GtkWidget *test = gtk_button_new_with_label("drop");
4313 //gtk_button_set_relief(GTK_BUTTON(test), GTK_RELIEF_NONE);
4314 //gtk_widget_show(test);
4315 //gtk_box_pack_end(GTK_BOX (tab->MTimebar), test, FALSE, FALSE, 0);
4316 //gtk_widget_add_events(tab->MText1, GDK_ALL_EVENTS_MASK);//GDK_BUTTON_PRESS_MASK);
4317 /*GtkWidget *event_box = gtk_event_box_new();
4318 gtk_widget_show(event_box);
4319 gtk_tooltips_set_tip(tooltips, event_box,
4320 "Paste Current Time Here", "");
4321 gtk_box_pack_end(GTK_BOX (tab->MTimebar), event_box, FALSE, FALSE, 0);
4322 GtkWidget *test = gtk_label_new("drop");
4323 gtk_container_add(GTK_CONTAINER(event_box), test);
4324 gtk_widget_show(test);
4325 g_signal_connect (G_OBJECT(event_box),
4326 "button-press-event",
4327 G_CALLBACK (on_MText1_paste),
4331 g_signal_connect (G_OBJECT(tab
->MEventBox1a
),
4332 "button-press-event",
4333 G_CALLBACK (on_MEventBox1a_paste
),
4336 g_signal_connect (G_OBJECT(tab
->MEventBox1b
),
4337 "button-press-event",
4338 G_CALLBACK (on_MEventBox1b_paste
),
4340 g_signal_connect (G_OBJECT(tab
->MEventBox3b
),
4341 "button-press-event",
4342 G_CALLBACK (on_MEventBox3b_paste
),
4344 g_signal_connect (G_OBJECT(tab
->MEventBox5b
),
4345 "button-press-event",
4346 G_CALLBACK (on_MEventBox5b_paste
),
4350 gtk_box_pack_end(GTK_BOX(tab
->vbox
),
4352 FALSE
, /* Do not expand */
4353 FALSE
, /* Fill has no effect here (expand false) */
4354 0); /* No padding */
4356 gtk_box_pack_end(GTK_BOX(tab
->vbox
),
4358 FALSE
, /* Do not expand */
4359 FALSE
, /* Fill has no effect here (expand false) */
4360 0); /* No padding */
4362 g_object_set_data(G_OBJECT(tab
->viewer_container
), "focused_viewer", NULL
);
4368 // Display a label with a X
4369 GtkWidget *w_hbox = gtk_hbox_new(FALSE, 4);
4370 GtkWidget *w_label = gtk_label_new (label);
4371 GtkWidget *pixmap = create_pixmap(GTK_WIDGET(notebook), "close.png");
4372 GtkWidget *w_button = gtk_button_new ();
4373 gtk_container_add(GTK_CONTAINER(w_button), pixmap);
4374 //GtkWidget *w_button = gtk_button_new_with_label("x");
4376 gtk_button_set_relief(GTK_BUTTON(w_button), GTK_RELIEF_NONE);
4378 gtk_box_pack_start(GTK_BOX(w_hbox), w_label, TRUE, TRUE, 0);
4379 gtk_box_pack_end(GTK_BOX(w_hbox), w_button, FALSE,
4382 g_signal_connect_swapped (w_button, "clicked",
4383 G_CALLBACK (on_close_tab_X_clicked),
4386 gtk_widget_set_state(w_button, GTK_STATE_ACTIVE);
4388 gtk_widget_show (w_label);
4389 gtk_widget_show (pixmap);
4390 gtk_widget_show (w_button);
4391 gtk_widget_show (w_hbox);
4393 tab->label = w_hbox;
4397 tab
->label
= gtk_label_new (label
);
4399 gtk_widget_show(tab
->label
);
4400 gtk_widget_show(tab
->scrollbar
);
4401 gtk_widget_show(tab
->viewer_container
);
4402 gtk_widget_show(tab
->vbox
);
4403 //gtk_widget_show(tab->multivpaned);
4406 /* Start with empty events requests list */
4407 tab
->events_requests
= NULL
;
4408 tab
->events_request_pending
= FALSE
;
4410 g_object_set_data_full(
4411 G_OBJECT(tab
->vbox
),
4414 (GDestroyNotify
)tab_destructor
);
4416 g_signal_connect(G_OBJECT(tab
->scrollbar
), "value-changed",
4417 G_CALLBACK(scroll_value_changed_cb
), tab
);
4419 g_signal_connect ((gpointer
) tab
->MEntry1
, "value-changed",
4420 G_CALLBACK (on_MEntry1_value_changed
),
4422 g_signal_connect ((gpointer
) tab
->MEntry2
, "value-changed",
4423 G_CALLBACK (on_MEntry2_value_changed
),
4425 g_signal_connect ((gpointer
) tab
->MEntry3
, "value-changed",
4426 G_CALLBACK (on_MEntry3_value_changed
),
4428 g_signal_connect ((gpointer
) tab
->MEntry4
, "value-changed",
4429 G_CALLBACK (on_MEntry4_value_changed
),
4431 g_signal_connect ((gpointer
) tab
->MEntry5
, "value-changed",
4432 G_CALLBACK (on_MEntry5_value_changed
),
4434 g_signal_connect ((gpointer
) tab
->MEntry6
, "value-changed",
4435 G_CALLBACK (on_MEntry6_value_changed
),
4438 //g_signal_connect(G_OBJECT(tab->scrollbar), "changed",
4439 // G_CALLBACK(scroll_value_changed_cb), tab);
4442 //insert tab into notebook
4443 gtk_notebook_append_page(notebook
,
4446 list
= gtk_container_get_children(GTK_CONTAINER(notebook
));
4447 gtk_notebook_set_current_page(notebook
,g_list_length(list
)-1);
4448 // always show : not if(g_list_length(list)>1)
4449 gtk_notebook_set_show_tabs(notebook
, TRUE
);
4455 * execute_events_requests
4457 * Idle function that executes the pending requests for a tab.
4459 * @return return value : TRUE : keep the idle function, FALSE : remove it.
4461 gboolean
execute_events_requests(Tab
*tab
)
4463 return ( lttvwindow_process_pending_requests(tab
) );