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