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