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
);
152 static gboolean
viewer_grab_focus(GtkWidget
*widget
, GdkEventButton
*event
,
155 GtkWidget
*viewer
= GTK_WIDGET(data
);
156 GtkWidget
*viewer_container
= gtk_widget_get_parent(viewer
);
158 g_debug("FOCUS GRABBED");
159 g_object_set_data(G_OBJECT(viewer_container
), "focused_viewer", viewer
);
163 static void connect_focus_recursive(GtkWidget
*widget
,
166 if(GTK_IS_CONTAINER(widget
)) {
167 gtk_container_forall(GTK_CONTAINER(widget
),
168 (GtkCallback
)connect_focus_recursive
,
171 gtk_widget_add_events(widget
, GDK_BUTTON_PRESS_MASK
);
172 g_signal_connect (G_OBJECT(widget
),
173 "button-press-event",
174 G_CALLBACK (viewer_grab_focus
),
178 /* insert_viewer function constructs an instance of a viewer first,
179 * then inserts the widget of the instance into the container of the
184 insert_viewer_wrap(GtkWidget
*menuitem
, gpointer user_data
)
188 insert_viewer((GtkWidget
*)menuitem
, (lttvwindow_viewer_constructor
)user_data
);
189 // selected_hook(&val);
193 /* internal functions */
194 void insert_viewer(GtkWidget
* widget
, lttvwindow_viewer_constructor constructor
)
196 GtkWidget
* viewer_container
;
197 MainWindow
* mw_data
= get_window_data_struct(widget
);
198 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
200 LttvTracesetSelector
* s
;
201 TimeInterval
* time_interval
;
202 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
203 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
207 tab
= create_new_tab(widget
, NULL
);
209 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
212 viewer_container
= tab
->viewer_container
;
214 s
= construct_traceset_selector(tab
->traceset_info
->traceset
);
215 viewer
= (GtkWidget
*)constructor(tab
, s
, "Traceset_Selector");
218 //gtk_multivpaned_widget_add(GTK_MULTIVPANED(multivpaned), viewer);
220 gtk_box_pack_end(GTK_BOX(viewer_container
),
226 /* We want to connect the viewer_grab_focus to EVERY
227 * child of this widget. The little trick is to get each child
228 * of each GTK_CONTAINER, even subchildren.
230 connect_focus_recursive(viewer
, viewer
);
235 * Function to set/update traceset for the viewers
236 * @param tab viewer's tab
237 * @param traceset traceset of the main window.
239 * 0 : traceset updated
240 * 1 : no traceset hooks to update; not an error.
243 int SetTraceset(Tab
* tab
, LttvTraceset
*traceset
)
245 LttvTracesetContext
*tsc
=
246 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
247 TimeInterval time_span
= tsc
->time_span
;
248 TimeWindow new_time_window
;
249 LttTime new_current_time
;
251 /* Set the tab's time window and current time if
253 if(ltt_time_compare(tab
->time_window
.start_time
, time_span
.start_time
) < 0
254 || ltt_time_compare( ltt_time_add(tab
->time_window
.start_time
,
255 tab
->time_window
.time_width
),
256 time_span
.end_time
) > 0) {
257 new_time_window
.start_time
= time_span
.start_time
;
259 new_current_time
= time_span
.start_time
;
263 if(DEFAULT_TIME_WIDTH_S
< time_span
.end_time
.tv_sec
)
264 tmp_time
.tv_sec
= DEFAULT_TIME_WIDTH_S
;
266 tmp_time
.tv_sec
= time_span
.end_time
.tv_sec
;
267 tmp_time
.tv_nsec
= 0;
268 new_time_window
.time_width
= tmp_time
;
270 time_change_manager(tab
, new_time_window
);
271 current_time_change_manager(tab
, new_current_time
);
275 GtkAdjustment
*adjustment
= gtk_range_get_adjustment(GTK_RANGE(tab
->scrollbar
));
276 LttTime upper
= ltt_time_sub(time_span
.end_time
, time_span
.start_time
);
278 g_object_set(G_OBJECT(adjustment
),
282 ltt_time_to_double(upper
)
283 * NANOSECONDS_PER_SECOND
, /* upper */
285 ltt_time_to_double(tab
->time_window
.time_width
)
286 / SCROLL_STEP_PER_PAGE
287 * NANOSECONDS_PER_SECOND
, /* step increment */
289 ltt_time_to_double(tab
->time_window
.time_width
)
290 * NANOSECONDS_PER_SECOND
, /* page increment */
292 ltt_time_to_double(tab
->time_window
.time_width
)
293 * NANOSECONDS_PER_SECOND
, /* page size */
295 gtk_adjustment_changed(adjustment
);
297 g_object_set(G_OBJECT(adjustment
),
300 ltt_time_sub(tab
->time_window
.start_time
, time_span
.start_time
))
301 * NANOSECONDS_PER_SECOND
, /* value */
303 gtk_adjustment_value_changed(adjustment
);
305 /* set the time bar. The value callbacks will change their nsec themself */
307 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry1
),
308 (double)time_span
.start_time
.tv_sec
,
309 (double)time_span
.end_time
.tv_sec
);
312 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry3
),
313 (double)time_span
.start_time
.tv_sec
,
314 (double)time_span
.end_time
.tv_sec
);
316 /* current seconds */
317 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry5
),
318 (double)time_span
.start_time
.tv_sec
,
319 (double)time_span
.end_time
.tv_sec
);
322 /* Finally, call the update hooks of the viewers */
324 LttvAttributeValue value
;
328 g_assert( lttv_iattribute_find_by_path(tab
->attributes
,
329 "hooks/updatetraceset", LTTV_POINTER
, &value
));
331 tmp
= (LttvHooks
*)*(value
.v_pointer
);
332 if(tmp
== NULL
) retval
= 1;
333 else lttv_hooks_call(tmp
,traceset
);
340 * Function to set/update filter for the viewers
341 * @param tab viewer's tab
342 * @param filter filter of the main window.
345 * 0 : filters updated
346 * 1 : no filter hooks to update; not an error.
349 int SetFilter(Tab
* tab
, gpointer filter
)
352 LttvAttributeValue value
;
354 g_assert(lttv_iattribute_find_by_path(tab
->attributes
,
355 "hooks/updatefilter", LTTV_POINTER
, &value
));
357 tmp
= (LttvHooks
*)*(value
.v_pointer
);
359 if(tmp
== NULL
) return 1;
360 lttv_hooks_call(tmp
,filter
);
368 * Function to redraw each viewer belonging to the current tab
369 * @param tab viewer's tab
372 void update_traceset(Tab
*tab
)
374 LttvAttributeValue value
;
376 g_assert(lttv_iattribute_find_by_path(tab
->attributes
,
377 "hooks/updatetraceset", LTTV_POINTER
, &value
));
378 tmp
= (LttvHooks
*)*(value
.v_pointer
);
379 if(tmp
== NULL
) return;
380 lttv_hooks_call(tmp
, NULL
);
384 /* get_label function is used to get user input, it displays an input
385 * box, which allows user to input a string
388 void get_label_string (GtkWidget
* text
, gchar
* label
)
390 GtkEntry
* entry
= (GtkEntry
*)text
;
391 if(strlen(gtk_entry_get_text(entry
))!=0)
392 strcpy(label
,gtk_entry_get_text(entry
));
395 gboolean
get_label(MainWindow
* mw
, gchar
* str
, gchar
* dialogue_title
, gchar
* label_str
)
397 GtkWidget
* dialogue
;
402 dialogue
= gtk_dialog_new_with_buttons(dialogue_title
,NULL
,
404 GTK_STOCK_OK
,GTK_RESPONSE_ACCEPT
,
405 GTK_STOCK_CANCEL
,GTK_RESPONSE_REJECT
,
408 label
= gtk_label_new(label_str
);
409 gtk_widget_show(label
);
411 text
= gtk_entry_new();
412 gtk_widget_show(text
);
414 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialogue
)->vbox
), label
,TRUE
, TRUE
,0);
415 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialogue
)->vbox
), text
,FALSE
, FALSE
,0);
417 id
= gtk_dialog_run(GTK_DIALOG(dialogue
));
419 case GTK_RESPONSE_ACCEPT
:
420 get_label_string(text
,str
);
421 gtk_widget_destroy(dialogue
);
423 case GTK_RESPONSE_REJECT
:
425 gtk_widget_destroy(dialogue
);
432 /* get_window_data_struct function is actually a lookup function,
433 * given a widget which is in the tree of the main window, it will
434 * return the MainWindow data structure associated with main window
437 MainWindow
* get_window_data_struct(GtkWidget
* widget
)
440 MainWindow
* mw_data
;
442 mw
= lookup_widget(widget
, "MWindow");
444 g_printf("Main window does not exist\n");
448 mw_data
= (MainWindow
*) g_object_get_data(G_OBJECT(mw
),"main_window_data");
450 g_printf("Main window data does not exist\n");
457 /* create_new_window function, just constructs a new main window
460 void create_new_window(GtkWidget
* widget
, gpointer user_data
, gboolean clone
)
462 MainWindow
* parent
= get_window_data_struct(widget
);
465 g_printf("Clone : use the same traceset\n");
466 construct_main_window(parent
);
468 g_printf("Empty : traceset is set to NULL\n");
469 construct_main_window(NULL
);
473 /* Get the currently focused viewer.
474 * If no viewer is focused, use the first one.
476 * If no viewer available, return NULL.
478 GtkWidget
*viewer_container_focus(GtkWidget
*container
)
482 widget
= (GtkWidget
*)g_object_get_data(G_OBJECT(container
),
486 g_debug("no widget focused");
487 GList
*children
= gtk_container_get_children(GTK_CONTAINER(container
));
490 widget
= GTK_WIDGET(children
->data
);
498 gint
viewer_container_position(GtkWidget
*container
, GtkWidget
*child
)
501 if(child
== NULL
) return -1;
504 GValue value
= { 0, };
505 g_value_init(&value
, G_TYPE_INT
);
506 gtk_container_child_get_property(GTK_CONTAINER(container
),
510 pos
= g_value_get_int(&value
);
516 /* move_*_viewer functions move the selected view up/down in
520 void move_down_viewer(GtkWidget
* widget
, gpointer user_data
)
522 MainWindow
* mw
= get_window_data_struct(widget
);
523 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
525 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
526 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
532 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
535 //gtk_multivpaned_widget_move_up(GTK_MULTIVPANED(tab->multivpaned));
537 /* change the position in the vbox */
538 GtkWidget
*focus_widget
;
540 focus_widget
= viewer_container_focus(tab
->viewer_container
);
541 position
= viewer_container_position(tab
->viewer_container
, focus_widget
);
544 /* can move up one position */
545 gtk_box_reorder_child(GTK_BOX(tab
->viewer_container
),
552 void move_up_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_move_down(GTK_MULTIVPANED(tab->multivpaned));
568 /* change the position in the vbox */
569 GtkWidget
*focus_widget
;
571 focus_widget
= viewer_container_focus(tab
->viewer_container
);
572 position
= viewer_container_position(tab
->viewer_container
, focus_widget
);
576 g_list_length(gtk_container_get_children(
577 GTK_CONTAINER(tab
->viewer_container
)))-1
579 /* can move down one position */
580 gtk_box_reorder_child(GTK_BOX(tab
->viewer_container
),
588 /* delete_viewer deletes the selected viewer in the current tab
591 void delete_viewer(GtkWidget
* widget
, gpointer user_data
)
593 MainWindow
* mw
= get_window_data_struct(widget
);
594 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
596 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
597 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
603 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
606 //gtk_multivpaned_widget_delete(GTK_MULTIVPANED(tab->multivpaned));
608 GtkWidget
*focus_widget
= viewer_container_focus(tab
->viewer_container
);
610 if(focus_widget
!= NULL
)
611 gtk_widget_destroy(focus_widget
);
613 g_object_set_data(G_OBJECT(tab
->viewer_container
), "focused_viewer", NULL
);
617 /* open_traceset will open a traceset saved in a file
618 * Right now, it is not finished yet, (not working)
622 void open_traceset(GtkWidget
* widget
, gpointer user_data
)
626 LttvTraceset
* traceset
;
627 MainWindow
* mw_data
= get_window_data_struct(widget
);
628 GtkFileSelection
* file_selector
=
629 (GtkFileSelection
*)gtk_file_selection_new("Select a traceset");
631 gtk_file_selection_hide_fileop_buttons(file_selector
);
633 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
635 case GTK_RESPONSE_ACCEPT
:
636 case GTK_RESPONSE_OK
:
637 dir
= gtk_file_selection_get_selections (file_selector
);
638 traceset
= lttv_traceset_load(dir
[0]);
639 g_printf("Open a trace set %s\n", dir
[0]);
642 case GTK_RESPONSE_REJECT
:
643 case GTK_RESPONSE_CANCEL
:
645 gtk_widget_destroy((GtkWidget
*)file_selector
);
651 static void events_request_free(EventsRequest
*events_request
)
653 if(events_request
== NULL
) return;
655 if(events_request
->start_position
!= NULL
)
656 lttv_traceset_context_position_destroy(events_request
->start_position
);
657 if(events_request
->end_position
!= NULL
)
658 lttv_traceset_context_position_destroy(events_request
->end_position
);
659 if(events_request
->before_chunk_traceset
!= NULL
)
660 lttv_hooks_destroy(events_request
->before_chunk_traceset
);
661 if(events_request
->before_chunk_trace
!= NULL
)
662 lttv_hooks_destroy(events_request
->before_chunk_trace
);
663 if(events_request
->before_chunk_tracefile
!= NULL
)
664 lttv_hooks_destroy(events_request
->before_chunk_tracefile
);
665 if(events_request
->event
!= NULL
)
666 lttv_hooks_destroy(events_request
->event
);
667 if(events_request
->event_by_id
!= NULL
)
668 lttv_hooks_by_id_destroy(events_request
->event_by_id
);
669 if(events_request
->after_chunk_tracefile
!= NULL
)
670 lttv_hooks_destroy(events_request
->after_chunk_tracefile
);
671 if(events_request
->after_chunk_trace
!= NULL
)
672 lttv_hooks_destroy(events_request
->after_chunk_trace
);
673 if(events_request
->after_chunk_traceset
!= NULL
)
674 lttv_hooks_destroy(events_request
->after_chunk_traceset
);
675 if(events_request
->before_request
!= NULL
)
676 lttv_hooks_destroy(events_request
->before_request
);
677 if(events_request
->after_request
!= NULL
)
678 lttv_hooks_destroy(events_request
->after_request
);
680 g_free(events_request
);
685 /* lttvwindow_process_pending_requests
687 * This internal function gets called by g_idle, taking care of the pending
688 * requests. It is responsible for concatenation of time intervals and position
689 * requests. It does it with the following algorithm organizing process traceset
690 * calls. Here is the detailed description of the way it works :
692 * - Events Requests Servicing Algorithm
694 * Data structures necessary :
696 * List of requests added to context : list_in
697 * List of requests not added to context : list_out
702 * list_out : many events requests
704 * FIXME : insert rest of algorithm here
708 #define list_out tab->events_requests
710 gboolean
lttvwindow_process_pending_requests(Tab
*tab
)
712 unsigned max_nb_events
;
716 LttvTracesetContext
*tsc
;
717 LttvTracefileContext
*tfc
;
718 GSList
*list_in
= NULL
;
722 LttvTracesetContextPosition
*end_position
;
725 g_critical("Foreground processing : tab does not exist. Processing removed.");
729 /* There is no events requests pending : we should never have been called! */
730 g_assert(g_slist_length(list_out
) != 0);
732 tsc
= LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
734 //set the cursor to be X shape, indicating that the computer is busy in doing its job
736 new = gdk_cursor_new(GDK_X_CURSOR
);
737 widget
= lookup_widget(tab
->mw
->mwindow
, "MToolbar1");
738 win
= gtk_widget_get_parent_window(widget
);
739 gdk_window_set_cursor(win
, new);
740 gdk_cursor_unref(new);
741 gdk_window_stick(win
);
742 gdk_window_unstick(win
);
745 g_debug("SIZE events req len : %d", g_slist_length(list_out
));
747 /* Preliminary check for no trace in traceset */
748 /* Unregister the routine if empty, empty list_out too */
749 if(lttv_traceset_number(tsc
->ts
) == 0) {
751 /* - For each req in list_out */
752 GSList
*iter
= list_out
;
754 while(iter
!= NULL
) {
756 gboolean remove
= FALSE
;
757 gboolean free_data
= FALSE
;
758 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
760 /* - Call end request for req */
761 if(events_request
->servicing
== TRUE
)
762 lttv_hooks_call(events_request
->after_request
, (gpointer
)tsc
);
764 /* - remove req from list_out */
765 /* Destroy the request */
772 GSList
*remove_iter
= iter
;
774 iter
= g_slist_next(iter
);
775 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
776 list_out
= g_slist_remove_link(list_out
, remove_iter
);
777 } else { // not remove
778 iter
= g_slist_next(iter
);
783 /* 0.1 Lock Traces */
788 iter_trace
<lttv_traceset_number(tsc
->ts
);
790 LttvTrace
*trace_v
= lttv_traceset_get(tsc
->ts
, iter_trace
);
792 if(lttvwindowtraces_lock(trace_v
) != 0) {
793 g_critical("Foreground processing : Unable to get trace lock");
794 return TRUE
; /* Cannot get lock, try later */
799 /* 0.2 Seek tracefiles positions to context position */
800 lttv_process_traceset_synchronize_tracefiles(tsc
);
803 /* Events processing algorithm implementation */
804 /* Warning : the gtk_events_pending takes a LOT of cpu time. So what we do
805 * instead is to leave the control to GTK and take it back.
807 /* A. Servicing loop */
808 //while( (g_slist_length(list_in) != 0 || g_slist_length(list_out) != 0)) {
809 if((g_slist_length(list_in
) != 0 || g_slist_length(list_out
) != 0)) {
811 /* 1. If list_in is empty (need a seek) */
812 if( g_slist_length(list_in
) == 0 ) {
814 /* list in is empty, need a seek */
816 /* 1.1 Add requests to list_in */
817 GSList
*ltime
= NULL
;
821 /* 1.1.1 Find all time requests with the lowest start time in list_out
824 if(g_slist_length(list_out
) > 0)
825 ltime
= g_slist_append(ltime
, g_slist_nth_data(list_out
, 0));
826 for(iter
=g_slist_nth(list_out
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
827 /* Find all time requests with the lowest start time in list_out */
828 guint index_ltime
= g_array_index(ltime
, guint
, 0);
829 EventsRequest
*event_request_ltime
= (EventsRequest
*)g_slist_nth_data(ltime
, 0);
830 EventsRequest
*event_request_list_out
= (EventsRequest
*)iter
->data
;
833 comp
= ltt_time_compare(event_request_ltime
->start_time
,
834 event_request_list_out
->start_time
);
836 ltime
= g_slist_append(ltime
, event_request_list_out
);
838 /* Remove all elements from ltime, and add current */
840 ltime
= g_slist_delete_link(ltime
, g_slist_nth(ltime
, 0));
841 ltime
= g_slist_append(ltime
, event_request_list_out
);
845 /* 1.1.2 Find all position requests with the lowest position in list_out
848 if(g_slist_length(list_out
) > 0)
849 lpos
= g_slist_append(lpos
, g_slist_nth_data(list_out
, 0));
850 for(iter
=g_slist_nth(list_out
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
851 /* Find all position requests with the lowest position in list_out */
852 EventsRequest
*event_request_lpos
= (EventsRequest
*)g_slist_nth_data(lpos
, 0);
853 EventsRequest
*event_request_list_out
= (EventsRequest
*)iter
->data
;
856 if(event_request_lpos
->start_position
!= NULL
857 && event_request_list_out
->start_position
!= NULL
)
859 comp
= lttv_traceset_context_pos_pos_compare
860 (event_request_lpos
->start_position
,
861 event_request_list_out
->start_position
);
866 lpos
= g_slist_append(lpos
, event_request_list_out
);
868 /* Remove all elements from lpos, and add current */
870 lpos
= g_slist_delete_link(lpos
, g_slist_nth(lpos
, 0));
871 lpos
= g_slist_append(lpos
, event_request_list_out
);
876 EventsRequest
*event_request_lpos
= (EventsRequest
*)g_slist_nth_data(lpos
, 0);
877 EventsRequest
*event_request_ltime
= (EventsRequest
*)g_slist_nth_data(ltime
, 0);
878 LttTime lpos_start_time
;
880 if(event_request_lpos
!= NULL
881 && event_request_lpos
->start_position
!= NULL
) {
882 lpos_start_time
= lttv_traceset_context_position_get_time(
883 event_request_lpos
->start_position
);
886 /* 1.1.3 If lpos.start time < ltime */
887 if(event_request_lpos
!= NULL
888 && event_request_lpos
->start_position
!= NULL
889 && ltt_time_compare(lpos_start_time
,
890 event_request_ltime
->start_time
)<0) {
891 /* Add lpos to list_in, remove them from list_out */
892 for(iter
=lpos
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
894 EventsRequest
*event_request_lpos
=
895 (EventsRequest
*)iter
->data
;
897 list_in
= g_slist_append(list_in
, event_request_lpos
);
898 /* Remove from list_out */
899 list_out
= g_slist_remove(list_out
, event_request_lpos
);
902 /* 1.1.4 (lpos.start time >= ltime) */
903 /* Add ltime to list_in, remove them from list_out */
905 for(iter
=ltime
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
907 EventsRequest
*event_request_ltime
=
908 (EventsRequest
*)iter
->data
;
910 list_in
= g_slist_append(list_in
, event_request_ltime
);
911 /* Remove from list_out */
912 list_out
= g_slist_remove(list_out
, event_request_ltime
);
922 tfc
= lttv_traceset_context_get_current_tfc(tsc
);
923 g_assert(g_slist_length(list_in
)>0);
924 EventsRequest
*events_request
= g_slist_nth_data(list_in
, 0);
927 /* 1.2.1 If first request in list_in is a time request */
928 if(events_request
->start_position
== NULL
) {
929 /* - If first req in list_in start time != current time */
930 if(tfc
== NULL
|| ltt_time_compare(events_request
->start_time
,
931 tfc
->timestamp
) != 0)
932 /* - Seek to that time */
933 g_debug("SEEK TIME : %lu, %lu", events_request
->start_time
.tv_sec
,
934 events_request
->start_time
.tv_nsec
);
935 //lttv_process_traceset_seek_time(tsc, events_request->start_time);
936 lttv_state_traceset_seek_time_closest(LTTV_TRACESET_STATE(tsc
),
937 events_request
->start_time
);
939 /* Process the traceset with only state hooks */
941 lttv_process_traceset_middle(tsc
,
942 events_request
->start_time
,
948 /* Else, the first request in list_in is a position request */
949 /* If first req in list_in pos != current pos */
950 g_assert(events_request
->start_position
!= NULL
);
951 g_debug("SEEK POS time : %lu, %lu",
952 lttv_traceset_context_position_get_time(
953 events_request
->start_position
).tv_sec
,
954 lttv_traceset_context_position_get_time(
955 events_request
->start_position
).tv_nsec
);
957 g_debug("SEEK POS context time : %lu, %lu",
958 lttv_traceset_context_get_current_tfc(tsc
)->timestamp
.tv_sec
,
959 lttv_traceset_context_get_current_tfc(tsc
)->timestamp
.tv_nsec
);
960 g_assert(events_request
->start_position
!= NULL
);
961 if(lttv_traceset_context_ctx_pos_compare(tsc
,
962 events_request
->start_position
) != 0) {
963 /* 1.2.2.1 Seek to that position */
964 g_debug("SEEK POSITION");
965 //lttv_process_traceset_seek_position(tsc, events_request->start_position);
966 pos_time
= lttv_traceset_context_position_get_time(
967 events_request
->start_position
);
969 lttv_state_traceset_seek_time_closest(LTTV_TRACESET_STATE(tsc
),
972 /* Process the traceset with only state hooks */
974 lttv_process_traceset_middle(tsc
,
977 events_request
->start_position
);
978 g_assert(lttv_traceset_context_ctx_pos_compare(tsc
,
979 events_request
->start_position
) == 0);
986 /* 1.3 Add hooks and call before request for all list_in members */
990 for(iter
=list_in
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
991 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
992 /* 1.3.1 If !servicing */
993 if(events_request
->servicing
== FALSE
) {
994 /* - begin request hooks called
997 lttv_hooks_call(events_request
->before_request
, (gpointer
)tsc
);
998 events_request
->servicing
= TRUE
;
1000 /* 1.3.2 call before chunk
1001 * 1.3.3 events hooks added
1003 lttv_process_traceset_begin(tsc
, events_request
->before_chunk_traceset
,
1004 events_request
->before_chunk_trace
,
1005 events_request
->before_chunk_tracefile
,
1006 events_request
->event
,
1007 events_request
->event_by_id
);
1011 /* 2. Else, list_in is not empty, we continue a read */
1014 /* 2.0 For each req of list_in */
1015 GSList
*iter
= list_in
;
1017 while(iter
!= NULL
) {
1019 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1021 /* - Call before chunk
1022 * - events hooks added
1024 lttv_process_traceset_begin(tsc
, events_request
->before_chunk_traceset
,
1025 events_request
->before_chunk_trace
,
1026 events_request
->before_chunk_tracefile
,
1027 events_request
->event
,
1028 events_request
->event_by_id
);
1030 iter
= g_slist_next(iter
);
1035 tfc
= lttv_traceset_context_get_current_tfc(tsc
);
1037 /* 2.1 For each req of list_out */
1038 GSList
*iter
= list_out
;
1040 while(iter
!= NULL
) {
1042 gboolean remove
= FALSE
;
1043 gboolean free_data
= FALSE
;
1044 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1046 /* if req.start time == current context time
1047 * or req.start position == current position*/
1048 if( ltt_time_compare(events_request
->start_time
,
1049 tfc
->timestamp
) == 0
1051 (events_request
->start_position
!= NULL
1053 lttv_traceset_context_ctx_pos_compare(tsc
,
1054 events_request
->start_position
) == 0)
1056 /* - Add to list_in, remove from list_out */
1057 list_in
= g_slist_append(list_in
, events_request
);
1061 /* - If !servicing */
1062 if(events_request
->servicing
== FALSE
) {
1063 /* - begin request hooks called
1064 * - servicing = TRUE
1066 lttv_hooks_call(events_request
->before_request
, (gpointer
)tsc
);
1067 events_request
->servicing
= TRUE
;
1069 /* call before chunk
1070 * events hooks added
1072 lttv_process_traceset_begin(tsc
, events_request
->before_chunk_traceset
,
1073 events_request
->before_chunk_trace
,
1074 events_request
->before_chunk_tracefile
,
1075 events_request
->event
,
1076 events_request
->event_by_id
);
1082 GSList
*remove_iter
= iter
;
1084 iter
= g_slist_next(iter
);
1085 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
1086 list_out
= g_slist_remove_link(list_out
, remove_iter
);
1087 } else { // not remove
1088 iter
= g_slist_next(iter
);
1094 /* 3. Find end criterions */
1099 /* 3.1.1 Find lowest end time in list_in */
1100 g_assert(g_slist_length(list_in
)>0);
1101 end_time
= ((EventsRequest
*)g_slist_nth_data(list_in
,0))->end_time
;
1103 for(iter
=g_slist_nth(list_in
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
1104 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1106 if(ltt_time_compare(events_request
->end_time
,
1108 end_time
= events_request
->end_time
;
1111 /* 3.1.2 Find lowest start time in list_out */
1112 for(iter
=list_out
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
1113 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1115 if(ltt_time_compare(events_request
->start_time
,
1117 end_time
= events_request
->start_time
;
1122 /* 3.2 Number of events */
1124 /* 3.2.1 Find lowest number of events in list_in */
1127 end_nb_events
= ((EventsRequest
*)g_slist_nth_data(list_in
,0))->num_events
;
1129 for(iter
=g_slist_nth(list_in
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
1130 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1132 if(events_request
->num_events
< end_nb_events
)
1133 end_nb_events
= events_request
->num_events
;
1136 /* 3.2.2 Use min(CHUNK_NUM_EVENTS, min num events in list_in) as
1139 end_nb_events
= MIN(CHUNK_NUM_EVENTS
, end_nb_events
);
1143 /* 3.3 End position */
1145 /* 3.3.1 Find lowest end position in list_in */
1148 end_position
=((EventsRequest
*)g_slist_nth_data(list_in
,0))->end_position
;
1150 for(iter
=g_slist_nth(list_in
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
1151 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1153 if(events_request
->end_position
!= NULL
&& end_position
!= NULL
&&
1154 lttv_traceset_context_pos_pos_compare(events_request
->end_position
,
1156 end_position
= events_request
->end_position
;
1161 /* 3.3.2 Find lowest start position in list_out */
1164 for(iter
=list_out
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
1165 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1167 if(events_request
->end_position
!= NULL
&& end_position
!= NULL
&&
1168 lttv_traceset_context_pos_pos_compare(events_request
->end_position
,
1170 end_position
= events_request
->end_position
;
1175 /* 4. Call process traceset middle */
1176 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
);
1177 count
= lttv_process_traceset_middle(tsc
, end_time
, end_nb_events
, end_position
);
1179 tfc
= lttv_traceset_context_get_current_tfc(tsc
);
1181 g_debug("Context time after middle : %lu, %lu", tfc
->timestamp
.tv_sec
,
1182 tfc
->timestamp
.tv_nsec
);
1184 g_debug("End of trace reached after middle.");
1188 /* 5. After process traceset middle */
1189 tfc
= lttv_traceset_context_get_current_tfc(tsc
);
1191 /* - if current context time > traceset.end time */
1192 if(tfc
== NULL
|| ltt_time_compare(tfc
->timestamp
,
1193 tsc
->time_span
.end_time
) > 0) {
1194 /* - 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
);
1211 /* - Call end request for req */
1212 lttv_hooks_call(events_request
->after_request
, (gpointer
)tsc
);
1214 /* - remove req from list_in */
1215 /* Destroy the request */
1222 GSList
*remove_iter
= iter
;
1224 iter
= g_slist_next(iter
);
1225 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
1226 list_in
= g_slist_remove_link(list_in
, remove_iter
);
1227 } else { // not remove
1228 iter
= g_slist_next(iter
);
1233 /* 5.1 For each req in list_in */
1234 GSList
*iter
= list_in
;
1236 while(iter
!= NULL
) {
1238 gboolean remove
= FALSE
;
1239 gboolean free_data
= FALSE
;
1240 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1242 /* - Remove events hooks for req
1243 * - Call end chunk for req
1245 lttv_process_traceset_end(tsc
, events_request
->after_chunk_traceset
,
1246 events_request
->after_chunk_trace
,
1247 events_request
->after_chunk_tracefile
,
1248 events_request
->event
,
1249 events_request
->event_by_id
);
1251 /* - req.num -= count */
1252 g_assert(events_request
->num_events
>= count
);
1253 events_request
->num_events
-= count
;
1255 g_assert(tfc
!= NULL
);
1256 /* - if req.num == 0
1258 * current context time >= req.end time
1260 * req.end pos == current pos
1262 * req.stop_flag == TRUE
1264 if( events_request
->num_events
== 0
1266 events_request
->stop_flag
== TRUE
1268 ltt_time_compare(tfc
->timestamp
,
1269 events_request
->end_time
) >= 0
1271 (events_request
->end_position
!= NULL
1273 lttv_traceset_context_ctx_pos_compare(tsc
,
1274 events_request
->end_position
) == 0)
1277 g_assert(events_request
->servicing
== TRUE
);
1278 /* - Call end request for req
1279 * - remove req from list_in */
1280 lttv_hooks_call(events_request
->after_request
, (gpointer
)tsc
);
1281 /* - remove req from list_in */
1282 /* Destroy the request */
1290 GSList
*remove_iter
= iter
;
1292 iter
= g_slist_next(iter
);
1293 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
1294 list_in
= g_slist_remove_link(list_in
, remove_iter
);
1295 } else { // not remove
1296 iter
= g_slist_next(iter
);
1302 /* End of removed servicing loop : leave control to GTK instead. */
1303 // if(gtk_events_pending()) break;
1306 /* B. When interrupted between chunks */
1309 GSList
*iter
= list_in
;
1311 /* 1. for each request in list_in */
1312 while(iter
!= NULL
) {
1314 gboolean remove
= FALSE
;
1315 gboolean free_data
= FALSE
;
1316 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1318 /* 1.1. Use current postition as start position */
1319 if(events_request
->start_position
!= NULL
)
1320 lttv_traceset_context_position_destroy(events_request
->start_position
);
1321 events_request
->start_position
= lttv_traceset_context_position_new();
1322 lttv_traceset_context_position_save(tsc
, events_request
->start_position
);
1324 /* 1.2. Remove start time */
1325 events_request
->start_time
= ltt_time_infinite
;
1327 /* 1.3. Move from list_in to list_out */
1330 list_out
= g_slist_append(list_out
, events_request
);
1335 GSList
*remove_iter
= iter
;
1337 iter
= g_slist_next(iter
);
1338 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
1339 list_in
= g_slist_remove_link(list_in
, remove_iter
);
1340 } else { // not remove
1341 iter
= g_slist_next(iter
);
1348 /* C Unlock Traces */
1350 //lttv_process_traceset_get_sync_data(tsc);
1355 iter_trace
<lttv_traceset_number(tsc
->ts
);
1357 LttvTrace
*trace_v
= lttv_traceset_get(tsc
->ts
, iter_trace
);
1359 lttvwindowtraces_unlock(trace_v
);
1364 //set the cursor back to normal
1365 gdk_window_set_cursor(win
, NULL
);
1368 g_assert(g_slist_length(list_in
) == 0);
1370 if( g_slist_length(list_out
) == 0 ) {
1371 /* Put tab's request pending flag back to normal */
1372 tab
->events_request_pending
= FALSE
;
1373 g_debug("remove the idle fct");
1374 return FALSE
; /* Remove the idle function */
1376 g_debug("leave the idle fct");
1377 return TRUE
; /* Leave the idle function */
1379 /* We do not use simili-round-robin, it may require to read 1 meg buffers
1380 * again and again if many tracesets use the same tracefiles. */
1381 /* Hack for round-robin idle functions */
1382 /* It will put the idle function at the end of the pool */
1383 /*g_idle_add_full((G_PRIORITY_HIGH_IDLE + 21),
1384 (GSourceFunc)execute_events_requests,
1394 /* add_trace_into_traceset_selector, each instance of a viewer has an associated
1395 * selector (filter), when a trace is added into traceset, the selector should
1396 * reflect the change. The function is used to update the selector
1399 void add_trace_into_traceset_selector(GtkWidget
* paned
, LttTrace
* t
)
1401 int j
, k
, m
, nb_tracefile
, nb_control
, nb_per_cpu
, nb_facility
, nb_event
;
1402 LttvTracesetSelector
* s
;
1403 LttvTraceSelector
* trace
;
1404 LttvTracefileSelector
* tracefile
;
1405 LttvEventtypeSelector
* eventtype
;
1411 w
= gtk_multivpaned_get_first_widget(GTK_MULTIVPANED(paned
));
1413 s
= g_object_get_data(G_OBJECT(w
), "Traceset_Selector");
1416 trace
= lttv_trace_selector_new(t
);
1417 lttv_traceset_selector_trace_add(s
, trace
);
1419 nb_facility
= ltt_trace_facility_number(t
);
1420 for(k
=0;k
<nb_facility
;k
++){
1421 fac
= ltt_trace_facility_get(t
,k
);
1422 nb_event
= (int) ltt_facility_eventtype_number(fac
);
1423 for(m
=0;m
<nb_event
;m
++){
1424 et
= ltt_facility_eventtype_get(fac
,m
);
1425 eventtype
= lttv_eventtype_selector_new(et
);
1426 lttv_trace_selector_eventtype_add(trace
, eventtype
);
1430 nb_control
= ltt_trace_control_tracefile_number(t
);
1431 nb_per_cpu
= ltt_trace_per_cpu_tracefile_number(t
);
1432 nb_tracefile
= nb_control
+ nb_per_cpu
;
1434 for(j
= 0 ; j
< nb_tracefile
; j
++) {
1436 tf
= ltt_trace_control_tracefile_get(t
, j
);
1438 tf
= ltt_trace_per_cpu_tracefile_get(t
, j
- nb_control
);
1439 tracefile
= lttv_tracefile_selector_new(tf
);
1440 lttv_trace_selector_tracefile_add(trace
, tracefile
);
1441 lttv_eventtype_selector_copy(trace
, tracefile
);
1443 }else g_warning("Module does not support filtering\n");
1445 w
= gtk_multivpaned_get_next_widget(GTK_MULTIVPANED(paned
));
1450 static void lttvwindow_add_trace(Tab
*tab
, LttvTrace
*trace_v
)
1452 LttvTraceset
*traceset
= tab
->traceset_info
->traceset
;
1454 guint num_traces
= lttv_traceset_number(traceset
);
1456 //Verify if trace is already present.
1457 for(i
=0; i
<num_traces
; i
++)
1459 LttvTrace
* trace
= lttv_traceset_get(traceset
, i
);
1460 if(trace
== trace_v
)
1464 //Keep a reference to the traces so they are not freed.
1465 for(i
=0; i
<lttv_traceset_number(traceset
); i
++)
1467 LttvTrace
* trace
= lttv_traceset_get(traceset
, i
);
1468 lttv_trace_ref(trace
);
1471 //remove state update hooks
1472 lttv_state_remove_event_hooks(
1473 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1475 lttv_context_fini(LTTV_TRACESET_CONTEXT(
1476 tab
->traceset_info
->traceset_context
));
1477 g_object_unref(tab
->traceset_info
->traceset_context
);
1479 lttv_traceset_add(traceset
, trace_v
);
1480 lttv_trace_ref(trace_v
); /* local ref */
1482 /* Create new context */
1483 tab
->traceset_info
->traceset_context
=
1484 g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
1486 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->
1491 //add state update hooks
1492 lttv_state_add_event_hooks(
1493 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1494 //Remove local reference to the traces.
1495 for(i
=0; i
<lttv_traceset_number(traceset
); i
++)
1497 LttvTrace
* trace
= lttv_traceset_get(traceset
, i
);
1498 lttv_trace_unref(trace
);
1502 //add_trace_into_traceset_selector(GTK_MULTIVPANED(tab->multivpaned), lttv_trace(trace_v));
1505 /* add_trace adds a trace into the current traceset. It first displays a
1506 * directory selection dialogue to let user choose a trace, then recreates
1507 * tracset_context, and redraws all the viewer of the current tab
1510 void add_trace(GtkWidget
* widget
, gpointer user_data
)
1513 LttvTrace
* trace_v
;
1514 LttvTraceset
* traceset
;
1516 char abs_path
[PATH_MAX
];
1519 MainWindow
* mw_data
= get_window_data_struct(widget
);
1520 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
1522 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
1523 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
1527 tab
= create_new_tab(widget
, NULL
);
1529 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
1532 GtkDirSelection
* file_selector
= (GtkDirSelection
*)gtk_dir_selection_new("Select a trace");
1533 gtk_dir_selection_hide_fileop_buttons(file_selector
);
1535 if(remember_trace_dir
[0] != '\0')
1536 gtk_dir_selection_set_filename(file_selector
, remember_trace_dir
);
1538 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
1540 case GTK_RESPONSE_ACCEPT
:
1541 case GTK_RESPONSE_OK
:
1542 dir
= gtk_dir_selection_get_dir (file_selector
);
1543 strncpy(remember_trace_dir
, dir
, PATH_MAX
);
1544 if(!dir
|| strlen(dir
) == 0){
1545 gtk_widget_destroy((GtkWidget
*)file_selector
);
1548 get_absolute_pathname(dir
, abs_path
);
1549 trace_v
= lttvwindowtraces_get_trace_by_name(abs_path
);
1550 if(trace_v
== NULL
) {
1551 trace
= ltt_trace_open(abs_path
);
1553 g_warning("cannot open trace %s", abs_path
);
1555 trace_v
= lttv_trace_new(trace
);
1556 lttvwindowtraces_add_trace(trace_v
);
1557 lttvwindow_add_trace(tab
, trace_v
);
1560 lttvwindow_add_trace(tab
, trace_v
);
1563 gtk_widget_destroy((GtkWidget
*)file_selector
);
1565 //update current tab
1566 //update_traceset(mw_data);
1568 /* Call the updatetraceset hooks */
1570 traceset
= tab
->traceset_info
->traceset
;
1571 SetTraceset(tab
, traceset
);
1572 // in expose now call_pending_read_hooks(mw_data);
1574 //lttvwindow_report_current_time(mw_data,&(tab->current_time));
1576 case GTK_RESPONSE_REJECT
:
1577 case GTK_RESPONSE_CANCEL
:
1579 gtk_widget_destroy((GtkWidget
*)file_selector
);
1585 /* remove_trace_into_traceset_selector, each instance of a viewer has an associated
1586 * selector (filter), when a trace is remove from traceset, the selector should
1587 * reflect the change. The function is used to update the selector
1590 void remove_trace_from_traceset_selector(GtkWidget
* paned
, unsigned i
)
1592 LttvTracesetSelector
* s
;
1593 LttvTraceSelector
* t
;
1596 w
= gtk_multivpaned_get_first_widget(GTK_MULTIVPANED(paned
));
1598 s
= g_object_get_data(G_OBJECT(w
), "Traceset_Selector");
1600 t
= lttv_traceset_selector_trace_get(s
,i
);
1601 lttv_traceset_selector_trace_remove(s
, i
);
1602 lttv_trace_selector_destroy(t
);
1603 }g_warning("Module dose not support filtering\n");
1604 w
= gtk_multivpaned_get_next_widget(GTK_MULTIVPANED(paned
));
1609 /* remove_trace removes a trace from the current traceset if all viewers in
1610 * the current tab are not interested in the trace. It first displays a
1611 * dialogue, which shows all traces in the current traceset, to let user choose
1612 * a trace, then it checks if all viewers unselect the trace, if it is true,
1613 * it will remove the trace, recreate the traceset_contex,
1614 * and redraws all the viewer of the current tab. If there is on trace in the
1615 * current traceset, it will delete all viewers of the current tab
1618 // MD : no filter version.
1619 void remove_trace(GtkWidget
*widget
, gpointer user_data
)
1622 LttvTrace
* trace_v
;
1623 LttvTraceset
* traceset
;
1624 gint i
, j
, nb_trace
, index
=-1;
1625 char ** name
, *remove_trace_name
;
1626 MainWindow
* mw_data
= get_window_data_struct(widget
);
1627 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
1629 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
1630 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
1636 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
1639 nb_trace
=lttv_traceset_number(tab
->traceset_info
->traceset
);
1640 name
= g_new(char*,nb_trace
);
1641 for(i
= 0; i
< nb_trace
; i
++){
1642 trace_v
= lttv_traceset_get(tab
->traceset_info
->traceset
, i
);
1643 trace
= lttv_trace(trace_v
);
1644 name
[i
] = ltt_trace_name(trace
);
1647 remove_trace_name
= get_remove_trace(name
, nb_trace
);
1650 if(remove_trace_name
){
1652 /* yuk, cut n paste from old code.. should be better (MD)*/
1653 for(i
= 0; i
<nb_trace
; i
++) {
1654 if(strcmp(remove_trace_name
,name
[i
]) == 0){
1659 traceset
= tab
->traceset_info
->traceset
;
1660 //Keep a reference to the traces so they are not freed.
1661 for(j
=0; j
<lttv_traceset_number(traceset
); j
++)
1663 LttvTrace
* trace
= lttv_traceset_get(traceset
, j
);
1664 lttv_trace_ref(trace
);
1667 //remove state update hooks
1668 lttv_state_remove_event_hooks(
1669 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1670 lttv_context_fini(LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
));
1671 g_object_unref(tab
->traceset_info
->traceset_context
);
1673 trace_v
= lttv_traceset_get(traceset
, index
);
1675 lttv_traceset_remove(traceset
, index
);
1676 lttv_trace_unref(trace_v
); // Remove local reference
1678 if(lttv_trace_get_ref_number(trace_v
) <= 1) {
1679 /* ref 1 : lttvwindowtraces only*/
1680 ltt_trace_close(lttv_trace(trace_v
));
1681 /* lttvwindowtraces_remove_trace takes care of destroying
1682 * the traceset linked with the trace_v and also of destroying
1683 * the trace_v at the same time.
1685 lttvwindowtraces_remove_trace(trace_v
);
1688 tab
->traceset_info
->traceset_context
=
1689 g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
1691 LTTV_TRACESET_CONTEXT(tab
->
1692 traceset_info
->traceset_context
),traceset
);
1693 //add state update hooks
1694 lttv_state_add_event_hooks(
1695 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1697 //Remove local reference to the traces.
1698 for(j
=0; j
<lttv_traceset_number(traceset
); j
++)
1700 LttvTrace
* trace
= lttv_traceset_get(traceset
, j
);
1701 lttv_trace_unref(trace
);
1704 SetTraceset(tab
, (gpointer
)traceset
);
1710 void remove_trace(GtkWidget
* widget
, gpointer user_data
)
1713 LttvTrace
* trace_v
;
1714 LttvTraceset
* traceset
;
1715 gint i
, j
, nb_trace
;
1716 char ** name
, *remove_trace_name
;
1717 MainWindow
* mw_data
= get_window_data_struct(widget
);
1718 LttvTracesetSelector
* s
;
1719 LttvTraceSelector
* t
;
1722 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
1724 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
1725 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
1731 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
1734 nb_trace
=lttv_traceset_number(tab
->traceset_info
->traceset
);
1735 name
= g_new(char*,nb_trace
);
1736 for(i
= 0; i
< nb_trace
; i
++){
1737 trace_v
= lttv_traceset_get(tab
->traceset_info
->traceset
, i
);
1738 trace
= lttv_trace(trace_v
);
1739 name
[i
] = ltt_trace_name(trace
);
1742 remove_trace_name
= get_remove_trace(name
, nb_trace
);
1744 if(remove_trace_name
){
1745 for(i
=0; i
<nb_trace
; i
++){
1746 if(strcmp(remove_trace_name
,name
[i
]) == 0){
1747 //unselect the trace from the current viewer
1749 w
= gtk_multivpaned_get_widget(GTK_MULTIVPANED(tab
->multivpaned
));
1751 s
= g_object_get_data(G_OBJECT(w
), "Traceset_Selector");
1753 t
= lttv_traceset_selector_trace_get(s
,i
);
1754 lttv_trace_selector_set_selected(t
, FALSE
);
1757 //check if other viewers select the trace
1758 w
= gtk_multivpaned_get_first_widget(GTK_MULTIVPANED(tab
->multivpaned
));
1760 s
= g_object_get_data(G_OBJECT(w
), "Traceset_Selector");
1762 t
= lttv_traceset_selector_trace_get(s
,i
);
1763 selected
= lttv_trace_selector_get_selected(t
);
1766 w
= gtk_multivpaned_get_next_widget(GTK_MULTIVPANED(tab
->multivpaned
));
1768 }else selected
= FALSE
;
1770 //if no viewer selects the trace, remove it
1772 remove_trace_from_traceset_selector(GTK_MULTIVPANED(tab
->multivpaned
), i
);
1774 traceset
= tab
->traceset_info
->traceset
;
1775 //Keep a reference to the traces so they are not freed.
1776 for(j
=0; j
<lttv_traceset_number(traceset
); j
++)
1778 LttvTrace
* trace
= lttv_traceset_get(traceset
, j
);
1779 lttv_trace_ref(trace
);
1782 //remove state update hooks
1783 lttv_state_remove_event_hooks(
1784 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1785 lttv_context_fini(LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
));
1786 g_object_unref(tab
->traceset_info
->traceset_context
);
1789 trace_v
= lttv_traceset_get(traceset
, i
);
1791 if(lttv_trace_get_ref_number(trace_v
) <= 2) {
1792 /* ref 2 : traceset, local */
1793 lttvwindowtraces_remove_trace(trace_v
);
1794 ltt_trace_close(lttv_trace(trace_v
));
1797 lttv_traceset_remove(traceset
, i
);
1798 lttv_trace_unref(trace_v
); // Remove local reference
1800 if(!lttv_trace_get_ref_number(trace_v
))
1801 lttv_trace_destroy(trace_v
);
1803 tab
->traceset_info
->traceset_context
=
1804 g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
1806 LTTV_TRACESET_CONTEXT(tab
->
1807 traceset_info
->traceset_context
),traceset
);
1808 //add state update hooks
1809 lttv_state_add_event_hooks(
1810 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1812 //Remove local reference to the traces.
1813 for(j
=0; j
<lttv_traceset_number(traceset
); j
++)
1815 LttvTrace
* trace
= lttv_traceset_get(traceset
, j
);
1816 lttv_trace_unref(trace
);
1820 //update current tab
1821 //update_traceset(mw_data);
1824 SetTraceset(tab
, (gpointer
)traceset
);
1825 // in expose now call_pending_read_hooks(mw_data);
1827 //lttvwindow_report_current_time(mw_data,&(tab->current_time));
1830 // while(tab->multi_vpaned->num_children){
1831 // gtk_multi_vpaned_widget_delete(tab->multi_vpaned);
1845 /* Redraw all the viewers in the current tab */
1846 void redraw(GtkWidget
*widget
, gpointer user_data
)
1848 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
1849 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
1850 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
1855 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
1859 LttvAttributeValue value
;
1861 g_assert(lttv_iattribute_find_by_path(tab
->attributes
, "hooks/redraw", LTTV_POINTER
, &value
));
1863 tmp
= (LttvHooks
*)*(value
.v_pointer
);
1865 lttv_hooks_call(tmp
,NULL
);
1869 void continue_processing(GtkWidget
*widget
, gpointer user_data
)
1871 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
1872 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
1873 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
1878 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
1882 LttvAttributeValue value
;
1884 g_assert(lttv_iattribute_find_by_path(tab
->attributes
,
1885 "hooks/continue", LTTV_POINTER
, &value
));
1887 tmp
= (LttvHooks
*)*(value
.v_pointer
);
1889 lttv_hooks_call(tmp
,NULL
);
1892 /* Stop the processing for the calling main window's current tab.
1893 * It removes every processing requests that are in its list. It does not call
1894 * the end request hooks, because the request is not finished.
1897 void stop_processing(GtkWidget
*widget
, gpointer user_data
)
1899 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
1900 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
1901 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
1906 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
1908 GSList
*iter
= tab
->events_requests
;
1910 while(iter
!= NULL
) {
1911 GSList
*remove_iter
= iter
;
1912 iter
= g_slist_next(iter
);
1914 g_free(remove_iter
->data
);
1915 tab
->events_requests
=
1916 g_slist_remove_link(tab
->events_requests
, remove_iter
);
1918 tab
->events_request_pending
= FALSE
;
1919 g_idle_remove_by_data(tab
);
1920 g_assert(g_slist_length(tab
->events_requests
) == 0);
1924 /* save will save the traceset to a file
1925 * Not implemented yet FIXME
1928 void save(GtkWidget
* widget
, gpointer user_data
)
1933 void save_as(GtkWidget
* widget
, gpointer user_data
)
1935 g_printf("Save as\n");
1939 /* zoom will change the time_window of all the viewers of the
1940 * current tab, and redisplay them. The main functionality is to
1941 * determine the new time_window of the current tab
1944 void zoom(GtkWidget
* widget
, double size
)
1946 TimeInterval time_span
;
1947 TimeWindow new_time_window
;
1948 LttTime current_time
, time_delta
, time_s
, time_e
, time_tmp
;
1949 MainWindow
* mw_data
= get_window_data_struct(widget
);
1950 LttvTracesetContext
*tsc
;
1951 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
1953 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
1954 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
1960 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
1963 if(size
== 1) return;
1965 tsc
= LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
1966 time_span
= tsc
->time_span
;
1967 new_time_window
= tab
->time_window
;
1968 current_time
= tab
->current_time
;
1970 time_delta
= ltt_time_sub(time_span
.end_time
,time_span
.start_time
);
1972 new_time_window
.start_time
= time_span
.start_time
;
1973 new_time_window
.time_width
= time_delta
;
1975 new_time_window
.time_width
= ltt_time_div(new_time_window
.time_width
, size
);
1976 if(ltt_time_compare(new_time_window
.time_width
,time_delta
) > 0)
1977 { /* Case where zoom out is bigger than trace length */
1978 new_time_window
.start_time
= time_span
.start_time
;
1979 new_time_window
.time_width
= time_delta
;
1983 /* Center the image on the current time */
1984 new_time_window
.start_time
=
1985 ltt_time_sub(current_time
, ltt_time_div(new_time_window
.time_width
, 2.0));
1986 /* If on borders, don't fall off */
1987 if(ltt_time_compare(new_time_window
.start_time
, time_span
.start_time
) <0)
1989 new_time_window
.start_time
= time_span
.start_time
;
1993 if(ltt_time_compare(
1994 ltt_time_add(new_time_window
.start_time
, new_time_window
.time_width
),
1995 time_span
.end_time
) > 0)
1997 new_time_window
.start_time
=
1998 ltt_time_sub(time_span
.end_time
, new_time_window
.time_width
);
2004 //time_tmp = ltt_time_div(new_time_window.time_width, 2);
2005 //if(ltt_time_compare(current_time, time_tmp) < 0){
2006 // time_s = time_span->startTime;
2008 // time_s = ltt_time_sub(current_time,time_tmp);
2010 //time_e = ltt_time_add(current_time,time_tmp);
2011 //if(ltt_time_compare(time_span->startTime, time_s) > 0){
2012 // time_s = time_span->startTime;
2013 //}else if(ltt_time_compare(time_span->endTime, time_e) < 0){
2014 // time_e = time_span->endTime;
2015 // time_s = ltt_time_sub(time_e,new_time_window.time_width);
2017 //new_time_window.start_time = time_s;
2020 //lttvwindow_report_time_window(mw_data, &new_time_window);
2021 //call_pending_read_hooks(mw_data);
2023 //lttvwindow_report_current_time(mw_data,&(tab->current_time));
2024 //set_time_window(tab, &new_time_window);
2025 // in expose now call_pending_read_hooks(mw_data);
2026 //gtk_multi_vpaned_set_adjust(tab->multi_vpaned, &new_time_window, FALSE);
2031 ltt_time_sub(new_time_window
.start_time
, time_span
.start_time
);
2032 if( ltt_time_to_double(new_time_window
.time_width
)
2033 * NANOSECONDS_PER_SECOND
2034 / SCROLL_STEP_PER_PAGE
/* step increment */
2036 ltt_time_to_double(rel_time
) * NANOSECONDS_PER_SECOND
/* page size */
2038 ltt_time_to_double(rel_time
) * NANOSECONDS_PER_SECOND
/* page size */
2040 g_warning("Can not zoom that far due to scrollbar precision");
2043 ltt_time_from_double(
2044 ltt_time_to_double(new_time_window
.time_width
)
2045 /SCROLL_STEP_PER_PAGE
),
2048 g_warning("Can not zoom that far due to time nanosecond precision");
2050 time_change_manager(tab
, new_time_window
);
2053 GtkAdjustment
*adjustment
= gtk_range_get_adjustment(GTK_RANGE(tab
->scrollbar
));
2055 g_object_set(G_OBJECT(adjustment
),
2057 //ltt_time_to_double(new_time_window.start_time)
2058 // * NANOSECONDS_PER_SECOND, /* value */
2063 ltt_time_sub(time_span
.end_time
, time_span
.start_time
))
2064 * NANOSECONDS_PER_SECOND
, /* upper */
2066 ltt_time_to_double(new_time_window
.time_width
)
2067 / SCROLL_STEP_PER_PAGE
2068 * NANOSECONDS_PER_SECOND
, /* step increment */
2070 ltt_time_to_double(new_time_window
.time_width
)
2071 * NANOSECONDS_PER_SECOND
, /* page increment */
2073 ltt_time_to_double(new_time_window
.time_width
)
2074 * NANOSECONDS_PER_SECOND
, /* page size */
2076 gtk_adjustment_changed(adjustment
);
2077 //gtk_range_set_adjustment(GTK_RANGE(tab->scrollbar), adjustment);
2078 //gtk_adjustment_value_changed(adjustment);
2079 g_object_set(G_OBJECT(adjustment
),
2082 ltt_time_sub(new_time_window
.start_time
, time_span
.start_time
))
2083 * NANOSECONDS_PER_SECOND
, /* value */
2085 gtk_adjustment_value_changed(adjustment
);
2088 //g_object_set(G_OBJECT(adjustment),
2090 // ltt_time_to_double(time_window->start_time)
2091 // * NANOSECONDS_PER_SECOND, /* value */
2093 /* Note : the set value will call set_time_window if scrollbar value changed
2095 //gtk_adjustment_set_value(adjustment,
2096 // ltt_time_to_double(new_time_window.start_time)
2097 // * NANOSECONDS_PER_SECOND);
2102 void zoom_in(GtkWidget
* widget
, gpointer user_data
)
2107 void zoom_out(GtkWidget
* widget
, gpointer user_data
)
2112 void zoom_extended(GtkWidget
* widget
, gpointer user_data
)
2117 void go_to_time(GtkWidget
* widget
, gpointer user_data
)
2119 g_printf("Go to time\n");
2122 void show_time_frame(GtkWidget
* widget
, gpointer user_data
)
2124 g_printf("Show time frame\n");
2128 /* callback function */
2131 on_empty_traceset_activate (GtkMenuItem
*menuitem
,
2134 create_new_window((GtkWidget
*)menuitem
, user_data
, FALSE
);
2139 on_clone_traceset_activate (GtkMenuItem
*menuitem
,
2142 create_new_window((GtkWidget
*)menuitem
, user_data
, TRUE
);
2146 /* create_new_tab calls create_tab to construct a new tab in the main window
2149 Tab
*create_new_tab(GtkWidget
* widget
, gpointer user_data
){
2150 gchar label
[PATH_MAX
];
2151 MainWindow
* mw_data
= get_window_data_struct(widget
);
2153 GtkNotebook
* notebook
= (GtkNotebook
*)lookup_widget(widget
, "MNotebook");
2154 if(notebook
== NULL
){
2155 g_printf("Notebook does not exist\n");
2158 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2159 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2165 copy_tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
2168 strcpy(label
,"Page");
2169 if(get_label(mw_data
, label
,"Get the name of the tab","Please input tab's name"))
2170 return (create_tab (mw_data
, copy_tab
, notebook
, label
));
2174 on_tab_activate (GtkMenuItem
*menuitem
,
2177 create_new_tab((GtkWidget
*)menuitem
, user_data
);
2182 on_open_activate (GtkMenuItem
*menuitem
,
2185 open_traceset((GtkWidget
*)menuitem
, user_data
);
2190 on_close_activate (GtkMenuItem
*menuitem
,
2193 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2194 main_window_destructor(mw_data
);
2198 /* remove the current tab from the main window
2202 on_close_tab_activate (GtkWidget
*widget
,
2206 GtkWidget
* notebook
;
2208 MainWindow
* mw_data
= get_window_data_struct(widget
);
2209 notebook
= lookup_widget(widget
, "MNotebook");
2210 if(notebook
== NULL
){
2211 g_printf("Notebook does not exist\n");
2215 page_num
= gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
));
2217 gtk_notebook_remove_page(GTK_NOTEBOOK(notebook
), page_num
);
2222 on_close_tab_X_clicked (GtkWidget
*widget
,
2226 GtkWidget
*notebook
= lookup_widget(widget
, "MNotebook");
2227 if(notebook
== NULL
){
2228 g_printf("Notebook does not exist\n");
2232 if((page_num
= gtk_notebook_page_num(GTK_NOTEBOOK(notebook
), widget
)) != -1)
2233 gtk_notebook_remove_page(GTK_NOTEBOOK(notebook
), page_num
);
2239 on_add_trace_activate (GtkMenuItem
*menuitem
,
2242 add_trace((GtkWidget
*)menuitem
, user_data
);
2247 on_remove_trace_activate (GtkMenuItem
*menuitem
,
2250 remove_trace((GtkWidget
*)menuitem
, user_data
);
2255 on_save_activate (GtkMenuItem
*menuitem
,
2258 save((GtkWidget
*)menuitem
, user_data
);
2263 on_save_as_activate (GtkMenuItem
*menuitem
,
2266 save_as((GtkWidget
*)menuitem
, user_data
);
2271 on_quit_activate (GtkMenuItem
*menuitem
,
2279 on_cut_activate (GtkMenuItem
*menuitem
,
2287 on_copy_activate (GtkMenuItem
*menuitem
,
2290 g_printf("Copye\n");
2295 on_paste_activate (GtkMenuItem
*menuitem
,
2298 g_printf("Paste\n");
2303 on_delete_activate (GtkMenuItem
*menuitem
,
2306 g_printf("Delete\n");
2311 on_zoom_in_activate (GtkMenuItem
*menuitem
,
2314 zoom_in((GtkWidget
*)menuitem
, user_data
);
2319 on_zoom_out_activate (GtkMenuItem
*menuitem
,
2322 zoom_out((GtkWidget
*)menuitem
, user_data
);
2327 on_zoom_extended_activate (GtkMenuItem
*menuitem
,
2330 zoom_extended((GtkWidget
*)menuitem
, user_data
);
2335 on_go_to_time_activate (GtkMenuItem
*menuitem
,
2338 go_to_time((GtkWidget
*)menuitem
, user_data
);
2343 on_show_time_frame_activate (GtkMenuItem
*menuitem
,
2346 show_time_frame((GtkWidget
*)menuitem
, user_data
);
2351 on_move_viewer_up_activate (GtkMenuItem
*menuitem
,
2354 move_up_viewer((GtkWidget
*)menuitem
, user_data
);
2359 on_move_viewer_down_activate (GtkMenuItem
*menuitem
,
2362 move_down_viewer((GtkWidget
*)menuitem
, user_data
);
2367 on_remove_viewer_activate (GtkMenuItem
*menuitem
,
2370 delete_viewer((GtkWidget
*)menuitem
, user_data
);
2375 on_trace_filter_activate (GtkMenuItem
*menuitem
,
2378 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2379 LttvTracesetSelector
* s
;
2381 GtkWidget
* notebook
= lookup_widget(GTK_WIDGET(menuitem
), "MNotebook");
2383 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2384 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2390 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
2393 w
= gtk_multivpaned_get_widget(GTK_MULTIVPANED(tab
->multivpaned
));
2395 s
= g_object_get_data(G_OBJECT(w
), "Traceset_Selector");
2397 g_printf("There is no viewer yet\n");
2400 if(get_filter_selection(s
, "Configure trace and tracefile filter", "Select traces and tracefiles")){
2401 //FIXME report filter change
2402 //update_traceset(mw_data);
2403 //call_pending_read_hooks(mw_data);
2404 //lttvwindow_report_current_time(mw_data,&(tab->current_time));
2410 on_trace_facility_activate (GtkMenuItem
*menuitem
,
2413 g_printf("Trace facility selector: %s\n");
2417 /* Dispaly a file selection dialogue to let user select a library, then call
2418 * lttv_library_load().
2422 on_load_library_activate (GtkMenuItem
*menuitem
,
2425 GError
*error
= NULL
;
2426 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2428 gchar load_module_path_alter
[PATH_MAX
];
2432 gchar
*load_module_path
;
2433 name
= g_ptr_array_new();
2434 nb
= lttv_library_path_number();
2435 /* ask for the library path */
2439 path
= lttv_library_path_get(i
);
2440 g_ptr_array_add(name
, path
);
2443 load_module_path
= get_selection((char **)(name
->pdata
), name
->len
,
2444 "Select a library path", "Library paths");
2445 if(load_module_path
!= NULL
)
2446 strncpy(load_module_path_alter
, load_module_path
, PATH_MAX
-1); // -1 for /
2448 g_ptr_array_free(name
, TRUE
);
2450 if(load_module_path
== NULL
) return;
2454 /* Make sure the module path ends with a / */
2455 gchar
*ptr
= load_module_path_alter
;
2457 ptr
= strchr(ptr
, '\0');
2459 if(*(ptr
-1) != '/') {
2466 /* Ask for the library to load : list files in the previously selected
2468 gchar str
[PATH_MAX
];
2471 GtkFileSelection
* file_selector
=
2472 (GtkFileSelection
*)gtk_file_selection_new("Select a module");
2473 gtk_file_selection_set_filename(file_selector
, load_module_path_alter
);
2474 gtk_file_selection_hide_fileop_buttons(file_selector
);
2477 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
2479 case GTK_RESPONSE_ACCEPT
:
2480 case GTK_RESPONSE_OK
:
2481 dir
= gtk_file_selection_get_selections (file_selector
);
2482 strncpy(str
,dir
[0],PATH_MAX
);
2483 strncpy(remember_plugins_dir
,dir
[0],PATH_MAX
);
2484 /* only keep file name */
2486 str1
= strrchr(str
,'/');
2489 str1
= strrchr(str
,'\\');
2494 if(*str1
== 'l' && *(str1
+1)== 'i' && *(str1
+2)=='b')
2496 remove info after
. */
2500 str2
= strrchr(str2
, '.');
2501 if(str2
!= NULL
) *str2
= '\0';
2503 lttv_module_require(str1
, &error
);
2505 lttv_library_load(str1
, &error
);
2506 if(error
!= NULL
) g_warning(error
->message
);
2507 else g_printf("Load library: %s\n", str
);
2509 case GTK_RESPONSE_REJECT
:
2510 case GTK_RESPONSE_CANCEL
:
2512 gtk_widget_destroy((GtkWidget
*)file_selector
);
2523 /* Display all loaded modules, let user to select a module to unload
2524 * by calling lttv_module_unload
2528 on_unload_library_activate (GtkMenuItem
*menuitem
,
2531 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2533 LttvLibrary
*library
;
2538 name
= g_ptr_array_new();
2539 nb
= lttv_library_number();
2540 LttvLibraryInfo
*lib_info
= g_new(LttvLibraryInfo
,nb
);
2541 /* ask for the library name */
2544 LttvLibrary
*iter_lib
= lttv_library_get(i
);
2545 lttv_library_info(iter_lib
, &lib_info
[i
]);
2547 gchar
*path
= lib_info
[i
].name
;
2548 g_ptr_array_add(name
, lib_info
[i
].name
);
2550 lib_name
= get_selection((char **)(name
->pdata
), name
->len
,
2551 "Select a library", "Libraries");
2552 if(lib_name
!= NULL
) {
2554 if(strcmp(lib_name
, lib_info
[i
].name
) == 0) {
2555 library
= lttv_library_get(i
);
2560 g_ptr_array_free(name
, TRUE
);
2563 if(lib_name
== NULL
) return;
2566 lttv_library_unload(library
);
2570 /* Dispaly a file selection dialogue to let user select a module, then call
2571 * lttv_module_require().
2575 on_load_module_activate (GtkMenuItem
*menuitem
,
2578 GError
*error
= NULL
;
2579 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2581 LttvLibrary
*library
;
2586 name
= g_ptr_array_new();
2587 nb
= lttv_library_number();
2588 LttvLibraryInfo
*lib_info
= g_new(LttvLibraryInfo
,nb
);
2589 /* ask for the library name */
2592 LttvLibrary
*iter_lib
= lttv_library_get(i
);
2593 lttv_library_info(iter_lib
, &lib_info
[i
]);
2595 gchar
*path
= lib_info
[i
].name
;
2596 g_ptr_array_add(name
, path
);
2598 lib_name
= get_selection((char **)(name
->pdata
), name
->len
,
2599 "Select a library", "Libraries");
2600 if(lib_name
!= NULL
) {
2602 if(strcmp(lib_name
, lib_info
[i
].name
) == 0) {
2603 library
= lttv_library_get(i
);
2608 g_ptr_array_free(name
, TRUE
);
2611 if(lib_name
== NULL
) return;
2614 //LttvModule *module;
2615 gchar module_name_out
[PATH_MAX
];
2617 /* Ask for the module to load : list modules in the selected lib */
2621 LttvModuleInfo
*module_info
= g_new(LttvModuleInfo
,nb
);
2622 name
= g_ptr_array_new();
2623 nb
= lttv_library_module_number(library
);
2624 /* ask for the module name */
2627 LttvModule
*iter_module
= lttv_library_module_get(library
, i
);
2628 lttv_module_info(iter_module
, &module_info
[i
]);
2630 gchar
*path
= module_info
[i
].name
;
2631 g_ptr_array_add(name
, path
);
2633 module_name
= get_selection((char **)(name
->pdata
), name
->len
,
2634 "Select a module", "Modules");
2635 if(module_name
!= NULL
) {
2637 if(strcmp(module_name
, module_info
[i
].name
) == 0) {
2638 strncpy(module_name_out
, module_name
, PATH_MAX
);
2639 //module = lttv_library_module_get(i);
2645 g_ptr_array_free(name
, TRUE
);
2646 g_free(module_info
);
2648 if(module_name
== NULL
) return;
2651 lttv_module_require(module_name_out
, &error
);
2652 if(error
!= NULL
) g_warning(error
->message
);
2653 else g_printf("Load module: %s\n", module_name_out
);
2660 gchar str
[PATH_MAX
];
2663 GtkFileSelection
* file_selector
=
2664 (GtkFileSelection
*)gtk_file_selection_new("Select a module");
2665 gtk_file_selection_set_filename(file_selector
, load_module_path_alter
);
2666 gtk_file_selection_hide_fileop_buttons(file_selector
);
2669 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
2671 case GTK_RESPONSE_ACCEPT
:
2672 case GTK_RESPONSE_OK
:
2673 dir
= gtk_file_selection_get_selections (file_selector
);
2674 strncpy(str
,dir
[0],PATH_MAX
);
2675 strncpy(remember_plugins_dir
,dir
[0],PATH_MAX
);
2677 /* only keep file name */
2679 str1
= strrchr(str
,'/');
2682 str1
= strrchr(str
,'\\');
2687 if(*str1
== 'l' && *(str1
+1)== 'i' && *(str1
+2)=='b')
2689 remove info after
. */
2693 str2
= strrchr(str2
, '.');
2694 if(str2
!= NULL
) *str2
= '\0';
2696 lttv_module_require(str1
, &error
);
2698 lttv_library_load(str1
, &error
);
2699 if(error
!= NULL
) g_warning(error
->message
);
2700 else g_printf("Load library: %s\n", str
);
2702 case GTK_RESPONSE_REJECT
:
2703 case GTK_RESPONSE_CANCEL
:
2705 gtk_widget_destroy((GtkWidget
*)file_selector
);
2717 /* Display all loaded modules, let user to select a module to unload
2718 * by calling lttv_module_unload
2722 on_unload_module_activate (GtkMenuItem
*menuitem
,
2725 GError
*error
= NULL
;
2726 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2728 LttvLibrary
*library
;
2733 name
= g_ptr_array_new();
2734 nb
= lttv_library_number();
2735 LttvLibraryInfo
*lib_info
= g_new(LttvLibraryInfo
,nb
);
2736 /* ask for the library name */
2739 LttvLibrary
*iter_lib
= lttv_library_get(i
);
2740 lttv_library_info(iter_lib
, &lib_info
[i
]);
2742 gchar
*path
= lib_info
[i
].name
;
2743 g_ptr_array_add(name
, path
);
2745 lib_name
= get_selection((char **)(name
->pdata
), name
->len
,
2746 "Select a library", "Libraries");
2747 if(lib_name
!= NULL
) {
2749 if(strcmp(lib_name
, lib_info
[i
].name
) == 0) {
2750 library
= lttv_library_get(i
);
2755 g_ptr_array_free(name
, TRUE
);
2758 if(lib_name
== NULL
) return;
2763 /* Ask for the module to load : list modules in the selected lib */
2767 nb
= lttv_library_module_number(library
);
2768 LttvModuleInfo
*module_info
= g_new(LttvModuleInfo
,nb
);
2769 name
= g_ptr_array_new();
2770 /* ask for the module name */
2773 LttvModule
*iter_module
= lttv_library_module_get(library
, i
);
2774 lttv_module_info(iter_module
, &module_info
[i
]);
2776 gchar
*path
= module_info
[i
].name
;
2777 if(module_info
[i
].use_count
> 0) g_ptr_array_add(name
, path
);
2779 module_name
= get_selection((char **)(name
->pdata
), name
->len
,
2780 "Select a module", "Modules");
2781 if(module_name
!= NULL
) {
2783 if(strcmp(module_name
, module_info
[i
].name
) == 0) {
2784 module
= lttv_library_module_get(library
, i
);
2790 g_ptr_array_free(name
, TRUE
);
2791 g_free(module_info
);
2793 if(module_name
== NULL
) return;
2796 LttvModuleInfo module_info
;
2797 lttv_module_info(module
, &module_info
);
2798 g_printf("Release module: %s\n", module_info
.name
);
2800 lttv_module_release(module
);
2804 /* Display a directory dialogue to let user select a path for library searching
2808 on_add_library_search_path_activate (GtkMenuItem
*menuitem
,
2811 GtkDirSelection
* file_selector
= (GtkDirSelection
*)gtk_dir_selection_new("Select library path");
2815 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2816 if(remember_plugins_dir
[0] != '\0')
2817 gtk_dir_selection_set_filename(file_selector
, remember_plugins_dir
);
2819 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
2821 case GTK_RESPONSE_ACCEPT
:
2822 case GTK_RESPONSE_OK
:
2823 dir
= gtk_dir_selection_get_dir (file_selector
);
2824 strncpy(remember_plugins_dir
,dir
,PATH_MAX
);
2825 strncat(remember_plugins_dir
,"/",PATH_MAX
);
2826 lttv_library_path_add(dir
);
2827 case GTK_RESPONSE_REJECT
:
2828 case GTK_RESPONSE_CANCEL
:
2830 gtk_widget_destroy((GtkWidget
*)file_selector
);
2836 /* Display a directory dialogue to let user select a path for library searching
2840 on_remove_library_search_path_activate (GtkMenuItem
*menuitem
,
2843 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2845 const char *lib_path
;
2850 name
= g_ptr_array_new();
2851 nb
= lttv_library_path_number();
2852 /* ask for the library name */
2855 gchar
*path
= lttv_library_path_get(i
);
2856 g_ptr_array_add(name
, path
);
2858 lib_path
= get_selection((char **)(name
->pdata
), name
->len
,
2859 "Select a library path", "Library paths");
2861 g_ptr_array_free(name
, TRUE
);
2863 if(lib_path
== NULL
) return;
2866 lttv_library_path_remove(lib_path
);
2870 on_color_activate (GtkMenuItem
*menuitem
,
2873 g_printf("Color\n");
2878 on_filter_activate (GtkMenuItem
*menuitem
,
2881 g_printf("Filter\n");
2886 on_save_configuration_activate (GtkMenuItem
*menuitem
,
2889 g_printf("Save configuration\n");
2894 on_content_activate (GtkMenuItem
*menuitem
,
2897 g_printf("Content\n");
2902 on_about_close_activate (GtkButton
*button
,
2905 GtkWidget
*about_widget
= GTK_WIDGET(user_data
);
2907 gtk_widget_destroy(about_widget
);
2911 on_about_activate (GtkMenuItem
*menuitem
,
2914 MainWindow
*main_window
= get_window_data_struct(GTK_WIDGET(menuitem
));
2915 GtkWidget
*window_widget
= main_window
->mwindow
;
2916 GtkWidget
*about_widget
= gtk_window_new(GTK_WINDOW_TOPLEVEL
);
2917 GtkWindow
*about_window
= GTK_WINDOW(about_widget
);
2918 gint window_width
, window_height
;
2920 gtk_window_set_title(about_window
, "About Linux Trace Toolkit");
2922 gtk_window_set_resizable(about_window
, FALSE
);
2923 gtk_window_set_transient_for(GTK_WINDOW(window_widget
), about_window
);
2924 gtk_window_set_destroy_with_parent(about_window
, TRUE
);
2925 gtk_window_set_modal(about_window
, FALSE
);
2927 /* Put the about window at the center of the screen */
2928 gtk_window_get_size(about_window
, &window_width
, &window_height
);
2929 gtk_window_move (about_window
,
2930 (gdk_screen_width() - window_width
)/2,
2931 (gdk_screen_height() - window_height
)/2);
2933 GtkWidget
*vbox
= gtk_vbox_new(FALSE
, 1);
2935 gtk_container_add(GTK_CONTAINER(about_widget
), vbox
);
2939 GtkWidget
*label1
= gtk_label_new("");
2940 gtk_misc_set_padding(GTK_MISC(label1
), 10, 20);
2941 gtk_label_set_markup(GTK_LABEL(label1
), "\
2942 <big>Linux Trace Toolkit</big>");
2943 gtk_label_set_justify(GTK_LABEL(label1
), GTK_JUSTIFY_CENTER
);
2945 GtkWidget
*label2
= gtk_label_new("");
2946 gtk_misc_set_padding(GTK_MISC(label2
), 10, 20);
2947 gtk_label_set_markup(GTK_LABEL(label2
), "\
2948 Project author: Karim Yaghmour\n\
2952 Michel Dagenais (New trace format, lttv main)\n\
2953 Mathieu Desnoyers (Directory structure, build with automake/conf,\n\
2954 lttv gui, control flow view, gui green threads\n\
2955 with interruptible foreground and background computation,\n\
2956 detailed event list)\n\
2957 Benoit Des Ligneris (Cluster adaptation)\n\
2958 Xang-Xiu Yang (new trace reading library and converter, lttv gui, \n\
2959 detailed event list and statistics view)\n\
2960 Tom Zanussi (RelayFS)");
2962 GtkWidget
*label3
= gtk_label_new("");
2963 gtk_label_set_markup(GTK_LABEL(label3
), "\
2964 Linux Trace Toolkit, Copyright (C) 2004 Karim Yaghmour\n\
2965 Linux Trace Toolkit comes with ABSOLUTELY NO WARRANTY.\n\
2966 This is free software, and you are welcome to redistribute it\n\
2967 under certain conditions. See COPYING for details.");
2968 gtk_misc_set_padding(GTK_MISC(label3
), 10, 20);
2970 gtk_box_pack_start_defaults(GTK_BOX(vbox
), label1
);
2971 gtk_box_pack_start_defaults(GTK_BOX(vbox
), label2
);
2972 gtk_box_pack_start_defaults(GTK_BOX(vbox
), label3
);
2974 GtkWidget
*hbox
= gtk_hbox_new(TRUE
, 0);
2975 gtk_box_pack_end(GTK_BOX(vbox
), hbox
, FALSE
, FALSE
, 0);
2976 GtkWidget
*close_button
= gtk_button_new_with_mnemonic("_Close");
2977 gtk_box_pack_end(GTK_BOX(hbox
), close_button
, FALSE
, FALSE
, 0);
2978 gtk_container_set_border_width(GTK_CONTAINER(close_button
), 20);
2980 g_signal_connect(G_OBJECT(close_button
), "clicked",
2981 G_CALLBACK(on_about_close_activate
),
2982 (gpointer
)about_widget
);
2984 gtk_widget_show_all(about_widget
);
2989 on_button_new_clicked (GtkButton
*button
,
2992 create_new_window((GtkWidget
*)button
, user_data
, TRUE
);
2996 on_button_new_tab_clicked (GtkButton
*button
,
2999 create_new_tab((GtkWidget
*)button
, user_data
);
3003 on_button_open_clicked (GtkButton
*button
,
3006 open_traceset((GtkWidget
*)button
, user_data
);
3011 on_button_add_trace_clicked (GtkButton
*button
,
3014 add_trace((GtkWidget
*)button
, user_data
);
3019 on_button_remove_trace_clicked (GtkButton
*button
,
3022 remove_trace((GtkWidget
*)button
, user_data
);
3026 on_button_redraw_clicked (GtkButton
*button
,
3029 redraw((GtkWidget
*)button
, user_data
);
3033 on_button_continue_processing_clicked (GtkButton
*button
,
3036 continue_processing((GtkWidget
*)button
, user_data
);
3040 on_button_stop_processing_clicked (GtkButton
*button
,
3043 stop_processing((GtkWidget
*)button
, user_data
);
3049 on_button_save_clicked (GtkButton
*button
,
3052 save((GtkWidget
*)button
, user_data
);
3057 on_button_save_as_clicked (GtkButton
*button
,
3060 save_as((GtkWidget
*)button
, user_data
);
3065 on_button_zoom_in_clicked (GtkButton
*button
,
3068 zoom_in((GtkWidget
*)button
, user_data
);
3073 on_button_zoom_out_clicked (GtkButton
*button
,
3076 zoom_out((GtkWidget
*)button
, user_data
);
3081 on_button_zoom_extended_clicked (GtkButton
*button
,
3084 zoom_extended((GtkWidget
*)button
, user_data
);
3089 on_button_go_to_time_clicked (GtkButton
*button
,
3092 go_to_time((GtkWidget
*)button
, user_data
);
3097 on_button_show_time_frame_clicked (GtkButton
*button
,
3100 show_time_frame((GtkWidget
*)button
, user_data
);
3105 on_button_move_up_clicked (GtkButton
*button
,
3108 move_up_viewer((GtkWidget
*)button
, user_data
);
3113 on_button_move_down_clicked (GtkButton
*button
,
3116 move_down_viewer((GtkWidget
*)button
, user_data
);
3121 on_button_delete_viewer_clicked (GtkButton
*button
,
3124 delete_viewer((GtkWidget
*)button
, user_data
);
3128 on_MWindow_destroy (GtkWidget
*widget
,
3131 MainWindow
*main_window
= get_window_data_struct(widget
);
3132 LttvIAttribute
*attributes
= main_window
->attributes
;
3133 LttvAttributeValue value
;
3135 //This is unnecessary, since widgets will be destroyed
3136 //by the main window widget anyway.
3137 //remove_all_menu_toolbar_constructors(main_window, NULL);
3139 g_assert(lttv_iattribute_find_by_path(attributes
,
3140 "viewers/menu", LTTV_POINTER
, &value
));
3141 lttv_menus_destroy((LttvMenus
*)*(value
.v_pointer
));
3143 g_assert(lttv_iattribute_find_by_path(attributes
,
3144 "viewers/toolbar", LTTV_POINTER
, &value
));
3145 lttv_toolbars_destroy((LttvToolbars
*)*(value
.v_pointer
));
3147 g_object_unref(main_window
->attributes
);
3148 g_main_window_list
= g_slist_remove(g_main_window_list
, main_window
);
3150 g_printf("There are now : %d windows\n",g_slist_length(g_main_window_list
));
3151 if(g_slist_length(g_main_window_list
) == 0)
3156 on_MWindow_configure (GtkWidget
*widget
,
3157 GdkEventConfigure
*event
,
3160 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)widget
);
3161 float width
= event
->width
;
3162 TimeWindow time_win
;
3164 TimeInterval
*time_span
;
3167 // MD : removed time width modification upon resizing of the main window.
3168 // The viewers will redraw themselves completely, without time interval
3171 if(mw_data->window_width){
3172 time_span = LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context)->Time_Span ;
3173 time_win = tab->time_window;
3174 ratio = width / mw_data->window_width;
3175 tab->time_window.time_width = ltt_time_mul(time_win.time_width,ratio);
3176 time = ltt_time_sub(time_span->endTime, time_win.start_time);
3177 if(ltt_time_compare(time, tab->time_window.time_width) < 0){
3178 tab->time_window.time_width = time;
3184 mw_data->window_width = (int)width;
3193 on_MNotebook_switch_page (GtkNotebook
*notebook
,
3194 GtkNotebookPage
*page
,
3202 void time_change_manager (Tab
*tab
,
3203 TimeWindow new_time_window
)
3205 /* Only one source of time change */
3206 if(tab
->time_manager_lock
== TRUE
) return;
3208 tab
->time_manager_lock
= TRUE
;
3210 LttvTracesetContext
*tsc
= LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3211 TimeInterval time_span
= tsc
->time_span
;
3212 LttTime start_time
= new_time_window
.start_time
;
3213 LttTime end_time
= ltt_time_add(new_time_window
.start_time
,
3214 new_time_window
.time_width
);
3217 GtkAdjustment
*adjustment
= gtk_range_get_adjustment(GTK_RANGE(tab
->scrollbar
));
3218 LttTime upper
= ltt_time_sub(time_span
.end_time
, time_span
.start_time
);
3220 gtk_range_set_increments(GTK_RANGE(tab
->scrollbar
),
3221 ltt_time_to_double(new_time_window
.time_width
)
3222 / SCROLL_STEP_PER_PAGE
3223 * NANOSECONDS_PER_SECOND
, /* step increment */
3224 ltt_time_to_double(new_time_window
.time_width
)
3225 * NANOSECONDS_PER_SECOND
); /* page increment */
3226 gtk_range_set_range(GTK_RANGE(tab
->scrollbar
),
3228 ltt_time_to_double(upper
)
3229 * NANOSECONDS_PER_SECOND
); /* upper */
3231 g_object_set(G_OBJECT(adjustment
),
3235 ltt_time_to_double(upper
)
3236 * NANOSECONDS_PER_SECOND
, /* upper */
3238 ltt_time_to_double(new_time_window
.time_width
)
3239 / SCROLL_STEP_PER_PAGE
3240 * NANOSECONDS_PER_SECOND
, /* step increment */
3242 ltt_time_to_double(new_time_window
.time_width
)
3243 * NANOSECONDS_PER_SECOND
, /* page increment */
3245 ltt_time_to_double(new_time_window
.time_width
)
3246 * NANOSECONDS_PER_SECOND
, /* page size */
3248 gtk_adjustment_changed(adjustment
);
3250 // g_object_set(G_OBJECT(adjustment),
3252 // ltt_time_to_double(
3253 // ltt_time_sub(start_time, time_span.start_time))
3254 // * NANOSECONDS_PER_SECOND, /* value */
3256 //gtk_adjustment_value_changed(adjustment);
3257 gtk_range_set_value(GTK_RANGE(tab
->scrollbar
),
3259 ltt_time_sub(start_time
, time_span
.start_time
))
3260 * NANOSECONDS_PER_SECOND
/* value */);
3262 /* set the time bar. */
3264 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry1
),
3265 (double)time_span
.start_time
.tv_sec
,
3266 (double)time_span
.end_time
.tv_sec
);
3267 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry1
),
3268 (double)start_time
.tv_sec
);
3270 /* start nanoseconds */
3271 if(start_time
.tv_sec
== time_span
.start_time
.tv_sec
) {
3272 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry2
),
3273 (double)time_span
.start_time
.tv_nsec
,
3274 (double)NANOSECONDS_PER_SECOND
-1);
3276 else if(start_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3277 /* If we are at the end, max nsec to end.. -1 (not zero length) */
3278 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry2
),
3280 (double)time_span
.end_time
.tv_nsec
-1);
3282 else /* anywhere else */
3283 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry2
),
3285 (double)NANOSECONDS_PER_SECOND
-1);
3286 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry2
),
3287 (double)start_time
.tv_nsec
);
3290 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry3
),
3291 (double)time_span
.start_time
.tv_sec
,
3292 (double)time_span
.end_time
.tv_sec
);
3293 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry3
),
3294 (double)end_time
.tv_sec
);
3296 /* end nanoseconds */
3297 if(end_time
.tv_sec
== time_span
.start_time
.tv_sec
) {
3298 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry4
),
3299 (double)time_span
.start_time
.tv_nsec
+1,
3300 (double)NANOSECONDS_PER_SECOND
-1);
3302 else if(end_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3303 /* If we are at the end, max nsec to end.. */
3304 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry4
),
3306 (double)time_span
.end_time
.tv_nsec
);
3308 else /* anywhere else */
3309 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry4
),
3311 (double)NANOSECONDS_PER_SECOND
-1);
3312 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry4
),
3313 (double)end_time
.tv_nsec
);
3315 /* call viewer hooks for new time window */
3316 set_time_window(tab
, &new_time_window
);
3318 tab
->time_manager_lock
= FALSE
;
3322 /* value changed for frame start s
3324 * Check time span : if ns is out of range, clip it the nearest good value.
3327 on_MEntry1_value_changed (GtkSpinButton
*spinbutton
,
3330 Tab
*tab
=(Tab
*)user_data
;
3331 LttvTracesetContext
* tsc
=
3332 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3333 TimeInterval time_span
= tsc
->time_span
;
3334 gint value
= gtk_spin_button_get_value_as_int(spinbutton
);
3336 TimeWindow new_time_window
= tab
->time_window
;
3338 LttTime end_time
= ltt_time_add(new_time_window
.start_time
,
3339 new_time_window
.time_width
);
3341 new_time_window
.start_time
.tv_sec
= value
;
3343 /* start nanoseconds */
3344 if(new_time_window
.start_time
.tv_sec
== time_span
.start_time
.tv_sec
) {
3345 if(new_time_window
.start_time
.tv_nsec
< time_span
.start_time
.tv_nsec
)
3346 new_time_window
.start_time
.tv_nsec
= time_span
.start_time
.tv_nsec
;
3348 else if(new_time_window
.start_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3349 if(new_time_window
.start_time
.tv_nsec
> time_span
.end_time
.tv_nsec
)
3350 new_time_window
.start_time
.tv_nsec
= time_span
.end_time
.tv_nsec
-1;
3353 /* check if end time selected is below or equal */
3354 if(ltt_time_compare(new_time_window
.start_time
, end_time
) >= 0) {
3355 /* Then, we must push back end time : keep the same time width
3356 * if possible, else end traceset time */
3357 end_time
= LTT_TIME_MIN(time_span
.end_time
,
3358 ltt_time_add(new_time_window
.start_time
,
3359 new_time_window
.time_width
)
3363 /* Fix the time width to fit start time and end time */
3364 new_time_window
.time_width
= ltt_time_sub(end_time
,
3365 new_time_window
.start_time
);
3367 time_change_manager(tab
, new_time_window
);
3372 on_MEntry2_value_changed (GtkSpinButton
*spinbutton
,
3375 Tab
*tab
=(Tab
*)user_data
;
3376 LttvTracesetContext
* tsc
=
3377 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3378 TimeInterval time_span
= tsc
->time_span
;
3379 gint value
= gtk_spin_button_get_value_as_int(spinbutton
);
3381 TimeWindow new_time_window
= tab
->time_window
;
3383 LttTime end_time
= ltt_time_add(new_time_window
.start_time
,
3384 new_time_window
.time_width
);
3386 new_time_window
.start_time
.tv_nsec
= value
;
3388 /* check if end time selected is below or equal */
3389 if(ltt_time_compare(new_time_window
.start_time
, end_time
) >= 0) {
3390 /* Then, we must push back end time : keep the same time width
3391 * if possible, else end traceset time */
3392 end_time
= LTT_TIME_MIN(time_span
.end_time
,
3393 ltt_time_add(new_time_window
.start_time
,
3394 new_time_window
.time_width
)
3398 /* Fix the time width to fit start time and end time */
3399 new_time_window
.time_width
= ltt_time_sub(end_time
,
3400 new_time_window
.start_time
);
3402 time_change_manager(tab
, new_time_window
);
3407 on_MEntry3_value_changed (GtkSpinButton
*spinbutton
,
3410 Tab
*tab
=(Tab
*)user_data
;
3411 LttvTracesetContext
* tsc
=
3412 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3413 TimeInterval time_span
= tsc
->time_span
;
3414 gint value
= gtk_spin_button_get_value_as_int(spinbutton
);
3416 TimeWindow new_time_window
= tab
->time_window
;
3418 LttTime end_time
= ltt_time_add(new_time_window
.start_time
,
3419 new_time_window
.time_width
);
3420 end_time
.tv_sec
= value
;
3422 /* end nanoseconds */
3423 if(end_time
.tv_sec
== time_span
.start_time
.tv_sec
) {
3424 if(end_time
.tv_nsec
< time_span
.start_time
.tv_nsec
)
3425 end_time
.tv_nsec
= time_span
.start_time
.tv_nsec
+1;
3427 else if(end_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3428 if(end_time
.tv_nsec
> time_span
.end_time
.tv_nsec
)
3429 end_time
.tv_nsec
= time_span
.end_time
.tv_nsec
;
3432 /* check if end time selected is below or equal */
3433 if(ltt_time_compare(new_time_window
.start_time
, end_time
) >= 0) {
3434 /* Then, we must push front start time : keep the same time width
3435 * if possible, else end traceset time */
3436 new_time_window
.start_time
= LTT_TIME_MAX(time_span
.start_time
,
3437 ltt_time_sub(end_time
,
3438 new_time_window
.time_width
)
3442 /* Fix the time width to fit start time and end time */
3443 new_time_window
.time_width
= ltt_time_sub(end_time
,
3444 new_time_window
.start_time
);
3446 time_change_manager(tab
, new_time_window
);
3451 on_MEntry4_value_changed (GtkSpinButton
*spinbutton
,
3454 Tab
*tab
=(Tab
*)user_data
;
3455 LttvTracesetContext
* tsc
=
3456 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3457 TimeInterval time_span
= tsc
->time_span
;
3458 gint value
= gtk_spin_button_get_value_as_int(spinbutton
);
3460 TimeWindow new_time_window
= tab
->time_window
;
3462 LttTime end_time
= ltt_time_add(new_time_window
.start_time
,
3463 new_time_window
.time_width
);
3464 end_time
.tv_nsec
= value
;
3466 /* check if end time selected is below or equal */
3467 if(ltt_time_compare(new_time_window
.start_time
, end_time
) >= 0) {
3468 /* Then, we must push front start time : keep the same time width
3469 * if possible, else end traceset time */
3470 new_time_window
.start_time
= LTT_TIME_MAX(time_span
.start_time
,
3471 ltt_time_sub(end_time
,
3472 new_time_window
.time_width
)
3476 /* Fix the time width to fit start time and end time */
3477 new_time_window
.time_width
= ltt_time_sub(end_time
,
3478 new_time_window
.start_time
);
3480 time_change_manager(tab
, new_time_window
);
3485 void current_time_change_manager (Tab
*tab
,
3486 LttTime new_current_time
)
3488 /* Only one source of time change */
3489 if(tab
->current_time_manager_lock
== TRUE
) return;
3491 tab
->current_time_manager_lock
= TRUE
;
3493 LttvTracesetContext
*tsc
= LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3494 TimeInterval time_span
= tsc
->time_span
;
3496 /* current seconds */
3497 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry5
),
3498 (double)time_span
.start_time
.tv_sec
,
3499 (double)time_span
.end_time
.tv_sec
);
3500 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry5
),
3501 (double)new_current_time
.tv_sec
);
3502 /* start nanoseconds */
3503 if(new_current_time
.tv_sec
== time_span
.start_time
.tv_sec
) {
3504 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry6
),
3505 (double)time_span
.start_time
.tv_nsec
,
3506 (double)NANOSECONDS_PER_SECOND
-1);
3508 else if(new_current_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3509 /* If we are at the end, max nsec to end.. */
3510 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry6
),
3512 (double)time_span
.end_time
.tv_nsec
);
3514 else /* anywhere else */
3515 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry6
),
3517 (double)NANOSECONDS_PER_SECOND
-1);
3518 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry6
),
3519 (double)new_current_time
.tv_nsec
);
3521 set_current_time(tab
, &new_current_time
);
3523 tab
->current_time_manager_lock
= FALSE
;
3527 on_MEntry5_value_changed (GtkSpinButton
*spinbutton
,
3530 Tab
*tab
= (Tab
*)user_data
;
3531 LttvTracesetContext
* tsc
=
3532 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3533 TimeInterval time_span
= tsc
->time_span
;
3534 gint value
= gtk_spin_button_get_value_as_int(spinbutton
);
3535 LttTime new_current_time
= tab
->current_time
;
3536 new_current_time
.tv_sec
= value
;
3538 /* current nanoseconds */
3539 if(new_current_time
.tv_sec
== time_span
.start_time
.tv_sec
) {
3540 if(new_current_time
.tv_nsec
< time_span
.start_time
.tv_nsec
)
3541 new_current_time
.tv_nsec
= time_span
.start_time
.tv_nsec
;
3543 else if(new_current_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3544 if(new_current_time
.tv_nsec
> time_span
.end_time
.tv_nsec
)
3545 new_current_time
.tv_nsec
= time_span
.end_time
.tv_nsec
;
3548 current_time_change_manager(tab
, new_current_time
);
3552 on_MEntry6_value_changed (GtkSpinButton
*spinbutton
,
3555 Tab
*tab
= (Tab
*)user_data
;
3556 gint value
= gtk_spin_button_get_value_as_int(spinbutton
);
3557 LttTime new_current_time
= tab
->current_time
;
3558 new_current_time
.tv_nsec
= value
;
3560 current_time_change_manager(tab
, new_current_time
);
3564 void scroll_value_changed_cb(GtkWidget
*scrollbar
,
3567 Tab
*tab
= (Tab
*)user_data
;
3568 TimeWindow new_time_window
;
3570 GtkAdjustment
*adjust
= gtk_range_get_adjustment(GTK_RANGE(scrollbar
));
3571 gdouble value
= gtk_adjustment_get_value(adjust
);
3572 // gdouble upper, lower, ratio, page_size;
3574 LttvTracesetContext
* tsc
=
3575 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3576 TimeInterval time_span
= tsc
->time_span
;
3578 time
= ltt_time_add(ltt_time_from_double(value
/NANOSECONDS_PER_SECOND
),
3579 time_span
.start_time
);
3581 new_time_window
.start_time
= time
;
3583 page_size
= adjust
->page_size
;
3585 new_time_window
.time_width
=
3586 ltt_time_from_double(page_size
/NANOSECONDS_PER_SECOND
);
3589 time_change_manager(tab
, new_time_window
);
3591 //time_window = tab->time_window;
3593 lower
= adjust
->lower
;
3594 upper
= adjust
->upper
;
3595 ratio
= (value
- lower
) / (upper
- lower
);
3596 g_info("lower %lu, upper %lu, value %lu, ratio %lu", lower
, upper
, value
, ratio
);
3598 //time = ltt_time_sub(time_span->end_time, time_span->start_time);
3599 //time = ltt_time_mul(time, (float)ratio);
3600 //time = ltt_time_add(time_span->start_time, time);
3601 time
= ltt_time_add(ltt_time_from_double(value
/NANOSECONDS_PER_SECOND
),
3602 time_span
.start_time
);
3604 time_window
.start_time
= time
;
3606 page_size
= adjust
->page_size
;
3608 time_window
.time_width
=
3609 ltt_time_from_double(page_size
/NANOSECONDS_PER_SECOND
);
3610 //time = ltt_time_sub(time_span.end_time, time);
3611 //if(ltt_time_compare(time,time_window.time_width) < 0){
3612 // time_window.time_width = time;
3615 /* call viewer hooks for new time window */
3616 set_time_window(tab
, &time_window
);
3621 /* callback function to check or uncheck the check box (filter)
3624 void checkbox_changed(GtkTreeView
*treeview
,
3626 GtkTreeViewColumn
*arg2
,
3629 GtkTreeStore
* store
= (GtkTreeStore
*)gtk_tree_view_get_model (treeview
);
3633 if (gtk_tree_model_get_iter ((GtkTreeModel
*)store
, &iter
, arg1
)){
3634 gtk_tree_model_get ((GtkTreeModel
*)store
, &iter
, CHECKBOX_COLUMN
, &value
, -1);
3635 value
= value
? FALSE
: TRUE
;
3636 gtk_tree_store_set (GTK_TREE_STORE (store
), &iter
, CHECKBOX_COLUMN
, value
, -1);
3642 /* According to user's selection, update selector(filter)
3645 void update_filter(LttvTracesetSelector
*s
, GtkTreeStore
*store
)
3647 GtkTreeIter iter
, child_iter
, child_iter1
, child_iter2
;
3648 int i
, j
, k
, nb_eventtype
;
3649 LttvTraceSelector
* trace
;
3650 LttvTracefileSelector
* tracefile
;
3651 LttvEventtypeSelector
* eventtype
;
3652 gboolean value
, value1
, value2
;
3654 if(gtk_tree_model_get_iter_first((GtkTreeModel
*)store
, &iter
)){
3657 trace
= lttv_traceset_selector_trace_get(s
, i
);
3658 nb_eventtype
= lttv_trace_selector_eventtype_number(trace
);
3659 gtk_tree_model_get ((GtkTreeModel
*)store
, &iter
, CHECKBOX_COLUMN
, &value
,-1);
3662 if(gtk_tree_model_iter_children ((GtkTreeModel
*)store
, &child_iter
, &iter
)){
3664 if(j
<1){//eventtype selector for trace
3665 gtk_tree_model_get ((GtkTreeModel
*)store
, &child_iter
, CHECKBOX_COLUMN
, &value2
,-1);
3668 if(gtk_tree_model_iter_children ((GtkTreeModel
*)store
, &child_iter1
, &child_iter
)){
3670 eventtype
= lttv_trace_selector_eventtype_get(trace
,k
);
3671 gtk_tree_model_get ((GtkTreeModel
*)store
, &child_iter1
, CHECKBOX_COLUMN
, &value2
,-1);
3672 lttv_eventtype_selector_set_selected(eventtype
,value2
);
3674 }while(gtk_tree_model_iter_next((GtkTreeModel
*)store
, &child_iter1
));
3677 }else{ //tracefile selector
3678 tracefile
= lttv_trace_selector_tracefile_get(trace
, j
- 1);
3679 gtk_tree_model_get ((GtkTreeModel
*)store
, &child_iter
, CHECKBOX_COLUMN
, &value1
,-1);
3680 lttv_tracefile_selector_set_selected(tracefile
,value1
);
3682 gtk_tree_model_iter_children((GtkTreeModel
*)store
, &child_iter1
, &child_iter
); //eventtype selector
3683 gtk_tree_model_get ((GtkTreeModel
*)store
, &child_iter1
, CHECKBOX_COLUMN
, &value2
,-1);
3686 if(gtk_tree_model_iter_children ((GtkTreeModel
*)store
, &child_iter2
, &child_iter1
)){
3687 do{//eventtype selector for tracefile
3688 eventtype
= lttv_tracefile_selector_eventtype_get(tracefile
,k
);
3689 gtk_tree_model_get ((GtkTreeModel
*)store
, &child_iter2
, CHECKBOX_COLUMN
, &value2
,-1);
3690 lttv_eventtype_selector_set_selected(eventtype
,value2
);
3692 }while(gtk_tree_model_iter_next((GtkTreeModel
*)store
, &child_iter2
));
3698 }while(gtk_tree_model_iter_next((GtkTreeModel
*)store
, &child_iter
));
3701 lttv_trace_selector_set_selected(trace
,value
);
3703 }while(gtk_tree_model_iter_next((GtkTreeModel
*)store
, &iter
));
3708 /* Display a dialogue showing all eventtypes and traces, let user to select the interested
3709 * eventtypes, tracefiles and traces (filter)
3712 gboolean
get_filter_selection(LttvTracesetSelector
*s
,char *title
, char * column_title
)
3714 GtkWidget
* dialogue
;
3715 GtkTreeStore
* store
;
3717 GtkWidget
* scroll_win
;
3718 GtkCellRenderer
* renderer
;
3719 GtkTreeViewColumn
* column
;
3720 GtkTreeIter iter
, child_iter
, child_iter1
, child_iter2
;
3721 int i
, j
, k
, id
, nb_trace
, nb_tracefile
, nb_eventtype
;
3722 LttvTraceSelector
* trace
;
3723 LttvTracefileSelector
* tracefile
;
3724 LttvEventtypeSelector
* eventtype
;
3728 dialogue
= gtk_dialog_new_with_buttons(title
,
3731 GTK_STOCK_OK
,GTK_RESPONSE_ACCEPT
,
3732 GTK_STOCK_CANCEL
,GTK_RESPONSE_REJECT
,
3734 gtk_window_set_default_size((GtkWindow
*)dialogue
, 300, 500);
3736 store
= gtk_tree_store_new (TOTAL_COLUMNS
, G_TYPE_BOOLEAN
, G_TYPE_STRING
);
3737 tree
= gtk_tree_view_new_with_model (GTK_TREE_MODEL (store
));
3738 g_object_unref (G_OBJECT (store
));
3739 g_signal_connect (G_OBJECT (tree
), "row-activated",
3740 G_CALLBACK (checkbox_changed
),
3744 renderer
= gtk_cell_renderer_toggle_new ();
3745 gtk_cell_renderer_toggle_set_radio((GtkCellRendererToggle
*)renderer
, FALSE
);
3747 g_object_set (G_OBJECT (renderer
),"activatable", TRUE
, NULL
);
3749 column
= gtk_tree_view_column_new_with_attributes ("Checkbox",
3751 "active", CHECKBOX_COLUMN
,
3753 gtk_tree_view_column_set_alignment (column
, 0.5);
3754 gtk_tree_view_column_set_fixed_width (column
, 20);
3755 gtk_tree_view_append_column (GTK_TREE_VIEW (tree
), column
);
3757 renderer
= gtk_cell_renderer_text_new ();
3758 column
= gtk_tree_view_column_new_with_attributes (column_title
,
3760 "text", NAME_COLUMN
,
3762 gtk_tree_view_column_set_alignment (column
, 0.0);
3763 gtk_tree_view_append_column (GTK_TREE_VIEW (tree
), column
);
3764 gtk_tree_view_set_headers_visible(GTK_TREE_VIEW (tree
), FALSE
);
3766 scroll_win
= gtk_scrolled_window_new (NULL
, NULL
);
3767 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll_win
),
3768 GTK_POLICY_AUTOMATIC
,GTK_POLICY_AUTOMATIC
);
3769 gtk_container_add (GTK_CONTAINER (scroll_win
), tree
);
3771 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialogue
)->vbox
), scroll_win
,TRUE
, TRUE
,0);
3773 gtk_widget_show(scroll_win
);
3774 gtk_widget_show(tree
);
3776 nb_trace
= lttv_traceset_selector_trace_number(s
);
3777 for(i
=0;i
<nb_trace
;i
++){
3778 trace
= lttv_traceset_selector_trace_get(s
, i
);
3779 name
= lttv_trace_selector_get_name(trace
);
3780 gtk_tree_store_append (store
, &iter
, NULL
);
3781 checked
= lttv_trace_selector_get_selected(trace
);
3782 gtk_tree_store_set (store
, &iter
,
3783 CHECKBOX_COLUMN
,checked
,
3787 gtk_tree_store_append (store
, &child_iter
, &iter
);
3788 gtk_tree_store_set (store
, &child_iter
,
3789 CHECKBOX_COLUMN
, checked
,
3790 NAME_COLUMN
,"eventtype",
3793 nb_eventtype
= lttv_trace_selector_eventtype_number(trace
);
3794 for(j
=0;j
<nb_eventtype
;j
++){
3795 eventtype
= lttv_trace_selector_eventtype_get(trace
,j
);
3796 name
= lttv_eventtype_selector_get_name(eventtype
);
3797 checked
= lttv_eventtype_selector_get_selected(eventtype
);
3798 gtk_tree_store_append (store
, &child_iter1
, &child_iter
);
3799 gtk_tree_store_set (store
, &child_iter1
,
3800 CHECKBOX_COLUMN
, checked
,
3805 nb_tracefile
= lttv_trace_selector_tracefile_number(trace
);
3806 for(j
=0;j
<nb_tracefile
;j
++){
3807 tracefile
= lttv_trace_selector_tracefile_get(trace
, j
);
3808 name
= lttv_tracefile_selector_get_name(tracefile
);
3809 gtk_tree_store_append (store
, &child_iter
, &iter
);
3810 checked
= lttv_tracefile_selector_get_selected(tracefile
);
3811 gtk_tree_store_set (store
, &child_iter
,
3812 CHECKBOX_COLUMN
, checked
,
3816 gtk_tree_store_append (store
, &child_iter1
, &child_iter
);
3817 gtk_tree_store_set (store
, &child_iter1
,
3818 CHECKBOX_COLUMN
, checked
,
3819 NAME_COLUMN
,"eventtype",
3822 for(k
=0;k
<nb_eventtype
;k
++){
3823 eventtype
= lttv_tracefile_selector_eventtype_get(tracefile
,k
);
3824 name
= lttv_eventtype_selector_get_name(eventtype
);
3825 checked
= lttv_eventtype_selector_get_selected(eventtype
);
3826 gtk_tree_store_append (store
, &child_iter2
, &child_iter1
);
3827 gtk_tree_store_set (store
, &child_iter2
,
3828 CHECKBOX_COLUMN
, checked
,
3835 id
= gtk_dialog_run(GTK_DIALOG(dialogue
));
3837 case GTK_RESPONSE_ACCEPT
:
3838 case GTK_RESPONSE_OK
:
3839 update_filter(s
, store
);
3840 gtk_widget_destroy(dialogue
);
3842 case GTK_RESPONSE_REJECT
:
3843 case GTK_RESPONSE_CANCEL
:
3845 gtk_widget_destroy(dialogue
);
3852 /* Select a trace which will be removed from traceset
3855 char * get_remove_trace(char ** all_trace_name
, int nb_trace
)
3857 return get_selection(all_trace_name
, nb_trace
,
3858 "Select a trace", "Trace pathname");
3862 /* Select a module which will be loaded
3865 char * get_load_module(char ** load_module_name
, int nb_module
)
3867 return get_selection(load_module_name
, nb_module
,
3868 "Select a module to load", "Module name");
3874 /* Select a module which will be unloaded
3877 char * get_unload_module(char ** loaded_module_name
, int nb_module
)
3879 return get_selection(loaded_module_name
, nb_module
,
3880 "Select a module to unload", "Module name");
3884 /* Display a dialogue which shows all selectable items, let user to
3885 * select one of them
3888 char * get_selection(char ** loaded_module_name
, int nb_module
,
3889 char *title
, char * column_title
)
3891 GtkWidget
* dialogue
;
3892 GtkWidget
* scroll_win
;
3894 GtkListStore
* store
;
3895 GtkTreeViewColumn
* column
;
3896 GtkCellRenderer
* renderer
;
3897 GtkTreeSelection
* select
;
3900 char * unload_module_name
= NULL
;
3902 dialogue
= gtk_dialog_new_with_buttons(title
,
3905 GTK_STOCK_OK
,GTK_RESPONSE_ACCEPT
,
3906 GTK_STOCK_CANCEL
,GTK_RESPONSE_REJECT
,
3908 gtk_window_set_default_size((GtkWindow
*)dialogue
, 500, 200);
3910 scroll_win
= gtk_scrolled_window_new (NULL
, NULL
);
3911 gtk_widget_show ( scroll_win
);
3912 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll_win
),
3913 GTK_POLICY_AUTOMATIC
, GTK_POLICY_AUTOMATIC
);
3915 store
= gtk_list_store_new (N_COLUMNS
,G_TYPE_STRING
);
3916 tree
= gtk_tree_view_new_with_model(GTK_TREE_MODEL (store
));
3917 gtk_widget_show ( tree
);
3918 g_object_unref (G_OBJECT (store
));
3920 renderer
= gtk_cell_renderer_text_new ();
3921 column
= gtk_tree_view_column_new_with_attributes (column_title
,
3923 "text", MODULE_COLUMN
,
3925 gtk_tree_view_column_set_alignment (column
, 0.5);
3926 gtk_tree_view_column_set_fixed_width (column
, 150);
3927 gtk_tree_view_append_column (GTK_TREE_VIEW (tree
), column
);
3929 select
= gtk_tree_view_get_selection (GTK_TREE_VIEW (tree
));
3930 gtk_tree_selection_set_mode (select
, GTK_SELECTION_SINGLE
);
3932 gtk_container_add (GTK_CONTAINER (scroll_win
), tree
);
3934 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialogue
)->vbox
), scroll_win
,TRUE
, TRUE
,0);
3936 for(i
=0;i
<nb_module
;i
++){
3937 gtk_list_store_append (store
, &iter
);
3938 gtk_list_store_set (store
, &iter
, MODULE_COLUMN
,loaded_module_name
[i
],-1);
3941 id
= gtk_dialog_run(GTK_DIALOG(dialogue
));
3943 case GTK_RESPONSE_ACCEPT
:
3944 case GTK_RESPONSE_OK
:
3945 if (gtk_tree_selection_get_selected (select
, (GtkTreeModel
**)&store
, &iter
)){
3946 gtk_tree_model_get ((GtkTreeModel
*)store
, &iter
, MODULE_COLUMN
, &unload_module_name
, -1);
3948 case GTK_RESPONSE_REJECT
:
3949 case GTK_RESPONSE_CANCEL
:
3951 gtk_widget_destroy(dialogue
);
3955 return unload_module_name
;
3959 /* Insert all menu entry and tool buttons into this main window
3964 void add_all_menu_toolbar_constructors(MainWindow
* mw
, gpointer user_data
)
3968 lttvwindow_viewer_constructor constructor
;
3969 LttvMenus
* global_menu
, * instance_menu
;
3970 LttvToolbars
* global_toolbar
, * instance_toolbar
;
3971 LttvMenuClosure
*menu_item
;
3972 LttvToolbarClosure
*toolbar_item
;
3973 LttvAttributeValue value
;
3974 LttvIAttribute
*global_attributes
= LTTV_IATTRIBUTE(lttv_global_attributes());
3975 LttvIAttribute
*attributes
= mw
->attributes
;
3976 GtkWidget
* tool_menu_title_menu
, *new_widget
, *pixmap
;
3978 g_assert(lttv_iattribute_find_by_path(global_attributes
,
3979 "viewers/menu", LTTV_POINTER
, &value
));
3980 if(*(value
.v_pointer
) == NULL
)
3981 *(value
.v_pointer
) = lttv_menus_new();
3982 global_menu
= (LttvMenus
*)*(value
.v_pointer
);
3984 g_assert(lttv_iattribute_find_by_path(attributes
,
3985 "viewers/menu", LTTV_POINTER
, &value
));
3986 if(*(value
.v_pointer
) == NULL
)
3987 *(value
.v_pointer
) = lttv_menus_new();
3988 instance_menu
= (LttvMenus
*)*(value
.v_pointer
);
3992 g_assert(lttv_iattribute_find_by_path(global_attributes
,
3993 "viewers/toolbar", LTTV_POINTER
, &value
));
3994 if(*(value
.v_pointer
) == NULL
)
3995 *(value
.v_pointer
) = lttv_toolbars_new();
3996 global_toolbar
= (LttvToolbars
*)*(value
.v_pointer
);
3998 g_assert(lttv_iattribute_find_by_path(attributes
,
3999 "viewers/toolbar", LTTV_POINTER
, &value
));
4000 if(*(value
.v_pointer
) == NULL
)
4001 *(value
.v_pointer
) = lttv_toolbars_new();
4002 instance_toolbar
= (LttvToolbars
*)*(value
.v_pointer
);
4004 /* Add missing menu entries to window instance */
4005 for(i
=0;i
<global_menu
->len
;i
++) {
4006 menu_item
= &g_array_index(global_menu
, LttvMenuClosure
, i
);
4008 //add menu_item to window instance;
4009 constructor
= menu_item
->con
;
4010 tool_menu_title_menu
= lookup_widget(mw
->mwindow
,"ToolMenuTitle_menu");
4012 gtk_menu_item_new_with_mnemonic (menu_item
->menu_text
);
4013 gtk_container_add (GTK_CONTAINER (tool_menu_title_menu
),
4015 g_signal_connect ((gpointer
) new_widget
, "activate",
4016 G_CALLBACK (insert_viewer_wrap
),
4018 gtk_widget_show (new_widget
);
4019 lttv_menus_add(instance_menu
, menu_item
->con
,
4020 menu_item
->menu_path
,
4021 menu_item
->menu_text
,
4026 /* Add missing toolbar entries to window instance */
4027 for(i
=0;i
<global_toolbar
->len
;i
++) {
4028 toolbar_item
= &g_array_index(global_toolbar
, LttvToolbarClosure
, i
);
4030 //add toolbar_item to window instance;
4031 constructor
= toolbar_item
->con
;
4032 tool_menu_title_menu
= lookup_widget(mw
->mwindow
,"MToolbar1");
4033 pixbuf
= gdk_pixbuf_new_from_xpm_data((const char**)toolbar_item
->pixmap
);
4034 pixmap
= gtk_image_new_from_pixbuf(pixbuf
);
4036 gtk_toolbar_append_element (GTK_TOOLBAR (tool_menu_title_menu
),
4037 GTK_TOOLBAR_CHILD_BUTTON
,
4040 toolbar_item
->tooltip
, NULL
,
4041 pixmap
, NULL
, NULL
);
4042 gtk_label_set_use_underline(
4043 GTK_LABEL (((GtkToolbarChild
*) (
4044 g_list_last (GTK_TOOLBAR
4045 (tool_menu_title_menu
)->children
)->data
))->label
),
4047 gtk_container_set_border_width (GTK_CONTAINER (new_widget
), 1);
4048 g_signal_connect ((gpointer
) new_widget
,
4050 G_CALLBACK (insert_viewer_wrap
),
4052 gtk_widget_show (new_widget
);
4054 lttv_toolbars_add(instance_toolbar
, toolbar_item
->con
,
4055 toolbar_item
->tooltip
,
4056 toolbar_item
->pixmap
,
4064 /* Create a main window
4067 void construct_main_window(MainWindow
* parent
)
4069 g_debug("construct_main_window()");
4070 GtkWidget
* new_window
; /* New generated main window */
4071 MainWindow
* new_m_window
;/* New main window structure */
4072 GtkNotebook
* notebook
;
4073 LttvIAttribute
*attributes
=
4074 LTTV_IATTRIBUTE(g_object_new(LTTV_ATTRIBUTE_TYPE
, NULL
));
4075 LttvAttributeValue value
;
4078 new_m_window
= g_new(MainWindow
, 1);
4080 // Add the object's information to the module's array
4081 g_main_window_list
= g_slist_append(g_main_window_list
, new_m_window
);
4083 new_window
= create_MWindow();
4084 gtk_widget_show (new_window
);
4086 new_m_window
->mwindow
= new_window
;
4087 new_m_window
->attributes
= attributes
;
4089 g_assert(lttv_iattribute_find_by_path(attributes
,
4090 "viewers/menu", LTTV_POINTER
, &value
));
4091 *(value
.v_pointer
) = lttv_menus_new();
4093 g_assert(lttv_iattribute_find_by_path(attributes
,
4094 "viewers/toolbar", LTTV_POINTER
, &value
));
4095 *(value
.v_pointer
) = lttv_toolbars_new();
4097 add_all_menu_toolbar_constructors(new_m_window
, NULL
);
4099 g_object_set_data_full(G_OBJECT(new_window
),
4101 (gpointer
)new_m_window
,
4102 (GDestroyNotify
)g_free
);
4103 //create a default tab
4104 notebook
= (GtkNotebook
*)lookup_widget(new_m_window
->mwindow
, "MNotebook");
4105 if(notebook
== NULL
){
4106 g_printf("Notebook does not exist\n");
4109 //gtk_notebook_popup_enable (GTK_NOTEBOOK(notebook));
4110 //for now there is no name field in LttvTraceset structure
4111 //Use "Traceset" as the label for the default tab
4113 GtkWidget
* parent_notebook
= lookup_widget(parent
->mwindow
, "MNotebook");
4114 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(parent_notebook
),
4115 gtk_notebook_get_current_page(GTK_NOTEBOOK(parent_notebook
)));
4121 parent_tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
4123 new_tab
= create_tab(new_m_window
, parent_tab
, notebook
, "Traceset");
4125 new_tab
= create_tab(new_m_window
, NULL
, notebook
, "Traceset");
4126 /* First window, use command line trace */
4127 if(g_init_trace
!= NULL
){
4128 lttvwindow_add_trace(new_tab
,
4132 LttvTraceset
*traceset
= new_tab
->traceset_info
->traceset
;
4133 SetTraceset(new_tab
, traceset
);
4136 g_printf("There are now : %d windows\n",g_slist_length(g_main_window_list
));
4140 /* Free the memory occupied by a tab structure
4144 void tab_destructor(Tab
* tab_instance
)
4146 int i
, nb
, ref_count
;
4149 if(tab_instance
->attributes
)
4150 g_object_unref(tab_instance
->attributes
);
4152 if(tab_instance
->interrupted_state
)
4153 g_object_unref(tab_instance
->interrupted_state
);
4156 if(tab_instance
->traceset_info
->traceset_context
!= NULL
){
4157 //remove state update hooks
4158 lttv_state_remove_event_hooks(
4159 (LttvTracesetState
*)tab_instance
->traceset_info
->
4161 lttv_context_fini(LTTV_TRACESET_CONTEXT(tab_instance
->traceset_info
->
4163 g_object_unref(tab_instance
->traceset_info
->traceset_context
);
4165 if(tab_instance
->traceset_info
->traceset
!= NULL
) {
4166 nb
= lttv_traceset_number(tab_instance
->traceset_info
->traceset
);
4167 for(i
= 0 ; i
< nb
; i
++) {
4168 trace
= lttv_traceset_get(tab_instance
->traceset_info
->traceset
, i
);
4169 ref_count
= lttv_trace_get_ref_number(trace
);
4171 ltt_trace_close(lttv_trace(trace
));
4175 lttv_traceset_destroy(tab_instance
->traceset_info
->traceset
);
4176 /* Remove the idle events requests processing function of the tab */
4177 g_idle_remove_by_data(tab_instance
);
4179 g_slist_free(tab_instance
->events_requests
);
4180 g_free(tab_instance
->traceset_info
);
4181 g_free(tab_instance
);
4185 /* Create a tab and insert it into the current main window
4188 Tab
* create_tab(MainWindow
* mw
, Tab
*copy_tab
,
4189 GtkNotebook
* notebook
, char * label
)
4195 //create a new tab data structure
4198 //construct and initialize the traceset_info
4199 tab
->traceset_info
= g_new(TracesetInfo
,1);
4202 tab
->traceset_info
->traceset
=
4203 lttv_traceset_copy(copy_tab
->traceset_info
->traceset
);
4205 tab
->traceset_info
->traceset
= lttv_traceset_new();
4209 lttv_attribute_write_xml(
4210 lttv_traceset_attribute(tab
->traceset_info
->traceset
),
4216 tab
->time_manager_lock
= FALSE
;
4217 tab
->current_time_manager_lock
= FALSE
;
4219 //FIXME copy not implemented in lower level
4220 tab
->traceset_info
->traceset_context
=
4221 g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
4222 g_assert(tab
->traceset_info
->traceset_context
!= NULL
);
4224 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
),
4225 tab
->traceset_info
->traceset
);
4226 //add state update hooks
4227 lttv_state_add_event_hooks(
4228 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
4230 //determine the current_time and time_window of the tab
4232 if(copy_tab
!= NULL
){
4233 tab
->time_window
= copy_tab
->time_window
;
4234 tab
->current_time
= copy_tab
->current_time
;
4236 tab
->time_window
.start_time
=
4237 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
4238 time_span
.start_time
;
4239 if(DEFAULT_TIME_WIDTH_S
<
4240 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
4241 time_span
.end_time
.tv_sec
)
4242 tmp_time
.tv_sec
= DEFAULT_TIME_WIDTH_S
;
4245 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
4246 time_span
.end_time
.tv_sec
;
4247 tmp_time
.tv_nsec
= 0;
4248 tab
->time_window
.time_width
= tmp_time
;
4249 tab
->current_time
.tv_sec
=
4250 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
4251 time_span
.start_time
.tv_sec
;
4252 tab
->current_time
.tv_nsec
=
4253 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
4254 time_span
.start_time
.tv_nsec
;
4257 tab
->attributes
= LTTV_IATTRIBUTE(g_object_new(LTTV_ATTRIBUTE_TYPE
, NULL
));
4258 tab
->interrupted_state
= g_object_new(LTTV_ATTRIBUTE_TYPE
, NULL
);
4260 tab
->vbox
= gtk_vbox_new(FALSE
, 2);
4261 tab
->viewer_container
= gtk_vbox_new(TRUE
, 2);
4262 tab
->scrollbar
= gtk_hscrollbar_new(NULL
);
4263 //tab->multivpaned = gtk_multi_vpaned_new();
4265 gtk_box_pack_start(GTK_BOX(tab
->vbox
),
4266 tab
->viewer_container
,
4268 TRUE
, /* Give the extra space to the child */
4269 0); /* No padding */
4271 /* Create the timebar */
4273 tab
->MTimebar
= gtk_hbox_new(FALSE
, 2);
4274 gtk_widget_show(tab
->MTimebar
);
4276 tab
->MText1
= gtk_label_new("Time Frame start: ");
4277 gtk_widget_show(tab
->MText1
);
4278 tab
->MText2
= gtk_label_new("s");
4279 gtk_widget_show(tab
->MText2
);
4280 tab
->MText3a
= gtk_label_new("ns");
4281 gtk_widget_show(tab
->MText3a
);
4282 tab
->MText3b
= gtk_label_new("end:");
4283 gtk_widget_show(tab
->MText3b
);
4284 tab
->MText4
= gtk_label_new("s");
4285 gtk_widget_show(tab
->MText4
);
4286 tab
->MText5a
= gtk_label_new("ns");
4287 gtk_widget_show(tab
->MText5a
);
4288 tab
->MText5b
= gtk_label_new("Current Time:");
4289 gtk_widget_show(tab
->MText5b
);
4290 tab
->MText6
= gtk_label_new("s");
4291 gtk_widget_show(tab
->MText6
);
4292 tab
->MText7
= gtk_label_new("ns");
4293 gtk_widget_show(tab
->MText7
);
4295 tab
->MEntry1
= gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4296 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab
->MEntry1
),0);
4297 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab
->MEntry1
),TRUE
);
4298 gtk_widget_show(tab
->MEntry1
);
4299 tab
->MEntry2
= gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4300 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab
->MEntry2
),0);
4301 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab
->MEntry2
),TRUE
);
4302 gtk_widget_show(tab
->MEntry2
);
4303 tab
->MEntry3
= gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4304 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab
->MEntry3
),0);
4305 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab
->MEntry3
),TRUE
);
4306 gtk_widget_show(tab
->MEntry3
);
4307 tab
->MEntry4
= gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4308 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab
->MEntry4
),0);
4309 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab
->MEntry4
),TRUE
);
4310 gtk_widget_show(tab
->MEntry4
);
4311 tab
->MEntry5
= gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4312 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab
->MEntry5
),0);
4313 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab
->MEntry5
),TRUE
);
4314 gtk_widget_show(tab
->MEntry5
);
4315 tab
->MEntry6
= gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4316 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab
->MEntry6
),0);
4317 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab
->MEntry6
),TRUE
);
4318 gtk_widget_show(tab
->MEntry6
);
4321 GtkWidget
*temp_widget
;
4323 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MText1
, FALSE
, FALSE
, 0);
4324 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEntry1
, FALSE
, FALSE
, 0);
4325 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MText2
, FALSE
, FALSE
, 0);
4326 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEntry2
, FALSE
, FALSE
, 0);
4327 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MText3a
, FALSE
, FALSE
, 0);
4328 temp_widget
= gtk_vseparator_new();
4329 gtk_widget_show(temp_widget
);
4330 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), temp_widget
, FALSE
, FALSE
, 0);
4331 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MText3b
, FALSE
, FALSE
, 0);
4332 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEntry3
, FALSE
, FALSE
, 0);
4333 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MText4
, FALSE
, FALSE
, 0);
4334 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEntry4
, FALSE
, FALSE
, 0);
4335 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MText5a
, FALSE
, FALSE
, 0);
4336 temp_widget
= gtk_vseparator_new();
4337 gtk_widget_show(temp_widget
);
4338 gtk_box_pack_end (GTK_BOX (tab
->MTimebar
), tab
->MText7
, FALSE
, FALSE
, 0);
4339 gtk_box_pack_end (GTK_BOX (tab
->MTimebar
), tab
->MEntry6
, FALSE
, FALSE
, 0);
4340 gtk_box_pack_end (GTK_BOX (tab
->MTimebar
), tab
->MText6
, FALSE
, FALSE
, 0);
4341 gtk_box_pack_end (GTK_BOX (tab
->MTimebar
), tab
->MEntry5
, FALSE
, FALSE
, 0);
4342 gtk_box_pack_end (GTK_BOX (tab
->MTimebar
), tab
->MText5b
, FALSE
, FALSE
, 0);
4343 gtk_box_pack_end (GTK_BOX (tab
->MTimebar
), temp_widget
, FALSE
, FALSE
, 0);
4346 gtk_box_pack_end(GTK_BOX(tab
->vbox
),
4348 FALSE
, /* Do not expand */
4349 FALSE
, /* Fill has no effect here (expand false) */
4350 0); /* No padding */
4352 gtk_box_pack_end(GTK_BOX(tab
->vbox
),
4354 FALSE
, /* Do not expand */
4355 FALSE
, /* Fill has no effect here (expand false) */
4356 0); /* No padding */
4358 g_object_set_data(G_OBJECT(tab
->viewer_container
), "focused_viewer", NULL
);
4364 // Display a label with a X
4365 GtkWidget *w_hbox = gtk_hbox_new(FALSE, 4);
4366 GtkWidget *w_label = gtk_label_new (label);
4367 GtkWidget *pixmap = create_pixmap(GTK_WIDGET(notebook), "close.png");
4368 GtkWidget *w_button = gtk_button_new ();
4369 gtk_container_add(GTK_CONTAINER(w_button), pixmap);
4370 //GtkWidget *w_button = gtk_button_new_with_label("x");
4372 gtk_button_set_relief(GTK_BUTTON(w_button), GTK_RELIEF_NONE);
4374 gtk_box_pack_start(GTK_BOX(w_hbox), w_label, TRUE, TRUE, 0);
4375 gtk_box_pack_end(GTK_BOX(w_hbox), w_button, FALSE,
4378 g_signal_connect_swapped (w_button, "clicked",
4379 G_CALLBACK (on_close_tab_X_clicked),
4382 gtk_widget_set_state(w_button, GTK_STATE_ACTIVE);
4384 gtk_widget_show (w_label);
4385 gtk_widget_show (pixmap);
4386 gtk_widget_show (w_button);
4387 gtk_widget_show (w_hbox);
4389 tab->label = w_hbox;
4393 tab
->label
= gtk_label_new (label
);
4395 gtk_widget_show(tab
->label
);
4396 gtk_widget_show(tab
->scrollbar
);
4397 gtk_widget_show(tab
->viewer_container
);
4398 gtk_widget_show(tab
->vbox
);
4399 //gtk_widget_show(tab->multivpaned);
4402 /* Start with empty events requests list */
4403 tab
->events_requests
= NULL
;
4404 tab
->events_request_pending
= FALSE
;
4406 g_object_set_data_full(
4407 G_OBJECT(tab
->vbox
),
4410 (GDestroyNotify
)tab_destructor
);
4412 g_signal_connect(G_OBJECT(tab
->scrollbar
), "value-changed",
4413 G_CALLBACK(scroll_value_changed_cb
), tab
);
4415 g_signal_connect ((gpointer
) tab
->MEntry1
, "value-changed",
4416 G_CALLBACK (on_MEntry1_value_changed
),
4418 g_signal_connect ((gpointer
) tab
->MEntry2
, "value-changed",
4419 G_CALLBACK (on_MEntry2_value_changed
),
4421 g_signal_connect ((gpointer
) tab
->MEntry3
, "value-changed",
4422 G_CALLBACK (on_MEntry3_value_changed
),
4424 g_signal_connect ((gpointer
) tab
->MEntry4
, "value-changed",
4425 G_CALLBACK (on_MEntry4_value_changed
),
4427 g_signal_connect ((gpointer
) tab
->MEntry5
, "value-changed",
4428 G_CALLBACK (on_MEntry5_value_changed
),
4430 g_signal_connect ((gpointer
) tab
->MEntry6
, "value-changed",
4431 G_CALLBACK (on_MEntry6_value_changed
),
4434 //g_signal_connect(G_OBJECT(tab->scrollbar), "changed",
4435 // G_CALLBACK(scroll_value_changed_cb), tab);
4438 //insert tab into notebook
4439 gtk_notebook_append_page(notebook
,
4442 list
= gtk_container_get_children(GTK_CONTAINER(notebook
));
4443 gtk_notebook_set_current_page(notebook
,g_list_length(list
)-1);
4444 // always show : not if(g_list_length(list)>1)
4445 gtk_notebook_set_show_tabs(notebook
, TRUE
);
4451 * execute_events_requests
4453 * Idle function that executes the pending requests for a tab.
4455 * @return return value : TRUE : keep the idle function, FALSE : remove it.
4457 gboolean
execute_events_requests(Tab
*tab
)
4459 return ( lttvwindow_process_pending_requests(tab
) );