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