Rework about dialog by using gtk_show_about_dialog
[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 void
3001 on_about_activate (GtkMenuItem *menuitem,
3002 gpointer user_data)
3003 {
3004 MainWindow *main_window = get_window_data_struct(GTK_WIDGET(menuitem));
3005
3006 gchar * authors[] = { "Yannick Brosseau",
3007 "Francis Deslauriers",
3008 "Mathieu Desnoyer",
3009 "Michel Dagenais",
3010 "Benoit Des Ligneris",
3011 "Eric Clement",
3012 "Xang-Xiu Yang",
3013 "Tom Zanussi",
3014 NULL };
3015
3016 static const gchar *comments = "Trace visualiser for LTTng 2.x data\
3017 \nInspired from the original Linux Trace Toolkit Visualizer made by Karim Yaghmour";
3018
3019 static const gchar *copyright = "Copyright \xc2\xa9 2004-2013";
3020
3021 gtk_show_about_dialog(main_window->mwindow,
3022 "authors", authors,
3023 "comments", comments,
3024 "version", VERSION,
3025 "program-name", "LTTV",
3026 "license", "GPLv2, see COPYING file for details",
3027 "website", "http://lttng.org/lttv/",
3028 "copyright", copyright,
3029 NULL);
3030 }
3031
3032
3033 void
3034 on_button_new_clicked (GtkButton *button,
3035 gpointer user_data)
3036 {
3037 #ifdef BABEL_CLEANUP
3038 create_new_window((GtkWidget*)button, user_data, TRUE);
3039 #else
3040 GtkWidget *dialogue =
3041 gtk_message_dialog_new(
3042 GTK_WINDOW(gtk_widget_get_toplevel(button)),
3043 GTK_DIALOG_MODAL|GTK_DIALOG_DESTROY_WITH_PARENT,
3044 GTK_MESSAGE_ERROR,
3045 GTK_BUTTONS_OK,
3046 "Opening multiple windows is disabled.");
3047 gtk_dialog_run(GTK_DIALOG(dialogue));
3048 gtk_widget_destroy(dialogue);
3049 #endif
3050 }
3051
3052 void
3053 on_button_new_tab_clicked (GtkButton *button,
3054 gpointer user_data)
3055 {
3056 create_new_tab((GtkWidget*)button, user_data);
3057 }
3058
3059 void
3060 on_button_open_clicked (GtkButton *button,
3061 gpointer user_data)
3062 {
3063 #ifdef UNFINISHED_FEATURE
3064 open_traceset((GtkWidget*)button, user_data);
3065 #endif
3066 }
3067
3068
3069 void
3070 on_button_add_trace_clicked (GtkButton *button,
3071 gpointer user_data)
3072 {
3073 add_trace((GtkWidget*)button, user_data);
3074 }
3075
3076
3077 void
3078 on_button_remove_trace_clicked (GtkButton *button,
3079 gpointer user_data)
3080 {
3081 remove_trace((GtkWidget*)button, user_data);
3082 }
3083
3084 void
3085 on_button_redraw_clicked (GtkButton *button,
3086 gpointer user_data)
3087 {
3088 redraw((GtkWidget*)button, user_data);
3089 }
3090
3091 void
3092 on_button_continue_processing_clicked (GtkButton *button,
3093 gpointer user_data)
3094 {
3095 continue_processing((GtkWidget*)button, user_data);
3096 }
3097
3098 void
3099 on_button_stop_processing_clicked (GtkButton *button,
3100 gpointer user_data)
3101 {
3102 stop_processing((GtkWidget*)button, user_data);
3103 }
3104
3105
3106
3107 void
3108 on_button_save_clicked (GtkButton *button,
3109 gpointer user_data)
3110 {
3111 save((GtkWidget*)button, user_data);
3112 }
3113
3114
3115 void
3116 on_button_save_as_clicked (GtkButton *button,
3117 gpointer user_data)
3118 {
3119 save_as((GtkWidget*)button, user_data);
3120 }
3121
3122
3123 void
3124 on_button_zoom_in_clicked (GtkButton *button,
3125 gpointer user_data)
3126 {
3127 zoom_in((GtkWidget*)button, user_data);
3128 }
3129
3130
3131 void
3132 on_button_zoom_out_clicked (GtkButton *button,
3133 gpointer user_data)
3134 {
3135 zoom_out((GtkWidget*)button, user_data);
3136 }
3137
3138
3139 void
3140 on_button_zoom_extended_clicked (GtkButton *button,
3141 gpointer user_data)
3142 {
3143 zoom_extended((GtkWidget*)button, user_data);
3144 }
3145
3146
3147 void
3148 on_button_go_to_time_clicked (GtkButton *button,
3149 gpointer user_data)
3150 {
3151 go_to_time((GtkWidget*)button, user_data);
3152 }
3153
3154
3155 void
3156 on_button_show_time_frame_clicked (GtkButton *button,
3157 gpointer user_data)
3158 {
3159 show_time_frame((GtkWidget*)button, user_data);
3160 }
3161
3162
3163 void
3164 on_button_move_up_clicked (GtkButton *button,
3165 gpointer user_data)
3166 {
3167 move_up_viewer((GtkWidget*)button, user_data);
3168 }
3169
3170
3171 void
3172 on_button_move_down_clicked (GtkButton *button,
3173 gpointer user_data)
3174 {
3175 move_down_viewer((GtkWidget*)button, user_data);
3176 }
3177
3178
3179 void
3180 on_button_delete_viewer_clicked (GtkButton *button,
3181 gpointer user_data)
3182 {
3183 delete_viewer((GtkWidget*)button, user_data);
3184 }
3185
3186 void
3187 on_MWindow_destroy (GtkWidget *widget,
3188 gpointer user_data)
3189 {
3190 MainWindow *main_window = get_window_data_struct(widget);
3191 LttvIAttribute *attributes = main_window->attributes;
3192 LttvAttributeValue value;
3193 gboolean retval;
3194
3195 //This is unnecessary, since widgets will be destroyed
3196 //by the main window widget anyway.
3197 //remove_all_menu_toolbar_constructors(main_window, NULL);
3198
3199 retval= lttv_iattribute_find_by_path(attributes, "viewers/menu",
3200 LTTV_POINTER, &value);
3201 g_assert(retval);
3202 lttv_menus_destroy((LttvMenus*)*(value.v_pointer));
3203
3204 retval= lttv_iattribute_find_by_path(attributes, "viewers/toolbar",
3205 LTTV_POINTER, &value);
3206 g_assert(retval);
3207 lttv_toolbars_destroy((LttvToolbars*)*(value.v_pointer));
3208
3209 g_object_unref(main_window->attributes);
3210 g_main_window_list = g_slist_remove(g_main_window_list, main_window);
3211
3212 g_info("There are now : %d windows\n",g_slist_length(g_main_window_list));
3213 if(g_slist_length(g_main_window_list) == 0)
3214 mainwindow_quit();
3215 }
3216
3217 gboolean
3218 on_MWindow_configure (GtkWidget *widget,
3219 GdkEventConfigure *event,
3220 gpointer user_data)
3221 {
3222 // MD : removed time width modification upon resizing of the main window.
3223 // The viewers will redraw themselves completely, without time interval
3224 // modification.
3225 /* while(tab){
3226 if(mw_data->window_width){
3227 time_span = LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context)->Time_Span ;
3228 time_win = tab->time_window;
3229 ratio = width / mw_data->window_width;
3230 tab->time_window.time_width = ltt_time_mul(time_win.time_width,ratio);
3231 time = ltt_time_sub(time_span->endTime, time_win.start_time);
3232 if(ltt_time_compare(time, tab->time_window.time_width) < 0){
3233 tab->time_window.time_width = time;
3234 }
3235 }
3236 tab = tab->next;
3237 }
3238
3239 mw_data->window_width = (int)width;
3240 */
3241 return FALSE;
3242 }
3243
3244 /* Set current tab
3245 */
3246
3247 void
3248 on_MNotebook_switch_page (GtkNotebook *notebook,
3249 GtkNotebookPage *page,
3250 guint page_num,
3251 gpointer user_data)
3252 {
3253
3254 }
3255
3256
3257 void time_change_manager (Tab *tab,
3258 TimeWindow new_time_window)
3259 {
3260
3261 /* Only one source of time change */
3262 if(tab->time_manager_lock == TRUE) return;
3263
3264 tab->time_manager_lock = TRUE;
3265 TimeInterval time_span;
3266
3267 LttvTraceset *ts = tab->traceset_info->traceset;
3268
3269 time_span = lttv_traceset_get_time_span_real(ts);
3270
3271 LttTime start_time = new_time_window.start_time;
3272 LttTime end_time = new_time_window.end_time;
3273
3274 g_assert(ltt_time_compare(start_time, end_time) < 0);
3275
3276 /* Set scrollbar */
3277 GtkAdjustment *adjustment = gtk_range_get_adjustment(GTK_RANGE(tab->scrollbar));
3278 LttTime upper = ltt_time_sub(time_span.end_time, time_span.start_time);
3279
3280 #if 0
3281 gtk_range_set_increments(GTK_RANGE(tab->scrollbar),
3282 ltt_time_to_double(new_time_window.time_width)
3283 / SCROLL_STEP_PER_PAGE
3284 * NANOSECONDS_PER_SECOND, /* step increment */
3285 ltt_time_to_double(new_time_window.time_width)
3286 * NANOSECONDS_PER_SECOND); /* page increment */
3287 gtk_range_set_range(GTK_RANGE(tab->scrollbar),
3288 0.0, /* lower */
3289 ltt_time_to_double(upper)
3290 * NANOSECONDS_PER_SECOND); /* upper */
3291 #endif //0
3292 g_object_set(G_OBJECT(adjustment),
3293 "lower",
3294 0.0, /* lower */
3295 "upper",
3296 ltt_time_to_double(upper), /* upper */
3297 "step_increment",
3298 new_time_window.time_width_double
3299 / SCROLL_STEP_PER_PAGE, /* step increment */
3300 "page_increment",
3301 new_time_window.time_width_double,
3302 /* page increment */
3303 "page_size",
3304 new_time_window.time_width_double, /* page size */
3305 NULL);
3306 gtk_adjustment_changed(adjustment);
3307
3308 // g_object_set(G_OBJECT(adjustment),
3309 // "value",
3310 // ltt_time_to_double(
3311 // ltt_time_sub(start_time, time_span.start_time))
3312 // , /* value */
3313 // NULL);
3314 //gtk_adjustment_value_changed(adjustment);
3315 gtk_range_set_value(GTK_RANGE(tab->scrollbar),
3316 ltt_time_to_double(
3317 ltt_time_sub(start_time, time_span.start_time)) /* value */);
3318
3319 /* set the time bar. */
3320
3321
3322 timebar_set_minmax_time(TIMEBAR(tab->MTimebar),
3323 &time_span.start_time,
3324 &time_span.end_time );
3325 timebar_set_start_time(TIMEBAR(tab->MTimebar),&start_time);
3326 timebar_set_end_time(TIMEBAR(tab->MTimebar),&end_time);
3327
3328
3329
3330 /* call viewer hooks for new time window */
3331 set_time_window(tab, &new_time_window);
3332
3333 tab->time_manager_lock = FALSE;
3334
3335
3336 }
3337
3338
3339
3340
3341
3342 void current_time_change_manager (Tab *tab,
3343 LttTime new_current_time)
3344 {
3345 /* Only one source of time change */
3346 if(tab->current_time_manager_lock == TRUE) return;
3347
3348 tab->current_time_manager_lock = TRUE;
3349
3350 timebar_set_current_time(TIMEBAR(tab->MTimebar), &new_current_time);
3351
3352 set_current_time(tab, &new_current_time);
3353
3354 tab->current_time_manager_lock = FALSE;
3355 }
3356
3357 void current_position_change_manager(Tab *tab, LttvTracesetPosition *pos)
3358 {
3359 lttv_traceset_seek_to_position( pos);
3360
3361 LttTime new_time = lttv_traceset_position_get_time(pos);
3362 /* Put the context in a state coherent position */
3363
3364 lttv_state_traceset_seek_time_closest(tab->traceset_info->traceset, ltt_time_zero);
3365
3366 current_time_change_manager(tab, new_time);
3367
3368 set_current_position(tab, pos);
3369 }
3370
3371 static void on_timebar_starttime_changed(Timebar *timebar,
3372 gpointer user_data)
3373 {
3374 Tab *tab = (Tab *)user_data;
3375 LttvTraceset * ts =tab->traceset_info->traceset;
3376 TimeInterval time_span = lttv_traceset_get_time_span_real(ts);
3377
3378 TimeWindow new_time_window = tab->time_window;
3379 new_time_window.start_time = timebar_get_start_time(timebar);
3380
3381 LttTime end_time = new_time_window.end_time;
3382
3383 /* TODO ybrosseau 2010-12-02: This if should have been checked
3384 by the timebar already */
3385 if(ltt_time_compare(new_time_window.start_time, end_time) >= 0) {
3386 /* Then, we must push back end time : keep the same time width
3387 * if possible, else end traceset time */
3388 end_time = LTT_TIME_MIN(ltt_time_add(new_time_window.start_time,
3389 new_time_window.time_width),
3390 time_span.end_time);
3391 }
3392
3393 /* Fix the time width to fit start time and end time */
3394 new_time_window.time_width = ltt_time_sub(end_time,
3395 new_time_window.start_time);
3396
3397 new_time_window.time_width_double =
3398 ltt_time_to_double(new_time_window.time_width);
3399
3400 new_time_window.end_time = end_time;
3401
3402 /* Notify the time_manager */
3403 time_change_manager(tab, new_time_window);
3404
3405 }
3406
3407 static void on_timebar_endtime_changed(Timebar *timebar,
3408 gpointer user_data)
3409 {
3410 Tab *tab = (Tab *)user_data;
3411 LttvTraceset * ts =tab->traceset_info->traceset;
3412 TimeInterval time_span = lttv_traceset_get_time_span_real(ts);
3413
3414 TimeWindow new_time_window = tab->time_window;
3415
3416 LttTime end_time = timebar_get_end_time(timebar);
3417
3418 /* TODO ybrosseau 2010-12-02: This if should have been
3419 checked by the timebar already */
3420 if(ltt_time_compare(new_time_window.start_time, end_time) >= 0) {
3421 /* Then, we must push front start time : keep the same time
3422 width if possible, else end traceset time */
3423 new_time_window.start_time = LTT_TIME_MAX(
3424 ltt_time_sub(end_time,
3425 new_time_window.time_width),
3426 time_span.start_time);
3427 }
3428
3429 /* Fix the time width to fit start time and end time */
3430 new_time_window.time_width = ltt_time_sub(end_time,
3431 new_time_window.start_time);
3432
3433 new_time_window.time_width_double =
3434 ltt_time_to_double(new_time_window.time_width);
3435
3436 new_time_window.end_time = end_time;
3437
3438 /* Notify the time_manager */
3439 time_change_manager(tab, new_time_window);
3440 }
3441 static void on_timebar_currenttime_changed(Timebar *timebar,
3442 gpointer user_data)
3443 {
3444 Tab *tab = (Tab *)user_data;
3445
3446 LttTime new_current_time = timebar_get_current_time(timebar);
3447
3448 current_time_change_manager(tab, new_current_time);
3449 }
3450
3451 void scroll_value_changed_cb(GtkWidget *scrollbar,
3452 gpointer user_data)
3453 {
3454 Tab *tab = (Tab *)user_data;
3455 TimeWindow new_time_window;
3456 LttTime time;
3457 GtkAdjustment *adjust = gtk_range_get_adjustment(GTK_RANGE(scrollbar));
3458 gdouble value = gtk_adjustment_get_value(adjust);
3459 // gdouble upper, lower, ratio, page_size;
3460 gdouble page_size;
3461
3462 LttvTraceset * ts = tab->traceset_info->traceset;
3463 TimeInterval time_span = lttv_traceset_get_time_span_real(ts);
3464
3465 time = ltt_time_add(ltt_time_from_double(value),
3466 time_span.start_time);
3467
3468 new_time_window.start_time = time;
3469
3470 page_size = adjust->page_size;
3471
3472 new_time_window.time_width =
3473 ltt_time_from_double(page_size);
3474
3475 new_time_window.time_width_double =
3476 page_size;
3477
3478 new_time_window.end_time = ltt_time_add(new_time_window.start_time,
3479 new_time_window.time_width);
3480
3481
3482 time_change_manager(tab, new_time_window);
3483
3484 #if 0
3485 //time_window = tab->time_window;
3486
3487 lower = adjust->lower;
3488 upper = adjust->upper;
3489 ratio = (value - lower) / (upper - lower);
3490 g_info("lower %lu, upper %lu, value %lu, ratio %lu", lower, upper, value, ratio);
3491
3492 //time = ltt_time_sub(time_span->end_time, time_span->start_time);
3493 //time = ltt_time_mul(time, (float)ratio);
3494 //time = ltt_time_add(time_span->start_time, time);
3495 time = ltt_time_add(ltt_time_from_double(value),
3496 time_span.start_time);
3497
3498 time_window.start_time = time;
3499
3500 page_size = adjust->page_size;
3501
3502 time_window.time_width =
3503 ltt_time_from_double(page_size);
3504 //time = ltt_time_sub(time_span.end_time, time);
3505 //if(ltt_time_compare(time,time_window.time_width) < 0){
3506 // time_window.time_width = time;
3507 //}
3508
3509 /* call viewer hooks for new time window */
3510 set_time_window(tab, &time_window);
3511 #endif //0
3512
3513 }
3514
3515
3516 /* Display a dialogue showing all eventtypes and traces, let user to select the interested
3517 * eventtypes, tracefiles and traces (filter)
3518 */
3519
3520 /* Select a trace which will be removed from traceset
3521 */
3522
3523 char * get_remove_trace(MainWindow *mw_data,
3524 char ** all_trace_name, int nb_trace)
3525 {
3526 return get_selection(mw_data, all_trace_name, nb_trace,
3527 "Select a trace", "Trace pathname");
3528 }
3529
3530
3531 /* Select a module which will be loaded
3532 */
3533
3534 char * get_load_module(MainWindow *mw_data,
3535 char ** load_module_name, int nb_module)
3536 {
3537 return get_selection(mw_data, load_module_name, nb_module,
3538 "Select a module to load", "Module name");
3539 }
3540
3541
3542
3543
3544 /* Select a module which will be unloaded
3545 */
3546
3547 char * get_unload_module(MainWindow *mw_data,
3548 char ** loaded_module_name, int nb_module)
3549 {
3550 return get_selection(mw_data, loaded_module_name, nb_module,
3551 "Select a module to unload", "Module name");
3552 }
3553
3554
3555 /* Display a dialogue which shows all selectable items, let user to
3556 * select one of them
3557 */
3558
3559 char * get_selection(MainWindow *mw_data,
3560 char ** loaded_module_name, int nb_module,
3561 char *title, char * column_title)
3562 {
3563 GtkWidget * dialogue;
3564 GtkWidget * scroll_win;
3565 GtkWidget * tree;
3566 GtkListStore * store;
3567 GtkTreeViewColumn * column;
3568 GtkCellRenderer * renderer;
3569 GtkTreeSelection * select;
3570 GtkTreeIter iter;
3571 gint id, i;
3572 char * unload_module_name = NULL;
3573
3574 dialogue = gtk_dialog_new_with_buttons(title,
3575 NULL,
3576 GTK_DIALOG_MODAL,
3577 GTK_STOCK_OK,GTK_RESPONSE_ACCEPT,
3578 GTK_STOCK_CANCEL,GTK_RESPONSE_REJECT,
3579 NULL);
3580 gtk_window_set_default_size((GtkWindow*)dialogue, 500, 200);
3581 gtk_window_set_transient_for(GTK_WINDOW(dialogue),
3582 GTK_WINDOW(mw_data->mwindow));
3583
3584 scroll_win = gtk_scrolled_window_new (NULL, NULL);
3585 gtk_widget_show ( scroll_win);
3586 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll_win),
3587 GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
3588
3589 store = gtk_list_store_new (N_COLUMNS,G_TYPE_STRING);
3590 tree = gtk_tree_view_new_with_model(GTK_TREE_MODEL (store));
3591 gtk_widget_show ( tree);
3592 g_object_unref (G_OBJECT (store));
3593
3594 renderer = gtk_cell_renderer_text_new ();
3595 column = gtk_tree_view_column_new_with_attributes (column_title,
3596 renderer,
3597 "text", MODULE_COLUMN,
3598 NULL);
3599 gtk_tree_view_column_set_alignment (column, 0.5);
3600 gtk_tree_view_column_set_fixed_width (column, 150);
3601 gtk_tree_view_append_column (GTK_TREE_VIEW (tree), column);
3602
3603 select = gtk_tree_view_get_selection (GTK_TREE_VIEW (tree));
3604 gtk_tree_selection_set_mode (select, GTK_SELECTION_SINGLE);
3605
3606 gtk_container_add (GTK_CONTAINER (scroll_win), tree);
3607
3608 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialogue)->vbox), scroll_win,TRUE, TRUE,0);
3609
3610 for(i=0;i<nb_module;i++){
3611 gtk_list_store_append (store, &iter);
3612 gtk_list_store_set (store, &iter, MODULE_COLUMN,loaded_module_name[i],-1);
3613 }
3614
3615 id = gtk_dialog_run(GTK_DIALOG(dialogue));
3616 GtkTreeModel **store_model = (GtkTreeModel**)&store;
3617 switch(id){
3618 case GTK_RESPONSE_ACCEPT:
3619 case GTK_RESPONSE_OK:
3620 if (gtk_tree_selection_get_selected (select, store_model, &iter)){
3621 gtk_tree_model_get ((GtkTreeModel*)store, &iter, MODULE_COLUMN, &unload_module_name, -1);
3622 }
3623 case GTK_RESPONSE_REJECT:
3624 case GTK_RESPONSE_CANCEL:
3625 default:
3626 gtk_widget_destroy(dialogue);
3627 break;
3628 }
3629
3630 return unload_module_name;
3631 }
3632
3633
3634 /* Insert all menu entry and tool buttons into this main window
3635 * for modules.
3636 *
3637 */
3638
3639 void add_all_menu_toolbar_constructors(MainWindow * mw, gpointer user_data)
3640 {
3641 guint i;
3642 GdkPixbuf *pixbuf;
3643 lttvwindow_viewer_constructor constructor;
3644 LttvMenus * global_menu, * instance_menu;
3645 LttvToolbars * global_toolbar, * instance_toolbar;
3646 LttvMenuClosure *menu_item;
3647 LttvToolbarClosure *toolbar_item;
3648 LttvAttributeValue value;
3649 LttvIAttribute *global_attributes = LTTV_IATTRIBUTE(lttv_global_attributes());
3650 LttvIAttribute *attributes = mw->attributes;
3651 GtkWidget * tool_menu_title_menu, *new_widget, *pixmap;
3652 gboolean retval;
3653
3654 retval= lttv_iattribute_find_by_path(global_attributes, "viewers/menu",
3655 LTTV_POINTER, &value);
3656 g_assert(retval);
3657 if(*(value.v_pointer) == NULL)
3658 *(value.v_pointer) = lttv_menus_new();
3659 global_menu = (LttvMenus*)*(value.v_pointer);
3660
3661 retval= lttv_iattribute_find_by_path(attributes, "viewers/menu",
3662 LTTV_POINTER, &value);
3663 g_assert(retval);
3664 if(*(value.v_pointer) == NULL)
3665 *(value.v_pointer) = lttv_menus_new();
3666 instance_menu = (LttvMenus*)*(value.v_pointer);
3667
3668 retval= lttv_iattribute_find_by_path(global_attributes, "viewers/toolbar",
3669 LTTV_POINTER, &value);
3670 g_assert(retval);
3671 if(*(value.v_pointer) == NULL)
3672 *(value.v_pointer) = lttv_toolbars_new();
3673 global_toolbar = (LttvToolbars*)*(value.v_pointer);
3674
3675 retval= lttv_iattribute_find_by_path(attributes, "viewers/toolbar",
3676 LTTV_POINTER, &value);
3677 g_assert(retval);
3678 if(*(value.v_pointer) == NULL)
3679 *(value.v_pointer) = lttv_toolbars_new();
3680 instance_toolbar = (LttvToolbars*)*(value.v_pointer);
3681
3682 /* Add missing menu entries to window instance */
3683 for(i=0;i<global_menu->len;i++) {
3684 menu_item = &g_array_index(global_menu, LttvMenuClosure, i);
3685
3686 //add menu_item to window instance;
3687 constructor = menu_item->con;
3688 tool_menu_title_menu = lookup_widget(mw->mwindow,"ToolMenuTitle_menu");
3689 new_widget =
3690 gtk_menu_item_new_with_mnemonic (menu_item->menu_text);
3691 gtk_container_add (GTK_CONTAINER (tool_menu_title_menu),
3692 new_widget);
3693 g_signal_connect ((gpointer) new_widget, "activate",
3694 G_CALLBACK (insert_viewer_wrap),
3695 constructor);
3696 gtk_widget_show (new_widget);
3697 lttv_menus_add(instance_menu, menu_item->con,
3698 menu_item->menu_path,
3699 menu_item->menu_text,
3700 new_widget);
3701
3702 }
3703
3704 /* Add missing toolbar entries to window instance */
3705 for(i=0;i<global_toolbar->len;i++) {
3706 toolbar_item = &g_array_index(global_toolbar, LttvToolbarClosure, i);
3707
3708 //add toolbar_item to window instance;
3709 constructor = toolbar_item->con;
3710 tool_menu_title_menu = lookup_widget(mw->mwindow,"MToolbar1");
3711 pixbuf = gdk_pixbuf_new_from_xpm_data((const char**)toolbar_item->pixmap);
3712 pixmap = gtk_image_new_from_pixbuf(pixbuf);
3713 new_widget =
3714 gtk_toolbar_append_element (GTK_TOOLBAR (tool_menu_title_menu),
3715 GTK_TOOLBAR_CHILD_BUTTON,
3716 NULL,
3717 "",
3718 toolbar_item->tooltip, NULL,
3719 pixmap, NULL, NULL);
3720 gtk_label_set_use_underline(
3721 GTK_LABEL (((GtkToolbarChild*) (
3722 g_list_last (GTK_TOOLBAR
3723 (tool_menu_title_menu)->children)->data))->label),
3724 TRUE);
3725 gtk_container_set_border_width (GTK_CONTAINER (new_widget), 1);
3726 g_signal_connect ((gpointer) new_widget,
3727 "clicked",
3728 G_CALLBACK (insert_viewer_wrap),
3729 constructor);
3730 gtk_widget_show (new_widget);
3731
3732 lttv_toolbars_add(instance_toolbar, toolbar_item->con,
3733 toolbar_item->tooltip,
3734 toolbar_item->pixmap,
3735 new_widget);
3736
3737 }
3738
3739 }
3740
3741
3742 /* Create a main window
3743 */
3744
3745 MainWindow *construct_main_window(MainWindow * parent)
3746 {
3747 gboolean retval;
3748
3749 g_debug("construct_main_window()");
3750 GtkWidget * new_window; /* New generated main window */
3751 MainWindow * new_m_window;/* New main window structure */
3752 GtkNotebook * notebook;
3753 LttvIAttribute *attributes =
3754 LTTV_IATTRIBUTE(g_object_new(LTTV_ATTRIBUTE_TYPE, NULL));
3755 LttvAttributeValue value;
3756
3757 new_m_window = g_new(MainWindow, 1);
3758
3759 // Add the object's information to the module's array
3760 g_main_window_list = g_slist_append(g_main_window_list, new_m_window);
3761
3762 new_window = create_MWindow();
3763 gtk_widget_show (new_window);
3764
3765 new_m_window->mwindow = new_window;
3766 new_m_window->attributes = attributes;
3767
3768 retval= lttv_iattribute_find_by_path(attributes, "viewers/menu",
3769 LTTV_POINTER, &value);
3770 g_assert(retval);
3771 *(value.v_pointer) = lttv_menus_new();
3772
3773 retval= lttv_iattribute_find_by_path(attributes, "viewers/toolbar",
3774 LTTV_POINTER, &value);
3775 g_assert(retval);
3776 *(value.v_pointer) = lttv_toolbars_new();
3777
3778 add_all_menu_toolbar_constructors(new_m_window, NULL);
3779
3780 g_object_set_data_full(G_OBJECT(new_window),
3781 "main_window_data",
3782 (gpointer)new_m_window,
3783 (GDestroyNotify)g_free);
3784 //create a default tab
3785 notebook = (GtkNotebook *)lookup_widget(new_m_window->mwindow, "MNotebook");
3786 if(notebook == NULL){
3787 g_info("Notebook does not exist\n");
3788 /* FIXME : destroy partially created widgets */
3789 g_free(new_m_window);
3790 return NULL;
3791 }
3792 //gtk_notebook_popup_enable (GTK_NOTEBOOK(notebook));
3793 //for now there is no name field in LttvTraceset structure
3794 //Use "Traceset" as the label for the default tab
3795 if(parent) {
3796 GtkWidget * parent_notebook = lookup_widget(parent->mwindow, "MNotebook");
3797 GtkWidget *page = gtk_notebook_get_nth_page(GTK_NOTEBOOK(parent_notebook),
3798 gtk_notebook_get_current_page(GTK_NOTEBOOK(parent_notebook)));
3799 Tab *parent_tab;
3800
3801 if(!page) {
3802 parent_tab = NULL;
3803 } else {
3804 LttvPluginTab *ptab;
3805 ptab = (LttvPluginTab *)g_object_get_data(G_OBJECT(page), "Tab_Plugin");
3806 parent_tab = ptab->tab;
3807 }
3808 LttvPluginTab *ptab = g_object_new(LTTV_TYPE_PLUGIN_TAB, NULL);
3809 init_tab(ptab->tab,
3810 new_m_window, parent_tab, notebook, "Traceset");
3811 ptab->parent.top_widget = ptab->tab->top_widget;
3812 g_object_set_data_full(
3813 G_OBJECT(ptab->tab->vbox),
3814 "Tab_Plugin",
3815 ptab,
3816 (GDestroyNotify)tab_destructor);
3817 } else {
3818 LttvPluginTab *ptab = g_object_new(LTTV_TYPE_PLUGIN_TAB, NULL);
3819 init_tab(ptab->tab, new_m_window, NULL, notebook, "Traceset");
3820 ptab->parent.top_widget = ptab->tab->top_widget;
3821 g_object_set_data_full(
3822 G_OBJECT(ptab->tab->vbox),
3823 "Tab_Plugin",
3824 ptab,
3825 (GDestroyNotify)tab_destructor);
3826 }
3827
3828 /* Insert default viewers */
3829 {
3830 LttvAttributeType type;
3831 LttvAttributeName name;
3832 LttvAttributeValue value;
3833 LttvAttribute *attribute;
3834
3835 LttvIAttribute *attributes_global =
3836 LTTV_IATTRIBUTE(lttv_global_attributes());
3837
3838 attribute = LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
3839 LTTV_IATTRIBUTE(attributes_global),
3840 LTTV_VIEWER_CONSTRUCTORS));
3841 g_assert(attribute);
3842
3843 name = g_quark_from_string("guievents");
3844 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute),
3845 name, &value);
3846 if(type == LTTV_POINTER) {
3847 lttvwindow_viewer_constructor viewer_constructor =
3848 (lttvwindow_viewer_constructor)*value.v_pointer;
3849 insert_viewer(new_window, viewer_constructor);
3850 }
3851
3852 name = g_quark_from_string("guicontrolflow");
3853 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute),
3854 name, &value);
3855 if(type == LTTV_POINTER) {
3856 lttvwindow_viewer_constructor viewer_constructor =
3857 (lttvwindow_viewer_constructor)*value.v_pointer;
3858 insert_viewer(new_window, viewer_constructor);
3859 }
3860
3861 name = g_quark_from_string("guistatistics");
3862 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute),
3863 name, &value);
3864 if(type == LTTV_POINTER) {
3865 lttvwindow_viewer_constructor viewer_constructor =
3866 (lttvwindow_viewer_constructor)*value.v_pointer;
3867 insert_viewer(new_window, viewer_constructor);
3868 }
3869 }
3870
3871 g_info("There are now : %d windows\n",g_slist_length(g_main_window_list));
3872
3873 return new_m_window;
3874 }
3875
3876
3877 /* Free the memory occupied by a tab structure
3878 * destroy the tab
3879 */
3880
3881 void tab_destructor(LttvPluginTab * ptab)
3882 {
3883 #ifdef BABEL_CLEANUP
3884 int i, nb, ref_count;
3885 LttvTrace * trace;
3886 Tab *tab = ptab->tab;
3887
3888 if(tab->attributes)
3889 g_object_unref(tab->attributes);
3890
3891 if(tab->interrupted_state)
3892 g_object_unref(tab->interrupted_state);
3893
3894
3895 if(tab->traceset_info->traceset_context != NULL){
3896 //remove state update hooks
3897 lttv_state_remove_event_hooks(
3898 (LttvTracesetState*)tab->traceset_info->
3899 traceset_context);
3900 lttv_context_fini(LTTV_TRACESET_CONTEXT(tab->traceset_info->
3901 traceset_context));
3902 g_object_unref(tab->traceset_info->traceset_context);
3903 }
3904 if(tab->traceset_info->traceset != NULL) {
3905 nb = lttv_traceset_number(tab->traceset_info->traceset);
3906 for(i = 0 ; i < nb ; i++) {
3907 trace = lttv_traceset_get(tab->traceset_info->traceset, i);
3908 ref_count = lttv_trace_get_ref_number(trace);
3909 if(ref_count <= 1){
3910 ltt_trace_close(lttv_trace(trace));
3911 }
3912 }
3913 }
3914 lttv_traceset_destroy(tab->traceset_info->traceset);
3915 /* Remove the idle events requests processing function of the tab */
3916 g_idle_remove_by_data(tab);
3917
3918 g_slist_free(tab->events_requests);
3919 g_free(tab->traceset_info);
3920 //g_free(tab);
3921 g_object_unref(ptab);
3922 #endif /* BABEL_CLEANUP */
3923 }
3924
3925
3926 /* Create a tab and insert it into the current main window
3927 */
3928
3929 void init_tab(Tab *tab, MainWindow * mw, Tab *copy_tab,
3930 GtkNotebook * notebook, char * label)
3931 {
3932
3933 GList * list;
3934 //Tab * tab;
3935 //LttvFilter *filter = NULL;
3936
3937 //create a new tab data structure
3938 //tab = g_new(Tab,1);
3939
3940 //construct and initialize the traceset_info
3941 tab->traceset_info = g_new(TracesetInfo,1);
3942
3943 if(copy_tab) {
3944 tab->traceset_info->traceset =
3945 lttv_traceset_copy(copy_tab->traceset_info->traceset);
3946
3947 /* Copy the previous tab's filter */
3948 /* We can clone the filter, as we copy the trace set also */
3949 /* The filter must always be in sync with the trace set */
3950
3951 #ifdef BABEL_CLEANUP
3952 tab->filter = lttv_filter_clone(copy_tab->filter);
3953 #endif /* BABEL_CLEANUP */
3954 } else {
3955 tab->traceset_info->traceset = lttv_traceset_new();
3956
3957 tab->filter = NULL;
3958 }
3959 #ifdef DEBUG
3960 lttv_attribute_write_xml(
3961 lttv_traceset_attribute(tab->traceset_info->traceset),
3962 stdout,
3963 0, 4);
3964 fflush(stdout);
3965 #endif //DEBUG
3966 //
3967 tab->time_manager_lock = FALSE;
3968 tab->current_time_manager_lock = FALSE;
3969 #ifdef BABEL_CLEANUP
3970 //FIXME copy not implemented in lower level
3971 tab->traceset_info->traceset_context =
3972 g_object_new(LTTV_TRACESET_STATS_TYPE, NULL);
3973 //add state update hooks
3974 #endif //BABEL_CLEANUP
3975 lttv_state_add_event_hooks(
3976 tab->traceset_info->traceset);
3977
3978 //determine the current_time and time_window of the tab
3979 #if 0
3980 if(copy_tab != NULL){
3981 tab->time_window = copy_tab->time_window;
3982 tab->current_time = copy_tab->current_time;
3983 }else{
3984 tab->time_window.start_time =
3985 LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context)->
3986 time_span.start_time;
3987 if(DEFAULT_TIME_WIDTH_S <
3988 LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context)->
3989 time_span.end_time.tv_sec)
3990 tmp_time.tv_sec = DEFAULT_TIME_WIDTH_S;
3991 else
3992 tmp_time.tv_sec =
3993 LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context)->
3994 time_span.end_time.tv_sec;
3995 tmp_time.tv_nsec = 0;
3996 tab->time_window.time_width = tmp_time ;
3997 tab->current_time.tv_sec =
3998 LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context)->
3999 time_span.start_time.tv_sec;
4000 tab->current_time.tv_nsec =
4001 LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context)->
4002 time_span.start_time.tv_nsec;
4003 }
4004 #endif //0
4005 tab->attributes = LTTV_IATTRIBUTE(g_object_new(LTTV_ATTRIBUTE_TYPE, NULL));
4006 tab->interrupted_state = g_object_new(LTTV_ATTRIBUTE_TYPE, NULL);
4007
4008 tab->vbox = gtk_vbox_new(FALSE, 2);
4009 tab->top_widget = tab->vbox;
4010 //g_object_set_data_full(G_OBJECT(tab->top_widget), "filter",
4011 // filter, (GDestroyNotify)lttv_filter_destroy);
4012
4013 // g_signal_connect (G_OBJECT(tab->top_widget),
4014 // "notify",
4015 // G_CALLBACK (on_top_notify),
4016 // (gpointer)tab);
4017
4018 tab->viewer_container = gtk_vbox_new(TRUE, 2);
4019 tab->scrollbar = gtk_hscrollbar_new(NULL);
4020 //tab->multivpaned = gtk_multi_vpaned_new();
4021
4022 gtk_box_pack_start(GTK_BOX(tab->vbox),
4023 tab->viewer_container,
4024 TRUE, /* expand */
4025 TRUE, /* Give the extra space to the child */
4026 0); /* No padding */
4027
4028 // if(copy_tab) {
4029 // tab->time_window = copy_tab->time_window;
4030 // tab->current_time = copy_tab->current_time;
4031 // }
4032
4033 /* Create the timebar */
4034
4035 tab->MTimebar = timebar_new();
4036
4037 gtk_box_pack_end(GTK_BOX(tab->vbox),
4038 tab->scrollbar,
4039 FALSE, /* Do not expand */
4040 FALSE, /* Fill has no effect here (expand false) */
4041 0); /* No padding */
4042
4043 gtk_box_pack_end(GTK_BOX(tab->vbox),
4044 tab->MTimebar,
4045 FALSE, /* Do not expand */
4046 FALSE, /* Fill has no effect here (expand false) */
4047 0); /* No padding */
4048
4049 g_object_set_data(G_OBJECT(tab->viewer_container), "focused_viewer", NULL);
4050
4051
4052 tab->mw = mw;
4053
4054 /*{
4055 // Display a label with a X
4056 GtkWidget *w_hbox = gtk_hbox_new(FALSE, 4);
4057 GtkWidget *w_label = gtk_label_new (label);
4058 GtkWidget *pixmap = create_pixmap(GTK_WIDGET(notebook), "close.png");
4059 GtkWidget *w_button = gtk_button_new ();
4060 gtk_container_add(GTK_CONTAINER(w_button), pixmap);
4061 //GtkWidget *w_button = gtk_button_new_with_label("x");
4062
4063 gtk_button_set_relief(GTK_BUTTON(w_button), GTK_RELIEF_NONE);
4064
4065 gtk_box_pack_start(GTK_BOX(w_hbox), w_label, TRUE, TRUE, 0);
4066 gtk_box_pack_end(GTK_BOX(w_hbox), w_button, FALSE,
4067 FALSE, 0);
4068
4069 g_signal_connect_swapped (w_button, "clicked",
4070 G_CALLBACK (on_close_tab_X_clicked),
4071 tab->multi_vpaned);
4072
4073 gtk_widget_set_state(w_button, GTK_STATE_ACTIVE);
4074
4075 gtk_widget_show (w_label);
4076 gtk_widget_show (pixmap);
4077 gtk_widget_show (w_button);
4078 gtk_widget_show (w_hbox);
4079
4080 tab->label = w_hbox;
4081 }*/
4082
4083
4084 tab->label = gtk_label_new (label);
4085
4086 gtk_widget_show(tab->label);
4087 gtk_widget_show(tab->scrollbar);
4088 gtk_widget_show(tab->MTimebar);
4089 gtk_widget_show(tab->viewer_container);
4090 gtk_widget_show(tab->vbox);
4091
4092 //gtk_widget_show(tab->multivpaned);
4093
4094
4095 /* Start with empty events requests list */
4096 tab->events_requests = NULL;
4097 tab->events_request_pending = FALSE;
4098 tab->stop_foreground = FALSE;
4099
4100
4101
4102 g_signal_connect(G_OBJECT(tab->scrollbar), "value-changed",
4103 G_CALLBACK(scroll_value_changed_cb), tab);
4104
4105
4106 /* Timebar signal handler */
4107 g_signal_connect(G_OBJECT(tab->MTimebar), "start-time-changed",
4108 G_CALLBACK(on_timebar_starttime_changed), tab);
4109 g_signal_connect(G_OBJECT(tab->MTimebar), "end-time-changed",
4110 G_CALLBACK(on_timebar_endtime_changed), tab);
4111 g_signal_connect(G_OBJECT(tab->MTimebar), "current-time-changed",
4112 G_CALLBACK(on_timebar_currenttime_changed), tab);
4113
4114 //g_signal_connect(G_OBJECT(tab->scrollbar), "changed",
4115 // G_CALLBACK(scroll_value_changed_cb), tab);
4116
4117
4118 //insert tab into notebook
4119 gtk_notebook_append_page(notebook,
4120 tab->vbox,
4121 tab->label);
4122 list = gtk_container_get_children(GTK_CONTAINER(notebook));
4123 gtk_notebook_set_current_page(notebook,g_list_length(list)-1);
4124 // always show : not if(g_list_length(list)>1)
4125 gtk_notebook_set_show_tabs(notebook, TRUE);
4126
4127 if(copy_tab) {
4128 lttvwindow_report_time_window(tab, copy_tab->time_window);
4129 lttvwindow_report_current_time(tab, copy_tab->current_time);
4130 } else {
4131 TimeWindow time_window;
4132
4133 time_window.start_time = ltt_time_zero;
4134 time_window.end_time = ltt_time_add(time_window.start_time,
4135 lttvwindow_default_time_width);
4136 time_window.time_width = lttvwindow_default_time_width;
4137 time_window.time_width_double = ltt_time_to_double(time_window.time_width);
4138
4139 lttvwindow_report_time_window(tab, time_window);
4140 lttvwindow_report_current_time(tab, ltt_time_zero);
4141 }
4142
4143 LttvTraceset *traceset = tab->traceset_info->traceset;
4144 SetTraceset(tab, traceset);
4145 }
4146
4147 /*
4148 * execute_events_requests
4149 *
4150 * Idle function that executes the pending requests for a tab.
4151 *
4152 * @return return value : TRUE : keep the idle function, FALSE : remove it.
4153 */
4154 gboolean execute_events_requests(Tab *tab)
4155 {
4156 return ( lttvwindow_process_pending_requests(tab) );
4157 }
4158
4159
4160 __EXPORT void create_main_window_with_trace_list(GSList *traces)
4161 {
4162
4163 GSList *iter = NULL;
4164
4165 /* Create window */
4166 MainWindow *mw = construct_main_window(NULL);
4167 GtkWidget *widget = mw->mwindow;
4168
4169 GtkWidget * notebook = lookup_widget(widget, "MNotebook");
4170 GtkWidget *page = gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook),
4171 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook)));
4172 LttvPluginTab *ptab;
4173 Tab *tab;
4174
4175 if(!page) {
4176 ptab = create_new_tab(widget, NULL);
4177 tab = ptab->tab;
4178 } else {
4179 ptab = (LttvPluginTab *)g_object_get_data(G_OBJECT(page), "Tab_Plugin");
4180 tab = ptab->tab;
4181 }
4182
4183 LttvTraceset * traceset = lttv_traceset_new();
4184 for(iter=traces; iter!=NULL; iter=g_slist_next(iter)) {
4185 gchar *path = (gchar*)iter->data;
4186 /* Add trace */
4187 gchar abs_path[PATH_MAX];
4188
4189
4190 get_absolute_pathname(path, abs_path);
4191
4192 if(lttv_traceset_add_path(traceset,abs_path) != 0 ){ /*failure*/
4193
4194 g_warning("cannot open trace %s", abs_path);
4195
4196 GtkWidget *dialogue =
4197 gtk_message_dialog_new(
4198 GTK_WINDOW(gtk_widget_get_toplevel(widget)),
4199 GTK_DIALOG_MODAL|GTK_DIALOG_DESTROY_WITH_PARENT,
4200 GTK_MESSAGE_ERROR,
4201 GTK_BUTTONS_OK,
4202 "Cannot open trace : maybe you should enter in the directory "
4203 "to select it ?");
4204 gtk_dialog_run(GTK_DIALOG(dialogue));
4205 gtk_widget_destroy(dialogue);
4206 }
4207 else{
4208 SetTraceset(tab, traceset);
4209 }
4210 }
4211 }
4212
This page took 0.184965 seconds and 4 git commands to generate.