1 /* This file is part of the Linux Trace Toolkit viewer
2 * Copyright (C) 2003-2004 XangXiu Yang
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,
25 #include "callbacks.h"
26 #include "interface.h"
28 #include <ltt/trace.h>
29 #include <ltt/facility.h>
31 #include <ltt/event.h>
32 #include <lttv/lttv.h>
33 #include <lttv/module.h>
34 #include <lttv/iattribute.h>
35 #include <lttv/stats.h>
36 #include <lttvwindow/mainwindow.h>
37 #include <lttvwindow/mainwindow-private.h>
38 #include <lttvwindow/menu.h>
39 #include <lttvwindow/toolbar.h>
40 #include <lttvwindow/lttvwindow.h>
41 #include <lttvwindow/gtkdirsel.h>
42 #include <lttvwindow/lttvfilter.h>
44 #define PATH_LENGTH 256
45 #define DEFAULT_TIME_WIDTH_S 1
47 extern LttvTrace
*g_init_trace
;
50 /** Array containing instanced objects. */
51 extern GSList
* g_main_window_list
;
53 /** MD : keep old directory. */
54 static char remember_plugins_dir
[PATH_LENGTH
] = "";
55 static char remember_trace_dir
[PATH_LENGTH
] = "";
58 MainWindow
* get_window_data_struct(GtkWidget
* widget
);
59 char * get_unload_module(char ** loaded_module_name
, int nb_module
);
60 char * get_remove_trace(char ** all_trace_name
, int nb_trace
);
61 char * get_selection(char ** all_name
, int nb
, char *title
, char * column_title
);
62 gboolean
get_filter_selection(LttvTracesetSelector
*s
, char *title
, char * column_title
);
63 Tab
* create_tab(MainWindow
* mw
, Tab
*copy_tab
,
64 GtkNotebook
* notebook
, char * label
);
66 static void insert_viewer(GtkWidget
* widget
, lttvwindow_viewer_constructor constructor
);
67 void update_filter(LttvTracesetSelector
*s
, GtkTreeStore
*store
);
69 void checkbox_changed(GtkTreeView
*treeview
,
71 GtkTreeViewColumn
*arg2
,
73 void remove_trace_from_traceset_selector(GtkMultiVPaned
* paned
, unsigned i
);
74 void add_trace_into_traceset_selector(GtkMultiVPaned
* paned
, LttTrace
* trace
);
75 Tab
*create_new_tab(GtkWidget
* widget
, gpointer user_data
);
77 LttvTracesetSelector
* construct_traceset_selector(LttvTraceset
* traceset
);
79 static gboolean
lttvwindow_process_pending_requests(Tab
*tab
);
93 /* Construct a selector(filter), which will be associated with a viewer,
94 * and provides an interface for user to select interested events and traces
97 LttvTracesetSelector
* construct_traceset_selector(LttvTraceset
* traceset
)
99 LttvTracesetSelector
* s
;
100 LttvTraceSelector
* trace
;
101 LttvTracefileSelector
* tracefile
;
102 LttvEventtypeSelector
* eventtype
;
104 int nb_trace
, nb_tracefile
, nb_control
, nb_per_cpu
, nb_facility
, nb_event
;
111 s
= lttv_traceset_selector_new(lttv_traceset_name(traceset
));
112 nb_trace
= lttv_traceset_number(traceset
);
113 for(i
=0;i
<nb_trace
;i
++){
114 trace_v
= lttv_traceset_get(traceset
, i
);
115 t
= lttv_trace(trace_v
);
116 trace
= lttv_trace_selector_new(t
);
117 lttv_traceset_selector_trace_add(s
, trace
);
119 nb_facility
= ltt_trace_facility_number(t
);
120 for(k
=0;k
<nb_facility
;k
++){
121 fac
= ltt_trace_facility_get(t
,k
);
122 nb_event
= (int) ltt_facility_eventtype_number(fac
);
123 for(m
=0;m
<nb_event
;m
++){
124 et
= ltt_facility_eventtype_get(fac
,m
);
125 eventtype
= lttv_eventtype_selector_new(et
);
126 lttv_trace_selector_eventtype_add(trace
, eventtype
);
130 nb_control
= ltt_trace_control_tracefile_number(t
);
131 nb_per_cpu
= ltt_trace_per_cpu_tracefile_number(t
);
132 nb_tracefile
= nb_control
+ nb_per_cpu
;
134 for(j
= 0 ; j
< nb_tracefile
; j
++) {
136 tf
= ltt_trace_control_tracefile_get(t
, j
);
138 tf
= ltt_trace_per_cpu_tracefile_get(t
, j
- nb_control
);
139 tracefile
= lttv_tracefile_selector_new(tf
);
140 lttv_trace_selector_tracefile_add(trace
, tracefile
);
141 lttv_eventtype_selector_copy(trace
, tracefile
);
148 /* insert_viewer function constructs an instance of a viewer first,
149 * then inserts the widget of the instance into the container of the
154 insert_viewer_wrap(GtkWidget
*menuitem
, gpointer user_data
)
158 insert_viewer((GtkWidget
*)menuitem
, (lttvwindow_viewer_constructor
)user_data
);
159 // selected_hook(&val);
163 /* internal functions */
164 void insert_viewer(GtkWidget
* widget
, lttvwindow_viewer_constructor constructor
)
166 GtkMultiVPaned
* multi_vpaned
;
167 MainWindow
* mw_data
= get_window_data_struct(widget
);
168 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
170 LttvTracesetSelector
* s
;
171 TimeInterval
* time_interval
;
172 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
173 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
177 tab
= create_new_tab(widget
, NULL
);
179 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
182 multi_vpaned
= tab
->multi_vpaned
;
184 s
= construct_traceset_selector(tab
->traceset_info
->traceset
);
185 viewer
= (GtkWidget
*)constructor(tab
, s
, "Traceset_Selector");
188 gtk_multi_vpaned_widget_add(multi_vpaned
, viewer
);
189 // We unref here, because it is now referenced by the multi_vpaned!
190 g_object_unref(G_OBJECT(viewer
));
192 // The viewer will show itself when it receives a show notify
193 // So we call the show notify hooks here. It will
194 // typically add hooks for reading, we call process trace, and the
195 // end of reading hook will call gtk_widget_show and unregister the
197 // Note that show notify gets the time_requested through the call_data.
198 //show_viewer(mw_data);
199 // in expose now call_pending_read_hooks(mw_data);
204 /* get_label function is used to get user input, it displays an input
205 * box, which allows user to input a string
208 void get_label_string (GtkWidget
* text
, gchar
* label
)
210 GtkEntry
* entry
= (GtkEntry
*)text
;
211 if(strlen(gtk_entry_get_text(entry
))!=0)
212 strcpy(label
,gtk_entry_get_text(entry
));
215 gboolean
get_label(MainWindow
* mw
, gchar
* str
, gchar
* dialogue_title
, gchar
* label_str
)
217 GtkWidget
* dialogue
;
222 dialogue
= gtk_dialog_new_with_buttons(dialogue_title
,NULL
,
224 GTK_STOCK_OK
,GTK_RESPONSE_ACCEPT
,
225 GTK_STOCK_CANCEL
,GTK_RESPONSE_REJECT
,
228 label
= gtk_label_new(label_str
);
229 gtk_widget_show(label
);
231 text
= gtk_entry_new();
232 gtk_widget_show(text
);
234 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialogue
)->vbox
), label
,TRUE
, TRUE
,0);
235 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialogue
)->vbox
), text
,FALSE
, FALSE
,0);
237 id
= gtk_dialog_run(GTK_DIALOG(dialogue
));
239 case GTK_RESPONSE_ACCEPT
:
240 get_label_string(text
,str
);
241 gtk_widget_destroy(dialogue
);
243 case GTK_RESPONSE_REJECT
:
245 gtk_widget_destroy(dialogue
);
252 /* get_window_data_struct function is actually a lookup function,
253 * given a widget which is in the tree of the main window, it will
254 * return the MainWindow data structure associated with main window
257 MainWindow
* get_window_data_struct(GtkWidget
* widget
)
260 MainWindow
* mw_data
;
262 mw
= lookup_widget(widget
, "MWindow");
264 g_printf("Main window does not exist\n");
268 mw_data
= (MainWindow
*) g_object_get_data(G_OBJECT(mw
),"main_window_data");
270 g_printf("Main window data does not exist\n");
277 /* create_new_window function, just constructs a new main window
280 void create_new_window(GtkWidget
* widget
, gpointer user_data
, gboolean clone
)
282 MainWindow
* parent
= get_window_data_struct(widget
);
285 g_printf("Clone : use the same traceset\n");
286 construct_main_window(parent
);
288 g_printf("Empty : traceset is set to NULL\n");
289 construct_main_window(NULL
);
294 /* move_*_viewer functions move the selected view up/down in
298 void move_up_viewer(GtkWidget
* widget
, gpointer user_data
)
300 MainWindow
* mw
= get_window_data_struct(widget
);
301 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
303 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
304 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
311 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
314 gtk_multi_vpaned_widget_move_up(tab
->multi_vpaned
);
317 void move_down_viewer(GtkWidget
* widget
, gpointer user_data
)
319 MainWindow
* mw
= get_window_data_struct(widget
);
320 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
322 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
323 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
329 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
332 gtk_multi_vpaned_widget_move_down(tab
->multi_vpaned
);
336 /* delete_viewer deletes the selected viewer in the current tab
339 void delete_viewer(GtkWidget
* widget
, gpointer user_data
)
341 MainWindow
* mw
= get_window_data_struct(widget
);
342 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
344 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
345 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
351 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
354 gtk_multi_vpaned_widget_delete(tab
->multi_vpaned
);
358 /* open_traceset will open a traceset saved in a file
359 * Right now, it is not finished yet, (not working)
363 void open_traceset(GtkWidget
* widget
, gpointer user_data
)
367 LttvTraceset
* traceset
;
368 MainWindow
* mw_data
= get_window_data_struct(widget
);
369 GtkFileSelection
* file_selector
=
370 (GtkFileSelection
*)gtk_file_selection_new("Select a traceset");
372 gtk_file_selection_hide_fileop_buttons(file_selector
);
374 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
376 case GTK_RESPONSE_ACCEPT
:
377 case GTK_RESPONSE_OK
:
378 dir
= gtk_file_selection_get_selections (file_selector
);
379 traceset
= lttv_traceset_load(dir
[0]);
380 g_printf("Open a trace set %s\n", dir
[0]);
383 case GTK_RESPONSE_REJECT
:
384 case GTK_RESPONSE_CANCEL
:
386 gtk_widget_destroy((GtkWidget
*)file_selector
);
393 /* lttvwindow_process_pending_requests
395 * This internal function gets called by g_idle, taking care of the pending
396 * requests. It is responsible for concatenation of time intervals and position
397 * requests. It does it with the following algorithm organizing process traceset
398 * calls. Here is the detailed description of the way it works :
400 * - Events Requests Servicing Algorithm
402 * Data structures necessary :
404 * List of requests added to context : list_in
405 * List of requests not added to context : list_out
410 * list_out : many events requests
412 * FIXME : insert rest of algorithm here
417 gboolean
lttvwindow_process_pending_requests(Tab
*tab
)
419 unsigned max_nb_events
;
423 LttvTracesetContext
*tsc
;
424 LttvTracefileContext
*tfc
;
425 GSList
*events_requests
= tab
->events_requests
;
426 GSList
*list_out
= events_requests
;
427 GSList
*list_in
= NULL
;
431 LttvTracesetContextPosition
*end_position
;
434 /* Current tab check : if no current tab is present, no hooks to call. */
435 /* (Xang Xiu) It makes the expose works.. MD:? */
439 /* There is no events requests pending : we should never have been called! */
440 g_assert(g_slist_length(events_requests
) != 0);
442 tsc
= LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
444 //set the cursor to be X shape, indicating that the computer is busy in doing its job
445 new = gdk_cursor_new(GDK_X_CURSOR
);
446 widget
= lookup_widget(tab
->mw
->mwindow
, "MToolbar1");
447 win
= gtk_widget_get_parent_window(widget
);
448 gdk_window_set_cursor(win
, new);
449 gdk_cursor_unref(new);
450 gdk_window_stick(win
);
451 gdk_window_unstick(win
);
453 g_debug("SIZE events req len : %d", g_slist_length(events_requests
));
455 /* Events processing algorithm implementation */
456 /* A. Servicing loop */
457 while( (g_slist_length(list_in
) != 0 || g_slist_length(list_out
) != 0)
458 && !gtk_events_pending() ) {
460 /* 1. If list_in is empty (need a seek) */
461 if( g_slist_length(list_in
) == 0 ) {
463 /* list in is empty, need a seek */
465 /* 1.1 Add requests to list_in */
466 GSList
*ltime
= NULL
;
470 /* 1.1.1 Find all time requests with the lowest start time in list_out
473 if(g_slist_length(list_out
) > 0)
474 ltime
= g_slist_append(ltime
, g_slist_nth_data(list_out
, 0));
475 for(iter
=g_slist_nth(list_out
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
476 /* Find all time requests with the lowest start time in list_out */
477 guint index_ltime
= g_array_index(ltime
, guint
, 0);
478 EventsRequest
*event_request_ltime
= (EventsRequest
*)g_slist_nth_data(ltime
, 0);
479 EventsRequest
*event_request_list_out
= (EventsRequest
*)iter
->data
;
482 comp
= ltt_time_compare(event_request_ltime
->start_time
,
483 event_request_list_out
->start_time
);
485 ltime
= g_slist_append(ltime
, event_request_list_out
);
487 /* Remove all elements from ltime, and add current */
489 ltime
= g_slist_delete_link(ltime
, g_slist_nth(ltime
, 0));
490 ltime
= g_slist_append(ltime
, event_request_list_out
);
494 /* 1.1.2 Find all position requests with the lowest position in list_out
497 if(g_slist_length(list_out
) > 0)
498 lpos
= g_slist_append(lpos
, g_slist_nth_data(list_out
, 0));
499 for(iter
=g_slist_nth(list_out
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
500 /* Find all position requests with the lowest position in list_out */
501 guint index_lpos
= g_array_index(lpos
, guint
, 0);
502 EventsRequest
*event_request_lpos
= (EventsRequest
*)g_slist_nth_data(lpos
, 0);
503 EventsRequest
*event_request_list_out
= (EventsRequest
*)iter
->data
;
506 if(event_request_lpos
->start_position
!= NULL
507 && event_request_list_out
->start_position
!= NULL
)
509 comp
= lttv_traceset_context_pos_pos_compare
510 (event_request_lpos
->start_position
,
511 event_request_list_out
->start_position
);
516 lpos
= g_slist_append(lpos
, event_request_list_out
);
518 /* Remove all elements from lpos, and add current */
520 lpos
= g_slist_delete_link(lpos
, g_slist_nth(lpos
, 0));
521 lpos
= g_slist_append(lpos
, event_request_list_out
);
525 /* 1.1.3 If lpos.start time < ltime */
527 EventsRequest
*event_request_lpos
= (EventsRequest
*)g_slist_nth_data(lpos
, 0);
528 EventsRequest
*event_request_ltime
= (EventsRequest
*)g_slist_nth_data(ltime
, 0);
529 LttTime lpos_start_time
;
531 if(event_request_lpos
!= NULL
532 && event_request_lpos
->start_position
!= NULL
) {
534 lpos_start_time
= lttv_traceset_context_position_get_time(
535 event_request_lpos
->start_position
);
536 if(ltt_time_compare(lpos_start_time
,
537 event_request_ltime
->start_time
)<0) {
538 /* Add lpos to list_in, remove them from list_out */
540 for(iter
=lpos
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
542 EventsRequest
*event_request_lpos
=
543 (EventsRequest
*)iter
->data
;
545 g_slist_append(list_in
, event_request_lpos
);
546 /* Remove from list_out */
547 g_slist_remove(list_out
, event_request_lpos
);
551 /* 1.1.4 (lpos.start time >= ltime) */
552 /* Add ltime to list_in, remove them from list_out */
554 for(iter
=ltime
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
556 EventsRequest
*event_request_ltime
=
557 (EventsRequest
*)iter
->data
;
559 g_slist_append(list_in
, event_request_ltime
);
560 /* Remove from list_out */
561 g_slist_remove(list_out
, event_request_ltime
);
571 tfc
= lttv_traceset_context_get_current_tfc(tsc
);
572 g_assert(g_slist_length(list_in
)>0);
573 EventsRequest
*events_request
= g_slist_nth_data(list_in
, 0);
575 /* 1.2.1 If first request in list_in is a time request */
576 if(events_request
->start_position
== NULL
) {
577 /* - If first req in list_in start time != current time */
578 if(tfc
!= NULL
&& ltt_time_compare(events_request
->start_time
,
579 tfc
->timestamp
) != 0)
580 /* - Seek to that time */
581 lttv_process_traceset_seek_time(tsc
, events_request
->start_time
);
583 /* Else, the first request in list_in is a position request */
584 /* If first req in list_in pos != current pos */
585 g_assert(events_request
->start_position
!= NULL
);
586 if(lttv_traceset_context_ctx_pos_compare(tsc
,
587 events_request
->start_position
) != 0) {
588 /* 1.2.2.1 Seek to that position */
589 lttv_process_traceset_seek_position(tsc
, events_request
->start_position
);
594 /* 1.3 Add hooks and call before request for all list_in members */
598 for(iter
=list_in
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
599 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
600 /* 1.3.1 If !servicing */
601 if(events_request
->servicing
== FALSE
) {
602 /* - begin request hooks called
605 lttv_hooks_call(events_request
->before_request
, NULL
);
606 events_request
->servicing
= TRUE
;
608 /* 1.3.2 call before chunk
609 * 1.3.3 events hooks added
611 lttv_process_traceset_begin(tsc
, events_request
->before_chunk_traceset
,
612 events_request
->before_chunk_trace
,
613 events_request
->before_chunk_tracefile
,
614 events_request
->event
,
615 events_request
->event_by_id
);
619 /* 2. Else, list_in is not empty, we continue a read */
621 tfc
= lttv_traceset_context_get_current_tfc(tsc
);
623 /* 2.1 For each req of list_out */
624 for(iter
=list_out
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
625 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
627 /* if req.start time == current context time
628 * or req.start position == current position*/
629 if( ltt_time_compare(events_request
->start_time
,
632 (events_request
->start_position
!= NULL
634 lttv_traceset_context_ctx_pos_compare(tsc
,
635 events_request
->start_position
) == 0)
637 /* - Add to list_in, remove from list_out */
638 g_slist_append(list_in
, events_request
);
639 g_slist_remove(list_out
, events_request
);
641 /* - If !servicing */
642 if(events_request
->servicing
== FALSE
) {
643 /* - begin request hooks called
646 lttv_hooks_call(events_request
->before_request
, NULL
);
647 events_request
->servicing
= TRUE
;
652 lttv_process_traceset_begin(tsc
, events_request
->before_chunk_traceset
,
653 events_request
->before_chunk_trace
,
654 events_request
->before_chunk_tracefile
,
655 events_request
->event
,
656 events_request
->event_by_id
);
661 /* 3. Find end criterions */
666 /* 3.1.1 Find lowest end time in list_in */
667 g_assert(g_slist_length(list_in
)>0);
668 end_time
= ((EventsRequest
*)g_slist_nth_data(list_in
,0))->end_time
;
670 for(iter
=g_slist_nth(list_in
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
671 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
673 if(ltt_time_compare(events_request
->end_time
,
675 end_time
= events_request
->end_time
;
678 /* 3.1.2 Find lowest start time in list_out */
679 for(iter
=list_out
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
680 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
682 if(ltt_time_compare(events_request
->start_time
,
684 end_time
= events_request
->start_time
;
689 /* 3.2 Number of events */
691 /* 3.2.1 Find lowest number of events in list_in */
694 end_nb_events
= ((EventsRequest
*)g_slist_nth_data(list_in
,0))->num_events
;
696 for(iter
=g_slist_nth(list_in
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
697 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
699 if(events_request
->num_events
< end_nb_events
)
700 end_nb_events
= events_request
->num_events
;
703 /* 3.2.2 Use min(CHUNK_NUM_EVENTS, min num events in list_in) as
706 end_nb_events
= MIN(CHUNK_NUM_EVENTS
, end_nb_events
);
710 /* 3.3 End position */
712 /* 3.3.1 Find lowest end position in list_in */
715 end_position
=((EventsRequest
*)g_slist_nth_data(list_in
,0))->end_position
;
717 for(iter
=g_slist_nth(list_in
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
718 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
720 if(events_request
->end_position
!= NULL
&& end_position
!= NULL
&&
721 lttv_traceset_context_pos_pos_compare(events_request
->end_position
,
723 end_position
= events_request
->end_position
;
728 /* 3.3.2 Find lowest start position in list_out */
731 for(iter
=list_out
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
732 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
734 if(events_request
->end_position
!= NULL
&& end_position
!= NULL
&&
735 lttv_traceset_context_pos_pos_compare(events_request
->end_position
,
737 end_position
= events_request
->end_position
;
742 /* 4. Call process traceset middle */
743 count
= lttv_process_traceset_middle(tsc
, end_time
, end_nb_events
, end_position
);
746 /* 5. After process traceset middle */
747 tfc
= lttv_traceset_context_get_current_tfc(tsc
);
749 /* - if current context time > traceset.end time */
750 if(tfc
== NULL
|| ltt_time_compare(tfc
->timestamp
,
751 tsc
->time_span
.end_time
) > 0) {
752 /* - For each req in list_in */
753 GSList
*iter
= list_in
;
755 while(iter
!= NULL
) {
757 gboolean remove
= FALSE
;
758 gboolean free_data
= FALSE
;
759 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
761 /* - Remove events hooks for req
762 * - Call end chunk for req
764 lttv_process_traceset_end(tsc
, events_request
->after_chunk_traceset
,
765 events_request
->after_chunk_trace
,
766 events_request
->after_chunk_tracefile
,
767 events_request
->event
,
768 events_request
->event_by_id
);
769 /* - Call end request for req */
770 lttv_hooks_call(events_request
->after_request
, NULL
);
772 /* - remove req from list_in */
773 /* Destroy the request */
780 GSList
*remove_iter
= iter
;
782 iter
= g_slist_next(iter
);
783 if(free_data
) g_free(remove_iter
->data
);
784 list_in
= g_slist_remove_link(list_in
, remove_iter
);
785 } else { // not remove
786 iter
= g_slist_next(iter
);
792 /* 5.1 For each req in list_in */
793 GSList
*iter
= list_in
;
795 while(iter
!= NULL
) {
797 gboolean remove
= FALSE
;
798 gboolean free_data
= FALSE
;
799 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
801 /* - Remove events hooks for req
802 * - Call end chunk for req
804 lttv_process_traceset_end(tsc
, events_request
->after_chunk_traceset
,
805 events_request
->after_chunk_trace
,
806 events_request
->after_chunk_tracefile
,
807 events_request
->event
,
808 events_request
->event_by_id
);
810 /* - req.num -= count */
811 g_assert(events_request
->num_events
>= count
);
812 events_request
->num_events
-= count
;
814 g_assert(tfc
!= NULL
);
817 * current context time > req.end time
819 * req.end pos == current pos
821 * req.stop_flag == TRUE
823 if( events_request
->num_events
== 0
825 events_request
->stop_flag
== TRUE
827 ltt_time_compare(tfc
->timestamp
,
828 events_request
->end_time
) > 0
830 (events_request
->start_position
!= NULL
832 lttv_traceset_context_ctx_pos_compare(tsc
,
833 events_request
->start_position
) != 0)
836 /* - Call end request for req
837 * - remove req from list_in */
838 lttv_hooks_call(events_request
->after_request
, NULL
);
839 /* - remove req from list_in */
840 /* Destroy the request */
848 GSList
*remove_iter
= iter
;
850 iter
= g_slist_next(iter
);
851 if(free_data
) g_free(remove_iter
->data
);
852 list_in
= g_slist_remove_link(list_in
, remove_iter
);
853 } else { // not remove
854 iter
= g_slist_next(iter
);
861 /* B. When interrupted between chunks */
864 GSList
*iter
= list_in
;
866 /* 1. for each request in list_in */
867 while(iter
!= NULL
) {
869 gboolean remove
= FALSE
;
870 gboolean free_data
= FALSE
;
871 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
873 /* 1.1. Use current postition as start position */
874 g_free(events_request
->start_position
);
875 lttv_traceset_context_position_save(tsc
, events_request
->start_position
);
877 /* 1.2. Remove start time */
878 events_request
->start_time
.tv_sec
= G_MAXUINT
;
879 events_request
->start_time
.tv_nsec
= G_MAXUINT
;
881 /* 1.3. Move from list_in to list_out */
884 list_out
= g_slist_append(list_out
, events_request
);
889 GSList
*remove_iter
= iter
;
891 iter
= g_slist_next(iter
);
892 if(free_data
) g_free(remove_iter
->data
);
893 list_in
= g_slist_remove_link(list_in
, remove_iter
);
894 } else { // not remove
895 iter
= g_slist_next(iter
);
902 //set the cursor back to normal
903 gdk_window_set_cursor(win
, NULL
);
906 g_assert(g_slist_length(list_in
) == 0);
907 if( g_slist_length(list_out
) == 0 ) {
908 /* Put tab's request pending flag back to normal */
909 tab
->events_request_pending
= FALSE
;
910 return FALSE
; /* Remove the idle function */
912 return TRUE
; /* Leave the idle function */
917 /* add_trace_into_traceset_selector, each instance of a viewer has an associated
918 * selector (filter), when a trace is added into traceset, the selector should
919 * reflect the change. The function is used to update the selector
922 void add_trace_into_traceset_selector(GtkMultiVPaned
* paned
, LttTrace
* t
)
924 int j
, k
, m
, nb_tracefile
, nb_control
, nb_per_cpu
, nb_facility
, nb_event
;
925 LttvTracesetSelector
* s
;
926 LttvTraceSelector
* trace
;
927 LttvTracefileSelector
* tracefile
;
928 LttvEventtypeSelector
* eventtype
;
934 w
= gtk_multi_vpaned_get_first_widget(paned
);
936 s
= g_object_get_data(G_OBJECT(w
), "Traceset_Selector");
939 trace
= lttv_trace_selector_new(t
);
940 lttv_traceset_selector_trace_add(s
, trace
);
942 nb_facility
= ltt_trace_facility_number(t
);
943 for(k
=0;k
<nb_facility
;k
++){
944 fac
= ltt_trace_facility_get(t
,k
);
945 nb_event
= (int) ltt_facility_eventtype_number(fac
);
946 for(m
=0;m
<nb_event
;m
++){
947 et
= ltt_facility_eventtype_get(fac
,m
);
948 eventtype
= lttv_eventtype_selector_new(et
);
949 lttv_trace_selector_eventtype_add(trace
, eventtype
);
953 nb_control
= ltt_trace_control_tracefile_number(t
);
954 nb_per_cpu
= ltt_trace_per_cpu_tracefile_number(t
);
955 nb_tracefile
= nb_control
+ nb_per_cpu
;
957 for(j
= 0 ; j
< nb_tracefile
; j
++) {
959 tf
= ltt_trace_control_tracefile_get(t
, j
);
961 tf
= ltt_trace_per_cpu_tracefile_get(t
, j
- nb_control
);
962 tracefile
= lttv_tracefile_selector_new(tf
);
963 lttv_trace_selector_tracefile_add(trace
, tracefile
);
964 lttv_eventtype_selector_copy(trace
, tracefile
);
966 }else g_warning("Module does not support filtering\n");
968 w
= gtk_multi_vpaned_get_next_widget(paned
);
973 static void lttvwindow_add_trace(Tab
*tab
, LttvTrace
*trace_v
)
975 LttvTraceset
*traceset
= tab
->traceset_info
->traceset
;
978 //Keep a reference to the traces so they are not freed.
979 for(i
=0; i
<lttv_traceset_number(traceset
); i
++)
981 LttvTrace
* trace
= lttv_traceset_get(traceset
, i
);
982 lttv_trace_ref(trace
);
985 //remove state update hooks
986 lttv_state_remove_event_hooks(
987 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
989 lttv_context_fini(LTTV_TRACESET_CONTEXT(
990 tab
->traceset_info
->traceset_context
));
991 g_object_unref(tab
->traceset_info
->traceset_context
);
993 lttv_traceset_add(traceset
, trace_v
);
995 /* Create new context */
996 tab
->traceset_info
->traceset_context
=
997 g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
999 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->
1002 //add state update hooks
1003 lttv_state_add_event_hooks(
1004 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1005 //Remove local reference to the traces.
1006 for(i
=0; i
<lttv_traceset_number(traceset
); i
++)
1008 LttvTrace
* trace
= lttv_traceset_get(traceset
, i
);
1009 lttv_trace_unref(trace
);
1012 add_trace_into_traceset_selector(tab
->multi_vpaned
, lttv_trace(trace_v
));
1015 /* add_trace adds a trace into the current traceset. It first displays a
1016 * directory selection dialogue to let user choose a trace, then recreates
1017 * tracset_context, and redraws all the viewer of the current tab
1020 void add_trace(GtkWidget
* widget
, gpointer user_data
)
1023 LttvTrace
* trace_v
;
1024 LttvTraceset
* traceset
;
1028 MainWindow
* mw_data
= get_window_data_struct(widget
);
1029 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
1031 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
1032 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
1036 tab
= create_new_tab(widget
, NULL
);
1038 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
1041 GtkDirSelection
* file_selector
= (GtkDirSelection
*)gtk_dir_selection_new("Select a trace");
1042 gtk_dir_selection_hide_fileop_buttons(file_selector
);
1044 if(remember_trace_dir
[0] != '\0')
1045 gtk_dir_selection_set_filename(file_selector
, remember_trace_dir
);
1047 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
1049 case GTK_RESPONSE_ACCEPT
:
1050 case GTK_RESPONSE_OK
:
1051 dir
= gtk_dir_selection_get_dir (file_selector
);
1052 strncpy(remember_trace_dir
, dir
, PATH_LENGTH
);
1053 if(!dir
|| strlen(dir
) == 0){
1054 gtk_widget_destroy((GtkWidget
*)file_selector
);
1057 trace
= ltt_trace_open(dir
);
1058 if(trace
== NULL
) g_critical("cannot open trace %s", dir
);
1059 trace_v
= lttv_trace_new(trace
);
1061 lttvwindow_add_trace(tab
, trace_v
);
1063 gtk_widget_destroy((GtkWidget
*)file_selector
);
1065 //update current tab
1066 //update_traceset(mw_data);
1068 /* Call the updatetraceset hooks */
1070 traceset
= tab
->traceset_info
->traceset
;
1071 SetTraceset(tab
, traceset
);
1072 // in expose now call_pending_read_hooks(mw_data);
1074 //lttvwindow_report_current_time(mw_data,&(tab->current_time));
1076 case GTK_RESPONSE_REJECT
:
1077 case GTK_RESPONSE_CANCEL
:
1079 gtk_widget_destroy((GtkWidget
*)file_selector
);
1085 /* remove_trace_into_traceset_selector, each instance of a viewer has an associated
1086 * selector (filter), when a trace is remove from traceset, the selector should
1087 * reflect the change. The function is used to update the selector
1090 void remove_trace_from_traceset_selector(GtkMultiVPaned
* paned
, unsigned i
)
1092 LttvTracesetSelector
* s
;
1093 LttvTraceSelector
* t
;
1096 w
= gtk_multi_vpaned_get_first_widget(paned
);
1098 s
= g_object_get_data(G_OBJECT(w
), "Traceset_Selector");
1100 t
= lttv_traceset_selector_trace_get(s
,i
);
1101 lttv_traceset_selector_trace_remove(s
, i
);
1102 lttv_trace_selector_destroy(t
);
1103 }g_warning("Module dose not support filtering\n");
1104 w
= gtk_multi_vpaned_get_next_widget(paned
);
1109 /* remove_trace removes a trace from the current traceset if all viewers in
1110 * the current tab are not interested in the trace. It first displays a
1111 * dialogue, which shows all traces in the current traceset, to let user choose
1112 * a trace, then it checks if all viewers unselect the trace, if it is true,
1113 * it will remove the trace, recreate the traceset_contex,
1114 * and redraws all the viewer of the current tab. If there is on trace in the
1115 * current traceset, it will delete all viewers of the current tab
1118 void remove_trace(GtkWidget
* widget
, gpointer user_data
)
1121 LttvTrace
* trace_v
;
1122 LttvTraceset
* traceset
;
1123 gint i
, j
, nb_trace
;
1124 char ** name
, *remove_trace_name
;
1125 MainWindow
* mw_data
= get_window_data_struct(widget
);
1126 LttvTracesetSelector
* s
;
1127 LttvTraceSelector
* t
;
1130 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
1132 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
1133 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
1139 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
1142 nb_trace
=lttv_traceset_number(tab
->traceset_info
->traceset
);
1143 name
= g_new(char*,nb_trace
);
1144 for(i
= 0; i
< nb_trace
; i
++){
1145 trace_v
= lttv_traceset_get(tab
->traceset_info
->traceset
, i
);
1146 trace
= lttv_trace(trace_v
);
1147 name
[i
] = ltt_trace_name(trace
);
1150 remove_trace_name
= get_remove_trace(name
, nb_trace
);
1152 if(remove_trace_name
){
1153 for(i
=0; i
<nb_trace
; i
++){
1154 if(strcmp(remove_trace_name
,name
[i
]) == 0){
1155 //unselect the trace from the current viewer
1156 w
= gtk_multi_vpaned_get_widget(tab
->multi_vpaned
);
1158 s
= g_object_get_data(G_OBJECT(w
), "Traceset_Selector");
1160 t
= lttv_traceset_selector_trace_get(s
,i
);
1161 lttv_trace_selector_set_selected(t
, FALSE
);
1164 //check if other viewers select the trace
1165 w
= gtk_multi_vpaned_get_first_widget(tab
->multi_vpaned
);
1167 s
= g_object_get_data(G_OBJECT(w
), "Traceset_Selector");
1169 t
= lttv_traceset_selector_trace_get(s
,i
);
1170 selected
= lttv_trace_selector_get_selected(t
);
1173 w
= gtk_multi_vpaned_get_next_widget(tab
->multi_vpaned
);
1175 }else selected
= FALSE
;
1177 //if no viewer selects the trace, remove it
1179 remove_trace_from_traceset_selector(tab
->multi_vpaned
, i
);
1181 traceset
= tab
->traceset_info
->traceset
;
1182 //Keep a reference to the traces so they are not freed.
1183 for(j
=0; j
<lttv_traceset_number(traceset
); j
++)
1185 LttvTrace
* trace
= lttv_traceset_get(traceset
, j
);
1186 lttv_trace_ref(trace
);
1189 //remove state update hooks
1190 lttv_state_remove_event_hooks(
1191 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1192 lttv_context_fini(LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
));
1193 g_object_unref(tab
->traceset_info
->traceset_context
);
1196 trace_v
= lttv_traceset_get(traceset
, i
);
1198 if(lttv_trace_get_ref_number(trace_v
) <= 1)
1199 ltt_trace_close(lttv_trace(trace_v
));
1201 lttv_traceset_remove(traceset
, i
);
1202 lttv_trace_unref(trace_v
); // Remove local reference
1204 if(!lttv_trace_get_ref_number(trace_v
))
1205 lttv_trace_destroy(trace_v
);
1207 tab
->traceset_info
->traceset_context
=
1208 g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
1210 LTTV_TRACESET_CONTEXT(tab
->
1211 traceset_info
->traceset_context
),traceset
);
1212 //add state update hooks
1213 lttv_state_add_event_hooks(
1214 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1216 //Remove local reference to the traces.
1217 for(j
=0; j
<lttv_traceset_number(traceset
); j
++)
1219 LttvTrace
* trace
= lttv_traceset_get(traceset
, j
);
1220 lttv_trace_unref(trace
);
1224 //update current tab
1225 //update_traceset(mw_data);
1228 SetTraceset(mw_data
, (gpointer
)traceset
);
1229 // in expose now call_pending_read_hooks(mw_data);
1231 //lttvwindow_report_current_time(mw_data,&(tab->current_time));
1234 while(tab
->multi_vpaned
->num_children
){
1235 gtk_multi_vpaned_widget_delete(tab
->multi_vpaned
);
1249 /* save will save the traceset to a file
1250 * Not implemented yet FIXME
1253 void save(GtkWidget
* widget
, gpointer user_data
)
1258 void save_as(GtkWidget
* widget
, gpointer user_data
)
1260 g_printf("Save as\n");
1264 /* zoom will change the time_window of all the viewers of the
1265 * current tab, and redisplay them. The main functionality is to
1266 * determine the new time_window of the current tab
1269 void zoom(GtkWidget
* widget
, double size
)
1271 TimeInterval
*time_span
;
1272 TimeWindow new_time_window
;
1273 LttTime current_time
, time_delta
, time_s
, time_e
, time_tmp
;
1274 MainWindow
* mw_data
= get_window_data_struct(widget
);
1275 LttvTracesetContext
*tsc
;
1276 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
1278 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
1279 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
1285 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
1288 if(size
== 1) return;
1290 tsc
= LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
1291 time_span
= &tsc
->time_span
;
1292 new_time_window
= tab
->time_window
;
1293 current_time
= tab
->current_time
;
1295 time_delta
= ltt_time_sub(time_span
->end_time
,time_span
->start_time
);
1297 new_time_window
.start_time
= time_span
->start_time
;
1298 new_time_window
.time_width
= time_delta
;
1300 new_time_window
.time_width
= ltt_time_div(new_time_window
.time_width
, size
);
1301 if(ltt_time_compare(new_time_window
.time_width
,time_delta
) > 0)
1302 { /* Case where zoom out is bigger than trace length */
1303 new_time_window
.start_time
= time_span
->start_time
;
1304 new_time_window
.time_width
= time_delta
;
1308 /* Center the image on the current time */
1309 g_critical("update is HERE");
1310 new_time_window
.start_time
=
1311 ltt_time_sub(current_time
, ltt_time_div(new_time_window
.time_width
, 2.0));
1312 /* If on borders, don't fall off */
1313 if(ltt_time_compare(new_time_window
.start_time
, time_span
->start_time
) <0)
1315 new_time_window
.start_time
= time_span
->start_time
;
1319 if(ltt_time_compare(
1320 ltt_time_add(new_time_window
.start_time
, new_time_window
.time_width
),
1321 time_span
->end_time
) > 0)
1323 new_time_window
.start_time
=
1324 ltt_time_sub(time_span
->end_time
, new_time_window
.time_width
);
1332 //time_tmp = ltt_time_div(new_time_window.time_width, 2);
1333 //if(ltt_time_compare(current_time, time_tmp) < 0){
1334 // time_s = time_span->startTime;
1336 // time_s = ltt_time_sub(current_time,time_tmp);
1338 //time_e = ltt_time_add(current_time,time_tmp);
1339 //if(ltt_time_compare(time_span->startTime, time_s) > 0){
1340 // time_s = time_span->startTime;
1341 //}else if(ltt_time_compare(time_span->endTime, time_e) < 0){
1342 // time_e = time_span->endTime;
1343 // time_s = ltt_time_sub(time_e,new_time_window.time_width);
1345 //new_time_window.start_time = time_s;
1348 //lttvwindow_report_time_window(mw_data, &new_time_window);
1349 //call_pending_read_hooks(mw_data);
1351 //lttvwindow_report_current_time(mw_data,&(tab->current_time));
1352 set_time_window(tab
, &new_time_window
);
1353 // in expose now call_pending_read_hooks(mw_data);
1354 gtk_multi_vpaned_set_adjust(tab
->multi_vpaned
, &new_time_window
, FALSE
);
1357 void zoom_in(GtkWidget
* widget
, gpointer user_data
)
1362 void zoom_out(GtkWidget
* widget
, gpointer user_data
)
1367 void zoom_extended(GtkWidget
* widget
, gpointer user_data
)
1372 void go_to_time(GtkWidget
* widget
, gpointer user_data
)
1374 g_printf("Go to time\n");
1377 void show_time_frame(GtkWidget
* widget
, gpointer user_data
)
1379 g_printf("Show time frame\n");
1383 /* callback function */
1386 on_empty_traceset_activate (GtkMenuItem
*menuitem
,
1389 create_new_window((GtkWidget
*)menuitem
, user_data
, FALSE
);
1394 on_clone_traceset_activate (GtkMenuItem
*menuitem
,
1397 create_new_window((GtkWidget
*)menuitem
, user_data
, TRUE
);
1401 /* create_new_tab calls create_tab to construct a new tab in the main window
1404 Tab
*create_new_tab(GtkWidget
* widget
, gpointer user_data
){
1405 gchar label
[PATH_LENGTH
];
1406 MainWindow
* mw_data
= get_window_data_struct(widget
);
1408 GtkNotebook
* notebook
= (GtkNotebook
*)lookup_widget(widget
, "MNotebook");
1409 if(notebook
== NULL
){
1410 g_printf("Notebook does not exist\n");
1413 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
1414 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
1420 copy_tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
1423 strcpy(label
,"Page");
1424 if(get_label(mw_data
, label
,"Get the name of the tab","Please input tab's name"))
1425 return (create_tab (mw_data
, copy_tab
, notebook
, label
));
1429 on_tab_activate (GtkMenuItem
*menuitem
,
1432 create_new_tab((GtkWidget
*)menuitem
, user_data
);
1437 on_open_activate (GtkMenuItem
*menuitem
,
1440 open_traceset((GtkWidget
*)menuitem
, user_data
);
1445 on_close_activate (GtkMenuItem
*menuitem
,
1448 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
1449 main_window_destructor(mw_data
);
1453 /* remove the current tab from the main window
1457 on_close_tab_activate (GtkMenuItem
*menuitem
,
1461 GtkWidget
* notebook
;
1463 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
1464 notebook
= lookup_widget((GtkWidget
*)menuitem
, "MNotebook");
1465 if(notebook
== NULL
){
1466 g_printf("Notebook does not exist\n");
1470 page_num
= gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
));
1472 gtk_notebook_remove_page(GTK_NOTEBOOK(notebook
), page_num
);
1478 on_add_trace_activate (GtkMenuItem
*menuitem
,
1481 add_trace((GtkWidget
*)menuitem
, user_data
);
1486 on_remove_trace_activate (GtkMenuItem
*menuitem
,
1489 remove_trace((GtkWidget
*)menuitem
, user_data
);
1494 on_save_activate (GtkMenuItem
*menuitem
,
1497 save((GtkWidget
*)menuitem
, user_data
);
1502 on_save_as_activate (GtkMenuItem
*menuitem
,
1505 save_as((GtkWidget
*)menuitem
, user_data
);
1510 on_quit_activate (GtkMenuItem
*menuitem
,
1518 on_cut_activate (GtkMenuItem
*menuitem
,
1526 on_copy_activate (GtkMenuItem
*menuitem
,
1529 g_printf("Copye\n");
1534 on_paste_activate (GtkMenuItem
*menuitem
,
1537 g_printf("Paste\n");
1542 on_delete_activate (GtkMenuItem
*menuitem
,
1545 g_printf("Delete\n");
1550 on_zoom_in_activate (GtkMenuItem
*menuitem
,
1553 zoom_in((GtkWidget
*)menuitem
, user_data
);
1558 on_zoom_out_activate (GtkMenuItem
*menuitem
,
1561 zoom_out((GtkWidget
*)menuitem
, user_data
);
1566 on_zoom_extended_activate (GtkMenuItem
*menuitem
,
1569 zoom_extended((GtkWidget
*)menuitem
, user_data
);
1574 on_go_to_time_activate (GtkMenuItem
*menuitem
,
1577 go_to_time((GtkWidget
*)menuitem
, user_data
);
1582 on_show_time_frame_activate (GtkMenuItem
*menuitem
,
1585 show_time_frame((GtkWidget
*)menuitem
, user_data
);
1590 on_move_viewer_up_activate (GtkMenuItem
*menuitem
,
1593 move_up_viewer((GtkWidget
*)menuitem
, user_data
);
1598 on_move_viewer_down_activate (GtkMenuItem
*menuitem
,
1601 move_down_viewer((GtkWidget
*)menuitem
, user_data
);
1606 on_remove_viewer_activate (GtkMenuItem
*menuitem
,
1609 delete_viewer((GtkWidget
*)menuitem
, user_data
);
1613 on_trace_filter_activate (GtkMenuItem
*menuitem
,
1616 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
1617 LttvTracesetSelector
* s
;
1619 GtkWidget
* notebook
= lookup_widget(GTK_WIDGET(menuitem
), "MNotebook");
1621 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
1622 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
1628 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
1631 w
= gtk_multi_vpaned_get_widget(tab
->multi_vpaned
);
1633 s
= g_object_get_data(G_OBJECT(w
), "Traceset_Selector");
1635 g_printf("There is no viewer yet\n");
1638 if(get_filter_selection(s
, "Configure trace and tracefile filter", "Select traces and tracefiles")){
1639 //FIXME report filter change
1640 //update_traceset(mw_data);
1641 //call_pending_read_hooks(mw_data);
1642 //lttvwindow_report_current_time(mw_data,&(tab->current_time));
1647 on_trace_facility_activate (GtkMenuItem
*menuitem
,
1650 g_printf("Trace facility selector: %s\n");
1654 /* Dispaly a file selection dialogue to let user select a module, then call
1655 * lttv_module_load(), finally insert tool button and menu entry in the main window
1656 * for the loaded module
1660 on_load_module_activate (GtkMenuItem
*menuitem
,
1665 char str
[PATH_LENGTH
], *str1
;
1666 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
1667 GtkFileSelection
* file_selector
= (GtkFileSelection
*)gtk_file_selection_new("Select a module");
1668 if(remember_plugins_dir
[0] != '\0')
1669 gtk_file_selection_set_filename(file_selector
, remember_plugins_dir
);
1670 gtk_file_selection_hide_fileop_buttons(file_selector
);
1673 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
1675 case GTK_RESPONSE_ACCEPT
:
1676 case GTK_RESPONSE_OK
:
1677 dir
= gtk_file_selection_get_selections (file_selector
);
1678 strncpy(str
,dir
[0],PATH_LENGTH
);
1679 strncpy(remember_plugins_dir
,dir
[0],PATH_LENGTH
);
1680 str1
= strrchr(str
,'/');
1683 str1
= strrchr(str
,'\\');
1686 lttv_module_require(str1
, NULL
);
1688 case GTK_RESPONSE_REJECT
:
1689 case GTK_RESPONSE_CANCEL
:
1691 gtk_widget_destroy((GtkWidget
*)file_selector
);
1694 g_printf("Load module: %s\n", str
);
1698 /* Display all loaded modules, let user to select a module to unload
1699 * by calling lttv_module_unload
1703 on_unload_module_activate (GtkMenuItem
*menuitem
,
1708 char *unload_module_name
;
1710 LttvLibrary
*library
;
1711 LttvLibraryInfo library_info
;
1712 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
1714 name
= g_ptr_array_new();
1715 nb
= lttv_library_number();
1718 library
= lttv_library_get(i
);
1719 lttv_library_info(library
, &library_info
);
1720 if(library_info
.load_count
> 0) g_ptr_array_add(name
, library_info
.name
);
1723 unload_module_name
=get_unload_module((char **)(name
->pdata
), name
->len
);
1725 if(unload_module_name
){
1727 library
= lttv_library_get(i
);
1728 lttv_library_info(library
, &library_info
);
1729 if(strcmp(unload_module_name
, library_info
.name
) == 0){
1730 lttv_library_unload(library
);
1736 g_ptr_array_free(name
, TRUE
);
1740 /* Display a directory dialogue to let user select a path for module searching
1744 on_add_module_search_path_activate (GtkMenuItem
*menuitem
,
1747 GtkDirSelection
* file_selector
= (GtkDirSelection
*)gtk_dir_selection_new("Select module path");
1751 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
1752 if(remember_plugins_dir
[0] != '\0')
1753 gtk_dir_selection_set_filename(file_selector
, remember_plugins_dir
);
1755 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
1757 case GTK_RESPONSE_ACCEPT
:
1758 case GTK_RESPONSE_OK
:
1759 dir
= gtk_dir_selection_get_dir (file_selector
);
1760 strncpy(remember_plugins_dir
,dir
,PATH_LENGTH
);
1761 strncat(remember_plugins_dir
,"/",PATH_LENGTH
);
1762 lttv_library_path_add(dir
);
1763 case GTK_RESPONSE_REJECT
:
1764 case GTK_RESPONSE_CANCEL
:
1766 gtk_widget_destroy((GtkWidget
*)file_selector
);
1773 on_color_activate (GtkMenuItem
*menuitem
,
1776 g_printf("Color\n");
1781 on_filter_activate (GtkMenuItem
*menuitem
,
1784 g_printf("Filter\n");
1789 on_save_configuration_activate (GtkMenuItem
*menuitem
,
1792 g_printf("Save configuration\n");
1797 on_content_activate (GtkMenuItem
*menuitem
,
1800 g_printf("Content\n");
1805 on_about_activate (GtkMenuItem
*menuitem
,
1808 g_printf("About...\n");
1813 on_button_new_clicked (GtkButton
*button
,
1816 create_new_window((GtkWidget
*)button
, user_data
, TRUE
);
1820 on_button_new_tab_clicked (GtkButton
*button
,
1823 create_new_tab((GtkWidget
*)button
, user_data
);
1827 on_button_open_clicked (GtkButton
*button
,
1830 open_traceset((GtkWidget
*)button
, user_data
);
1835 on_button_add_trace_clicked (GtkButton
*button
,
1838 add_trace((GtkWidget
*)button
, user_data
);
1843 on_button_remove_trace_clicked (GtkButton
*button
,
1846 remove_trace((GtkWidget
*)button
, user_data
);
1851 on_button_save_clicked (GtkButton
*button
,
1854 save((GtkWidget
*)button
, user_data
);
1859 on_button_save_as_clicked (GtkButton
*button
,
1862 save_as((GtkWidget
*)button
, user_data
);
1867 on_button_zoom_in_clicked (GtkButton
*button
,
1870 zoom_in((GtkWidget
*)button
, user_data
);
1875 on_button_zoom_out_clicked (GtkButton
*button
,
1878 zoom_out((GtkWidget
*)button
, user_data
);
1883 on_button_zoom_extended_clicked (GtkButton
*button
,
1886 zoom_extended((GtkWidget
*)button
, user_data
);
1891 on_button_go_to_time_clicked (GtkButton
*button
,
1894 go_to_time((GtkWidget
*)button
, user_data
);
1899 on_button_show_time_frame_clicked (GtkButton
*button
,
1902 show_time_frame((GtkWidget
*)button
, user_data
);
1907 on_button_move_up_clicked (GtkButton
*button
,
1910 move_up_viewer((GtkWidget
*)button
, user_data
);
1915 on_button_move_down_clicked (GtkButton
*button
,
1918 move_down_viewer((GtkWidget
*)button
, user_data
);
1923 on_button_delete_viewer_clicked (GtkButton
*button
,
1926 delete_viewer((GtkWidget
*)button
, user_data
);
1930 on_MWindow_destroy (GtkWidget
*widget
,
1933 MainWindow
*main_window
= get_window_data_struct(widget
);
1934 LttvIAttribute
*attributes
= main_window
->attributes
;
1935 LttvAttributeValue value
;
1937 //This is unnecessary, since widgets will be destroyed
1938 //by the main window widget anyway.
1939 //remove_all_menu_toolbar_constructors(main_window, NULL);
1941 g_assert(lttv_iattribute_find_by_path(attributes
,
1942 "viewers/menu", LTTV_POINTER
, &value
));
1943 lttv_menus_destroy((LttvMenus
*)*(value
.v_pointer
));
1945 g_assert(lttv_iattribute_find_by_path(attributes
,
1946 "viewers/toolbar", LTTV_POINTER
, &value
));
1947 lttv_toolbars_destroy((LttvToolbars
*)*(value
.v_pointer
));
1949 g_object_unref(main_window
->attributes
);
1950 g_main_window_list
= g_slist_remove(g_main_window_list
, main_window
);
1952 g_printf("There are now : %d windows\n",g_slist_length(g_main_window_list
));
1953 if(g_slist_length(g_main_window_list
) == 0)
1958 on_MWindow_configure (GtkWidget
*widget
,
1959 GdkEventConfigure
*event
,
1962 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)widget
);
1963 float width
= event
->width
;
1964 TimeWindow time_win
;
1966 TimeInterval
*time_span
;
1969 // MD : removed time width modification upon resizing of the main window.
1970 // The viewers will redraw themselves completely, without time interval
1973 if(mw_data->window_width){
1974 time_span = LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context)->Time_Span ;
1975 time_win = tab->time_window;
1976 ratio = width / mw_data->window_width;
1977 tab->time_window.time_width = ltt_time_mul(time_win.time_width,ratio);
1978 time = ltt_time_sub(time_span->endTime, time_win.start_time);
1979 if(ltt_time_compare(time, tab->time_window.time_width) < 0){
1980 tab->time_window.time_width = time;
1986 mw_data->window_width = (int)width;
1995 on_MNotebook_switch_page (GtkNotebook
*notebook
,
1996 GtkNotebookPage
*page
,
2004 /* callback function to check or uncheck the check box (filter)
2007 void checkbox_changed(GtkTreeView
*treeview
,
2009 GtkTreeViewColumn
*arg2
,
2012 GtkTreeStore
* store
= (GtkTreeStore
*)gtk_tree_view_get_model (treeview
);
2016 if (gtk_tree_model_get_iter ((GtkTreeModel
*)store
, &iter
, arg1
)){
2017 gtk_tree_model_get ((GtkTreeModel
*)store
, &iter
, CHECKBOX_COLUMN
, &value
, -1);
2018 value
= value
? FALSE
: TRUE
;
2019 gtk_tree_store_set (GTK_TREE_STORE (store
), &iter
, CHECKBOX_COLUMN
, value
, -1);
2025 /* According to user's selection, update selector(filter)
2028 void update_filter(LttvTracesetSelector
*s
, GtkTreeStore
*store
)
2030 GtkTreeIter iter
, child_iter
, child_iter1
, child_iter2
;
2031 int i
, j
, k
, nb_eventtype
;
2032 LttvTraceSelector
* trace
;
2033 LttvTracefileSelector
* tracefile
;
2034 LttvEventtypeSelector
* eventtype
;
2035 gboolean value
, value1
, value2
;
2037 if(gtk_tree_model_get_iter_first((GtkTreeModel
*)store
, &iter
)){
2040 trace
= lttv_traceset_selector_trace_get(s
, i
);
2041 nb_eventtype
= lttv_trace_selector_eventtype_number(trace
);
2042 gtk_tree_model_get ((GtkTreeModel
*)store
, &iter
, CHECKBOX_COLUMN
, &value
,-1);
2045 if(gtk_tree_model_iter_children ((GtkTreeModel
*)store
, &child_iter
, &iter
)){
2047 if(j
<1){//eventtype selector for trace
2048 gtk_tree_model_get ((GtkTreeModel
*)store
, &child_iter
, CHECKBOX_COLUMN
, &value2
,-1);
2051 if(gtk_tree_model_iter_children ((GtkTreeModel
*)store
, &child_iter1
, &child_iter
)){
2053 eventtype
= lttv_trace_selector_eventtype_get(trace
,k
);
2054 gtk_tree_model_get ((GtkTreeModel
*)store
, &child_iter1
, CHECKBOX_COLUMN
, &value2
,-1);
2055 lttv_eventtype_selector_set_selected(eventtype
,value2
);
2057 }while(gtk_tree_model_iter_next((GtkTreeModel
*)store
, &child_iter1
));
2060 }else{ //tracefile selector
2061 tracefile
= lttv_trace_selector_tracefile_get(trace
, j
- 1);
2062 gtk_tree_model_get ((GtkTreeModel
*)store
, &child_iter
, CHECKBOX_COLUMN
, &value1
,-1);
2063 lttv_tracefile_selector_set_selected(tracefile
,value1
);
2065 gtk_tree_model_iter_children((GtkTreeModel
*)store
, &child_iter1
, &child_iter
); //eventtype selector
2066 gtk_tree_model_get ((GtkTreeModel
*)store
, &child_iter1
, CHECKBOX_COLUMN
, &value2
,-1);
2069 if(gtk_tree_model_iter_children ((GtkTreeModel
*)store
, &child_iter2
, &child_iter1
)){
2070 do{//eventtype selector for tracefile
2071 eventtype
= lttv_tracefile_selector_eventtype_get(tracefile
,k
);
2072 gtk_tree_model_get ((GtkTreeModel
*)store
, &child_iter2
, CHECKBOX_COLUMN
, &value2
,-1);
2073 lttv_eventtype_selector_set_selected(eventtype
,value2
);
2075 }while(gtk_tree_model_iter_next((GtkTreeModel
*)store
, &child_iter2
));
2081 }while(gtk_tree_model_iter_next((GtkTreeModel
*)store
, &child_iter
));
2084 lttv_trace_selector_set_selected(trace
,value
);
2086 }while(gtk_tree_model_iter_next((GtkTreeModel
*)store
, &iter
));
2091 /* Display a dialogue showing all eventtypes and traces, let user to select the interested
2092 * eventtypes, tracefiles and traces (filter)
2095 gboolean
get_filter_selection(LttvTracesetSelector
*s
,char *title
, char * column_title
)
2097 GtkWidget
* dialogue
;
2098 GtkTreeStore
* store
;
2100 GtkWidget
* scroll_win
;
2101 GtkCellRenderer
* renderer
;
2102 GtkTreeViewColumn
* column
;
2103 GtkTreeIter iter
, child_iter
, child_iter1
, child_iter2
;
2104 int i
, j
, k
, id
, nb_trace
, nb_tracefile
, nb_eventtype
;
2105 LttvTraceSelector
* trace
;
2106 LttvTracefileSelector
* tracefile
;
2107 LttvEventtypeSelector
* eventtype
;
2111 dialogue
= gtk_dialog_new_with_buttons(title
,
2114 GTK_STOCK_OK
,GTK_RESPONSE_ACCEPT
,
2115 GTK_STOCK_CANCEL
,GTK_RESPONSE_REJECT
,
2117 gtk_window_set_default_size((GtkWindow
*)dialogue
, 300, 500);
2119 store
= gtk_tree_store_new (TOTAL_COLUMNS
, G_TYPE_BOOLEAN
, G_TYPE_STRING
);
2120 tree
= gtk_tree_view_new_with_model (GTK_TREE_MODEL (store
));
2121 g_object_unref (G_OBJECT (store
));
2122 g_signal_connect (G_OBJECT (tree
), "row-activated",
2123 G_CALLBACK (checkbox_changed
),
2127 renderer
= gtk_cell_renderer_toggle_new ();
2128 gtk_cell_renderer_toggle_set_radio((GtkCellRendererToggle
*)renderer
, FALSE
);
2130 g_object_set (G_OBJECT (renderer
),"activatable", TRUE
, NULL
);
2132 column
= gtk_tree_view_column_new_with_attributes ("Checkbox",
2134 "active", CHECKBOX_COLUMN
,
2136 gtk_tree_view_column_set_alignment (column
, 0.5);
2137 gtk_tree_view_column_set_fixed_width (column
, 20);
2138 gtk_tree_view_append_column (GTK_TREE_VIEW (tree
), column
);
2140 renderer
= gtk_cell_renderer_text_new ();
2141 column
= gtk_tree_view_column_new_with_attributes (column_title
,
2143 "text", NAME_COLUMN
,
2145 gtk_tree_view_column_set_alignment (column
, 0.0);
2146 gtk_tree_view_append_column (GTK_TREE_VIEW (tree
), column
);
2147 gtk_tree_view_set_headers_visible(GTK_TREE_VIEW (tree
), FALSE
);
2149 scroll_win
= gtk_scrolled_window_new (NULL
, NULL
);
2150 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll_win
),
2151 GTK_POLICY_AUTOMATIC
,GTK_POLICY_AUTOMATIC
);
2152 gtk_container_add (GTK_CONTAINER (scroll_win
), tree
);
2154 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialogue
)->vbox
), scroll_win
,TRUE
, TRUE
,0);
2156 gtk_widget_show(scroll_win
);
2157 gtk_widget_show(tree
);
2159 nb_trace
= lttv_traceset_selector_trace_number(s
);
2160 for(i
=0;i
<nb_trace
;i
++){
2161 trace
= lttv_traceset_selector_trace_get(s
, i
);
2162 name
= lttv_trace_selector_get_name(trace
);
2163 gtk_tree_store_append (store
, &iter
, NULL
);
2164 checked
= lttv_trace_selector_get_selected(trace
);
2165 gtk_tree_store_set (store
, &iter
,
2166 CHECKBOX_COLUMN
,checked
,
2170 gtk_tree_store_append (store
, &child_iter
, &iter
);
2171 gtk_tree_store_set (store
, &child_iter
,
2172 CHECKBOX_COLUMN
, checked
,
2173 NAME_COLUMN
,"eventtype",
2176 nb_eventtype
= lttv_trace_selector_eventtype_number(trace
);
2177 for(j
=0;j
<nb_eventtype
;j
++){
2178 eventtype
= lttv_trace_selector_eventtype_get(trace
,j
);
2179 name
= lttv_eventtype_selector_get_name(eventtype
);
2180 checked
= lttv_eventtype_selector_get_selected(eventtype
);
2181 gtk_tree_store_append (store
, &child_iter1
, &child_iter
);
2182 gtk_tree_store_set (store
, &child_iter1
,
2183 CHECKBOX_COLUMN
, checked
,
2188 nb_tracefile
= lttv_trace_selector_tracefile_number(trace
);
2189 for(j
=0;j
<nb_tracefile
;j
++){
2190 tracefile
= lttv_trace_selector_tracefile_get(trace
, j
);
2191 name
= lttv_tracefile_selector_get_name(tracefile
);
2192 gtk_tree_store_append (store
, &child_iter
, &iter
);
2193 checked
= lttv_tracefile_selector_get_selected(tracefile
);
2194 gtk_tree_store_set (store
, &child_iter
,
2195 CHECKBOX_COLUMN
, checked
,
2199 gtk_tree_store_append (store
, &child_iter1
, &child_iter
);
2200 gtk_tree_store_set (store
, &child_iter1
,
2201 CHECKBOX_COLUMN
, checked
,
2202 NAME_COLUMN
,"eventtype",
2205 for(k
=0;k
<nb_eventtype
;k
++){
2206 eventtype
= lttv_tracefile_selector_eventtype_get(tracefile
,k
);
2207 name
= lttv_eventtype_selector_get_name(eventtype
);
2208 checked
= lttv_eventtype_selector_get_selected(eventtype
);
2209 gtk_tree_store_append (store
, &child_iter2
, &child_iter1
);
2210 gtk_tree_store_set (store
, &child_iter2
,
2211 CHECKBOX_COLUMN
, checked
,
2218 id
= gtk_dialog_run(GTK_DIALOG(dialogue
));
2220 case GTK_RESPONSE_ACCEPT
:
2221 case GTK_RESPONSE_OK
:
2222 update_filter(s
, store
);
2223 gtk_widget_destroy(dialogue
);
2225 case GTK_RESPONSE_REJECT
:
2226 case GTK_RESPONSE_CANCEL
:
2228 gtk_widget_destroy(dialogue
);
2235 /* Select a trace which will be removed from traceset
2238 char * get_remove_trace(char ** all_trace_name
, int nb_trace
)
2240 return get_selection(all_trace_name
, nb_trace
,
2241 "Select a trace", "Trace pathname");
2245 /* Select a module which will be unloaded
2248 char * get_unload_module(char ** loaded_module_name
, int nb_module
)
2250 return get_selection(loaded_module_name
, nb_module
,
2251 "Select an unload module", "Module pathname");
2255 /* Display a dialogue which shows all selectable items, let user to
2256 * select one of them
2259 char * get_selection(char ** loaded_module_name
, int nb_module
,
2260 char *title
, char * column_title
)
2262 GtkWidget
* dialogue
;
2263 GtkWidget
* scroll_win
;
2265 GtkListStore
* store
;
2266 GtkTreeViewColumn
* column
;
2267 GtkCellRenderer
* renderer
;
2268 GtkTreeSelection
* select
;
2271 char * unload_module_name
= NULL
;
2273 dialogue
= gtk_dialog_new_with_buttons(title
,
2276 GTK_STOCK_OK
,GTK_RESPONSE_ACCEPT
,
2277 GTK_STOCK_CANCEL
,GTK_RESPONSE_REJECT
,
2279 gtk_window_set_default_size((GtkWindow
*)dialogue
, 500, 200);
2281 scroll_win
= gtk_scrolled_window_new (NULL
, NULL
);
2282 gtk_widget_show ( scroll_win
);
2283 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll_win
),
2284 GTK_POLICY_AUTOMATIC
, GTK_POLICY_AUTOMATIC
);
2286 store
= gtk_list_store_new (N_COLUMNS
,G_TYPE_STRING
);
2287 tree
= gtk_tree_view_new_with_model(GTK_TREE_MODEL (store
));
2288 gtk_widget_show ( tree
);
2289 g_object_unref (G_OBJECT (store
));
2291 renderer
= gtk_cell_renderer_text_new ();
2292 column
= gtk_tree_view_column_new_with_attributes (column_title
,
2294 "text", MODULE_COLUMN
,
2296 gtk_tree_view_column_set_alignment (column
, 0.5);
2297 gtk_tree_view_column_set_fixed_width (column
, 150);
2298 gtk_tree_view_append_column (GTK_TREE_VIEW (tree
), column
);
2300 select
= gtk_tree_view_get_selection (GTK_TREE_VIEW (tree
));
2301 gtk_tree_selection_set_mode (select
, GTK_SELECTION_SINGLE
);
2303 gtk_container_add (GTK_CONTAINER (scroll_win
), tree
);
2305 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialogue
)->vbox
), scroll_win
,TRUE
, TRUE
,0);
2307 for(i
=0;i
<nb_module
;i
++){
2308 gtk_list_store_append (store
, &iter
);
2309 gtk_list_store_set (store
, &iter
, MODULE_COLUMN
,loaded_module_name
[i
],-1);
2312 id
= gtk_dialog_run(GTK_DIALOG(dialogue
));
2314 case GTK_RESPONSE_ACCEPT
:
2315 case GTK_RESPONSE_OK
:
2316 if (gtk_tree_selection_get_selected (select
, (GtkTreeModel
**)&store
, &iter
)){
2317 gtk_tree_model_get ((GtkTreeModel
*)store
, &iter
, MODULE_COLUMN
, &unload_module_name
, -1);
2319 case GTK_RESPONSE_REJECT
:
2320 case GTK_RESPONSE_CANCEL
:
2322 gtk_widget_destroy(dialogue
);
2326 return unload_module_name
;
2330 /* Insert all menu entry and tool buttons into this main window
2335 void add_all_menu_toolbar_constructors(MainWindow
* mw
, gpointer user_data
)
2339 lttvwindow_viewer_constructor constructor
;
2340 LttvMenus
* global_menu
, * instance_menu
;
2341 LttvToolbars
* global_toolbar
, * instance_toolbar
;
2342 LttvMenuClosure
*menu_item
;
2343 LttvToolbarClosure
*toolbar_item
;
2344 LttvAttributeValue value
;
2345 LttvIAttribute
*global_attributes
= LTTV_IATTRIBUTE(lttv_global_attributes());
2346 LttvIAttribute
*attributes
= mw
->attributes
;
2347 GtkWidget
* tool_menu_title_menu
, *new_widget
, *pixmap
;
2349 g_assert(lttv_iattribute_find_by_path(global_attributes
,
2350 "viewers/menu", LTTV_POINTER
, &value
));
2351 if(*(value
.v_pointer
) == NULL
)
2352 *(value
.v_pointer
) = lttv_menus_new();
2353 global_menu
= (LttvMenus
*)*(value
.v_pointer
);
2355 g_assert(lttv_iattribute_find_by_path(attributes
,
2356 "viewers/menu", LTTV_POINTER
, &value
));
2357 if(*(value
.v_pointer
) == NULL
)
2358 *(value
.v_pointer
) = lttv_menus_new();
2359 instance_menu
= (LttvMenus
*)*(value
.v_pointer
);
2363 g_assert(lttv_iattribute_find_by_path(global_attributes
,
2364 "viewers/toolbar", LTTV_POINTER
, &value
));
2365 if(*(value
.v_pointer
) == NULL
)
2366 *(value
.v_pointer
) = lttv_toolbars_new();
2367 global_toolbar
= (LttvToolbars
*)*(value
.v_pointer
);
2369 g_assert(lttv_iattribute_find_by_path(attributes
,
2370 "viewers/toolbar", LTTV_POINTER
, &value
));
2371 if(*(value
.v_pointer
) == NULL
)
2372 *(value
.v_pointer
) = lttv_toolbars_new();
2373 instance_toolbar
= (LttvToolbars
*)*(value
.v_pointer
);
2375 /* Add missing menu entries to window instance */
2376 for(i
=0;i
<global_menu
->len
;i
++) {
2377 menu_item
= &g_array_index(global_menu
, LttvMenuClosure
, i
);
2379 //add menu_item to window instance;
2380 constructor
= menu_item
->con
;
2381 tool_menu_title_menu
= lookup_widget(mw
->mwindow
,"ToolMenuTitle_menu");
2383 gtk_menu_item_new_with_mnemonic (menu_item
->menu_text
);
2384 gtk_container_add (GTK_CONTAINER (tool_menu_title_menu
),
2386 g_signal_connect ((gpointer
) new_widget
, "activate",
2387 G_CALLBACK (insert_viewer_wrap
),
2389 gtk_widget_show (new_widget
);
2390 lttv_menus_add(instance_menu
, menu_item
->con
,
2391 menu_item
->menu_path
,
2392 menu_item
->menu_text
,
2397 /* Add missing toolbar entries to window instance */
2398 for(i
=0;i
<global_toolbar
->len
;i
++) {
2399 toolbar_item
= &g_array_index(global_toolbar
, LttvToolbarClosure
, i
);
2401 //add toolbar_item to window instance;
2402 constructor
= toolbar_item
->con
;
2403 tool_menu_title_menu
= lookup_widget(mw
->mwindow
,"MToolbar1");
2404 pixbuf
= gdk_pixbuf_new_from_xpm_data((const char**)toolbar_item
->pixmap
);
2405 pixmap
= gtk_image_new_from_pixbuf(pixbuf
);
2407 gtk_toolbar_append_element (GTK_TOOLBAR (tool_menu_title_menu
),
2408 GTK_TOOLBAR_CHILD_BUTTON
,
2411 toolbar_item
->tooltip
, NULL
,
2412 pixmap
, NULL
, NULL
);
2413 gtk_label_set_use_underline(
2414 GTK_LABEL (((GtkToolbarChild
*) (
2415 g_list_last (GTK_TOOLBAR
2416 (tool_menu_title_menu
)->children
)->data
))->label
),
2418 gtk_container_set_border_width (GTK_CONTAINER (new_widget
), 1);
2419 g_signal_connect ((gpointer
) new_widget
,
2421 G_CALLBACK (insert_viewer_wrap
),
2423 gtk_widget_show (new_widget
);
2425 lttv_toolbars_add(instance_toolbar
, toolbar_item
->con
,
2426 toolbar_item
->tooltip
,
2427 toolbar_item
->pixmap
,
2435 /* Create a main window
2438 void construct_main_window(MainWindow
* parent
)
2440 g_debug("construct_main_window()");
2441 GtkWidget
* new_window
; /* New generated main window */
2442 MainWindow
* new_m_window
;/* New main window structure */
2443 GtkNotebook
* notebook
;
2444 LttvIAttribute
*attributes
=
2445 LTTV_IATTRIBUTE(g_object_new(LTTV_ATTRIBUTE_TYPE
, NULL
));
2446 LttvAttributeValue value
;
2449 new_m_window
= g_new(MainWindow
, 1);
2451 // Add the object's information to the module's array
2452 g_main_window_list
= g_slist_append(g_main_window_list
, new_m_window
);
2455 new_window
= create_MWindow();
2456 gtk_widget_show (new_window
);
2458 new_m_window
->mwindow
= new_window
;
2459 new_m_window
->attributes
= attributes
;
2461 g_assert(lttv_iattribute_find_by_path(attributes
,
2462 "viewers/menu", LTTV_POINTER
, &value
));
2463 *(value
.v_pointer
) = lttv_menus_new();
2465 g_assert(lttv_iattribute_find_by_path(attributes
,
2466 "viewers/toolbar", LTTV_POINTER
, &value
));
2467 *(value
.v_pointer
) = lttv_toolbars_new();
2469 add_all_menu_toolbar_constructors(new_m_window
, NULL
);
2471 g_object_set_data_full(G_OBJECT(new_window
),
2473 (gpointer
)new_m_window
,
2474 (GDestroyNotify
)g_free
);
2475 //create a default tab
2476 notebook
= (GtkNotebook
*)lookup_widget(new_m_window
->mwindow
, "MNotebook");
2477 if(notebook
== NULL
){
2478 g_printf("Notebook does not exist\n");
2481 //for now there is no name field in LttvTraceset structure
2482 //Use "Traceset" as the label for the default tab
2484 GtkWidget
* parent_notebook
= lookup_widget(parent
->mwindow
, "MNotebook");
2485 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(parent_notebook
),
2486 gtk_notebook_get_current_page(GTK_NOTEBOOK(parent_notebook
)));
2492 parent_tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
2494 new_tab
= create_tab(new_m_window
, parent_tab
, notebook
, "Traceset");
2496 new_tab
= create_tab(new_m_window
, NULL
, notebook
, "Traceset");
2497 if(g_init_trace
!= NULL
){
2498 lttvwindow_add_trace(new_tab
,
2503 g_printf("There are now : %d windows\n",g_slist_length(g_main_window_list
));
2507 /* Free the memory occupied by a tab structure
2511 void tab_destructor(Tab
* tab_instance
)
2513 int i
, nb
, ref_count
;
2516 if(tab_instance
->attributes
)
2517 g_object_unref(tab_instance
->attributes
);
2519 if(tab_instance
->interrupted_state
)
2520 g_object_unref(tab_instance
->interrupted_state
);
2523 if(tab_instance
->traceset_info
->traceset_context
!= NULL
){
2524 //remove state update hooks
2525 lttv_state_remove_event_hooks(
2526 (LttvTracesetState
*)tab_instance
->traceset_info
->
2528 lttv_context_fini(LTTV_TRACESET_CONTEXT(tab_instance
->traceset_info
->
2530 g_object_unref(tab_instance
->traceset_info
->traceset_context
);
2532 if(tab_instance
->traceset_info
->traceset
!= NULL
) {
2533 nb
= lttv_traceset_number(tab_instance
->traceset_info
->traceset
);
2534 for(i
= 0 ; i
< nb
; i
++) {
2535 trace
= lttv_traceset_get(tab_instance
->traceset_info
->traceset
, i
);
2536 ref_count
= lttv_trace_get_ref_number(trace
);
2538 ltt_trace_close(lttv_trace(trace
));
2539 lttv_trace_destroy(trace
);
2541 // lttv_trace_destroy(trace);
2544 lttv_traceset_destroy(tab_instance
->traceset_info
->traceset
);
2545 /* Remove the idle events requests processing function of the tab */
2546 g_idle_remove_by_data(tab_instance
);
2548 g_slist_free(tab_instance
->events_requests
);
2549 g_free(tab_instance
->traceset_info
);
2550 g_free(tab_instance
);
2554 /* Create a tab and insert it into the current main window
2557 Tab
* create_tab(MainWindow
* mw
, Tab
*copy_tab
,
2558 GtkNotebook
* notebook
, char * label
)
2564 //create a new tab data structure
2567 //construct and initialize the traceset_info
2568 tab
->traceset_info
= g_new(TracesetInfo
,1);
2571 tab
->traceset_info
->traceset
=
2572 lttv_traceset_copy(copy_tab
->traceset_info
->traceset
);
2574 tab
->traceset_info
->traceset
= lttv_traceset_new();
2577 //FIXME : this is g_debug level
2578 lttv_attribute_write_xml(
2579 lttv_traceset_attribute(tab
->traceset_info
->traceset
),
2585 //FIXME copy not implemented in lower level
2586 tab
->traceset_info
->traceset_context
=
2587 g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
2588 g_assert(tab
->traceset_info
->traceset_context
!= NULL
);
2590 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
),
2591 tab
->traceset_info
->traceset
);
2592 //add state update hooks
2593 lttv_state_add_event_hooks(
2594 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
2596 //determine the current_time and time_window of the tab
2597 if(copy_tab
!= NULL
){
2598 tab
->time_window
= copy_tab
->time_window
;
2599 tab
->current_time
= copy_tab
->current_time
;
2601 tab
->time_window
.start_time
=
2602 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
2603 time_span
.start_time
;
2604 if(DEFAULT_TIME_WIDTH_S
<
2605 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
2606 time_span
.end_time
.tv_sec
)
2607 tmp_time
.tv_sec
= DEFAULT_TIME_WIDTH_S
;
2610 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
2611 time_span
.end_time
.tv_sec
;
2612 tmp_time
.tv_nsec
= 0;
2613 tab
->time_window
.time_width
= tmp_time
;
2614 tab
->current_time
.tv_sec
=
2615 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
2616 time_span
.start_time
.tv_sec
;
2617 tab
->current_time
.tv_nsec
=
2618 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
2619 time_span
.start_time
.tv_nsec
;
2621 tab
->attributes
= LTTV_IATTRIBUTE(g_object_new(LTTV_ATTRIBUTE_TYPE
, NULL
));
2622 tab
->interrupted_state
= g_object_new(LTTV_ATTRIBUTE_TYPE
, NULL
);
2623 tab
->multi_vpaned
= (GtkMultiVPaned
*)gtk_multi_vpaned_new();
2624 gtk_widget_show((GtkWidget
*)tab
->multi_vpaned
);
2627 tab
->label
= gtk_label_new (label
);
2628 gtk_widget_show (tab
->label
);
2630 /* Start with empty events requests list */
2631 tab
->events_requests
= NULL
;
2632 tab
->events_request_pending
= FALSE
;
2634 g_object_set_data_full(
2635 G_OBJECT(tab
->multi_vpaned
),
2638 (GDestroyNotify
)tab_destructor
);
2640 //insert tab into notebook
2641 gtk_notebook_append_page(notebook
,
2642 (GtkWidget
*)tab
->multi_vpaned
,
2644 list
= gtk_container_get_children(GTK_CONTAINER(notebook
));
2645 gtk_notebook_set_current_page(notebook
,g_list_length(list
)-1);
2646 // always show : not if(g_list_length(list)>1)
2647 gtk_notebook_set_show_tabs(notebook
, TRUE
);
2653 * execute_events_requests
2655 * Idle function that executes the pending requests for a tab.
2657 * @return return value : TRUE : keep the idle function, FALSE : remove it.
2659 gboolean
execute_events_requests(Tab
*tab
)
2661 return ( lttvwindow_process_pending_requests(tab
) );