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