1 /* This file is part of the Linux Trace Toolkit viewer
2 * Copyright (C) 2003-2004 XangXiu Yang, Mathieu Desnoyers
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License Version 2 as
6 * published by the Free Software Foundation;
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place - Suite 330, Boston,
23 #include <limits.h> // for PATH_MAX
31 #include "callbacks.h"
32 #include "interface.h"
34 #include <ltt/trace.h>
36 #include <ltt/event.h>
37 #include <lttv/lttv.h>
38 #include <lttv/module.h>
39 #include <lttv/iattribute.h>
40 #include <lttv/stats.h>
41 #include <lttv/filter.h>
42 #include <lttv/sync/sync_chain_lttv.h>
43 #include <lttvwindow/mainwindow.h>
44 #include <lttvwindow/mainwindow-private.h>
45 #include <lttvwindow/menu.h>
46 #include <lttvwindow/toolbar.h>
47 #include <lttvwindow/lttvwindow.h>
48 #include <lttvwindow/lttvwindowtraces.h>
49 #include <lttvwindow/lttv_plugin_tab.h>
51 static LttTime lttvwindow_default_time_width
= { 1, 0 };
52 #define CLIP_BUF 256 // size of clipboard buffer
54 extern LttvTrace
*g_init_trace
;
57 /** Array containing instanced objects. */
58 extern GSList
* g_main_window_list
;
60 /** MD : keep old directory. */
61 static char remember_plugins_dir
[PATH_MAX
] = "";
62 static char remember_trace_dir
[PATH_MAX
] = "";
64 void tab_destructor(LttvPluginTab
* ptab
);
66 MainWindow
* get_window_data_struct(GtkWidget
* widget
);
67 char * get_load_module(MainWindow
*mw
,
68 char ** load_module_name
, int nb_module
);
69 char * get_unload_module(MainWindow
*mw
,
70 char ** loaded_module_name
, int nb_module
);
71 char * get_remove_trace(MainWindow
*mw
, char ** all_trace_name
, int nb_trace
);
72 char * get_selection(MainWindow
*mw
,
73 char ** all_name
, int nb
, char *title
, char * column_title
);
74 void init_tab(Tab
*tab
, MainWindow
* mw
, Tab
*copy_tab
,
75 GtkNotebook
* notebook
, char * label
);
77 static void insert_viewer(GtkWidget
* widget
, lttvwindow_viewer_constructor constructor
);
79 LttvPluginTab
*create_new_tab(GtkWidget
* widget
, gpointer user_data
);
81 static gboolean
lttvwindow_process_pending_requests(Tab
*tab
);
95 /* Pasting routines */
97 static void MEventBox1a_receive(GtkClipboard
*clipboard
,
101 if(text
== NULL
) return;
102 Tab
*tab
= (Tab
*)data
;
103 gchar buffer
[CLIP_BUF
];
104 gchar
*ptr
= buffer
, *ptr_ssec
, *ptr_snsec
, *ptr_esec
, *ptr_ensec
;
106 strncpy(buffer
, text
, CLIP_BUF
);
109 while(!isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
110 /* remove leading junk */
112 while(isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
113 /* read all the first number */
117 while(!isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
118 /* remove leading junk */
120 while(isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
121 /* read all the first number */
125 while(!isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
126 /* remove leading junk */
128 while(isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
129 /* read all the first number */
133 while(!isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
134 /* remove leading junk */
136 while(isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
137 /* read all the first number */
140 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry1
),
141 (double)strtoul(ptr_ssec
, NULL
, 10));
142 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry2
),
143 (double)strtoul(ptr_snsec
, NULL
, 10));
144 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry3
),
145 (double)strtoul(ptr_esec
, NULL
, 10));
146 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry4
),
147 (double)strtoul(ptr_ensec
, NULL
, 10));
150 static gboolean
on_MEventBox1a_paste(GtkWidget
*widget
, GdkEventButton
*event
,
153 Tab
*tab
= (Tab
*)data
;
155 GtkClipboard
*clip
= gtk_clipboard_get_for_display(gdk_display_get_default(),
156 GDK_SELECTION_PRIMARY
);
157 gtk_clipboard_request_text(clip
,
158 (GtkClipboardTextReceivedFunc
)MEventBox1a_receive
,
165 static void MEventBox1b_receive(GtkClipboard
*clipboard
,
169 if(text
== NULL
) return;
170 Tab
*tab
= (Tab
*)data
;
171 gchar buffer
[CLIP_BUF
];
172 gchar
*ptr
= buffer
, *ptr_sec
, *ptr_nsec
;
174 strncpy(buffer
, text
, CLIP_BUF
);
176 while(!isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
177 /* remove leading junk */
179 while(isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
180 /* read all the first number */
184 while(!isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
185 /* remove leading junk */
187 while(isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
188 /* read all the first number */
191 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry1
),
192 (double)strtoul(ptr_sec
, NULL
, 10));
193 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry2
),
194 (double)strtoul(ptr_nsec
, NULL
, 10));
198 static gboolean
on_MEventBox1b_paste(GtkWidget
*widget
, GdkEventButton
*event
,
201 Tab
*tab
= (Tab
*)data
;
203 GtkClipboard
*clip
= gtk_clipboard_get_for_display(gdk_display_get_default(),
204 GDK_SELECTION_PRIMARY
);
205 gtk_clipboard_request_text(clip
,
206 (GtkClipboardTextReceivedFunc
)MEventBox1b_receive
,
212 static void MEventBox3b_receive(GtkClipboard
*clipboard
,
216 if(text
== NULL
) return;
217 Tab
*tab
= (Tab
*)data
;
218 gchar buffer
[CLIP_BUF
];
219 gchar
*ptr
= buffer
, *ptr_sec
, *ptr_nsec
;
221 strncpy(buffer
, text
, CLIP_BUF
);
223 while(!isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
224 /* remove leading junk */
226 while(isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
227 /* read all the first number */
231 while(!isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
232 /* remove leading junk */
234 while(isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
235 /* read all the first number */
238 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry3
),
239 (double)strtoul(ptr_sec
, NULL
, 10));
240 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry4
),
241 (double)strtoul(ptr_nsec
, NULL
, 10));
245 static gboolean
on_MEventBox3b_paste(GtkWidget
*widget
, GdkEventButton
*event
,
248 Tab
*tab
= (Tab
*)data
;
250 GtkClipboard
*clip
= gtk_clipboard_get_for_display(gdk_display_get_default(),
251 GDK_SELECTION_PRIMARY
);
252 gtk_clipboard_request_text(clip
,
253 (GtkClipboardTextReceivedFunc
)MEventBox3b_receive
,
259 static void MEventBox5b_receive(GtkClipboard
*clipboard
,
263 if(text
== NULL
) return;
264 Tab
*tab
= (Tab
*)data
;
265 gchar buffer
[CLIP_BUF
];
266 gchar
*ptr
= buffer
, *ptr_sec
, *ptr_nsec
;
268 strncpy(buffer
, text
, CLIP_BUF
);
270 while(!isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
271 /* remove leading junk */
273 while(isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
274 /* read all the first number */
278 while(!isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
279 /* remove leading junk */
281 while(isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
282 /* read all the first number */
285 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry5
),
286 (double)strtoul(ptr_sec
, NULL
, 10));
287 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry6
),
288 (double)strtoul(ptr_nsec
, NULL
, 10));
292 static gboolean
on_MEventBox5b_paste(GtkWidget
*widget
, GdkEventButton
*event
,
295 Tab
*tab
= (Tab
*)data
;
297 GtkClipboard
*clip
= gtk_clipboard_get_for_display(gdk_display_get_default(),
298 GDK_SELECTION_PRIMARY
);
299 gtk_clipboard_request_text(clip
,
300 (GtkClipboardTextReceivedFunc
)MEventBox5b_receive
,
306 static void MEventBox8_receive(GtkClipboard
*clipboard
,
310 if(text
== NULL
) return;
311 Tab
*tab
= (Tab
*)data
;
312 gchar buffer
[CLIP_BUF
];
313 gchar
*ptr
= buffer
, *ptr_sec
, *ptr_nsec
;
315 strncpy(buffer
, text
, CLIP_BUF
);
317 while(!isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
318 /* remove leading junk */
320 while(isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
321 /* read all the first number */
325 while(!isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
326 /* remove leading junk */
328 while(isdigit(*ptr
) && ptr
< buffer
+CLIP_BUF
-1) ptr
++;
329 /* read all the first number */
332 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry7
),
333 (double)strtoul(ptr_sec
, NULL
, 10));
334 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry8
),
335 (double)strtoul(ptr_nsec
, NULL
, 10));
339 static gboolean
on_MEventBox8_paste(GtkWidget
*widget
, GdkEventButton
*event
,
342 Tab
*tab
= (Tab
*)data
;
344 GtkClipboard
*clip
= gtk_clipboard_get_for_display(gdk_display_get_default(),
345 GDK_SELECTION_PRIMARY
);
346 gtk_clipboard_request_text(clip
,
347 (GtkClipboardTextReceivedFunc
)MEventBox8_receive
,
353 static void on_top_notify(GObject
*gobject
,
357 Tab
*tab
= (Tab
*)user_data
;
358 g_message("in on_top_notify.\n");
362 static gboolean
viewer_grab_focus(GtkWidget
*widget
, GdkEventButton
*event
,
365 GtkWidget
*viewer
= GTK_WIDGET(data
);
366 GtkWidget
*viewer_container
= gtk_widget_get_parent(viewer
);
368 g_debug("FOCUS GRABBED");
369 g_object_set_data(G_OBJECT(viewer_container
), "focused_viewer", viewer
);
374 static void connect_focus_recursive(GtkWidget
*widget
,
377 if(GTK_IS_CONTAINER(widget
)) {
378 gtk_container_forall(GTK_CONTAINER(widget
),
379 (GtkCallback
)connect_focus_recursive
,
383 if(GTK_IS_TREE_VIEW(widget
)) {
384 gtk_tree_view_set_headers_clickable(GTK_TREE_VIEW(widget
), TRUE
);
386 gtk_widget_add_events(widget
, GDK_BUTTON_PRESS_MASK
);
387 g_signal_connect (G_OBJECT(widget
),
388 "button-press-event",
389 G_CALLBACK (viewer_grab_focus
),
393 /* Stop all the processings and call gtk_main_quit() */
394 static void mainwindow_quit()
396 lttvwindowtraces_unregister_requests(g_quark_from_string("stats"));
397 lttvwindowtraces_unregister_requests(g_quark_from_string("state"));
398 lttvwindowtraces_unregister_computation_hooks(g_quark_from_string("stats"));
399 lttvwindowtraces_unregister_computation_hooks(g_quark_from_string("state"));
405 /* insert_viewer function constructs an instance of a viewer first,
406 * then inserts the widget of the instance into the container of the
411 insert_viewer_wrap(GtkWidget
*menuitem
, gpointer user_data
)
413 insert_viewer((GtkWidget
*)menuitem
, (lttvwindow_viewer_constructor
)user_data
);
417 /* internal functions */
418 void insert_viewer(GtkWidget
* widget
, lttvwindow_viewer_constructor constructor
)
420 GtkWidget
* viewer_container
;
421 MainWindow
* mw_data
= get_window_data_struct(widget
);
422 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
424 TimeInterval
* time_interval
;
425 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
426 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
431 ptab
= create_new_tab(widget
, NULL
);
433 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
437 viewer_container
= tab
->viewer_container
;
439 viewer
= (GtkWidget
*)constructor(ptab
);
442 //gtk_multivpaned_widget_add(GTK_MULTIVPANED(multivpaned), viewer);
444 gtk_box_pack_end(GTK_BOX(viewer_container
),
450 /* We want to connect the viewer_grab_focus to EVERY
451 * child of this widget. The little trick is to get each child
452 * of each GTK_CONTAINER, even subchildren.
454 connect_focus_recursive(viewer
, viewer
);
459 * Function to set/update traceset for the viewers
460 * @param tab viewer's tab
461 * @param traceset traceset of the main window.
463 * 0 : traceset updated
464 * 1 : no traceset hooks to update; not an error.
467 int SetTraceset(Tab
* tab
, LttvTraceset
*traceset
)
470 TimeInterval time_span
;
471 TimeWindow new_time_window
;
472 LttTime new_current_time
;
473 LttvTracesetContext
*tsc
=
474 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
476 // Perform time synchronization on the traces
477 if (syncTraceset(tsc
))
479 /* There is some time-dependant information that was calculated during
480 * context initialization. Destroy the old contexts and initialize new
482 * Modified from lttvwindow_add_trace()
484 // Keep a reference to the traces so they are not freed
485 for(i
= 0; i
< lttv_traceset_number(traceset
); i
++)
487 LttvTrace
*trace
= lttv_traceset_get(traceset
, i
);
488 lttv_trace_ref(trace
);
491 // Remove state update hooks
492 lttv_state_remove_event_hooks(
493 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
495 lttv_context_fini(LTTV_TRACESET_CONTEXT(
496 tab
->traceset_info
->traceset_context
));
497 g_object_unref(tab
->traceset_info
->traceset_context
);
499 for(i
= 0; i
< lttv_traceset_number(traceset
); i
++)
501 LttvTrace
*trace
= lttv_traceset_get(traceset
, i
);
502 lttvwindowtraces_remove_trace(trace
);
503 lttvwindowtraces_add_trace(trace
);
506 // Create new context
507 tab
->traceset_info
->traceset_context
=
508 g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
509 lttv_context_init(LTTV_TRACESET_CONTEXT(tab
->traceset_info
->
510 traceset_context
), traceset
);
512 // Add state update hooks
513 lttv_state_add_event_hooks(
514 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
516 // Remove local reference to the traces
517 for(i
=0; i
<lttv_traceset_number(traceset
); i
++)
519 LttvTrace
*trace
= lttv_traceset_get(traceset
, i
);
520 lttv_trace_unref(trace
);
523 tsc
= LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
526 time_span
= tsc
->time_span
;
527 new_time_window
= tab
->time_window
;
528 new_current_time
= tab
->current_time
;
530 /* Set the tab's time window and current time if
532 if(ltt_time_compare(tab
->time_window
.start_time
, time_span
.start_time
) < 0
533 || ltt_time_compare(tab
->time_window
.end_time
,
534 time_span
.end_time
) > 0) {
535 new_time_window
.start_time
= time_span
.start_time
;
537 new_current_time
= time_span
.start_time
;
541 if(ltt_time_compare(lttvwindow_default_time_width
,
542 ltt_time_sub(time_span
.end_time
, time_span
.start_time
)) < 0
544 ltt_time_compare(time_span
.end_time
, time_span
.start_time
) == 0)
545 tmp_time
= lttvwindow_default_time_width
;
547 tmp_time
= time_span
.end_time
;
549 new_time_window
.time_width
= tmp_time
;
550 new_time_window
.time_width_double
= ltt_time_to_double(tmp_time
);
551 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
552 new_time_window
.time_width
) ;
559 GtkAdjustment
*adjustment
= gtk_range_get_adjustment(GTK_RANGE(tab
->scrollbar
));
560 LttTime upper
= ltt_time_sub(time_span
.end_time
, time_span
.start_time
);
562 g_object_set(G_OBJECT(adjustment
),
566 ltt_time_to_double(upper
)
567 * NANOSECONDS_PER_SECOND
, /* upper */
569 ltt_time_to_double(tab
->time_window
.time_width
)
570 / SCROLL_STEP_PER_PAGE
571 * NANOSECONDS_PER_SECOND
, /* step increment */
573 ltt_time_to_double(tab
->time_window
.time_width
)
574 * NANOSECONDS_PER_SECOND
, /* page increment */
576 ltt_time_to_double(tab
->time_window
.time_width
)
577 * NANOSECONDS_PER_SECOND
, /* page size */
579 gtk_adjustment_changed(adjustment
);
581 g_object_set(G_OBJECT(adjustment
),
584 ltt_time_sub(tab
->time_window
.start_time
, time_span
.start_time
))
585 * NANOSECONDS_PER_SECOND
, /* value */
587 gtk_adjustment_value_changed(adjustment
);
589 /* set the time bar. The value callbacks will change their nsec themself */
591 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry1
),
592 (double)time_span
.start_time
.tv_sec
,
593 (double)time_span
.end_time
.tv_sec
);
596 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry3
),
597 (double)time_span
.start_time
.tv_sec
,
598 (double)time_span
.end_time
.tv_sec
);
600 /* current seconds */
601 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry5
),
602 (double)time_span
.start_time
.tv_sec
,
603 (double)time_span
.end_time
.tv_sec
);
606 /* Finally, call the update hooks of the viewers */
608 LttvAttributeValue value
;
611 retval
= lttv_iattribute_find_by_path(tab
->attributes
,
612 "hooks/updatetraceset", LTTV_POINTER
, &value
);
615 tmp
= (LttvHooks
*)*(value
.v_pointer
);
619 lttv_hooks_call(tmp
,traceset
);
621 time_change_manager(tab
, new_time_window
);
622 current_time_change_manager(tab
, new_current_time
);
628 * Function to set/update filter for the viewers
629 * @param tab viewer's tab
630 * @param filter filter of the main window.
633 * 0 : filters updated
634 * 1 : no filter hooks to update; not an error.
637 int SetFilter(Tab
* tab
, gpointer filter
)
640 LttvAttributeValue value
;
642 g_assert(lttv_iattribute_find_by_path(tab
->attributes
,
643 "hooks/updatefilter", LTTV_POINTER
, &value
));
645 tmp
= (LttvHooks
*)*(value
.v_pointer
);
647 if(tmp
== NULL
) return 1;
648 lttv_hooks_call(tmp
,filter
);
656 * Function to redraw each viewer belonging to the current tab
657 * @param tab viewer's tab
660 void update_traceset(Tab
*tab
)
662 LttvAttributeValue value
;
666 retval
= lttv_iattribute_find_by_path(tab
->attributes
,
667 "hooks/updatetraceset", LTTV_POINTER
, &value
);
669 tmp
= (LttvHooks
*)*(value
.v_pointer
);
670 if(tmp
== NULL
) return;
671 lttv_hooks_call(tmp
, NULL
);
675 /* get_label function is used to get user input, it displays an input
676 * box, which allows user to input a string
679 void get_label_string (GtkWidget
* text
, gchar
* label
)
681 GtkEntry
* entry
= (GtkEntry
*)text
;
682 if(strlen(gtk_entry_get_text(entry
))!=0)
683 strcpy(label
,gtk_entry_get_text(entry
));
686 gboolean
get_label(MainWindow
* mw
, gchar
* str
, gchar
* dialogue_title
, gchar
* label_str
)
688 GtkWidget
* dialogue
;
693 dialogue
= gtk_dialog_new_with_buttons(dialogue_title
,NULL
,
695 GTK_STOCK_OK
,GTK_RESPONSE_ACCEPT
,
696 GTK_STOCK_CANCEL
,GTK_RESPONSE_REJECT
,
699 label
= gtk_label_new(label_str
);
700 gtk_widget_show(label
);
702 text
= gtk_entry_new();
703 gtk_widget_show(text
);
705 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialogue
)->vbox
), label
,TRUE
, TRUE
,0);
706 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialogue
)->vbox
), text
,FALSE
, FALSE
,0);
708 id
= gtk_dialog_run(GTK_DIALOG(dialogue
));
710 case GTK_RESPONSE_ACCEPT
:
711 get_label_string(text
,str
);
712 gtk_widget_destroy(dialogue
);
714 case GTK_RESPONSE_REJECT
:
716 gtk_widget_destroy(dialogue
);
723 /* get_window_data_struct function is actually a lookup function,
724 * given a widget which is in the tree of the main window, it will
725 * return the MainWindow data structure associated with main window
728 MainWindow
* get_window_data_struct(GtkWidget
* widget
)
731 MainWindow
* mw_data
;
733 mw
= lookup_widget(widget
, "MWindow");
735 g_info("Main window does not exist\n");
739 mw_data
= (MainWindow
*) g_object_get_data(G_OBJECT(mw
),"main_window_data");
741 g_warning("Main window data does not exist\n");
748 /* create_new_window function, just constructs a new main window
751 void create_new_window(GtkWidget
* widget
, gpointer user_data
, gboolean clone
)
753 MainWindow
* parent
= get_window_data_struct(widget
);
756 g_info("Clone : use the same traceset\n");
757 construct_main_window(parent
);
759 g_info("Empty : traceset is set to NULL\n");
760 construct_main_window(NULL
);
764 /* Get the currently focused viewer.
765 * If no viewer is focused, use the first one.
767 * If no viewer available, return NULL.
769 GtkWidget
*viewer_container_focus(GtkWidget
*container
)
773 widget
= (GtkWidget
*)g_object_get_data(G_OBJECT(container
),
777 g_debug("no widget focused");
778 GList
*children
= gtk_container_get_children(GTK_CONTAINER(container
));
781 widget
= GTK_WIDGET(children
->data
);
782 g_object_set_data(G_OBJECT(container
),
792 gint
viewer_container_position(GtkWidget
*container
, GtkWidget
*child
)
795 if(child
== NULL
) return -1;
799 memset(&value
, 0, sizeof(GValue
));
800 g_value_init(&value
, G_TYPE_INT
);
801 gtk_container_child_get_property(GTK_CONTAINER(container
),
805 pos
= g_value_get_int(&value
);
811 /* move_*_viewer functions move the selected view up/down in
815 void move_down_viewer(GtkWidget
* widget
, gpointer user_data
)
817 MainWindow
* mw
= get_window_data_struct(widget
);
818 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
820 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
821 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
828 ptab
= g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
832 //gtk_multivpaned_widget_move_up(GTK_MULTIVPANED(tab->multivpaned));
834 /* change the position in the vbox */
835 GtkWidget
*focus_widget
;
837 focus_widget
= viewer_container_focus(tab
->viewer_container
);
838 position
= viewer_container_position(tab
->viewer_container
, focus_widget
);
841 /* can move up one position */
842 gtk_box_reorder_child(GTK_BOX(tab
->viewer_container
),
849 void move_up_viewer(GtkWidget
* widget
, gpointer user_data
)
851 MainWindow
* mw
= get_window_data_struct(widget
);
852 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
854 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
855 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
862 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
866 //gtk_multivpaned_widget_move_down(GTK_MULTIVPANED(tab->multivpaned));
867 /* change the position in the vbox */
868 GtkWidget
*focus_widget
;
870 focus_widget
= viewer_container_focus(tab
->viewer_container
);
871 position
= viewer_container_position(tab
->viewer_container
, focus_widget
);
875 g_list_length(gtk_container_get_children(
876 GTK_CONTAINER(tab
->viewer_container
)))-1
878 /* can move down one position */
879 gtk_box_reorder_child(GTK_BOX(tab
->viewer_container
),
887 /* delete_viewer deletes the selected viewer in the current tab
890 void delete_viewer(GtkWidget
* widget
, gpointer user_data
)
892 MainWindow
* mw
= get_window_data_struct(widget
);
893 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
895 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
896 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
903 ptab
= g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
907 //gtk_multivpaned_widget_delete(GTK_MULTIVPANED(tab->multivpaned));
909 GtkWidget
*focus_widget
= viewer_container_focus(tab
->viewer_container
);
911 if(focus_widget
!= NULL
)
912 gtk_widget_destroy(focus_widget
);
914 g_object_set_data(G_OBJECT(tab
->viewer_container
), "focused_viewer", NULL
);
918 /* open_traceset will open a traceset saved in a file
919 * Right now, it is not finished yet, (not working)
923 void open_traceset(GtkWidget
* widget
, gpointer user_data
)
927 LttvTraceset
* traceset
;
928 MainWindow
* mw_data
= get_window_data_struct(widget
);
929 GtkFileSelection
* file_selector
=
930 (GtkFileSelection
*)gtk_file_selection_new("Select a traceset");
932 gtk_file_selection_hide_fileop_buttons(file_selector
);
934 gtk_window_set_transient_for(GTK_WINDOW(file_selector
),
935 GTK_WINDOW(mw_data
->mwindow
));
937 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
939 case GTK_RESPONSE_ACCEPT
:
940 case GTK_RESPONSE_OK
:
941 dir
= gtk_file_selection_get_selections (file_selector
);
942 traceset
= lttv_traceset_load(dir
[0]);
943 g_info("Open a trace set %s\n", dir
[0]);
946 case GTK_RESPONSE_REJECT
:
947 case GTK_RESPONSE_CANCEL
:
949 gtk_widget_destroy((GtkWidget
*)file_selector
);
955 /* lttvwindow_process_pending_requests
957 * Process requests for parts of the trace from viewers.
959 * These requests are made by lttvwindow_events_request().
961 * This internal function gets called by g_idle, taking care of the pending
962 * requests. It is responsible for concatenation of time intervals and position
963 * requests. It does it with the following algorithm organizing process traceset
964 * calls. Here is the detailed description of the way it works :
966 * - Events Requests Servicing Algorithm
968 * Data structures necessary :
970 * List of requests added to context : list_in
971 * List of requests not added to context : list_out
976 * list_out : many events requests
978 * FIXME : insert rest of algorithm here
982 #define list_out tab->events_requests
984 gboolean
lttvwindow_process_pending_requests(Tab
*tab
)
987 LttvTracesetContext
*tsc
;
988 LttvTracefileContext
*tfc
;
989 GSList
*list_in
= NULL
;
993 LttvTracesetContextPosition
*end_position
;
995 if(lttvwindow_preempt_count
> 0) return TRUE
;
998 g_critical("Foreground processing : tab does not exist. Processing removed.");
1002 /* There is no events requests pending : we should never have been called! */
1003 g_assert(g_slist_length(list_out
) != 0);
1005 tsc
= LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
1007 //set the cursor to be X shape, indicating that the computer is busy in doing its job
1009 new = gdk_cursor_new(GDK_X_CURSOR
);
1010 widget
= lookup_widget(tab
->mw
->mwindow
, "MToolbar1");
1011 win
= gtk_widget_get_parent_window(widget
);
1012 gdk_window_set_cursor(win
, new);
1013 gdk_cursor_unref(new);
1014 gdk_window_stick(win
);
1015 gdk_window_unstick(win
);
1018 g_debug("SIZE events req len : %d", g_slist_length(list_out
));
1020 /* Preliminary check for no trace in traceset */
1021 /* Unregister the routine if empty, empty list_out too */
1022 if(lttv_traceset_number(tsc
->ts
) == 0) {
1024 /* - For each req in list_out */
1025 GSList
*iter
= list_out
;
1027 while(iter
!= NULL
) {
1029 gboolean remove
= FALSE
;
1030 gboolean free_data
= FALSE
;
1031 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1033 /* - Call end request for req */
1034 if(events_request
->servicing
== TRUE
)
1035 lttv_hooks_call(events_request
->after_request
, (gpointer
)tsc
);
1037 /* - remove req from list_out */
1038 /* Destroy the request */
1045 GSList
*remove_iter
= iter
;
1047 iter
= g_slist_next(iter
);
1048 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
1049 list_out
= g_slist_remove_link(list_out
, remove_iter
);
1050 } else { // not remove
1051 iter
= g_slist_next(iter
);
1056 /* 0.1 Lock Traces */
1061 iter_trace
<lttv_traceset_number(tsc
->ts
);
1063 LttvTrace
*trace_v
= lttv_traceset_get(tsc
->ts
, iter_trace
);
1065 if(lttvwindowtraces_lock(trace_v
) != 0) {
1066 g_critical("Foreground processing : Unable to get trace lock");
1067 return TRUE
; /* Cannot get lock, try later */
1072 /* 0.2 Seek tracefiles positions to context position */
1073 //g_assert(lttv_process_traceset_seek_position(tsc, sync_position) == 0);
1074 lttv_process_traceset_synchronize_tracefiles(tsc
);
1077 /* Events processing algorithm implementation */
1078 /* Warning : the gtk_events_pending takes a LOT of cpu time. So what we do
1079 * instead is to leave the control to GTK and take it back.
1081 /* A. Servicing loop */
1082 //while( (g_slist_length(list_in) != 0 || g_slist_length(list_out) != 0)) {
1083 if((g_slist_length(list_in
) != 0 || g_slist_length(list_out
) != 0)) {
1085 /* 1. If list_in is empty (need a seek) */
1086 if( g_slist_length(list_in
) == 0 ) {
1088 /* list in is empty, need a seek */
1090 /* 1.1 Add requests to list_in */
1091 GSList
*ltime
= NULL
;
1092 GSList
*lpos
= NULL
;
1093 GSList
*iter
= NULL
;
1095 /* 1.1.1 Find all time requests with the lowest start time in list_out
1098 if(g_slist_length(list_out
) > 0)
1099 ltime
= g_slist_append(ltime
, g_slist_nth_data(list_out
, 0));
1100 for(iter
=g_slist_nth(list_out
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
1101 /* Find all time requests with the lowest start time in list_out */
1102 EventsRequest
*event_request_ltime
= (EventsRequest
*)g_slist_nth_data(ltime
, 0);
1103 EventsRequest
*event_request_list_out
= (EventsRequest
*)iter
->data
;
1106 comp
= ltt_time_compare(event_request_ltime
->start_time
,
1107 event_request_list_out
->start_time
);
1109 ltime
= g_slist_append(ltime
, event_request_list_out
);
1111 /* Remove all elements from ltime, and add current */
1112 while(ltime
!= NULL
)
1113 ltime
= g_slist_delete_link(ltime
, g_slist_nth(ltime
, 0));
1114 ltime
= g_slist_append(ltime
, event_request_list_out
);
1118 /* 1.1.2 Find all position requests with the lowest position in list_out
1121 if(g_slist_length(list_out
) > 0)
1122 lpos
= g_slist_append(lpos
, g_slist_nth_data(list_out
, 0));
1123 for(iter
=g_slist_nth(list_out
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
1124 /* Find all position requests with the lowest position in list_out */
1125 EventsRequest
*event_request_lpos
= (EventsRequest
*)g_slist_nth_data(lpos
, 0);
1126 EventsRequest
*event_request_list_out
= (EventsRequest
*)iter
->data
;
1129 if(event_request_lpos
->start_position
!= NULL
1130 && event_request_list_out
->start_position
!= NULL
)
1132 comp
= lttv_traceset_context_pos_pos_compare
1133 (event_request_lpos
->start_position
,
1134 event_request_list_out
->start_position
);
1139 lpos
= g_slist_append(lpos
, event_request_list_out
);
1141 /* Remove all elements from lpos, and add current */
1143 lpos
= g_slist_delete_link(lpos
, g_slist_nth(lpos
, 0));
1144 lpos
= g_slist_append(lpos
, event_request_list_out
);
1149 EventsRequest
*event_request_lpos
= (EventsRequest
*)g_slist_nth_data(lpos
, 0);
1150 EventsRequest
*event_request_ltime
= (EventsRequest
*)g_slist_nth_data(ltime
, 0);
1151 LttTime lpos_start_time
;
1153 if(event_request_lpos
!= NULL
1154 && event_request_lpos
->start_position
!= NULL
) {
1155 lpos_start_time
= lttv_traceset_context_position_get_time(
1156 event_request_lpos
->start_position
);
1159 /* 1.1.3 If lpos.start time < ltime */
1160 if(event_request_lpos
!= NULL
1161 && event_request_lpos
->start_position
!= NULL
1162 && ltt_time_compare(lpos_start_time
,
1163 event_request_ltime
->start_time
)<0) {
1164 /* Add lpos to list_in, remove them from list_out */
1165 for(iter
=lpos
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
1166 /* Add to list_in */
1167 EventsRequest
*event_request_lpos
=
1168 (EventsRequest
*)iter
->data
;
1170 list_in
= g_slist_append(list_in
, event_request_lpos
);
1171 /* Remove from list_out */
1172 list_out
= g_slist_remove(list_out
, event_request_lpos
);
1175 /* 1.1.4 (lpos.start time >= ltime) */
1176 /* Add ltime to list_in, remove them from list_out */
1178 for(iter
=ltime
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
1179 /* Add to list_in */
1180 EventsRequest
*event_request_ltime
=
1181 (EventsRequest
*)iter
->data
;
1183 list_in
= g_slist_append(list_in
, event_request_ltime
);
1184 /* Remove from list_out */
1185 list_out
= g_slist_remove(list_out
, event_request_ltime
);
1190 g_slist_free(ltime
);
1195 tfc
= lttv_traceset_context_get_current_tfc(tsc
);
1196 g_assert(g_slist_length(list_in
)>0);
1197 EventsRequest
*events_request
= g_slist_nth_data(list_in
, 0);
1200 /* 1.2.1 If first request in list_in is a time request */
1201 if(events_request
->start_position
== NULL
) {
1202 /* - If first req in list_in start time != current time */
1203 if(tfc
== NULL
|| ltt_time_compare(events_request
->start_time
,
1204 tfc
->timestamp
) != 0)
1205 /* - Seek to that time */
1206 g_debug("SEEK TIME : %lu, %lu", events_request
->start_time
.tv_sec
,
1207 events_request
->start_time
.tv_nsec
);
1208 //lttv_process_traceset_seek_time(tsc, events_request->start_time);
1209 lttv_state_traceset_seek_time_closest(LTTV_TRACESET_STATE(tsc
),
1210 events_request
->start_time
);
1212 /* Process the traceset with only state hooks */
1214 lttv_process_traceset_middle(tsc
,
1215 events_request
->start_time
,
1218 g_assert(seek_count
< LTTV_STATE_SAVE_INTERVAL
);
1224 LttvTracefileContext
*tfc
=
1225 lttv_traceset_context_get_current_tfc(tsc
);
1226 /* Else, the first request in list_in is a position request */
1227 /* If first req in list_in pos != current pos */
1228 g_assert(events_request
->start_position
!= NULL
);
1229 g_debug("SEEK POS time : %lu, %lu",
1230 lttv_traceset_context_position_get_time(
1231 events_request
->start_position
).tv_sec
,
1232 lttv_traceset_context_position_get_time(
1233 events_request
->start_position
).tv_nsec
);
1236 g_debug("SEEK POS context time : %lu, %lu",
1237 tfc
->timestamp
.tv_sec
,
1238 tfc
->timestamp
.tv_nsec
);
1240 g_debug("SEEK POS context time : %lu, %lu",
1241 ltt_time_infinite
.tv_sec
,
1242 ltt_time_infinite
.tv_nsec
);
1244 g_assert(events_request
->start_position
!= NULL
);
1245 if(lttv_traceset_context_ctx_pos_compare(tsc
,
1246 events_request
->start_position
) != 0) {
1247 /* 1.2.2.1 Seek to that position */
1248 g_debug("SEEK POSITION");
1249 //lttv_process_traceset_seek_position(tsc, events_request->start_position);
1250 pos_time
= lttv_traceset_context_position_get_time(
1251 events_request
->start_position
);
1253 lttv_state_traceset_seek_time_closest(LTTV_TRACESET_STATE(tsc
),
1256 /* Process the traceset with only state hooks */
1258 lttv_process_traceset_middle(tsc
,
1261 events_request
->start_position
);
1262 g_assert(lttv_traceset_context_ctx_pos_compare(tsc
,
1263 events_request
->start_position
) == 0);
1270 /* 1.3 Add hooks and call before request for all list_in members */
1272 GSList
*iter
= NULL
;
1274 for(iter
=list_in
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
1275 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1276 /* 1.3.1 If !servicing */
1277 if(events_request
->servicing
== FALSE
) {
1278 /* - begin request hooks called
1279 * - servicing = TRUE
1281 lttv_hooks_call(events_request
->before_request
, (gpointer
)tsc
);
1282 events_request
->servicing
= TRUE
;
1284 /* 1.3.2 call before chunk
1285 * 1.3.3 events hooks added
1287 if(events_request
->trace
== -1)
1288 lttv_process_traceset_begin(tsc
,
1289 events_request
->before_chunk_traceset
,
1290 events_request
->before_chunk_trace
,
1291 events_request
->before_chunk_tracefile
,
1292 events_request
->event
,
1293 events_request
->event_by_id_channel
);
1295 guint nb_trace
= lttv_traceset_number(tsc
->ts
);
1296 g_assert((guint
)events_request
->trace
< nb_trace
&&
1297 events_request
->trace
> -1);
1298 LttvTraceContext
*tc
= tsc
->traces
[events_request
->trace
];
1300 lttv_hooks_call(events_request
->before_chunk_traceset
, tsc
);
1302 lttv_trace_context_add_hooks(tc
,
1303 events_request
->before_chunk_trace
,
1304 events_request
->before_chunk_tracefile
,
1305 events_request
->event
,
1306 events_request
->event_by_id_channel
);
1311 /* 2. Else, list_in is not empty, we continue a read */
1314 /* 2.0 For each req of list_in */
1315 GSList
*iter
= list_in
;
1317 while(iter
!= NULL
) {
1319 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1321 /* - Call before chunk
1322 * - events hooks added
1324 if(events_request
->trace
== -1)
1325 lttv_process_traceset_begin(tsc
,
1326 events_request
->before_chunk_traceset
,
1327 events_request
->before_chunk_trace
,
1328 events_request
->before_chunk_tracefile
,
1329 events_request
->event
,
1330 events_request
->event_by_id_channel
);
1332 guint nb_trace
= lttv_traceset_number(tsc
->ts
);
1333 g_assert((guint
)events_request
->trace
< nb_trace
&&
1334 events_request
->trace
> -1);
1335 LttvTraceContext
*tc
= tsc
->traces
[events_request
->trace
];
1337 lttv_hooks_call(events_request
->before_chunk_traceset
, tsc
);
1339 lttv_trace_context_add_hooks(tc
,
1340 events_request
->before_chunk_trace
,
1341 events_request
->before_chunk_tracefile
,
1342 events_request
->event
,
1343 events_request
->event_by_id_channel
);
1346 iter
= g_slist_next(iter
);
1351 tfc
= lttv_traceset_context_get_current_tfc(tsc
);
1353 /* 2.1 For each req of list_out */
1354 GSList
*iter
= list_out
;
1356 while(iter
!= NULL
) {
1358 gboolean remove
= FALSE
;
1359 gboolean free_data
= FALSE
;
1360 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1362 /* if req.start time == current context time
1363 * or req.start position == current position*/
1364 if( ltt_time_compare(events_request
->start_time
,
1365 tfc
->timestamp
) == 0
1367 (events_request
->start_position
!= NULL
1369 lttv_traceset_context_ctx_pos_compare(tsc
,
1370 events_request
->start_position
) == 0)
1372 /* - Add to list_in, remove from list_out */
1373 list_in
= g_slist_append(list_in
, events_request
);
1377 /* - If !servicing */
1378 if(events_request
->servicing
== FALSE
) {
1379 /* - begin request hooks called
1380 * - servicing = TRUE
1382 lttv_hooks_call(events_request
->before_request
, (gpointer
)tsc
);
1383 events_request
->servicing
= TRUE
;
1385 /* call before chunk
1386 * events hooks added
1388 if(events_request
->trace
== -1)
1389 lttv_process_traceset_begin(tsc
,
1390 events_request
->before_chunk_traceset
,
1391 events_request
->before_chunk_trace
,
1392 events_request
->before_chunk_tracefile
,
1393 events_request
->event
,
1394 events_request
->event_by_id_channel
);
1396 guint nb_trace
= lttv_traceset_number(tsc
->ts
);
1397 g_assert((guint
)events_request
->trace
< nb_trace
&&
1398 events_request
->trace
> -1);
1399 LttvTraceContext
*tc
= tsc
->traces
[events_request
->trace
];
1401 lttv_hooks_call(events_request
->before_chunk_traceset
, tsc
);
1403 lttv_trace_context_add_hooks(tc
,
1404 events_request
->before_chunk_trace
,
1405 events_request
->before_chunk_tracefile
,
1406 events_request
->event
,
1407 events_request
->event_by_id_channel
);
1416 GSList
*remove_iter
= iter
;
1418 iter
= g_slist_next(iter
);
1419 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
1420 list_out
= g_slist_remove_link(list_out
, remove_iter
);
1421 } else { // not remove
1422 iter
= g_slist_next(iter
);
1428 /* 3. Find end criterions */
1433 /* 3.1.1 Find lowest end time in list_in */
1434 g_assert(g_slist_length(list_in
)>0);
1435 end_time
= ((EventsRequest
*)g_slist_nth_data(list_in
,0))->end_time
;
1437 for(iter
=g_slist_nth(list_in
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
1438 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1440 if(ltt_time_compare(events_request
->end_time
,
1442 end_time
= events_request
->end_time
;
1445 /* 3.1.2 Find lowest start time in list_out */
1446 for(iter
=list_out
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
1447 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1449 if(ltt_time_compare(events_request
->start_time
,
1451 end_time
= events_request
->start_time
;
1456 /* 3.2 Number of events */
1458 /* 3.2.1 Find lowest number of events in list_in */
1461 end_nb_events
= ((EventsRequest
*)g_slist_nth_data(list_in
,0))->num_events
;
1463 for(iter
=g_slist_nth(list_in
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
1464 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1466 if(events_request
->num_events
< end_nb_events
)
1467 end_nb_events
= events_request
->num_events
;
1470 /* 3.2.2 Use min(CHUNK_NUM_EVENTS, min num events in list_in) as
1473 end_nb_events
= MIN(CHUNK_NUM_EVENTS
, end_nb_events
);
1477 /* 3.3 End position */
1479 /* 3.3.1 Find lowest end position in list_in */
1482 end_position
=((EventsRequest
*)g_slist_nth_data(list_in
,0))->end_position
;
1484 for(iter
=g_slist_nth(list_in
,1);iter
!=NULL
;iter
=g_slist_next(iter
)) {
1485 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1487 if(events_request
->end_position
!= NULL
&& end_position
!= NULL
&&
1488 lttv_traceset_context_pos_pos_compare(events_request
->end_position
,
1490 end_position
= events_request
->end_position
;
1495 /* 3.3.2 Find lowest start position in list_out */
1498 for(iter
=list_out
;iter
!=NULL
;iter
=g_slist_next(iter
)) {
1499 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1501 if(events_request
->end_position
!= NULL
&& end_position
!= NULL
&&
1502 lttv_traceset_context_pos_pos_compare(events_request
->end_position
,
1504 end_position
= events_request
->end_position
;
1509 /* 4. Call process traceset middle */
1510 g_debug("Calling process traceset middle with %p, %lu sec %lu nsec, %u nb ev, %p end pos", tsc
, end_time
.tv_sec
, end_time
.tv_nsec
, end_nb_events
, end_position
);
1511 count
= lttv_process_traceset_middle(tsc
, end_time
, end_nb_events
, end_position
);
1513 tfc
= lttv_traceset_context_get_current_tfc(tsc
);
1515 g_debug("Context time after middle : %lu, %lu", tfc
->timestamp
.tv_sec
,
1516 tfc
->timestamp
.tv_nsec
);
1518 g_debug("End of trace reached after middle.");
1522 /* 5. After process traceset middle */
1523 tfc
= lttv_traceset_context_get_current_tfc(tsc
);
1525 /* - if current context time > traceset.end time */
1526 if(tfc
== NULL
|| ltt_time_compare(tfc
->timestamp
,
1527 tsc
->time_span
.end_time
) > 0) {
1528 /* - For each req in list_in */
1529 GSList
*iter
= list_in
;
1531 while(iter
!= NULL
) {
1533 gboolean remove
= FALSE
;
1534 gboolean free_data
= FALSE
;
1535 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1537 /* - Remove events hooks for req
1538 * - Call end chunk for req
1541 if(events_request
->trace
== -1)
1542 lttv_process_traceset_end(tsc
,
1543 events_request
->after_chunk_traceset
,
1544 events_request
->after_chunk_trace
,
1545 events_request
->after_chunk_tracefile
,
1546 events_request
->event
,
1547 events_request
->event_by_id_channel
);
1550 guint nb_trace
= lttv_traceset_number(tsc
->ts
);
1551 g_assert(events_request
->trace
< nb_trace
&&
1552 events_request
->trace
> -1);
1553 LttvTraceContext
*tc
= tsc
->traces
[events_request
->trace
];
1555 lttv_trace_context_remove_hooks(tc
,
1556 events_request
->after_chunk_trace
,
1557 events_request
->after_chunk_tracefile
,
1558 events_request
->event
,
1559 events_request
->event_by_id_channel
);
1560 lttv_hooks_call(events_request
->after_chunk_traceset
, tsc
);
1565 /* - Call end request for req */
1566 lttv_hooks_call(events_request
->after_request
, (gpointer
)tsc
);
1568 /* - remove req from list_in */
1569 /* Destroy the request */
1576 GSList
*remove_iter
= iter
;
1578 iter
= g_slist_next(iter
);
1579 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
1580 list_in
= g_slist_remove_link(list_in
, remove_iter
);
1581 } else { // not remove
1582 iter
= g_slist_next(iter
);
1587 /* 5.1 For each req in list_in */
1588 GSList
*iter
= list_in
;
1590 while(iter
!= NULL
) {
1592 gboolean remove
= FALSE
;
1593 gboolean free_data
= FALSE
;
1594 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1596 /* - Remove events hooks for req
1597 * - Call end chunk for req
1599 if(events_request
->trace
== -1)
1600 lttv_process_traceset_end(tsc
,
1601 events_request
->after_chunk_traceset
,
1602 events_request
->after_chunk_trace
,
1603 events_request
->after_chunk_tracefile
,
1604 events_request
->event
,
1605 events_request
->event_by_id_channel
);
1608 guint nb_trace
= lttv_traceset_number(tsc
->ts
);
1609 g_assert(events_request
->trace
< nb_trace
&&
1610 events_request
->trace
> -1);
1611 LttvTraceContext
*tc
= tsc
->traces
[events_request
->trace
];
1613 lttv_trace_context_remove_hooks(tc
,
1614 events_request
->after_chunk_trace
,
1615 events_request
->after_chunk_tracefile
,
1616 events_request
->event
,
1617 events_request
->event_by_id_channel
);
1619 lttv_hooks_call(events_request
->after_chunk_traceset
, tsc
);
1622 /* - req.num -= count */
1623 g_assert(events_request
->num_events
>= count
);
1624 events_request
->num_events
-= count
;
1626 g_assert(tfc
!= NULL
);
1627 /* - if req.num == 0
1629 * current context time >= req.end time
1631 * req.end pos == current pos
1633 * req.stop_flag == TRUE
1635 if( events_request
->num_events
== 0
1637 events_request
->stop_flag
== TRUE
1639 ltt_time_compare(tfc
->timestamp
,
1640 events_request
->end_time
) >= 0
1642 (events_request
->end_position
!= NULL
1644 lttv_traceset_context_ctx_pos_compare(tsc
,
1645 events_request
->end_position
) == 0)
1648 g_assert(events_request
->servicing
== TRUE
);
1649 /* - Call end request for req
1650 * - remove req from list_in */
1651 lttv_hooks_call(events_request
->after_request
, (gpointer
)tsc
);
1652 /* - remove req from list_in */
1653 /* Destroy the request */
1661 GSList
*remove_iter
= iter
;
1663 iter
= g_slist_next(iter
);
1664 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
1665 list_in
= g_slist_remove_link(list_in
, remove_iter
);
1666 } else { // not remove
1667 iter
= g_slist_next(iter
);
1673 /* End of removed servicing loop : leave control to GTK instead. */
1674 // if(gtk_events_pending()) break;
1677 /* B. When interrupted between chunks */
1680 GSList
*iter
= list_in
;
1682 /* 1. for each request in list_in */
1683 while(iter
!= NULL
) {
1685 gboolean remove
= FALSE
;
1686 gboolean free_data
= FALSE
;
1687 EventsRequest
*events_request
= (EventsRequest
*)iter
->data
;
1689 /* 1.1. Use current postition as start position */
1690 if(events_request
->start_position
!= NULL
)
1691 lttv_traceset_context_position_destroy(events_request
->start_position
);
1692 events_request
->start_position
= lttv_traceset_context_position_new(tsc
);
1693 lttv_traceset_context_position_save(tsc
, events_request
->start_position
);
1695 /* 1.2. Remove start time */
1696 events_request
->start_time
= ltt_time_infinite
;
1698 /* 1.3. Move from list_in to list_out */
1701 list_out
= g_slist_append(list_out
, events_request
);
1706 GSList
*remove_iter
= iter
;
1708 iter
= g_slist_next(iter
);
1709 if(free_data
) events_request_free((EventsRequest
*)remove_iter
->data
);
1710 list_in
= g_slist_remove_link(list_in
, remove_iter
);
1711 } else { // not remove
1712 iter
= g_slist_next(iter
);
1718 /* C Unlock Traces */
1720 lttv_process_traceset_get_sync_data(tsc
);
1721 //lttv_traceset_context_position_save(tsc, sync_position);
1726 iter_trace
<lttv_traceset_number(tsc
->ts
);
1728 LttvTrace
*trace_v
= lttv_traceset_get(tsc
->ts
, iter_trace
);
1730 lttvwindowtraces_unlock(trace_v
);
1734 //set the cursor back to normal
1735 gdk_window_set_cursor(win
, NULL
);
1738 g_assert(g_slist_length(list_in
) == 0);
1740 if( g_slist_length(list_out
) == 0 ) {
1741 /* Put tab's request pending flag back to normal */
1742 tab
->events_request_pending
= FALSE
;
1743 g_debug("remove the idle fct");
1744 return FALSE
; /* Remove the idle function */
1746 g_debug("leave the idle fct");
1747 return TRUE
; /* Leave the idle function */
1749 /* We do not use simili-round-robin, it may require to read 1 meg buffers
1750 * again and again if many tracesets use the same tracefiles. */
1751 /* Hack for round-robin idle functions */
1752 /* It will put the idle function at the end of the pool */
1753 /*g_idle_add_full((G_PRIORITY_HIGH_IDLE + 21),
1754 (GSourceFunc)execute_events_requests,
1764 static void lttvwindow_add_trace(Tab
*tab
, LttvTrace
*trace_v
)
1766 LttvTraceset
*traceset
= tab
->traceset_info
->traceset
;
1768 guint num_traces
= lttv_traceset_number(traceset
);
1770 //Verify if trace is already present.
1771 for(i
=0; i
<num_traces
; i
++)
1773 LttvTrace
* trace
= lttv_traceset_get(traceset
, i
);
1774 if(trace
== trace_v
)
1778 //Keep a reference to the traces so they are not freed.
1779 for(i
=0; i
<lttv_traceset_number(traceset
); i
++)
1781 LttvTrace
* trace
= lttv_traceset_get(traceset
, i
);
1782 lttv_trace_ref(trace
);
1785 //remove state update hooks
1786 lttv_state_remove_event_hooks(
1787 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1789 lttv_context_fini(LTTV_TRACESET_CONTEXT(
1790 tab
->traceset_info
->traceset_context
));
1791 g_object_unref(tab
->traceset_info
->traceset_context
);
1793 lttv_traceset_add(traceset
, trace_v
);
1794 lttv_trace_ref(trace_v
); /* local ref */
1796 /* Create new context */
1797 tab
->traceset_info
->traceset_context
=
1798 g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
1800 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->
1805 //add state update hooks
1806 lttv_state_add_event_hooks(
1807 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1808 //Remove local reference to the traces.
1809 for(i
=0; i
<lttv_traceset_number(traceset
); i
++)
1811 LttvTrace
* trace
= lttv_traceset_get(traceset
, i
);
1812 lttv_trace_unref(trace
);
1816 //add_trace_into_traceset_selector(GTK_MULTIVPANED(tab->multivpaned), lttv_trace(trace_v));
1819 /* add_trace adds a trace into the current traceset. It first displays a
1820 * directory selection dialogue to let user choose a trace, then recreates
1821 * tracset_context, and redraws all the viewer of the current tab
1824 void add_trace(GtkWidget
* widget
, gpointer user_data
)
1827 LttvTrace
* trace_v
;
1828 LttvTraceset
* traceset
;
1830 char abs_path
[PATH_MAX
];
1832 MainWindow
* mw_data
= get_window_data_struct(widget
);
1833 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
1835 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
1836 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
1837 LttvPluginTab
*ptab
;
1841 ptab
= create_new_tab(widget
, NULL
);
1844 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
1848 //GtkDirSelection * file_selector = (GtkDirSelection *)gtk_dir_selection_new("Select a trace");
1849 GtkFileSelection
* file_selector
= (GtkFileSelection
*)gtk_file_selection_new("Select a trace");
1850 gtk_widget_hide( (file_selector
)->file_list
->parent
) ;
1851 gtk_file_selection_hide_fileop_buttons(file_selector
);
1852 gtk_window_set_transient_for(GTK_WINDOW(file_selector
),
1853 GTK_WINDOW(mw_data
->mwindow
));
1855 if(remember_trace_dir
[0] != '\0')
1856 gtk_file_selection_set_filename(file_selector
, remember_trace_dir
);
1858 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
1860 case GTK_RESPONSE_ACCEPT
:
1861 case GTK_RESPONSE_OK
:
1862 dir
= gtk_file_selection_get_filename (file_selector
);
1863 strncpy(remember_trace_dir
, dir
, PATH_MAX
);
1864 strncat(remember_trace_dir
, "/", PATH_MAX
);
1865 if(!dir
|| strlen(dir
) == 0){
1866 gtk_widget_destroy((GtkWidget
*)file_selector
);
1869 get_absolute_pathname(dir
, abs_path
);
1870 trace_v
= lttvwindowtraces_get_trace_by_name(abs_path
);
1871 if(trace_v
== NULL
) {
1872 trace
= ltt_trace_open(abs_path
);
1874 g_warning("cannot open trace %s", abs_path
);
1876 GtkWidget
*dialogue
=
1877 gtk_message_dialog_new(
1878 GTK_WINDOW(gtk_widget_get_toplevel(widget
)),
1879 GTK_DIALOG_MODAL
|GTK_DIALOG_DESTROY_WITH_PARENT
,
1882 "Cannot open trace : maybe you should enter in the trace "
1883 "directory to select it ?");
1884 gtk_dialog_run(GTK_DIALOG(dialogue
));
1885 gtk_widget_destroy(dialogue
);
1888 trace_v
= lttv_trace_new(trace
);
1889 lttvwindowtraces_add_trace(trace_v
);
1890 lttvwindow_add_trace(tab
, trace_v
);
1893 lttvwindow_add_trace(tab
, trace_v
);
1896 gtk_widget_destroy((GtkWidget
*)file_selector
);
1898 //update current tab
1899 //update_traceset(mw_data);
1901 /* Call the updatetraceset hooks */
1903 traceset
= tab
->traceset_info
->traceset
;
1904 SetTraceset(tab
, traceset
);
1905 // in expose now call_pending_read_hooks(mw_data);
1907 //lttvwindow_report_current_time(mw_data,&(tab->current_time));
1909 case GTK_RESPONSE_REJECT
:
1910 case GTK_RESPONSE_CANCEL
:
1912 gtk_widget_destroy((GtkWidget
*)file_selector
);
1917 /* remove_trace removes a trace from the current traceset if all viewers in
1918 * the current tab are not interested in the trace. It first displays a
1919 * dialogue, which shows all traces in the current traceset, to let user choose
1920 * a trace, then it checks if all viewers unselect the trace, if it is true,
1921 * it will remove the trace, recreate the traceset_contex,
1922 * and redraws all the viewer of the current tab. If there is on trace in the
1923 * current traceset, it will delete all viewers of the current tab
1925 * It destroys the filter tree. FIXME... we should request for an update
1929 void remove_trace(GtkWidget
*widget
, gpointer user_data
)
1932 LttvTrace
* trace_v
;
1933 LttvTraceset
* traceset
;
1934 gint i
, j
, nb_trace
, index
=-1;
1935 char ** name
, *remove_trace_name
;
1936 MainWindow
* mw_data
= get_window_data_struct(widget
);
1937 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
1939 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
1940 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
1946 LttvPluginTab
*ptab
;
1947 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
1951 nb_trace
=lttv_traceset_number(tab
->traceset_info
->traceset
);
1952 name
= g_new(char*,nb_trace
);
1953 for(i
= 0; i
< nb_trace
; i
++){
1954 trace_v
= lttv_traceset_get(tab
->traceset_info
->traceset
, i
);
1955 trace
= lttv_trace(trace_v
);
1956 name
[i
] = g_quark_to_string(ltt_trace_name(trace
));
1959 remove_trace_name
= get_remove_trace(mw_data
, name
, nb_trace
);
1962 if(remove_trace_name
){
1964 /* yuk, cut n paste from old code.. should be better (MD)*/
1965 for(i
= 0; i
<nb_trace
; i
++) {
1966 if(strcmp(remove_trace_name
,name
[i
]) == 0){
1971 traceset
= tab
->traceset_info
->traceset
;
1972 //Keep a reference to the traces so they are not freed.
1973 for(j
=0; j
<lttv_traceset_number(traceset
); j
++)
1975 LttvTrace
* trace
= lttv_traceset_get(traceset
, j
);
1976 lttv_trace_ref(trace
);
1979 //remove state update hooks
1980 lttv_state_remove_event_hooks(
1981 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
1982 lttv_context_fini(LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
));
1983 g_object_unref(tab
->traceset_info
->traceset_context
);
1985 trace_v
= lttv_traceset_get(traceset
, index
);
1987 lttv_traceset_remove(traceset
, index
);
1988 lttv_trace_unref(trace_v
); // Remove local reference
1990 if(lttv_trace_get_ref_number(trace_v
) <= 1) {
1991 /* ref 1 : lttvwindowtraces only*/
1992 ltt_trace_close(lttv_trace(trace_v
));
1993 /* lttvwindowtraces_remove_trace takes care of destroying
1994 * the traceset linked with the trace_v and also of destroying
1995 * the trace_v at the same time.
1997 lttvwindowtraces_remove_trace(trace_v
);
2000 tab
->traceset_info
->traceset_context
=
2001 g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
2003 LTTV_TRACESET_CONTEXT(tab
->
2004 traceset_info
->traceset_context
),traceset
);
2005 //add state update hooks
2006 lttv_state_add_event_hooks(
2007 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
2009 //Remove local reference to the traces.
2010 for(j
=0; j
<lttv_traceset_number(traceset
); j
++)
2012 LttvTrace
* trace
= lttv_traceset_get(traceset
, j
);
2013 lttv_trace_unref(trace
);
2016 SetTraceset(tab
, (gpointer
)traceset
);
2022 void remove_trace(GtkWidget
* widget
, gpointer user_data
)
2025 LttvTrace
* trace_v
;
2026 LttvTraceset
* traceset
;
2027 gint i
, j
, nb_trace
;
2028 char ** name
, *remove_trace_name
;
2029 MainWindow
* mw_data
= get_window_data_struct(widget
);
2030 LttvTracesetSelector
* s
;
2031 LttvTraceSelector
* t
;
2034 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
2036 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2037 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2043 tab
= (Tab
*)g_object_get_data(G_OBJECT(page
), "Tab_Info");
2046 nb_trace
=lttv_traceset_number(tab
->traceset_info
->traceset
);
2047 name
= g_new(char*,nb_trace
);
2048 for(i
= 0; i
< nb_trace
; i
++){
2049 trace_v
= lttv_traceset_get(tab
->traceset_info
->traceset
, i
);
2050 trace
= lttv_trace(trace_v
);
2051 name
[i
] = ltt_trace_name(trace
);
2054 remove_trace_name
= get_remove_trace(name
, nb_trace
);
2056 if(remove_trace_name
){
2057 for(i
=0; i
<nb_trace
; i
++){
2058 if(strcmp(remove_trace_name
,name
[i
]) == 0){
2059 //unselect the trace from the current viewer
2061 w
= gtk_multivpaned_get_widget(GTK_MULTIVPANED(tab
->multivpaned
));
2063 s
= g_object_get_data(G_OBJECT(w
), "Traceset_Selector");
2065 t
= lttv_traceset_selector_trace_get(s
,i
);
2066 lttv_trace_selector_set_selected(t
, FALSE
);
2069 //check if other viewers select the trace
2070 w
= gtk_multivpaned_get_first_widget(GTK_MULTIVPANED(tab
->multivpaned
));
2072 s
= g_object_get_data(G_OBJECT(w
), "Traceset_Selector");
2074 t
= lttv_traceset_selector_trace_get(s
,i
);
2075 selected
= lttv_trace_selector_get_selected(t
);
2078 w
= gtk_multivpaned_get_next_widget(GTK_MULTIVPANED(tab
->multivpaned
));
2080 }else selected
= FALSE
;
2082 //if no viewer selects the trace, remove it
2084 remove_trace_from_traceset_selector(GTK_MULTIVPANED(tab
->multivpaned
), i
);
2086 traceset
= tab
->traceset_info
->traceset
;
2087 //Keep a reference to the traces so they are not freed.
2088 for(j
=0; j
<lttv_traceset_number(traceset
); j
++)
2090 LttvTrace
* trace
= lttv_traceset_get(traceset
, j
);
2091 lttv_trace_ref(trace
);
2094 //remove state update hooks
2095 lttv_state_remove_event_hooks(
2096 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
2097 lttv_context_fini(LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
));
2098 g_object_unref(tab
->traceset_info
->traceset_context
);
2101 trace_v
= lttv_traceset_get(traceset
, i
);
2103 if(lttv_trace_get_ref_number(trace_v
) <= 2) {
2104 /* ref 2 : traceset, local */
2105 lttvwindowtraces_remove_trace(trace_v
);
2106 ltt_trace_close(lttv_trace(trace_v
));
2109 lttv_traceset_remove(traceset
, i
);
2110 lttv_trace_unref(trace_v
); // Remove local reference
2112 if(!lttv_trace_get_ref_number(trace_v
))
2113 lttv_trace_destroy(trace_v
);
2115 tab
->traceset_info
->traceset_context
=
2116 g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
2118 LTTV_TRACESET_CONTEXT(tab
->
2119 traceset_info
->traceset_context
),traceset
);
2120 //add state update hooks
2121 lttv_state_add_event_hooks(
2122 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
2124 //Remove local reference to the traces.
2125 for(j
=0; j
<lttv_traceset_number(traceset
); j
++)
2127 LttvTrace
* trace
= lttv_traceset_get(traceset
, j
);
2128 lttv_trace_unref(trace
);
2132 //update current tab
2133 //update_traceset(mw_data);
2136 SetTraceset(tab
, (gpointer
)traceset
);
2137 // in expose now call_pending_read_hooks(mw_data);
2139 //lttvwindow_report_current_time(mw_data,&(tab->current_time));
2142 // while(tab->multi_vpaned->num_children){
2143 // gtk_multi_vpaned_widget_delete(tab->multi_vpaned);
2157 /* Redraw all the viewers in the current tab */
2158 void redraw(GtkWidget
*widget
, gpointer user_data
)
2160 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
2161 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2162 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2169 LttvPluginTab
*ptab
;
2170 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
2175 LttvAttributeValue value
;
2177 retval
= lttv_iattribute_find_by_path(tab
->attributes
, "hooks/redraw", LTTV_POINTER
, &value
);
2180 tmp
= (LttvHooks
*)*(value
.v_pointer
);
2182 lttv_hooks_call(tmp
,NULL
);
2186 void continue_processing(GtkWidget
*widget
, gpointer user_data
)
2188 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
2189 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2190 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2197 LttvPluginTab
*ptab
;
2198 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
2203 LttvAttributeValue value
;
2205 retval
= lttv_iattribute_find_by_path(tab
->attributes
, "hooks/continue",
2206 LTTV_POINTER
, &value
);
2209 tmp
= (LttvHooks
*)*(value
.v_pointer
);
2211 lttv_hooks_call(tmp
,NULL
);
2214 /* Stop the processing for the calling main window's current tab.
2215 * It removes every processing requests that are in its list. It does not call
2216 * the end request hooks, because the request is not finished.
2219 void stop_processing(GtkWidget
*widget
, gpointer user_data
)
2221 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
2222 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2223 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2228 LttvPluginTab
*ptab
;
2229 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
2232 GSList
*iter
= tab
->events_requests
;
2234 while(iter
!= NULL
) {
2235 GSList
*remove_iter
= iter
;
2236 iter
= g_slist_next(iter
);
2238 g_free(remove_iter
->data
);
2239 tab
->events_requests
=
2240 g_slist_remove_link(tab
->events_requests
, remove_iter
);
2242 tab
->events_request_pending
= FALSE
;
2243 tab
->stop_foreground
= TRUE
;
2244 g_idle_remove_by_data(tab
);
2245 g_assert(g_slist_length(tab
->events_requests
) == 0);
2249 /* save will save the traceset to a file
2250 * Not implemented yet FIXME
2253 void save(GtkWidget
* widget
, gpointer user_data
)
2258 void save_as(GtkWidget
* widget
, gpointer user_data
)
2260 g_info("Save as\n");
2264 /* zoom will change the time_window of all the viewers of the
2265 * current tab, and redisplay them. The main functionality is to
2266 * determine the new time_window of the current tab
2269 void zoom(GtkWidget
* widget
, double size
)
2271 TimeInterval time_span
;
2272 TimeWindow new_time_window
;
2273 LttTime current_time
, time_delta
;
2274 MainWindow
* mw_data
= get_window_data_struct(widget
);
2275 LttvTracesetContext
*tsc
;
2276 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
2278 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2279 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2285 LttvPluginTab
*ptab
;
2286 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
2290 if(size
== 1) return;
2292 tsc
= LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
2293 time_span
= tsc
->time_span
;
2294 new_time_window
= tab
->time_window
;
2295 current_time
= tab
->current_time
;
2297 time_delta
= ltt_time_sub(time_span
.end_time
,time_span
.start_time
);
2299 new_time_window
.start_time
= time_span
.start_time
;
2300 new_time_window
.time_width
= time_delta
;
2301 new_time_window
.time_width_double
= ltt_time_to_double(time_delta
);
2302 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
2303 new_time_window
.time_width
) ;
2305 new_time_window
.time_width
= ltt_time_div(new_time_window
.time_width
, size
);
2306 new_time_window
.time_width_double
=
2307 ltt_time_to_double(new_time_window
.time_width
);
2308 if(ltt_time_compare(new_time_window
.time_width
,time_delta
) > 0)
2309 { /* Case where zoom out is bigger than trace length */
2310 new_time_window
.start_time
= time_span
.start_time
;
2311 new_time_window
.time_width
= time_delta
;
2312 new_time_window
.time_width_double
= ltt_time_to_double(time_delta
);
2313 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
2314 new_time_window
.time_width
) ;
2318 /* Center the image on the current time */
2319 new_time_window
.start_time
=
2320 ltt_time_sub(current_time
,
2321 ltt_time_from_double(new_time_window
.time_width_double
/2.0));
2322 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
2323 new_time_window
.time_width
) ;
2324 /* If on borders, don't fall off */
2325 if(ltt_time_compare(new_time_window
.start_time
, time_span
.start_time
) <0
2326 || ltt_time_compare(new_time_window
.start_time
, time_span
.end_time
) >0)
2328 new_time_window
.start_time
= time_span
.start_time
;
2329 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
2330 new_time_window
.time_width
) ;
2334 if(ltt_time_compare(new_time_window
.end_time
,
2335 time_span
.end_time
) > 0
2336 || ltt_time_compare(new_time_window
.end_time
,
2337 time_span
.start_time
) < 0)
2339 new_time_window
.start_time
=
2340 ltt_time_sub(time_span
.end_time
, new_time_window
.time_width
);
2342 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
2343 new_time_window
.time_width
) ;
2350 if(ltt_time_compare(new_time_window
.time_width
, ltt_time_zero
) == 0) {
2351 g_warning("Zoom more than 1 ns impossible");
2353 time_change_manager(tab
, new_time_window
);
2357 void zoom_in(GtkWidget
* widget
, gpointer user_data
)
2362 void zoom_out(GtkWidget
* widget
, gpointer user_data
)
2367 void zoom_extended(GtkWidget
* widget
, gpointer user_data
)
2372 void go_to_time(GtkWidget
* widget
, gpointer user_data
)
2374 g_info("Go to time\n");
2377 void show_time_frame(GtkWidget
* widget
, gpointer user_data
)
2379 g_info("Show time frame\n");
2383 /* callback function */
2386 on_empty_traceset_activate (GtkMenuItem
*menuitem
,
2389 create_new_window((GtkWidget
*)menuitem
, user_data
, FALSE
);
2394 on_clone_traceset_activate (GtkMenuItem
*menuitem
,
2397 create_new_window((GtkWidget
*)menuitem
, user_data
, TRUE
);
2401 /* create_new_tab calls create_tab to construct a new tab in the main window
2404 LttvPluginTab
*create_new_tab(GtkWidget
* widget
, gpointer user_data
)
2406 gchar label
[PATH_MAX
];
2407 MainWindow
* mw_data
= get_window_data_struct(widget
);
2409 GtkNotebook
* notebook
= (GtkNotebook
*)lookup_widget(widget
, "MNotebook");
2410 if(notebook
== NULL
){
2411 g_info("Notebook does not exist\n");
2414 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
2415 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
2421 LttvPluginTab
*ptab
;
2422 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
2423 copy_tab
= ptab
->tab
;
2426 strcpy(label
,"Page");
2427 if(get_label(mw_data
, label
,"Get the name of the tab","Please input tab's name")) {
2428 LttvPluginTab
*ptab
;
2430 ptab
= g_object_new(LTTV_TYPE_PLUGIN_TAB
, NULL
);
2431 init_tab (ptab
->tab
, mw_data
, copy_tab
, notebook
, label
);
2432 ptab
->parent
.top_widget
= ptab
->tab
->top_widget
;
2433 g_object_set_data_full(
2434 G_OBJECT(ptab
->tab
->vbox
),
2437 (GDestroyNotify
)tab_destructor
);
2444 on_tab_activate (GtkMenuItem
*menuitem
,
2447 create_new_tab((GtkWidget
*)menuitem
, user_data
);
2452 on_open_activate (GtkMenuItem
*menuitem
,
2455 open_traceset((GtkWidget
*)menuitem
, user_data
);
2460 on_close_activate (GtkMenuItem
*menuitem
,
2463 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2464 main_window_destructor(mw_data
);
2468 /* remove the current tab from the main window
2472 on_close_tab_activate (GtkWidget
*widget
,
2476 GtkWidget
* notebook
;
2478 MainWindow
* mw_data
= get_window_data_struct(widget
);
2479 notebook
= lookup_widget(widget
, "MNotebook");
2480 if(notebook
== NULL
){
2481 g_info("Notebook does not exist\n");
2485 page_num
= gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
));
2487 gtk_notebook_remove_page(GTK_NOTEBOOK(notebook
), page_num
);
2492 on_close_tab_X_clicked (GtkWidget
*widget
,
2496 GtkWidget
*notebook
= lookup_widget(widget
, "MNotebook");
2497 if(notebook
== NULL
){
2498 g_info("Notebook does not exist\n");
2502 if((page_num
= gtk_notebook_page_num(GTK_NOTEBOOK(notebook
), widget
)) != -1)
2503 gtk_notebook_remove_page(GTK_NOTEBOOK(notebook
), page_num
);
2509 on_add_trace_activate (GtkMenuItem
*menuitem
,
2512 add_trace((GtkWidget
*)menuitem
, user_data
);
2517 on_remove_trace_activate (GtkMenuItem
*menuitem
,
2520 remove_trace((GtkWidget
*)menuitem
, user_data
);
2525 on_save_activate (GtkMenuItem
*menuitem
,
2528 save((GtkWidget
*)menuitem
, user_data
);
2533 on_save_as_activate (GtkMenuItem
*menuitem
,
2536 save_as((GtkWidget
*)menuitem
, user_data
);
2541 on_quit_activate (GtkMenuItem
*menuitem
,
2544 while (g_slist_length(g_main_window_list
) != 0) {
2545 on_MWindow_destroy(((MainWindow
*)g_main_window_list
->data
)->mwindow
,
2552 on_cut_activate (GtkMenuItem
*menuitem
,
2560 on_copy_activate (GtkMenuItem
*menuitem
,
2568 on_paste_activate (GtkMenuItem
*menuitem
,
2576 on_delete_activate (GtkMenuItem
*menuitem
,
2584 on_zoom_in_activate (GtkMenuItem
*menuitem
,
2587 zoom_in((GtkWidget
*)menuitem
, user_data
);
2592 on_zoom_out_activate (GtkMenuItem
*menuitem
,
2595 zoom_out((GtkWidget
*)menuitem
, user_data
);
2600 on_zoom_extended_activate (GtkMenuItem
*menuitem
,
2603 zoom_extended((GtkWidget
*)menuitem
, user_data
);
2608 on_go_to_time_activate (GtkMenuItem
*menuitem
,
2611 go_to_time((GtkWidget
*)menuitem
, user_data
);
2616 on_show_time_frame_activate (GtkMenuItem
*menuitem
,
2619 show_time_frame((GtkWidget
*)menuitem
, user_data
);
2624 on_move_viewer_up_activate (GtkMenuItem
*menuitem
,
2627 move_up_viewer((GtkWidget
*)menuitem
, user_data
);
2632 on_move_viewer_down_activate (GtkMenuItem
*menuitem
,
2635 move_down_viewer((GtkWidget
*)menuitem
, user_data
);
2640 on_remove_viewer_activate (GtkMenuItem
*menuitem
,
2643 delete_viewer((GtkWidget
*)menuitem
, user_data
);
2647 on_trace_facility_activate (GtkMenuItem
*menuitem
,
2650 g_info("Trace facility selector: %s\n", "");
2654 /* Dispaly a file selection dialogue to let user select a library, then call
2655 * lttv_library_load().
2659 on_load_library_activate (GtkMenuItem
*menuitem
,
2662 GError
*error
= NULL
;
2663 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2665 gchar load_module_path_alter
[PATH_MAX
];
2669 gchar
*load_module_path
;
2670 name
= g_ptr_array_new();
2671 nb
= lttv_library_path_number();
2672 /* ask for the library path */
2676 path
= lttv_library_path_get(i
);
2677 g_ptr_array_add(name
, path
);
2680 load_module_path
= get_selection(mw_data
,
2681 (char **)(name
->pdata
), name
->len
,
2682 "Select a library path", "Library paths");
2683 if(load_module_path
!= NULL
)
2684 strncpy(load_module_path_alter
, load_module_path
, PATH_MAX
-1); // -1 for /
2686 g_ptr_array_free(name
, TRUE
);
2688 if(load_module_path
== NULL
) return;
2692 /* Make sure the module path ends with a / */
2693 gchar
*ptr
= load_module_path_alter
;
2695 ptr
= strchr(ptr
, '\0');
2697 if(*(ptr
-1) != '/') {
2704 /* Ask for the library to load : list files in the previously selected
2706 gchar str
[PATH_MAX
];
2709 GtkFileSelection
* file_selector
=
2710 (GtkFileSelection
*)gtk_file_selection_new("Select a module");
2711 gtk_file_selection_set_filename(file_selector
, load_module_path_alter
);
2712 gtk_file_selection_hide_fileop_buttons(file_selector
);
2714 gtk_window_set_transient_for(GTK_WINDOW(file_selector
),
2715 GTK_WINDOW(mw_data
->mwindow
));
2718 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
2720 case GTK_RESPONSE_ACCEPT
:
2721 case GTK_RESPONSE_OK
:
2722 dir
= gtk_file_selection_get_selections (file_selector
);
2723 strncpy(str
,dir
[0],PATH_MAX
);
2724 strncpy(remember_plugins_dir
,dir
[0],PATH_MAX
);
2725 /* only keep file name */
2727 str1
= strrchr(str
,'/');
2730 str1
= strrchr(str
,'\\');
2735 if(*str1
== 'l' && *(str1
+1)== 'i' && *(str1
+2)=='b')
2737 remove info after
. */
2741 str2
= strrchr(str2
, '.');
2742 if(str2
!= NULL
) *str2
= '\0';
2744 lttv_module_require(str1
, &error
);
2746 lttv_library_load(str1
, &error
);
2747 if(error
!= NULL
) g_warning("%s", error
->message
);
2748 else g_info("Load library: %s\n", str
);
2750 case GTK_RESPONSE_REJECT
:
2751 case GTK_RESPONSE_CANCEL
:
2753 gtk_widget_destroy((GtkWidget
*)file_selector
);
2764 /* Display all loaded modules, let user to select a module to unload
2765 * by calling lttv_module_unload
2769 on_unload_library_activate (GtkMenuItem
*menuitem
,
2772 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2774 LttvLibrary
*library
= NULL
;
2779 name
= g_ptr_array_new();
2780 nb
= lttv_library_number();
2781 LttvLibraryInfo
*lib_info
= g_new(LttvLibraryInfo
,nb
);
2782 /* ask for the library name */
2785 LttvLibrary
*iter_lib
= lttv_library_get(i
);
2786 lttv_library_info(iter_lib
, &lib_info
[i
]);
2788 gchar
*path
= lib_info
[i
].name
;
2789 g_ptr_array_add(name
, path
);
2791 lib_name
= get_selection(mw_data
, (char **)(name
->pdata
), name
->len
,
2792 "Select a library", "Libraries");
2793 if(lib_name
!= NULL
) {
2795 if(strcmp(lib_name
, lib_info
[i
].name
) == 0) {
2796 library
= lttv_library_get(i
);
2801 g_ptr_array_free(name
, TRUE
);
2804 if(lib_name
== NULL
) return;
2806 if(library
!= NULL
) lttv_library_unload(library
);
2810 /* Dispaly a file selection dialogue to let user select a module, then call
2811 * lttv_module_require().
2815 on_load_module_activate (GtkMenuItem
*menuitem
,
2818 GError
*error
= NULL
;
2819 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2821 LttvLibrary
*library
= NULL
;
2826 name
= g_ptr_array_new();
2827 nb
= lttv_library_number();
2828 LttvLibraryInfo
*lib_info
= g_new(LttvLibraryInfo
,nb
);
2829 /* ask for the library name */
2832 LttvLibrary
*iter_lib
= lttv_library_get(i
);
2833 lttv_library_info(iter_lib
, &lib_info
[i
]);
2835 gchar
*path
= lib_info
[i
].name
;
2836 g_ptr_array_add(name
, path
);
2838 lib_name
= get_selection(mw_data
,(char **)(name
->pdata
), name
->len
,
2839 "Select a library", "Libraries");
2840 if(lib_name
!= NULL
) {
2842 if(strcmp(lib_name
, lib_info
[i
].name
) == 0) {
2843 library
= lttv_library_get(i
);
2848 g_ptr_array_free(name
, TRUE
);
2851 if(lib_name
== NULL
) return;
2854 //LttvModule *module;
2855 gchar module_name_out
[PATH_MAX
];
2857 /* Ask for the module to load : list modules in the selected lib */
2861 nb
= lttv_library_module_number(library
);
2862 LttvModuleInfo
*module_info
= g_new(LttvModuleInfo
,nb
);
2863 name
= g_ptr_array_new();
2864 /* ask for the module name */
2867 LttvModule
*iter_module
= lttv_library_module_get(library
, i
);
2868 lttv_module_info(iter_module
, &module_info
[i
]);
2870 gchar
*path
= module_info
[i
].name
;
2871 g_ptr_array_add(name
, path
);
2873 module_name
= get_selection(mw_data
, (char **)(name
->pdata
), name
->len
,
2874 "Select a module", "Modules");
2875 if(module_name
!= NULL
) {
2877 if(strcmp(module_name
, module_info
[i
].name
) == 0) {
2878 strncpy(module_name_out
, module_name
, PATH_MAX
);
2879 //module = lttv_library_module_get(i);
2885 g_ptr_array_free(name
, TRUE
);
2886 g_free(module_info
);
2888 if(module_name
== NULL
) return;
2891 lttv_module_require(module_name_out
, &error
);
2892 if(error
!= NULL
) g_warning("%s", error
->message
);
2893 else g_info("Load module: %s", module_name_out
);
2900 gchar str
[PATH_MAX
];
2903 GtkFileSelection
* file_selector
=
2904 (GtkFileSelection
*)gtk_file_selection_new("Select a module");
2905 gtk_file_selection_set_filename(file_selector
, load_module_path_alter
);
2906 gtk_file_selection_hide_fileop_buttons(file_selector
);
2909 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
2911 case GTK_RESPONSE_ACCEPT
:
2912 case GTK_RESPONSE_OK
:
2913 dir
= gtk_file_selection_get_selections (file_selector
);
2914 strncpy(str
,dir
[0],PATH_MAX
);
2915 strncpy(remember_plugins_dir
,dir
[0],PATH_MAX
);
2917 /* only keep file name */
2919 str1
= strrchr(str
,'/');
2922 str1
= strrchr(str
,'\\');
2927 if(*str1
== 'l' && *(str1
+1)== 'i' && *(str1
+2)=='b')
2929 remove info after
. */
2933 str2
= strrchr(str2
, '.');
2934 if(str2
!= NULL
) *str2
= '\0';
2936 lttv_module_require(str1
, &error
);
2938 lttv_library_load(str1
, &error
);
2939 if(error
!= NULL
) g_warning(error
->message
);
2940 else g_info("Load library: %s\n", str
);
2942 case GTK_RESPONSE_REJECT
:
2943 case GTK_RESPONSE_CANCEL
:
2945 gtk_widget_destroy((GtkWidget
*)file_selector
);
2957 /* Display all loaded modules, let user to select a module to unload
2958 * by calling lttv_module_unload
2962 on_unload_module_activate (GtkMenuItem
*menuitem
,
2965 GError
*error
= NULL
;
2966 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
2968 LttvLibrary
*library
= NULL
;
2973 name
= g_ptr_array_new();
2974 nb
= lttv_library_number();
2975 LttvLibraryInfo
*lib_info
= g_new(LttvLibraryInfo
,nb
);
2976 /* ask for the library name */
2979 LttvLibrary
*iter_lib
= lttv_library_get(i
);
2980 lttv_library_info(iter_lib
, &lib_info
[i
]);
2982 gchar
*path
= lib_info
[i
].name
;
2983 g_ptr_array_add(name
, path
);
2985 lib_name
= get_selection(mw_data
, (char **)(name
->pdata
), name
->len
,
2986 "Select a library", "Libraries");
2987 if(lib_name
!= NULL
) {
2989 if(strcmp(lib_name
, lib_info
[i
].name
) == 0) {
2990 library
= lttv_library_get(i
);
2995 g_ptr_array_free(name
, TRUE
);
2998 if(lib_name
== NULL
) return;
3001 LttvModule
*module
= NULL
;
3003 /* Ask for the module to load : list modules in the selected lib */
3007 nb
= lttv_library_module_number(library
);
3008 LttvModuleInfo
*module_info
= g_new(LttvModuleInfo
,nb
);
3009 name
= g_ptr_array_new();
3010 /* ask for the module name */
3013 LttvModule
*iter_module
= lttv_library_module_get(library
, i
);
3014 lttv_module_info(iter_module
, &module_info
[i
]);
3016 gchar
*path
= module_info
[i
].name
;
3017 if(module_info
[i
].use_count
> 0) g_ptr_array_add(name
, path
);
3019 module_name
= get_selection(mw_data
, (char **)(name
->pdata
), name
->len
,
3020 "Select a module", "Modules");
3021 if(module_name
!= NULL
) {
3023 if(strcmp(module_name
, module_info
[i
].name
) == 0) {
3024 module
= lttv_library_module_get(library
, i
);
3030 g_ptr_array_free(name
, TRUE
);
3031 g_free(module_info
);
3033 if(module_name
== NULL
) return;
3036 LttvModuleInfo module_info
;
3037 lttv_module_info(module
, &module_info
);
3038 g_info("Release module: %s\n", module_info
.name
);
3040 lttv_module_release(module
);
3044 /* Display a directory dialogue to let user select a path for library searching
3048 on_add_library_search_path_activate (GtkMenuItem
*menuitem
,
3051 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
3052 //GtkDirSelection * file_selector = (GtkDirSelection *)gtk_dir_selection_new("Select library path");
3053 GtkFileSelection
* file_selector
= (GtkFileSelection
*)gtk_file_selection_new("Select a trace");
3054 gtk_widget_hide( (file_selector
)->file_list
->parent
) ;
3056 gtk_window_set_transient_for(GTK_WINDOW(file_selector
),
3057 GTK_WINDOW(mw_data
->mwindow
));
3062 if(remember_plugins_dir
[0] != '\0')
3063 gtk_file_selection_set_filename(file_selector
, remember_plugins_dir
);
3065 id
= gtk_dialog_run(GTK_DIALOG(file_selector
));
3067 case GTK_RESPONSE_ACCEPT
:
3068 case GTK_RESPONSE_OK
:
3069 dir
= gtk_file_selection_get_filename (file_selector
);
3070 strncpy(remember_plugins_dir
,dir
,PATH_MAX
);
3071 strncat(remember_plugins_dir
,"/",PATH_MAX
);
3072 lttv_library_path_add(dir
);
3073 case GTK_RESPONSE_REJECT
:
3074 case GTK_RESPONSE_CANCEL
:
3076 gtk_widget_destroy((GtkWidget
*)file_selector
);
3082 /* Display a directory dialogue to let user select a path for library searching
3086 on_remove_library_search_path_activate (GtkMenuItem
*menuitem
,
3089 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)menuitem
);
3091 const char *lib_path
;
3096 name
= g_ptr_array_new();
3097 nb
= lttv_library_path_number();
3098 /* ask for the library name */
3101 gchar
*path
= lttv_library_path_get(i
);
3102 g_ptr_array_add(name
, path
);
3104 lib_path
= get_selection(mw_data
, (char **)(name
->pdata
), name
->len
,
3105 "Select a library path", "Library paths");
3107 g_ptr_array_free(name
, TRUE
);
3109 if(lib_path
== NULL
) return;
3112 lttv_library_path_remove(lib_path
);
3116 on_color_activate (GtkMenuItem
*menuitem
,
3124 on_save_configuration_activate (GtkMenuItem
*menuitem
,
3127 g_info("Save configuration\n");
3132 on_content_activate (GtkMenuItem
*menuitem
,
3135 g_info("Content\n");
3140 on_about_close_activate (GtkButton
*button
,
3143 GtkWidget
*about_widget
= GTK_WIDGET(user_data
);
3145 gtk_widget_destroy(about_widget
);
3149 on_about_activate (GtkMenuItem
*menuitem
,
3152 MainWindow
*main_window
= get_window_data_struct(GTK_WIDGET(menuitem
));
3153 GtkWidget
*window_widget
= main_window
->mwindow
;
3154 GtkWidget
*about_widget
= gtk_window_new(GTK_WINDOW_TOPLEVEL
);
3155 GtkWindow
*about_window
= GTK_WINDOW(about_widget
);
3156 gint window_width
, window_height
;
3158 gtk_window_set_title(about_window
, "About Linux Trace Toolkit");
3160 gtk_window_set_resizable(about_window
, FALSE
);
3161 gtk_window_set_transient_for(about_window
, GTK_WINDOW(window_widget
));
3162 gtk_window_set_destroy_with_parent(about_window
, TRUE
);
3163 gtk_window_set_modal(about_window
, FALSE
);
3165 /* Put the about window at the center of the screen */
3166 gtk_window_get_size(about_window
, &window_width
, &window_height
);
3167 gtk_window_move (about_window
,
3168 (gdk_screen_width() - window_width
)/2,
3169 (gdk_screen_height() - window_height
)/2);
3171 GtkWidget
*vbox
= gtk_vbox_new(FALSE
, 1);
3173 gtk_container_add(GTK_CONTAINER(about_widget
), vbox
);
3177 GtkWidget
*label1
= gtk_label_new("");
3178 gtk_misc_set_padding(GTK_MISC(label1
), 10, 20);
3179 gtk_label_set_markup(GTK_LABEL(label1
), "\
3180 <big>Linux Trace Toolkit " VERSION
"</big>");
3181 gtk_label_set_justify(GTK_LABEL(label1
), GTK_JUSTIFY_CENTER
);
3183 GtkWidget
*label2
= gtk_label_new("");
3184 gtk_misc_set_padding(GTK_MISC(label2
), 10, 20);
3185 gtk_label_set_markup(GTK_LABEL(label2
), "\
3188 Michel Dagenais (New trace format, lttv main)\n\
3189 Mathieu Desnoyers (Kernel Tracer, Directory structure, build with automake/conf,\n\
3190 lttv gui, control flow view, gui cooperative trace reading\n\
3191 scheduler with interruptible foreground and background\n\
3192 computation, detailed event list (rewrite), trace reading\n\
3193 library (rewrite))\n\
3194 Benoit Des Ligneris, Eric Clement (Cluster adaptation, work in progress)\n\
3195 Xang-Xiu Yang (new trace reading library and converter, lttv gui, \n\
3196 detailed event list and statistics view)\n\
3197 Tom Zanussi (RelayFS)\n\
3199 Inspired from the original Linux Trace Toolkit Visualizer made by\n\
3202 GtkWidget
*label3
= gtk_label_new("");
3203 gtk_label_set_markup(GTK_LABEL(label3
), "\
3204 Linux Trace Toolkit Viewer, Copyright (C) 2004, 2005, 2006\n\
3206 Mathieu Desnoyers\n\
3208 Linux Trace Toolkit comes with ABSOLUTELY NO WARRANTY.\n\
3209 This is free software, and you are welcome to redistribute it\n\
3210 under certain conditions. See COPYING for details.");
3211 gtk_misc_set_padding(GTK_MISC(label3
), 10, 20);
3213 gtk_box_pack_start_defaults(GTK_BOX(vbox
), label1
);
3214 gtk_box_pack_start_defaults(GTK_BOX(vbox
), label2
);
3215 gtk_box_pack_start_defaults(GTK_BOX(vbox
), label3
);
3217 GtkWidget
*hbox
= gtk_hbox_new(TRUE
, 0);
3218 gtk_box_pack_end(GTK_BOX(vbox
), hbox
, FALSE
, FALSE
, 0);
3219 GtkWidget
*close_button
= gtk_button_new_with_mnemonic("_Close");
3220 gtk_box_pack_end(GTK_BOX(hbox
), close_button
, FALSE
, FALSE
, 0);
3221 gtk_container_set_border_width(GTK_CONTAINER(close_button
), 20);
3223 g_signal_connect(G_OBJECT(close_button
), "clicked",
3224 G_CALLBACK(on_about_close_activate
),
3225 (gpointer
)about_widget
);
3227 gtk_widget_show_all(about_widget
);
3232 on_button_new_clicked (GtkButton
*button
,
3235 create_new_window((GtkWidget
*)button
, user_data
, TRUE
);
3239 on_button_new_tab_clicked (GtkButton
*button
,
3242 create_new_tab((GtkWidget
*)button
, user_data
);
3246 on_button_open_clicked (GtkButton
*button
,
3249 open_traceset((GtkWidget
*)button
, user_data
);
3254 on_button_add_trace_clicked (GtkButton
*button
,
3257 add_trace((GtkWidget
*)button
, user_data
);
3262 on_button_remove_trace_clicked (GtkButton
*button
,
3265 remove_trace((GtkWidget
*)button
, user_data
);
3269 on_button_redraw_clicked (GtkButton
*button
,
3272 redraw((GtkWidget
*)button
, user_data
);
3276 on_button_continue_processing_clicked (GtkButton
*button
,
3279 continue_processing((GtkWidget
*)button
, user_data
);
3283 on_button_stop_processing_clicked (GtkButton
*button
,
3286 stop_processing((GtkWidget
*)button
, user_data
);
3292 on_button_save_clicked (GtkButton
*button
,
3295 save((GtkWidget
*)button
, user_data
);
3300 on_button_save_as_clicked (GtkButton
*button
,
3303 save_as((GtkWidget
*)button
, user_data
);
3308 on_button_zoom_in_clicked (GtkButton
*button
,
3311 zoom_in((GtkWidget
*)button
, user_data
);
3316 on_button_zoom_out_clicked (GtkButton
*button
,
3319 zoom_out((GtkWidget
*)button
, user_data
);
3324 on_button_zoom_extended_clicked (GtkButton
*button
,
3327 zoom_extended((GtkWidget
*)button
, user_data
);
3332 on_button_go_to_time_clicked (GtkButton
*button
,
3335 go_to_time((GtkWidget
*)button
, user_data
);
3340 on_button_show_time_frame_clicked (GtkButton
*button
,
3343 show_time_frame((GtkWidget
*)button
, user_data
);
3348 on_button_move_up_clicked (GtkButton
*button
,
3351 move_up_viewer((GtkWidget
*)button
, user_data
);
3356 on_button_move_down_clicked (GtkButton
*button
,
3359 move_down_viewer((GtkWidget
*)button
, user_data
);
3364 on_button_delete_viewer_clicked (GtkButton
*button
,
3367 delete_viewer((GtkWidget
*)button
, user_data
);
3371 on_MWindow_destroy (GtkWidget
*widget
,
3374 MainWindow
*main_window
= get_window_data_struct(widget
);
3375 LttvIAttribute
*attributes
= main_window
->attributes
;
3376 LttvAttributeValue value
;
3379 //This is unnecessary, since widgets will be destroyed
3380 //by the main window widget anyway.
3381 //remove_all_menu_toolbar_constructors(main_window, NULL);
3383 retval
= lttv_iattribute_find_by_path(attributes
, "viewers/menu",
3384 LTTV_POINTER
, &value
);
3386 lttv_menus_destroy((LttvMenus
*)*(value
.v_pointer
));
3388 retval
= lttv_iattribute_find_by_path(attributes
, "viewers/toolbar",
3389 LTTV_POINTER
, &value
);
3391 lttv_toolbars_destroy((LttvToolbars
*)*(value
.v_pointer
));
3393 g_object_unref(main_window
->attributes
);
3394 g_main_window_list
= g_slist_remove(g_main_window_list
, main_window
);
3396 g_info("There are now : %d windows\n",g_slist_length(g_main_window_list
));
3397 if(g_slist_length(g_main_window_list
) == 0)
3402 on_MWindow_configure (GtkWidget
*widget
,
3403 GdkEventConfigure
*event
,
3406 MainWindow
* mw_data
= get_window_data_struct((GtkWidget
*)widget
);
3408 // MD : removed time width modification upon resizing of the main window.
3409 // The viewers will redraw themselves completely, without time interval
3412 if(mw_data->window_width){
3413 time_span = LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context)->Time_Span ;
3414 time_win = tab->time_window;
3415 ratio = width / mw_data->window_width;
3416 tab->time_window.time_width = ltt_time_mul(time_win.time_width,ratio);
3417 time = ltt_time_sub(time_span->endTime, time_win.start_time);
3418 if(ltt_time_compare(time, tab->time_window.time_width) < 0){
3419 tab->time_window.time_width = time;
3425 mw_data->window_width = (int)width;
3434 on_MNotebook_switch_page (GtkNotebook
*notebook
,
3435 GtkNotebookPage
*page
,
3443 void time_change_manager (Tab
*tab
,
3444 TimeWindow new_time_window
)
3446 /* Only one source of time change */
3447 if(tab
->time_manager_lock
== TRUE
) return;
3449 tab
->time_manager_lock
= TRUE
;
3451 LttvTracesetContext
*tsc
= LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3452 TimeInterval time_span
= tsc
->time_span
;
3453 LttTime start_time
= new_time_window
.start_time
;
3454 LttTime end_time
= new_time_window
.end_time
;
3455 LttTime time_width
= new_time_window
.time_width
;
3457 g_assert(ltt_time_compare(start_time
, end_time
) < 0);
3460 GtkAdjustment
*adjustment
= gtk_range_get_adjustment(GTK_RANGE(tab
->scrollbar
));
3461 LttTime upper
= ltt_time_sub(time_span
.end_time
, time_span
.start_time
);
3463 gtk_range_set_increments(GTK_RANGE(tab
->scrollbar
),
3464 ltt_time_to_double(new_time_window
.time_width
)
3465 / SCROLL_STEP_PER_PAGE
3466 * NANOSECONDS_PER_SECOND
, /* step increment */
3467 ltt_time_to_double(new_time_window
.time_width
)
3468 * NANOSECONDS_PER_SECOND
); /* page increment */
3469 gtk_range_set_range(GTK_RANGE(tab
->scrollbar
),
3471 ltt_time_to_double(upper
)
3472 * NANOSECONDS_PER_SECOND
); /* upper */
3474 g_object_set(G_OBJECT(adjustment
),
3478 ltt_time_to_double(upper
), /* upper */
3480 new_time_window
.time_width_double
3481 / SCROLL_STEP_PER_PAGE
, /* step increment */
3483 new_time_window
.time_width_double
,
3484 /* page increment */
3486 new_time_window
.time_width_double
, /* page size */
3488 gtk_adjustment_changed(adjustment
);
3490 // g_object_set(G_OBJECT(adjustment),
3492 // ltt_time_to_double(
3493 // ltt_time_sub(start_time, time_span.start_time))
3496 //gtk_adjustment_value_changed(adjustment);
3497 gtk_range_set_value(GTK_RANGE(tab
->scrollbar
),
3499 ltt_time_sub(start_time
, time_span
.start_time
)) /* value */);
3501 /* set the time bar. */
3503 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry1
),
3504 (double)time_span
.start_time
.tv_sec
,
3505 (double)time_span
.end_time
.tv_sec
);
3506 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry1
),
3507 (double)start_time
.tv_sec
);
3509 /* start nanoseconds */
3510 if(start_time
.tv_sec
== time_span
.start_time
.tv_sec
) {
3511 /* can be both beginning and end at the same time. */
3512 if(start_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3513 /* If we are at the end, max nsec to end.. -1 (not zero length) */
3514 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry2
),
3515 (double)time_span
.start_time
.tv_nsec
,
3516 (double)time_span
.end_time
.tv_nsec
-1);
3518 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry2
),
3519 (double)time_span
.start_time
.tv_nsec
,
3520 (double)NANOSECONDS_PER_SECOND
-1);
3522 } else if(start_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3523 /* If we are at the end, max nsec to end.. -1 (not zero length) */
3524 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry2
),
3526 (double)time_span
.end_time
.tv_nsec
-1);
3527 } else /* anywhere else */
3528 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry2
),
3530 (double)NANOSECONDS_PER_SECOND
-1);
3531 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry2
),
3532 (double)start_time
.tv_nsec
);
3535 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry3
),
3536 (double)time_span
.start_time
.tv_sec
,
3537 (double)time_span
.end_time
.tv_sec
);
3538 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry3
),
3539 (double)end_time
.tv_sec
);
3541 /* end nanoseconds */
3542 if(end_time
.tv_sec
== time_span
.start_time
.tv_sec
) {
3543 /* can be both beginning and end at the same time. */
3544 if(end_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3545 /* If we are at the end, max nsec to end.. */
3546 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry4
),
3547 (double)time_span
.start_time
.tv_nsec
+1,
3548 (double)time_span
.end_time
.tv_nsec
);
3550 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry4
),
3551 (double)time_span
.start_time
.tv_nsec
+1,
3552 (double)NANOSECONDS_PER_SECOND
-1);
3555 else if(end_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3556 /* If we are at the end, max nsec to end.. */
3557 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry4
),
3559 (double)time_span
.end_time
.tv_nsec
);
3561 else /* anywhere else */
3562 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry4
),
3564 (double)NANOSECONDS_PER_SECOND
-1);
3565 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry4
),
3566 (double)end_time
.tv_nsec
);
3569 if(time_width
.tv_nsec
== 0) {
3570 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry7
),
3572 (double)upper
.tv_sec
);
3574 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry7
),
3576 (double)upper
.tv_sec
);
3578 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry7
),
3579 (double)time_width
.tv_sec
);
3581 /* width nanoseconds */
3582 if(time_width
.tv_sec
== upper
.tv_sec
) {
3583 if(time_width
.tv_sec
== 0) {
3584 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry8
),
3586 (double)upper
.tv_nsec
);
3588 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry8
),
3590 (double)upper
.tv_nsec
);
3593 else if(time_width
.tv_sec
== 0) {
3594 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry8
),
3596 (double)upper
.tv_nsec
);
3598 else /* anywhere else */
3599 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry8
),
3601 (double)NANOSECONDS_PER_SECOND
-1);
3602 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry8
),
3603 (double)time_width
.tv_nsec
);
3605 /* call viewer hooks for new time window */
3606 set_time_window(tab
, &new_time_window
);
3608 tab
->time_manager_lock
= FALSE
;
3612 /* value changed for frame start s
3614 * Check time span : if ns is out of range, clip it the nearest good value.
3617 on_MEntry1_value_changed (GtkSpinButton
*spinbutton
,
3620 Tab
*tab
=(Tab
*)user_data
;
3621 LttvTracesetContext
* tsc
=
3622 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3623 TimeInterval time_span
= tsc
->time_span
;
3624 gint value
= gtk_spin_button_get_value_as_int(spinbutton
);
3626 TimeWindow new_time_window
= tab
->time_window
;
3628 LttTime end_time
= new_time_window
.end_time
;
3630 new_time_window
.start_time
.tv_sec
= value
;
3632 /* start nanoseconds */
3633 if(new_time_window
.start_time
.tv_sec
== time_span
.start_time
.tv_sec
) {
3634 if(new_time_window
.start_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3635 if(new_time_window
.start_time
.tv_nsec
> time_span
.end_time
.tv_nsec
)
3636 new_time_window
.start_time
.tv_nsec
= time_span
.end_time
.tv_nsec
-1;
3637 if(new_time_window
.start_time
.tv_nsec
< time_span
.start_time
.tv_nsec
)
3638 new_time_window
.start_time
.tv_nsec
= time_span
.start_time
.tv_nsec
;
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
;
3644 else if(new_time_window
.start_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3645 if(new_time_window
.start_time
.tv_nsec
> time_span
.end_time
.tv_nsec
)
3646 new_time_window
.start_time
.tv_nsec
= time_span
.end_time
.tv_nsec
-1;
3649 if(ltt_time_compare(new_time_window
.start_time
, end_time
) >= 0) {
3650 /* Then, we must push back end time : keep the same time width
3651 * if possible, else end traceset time */
3652 end_time
= LTT_TIME_MIN(ltt_time_add(new_time_window
.start_time
,
3653 new_time_window
.time_width
),
3654 time_span
.end_time
);
3657 /* Fix the time width to fit start time and end time */
3658 new_time_window
.time_width
= ltt_time_sub(end_time
,
3659 new_time_window
.start_time
);
3660 new_time_window
.time_width_double
=
3661 ltt_time_to_double(new_time_window
.time_width
);
3663 new_time_window
.end_time
= end_time
;
3665 time_change_manager(tab
, new_time_window
);
3670 on_MEntry2_value_changed (GtkSpinButton
*spinbutton
,
3673 Tab
*tab
=(Tab
*)user_data
;
3674 LttvTracesetContext
* tsc
=
3675 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3676 TimeInterval time_span
= tsc
->time_span
;
3677 gint value
= gtk_spin_button_get_value_as_int(spinbutton
);
3679 TimeWindow new_time_window
= tab
->time_window
;
3681 LttTime end_time
= new_time_window
.end_time
;
3683 new_time_window
.start_time
.tv_nsec
= value
;
3685 if(ltt_time_compare(new_time_window
.start_time
, end_time
) >= 0) {
3686 /* Then, we must push back end time : keep the same time width
3687 * if possible, else end traceset time */
3688 end_time
= LTT_TIME_MIN(ltt_time_add(new_time_window
.start_time
,
3689 new_time_window
.time_width
),
3690 time_span
.end_time
);
3693 /* Fix the time width to fit start time and end time */
3694 new_time_window
.time_width
= ltt_time_sub(end_time
,
3695 new_time_window
.start_time
);
3696 new_time_window
.time_width_double
=
3697 ltt_time_to_double(new_time_window
.time_width
);
3699 new_time_window
.end_time
= end_time
;
3701 time_change_manager(tab
, new_time_window
);
3706 on_MEntry3_value_changed (GtkSpinButton
*spinbutton
,
3709 Tab
*tab
=(Tab
*)user_data
;
3710 LttvTracesetContext
* tsc
=
3711 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3712 TimeInterval time_span
= tsc
->time_span
;
3713 gint value
= gtk_spin_button_get_value_as_int(spinbutton
);
3715 TimeWindow new_time_window
= tab
->time_window
;
3717 LttTime end_time
= new_time_window
.end_time
;
3719 end_time
.tv_sec
= value
;
3721 /* end nanoseconds */
3722 if(end_time
.tv_sec
== time_span
.start_time
.tv_sec
) {
3723 if(end_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3724 if(end_time
.tv_nsec
> time_span
.end_time
.tv_nsec
)
3725 end_time
.tv_nsec
= time_span
.end_time
.tv_nsec
;
3726 if(end_time
.tv_nsec
< time_span
.start_time
.tv_nsec
)
3727 end_time
.tv_nsec
= time_span
.start_time
.tv_nsec
+1;
3729 if(end_time
.tv_nsec
< time_span
.start_time
.tv_nsec
)
3730 end_time
.tv_nsec
= time_span
.start_time
.tv_nsec
+1;
3733 else if(end_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3734 if(end_time
.tv_nsec
> time_span
.end_time
.tv_nsec
)
3735 end_time
.tv_nsec
= time_span
.end_time
.tv_nsec
;
3738 if(ltt_time_compare(new_time_window
.start_time
, end_time
) >= 0) {
3739 /* Then, we must push front start time : keep the same time width
3740 * if possible, else end traceset time */
3741 new_time_window
.start_time
= LTT_TIME_MAX(
3742 ltt_time_sub(end_time
,
3743 new_time_window
.time_width
),
3744 time_span
.start_time
);
3747 /* Fix the time width to fit start time and end time */
3748 new_time_window
.time_width
= ltt_time_sub(end_time
,
3749 new_time_window
.start_time
);
3750 new_time_window
.time_width_double
=
3751 ltt_time_to_double(new_time_window
.time_width
);
3753 new_time_window
.end_time
= end_time
;
3755 time_change_manager(tab
, new_time_window
);
3760 on_MEntry4_value_changed (GtkSpinButton
*spinbutton
,
3763 Tab
*tab
=(Tab
*)user_data
;
3764 LttvTracesetContext
* tsc
=
3765 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3766 TimeInterval time_span
= tsc
->time_span
;
3767 gint value
= gtk_spin_button_get_value_as_int(spinbutton
);
3769 TimeWindow new_time_window
= tab
->time_window
;
3771 LttTime end_time
= new_time_window
.end_time
;
3773 end_time
.tv_nsec
= value
;
3775 if(ltt_time_compare(new_time_window
.start_time
, end_time
) >= 0) {
3776 /* Then, we must push front start time : keep the same time width
3777 * if possible, else end traceset time */
3778 new_time_window
.start_time
= LTT_TIME_MAX(
3779 ltt_time_sub(end_time
,
3780 new_time_window
.time_width
),
3781 time_span
.start_time
);
3784 /* Fix the time width to fit start time and end time */
3785 new_time_window
.time_width
= ltt_time_sub(end_time
,
3786 new_time_window
.start_time
);
3787 new_time_window
.time_width_double
=
3788 ltt_time_to_double(new_time_window
.time_width
);
3789 new_time_window
.end_time
= end_time
;
3791 time_change_manager(tab
, new_time_window
);
3795 /* value changed for time frame interval s
3797 * Check time span : if ns is out of range, clip it the nearest good value.
3800 on_MEntry7_value_changed (GtkSpinButton
*spinbutton
,
3803 Tab
*tab
=(Tab
*)user_data
;
3804 LttvTracesetContext
* tsc
=
3805 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3806 TimeInterval time_span
= tsc
->time_span
;
3807 gint value
= gtk_spin_button_get_value_as_int(spinbutton
);
3808 LttTime current_time
, time_delta
;
3809 TimeWindow new_time_window
= tab
->time_window
;
3810 current_time
= tab
->current_time
;
3812 time_delta
= ltt_time_sub(time_span
.end_time
,time_span
.start_time
);
3813 new_time_window
.time_width
.tv_sec
= value
;
3814 new_time_window
.time_width_double
=
3815 ltt_time_to_double(new_time_window
.time_width
);
3816 if(ltt_time_compare(new_time_window
.time_width
,time_delta
) > 0)
3817 { /* Case where zoom out is bigger than trace length */
3818 new_time_window
.start_time
= time_span
.start_time
;
3819 new_time_window
.time_width
= time_delta
;
3820 new_time_window
.time_width_double
= ltt_time_to_double(time_delta
);
3821 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
3822 new_time_window
.time_width
) ;
3826 /* Center the image on the current time */
3827 new_time_window
.start_time
=
3828 ltt_time_sub(current_time
,
3829 ltt_time_from_double(new_time_window
.time_width_double
/2.0));
3830 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
3831 new_time_window
.time_width
) ;
3832 /* If on borders, don't fall off */
3833 if(ltt_time_compare(new_time_window
.start_time
, time_span
.start_time
) <0
3834 || ltt_time_compare(new_time_window
.start_time
, time_span
.end_time
) >0)
3836 new_time_window
.start_time
= time_span
.start_time
;
3837 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
3838 new_time_window
.time_width
) ;
3842 if(ltt_time_compare(new_time_window
.end_time
,
3843 time_span
.end_time
) > 0
3844 || ltt_time_compare(new_time_window
.end_time
,
3845 time_span
.start_time
) < 0)
3847 new_time_window
.start_time
=
3848 ltt_time_sub(time_span
.end_time
, new_time_window
.time_width
);
3850 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
3851 new_time_window
.time_width
) ;
3857 if(ltt_time_compare(new_time_window
.time_width
, ltt_time_zero
) == 0) {
3858 g_warning("Zoom more than 1 ns impossible");
3860 time_change_manager(tab
, new_time_window
);
3865 on_MEntry8_value_changed (GtkSpinButton
*spinbutton
,
3868 Tab
*tab
=(Tab
*)user_data
;
3869 LttvTracesetContext
* tsc
=
3870 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3871 TimeInterval time_span
= tsc
->time_span
;
3872 gint value
= gtk_spin_button_get_value_as_int(spinbutton
);
3873 LttTime current_time
, time_delta
;
3874 TimeWindow new_time_window
= tab
->time_window
;
3875 current_time
= tab
->current_time
;
3877 time_delta
= ltt_time_sub(time_span
.end_time
,time_span
.start_time
);
3878 new_time_window
.time_width
.tv_nsec
= value
;
3879 new_time_window
.time_width_double
=
3880 ltt_time_to_double(new_time_window
.time_width
);
3881 if(ltt_time_compare(new_time_window
.time_width
,time_delta
) > 0)
3882 { /* Case where zoom out is bigger than trace length */
3883 new_time_window
.start_time
= time_span
.start_time
;
3884 new_time_window
.time_width
= time_delta
;
3885 new_time_window
.time_width_double
= ltt_time_to_double(time_delta
);
3886 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
3887 new_time_window
.time_width
) ;
3891 /* Center the image on the current time */
3892 new_time_window
.start_time
=
3893 ltt_time_sub(current_time
,
3894 ltt_time_from_double(new_time_window
.time_width_double
/2.0));
3895 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
3896 new_time_window
.time_width
) ;
3897 /* If on borders, don't fall off */
3898 if(ltt_time_compare(new_time_window
.start_time
, time_span
.start_time
) <0
3899 || ltt_time_compare(new_time_window
.start_time
, time_span
.end_time
) >0)
3901 new_time_window
.start_time
= time_span
.start_time
;
3902 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
3903 new_time_window
.time_width
) ;
3907 if(ltt_time_compare(new_time_window
.end_time
,
3908 time_span
.end_time
) > 0
3909 || ltt_time_compare(new_time_window
.end_time
,
3910 time_span
.start_time
) < 0)
3912 new_time_window
.start_time
=
3913 ltt_time_sub(time_span
.end_time
, new_time_window
.time_width
);
3915 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
3916 new_time_window
.time_width
) ;
3922 if(ltt_time_compare(new_time_window
.time_width
, ltt_time_zero
) == 0) {
3923 g_warning("Zoom more than 1 ns impossible");
3925 time_change_manager(tab
, new_time_window
);
3931 void current_time_change_manager (Tab
*tab
,
3932 LttTime new_current_time
)
3934 /* Only one source of time change */
3935 if(tab
->current_time_manager_lock
== TRUE
) return;
3937 tab
->current_time_manager_lock
= TRUE
;
3939 LttvTracesetContext
*tsc
= LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3940 TimeInterval time_span
= tsc
->time_span
;
3942 /* current seconds */
3943 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry5
),
3944 (double)time_span
.start_time
.tv_sec
,
3945 (double)time_span
.end_time
.tv_sec
);
3946 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry5
),
3947 (double)new_current_time
.tv_sec
);
3950 /* start nanoseconds */
3951 if(new_current_time
.tv_sec
== time_span
.start_time
.tv_sec
) {
3952 /* can be both beginning and end at the same time. */
3953 if(new_current_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3954 /* If we are at the end, max nsec to end.. */
3955 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry6
),
3956 (double)time_span
.start_time
.tv_nsec
,
3957 (double)time_span
.end_time
.tv_nsec
);
3959 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry6
),
3960 (double)time_span
.start_time
.tv_nsec
,
3961 (double)NANOSECONDS_PER_SECOND
-1);
3963 } else if(new_current_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
3964 /* If we are at the end, max nsec to end.. */
3965 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry6
),
3967 (double)time_span
.end_time
.tv_nsec
);
3968 } else /* anywhere else */
3969 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab
->MEntry6
),
3971 (double)NANOSECONDS_PER_SECOND
-1);
3973 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab
->MEntry6
),
3974 (double)new_current_time
.tv_nsec
);
3976 set_current_time(tab
, &new_current_time
);
3978 tab
->current_time_manager_lock
= FALSE
;
3981 void current_position_change_manager(Tab
*tab
,
3982 LttvTracesetContextPosition
*pos
)
3984 LttvTracesetContext
*tsc
=
3985 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
3986 TimeInterval time_span
= tsc
->time_span
;
3989 retval
= lttv_process_traceset_seek_position(tsc
, pos
);
3990 g_assert_cmpint(retval
, ==, 0);
3991 LttTime new_time
= lttv_traceset_context_position_get_time(pos
);
3992 /* Put the context in a state coherent position */
3993 lttv_state_traceset_seek_time_closest((LttvTracesetState
*)tsc
, ltt_time_zero
);
3995 current_time_change_manager(tab
, new_time
);
3997 set_current_position(tab
, pos
);
4002 on_MEntry5_value_changed (GtkSpinButton
*spinbutton
,
4005 Tab
*tab
= (Tab
*)user_data
;
4006 LttvTracesetContext
* tsc
=
4007 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
4008 TimeInterval time_span
= tsc
->time_span
;
4009 gint value
= gtk_spin_button_get_value_as_int(spinbutton
);
4010 LttTime new_current_time
= tab
->current_time
;
4011 new_current_time
.tv_sec
= value
;
4013 /* current nanoseconds */
4014 if(new_current_time
.tv_sec
== time_span
.start_time
.tv_sec
) {
4015 if(new_current_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
4016 if(new_current_time
.tv_nsec
> time_span
.end_time
.tv_nsec
)
4017 new_current_time
.tv_nsec
= time_span
.end_time
.tv_nsec
;
4018 if(new_current_time
.tv_nsec
< time_span
.start_time
.tv_nsec
)
4019 new_current_time
.tv_nsec
= time_span
.start_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
;
4025 else if(new_current_time
.tv_sec
== time_span
.end_time
.tv_sec
) {
4026 if(new_current_time
.tv_nsec
> time_span
.end_time
.tv_nsec
)
4027 new_current_time
.tv_nsec
= time_span
.end_time
.tv_nsec
;
4030 current_time_change_manager(tab
, new_current_time
);
4034 on_MEntry6_value_changed (GtkSpinButton
*spinbutton
,
4037 Tab
*tab
= (Tab
*)user_data
;
4038 gint value
= gtk_spin_button_get_value_as_int(spinbutton
);
4039 LttTime new_current_time
= tab
->current_time
;
4040 new_current_time
.tv_nsec
= value
;
4042 current_time_change_manager(tab
, new_current_time
);
4046 void scroll_value_changed_cb(GtkWidget
*scrollbar
,
4049 Tab
*tab
= (Tab
*)user_data
;
4050 TimeWindow new_time_window
;
4052 GtkAdjustment
*adjust
= gtk_range_get_adjustment(GTK_RANGE(scrollbar
));
4053 gdouble value
= gtk_adjustment_get_value(adjust
);
4054 // gdouble upper, lower, ratio, page_size;
4056 LttvTracesetContext
* tsc
=
4057 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
);
4058 TimeInterval time_span
= tsc
->time_span
;
4060 time
= ltt_time_add(ltt_time_from_double(value
),
4061 time_span
.start_time
);
4063 new_time_window
.start_time
= time
;
4065 page_size
= adjust
->page_size
;
4067 new_time_window
.time_width
=
4068 ltt_time_from_double(page_size
);
4070 new_time_window
.time_width_double
=
4073 new_time_window
.end_time
= ltt_time_add(new_time_window
.start_time
,
4074 new_time_window
.time_width
);
4077 time_change_manager(tab
, new_time_window
);
4079 //time_window = tab->time_window;
4081 lower
= adjust
->lower
;
4082 upper
= adjust
->upper
;
4083 ratio
= (value
- lower
) / (upper
- lower
);
4084 g_info("lower %lu, upper %lu, value %lu, ratio %lu", lower
, upper
, value
, ratio
);
4086 //time = ltt_time_sub(time_span->end_time, time_span->start_time);
4087 //time = ltt_time_mul(time, (float)ratio);
4088 //time = ltt_time_add(time_span->start_time, time);
4089 time
= ltt_time_add(ltt_time_from_double(value
),
4090 time_span
.start_time
);
4092 time_window
.start_time
= time
;
4094 page_size
= adjust
->page_size
;
4096 time_window
.time_width
=
4097 ltt_time_from_double(page_size
);
4098 //time = ltt_time_sub(time_span.end_time, time);
4099 //if(ltt_time_compare(time,time_window.time_width) < 0){
4100 // time_window.time_width = time;
4103 /* call viewer hooks for new time window */
4104 set_time_window(tab
, &time_window
);
4109 /* Display a dialogue showing all eventtypes and traces, let user to select the interested
4110 * eventtypes, tracefiles and traces (filter)
4113 /* Select a trace which will be removed from traceset
4116 char * get_remove_trace(MainWindow
*mw_data
,
4117 char ** all_trace_name
, int nb_trace
)
4119 return get_selection(mw_data
, all_trace_name
, nb_trace
,
4120 "Select a trace", "Trace pathname");
4124 /* Select a module which will be loaded
4127 char * get_load_module(MainWindow
*mw_data
,
4128 char ** load_module_name
, int nb_module
)
4130 return get_selection(mw_data
, load_module_name
, nb_module
,
4131 "Select a module to load", "Module name");
4137 /* Select a module which will be unloaded
4140 char * get_unload_module(MainWindow
*mw_data
,
4141 char ** loaded_module_name
, int nb_module
)
4143 return get_selection(mw_data
, loaded_module_name
, nb_module
,
4144 "Select a module to unload", "Module name");
4148 /* Display a dialogue which shows all selectable items, let user to
4149 * select one of them
4152 char * get_selection(MainWindow
*mw_data
,
4153 char ** loaded_module_name
, int nb_module
,
4154 char *title
, char * column_title
)
4156 GtkWidget
* dialogue
;
4157 GtkWidget
* scroll_win
;
4159 GtkListStore
* store
;
4160 GtkTreeViewColumn
* column
;
4161 GtkCellRenderer
* renderer
;
4162 GtkTreeSelection
* select
;
4165 char * unload_module_name
= NULL
;
4167 dialogue
= gtk_dialog_new_with_buttons(title
,
4170 GTK_STOCK_OK
,GTK_RESPONSE_ACCEPT
,
4171 GTK_STOCK_CANCEL
,GTK_RESPONSE_REJECT
,
4173 gtk_window_set_default_size((GtkWindow
*)dialogue
, 500, 200);
4174 gtk_window_set_transient_for(GTK_WINDOW(dialogue
),
4175 GTK_WINDOW(mw_data
->mwindow
));
4177 scroll_win
= gtk_scrolled_window_new (NULL
, NULL
);
4178 gtk_widget_show ( scroll_win
);
4179 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll_win
),
4180 GTK_POLICY_AUTOMATIC
, GTK_POLICY_AUTOMATIC
);
4182 store
= gtk_list_store_new (N_COLUMNS
,G_TYPE_STRING
);
4183 tree
= gtk_tree_view_new_with_model(GTK_TREE_MODEL (store
));
4184 gtk_widget_show ( tree
);
4185 g_object_unref (G_OBJECT (store
));
4187 renderer
= gtk_cell_renderer_text_new ();
4188 column
= gtk_tree_view_column_new_with_attributes (column_title
,
4190 "text", MODULE_COLUMN
,
4192 gtk_tree_view_column_set_alignment (column
, 0.5);
4193 gtk_tree_view_column_set_fixed_width (column
, 150);
4194 gtk_tree_view_append_column (GTK_TREE_VIEW (tree
), column
);
4196 select
= gtk_tree_view_get_selection (GTK_TREE_VIEW (tree
));
4197 gtk_tree_selection_set_mode (select
, GTK_SELECTION_SINGLE
);
4199 gtk_container_add (GTK_CONTAINER (scroll_win
), tree
);
4201 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialogue
)->vbox
), scroll_win
,TRUE
, TRUE
,0);
4203 for(i
=0;i
<nb_module
;i
++){
4204 gtk_list_store_append (store
, &iter
);
4205 gtk_list_store_set (store
, &iter
, MODULE_COLUMN
,loaded_module_name
[i
],-1);
4208 id
= gtk_dialog_run(GTK_DIALOG(dialogue
));
4209 GtkTreeModel
**store_model
= (GtkTreeModel
**)&store
;
4211 case GTK_RESPONSE_ACCEPT
:
4212 case GTK_RESPONSE_OK
:
4213 if (gtk_tree_selection_get_selected (select
, store_model
, &iter
)){
4214 gtk_tree_model_get ((GtkTreeModel
*)store
, &iter
, MODULE_COLUMN
, &unload_module_name
, -1);
4216 case GTK_RESPONSE_REJECT
:
4217 case GTK_RESPONSE_CANCEL
:
4219 gtk_widget_destroy(dialogue
);
4223 return unload_module_name
;
4227 /* Insert all menu entry and tool buttons into this main window
4232 void add_all_menu_toolbar_constructors(MainWindow
* mw
, gpointer user_data
)
4236 lttvwindow_viewer_constructor constructor
;
4237 LttvMenus
* global_menu
, * instance_menu
;
4238 LttvToolbars
* global_toolbar
, * instance_toolbar
;
4239 LttvMenuClosure
*menu_item
;
4240 LttvToolbarClosure
*toolbar_item
;
4241 LttvAttributeValue value
;
4242 LttvIAttribute
*global_attributes
= LTTV_IATTRIBUTE(lttv_global_attributes());
4243 LttvIAttribute
*attributes
= mw
->attributes
;
4244 GtkWidget
* tool_menu_title_menu
, *new_widget
, *pixmap
;
4247 retval
= lttv_iattribute_find_by_path(global_attributes
, "viewers/menu",
4248 LTTV_POINTER
, &value
);
4250 if(*(value
.v_pointer
) == NULL
)
4251 *(value
.v_pointer
) = lttv_menus_new();
4252 global_menu
= (LttvMenus
*)*(value
.v_pointer
);
4254 retval
= lttv_iattribute_find_by_path(attributes
, "viewers/menu",
4255 LTTV_POINTER
, &value
);
4257 if(*(value
.v_pointer
) == NULL
)
4258 *(value
.v_pointer
) = lttv_menus_new();
4259 instance_menu
= (LttvMenus
*)*(value
.v_pointer
);
4261 retval
= lttv_iattribute_find_by_path(global_attributes
, "viewers/toolbar",
4262 LTTV_POINTER
, &value
);
4264 if(*(value
.v_pointer
) == NULL
)
4265 *(value
.v_pointer
) = lttv_toolbars_new();
4266 global_toolbar
= (LttvToolbars
*)*(value
.v_pointer
);
4268 retval
= lttv_iattribute_find_by_path(attributes
, "viewers/toolbar",
4269 LTTV_POINTER
, &value
);
4271 if(*(value
.v_pointer
) == NULL
)
4272 *(value
.v_pointer
) = lttv_toolbars_new();
4273 instance_toolbar
= (LttvToolbars
*)*(value
.v_pointer
);
4275 /* Add missing menu entries to window instance */
4276 for(i
=0;i
<global_menu
->len
;i
++) {
4277 menu_item
= &g_array_index(global_menu
, LttvMenuClosure
, i
);
4279 //add menu_item to window instance;
4280 constructor
= menu_item
->con
;
4281 tool_menu_title_menu
= lookup_widget(mw
->mwindow
,"ToolMenuTitle_menu");
4283 gtk_menu_item_new_with_mnemonic (menu_item
->menu_text
);
4284 gtk_container_add (GTK_CONTAINER (tool_menu_title_menu
),
4286 g_signal_connect ((gpointer
) new_widget
, "activate",
4287 G_CALLBACK (insert_viewer_wrap
),
4289 gtk_widget_show (new_widget
);
4290 lttv_menus_add(instance_menu
, menu_item
->con
,
4291 menu_item
->menu_path
,
4292 menu_item
->menu_text
,
4297 /* Add missing toolbar entries to window instance */
4298 for(i
=0;i
<global_toolbar
->len
;i
++) {
4299 toolbar_item
= &g_array_index(global_toolbar
, LttvToolbarClosure
, i
);
4301 //add toolbar_item to window instance;
4302 constructor
= toolbar_item
->con
;
4303 tool_menu_title_menu
= lookup_widget(mw
->mwindow
,"MToolbar1");
4304 pixbuf
= gdk_pixbuf_new_from_xpm_data((const char**)toolbar_item
->pixmap
);
4305 pixmap
= gtk_image_new_from_pixbuf(pixbuf
);
4307 gtk_toolbar_append_element (GTK_TOOLBAR (tool_menu_title_menu
),
4308 GTK_TOOLBAR_CHILD_BUTTON
,
4311 toolbar_item
->tooltip
, NULL
,
4312 pixmap
, NULL
, NULL
);
4313 gtk_label_set_use_underline(
4314 GTK_LABEL (((GtkToolbarChild
*) (
4315 g_list_last (GTK_TOOLBAR
4316 (tool_menu_title_menu
)->children
)->data
))->label
),
4318 gtk_container_set_border_width (GTK_CONTAINER (new_widget
), 1);
4319 g_signal_connect ((gpointer
) new_widget
,
4321 G_CALLBACK (insert_viewer_wrap
),
4323 gtk_widget_show (new_widget
);
4325 lttv_toolbars_add(instance_toolbar
, toolbar_item
->con
,
4326 toolbar_item
->tooltip
,
4327 toolbar_item
->pixmap
,
4335 /* Create a main window
4338 MainWindow
*construct_main_window(MainWindow
* parent
)
4342 g_debug("construct_main_window()");
4343 GtkWidget
* new_window
; /* New generated main window */
4344 MainWindow
* new_m_window
;/* New main window structure */
4345 GtkNotebook
* notebook
;
4346 LttvIAttribute
*attributes
=
4347 LTTV_IATTRIBUTE(g_object_new(LTTV_ATTRIBUTE_TYPE
, NULL
));
4348 LttvAttributeValue value
;
4351 new_m_window
= g_new(MainWindow
, 1);
4353 // Add the object's information to the module's array
4354 g_main_window_list
= g_slist_append(g_main_window_list
, new_m_window
);
4356 new_window
= create_MWindow();
4357 gtk_widget_show (new_window
);
4359 new_m_window
->mwindow
= new_window
;
4360 new_m_window
->attributes
= attributes
;
4362 retval
= lttv_iattribute_find_by_path(attributes
, "viewers/menu",
4363 LTTV_POINTER
, &value
);
4365 *(value
.v_pointer
) = lttv_menus_new();
4367 retval
= lttv_iattribute_find_by_path(attributes
, "viewers/toolbar",
4368 LTTV_POINTER
, &value
);
4370 *(value
.v_pointer
) = lttv_toolbars_new();
4372 add_all_menu_toolbar_constructors(new_m_window
, NULL
);
4374 g_object_set_data_full(G_OBJECT(new_window
),
4376 (gpointer
)new_m_window
,
4377 (GDestroyNotify
)g_free
);
4378 //create a default tab
4379 notebook
= (GtkNotebook
*)lookup_widget(new_m_window
->mwindow
, "MNotebook");
4380 if(notebook
== NULL
){
4381 g_info("Notebook does not exist\n");
4382 /* FIXME : destroy partially created widgets */
4383 g_free(new_m_window
);
4386 //gtk_notebook_popup_enable (GTK_NOTEBOOK(notebook));
4387 //for now there is no name field in LttvTraceset structure
4388 //Use "Traceset" as the label for the default tab
4390 GtkWidget
* parent_notebook
= lookup_widget(parent
->mwindow
, "MNotebook");
4391 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(parent_notebook
),
4392 gtk_notebook_get_current_page(GTK_NOTEBOOK(parent_notebook
)));
4398 LttvPluginTab
*ptab
;
4399 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
4400 parent_tab
= ptab
->tab
;
4402 LttvPluginTab
*ptab
= g_object_new(LTTV_TYPE_PLUGIN_TAB
, NULL
);
4404 new_m_window
, parent_tab
, notebook
, "Traceset");
4405 ptab
->parent
.top_widget
= ptab
->tab
->top_widget
;
4406 g_object_set_data_full(
4407 G_OBJECT(ptab
->tab
->vbox
),
4410 (GDestroyNotify
)tab_destructor
);
4411 new_tab
= ptab
->tab
;
4413 LttvPluginTab
*ptab
= g_object_new(LTTV_TYPE_PLUGIN_TAB
, NULL
);
4414 init_tab(ptab
->tab
, new_m_window
, NULL
, notebook
, "Traceset");
4415 ptab
->parent
.top_widget
= ptab
->tab
->top_widget
;
4416 g_object_set_data_full(
4417 G_OBJECT(ptab
->tab
->vbox
),
4420 (GDestroyNotify
)tab_destructor
);
4421 new_tab
= ptab
->tab
;
4424 /* Insert default viewers */
4426 LttvAttributeType type
;
4427 LttvAttributeName name
;
4428 LttvAttributeValue value
;
4429 LttvAttribute
*attribute
;
4431 LttvIAttribute
*attributes_global
=
4432 LTTV_IATTRIBUTE(lttv_global_attributes());
4434 attribute
= LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
4435 LTTV_IATTRIBUTE(attributes_global
),
4436 LTTV_VIEWER_CONSTRUCTORS
));
4437 g_assert(attribute
);
4439 name
= g_quark_from_string("guievents");
4440 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
4442 if(type
== LTTV_POINTER
) {
4443 lttvwindow_viewer_constructor viewer_constructor
=
4444 (lttvwindow_viewer_constructor
)*value
.v_pointer
;
4445 insert_viewer(new_window
, viewer_constructor
);
4448 name
= g_quark_from_string("guicontrolflow");
4449 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
4451 if(type
== LTTV_POINTER
) {
4452 lttvwindow_viewer_constructor viewer_constructor
=
4453 (lttvwindow_viewer_constructor
)*value
.v_pointer
;
4454 insert_viewer(new_window
, viewer_constructor
);
4457 name
= g_quark_from_string("guistatistics");
4458 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
4460 if(type
== LTTV_POINTER
) {
4461 lttvwindow_viewer_constructor viewer_constructor
=
4462 (lttvwindow_viewer_constructor
)*value
.v_pointer
;
4463 insert_viewer(new_window
, viewer_constructor
);
4467 g_info("There are now : %d windows\n",g_slist_length(g_main_window_list
));
4469 return new_m_window
;
4473 /* Free the memory occupied by a tab structure
4477 void tab_destructor(LttvPluginTab
* ptab
)
4479 int i
, nb
, ref_count
;
4481 Tab
*tab
= ptab
->tab
;
4483 gtk_object_destroy(GTK_OBJECT(tab
->tooltips
));
4486 g_object_unref(tab
->attributes
);
4488 if(tab
->interrupted_state
)
4489 g_object_unref(tab
->interrupted_state
);
4492 if(tab
->traceset_info
->traceset_context
!= NULL
){
4493 //remove state update hooks
4494 lttv_state_remove_event_hooks(
4495 (LttvTracesetState
*)tab
->traceset_info
->
4497 lttv_context_fini(LTTV_TRACESET_CONTEXT(tab
->traceset_info
->
4499 g_object_unref(tab
->traceset_info
->traceset_context
);
4501 if(tab
->traceset_info
->traceset
!= NULL
) {
4502 nb
= lttv_traceset_number(tab
->traceset_info
->traceset
);
4503 for(i
= 0 ; i
< nb
; i
++) {
4504 trace
= lttv_traceset_get(tab
->traceset_info
->traceset
, i
);
4505 ref_count
= lttv_trace_get_ref_number(trace
);
4507 ltt_trace_close(lttv_trace(trace
));
4511 lttv_traceset_destroy(tab
->traceset_info
->traceset
);
4512 /* Remove the idle events requests processing function of the tab */
4513 g_idle_remove_by_data(tab
);
4515 g_slist_free(tab
->events_requests
);
4516 g_free(tab
->traceset_info
);
4518 g_object_unref(ptab
);
4522 /* Create a tab and insert it into the current main window
4525 void init_tab(Tab
*tab
, MainWindow
* mw
, Tab
*copy_tab
,
4526 GtkNotebook
* notebook
, char * label
)
4530 //LttvFilter *filter = NULL;
4532 //create a new tab data structure
4533 //tab = g_new(Tab,1);
4535 //construct and initialize the traceset_info
4536 tab
->traceset_info
= g_new(TracesetInfo
,1);
4539 tab
->traceset_info
->traceset
=
4540 lttv_traceset_copy(copy_tab
->traceset_info
->traceset
);
4542 /* Copy the previous tab's filter */
4543 /* We can clone the filter, as we copy the trace set also */
4544 /* The filter must always be in sync with the trace set */
4545 tab
->filter
= lttv_filter_clone(copy_tab
->filter
);
4547 tab
->traceset_info
->traceset
= lttv_traceset_new();
4551 lttv_attribute_write_xml(
4552 lttv_traceset_attribute(tab
->traceset_info
->traceset
),
4558 tab
->time_manager_lock
= FALSE
;
4559 tab
->current_time_manager_lock
= FALSE
;
4561 //FIXME copy not implemented in lower level
4562 tab
->traceset_info
->traceset_context
=
4563 g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
4564 g_assert(tab
->traceset_info
->traceset_context
!= NULL
);
4566 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
),
4567 tab
->traceset_info
->traceset
);
4568 //add state update hooks
4569 lttv_state_add_event_hooks(
4570 (LttvTracesetState
*)tab
->traceset_info
->traceset_context
);
4572 //determine the current_time and time_window of the tab
4574 if(copy_tab
!= NULL
){
4575 tab
->time_window
= copy_tab
->time_window
;
4576 tab
->current_time
= copy_tab
->current_time
;
4578 tab
->time_window
.start_time
=
4579 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
4580 time_span
.start_time
;
4581 if(DEFAULT_TIME_WIDTH_S
<
4582 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
4583 time_span
.end_time
.tv_sec
)
4584 tmp_time
.tv_sec
= DEFAULT_TIME_WIDTH_S
;
4587 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
4588 time_span
.end_time
.tv_sec
;
4589 tmp_time
.tv_nsec
= 0;
4590 tab
->time_window
.time_width
= tmp_time
;
4591 tab
->current_time
.tv_sec
=
4592 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
4593 time_span
.start_time
.tv_sec
;
4594 tab
->current_time
.tv_nsec
=
4595 LTTV_TRACESET_CONTEXT(tab
->traceset_info
->traceset_context
)->
4596 time_span
.start_time
.tv_nsec
;
4599 tab
->attributes
= LTTV_IATTRIBUTE(g_object_new(LTTV_ATTRIBUTE_TYPE
, NULL
));
4600 tab
->interrupted_state
= g_object_new(LTTV_ATTRIBUTE_TYPE
, NULL
);
4602 tab
->vbox
= gtk_vbox_new(FALSE
, 2);
4603 tab
->top_widget
= tab
->vbox
;
4604 //g_object_set_data_full(G_OBJECT(tab->top_widget), "filter",
4605 // filter, (GDestroyNotify)lttv_filter_destroy);
4607 // g_signal_connect (G_OBJECT(tab->top_widget),
4609 // G_CALLBACK (on_top_notify),
4612 tab
->viewer_container
= gtk_vbox_new(TRUE
, 2);
4613 tab
->scrollbar
= gtk_hscrollbar_new(NULL
);
4614 //tab->multivpaned = gtk_multi_vpaned_new();
4616 gtk_box_pack_start(GTK_BOX(tab
->vbox
),
4617 tab
->viewer_container
,
4619 TRUE
, /* Give the extra space to the child */
4620 0); /* No padding */
4623 // tab->time_window = copy_tab->time_window;
4624 // tab->current_time = copy_tab->current_time;
4627 /* Create the timebar */
4629 tab
->MTimebar
= gtk_hbox_new(FALSE
, 2);
4630 gtk_widget_show(tab
->MTimebar
);
4631 tab
->tooltips
= gtk_tooltips_new();
4633 tab
->MEventBox1a
= gtk_event_box_new();
4634 gtk_widget_show(tab
->MEventBox1a
);
4635 gtk_tooltips_set_tip(tab
->tooltips
, tab
->MEventBox1a
,
4636 "Paste Start and End Times Here", "");
4637 tab
->MText1a
= gtk_label_new("Time Frame ");
4638 gtk_widget_show(tab
->MText1a
);
4639 gtk_container_add(GTK_CONTAINER(tab
->MEventBox1a
), tab
->MText1a
);
4640 tab
->MEventBox1b
= gtk_event_box_new();
4641 gtk_widget_show(tab
->MEventBox1b
);
4642 gtk_tooltips_set_tip(tab
->tooltips
, tab
->MEventBox1b
,
4643 "Paste Start Time Here", "");
4644 tab
->MText1b
= gtk_label_new("start: ");
4645 gtk_widget_show(tab
->MText1b
);
4646 gtk_container_add(GTK_CONTAINER(tab
->MEventBox1b
), tab
->MText1b
);
4647 tab
->MText2
= gtk_label_new("s");
4648 gtk_widget_show(tab
->MText2
);
4649 tab
->MText3a
= gtk_label_new("ns");
4650 gtk_widget_show(tab
->MText3a
);
4652 tab
->MEventBox3b
= gtk_event_box_new();
4653 gtk_widget_show(tab
->MEventBox3b
);
4654 gtk_tooltips_set_tip(tab
->tooltips
, tab
->MEventBox3b
,
4655 "Paste End Time Here", "");
4656 tab
->MText3b
= gtk_label_new("end:");
4657 gtk_widget_show(tab
->MText3b
);
4658 gtk_container_add(GTK_CONTAINER(tab
->MEventBox3b
), tab
->MText3b
);
4659 tab
->MText4
= gtk_label_new("s");
4660 gtk_widget_show(tab
->MText4
);
4661 tab
->MText5a
= gtk_label_new("ns");
4662 gtk_widget_show(tab
->MText5a
);
4664 tab
->MEventBox8
= gtk_event_box_new();
4665 gtk_widget_show(tab
->MEventBox8
);
4666 gtk_tooltips_set_tip(tab
->tooltips
, tab
->MEventBox8
,
4667 "Paste Time Interval here", "");
4668 tab
->MText8
= gtk_label_new("Time Interval:");
4669 gtk_widget_show(tab
->MText8
);
4670 gtk_container_add(GTK_CONTAINER(tab
->MEventBox8
), tab
->MText8
);
4671 tab
->MText9
= gtk_label_new("s");
4672 gtk_widget_show(tab
->MText9
);
4673 tab
->MText10
= gtk_label_new("ns");
4674 gtk_widget_show(tab
->MText10
);
4676 tab
->MEventBox5b
= gtk_event_box_new();
4677 gtk_widget_show(tab
->MEventBox5b
);
4678 gtk_tooltips_set_tip(tab
->tooltips
, tab
->MEventBox5b
,
4679 "Paste Current Time Here", "");
4680 tab
->MText5b
= gtk_label_new("Current Time:");
4681 gtk_widget_show(tab
->MText5b
);
4682 gtk_container_add(GTK_CONTAINER(tab
->MEventBox5b
), tab
->MText5b
);
4683 tab
->MText6
= gtk_label_new("s");
4684 gtk_widget_show(tab
->MText6
);
4685 tab
->MText7
= gtk_label_new("ns");
4686 gtk_widget_show(tab
->MText7
);
4688 tab
->MEntry1
= gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4689 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab
->MEntry1
),0);
4690 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab
->MEntry1
),TRUE
);
4691 gtk_widget_show(tab
->MEntry1
);
4692 tab
->MEntry2
= gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4693 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab
->MEntry2
),0);
4694 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab
->MEntry2
),TRUE
);
4695 gtk_widget_show(tab
->MEntry2
);
4696 tab
->MEntry3
= gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4697 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab
->MEntry3
),0);
4698 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab
->MEntry3
),TRUE
);
4699 gtk_widget_show(tab
->MEntry3
);
4700 tab
->MEntry4
= gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4701 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab
->MEntry4
),0);
4702 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab
->MEntry4
),TRUE
);
4703 gtk_widget_show(tab
->MEntry4
);
4704 tab
->MEntry5
= gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4705 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab
->MEntry5
),0);
4706 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab
->MEntry5
),TRUE
);
4707 gtk_widget_show(tab
->MEntry5
);
4708 tab
->MEntry6
= gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4709 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab
->MEntry6
),0);
4710 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab
->MEntry6
),TRUE
);
4711 gtk_widget_show(tab
->MEntry6
);
4712 tab
->MEntry7
= gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4713 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab
->MEntry7
),0);
4714 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab
->MEntry7
),TRUE
);
4715 gtk_widget_show(tab
->MEntry7
);
4716 tab
->MEntry8
= gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4717 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab
->MEntry8
),0);
4718 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab
->MEntry8
),TRUE
);
4719 gtk_widget_show(tab
->MEntry8
);
4721 GtkWidget
*temp_widget
;
4723 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEventBox1a
, FALSE
,
4725 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEventBox1b
, FALSE
,
4727 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEntry1
, FALSE
, FALSE
, 0);
4728 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MText2
, FALSE
, FALSE
, 0);
4729 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEntry2
, FALSE
, FALSE
, 0);
4730 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MText3a
, FALSE
, FALSE
, 0);
4731 temp_widget
= gtk_vseparator_new();
4732 gtk_widget_show(temp_widget
);
4733 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), temp_widget
, FALSE
, FALSE
, 0);
4734 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEventBox3b
, FALSE
,
4736 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEntry3
, FALSE
, FALSE
, 0);
4737 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MText4
, FALSE
, FALSE
, 0);
4738 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEntry4
, FALSE
, FALSE
, 0);
4739 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MText5a
, FALSE
, FALSE
, 0);
4740 temp_widget
= gtk_vseparator_new();
4741 gtk_widget_show(temp_widget
);
4742 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), temp_widget
, FALSE
, FALSE
, 0);
4743 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEventBox8
, FALSE
,
4745 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEntry7
, FALSE
, FALSE
, 0);
4746 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MText9
, FALSE
, FALSE
, 0);
4747 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MEntry8
, FALSE
, FALSE
, 0);
4748 gtk_box_pack_start (GTK_BOX (tab
->MTimebar
), tab
->MText10
, FALSE
, FALSE
, 0);
4750 temp_widget
= gtk_vseparator_new();
4751 gtk_widget_show(temp_widget
);
4752 gtk_box_pack_end (GTK_BOX (tab
->MTimebar
), tab
->MText7
, FALSE
, FALSE
, 0);
4753 gtk_box_pack_end (GTK_BOX (tab
->MTimebar
), tab
->MEntry6
, FALSE
, FALSE
, 0);
4754 gtk_box_pack_end (GTK_BOX (tab
->MTimebar
), tab
->MText6
, FALSE
, FALSE
, 0);
4755 gtk_box_pack_end (GTK_BOX (tab
->MTimebar
), tab
->MEntry5
, FALSE
, FALSE
, 0);
4756 gtk_box_pack_end (GTK_BOX (tab
->MTimebar
), tab
->MEventBox5b
, FALSE
,
4758 gtk_box_pack_end (GTK_BOX (tab
->MTimebar
), temp_widget
, FALSE
, FALSE
, 0);
4761 //GtkWidget *test = gtk_button_new_with_label("drop");
4762 //gtk_button_set_relief(GTK_BUTTON(test), GTK_RELIEF_NONE);
4763 //gtk_widget_show(test);
4764 //gtk_box_pack_end(GTK_BOX (tab->MTimebar), test, FALSE, FALSE, 0);
4765 //gtk_widget_add_events(tab->MText1, GDK_ALL_EVENTS_MASK);//GDK_BUTTON_PRESS_MASK);
4766 /*GtkWidget *event_box = gtk_event_box_new();
4767 gtk_widget_show(event_box);
4768 gtk_tooltips_set_tip(tooltips, event_box,
4769 "Paste Current Time Here", "");
4770 gtk_box_pack_end(GTK_BOX (tab->MTimebar), event_box, FALSE, FALSE, 0);
4771 GtkWidget *test = gtk_label_new("drop");
4772 gtk_container_add(GTK_CONTAINER(event_box), test);
4773 gtk_widget_show(test);
4774 g_signal_connect (G_OBJECT(event_box),
4775 "button-press-event",
4776 G_CALLBACK (on_MText1_paste),
4780 g_signal_connect (G_OBJECT(tab
->MEventBox1a
),
4781 "button-press-event",
4782 G_CALLBACK (on_MEventBox1a_paste
),
4785 g_signal_connect (G_OBJECT(tab
->MEventBox1b
),
4786 "button-press-event",
4787 G_CALLBACK (on_MEventBox1b_paste
),
4789 g_signal_connect (G_OBJECT(tab
->MEventBox3b
),
4790 "button-press-event",
4791 G_CALLBACK (on_MEventBox3b_paste
),
4793 g_signal_connect (G_OBJECT(tab
->MEventBox5b
),
4794 "button-press-event",
4795 G_CALLBACK (on_MEventBox5b_paste
),
4797 g_signal_connect (G_OBJECT(tab
->MEventBox8
),
4798 "button-press-event",
4799 G_CALLBACK (on_MEventBox8_paste
),
4803 gtk_box_pack_end(GTK_BOX(tab
->vbox
),
4805 FALSE
, /* Do not expand */
4806 FALSE
, /* Fill has no effect here (expand false) */
4807 0); /* No padding */
4809 gtk_box_pack_end(GTK_BOX(tab
->vbox
),
4811 FALSE
, /* Do not expand */
4812 FALSE
, /* Fill has no effect here (expand false) */
4813 0); /* No padding */
4815 g_object_set_data(G_OBJECT(tab
->viewer_container
), "focused_viewer", NULL
);
4821 // Display a label with a X
4822 GtkWidget *w_hbox = gtk_hbox_new(FALSE, 4);
4823 GtkWidget *w_label = gtk_label_new (label);
4824 GtkWidget *pixmap = create_pixmap(GTK_WIDGET(notebook), "close.png");
4825 GtkWidget *w_button = gtk_button_new ();
4826 gtk_container_add(GTK_CONTAINER(w_button), pixmap);
4827 //GtkWidget *w_button = gtk_button_new_with_label("x");
4829 gtk_button_set_relief(GTK_BUTTON(w_button), GTK_RELIEF_NONE);
4831 gtk_box_pack_start(GTK_BOX(w_hbox), w_label, TRUE, TRUE, 0);
4832 gtk_box_pack_end(GTK_BOX(w_hbox), w_button, FALSE,
4835 g_signal_connect_swapped (w_button, "clicked",
4836 G_CALLBACK (on_close_tab_X_clicked),
4839 gtk_widget_set_state(w_button, GTK_STATE_ACTIVE);
4841 gtk_widget_show (w_label);
4842 gtk_widget_show (pixmap);
4843 gtk_widget_show (w_button);
4844 gtk_widget_show (w_hbox);
4846 tab->label = w_hbox;
4850 tab
->label
= gtk_label_new (label
);
4852 gtk_widget_show(tab
->label
);
4853 gtk_widget_show(tab
->scrollbar
);
4854 gtk_widget_show(tab
->viewer_container
);
4855 gtk_widget_show(tab
->vbox
);
4856 //gtk_widget_show(tab->multivpaned);
4859 /* Start with empty events requests list */
4860 tab
->events_requests
= NULL
;
4861 tab
->events_request_pending
= FALSE
;
4862 tab
->stop_foreground
= FALSE
;
4866 g_signal_connect(G_OBJECT(tab
->scrollbar
), "value-changed",
4867 G_CALLBACK(scroll_value_changed_cb
), tab
);
4869 g_signal_connect ((gpointer
) tab
->MEntry1
, "value-changed",
4870 G_CALLBACK (on_MEntry1_value_changed
),
4872 g_signal_connect ((gpointer
) tab
->MEntry2
, "value-changed",
4873 G_CALLBACK (on_MEntry2_value_changed
),
4875 g_signal_connect ((gpointer
) tab
->MEntry3
, "value-changed",
4876 G_CALLBACK (on_MEntry3_value_changed
),
4878 g_signal_connect ((gpointer
) tab
->MEntry4
, "value-changed",
4879 G_CALLBACK (on_MEntry4_value_changed
),
4881 g_signal_connect ((gpointer
) tab
->MEntry5
, "value-changed",
4882 G_CALLBACK (on_MEntry5_value_changed
),
4884 g_signal_connect ((gpointer
) tab
->MEntry6
, "value-changed",
4885 G_CALLBACK (on_MEntry6_value_changed
),
4887 g_signal_connect ((gpointer
) tab
->MEntry7
, "value-changed",
4888 G_CALLBACK (on_MEntry7_value_changed
),
4890 g_signal_connect ((gpointer
) tab
->MEntry8
, "value-changed",
4891 G_CALLBACK (on_MEntry8_value_changed
),
4894 //g_signal_connect(G_OBJECT(tab->scrollbar), "changed",
4895 // G_CALLBACK(scroll_value_changed_cb), tab);
4898 //insert tab into notebook
4899 gtk_notebook_append_page(notebook
,
4902 list
= gtk_container_get_children(GTK_CONTAINER(notebook
));
4903 gtk_notebook_set_current_page(notebook
,g_list_length(list
)-1);
4904 // always show : not if(g_list_length(list)>1)
4905 gtk_notebook_set_show_tabs(notebook
, TRUE
);
4908 lttvwindow_report_time_window(tab
, copy_tab
->time_window
);
4909 lttvwindow_report_current_time(tab
, copy_tab
->current_time
);
4911 TimeWindow time_window
;
4913 time_window
.start_time
= ltt_time_zero
;
4914 time_window
.end_time
= ltt_time_add(time_window
.start_time
,
4915 lttvwindow_default_time_width
);
4916 time_window
.time_width
= lttvwindow_default_time_width
;
4917 time_window
.time_width_double
= ltt_time_to_double(time_window
.time_width
);
4919 lttvwindow_report_time_window(tab
, time_window
);
4920 lttvwindow_report_current_time(tab
, ltt_time_zero
);
4923 LttvTraceset
*traceset
= tab
->traceset_info
->traceset
;
4924 SetTraceset(tab
, traceset
);
4928 * execute_events_requests
4930 * Idle function that executes the pending requests for a tab.
4932 * @return return value : TRUE : keep the idle function, FALSE : remove it.
4934 gboolean
execute_events_requests(Tab
*tab
)
4936 return ( lttvwindow_process_pending_requests(tab
) );
4940 __EXPORT
void create_main_window_with_trace_list(GSList
*traces
)
4942 GSList
*iter
= NULL
;
4945 MainWindow
*mw
= construct_main_window(NULL
);
4946 GtkWidget
*widget
= mw
->mwindow
;
4948 GtkWidget
* notebook
= lookup_widget(widget
, "MNotebook");
4949 GtkWidget
*page
= gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook
),
4950 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook
)));
4951 LttvPluginTab
*ptab
;
4955 ptab
= create_new_tab(widget
, NULL
);
4958 ptab
= (LttvPluginTab
*)g_object_get_data(G_OBJECT(page
), "Tab_Plugin");
4962 for(iter
=traces
; iter
!=NULL
; iter
=g_slist_next(iter
)) {
4963 gchar
*path
= (gchar
*)iter
->data
;
4965 gchar abs_path
[PATH_MAX
];
4969 get_absolute_pathname(path
, abs_path
);
4970 trace_v
= lttvwindowtraces_get_trace_by_name(abs_path
);
4971 if(trace_v
== NULL
) {
4972 trace
= ltt_trace_open(abs_path
);
4974 g_warning("cannot open trace %s", abs_path
);
4976 GtkWidget
*dialogue
=
4977 gtk_message_dialog_new(
4978 GTK_WINDOW(gtk_widget_get_toplevel(widget
)),
4979 GTK_DIALOG_MODAL
|GTK_DIALOG_DESTROY_WITH_PARENT
,
4982 "Cannot open trace : maybe you should enter in the directory "
4984 gtk_dialog_run(GTK_DIALOG(dialogue
));
4985 gtk_widget_destroy(dialogue
);
4987 trace_v
= lttv_trace_new(trace
);
4988 lttvwindowtraces_add_trace(trace_v
);
4989 lttvwindow_add_trace(tab
, trace_v
);
4992 lttvwindow_add_trace(tab
, trace_v
);
4996 LttvTraceset
*traceset
;
4998 traceset
= tab
->traceset_info
->traceset
;
4999 SetTraceset(tab
, traceset
);