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
= ltt_time_infinite
;
1288 /* 1.3. Move from list_in to list_out */
1291 list_out
= g_slist_append(list_out
, events_request
);
1296 GSList
*remove_iter
= iter
;
1298 iter
= g_slist_next(iter
);
1299 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
1300 list_in
= g_slist_remove_link(list_in
, remove_iter
);
1301 } else { // not remove
1302 iter
= g_slist_next(iter
);
1309 /* C Unlock Traces */
1311 //lttv_process_traceset_get_sync_data(tsc);
1316 iter_trace
<lttv_traceset_number(tsc
->ts
);
1318 LttvTrace
*trace_v
= lttv_traceset_get(tsc
->ts
, iter_trace
);
1320 lttvwindowtraces_unlock(trace_v
);
1325 //set the cursor back to normal
1326 gdk_window_set_cursor(win
, NULL
);
1329 g_assert(g_slist_length(list_in
) == 0);
1331 if( g_slist_length(list_out
) == 0 ) {
1332 /* Put tab's request pending flag back to normal */
1333 tab
->events_request_pending
= FALSE
;
1334 g_debug("remove the idle fct");
1335 return FALSE
; /* Remove the idle function */
1337 g_debug("leave the idle fct");
1338 return TRUE
; /* Leave the idle function */
1340 /* We do not use simili-round-robin, it may require to read 1 meg buffers
1341 * again and again if many tracesets use the same tracefiles. */
1342 /* Hack for round-robin idle functions */
1343 /* It will put the idle function at the end of the pool */
1344 /*g_idle_add_full((G_PRIORITY_HIGH_IDLE + 21),
1345 (GSourceFunc)execute_events_requests,
1355 /* add_trace_into_traceset_selector, each instance of a viewer has an associated
1356 * selector (filter), when a trace is added into traceset, the selector should
1357 * reflect the change. The function is used to update the selector
1360 void add_trace_into_traceset_selector(GtkWidget
* paned
, LttTrace
* t
)
1362 int j
, k
, m
, nb_tracefile
, nb_control
, nb_per_cpu
, nb_facility
, nb_event
;
1363 LttvTracesetSelector
* s
;
1364 LttvTraceSelector
* trace
;
1365 LttvTracefileSelector
* tracefile
;
1366 LttvEventtypeSelector
* eventtype
;
1372 w
= gtk_multivpaned_get_first_widget(GTK_MULTIVPANED(paned
));
1374 s
= g_object_get_data(G_OBJECT(w
), "Traceset_Selector");
1377 trace
= lttv_trace_selector_new(t
);
1378 lttv_traceset_selector_trace_add(s
, trace
);
1380 nb_facility
= ltt_trace_facility_number(t
);
1381 for(k
=0;k
<nb_facility
;k
++){
1382 fac
= ltt_trace_facility_get(t
,k
);
1383 nb_event
= (int) ltt_facility_eventtype_number(fac
);
1384 for(m
=0;m
<nb_event
;m
++){
1385 et
= ltt_facility_eventtype_get(fac
,m
);
1386 eventtype
= lttv_eventtype_selector_new(et
);
1387 lttv_trace_selector_eventtype_add(trace
, eventtype
);
1391 nb_control
= ltt_trace_control_tracefile_number(t
);
1392 nb_per_cpu
= ltt_trace_per_cpu_tracefile_number(t
);
1393 nb_tracefile
= nb_control
+ nb_per_cpu
;
1395 for(j
= 0 ; j
< nb_tracefile
; j
++) {
1397 tf
= ltt_trace_control_tracefile_get(t
, j
);
1399 tf
= ltt_trace_per_cpu_tracefile_get(t
, j
- nb_control
);
1400 tracefile
= lttv_tracefile_selector_new(tf
);
1401 lttv_trace_selector_tracefile_add(trace
, tracefile
);
1402 lttv_eventtype_selector_copy(trace
, tracefile
);
1404 }else g_warning("Module does not support filtering\n");
1406 w
= gtk_multivpaned_get_next_widget(GTK_MULTIVPANED(paned
));
1411 static void lttvwindow_add_trace(Tab
*tab
, LttvTrace
*trace_v
)
1413 LttvTraceset
*traceset
= tab
->traceset_info
->traceset
;
1415 guint num_traces
= lttv_traceset_number(traceset
);
1417 //Verify if trace is already present.
1418 for(i
=0; i
<num_traces
; i
++)
1420 LttvTrace
* trace
= lttv_traceset_get(traceset
, i
);
1421 if(trace
== trace_v
)
1425 //Keep a reference to the traces so they are not freed.
1426 for(i
=0; i
<lttv_traceset_number(traceset
); i
++)
1428 LttvTrace
* trace
= lttv_traceset_get(traceset
, i
);
1429 lttv_trace_ref(trace
);
1432 //remove state update hooks
1433 lttv_state_remove_event_hooks(
1434 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1436 lttv_context_fini(LTTV_TRACESET_CONTEXT(
1437 tab
->traceset_info
->traceset_context
));
1438 g_object_unref(tab
->traceset_info
->traceset_context
);
1440 lttv_traceset_add(traceset
, trace_v
);
1441 lttv_trace_ref(trace_v
); /* local ref */
1443 /* Create new context */
1444 tab
->traceset_info
->traceset_context
=
1445 g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
1447 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->
1452 //add state update hooks
1453 lttv_state_add_event_hooks(
1454 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1455 //Remove local reference to the traces.
1456 for(i
=0; i
<lttv_traceset_number(traceset
); i
++)
1458 LttvTrace
* trace
= lttv_traceset_get(traceset
, i
);
1459 lttv_trace_unref(trace
);
1463 //add_trace_into_traceset_selector(GTK_MULTIVPANED(tab->multivpaned), lttv_trace(trace_v));
1466 /* add_trace adds a trace into the current traceset. It first displays a
1467 * directory selection dialogue to let user choose a trace, then recreates
1468 * tracset_context, and redraws all the viewer of the current tab
1471 void add_trace(GtkWidget
* widget
, gpointer user_data
)
1474 LttvTrace
* trace_v
;
1475 LttvTraceset
* traceset
;
1477 char abs_path
[PATH_MAX
];
1480 MainWindow
* mw_data
= get_window_data_struct(widget
);
1481 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
1483 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
1484 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
1488 tab
= create_new_tab(widget
, NULL
);
1490 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
1493 GtkDirSelection
* file_selector
= (GtkDirSelection
*)gtk_dir_selection_new("Select a trace");
1494 gtk_dir_selection_hide_fileop_buttons(file_selector
);
1496 if(remember_trace_dir
[0] != '\0')
1497 gtk_dir_selection_set_filename(file_selector
, remember_trace_dir
);
1499 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
1501 case GTK_RESPONSE_ACCEPT
:
1502 case GTK_RESPONSE_OK
:
1503 dir
= gtk_dir_selection_get_dir (file_selector
);
1504 strncpy(remember_trace_dir
, dir
, PATH_MAX
);
1505 if(!dir
|| strlen(dir
) == 0){
1506 gtk_widget_destroy((GtkWidget
*)file_selector
);
1509 get_absolute_pathname(dir
, abs_path
);
1510 trace_v
= lttvwindowtraces_get_trace_by_name(abs_path
);
1511 if(trace_v
== NULL
) {
1512 trace
= ltt_trace_open(abs_path
);
1514 g_warning("cannot open trace %s", abs_path
);
1516 trace_v
= lttv_trace_new(trace
);
1517 lttvwindowtraces_add_trace(trace_v
);
1518 lttvwindow_add_trace(tab
, trace_v
);
1521 lttvwindow_add_trace(tab
, trace_v
);
1524 gtk_widget_destroy((GtkWidget
*)file_selector
);
1526 //update current tab
1527 //update_traceset(mw_data);
1529 /* Call the updatetraceset hooks */
1531 traceset
= tab
->traceset_info
->traceset
;
1532 SetTraceset(tab
, traceset
);
1533 // in expose now call_pending_read_hooks(mw_data);
1535 //lttvwindow_report_current_time(mw_data,&(tab->current_time));
1537 case GTK_RESPONSE_REJECT
:
1538 case GTK_RESPONSE_CANCEL
:
1540 gtk_widget_destroy((GtkWidget
*)file_selector
);
1546 /* remove_trace_into_traceset_selector, each instance of a viewer has an associated
1547 * selector (filter), when a trace is remove from traceset, the selector should
1548 * reflect the change. The function is used to update the selector
1551 void remove_trace_from_traceset_selector(GtkWidget
* paned
, unsigned i
)
1553 LttvTracesetSelector
* s
;
1554 LttvTraceSelector
* t
;
1557 w
= gtk_multivpaned_get_first_widget(GTK_MULTIVPANED(paned
));
1559 s
= g_object_get_data(G_OBJECT(w
), "Traceset_Selector");
1561 t
= lttv_traceset_selector_trace_get(s
,i
);
1562 lttv_traceset_selector_trace_remove(s
, i
);
1563 lttv_trace_selector_destroy(t
);
1564 }g_warning("Module dose not support filtering\n");
1565 w
= gtk_multivpaned_get_next_widget(GTK_MULTIVPANED(paned
));
1570 /* remove_trace removes a trace from the current traceset if all viewers in
1571 * the current tab are not interested in the trace. It first displays a
1572 * dialogue, which shows all traces in the current traceset, to let user choose
1573 * a trace, then it checks if all viewers unselect the trace, if it is true,
1574 * it will remove the trace, recreate the traceset_contex,
1575 * and redraws all the viewer of the current tab. If there is on trace in the
1576 * current traceset, it will delete all viewers of the current tab
1579 // MD : no filter version.
1580 void remove_trace(GtkWidget
*widget
, gpointer user_data
)
1583 LttvTrace
* trace_v
;
1584 LttvTraceset
* traceset
;
1585 gint i
, j
, nb_trace
, index
=-1;
1586 char ** name
, *remove_trace_name
;
1587 MainWindow
* mw_data
= get_window_data_struct(widget
);
1588 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
1590 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
1591 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
1597 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
1600 nb_trace
=lttv_traceset_number(tab
->traceset_info
->traceset
);
1601 name
= g_new(char*,nb_trace
);
1602 for(i
= 0; i
< nb_trace
; i
++){
1603 trace_v
= lttv_traceset_get(tab
->traceset_info
->traceset
, i
);
1604 trace
= lttv_trace(trace_v
);
1605 name
[i
] = ltt_trace_name(trace
);
1608 remove_trace_name
= get_remove_trace(name
, nb_trace
);
1611 if(remove_trace_name
){
1613 /* yuk, cut n paste from old code.. should be better (MD)*/
1614 for(i
= 0; i
<nb_trace
; i
++) {
1615 if(strcmp(remove_trace_name
,name
[i
]) == 0){
1620 traceset
= tab
->traceset_info
->traceset
;
1621 //Keep a reference to the traces so they are not freed.
1622 for(j
=0; j
<lttv_traceset_number(traceset
); j
++)
1624 LttvTrace
* trace
= lttv_traceset_get(traceset
, j
);
1625 lttv_trace_ref(trace
);
1628 //remove state update hooks
1629 lttv_state_remove_event_hooks(
1630 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1631 lttv_context_fini(LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
));
1632 g_object_unref(tab
->traceset_info
->traceset_context
);
1634 trace_v
= lttv_traceset_get(traceset
, index
);
1636 lttv_traceset_remove(traceset
, index
);
1637 lttv_trace_unref(trace_v
); // Remove local reference
1639 if(lttv_trace_get_ref_number(trace_v
) <= 1) {
1640 /* ref 1 : lttvwindowtraces only*/
1641 ltt_trace_close(lttv_trace(trace_v
));
1642 /* lttvwindowtraces_remove_trace takes care of destroying
1643 * the traceset linked with the trace_v and also of destroying
1644 * the trace_v at the same time.
1646 lttvwindowtraces_remove_trace(trace_v
);
1649 tab
->traceset_info
->traceset_context
=
1650 g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
1652 LTTV_TRACESET_CONTEXT(tab
->
1653 traceset_info
->traceset_context
),traceset
);
1654 //add state update hooks
1655 lttv_state_add_event_hooks(
1656 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1658 //Remove local reference to the traces.
1659 for(j
=0; j
<lttv_traceset_number(traceset
); j
++)
1661 LttvTrace
* trace
= lttv_traceset_get(traceset
, j
);
1662 lttv_trace_unref(trace
);
1665 SetTraceset(tab
, (gpointer
)traceset
);
1671 void remove_trace(GtkWidget
* widget
, gpointer user_data
)
1674 LttvTrace
* trace_v
;
1675 LttvTraceset
* traceset
;
1676 gint i
, j
, nb_trace
;
1677 char ** name
, *remove_trace_name
;
1678 MainWindow
* mw_data
= get_window_data_struct(widget
);
1679 LttvTracesetSelector
* s
;
1680 LttvTraceSelector
* t
;
1683 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
1685 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
1686 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
1692 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
1695 nb_trace
=lttv_traceset_number(tab
->traceset_info
->traceset
);
1696 name
= g_new(char*,nb_trace
);
1697 for(i
= 0; i
< nb_trace
; i
++){
1698 trace_v
= lttv_traceset_get(tab
->traceset_info
->traceset
, i
);
1699 trace
= lttv_trace(trace_v
);
1700 name
[i
] = ltt_trace_name(trace
);
1703 remove_trace_name
= get_remove_trace(name
, nb_trace
);
1705 if(remove_trace_name
){
1706 for(i
=0; i
<nb_trace
; i
++){
1707 if(strcmp(remove_trace_name
,name
[i
]) == 0){
1708 //unselect the trace from the current viewer
1710 w
= gtk_multivpaned_get_widget(GTK_MULTIVPANED(tab
->multivpaned
));
1712 s
= g_object_get_data(G_OBJECT(w
), "Traceset_Selector");
1714 t
= lttv_traceset_selector_trace_get(s
,i
);
1715 lttv_trace_selector_set_selected(t
, FALSE
);
1718 //check if other viewers select the trace
1719 w
= gtk_multivpaned_get_first_widget(GTK_MULTIVPANED(tab
->multivpaned
));
1721 s
= g_object_get_data(G_OBJECT(w
), "Traceset_Selector");
1723 t
= lttv_traceset_selector_trace_get(s
,i
);
1724 selected
= lttv_trace_selector_get_selected(t
);
1727 w
= gtk_multivpaned_get_next_widget(GTK_MULTIVPANED(tab
->multivpaned
));
1729 }else selected
= FALSE
;
1731 //if no viewer selects the trace, remove it
1733 remove_trace_from_traceset_selector(GTK_MULTIVPANED(tab
->multivpaned
), i
);
1735 traceset
= tab
->traceset_info
->traceset
;
1736 //Keep a reference to the traces so they are not freed.
1737 for(j
=0; j
<lttv_traceset_number(traceset
); j
++)
1739 LttvTrace
* trace
= lttv_traceset_get(traceset
, j
);
1740 lttv_trace_ref(trace
);
1743 //remove state update hooks
1744 lttv_state_remove_event_hooks(
1745 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1746 lttv_context_fini(LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
));
1747 g_object_unref(tab
->traceset_info
->traceset_context
);
1750 trace_v
= lttv_traceset_get(traceset
, i
);
1752 if(lttv_trace_get_ref_number(trace_v
) <= 2) {
1753 /* ref 2 : traceset, local */
1754 lttvwindowtraces_remove_trace(trace_v
);
1755 ltt_trace_close(lttv_trace(trace_v
));
1758 lttv_traceset_remove(traceset
, i
);
1759 lttv_trace_unref(trace_v
); // Remove local reference
1761 if(!lttv_trace_get_ref_number(trace_v
))
1762 lttv_trace_destroy(trace_v
);
1764 tab
->traceset_info
->traceset_context
=
1765 g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
1767 LTTV_TRACESET_CONTEXT(tab
->
1768 traceset_info
->traceset_context
),traceset
);
1769 //add state update hooks
1770 lttv_state_add_event_hooks(
1771 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1773 //Remove local reference to the traces.
1774 for(j
=0; j
<lttv_traceset_number(traceset
); j
++)
1776 LttvTrace
* trace
= lttv_traceset_get(traceset
, j
);
1777 lttv_trace_unref(trace
);
1781 //update current tab
1782 //update_traceset(mw_data);
1785 SetTraceset(tab
, (gpointer
)traceset
);
1786 // in expose now call_pending_read_hooks(mw_data);
1788 //lttvwindow_report_current_time(mw_data,&(tab->current_time));
1791 // while(tab->multi_vpaned->num_children){
1792 // gtk_multi_vpaned_widget_delete(tab->multi_vpaned);
1806 /* Redraw all the viewers in the current tab */
1807 void redraw(GtkWidget
*widget
, gpointer user_data
)
1809 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
1810 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
1811 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
1816 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
1820 LttvAttributeValue value
;
1822 g_assert(lttv_iattribute_find_by_path(tab
->attributes
, "hooks/redraw", LTTV_POINTER
, &value
));
1824 tmp
= (LttvHooks
*)*(value
.v_pointer
);
1826 lttv_hooks_call(tmp
,NULL
);
1830 void continue_processing(GtkWidget
*widget
, gpointer user_data
)
1832 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
1833 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
1834 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
1839 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
1843 LttvAttributeValue value
;
1845 g_assert(lttv_iattribute_find_by_path(tab
->attributes
,
1846 "hooks/continue", LTTV_POINTER
, &value
));
1848 tmp
= (LttvHooks
*)*(value
.v_pointer
);
1850 lttv_hooks_call(tmp
,NULL
);
1853 /* Stop the processing for the calling main window's current tab.
1854 * It removes every processing requests that are in its list. It does not call
1855 * the end request hooks, because the request is not finished.
1858 void stop_processing(GtkWidget
*widget
, gpointer user_data
)
1860 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
1861 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
1862 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
1867 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
1869 GSList
*iter
= tab
->events_requests
;
1871 while(iter
!= NULL
) {
1872 GSList
*remove_iter
= iter
;
1873 iter
= g_slist_next(iter
);
1875 g_free(remove_iter
->data
);
1876 tab
->events_requests
=
1877 g_slist_remove_link(tab
->events_requests
, remove_iter
);
1879 tab
->events_request_pending
= FALSE
;
1880 g_idle_remove_by_data(tab
);
1881 g_assert(g_slist_length(tab
->events_requests
) == 0);
1885 /* save will save the traceset to a file
1886 * Not implemented yet FIXME
1889 void save(GtkWidget
* widget
, gpointer user_data
)
1894 void save_as(GtkWidget
* widget
, gpointer user_data
)
1896 g_printf("Save as\n");
1900 /* zoom will change the time_window of all the viewers of the
1901 * current tab, and redisplay them. The main functionality is to
1902 * determine the new time_window of the current tab
1905 void zoom(GtkWidget
* widget
, double size
)
1907 TimeInterval time_span
;
1908 TimeWindow new_time_window
;
1909 LttTime current_time
, time_delta
, time_s
, time_e
, time_tmp
;
1910 MainWindow
* mw_data
= get_window_data_struct(widget
);
1911 LttvTracesetContext
*tsc
;
1912 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
1914 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
1915 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
1921 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
1924 if(size
== 1) return;
1926 tsc
= LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
1927 time_span
= tsc
->time_span
;
1928 new_time_window
= tab
->time_window
;
1929 current_time
= tab
->current_time
;
1931 time_delta
= ltt_time_sub(time_span
.end_time
,time_span
.start_time
);
1933 new_time_window
.start_time
= time_span
.start_time
;
1934 new_time_window
.time_width
= time_delta
;
1936 new_time_window
.time_width
= ltt_time_div(new_time_window
.time_width
, size
);
1937 if(ltt_time_compare(new_time_window
.time_width
,time_delta
) > 0)
1938 { /* Case where zoom out is bigger than trace length */
1939 new_time_window
.start_time
= time_span
.start_time
;
1940 new_time_window
.time_width
= time_delta
;
1944 /* Center the image on the current time */
1945 new_time_window
.start_time
=
1946 ltt_time_sub(current_time
, ltt_time_div(new_time_window
.time_width
, 2.0));
1947 /* If on borders, don't fall off */
1948 if(ltt_time_compare(new_time_window
.start_time
, time_span
.start_time
) <0)
1950 new_time_window
.start_time
= time_span
.start_time
;
1954 if(ltt_time_compare(
1955 ltt_time_add(new_time_window
.start_time
, new_time_window
.time_width
),
1956 time_span
.end_time
) > 0)
1958 new_time_window
.start_time
=
1959 ltt_time_sub(time_span
.end_time
, new_time_window
.time_width
);
1965 //time_tmp = ltt_time_div(new_time_window.time_width, 2);
1966 //if(ltt_time_compare(current_time, time_tmp) < 0){
1967 // time_s = time_span->startTime;
1969 // time_s = ltt_time_sub(current_time,time_tmp);
1971 //time_e = ltt_time_add(current_time,time_tmp);
1972 //if(ltt_time_compare(time_span->startTime, time_s) > 0){
1973 // time_s = time_span->startTime;
1974 //}else if(ltt_time_compare(time_span->endTime, time_e) < 0){
1975 // time_e = time_span->endTime;
1976 // time_s = ltt_time_sub(time_e,new_time_window.time_width);
1978 //new_time_window.start_time = time_s;
1981 //lttvwindow_report_time_window(mw_data, &new_time_window);
1982 //call_pending_read_hooks(mw_data);
1984 //lttvwindow_report_current_time(mw_data,&(tab->current_time));
1985 //set_time_window(tab, &new_time_window);
1986 // in expose now call_pending_read_hooks(mw_data);
1987 //gtk_multi_vpaned_set_adjust(tab->multi_vpaned, &new_time_window, FALSE);
1992 ltt_time_sub(new_time_window
.start_time
, time_span
.start_time
);
1993 if( ltt_time_to_double(new_time_window
.time_width
)
1994 * NANOSECONDS_PER_SECOND
1995 / SCROLL_STEP_PER_PAGE
/* step increment */
1997 ltt_time_to_double(rel_time
) * NANOSECONDS_PER_SECOND
/* page size */
1999 ltt_time_to_double(rel_time
) * NANOSECONDS_PER_SECOND
/* page size */
2001 g_warning("Can not zoom that far due to scrollbar precision");
2004 ltt_time_from_double(
2005 ltt_time_to_double(new_time_window
.time_width
)
2006 /SCROLL_STEP_PER_PAGE
),
2009 g_warning("Can not zoom that far due to time nanosecond precision");
2012 GtkAdjustment
*adjustment
= gtk_range_get_adjustment(GTK_RANGE(tab
->scrollbar
));
2014 g_object_set(G_OBJECT(adjustment
),
2016 //ltt_time_to_double(new_time_window.start_time)
2017 // * NANOSECONDS_PER_SECOND, /* value */
2022 ltt_time_sub(time_span
.end_time
, time_span
.start_time
))
2023 * NANOSECONDS_PER_SECOND
, /* upper */
2025 ltt_time_to_double(new_time_window
.time_width
)
2026 / SCROLL_STEP_PER_PAGE
2027 * NANOSECONDS_PER_SECOND
, /* step increment */
2029 ltt_time_to_double(new_time_window
.time_width
)
2030 * NANOSECONDS_PER_SECOND
, /* page increment */
2032 ltt_time_to_double(new_time_window
.time_width
)
2033 * NANOSECONDS_PER_SECOND
, /* page size */
2035 gtk_adjustment_changed(adjustment
);
2036 //gtk_range_set_adjustment(GTK_RANGE(tab->scrollbar), adjustment);
2037 //gtk_adjustment_value_changed(adjustment);
2038 g_object_set(G_OBJECT(adjustment
),
2041 ltt_time_sub(new_time_window
.start_time
, time_span
.start_time
))
2042 * NANOSECONDS_PER_SECOND
, /* value */
2044 gtk_adjustment_value_changed(adjustment
);
2047 //g_object_set(G_OBJECT(adjustment),
2049 // ltt_time_to_double(time_window->start_time)
2050 // * NANOSECONDS_PER_SECOND, /* value */
2052 /* Note : the set value will call set_time_window if scrollbar value changed
2054 //gtk_adjustment_set_value(adjustment,
2055 // ltt_time_to_double(new_time_window.start_time)
2056 // * NANOSECONDS_PER_SECOND);
2060 void zoom_in(GtkWidget
* widget
, gpointer user_data
)
2065 void zoom_out(GtkWidget
* widget
, gpointer user_data
)
2070 void zoom_extended(GtkWidget
* widget
, gpointer user_data
)
2075 void go_to_time(GtkWidget
* widget
, gpointer user_data
)
2077 g_printf("Go to time\n");
2080 void show_time_frame(GtkWidget
* widget
, gpointer user_data
)
2082 g_printf("Show time frame\n");
2086 /* callback function */
2089 on_empty_traceset_activate (GtkMenuItem
*menuitem
,
2092 create_new_window((GtkWidget
*)menuitem
, user_data
, FALSE
);
2097 on_clone_traceset_activate (GtkMenuItem
*menuitem
,
2100 create_new_window((GtkWidget
*)menuitem
, user_data
, TRUE
);
2104 /* create_new_tab calls create_tab to construct a new tab in the main window
2107 Tab
*create_new_tab(GtkWidget
* widget
, gpointer user_data
){
2108 gchar label
[PATH_MAX
];
2109 MainWindow
* mw_data
= get_window_data_struct(widget
);
2111 GtkNotebook
* notebook
= (GtkNotebook
*)lookup_widget(widget
, "MNotebook");
2112 if(notebook
== NULL
){
2113 g_printf("Notebook does not exist\n");
2116 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2117 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2123 copy_tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
2126 strcpy(label
,"Page");
2127 if(get_label(mw_data
, label
,"Get the name of the tab","Please input tab's name"))
2128 return (create_tab (mw_data
, copy_tab
, notebook
, label
));
2132 on_tab_activate (GtkMenuItem
*menuitem
,
2135 create_new_tab((GtkWidget
*)menuitem
, user_data
);
2140 on_open_activate (GtkMenuItem
*menuitem
,
2143 open_traceset((GtkWidget
*)menuitem
, user_data
);
2148 on_close_activate (GtkMenuItem
*menuitem
,
2151 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2152 main_window_destructor(mw_data
);
2156 /* remove the current tab from the main window
2160 on_close_tab_activate (GtkWidget
*widget
,
2164 GtkWidget
* notebook
;
2166 MainWindow
* mw_data
= get_window_data_struct(widget
);
2167 notebook
= lookup_widget(widget
, "MNotebook");
2168 if(notebook
== NULL
){
2169 g_printf("Notebook does not exist\n");
2173 page_num
= gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
));
2175 gtk_notebook_remove_page(GTK_NOTEBOOK(notebook
), page_num
);
2180 on_close_tab_X_clicked (GtkWidget
*widget
,
2184 GtkWidget
*notebook
= lookup_widget(widget
, "MNotebook");
2185 if(notebook
== NULL
){
2186 g_printf("Notebook does not exist\n");
2190 if((page_num
= gtk_notebook_page_num(GTK_NOTEBOOK(notebook
), widget
)) != -1)
2191 gtk_notebook_remove_page(GTK_NOTEBOOK(notebook
), page_num
);
2197 on_add_trace_activate (GtkMenuItem
*menuitem
,
2200 add_trace((GtkWidget
*)menuitem
, user_data
);
2205 on_remove_trace_activate (GtkMenuItem
*menuitem
,
2208 remove_trace((GtkWidget
*)menuitem
, user_data
);
2213 on_save_activate (GtkMenuItem
*menuitem
,
2216 save((GtkWidget
*)menuitem
, user_data
);
2221 on_save_as_activate (GtkMenuItem
*menuitem
,
2224 save_as((GtkWidget
*)menuitem
, user_data
);
2229 on_quit_activate (GtkMenuItem
*menuitem
,
2237 on_cut_activate (GtkMenuItem
*menuitem
,
2245 on_copy_activate (GtkMenuItem
*menuitem
,
2248 g_printf("Copye\n");
2253 on_paste_activate (GtkMenuItem
*menuitem
,
2256 g_printf("Paste\n");
2261 on_delete_activate (GtkMenuItem
*menuitem
,
2264 g_printf("Delete\n");
2269 on_zoom_in_activate (GtkMenuItem
*menuitem
,
2272 zoom_in((GtkWidget
*)menuitem
, user_data
);
2277 on_zoom_out_activate (GtkMenuItem
*menuitem
,
2280 zoom_out((GtkWidget
*)menuitem
, user_data
);
2285 on_zoom_extended_activate (GtkMenuItem
*menuitem
,
2288 zoom_extended((GtkWidget
*)menuitem
, user_data
);
2293 on_go_to_time_activate (GtkMenuItem
*menuitem
,
2296 go_to_time((GtkWidget
*)menuitem
, user_data
);
2301 on_show_time_frame_activate (GtkMenuItem
*menuitem
,
2304 show_time_frame((GtkWidget
*)menuitem
, user_data
);
2309 on_move_viewer_up_activate (GtkMenuItem
*menuitem
,
2312 move_up_viewer((GtkWidget
*)menuitem
, user_data
);
2317 on_move_viewer_down_activate (GtkMenuItem
*menuitem
,
2320 move_down_viewer((GtkWidget
*)menuitem
, user_data
);
2325 on_remove_viewer_activate (GtkMenuItem
*menuitem
,
2328 delete_viewer((GtkWidget
*)menuitem
, user_data
);
2333 on_trace_filter_activate (GtkMenuItem
*menuitem
,
2336 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2337 LttvTracesetSelector
* s
;
2339 GtkWidget
* notebook
= lookup_widget(GTK_WIDGET(menuitem
), "MNotebook");
2341 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2342 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2348 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
2351 w
= gtk_multivpaned_get_widget(GTK_MULTIVPANED(tab
->multivpaned
));
2353 s
= g_object_get_data(G_OBJECT(w
), "Traceset_Selector");
2355 g_printf("There is no viewer yet\n");
2358 if(get_filter_selection(s
, "Configure trace and tracefile filter", "Select traces and tracefiles")){
2359 //FIXME report filter change
2360 //update_traceset(mw_data);
2361 //call_pending_read_hooks(mw_data);
2362 //lttvwindow_report_current_time(mw_data,&(tab->current_time));
2368 on_trace_facility_activate (GtkMenuItem
*menuitem
,
2371 g_printf("Trace facility selector: %s\n");
2375 /* Dispaly a file selection dialogue to let user select a library, then call
2376 * lttv_library_load().
2380 on_load_library_activate (GtkMenuItem
*menuitem
,
2383 GError
*error
= NULL
;
2384 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2386 gchar load_module_path_alter
[PATH_MAX
];
2390 gchar
*load_module_path
;
2391 name
= g_ptr_array_new();
2392 nb
= lttv_library_path_number();
2393 /* ask for the library path */
2397 path
= lttv_library_path_get(i
);
2398 g_ptr_array_add(name
, path
);
2401 load_module_path
= get_selection((char **)(name
->pdata
), name
->len
,
2402 "Select a library path", "Library paths");
2403 if(load_module_path
!= NULL
)
2404 strncpy(load_module_path_alter
, load_module_path
, PATH_MAX
-1); // -1 for /
2406 g_ptr_array_free(name
, TRUE
);
2408 if(load_module_path
== NULL
) return;
2412 /* Make sure the module path ends with a / */
2413 gchar
*ptr
= load_module_path_alter
;
2415 ptr
= strchr(ptr
, '\0');
2417 if(*(ptr
-1) != '/') {
2424 /* Ask for the library to load : list files in the previously selected
2426 gchar str
[PATH_MAX
];
2429 GtkFileSelection
* file_selector
=
2430 (GtkFileSelection
*)gtk_file_selection_new("Select a module");
2431 gtk_file_selection_set_filename(file_selector
, load_module_path_alter
);
2432 gtk_file_selection_hide_fileop_buttons(file_selector
);
2435 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
2437 case GTK_RESPONSE_ACCEPT
:
2438 case GTK_RESPONSE_OK
:
2439 dir
= gtk_file_selection_get_selections (file_selector
);
2440 strncpy(str
,dir
[0],PATH_MAX
);
2441 strncpy(remember_plugins_dir
,dir
[0],PATH_MAX
);
2442 /* only keep file name */
2444 str1
= strrchr(str
,'/');
2447 str1
= strrchr(str
,'\\');
2452 if(*str1
== 'l' && *(str1
+1)== 'i' && *(str1
+2)=='b')
2454 remove info after
. */
2458 str2
= strrchr(str2
, '.');
2459 if(str2
!= NULL
) *str2
= '\0';
2461 lttv_module_require(str1
, &error
);
2463 lttv_library_load(str1
, &error
);
2464 if(error
!= NULL
) g_warning(error
->message
);
2465 else g_printf("Load library: %s\n", str
);
2467 case GTK_RESPONSE_REJECT
:
2468 case GTK_RESPONSE_CANCEL
:
2470 gtk_widget_destroy((GtkWidget
*)file_selector
);
2481 /* Display all loaded modules, let user to select a module to unload
2482 * by calling lttv_module_unload
2486 on_unload_library_activate (GtkMenuItem
*menuitem
,
2489 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2491 LttvLibrary
*library
;
2496 name
= g_ptr_array_new();
2497 nb
= lttv_library_number();
2498 LttvLibraryInfo
*lib_info
= g_new(LttvLibraryInfo
,nb
);
2499 /* ask for the library name */
2502 LttvLibrary
*iter_lib
= lttv_library_get(i
);
2503 lttv_library_info(iter_lib
, &lib_info
[i
]);
2505 gchar
*path
= lib_info
[i
].name
;
2506 g_ptr_array_add(name
, lib_info
[i
].name
);
2508 lib_name
= get_selection((char **)(name
->pdata
), name
->len
,
2509 "Select a library", "Libraries");
2510 if(lib_name
!= NULL
) {
2512 if(strcmp(lib_name
, lib_info
[i
].name
) == 0) {
2513 library
= lttv_library_get(i
);
2518 g_ptr_array_free(name
, TRUE
);
2521 if(lib_name
== NULL
) return;
2524 lttv_library_unload(library
);
2528 /* Dispaly a file selection dialogue to let user select a module, then call
2529 * lttv_module_require().
2533 on_load_module_activate (GtkMenuItem
*menuitem
,
2536 GError
*error
= NULL
;
2537 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2539 LttvLibrary
*library
;
2544 name
= g_ptr_array_new();
2545 nb
= lttv_library_number();
2546 LttvLibraryInfo
*lib_info
= g_new(LttvLibraryInfo
,nb
);
2547 /* ask for the library name */
2550 LttvLibrary
*iter_lib
= lttv_library_get(i
);
2551 lttv_library_info(iter_lib
, &lib_info
[i
]);
2553 gchar
*path
= lib_info
[i
].name
;
2554 g_ptr_array_add(name
, path
);
2556 lib_name
= get_selection((char **)(name
->pdata
), name
->len
,
2557 "Select a library", "Libraries");
2558 if(lib_name
!= NULL
) {
2560 if(strcmp(lib_name
, lib_info
[i
].name
) == 0) {
2561 library
= lttv_library_get(i
);
2566 g_ptr_array_free(name
, TRUE
);
2569 if(lib_name
== NULL
) return;
2572 //LttvModule *module;
2573 gchar module_name_out
[PATH_MAX
];
2575 /* Ask for the module to load : list modules in the selected lib */
2579 LttvModuleInfo
*module_info
= g_new(LttvModuleInfo
,nb
);
2580 name
= g_ptr_array_new();
2581 nb
= lttv_library_module_number(library
);
2582 /* ask for the module name */
2585 LttvModule
*iter_module
= lttv_library_module_get(library
, i
);
2586 lttv_module_info(iter_module
, &module_info
[i
]);
2588 gchar
*path
= module_info
[i
].name
;
2589 g_ptr_array_add(name
, path
);
2591 module_name
= get_selection((char **)(name
->pdata
), name
->len
,
2592 "Select a module", "Modules");
2593 if(module_name
!= NULL
) {
2595 if(strcmp(module_name
, module_info
[i
].name
) == 0) {
2596 strncpy(module_name_out
, module_name
, PATH_MAX
);
2597 //module = lttv_library_module_get(i);
2603 g_ptr_array_free(name
, TRUE
);
2604 g_free(module_info
);
2606 if(module_name
== NULL
) return;
2609 lttv_module_require(module_name_out
, &error
);
2610 if(error
!= NULL
) g_warning(error
->message
);
2611 else g_printf("Load module: %s\n", module_name_out
);
2618 gchar str
[PATH_MAX
];
2621 GtkFileSelection
* file_selector
=
2622 (GtkFileSelection
*)gtk_file_selection_new("Select a module");
2623 gtk_file_selection_set_filename(file_selector
, load_module_path_alter
);
2624 gtk_file_selection_hide_fileop_buttons(file_selector
);
2627 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
2629 case GTK_RESPONSE_ACCEPT
:
2630 case GTK_RESPONSE_OK
:
2631 dir
= gtk_file_selection_get_selections (file_selector
);
2632 strncpy(str
,dir
[0],PATH_MAX
);
2633 strncpy(remember_plugins_dir
,dir
[0],PATH_MAX
);
2635 /* only keep file name */
2637 str1
= strrchr(str
,'/');
2640 str1
= strrchr(str
,'\\');
2645 if(*str1
== 'l' && *(str1
+1)== 'i' && *(str1
+2)=='b')
2647 remove info after
. */
2651 str2
= strrchr(str2
, '.');
2652 if(str2
!= NULL
) *str2
= '\0';
2654 lttv_module_require(str1
, &error
);
2656 lttv_library_load(str1
, &error
);
2657 if(error
!= NULL
) g_warning(error
->message
);
2658 else g_printf("Load library: %s\n", str
);
2660 case GTK_RESPONSE_REJECT
:
2661 case GTK_RESPONSE_CANCEL
:
2663 gtk_widget_destroy((GtkWidget
*)file_selector
);
2675 /* Display all loaded modules, let user to select a module to unload
2676 * by calling lttv_module_unload
2680 on_unload_module_activate (GtkMenuItem
*menuitem
,
2683 GError
*error
= NULL
;
2684 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2686 LttvLibrary
*library
;
2691 name
= g_ptr_array_new();
2692 nb
= lttv_library_number();
2693 LttvLibraryInfo
*lib_info
= g_new(LttvLibraryInfo
,nb
);
2694 /* ask for the library name */
2697 LttvLibrary
*iter_lib
= lttv_library_get(i
);
2698 lttv_library_info(iter_lib
, &lib_info
[i
]);
2700 gchar
*path
= lib_info
[i
].name
;
2701 g_ptr_array_add(name
, path
);
2703 lib_name
= get_selection((char **)(name
->pdata
), name
->len
,
2704 "Select a library", "Libraries");
2705 if(lib_name
!= NULL
) {
2707 if(strcmp(lib_name
, lib_info
[i
].name
) == 0) {
2708 library
= lttv_library_get(i
);
2713 g_ptr_array_free(name
, TRUE
);
2716 if(lib_name
== NULL
) return;
2721 /* Ask for the module to load : list modules in the selected lib */
2725 nb
= lttv_library_module_number(library
);
2726 LttvModuleInfo
*module_info
= g_new(LttvModuleInfo
,nb
);
2727 name
= g_ptr_array_new();
2728 /* ask for the module name */
2731 LttvModule
*iter_module
= lttv_library_module_get(library
, i
);
2732 lttv_module_info(iter_module
, &module_info
[i
]);
2734 gchar
*path
= module_info
[i
].name
;
2735 if(module_info
[i
].use_count
> 0) g_ptr_array_add(name
, path
);
2737 module_name
= get_selection((char **)(name
->pdata
), name
->len
,
2738 "Select a module", "Modules");
2739 if(module_name
!= NULL
) {
2741 if(strcmp(module_name
, module_info
[i
].name
) == 0) {
2742 module
= lttv_library_module_get(library
, i
);
2748 g_ptr_array_free(name
, TRUE
);
2749 g_free(module_info
);
2751 if(module_name
== NULL
) return;
2754 LttvModuleInfo module_info
;
2755 lttv_module_info(module
, &module_info
);
2756 g_printf("Release module: %s\n", module_info
.name
);
2758 lttv_module_release(module
);
2762 /* Display a directory dialogue to let user select a path for library searching
2766 on_add_library_search_path_activate (GtkMenuItem
*menuitem
,
2769 GtkDirSelection
* file_selector
= (GtkDirSelection
*)gtk_dir_selection_new("Select library path");
2773 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2774 if(remember_plugins_dir
[0] != '\0')
2775 gtk_dir_selection_set_filename(file_selector
, remember_plugins_dir
);
2777 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
2779 case GTK_RESPONSE_ACCEPT
:
2780 case GTK_RESPONSE_OK
:
2781 dir
= gtk_dir_selection_get_dir (file_selector
);
2782 strncpy(remember_plugins_dir
,dir
,PATH_MAX
);
2783 strncat(remember_plugins_dir
,"/",PATH_MAX
);
2784 lttv_library_path_add(dir
);
2785 case GTK_RESPONSE_REJECT
:
2786 case GTK_RESPONSE_CANCEL
:
2788 gtk_widget_destroy((GtkWidget
*)file_selector
);
2794 /* Display a directory dialogue to let user select a path for library searching
2798 on_remove_library_search_path_activate (GtkMenuItem
*menuitem
,
2801 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2803 const char *lib_path
;
2808 name
= g_ptr_array_new();
2809 nb
= lttv_library_path_number();
2810 /* ask for the library name */
2813 gchar
*path
= lttv_library_path_get(i
);
2814 g_ptr_array_add(name
, path
);
2816 lib_path
= get_selection((char **)(name
->pdata
), name
->len
,
2817 "Select a library path", "Library paths");
2819 g_ptr_array_free(name
, TRUE
);
2821 if(lib_path
== NULL
) return;
2824 lttv_library_path_remove(lib_path
);
2828 on_color_activate (GtkMenuItem
*menuitem
,
2831 g_printf("Color\n");
2836 on_filter_activate (GtkMenuItem
*menuitem
,
2839 g_printf("Filter\n");
2844 on_save_configuration_activate (GtkMenuItem
*menuitem
,
2847 g_printf("Save configuration\n");
2852 on_content_activate (GtkMenuItem
*menuitem
,
2855 g_printf("Content\n");
2860 on_about_close_activate (GtkButton
*button
,
2863 GtkWidget
*about_widget
= GTK_WIDGET(user_data
);
2865 gtk_widget_destroy(about_widget
);
2869 on_about_activate (GtkMenuItem
*menuitem
,
2872 MainWindow
*main_window
= get_window_data_struct(GTK_WIDGET(menuitem
));
2873 GtkWidget
*window_widget
= main_window
->mwindow
;
2874 GtkWidget
*about_widget
= gtk_window_new(GTK_WINDOW_TOPLEVEL
);
2875 GtkWindow
*about_window
= GTK_WINDOW(about_widget
);
2876 gint window_width
, window_height
;
2878 gtk_window_set_title(about_window
, "About Linux Trace Toolkit");
2880 gtk_window_set_resizable(about_window
, FALSE
);
2881 gtk_window_set_transient_for(GTK_WINDOW(window_widget
), about_window
);
2882 gtk_window_set_destroy_with_parent(about_window
, TRUE
);
2883 gtk_window_set_modal(about_window
, FALSE
);
2885 /* Put the about window at the center of the screen */
2886 gtk_window_get_size(about_window
, &window_width
, &window_height
);
2887 gtk_window_move (about_window
,
2888 (gdk_screen_width() - window_width
)/2,
2889 (gdk_screen_height() - window_height
)/2);
2891 GtkWidget
*vbox
= gtk_vbox_new(FALSE
, 1);
2893 gtk_container_add(GTK_CONTAINER(about_widget
), vbox
);
2897 GtkWidget
*label1
= gtk_label_new("");
2898 gtk_misc_set_padding(GTK_MISC(label1
), 10, 20);
2899 gtk_label_set_markup(GTK_LABEL(label1
), "\
2900 <big>Linux Trace Toolkit</big>");
2901 gtk_label_set_justify(GTK_LABEL(label1
), GTK_JUSTIFY_CENTER
);
2903 GtkWidget
*label2
= gtk_label_new("");
2904 gtk_misc_set_padding(GTK_MISC(label2
), 10, 20);
2905 gtk_label_set_markup(GTK_LABEL(label2
), "\
2906 Project author: Karim Yaghmour\n\
2910 Michel Dagenais (New trace format, lttv main)\n\
2911 Mathieu Desnoyers (Directory structure, build with automake/conf,\n\
2912 lttv gui, control flow view, gui green threads\n\
2913 with interruptible foreground and background computation,\n\
2914 detailed event list)\n\
2915 Benoit Des Ligneris (Cluster adaptation)\n\
2916 Xang-Xiu Yang (new trace reading library and converter, lttv gui, \n\
2917 detailed event list and statistics view)\n\
2918 Tom Zanussi (RelayFS)");
2920 GtkWidget
*label3
= gtk_label_new("");
2921 gtk_label_set_markup(GTK_LABEL(label3
), "\
2922 Linux Trace Toolkit, Copyright (C) 2004 Karim Yaghmour\n\
2923 Linux Trace Toolkit comes with ABSOLUTELY NO WARRANTY.\n\
2924 This is free software, and you are welcome to redistribute it\n\
2925 under certain conditions. See COPYING for details.");
2926 gtk_misc_set_padding(GTK_MISC(label3
), 10, 20);
2928 gtk_box_pack_start_defaults(GTK_BOX(vbox
), label1
);
2929 gtk_box_pack_start_defaults(GTK_BOX(vbox
), label2
);
2930 gtk_box_pack_start_defaults(GTK_BOX(vbox
), label3
);
2932 GtkWidget
*hbox
= gtk_hbox_new(TRUE
, 0);
2933 gtk_box_pack_end(GTK_BOX(vbox
), hbox
, FALSE
, FALSE
, 0);
2934 GtkWidget
*close_button
= gtk_button_new_with_mnemonic("_Close");
2935 gtk_box_pack_end(GTK_BOX(hbox
), close_button
, FALSE
, FALSE
, 0);
2936 gtk_container_set_border_width(GTK_CONTAINER(close_button
), 20);
2938 g_signal_connect(G_OBJECT(close_button
), "clicked",
2939 G_CALLBACK(on_about_close_activate
),
2940 (gpointer
)about_widget
);
2942 gtk_widget_show_all(about_widget
);
2947 on_button_new_clicked (GtkButton
*button
,
2950 create_new_window((GtkWidget
*)button
, user_data
, TRUE
);
2954 on_button_new_tab_clicked (GtkButton
*button
,
2957 create_new_tab((GtkWidget
*)button
, user_data
);
2961 on_button_open_clicked (GtkButton
*button
,
2964 open_traceset((GtkWidget
*)button
, user_data
);
2969 on_button_add_trace_clicked (GtkButton
*button
,
2972 add_trace((GtkWidget
*)button
, user_data
);
2977 on_button_remove_trace_clicked (GtkButton
*button
,
2980 remove_trace((GtkWidget
*)button
, user_data
);
2984 on_button_redraw_clicked (GtkButton
*button
,
2987 redraw((GtkWidget
*)button
, user_data
);
2991 on_button_continue_processing_clicked (GtkButton
*button
,
2994 continue_processing((GtkWidget
*)button
, user_data
);
2998 on_button_stop_processing_clicked (GtkButton
*button
,
3001 stop_processing((GtkWidget
*)button
, user_data
);
3007 on_button_save_clicked (GtkButton
*button
,
3010 save((GtkWidget
*)button
, user_data
);
3015 on_button_save_as_clicked (GtkButton
*button
,
3018 save_as((GtkWidget
*)button
, user_data
);
3023 on_button_zoom_in_clicked (GtkButton
*button
,
3026 zoom_in((GtkWidget
*)button
, user_data
);
3031 on_button_zoom_out_clicked (GtkButton
*button
,
3034 zoom_out((GtkWidget
*)button
, user_data
);
3039 on_button_zoom_extended_clicked (GtkButton
*button
,
3042 zoom_extended((GtkWidget
*)button
, user_data
);
3047 on_button_go_to_time_clicked (GtkButton
*button
,
3050 go_to_time((GtkWidget
*)button
, user_data
);
3055 on_button_show_time_frame_clicked (GtkButton
*button
,
3058 show_time_frame((GtkWidget
*)button
, user_data
);
3063 on_button_move_up_clicked (GtkButton
*button
,
3066 move_up_viewer((GtkWidget
*)button
, user_data
);
3071 on_button_move_down_clicked (GtkButton
*button
,
3074 move_down_viewer((GtkWidget
*)button
, user_data
);
3079 on_button_delete_viewer_clicked (GtkButton
*button
,
3082 delete_viewer((GtkWidget
*)button
, user_data
);
3086 on_MWindow_destroy (GtkWidget
*widget
,
3089 MainWindow
*main_window
= get_window_data_struct(widget
);
3090 LttvIAttribute
*attributes
= main_window
->attributes
;
3091 LttvAttributeValue value
;
3093 //This is unnecessary, since widgets will be destroyed
3094 //by the main window widget anyway.
3095 //remove_all_menu_toolbar_constructors(main_window, NULL);
3097 g_assert(lttv_iattribute_find_by_path(attributes
,
3098 "viewers/menu", LTTV_POINTER
, &value
));
3099 lttv_menus_destroy((LttvMenus
*)*(value
.v_pointer
));
3101 g_assert(lttv_iattribute_find_by_path(attributes
,
3102 "viewers/toolbar", LTTV_POINTER
, &value
));
3103 lttv_toolbars_destroy((LttvToolbars
*)*(value
.v_pointer
));
3105 g_object_unref(main_window
->attributes
);
3106 g_main_window_list
= g_slist_remove(g_main_window_list
, main_window
);
3108 g_printf("There are now : %d windows\n",g_slist_length(g_main_window_list
));
3109 if(g_slist_length(g_main_window_list
) == 0)
3114 on_MWindow_configure (GtkWidget
*widget
,
3115 GdkEventConfigure
*event
,
3118 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)widget
);
3119 float width
= event
->width
;
3120 TimeWindow time_win
;
3122 TimeInterval
*time_span
;
3125 // MD : removed time width modification upon resizing of the main window.
3126 // The viewers will redraw themselves completely, without time interval
3129 if(mw_data->window_width){
3130 time_span = LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context)->Time_Span ;
3131 time_win = tab->time_window;
3132 ratio = width / mw_data->window_width;
3133 tab->time_window.time_width = ltt_time_mul(time_win.time_width,ratio);
3134 time = ltt_time_sub(time_span->endTime, time_win.start_time);
3135 if(ltt_time_compare(time, tab->time_window.time_width) < 0){
3136 tab->time_window.time_width = time;
3142 mw_data->window_width = (int)width;
3151 on_MNotebook_switch_page (GtkNotebook
*notebook
,
3152 GtkNotebookPage
*page
,
3160 void scroll_value_changed_cb(GtkWidget
*scrollbar
,
3163 Tab
*tab
= (Tab
*)user_data
;
3164 TimeWindow time_window
;
3166 GtkAdjustment
*adjust
= gtk_range_get_adjustment(GTK_RANGE(scrollbar
));
3167 gdouble value
= gtk_adjustment_get_value(adjust
);
3168 gdouble upper
, lower
, ratio
, page_size
;
3169 LttvTracesetContext
* tsc
=
3170 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3171 TimeInterval time_span
= tsc
->time_span
;
3173 //time_window = tab->time_window;
3175 lower
= adjust
->lower
;
3176 upper
= adjust
->upper
;
3177 ratio
= (value
- lower
) / (upper
- lower
);
3178 g_info("lower %lu, upper %lu, value %lu, ratio %lu", lower
, upper
, value
, ratio
);
3180 //time = ltt_time_sub(time_span->end_time, time_span->start_time);
3181 //time = ltt_time_mul(time, (float)ratio);
3182 //time = ltt_time_add(time_span->start_time, time);
3183 time
= ltt_time_add(ltt_time_from_double(value
/NANOSECONDS_PER_SECOND
),
3184 time_span
.start_time
);
3186 time_window
.start_time
= time
;
3188 page_size
= adjust
->page_size
;
3190 time_window
.time_width
=
3191 ltt_time_from_double(page_size
/NANOSECONDS_PER_SECOND
);
3192 //time = ltt_time_sub(time_span.end_time, time);
3193 //if(ltt_time_compare(time,time_window.time_width) < 0){
3194 // time_window.time_width = time;
3197 /* call viewer hooks for new time window */
3198 set_time_window(tab
, &time_window
);
3203 /* callback function to check or uncheck the check box (filter)
3206 void checkbox_changed(GtkTreeView
*treeview
,
3208 GtkTreeViewColumn
*arg2
,
3211 GtkTreeStore
* store
= (GtkTreeStore
*)gtk_tree_view_get_model (treeview
);
3215 if (gtk_tree_model_get_iter ((GtkTreeModel
*)store
, &iter
, arg1
)){
3216 gtk_tree_model_get ((GtkTreeModel
*)store
, &iter
, CHECKBOX_COLUMN
, &value
, -1);
3217 value
= value
? FALSE
: TRUE
;
3218 gtk_tree_store_set (GTK_TREE_STORE (store
), &iter
, CHECKBOX_COLUMN
, value
, -1);
3224 /* According to user's selection, update selector(filter)
3227 void update_filter(LttvTracesetSelector
*s
, GtkTreeStore
*store
)
3229 GtkTreeIter iter
, child_iter
, child_iter1
, child_iter2
;
3230 int i
, j
, k
, nb_eventtype
;
3231 LttvTraceSelector
* trace
;
3232 LttvTracefileSelector
* tracefile
;
3233 LttvEventtypeSelector
* eventtype
;
3234 gboolean value
, value1
, value2
;
3236 if(gtk_tree_model_get_iter_first((GtkTreeModel
*)store
, &iter
)){
3239 trace
= lttv_traceset_selector_trace_get(s
, i
);
3240 nb_eventtype
= lttv_trace_selector_eventtype_number(trace
);
3241 gtk_tree_model_get ((GtkTreeModel
*)store
, &iter
, CHECKBOX_COLUMN
, &value
,-1);
3244 if(gtk_tree_model_iter_children ((GtkTreeModel
*)store
, &child_iter
, &iter
)){
3246 if(j
<1){//eventtype selector for trace
3247 gtk_tree_model_get ((GtkTreeModel
*)store
, &child_iter
, CHECKBOX_COLUMN
, &value2
,-1);
3250 if(gtk_tree_model_iter_children ((GtkTreeModel
*)store
, &child_iter1
, &child_iter
)){
3252 eventtype
= lttv_trace_selector_eventtype_get(trace
,k
);
3253 gtk_tree_model_get ((GtkTreeModel
*)store
, &child_iter1
, CHECKBOX_COLUMN
, &value2
,-1);
3254 lttv_eventtype_selector_set_selected(eventtype
,value2
);
3256 }while(gtk_tree_model_iter_next((GtkTreeModel
*)store
, &child_iter1
));
3259 }else{ //tracefile selector
3260 tracefile
= lttv_trace_selector_tracefile_get(trace
, j
- 1);
3261 gtk_tree_model_get ((GtkTreeModel
*)store
, &child_iter
, CHECKBOX_COLUMN
, &value1
,-1);
3262 lttv_tracefile_selector_set_selected(tracefile
,value1
);
3264 gtk_tree_model_iter_children((GtkTreeModel
*)store
, &child_iter1
, &child_iter
); //eventtype selector
3265 gtk_tree_model_get ((GtkTreeModel
*)store
, &child_iter1
, CHECKBOX_COLUMN
, &value2
,-1);
3268 if(gtk_tree_model_iter_children ((GtkTreeModel
*)store
, &child_iter2
, &child_iter1
)){
3269 do{//eventtype selector for tracefile
3270 eventtype
= lttv_tracefile_selector_eventtype_get(tracefile
,k
);
3271 gtk_tree_model_get ((GtkTreeModel
*)store
, &child_iter2
, CHECKBOX_COLUMN
, &value2
,-1);
3272 lttv_eventtype_selector_set_selected(eventtype
,value2
);
3274 }while(gtk_tree_model_iter_next((GtkTreeModel
*)store
, &child_iter2
));
3280 }while(gtk_tree_model_iter_next((GtkTreeModel
*)store
, &child_iter
));
3283 lttv_trace_selector_set_selected(trace
,value
);
3285 }while(gtk_tree_model_iter_next((GtkTreeModel
*)store
, &iter
));
3290 /* Display a dialogue showing all eventtypes and traces, let user to select the interested
3291 * eventtypes, tracefiles and traces (filter)
3294 gboolean
get_filter_selection(LttvTracesetSelector
*s
,char *title
, char * column_title
)
3296 GtkWidget
* dialogue
;
3297 GtkTreeStore
* store
;
3299 GtkWidget
* scroll_win
;
3300 GtkCellRenderer
* renderer
;
3301 GtkTreeViewColumn
* column
;
3302 GtkTreeIter iter
, child_iter
, child_iter1
, child_iter2
;
3303 int i
, j
, k
, id
, nb_trace
, nb_tracefile
, nb_eventtype
;
3304 LttvTraceSelector
* trace
;
3305 LttvTracefileSelector
* tracefile
;
3306 LttvEventtypeSelector
* eventtype
;
3310 dialogue
= gtk_dialog_new_with_buttons(title
,
3313 GTK_STOCK_OK
,GTK_RESPONSE_ACCEPT
,
3314 GTK_STOCK_CANCEL
,GTK_RESPONSE_REJECT
,
3316 gtk_window_set_default_size((GtkWindow
*)dialogue
, 300, 500);
3318 store
= gtk_tree_store_new (TOTAL_COLUMNS
, G_TYPE_BOOLEAN
, G_TYPE_STRING
);
3319 tree
= gtk_tree_view_new_with_model (GTK_TREE_MODEL (store
));
3320 g_object_unref (G_OBJECT (store
));
3321 g_signal_connect (G_OBJECT (tree
), "row-activated",
3322 G_CALLBACK (checkbox_changed
),
3326 renderer
= gtk_cell_renderer_toggle_new ();
3327 gtk_cell_renderer_toggle_set_radio((GtkCellRendererToggle
*)renderer
, FALSE
);
3329 g_object_set (G_OBJECT (renderer
),"activatable", TRUE
, NULL
);
3331 column
= gtk_tree_view_column_new_with_attributes ("Checkbox",
3333 "active", CHECKBOX_COLUMN
,
3335 gtk_tree_view_column_set_alignment (column
, 0.5);
3336 gtk_tree_view_column_set_fixed_width (column
, 20);
3337 gtk_tree_view_append_column (GTK_TREE_VIEW (tree
), column
);
3339 renderer
= gtk_cell_renderer_text_new ();
3340 column
= gtk_tree_view_column_new_with_attributes (column_title
,
3342 "text", NAME_COLUMN
,
3344 gtk_tree_view_column_set_alignment (column
, 0.0);
3345 gtk_tree_view_append_column (GTK_TREE_VIEW (tree
), column
);
3346 gtk_tree_view_set_headers_visible(GTK_TREE_VIEW (tree
), FALSE
);
3348 scroll_win
= gtk_scrolled_window_new (NULL
, NULL
);
3349 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll_win
),
3350 GTK_POLICY_AUTOMATIC
,GTK_POLICY_AUTOMATIC
);
3351 gtk_container_add (GTK_CONTAINER (scroll_win
), tree
);
3353 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialogue
)->vbox
), scroll_win
,TRUE
, TRUE
,0);
3355 gtk_widget_show(scroll_win
);
3356 gtk_widget_show(tree
);
3358 nb_trace
= lttv_traceset_selector_trace_number(s
);
3359 for(i
=0;i
<nb_trace
;i
++){
3360 trace
= lttv_traceset_selector_trace_get(s
, i
);
3361 name
= lttv_trace_selector_get_name(trace
);
3362 gtk_tree_store_append (store
, &iter
, NULL
);
3363 checked
= lttv_trace_selector_get_selected(trace
);
3364 gtk_tree_store_set (store
, &iter
,
3365 CHECKBOX_COLUMN
,checked
,
3369 gtk_tree_store_append (store
, &child_iter
, &iter
);
3370 gtk_tree_store_set (store
, &child_iter
,
3371 CHECKBOX_COLUMN
, checked
,
3372 NAME_COLUMN
,"eventtype",
3375 nb_eventtype
= lttv_trace_selector_eventtype_number(trace
);
3376 for(j
=0;j
<nb_eventtype
;j
++){
3377 eventtype
= lttv_trace_selector_eventtype_get(trace
,j
);
3378 name
= lttv_eventtype_selector_get_name(eventtype
);
3379 checked
= lttv_eventtype_selector_get_selected(eventtype
);
3380 gtk_tree_store_append (store
, &child_iter1
, &child_iter
);
3381 gtk_tree_store_set (store
, &child_iter1
,
3382 CHECKBOX_COLUMN
, checked
,
3387 nb_tracefile
= lttv_trace_selector_tracefile_number(trace
);
3388 for(j
=0;j
<nb_tracefile
;j
++){
3389 tracefile
= lttv_trace_selector_tracefile_get(trace
, j
);
3390 name
= lttv_tracefile_selector_get_name(tracefile
);
3391 gtk_tree_store_append (store
, &child_iter
, &iter
);
3392 checked
= lttv_tracefile_selector_get_selected(tracefile
);
3393 gtk_tree_store_set (store
, &child_iter
,
3394 CHECKBOX_COLUMN
, checked
,
3398 gtk_tree_store_append (store
, &child_iter1
, &child_iter
);
3399 gtk_tree_store_set (store
, &child_iter1
,
3400 CHECKBOX_COLUMN
, checked
,
3401 NAME_COLUMN
,"eventtype",
3404 for(k
=0;k
<nb_eventtype
;k
++){
3405 eventtype
= lttv_tracefile_selector_eventtype_get(tracefile
,k
);
3406 name
= lttv_eventtype_selector_get_name(eventtype
);
3407 checked
= lttv_eventtype_selector_get_selected(eventtype
);
3408 gtk_tree_store_append (store
, &child_iter2
, &child_iter1
);
3409 gtk_tree_store_set (store
, &child_iter2
,
3410 CHECKBOX_COLUMN
, checked
,
3417 id
= gtk_dialog_run(GTK_DIALOG(dialogue
));
3419 case GTK_RESPONSE_ACCEPT
:
3420 case GTK_RESPONSE_OK
:
3421 update_filter(s
, store
);
3422 gtk_widget_destroy(dialogue
);
3424 case GTK_RESPONSE_REJECT
:
3425 case GTK_RESPONSE_CANCEL
:
3427 gtk_widget_destroy(dialogue
);
3434 /* Select a trace which will be removed from traceset
3437 char * get_remove_trace(char ** all_trace_name
, int nb_trace
)
3439 return get_selection(all_trace_name
, nb_trace
,
3440 "Select a trace", "Trace pathname");
3444 /* Select a module which will be loaded
3447 char * get_load_module(char ** load_module_name
, int nb_module
)
3449 return get_selection(load_module_name
, nb_module
,
3450 "Select a module to load", "Module name");
3456 /* Select a module which will be unloaded
3459 char * get_unload_module(char ** loaded_module_name
, int nb_module
)
3461 return get_selection(loaded_module_name
, nb_module
,
3462 "Select a module to unload", "Module name");
3466 /* Display a dialogue which shows all selectable items, let user to
3467 * select one of them
3470 char * get_selection(char ** loaded_module_name
, int nb_module
,
3471 char *title
, char * column_title
)
3473 GtkWidget
* dialogue
;
3474 GtkWidget
* scroll_win
;
3476 GtkListStore
* store
;
3477 GtkTreeViewColumn
* column
;
3478 GtkCellRenderer
* renderer
;
3479 GtkTreeSelection
* select
;
3482 char * unload_module_name
= NULL
;
3484 dialogue
= gtk_dialog_new_with_buttons(title
,
3487 GTK_STOCK_OK
,GTK_RESPONSE_ACCEPT
,
3488 GTK_STOCK_CANCEL
,GTK_RESPONSE_REJECT
,
3490 gtk_window_set_default_size((GtkWindow
*)dialogue
, 500, 200);
3492 scroll_win
= gtk_scrolled_window_new (NULL
, NULL
);
3493 gtk_widget_show ( scroll_win
);
3494 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll_win
),
3495 GTK_POLICY_AUTOMATIC
, GTK_POLICY_AUTOMATIC
);
3497 store
= gtk_list_store_new (N_COLUMNS
,G_TYPE_STRING
);
3498 tree
= gtk_tree_view_new_with_model(GTK_TREE_MODEL (store
));
3499 gtk_widget_show ( tree
);
3500 g_object_unref (G_OBJECT (store
));
3502 renderer
= gtk_cell_renderer_text_new ();
3503 column
= gtk_tree_view_column_new_with_attributes (column_title
,
3505 "text", MODULE_COLUMN
,
3507 gtk_tree_view_column_set_alignment (column
, 0.5);
3508 gtk_tree_view_column_set_fixed_width (column
, 150);
3509 gtk_tree_view_append_column (GTK_TREE_VIEW (tree
), column
);
3511 select
= gtk_tree_view_get_selection (GTK_TREE_VIEW (tree
));
3512 gtk_tree_selection_set_mode (select
, GTK_SELECTION_SINGLE
);
3514 gtk_container_add (GTK_CONTAINER (scroll_win
), tree
);
3516 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialogue
)->vbox
), scroll_win
,TRUE
, TRUE
,0);
3518 for(i
=0;i
<nb_module
;i
++){
3519 gtk_list_store_append (store
, &iter
);
3520 gtk_list_store_set (store
, &iter
, MODULE_COLUMN
,loaded_module_name
[i
],-1);
3523 id
= gtk_dialog_run(GTK_DIALOG(dialogue
));
3525 case GTK_RESPONSE_ACCEPT
:
3526 case GTK_RESPONSE_OK
:
3527 if (gtk_tree_selection_get_selected (select
, (GtkTreeModel
**)&store
, &iter
)){
3528 gtk_tree_model_get ((GtkTreeModel
*)store
, &iter
, MODULE_COLUMN
, &unload_module_name
, -1);
3530 case GTK_RESPONSE_REJECT
:
3531 case GTK_RESPONSE_CANCEL
:
3533 gtk_widget_destroy(dialogue
);
3537 return unload_module_name
;
3541 /* Insert all menu entry and tool buttons into this main window
3546 void add_all_menu_toolbar_constructors(MainWindow
* mw
, gpointer user_data
)
3550 lttvwindow_viewer_constructor constructor
;
3551 LttvMenus
* global_menu
, * instance_menu
;
3552 LttvToolbars
* global_toolbar
, * instance_toolbar
;
3553 LttvMenuClosure
*menu_item
;
3554 LttvToolbarClosure
*toolbar_item
;
3555 LttvAttributeValue value
;
3556 LttvIAttribute
*global_attributes
= LTTV_IATTRIBUTE(lttv_global_attributes());
3557 LttvIAttribute
*attributes
= mw
->attributes
;
3558 GtkWidget
* tool_menu_title_menu
, *new_widget
, *pixmap
;
3560 g_assert(lttv_iattribute_find_by_path(global_attributes
,
3561 "viewers/menu", LTTV_POINTER
, &value
));
3562 if(*(value
.v_pointer
) == NULL
)
3563 *(value
.v_pointer
) = lttv_menus_new();
3564 global_menu
= (LttvMenus
*)*(value
.v_pointer
);
3566 g_assert(lttv_iattribute_find_by_path(attributes
,
3567 "viewers/menu", LTTV_POINTER
, &value
));
3568 if(*(value
.v_pointer
) == NULL
)
3569 *(value
.v_pointer
) = lttv_menus_new();
3570 instance_menu
= (LttvMenus
*)*(value
.v_pointer
);
3574 g_assert(lttv_iattribute_find_by_path(global_attributes
,
3575 "viewers/toolbar", LTTV_POINTER
, &value
));
3576 if(*(value
.v_pointer
) == NULL
)
3577 *(value
.v_pointer
) = lttv_toolbars_new();
3578 global_toolbar
= (LttvToolbars
*)*(value
.v_pointer
);
3580 g_assert(lttv_iattribute_find_by_path(attributes
,
3581 "viewers/toolbar", LTTV_POINTER
, &value
));
3582 if(*(value
.v_pointer
) == NULL
)
3583 *(value
.v_pointer
) = lttv_toolbars_new();
3584 instance_toolbar
= (LttvToolbars
*)*(value
.v_pointer
);
3586 /* Add missing menu entries to window instance */
3587 for(i
=0;i
<global_menu
->len
;i
++) {
3588 menu_item
= &g_array_index(global_menu
, LttvMenuClosure
, i
);
3590 //add menu_item to window instance;
3591 constructor
= menu_item
->con
;
3592 tool_menu_title_menu
= lookup_widget(mw
->mwindow
,"ToolMenuTitle_menu");
3594 gtk_menu_item_new_with_mnemonic (menu_item
->menu_text
);
3595 gtk_container_add (GTK_CONTAINER (tool_menu_title_menu
),
3597 g_signal_connect ((gpointer
) new_widget
, "activate",
3598 G_CALLBACK (insert_viewer_wrap
),
3600 gtk_widget_show (new_widget
);
3601 lttv_menus_add(instance_menu
, menu_item
->con
,
3602 menu_item
->menu_path
,
3603 menu_item
->menu_text
,
3608 /* Add missing toolbar entries to window instance */
3609 for(i
=0;i
<global_toolbar
->len
;i
++) {
3610 toolbar_item
= &g_array_index(global_toolbar
, LttvToolbarClosure
, i
);
3612 //add toolbar_item to window instance;
3613 constructor
= toolbar_item
->con
;
3614 tool_menu_title_menu
= lookup_widget(mw
->mwindow
,"MToolbar1");
3615 pixbuf
= gdk_pixbuf_new_from_xpm_data((const char**)toolbar_item
->pixmap
);
3616 pixmap
= gtk_image_new_from_pixbuf(pixbuf
);
3618 gtk_toolbar_append_element (GTK_TOOLBAR (tool_menu_title_menu
),
3619 GTK_TOOLBAR_CHILD_BUTTON
,
3622 toolbar_item
->tooltip
, NULL
,
3623 pixmap
, NULL
, NULL
);
3624 gtk_label_set_use_underline(
3625 GTK_LABEL (((GtkToolbarChild
*) (
3626 g_list_last (GTK_TOOLBAR
3627 (tool_menu_title_menu
)->children
)->data
))->label
),
3629 gtk_container_set_border_width (GTK_CONTAINER (new_widget
), 1);
3630 g_signal_connect ((gpointer
) new_widget
,
3632 G_CALLBACK (insert_viewer_wrap
),
3634 gtk_widget_show (new_widget
);
3636 lttv_toolbars_add(instance_toolbar
, toolbar_item
->con
,
3637 toolbar_item
->tooltip
,
3638 toolbar_item
->pixmap
,
3646 /* Create a main window
3649 void construct_main_window(MainWindow
* parent
)
3651 g_debug("construct_main_window()");
3652 GtkWidget
* new_window
; /* New generated main window */
3653 MainWindow
* new_m_window
;/* New main window structure */
3654 GtkNotebook
* notebook
;
3655 LttvIAttribute
*attributes
=
3656 LTTV_IATTRIBUTE(g_object_new(LTTV_ATTRIBUTE_TYPE
, NULL
));
3657 LttvAttributeValue value
;
3660 new_m_window
= g_new(MainWindow
, 1);
3662 // Add the object's information to the module's array
3663 g_main_window_list
= g_slist_append(g_main_window_list
, new_m_window
);
3666 new_window
= create_MWindow();
3667 gtk_widget_show (new_window
);
3669 new_m_window
->mwindow
= new_window
;
3670 new_m_window
->attributes
= attributes
;
3672 g_assert(lttv_iattribute_find_by_path(attributes
,
3673 "viewers/menu", LTTV_POINTER
, &value
));
3674 *(value
.v_pointer
) = lttv_menus_new();
3676 g_assert(lttv_iattribute_find_by_path(attributes
,
3677 "viewers/toolbar", LTTV_POINTER
, &value
));
3678 *(value
.v_pointer
) = lttv_toolbars_new();
3680 add_all_menu_toolbar_constructors(new_m_window
, NULL
);
3682 g_object_set_data_full(G_OBJECT(new_window
),
3684 (gpointer
)new_m_window
,
3685 (GDestroyNotify
)g_free
);
3686 //create a default tab
3687 notebook
= (GtkNotebook
*)lookup_widget(new_m_window
->mwindow
, "MNotebook");
3688 if(notebook
== NULL
){
3689 g_printf("Notebook does not exist\n");
3692 gtk_notebook_popup_enable (GTK_NOTEBOOK(notebook
));
3693 //for now there is no name field in LttvTraceset structure
3694 //Use "Traceset" as the label for the default tab
3696 GtkWidget
* parent_notebook
= lookup_widget(parent
->mwindow
, "MNotebook");
3697 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(parent_notebook
),
3698 gtk_notebook_get_current_page(GTK_NOTEBOOK(parent_notebook
)));
3704 parent_tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
3706 new_tab
= create_tab(new_m_window
, parent_tab
, notebook
, "Traceset");
3708 new_tab
= create_tab(new_m_window
, NULL
, notebook
, "Traceset");
3709 /* First window, use command line trace */
3710 if(g_init_trace
!= NULL
){
3711 lttvwindow_add_trace(new_tab
,
3714 LttvTraceset
*traceset
= new_tab
->traceset_info
->traceset
;
3715 SetTraceset(new_tab
, traceset
);
3719 g_printf("There are now : %d windows\n",g_slist_length(g_main_window_list
));
3723 /* Free the memory occupied by a tab structure
3727 void tab_destructor(Tab
* tab_instance
)
3729 int i
, nb
, ref_count
;
3732 if(tab_instance
->attributes
)
3733 g_object_unref(tab_instance
->attributes
);
3735 if(tab_instance
->interrupted_state
)
3736 g_object_unref(tab_instance
->interrupted_state
);
3739 if(tab_instance
->traceset_info
->traceset_context
!= NULL
){
3740 //remove state update hooks
3741 lttv_state_remove_event_hooks(
3742 (LttvTracesetState
*)tab_instance
->traceset_info
->
3744 lttv_context_fini(LTTV_TRACESET_CONTEXT(tab_instance
->traceset_info
->
3746 g_object_unref(tab_instance
->traceset_info
->traceset_context
);
3748 if(tab_instance
->traceset_info
->traceset
!= NULL
) {
3749 nb
= lttv_traceset_number(tab_instance
->traceset_info
->traceset
);
3750 for(i
= 0 ; i
< nb
; i
++) {
3751 trace
= lttv_traceset_get(tab_instance
->traceset_info
->traceset
, i
);
3752 ref_count
= lttv_trace_get_ref_number(trace
);
3754 ltt_trace_close(lttv_trace(trace
));
3758 lttv_traceset_destroy(tab_instance
->traceset_info
->traceset
);
3759 /* Remove the idle events requests processing function of the tab */
3760 g_idle_remove_by_data(tab_instance
);
3762 g_slist_free(tab_instance
->events_requests
);
3763 g_free(tab_instance
->traceset_info
);
3764 g_free(tab_instance
);
3768 /* Create a tab and insert it into the current main window
3771 Tab
* create_tab(MainWindow
* mw
, Tab
*copy_tab
,
3772 GtkNotebook
* notebook
, char * label
)
3778 //create a new tab data structure
3781 //construct and initialize the traceset_info
3782 tab
->traceset_info
= g_new(TracesetInfo
,1);
3785 tab
->traceset_info
->traceset
=
3786 lttv_traceset_copy(copy_tab
->traceset_info
->traceset
);
3788 tab
->traceset_info
->traceset
= lttv_traceset_new();
3792 lttv_attribute_write_xml(
3793 lttv_traceset_attribute(tab
->traceset_info
->traceset
),
3800 //FIXME copy not implemented in lower level
3801 tab
->traceset_info
->traceset_context
=
3802 g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
3803 g_assert(tab
->traceset_info
->traceset_context
!= NULL
);
3805 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
),
3806 tab
->traceset_info
->traceset
);
3807 //add state update hooks
3808 lttv_state_add_event_hooks(
3809 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
3811 //determine the current_time and time_window of the tab
3812 if(copy_tab
!= NULL
){
3813 tab
->time_window
= copy_tab
->time_window
;
3814 tab
->current_time
= copy_tab
->current_time
;
3816 tab
->time_window
.start_time
=
3817 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
3818 time_span
.start_time
;
3819 if(DEFAULT_TIME_WIDTH_S
<
3820 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
3821 time_span
.end_time
.tv_sec
)
3822 tmp_time
.tv_sec
= DEFAULT_TIME_WIDTH_S
;
3825 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
3826 time_span
.end_time
.tv_sec
;
3827 tmp_time
.tv_nsec
= 0;
3828 tab
->time_window
.time_width
= tmp_time
;
3829 tab
->current_time
.tv_sec
=
3830 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
3831 time_span
.start_time
.tv_sec
;
3832 tab
->current_time
.tv_nsec
=
3833 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
3834 time_span
.start_time
.tv_nsec
;
3836 tab
->attributes
= LTTV_IATTRIBUTE(g_object_new(LTTV_ATTRIBUTE_TYPE
, NULL
));
3837 tab
->interrupted_state
= g_object_new(LTTV_ATTRIBUTE_TYPE
, NULL
);
3839 tab
->vbox
= gtk_vbox_new(FALSE
, 2);
3840 tab
->viewer_container
= gtk_vbox_new(TRUE
, 2);
3841 tab
->scrollbar
= gtk_hscrollbar_new(NULL
);
3842 //tab->multivpaned = gtk_multi_vpaned_new();
3844 gtk_box_pack_start(GTK_BOX(tab
->vbox
),
3845 tab
->viewer_container
,
3847 TRUE
, /* Give the extra space to the child */
3848 0); /* No padding */
3850 gtk_box_pack_end(GTK_BOX(tab
->vbox
),
3852 FALSE
, /* Do not expand */
3853 FALSE
, /* Fill has no effect here (expand false) */
3854 0); /* No padding */
3856 g_object_set_data(G_OBJECT(tab
->viewer_container
), "focused_viewer", NULL
);
3862 // Display a label with a X
3863 GtkWidget *w_hbox = gtk_hbox_new(FALSE, 4);
3864 GtkWidget *w_label = gtk_label_new (label);
3865 GtkWidget *pixmap = create_pixmap(GTK_WIDGET(notebook), "close.png");
3866 GtkWidget *w_button = gtk_button_new ();
3867 gtk_container_add(GTK_CONTAINER(w_button), pixmap);
3868 //GtkWidget *w_button = gtk_button_new_with_label("x");
3870 gtk_button_set_relief(GTK_BUTTON(w_button), GTK_RELIEF_NONE);
3872 gtk_box_pack_start(GTK_BOX(w_hbox), w_label, TRUE, TRUE, 0);
3873 gtk_box_pack_end(GTK_BOX(w_hbox), w_button, FALSE,
3876 g_signal_connect_swapped (w_button, "clicked",
3877 G_CALLBACK (on_close_tab_X_clicked),
3880 gtk_widget_set_state(w_button, GTK_STATE_ACTIVE);
3882 gtk_widget_show (w_label);
3883 gtk_widget_show (pixmap);
3884 gtk_widget_show (w_button);
3885 gtk_widget_show (w_hbox);
3887 tab->label = w_hbox;
3891 tab
->label
= gtk_label_new (label
);
3893 gtk_widget_show(tab
->label
);
3894 gtk_widget_show(tab
->scrollbar
);
3895 gtk_widget_show(tab
->viewer_container
);
3896 gtk_widget_show(tab
->vbox
);
3897 //gtk_widget_show(tab->multivpaned);
3900 /* Start with empty events requests list */
3901 tab
->events_requests
= NULL
;
3902 tab
->events_request_pending
= FALSE
;
3904 g_object_set_data_full(
3905 G_OBJECT(tab
->vbox
),
3908 (GDestroyNotify
)tab_destructor
);
3910 g_signal_connect(G_OBJECT(tab
->scrollbar
), "value-changed",
3911 G_CALLBACK(scroll_value_changed_cb
), tab
);
3912 //g_signal_connect(G_OBJECT(tab->scrollbar), "changed",
3913 // G_CALLBACK(scroll_value_changed_cb), tab);
3916 //insert tab into notebook
3917 gtk_notebook_append_page(notebook
,
3920 list
= gtk_container_get_children(GTK_CONTAINER(notebook
));
3921 gtk_notebook_set_current_page(notebook
,g_list_length(list
)-1);
3922 // always show : not if(g_list_length(list)>1)
3923 gtk_notebook_set_show_tabs(notebook
, TRUE
);
3929 * execute_events_requests
3931 * Idle function that executes the pending requests for a tab.
3933 * @return return value : TRUE : keep the idle function, FALSE : remove it.
3935 gboolean
execute_events_requests(Tab
*tab
)
3937 return ( lttvwindow_process_pending_requests(tab
) );