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