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