implements add trace dialog
[lttv.git] / lttv / modules / gui / lttvwindow / lttvwindow / callbacks.c
1 /* This file is part of the Linux Trace Toolkit viewer
2 * Copyright (C) 2003-2004 XangXiu Yang, Mathieu Desnoyers
3 *
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;
7 *
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.
12 *
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,
16 * MA 02111-1307, USA.
17 */
18
19 #ifdef HAVE_CONFIG_H
20 # include <config.h>
21 #endif
22
23 #include <limits.h> // for PATH_MAX
24 #include <stdlib.h>
25 #include <ctype.h>
26 #include <string.h>
27 #include <stdlib.h>
28
29 #include <gtk/gtk.h>
30
31 #include "callbacks.h"
32 #include "interface.h"
33 #include "support.h"
34 #include <ltt/trace.h>
35 #include <ltt/time.h>
36 #include <ltt/event.h>
37 #include <lttv/lttv.h>
38 #include <lttv/module.h>
39 #include <lttv/iattribute.h>
40 #include <lttv/traceset.h>
41 #ifdef BABEL_CLEANUP
42 #include <lttv/stats.h>
43 #include <lttv/sync/sync_chain_lttv.h>
44 #endif /* BABEL_CLEANUP */
45 #include <lttv/filter.h>
46 #include <lttvwindow/mainwindow.h>
47 #include <lttvwindow/mainwindow-private.h>
48 #include <lttvwindow/menu.h>
49 #include <lttvwindow/timebar.h>
50 #include <lttvwindow/toolbar.h>
51 #include <lttvwindow/lttvwindow.h>
52 #include <lttvwindow/lttvwindowtraces.h>
53 #include <lttvwindow/lttv_plugin_tab.h>
54
55 #include <babeltrace/babeltrace.h>
56 #include <babeltrace/ctf/events.h>
57 #include <babeltrace/ctf/iterator.h>
58
59 static LttTime lttvwindow_default_time_width = { 1, 0 };
60 #define CLIP_BUF 256 // size of clipboard buffer
61
62 extern LttvTrace *g_init_trace ;
63
64
65 /** Array containing instanced objects. */
66 extern GSList * g_main_window_list;
67
68 /** MD : keep old directory. */
69 static char remember_plugins_dir[PATH_MAX] = "";
70 static char remember_trace_dir[PATH_MAX] = "";
71
72 void tab_destructor(LttvPluginTab * ptab);
73
74 MainWindow * get_window_data_struct(GtkWidget * widget);
75 char * get_load_module(MainWindow *mw,
76 char ** load_module_name, int nb_module);
77 char * get_unload_module(MainWindow *mw,
78 char ** loaded_module_name, int nb_module);
79 char * get_remove_trace(MainWindow *mw, char ** all_trace_name, int nb_trace);
80 char * get_selection(MainWindow *mw,
81 char ** all_name, int nb, char *title, char * column_title);
82 void init_tab(Tab *tab, MainWindow * mw, Tab *copy_tab,
83 GtkNotebook * notebook, char * label);
84
85 int update_traceset(Tab *tab, LttvTraceset *traceset);
86
87 static void insert_viewer(GtkWidget* widget, lttvwindow_viewer_constructor constructor);
88
89 LttvPluginTab *create_new_tab(GtkWidget* widget, gpointer user_data);
90
91 static gboolean lttvwindow_process_pending_requests(Tab *tab);
92
93 static void on_timebar_starttime_changed(Timebar *timebar,
94 gpointer user_data);
95 static void on_timebar_endtime_changed(Timebar *timebar,
96 gpointer user_data);
97 static void on_timebar_currenttime_changed(Timebar *timebar,
98 gpointer user_data);
99
100 enum {
101 CHECKBOX_COLUMN,
102 NAME_COLUMN,
103 TOTAL_COLUMNS
104 };
105
106 enum
107 {
108 MODULE_COLUMN,
109 N_COLUMNS
110 };
111
112
113 #if 0
114 static void on_top_notify(GObject *gobject,
115 GParamSpec *arg1,
116 gpointer user_data)
117 {
118 Tab *tab = (Tab*)user_data;
119 g_message("in on_top_notify.\n");
120
121 }
122 #endif //0
123 static gboolean viewer_grab_focus(GtkWidget *widget, GdkEventButton *event,
124 gpointer data)
125 {
126 GtkWidget *viewer = GTK_WIDGET(data);
127 GtkWidget *viewer_container = gtk_widget_get_parent(viewer);
128
129 g_debug("FOCUS GRABBED");
130 g_object_set_data(G_OBJECT(viewer_container), "focused_viewer", viewer);
131 return 0;
132 }
133
134
135 static void connect_focus_recursive(GtkWidget *widget,
136 GtkWidget *viewer)
137 {
138 if(GTK_IS_CONTAINER(widget)) {
139 gtk_container_forall(GTK_CONTAINER(widget),
140 (GtkCallback)connect_focus_recursive,
141 viewer);
142
143 }
144 if(GTK_IS_TREE_VIEW(widget)) {
145 gtk_tree_view_set_headers_clickable(GTK_TREE_VIEW(widget), TRUE);
146 }
147 gtk_widget_add_events(widget, GDK_BUTTON_PRESS_MASK);
148 g_signal_connect (G_OBJECT(widget),
149 "button-press-event",
150 G_CALLBACK (viewer_grab_focus),
151 (gpointer)viewer);
152 }
153
154 /* Stop all the processings and call gtk_main_quit() */
155 static void mainwindow_quit()
156 {
157 lttvwindowtraces_unregister_requests(g_quark_from_string("stats"));
158 lttvwindowtraces_unregister_requests(g_quark_from_string("state"));
159 lttvwindowtraces_unregister_computation_hooks(g_quark_from_string("stats"));
160 lttvwindowtraces_unregister_computation_hooks(g_quark_from_string("state"));
161
162 gtk_main_quit();
163 }
164
165
166 /* insert_viewer function constructs an instance of a viewer first,
167 * then inserts the widget of the instance into the container of the
168 * main window
169 */
170
171 void
172 insert_viewer_wrap(GtkWidget *menuitem, gpointer user_data)
173 {
174 insert_viewer((GtkWidget*)menuitem, (lttvwindow_viewer_constructor)user_data);
175 }
176
177
178 /* internal functions */
179 void insert_viewer(GtkWidget* widget, lttvwindow_viewer_constructor constructor)
180 {
181 GtkWidget * viewer_container;
182 GtkWidget * notebook = lookup_widget(widget, "MNotebook");
183 GtkWidget * viewer;
184 GtkWidget *page = gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook),
185 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook)));
186 LttvPluginTab *ptab;
187 Tab *tab;
188
189 if(!page) {
190 ptab = create_new_tab(widget, NULL);
191 } else {
192 ptab = (LttvPluginTab *)g_object_get_data(G_OBJECT(page), "Tab_Plugin");
193 }
194 tab = ptab->tab;
195
196 viewer_container = tab->viewer_container;
197
198 viewer = (GtkWidget*)constructor(&ptab->parent);
199 if(viewer)
200 {
201 //gtk_multivpaned_widget_add(GTK_MULTIVPANED(multivpaned), viewer);
202
203 gtk_box_pack_end(GTK_BOX(viewer_container),
204 viewer,
205 TRUE,
206 TRUE,
207 0);
208
209 /* We want to connect the viewer_grab_focus to EVERY
210 * child of this widget. The little trick is to get each child
211 * of each GTK_CONTAINER, even subchildren.
212 */
213 connect_focus_recursive(viewer, viewer);
214 }
215 }
216
217 /**
218 * Function to set/update traceset for the viewers
219 * @param tab viewer's tab
220 * @param traceset traceset of the main window.
221 * return value :
222 * 0 : traceset updated
223 * 1 : no traceset hooks to update; not an error.
224 */
225
226 int SetTraceset(Tab * tab, LttvTraceset *traceset)
227 {
228
229 guint i;
230 TimeInterval time_span;
231 TimeWindow new_time_window;
232 LttTime new_current_time;
233
234 #ifdef BABEL_CLEANUP
235 // Perform time synchronization on the traces
236 if (syncTraceset(tsc))
237 {
238 /* There is some time-dependant information that was calculated during
239 * context initialization. Destroy the old contexts and initialize new
240 * ones.
241 * Modified from lttvwindow_add_trace()
242 */
243 // Keep a reference to the traces so they are not freed
244 for(i = 0; i < lttv_traceset_number(traceset); i++)
245 {
246 LttvTrace *trace = lttv_traceset_get(traceset, i);
247 lttv_trace_ref(trace);
248 }
249
250 // Remove state update hooks
251 lttv_state_remove_event_hooks(
252 (LttvTracesetState*)tab->traceset_info->traceset_context);
253
254 lttv_context_fini(LTTV_TRACESET_CONTEXT(
255 tab->traceset_info->traceset_context));
256 g_object_unref(tab->traceset_info->traceset_context);
257
258 for(i = 0; i < lttv_traceset_number(traceset); i++)
259 {
260 LttvTrace *trace = lttv_traceset_get(traceset, i);
261 lttvwindowtraces_remove_trace(trace);
262 lttvwindowtraces_add_trace(trace);
263 }
264
265 // Create new context
266 tab->traceset_info->traceset_context =
267 g_object_new(LTTV_TRACESET_STATS_TYPE, NULL);
268 lttv_context_init(LTTV_TRACESET_CONTEXT(tab->traceset_info->
269 traceset_context), traceset);
270
271 // Add state update hooks
272 lttv_state_add_event_hooks(
273 (LttvTracesetState*)tab->traceset_info->traceset_context);
274
275 // Remove local reference to the traces
276 for(i=0; i<lttv_traceset_number(traceset); i++)
277 {
278 LttvTrace *trace = lttv_traceset_get(traceset, i);
279 lttv_trace_unref(trace);
280 }
281
282 tsc = LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context);
283 }
284 #endif /*BABEL_CLEANUP*/
285
286
287 time_span.start_time =ltt_time_from_uint64( lttv_traceset_get_timestamp_begin(traceset));
288 time_span.end_time = ltt_time_from_uint64(lttv_traceset_get_timestamp_end(traceset));
289
290 tab->traceset_info->traceset = traceset;
291
292 new_time_window = tab->time_window;
293 new_current_time = tab->current_time;
294
295 /* Set the tab's time window and current time if
296 * out of bounds */
297 if(ltt_time_compare(tab->time_window.start_time, time_span.start_time) < 0
298 || ltt_time_compare(tab->time_window.end_time,
299 time_span.end_time) > 0) {
300 new_time_window.start_time = time_span.start_time;
301
302 new_current_time = time_span.start_time;
303
304 LttTime tmp_time;
305
306 if(ltt_time_compare(lttvwindow_default_time_width,
307 ltt_time_sub(time_span.end_time, time_span.start_time)) < 0
308 ||
309 ltt_time_compare(time_span.end_time, time_span.start_time) == 0)
310 tmp_time = lttvwindow_default_time_width;
311 else
312 tmp_time = time_span.end_time;
313
314 new_time_window.time_width = tmp_time ;
315 new_time_window.time_width_double = ltt_time_to_double(tmp_time);
316 new_time_window.end_time = ltt_time_add(new_time_window.start_time,
317 new_time_window.time_width) ;
318 }
319
320 /* Finally, call the update hooks of the viewers */
321 gint retval = update_traceset(tab, traceset);
322
323 time_change_manager(tab, new_time_window);
324 current_time_change_manager(tab, new_current_time);
325
326 return retval;
327
328 }
329
330 /**
331 * Function to set/update filter for the viewers
332 * @param tab viewer's tab
333 * @param filter filter of the main window.
334 * return value :
335 * -1 : error
336 * 0 : filters updated
337 * 1 : no filter hooks to update; not an error.
338 */
339 #if 0
340 int SetFilter(Tab * tab, gpointer filter)
341 {
342 LttvHooks * tmp;
343 LttvAttributeValue value;
344
345 g_assert(lttv_iattribute_find_by_path(tab->attributes,
346 "hooks/updatefilter", LTTV_POINTER, &value));
347
348 tmp = (LttvHooks*)*(value.v_pointer);
349
350 if(tmp == NULL) return 1;
351 lttv_hooks_call(tmp,filter);
352
353 return 0;
354 }
355 #endif //0
356
357
358 /**
359 * Function to redraw each viewer belonging to the current tab
360 * @param tab viewer's tab
361 */
362
363 int update_traceset(Tab *tab, LttvTraceset *traceset)
364 {
365 LttvAttributeValue value;
366 LttvHooks * tmp;
367 gboolean retval;
368
369 retval= lttv_iattribute_find_by_path(tab->attributes,
370 "hooks/updatetraceset",
371 LTTV_POINTER,
372 &value);
373 g_assert(retval);
374 tmp = (LttvHooks*)*(value.v_pointer);
375 if(tmp == NULL) {
376 retval = 1;
377 } else {
378 lttv_hooks_call(tmp, traceset);
379 }
380 return retval;
381 }
382
383 /**
384 Call hooks register to get update on traceset time span changes
385 */
386 int notify_time_span_changed(Tab *tab)
387 {
388 LttvAttributeValue value;
389 LttvHooks * tmp;
390 gboolean retval;
391
392 retval= lttv_iattribute_find_by_path(tab->attributes,
393 "hooks/updatetimespan",
394 LTTV_POINTER,
395 &value);
396 g_assert(retval);
397 tmp = (LttvHooks*)*(value.v_pointer);
398 if(tmp == NULL) {
399 retval = 1;
400 } else {
401 lttv_hooks_call(tmp, NULL);
402 }
403 return retval;
404 }
405
406 /* get_label function is used to get user input, it displays an input
407 * box, which allows user to input a string
408 */
409
410 void get_label_string (GtkWidget * text, gchar * label)
411 {
412 GtkEntry * entry = (GtkEntry*)text;
413 if(strlen(gtk_entry_get_text(entry))!=0)
414 strcpy(label,gtk_entry_get_text(entry));
415 }
416
417 gboolean get_label(MainWindow * mw, gchar * str, gchar* dialogue_title, gchar * label_str)
418 {
419 GtkWidget * dialogue;
420 GtkWidget * text;
421 GtkWidget * label;
422 gint id;
423
424 dialogue = gtk_dialog_new_with_buttons(dialogue_title,NULL,
425 GTK_DIALOG_MODAL,
426 GTK_STOCK_OK,GTK_RESPONSE_ACCEPT,
427 GTK_STOCK_CANCEL,GTK_RESPONSE_REJECT,
428 NULL);
429
430 label = gtk_label_new(label_str);
431 gtk_widget_show(label);
432
433 text = gtk_entry_new();
434 gtk_widget_show(text);
435
436 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialogue)->vbox), label,TRUE, TRUE,0);
437 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialogue)->vbox), text,FALSE, FALSE,0);
438
439 id = gtk_dialog_run(GTK_DIALOG(dialogue));
440 switch(id){
441 case GTK_RESPONSE_ACCEPT:
442 get_label_string(text,str);
443 gtk_widget_destroy(dialogue);
444 break;
445 case GTK_RESPONSE_REJECT:
446 default:
447 gtk_widget_destroy(dialogue);
448 return FALSE;
449 }
450 return TRUE;
451 }
452
453
454 /* get_window_data_struct function is actually a lookup function,
455 * given a widget which is in the tree of the main window, it will
456 * return the MainWindow data structure associated with main window
457 */
458
459 MainWindow * get_window_data_struct(GtkWidget * widget)
460 {
461 GtkWidget * mw;
462 MainWindow * mw_data;
463
464 mw = lookup_widget(widget, "MWindow");
465 if(mw == NULL){
466 g_info("Main window does not exist\n");
467 return NULL;
468 }
469
470 mw_data = (MainWindow *) g_object_get_data(G_OBJECT(mw),"main_window_data");
471 if(mw_data == NULL){
472 g_warning("Main window data does not exist\n");
473 return NULL;
474 }
475 return mw_data;
476 }
477
478
479 /* create_new_window function, just constructs a new main window
480 */
481
482 void create_new_window(GtkWidget* widget, gpointer user_data, gboolean clone)
483 {
484 MainWindow * parent = get_window_data_struct(widget);
485
486 if(clone){
487 g_info("Clone : use the same traceset\n");
488 construct_main_window(parent);
489 }else{
490 g_info("Empty : traceset is set to NULL\n");
491 construct_main_window(NULL);
492 }
493 }
494
495 /* Get the currently focused viewer.
496 * If no viewer is focused, use the first one.
497 *
498 * If no viewer available, return NULL.
499 */
500 GtkWidget *viewer_container_focus(GtkWidget *container)
501 {
502 GtkWidget *widget;
503
504 widget = (GtkWidget*)g_object_get_data(G_OBJECT(container),
505 "focused_viewer");
506
507 if(widget == NULL) {
508 g_debug("no widget focused");
509 GList *children = gtk_container_get_children(GTK_CONTAINER(container));
510
511 if(children != NULL)
512 widget = GTK_WIDGET(children->data);
513 g_object_set_data(G_OBJECT(container),
514 "focused_viewer",
515 widget);
516 }
517
518 return widget;
519
520
521 }
522
523 gint viewer_container_position(GtkWidget *container, GtkWidget *child)
524 {
525
526 if(child == NULL) return -1;
527
528 gint pos;
529 GValue value;
530 memset(&value, 0, sizeof(GValue));
531 g_value_init(&value, G_TYPE_INT);
532 gtk_container_child_get_property(GTK_CONTAINER(container),
533 child,
534 "position",
535 &value);
536 pos = g_value_get_int(&value);
537
538 return pos;
539 }
540
541
542 /* move_*_viewer functions move the selected view up/down in
543 * the current tab
544 */
545
546 void move_down_viewer(GtkWidget * widget, gpointer user_data)
547 {
548 GtkWidget * notebook = lookup_widget(widget, "MNotebook");
549
550 GtkWidget *page = gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook),
551 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook)));
552
553 Tab *tab;
554 if(!page) {
555 return;
556 } else {
557 LttvPluginTab *ptab;
558 ptab = g_object_get_data(G_OBJECT(page), "Tab_Plugin");
559 tab = ptab->tab;
560 }
561
562 //gtk_multivpaned_widget_move_up(GTK_MULTIVPANED(tab->multivpaned));
563
564 /* change the position in the vbox */
565 GtkWidget *focus_widget;
566 gint position;
567 focus_widget = viewer_container_focus(tab->viewer_container);
568 position = viewer_container_position(tab->viewer_container, focus_widget);
569
570 if(position > 0) {
571 /* can move up one position */
572 gtk_box_reorder_child(GTK_BOX(tab->viewer_container),
573 focus_widget,
574 position-1);
575 }
576
577 }
578
579 void move_up_viewer(GtkWidget * widget, gpointer user_data)
580 {
581 GtkWidget * notebook = lookup_widget(widget, "MNotebook");
582
583 GtkWidget *page = gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook),
584 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook)));
585 Tab *tab;
586
587 if(!page) {
588 return;
589 } else {
590 LttvPluginTab *ptab;
591 ptab = (LttvPluginTab *)g_object_get_data(G_OBJECT(page), "Tab_Plugin");
592 tab = ptab->tab;
593 }
594
595 //gtk_multivpaned_widget_move_down(GTK_MULTIVPANED(tab->multivpaned));
596 /* change the position in the vbox */
597 GtkWidget *focus_widget;
598 gint position;
599 focus_widget = viewer_container_focus(tab->viewer_container);
600 position = viewer_container_position(tab->viewer_container, focus_widget);
601
602 if(position != -1 &&
603 position <
604 g_list_length(gtk_container_get_children(
605 GTK_CONTAINER(tab->viewer_container)))-1
606 ) {
607 /* can move down one position */
608 gtk_box_reorder_child(GTK_BOX(tab->viewer_container),
609 focus_widget,
610 position+1);
611 }
612
613 }
614
615
616 /* delete_viewer deletes the selected viewer in the current tab
617 */
618
619 void delete_viewer(GtkWidget * widget, gpointer user_data)
620 {
621 GtkWidget * notebook = lookup_widget(widget, "MNotebook");
622
623 GtkWidget *page = gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook),
624 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook)));
625 Tab *tab;
626
627 if(!page) {
628 return;
629 } else {
630 LttvPluginTab *ptab;
631 ptab = g_object_get_data(G_OBJECT(page), "Tab_Plugin");
632 tab = ptab->tab;
633 }
634
635 //gtk_multivpaned_widget_delete(GTK_MULTIVPANED(tab->multivpaned));
636
637 GtkWidget *focus_widget = viewer_container_focus(tab->viewer_container);
638
639 if(focus_widget != NULL)
640 gtk_widget_destroy(focus_widget);
641
642 g_object_set_data(G_OBJECT(tab->viewer_container), "focused_viewer", NULL);
643 }
644
645 #if UNFINISHED_FEATURE
646 /* TODO ybrosseau 2012-03-15: Function is half implemented. Should be removed */
647 /* open_traceset will open a traceset saved in a file
648 * Right now, it is not finished yet, (not working)
649 * FIXME
650 */
651
652 void open_traceset(GtkWidget * widget, gpointer user_data)
653 {
654 char ** dir;
655 gint id;
656 LttvTraceset * traceset;
657 MainWindow * mw_data = get_window_data_struct(widget);
658 GtkFileSelection * file_selector =
659 (GtkFileSelection *)gtk_file_selection_new("Select a traceset");
660
661 gtk_file_selection_hide_fileop_buttons(file_selector);
662
663 gtk_window_set_transient_for(GTK_WINDOW(file_selector),
664 GTK_WINDOW(mw_data->mwindow));
665
666 id = gtk_dialog_run(GTK_DIALOG(file_selector));
667 switch(id){
668 case GTK_RESPONSE_ACCEPT:
669 case GTK_RESPONSE_OK:
670 dir = gtk_file_selection_get_selections (file_selector);
671 traceset = lttv_traceset_load(dir[0]);
672 g_info("Open a trace set %s\n", dir[0]);
673 //Not finished yet
674 g_strfreev(dir);
675 case GTK_RESPONSE_REJECT:
676 case GTK_RESPONSE_CANCEL:
677 default:
678 gtk_widget_destroy((GtkWidget*)file_selector);
679 break;
680 }
681
682 }
683 #endif
684 /* lttvwindow_process_pending_requests
685 *
686 * Process requests for parts of the trace from viewers.
687 *
688 * These requests are made by lttvwindow_events_request().
689 *
690 * This internal function gets called by g_idle, taking care of the pending
691 * requests. It is responsible for concatenation of time intervals and position
692 * requests. It does it with the following algorithm organizing process traceset
693 * calls. Here is the detailed description of the way it works :
694 *
695 * - Events Requests Servicing Algorithm
696 *
697 * Data structures necessary :
698 *
699 * List of requests added to context : list_in
700 * List of requests not added to context : list_out
701 *
702 * Initial state :
703 *
704 * list_in : empty
705 * list_out : many events requests
706 *
707 * FIXME : insert rest of algorithm here
708 *
709 */
710
711 #define list_out tab->events_requests
712
713 gboolean lttvwindow_process_pending_requests(Tab *tab)
714 {
715 #ifdef BABEL_CLEANUP
716 LttvTracesetContext *tsc;
717 LttvTracefileContext *tfc;
718 GSList *list_in = NULL;
719 LttTime end_time;
720 guint end_nb_events;
721 guint count;
722 LttvTracesetContextPosition *end_position;
723
724 if(lttvwindow_preempt_count > 0) return TRUE;
725
726 if(tab == NULL) {
727 g_critical("Foreground processing : tab does not exist. Processing removed.");
728 return FALSE;
729 }
730
731 /* There is no events requests pending : we should never have been called! */
732 g_assert(g_slist_length(list_out) != 0);
733
734 tsc = LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context);
735
736 //set the cursor to be X shape, indicating that the computer is busy in doing its job
737 #if 0
738 new = gdk_cursor_new(GDK_X_CURSOR);
739 widget = lookup_widget(tab->mw->mwindow, "MToolbar1");
740 win = gtk_widget_get_parent_window(widget);
741 gdk_window_set_cursor(win, new);
742 gdk_cursor_unref(new);
743 gdk_window_stick(win);
744 gdk_window_unstick(win);
745 #endif //0
746
747 g_debug("SIZE events req len : %d", g_slist_length(list_out));
748
749 /* Preliminary check for no trace in traceset */
750 /* Unregister the routine if empty, empty list_out too */
751 if(lttv_traceset_number(tsc->ts) == 0) {
752
753 /* - For each req in list_out */
754 GSList *iter = list_out;
755
756 while(iter != NULL) {
757
758 gboolean remove = FALSE;
759 gboolean free_data = FALSE;
760 EventsRequest *events_request = (EventsRequest *)iter->data;
761
762 /* - Call end request for req */
763 if(events_request->servicing == TRUE)
764 lttv_hooks_call(events_request->after_request, (gpointer)tsc);
765
766 /* - remove req from list_out */
767 /* Destroy the request */
768 remove = TRUE;
769 free_data = TRUE;
770
771 /* Go to next */
772 if(remove)
773 {
774 GSList *remove_iter = iter;
775
776 iter = g_slist_next(iter);
777 if(free_data) events_request_free((EventsRequest*)remove_iter->data);
778 list_out = g_slist_remove_link(list_out, remove_iter);
779 } else { // not remove
780 iter = g_slist_next(iter);
781 }
782 }
783 }
784
785 /* 0.1 Lock Traces */
786 {
787 guint iter_trace=0;
788
789 for(iter_trace=0;
790 iter_trace<lttv_traceset_number(tsc->ts);
791 iter_trace++) {
792 LttvTrace *trace_v = lttv_traceset_get(tsc->ts, iter_trace);
793
794 if(lttvwindowtraces_lock(trace_v) != 0) {
795 g_critical("Foreground processing : Unable to get trace lock");
796 return TRUE; /* Cannot get lock, try later */
797 }
798 }
799 }
800
801 /* 0.2 Seek tracefiles positions to context position */
802 //g_assert(lttv_process_traceset_seek_position(tsc, sync_position) == 0);
803 lttv_process_traceset_synchronize_tracefiles(tsc);
804
805
806 /* Events processing algorithm implementation */
807 /* Warning : the gtk_events_pending takes a LOT of cpu time. So what we do
808 * instead is to leave the control to GTK and take it back.
809 */
810 /* A. Servicing loop */
811 //while( (g_slist_length(list_in) != 0 || g_slist_length(list_out) != 0)) {
812 if((g_slist_length(list_in) != 0 || g_slist_length(list_out) != 0)) {
813 /* Servicing */
814 /* 1. If list_in is empty (need a seek) */
815 if( g_slist_length(list_in) == 0 ) {
816
817 /* list in is empty, need a seek */
818 {
819 /* 1.1 Add requests to list_in */
820 GSList *ltime = NULL;
821 GSList *lpos = NULL;
822 GSList *iter = NULL;
823
824 /* 1.1.1 Find all time requests with the lowest start time in list_out
825 * (ltime)
826 */
827 if(g_slist_length(list_out) > 0)
828 ltime = g_slist_append(ltime, g_slist_nth_data(list_out, 0));
829 for(iter=g_slist_nth(list_out,1);iter!=NULL;iter=g_slist_next(iter)) {
830 /* Find all time requests with the lowest start time in list_out */
831 EventsRequest *event_request_ltime = (EventsRequest*)g_slist_nth_data(ltime, 0);
832 EventsRequest *event_request_list_out = (EventsRequest*)iter->data;
833
834 int comp;
835 comp = ltt_time_compare(event_request_ltime->start_time,
836 event_request_list_out->start_time);
837 if(comp == 0)
838 ltime = g_slist_append(ltime, event_request_list_out);
839 else if(comp > 0) {
840 /* Remove all elements from ltime, and add current */
841 while(ltime != NULL)
842 ltime = g_slist_delete_link(ltime, g_slist_nth(ltime, 0));
843 ltime = g_slist_append(ltime, event_request_list_out);
844 }
845 }
846
847 /* 1.1.2 Find all position requests with the lowest position in list_out
848 * (lpos)
849 */
850 if(g_slist_length(list_out) > 0)
851 lpos = g_slist_append(lpos, g_slist_nth_data(list_out, 0));
852 for(iter=g_slist_nth(list_out,1);iter!=NULL;iter=g_slist_next(iter)) {
853 /* Find all position requests with the lowest position in list_out */
854 EventsRequest *event_request_lpos = (EventsRequest*)g_slist_nth_data(lpos, 0);
855 EventsRequest *event_request_list_out = (EventsRequest*)iter->data;
856
857 int comp;
858 if(event_request_lpos->start_position != NULL
859 && event_request_list_out->start_position != NULL)
860 {
861 comp = lttv_traceset_context_pos_pos_compare
862 (event_request_lpos->start_position,
863 event_request_list_out->start_position);
864 } else {
865 comp = -1;
866 }
867 if(comp == 0)
868 lpos = g_slist_append(lpos, event_request_list_out);
869 else if(comp > 0) {
870 /* Remove all elements from lpos, and add current */
871 while(lpos != NULL)
872 lpos = g_slist_delete_link(lpos, g_slist_nth(lpos, 0));
873 lpos = g_slist_append(lpos, event_request_list_out);
874 }
875 }
876
877 {
878 EventsRequest *event_request_lpos = (EventsRequest*)g_slist_nth_data(lpos, 0);
879 EventsRequest *event_request_ltime = (EventsRequest*)g_slist_nth_data(ltime, 0);
880 LttTime lpos_start_time;
881
882 if(event_request_lpos != NULL
883 && event_request_lpos->start_position != NULL) {
884 lpos_start_time = lttv_traceset_context_position_get_time(
885 event_request_lpos->start_position);
886 }
887
888 /* 1.1.3 If lpos.start time < ltime */
889 if(event_request_lpos != NULL
890 && event_request_lpos->start_position != NULL
891 && ltt_time_compare(lpos_start_time,
892 event_request_ltime->start_time)<0) {
893 /* Add lpos to list_in, remove them from list_out */
894 for(iter=lpos;iter!=NULL;iter=g_slist_next(iter)) {
895 /* Add to list_in */
896 EventsRequest *event_request_lpos =
897 (EventsRequest*)iter->data;
898
899 list_in = g_slist_append(list_in, event_request_lpos);
900 /* Remove from list_out */
901 list_out = g_slist_remove(list_out, event_request_lpos);
902 }
903 } else {
904 /* 1.1.4 (lpos.start time >= ltime) */
905 /* Add ltime to list_in, remove them from list_out */
906
907 for(iter=ltime;iter!=NULL;iter=g_slist_next(iter)) {
908 /* Add to list_in */
909 EventsRequest *event_request_ltime =
910 (EventsRequest*)iter->data;
911
912 list_in = g_slist_append(list_in, event_request_ltime);
913 /* Remove from list_out */
914 list_out = g_slist_remove(list_out, event_request_ltime);
915 }
916 }
917 }
918 g_slist_free(lpos);
919 g_slist_free(ltime);
920 }
921
922 /* 1.2 Seek */
923 {
924 tfc = lttv_traceset_context_get_current_tfc(tsc);
925 g_assert(g_slist_length(list_in)>0);
926 EventsRequest *events_request = g_slist_nth_data(list_in, 0);
927 #ifdef DEBUG
928 guint seek_count;
929 #endif
930
931 /* 1.2.1 If first request in list_in is a time request */
932 if(events_request->start_position == NULL) {
933 /* - If first req in list_in start time != current time */
934 if(tfc == NULL || ltt_time_compare(events_request->start_time,
935 tfc->timestamp) != 0)
936 /* - Seek to that time */
937 g_debug("SEEK TIME : %lu, %lu", events_request->start_time.tv_sec,
938 events_request->start_time.tv_nsec);
939 //lttv_process_traceset_seek_time(tsc, events_request->start_time);
940 lttv_state_traceset_seek_time_closest(LTTV_TRACESET_STATE(tsc),
941 events_request->start_time);
942
943 /* Process the traceset with only state hooks */
944 #ifdef DEBUG
945 seek_count =
946 #endif //DEBUG
947 lttv_process_traceset_middle(tsc,
948 events_request->start_time,
949 G_MAXUINT, NULL);
950 #ifdef DEBUG
951 g_assert(seek_count < LTTV_STATE_SAVE_INTERVAL);
952 #endif //DEBUG
953
954
955 } else {
956 LttTime pos_time;
957 LttvTracefileContext *tfc =
958 lttv_traceset_context_get_current_tfc(tsc);
959 /* Else, the first request in list_in is a position request */
960 /* If first req in list_in pos != current pos */
961 g_assert(events_request->start_position != NULL);
962 g_debug("SEEK POS time : %lu, %lu",
963 lttv_traceset_context_position_get_time(
964 events_request->start_position).tv_sec,
965 lttv_traceset_context_position_get_time(
966 events_request->start_position).tv_nsec);
967
968 if(tfc) {
969 g_debug("SEEK POS context time : %lu, %lu",
970 tfc->timestamp.tv_sec,
971 tfc->timestamp.tv_nsec);
972 } else {
973 g_debug("SEEK POS context time : %lu, %lu",
974 ltt_time_infinite.tv_sec,
975 ltt_time_infinite.tv_nsec);
976 }
977 g_assert(events_request->start_position != NULL);
978 if(lttv_traceset_context_ctx_pos_compare(tsc,
979 events_request->start_position) != 0) {
980 /* 1.2.2.1 Seek to that position */
981 g_debug("SEEK POSITION");
982 //lttv_process_traceset_seek_position(tsc, events_request->start_position);
983 pos_time = lttv_traceset_context_position_get_time(
984 events_request->start_position);
985
986 lttv_state_traceset_seek_time_closest(LTTV_TRACESET_STATE(tsc),
987 pos_time);
988
989 /* Process the traceset with only state hooks */
990 #ifdef DEBUG
991 seek_count =
992 #endif
993 lttv_process_traceset_middle(tsc,
994 ltt_time_infinite,
995 G_MAXUINT,
996 events_request->start_position);
997 g_assert(lttv_traceset_context_ctx_pos_compare(tsc,
998 events_request->start_position) == 0);
999
1000
1001 }
1002 }
1003 }
1004
1005 /* 1.3 Add hooks and call before request for all list_in members */
1006 {
1007 GSList *iter = NULL;
1008
1009 for(iter=list_in;iter!=NULL;iter=g_slist_next(iter)) {
1010 EventsRequest *events_request = (EventsRequest*)iter->data;
1011 /* 1.3.1 If !servicing */
1012 if(events_request->servicing == FALSE) {
1013 /* - begin request hooks called
1014 * - servicing = TRUE
1015 */
1016 lttv_hooks_call(events_request->before_request, (gpointer)tsc);
1017 events_request->servicing = TRUE;
1018 }
1019 /* 1.3.2 call before chunk
1020 * 1.3.3 events hooks added
1021 */
1022 if(events_request->trace == -1)
1023 lttv_process_traceset_begin(tsc,
1024 events_request->before_chunk_traceset,
1025 events_request->before_chunk_trace,
1026 events_request->before_chunk_tracefile,
1027 events_request->event,
1028 events_request->event_by_id_channel);
1029 else {
1030 guint nb_trace = lttv_traceset_number(tsc->ts);
1031 g_assert((guint)events_request->trace < nb_trace &&
1032 events_request->trace > -1);
1033 LttvTraceContext *tc = tsc->traces[events_request->trace];
1034
1035 lttv_hooks_call(events_request->before_chunk_traceset, tsc);
1036
1037 lttv_trace_context_add_hooks(tc,
1038 events_request->before_chunk_trace,
1039 events_request->before_chunk_tracefile,
1040 events_request->event,
1041 events_request->event_by_id_channel);
1042 }
1043 }
1044 }
1045 } else {
1046 /* 2. Else, list_in is not empty, we continue a read */
1047
1048 {
1049 /* 2.0 For each req of list_in */
1050 GSList *iter = list_in;
1051
1052 while(iter != NULL) {
1053
1054 EventsRequest *events_request = (EventsRequest *)iter->data;
1055
1056 /* - Call before chunk
1057 * - events hooks added
1058 */
1059 if(events_request->trace == -1)
1060 lttv_process_traceset_begin(tsc,
1061 events_request->before_chunk_traceset,
1062 events_request->before_chunk_trace,
1063 events_request->before_chunk_tracefile,
1064 events_request->event,
1065 events_request->event_by_id_channel);
1066 else {
1067 guint nb_trace = lttv_traceset_number(tsc->ts);
1068 g_assert((guint)events_request->trace < nb_trace &&
1069 events_request->trace > -1);
1070 LttvTraceContext *tc = tsc->traces[events_request->trace];
1071
1072 lttv_hooks_call(events_request->before_chunk_traceset, tsc);
1073
1074 lttv_trace_context_add_hooks(tc,
1075 events_request->before_chunk_trace,
1076 events_request->before_chunk_tracefile,
1077 events_request->event,
1078 events_request->event_by_id_channel);
1079 }
1080
1081 iter = g_slist_next(iter);
1082 }
1083 }
1084
1085 {
1086 tfc = lttv_traceset_context_get_current_tfc(tsc);
1087
1088 /* 2.1 For each req of list_out */
1089 GSList *iter = list_out;
1090
1091 while(iter != NULL) {
1092
1093 gboolean remove = FALSE;
1094 gboolean free_data = FALSE;
1095 EventsRequest *events_request = (EventsRequest *)iter->data;
1096
1097 /* if req.start time == current context time
1098 * or req.start position == current position*/
1099 if( ltt_time_compare(events_request->start_time,
1100 tfc->timestamp) == 0
1101 ||
1102 (events_request->start_position != NULL
1103 &&
1104 lttv_traceset_context_ctx_pos_compare(tsc,
1105 events_request->start_position) == 0)
1106 ) {
1107 /* - Add to list_in, remove from list_out */
1108 list_in = g_slist_append(list_in, events_request);
1109 remove = TRUE;
1110 free_data = FALSE;
1111
1112 /* - If !servicing */
1113 if(events_request->servicing == FALSE) {
1114 /* - begin request hooks called
1115 * - servicing = TRUE
1116 */
1117 lttv_hooks_call(events_request->before_request, (gpointer)tsc);
1118 events_request->servicing = TRUE;
1119 }
1120 /* call before chunk
1121 * events hooks added
1122 */
1123 if(events_request->trace == -1)
1124 lttv_process_traceset_begin(tsc,
1125 events_request->before_chunk_traceset,
1126 events_request->before_chunk_trace,
1127 events_request->before_chunk_tracefile,
1128 events_request->event,
1129 events_request->event_by_id_channel);
1130 else {
1131 guint nb_trace = lttv_traceset_number(tsc->ts);
1132 g_assert((guint)events_request->trace < nb_trace &&
1133 events_request->trace > -1);
1134 LttvTraceContext *tc = tsc->traces[events_request->trace];
1135
1136 lttv_hooks_call(events_request->before_chunk_traceset, tsc);
1137
1138 lttv_trace_context_add_hooks(tc,
1139 events_request->before_chunk_trace,
1140 events_request->before_chunk_tracefile,
1141 events_request->event,
1142 events_request->event_by_id_channel);
1143 }
1144
1145
1146 }
1147
1148 /* Go to next */
1149 if(remove)
1150 {
1151 GSList *remove_iter = iter;
1152
1153 iter = g_slist_next(iter);
1154 if(free_data) events_request_free((EventsRequest*)remove_iter->data);
1155 list_out = g_slist_remove_link(list_out, remove_iter);
1156 } else { // not remove
1157 iter = g_slist_next(iter);
1158 }
1159 }
1160 }
1161 }
1162
1163 /* 3. Find end criterions */
1164 {
1165 /* 3.1 End time */
1166 GSList *iter;
1167
1168 /* 3.1.1 Find lowest end time in list_in */
1169 g_assert(g_slist_length(list_in)>0);
1170 end_time = ((EventsRequest*)g_slist_nth_data(list_in,0))->end_time;
1171
1172 for(iter=g_slist_nth(list_in,1);iter!=NULL;iter=g_slist_next(iter)) {
1173 EventsRequest *events_request = (EventsRequest*)iter->data;
1174
1175 if(ltt_time_compare(events_request->end_time,
1176 end_time) < 0)
1177 end_time = events_request->end_time;
1178 }
1179
1180 /* 3.1.2 Find lowest start time in list_out */
1181 for(iter=list_out;iter!=NULL;iter=g_slist_next(iter)) {
1182 EventsRequest *events_request = (EventsRequest*)iter->data;
1183
1184 if(ltt_time_compare(events_request->start_time,
1185 end_time) < 0)
1186 end_time = events_request->start_time;
1187 }
1188 }
1189
1190 {
1191 /* 3.2 Number of events */
1192
1193 /* 3.2.1 Find lowest number of events in list_in */
1194 GSList *iter;
1195
1196 end_nb_events = ((EventsRequest*)g_slist_nth_data(list_in,0))->num_events;
1197
1198 for(iter=g_slist_nth(list_in,1);iter!=NULL;iter=g_slist_next(iter)) {
1199 EventsRequest *events_request = (EventsRequest*)iter->data;
1200
1201 if(events_request->num_events < end_nb_events)
1202 end_nb_events = events_request->num_events;
1203 }
1204
1205 /* 3.2.2 Use min(CHUNK_NUM_EVENTS, min num events in list_in) as
1206 * num_events */
1207
1208 end_nb_events = MIN(CHUNK_NUM_EVENTS, end_nb_events);
1209 }
1210
1211 {
1212 /* 3.3 End position */
1213
1214 /* 3.3.1 Find lowest end position in list_in */
1215 GSList *iter;
1216
1217 end_position =((EventsRequest*)g_slist_nth_data(list_in,0))->end_position;
1218
1219 for(iter=g_slist_nth(list_in,1);iter!=NULL;iter=g_slist_next(iter)) {
1220 EventsRequest *events_request = (EventsRequest*)iter->data;
1221
1222 if(events_request->end_position != NULL && end_position != NULL &&
1223 lttv_traceset_context_pos_pos_compare(events_request->end_position,
1224 end_position) <0)
1225 end_position = events_request->end_position;
1226 }
1227 }
1228
1229 {
1230 /* 3.3.2 Find lowest start position in list_out */
1231 GSList *iter;
1232
1233 for(iter=list_out;iter!=NULL;iter=g_slist_next(iter)) {
1234 EventsRequest *events_request = (EventsRequest*)iter->data;
1235
1236 if(events_request->end_position != NULL && end_position != NULL &&
1237 lttv_traceset_context_pos_pos_compare(events_request->end_position,
1238 end_position) <0)
1239 end_position = events_request->end_position;
1240 }
1241 }
1242
1243 {
1244 /* 4. Call process traceset middle */
1245 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);
1246 count = lttv_process_traceset_middle(tsc, end_time, end_nb_events, end_position);
1247
1248 tfc = lttv_traceset_context_get_current_tfc(tsc);
1249 if(tfc != NULL)
1250 g_debug("Context time after middle : %lu, %lu", tfc->timestamp.tv_sec,
1251 tfc->timestamp.tv_nsec);
1252 else
1253 g_debug("End of trace reached after middle.");
1254
1255 }
1256 {
1257 /* 5. After process traceset middle */
1258 tfc = lttv_traceset_context_get_current_tfc(tsc);
1259
1260 /* - if current context time > traceset.end time */
1261 if(tfc == NULL || ltt_time_compare(tfc->timestamp,
1262 tsc->time_span.end_time) > 0) {
1263 /* - For each req in list_in */
1264 GSList *iter = list_in;
1265
1266 while(iter != NULL) {
1267
1268 gboolean remove = FALSE;
1269 gboolean free_data = FALSE;
1270 EventsRequest *events_request = (EventsRequest *)iter->data;
1271
1272 /* - Remove events hooks for req
1273 * - Call end chunk for req
1274 */
1275
1276 if(events_request->trace == -1)
1277 lttv_process_traceset_end(tsc,
1278 events_request->after_chunk_traceset,
1279 events_request->after_chunk_trace,
1280 events_request->after_chunk_tracefile,
1281 events_request->event,
1282 events_request->event_by_id_channel);
1283
1284 else {
1285 guint nb_trace = lttv_traceset_number(tsc->ts);
1286 g_assert(events_request->trace < nb_trace &&
1287 events_request->trace > -1);
1288 LttvTraceContext *tc = tsc->traces[events_request->trace];
1289
1290 lttv_trace_context_remove_hooks(tc,
1291 events_request->after_chunk_trace,
1292 events_request->after_chunk_tracefile,
1293 events_request->event,
1294 events_request->event_by_id_channel);
1295 lttv_hooks_call(events_request->after_chunk_traceset, tsc);
1296
1297
1298 }
1299
1300 /* - Call end request for req */
1301 lttv_hooks_call(events_request->after_request, (gpointer)tsc);
1302
1303 /* - remove req from list_in */
1304 /* Destroy the request */
1305 remove = TRUE;
1306 free_data = TRUE;
1307
1308 /* Go to next */
1309 if(remove)
1310 {
1311 GSList *remove_iter = iter;
1312
1313 iter = g_slist_next(iter);
1314 if(free_data) events_request_free((EventsRequest*)remove_iter->data);
1315 list_in = g_slist_remove_link(list_in, remove_iter);
1316 } else { // not remove
1317 iter = g_slist_next(iter);
1318 }
1319 }
1320 }
1321 {
1322 /* 5.1 For each req in list_in */
1323 GSList *iter = list_in;
1324
1325 while(iter != NULL) {
1326
1327 gboolean remove = FALSE;
1328 gboolean free_data = FALSE;
1329 EventsRequest *events_request = (EventsRequest *)iter->data;
1330
1331 /* - Remove events hooks for req
1332 * - Call end chunk for req
1333 */
1334 if(events_request->trace == -1)
1335 lttv_process_traceset_end(tsc,
1336 events_request->after_chunk_traceset,
1337 events_request->after_chunk_trace,
1338 events_request->after_chunk_tracefile,
1339 events_request->event,
1340 events_request->event_by_id_channel);
1341
1342 else {
1343 guint nb_trace = lttv_traceset_number(tsc->ts);
1344 g_assert(events_request->trace < nb_trace &&
1345 events_request->trace > -1);
1346 LttvTraceContext *tc = tsc->traces[events_request->trace];
1347
1348 lttv_trace_context_remove_hooks(tc,
1349 events_request->after_chunk_trace,
1350 events_request->after_chunk_tracefile,
1351 events_request->event,
1352 events_request->event_by_id_channel);
1353
1354 lttv_hooks_call(events_request->after_chunk_traceset, tsc);
1355 }
1356
1357 /* - req.num -= count */
1358 g_assert(events_request->num_events >= count);
1359 events_request->num_events -= count;
1360
1361 g_assert(tfc != NULL);
1362 /* - if req.num == 0
1363 * or
1364 * current context time >= req.end time
1365 * or
1366 * req.end pos == current pos
1367 * or
1368 * req.stop_flag == TRUE
1369 */
1370 if( events_request->num_events == 0
1371 ||
1372 events_request->stop_flag == TRUE
1373 ||
1374 ltt_time_compare(tfc->timestamp,
1375 events_request->end_time) >= 0
1376 ||
1377 (events_request->end_position != NULL
1378 &&
1379 lttv_traceset_context_ctx_pos_compare(tsc,
1380 events_request->end_position) == 0)
1381
1382 ) {
1383 g_assert(events_request->servicing == TRUE);
1384 /* - Call end request for req
1385 * - remove req from list_in */
1386 lttv_hooks_call(events_request->after_request, (gpointer)tsc);
1387 /* - remove req from list_in */
1388 /* Destroy the request */
1389 remove = TRUE;
1390 free_data = TRUE;
1391 }
1392
1393 /* Go to next */
1394 if(remove)
1395 {
1396 GSList *remove_iter = iter;
1397
1398 iter = g_slist_next(iter);
1399 if(free_data) events_request_free((EventsRequest*)remove_iter->data);
1400 list_in = g_slist_remove_link(list_in, remove_iter);
1401 } else { // not remove
1402 iter = g_slist_next(iter);
1403 }
1404 }
1405 }
1406 }
1407 }
1408 /* End of removed servicing loop : leave control to GTK instead. */
1409 // if(gtk_events_pending()) break;
1410 //}
1411
1412 /* B. When interrupted between chunks */
1413
1414 {
1415 GSList *iter = list_in;
1416
1417 /* 1. for each request in list_in */
1418 while(iter != NULL) {
1419
1420 gboolean remove = FALSE;
1421 gboolean free_data = FALSE;
1422 EventsRequest *events_request = (EventsRequest *)iter->data;
1423
1424 /* 1.1. Use current postition as start position */
1425 if(events_request->start_position != NULL)
1426 lttv_traceset_context_position_destroy(events_request->start_position);
1427 events_request->start_position = lttv_traceset_context_position_new(tsc);
1428 lttv_traceset_context_position_save(tsc, events_request->start_position);
1429
1430 /* 1.2. Remove start time */
1431 events_request->start_time = ltt_time_infinite;
1432
1433 /* 1.3. Move from list_in to list_out */
1434 remove = TRUE;
1435 free_data = FALSE;
1436 list_out = g_slist_append(list_out, events_request);
1437
1438 /* Go to next */
1439 if(remove)
1440 {
1441 GSList *remove_iter = iter;
1442
1443 iter = g_slist_next(iter);
1444 if(free_data) events_request_free((EventsRequest*)remove_iter->data);
1445 list_in = g_slist_remove_link(list_in, remove_iter);
1446 } else { // not remove
1447 iter = g_slist_next(iter);
1448 }
1449 }
1450
1451
1452 }
1453 /* C Unlock Traces */
1454 {
1455 lttv_process_traceset_get_sync_data(tsc);
1456 //lttv_traceset_context_position_save(tsc, sync_position);
1457
1458 guint iter_trace;
1459
1460 for(iter_trace=0;
1461 iter_trace<lttv_traceset_number(tsc->ts);
1462 iter_trace++) {
1463 LttvTrace *trace_v = lttv_traceset_get(tsc->ts, iter_trace);
1464
1465 lttvwindowtraces_unlock(trace_v);
1466 }
1467 }
1468 #if 0
1469 //set the cursor back to normal
1470 gdk_window_set_cursor(win, NULL);
1471 #endif //0
1472
1473 g_assert(g_slist_length(list_in) == 0);
1474
1475 if( g_slist_length(list_out) == 0 ) {
1476 /* Put tab's request pending flag back to normal */
1477 tab->events_request_pending = FALSE;
1478 g_debug("remove the idle fct");
1479 return FALSE; /* Remove the idle function */
1480 }
1481 g_debug("leave the idle fct");
1482 return TRUE; /* Leave the idle function */
1483
1484 /* We do not use simili-round-robin, it may require to read 1 meg buffers
1485 * again and again if many tracesets use the same tracefiles. */
1486 /* Hack for round-robin idle functions */
1487 /* It will put the idle function at the end of the pool */
1488 /*g_idle_add_full((G_PRIORITY_HIGH_IDLE + 21),
1489 (GSourceFunc)execute_events_requests,
1490 tab,
1491 NULL);
1492 return FALSE;
1493 */
1494
1495 #endif /* BABEL_CLEANUP */
1496 }
1497
1498 #undef list_out
1499 /**
1500 Manage the periodic update of a live trace
1501 */
1502 static gboolean
1503 live_trace_update_handler(Tab *tab)
1504 {
1505 unsigned int updated_count;
1506 #ifdef BABEL_CLEANUP
1507 LttvTracesetContext *tsc = LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context);
1508 TimeInterval initial_time_span = tsc->time_span;
1509 TimeInterval updated_time_span;
1510
1511 updated_count = lttv_process_traceset_update(tsc);
1512
1513 /* TODO ybrosseau 2011-01-12: Add trace resynchronization */
1514
1515 /* Get the changed period bounds */
1516 updated_time_span = tsc->time_span;
1517
1518 if(ltt_time_compare(updated_time_span.start_time,
1519 initial_time_span.start_time) != 0) {
1520 /* The initial time should not change on a live update */
1521 g_assert(FALSE);
1522 }
1523
1524 /* Notify viewers (only on updates) */
1525 if(ltt_time_compare(updated_time_span.end_time,
1526 initial_time_span.end_time) != 0) {
1527
1528 notify_time_span_changed(tab);
1529 /* TODO ybrosseau 2011-01-12: Change the timebar to register
1530 to the time_span hook */
1531 timebar_set_minmax_time(TIMEBAR(tab->MTimebar),
1532 &updated_time_span.start_time,
1533 &updated_time_span.end_time );
1534
1535 /* To update the min max */
1536 time_change_manager(tab, tab->time_window);
1537 }
1538
1539 /* Timer will be recalled as long as there is files to update */
1540 return (updated_count > 0);
1541 #endif /* BABEL_CLEANUP */
1542 }
1543
1544 static void lttvwindow_add_trace(Tab *tab, LttvTrace *trace_v)
1545 {
1546 #ifdef BABEL_CLEANUP
1547 LttvTraceset *traceset = tab->traceset_info->traceset;
1548 guint i;
1549 guint num_traces = lttv_traceset_number(traceset);
1550
1551 //Verify if trace is already present.
1552 for(i=0; i<num_traces; i++)
1553 {
1554 LttvTrace * trace = lttv_traceset_get(traceset, i);
1555 if(trace == trace_v)
1556 return;
1557 }
1558
1559 //Keep a reference to the traces so they are not freed.
1560 for(i=0; i<lttv_traceset_number(traceset); i++)
1561 {
1562 LttvTrace * trace = lttv_traceset_get(traceset, i);
1563 lttv_trace_ref(trace);
1564 }
1565
1566 //remove state update hooks
1567 lttv_state_remove_event_hooks(
1568 (LttvTracesetState*)tab->traceset_info->traceset_context);
1569
1570 lttv_context_fini(LTTV_TRACESET_CONTEXT(
1571 tab->traceset_info->traceset_context));
1572 g_object_unref(tab->traceset_info->traceset_context);
1573
1574 lttv_traceset_add(traceset, trace_v);
1575 lttv_trace_ref(trace_v); /* local ref */
1576
1577 /* Create new context */
1578 tab->traceset_info->traceset_context =
1579 g_object_new(LTTV_TRACESET_STATS_TYPE, NULL);
1580 lttv_context_init(
1581 LTTV_TRACESET_CONTEXT(tab->traceset_info->
1582 traceset_context),
1583 traceset);
1584
1585
1586 //add state update hooks
1587 lttv_state_add_event_hooks(
1588 (LttvTracesetState*)tab->traceset_info->traceset_context);
1589 //Remove local reference to the traces.
1590 for(i=0; i<lttv_traceset_number(traceset); i++)
1591 {
1592 LttvTrace * trace = lttv_traceset_get(traceset, i);
1593 lttv_trace_unref(trace);
1594 }
1595
1596 //FIXME
1597 //add_trace_into_traceset_selector(GTK_MULTIVPANED(tab->multivpaned), lttv_trace(trace_v));
1598
1599
1600 if (lttv_trace(trace_v)->is_live) {
1601 /* Add timer for live update */
1602 /* TODO ybrosseau 2011-01-12: Parametrize the hardcoded 1 seconds */
1603 g_timeout_add_seconds (1,
1604 (GSourceFunc) live_trace_update_handler,
1605 tab);
1606 }
1607 #endif /* BABEL_CLEANUP */
1608 }
1609
1610 /* add_trace adds a trace into the current traceset. It first displays a
1611 * directory selection dialogue to let user choose a trace, then recreates
1612 * tracset_context, and redraws all the viewer of the current tab
1613 */
1614
1615 void add_trace(GtkWidget * widget, gpointer user_data)
1616 {
1617
1618 LttvTraceset * traceset;
1619 const char * path;
1620 char abs_path[PATH_MAX];
1621 gint id;
1622 MainWindow * mw_data = get_window_data_struct(widget);
1623 GtkWidget * notebook = lookup_widget(widget, "MNotebook");
1624
1625 GtkWidget *page = gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook),
1626 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook)));
1627 LttvPluginTab *ptab;
1628 Tab *tab;
1629
1630 if(!page) {
1631 ptab = create_new_tab(widget, NULL);
1632 tab = ptab->tab;
1633 } else {
1634 ptab = (LttvPluginTab *)g_object_get_data(G_OBJECT(page), "Tab_Plugin");
1635 tab = ptab->tab;
1636 }
1637 /* Create a new traceset*/
1638 traceset = lttv_traceset_new();
1639 /* File open dialog management */
1640 GtkWidget *extra_live_button;
1641 GtkFileChooser * file_chooser =
1642 GTK_FILE_CHOOSER(
1643 gtk_file_chooser_dialog_new ("Select a trace",
1644 GTK_WINDOW(mw_data->mwindow),
1645 GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER,
1646 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
1647 GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
1648 NULL));
1649
1650 /* Button to indicate the opening of a live trace */
1651 extra_live_button = gtk_check_button_new_with_mnemonic ("Trace is live (currently being writen)");
1652 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (extra_live_button), FALSE);
1653 gtk_file_chooser_set_extra_widget (GTK_FILE_CHOOSER (file_chooser), extra_live_button);
1654
1655 gtk_file_chooser_set_show_hidden (file_chooser, TRUE);
1656 if(remember_trace_dir[0] != '\0')
1657 gtk_file_chooser_set_filename(file_chooser, remember_trace_dir);
1658
1659 gboolean closeFileChooserDialog = TRUE;
1660
1661 do
1662 {
1663 id = gtk_dialog_run(GTK_DIALOG(file_chooser));
1664 switch(id){
1665 case GTK_RESPONSE_ACCEPT:
1666 case GTK_RESPONSE_OK:
1667 path = gtk_file_chooser_get_filename (file_chooser);
1668
1669 strncpy(remember_trace_dir, path, PATH_MAX);
1670 strncat(remember_trace_dir, "/", PATH_MAX);
1671 if(!path || strlen(path) == 0){
1672 break;
1673 }
1674 get_absolute_pathname(path, abs_path);
1675
1676 if(lttv_traceset_add_path(traceset,abs_path) != 0 ){ /*failure*/
1677
1678 g_warning("cannot open trace %s", abs_path);
1679 strncpy(remember_trace_dir, "\0", PATH_MAX);
1680 GtkWidget *dialogue =
1681 gtk_message_dialog_new(
1682 GTK_WINDOW(gtk_widget_get_toplevel(widget)),
1683 GTK_DIALOG_MODAL|GTK_DIALOG_DESTROY_WITH_PARENT,
1684 GTK_MESSAGE_ERROR,
1685 GTK_BUTTONS_OK,
1686 "Cannot open trace : maybe you should enter in the directory "
1687 "to select it ?");
1688 gtk_dialog_run(GTK_DIALOG(dialogue));
1689 gtk_widget_destroy(dialogue);
1690 closeFileChooserDialog = FALSE;
1691 }
1692 else{
1693 closeFileChooserDialog = TRUE;
1694 SetTraceset(tab, traceset);
1695 }
1696 break;
1697 //update current tab
1698 //update_traceset(mw_data);
1699
1700 // in expose now call_pending_read_hooks(mw_data);
1701
1702 //lttvwindow_report_current_time(mw_data,&(tab->current_time));
1703
1704 case GTK_RESPONSE_REJECT:
1705 case GTK_RESPONSE_CANCEL:
1706 default:
1707 closeFileChooserDialog = TRUE;
1708 break;
1709 }
1710 }while(!closeFileChooserDialog);
1711
1712 gtk_widget_destroy((GtkWidget*)file_chooser);
1713
1714 }
1715
1716 /* remove_trace removes a trace from the current traceset if all viewers in
1717 * the current tab are not interested in the trace. It first displays a
1718 * dialogue, which shows all traces in the current traceset, to let user choose
1719 * a trace, then it checks if all viewers unselect the trace, if it is true,
1720 * it will remove the trace, recreate the traceset_contex,
1721 * and redraws all the viewer of the current tab. If there is on trace in the
1722 * current traceset, it will delete all viewers of the current tab
1723 *
1724 * It destroys the filter tree. FIXME... we should request for an update
1725 * instead.
1726 */
1727
1728 void remove_trace(GtkWidget *widget, gpointer user_data)
1729 {
1730 #ifdef BABEL_CLEANUP
1731 LttTrace *trace;
1732 LttvTrace * trace_v;
1733 LttvTraceset * traceset;
1734 gint i, j, nb_trace, index=-1;
1735 char ** name, *remove_trace_name;
1736 MainWindow * mw_data = get_window_data_struct(widget);
1737 GtkWidget * notebook = lookup_widget(widget, "MNotebook");
1738
1739 GtkWidget *page = gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook),
1740 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook)));
1741 Tab *tab;
1742
1743 if(!page) {
1744 return;
1745 } else {
1746 LttvPluginTab *ptab;
1747 ptab = (LttvPluginTab *)g_object_get_data(G_OBJECT(page), "Tab_Plugin");
1748 tab = ptab->tab;
1749 }
1750
1751 nb_trace =lttv_traceset_number(tab->traceset_info->traceset);
1752 name = g_new(char*,nb_trace);
1753 for(i = 0; i < nb_trace; i++){
1754 trace_v = lttv_traceset_get(tab->traceset_info->traceset, i);
1755 trace = lttv_trace(trace_v);
1756 name[i] = (char *) g_quark_to_string(ltt_trace_name(trace));
1757 }
1758
1759 remove_trace_name = get_remove_trace(mw_data, name, nb_trace);
1760
1761
1762 if(remove_trace_name){
1763
1764 /* yuk, cut n paste from old code.. should be better (MD)*/
1765 for(i = 0; i<nb_trace; i++) {
1766 if(strcmp(remove_trace_name,name[i]) == 0){
1767 index = i;
1768 }
1769 }
1770
1771 traceset = tab->traceset_info->traceset;
1772 //Keep a reference to the traces so they are not freed.
1773 for(j=0; j<lttv_traceset_number(traceset); j++)
1774 {
1775 LttvTrace * trace = lttv_traceset_get(traceset, j);
1776 lttv_trace_ref(trace);
1777 }
1778
1779 //remove state update hooks
1780 lttv_state_remove_event_hooks(
1781 (LttvTracesetState*)tab->traceset_info->traceset_context);
1782 lttv_context_fini(LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context));
1783 g_object_unref(tab->traceset_info->traceset_context);
1784
1785 trace_v = lttv_traceset_get(traceset, index);
1786
1787 lttv_traceset_remove(traceset, index);
1788 lttv_trace_unref(trace_v); // Remove local reference
1789
1790 if(lttv_trace_get_ref_number(trace_v) <= 1) {
1791 /* ref 1 : lttvwindowtraces only*/
1792 ltt_trace_close(lttv_trace(trace_v));
1793 /* lttvwindowtraces_remove_trace takes care of destroying
1794 * the traceset linked with the trace_v and also of destroying
1795 * the trace_v at the same time.
1796 */
1797 lttvwindowtraces_remove_trace(trace_v);
1798 }
1799
1800 tab->traceset_info->traceset_context =
1801 g_object_new(LTTV_TRACESET_STATS_TYPE, NULL);
1802 lttv_context_init(
1803 LTTV_TRACESET_CONTEXT(tab->
1804 traceset_info->traceset_context),traceset);
1805 //add state update hooks
1806 lttv_state_add_event_hooks(
1807 (LttvTracesetState*)tab->traceset_info->traceset_context);
1808
1809 //Remove local reference to the traces.
1810 for(j=0; j<lttv_traceset_number(traceset); j++)
1811 {
1812 LttvTrace * trace = lttv_traceset_get(traceset, j);
1813 lttv_trace_unref(trace);
1814 }
1815
1816 SetTraceset(tab, (gpointer)traceset);
1817 }
1818 g_free(name);
1819 #endif /* BABEL_CLEANUP */
1820 }
1821
1822 #if 0
1823 void remove_trace(GtkWidget * widget, gpointer user_data)
1824 {
1825 LttTrace *trace;
1826 LttvTrace * trace_v;
1827 LttvTraceset * traceset;
1828 gint i, j, nb_trace;
1829 char ** name, *remove_trace_name;
1830 MainWindow * mw_data = get_window_data_struct(widget);
1831 LttvTracesetSelector * s;
1832 LttvTraceSelector * t;
1833 GtkWidget * w;
1834 gboolean selected;
1835 GtkWidget * notebook = lookup_widget(widget, "MNotebook");
1836
1837 GtkWidget *page = gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook),
1838 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook)));
1839 Tab *tab;
1840
1841 if(!page) {
1842 return;
1843 } else {
1844 tab = (Tab *)g_object_get_data(G_OBJECT(page), "Tab_Info");
1845 }
1846
1847 nb_trace =lttv_traceset_number(tab->traceset_info->traceset);
1848 name = g_new(char*,nb_trace);
1849 for(i = 0; i < nb_trace; i++){
1850 trace_v = lttv_traceset_get(tab->traceset_info->traceset, i);
1851 trace = lttv_trace(trace_v);
1852 name[i] = ltt_trace_name(trace);
1853 }
1854
1855 remove_trace_name = get_remove_trace(name, nb_trace);
1856
1857 if(remove_trace_name){
1858 for(i=0; i<nb_trace; i++){
1859 if(strcmp(remove_trace_name,name[i]) == 0){
1860 //unselect the trace from the current viewer
1861 //FIXME
1862 w = gtk_multivpaned_get_widget(GTK_MULTIVPANED(tab->multivpaned));
1863 if(w){
1864 s = g_object_get_data(G_OBJECT(w), "Traceset_Selector");
1865 if(s){
1866 t = lttv_traceset_selector_trace_get(s,i);
1867 lttv_trace_selector_set_selected(t, FALSE);
1868 }
1869
1870 //check if other viewers select the trace
1871 w = gtk_multivpaned_get_first_widget(GTK_MULTIVPANED(tab->multivpaned));
1872 while(w){
1873 s = g_object_get_data(G_OBJECT(w), "Traceset_Selector");
1874 if(s){
1875 t = lttv_traceset_selector_trace_get(s,i);
1876 selected = lttv_trace_selector_get_selected(t);
1877 if(selected)break;
1878 }
1879 w = gtk_multivpaned_get_next_widget(GTK_MULTIVPANED(tab->multivpaned));
1880 }
1881 }else selected = FALSE;
1882
1883 //if no viewer selects the trace, remove it
1884 if(!selected){
1885 remove_trace_from_traceset_selector(GTK_MULTIVPANED(tab->multivpaned), i);
1886
1887 traceset = tab->traceset_info->traceset;
1888 //Keep a reference to the traces so they are not freed.
1889 for(j=0; j<lttv_traceset_number(traceset); j++)
1890 {
1891 LttvTrace * trace = lttv_traceset_get(traceset, j);
1892 lttv_trace_ref(trace);
1893 }
1894
1895 //remove state update hooks
1896 lttv_state_remove_event_hooks(
1897 (LttvTracesetState*)tab->traceset_info->traceset_context);
1898 lttv_context_fini(LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context));
1899 g_object_unref(tab->traceset_info->traceset_context);
1900
1901
1902 trace_v = lttv_traceset_get(traceset, i);
1903
1904 if(lttv_trace_get_ref_number(trace_v) <= 2) {
1905 /* ref 2 : traceset, local */
1906 lttvwindowtraces_remove_trace(trace_v);
1907 ltt_trace_close(lttv_trace(trace_v));
1908 }
1909
1910 lttv_traceset_remove(traceset, i);
1911 lttv_trace_unref(trace_v); // Remove local reference
1912
1913 if(!lttv_trace_get_ref_number(trace_v))
1914 lttv_trace_destroy(trace_v);
1915
1916 tab->traceset_info->traceset_context =
1917 g_object_new(LTTV_TRACESET_STATS_TYPE, NULL);
1918 lttv_context_init(
1919 LTTV_TRACESET_CONTEXT(tab->
1920 traceset_info->traceset_context),traceset);
1921 //add state update hooks
1922 lttv_state_add_event_hooks(
1923 (LttvTracesetState*)tab->traceset_info->traceset_context);
1924
1925 //Remove local reference to the traces.
1926 for(j=0; j<lttv_traceset_number(traceset); j++)
1927 {
1928 LttvTrace * trace = lttv_traceset_get(traceset, j);
1929 lttv_trace_unref(trace);
1930 }
1931
1932
1933 //update current tab
1934 //update_traceset(mw_data);
1935 //if(nb_trace > 1){
1936
1937 SetTraceset(tab, (gpointer)traceset);
1938 // in expose now call_pending_read_hooks(mw_data);
1939
1940 //lttvwindow_report_current_time(mw_data,&(tab->current_time));
1941 //}else{
1942 // if(tab){
1943 // while(tab->multi_vpaned->num_children){
1944 // gtk_multi_vpaned_widget_delete(tab->multi_vpaned);
1945 // }
1946 // }
1947 //}
1948 }
1949 break;
1950 }
1951 }
1952 }
1953
1954 g_free(name);
1955 }
1956 #endif //0
1957
1958 /* Redraw all the viewers in the current tab */
1959 void redraw(GtkWidget *widget, gpointer user_data)
1960 {
1961 GtkWidget * notebook = lookup_widget(widget, "MNotebook");
1962 GtkWidget *page = gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook),
1963 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook)));
1964 Tab *tab;
1965 gboolean retval;
1966
1967 if(!page) {
1968 return;
1969 } else {
1970 LttvPluginTab *ptab;
1971 ptab = (LttvPluginTab *)g_object_get_data(G_OBJECT(page), "Tab_Plugin");
1972 tab = ptab->tab;
1973 }
1974
1975 LttvHooks * tmp;
1976 LttvAttributeValue value;
1977
1978 retval= lttv_iattribute_find_by_path(tab->attributes, "hooks/redraw", LTTV_POINTER, &value);
1979 g_assert(retval);
1980
1981 tmp = (LttvHooks*)*(value.v_pointer);
1982 if(tmp != NULL)
1983 lttv_hooks_call(tmp,NULL);
1984 }
1985
1986
1987 void continue_processing(GtkWidget *widget, gpointer user_data)
1988 {
1989 GtkWidget * notebook = lookup_widget(widget, "MNotebook");
1990 GtkWidget *page = gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook),
1991 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook)));
1992 Tab *tab;
1993 gboolean retval;
1994
1995 if(!page) {
1996 return;
1997 } else {
1998 LttvPluginTab *ptab;
1999 ptab = (LttvPluginTab *)g_object_get_data(G_OBJECT(page), "Tab_Plugin");
2000 tab = ptab->tab;
2001 }
2002
2003 LttvHooks * tmp;
2004 LttvAttributeValue value;
2005
2006 retval= lttv_iattribute_find_by_path(tab->attributes, "hooks/continue",
2007 LTTV_POINTER, &value);
2008 g_assert(retval);
2009
2010 tmp = (LttvHooks*)*(value.v_pointer);
2011 if(tmp != NULL)
2012 lttv_hooks_call(tmp,NULL);
2013 }
2014
2015 /* Stop the processing for the calling main window's current tab.
2016 * It removes every processing requests that are in its list. It does not call
2017 * the end request hooks, because the request is not finished.
2018 */
2019
2020 void stop_processing(GtkWidget *widget, gpointer user_data)
2021 {
2022 GtkWidget * notebook = lookup_widget(widget, "MNotebook");
2023 GtkWidget *page = gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook),
2024 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook)));
2025 Tab *tab;
2026 if(!page) {
2027 return;
2028 } else {
2029 LttvPluginTab *ptab;
2030 ptab = (LttvPluginTab *)g_object_get_data(G_OBJECT(page), "Tab_Plugin");
2031 tab = ptab->tab;
2032 }
2033 GSList *iter = tab->events_requests;
2034
2035 while(iter != NULL) {
2036 GSList *remove_iter = iter;
2037 iter = g_slist_next(iter);
2038
2039 g_free(remove_iter->data);
2040 tab->events_requests =
2041 g_slist_remove_link(tab->events_requests, remove_iter);
2042 }
2043 tab->events_request_pending = FALSE;
2044 tab->stop_foreground = TRUE;
2045 g_idle_remove_by_data(tab);
2046 g_assert(g_slist_length(tab->events_requests) == 0);
2047 }
2048
2049
2050 /* save will save the traceset to a file
2051 * Not implemented yet FIXME
2052 */
2053
2054 void save(GtkWidget * widget, gpointer user_data)
2055 {
2056 g_info("Save\n");
2057 }
2058
2059 void save_as(GtkWidget * widget, gpointer user_data)
2060 {
2061 g_info("Save as\n");
2062 }
2063
2064
2065 /* zoom will change the time_window of all the viewers of the
2066 * current tab, and redisplay them. The main functionality is to
2067 * determine the new time_window of the current tab
2068 */
2069
2070 void zoom(GtkWidget * widget, double size)
2071 {
2072 #ifdef BABEL_CLEANUP
2073 TimeInterval time_span;
2074 TimeWindow new_time_window;
2075 LttTime current_time, time_delta;
2076 LttvTracesetContext *tsc;
2077 GtkWidget * notebook = lookup_widget(widget, "MNotebook");
2078
2079 GtkWidget *page = gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook),
2080 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook)));
2081 Tab *tab;
2082
2083 if(!page) {
2084 return;
2085 } else {
2086 LttvPluginTab *ptab;
2087 ptab = (LttvPluginTab *)g_object_get_data(G_OBJECT(page), "Tab_Plugin");
2088 tab = ptab->tab;
2089 }
2090
2091 if(size == 1) return;
2092
2093 tsc = LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context);
2094 time_span = tsc->time_span;
2095 new_time_window = tab->time_window;
2096 current_time = tab->current_time;
2097
2098 time_delta = ltt_time_sub(time_span.end_time,time_span.start_time);
2099 if(size == 0){
2100 new_time_window.start_time = time_span.start_time;
2101 new_time_window.time_width = time_delta;
2102 new_time_window.time_width_double = ltt_time_to_double(time_delta);
2103 new_time_window.end_time = ltt_time_add(new_time_window.start_time,
2104 new_time_window.time_width) ;
2105 }else{
2106 new_time_window.time_width = ltt_time_div(new_time_window.time_width, size);
2107 new_time_window.time_width_double =
2108 ltt_time_to_double(new_time_window.time_width);
2109 if(ltt_time_compare(new_time_window.time_width,time_delta) > 0)
2110 { /* Case where zoom out is bigger than trace length */
2111 new_time_window.start_time = time_span.start_time;
2112 new_time_window.time_width = time_delta;
2113 new_time_window.time_width_double = ltt_time_to_double(time_delta);
2114 new_time_window.end_time = ltt_time_add(new_time_window.start_time,
2115 new_time_window.time_width) ;
2116 }
2117 else
2118 {
2119 /* Center the image on the current time */
2120 new_time_window.start_time =
2121 ltt_time_sub(current_time,
2122 ltt_time_from_double(new_time_window.time_width_double/2.0));
2123 new_time_window.end_time = ltt_time_add(new_time_window.start_time,
2124 new_time_window.time_width) ;
2125 /* If on borders, don't fall off */
2126 if(ltt_time_compare(new_time_window.start_time, time_span.start_time) <0
2127 || ltt_time_compare(new_time_window.start_time, time_span.end_time) >0)
2128 {
2129 new_time_window.start_time = time_span.start_time;
2130 new_time_window.end_time = ltt_time_add(new_time_window.start_time,
2131 new_time_window.time_width) ;
2132 }
2133 else
2134 {
2135 if(ltt_time_compare(new_time_window.end_time,
2136 time_span.end_time) > 0
2137 || ltt_time_compare(new_time_window.end_time,
2138 time_span.start_time) < 0)
2139 {
2140 new_time_window.start_time =
2141 ltt_time_sub(time_span.end_time, new_time_window.time_width);
2142
2143 new_time_window.end_time = ltt_time_add(new_time_window.start_time,
2144 new_time_window.time_width) ;
2145 }
2146 }
2147
2148 }
2149 }
2150
2151 if(ltt_time_compare(new_time_window.time_width, ltt_time_zero) == 0) {
2152 g_warning("Zoom more than 1 ns impossible");
2153 } else {
2154 time_change_manager(tab, new_time_window);
2155 }
2156
2157 #endif /* BABEL_CLEANUP */
2158 }
2159
2160 void zoom_in(GtkWidget * widget, gpointer user_data)
2161 {
2162 zoom(widget, 2);
2163 }
2164
2165 void zoom_out(GtkWidget * widget, gpointer user_data)
2166 {
2167 zoom(widget, 0.5);
2168 }
2169
2170 void zoom_extended(GtkWidget * widget, gpointer user_data)
2171 {
2172 zoom(widget, 0);
2173 }
2174
2175 void go_to_time(GtkWidget * widget, gpointer user_data)
2176 {
2177 g_info("Go to time\n");
2178 }
2179
2180 void show_time_frame(GtkWidget * widget, gpointer user_data)
2181 {
2182 g_info("Show time frame\n");
2183 }
2184
2185
2186 /* callback function */
2187
2188 void
2189 on_empty_traceset_activate (GtkMenuItem *menuitem,
2190 gpointer user_data)
2191 {
2192 create_new_window((GtkWidget*)menuitem, user_data, FALSE);
2193 }
2194
2195
2196 void
2197 on_clone_traceset_activate (GtkMenuItem *menuitem,
2198 gpointer user_data)
2199 {
2200 create_new_window((GtkWidget*)menuitem, user_data, TRUE);
2201 }
2202
2203
2204 /* create_new_tab calls create_tab to construct a new tab in the main window
2205 */
2206
2207 LttvPluginTab *create_new_tab(GtkWidget* widget, gpointer user_data)
2208 {
2209 gchar label[PATH_MAX];
2210 MainWindow * mw_data = get_window_data_struct(widget);
2211
2212 GtkNotebook * notebook = (GtkNotebook *)lookup_widget(widget, "MNotebook");
2213 if(notebook == NULL){
2214 g_info("Notebook does not exist\n");
2215 return NULL;
2216 }
2217 GtkWidget *page = gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook),
2218 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook)));
2219 Tab *copy_tab;
2220
2221 if(!page) {
2222 copy_tab = NULL;
2223 } else {
2224 LttvPluginTab *ptab;
2225 ptab = (LttvPluginTab *)g_object_get_data(G_OBJECT(page), "Tab_Plugin");
2226 copy_tab = ptab->tab;
2227 }
2228
2229 strcpy(label,"Page");
2230 if(get_label(mw_data, label,"Get the name of the tab","Please input tab's name")) {
2231 LttvPluginTab *ptab;
2232
2233 ptab = g_object_new(LTTV_TYPE_PLUGIN_TAB, NULL);
2234 init_tab (ptab->tab, mw_data, copy_tab, notebook, label);
2235 ptab->parent.top_widget = ptab->tab->top_widget;
2236 g_object_set_data_full(
2237 G_OBJECT(ptab->tab->vbox),
2238 "Tab_Plugin",
2239 ptab,
2240 (GDestroyNotify)tab_destructor);
2241 return ptab;
2242 }
2243 else return NULL;
2244 }
2245
2246 void
2247 on_tab_activate (GtkMenuItem *menuitem,
2248 gpointer user_data)
2249 {
2250 create_new_tab((GtkWidget*)menuitem, user_data);
2251 }
2252
2253
2254 void
2255 on_open_activate (GtkMenuItem *menuitem,
2256 gpointer user_data)
2257 {
2258 #ifdef UNFINISHED_FEATURE
2259 open_traceset((GtkWidget*)menuitem, user_data);
2260 #endif
2261 }
2262
2263
2264 void
2265 on_close_activate (GtkMenuItem *menuitem,
2266 gpointer user_data)
2267 {
2268 MainWindow * mw_data = get_window_data_struct((GtkWidget*)menuitem);
2269 main_window_destructor(mw_data);
2270 }
2271
2272
2273 /* remove the current tab from the main window
2274 */
2275
2276 void
2277 on_close_tab_activate (GtkWidget *widget,
2278 gpointer user_data)
2279 {
2280 gint page_num;
2281 GtkWidget * notebook;
2282 notebook = lookup_widget(widget, "MNotebook");
2283 if(notebook == NULL){
2284 g_info("Notebook does not exist\n");
2285 return;
2286 }
2287
2288 page_num = gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook));
2289
2290 gtk_notebook_remove_page(GTK_NOTEBOOK(notebook), page_num);
2291
2292 }
2293
2294 void
2295 on_close_tab_X_clicked (GtkWidget *widget,
2296 gpointer user_data)
2297 {
2298 gint page_num;
2299 GtkWidget *notebook = lookup_widget(widget, "MNotebook");
2300 if(notebook == NULL){
2301 g_info("Notebook does not exist\n");
2302 return;
2303 }
2304
2305 if((page_num = gtk_notebook_page_num(GTK_NOTEBOOK(notebook), widget)) != -1)
2306 gtk_notebook_remove_page(GTK_NOTEBOOK(notebook), page_num);
2307
2308 }
2309
2310
2311 void
2312 on_add_trace_activate (GtkMenuItem *menuitem,
2313 gpointer user_data)
2314 {
2315 add_trace((GtkWidget*)menuitem, user_data);
2316 }
2317
2318
2319 void
2320 on_remove_trace_activate (GtkMenuItem *menuitem,
2321 gpointer user_data)
2322 {
2323 remove_trace((GtkWidget*)menuitem, user_data);
2324 }
2325
2326
2327 void
2328 on_save_activate (GtkMenuItem *menuitem,
2329 gpointer user_data)
2330 {
2331 save((GtkWidget*)menuitem, user_data);
2332 }
2333
2334
2335 void
2336 on_save_as_activate (GtkMenuItem *menuitem,
2337 gpointer user_data)
2338 {
2339 save_as((GtkWidget*)menuitem, user_data);
2340 }
2341
2342
2343 void
2344 on_quit_activate (GtkMenuItem *menuitem,
2345 gpointer user_data)
2346 {
2347 while (g_slist_length(g_main_window_list) != 0) {
2348 on_MWindow_destroy(((MainWindow *)g_main_window_list->data)->mwindow,
2349 user_data);
2350 }
2351 }
2352
2353
2354 void
2355 on_cut_activate (GtkMenuItem *menuitem,
2356 gpointer user_data)
2357 {
2358 g_info("Cut\n");
2359 }
2360
2361
2362 void
2363 on_copy_activate (GtkMenuItem *menuitem,
2364 gpointer user_data)
2365 {
2366 g_info("Copye\n");
2367 }
2368
2369
2370 void
2371 on_paste_activate (GtkMenuItem *menuitem,
2372 gpointer user_data)
2373 {
2374 g_info("Paste\n");
2375 }
2376
2377
2378 void
2379 on_delete_activate (GtkMenuItem *menuitem,
2380 gpointer user_data)
2381 {
2382 g_info("Delete\n");
2383 }
2384
2385
2386 void
2387 on_zoom_in_activate (GtkMenuItem *menuitem,
2388 gpointer user_data)
2389 {
2390 zoom_in((GtkWidget*)menuitem, user_data);
2391 }
2392
2393
2394 void
2395 on_zoom_out_activate (GtkMenuItem *menuitem,
2396 gpointer user_data)
2397 {
2398 zoom_out((GtkWidget*)menuitem, user_data);
2399 }
2400
2401
2402 void
2403 on_zoom_extended_activate (GtkMenuItem *menuitem,
2404 gpointer user_data)
2405 {
2406 zoom_extended((GtkWidget*)menuitem, user_data);
2407 }
2408
2409
2410 void
2411 on_go_to_time_activate (GtkMenuItem *menuitem,
2412 gpointer user_data)
2413 {
2414 go_to_time((GtkWidget*)menuitem, user_data);
2415 }
2416
2417
2418 void
2419 on_show_time_frame_activate (GtkMenuItem *menuitem,
2420 gpointer user_data)
2421 {
2422 show_time_frame((GtkWidget*)menuitem, user_data);
2423 }
2424
2425
2426 void
2427 on_move_viewer_up_activate (GtkMenuItem *menuitem,
2428 gpointer user_data)
2429 {
2430 move_up_viewer((GtkWidget*)menuitem, user_data);
2431 }
2432
2433
2434 void
2435 on_move_viewer_down_activate (GtkMenuItem *menuitem,
2436 gpointer user_data)
2437 {
2438 move_down_viewer((GtkWidget*)menuitem, user_data);
2439 }
2440
2441
2442 void
2443 on_remove_viewer_activate (GtkMenuItem *menuitem,
2444 gpointer user_data)
2445 {
2446 delete_viewer((GtkWidget*)menuitem, user_data);
2447 }
2448
2449 void
2450 on_trace_facility_activate (GtkMenuItem *menuitem,
2451 gpointer user_data)
2452 {
2453 g_info("Trace facility selector: %s\n", "");
2454 }
2455
2456
2457 /* Dispaly a file selection dialogue to let user select a library, then call
2458 * lttv_library_load().
2459 */
2460
2461 void
2462 on_load_library_activate (GtkMenuItem *menuitem,
2463 gpointer user_data)
2464 {
2465 GError *error = NULL;
2466 MainWindow * mw_data = get_window_data_struct((GtkWidget*)menuitem);
2467
2468 gchar load_module_path_alter[PATH_MAX];
2469 {
2470 GPtrArray *name;
2471 guint nb,i;
2472 gchar *load_module_path;
2473 name = g_ptr_array_new();
2474 nb = lttv_library_path_number();
2475 /* ask for the library path */
2476
2477 for(i=0;i<nb;i++){
2478 gchar *path;
2479 path = lttv_library_path_get(i);
2480 g_ptr_array_add(name, path);
2481 }
2482
2483 load_module_path = get_selection(mw_data,
2484 (char **)(name->pdata), name->len,
2485 "Select a library path", "Library paths");
2486 if(load_module_path != NULL)
2487 strncpy(load_module_path_alter, load_module_path, PATH_MAX-1); // -1 for /
2488
2489 g_ptr_array_free(name, TRUE);
2490
2491 if(load_module_path == NULL) return;
2492 }
2493
2494 {
2495 /* Make sure the module path ends with a / */
2496 gchar *ptr = load_module_path_alter;
2497
2498 ptr = strchr(ptr, '\0');
2499
2500 if(*(ptr-1) != '/') {
2501 *ptr = '/';
2502 *(ptr+1) = '\0';
2503 }
2504 }
2505
2506 {
2507 /* Ask for the library to load : list files in the previously selected
2508 * directory */
2509 gchar str[PATH_MAX];
2510 gchar ** dir;
2511 gint id;
2512 GtkFileSelection * file_selector =
2513 (GtkFileSelection *)gtk_file_selection_new("Select a module");
2514 gtk_file_selection_set_filename(file_selector, load_module_path_alter);
2515 gtk_file_selection_hide_fileop_buttons(file_selector);
2516
2517 gtk_window_set_transient_for(GTK_WINDOW(file_selector),
2518 GTK_WINDOW(mw_data->mwindow));
2519
2520 str[0] = '\0';
2521 id = gtk_dialog_run(GTK_DIALOG(file_selector));
2522 switch(id){
2523 case GTK_RESPONSE_ACCEPT:
2524 case GTK_RESPONSE_OK:
2525 dir = gtk_file_selection_get_selections (file_selector);
2526 strncpy(str,dir[0],PATH_MAX);
2527 strncpy(remember_plugins_dir,dir[0],PATH_MAX);
2528 /* only keep file name */
2529 gchar *str1;
2530 str1 = strrchr(str,'/');
2531 if(str1)str1++;
2532 else{
2533 str1 = strrchr(str,'\\');
2534 str1++;
2535 }
2536 #if 0
2537 /* remove "lib" */
2538 if(*str1 == 'l' && *(str1+1)== 'i' && *(str1+2)=='b')
2539 str1=str1+3;
2540 remove info after . */
2541 {
2542 gchar *str2 = str1;
2543
2544 str2 = strrchr(str2, '.');
2545 if(str2 != NULL) *str2 = '\0';
2546 }
2547 lttv_module_require(str1, &error);
2548 #endif //0
2549 lttv_library_load(str1, &error);
2550 if(error != NULL) g_warning("%s", error->message);
2551 else g_info("Load library: %s\n", str);
2552 g_strfreev(dir);
2553 case GTK_RESPONSE_REJECT:
2554 case GTK_RESPONSE_CANCEL:
2555 default:
2556 gtk_widget_destroy((GtkWidget*)file_selector);
2557 break;
2558 }
2559
2560 }
2561
2562
2563
2564 }
2565
2566
2567 /* Display all loaded modules, let user to select a module to unload
2568 * by calling lttv_module_unload
2569 */
2570
2571 void
2572 on_unload_library_activate (GtkMenuItem *menuitem,
2573 gpointer user_data)
2574 {
2575 MainWindow * mw_data = get_window_data_struct((GtkWidget*)menuitem);
2576
2577 LttvLibrary *library = NULL;
2578
2579 GPtrArray *name;
2580 guint nb,i;
2581 gchar *lib_name;
2582 name = g_ptr_array_new();
2583 nb = lttv_library_number();
2584 LttvLibraryInfo *lib_info = g_new(LttvLibraryInfo,nb);
2585 /* ask for the library name */
2586
2587 for(i=0;i<nb;i++){
2588 LttvLibrary *iter_lib = lttv_library_get(i);
2589 lttv_library_info(iter_lib, &lib_info[i]);
2590
2591 gchar *path = lib_info[i].name;
2592 g_ptr_array_add(name, path);
2593 }
2594 lib_name = get_selection(mw_data, (char **)(name->pdata), name->len,
2595 "Select a library", "Libraries");
2596 if(lib_name != NULL) {
2597 for(i=0;i<nb;i++){
2598 if(strcmp(lib_name, lib_info[i].name) == 0) {
2599 library = lttv_library_get(i);
2600 break;
2601 }
2602 }
2603 }
2604 g_ptr_array_free(name, TRUE);
2605 g_free(lib_info);
2606
2607 if(lib_name == NULL) return;
2608
2609 if(library != NULL) lttv_library_unload(library);
2610 }
2611
2612
2613 /* Dispaly a file selection dialogue to let user select a module, then call
2614 * lttv_module_require().
2615 */
2616
2617 void
2618 on_load_module_activate (GtkMenuItem *menuitem,
2619 gpointer user_data)
2620 {
2621 GError *error = NULL;
2622 MainWindow * mw_data = get_window_data_struct((GtkWidget*)menuitem);
2623
2624 LttvLibrary *library = NULL;
2625 {
2626 GPtrArray *name;
2627 guint nb,i;
2628 gchar *lib_name;
2629 name = g_ptr_array_new();
2630 nb = lttv_library_number();
2631 LttvLibraryInfo *lib_info = g_new(LttvLibraryInfo,nb);
2632 /* ask for the library name */
2633
2634 for(i=0;i<nb;i++){
2635 LttvLibrary *iter_lib = lttv_library_get(i);
2636 lttv_library_info(iter_lib, &lib_info[i]);
2637
2638 gchar *path = lib_info[i].name;
2639 g_ptr_array_add(name, path);
2640 }
2641 lib_name = get_selection(mw_data,(char **)(name->pdata), name->len,
2642 "Select a library", "Libraries");
2643 if(lib_name != NULL) {
2644 for(i=0;i<nb;i++){
2645 if(strcmp(lib_name, lib_info[i].name) == 0) {
2646 library = lttv_library_get(i);
2647 break;
2648 }
2649 }
2650 }
2651 g_ptr_array_free(name, TRUE);
2652 g_free(lib_info);
2653
2654 if(lib_name == NULL) return;
2655 }
2656
2657 //LttvModule *module;
2658 gchar module_name_out[PATH_MAX];
2659 {
2660 /* Ask for the module to load : list modules in the selected lib */
2661 GPtrArray *name;
2662 guint nb,i;
2663 gchar *module_name;
2664 nb = lttv_library_module_number(library);
2665 LttvModuleInfo *module_info = g_new(LttvModuleInfo,nb);
2666 name = g_ptr_array_new();
2667 /* ask for the module name */
2668
2669 for(i=0;i<nb;i++){
2670 LttvModule *iter_module = lttv_library_module_get(library, i);
2671 lttv_module_info(iter_module, &module_info[i]);
2672
2673 gchar *path = module_info[i].name;
2674 g_ptr_array_add(name, path);
2675 }
2676 module_name = get_selection(mw_data, (char **)(name->pdata), name->len,
2677 "Select a module", "Modules");
2678 if(module_name != NULL) {
2679 for(i=0;i<nb;i++){
2680 if(strcmp(module_name, module_info[i].name) == 0) {
2681 strncpy(module_name_out, module_name, PATH_MAX);
2682 //module = lttv_library_module_get(i);
2683 break;
2684 }
2685 }
2686 }
2687
2688 g_ptr_array_free(name, TRUE);
2689 g_free(module_info);
2690
2691 if(module_name == NULL) return;
2692 }
2693
2694 lttv_module_require(module_name_out, &error);
2695 if(error != NULL) g_warning("%s", error->message);
2696 else g_info("Load module: %s", module_name_out);
2697
2698
2699 #if 0
2700 {
2701
2702
2703 gchar str[PATH_MAX];
2704 gchar ** dir;
2705 gint id;
2706 GtkFileSelection * file_selector =
2707 (GtkFileSelection *)gtk_file_selection_new("Select a module");
2708 gtk_file_selection_set_filename(file_selector, load_module_path_alter);
2709 gtk_file_selection_hide_fileop_buttons(file_selector);
2710
2711 str[0] = '\0';
2712 id = gtk_dialog_run(GTK_DIALOG(file_selector));
2713 switch(id){
2714 case GTK_RESPONSE_ACCEPT:
2715 case GTK_RESPONSE_OK:
2716 dir = gtk_file_selection_get_selections (file_selector);
2717 strncpy(str,dir[0],PATH_MAX);
2718 strncpy(remember_plugins_dir,dir[0],PATH_MAX);
2719 {
2720 /* only keep file name */
2721 gchar *str1;
2722 str1 = strrchr(str,'/');
2723 if(str1)str1++;
2724 else{
2725 str1 = strrchr(str,'\\');
2726 str1++;
2727 }
2728 #if 0
2729 /* remove "lib" */
2730 if(*str1 == 'l' && *(str1+1)== 'i' && *(str1+2)=='b')
2731 str1=str1+3;
2732 remove info after . */
2733 {
2734 gchar *str2 = str1;
2735
2736 str2 = strrchr(str2, '.');
2737 if(str2 != NULL) *str2 = '\0';
2738 }
2739 lttv_module_require(str1, &error);
2740 #endif //0
2741 lttv_library_load(str1, &error);
2742 if(error != NULL) g_warning(error->message);
2743 else g_info("Load library: %s\n", str);
2744 g_strfreev(dir);
2745 case GTK_RESPONSE_REJECT:
2746 case GTK_RESPONSE_CANCEL:
2747 default:
2748 gtk_widget_destroy((GtkWidget*)file_selector);
2749 break;
2750 }
2751
2752 }
2753 #endif //0
2754
2755
2756 }
2757
2758
2759
2760 /* Display all loaded modules, let user to select a module to unload
2761 * by calling lttv_module_unload
2762 */
2763
2764 void
2765 on_unload_module_activate (GtkMenuItem *menuitem,
2766 gpointer user_data)
2767 {
2768 MainWindow * mw_data = get_window_data_struct((GtkWidget*)menuitem);
2769
2770 LttvLibrary *library = NULL;
2771 {
2772 GPtrArray *name;
2773 guint nb,i;
2774 gchar *lib_name;
2775 name = g_ptr_array_new();
2776 nb = lttv_library_number();
2777 LttvLibraryInfo *lib_info = g_new(LttvLibraryInfo,nb);
2778 /* ask for the library name */
2779
2780 for(i=0;i<nb;i++){
2781 LttvLibrary *iter_lib = lttv_library_get(i);
2782 lttv_library_info(iter_lib, &lib_info[i]);
2783
2784 gchar *path = lib_info[i].name;
2785 g_ptr_array_add(name, path);
2786 }
2787 lib_name = get_selection(mw_data, (char **)(name->pdata), name->len,
2788 "Select a library", "Libraries");
2789 if(lib_name != NULL) {
2790 for(i=0;i<nb;i++){
2791 if(strcmp(lib_name, lib_info[i].name) == 0) {
2792 library = lttv_library_get(i);
2793 break;
2794 }
2795 }
2796 }
2797 g_ptr_array_free(name, TRUE);
2798 g_free(lib_info);
2799
2800 if(lib_name == NULL) return;
2801 }
2802
2803 LttvModule *module = NULL;
2804 {
2805 /* Ask for the module to load : list modules in the selected lib */
2806 GPtrArray *name;
2807 guint nb,i;
2808 gchar *module_name;
2809 nb = lttv_library_module_number(library);
2810 LttvModuleInfo *module_info = g_new(LttvModuleInfo,nb);
2811 name = g_ptr_array_new();
2812 /* ask for the module name */
2813
2814 for(i=0;i<nb;i++){
2815 LttvModule *iter_module = lttv_library_module_get(library, i);
2816 lttv_module_info(iter_module, &module_info[i]);
2817
2818 gchar *path = module_info[i].name;
2819 if(module_info[i].use_count > 0) g_ptr_array_add(name, path);
2820 }
2821 module_name = get_selection(mw_data, (char **)(name->pdata), name->len,
2822 "Select a module", "Modules");
2823 if(module_name != NULL) {
2824 for(i=0;i<nb;i++){
2825 if(strcmp(module_name, module_info[i].name) == 0) {
2826 module = lttv_library_module_get(library, i);
2827 break;
2828 }
2829 }
2830 }
2831
2832 g_ptr_array_free(name, TRUE);
2833 g_free(module_info);
2834
2835 if(module_name == NULL) return;
2836 }
2837
2838 LttvModuleInfo module_info;
2839 lttv_module_info(module, &module_info);
2840 g_info("Release module: %s\n", module_info.name);
2841
2842 lttv_module_release(module);
2843 }
2844
2845
2846 /* Display a directory dialogue to let user select a path for library searching
2847 */
2848
2849 void
2850 on_add_library_search_path_activate (GtkMenuItem *menuitem,
2851 gpointer user_data)
2852 {
2853 MainWindow * mw_data = get_window_data_struct((GtkWidget*)menuitem);
2854 //GtkDirSelection * file_selector = (GtkDirSelection *)gtk_dir_selection_new("Select library path");
2855 GtkFileSelection * file_selector = (GtkFileSelection *)gtk_file_selection_new("Select a trace");
2856 gtk_widget_hide( (file_selector)->file_list->parent) ;
2857
2858 gtk_window_set_transient_for(GTK_WINDOW(file_selector),
2859 GTK_WINDOW(mw_data->mwindow));
2860
2861 const char * dir;
2862 gint id;
2863
2864 if(remember_plugins_dir[0] != '\0')
2865 gtk_file_selection_set_filename(file_selector, remember_plugins_dir);
2866
2867 id = gtk_dialog_run(GTK_DIALOG(file_selector));
2868 switch(id){
2869 case GTK_RESPONSE_ACCEPT:
2870 case GTK_RESPONSE_OK:
2871 dir = gtk_file_selection_get_filename (file_selector);
2872 strncpy(remember_plugins_dir,dir,PATH_MAX);
2873 strncat(remember_plugins_dir,"/",PATH_MAX);
2874 lttv_library_path_add(dir);
2875 case GTK_RESPONSE_REJECT:
2876 case GTK_RESPONSE_CANCEL:
2877 default:
2878 gtk_widget_destroy((GtkWidget*)file_selector);
2879 break;
2880 }
2881 }
2882
2883
2884 /* Display a directory dialogue to let user select a path for library searching
2885 */
2886
2887 void
2888 on_remove_library_search_path_activate (GtkMenuItem *menuitem,
2889 gpointer user_data)
2890 {
2891 MainWindow * mw_data = get_window_data_struct((GtkWidget*)menuitem);
2892
2893 const char *lib_path;
2894 {
2895 GPtrArray *name;
2896 guint nb,i;
2897 name = g_ptr_array_new();
2898 nb = lttv_library_path_number();
2899 /* ask for the library name */
2900
2901 for(i=0;i<nb;i++){
2902 gchar *path = lttv_library_path_get(i);
2903 g_ptr_array_add(name, path);
2904 }
2905 lib_path = get_selection(mw_data, (char **)(name->pdata), name->len,
2906 "Select a library path", "Library paths");
2907
2908 g_ptr_array_free(name, TRUE);
2909
2910 if(lib_path == NULL) return;
2911 }
2912
2913 lttv_library_path_remove(lib_path);
2914 }
2915
2916 void
2917 on_color_activate (GtkMenuItem *menuitem,
2918 gpointer user_data)
2919 {
2920 g_info("Color\n");
2921 }
2922
2923
2924 void
2925 on_save_configuration_activate (GtkMenuItem *menuitem,
2926 gpointer user_data)
2927 {
2928 g_info("Save configuration\n");
2929 }
2930
2931
2932 void
2933 on_content_activate (GtkMenuItem *menuitem,
2934 gpointer user_data)
2935 {
2936 char* filename = NULL,
2937 *path;
2938 GdkScreen *screen;
2939 const char* relativePath = "doc/user/user_guide/html/index.html";
2940 filename = g_build_filename (g_get_current_dir(), relativePath, NULL);
2941 path = g_strdup_printf ("ghelp://%s", filename);
2942
2943 screen = gdk_screen_get_default();
2944 gtk_show_uri (screen, path, gtk_get_current_event_time(), NULL);
2945
2946 g_free(filename);
2947 g_free(path);
2948 g_info("Content\n");
2949 }
2950
2951
2952 static void
2953 on_about_close_activate (GtkButton *button,
2954 gpointer user_data)
2955 {
2956 GtkWidget *about_widget = GTK_WIDGET(user_data);
2957
2958 gtk_widget_destroy(about_widget);
2959 }
2960
2961 void
2962 on_about_activate (GtkMenuItem *menuitem,
2963 gpointer user_data)
2964 {
2965 MainWindow *main_window = get_window_data_struct(GTK_WIDGET(menuitem));
2966 GtkWidget *window_widget = main_window->mwindow;
2967 GtkWidget *about_widget = gtk_window_new(GTK_WINDOW_TOPLEVEL);
2968 GtkWindow *about_window = GTK_WINDOW(about_widget);
2969
2970 gtk_window_set_title(about_window, "About Linux Trace Toolkit");
2971
2972 gtk_window_set_resizable(about_window, FALSE);
2973 gtk_window_set_transient_for(about_window, GTK_WINDOW(window_widget));
2974 gtk_window_set_destroy_with_parent(about_window, TRUE);
2975 gtk_window_set_modal(about_window, FALSE);
2976
2977 /* Put the about window at the center of the screen */
2978 gtk_window_set_position(about_window, GTK_WIN_POS_CENTER_ALWAYS);
2979
2980 GtkWidget *vbox = gtk_vbox_new(FALSE, 1);
2981
2982 gtk_container_add(GTK_CONTAINER(about_widget), vbox);
2983
2984 /* Text to show */
2985 GtkWidget *label1 = gtk_label_new("");
2986 gtk_misc_set_padding(GTK_MISC(label1), 10, 20);
2987 gtk_label_set_markup(GTK_LABEL(label1), "\
2988 <big>Linux Trace Toolkit " VERSION "</big>");
2989 gtk_label_set_justify(GTK_LABEL(label1), GTK_JUSTIFY_CENTER);
2990
2991 GtkWidget *label2 = gtk_label_new("");
2992 gtk_misc_set_padding(GTK_MISC(label2), 10, 20);
2993 gtk_label_set_markup(GTK_LABEL(label2), "\
2994 Contributors :\n\
2995 \n\
2996 Michel Dagenais (New trace format, lttv main)\n\
2997 Mathieu Desnoyers (Kernel Tracer, Directory structure, build with automake/conf,\n\
2998 lttv gui, control flow view, gui cooperative trace reading\n\
2999 scheduler with interruptible foreground and background\n\
3000 computation, detailed event list (rewrite), trace reading\n\
3001 library (rewrite))\n\
3002 Benoit Des Ligneris, Eric Clement (Cluster adaptation, work in progress)\n\
3003 Xang-Xiu Yang (new trace reading library and converter, lttv gui, \n\
3004 detailed event list and statistics view)\n\
3005 Tom Zanussi (RelayFS)\n\
3006 \n\
3007 Inspired from the original Linux Trace Toolkit Visualizer made by\n\
3008 Karim Yaghmour");
3009
3010 GtkWidget *label3 = gtk_label_new("");
3011 gtk_label_set_markup(GTK_LABEL(label3), "\
3012 Linux Trace Toolkit Viewer, Copyright (C) 2004, 2005, 2006\n\
3013 Michel Dagenais\n\
3014 Mathieu Desnoyers\n\
3015 Xang-Xiu Yang\n\
3016 Linux Trace Toolkit comes with ABSOLUTELY NO WARRANTY.\n\
3017 This is free software, and you are welcome to redistribute it\n\
3018 under certain conditions. See COPYING for details.");
3019 gtk_misc_set_padding(GTK_MISC(label3), 10, 20);
3020
3021 gtk_box_pack_start_defaults(GTK_BOX(vbox), label1);
3022 gtk_box_pack_start_defaults(GTK_BOX(vbox), label2);
3023 gtk_box_pack_start_defaults(GTK_BOX(vbox), label3);
3024
3025 GtkWidget *hbox = gtk_hbox_new(TRUE, 0);
3026 gtk_box_pack_end(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
3027 GtkWidget *close_button = gtk_button_new_with_mnemonic("_Close");
3028 gtk_box_pack_end(GTK_BOX(hbox), close_button, FALSE, FALSE, 0);
3029 gtk_container_set_border_width(GTK_CONTAINER(close_button), 20);
3030
3031 g_signal_connect(G_OBJECT(close_button), "clicked",
3032 G_CALLBACK(on_about_close_activate),
3033 (gpointer)about_widget);
3034
3035 gtk_widget_show_all(about_widget);
3036 }
3037
3038
3039 void
3040 on_button_new_clicked (GtkButton *button,
3041 gpointer user_data)
3042 {
3043 create_new_window((GtkWidget*)button, user_data, TRUE);
3044 }
3045
3046 void
3047 on_button_new_tab_clicked (GtkButton *button,
3048 gpointer user_data)
3049 {
3050 create_new_tab((GtkWidget*)button, user_data);
3051 }
3052
3053 void
3054 on_button_open_clicked (GtkButton *button,
3055 gpointer user_data)
3056 {
3057 #ifdef UNFINISHED_FEATURE
3058 open_traceset((GtkWidget*)button, user_data);
3059 #endif
3060 }
3061
3062
3063 void
3064 on_button_add_trace_clicked (GtkButton *button,
3065 gpointer user_data)
3066 {
3067 add_trace((GtkWidget*)button, user_data);
3068 }
3069
3070
3071 void
3072 on_button_remove_trace_clicked (GtkButton *button,
3073 gpointer user_data)
3074 {
3075 remove_trace((GtkWidget*)button, user_data);
3076 }
3077
3078 void
3079 on_button_redraw_clicked (GtkButton *button,
3080 gpointer user_data)
3081 {
3082 redraw((GtkWidget*)button, user_data);
3083 }
3084
3085 void
3086 on_button_continue_processing_clicked (GtkButton *button,
3087 gpointer user_data)
3088 {
3089 continue_processing((GtkWidget*)button, user_data);
3090 }
3091
3092 void
3093 on_button_stop_processing_clicked (GtkButton *button,
3094 gpointer user_data)
3095 {
3096 stop_processing((GtkWidget*)button, user_data);
3097 }
3098
3099
3100
3101 void
3102 on_button_save_clicked (GtkButton *button,
3103 gpointer user_data)
3104 {
3105 save((GtkWidget*)button, user_data);
3106 }
3107
3108
3109 void
3110 on_button_save_as_clicked (GtkButton *button,
3111 gpointer user_data)
3112 {
3113 save_as((GtkWidget*)button, user_data);
3114 }
3115
3116
3117 void
3118 on_button_zoom_in_clicked (GtkButton *button,
3119 gpointer user_data)
3120 {
3121 zoom_in((GtkWidget*)button, user_data);
3122 }
3123
3124
3125 void
3126 on_button_zoom_out_clicked (GtkButton *button,
3127 gpointer user_data)
3128 {
3129 zoom_out((GtkWidget*)button, user_data);
3130 }
3131
3132
3133 void
3134 on_button_zoom_extended_clicked (GtkButton *button,
3135 gpointer user_data)
3136 {
3137 zoom_extended((GtkWidget*)button, user_data);
3138 }
3139
3140
3141 void
3142 on_button_go_to_time_clicked (GtkButton *button,
3143 gpointer user_data)
3144 {
3145 go_to_time((GtkWidget*)button, user_data);
3146 }
3147
3148
3149 void
3150 on_button_show_time_frame_clicked (GtkButton *button,
3151 gpointer user_data)
3152 {
3153 show_time_frame((GtkWidget*)button, user_data);
3154 }
3155
3156
3157 void
3158 on_button_move_up_clicked (GtkButton *button,
3159 gpointer user_data)
3160 {
3161 move_up_viewer((GtkWidget*)button, user_data);
3162 }
3163
3164
3165 void
3166 on_button_move_down_clicked (GtkButton *button,
3167 gpointer user_data)
3168 {
3169 move_down_viewer((GtkWidget*)button, user_data);
3170 }
3171
3172
3173 void
3174 on_button_delete_viewer_clicked (GtkButton *button,
3175 gpointer user_data)
3176 {
3177 delete_viewer((GtkWidget*)button, user_data);
3178 }
3179
3180 void
3181 on_MWindow_destroy (GtkWidget *widget,
3182 gpointer user_data)
3183 {
3184 MainWindow *main_window = get_window_data_struct(widget);
3185 LttvIAttribute *attributes = main_window->attributes;
3186 LttvAttributeValue value;
3187 gboolean retval;
3188
3189 //This is unnecessary, since widgets will be destroyed
3190 //by the main window widget anyway.
3191 //remove_all_menu_toolbar_constructors(main_window, NULL);
3192
3193 retval= lttv_iattribute_find_by_path(attributes, "viewers/menu",
3194 LTTV_POINTER, &value);
3195 g_assert(retval);
3196 lttv_menus_destroy((LttvMenus*)*(value.v_pointer));
3197
3198 retval= lttv_iattribute_find_by_path(attributes, "viewers/toolbar",
3199 LTTV_POINTER, &value);
3200 g_assert(retval);
3201 lttv_toolbars_destroy((LttvToolbars*)*(value.v_pointer));
3202
3203 g_object_unref(main_window->attributes);
3204 g_main_window_list = g_slist_remove(g_main_window_list, main_window);
3205
3206 g_info("There are now : %d windows\n",g_slist_length(g_main_window_list));
3207 if(g_slist_length(g_main_window_list) == 0)
3208 mainwindow_quit();
3209 }
3210
3211 gboolean
3212 on_MWindow_configure (GtkWidget *widget,
3213 GdkEventConfigure *event,
3214 gpointer user_data)
3215 {
3216 // MD : removed time width modification upon resizing of the main window.
3217 // The viewers will redraw themselves completely, without time interval
3218 // modification.
3219 /* while(tab){
3220 if(mw_data->window_width){
3221 time_span = LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context)->Time_Span ;
3222 time_win = tab->time_window;
3223 ratio = width / mw_data->window_width;
3224 tab->time_window.time_width = ltt_time_mul(time_win.time_width,ratio);
3225 time = ltt_time_sub(time_span->endTime, time_win.start_time);
3226 if(ltt_time_compare(time, tab->time_window.time_width) < 0){
3227 tab->time_window.time_width = time;
3228 }
3229 }
3230 tab = tab->next;
3231 }
3232
3233 mw_data->window_width = (int)width;
3234 */
3235 return FALSE;
3236 }
3237
3238 /* Set current tab
3239 */
3240
3241 void
3242 on_MNotebook_switch_page (GtkNotebook *notebook,
3243 GtkNotebookPage *page,
3244 guint page_num,
3245 gpointer user_data)
3246 {
3247
3248 }
3249
3250
3251 void time_change_manager (Tab *tab,
3252 TimeWindow new_time_window)
3253 {
3254
3255 /* Only one source of time change */
3256 if(tab->time_manager_lock == TRUE) return;
3257
3258 tab->time_manager_lock = TRUE;
3259 TimeInterval time_span;
3260
3261 LttvTraceset *ts = tab->traceset_info->traceset;
3262 time_span.start_time =ltt_time_from_uint64( lttv_traceset_get_timestamp_begin(ts));
3263 time_span.end_time = ltt_time_from_uint64(lttv_traceset_get_timestamp_end(ts));
3264
3265
3266 LttTime start_time = new_time_window.start_time;
3267 LttTime end_time = new_time_window.end_time;
3268
3269 g_assert(ltt_time_compare(start_time, end_time) < 0);
3270
3271 /* Set scrollbar */
3272 GtkAdjustment *adjustment = gtk_range_get_adjustment(GTK_RANGE(tab->scrollbar));
3273 LttTime upper = ltt_time_sub(time_span.end_time, time_span.start_time);
3274
3275 #if 0
3276 gtk_range_set_increments(GTK_RANGE(tab->scrollbar),
3277 ltt_time_to_double(new_time_window.time_width)
3278 / SCROLL_STEP_PER_PAGE
3279 * NANOSECONDS_PER_SECOND, /* step increment */
3280 ltt_time_to_double(new_time_window.time_width)
3281 * NANOSECONDS_PER_SECOND); /* page increment */
3282 gtk_range_set_range(GTK_RANGE(tab->scrollbar),
3283 0.0, /* lower */
3284 ltt_time_to_double(upper)
3285 * NANOSECONDS_PER_SECOND); /* upper */
3286 #endif //0
3287 g_object_set(G_OBJECT(adjustment),
3288 "lower",
3289 0.0, /* lower */
3290 "upper",
3291 ltt_time_to_double(upper), /* upper */
3292 "step_increment",
3293 new_time_window.time_width_double
3294 / SCROLL_STEP_PER_PAGE, /* step increment */
3295 "page_increment",
3296 new_time_window.time_width_double,
3297 /* page increment */
3298 "page_size",
3299 new_time_window.time_width_double, /* page size */
3300 NULL);
3301 gtk_adjustment_changed(adjustment);
3302
3303 // g_object_set(G_OBJECT(adjustment),
3304 // "value",
3305 // ltt_time_to_double(
3306 // ltt_time_sub(start_time, time_span.start_time))
3307 // , /* value */
3308 // NULL);
3309 //gtk_adjustment_value_changed(adjustment);
3310 gtk_range_set_value(GTK_RANGE(tab->scrollbar),
3311 ltt_time_to_double(
3312 ltt_time_sub(start_time, time_span.start_time)) /* value */);
3313
3314 /* set the time bar. */
3315
3316
3317 timebar_set_minmax_time(TIMEBAR(tab->MTimebar),
3318 &time_span.start_time,
3319 &time_span.end_time );
3320 timebar_set_start_time(TIMEBAR(tab->MTimebar),&start_time);
3321 timebar_set_end_time(TIMEBAR(tab->MTimebar),&end_time);
3322
3323
3324
3325 /* call viewer hooks for new time window */
3326 set_time_window(tab, &new_time_window);
3327
3328 tab->time_manager_lock = FALSE;
3329
3330
3331 }
3332
3333
3334
3335
3336
3337 void current_time_change_manager (Tab *tab,
3338 LttTime new_current_time)
3339 {
3340 /* Only one source of time change */
3341 if(tab->current_time_manager_lock == TRUE) return;
3342
3343 tab->current_time_manager_lock = TRUE;
3344
3345 timebar_set_current_time(TIMEBAR(tab->MTimebar), &new_current_time);
3346
3347 set_current_time(tab, &new_current_time);
3348
3349 tab->current_time_manager_lock = FALSE;
3350 }
3351
3352 void current_position_change_manager(Tab *tab,
3353 LttvTracesetPosition *pos)
3354 {
3355 #ifdef BABEL_CLEANUP
3356 LttvTracesetContext *tsc =
3357 LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context);
3358 int retval;
3359
3360 retval= lttv_process_traceset_seek_position(tsc, pos);
3361 g_assert_cmpint(retval, ==, 0);
3362 LttTime new_time = lttv_traceset_context_position_get_time(pos);
3363 /* Put the context in a state coherent position */
3364 lttv_state_traceset_seek_time_closest((LttvTracesetState*)tsc, ltt_time_zero);
3365
3366 current_time_change_manager(tab, new_time);
3367
3368 set_current_position(tab, pos);
3369 #endif /* BABEL_CLEANUP */
3370 }
3371
3372 static void on_timebar_starttime_changed(Timebar *timebar,
3373 gpointer user_data)
3374 {
3375 #ifdef BABEL_CLEANUP
3376 Tab *tab = (Tab *)user_data;
3377 LttvTracesetContext * tsc =
3378 LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context);
3379 TimeInterval time_span = tsc->time_span;
3380
3381 TimeWindow new_time_window = tab->time_window;
3382 new_time_window.start_time = timebar_get_start_time(timebar);
3383
3384 LttTime end_time = new_time_window.end_time;
3385
3386 /* TODO ybrosseau 2010-12-02: This if should have been checked
3387 by the timebar already */
3388 if(ltt_time_compare(new_time_window.start_time, end_time) >= 0) {
3389 /* Then, we must push back end time : keep the same time width
3390 * if possible, else end traceset time */
3391 end_time = LTT_TIME_MIN(ltt_time_add(new_time_window.start_time,
3392 new_time_window.time_width),
3393 time_span.end_time);
3394 }
3395
3396 /* Fix the time width to fit start time and end time */
3397 new_time_window.time_width = ltt_time_sub(end_time,
3398 new_time_window.start_time);
3399
3400 new_time_window.time_width_double =
3401 ltt_time_to_double(new_time_window.time_width);
3402
3403 new_time_window.end_time = end_time;
3404
3405 /* Notify the time_manager */
3406 time_change_manager(tab, new_time_window);
3407 #endif /* BABEL_CLEANUP */
3408 }
3409
3410 static void on_timebar_endtime_changed(Timebar *timebar,
3411 gpointer user_data)
3412 {
3413 #ifdef BABEL_CLEANUP
3414 Tab *tab = (Tab *)user_data;
3415 LttvTracesetContext * tsc =
3416 LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context);
3417 TimeInterval time_span = tsc->time_span;
3418
3419 TimeWindow new_time_window = tab->time_window;
3420
3421 LttTime end_time = timebar_get_end_time(timebar);
3422
3423 /* TODO ybrosseau 2010-12-02: This if should have been
3424 checked by the timebar already */
3425 if(ltt_time_compare(new_time_window.start_time, end_time) >= 0) {
3426 /* Then, we must push front start time : keep the same time
3427 width if possible, else end traceset time */
3428 new_time_window.start_time = LTT_TIME_MAX(
3429 ltt_time_sub(end_time,
3430 new_time_window.time_width),
3431 time_span.start_time);
3432 }
3433
3434 /* Fix the time width to fit start time and end time */
3435 new_time_window.time_width = ltt_time_sub(end_time,
3436 new_time_window.start_time);
3437
3438 new_time_window.time_width_double =
3439 ltt_time_to_double(new_time_window.time_width);
3440
3441 new_time_window.end_time = end_time;
3442
3443 /* Notify the time_manager */
3444 time_change_manager(tab, new_time_window);
3445 #endif /* BABEL_CLEANUP*/
3446 }
3447 static void on_timebar_currenttime_changed(Timebar *timebar,
3448 gpointer user_data)
3449 {
3450 Tab *tab = (Tab *)user_data;
3451
3452 LttTime new_current_time = timebar_get_current_time(timebar);
3453
3454 current_time_change_manager(tab, new_current_time);
3455 }
3456
3457 void scroll_value_changed_cb(GtkWidget *scrollbar,
3458 gpointer user_data)
3459 {
3460 #ifdef BABEL_CLEANUP
3461 Tab *tab = (Tab *)user_data;
3462 TimeWindow new_time_window;
3463 LttTime time;
3464 GtkAdjustment *adjust = gtk_range_get_adjustment(GTK_RANGE(scrollbar));
3465 gdouble value = gtk_adjustment_get_value(adjust);
3466 // gdouble upper, lower, ratio, page_size;
3467 gdouble page_size;
3468 LttvTracesetContext * tsc =
3469 LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context);
3470 TimeInterval time_span = tsc->time_span;
3471
3472 time = ltt_time_add(ltt_time_from_double(value),
3473 time_span.start_time);
3474
3475 new_time_window.start_time = time;
3476
3477 page_size = adjust->page_size;
3478
3479 new_time_window.time_width =
3480 ltt_time_from_double(page_size);
3481
3482 new_time_window.time_width_double =
3483 page_size;
3484
3485 new_time_window.end_time = ltt_time_add(new_time_window.start_time,
3486 new_time_window.time_width);
3487
3488
3489 time_change_manager(tab, new_time_window);
3490 #if 0
3491 //time_window = tab->time_window;
3492
3493 lower = adjust->lower;
3494 upper = adjust->upper;
3495 ratio = (value - lower) / (upper - lower);
3496 g_info("lower %lu, upper %lu, value %lu, ratio %lu", lower, upper, value, ratio);
3497
3498 //time = ltt_time_sub(time_span->end_time, time_span->start_time);
3499 //time = ltt_time_mul(time, (float)ratio);
3500 //time = ltt_time_add(time_span->start_time, time);
3501 time = ltt_time_add(ltt_time_from_double(value),
3502 time_span.start_time);
3503
3504 time_window.start_time = time;
3505
3506 page_size = adjust->page_size;
3507
3508 time_window.time_width =
3509 ltt_time_from_double(page_size);
3510 //time = ltt_time_sub(time_span.end_time, time);
3511 //if(ltt_time_compare(time,time_window.time_width) < 0){
3512 // time_window.time_width = time;
3513 //}
3514
3515 /* call viewer hooks for new time window */
3516 set_time_window(tab, &time_window);
3517 #endif //0
3518 #endif /* BABEL_CLEANUP */
3519 }
3520
3521
3522 /* Display a dialogue showing all eventtypes and traces, let user to select the interested
3523 * eventtypes, tracefiles and traces (filter)
3524 */
3525
3526 /* Select a trace which will be removed from traceset
3527 */
3528
3529 char * get_remove_trace(MainWindow *mw_data,
3530 char ** all_trace_name, int nb_trace)
3531 {
3532 return get_selection(mw_data, all_trace_name, nb_trace,
3533 "Select a trace", "Trace pathname");
3534 }
3535
3536
3537 /* Select a module which will be loaded
3538 */
3539
3540 char * get_load_module(MainWindow *mw_data,
3541 char ** load_module_name, int nb_module)
3542 {
3543 return get_selection(mw_data, load_module_name, nb_module,
3544 "Select a module to load", "Module name");
3545 }
3546
3547
3548
3549
3550 /* Select a module which will be unloaded
3551 */
3552
3553 char * get_unload_module(MainWindow *mw_data,
3554 char ** loaded_module_name, int nb_module)
3555 {
3556 return get_selection(mw_data, loaded_module_name, nb_module,
3557 "Select a module to unload", "Module name");
3558 }
3559
3560
3561 /* Display a dialogue which shows all selectable items, let user to
3562 * select one of them
3563 */
3564
3565 char * get_selection(MainWindow *mw_data,
3566 char ** loaded_module_name, int nb_module,
3567 char *title, char * column_title)
3568 {
3569 GtkWidget * dialogue;
3570 GtkWidget * scroll_win;
3571 GtkWidget * tree;
3572 GtkListStore * store;
3573 GtkTreeViewColumn * column;
3574 GtkCellRenderer * renderer;
3575 GtkTreeSelection * select;
3576 GtkTreeIter iter;
3577 gint id, i;
3578 char * unload_module_name = NULL;
3579
3580 dialogue = gtk_dialog_new_with_buttons(title,
3581 NULL,
3582 GTK_DIALOG_MODAL,
3583 GTK_STOCK_OK,GTK_RESPONSE_ACCEPT,
3584 GTK_STOCK_CANCEL,GTK_RESPONSE_REJECT,
3585 NULL);
3586 gtk_window_set_default_size((GtkWindow*)dialogue, 500, 200);
3587 gtk_window_set_transient_for(GTK_WINDOW(dialogue),
3588 GTK_WINDOW(mw_data->mwindow));
3589
3590 scroll_win = gtk_scrolled_window_new (NULL, NULL);
3591 gtk_widget_show ( scroll_win);
3592 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll_win),
3593 GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
3594
3595 store = gtk_list_store_new (N_COLUMNS,G_TYPE_STRING);
3596 tree = gtk_tree_view_new_with_model(GTK_TREE_MODEL (store));
3597 gtk_widget_show ( tree);
3598 g_object_unref (G_OBJECT (store));
3599
3600 renderer = gtk_cell_renderer_text_new ();
3601 column = gtk_tree_view_column_new_with_attributes (column_title,
3602 renderer,
3603 "text", MODULE_COLUMN,
3604 NULL);
3605 gtk_tree_view_column_set_alignment (column, 0.5);
3606 gtk_tree_view_column_set_fixed_width (column, 150);
3607 gtk_tree_view_append_column (GTK_TREE_VIEW (tree), column);
3608
3609 select = gtk_tree_view_get_selection (GTK_TREE_VIEW (tree));
3610 gtk_tree_selection_set_mode (select, GTK_SELECTION_SINGLE);
3611
3612 gtk_container_add (GTK_CONTAINER (scroll_win), tree);
3613
3614 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialogue)->vbox), scroll_win,TRUE, TRUE,0);
3615
3616 for(i=0;i<nb_module;i++){
3617 gtk_list_store_append (store, &iter);
3618 gtk_list_store_set (store, &iter, MODULE_COLUMN,loaded_module_name[i],-1);
3619 }
3620
3621 id = gtk_dialog_run(GTK_DIALOG(dialogue));
3622 GtkTreeModel **store_model = (GtkTreeModel**)&store;
3623 switch(id){
3624 case GTK_RESPONSE_ACCEPT:
3625 case GTK_RESPONSE_OK:
3626 if (gtk_tree_selection_get_selected (select, store_model, &iter)){
3627 gtk_tree_model_get ((GtkTreeModel*)store, &iter, MODULE_COLUMN, &unload_module_name, -1);
3628 }
3629 case GTK_RESPONSE_REJECT:
3630 case GTK_RESPONSE_CANCEL:
3631 default:
3632 gtk_widget_destroy(dialogue);
3633 break;
3634 }
3635
3636 return unload_module_name;
3637 }
3638
3639
3640 /* Insert all menu entry and tool buttons into this main window
3641 * for modules.
3642 *
3643 */
3644
3645 void add_all_menu_toolbar_constructors(MainWindow * mw, gpointer user_data)
3646 {
3647 guint i;
3648 GdkPixbuf *pixbuf;
3649 lttvwindow_viewer_constructor constructor;
3650 LttvMenus * global_menu, * instance_menu;
3651 LttvToolbars * global_toolbar, * instance_toolbar;
3652 LttvMenuClosure *menu_item;
3653 LttvToolbarClosure *toolbar_item;
3654 LttvAttributeValue value;
3655 LttvIAttribute *global_attributes = LTTV_IATTRIBUTE(lttv_global_attributes());
3656 LttvIAttribute *attributes = mw->attributes;
3657 GtkWidget * tool_menu_title_menu, *new_widget, *pixmap;
3658 gboolean retval;
3659
3660 retval= lttv_iattribute_find_by_path(global_attributes, "viewers/menu",
3661 LTTV_POINTER, &value);
3662 g_assert(retval);
3663 if(*(value.v_pointer) == NULL)
3664 *(value.v_pointer) = lttv_menus_new();
3665 global_menu = (LttvMenus*)*(value.v_pointer);
3666
3667 retval= lttv_iattribute_find_by_path(attributes, "viewers/menu",
3668 LTTV_POINTER, &value);
3669 g_assert(retval);
3670 if(*(value.v_pointer) == NULL)
3671 *(value.v_pointer) = lttv_menus_new();
3672 instance_menu = (LttvMenus*)*(value.v_pointer);
3673
3674 retval= lttv_iattribute_find_by_path(global_attributes, "viewers/toolbar",
3675 LTTV_POINTER, &value);
3676 g_assert(retval);
3677 if(*(value.v_pointer) == NULL)
3678 *(value.v_pointer) = lttv_toolbars_new();
3679 global_toolbar = (LttvToolbars*)*(value.v_pointer);
3680
3681 retval= lttv_iattribute_find_by_path(attributes, "viewers/toolbar",
3682 LTTV_POINTER, &value);
3683 g_assert(retval);
3684 if(*(value.v_pointer) == NULL)
3685 *(value.v_pointer) = lttv_toolbars_new();
3686 instance_toolbar = (LttvToolbars*)*(value.v_pointer);
3687
3688 /* Add missing menu entries to window instance */
3689 for(i=0;i<global_menu->len;i++) {
3690 menu_item = &g_array_index(global_menu, LttvMenuClosure, i);
3691
3692 //add menu_item to window instance;
3693 constructor = menu_item->con;
3694 tool_menu_title_menu = lookup_widget(mw->mwindow,"ToolMenuTitle_menu");
3695 new_widget =
3696 gtk_menu_item_new_with_mnemonic (menu_item->menu_text);
3697 gtk_container_add (GTK_CONTAINER (tool_menu_title_menu),
3698 new_widget);
3699 g_signal_connect ((gpointer) new_widget, "activate",
3700 G_CALLBACK (insert_viewer_wrap),
3701 constructor);
3702 gtk_widget_show (new_widget);
3703 lttv_menus_add(instance_menu, menu_item->con,
3704 menu_item->menu_path,
3705 menu_item->menu_text,
3706 new_widget);
3707
3708 }
3709
3710 /* Add missing toolbar entries to window instance */
3711 for(i=0;i<global_toolbar->len;i++) {
3712 toolbar_item = &g_array_index(global_toolbar, LttvToolbarClosure, i);
3713
3714 //add toolbar_item to window instance;
3715 constructor = toolbar_item->con;
3716 tool_menu_title_menu = lookup_widget(mw->mwindow,"MToolbar1");
3717 pixbuf = gdk_pixbuf_new_from_xpm_data((const char**)toolbar_item->pixmap);
3718 pixmap = gtk_image_new_from_pixbuf(pixbuf);
3719 new_widget =
3720 gtk_toolbar_append_element (GTK_TOOLBAR (tool_menu_title_menu),
3721 GTK_TOOLBAR_CHILD_BUTTON,
3722 NULL,
3723 "",
3724 toolbar_item->tooltip, NULL,
3725 pixmap, NULL, NULL);
3726 gtk_label_set_use_underline(
3727 GTK_LABEL (((GtkToolbarChild*) (
3728 g_list_last (GTK_TOOLBAR
3729 (tool_menu_title_menu)->children)->data))->label),
3730 TRUE);
3731 gtk_container_set_border_width (GTK_CONTAINER (new_widget), 1);
3732 g_signal_connect ((gpointer) new_widget,
3733 "clicked",
3734 G_CALLBACK (insert_viewer_wrap),
3735 constructor);
3736 gtk_widget_show (new_widget);
3737
3738 lttv_toolbars_add(instance_toolbar, toolbar_item->con,
3739 toolbar_item->tooltip,
3740 toolbar_item->pixmap,
3741 new_widget);
3742
3743 }
3744
3745 }
3746
3747
3748 /* Create a main window
3749 */
3750
3751 MainWindow *construct_main_window(MainWindow * parent)
3752 {
3753 gboolean retval;
3754
3755 g_debug("construct_main_window()");
3756 GtkWidget * new_window; /* New generated main window */
3757 MainWindow * new_m_window;/* New main window structure */
3758 GtkNotebook * notebook;
3759 LttvIAttribute *attributes =
3760 LTTV_IATTRIBUTE(g_object_new(LTTV_ATTRIBUTE_TYPE, NULL));
3761 LttvAttributeValue value;
3762
3763 new_m_window = g_new(MainWindow, 1);
3764
3765 // Add the object's information to the module's array
3766 g_main_window_list = g_slist_append(g_main_window_list, new_m_window);
3767
3768 new_window = create_MWindow();
3769 gtk_widget_show (new_window);
3770
3771 new_m_window->mwindow = new_window;
3772 new_m_window->attributes = attributes;
3773
3774 retval= lttv_iattribute_find_by_path(attributes, "viewers/menu",
3775 LTTV_POINTER, &value);
3776 g_assert(retval);
3777 *(value.v_pointer) = lttv_menus_new();
3778
3779 retval= lttv_iattribute_find_by_path(attributes, "viewers/toolbar",
3780 LTTV_POINTER, &value);
3781 g_assert(retval);
3782 *(value.v_pointer) = lttv_toolbars_new();
3783
3784 add_all_menu_toolbar_constructors(new_m_window, NULL);
3785
3786 g_object_set_data_full(G_OBJECT(new_window),
3787 "main_window_data",
3788 (gpointer)new_m_window,
3789 (GDestroyNotify)g_free);
3790 //create a default tab
3791 notebook = (GtkNotebook *)lookup_widget(new_m_window->mwindow, "MNotebook");
3792 if(notebook == NULL){
3793 g_info("Notebook does not exist\n");
3794 /* FIXME : destroy partially created widgets */
3795 g_free(new_m_window);
3796 return NULL;
3797 }
3798 //gtk_notebook_popup_enable (GTK_NOTEBOOK(notebook));
3799 //for now there is no name field in LttvTraceset structure
3800 //Use "Traceset" as the label for the default tab
3801 if(parent) {
3802 GtkWidget * parent_notebook = lookup_widget(parent->mwindow, "MNotebook");
3803 GtkWidget *page = gtk_notebook_get_nth_page(GTK_NOTEBOOK(parent_notebook),
3804 gtk_notebook_get_current_page(GTK_NOTEBOOK(parent_notebook)));
3805 Tab *parent_tab;
3806
3807 if(!page) {
3808 parent_tab = NULL;
3809 } else {
3810 LttvPluginTab *ptab;
3811 ptab = (LttvPluginTab *)g_object_get_data(G_OBJECT(page), "Tab_Plugin");
3812 parent_tab = ptab->tab;
3813 }
3814 LttvPluginTab *ptab = g_object_new(LTTV_TYPE_PLUGIN_TAB, NULL);
3815 init_tab(ptab->tab,
3816 new_m_window, parent_tab, notebook, "Traceset");
3817 ptab->parent.top_widget = ptab->tab->top_widget;
3818 g_object_set_data_full(
3819 G_OBJECT(ptab->tab->vbox),
3820 "Tab_Plugin",
3821 ptab,
3822 (GDestroyNotify)tab_destructor);
3823 } else {
3824 LttvPluginTab *ptab = g_object_new(LTTV_TYPE_PLUGIN_TAB, NULL);
3825 init_tab(ptab->tab, new_m_window, NULL, notebook, "Traceset");
3826 ptab->parent.top_widget = ptab->tab->top_widget;
3827 g_object_set_data_full(
3828 G_OBJECT(ptab->tab->vbox),
3829 "Tab_Plugin",
3830 ptab,
3831 (GDestroyNotify)tab_destructor);
3832 }
3833
3834 /* Insert default viewers */
3835 {
3836 LttvAttributeType type;
3837 LttvAttributeName name;
3838 LttvAttributeValue value;
3839 LttvAttribute *attribute;
3840
3841 LttvIAttribute *attributes_global =
3842 LTTV_IATTRIBUTE(lttv_global_attributes());
3843
3844 attribute = LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
3845 LTTV_IATTRIBUTE(attributes_global),
3846 LTTV_VIEWER_CONSTRUCTORS));
3847 g_assert(attribute);
3848
3849 name = g_quark_from_string("guievents");
3850 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute),
3851 name, &value);
3852 if(type == LTTV_POINTER) {
3853 lttvwindow_viewer_constructor viewer_constructor =
3854 (lttvwindow_viewer_constructor)*value.v_pointer;
3855 insert_viewer(new_window, viewer_constructor);
3856 }
3857
3858 name = g_quark_from_string("guicontrolflow");
3859 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute),
3860 name, &value);
3861 if(type == LTTV_POINTER) {
3862 lttvwindow_viewer_constructor viewer_constructor =
3863 (lttvwindow_viewer_constructor)*value.v_pointer;
3864 insert_viewer(new_window, viewer_constructor);
3865 }
3866
3867 name = g_quark_from_string("guistatistics");
3868 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute),
3869 name, &value);
3870 if(type == LTTV_POINTER) {
3871 lttvwindow_viewer_constructor viewer_constructor =
3872 (lttvwindow_viewer_constructor)*value.v_pointer;
3873 insert_viewer(new_window, viewer_constructor);
3874 }
3875 }
3876
3877 g_info("There are now : %d windows\n",g_slist_length(g_main_window_list));
3878
3879 return new_m_window;
3880 }
3881
3882
3883 /* Free the memory occupied by a tab structure
3884 * destroy the tab
3885 */
3886
3887 void tab_destructor(LttvPluginTab * ptab)
3888 {
3889 #ifdef BABEL_CLEANUP
3890 int i, nb, ref_count;
3891 LttvTrace * trace;
3892 Tab *tab = ptab->tab;
3893
3894 if(tab->attributes)
3895 g_object_unref(tab->attributes);
3896
3897 if(tab->interrupted_state)
3898 g_object_unref(tab->interrupted_state);
3899
3900
3901 if(tab->traceset_info->traceset_context != NULL){
3902 //remove state update hooks
3903 lttv_state_remove_event_hooks(
3904 (LttvTracesetState*)tab->traceset_info->
3905 traceset_context);
3906 lttv_context_fini(LTTV_TRACESET_CONTEXT(tab->traceset_info->
3907 traceset_context));
3908 g_object_unref(tab->traceset_info->traceset_context);
3909 }
3910 if(tab->traceset_info->traceset != NULL) {
3911 nb = lttv_traceset_number(tab->traceset_info->traceset);
3912 for(i = 0 ; i < nb ; i++) {
3913 trace = lttv_traceset_get(tab->traceset_info->traceset, i);
3914 ref_count = lttv_trace_get_ref_number(trace);
3915 if(ref_count <= 1){
3916 ltt_trace_close(lttv_trace(trace));
3917 }
3918 }
3919 }
3920 lttv_traceset_destroy(tab->traceset_info->traceset);
3921 /* Remove the idle events requests processing function of the tab */
3922 g_idle_remove_by_data(tab);
3923
3924 g_slist_free(tab->events_requests);
3925 g_free(tab->traceset_info);
3926 //g_free(tab);
3927 g_object_unref(ptab);
3928 #endif /* BABEL_CLEANUP */
3929 }
3930
3931
3932 /* Create a tab and insert it into the current main window
3933 */
3934
3935 void init_tab(Tab *tab, MainWindow * mw, Tab *copy_tab,
3936 GtkNotebook * notebook, char * label)
3937 {
3938
3939 GList * list;
3940 //Tab * tab;
3941 //LttvFilter *filter = NULL;
3942
3943 //create a new tab data structure
3944 //tab = g_new(Tab,1);
3945
3946 //construct and initialize the traceset_info
3947 tab->traceset_info = g_new(TracesetInfo,1);
3948
3949 if(copy_tab) {
3950 tab->traceset_info->traceset =
3951 lttv_traceset_copy(copy_tab->traceset_info->traceset);
3952
3953 /* Copy the previous tab's filter */
3954 /* We can clone the filter, as we copy the trace set also */
3955 /* The filter must always be in sync with the trace set */
3956
3957 #ifdef BABEL_CLEANUP
3958 tab->filter = lttv_filter_clone(copy_tab->filter);
3959 #endif /* BABEL_CLEANUP */
3960 } else {
3961 tab->traceset_info->traceset = lttv_traceset_new();
3962
3963 tab->filter = NULL;
3964 }
3965 #ifdef DEBUG
3966 lttv_attribute_write_xml(
3967 lttv_traceset_attribute(tab->traceset_info->traceset),
3968 stdout,
3969 0, 4);
3970 fflush(stdout);
3971 #endif //DEBUG
3972 //
3973 tab->time_manager_lock = FALSE;
3974 tab->current_time_manager_lock = FALSE;
3975 #ifdef BABEL_CLEANUP
3976 //FIXME copy not implemented in lower level
3977 tab->traceset_info->traceset_context =
3978 g_object_new(LTTV_TRACESET_STATS_TYPE, NULL);
3979 //add state update hooks
3980 lttv_state_add_event_hooks(
3981 (LttvTracesetState*)tab->traceset_info->traceset_context);
3982 #endif //BABEL_CLEANUP
3983 //determine the current_time and time_window of the tab
3984 #if 0
3985 if(copy_tab != NULL){
3986 tab->time_window = copy_tab->time_window;
3987 tab->current_time = copy_tab->current_time;
3988 }else{
3989 tab->time_window.start_time =
3990 LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context)->
3991 time_span.start_time;
3992 if(DEFAULT_TIME_WIDTH_S <
3993 LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context)->
3994 time_span.end_time.tv_sec)
3995 tmp_time.tv_sec = DEFAULT_TIME_WIDTH_S;
3996 else
3997 tmp_time.tv_sec =
3998 LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context)->
3999 time_span.end_time.tv_sec;
4000 tmp_time.tv_nsec = 0;
4001 tab->time_window.time_width = tmp_time ;
4002 tab->current_time.tv_sec =
4003 LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context)->
4004 time_span.start_time.tv_sec;
4005 tab->current_time.tv_nsec =
4006 LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context)->
4007 time_span.start_time.tv_nsec;
4008 }
4009 #endif //0
4010 tab->attributes = LTTV_IATTRIBUTE(g_object_new(LTTV_ATTRIBUTE_TYPE, NULL));
4011 tab->interrupted_state = g_object_new(LTTV_ATTRIBUTE_TYPE, NULL);
4012
4013 tab->vbox = gtk_vbox_new(FALSE, 2);
4014 tab->top_widget = tab->vbox;
4015 //g_object_set_data_full(G_OBJECT(tab->top_widget), "filter",
4016 // filter, (GDestroyNotify)lttv_filter_destroy);
4017
4018 // g_signal_connect (G_OBJECT(tab->top_widget),
4019 // "notify",
4020 // G_CALLBACK (on_top_notify),
4021 // (gpointer)tab);
4022
4023 tab->viewer_container = gtk_vbox_new(TRUE, 2);
4024 tab->scrollbar = gtk_hscrollbar_new(NULL);
4025 //tab->multivpaned = gtk_multi_vpaned_new();
4026
4027 gtk_box_pack_start(GTK_BOX(tab->vbox),
4028 tab->viewer_container,
4029 TRUE, /* expand */
4030 TRUE, /* Give the extra space to the child */
4031 0); /* No padding */
4032
4033 // if(copy_tab) {
4034 // tab->time_window = copy_tab->time_window;
4035 // tab->current_time = copy_tab->current_time;
4036 // }
4037
4038 /* Create the timebar */
4039
4040 tab->MTimebar = timebar_new();
4041
4042 gtk_box_pack_end(GTK_BOX(tab->vbox),
4043 tab->scrollbar,
4044 FALSE, /* Do not expand */
4045 FALSE, /* Fill has no effect here (expand false) */
4046 0); /* No padding */
4047
4048 gtk_box_pack_end(GTK_BOX(tab->vbox),
4049 tab->MTimebar,
4050 FALSE, /* Do not expand */
4051 FALSE, /* Fill has no effect here (expand false) */
4052 0); /* No padding */
4053
4054 g_object_set_data(G_OBJECT(tab->viewer_container), "focused_viewer", NULL);
4055
4056
4057 tab->mw = mw;
4058
4059 /*{
4060 // Display a label with a X
4061 GtkWidget *w_hbox = gtk_hbox_new(FALSE, 4);
4062 GtkWidget *w_label = gtk_label_new (label);
4063 GtkWidget *pixmap = create_pixmap(GTK_WIDGET(notebook), "close.png");
4064 GtkWidget *w_button = gtk_button_new ();
4065 gtk_container_add(GTK_CONTAINER(w_button), pixmap);
4066 //GtkWidget *w_button = gtk_button_new_with_label("x");
4067
4068 gtk_button_set_relief(GTK_BUTTON(w_button), GTK_RELIEF_NONE);
4069
4070 gtk_box_pack_start(GTK_BOX(w_hbox), w_label, TRUE, TRUE, 0);
4071 gtk_box_pack_end(GTK_BOX(w_hbox), w_button, FALSE,
4072 FALSE, 0);
4073
4074 g_signal_connect_swapped (w_button, "clicked",
4075 G_CALLBACK (on_close_tab_X_clicked),
4076 tab->multi_vpaned);
4077
4078 gtk_widget_set_state(w_button, GTK_STATE_ACTIVE);
4079
4080 gtk_widget_show (w_label);
4081 gtk_widget_show (pixmap);
4082 gtk_widget_show (w_button);
4083 gtk_widget_show (w_hbox);
4084
4085 tab->label = w_hbox;
4086 }*/
4087
4088
4089 tab->label = gtk_label_new (label);
4090
4091 gtk_widget_show(tab->label);
4092 gtk_widget_show(tab->scrollbar);
4093 gtk_widget_show(tab->MTimebar);
4094 gtk_widget_show(tab->viewer_container);
4095 gtk_widget_show(tab->vbox);
4096
4097 //gtk_widget_show(tab->multivpaned);
4098
4099
4100 /* Start with empty events requests list */
4101 tab->events_requests = NULL;
4102 tab->events_request_pending = FALSE;
4103 tab->stop_foreground = FALSE;
4104
4105
4106
4107 g_signal_connect(G_OBJECT(tab->scrollbar), "value-changed",
4108 G_CALLBACK(scroll_value_changed_cb), tab);
4109
4110
4111 /* Timebar signal handler */
4112 g_signal_connect(G_OBJECT(tab->MTimebar), "start-time-changed",
4113 G_CALLBACK(on_timebar_starttime_changed), tab);
4114 g_signal_connect(G_OBJECT(tab->MTimebar), "end-time-changed",
4115 G_CALLBACK(on_timebar_endtime_changed), tab);
4116 g_signal_connect(G_OBJECT(tab->MTimebar), "current-time-changed",
4117 G_CALLBACK(on_timebar_currenttime_changed), tab);
4118
4119 //g_signal_connect(G_OBJECT(tab->scrollbar), "changed",
4120 // G_CALLBACK(scroll_value_changed_cb), tab);
4121
4122
4123 //insert tab into notebook
4124 gtk_notebook_append_page(notebook,
4125 tab->vbox,
4126 tab->label);
4127 list = gtk_container_get_children(GTK_CONTAINER(notebook));
4128 gtk_notebook_set_current_page(notebook,g_list_length(list)-1);
4129 // always show : not if(g_list_length(list)>1)
4130 gtk_notebook_set_show_tabs(notebook, TRUE);
4131
4132 if(copy_tab) {
4133 lttvwindow_report_time_window(tab, copy_tab->time_window);
4134 lttvwindow_report_current_time(tab, copy_tab->current_time);
4135 } else {
4136 TimeWindow time_window;
4137
4138 time_window.start_time = ltt_time_zero;
4139 time_window.end_time = ltt_time_add(time_window.start_time,
4140 lttvwindow_default_time_width);
4141 time_window.time_width = lttvwindow_default_time_width;
4142 time_window.time_width_double = ltt_time_to_double(time_window.time_width);
4143
4144 lttvwindow_report_time_window(tab, time_window);
4145 lttvwindow_report_current_time(tab, ltt_time_zero);
4146 }
4147
4148 LttvTraceset *traceset = tab->traceset_info->traceset;
4149 SetTraceset(tab, traceset);
4150 }
4151
4152 /*
4153 * execute_events_requests
4154 *
4155 * Idle function that executes the pending requests for a tab.
4156 *
4157 * @return return value : TRUE : keep the idle function, FALSE : remove it.
4158 */
4159 gboolean execute_events_requests(Tab *tab)
4160 {
4161 return ( lttvwindow_process_pending_requests(tab) );
4162 }
4163
4164
4165 __EXPORT void create_main_window_with_trace_list(GSList *traces)
4166 {
4167
4168 GSList *iter = NULL;
4169
4170 /* Create window */
4171 MainWindow *mw = construct_main_window(NULL);
4172 GtkWidget *widget = mw->mwindow;
4173
4174 GtkWidget * notebook = lookup_widget(widget, "MNotebook");
4175 GtkWidget *page = gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook),
4176 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook)));
4177 LttvPluginTab *ptab;
4178 Tab *tab;
4179
4180 if(!page) {
4181 ptab = create_new_tab(widget, NULL);
4182 tab = ptab->tab;
4183 } else {
4184 ptab = (LttvPluginTab *)g_object_get_data(G_OBJECT(page), "Tab_Plugin");
4185 tab = ptab->tab;
4186 }
4187
4188 LttvTraceset * traceset = lttv_traceset_new();
4189 for(iter=traces; iter!=NULL; iter=g_slist_next(iter)) {
4190 gchar *path = (gchar*)iter->data;
4191 /* Add trace */
4192 gchar abs_path[PATH_MAX];
4193
4194
4195 get_absolute_pathname(path, abs_path);
4196
4197 if(lttv_traceset_add_path(traceset,abs_path) != 0 ){ /*failure*/
4198
4199 g_warning("cannot open trace %s", abs_path);
4200
4201 GtkWidget *dialogue =
4202 gtk_message_dialog_new(
4203 GTK_WINDOW(gtk_widget_get_toplevel(widget)),
4204 GTK_DIALOG_MODAL|GTK_DIALOG_DESTROY_WITH_PARENT,
4205 GTK_MESSAGE_ERROR,
4206 GTK_BUTTONS_OK,
4207 "Cannot open trace : maybe you should enter in the directory "
4208 "to select it ?");
4209 gtk_dialog_run(GTK_DIALOG(dialogue));
4210 gtk_widget_destroy(dialogue);
4211 }
4212 else{
4213 SetTraceset(tab, traceset);
4214 }
4215 }
4216 }
4217
This page took 0.179869 seconds and 4 git commands to generate.