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