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