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