1 /* This file is part of the Linux Trace Toolkit viewer
2 * Copyright (C) 2003-2004 XangXiu Yang, Mathieu Desnoyers
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License Version 2 as
6 * published by the Free Software Foundation;
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place - Suite 330, Boston,
23 #include <limits.h> // for PATH_MAX
28 #include "callbacks.h"
29 #include "interface.h"
31 #include <ltt/trace.h>
32 #include <ltt/facility.h>
34 #include <ltt/event.h>
35 #include <lttv/lttv.h>
36 #include <lttv/module.h>
37 #include <lttv/iattribute.h>
38 #include <lttv/stats.h>
39 #include <lttvwindow/mainwindow.h>
40 #include <lttvwindow/mainwindow-private.h>
41 #include <lttvwindow/menu.h>
42 #include <lttvwindow/toolbar.h>
43 #include <lttvwindow/lttvwindow.h>
44 #include <lttvwindow/lttvwindowtraces.h>
45 #include <lttvwindow/gtkdirsel.h>
46 #include <lttvwindow/lttvfilter.h>
49 #define DEFAULT_TIME_WIDTH_S 1
51 extern LttvTrace
*g_init_trace
;
54 /** Array containing instanced objects. */
55 extern GSList
* g_main_window_list
;
57 /** MD : keep old directory. */
58 static char remember_plugins_dir
[PATH_MAX
] = "";
59 static char remember_trace_dir
[PATH_MAX
] = "";
62 MainWindow
* get_window_data_struct(GtkWidget
* widget
);
63 char * get_load_module(char ** load_module_name
, int nb_module
);
64 char * get_unload_module(char ** loaded_module_name
, int nb_module
);
65 char * get_remove_trace(char ** all_trace_name
, int nb_trace
);
66 char * get_selection(char ** all_name
, int nb
, char *title
, char * column_title
);
67 gboolean
get_filter_selection(LttvTracesetSelector
*s
, char *title
, char * column_title
);
68 Tab
* create_tab(MainWindow
* mw
, Tab
*copy_tab
,
69 GtkNotebook
* notebook
, char * label
);
71 static void insert_viewer(GtkWidget
* widget
, lttvwindow_viewer_constructor constructor
);
72 void update_filter(LttvTracesetSelector
*s
, GtkTreeStore
*store
);
74 void checkbox_changed(GtkTreeView
*treeview
,
76 GtkTreeViewColumn
*arg2
,
78 void remove_trace_from_traceset_selector(GtkWidget
* paned
, unsigned i
);
79 void add_trace_into_traceset_selector(GtkWidget
* paned
, LttTrace
* trace
);
80 Tab
*create_new_tab(GtkWidget
* widget
, gpointer user_data
);
82 LttvTracesetSelector
* construct_traceset_selector(LttvTraceset
* traceset
);
84 static gboolean
lttvwindow_process_pending_requests(Tab
*tab
);
98 /* Construct a selector(filter), which will be associated with a viewer,
99 * and provides an interface for user to select interested events and traces
102 LttvTracesetSelector
* construct_traceset_selector(LttvTraceset
* traceset
)
104 LttvTracesetSelector
* s
;
105 LttvTraceSelector
* trace
;
106 LttvTracefileSelector
* tracefile
;
107 LttvEventtypeSelector
* eventtype
;
109 int nb_trace
, nb_tracefile
, nb_control
, nb_per_cpu
, nb_facility
, nb_event
;
116 s
= lttv_traceset_selector_new(lttv_traceset_name(traceset
));
117 nb_trace
= lttv_traceset_number(traceset
);
118 for(i
=0;i
<nb_trace
;i
++){
119 trace_v
= lttv_traceset_get(traceset
, i
);
120 t
= lttv_trace(trace_v
);
121 trace
= lttv_trace_selector_new(t
);
122 lttv_traceset_selector_trace_add(s
, trace
);
124 nb_facility
= ltt_trace_facility_number(t
);
125 for(k
=0;k
<nb_facility
;k
++){
126 fac
= ltt_trace_facility_get(t
,k
);
127 nb_event
= (int) ltt_facility_eventtype_number(fac
);
128 for(m
=0;m
<nb_event
;m
++){
129 et
= ltt_facility_eventtype_get(fac
,m
);
130 eventtype
= lttv_eventtype_selector_new(et
);
131 lttv_trace_selector_eventtype_add(trace
, eventtype
);
135 nb_control
= ltt_trace_control_tracefile_number(t
);
136 nb_per_cpu
= ltt_trace_per_cpu_tracefile_number(t
);
137 nb_tracefile
= nb_control
+ nb_per_cpu
;
139 for(j
= 0 ; j
< nb_tracefile
; j
++) {
141 tf
= ltt_trace_control_tracefile_get(t
, j
);
143 tf
= ltt_trace_per_cpu_tracefile_get(t
, j
- nb_control
);
144 tracefile
= lttv_tracefile_selector_new(tf
);
145 lttv_trace_selector_tracefile_add(trace
, tracefile
);
146 lttv_eventtype_selector_copy(trace
, tracefile
);
153 static gboolean
viewer_grab_focus(GtkWidget
*widget
, GdkEventButton
*event
,
156 GtkWidget
*viewer_container
= GTK_WIDGET(data
);
158 g_debug("FOCUS GRABBED");
159 g_object_set_data(G_OBJECT(viewer_container
), "focused_viewer", widget
);
163 /* insert_viewer function constructs an instance of a viewer first,
164 * then inserts the widget of the instance into the container of the
169 insert_viewer_wrap(GtkWidget
*menuitem
, gpointer user_data
)
173 insert_viewer((GtkWidget
*)menuitem
, (lttvwindow_viewer_constructor
)user_data
);
174 // selected_hook(&val);
178 /* internal functions */
179 void insert_viewer(GtkWidget
* widget
, lttvwindow_viewer_constructor constructor
)
181 GtkWidget
* viewer_container
;
182 MainWindow
* mw_data
= get_window_data_struct(widget
);
183 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
185 LttvTracesetSelector
* s
;
186 TimeInterval
* time_interval
;
187 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
188 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
192 tab
= create_new_tab(widget
, NULL
);
194 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
197 viewer_container
= tab
->viewer_container
;
199 s
= construct_traceset_selector(tab
->traceset_info
->traceset
);
200 viewer
= (GtkWidget
*)constructor(tab
, s
, "Traceset_Selector");
203 //gtk_multivpaned_widget_add(GTK_MULTIVPANED(multivpaned), viewer);
205 gtk_box_pack_end(GTK_BOX(viewer_container
),
211 g_signal_connect (G_OBJECT(viewer
),
212 "button-press-event",
213 G_CALLBACK (viewer_grab_focus
),
214 (gpointer
)viewer_container
);
216 // We unref here, because it is now referenced by the viewer_container!
217 // not for a box ... g_object_unref(G_OBJECT(viewer));
219 // The viewer will show itself when it receives a show notify
220 // So we call the show notify hooks here. It will
221 // typically add hooks for reading, we call process trace, and the
222 // end of reading hook will call gtk_widget_show and unregister the
224 // Note that show notify gets the time_requested through the call_data.
225 //show_viewer(mw_data);
226 // in expose now call_pending_read_hooks(mw_data);
231 * Function to set/update traceset for the viewers
232 * @param tab viewer's tab
233 * @param traceset traceset of the main window.
235 * 0 : traceset updated
236 * 1 : no traceset hooks to update; not an error.
239 int SetTraceset(Tab
* tab
, LttvTraceset
*traceset
)
242 LttvAttributeValue value
;
246 g_assert( lttv_iattribute_find_by_path(tab
->attributes
,
247 "hooks/updatetraceset", LTTV_POINTER
, &value
));
249 tmp
= (LttvHooks
*)*(value
.v_pointer
);
250 if(tmp
== NULL
) retval
= 1;
251 else lttv_hooks_call(tmp
,traceset
);
255 LttvTracesetContext
*tsc
=
256 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
257 TimeInterval time_span
= tsc
->time_span
;
258 GtkAdjustment
*adjustment
= gtk_range_get_adjustment(GTK_RANGE(tab
->scrollbar
));
260 g_object_set(G_OBJECT(adjustment
),
262 ltt_time_to_double(time_span
.start_time
)
263 * NANOSECONDS_PER_SECOND
, /* lower */
265 ltt_time_to_double(time_span
.end_time
)
266 * NANOSECONDS_PER_SECOND
, /* upper */
268 ltt_time_to_double(tab
->time_window
.time_width
)
269 / SCROLL_STEP_PER_PAGE
270 * NANOSECONDS_PER_SECOND
, /* step increment */
272 ltt_time_to_double(tab
->time_window
.time_width
)
273 * NANOSECONDS_PER_SECOND
, /* page increment */
275 ltt_time_to_double(tab
->time_window
.time_width
)
276 * NANOSECONDS_PER_SECOND
, /* page size */
278 gtk_adjustment_changed(adjustment
);
280 g_object_set(G_OBJECT(adjustment
),
282 ltt_time_to_double(tab
->time_window
.start_time
)
283 * NANOSECONDS_PER_SECOND
, /* value */
285 gtk_adjustment_value_changed(adjustment
);
291 * Function to set/update filter for the viewers
292 * @param tab viewer's tab
293 * @param filter filter of the main window.
296 * 0 : filters updated
297 * 1 : no filter hooks to update; not an error.
300 int SetFilter(Tab
* tab
, gpointer filter
)
303 LttvAttributeValue value
;
305 g_assert(lttv_iattribute_find_by_path(tab
->attributes
,
306 "hooks/updatefilter", LTTV_POINTER
, &value
));
308 tmp
= (LttvHooks
*)*(value
.v_pointer
);
310 if(tmp
== NULL
) return 1;
311 lttv_hooks_call(tmp
,filter
);
319 * Function to redraw each viewer belonging to the current tab
320 * @param tab viewer's tab
323 void update_traceset(Tab
*tab
)
325 LttvAttributeValue value
;
327 g_assert(lttv_iattribute_find_by_path(tab
->attributes
,
328 "hooks/updatetraceset", LTTV_POINTER
, &value
));
329 tmp
= (LttvHooks
*)*(value
.v_pointer
);
330 if(tmp
== NULL
) return;
331 lttv_hooks_call(tmp
, NULL
);
335 /* get_label function is used to get user input, it displays an input
336 * box, which allows user to input a string
339 void get_label_string (GtkWidget
* text
, gchar
* label
)
341 GtkEntry
* entry
= (GtkEntry
*)text
;
342 if(strlen(gtk_entry_get_text(entry
))!=0)
343 strcpy(label
,gtk_entry_get_text(entry
));
346 gboolean
get_label(MainWindow
* mw
, gchar
* str
, gchar
* dialogue_title
, gchar
* label_str
)
348 GtkWidget
* dialogue
;
353 dialogue
= gtk_dialog_new_with_buttons(dialogue_title
,NULL
,
355 GTK_STOCK_OK
,GTK_RESPONSE_ACCEPT
,
356 GTK_STOCK_CANCEL
,GTK_RESPONSE_REJECT
,
359 label
= gtk_label_new(label_str
);
360 gtk_widget_show(label
);
362 text
= gtk_entry_new();
363 gtk_widget_show(text
);
365 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialogue
)->vbox
), label
,TRUE
, TRUE
,0);
366 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialogue
)->vbox
), text
,FALSE
, FALSE
,0);
368 id
= gtk_dialog_run(GTK_DIALOG(dialogue
));
370 case GTK_RESPONSE_ACCEPT
:
371 get_label_string(text
,str
);
372 gtk_widget_destroy(dialogue
);
374 case GTK_RESPONSE_REJECT
:
376 gtk_widget_destroy(dialogue
);
383 /* get_window_data_struct function is actually a lookup function,
384 * given a widget which is in the tree of the main window, it will
385 * return the MainWindow data structure associated with main window
388 MainWindow
* get_window_data_struct(GtkWidget
* widget
)
391 MainWindow
* mw_data
;
393 mw
= lookup_widget(widget
, "MWindow");
395 g_printf("Main window does not exist\n");
399 mw_data
= (MainWindow
*) g_object_get_data(G_OBJECT(mw
),"main_window_data");
401 g_printf("Main window data does not exist\n");
408 /* create_new_window function, just constructs a new main window
411 void create_new_window(GtkWidget
* widget
, gpointer user_data
, gboolean clone
)
413 MainWindow
* parent
= get_window_data_struct(widget
);
416 g_printf("Clone : use the same traceset\n");
417 construct_main_window(parent
);
419 g_printf("Empty : traceset is set to NULL\n");
420 construct_main_window(NULL
);
424 GtkWidget
*viewer_container_focus(GtkWidget
*container
)
428 widget
= (GtkWidget
*)g_object_get_data(G_OBJECT(container
),
431 if(widget
== NULL
) g_debug("no widget focused");
437 gint
viewer_container_position(GtkWidget
*container
, GtkWidget
*child
)
440 if(child
== NULL
) return -1;
443 GValue value
= { 0, };
444 g_value_init(&value
, G_TYPE_INT
);
445 gtk_container_child_get_property(GTK_CONTAINER(container
),
449 pos
= g_value_get_int(&value
);
455 /* move_*_viewer functions move the selected view up/down in
459 void move_down_viewer(GtkWidget
* widget
, gpointer user_data
)
461 MainWindow
* mw
= get_window_data_struct(widget
);
462 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
464 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
465 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
471 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
474 //gtk_multivpaned_widget_move_up(GTK_MULTIVPANED(tab->multivpaned));
476 /* change the position in the vbox */
477 GtkWidget
*focus_widget
;
479 focus_widget
= viewer_container_focus(tab
->viewer_container
);
480 position
= viewer_container_position(tab
->viewer_container
, focus_widget
);
483 /* can move up one position */
484 gtk_box_reorder_child(GTK_BOX(tab
->viewer_container
),
491 void move_up_viewer(GtkWidget
* widget
, gpointer user_data
)
493 MainWindow
* mw
= get_window_data_struct(widget
);
494 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
496 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
497 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
503 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
506 //gtk_multivpaned_widget_move_down(GTK_MULTIVPANED(tab->multivpaned));
507 /* change the position in the vbox */
508 GtkWidget
*focus_widget
;
510 focus_widget
= viewer_container_focus(tab
->viewer_container
);
511 position
= viewer_container_position(tab
->viewer_container
, focus_widget
);
515 g_list_length(gtk_container_get_children(
516 GTK_CONTAINER(tab
->viewer_container
)))-1
518 /* can move down one position */
519 gtk_box_reorder_child(GTK_BOX(tab
->viewer_container
),
527 /* delete_viewer deletes the selected viewer in the current tab
530 void delete_viewer(GtkWidget
* widget
, gpointer user_data
)
532 MainWindow
* mw
= get_window_data_struct(widget
);
533 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
535 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
536 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
542 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
545 //gtk_multivpaned_widget_delete(GTK_MULTIVPANED(tab->multivpaned));
547 GtkWidget
*focus_widget
= viewer_container_focus(tab
->viewer_container
);
549 if(focus_widget
!= NULL
)
550 gtk_widget_destroy(focus_widget
);
552 g_object_set_data(G_OBJECT(tab
->viewer_container
), "focused_viewer", NULL
);
556 /* open_traceset will open a traceset saved in a file
557 * Right now, it is not finished yet, (not working)
561 void open_traceset(GtkWidget
* widget
, gpointer user_data
)
565 LttvTraceset
* traceset
;
566 MainWindow
* mw_data
= get_window_data_struct(widget
);
567 GtkFileSelection
* file_selector
=
568 (GtkFileSelection
*)gtk_file_selection_new("Select a traceset");
570 gtk_file_selection_hide_fileop_buttons(file_selector
);
572 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
574 case GTK_RESPONSE_ACCEPT
:
575 case GTK_RESPONSE_OK
:
576 dir
= gtk_file_selection_get_selections (file_selector
);
577 traceset
= lttv_traceset_load(dir
[0]);
578 g_printf("Open a trace set %s\n", dir
[0]);
581 case GTK_RESPONSE_REJECT
:
582 case GTK_RESPONSE_CANCEL
:
584 gtk_widget_destroy((GtkWidget
*)file_selector
);
590 static void events_request_free(EventsRequest
*events_request
)
592 if(events_request
== NULL
) return;
594 if(events_request
->start_position
!= NULL
)
595 lttv_traceset_context_position_destroy(events_request
->start_position
);
596 if(events_request
->end_position
!= NULL
)
597 lttv_traceset_context_position_destroy(events_request
->end_position
);
598 if(events_request
->before_chunk_traceset
!= NULL
)
599 lttv_hooks_destroy(events_request
->before_chunk_traceset
);
600 if(events_request
->before_chunk_trace
!= NULL
)
601 lttv_hooks_destroy(events_request
->before_chunk_trace
);
602 if(events_request
->before_chunk_tracefile
!= NULL
)
603 lttv_hooks_destroy(events_request
->before_chunk_tracefile
);
604 if(events_request
->event
!= NULL
)
605 lttv_hooks_destroy(events_request
->event
);
606 if(events_request
->event_by_id
!= NULL
)
607 lttv_hooks_by_id_destroy(events_request
->event_by_id
);
608 if(events_request
->after_chunk_tracefile
!= NULL
)
609 lttv_hooks_destroy(events_request
->after_chunk_tracefile
);
610 if(events_request
->after_chunk_trace
!= NULL
)
611 lttv_hooks_destroy(events_request
->after_chunk_trace
);
612 if(events_request
->after_chunk_traceset
!= NULL
)
613 lttv_hooks_destroy(events_request
->after_chunk_traceset
);
614 if(events_request
->before_request
!= NULL
)
615 lttv_hooks_destroy(events_request
->before_request
);
616 if(events_request
->after_request
!= NULL
)
617 lttv_hooks_destroy(events_request
->after_request
);
619 g_free(events_request
);
624 /* lttvwindow_process_pending_requests
626 * This internal function gets called by g_idle, taking care of the pending
627 * requests. It is responsible for concatenation of time intervals and position
628 * requests. It does it with the following algorithm organizing process traceset
629 * calls. Here is the detailed description of the way it works :
631 * - Events Requests Servicing Algorithm
633 * Data structures necessary :
635 * List of requests added to context : list_in
636 * List of requests not added to context : list_out
641 * list_out : many events requests
643 * FIXME : insert rest of algorithm here
647 #define list_out tab->events_requests
649 gboolean
lttvwindow_process_pending_requests(Tab
*tab
)
651 unsigned max_nb_events
;
655 LttvTracesetContext
*tsc
;
656 LttvTracefileContext
*tfc
;
657 GSList
*list_in
= NULL
;
661 LttvTracesetContextPosition
*end_position
;
664 g_critical("Foreground processing : tab does not exist. Processing removed.");
668 /* There is no events requests pending : we should never have been called! */
669 g_assert(g_slist_length(list_out
) != 0);
671 tsc
= LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
673 //set the cursor to be X shape, indicating that the computer is busy in doing its job
675 new = gdk_cursor_new(GDK_X_CURSOR
);
676 widget
= lookup_widget(tab
->mw
->mwindow
, "MToolbar1");
677 win
= gtk_widget_get_parent_window(widget
);
678 gdk_window_set_cursor(win
, new);
679 gdk_cursor_unref(new);
680 gdk_window_stick(win
);
681 gdk_window_unstick(win
);
684 g_debug("SIZE events req len : %d", g_slist_length(list_out
));
686 /* Preliminary check for no trace in traceset */
687 /* Unregister the routine if empty, empty list_out too */
688 if(lttv_traceset_number(tsc
->ts
) == 0) {
690 /* - For each req in list_out */
691 GSList
*iter
= list_out
;
693 while(iter
!= NULL
) {
695 gboolean remove
= FALSE
;
696 gboolean free_data
= FALSE
;
697 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
699 /* - Call end request for req */
700 if(events_request
->servicing
== TRUE
)
701 lttv_hooks_call(events_request
->after_request
, (gpointer
)tsc
);
703 /* - remove req from list_out */
704 /* Destroy the request */
711 GSList
*remove_iter
= iter
;
713 iter
= g_slist_next(iter
);
714 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
715 list_out
= g_slist_remove_link(list_out
, remove_iter
);
716 } else { // not remove
717 iter
= g_slist_next(iter
);
722 /* 0.1 Lock Traces */
727 iter_trace
<lttv_traceset_number(tsc
->ts
);
729 LttvTrace
*trace_v
= lttv_traceset_get(tsc
->ts
, iter_trace
);
731 if(lttvwindowtraces_lock(trace_v
) != 0) {
732 g_critical("Foreground processing : Unable to get trace lock");
733 return TRUE
; /* Cannot get lock, try later */
738 /* 0.2 Seek tracefiles positions to context position */
739 lttv_process_traceset_synchronize_tracefiles(tsc
);
742 /* Events processing algorithm implementation */
743 /* A. Servicing loop */
744 while( (g_slist_length(list_in
) != 0 || g_slist_length(list_out
) != 0)) {
745 /* && !gtk_events_pending() ) */
747 /* 1. If list_in is empty (need a seek) */
748 if( g_slist_length(list_in
) == 0 ) {
750 /* list in is empty, need a seek */
752 /* 1.1 Add requests to list_in */
753 GSList
*ltime
= NULL
;
757 /* 1.1.1 Find all time requests with the lowest start time in list_out
760 if(g_slist_length(list_out
) > 0)
761 ltime
= g_slist_append(ltime
, g_slist_nth_data(list_out
, 0));
762 for(iter
=g_slist_nth(list_out
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
763 /* Find all time requests with the lowest start time in list_out */
764 guint index_ltime
= g_array_index(ltime
, guint
, 0);
765 EventsRequest
*event_request_ltime
= (EventsRequest
*)g_slist_nth_data(ltime
, 0);
766 EventsRequest
*event_request_list_out
= (EventsRequest
*)iter
->data
;
769 comp
= ltt_time_compare(event_request_ltime
->start_time
,
770 event_request_list_out
->start_time
);
772 ltime
= g_slist_append(ltime
, event_request_list_out
);
774 /* Remove all elements from ltime, and add current */
776 ltime
= g_slist_delete_link(ltime
, g_slist_nth(ltime
, 0));
777 ltime
= g_slist_append(ltime
, event_request_list_out
);
781 /* 1.1.2 Find all position requests with the lowest position in list_out
784 if(g_slist_length(list_out
) > 0)
785 lpos
= g_slist_append(lpos
, g_slist_nth_data(list_out
, 0));
786 for(iter
=g_slist_nth(list_out
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
787 /* Find all position requests with the lowest position in list_out */
788 EventsRequest
*event_request_lpos
= (EventsRequest
*)g_slist_nth_data(lpos
, 0);
789 EventsRequest
*event_request_list_out
= (EventsRequest
*)iter
->data
;
792 if(event_request_lpos
->start_position
!= NULL
793 && event_request_list_out
->start_position
!= NULL
)
795 comp
= lttv_traceset_context_pos_pos_compare
796 (event_request_lpos
->start_position
,
797 event_request_list_out
->start_position
);
802 lpos
= g_slist_append(lpos
, event_request_list_out
);
804 /* Remove all elements from lpos, and add current */
806 lpos
= g_slist_delete_link(lpos
, g_slist_nth(lpos
, 0));
807 lpos
= g_slist_append(lpos
, event_request_list_out
);
812 EventsRequest
*event_request_lpos
= (EventsRequest
*)g_slist_nth_data(lpos
, 0);
813 EventsRequest
*event_request_ltime
= (EventsRequest
*)g_slist_nth_data(ltime
, 0);
814 LttTime lpos_start_time
;
816 if(event_request_lpos
!= NULL
817 && event_request_lpos
->start_position
!= NULL
) {
818 lpos_start_time
= lttv_traceset_context_position_get_time(
819 event_request_lpos
->start_position
);
822 /* 1.1.3 If lpos.start time < ltime */
823 if(event_request_lpos
!= NULL
824 && event_request_lpos
->start_position
!= NULL
825 && ltt_time_compare(lpos_start_time
,
826 event_request_ltime
->start_time
)<0) {
827 /* Add lpos to list_in, remove them from list_out */
828 for(iter
=lpos
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
830 EventsRequest
*event_request_lpos
=
831 (EventsRequest
*)iter
->data
;
833 list_in
= g_slist_append(list_in
, event_request_lpos
);
834 /* Remove from list_out */
835 list_out
= g_slist_remove(list_out
, event_request_lpos
);
838 /* 1.1.4 (lpos.start time >= ltime) */
839 /* Add ltime to list_in, remove them from list_out */
841 for(iter
=ltime
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
843 EventsRequest
*event_request_ltime
=
844 (EventsRequest
*)iter
->data
;
846 list_in
= g_slist_append(list_in
, event_request_ltime
);
847 /* Remove from list_out */
848 list_out
= g_slist_remove(list_out
, event_request_ltime
);
858 tfc
= lttv_traceset_context_get_current_tfc(tsc
);
859 g_assert(g_slist_length(list_in
)>0);
860 EventsRequest
*events_request
= g_slist_nth_data(list_in
, 0);
863 /* 1.2.1 If first request in list_in is a time request */
864 if(events_request
->start_position
== NULL
) {
865 /* - If first req in list_in start time != current time */
866 if(tfc
== NULL
|| ltt_time_compare(events_request
->start_time
,
867 tfc
->timestamp
) != 0)
868 /* - Seek to that time */
869 g_debug("SEEK TIME : %lu, %lu", events_request
->start_time
.tv_sec
,
870 events_request
->start_time
.tv_nsec
);
871 //lttv_process_traceset_seek_time(tsc, events_request->start_time);
872 lttv_state_traceset_seek_time_closest(LTTV_TRACESET_STATE(tsc
),
873 events_request
->start_time
);
875 /* Process the traceset with only state hooks */
877 lttv_process_traceset_middle(tsc
,
878 events_request
->start_time
,
884 /* Else, the first request in list_in is a position request */
885 /* If first req in list_in pos != current pos */
886 g_assert(events_request
->start_position
!= NULL
);
887 g_debug("SEEK POS time : %lu, %lu",
888 lttv_traceset_context_position_get_time(
889 events_request
->start_position
).tv_sec
,
890 lttv_traceset_context_position_get_time(
891 events_request
->start_position
).tv_nsec
);
893 g_debug("SEEK POS context time : %lu, %lu",
894 lttv_traceset_context_get_current_tfc(tsc
)->timestamp
.tv_sec
,
895 lttv_traceset_context_get_current_tfc(tsc
)->timestamp
.tv_nsec
);
896 g_assert(events_request
->start_position
!= NULL
);
897 if(lttv_traceset_context_ctx_pos_compare(tsc
,
898 events_request
->start_position
) != 0) {
899 /* 1.2.2.1 Seek to that position */
900 g_debug("SEEK POSITION");
901 //lttv_process_traceset_seek_position(tsc, events_request->start_position);
902 pos_time
= lttv_traceset_context_position_get_time(
903 events_request
->start_position
);
905 lttv_state_traceset_seek_time_closest(LTTV_TRACESET_STATE(tsc
),
908 /* Process the traceset with only state hooks */
910 lttv_process_traceset_middle(tsc
,
913 events_request
->start_position
);
914 g_assert(lttv_traceset_context_ctx_pos_compare(tsc
,
915 events_request
->start_position
) == 0);
922 /* 1.3 Add hooks and call before request for all list_in members */
926 for(iter
=list_in
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
927 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
928 /* 1.3.1 If !servicing */
929 if(events_request
->servicing
== FALSE
) {
930 /* - begin request hooks called
933 lttv_hooks_call(events_request
->before_request
, (gpointer
)tsc
);
934 events_request
->servicing
= TRUE
;
936 /* 1.3.2 call before chunk
937 * 1.3.3 events hooks added
939 lttv_process_traceset_begin(tsc
, events_request
->before_chunk_traceset
,
940 events_request
->before_chunk_trace
,
941 events_request
->before_chunk_tracefile
,
942 events_request
->event
,
943 events_request
->event_by_id
);
947 /* 2. Else, list_in is not empty, we continue a read */
950 /* 2.0 For each req of list_in */
951 GSList
*iter
= list_in
;
953 while(iter
!= NULL
) {
955 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
957 /* - Call before chunk
958 * - events hooks added
960 lttv_process_traceset_begin(tsc
, events_request
->before_chunk_traceset
,
961 events_request
->before_chunk_trace
,
962 events_request
->before_chunk_tracefile
,
963 events_request
->event
,
964 events_request
->event_by_id
);
966 iter
= g_slist_next(iter
);
971 tfc
= lttv_traceset_context_get_current_tfc(tsc
);
973 /* 2.1 For each req of list_out */
974 GSList
*iter
= list_out
;
976 while(iter
!= NULL
) {
978 gboolean remove
= FALSE
;
979 gboolean free_data
= FALSE
;
980 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
982 /* if req.start time == current context time
983 * or req.start position == current position*/
984 if( ltt_time_compare(events_request
->start_time
,
987 (events_request
->start_position
!= NULL
989 lttv_traceset_context_ctx_pos_compare(tsc
,
990 events_request
->start_position
) == 0)
992 /* - Add to list_in, remove from list_out */
993 list_in
= g_slist_append(list_in
, events_request
);
997 /* - If !servicing */
998 if(events_request
->servicing
== FALSE
) {
999 /* - begin request hooks called
1000 * - servicing = TRUE
1002 lttv_hooks_call(events_request
->before_request
, (gpointer
)tsc
);
1003 events_request
->servicing
= TRUE
;
1005 /* call before chunk
1006 * events hooks added
1008 lttv_process_traceset_begin(tsc
, events_request
->before_chunk_traceset
,
1009 events_request
->before_chunk_trace
,
1010 events_request
->before_chunk_tracefile
,
1011 events_request
->event
,
1012 events_request
->event_by_id
);
1018 GSList
*remove_iter
= iter
;
1020 iter
= g_slist_next(iter
);
1021 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
1022 list_out
= g_slist_remove_link(list_out
, remove_iter
);
1023 } else { // not remove
1024 iter
= g_slist_next(iter
);
1030 /* 3. Find end criterions */
1035 /* 3.1.1 Find lowest end time in list_in */
1036 g_assert(g_slist_length(list_in
)>0);
1037 end_time
= ((EventsRequest
*)g_slist_nth_data(list_in
,0))->end_time
;
1039 for(iter
=g_slist_nth(list_in
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
1040 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1042 if(ltt_time_compare(events_request
->end_time
,
1044 end_time
= events_request
->end_time
;
1047 /* 3.1.2 Find lowest start time in list_out */
1048 for(iter
=list_out
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
1049 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1051 if(ltt_time_compare(events_request
->start_time
,
1053 end_time
= events_request
->start_time
;
1058 /* 3.2 Number of events */
1060 /* 3.2.1 Find lowest number of events in list_in */
1063 end_nb_events
= ((EventsRequest
*)g_slist_nth_data(list_in
,0))->num_events
;
1065 for(iter
=g_slist_nth(list_in
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
1066 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1068 if(events_request
->num_events
< end_nb_events
)
1069 end_nb_events
= events_request
->num_events
;
1072 /* 3.2.2 Use min(CHUNK_NUM_EVENTS, min num events in list_in) as
1075 end_nb_events
= MIN(CHUNK_NUM_EVENTS
, end_nb_events
);
1079 /* 3.3 End position */
1081 /* 3.3.1 Find lowest end position in list_in */
1084 end_position
=((EventsRequest
*)g_slist_nth_data(list_in
,0))->end_position
;
1086 for(iter
=g_slist_nth(list_in
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
1087 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1089 if(events_request
->end_position
!= NULL
&& end_position
!= NULL
&&
1090 lttv_traceset_context_pos_pos_compare(events_request
->end_position
,
1092 end_position
= events_request
->end_position
;
1097 /* 3.3.2 Find lowest start position in list_out */
1100 for(iter
=list_out
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
1101 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1103 if(events_request
->end_position
!= NULL
&& end_position
!= NULL
&&
1104 lttv_traceset_context_pos_pos_compare(events_request
->end_position
,
1106 end_position
= events_request
->end_position
;
1111 /* 4. Call process traceset middle */
1112 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
);
1113 count
= lttv_process_traceset_middle(tsc
, end_time
, end_nb_events
, end_position
);
1115 tfc
= lttv_traceset_context_get_current_tfc(tsc
);
1116 g_debug("Context time after middle : %lu, %lu", tfc
->timestamp
.tv_sec
,
1117 tfc
->timestamp
.tv_nsec
);
1121 /* 5. After process traceset middle */
1122 tfc
= lttv_traceset_context_get_current_tfc(tsc
);
1124 /* - if current context time > traceset.end time */
1125 if(tfc
== NULL
|| ltt_time_compare(tfc
->timestamp
,
1126 tsc
->time_span
.end_time
) > 0) {
1127 /* - For each req in list_in */
1128 GSList
*iter
= list_in
;
1130 while(iter
!= NULL
) {
1132 gboolean remove
= FALSE
;
1133 gboolean free_data
= FALSE
;
1134 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1136 /* - Remove events hooks for req
1137 * - Call end chunk for req
1139 lttv_process_traceset_end(tsc
, events_request
->after_chunk_traceset
,
1140 events_request
->after_chunk_trace
,
1141 events_request
->after_chunk_tracefile
,
1142 events_request
->event
,
1143 events_request
->event_by_id
);
1144 /* - Call end request for req */
1145 lttv_hooks_call(events_request
->after_request
, (gpointer
)tsc
);
1147 /* - remove req from list_in */
1148 /* Destroy the request */
1155 GSList
*remove_iter
= iter
;
1157 iter
= g_slist_next(iter
);
1158 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
1159 list_in
= g_slist_remove_link(list_in
, remove_iter
);
1160 } else { // not remove
1161 iter
= g_slist_next(iter
);
1166 /* 5.1 For each req in list_in */
1167 GSList
*iter
= list_in
;
1169 while(iter
!= NULL
) {
1171 gboolean remove
= FALSE
;
1172 gboolean free_data
= FALSE
;
1173 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1175 /* - Remove events hooks for req
1176 * - Call end chunk for req
1178 lttv_process_traceset_end(tsc
, events_request
->after_chunk_traceset
,
1179 events_request
->after_chunk_trace
,
1180 events_request
->after_chunk_tracefile
,
1181 events_request
->event
,
1182 events_request
->event_by_id
);
1184 /* - req.num -= count */
1185 g_assert(events_request
->num_events
>= count
);
1186 events_request
->num_events
-= count
;
1188 g_assert(tfc
!= NULL
);
1189 /* - if req.num == 0
1191 * current context time >= req.end time
1193 * req.end pos == current pos
1195 * req.stop_flag == TRUE
1197 if( events_request
->num_events
== 0
1199 events_request
->stop_flag
== TRUE
1201 ltt_time_compare(tfc
->timestamp
,
1202 events_request
->end_time
) >= 0
1204 (events_request
->end_position
!= NULL
1206 lttv_traceset_context_ctx_pos_compare(tsc
,
1207 events_request
->end_position
) == 0)
1210 g_assert(events_request
->servicing
== TRUE
);
1211 /* - Call end request for req
1212 * - remove req from list_in */
1213 lttv_hooks_call(events_request
->after_request
, (gpointer
)tsc
);
1214 /* - remove req from list_in */
1215 /* Destroy the request */
1223 GSList
*remove_iter
= iter
;
1225 iter
= g_slist_next(iter
);
1226 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
1227 list_in
= g_slist_remove_link(list_in
, remove_iter
);
1228 } else { // not remove
1229 iter
= g_slist_next(iter
);
1235 if(gtk_events_pending()) break;
1238 /* B. When interrupted between chunks */
1241 GSList
*iter
= list_in
;
1243 /* 1. for each request in list_in */
1244 while(iter
!= NULL
) {
1246 gboolean remove
= FALSE
;
1247 gboolean free_data
= FALSE
;
1248 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1250 /* 1.1. Use current postition as start position */
1251 if(events_request
->start_position
!= NULL
)
1252 lttv_traceset_context_position_destroy(events_request
->start_position
);
1253 events_request
->start_position
= lttv_traceset_context_position_new();
1254 lttv_traceset_context_position_save(tsc
, events_request
->start_position
);
1256 /* 1.2. Remove start time */
1257 events_request
->start_time
.tv_sec
= G_MAXUINT
;
1258 events_request
->start_time
.tv_nsec
= G_MAXUINT
;
1260 /* 1.3. Move from list_in to list_out */
1263 list_out
= g_slist_append(list_out
, events_request
);
1268 GSList
*remove_iter
= iter
;
1270 iter
= g_slist_next(iter
);
1271 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
1272 list_in
= g_slist_remove_link(list_in
, remove_iter
);
1273 } else { // not remove
1274 iter
= g_slist_next(iter
);
1281 /* C Unlock Traces */
1283 //lttv_process_traceset_get_sync_data(tsc);
1288 iter_trace
<lttv_traceset_number(tsc
->ts
);
1290 LttvTrace
*trace_v
= lttv_traceset_get(tsc
->ts
, iter_trace
);
1292 lttvwindowtraces_unlock(trace_v
);
1297 //set the cursor back to normal
1298 gdk_window_set_cursor(win
, NULL
);
1301 g_assert(g_slist_length(list_in
) == 0);
1303 if( g_slist_length(list_out
) == 0 ) {
1304 /* Put tab's request pending flag back to normal */
1305 tab
->events_request_pending
= FALSE
;
1306 g_debug("remove the idle fct");
1307 return FALSE
; /* Remove the idle function */
1309 g_debug("leave the idle fct");
1310 return TRUE
; /* Leave the idle function */
1312 /* We do not use simili-round-robin, it may require to read 1 meg buffers
1313 * again and again if many tracesets use the same tracefiles. */
1314 /* Hack for round-robin idle functions */
1315 /* It will put the idle function at the end of the pool */
1316 /*g_idle_add_full((G_PRIORITY_HIGH_IDLE + 21),
1317 (GSourceFunc)execute_events_requests,
1327 /* add_trace_into_traceset_selector, each instance of a viewer has an associated
1328 * selector (filter), when a trace is added into traceset, the selector should
1329 * reflect the change. The function is used to update the selector
1332 void add_trace_into_traceset_selector(GtkWidget
* paned
, LttTrace
* t
)
1334 int j
, k
, m
, nb_tracefile
, nb_control
, nb_per_cpu
, nb_facility
, nb_event
;
1335 LttvTracesetSelector
* s
;
1336 LttvTraceSelector
* trace
;
1337 LttvTracefileSelector
* tracefile
;
1338 LttvEventtypeSelector
* eventtype
;
1344 w
= gtk_multivpaned_get_first_widget(GTK_MULTIVPANED(paned
));
1346 s
= g_object_get_data(G_OBJECT(w
), "Traceset_Selector");
1349 trace
= lttv_trace_selector_new(t
);
1350 lttv_traceset_selector_trace_add(s
, trace
);
1352 nb_facility
= ltt_trace_facility_number(t
);
1353 for(k
=0;k
<nb_facility
;k
++){
1354 fac
= ltt_trace_facility_get(t
,k
);
1355 nb_event
= (int) ltt_facility_eventtype_number(fac
);
1356 for(m
=0;m
<nb_event
;m
++){
1357 et
= ltt_facility_eventtype_get(fac
,m
);
1358 eventtype
= lttv_eventtype_selector_new(et
);
1359 lttv_trace_selector_eventtype_add(trace
, eventtype
);
1363 nb_control
= ltt_trace_control_tracefile_number(t
);
1364 nb_per_cpu
= ltt_trace_per_cpu_tracefile_number(t
);
1365 nb_tracefile
= nb_control
+ nb_per_cpu
;
1367 for(j
= 0 ; j
< nb_tracefile
; j
++) {
1369 tf
= ltt_trace_control_tracefile_get(t
, j
);
1371 tf
= ltt_trace_per_cpu_tracefile_get(t
, j
- nb_control
);
1372 tracefile
= lttv_tracefile_selector_new(tf
);
1373 lttv_trace_selector_tracefile_add(trace
, tracefile
);
1374 lttv_eventtype_selector_copy(trace
, tracefile
);
1376 }else g_warning("Module does not support filtering\n");
1378 w
= gtk_multivpaned_get_next_widget(GTK_MULTIVPANED(paned
));
1383 static void lttvwindow_add_trace(Tab
*tab
, LttvTrace
*trace_v
)
1385 LttvTraceset
*traceset
= tab
->traceset_info
->traceset
;
1388 //Verify if trace is already present.
1389 for(i
=0; i
<lttv_traceset_number(traceset
); i
++)
1391 LttvTrace
* trace
= lttv_traceset_get(traceset
, i
);
1392 if(trace
== trace_v
)
1396 //Keep a reference to the traces so they are not freed.
1397 for(i
=0; i
<lttv_traceset_number(traceset
); i
++)
1399 LttvTrace
* trace
= lttv_traceset_get(traceset
, i
);
1400 lttv_trace_ref(trace
);
1403 //remove state update hooks
1404 lttv_state_remove_event_hooks(
1405 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1407 lttv_context_fini(LTTV_TRACESET_CONTEXT(
1408 tab
->traceset_info
->traceset_context
));
1409 g_object_unref(tab
->traceset_info
->traceset_context
);
1411 lttv_traceset_add(traceset
, trace_v
);
1412 lttv_trace_ref(trace_v
); /* local ref */
1414 /* Create new context */
1415 tab
->traceset_info
->traceset_context
=
1416 g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
1418 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->
1422 /* Set the tab's time window and current time if
1424 TimeInterval time_span
=
1425 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->time_span
;
1426 if(ltt_time_compare(tab
->time_window
.start_time
, time_span
.start_time
) < 0
1427 || ltt_time_compare( ltt_time_add(tab
->time_window
.start_time
,
1428 tab
->time_window
.time_width
),
1429 time_span
.end_time
) > 0) {
1430 tab
->time_window
.start_time
=
1431 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
1432 time_span
.start_time
;
1434 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
1435 time_span
.start_time
;
1439 if(DEFAULT_TIME_WIDTH_S
<
1440 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
1441 time_span
.end_time
.tv_sec
)
1442 tmp_time
.tv_sec
= DEFAULT_TIME_WIDTH_S
;
1445 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
1446 time_span
.end_time
.tv_sec
;
1447 tmp_time
.tv_nsec
= 0;
1448 tab
->time_window
.time_width
= tmp_time
;
1452 //add state update hooks
1453 lttv_state_add_event_hooks(
1454 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1455 //Remove local reference to the traces.
1456 for(i
=0; i
<lttv_traceset_number(traceset
); i
++)
1458 LttvTrace
* trace
= lttv_traceset_get(traceset
, i
);
1459 lttv_trace_unref(trace
);
1463 //add_trace_into_traceset_selector(GTK_MULTIVPANED(tab->multivpaned), lttv_trace(trace_v));
1466 /* add_trace adds a trace into the current traceset. It first displays a
1467 * directory selection dialogue to let user choose a trace, then recreates
1468 * tracset_context, and redraws all the viewer of the current tab
1471 void add_trace(GtkWidget
* widget
, gpointer user_data
)
1474 LttvTrace
* trace_v
;
1475 LttvTraceset
* traceset
;
1477 char abs_path
[PATH_MAX
];
1480 MainWindow
* mw_data
= get_window_data_struct(widget
);
1481 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
1483 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
1484 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
1488 tab
= create_new_tab(widget
, NULL
);
1490 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
1493 GtkDirSelection
* file_selector
= (GtkDirSelection
*)gtk_dir_selection_new("Select a trace");
1494 gtk_dir_selection_hide_fileop_buttons(file_selector
);
1496 if(remember_trace_dir
[0] != '\0')
1497 gtk_dir_selection_set_filename(file_selector
, remember_trace_dir
);
1499 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
1501 case GTK_RESPONSE_ACCEPT
:
1502 case GTK_RESPONSE_OK
:
1503 dir
= gtk_dir_selection_get_dir (file_selector
);
1504 strncpy(remember_trace_dir
, dir
, PATH_MAX
);
1505 if(!dir
|| strlen(dir
) == 0){
1506 gtk_widget_destroy((GtkWidget
*)file_selector
);
1509 get_absolute_pathname(dir
, abs_path
);
1510 trace_v
= lttvwindowtraces_get_trace_by_name(abs_path
);
1511 if(trace_v
== NULL
) {
1512 trace
= ltt_trace_open(abs_path
);
1514 g_warning("cannot open trace %s", abs_path
);
1516 trace_v
= lttv_trace_new(trace
);
1517 lttvwindowtraces_add_trace(trace_v
);
1518 lttvwindow_add_trace(tab
, trace_v
);
1521 lttvwindow_add_trace(tab
, trace_v
);
1524 gtk_widget_destroy((GtkWidget
*)file_selector
);
1526 //update current tab
1527 //update_traceset(mw_data);
1529 /* Call the updatetraceset hooks */
1531 traceset
= tab
->traceset_info
->traceset
;
1532 SetTraceset(tab
, traceset
);
1533 // in expose now call_pending_read_hooks(mw_data);
1535 //lttvwindow_report_current_time(mw_data,&(tab->current_time));
1537 case GTK_RESPONSE_REJECT
:
1538 case GTK_RESPONSE_CANCEL
:
1540 gtk_widget_destroy((GtkWidget
*)file_selector
);
1546 /* remove_trace_into_traceset_selector, each instance of a viewer has an associated
1547 * selector (filter), when a trace is remove from traceset, the selector should
1548 * reflect the change. The function is used to update the selector
1551 void remove_trace_from_traceset_selector(GtkWidget
* paned
, unsigned i
)
1553 LttvTracesetSelector
* s
;
1554 LttvTraceSelector
* t
;
1557 w
= gtk_multivpaned_get_first_widget(GTK_MULTIVPANED(paned
));
1559 s
= g_object_get_data(G_OBJECT(w
), "Traceset_Selector");
1561 t
= lttv_traceset_selector_trace_get(s
,i
);
1562 lttv_traceset_selector_trace_remove(s
, i
);
1563 lttv_trace_selector_destroy(t
);
1564 }g_warning("Module dose not support filtering\n");
1565 w
= gtk_multivpaned_get_next_widget(GTK_MULTIVPANED(paned
));
1570 /* remove_trace removes a trace from the current traceset if all viewers in
1571 * the current tab are not interested in the trace. It first displays a
1572 * dialogue, which shows all traces in the current traceset, to let user choose
1573 * a trace, then it checks if all viewers unselect the trace, if it is true,
1574 * it will remove the trace, recreate the traceset_contex,
1575 * and redraws all the viewer of the current tab. If there is on trace in the
1576 * current traceset, it will delete all viewers of the current tab
1579 // MD : no filter version.
1580 void remove_trace(GtkWidget
*widget
, gpointer user_data
)
1583 LttvTrace
* trace_v
;
1584 LttvTraceset
* traceset
;
1585 gint i
, j
, nb_trace
, index
=-1;
1586 char ** name
, *remove_trace_name
;
1587 MainWindow
* mw_data
= get_window_data_struct(widget
);
1588 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
1590 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
1591 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
1597 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
1600 nb_trace
=lttv_traceset_number(tab
->traceset_info
->traceset
);
1601 name
= g_new(char*,nb_trace
);
1602 for(i
= 0; i
< nb_trace
; i
++){
1603 trace_v
= lttv_traceset_get(tab
->traceset_info
->traceset
, i
);
1604 trace
= lttv_trace(trace_v
);
1605 name
[i
] = ltt_trace_name(trace
);
1608 remove_trace_name
= get_remove_trace(name
, nb_trace
);
1611 if(remove_trace_name
){
1613 /* yuk, cut n paste from old code.. should be better (MD)*/
1614 for(i
= 0; i
<nb_trace
; i
++) {
1615 if(strcmp(remove_trace_name
,name
[i
]) == 0){
1620 traceset
= tab
->traceset_info
->traceset
;
1621 //Keep a reference to the traces so they are not freed.
1622 for(j
=0; j
<lttv_traceset_number(traceset
); j
++)
1624 LttvTrace
* trace
= lttv_traceset_get(traceset
, j
);
1625 lttv_trace_ref(trace
);
1628 //remove state update hooks
1629 lttv_state_remove_event_hooks(
1630 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1631 lttv_context_fini(LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
));
1632 g_object_unref(tab
->traceset_info
->traceset_context
);
1634 trace_v
= lttv_traceset_get(traceset
, index
);
1636 if(lttv_trace_get_ref_number(trace_v
) <= 2) {
1637 /* ref 2 : traceset, local */
1638 lttvwindowtraces_remove_trace(trace_v
);
1639 ltt_trace_close(lttv_trace(trace_v
));
1642 lttv_traceset_remove(traceset
, index
);
1643 lttv_trace_unref(trace_v
); // Remove local reference
1645 if(!lttv_trace_get_ref_number(trace_v
))
1646 lttv_trace_destroy(trace_v
);
1648 tab
->traceset_info
->traceset_context
=
1649 g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
1651 LTTV_TRACESET_CONTEXT(tab
->
1652 traceset_info
->traceset_context
),traceset
);
1653 //add state update hooks
1654 lttv_state_add_event_hooks(
1655 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1657 //Remove local reference to the traces.
1658 for(j
=0; j
<lttv_traceset_number(traceset
); j
++)
1660 LttvTrace
* trace
= lttv_traceset_get(traceset
, j
);
1661 lttv_trace_unref(trace
);
1664 SetTraceset(tab
, (gpointer
)traceset
);
1670 void remove_trace(GtkWidget
* widget
, gpointer user_data
)
1673 LttvTrace
* trace_v
;
1674 LttvTraceset
* traceset
;
1675 gint i
, j
, nb_trace
;
1676 char ** name
, *remove_trace_name
;
1677 MainWindow
* mw_data
= get_window_data_struct(widget
);
1678 LttvTracesetSelector
* s
;
1679 LttvTraceSelector
* t
;
1682 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
1684 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
1685 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
1691 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
1694 nb_trace
=lttv_traceset_number(tab
->traceset_info
->traceset
);
1695 name
= g_new(char*,nb_trace
);
1696 for(i
= 0; i
< nb_trace
; i
++){
1697 trace_v
= lttv_traceset_get(tab
->traceset_info
->traceset
, i
);
1698 trace
= lttv_trace(trace_v
);
1699 name
[i
] = ltt_trace_name(trace
);
1702 remove_trace_name
= get_remove_trace(name
, nb_trace
);
1704 if(remove_trace_name
){
1705 for(i
=0; i
<nb_trace
; i
++){
1706 if(strcmp(remove_trace_name
,name
[i
]) == 0){
1707 //unselect the trace from the current viewer
1709 w
= gtk_multivpaned_get_widget(GTK_MULTIVPANED(tab
->multivpaned
));
1711 s
= g_object_get_data(G_OBJECT(w
), "Traceset_Selector");
1713 t
= lttv_traceset_selector_trace_get(s
,i
);
1714 lttv_trace_selector_set_selected(t
, FALSE
);
1717 //check if other viewers select the trace
1718 w
= gtk_multivpaned_get_first_widget(GTK_MULTIVPANED(tab
->multivpaned
));
1720 s
= g_object_get_data(G_OBJECT(w
), "Traceset_Selector");
1722 t
= lttv_traceset_selector_trace_get(s
,i
);
1723 selected
= lttv_trace_selector_get_selected(t
);
1726 w
= gtk_multivpaned_get_next_widget(GTK_MULTIVPANED(tab
->multivpaned
));
1728 }else selected
= FALSE
;
1730 //if no viewer selects the trace, remove it
1732 remove_trace_from_traceset_selector(GTK_MULTIVPANED(tab
->multivpaned
), i
);
1734 traceset
= tab
->traceset_info
->traceset
;
1735 //Keep a reference to the traces so they are not freed.
1736 for(j
=0; j
<lttv_traceset_number(traceset
); j
++)
1738 LttvTrace
* trace
= lttv_traceset_get(traceset
, j
);
1739 lttv_trace_ref(trace
);
1742 //remove state update hooks
1743 lttv_state_remove_event_hooks(
1744 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1745 lttv_context_fini(LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
));
1746 g_object_unref(tab
->traceset_info
->traceset_context
);
1749 trace_v
= lttv_traceset_get(traceset
, i
);
1751 if(lttv_trace_get_ref_number(trace_v
) <= 2) {
1752 /* ref 2 : traceset, local */
1753 lttvwindowtraces_remove_trace(trace_v
);
1754 ltt_trace_close(lttv_trace(trace_v
));
1757 lttv_traceset_remove(traceset
, i
);
1758 lttv_trace_unref(trace_v
); // Remove local reference
1760 if(!lttv_trace_get_ref_number(trace_v
))
1761 lttv_trace_destroy(trace_v
);
1763 tab
->traceset_info
->traceset_context
=
1764 g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
1766 LTTV_TRACESET_CONTEXT(tab
->
1767 traceset_info
->traceset_context
),traceset
);
1768 //add state update hooks
1769 lttv_state_add_event_hooks(
1770 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1772 //Remove local reference to the traces.
1773 for(j
=0; j
<lttv_traceset_number(traceset
); j
++)
1775 LttvTrace
* trace
= lttv_traceset_get(traceset
, j
);
1776 lttv_trace_unref(trace
);
1780 //update current tab
1781 //update_traceset(mw_data);
1784 SetTraceset(tab
, (gpointer
)traceset
);
1785 // in expose now call_pending_read_hooks(mw_data);
1787 //lttvwindow_report_current_time(mw_data,&(tab->current_time));
1790 // while(tab->multi_vpaned->num_children){
1791 // gtk_multi_vpaned_widget_delete(tab->multi_vpaned);
1805 /* Redraw all the viewers in the current tab */
1806 void redraw(GtkWidget
*widget
, gpointer user_data
)
1808 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
1809 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
1810 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
1815 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
1819 LttvAttributeValue value
;
1821 g_assert(lttv_iattribute_find_by_path(tab
->attributes
, "hooks/redraw", LTTV_POINTER
, &value
));
1823 tmp
= (LttvHooks
*)*(value
.v_pointer
);
1825 lttv_hooks_call(tmp
,NULL
);
1829 void continue_processing(GtkWidget
*widget
, gpointer user_data
)
1831 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
1832 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
1833 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
1838 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
1842 LttvAttributeValue value
;
1844 g_assert(lttv_iattribute_find_by_path(tab
->attributes
,
1845 "hooks/continue", LTTV_POINTER
, &value
));
1847 tmp
= (LttvHooks
*)*(value
.v_pointer
);
1849 lttv_hooks_call(tmp
,NULL
);
1852 /* Stop the processing for the calling main window's current tab.
1853 * It removes every processing requests that are in its list. It does not call
1854 * the end request hooks, because the request is not finished.
1857 void stop_processing(GtkWidget
*widget
, gpointer user_data
)
1859 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
1860 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
1861 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
1866 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
1868 GSList
*iter
= tab
->events_requests
;
1870 while(iter
!= NULL
) {
1871 GSList
*remove_iter
= iter
;
1872 iter
= g_slist_next(iter
);
1874 g_free(remove_iter
->data
);
1875 tab
->events_requests
=
1876 g_slist_remove_link(tab
->events_requests
, remove_iter
);
1878 tab
->events_request_pending
= FALSE
;
1879 g_idle_remove_by_data(tab
);
1880 g_assert(g_slist_length(tab
->events_requests
) == 0);
1884 /* save will save the traceset to a file
1885 * Not implemented yet FIXME
1888 void save(GtkWidget
* widget
, gpointer user_data
)
1893 void save_as(GtkWidget
* widget
, gpointer user_data
)
1895 g_printf("Save as\n");
1899 /* zoom will change the time_window of all the viewers of the
1900 * current tab, and redisplay them. The main functionality is to
1901 * determine the new time_window of the current tab
1904 void zoom(GtkWidget
* widget
, double size
)
1906 TimeInterval time_span
;
1907 TimeWindow new_time_window
;
1908 LttTime current_time
, time_delta
, time_s
, time_e
, time_tmp
;
1909 MainWindow
* mw_data
= get_window_data_struct(widget
);
1910 LttvTracesetContext
*tsc
;
1911 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
1913 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
1914 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
1920 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
1923 if(size
== 1) return;
1925 tsc
= LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
1926 time_span
= tsc
->time_span
;
1927 new_time_window
= tab
->time_window
;
1928 current_time
= tab
->current_time
;
1930 time_delta
= ltt_time_sub(time_span
.end_time
,time_span
.start_time
);
1932 new_time_window
.start_time
= time_span
.start_time
;
1933 new_time_window
.time_width
= time_delta
;
1935 new_time_window
.time_width
= ltt_time_div(new_time_window
.time_width
, size
);
1936 if(ltt_time_compare(new_time_window
.time_width
,time_delta
) > 0)
1937 { /* Case where zoom out is bigger than trace length */
1938 new_time_window
.start_time
= time_span
.start_time
;
1939 new_time_window
.time_width
= time_delta
;
1943 /* Center the image on the current time */
1944 new_time_window
.start_time
=
1945 ltt_time_sub(current_time
, ltt_time_div(new_time_window
.time_width
, 2.0));
1946 /* If on borders, don't fall off */
1947 if(ltt_time_compare(new_time_window
.start_time
, time_span
.start_time
) <0)
1949 new_time_window
.start_time
= time_span
.start_time
;
1953 if(ltt_time_compare(
1954 ltt_time_add(new_time_window
.start_time
, new_time_window
.time_width
),
1955 time_span
.end_time
) > 0)
1957 new_time_window
.start_time
=
1958 ltt_time_sub(time_span
.end_time
, new_time_window
.time_width
);
1964 //time_tmp = ltt_time_div(new_time_window.time_width, 2);
1965 //if(ltt_time_compare(current_time, time_tmp) < 0){
1966 // time_s = time_span->startTime;
1968 // time_s = ltt_time_sub(current_time,time_tmp);
1970 //time_e = ltt_time_add(current_time,time_tmp);
1971 //if(ltt_time_compare(time_span->startTime, time_s) > 0){
1972 // time_s = time_span->startTime;
1973 //}else if(ltt_time_compare(time_span->endTime, time_e) < 0){
1974 // time_e = time_span->endTime;
1975 // time_s = ltt_time_sub(time_e,new_time_window.time_width);
1977 //new_time_window.start_time = time_s;
1980 //lttvwindow_report_time_window(mw_data, &new_time_window);
1981 //call_pending_read_hooks(mw_data);
1983 //lttvwindow_report_current_time(mw_data,&(tab->current_time));
1984 //set_time_window(tab, &new_time_window);
1985 // in expose now call_pending_read_hooks(mw_data);
1986 //gtk_multi_vpaned_set_adjust(tab->multi_vpaned, &new_time_window, FALSE);
1990 if( ltt_time_to_double(new_time_window
.time_width
)
1991 * NANOSECONDS_PER_SECOND
1992 / SCROLL_STEP_PER_PAGE
/* step increment */
1994 ltt_time_to_double(new_time_window
.start_time
)
1995 * NANOSECONDS_PER_SECOND
/* page size */
1997 ltt_time_to_double(new_time_window
.start_time
)
1998 * NANOSECONDS_PER_SECOND
/* page size */
2000 g_warning("Can not zoom that far due to scrollbar precision");
2003 ltt_time_from_double(
2004 ltt_time_to_double(new_time_window
.time_width
)
2005 /SCROLL_STEP_PER_PAGE
),
2008 g_warning("Can not zoom that far due to time nanosecond precision");
2011 GtkAdjustment
*adjustment
= gtk_range_get_adjustment(GTK_RANGE(tab
->scrollbar
));
2013 g_object_set(G_OBJECT(adjustment
),
2015 //ltt_time_to_double(new_time_window.start_time)
2016 // * NANOSECONDS_PER_SECOND, /* value */
2018 ltt_time_to_double(time_span
.start_time
)
2019 * NANOSECONDS_PER_SECOND
, /* lower */
2021 ltt_time_to_double(time_span
.end_time
)
2022 * NANOSECONDS_PER_SECOND
, /* upper */
2024 ltt_time_to_double(new_time_window
.time_width
)
2025 / SCROLL_STEP_PER_PAGE
2026 * NANOSECONDS_PER_SECOND
, /* step increment */
2028 ltt_time_to_double(new_time_window
.time_width
)
2029 * NANOSECONDS_PER_SECOND
, /* page increment */
2031 ltt_time_to_double(new_time_window
.time_width
)
2032 * NANOSECONDS_PER_SECOND
, /* page size */
2034 gtk_adjustment_changed(adjustment
);
2035 //gtk_range_set_adjustment(GTK_RANGE(tab->scrollbar), adjustment);
2036 //gtk_adjustment_value_changed(adjustment);
2037 g_object_set(G_OBJECT(adjustment
),
2039 ltt_time_to_double(new_time_window
.start_time
)
2040 * NANOSECONDS_PER_SECOND
, /* value */
2042 gtk_adjustment_value_changed(adjustment
);
2045 //g_object_set(G_OBJECT(adjustment),
2047 // ltt_time_to_double(time_window->start_time)
2048 // * NANOSECONDS_PER_SECOND, /* value */
2050 /* Note : the set value will call set_time_window if scrollbar value changed
2052 //gtk_adjustment_set_value(adjustment,
2053 // ltt_time_to_double(new_time_window.start_time)
2054 // * NANOSECONDS_PER_SECOND);
2058 void zoom_in(GtkWidget
* widget
, gpointer user_data
)
2063 void zoom_out(GtkWidget
* widget
, gpointer user_data
)
2068 void zoom_extended(GtkWidget
* widget
, gpointer user_data
)
2073 void go_to_time(GtkWidget
* widget
, gpointer user_data
)
2075 g_printf("Go to time\n");
2078 void show_time_frame(GtkWidget
* widget
, gpointer user_data
)
2080 g_printf("Show time frame\n");
2084 /* callback function */
2087 on_empty_traceset_activate (GtkMenuItem
*menuitem
,
2090 create_new_window((GtkWidget
*)menuitem
, user_data
, FALSE
);
2095 on_clone_traceset_activate (GtkMenuItem
*menuitem
,
2098 create_new_window((GtkWidget
*)menuitem
, user_data
, TRUE
);
2102 /* create_new_tab calls create_tab to construct a new tab in the main window
2105 Tab
*create_new_tab(GtkWidget
* widget
, gpointer user_data
){
2106 gchar label
[PATH_MAX
];
2107 MainWindow
* mw_data
= get_window_data_struct(widget
);
2109 GtkNotebook
* notebook
= (GtkNotebook
*)lookup_widget(widget
, "MNotebook");
2110 if(notebook
== NULL
){
2111 g_printf("Notebook does not exist\n");
2114 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2115 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2121 copy_tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
2124 strcpy(label
,"Page");
2125 if(get_label(mw_data
, label
,"Get the name of the tab","Please input tab's name"))
2126 return (create_tab (mw_data
, copy_tab
, notebook
, label
));
2130 on_tab_activate (GtkMenuItem
*menuitem
,
2133 create_new_tab((GtkWidget
*)menuitem
, user_data
);
2138 on_open_activate (GtkMenuItem
*menuitem
,
2141 open_traceset((GtkWidget
*)menuitem
, user_data
);
2146 on_close_activate (GtkMenuItem
*menuitem
,
2149 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2150 main_window_destructor(mw_data
);
2154 /* remove the current tab from the main window
2158 on_close_tab_activate (GtkWidget
*widget
,
2162 GtkWidget
* notebook
;
2164 MainWindow
* mw_data
= get_window_data_struct(widget
);
2165 notebook
= lookup_widget(widget
, "MNotebook");
2166 if(notebook
== NULL
){
2167 g_printf("Notebook does not exist\n");
2171 page_num
= gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
));
2173 gtk_notebook_remove_page(GTK_NOTEBOOK(notebook
), page_num
);
2178 on_close_tab_X_clicked (GtkWidget
*widget
,
2182 GtkWidget
*notebook
= lookup_widget(widget
, "MNotebook");
2183 if(notebook
== NULL
){
2184 g_printf("Notebook does not exist\n");
2188 if((page_num
= gtk_notebook_page_num(GTK_NOTEBOOK(notebook
), widget
)) != -1)
2189 gtk_notebook_remove_page(GTK_NOTEBOOK(notebook
), page_num
);
2195 on_add_trace_activate (GtkMenuItem
*menuitem
,
2198 add_trace((GtkWidget
*)menuitem
, user_data
);
2203 on_remove_trace_activate (GtkMenuItem
*menuitem
,
2206 remove_trace((GtkWidget
*)menuitem
, user_data
);
2211 on_save_activate (GtkMenuItem
*menuitem
,
2214 save((GtkWidget
*)menuitem
, user_data
);
2219 on_save_as_activate (GtkMenuItem
*menuitem
,
2222 save_as((GtkWidget
*)menuitem
, user_data
);
2227 on_quit_activate (GtkMenuItem
*menuitem
,
2235 on_cut_activate (GtkMenuItem
*menuitem
,
2243 on_copy_activate (GtkMenuItem
*menuitem
,
2246 g_printf("Copye\n");
2251 on_paste_activate (GtkMenuItem
*menuitem
,
2254 g_printf("Paste\n");
2259 on_delete_activate (GtkMenuItem
*menuitem
,
2262 g_printf("Delete\n");
2267 on_zoom_in_activate (GtkMenuItem
*menuitem
,
2270 zoom_in((GtkWidget
*)menuitem
, user_data
);
2275 on_zoom_out_activate (GtkMenuItem
*menuitem
,
2278 zoom_out((GtkWidget
*)menuitem
, user_data
);
2283 on_zoom_extended_activate (GtkMenuItem
*menuitem
,
2286 zoom_extended((GtkWidget
*)menuitem
, user_data
);
2291 on_go_to_time_activate (GtkMenuItem
*menuitem
,
2294 go_to_time((GtkWidget
*)menuitem
, user_data
);
2299 on_show_time_frame_activate (GtkMenuItem
*menuitem
,
2302 show_time_frame((GtkWidget
*)menuitem
, user_data
);
2307 on_move_viewer_up_activate (GtkMenuItem
*menuitem
,
2310 move_up_viewer((GtkWidget
*)menuitem
, user_data
);
2315 on_move_viewer_down_activate (GtkMenuItem
*menuitem
,
2318 move_down_viewer((GtkWidget
*)menuitem
, user_data
);
2323 on_remove_viewer_activate (GtkMenuItem
*menuitem
,
2326 delete_viewer((GtkWidget
*)menuitem
, user_data
);
2331 on_trace_filter_activate (GtkMenuItem
*menuitem
,
2334 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2335 LttvTracesetSelector
* s
;
2337 GtkWidget
* notebook
= lookup_widget(GTK_WIDGET(menuitem
), "MNotebook");
2339 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2340 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2346 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
2349 w
= gtk_multivpaned_get_widget(GTK_MULTIVPANED(tab
->multivpaned
));
2351 s
= g_object_get_data(G_OBJECT(w
), "Traceset_Selector");
2353 g_printf("There is no viewer yet\n");
2356 if(get_filter_selection(s
, "Configure trace and tracefile filter", "Select traces and tracefiles")){
2357 //FIXME report filter change
2358 //update_traceset(mw_data);
2359 //call_pending_read_hooks(mw_data);
2360 //lttvwindow_report_current_time(mw_data,&(tab->current_time));
2366 on_trace_facility_activate (GtkMenuItem
*menuitem
,
2369 g_printf("Trace facility selector: %s\n");
2373 /* Dispaly a file selection dialogue to let user select a library, then call
2374 * lttv_library_load().
2378 on_load_library_activate (GtkMenuItem
*menuitem
,
2381 GError
*error
= NULL
;
2382 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2384 gchar load_module_path_alter
[PATH_MAX
];
2388 gchar
*load_module_path
;
2389 name
= g_ptr_array_new();
2390 nb
= lttv_library_path_number();
2391 /* ask for the library path */
2395 path
= lttv_library_path_get(i
);
2396 g_ptr_array_add(name
, path
);
2399 load_module_path
= get_selection((char **)(name
->pdata
), name
->len
,
2400 "Select a library path", "Library paths");
2401 if(load_module_path
!= NULL
)
2402 strncpy(load_module_path_alter
, load_module_path
, PATH_MAX
-1); // -1 for /
2404 g_ptr_array_free(name
, TRUE
);
2406 if(load_module_path
== NULL
) return;
2410 /* Make sure the module path ends with a / */
2411 gchar
*ptr
= load_module_path_alter
;
2413 ptr
= strchr(ptr
, '\0');
2415 if(*(ptr
-1) != '/') {
2422 /* Ask for the library to load : list files in the previously selected
2424 gchar str
[PATH_MAX
];
2427 GtkFileSelection
* file_selector
=
2428 (GtkFileSelection
*)gtk_file_selection_new("Select a module");
2429 gtk_file_selection_set_filename(file_selector
, load_module_path_alter
);
2430 gtk_file_selection_hide_fileop_buttons(file_selector
);
2433 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
2435 case GTK_RESPONSE_ACCEPT
:
2436 case GTK_RESPONSE_OK
:
2437 dir
= gtk_file_selection_get_selections (file_selector
);
2438 strncpy(str
,dir
[0],PATH_MAX
);
2439 strncpy(remember_plugins_dir
,dir
[0],PATH_MAX
);
2440 /* only keep file name */
2442 str1
= strrchr(str
,'/');
2445 str1
= strrchr(str
,'\\');
2450 if(*str1
== 'l' && *(str1
+1)== 'i' && *(str1
+2)=='b')
2452 remove info after
. */
2456 str2
= strrchr(str2
, '.');
2457 if(str2
!= NULL
) *str2
= '\0';
2459 lttv_module_require(str1
, &error
);
2461 lttv_library_load(str1
, &error
);
2462 if(error
!= NULL
) g_warning(error
->message
);
2463 else g_printf("Load library: %s\n", str
);
2465 case GTK_RESPONSE_REJECT
:
2466 case GTK_RESPONSE_CANCEL
:
2468 gtk_widget_destroy((GtkWidget
*)file_selector
);
2479 /* Display all loaded modules, let user to select a module to unload
2480 * by calling lttv_module_unload
2484 on_unload_library_activate (GtkMenuItem
*menuitem
,
2487 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2489 LttvLibrary
*library
;
2494 name
= g_ptr_array_new();
2495 nb
= lttv_library_number();
2496 LttvLibraryInfo
*lib_info
= g_new(LttvLibraryInfo
,nb
);
2497 /* ask for the library name */
2500 LttvLibrary
*iter_lib
= lttv_library_get(i
);
2501 lttv_library_info(iter_lib
, &lib_info
[i
]);
2503 gchar
*path
= lib_info
[i
].name
;
2504 g_ptr_array_add(name
, lib_info
[i
].name
);
2506 lib_name
= get_selection((char **)(name
->pdata
), name
->len
,
2507 "Select a library", "Libraries");
2508 if(lib_name
!= NULL
) {
2510 if(strcmp(lib_name
, lib_info
[i
].name
) == 0) {
2511 library
= lttv_library_get(i
);
2516 g_ptr_array_free(name
, TRUE
);
2519 if(lib_name
== NULL
) return;
2522 lttv_library_unload(library
);
2526 /* Dispaly a file selection dialogue to let user select a module, then call
2527 * lttv_module_require().
2531 on_load_module_activate (GtkMenuItem
*menuitem
,
2534 GError
*error
= NULL
;
2535 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2537 LttvLibrary
*library
;
2542 name
= g_ptr_array_new();
2543 nb
= lttv_library_number();
2544 LttvLibraryInfo
*lib_info
= g_new(LttvLibraryInfo
,nb
);
2545 /* ask for the library name */
2548 LttvLibrary
*iter_lib
= lttv_library_get(i
);
2549 lttv_library_info(iter_lib
, &lib_info
[i
]);
2551 gchar
*path
= lib_info
[i
].name
;
2552 g_ptr_array_add(name
, path
);
2554 lib_name
= get_selection((char **)(name
->pdata
), name
->len
,
2555 "Select a library", "Libraries");
2556 if(lib_name
!= NULL
) {
2558 if(strcmp(lib_name
, lib_info
[i
].name
) == 0) {
2559 library
= lttv_library_get(i
);
2564 g_ptr_array_free(name
, TRUE
);
2567 if(lib_name
== NULL
) return;
2570 //LttvModule *module;
2571 gchar module_name_out
[PATH_MAX
];
2573 /* Ask for the module to load : list modules in the selected lib */
2577 LttvModuleInfo
*module_info
= g_new(LttvModuleInfo
,nb
);
2578 name
= g_ptr_array_new();
2579 nb
= lttv_library_module_number(library
);
2580 /* ask for the module name */
2583 LttvModule
*iter_module
= lttv_library_module_get(library
, i
);
2584 lttv_module_info(iter_module
, &module_info
[i
]);
2586 gchar
*path
= module_info
[i
].name
;
2587 g_ptr_array_add(name
, path
);
2589 module_name
= get_selection((char **)(name
->pdata
), name
->len
,
2590 "Select a module", "Modules");
2591 if(module_name
!= NULL
) {
2593 if(strcmp(module_name
, module_info
[i
].name
) == 0) {
2594 strncpy(module_name_out
, module_name
, PATH_MAX
);
2595 //module = lttv_library_module_get(i);
2601 g_ptr_array_free(name
, TRUE
);
2602 g_free(module_info
);
2604 if(module_name
== NULL
) return;
2607 lttv_module_require(module_name_out
, &error
);
2608 if(error
!= NULL
) g_warning(error
->message
);
2609 else g_printf("Load module: %s\n", module_name_out
);
2616 gchar str
[PATH_MAX
];
2619 GtkFileSelection
* file_selector
=
2620 (GtkFileSelection
*)gtk_file_selection_new("Select a module");
2621 gtk_file_selection_set_filename(file_selector
, load_module_path_alter
);
2622 gtk_file_selection_hide_fileop_buttons(file_selector
);
2625 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
2627 case GTK_RESPONSE_ACCEPT
:
2628 case GTK_RESPONSE_OK
:
2629 dir
= gtk_file_selection_get_selections (file_selector
);
2630 strncpy(str
,dir
[0],PATH_MAX
);
2631 strncpy(remember_plugins_dir
,dir
[0],PATH_MAX
);
2633 /* only keep file name */
2635 str1
= strrchr(str
,'/');
2638 str1
= strrchr(str
,'\\');
2643 if(*str1
== 'l' && *(str1
+1)== 'i' && *(str1
+2)=='b')
2645 remove info after
. */
2649 str2
= strrchr(str2
, '.');
2650 if(str2
!= NULL
) *str2
= '\0';
2652 lttv_module_require(str1
, &error
);
2654 lttv_library_load(str1
, &error
);
2655 if(error
!= NULL
) g_warning(error
->message
);
2656 else g_printf("Load library: %s\n", str
);
2658 case GTK_RESPONSE_REJECT
:
2659 case GTK_RESPONSE_CANCEL
:
2661 gtk_widget_destroy((GtkWidget
*)file_selector
);
2673 /* Display all loaded modules, let user to select a module to unload
2674 * by calling lttv_module_unload
2678 on_unload_module_activate (GtkMenuItem
*menuitem
,
2681 GError
*error
= NULL
;
2682 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2684 LttvLibrary
*library
;
2689 name
= g_ptr_array_new();
2690 nb
= lttv_library_number();
2691 LttvLibraryInfo
*lib_info
= g_new(LttvLibraryInfo
,nb
);
2692 /* ask for the library name */
2695 LttvLibrary
*iter_lib
= lttv_library_get(i
);
2696 lttv_library_info(iter_lib
, &lib_info
[i
]);
2698 gchar
*path
= lib_info
[i
].name
;
2699 g_ptr_array_add(name
, path
);
2701 lib_name
= get_selection((char **)(name
->pdata
), name
->len
,
2702 "Select a library", "Libraries");
2703 if(lib_name
!= NULL
) {
2705 if(strcmp(lib_name
, lib_info
[i
].name
) == 0) {
2706 library
= lttv_library_get(i
);
2711 g_ptr_array_free(name
, TRUE
);
2714 if(lib_name
== NULL
) return;
2719 /* Ask for the module to load : list modules in the selected lib */
2723 LttvModuleInfo
*module_info
= g_new(LttvModuleInfo
,nb
);
2724 name
= g_ptr_array_new();
2725 nb
= lttv_library_module_number(library
);
2726 /* ask for the module name */
2729 LttvModule
*iter_module
= lttv_library_module_get(library
, i
);
2730 lttv_module_info(iter_module
, &module_info
[i
]);
2732 gchar
*path
= module_info
[i
].name
;
2733 if(module_info
[i
].use_count
> 0) g_ptr_array_add(name
, path
);
2735 module_name
= get_selection((char **)(name
->pdata
), name
->len
,
2736 "Select a module", "Modules");
2737 if(module_name
!= NULL
) {
2739 if(strcmp(module_name
, module_info
[i
].name
) == 0) {
2740 module
= lttv_library_module_get(library
, i
);
2746 g_ptr_array_free(name
, TRUE
);
2747 g_free(module_info
);
2749 if(module_name
== NULL
) return;
2752 lttv_module_release(module
);
2753 LttvModuleInfo module_info
;
2754 lttv_module_info(module
, &module_info
);
2755 g_printf("Release module: %s\n", module_info
.name
);
2759 /* Display a directory dialogue to let user select a path for library searching
2763 on_add_library_search_path_activate (GtkMenuItem
*menuitem
,
2766 GtkDirSelection
* file_selector
= (GtkDirSelection
*)gtk_dir_selection_new("Select library path");
2770 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2771 if(remember_plugins_dir
[0] != '\0')
2772 gtk_dir_selection_set_filename(file_selector
, remember_plugins_dir
);
2774 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
2776 case GTK_RESPONSE_ACCEPT
:
2777 case GTK_RESPONSE_OK
:
2778 dir
= gtk_dir_selection_get_dir (file_selector
);
2779 strncpy(remember_plugins_dir
,dir
,PATH_MAX
);
2780 strncat(remember_plugins_dir
,"/",PATH_MAX
);
2781 lttv_library_path_add(dir
);
2782 case GTK_RESPONSE_REJECT
:
2783 case GTK_RESPONSE_CANCEL
:
2785 gtk_widget_destroy((GtkWidget
*)file_selector
);
2791 /* Display a directory dialogue to let user select a path for library searching
2795 on_remove_library_search_path_activate (GtkMenuItem
*menuitem
,
2798 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2800 const char *lib_path
;
2805 name
= g_ptr_array_new();
2806 nb
= lttv_library_path_number();
2807 /* ask for the library name */
2810 gchar
*path
= lttv_library_path_get(i
);
2811 g_ptr_array_add(name
, path
);
2813 lib_path
= get_selection((char **)(name
->pdata
), name
->len
,
2814 "Select a library path", "Library paths");
2816 g_ptr_array_free(name
, TRUE
);
2818 if(lib_path
== NULL
) return;
2821 lttv_library_path_remove(lib_path
);
2825 on_color_activate (GtkMenuItem
*menuitem
,
2828 g_printf("Color\n");
2833 on_filter_activate (GtkMenuItem
*menuitem
,
2836 g_printf("Filter\n");
2841 on_save_configuration_activate (GtkMenuItem
*menuitem
,
2844 g_printf("Save configuration\n");
2849 on_content_activate (GtkMenuItem
*menuitem
,
2852 g_printf("Content\n");
2857 on_about_activate (GtkMenuItem
*menuitem
,
2860 g_printf("About...\n");
2865 on_button_new_clicked (GtkButton
*button
,
2868 create_new_window((GtkWidget
*)button
, user_data
, TRUE
);
2872 on_button_new_tab_clicked (GtkButton
*button
,
2875 create_new_tab((GtkWidget
*)button
, user_data
);
2879 on_button_open_clicked (GtkButton
*button
,
2882 open_traceset((GtkWidget
*)button
, user_data
);
2887 on_button_add_trace_clicked (GtkButton
*button
,
2890 add_trace((GtkWidget
*)button
, user_data
);
2895 on_button_remove_trace_clicked (GtkButton
*button
,
2898 remove_trace((GtkWidget
*)button
, user_data
);
2902 on_button_redraw_clicked (GtkButton
*button
,
2905 redraw((GtkWidget
*)button
, user_data
);
2909 on_button_continue_processing_clicked (GtkButton
*button
,
2912 continue_processing((GtkWidget
*)button
, user_data
);
2916 on_button_stop_processing_clicked (GtkButton
*button
,
2919 stop_processing((GtkWidget
*)button
, user_data
);
2925 on_button_save_clicked (GtkButton
*button
,
2928 save((GtkWidget
*)button
, user_data
);
2933 on_button_save_as_clicked (GtkButton
*button
,
2936 save_as((GtkWidget
*)button
, user_data
);
2941 on_button_zoom_in_clicked (GtkButton
*button
,
2944 zoom_in((GtkWidget
*)button
, user_data
);
2949 on_button_zoom_out_clicked (GtkButton
*button
,
2952 zoom_out((GtkWidget
*)button
, user_data
);
2957 on_button_zoom_extended_clicked (GtkButton
*button
,
2960 zoom_extended((GtkWidget
*)button
, user_data
);
2965 on_button_go_to_time_clicked (GtkButton
*button
,
2968 go_to_time((GtkWidget
*)button
, user_data
);
2973 on_button_show_time_frame_clicked (GtkButton
*button
,
2976 show_time_frame((GtkWidget
*)button
, user_data
);
2981 on_button_move_up_clicked (GtkButton
*button
,
2984 move_up_viewer((GtkWidget
*)button
, user_data
);
2989 on_button_move_down_clicked (GtkButton
*button
,
2992 move_down_viewer((GtkWidget
*)button
, user_data
);
2997 on_button_delete_viewer_clicked (GtkButton
*button
,
3000 delete_viewer((GtkWidget
*)button
, user_data
);
3004 on_MWindow_destroy (GtkWidget
*widget
,
3007 MainWindow
*main_window
= get_window_data_struct(widget
);
3008 LttvIAttribute
*attributes
= main_window
->attributes
;
3009 LttvAttributeValue value
;
3011 //This is unnecessary, since widgets will be destroyed
3012 //by the main window widget anyway.
3013 //remove_all_menu_toolbar_constructors(main_window, NULL);
3015 g_assert(lttv_iattribute_find_by_path(attributes
,
3016 "viewers/menu", LTTV_POINTER
, &value
));
3017 lttv_menus_destroy((LttvMenus
*)*(value
.v_pointer
));
3019 g_assert(lttv_iattribute_find_by_path(attributes
,
3020 "viewers/toolbar", LTTV_POINTER
, &value
));
3021 lttv_toolbars_destroy((LttvToolbars
*)*(value
.v_pointer
));
3023 g_object_unref(main_window
->attributes
);
3024 g_main_window_list
= g_slist_remove(g_main_window_list
, main_window
);
3026 g_printf("There are now : %d windows\n",g_slist_length(g_main_window_list
));
3027 if(g_slist_length(g_main_window_list
) == 0)
3032 on_MWindow_configure (GtkWidget
*widget
,
3033 GdkEventConfigure
*event
,
3036 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)widget
);
3037 float width
= event
->width
;
3038 TimeWindow time_win
;
3040 TimeInterval
*time_span
;
3043 // MD : removed time width modification upon resizing of the main window.
3044 // The viewers will redraw themselves completely, without time interval
3047 if(mw_data->window_width){
3048 time_span = LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context)->Time_Span ;
3049 time_win = tab->time_window;
3050 ratio = width / mw_data->window_width;
3051 tab->time_window.time_width = ltt_time_mul(time_win.time_width,ratio);
3052 time = ltt_time_sub(time_span->endTime, time_win.start_time);
3053 if(ltt_time_compare(time, tab->time_window.time_width) < 0){
3054 tab->time_window.time_width = time;
3060 mw_data->window_width = (int)width;
3069 on_MNotebook_switch_page (GtkNotebook
*notebook
,
3070 GtkNotebookPage
*page
,
3078 void scroll_value_changed_cb(GtkWidget
*scrollbar
,
3081 Tab
*tab
= (Tab
*)user_data
;
3082 TimeWindow time_window
;
3083 TimeInterval
*time_span
;
3085 GtkAdjustment
*adjust
= gtk_range_get_adjustment(GTK_RANGE(scrollbar
));
3086 gdouble value
= gtk_adjustment_get_value(adjust
);
3087 gdouble upper
, lower
, ratio
, page_size
;
3088 LttvTracesetContext
* tsc
=
3089 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3091 //time_window = tab->time_window;
3093 time_span
= &tsc
->time_span
;
3094 lower
= adjust
->lower
;
3095 upper
= adjust
->upper
;
3096 ratio
= (value
- lower
) / (upper
- lower
);
3097 g_critical("lower %lu, upper %lu, value %lu, ratio %lu", lower
, upper
, value
, ratio
);
3099 //time = ltt_time_sub(time_span->end_time, time_span->start_time);
3100 //time = ltt_time_mul(time, (float)ratio);
3101 //time = ltt_time_add(time_span->start_time, time);
3102 time
= ltt_time_from_double(value
/NANOSECONDS_PER_SECOND
);
3104 time_window
.start_time
= time
;
3106 page_size
= adjust
->page_size
;
3108 time_window
.time_width
=
3109 ltt_time_from_double(page_size
/NANOSECONDS_PER_SECOND
);
3110 //time = ltt_time_sub(time_span->end_time, time);
3111 //if(ltt_time_compare(time,time_window.time_width) < 0){
3112 // time_window.time_width = time;
3115 /* call viewer hooks for new time window */
3116 set_time_window(tab
, &time_window
);
3121 /* callback function to check or uncheck the check box (filter)
3124 void checkbox_changed(GtkTreeView
*treeview
,
3126 GtkTreeViewColumn
*arg2
,
3129 GtkTreeStore
* store
= (GtkTreeStore
*)gtk_tree_view_get_model (treeview
);
3133 if (gtk_tree_model_get_iter ((GtkTreeModel
*)store
, &iter
, arg1
)){
3134 gtk_tree_model_get ((GtkTreeModel
*)store
, &iter
, CHECKBOX_COLUMN
, &value
, -1);
3135 value
= value
? FALSE
: TRUE
;
3136 gtk_tree_store_set (GTK_TREE_STORE (store
), &iter
, CHECKBOX_COLUMN
, value
, -1);
3142 /* According to user's selection, update selector(filter)
3145 void update_filter(LttvTracesetSelector
*s
, GtkTreeStore
*store
)
3147 GtkTreeIter iter
, child_iter
, child_iter1
, child_iter2
;
3148 int i
, j
, k
, nb_eventtype
;
3149 LttvTraceSelector
* trace
;
3150 LttvTracefileSelector
* tracefile
;
3151 LttvEventtypeSelector
* eventtype
;
3152 gboolean value
, value1
, value2
;
3154 if(gtk_tree_model_get_iter_first((GtkTreeModel
*)store
, &iter
)){
3157 trace
= lttv_traceset_selector_trace_get(s
, i
);
3158 nb_eventtype
= lttv_trace_selector_eventtype_number(trace
);
3159 gtk_tree_model_get ((GtkTreeModel
*)store
, &iter
, CHECKBOX_COLUMN
, &value
,-1);
3162 if(gtk_tree_model_iter_children ((GtkTreeModel
*)store
, &child_iter
, &iter
)){
3164 if(j
<1){//eventtype selector for trace
3165 gtk_tree_model_get ((GtkTreeModel
*)store
, &child_iter
, CHECKBOX_COLUMN
, &value2
,-1);
3168 if(gtk_tree_model_iter_children ((GtkTreeModel
*)store
, &child_iter1
, &child_iter
)){
3170 eventtype
= lttv_trace_selector_eventtype_get(trace
,k
);
3171 gtk_tree_model_get ((GtkTreeModel
*)store
, &child_iter1
, CHECKBOX_COLUMN
, &value2
,-1);
3172 lttv_eventtype_selector_set_selected(eventtype
,value2
);
3174 }while(gtk_tree_model_iter_next((GtkTreeModel
*)store
, &child_iter1
));
3177 }else{ //tracefile selector
3178 tracefile
= lttv_trace_selector_tracefile_get(trace
, j
- 1);
3179 gtk_tree_model_get ((GtkTreeModel
*)store
, &child_iter
, CHECKBOX_COLUMN
, &value1
,-1);
3180 lttv_tracefile_selector_set_selected(tracefile
,value1
);
3182 gtk_tree_model_iter_children((GtkTreeModel
*)store
, &child_iter1
, &child_iter
); //eventtype selector
3183 gtk_tree_model_get ((GtkTreeModel
*)store
, &child_iter1
, CHECKBOX_COLUMN
, &value2
,-1);
3186 if(gtk_tree_model_iter_children ((GtkTreeModel
*)store
, &child_iter2
, &child_iter1
)){
3187 do{//eventtype selector for tracefile
3188 eventtype
= lttv_tracefile_selector_eventtype_get(tracefile
,k
);
3189 gtk_tree_model_get ((GtkTreeModel
*)store
, &child_iter2
, CHECKBOX_COLUMN
, &value2
,-1);
3190 lttv_eventtype_selector_set_selected(eventtype
,value2
);
3192 }while(gtk_tree_model_iter_next((GtkTreeModel
*)store
, &child_iter2
));
3198 }while(gtk_tree_model_iter_next((GtkTreeModel
*)store
, &child_iter
));
3201 lttv_trace_selector_set_selected(trace
,value
);
3203 }while(gtk_tree_model_iter_next((GtkTreeModel
*)store
, &iter
));
3208 /* Display a dialogue showing all eventtypes and traces, let user to select the interested
3209 * eventtypes, tracefiles and traces (filter)
3212 gboolean
get_filter_selection(LttvTracesetSelector
*s
,char *title
, char * column_title
)
3214 GtkWidget
* dialogue
;
3215 GtkTreeStore
* store
;
3217 GtkWidget
* scroll_win
;
3218 GtkCellRenderer
* renderer
;
3219 GtkTreeViewColumn
* column
;
3220 GtkTreeIter iter
, child_iter
, child_iter1
, child_iter2
;
3221 int i
, j
, k
, id
, nb_trace
, nb_tracefile
, nb_eventtype
;
3222 LttvTraceSelector
* trace
;
3223 LttvTracefileSelector
* tracefile
;
3224 LttvEventtypeSelector
* eventtype
;
3228 dialogue
= gtk_dialog_new_with_buttons(title
,
3231 GTK_STOCK_OK
,GTK_RESPONSE_ACCEPT
,
3232 GTK_STOCK_CANCEL
,GTK_RESPONSE_REJECT
,
3234 gtk_window_set_default_size((GtkWindow
*)dialogue
, 300, 500);
3236 store
= gtk_tree_store_new (TOTAL_COLUMNS
, G_TYPE_BOOLEAN
, G_TYPE_STRING
);
3237 tree
= gtk_tree_view_new_with_model (GTK_TREE_MODEL (store
));
3238 g_object_unref (G_OBJECT (store
));
3239 g_signal_connect (G_OBJECT (tree
), "row-activated",
3240 G_CALLBACK (checkbox_changed
),
3244 renderer
= gtk_cell_renderer_toggle_new ();
3245 gtk_cell_renderer_toggle_set_radio((GtkCellRendererToggle
*)renderer
, FALSE
);
3247 g_object_set (G_OBJECT (renderer
),"activatable", TRUE
, NULL
);
3249 column
= gtk_tree_view_column_new_with_attributes ("Checkbox",
3251 "active", CHECKBOX_COLUMN
,
3253 gtk_tree_view_column_set_alignment (column
, 0.5);
3254 gtk_tree_view_column_set_fixed_width (column
, 20);
3255 gtk_tree_view_append_column (GTK_TREE_VIEW (tree
), column
);
3257 renderer
= gtk_cell_renderer_text_new ();
3258 column
= gtk_tree_view_column_new_with_attributes (column_title
,
3260 "text", NAME_COLUMN
,
3262 gtk_tree_view_column_set_alignment (column
, 0.0);
3263 gtk_tree_view_append_column (GTK_TREE_VIEW (tree
), column
);
3264 gtk_tree_view_set_headers_visible(GTK_TREE_VIEW (tree
), FALSE
);
3266 scroll_win
= gtk_scrolled_window_new (NULL
, NULL
);
3267 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll_win
),
3268 GTK_POLICY_AUTOMATIC
,GTK_POLICY_AUTOMATIC
);
3269 gtk_container_add (GTK_CONTAINER (scroll_win
), tree
);
3271 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialogue
)->vbox
), scroll_win
,TRUE
, TRUE
,0);
3273 gtk_widget_show(scroll_win
);
3274 gtk_widget_show(tree
);
3276 nb_trace
= lttv_traceset_selector_trace_number(s
);
3277 for(i
=0;i
<nb_trace
;i
++){
3278 trace
= lttv_traceset_selector_trace_get(s
, i
);
3279 name
= lttv_trace_selector_get_name(trace
);
3280 gtk_tree_store_append (store
, &iter
, NULL
);
3281 checked
= lttv_trace_selector_get_selected(trace
);
3282 gtk_tree_store_set (store
, &iter
,
3283 CHECKBOX_COLUMN
,checked
,
3287 gtk_tree_store_append (store
, &child_iter
, &iter
);
3288 gtk_tree_store_set (store
, &child_iter
,
3289 CHECKBOX_COLUMN
, checked
,
3290 NAME_COLUMN
,"eventtype",
3293 nb_eventtype
= lttv_trace_selector_eventtype_number(trace
);
3294 for(j
=0;j
<nb_eventtype
;j
++){
3295 eventtype
= lttv_trace_selector_eventtype_get(trace
,j
);
3296 name
= lttv_eventtype_selector_get_name(eventtype
);
3297 checked
= lttv_eventtype_selector_get_selected(eventtype
);
3298 gtk_tree_store_append (store
, &child_iter1
, &child_iter
);
3299 gtk_tree_store_set (store
, &child_iter1
,
3300 CHECKBOX_COLUMN
, checked
,
3305 nb_tracefile
= lttv_trace_selector_tracefile_number(trace
);
3306 for(j
=0;j
<nb_tracefile
;j
++){
3307 tracefile
= lttv_trace_selector_tracefile_get(trace
, j
);
3308 name
= lttv_tracefile_selector_get_name(tracefile
);
3309 gtk_tree_store_append (store
, &child_iter
, &iter
);
3310 checked
= lttv_tracefile_selector_get_selected(tracefile
);
3311 gtk_tree_store_set (store
, &child_iter
,
3312 CHECKBOX_COLUMN
, checked
,
3316 gtk_tree_store_append (store
, &child_iter1
, &child_iter
);
3317 gtk_tree_store_set (store
, &child_iter1
,
3318 CHECKBOX_COLUMN
, checked
,
3319 NAME_COLUMN
,"eventtype",
3322 for(k
=0;k
<nb_eventtype
;k
++){
3323 eventtype
= lttv_tracefile_selector_eventtype_get(tracefile
,k
);
3324 name
= lttv_eventtype_selector_get_name(eventtype
);
3325 checked
= lttv_eventtype_selector_get_selected(eventtype
);
3326 gtk_tree_store_append (store
, &child_iter2
, &child_iter1
);
3327 gtk_tree_store_set (store
, &child_iter2
,
3328 CHECKBOX_COLUMN
, checked
,
3335 id
= gtk_dialog_run(GTK_DIALOG(dialogue
));
3337 case GTK_RESPONSE_ACCEPT
:
3338 case GTK_RESPONSE_OK
:
3339 update_filter(s
, store
);
3340 gtk_widget_destroy(dialogue
);
3342 case GTK_RESPONSE_REJECT
:
3343 case GTK_RESPONSE_CANCEL
:
3345 gtk_widget_destroy(dialogue
);
3352 /* Select a trace which will be removed from traceset
3355 char * get_remove_trace(char ** all_trace_name
, int nb_trace
)
3357 return get_selection(all_trace_name
, nb_trace
,
3358 "Select a trace", "Trace pathname");
3362 /* Select a module which will be loaded
3365 char * get_load_module(char ** load_module_name
, int nb_module
)
3367 return get_selection(load_module_name
, nb_module
,
3368 "Select a module to load", "Module name");
3374 /* Select a module which will be unloaded
3377 char * get_unload_module(char ** loaded_module_name
, int nb_module
)
3379 return get_selection(loaded_module_name
, nb_module
,
3380 "Select a module to unload", "Module name");
3384 /* Display a dialogue which shows all selectable items, let user to
3385 * select one of them
3388 char * get_selection(char ** loaded_module_name
, int nb_module
,
3389 char *title
, char * column_title
)
3391 GtkWidget
* dialogue
;
3392 GtkWidget
* scroll_win
;
3394 GtkListStore
* store
;
3395 GtkTreeViewColumn
* column
;
3396 GtkCellRenderer
* renderer
;
3397 GtkTreeSelection
* select
;
3400 char * unload_module_name
= NULL
;
3402 dialogue
= gtk_dialog_new_with_buttons(title
,
3405 GTK_STOCK_OK
,GTK_RESPONSE_ACCEPT
,
3406 GTK_STOCK_CANCEL
,GTK_RESPONSE_REJECT
,
3408 gtk_window_set_default_size((GtkWindow
*)dialogue
, 500, 200);
3410 scroll_win
= gtk_scrolled_window_new (NULL
, NULL
);
3411 gtk_widget_show ( scroll_win
);
3412 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll_win
),
3413 GTK_POLICY_AUTOMATIC
, GTK_POLICY_AUTOMATIC
);
3415 store
= gtk_list_store_new (N_COLUMNS
,G_TYPE_STRING
);
3416 tree
= gtk_tree_view_new_with_model(GTK_TREE_MODEL (store
));
3417 gtk_widget_show ( tree
);
3418 g_object_unref (G_OBJECT (store
));
3420 renderer
= gtk_cell_renderer_text_new ();
3421 column
= gtk_tree_view_column_new_with_attributes (column_title
,
3423 "text", MODULE_COLUMN
,
3425 gtk_tree_view_column_set_alignment (column
, 0.5);
3426 gtk_tree_view_column_set_fixed_width (column
, 150);
3427 gtk_tree_view_append_column (GTK_TREE_VIEW (tree
), column
);
3429 select
= gtk_tree_view_get_selection (GTK_TREE_VIEW (tree
));
3430 gtk_tree_selection_set_mode (select
, GTK_SELECTION_SINGLE
);
3432 gtk_container_add (GTK_CONTAINER (scroll_win
), tree
);
3434 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialogue
)->vbox
), scroll_win
,TRUE
, TRUE
,0);
3436 for(i
=0;i
<nb_module
;i
++){
3437 gtk_list_store_append (store
, &iter
);
3438 gtk_list_store_set (store
, &iter
, MODULE_COLUMN
,loaded_module_name
[i
],-1);
3441 id
= gtk_dialog_run(GTK_DIALOG(dialogue
));
3443 case GTK_RESPONSE_ACCEPT
:
3444 case GTK_RESPONSE_OK
:
3445 if (gtk_tree_selection_get_selected (select
, (GtkTreeModel
**)&store
, &iter
)){
3446 gtk_tree_model_get ((GtkTreeModel
*)store
, &iter
, MODULE_COLUMN
, &unload_module_name
, -1);
3448 case GTK_RESPONSE_REJECT
:
3449 case GTK_RESPONSE_CANCEL
:
3451 gtk_widget_destroy(dialogue
);
3455 return unload_module_name
;
3459 /* Insert all menu entry and tool buttons into this main window
3464 void add_all_menu_toolbar_constructors(MainWindow
* mw
, gpointer user_data
)
3468 lttvwindow_viewer_constructor constructor
;
3469 LttvMenus
* global_menu
, * instance_menu
;
3470 LttvToolbars
* global_toolbar
, * instance_toolbar
;
3471 LttvMenuClosure
*menu_item
;
3472 LttvToolbarClosure
*toolbar_item
;
3473 LttvAttributeValue value
;
3474 LttvIAttribute
*global_attributes
= LTTV_IATTRIBUTE(lttv_global_attributes());
3475 LttvIAttribute
*attributes
= mw
->attributes
;
3476 GtkWidget
* tool_menu_title_menu
, *new_widget
, *pixmap
;
3478 g_assert(lttv_iattribute_find_by_path(global_attributes
,
3479 "viewers/menu", LTTV_POINTER
, &value
));
3480 if(*(value
.v_pointer
) == NULL
)
3481 *(value
.v_pointer
) = lttv_menus_new();
3482 global_menu
= (LttvMenus
*)*(value
.v_pointer
);
3484 g_assert(lttv_iattribute_find_by_path(attributes
,
3485 "viewers/menu", LTTV_POINTER
, &value
));
3486 if(*(value
.v_pointer
) == NULL
)
3487 *(value
.v_pointer
) = lttv_menus_new();
3488 instance_menu
= (LttvMenus
*)*(value
.v_pointer
);
3492 g_assert(lttv_iattribute_find_by_path(global_attributes
,
3493 "viewers/toolbar", LTTV_POINTER
, &value
));
3494 if(*(value
.v_pointer
) == NULL
)
3495 *(value
.v_pointer
) = lttv_toolbars_new();
3496 global_toolbar
= (LttvToolbars
*)*(value
.v_pointer
);
3498 g_assert(lttv_iattribute_find_by_path(attributes
,
3499 "viewers/toolbar", LTTV_POINTER
, &value
));
3500 if(*(value
.v_pointer
) == NULL
)
3501 *(value
.v_pointer
) = lttv_toolbars_new();
3502 instance_toolbar
= (LttvToolbars
*)*(value
.v_pointer
);
3504 /* Add missing menu entries to window instance */
3505 for(i
=0;i
<global_menu
->len
;i
++) {
3506 menu_item
= &g_array_index(global_menu
, LttvMenuClosure
, i
);
3508 //add menu_item to window instance;
3509 constructor
= menu_item
->con
;
3510 tool_menu_title_menu
= lookup_widget(mw
->mwindow
,"ToolMenuTitle_menu");
3512 gtk_menu_item_new_with_mnemonic (menu_item
->menu_text
);
3513 gtk_container_add (GTK_CONTAINER (tool_menu_title_menu
),
3515 g_signal_connect ((gpointer
) new_widget
, "activate",
3516 G_CALLBACK (insert_viewer_wrap
),
3518 gtk_widget_show (new_widget
);
3519 lttv_menus_add(instance_menu
, menu_item
->con
,
3520 menu_item
->menu_path
,
3521 menu_item
->menu_text
,
3526 /* Add missing toolbar entries to window instance */
3527 for(i
=0;i
<global_toolbar
->len
;i
++) {
3528 toolbar_item
= &g_array_index(global_toolbar
, LttvToolbarClosure
, i
);
3530 //add toolbar_item to window instance;
3531 constructor
= toolbar_item
->con
;
3532 tool_menu_title_menu
= lookup_widget(mw
->mwindow
,"MToolbar1");
3533 pixbuf
= gdk_pixbuf_new_from_xpm_data((const char**)toolbar_item
->pixmap
);
3534 pixmap
= gtk_image_new_from_pixbuf(pixbuf
);
3536 gtk_toolbar_append_element (GTK_TOOLBAR (tool_menu_title_menu
),
3537 GTK_TOOLBAR_CHILD_BUTTON
,
3540 toolbar_item
->tooltip
, NULL
,
3541 pixmap
, NULL
, NULL
);
3542 gtk_label_set_use_underline(
3543 GTK_LABEL (((GtkToolbarChild
*) (
3544 g_list_last (GTK_TOOLBAR
3545 (tool_menu_title_menu
)->children
)->data
))->label
),
3547 gtk_container_set_border_width (GTK_CONTAINER (new_widget
), 1);
3548 g_signal_connect ((gpointer
) new_widget
,
3550 G_CALLBACK (insert_viewer_wrap
),
3552 gtk_widget_show (new_widget
);
3554 lttv_toolbars_add(instance_toolbar
, toolbar_item
->con
,
3555 toolbar_item
->tooltip
,
3556 toolbar_item
->pixmap
,
3564 /* Create a main window
3567 void construct_main_window(MainWindow
* parent
)
3569 g_debug("construct_main_window()");
3570 GtkWidget
* new_window
; /* New generated main window */
3571 MainWindow
* new_m_window
;/* New main window structure */
3572 GtkNotebook
* notebook
;
3573 LttvIAttribute
*attributes
=
3574 LTTV_IATTRIBUTE(g_object_new(LTTV_ATTRIBUTE_TYPE
, NULL
));
3575 LttvAttributeValue value
;
3578 new_m_window
= g_new(MainWindow
, 1);
3580 // Add the object's information to the module's array
3581 g_main_window_list
= g_slist_append(g_main_window_list
, new_m_window
);
3584 new_window
= create_MWindow();
3585 gtk_widget_show (new_window
);
3587 new_m_window
->mwindow
= new_window
;
3588 new_m_window
->attributes
= attributes
;
3590 g_assert(lttv_iattribute_find_by_path(attributes
,
3591 "viewers/menu", LTTV_POINTER
, &value
));
3592 *(value
.v_pointer
) = lttv_menus_new();
3594 g_assert(lttv_iattribute_find_by_path(attributes
,
3595 "viewers/toolbar", LTTV_POINTER
, &value
));
3596 *(value
.v_pointer
) = lttv_toolbars_new();
3598 add_all_menu_toolbar_constructors(new_m_window
, NULL
);
3600 g_object_set_data_full(G_OBJECT(new_window
),
3602 (gpointer
)new_m_window
,
3603 (GDestroyNotify
)g_free
);
3604 //create a default tab
3605 notebook
= (GtkNotebook
*)lookup_widget(new_m_window
->mwindow
, "MNotebook");
3606 if(notebook
== NULL
){
3607 g_printf("Notebook does not exist\n");
3610 gtk_notebook_popup_enable (GTK_NOTEBOOK(notebook
));
3611 //for now there is no name field in LttvTraceset structure
3612 //Use "Traceset" as the label for the default tab
3614 GtkWidget
* parent_notebook
= lookup_widget(parent
->mwindow
, "MNotebook");
3615 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(parent_notebook
),
3616 gtk_notebook_get_current_page(GTK_NOTEBOOK(parent_notebook
)));
3622 parent_tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
3624 new_tab
= create_tab(new_m_window
, parent_tab
, notebook
, "Traceset");
3626 new_tab
= create_tab(new_m_window
, NULL
, notebook
, "Traceset");
3627 if(g_init_trace
!= NULL
){
3628 lttvwindow_add_trace(new_tab
,
3633 g_printf("There are now : %d windows\n",g_slist_length(g_main_window_list
));
3637 /* Free the memory occupied by a tab structure
3641 void tab_destructor(Tab
* tab_instance
)
3643 int i
, nb
, ref_count
;
3646 if(tab_instance
->attributes
)
3647 g_object_unref(tab_instance
->attributes
);
3649 if(tab_instance
->interrupted_state
)
3650 g_object_unref(tab_instance
->interrupted_state
);
3653 if(tab_instance
->traceset_info
->traceset_context
!= NULL
){
3654 //remove state update hooks
3655 lttv_state_remove_event_hooks(
3656 (LttvTracesetState
*)tab_instance
->traceset_info
->
3658 lttv_context_fini(LTTV_TRACESET_CONTEXT(tab_instance
->traceset_info
->
3660 g_object_unref(tab_instance
->traceset_info
->traceset_context
);
3662 if(tab_instance
->traceset_info
->traceset
!= NULL
) {
3663 nb
= lttv_traceset_number(tab_instance
->traceset_info
->traceset
);
3664 for(i
= 0 ; i
< nb
; i
++) {
3665 trace
= lttv_traceset_get(tab_instance
->traceset_info
->traceset
, i
);
3666 ref_count
= lttv_trace_get_ref_number(trace
);
3668 ltt_trace_close(lttv_trace(trace
));
3672 lttv_traceset_destroy(tab_instance
->traceset_info
->traceset
);
3673 /* Remove the idle events requests processing function of the tab */
3674 g_idle_remove_by_data(tab_instance
);
3676 g_slist_free(tab_instance
->events_requests
);
3677 g_free(tab_instance
->traceset_info
);
3678 g_free(tab_instance
);
3682 /* Create a tab and insert it into the current main window
3685 Tab
* create_tab(MainWindow
* mw
, Tab
*copy_tab
,
3686 GtkNotebook
* notebook
, char * label
)
3692 //create a new tab data structure
3695 //construct and initialize the traceset_info
3696 tab
->traceset_info
= g_new(TracesetInfo
,1);
3699 tab
->traceset_info
->traceset
=
3700 lttv_traceset_copy(copy_tab
->traceset_info
->traceset
);
3702 tab
->traceset_info
->traceset
= lttv_traceset_new();
3705 //FIXME : this is g_debug level
3706 lttv_attribute_write_xml(
3707 lttv_traceset_attribute(tab
->traceset_info
->traceset
),
3713 //FIXME copy not implemented in lower level
3714 tab
->traceset_info
->traceset_context
=
3715 g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
3716 g_assert(tab
->traceset_info
->traceset_context
!= NULL
);
3718 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
),
3719 tab
->traceset_info
->traceset
);
3720 //add state update hooks
3721 lttv_state_add_event_hooks(
3722 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
3724 //determine the current_time and time_window of the tab
3725 if(copy_tab
!= NULL
){
3726 tab
->time_window
= copy_tab
->time_window
;
3727 tab
->current_time
= copy_tab
->current_time
;
3729 tab
->time_window
.start_time
=
3730 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
3731 time_span
.start_time
;
3732 if(DEFAULT_TIME_WIDTH_S
<
3733 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
3734 time_span
.end_time
.tv_sec
)
3735 tmp_time
.tv_sec
= DEFAULT_TIME_WIDTH_S
;
3738 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
3739 time_span
.end_time
.tv_sec
;
3740 tmp_time
.tv_nsec
= 0;
3741 tab
->time_window
.time_width
= tmp_time
;
3742 tab
->current_time
.tv_sec
=
3743 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
3744 time_span
.start_time
.tv_sec
;
3745 tab
->current_time
.tv_nsec
=
3746 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
3747 time_span
.start_time
.tv_nsec
;
3749 tab
->attributes
= LTTV_IATTRIBUTE(g_object_new(LTTV_ATTRIBUTE_TYPE
, NULL
));
3750 tab
->interrupted_state
= g_object_new(LTTV_ATTRIBUTE_TYPE
, NULL
);
3752 tab
->vbox
= gtk_vbox_new(FALSE
, 0);
3753 tab
->viewer_container
= gtk_vbox_new(TRUE
, 0);
3754 tab
->scrollbar
= gtk_hscrollbar_new(NULL
);
3755 //tab->multivpaned = gtk_multi_vpaned_new();
3757 gtk_box_pack_start(GTK_BOX(tab
->vbox
),
3758 tab
->viewer_container
,
3760 TRUE
, /* Give the extra space to the child */
3761 0); /* No padding */
3763 gtk_box_pack_end(GTK_BOX(tab
->vbox
),
3765 FALSE
, /* Do not expand */
3766 FALSE
, /* Fill has no effect here (expand false) */
3767 0); /* No padding */
3769 g_object_set_data(G_OBJECT(tab
->viewer_container
), "focused_viewer", NULL
);
3775 // Display a label with a X
3776 GtkWidget *w_hbox = gtk_hbox_new(FALSE, 4);
3777 GtkWidget *w_label = gtk_label_new (label);
3778 GtkWidget *pixmap = create_pixmap(GTK_WIDGET(notebook), "close.png");
3779 GtkWidget *w_button = gtk_button_new ();
3780 gtk_container_add(GTK_CONTAINER(w_button), pixmap);
3781 //GtkWidget *w_button = gtk_button_new_with_label("x");
3783 gtk_button_set_relief(GTK_BUTTON(w_button), GTK_RELIEF_NONE);
3785 gtk_box_pack_start(GTK_BOX(w_hbox), w_label, TRUE, TRUE, 0);
3786 gtk_box_pack_end(GTK_BOX(w_hbox), w_button, FALSE,
3789 g_signal_connect_swapped (w_button, "clicked",
3790 G_CALLBACK (on_close_tab_X_clicked),
3793 gtk_widget_set_state(w_button, GTK_STATE_ACTIVE);
3795 gtk_widget_show (w_label);
3796 gtk_widget_show (pixmap);
3797 gtk_widget_show (w_button);
3798 gtk_widget_show (w_hbox);
3800 tab->label = w_hbox;
3804 tab
->label
= gtk_label_new (label
);
3806 gtk_widget_show(tab
->label
);
3807 gtk_widget_show(tab
->scrollbar
);
3808 gtk_widget_show(tab
->viewer_container
);
3809 gtk_widget_show(tab
->vbox
);
3810 //gtk_widget_show(tab->multivpaned);
3813 /* Start with empty events requests list */
3814 tab
->events_requests
= NULL
;
3815 tab
->events_request_pending
= FALSE
;
3817 g_object_set_data_full(
3818 G_OBJECT(tab
->vbox
),
3821 (GDestroyNotify
)tab_destructor
);
3823 g_signal_connect(G_OBJECT(tab
->scrollbar
), "value-changed",
3824 G_CALLBACK(scroll_value_changed_cb
), tab
);
3825 //g_signal_connect(G_OBJECT(tab->scrollbar), "changed",
3826 // G_CALLBACK(scroll_value_changed_cb), tab);
3829 //insert tab into notebook
3830 gtk_notebook_append_page(notebook
,
3833 list
= gtk_container_get_children(GTK_CONTAINER(notebook
));
3834 gtk_notebook_set_current_page(notebook
,g_list_length(list
)-1);
3835 // always show : not if(g_list_length(list)>1)
3836 gtk_notebook_set_show_tabs(notebook
, TRUE
);
3842 * execute_events_requests
3844 * Idle function that executes the pending requests for a tab.
3846 * @return return value : TRUE : keep the idle function, FALSE : remove it.
3848 gboolean
execute_events_requests(Tab
*tab
)
3850 return ( lttvwindow_process_pending_requests(tab
) );