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
);
491 g_object_set_data(G_OBJECT(container
),
501 gint
viewer_container_position(GtkWidget
*container
, GtkWidget
*child
)
504 if(child
== NULL
) return -1;
507 GValue value
= { 0, };
508 g_value_init(&value
, G_TYPE_INT
);
509 gtk_container_child_get_property(GTK_CONTAINER(container
),
513 pos
= g_value_get_int(&value
);
519 /* move_*_viewer functions move the selected view up/down in
523 void move_down_viewer(GtkWidget
* widget
, gpointer user_data
)
525 MainWindow
* mw
= get_window_data_struct(widget
);
526 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
528 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
529 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
535 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
538 //gtk_multivpaned_widget_move_up(GTK_MULTIVPANED(tab->multivpaned));
540 /* change the position in the vbox */
541 GtkWidget
*focus_widget
;
543 focus_widget
= viewer_container_focus(tab
->viewer_container
);
544 position
= viewer_container_position(tab
->viewer_container
, focus_widget
);
547 /* can move up one position */
548 gtk_box_reorder_child(GTK_BOX(tab
->viewer_container
),
555 void move_up_viewer(GtkWidget
* widget
, gpointer user_data
)
557 MainWindow
* mw
= get_window_data_struct(widget
);
558 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
560 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
561 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
567 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
570 //gtk_multivpaned_widget_move_down(GTK_MULTIVPANED(tab->multivpaned));
571 /* change the position in the vbox */
572 GtkWidget
*focus_widget
;
574 focus_widget
= viewer_container_focus(tab
->viewer_container
);
575 position
= viewer_container_position(tab
->viewer_container
, focus_widget
);
579 g_list_length(gtk_container_get_children(
580 GTK_CONTAINER(tab
->viewer_container
)))-1
582 /* can move down one position */
583 gtk_box_reorder_child(GTK_BOX(tab
->viewer_container
),
591 /* delete_viewer deletes the selected viewer in the current tab
594 void delete_viewer(GtkWidget
* widget
, gpointer user_data
)
596 MainWindow
* mw
= get_window_data_struct(widget
);
597 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
599 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
600 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
606 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
609 //gtk_multivpaned_widget_delete(GTK_MULTIVPANED(tab->multivpaned));
611 GtkWidget
*focus_widget
= viewer_container_focus(tab
->viewer_container
);
613 if(focus_widget
!= NULL
)
614 gtk_widget_destroy(focus_widget
);
616 g_object_set_data(G_OBJECT(tab
->viewer_container
), "focused_viewer", NULL
);
620 /* open_traceset will open a traceset saved in a file
621 * Right now, it is not finished yet, (not working)
625 void open_traceset(GtkWidget
* widget
, gpointer user_data
)
629 LttvTraceset
* traceset
;
630 MainWindow
* mw_data
= get_window_data_struct(widget
);
631 GtkFileSelection
* file_selector
=
632 (GtkFileSelection
*)gtk_file_selection_new("Select a traceset");
634 gtk_file_selection_hide_fileop_buttons(file_selector
);
636 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
638 case GTK_RESPONSE_ACCEPT
:
639 case GTK_RESPONSE_OK
:
640 dir
= gtk_file_selection_get_selections (file_selector
);
641 traceset
= lttv_traceset_load(dir
[0]);
642 g_printf("Open a trace set %s\n", dir
[0]);
645 case GTK_RESPONSE_REJECT
:
646 case GTK_RESPONSE_CANCEL
:
648 gtk_widget_destroy((GtkWidget
*)file_selector
);
654 static void events_request_free(EventsRequest
*events_request
)
656 if(events_request
== NULL
) return;
658 if(events_request
->start_position
!= NULL
)
659 lttv_traceset_context_position_destroy(events_request
->start_position
);
660 if(events_request
->end_position
!= NULL
)
661 lttv_traceset_context_position_destroy(events_request
->end_position
);
662 if(events_request
->before_chunk_traceset
!= NULL
)
663 lttv_hooks_destroy(events_request
->before_chunk_traceset
);
664 if(events_request
->before_chunk_trace
!= NULL
)
665 lttv_hooks_destroy(events_request
->before_chunk_trace
);
666 if(events_request
->before_chunk_tracefile
!= NULL
)
667 lttv_hooks_destroy(events_request
->before_chunk_tracefile
);
668 if(events_request
->event
!= NULL
)
669 lttv_hooks_destroy(events_request
->event
);
670 if(events_request
->event_by_id
!= NULL
)
671 lttv_hooks_by_id_destroy(events_request
->event_by_id
);
672 if(events_request
->after_chunk_tracefile
!= NULL
)
673 lttv_hooks_destroy(events_request
->after_chunk_tracefile
);
674 if(events_request
->after_chunk_trace
!= NULL
)
675 lttv_hooks_destroy(events_request
->after_chunk_trace
);
676 if(events_request
->after_chunk_traceset
!= NULL
)
677 lttv_hooks_destroy(events_request
->after_chunk_traceset
);
678 if(events_request
->before_request
!= NULL
)
679 lttv_hooks_destroy(events_request
->before_request
);
680 if(events_request
->after_request
!= NULL
)
681 lttv_hooks_destroy(events_request
->after_request
);
683 g_free(events_request
);
688 /* lttvwindow_process_pending_requests
690 * This internal function gets called by g_idle, taking care of the pending
691 * requests. It is responsible for concatenation of time intervals and position
692 * requests. It does it with the following algorithm organizing process traceset
693 * calls. Here is the detailed description of the way it works :
695 * - Events Requests Servicing Algorithm
697 * Data structures necessary :
699 * List of requests added to context : list_in
700 * List of requests not added to context : list_out
705 * list_out : many events requests
707 * FIXME : insert rest of algorithm here
711 #define list_out tab->events_requests
713 gboolean
lttvwindow_process_pending_requests(Tab
*tab
)
715 unsigned max_nb_events
;
719 LttvTracesetContext
*tsc
;
720 LttvTracefileContext
*tfc
;
721 GSList
*list_in
= NULL
;
725 LttvTracesetContextPosition
*end_position
;
728 g_critical("Foreground processing : tab does not exist. Processing removed.");
732 /* There is no events requests pending : we should never have been called! */
733 g_assert(g_slist_length(list_out
) != 0);
735 tsc
= LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
737 //set the cursor to be X shape, indicating that the computer is busy in doing its job
739 new = gdk_cursor_new(GDK_X_CURSOR
);
740 widget
= lookup_widget(tab
->mw
->mwindow
, "MToolbar1");
741 win
= gtk_widget_get_parent_window(widget
);
742 gdk_window_set_cursor(win
, new);
743 gdk_cursor_unref(new);
744 gdk_window_stick(win
);
745 gdk_window_unstick(win
);
748 g_debug("SIZE events req len : %d", g_slist_length(list_out
));
750 /* Preliminary check for no trace in traceset */
751 /* Unregister the routine if empty, empty list_out too */
752 if(lttv_traceset_number(tsc
->ts
) == 0) {
754 /* - For each req in list_out */
755 GSList
*iter
= list_out
;
757 while(iter
!= NULL
) {
759 gboolean remove
= FALSE
;
760 gboolean free_data
= FALSE
;
761 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
763 /* - Call end request for req */
764 if(events_request
->servicing
== TRUE
)
765 lttv_hooks_call(events_request
->after_request
, (gpointer
)tsc
);
767 /* - remove req from list_out */
768 /* Destroy the request */
775 GSList
*remove_iter
= iter
;
777 iter
= g_slist_next(iter
);
778 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
779 list_out
= g_slist_remove_link(list_out
, remove_iter
);
780 } else { // not remove
781 iter
= g_slist_next(iter
);
786 /* 0.1 Lock Traces */
791 iter_trace
<lttv_traceset_number(tsc
->ts
);
793 LttvTrace
*trace_v
= lttv_traceset_get(tsc
->ts
, iter_trace
);
795 if(lttvwindowtraces_lock(trace_v
) != 0) {
796 g_critical("Foreground processing : Unable to get trace lock");
797 return TRUE
; /* Cannot get lock, try later */
802 /* 0.2 Seek tracefiles positions to context position */
803 lttv_process_traceset_synchronize_tracefiles(tsc
);
806 /* Events processing algorithm implementation */
807 /* Warning : the gtk_events_pending takes a LOT of cpu time. So what we do
808 * instead is to leave the control to GTK and take it back.
810 /* A. Servicing loop */
811 //while( (g_slist_length(list_in) != 0 || g_slist_length(list_out) != 0)) {
812 if((g_slist_length(list_in
) != 0 || g_slist_length(list_out
) != 0)) {
814 /* 1. If list_in is empty (need a seek) */
815 if( g_slist_length(list_in
) == 0 ) {
817 /* list in is empty, need a seek */
819 /* 1.1 Add requests to list_in */
820 GSList
*ltime
= NULL
;
824 /* 1.1.1 Find all time requests with the lowest start time in list_out
827 if(g_slist_length(list_out
) > 0)
828 ltime
= g_slist_append(ltime
, g_slist_nth_data(list_out
, 0));
829 for(iter
=g_slist_nth(list_out
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
830 /* Find all time requests with the lowest start time in list_out */
831 guint index_ltime
= g_array_index(ltime
, guint
, 0);
832 EventsRequest
*event_request_ltime
= (EventsRequest
*)g_slist_nth_data(ltime
, 0);
833 EventsRequest
*event_request_list_out
= (EventsRequest
*)iter
->data
;
836 comp
= ltt_time_compare(event_request_ltime
->start_time
,
837 event_request_list_out
->start_time
);
839 ltime
= g_slist_append(ltime
, event_request_list_out
);
841 /* Remove all elements from ltime, and add current */
843 ltime
= g_slist_delete_link(ltime
, g_slist_nth(ltime
, 0));
844 ltime
= g_slist_append(ltime
, event_request_list_out
);
848 /* 1.1.2 Find all position requests with the lowest position in list_out
851 if(g_slist_length(list_out
) > 0)
852 lpos
= g_slist_append(lpos
, g_slist_nth_data(list_out
, 0));
853 for(iter
=g_slist_nth(list_out
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
854 /* Find all position requests with the lowest position in list_out */
855 EventsRequest
*event_request_lpos
= (EventsRequest
*)g_slist_nth_data(lpos
, 0);
856 EventsRequest
*event_request_list_out
= (EventsRequest
*)iter
->data
;
859 if(event_request_lpos
->start_position
!= NULL
860 && event_request_list_out
->start_position
!= NULL
)
862 comp
= lttv_traceset_context_pos_pos_compare
863 (event_request_lpos
->start_position
,
864 event_request_list_out
->start_position
);
869 lpos
= g_slist_append(lpos
, event_request_list_out
);
871 /* Remove all elements from lpos, and add current */
873 lpos
= g_slist_delete_link(lpos
, g_slist_nth(lpos
, 0));
874 lpos
= g_slist_append(lpos
, event_request_list_out
);
879 EventsRequest
*event_request_lpos
= (EventsRequest
*)g_slist_nth_data(lpos
, 0);
880 EventsRequest
*event_request_ltime
= (EventsRequest
*)g_slist_nth_data(ltime
, 0);
881 LttTime lpos_start_time
;
883 if(event_request_lpos
!= NULL
884 && event_request_lpos
->start_position
!= NULL
) {
885 lpos_start_time
= lttv_traceset_context_position_get_time(
886 event_request_lpos
->start_position
);
889 /* 1.1.3 If lpos.start time < ltime */
890 if(event_request_lpos
!= NULL
891 && event_request_lpos
->start_position
!= NULL
892 && ltt_time_compare(lpos_start_time
,
893 event_request_ltime
->start_time
)<0) {
894 /* Add lpos to list_in, remove them from list_out */
895 for(iter
=lpos
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
897 EventsRequest
*event_request_lpos
=
898 (EventsRequest
*)iter
->data
;
900 list_in
= g_slist_append(list_in
, event_request_lpos
);
901 /* Remove from list_out */
902 list_out
= g_slist_remove(list_out
, event_request_lpos
);
905 /* 1.1.4 (lpos.start time >= ltime) */
906 /* Add ltime to list_in, remove them from list_out */
908 for(iter
=ltime
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
910 EventsRequest
*event_request_ltime
=
911 (EventsRequest
*)iter
->data
;
913 list_in
= g_slist_append(list_in
, event_request_ltime
);
914 /* Remove from list_out */
915 list_out
= g_slist_remove(list_out
, event_request_ltime
);
925 tfc
= lttv_traceset_context_get_current_tfc(tsc
);
926 g_assert(g_slist_length(list_in
)>0);
927 EventsRequest
*events_request
= g_slist_nth_data(list_in
, 0);
930 /* 1.2.1 If first request in list_in is a time request */
931 if(events_request
->start_position
== NULL
) {
932 /* - If first req in list_in start time != current time */
933 if(tfc
== NULL
|| ltt_time_compare(events_request
->start_time
,
934 tfc
->timestamp
) != 0)
935 /* - Seek to that time */
936 g_debug("SEEK TIME : %lu, %lu", events_request
->start_time
.tv_sec
,
937 events_request
->start_time
.tv_nsec
);
938 //lttv_process_traceset_seek_time(tsc, events_request->start_time);
939 lttv_state_traceset_seek_time_closest(LTTV_TRACESET_STATE(tsc
),
940 events_request
->start_time
);
942 /* Process the traceset with only state hooks */
944 lttv_process_traceset_middle(tsc
,
945 events_request
->start_time
,
951 /* Else, the first request in list_in is a position request */
952 /* If first req in list_in pos != current pos */
953 g_assert(events_request
->start_position
!= NULL
);
954 g_debug("SEEK POS time : %lu, %lu",
955 lttv_traceset_context_position_get_time(
956 events_request
->start_position
).tv_sec
,
957 lttv_traceset_context_position_get_time(
958 events_request
->start_position
).tv_nsec
);
960 g_debug("SEEK POS context time : %lu, %lu",
961 lttv_traceset_context_get_current_tfc(tsc
)->timestamp
.tv_sec
,
962 lttv_traceset_context_get_current_tfc(tsc
)->timestamp
.tv_nsec
);
963 g_assert(events_request
->start_position
!= NULL
);
964 if(lttv_traceset_context_ctx_pos_compare(tsc
,
965 events_request
->start_position
) != 0) {
966 /* 1.2.2.1 Seek to that position */
967 g_debug("SEEK POSITION");
968 //lttv_process_traceset_seek_position(tsc, events_request->start_position);
969 pos_time
= lttv_traceset_context_position_get_time(
970 events_request
->start_position
);
972 lttv_state_traceset_seek_time_closest(LTTV_TRACESET_STATE(tsc
),
975 /* Process the traceset with only state hooks */
977 lttv_process_traceset_middle(tsc
,
980 events_request
->start_position
);
981 g_assert(lttv_traceset_context_ctx_pos_compare(tsc
,
982 events_request
->start_position
) == 0);
989 /* 1.3 Add hooks and call before request for all list_in members */
993 for(iter
=list_in
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
994 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
995 /* 1.3.1 If !servicing */
996 if(events_request
->servicing
== FALSE
) {
997 /* - begin request hooks called
1000 lttv_hooks_call(events_request
->before_request
, (gpointer
)tsc
);
1001 events_request
->servicing
= TRUE
;
1003 /* 1.3.2 call before chunk
1004 * 1.3.3 events hooks added
1006 lttv_process_traceset_begin(tsc
, events_request
->before_chunk_traceset
,
1007 events_request
->before_chunk_trace
,
1008 events_request
->before_chunk_tracefile
,
1009 events_request
->event
,
1010 events_request
->event_by_id
);
1014 /* 2. Else, list_in is not empty, we continue a read */
1017 /* 2.0 For each req of list_in */
1018 GSList
*iter
= list_in
;
1020 while(iter
!= NULL
) {
1022 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1024 /* - Call before chunk
1025 * - events hooks added
1027 lttv_process_traceset_begin(tsc
, events_request
->before_chunk_traceset
,
1028 events_request
->before_chunk_trace
,
1029 events_request
->before_chunk_tracefile
,
1030 events_request
->event
,
1031 events_request
->event_by_id
);
1033 iter
= g_slist_next(iter
);
1038 tfc
= lttv_traceset_context_get_current_tfc(tsc
);
1040 /* 2.1 For each req of list_out */
1041 GSList
*iter
= list_out
;
1043 while(iter
!= NULL
) {
1045 gboolean remove
= FALSE
;
1046 gboolean free_data
= FALSE
;
1047 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1049 /* if req.start time == current context time
1050 * or req.start position == current position*/
1051 if( ltt_time_compare(events_request
->start_time
,
1052 tfc
->timestamp
) == 0
1054 (events_request
->start_position
!= NULL
1056 lttv_traceset_context_ctx_pos_compare(tsc
,
1057 events_request
->start_position
) == 0)
1059 /* - Add to list_in, remove from list_out */
1060 list_in
= g_slist_append(list_in
, events_request
);
1064 /* - If !servicing */
1065 if(events_request
->servicing
== FALSE
) {
1066 /* - begin request hooks called
1067 * - servicing = TRUE
1069 lttv_hooks_call(events_request
->before_request
, (gpointer
)tsc
);
1070 events_request
->servicing
= TRUE
;
1072 /* call before chunk
1073 * events hooks added
1075 lttv_process_traceset_begin(tsc
, events_request
->before_chunk_traceset
,
1076 events_request
->before_chunk_trace
,
1077 events_request
->before_chunk_tracefile
,
1078 events_request
->event
,
1079 events_request
->event_by_id
);
1085 GSList
*remove_iter
= iter
;
1087 iter
= g_slist_next(iter
);
1088 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
1089 list_out
= g_slist_remove_link(list_out
, remove_iter
);
1090 } else { // not remove
1091 iter
= g_slist_next(iter
);
1097 /* 3. Find end criterions */
1102 /* 3.1.1 Find lowest end time in list_in */
1103 g_assert(g_slist_length(list_in
)>0);
1104 end_time
= ((EventsRequest
*)g_slist_nth_data(list_in
,0))->end_time
;
1106 for(iter
=g_slist_nth(list_in
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
1107 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1109 if(ltt_time_compare(events_request
->end_time
,
1111 end_time
= events_request
->end_time
;
1114 /* 3.1.2 Find lowest start time in list_out */
1115 for(iter
=list_out
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
1116 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1118 if(ltt_time_compare(events_request
->start_time
,
1120 end_time
= events_request
->start_time
;
1125 /* 3.2 Number of events */
1127 /* 3.2.1 Find lowest number of events in list_in */
1130 end_nb_events
= ((EventsRequest
*)g_slist_nth_data(list_in
,0))->num_events
;
1132 for(iter
=g_slist_nth(list_in
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
1133 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1135 if(events_request
->num_events
< end_nb_events
)
1136 end_nb_events
= events_request
->num_events
;
1139 /* 3.2.2 Use min(CHUNK_NUM_EVENTS, min num events in list_in) as
1142 end_nb_events
= MIN(CHUNK_NUM_EVENTS
, end_nb_events
);
1146 /* 3.3 End position */
1148 /* 3.3.1 Find lowest end position in list_in */
1151 end_position
=((EventsRequest
*)g_slist_nth_data(list_in
,0))->end_position
;
1153 for(iter
=g_slist_nth(list_in
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
1154 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1156 if(events_request
->end_position
!= NULL
&& end_position
!= NULL
&&
1157 lttv_traceset_context_pos_pos_compare(events_request
->end_position
,
1159 end_position
= events_request
->end_position
;
1164 /* 3.3.2 Find lowest start position in list_out */
1167 for(iter
=list_out
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
1168 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1170 if(events_request
->end_position
!= NULL
&& end_position
!= NULL
&&
1171 lttv_traceset_context_pos_pos_compare(events_request
->end_position
,
1173 end_position
= events_request
->end_position
;
1178 /* 4. Call process traceset middle */
1179 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
);
1180 count
= lttv_process_traceset_middle(tsc
, end_time
, end_nb_events
, end_position
);
1182 tfc
= lttv_traceset_context_get_current_tfc(tsc
);
1184 g_debug("Context time after middle : %lu, %lu", tfc
->timestamp
.tv_sec
,
1185 tfc
->timestamp
.tv_nsec
);
1187 g_debug("End of trace reached after middle.");
1191 /* 5. After process traceset middle */
1192 tfc
= lttv_traceset_context_get_current_tfc(tsc
);
1194 /* - if current context time > traceset.end time */
1195 if(tfc
== NULL
|| ltt_time_compare(tfc
->timestamp
,
1196 tsc
->time_span
.end_time
) > 0) {
1197 /* - For each req in list_in */
1198 GSList
*iter
= list_in
;
1200 while(iter
!= NULL
) {
1202 gboolean remove
= FALSE
;
1203 gboolean free_data
= FALSE
;
1204 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1206 /* - Remove events hooks for req
1207 * - Call end chunk for req
1209 lttv_process_traceset_end(tsc
, events_request
->after_chunk_traceset
,
1210 events_request
->after_chunk_trace
,
1211 events_request
->after_chunk_tracefile
,
1212 events_request
->event
,
1213 events_request
->event_by_id
);
1214 /* - Call end request for req */
1215 lttv_hooks_call(events_request
->after_request
, (gpointer
)tsc
);
1217 /* - remove req from list_in */
1218 /* Destroy the request */
1225 GSList
*remove_iter
= iter
;
1227 iter
= g_slist_next(iter
);
1228 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
1229 list_in
= g_slist_remove_link(list_in
, remove_iter
);
1230 } else { // not remove
1231 iter
= g_slist_next(iter
);
1236 /* 5.1 For each req in list_in */
1237 GSList
*iter
= list_in
;
1239 while(iter
!= NULL
) {
1241 gboolean remove
= FALSE
;
1242 gboolean free_data
= FALSE
;
1243 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1245 /* - Remove events hooks for req
1246 * - Call end chunk for req
1248 lttv_process_traceset_end(tsc
, events_request
->after_chunk_traceset
,
1249 events_request
->after_chunk_trace
,
1250 events_request
->after_chunk_tracefile
,
1251 events_request
->event
,
1252 events_request
->event_by_id
);
1254 /* - req.num -= count */
1255 g_assert(events_request
->num_events
>= count
);
1256 events_request
->num_events
-= count
;
1258 g_assert(tfc
!= NULL
);
1259 /* - if req.num == 0
1261 * current context time >= req.end time
1263 * req.end pos == current pos
1265 * req.stop_flag == TRUE
1267 if( events_request
->num_events
== 0
1269 events_request
->stop_flag
== TRUE
1271 ltt_time_compare(tfc
->timestamp
,
1272 events_request
->end_time
) >= 0
1274 (events_request
->end_position
!= NULL
1276 lttv_traceset_context_ctx_pos_compare(tsc
,
1277 events_request
->end_position
) == 0)
1280 g_assert(events_request
->servicing
== TRUE
);
1281 /* - Call end request for req
1282 * - remove req from list_in */
1283 lttv_hooks_call(events_request
->after_request
, (gpointer
)tsc
);
1284 /* - remove req from list_in */
1285 /* Destroy the request */
1293 GSList
*remove_iter
= iter
;
1295 iter
= g_slist_next(iter
);
1296 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
1297 list_in
= g_slist_remove_link(list_in
, remove_iter
);
1298 } else { // not remove
1299 iter
= g_slist_next(iter
);
1305 /* End of removed servicing loop : leave control to GTK instead. */
1306 // if(gtk_events_pending()) break;
1309 /* B. When interrupted between chunks */
1312 GSList
*iter
= list_in
;
1314 /* 1. for each request in list_in */
1315 while(iter
!= NULL
) {
1317 gboolean remove
= FALSE
;
1318 gboolean free_data
= FALSE
;
1319 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1321 /* 1.1. Use current postition as start position */
1322 if(events_request
->start_position
!= NULL
)
1323 lttv_traceset_context_position_destroy(events_request
->start_position
);
1324 events_request
->start_position
= lttv_traceset_context_position_new();
1325 lttv_traceset_context_position_save(tsc
, events_request
->start_position
);
1327 /* 1.2. Remove start time */
1328 events_request
->start_time
= ltt_time_infinite
;
1330 /* 1.3. Move from list_in to list_out */
1333 list_out
= g_slist_append(list_out
, events_request
);
1338 GSList
*remove_iter
= iter
;
1340 iter
= g_slist_next(iter
);
1341 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
1342 list_in
= g_slist_remove_link(list_in
, remove_iter
);
1343 } else { // not remove
1344 iter
= g_slist_next(iter
);
1351 /* C Unlock Traces */
1353 //lttv_process_traceset_get_sync_data(tsc);
1358 iter_trace
<lttv_traceset_number(tsc
->ts
);
1360 LttvTrace
*trace_v
= lttv_traceset_get(tsc
->ts
, iter_trace
);
1362 lttvwindowtraces_unlock(trace_v
);
1367 //set the cursor back to normal
1368 gdk_window_set_cursor(win
, NULL
);
1371 g_assert(g_slist_length(list_in
) == 0);
1373 if( g_slist_length(list_out
) == 0 ) {
1374 /* Put tab's request pending flag back to normal */
1375 tab
->events_request_pending
= FALSE
;
1376 g_debug("remove the idle fct");
1377 return FALSE
; /* Remove the idle function */
1379 g_debug("leave the idle fct");
1380 return TRUE
; /* Leave the idle function */
1382 /* We do not use simili-round-robin, it may require to read 1 meg buffers
1383 * again and again if many tracesets use the same tracefiles. */
1384 /* Hack for round-robin idle functions */
1385 /* It will put the idle function at the end of the pool */
1386 /*g_idle_add_full((G_PRIORITY_HIGH_IDLE + 21),
1387 (GSourceFunc)execute_events_requests,
1397 /* add_trace_into_traceset_selector, each instance of a viewer has an associated
1398 * selector (filter), when a trace is added into traceset, the selector should
1399 * reflect the change. The function is used to update the selector
1402 void add_trace_into_traceset_selector(GtkWidget
* paned
, LttTrace
* t
)
1404 int j
, k
, m
, nb_tracefile
, nb_control
, nb_per_cpu
, nb_facility
, nb_event
;
1405 LttvTracesetSelector
* s
;
1406 LttvTraceSelector
* trace
;
1407 LttvTracefileSelector
* tracefile
;
1408 LttvEventtypeSelector
* eventtype
;
1414 w
= gtk_multivpaned_get_first_widget(GTK_MULTIVPANED(paned
));
1416 s
= g_object_get_data(G_OBJECT(w
), "Traceset_Selector");
1419 trace
= lttv_trace_selector_new(t
);
1420 lttv_traceset_selector_trace_add(s
, trace
);
1422 nb_facility
= ltt_trace_facility_number(t
);
1423 for(k
=0;k
<nb_facility
;k
++){
1424 fac
= ltt_trace_facility_get(t
,k
);
1425 nb_event
= (int) ltt_facility_eventtype_number(fac
);
1426 for(m
=0;m
<nb_event
;m
++){
1427 et
= ltt_facility_eventtype_get(fac
,m
);
1428 eventtype
= lttv_eventtype_selector_new(et
);
1429 lttv_trace_selector_eventtype_add(trace
, eventtype
);
1433 nb_control
= ltt_trace_control_tracefile_number(t
);
1434 nb_per_cpu
= ltt_trace_per_cpu_tracefile_number(t
);
1435 nb_tracefile
= nb_control
+ nb_per_cpu
;
1437 for(j
= 0 ; j
< nb_tracefile
; j
++) {
1439 tf
= ltt_trace_control_tracefile_get(t
, j
);
1441 tf
= ltt_trace_per_cpu_tracefile_get(t
, j
- nb_control
);
1442 tracefile
= lttv_tracefile_selector_new(tf
);
1443 lttv_trace_selector_tracefile_add(trace
, tracefile
);
1444 lttv_eventtype_selector_copy(trace
, tracefile
);
1446 }else g_warning("Module does not support filtering\n");
1448 w
= gtk_multivpaned_get_next_widget(GTK_MULTIVPANED(paned
));
1453 static void lttvwindow_add_trace(Tab
*tab
, LttvTrace
*trace_v
)
1455 LttvTraceset
*traceset
= tab
->traceset_info
->traceset
;
1457 guint num_traces
= lttv_traceset_number(traceset
);
1459 //Verify if trace is already present.
1460 for(i
=0; i
<num_traces
; i
++)
1462 LttvTrace
* trace
= lttv_traceset_get(traceset
, i
);
1463 if(trace
== trace_v
)
1467 //Keep a reference to the traces so they are not freed.
1468 for(i
=0; i
<lttv_traceset_number(traceset
); i
++)
1470 LttvTrace
* trace
= lttv_traceset_get(traceset
, i
);
1471 lttv_trace_ref(trace
);
1474 //remove state update hooks
1475 lttv_state_remove_event_hooks(
1476 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1478 lttv_context_fini(LTTV_TRACESET_CONTEXT(
1479 tab
->traceset_info
->traceset_context
));
1480 g_object_unref(tab
->traceset_info
->traceset_context
);
1482 lttv_traceset_add(traceset
, trace_v
);
1483 lttv_trace_ref(trace_v
); /* local ref */
1485 /* Create new context */
1486 tab
->traceset_info
->traceset_context
=
1487 g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
1489 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->
1494 //add state update hooks
1495 lttv_state_add_event_hooks(
1496 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1497 //Remove local reference to the traces.
1498 for(i
=0; i
<lttv_traceset_number(traceset
); i
++)
1500 LttvTrace
* trace
= lttv_traceset_get(traceset
, i
);
1501 lttv_trace_unref(trace
);
1505 //add_trace_into_traceset_selector(GTK_MULTIVPANED(tab->multivpaned), lttv_trace(trace_v));
1508 /* add_trace adds a trace into the current traceset. It first displays a
1509 * directory selection dialogue to let user choose a trace, then recreates
1510 * tracset_context, and redraws all the viewer of the current tab
1513 void add_trace(GtkWidget
* widget
, gpointer user_data
)
1516 LttvTrace
* trace_v
;
1517 LttvTraceset
* traceset
;
1519 char abs_path
[PATH_MAX
];
1522 MainWindow
* mw_data
= get_window_data_struct(widget
);
1523 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
1525 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
1526 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
1530 tab
= create_new_tab(widget
, NULL
);
1532 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
1535 GtkDirSelection
* file_selector
= (GtkDirSelection
*)gtk_dir_selection_new("Select a trace");
1536 gtk_dir_selection_hide_fileop_buttons(file_selector
);
1538 if(remember_trace_dir
[0] != '\0')
1539 gtk_dir_selection_set_filename(file_selector
, remember_trace_dir
);
1541 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
1543 case GTK_RESPONSE_ACCEPT
:
1544 case GTK_RESPONSE_OK
:
1545 dir
= gtk_dir_selection_get_dir (file_selector
);
1546 strncpy(remember_trace_dir
, dir
, PATH_MAX
);
1547 if(!dir
|| strlen(dir
) == 0){
1548 gtk_widget_destroy((GtkWidget
*)file_selector
);
1551 get_absolute_pathname(dir
, abs_path
);
1552 trace_v
= lttvwindowtraces_get_trace_by_name(abs_path
);
1553 if(trace_v
== NULL
) {
1554 trace
= ltt_trace_open(abs_path
);
1556 g_warning("cannot open trace %s", abs_path
);
1558 trace_v
= lttv_trace_new(trace
);
1559 lttvwindowtraces_add_trace(trace_v
);
1560 lttvwindow_add_trace(tab
, trace_v
);
1563 lttvwindow_add_trace(tab
, trace_v
);
1566 gtk_widget_destroy((GtkWidget
*)file_selector
);
1568 //update current tab
1569 //update_traceset(mw_data);
1571 /* Call the updatetraceset hooks */
1573 traceset
= tab
->traceset_info
->traceset
;
1574 SetTraceset(tab
, traceset
);
1575 // in expose now call_pending_read_hooks(mw_data);
1577 //lttvwindow_report_current_time(mw_data,&(tab->current_time));
1579 case GTK_RESPONSE_REJECT
:
1580 case GTK_RESPONSE_CANCEL
:
1582 gtk_widget_destroy((GtkWidget
*)file_selector
);
1588 /* remove_trace_into_traceset_selector, each instance of a viewer has an associated
1589 * selector (filter), when a trace is remove from traceset, the selector should
1590 * reflect the change. The function is used to update the selector
1593 void remove_trace_from_traceset_selector(GtkWidget
* paned
, unsigned i
)
1595 LttvTracesetSelector
* s
;
1596 LttvTraceSelector
* t
;
1599 w
= gtk_multivpaned_get_first_widget(GTK_MULTIVPANED(paned
));
1601 s
= g_object_get_data(G_OBJECT(w
), "Traceset_Selector");
1603 t
= lttv_traceset_selector_trace_get(s
,i
);
1604 lttv_traceset_selector_trace_remove(s
, i
);
1605 lttv_trace_selector_destroy(t
);
1606 }g_warning("Module dose not support filtering\n");
1607 w
= gtk_multivpaned_get_next_widget(GTK_MULTIVPANED(paned
));
1612 /* remove_trace removes a trace from the current traceset if all viewers in
1613 * the current tab are not interested in the trace. It first displays a
1614 * dialogue, which shows all traces in the current traceset, to let user choose
1615 * a trace, then it checks if all viewers unselect the trace, if it is true,
1616 * it will remove the trace, recreate the traceset_contex,
1617 * and redraws all the viewer of the current tab. If there is on trace in the
1618 * current traceset, it will delete all viewers of the current tab
1621 // MD : no filter version.
1622 void remove_trace(GtkWidget
*widget
, gpointer user_data
)
1625 LttvTrace
* trace_v
;
1626 LttvTraceset
* traceset
;
1627 gint i
, j
, nb_trace
, index
=-1;
1628 char ** name
, *remove_trace_name
;
1629 MainWindow
* mw_data
= get_window_data_struct(widget
);
1630 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
1632 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
1633 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
1639 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
1642 nb_trace
=lttv_traceset_number(tab
->traceset_info
->traceset
);
1643 name
= g_new(char*,nb_trace
);
1644 for(i
= 0; i
< nb_trace
; i
++){
1645 trace_v
= lttv_traceset_get(tab
->traceset_info
->traceset
, i
);
1646 trace
= lttv_trace(trace_v
);
1647 name
[i
] = ltt_trace_name(trace
);
1650 remove_trace_name
= get_remove_trace(name
, nb_trace
);
1653 if(remove_trace_name
){
1655 /* yuk, cut n paste from old code.. should be better (MD)*/
1656 for(i
= 0; i
<nb_trace
; i
++) {
1657 if(strcmp(remove_trace_name
,name
[i
]) == 0){
1662 traceset
= tab
->traceset_info
->traceset
;
1663 //Keep a reference to the traces so they are not freed.
1664 for(j
=0; j
<lttv_traceset_number(traceset
); j
++)
1666 LttvTrace
* trace
= lttv_traceset_get(traceset
, j
);
1667 lttv_trace_ref(trace
);
1670 //remove state update hooks
1671 lttv_state_remove_event_hooks(
1672 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1673 lttv_context_fini(LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
));
1674 g_object_unref(tab
->traceset_info
->traceset_context
);
1676 trace_v
= lttv_traceset_get(traceset
, index
);
1678 lttv_traceset_remove(traceset
, index
);
1679 lttv_trace_unref(trace_v
); // Remove local reference
1681 if(lttv_trace_get_ref_number(trace_v
) <= 1) {
1682 /* ref 1 : lttvwindowtraces only*/
1683 ltt_trace_close(lttv_trace(trace_v
));
1684 /* lttvwindowtraces_remove_trace takes care of destroying
1685 * the traceset linked with the trace_v and also of destroying
1686 * the trace_v at the same time.
1688 lttvwindowtraces_remove_trace(trace_v
);
1691 tab
->traceset_info
->traceset_context
=
1692 g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
1694 LTTV_TRACESET_CONTEXT(tab
->
1695 traceset_info
->traceset_context
),traceset
);
1696 //add state update hooks
1697 lttv_state_add_event_hooks(
1698 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1700 //Remove local reference to the traces.
1701 for(j
=0; j
<lttv_traceset_number(traceset
); j
++)
1703 LttvTrace
* trace
= lttv_traceset_get(traceset
, j
);
1704 lttv_trace_unref(trace
);
1707 SetTraceset(tab
, (gpointer
)traceset
);
1713 void remove_trace(GtkWidget
* widget
, gpointer user_data
)
1716 LttvTrace
* trace_v
;
1717 LttvTraceset
* traceset
;
1718 gint i
, j
, nb_trace
;
1719 char ** name
, *remove_trace_name
;
1720 MainWindow
* mw_data
= get_window_data_struct(widget
);
1721 LttvTracesetSelector
* s
;
1722 LttvTraceSelector
* t
;
1725 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
1727 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
1728 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
1734 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
1737 nb_trace
=lttv_traceset_number(tab
->traceset_info
->traceset
);
1738 name
= g_new(char*,nb_trace
);
1739 for(i
= 0; i
< nb_trace
; i
++){
1740 trace_v
= lttv_traceset_get(tab
->traceset_info
->traceset
, i
);
1741 trace
= lttv_trace(trace_v
);
1742 name
[i
] = ltt_trace_name(trace
);
1745 remove_trace_name
= get_remove_trace(name
, nb_trace
);
1747 if(remove_trace_name
){
1748 for(i
=0; i
<nb_trace
; i
++){
1749 if(strcmp(remove_trace_name
,name
[i
]) == 0){
1750 //unselect the trace from the current viewer
1752 w
= gtk_multivpaned_get_widget(GTK_MULTIVPANED(tab
->multivpaned
));
1754 s
= g_object_get_data(G_OBJECT(w
), "Traceset_Selector");
1756 t
= lttv_traceset_selector_trace_get(s
,i
);
1757 lttv_trace_selector_set_selected(t
, FALSE
);
1760 //check if other viewers select the trace
1761 w
= gtk_multivpaned_get_first_widget(GTK_MULTIVPANED(tab
->multivpaned
));
1763 s
= g_object_get_data(G_OBJECT(w
), "Traceset_Selector");
1765 t
= lttv_traceset_selector_trace_get(s
,i
);
1766 selected
= lttv_trace_selector_get_selected(t
);
1769 w
= gtk_multivpaned_get_next_widget(GTK_MULTIVPANED(tab
->multivpaned
));
1771 }else selected
= FALSE
;
1773 //if no viewer selects the trace, remove it
1775 remove_trace_from_traceset_selector(GTK_MULTIVPANED(tab
->multivpaned
), i
);
1777 traceset
= tab
->traceset_info
->traceset
;
1778 //Keep a reference to the traces so they are not freed.
1779 for(j
=0; j
<lttv_traceset_number(traceset
); j
++)
1781 LttvTrace
* trace
= lttv_traceset_get(traceset
, j
);
1782 lttv_trace_ref(trace
);
1785 //remove state update hooks
1786 lttv_state_remove_event_hooks(
1787 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1788 lttv_context_fini(LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
));
1789 g_object_unref(tab
->traceset_info
->traceset_context
);
1792 trace_v
= lttv_traceset_get(traceset
, i
);
1794 if(lttv_trace_get_ref_number(trace_v
) <= 2) {
1795 /* ref 2 : traceset, local */
1796 lttvwindowtraces_remove_trace(trace_v
);
1797 ltt_trace_close(lttv_trace(trace_v
));
1800 lttv_traceset_remove(traceset
, i
);
1801 lttv_trace_unref(trace_v
); // Remove local reference
1803 if(!lttv_trace_get_ref_number(trace_v
))
1804 lttv_trace_destroy(trace_v
);
1806 tab
->traceset_info
->traceset_context
=
1807 g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
1809 LTTV_TRACESET_CONTEXT(tab
->
1810 traceset_info
->traceset_context
),traceset
);
1811 //add state update hooks
1812 lttv_state_add_event_hooks(
1813 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1815 //Remove local reference to the traces.
1816 for(j
=0; j
<lttv_traceset_number(traceset
); j
++)
1818 LttvTrace
* trace
= lttv_traceset_get(traceset
, j
);
1819 lttv_trace_unref(trace
);
1823 //update current tab
1824 //update_traceset(mw_data);
1827 SetTraceset(tab
, (gpointer
)traceset
);
1828 // in expose now call_pending_read_hooks(mw_data);
1830 //lttvwindow_report_current_time(mw_data,&(tab->current_time));
1833 // while(tab->multi_vpaned->num_children){
1834 // gtk_multi_vpaned_widget_delete(tab->multi_vpaned);
1848 /* Redraw all the viewers in the current tab */
1849 void redraw(GtkWidget
*widget
, gpointer user_data
)
1851 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
1852 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
1853 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
1858 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
1862 LttvAttributeValue value
;
1864 g_assert(lttv_iattribute_find_by_path(tab
->attributes
, "hooks/redraw", LTTV_POINTER
, &value
));
1866 tmp
= (LttvHooks
*)*(value
.v_pointer
);
1868 lttv_hooks_call(tmp
,NULL
);
1872 void continue_processing(GtkWidget
*widget
, gpointer user_data
)
1874 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
1875 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
1876 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
1881 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
1885 LttvAttributeValue value
;
1887 g_assert(lttv_iattribute_find_by_path(tab
->attributes
,
1888 "hooks/continue", LTTV_POINTER
, &value
));
1890 tmp
= (LttvHooks
*)*(value
.v_pointer
);
1892 lttv_hooks_call(tmp
,NULL
);
1895 /* Stop the processing for the calling main window's current tab.
1896 * It removes every processing requests that are in its list. It does not call
1897 * the end request hooks, because the request is not finished.
1900 void stop_processing(GtkWidget
*widget
, gpointer user_data
)
1902 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
1903 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
1904 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
1909 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
1911 GSList
*iter
= tab
->events_requests
;
1913 while(iter
!= NULL
) {
1914 GSList
*remove_iter
= iter
;
1915 iter
= g_slist_next(iter
);
1917 g_free(remove_iter
->data
);
1918 tab
->events_requests
=
1919 g_slist_remove_link(tab
->events_requests
, remove_iter
);
1921 tab
->events_request_pending
= FALSE
;
1922 g_idle_remove_by_data(tab
);
1923 g_assert(g_slist_length(tab
->events_requests
) == 0);
1927 /* save will save the traceset to a file
1928 * Not implemented yet FIXME
1931 void save(GtkWidget
* widget
, gpointer user_data
)
1936 void save_as(GtkWidget
* widget
, gpointer user_data
)
1938 g_printf("Save as\n");
1942 /* zoom will change the time_window of all the viewers of the
1943 * current tab, and redisplay them. The main functionality is to
1944 * determine the new time_window of the current tab
1947 void zoom(GtkWidget
* widget
, double size
)
1949 TimeInterval time_span
;
1950 TimeWindow new_time_window
;
1951 LttTime current_time
, time_delta
, time_s
, time_e
, time_tmp
;
1952 MainWindow
* mw_data
= get_window_data_struct(widget
);
1953 LttvTracesetContext
*tsc
;
1954 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
1956 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
1957 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
1963 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
1966 if(size
== 1) return;
1968 tsc
= LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
1969 time_span
= tsc
->time_span
;
1970 new_time_window
= tab
->time_window
;
1971 current_time
= tab
->current_time
;
1973 time_delta
= ltt_time_sub(time_span
.end_time
,time_span
.start_time
);
1975 new_time_window
.start_time
= time_span
.start_time
;
1976 new_time_window
.time_width
= time_delta
;
1978 new_time_window
.time_width
= ltt_time_div(new_time_window
.time_width
, size
);
1979 if(ltt_time_compare(new_time_window
.time_width
,time_delta
) > 0)
1980 { /* Case where zoom out is bigger than trace length */
1981 new_time_window
.start_time
= time_span
.start_time
;
1982 new_time_window
.time_width
= time_delta
;
1986 /* Center the image on the current time */
1987 new_time_window
.start_time
=
1988 ltt_time_sub(current_time
, ltt_time_div(new_time_window
.time_width
, 2.0));
1989 /* If on borders, don't fall off */
1990 if(ltt_time_compare(new_time_window
.start_time
, time_span
.start_time
) <0)
1992 new_time_window
.start_time
= time_span
.start_time
;
1996 if(ltt_time_compare(
1997 ltt_time_add(new_time_window
.start_time
, new_time_window
.time_width
),
1998 time_span
.end_time
) > 0)
2000 new_time_window
.start_time
=
2001 ltt_time_sub(time_span
.end_time
, new_time_window
.time_width
);
2007 //time_tmp = ltt_time_div(new_time_window.time_width, 2);
2008 //if(ltt_time_compare(current_time, time_tmp) < 0){
2009 // time_s = time_span->startTime;
2011 // time_s = ltt_time_sub(current_time,time_tmp);
2013 //time_e = ltt_time_add(current_time,time_tmp);
2014 //if(ltt_time_compare(time_span->startTime, time_s) > 0){
2015 // time_s = time_span->startTime;
2016 //}else if(ltt_time_compare(time_span->endTime, time_e) < 0){
2017 // time_e = time_span->endTime;
2018 // time_s = ltt_time_sub(time_e,new_time_window.time_width);
2020 //new_time_window.start_time = time_s;
2023 //lttvwindow_report_time_window(mw_data, &new_time_window);
2024 //call_pending_read_hooks(mw_data);
2026 //lttvwindow_report_current_time(mw_data,&(tab->current_time));
2027 //set_time_window(tab, &new_time_window);
2028 // in expose now call_pending_read_hooks(mw_data);
2029 //gtk_multi_vpaned_set_adjust(tab->multi_vpaned, &new_time_window, FALSE);
2034 ltt_time_sub(new_time_window
.start_time
, time_span
.start_time
);
2035 if( ltt_time_to_double(new_time_window
.time_width
)
2036 * NANOSECONDS_PER_SECOND
2037 / SCROLL_STEP_PER_PAGE
/* step increment */
2039 ltt_time_to_double(rel_time
) * NANOSECONDS_PER_SECOND
/* page size */
2041 ltt_time_to_double(rel_time
) * NANOSECONDS_PER_SECOND
/* page size */
2043 g_warning("Can not zoom that far due to scrollbar precision");
2046 ltt_time_from_double(
2047 ltt_time_to_double(new_time_window
.time_width
)
2048 /SCROLL_STEP_PER_PAGE
),
2051 g_warning("Can not zoom that far due to time nanosecond precision");
2053 time_change_manager(tab
, new_time_window
);
2056 GtkAdjustment
*adjustment
= gtk_range_get_adjustment(GTK_RANGE(tab
->scrollbar
));
2058 g_object_set(G_OBJECT(adjustment
),
2060 //ltt_time_to_double(new_time_window.start_time)
2061 // * NANOSECONDS_PER_SECOND, /* value */
2066 ltt_time_sub(time_span
.end_time
, time_span
.start_time
))
2067 * NANOSECONDS_PER_SECOND
, /* upper */
2069 ltt_time_to_double(new_time_window
.time_width
)
2070 / SCROLL_STEP_PER_PAGE
2071 * NANOSECONDS_PER_SECOND
, /* step increment */
2073 ltt_time_to_double(new_time_window
.time_width
)
2074 * NANOSECONDS_PER_SECOND
, /* page increment */
2076 ltt_time_to_double(new_time_window
.time_width
)
2077 * NANOSECONDS_PER_SECOND
, /* page size */
2079 gtk_adjustment_changed(adjustment
);
2080 //gtk_range_set_adjustment(GTK_RANGE(tab->scrollbar), adjustment);
2081 //gtk_adjustment_value_changed(adjustment);
2082 g_object_set(G_OBJECT(adjustment
),
2085 ltt_time_sub(new_time_window
.start_time
, time_span
.start_time
))
2086 * NANOSECONDS_PER_SECOND
, /* value */
2088 gtk_adjustment_value_changed(adjustment
);
2091 //g_object_set(G_OBJECT(adjustment),
2093 // ltt_time_to_double(time_window->start_time)
2094 // * NANOSECONDS_PER_SECOND, /* value */
2096 /* Note : the set value will call set_time_window if scrollbar value changed
2098 //gtk_adjustment_set_value(adjustment,
2099 // ltt_time_to_double(new_time_window.start_time)
2100 // * NANOSECONDS_PER_SECOND);
2105 void zoom_in(GtkWidget
* widget
, gpointer user_data
)
2110 void zoom_out(GtkWidget
* widget
, gpointer user_data
)
2115 void zoom_extended(GtkWidget
* widget
, gpointer user_data
)
2120 void go_to_time(GtkWidget
* widget
, gpointer user_data
)
2122 g_printf("Go to time\n");
2125 void show_time_frame(GtkWidget
* widget
, gpointer user_data
)
2127 g_printf("Show time frame\n");
2131 /* callback function */
2134 on_empty_traceset_activate (GtkMenuItem
*menuitem
,
2137 create_new_window((GtkWidget
*)menuitem
, user_data
, FALSE
);
2142 on_clone_traceset_activate (GtkMenuItem
*menuitem
,
2145 create_new_window((GtkWidget
*)menuitem
, user_data
, TRUE
);
2149 /* create_new_tab calls create_tab to construct a new tab in the main window
2152 Tab
*create_new_tab(GtkWidget
* widget
, gpointer user_data
){
2153 gchar label
[PATH_MAX
];
2154 MainWindow
* mw_data
= get_window_data_struct(widget
);
2156 GtkNotebook
* notebook
= (GtkNotebook
*)lookup_widget(widget
, "MNotebook");
2157 if(notebook
== NULL
){
2158 g_printf("Notebook does not exist\n");
2161 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2162 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2168 copy_tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
2171 strcpy(label
,"Page");
2172 if(get_label(mw_data
, label
,"Get the name of the tab","Please input tab's name"))
2173 return (create_tab (mw_data
, copy_tab
, notebook
, label
));
2177 on_tab_activate (GtkMenuItem
*menuitem
,
2180 create_new_tab((GtkWidget
*)menuitem
, user_data
);
2185 on_open_activate (GtkMenuItem
*menuitem
,
2188 open_traceset((GtkWidget
*)menuitem
, user_data
);
2193 on_close_activate (GtkMenuItem
*menuitem
,
2196 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2197 main_window_destructor(mw_data
);
2201 /* remove the current tab from the main window
2205 on_close_tab_activate (GtkWidget
*widget
,
2209 GtkWidget
* notebook
;
2211 MainWindow
* mw_data
= get_window_data_struct(widget
);
2212 notebook
= lookup_widget(widget
, "MNotebook");
2213 if(notebook
== NULL
){
2214 g_printf("Notebook does not exist\n");
2218 page_num
= gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
));
2220 gtk_notebook_remove_page(GTK_NOTEBOOK(notebook
), page_num
);
2225 on_close_tab_X_clicked (GtkWidget
*widget
,
2229 GtkWidget
*notebook
= lookup_widget(widget
, "MNotebook");
2230 if(notebook
== NULL
){
2231 g_printf("Notebook does not exist\n");
2235 if((page_num
= gtk_notebook_page_num(GTK_NOTEBOOK(notebook
), widget
)) != -1)
2236 gtk_notebook_remove_page(GTK_NOTEBOOK(notebook
), page_num
);
2242 on_add_trace_activate (GtkMenuItem
*menuitem
,
2245 add_trace((GtkWidget
*)menuitem
, user_data
);
2250 on_remove_trace_activate (GtkMenuItem
*menuitem
,
2253 remove_trace((GtkWidget
*)menuitem
, user_data
);
2258 on_save_activate (GtkMenuItem
*menuitem
,
2261 save((GtkWidget
*)menuitem
, user_data
);
2266 on_save_as_activate (GtkMenuItem
*menuitem
,
2269 save_as((GtkWidget
*)menuitem
, user_data
);
2274 on_quit_activate (GtkMenuItem
*menuitem
,
2282 on_cut_activate (GtkMenuItem
*menuitem
,
2290 on_copy_activate (GtkMenuItem
*menuitem
,
2293 g_printf("Copye\n");
2298 on_paste_activate (GtkMenuItem
*menuitem
,
2301 g_printf("Paste\n");
2306 on_delete_activate (GtkMenuItem
*menuitem
,
2309 g_printf("Delete\n");
2314 on_zoom_in_activate (GtkMenuItem
*menuitem
,
2317 zoom_in((GtkWidget
*)menuitem
, user_data
);
2322 on_zoom_out_activate (GtkMenuItem
*menuitem
,
2325 zoom_out((GtkWidget
*)menuitem
, user_data
);
2330 on_zoom_extended_activate (GtkMenuItem
*menuitem
,
2333 zoom_extended((GtkWidget
*)menuitem
, user_data
);
2338 on_go_to_time_activate (GtkMenuItem
*menuitem
,
2341 go_to_time((GtkWidget
*)menuitem
, user_data
);
2346 on_show_time_frame_activate (GtkMenuItem
*menuitem
,
2349 show_time_frame((GtkWidget
*)menuitem
, user_data
);
2354 on_move_viewer_up_activate (GtkMenuItem
*menuitem
,
2357 move_up_viewer((GtkWidget
*)menuitem
, user_data
);
2362 on_move_viewer_down_activate (GtkMenuItem
*menuitem
,
2365 move_down_viewer((GtkWidget
*)menuitem
, user_data
);
2370 on_remove_viewer_activate (GtkMenuItem
*menuitem
,
2373 delete_viewer((GtkWidget
*)menuitem
, user_data
);
2378 on_trace_filter_activate (GtkMenuItem
*menuitem
,
2381 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2382 LttvTracesetSelector
* s
;
2384 GtkWidget
* notebook
= lookup_widget(GTK_WIDGET(menuitem
), "MNotebook");
2386 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2387 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2393 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
2396 w
= gtk_multivpaned_get_widget(GTK_MULTIVPANED(tab
->multivpaned
));
2398 s
= g_object_get_data(G_OBJECT(w
), "Traceset_Selector");
2400 g_printf("There is no viewer yet\n");
2403 if(get_filter_selection(s
, "Configure trace and tracefile filter", "Select traces and tracefiles")){
2404 //FIXME report filter change
2405 //update_traceset(mw_data);
2406 //call_pending_read_hooks(mw_data);
2407 //lttvwindow_report_current_time(mw_data,&(tab->current_time));
2413 on_trace_facility_activate (GtkMenuItem
*menuitem
,
2416 g_printf("Trace facility selector: %s\n");
2420 /* Dispaly a file selection dialogue to let user select a library, then call
2421 * lttv_library_load().
2425 on_load_library_activate (GtkMenuItem
*menuitem
,
2428 GError
*error
= NULL
;
2429 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2431 gchar load_module_path_alter
[PATH_MAX
];
2435 gchar
*load_module_path
;
2436 name
= g_ptr_array_new();
2437 nb
= lttv_library_path_number();
2438 /* ask for the library path */
2442 path
= lttv_library_path_get(i
);
2443 g_ptr_array_add(name
, path
);
2446 load_module_path
= get_selection((char **)(name
->pdata
), name
->len
,
2447 "Select a library path", "Library paths");
2448 if(load_module_path
!= NULL
)
2449 strncpy(load_module_path_alter
, load_module_path
, PATH_MAX
-1); // -1 for /
2451 g_ptr_array_free(name
, TRUE
);
2453 if(load_module_path
== NULL
) return;
2457 /* Make sure the module path ends with a / */
2458 gchar
*ptr
= load_module_path_alter
;
2460 ptr
= strchr(ptr
, '\0');
2462 if(*(ptr
-1) != '/') {
2469 /* Ask for the library to load : list files in the previously selected
2471 gchar str
[PATH_MAX
];
2474 GtkFileSelection
* file_selector
=
2475 (GtkFileSelection
*)gtk_file_selection_new("Select a module");
2476 gtk_file_selection_set_filename(file_selector
, load_module_path_alter
);
2477 gtk_file_selection_hide_fileop_buttons(file_selector
);
2480 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
2482 case GTK_RESPONSE_ACCEPT
:
2483 case GTK_RESPONSE_OK
:
2484 dir
= gtk_file_selection_get_selections (file_selector
);
2485 strncpy(str
,dir
[0],PATH_MAX
);
2486 strncpy(remember_plugins_dir
,dir
[0],PATH_MAX
);
2487 /* only keep file name */
2489 str1
= strrchr(str
,'/');
2492 str1
= strrchr(str
,'\\');
2497 if(*str1
== 'l' && *(str1
+1)== 'i' && *(str1
+2)=='b')
2499 remove info after
. */
2503 str2
= strrchr(str2
, '.');
2504 if(str2
!= NULL
) *str2
= '\0';
2506 lttv_module_require(str1
, &error
);
2508 lttv_library_load(str1
, &error
);
2509 if(error
!= NULL
) g_warning(error
->message
);
2510 else g_printf("Load library: %s\n", str
);
2512 case GTK_RESPONSE_REJECT
:
2513 case GTK_RESPONSE_CANCEL
:
2515 gtk_widget_destroy((GtkWidget
*)file_selector
);
2526 /* Display all loaded modules, let user to select a module to unload
2527 * by calling lttv_module_unload
2531 on_unload_library_activate (GtkMenuItem
*menuitem
,
2534 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2536 LttvLibrary
*library
;
2541 name
= g_ptr_array_new();
2542 nb
= lttv_library_number();
2543 LttvLibraryInfo
*lib_info
= g_new(LttvLibraryInfo
,nb
);
2544 /* ask for the library name */
2547 LttvLibrary
*iter_lib
= lttv_library_get(i
);
2548 lttv_library_info(iter_lib
, &lib_info
[i
]);
2550 gchar
*path
= lib_info
[i
].name
;
2551 g_ptr_array_add(name
, lib_info
[i
].name
);
2553 lib_name
= get_selection((char **)(name
->pdata
), name
->len
,
2554 "Select a library", "Libraries");
2555 if(lib_name
!= NULL
) {
2557 if(strcmp(lib_name
, lib_info
[i
].name
) == 0) {
2558 library
= lttv_library_get(i
);
2563 g_ptr_array_free(name
, TRUE
);
2566 if(lib_name
== NULL
) return;
2569 lttv_library_unload(library
);
2573 /* Dispaly a file selection dialogue to let user select a module, then call
2574 * lttv_module_require().
2578 on_load_module_activate (GtkMenuItem
*menuitem
,
2581 GError
*error
= NULL
;
2582 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2584 LttvLibrary
*library
;
2589 name
= g_ptr_array_new();
2590 nb
= lttv_library_number();
2591 LttvLibraryInfo
*lib_info
= g_new(LttvLibraryInfo
,nb
);
2592 /* ask for the library name */
2595 LttvLibrary
*iter_lib
= lttv_library_get(i
);
2596 lttv_library_info(iter_lib
, &lib_info
[i
]);
2598 gchar
*path
= lib_info
[i
].name
;
2599 g_ptr_array_add(name
, path
);
2601 lib_name
= get_selection((char **)(name
->pdata
), name
->len
,
2602 "Select a library", "Libraries");
2603 if(lib_name
!= NULL
) {
2605 if(strcmp(lib_name
, lib_info
[i
].name
) == 0) {
2606 library
= lttv_library_get(i
);
2611 g_ptr_array_free(name
, TRUE
);
2614 if(lib_name
== NULL
) return;
2617 //LttvModule *module;
2618 gchar module_name_out
[PATH_MAX
];
2620 /* Ask for the module to load : list modules in the selected lib */
2624 LttvModuleInfo
*module_info
= g_new(LttvModuleInfo
,nb
);
2625 name
= g_ptr_array_new();
2626 nb
= lttv_library_module_number(library
);
2627 /* ask for the module name */
2630 LttvModule
*iter_module
= lttv_library_module_get(library
, i
);
2631 lttv_module_info(iter_module
, &module_info
[i
]);
2633 gchar
*path
= module_info
[i
].name
;
2634 g_ptr_array_add(name
, path
);
2636 module_name
= get_selection((char **)(name
->pdata
), name
->len
,
2637 "Select a module", "Modules");
2638 if(module_name
!= NULL
) {
2640 if(strcmp(module_name
, module_info
[i
].name
) == 0) {
2641 strncpy(module_name_out
, module_name
, PATH_MAX
);
2642 //module = lttv_library_module_get(i);
2648 g_ptr_array_free(name
, TRUE
);
2649 g_free(module_info
);
2651 if(module_name
== NULL
) return;
2654 lttv_module_require(module_name_out
, &error
);
2655 if(error
!= NULL
) g_warning(error
->message
);
2656 else g_printf("Load module: %s\n", module_name_out
);
2663 gchar str
[PATH_MAX
];
2666 GtkFileSelection
* file_selector
=
2667 (GtkFileSelection
*)gtk_file_selection_new("Select a module");
2668 gtk_file_selection_set_filename(file_selector
, load_module_path_alter
);
2669 gtk_file_selection_hide_fileop_buttons(file_selector
);
2672 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
2674 case GTK_RESPONSE_ACCEPT
:
2675 case GTK_RESPONSE_OK
:
2676 dir
= gtk_file_selection_get_selections (file_selector
);
2677 strncpy(str
,dir
[0],PATH_MAX
);
2678 strncpy(remember_plugins_dir
,dir
[0],PATH_MAX
);
2680 /* only keep file name */
2682 str1
= strrchr(str
,'/');
2685 str1
= strrchr(str
,'\\');
2690 if(*str1
== 'l' && *(str1
+1)== 'i' && *(str1
+2)=='b')
2692 remove info after
. */
2696 str2
= strrchr(str2
, '.');
2697 if(str2
!= NULL
) *str2
= '\0';
2699 lttv_module_require(str1
, &error
);
2701 lttv_library_load(str1
, &error
);
2702 if(error
!= NULL
) g_warning(error
->message
);
2703 else g_printf("Load library: %s\n", str
);
2705 case GTK_RESPONSE_REJECT
:
2706 case GTK_RESPONSE_CANCEL
:
2708 gtk_widget_destroy((GtkWidget
*)file_selector
);
2720 /* Display all loaded modules, let user to select a module to unload
2721 * by calling lttv_module_unload
2725 on_unload_module_activate (GtkMenuItem
*menuitem
,
2728 GError
*error
= NULL
;
2729 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2731 LttvLibrary
*library
;
2736 name
= g_ptr_array_new();
2737 nb
= lttv_library_number();
2738 LttvLibraryInfo
*lib_info
= g_new(LttvLibraryInfo
,nb
);
2739 /* ask for the library name */
2742 LttvLibrary
*iter_lib
= lttv_library_get(i
);
2743 lttv_library_info(iter_lib
, &lib_info
[i
]);
2745 gchar
*path
= lib_info
[i
].name
;
2746 g_ptr_array_add(name
, path
);
2748 lib_name
= get_selection((char **)(name
->pdata
), name
->len
,
2749 "Select a library", "Libraries");
2750 if(lib_name
!= NULL
) {
2752 if(strcmp(lib_name
, lib_info
[i
].name
) == 0) {
2753 library
= lttv_library_get(i
);
2758 g_ptr_array_free(name
, TRUE
);
2761 if(lib_name
== NULL
) return;
2766 /* Ask for the module to load : list modules in the selected lib */
2770 nb
= lttv_library_module_number(library
);
2771 LttvModuleInfo
*module_info
= g_new(LttvModuleInfo
,nb
);
2772 name
= g_ptr_array_new();
2773 /* ask for the module name */
2776 LttvModule
*iter_module
= lttv_library_module_get(library
, i
);
2777 lttv_module_info(iter_module
, &module_info
[i
]);
2779 gchar
*path
= module_info
[i
].name
;
2780 if(module_info
[i
].use_count
> 0) g_ptr_array_add(name
, path
);
2782 module_name
= get_selection((char **)(name
->pdata
), name
->len
,
2783 "Select a module", "Modules");
2784 if(module_name
!= NULL
) {
2786 if(strcmp(module_name
, module_info
[i
].name
) == 0) {
2787 module
= lttv_library_module_get(library
, i
);
2793 g_ptr_array_free(name
, TRUE
);
2794 g_free(module_info
);
2796 if(module_name
== NULL
) return;
2799 LttvModuleInfo module_info
;
2800 lttv_module_info(module
, &module_info
);
2801 g_printf("Release module: %s\n", module_info
.name
);
2803 lttv_module_release(module
);
2807 /* Display a directory dialogue to let user select a path for library searching
2811 on_add_library_search_path_activate (GtkMenuItem
*menuitem
,
2814 GtkDirSelection
* file_selector
= (GtkDirSelection
*)gtk_dir_selection_new("Select library path");
2818 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2819 if(remember_plugins_dir
[0] != '\0')
2820 gtk_dir_selection_set_filename(file_selector
, remember_plugins_dir
);
2822 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
2824 case GTK_RESPONSE_ACCEPT
:
2825 case GTK_RESPONSE_OK
:
2826 dir
= gtk_dir_selection_get_dir (file_selector
);
2827 strncpy(remember_plugins_dir
,dir
,PATH_MAX
);
2828 strncat(remember_plugins_dir
,"/",PATH_MAX
);
2829 lttv_library_path_add(dir
);
2830 case GTK_RESPONSE_REJECT
:
2831 case GTK_RESPONSE_CANCEL
:
2833 gtk_widget_destroy((GtkWidget
*)file_selector
);
2839 /* Display a directory dialogue to let user select a path for library searching
2843 on_remove_library_search_path_activate (GtkMenuItem
*menuitem
,
2846 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2848 const char *lib_path
;
2853 name
= g_ptr_array_new();
2854 nb
= lttv_library_path_number();
2855 /* ask for the library name */
2858 gchar
*path
= lttv_library_path_get(i
);
2859 g_ptr_array_add(name
, path
);
2861 lib_path
= get_selection((char **)(name
->pdata
), name
->len
,
2862 "Select a library path", "Library paths");
2864 g_ptr_array_free(name
, TRUE
);
2866 if(lib_path
== NULL
) return;
2869 lttv_library_path_remove(lib_path
);
2873 on_color_activate (GtkMenuItem
*menuitem
,
2876 g_printf("Color\n");
2881 on_filter_activate (GtkMenuItem
*menuitem
,
2884 g_printf("Filter\n");
2889 on_save_configuration_activate (GtkMenuItem
*menuitem
,
2892 g_printf("Save configuration\n");
2897 on_content_activate (GtkMenuItem
*menuitem
,
2900 g_printf("Content\n");
2905 on_about_close_activate (GtkButton
*button
,
2908 GtkWidget
*about_widget
= GTK_WIDGET(user_data
);
2910 gtk_widget_destroy(about_widget
);
2914 on_about_activate (GtkMenuItem
*menuitem
,
2917 MainWindow
*main_window
= get_window_data_struct(GTK_WIDGET(menuitem
));
2918 GtkWidget
*window_widget
= main_window
->mwindow
;
2919 GtkWidget
*about_widget
= gtk_window_new(GTK_WINDOW_TOPLEVEL
);
2920 GtkWindow
*about_window
= GTK_WINDOW(about_widget
);
2921 gint window_width
, window_height
;
2923 gtk_window_set_title(about_window
, "About Linux Trace Toolkit");
2925 gtk_window_set_resizable(about_window
, FALSE
);
2926 gtk_window_set_transient_for(GTK_WINDOW(window_widget
), about_window
);
2927 gtk_window_set_destroy_with_parent(about_window
, TRUE
);
2928 gtk_window_set_modal(about_window
, FALSE
);
2930 /* Put the about window at the center of the screen */
2931 gtk_window_get_size(about_window
, &window_width
, &window_height
);
2932 gtk_window_move (about_window
,
2933 (gdk_screen_width() - window_width
)/2,
2934 (gdk_screen_height() - window_height
)/2);
2936 GtkWidget
*vbox
= gtk_vbox_new(FALSE
, 1);
2938 gtk_container_add(GTK_CONTAINER(about_widget
), vbox
);
2942 GtkWidget
*label1
= gtk_label_new("");
2943 gtk_misc_set_padding(GTK_MISC(label1
), 10, 20);
2944 gtk_label_set_markup(GTK_LABEL(label1
), "\
2945 <big>Linux Trace Toolkit</big>");
2946 gtk_label_set_justify(GTK_LABEL(label1
), GTK_JUSTIFY_CENTER
);
2948 GtkWidget
*label2
= gtk_label_new("");
2949 gtk_misc_set_padding(GTK_MISC(label2
), 10, 20);
2950 gtk_label_set_markup(GTK_LABEL(label2
), "\
2951 Project author: Karim Yaghmour\n\
2955 Michel Dagenais (New trace format, lttv main)\n\
2956 Mathieu Desnoyers (Directory structure, build with automake/conf,\n\
2957 lttv gui, control flow view, gui green threads\n\
2958 with interruptible foreground and background computation,\n\
2959 detailed event list)\n\
2960 Benoit Des Ligneris (Cluster adaptation)\n\
2961 Xang-Xiu Yang (new trace reading library and converter, lttv gui, \n\
2962 detailed event list and statistics view)\n\
2963 Tom Zanussi (RelayFS)");
2965 GtkWidget
*label3
= gtk_label_new("");
2966 gtk_label_set_markup(GTK_LABEL(label3
), "\
2967 Linux Trace Toolkit, Copyright (C) 2004 Karim Yaghmour\n\
2968 Linux Trace Toolkit comes with ABSOLUTELY NO WARRANTY.\n\
2969 This is free software, and you are welcome to redistribute it\n\
2970 under certain conditions. See COPYING for details.");
2971 gtk_misc_set_padding(GTK_MISC(label3
), 10, 20);
2973 gtk_box_pack_start_defaults(GTK_BOX(vbox
), label1
);
2974 gtk_box_pack_start_defaults(GTK_BOX(vbox
), label2
);
2975 gtk_box_pack_start_defaults(GTK_BOX(vbox
), label3
);
2977 GtkWidget
*hbox
= gtk_hbox_new(TRUE
, 0);
2978 gtk_box_pack_end(GTK_BOX(vbox
), hbox
, FALSE
, FALSE
, 0);
2979 GtkWidget
*close_button
= gtk_button_new_with_mnemonic("_Close");
2980 gtk_box_pack_end(GTK_BOX(hbox
), close_button
, FALSE
, FALSE
, 0);
2981 gtk_container_set_border_width(GTK_CONTAINER(close_button
), 20);
2983 g_signal_connect(G_OBJECT(close_button
), "clicked",
2984 G_CALLBACK(on_about_close_activate
),
2985 (gpointer
)about_widget
);
2987 gtk_widget_show_all(about_widget
);
2992 on_button_new_clicked (GtkButton
*button
,
2995 create_new_window((GtkWidget
*)button
, user_data
, TRUE
);
2999 on_button_new_tab_clicked (GtkButton
*button
,
3002 create_new_tab((GtkWidget
*)button
, user_data
);
3006 on_button_open_clicked (GtkButton
*button
,
3009 open_traceset((GtkWidget
*)button
, user_data
);
3014 on_button_add_trace_clicked (GtkButton
*button
,
3017 add_trace((GtkWidget
*)button
, user_data
);
3022 on_button_remove_trace_clicked (GtkButton
*button
,
3025 remove_trace((GtkWidget
*)button
, user_data
);
3029 on_button_redraw_clicked (GtkButton
*button
,
3032 redraw((GtkWidget
*)button
, user_data
);
3036 on_button_continue_processing_clicked (GtkButton
*button
,
3039 continue_processing((GtkWidget
*)button
, user_data
);
3043 on_button_stop_processing_clicked (GtkButton
*button
,
3046 stop_processing((GtkWidget
*)button
, user_data
);
3052 on_button_save_clicked (GtkButton
*button
,
3055 save((GtkWidget
*)button
, user_data
);
3060 on_button_save_as_clicked (GtkButton
*button
,
3063 save_as((GtkWidget
*)button
, user_data
);
3068 on_button_zoom_in_clicked (GtkButton
*button
,
3071 zoom_in((GtkWidget
*)button
, user_data
);
3076 on_button_zoom_out_clicked (GtkButton
*button
,
3079 zoom_out((GtkWidget
*)button
, user_data
);
3084 on_button_zoom_extended_clicked (GtkButton
*button
,
3087 zoom_extended((GtkWidget
*)button
, user_data
);
3092 on_button_go_to_time_clicked (GtkButton
*button
,
3095 go_to_time((GtkWidget
*)button
, user_data
);
3100 on_button_show_time_frame_clicked (GtkButton
*button
,
3103 show_time_frame((GtkWidget
*)button
, user_data
);
3108 on_button_move_up_clicked (GtkButton
*button
,
3111 move_up_viewer((GtkWidget
*)button
, user_data
);
3116 on_button_move_down_clicked (GtkButton
*button
,
3119 move_down_viewer((GtkWidget
*)button
, user_data
);
3124 on_button_delete_viewer_clicked (GtkButton
*button
,
3127 delete_viewer((GtkWidget
*)button
, user_data
);
3131 on_MWindow_destroy (GtkWidget
*widget
,
3134 MainWindow
*main_window
= get_window_data_struct(widget
);
3135 LttvIAttribute
*attributes
= main_window
->attributes
;
3136 LttvAttributeValue value
;
3138 //This is unnecessary, since widgets will be destroyed
3139 //by the main window widget anyway.
3140 //remove_all_menu_toolbar_constructors(main_window, NULL);
3142 g_assert(lttv_iattribute_find_by_path(attributes
,
3143 "viewers/menu", LTTV_POINTER
, &value
));
3144 lttv_menus_destroy((LttvMenus
*)*(value
.v_pointer
));
3146 g_assert(lttv_iattribute_find_by_path(attributes
,
3147 "viewers/toolbar", LTTV_POINTER
, &value
));
3148 lttv_toolbars_destroy((LttvToolbars
*)*(value
.v_pointer
));
3150 g_object_unref(main_window
->attributes
);
3151 g_main_window_list
= g_slist_remove(g_main_window_list
, main_window
);
3153 g_printf("There are now : %d windows\n",g_slist_length(g_main_window_list
));
3154 if(g_slist_length(g_main_window_list
) == 0)
3159 on_MWindow_configure (GtkWidget
*widget
,
3160 GdkEventConfigure
*event
,
3163 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)widget
);
3164 float width
= event
->width
;
3165 TimeWindow time_win
;
3167 TimeInterval
*time_span
;
3170 // MD : removed time width modification upon resizing of the main window.
3171 // The viewers will redraw themselves completely, without time interval
3174 if(mw_data->window_width){
3175 time_span = LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context)->Time_Span ;
3176 time_win = tab->time_window;
3177 ratio = width / mw_data->window_width;
3178 tab->time_window.time_width = ltt_time_mul(time_win.time_width,ratio);
3179 time = ltt_time_sub(time_span->endTime, time_win.start_time);
3180 if(ltt_time_compare(time, tab->time_window.time_width) < 0){
3181 tab->time_window.time_width = time;
3187 mw_data->window_width = (int)width;
3196 on_MNotebook_switch_page (GtkNotebook
*notebook
,
3197 GtkNotebookPage
*page
,
3205 void time_change_manager (Tab
*tab
,
3206 TimeWindow new_time_window
)
3208 /* Only one source of time change */
3209 if(tab
->time_manager_lock
== TRUE
) return;
3211 tab
->time_manager_lock
= TRUE
;
3213 LttvTracesetContext
*tsc
= LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3214 TimeInterval time_span
= tsc
->time_span
;
3215 LttTime start_time
= new_time_window
.start_time
;
3216 LttTime end_time
= ltt_time_add(new_time_window
.start_time
,
3217 new_time_window
.time_width
);
3220 GtkAdjustment
*adjustment
= gtk_range_get_adjustment(GTK_RANGE(tab
->scrollbar
));
3221 LttTime upper
= ltt_time_sub(time_span
.end_time
, time_span
.start_time
);
3223 gtk_range_set_increments(GTK_RANGE(tab
->scrollbar
),
3224 ltt_time_to_double(new_time_window
.time_width
)
3225 / SCROLL_STEP_PER_PAGE
3226 * NANOSECONDS_PER_SECOND
, /* step increment */
3227 ltt_time_to_double(new_time_window
.time_width
)
3228 * NANOSECONDS_PER_SECOND
); /* page increment */
3229 gtk_range_set_range(GTK_RANGE(tab
->scrollbar
),
3231 ltt_time_to_double(upper
)
3232 * NANOSECONDS_PER_SECOND
); /* upper */
3234 g_object_set(G_OBJECT(adjustment
),
3238 ltt_time_to_double(upper
)
3239 * NANOSECONDS_PER_SECOND
, /* upper */
3241 ltt_time_to_double(new_time_window
.time_width
)
3242 / SCROLL_STEP_PER_PAGE
3243 * NANOSECONDS_PER_SECOND
, /* step increment */
3245 ltt_time_to_double(new_time_window
.time_width
)
3246 * NANOSECONDS_PER_SECOND
, /* page increment */
3248 ltt_time_to_double(new_time_window
.time_width
)
3249 * NANOSECONDS_PER_SECOND
, /* page size */
3251 gtk_adjustment_changed(adjustment
);
3253 // g_object_set(G_OBJECT(adjustment),
3255 // ltt_time_to_double(
3256 // ltt_time_sub(start_time, time_span.start_time))
3257 // * NANOSECONDS_PER_SECOND, /* value */
3259 //gtk_adjustment_value_changed(adjustment);
3260 gtk_range_set_value(GTK_RANGE(tab
->scrollbar
),
3262 ltt_time_sub(start_time
, time_span
.start_time
))
3263 * NANOSECONDS_PER_SECOND
/* value */);
3265 /* set the time bar. */
3267 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry1
),
3268 (double)time_span
.start_time
.tv_sec
,
3269 (double)time_span
.end_time
.tv_sec
);
3270 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry1
),
3271 (double)start_time
.tv_sec
);
3273 /* start nanoseconds */
3274 if(start_time
.tv_sec
== time_span
.start_time
.tv_sec
) {
3275 /* can be both beginning and end at the same time. */
3276 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
),
3279 (double)time_span
.start_time
.tv_nsec
,
3280 (double)time_span
.end_time
.tv_nsec
-1);
3282 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry2
),
3283 (double)time_span
.start_time
.tv_nsec
,
3284 (double)NANOSECONDS_PER_SECOND
-1);
3286 } else if(start_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3287 /* If we are at the end, max nsec to end.. -1 (not zero length) */
3288 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry2
),
3290 (double)time_span
.end_time
.tv_nsec
-1);
3291 } else /* anywhere else */
3292 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry2
),
3294 (double)NANOSECONDS_PER_SECOND
-1);
3295 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry2
),
3296 (double)start_time
.tv_nsec
);
3299 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry3
),
3300 (double)time_span
.start_time
.tv_sec
,
3301 (double)time_span
.end_time
.tv_sec
);
3302 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry3
),
3303 (double)end_time
.tv_sec
);
3305 /* end nanoseconds */
3306 if(end_time
.tv_sec
== time_span
.start_time
.tv_sec
) {
3307 /* can be both beginning and end at the same time. */
3308 if(end_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3309 /* If we are at the end, max nsec to end.. */
3310 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry4
),
3311 (double)time_span
.start_time
.tv_nsec
+1,
3312 (double)time_span
.end_time
.tv_nsec
);
3314 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry4
),
3315 (double)time_span
.start_time
.tv_nsec
+1,
3316 (double)NANOSECONDS_PER_SECOND
-1);
3319 else if(end_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3320 /* If we are at the end, max nsec to end.. */
3321 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry4
),
3323 (double)time_span
.end_time
.tv_nsec
);
3325 else /* anywhere else */
3326 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry4
),
3328 (double)NANOSECONDS_PER_SECOND
-1);
3329 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry4
),
3330 (double)end_time
.tv_nsec
);
3332 /* call viewer hooks for new time window */
3333 set_time_window(tab
, &new_time_window
);
3335 tab
->time_manager_lock
= FALSE
;
3339 /* value changed for frame start s
3341 * Check time span : if ns is out of range, clip it the nearest good value.
3344 on_MEntry1_value_changed (GtkSpinButton
*spinbutton
,
3347 Tab
*tab
=(Tab
*)user_data
;
3348 LttvTracesetContext
* tsc
=
3349 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3350 TimeInterval time_span
= tsc
->time_span
;
3351 gint value
= gtk_spin_button_get_value_as_int(spinbutton
);
3353 TimeWindow new_time_window
= tab
->time_window
;
3355 LttTime end_time
= ltt_time_add(new_time_window
.start_time
,
3356 new_time_window
.time_width
);
3358 new_time_window
.start_time
.tv_sec
= value
;
3360 /* start nanoseconds */
3361 if(new_time_window
.start_time
.tv_sec
== time_span
.start_time
.tv_sec
) {
3362 if(new_time_window
.start_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3363 if(new_time_window
.start_time
.tv_nsec
> time_span
.end_time
.tv_nsec
)
3364 new_time_window
.start_time
.tv_nsec
= time_span
.end_time
.tv_nsec
-1;
3365 if(new_time_window
.start_time
.tv_nsec
< time_span
.start_time
.tv_nsec
)
3366 new_time_window
.start_time
.tv_nsec
= time_span
.start_time
.tv_nsec
;
3368 if(new_time_window
.start_time
.tv_nsec
< time_span
.start_time
.tv_nsec
)
3369 new_time_window
.start_time
.tv_nsec
= time_span
.start_time
.tv_nsec
;
3372 else if(new_time_window
.start_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3373 if(new_time_window
.start_time
.tv_nsec
> time_span
.end_time
.tv_nsec
)
3374 new_time_window
.start_time
.tv_nsec
= time_span
.end_time
.tv_nsec
-1;
3377 /* check if end time selected is below or equal */
3378 if(ltt_time_compare(new_time_window
.start_time
, end_time
) >= 0) {
3379 /* Then, we must push back end time : keep the same time width
3380 * if possible, else end traceset time */
3381 end_time
= LTT_TIME_MIN(time_span
.end_time
,
3382 ltt_time_add(new_time_window
.start_time
,
3383 new_time_window
.time_width
)
3387 /* Fix the time width to fit start time and end time */
3388 new_time_window
.time_width
= ltt_time_sub(end_time
,
3389 new_time_window
.start_time
);
3391 time_change_manager(tab
, new_time_window
);
3396 on_MEntry2_value_changed (GtkSpinButton
*spinbutton
,
3399 Tab
*tab
=(Tab
*)user_data
;
3400 LttvTracesetContext
* tsc
=
3401 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3402 TimeInterval time_span
= tsc
->time_span
;
3403 gint value
= gtk_spin_button_get_value_as_int(spinbutton
);
3405 TimeWindow new_time_window
= tab
->time_window
;
3407 LttTime end_time
= ltt_time_add(new_time_window
.start_time
,
3408 new_time_window
.time_width
);
3410 new_time_window
.start_time
.tv_nsec
= value
;
3412 /* check if end time selected is below or equal */
3413 if(ltt_time_compare(new_time_window
.start_time
, end_time
) >= 0) {
3414 /* Then, we must push back end time : keep the same time width
3415 * if possible, else end traceset time */
3416 end_time
= LTT_TIME_MIN(time_span
.end_time
,
3417 ltt_time_add(new_time_window
.start_time
,
3418 new_time_window
.time_width
)
3422 /* Fix the time width to fit start time and end time */
3423 new_time_window
.time_width
= ltt_time_sub(end_time
,
3424 new_time_window
.start_time
);
3426 time_change_manager(tab
, new_time_window
);
3431 on_MEntry3_value_changed (GtkSpinButton
*spinbutton
,
3434 Tab
*tab
=(Tab
*)user_data
;
3435 LttvTracesetContext
* tsc
=
3436 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3437 TimeInterval time_span
= tsc
->time_span
;
3438 gint value
= gtk_spin_button_get_value_as_int(spinbutton
);
3440 TimeWindow new_time_window
= tab
->time_window
;
3442 LttTime end_time
= ltt_time_add(new_time_window
.start_time
,
3443 new_time_window
.time_width
);
3444 end_time
.tv_sec
= value
;
3446 /* end nanoseconds */
3447 if(end_time
.tv_sec
== time_span
.start_time
.tv_sec
) {
3448 if(end_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3449 if(end_time
.tv_nsec
> time_span
.end_time
.tv_nsec
)
3450 end_time
.tv_nsec
= time_span
.end_time
.tv_nsec
;
3451 if(end_time
.tv_nsec
< time_span
.start_time
.tv_nsec
)
3452 end_time
.tv_nsec
= time_span
.start_time
.tv_nsec
+1;
3454 if(end_time
.tv_nsec
< time_span
.start_time
.tv_nsec
)
3455 end_time
.tv_nsec
= time_span
.start_time
.tv_nsec
+1;
3458 else if(end_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3459 if(end_time
.tv_nsec
> time_span
.end_time
.tv_nsec
)
3460 end_time
.tv_nsec
= time_span
.end_time
.tv_nsec
;
3463 /* check if end time selected is below or equal */
3464 if(ltt_time_compare(new_time_window
.start_time
, end_time
) >= 0) {
3465 /* Then, we must push front start time : keep the same time width
3466 * if possible, else end traceset time */
3467 new_time_window
.start_time
= LTT_TIME_MAX(time_span
.start_time
,
3468 ltt_time_sub(end_time
,
3469 new_time_window
.time_width
)
3473 /* Fix the time width to fit start time and end time */
3474 new_time_window
.time_width
= ltt_time_sub(end_time
,
3475 new_time_window
.start_time
);
3477 time_change_manager(tab
, new_time_window
);
3482 on_MEntry4_value_changed (GtkSpinButton
*spinbutton
,
3485 Tab
*tab
=(Tab
*)user_data
;
3486 LttvTracesetContext
* tsc
=
3487 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3488 TimeInterval time_span
= tsc
->time_span
;
3489 gint value
= gtk_spin_button_get_value_as_int(spinbutton
);
3491 TimeWindow new_time_window
= tab
->time_window
;
3493 LttTime end_time
= ltt_time_add(new_time_window
.start_time
,
3494 new_time_window
.time_width
);
3495 end_time
.tv_nsec
= value
;
3497 /* check if end time selected is below or equal */
3498 if(ltt_time_compare(new_time_window
.start_time
, end_time
) >= 0) {
3499 /* Then, we must push front start time : keep the same time width
3500 * if possible, else end traceset time */
3501 new_time_window
.start_time
= LTT_TIME_MAX(time_span
.start_time
,
3502 ltt_time_sub(end_time
,
3503 new_time_window
.time_width
)
3507 /* Fix the time width to fit start time and end time */
3508 new_time_window
.time_width
= ltt_time_sub(end_time
,
3509 new_time_window
.start_time
);
3511 time_change_manager(tab
, new_time_window
);
3516 void current_time_change_manager (Tab
*tab
,
3517 LttTime new_current_time
)
3519 /* Only one source of time change */
3520 if(tab
->current_time_manager_lock
== TRUE
) return;
3522 tab
->current_time_manager_lock
= TRUE
;
3524 LttvTracesetContext
*tsc
= LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3525 TimeInterval time_span
= tsc
->time_span
;
3527 /* current seconds */
3528 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry5
),
3529 (double)time_span
.start_time
.tv_sec
,
3530 (double)time_span
.end_time
.tv_sec
);
3531 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry5
),
3532 (double)new_current_time
.tv_sec
);
3535 /* start nanoseconds */
3536 if(new_current_time
.tv_sec
== time_span
.start_time
.tv_sec
) {
3537 /* can be both beginning and end at the same time. */
3538 if(new_current_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3539 /* If we are at the end, max nsec to end.. */
3540 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry6
),
3541 (double)time_span
.start_time
.tv_nsec
,
3542 (double)time_span
.end_time
.tv_nsec
);
3544 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry6
),
3545 (double)time_span
.start_time
.tv_nsec
,
3546 (double)NANOSECONDS_PER_SECOND
-1);
3548 } else if(new_current_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3549 /* If we are at the end, max nsec to end.. */
3550 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry6
),
3552 (double)time_span
.end_time
.tv_nsec
);
3553 } else /* anywhere else */
3554 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry6
),
3556 (double)NANOSECONDS_PER_SECOND
-1);
3558 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry6
),
3559 (double)new_current_time
.tv_nsec
);
3561 set_current_time(tab
, &new_current_time
);
3563 tab
->current_time_manager_lock
= FALSE
;
3567 on_MEntry5_value_changed (GtkSpinButton
*spinbutton
,
3570 Tab
*tab
= (Tab
*)user_data
;
3571 LttvTracesetContext
* tsc
=
3572 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3573 TimeInterval time_span
= tsc
->time_span
;
3574 gint value
= gtk_spin_button_get_value_as_int(spinbutton
);
3575 LttTime new_current_time
= tab
->current_time
;
3576 new_current_time
.tv_sec
= value
;
3578 /* current nanoseconds */
3579 if(new_current_time
.tv_sec
== time_span
.start_time
.tv_sec
) {
3580 if(new_current_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3581 if(new_current_time
.tv_nsec
> time_span
.end_time
.tv_nsec
)
3582 new_current_time
.tv_nsec
= time_span
.end_time
.tv_nsec
;
3583 if(new_current_time
.tv_nsec
< time_span
.start_time
.tv_nsec
)
3584 new_current_time
.tv_nsec
= time_span
.start_time
.tv_nsec
;
3586 if(new_current_time
.tv_nsec
< time_span
.start_time
.tv_nsec
)
3587 new_current_time
.tv_nsec
= time_span
.start_time
.tv_nsec
;
3590 else if(new_current_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3591 if(new_current_time
.tv_nsec
> time_span
.end_time
.tv_nsec
)
3592 new_current_time
.tv_nsec
= time_span
.end_time
.tv_nsec
;
3595 current_time_change_manager(tab
, new_current_time
);
3599 on_MEntry6_value_changed (GtkSpinButton
*spinbutton
,
3602 Tab
*tab
= (Tab
*)user_data
;
3603 gint value
= gtk_spin_button_get_value_as_int(spinbutton
);
3604 LttTime new_current_time
= tab
->current_time
;
3605 new_current_time
.tv_nsec
= value
;
3607 current_time_change_manager(tab
, new_current_time
);
3611 void scroll_value_changed_cb(GtkWidget
*scrollbar
,
3614 Tab
*tab
= (Tab
*)user_data
;
3615 TimeWindow new_time_window
;
3617 GtkAdjustment
*adjust
= gtk_range_get_adjustment(GTK_RANGE(scrollbar
));
3618 gdouble value
= gtk_adjustment_get_value(adjust
);
3619 // gdouble upper, lower, ratio, page_size;
3621 LttvTracesetContext
* tsc
=
3622 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3623 TimeInterval time_span
= tsc
->time_span
;
3625 time
= ltt_time_add(ltt_time_from_double(value
/NANOSECONDS_PER_SECOND
),
3626 time_span
.start_time
);
3628 new_time_window
.start_time
= time
;
3630 page_size
= adjust
->page_size
;
3632 new_time_window
.time_width
=
3633 ltt_time_from_double(page_size
/NANOSECONDS_PER_SECOND
);
3636 time_change_manager(tab
, new_time_window
);
3638 //time_window = tab->time_window;
3640 lower
= adjust
->lower
;
3641 upper
= adjust
->upper
;
3642 ratio
= (value
- lower
) / (upper
- lower
);
3643 g_info("lower %lu, upper %lu, value %lu, ratio %lu", lower
, upper
, value
, ratio
);
3645 //time = ltt_time_sub(time_span->end_time, time_span->start_time);
3646 //time = ltt_time_mul(time, (float)ratio);
3647 //time = ltt_time_add(time_span->start_time, time);
3648 time
= ltt_time_add(ltt_time_from_double(value
/NANOSECONDS_PER_SECOND
),
3649 time_span
.start_time
);
3651 time_window
.start_time
= time
;
3653 page_size
= adjust
->page_size
;
3655 time_window
.time_width
=
3656 ltt_time_from_double(page_size
/NANOSECONDS_PER_SECOND
);
3657 //time = ltt_time_sub(time_span.end_time, time);
3658 //if(ltt_time_compare(time,time_window.time_width) < 0){
3659 // time_window.time_width = time;
3662 /* call viewer hooks for new time window */
3663 set_time_window(tab
, &time_window
);
3668 /* callback function to check or uncheck the check box (filter)
3671 void checkbox_changed(GtkTreeView
*treeview
,
3673 GtkTreeViewColumn
*arg2
,
3676 GtkTreeStore
* store
= (GtkTreeStore
*)gtk_tree_view_get_model (treeview
);
3680 if (gtk_tree_model_get_iter ((GtkTreeModel
*)store
, &iter
, arg1
)){
3681 gtk_tree_model_get ((GtkTreeModel
*)store
, &iter
, CHECKBOX_COLUMN
, &value
, -1);
3682 value
= value
? FALSE
: TRUE
;
3683 gtk_tree_store_set (GTK_TREE_STORE (store
), &iter
, CHECKBOX_COLUMN
, value
, -1);
3689 /* According to user's selection, update selector(filter)
3692 void update_filter(LttvTracesetSelector
*s
, GtkTreeStore
*store
)
3694 GtkTreeIter iter
, child_iter
, child_iter1
, child_iter2
;
3695 int i
, j
, k
, nb_eventtype
;
3696 LttvTraceSelector
* trace
;
3697 LttvTracefileSelector
* tracefile
;
3698 LttvEventtypeSelector
* eventtype
;
3699 gboolean value
, value1
, value2
;
3701 if(gtk_tree_model_get_iter_first((GtkTreeModel
*)store
, &iter
)){
3704 trace
= lttv_traceset_selector_trace_get(s
, i
);
3705 nb_eventtype
= lttv_trace_selector_eventtype_number(trace
);
3706 gtk_tree_model_get ((GtkTreeModel
*)store
, &iter
, CHECKBOX_COLUMN
, &value
,-1);
3709 if(gtk_tree_model_iter_children ((GtkTreeModel
*)store
, &child_iter
, &iter
)){
3711 if(j
<1){//eventtype selector for trace
3712 gtk_tree_model_get ((GtkTreeModel
*)store
, &child_iter
, CHECKBOX_COLUMN
, &value2
,-1);
3715 if(gtk_tree_model_iter_children ((GtkTreeModel
*)store
, &child_iter1
, &child_iter
)){
3717 eventtype
= lttv_trace_selector_eventtype_get(trace
,k
);
3718 gtk_tree_model_get ((GtkTreeModel
*)store
, &child_iter1
, CHECKBOX_COLUMN
, &value2
,-1);
3719 lttv_eventtype_selector_set_selected(eventtype
,value2
);
3721 }while(gtk_tree_model_iter_next((GtkTreeModel
*)store
, &child_iter1
));
3724 }else{ //tracefile selector
3725 tracefile
= lttv_trace_selector_tracefile_get(trace
, j
- 1);
3726 gtk_tree_model_get ((GtkTreeModel
*)store
, &child_iter
, CHECKBOX_COLUMN
, &value1
,-1);
3727 lttv_tracefile_selector_set_selected(tracefile
,value1
);
3729 gtk_tree_model_iter_children((GtkTreeModel
*)store
, &child_iter1
, &child_iter
); //eventtype selector
3730 gtk_tree_model_get ((GtkTreeModel
*)store
, &child_iter1
, CHECKBOX_COLUMN
, &value2
,-1);
3733 if(gtk_tree_model_iter_children ((GtkTreeModel
*)store
, &child_iter2
, &child_iter1
)){
3734 do{//eventtype selector for tracefile
3735 eventtype
= lttv_tracefile_selector_eventtype_get(tracefile
,k
);
3736 gtk_tree_model_get ((GtkTreeModel
*)store
, &child_iter2
, CHECKBOX_COLUMN
, &value2
,-1);
3737 lttv_eventtype_selector_set_selected(eventtype
,value2
);
3739 }while(gtk_tree_model_iter_next((GtkTreeModel
*)store
, &child_iter2
));
3745 }while(gtk_tree_model_iter_next((GtkTreeModel
*)store
, &child_iter
));
3748 lttv_trace_selector_set_selected(trace
,value
);
3750 }while(gtk_tree_model_iter_next((GtkTreeModel
*)store
, &iter
));
3755 /* Display a dialogue showing all eventtypes and traces, let user to select the interested
3756 * eventtypes, tracefiles and traces (filter)
3759 gboolean
get_filter_selection(LttvTracesetSelector
*s
,char *title
, char * column_title
)
3761 GtkWidget
* dialogue
;
3762 GtkTreeStore
* store
;
3764 GtkWidget
* scroll_win
;
3765 GtkCellRenderer
* renderer
;
3766 GtkTreeViewColumn
* column
;
3767 GtkTreeIter iter
, child_iter
, child_iter1
, child_iter2
;
3768 int i
, j
, k
, id
, nb_trace
, nb_tracefile
, nb_eventtype
;
3769 LttvTraceSelector
* trace
;
3770 LttvTracefileSelector
* tracefile
;
3771 LttvEventtypeSelector
* eventtype
;
3775 dialogue
= gtk_dialog_new_with_buttons(title
,
3778 GTK_STOCK_OK
,GTK_RESPONSE_ACCEPT
,
3779 GTK_STOCK_CANCEL
,GTK_RESPONSE_REJECT
,
3781 gtk_window_set_default_size((GtkWindow
*)dialogue
, 300, 500);
3783 store
= gtk_tree_store_new (TOTAL_COLUMNS
, G_TYPE_BOOLEAN
, G_TYPE_STRING
);
3784 tree
= gtk_tree_view_new_with_model (GTK_TREE_MODEL (store
));
3785 g_object_unref (G_OBJECT (store
));
3786 g_signal_connect (G_OBJECT (tree
), "row-activated",
3787 G_CALLBACK (checkbox_changed
),
3791 renderer
= gtk_cell_renderer_toggle_new ();
3792 gtk_cell_renderer_toggle_set_radio((GtkCellRendererToggle
*)renderer
, FALSE
);
3794 g_object_set (G_OBJECT (renderer
),"activatable", TRUE
, NULL
);
3796 column
= gtk_tree_view_column_new_with_attributes ("Checkbox",
3798 "active", CHECKBOX_COLUMN
,
3800 gtk_tree_view_column_set_alignment (column
, 0.5);
3801 gtk_tree_view_column_set_fixed_width (column
, 20);
3802 gtk_tree_view_append_column (GTK_TREE_VIEW (tree
), column
);
3804 renderer
= gtk_cell_renderer_text_new ();
3805 column
= gtk_tree_view_column_new_with_attributes (column_title
,
3807 "text", NAME_COLUMN
,
3809 gtk_tree_view_column_set_alignment (column
, 0.0);
3810 gtk_tree_view_append_column (GTK_TREE_VIEW (tree
), column
);
3811 gtk_tree_view_set_headers_visible(GTK_TREE_VIEW (tree
), FALSE
);
3813 scroll_win
= gtk_scrolled_window_new (NULL
, NULL
);
3814 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll_win
),
3815 GTK_POLICY_AUTOMATIC
,GTK_POLICY_AUTOMATIC
);
3816 gtk_container_add (GTK_CONTAINER (scroll_win
), tree
);
3818 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialogue
)->vbox
), scroll_win
,TRUE
, TRUE
,0);
3820 gtk_widget_show(scroll_win
);
3821 gtk_widget_show(tree
);
3823 nb_trace
= lttv_traceset_selector_trace_number(s
);
3824 for(i
=0;i
<nb_trace
;i
++){
3825 trace
= lttv_traceset_selector_trace_get(s
, i
);
3826 name
= lttv_trace_selector_get_name(trace
);
3827 gtk_tree_store_append (store
, &iter
, NULL
);
3828 checked
= lttv_trace_selector_get_selected(trace
);
3829 gtk_tree_store_set (store
, &iter
,
3830 CHECKBOX_COLUMN
,checked
,
3834 gtk_tree_store_append (store
, &child_iter
, &iter
);
3835 gtk_tree_store_set (store
, &child_iter
,
3836 CHECKBOX_COLUMN
, checked
,
3837 NAME_COLUMN
,"eventtype",
3840 nb_eventtype
= lttv_trace_selector_eventtype_number(trace
);
3841 for(j
=0;j
<nb_eventtype
;j
++){
3842 eventtype
= lttv_trace_selector_eventtype_get(trace
,j
);
3843 name
= lttv_eventtype_selector_get_name(eventtype
);
3844 checked
= lttv_eventtype_selector_get_selected(eventtype
);
3845 gtk_tree_store_append (store
, &child_iter1
, &child_iter
);
3846 gtk_tree_store_set (store
, &child_iter1
,
3847 CHECKBOX_COLUMN
, checked
,
3852 nb_tracefile
= lttv_trace_selector_tracefile_number(trace
);
3853 for(j
=0;j
<nb_tracefile
;j
++){
3854 tracefile
= lttv_trace_selector_tracefile_get(trace
, j
);
3855 name
= lttv_tracefile_selector_get_name(tracefile
);
3856 gtk_tree_store_append (store
, &child_iter
, &iter
);
3857 checked
= lttv_tracefile_selector_get_selected(tracefile
);
3858 gtk_tree_store_set (store
, &child_iter
,
3859 CHECKBOX_COLUMN
, checked
,
3863 gtk_tree_store_append (store
, &child_iter1
, &child_iter
);
3864 gtk_tree_store_set (store
, &child_iter1
,
3865 CHECKBOX_COLUMN
, checked
,
3866 NAME_COLUMN
,"eventtype",
3869 for(k
=0;k
<nb_eventtype
;k
++){
3870 eventtype
= lttv_tracefile_selector_eventtype_get(tracefile
,k
);
3871 name
= lttv_eventtype_selector_get_name(eventtype
);
3872 checked
= lttv_eventtype_selector_get_selected(eventtype
);
3873 gtk_tree_store_append (store
, &child_iter2
, &child_iter1
);
3874 gtk_tree_store_set (store
, &child_iter2
,
3875 CHECKBOX_COLUMN
, checked
,
3882 id
= gtk_dialog_run(GTK_DIALOG(dialogue
));
3884 case GTK_RESPONSE_ACCEPT
:
3885 case GTK_RESPONSE_OK
:
3886 update_filter(s
, store
);
3887 gtk_widget_destroy(dialogue
);
3889 case GTK_RESPONSE_REJECT
:
3890 case GTK_RESPONSE_CANCEL
:
3892 gtk_widget_destroy(dialogue
);
3899 /* Select a trace which will be removed from traceset
3902 char * get_remove_trace(char ** all_trace_name
, int nb_trace
)
3904 return get_selection(all_trace_name
, nb_trace
,
3905 "Select a trace", "Trace pathname");
3909 /* Select a module which will be loaded
3912 char * get_load_module(char ** load_module_name
, int nb_module
)
3914 return get_selection(load_module_name
, nb_module
,
3915 "Select a module to load", "Module name");
3921 /* Select a module which will be unloaded
3924 char * get_unload_module(char ** loaded_module_name
, int nb_module
)
3926 return get_selection(loaded_module_name
, nb_module
,
3927 "Select a module to unload", "Module name");
3931 /* Display a dialogue which shows all selectable items, let user to
3932 * select one of them
3935 char * get_selection(char ** loaded_module_name
, int nb_module
,
3936 char *title
, char * column_title
)
3938 GtkWidget
* dialogue
;
3939 GtkWidget
* scroll_win
;
3941 GtkListStore
* store
;
3942 GtkTreeViewColumn
* column
;
3943 GtkCellRenderer
* renderer
;
3944 GtkTreeSelection
* select
;
3947 char * unload_module_name
= NULL
;
3949 dialogue
= gtk_dialog_new_with_buttons(title
,
3952 GTK_STOCK_OK
,GTK_RESPONSE_ACCEPT
,
3953 GTK_STOCK_CANCEL
,GTK_RESPONSE_REJECT
,
3955 gtk_window_set_default_size((GtkWindow
*)dialogue
, 500, 200);
3957 scroll_win
= gtk_scrolled_window_new (NULL
, NULL
);
3958 gtk_widget_show ( scroll_win
);
3959 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll_win
),
3960 GTK_POLICY_AUTOMATIC
, GTK_POLICY_AUTOMATIC
);
3962 store
= gtk_list_store_new (N_COLUMNS
,G_TYPE_STRING
);
3963 tree
= gtk_tree_view_new_with_model(GTK_TREE_MODEL (store
));
3964 gtk_widget_show ( tree
);
3965 g_object_unref (G_OBJECT (store
));
3967 renderer
= gtk_cell_renderer_text_new ();
3968 column
= gtk_tree_view_column_new_with_attributes (column_title
,
3970 "text", MODULE_COLUMN
,
3972 gtk_tree_view_column_set_alignment (column
, 0.5);
3973 gtk_tree_view_column_set_fixed_width (column
, 150);
3974 gtk_tree_view_append_column (GTK_TREE_VIEW (tree
), column
);
3976 select
= gtk_tree_view_get_selection (GTK_TREE_VIEW (tree
));
3977 gtk_tree_selection_set_mode (select
, GTK_SELECTION_SINGLE
);
3979 gtk_container_add (GTK_CONTAINER (scroll_win
), tree
);
3981 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialogue
)->vbox
), scroll_win
,TRUE
, TRUE
,0);
3983 for(i
=0;i
<nb_module
;i
++){
3984 gtk_list_store_append (store
, &iter
);
3985 gtk_list_store_set (store
, &iter
, MODULE_COLUMN
,loaded_module_name
[i
],-1);
3988 id
= gtk_dialog_run(GTK_DIALOG(dialogue
));
3990 case GTK_RESPONSE_ACCEPT
:
3991 case GTK_RESPONSE_OK
:
3992 if (gtk_tree_selection_get_selected (select
, (GtkTreeModel
**)&store
, &iter
)){
3993 gtk_tree_model_get ((GtkTreeModel
*)store
, &iter
, MODULE_COLUMN
, &unload_module_name
, -1);
3995 case GTK_RESPONSE_REJECT
:
3996 case GTK_RESPONSE_CANCEL
:
3998 gtk_widget_destroy(dialogue
);
4002 return unload_module_name
;
4006 /* Insert all menu entry and tool buttons into this main window
4011 void add_all_menu_toolbar_constructors(MainWindow
* mw
, gpointer user_data
)
4015 lttvwindow_viewer_constructor constructor
;
4016 LttvMenus
* global_menu
, * instance_menu
;
4017 LttvToolbars
* global_toolbar
, * instance_toolbar
;
4018 LttvMenuClosure
*menu_item
;
4019 LttvToolbarClosure
*toolbar_item
;
4020 LttvAttributeValue value
;
4021 LttvIAttribute
*global_attributes
= LTTV_IATTRIBUTE(lttv_global_attributes());
4022 LttvIAttribute
*attributes
= mw
->attributes
;
4023 GtkWidget
* tool_menu_title_menu
, *new_widget
, *pixmap
;
4025 g_assert(lttv_iattribute_find_by_path(global_attributes
,
4026 "viewers/menu", LTTV_POINTER
, &value
));
4027 if(*(value
.v_pointer
) == NULL
)
4028 *(value
.v_pointer
) = lttv_menus_new();
4029 global_menu
= (LttvMenus
*)*(value
.v_pointer
);
4031 g_assert(lttv_iattribute_find_by_path(attributes
,
4032 "viewers/menu", LTTV_POINTER
, &value
));
4033 if(*(value
.v_pointer
) == NULL
)
4034 *(value
.v_pointer
) = lttv_menus_new();
4035 instance_menu
= (LttvMenus
*)*(value
.v_pointer
);
4039 g_assert(lttv_iattribute_find_by_path(global_attributes
,
4040 "viewers/toolbar", LTTV_POINTER
, &value
));
4041 if(*(value
.v_pointer
) == NULL
)
4042 *(value
.v_pointer
) = lttv_toolbars_new();
4043 global_toolbar
= (LttvToolbars
*)*(value
.v_pointer
);
4045 g_assert(lttv_iattribute_find_by_path(attributes
,
4046 "viewers/toolbar", LTTV_POINTER
, &value
));
4047 if(*(value
.v_pointer
) == NULL
)
4048 *(value
.v_pointer
) = lttv_toolbars_new();
4049 instance_toolbar
= (LttvToolbars
*)*(value
.v_pointer
);
4051 /* Add missing menu entries to window instance */
4052 for(i
=0;i
<global_menu
->len
;i
++) {
4053 menu_item
= &g_array_index(global_menu
, LttvMenuClosure
, i
);
4055 //add menu_item to window instance;
4056 constructor
= menu_item
->con
;
4057 tool_menu_title_menu
= lookup_widget(mw
->mwindow
,"ToolMenuTitle_menu");
4059 gtk_menu_item_new_with_mnemonic (menu_item
->menu_text
);
4060 gtk_container_add (GTK_CONTAINER (tool_menu_title_menu
),
4062 g_signal_connect ((gpointer
) new_widget
, "activate",
4063 G_CALLBACK (insert_viewer_wrap
),
4065 gtk_widget_show (new_widget
);
4066 lttv_menus_add(instance_menu
, menu_item
->con
,
4067 menu_item
->menu_path
,
4068 menu_item
->menu_text
,
4073 /* Add missing toolbar entries to window instance */
4074 for(i
=0;i
<global_toolbar
->len
;i
++) {
4075 toolbar_item
= &g_array_index(global_toolbar
, LttvToolbarClosure
, i
);
4077 //add toolbar_item to window instance;
4078 constructor
= toolbar_item
->con
;
4079 tool_menu_title_menu
= lookup_widget(mw
->mwindow
,"MToolbar1");
4080 pixbuf
= gdk_pixbuf_new_from_xpm_data((const char**)toolbar_item
->pixmap
);
4081 pixmap
= gtk_image_new_from_pixbuf(pixbuf
);
4083 gtk_toolbar_append_element (GTK_TOOLBAR (tool_menu_title_menu
),
4084 GTK_TOOLBAR_CHILD_BUTTON
,
4087 toolbar_item
->tooltip
, NULL
,
4088 pixmap
, NULL
, NULL
);
4089 gtk_label_set_use_underline(
4090 GTK_LABEL (((GtkToolbarChild
*) (
4091 g_list_last (GTK_TOOLBAR
4092 (tool_menu_title_menu
)->children
)->data
))->label
),
4094 gtk_container_set_border_width (GTK_CONTAINER (new_widget
), 1);
4095 g_signal_connect ((gpointer
) new_widget
,
4097 G_CALLBACK (insert_viewer_wrap
),
4099 gtk_widget_show (new_widget
);
4101 lttv_toolbars_add(instance_toolbar
, toolbar_item
->con
,
4102 toolbar_item
->tooltip
,
4103 toolbar_item
->pixmap
,
4111 /* Create a main window
4114 void construct_main_window(MainWindow
* parent
)
4116 g_debug("construct_main_window()");
4117 GtkWidget
* new_window
; /* New generated main window */
4118 MainWindow
* new_m_window
;/* New main window structure */
4119 GtkNotebook
* notebook
;
4120 LttvIAttribute
*attributes
=
4121 LTTV_IATTRIBUTE(g_object_new(LTTV_ATTRIBUTE_TYPE
, NULL
));
4122 LttvAttributeValue value
;
4125 new_m_window
= g_new(MainWindow
, 1);
4127 // Add the object's information to the module's array
4128 g_main_window_list
= g_slist_append(g_main_window_list
, new_m_window
);
4130 new_window
= create_MWindow();
4131 gtk_widget_show (new_window
);
4133 new_m_window
->mwindow
= new_window
;
4134 new_m_window
->attributes
= attributes
;
4136 g_assert(lttv_iattribute_find_by_path(attributes
,
4137 "viewers/menu", LTTV_POINTER
, &value
));
4138 *(value
.v_pointer
) = lttv_menus_new();
4140 g_assert(lttv_iattribute_find_by_path(attributes
,
4141 "viewers/toolbar", LTTV_POINTER
, &value
));
4142 *(value
.v_pointer
) = lttv_toolbars_new();
4144 add_all_menu_toolbar_constructors(new_m_window
, NULL
);
4146 g_object_set_data_full(G_OBJECT(new_window
),
4148 (gpointer
)new_m_window
,
4149 (GDestroyNotify
)g_free
);
4150 //create a default tab
4151 notebook
= (GtkNotebook
*)lookup_widget(new_m_window
->mwindow
, "MNotebook");
4152 if(notebook
== NULL
){
4153 g_printf("Notebook does not exist\n");
4156 //gtk_notebook_popup_enable (GTK_NOTEBOOK(notebook));
4157 //for now there is no name field in LttvTraceset structure
4158 //Use "Traceset" as the label for the default tab
4160 GtkWidget
* parent_notebook
= lookup_widget(parent
->mwindow
, "MNotebook");
4161 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(parent_notebook
),
4162 gtk_notebook_get_current_page(GTK_NOTEBOOK(parent_notebook
)));
4168 parent_tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
4170 new_tab
= create_tab(new_m_window
, parent_tab
, notebook
, "Traceset");
4172 new_tab
= create_tab(new_m_window
, NULL
, notebook
, "Traceset");
4173 /* First window, use command line trace */
4174 if(g_init_trace
!= NULL
){
4175 lttvwindow_add_trace(new_tab
,
4179 LttvTraceset
*traceset
= new_tab
->traceset_info
->traceset
;
4180 SetTraceset(new_tab
, traceset
);
4183 g_printf("There are now : %d windows\n",g_slist_length(g_main_window_list
));
4187 /* Free the memory occupied by a tab structure
4191 void tab_destructor(Tab
* tab_instance
)
4193 int i
, nb
, ref_count
;
4196 if(tab_instance
->attributes
)
4197 g_object_unref(tab_instance
->attributes
);
4199 if(tab_instance
->interrupted_state
)
4200 g_object_unref(tab_instance
->interrupted_state
);
4203 if(tab_instance
->traceset_info
->traceset_context
!= NULL
){
4204 //remove state update hooks
4205 lttv_state_remove_event_hooks(
4206 (LttvTracesetState
*)tab_instance
->traceset_info
->
4208 lttv_context_fini(LTTV_TRACESET_CONTEXT(tab_instance
->traceset_info
->
4210 g_object_unref(tab_instance
->traceset_info
->traceset_context
);
4212 if(tab_instance
->traceset_info
->traceset
!= NULL
) {
4213 nb
= lttv_traceset_number(tab_instance
->traceset_info
->traceset
);
4214 for(i
= 0 ; i
< nb
; i
++) {
4215 trace
= lttv_traceset_get(tab_instance
->traceset_info
->traceset
, i
);
4216 ref_count
= lttv_trace_get_ref_number(trace
);
4218 ltt_trace_close(lttv_trace(trace
));
4222 lttv_traceset_destroy(tab_instance
->traceset_info
->traceset
);
4223 /* Remove the idle events requests processing function of the tab */
4224 g_idle_remove_by_data(tab_instance
);
4226 g_slist_free(tab_instance
->events_requests
);
4227 g_free(tab_instance
->traceset_info
);
4228 g_free(tab_instance
);
4232 /* Create a tab and insert it into the current main window
4235 Tab
* create_tab(MainWindow
* mw
, Tab
*copy_tab
,
4236 GtkNotebook
* notebook
, char * label
)
4242 //create a new tab data structure
4245 //construct and initialize the traceset_info
4246 tab
->traceset_info
= g_new(TracesetInfo
,1);
4249 tab
->traceset_info
->traceset
=
4250 lttv_traceset_copy(copy_tab
->traceset_info
->traceset
);
4252 tab
->traceset_info
->traceset
= lttv_traceset_new();
4256 lttv_attribute_write_xml(
4257 lttv_traceset_attribute(tab
->traceset_info
->traceset
),
4263 tab
->time_manager_lock
= FALSE
;
4264 tab
->current_time_manager_lock
= FALSE
;
4266 //FIXME copy not implemented in lower level
4267 tab
->traceset_info
->traceset_context
=
4268 g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
4269 g_assert(tab
->traceset_info
->traceset_context
!= NULL
);
4271 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
),
4272 tab
->traceset_info
->traceset
);
4273 //add state update hooks
4274 lttv_state_add_event_hooks(
4275 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
4277 //determine the current_time and time_window of the tab
4279 if(copy_tab
!= NULL
){
4280 tab
->time_window
= copy_tab
->time_window
;
4281 tab
->current_time
= copy_tab
->current_time
;
4283 tab
->time_window
.start_time
=
4284 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
4285 time_span
.start_time
;
4286 if(DEFAULT_TIME_WIDTH_S
<
4287 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
4288 time_span
.end_time
.tv_sec
)
4289 tmp_time
.tv_sec
= DEFAULT_TIME_WIDTH_S
;
4292 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
4293 time_span
.end_time
.tv_sec
;
4294 tmp_time
.tv_nsec
= 0;
4295 tab
->time_window
.time_width
= tmp_time
;
4296 tab
->current_time
.tv_sec
=
4297 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
4298 time_span
.start_time
.tv_sec
;
4299 tab
->current_time
.tv_nsec
=
4300 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
4301 time_span
.start_time
.tv_nsec
;
4304 tab
->attributes
= LTTV_IATTRIBUTE(g_object_new(LTTV_ATTRIBUTE_TYPE
, NULL
));
4305 tab
->interrupted_state
= g_object_new(LTTV_ATTRIBUTE_TYPE
, NULL
);
4307 tab
->vbox
= gtk_vbox_new(FALSE
, 2);
4308 tab
->viewer_container
= gtk_vbox_new(TRUE
, 2);
4309 tab
->scrollbar
= gtk_hscrollbar_new(NULL
);
4310 //tab->multivpaned = gtk_multi_vpaned_new();
4312 gtk_box_pack_start(GTK_BOX(tab
->vbox
),
4313 tab
->viewer_container
,
4315 TRUE
, /* Give the extra space to the child */
4316 0); /* No padding */
4318 /* Create the timebar */
4320 tab
->MTimebar
= gtk_hbox_new(FALSE
, 2);
4321 gtk_widget_show(tab
->MTimebar
);
4323 tab
->MText1
= gtk_label_new("Time Frame start: ");
4324 gtk_widget_show(tab
->MText1
);
4325 tab
->MText2
= gtk_label_new("s");
4326 gtk_widget_show(tab
->MText2
);
4327 tab
->MText3a
= gtk_label_new("ns");
4328 gtk_widget_show(tab
->MText3a
);
4329 tab
->MText3b
= gtk_label_new("end:");
4330 gtk_widget_show(tab
->MText3b
);
4331 tab
->MText4
= gtk_label_new("s");
4332 gtk_widget_show(tab
->MText4
);
4333 tab
->MText5a
= gtk_label_new("ns");
4334 gtk_widget_show(tab
->MText5a
);
4335 tab
->MText5b
= gtk_label_new("Current Time:");
4336 gtk_widget_show(tab
->MText5b
);
4337 tab
->MText6
= gtk_label_new("s");
4338 gtk_widget_show(tab
->MText6
);
4339 tab
->MText7
= gtk_label_new("ns");
4340 gtk_widget_show(tab
->MText7
);
4342 tab
->MEntry1
= gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4343 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab
->MEntry1
),0);
4344 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab
->MEntry1
),TRUE
);
4345 gtk_widget_show(tab
->MEntry1
);
4346 tab
->MEntry2
= gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4347 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab
->MEntry2
),0);
4348 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab
->MEntry2
),TRUE
);
4349 gtk_widget_show(tab
->MEntry2
);
4350 tab
->MEntry3
= gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4351 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab
->MEntry3
),0);
4352 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab
->MEntry3
),TRUE
);
4353 gtk_widget_show(tab
->MEntry3
);
4354 tab
->MEntry4
= gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4355 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab
->MEntry4
),0);
4356 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab
->MEntry4
),TRUE
);
4357 gtk_widget_show(tab
->MEntry4
);
4358 tab
->MEntry5
= gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4359 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab
->MEntry5
),0);
4360 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab
->MEntry5
),TRUE
);
4361 gtk_widget_show(tab
->MEntry5
);
4362 tab
->MEntry6
= gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4363 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab
->MEntry6
),0);
4364 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab
->MEntry6
),TRUE
);
4365 gtk_widget_show(tab
->MEntry6
);
4368 GtkWidget
*temp_widget
;
4370 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MText1
, FALSE
, FALSE
, 0);
4371 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEntry1
, FALSE
, FALSE
, 0);
4372 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MText2
, FALSE
, FALSE
, 0);
4373 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEntry2
, FALSE
, FALSE
, 0);
4374 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MText3a
, FALSE
, FALSE
, 0);
4375 temp_widget
= gtk_vseparator_new();
4376 gtk_widget_show(temp_widget
);
4377 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), temp_widget
, FALSE
, FALSE
, 0);
4378 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MText3b
, FALSE
, FALSE
, 0);
4379 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEntry3
, FALSE
, FALSE
, 0);
4380 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MText4
, FALSE
, FALSE
, 0);
4381 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEntry4
, FALSE
, FALSE
, 0);
4382 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MText5a
, FALSE
, FALSE
, 0);
4383 temp_widget
= gtk_vseparator_new();
4384 gtk_widget_show(temp_widget
);
4385 gtk_box_pack_end (GTK_BOX (tab
->MTimebar
), tab
->MText7
, FALSE
, FALSE
, 0);
4386 gtk_box_pack_end (GTK_BOX (tab
->MTimebar
), tab
->MEntry6
, FALSE
, FALSE
, 0);
4387 gtk_box_pack_end (GTK_BOX (tab
->MTimebar
), tab
->MText6
, FALSE
, FALSE
, 0);
4388 gtk_box_pack_end (GTK_BOX (tab
->MTimebar
), tab
->MEntry5
, FALSE
, FALSE
, 0);
4389 gtk_box_pack_end (GTK_BOX (tab
->MTimebar
), tab
->MText5b
, FALSE
, FALSE
, 0);
4390 gtk_box_pack_end (GTK_BOX (tab
->MTimebar
), temp_widget
, FALSE
, FALSE
, 0);
4393 gtk_box_pack_end(GTK_BOX(tab
->vbox
),
4395 FALSE
, /* Do not expand */
4396 FALSE
, /* Fill has no effect here (expand false) */
4397 0); /* No padding */
4399 gtk_box_pack_end(GTK_BOX(tab
->vbox
),
4401 FALSE
, /* Do not expand */
4402 FALSE
, /* Fill has no effect here (expand false) */
4403 0); /* No padding */
4405 g_object_set_data(G_OBJECT(tab
->viewer_container
), "focused_viewer", NULL
);
4411 // Display a label with a X
4412 GtkWidget *w_hbox = gtk_hbox_new(FALSE, 4);
4413 GtkWidget *w_label = gtk_label_new (label);
4414 GtkWidget *pixmap = create_pixmap(GTK_WIDGET(notebook), "close.png");
4415 GtkWidget *w_button = gtk_button_new ();
4416 gtk_container_add(GTK_CONTAINER(w_button), pixmap);
4417 //GtkWidget *w_button = gtk_button_new_with_label("x");
4419 gtk_button_set_relief(GTK_BUTTON(w_button), GTK_RELIEF_NONE);
4421 gtk_box_pack_start(GTK_BOX(w_hbox), w_label, TRUE, TRUE, 0);
4422 gtk_box_pack_end(GTK_BOX(w_hbox), w_button, FALSE,
4425 g_signal_connect_swapped (w_button, "clicked",
4426 G_CALLBACK (on_close_tab_X_clicked),
4429 gtk_widget_set_state(w_button, GTK_STATE_ACTIVE);
4431 gtk_widget_show (w_label);
4432 gtk_widget_show (pixmap);
4433 gtk_widget_show (w_button);
4434 gtk_widget_show (w_hbox);
4436 tab->label = w_hbox;
4440 tab
->label
= gtk_label_new (label
);
4442 gtk_widget_show(tab
->label
);
4443 gtk_widget_show(tab
->scrollbar
);
4444 gtk_widget_show(tab
->viewer_container
);
4445 gtk_widget_show(tab
->vbox
);
4446 //gtk_widget_show(tab->multivpaned);
4449 /* Start with empty events requests list */
4450 tab
->events_requests
= NULL
;
4451 tab
->events_request_pending
= FALSE
;
4453 g_object_set_data_full(
4454 G_OBJECT(tab
->vbox
),
4457 (GDestroyNotify
)tab_destructor
);
4459 g_signal_connect(G_OBJECT(tab
->scrollbar
), "value-changed",
4460 G_CALLBACK(scroll_value_changed_cb
), tab
);
4462 g_signal_connect ((gpointer
) tab
->MEntry1
, "value-changed",
4463 G_CALLBACK (on_MEntry1_value_changed
),
4465 g_signal_connect ((gpointer
) tab
->MEntry2
, "value-changed",
4466 G_CALLBACK (on_MEntry2_value_changed
),
4468 g_signal_connect ((gpointer
) tab
->MEntry3
, "value-changed",
4469 G_CALLBACK (on_MEntry3_value_changed
),
4471 g_signal_connect ((gpointer
) tab
->MEntry4
, "value-changed",
4472 G_CALLBACK (on_MEntry4_value_changed
),
4474 g_signal_connect ((gpointer
) tab
->MEntry5
, "value-changed",
4475 G_CALLBACK (on_MEntry5_value_changed
),
4477 g_signal_connect ((gpointer
) tab
->MEntry6
, "value-changed",
4478 G_CALLBACK (on_MEntry6_value_changed
),
4481 //g_signal_connect(G_OBJECT(tab->scrollbar), "changed",
4482 // G_CALLBACK(scroll_value_changed_cb), tab);
4485 //insert tab into notebook
4486 gtk_notebook_append_page(notebook
,
4489 list
= gtk_container_get_children(GTK_CONTAINER(notebook
));
4490 gtk_notebook_set_current_page(notebook
,g_list_length(list
)-1);
4491 // always show : not if(g_list_length(list)>1)
4492 gtk_notebook_set_show_tabs(notebook
, TRUE
);
4498 * execute_events_requests
4500 * Idle function that executes the pending requests for a tab.
4502 * @return return value : TRUE : keep the idle function, FALSE : remove it.
4504 gboolean
execute_events_requests(Tab
*tab
)
4506 return ( lttvwindow_process_pending_requests(tab
) );