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
28 #include "callbacks.h"
29 #include "interface.h"
31 #include <ltt/trace.h>
32 #include <ltt/facility.h>
34 #include <ltt/event.h>
35 #include <lttv/lttv.h>
36 #include <lttv/module.h>
37 #include <lttv/iattribute.h>
38 #include <lttv/stats.h>
39 #include <lttvwindow/mainwindow.h>
40 #include <lttvwindow/mainwindow-private.h>
41 #include <lttvwindow/menu.h>
42 #include <lttvwindow/toolbar.h>
43 #include <lttvwindow/lttvwindow.h>
44 #include <lttvwindow/lttvwindowtraces.h>
45 #include <lttvwindow/gtkdirsel.h>
46 #include <lttvwindow/lttvfilter.h>
49 #define DEFAULT_TIME_WIDTH_S 1
51 extern LttvTrace
*g_init_trace
;
54 /** Array containing instanced objects. */
55 extern GSList
* g_main_window_list
;
57 /** MD : keep old directory. */
58 static char remember_plugins_dir
[PATH_MAX
] = "";
59 static char remember_trace_dir
[PATH_MAX
] = "";
62 MainWindow
* get_window_data_struct(GtkWidget
* widget
);
63 char * get_load_module(char ** load_module_name
, int nb_module
);
64 char * get_unload_module(char ** loaded_module_name
, int nb_module
);
65 char * get_remove_trace(char ** all_trace_name
, int nb_trace
);
66 char * get_selection(char ** all_name
, int nb
, char *title
, char * column_title
);
67 gboolean
get_filter_selection(LttvTracesetSelector
*s
, char *title
, char * column_title
);
68 Tab
* create_tab(MainWindow
* mw
, Tab
*copy_tab
,
69 GtkNotebook
* notebook
, char * label
);
71 static void insert_viewer(GtkWidget
* widget
, lttvwindow_viewer_constructor constructor
);
72 void update_filter(LttvTracesetSelector
*s
, GtkTreeStore
*store
);
74 void checkbox_changed(GtkTreeView
*treeview
,
76 GtkTreeViewColumn
*arg2
,
78 void remove_trace_from_traceset_selector(GtkWidget
* paned
, unsigned i
);
79 void add_trace_into_traceset_selector(GtkWidget
* paned
, LttTrace
* trace
);
80 Tab
*create_new_tab(GtkWidget
* widget
, gpointer user_data
);
82 LttvTracesetSelector
* construct_traceset_selector(LttvTraceset
* traceset
);
84 static gboolean
lttvwindow_process_pending_requests(Tab
*tab
);
98 /* Construct a selector(filter), which will be associated with a viewer,
99 * and provides an interface for user to select interested events and traces
102 LttvTracesetSelector
* construct_traceset_selector(LttvTraceset
* traceset
)
104 LttvTracesetSelector
* s
;
105 LttvTraceSelector
* trace
;
106 LttvTracefileSelector
* tracefile
;
107 LttvEventtypeSelector
* eventtype
;
109 int nb_trace
, nb_tracefile
, nb_control
, nb_per_cpu
, nb_facility
, nb_event
;
116 s
= lttv_traceset_selector_new(lttv_traceset_name(traceset
));
117 nb_trace
= lttv_traceset_number(traceset
);
118 for(i
=0;i
<nb_trace
;i
++){
119 trace_v
= lttv_traceset_get(traceset
, i
);
120 t
= lttv_trace(trace_v
);
121 trace
= lttv_trace_selector_new(t
);
122 lttv_traceset_selector_trace_add(s
, trace
);
124 nb_facility
= ltt_trace_facility_number(t
);
125 for(k
=0;k
<nb_facility
;k
++){
126 fac
= ltt_trace_facility_get(t
,k
);
127 nb_event
= (int) ltt_facility_eventtype_number(fac
);
128 for(m
=0;m
<nb_event
;m
++){
129 et
= ltt_facility_eventtype_get(fac
,m
);
130 eventtype
= lttv_eventtype_selector_new(et
);
131 lttv_trace_selector_eventtype_add(trace
, eventtype
);
135 nb_control
= ltt_trace_control_tracefile_number(t
);
136 nb_per_cpu
= ltt_trace_per_cpu_tracefile_number(t
);
137 nb_tracefile
= nb_control
+ nb_per_cpu
;
139 for(j
= 0 ; j
< nb_tracefile
; j
++) {
141 tf
= ltt_trace_control_tracefile_get(t
, j
);
143 tf
= ltt_trace_per_cpu_tracefile_get(t
, j
- nb_control
);
144 tracefile
= lttv_tracefile_selector_new(tf
);
145 lttv_trace_selector_tracefile_add(trace
, tracefile
);
146 lttv_eventtype_selector_copy(trace
, tracefile
);
153 static gboolean
viewer_grab_focus(GtkWidget
*widget
, GdkEventButton
*event
,
156 GtkWidget
*viewer_container
= GTK_WIDGET(data
);
158 g_debug("FOCUS GRABBED");
159 g_object_set_data(G_OBJECT(viewer_container
), "focused_viewer", widget
);
163 /* insert_viewer function constructs an instance of a viewer first,
164 * then inserts the widget of the instance into the container of the
169 insert_viewer_wrap(GtkWidget
*menuitem
, gpointer user_data
)
173 insert_viewer((GtkWidget
*)menuitem
, (lttvwindow_viewer_constructor
)user_data
);
174 // selected_hook(&val);
178 /* internal functions */
179 void insert_viewer(GtkWidget
* widget
, lttvwindow_viewer_constructor constructor
)
181 GtkWidget
* viewer_container
;
182 MainWindow
* mw_data
= get_window_data_struct(widget
);
183 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
185 LttvTracesetSelector
* s
;
186 TimeInterval
* time_interval
;
187 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
188 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
192 tab
= create_new_tab(widget
, NULL
);
194 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
197 viewer_container
= tab
->viewer_container
;
199 s
= construct_traceset_selector(tab
->traceset_info
->traceset
);
200 viewer
= (GtkWidget
*)constructor(tab
, s
, "Traceset_Selector");
203 //gtk_multivpaned_widget_add(GTK_MULTIVPANED(multivpaned), viewer);
205 gtk_box_pack_end(GTK_BOX(viewer_container
),
211 g_signal_connect (G_OBJECT(viewer
),
212 "button-press-event",
213 G_CALLBACK (viewer_grab_focus
),
214 (gpointer
)viewer_container
);
216 // We unref here, because it is now referenced by the viewer_container!
217 // not for a box ... g_object_unref(G_OBJECT(viewer));
219 // The viewer will show itself when it receives a show notify
220 // So we call the show notify hooks here. It will
221 // typically add hooks for reading, we call process trace, and the
222 // end of reading hook will call gtk_widget_show and unregister the
224 // Note that show notify gets the time_requested through the call_data.
225 //show_viewer(mw_data);
226 // in expose now call_pending_read_hooks(mw_data);
231 * Function to set/update traceset for the viewers
232 * @param tab viewer's tab
233 * @param traceset traceset of the main window.
235 * 0 : traceset updated
236 * 1 : no traceset hooks to update; not an error.
239 int SetTraceset(Tab
* tab
, LttvTraceset
*traceset
)
241 LttvTracesetContext
*tsc
=
242 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
243 TimeInterval time_span
= tsc
->time_span
;
245 /* Set the tab's time window and current time if
247 if(ltt_time_compare(tab
->time_window
.start_time
, time_span
.start_time
) < 0
248 || ltt_time_compare( ltt_time_add(tab
->time_window
.start_time
,
249 tab
->time_window
.time_width
),
250 time_span
.end_time
) > 0) {
251 tab
->time_window
.start_time
= time_span
.start_time
;
252 tab
->current_time
= time_span
.start_time
;
256 if(DEFAULT_TIME_WIDTH_S
< time_span
.end_time
.tv_sec
)
257 tmp_time
.tv_sec
= DEFAULT_TIME_WIDTH_S
;
259 tmp_time
.tv_sec
= time_span
.end_time
.tv_sec
;
260 tmp_time
.tv_nsec
= 0;
261 tab
->time_window
.time_width
= tmp_time
;
265 GtkAdjustment
*adjustment
= gtk_range_get_adjustment(GTK_RANGE(tab
->scrollbar
));
266 LttTime upper
= ltt_time_sub(time_span
.end_time
, time_span
.start_time
);
268 g_object_set(G_OBJECT(adjustment
),
272 ltt_time_to_double(upper
)
273 * NANOSECONDS_PER_SECOND
, /* upper */
275 ltt_time_to_double(tab
->time_window
.time_width
)
276 / SCROLL_STEP_PER_PAGE
277 * NANOSECONDS_PER_SECOND
, /* step increment */
279 ltt_time_to_double(tab
->time_window
.time_width
)
280 * NANOSECONDS_PER_SECOND
, /* page increment */
282 ltt_time_to_double(tab
->time_window
.time_width
)
283 * NANOSECONDS_PER_SECOND
, /* page size */
285 gtk_adjustment_changed(adjustment
);
287 g_object_set(G_OBJECT(adjustment
),
290 ltt_time_sub(tab
->time_window
.start_time
, time_span
.start_time
))
291 * NANOSECONDS_PER_SECOND
, /* value */
293 gtk_adjustment_value_changed(adjustment
);
295 /* Finally, call the update hooks of the viewers */
297 LttvAttributeValue value
;
301 g_assert( lttv_iattribute_find_by_path(tab
->attributes
,
302 "hooks/updatetraceset", LTTV_POINTER
, &value
));
304 tmp
= (LttvHooks
*)*(value
.v_pointer
);
305 if(tmp
== NULL
) retval
= 1;
306 else lttv_hooks_call(tmp
,traceset
);
313 * Function to set/update filter for the viewers
314 * @param tab viewer's tab
315 * @param filter filter of the main window.
318 * 0 : filters updated
319 * 1 : no filter hooks to update; not an error.
322 int SetFilter(Tab
* tab
, gpointer filter
)
325 LttvAttributeValue value
;
327 g_assert(lttv_iattribute_find_by_path(tab
->attributes
,
328 "hooks/updatefilter", LTTV_POINTER
, &value
));
330 tmp
= (LttvHooks
*)*(value
.v_pointer
);
332 if(tmp
== NULL
) return 1;
333 lttv_hooks_call(tmp
,filter
);
341 * Function to redraw each viewer belonging to the current tab
342 * @param tab viewer's tab
345 void update_traceset(Tab
*tab
)
347 LttvAttributeValue value
;
349 g_assert(lttv_iattribute_find_by_path(tab
->attributes
,
350 "hooks/updatetraceset", LTTV_POINTER
, &value
));
351 tmp
= (LttvHooks
*)*(value
.v_pointer
);
352 if(tmp
== NULL
) return;
353 lttv_hooks_call(tmp
, NULL
);
357 /* get_label function is used to get user input, it displays an input
358 * box, which allows user to input a string
361 void get_label_string (GtkWidget
* text
, gchar
* label
)
363 GtkEntry
* entry
= (GtkEntry
*)text
;
364 if(strlen(gtk_entry_get_text(entry
))!=0)
365 strcpy(label
,gtk_entry_get_text(entry
));
368 gboolean
get_label(MainWindow
* mw
, gchar
* str
, gchar
* dialogue_title
, gchar
* label_str
)
370 GtkWidget
* dialogue
;
375 dialogue
= gtk_dialog_new_with_buttons(dialogue_title
,NULL
,
377 GTK_STOCK_OK
,GTK_RESPONSE_ACCEPT
,
378 GTK_STOCK_CANCEL
,GTK_RESPONSE_REJECT
,
381 label
= gtk_label_new(label_str
);
382 gtk_widget_show(label
);
384 text
= gtk_entry_new();
385 gtk_widget_show(text
);
387 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialogue
)->vbox
), label
,TRUE
, TRUE
,0);
388 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialogue
)->vbox
), text
,FALSE
, FALSE
,0);
390 id
= gtk_dialog_run(GTK_DIALOG(dialogue
));
392 case GTK_RESPONSE_ACCEPT
:
393 get_label_string(text
,str
);
394 gtk_widget_destroy(dialogue
);
396 case GTK_RESPONSE_REJECT
:
398 gtk_widget_destroy(dialogue
);
405 /* get_window_data_struct function is actually a lookup function,
406 * given a widget which is in the tree of the main window, it will
407 * return the MainWindow data structure associated with main window
410 MainWindow
* get_window_data_struct(GtkWidget
* widget
)
413 MainWindow
* mw_data
;
415 mw
= lookup_widget(widget
, "MWindow");
417 g_printf("Main window does not exist\n");
421 mw_data
= (MainWindow
*) g_object_get_data(G_OBJECT(mw
),"main_window_data");
423 g_printf("Main window data does not exist\n");
430 /* create_new_window function, just constructs a new main window
433 void create_new_window(GtkWidget
* widget
, gpointer user_data
, gboolean clone
)
435 MainWindow
* parent
= get_window_data_struct(widget
);
438 g_printf("Clone : use the same traceset\n");
439 construct_main_window(parent
);
441 g_printf("Empty : traceset is set to NULL\n");
442 construct_main_window(NULL
);
446 GtkWidget
*viewer_container_focus(GtkWidget
*container
)
450 widget
= (GtkWidget
*)g_object_get_data(G_OBJECT(container
),
453 if(widget
== NULL
) g_debug("no widget focused");
459 gint
viewer_container_position(GtkWidget
*container
, GtkWidget
*child
)
462 if(child
== NULL
) return -1;
465 GValue value
= { 0, };
466 g_value_init(&value
, G_TYPE_INT
);
467 gtk_container_child_get_property(GTK_CONTAINER(container
),
471 pos
= g_value_get_int(&value
);
477 /* move_*_viewer functions move the selected view up/down in
481 void move_down_viewer(GtkWidget
* widget
, gpointer user_data
)
483 MainWindow
* mw
= get_window_data_struct(widget
);
484 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
486 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
487 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
493 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
496 //gtk_multivpaned_widget_move_up(GTK_MULTIVPANED(tab->multivpaned));
498 /* change the position in the vbox */
499 GtkWidget
*focus_widget
;
501 focus_widget
= viewer_container_focus(tab
->viewer_container
);
502 position
= viewer_container_position(tab
->viewer_container
, focus_widget
);
505 /* can move up one position */
506 gtk_box_reorder_child(GTK_BOX(tab
->viewer_container
),
513 void move_up_viewer(GtkWidget
* widget
, gpointer user_data
)
515 MainWindow
* mw
= get_window_data_struct(widget
);
516 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
518 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
519 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
525 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
528 //gtk_multivpaned_widget_move_down(GTK_MULTIVPANED(tab->multivpaned));
529 /* change the position in the vbox */
530 GtkWidget
*focus_widget
;
532 focus_widget
= viewer_container_focus(tab
->viewer_container
);
533 position
= viewer_container_position(tab
->viewer_container
, focus_widget
);
537 g_list_length(gtk_container_get_children(
538 GTK_CONTAINER(tab
->viewer_container
)))-1
540 /* can move down one position */
541 gtk_box_reorder_child(GTK_BOX(tab
->viewer_container
),
549 /* delete_viewer deletes the selected viewer in the current tab
552 void delete_viewer(GtkWidget
* widget
, gpointer user_data
)
554 MainWindow
* mw
= get_window_data_struct(widget
);
555 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
557 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
558 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
564 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
567 //gtk_multivpaned_widget_delete(GTK_MULTIVPANED(tab->multivpaned));
569 GtkWidget
*focus_widget
= viewer_container_focus(tab
->viewer_container
);
571 if(focus_widget
!= NULL
)
572 gtk_widget_destroy(focus_widget
);
574 g_object_set_data(G_OBJECT(tab
->viewer_container
), "focused_viewer", NULL
);
578 /* open_traceset will open a traceset saved in a file
579 * Right now, it is not finished yet, (not working)
583 void open_traceset(GtkWidget
* widget
, gpointer user_data
)
587 LttvTraceset
* traceset
;
588 MainWindow
* mw_data
= get_window_data_struct(widget
);
589 GtkFileSelection
* file_selector
=
590 (GtkFileSelection
*)gtk_file_selection_new("Select a traceset");
592 gtk_file_selection_hide_fileop_buttons(file_selector
);
594 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
596 case GTK_RESPONSE_ACCEPT
:
597 case GTK_RESPONSE_OK
:
598 dir
= gtk_file_selection_get_selections (file_selector
);
599 traceset
= lttv_traceset_load(dir
[0]);
600 g_printf("Open a trace set %s\n", dir
[0]);
603 case GTK_RESPONSE_REJECT
:
604 case GTK_RESPONSE_CANCEL
:
606 gtk_widget_destroy((GtkWidget
*)file_selector
);
612 static void events_request_free(EventsRequest
*events_request
)
614 if(events_request
== NULL
) return;
616 if(events_request
->start_position
!= NULL
)
617 lttv_traceset_context_position_destroy(events_request
->start_position
);
618 if(events_request
->end_position
!= NULL
)
619 lttv_traceset_context_position_destroy(events_request
->end_position
);
620 if(events_request
->before_chunk_traceset
!= NULL
)
621 lttv_hooks_destroy(events_request
->before_chunk_traceset
);
622 if(events_request
->before_chunk_trace
!= NULL
)
623 lttv_hooks_destroy(events_request
->before_chunk_trace
);
624 if(events_request
->before_chunk_tracefile
!= NULL
)
625 lttv_hooks_destroy(events_request
->before_chunk_tracefile
);
626 if(events_request
->event
!= NULL
)
627 lttv_hooks_destroy(events_request
->event
);
628 if(events_request
->event_by_id
!= NULL
)
629 lttv_hooks_by_id_destroy(events_request
->event_by_id
);
630 if(events_request
->after_chunk_tracefile
!= NULL
)
631 lttv_hooks_destroy(events_request
->after_chunk_tracefile
);
632 if(events_request
->after_chunk_trace
!= NULL
)
633 lttv_hooks_destroy(events_request
->after_chunk_trace
);
634 if(events_request
->after_chunk_traceset
!= NULL
)
635 lttv_hooks_destroy(events_request
->after_chunk_traceset
);
636 if(events_request
->before_request
!= NULL
)
637 lttv_hooks_destroy(events_request
->before_request
);
638 if(events_request
->after_request
!= NULL
)
639 lttv_hooks_destroy(events_request
->after_request
);
641 g_free(events_request
);
646 /* lttvwindow_process_pending_requests
648 * This internal function gets called by g_idle, taking care of the pending
649 * requests. It is responsible for concatenation of time intervals and position
650 * requests. It does it with the following algorithm organizing process traceset
651 * calls. Here is the detailed description of the way it works :
653 * - Events Requests Servicing Algorithm
655 * Data structures necessary :
657 * List of requests added to context : list_in
658 * List of requests not added to context : list_out
663 * list_out : many events requests
665 * FIXME : insert rest of algorithm here
669 #define list_out tab->events_requests
671 gboolean
lttvwindow_process_pending_requests(Tab
*tab
)
673 unsigned max_nb_events
;
677 LttvTracesetContext
*tsc
;
678 LttvTracefileContext
*tfc
;
679 GSList
*list_in
= NULL
;
683 LttvTracesetContextPosition
*end_position
;
686 g_critical("Foreground processing : tab does not exist. Processing removed.");
690 /* There is no events requests pending : we should never have been called! */
691 g_assert(g_slist_length(list_out
) != 0);
693 tsc
= LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
695 //set the cursor to be X shape, indicating that the computer is busy in doing its job
697 new = gdk_cursor_new(GDK_X_CURSOR
);
698 widget
= lookup_widget(tab
->mw
->mwindow
, "MToolbar1");
699 win
= gtk_widget_get_parent_window(widget
);
700 gdk_window_set_cursor(win
, new);
701 gdk_cursor_unref(new);
702 gdk_window_stick(win
);
703 gdk_window_unstick(win
);
706 g_debug("SIZE events req len : %d", g_slist_length(list_out
));
708 /* Preliminary check for no trace in traceset */
709 /* Unregister the routine if empty, empty list_out too */
710 if(lttv_traceset_number(tsc
->ts
) == 0) {
712 /* - For each req in list_out */
713 GSList
*iter
= list_out
;
715 while(iter
!= NULL
) {
717 gboolean remove
= FALSE
;
718 gboolean free_data
= FALSE
;
719 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
721 /* - Call end request for req */
722 if(events_request
->servicing
== TRUE
)
723 lttv_hooks_call(events_request
->after_request
, (gpointer
)tsc
);
725 /* - remove req from list_out */
726 /* Destroy the request */
733 GSList
*remove_iter
= iter
;
735 iter
= g_slist_next(iter
);
736 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
737 list_out
= g_slist_remove_link(list_out
, remove_iter
);
738 } else { // not remove
739 iter
= g_slist_next(iter
);
744 /* 0.1 Lock Traces */
749 iter_trace
<lttv_traceset_number(tsc
->ts
);
751 LttvTrace
*trace_v
= lttv_traceset_get(tsc
->ts
, iter_trace
);
753 if(lttvwindowtraces_lock(trace_v
) != 0) {
754 g_critical("Foreground processing : Unable to get trace lock");
755 return TRUE
; /* Cannot get lock, try later */
760 /* 0.2 Seek tracefiles positions to context position */
761 lttv_process_traceset_synchronize_tracefiles(tsc
);
764 /* Events processing algorithm implementation */
765 /* Warning : the gtk_events_pending takes a LOT of cpu time. So what we do
766 * instead is to leave the control to GTK and take it back.
768 /* A. Servicing loop */
769 //while( (g_slist_length(list_in) != 0 || g_slist_length(list_out) != 0)) {
770 if((g_slist_length(list_in
) != 0 || g_slist_length(list_out
) != 0)) {
772 /* 1. If list_in is empty (need a seek) */
773 if( g_slist_length(list_in
) == 0 ) {
775 /* list in is empty, need a seek */
777 /* 1.1 Add requests to list_in */
778 GSList
*ltime
= NULL
;
782 /* 1.1.1 Find all time requests with the lowest start time in list_out
785 if(g_slist_length(list_out
) > 0)
786 ltime
= g_slist_append(ltime
, g_slist_nth_data(list_out
, 0));
787 for(iter
=g_slist_nth(list_out
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
788 /* Find all time requests with the lowest start time in list_out */
789 guint index_ltime
= g_array_index(ltime
, guint
, 0);
790 EventsRequest
*event_request_ltime
= (EventsRequest
*)g_slist_nth_data(ltime
, 0);
791 EventsRequest
*event_request_list_out
= (EventsRequest
*)iter
->data
;
794 comp
= ltt_time_compare(event_request_ltime
->start_time
,
795 event_request_list_out
->start_time
);
797 ltime
= g_slist_append(ltime
, event_request_list_out
);
799 /* Remove all elements from ltime, and add current */
801 ltime
= g_slist_delete_link(ltime
, g_slist_nth(ltime
, 0));
802 ltime
= g_slist_append(ltime
, event_request_list_out
);
806 /* 1.1.2 Find all position requests with the lowest position in list_out
809 if(g_slist_length(list_out
) > 0)
810 lpos
= g_slist_append(lpos
, g_slist_nth_data(list_out
, 0));
811 for(iter
=g_slist_nth(list_out
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
812 /* Find all position requests with the lowest position in list_out */
813 EventsRequest
*event_request_lpos
= (EventsRequest
*)g_slist_nth_data(lpos
, 0);
814 EventsRequest
*event_request_list_out
= (EventsRequest
*)iter
->data
;
817 if(event_request_lpos
->start_position
!= NULL
818 && event_request_list_out
->start_position
!= NULL
)
820 comp
= lttv_traceset_context_pos_pos_compare
821 (event_request_lpos
->start_position
,
822 event_request_list_out
->start_position
);
827 lpos
= g_slist_append(lpos
, event_request_list_out
);
829 /* Remove all elements from lpos, and add current */
831 lpos
= g_slist_delete_link(lpos
, g_slist_nth(lpos
, 0));
832 lpos
= g_slist_append(lpos
, event_request_list_out
);
837 EventsRequest
*event_request_lpos
= (EventsRequest
*)g_slist_nth_data(lpos
, 0);
838 EventsRequest
*event_request_ltime
= (EventsRequest
*)g_slist_nth_data(ltime
, 0);
839 LttTime lpos_start_time
;
841 if(event_request_lpos
!= NULL
842 && event_request_lpos
->start_position
!= NULL
) {
843 lpos_start_time
= lttv_traceset_context_position_get_time(
844 event_request_lpos
->start_position
);
847 /* 1.1.3 If lpos.start time < ltime */
848 if(event_request_lpos
!= NULL
849 && event_request_lpos
->start_position
!= NULL
850 && ltt_time_compare(lpos_start_time
,
851 event_request_ltime
->start_time
)<0) {
852 /* Add lpos to list_in, remove them from list_out */
853 for(iter
=lpos
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
855 EventsRequest
*event_request_lpos
=
856 (EventsRequest
*)iter
->data
;
858 list_in
= g_slist_append(list_in
, event_request_lpos
);
859 /* Remove from list_out */
860 list_out
= g_slist_remove(list_out
, event_request_lpos
);
863 /* 1.1.4 (lpos.start time >= ltime) */
864 /* Add ltime to list_in, remove them from list_out */
866 for(iter
=ltime
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
868 EventsRequest
*event_request_ltime
=
869 (EventsRequest
*)iter
->data
;
871 list_in
= g_slist_append(list_in
, event_request_ltime
);
872 /* Remove from list_out */
873 list_out
= g_slist_remove(list_out
, event_request_ltime
);
883 tfc
= lttv_traceset_context_get_current_tfc(tsc
);
884 g_assert(g_slist_length(list_in
)>0);
885 EventsRequest
*events_request
= g_slist_nth_data(list_in
, 0);
888 /* 1.2.1 If first request in list_in is a time request */
889 if(events_request
->start_position
== NULL
) {
890 /* - If first req in list_in start time != current time */
891 if(tfc
== NULL
|| ltt_time_compare(events_request
->start_time
,
892 tfc
->timestamp
) != 0)
893 /* - Seek to that time */
894 g_debug("SEEK TIME : %lu, %lu", events_request
->start_time
.tv_sec
,
895 events_request
->start_time
.tv_nsec
);
896 //lttv_process_traceset_seek_time(tsc, events_request->start_time);
897 lttv_state_traceset_seek_time_closest(LTTV_TRACESET_STATE(tsc
),
898 events_request
->start_time
);
900 /* Process the traceset with only state hooks */
902 lttv_process_traceset_middle(tsc
,
903 events_request
->start_time
,
909 /* Else, the first request in list_in is a position request */
910 /* If first req in list_in pos != current pos */
911 g_assert(events_request
->start_position
!= NULL
);
912 g_debug("SEEK POS time : %lu, %lu",
913 lttv_traceset_context_position_get_time(
914 events_request
->start_position
).tv_sec
,
915 lttv_traceset_context_position_get_time(
916 events_request
->start_position
).tv_nsec
);
918 g_debug("SEEK POS context time : %lu, %lu",
919 lttv_traceset_context_get_current_tfc(tsc
)->timestamp
.tv_sec
,
920 lttv_traceset_context_get_current_tfc(tsc
)->timestamp
.tv_nsec
);
921 g_assert(events_request
->start_position
!= NULL
);
922 if(lttv_traceset_context_ctx_pos_compare(tsc
,
923 events_request
->start_position
) != 0) {
924 /* 1.2.2.1 Seek to that position */
925 g_debug("SEEK POSITION");
926 //lttv_process_traceset_seek_position(tsc, events_request->start_position);
927 pos_time
= lttv_traceset_context_position_get_time(
928 events_request
->start_position
);
930 lttv_state_traceset_seek_time_closest(LTTV_TRACESET_STATE(tsc
),
933 /* Process the traceset with only state hooks */
935 lttv_process_traceset_middle(tsc
,
938 events_request
->start_position
);
939 g_assert(lttv_traceset_context_ctx_pos_compare(tsc
,
940 events_request
->start_position
) == 0);
947 /* 1.3 Add hooks and call before request for all list_in members */
951 for(iter
=list_in
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
952 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
953 /* 1.3.1 If !servicing */
954 if(events_request
->servicing
== FALSE
) {
955 /* - begin request hooks called
958 lttv_hooks_call(events_request
->before_request
, (gpointer
)tsc
);
959 events_request
->servicing
= TRUE
;
961 /* 1.3.2 call before chunk
962 * 1.3.3 events hooks added
964 lttv_process_traceset_begin(tsc
, events_request
->before_chunk_traceset
,
965 events_request
->before_chunk_trace
,
966 events_request
->before_chunk_tracefile
,
967 events_request
->event
,
968 events_request
->event_by_id
);
972 /* 2. Else, list_in is not empty, we continue a read */
975 /* 2.0 For each req of list_in */
976 GSList
*iter
= list_in
;
978 while(iter
!= NULL
) {
980 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
982 /* - Call before chunk
983 * - events hooks added
985 lttv_process_traceset_begin(tsc
, events_request
->before_chunk_traceset
,
986 events_request
->before_chunk_trace
,
987 events_request
->before_chunk_tracefile
,
988 events_request
->event
,
989 events_request
->event_by_id
);
991 iter
= g_slist_next(iter
);
996 tfc
= lttv_traceset_context_get_current_tfc(tsc
);
998 /* 2.1 For each req of list_out */
999 GSList
*iter
= list_out
;
1001 while(iter
!= NULL
) {
1003 gboolean remove
= FALSE
;
1004 gboolean free_data
= FALSE
;
1005 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1007 /* if req.start time == current context time
1008 * or req.start position == current position*/
1009 if( ltt_time_compare(events_request
->start_time
,
1010 tfc
->timestamp
) == 0
1012 (events_request
->start_position
!= NULL
1014 lttv_traceset_context_ctx_pos_compare(tsc
,
1015 events_request
->start_position
) == 0)
1017 /* - Add to list_in, remove from list_out */
1018 list_in
= g_slist_append(list_in
, events_request
);
1022 /* - If !servicing */
1023 if(events_request
->servicing
== FALSE
) {
1024 /* - begin request hooks called
1025 * - servicing = TRUE
1027 lttv_hooks_call(events_request
->before_request
, (gpointer
)tsc
);
1028 events_request
->servicing
= TRUE
;
1030 /* call before chunk
1031 * events hooks added
1033 lttv_process_traceset_begin(tsc
, events_request
->before_chunk_traceset
,
1034 events_request
->before_chunk_trace
,
1035 events_request
->before_chunk_tracefile
,
1036 events_request
->event
,
1037 events_request
->event_by_id
);
1043 GSList
*remove_iter
= iter
;
1045 iter
= g_slist_next(iter
);
1046 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
1047 list_out
= g_slist_remove_link(list_out
, remove_iter
);
1048 } else { // not remove
1049 iter
= g_slist_next(iter
);
1055 /* 3. Find end criterions */
1060 /* 3.1.1 Find lowest end time in list_in */
1061 g_assert(g_slist_length(list_in
)>0);
1062 end_time
= ((EventsRequest
*)g_slist_nth_data(list_in
,0))->end_time
;
1064 for(iter
=g_slist_nth(list_in
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
1065 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1067 if(ltt_time_compare(events_request
->end_time
,
1069 end_time
= events_request
->end_time
;
1072 /* 3.1.2 Find lowest start time in list_out */
1073 for(iter
=list_out
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
1074 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1076 if(ltt_time_compare(events_request
->start_time
,
1078 end_time
= events_request
->start_time
;
1083 /* 3.2 Number of events */
1085 /* 3.2.1 Find lowest number of events in list_in */
1088 end_nb_events
= ((EventsRequest
*)g_slist_nth_data(list_in
,0))->num_events
;
1090 for(iter
=g_slist_nth(list_in
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
1091 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1093 if(events_request
->num_events
< end_nb_events
)
1094 end_nb_events
= events_request
->num_events
;
1097 /* 3.2.2 Use min(CHUNK_NUM_EVENTS, min num events in list_in) as
1100 end_nb_events
= MIN(CHUNK_NUM_EVENTS
, end_nb_events
);
1104 /* 3.3 End position */
1106 /* 3.3.1 Find lowest end position in list_in */
1109 end_position
=((EventsRequest
*)g_slist_nth_data(list_in
,0))->end_position
;
1111 for(iter
=g_slist_nth(list_in
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
1112 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1114 if(events_request
->end_position
!= NULL
&& end_position
!= NULL
&&
1115 lttv_traceset_context_pos_pos_compare(events_request
->end_position
,
1117 end_position
= events_request
->end_position
;
1122 /* 3.3.2 Find lowest start position in list_out */
1125 for(iter
=list_out
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
1126 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1128 if(events_request
->end_position
!= NULL
&& end_position
!= NULL
&&
1129 lttv_traceset_context_pos_pos_compare(events_request
->end_position
,
1131 end_position
= events_request
->end_position
;
1136 /* 4. Call process traceset middle */
1137 g_debug("Calling process traceset middle with %p, %lu sec %lu nsec, %lu nb ev, %p end pos", tsc
, end_time
.tv_sec
, end_time
.tv_nsec
, end_nb_events
, end_position
);
1138 count
= lttv_process_traceset_middle(tsc
, end_time
, end_nb_events
, end_position
);
1140 tfc
= lttv_traceset_context_get_current_tfc(tsc
);
1142 g_debug("Context time after middle : %lu, %lu", tfc
->timestamp
.tv_sec
,
1143 tfc
->timestamp
.tv_nsec
);
1145 g_debug("End of trace reached after middle.");
1149 /* 5. After process traceset middle */
1150 tfc
= lttv_traceset_context_get_current_tfc(tsc
);
1152 /* - if current context time > traceset.end time */
1153 if(tfc
== NULL
|| ltt_time_compare(tfc
->timestamp
,
1154 tsc
->time_span
.end_time
) > 0) {
1155 /* - For each req in list_in */
1156 GSList
*iter
= list_in
;
1158 while(iter
!= NULL
) {
1160 gboolean remove
= FALSE
;
1161 gboolean free_data
= FALSE
;
1162 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1164 /* - Remove events hooks for req
1165 * - Call end chunk for req
1167 lttv_process_traceset_end(tsc
, events_request
->after_chunk_traceset
,
1168 events_request
->after_chunk_trace
,
1169 events_request
->after_chunk_tracefile
,
1170 events_request
->event
,
1171 events_request
->event_by_id
);
1172 /* - Call end request for req */
1173 lttv_hooks_call(events_request
->after_request
, (gpointer
)tsc
);
1175 /* - remove req from list_in */
1176 /* Destroy the request */
1183 GSList
*remove_iter
= iter
;
1185 iter
= g_slist_next(iter
);
1186 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
1187 list_in
= g_slist_remove_link(list_in
, remove_iter
);
1188 } else { // not remove
1189 iter
= g_slist_next(iter
);
1194 /* 5.1 For each req in list_in */
1195 GSList
*iter
= list_in
;
1197 while(iter
!= NULL
) {
1199 gboolean remove
= FALSE
;
1200 gboolean free_data
= FALSE
;
1201 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1203 /* - Remove events hooks for req
1204 * - Call end chunk for req
1206 lttv_process_traceset_end(tsc
, events_request
->after_chunk_traceset
,
1207 events_request
->after_chunk_trace
,
1208 events_request
->after_chunk_tracefile
,
1209 events_request
->event
,
1210 events_request
->event_by_id
);
1212 /* - req.num -= count */
1213 g_assert(events_request
->num_events
>= count
);
1214 events_request
->num_events
-= count
;
1216 g_assert(tfc
!= NULL
);
1217 /* - if req.num == 0
1219 * current context time >= req.end time
1221 * req.end pos == current pos
1223 * req.stop_flag == TRUE
1225 if( events_request
->num_events
== 0
1227 events_request
->stop_flag
== TRUE
1229 ltt_time_compare(tfc
->timestamp
,
1230 events_request
->end_time
) >= 0
1232 (events_request
->end_position
!= NULL
1234 lttv_traceset_context_ctx_pos_compare(tsc
,
1235 events_request
->end_position
) == 0)
1238 g_assert(events_request
->servicing
== TRUE
);
1239 /* - Call end request for req
1240 * - remove req from list_in */
1241 lttv_hooks_call(events_request
->after_request
, (gpointer
)tsc
);
1242 /* - remove req from list_in */
1243 /* Destroy the request */
1251 GSList
*remove_iter
= iter
;
1253 iter
= g_slist_next(iter
);
1254 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
1255 list_in
= g_slist_remove_link(list_in
, remove_iter
);
1256 } else { // not remove
1257 iter
= g_slist_next(iter
);
1263 /* End of removed servicing loop : leave control to GTK instead. */
1264 // if(gtk_events_pending()) break;
1267 /* B. When interrupted between chunks */
1270 GSList
*iter
= list_in
;
1272 /* 1. for each request in list_in */
1273 while(iter
!= NULL
) {
1275 gboolean remove
= FALSE
;
1276 gboolean free_data
= FALSE
;
1277 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1279 /* 1.1. Use current postition as start position */
1280 if(events_request
->start_position
!= NULL
)
1281 lttv_traceset_context_position_destroy(events_request
->start_position
);
1282 events_request
->start_position
= lttv_traceset_context_position_new();
1283 lttv_traceset_context_position_save(tsc
, events_request
->start_position
);
1285 /* 1.2. Remove start time */
1286 events_request
->start_time
.tv_sec
= G_MAXUINT
;
1287 events_request
->start_time
.tv_nsec
= G_MAXUINT
;
1289 /* 1.3. Move from list_in to list_out */
1292 list_out
= g_slist_append(list_out
, events_request
);
1297 GSList
*remove_iter
= iter
;
1299 iter
= g_slist_next(iter
);
1300 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
1301 list_in
= g_slist_remove_link(list_in
, remove_iter
);
1302 } else { // not remove
1303 iter
= g_slist_next(iter
);
1310 /* C Unlock Traces */
1312 //lttv_process_traceset_get_sync_data(tsc);
1317 iter_trace
<lttv_traceset_number(tsc
->ts
);
1319 LttvTrace
*trace_v
= lttv_traceset_get(tsc
->ts
, iter_trace
);
1321 lttvwindowtraces_unlock(trace_v
);
1326 //set the cursor back to normal
1327 gdk_window_set_cursor(win
, NULL
);
1330 g_assert(g_slist_length(list_in
) == 0);
1332 if( g_slist_length(list_out
) == 0 ) {
1333 /* Put tab's request pending flag back to normal */
1334 tab
->events_request_pending
= FALSE
;
1335 g_debug("remove the idle fct");
1336 return FALSE
; /* Remove the idle function */
1338 g_debug("leave the idle fct");
1339 return TRUE
; /* Leave the idle function */
1341 /* We do not use simili-round-robin, it may require to read 1 meg buffers
1342 * again and again if many tracesets use the same tracefiles. */
1343 /* Hack for round-robin idle functions */
1344 /* It will put the idle function at the end of the pool */
1345 /*g_idle_add_full((G_PRIORITY_HIGH_IDLE + 21),
1346 (GSourceFunc)execute_events_requests,
1356 /* add_trace_into_traceset_selector, each instance of a viewer has an associated
1357 * selector (filter), when a trace is added into traceset, the selector should
1358 * reflect the change. The function is used to update the selector
1361 void add_trace_into_traceset_selector(GtkWidget
* paned
, LttTrace
* t
)
1363 int j
, k
, m
, nb_tracefile
, nb_control
, nb_per_cpu
, nb_facility
, nb_event
;
1364 LttvTracesetSelector
* s
;
1365 LttvTraceSelector
* trace
;
1366 LttvTracefileSelector
* tracefile
;
1367 LttvEventtypeSelector
* eventtype
;
1373 w
= gtk_multivpaned_get_first_widget(GTK_MULTIVPANED(paned
));
1375 s
= g_object_get_data(G_OBJECT(w
), "Traceset_Selector");
1378 trace
= lttv_trace_selector_new(t
);
1379 lttv_traceset_selector_trace_add(s
, trace
);
1381 nb_facility
= ltt_trace_facility_number(t
);
1382 for(k
=0;k
<nb_facility
;k
++){
1383 fac
= ltt_trace_facility_get(t
,k
);
1384 nb_event
= (int) ltt_facility_eventtype_number(fac
);
1385 for(m
=0;m
<nb_event
;m
++){
1386 et
= ltt_facility_eventtype_get(fac
,m
);
1387 eventtype
= lttv_eventtype_selector_new(et
);
1388 lttv_trace_selector_eventtype_add(trace
, eventtype
);
1392 nb_control
= ltt_trace_control_tracefile_number(t
);
1393 nb_per_cpu
= ltt_trace_per_cpu_tracefile_number(t
);
1394 nb_tracefile
= nb_control
+ nb_per_cpu
;
1396 for(j
= 0 ; j
< nb_tracefile
; j
++) {
1398 tf
= ltt_trace_control_tracefile_get(t
, j
);
1400 tf
= ltt_trace_per_cpu_tracefile_get(t
, j
- nb_control
);
1401 tracefile
= lttv_tracefile_selector_new(tf
);
1402 lttv_trace_selector_tracefile_add(trace
, tracefile
);
1403 lttv_eventtype_selector_copy(trace
, tracefile
);
1405 }else g_warning("Module does not support filtering\n");
1407 w
= gtk_multivpaned_get_next_widget(GTK_MULTIVPANED(paned
));
1412 static void lttvwindow_add_trace(Tab
*tab
, LttvTrace
*trace_v
)
1414 LttvTraceset
*traceset
= tab
->traceset_info
->traceset
;
1416 guint num_traces
= lttv_traceset_number(traceset
);
1418 //Verify if trace is already present.
1419 for(i
=0; i
<num_traces
; i
++)
1421 LttvTrace
* trace
= lttv_traceset_get(traceset
, i
);
1422 if(trace
== trace_v
)
1426 //Keep a reference to the traces so they are not freed.
1427 for(i
=0; i
<lttv_traceset_number(traceset
); i
++)
1429 LttvTrace
* trace
= lttv_traceset_get(traceset
, i
);
1430 lttv_trace_ref(trace
);
1433 //remove state update hooks
1434 lttv_state_remove_event_hooks(
1435 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1437 lttv_context_fini(LTTV_TRACESET_CONTEXT(
1438 tab
->traceset_info
->traceset_context
));
1439 g_object_unref(tab
->traceset_info
->traceset_context
);
1441 lttv_traceset_add(traceset
, trace_v
);
1442 lttv_trace_ref(trace_v
); /* local ref */
1444 /* Create new context */
1445 tab
->traceset_info
->traceset_context
=
1446 g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
1448 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->
1453 //add state update hooks
1454 lttv_state_add_event_hooks(
1455 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1456 //Remove local reference to the traces.
1457 for(i
=0; i
<lttv_traceset_number(traceset
); i
++)
1459 LttvTrace
* trace
= lttv_traceset_get(traceset
, i
);
1460 lttv_trace_unref(trace
);
1464 //add_trace_into_traceset_selector(GTK_MULTIVPANED(tab->multivpaned), lttv_trace(trace_v));
1467 /* add_trace adds a trace into the current traceset. It first displays a
1468 * directory selection dialogue to let user choose a trace, then recreates
1469 * tracset_context, and redraws all the viewer of the current tab
1472 void add_trace(GtkWidget
* widget
, gpointer user_data
)
1475 LttvTrace
* trace_v
;
1476 LttvTraceset
* traceset
;
1478 char abs_path
[PATH_MAX
];
1481 MainWindow
* mw_data
= get_window_data_struct(widget
);
1482 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
1484 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
1485 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
1489 tab
= create_new_tab(widget
, NULL
);
1491 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
1494 GtkDirSelection
* file_selector
= (GtkDirSelection
*)gtk_dir_selection_new("Select a trace");
1495 gtk_dir_selection_hide_fileop_buttons(file_selector
);
1497 if(remember_trace_dir
[0] != '\0')
1498 gtk_dir_selection_set_filename(file_selector
, remember_trace_dir
);
1500 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
1502 case GTK_RESPONSE_ACCEPT
:
1503 case GTK_RESPONSE_OK
:
1504 dir
= gtk_dir_selection_get_dir (file_selector
);
1505 strncpy(remember_trace_dir
, dir
, PATH_MAX
);
1506 if(!dir
|| strlen(dir
) == 0){
1507 gtk_widget_destroy((GtkWidget
*)file_selector
);
1510 get_absolute_pathname(dir
, abs_path
);
1511 trace_v
= lttvwindowtraces_get_trace_by_name(abs_path
);
1512 if(trace_v
== NULL
) {
1513 trace
= ltt_trace_open(abs_path
);
1515 g_warning("cannot open trace %s", abs_path
);
1517 trace_v
= lttv_trace_new(trace
);
1518 lttvwindowtraces_add_trace(trace_v
);
1519 lttvwindow_add_trace(tab
, trace_v
);
1522 lttvwindow_add_trace(tab
, trace_v
);
1525 gtk_widget_destroy((GtkWidget
*)file_selector
);
1527 //update current tab
1528 //update_traceset(mw_data);
1530 /* Call the updatetraceset hooks */
1532 traceset
= tab
->traceset_info
->traceset
;
1533 SetTraceset(tab
, traceset
);
1534 // in expose now call_pending_read_hooks(mw_data);
1536 //lttvwindow_report_current_time(mw_data,&(tab->current_time));
1538 case GTK_RESPONSE_REJECT
:
1539 case GTK_RESPONSE_CANCEL
:
1541 gtk_widget_destroy((GtkWidget
*)file_selector
);
1547 /* remove_trace_into_traceset_selector, each instance of a viewer has an associated
1548 * selector (filter), when a trace is remove from traceset, the selector should
1549 * reflect the change. The function is used to update the selector
1552 void remove_trace_from_traceset_selector(GtkWidget
* paned
, unsigned i
)
1554 LttvTracesetSelector
* s
;
1555 LttvTraceSelector
* t
;
1558 w
= gtk_multivpaned_get_first_widget(GTK_MULTIVPANED(paned
));
1560 s
= g_object_get_data(G_OBJECT(w
), "Traceset_Selector");
1562 t
= lttv_traceset_selector_trace_get(s
,i
);
1563 lttv_traceset_selector_trace_remove(s
, i
);
1564 lttv_trace_selector_destroy(t
);
1565 }g_warning("Module dose not support filtering\n");
1566 w
= gtk_multivpaned_get_next_widget(GTK_MULTIVPANED(paned
));
1571 /* remove_trace removes a trace from the current traceset if all viewers in
1572 * the current tab are not interested in the trace. It first displays a
1573 * dialogue, which shows all traces in the current traceset, to let user choose
1574 * a trace, then it checks if all viewers unselect the trace, if it is true,
1575 * it will remove the trace, recreate the traceset_contex,
1576 * and redraws all the viewer of the current tab. If there is on trace in the
1577 * current traceset, it will delete all viewers of the current tab
1580 // MD : no filter version.
1581 void remove_trace(GtkWidget
*widget
, gpointer user_data
)
1584 LttvTrace
* trace_v
;
1585 LttvTraceset
* traceset
;
1586 gint i
, j
, nb_trace
, index
=-1;
1587 char ** name
, *remove_trace_name
;
1588 MainWindow
* mw_data
= get_window_data_struct(widget
);
1589 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
1591 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
1592 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
1598 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
1601 nb_trace
=lttv_traceset_number(tab
->traceset_info
->traceset
);
1602 name
= g_new(char*,nb_trace
);
1603 for(i
= 0; i
< nb_trace
; i
++){
1604 trace_v
= lttv_traceset_get(tab
->traceset_info
->traceset
, i
);
1605 trace
= lttv_trace(trace_v
);
1606 name
[i
] = ltt_trace_name(trace
);
1609 remove_trace_name
= get_remove_trace(name
, nb_trace
);
1612 if(remove_trace_name
){
1614 /* yuk, cut n paste from old code.. should be better (MD)*/
1615 for(i
= 0; i
<nb_trace
; i
++) {
1616 if(strcmp(remove_trace_name
,name
[i
]) == 0){
1621 traceset
= tab
->traceset_info
->traceset
;
1622 //Keep a reference to the traces so they are not freed.
1623 for(j
=0; j
<lttv_traceset_number(traceset
); j
++)
1625 LttvTrace
* trace
= lttv_traceset_get(traceset
, j
);
1626 lttv_trace_ref(trace
);
1629 //remove state update hooks
1630 lttv_state_remove_event_hooks(
1631 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1632 lttv_context_fini(LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
));
1633 g_object_unref(tab
->traceset_info
->traceset_context
);
1635 trace_v
= lttv_traceset_get(traceset
, index
);
1637 lttv_traceset_remove(traceset
, index
);
1638 lttv_trace_unref(trace_v
); // Remove local reference
1640 if(lttv_trace_get_ref_number(trace_v
) <= 1) {
1641 /* ref 1 : lttvwindowtraces only*/
1642 ltt_trace_close(lttv_trace(trace_v
));
1643 /* lttvwindowtraces_remove_trace takes care of destroying
1644 * the traceset linked with the trace_v and also of destroying
1645 * the trace_v at the same time.
1647 lttvwindowtraces_remove_trace(trace_v
);
1650 tab
->traceset_info
->traceset_context
=
1651 g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
1653 LTTV_TRACESET_CONTEXT(tab
->
1654 traceset_info
->traceset_context
),traceset
);
1655 //add state update hooks
1656 lttv_state_add_event_hooks(
1657 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1659 //Remove local reference to the traces.
1660 for(j
=0; j
<lttv_traceset_number(traceset
); j
++)
1662 LttvTrace
* trace
= lttv_traceset_get(traceset
, j
);
1663 lttv_trace_unref(trace
);
1666 SetTraceset(tab
, (gpointer
)traceset
);
1672 void remove_trace(GtkWidget
* widget
, gpointer user_data
)
1675 LttvTrace
* trace_v
;
1676 LttvTraceset
* traceset
;
1677 gint i
, j
, nb_trace
;
1678 char ** name
, *remove_trace_name
;
1679 MainWindow
* mw_data
= get_window_data_struct(widget
);
1680 LttvTracesetSelector
* s
;
1681 LttvTraceSelector
* t
;
1684 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
1686 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
1687 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
1693 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
1696 nb_trace
=lttv_traceset_number(tab
->traceset_info
->traceset
);
1697 name
= g_new(char*,nb_trace
);
1698 for(i
= 0; i
< nb_trace
; i
++){
1699 trace_v
= lttv_traceset_get(tab
->traceset_info
->traceset
, i
);
1700 trace
= lttv_trace(trace_v
);
1701 name
[i
] = ltt_trace_name(trace
);
1704 remove_trace_name
= get_remove_trace(name
, nb_trace
);
1706 if(remove_trace_name
){
1707 for(i
=0; i
<nb_trace
; i
++){
1708 if(strcmp(remove_trace_name
,name
[i
]) == 0){
1709 //unselect the trace from the current viewer
1711 w
= gtk_multivpaned_get_widget(GTK_MULTIVPANED(tab
->multivpaned
));
1713 s
= g_object_get_data(G_OBJECT(w
), "Traceset_Selector");
1715 t
= lttv_traceset_selector_trace_get(s
,i
);
1716 lttv_trace_selector_set_selected(t
, FALSE
);
1719 //check if other viewers select the trace
1720 w
= gtk_multivpaned_get_first_widget(GTK_MULTIVPANED(tab
->multivpaned
));
1722 s
= g_object_get_data(G_OBJECT(w
), "Traceset_Selector");
1724 t
= lttv_traceset_selector_trace_get(s
,i
);
1725 selected
= lttv_trace_selector_get_selected(t
);
1728 w
= gtk_multivpaned_get_next_widget(GTK_MULTIVPANED(tab
->multivpaned
));
1730 }else selected
= FALSE
;
1732 //if no viewer selects the trace, remove it
1734 remove_trace_from_traceset_selector(GTK_MULTIVPANED(tab
->multivpaned
), i
);
1736 traceset
= tab
->traceset_info
->traceset
;
1737 //Keep a reference to the traces so they are not freed.
1738 for(j
=0; j
<lttv_traceset_number(traceset
); j
++)
1740 LttvTrace
* trace
= lttv_traceset_get(traceset
, j
);
1741 lttv_trace_ref(trace
);
1744 //remove state update hooks
1745 lttv_state_remove_event_hooks(
1746 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1747 lttv_context_fini(LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
));
1748 g_object_unref(tab
->traceset_info
->traceset_context
);
1751 trace_v
= lttv_traceset_get(traceset
, i
);
1753 if(lttv_trace_get_ref_number(trace_v
) <= 2) {
1754 /* ref 2 : traceset, local */
1755 lttvwindowtraces_remove_trace(trace_v
);
1756 ltt_trace_close(lttv_trace(trace_v
));
1759 lttv_traceset_remove(traceset
, i
);
1760 lttv_trace_unref(trace_v
); // Remove local reference
1762 if(!lttv_trace_get_ref_number(trace_v
))
1763 lttv_trace_destroy(trace_v
);
1765 tab
->traceset_info
->traceset_context
=
1766 g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
1768 LTTV_TRACESET_CONTEXT(tab
->
1769 traceset_info
->traceset_context
),traceset
);
1770 //add state update hooks
1771 lttv_state_add_event_hooks(
1772 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1774 //Remove local reference to the traces.
1775 for(j
=0; j
<lttv_traceset_number(traceset
); j
++)
1777 LttvTrace
* trace
= lttv_traceset_get(traceset
, j
);
1778 lttv_trace_unref(trace
);
1782 //update current tab
1783 //update_traceset(mw_data);
1786 SetTraceset(tab
, (gpointer
)traceset
);
1787 // in expose now call_pending_read_hooks(mw_data);
1789 //lttvwindow_report_current_time(mw_data,&(tab->current_time));
1792 // while(tab->multi_vpaned->num_children){
1793 // gtk_multi_vpaned_widget_delete(tab->multi_vpaned);
1807 /* Redraw all the viewers in the current tab */
1808 void redraw(GtkWidget
*widget
, gpointer user_data
)
1810 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
1811 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
1812 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
1817 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
1821 LttvAttributeValue value
;
1823 g_assert(lttv_iattribute_find_by_path(tab
->attributes
, "hooks/redraw", LTTV_POINTER
, &value
));
1825 tmp
= (LttvHooks
*)*(value
.v_pointer
);
1827 lttv_hooks_call(tmp
,NULL
);
1831 void continue_processing(GtkWidget
*widget
, gpointer user_data
)
1833 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
1834 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
1835 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
1840 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
1844 LttvAttributeValue value
;
1846 g_assert(lttv_iattribute_find_by_path(tab
->attributes
,
1847 "hooks/continue", LTTV_POINTER
, &value
));
1849 tmp
= (LttvHooks
*)*(value
.v_pointer
);
1851 lttv_hooks_call(tmp
,NULL
);
1854 /* Stop the processing for the calling main window's current tab.
1855 * It removes every processing requests that are in its list. It does not call
1856 * the end request hooks, because the request is not finished.
1859 void stop_processing(GtkWidget
*widget
, gpointer user_data
)
1861 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
1862 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
1863 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
1868 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
1870 GSList
*iter
= tab
->events_requests
;
1872 while(iter
!= NULL
) {
1873 GSList
*remove_iter
= iter
;
1874 iter
= g_slist_next(iter
);
1876 g_free(remove_iter
->data
);
1877 tab
->events_requests
=
1878 g_slist_remove_link(tab
->events_requests
, remove_iter
);
1880 tab
->events_request_pending
= FALSE
;
1881 g_idle_remove_by_data(tab
);
1882 g_assert(g_slist_length(tab
->events_requests
) == 0);
1886 /* save will save the traceset to a file
1887 * Not implemented yet FIXME
1890 void save(GtkWidget
* widget
, gpointer user_data
)
1895 void save_as(GtkWidget
* widget
, gpointer user_data
)
1897 g_printf("Save as\n");
1901 /* zoom will change the time_window of all the viewers of the
1902 * current tab, and redisplay them. The main functionality is to
1903 * determine the new time_window of the current tab
1906 void zoom(GtkWidget
* widget
, double size
)
1908 TimeInterval time_span
;
1909 TimeWindow new_time_window
;
1910 LttTime current_time
, time_delta
, time_s
, time_e
, time_tmp
;
1911 MainWindow
* mw_data
= get_window_data_struct(widget
);
1912 LttvTracesetContext
*tsc
;
1913 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
1915 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
1916 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
1922 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
1925 if(size
== 1) return;
1927 tsc
= LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
1928 time_span
= tsc
->time_span
;
1929 new_time_window
= tab
->time_window
;
1930 current_time
= tab
->current_time
;
1932 time_delta
= ltt_time_sub(time_span
.end_time
,time_span
.start_time
);
1934 new_time_window
.start_time
= time_span
.start_time
;
1935 new_time_window
.time_width
= time_delta
;
1937 new_time_window
.time_width
= ltt_time_div(new_time_window
.time_width
, size
);
1938 if(ltt_time_compare(new_time_window
.time_width
,time_delta
) > 0)
1939 { /* Case where zoom out is bigger than trace length */
1940 new_time_window
.start_time
= time_span
.start_time
;
1941 new_time_window
.time_width
= time_delta
;
1945 /* Center the image on the current time */
1946 new_time_window
.start_time
=
1947 ltt_time_sub(current_time
, ltt_time_div(new_time_window
.time_width
, 2.0));
1948 /* If on borders, don't fall off */
1949 if(ltt_time_compare(new_time_window
.start_time
, time_span
.start_time
) <0)
1951 new_time_window
.start_time
= time_span
.start_time
;
1955 if(ltt_time_compare(
1956 ltt_time_add(new_time_window
.start_time
, new_time_window
.time_width
),
1957 time_span
.end_time
) > 0)
1959 new_time_window
.start_time
=
1960 ltt_time_sub(time_span
.end_time
, new_time_window
.time_width
);
1966 //time_tmp = ltt_time_div(new_time_window.time_width, 2);
1967 //if(ltt_time_compare(current_time, time_tmp) < 0){
1968 // time_s = time_span->startTime;
1970 // time_s = ltt_time_sub(current_time,time_tmp);
1972 //time_e = ltt_time_add(current_time,time_tmp);
1973 //if(ltt_time_compare(time_span->startTime, time_s) > 0){
1974 // time_s = time_span->startTime;
1975 //}else if(ltt_time_compare(time_span->endTime, time_e) < 0){
1976 // time_e = time_span->endTime;
1977 // time_s = ltt_time_sub(time_e,new_time_window.time_width);
1979 //new_time_window.start_time = time_s;
1982 //lttvwindow_report_time_window(mw_data, &new_time_window);
1983 //call_pending_read_hooks(mw_data);
1985 //lttvwindow_report_current_time(mw_data,&(tab->current_time));
1986 //set_time_window(tab, &new_time_window);
1987 // in expose now call_pending_read_hooks(mw_data);
1988 //gtk_multi_vpaned_set_adjust(tab->multi_vpaned, &new_time_window, FALSE);
1993 ltt_time_sub(new_time_window
.start_time
, time_span
.start_time
);
1994 if( ltt_time_to_double(new_time_window
.time_width
)
1995 * NANOSECONDS_PER_SECOND
1996 / SCROLL_STEP_PER_PAGE
/* step increment */
1998 ltt_time_to_double(rel_time
) * NANOSECONDS_PER_SECOND
/* page size */
2000 ltt_time_to_double(rel_time
) * NANOSECONDS_PER_SECOND
/* page size */
2002 g_warning("Can not zoom that far due to scrollbar precision");
2005 ltt_time_from_double(
2006 ltt_time_to_double(new_time_window
.time_width
)
2007 /SCROLL_STEP_PER_PAGE
),
2010 g_warning("Can not zoom that far due to time nanosecond precision");
2013 GtkAdjustment
*adjustment
= gtk_range_get_adjustment(GTK_RANGE(tab
->scrollbar
));
2015 g_object_set(G_OBJECT(adjustment
),
2017 //ltt_time_to_double(new_time_window.start_time)
2018 // * NANOSECONDS_PER_SECOND, /* value */
2023 ltt_time_sub(time_span
.end_time
, time_span
.start_time
))
2024 * NANOSECONDS_PER_SECOND
, /* upper */
2026 ltt_time_to_double(new_time_window
.time_width
)
2027 / SCROLL_STEP_PER_PAGE
2028 * NANOSECONDS_PER_SECOND
, /* step increment */
2030 ltt_time_to_double(new_time_window
.time_width
)
2031 * NANOSECONDS_PER_SECOND
, /* page increment */
2033 ltt_time_to_double(new_time_window
.time_width
)
2034 * NANOSECONDS_PER_SECOND
, /* page size */
2036 gtk_adjustment_changed(adjustment
);
2037 //gtk_range_set_adjustment(GTK_RANGE(tab->scrollbar), adjustment);
2038 //gtk_adjustment_value_changed(adjustment);
2039 g_object_set(G_OBJECT(adjustment
),
2042 ltt_time_sub(new_time_window
.start_time
, time_span
.start_time
))
2043 * NANOSECONDS_PER_SECOND
, /* value */
2045 gtk_adjustment_value_changed(adjustment
);
2048 //g_object_set(G_OBJECT(adjustment),
2050 // ltt_time_to_double(time_window->start_time)
2051 // * NANOSECONDS_PER_SECOND, /* value */
2053 /* Note : the set value will call set_time_window if scrollbar value changed
2055 //gtk_adjustment_set_value(adjustment,
2056 // ltt_time_to_double(new_time_window.start_time)
2057 // * NANOSECONDS_PER_SECOND);
2061 void zoom_in(GtkWidget
* widget
, gpointer user_data
)
2066 void zoom_out(GtkWidget
* widget
, gpointer user_data
)
2071 void zoom_extended(GtkWidget
* widget
, gpointer user_data
)
2076 void go_to_time(GtkWidget
* widget
, gpointer user_data
)
2078 g_printf("Go to time\n");
2081 void show_time_frame(GtkWidget
* widget
, gpointer user_data
)
2083 g_printf("Show time frame\n");
2087 /* callback function */
2090 on_empty_traceset_activate (GtkMenuItem
*menuitem
,
2093 create_new_window((GtkWidget
*)menuitem
, user_data
, FALSE
);
2098 on_clone_traceset_activate (GtkMenuItem
*menuitem
,
2101 create_new_window((GtkWidget
*)menuitem
, user_data
, TRUE
);
2105 /* create_new_tab calls create_tab to construct a new tab in the main window
2108 Tab
*create_new_tab(GtkWidget
* widget
, gpointer user_data
){
2109 gchar label
[PATH_MAX
];
2110 MainWindow
* mw_data
= get_window_data_struct(widget
);
2112 GtkNotebook
* notebook
= (GtkNotebook
*)lookup_widget(widget
, "MNotebook");
2113 if(notebook
== NULL
){
2114 g_printf("Notebook does not exist\n");
2117 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2118 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2124 copy_tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
2127 strcpy(label
,"Page");
2128 if(get_label(mw_data
, label
,"Get the name of the tab","Please input tab's name"))
2129 return (create_tab (mw_data
, copy_tab
, notebook
, label
));
2133 on_tab_activate (GtkMenuItem
*menuitem
,
2136 create_new_tab((GtkWidget
*)menuitem
, user_data
);
2141 on_open_activate (GtkMenuItem
*menuitem
,
2144 open_traceset((GtkWidget
*)menuitem
, user_data
);
2149 on_close_activate (GtkMenuItem
*menuitem
,
2152 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2153 main_window_destructor(mw_data
);
2157 /* remove the current tab from the main window
2161 on_close_tab_activate (GtkWidget
*widget
,
2165 GtkWidget
* notebook
;
2167 MainWindow
* mw_data
= get_window_data_struct(widget
);
2168 notebook
= lookup_widget(widget
, "MNotebook");
2169 if(notebook
== NULL
){
2170 g_printf("Notebook does not exist\n");
2174 page_num
= gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
));
2176 gtk_notebook_remove_page(GTK_NOTEBOOK(notebook
), page_num
);
2181 on_close_tab_X_clicked (GtkWidget
*widget
,
2185 GtkWidget
*notebook
= lookup_widget(widget
, "MNotebook");
2186 if(notebook
== NULL
){
2187 g_printf("Notebook does not exist\n");
2191 if((page_num
= gtk_notebook_page_num(GTK_NOTEBOOK(notebook
), widget
)) != -1)
2192 gtk_notebook_remove_page(GTK_NOTEBOOK(notebook
), page_num
);
2198 on_add_trace_activate (GtkMenuItem
*menuitem
,
2201 add_trace((GtkWidget
*)menuitem
, user_data
);
2206 on_remove_trace_activate (GtkMenuItem
*menuitem
,
2209 remove_trace((GtkWidget
*)menuitem
, user_data
);
2214 on_save_activate (GtkMenuItem
*menuitem
,
2217 save((GtkWidget
*)menuitem
, user_data
);
2222 on_save_as_activate (GtkMenuItem
*menuitem
,
2225 save_as((GtkWidget
*)menuitem
, user_data
);
2230 on_quit_activate (GtkMenuItem
*menuitem
,
2238 on_cut_activate (GtkMenuItem
*menuitem
,
2246 on_copy_activate (GtkMenuItem
*menuitem
,
2249 g_printf("Copye\n");
2254 on_paste_activate (GtkMenuItem
*menuitem
,
2257 g_printf("Paste\n");
2262 on_delete_activate (GtkMenuItem
*menuitem
,
2265 g_printf("Delete\n");
2270 on_zoom_in_activate (GtkMenuItem
*menuitem
,
2273 zoom_in((GtkWidget
*)menuitem
, user_data
);
2278 on_zoom_out_activate (GtkMenuItem
*menuitem
,
2281 zoom_out((GtkWidget
*)menuitem
, user_data
);
2286 on_zoom_extended_activate (GtkMenuItem
*menuitem
,
2289 zoom_extended((GtkWidget
*)menuitem
, user_data
);
2294 on_go_to_time_activate (GtkMenuItem
*menuitem
,
2297 go_to_time((GtkWidget
*)menuitem
, user_data
);
2302 on_show_time_frame_activate (GtkMenuItem
*menuitem
,
2305 show_time_frame((GtkWidget
*)menuitem
, user_data
);
2310 on_move_viewer_up_activate (GtkMenuItem
*menuitem
,
2313 move_up_viewer((GtkWidget
*)menuitem
, user_data
);
2318 on_move_viewer_down_activate (GtkMenuItem
*menuitem
,
2321 move_down_viewer((GtkWidget
*)menuitem
, user_data
);
2326 on_remove_viewer_activate (GtkMenuItem
*menuitem
,
2329 delete_viewer((GtkWidget
*)menuitem
, user_data
);
2334 on_trace_filter_activate (GtkMenuItem
*menuitem
,
2337 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2338 LttvTracesetSelector
* s
;
2340 GtkWidget
* notebook
= lookup_widget(GTK_WIDGET(menuitem
), "MNotebook");
2342 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2343 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2349 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
2352 w
= gtk_multivpaned_get_widget(GTK_MULTIVPANED(tab
->multivpaned
));
2354 s
= g_object_get_data(G_OBJECT(w
), "Traceset_Selector");
2356 g_printf("There is no viewer yet\n");
2359 if(get_filter_selection(s
, "Configure trace and tracefile filter", "Select traces and tracefiles")){
2360 //FIXME report filter change
2361 //update_traceset(mw_data);
2362 //call_pending_read_hooks(mw_data);
2363 //lttvwindow_report_current_time(mw_data,&(tab->current_time));
2369 on_trace_facility_activate (GtkMenuItem
*menuitem
,
2372 g_printf("Trace facility selector: %s\n");
2376 /* Dispaly a file selection dialogue to let user select a library, then call
2377 * lttv_library_load().
2381 on_load_library_activate (GtkMenuItem
*menuitem
,
2384 GError
*error
= NULL
;
2385 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2387 gchar load_module_path_alter
[PATH_MAX
];
2391 gchar
*load_module_path
;
2392 name
= g_ptr_array_new();
2393 nb
= lttv_library_path_number();
2394 /* ask for the library path */
2398 path
= lttv_library_path_get(i
);
2399 g_ptr_array_add(name
, path
);
2402 load_module_path
= get_selection((char **)(name
->pdata
), name
->len
,
2403 "Select a library path", "Library paths");
2404 if(load_module_path
!= NULL
)
2405 strncpy(load_module_path_alter
, load_module_path
, PATH_MAX
-1); // -1 for /
2407 g_ptr_array_free(name
, TRUE
);
2409 if(load_module_path
== NULL
) return;
2413 /* Make sure the module path ends with a / */
2414 gchar
*ptr
= load_module_path_alter
;
2416 ptr
= strchr(ptr
, '\0');
2418 if(*(ptr
-1) != '/') {
2425 /* Ask for the library to load : list files in the previously selected
2427 gchar str
[PATH_MAX
];
2430 GtkFileSelection
* file_selector
=
2431 (GtkFileSelection
*)gtk_file_selection_new("Select a module");
2432 gtk_file_selection_set_filename(file_selector
, load_module_path_alter
);
2433 gtk_file_selection_hide_fileop_buttons(file_selector
);
2436 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
2438 case GTK_RESPONSE_ACCEPT
:
2439 case GTK_RESPONSE_OK
:
2440 dir
= gtk_file_selection_get_selections (file_selector
);
2441 strncpy(str
,dir
[0],PATH_MAX
);
2442 strncpy(remember_plugins_dir
,dir
[0],PATH_MAX
);
2443 /* only keep file name */
2445 str1
= strrchr(str
,'/');
2448 str1
= strrchr(str
,'\\');
2453 if(*str1
== 'l' && *(str1
+1)== 'i' && *(str1
+2)=='b')
2455 remove info after
. */
2459 str2
= strrchr(str2
, '.');
2460 if(str2
!= NULL
) *str2
= '\0';
2462 lttv_module_require(str1
, &error
);
2464 lttv_library_load(str1
, &error
);
2465 if(error
!= NULL
) g_warning(error
->message
);
2466 else g_printf("Load library: %s\n", str
);
2468 case GTK_RESPONSE_REJECT
:
2469 case GTK_RESPONSE_CANCEL
:
2471 gtk_widget_destroy((GtkWidget
*)file_selector
);
2482 /* Display all loaded modules, let user to select a module to unload
2483 * by calling lttv_module_unload
2487 on_unload_library_activate (GtkMenuItem
*menuitem
,
2490 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2492 LttvLibrary
*library
;
2497 name
= g_ptr_array_new();
2498 nb
= lttv_library_number();
2499 LttvLibraryInfo
*lib_info
= g_new(LttvLibraryInfo
,nb
);
2500 /* ask for the library name */
2503 LttvLibrary
*iter_lib
= lttv_library_get(i
);
2504 lttv_library_info(iter_lib
, &lib_info
[i
]);
2506 gchar
*path
= lib_info
[i
].name
;
2507 g_ptr_array_add(name
, lib_info
[i
].name
);
2509 lib_name
= get_selection((char **)(name
->pdata
), name
->len
,
2510 "Select a library", "Libraries");
2511 if(lib_name
!= NULL
) {
2513 if(strcmp(lib_name
, lib_info
[i
].name
) == 0) {
2514 library
= lttv_library_get(i
);
2519 g_ptr_array_free(name
, TRUE
);
2522 if(lib_name
== NULL
) return;
2525 lttv_library_unload(library
);
2529 /* Dispaly a file selection dialogue to let user select a module, then call
2530 * lttv_module_require().
2534 on_load_module_activate (GtkMenuItem
*menuitem
,
2537 GError
*error
= NULL
;
2538 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2540 LttvLibrary
*library
;
2545 name
= g_ptr_array_new();
2546 nb
= lttv_library_number();
2547 LttvLibraryInfo
*lib_info
= g_new(LttvLibraryInfo
,nb
);
2548 /* ask for the library name */
2551 LttvLibrary
*iter_lib
= lttv_library_get(i
);
2552 lttv_library_info(iter_lib
, &lib_info
[i
]);
2554 gchar
*path
= lib_info
[i
].name
;
2555 g_ptr_array_add(name
, path
);
2557 lib_name
= get_selection((char **)(name
->pdata
), name
->len
,
2558 "Select a library", "Libraries");
2559 if(lib_name
!= NULL
) {
2561 if(strcmp(lib_name
, lib_info
[i
].name
) == 0) {
2562 library
= lttv_library_get(i
);
2567 g_ptr_array_free(name
, TRUE
);
2570 if(lib_name
== NULL
) return;
2573 //LttvModule *module;
2574 gchar module_name_out
[PATH_MAX
];
2576 /* Ask for the module to load : list modules in the selected lib */
2580 LttvModuleInfo
*module_info
= g_new(LttvModuleInfo
,nb
);
2581 name
= g_ptr_array_new();
2582 nb
= lttv_library_module_number(library
);
2583 /* ask for the module name */
2586 LttvModule
*iter_module
= lttv_library_module_get(library
, i
);
2587 lttv_module_info(iter_module
, &module_info
[i
]);
2589 gchar
*path
= module_info
[i
].name
;
2590 g_ptr_array_add(name
, path
);
2592 module_name
= get_selection((char **)(name
->pdata
), name
->len
,
2593 "Select a module", "Modules");
2594 if(module_name
!= NULL
) {
2596 if(strcmp(module_name
, module_info
[i
].name
) == 0) {
2597 strncpy(module_name_out
, module_name
, PATH_MAX
);
2598 //module = lttv_library_module_get(i);
2604 g_ptr_array_free(name
, TRUE
);
2605 g_free(module_info
);
2607 if(module_name
== NULL
) return;
2610 lttv_module_require(module_name_out
, &error
);
2611 if(error
!= NULL
) g_warning(error
->message
);
2612 else g_printf("Load module: %s\n", module_name_out
);
2619 gchar str
[PATH_MAX
];
2622 GtkFileSelection
* file_selector
=
2623 (GtkFileSelection
*)gtk_file_selection_new("Select a module");
2624 gtk_file_selection_set_filename(file_selector
, load_module_path_alter
);
2625 gtk_file_selection_hide_fileop_buttons(file_selector
);
2628 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
2630 case GTK_RESPONSE_ACCEPT
:
2631 case GTK_RESPONSE_OK
:
2632 dir
= gtk_file_selection_get_selections (file_selector
);
2633 strncpy(str
,dir
[0],PATH_MAX
);
2634 strncpy(remember_plugins_dir
,dir
[0],PATH_MAX
);
2636 /* only keep file name */
2638 str1
= strrchr(str
,'/');
2641 str1
= strrchr(str
,'\\');
2646 if(*str1
== 'l' && *(str1
+1)== 'i' && *(str1
+2)=='b')
2648 remove info after
. */
2652 str2
= strrchr(str2
, '.');
2653 if(str2
!= NULL
) *str2
= '\0';
2655 lttv_module_require(str1
, &error
);
2657 lttv_library_load(str1
, &error
);
2658 if(error
!= NULL
) g_warning(error
->message
);
2659 else g_printf("Load library: %s\n", str
);
2661 case GTK_RESPONSE_REJECT
:
2662 case GTK_RESPONSE_CANCEL
:
2664 gtk_widget_destroy((GtkWidget
*)file_selector
);
2676 /* Display all loaded modules, let user to select a module to unload
2677 * by calling lttv_module_unload
2681 on_unload_module_activate (GtkMenuItem
*menuitem
,
2684 GError
*error
= NULL
;
2685 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2687 LttvLibrary
*library
;
2692 name
= g_ptr_array_new();
2693 nb
= lttv_library_number();
2694 LttvLibraryInfo
*lib_info
= g_new(LttvLibraryInfo
,nb
);
2695 /* ask for the library name */
2698 LttvLibrary
*iter_lib
= lttv_library_get(i
);
2699 lttv_library_info(iter_lib
, &lib_info
[i
]);
2701 gchar
*path
= lib_info
[i
].name
;
2702 g_ptr_array_add(name
, path
);
2704 lib_name
= get_selection((char **)(name
->pdata
), name
->len
,
2705 "Select a library", "Libraries");
2706 if(lib_name
!= NULL
) {
2708 if(strcmp(lib_name
, lib_info
[i
].name
) == 0) {
2709 library
= lttv_library_get(i
);
2714 g_ptr_array_free(name
, TRUE
);
2717 if(lib_name
== NULL
) return;
2722 /* Ask for the module to load : list modules in the selected lib */
2726 nb
= lttv_library_module_number(library
);
2727 LttvModuleInfo
*module_info
= g_new(LttvModuleInfo
,nb
);
2728 name
= g_ptr_array_new();
2729 /* ask for the module name */
2732 LttvModule
*iter_module
= lttv_library_module_get(library
, i
);
2733 lttv_module_info(iter_module
, &module_info
[i
]);
2735 gchar
*path
= module_info
[i
].name
;
2736 if(module_info
[i
].use_count
> 0) g_ptr_array_add(name
, path
);
2738 module_name
= get_selection((char **)(name
->pdata
), name
->len
,
2739 "Select a module", "Modules");
2740 if(module_name
!= NULL
) {
2742 if(strcmp(module_name
, module_info
[i
].name
) == 0) {
2743 module
= lttv_library_module_get(library
, i
);
2749 g_ptr_array_free(name
, TRUE
);
2750 g_free(module_info
);
2752 if(module_name
== NULL
) return;
2755 LttvModuleInfo module_info
;
2756 lttv_module_info(module
, &module_info
);
2757 g_printf("Release module: %s\n", module_info
.name
);
2759 lttv_module_release(module
);
2763 /* Display a directory dialogue to let user select a path for library searching
2767 on_add_library_search_path_activate (GtkMenuItem
*menuitem
,
2770 GtkDirSelection
* file_selector
= (GtkDirSelection
*)gtk_dir_selection_new("Select library path");
2774 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2775 if(remember_plugins_dir
[0] != '\0')
2776 gtk_dir_selection_set_filename(file_selector
, remember_plugins_dir
);
2778 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
2780 case GTK_RESPONSE_ACCEPT
:
2781 case GTK_RESPONSE_OK
:
2782 dir
= gtk_dir_selection_get_dir (file_selector
);
2783 strncpy(remember_plugins_dir
,dir
,PATH_MAX
);
2784 strncat(remember_plugins_dir
,"/",PATH_MAX
);
2785 lttv_library_path_add(dir
);
2786 case GTK_RESPONSE_REJECT
:
2787 case GTK_RESPONSE_CANCEL
:
2789 gtk_widget_destroy((GtkWidget
*)file_selector
);
2795 /* Display a directory dialogue to let user select a path for library searching
2799 on_remove_library_search_path_activate (GtkMenuItem
*menuitem
,
2802 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2804 const char *lib_path
;
2809 name
= g_ptr_array_new();
2810 nb
= lttv_library_path_number();
2811 /* ask for the library name */
2814 gchar
*path
= lttv_library_path_get(i
);
2815 g_ptr_array_add(name
, path
);
2817 lib_path
= get_selection((char **)(name
->pdata
), name
->len
,
2818 "Select a library path", "Library paths");
2820 g_ptr_array_free(name
, TRUE
);
2822 if(lib_path
== NULL
) return;
2825 lttv_library_path_remove(lib_path
);
2829 on_color_activate (GtkMenuItem
*menuitem
,
2832 g_printf("Color\n");
2837 on_filter_activate (GtkMenuItem
*menuitem
,
2840 g_printf("Filter\n");
2845 on_save_configuration_activate (GtkMenuItem
*menuitem
,
2848 g_printf("Save configuration\n");
2853 on_content_activate (GtkMenuItem
*menuitem
,
2856 g_printf("Content\n");
2861 on_about_close_activate (GtkButton
*button
,
2864 GtkWidget
*about_widget
= GTK_WIDGET(user_data
);
2866 gtk_widget_destroy(about_widget
);
2870 on_about_activate (GtkMenuItem
*menuitem
,
2873 MainWindow
*main_window
= get_window_data_struct(GTK_WIDGET(menuitem
));
2874 GtkWidget
*window_widget
= main_window
->mwindow
;
2875 GtkWidget
*about_widget
= gtk_window_new(GTK_WINDOW_TOPLEVEL
);
2876 GtkWindow
*about_window
= GTK_WINDOW(about_widget
);
2877 gint window_width
, window_height
;
2879 gtk_window_set_title(about_window
, "About Linux Trace Toolkit");
2881 gtk_window_set_resizable(about_window
, FALSE
);
2882 gtk_window_set_transient_for(GTK_WINDOW(window_widget
), about_window
);
2883 gtk_window_set_destroy_with_parent(about_window
, TRUE
);
2884 gtk_window_set_modal(about_window
, FALSE
);
2886 /* Put the about window at the center of the screen */
2887 gtk_window_get_size(about_window
, &window_width
, &window_height
);
2888 gtk_window_move (about_window
,
2889 (gdk_screen_width() - window_width
)/2,
2890 (gdk_screen_height() - window_height
)/2);
2892 GtkWidget
*vbox
= gtk_vbox_new(FALSE
, 1);
2894 gtk_container_add(GTK_CONTAINER(about_widget
), vbox
);
2898 GtkWidget
*label1
= gtk_label_new("");
2899 gtk_misc_set_padding(GTK_MISC(label1
), 10, 20);
2900 gtk_label_set_markup(GTK_LABEL(label1
), "\
2901 <big>Linux Trace Toolkit</big>");
2902 gtk_label_set_justify(GTK_LABEL(label1
), GTK_JUSTIFY_CENTER
);
2904 GtkWidget
*label2
= gtk_label_new("");
2905 gtk_misc_set_padding(GTK_MISC(label2
), 10, 20);
2906 gtk_label_set_markup(GTK_LABEL(label2
), "\
2907 Project author: Karim Yaghmour\n\
2911 Michel Dagenais (New trace format, lttv main)\n\
2912 Mathieu Desnoyers (Directory structure, build with automake/conf,\n\
2913 lttv gui, control flow view, gui green threads\n\
2914 with interruptible foreground and background computation,\n\
2915 detailed event list)\n\
2916 Benoit Des Ligneris (Cluster adaptation)\n\
2917 Xang-Xiu Yang (new trace reading library and converter, lttv gui, \n\
2918 detailed event list and statistics view)\n\
2919 Tom Zanussi (RelayFS)");
2921 GtkWidget
*label3
= gtk_label_new("");
2922 gtk_label_set_markup(GTK_LABEL(label3
), "\
2923 Linux Trace Toolkit, Copyright (C) 2004 Karim Yaghmour\n\
2924 Linux Trace Toolkit comes with ABSOLUTELY NO WARRANTY.\n\
2925 This is free software, and you are welcome to redistribute it\n\
2926 under certain conditions. See COPYING for details.");
2927 gtk_misc_set_padding(GTK_MISC(label3
), 10, 20);
2929 gtk_box_pack_start_defaults(GTK_BOX(vbox
), label1
);
2930 gtk_box_pack_start_defaults(GTK_BOX(vbox
), label2
);
2931 gtk_box_pack_start_defaults(GTK_BOX(vbox
), label3
);
2933 GtkWidget
*hbox
= gtk_hbox_new(TRUE
, 0);
2934 gtk_box_pack_end(GTK_BOX(vbox
), hbox
, FALSE
, FALSE
, 0);
2935 GtkWidget
*close_button
= gtk_button_new_with_mnemonic("_Close");
2936 gtk_box_pack_end(GTK_BOX(hbox
), close_button
, FALSE
, FALSE
, 0);
2937 gtk_container_set_border_width(GTK_CONTAINER(close_button
), 20);
2939 g_signal_connect(G_OBJECT(close_button
), "clicked",
2940 G_CALLBACK(on_about_close_activate
),
2941 (gpointer
)about_widget
);
2943 gtk_widget_show_all(about_widget
);
2948 on_button_new_clicked (GtkButton
*button
,
2951 create_new_window((GtkWidget
*)button
, user_data
, TRUE
);
2955 on_button_new_tab_clicked (GtkButton
*button
,
2958 create_new_tab((GtkWidget
*)button
, user_data
);
2962 on_button_open_clicked (GtkButton
*button
,
2965 open_traceset((GtkWidget
*)button
, user_data
);
2970 on_button_add_trace_clicked (GtkButton
*button
,
2973 add_trace((GtkWidget
*)button
, user_data
);
2978 on_button_remove_trace_clicked (GtkButton
*button
,
2981 remove_trace((GtkWidget
*)button
, user_data
);
2985 on_button_redraw_clicked (GtkButton
*button
,
2988 redraw((GtkWidget
*)button
, user_data
);
2992 on_button_continue_processing_clicked (GtkButton
*button
,
2995 continue_processing((GtkWidget
*)button
, user_data
);
2999 on_button_stop_processing_clicked (GtkButton
*button
,
3002 stop_processing((GtkWidget
*)button
, user_data
);
3008 on_button_save_clicked (GtkButton
*button
,
3011 save((GtkWidget
*)button
, user_data
);
3016 on_button_save_as_clicked (GtkButton
*button
,
3019 save_as((GtkWidget
*)button
, user_data
);
3024 on_button_zoom_in_clicked (GtkButton
*button
,
3027 zoom_in((GtkWidget
*)button
, user_data
);
3032 on_button_zoom_out_clicked (GtkButton
*button
,
3035 zoom_out((GtkWidget
*)button
, user_data
);
3040 on_button_zoom_extended_clicked (GtkButton
*button
,
3043 zoom_extended((GtkWidget
*)button
, user_data
);
3048 on_button_go_to_time_clicked (GtkButton
*button
,
3051 go_to_time((GtkWidget
*)button
, user_data
);
3056 on_button_show_time_frame_clicked (GtkButton
*button
,
3059 show_time_frame((GtkWidget
*)button
, user_data
);
3064 on_button_move_up_clicked (GtkButton
*button
,
3067 move_up_viewer((GtkWidget
*)button
, user_data
);
3072 on_button_move_down_clicked (GtkButton
*button
,
3075 move_down_viewer((GtkWidget
*)button
, user_data
);
3080 on_button_delete_viewer_clicked (GtkButton
*button
,
3083 delete_viewer((GtkWidget
*)button
, user_data
);
3087 on_MWindow_destroy (GtkWidget
*widget
,
3090 MainWindow
*main_window
= get_window_data_struct(widget
);
3091 LttvIAttribute
*attributes
= main_window
->attributes
;
3092 LttvAttributeValue value
;
3094 //This is unnecessary, since widgets will be destroyed
3095 //by the main window widget anyway.
3096 //remove_all_menu_toolbar_constructors(main_window, NULL);
3098 g_assert(lttv_iattribute_find_by_path(attributes
,
3099 "viewers/menu", LTTV_POINTER
, &value
));
3100 lttv_menus_destroy((LttvMenus
*)*(value
.v_pointer
));
3102 g_assert(lttv_iattribute_find_by_path(attributes
,
3103 "viewers/toolbar", LTTV_POINTER
, &value
));
3104 lttv_toolbars_destroy((LttvToolbars
*)*(value
.v_pointer
));
3106 g_object_unref(main_window
->attributes
);
3107 g_main_window_list
= g_slist_remove(g_main_window_list
, main_window
);
3109 g_printf("There are now : %d windows\n",g_slist_length(g_main_window_list
));
3110 if(g_slist_length(g_main_window_list
) == 0)
3115 on_MWindow_configure (GtkWidget
*widget
,
3116 GdkEventConfigure
*event
,
3119 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)widget
);
3120 float width
= event
->width
;
3121 TimeWindow time_win
;
3123 TimeInterval
*time_span
;
3126 // MD : removed time width modification upon resizing of the main window.
3127 // The viewers will redraw themselves completely, without time interval
3130 if(mw_data->window_width){
3131 time_span = LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context)->Time_Span ;
3132 time_win = tab->time_window;
3133 ratio = width / mw_data->window_width;
3134 tab->time_window.time_width = ltt_time_mul(time_win.time_width,ratio);
3135 time = ltt_time_sub(time_span->endTime, time_win.start_time);
3136 if(ltt_time_compare(time, tab->time_window.time_width) < 0){
3137 tab->time_window.time_width = time;
3143 mw_data->window_width = (int)width;
3152 on_MNotebook_switch_page (GtkNotebook
*notebook
,
3153 GtkNotebookPage
*page
,
3161 void scroll_value_changed_cb(GtkWidget
*scrollbar
,
3164 Tab
*tab
= (Tab
*)user_data
;
3165 TimeWindow time_window
;
3167 GtkAdjustment
*adjust
= gtk_range_get_adjustment(GTK_RANGE(scrollbar
));
3168 gdouble value
= gtk_adjustment_get_value(adjust
);
3169 gdouble upper
, lower
, ratio
, page_size
;
3170 LttvTracesetContext
* tsc
=
3171 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3172 TimeInterval time_span
= tsc
->time_span
;
3174 //time_window = tab->time_window;
3176 lower
= adjust
->lower
;
3177 upper
= adjust
->upper
;
3178 ratio
= (value
- lower
) / (upper
- lower
);
3179 g_info("lower %lu, upper %lu, value %lu, ratio %lu", lower
, upper
, value
, ratio
);
3181 //time = ltt_time_sub(time_span->end_time, time_span->start_time);
3182 //time = ltt_time_mul(time, (float)ratio);
3183 //time = ltt_time_add(time_span->start_time, time);
3184 time
= ltt_time_add(ltt_time_from_double(value
/NANOSECONDS_PER_SECOND
),
3185 time_span
.start_time
);
3187 time_window
.start_time
= time
;
3189 page_size
= adjust
->page_size
;
3191 time_window
.time_width
=
3192 ltt_time_from_double(page_size
/NANOSECONDS_PER_SECOND
);
3193 //time = ltt_time_sub(time_span.end_time, time);
3194 //if(ltt_time_compare(time,time_window.time_width) < 0){
3195 // time_window.time_width = time;
3198 /* call viewer hooks for new time window */
3199 set_time_window(tab
, &time_window
);
3204 /* callback function to check or uncheck the check box (filter)
3207 void checkbox_changed(GtkTreeView
*treeview
,
3209 GtkTreeViewColumn
*arg2
,
3212 GtkTreeStore
* store
= (GtkTreeStore
*)gtk_tree_view_get_model (treeview
);
3216 if (gtk_tree_model_get_iter ((GtkTreeModel
*)store
, &iter
, arg1
)){
3217 gtk_tree_model_get ((GtkTreeModel
*)store
, &iter
, CHECKBOX_COLUMN
, &value
, -1);
3218 value
= value
? FALSE
: TRUE
;
3219 gtk_tree_store_set (GTK_TREE_STORE (store
), &iter
, CHECKBOX_COLUMN
, value
, -1);
3225 /* According to user's selection, update selector(filter)
3228 void update_filter(LttvTracesetSelector
*s
, GtkTreeStore
*store
)
3230 GtkTreeIter iter
, child_iter
, child_iter1
, child_iter2
;
3231 int i
, j
, k
, nb_eventtype
;
3232 LttvTraceSelector
* trace
;
3233 LttvTracefileSelector
* tracefile
;
3234 LttvEventtypeSelector
* eventtype
;
3235 gboolean value
, value1
, value2
;
3237 if(gtk_tree_model_get_iter_first((GtkTreeModel
*)store
, &iter
)){
3240 trace
= lttv_traceset_selector_trace_get(s
, i
);
3241 nb_eventtype
= lttv_trace_selector_eventtype_number(trace
);
3242 gtk_tree_model_get ((GtkTreeModel
*)store
, &iter
, CHECKBOX_COLUMN
, &value
,-1);
3245 if(gtk_tree_model_iter_children ((GtkTreeModel
*)store
, &child_iter
, &iter
)){
3247 if(j
<1){//eventtype selector for trace
3248 gtk_tree_model_get ((GtkTreeModel
*)store
, &child_iter
, CHECKBOX_COLUMN
, &value2
,-1);
3251 if(gtk_tree_model_iter_children ((GtkTreeModel
*)store
, &child_iter1
, &child_iter
)){
3253 eventtype
= lttv_trace_selector_eventtype_get(trace
,k
);
3254 gtk_tree_model_get ((GtkTreeModel
*)store
, &child_iter1
, CHECKBOX_COLUMN
, &value2
,-1);
3255 lttv_eventtype_selector_set_selected(eventtype
,value2
);
3257 }while(gtk_tree_model_iter_next((GtkTreeModel
*)store
, &child_iter1
));
3260 }else{ //tracefile selector
3261 tracefile
= lttv_trace_selector_tracefile_get(trace
, j
- 1);
3262 gtk_tree_model_get ((GtkTreeModel
*)store
, &child_iter
, CHECKBOX_COLUMN
, &value1
,-1);
3263 lttv_tracefile_selector_set_selected(tracefile
,value1
);
3265 gtk_tree_model_iter_children((GtkTreeModel
*)store
, &child_iter1
, &child_iter
); //eventtype selector
3266 gtk_tree_model_get ((GtkTreeModel
*)store
, &child_iter1
, CHECKBOX_COLUMN
, &value2
,-1);
3269 if(gtk_tree_model_iter_children ((GtkTreeModel
*)store
, &child_iter2
, &child_iter1
)){
3270 do{//eventtype selector for tracefile
3271 eventtype
= lttv_tracefile_selector_eventtype_get(tracefile
,k
);
3272 gtk_tree_model_get ((GtkTreeModel
*)store
, &child_iter2
, CHECKBOX_COLUMN
, &value2
,-1);
3273 lttv_eventtype_selector_set_selected(eventtype
,value2
);
3275 }while(gtk_tree_model_iter_next((GtkTreeModel
*)store
, &child_iter2
));
3281 }while(gtk_tree_model_iter_next((GtkTreeModel
*)store
, &child_iter
));
3284 lttv_trace_selector_set_selected(trace
,value
);
3286 }while(gtk_tree_model_iter_next((GtkTreeModel
*)store
, &iter
));
3291 /* Display a dialogue showing all eventtypes and traces, let user to select the interested
3292 * eventtypes, tracefiles and traces (filter)
3295 gboolean
get_filter_selection(LttvTracesetSelector
*s
,char *title
, char * column_title
)
3297 GtkWidget
* dialogue
;
3298 GtkTreeStore
* store
;
3300 GtkWidget
* scroll_win
;
3301 GtkCellRenderer
* renderer
;
3302 GtkTreeViewColumn
* column
;
3303 GtkTreeIter iter
, child_iter
, child_iter1
, child_iter2
;
3304 int i
, j
, k
, id
, nb_trace
, nb_tracefile
, nb_eventtype
;
3305 LttvTraceSelector
* trace
;
3306 LttvTracefileSelector
* tracefile
;
3307 LttvEventtypeSelector
* eventtype
;
3311 dialogue
= gtk_dialog_new_with_buttons(title
,
3314 GTK_STOCK_OK
,GTK_RESPONSE_ACCEPT
,
3315 GTK_STOCK_CANCEL
,GTK_RESPONSE_REJECT
,
3317 gtk_window_set_default_size((GtkWindow
*)dialogue
, 300, 500);
3319 store
= gtk_tree_store_new (TOTAL_COLUMNS
, G_TYPE_BOOLEAN
, G_TYPE_STRING
);
3320 tree
= gtk_tree_view_new_with_model (GTK_TREE_MODEL (store
));
3321 g_object_unref (G_OBJECT (store
));
3322 g_signal_connect (G_OBJECT (tree
), "row-activated",
3323 G_CALLBACK (checkbox_changed
),
3327 renderer
= gtk_cell_renderer_toggle_new ();
3328 gtk_cell_renderer_toggle_set_radio((GtkCellRendererToggle
*)renderer
, FALSE
);
3330 g_object_set (G_OBJECT (renderer
),"activatable", TRUE
, NULL
);
3332 column
= gtk_tree_view_column_new_with_attributes ("Checkbox",
3334 "active", CHECKBOX_COLUMN
,
3336 gtk_tree_view_column_set_alignment (column
, 0.5);
3337 gtk_tree_view_column_set_fixed_width (column
, 20);
3338 gtk_tree_view_append_column (GTK_TREE_VIEW (tree
), column
);
3340 renderer
= gtk_cell_renderer_text_new ();
3341 column
= gtk_tree_view_column_new_with_attributes (column_title
,
3343 "text", NAME_COLUMN
,
3345 gtk_tree_view_column_set_alignment (column
, 0.0);
3346 gtk_tree_view_append_column (GTK_TREE_VIEW (tree
), column
);
3347 gtk_tree_view_set_headers_visible(GTK_TREE_VIEW (tree
), FALSE
);
3349 scroll_win
= gtk_scrolled_window_new (NULL
, NULL
);
3350 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll_win
),
3351 GTK_POLICY_AUTOMATIC
,GTK_POLICY_AUTOMATIC
);
3352 gtk_container_add (GTK_CONTAINER (scroll_win
), tree
);
3354 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialogue
)->vbox
), scroll_win
,TRUE
, TRUE
,0);
3356 gtk_widget_show(scroll_win
);
3357 gtk_widget_show(tree
);
3359 nb_trace
= lttv_traceset_selector_trace_number(s
);
3360 for(i
=0;i
<nb_trace
;i
++){
3361 trace
= lttv_traceset_selector_trace_get(s
, i
);
3362 name
= lttv_trace_selector_get_name(trace
);
3363 gtk_tree_store_append (store
, &iter
, NULL
);
3364 checked
= lttv_trace_selector_get_selected(trace
);
3365 gtk_tree_store_set (store
, &iter
,
3366 CHECKBOX_COLUMN
,checked
,
3370 gtk_tree_store_append (store
, &child_iter
, &iter
);
3371 gtk_tree_store_set (store
, &child_iter
,
3372 CHECKBOX_COLUMN
, checked
,
3373 NAME_COLUMN
,"eventtype",
3376 nb_eventtype
= lttv_trace_selector_eventtype_number(trace
);
3377 for(j
=0;j
<nb_eventtype
;j
++){
3378 eventtype
= lttv_trace_selector_eventtype_get(trace
,j
);
3379 name
= lttv_eventtype_selector_get_name(eventtype
);
3380 checked
= lttv_eventtype_selector_get_selected(eventtype
);
3381 gtk_tree_store_append (store
, &child_iter1
, &child_iter
);
3382 gtk_tree_store_set (store
, &child_iter1
,
3383 CHECKBOX_COLUMN
, checked
,
3388 nb_tracefile
= lttv_trace_selector_tracefile_number(trace
);
3389 for(j
=0;j
<nb_tracefile
;j
++){
3390 tracefile
= lttv_trace_selector_tracefile_get(trace
, j
);
3391 name
= lttv_tracefile_selector_get_name(tracefile
);
3392 gtk_tree_store_append (store
, &child_iter
, &iter
);
3393 checked
= lttv_tracefile_selector_get_selected(tracefile
);
3394 gtk_tree_store_set (store
, &child_iter
,
3395 CHECKBOX_COLUMN
, checked
,
3399 gtk_tree_store_append (store
, &child_iter1
, &child_iter
);
3400 gtk_tree_store_set (store
, &child_iter1
,
3401 CHECKBOX_COLUMN
, checked
,
3402 NAME_COLUMN
,"eventtype",
3405 for(k
=0;k
<nb_eventtype
;k
++){
3406 eventtype
= lttv_tracefile_selector_eventtype_get(tracefile
,k
);
3407 name
= lttv_eventtype_selector_get_name(eventtype
);
3408 checked
= lttv_eventtype_selector_get_selected(eventtype
);
3409 gtk_tree_store_append (store
, &child_iter2
, &child_iter1
);
3410 gtk_tree_store_set (store
, &child_iter2
,
3411 CHECKBOX_COLUMN
, checked
,
3418 id
= gtk_dialog_run(GTK_DIALOG(dialogue
));
3420 case GTK_RESPONSE_ACCEPT
:
3421 case GTK_RESPONSE_OK
:
3422 update_filter(s
, store
);
3423 gtk_widget_destroy(dialogue
);
3425 case GTK_RESPONSE_REJECT
:
3426 case GTK_RESPONSE_CANCEL
:
3428 gtk_widget_destroy(dialogue
);
3435 /* Select a trace which will be removed from traceset
3438 char * get_remove_trace(char ** all_trace_name
, int nb_trace
)
3440 return get_selection(all_trace_name
, nb_trace
,
3441 "Select a trace", "Trace pathname");
3445 /* Select a module which will be loaded
3448 char * get_load_module(char ** load_module_name
, int nb_module
)
3450 return get_selection(load_module_name
, nb_module
,
3451 "Select a module to load", "Module name");
3457 /* Select a module which will be unloaded
3460 char * get_unload_module(char ** loaded_module_name
, int nb_module
)
3462 return get_selection(loaded_module_name
, nb_module
,
3463 "Select a module to unload", "Module name");
3467 /* Display a dialogue which shows all selectable items, let user to
3468 * select one of them
3471 char * get_selection(char ** loaded_module_name
, int nb_module
,
3472 char *title
, char * column_title
)
3474 GtkWidget
* dialogue
;
3475 GtkWidget
* scroll_win
;
3477 GtkListStore
* store
;
3478 GtkTreeViewColumn
* column
;
3479 GtkCellRenderer
* renderer
;
3480 GtkTreeSelection
* select
;
3483 char * unload_module_name
= NULL
;
3485 dialogue
= gtk_dialog_new_with_buttons(title
,
3488 GTK_STOCK_OK
,GTK_RESPONSE_ACCEPT
,
3489 GTK_STOCK_CANCEL
,GTK_RESPONSE_REJECT
,
3491 gtk_window_set_default_size((GtkWindow
*)dialogue
, 500, 200);
3493 scroll_win
= gtk_scrolled_window_new (NULL
, NULL
);
3494 gtk_widget_show ( scroll_win
);
3495 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll_win
),
3496 GTK_POLICY_AUTOMATIC
, GTK_POLICY_AUTOMATIC
);
3498 store
= gtk_list_store_new (N_COLUMNS
,G_TYPE_STRING
);
3499 tree
= gtk_tree_view_new_with_model(GTK_TREE_MODEL (store
));
3500 gtk_widget_show ( tree
);
3501 g_object_unref (G_OBJECT (store
));
3503 renderer
= gtk_cell_renderer_text_new ();
3504 column
= gtk_tree_view_column_new_with_attributes (column_title
,
3506 "text", MODULE_COLUMN
,
3508 gtk_tree_view_column_set_alignment (column
, 0.5);
3509 gtk_tree_view_column_set_fixed_width (column
, 150);
3510 gtk_tree_view_append_column (GTK_TREE_VIEW (tree
), column
);
3512 select
= gtk_tree_view_get_selection (GTK_TREE_VIEW (tree
));
3513 gtk_tree_selection_set_mode (select
, GTK_SELECTION_SINGLE
);
3515 gtk_container_add (GTK_CONTAINER (scroll_win
), tree
);
3517 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialogue
)->vbox
), scroll_win
,TRUE
, TRUE
,0);
3519 for(i
=0;i
<nb_module
;i
++){
3520 gtk_list_store_append (store
, &iter
);
3521 gtk_list_store_set (store
, &iter
, MODULE_COLUMN
,loaded_module_name
[i
],-1);
3524 id
= gtk_dialog_run(GTK_DIALOG(dialogue
));
3526 case GTK_RESPONSE_ACCEPT
:
3527 case GTK_RESPONSE_OK
:
3528 if (gtk_tree_selection_get_selected (select
, (GtkTreeModel
**)&store
, &iter
)){
3529 gtk_tree_model_get ((GtkTreeModel
*)store
, &iter
, MODULE_COLUMN
, &unload_module_name
, -1);
3531 case GTK_RESPONSE_REJECT
:
3532 case GTK_RESPONSE_CANCEL
:
3534 gtk_widget_destroy(dialogue
);
3538 return unload_module_name
;
3542 /* Insert all menu entry and tool buttons into this main window
3547 void add_all_menu_toolbar_constructors(MainWindow
* mw
, gpointer user_data
)
3551 lttvwindow_viewer_constructor constructor
;
3552 LttvMenus
* global_menu
, * instance_menu
;
3553 LttvToolbars
* global_toolbar
, * instance_toolbar
;
3554 LttvMenuClosure
*menu_item
;
3555 LttvToolbarClosure
*toolbar_item
;
3556 LttvAttributeValue value
;
3557 LttvIAttribute
*global_attributes
= LTTV_IATTRIBUTE(lttv_global_attributes());
3558 LttvIAttribute
*attributes
= mw
->attributes
;
3559 GtkWidget
* tool_menu_title_menu
, *new_widget
, *pixmap
;
3561 g_assert(lttv_iattribute_find_by_path(global_attributes
,
3562 "viewers/menu", LTTV_POINTER
, &value
));
3563 if(*(value
.v_pointer
) == NULL
)
3564 *(value
.v_pointer
) = lttv_menus_new();
3565 global_menu
= (LttvMenus
*)*(value
.v_pointer
);
3567 g_assert(lttv_iattribute_find_by_path(attributes
,
3568 "viewers/menu", LTTV_POINTER
, &value
));
3569 if(*(value
.v_pointer
) == NULL
)
3570 *(value
.v_pointer
) = lttv_menus_new();
3571 instance_menu
= (LttvMenus
*)*(value
.v_pointer
);
3575 g_assert(lttv_iattribute_find_by_path(global_attributes
,
3576 "viewers/toolbar", LTTV_POINTER
, &value
));
3577 if(*(value
.v_pointer
) == NULL
)
3578 *(value
.v_pointer
) = lttv_toolbars_new();
3579 global_toolbar
= (LttvToolbars
*)*(value
.v_pointer
);
3581 g_assert(lttv_iattribute_find_by_path(attributes
,
3582 "viewers/toolbar", LTTV_POINTER
, &value
));
3583 if(*(value
.v_pointer
) == NULL
)
3584 *(value
.v_pointer
) = lttv_toolbars_new();
3585 instance_toolbar
= (LttvToolbars
*)*(value
.v_pointer
);
3587 /* Add missing menu entries to window instance */
3588 for(i
=0;i
<global_menu
->len
;i
++) {
3589 menu_item
= &g_array_index(global_menu
, LttvMenuClosure
, i
);
3591 //add menu_item to window instance;
3592 constructor
= menu_item
->con
;
3593 tool_menu_title_menu
= lookup_widget(mw
->mwindow
,"ToolMenuTitle_menu");
3595 gtk_menu_item_new_with_mnemonic (menu_item
->menu_text
);
3596 gtk_container_add (GTK_CONTAINER (tool_menu_title_menu
),
3598 g_signal_connect ((gpointer
) new_widget
, "activate",
3599 G_CALLBACK (insert_viewer_wrap
),
3601 gtk_widget_show (new_widget
);
3602 lttv_menus_add(instance_menu
, menu_item
->con
,
3603 menu_item
->menu_path
,
3604 menu_item
->menu_text
,
3609 /* Add missing toolbar entries to window instance */
3610 for(i
=0;i
<global_toolbar
->len
;i
++) {
3611 toolbar_item
= &g_array_index(global_toolbar
, LttvToolbarClosure
, i
);
3613 //add toolbar_item to window instance;
3614 constructor
= toolbar_item
->con
;
3615 tool_menu_title_menu
= lookup_widget(mw
->mwindow
,"MToolbar1");
3616 pixbuf
= gdk_pixbuf_new_from_xpm_data((const char**)toolbar_item
->pixmap
);
3617 pixmap
= gtk_image_new_from_pixbuf(pixbuf
);
3619 gtk_toolbar_append_element (GTK_TOOLBAR (tool_menu_title_menu
),
3620 GTK_TOOLBAR_CHILD_BUTTON
,
3623 toolbar_item
->tooltip
, NULL
,
3624 pixmap
, NULL
, NULL
);
3625 gtk_label_set_use_underline(
3626 GTK_LABEL (((GtkToolbarChild
*) (
3627 g_list_last (GTK_TOOLBAR
3628 (tool_menu_title_menu
)->children
)->data
))->label
),
3630 gtk_container_set_border_width (GTK_CONTAINER (new_widget
), 1);
3631 g_signal_connect ((gpointer
) new_widget
,
3633 G_CALLBACK (insert_viewer_wrap
),
3635 gtk_widget_show (new_widget
);
3637 lttv_toolbars_add(instance_toolbar
, toolbar_item
->con
,
3638 toolbar_item
->tooltip
,
3639 toolbar_item
->pixmap
,
3647 /* Create a main window
3650 void construct_main_window(MainWindow
* parent
)
3652 g_debug("construct_main_window()");
3653 GtkWidget
* new_window
; /* New generated main window */
3654 MainWindow
* new_m_window
;/* New main window structure */
3655 GtkNotebook
* notebook
;
3656 LttvIAttribute
*attributes
=
3657 LTTV_IATTRIBUTE(g_object_new(LTTV_ATTRIBUTE_TYPE
, NULL
));
3658 LttvAttributeValue value
;
3661 new_m_window
= g_new(MainWindow
, 1);
3663 // Add the object's information to the module's array
3664 g_main_window_list
= g_slist_append(g_main_window_list
, new_m_window
);
3667 new_window
= create_MWindow();
3668 gtk_widget_show (new_window
);
3670 new_m_window
->mwindow
= new_window
;
3671 new_m_window
->attributes
= attributes
;
3673 g_assert(lttv_iattribute_find_by_path(attributes
,
3674 "viewers/menu", LTTV_POINTER
, &value
));
3675 *(value
.v_pointer
) = lttv_menus_new();
3677 g_assert(lttv_iattribute_find_by_path(attributes
,
3678 "viewers/toolbar", LTTV_POINTER
, &value
));
3679 *(value
.v_pointer
) = lttv_toolbars_new();
3681 add_all_menu_toolbar_constructors(new_m_window
, NULL
);
3683 g_object_set_data_full(G_OBJECT(new_window
),
3685 (gpointer
)new_m_window
,
3686 (GDestroyNotify
)g_free
);
3687 //create a default tab
3688 notebook
= (GtkNotebook
*)lookup_widget(new_m_window
->mwindow
, "MNotebook");
3689 if(notebook
== NULL
){
3690 g_printf("Notebook does not exist\n");
3693 gtk_notebook_popup_enable (GTK_NOTEBOOK(notebook
));
3694 //for now there is no name field in LttvTraceset structure
3695 //Use "Traceset" as the label for the default tab
3697 GtkWidget
* parent_notebook
= lookup_widget(parent
->mwindow
, "MNotebook");
3698 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(parent_notebook
),
3699 gtk_notebook_get_current_page(GTK_NOTEBOOK(parent_notebook
)));
3705 parent_tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
3707 new_tab
= create_tab(new_m_window
, parent_tab
, notebook
, "Traceset");
3709 new_tab
= create_tab(new_m_window
, NULL
, notebook
, "Traceset");
3710 /* First window, use command line trace */
3711 if(g_init_trace
!= NULL
){
3712 lttvwindow_add_trace(new_tab
,
3715 LttvTraceset
*traceset
= new_tab
->traceset_info
->traceset
;
3716 SetTraceset(new_tab
, traceset
);
3720 g_printf("There are now : %d windows\n",g_slist_length(g_main_window_list
));
3724 /* Free the memory occupied by a tab structure
3728 void tab_destructor(Tab
* tab_instance
)
3730 int i
, nb
, ref_count
;
3733 if(tab_instance
->attributes
)
3734 g_object_unref(tab_instance
->attributes
);
3736 if(tab_instance
->interrupted_state
)
3737 g_object_unref(tab_instance
->interrupted_state
);
3740 if(tab_instance
->traceset_info
->traceset_context
!= NULL
){
3741 //remove state update hooks
3742 lttv_state_remove_event_hooks(
3743 (LttvTracesetState
*)tab_instance
->traceset_info
->
3745 lttv_context_fini(LTTV_TRACESET_CONTEXT(tab_instance
->traceset_info
->
3747 g_object_unref(tab_instance
->traceset_info
->traceset_context
);
3749 if(tab_instance
->traceset_info
->traceset
!= NULL
) {
3750 nb
= lttv_traceset_number(tab_instance
->traceset_info
->traceset
);
3751 for(i
= 0 ; i
< nb
; i
++) {
3752 trace
= lttv_traceset_get(tab_instance
->traceset_info
->traceset
, i
);
3753 ref_count
= lttv_trace_get_ref_number(trace
);
3755 ltt_trace_close(lttv_trace(trace
));
3759 lttv_traceset_destroy(tab_instance
->traceset_info
->traceset
);
3760 /* Remove the idle events requests processing function of the tab */
3761 g_idle_remove_by_data(tab_instance
);
3763 g_slist_free(tab_instance
->events_requests
);
3764 g_free(tab_instance
->traceset_info
);
3765 g_free(tab_instance
);
3769 /* Create a tab and insert it into the current main window
3772 Tab
* create_tab(MainWindow
* mw
, Tab
*copy_tab
,
3773 GtkNotebook
* notebook
, char * label
)
3779 //create a new tab data structure
3782 //construct and initialize the traceset_info
3783 tab
->traceset_info
= g_new(TracesetInfo
,1);
3786 tab
->traceset_info
->traceset
=
3787 lttv_traceset_copy(copy_tab
->traceset_info
->traceset
);
3789 tab
->traceset_info
->traceset
= lttv_traceset_new();
3793 lttv_attribute_write_xml(
3794 lttv_traceset_attribute(tab
->traceset_info
->traceset
),
3801 //FIXME copy not implemented in lower level
3802 tab
->traceset_info
->traceset_context
=
3803 g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
3804 g_assert(tab
->traceset_info
->traceset_context
!= NULL
);
3806 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
),
3807 tab
->traceset_info
->traceset
);
3808 //add state update hooks
3809 lttv_state_add_event_hooks(
3810 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
3812 //determine the current_time and time_window of the tab
3813 if(copy_tab
!= NULL
){
3814 tab
->time_window
= copy_tab
->time_window
;
3815 tab
->current_time
= copy_tab
->current_time
;
3817 tab
->time_window
.start_time
=
3818 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
3819 time_span
.start_time
;
3820 if(DEFAULT_TIME_WIDTH_S
<
3821 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
3822 time_span
.end_time
.tv_sec
)
3823 tmp_time
.tv_sec
= DEFAULT_TIME_WIDTH_S
;
3826 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
3827 time_span
.end_time
.tv_sec
;
3828 tmp_time
.tv_nsec
= 0;
3829 tab
->time_window
.time_width
= tmp_time
;
3830 tab
->current_time
.tv_sec
=
3831 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
3832 time_span
.start_time
.tv_sec
;
3833 tab
->current_time
.tv_nsec
=
3834 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
3835 time_span
.start_time
.tv_nsec
;
3837 tab
->attributes
= LTTV_IATTRIBUTE(g_object_new(LTTV_ATTRIBUTE_TYPE
, NULL
));
3838 tab
->interrupted_state
= g_object_new(LTTV_ATTRIBUTE_TYPE
, NULL
);
3840 tab
->vbox
= gtk_vbox_new(FALSE
, 2);
3841 tab
->viewer_container
= gtk_vbox_new(TRUE
, 2);
3842 tab
->scrollbar
= gtk_hscrollbar_new(NULL
);
3843 //tab->multivpaned = gtk_multi_vpaned_new();
3845 gtk_box_pack_start(GTK_BOX(tab
->vbox
),
3846 tab
->viewer_container
,
3848 TRUE
, /* Give the extra space to the child */
3849 0); /* No padding */
3851 gtk_box_pack_end(GTK_BOX(tab
->vbox
),
3853 FALSE
, /* Do not expand */
3854 FALSE
, /* Fill has no effect here (expand false) */
3855 0); /* No padding */
3857 g_object_set_data(G_OBJECT(tab
->viewer_container
), "focused_viewer", NULL
);
3863 // Display a label with a X
3864 GtkWidget *w_hbox = gtk_hbox_new(FALSE, 4);
3865 GtkWidget *w_label = gtk_label_new (label);
3866 GtkWidget *pixmap = create_pixmap(GTK_WIDGET(notebook), "close.png");
3867 GtkWidget *w_button = gtk_button_new ();
3868 gtk_container_add(GTK_CONTAINER(w_button), pixmap);
3869 //GtkWidget *w_button = gtk_button_new_with_label("x");
3871 gtk_button_set_relief(GTK_BUTTON(w_button), GTK_RELIEF_NONE);
3873 gtk_box_pack_start(GTK_BOX(w_hbox), w_label, TRUE, TRUE, 0);
3874 gtk_box_pack_end(GTK_BOX(w_hbox), w_button, FALSE,
3877 g_signal_connect_swapped (w_button, "clicked",
3878 G_CALLBACK (on_close_tab_X_clicked),
3881 gtk_widget_set_state(w_button, GTK_STATE_ACTIVE);
3883 gtk_widget_show (w_label);
3884 gtk_widget_show (pixmap);
3885 gtk_widget_show (w_button);
3886 gtk_widget_show (w_hbox);
3888 tab->label = w_hbox;
3892 tab
->label
= gtk_label_new (label
);
3894 gtk_widget_show(tab
->label
);
3895 gtk_widget_show(tab
->scrollbar
);
3896 gtk_widget_show(tab
->viewer_container
);
3897 gtk_widget_show(tab
->vbox
);
3898 //gtk_widget_show(tab->multivpaned);
3901 /* Start with empty events requests list */
3902 tab
->events_requests
= NULL
;
3903 tab
->events_request_pending
= FALSE
;
3905 g_object_set_data_full(
3906 G_OBJECT(tab
->vbox
),
3909 (GDestroyNotify
)tab_destructor
);
3911 g_signal_connect(G_OBJECT(tab
->scrollbar
), "value-changed",
3912 G_CALLBACK(scroll_value_changed_cb
), tab
);
3913 //g_signal_connect(G_OBJECT(tab->scrollbar), "changed",
3914 // G_CALLBACK(scroll_value_changed_cb), tab);
3917 //insert tab into notebook
3918 gtk_notebook_append_page(notebook
,
3921 list
= gtk_container_get_children(GTK_CONTAINER(notebook
));
3922 gtk_notebook_set_current_page(notebook
,g_list_length(list
)-1);
3923 // always show : not if(g_list_length(list)>1)
3924 gtk_notebook_set_show_tabs(notebook
, TRUE
);
3930 * execute_events_requests
3932 * Idle function that executes the pending requests for a tab.
3934 * @return return value : TRUE : keep the idle function, FALSE : remove it.
3936 gboolean
execute_events_requests(Tab
*tab
)
3938 return ( lttvwindow_process_pending_requests(tab
) );