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
);
460 * Function to set/update traceset for the viewers
461 * @param tab viewer's tab
462 * @param traceset traceset of the main window.
464 * 0 : traceset updated
465 * 1 : no traceset hooks to update; not an error.
468 int SetTraceset(Tab
* tab
, LttvTraceset
*traceset
)
471 TimeInterval time_span
;
472 TimeWindow new_time_window
;
473 LttTime new_current_time
;
474 LttvTracesetContext
*tsc
=
475 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
477 // Perform time synchronization on the traces
478 /* Mathieu Desnoyers: temporarily disable syncTraceset */
479 //if (syncTraceset(tsc))
482 /* There is some time-dependant information that was calculated during
483 * context initialization. Destroy the old contexts and initialize new
485 * Modified from lttvwindow_add_trace()
487 // Keep a reference to the traces so they are not freed
488 for(i
= 0; i
< lttv_traceset_number(traceset
); i
++)
490 LttvTrace
*trace
= lttv_traceset_get(traceset
, i
);
491 lttv_trace_ref(trace
);
494 // Remove state update hooks
495 lttv_state_remove_event_hooks(
496 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
498 lttv_context_fini(LTTV_TRACESET_CONTEXT(
499 tab
->traceset_info
->traceset_context
));
500 g_object_unref(tab
->traceset_info
->traceset_context
);
502 for(i
= 0; i
< lttv_traceset_number(traceset
); i
++)
504 LttvTrace
*trace
= lttv_traceset_get(traceset
, i
);
505 lttvwindowtraces_remove_trace(trace
);
506 lttvwindowtraces_add_trace(trace
);
509 // Create new context
510 tab
->traceset_info
->traceset_context
=
511 g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
512 lttv_context_init(LTTV_TRACESET_CONTEXT(tab
->traceset_info
->
513 traceset_context
), traceset
);
515 // Add state update hooks
516 lttv_state_add_event_hooks(
517 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
519 // Remove local reference to the traces
520 for(i
=0; i
<lttv_traceset_number(traceset
); i
++)
522 LttvTrace
*trace
= lttv_traceset_get(traceset
, i
);
523 lttv_trace_unref(trace
);
526 tsc
= LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
529 time_span
= tsc
->time_span
;
530 new_time_window
= tab
->time_window
;
531 new_current_time
= tab
->current_time
;
533 /* Set the tab's time window and current time if
535 if(ltt_time_compare(tab
->time_window
.start_time
, time_span
.start_time
) < 0
536 || ltt_time_compare(tab
->time_window
.end_time
,
537 time_span
.end_time
) > 0) {
538 new_time_window
.start_time
= time_span
.start_time
;
540 new_current_time
= time_span
.start_time
;
544 if(ltt_time_compare(lttvwindow_default_time_width
,
545 ltt_time_sub(time_span
.end_time
, time_span
.start_time
)) < 0
547 ltt_time_compare(time_span
.end_time
, time_span
.start_time
) == 0)
548 tmp_time
= lttvwindow_default_time_width
;
550 tmp_time
= time_span
.end_time
;
552 new_time_window
.time_width
= tmp_time
;
553 new_time_window
.time_width_double
= ltt_time_to_double(tmp_time
);
554 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
555 new_time_window
.time_width
) ;
562 GtkAdjustment
*adjustment
= gtk_range_get_adjustment(GTK_RANGE(tab
->scrollbar
));
563 LttTime upper
= ltt_time_sub(time_span
.end_time
, time_span
.start_time
);
565 g_object_set(G_OBJECT(adjustment
),
569 ltt_time_to_double(upper
)
570 * NANOSECONDS_PER_SECOND
, /* upper */
572 ltt_time_to_double(tab
->time_window
.time_width
)
573 / SCROLL_STEP_PER_PAGE
574 * NANOSECONDS_PER_SECOND
, /* step increment */
576 ltt_time_to_double(tab
->time_window
.time_width
)
577 * NANOSECONDS_PER_SECOND
, /* page increment */
579 ltt_time_to_double(tab
->time_window
.time_width
)
580 * NANOSECONDS_PER_SECOND
, /* page size */
582 gtk_adjustment_changed(adjustment
);
584 g_object_set(G_OBJECT(adjustment
),
587 ltt_time_sub(tab
->time_window
.start_time
, time_span
.start_time
))
588 * NANOSECONDS_PER_SECOND
, /* value */
590 gtk_adjustment_value_changed(adjustment
);
592 /* set the time bar. The value callbacks will change their nsec themself */
594 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry1
),
595 (double)time_span
.start_time
.tv_sec
,
596 (double)time_span
.end_time
.tv_sec
);
599 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry3
),
600 (double)time_span
.start_time
.tv_sec
,
601 (double)time_span
.end_time
.tv_sec
);
603 /* current seconds */
604 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry5
),
605 (double)time_span
.start_time
.tv_sec
,
606 (double)time_span
.end_time
.tv_sec
);
609 /* Finally, call the update hooks of the viewers */
611 LttvAttributeValue value
;
614 retval
= lttv_iattribute_find_by_path(tab
->attributes
,
615 "hooks/updatetraceset", LTTV_POINTER
, &value
);
618 tmp
= (LttvHooks
*)*(value
.v_pointer
);
622 lttv_hooks_call(tmp
,traceset
);
624 time_change_manager(tab
, new_time_window
);
625 current_time_change_manager(tab
, new_current_time
);
631 * Function to set/update filter for the viewers
632 * @param tab viewer's tab
633 * @param filter filter of the main window.
636 * 0 : filters updated
637 * 1 : no filter hooks to update; not an error.
640 int SetFilter(Tab
* tab
, gpointer filter
)
643 LttvAttributeValue value
;
645 g_assert(lttv_iattribute_find_by_path(tab
->attributes
,
646 "hooks/updatefilter", LTTV_POINTER
, &value
));
648 tmp
= (LttvHooks
*)*(value
.v_pointer
);
650 if(tmp
== NULL
) return 1;
651 lttv_hooks_call(tmp
,filter
);
659 * Function to redraw each viewer belonging to the current tab
660 * @param tab viewer's tab
663 void update_traceset(Tab
*tab
)
665 LttvAttributeValue value
;
669 retval
= lttv_iattribute_find_by_path(tab
->attributes
,
670 "hooks/updatetraceset", LTTV_POINTER
, &value
);
672 tmp
= (LttvHooks
*)*(value
.v_pointer
);
673 if(tmp
== NULL
) return;
674 lttv_hooks_call(tmp
, NULL
);
678 /* get_label function is used to get user input, it displays an input
679 * box, which allows user to input a string
682 void get_label_string (GtkWidget
* text
, gchar
* label
)
684 GtkEntry
* entry
= (GtkEntry
*)text
;
685 if(strlen(gtk_entry_get_text(entry
))!=0)
686 strcpy(label
,gtk_entry_get_text(entry
));
689 gboolean
get_label(MainWindow
* mw
, gchar
* str
, gchar
* dialogue_title
, gchar
* label_str
)
691 GtkWidget
* dialogue
;
696 dialogue
= gtk_dialog_new_with_buttons(dialogue_title
,NULL
,
698 GTK_STOCK_OK
,GTK_RESPONSE_ACCEPT
,
699 GTK_STOCK_CANCEL
,GTK_RESPONSE_REJECT
,
702 label
= gtk_label_new(label_str
);
703 gtk_widget_show(label
);
705 text
= gtk_entry_new();
706 gtk_widget_show(text
);
708 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialogue
)->vbox
), label
,TRUE
, TRUE
,0);
709 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialogue
)->vbox
), text
,FALSE
, FALSE
,0);
711 id
= gtk_dialog_run(GTK_DIALOG(dialogue
));
713 case GTK_RESPONSE_ACCEPT
:
714 get_label_string(text
,str
);
715 gtk_widget_destroy(dialogue
);
717 case GTK_RESPONSE_REJECT
:
719 gtk_widget_destroy(dialogue
);
726 /* get_window_data_struct function is actually a lookup function,
727 * given a widget which is in the tree of the main window, it will
728 * return the MainWindow data structure associated with main window
731 MainWindow
* get_window_data_struct(GtkWidget
* widget
)
734 MainWindow
* mw_data
;
736 mw
= lookup_widget(widget
, "MWindow");
738 g_info("Main window does not exist\n");
742 mw_data
= (MainWindow
*) g_object_get_data(G_OBJECT(mw
),"main_window_data");
744 g_warning("Main window data does not exist\n");
751 /* create_new_window function, just constructs a new main window
754 void create_new_window(GtkWidget
* widget
, gpointer user_data
, gboolean clone
)
756 MainWindow
* parent
= get_window_data_struct(widget
);
759 g_info("Clone : use the same traceset\n");
760 construct_main_window(parent
);
762 g_info("Empty : traceset is set to NULL\n");
763 construct_main_window(NULL
);
767 /* Get the currently focused viewer.
768 * If no viewer is focused, use the first one.
770 * If no viewer available, return NULL.
772 GtkWidget
*viewer_container_focus(GtkWidget
*container
)
776 widget
= (GtkWidget
*)g_object_get_data(G_OBJECT(container
),
780 g_debug("no widget focused");
781 GList
*children
= gtk_container_get_children(GTK_CONTAINER(container
));
784 widget
= GTK_WIDGET(children
->data
);
785 g_object_set_data(G_OBJECT(container
),
795 gint
viewer_container_position(GtkWidget
*container
, GtkWidget
*child
)
798 if(child
== NULL
) return -1;
802 memset(&value
, 0, sizeof(GValue
));
803 g_value_init(&value
, G_TYPE_INT
);
804 gtk_container_child_get_property(GTK_CONTAINER(container
),
808 pos
= g_value_get_int(&value
);
814 /* move_*_viewer functions move the selected view up/down in
818 void move_down_viewer(GtkWidget
* widget
, gpointer user_data
)
820 MainWindow
* mw
= get_window_data_struct(widget
);
821 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
823 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
824 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
831 ptab
= g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
835 //gtk_multivpaned_widget_move_up(GTK_MULTIVPANED(tab->multivpaned));
837 /* change the position in the vbox */
838 GtkWidget
*focus_widget
;
840 focus_widget
= viewer_container_focus(tab
->viewer_container
);
841 position
= viewer_container_position(tab
->viewer_container
, focus_widget
);
844 /* can move up one position */
845 gtk_box_reorder_child(GTK_BOX(tab
->viewer_container
),
852 void move_up_viewer(GtkWidget
* widget
, gpointer user_data
)
854 MainWindow
* mw
= get_window_data_struct(widget
);
855 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
857 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
858 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
865 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
869 //gtk_multivpaned_widget_move_down(GTK_MULTIVPANED(tab->multivpaned));
870 /* change the position in the vbox */
871 GtkWidget
*focus_widget
;
873 focus_widget
= viewer_container_focus(tab
->viewer_container
);
874 position
= viewer_container_position(tab
->viewer_container
, focus_widget
);
878 g_list_length(gtk_container_get_children(
879 GTK_CONTAINER(tab
->viewer_container
)))-1
881 /* can move down one position */
882 gtk_box_reorder_child(GTK_BOX(tab
->viewer_container
),
890 /* delete_viewer deletes the selected viewer in the current tab
893 void delete_viewer(GtkWidget
* widget
, gpointer user_data
)
895 MainWindow
* mw
= get_window_data_struct(widget
);
896 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
898 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
899 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
906 ptab
= g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
910 //gtk_multivpaned_widget_delete(GTK_MULTIVPANED(tab->multivpaned));
912 GtkWidget
*focus_widget
= viewer_container_focus(tab
->viewer_container
);
914 if(focus_widget
!= NULL
)
915 gtk_widget_destroy(focus_widget
);
917 g_object_set_data(G_OBJECT(tab
->viewer_container
), "focused_viewer", NULL
);
921 /* open_traceset will open a traceset saved in a file
922 * Right now, it is not finished yet, (not working)
926 void open_traceset(GtkWidget
* widget
, gpointer user_data
)
930 LttvTraceset
* traceset
;
931 MainWindow
* mw_data
= get_window_data_struct(widget
);
932 GtkFileSelection
* file_selector
=
933 (GtkFileSelection
*)gtk_file_selection_new("Select a traceset");
935 gtk_file_selection_hide_fileop_buttons(file_selector
);
937 gtk_window_set_transient_for(GTK_WINDOW(file_selector
),
938 GTK_WINDOW(mw_data
->mwindow
));
940 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
942 case GTK_RESPONSE_ACCEPT
:
943 case GTK_RESPONSE_OK
:
944 dir
= gtk_file_selection_get_selections (file_selector
);
945 traceset
= lttv_traceset_load(dir
[0]);
946 g_info("Open a trace set %s\n", dir
[0]);
949 case GTK_RESPONSE_REJECT
:
950 case GTK_RESPONSE_CANCEL
:
952 gtk_widget_destroy((GtkWidget
*)file_selector
);
958 /* lttvwindow_process_pending_requests
960 * Process requests for parts of the trace from viewers.
962 * These requests are made by lttvwindow_events_request().
964 * This internal function gets called by g_idle, taking care of the pending
965 * requests. It is responsible for concatenation of time intervals and position
966 * requests. It does it with the following algorithm organizing process traceset
967 * calls. Here is the detailed description of the way it works :
969 * - Events Requests Servicing Algorithm
971 * Data structures necessary :
973 * List of requests added to context : list_in
974 * List of requests not added to context : list_out
979 * list_out : many events requests
981 * FIXME : insert rest of algorithm here
985 #define list_out tab->events_requests
987 gboolean
lttvwindow_process_pending_requests(Tab
*tab
)
990 LttvTracesetContext
*tsc
;
991 LttvTracefileContext
*tfc
;
992 GSList
*list_in
= NULL
;
996 LttvTracesetContextPosition
*end_position
;
998 if(lttvwindow_preempt_count
> 0) return TRUE
;
1001 g_critical("Foreground processing : tab does not exist. Processing removed.");
1005 /* There is no events requests pending : we should never have been called! */
1006 g_assert(g_slist_length(list_out
) != 0);
1008 tsc
= LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
1010 //set the cursor to be X shape, indicating that the computer is busy in doing its job
1012 new = gdk_cursor_new(GDK_X_CURSOR
);
1013 widget
= lookup_widget(tab
->mw
->mwindow
, "MToolbar1");
1014 win
= gtk_widget_get_parent_window(widget
);
1015 gdk_window_set_cursor(win
, new);
1016 gdk_cursor_unref(new);
1017 gdk_window_stick(win
);
1018 gdk_window_unstick(win
);
1021 g_debug("SIZE events req len : %d", g_slist_length(list_out
));
1023 /* Preliminary check for no trace in traceset */
1024 /* Unregister the routine if empty, empty list_out too */
1025 if(lttv_traceset_number(tsc
->ts
) == 0) {
1027 /* - For each req in list_out */
1028 GSList
*iter
= list_out
;
1030 while(iter
!= NULL
) {
1032 gboolean remove
= FALSE
;
1033 gboolean free_data
= FALSE
;
1034 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1036 /* - Call end request for req */
1037 if(events_request
->servicing
== TRUE
)
1038 lttv_hooks_call(events_request
->after_request
, (gpointer
)tsc
);
1040 /* - remove req from list_out */
1041 /* Destroy the request */
1048 GSList
*remove_iter
= iter
;
1050 iter
= g_slist_next(iter
);
1051 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
1052 list_out
= g_slist_remove_link(list_out
, remove_iter
);
1053 } else { // not remove
1054 iter
= g_slist_next(iter
);
1059 /* 0.1 Lock Traces */
1064 iter_trace
<lttv_traceset_number(tsc
->ts
);
1066 LttvTrace
*trace_v
= lttv_traceset_get(tsc
->ts
, iter_trace
);
1068 if(lttvwindowtraces_lock(trace_v
) != 0) {
1069 g_critical("Foreground processing : Unable to get trace lock");
1070 return TRUE
; /* Cannot get lock, try later */
1075 /* 0.2 Seek tracefiles positions to context position */
1076 //g_assert(lttv_process_traceset_seek_position(tsc, sync_position) == 0);
1077 lttv_process_traceset_synchronize_tracefiles(tsc
);
1080 /* Events processing algorithm implementation */
1081 /* Warning : the gtk_events_pending takes a LOT of cpu time. So what we do
1082 * instead is to leave the control to GTK and take it back.
1084 /* A. Servicing loop */
1085 //while( (g_slist_length(list_in) != 0 || g_slist_length(list_out) != 0)) {
1086 if((g_slist_length(list_in
) != 0 || g_slist_length(list_out
) != 0)) {
1088 /* 1. If list_in is empty (need a seek) */
1089 if( g_slist_length(list_in
) == 0 ) {
1091 /* list in is empty, need a seek */
1093 /* 1.1 Add requests to list_in */
1094 GSList
*ltime
= NULL
;
1095 GSList
*lpos
= NULL
;
1096 GSList
*iter
= NULL
;
1098 /* 1.1.1 Find all time requests with the lowest start time in list_out
1101 if(g_slist_length(list_out
) > 0)
1102 ltime
= g_slist_append(ltime
, g_slist_nth_data(list_out
, 0));
1103 for(iter
=g_slist_nth(list_out
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
1104 /* Find all time requests with the lowest start time in list_out */
1105 EventsRequest
*event_request_ltime
= (EventsRequest
*)g_slist_nth_data(ltime
, 0);
1106 EventsRequest
*event_request_list_out
= (EventsRequest
*)iter
->data
;
1109 comp
= ltt_time_compare(event_request_ltime
->start_time
,
1110 event_request_list_out
->start_time
);
1112 ltime
= g_slist_append(ltime
, event_request_list_out
);
1114 /* Remove all elements from ltime, and add current */
1115 while(ltime
!= NULL
)
1116 ltime
= g_slist_delete_link(ltime
, g_slist_nth(ltime
, 0));
1117 ltime
= g_slist_append(ltime
, event_request_list_out
);
1121 /* 1.1.2 Find all position requests with the lowest position in list_out
1124 if(g_slist_length(list_out
) > 0)
1125 lpos
= g_slist_append(lpos
, g_slist_nth_data(list_out
, 0));
1126 for(iter
=g_slist_nth(list_out
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
1127 /* Find all position requests with the lowest position in list_out */
1128 EventsRequest
*event_request_lpos
= (EventsRequest
*)g_slist_nth_data(lpos
, 0);
1129 EventsRequest
*event_request_list_out
= (EventsRequest
*)iter
->data
;
1132 if(event_request_lpos
->start_position
!= NULL
1133 && event_request_list_out
->start_position
!= NULL
)
1135 comp
= lttv_traceset_context_pos_pos_compare
1136 (event_request_lpos
->start_position
,
1137 event_request_list_out
->start_position
);
1142 lpos
= g_slist_append(lpos
, event_request_list_out
);
1144 /* Remove all elements from lpos, and add current */
1146 lpos
= g_slist_delete_link(lpos
, g_slist_nth(lpos
, 0));
1147 lpos
= g_slist_append(lpos
, event_request_list_out
);
1152 EventsRequest
*event_request_lpos
= (EventsRequest
*)g_slist_nth_data(lpos
, 0);
1153 EventsRequest
*event_request_ltime
= (EventsRequest
*)g_slist_nth_data(ltime
, 0);
1154 LttTime lpos_start_time
;
1156 if(event_request_lpos
!= NULL
1157 && event_request_lpos
->start_position
!= NULL
) {
1158 lpos_start_time
= lttv_traceset_context_position_get_time(
1159 event_request_lpos
->start_position
);
1162 /* 1.1.3 If lpos.start time < ltime */
1163 if(event_request_lpos
!= NULL
1164 && event_request_lpos
->start_position
!= NULL
1165 && ltt_time_compare(lpos_start_time
,
1166 event_request_ltime
->start_time
)<0) {
1167 /* Add lpos to list_in, remove them from list_out */
1168 for(iter
=lpos
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
1169 /* Add to list_in */
1170 EventsRequest
*event_request_lpos
=
1171 (EventsRequest
*)iter
->data
;
1173 list_in
= g_slist_append(list_in
, event_request_lpos
);
1174 /* Remove from list_out */
1175 list_out
= g_slist_remove(list_out
, event_request_lpos
);
1178 /* 1.1.4 (lpos.start time >= ltime) */
1179 /* Add ltime to list_in, remove them from list_out */
1181 for(iter
=ltime
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
1182 /* Add to list_in */
1183 EventsRequest
*event_request_ltime
=
1184 (EventsRequest
*)iter
->data
;
1186 list_in
= g_slist_append(list_in
, event_request_ltime
);
1187 /* Remove from list_out */
1188 list_out
= g_slist_remove(list_out
, event_request_ltime
);
1193 g_slist_free(ltime
);
1198 tfc
= lttv_traceset_context_get_current_tfc(tsc
);
1199 g_assert(g_slist_length(list_in
)>0);
1200 EventsRequest
*events_request
= g_slist_nth_data(list_in
, 0);
1203 /* 1.2.1 If first request in list_in is a time request */
1204 if(events_request
->start_position
== NULL
) {
1205 /* - If first req in list_in start time != current time */
1206 if(tfc
== NULL
|| ltt_time_compare(events_request
->start_time
,
1207 tfc
->timestamp
) != 0)
1208 /* - Seek to that time */
1209 g_debug("SEEK TIME : %lu, %lu", events_request
->start_time
.tv_sec
,
1210 events_request
->start_time
.tv_nsec
);
1211 //lttv_process_traceset_seek_time(tsc, events_request->start_time);
1212 lttv_state_traceset_seek_time_closest(LTTV_TRACESET_STATE(tsc
),
1213 events_request
->start_time
);
1215 /* Process the traceset with only state hooks */
1217 lttv_process_traceset_middle(tsc
,
1218 events_request
->start_time
,
1221 g_assert(seek_count
< LTTV_STATE_SAVE_INTERVAL
);
1227 LttvTracefileContext
*tfc
=
1228 lttv_traceset_context_get_current_tfc(tsc
);
1229 /* Else, the first request in list_in is a position request */
1230 /* If first req in list_in pos != current pos */
1231 g_assert(events_request
->start_position
!= NULL
);
1232 g_debug("SEEK POS time : %lu, %lu",
1233 lttv_traceset_context_position_get_time(
1234 events_request
->start_position
).tv_sec
,
1235 lttv_traceset_context_position_get_time(
1236 events_request
->start_position
).tv_nsec
);
1239 g_debug("SEEK POS context time : %lu, %lu",
1240 tfc
->timestamp
.tv_sec
,
1241 tfc
->timestamp
.tv_nsec
);
1243 g_debug("SEEK POS context time : %lu, %lu",
1244 ltt_time_infinite
.tv_sec
,
1245 ltt_time_infinite
.tv_nsec
);
1247 g_assert(events_request
->start_position
!= NULL
);
1248 if(lttv_traceset_context_ctx_pos_compare(tsc
,
1249 events_request
->start_position
) != 0) {
1250 /* 1.2.2.1 Seek to that position */
1251 g_debug("SEEK POSITION");
1252 //lttv_process_traceset_seek_position(tsc, events_request->start_position);
1253 pos_time
= lttv_traceset_context_position_get_time(
1254 events_request
->start_position
);
1256 lttv_state_traceset_seek_time_closest(LTTV_TRACESET_STATE(tsc
),
1259 /* Process the traceset with only state hooks */
1261 lttv_process_traceset_middle(tsc
,
1264 events_request
->start_position
);
1265 g_assert(lttv_traceset_context_ctx_pos_compare(tsc
,
1266 events_request
->start_position
) == 0);
1273 /* 1.3 Add hooks and call before request for all list_in members */
1275 GSList
*iter
= NULL
;
1277 for(iter
=list_in
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
1278 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1279 /* 1.3.1 If !servicing */
1280 if(events_request
->servicing
== FALSE
) {
1281 /* - begin request hooks called
1282 * - servicing = TRUE
1284 lttv_hooks_call(events_request
->before_request
, (gpointer
)tsc
);
1285 events_request
->servicing
= TRUE
;
1287 /* 1.3.2 call before chunk
1288 * 1.3.3 events hooks added
1290 if(events_request
->trace
== -1)
1291 lttv_process_traceset_begin(tsc
,
1292 events_request
->before_chunk_traceset
,
1293 events_request
->before_chunk_trace
,
1294 events_request
->before_chunk_tracefile
,
1295 events_request
->event
,
1296 events_request
->event_by_id_channel
);
1298 guint nb_trace
= lttv_traceset_number(tsc
->ts
);
1299 g_assert((guint
)events_request
->trace
< nb_trace
&&
1300 events_request
->trace
> -1);
1301 LttvTraceContext
*tc
= tsc
->traces
[events_request
->trace
];
1303 lttv_hooks_call(events_request
->before_chunk_traceset
, tsc
);
1305 lttv_trace_context_add_hooks(tc
,
1306 events_request
->before_chunk_trace
,
1307 events_request
->before_chunk_tracefile
,
1308 events_request
->event
,
1309 events_request
->event_by_id_channel
);
1314 /* 2. Else, list_in is not empty, we continue a read */
1317 /* 2.0 For each req of list_in */
1318 GSList
*iter
= list_in
;
1320 while(iter
!= NULL
) {
1322 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1324 /* - Call before chunk
1325 * - events hooks added
1327 if(events_request
->trace
== -1)
1328 lttv_process_traceset_begin(tsc
,
1329 events_request
->before_chunk_traceset
,
1330 events_request
->before_chunk_trace
,
1331 events_request
->before_chunk_tracefile
,
1332 events_request
->event
,
1333 events_request
->event_by_id_channel
);
1335 guint nb_trace
= lttv_traceset_number(tsc
->ts
);
1336 g_assert((guint
)events_request
->trace
< nb_trace
&&
1337 events_request
->trace
> -1);
1338 LttvTraceContext
*tc
= tsc
->traces
[events_request
->trace
];
1340 lttv_hooks_call(events_request
->before_chunk_traceset
, tsc
);
1342 lttv_trace_context_add_hooks(tc
,
1343 events_request
->before_chunk_trace
,
1344 events_request
->before_chunk_tracefile
,
1345 events_request
->event
,
1346 events_request
->event_by_id_channel
);
1349 iter
= g_slist_next(iter
);
1354 tfc
= lttv_traceset_context_get_current_tfc(tsc
);
1356 /* 2.1 For each req of list_out */
1357 GSList
*iter
= list_out
;
1359 while(iter
!= NULL
) {
1361 gboolean remove
= FALSE
;
1362 gboolean free_data
= FALSE
;
1363 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1365 /* if req.start time == current context time
1366 * or req.start position == current position*/
1367 if( ltt_time_compare(events_request
->start_time
,
1368 tfc
->timestamp
) == 0
1370 (events_request
->start_position
!= NULL
1372 lttv_traceset_context_ctx_pos_compare(tsc
,
1373 events_request
->start_position
) == 0)
1375 /* - Add to list_in, remove from list_out */
1376 list_in
= g_slist_append(list_in
, events_request
);
1380 /* - If !servicing */
1381 if(events_request
->servicing
== FALSE
) {
1382 /* - begin request hooks called
1383 * - servicing = TRUE
1385 lttv_hooks_call(events_request
->before_request
, (gpointer
)tsc
);
1386 events_request
->servicing
= TRUE
;
1388 /* call before chunk
1389 * events hooks added
1391 if(events_request
->trace
== -1)
1392 lttv_process_traceset_begin(tsc
,
1393 events_request
->before_chunk_traceset
,
1394 events_request
->before_chunk_trace
,
1395 events_request
->before_chunk_tracefile
,
1396 events_request
->event
,
1397 events_request
->event_by_id_channel
);
1399 guint nb_trace
= lttv_traceset_number(tsc
->ts
);
1400 g_assert((guint
)events_request
->trace
< nb_trace
&&
1401 events_request
->trace
> -1);
1402 LttvTraceContext
*tc
= tsc
->traces
[events_request
->trace
];
1404 lttv_hooks_call(events_request
->before_chunk_traceset
, tsc
);
1406 lttv_trace_context_add_hooks(tc
,
1407 events_request
->before_chunk_trace
,
1408 events_request
->before_chunk_tracefile
,
1409 events_request
->event
,
1410 events_request
->event_by_id_channel
);
1419 GSList
*remove_iter
= iter
;
1421 iter
= g_slist_next(iter
);
1422 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
1423 list_out
= g_slist_remove_link(list_out
, remove_iter
);
1424 } else { // not remove
1425 iter
= g_slist_next(iter
);
1431 /* 3. Find end criterions */
1436 /* 3.1.1 Find lowest end time in list_in */
1437 g_assert(g_slist_length(list_in
)>0);
1438 end_time
= ((EventsRequest
*)g_slist_nth_data(list_in
,0))->end_time
;
1440 for(iter
=g_slist_nth(list_in
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
1441 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1443 if(ltt_time_compare(events_request
->end_time
,
1445 end_time
= events_request
->end_time
;
1448 /* 3.1.2 Find lowest start time in list_out */
1449 for(iter
=list_out
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
1450 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1452 if(ltt_time_compare(events_request
->start_time
,
1454 end_time
= events_request
->start_time
;
1459 /* 3.2 Number of events */
1461 /* 3.2.1 Find lowest number of events in list_in */
1464 end_nb_events
= ((EventsRequest
*)g_slist_nth_data(list_in
,0))->num_events
;
1466 for(iter
=g_slist_nth(list_in
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
1467 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1469 if(events_request
->num_events
< end_nb_events
)
1470 end_nb_events
= events_request
->num_events
;
1473 /* 3.2.2 Use min(CHUNK_NUM_EVENTS, min num events in list_in) as
1476 end_nb_events
= MIN(CHUNK_NUM_EVENTS
, end_nb_events
);
1480 /* 3.3 End position */
1482 /* 3.3.1 Find lowest end position in list_in */
1485 end_position
=((EventsRequest
*)g_slist_nth_data(list_in
,0))->end_position
;
1487 for(iter
=g_slist_nth(list_in
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
1488 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1490 if(events_request
->end_position
!= NULL
&& end_position
!= NULL
&&
1491 lttv_traceset_context_pos_pos_compare(events_request
->end_position
,
1493 end_position
= events_request
->end_position
;
1498 /* 3.3.2 Find lowest start position in list_out */
1501 for(iter
=list_out
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
1502 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1504 if(events_request
->end_position
!= NULL
&& end_position
!= NULL
&&
1505 lttv_traceset_context_pos_pos_compare(events_request
->end_position
,
1507 end_position
= events_request
->end_position
;
1512 /* 4. Call process traceset middle */
1513 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
);
1514 count
= lttv_process_traceset_middle(tsc
, end_time
, end_nb_events
, end_position
);
1516 tfc
= lttv_traceset_context_get_current_tfc(tsc
);
1518 g_debug("Context time after middle : %lu, %lu", tfc
->timestamp
.tv_sec
,
1519 tfc
->timestamp
.tv_nsec
);
1521 g_debug("End of trace reached after middle.");
1525 /* 5. After process traceset middle */
1526 tfc
= lttv_traceset_context_get_current_tfc(tsc
);
1528 /* - if current context time > traceset.end time */
1529 if(tfc
== NULL
|| ltt_time_compare(tfc
->timestamp
,
1530 tsc
->time_span
.end_time
) > 0) {
1531 /* - For each req in list_in */
1532 GSList
*iter
= list_in
;
1534 while(iter
!= NULL
) {
1536 gboolean remove
= FALSE
;
1537 gboolean free_data
= FALSE
;
1538 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1540 /* - Remove events hooks for req
1541 * - Call end chunk for req
1544 if(events_request
->trace
== -1)
1545 lttv_process_traceset_end(tsc
,
1546 events_request
->after_chunk_traceset
,
1547 events_request
->after_chunk_trace
,
1548 events_request
->after_chunk_tracefile
,
1549 events_request
->event
,
1550 events_request
->event_by_id_channel
);
1553 guint nb_trace
= lttv_traceset_number(tsc
->ts
);
1554 g_assert(events_request
->trace
< nb_trace
&&
1555 events_request
->trace
> -1);
1556 LttvTraceContext
*tc
= tsc
->traces
[events_request
->trace
];
1558 lttv_trace_context_remove_hooks(tc
,
1559 events_request
->after_chunk_trace
,
1560 events_request
->after_chunk_tracefile
,
1561 events_request
->event
,
1562 events_request
->event_by_id_channel
);
1563 lttv_hooks_call(events_request
->after_chunk_traceset
, tsc
);
1568 /* - Call end request for req */
1569 lttv_hooks_call(events_request
->after_request
, (gpointer
)tsc
);
1571 /* - remove req from list_in */
1572 /* Destroy the request */
1579 GSList
*remove_iter
= iter
;
1581 iter
= g_slist_next(iter
);
1582 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
1583 list_in
= g_slist_remove_link(list_in
, remove_iter
);
1584 } else { // not remove
1585 iter
= g_slist_next(iter
);
1590 /* 5.1 For each req in list_in */
1591 GSList
*iter
= list_in
;
1593 while(iter
!= NULL
) {
1595 gboolean remove
= FALSE
;
1596 gboolean free_data
= FALSE
;
1597 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1599 /* - Remove events hooks for req
1600 * - Call end chunk for req
1602 if(events_request
->trace
== -1)
1603 lttv_process_traceset_end(tsc
,
1604 events_request
->after_chunk_traceset
,
1605 events_request
->after_chunk_trace
,
1606 events_request
->after_chunk_tracefile
,
1607 events_request
->event
,
1608 events_request
->event_by_id_channel
);
1611 guint nb_trace
= lttv_traceset_number(tsc
->ts
);
1612 g_assert(events_request
->trace
< nb_trace
&&
1613 events_request
->trace
> -1);
1614 LttvTraceContext
*tc
= tsc
->traces
[events_request
->trace
];
1616 lttv_trace_context_remove_hooks(tc
,
1617 events_request
->after_chunk_trace
,
1618 events_request
->after_chunk_tracefile
,
1619 events_request
->event
,
1620 events_request
->event_by_id_channel
);
1622 lttv_hooks_call(events_request
->after_chunk_traceset
, tsc
);
1625 /* - req.num -= count */
1626 g_assert(events_request
->num_events
>= count
);
1627 events_request
->num_events
-= count
;
1629 g_assert(tfc
!= NULL
);
1630 /* - if req.num == 0
1632 * current context time >= req.end time
1634 * req.end pos == current pos
1636 * req.stop_flag == TRUE
1638 if( events_request
->num_events
== 0
1640 events_request
->stop_flag
== TRUE
1642 ltt_time_compare(tfc
->timestamp
,
1643 events_request
->end_time
) >= 0
1645 (events_request
->end_position
!= NULL
1647 lttv_traceset_context_ctx_pos_compare(tsc
,
1648 events_request
->end_position
) == 0)
1651 g_assert(events_request
->servicing
== TRUE
);
1652 /* - Call end request for req
1653 * - remove req from list_in */
1654 lttv_hooks_call(events_request
->after_request
, (gpointer
)tsc
);
1655 /* - remove req from list_in */
1656 /* Destroy the request */
1664 GSList
*remove_iter
= iter
;
1666 iter
= g_slist_next(iter
);
1667 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
1668 list_in
= g_slist_remove_link(list_in
, remove_iter
);
1669 } else { // not remove
1670 iter
= g_slist_next(iter
);
1676 /* End of removed servicing loop : leave control to GTK instead. */
1677 // if(gtk_events_pending()) break;
1680 /* B. When interrupted between chunks */
1683 GSList
*iter
= list_in
;
1685 /* 1. for each request in list_in */
1686 while(iter
!= NULL
) {
1688 gboolean remove
= FALSE
;
1689 gboolean free_data
= FALSE
;
1690 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1692 /* 1.1. Use current postition as start position */
1693 if(events_request
->start_position
!= NULL
)
1694 lttv_traceset_context_position_destroy(events_request
->start_position
);
1695 events_request
->start_position
= lttv_traceset_context_position_new(tsc
);
1696 lttv_traceset_context_position_save(tsc
, events_request
->start_position
);
1698 /* 1.2. Remove start time */
1699 events_request
->start_time
= ltt_time_infinite
;
1701 /* 1.3. Move from list_in to list_out */
1704 list_out
= g_slist_append(list_out
, events_request
);
1709 GSList
*remove_iter
= iter
;
1711 iter
= g_slist_next(iter
);
1712 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
1713 list_in
= g_slist_remove_link(list_in
, remove_iter
);
1714 } else { // not remove
1715 iter
= g_slist_next(iter
);
1721 /* C Unlock Traces */
1723 lttv_process_traceset_get_sync_data(tsc
);
1724 //lttv_traceset_context_position_save(tsc, sync_position);
1729 iter_trace
<lttv_traceset_number(tsc
->ts
);
1731 LttvTrace
*trace_v
= lttv_traceset_get(tsc
->ts
, iter_trace
);
1733 lttvwindowtraces_unlock(trace_v
);
1737 //set the cursor back to normal
1738 gdk_window_set_cursor(win
, NULL
);
1741 g_assert(g_slist_length(list_in
) == 0);
1743 if( g_slist_length(list_out
) == 0 ) {
1744 /* Put tab's request pending flag back to normal */
1745 tab
->events_request_pending
= FALSE
;
1746 g_debug("remove the idle fct");
1747 return FALSE
; /* Remove the idle function */
1749 g_debug("leave the idle fct");
1750 return TRUE
; /* Leave the idle function */
1752 /* We do not use simili-round-robin, it may require to read 1 meg buffers
1753 * again and again if many tracesets use the same tracefiles. */
1754 /* Hack for round-robin idle functions */
1755 /* It will put the idle function at the end of the pool */
1756 /*g_idle_add_full((G_PRIORITY_HIGH_IDLE + 21),
1757 (GSourceFunc)execute_events_requests,
1767 static void lttvwindow_add_trace(Tab
*tab
, LttvTrace
*trace_v
)
1769 LttvTraceset
*traceset
= tab
->traceset_info
->traceset
;
1771 guint num_traces
= lttv_traceset_number(traceset
);
1773 //Verify if trace is already present.
1774 for(i
=0; i
<num_traces
; i
++)
1776 LttvTrace
* trace
= lttv_traceset_get(traceset
, i
);
1777 if(trace
== trace_v
)
1781 //Keep a reference to the traces so they are not freed.
1782 for(i
=0; i
<lttv_traceset_number(traceset
); i
++)
1784 LttvTrace
* trace
= lttv_traceset_get(traceset
, i
);
1785 lttv_trace_ref(trace
);
1788 //remove state update hooks
1789 lttv_state_remove_event_hooks(
1790 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1792 lttv_context_fini(LTTV_TRACESET_CONTEXT(
1793 tab
->traceset_info
->traceset_context
));
1794 g_object_unref(tab
->traceset_info
->traceset_context
);
1796 lttv_traceset_add(traceset
, trace_v
);
1797 lttv_trace_ref(trace_v
); /* local ref */
1799 /* Create new context */
1800 tab
->traceset_info
->traceset_context
=
1801 g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
1803 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->
1808 //add state update hooks
1809 lttv_state_add_event_hooks(
1810 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1811 //Remove local reference to the traces.
1812 for(i
=0; i
<lttv_traceset_number(traceset
); i
++)
1814 LttvTrace
* trace
= lttv_traceset_get(traceset
, i
);
1815 lttv_trace_unref(trace
);
1819 //add_trace_into_traceset_selector(GTK_MULTIVPANED(tab->multivpaned), lttv_trace(trace_v));
1822 /* add_trace adds a trace into the current traceset. It first displays a
1823 * directory selection dialogue to let user choose a trace, then recreates
1824 * tracset_context, and redraws all the viewer of the current tab
1827 void add_trace(GtkWidget
* widget
, gpointer user_data
)
1830 LttvTrace
* trace_v
;
1831 LttvTraceset
* traceset
;
1833 char abs_path
[PATH_MAX
];
1835 MainWindow
* mw_data
= get_window_data_struct(widget
);
1836 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
1838 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
1839 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
1840 LttvPluginTab
*ptab
;
1844 ptab
= create_new_tab(widget
, NULL
);
1847 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
1851 //GtkDirSelection * file_selector = (GtkDirSelection *)gtk_dir_selection_new("Select a trace");
1852 GtkFileSelection
* file_selector
= (GtkFileSelection
*)gtk_file_selection_new("Select a trace");
1853 gtk_widget_hide( (file_selector
)->file_list
->parent
) ;
1854 gtk_file_selection_hide_fileop_buttons(file_selector
);
1855 gtk_window_set_transient_for(GTK_WINDOW(file_selector
),
1856 GTK_WINDOW(mw_data
->mwindow
));
1858 if(remember_trace_dir
[0] != '\0')
1859 gtk_file_selection_set_filename(file_selector
, remember_trace_dir
);
1861 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
1863 case GTK_RESPONSE_ACCEPT
:
1864 case GTK_RESPONSE_OK
:
1865 dir
= gtk_file_selection_get_filename (file_selector
);
1866 strncpy(remember_trace_dir
, dir
, PATH_MAX
);
1867 strncat(remember_trace_dir
, "/", PATH_MAX
);
1868 if(!dir
|| strlen(dir
) == 0){
1869 gtk_widget_destroy((GtkWidget
*)file_selector
);
1872 get_absolute_pathname(dir
, abs_path
);
1873 trace_v
= lttvwindowtraces_get_trace_by_name(abs_path
);
1874 if(trace_v
== NULL
) {
1875 trace
= ltt_trace_open(abs_path
);
1877 g_warning("cannot open trace %s", abs_path
);
1879 GtkWidget
*dialogue
=
1880 gtk_message_dialog_new(
1881 GTK_WINDOW(gtk_widget_get_toplevel(widget
)),
1882 GTK_DIALOG_MODAL
|GTK_DIALOG_DESTROY_WITH_PARENT
,
1885 "Cannot open trace : maybe you should enter in the trace "
1886 "directory to select it ?");
1887 gtk_dialog_run(GTK_DIALOG(dialogue
));
1888 gtk_widget_destroy(dialogue
);
1891 trace_v
= lttv_trace_new(trace
);
1892 lttvwindowtraces_add_trace(trace_v
);
1893 lttvwindow_add_trace(tab
, trace_v
);
1896 lttvwindow_add_trace(tab
, trace_v
);
1899 gtk_widget_destroy((GtkWidget
*)file_selector
);
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
:
1915 gtk_widget_destroy((GtkWidget
*)file_selector
);
1920 /* remove_trace removes a trace from the current traceset if all viewers in
1921 * the current tab are not interested in the trace. It first displays a
1922 * dialogue, which shows all traces in the current traceset, to let user choose
1923 * a trace, then it checks if all viewers unselect the trace, if it is true,
1924 * it will remove the trace, recreate the traceset_contex,
1925 * and redraws all the viewer of the current tab. If there is on trace in the
1926 * current traceset, it will delete all viewers of the current tab
1928 * It destroys the filter tree. FIXME... we should request for an update
1932 void remove_trace(GtkWidget
*widget
, gpointer user_data
)
1935 LttvTrace
* trace_v
;
1936 LttvTraceset
* traceset
;
1937 gint i
, j
, nb_trace
, index
=-1;
1938 char ** name
, *remove_trace_name
;
1939 MainWindow
* mw_data
= get_window_data_struct(widget
);
1940 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
1942 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
1943 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
1949 LttvPluginTab
*ptab
;
1950 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
1954 nb_trace
=lttv_traceset_number(tab
->traceset_info
->traceset
);
1955 name
= g_new(char*,nb_trace
);
1956 for(i
= 0; i
< nb_trace
; i
++){
1957 trace_v
= lttv_traceset_get(tab
->traceset_info
->traceset
, i
);
1958 trace
= lttv_trace(trace_v
);
1959 name
[i
] = g_quark_to_string(ltt_trace_name(trace
));
1962 remove_trace_name
= get_remove_trace(mw_data
, name
, nb_trace
);
1965 if(remove_trace_name
){
1967 /* yuk, cut n paste from old code.. should be better (MD)*/
1968 for(i
= 0; i
<nb_trace
; i
++) {
1969 if(strcmp(remove_trace_name
,name
[i
]) == 0){
1974 traceset
= tab
->traceset_info
->traceset
;
1975 //Keep a reference to the traces so they are not freed.
1976 for(j
=0; j
<lttv_traceset_number(traceset
); j
++)
1978 LttvTrace
* trace
= lttv_traceset_get(traceset
, j
);
1979 lttv_trace_ref(trace
);
1982 //remove state update hooks
1983 lttv_state_remove_event_hooks(
1984 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1985 lttv_context_fini(LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
));
1986 g_object_unref(tab
->traceset_info
->traceset_context
);
1988 trace_v
= lttv_traceset_get(traceset
, index
);
1990 lttv_traceset_remove(traceset
, index
);
1991 lttv_trace_unref(trace_v
); // Remove local reference
1993 if(lttv_trace_get_ref_number(trace_v
) <= 1) {
1994 /* ref 1 : lttvwindowtraces only*/
1995 ltt_trace_close(lttv_trace(trace_v
));
1996 /* lttvwindowtraces_remove_trace takes care of destroying
1997 * the traceset linked with the trace_v and also of destroying
1998 * the trace_v at the same time.
2000 lttvwindowtraces_remove_trace(trace_v
);
2003 tab
->traceset_info
->traceset_context
=
2004 g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
2006 LTTV_TRACESET_CONTEXT(tab
->
2007 traceset_info
->traceset_context
),traceset
);
2008 //add state update hooks
2009 lttv_state_add_event_hooks(
2010 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
2012 //Remove local reference to the traces.
2013 for(j
=0; j
<lttv_traceset_number(traceset
); j
++)
2015 LttvTrace
* trace
= lttv_traceset_get(traceset
, j
);
2016 lttv_trace_unref(trace
);
2019 SetTraceset(tab
, (gpointer
)traceset
);
2025 void remove_trace(GtkWidget
* widget
, gpointer user_data
)
2028 LttvTrace
* trace_v
;
2029 LttvTraceset
* traceset
;
2030 gint i
, j
, nb_trace
;
2031 char ** name
, *remove_trace_name
;
2032 MainWindow
* mw_data
= get_window_data_struct(widget
);
2033 LttvTracesetSelector
* s
;
2034 LttvTraceSelector
* t
;
2037 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
2039 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2040 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2046 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
2049 nb_trace
=lttv_traceset_number(tab
->traceset_info
->traceset
);
2050 name
= g_new(char*,nb_trace
);
2051 for(i
= 0; i
< nb_trace
; i
++){
2052 trace_v
= lttv_traceset_get(tab
->traceset_info
->traceset
, i
);
2053 trace
= lttv_trace(trace_v
);
2054 name
[i
] = ltt_trace_name(trace
);
2057 remove_trace_name
= get_remove_trace(name
, nb_trace
);
2059 if(remove_trace_name
){
2060 for(i
=0; i
<nb_trace
; i
++){
2061 if(strcmp(remove_trace_name
,name
[i
]) == 0){
2062 //unselect the trace from the current viewer
2064 w
= gtk_multivpaned_get_widget(GTK_MULTIVPANED(tab
->multivpaned
));
2066 s
= g_object_get_data(G_OBJECT(w
), "Traceset_Selector");
2068 t
= lttv_traceset_selector_trace_get(s
,i
);
2069 lttv_trace_selector_set_selected(t
, FALSE
);
2072 //check if other viewers select the trace
2073 w
= gtk_multivpaned_get_first_widget(GTK_MULTIVPANED(tab
->multivpaned
));
2075 s
= g_object_get_data(G_OBJECT(w
), "Traceset_Selector");
2077 t
= lttv_traceset_selector_trace_get(s
,i
);
2078 selected
= lttv_trace_selector_get_selected(t
);
2081 w
= gtk_multivpaned_get_next_widget(GTK_MULTIVPANED(tab
->multivpaned
));
2083 }else selected
= FALSE
;
2085 //if no viewer selects the trace, remove it
2087 remove_trace_from_traceset_selector(GTK_MULTIVPANED(tab
->multivpaned
), i
);
2089 traceset
= tab
->traceset_info
->traceset
;
2090 //Keep a reference to the traces so they are not freed.
2091 for(j
=0; j
<lttv_traceset_number(traceset
); j
++)
2093 LttvTrace
* trace
= lttv_traceset_get(traceset
, j
);
2094 lttv_trace_ref(trace
);
2097 //remove state update hooks
2098 lttv_state_remove_event_hooks(
2099 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
2100 lttv_context_fini(LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
));
2101 g_object_unref(tab
->traceset_info
->traceset_context
);
2104 trace_v
= lttv_traceset_get(traceset
, i
);
2106 if(lttv_trace_get_ref_number(trace_v
) <= 2) {
2107 /* ref 2 : traceset, local */
2108 lttvwindowtraces_remove_trace(trace_v
);
2109 ltt_trace_close(lttv_trace(trace_v
));
2112 lttv_traceset_remove(traceset
, i
);
2113 lttv_trace_unref(trace_v
); // Remove local reference
2115 if(!lttv_trace_get_ref_number(trace_v
))
2116 lttv_trace_destroy(trace_v
);
2118 tab
->traceset_info
->traceset_context
=
2119 g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
2121 LTTV_TRACESET_CONTEXT(tab
->
2122 traceset_info
->traceset_context
),traceset
);
2123 //add state update hooks
2124 lttv_state_add_event_hooks(
2125 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
2127 //Remove local reference to the traces.
2128 for(j
=0; j
<lttv_traceset_number(traceset
); j
++)
2130 LttvTrace
* trace
= lttv_traceset_get(traceset
, j
);
2131 lttv_trace_unref(trace
);
2135 //update current tab
2136 //update_traceset(mw_data);
2139 SetTraceset(tab
, (gpointer
)traceset
);
2140 // in expose now call_pending_read_hooks(mw_data);
2142 //lttvwindow_report_current_time(mw_data,&(tab->current_time));
2145 // while(tab->multi_vpaned->num_children){
2146 // gtk_multi_vpaned_widget_delete(tab->multi_vpaned);
2160 /* Redraw all the viewers in the current tab */
2161 void redraw(GtkWidget
*widget
, gpointer user_data
)
2163 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
2164 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2165 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2172 LttvPluginTab
*ptab
;
2173 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
2178 LttvAttributeValue value
;
2180 retval
= lttv_iattribute_find_by_path(tab
->attributes
, "hooks/redraw", LTTV_POINTER
, &value
);
2183 tmp
= (LttvHooks
*)*(value
.v_pointer
);
2185 lttv_hooks_call(tmp
,NULL
);
2189 void continue_processing(GtkWidget
*widget
, gpointer user_data
)
2191 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
2192 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2193 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2200 LttvPluginTab
*ptab
;
2201 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
2206 LttvAttributeValue value
;
2208 retval
= lttv_iattribute_find_by_path(tab
->attributes
, "hooks/continue",
2209 LTTV_POINTER
, &value
);
2212 tmp
= (LttvHooks
*)*(value
.v_pointer
);
2214 lttv_hooks_call(tmp
,NULL
);
2217 /* Stop the processing for the calling main window's current tab.
2218 * It removes every processing requests that are in its list. It does not call
2219 * the end request hooks, because the request is not finished.
2222 void stop_processing(GtkWidget
*widget
, gpointer user_data
)
2224 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
2225 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2226 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2231 LttvPluginTab
*ptab
;
2232 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
2235 GSList
*iter
= tab
->events_requests
;
2237 while(iter
!= NULL
) {
2238 GSList
*remove_iter
= iter
;
2239 iter
= g_slist_next(iter
);
2241 g_free(remove_iter
->data
);
2242 tab
->events_requests
=
2243 g_slist_remove_link(tab
->events_requests
, remove_iter
);
2245 tab
->events_request_pending
= FALSE
;
2246 tab
->stop_foreground
= TRUE
;
2247 g_idle_remove_by_data(tab
);
2248 g_assert(g_slist_length(tab
->events_requests
) == 0);
2252 /* save will save the traceset to a file
2253 * Not implemented yet FIXME
2256 void save(GtkWidget
* widget
, gpointer user_data
)
2261 void save_as(GtkWidget
* widget
, gpointer user_data
)
2263 g_info("Save as\n");
2267 /* zoom will change the time_window of all the viewers of the
2268 * current tab, and redisplay them. The main functionality is to
2269 * determine the new time_window of the current tab
2272 void zoom(GtkWidget
* widget
, double size
)
2274 TimeInterval time_span
;
2275 TimeWindow new_time_window
;
2276 LttTime current_time
, time_delta
;
2277 MainWindow
* mw_data
= get_window_data_struct(widget
);
2278 LttvTracesetContext
*tsc
;
2279 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
2281 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2282 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2288 LttvPluginTab
*ptab
;
2289 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
2293 if(size
== 1) return;
2295 tsc
= LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
2296 time_span
= tsc
->time_span
;
2297 new_time_window
= tab
->time_window
;
2298 current_time
= tab
->current_time
;
2300 time_delta
= ltt_time_sub(time_span
.end_time
,time_span
.start_time
);
2302 new_time_window
.start_time
= time_span
.start_time
;
2303 new_time_window
.time_width
= time_delta
;
2304 new_time_window
.time_width_double
= ltt_time_to_double(time_delta
);
2305 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
2306 new_time_window
.time_width
) ;
2308 new_time_window
.time_width
= ltt_time_div(new_time_window
.time_width
, size
);
2309 new_time_window
.time_width_double
=
2310 ltt_time_to_double(new_time_window
.time_width
);
2311 if(ltt_time_compare(new_time_window
.time_width
,time_delta
) > 0)
2312 { /* Case where zoom out is bigger than trace length */
2313 new_time_window
.start_time
= time_span
.start_time
;
2314 new_time_window
.time_width
= time_delta
;
2315 new_time_window
.time_width_double
= ltt_time_to_double(time_delta
);
2316 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
2317 new_time_window
.time_width
) ;
2321 /* Center the image on the current time */
2322 new_time_window
.start_time
=
2323 ltt_time_sub(current_time
,
2324 ltt_time_from_double(new_time_window
.time_width_double
/2.0));
2325 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
2326 new_time_window
.time_width
) ;
2327 /* If on borders, don't fall off */
2328 if(ltt_time_compare(new_time_window
.start_time
, time_span
.start_time
) <0
2329 || ltt_time_compare(new_time_window
.start_time
, time_span
.end_time
) >0)
2331 new_time_window
.start_time
= time_span
.start_time
;
2332 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
2333 new_time_window
.time_width
) ;
2337 if(ltt_time_compare(new_time_window
.end_time
,
2338 time_span
.end_time
) > 0
2339 || ltt_time_compare(new_time_window
.end_time
,
2340 time_span
.start_time
) < 0)
2342 new_time_window
.start_time
=
2343 ltt_time_sub(time_span
.end_time
, new_time_window
.time_width
);
2345 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
2346 new_time_window
.time_width
) ;
2353 if(ltt_time_compare(new_time_window
.time_width
, ltt_time_zero
) == 0) {
2354 g_warning("Zoom more than 1 ns impossible");
2356 time_change_manager(tab
, new_time_window
);
2360 void zoom_in(GtkWidget
* widget
, gpointer user_data
)
2365 void zoom_out(GtkWidget
* widget
, gpointer user_data
)
2370 void zoom_extended(GtkWidget
* widget
, gpointer user_data
)
2375 void go_to_time(GtkWidget
* widget
, gpointer user_data
)
2377 g_info("Go to time\n");
2380 void show_time_frame(GtkWidget
* widget
, gpointer user_data
)
2382 g_info("Show time frame\n");
2386 /* callback function */
2389 on_empty_traceset_activate (GtkMenuItem
*menuitem
,
2392 create_new_window((GtkWidget
*)menuitem
, user_data
, FALSE
);
2397 on_clone_traceset_activate (GtkMenuItem
*menuitem
,
2400 create_new_window((GtkWidget
*)menuitem
, user_data
, TRUE
);
2404 /* create_new_tab calls create_tab to construct a new tab in the main window
2407 LttvPluginTab
*create_new_tab(GtkWidget
* widget
, gpointer user_data
)
2409 gchar label
[PATH_MAX
];
2410 MainWindow
* mw_data
= get_window_data_struct(widget
);
2412 GtkNotebook
* notebook
= (GtkNotebook
*)lookup_widget(widget
, "MNotebook");
2413 if(notebook
== NULL
){
2414 g_info("Notebook does not exist\n");
2417 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2418 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2424 LttvPluginTab
*ptab
;
2425 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
2426 copy_tab
= ptab
->tab
;
2429 strcpy(label
,"Page");
2430 if(get_label(mw_data
, label
,"Get the name of the tab","Please input tab's name")) {
2431 LttvPluginTab
*ptab
;
2433 ptab
= g_object_new(LTTV_TYPE_PLUGIN_TAB
, NULL
);
2434 init_tab (ptab
->tab
, mw_data
, copy_tab
, notebook
, label
);
2435 ptab
->parent
.top_widget
= ptab
->tab
->top_widget
;
2436 g_object_set_data_full(
2437 G_OBJECT(ptab
->tab
->vbox
),
2440 (GDestroyNotify
)tab_destructor
);
2447 on_tab_activate (GtkMenuItem
*menuitem
,
2450 create_new_tab((GtkWidget
*)menuitem
, user_data
);
2455 on_open_activate (GtkMenuItem
*menuitem
,
2458 open_traceset((GtkWidget
*)menuitem
, user_data
);
2463 on_close_activate (GtkMenuItem
*menuitem
,
2466 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2467 main_window_destructor(mw_data
);
2471 /* remove the current tab from the main window
2475 on_close_tab_activate (GtkWidget
*widget
,
2479 GtkWidget
* notebook
;
2481 MainWindow
* mw_data
= get_window_data_struct(widget
);
2482 notebook
= lookup_widget(widget
, "MNotebook");
2483 if(notebook
== NULL
){
2484 g_info("Notebook does not exist\n");
2488 page_num
= gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
));
2490 gtk_notebook_remove_page(GTK_NOTEBOOK(notebook
), page_num
);
2495 on_close_tab_X_clicked (GtkWidget
*widget
,
2499 GtkWidget
*notebook
= lookup_widget(widget
, "MNotebook");
2500 if(notebook
== NULL
){
2501 g_info("Notebook does not exist\n");
2505 if((page_num
= gtk_notebook_page_num(GTK_NOTEBOOK(notebook
), widget
)) != -1)
2506 gtk_notebook_remove_page(GTK_NOTEBOOK(notebook
), page_num
);
2512 on_add_trace_activate (GtkMenuItem
*menuitem
,
2515 add_trace((GtkWidget
*)menuitem
, user_data
);
2520 on_remove_trace_activate (GtkMenuItem
*menuitem
,
2523 remove_trace((GtkWidget
*)menuitem
, user_data
);
2528 on_save_activate (GtkMenuItem
*menuitem
,
2531 save((GtkWidget
*)menuitem
, user_data
);
2536 on_save_as_activate (GtkMenuItem
*menuitem
,
2539 save_as((GtkWidget
*)menuitem
, user_data
);
2544 on_quit_activate (GtkMenuItem
*menuitem
,
2547 while (g_slist_length(g_main_window_list
) != 0) {
2548 on_MWindow_destroy(((MainWindow
*)g_main_window_list
->data
)->mwindow
,
2555 on_cut_activate (GtkMenuItem
*menuitem
,
2563 on_copy_activate (GtkMenuItem
*menuitem
,
2571 on_paste_activate (GtkMenuItem
*menuitem
,
2579 on_delete_activate (GtkMenuItem
*menuitem
,
2587 on_zoom_in_activate (GtkMenuItem
*menuitem
,
2590 zoom_in((GtkWidget
*)menuitem
, user_data
);
2595 on_zoom_out_activate (GtkMenuItem
*menuitem
,
2598 zoom_out((GtkWidget
*)menuitem
, user_data
);
2603 on_zoom_extended_activate (GtkMenuItem
*menuitem
,
2606 zoom_extended((GtkWidget
*)menuitem
, user_data
);
2611 on_go_to_time_activate (GtkMenuItem
*menuitem
,
2614 go_to_time((GtkWidget
*)menuitem
, user_data
);
2619 on_show_time_frame_activate (GtkMenuItem
*menuitem
,
2622 show_time_frame((GtkWidget
*)menuitem
, user_data
);
2627 on_move_viewer_up_activate (GtkMenuItem
*menuitem
,
2630 move_up_viewer((GtkWidget
*)menuitem
, user_data
);
2635 on_move_viewer_down_activate (GtkMenuItem
*menuitem
,
2638 move_down_viewer((GtkWidget
*)menuitem
, user_data
);
2643 on_remove_viewer_activate (GtkMenuItem
*menuitem
,
2646 delete_viewer((GtkWidget
*)menuitem
, user_data
);
2650 on_trace_facility_activate (GtkMenuItem
*menuitem
,
2653 g_info("Trace facility selector: %s\n", "");
2657 /* Dispaly a file selection dialogue to let user select a library, then call
2658 * lttv_library_load().
2662 on_load_library_activate (GtkMenuItem
*menuitem
,
2665 GError
*error
= NULL
;
2666 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2668 gchar load_module_path_alter
[PATH_MAX
];
2672 gchar
*load_module_path
;
2673 name
= g_ptr_array_new();
2674 nb
= lttv_library_path_number();
2675 /* ask for the library path */
2679 path
= lttv_library_path_get(i
);
2680 g_ptr_array_add(name
, path
);
2683 load_module_path
= get_selection(mw_data
,
2684 (char **)(name
->pdata
), name
->len
,
2685 "Select a library path", "Library paths");
2686 if(load_module_path
!= NULL
)
2687 strncpy(load_module_path_alter
, load_module_path
, PATH_MAX
-1); // -1 for /
2689 g_ptr_array_free(name
, TRUE
);
2691 if(load_module_path
== NULL
) return;
2695 /* Make sure the module path ends with a / */
2696 gchar
*ptr
= load_module_path_alter
;
2698 ptr
= strchr(ptr
, '\0');
2700 if(*(ptr
-1) != '/') {
2707 /* Ask for the library to load : list files in the previously selected
2709 gchar str
[PATH_MAX
];
2712 GtkFileSelection
* file_selector
=
2713 (GtkFileSelection
*)gtk_file_selection_new("Select a module");
2714 gtk_file_selection_set_filename(file_selector
, load_module_path_alter
);
2715 gtk_file_selection_hide_fileop_buttons(file_selector
);
2717 gtk_window_set_transient_for(GTK_WINDOW(file_selector
),
2718 GTK_WINDOW(mw_data
->mwindow
));
2721 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
2723 case GTK_RESPONSE_ACCEPT
:
2724 case GTK_RESPONSE_OK
:
2725 dir
= gtk_file_selection_get_selections (file_selector
);
2726 strncpy(str
,dir
[0],PATH_MAX
);
2727 strncpy(remember_plugins_dir
,dir
[0],PATH_MAX
);
2728 /* only keep file name */
2730 str1
= strrchr(str
,'/');
2733 str1
= strrchr(str
,'\\');
2738 if(*str1
== 'l' && *(str1
+1)== 'i' && *(str1
+2)=='b')
2740 remove info after
. */
2744 str2
= strrchr(str2
, '.');
2745 if(str2
!= NULL
) *str2
= '\0';
2747 lttv_module_require(str1
, &error
);
2749 lttv_library_load(str1
, &error
);
2750 if(error
!= NULL
) g_warning("%s", error
->message
);
2751 else g_info("Load library: %s\n", str
);
2753 case GTK_RESPONSE_REJECT
:
2754 case GTK_RESPONSE_CANCEL
:
2756 gtk_widget_destroy((GtkWidget
*)file_selector
);
2767 /* Display all loaded modules, let user to select a module to unload
2768 * by calling lttv_module_unload
2772 on_unload_library_activate (GtkMenuItem
*menuitem
,
2775 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2777 LttvLibrary
*library
= NULL
;
2782 name
= g_ptr_array_new();
2783 nb
= lttv_library_number();
2784 LttvLibraryInfo
*lib_info
= g_new(LttvLibraryInfo
,nb
);
2785 /* ask for the library name */
2788 LttvLibrary
*iter_lib
= lttv_library_get(i
);
2789 lttv_library_info(iter_lib
, &lib_info
[i
]);
2791 gchar
*path
= lib_info
[i
].name
;
2792 g_ptr_array_add(name
, path
);
2794 lib_name
= get_selection(mw_data
, (char **)(name
->pdata
), name
->len
,
2795 "Select a library", "Libraries");
2796 if(lib_name
!= NULL
) {
2798 if(strcmp(lib_name
, lib_info
[i
].name
) == 0) {
2799 library
= lttv_library_get(i
);
2804 g_ptr_array_free(name
, TRUE
);
2807 if(lib_name
== NULL
) return;
2809 if(library
!= NULL
) lttv_library_unload(library
);
2813 /* Dispaly a file selection dialogue to let user select a module, then call
2814 * lttv_module_require().
2818 on_load_module_activate (GtkMenuItem
*menuitem
,
2821 GError
*error
= NULL
;
2822 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2824 LttvLibrary
*library
= NULL
;
2829 name
= g_ptr_array_new();
2830 nb
= lttv_library_number();
2831 LttvLibraryInfo
*lib_info
= g_new(LttvLibraryInfo
,nb
);
2832 /* ask for the library name */
2835 LttvLibrary
*iter_lib
= lttv_library_get(i
);
2836 lttv_library_info(iter_lib
, &lib_info
[i
]);
2838 gchar
*path
= lib_info
[i
].name
;
2839 g_ptr_array_add(name
, path
);
2841 lib_name
= get_selection(mw_data
,(char **)(name
->pdata
), name
->len
,
2842 "Select a library", "Libraries");
2843 if(lib_name
!= NULL
) {
2845 if(strcmp(lib_name
, lib_info
[i
].name
) == 0) {
2846 library
= lttv_library_get(i
);
2851 g_ptr_array_free(name
, TRUE
);
2854 if(lib_name
== NULL
) return;
2857 //LttvModule *module;
2858 gchar module_name_out
[PATH_MAX
];
2860 /* Ask for the module to load : list modules in the selected lib */
2864 nb
= lttv_library_module_number(library
);
2865 LttvModuleInfo
*module_info
= g_new(LttvModuleInfo
,nb
);
2866 name
= g_ptr_array_new();
2867 /* ask for the module name */
2870 LttvModule
*iter_module
= lttv_library_module_get(library
, i
);
2871 lttv_module_info(iter_module
, &module_info
[i
]);
2873 gchar
*path
= module_info
[i
].name
;
2874 g_ptr_array_add(name
, path
);
2876 module_name
= get_selection(mw_data
, (char **)(name
->pdata
), name
->len
,
2877 "Select a module", "Modules");
2878 if(module_name
!= NULL
) {
2880 if(strcmp(module_name
, module_info
[i
].name
) == 0) {
2881 strncpy(module_name_out
, module_name
, PATH_MAX
);
2882 //module = lttv_library_module_get(i);
2888 g_ptr_array_free(name
, TRUE
);
2889 g_free(module_info
);
2891 if(module_name
== NULL
) return;
2894 lttv_module_require(module_name_out
, &error
);
2895 if(error
!= NULL
) g_warning("%s", error
->message
);
2896 else g_info("Load module: %s", module_name_out
);
2903 gchar str
[PATH_MAX
];
2906 GtkFileSelection
* file_selector
=
2907 (GtkFileSelection
*)gtk_file_selection_new("Select a module");
2908 gtk_file_selection_set_filename(file_selector
, load_module_path_alter
);
2909 gtk_file_selection_hide_fileop_buttons(file_selector
);
2912 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
2914 case GTK_RESPONSE_ACCEPT
:
2915 case GTK_RESPONSE_OK
:
2916 dir
= gtk_file_selection_get_selections (file_selector
);
2917 strncpy(str
,dir
[0],PATH_MAX
);
2918 strncpy(remember_plugins_dir
,dir
[0],PATH_MAX
);
2920 /* only keep file name */
2922 str1
= strrchr(str
,'/');
2925 str1
= strrchr(str
,'\\');
2930 if(*str1
== 'l' && *(str1
+1)== 'i' && *(str1
+2)=='b')
2932 remove info after
. */
2936 str2
= strrchr(str2
, '.');
2937 if(str2
!= NULL
) *str2
= '\0';
2939 lttv_module_require(str1
, &error
);
2941 lttv_library_load(str1
, &error
);
2942 if(error
!= NULL
) g_warning(error
->message
);
2943 else g_info("Load library: %s\n", str
);
2945 case GTK_RESPONSE_REJECT
:
2946 case GTK_RESPONSE_CANCEL
:
2948 gtk_widget_destroy((GtkWidget
*)file_selector
);
2960 /* Display all loaded modules, let user to select a module to unload
2961 * by calling lttv_module_unload
2965 on_unload_module_activate (GtkMenuItem
*menuitem
,
2968 GError
*error
= NULL
;
2969 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2971 LttvLibrary
*library
= NULL
;
2976 name
= g_ptr_array_new();
2977 nb
= lttv_library_number();
2978 LttvLibraryInfo
*lib_info
= g_new(LttvLibraryInfo
,nb
);
2979 /* ask for the library name */
2982 LttvLibrary
*iter_lib
= lttv_library_get(i
);
2983 lttv_library_info(iter_lib
, &lib_info
[i
]);
2985 gchar
*path
= lib_info
[i
].name
;
2986 g_ptr_array_add(name
, path
);
2988 lib_name
= get_selection(mw_data
, (char **)(name
->pdata
), name
->len
,
2989 "Select a library", "Libraries");
2990 if(lib_name
!= NULL
) {
2992 if(strcmp(lib_name
, lib_info
[i
].name
) == 0) {
2993 library
= lttv_library_get(i
);
2998 g_ptr_array_free(name
, TRUE
);
3001 if(lib_name
== NULL
) return;
3004 LttvModule
*module
= NULL
;
3006 /* Ask for the module to load : list modules in the selected lib */
3010 nb
= lttv_library_module_number(library
);
3011 LttvModuleInfo
*module_info
= g_new(LttvModuleInfo
,nb
);
3012 name
= g_ptr_array_new();
3013 /* ask for the module name */
3016 LttvModule
*iter_module
= lttv_library_module_get(library
, i
);
3017 lttv_module_info(iter_module
, &module_info
[i
]);
3019 gchar
*path
= module_info
[i
].name
;
3020 if(module_info
[i
].use_count
> 0) g_ptr_array_add(name
, path
);
3022 module_name
= get_selection(mw_data
, (char **)(name
->pdata
), name
->len
,
3023 "Select a module", "Modules");
3024 if(module_name
!= NULL
) {
3026 if(strcmp(module_name
, module_info
[i
].name
) == 0) {
3027 module
= lttv_library_module_get(library
, i
);
3033 g_ptr_array_free(name
, TRUE
);
3034 g_free(module_info
);
3036 if(module_name
== NULL
) return;
3039 LttvModuleInfo module_info
;
3040 lttv_module_info(module
, &module_info
);
3041 g_info("Release module: %s\n", module_info
.name
);
3043 lttv_module_release(module
);
3047 /* Display a directory dialogue to let user select a path for library searching
3051 on_add_library_search_path_activate (GtkMenuItem
*menuitem
,
3054 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
3055 //GtkDirSelection * file_selector = (GtkDirSelection *)gtk_dir_selection_new("Select library path");
3056 GtkFileSelection
* file_selector
= (GtkFileSelection
*)gtk_file_selection_new("Select a trace");
3057 gtk_widget_hide( (file_selector
)->file_list
->parent
) ;
3059 gtk_window_set_transient_for(GTK_WINDOW(file_selector
),
3060 GTK_WINDOW(mw_data
->mwindow
));
3065 if(remember_plugins_dir
[0] != '\0')
3066 gtk_file_selection_set_filename(file_selector
, remember_plugins_dir
);
3068 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
3070 case GTK_RESPONSE_ACCEPT
:
3071 case GTK_RESPONSE_OK
:
3072 dir
= gtk_file_selection_get_filename (file_selector
);
3073 strncpy(remember_plugins_dir
,dir
,PATH_MAX
);
3074 strncat(remember_plugins_dir
,"/",PATH_MAX
);
3075 lttv_library_path_add(dir
);
3076 case GTK_RESPONSE_REJECT
:
3077 case GTK_RESPONSE_CANCEL
:
3079 gtk_widget_destroy((GtkWidget
*)file_selector
);
3085 /* Display a directory dialogue to let user select a path for library searching
3089 on_remove_library_search_path_activate (GtkMenuItem
*menuitem
,
3092 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
3094 const char *lib_path
;
3099 name
= g_ptr_array_new();
3100 nb
= lttv_library_path_number();
3101 /* ask for the library name */
3104 gchar
*path
= lttv_library_path_get(i
);
3105 g_ptr_array_add(name
, path
);
3107 lib_path
= get_selection(mw_data
, (char **)(name
->pdata
), name
->len
,
3108 "Select a library path", "Library paths");
3110 g_ptr_array_free(name
, TRUE
);
3112 if(lib_path
== NULL
) return;
3115 lttv_library_path_remove(lib_path
);
3119 on_color_activate (GtkMenuItem
*menuitem
,
3127 on_save_configuration_activate (GtkMenuItem
*menuitem
,
3130 g_info("Save configuration\n");
3135 on_content_activate (GtkMenuItem
*menuitem
,
3138 g_info("Content\n");
3143 on_about_close_activate (GtkButton
*button
,
3146 GtkWidget
*about_widget
= GTK_WIDGET(user_data
);
3148 gtk_widget_destroy(about_widget
);
3152 on_about_activate (GtkMenuItem
*menuitem
,
3155 MainWindow
*main_window
= get_window_data_struct(GTK_WIDGET(menuitem
));
3156 GtkWidget
*window_widget
= main_window
->mwindow
;
3157 GtkWidget
*about_widget
= gtk_window_new(GTK_WINDOW_TOPLEVEL
);
3158 GtkWindow
*about_window
= GTK_WINDOW(about_widget
);
3159 gint window_width
, window_height
;
3161 gtk_window_set_title(about_window
, "About Linux Trace Toolkit");
3163 gtk_window_set_resizable(about_window
, FALSE
);
3164 gtk_window_set_transient_for(about_window
, GTK_WINDOW(window_widget
));
3165 gtk_window_set_destroy_with_parent(about_window
, TRUE
);
3166 gtk_window_set_modal(about_window
, FALSE
);
3168 /* Put the about window at the center of the screen */
3169 gtk_window_get_size(about_window
, &window_width
, &window_height
);
3170 gtk_window_move (about_window
,
3171 (gdk_screen_width() - window_width
)/2,
3172 (gdk_screen_height() - window_height
)/2);
3174 GtkWidget
*vbox
= gtk_vbox_new(FALSE
, 1);
3176 gtk_container_add(GTK_CONTAINER(about_widget
), vbox
);
3180 GtkWidget
*label1
= gtk_label_new("");
3181 gtk_misc_set_padding(GTK_MISC(label1
), 10, 20);
3182 gtk_label_set_markup(GTK_LABEL(label1
), "\
3183 <big>Linux Trace Toolkit " VERSION
"</big>");
3184 gtk_label_set_justify(GTK_LABEL(label1
), GTK_JUSTIFY_CENTER
);
3186 GtkWidget
*label2
= gtk_label_new("");
3187 gtk_misc_set_padding(GTK_MISC(label2
), 10, 20);
3188 gtk_label_set_markup(GTK_LABEL(label2
), "\
3191 Michel Dagenais (New trace format, lttv main)\n\
3192 Mathieu Desnoyers (Kernel Tracer, Directory structure, build with automake/conf,\n\
3193 lttv gui, control flow view, gui cooperative trace reading\n\
3194 scheduler with interruptible foreground and background\n\
3195 computation, detailed event list (rewrite), trace reading\n\
3196 library (rewrite))\n\
3197 Benoit Des Ligneris, Eric Clement (Cluster adaptation, work in progress)\n\
3198 Xang-Xiu Yang (new trace reading library and converter, lttv gui, \n\
3199 detailed event list and statistics view)\n\
3200 Tom Zanussi (RelayFS)\n\
3202 Inspired from the original Linux Trace Toolkit Visualizer made by\n\
3205 GtkWidget
*label3
= gtk_label_new("");
3206 gtk_label_set_markup(GTK_LABEL(label3
), "\
3207 Linux Trace Toolkit Viewer, Copyright (C) 2004, 2005, 2006\n\
3209 Mathieu Desnoyers\n\
3211 Linux Trace Toolkit comes with ABSOLUTELY NO WARRANTY.\n\
3212 This is free software, and you are welcome to redistribute it\n\
3213 under certain conditions. See COPYING for details.");
3214 gtk_misc_set_padding(GTK_MISC(label3
), 10, 20);
3216 gtk_box_pack_start_defaults(GTK_BOX(vbox
), label1
);
3217 gtk_box_pack_start_defaults(GTK_BOX(vbox
), label2
);
3218 gtk_box_pack_start_defaults(GTK_BOX(vbox
), label3
);
3220 GtkWidget
*hbox
= gtk_hbox_new(TRUE
, 0);
3221 gtk_box_pack_end(GTK_BOX(vbox
), hbox
, FALSE
, FALSE
, 0);
3222 GtkWidget
*close_button
= gtk_button_new_with_mnemonic("_Close");
3223 gtk_box_pack_end(GTK_BOX(hbox
), close_button
, FALSE
, FALSE
, 0);
3224 gtk_container_set_border_width(GTK_CONTAINER(close_button
), 20);
3226 g_signal_connect(G_OBJECT(close_button
), "clicked",
3227 G_CALLBACK(on_about_close_activate
),
3228 (gpointer
)about_widget
);
3230 gtk_widget_show_all(about_widget
);
3235 on_button_new_clicked (GtkButton
*button
,
3238 create_new_window((GtkWidget
*)button
, user_data
, TRUE
);
3242 on_button_new_tab_clicked (GtkButton
*button
,
3245 create_new_tab((GtkWidget
*)button
, user_data
);
3249 on_button_open_clicked (GtkButton
*button
,
3252 open_traceset((GtkWidget
*)button
, user_data
);
3257 on_button_add_trace_clicked (GtkButton
*button
,
3260 add_trace((GtkWidget
*)button
, user_data
);
3265 on_button_remove_trace_clicked (GtkButton
*button
,
3268 remove_trace((GtkWidget
*)button
, user_data
);
3272 on_button_redraw_clicked (GtkButton
*button
,
3275 redraw((GtkWidget
*)button
, user_data
);
3279 on_button_continue_processing_clicked (GtkButton
*button
,
3282 continue_processing((GtkWidget
*)button
, user_data
);
3286 on_button_stop_processing_clicked (GtkButton
*button
,
3289 stop_processing((GtkWidget
*)button
, user_data
);
3295 on_button_save_clicked (GtkButton
*button
,
3298 save((GtkWidget
*)button
, user_data
);
3303 on_button_save_as_clicked (GtkButton
*button
,
3306 save_as((GtkWidget
*)button
, user_data
);
3311 on_button_zoom_in_clicked (GtkButton
*button
,
3314 zoom_in((GtkWidget
*)button
, user_data
);
3319 on_button_zoom_out_clicked (GtkButton
*button
,
3322 zoom_out((GtkWidget
*)button
, user_data
);
3327 on_button_zoom_extended_clicked (GtkButton
*button
,
3330 zoom_extended((GtkWidget
*)button
, user_data
);
3335 on_button_go_to_time_clicked (GtkButton
*button
,
3338 go_to_time((GtkWidget
*)button
, user_data
);
3343 on_button_show_time_frame_clicked (GtkButton
*button
,
3346 show_time_frame((GtkWidget
*)button
, user_data
);
3351 on_button_move_up_clicked (GtkButton
*button
,
3354 move_up_viewer((GtkWidget
*)button
, user_data
);
3359 on_button_move_down_clicked (GtkButton
*button
,
3362 move_down_viewer((GtkWidget
*)button
, user_data
);
3367 on_button_delete_viewer_clicked (GtkButton
*button
,
3370 delete_viewer((GtkWidget
*)button
, user_data
);
3374 on_MWindow_destroy (GtkWidget
*widget
,
3377 MainWindow
*main_window
= get_window_data_struct(widget
);
3378 LttvIAttribute
*attributes
= main_window
->attributes
;
3379 LttvAttributeValue value
;
3382 //This is unnecessary, since widgets will be destroyed
3383 //by the main window widget anyway.
3384 //remove_all_menu_toolbar_constructors(main_window, NULL);
3386 retval
= lttv_iattribute_find_by_path(attributes
, "viewers/menu",
3387 LTTV_POINTER
, &value
);
3389 lttv_menus_destroy((LttvMenus
*)*(value
.v_pointer
));
3391 retval
= lttv_iattribute_find_by_path(attributes
, "viewers/toolbar",
3392 LTTV_POINTER
, &value
);
3394 lttv_toolbars_destroy((LttvToolbars
*)*(value
.v_pointer
));
3396 g_object_unref(main_window
->attributes
);
3397 g_main_window_list
= g_slist_remove(g_main_window_list
, main_window
);
3399 g_info("There are now : %d windows\n",g_slist_length(g_main_window_list
));
3400 if(g_slist_length(g_main_window_list
) == 0)
3405 on_MWindow_configure (GtkWidget
*widget
,
3406 GdkEventConfigure
*event
,
3409 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)widget
);
3411 // MD : removed time width modification upon resizing of the main window.
3412 // The viewers will redraw themselves completely, without time interval
3415 if(mw_data->window_width){
3416 time_span = LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context)->Time_Span ;
3417 time_win = tab->time_window;
3418 ratio = width / mw_data->window_width;
3419 tab->time_window.time_width = ltt_time_mul(time_win.time_width,ratio);
3420 time = ltt_time_sub(time_span->endTime, time_win.start_time);
3421 if(ltt_time_compare(time, tab->time_window.time_width) < 0){
3422 tab->time_window.time_width = time;
3428 mw_data->window_width = (int)width;
3437 on_MNotebook_switch_page (GtkNotebook
*notebook
,
3438 GtkNotebookPage
*page
,
3446 void time_change_manager (Tab
*tab
,
3447 TimeWindow new_time_window
)
3449 /* Only one source of time change */
3450 if(tab
->time_manager_lock
== TRUE
) return;
3452 tab
->time_manager_lock
= TRUE
;
3454 LttvTracesetContext
*tsc
= LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3455 TimeInterval time_span
= tsc
->time_span
;
3456 LttTime start_time
= new_time_window
.start_time
;
3457 LttTime end_time
= new_time_window
.end_time
;
3458 LttTime time_width
= new_time_window
.time_width
;
3460 g_assert(ltt_time_compare(start_time
, end_time
) < 0);
3463 GtkAdjustment
*adjustment
= gtk_range_get_adjustment(GTK_RANGE(tab
->scrollbar
));
3464 LttTime upper
= ltt_time_sub(time_span
.end_time
, time_span
.start_time
);
3466 gtk_range_set_increments(GTK_RANGE(tab
->scrollbar
),
3467 ltt_time_to_double(new_time_window
.time_width
)
3468 / SCROLL_STEP_PER_PAGE
3469 * NANOSECONDS_PER_SECOND
, /* step increment */
3470 ltt_time_to_double(new_time_window
.time_width
)
3471 * NANOSECONDS_PER_SECOND
); /* page increment */
3472 gtk_range_set_range(GTK_RANGE(tab
->scrollbar
),
3474 ltt_time_to_double(upper
)
3475 * NANOSECONDS_PER_SECOND
); /* upper */
3477 g_object_set(G_OBJECT(adjustment
),
3481 ltt_time_to_double(upper
), /* upper */
3483 new_time_window
.time_width_double
3484 / SCROLL_STEP_PER_PAGE
, /* step increment */
3486 new_time_window
.time_width_double
,
3487 /* page increment */
3489 new_time_window
.time_width_double
, /* page size */
3491 gtk_adjustment_changed(adjustment
);
3493 // g_object_set(G_OBJECT(adjustment),
3495 // ltt_time_to_double(
3496 // ltt_time_sub(start_time, time_span.start_time))
3499 //gtk_adjustment_value_changed(adjustment);
3500 gtk_range_set_value(GTK_RANGE(tab
->scrollbar
),
3502 ltt_time_sub(start_time
, time_span
.start_time
)) /* value */);
3504 /* set the time bar. */
3506 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry1
),
3507 (double)time_span
.start_time
.tv_sec
,
3508 (double)time_span
.end_time
.tv_sec
);
3509 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry1
),
3510 (double)start_time
.tv_sec
);
3512 /* start nanoseconds */
3513 if(start_time
.tv_sec
== time_span
.start_time
.tv_sec
) {
3514 /* can be both beginning and end at the same time. */
3515 if(start_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3516 /* If we are at the end, max nsec to end.. -1 (not zero length) */
3517 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry2
),
3518 (double)time_span
.start_time
.tv_nsec
,
3519 (double)time_span
.end_time
.tv_nsec
-1);
3521 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry2
),
3522 (double)time_span
.start_time
.tv_nsec
,
3523 (double)NANOSECONDS_PER_SECOND
-1);
3525 } else if(start_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3526 /* If we are at the end, max nsec to end.. -1 (not zero length) */
3527 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry2
),
3529 (double)time_span
.end_time
.tv_nsec
-1);
3530 } else /* anywhere else */
3531 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry2
),
3533 (double)NANOSECONDS_PER_SECOND
-1);
3534 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry2
),
3535 (double)start_time
.tv_nsec
);
3538 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry3
),
3539 (double)time_span
.start_time
.tv_sec
,
3540 (double)time_span
.end_time
.tv_sec
);
3541 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry3
),
3542 (double)end_time
.tv_sec
);
3544 /* end nanoseconds */
3545 if(end_time
.tv_sec
== time_span
.start_time
.tv_sec
) {
3546 /* can be both beginning and end at the same time. */
3547 if(end_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3548 /* If we are at the end, max nsec to end.. */
3549 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry4
),
3550 (double)time_span
.start_time
.tv_nsec
+1,
3551 (double)time_span
.end_time
.tv_nsec
);
3553 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry4
),
3554 (double)time_span
.start_time
.tv_nsec
+1,
3555 (double)NANOSECONDS_PER_SECOND
-1);
3558 else if(end_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3559 /* If we are at the end, max nsec to end.. */
3560 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry4
),
3562 (double)time_span
.end_time
.tv_nsec
);
3564 else /* anywhere else */
3565 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry4
),
3567 (double)NANOSECONDS_PER_SECOND
-1);
3568 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry4
),
3569 (double)end_time
.tv_nsec
);
3572 if(time_width
.tv_nsec
== 0) {
3573 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry7
),
3575 (double)upper
.tv_sec
);
3577 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry7
),
3579 (double)upper
.tv_sec
);
3581 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry7
),
3582 (double)time_width
.tv_sec
);
3584 /* width nanoseconds */
3585 if(time_width
.tv_sec
== upper
.tv_sec
) {
3586 if(time_width
.tv_sec
== 0) {
3587 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry8
),
3589 (double)upper
.tv_nsec
);
3591 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry8
),
3593 (double)upper
.tv_nsec
);
3596 else if(time_width
.tv_sec
== 0) {
3597 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry8
),
3599 (double)upper
.tv_nsec
);
3601 else /* anywhere else */
3602 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry8
),
3604 (double)NANOSECONDS_PER_SECOND
-1);
3605 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry8
),
3606 (double)time_width
.tv_nsec
);
3608 /* call viewer hooks for new time window */
3609 set_time_window(tab
, &new_time_window
);
3611 tab
->time_manager_lock
= FALSE
;
3615 /* value changed for frame start s
3617 * Check time span : if ns is out of range, clip it the nearest good value.
3620 on_MEntry1_value_changed (GtkSpinButton
*spinbutton
,
3623 Tab
*tab
=(Tab
*)user_data
;
3624 LttvTracesetContext
* tsc
=
3625 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3626 TimeInterval time_span
= tsc
->time_span
;
3627 gint value
= gtk_spin_button_get_value_as_int(spinbutton
);
3629 TimeWindow new_time_window
= tab
->time_window
;
3631 LttTime end_time
= new_time_window
.end_time
;
3633 new_time_window
.start_time
.tv_sec
= value
;
3635 /* start nanoseconds */
3636 if(new_time_window
.start_time
.tv_sec
== time_span
.start_time
.tv_sec
) {
3637 if(new_time_window
.start_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3638 if(new_time_window
.start_time
.tv_nsec
> time_span
.end_time
.tv_nsec
)
3639 new_time_window
.start_time
.tv_nsec
= time_span
.end_time
.tv_nsec
-1;
3640 if(new_time_window
.start_time
.tv_nsec
< time_span
.start_time
.tv_nsec
)
3641 new_time_window
.start_time
.tv_nsec
= time_span
.start_time
.tv_nsec
;
3643 if(new_time_window
.start_time
.tv_nsec
< time_span
.start_time
.tv_nsec
)
3644 new_time_window
.start_time
.tv_nsec
= time_span
.start_time
.tv_nsec
;
3647 else if(new_time_window
.start_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3648 if(new_time_window
.start_time
.tv_nsec
> time_span
.end_time
.tv_nsec
)
3649 new_time_window
.start_time
.tv_nsec
= time_span
.end_time
.tv_nsec
-1;
3652 if(ltt_time_compare(new_time_window
.start_time
, end_time
) >= 0) {
3653 /* Then, we must push back end time : keep the same time width
3654 * if possible, else end traceset time */
3655 end_time
= LTT_TIME_MIN(ltt_time_add(new_time_window
.start_time
,
3656 new_time_window
.time_width
),
3657 time_span
.end_time
);
3660 /* Fix the time width to fit start time and end time */
3661 new_time_window
.time_width
= ltt_time_sub(end_time
,
3662 new_time_window
.start_time
);
3663 new_time_window
.time_width_double
=
3664 ltt_time_to_double(new_time_window
.time_width
);
3666 new_time_window
.end_time
= end_time
;
3668 time_change_manager(tab
, new_time_window
);
3673 on_MEntry2_value_changed (GtkSpinButton
*spinbutton
,
3676 Tab
*tab
=(Tab
*)user_data
;
3677 LttvTracesetContext
* tsc
=
3678 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3679 TimeInterval time_span
= tsc
->time_span
;
3680 gint value
= gtk_spin_button_get_value_as_int(spinbutton
);
3682 TimeWindow new_time_window
= tab
->time_window
;
3684 LttTime end_time
= new_time_window
.end_time
;
3686 new_time_window
.start_time
.tv_nsec
= value
;
3688 if(ltt_time_compare(new_time_window
.start_time
, end_time
) >= 0) {
3689 /* Then, we must push back end time : keep the same time width
3690 * if possible, else end traceset time */
3691 end_time
= LTT_TIME_MIN(ltt_time_add(new_time_window
.start_time
,
3692 new_time_window
.time_width
),
3693 time_span
.end_time
);
3696 /* Fix the time width to fit start time and end time */
3697 new_time_window
.time_width
= ltt_time_sub(end_time
,
3698 new_time_window
.start_time
);
3699 new_time_window
.time_width_double
=
3700 ltt_time_to_double(new_time_window
.time_width
);
3702 new_time_window
.end_time
= end_time
;
3704 time_change_manager(tab
, new_time_window
);
3709 on_MEntry3_value_changed (GtkSpinButton
*spinbutton
,
3712 Tab
*tab
=(Tab
*)user_data
;
3713 LttvTracesetContext
* tsc
=
3714 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3715 TimeInterval time_span
= tsc
->time_span
;
3716 gint value
= gtk_spin_button_get_value_as_int(spinbutton
);
3718 TimeWindow new_time_window
= tab
->time_window
;
3720 LttTime end_time
= new_time_window
.end_time
;
3722 end_time
.tv_sec
= value
;
3724 /* end nanoseconds */
3725 if(end_time
.tv_sec
== time_span
.start_time
.tv_sec
) {
3726 if(end_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3727 if(end_time
.tv_nsec
> time_span
.end_time
.tv_nsec
)
3728 end_time
.tv_nsec
= time_span
.end_time
.tv_nsec
;
3729 if(end_time
.tv_nsec
< time_span
.start_time
.tv_nsec
)
3730 end_time
.tv_nsec
= time_span
.start_time
.tv_nsec
+1;
3732 if(end_time
.tv_nsec
< time_span
.start_time
.tv_nsec
)
3733 end_time
.tv_nsec
= time_span
.start_time
.tv_nsec
+1;
3736 else if(end_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3737 if(end_time
.tv_nsec
> time_span
.end_time
.tv_nsec
)
3738 end_time
.tv_nsec
= time_span
.end_time
.tv_nsec
;
3741 if(ltt_time_compare(new_time_window
.start_time
, end_time
) >= 0) {
3742 /* Then, we must push front start time : keep the same time width
3743 * if possible, else end traceset time */
3744 new_time_window
.start_time
= LTT_TIME_MAX(
3745 ltt_time_sub(end_time
,
3746 new_time_window
.time_width
),
3747 time_span
.start_time
);
3750 /* Fix the time width to fit start time and end time */
3751 new_time_window
.time_width
= ltt_time_sub(end_time
,
3752 new_time_window
.start_time
);
3753 new_time_window
.time_width_double
=
3754 ltt_time_to_double(new_time_window
.time_width
);
3756 new_time_window
.end_time
= end_time
;
3758 time_change_manager(tab
, new_time_window
);
3763 on_MEntry4_value_changed (GtkSpinButton
*spinbutton
,
3766 Tab
*tab
=(Tab
*)user_data
;
3767 LttvTracesetContext
* tsc
=
3768 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3769 TimeInterval time_span
= tsc
->time_span
;
3770 gint value
= gtk_spin_button_get_value_as_int(spinbutton
);
3772 TimeWindow new_time_window
= tab
->time_window
;
3774 LttTime end_time
= new_time_window
.end_time
;
3776 end_time
.tv_nsec
= value
;
3778 if(ltt_time_compare(new_time_window
.start_time
, end_time
) >= 0) {
3779 /* Then, we must push front start time : keep the same time width
3780 * if possible, else end traceset time */
3781 new_time_window
.start_time
= LTT_TIME_MAX(
3782 ltt_time_sub(end_time
,
3783 new_time_window
.time_width
),
3784 time_span
.start_time
);
3787 /* Fix the time width to fit start time and end time */
3788 new_time_window
.time_width
= ltt_time_sub(end_time
,
3789 new_time_window
.start_time
);
3790 new_time_window
.time_width_double
=
3791 ltt_time_to_double(new_time_window
.time_width
);
3792 new_time_window
.end_time
= end_time
;
3794 time_change_manager(tab
, new_time_window
);
3798 /* value changed for time frame interval s
3800 * Check time span : if ns is out of range, clip it the nearest good value.
3803 on_MEntry7_value_changed (GtkSpinButton
*spinbutton
,
3806 Tab
*tab
=(Tab
*)user_data
;
3807 LttvTracesetContext
* tsc
=
3808 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3809 TimeInterval time_span
= tsc
->time_span
;
3810 gint value
= gtk_spin_button_get_value_as_int(spinbutton
);
3811 LttTime current_time
, time_delta
;
3812 TimeWindow new_time_window
= tab
->time_window
;
3813 current_time
= tab
->current_time
;
3815 time_delta
= ltt_time_sub(time_span
.end_time
,time_span
.start_time
);
3816 new_time_window
.time_width
.tv_sec
= value
;
3817 new_time_window
.time_width_double
=
3818 ltt_time_to_double(new_time_window
.time_width
);
3819 if(ltt_time_compare(new_time_window
.time_width
,time_delta
) > 0)
3820 { /* Case where zoom out is bigger than trace length */
3821 new_time_window
.start_time
= time_span
.start_time
;
3822 new_time_window
.time_width
= time_delta
;
3823 new_time_window
.time_width_double
= ltt_time_to_double(time_delta
);
3824 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
3825 new_time_window
.time_width
) ;
3829 /* Center the image on the current time */
3830 new_time_window
.start_time
=
3831 ltt_time_sub(current_time
,
3832 ltt_time_from_double(new_time_window
.time_width_double
/2.0));
3833 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
3834 new_time_window
.time_width
) ;
3835 /* If on borders, don't fall off */
3836 if(ltt_time_compare(new_time_window
.start_time
, time_span
.start_time
) <0
3837 || ltt_time_compare(new_time_window
.start_time
, time_span
.end_time
) >0)
3839 new_time_window
.start_time
= time_span
.start_time
;
3840 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
3841 new_time_window
.time_width
) ;
3845 if(ltt_time_compare(new_time_window
.end_time
,
3846 time_span
.end_time
) > 0
3847 || ltt_time_compare(new_time_window
.end_time
,
3848 time_span
.start_time
) < 0)
3850 new_time_window
.start_time
=
3851 ltt_time_sub(time_span
.end_time
, new_time_window
.time_width
);
3853 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
3854 new_time_window
.time_width
) ;
3860 if(ltt_time_compare(new_time_window
.time_width
, ltt_time_zero
) == 0) {
3861 g_warning("Zoom more than 1 ns impossible");
3863 time_change_manager(tab
, new_time_window
);
3868 on_MEntry8_value_changed (GtkSpinButton
*spinbutton
,
3871 Tab
*tab
=(Tab
*)user_data
;
3872 LttvTracesetContext
* tsc
=
3873 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3874 TimeInterval time_span
= tsc
->time_span
;
3875 gint value
= gtk_spin_button_get_value_as_int(spinbutton
);
3876 LttTime current_time
, time_delta
;
3877 TimeWindow new_time_window
= tab
->time_window
;
3878 current_time
= tab
->current_time
;
3880 time_delta
= ltt_time_sub(time_span
.end_time
,time_span
.start_time
);
3881 new_time_window
.time_width
.tv_nsec
= value
;
3882 new_time_window
.time_width_double
=
3883 ltt_time_to_double(new_time_window
.time_width
);
3884 if(ltt_time_compare(new_time_window
.time_width
,time_delta
) > 0)
3885 { /* Case where zoom out is bigger than trace length */
3886 new_time_window
.start_time
= time_span
.start_time
;
3887 new_time_window
.time_width
= time_delta
;
3888 new_time_window
.time_width_double
= ltt_time_to_double(time_delta
);
3889 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
3890 new_time_window
.time_width
) ;
3894 /* Center the image on the current time */
3895 new_time_window
.start_time
=
3896 ltt_time_sub(current_time
,
3897 ltt_time_from_double(new_time_window
.time_width_double
/2.0));
3898 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
3899 new_time_window
.time_width
) ;
3900 /* If on borders, don't fall off */
3901 if(ltt_time_compare(new_time_window
.start_time
, time_span
.start_time
) <0
3902 || ltt_time_compare(new_time_window
.start_time
, time_span
.end_time
) >0)
3904 new_time_window
.start_time
= time_span
.start_time
;
3905 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
3906 new_time_window
.time_width
) ;
3910 if(ltt_time_compare(new_time_window
.end_time
,
3911 time_span
.end_time
) > 0
3912 || ltt_time_compare(new_time_window
.end_time
,
3913 time_span
.start_time
) < 0)
3915 new_time_window
.start_time
=
3916 ltt_time_sub(time_span
.end_time
, new_time_window
.time_width
);
3918 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
3919 new_time_window
.time_width
) ;
3925 if(ltt_time_compare(new_time_window
.time_width
, ltt_time_zero
) == 0) {
3926 g_warning("Zoom more than 1 ns impossible");
3928 time_change_manager(tab
, new_time_window
);
3934 void current_time_change_manager (Tab
*tab
,
3935 LttTime new_current_time
)
3937 /* Only one source of time change */
3938 if(tab
->current_time_manager_lock
== TRUE
) return;
3940 tab
->current_time_manager_lock
= TRUE
;
3942 LttvTracesetContext
*tsc
= LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3943 TimeInterval time_span
= tsc
->time_span
;
3945 /* current seconds */
3946 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry5
),
3947 (double)time_span
.start_time
.tv_sec
,
3948 (double)time_span
.end_time
.tv_sec
);
3949 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry5
),
3950 (double)new_current_time
.tv_sec
);
3953 /* start nanoseconds */
3954 if(new_current_time
.tv_sec
== time_span
.start_time
.tv_sec
) {
3955 /* can be both beginning and end at the same time. */
3956 if(new_current_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3957 /* If we are at the end, max nsec to end.. */
3958 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry6
),
3959 (double)time_span
.start_time
.tv_nsec
,
3960 (double)time_span
.end_time
.tv_nsec
);
3962 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry6
),
3963 (double)time_span
.start_time
.tv_nsec
,
3964 (double)NANOSECONDS_PER_SECOND
-1);
3966 } else if(new_current_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3967 /* If we are at the end, max nsec to end.. */
3968 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry6
),
3970 (double)time_span
.end_time
.tv_nsec
);
3971 } else /* anywhere else */
3972 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry6
),
3974 (double)NANOSECONDS_PER_SECOND
-1);
3976 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry6
),
3977 (double)new_current_time
.tv_nsec
);
3979 set_current_time(tab
, &new_current_time
);
3981 tab
->current_time_manager_lock
= FALSE
;
3984 void current_position_change_manager(Tab
*tab
,
3985 LttvTracesetContextPosition
*pos
)
3987 LttvTracesetContext
*tsc
=
3988 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3989 TimeInterval time_span
= tsc
->time_span
;
3992 retval
= lttv_process_traceset_seek_position(tsc
, pos
);
3993 g_assert_cmpint(retval
, ==, 0);
3994 LttTime new_time
= lttv_traceset_context_position_get_time(pos
);
3995 /* Put the context in a state coherent position */
3996 lttv_state_traceset_seek_time_closest((LttvTracesetState
*)tsc
, ltt_time_zero
);
3998 current_time_change_manager(tab
, new_time
);
4000 set_current_position(tab
, pos
);
4005 on_MEntry5_value_changed (GtkSpinButton
*spinbutton
,
4008 Tab
*tab
= (Tab
*)user_data
;
4009 LttvTracesetContext
* tsc
=
4010 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
4011 TimeInterval time_span
= tsc
->time_span
;
4012 gint value
= gtk_spin_button_get_value_as_int(spinbutton
);
4013 LttTime new_current_time
= tab
->current_time
;
4014 new_current_time
.tv_sec
= value
;
4016 /* current nanoseconds */
4017 if(new_current_time
.tv_sec
== time_span
.start_time
.tv_sec
) {
4018 if(new_current_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
4019 if(new_current_time
.tv_nsec
> time_span
.end_time
.tv_nsec
)
4020 new_current_time
.tv_nsec
= time_span
.end_time
.tv_nsec
;
4021 if(new_current_time
.tv_nsec
< time_span
.start_time
.tv_nsec
)
4022 new_current_time
.tv_nsec
= time_span
.start_time
.tv_nsec
;
4024 if(new_current_time
.tv_nsec
< time_span
.start_time
.tv_nsec
)
4025 new_current_time
.tv_nsec
= time_span
.start_time
.tv_nsec
;
4028 else if(new_current_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
4029 if(new_current_time
.tv_nsec
> time_span
.end_time
.tv_nsec
)
4030 new_current_time
.tv_nsec
= time_span
.end_time
.tv_nsec
;
4033 current_time_change_manager(tab
, new_current_time
);
4037 on_MEntry6_value_changed (GtkSpinButton
*spinbutton
,
4040 Tab
*tab
= (Tab
*)user_data
;
4041 gint value
= gtk_spin_button_get_value_as_int(spinbutton
);
4042 LttTime new_current_time
= tab
->current_time
;
4043 new_current_time
.tv_nsec
= value
;
4045 current_time_change_manager(tab
, new_current_time
);
4049 void scroll_value_changed_cb(GtkWidget
*scrollbar
,
4052 Tab
*tab
= (Tab
*)user_data
;
4053 TimeWindow new_time_window
;
4055 GtkAdjustment
*adjust
= gtk_range_get_adjustment(GTK_RANGE(scrollbar
));
4056 gdouble value
= gtk_adjustment_get_value(adjust
);
4057 // gdouble upper, lower, ratio, page_size;
4059 LttvTracesetContext
* tsc
=
4060 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
4061 TimeInterval time_span
= tsc
->time_span
;
4063 time
= ltt_time_add(ltt_time_from_double(value
),
4064 time_span
.start_time
);
4066 new_time_window
.start_time
= time
;
4068 page_size
= adjust
->page_size
;
4070 new_time_window
.time_width
=
4071 ltt_time_from_double(page_size
);
4073 new_time_window
.time_width_double
=
4076 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
4077 new_time_window
.time_width
);
4080 time_change_manager(tab
, new_time_window
);
4082 //time_window = tab->time_window;
4084 lower
= adjust
->lower
;
4085 upper
= adjust
->upper
;
4086 ratio
= (value
- lower
) / (upper
- lower
);
4087 g_info("lower %lu, upper %lu, value %lu, ratio %lu", lower
, upper
, value
, ratio
);
4089 //time = ltt_time_sub(time_span->end_time, time_span->start_time);
4090 //time = ltt_time_mul(time, (float)ratio);
4091 //time = ltt_time_add(time_span->start_time, time);
4092 time
= ltt_time_add(ltt_time_from_double(value
),
4093 time_span
.start_time
);
4095 time_window
.start_time
= time
;
4097 page_size
= adjust
->page_size
;
4099 time_window
.time_width
=
4100 ltt_time_from_double(page_size
);
4101 //time = ltt_time_sub(time_span.end_time, time);
4102 //if(ltt_time_compare(time,time_window.time_width) < 0){
4103 // time_window.time_width = time;
4106 /* call viewer hooks for new time window */
4107 set_time_window(tab
, &time_window
);
4112 /* Display a dialogue showing all eventtypes and traces, let user to select the interested
4113 * eventtypes, tracefiles and traces (filter)
4116 /* Select a trace which will be removed from traceset
4119 char * get_remove_trace(MainWindow
*mw_data
,
4120 char ** all_trace_name
, int nb_trace
)
4122 return get_selection(mw_data
, all_trace_name
, nb_trace
,
4123 "Select a trace", "Trace pathname");
4127 /* Select a module which will be loaded
4130 char * get_load_module(MainWindow
*mw_data
,
4131 char ** load_module_name
, int nb_module
)
4133 return get_selection(mw_data
, load_module_name
, nb_module
,
4134 "Select a module to load", "Module name");
4140 /* Select a module which will be unloaded
4143 char * get_unload_module(MainWindow
*mw_data
,
4144 char ** loaded_module_name
, int nb_module
)
4146 return get_selection(mw_data
, loaded_module_name
, nb_module
,
4147 "Select a module to unload", "Module name");
4151 /* Display a dialogue which shows all selectable items, let user to
4152 * select one of them
4155 char * get_selection(MainWindow
*mw_data
,
4156 char ** loaded_module_name
, int nb_module
,
4157 char *title
, char * column_title
)
4159 GtkWidget
* dialogue
;
4160 GtkWidget
* scroll_win
;
4162 GtkListStore
* store
;
4163 GtkTreeViewColumn
* column
;
4164 GtkCellRenderer
* renderer
;
4165 GtkTreeSelection
* select
;
4168 char * unload_module_name
= NULL
;
4170 dialogue
= gtk_dialog_new_with_buttons(title
,
4173 GTK_STOCK_OK
,GTK_RESPONSE_ACCEPT
,
4174 GTK_STOCK_CANCEL
,GTK_RESPONSE_REJECT
,
4176 gtk_window_set_default_size((GtkWindow
*)dialogue
, 500, 200);
4177 gtk_window_set_transient_for(GTK_WINDOW(dialogue
),
4178 GTK_WINDOW(mw_data
->mwindow
));
4180 scroll_win
= gtk_scrolled_window_new (NULL
, NULL
);
4181 gtk_widget_show ( scroll_win
);
4182 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll_win
),
4183 GTK_POLICY_AUTOMATIC
, GTK_POLICY_AUTOMATIC
);
4185 store
= gtk_list_store_new (N_COLUMNS
,G_TYPE_STRING
);
4186 tree
= gtk_tree_view_new_with_model(GTK_TREE_MODEL (store
));
4187 gtk_widget_show ( tree
);
4188 g_object_unref (G_OBJECT (store
));
4190 renderer
= gtk_cell_renderer_text_new ();
4191 column
= gtk_tree_view_column_new_with_attributes (column_title
,
4193 "text", MODULE_COLUMN
,
4195 gtk_tree_view_column_set_alignment (column
, 0.5);
4196 gtk_tree_view_column_set_fixed_width (column
, 150);
4197 gtk_tree_view_append_column (GTK_TREE_VIEW (tree
), column
);
4199 select
= gtk_tree_view_get_selection (GTK_TREE_VIEW (tree
));
4200 gtk_tree_selection_set_mode (select
, GTK_SELECTION_SINGLE
);
4202 gtk_container_add (GTK_CONTAINER (scroll_win
), tree
);
4204 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialogue
)->vbox
), scroll_win
,TRUE
, TRUE
,0);
4206 for(i
=0;i
<nb_module
;i
++){
4207 gtk_list_store_append (store
, &iter
);
4208 gtk_list_store_set (store
, &iter
, MODULE_COLUMN
,loaded_module_name
[i
],-1);
4211 id
= gtk_dialog_run(GTK_DIALOG(dialogue
));
4212 GtkTreeModel
**store_model
= (GtkTreeModel
**)&store
;
4214 case GTK_RESPONSE_ACCEPT
:
4215 case GTK_RESPONSE_OK
:
4216 if (gtk_tree_selection_get_selected (select
, store_model
, &iter
)){
4217 gtk_tree_model_get ((GtkTreeModel
*)store
, &iter
, MODULE_COLUMN
, &unload_module_name
, -1);
4219 case GTK_RESPONSE_REJECT
:
4220 case GTK_RESPONSE_CANCEL
:
4222 gtk_widget_destroy(dialogue
);
4226 return unload_module_name
;
4230 /* Insert all menu entry and tool buttons into this main window
4235 void add_all_menu_toolbar_constructors(MainWindow
* mw
, gpointer user_data
)
4239 lttvwindow_viewer_constructor constructor
;
4240 LttvMenus
* global_menu
, * instance_menu
;
4241 LttvToolbars
* global_toolbar
, * instance_toolbar
;
4242 LttvMenuClosure
*menu_item
;
4243 LttvToolbarClosure
*toolbar_item
;
4244 LttvAttributeValue value
;
4245 LttvIAttribute
*global_attributes
= LTTV_IATTRIBUTE(lttv_global_attributes());
4246 LttvIAttribute
*attributes
= mw
->attributes
;
4247 GtkWidget
* tool_menu_title_menu
, *new_widget
, *pixmap
;
4250 retval
= lttv_iattribute_find_by_path(global_attributes
, "viewers/menu",
4251 LTTV_POINTER
, &value
);
4253 if(*(value
.v_pointer
) == NULL
)
4254 *(value
.v_pointer
) = lttv_menus_new();
4255 global_menu
= (LttvMenus
*)*(value
.v_pointer
);
4257 retval
= lttv_iattribute_find_by_path(attributes
, "viewers/menu",
4258 LTTV_POINTER
, &value
);
4260 if(*(value
.v_pointer
) == NULL
)
4261 *(value
.v_pointer
) = lttv_menus_new();
4262 instance_menu
= (LttvMenus
*)*(value
.v_pointer
);
4264 retval
= lttv_iattribute_find_by_path(global_attributes
, "viewers/toolbar",
4265 LTTV_POINTER
, &value
);
4267 if(*(value
.v_pointer
) == NULL
)
4268 *(value
.v_pointer
) = lttv_toolbars_new();
4269 global_toolbar
= (LttvToolbars
*)*(value
.v_pointer
);
4271 retval
= lttv_iattribute_find_by_path(attributes
, "viewers/toolbar",
4272 LTTV_POINTER
, &value
);
4274 if(*(value
.v_pointer
) == NULL
)
4275 *(value
.v_pointer
) = lttv_toolbars_new();
4276 instance_toolbar
= (LttvToolbars
*)*(value
.v_pointer
);
4278 /* Add missing menu entries to window instance */
4279 for(i
=0;i
<global_menu
->len
;i
++) {
4280 menu_item
= &g_array_index(global_menu
, LttvMenuClosure
, i
);
4282 //add menu_item to window instance;
4283 constructor
= menu_item
->con
;
4284 tool_menu_title_menu
= lookup_widget(mw
->mwindow
,"ToolMenuTitle_menu");
4286 gtk_menu_item_new_with_mnemonic (menu_item
->menu_text
);
4287 gtk_container_add (GTK_CONTAINER (tool_menu_title_menu
),
4289 g_signal_connect ((gpointer
) new_widget
, "activate",
4290 G_CALLBACK (insert_viewer_wrap
),
4292 gtk_widget_show (new_widget
);
4293 lttv_menus_add(instance_menu
, menu_item
->con
,
4294 menu_item
->menu_path
,
4295 menu_item
->menu_text
,
4300 /* Add missing toolbar entries to window instance */
4301 for(i
=0;i
<global_toolbar
->len
;i
++) {
4302 toolbar_item
= &g_array_index(global_toolbar
, LttvToolbarClosure
, i
);
4304 //add toolbar_item to window instance;
4305 constructor
= toolbar_item
->con
;
4306 tool_menu_title_menu
= lookup_widget(mw
->mwindow
,"MToolbar1");
4307 pixbuf
= gdk_pixbuf_new_from_xpm_data((const char**)toolbar_item
->pixmap
);
4308 pixmap
= gtk_image_new_from_pixbuf(pixbuf
);
4310 gtk_toolbar_append_element (GTK_TOOLBAR (tool_menu_title_menu
),
4311 GTK_TOOLBAR_CHILD_BUTTON
,
4314 toolbar_item
->tooltip
, NULL
,
4315 pixmap
, NULL
, NULL
);
4316 gtk_label_set_use_underline(
4317 GTK_LABEL (((GtkToolbarChild
*) (
4318 g_list_last (GTK_TOOLBAR
4319 (tool_menu_title_menu
)->children
)->data
))->label
),
4321 gtk_container_set_border_width (GTK_CONTAINER (new_widget
), 1);
4322 g_signal_connect ((gpointer
) new_widget
,
4324 G_CALLBACK (insert_viewer_wrap
),
4326 gtk_widget_show (new_widget
);
4328 lttv_toolbars_add(instance_toolbar
, toolbar_item
->con
,
4329 toolbar_item
->tooltip
,
4330 toolbar_item
->pixmap
,
4338 /* Create a main window
4341 MainWindow
*construct_main_window(MainWindow
* parent
)
4345 g_debug("construct_main_window()");
4346 GtkWidget
* new_window
; /* New generated main window */
4347 MainWindow
* new_m_window
;/* New main window structure */
4348 GtkNotebook
* notebook
;
4349 LttvIAttribute
*attributes
=
4350 LTTV_IATTRIBUTE(g_object_new(LTTV_ATTRIBUTE_TYPE
, NULL
));
4351 LttvAttributeValue value
;
4354 new_m_window
= g_new(MainWindow
, 1);
4356 // Add the object's information to the module's array
4357 g_main_window_list
= g_slist_append(g_main_window_list
, new_m_window
);
4359 new_window
= create_MWindow();
4360 gtk_widget_show (new_window
);
4362 new_m_window
->mwindow
= new_window
;
4363 new_m_window
->attributes
= attributes
;
4365 retval
= lttv_iattribute_find_by_path(attributes
, "viewers/menu",
4366 LTTV_POINTER
, &value
);
4368 *(value
.v_pointer
) = lttv_menus_new();
4370 retval
= lttv_iattribute_find_by_path(attributes
, "viewers/toolbar",
4371 LTTV_POINTER
, &value
);
4373 *(value
.v_pointer
) = lttv_toolbars_new();
4375 add_all_menu_toolbar_constructors(new_m_window
, NULL
);
4377 g_object_set_data_full(G_OBJECT(new_window
),
4379 (gpointer
)new_m_window
,
4380 (GDestroyNotify
)g_free
);
4381 //create a default tab
4382 notebook
= (GtkNotebook
*)lookup_widget(new_m_window
->mwindow
, "MNotebook");
4383 if(notebook
== NULL
){
4384 g_info("Notebook does not exist\n");
4385 /* FIXME : destroy partially created widgets */
4386 g_free(new_m_window
);
4389 //gtk_notebook_popup_enable (GTK_NOTEBOOK(notebook));
4390 //for now there is no name field in LttvTraceset structure
4391 //Use "Traceset" as the label for the default tab
4393 GtkWidget
* parent_notebook
= lookup_widget(parent
->mwindow
, "MNotebook");
4394 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(parent_notebook
),
4395 gtk_notebook_get_current_page(GTK_NOTEBOOK(parent_notebook
)));
4401 LttvPluginTab
*ptab
;
4402 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
4403 parent_tab
= ptab
->tab
;
4405 LttvPluginTab
*ptab
= g_object_new(LTTV_TYPE_PLUGIN_TAB
, NULL
);
4407 new_m_window
, parent_tab
, notebook
, "Traceset");
4408 ptab
->parent
.top_widget
= ptab
->tab
->top_widget
;
4409 g_object_set_data_full(
4410 G_OBJECT(ptab
->tab
->vbox
),
4413 (GDestroyNotify
)tab_destructor
);
4414 new_tab
= ptab
->tab
;
4416 LttvPluginTab
*ptab
= g_object_new(LTTV_TYPE_PLUGIN_TAB
, NULL
);
4417 init_tab(ptab
->tab
, new_m_window
, NULL
, notebook
, "Traceset");
4418 ptab
->parent
.top_widget
= ptab
->tab
->top_widget
;
4419 g_object_set_data_full(
4420 G_OBJECT(ptab
->tab
->vbox
),
4423 (GDestroyNotify
)tab_destructor
);
4424 new_tab
= ptab
->tab
;
4427 /* Insert default viewers */
4429 LttvAttributeType type
;
4430 LttvAttributeName name
;
4431 LttvAttributeValue value
;
4432 LttvAttribute
*attribute
;
4434 LttvIAttribute
*attributes_global
=
4435 LTTV_IATTRIBUTE(lttv_global_attributes());
4437 attribute
= LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
4438 LTTV_IATTRIBUTE(attributes_global
),
4439 LTTV_VIEWER_CONSTRUCTORS
));
4440 g_assert(attribute
);
4442 name
= g_quark_from_string("guievents");
4443 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
4445 if(type
== LTTV_POINTER
) {
4446 lttvwindow_viewer_constructor viewer_constructor
=
4447 (lttvwindow_viewer_constructor
)*value
.v_pointer
;
4448 insert_viewer(new_window
, viewer_constructor
);
4451 name
= g_quark_from_string("guicontrolflow");
4452 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
4454 if(type
== LTTV_POINTER
) {
4455 lttvwindow_viewer_constructor viewer_constructor
=
4456 (lttvwindow_viewer_constructor
)*value
.v_pointer
;
4457 insert_viewer(new_window
, viewer_constructor
);
4460 name
= g_quark_from_string("guistatistics");
4461 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
4463 if(type
== LTTV_POINTER
) {
4464 lttvwindow_viewer_constructor viewer_constructor
=
4465 (lttvwindow_viewer_constructor
)*value
.v_pointer
;
4466 insert_viewer(new_window
, viewer_constructor
);
4470 g_info("There are now : %d windows\n",g_slist_length(g_main_window_list
));
4472 return new_m_window
;
4476 /* Free the memory occupied by a tab structure
4480 void tab_destructor(LttvPluginTab
* ptab
)
4482 int i
, nb
, ref_count
;
4484 Tab
*tab
= ptab
->tab
;
4486 gtk_object_destroy(GTK_OBJECT(tab
->tooltips
));
4489 g_object_unref(tab
->attributes
);
4491 if(tab
->interrupted_state
)
4492 g_object_unref(tab
->interrupted_state
);
4495 if(tab
->traceset_info
->traceset_context
!= NULL
){
4496 //remove state update hooks
4497 lttv_state_remove_event_hooks(
4498 (LttvTracesetState
*)tab
->traceset_info
->
4500 lttv_context_fini(LTTV_TRACESET_CONTEXT(tab
->traceset_info
->
4502 g_object_unref(tab
->traceset_info
->traceset_context
);
4504 if(tab
->traceset_info
->traceset
!= NULL
) {
4505 nb
= lttv_traceset_number(tab
->traceset_info
->traceset
);
4506 for(i
= 0 ; i
< nb
; i
++) {
4507 trace
= lttv_traceset_get(tab
->traceset_info
->traceset
, i
);
4508 ref_count
= lttv_trace_get_ref_number(trace
);
4510 ltt_trace_close(lttv_trace(trace
));
4514 lttv_traceset_destroy(tab
->traceset_info
->traceset
);
4515 /* Remove the idle events requests processing function of the tab */
4516 g_idle_remove_by_data(tab
);
4518 g_slist_free(tab
->events_requests
);
4519 g_free(tab
->traceset_info
);
4521 g_object_unref(ptab
);
4525 /* Create a tab and insert it into the current main window
4528 void init_tab(Tab
*tab
, MainWindow
* mw
, Tab
*copy_tab
,
4529 GtkNotebook
* notebook
, char * label
)
4533 //LttvFilter *filter = NULL;
4535 //create a new tab data structure
4536 //tab = g_new(Tab,1);
4538 //construct and initialize the traceset_info
4539 tab
->traceset_info
= g_new(TracesetInfo
,1);
4542 tab
->traceset_info
->traceset
=
4543 lttv_traceset_copy(copy_tab
->traceset_info
->traceset
);
4545 /* Copy the previous tab's filter */
4546 /* We can clone the filter, as we copy the trace set also */
4547 /* The filter must always be in sync with the trace set */
4548 tab
->filter
= lttv_filter_clone(copy_tab
->filter
);
4550 tab
->traceset_info
->traceset
= lttv_traceset_new();
4554 lttv_attribute_write_xml(
4555 lttv_traceset_attribute(tab
->traceset_info
->traceset
),
4561 tab
->time_manager_lock
= FALSE
;
4562 tab
->current_time_manager_lock
= FALSE
;
4564 //FIXME copy not implemented in lower level
4565 tab
->traceset_info
->traceset_context
=
4566 g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
4567 g_assert(tab
->traceset_info
->traceset_context
!= NULL
);
4569 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
),
4570 tab
->traceset_info
->traceset
);
4571 //add state update hooks
4572 lttv_state_add_event_hooks(
4573 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
4575 //determine the current_time and time_window of the tab
4577 if(copy_tab
!= NULL
){
4578 tab
->time_window
= copy_tab
->time_window
;
4579 tab
->current_time
= copy_tab
->current_time
;
4581 tab
->time_window
.start_time
=
4582 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
4583 time_span
.start_time
;
4584 if(DEFAULT_TIME_WIDTH_S
<
4585 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
4586 time_span
.end_time
.tv_sec
)
4587 tmp_time
.tv_sec
= DEFAULT_TIME_WIDTH_S
;
4590 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
4591 time_span
.end_time
.tv_sec
;
4592 tmp_time
.tv_nsec
= 0;
4593 tab
->time_window
.time_width
= tmp_time
;
4594 tab
->current_time
.tv_sec
=
4595 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
4596 time_span
.start_time
.tv_sec
;
4597 tab
->current_time
.tv_nsec
=
4598 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
4599 time_span
.start_time
.tv_nsec
;
4602 tab
->attributes
= LTTV_IATTRIBUTE(g_object_new(LTTV_ATTRIBUTE_TYPE
, NULL
));
4603 tab
->interrupted_state
= g_object_new(LTTV_ATTRIBUTE_TYPE
, NULL
);
4605 tab
->vbox
= gtk_vbox_new(FALSE
, 2);
4606 tab
->top_widget
= tab
->vbox
;
4607 //g_object_set_data_full(G_OBJECT(tab->top_widget), "filter",
4608 // filter, (GDestroyNotify)lttv_filter_destroy);
4610 // g_signal_connect (G_OBJECT(tab->top_widget),
4612 // G_CALLBACK (on_top_notify),
4615 tab
->viewer_container
= gtk_vbox_new(TRUE
, 2);
4616 tab
->scrollbar
= gtk_hscrollbar_new(NULL
);
4617 //tab->multivpaned = gtk_multi_vpaned_new();
4619 gtk_box_pack_start(GTK_BOX(tab
->vbox
),
4620 tab
->viewer_container
,
4622 TRUE
, /* Give the extra space to the child */
4623 0); /* No padding */
4626 // tab->time_window = copy_tab->time_window;
4627 // tab->current_time = copy_tab->current_time;
4630 /* Create the timebar */
4632 tab
->MTimebar
= gtk_hbox_new(FALSE
, 2);
4633 gtk_widget_show(tab
->MTimebar
);
4634 tab
->tooltips
= gtk_tooltips_new();
4636 tab
->MEventBox1a
= gtk_event_box_new();
4637 gtk_widget_show(tab
->MEventBox1a
);
4638 gtk_tooltips_set_tip(tab
->tooltips
, tab
->MEventBox1a
,
4639 "Paste Start and End Times Here", "");
4640 tab
->MText1a
= gtk_label_new("Time Frame ");
4641 gtk_widget_show(tab
->MText1a
);
4642 gtk_container_add(GTK_CONTAINER(tab
->MEventBox1a
), tab
->MText1a
);
4643 tab
->MEventBox1b
= gtk_event_box_new();
4644 gtk_widget_show(tab
->MEventBox1b
);
4645 gtk_tooltips_set_tip(tab
->tooltips
, tab
->MEventBox1b
,
4646 "Paste Start Time Here", "");
4647 tab
->MText1b
= gtk_label_new("start: ");
4648 gtk_widget_show(tab
->MText1b
);
4649 gtk_container_add(GTK_CONTAINER(tab
->MEventBox1b
), tab
->MText1b
);
4650 tab
->MText2
= gtk_label_new("s");
4651 gtk_widget_show(tab
->MText2
);
4652 tab
->MText3a
= gtk_label_new("ns");
4653 gtk_widget_show(tab
->MText3a
);
4655 tab
->MEventBox3b
= gtk_event_box_new();
4656 gtk_widget_show(tab
->MEventBox3b
);
4657 gtk_tooltips_set_tip(tab
->tooltips
, tab
->MEventBox3b
,
4658 "Paste End Time Here", "");
4659 tab
->MText3b
= gtk_label_new("end:");
4660 gtk_widget_show(tab
->MText3b
);
4661 gtk_container_add(GTK_CONTAINER(tab
->MEventBox3b
), tab
->MText3b
);
4662 tab
->MText4
= gtk_label_new("s");
4663 gtk_widget_show(tab
->MText4
);
4664 tab
->MText5a
= gtk_label_new("ns");
4665 gtk_widget_show(tab
->MText5a
);
4667 tab
->MEventBox8
= gtk_event_box_new();
4668 gtk_widget_show(tab
->MEventBox8
);
4669 gtk_tooltips_set_tip(tab
->tooltips
, tab
->MEventBox8
,
4670 "Paste Time Interval here", "");
4671 tab
->MText8
= gtk_label_new("Time Interval:");
4672 gtk_widget_show(tab
->MText8
);
4673 gtk_container_add(GTK_CONTAINER(tab
->MEventBox8
), tab
->MText8
);
4674 tab
->MText9
= gtk_label_new("s");
4675 gtk_widget_show(tab
->MText9
);
4676 tab
->MText10
= gtk_label_new("ns");
4677 gtk_widget_show(tab
->MText10
);
4679 tab
->MEventBox5b
= gtk_event_box_new();
4680 gtk_widget_show(tab
->MEventBox5b
);
4681 gtk_tooltips_set_tip(tab
->tooltips
, tab
->MEventBox5b
,
4682 "Paste Current Time Here", "");
4683 tab
->MText5b
= gtk_label_new("Current Time:");
4684 gtk_widget_show(tab
->MText5b
);
4685 gtk_container_add(GTK_CONTAINER(tab
->MEventBox5b
), tab
->MText5b
);
4686 tab
->MText6
= gtk_label_new("s");
4687 gtk_widget_show(tab
->MText6
);
4688 tab
->MText7
= gtk_label_new("ns");
4689 gtk_widget_show(tab
->MText7
);
4691 tab
->MEntry1
= gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4692 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab
->MEntry1
),0);
4693 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab
->MEntry1
),TRUE
);
4694 gtk_widget_show(tab
->MEntry1
);
4695 tab
->MEntry2
= gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4696 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab
->MEntry2
),0);
4697 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab
->MEntry2
),TRUE
);
4698 gtk_widget_show(tab
->MEntry2
);
4699 tab
->MEntry3
= gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4700 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab
->MEntry3
),0);
4701 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab
->MEntry3
),TRUE
);
4702 gtk_widget_show(tab
->MEntry3
);
4703 tab
->MEntry4
= gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4704 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab
->MEntry4
),0);
4705 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab
->MEntry4
),TRUE
);
4706 gtk_widget_show(tab
->MEntry4
);
4707 tab
->MEntry5
= gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4708 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab
->MEntry5
),0);
4709 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab
->MEntry5
),TRUE
);
4710 gtk_widget_show(tab
->MEntry5
);
4711 tab
->MEntry6
= gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4712 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab
->MEntry6
),0);
4713 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab
->MEntry6
),TRUE
);
4714 gtk_widget_show(tab
->MEntry6
);
4715 tab
->MEntry7
= gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4716 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab
->MEntry7
),0);
4717 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab
->MEntry7
),TRUE
);
4718 gtk_widget_show(tab
->MEntry7
);
4719 tab
->MEntry8
= gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4720 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab
->MEntry8
),0);
4721 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab
->MEntry8
),TRUE
);
4722 gtk_widget_show(tab
->MEntry8
);
4724 GtkWidget
*temp_widget
;
4726 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEventBox1a
, FALSE
,
4728 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEventBox1b
, FALSE
,
4730 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEntry1
, FALSE
, FALSE
, 0);
4731 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MText2
, FALSE
, FALSE
, 0);
4732 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEntry2
, FALSE
, FALSE
, 0);
4733 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MText3a
, FALSE
, FALSE
, 0);
4734 temp_widget
= gtk_vseparator_new();
4735 gtk_widget_show(temp_widget
);
4736 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), temp_widget
, FALSE
, FALSE
, 0);
4737 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEventBox3b
, FALSE
,
4739 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEntry3
, FALSE
, FALSE
, 0);
4740 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MText4
, FALSE
, FALSE
, 0);
4741 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEntry4
, FALSE
, FALSE
, 0);
4742 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MText5a
, FALSE
, FALSE
, 0);
4743 temp_widget
= gtk_vseparator_new();
4744 gtk_widget_show(temp_widget
);
4745 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), temp_widget
, FALSE
, FALSE
, 0);
4746 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEventBox8
, FALSE
,
4748 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEntry7
, FALSE
, FALSE
, 0);
4749 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MText9
, FALSE
, FALSE
, 0);
4750 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEntry8
, FALSE
, FALSE
, 0);
4751 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MText10
, FALSE
, FALSE
, 0);
4753 temp_widget
= gtk_vseparator_new();
4754 gtk_widget_show(temp_widget
);
4755 gtk_box_pack_end (GTK_BOX (tab
->MTimebar
), tab
->MText7
, FALSE
, FALSE
, 0);
4756 gtk_box_pack_end (GTK_BOX (tab
->MTimebar
), tab
->MEntry6
, FALSE
, FALSE
, 0);
4757 gtk_box_pack_end (GTK_BOX (tab
->MTimebar
), tab
->MText6
, FALSE
, FALSE
, 0);
4758 gtk_box_pack_end (GTK_BOX (tab
->MTimebar
), tab
->MEntry5
, FALSE
, FALSE
, 0);
4759 gtk_box_pack_end (GTK_BOX (tab
->MTimebar
), tab
->MEventBox5b
, FALSE
,
4761 gtk_box_pack_end (GTK_BOX (tab
->MTimebar
), temp_widget
, FALSE
, FALSE
, 0);
4764 //GtkWidget *test = gtk_button_new_with_label("drop");
4765 //gtk_button_set_relief(GTK_BUTTON(test), GTK_RELIEF_NONE);
4766 //gtk_widget_show(test);
4767 //gtk_box_pack_end(GTK_BOX (tab->MTimebar), test, FALSE, FALSE, 0);
4768 //gtk_widget_add_events(tab->MText1, GDK_ALL_EVENTS_MASK);//GDK_BUTTON_PRESS_MASK);
4769 /*GtkWidget *event_box = gtk_event_box_new();
4770 gtk_widget_show(event_box);
4771 gtk_tooltips_set_tip(tooltips, event_box,
4772 "Paste Current Time Here", "");
4773 gtk_box_pack_end(GTK_BOX (tab->MTimebar), event_box, FALSE, FALSE, 0);
4774 GtkWidget *test = gtk_label_new("drop");
4775 gtk_container_add(GTK_CONTAINER(event_box), test);
4776 gtk_widget_show(test);
4777 g_signal_connect (G_OBJECT(event_box),
4778 "button-press-event",
4779 G_CALLBACK (on_MText1_paste),
4783 g_signal_connect (G_OBJECT(tab
->MEventBox1a
),
4784 "button-press-event",
4785 G_CALLBACK (on_MEventBox1a_paste
),
4788 g_signal_connect (G_OBJECT(tab
->MEventBox1b
),
4789 "button-press-event",
4790 G_CALLBACK (on_MEventBox1b_paste
),
4792 g_signal_connect (G_OBJECT(tab
->MEventBox3b
),
4793 "button-press-event",
4794 G_CALLBACK (on_MEventBox3b_paste
),
4796 g_signal_connect (G_OBJECT(tab
->MEventBox5b
),
4797 "button-press-event",
4798 G_CALLBACK (on_MEventBox5b_paste
),
4800 g_signal_connect (G_OBJECT(tab
->MEventBox8
),
4801 "button-press-event",
4802 G_CALLBACK (on_MEventBox8_paste
),
4806 gtk_box_pack_end(GTK_BOX(tab
->vbox
),
4808 FALSE
, /* Do not expand */
4809 FALSE
, /* Fill has no effect here (expand false) */
4810 0); /* No padding */
4812 gtk_box_pack_end(GTK_BOX(tab
->vbox
),
4814 FALSE
, /* Do not expand */
4815 FALSE
, /* Fill has no effect here (expand false) */
4816 0); /* No padding */
4818 g_object_set_data(G_OBJECT(tab
->viewer_container
), "focused_viewer", NULL
);
4824 // Display a label with a X
4825 GtkWidget *w_hbox = gtk_hbox_new(FALSE, 4);
4826 GtkWidget *w_label = gtk_label_new (label);
4827 GtkWidget *pixmap = create_pixmap(GTK_WIDGET(notebook), "close.png");
4828 GtkWidget *w_button = gtk_button_new ();
4829 gtk_container_add(GTK_CONTAINER(w_button), pixmap);
4830 //GtkWidget *w_button = gtk_button_new_with_label("x");
4832 gtk_button_set_relief(GTK_BUTTON(w_button), GTK_RELIEF_NONE);
4834 gtk_box_pack_start(GTK_BOX(w_hbox), w_label, TRUE, TRUE, 0);
4835 gtk_box_pack_end(GTK_BOX(w_hbox), w_button, FALSE,
4838 g_signal_connect_swapped (w_button, "clicked",
4839 G_CALLBACK (on_close_tab_X_clicked),
4842 gtk_widget_set_state(w_button, GTK_STATE_ACTIVE);
4844 gtk_widget_show (w_label);
4845 gtk_widget_show (pixmap);
4846 gtk_widget_show (w_button);
4847 gtk_widget_show (w_hbox);
4849 tab->label = w_hbox;
4853 tab
->label
= gtk_label_new (label
);
4855 gtk_widget_show(tab
->label
);
4856 gtk_widget_show(tab
->scrollbar
);
4857 gtk_widget_show(tab
->viewer_container
);
4858 gtk_widget_show(tab
->vbox
);
4859 //gtk_widget_show(tab->multivpaned);
4862 /* Start with empty events requests list */
4863 tab
->events_requests
= NULL
;
4864 tab
->events_request_pending
= FALSE
;
4865 tab
->stop_foreground
= FALSE
;
4869 g_signal_connect(G_OBJECT(tab
->scrollbar
), "value-changed",
4870 G_CALLBACK(scroll_value_changed_cb
), tab
);
4872 g_signal_connect ((gpointer
) tab
->MEntry1
, "value-changed",
4873 G_CALLBACK (on_MEntry1_value_changed
),
4875 g_signal_connect ((gpointer
) tab
->MEntry2
, "value-changed",
4876 G_CALLBACK (on_MEntry2_value_changed
),
4878 g_signal_connect ((gpointer
) tab
->MEntry3
, "value-changed",
4879 G_CALLBACK (on_MEntry3_value_changed
),
4881 g_signal_connect ((gpointer
) tab
->MEntry4
, "value-changed",
4882 G_CALLBACK (on_MEntry4_value_changed
),
4884 g_signal_connect ((gpointer
) tab
->MEntry5
, "value-changed",
4885 G_CALLBACK (on_MEntry5_value_changed
),
4887 g_signal_connect ((gpointer
) tab
->MEntry6
, "value-changed",
4888 G_CALLBACK (on_MEntry6_value_changed
),
4890 g_signal_connect ((gpointer
) tab
->MEntry7
, "value-changed",
4891 G_CALLBACK (on_MEntry7_value_changed
),
4893 g_signal_connect ((gpointer
) tab
->MEntry8
, "value-changed",
4894 G_CALLBACK (on_MEntry8_value_changed
),
4897 //g_signal_connect(G_OBJECT(tab->scrollbar), "changed",
4898 // G_CALLBACK(scroll_value_changed_cb), tab);
4901 //insert tab into notebook
4902 gtk_notebook_append_page(notebook
,
4905 list
= gtk_container_get_children(GTK_CONTAINER(notebook
));
4906 gtk_notebook_set_current_page(notebook
,g_list_length(list
)-1);
4907 // always show : not if(g_list_length(list)>1)
4908 gtk_notebook_set_show_tabs(notebook
, TRUE
);
4911 lttvwindow_report_time_window(tab
, copy_tab
->time_window
);
4912 lttvwindow_report_current_time(tab
, copy_tab
->current_time
);
4914 TimeWindow time_window
;
4916 time_window
.start_time
= ltt_time_zero
;
4917 time_window
.end_time
= ltt_time_add(time_window
.start_time
,
4918 lttvwindow_default_time_width
);
4919 time_window
.time_width
= lttvwindow_default_time_width
;
4920 time_window
.time_width_double
= ltt_time_to_double(time_window
.time_width
);
4922 lttvwindow_report_time_window(tab
, time_window
);
4923 lttvwindow_report_current_time(tab
, ltt_time_zero
);
4926 LttvTraceset
*traceset
= tab
->traceset_info
->traceset
;
4927 SetTraceset(tab
, traceset
);
4931 * execute_events_requests
4933 * Idle function that executes the pending requests for a tab.
4935 * @return return value : TRUE : keep the idle function, FALSE : remove it.
4937 gboolean
execute_events_requests(Tab
*tab
)
4939 return ( lttvwindow_process_pending_requests(tab
) );
4943 __EXPORT
void create_main_window_with_trace_list(GSList
*traces
)
4945 GSList
*iter
= NULL
;
4948 MainWindow
*mw
= construct_main_window(NULL
);
4949 GtkWidget
*widget
= mw
->mwindow
;
4951 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
4952 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
4953 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
4954 LttvPluginTab
*ptab
;
4958 ptab
= create_new_tab(widget
, NULL
);
4961 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
4965 for(iter
=traces
; iter
!=NULL
; iter
=g_slist_next(iter
)) {
4966 gchar
*path
= (gchar
*)iter
->data
;
4968 gchar abs_path
[PATH_MAX
];
4972 get_absolute_pathname(path
, abs_path
);
4973 trace_v
= lttvwindowtraces_get_trace_by_name(abs_path
);
4974 if(trace_v
== NULL
) {
4975 trace
= ltt_trace_open(abs_path
);
4977 g_warning("cannot open trace %s", abs_path
);
4979 GtkWidget
*dialogue
=
4980 gtk_message_dialog_new(
4981 GTK_WINDOW(gtk_widget_get_toplevel(widget
)),
4982 GTK_DIALOG_MODAL
|GTK_DIALOG_DESTROY_WITH_PARENT
,
4985 "Cannot open trace : maybe you should enter in the directory "
4987 gtk_dialog_run(GTK_DIALOG(dialogue
));
4988 gtk_widget_destroy(dialogue
);
4990 trace_v
= lttv_trace_new(trace
);
4991 lttvwindowtraces_add_trace(trace_v
);
4992 lttvwindow_add_trace(tab
, trace_v
);
4995 lttvwindow_add_trace(tab
, trace_v
);
4999 LttvTraceset
*traceset
;
5001 traceset
= tab
->traceset_info
->traceset
;
5002 SetTraceset(tab
, traceset
);