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