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