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
,
172 if(GTK_IS_TREE_VIEW(widget
)) {
173 gtk_tree_view_set_headers_clickable(widget
, TRUE
);
175 gtk_widget_add_events(widget
, GDK_BUTTON_PRESS_MASK
);
176 g_signal_connect (G_OBJECT(widget
),
177 "button-press-event",
178 G_CALLBACK (viewer_grab_focus
),
182 /* insert_viewer function constructs an instance of a viewer first,
183 * then inserts the widget of the instance into the container of the
188 insert_viewer_wrap(GtkWidget
*menuitem
, gpointer user_data
)
192 insert_viewer((GtkWidget
*)menuitem
, (lttvwindow_viewer_constructor
)user_data
);
193 // selected_hook(&val);
197 /* internal functions */
198 void insert_viewer(GtkWidget
* widget
, lttvwindow_viewer_constructor constructor
)
200 GtkWidget
* viewer_container
;
201 MainWindow
* mw_data
= get_window_data_struct(widget
);
202 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
204 LttvTracesetSelector
* s
;
205 TimeInterval
* time_interval
;
206 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
207 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
211 tab
= create_new_tab(widget
, NULL
);
213 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
216 viewer_container
= tab
->viewer_container
;
218 s
= construct_traceset_selector(tab
->traceset_info
->traceset
);
219 viewer
= (GtkWidget
*)constructor(tab
);
222 //gtk_multivpaned_widget_add(GTK_MULTIVPANED(multivpaned), viewer);
224 gtk_box_pack_end(GTK_BOX(viewer_container
),
230 /* We want to connect the viewer_grab_focus to EVERY
231 * child of this widget. The little trick is to get each child
232 * of each GTK_CONTAINER, even subchildren.
234 connect_focus_recursive(viewer
, viewer
);
239 * Function to set/update traceset for the viewers
240 * @param tab viewer's tab
241 * @param traceset traceset of the main window.
243 * 0 : traceset updated
244 * 1 : no traceset hooks to update; not an error.
247 int SetTraceset(Tab
* tab
, LttvTraceset
*traceset
)
249 LttvTracesetContext
*tsc
=
250 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
251 TimeInterval time_span
= tsc
->time_span
;
252 TimeWindow new_time_window
;
253 LttTime new_current_time
;
255 /* Set the tab's time window and current time if
257 if(ltt_time_compare(tab
->time_window
.start_time
, time_span
.start_time
) < 0
258 || ltt_time_compare( ltt_time_add(tab
->time_window
.start_time
,
259 tab
->time_window
.time_width
),
260 time_span
.end_time
) > 0) {
261 new_time_window
.start_time
= time_span
.start_time
;
263 new_current_time
= time_span
.start_time
;
267 if(DEFAULT_TIME_WIDTH_S
< time_span
.end_time
.tv_sec
)
268 tmp_time
.tv_sec
= DEFAULT_TIME_WIDTH_S
;
270 tmp_time
.tv_sec
= time_span
.end_time
.tv_sec
;
271 tmp_time
.tv_nsec
= 0;
272 new_time_window
.time_width
= tmp_time
;
274 time_change_manager(tab
, new_time_window
);
275 current_time_change_manager(tab
, new_current_time
);
279 GtkAdjustment
*adjustment
= gtk_range_get_adjustment(GTK_RANGE(tab
->scrollbar
));
280 LttTime upper
= ltt_time_sub(time_span
.end_time
, time_span
.start_time
);
282 g_object_set(G_OBJECT(adjustment
),
286 ltt_time_to_double(upper
)
287 * NANOSECONDS_PER_SECOND
, /* upper */
289 ltt_time_to_double(tab
->time_window
.time_width
)
290 / SCROLL_STEP_PER_PAGE
291 * NANOSECONDS_PER_SECOND
, /* step increment */
293 ltt_time_to_double(tab
->time_window
.time_width
)
294 * NANOSECONDS_PER_SECOND
, /* page increment */
296 ltt_time_to_double(tab
->time_window
.time_width
)
297 * NANOSECONDS_PER_SECOND
, /* page size */
299 gtk_adjustment_changed(adjustment
);
301 g_object_set(G_OBJECT(adjustment
),
304 ltt_time_sub(tab
->time_window
.start_time
, time_span
.start_time
))
305 * NANOSECONDS_PER_SECOND
, /* value */
307 gtk_adjustment_value_changed(adjustment
);
309 /* set the time bar. The value callbacks will change their nsec themself */
311 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry1
),
312 (double)time_span
.start_time
.tv_sec
,
313 (double)time_span
.end_time
.tv_sec
);
316 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry3
),
317 (double)time_span
.start_time
.tv_sec
,
318 (double)time_span
.end_time
.tv_sec
);
320 /* current seconds */
321 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry5
),
322 (double)time_span
.start_time
.tv_sec
,
323 (double)time_span
.end_time
.tv_sec
);
326 /* Finally, call the update hooks of the viewers */
328 LttvAttributeValue value
;
332 g_assert( lttv_iattribute_find_by_path(tab
->attributes
,
333 "hooks/updatetraceset", LTTV_POINTER
, &value
));
335 tmp
= (LttvHooks
*)*(value
.v_pointer
);
336 if(tmp
== NULL
) retval
= 1;
337 else lttv_hooks_call(tmp
,traceset
);
344 * Function to set/update filter for the viewers
345 * @param tab viewer's tab
346 * @param filter filter of the main window.
349 * 0 : filters updated
350 * 1 : no filter hooks to update; not an error.
353 int SetFilter(Tab
* tab
, gpointer filter
)
356 LttvAttributeValue value
;
358 g_assert(lttv_iattribute_find_by_path(tab
->attributes
,
359 "hooks/updatefilter", LTTV_POINTER
, &value
));
361 tmp
= (LttvHooks
*)*(value
.v_pointer
);
363 if(tmp
== NULL
) return 1;
364 lttv_hooks_call(tmp
,filter
);
372 * Function to redraw each viewer belonging to the current tab
373 * @param tab viewer's tab
376 void update_traceset(Tab
*tab
)
378 LttvAttributeValue value
;
380 g_assert(lttv_iattribute_find_by_path(tab
->attributes
,
381 "hooks/updatetraceset", LTTV_POINTER
, &value
));
382 tmp
= (LttvHooks
*)*(value
.v_pointer
);
383 if(tmp
== NULL
) return;
384 lttv_hooks_call(tmp
, NULL
);
388 /* get_label function is used to get user input, it displays an input
389 * box, which allows user to input a string
392 void get_label_string (GtkWidget
* text
, gchar
* label
)
394 GtkEntry
* entry
= (GtkEntry
*)text
;
395 if(strlen(gtk_entry_get_text(entry
))!=0)
396 strcpy(label
,gtk_entry_get_text(entry
));
399 gboolean
get_label(MainWindow
* mw
, gchar
* str
, gchar
* dialogue_title
, gchar
* label_str
)
401 GtkWidget
* dialogue
;
406 dialogue
= gtk_dialog_new_with_buttons(dialogue_title
,NULL
,
408 GTK_STOCK_OK
,GTK_RESPONSE_ACCEPT
,
409 GTK_STOCK_CANCEL
,GTK_RESPONSE_REJECT
,
412 label
= gtk_label_new(label_str
);
413 gtk_widget_show(label
);
415 text
= gtk_entry_new();
416 gtk_widget_show(text
);
418 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialogue
)->vbox
), label
,TRUE
, TRUE
,0);
419 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialogue
)->vbox
), text
,FALSE
, FALSE
,0);
421 id
= gtk_dialog_run(GTK_DIALOG(dialogue
));
423 case GTK_RESPONSE_ACCEPT
:
424 get_label_string(text
,str
);
425 gtk_widget_destroy(dialogue
);
427 case GTK_RESPONSE_REJECT
:
429 gtk_widget_destroy(dialogue
);
436 /* get_window_data_struct function is actually a lookup function,
437 * given a widget which is in the tree of the main window, it will
438 * return the MainWindow data structure associated with main window
441 MainWindow
* get_window_data_struct(GtkWidget
* widget
)
444 MainWindow
* mw_data
;
446 mw
= lookup_widget(widget
, "MWindow");
448 g_printf("Main window does not exist\n");
452 mw_data
= (MainWindow
*) g_object_get_data(G_OBJECT(mw
),"main_window_data");
454 g_printf("Main window data does not exist\n");
461 /* create_new_window function, just constructs a new main window
464 void create_new_window(GtkWidget
* widget
, gpointer user_data
, gboolean clone
)
466 MainWindow
* parent
= get_window_data_struct(widget
);
469 g_printf("Clone : use the same traceset\n");
470 construct_main_window(parent
);
472 g_printf("Empty : traceset is set to NULL\n");
473 construct_main_window(NULL
);
477 /* Get the currently focused viewer.
478 * If no viewer is focused, use the first one.
480 * If no viewer available, return NULL.
482 GtkWidget
*viewer_container_focus(GtkWidget
*container
)
486 widget
= (GtkWidget
*)g_object_get_data(G_OBJECT(container
),
490 g_debug("no widget focused");
491 GList
*children
= gtk_container_get_children(GTK_CONTAINER(container
));
494 widget
= GTK_WIDGET(children
->data
);
495 g_object_set_data(G_OBJECT(container
),
505 gint
viewer_container_position(GtkWidget
*container
, GtkWidget
*child
)
508 if(child
== NULL
) return -1;
511 GValue value
= { 0, };
512 g_value_init(&value
, G_TYPE_INT
);
513 gtk_container_child_get_property(GTK_CONTAINER(container
),
517 pos
= g_value_get_int(&value
);
523 /* move_*_viewer functions move the selected view up/down in
527 void move_down_viewer(GtkWidget
* widget
, gpointer user_data
)
529 MainWindow
* mw
= get_window_data_struct(widget
);
530 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
532 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
533 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
539 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
542 //gtk_multivpaned_widget_move_up(GTK_MULTIVPANED(tab->multivpaned));
544 /* change the position in the vbox */
545 GtkWidget
*focus_widget
;
547 focus_widget
= viewer_container_focus(tab
->viewer_container
);
548 position
= viewer_container_position(tab
->viewer_container
, focus_widget
);
551 /* can move up one position */
552 gtk_box_reorder_child(GTK_BOX(tab
->viewer_container
),
559 void move_up_viewer(GtkWidget
* widget
, gpointer user_data
)
561 MainWindow
* mw
= get_window_data_struct(widget
);
562 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
564 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
565 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
571 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
574 //gtk_multivpaned_widget_move_down(GTK_MULTIVPANED(tab->multivpaned));
575 /* change the position in the vbox */
576 GtkWidget
*focus_widget
;
578 focus_widget
= viewer_container_focus(tab
->viewer_container
);
579 position
= viewer_container_position(tab
->viewer_container
, focus_widget
);
583 g_list_length(gtk_container_get_children(
584 GTK_CONTAINER(tab
->viewer_container
)))-1
586 /* can move down one position */
587 gtk_box_reorder_child(GTK_BOX(tab
->viewer_container
),
595 /* delete_viewer deletes the selected viewer in the current tab
598 void delete_viewer(GtkWidget
* widget
, gpointer user_data
)
600 MainWindow
* mw
= get_window_data_struct(widget
);
601 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
603 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
604 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
610 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
613 //gtk_multivpaned_widget_delete(GTK_MULTIVPANED(tab->multivpaned));
615 GtkWidget
*focus_widget
= viewer_container_focus(tab
->viewer_container
);
617 if(focus_widget
!= NULL
)
618 gtk_widget_destroy(focus_widget
);
620 g_object_set_data(G_OBJECT(tab
->viewer_container
), "focused_viewer", NULL
);
624 /* open_traceset will open a traceset saved in a file
625 * Right now, it is not finished yet, (not working)
629 void open_traceset(GtkWidget
* widget
, gpointer user_data
)
633 LttvTraceset
* traceset
;
634 MainWindow
* mw_data
= get_window_data_struct(widget
);
635 GtkFileSelection
* file_selector
=
636 (GtkFileSelection
*)gtk_file_selection_new("Select a traceset");
638 gtk_file_selection_hide_fileop_buttons(file_selector
);
640 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
642 case GTK_RESPONSE_ACCEPT
:
643 case GTK_RESPONSE_OK
:
644 dir
= gtk_file_selection_get_selections (file_selector
);
645 traceset
= lttv_traceset_load(dir
[0]);
646 g_printf("Open a trace set %s\n", dir
[0]);
649 case GTK_RESPONSE_REJECT
:
650 case GTK_RESPONSE_CANCEL
:
652 gtk_widget_destroy((GtkWidget
*)file_selector
);
658 static void events_request_free(EventsRequest
*events_request
)
660 if(events_request
== NULL
) return;
662 if(events_request
->start_position
!= NULL
)
663 lttv_traceset_context_position_destroy(events_request
->start_position
);
664 if(events_request
->end_position
!= NULL
)
665 lttv_traceset_context_position_destroy(events_request
->end_position
);
666 if(events_request
->before_chunk_traceset
!= NULL
)
667 lttv_hooks_destroy(events_request
->before_chunk_traceset
);
668 if(events_request
->before_chunk_trace
!= NULL
)
669 lttv_hooks_destroy(events_request
->before_chunk_trace
);
670 if(events_request
->before_chunk_tracefile
!= NULL
)
671 lttv_hooks_destroy(events_request
->before_chunk_tracefile
);
672 if(events_request
->event
!= NULL
)
673 lttv_hooks_destroy(events_request
->event
);
674 if(events_request
->event_by_id
!= NULL
)
675 lttv_hooks_by_id_destroy(events_request
->event_by_id
);
676 if(events_request
->after_chunk_tracefile
!= NULL
)
677 lttv_hooks_destroy(events_request
->after_chunk_tracefile
);
678 if(events_request
->after_chunk_trace
!= NULL
)
679 lttv_hooks_destroy(events_request
->after_chunk_trace
);
680 if(events_request
->after_chunk_traceset
!= NULL
)
681 lttv_hooks_destroy(events_request
->after_chunk_traceset
);
682 if(events_request
->before_request
!= NULL
)
683 lttv_hooks_destroy(events_request
->before_request
);
684 if(events_request
->after_request
!= NULL
)
685 lttv_hooks_destroy(events_request
->after_request
);
687 g_free(events_request
);
692 /* lttvwindow_process_pending_requests
694 * This internal function gets called by g_idle, taking care of the pending
695 * requests. It is responsible for concatenation of time intervals and position
696 * requests. It does it with the following algorithm organizing process traceset
697 * calls. Here is the detailed description of the way it works :
699 * - Events Requests Servicing Algorithm
701 * Data structures necessary :
703 * List of requests added to context : list_in
704 * List of requests not added to context : list_out
709 * list_out : many events requests
711 * FIXME : insert rest of algorithm here
715 #define list_out tab->events_requests
717 gboolean
lttvwindow_process_pending_requests(Tab
*tab
)
719 unsigned max_nb_events
;
723 LttvTracesetContext
*tsc
;
724 LttvTracefileContext
*tfc
;
725 GSList
*list_in
= NULL
;
729 LttvTracesetContextPosition
*end_position
;
732 g_critical("Foreground processing : tab does not exist. Processing removed.");
736 /* There is no events requests pending : we should never have been called! */
737 g_assert(g_slist_length(list_out
) != 0);
739 tsc
= LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
741 //set the cursor to be X shape, indicating that the computer is busy in doing its job
743 new = gdk_cursor_new(GDK_X_CURSOR
);
744 widget
= lookup_widget(tab
->mw
->mwindow
, "MToolbar1");
745 win
= gtk_widget_get_parent_window(widget
);
746 gdk_window_set_cursor(win
, new);
747 gdk_cursor_unref(new);
748 gdk_window_stick(win
);
749 gdk_window_unstick(win
);
752 g_debug("SIZE events req len : %d", g_slist_length(list_out
));
754 /* Preliminary check for no trace in traceset */
755 /* Unregister the routine if empty, empty list_out too */
756 if(lttv_traceset_number(tsc
->ts
) == 0) {
758 /* - For each req in list_out */
759 GSList
*iter
= list_out
;
761 while(iter
!= NULL
) {
763 gboolean remove
= FALSE
;
764 gboolean free_data
= FALSE
;
765 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
767 /* - Call end request for req */
768 if(events_request
->servicing
== TRUE
)
769 lttv_hooks_call(events_request
->after_request
, (gpointer
)tsc
);
771 /* - remove req from list_out */
772 /* Destroy the request */
779 GSList
*remove_iter
= iter
;
781 iter
= g_slist_next(iter
);
782 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
783 list_out
= g_slist_remove_link(list_out
, remove_iter
);
784 } else { // not remove
785 iter
= g_slist_next(iter
);
790 /* 0.1 Lock Traces */
795 iter_trace
<lttv_traceset_number(tsc
->ts
);
797 LttvTrace
*trace_v
= lttv_traceset_get(tsc
->ts
, iter_trace
);
799 if(lttvwindowtraces_lock(trace_v
) != 0) {
800 g_critical("Foreground processing : Unable to get trace lock");
801 return TRUE
; /* Cannot get lock, try later */
806 /* 0.2 Seek tracefiles positions to context position */
807 lttv_process_traceset_synchronize_tracefiles(tsc
);
810 /* Events processing algorithm implementation */
811 /* Warning : the gtk_events_pending takes a LOT of cpu time. So what we do
812 * instead is to leave the control to GTK and take it back.
814 /* A. Servicing loop */
815 //while( (g_slist_length(list_in) != 0 || g_slist_length(list_out) != 0)) {
816 if((g_slist_length(list_in
) != 0 || g_slist_length(list_out
) != 0)) {
818 /* 1. If list_in is empty (need a seek) */
819 if( g_slist_length(list_in
) == 0 ) {
821 /* list in is empty, need a seek */
823 /* 1.1 Add requests to list_in */
824 GSList
*ltime
= NULL
;
828 /* 1.1.1 Find all time requests with the lowest start time in list_out
831 if(g_slist_length(list_out
) > 0)
832 ltime
= g_slist_append(ltime
, g_slist_nth_data(list_out
, 0));
833 for(iter
=g_slist_nth(list_out
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
834 /* Find all time requests with the lowest start time in list_out */
835 guint index_ltime
= g_array_index(ltime
, guint
, 0);
836 EventsRequest
*event_request_ltime
= (EventsRequest
*)g_slist_nth_data(ltime
, 0);
837 EventsRequest
*event_request_list_out
= (EventsRequest
*)iter
->data
;
840 comp
= ltt_time_compare(event_request_ltime
->start_time
,
841 event_request_list_out
->start_time
);
843 ltime
= g_slist_append(ltime
, event_request_list_out
);
845 /* Remove all elements from ltime, and add current */
847 ltime
= g_slist_delete_link(ltime
, g_slist_nth(ltime
, 0));
848 ltime
= g_slist_append(ltime
, event_request_list_out
);
852 /* 1.1.2 Find all position requests with the lowest position in list_out
855 if(g_slist_length(list_out
) > 0)
856 lpos
= g_slist_append(lpos
, g_slist_nth_data(list_out
, 0));
857 for(iter
=g_slist_nth(list_out
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
858 /* Find all position requests with the lowest position in list_out */
859 EventsRequest
*event_request_lpos
= (EventsRequest
*)g_slist_nth_data(lpos
, 0);
860 EventsRequest
*event_request_list_out
= (EventsRequest
*)iter
->data
;
863 if(event_request_lpos
->start_position
!= NULL
864 && event_request_list_out
->start_position
!= NULL
)
866 comp
= lttv_traceset_context_pos_pos_compare
867 (event_request_lpos
->start_position
,
868 event_request_list_out
->start_position
);
873 lpos
= g_slist_append(lpos
, event_request_list_out
);
875 /* Remove all elements from lpos, and add current */
877 lpos
= g_slist_delete_link(lpos
, g_slist_nth(lpos
, 0));
878 lpos
= g_slist_append(lpos
, event_request_list_out
);
883 EventsRequest
*event_request_lpos
= (EventsRequest
*)g_slist_nth_data(lpos
, 0);
884 EventsRequest
*event_request_ltime
= (EventsRequest
*)g_slist_nth_data(ltime
, 0);
885 LttTime lpos_start_time
;
887 if(event_request_lpos
!= NULL
888 && event_request_lpos
->start_position
!= NULL
) {
889 lpos_start_time
= lttv_traceset_context_position_get_time(
890 event_request_lpos
->start_position
);
893 /* 1.1.3 If lpos.start time < ltime */
894 if(event_request_lpos
!= NULL
895 && event_request_lpos
->start_position
!= NULL
896 && ltt_time_compare(lpos_start_time
,
897 event_request_ltime
->start_time
)<0) {
898 /* Add lpos to list_in, remove them from list_out */
899 for(iter
=lpos
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
901 EventsRequest
*event_request_lpos
=
902 (EventsRequest
*)iter
->data
;
904 list_in
= g_slist_append(list_in
, event_request_lpos
);
905 /* Remove from list_out */
906 list_out
= g_slist_remove(list_out
, event_request_lpos
);
909 /* 1.1.4 (lpos.start time >= ltime) */
910 /* Add ltime to list_in, remove them from list_out */
912 for(iter
=ltime
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
914 EventsRequest
*event_request_ltime
=
915 (EventsRequest
*)iter
->data
;
917 list_in
= g_slist_append(list_in
, event_request_ltime
);
918 /* Remove from list_out */
919 list_out
= g_slist_remove(list_out
, event_request_ltime
);
929 tfc
= lttv_traceset_context_get_current_tfc(tsc
);
930 g_assert(g_slist_length(list_in
)>0);
931 EventsRequest
*events_request
= g_slist_nth_data(list_in
, 0);
934 /* 1.2.1 If first request in list_in is a time request */
935 if(events_request
->start_position
== NULL
) {
936 /* - If first req in list_in start time != current time */
937 if(tfc
== NULL
|| ltt_time_compare(events_request
->start_time
,
938 tfc
->timestamp
) != 0)
939 /* - Seek to that time */
940 g_debug("SEEK TIME : %lu, %lu", events_request
->start_time
.tv_sec
,
941 events_request
->start_time
.tv_nsec
);
942 //lttv_process_traceset_seek_time(tsc, events_request->start_time);
943 lttv_state_traceset_seek_time_closest(LTTV_TRACESET_STATE(tsc
),
944 events_request
->start_time
);
946 /* Process the traceset with only state hooks */
948 lttv_process_traceset_middle(tsc
,
949 events_request
->start_time
,
955 /* Else, the first request in list_in is a position request */
956 /* If first req in list_in pos != current pos */
957 g_assert(events_request
->start_position
!= NULL
);
958 g_debug("SEEK POS time : %lu, %lu",
959 lttv_traceset_context_position_get_time(
960 events_request
->start_position
).tv_sec
,
961 lttv_traceset_context_position_get_time(
962 events_request
->start_position
).tv_nsec
);
964 g_debug("SEEK POS context time : %lu, %lu",
965 lttv_traceset_context_get_current_tfc(tsc
)->timestamp
.tv_sec
,
966 lttv_traceset_context_get_current_tfc(tsc
)->timestamp
.tv_nsec
);
967 g_assert(events_request
->start_position
!= NULL
);
968 if(lttv_traceset_context_ctx_pos_compare(tsc
,
969 events_request
->start_position
) != 0) {
970 /* 1.2.2.1 Seek to that position */
971 g_debug("SEEK POSITION");
972 //lttv_process_traceset_seek_position(tsc, events_request->start_position);
973 pos_time
= lttv_traceset_context_position_get_time(
974 events_request
->start_position
);
976 lttv_state_traceset_seek_time_closest(LTTV_TRACESET_STATE(tsc
),
979 /* Process the traceset with only state hooks */
981 lttv_process_traceset_middle(tsc
,
984 events_request
->start_position
);
985 g_assert(lttv_traceset_context_ctx_pos_compare(tsc
,
986 events_request
->start_position
) == 0);
993 /* 1.3 Add hooks and call before request for all list_in members */
997 for(iter
=list_in
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
998 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
999 /* 1.3.1 If !servicing */
1000 if(events_request
->servicing
== FALSE
) {
1001 /* - begin request hooks called
1002 * - servicing = TRUE
1004 lttv_hooks_call(events_request
->before_request
, (gpointer
)tsc
);
1005 events_request
->servicing
= TRUE
;
1007 /* 1.3.2 call before chunk
1008 * 1.3.3 events hooks added
1010 lttv_process_traceset_begin(tsc
, events_request
->before_chunk_traceset
,
1011 events_request
->before_chunk_trace
,
1012 events_request
->before_chunk_tracefile
,
1013 events_request
->event
,
1014 events_request
->event_by_id
);
1018 /* 2. Else, list_in is not empty, we continue a read */
1021 /* 2.0 For each req of list_in */
1022 GSList
*iter
= list_in
;
1024 while(iter
!= NULL
) {
1026 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1028 /* - Call before chunk
1029 * - events hooks added
1031 lttv_process_traceset_begin(tsc
, events_request
->before_chunk_traceset
,
1032 events_request
->before_chunk_trace
,
1033 events_request
->before_chunk_tracefile
,
1034 events_request
->event
,
1035 events_request
->event_by_id
);
1037 iter
= g_slist_next(iter
);
1042 tfc
= lttv_traceset_context_get_current_tfc(tsc
);
1044 /* 2.1 For each req of list_out */
1045 GSList
*iter
= list_out
;
1047 while(iter
!= NULL
) {
1049 gboolean remove
= FALSE
;
1050 gboolean free_data
= FALSE
;
1051 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1053 /* if req.start time == current context time
1054 * or req.start position == current position*/
1055 if( ltt_time_compare(events_request
->start_time
,
1056 tfc
->timestamp
) == 0
1058 (events_request
->start_position
!= NULL
1060 lttv_traceset_context_ctx_pos_compare(tsc
,
1061 events_request
->start_position
) == 0)
1063 /* - Add to list_in, remove from list_out */
1064 list_in
= g_slist_append(list_in
, events_request
);
1068 /* - If !servicing */
1069 if(events_request
->servicing
== FALSE
) {
1070 /* - begin request hooks called
1071 * - servicing = TRUE
1073 lttv_hooks_call(events_request
->before_request
, (gpointer
)tsc
);
1074 events_request
->servicing
= TRUE
;
1076 /* call before chunk
1077 * events hooks added
1079 lttv_process_traceset_begin(tsc
, events_request
->before_chunk_traceset
,
1080 events_request
->before_chunk_trace
,
1081 events_request
->before_chunk_tracefile
,
1082 events_request
->event
,
1083 events_request
->event_by_id
);
1089 GSList
*remove_iter
= iter
;
1091 iter
= g_slist_next(iter
);
1092 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
1093 list_out
= g_slist_remove_link(list_out
, remove_iter
);
1094 } else { // not remove
1095 iter
= g_slist_next(iter
);
1101 /* 3. Find end criterions */
1106 /* 3.1.1 Find lowest end time in list_in */
1107 g_assert(g_slist_length(list_in
)>0);
1108 end_time
= ((EventsRequest
*)g_slist_nth_data(list_in
,0))->end_time
;
1110 for(iter
=g_slist_nth(list_in
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
1111 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1113 if(ltt_time_compare(events_request
->end_time
,
1115 end_time
= events_request
->end_time
;
1118 /* 3.1.2 Find lowest start time in list_out */
1119 for(iter
=list_out
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
1120 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1122 if(ltt_time_compare(events_request
->start_time
,
1124 end_time
= events_request
->start_time
;
1129 /* 3.2 Number of events */
1131 /* 3.2.1 Find lowest number of events in list_in */
1134 end_nb_events
= ((EventsRequest
*)g_slist_nth_data(list_in
,0))->num_events
;
1136 for(iter
=g_slist_nth(list_in
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
1137 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1139 if(events_request
->num_events
< end_nb_events
)
1140 end_nb_events
= events_request
->num_events
;
1143 /* 3.2.2 Use min(CHUNK_NUM_EVENTS, min num events in list_in) as
1146 end_nb_events
= MIN(CHUNK_NUM_EVENTS
, end_nb_events
);
1150 /* 3.3 End position */
1152 /* 3.3.1 Find lowest end position in list_in */
1155 end_position
=((EventsRequest
*)g_slist_nth_data(list_in
,0))->end_position
;
1157 for(iter
=g_slist_nth(list_in
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
1158 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1160 if(events_request
->end_position
!= NULL
&& end_position
!= NULL
&&
1161 lttv_traceset_context_pos_pos_compare(events_request
->end_position
,
1163 end_position
= events_request
->end_position
;
1168 /* 3.3.2 Find lowest start position in list_out */
1171 for(iter
=list_out
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
1172 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1174 if(events_request
->end_position
!= NULL
&& end_position
!= NULL
&&
1175 lttv_traceset_context_pos_pos_compare(events_request
->end_position
,
1177 end_position
= events_request
->end_position
;
1182 /* 4. Call process traceset middle */
1183 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
);
1184 count
= lttv_process_traceset_middle(tsc
, end_time
, end_nb_events
, end_position
);
1186 tfc
= lttv_traceset_context_get_current_tfc(tsc
);
1188 g_debug("Context time after middle : %lu, %lu", tfc
->timestamp
.tv_sec
,
1189 tfc
->timestamp
.tv_nsec
);
1191 g_debug("End of trace reached after middle.");
1195 /* 5. After process traceset middle */
1196 tfc
= lttv_traceset_context_get_current_tfc(tsc
);
1198 /* - if current context time > traceset.end time */
1199 if(tfc
== NULL
|| ltt_time_compare(tfc
->timestamp
,
1200 tsc
->time_span
.end_time
) > 0) {
1201 /* - For each req in list_in */
1202 GSList
*iter
= list_in
;
1204 while(iter
!= NULL
) {
1206 gboolean remove
= FALSE
;
1207 gboolean free_data
= FALSE
;
1208 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1210 /* - Remove events hooks for req
1211 * - Call end chunk for req
1213 lttv_process_traceset_end(tsc
, events_request
->after_chunk_traceset
,
1214 events_request
->after_chunk_trace
,
1215 events_request
->after_chunk_tracefile
,
1216 events_request
->event
,
1217 events_request
->event_by_id
);
1218 /* - Call end request for req */
1219 lttv_hooks_call(events_request
->after_request
, (gpointer
)tsc
);
1221 /* - remove req from list_in */
1222 /* Destroy the request */
1229 GSList
*remove_iter
= iter
;
1231 iter
= g_slist_next(iter
);
1232 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
1233 list_in
= g_slist_remove_link(list_in
, remove_iter
);
1234 } else { // not remove
1235 iter
= g_slist_next(iter
);
1240 /* 5.1 For each req in list_in */
1241 GSList
*iter
= list_in
;
1243 while(iter
!= NULL
) {
1245 gboolean remove
= FALSE
;
1246 gboolean free_data
= FALSE
;
1247 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1249 /* - Remove events hooks for req
1250 * - Call end chunk for req
1252 lttv_process_traceset_end(tsc
, events_request
->after_chunk_traceset
,
1253 events_request
->after_chunk_trace
,
1254 events_request
->after_chunk_tracefile
,
1255 events_request
->event
,
1256 events_request
->event_by_id
);
1258 /* - req.num -= count */
1259 g_assert(events_request
->num_events
>= count
);
1260 events_request
->num_events
-= count
;
1262 g_assert(tfc
!= NULL
);
1263 /* - if req.num == 0
1265 * current context time >= req.end time
1267 * req.end pos == current pos
1269 * req.stop_flag == TRUE
1271 if( events_request
->num_events
== 0
1273 events_request
->stop_flag
== TRUE
1275 ltt_time_compare(tfc
->timestamp
,
1276 events_request
->end_time
) >= 0
1278 (events_request
->end_position
!= NULL
1280 lttv_traceset_context_ctx_pos_compare(tsc
,
1281 events_request
->end_position
) == 0)
1284 g_assert(events_request
->servicing
== TRUE
);
1285 /* - Call end request for req
1286 * - remove req from list_in */
1287 lttv_hooks_call(events_request
->after_request
, (gpointer
)tsc
);
1288 /* - remove req from list_in */
1289 /* Destroy the request */
1297 GSList
*remove_iter
= iter
;
1299 iter
= g_slist_next(iter
);
1300 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
1301 list_in
= g_slist_remove_link(list_in
, remove_iter
);
1302 } else { // not remove
1303 iter
= g_slist_next(iter
);
1309 /* End of removed servicing loop : leave control to GTK instead. */
1310 // if(gtk_events_pending()) break;
1313 /* B. When interrupted between chunks */
1316 GSList
*iter
= list_in
;
1318 /* 1. for each request in list_in */
1319 while(iter
!= NULL
) {
1321 gboolean remove
= FALSE
;
1322 gboolean free_data
= FALSE
;
1323 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1325 /* 1.1. Use current postition as start position */
1326 if(events_request
->start_position
!= NULL
)
1327 lttv_traceset_context_position_destroy(events_request
->start_position
);
1328 events_request
->start_position
= lttv_traceset_context_position_new();
1329 lttv_traceset_context_position_save(tsc
, events_request
->start_position
);
1331 /* 1.2. Remove start time */
1332 events_request
->start_time
= ltt_time_infinite
;
1334 /* 1.3. Move from list_in to list_out */
1337 list_out
= g_slist_append(list_out
, events_request
);
1342 GSList
*remove_iter
= iter
;
1344 iter
= g_slist_next(iter
);
1345 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
1346 list_in
= g_slist_remove_link(list_in
, remove_iter
);
1347 } else { // not remove
1348 iter
= g_slist_next(iter
);
1355 /* C Unlock Traces */
1357 //lttv_process_traceset_get_sync_data(tsc);
1362 iter_trace
<lttv_traceset_number(tsc
->ts
);
1364 LttvTrace
*trace_v
= lttv_traceset_get(tsc
->ts
, iter_trace
);
1366 lttvwindowtraces_unlock(trace_v
);
1371 //set the cursor back to normal
1372 gdk_window_set_cursor(win
, NULL
);
1375 g_assert(g_slist_length(list_in
) == 0);
1377 if( g_slist_length(list_out
) == 0 ) {
1378 /* Put tab's request pending flag back to normal */
1379 tab
->events_request_pending
= FALSE
;
1380 g_debug("remove the idle fct");
1381 return FALSE
; /* Remove the idle function */
1383 g_debug("leave the idle fct");
1384 return TRUE
; /* Leave the idle function */
1386 /* We do not use simili-round-robin, it may require to read 1 meg buffers
1387 * again and again if many tracesets use the same tracefiles. */
1388 /* Hack for round-robin idle functions */
1389 /* It will put the idle function at the end of the pool */
1390 /*g_idle_add_full((G_PRIORITY_HIGH_IDLE + 21),
1391 (GSourceFunc)execute_events_requests,
1401 /* add_trace_into_traceset_selector, each instance of a viewer has an associated
1402 * selector (filter), when a trace is added into traceset, the selector should
1403 * reflect the change. The function is used to update the selector
1406 void add_trace_into_traceset_selector(GtkWidget
* paned
, LttTrace
* t
)
1408 int j
, k
, m
, nb_tracefile
, nb_control
, nb_per_cpu
, nb_facility
, nb_event
;
1409 LttvTracesetSelector
* s
;
1410 LttvTraceSelector
* trace
;
1411 LttvTracefileSelector
* tracefile
;
1412 LttvEventtypeSelector
* eventtype
;
1418 w
= gtk_multivpaned_get_first_widget(GTK_MULTIVPANED(paned
));
1420 s
= g_object_get_data(G_OBJECT(w
), "Traceset_Selector");
1423 trace
= lttv_trace_selector_new(t
);
1424 lttv_traceset_selector_trace_add(s
, trace
);
1426 nb_facility
= ltt_trace_facility_number(t
);
1427 for(k
=0;k
<nb_facility
;k
++){
1428 fac
= ltt_trace_facility_get(t
,k
);
1429 nb_event
= (int) ltt_facility_eventtype_number(fac
);
1430 for(m
=0;m
<nb_event
;m
++){
1431 et
= ltt_facility_eventtype_get(fac
,m
);
1432 eventtype
= lttv_eventtype_selector_new(et
);
1433 lttv_trace_selector_eventtype_add(trace
, eventtype
);
1437 nb_control
= ltt_trace_control_tracefile_number(t
);
1438 nb_per_cpu
= ltt_trace_per_cpu_tracefile_number(t
);
1439 nb_tracefile
= nb_control
+ nb_per_cpu
;
1441 for(j
= 0 ; j
< nb_tracefile
; j
++) {
1443 tf
= ltt_trace_control_tracefile_get(t
, j
);
1445 tf
= ltt_trace_per_cpu_tracefile_get(t
, j
- nb_control
);
1446 tracefile
= lttv_tracefile_selector_new(tf
);
1447 lttv_trace_selector_tracefile_add(trace
, tracefile
);
1448 lttv_eventtype_selector_copy(trace
, tracefile
);
1450 }else g_warning("Module does not support filtering\n");
1452 w
= gtk_multivpaned_get_next_widget(GTK_MULTIVPANED(paned
));
1457 static void lttvwindow_add_trace(Tab
*tab
, LttvTrace
*trace_v
)
1459 LttvTraceset
*traceset
= tab
->traceset_info
->traceset
;
1461 guint num_traces
= lttv_traceset_number(traceset
);
1463 //Verify if trace is already present.
1464 for(i
=0; i
<num_traces
; i
++)
1466 LttvTrace
* trace
= lttv_traceset_get(traceset
, i
);
1467 if(trace
== trace_v
)
1471 //Keep a reference to the traces so they are not freed.
1472 for(i
=0; i
<lttv_traceset_number(traceset
); i
++)
1474 LttvTrace
* trace
= lttv_traceset_get(traceset
, i
);
1475 lttv_trace_ref(trace
);
1478 //remove state update hooks
1479 lttv_state_remove_event_hooks(
1480 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1482 lttv_context_fini(LTTV_TRACESET_CONTEXT(
1483 tab
->traceset_info
->traceset_context
));
1484 g_object_unref(tab
->traceset_info
->traceset_context
);
1486 lttv_traceset_add(traceset
, trace_v
);
1487 lttv_trace_ref(trace_v
); /* local ref */
1489 /* Create new context */
1490 tab
->traceset_info
->traceset_context
=
1491 g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
1493 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->
1498 //add state update hooks
1499 lttv_state_add_event_hooks(
1500 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1501 //Remove local reference to the traces.
1502 for(i
=0; i
<lttv_traceset_number(traceset
); i
++)
1504 LttvTrace
* trace
= lttv_traceset_get(traceset
, i
);
1505 lttv_trace_unref(trace
);
1509 //add_trace_into_traceset_selector(GTK_MULTIVPANED(tab->multivpaned), lttv_trace(trace_v));
1512 /* add_trace adds a trace into the current traceset. It first displays a
1513 * directory selection dialogue to let user choose a trace, then recreates
1514 * tracset_context, and redraws all the viewer of the current tab
1517 void add_trace(GtkWidget
* widget
, gpointer user_data
)
1520 LttvTrace
* trace_v
;
1521 LttvTraceset
* traceset
;
1523 char abs_path
[PATH_MAX
];
1526 MainWindow
* mw_data
= get_window_data_struct(widget
);
1527 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
1529 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
1530 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
1534 tab
= create_new_tab(widget
, NULL
);
1536 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
1539 GtkDirSelection
* file_selector
= (GtkDirSelection
*)gtk_dir_selection_new("Select a trace");
1540 gtk_dir_selection_hide_fileop_buttons(file_selector
);
1542 if(remember_trace_dir
[0] != '\0')
1543 gtk_dir_selection_set_filename(file_selector
, remember_trace_dir
);
1545 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
1547 case GTK_RESPONSE_ACCEPT
:
1548 case GTK_RESPONSE_OK
:
1549 dir
= gtk_dir_selection_get_dir (file_selector
);
1550 strncpy(remember_trace_dir
, dir
, PATH_MAX
);
1551 if(!dir
|| strlen(dir
) == 0){
1552 gtk_widget_destroy((GtkWidget
*)file_selector
);
1555 get_absolute_pathname(dir
, abs_path
);
1556 trace_v
= lttvwindowtraces_get_trace_by_name(abs_path
);
1557 if(trace_v
== NULL
) {
1558 trace
= ltt_trace_open(abs_path
);
1560 g_warning("cannot open trace %s", abs_path
);
1562 trace_v
= lttv_trace_new(trace
);
1563 lttvwindowtraces_add_trace(trace_v
);
1564 lttvwindow_add_trace(tab
, trace_v
);
1567 lttvwindow_add_trace(tab
, trace_v
);
1570 gtk_widget_destroy((GtkWidget
*)file_selector
);
1572 //update current tab
1573 //update_traceset(mw_data);
1575 /* Call the updatetraceset hooks */
1577 traceset
= tab
->traceset_info
->traceset
;
1578 SetTraceset(tab
, traceset
);
1579 // in expose now call_pending_read_hooks(mw_data);
1581 //lttvwindow_report_current_time(mw_data,&(tab->current_time));
1583 case GTK_RESPONSE_REJECT
:
1584 case GTK_RESPONSE_CANCEL
:
1586 gtk_widget_destroy((GtkWidget
*)file_selector
);
1592 /* remove_trace_into_traceset_selector, each instance of a viewer has an associated
1593 * selector (filter), when a trace is remove from traceset, the selector should
1594 * reflect the change. The function is used to update the selector
1597 void remove_trace_from_traceset_selector(GtkWidget
* paned
, unsigned i
)
1599 LttvTracesetSelector
* s
;
1600 LttvTraceSelector
* t
;
1603 w
= gtk_multivpaned_get_first_widget(GTK_MULTIVPANED(paned
));
1605 s
= g_object_get_data(G_OBJECT(w
), "Traceset_Selector");
1607 t
= lttv_traceset_selector_trace_get(s
,i
);
1608 lttv_traceset_selector_trace_remove(s
, i
);
1609 lttv_trace_selector_destroy(t
);
1610 }g_warning("Module dose not support filtering\n");
1611 w
= gtk_multivpaned_get_next_widget(GTK_MULTIVPANED(paned
));
1616 /* remove_trace removes a trace from the current traceset if all viewers in
1617 * the current tab are not interested in the trace. It first displays a
1618 * dialogue, which shows all traces in the current traceset, to let user choose
1619 * a trace, then it checks if all viewers unselect the trace, if it is true,
1620 * it will remove the trace, recreate the traceset_contex,
1621 * and redraws all the viewer of the current tab. If there is on trace in the
1622 * current traceset, it will delete all viewers of the current tab
1625 // MD : no filter version.
1626 void remove_trace(GtkWidget
*widget
, gpointer user_data
)
1629 LttvTrace
* trace_v
;
1630 LttvTraceset
* traceset
;
1631 gint i
, j
, nb_trace
, index
=-1;
1632 char ** name
, *remove_trace_name
;
1633 MainWindow
* mw_data
= get_window_data_struct(widget
);
1634 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
1636 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
1637 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
1643 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
1646 nb_trace
=lttv_traceset_number(tab
->traceset_info
->traceset
);
1647 name
= g_new(char*,nb_trace
);
1648 for(i
= 0; i
< nb_trace
; i
++){
1649 trace_v
= lttv_traceset_get(tab
->traceset_info
->traceset
, i
);
1650 trace
= lttv_trace(trace_v
);
1651 name
[i
] = ltt_trace_name(trace
);
1654 remove_trace_name
= get_remove_trace(name
, nb_trace
);
1657 if(remove_trace_name
){
1659 /* yuk, cut n paste from old code.. should be better (MD)*/
1660 for(i
= 0; i
<nb_trace
; i
++) {
1661 if(strcmp(remove_trace_name
,name
[i
]) == 0){
1666 traceset
= tab
->traceset_info
->traceset
;
1667 //Keep a reference to the traces so they are not freed.
1668 for(j
=0; j
<lttv_traceset_number(traceset
); j
++)
1670 LttvTrace
* trace
= lttv_traceset_get(traceset
, j
);
1671 lttv_trace_ref(trace
);
1674 //remove state update hooks
1675 lttv_state_remove_event_hooks(
1676 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1677 lttv_context_fini(LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
));
1678 g_object_unref(tab
->traceset_info
->traceset_context
);
1680 trace_v
= lttv_traceset_get(traceset
, index
);
1682 lttv_traceset_remove(traceset
, index
);
1683 lttv_trace_unref(trace_v
); // Remove local reference
1685 if(lttv_trace_get_ref_number(trace_v
) <= 1) {
1686 /* ref 1 : lttvwindowtraces only*/
1687 ltt_trace_close(lttv_trace(trace_v
));
1688 /* lttvwindowtraces_remove_trace takes care of destroying
1689 * the traceset linked with the trace_v and also of destroying
1690 * the trace_v at the same time.
1692 lttvwindowtraces_remove_trace(trace_v
);
1695 tab
->traceset_info
->traceset_context
=
1696 g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
1698 LTTV_TRACESET_CONTEXT(tab
->
1699 traceset_info
->traceset_context
),traceset
);
1700 //add state update hooks
1701 lttv_state_add_event_hooks(
1702 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1704 //Remove local reference to the traces.
1705 for(j
=0; j
<lttv_traceset_number(traceset
); j
++)
1707 LttvTrace
* trace
= lttv_traceset_get(traceset
, j
);
1708 lttv_trace_unref(trace
);
1711 SetTraceset(tab
, (gpointer
)traceset
);
1717 void remove_trace(GtkWidget
* widget
, gpointer user_data
)
1720 LttvTrace
* trace_v
;
1721 LttvTraceset
* traceset
;
1722 gint i
, j
, nb_trace
;
1723 char ** name
, *remove_trace_name
;
1724 MainWindow
* mw_data
= get_window_data_struct(widget
);
1725 LttvTracesetSelector
* s
;
1726 LttvTraceSelector
* t
;
1729 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
1731 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
1732 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
1738 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
1741 nb_trace
=lttv_traceset_number(tab
->traceset_info
->traceset
);
1742 name
= g_new(char*,nb_trace
);
1743 for(i
= 0; i
< nb_trace
; i
++){
1744 trace_v
= lttv_traceset_get(tab
->traceset_info
->traceset
, i
);
1745 trace
= lttv_trace(trace_v
);
1746 name
[i
] = ltt_trace_name(trace
);
1749 remove_trace_name
= get_remove_trace(name
, nb_trace
);
1751 if(remove_trace_name
){
1752 for(i
=0; i
<nb_trace
; i
++){
1753 if(strcmp(remove_trace_name
,name
[i
]) == 0){
1754 //unselect the trace from the current viewer
1756 w
= gtk_multivpaned_get_widget(GTK_MULTIVPANED(tab
->multivpaned
));
1758 s
= g_object_get_data(G_OBJECT(w
), "Traceset_Selector");
1760 t
= lttv_traceset_selector_trace_get(s
,i
);
1761 lttv_trace_selector_set_selected(t
, FALSE
);
1764 //check if other viewers select the trace
1765 w
= gtk_multivpaned_get_first_widget(GTK_MULTIVPANED(tab
->multivpaned
));
1767 s
= g_object_get_data(G_OBJECT(w
), "Traceset_Selector");
1769 t
= lttv_traceset_selector_trace_get(s
,i
);
1770 selected
= lttv_trace_selector_get_selected(t
);
1773 w
= gtk_multivpaned_get_next_widget(GTK_MULTIVPANED(tab
->multivpaned
));
1775 }else selected
= FALSE
;
1777 //if no viewer selects the trace, remove it
1779 remove_trace_from_traceset_selector(GTK_MULTIVPANED(tab
->multivpaned
), i
);
1781 traceset
= tab
->traceset_info
->traceset
;
1782 //Keep a reference to the traces so they are not freed.
1783 for(j
=0; j
<lttv_traceset_number(traceset
); j
++)
1785 LttvTrace
* trace
= lttv_traceset_get(traceset
, j
);
1786 lttv_trace_ref(trace
);
1789 //remove state update hooks
1790 lttv_state_remove_event_hooks(
1791 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1792 lttv_context_fini(LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
));
1793 g_object_unref(tab
->traceset_info
->traceset_context
);
1796 trace_v
= lttv_traceset_get(traceset
, i
);
1798 if(lttv_trace_get_ref_number(trace_v
) <= 2) {
1799 /* ref 2 : traceset, local */
1800 lttvwindowtraces_remove_trace(trace_v
);
1801 ltt_trace_close(lttv_trace(trace_v
));
1804 lttv_traceset_remove(traceset
, i
);
1805 lttv_trace_unref(trace_v
); // Remove local reference
1807 if(!lttv_trace_get_ref_number(trace_v
))
1808 lttv_trace_destroy(trace_v
);
1810 tab
->traceset_info
->traceset_context
=
1811 g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
1813 LTTV_TRACESET_CONTEXT(tab
->
1814 traceset_info
->traceset_context
),traceset
);
1815 //add state update hooks
1816 lttv_state_add_event_hooks(
1817 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1819 //Remove local reference to the traces.
1820 for(j
=0; j
<lttv_traceset_number(traceset
); j
++)
1822 LttvTrace
* trace
= lttv_traceset_get(traceset
, j
);
1823 lttv_trace_unref(trace
);
1827 //update current tab
1828 //update_traceset(mw_data);
1831 SetTraceset(tab
, (gpointer
)traceset
);
1832 // in expose now call_pending_read_hooks(mw_data);
1834 //lttvwindow_report_current_time(mw_data,&(tab->current_time));
1837 // while(tab->multi_vpaned->num_children){
1838 // gtk_multi_vpaned_widget_delete(tab->multi_vpaned);
1852 /* Redraw all the viewers in the current tab */
1853 void redraw(GtkWidget
*widget
, gpointer user_data
)
1855 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
1856 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
1857 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
1862 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
1866 LttvAttributeValue value
;
1868 g_assert(lttv_iattribute_find_by_path(tab
->attributes
, "hooks/redraw", LTTV_POINTER
, &value
));
1870 tmp
= (LttvHooks
*)*(value
.v_pointer
);
1872 lttv_hooks_call(tmp
,NULL
);
1876 void continue_processing(GtkWidget
*widget
, gpointer user_data
)
1878 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
1879 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
1880 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
1885 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
1889 LttvAttributeValue value
;
1891 g_assert(lttv_iattribute_find_by_path(tab
->attributes
,
1892 "hooks/continue", LTTV_POINTER
, &value
));
1894 tmp
= (LttvHooks
*)*(value
.v_pointer
);
1896 lttv_hooks_call(tmp
,NULL
);
1899 /* Stop the processing for the calling main window's current tab.
1900 * It removes every processing requests that are in its list. It does not call
1901 * the end request hooks, because the request is not finished.
1904 void stop_processing(GtkWidget
*widget
, gpointer user_data
)
1906 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
1907 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
1908 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
1913 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
1915 GSList
*iter
= tab
->events_requests
;
1917 while(iter
!= NULL
) {
1918 GSList
*remove_iter
= iter
;
1919 iter
= g_slist_next(iter
);
1921 g_free(remove_iter
->data
);
1922 tab
->events_requests
=
1923 g_slist_remove_link(tab
->events_requests
, remove_iter
);
1925 tab
->events_request_pending
= FALSE
;
1926 g_idle_remove_by_data(tab
);
1927 g_assert(g_slist_length(tab
->events_requests
) == 0);
1931 /* save will save the traceset to a file
1932 * Not implemented yet FIXME
1935 void save(GtkWidget
* widget
, gpointer user_data
)
1940 void save_as(GtkWidget
* widget
, gpointer user_data
)
1942 g_printf("Save as\n");
1946 /* zoom will change the time_window of all the viewers of the
1947 * current tab, and redisplay them. The main functionality is to
1948 * determine the new time_window of the current tab
1951 void zoom(GtkWidget
* widget
, double size
)
1953 TimeInterval time_span
;
1954 TimeWindow new_time_window
;
1955 LttTime current_time
, time_delta
, time_s
, time_e
, time_tmp
;
1956 MainWindow
* mw_data
= get_window_data_struct(widget
);
1957 LttvTracesetContext
*tsc
;
1958 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
1960 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
1961 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
1967 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
1970 if(size
== 1) return;
1972 tsc
= LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
1973 time_span
= tsc
->time_span
;
1974 new_time_window
= tab
->time_window
;
1975 current_time
= tab
->current_time
;
1977 time_delta
= ltt_time_sub(time_span
.end_time
,time_span
.start_time
);
1979 new_time_window
.start_time
= time_span
.start_time
;
1980 new_time_window
.time_width
= time_delta
;
1982 new_time_window
.time_width
= ltt_time_div(new_time_window
.time_width
, size
);
1983 if(ltt_time_compare(new_time_window
.time_width
,time_delta
) > 0)
1984 { /* Case where zoom out is bigger than trace length */
1985 new_time_window
.start_time
= time_span
.start_time
;
1986 new_time_window
.time_width
= time_delta
;
1990 /* Center the image on the current time */
1991 new_time_window
.start_time
=
1992 ltt_time_sub(current_time
, ltt_time_div(new_time_window
.time_width
, 2.0));
1993 /* If on borders, don't fall off */
1994 if(ltt_time_compare(new_time_window
.start_time
, time_span
.start_time
) <0)
1996 new_time_window
.start_time
= time_span
.start_time
;
2000 if(ltt_time_compare(
2001 ltt_time_add(new_time_window
.start_time
, new_time_window
.time_width
),
2002 time_span
.end_time
) > 0)
2004 new_time_window
.start_time
=
2005 ltt_time_sub(time_span
.end_time
, new_time_window
.time_width
);
2011 //time_tmp = ltt_time_div(new_time_window.time_width, 2);
2012 //if(ltt_time_compare(current_time, time_tmp) < 0){
2013 // time_s = time_span->startTime;
2015 // time_s = ltt_time_sub(current_time,time_tmp);
2017 //time_e = ltt_time_add(current_time,time_tmp);
2018 //if(ltt_time_compare(time_span->startTime, time_s) > 0){
2019 // time_s = time_span->startTime;
2020 //}else if(ltt_time_compare(time_span->endTime, time_e) < 0){
2021 // time_e = time_span->endTime;
2022 // time_s = ltt_time_sub(time_e,new_time_window.time_width);
2024 //new_time_window.start_time = time_s;
2027 //lttvwindow_report_time_window(mw_data, &new_time_window);
2028 //call_pending_read_hooks(mw_data);
2030 //lttvwindow_report_current_time(mw_data,&(tab->current_time));
2031 //set_time_window(tab, &new_time_window);
2032 // in expose now call_pending_read_hooks(mw_data);
2033 //gtk_multi_vpaned_set_adjust(tab->multi_vpaned, &new_time_window, FALSE);
2038 ltt_time_sub(new_time_window
.start_time
, time_span
.start_time
);
2039 if( ltt_time_to_double(new_time_window
.time_width
)
2040 * NANOSECONDS_PER_SECOND
2041 / SCROLL_STEP_PER_PAGE
/* step increment */
2043 ltt_time_to_double(rel_time
) * NANOSECONDS_PER_SECOND
/* page size */
2045 ltt_time_to_double(rel_time
) * NANOSECONDS_PER_SECOND
/* page size */
2047 g_warning("Can not zoom that far due to scrollbar precision");
2050 ltt_time_from_double(
2051 ltt_time_to_double(new_time_window
.time_width
)
2052 /SCROLL_STEP_PER_PAGE
),
2055 g_warning("Can not zoom that far due to time nanosecond precision");
2057 time_change_manager(tab
, new_time_window
);
2060 GtkAdjustment
*adjustment
= gtk_range_get_adjustment(GTK_RANGE(tab
->scrollbar
));
2062 g_object_set(G_OBJECT(adjustment
),
2064 //ltt_time_to_double(new_time_window.start_time)
2065 // * NANOSECONDS_PER_SECOND, /* value */
2070 ltt_time_sub(time_span
.end_time
, time_span
.start_time
))
2071 * NANOSECONDS_PER_SECOND
, /* upper */
2073 ltt_time_to_double(new_time_window
.time_width
)
2074 / SCROLL_STEP_PER_PAGE
2075 * NANOSECONDS_PER_SECOND
, /* step increment */
2077 ltt_time_to_double(new_time_window
.time_width
)
2078 * NANOSECONDS_PER_SECOND
, /* page increment */
2080 ltt_time_to_double(new_time_window
.time_width
)
2081 * NANOSECONDS_PER_SECOND
, /* page size */
2083 gtk_adjustment_changed(adjustment
);
2084 //gtk_range_set_adjustment(GTK_RANGE(tab->scrollbar), adjustment);
2085 //gtk_adjustment_value_changed(adjustment);
2086 g_object_set(G_OBJECT(adjustment
),
2089 ltt_time_sub(new_time_window
.start_time
, time_span
.start_time
))
2090 * NANOSECONDS_PER_SECOND
, /* value */
2092 gtk_adjustment_value_changed(adjustment
);
2095 //g_object_set(G_OBJECT(adjustment),
2097 // ltt_time_to_double(time_window->start_time)
2098 // * NANOSECONDS_PER_SECOND, /* value */
2100 /* Note : the set value will call set_time_window if scrollbar value changed
2102 //gtk_adjustment_set_value(adjustment,
2103 // ltt_time_to_double(new_time_window.start_time)
2104 // * NANOSECONDS_PER_SECOND);
2109 void zoom_in(GtkWidget
* widget
, gpointer user_data
)
2114 void zoom_out(GtkWidget
* widget
, gpointer user_data
)
2119 void zoom_extended(GtkWidget
* widget
, gpointer user_data
)
2124 void go_to_time(GtkWidget
* widget
, gpointer user_data
)
2126 g_printf("Go to time\n");
2129 void show_time_frame(GtkWidget
* widget
, gpointer user_data
)
2131 g_printf("Show time frame\n");
2135 /* callback function */
2138 on_empty_traceset_activate (GtkMenuItem
*menuitem
,
2141 create_new_window((GtkWidget
*)menuitem
, user_data
, FALSE
);
2146 on_clone_traceset_activate (GtkMenuItem
*menuitem
,
2149 create_new_window((GtkWidget
*)menuitem
, user_data
, TRUE
);
2153 /* create_new_tab calls create_tab to construct a new tab in the main window
2156 Tab
*create_new_tab(GtkWidget
* widget
, gpointer user_data
){
2157 gchar label
[PATH_MAX
];
2158 MainWindow
* mw_data
= get_window_data_struct(widget
);
2160 GtkNotebook
* notebook
= (GtkNotebook
*)lookup_widget(widget
, "MNotebook");
2161 if(notebook
== NULL
){
2162 g_printf("Notebook does not exist\n");
2165 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2166 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2172 copy_tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
2175 strcpy(label
,"Page");
2176 if(get_label(mw_data
, label
,"Get the name of the tab","Please input tab's name"))
2177 return (create_tab (mw_data
, copy_tab
, notebook
, label
));
2181 on_tab_activate (GtkMenuItem
*menuitem
,
2184 create_new_tab((GtkWidget
*)menuitem
, user_data
);
2189 on_open_activate (GtkMenuItem
*menuitem
,
2192 open_traceset((GtkWidget
*)menuitem
, user_data
);
2197 on_close_activate (GtkMenuItem
*menuitem
,
2200 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2201 main_window_destructor(mw_data
);
2205 /* remove the current tab from the main window
2209 on_close_tab_activate (GtkWidget
*widget
,
2213 GtkWidget
* notebook
;
2215 MainWindow
* mw_data
= get_window_data_struct(widget
);
2216 notebook
= lookup_widget(widget
, "MNotebook");
2217 if(notebook
== NULL
){
2218 g_printf("Notebook does not exist\n");
2222 page_num
= gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
));
2224 gtk_notebook_remove_page(GTK_NOTEBOOK(notebook
), page_num
);
2229 on_close_tab_X_clicked (GtkWidget
*widget
,
2233 GtkWidget
*notebook
= lookup_widget(widget
, "MNotebook");
2234 if(notebook
== NULL
){
2235 g_printf("Notebook does not exist\n");
2239 if((page_num
= gtk_notebook_page_num(GTK_NOTEBOOK(notebook
), widget
)) != -1)
2240 gtk_notebook_remove_page(GTK_NOTEBOOK(notebook
), page_num
);
2246 on_add_trace_activate (GtkMenuItem
*menuitem
,
2249 add_trace((GtkWidget
*)menuitem
, user_data
);
2254 on_remove_trace_activate (GtkMenuItem
*menuitem
,
2257 remove_trace((GtkWidget
*)menuitem
, user_data
);
2262 on_save_activate (GtkMenuItem
*menuitem
,
2265 save((GtkWidget
*)menuitem
, user_data
);
2270 on_save_as_activate (GtkMenuItem
*menuitem
,
2273 save_as((GtkWidget
*)menuitem
, user_data
);
2278 on_quit_activate (GtkMenuItem
*menuitem
,
2286 on_cut_activate (GtkMenuItem
*menuitem
,
2294 on_copy_activate (GtkMenuItem
*menuitem
,
2297 g_printf("Copye\n");
2302 on_paste_activate (GtkMenuItem
*menuitem
,
2305 g_printf("Paste\n");
2310 on_delete_activate (GtkMenuItem
*menuitem
,
2313 g_printf("Delete\n");
2318 on_zoom_in_activate (GtkMenuItem
*menuitem
,
2321 zoom_in((GtkWidget
*)menuitem
, user_data
);
2326 on_zoom_out_activate (GtkMenuItem
*menuitem
,
2329 zoom_out((GtkWidget
*)menuitem
, user_data
);
2334 on_zoom_extended_activate (GtkMenuItem
*menuitem
,
2337 zoom_extended((GtkWidget
*)menuitem
, user_data
);
2342 on_go_to_time_activate (GtkMenuItem
*menuitem
,
2345 go_to_time((GtkWidget
*)menuitem
, user_data
);
2350 on_show_time_frame_activate (GtkMenuItem
*menuitem
,
2353 show_time_frame((GtkWidget
*)menuitem
, user_data
);
2358 on_move_viewer_up_activate (GtkMenuItem
*menuitem
,
2361 move_up_viewer((GtkWidget
*)menuitem
, user_data
);
2366 on_move_viewer_down_activate (GtkMenuItem
*menuitem
,
2369 move_down_viewer((GtkWidget
*)menuitem
, user_data
);
2374 on_remove_viewer_activate (GtkMenuItem
*menuitem
,
2377 delete_viewer((GtkWidget
*)menuitem
, user_data
);
2382 on_trace_filter_activate (GtkMenuItem
*menuitem
,
2385 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2386 LttvTracesetSelector
* s
;
2388 GtkWidget
* notebook
= lookup_widget(GTK_WIDGET(menuitem
), "MNotebook");
2390 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2391 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2397 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
2400 w
= gtk_multivpaned_get_widget(GTK_MULTIVPANED(tab
->multivpaned
));
2402 s
= g_object_get_data(G_OBJECT(w
), "Traceset_Selector");
2404 g_printf("There is no viewer yet\n");
2407 if(get_filter_selection(s
, "Configure trace and tracefile filter", "Select traces and tracefiles")){
2408 //FIXME report filter change
2409 //update_traceset(mw_data);
2410 //call_pending_read_hooks(mw_data);
2411 //lttvwindow_report_current_time(mw_data,&(tab->current_time));
2417 on_trace_facility_activate (GtkMenuItem
*menuitem
,
2420 g_printf("Trace facility selector: %s\n");
2424 /* Dispaly a file selection dialogue to let user select a library, then call
2425 * lttv_library_load().
2429 on_load_library_activate (GtkMenuItem
*menuitem
,
2432 GError
*error
= NULL
;
2433 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2435 gchar load_module_path_alter
[PATH_MAX
];
2439 gchar
*load_module_path
;
2440 name
= g_ptr_array_new();
2441 nb
= lttv_library_path_number();
2442 /* ask for the library path */
2446 path
= lttv_library_path_get(i
);
2447 g_ptr_array_add(name
, path
);
2450 load_module_path
= get_selection((char **)(name
->pdata
), name
->len
,
2451 "Select a library path", "Library paths");
2452 if(load_module_path
!= NULL
)
2453 strncpy(load_module_path_alter
, load_module_path
, PATH_MAX
-1); // -1 for /
2455 g_ptr_array_free(name
, TRUE
);
2457 if(load_module_path
== NULL
) return;
2461 /* Make sure the module path ends with a / */
2462 gchar
*ptr
= load_module_path_alter
;
2464 ptr
= strchr(ptr
, '\0');
2466 if(*(ptr
-1) != '/') {
2473 /* Ask for the library to load : list files in the previously selected
2475 gchar str
[PATH_MAX
];
2478 GtkFileSelection
* file_selector
=
2479 (GtkFileSelection
*)gtk_file_selection_new("Select a module");
2480 gtk_file_selection_set_filename(file_selector
, load_module_path_alter
);
2481 gtk_file_selection_hide_fileop_buttons(file_selector
);
2484 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
2486 case GTK_RESPONSE_ACCEPT
:
2487 case GTK_RESPONSE_OK
:
2488 dir
= gtk_file_selection_get_selections (file_selector
);
2489 strncpy(str
,dir
[0],PATH_MAX
);
2490 strncpy(remember_plugins_dir
,dir
[0],PATH_MAX
);
2491 /* only keep file name */
2493 str1
= strrchr(str
,'/');
2496 str1
= strrchr(str
,'\\');
2501 if(*str1
== 'l' && *(str1
+1)== 'i' && *(str1
+2)=='b')
2503 remove info after
. */
2507 str2
= strrchr(str2
, '.');
2508 if(str2
!= NULL
) *str2
= '\0';
2510 lttv_module_require(str1
, &error
);
2512 lttv_library_load(str1
, &error
);
2513 if(error
!= NULL
) g_warning(error
->message
);
2514 else g_printf("Load library: %s\n", str
);
2516 case GTK_RESPONSE_REJECT
:
2517 case GTK_RESPONSE_CANCEL
:
2519 gtk_widget_destroy((GtkWidget
*)file_selector
);
2530 /* Display all loaded modules, let user to select a module to unload
2531 * by calling lttv_module_unload
2535 on_unload_library_activate (GtkMenuItem
*menuitem
,
2538 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2540 LttvLibrary
*library
;
2545 name
= g_ptr_array_new();
2546 nb
= lttv_library_number();
2547 LttvLibraryInfo
*lib_info
= g_new(LttvLibraryInfo
,nb
);
2548 /* ask for the library name */
2551 LttvLibrary
*iter_lib
= lttv_library_get(i
);
2552 lttv_library_info(iter_lib
, &lib_info
[i
]);
2554 gchar
*path
= lib_info
[i
].name
;
2555 g_ptr_array_add(name
, lib_info
[i
].name
);
2557 lib_name
= get_selection((char **)(name
->pdata
), name
->len
,
2558 "Select a library", "Libraries");
2559 if(lib_name
!= NULL
) {
2561 if(strcmp(lib_name
, lib_info
[i
].name
) == 0) {
2562 library
= lttv_library_get(i
);
2567 g_ptr_array_free(name
, TRUE
);
2570 if(lib_name
== NULL
) return;
2573 lttv_library_unload(library
);
2577 /* Dispaly a file selection dialogue to let user select a module, then call
2578 * lttv_module_require().
2582 on_load_module_activate (GtkMenuItem
*menuitem
,
2585 GError
*error
= NULL
;
2586 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2588 LttvLibrary
*library
;
2593 name
= g_ptr_array_new();
2594 nb
= lttv_library_number();
2595 LttvLibraryInfo
*lib_info
= g_new(LttvLibraryInfo
,nb
);
2596 /* ask for the library name */
2599 LttvLibrary
*iter_lib
= lttv_library_get(i
);
2600 lttv_library_info(iter_lib
, &lib_info
[i
]);
2602 gchar
*path
= lib_info
[i
].name
;
2603 g_ptr_array_add(name
, path
);
2605 lib_name
= get_selection((char **)(name
->pdata
), name
->len
,
2606 "Select a library", "Libraries");
2607 if(lib_name
!= NULL
) {
2609 if(strcmp(lib_name
, lib_info
[i
].name
) == 0) {
2610 library
= lttv_library_get(i
);
2615 g_ptr_array_free(name
, TRUE
);
2618 if(lib_name
== NULL
) return;
2621 //LttvModule *module;
2622 gchar module_name_out
[PATH_MAX
];
2624 /* Ask for the module to load : list modules in the selected lib */
2628 LttvModuleInfo
*module_info
= g_new(LttvModuleInfo
,nb
);
2629 name
= g_ptr_array_new();
2630 nb
= lttv_library_module_number(library
);
2631 /* ask for the module name */
2634 LttvModule
*iter_module
= lttv_library_module_get(library
, i
);
2635 lttv_module_info(iter_module
, &module_info
[i
]);
2637 gchar
*path
= module_info
[i
].name
;
2638 g_ptr_array_add(name
, path
);
2640 module_name
= get_selection((char **)(name
->pdata
), name
->len
,
2641 "Select a module", "Modules");
2642 if(module_name
!= NULL
) {
2644 if(strcmp(module_name
, module_info
[i
].name
) == 0) {
2645 strncpy(module_name_out
, module_name
, PATH_MAX
);
2646 //module = lttv_library_module_get(i);
2652 g_ptr_array_free(name
, TRUE
);
2653 g_free(module_info
);
2655 if(module_name
== NULL
) return;
2658 lttv_module_require(module_name_out
, &error
);
2659 if(error
!= NULL
) g_warning(error
->message
);
2660 else g_printf("Load module: %s\n", module_name_out
);
2667 gchar str
[PATH_MAX
];
2670 GtkFileSelection
* file_selector
=
2671 (GtkFileSelection
*)gtk_file_selection_new("Select a module");
2672 gtk_file_selection_set_filename(file_selector
, load_module_path_alter
);
2673 gtk_file_selection_hide_fileop_buttons(file_selector
);
2676 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
2678 case GTK_RESPONSE_ACCEPT
:
2679 case GTK_RESPONSE_OK
:
2680 dir
= gtk_file_selection_get_selections (file_selector
);
2681 strncpy(str
,dir
[0],PATH_MAX
);
2682 strncpy(remember_plugins_dir
,dir
[0],PATH_MAX
);
2684 /* only keep file name */
2686 str1
= strrchr(str
,'/');
2689 str1
= strrchr(str
,'\\');
2694 if(*str1
== 'l' && *(str1
+1)== 'i' && *(str1
+2)=='b')
2696 remove info after
. */
2700 str2
= strrchr(str2
, '.');
2701 if(str2
!= NULL
) *str2
= '\0';
2703 lttv_module_require(str1
, &error
);
2705 lttv_library_load(str1
, &error
);
2706 if(error
!= NULL
) g_warning(error
->message
);
2707 else g_printf("Load library: %s\n", str
);
2709 case GTK_RESPONSE_REJECT
:
2710 case GTK_RESPONSE_CANCEL
:
2712 gtk_widget_destroy((GtkWidget
*)file_selector
);
2724 /* Display all loaded modules, let user to select a module to unload
2725 * by calling lttv_module_unload
2729 on_unload_module_activate (GtkMenuItem
*menuitem
,
2732 GError
*error
= NULL
;
2733 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2735 LttvLibrary
*library
;
2740 name
= g_ptr_array_new();
2741 nb
= lttv_library_number();
2742 LttvLibraryInfo
*lib_info
= g_new(LttvLibraryInfo
,nb
);
2743 /* ask for the library name */
2746 LttvLibrary
*iter_lib
= lttv_library_get(i
);
2747 lttv_library_info(iter_lib
, &lib_info
[i
]);
2749 gchar
*path
= lib_info
[i
].name
;
2750 g_ptr_array_add(name
, path
);
2752 lib_name
= get_selection((char **)(name
->pdata
), name
->len
,
2753 "Select a library", "Libraries");
2754 if(lib_name
!= NULL
) {
2756 if(strcmp(lib_name
, lib_info
[i
].name
) == 0) {
2757 library
= lttv_library_get(i
);
2762 g_ptr_array_free(name
, TRUE
);
2765 if(lib_name
== NULL
) return;
2770 /* Ask for the module to load : list modules in the selected lib */
2774 nb
= lttv_library_module_number(library
);
2775 LttvModuleInfo
*module_info
= g_new(LttvModuleInfo
,nb
);
2776 name
= g_ptr_array_new();
2777 /* ask for the module name */
2780 LttvModule
*iter_module
= lttv_library_module_get(library
, i
);
2781 lttv_module_info(iter_module
, &module_info
[i
]);
2783 gchar
*path
= module_info
[i
].name
;
2784 if(module_info
[i
].use_count
> 0) g_ptr_array_add(name
, path
);
2786 module_name
= get_selection((char **)(name
->pdata
), name
->len
,
2787 "Select a module", "Modules");
2788 if(module_name
!= NULL
) {
2790 if(strcmp(module_name
, module_info
[i
].name
) == 0) {
2791 module
= lttv_library_module_get(library
, i
);
2797 g_ptr_array_free(name
, TRUE
);
2798 g_free(module_info
);
2800 if(module_name
== NULL
) return;
2803 LttvModuleInfo module_info
;
2804 lttv_module_info(module
, &module_info
);
2805 g_printf("Release module: %s\n", module_info
.name
);
2807 lttv_module_release(module
);
2811 /* Display a directory dialogue to let user select a path for library searching
2815 on_add_library_search_path_activate (GtkMenuItem
*menuitem
,
2818 GtkDirSelection
* file_selector
= (GtkDirSelection
*)gtk_dir_selection_new("Select library path");
2822 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2823 if(remember_plugins_dir
[0] != '\0')
2824 gtk_dir_selection_set_filename(file_selector
, remember_plugins_dir
);
2826 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
2828 case GTK_RESPONSE_ACCEPT
:
2829 case GTK_RESPONSE_OK
:
2830 dir
= gtk_dir_selection_get_dir (file_selector
);
2831 strncpy(remember_plugins_dir
,dir
,PATH_MAX
);
2832 strncat(remember_plugins_dir
,"/",PATH_MAX
);
2833 lttv_library_path_add(dir
);
2834 case GTK_RESPONSE_REJECT
:
2835 case GTK_RESPONSE_CANCEL
:
2837 gtk_widget_destroy((GtkWidget
*)file_selector
);
2843 /* Display a directory dialogue to let user select a path for library searching
2847 on_remove_library_search_path_activate (GtkMenuItem
*menuitem
,
2850 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2852 const char *lib_path
;
2857 name
= g_ptr_array_new();
2858 nb
= lttv_library_path_number();
2859 /* ask for the library name */
2862 gchar
*path
= lttv_library_path_get(i
);
2863 g_ptr_array_add(name
, path
);
2865 lib_path
= get_selection((char **)(name
->pdata
), name
->len
,
2866 "Select a library path", "Library paths");
2868 g_ptr_array_free(name
, TRUE
);
2870 if(lib_path
== NULL
) return;
2873 lttv_library_path_remove(lib_path
);
2877 on_color_activate (GtkMenuItem
*menuitem
,
2880 g_printf("Color\n");
2885 on_filter_activate (GtkMenuItem
*menuitem
,
2888 g_printf("Filter\n");
2893 on_save_configuration_activate (GtkMenuItem
*menuitem
,
2896 g_printf("Save configuration\n");
2901 on_content_activate (GtkMenuItem
*menuitem
,
2904 g_printf("Content\n");
2909 on_about_close_activate (GtkButton
*button
,
2912 GtkWidget
*about_widget
= GTK_WIDGET(user_data
);
2914 gtk_widget_destroy(about_widget
);
2918 on_about_activate (GtkMenuItem
*menuitem
,
2921 MainWindow
*main_window
= get_window_data_struct(GTK_WIDGET(menuitem
));
2922 GtkWidget
*window_widget
= main_window
->mwindow
;
2923 GtkWidget
*about_widget
= gtk_window_new(GTK_WINDOW_TOPLEVEL
);
2924 GtkWindow
*about_window
= GTK_WINDOW(about_widget
);
2925 gint window_width
, window_height
;
2927 gtk_window_set_title(about_window
, "About Linux Trace Toolkit");
2929 gtk_window_set_resizable(about_window
, FALSE
);
2930 gtk_window_set_transient_for(GTK_WINDOW(window_widget
), about_window
);
2931 gtk_window_set_destroy_with_parent(about_window
, TRUE
);
2932 gtk_window_set_modal(about_window
, FALSE
);
2934 /* Put the about window at the center of the screen */
2935 gtk_window_get_size(about_window
, &window_width
, &window_height
);
2936 gtk_window_move (about_window
,
2937 (gdk_screen_width() - window_width
)/2,
2938 (gdk_screen_height() - window_height
)/2);
2940 GtkWidget
*vbox
= gtk_vbox_new(FALSE
, 1);
2942 gtk_container_add(GTK_CONTAINER(about_widget
), vbox
);
2946 GtkWidget
*label1
= gtk_label_new("");
2947 gtk_misc_set_padding(GTK_MISC(label1
), 10, 20);
2948 gtk_label_set_markup(GTK_LABEL(label1
), "\
2949 <big>Linux Trace Toolkit</big>");
2950 gtk_label_set_justify(GTK_LABEL(label1
), GTK_JUSTIFY_CENTER
);
2952 GtkWidget
*label2
= gtk_label_new("");
2953 gtk_misc_set_padding(GTK_MISC(label2
), 10, 20);
2954 gtk_label_set_markup(GTK_LABEL(label2
), "\
2955 Project author: Karim Yaghmour\n\
2959 Michel Dagenais (New trace format, lttv main)\n\
2960 Mathieu Desnoyers (Directory structure, build with automake/conf,\n\
2961 lttv gui, control flow view, gui green threads\n\
2962 with interruptible foreground and background computation,\n\
2963 detailed event list)\n\
2964 Benoit Des Ligneris (Cluster adaptation)\n\
2965 Xang-Xiu Yang (new trace reading library and converter, lttv gui, \n\
2966 detailed event list and statistics view)\n\
2967 Tom Zanussi (RelayFS)");
2969 GtkWidget
*label3
= gtk_label_new("");
2970 gtk_label_set_markup(GTK_LABEL(label3
), "\
2971 Linux Trace Toolkit, Copyright (C) 2004 Karim Yaghmour\n\
2972 Linux Trace Toolkit comes with ABSOLUTELY NO WARRANTY.\n\
2973 This is free software, and you are welcome to redistribute it\n\
2974 under certain conditions. See COPYING for details.");
2975 gtk_misc_set_padding(GTK_MISC(label3
), 10, 20);
2977 gtk_box_pack_start_defaults(GTK_BOX(vbox
), label1
);
2978 gtk_box_pack_start_defaults(GTK_BOX(vbox
), label2
);
2979 gtk_box_pack_start_defaults(GTK_BOX(vbox
), label3
);
2981 GtkWidget
*hbox
= gtk_hbox_new(TRUE
, 0);
2982 gtk_box_pack_end(GTK_BOX(vbox
), hbox
, FALSE
, FALSE
, 0);
2983 GtkWidget
*close_button
= gtk_button_new_with_mnemonic("_Close");
2984 gtk_box_pack_end(GTK_BOX(hbox
), close_button
, FALSE
, FALSE
, 0);
2985 gtk_container_set_border_width(GTK_CONTAINER(close_button
), 20);
2987 g_signal_connect(G_OBJECT(close_button
), "clicked",
2988 G_CALLBACK(on_about_close_activate
),
2989 (gpointer
)about_widget
);
2991 gtk_widget_show_all(about_widget
);
2996 on_button_new_clicked (GtkButton
*button
,
2999 create_new_window((GtkWidget
*)button
, user_data
, TRUE
);
3003 on_button_new_tab_clicked (GtkButton
*button
,
3006 create_new_tab((GtkWidget
*)button
, user_data
);
3010 on_button_open_clicked (GtkButton
*button
,
3013 open_traceset((GtkWidget
*)button
, user_data
);
3018 on_button_add_trace_clicked (GtkButton
*button
,
3021 add_trace((GtkWidget
*)button
, user_data
);
3026 on_button_remove_trace_clicked (GtkButton
*button
,
3029 remove_trace((GtkWidget
*)button
, user_data
);
3033 on_button_redraw_clicked (GtkButton
*button
,
3036 redraw((GtkWidget
*)button
, user_data
);
3040 on_button_continue_processing_clicked (GtkButton
*button
,
3043 continue_processing((GtkWidget
*)button
, user_data
);
3047 on_button_stop_processing_clicked (GtkButton
*button
,
3050 stop_processing((GtkWidget
*)button
, user_data
);
3056 on_button_save_clicked (GtkButton
*button
,
3059 save((GtkWidget
*)button
, user_data
);
3064 on_button_save_as_clicked (GtkButton
*button
,
3067 save_as((GtkWidget
*)button
, user_data
);
3072 on_button_zoom_in_clicked (GtkButton
*button
,
3075 zoom_in((GtkWidget
*)button
, user_data
);
3080 on_button_zoom_out_clicked (GtkButton
*button
,
3083 zoom_out((GtkWidget
*)button
, user_data
);
3088 on_button_zoom_extended_clicked (GtkButton
*button
,
3091 zoom_extended((GtkWidget
*)button
, user_data
);
3096 on_button_go_to_time_clicked (GtkButton
*button
,
3099 go_to_time((GtkWidget
*)button
, user_data
);
3104 on_button_show_time_frame_clicked (GtkButton
*button
,
3107 show_time_frame((GtkWidget
*)button
, user_data
);
3112 on_button_move_up_clicked (GtkButton
*button
,
3115 move_up_viewer((GtkWidget
*)button
, user_data
);
3120 on_button_move_down_clicked (GtkButton
*button
,
3123 move_down_viewer((GtkWidget
*)button
, user_data
);
3128 on_button_delete_viewer_clicked (GtkButton
*button
,
3131 delete_viewer((GtkWidget
*)button
, user_data
);
3135 on_MWindow_destroy (GtkWidget
*widget
,
3138 MainWindow
*main_window
= get_window_data_struct(widget
);
3139 LttvIAttribute
*attributes
= main_window
->attributes
;
3140 LttvAttributeValue value
;
3142 //This is unnecessary, since widgets will be destroyed
3143 //by the main window widget anyway.
3144 //remove_all_menu_toolbar_constructors(main_window, NULL);
3146 g_assert(lttv_iattribute_find_by_path(attributes
,
3147 "viewers/menu", LTTV_POINTER
, &value
));
3148 lttv_menus_destroy((LttvMenus
*)*(value
.v_pointer
));
3150 g_assert(lttv_iattribute_find_by_path(attributes
,
3151 "viewers/toolbar", LTTV_POINTER
, &value
));
3152 lttv_toolbars_destroy((LttvToolbars
*)*(value
.v_pointer
));
3154 g_object_unref(main_window
->attributes
);
3155 g_main_window_list
= g_slist_remove(g_main_window_list
, main_window
);
3157 g_printf("There are now : %d windows\n",g_slist_length(g_main_window_list
));
3158 if(g_slist_length(g_main_window_list
) == 0)
3163 on_MWindow_configure (GtkWidget
*widget
,
3164 GdkEventConfigure
*event
,
3167 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)widget
);
3168 float width
= event
->width
;
3169 TimeWindow time_win
;
3171 TimeInterval
*time_span
;
3174 // MD : removed time width modification upon resizing of the main window.
3175 // The viewers will redraw themselves completely, without time interval
3178 if(mw_data->window_width){
3179 time_span = LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context)->Time_Span ;
3180 time_win = tab->time_window;
3181 ratio = width / mw_data->window_width;
3182 tab->time_window.time_width = ltt_time_mul(time_win.time_width,ratio);
3183 time = ltt_time_sub(time_span->endTime, time_win.start_time);
3184 if(ltt_time_compare(time, tab->time_window.time_width) < 0){
3185 tab->time_window.time_width = time;
3191 mw_data->window_width = (int)width;
3200 on_MNotebook_switch_page (GtkNotebook
*notebook
,
3201 GtkNotebookPage
*page
,
3209 void time_change_manager (Tab
*tab
,
3210 TimeWindow new_time_window
)
3212 /* Only one source of time change */
3213 if(tab
->time_manager_lock
== TRUE
) return;
3215 tab
->time_manager_lock
= TRUE
;
3217 LttvTracesetContext
*tsc
= LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3218 TimeInterval time_span
= tsc
->time_span
;
3219 LttTime start_time
= new_time_window
.start_time
;
3220 LttTime end_time
= ltt_time_add(new_time_window
.start_time
,
3221 new_time_window
.time_width
);
3224 GtkAdjustment
*adjustment
= gtk_range_get_adjustment(GTK_RANGE(tab
->scrollbar
));
3225 LttTime upper
= ltt_time_sub(time_span
.end_time
, time_span
.start_time
);
3227 gtk_range_set_increments(GTK_RANGE(tab
->scrollbar
),
3228 ltt_time_to_double(new_time_window
.time_width
)
3229 / SCROLL_STEP_PER_PAGE
3230 * NANOSECONDS_PER_SECOND
, /* step increment */
3231 ltt_time_to_double(new_time_window
.time_width
)
3232 * NANOSECONDS_PER_SECOND
); /* page increment */
3233 gtk_range_set_range(GTK_RANGE(tab
->scrollbar
),
3235 ltt_time_to_double(upper
)
3236 * NANOSECONDS_PER_SECOND
); /* upper */
3238 g_object_set(G_OBJECT(adjustment
),
3242 ltt_time_to_double(upper
)
3243 * NANOSECONDS_PER_SECOND
, /* upper */
3245 ltt_time_to_double(new_time_window
.time_width
)
3246 / SCROLL_STEP_PER_PAGE
3247 * NANOSECONDS_PER_SECOND
, /* step increment */
3249 ltt_time_to_double(new_time_window
.time_width
)
3250 * NANOSECONDS_PER_SECOND
, /* page increment */
3252 ltt_time_to_double(new_time_window
.time_width
)
3253 * NANOSECONDS_PER_SECOND
, /* page size */
3255 gtk_adjustment_changed(adjustment
);
3257 // g_object_set(G_OBJECT(adjustment),
3259 // ltt_time_to_double(
3260 // ltt_time_sub(start_time, time_span.start_time))
3261 // * NANOSECONDS_PER_SECOND, /* value */
3263 //gtk_adjustment_value_changed(adjustment);
3264 gtk_range_set_value(GTK_RANGE(tab
->scrollbar
),
3266 ltt_time_sub(start_time
, time_span
.start_time
))
3267 * NANOSECONDS_PER_SECOND
/* value */);
3269 /* set the time bar. */
3271 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry1
),
3272 (double)time_span
.start_time
.tv_sec
,
3273 (double)time_span
.end_time
.tv_sec
);
3274 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry1
),
3275 (double)start_time
.tv_sec
);
3277 /* start nanoseconds */
3278 if(start_time
.tv_sec
== time_span
.start_time
.tv_sec
) {
3279 /* can be both beginning and end at the same time. */
3280 if(start_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3281 /* If we are at the end, max nsec to end.. -1 (not zero length) */
3282 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry2
),
3283 (double)time_span
.start_time
.tv_nsec
,
3284 (double)time_span
.end_time
.tv_nsec
-1);
3286 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry2
),
3287 (double)time_span
.start_time
.tv_nsec
,
3288 (double)NANOSECONDS_PER_SECOND
-1);
3290 } else if(start_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3291 /* If we are at the end, max nsec to end.. -1 (not zero length) */
3292 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry2
),
3294 (double)time_span
.end_time
.tv_nsec
-1);
3295 } else /* anywhere else */
3296 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry2
),
3298 (double)NANOSECONDS_PER_SECOND
-1);
3299 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry2
),
3300 (double)start_time
.tv_nsec
);
3303 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry3
),
3304 (double)time_span
.start_time
.tv_sec
,
3305 (double)time_span
.end_time
.tv_sec
);
3306 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry3
),
3307 (double)end_time
.tv_sec
);
3309 /* end nanoseconds */
3310 if(end_time
.tv_sec
== time_span
.start_time
.tv_sec
) {
3311 /* can be both beginning and end at the same time. */
3312 if(end_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3313 /* If we are at the end, max nsec to end.. */
3314 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry4
),
3315 (double)time_span
.start_time
.tv_nsec
+1,
3316 (double)time_span
.end_time
.tv_nsec
);
3318 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry4
),
3319 (double)time_span
.start_time
.tv_nsec
+1,
3320 (double)NANOSECONDS_PER_SECOND
-1);
3323 else if(end_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3324 /* If we are at the end, max nsec to end.. */
3325 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry4
),
3327 (double)time_span
.end_time
.tv_nsec
);
3329 else /* anywhere else */
3330 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry4
),
3332 (double)NANOSECONDS_PER_SECOND
-1);
3333 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry4
),
3334 (double)end_time
.tv_nsec
);
3336 /* call viewer hooks for new time window */
3337 set_time_window(tab
, &new_time_window
);
3339 tab
->time_manager_lock
= FALSE
;
3343 /* value changed for frame start s
3345 * Check time span : if ns is out of range, clip it the nearest good value.
3348 on_MEntry1_value_changed (GtkSpinButton
*spinbutton
,
3351 Tab
*tab
=(Tab
*)user_data
;
3352 LttvTracesetContext
* tsc
=
3353 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3354 TimeInterval time_span
= tsc
->time_span
;
3355 gint value
= gtk_spin_button_get_value_as_int(spinbutton
);
3357 TimeWindow new_time_window
= tab
->time_window
;
3359 LttTime end_time
= ltt_time_add(new_time_window
.start_time
,
3360 new_time_window
.time_width
);
3362 new_time_window
.start_time
.tv_sec
= value
;
3364 /* start nanoseconds */
3365 if(new_time_window
.start_time
.tv_sec
== time_span
.start_time
.tv_sec
) {
3366 if(new_time_window
.start_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3367 if(new_time_window
.start_time
.tv_nsec
> time_span
.end_time
.tv_nsec
)
3368 new_time_window
.start_time
.tv_nsec
= time_span
.end_time
.tv_nsec
-1;
3369 if(new_time_window
.start_time
.tv_nsec
< time_span
.start_time
.tv_nsec
)
3370 new_time_window
.start_time
.tv_nsec
= time_span
.start_time
.tv_nsec
;
3372 if(new_time_window
.start_time
.tv_nsec
< time_span
.start_time
.tv_nsec
)
3373 new_time_window
.start_time
.tv_nsec
= time_span
.start_time
.tv_nsec
;
3376 else if(new_time_window
.start_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3377 if(new_time_window
.start_time
.tv_nsec
> time_span
.end_time
.tv_nsec
)
3378 new_time_window
.start_time
.tv_nsec
= time_span
.end_time
.tv_nsec
-1;
3381 /* check if end time selected is below or equal */
3382 if(ltt_time_compare(new_time_window
.start_time
, end_time
) >= 0) {
3383 /* Then, we must push back end time : keep the same time width
3384 * if possible, else end traceset time */
3385 end_time
= LTT_TIME_MIN(time_span
.end_time
,
3386 ltt_time_add(new_time_window
.start_time
,
3387 new_time_window
.time_width
)
3391 /* Fix the time width to fit start time and end time */
3392 new_time_window
.time_width
= ltt_time_sub(end_time
,
3393 new_time_window
.start_time
);
3395 time_change_manager(tab
, new_time_window
);
3400 on_MEntry2_value_changed (GtkSpinButton
*spinbutton
,
3403 Tab
*tab
=(Tab
*)user_data
;
3404 LttvTracesetContext
* tsc
=
3405 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3406 TimeInterval time_span
= tsc
->time_span
;
3407 gint value
= gtk_spin_button_get_value_as_int(spinbutton
);
3409 TimeWindow new_time_window
= tab
->time_window
;
3411 LttTime end_time
= ltt_time_add(new_time_window
.start_time
,
3412 new_time_window
.time_width
);
3414 new_time_window
.start_time
.tv_nsec
= value
;
3416 /* check if end time selected is below or equal */
3417 if(ltt_time_compare(new_time_window
.start_time
, end_time
) >= 0) {
3418 /* Then, we must push back end time : keep the same time width
3419 * if possible, else end traceset time */
3420 end_time
= LTT_TIME_MIN(time_span
.end_time
,
3421 ltt_time_add(new_time_window
.start_time
,
3422 new_time_window
.time_width
)
3426 /* Fix the time width to fit start time and end time */
3427 new_time_window
.time_width
= ltt_time_sub(end_time
,
3428 new_time_window
.start_time
);
3430 time_change_manager(tab
, new_time_window
);
3435 on_MEntry3_value_changed (GtkSpinButton
*spinbutton
,
3438 Tab
*tab
=(Tab
*)user_data
;
3439 LttvTracesetContext
* tsc
=
3440 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3441 TimeInterval time_span
= tsc
->time_span
;
3442 gint value
= gtk_spin_button_get_value_as_int(spinbutton
);
3444 TimeWindow new_time_window
= tab
->time_window
;
3446 LttTime end_time
= ltt_time_add(new_time_window
.start_time
,
3447 new_time_window
.time_width
);
3448 end_time
.tv_sec
= value
;
3450 /* end nanoseconds */
3451 if(end_time
.tv_sec
== time_span
.start_time
.tv_sec
) {
3452 if(end_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3453 if(end_time
.tv_nsec
> time_span
.end_time
.tv_nsec
)
3454 end_time
.tv_nsec
= time_span
.end_time
.tv_nsec
;
3455 if(end_time
.tv_nsec
< time_span
.start_time
.tv_nsec
)
3456 end_time
.tv_nsec
= time_span
.start_time
.tv_nsec
+1;
3458 if(end_time
.tv_nsec
< time_span
.start_time
.tv_nsec
)
3459 end_time
.tv_nsec
= time_span
.start_time
.tv_nsec
+1;
3462 else if(end_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3463 if(end_time
.tv_nsec
> time_span
.end_time
.tv_nsec
)
3464 end_time
.tv_nsec
= time_span
.end_time
.tv_nsec
;
3467 /* check if end time selected is below or equal */
3468 if(ltt_time_compare(new_time_window
.start_time
, end_time
) >= 0) {
3469 /* Then, we must push front start time : keep the same time width
3470 * if possible, else end traceset time */
3471 new_time_window
.start_time
= LTT_TIME_MAX(time_span
.start_time
,
3472 ltt_time_sub(end_time
,
3473 new_time_window
.time_width
)
3477 /* Fix the time width to fit start time and end time */
3478 new_time_window
.time_width
= ltt_time_sub(end_time
,
3479 new_time_window
.start_time
);
3481 time_change_manager(tab
, new_time_window
);
3486 on_MEntry4_value_changed (GtkSpinButton
*spinbutton
,
3489 Tab
*tab
=(Tab
*)user_data
;
3490 LttvTracesetContext
* tsc
=
3491 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3492 TimeInterval time_span
= tsc
->time_span
;
3493 gint value
= gtk_spin_button_get_value_as_int(spinbutton
);
3495 TimeWindow new_time_window
= tab
->time_window
;
3497 LttTime end_time
= ltt_time_add(new_time_window
.start_time
,
3498 new_time_window
.time_width
);
3499 end_time
.tv_nsec
= value
;
3501 /* check if end time selected is below or equal */
3502 if(ltt_time_compare(new_time_window
.start_time
, end_time
) >= 0) {
3503 /* Then, we must push front start time : keep the same time width
3504 * if possible, else end traceset time */
3505 new_time_window
.start_time
= LTT_TIME_MAX(time_span
.start_time
,
3506 ltt_time_sub(end_time
,
3507 new_time_window
.time_width
)
3511 /* Fix the time width to fit start time and end time */
3512 new_time_window
.time_width
= ltt_time_sub(end_time
,
3513 new_time_window
.start_time
);
3515 time_change_manager(tab
, new_time_window
);
3520 void current_time_change_manager (Tab
*tab
,
3521 LttTime new_current_time
)
3523 /* Only one source of time change */
3524 if(tab
->current_time_manager_lock
== TRUE
) return;
3526 tab
->current_time_manager_lock
= TRUE
;
3528 LttvTracesetContext
*tsc
= LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3529 TimeInterval time_span
= tsc
->time_span
;
3531 /* current seconds */
3532 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry5
),
3533 (double)time_span
.start_time
.tv_sec
,
3534 (double)time_span
.end_time
.tv_sec
);
3535 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry5
),
3536 (double)new_current_time
.tv_sec
);
3539 /* start nanoseconds */
3540 if(new_current_time
.tv_sec
== time_span
.start_time
.tv_sec
) {
3541 /* can be both beginning and end at the same time. */
3542 if(new_current_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3543 /* If we are at the end, max nsec to end.. */
3544 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry6
),
3545 (double)time_span
.start_time
.tv_nsec
,
3546 (double)time_span
.end_time
.tv_nsec
);
3548 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry6
),
3549 (double)time_span
.start_time
.tv_nsec
,
3550 (double)NANOSECONDS_PER_SECOND
-1);
3552 } else if(new_current_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3553 /* If we are at the end, max nsec to end.. */
3554 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry6
),
3556 (double)time_span
.end_time
.tv_nsec
);
3557 } else /* anywhere else */
3558 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry6
),
3560 (double)NANOSECONDS_PER_SECOND
-1);
3562 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry6
),
3563 (double)new_current_time
.tv_nsec
);
3565 set_current_time(tab
, &new_current_time
);
3567 tab
->current_time_manager_lock
= FALSE
;
3571 on_MEntry5_value_changed (GtkSpinButton
*spinbutton
,
3574 Tab
*tab
= (Tab
*)user_data
;
3575 LttvTracesetContext
* tsc
=
3576 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3577 TimeInterval time_span
= tsc
->time_span
;
3578 gint value
= gtk_spin_button_get_value_as_int(spinbutton
);
3579 LttTime new_current_time
= tab
->current_time
;
3580 new_current_time
.tv_sec
= value
;
3582 /* current nanoseconds */
3583 if(new_current_time
.tv_sec
== time_span
.start_time
.tv_sec
) {
3584 if(new_current_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3585 if(new_current_time
.tv_nsec
> time_span
.end_time
.tv_nsec
)
3586 new_current_time
.tv_nsec
= time_span
.end_time
.tv_nsec
;
3587 if(new_current_time
.tv_nsec
< time_span
.start_time
.tv_nsec
)
3588 new_current_time
.tv_nsec
= time_span
.start_time
.tv_nsec
;
3590 if(new_current_time
.tv_nsec
< time_span
.start_time
.tv_nsec
)
3591 new_current_time
.tv_nsec
= time_span
.start_time
.tv_nsec
;
3594 else if(new_current_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3595 if(new_current_time
.tv_nsec
> time_span
.end_time
.tv_nsec
)
3596 new_current_time
.tv_nsec
= time_span
.end_time
.tv_nsec
;
3599 current_time_change_manager(tab
, new_current_time
);
3603 on_MEntry6_value_changed (GtkSpinButton
*spinbutton
,
3606 Tab
*tab
= (Tab
*)user_data
;
3607 gint value
= gtk_spin_button_get_value_as_int(spinbutton
);
3608 LttTime new_current_time
= tab
->current_time
;
3609 new_current_time
.tv_nsec
= value
;
3611 current_time_change_manager(tab
, new_current_time
);
3615 void scroll_value_changed_cb(GtkWidget
*scrollbar
,
3618 Tab
*tab
= (Tab
*)user_data
;
3619 TimeWindow new_time_window
;
3621 GtkAdjustment
*adjust
= gtk_range_get_adjustment(GTK_RANGE(scrollbar
));
3622 gdouble value
= gtk_adjustment_get_value(adjust
);
3623 // gdouble upper, lower, ratio, page_size;
3625 LttvTracesetContext
* tsc
=
3626 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3627 TimeInterval time_span
= tsc
->time_span
;
3629 time
= ltt_time_add(ltt_time_from_double(value
/NANOSECONDS_PER_SECOND
),
3630 time_span
.start_time
);
3632 new_time_window
.start_time
= time
;
3634 page_size
= adjust
->page_size
;
3636 new_time_window
.time_width
=
3637 ltt_time_from_double(page_size
/NANOSECONDS_PER_SECOND
);
3640 time_change_manager(tab
, new_time_window
);
3642 //time_window = tab->time_window;
3644 lower
= adjust
->lower
;
3645 upper
= adjust
->upper
;
3646 ratio
= (value
- lower
) / (upper
- lower
);
3647 g_info("lower %lu, upper %lu, value %lu, ratio %lu", lower
, upper
, value
, ratio
);
3649 //time = ltt_time_sub(time_span->end_time, time_span->start_time);
3650 //time = ltt_time_mul(time, (float)ratio);
3651 //time = ltt_time_add(time_span->start_time, time);
3652 time
= ltt_time_add(ltt_time_from_double(value
/NANOSECONDS_PER_SECOND
),
3653 time_span
.start_time
);
3655 time_window
.start_time
= time
;
3657 page_size
= adjust
->page_size
;
3659 time_window
.time_width
=
3660 ltt_time_from_double(page_size
/NANOSECONDS_PER_SECOND
);
3661 //time = ltt_time_sub(time_span.end_time, time);
3662 //if(ltt_time_compare(time,time_window.time_width) < 0){
3663 // time_window.time_width = time;
3666 /* call viewer hooks for new time window */
3667 set_time_window(tab
, &time_window
);
3672 /* callback function to check or uncheck the check box (filter)
3675 void checkbox_changed(GtkTreeView
*treeview
,
3677 GtkTreeViewColumn
*arg2
,
3680 GtkTreeStore
* store
= (GtkTreeStore
*)gtk_tree_view_get_model (treeview
);
3684 if (gtk_tree_model_get_iter ((GtkTreeModel
*)store
, &iter
, arg1
)){
3685 gtk_tree_model_get ((GtkTreeModel
*)store
, &iter
, CHECKBOX_COLUMN
, &value
, -1);
3686 value
= value
? FALSE
: TRUE
;
3687 gtk_tree_store_set (GTK_TREE_STORE (store
), &iter
, CHECKBOX_COLUMN
, value
, -1);
3693 /* According to user's selection, update selector(filter)
3696 void update_filter(LttvTracesetSelector
*s
, GtkTreeStore
*store
)
3698 GtkTreeIter iter
, child_iter
, child_iter1
, child_iter2
;
3699 int i
, j
, k
, nb_eventtype
;
3700 LttvTraceSelector
* trace
;
3701 LttvTracefileSelector
* tracefile
;
3702 LttvEventtypeSelector
* eventtype
;
3703 gboolean value
, value1
, value2
;
3705 if(gtk_tree_model_get_iter_first((GtkTreeModel
*)store
, &iter
)){
3708 trace
= lttv_traceset_selector_trace_get(s
, i
);
3709 nb_eventtype
= lttv_trace_selector_eventtype_number(trace
);
3710 gtk_tree_model_get ((GtkTreeModel
*)store
, &iter
, CHECKBOX_COLUMN
, &value
,-1);
3713 if(gtk_tree_model_iter_children ((GtkTreeModel
*)store
, &child_iter
, &iter
)){
3715 if(j
<1){//eventtype selector for trace
3716 gtk_tree_model_get ((GtkTreeModel
*)store
, &child_iter
, CHECKBOX_COLUMN
, &value2
,-1);
3719 if(gtk_tree_model_iter_children ((GtkTreeModel
*)store
, &child_iter1
, &child_iter
)){
3721 eventtype
= lttv_trace_selector_eventtype_get(trace
,k
);
3722 gtk_tree_model_get ((GtkTreeModel
*)store
, &child_iter1
, CHECKBOX_COLUMN
, &value2
,-1);
3723 lttv_eventtype_selector_set_selected(eventtype
,value2
);
3725 }while(gtk_tree_model_iter_next((GtkTreeModel
*)store
, &child_iter1
));
3728 }else{ //tracefile selector
3729 tracefile
= lttv_trace_selector_tracefile_get(trace
, j
- 1);
3730 gtk_tree_model_get ((GtkTreeModel
*)store
, &child_iter
, CHECKBOX_COLUMN
, &value1
,-1);
3731 lttv_tracefile_selector_set_selected(tracefile
,value1
);
3733 gtk_tree_model_iter_children((GtkTreeModel
*)store
, &child_iter1
, &child_iter
); //eventtype selector
3734 gtk_tree_model_get ((GtkTreeModel
*)store
, &child_iter1
, CHECKBOX_COLUMN
, &value2
,-1);
3737 if(gtk_tree_model_iter_children ((GtkTreeModel
*)store
, &child_iter2
, &child_iter1
)){
3738 do{//eventtype selector for tracefile
3739 eventtype
= lttv_tracefile_selector_eventtype_get(tracefile
,k
);
3740 gtk_tree_model_get ((GtkTreeModel
*)store
, &child_iter2
, CHECKBOX_COLUMN
, &value2
,-1);
3741 lttv_eventtype_selector_set_selected(eventtype
,value2
);
3743 }while(gtk_tree_model_iter_next((GtkTreeModel
*)store
, &child_iter2
));
3749 }while(gtk_tree_model_iter_next((GtkTreeModel
*)store
, &child_iter
));
3752 lttv_trace_selector_set_selected(trace
,value
);
3754 }while(gtk_tree_model_iter_next((GtkTreeModel
*)store
, &iter
));
3759 /* Display a dialogue showing all eventtypes and traces, let user to select the interested
3760 * eventtypes, tracefiles and traces (filter)
3763 gboolean
get_filter_selection(LttvTracesetSelector
*s
,char *title
, char * column_title
)
3765 GtkWidget
* dialogue
;
3766 GtkTreeStore
* store
;
3768 GtkWidget
* scroll_win
;
3769 GtkCellRenderer
* renderer
;
3770 GtkTreeViewColumn
* column
;
3771 GtkTreeIter iter
, child_iter
, child_iter1
, child_iter2
;
3772 int i
, j
, k
, id
, nb_trace
, nb_tracefile
, nb_eventtype
;
3773 LttvTraceSelector
* trace
;
3774 LttvTracefileSelector
* tracefile
;
3775 LttvEventtypeSelector
* eventtype
;
3779 dialogue
= gtk_dialog_new_with_buttons(title
,
3782 GTK_STOCK_OK
,GTK_RESPONSE_ACCEPT
,
3783 GTK_STOCK_CANCEL
,GTK_RESPONSE_REJECT
,
3785 gtk_window_set_default_size((GtkWindow
*)dialogue
, 300, 500);
3787 store
= gtk_tree_store_new (TOTAL_COLUMNS
, G_TYPE_BOOLEAN
, G_TYPE_STRING
);
3788 tree
= gtk_tree_view_new_with_model (GTK_TREE_MODEL (store
));
3789 g_object_unref (G_OBJECT (store
));
3790 g_signal_connect (G_OBJECT (tree
), "row-activated",
3791 G_CALLBACK (checkbox_changed
),
3795 renderer
= gtk_cell_renderer_toggle_new ();
3796 gtk_cell_renderer_toggle_set_radio((GtkCellRendererToggle
*)renderer
, FALSE
);
3798 g_object_set (G_OBJECT (renderer
),"activatable", TRUE
, NULL
);
3800 column
= gtk_tree_view_column_new_with_attributes ("Checkbox",
3802 "active", CHECKBOX_COLUMN
,
3804 gtk_tree_view_column_set_alignment (column
, 0.5);
3805 gtk_tree_view_column_set_fixed_width (column
, 20);
3806 gtk_tree_view_append_column (GTK_TREE_VIEW (tree
), column
);
3808 renderer
= gtk_cell_renderer_text_new ();
3809 column
= gtk_tree_view_column_new_with_attributes (column_title
,
3811 "text", NAME_COLUMN
,
3813 gtk_tree_view_column_set_alignment (column
, 0.0);
3814 gtk_tree_view_append_column (GTK_TREE_VIEW (tree
), column
);
3815 gtk_tree_view_set_headers_visible(GTK_TREE_VIEW (tree
), FALSE
);
3817 scroll_win
= gtk_scrolled_window_new (NULL
, NULL
);
3818 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll_win
),
3819 GTK_POLICY_AUTOMATIC
,GTK_POLICY_AUTOMATIC
);
3820 gtk_container_add (GTK_CONTAINER (scroll_win
), tree
);
3822 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialogue
)->vbox
), scroll_win
,TRUE
, TRUE
,0);
3824 gtk_widget_show(scroll_win
);
3825 gtk_widget_show(tree
);
3827 nb_trace
= lttv_traceset_selector_trace_number(s
);
3828 for(i
=0;i
<nb_trace
;i
++){
3829 trace
= lttv_traceset_selector_trace_get(s
, i
);
3830 name
= lttv_trace_selector_get_name(trace
);
3831 gtk_tree_store_append (store
, &iter
, NULL
);
3832 checked
= lttv_trace_selector_get_selected(trace
);
3833 gtk_tree_store_set (store
, &iter
,
3834 CHECKBOX_COLUMN
,checked
,
3838 gtk_tree_store_append (store
, &child_iter
, &iter
);
3839 gtk_tree_store_set (store
, &child_iter
,
3840 CHECKBOX_COLUMN
, checked
,
3841 NAME_COLUMN
,"eventtype",
3844 nb_eventtype
= lttv_trace_selector_eventtype_number(trace
);
3845 for(j
=0;j
<nb_eventtype
;j
++){
3846 eventtype
= lttv_trace_selector_eventtype_get(trace
,j
);
3847 name
= lttv_eventtype_selector_get_name(eventtype
);
3848 checked
= lttv_eventtype_selector_get_selected(eventtype
);
3849 gtk_tree_store_append (store
, &child_iter1
, &child_iter
);
3850 gtk_tree_store_set (store
, &child_iter1
,
3851 CHECKBOX_COLUMN
, checked
,
3856 nb_tracefile
= lttv_trace_selector_tracefile_number(trace
);
3857 for(j
=0;j
<nb_tracefile
;j
++){
3858 tracefile
= lttv_trace_selector_tracefile_get(trace
, j
);
3859 name
= lttv_tracefile_selector_get_name(tracefile
);
3860 gtk_tree_store_append (store
, &child_iter
, &iter
);
3861 checked
= lttv_tracefile_selector_get_selected(tracefile
);
3862 gtk_tree_store_set (store
, &child_iter
,
3863 CHECKBOX_COLUMN
, checked
,
3867 gtk_tree_store_append (store
, &child_iter1
, &child_iter
);
3868 gtk_tree_store_set (store
, &child_iter1
,
3869 CHECKBOX_COLUMN
, checked
,
3870 NAME_COLUMN
,"eventtype",
3873 for(k
=0;k
<nb_eventtype
;k
++){
3874 eventtype
= lttv_tracefile_selector_eventtype_get(tracefile
,k
);
3875 name
= lttv_eventtype_selector_get_name(eventtype
);
3876 checked
= lttv_eventtype_selector_get_selected(eventtype
);
3877 gtk_tree_store_append (store
, &child_iter2
, &child_iter1
);
3878 gtk_tree_store_set (store
, &child_iter2
,
3879 CHECKBOX_COLUMN
, checked
,
3886 id
= gtk_dialog_run(GTK_DIALOG(dialogue
));
3888 case GTK_RESPONSE_ACCEPT
:
3889 case GTK_RESPONSE_OK
:
3890 update_filter(s
, store
);
3891 gtk_widget_destroy(dialogue
);
3893 case GTK_RESPONSE_REJECT
:
3894 case GTK_RESPONSE_CANCEL
:
3896 gtk_widget_destroy(dialogue
);
3903 /* Select a trace which will be removed from traceset
3906 char * get_remove_trace(char ** all_trace_name
, int nb_trace
)
3908 return get_selection(all_trace_name
, nb_trace
,
3909 "Select a trace", "Trace pathname");
3913 /* Select a module which will be loaded
3916 char * get_load_module(char ** load_module_name
, int nb_module
)
3918 return get_selection(load_module_name
, nb_module
,
3919 "Select a module to load", "Module name");
3925 /* Select a module which will be unloaded
3928 char * get_unload_module(char ** loaded_module_name
, int nb_module
)
3930 return get_selection(loaded_module_name
, nb_module
,
3931 "Select a module to unload", "Module name");
3935 /* Display a dialogue which shows all selectable items, let user to
3936 * select one of them
3939 char * get_selection(char ** loaded_module_name
, int nb_module
,
3940 char *title
, char * column_title
)
3942 GtkWidget
* dialogue
;
3943 GtkWidget
* scroll_win
;
3945 GtkListStore
* store
;
3946 GtkTreeViewColumn
* column
;
3947 GtkCellRenderer
* renderer
;
3948 GtkTreeSelection
* select
;
3951 char * unload_module_name
= NULL
;
3953 dialogue
= gtk_dialog_new_with_buttons(title
,
3956 GTK_STOCK_OK
,GTK_RESPONSE_ACCEPT
,
3957 GTK_STOCK_CANCEL
,GTK_RESPONSE_REJECT
,
3959 gtk_window_set_default_size((GtkWindow
*)dialogue
, 500, 200);
3961 scroll_win
= gtk_scrolled_window_new (NULL
, NULL
);
3962 gtk_widget_show ( scroll_win
);
3963 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll_win
),
3964 GTK_POLICY_AUTOMATIC
, GTK_POLICY_AUTOMATIC
);
3966 store
= gtk_list_store_new (N_COLUMNS
,G_TYPE_STRING
);
3967 tree
= gtk_tree_view_new_with_model(GTK_TREE_MODEL (store
));
3968 gtk_widget_show ( tree
);
3969 g_object_unref (G_OBJECT (store
));
3971 renderer
= gtk_cell_renderer_text_new ();
3972 column
= gtk_tree_view_column_new_with_attributes (column_title
,
3974 "text", MODULE_COLUMN
,
3976 gtk_tree_view_column_set_alignment (column
, 0.5);
3977 gtk_tree_view_column_set_fixed_width (column
, 150);
3978 gtk_tree_view_append_column (GTK_TREE_VIEW (tree
), column
);
3980 select
= gtk_tree_view_get_selection (GTK_TREE_VIEW (tree
));
3981 gtk_tree_selection_set_mode (select
, GTK_SELECTION_SINGLE
);
3983 gtk_container_add (GTK_CONTAINER (scroll_win
), tree
);
3985 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialogue
)->vbox
), scroll_win
,TRUE
, TRUE
,0);
3987 for(i
=0;i
<nb_module
;i
++){
3988 gtk_list_store_append (store
, &iter
);
3989 gtk_list_store_set (store
, &iter
, MODULE_COLUMN
,loaded_module_name
[i
],-1);
3992 id
= gtk_dialog_run(GTK_DIALOG(dialogue
));
3994 case GTK_RESPONSE_ACCEPT
:
3995 case GTK_RESPONSE_OK
:
3996 if (gtk_tree_selection_get_selected (select
, (GtkTreeModel
**)&store
, &iter
)){
3997 gtk_tree_model_get ((GtkTreeModel
*)store
, &iter
, MODULE_COLUMN
, &unload_module_name
, -1);
3999 case GTK_RESPONSE_REJECT
:
4000 case GTK_RESPONSE_CANCEL
:
4002 gtk_widget_destroy(dialogue
);
4006 return unload_module_name
;
4010 /* Insert all menu entry and tool buttons into this main window
4015 void add_all_menu_toolbar_constructors(MainWindow
* mw
, gpointer user_data
)
4019 lttvwindow_viewer_constructor constructor
;
4020 LttvMenus
* global_menu
, * instance_menu
;
4021 LttvToolbars
* global_toolbar
, * instance_toolbar
;
4022 LttvMenuClosure
*menu_item
;
4023 LttvToolbarClosure
*toolbar_item
;
4024 LttvAttributeValue value
;
4025 LttvIAttribute
*global_attributes
= LTTV_IATTRIBUTE(lttv_global_attributes());
4026 LttvIAttribute
*attributes
= mw
->attributes
;
4027 GtkWidget
* tool_menu_title_menu
, *new_widget
, *pixmap
;
4029 g_assert(lttv_iattribute_find_by_path(global_attributes
,
4030 "viewers/menu", LTTV_POINTER
, &value
));
4031 if(*(value
.v_pointer
) == NULL
)
4032 *(value
.v_pointer
) = lttv_menus_new();
4033 global_menu
= (LttvMenus
*)*(value
.v_pointer
);
4035 g_assert(lttv_iattribute_find_by_path(attributes
,
4036 "viewers/menu", LTTV_POINTER
, &value
));
4037 if(*(value
.v_pointer
) == NULL
)
4038 *(value
.v_pointer
) = lttv_menus_new();
4039 instance_menu
= (LttvMenus
*)*(value
.v_pointer
);
4043 g_assert(lttv_iattribute_find_by_path(global_attributes
,
4044 "viewers/toolbar", LTTV_POINTER
, &value
));
4045 if(*(value
.v_pointer
) == NULL
)
4046 *(value
.v_pointer
) = lttv_toolbars_new();
4047 global_toolbar
= (LttvToolbars
*)*(value
.v_pointer
);
4049 g_assert(lttv_iattribute_find_by_path(attributes
,
4050 "viewers/toolbar", LTTV_POINTER
, &value
));
4051 if(*(value
.v_pointer
) == NULL
)
4052 *(value
.v_pointer
) = lttv_toolbars_new();
4053 instance_toolbar
= (LttvToolbars
*)*(value
.v_pointer
);
4055 /* Add missing menu entries to window instance */
4056 for(i
=0;i
<global_menu
->len
;i
++) {
4057 menu_item
= &g_array_index(global_menu
, LttvMenuClosure
, i
);
4059 //add menu_item to window instance;
4060 constructor
= menu_item
->con
;
4061 tool_menu_title_menu
= lookup_widget(mw
->mwindow
,"ToolMenuTitle_menu");
4063 gtk_menu_item_new_with_mnemonic (menu_item
->menu_text
);
4064 gtk_container_add (GTK_CONTAINER (tool_menu_title_menu
),
4066 g_signal_connect ((gpointer
) new_widget
, "activate",
4067 G_CALLBACK (insert_viewer_wrap
),
4069 gtk_widget_show (new_widget
);
4070 lttv_menus_add(instance_menu
, menu_item
->con
,
4071 menu_item
->menu_path
,
4072 menu_item
->menu_text
,
4077 /* Add missing toolbar entries to window instance */
4078 for(i
=0;i
<global_toolbar
->len
;i
++) {
4079 toolbar_item
= &g_array_index(global_toolbar
, LttvToolbarClosure
, i
);
4081 //add toolbar_item to window instance;
4082 constructor
= toolbar_item
->con
;
4083 tool_menu_title_menu
= lookup_widget(mw
->mwindow
,"MToolbar1");
4084 pixbuf
= gdk_pixbuf_new_from_xpm_data((const char**)toolbar_item
->pixmap
);
4085 pixmap
= gtk_image_new_from_pixbuf(pixbuf
);
4087 gtk_toolbar_append_element (GTK_TOOLBAR (tool_menu_title_menu
),
4088 GTK_TOOLBAR_CHILD_BUTTON
,
4091 toolbar_item
->tooltip
, NULL
,
4092 pixmap
, NULL
, NULL
);
4093 gtk_label_set_use_underline(
4094 GTK_LABEL (((GtkToolbarChild
*) (
4095 g_list_last (GTK_TOOLBAR
4096 (tool_menu_title_menu
)->children
)->data
))->label
),
4098 gtk_container_set_border_width (GTK_CONTAINER (new_widget
), 1);
4099 g_signal_connect ((gpointer
) new_widget
,
4101 G_CALLBACK (insert_viewer_wrap
),
4103 gtk_widget_show (new_widget
);
4105 lttv_toolbars_add(instance_toolbar
, toolbar_item
->con
,
4106 toolbar_item
->tooltip
,
4107 toolbar_item
->pixmap
,
4115 /* Create a main window
4118 void construct_main_window(MainWindow
* parent
)
4120 g_debug("construct_main_window()");
4121 GtkWidget
* new_window
; /* New generated main window */
4122 MainWindow
* new_m_window
;/* New main window structure */
4123 GtkNotebook
* notebook
;
4124 LttvIAttribute
*attributes
=
4125 LTTV_IATTRIBUTE(g_object_new(LTTV_ATTRIBUTE_TYPE
, NULL
));
4126 LttvAttributeValue value
;
4129 new_m_window
= g_new(MainWindow
, 1);
4131 // Add the object's information to the module's array
4132 g_main_window_list
= g_slist_append(g_main_window_list
, new_m_window
);
4134 new_window
= create_MWindow();
4135 gtk_widget_show (new_window
);
4137 new_m_window
->mwindow
= new_window
;
4138 new_m_window
->attributes
= attributes
;
4140 g_assert(lttv_iattribute_find_by_path(attributes
,
4141 "viewers/menu", LTTV_POINTER
, &value
));
4142 *(value
.v_pointer
) = lttv_menus_new();
4144 g_assert(lttv_iattribute_find_by_path(attributes
,
4145 "viewers/toolbar", LTTV_POINTER
, &value
));
4146 *(value
.v_pointer
) = lttv_toolbars_new();
4148 add_all_menu_toolbar_constructors(new_m_window
, NULL
);
4150 g_object_set_data_full(G_OBJECT(new_window
),
4152 (gpointer
)new_m_window
,
4153 (GDestroyNotify
)g_free
);
4154 //create a default tab
4155 notebook
= (GtkNotebook
*)lookup_widget(new_m_window
->mwindow
, "MNotebook");
4156 if(notebook
== NULL
){
4157 g_printf("Notebook does not exist\n");
4160 //gtk_notebook_popup_enable (GTK_NOTEBOOK(notebook));
4161 //for now there is no name field in LttvTraceset structure
4162 //Use "Traceset" as the label for the default tab
4164 GtkWidget
* parent_notebook
= lookup_widget(parent
->mwindow
, "MNotebook");
4165 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(parent_notebook
),
4166 gtk_notebook_get_current_page(GTK_NOTEBOOK(parent_notebook
)));
4172 parent_tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
4174 new_tab
= create_tab(new_m_window
, parent_tab
, notebook
, "Traceset");
4176 new_tab
= create_tab(new_m_window
, NULL
, notebook
, "Traceset");
4177 /* First window, use command line trace */
4178 if(g_init_trace
!= NULL
){
4179 lttvwindow_add_trace(new_tab
,
4183 LttvTraceset
*traceset
= new_tab
->traceset_info
->traceset
;
4184 SetTraceset(new_tab
, traceset
);
4187 g_printf("There are now : %d windows\n",g_slist_length(g_main_window_list
));
4191 /* Free the memory occupied by a tab structure
4195 void tab_destructor(Tab
* tab_instance
)
4197 int i
, nb
, ref_count
;
4200 if(tab_instance
->attributes
)
4201 g_object_unref(tab_instance
->attributes
);
4203 if(tab_instance
->interrupted_state
)
4204 g_object_unref(tab_instance
->interrupted_state
);
4207 if(tab_instance
->traceset_info
->traceset_context
!= NULL
){
4208 //remove state update hooks
4209 lttv_state_remove_event_hooks(
4210 (LttvTracesetState
*)tab_instance
->traceset_info
->
4212 lttv_context_fini(LTTV_TRACESET_CONTEXT(tab_instance
->traceset_info
->
4214 g_object_unref(tab_instance
->traceset_info
->traceset_context
);
4216 if(tab_instance
->traceset_info
->traceset
!= NULL
) {
4217 nb
= lttv_traceset_number(tab_instance
->traceset_info
->traceset
);
4218 for(i
= 0 ; i
< nb
; i
++) {
4219 trace
= lttv_traceset_get(tab_instance
->traceset_info
->traceset
, i
);
4220 ref_count
= lttv_trace_get_ref_number(trace
);
4222 ltt_trace_close(lttv_trace(trace
));
4226 lttv_traceset_destroy(tab_instance
->traceset_info
->traceset
);
4227 /* Remove the idle events requests processing function of the tab */
4228 g_idle_remove_by_data(tab_instance
);
4230 g_slist_free(tab_instance
->events_requests
);
4231 g_free(tab_instance
->traceset_info
);
4232 g_free(tab_instance
);
4236 /* Create a tab and insert it into the current main window
4239 Tab
* create_tab(MainWindow
* mw
, Tab
*copy_tab
,
4240 GtkNotebook
* notebook
, char * label
)
4246 //create a new tab data structure
4249 //construct and initialize the traceset_info
4250 tab
->traceset_info
= g_new(TracesetInfo
,1);
4253 tab
->traceset_info
->traceset
=
4254 lttv_traceset_copy(copy_tab
->traceset_info
->traceset
);
4256 tab
->traceset_info
->traceset
= lttv_traceset_new();
4260 lttv_attribute_write_xml(
4261 lttv_traceset_attribute(tab
->traceset_info
->traceset
),
4267 tab
->time_manager_lock
= FALSE
;
4268 tab
->current_time_manager_lock
= FALSE
;
4270 //FIXME copy not implemented in lower level
4271 tab
->traceset_info
->traceset_context
=
4272 g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
4273 g_assert(tab
->traceset_info
->traceset_context
!= NULL
);
4275 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
),
4276 tab
->traceset_info
->traceset
);
4277 //add state update hooks
4278 lttv_state_add_event_hooks(
4279 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
4281 //determine the current_time and time_window of the tab
4283 if(copy_tab
!= NULL
){
4284 tab
->time_window
= copy_tab
->time_window
;
4285 tab
->current_time
= copy_tab
->current_time
;
4287 tab
->time_window
.start_time
=
4288 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
4289 time_span
.start_time
;
4290 if(DEFAULT_TIME_WIDTH_S
<
4291 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
4292 time_span
.end_time
.tv_sec
)
4293 tmp_time
.tv_sec
= DEFAULT_TIME_WIDTH_S
;
4296 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
4297 time_span
.end_time
.tv_sec
;
4298 tmp_time
.tv_nsec
= 0;
4299 tab
->time_window
.time_width
= tmp_time
;
4300 tab
->current_time
.tv_sec
=
4301 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
4302 time_span
.start_time
.tv_sec
;
4303 tab
->current_time
.tv_nsec
=
4304 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
4305 time_span
.start_time
.tv_nsec
;
4308 tab
->attributes
= LTTV_IATTRIBUTE(g_object_new(LTTV_ATTRIBUTE_TYPE
, NULL
));
4309 tab
->interrupted_state
= g_object_new(LTTV_ATTRIBUTE_TYPE
, NULL
);
4311 tab
->vbox
= gtk_vbox_new(FALSE
, 2);
4312 tab
->viewer_container
= gtk_vbox_new(TRUE
, 2);
4313 tab
->scrollbar
= gtk_hscrollbar_new(NULL
);
4314 //tab->multivpaned = gtk_multi_vpaned_new();
4316 gtk_box_pack_start(GTK_BOX(tab
->vbox
),
4317 tab
->viewer_container
,
4319 TRUE
, /* Give the extra space to the child */
4320 0); /* No padding */
4322 /* Create the timebar */
4324 tab
->MTimebar
= gtk_hbox_new(FALSE
, 2);
4325 gtk_widget_show(tab
->MTimebar
);
4327 tab
->MText1
= gtk_label_new("Time Frame start: ");
4328 gtk_widget_show(tab
->MText1
);
4329 tab
->MText2
= gtk_label_new("s");
4330 gtk_widget_show(tab
->MText2
);
4331 tab
->MText3a
= gtk_label_new("ns");
4332 gtk_widget_show(tab
->MText3a
);
4333 tab
->MText3b
= gtk_label_new("end:");
4334 gtk_widget_show(tab
->MText3b
);
4335 tab
->MText4
= gtk_label_new("s");
4336 gtk_widget_show(tab
->MText4
);
4337 tab
->MText5a
= gtk_label_new("ns");
4338 gtk_widget_show(tab
->MText5a
);
4339 tab
->MText5b
= gtk_label_new("Current Time:");
4340 gtk_widget_show(tab
->MText5b
);
4341 tab
->MText6
= gtk_label_new("s");
4342 gtk_widget_show(tab
->MText6
);
4343 tab
->MText7
= gtk_label_new("ns");
4344 gtk_widget_show(tab
->MText7
);
4346 tab
->MEntry1
= gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4347 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab
->MEntry1
),0);
4348 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab
->MEntry1
),TRUE
);
4349 gtk_widget_show(tab
->MEntry1
);
4350 tab
->MEntry2
= gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4351 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab
->MEntry2
),0);
4352 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab
->MEntry2
),TRUE
);
4353 gtk_widget_show(tab
->MEntry2
);
4354 tab
->MEntry3
= gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4355 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab
->MEntry3
),0);
4356 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab
->MEntry3
),TRUE
);
4357 gtk_widget_show(tab
->MEntry3
);
4358 tab
->MEntry4
= gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4359 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab
->MEntry4
),0);
4360 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab
->MEntry4
),TRUE
);
4361 gtk_widget_show(tab
->MEntry4
);
4362 tab
->MEntry5
= gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4363 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab
->MEntry5
),0);
4364 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab
->MEntry5
),TRUE
);
4365 gtk_widget_show(tab
->MEntry5
);
4366 tab
->MEntry6
= gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4367 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab
->MEntry6
),0);
4368 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab
->MEntry6
),TRUE
);
4369 gtk_widget_show(tab
->MEntry6
);
4372 GtkWidget
*temp_widget
;
4374 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MText1
, FALSE
, FALSE
, 0);
4375 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEntry1
, FALSE
, FALSE
, 0);
4376 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MText2
, FALSE
, FALSE
, 0);
4377 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEntry2
, FALSE
, FALSE
, 0);
4378 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MText3a
, FALSE
, FALSE
, 0);
4379 temp_widget
= gtk_vseparator_new();
4380 gtk_widget_show(temp_widget
);
4381 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), temp_widget
, FALSE
, FALSE
, 0);
4382 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MText3b
, FALSE
, FALSE
, 0);
4383 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEntry3
, FALSE
, FALSE
, 0);
4384 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MText4
, FALSE
, FALSE
, 0);
4385 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEntry4
, FALSE
, FALSE
, 0);
4386 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MText5a
, FALSE
, FALSE
, 0);
4387 temp_widget
= gtk_vseparator_new();
4388 gtk_widget_show(temp_widget
);
4389 gtk_box_pack_end (GTK_BOX (tab
->MTimebar
), tab
->MText7
, FALSE
, FALSE
, 0);
4390 gtk_box_pack_end (GTK_BOX (tab
->MTimebar
), tab
->MEntry6
, FALSE
, FALSE
, 0);
4391 gtk_box_pack_end (GTK_BOX (tab
->MTimebar
), tab
->MText6
, FALSE
, FALSE
, 0);
4392 gtk_box_pack_end (GTK_BOX (tab
->MTimebar
), tab
->MEntry5
, FALSE
, FALSE
, 0);
4393 gtk_box_pack_end (GTK_BOX (tab
->MTimebar
), tab
->MText5b
, FALSE
, FALSE
, 0);
4394 gtk_box_pack_end (GTK_BOX (tab
->MTimebar
), temp_widget
, FALSE
, FALSE
, 0);
4397 gtk_box_pack_end(GTK_BOX(tab
->vbox
),
4399 FALSE
, /* Do not expand */
4400 FALSE
, /* Fill has no effect here (expand false) */
4401 0); /* No padding */
4403 gtk_box_pack_end(GTK_BOX(tab
->vbox
),
4405 FALSE
, /* Do not expand */
4406 FALSE
, /* Fill has no effect here (expand false) */
4407 0); /* No padding */
4409 g_object_set_data(G_OBJECT(tab
->viewer_container
), "focused_viewer", NULL
);
4415 // Display a label with a X
4416 GtkWidget *w_hbox = gtk_hbox_new(FALSE, 4);
4417 GtkWidget *w_label = gtk_label_new (label);
4418 GtkWidget *pixmap = create_pixmap(GTK_WIDGET(notebook), "close.png");
4419 GtkWidget *w_button = gtk_button_new ();
4420 gtk_container_add(GTK_CONTAINER(w_button), pixmap);
4421 //GtkWidget *w_button = gtk_button_new_with_label("x");
4423 gtk_button_set_relief(GTK_BUTTON(w_button), GTK_RELIEF_NONE);
4425 gtk_box_pack_start(GTK_BOX(w_hbox), w_label, TRUE, TRUE, 0);
4426 gtk_box_pack_end(GTK_BOX(w_hbox), w_button, FALSE,
4429 g_signal_connect_swapped (w_button, "clicked",
4430 G_CALLBACK (on_close_tab_X_clicked),
4433 gtk_widget_set_state(w_button, GTK_STATE_ACTIVE);
4435 gtk_widget_show (w_label);
4436 gtk_widget_show (pixmap);
4437 gtk_widget_show (w_button);
4438 gtk_widget_show (w_hbox);
4440 tab->label = w_hbox;
4444 tab
->label
= gtk_label_new (label
);
4446 gtk_widget_show(tab
->label
);
4447 gtk_widget_show(tab
->scrollbar
);
4448 gtk_widget_show(tab
->viewer_container
);
4449 gtk_widget_show(tab
->vbox
);
4450 //gtk_widget_show(tab->multivpaned);
4453 /* Start with empty events requests list */
4454 tab
->events_requests
= NULL
;
4455 tab
->events_request_pending
= FALSE
;
4457 g_object_set_data_full(
4458 G_OBJECT(tab
->vbox
),
4461 (GDestroyNotify
)tab_destructor
);
4463 g_signal_connect(G_OBJECT(tab
->scrollbar
), "value-changed",
4464 G_CALLBACK(scroll_value_changed_cb
), tab
);
4466 g_signal_connect ((gpointer
) tab
->MEntry1
, "value-changed",
4467 G_CALLBACK (on_MEntry1_value_changed
),
4469 g_signal_connect ((gpointer
) tab
->MEntry2
, "value-changed",
4470 G_CALLBACK (on_MEntry2_value_changed
),
4472 g_signal_connect ((gpointer
) tab
->MEntry3
, "value-changed",
4473 G_CALLBACK (on_MEntry3_value_changed
),
4475 g_signal_connect ((gpointer
) tab
->MEntry4
, "value-changed",
4476 G_CALLBACK (on_MEntry4_value_changed
),
4478 g_signal_connect ((gpointer
) tab
->MEntry5
, "value-changed",
4479 G_CALLBACK (on_MEntry5_value_changed
),
4481 g_signal_connect ((gpointer
) tab
->MEntry6
, "value-changed",
4482 G_CALLBACK (on_MEntry6_value_changed
),
4485 //g_signal_connect(G_OBJECT(tab->scrollbar), "changed",
4486 // G_CALLBACK(scroll_value_changed_cb), tab);
4489 //insert tab into notebook
4490 gtk_notebook_append_page(notebook
,
4493 list
= gtk_container_get_children(GTK_CONTAINER(notebook
));
4494 gtk_notebook_set_current_page(notebook
,g_list_length(list
)-1);
4495 // always show : not if(g_list_length(list)>1)
4496 gtk_notebook_set_show_tabs(notebook
, TRUE
);
4502 * execute_events_requests
4504 * Idle function that executes the pending requests for a tab.
4506 * @return return value : TRUE : keep the idle function, FALSE : remove it.
4508 gboolean
execute_events_requests(Tab
*tab
)
4510 return ( lttvwindow_process_pending_requests(tab
) );