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