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
31 #include "callbacks.h"
32 #include "interface.h"
34 #include <ltt/trace.h>
36 #include <ltt/event.h>
37 #include <lttv/lttv.h>
38 #include <lttv/module.h>
39 #include <lttv/iattribute.h>
40 #include <lttv/stats.h>
41 #include <lttv/filter.h>
42 #include <lttv/sync/sync_chain_lttv.h>
43 #include <lttvwindow/mainwindow.h>
44 #include <lttvwindow/mainwindow-private.h>
45 #include <lttvwindow/menu.h>
46 #include <lttvwindow/toolbar.h>
47 #include <lttvwindow/lttvwindow.h>
48 #include <lttvwindow/lttvwindowtraces.h>
49 #include <lttvwindow/lttv_plugin_tab.h>
51 static LttTime lttvwindow_default_time_width
= { 1, 0 };
52 #define CLIP_BUF 256 // size of clipboard buffer
54 extern LttvTrace
*g_init_trace
;
57 /** Array containing instanced objects. */
58 extern GSList
* g_main_window_list
;
60 /** MD : keep old directory. */
61 static char remember_plugins_dir
[PATH_MAX
] = "";
62 static char remember_trace_dir
[PATH_MAX
] = "";
64 void tab_destructor(LttvPluginTab
* ptab
);
66 MainWindow
* get_window_data_struct(GtkWidget
* widget
);
67 char * get_load_module(MainWindow
*mw
,
68 char ** load_module_name
, int nb_module
);
69 char * get_unload_module(MainWindow
*mw
,
70 char ** loaded_module_name
, int nb_module
);
71 char * get_remove_trace(MainWindow
*mw
, char ** all_trace_name
, int nb_trace
);
72 char * get_selection(MainWindow
*mw
,
73 char ** all_name
, int nb
, char *title
, char * column_title
);
74 void init_tab(Tab
*tab
, MainWindow
* mw
, Tab
*copy_tab
,
75 GtkNotebook
* notebook
, char * label
);
77 static void insert_viewer(GtkWidget
* widget
, lttvwindow_viewer_constructor constructor
);
79 LttvPluginTab
*create_new_tab(GtkWidget
* widget
, gpointer user_data
);
81 static gboolean
lttvwindow_process_pending_requests(Tab
*tab
);
95 /* Pasting routines */
97 static void MEventBox1a_receive(GtkClipboard
*clipboard
,
101 if(text
== NULL
) return;
102 Tab
*tab
= (Tab
*)data
;
103 gchar buffer
[CLIP_BUF
];
104 gchar
*ptr
= buffer
, *ptr_ssec
, *ptr_snsec
, *ptr_esec
, *ptr_ensec
;
106 strncpy(buffer
, text
, CLIP_BUF
);
109 while(!isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
110 /* remove leading junk */
112 while(isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
113 /* read all the first number */
117 while(!isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
118 /* remove leading junk */
120 while(isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
121 /* read all the first number */
125 while(!isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
126 /* remove leading junk */
128 while(isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
129 /* read all the first number */
133 while(!isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
134 /* remove leading junk */
136 while(isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
137 /* read all the first number */
140 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry1
),
141 (double)strtoul(ptr_ssec
, NULL
, 10));
142 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry2
),
143 (double)strtoul(ptr_snsec
, NULL
, 10));
144 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry3
),
145 (double)strtoul(ptr_esec
, NULL
, 10));
146 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry4
),
147 (double)strtoul(ptr_ensec
, NULL
, 10));
150 static gboolean
on_MEventBox1a_paste(GtkWidget
*widget
, GdkEventButton
*event
,
153 Tab
*tab
= (Tab
*)data
;
155 GtkClipboard
*clip
= gtk_clipboard_get_for_display(gdk_display_get_default(),
156 GDK_SELECTION_PRIMARY
);
157 gtk_clipboard_request_text(clip
,
158 (GtkClipboardTextReceivedFunc
)MEventBox1a_receive
,
165 static void MEventBox1b_receive(GtkClipboard
*clipboard
,
169 if(text
== NULL
) return;
170 Tab
*tab
= (Tab
*)data
;
171 gchar buffer
[CLIP_BUF
];
172 gchar
*ptr
= buffer
, *ptr_sec
, *ptr_nsec
;
174 strncpy(buffer
, text
, CLIP_BUF
);
176 while(!isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
177 /* remove leading junk */
179 while(isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
180 /* read all the first number */
184 while(!isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
185 /* remove leading junk */
187 while(isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
188 /* read all the first number */
191 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry1
),
192 (double)strtoul(ptr_sec
, NULL
, 10));
193 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry2
),
194 (double)strtoul(ptr_nsec
, NULL
, 10));
198 static gboolean
on_MEventBox1b_paste(GtkWidget
*widget
, GdkEventButton
*event
,
201 Tab
*tab
= (Tab
*)data
;
203 GtkClipboard
*clip
= gtk_clipboard_get_for_display(gdk_display_get_default(),
204 GDK_SELECTION_PRIMARY
);
205 gtk_clipboard_request_text(clip
,
206 (GtkClipboardTextReceivedFunc
)MEventBox1b_receive
,
212 static void MEventBox3b_receive(GtkClipboard
*clipboard
,
216 if(text
== NULL
) return;
217 Tab
*tab
= (Tab
*)data
;
218 gchar buffer
[CLIP_BUF
];
219 gchar
*ptr
= buffer
, *ptr_sec
, *ptr_nsec
;
221 strncpy(buffer
, text
, CLIP_BUF
);
223 while(!isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
224 /* remove leading junk */
226 while(isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
227 /* read all the first number */
231 while(!isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
232 /* remove leading junk */
234 while(isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
235 /* read all the first number */
238 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry3
),
239 (double)strtoul(ptr_sec
, NULL
, 10));
240 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry4
),
241 (double)strtoul(ptr_nsec
, NULL
, 10));
245 static gboolean
on_MEventBox3b_paste(GtkWidget
*widget
, GdkEventButton
*event
,
248 Tab
*tab
= (Tab
*)data
;
250 GtkClipboard
*clip
= gtk_clipboard_get_for_display(gdk_display_get_default(),
251 GDK_SELECTION_PRIMARY
);
252 gtk_clipboard_request_text(clip
,
253 (GtkClipboardTextReceivedFunc
)MEventBox3b_receive
,
259 static void MEventBox5b_receive(GtkClipboard
*clipboard
,
263 if(text
== NULL
) return;
264 Tab
*tab
= (Tab
*)data
;
265 gchar buffer
[CLIP_BUF
];
266 gchar
*ptr
= buffer
, *ptr_sec
, *ptr_nsec
;
268 strncpy(buffer
, text
, CLIP_BUF
);
270 while(!isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
271 /* remove leading junk */
273 while(isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
274 /* read all the first number */
278 while(!isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
279 /* remove leading junk */
281 while(isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
282 /* read all the first number */
285 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry5
),
286 (double)strtoul(ptr_sec
, NULL
, 10));
287 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry6
),
288 (double)strtoul(ptr_nsec
, NULL
, 10));
292 static gboolean
on_MEventBox5b_paste(GtkWidget
*widget
, GdkEventButton
*event
,
295 Tab
*tab
= (Tab
*)data
;
297 GtkClipboard
*clip
= gtk_clipboard_get_for_display(gdk_display_get_default(),
298 GDK_SELECTION_PRIMARY
);
299 gtk_clipboard_request_text(clip
,
300 (GtkClipboardTextReceivedFunc
)MEventBox5b_receive
,
306 static void MEventBox8_receive(GtkClipboard
*clipboard
,
310 if(text
== NULL
) return;
311 Tab
*tab
= (Tab
*)data
;
312 gchar buffer
[CLIP_BUF
];
313 gchar
*ptr
= buffer
, *ptr_sec
, *ptr_nsec
;
315 strncpy(buffer
, text
, CLIP_BUF
);
317 while(!isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
318 /* remove leading junk */
320 while(isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
321 /* read all the first number */
325 while(!isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
326 /* remove leading junk */
328 while(isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
329 /* read all the first number */
332 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry7
),
333 (double)strtoul(ptr_sec
, NULL
, 10));
334 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry8
),
335 (double)strtoul(ptr_nsec
, NULL
, 10));
339 static gboolean
on_MEventBox8_paste(GtkWidget
*widget
, GdkEventButton
*event
,
342 Tab
*tab
= (Tab
*)data
;
344 GtkClipboard
*clip
= gtk_clipboard_get_for_display(gdk_display_get_default(),
345 GDK_SELECTION_PRIMARY
);
346 gtk_clipboard_request_text(clip
,
347 (GtkClipboardTextReceivedFunc
)MEventBox8_receive
,
353 static void on_top_notify(GObject
*gobject
,
357 Tab
*tab
= (Tab
*)user_data
;
358 g_message("in on_top_notify.\n");
362 static gboolean
viewer_grab_focus(GtkWidget
*widget
, GdkEventButton
*event
,
365 GtkWidget
*viewer
= GTK_WIDGET(data
);
366 GtkWidget
*viewer_container
= gtk_widget_get_parent(viewer
);
368 g_debug("FOCUS GRABBED");
369 g_object_set_data(G_OBJECT(viewer_container
), "focused_viewer", viewer
);
374 static void connect_focus_recursive(GtkWidget
*widget
,
377 if(GTK_IS_CONTAINER(widget
)) {
378 gtk_container_forall(GTK_CONTAINER(widget
),
379 (GtkCallback
)connect_focus_recursive
,
383 if(GTK_IS_TREE_VIEW(widget
)) {
384 gtk_tree_view_set_headers_clickable(GTK_TREE_VIEW(widget
), TRUE
);
386 gtk_widget_add_events(widget
, GDK_BUTTON_PRESS_MASK
);
387 g_signal_connect (G_OBJECT(widget
),
388 "button-press-event",
389 G_CALLBACK (viewer_grab_focus
),
393 /* Stop all the processings and call gtk_main_quit() */
394 static void mainwindow_quit()
396 lttvwindowtraces_unregister_requests(g_quark_from_string("stats"));
397 lttvwindowtraces_unregister_requests(g_quark_from_string("state"));
398 lttvwindowtraces_unregister_computation_hooks(g_quark_from_string("stats"));
399 lttvwindowtraces_unregister_computation_hooks(g_quark_from_string("state"));
405 /* insert_viewer function constructs an instance of a viewer first,
406 * then inserts the widget of the instance into the container of the
411 insert_viewer_wrap(GtkWidget
*menuitem
, gpointer user_data
)
413 insert_viewer((GtkWidget
*)menuitem
, (lttvwindow_viewer_constructor
)user_data
);
417 /* internal functions */
418 void insert_viewer(GtkWidget
* widget
, lttvwindow_viewer_constructor constructor
)
420 GtkWidget
* viewer_container
;
421 MainWindow
* mw_data
= get_window_data_struct(widget
);
422 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
424 TimeInterval
* time_interval
;
425 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
426 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
431 ptab
= create_new_tab(widget
, NULL
);
433 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
437 viewer_container
= tab
->viewer_container
;
439 viewer
= (GtkWidget
*)constructor(ptab
);
442 //gtk_multivpaned_widget_add(GTK_MULTIVPANED(multivpaned), viewer);
444 gtk_box_pack_end(GTK_BOX(viewer_container
),
450 /* We want to connect the viewer_grab_focus to EVERY
451 * child of this widget. The little trick is to get each child
452 * of each GTK_CONTAINER, even subchildren.
454 connect_focus_recursive(viewer
, viewer
);
459 * Function to set/update traceset for the viewers
460 * @param tab viewer's tab
461 * @param traceset traceset of the main window.
463 * 0 : traceset updated
464 * 1 : no traceset hooks to update; not an error.
467 int SetTraceset(Tab
* tab
, LttvTraceset
*traceset
)
470 TimeInterval time_span
;
471 TimeWindow new_time_window
;
472 LttTime new_current_time
;
473 LttvTracesetContext
*tsc
=
474 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
476 // Perform time synchronization on the traces
477 if (syncTraceset(tsc
))
479 /* There is some time-dependant information that was calculated during
480 * context initialization. Destroy the old contexts and initialize new
482 * Modified from lttvwindow_add_trace()
484 // Keep a reference to the traces so they are not freed
485 for(i
= 0; i
< lttv_traceset_number(traceset
); i
++)
487 LttvTrace
*trace
= lttv_traceset_get(traceset
, i
);
488 lttv_trace_ref(trace
);
491 // Remove state update hooks
492 lttv_state_remove_event_hooks(
493 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
495 lttv_context_fini(LTTV_TRACESET_CONTEXT(
496 tab
->traceset_info
->traceset_context
));
497 g_object_unref(tab
->traceset_info
->traceset_context
);
499 for(i
= 0; i
< lttv_traceset_number(traceset
); i
++)
501 LttvTrace
*trace
= lttv_traceset_get(traceset
, i
);
502 lttvwindowtraces_remove_trace(trace
);
503 lttvwindowtraces_add_trace(trace
);
506 // Create new context
507 tab
->traceset_info
->traceset_context
=
508 g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
509 lttv_context_init(LTTV_TRACESET_CONTEXT(tab
->traceset_info
->
510 traceset_context
), traceset
);
512 // Add state update hooks
513 lttv_state_add_event_hooks(
514 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
516 // Remove local reference to the traces
517 for(i
=0; i
<lttv_traceset_number(traceset
); i
++)
519 LttvTrace
*trace
= lttv_traceset_get(traceset
, i
);
520 lttv_trace_unref(trace
);
523 tsc
= LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
526 time_span
= tsc
->time_span
;
527 new_time_window
= tab
->time_window
;
528 new_current_time
= tab
->current_time
;
530 /* Set the tab's time window and current time if
532 if(ltt_time_compare(tab
->time_window
.start_time
, time_span
.start_time
) < 0
533 || ltt_time_compare(tab
->time_window
.end_time
,
534 time_span
.end_time
) > 0) {
535 new_time_window
.start_time
= time_span
.start_time
;
537 new_current_time
= time_span
.start_time
;
541 if(ltt_time_compare(lttvwindow_default_time_width
,
542 ltt_time_sub(time_span
.end_time
, time_span
.start_time
)) < 0
544 ltt_time_compare(time_span
.end_time
, time_span
.start_time
) == 0)
545 tmp_time
= lttvwindow_default_time_width
;
547 tmp_time
= time_span
.end_time
;
549 new_time_window
.time_width
= tmp_time
;
550 new_time_window
.time_width_double
= ltt_time_to_double(tmp_time
);
551 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
552 new_time_window
.time_width
) ;
559 GtkAdjustment
*adjustment
= gtk_range_get_adjustment(GTK_RANGE(tab
->scrollbar
));
560 LttTime upper
= ltt_time_sub(time_span
.end_time
, time_span
.start_time
);
562 g_object_set(G_OBJECT(adjustment
),
566 ltt_time_to_double(upper
)
567 * NANOSECONDS_PER_SECOND
, /* upper */
569 ltt_time_to_double(tab
->time_window
.time_width
)
570 / SCROLL_STEP_PER_PAGE
571 * NANOSECONDS_PER_SECOND
, /* step increment */
573 ltt_time_to_double(tab
->time_window
.time_width
)
574 * NANOSECONDS_PER_SECOND
, /* page increment */
576 ltt_time_to_double(tab
->time_window
.time_width
)
577 * NANOSECONDS_PER_SECOND
, /* page size */
579 gtk_adjustment_changed(adjustment
);
581 g_object_set(G_OBJECT(adjustment
),
584 ltt_time_sub(tab
->time_window
.start_time
, time_span
.start_time
))
585 * NANOSECONDS_PER_SECOND
, /* value */
587 gtk_adjustment_value_changed(adjustment
);
589 /* set the time bar. The value callbacks will change their nsec themself */
591 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry1
),
592 (double)time_span
.start_time
.tv_sec
,
593 (double)time_span
.end_time
.tv_sec
);
596 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry3
),
597 (double)time_span
.start_time
.tv_sec
,
598 (double)time_span
.end_time
.tv_sec
);
600 /* current seconds */
601 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry5
),
602 (double)time_span
.start_time
.tv_sec
,
603 (double)time_span
.end_time
.tv_sec
);
606 /* Finally, call the update hooks of the viewers */
608 LttvAttributeValue value
;
611 retval
= lttv_iattribute_find_by_path(tab
->attributes
,
612 "hooks/updatetraceset", LTTV_POINTER
, &value
);
615 tmp
= (LttvHooks
*)*(value
.v_pointer
);
619 lttv_hooks_call(tmp
,traceset
);
621 time_change_manager(tab
, new_time_window
);
622 current_time_change_manager(tab
, new_current_time
);
628 * Function to set/update filter for the viewers
629 * @param tab viewer's tab
630 * @param filter filter of the main window.
633 * 0 : filters updated
634 * 1 : no filter hooks to update; not an error.
637 int SetFilter(Tab
* tab
, gpointer filter
)
640 LttvAttributeValue value
;
642 g_assert(lttv_iattribute_find_by_path(tab
->attributes
,
643 "hooks/updatefilter", LTTV_POINTER
, &value
));
645 tmp
= (LttvHooks
*)*(value
.v_pointer
);
647 if(tmp
== NULL
) return 1;
648 lttv_hooks_call(tmp
,filter
);
656 * Function to redraw each viewer belonging to the current tab
657 * @param tab viewer's tab
660 void update_traceset(Tab
*tab
)
662 LttvAttributeValue value
;
666 retval
= lttv_iattribute_find_by_path(tab
->attributes
,
667 "hooks/updatetraceset", LTTV_POINTER
, &value
);
669 tmp
= (LttvHooks
*)*(value
.v_pointer
);
670 if(tmp
== NULL
) return;
671 lttv_hooks_call(tmp
, NULL
);
675 /* get_label function is used to get user input, it displays an input
676 * box, which allows user to input a string
679 void get_label_string (GtkWidget
* text
, gchar
* label
)
681 GtkEntry
* entry
= (GtkEntry
*)text
;
682 if(strlen(gtk_entry_get_text(entry
))!=0)
683 strcpy(label
,gtk_entry_get_text(entry
));
686 gboolean
get_label(MainWindow
* mw
, gchar
* str
, gchar
* dialogue_title
, gchar
* label_str
)
688 GtkWidget
* dialogue
;
693 dialogue
= gtk_dialog_new_with_buttons(dialogue_title
,NULL
,
695 GTK_STOCK_OK
,GTK_RESPONSE_ACCEPT
,
696 GTK_STOCK_CANCEL
,GTK_RESPONSE_REJECT
,
699 label
= gtk_label_new(label_str
);
700 gtk_widget_show(label
);
702 text
= gtk_entry_new();
703 gtk_widget_show(text
);
705 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialogue
)->vbox
), label
,TRUE
, TRUE
,0);
706 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialogue
)->vbox
), text
,FALSE
, FALSE
,0);
708 id
= gtk_dialog_run(GTK_DIALOG(dialogue
));
710 case GTK_RESPONSE_ACCEPT
:
711 get_label_string(text
,str
);
712 gtk_widget_destroy(dialogue
);
714 case GTK_RESPONSE_REJECT
:
716 gtk_widget_destroy(dialogue
);
723 /* get_window_data_struct function is actually a lookup function,
724 * given a widget which is in the tree of the main window, it will
725 * return the MainWindow data structure associated with main window
728 MainWindow
* get_window_data_struct(GtkWidget
* widget
)
731 MainWindow
* mw_data
;
733 mw
= lookup_widget(widget
, "MWindow");
735 g_info("Main window does not exist\n");
739 mw_data
= (MainWindow
*) g_object_get_data(G_OBJECT(mw
),"main_window_data");
741 g_warning("Main window data does not exist\n");
748 /* create_new_window function, just constructs a new main window
751 void create_new_window(GtkWidget
* widget
, gpointer user_data
, gboolean clone
)
753 MainWindow
* parent
= get_window_data_struct(widget
);
756 g_info("Clone : use the same traceset\n");
757 construct_main_window(parent
);
759 g_info("Empty : traceset is set to NULL\n");
760 construct_main_window(NULL
);
764 /* Get the currently focused viewer.
765 * If no viewer is focused, use the first one.
767 * If no viewer available, return NULL.
769 GtkWidget
*viewer_container_focus(GtkWidget
*container
)
773 widget
= (GtkWidget
*)g_object_get_data(G_OBJECT(container
),
777 g_debug("no widget focused");
778 GList
*children
= gtk_container_get_children(GTK_CONTAINER(container
));
781 widget
= GTK_WIDGET(children
->data
);
782 g_object_set_data(G_OBJECT(container
),
792 gint
viewer_container_position(GtkWidget
*container
, GtkWidget
*child
)
795 if(child
== NULL
) return -1;
799 memset(&value
, 0, sizeof(GValue
));
800 g_value_init(&value
, G_TYPE_INT
);
801 gtk_container_child_get_property(GTK_CONTAINER(container
),
805 pos
= g_value_get_int(&value
);
811 /* move_*_viewer functions move the selected view up/down in
815 void move_down_viewer(GtkWidget
* widget
, gpointer user_data
)
817 MainWindow
* mw
= get_window_data_struct(widget
);
818 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
820 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
821 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
828 ptab
= g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
832 //gtk_multivpaned_widget_move_up(GTK_MULTIVPANED(tab->multivpaned));
834 /* change the position in the vbox */
835 GtkWidget
*focus_widget
;
837 focus_widget
= viewer_container_focus(tab
->viewer_container
);
838 position
= viewer_container_position(tab
->viewer_container
, focus_widget
);
841 /* can move up one position */
842 gtk_box_reorder_child(GTK_BOX(tab
->viewer_container
),
849 void move_up_viewer(GtkWidget
* widget
, gpointer user_data
)
851 MainWindow
* mw
= get_window_data_struct(widget
);
852 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
854 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
855 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
862 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
866 //gtk_multivpaned_widget_move_down(GTK_MULTIVPANED(tab->multivpaned));
867 /* change the position in the vbox */
868 GtkWidget
*focus_widget
;
870 focus_widget
= viewer_container_focus(tab
->viewer_container
);
871 position
= viewer_container_position(tab
->viewer_container
, focus_widget
);
875 g_list_length(gtk_container_get_children(
876 GTK_CONTAINER(tab
->viewer_container
)))-1
878 /* can move down one position */
879 gtk_box_reorder_child(GTK_BOX(tab
->viewer_container
),
887 /* delete_viewer deletes the selected viewer in the current tab
890 void delete_viewer(GtkWidget
* widget
, gpointer user_data
)
892 MainWindow
* mw
= get_window_data_struct(widget
);
893 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
895 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
896 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
903 ptab
= g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
907 //gtk_multivpaned_widget_delete(GTK_MULTIVPANED(tab->multivpaned));
909 GtkWidget
*focus_widget
= viewer_container_focus(tab
->viewer_container
);
911 if(focus_widget
!= NULL
)
912 gtk_widget_destroy(focus_widget
);
914 g_object_set_data(G_OBJECT(tab
->viewer_container
), "focused_viewer", NULL
);
918 /* open_traceset will open a traceset saved in a file
919 * Right now, it is not finished yet, (not working)
923 void open_traceset(GtkWidget
* widget
, gpointer user_data
)
927 LttvTraceset
* traceset
;
928 MainWindow
* mw_data
= get_window_data_struct(widget
);
929 GtkFileSelection
* file_selector
=
930 (GtkFileSelection
*)gtk_file_selection_new("Select a traceset");
932 gtk_file_selection_hide_fileop_buttons(file_selector
);
934 gtk_window_set_transient_for(GTK_WINDOW(file_selector
),
935 GTK_WINDOW(mw_data
->mwindow
));
937 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
939 case GTK_RESPONSE_ACCEPT
:
940 case GTK_RESPONSE_OK
:
941 dir
= gtk_file_selection_get_selections (file_selector
);
942 traceset
= lttv_traceset_load(dir
[0]);
943 g_info("Open a trace set %s\n", dir
[0]);
946 case GTK_RESPONSE_REJECT
:
947 case GTK_RESPONSE_CANCEL
:
949 gtk_widget_destroy((GtkWidget
*)file_selector
);
955 /* lttvwindow_process_pending_requests
957 * Process requests for parts of the trace from viewers.
959 * These requests are made by lttvwindow_events_request().
961 * This internal function gets called by g_idle, taking care of the pending
962 * requests. It is responsible for concatenation of time intervals and position
963 * requests. It does it with the following algorithm organizing process traceset
964 * calls. Here is the detailed description of the way it works :
966 * - Events Requests Servicing Algorithm
968 * Data structures necessary :
970 * List of requests added to context : list_in
971 * List of requests not added to context : list_out
976 * list_out : many events requests
978 * FIXME : insert rest of algorithm here
982 #define list_out tab->events_requests
984 gboolean
lttvwindow_process_pending_requests(Tab
*tab
)
987 LttvTracesetContext
*tsc
;
988 LttvTracefileContext
*tfc
;
989 GSList
*list_in
= NULL
;
993 LttvTracesetContextPosition
*end_position
;
995 if(lttvwindow_preempt_count
> 0) return TRUE
;
998 g_critical("Foreground processing : tab does not exist. Processing removed.");
1002 /* There is no events requests pending : we should never have been called! */
1003 g_assert(g_slist_length(list_out
) != 0);
1005 tsc
= LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
1007 //set the cursor to be X shape, indicating that the computer is busy in doing its job
1009 new = gdk_cursor_new(GDK_X_CURSOR
);
1010 widget
= lookup_widget(tab
->mw
->mwindow
, "MToolbar1");
1011 win
= gtk_widget_get_parent_window(widget
);
1012 gdk_window_set_cursor(win
, new);
1013 gdk_cursor_unref(new);
1014 gdk_window_stick(win
);
1015 gdk_window_unstick(win
);
1018 g_debug("SIZE events req len : %d", g_slist_length(list_out
));
1020 /* Preliminary check for no trace in traceset */
1021 /* Unregister the routine if empty, empty list_out too */
1022 if(lttv_traceset_number(tsc
->ts
) == 0) {
1024 /* - For each req in list_out */
1025 GSList
*iter
= list_out
;
1027 while(iter
!= NULL
) {
1029 gboolean remove
= FALSE
;
1030 gboolean free_data
= FALSE
;
1031 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1033 /* - Call end request for req */
1034 if(events_request
->servicing
== TRUE
)
1035 lttv_hooks_call(events_request
->after_request
, (gpointer
)tsc
);
1037 /* - remove req from list_out */
1038 /* Destroy the request */
1045 GSList
*remove_iter
= iter
;
1047 iter
= g_slist_next(iter
);
1048 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
1049 list_out
= g_slist_remove_link(list_out
, remove_iter
);
1050 } else { // not remove
1051 iter
= g_slist_next(iter
);
1056 /* 0.1 Lock Traces */
1061 iter_trace
<lttv_traceset_number(tsc
->ts
);
1063 LttvTrace
*trace_v
= lttv_traceset_get(tsc
->ts
, iter_trace
);
1065 if(lttvwindowtraces_lock(trace_v
) != 0) {
1066 g_critical("Foreground processing : Unable to get trace lock");
1067 return TRUE
; /* Cannot get lock, try later */
1072 /* 0.2 Seek tracefiles positions to context position */
1073 //g_assert(lttv_process_traceset_seek_position(tsc, sync_position) == 0);
1074 lttv_process_traceset_synchronize_tracefiles(tsc
);
1077 /* Events processing algorithm implementation */
1078 /* Warning : the gtk_events_pending takes a LOT of cpu time. So what we do
1079 * instead is to leave the control to GTK and take it back.
1081 /* A. Servicing loop */
1082 //while( (g_slist_length(list_in) != 0 || g_slist_length(list_out) != 0)) {
1083 if((g_slist_length(list_in
) != 0 || g_slist_length(list_out
) != 0)) {
1085 /* 1. If list_in is empty (need a seek) */
1086 if( g_slist_length(list_in
) == 0 ) {
1088 /* list in is empty, need a seek */
1090 /* 1.1 Add requests to list_in */
1091 GSList
*ltime
= NULL
;
1092 GSList
*lpos
= NULL
;
1093 GSList
*iter
= NULL
;
1095 /* 1.1.1 Find all time requests with the lowest start time in list_out
1098 if(g_slist_length(list_out
) > 0)
1099 ltime
= g_slist_append(ltime
, g_slist_nth_data(list_out
, 0));
1100 for(iter
=g_slist_nth(list_out
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
1101 /* Find all time requests with the lowest start time in list_out */
1102 EventsRequest
*event_request_ltime
= (EventsRequest
*)g_slist_nth_data(ltime
, 0);
1103 EventsRequest
*event_request_list_out
= (EventsRequest
*)iter
->data
;
1106 comp
= ltt_time_compare(event_request_ltime
->start_time
,
1107 event_request_list_out
->start_time
);
1109 ltime
= g_slist_append(ltime
, event_request_list_out
);
1111 /* Remove all elements from ltime, and add current */
1112 while(ltime
!= NULL
)
1113 ltime
= g_slist_delete_link(ltime
, g_slist_nth(ltime
, 0));
1114 ltime
= g_slist_append(ltime
, event_request_list_out
);
1118 /* 1.1.2 Find all position requests with the lowest position in list_out
1121 if(g_slist_length(list_out
) > 0)
1122 lpos
= g_slist_append(lpos
, g_slist_nth_data(list_out
, 0));
1123 for(iter
=g_slist_nth(list_out
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
1124 /* Find all position requests with the lowest position in list_out */
1125 EventsRequest
*event_request_lpos
= (EventsRequest
*)g_slist_nth_data(lpos
, 0);
1126 EventsRequest
*event_request_list_out
= (EventsRequest
*)iter
->data
;
1129 if(event_request_lpos
->start_position
!= NULL
1130 && event_request_list_out
->start_position
!= NULL
)
1132 comp
= lttv_traceset_context_pos_pos_compare
1133 (event_request_lpos
->start_position
,
1134 event_request_list_out
->start_position
);
1139 lpos
= g_slist_append(lpos
, event_request_list_out
);
1141 /* Remove all elements from lpos, and add current */
1143 lpos
= g_slist_delete_link(lpos
, g_slist_nth(lpos
, 0));
1144 lpos
= g_slist_append(lpos
, event_request_list_out
);
1149 EventsRequest
*event_request_lpos
= (EventsRequest
*)g_slist_nth_data(lpos
, 0);
1150 EventsRequest
*event_request_ltime
= (EventsRequest
*)g_slist_nth_data(ltime
, 0);
1151 LttTime lpos_start_time
;
1153 if(event_request_lpos
!= NULL
1154 && event_request_lpos
->start_position
!= NULL
) {
1155 lpos_start_time
= lttv_traceset_context_position_get_time(
1156 event_request_lpos
->start_position
);
1159 /* 1.1.3 If lpos.start time < ltime */
1160 if(event_request_lpos
!= NULL
1161 && event_request_lpos
->start_position
!= NULL
1162 && ltt_time_compare(lpos_start_time
,
1163 event_request_ltime
->start_time
)<0) {
1164 /* Add lpos to list_in, remove them from list_out */
1165 for(iter
=lpos
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
1166 /* Add to list_in */
1167 EventsRequest
*event_request_lpos
=
1168 (EventsRequest
*)iter
->data
;
1170 list_in
= g_slist_append(list_in
, event_request_lpos
);
1171 /* Remove from list_out */
1172 list_out
= g_slist_remove(list_out
, event_request_lpos
);
1175 /* 1.1.4 (lpos.start time >= ltime) */
1176 /* Add ltime to list_in, remove them from list_out */
1178 for(iter
=ltime
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
1179 /* Add to list_in */
1180 EventsRequest
*event_request_ltime
=
1181 (EventsRequest
*)iter
->data
;
1183 list_in
= g_slist_append(list_in
, event_request_ltime
);
1184 /* Remove from list_out */
1185 list_out
= g_slist_remove(list_out
, event_request_ltime
);
1190 g_slist_free(ltime
);
1195 tfc
= lttv_traceset_context_get_current_tfc(tsc
);
1196 g_assert(g_slist_length(list_in
)>0);
1197 EventsRequest
*events_request
= g_slist_nth_data(list_in
, 0);
1200 /* 1.2.1 If first request in list_in is a time request */
1201 if(events_request
->start_position
== NULL
) {
1202 /* - If first req in list_in start time != current time */
1203 if(tfc
== NULL
|| ltt_time_compare(events_request
->start_time
,
1204 tfc
->timestamp
) != 0)
1205 /* - Seek to that time */
1206 g_debug("SEEK TIME : %lu, %lu", events_request
->start_time
.tv_sec
,
1207 events_request
->start_time
.tv_nsec
);
1208 //lttv_process_traceset_seek_time(tsc, events_request->start_time);
1209 lttv_state_traceset_seek_time_closest(LTTV_TRACESET_STATE(tsc
),
1210 events_request
->start_time
);
1212 /* Process the traceset with only state hooks */
1214 lttv_process_traceset_middle(tsc
,
1215 events_request
->start_time
,
1218 g_assert(seek_count
< LTTV_STATE_SAVE_INTERVAL
);
1224 LttvTracefileContext
*tfc
=
1225 lttv_traceset_context_get_current_tfc(tsc
);
1226 /* Else, the first request in list_in is a position request */
1227 /* If first req in list_in pos != current pos */
1228 g_assert(events_request
->start_position
!= NULL
);
1229 g_debug("SEEK POS time : %lu, %lu",
1230 lttv_traceset_context_position_get_time(
1231 events_request
->start_position
).tv_sec
,
1232 lttv_traceset_context_position_get_time(
1233 events_request
->start_position
).tv_nsec
);
1236 g_debug("SEEK POS context time : %lu, %lu",
1237 tfc
->timestamp
.tv_sec
,
1238 tfc
->timestamp
.tv_nsec
);
1240 g_debug("SEEK POS context time : %lu, %lu",
1241 ltt_time_infinite
.tv_sec
,
1242 ltt_time_infinite
.tv_nsec
);
1244 g_assert(events_request
->start_position
!= NULL
);
1245 if(lttv_traceset_context_ctx_pos_compare(tsc
,
1246 events_request
->start_position
) != 0) {
1247 /* 1.2.2.1 Seek to that position */
1248 g_debug("SEEK POSITION");
1249 //lttv_process_traceset_seek_position(tsc, events_request->start_position);
1250 pos_time
= lttv_traceset_context_position_get_time(
1251 events_request
->start_position
);
1253 lttv_state_traceset_seek_time_closest(LTTV_TRACESET_STATE(tsc
),
1256 /* Process the traceset with only state hooks */
1258 lttv_process_traceset_middle(tsc
,
1261 events_request
->start_position
);
1262 g_assert(lttv_traceset_context_ctx_pos_compare(tsc
,
1263 events_request
->start_position
) == 0);
1270 /* 1.3 Add hooks and call before request for all list_in members */
1272 GSList
*iter
= NULL
;
1274 for(iter
=list_in
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
1275 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1276 /* 1.3.1 If !servicing */
1277 if(events_request
->servicing
== FALSE
) {
1278 /* - begin request hooks called
1279 * - servicing = TRUE
1281 lttv_hooks_call(events_request
->before_request
, (gpointer
)tsc
);
1282 events_request
->servicing
= TRUE
;
1284 /* 1.3.2 call before chunk
1285 * 1.3.3 events hooks added
1287 if(events_request
->trace
== -1)
1288 lttv_process_traceset_begin(tsc
,
1289 events_request
->before_chunk_traceset
,
1290 events_request
->before_chunk_trace
,
1291 events_request
->before_chunk_tracefile
,
1292 events_request
->event
,
1293 events_request
->event_by_id_channel
);
1295 guint nb_trace
= lttv_traceset_number(tsc
->ts
);
1296 g_assert((guint
)events_request
->trace
< nb_trace
&&
1297 events_request
->trace
> -1);
1298 LttvTraceContext
*tc
= tsc
->traces
[events_request
->trace
];
1300 lttv_hooks_call(events_request
->before_chunk_traceset
, tsc
);
1302 lttv_trace_context_add_hooks(tc
,
1303 events_request
->before_chunk_trace
,
1304 events_request
->before_chunk_tracefile
,
1305 events_request
->event
,
1306 events_request
->event_by_id_channel
);
1311 /* 2. Else, list_in is not empty, we continue a read */
1314 /* 2.0 For each req of list_in */
1315 GSList
*iter
= list_in
;
1317 while(iter
!= NULL
) {
1319 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1321 /* - Call before chunk
1322 * - events hooks added
1324 if(events_request
->trace
== -1)
1325 lttv_process_traceset_begin(tsc
,
1326 events_request
->before_chunk_traceset
,
1327 events_request
->before_chunk_trace
,
1328 events_request
->before_chunk_tracefile
,
1329 events_request
->event
,
1330 events_request
->event_by_id_channel
);
1332 guint nb_trace
= lttv_traceset_number(tsc
->ts
);
1333 g_assert((guint
)events_request
->trace
< nb_trace
&&
1334 events_request
->trace
> -1);
1335 LttvTraceContext
*tc
= tsc
->traces
[events_request
->trace
];
1337 lttv_hooks_call(events_request
->before_chunk_traceset
, tsc
);
1339 lttv_trace_context_add_hooks(tc
,
1340 events_request
->before_chunk_trace
,
1341 events_request
->before_chunk_tracefile
,
1342 events_request
->event
,
1343 events_request
->event_by_id_channel
);
1346 iter
= g_slist_next(iter
);
1351 tfc
= lttv_traceset_context_get_current_tfc(tsc
);
1353 /* 2.1 For each req of list_out */
1354 GSList
*iter
= list_out
;
1356 while(iter
!= NULL
) {
1358 gboolean remove
= FALSE
;
1359 gboolean free_data
= FALSE
;
1360 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1362 /* if req.start time == current context time
1363 * or req.start position == current position*/
1364 if( ltt_time_compare(events_request
->start_time
,
1365 tfc
->timestamp
) == 0
1367 (events_request
->start_position
!= NULL
1369 lttv_traceset_context_ctx_pos_compare(tsc
,
1370 events_request
->start_position
) == 0)
1372 /* - Add to list_in, remove from list_out */
1373 list_in
= g_slist_append(list_in
, events_request
);
1377 /* - If !servicing */
1378 if(events_request
->servicing
== FALSE
) {
1379 /* - begin request hooks called
1380 * - servicing = TRUE
1382 lttv_hooks_call(events_request
->before_request
, (gpointer
)tsc
);
1383 events_request
->servicing
= TRUE
;
1385 /* call before chunk
1386 * events hooks added
1388 if(events_request
->trace
== -1)
1389 lttv_process_traceset_begin(tsc
,
1390 events_request
->before_chunk_traceset
,
1391 events_request
->before_chunk_trace
,
1392 events_request
->before_chunk_tracefile
,
1393 events_request
->event
,
1394 events_request
->event_by_id_channel
);
1396 guint nb_trace
= lttv_traceset_number(tsc
->ts
);
1397 g_assert((guint
)events_request
->trace
< nb_trace
&&
1398 events_request
->trace
> -1);
1399 LttvTraceContext
*tc
= tsc
->traces
[events_request
->trace
];
1401 lttv_hooks_call(events_request
->before_chunk_traceset
, tsc
);
1403 lttv_trace_context_add_hooks(tc
,
1404 events_request
->before_chunk_trace
,
1405 events_request
->before_chunk_tracefile
,
1406 events_request
->event
,
1407 events_request
->event_by_id_channel
);
1416 GSList
*remove_iter
= iter
;
1418 iter
= g_slist_next(iter
);
1419 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
1420 list_out
= g_slist_remove_link(list_out
, remove_iter
);
1421 } else { // not remove
1422 iter
= g_slist_next(iter
);
1428 /* 3. Find end criterions */
1433 /* 3.1.1 Find lowest end time in list_in */
1434 g_assert(g_slist_length(list_in
)>0);
1435 end_time
= ((EventsRequest
*)g_slist_nth_data(list_in
,0))->end_time
;
1437 for(iter
=g_slist_nth(list_in
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
1438 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1440 if(ltt_time_compare(events_request
->end_time
,
1442 end_time
= events_request
->end_time
;
1445 /* 3.1.2 Find lowest start time in list_out */
1446 for(iter
=list_out
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
1447 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1449 if(ltt_time_compare(events_request
->start_time
,
1451 end_time
= events_request
->start_time
;
1456 /* 3.2 Number of events */
1458 /* 3.2.1 Find lowest number of events in list_in */
1461 end_nb_events
= ((EventsRequest
*)g_slist_nth_data(list_in
,0))->num_events
;
1463 for(iter
=g_slist_nth(list_in
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
1464 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1466 if(events_request
->num_events
< end_nb_events
)
1467 end_nb_events
= events_request
->num_events
;
1470 /* 3.2.2 Use min(CHUNK_NUM_EVENTS, min num events in list_in) as
1473 end_nb_events
= MIN(CHUNK_NUM_EVENTS
, end_nb_events
);
1477 /* 3.3 End position */
1479 /* 3.3.1 Find lowest end position in list_in */
1482 end_position
=((EventsRequest
*)g_slist_nth_data(list_in
,0))->end_position
;
1484 for(iter
=g_slist_nth(list_in
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
1485 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1487 if(events_request
->end_position
!= NULL
&& end_position
!= NULL
&&
1488 lttv_traceset_context_pos_pos_compare(events_request
->end_position
,
1490 end_position
= events_request
->end_position
;
1495 /* 3.3.2 Find lowest start position in list_out */
1498 for(iter
=list_out
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
1499 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1501 if(events_request
->end_position
!= NULL
&& end_position
!= NULL
&&
1502 lttv_traceset_context_pos_pos_compare(events_request
->end_position
,
1504 end_position
= events_request
->end_position
;
1509 /* 4. Call process traceset middle */
1510 g_debug("Calling process traceset middle with %p, %lu sec %lu nsec, %u nb ev, %p end pos", tsc
, end_time
.tv_sec
, end_time
.tv_nsec
, end_nb_events
, end_position
);
1511 count
= lttv_process_traceset_middle(tsc
, end_time
, end_nb_events
, end_position
);
1513 tfc
= lttv_traceset_context_get_current_tfc(tsc
);
1515 g_debug("Context time after middle : %lu, %lu", tfc
->timestamp
.tv_sec
,
1516 tfc
->timestamp
.tv_nsec
);
1518 g_debug("End of trace reached after middle.");
1522 /* 5. After process traceset middle */
1523 tfc
= lttv_traceset_context_get_current_tfc(tsc
);
1525 /* - if current context time > traceset.end time */
1526 if(tfc
== NULL
|| ltt_time_compare(tfc
->timestamp
,
1527 tsc
->time_span
.end_time
) > 0) {
1528 /* - For each req in list_in */
1529 GSList
*iter
= list_in
;
1531 while(iter
!= NULL
) {
1533 gboolean remove
= FALSE
;
1534 gboolean free_data
= FALSE
;
1535 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1537 /* - Remove events hooks for req
1538 * - Call end chunk for req
1541 if(events_request
->trace
== -1)
1542 lttv_process_traceset_end(tsc
,
1543 events_request
->after_chunk_traceset
,
1544 events_request
->after_chunk_trace
,
1545 events_request
->after_chunk_tracefile
,
1546 events_request
->event
,
1547 events_request
->event_by_id_channel
);
1550 guint nb_trace
= lttv_traceset_number(tsc
->ts
);
1551 g_assert(events_request
->trace
< nb_trace
&&
1552 events_request
->trace
> -1);
1553 LttvTraceContext
*tc
= tsc
->traces
[events_request
->trace
];
1555 lttv_trace_context_remove_hooks(tc
,
1556 events_request
->after_chunk_trace
,
1557 events_request
->after_chunk_tracefile
,
1558 events_request
->event
,
1559 events_request
->event_by_id_channel
);
1560 lttv_hooks_call(events_request
->after_chunk_traceset
, tsc
);
1565 /* - Call end request for req */
1566 lttv_hooks_call(events_request
->after_request
, (gpointer
)tsc
);
1568 /* - remove req from list_in */
1569 /* Destroy the request */
1576 GSList
*remove_iter
= iter
;
1578 iter
= g_slist_next(iter
);
1579 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
1580 list_in
= g_slist_remove_link(list_in
, remove_iter
);
1581 } else { // not remove
1582 iter
= g_slist_next(iter
);
1587 /* 5.1 For each req in list_in */
1588 GSList
*iter
= list_in
;
1590 while(iter
!= NULL
) {
1592 gboolean remove
= FALSE
;
1593 gboolean free_data
= FALSE
;
1594 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1596 /* - Remove events hooks for req
1597 * - Call end chunk for req
1599 if(events_request
->trace
== -1)
1600 lttv_process_traceset_end(tsc
,
1601 events_request
->after_chunk_traceset
,
1602 events_request
->after_chunk_trace
,
1603 events_request
->after_chunk_tracefile
,
1604 events_request
->event
,
1605 events_request
->event_by_id_channel
);
1608 guint nb_trace
= lttv_traceset_number(tsc
->ts
);
1609 g_assert(events_request
->trace
< nb_trace
&&
1610 events_request
->trace
> -1);
1611 LttvTraceContext
*tc
= tsc
->traces
[events_request
->trace
];
1613 lttv_trace_context_remove_hooks(tc
,
1614 events_request
->after_chunk_trace
,
1615 events_request
->after_chunk_tracefile
,
1616 events_request
->event
,
1617 events_request
->event_by_id_channel
);
1619 lttv_hooks_call(events_request
->after_chunk_traceset
, tsc
);
1622 /* - req.num -= count */
1623 g_assert(events_request
->num_events
>= count
);
1624 events_request
->num_events
-= count
;
1626 g_assert(tfc
!= NULL
);
1627 /* - if req.num == 0
1629 * current context time >= req.end time
1631 * req.end pos == current pos
1633 * req.stop_flag == TRUE
1635 if( events_request
->num_events
== 0
1637 events_request
->stop_flag
== TRUE
1639 ltt_time_compare(tfc
->timestamp
,
1640 events_request
->end_time
) >= 0
1642 (events_request
->end_position
!= NULL
1644 lttv_traceset_context_ctx_pos_compare(tsc
,
1645 events_request
->end_position
) == 0)
1648 g_assert(events_request
->servicing
== TRUE
);
1649 /* - Call end request for req
1650 * - remove req from list_in */
1651 lttv_hooks_call(events_request
->after_request
, (gpointer
)tsc
);
1652 /* - remove req from list_in */
1653 /* Destroy the request */
1661 GSList
*remove_iter
= iter
;
1663 iter
= g_slist_next(iter
);
1664 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
1665 list_in
= g_slist_remove_link(list_in
, remove_iter
);
1666 } else { // not remove
1667 iter
= g_slist_next(iter
);
1673 /* End of removed servicing loop : leave control to GTK instead. */
1674 // if(gtk_events_pending()) break;
1677 /* B. When interrupted between chunks */
1680 GSList
*iter
= list_in
;
1682 /* 1. for each request in list_in */
1683 while(iter
!= NULL
) {
1685 gboolean remove
= FALSE
;
1686 gboolean free_data
= FALSE
;
1687 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1689 /* 1.1. Use current postition as start position */
1690 if(events_request
->start_position
!= NULL
)
1691 lttv_traceset_context_position_destroy(events_request
->start_position
);
1692 events_request
->start_position
= lttv_traceset_context_position_new(tsc
);
1693 lttv_traceset_context_position_save(tsc
, events_request
->start_position
);
1695 /* 1.2. Remove start time */
1696 events_request
->start_time
= ltt_time_infinite
;
1698 /* 1.3. Move from list_in to list_out */
1701 list_out
= g_slist_append(list_out
, events_request
);
1706 GSList
*remove_iter
= iter
;
1708 iter
= g_slist_next(iter
);
1709 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
1710 list_in
= g_slist_remove_link(list_in
, remove_iter
);
1711 } else { // not remove
1712 iter
= g_slist_next(iter
);
1718 /* C Unlock Traces */
1720 lttv_process_traceset_get_sync_data(tsc
);
1721 //lttv_traceset_context_position_save(tsc, sync_position);
1726 iter_trace
<lttv_traceset_number(tsc
->ts
);
1728 LttvTrace
*trace_v
= lttv_traceset_get(tsc
->ts
, iter_trace
);
1730 lttvwindowtraces_unlock(trace_v
);
1734 //set the cursor back to normal
1735 gdk_window_set_cursor(win
, NULL
);
1738 g_assert(g_slist_length(list_in
) == 0);
1740 if( g_slist_length(list_out
) == 0 ) {
1741 /* Put tab's request pending flag back to normal */
1742 tab
->events_request_pending
= FALSE
;
1743 g_debug("remove the idle fct");
1744 return FALSE
; /* Remove the idle function */
1746 g_debug("leave the idle fct");
1747 return TRUE
; /* Leave the idle function */
1749 /* We do not use simili-round-robin, it may require to read 1 meg buffers
1750 * again and again if many tracesets use the same tracefiles. */
1751 /* Hack for round-robin idle functions */
1752 /* It will put the idle function at the end of the pool */
1753 /*g_idle_add_full((G_PRIORITY_HIGH_IDLE + 21),
1754 (GSourceFunc)execute_events_requests,
1764 static void lttvwindow_add_trace(Tab
*tab
, LttvTrace
*trace_v
)
1766 LttvTraceset
*traceset
= tab
->traceset_info
->traceset
;
1768 guint num_traces
= lttv_traceset_number(traceset
);
1770 //Verify if trace is already present.
1771 for(i
=0; i
<num_traces
; i
++)
1773 LttvTrace
* trace
= lttv_traceset_get(traceset
, i
);
1774 if(trace
== trace_v
)
1778 //Keep a reference to the traces so they are not freed.
1779 for(i
=0; i
<lttv_traceset_number(traceset
); i
++)
1781 LttvTrace
* trace
= lttv_traceset_get(traceset
, i
);
1782 lttv_trace_ref(trace
);
1785 //remove state update hooks
1786 lttv_state_remove_event_hooks(
1787 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1789 lttv_context_fini(LTTV_TRACESET_CONTEXT(
1790 tab
->traceset_info
->traceset_context
));
1791 g_object_unref(tab
->traceset_info
->traceset_context
);
1793 lttv_traceset_add(traceset
, trace_v
);
1794 lttv_trace_ref(trace_v
); /* local ref */
1796 /* Create new context */
1797 tab
->traceset_info
->traceset_context
=
1798 g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
1800 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->
1805 //add state update hooks
1806 lttv_state_add_event_hooks(
1807 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1808 //Remove local reference to the traces.
1809 for(i
=0; i
<lttv_traceset_number(traceset
); i
++)
1811 LttvTrace
* trace
= lttv_traceset_get(traceset
, i
);
1812 lttv_trace_unref(trace
);
1816 //add_trace_into_traceset_selector(GTK_MULTIVPANED(tab->multivpaned), lttv_trace(trace_v));
1819 /* add_trace adds a trace into the current traceset. It first displays a
1820 * directory selection dialogue to let user choose a trace, then recreates
1821 * tracset_context, and redraws all the viewer of the current tab
1824 void add_trace(GtkWidget
* widget
, gpointer user_data
)
1827 LttvTrace
* trace_v
;
1828 LttvTraceset
* traceset
;
1830 char abs_path
[PATH_MAX
];
1832 MainWindow
* mw_data
= get_window_data_struct(widget
);
1833 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
1835 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
1836 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
1837 LttvPluginTab
*ptab
;
1841 ptab
= create_new_tab(widget
, NULL
);
1844 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
1848 /* File open dialog management */
1849 GtkFileChooser
* file_chooser
=
1851 gtk_file_chooser_dialog_new ("Select a trace",
1852 GTK_WINDOW(mw_data
->mwindow
),
1853 GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER
,
1854 GTK_STOCK_CANCEL
, GTK_RESPONSE_CANCEL
,
1855 GTK_STOCK_OPEN
, GTK_RESPONSE_ACCEPT
,
1858 gtk_file_chooser_set_show_hidden (file_chooser
, TRUE
);
1859 if(remember_trace_dir
[0] != '\0')
1860 gtk_file_chooser_set_filename(file_chooser
, remember_trace_dir
);
1862 id
= gtk_dialog_run(GTK_DIALOG(file_chooser
));
1865 case GTK_RESPONSE_ACCEPT
:
1866 case GTK_RESPONSE_OK
:
1867 dir
= gtk_file_chooser_get_filename (file_chooser
);
1868 strncpy(remember_trace_dir
, dir
, PATH_MAX
);
1869 strncat(remember_trace_dir
, "/", PATH_MAX
);
1870 if(!dir
|| strlen(dir
) == 0){
1873 get_absolute_pathname(dir
, abs_path
);
1874 trace_v
= lttvwindowtraces_get_trace_by_name(abs_path
);
1875 if(trace_v
== NULL
) {
1876 trace
= ltt_trace_open(abs_path
);
1878 g_warning("cannot open trace %s", abs_path
);
1880 GtkWidget
*dialogue
=
1881 gtk_message_dialog_new(
1882 GTK_WINDOW(gtk_widget_get_toplevel(widget
)),
1883 GTK_DIALOG_MODAL
|GTK_DIALOG_DESTROY_WITH_PARENT
,
1886 "Cannot open trace : maybe you should enter in the trace "
1887 "directory to select it ?");
1888 gtk_dialog_run(GTK_DIALOG(dialogue
));
1889 gtk_widget_destroy(dialogue
);
1892 trace_v
= lttv_trace_new(trace
);
1893 lttvwindowtraces_add_trace(trace_v
);
1894 lttvwindow_add_trace(tab
, trace_v
);
1897 lttvwindow_add_trace(tab
, trace_v
);
1901 //update current tab
1902 //update_traceset(mw_data);
1904 /* Call the updatetraceset hooks */
1906 traceset
= tab
->traceset_info
->traceset
;
1907 SetTraceset(tab
, traceset
);
1908 // in expose now call_pending_read_hooks(mw_data);
1910 //lttvwindow_report_current_time(mw_data,&(tab->current_time));
1912 case GTK_RESPONSE_REJECT
:
1913 case GTK_RESPONSE_CANCEL
:
1917 gtk_widget_destroy((GtkWidget
*)file_chooser
);
1921 /* remove_trace removes a trace from the current traceset if all viewers in
1922 * the current tab are not interested in the trace. It first displays a
1923 * dialogue, which shows all traces in the current traceset, to let user choose
1924 * a trace, then it checks if all viewers unselect the trace, if it is true,
1925 * it will remove the trace, recreate the traceset_contex,
1926 * and redraws all the viewer of the current tab. If there is on trace in the
1927 * current traceset, it will delete all viewers of the current tab
1929 * It destroys the filter tree. FIXME... we should request for an update
1933 void remove_trace(GtkWidget
*widget
, gpointer user_data
)
1936 LttvTrace
* trace_v
;
1937 LttvTraceset
* traceset
;
1938 gint i
, j
, nb_trace
, index
=-1;
1939 char ** name
, *remove_trace_name
;
1940 MainWindow
* mw_data
= get_window_data_struct(widget
);
1941 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
1943 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
1944 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
1950 LttvPluginTab
*ptab
;
1951 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
1955 nb_trace
=lttv_traceset_number(tab
->traceset_info
->traceset
);
1956 name
= g_new(char*,nb_trace
);
1957 for(i
= 0; i
< nb_trace
; i
++){
1958 trace_v
= lttv_traceset_get(tab
->traceset_info
->traceset
, i
);
1959 trace
= lttv_trace(trace_v
);
1960 name
[i
] = g_quark_to_string(ltt_trace_name(trace
));
1963 remove_trace_name
= get_remove_trace(mw_data
, name
, nb_trace
);
1966 if(remove_trace_name
){
1968 /* yuk, cut n paste from old code.. should be better (MD)*/
1969 for(i
= 0; i
<nb_trace
; i
++) {
1970 if(strcmp(remove_trace_name
,name
[i
]) == 0){
1975 traceset
= tab
->traceset_info
->traceset
;
1976 //Keep a reference to the traces so they are not freed.
1977 for(j
=0; j
<lttv_traceset_number(traceset
); j
++)
1979 LttvTrace
* trace
= lttv_traceset_get(traceset
, j
);
1980 lttv_trace_ref(trace
);
1983 //remove state update hooks
1984 lttv_state_remove_event_hooks(
1985 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1986 lttv_context_fini(LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
));
1987 g_object_unref(tab
->traceset_info
->traceset_context
);
1989 trace_v
= lttv_traceset_get(traceset
, index
);
1991 lttv_traceset_remove(traceset
, index
);
1992 lttv_trace_unref(trace_v
); // Remove local reference
1994 if(lttv_trace_get_ref_number(trace_v
) <= 1) {
1995 /* ref 1 : lttvwindowtraces only*/
1996 ltt_trace_close(lttv_trace(trace_v
));
1997 /* lttvwindowtraces_remove_trace takes care of destroying
1998 * the traceset linked with the trace_v and also of destroying
1999 * the trace_v at the same time.
2001 lttvwindowtraces_remove_trace(trace_v
);
2004 tab
->traceset_info
->traceset_context
=
2005 g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
2007 LTTV_TRACESET_CONTEXT(tab
->
2008 traceset_info
->traceset_context
),traceset
);
2009 //add state update hooks
2010 lttv_state_add_event_hooks(
2011 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
2013 //Remove local reference to the traces.
2014 for(j
=0; j
<lttv_traceset_number(traceset
); j
++)
2016 LttvTrace
* trace
= lttv_traceset_get(traceset
, j
);
2017 lttv_trace_unref(trace
);
2020 SetTraceset(tab
, (gpointer
)traceset
);
2026 void remove_trace(GtkWidget
* widget
, gpointer user_data
)
2029 LttvTrace
* trace_v
;
2030 LttvTraceset
* traceset
;
2031 gint i
, j
, nb_trace
;
2032 char ** name
, *remove_trace_name
;
2033 MainWindow
* mw_data
= get_window_data_struct(widget
);
2034 LttvTracesetSelector
* s
;
2035 LttvTraceSelector
* t
;
2038 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
2040 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2041 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2047 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
2050 nb_trace
=lttv_traceset_number(tab
->traceset_info
->traceset
);
2051 name
= g_new(char*,nb_trace
);
2052 for(i
= 0; i
< nb_trace
; i
++){
2053 trace_v
= lttv_traceset_get(tab
->traceset_info
->traceset
, i
);
2054 trace
= lttv_trace(trace_v
);
2055 name
[i
] = ltt_trace_name(trace
);
2058 remove_trace_name
= get_remove_trace(name
, nb_trace
);
2060 if(remove_trace_name
){
2061 for(i
=0; i
<nb_trace
; i
++){
2062 if(strcmp(remove_trace_name
,name
[i
]) == 0){
2063 //unselect the trace from the current viewer
2065 w
= gtk_multivpaned_get_widget(GTK_MULTIVPANED(tab
->multivpaned
));
2067 s
= g_object_get_data(G_OBJECT(w
), "Traceset_Selector");
2069 t
= lttv_traceset_selector_trace_get(s
,i
);
2070 lttv_trace_selector_set_selected(t
, FALSE
);
2073 //check if other viewers select the trace
2074 w
= gtk_multivpaned_get_first_widget(GTK_MULTIVPANED(tab
->multivpaned
));
2076 s
= g_object_get_data(G_OBJECT(w
), "Traceset_Selector");
2078 t
= lttv_traceset_selector_trace_get(s
,i
);
2079 selected
= lttv_trace_selector_get_selected(t
);
2082 w
= gtk_multivpaned_get_next_widget(GTK_MULTIVPANED(tab
->multivpaned
));
2084 }else selected
= FALSE
;
2086 //if no viewer selects the trace, remove it
2088 remove_trace_from_traceset_selector(GTK_MULTIVPANED(tab
->multivpaned
), i
);
2090 traceset
= tab
->traceset_info
->traceset
;
2091 //Keep a reference to the traces so they are not freed.
2092 for(j
=0; j
<lttv_traceset_number(traceset
); j
++)
2094 LttvTrace
* trace
= lttv_traceset_get(traceset
, j
);
2095 lttv_trace_ref(trace
);
2098 //remove state update hooks
2099 lttv_state_remove_event_hooks(
2100 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
2101 lttv_context_fini(LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
));
2102 g_object_unref(tab
->traceset_info
->traceset_context
);
2105 trace_v
= lttv_traceset_get(traceset
, i
);
2107 if(lttv_trace_get_ref_number(trace_v
) <= 2) {
2108 /* ref 2 : traceset, local */
2109 lttvwindowtraces_remove_trace(trace_v
);
2110 ltt_trace_close(lttv_trace(trace_v
));
2113 lttv_traceset_remove(traceset
, i
);
2114 lttv_trace_unref(trace_v
); // Remove local reference
2116 if(!lttv_trace_get_ref_number(trace_v
))
2117 lttv_trace_destroy(trace_v
);
2119 tab
->traceset_info
->traceset_context
=
2120 g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
2122 LTTV_TRACESET_CONTEXT(tab
->
2123 traceset_info
->traceset_context
),traceset
);
2124 //add state update hooks
2125 lttv_state_add_event_hooks(
2126 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
2128 //Remove local reference to the traces.
2129 for(j
=0; j
<lttv_traceset_number(traceset
); j
++)
2131 LttvTrace
* trace
= lttv_traceset_get(traceset
, j
);
2132 lttv_trace_unref(trace
);
2136 //update current tab
2137 //update_traceset(mw_data);
2140 SetTraceset(tab
, (gpointer
)traceset
);
2141 // in expose now call_pending_read_hooks(mw_data);
2143 //lttvwindow_report_current_time(mw_data,&(tab->current_time));
2146 // while(tab->multi_vpaned->num_children){
2147 // gtk_multi_vpaned_widget_delete(tab->multi_vpaned);
2161 /* Redraw all the viewers in the current tab */
2162 void redraw(GtkWidget
*widget
, gpointer user_data
)
2164 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
2165 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2166 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2173 LttvPluginTab
*ptab
;
2174 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
2179 LttvAttributeValue value
;
2181 retval
= lttv_iattribute_find_by_path(tab
->attributes
, "hooks/redraw", LTTV_POINTER
, &value
);
2184 tmp
= (LttvHooks
*)*(value
.v_pointer
);
2186 lttv_hooks_call(tmp
,NULL
);
2190 void continue_processing(GtkWidget
*widget
, gpointer user_data
)
2192 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
2193 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2194 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2201 LttvPluginTab
*ptab
;
2202 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
2207 LttvAttributeValue value
;
2209 retval
= lttv_iattribute_find_by_path(tab
->attributes
, "hooks/continue",
2210 LTTV_POINTER
, &value
);
2213 tmp
= (LttvHooks
*)*(value
.v_pointer
);
2215 lttv_hooks_call(tmp
,NULL
);
2218 /* Stop the processing for the calling main window's current tab.
2219 * It removes every processing requests that are in its list. It does not call
2220 * the end request hooks, because the request is not finished.
2223 void stop_processing(GtkWidget
*widget
, gpointer user_data
)
2225 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
2226 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2227 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2232 LttvPluginTab
*ptab
;
2233 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
2236 GSList
*iter
= tab
->events_requests
;
2238 while(iter
!= NULL
) {
2239 GSList
*remove_iter
= iter
;
2240 iter
= g_slist_next(iter
);
2242 g_free(remove_iter
->data
);
2243 tab
->events_requests
=
2244 g_slist_remove_link(tab
->events_requests
, remove_iter
);
2246 tab
->events_request_pending
= FALSE
;
2247 tab
->stop_foreground
= TRUE
;
2248 g_idle_remove_by_data(tab
);
2249 g_assert(g_slist_length(tab
->events_requests
) == 0);
2253 /* save will save the traceset to a file
2254 * Not implemented yet FIXME
2257 void save(GtkWidget
* widget
, gpointer user_data
)
2262 void save_as(GtkWidget
* widget
, gpointer user_data
)
2264 g_info("Save as\n");
2268 /* zoom will change the time_window of all the viewers of the
2269 * current tab, and redisplay them. The main functionality is to
2270 * determine the new time_window of the current tab
2273 void zoom(GtkWidget
* widget
, double size
)
2275 TimeInterval time_span
;
2276 TimeWindow new_time_window
;
2277 LttTime current_time
, time_delta
;
2278 MainWindow
* mw_data
= get_window_data_struct(widget
);
2279 LttvTracesetContext
*tsc
;
2280 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
2282 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2283 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2289 LttvPluginTab
*ptab
;
2290 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
2294 if(size
== 1) return;
2296 tsc
= LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
2297 time_span
= tsc
->time_span
;
2298 new_time_window
= tab
->time_window
;
2299 current_time
= tab
->current_time
;
2301 time_delta
= ltt_time_sub(time_span
.end_time
,time_span
.start_time
);
2303 new_time_window
.start_time
= time_span
.start_time
;
2304 new_time_window
.time_width
= time_delta
;
2305 new_time_window
.time_width_double
= ltt_time_to_double(time_delta
);
2306 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
2307 new_time_window
.time_width
) ;
2309 new_time_window
.time_width
= ltt_time_div(new_time_window
.time_width
, size
);
2310 new_time_window
.time_width_double
=
2311 ltt_time_to_double(new_time_window
.time_width
);
2312 if(ltt_time_compare(new_time_window
.time_width
,time_delta
) > 0)
2313 { /* Case where zoom out is bigger than trace length */
2314 new_time_window
.start_time
= time_span
.start_time
;
2315 new_time_window
.time_width
= time_delta
;
2316 new_time_window
.time_width_double
= ltt_time_to_double(time_delta
);
2317 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
2318 new_time_window
.time_width
) ;
2322 /* Center the image on the current time */
2323 new_time_window
.start_time
=
2324 ltt_time_sub(current_time
,
2325 ltt_time_from_double(new_time_window
.time_width_double
/2.0));
2326 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
2327 new_time_window
.time_width
) ;
2328 /* If on borders, don't fall off */
2329 if(ltt_time_compare(new_time_window
.start_time
, time_span
.start_time
) <0
2330 || ltt_time_compare(new_time_window
.start_time
, time_span
.end_time
) >0)
2332 new_time_window
.start_time
= time_span
.start_time
;
2333 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
2334 new_time_window
.time_width
) ;
2338 if(ltt_time_compare(new_time_window
.end_time
,
2339 time_span
.end_time
) > 0
2340 || ltt_time_compare(new_time_window
.end_time
,
2341 time_span
.start_time
) < 0)
2343 new_time_window
.start_time
=
2344 ltt_time_sub(time_span
.end_time
, new_time_window
.time_width
);
2346 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
2347 new_time_window
.time_width
) ;
2354 if(ltt_time_compare(new_time_window
.time_width
, ltt_time_zero
) == 0) {
2355 g_warning("Zoom more than 1 ns impossible");
2357 time_change_manager(tab
, new_time_window
);
2361 void zoom_in(GtkWidget
* widget
, gpointer user_data
)
2366 void zoom_out(GtkWidget
* widget
, gpointer user_data
)
2371 void zoom_extended(GtkWidget
* widget
, gpointer user_data
)
2376 void go_to_time(GtkWidget
* widget
, gpointer user_data
)
2378 g_info("Go to time\n");
2381 void show_time_frame(GtkWidget
* widget
, gpointer user_data
)
2383 g_info("Show time frame\n");
2387 /* callback function */
2390 on_empty_traceset_activate (GtkMenuItem
*menuitem
,
2393 create_new_window((GtkWidget
*)menuitem
, user_data
, FALSE
);
2398 on_clone_traceset_activate (GtkMenuItem
*menuitem
,
2401 create_new_window((GtkWidget
*)menuitem
, user_data
, TRUE
);
2405 /* create_new_tab calls create_tab to construct a new tab in the main window
2408 LttvPluginTab
*create_new_tab(GtkWidget
* widget
, gpointer user_data
)
2410 gchar label
[PATH_MAX
];
2411 MainWindow
* mw_data
= get_window_data_struct(widget
);
2413 GtkNotebook
* notebook
= (GtkNotebook
*)lookup_widget(widget
, "MNotebook");
2414 if(notebook
== NULL
){
2415 g_info("Notebook does not exist\n");
2418 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2419 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2425 LttvPluginTab
*ptab
;
2426 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
2427 copy_tab
= ptab
->tab
;
2430 strcpy(label
,"Page");
2431 if(get_label(mw_data
, label
,"Get the name of the tab","Please input tab's name")) {
2432 LttvPluginTab
*ptab
;
2434 ptab
= g_object_new(LTTV_TYPE_PLUGIN_TAB
, NULL
);
2435 init_tab (ptab
->tab
, mw_data
, copy_tab
, notebook
, label
);
2436 ptab
->parent
.top_widget
= ptab
->tab
->top_widget
;
2437 g_object_set_data_full(
2438 G_OBJECT(ptab
->tab
->vbox
),
2441 (GDestroyNotify
)tab_destructor
);
2448 on_tab_activate (GtkMenuItem
*menuitem
,
2451 create_new_tab((GtkWidget
*)menuitem
, user_data
);
2456 on_open_activate (GtkMenuItem
*menuitem
,
2459 open_traceset((GtkWidget
*)menuitem
, user_data
);
2464 on_close_activate (GtkMenuItem
*menuitem
,
2467 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2468 main_window_destructor(mw_data
);
2472 /* remove the current tab from the main window
2476 on_close_tab_activate (GtkWidget
*widget
,
2480 GtkWidget
* notebook
;
2482 MainWindow
* mw_data
= get_window_data_struct(widget
);
2483 notebook
= lookup_widget(widget
, "MNotebook");
2484 if(notebook
== NULL
){
2485 g_info("Notebook does not exist\n");
2489 page_num
= gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
));
2491 gtk_notebook_remove_page(GTK_NOTEBOOK(notebook
), page_num
);
2496 on_close_tab_X_clicked (GtkWidget
*widget
,
2500 GtkWidget
*notebook
= lookup_widget(widget
, "MNotebook");
2501 if(notebook
== NULL
){
2502 g_info("Notebook does not exist\n");
2506 if((page_num
= gtk_notebook_page_num(GTK_NOTEBOOK(notebook
), widget
)) != -1)
2507 gtk_notebook_remove_page(GTK_NOTEBOOK(notebook
), page_num
);
2513 on_add_trace_activate (GtkMenuItem
*menuitem
,
2516 add_trace((GtkWidget
*)menuitem
, user_data
);
2521 on_remove_trace_activate (GtkMenuItem
*menuitem
,
2524 remove_trace((GtkWidget
*)menuitem
, user_data
);
2529 on_save_activate (GtkMenuItem
*menuitem
,
2532 save((GtkWidget
*)menuitem
, user_data
);
2537 on_save_as_activate (GtkMenuItem
*menuitem
,
2540 save_as((GtkWidget
*)menuitem
, user_data
);
2545 on_quit_activate (GtkMenuItem
*menuitem
,
2548 while (g_slist_length(g_main_window_list
) != 0) {
2549 on_MWindow_destroy(((MainWindow
*)g_main_window_list
->data
)->mwindow
,
2556 on_cut_activate (GtkMenuItem
*menuitem
,
2564 on_copy_activate (GtkMenuItem
*menuitem
,
2572 on_paste_activate (GtkMenuItem
*menuitem
,
2580 on_delete_activate (GtkMenuItem
*menuitem
,
2588 on_zoom_in_activate (GtkMenuItem
*menuitem
,
2591 zoom_in((GtkWidget
*)menuitem
, user_data
);
2596 on_zoom_out_activate (GtkMenuItem
*menuitem
,
2599 zoom_out((GtkWidget
*)menuitem
, user_data
);
2604 on_zoom_extended_activate (GtkMenuItem
*menuitem
,
2607 zoom_extended((GtkWidget
*)menuitem
, user_data
);
2612 on_go_to_time_activate (GtkMenuItem
*menuitem
,
2615 go_to_time((GtkWidget
*)menuitem
, user_data
);
2620 on_show_time_frame_activate (GtkMenuItem
*menuitem
,
2623 show_time_frame((GtkWidget
*)menuitem
, user_data
);
2628 on_move_viewer_up_activate (GtkMenuItem
*menuitem
,
2631 move_up_viewer((GtkWidget
*)menuitem
, user_data
);
2636 on_move_viewer_down_activate (GtkMenuItem
*menuitem
,
2639 move_down_viewer((GtkWidget
*)menuitem
, user_data
);
2644 on_remove_viewer_activate (GtkMenuItem
*menuitem
,
2647 delete_viewer((GtkWidget
*)menuitem
, user_data
);
2651 on_trace_facility_activate (GtkMenuItem
*menuitem
,
2654 g_info("Trace facility selector: %s\n", "");
2658 /* Dispaly a file selection dialogue to let user select a library, then call
2659 * lttv_library_load().
2663 on_load_library_activate (GtkMenuItem
*menuitem
,
2666 GError
*error
= NULL
;
2667 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2669 gchar load_module_path_alter
[PATH_MAX
];
2673 gchar
*load_module_path
;
2674 name
= g_ptr_array_new();
2675 nb
= lttv_library_path_number();
2676 /* ask for the library path */
2680 path
= lttv_library_path_get(i
);
2681 g_ptr_array_add(name
, path
);
2684 load_module_path
= get_selection(mw_data
,
2685 (char **)(name
->pdata
), name
->len
,
2686 "Select a library path", "Library paths");
2687 if(load_module_path
!= NULL
)
2688 strncpy(load_module_path_alter
, load_module_path
, PATH_MAX
-1); // -1 for /
2690 g_ptr_array_free(name
, TRUE
);
2692 if(load_module_path
== NULL
) return;
2696 /* Make sure the module path ends with a / */
2697 gchar
*ptr
= load_module_path_alter
;
2699 ptr
= strchr(ptr
, '\0');
2701 if(*(ptr
-1) != '/') {
2708 /* Ask for the library to load : list files in the previously selected
2710 gchar str
[PATH_MAX
];
2713 GtkFileSelection
* file_selector
=
2714 (GtkFileSelection
*)gtk_file_selection_new("Select a module");
2715 gtk_file_selection_set_filename(file_selector
, load_module_path_alter
);
2716 gtk_file_selection_hide_fileop_buttons(file_selector
);
2718 gtk_window_set_transient_for(GTK_WINDOW(file_selector
),
2719 GTK_WINDOW(mw_data
->mwindow
));
2722 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
2724 case GTK_RESPONSE_ACCEPT
:
2725 case GTK_RESPONSE_OK
:
2726 dir
= gtk_file_selection_get_selections (file_selector
);
2727 strncpy(str
,dir
[0],PATH_MAX
);
2728 strncpy(remember_plugins_dir
,dir
[0],PATH_MAX
);
2729 /* only keep file name */
2731 str1
= strrchr(str
,'/');
2734 str1
= strrchr(str
,'\\');
2739 if(*str1
== 'l' && *(str1
+1)== 'i' && *(str1
+2)=='b')
2741 remove info after
. */
2745 str2
= strrchr(str2
, '.');
2746 if(str2
!= NULL
) *str2
= '\0';
2748 lttv_module_require(str1
, &error
);
2750 lttv_library_load(str1
, &error
);
2751 if(error
!= NULL
) g_warning("%s", error
->message
);
2752 else g_info("Load library: %s\n", str
);
2754 case GTK_RESPONSE_REJECT
:
2755 case GTK_RESPONSE_CANCEL
:
2757 gtk_widget_destroy((GtkWidget
*)file_selector
);
2768 /* Display all loaded modules, let user to select a module to unload
2769 * by calling lttv_module_unload
2773 on_unload_library_activate (GtkMenuItem
*menuitem
,
2776 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2778 LttvLibrary
*library
= NULL
;
2783 name
= g_ptr_array_new();
2784 nb
= lttv_library_number();
2785 LttvLibraryInfo
*lib_info
= g_new(LttvLibraryInfo
,nb
);
2786 /* ask for the library name */
2789 LttvLibrary
*iter_lib
= lttv_library_get(i
);
2790 lttv_library_info(iter_lib
, &lib_info
[i
]);
2792 gchar
*path
= lib_info
[i
].name
;
2793 g_ptr_array_add(name
, path
);
2795 lib_name
= get_selection(mw_data
, (char **)(name
->pdata
), name
->len
,
2796 "Select a library", "Libraries");
2797 if(lib_name
!= NULL
) {
2799 if(strcmp(lib_name
, lib_info
[i
].name
) == 0) {
2800 library
= lttv_library_get(i
);
2805 g_ptr_array_free(name
, TRUE
);
2808 if(lib_name
== NULL
) return;
2810 if(library
!= NULL
) lttv_library_unload(library
);
2814 /* Dispaly a file selection dialogue to let user select a module, then call
2815 * lttv_module_require().
2819 on_load_module_activate (GtkMenuItem
*menuitem
,
2822 GError
*error
= NULL
;
2823 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2825 LttvLibrary
*library
= NULL
;
2830 name
= g_ptr_array_new();
2831 nb
= lttv_library_number();
2832 LttvLibraryInfo
*lib_info
= g_new(LttvLibraryInfo
,nb
);
2833 /* ask for the library name */
2836 LttvLibrary
*iter_lib
= lttv_library_get(i
);
2837 lttv_library_info(iter_lib
, &lib_info
[i
]);
2839 gchar
*path
= lib_info
[i
].name
;
2840 g_ptr_array_add(name
, path
);
2842 lib_name
= get_selection(mw_data
,(char **)(name
->pdata
), name
->len
,
2843 "Select a library", "Libraries");
2844 if(lib_name
!= NULL
) {
2846 if(strcmp(lib_name
, lib_info
[i
].name
) == 0) {
2847 library
= lttv_library_get(i
);
2852 g_ptr_array_free(name
, TRUE
);
2855 if(lib_name
== NULL
) return;
2858 //LttvModule *module;
2859 gchar module_name_out
[PATH_MAX
];
2861 /* Ask for the module to load : list modules in the selected lib */
2865 nb
= lttv_library_module_number(library
);
2866 LttvModuleInfo
*module_info
= g_new(LttvModuleInfo
,nb
);
2867 name
= g_ptr_array_new();
2868 /* ask for the module name */
2871 LttvModule
*iter_module
= lttv_library_module_get(library
, i
);
2872 lttv_module_info(iter_module
, &module_info
[i
]);
2874 gchar
*path
= module_info
[i
].name
;
2875 g_ptr_array_add(name
, path
);
2877 module_name
= get_selection(mw_data
, (char **)(name
->pdata
), name
->len
,
2878 "Select a module", "Modules");
2879 if(module_name
!= NULL
) {
2881 if(strcmp(module_name
, module_info
[i
].name
) == 0) {
2882 strncpy(module_name_out
, module_name
, PATH_MAX
);
2883 //module = lttv_library_module_get(i);
2889 g_ptr_array_free(name
, TRUE
);
2890 g_free(module_info
);
2892 if(module_name
== NULL
) return;
2895 lttv_module_require(module_name_out
, &error
);
2896 if(error
!= NULL
) g_warning("%s", error
->message
);
2897 else g_info("Load module: %s", module_name_out
);
2904 gchar str
[PATH_MAX
];
2907 GtkFileSelection
* file_selector
=
2908 (GtkFileSelection
*)gtk_file_selection_new("Select a module");
2909 gtk_file_selection_set_filename(file_selector
, load_module_path_alter
);
2910 gtk_file_selection_hide_fileop_buttons(file_selector
);
2913 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
2915 case GTK_RESPONSE_ACCEPT
:
2916 case GTK_RESPONSE_OK
:
2917 dir
= gtk_file_selection_get_selections (file_selector
);
2918 strncpy(str
,dir
[0],PATH_MAX
);
2919 strncpy(remember_plugins_dir
,dir
[0],PATH_MAX
);
2921 /* only keep file name */
2923 str1
= strrchr(str
,'/');
2926 str1
= strrchr(str
,'\\');
2931 if(*str1
== 'l' && *(str1
+1)== 'i' && *(str1
+2)=='b')
2933 remove info after
. */
2937 str2
= strrchr(str2
, '.');
2938 if(str2
!= NULL
) *str2
= '\0';
2940 lttv_module_require(str1
, &error
);
2942 lttv_library_load(str1
, &error
);
2943 if(error
!= NULL
) g_warning(error
->message
);
2944 else g_info("Load library: %s\n", str
);
2946 case GTK_RESPONSE_REJECT
:
2947 case GTK_RESPONSE_CANCEL
:
2949 gtk_widget_destroy((GtkWidget
*)file_selector
);
2961 /* Display all loaded modules, let user to select a module to unload
2962 * by calling lttv_module_unload
2966 on_unload_module_activate (GtkMenuItem
*menuitem
,
2969 GError
*error
= NULL
;
2970 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2972 LttvLibrary
*library
= NULL
;
2977 name
= g_ptr_array_new();
2978 nb
= lttv_library_number();
2979 LttvLibraryInfo
*lib_info
= g_new(LttvLibraryInfo
,nb
);
2980 /* ask for the library name */
2983 LttvLibrary
*iter_lib
= lttv_library_get(i
);
2984 lttv_library_info(iter_lib
, &lib_info
[i
]);
2986 gchar
*path
= lib_info
[i
].name
;
2987 g_ptr_array_add(name
, path
);
2989 lib_name
= get_selection(mw_data
, (char **)(name
->pdata
), name
->len
,
2990 "Select a library", "Libraries");
2991 if(lib_name
!= NULL
) {
2993 if(strcmp(lib_name
, lib_info
[i
].name
) == 0) {
2994 library
= lttv_library_get(i
);
2999 g_ptr_array_free(name
, TRUE
);
3002 if(lib_name
== NULL
) return;
3005 LttvModule
*module
= NULL
;
3007 /* Ask for the module to load : list modules in the selected lib */
3011 nb
= lttv_library_module_number(library
);
3012 LttvModuleInfo
*module_info
= g_new(LttvModuleInfo
,nb
);
3013 name
= g_ptr_array_new();
3014 /* ask for the module name */
3017 LttvModule
*iter_module
= lttv_library_module_get(library
, i
);
3018 lttv_module_info(iter_module
, &module_info
[i
]);
3020 gchar
*path
= module_info
[i
].name
;
3021 if(module_info
[i
].use_count
> 0) g_ptr_array_add(name
, path
);
3023 module_name
= get_selection(mw_data
, (char **)(name
->pdata
), name
->len
,
3024 "Select a module", "Modules");
3025 if(module_name
!= NULL
) {
3027 if(strcmp(module_name
, module_info
[i
].name
) == 0) {
3028 module
= lttv_library_module_get(library
, i
);
3034 g_ptr_array_free(name
, TRUE
);
3035 g_free(module_info
);
3037 if(module_name
== NULL
) return;
3040 LttvModuleInfo module_info
;
3041 lttv_module_info(module
, &module_info
);
3042 g_info("Release module: %s\n", module_info
.name
);
3044 lttv_module_release(module
);
3048 /* Display a directory dialogue to let user select a path for library searching
3052 on_add_library_search_path_activate (GtkMenuItem
*menuitem
,
3055 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
3056 //GtkDirSelection * file_selector = (GtkDirSelection *)gtk_dir_selection_new("Select library path");
3057 GtkFileSelection
* file_selector
= (GtkFileSelection
*)gtk_file_selection_new("Select a trace");
3058 gtk_widget_hide( (file_selector
)->file_list
->parent
) ;
3060 gtk_window_set_transient_for(GTK_WINDOW(file_selector
),
3061 GTK_WINDOW(mw_data
->mwindow
));
3066 if(remember_plugins_dir
[0] != '\0')
3067 gtk_file_selection_set_filename(file_selector
, remember_plugins_dir
);
3069 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
3071 case GTK_RESPONSE_ACCEPT
:
3072 case GTK_RESPONSE_OK
:
3073 dir
= gtk_file_selection_get_filename (file_selector
);
3074 strncpy(remember_plugins_dir
,dir
,PATH_MAX
);
3075 strncat(remember_plugins_dir
,"/",PATH_MAX
);
3076 lttv_library_path_add(dir
);
3077 case GTK_RESPONSE_REJECT
:
3078 case GTK_RESPONSE_CANCEL
:
3080 gtk_widget_destroy((GtkWidget
*)file_selector
);
3086 /* Display a directory dialogue to let user select a path for library searching
3090 on_remove_library_search_path_activate (GtkMenuItem
*menuitem
,
3093 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
3095 const char *lib_path
;
3100 name
= g_ptr_array_new();
3101 nb
= lttv_library_path_number();
3102 /* ask for the library name */
3105 gchar
*path
= lttv_library_path_get(i
);
3106 g_ptr_array_add(name
, path
);
3108 lib_path
= get_selection(mw_data
, (char **)(name
->pdata
), name
->len
,
3109 "Select a library path", "Library paths");
3111 g_ptr_array_free(name
, TRUE
);
3113 if(lib_path
== NULL
) return;
3116 lttv_library_path_remove(lib_path
);
3120 on_color_activate (GtkMenuItem
*menuitem
,
3128 on_save_configuration_activate (GtkMenuItem
*menuitem
,
3131 g_info("Save configuration\n");
3136 on_content_activate (GtkMenuItem
*menuitem
,
3139 g_info("Content\n");
3144 on_about_close_activate (GtkButton
*button
,
3147 GtkWidget
*about_widget
= GTK_WIDGET(user_data
);
3149 gtk_widget_destroy(about_widget
);
3153 on_about_activate (GtkMenuItem
*menuitem
,
3156 MainWindow
*main_window
= get_window_data_struct(GTK_WIDGET(menuitem
));
3157 GtkWidget
*window_widget
= main_window
->mwindow
;
3158 GtkWidget
*about_widget
= gtk_window_new(GTK_WINDOW_TOPLEVEL
);
3159 GtkWindow
*about_window
= GTK_WINDOW(about_widget
);
3160 gint window_width
, window_height
;
3162 gtk_window_set_title(about_window
, "About Linux Trace Toolkit");
3164 gtk_window_set_resizable(about_window
, FALSE
);
3165 gtk_window_set_transient_for(about_window
, GTK_WINDOW(window_widget
));
3166 gtk_window_set_destroy_with_parent(about_window
, TRUE
);
3167 gtk_window_set_modal(about_window
, FALSE
);
3169 /* Put the about window at the center of the screen */
3170 gtk_window_get_size(about_window
, &window_width
, &window_height
);
3171 gtk_window_move (about_window
,
3172 (gdk_screen_width() - window_width
)/2,
3173 (gdk_screen_height() - window_height
)/2);
3175 GtkWidget
*vbox
= gtk_vbox_new(FALSE
, 1);
3177 gtk_container_add(GTK_CONTAINER(about_widget
), vbox
);
3181 GtkWidget
*label1
= gtk_label_new("");
3182 gtk_misc_set_padding(GTK_MISC(label1
), 10, 20);
3183 gtk_label_set_markup(GTK_LABEL(label1
), "\
3184 <big>Linux Trace Toolkit " VERSION
"</big>");
3185 gtk_label_set_justify(GTK_LABEL(label1
), GTK_JUSTIFY_CENTER
);
3187 GtkWidget
*label2
= gtk_label_new("");
3188 gtk_misc_set_padding(GTK_MISC(label2
), 10, 20);
3189 gtk_label_set_markup(GTK_LABEL(label2
), "\
3192 Michel Dagenais (New trace format, lttv main)\n\
3193 Mathieu Desnoyers (Kernel Tracer, Directory structure, build with automake/conf,\n\
3194 lttv gui, control flow view, gui cooperative trace reading\n\
3195 scheduler with interruptible foreground and background\n\
3196 computation, detailed event list (rewrite), trace reading\n\
3197 library (rewrite))\n\
3198 Benoit Des Ligneris, Eric Clement (Cluster adaptation, work in progress)\n\
3199 Xang-Xiu Yang (new trace reading library and converter, lttv gui, \n\
3200 detailed event list and statistics view)\n\
3201 Tom Zanussi (RelayFS)\n\
3203 Inspired from the original Linux Trace Toolkit Visualizer made by\n\
3206 GtkWidget
*label3
= gtk_label_new("");
3207 gtk_label_set_markup(GTK_LABEL(label3
), "\
3208 Linux Trace Toolkit Viewer, Copyright (C) 2004, 2005, 2006\n\
3210 Mathieu Desnoyers\n\
3212 Linux Trace Toolkit comes with ABSOLUTELY NO WARRANTY.\n\
3213 This is free software, and you are welcome to redistribute it\n\
3214 under certain conditions. See COPYING for details.");
3215 gtk_misc_set_padding(GTK_MISC(label3
), 10, 20);
3217 gtk_box_pack_start_defaults(GTK_BOX(vbox
), label1
);
3218 gtk_box_pack_start_defaults(GTK_BOX(vbox
), label2
);
3219 gtk_box_pack_start_defaults(GTK_BOX(vbox
), label3
);
3221 GtkWidget
*hbox
= gtk_hbox_new(TRUE
, 0);
3222 gtk_box_pack_end(GTK_BOX(vbox
), hbox
, FALSE
, FALSE
, 0);
3223 GtkWidget
*close_button
= gtk_button_new_with_mnemonic("_Close");
3224 gtk_box_pack_end(GTK_BOX(hbox
), close_button
, FALSE
, FALSE
, 0);
3225 gtk_container_set_border_width(GTK_CONTAINER(close_button
), 20);
3227 g_signal_connect(G_OBJECT(close_button
), "clicked",
3228 G_CALLBACK(on_about_close_activate
),
3229 (gpointer
)about_widget
);
3231 gtk_widget_show_all(about_widget
);
3236 on_button_new_clicked (GtkButton
*button
,
3239 create_new_window((GtkWidget
*)button
, user_data
, TRUE
);
3243 on_button_new_tab_clicked (GtkButton
*button
,
3246 create_new_tab((GtkWidget
*)button
, user_data
);
3250 on_button_open_clicked (GtkButton
*button
,
3253 open_traceset((GtkWidget
*)button
, user_data
);
3258 on_button_add_trace_clicked (GtkButton
*button
,
3261 add_trace((GtkWidget
*)button
, user_data
);
3266 on_button_remove_trace_clicked (GtkButton
*button
,
3269 remove_trace((GtkWidget
*)button
, user_data
);
3273 on_button_redraw_clicked (GtkButton
*button
,
3276 redraw((GtkWidget
*)button
, user_data
);
3280 on_button_continue_processing_clicked (GtkButton
*button
,
3283 continue_processing((GtkWidget
*)button
, user_data
);
3287 on_button_stop_processing_clicked (GtkButton
*button
,
3290 stop_processing((GtkWidget
*)button
, user_data
);
3296 on_button_save_clicked (GtkButton
*button
,
3299 save((GtkWidget
*)button
, user_data
);
3304 on_button_save_as_clicked (GtkButton
*button
,
3307 save_as((GtkWidget
*)button
, user_data
);
3312 on_button_zoom_in_clicked (GtkButton
*button
,
3315 zoom_in((GtkWidget
*)button
, user_data
);
3320 on_button_zoom_out_clicked (GtkButton
*button
,
3323 zoom_out((GtkWidget
*)button
, user_data
);
3328 on_button_zoom_extended_clicked (GtkButton
*button
,
3331 zoom_extended((GtkWidget
*)button
, user_data
);
3336 on_button_go_to_time_clicked (GtkButton
*button
,
3339 go_to_time((GtkWidget
*)button
, user_data
);
3344 on_button_show_time_frame_clicked (GtkButton
*button
,
3347 show_time_frame((GtkWidget
*)button
, user_data
);
3352 on_button_move_up_clicked (GtkButton
*button
,
3355 move_up_viewer((GtkWidget
*)button
, user_data
);
3360 on_button_move_down_clicked (GtkButton
*button
,
3363 move_down_viewer((GtkWidget
*)button
, user_data
);
3368 on_button_delete_viewer_clicked (GtkButton
*button
,
3371 delete_viewer((GtkWidget
*)button
, user_data
);
3375 on_MWindow_destroy (GtkWidget
*widget
,
3378 MainWindow
*main_window
= get_window_data_struct(widget
);
3379 LttvIAttribute
*attributes
= main_window
->attributes
;
3380 LttvAttributeValue value
;
3383 //This is unnecessary, since widgets will be destroyed
3384 //by the main window widget anyway.
3385 //remove_all_menu_toolbar_constructors(main_window, NULL);
3387 retval
= lttv_iattribute_find_by_path(attributes
, "viewers/menu",
3388 LTTV_POINTER
, &value
);
3390 lttv_menus_destroy((LttvMenus
*)*(value
.v_pointer
));
3392 retval
= lttv_iattribute_find_by_path(attributes
, "viewers/toolbar",
3393 LTTV_POINTER
, &value
);
3395 lttv_toolbars_destroy((LttvToolbars
*)*(value
.v_pointer
));
3397 g_object_unref(main_window
->attributes
);
3398 g_main_window_list
= g_slist_remove(g_main_window_list
, main_window
);
3400 g_info("There are now : %d windows\n",g_slist_length(g_main_window_list
));
3401 if(g_slist_length(g_main_window_list
) == 0)
3406 on_MWindow_configure (GtkWidget
*widget
,
3407 GdkEventConfigure
*event
,
3410 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)widget
);
3412 // MD : removed time width modification upon resizing of the main window.
3413 // The viewers will redraw themselves completely, without time interval
3416 if(mw_data->window_width){
3417 time_span = LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context)->Time_Span ;
3418 time_win = tab->time_window;
3419 ratio = width / mw_data->window_width;
3420 tab->time_window.time_width = ltt_time_mul(time_win.time_width,ratio);
3421 time = ltt_time_sub(time_span->endTime, time_win.start_time);
3422 if(ltt_time_compare(time, tab->time_window.time_width) < 0){
3423 tab->time_window.time_width = time;
3429 mw_data->window_width = (int)width;
3438 on_MNotebook_switch_page (GtkNotebook
*notebook
,
3439 GtkNotebookPage
*page
,
3447 void time_change_manager (Tab
*tab
,
3448 TimeWindow new_time_window
)
3450 /* Only one source of time change */
3451 if(tab
->time_manager_lock
== TRUE
) return;
3453 tab
->time_manager_lock
= TRUE
;
3455 LttvTracesetContext
*tsc
= LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3456 TimeInterval time_span
= tsc
->time_span
;
3457 LttTime start_time
= new_time_window
.start_time
;
3458 LttTime end_time
= new_time_window
.end_time
;
3459 LttTime time_width
= new_time_window
.time_width
;
3461 g_assert(ltt_time_compare(start_time
, end_time
) < 0);
3464 GtkAdjustment
*adjustment
= gtk_range_get_adjustment(GTK_RANGE(tab
->scrollbar
));
3465 LttTime upper
= ltt_time_sub(time_span
.end_time
, time_span
.start_time
);
3467 gtk_range_set_increments(GTK_RANGE(tab
->scrollbar
),
3468 ltt_time_to_double(new_time_window
.time_width
)
3469 / SCROLL_STEP_PER_PAGE
3470 * NANOSECONDS_PER_SECOND
, /* step increment */
3471 ltt_time_to_double(new_time_window
.time_width
)
3472 * NANOSECONDS_PER_SECOND
); /* page increment */
3473 gtk_range_set_range(GTK_RANGE(tab
->scrollbar
),
3475 ltt_time_to_double(upper
)
3476 * NANOSECONDS_PER_SECOND
); /* upper */
3478 g_object_set(G_OBJECT(adjustment
),
3482 ltt_time_to_double(upper
), /* upper */
3484 new_time_window
.time_width_double
3485 / SCROLL_STEP_PER_PAGE
, /* step increment */
3487 new_time_window
.time_width_double
,
3488 /* page increment */
3490 new_time_window
.time_width_double
, /* page size */
3492 gtk_adjustment_changed(adjustment
);
3494 // g_object_set(G_OBJECT(adjustment),
3496 // ltt_time_to_double(
3497 // ltt_time_sub(start_time, time_span.start_time))
3500 //gtk_adjustment_value_changed(adjustment);
3501 gtk_range_set_value(GTK_RANGE(tab
->scrollbar
),
3503 ltt_time_sub(start_time
, time_span
.start_time
)) /* value */);
3505 /* set the time bar. */
3507 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry1
),
3508 (double)time_span
.start_time
.tv_sec
,
3509 (double)time_span
.end_time
.tv_sec
);
3510 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry1
),
3511 (double)start_time
.tv_sec
);
3513 /* start nanoseconds */
3514 if(start_time
.tv_sec
== time_span
.start_time
.tv_sec
) {
3515 /* can be both beginning and end at the same time. */
3516 if(start_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3517 /* If we are at the end, max nsec to end.. -1 (not zero length) */
3518 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry2
),
3519 (double)time_span
.start_time
.tv_nsec
,
3520 (double)time_span
.end_time
.tv_nsec
-1);
3522 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry2
),
3523 (double)time_span
.start_time
.tv_nsec
,
3524 (double)NANOSECONDS_PER_SECOND
-1);
3526 } else if(start_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3527 /* If we are at the end, max nsec to end.. -1 (not zero length) */
3528 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry2
),
3530 (double)time_span
.end_time
.tv_nsec
-1);
3531 } else /* anywhere else */
3532 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry2
),
3534 (double)NANOSECONDS_PER_SECOND
-1);
3535 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry2
),
3536 (double)start_time
.tv_nsec
);
3539 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry3
),
3540 (double)time_span
.start_time
.tv_sec
,
3541 (double)time_span
.end_time
.tv_sec
);
3542 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry3
),
3543 (double)end_time
.tv_sec
);
3545 /* end nanoseconds */
3546 if(end_time
.tv_sec
== time_span
.start_time
.tv_sec
) {
3547 /* can be both beginning and end at the same time. */
3548 if(end_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3549 /* If we are at the end, max nsec to end.. */
3550 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry4
),
3551 (double)time_span
.start_time
.tv_nsec
+1,
3552 (double)time_span
.end_time
.tv_nsec
);
3554 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry4
),
3555 (double)time_span
.start_time
.tv_nsec
+1,
3556 (double)NANOSECONDS_PER_SECOND
-1);
3559 else if(end_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3560 /* If we are at the end, max nsec to end.. */
3561 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry4
),
3563 (double)time_span
.end_time
.tv_nsec
);
3565 else /* anywhere else */
3566 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry4
),
3568 (double)NANOSECONDS_PER_SECOND
-1);
3569 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry4
),
3570 (double)end_time
.tv_nsec
);
3573 if(time_width
.tv_nsec
== 0) {
3574 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry7
),
3576 (double)upper
.tv_sec
);
3578 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry7
),
3580 (double)upper
.tv_sec
);
3582 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry7
),
3583 (double)time_width
.tv_sec
);
3585 /* width nanoseconds */
3586 if(time_width
.tv_sec
== upper
.tv_sec
) {
3587 if(time_width
.tv_sec
== 0) {
3588 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry8
),
3590 (double)upper
.tv_nsec
);
3592 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry8
),
3594 (double)upper
.tv_nsec
);
3597 else if(time_width
.tv_sec
== 0) {
3598 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry8
),
3600 (double)upper
.tv_nsec
);
3602 else /* anywhere else */
3603 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry8
),
3605 (double)NANOSECONDS_PER_SECOND
-1);
3606 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry8
),
3607 (double)time_width
.tv_nsec
);
3609 /* call viewer hooks for new time window */
3610 set_time_window(tab
, &new_time_window
);
3612 tab
->time_manager_lock
= FALSE
;
3616 /* value changed for frame start s
3618 * Check time span : if ns is out of range, clip it the nearest good value.
3621 on_MEntry1_value_changed (GtkSpinButton
*spinbutton
,
3624 Tab
*tab
=(Tab
*)user_data
;
3625 LttvTracesetContext
* tsc
=
3626 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3627 TimeInterval time_span
= tsc
->time_span
;
3628 gint value
= gtk_spin_button_get_value_as_int(spinbutton
);
3630 TimeWindow new_time_window
= tab
->time_window
;
3632 LttTime end_time
= new_time_window
.end_time
;
3634 new_time_window
.start_time
.tv_sec
= value
;
3636 /* start nanoseconds */
3637 if(new_time_window
.start_time
.tv_sec
== time_span
.start_time
.tv_sec
) {
3638 if(new_time_window
.start_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3639 if(new_time_window
.start_time
.tv_nsec
> time_span
.end_time
.tv_nsec
)
3640 new_time_window
.start_time
.tv_nsec
= time_span
.end_time
.tv_nsec
-1;
3641 if(new_time_window
.start_time
.tv_nsec
< time_span
.start_time
.tv_nsec
)
3642 new_time_window
.start_time
.tv_nsec
= time_span
.start_time
.tv_nsec
;
3644 if(new_time_window
.start_time
.tv_nsec
< time_span
.start_time
.tv_nsec
)
3645 new_time_window
.start_time
.tv_nsec
= time_span
.start_time
.tv_nsec
;
3648 else if(new_time_window
.start_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3649 if(new_time_window
.start_time
.tv_nsec
> time_span
.end_time
.tv_nsec
)
3650 new_time_window
.start_time
.tv_nsec
= time_span
.end_time
.tv_nsec
-1;
3653 if(ltt_time_compare(new_time_window
.start_time
, end_time
) >= 0) {
3654 /* Then, we must push back end time : keep the same time width
3655 * if possible, else end traceset time */
3656 end_time
= LTT_TIME_MIN(ltt_time_add(new_time_window
.start_time
,
3657 new_time_window
.time_width
),
3658 time_span
.end_time
);
3661 /* Fix the time width to fit start time and end time */
3662 new_time_window
.time_width
= ltt_time_sub(end_time
,
3663 new_time_window
.start_time
);
3664 new_time_window
.time_width_double
=
3665 ltt_time_to_double(new_time_window
.time_width
);
3667 new_time_window
.end_time
= end_time
;
3669 time_change_manager(tab
, new_time_window
);
3674 on_MEntry2_value_changed (GtkSpinButton
*spinbutton
,
3677 Tab
*tab
=(Tab
*)user_data
;
3678 LttvTracesetContext
* tsc
=
3679 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3680 TimeInterval time_span
= tsc
->time_span
;
3681 gint value
= gtk_spin_button_get_value_as_int(spinbutton
);
3683 TimeWindow new_time_window
= tab
->time_window
;
3685 LttTime end_time
= new_time_window
.end_time
;
3687 new_time_window
.start_time
.tv_nsec
= value
;
3689 if(ltt_time_compare(new_time_window
.start_time
, end_time
) >= 0) {
3690 /* Then, we must push back end time : keep the same time width
3691 * if possible, else end traceset time */
3692 end_time
= LTT_TIME_MIN(ltt_time_add(new_time_window
.start_time
,
3693 new_time_window
.time_width
),
3694 time_span
.end_time
);
3697 /* Fix the time width to fit start time and end time */
3698 new_time_window
.time_width
= ltt_time_sub(end_time
,
3699 new_time_window
.start_time
);
3700 new_time_window
.time_width_double
=
3701 ltt_time_to_double(new_time_window
.time_width
);
3703 new_time_window
.end_time
= end_time
;
3705 time_change_manager(tab
, new_time_window
);
3710 on_MEntry3_value_changed (GtkSpinButton
*spinbutton
,
3713 Tab
*tab
=(Tab
*)user_data
;
3714 LttvTracesetContext
* tsc
=
3715 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3716 TimeInterval time_span
= tsc
->time_span
;
3717 gint value
= gtk_spin_button_get_value_as_int(spinbutton
);
3719 TimeWindow new_time_window
= tab
->time_window
;
3721 LttTime end_time
= new_time_window
.end_time
;
3723 end_time
.tv_sec
= value
;
3725 /* end nanoseconds */
3726 if(end_time
.tv_sec
== time_span
.start_time
.tv_sec
) {
3727 if(end_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3728 if(end_time
.tv_nsec
> time_span
.end_time
.tv_nsec
)
3729 end_time
.tv_nsec
= time_span
.end_time
.tv_nsec
;
3730 if(end_time
.tv_nsec
< time_span
.start_time
.tv_nsec
)
3731 end_time
.tv_nsec
= time_span
.start_time
.tv_nsec
+1;
3733 if(end_time
.tv_nsec
< time_span
.start_time
.tv_nsec
)
3734 end_time
.tv_nsec
= time_span
.start_time
.tv_nsec
+1;
3737 else if(end_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3738 if(end_time
.tv_nsec
> time_span
.end_time
.tv_nsec
)
3739 end_time
.tv_nsec
= time_span
.end_time
.tv_nsec
;
3742 if(ltt_time_compare(new_time_window
.start_time
, end_time
) >= 0) {
3743 /* Then, we must push front start time : keep the same time width
3744 * if possible, else end traceset time */
3745 new_time_window
.start_time
= LTT_TIME_MAX(
3746 ltt_time_sub(end_time
,
3747 new_time_window
.time_width
),
3748 time_span
.start_time
);
3751 /* Fix the time width to fit start time and end time */
3752 new_time_window
.time_width
= ltt_time_sub(end_time
,
3753 new_time_window
.start_time
);
3754 new_time_window
.time_width_double
=
3755 ltt_time_to_double(new_time_window
.time_width
);
3757 new_time_window
.end_time
= end_time
;
3759 time_change_manager(tab
, new_time_window
);
3764 on_MEntry4_value_changed (GtkSpinButton
*spinbutton
,
3767 Tab
*tab
=(Tab
*)user_data
;
3768 LttvTracesetContext
* tsc
=
3769 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3770 TimeInterval time_span
= tsc
->time_span
;
3771 gint value
= gtk_spin_button_get_value_as_int(spinbutton
);
3773 TimeWindow new_time_window
= tab
->time_window
;
3775 LttTime end_time
= new_time_window
.end_time
;
3777 end_time
.tv_nsec
= value
;
3779 if(ltt_time_compare(new_time_window
.start_time
, end_time
) >= 0) {
3780 /* Then, we must push front start time : keep the same time width
3781 * if possible, else end traceset time */
3782 new_time_window
.start_time
= LTT_TIME_MAX(
3783 ltt_time_sub(end_time
,
3784 new_time_window
.time_width
),
3785 time_span
.start_time
);
3788 /* Fix the time width to fit start time and end time */
3789 new_time_window
.time_width
= ltt_time_sub(end_time
,
3790 new_time_window
.start_time
);
3791 new_time_window
.time_width_double
=
3792 ltt_time_to_double(new_time_window
.time_width
);
3793 new_time_window
.end_time
= end_time
;
3795 time_change_manager(tab
, new_time_window
);
3799 /* value changed for time frame interval s
3801 * Check time span : if ns is out of range, clip it the nearest good value.
3804 on_MEntry7_value_changed (GtkSpinButton
*spinbutton
,
3807 Tab
*tab
=(Tab
*)user_data
;
3808 LttvTracesetContext
* tsc
=
3809 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3810 TimeInterval time_span
= tsc
->time_span
;
3811 gint value
= gtk_spin_button_get_value_as_int(spinbutton
);
3812 LttTime current_time
, time_delta
;
3813 TimeWindow new_time_window
= tab
->time_window
;
3814 current_time
= tab
->current_time
;
3816 time_delta
= ltt_time_sub(time_span
.end_time
,time_span
.start_time
);
3817 new_time_window
.time_width
.tv_sec
= value
;
3818 new_time_window
.time_width_double
=
3819 ltt_time_to_double(new_time_window
.time_width
);
3820 if(ltt_time_compare(new_time_window
.time_width
,time_delta
) > 0)
3821 { /* Case where zoom out is bigger than trace length */
3822 new_time_window
.start_time
= time_span
.start_time
;
3823 new_time_window
.time_width
= time_delta
;
3824 new_time_window
.time_width_double
= ltt_time_to_double(time_delta
);
3825 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
3826 new_time_window
.time_width
) ;
3830 /* Center the image on the current time */
3831 new_time_window
.start_time
=
3832 ltt_time_sub(current_time
,
3833 ltt_time_from_double(new_time_window
.time_width_double
/2.0));
3834 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
3835 new_time_window
.time_width
) ;
3836 /* If on borders, don't fall off */
3837 if(ltt_time_compare(new_time_window
.start_time
, time_span
.start_time
) <0
3838 || ltt_time_compare(new_time_window
.start_time
, time_span
.end_time
) >0)
3840 new_time_window
.start_time
= time_span
.start_time
;
3841 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
3842 new_time_window
.time_width
) ;
3846 if(ltt_time_compare(new_time_window
.end_time
,
3847 time_span
.end_time
) > 0
3848 || ltt_time_compare(new_time_window
.end_time
,
3849 time_span
.start_time
) < 0)
3851 new_time_window
.start_time
=
3852 ltt_time_sub(time_span
.end_time
, new_time_window
.time_width
);
3854 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
3855 new_time_window
.time_width
) ;
3861 if(ltt_time_compare(new_time_window
.time_width
, ltt_time_zero
) == 0) {
3862 g_warning("Zoom more than 1 ns impossible");
3864 time_change_manager(tab
, new_time_window
);
3869 on_MEntry8_value_changed (GtkSpinButton
*spinbutton
,
3872 Tab
*tab
=(Tab
*)user_data
;
3873 LttvTracesetContext
* tsc
=
3874 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3875 TimeInterval time_span
= tsc
->time_span
;
3876 gint value
= gtk_spin_button_get_value_as_int(spinbutton
);
3877 LttTime current_time
, time_delta
;
3878 TimeWindow new_time_window
= tab
->time_window
;
3879 current_time
= tab
->current_time
;
3881 time_delta
= ltt_time_sub(time_span
.end_time
,time_span
.start_time
);
3882 new_time_window
.time_width
.tv_nsec
= value
;
3883 new_time_window
.time_width_double
=
3884 ltt_time_to_double(new_time_window
.time_width
);
3885 if(ltt_time_compare(new_time_window
.time_width
,time_delta
) > 0)
3886 { /* Case where zoom out is bigger than trace length */
3887 new_time_window
.start_time
= time_span
.start_time
;
3888 new_time_window
.time_width
= time_delta
;
3889 new_time_window
.time_width_double
= ltt_time_to_double(time_delta
);
3890 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
3891 new_time_window
.time_width
) ;
3895 /* Center the image on the current time */
3896 new_time_window
.start_time
=
3897 ltt_time_sub(current_time
,
3898 ltt_time_from_double(new_time_window
.time_width_double
/2.0));
3899 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
3900 new_time_window
.time_width
) ;
3901 /* If on borders, don't fall off */
3902 if(ltt_time_compare(new_time_window
.start_time
, time_span
.start_time
) <0
3903 || ltt_time_compare(new_time_window
.start_time
, time_span
.end_time
) >0)
3905 new_time_window
.start_time
= time_span
.start_time
;
3906 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
3907 new_time_window
.time_width
) ;
3911 if(ltt_time_compare(new_time_window
.end_time
,
3912 time_span
.end_time
) > 0
3913 || ltt_time_compare(new_time_window
.end_time
,
3914 time_span
.start_time
) < 0)
3916 new_time_window
.start_time
=
3917 ltt_time_sub(time_span
.end_time
, new_time_window
.time_width
);
3919 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
3920 new_time_window
.time_width
) ;
3926 if(ltt_time_compare(new_time_window
.time_width
, ltt_time_zero
) == 0) {
3927 g_warning("Zoom more than 1 ns impossible");
3929 time_change_manager(tab
, new_time_window
);
3935 void current_time_change_manager (Tab
*tab
,
3936 LttTime new_current_time
)
3938 /* Only one source of time change */
3939 if(tab
->current_time_manager_lock
== TRUE
) return;
3941 tab
->current_time_manager_lock
= TRUE
;
3943 LttvTracesetContext
*tsc
= LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3944 TimeInterval time_span
= tsc
->time_span
;
3946 /* current seconds */
3947 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry5
),
3948 (double)time_span
.start_time
.tv_sec
,
3949 (double)time_span
.end_time
.tv_sec
);
3950 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry5
),
3951 (double)new_current_time
.tv_sec
);
3954 /* start nanoseconds */
3955 if(new_current_time
.tv_sec
== time_span
.start_time
.tv_sec
) {
3956 /* can be both beginning and end at the same time. */
3957 if(new_current_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3958 /* If we are at the end, max nsec to end.. */
3959 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry6
),
3960 (double)time_span
.start_time
.tv_nsec
,
3961 (double)time_span
.end_time
.tv_nsec
);
3963 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry6
),
3964 (double)time_span
.start_time
.tv_nsec
,
3965 (double)NANOSECONDS_PER_SECOND
-1);
3967 } else if(new_current_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3968 /* If we are at the end, max nsec to end.. */
3969 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry6
),
3971 (double)time_span
.end_time
.tv_nsec
);
3972 } else /* anywhere else */
3973 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry6
),
3975 (double)NANOSECONDS_PER_SECOND
-1);
3977 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry6
),
3978 (double)new_current_time
.tv_nsec
);
3980 set_current_time(tab
, &new_current_time
);
3982 tab
->current_time_manager_lock
= FALSE
;
3985 void current_position_change_manager(Tab
*tab
,
3986 LttvTracesetContextPosition
*pos
)
3988 LttvTracesetContext
*tsc
=
3989 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3990 TimeInterval time_span
= tsc
->time_span
;
3993 retval
= lttv_process_traceset_seek_position(tsc
, pos
);
3994 g_assert_cmpint(retval
, ==, 0);
3995 LttTime new_time
= lttv_traceset_context_position_get_time(pos
);
3996 /* Put the context in a state coherent position */
3997 lttv_state_traceset_seek_time_closest((LttvTracesetState
*)tsc
, ltt_time_zero
);
3999 current_time_change_manager(tab
, new_time
);
4001 set_current_position(tab
, pos
);
4006 on_MEntry5_value_changed (GtkSpinButton
*spinbutton
,
4009 Tab
*tab
= (Tab
*)user_data
;
4010 LttvTracesetContext
* tsc
=
4011 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
4012 TimeInterval time_span
= tsc
->time_span
;
4013 gint value
= gtk_spin_button_get_value_as_int(spinbutton
);
4014 LttTime new_current_time
= tab
->current_time
;
4015 new_current_time
.tv_sec
= value
;
4017 /* current nanoseconds */
4018 if(new_current_time
.tv_sec
== time_span
.start_time
.tv_sec
) {
4019 if(new_current_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
4020 if(new_current_time
.tv_nsec
> time_span
.end_time
.tv_nsec
)
4021 new_current_time
.tv_nsec
= time_span
.end_time
.tv_nsec
;
4022 if(new_current_time
.tv_nsec
< time_span
.start_time
.tv_nsec
)
4023 new_current_time
.tv_nsec
= time_span
.start_time
.tv_nsec
;
4025 if(new_current_time
.tv_nsec
< time_span
.start_time
.tv_nsec
)
4026 new_current_time
.tv_nsec
= time_span
.start_time
.tv_nsec
;
4029 else if(new_current_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
4030 if(new_current_time
.tv_nsec
> time_span
.end_time
.tv_nsec
)
4031 new_current_time
.tv_nsec
= time_span
.end_time
.tv_nsec
;
4034 current_time_change_manager(tab
, new_current_time
);
4038 on_MEntry6_value_changed (GtkSpinButton
*spinbutton
,
4041 Tab
*tab
= (Tab
*)user_data
;
4042 gint value
= gtk_spin_button_get_value_as_int(spinbutton
);
4043 LttTime new_current_time
= tab
->current_time
;
4044 new_current_time
.tv_nsec
= value
;
4046 current_time_change_manager(tab
, new_current_time
);
4050 void scroll_value_changed_cb(GtkWidget
*scrollbar
,
4053 Tab
*tab
= (Tab
*)user_data
;
4054 TimeWindow new_time_window
;
4056 GtkAdjustment
*adjust
= gtk_range_get_adjustment(GTK_RANGE(scrollbar
));
4057 gdouble value
= gtk_adjustment_get_value(adjust
);
4058 // gdouble upper, lower, ratio, page_size;
4060 LttvTracesetContext
* tsc
=
4061 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
4062 TimeInterval time_span
= tsc
->time_span
;
4064 time
= ltt_time_add(ltt_time_from_double(value
),
4065 time_span
.start_time
);
4067 new_time_window
.start_time
= time
;
4069 page_size
= adjust
->page_size
;
4071 new_time_window
.time_width
=
4072 ltt_time_from_double(page_size
);
4074 new_time_window
.time_width_double
=
4077 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
4078 new_time_window
.time_width
);
4081 time_change_manager(tab
, new_time_window
);
4083 //time_window = tab->time_window;
4085 lower
= adjust
->lower
;
4086 upper
= adjust
->upper
;
4087 ratio
= (value
- lower
) / (upper
- lower
);
4088 g_info("lower %lu, upper %lu, value %lu, ratio %lu", lower
, upper
, value
, ratio
);
4090 //time = ltt_time_sub(time_span->end_time, time_span->start_time);
4091 //time = ltt_time_mul(time, (float)ratio);
4092 //time = ltt_time_add(time_span->start_time, time);
4093 time
= ltt_time_add(ltt_time_from_double(value
),
4094 time_span
.start_time
);
4096 time_window
.start_time
= time
;
4098 page_size
= adjust
->page_size
;
4100 time_window
.time_width
=
4101 ltt_time_from_double(page_size
);
4102 //time = ltt_time_sub(time_span.end_time, time);
4103 //if(ltt_time_compare(time,time_window.time_width) < 0){
4104 // time_window.time_width = time;
4107 /* call viewer hooks for new time window */
4108 set_time_window(tab
, &time_window
);
4113 /* Display a dialogue showing all eventtypes and traces, let user to select the interested
4114 * eventtypes, tracefiles and traces (filter)
4117 /* Select a trace which will be removed from traceset
4120 char * get_remove_trace(MainWindow
*mw_data
,
4121 char ** all_trace_name
, int nb_trace
)
4123 return get_selection(mw_data
, all_trace_name
, nb_trace
,
4124 "Select a trace", "Trace pathname");
4128 /* Select a module which will be loaded
4131 char * get_load_module(MainWindow
*mw_data
,
4132 char ** load_module_name
, int nb_module
)
4134 return get_selection(mw_data
, load_module_name
, nb_module
,
4135 "Select a module to load", "Module name");
4141 /* Select a module which will be unloaded
4144 char * get_unload_module(MainWindow
*mw_data
,
4145 char ** loaded_module_name
, int nb_module
)
4147 return get_selection(mw_data
, loaded_module_name
, nb_module
,
4148 "Select a module to unload", "Module name");
4152 /* Display a dialogue which shows all selectable items, let user to
4153 * select one of them
4156 char * get_selection(MainWindow
*mw_data
,
4157 char ** loaded_module_name
, int nb_module
,
4158 char *title
, char * column_title
)
4160 GtkWidget
* dialogue
;
4161 GtkWidget
* scroll_win
;
4163 GtkListStore
* store
;
4164 GtkTreeViewColumn
* column
;
4165 GtkCellRenderer
* renderer
;
4166 GtkTreeSelection
* select
;
4169 char * unload_module_name
= NULL
;
4171 dialogue
= gtk_dialog_new_with_buttons(title
,
4174 GTK_STOCK_OK
,GTK_RESPONSE_ACCEPT
,
4175 GTK_STOCK_CANCEL
,GTK_RESPONSE_REJECT
,
4177 gtk_window_set_default_size((GtkWindow
*)dialogue
, 500, 200);
4178 gtk_window_set_transient_for(GTK_WINDOW(dialogue
),
4179 GTK_WINDOW(mw_data
->mwindow
));
4181 scroll_win
= gtk_scrolled_window_new (NULL
, NULL
);
4182 gtk_widget_show ( scroll_win
);
4183 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll_win
),
4184 GTK_POLICY_AUTOMATIC
, GTK_POLICY_AUTOMATIC
);
4186 store
= gtk_list_store_new (N_COLUMNS
,G_TYPE_STRING
);
4187 tree
= gtk_tree_view_new_with_model(GTK_TREE_MODEL (store
));
4188 gtk_widget_show ( tree
);
4189 g_object_unref (G_OBJECT (store
));
4191 renderer
= gtk_cell_renderer_text_new ();
4192 column
= gtk_tree_view_column_new_with_attributes (column_title
,
4194 "text", MODULE_COLUMN
,
4196 gtk_tree_view_column_set_alignment (column
, 0.5);
4197 gtk_tree_view_column_set_fixed_width (column
, 150);
4198 gtk_tree_view_append_column (GTK_TREE_VIEW (tree
), column
);
4200 select
= gtk_tree_view_get_selection (GTK_TREE_VIEW (tree
));
4201 gtk_tree_selection_set_mode (select
, GTK_SELECTION_SINGLE
);
4203 gtk_container_add (GTK_CONTAINER (scroll_win
), tree
);
4205 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialogue
)->vbox
), scroll_win
,TRUE
, TRUE
,0);
4207 for(i
=0;i
<nb_module
;i
++){
4208 gtk_list_store_append (store
, &iter
);
4209 gtk_list_store_set (store
, &iter
, MODULE_COLUMN
,loaded_module_name
[i
],-1);
4212 id
= gtk_dialog_run(GTK_DIALOG(dialogue
));
4213 GtkTreeModel
**store_model
= (GtkTreeModel
**)&store
;
4215 case GTK_RESPONSE_ACCEPT
:
4216 case GTK_RESPONSE_OK
:
4217 if (gtk_tree_selection_get_selected (select
, store_model
, &iter
)){
4218 gtk_tree_model_get ((GtkTreeModel
*)store
, &iter
, MODULE_COLUMN
, &unload_module_name
, -1);
4220 case GTK_RESPONSE_REJECT
:
4221 case GTK_RESPONSE_CANCEL
:
4223 gtk_widget_destroy(dialogue
);
4227 return unload_module_name
;
4231 /* Insert all menu entry and tool buttons into this main window
4236 void add_all_menu_toolbar_constructors(MainWindow
* mw
, gpointer user_data
)
4240 lttvwindow_viewer_constructor constructor
;
4241 LttvMenus
* global_menu
, * instance_menu
;
4242 LttvToolbars
* global_toolbar
, * instance_toolbar
;
4243 LttvMenuClosure
*menu_item
;
4244 LttvToolbarClosure
*toolbar_item
;
4245 LttvAttributeValue value
;
4246 LttvIAttribute
*global_attributes
= LTTV_IATTRIBUTE(lttv_global_attributes());
4247 LttvIAttribute
*attributes
= mw
->attributes
;
4248 GtkWidget
* tool_menu_title_menu
, *new_widget
, *pixmap
;
4251 retval
= lttv_iattribute_find_by_path(global_attributes
, "viewers/menu",
4252 LTTV_POINTER
, &value
);
4254 if(*(value
.v_pointer
) == NULL
)
4255 *(value
.v_pointer
) = lttv_menus_new();
4256 global_menu
= (LttvMenus
*)*(value
.v_pointer
);
4258 retval
= lttv_iattribute_find_by_path(attributes
, "viewers/menu",
4259 LTTV_POINTER
, &value
);
4261 if(*(value
.v_pointer
) == NULL
)
4262 *(value
.v_pointer
) = lttv_menus_new();
4263 instance_menu
= (LttvMenus
*)*(value
.v_pointer
);
4265 retval
= lttv_iattribute_find_by_path(global_attributes
, "viewers/toolbar",
4266 LTTV_POINTER
, &value
);
4268 if(*(value
.v_pointer
) == NULL
)
4269 *(value
.v_pointer
) = lttv_toolbars_new();
4270 global_toolbar
= (LttvToolbars
*)*(value
.v_pointer
);
4272 retval
= lttv_iattribute_find_by_path(attributes
, "viewers/toolbar",
4273 LTTV_POINTER
, &value
);
4275 if(*(value
.v_pointer
) == NULL
)
4276 *(value
.v_pointer
) = lttv_toolbars_new();
4277 instance_toolbar
= (LttvToolbars
*)*(value
.v_pointer
);
4279 /* Add missing menu entries to window instance */
4280 for(i
=0;i
<global_menu
->len
;i
++) {
4281 menu_item
= &g_array_index(global_menu
, LttvMenuClosure
, i
);
4283 //add menu_item to window instance;
4284 constructor
= menu_item
->con
;
4285 tool_menu_title_menu
= lookup_widget(mw
->mwindow
,"ToolMenuTitle_menu");
4287 gtk_menu_item_new_with_mnemonic (menu_item
->menu_text
);
4288 gtk_container_add (GTK_CONTAINER (tool_menu_title_menu
),
4290 g_signal_connect ((gpointer
) new_widget
, "activate",
4291 G_CALLBACK (insert_viewer_wrap
),
4293 gtk_widget_show (new_widget
);
4294 lttv_menus_add(instance_menu
, menu_item
->con
,
4295 menu_item
->menu_path
,
4296 menu_item
->menu_text
,
4301 /* Add missing toolbar entries to window instance */
4302 for(i
=0;i
<global_toolbar
->len
;i
++) {
4303 toolbar_item
= &g_array_index(global_toolbar
, LttvToolbarClosure
, i
);
4305 //add toolbar_item to window instance;
4306 constructor
= toolbar_item
->con
;
4307 tool_menu_title_menu
= lookup_widget(mw
->mwindow
,"MToolbar1");
4308 pixbuf
= gdk_pixbuf_new_from_xpm_data((const char**)toolbar_item
->pixmap
);
4309 pixmap
= gtk_image_new_from_pixbuf(pixbuf
);
4311 gtk_toolbar_append_element (GTK_TOOLBAR (tool_menu_title_menu
),
4312 GTK_TOOLBAR_CHILD_BUTTON
,
4315 toolbar_item
->tooltip
, NULL
,
4316 pixmap
, NULL
, NULL
);
4317 gtk_label_set_use_underline(
4318 GTK_LABEL (((GtkToolbarChild
*) (
4319 g_list_last (GTK_TOOLBAR
4320 (tool_menu_title_menu
)->children
)->data
))->label
),
4322 gtk_container_set_border_width (GTK_CONTAINER (new_widget
), 1);
4323 g_signal_connect ((gpointer
) new_widget
,
4325 G_CALLBACK (insert_viewer_wrap
),
4327 gtk_widget_show (new_widget
);
4329 lttv_toolbars_add(instance_toolbar
, toolbar_item
->con
,
4330 toolbar_item
->tooltip
,
4331 toolbar_item
->pixmap
,
4339 /* Create a main window
4342 MainWindow
*construct_main_window(MainWindow
* parent
)
4346 g_debug("construct_main_window()");
4347 GtkWidget
* new_window
; /* New generated main window */
4348 MainWindow
* new_m_window
;/* New main window structure */
4349 GtkNotebook
* notebook
;
4350 LttvIAttribute
*attributes
=
4351 LTTV_IATTRIBUTE(g_object_new(LTTV_ATTRIBUTE_TYPE
, NULL
));
4352 LttvAttributeValue value
;
4355 new_m_window
= g_new(MainWindow
, 1);
4357 // Add the object's information to the module's array
4358 g_main_window_list
= g_slist_append(g_main_window_list
, new_m_window
);
4360 new_window
= create_MWindow();
4361 gtk_widget_show (new_window
);
4363 new_m_window
->mwindow
= new_window
;
4364 new_m_window
->attributes
= attributes
;
4366 retval
= lttv_iattribute_find_by_path(attributes
, "viewers/menu",
4367 LTTV_POINTER
, &value
);
4369 *(value
.v_pointer
) = lttv_menus_new();
4371 retval
= lttv_iattribute_find_by_path(attributes
, "viewers/toolbar",
4372 LTTV_POINTER
, &value
);
4374 *(value
.v_pointer
) = lttv_toolbars_new();
4376 add_all_menu_toolbar_constructors(new_m_window
, NULL
);
4378 g_object_set_data_full(G_OBJECT(new_window
),
4380 (gpointer
)new_m_window
,
4381 (GDestroyNotify
)g_free
);
4382 //create a default tab
4383 notebook
= (GtkNotebook
*)lookup_widget(new_m_window
->mwindow
, "MNotebook");
4384 if(notebook
== NULL
){
4385 g_info("Notebook does not exist\n");
4386 /* FIXME : destroy partially created widgets */
4387 g_free(new_m_window
);
4390 //gtk_notebook_popup_enable (GTK_NOTEBOOK(notebook));
4391 //for now there is no name field in LttvTraceset structure
4392 //Use "Traceset" as the label for the default tab
4394 GtkWidget
* parent_notebook
= lookup_widget(parent
->mwindow
, "MNotebook");
4395 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(parent_notebook
),
4396 gtk_notebook_get_current_page(GTK_NOTEBOOK(parent_notebook
)));
4402 LttvPluginTab
*ptab
;
4403 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
4404 parent_tab
= ptab
->tab
;
4406 LttvPluginTab
*ptab
= g_object_new(LTTV_TYPE_PLUGIN_TAB
, NULL
);
4408 new_m_window
, parent_tab
, notebook
, "Traceset");
4409 ptab
->parent
.top_widget
= ptab
->tab
->top_widget
;
4410 g_object_set_data_full(
4411 G_OBJECT(ptab
->tab
->vbox
),
4414 (GDestroyNotify
)tab_destructor
);
4415 new_tab
= ptab
->tab
;
4417 LttvPluginTab
*ptab
= g_object_new(LTTV_TYPE_PLUGIN_TAB
, NULL
);
4418 init_tab(ptab
->tab
, new_m_window
, NULL
, notebook
, "Traceset");
4419 ptab
->parent
.top_widget
= ptab
->tab
->top_widget
;
4420 g_object_set_data_full(
4421 G_OBJECT(ptab
->tab
->vbox
),
4424 (GDestroyNotify
)tab_destructor
);
4425 new_tab
= ptab
->tab
;
4428 /* Insert default viewers */
4430 LttvAttributeType type
;
4431 LttvAttributeName name
;
4432 LttvAttributeValue value
;
4433 LttvAttribute
*attribute
;
4435 LttvIAttribute
*attributes_global
=
4436 LTTV_IATTRIBUTE(lttv_global_attributes());
4438 attribute
= LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
4439 LTTV_IATTRIBUTE(attributes_global
),
4440 LTTV_VIEWER_CONSTRUCTORS
));
4441 g_assert(attribute
);
4443 name
= g_quark_from_string("guievents");
4444 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
4446 if(type
== LTTV_POINTER
) {
4447 lttvwindow_viewer_constructor viewer_constructor
=
4448 (lttvwindow_viewer_constructor
)*value
.v_pointer
;
4449 insert_viewer(new_window
, viewer_constructor
);
4452 name
= g_quark_from_string("guicontrolflow");
4453 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
4455 if(type
== LTTV_POINTER
) {
4456 lttvwindow_viewer_constructor viewer_constructor
=
4457 (lttvwindow_viewer_constructor
)*value
.v_pointer
;
4458 insert_viewer(new_window
, viewer_constructor
);
4461 name
= g_quark_from_string("guistatistics");
4462 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
4464 if(type
== LTTV_POINTER
) {
4465 lttvwindow_viewer_constructor viewer_constructor
=
4466 (lttvwindow_viewer_constructor
)*value
.v_pointer
;
4467 insert_viewer(new_window
, viewer_constructor
);
4471 g_info("There are now : %d windows\n",g_slist_length(g_main_window_list
));
4473 return new_m_window
;
4477 /* Free the memory occupied by a tab structure
4481 void tab_destructor(LttvPluginTab
* ptab
)
4483 int i
, nb
, ref_count
;
4485 Tab
*tab
= ptab
->tab
;
4487 gtk_object_destroy(GTK_OBJECT(tab
->tooltips
));
4490 g_object_unref(tab
->attributes
);
4492 if(tab
->interrupted_state
)
4493 g_object_unref(tab
->interrupted_state
);
4496 if(tab
->traceset_info
->traceset_context
!= NULL
){
4497 //remove state update hooks
4498 lttv_state_remove_event_hooks(
4499 (LttvTracesetState
*)tab
->traceset_info
->
4501 lttv_context_fini(LTTV_TRACESET_CONTEXT(tab
->traceset_info
->
4503 g_object_unref(tab
->traceset_info
->traceset_context
);
4505 if(tab
->traceset_info
->traceset
!= NULL
) {
4506 nb
= lttv_traceset_number(tab
->traceset_info
->traceset
);
4507 for(i
= 0 ; i
< nb
; i
++) {
4508 trace
= lttv_traceset_get(tab
->traceset_info
->traceset
, i
);
4509 ref_count
= lttv_trace_get_ref_number(trace
);
4511 ltt_trace_close(lttv_trace(trace
));
4515 lttv_traceset_destroy(tab
->traceset_info
->traceset
);
4516 /* Remove the idle events requests processing function of the tab */
4517 g_idle_remove_by_data(tab
);
4519 g_slist_free(tab
->events_requests
);
4520 g_free(tab
->traceset_info
);
4522 g_object_unref(ptab
);
4526 /* Create a tab and insert it into the current main window
4529 void init_tab(Tab
*tab
, MainWindow
* mw
, Tab
*copy_tab
,
4530 GtkNotebook
* notebook
, char * label
)
4534 //LttvFilter *filter = NULL;
4536 //create a new tab data structure
4537 //tab = g_new(Tab,1);
4539 //construct and initialize the traceset_info
4540 tab
->traceset_info
= g_new(TracesetInfo
,1);
4543 tab
->traceset_info
->traceset
=
4544 lttv_traceset_copy(copy_tab
->traceset_info
->traceset
);
4546 /* Copy the previous tab's filter */
4547 /* We can clone the filter, as we copy the trace set also */
4548 /* The filter must always be in sync with the trace set */
4549 tab
->filter
= lttv_filter_clone(copy_tab
->filter
);
4551 tab
->traceset_info
->traceset
= lttv_traceset_new();
4555 lttv_attribute_write_xml(
4556 lttv_traceset_attribute(tab
->traceset_info
->traceset
),
4562 tab
->time_manager_lock
= FALSE
;
4563 tab
->current_time_manager_lock
= FALSE
;
4565 //FIXME copy not implemented in lower level
4566 tab
->traceset_info
->traceset_context
=
4567 g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
4568 g_assert(tab
->traceset_info
->traceset_context
!= NULL
);
4570 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
),
4571 tab
->traceset_info
->traceset
);
4572 //add state update hooks
4573 lttv_state_add_event_hooks(
4574 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
4576 //determine the current_time and time_window of the tab
4578 if(copy_tab
!= NULL
){
4579 tab
->time_window
= copy_tab
->time_window
;
4580 tab
->current_time
= copy_tab
->current_time
;
4582 tab
->time_window
.start_time
=
4583 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
4584 time_span
.start_time
;
4585 if(DEFAULT_TIME_WIDTH_S
<
4586 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
4587 time_span
.end_time
.tv_sec
)
4588 tmp_time
.tv_sec
= DEFAULT_TIME_WIDTH_S
;
4591 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
4592 time_span
.end_time
.tv_sec
;
4593 tmp_time
.tv_nsec
= 0;
4594 tab
->time_window
.time_width
= tmp_time
;
4595 tab
->current_time
.tv_sec
=
4596 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
4597 time_span
.start_time
.tv_sec
;
4598 tab
->current_time
.tv_nsec
=
4599 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
4600 time_span
.start_time
.tv_nsec
;
4603 tab
->attributes
= LTTV_IATTRIBUTE(g_object_new(LTTV_ATTRIBUTE_TYPE
, NULL
));
4604 tab
->interrupted_state
= g_object_new(LTTV_ATTRIBUTE_TYPE
, NULL
);
4606 tab
->vbox
= gtk_vbox_new(FALSE
, 2);
4607 tab
->top_widget
= tab
->vbox
;
4608 //g_object_set_data_full(G_OBJECT(tab->top_widget), "filter",
4609 // filter, (GDestroyNotify)lttv_filter_destroy);
4611 // g_signal_connect (G_OBJECT(tab->top_widget),
4613 // G_CALLBACK (on_top_notify),
4616 tab
->viewer_container
= gtk_vbox_new(TRUE
, 2);
4617 tab
->scrollbar
= gtk_hscrollbar_new(NULL
);
4618 //tab->multivpaned = gtk_multi_vpaned_new();
4620 gtk_box_pack_start(GTK_BOX(tab
->vbox
),
4621 tab
->viewer_container
,
4623 TRUE
, /* Give the extra space to the child */
4624 0); /* No padding */
4627 // tab->time_window = copy_tab->time_window;
4628 // tab->current_time = copy_tab->current_time;
4631 /* Create the timebar */
4633 tab
->MTimebar
= gtk_hbox_new(FALSE
, 2);
4634 gtk_widget_show(tab
->MTimebar
);
4635 tab
->tooltips
= gtk_tooltips_new();
4637 tab
->MEventBox1a
= gtk_event_box_new();
4638 gtk_widget_show(tab
->MEventBox1a
);
4639 gtk_tooltips_set_tip(tab
->tooltips
, tab
->MEventBox1a
,
4640 "Paste Start and End Times Here", "");
4641 tab
->MText1a
= gtk_label_new("Time Frame ");
4642 gtk_widget_show(tab
->MText1a
);
4643 gtk_container_add(GTK_CONTAINER(tab
->MEventBox1a
), tab
->MText1a
);
4644 tab
->MEventBox1b
= gtk_event_box_new();
4645 gtk_widget_show(tab
->MEventBox1b
);
4646 gtk_tooltips_set_tip(tab
->tooltips
, tab
->MEventBox1b
,
4647 "Paste Start Time Here", "");
4648 tab
->MText1b
= gtk_label_new("start: ");
4649 gtk_widget_show(tab
->MText1b
);
4650 gtk_container_add(GTK_CONTAINER(tab
->MEventBox1b
), tab
->MText1b
);
4651 tab
->MText2
= gtk_label_new("s");
4652 gtk_widget_show(tab
->MText2
);
4653 tab
->MText3a
= gtk_label_new("ns");
4654 gtk_widget_show(tab
->MText3a
);
4656 tab
->MEventBox3b
= gtk_event_box_new();
4657 gtk_widget_show(tab
->MEventBox3b
);
4658 gtk_tooltips_set_tip(tab
->tooltips
, tab
->MEventBox3b
,
4659 "Paste End Time Here", "");
4660 tab
->MText3b
= gtk_label_new("end:");
4661 gtk_widget_show(tab
->MText3b
);
4662 gtk_container_add(GTK_CONTAINER(tab
->MEventBox3b
), tab
->MText3b
);
4663 tab
->MText4
= gtk_label_new("s");
4664 gtk_widget_show(tab
->MText4
);
4665 tab
->MText5a
= gtk_label_new("ns");
4666 gtk_widget_show(tab
->MText5a
);
4668 tab
->MEventBox8
= gtk_event_box_new();
4669 gtk_widget_show(tab
->MEventBox8
);
4670 gtk_tooltips_set_tip(tab
->tooltips
, tab
->MEventBox8
,
4671 "Paste Time Interval here", "");
4672 tab
->MText8
= gtk_label_new("Time Interval:");
4673 gtk_widget_show(tab
->MText8
);
4674 gtk_container_add(GTK_CONTAINER(tab
->MEventBox8
), tab
->MText8
);
4675 tab
->MText9
= gtk_label_new("s");
4676 gtk_widget_show(tab
->MText9
);
4677 tab
->MText10
= gtk_label_new("ns");
4678 gtk_widget_show(tab
->MText10
);
4680 tab
->MEventBox5b
= gtk_event_box_new();
4681 gtk_widget_show(tab
->MEventBox5b
);
4682 gtk_tooltips_set_tip(tab
->tooltips
, tab
->MEventBox5b
,
4683 "Paste Current Time Here", "");
4684 tab
->MText5b
= gtk_label_new("Current Time:");
4685 gtk_widget_show(tab
->MText5b
);
4686 gtk_container_add(GTK_CONTAINER(tab
->MEventBox5b
), tab
->MText5b
);
4687 tab
->MText6
= gtk_label_new("s");
4688 gtk_widget_show(tab
->MText6
);
4689 tab
->MText7
= gtk_label_new("ns");
4690 gtk_widget_show(tab
->MText7
);
4692 tab
->MEntry1
= gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4693 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab
->MEntry1
),0);
4694 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab
->MEntry1
),TRUE
);
4695 gtk_widget_show(tab
->MEntry1
);
4696 tab
->MEntry2
= gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4697 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab
->MEntry2
),0);
4698 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab
->MEntry2
),TRUE
);
4699 gtk_widget_show(tab
->MEntry2
);
4700 tab
->MEntry3
= gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4701 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab
->MEntry3
),0);
4702 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab
->MEntry3
),TRUE
);
4703 gtk_widget_show(tab
->MEntry3
);
4704 tab
->MEntry4
= gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4705 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab
->MEntry4
),0);
4706 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab
->MEntry4
),TRUE
);
4707 gtk_widget_show(tab
->MEntry4
);
4708 tab
->MEntry5
= gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4709 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab
->MEntry5
),0);
4710 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab
->MEntry5
),TRUE
);
4711 gtk_widget_show(tab
->MEntry5
);
4712 tab
->MEntry6
= gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4713 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab
->MEntry6
),0);
4714 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab
->MEntry6
),TRUE
);
4715 gtk_widget_show(tab
->MEntry6
);
4716 tab
->MEntry7
= gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4717 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab
->MEntry7
),0);
4718 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab
->MEntry7
),TRUE
);
4719 gtk_widget_show(tab
->MEntry7
);
4720 tab
->MEntry8
= gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4721 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab
->MEntry8
),0);
4722 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab
->MEntry8
),TRUE
);
4723 gtk_widget_show(tab
->MEntry8
);
4725 GtkWidget
*temp_widget
;
4727 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEventBox1a
, FALSE
,
4729 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEventBox1b
, FALSE
,
4731 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEntry1
, FALSE
, FALSE
, 0);
4732 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MText2
, FALSE
, FALSE
, 0);
4733 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEntry2
, FALSE
, FALSE
, 0);
4734 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MText3a
, FALSE
, FALSE
, 0);
4735 temp_widget
= gtk_vseparator_new();
4736 gtk_widget_show(temp_widget
);
4737 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), temp_widget
, FALSE
, FALSE
, 0);
4738 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEventBox3b
, FALSE
,
4740 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEntry3
, FALSE
, FALSE
, 0);
4741 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MText4
, FALSE
, FALSE
, 0);
4742 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEntry4
, FALSE
, FALSE
, 0);
4743 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MText5a
, FALSE
, FALSE
, 0);
4744 temp_widget
= gtk_vseparator_new();
4745 gtk_widget_show(temp_widget
);
4746 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), temp_widget
, FALSE
, FALSE
, 0);
4747 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEventBox8
, FALSE
,
4749 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEntry7
, FALSE
, FALSE
, 0);
4750 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MText9
, FALSE
, FALSE
, 0);
4751 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEntry8
, FALSE
, FALSE
, 0);
4752 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MText10
, FALSE
, FALSE
, 0);
4754 temp_widget
= gtk_vseparator_new();
4755 gtk_widget_show(temp_widget
);
4756 gtk_box_pack_end (GTK_BOX (tab
->MTimebar
), tab
->MText7
, FALSE
, FALSE
, 0);
4757 gtk_box_pack_end (GTK_BOX (tab
->MTimebar
), tab
->MEntry6
, FALSE
, FALSE
, 0);
4758 gtk_box_pack_end (GTK_BOX (tab
->MTimebar
), tab
->MText6
, FALSE
, FALSE
, 0);
4759 gtk_box_pack_end (GTK_BOX (tab
->MTimebar
), tab
->MEntry5
, FALSE
, FALSE
, 0);
4760 gtk_box_pack_end (GTK_BOX (tab
->MTimebar
), tab
->MEventBox5b
, FALSE
,
4762 gtk_box_pack_end (GTK_BOX (tab
->MTimebar
), temp_widget
, FALSE
, FALSE
, 0);
4765 //GtkWidget *test = gtk_button_new_with_label("drop");
4766 //gtk_button_set_relief(GTK_BUTTON(test), GTK_RELIEF_NONE);
4767 //gtk_widget_show(test);
4768 //gtk_box_pack_end(GTK_BOX (tab->MTimebar), test, FALSE, FALSE, 0);
4769 //gtk_widget_add_events(tab->MText1, GDK_ALL_EVENTS_MASK);//GDK_BUTTON_PRESS_MASK);
4770 /*GtkWidget *event_box = gtk_event_box_new();
4771 gtk_widget_show(event_box);
4772 gtk_tooltips_set_tip(tooltips, event_box,
4773 "Paste Current Time Here", "");
4774 gtk_box_pack_end(GTK_BOX (tab->MTimebar), event_box, FALSE, FALSE, 0);
4775 GtkWidget *test = gtk_label_new("drop");
4776 gtk_container_add(GTK_CONTAINER(event_box), test);
4777 gtk_widget_show(test);
4778 g_signal_connect (G_OBJECT(event_box),
4779 "button-press-event",
4780 G_CALLBACK (on_MText1_paste),
4784 g_signal_connect (G_OBJECT(tab
->MEventBox1a
),
4785 "button-press-event",
4786 G_CALLBACK (on_MEventBox1a_paste
),
4789 g_signal_connect (G_OBJECT(tab
->MEventBox1b
),
4790 "button-press-event",
4791 G_CALLBACK (on_MEventBox1b_paste
),
4793 g_signal_connect (G_OBJECT(tab
->MEventBox3b
),
4794 "button-press-event",
4795 G_CALLBACK (on_MEventBox3b_paste
),
4797 g_signal_connect (G_OBJECT(tab
->MEventBox5b
),
4798 "button-press-event",
4799 G_CALLBACK (on_MEventBox5b_paste
),
4801 g_signal_connect (G_OBJECT(tab
->MEventBox8
),
4802 "button-press-event",
4803 G_CALLBACK (on_MEventBox8_paste
),
4807 gtk_box_pack_end(GTK_BOX(tab
->vbox
),
4809 FALSE
, /* Do not expand */
4810 FALSE
, /* Fill has no effect here (expand false) */
4811 0); /* No padding */
4813 gtk_box_pack_end(GTK_BOX(tab
->vbox
),
4815 FALSE
, /* Do not expand */
4816 FALSE
, /* Fill has no effect here (expand false) */
4817 0); /* No padding */
4819 g_object_set_data(G_OBJECT(tab
->viewer_container
), "focused_viewer", NULL
);
4825 // Display a label with a X
4826 GtkWidget *w_hbox = gtk_hbox_new(FALSE, 4);
4827 GtkWidget *w_label = gtk_label_new (label);
4828 GtkWidget *pixmap = create_pixmap(GTK_WIDGET(notebook), "close.png");
4829 GtkWidget *w_button = gtk_button_new ();
4830 gtk_container_add(GTK_CONTAINER(w_button), pixmap);
4831 //GtkWidget *w_button = gtk_button_new_with_label("x");
4833 gtk_button_set_relief(GTK_BUTTON(w_button), GTK_RELIEF_NONE);
4835 gtk_box_pack_start(GTK_BOX(w_hbox), w_label, TRUE, TRUE, 0);
4836 gtk_box_pack_end(GTK_BOX(w_hbox), w_button, FALSE,
4839 g_signal_connect_swapped (w_button, "clicked",
4840 G_CALLBACK (on_close_tab_X_clicked),
4843 gtk_widget_set_state(w_button, GTK_STATE_ACTIVE);
4845 gtk_widget_show (w_label);
4846 gtk_widget_show (pixmap);
4847 gtk_widget_show (w_button);
4848 gtk_widget_show (w_hbox);
4850 tab->label = w_hbox;
4854 tab
->label
= gtk_label_new (label
);
4856 gtk_widget_show(tab
->label
);
4857 gtk_widget_show(tab
->scrollbar
);
4858 gtk_widget_show(tab
->viewer_container
);
4859 gtk_widget_show(tab
->vbox
);
4860 //gtk_widget_show(tab->multivpaned);
4863 /* Start with empty events requests list */
4864 tab
->events_requests
= NULL
;
4865 tab
->events_request_pending
= FALSE
;
4866 tab
->stop_foreground
= FALSE
;
4870 g_signal_connect(G_OBJECT(tab
->scrollbar
), "value-changed",
4871 G_CALLBACK(scroll_value_changed_cb
), tab
);
4873 g_signal_connect ((gpointer
) tab
->MEntry1
, "value-changed",
4874 G_CALLBACK (on_MEntry1_value_changed
),
4876 g_signal_connect ((gpointer
) tab
->MEntry2
, "value-changed",
4877 G_CALLBACK (on_MEntry2_value_changed
),
4879 g_signal_connect ((gpointer
) tab
->MEntry3
, "value-changed",
4880 G_CALLBACK (on_MEntry3_value_changed
),
4882 g_signal_connect ((gpointer
) tab
->MEntry4
, "value-changed",
4883 G_CALLBACK (on_MEntry4_value_changed
),
4885 g_signal_connect ((gpointer
) tab
->MEntry5
, "value-changed",
4886 G_CALLBACK (on_MEntry5_value_changed
),
4888 g_signal_connect ((gpointer
) tab
->MEntry6
, "value-changed",
4889 G_CALLBACK (on_MEntry6_value_changed
),
4891 g_signal_connect ((gpointer
) tab
->MEntry7
, "value-changed",
4892 G_CALLBACK (on_MEntry7_value_changed
),
4894 g_signal_connect ((gpointer
) tab
->MEntry8
, "value-changed",
4895 G_CALLBACK (on_MEntry8_value_changed
),
4898 //g_signal_connect(G_OBJECT(tab->scrollbar), "changed",
4899 // G_CALLBACK(scroll_value_changed_cb), tab);
4902 //insert tab into notebook
4903 gtk_notebook_append_page(notebook
,
4906 list
= gtk_container_get_children(GTK_CONTAINER(notebook
));
4907 gtk_notebook_set_current_page(notebook
,g_list_length(list
)-1);
4908 // always show : not if(g_list_length(list)>1)
4909 gtk_notebook_set_show_tabs(notebook
, TRUE
);
4912 lttvwindow_report_time_window(tab
, copy_tab
->time_window
);
4913 lttvwindow_report_current_time(tab
, copy_tab
->current_time
);
4915 TimeWindow time_window
;
4917 time_window
.start_time
= ltt_time_zero
;
4918 time_window
.end_time
= ltt_time_add(time_window
.start_time
,
4919 lttvwindow_default_time_width
);
4920 time_window
.time_width
= lttvwindow_default_time_width
;
4921 time_window
.time_width_double
= ltt_time_to_double(time_window
.time_width
);
4923 lttvwindow_report_time_window(tab
, time_window
);
4924 lttvwindow_report_current_time(tab
, ltt_time_zero
);
4927 LttvTraceset
*traceset
= tab
->traceset_info
->traceset
;
4928 SetTraceset(tab
, traceset
);
4932 * execute_events_requests
4934 * Idle function that executes the pending requests for a tab.
4936 * @return return value : TRUE : keep the idle function, FALSE : remove it.
4938 gboolean
execute_events_requests(Tab
*tab
)
4940 return ( lttvwindow_process_pending_requests(tab
) );
4944 __EXPORT
void create_main_window_with_trace_list(GSList
*traces
)
4946 GSList
*iter
= NULL
;
4949 MainWindow
*mw
= construct_main_window(NULL
);
4950 GtkWidget
*widget
= mw
->mwindow
;
4952 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
4953 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
4954 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
4955 LttvPluginTab
*ptab
;
4959 ptab
= create_new_tab(widget
, NULL
);
4962 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
4966 for(iter
=traces
; iter
!=NULL
; iter
=g_slist_next(iter
)) {
4967 gchar
*path
= (gchar
*)iter
->data
;
4969 gchar abs_path
[PATH_MAX
];
4973 get_absolute_pathname(path
, abs_path
);
4974 trace_v
= lttvwindowtraces_get_trace_by_name(abs_path
);
4975 if(trace_v
== NULL
) {
4976 trace
= ltt_trace_open(abs_path
);
4978 g_warning("cannot open trace %s", abs_path
);
4980 GtkWidget
*dialogue
=
4981 gtk_message_dialog_new(
4982 GTK_WINDOW(gtk_widget_get_toplevel(widget
)),
4983 GTK_DIALOG_MODAL
|GTK_DIALOG_DESTROY_WITH_PARENT
,
4986 "Cannot open trace : maybe you should enter in the directory "
4988 gtk_dialog_run(GTK_DIALOG(dialogue
));
4989 gtk_widget_destroy(dialogue
);
4991 trace_v
= lttv_trace_new(trace
);
4992 lttvwindowtraces_add_trace(trace_v
);
4993 lttvwindow_add_trace(tab
, trace_v
);
4996 lttvwindow_add_trace(tab
, trace_v
);
5000 LttvTraceset
*traceset
;
5002 traceset
= tab
->traceset_info
->traceset
;
5003 SetTraceset(tab
, traceset
);