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