fix trace directory selection
[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 GtkFileSelection * file_selector = (GtkFileSelection *)gtk_file_selection_new("Select a trace");
1703 gtk_widget_hide( (file_selector)->file_list->parent) ;
1704 gtk_file_selection_hide_fileop_buttons(file_selector);
1705
1706 if(remember_trace_dir[0] != '\0')
1707 gtk_file_selection_set_filename(file_selector, remember_trace_dir);
1708
1709 id = gtk_dialog_run(GTK_DIALOG(file_selector));
1710 switch(id){
1711 case GTK_RESPONSE_ACCEPT:
1712 case GTK_RESPONSE_OK:
1713 dir = gtk_file_selection_get_filename (file_selector);
1714 strncpy(remember_trace_dir, dir, PATH_MAX);
1715 strncat(remember_trace_dir, "/", PATH_MAX);
1716 if(!dir || strlen(dir) == 0){
1717 gtk_widget_destroy((GtkWidget*)file_selector);
1718 break;
1719 }
1720 get_absolute_pathname(dir, abs_path);
1721 trace_v = lttvwindowtraces_get_trace_by_name(abs_path);
1722 if(trace_v == NULL) {
1723 trace = ltt_trace_open(abs_path);
1724 if(trace == NULL) {
1725 g_warning("cannot open trace %s", abs_path);
1726 } else {
1727 trace_v = lttv_trace_new(trace);
1728 lttvwindowtraces_add_trace(trace_v);
1729 lttvwindow_add_trace(tab, trace_v);
1730 }
1731 } else {
1732 lttvwindow_add_trace(tab, trace_v);
1733 }
1734
1735 gtk_widget_destroy((GtkWidget*)file_selector);
1736
1737 //update current tab
1738 //update_traceset(mw_data);
1739
1740 /* Call the updatetraceset hooks */
1741
1742 traceset = tab->traceset_info->traceset;
1743 SetTraceset(tab, traceset);
1744 // in expose now call_pending_read_hooks(mw_data);
1745
1746 //lttvwindow_report_current_time(mw_data,&(tab->current_time));
1747 break;
1748 case GTK_RESPONSE_REJECT:
1749 case GTK_RESPONSE_CANCEL:
1750 default:
1751 gtk_widget_destroy((GtkWidget*)file_selector);
1752 break;
1753 }
1754 }
1755
1756 /* remove_trace removes a trace from the current traceset if all viewers in
1757 * the current tab are not interested in the trace. It first displays a
1758 * dialogue, which shows all traces in the current traceset, to let user choose
1759 * a trace, then it checks if all viewers unselect the trace, if it is true,
1760 * it will remove the trace, recreate the traceset_contex,
1761 * and redraws all the viewer of the current tab. If there is on trace in the
1762 * current traceset, it will delete all viewers of the current tab
1763 *
1764 * It destroys the filter tree. FIXME... we should request for an update
1765 * instead.
1766 */
1767
1768 void remove_trace(GtkWidget *widget, gpointer user_data)
1769 {
1770 LttTrace *trace;
1771 LttvTrace * trace_v;
1772 LttvTraceset * traceset;
1773 gint i, j, nb_trace, index=-1;
1774 char ** name, *remove_trace_name;
1775 MainWindow * mw_data = get_window_data_struct(widget);
1776 GtkWidget * notebook = lookup_widget(widget, "MNotebook");
1777
1778 GtkWidget *page = gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook),
1779 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook)));
1780 Tab *tab;
1781
1782 if(!page) {
1783 return;
1784 } else {
1785 tab = (Tab *)g_object_get_data(G_OBJECT(page), "Tab_Info");
1786 }
1787
1788 nb_trace =lttv_traceset_number(tab->traceset_info->traceset);
1789 name = g_new(char*,nb_trace);
1790 for(i = 0; i < nb_trace; i++){
1791 trace_v = lttv_traceset_get(tab->traceset_info->traceset, i);
1792 trace = lttv_trace(trace_v);
1793 name[i] = g_quark_to_string(ltt_trace_name(trace));
1794 }
1795
1796 remove_trace_name = get_remove_trace(name, nb_trace);
1797
1798
1799 if(remove_trace_name){
1800
1801 /* yuk, cut n paste from old code.. should be better (MD)*/
1802 for(i = 0; i<nb_trace; i++) {
1803 if(strcmp(remove_trace_name,name[i]) == 0){
1804 index = i;
1805 }
1806 }
1807
1808 traceset = tab->traceset_info->traceset;
1809 //Keep a reference to the traces so they are not freed.
1810 for(j=0; j<lttv_traceset_number(traceset); j++)
1811 {
1812 LttvTrace * trace = lttv_traceset_get(traceset, j);
1813 lttv_trace_ref(trace);
1814 }
1815
1816 //remove state update hooks
1817 lttv_state_remove_event_hooks(
1818 (LttvTracesetState*)tab->traceset_info->traceset_context);
1819 lttv_context_fini(LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context));
1820 g_object_unref(tab->traceset_info->traceset_context);
1821
1822 trace_v = lttv_traceset_get(traceset, index);
1823
1824 lttv_traceset_remove(traceset, index);
1825 lttv_trace_unref(trace_v); // Remove local reference
1826
1827 if(lttv_trace_get_ref_number(trace_v) <= 1) {
1828 /* ref 1 : lttvwindowtraces only*/
1829 ltt_trace_close(lttv_trace(trace_v));
1830 /* lttvwindowtraces_remove_trace takes care of destroying
1831 * the traceset linked with the trace_v and also of destroying
1832 * the trace_v at the same time.
1833 */
1834 lttvwindowtraces_remove_trace(trace_v);
1835 }
1836
1837 tab->traceset_info->traceset_context =
1838 g_object_new(LTTV_TRACESET_STATS_TYPE, NULL);
1839 lttv_context_init(
1840 LTTV_TRACESET_CONTEXT(tab->
1841 traceset_info->traceset_context),traceset);
1842 //add state update hooks
1843 lttv_state_add_event_hooks(
1844 (LttvTracesetState*)tab->traceset_info->traceset_context);
1845
1846 //Remove local reference to the traces.
1847 for(j=0; j<lttv_traceset_number(traceset); j++)
1848 {
1849 LttvTrace * trace = lttv_traceset_get(traceset, j);
1850 lttv_trace_unref(trace);
1851 }
1852
1853 SetTraceset(tab, (gpointer)traceset);
1854 }
1855 g_free(name);
1856 }
1857
1858 #if 0
1859 void remove_trace(GtkWidget * widget, gpointer user_data)
1860 {
1861 LttTrace *trace;
1862 LttvTrace * trace_v;
1863 LttvTraceset * traceset;
1864 gint i, j, nb_trace;
1865 char ** name, *remove_trace_name;
1866 MainWindow * mw_data = get_window_data_struct(widget);
1867 LttvTracesetSelector * s;
1868 LttvTraceSelector * t;
1869 GtkWidget * w;
1870 gboolean selected;
1871 GtkWidget * notebook = lookup_widget(widget, "MNotebook");
1872
1873 GtkWidget *page = gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook),
1874 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook)));
1875 Tab *tab;
1876
1877 if(!page) {
1878 return;
1879 } else {
1880 tab = (Tab *)g_object_get_data(G_OBJECT(page), "Tab_Info");
1881 }
1882
1883 nb_trace =lttv_traceset_number(tab->traceset_info->traceset);
1884 name = g_new(char*,nb_trace);
1885 for(i = 0; i < nb_trace; i++){
1886 trace_v = lttv_traceset_get(tab->traceset_info->traceset, i);
1887 trace = lttv_trace(trace_v);
1888 name[i] = ltt_trace_name(trace);
1889 }
1890
1891 remove_trace_name = get_remove_trace(name, nb_trace);
1892
1893 if(remove_trace_name){
1894 for(i=0; i<nb_trace; i++){
1895 if(strcmp(remove_trace_name,name[i]) == 0){
1896 //unselect the trace from the current viewer
1897 //FIXME
1898 w = gtk_multivpaned_get_widget(GTK_MULTIVPANED(tab->multivpaned));
1899 if(w){
1900 s = g_object_get_data(G_OBJECT(w), "Traceset_Selector");
1901 if(s){
1902 t = lttv_traceset_selector_trace_get(s,i);
1903 lttv_trace_selector_set_selected(t, FALSE);
1904 }
1905
1906 //check if other viewers select the trace
1907 w = gtk_multivpaned_get_first_widget(GTK_MULTIVPANED(tab->multivpaned));
1908 while(w){
1909 s = g_object_get_data(G_OBJECT(w), "Traceset_Selector");
1910 if(s){
1911 t = lttv_traceset_selector_trace_get(s,i);
1912 selected = lttv_trace_selector_get_selected(t);
1913 if(selected)break;
1914 }
1915 w = gtk_multivpaned_get_next_widget(GTK_MULTIVPANED(tab->multivpaned));
1916 }
1917 }else selected = FALSE;
1918
1919 //if no viewer selects the trace, remove it
1920 if(!selected){
1921 remove_trace_from_traceset_selector(GTK_MULTIVPANED(tab->multivpaned), i);
1922
1923 traceset = tab->traceset_info->traceset;
1924 //Keep a reference to the traces so they are not freed.
1925 for(j=0; j<lttv_traceset_number(traceset); j++)
1926 {
1927 LttvTrace * trace = lttv_traceset_get(traceset, j);
1928 lttv_trace_ref(trace);
1929 }
1930
1931 //remove state update hooks
1932 lttv_state_remove_event_hooks(
1933 (LttvTracesetState*)tab->traceset_info->traceset_context);
1934 lttv_context_fini(LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context));
1935 g_object_unref(tab->traceset_info->traceset_context);
1936
1937
1938 trace_v = lttv_traceset_get(traceset, i);
1939
1940 if(lttv_trace_get_ref_number(trace_v) <= 2) {
1941 /* ref 2 : traceset, local */
1942 lttvwindowtraces_remove_trace(trace_v);
1943 ltt_trace_close(lttv_trace(trace_v));
1944 }
1945
1946 lttv_traceset_remove(traceset, i);
1947 lttv_trace_unref(trace_v); // Remove local reference
1948
1949 if(!lttv_trace_get_ref_number(trace_v))
1950 lttv_trace_destroy(trace_v);
1951
1952 tab->traceset_info->traceset_context =
1953 g_object_new(LTTV_TRACESET_STATS_TYPE, NULL);
1954 lttv_context_init(
1955 LTTV_TRACESET_CONTEXT(tab->
1956 traceset_info->traceset_context),traceset);
1957 //add state update hooks
1958 lttv_state_add_event_hooks(
1959 (LttvTracesetState*)tab->traceset_info->traceset_context);
1960
1961 //Remove local reference to the traces.
1962 for(j=0; j<lttv_traceset_number(traceset); j++)
1963 {
1964 LttvTrace * trace = lttv_traceset_get(traceset, j);
1965 lttv_trace_unref(trace);
1966 }
1967
1968
1969 //update current tab
1970 //update_traceset(mw_data);
1971 //if(nb_trace > 1){
1972
1973 SetTraceset(tab, (gpointer)traceset);
1974 // in expose now call_pending_read_hooks(mw_data);
1975
1976 //lttvwindow_report_current_time(mw_data,&(tab->current_time));
1977 //}else{
1978 // if(tab){
1979 // while(tab->multi_vpaned->num_children){
1980 // gtk_multi_vpaned_widget_delete(tab->multi_vpaned);
1981 // }
1982 // }
1983 //}
1984 }
1985 break;
1986 }
1987 }
1988 }
1989
1990 g_free(name);
1991 }
1992 #endif //0
1993
1994 /* Redraw all the viewers in the current tab */
1995 void redraw(GtkWidget *widget, gpointer user_data)
1996 {
1997 GtkWidget * notebook = lookup_widget(widget, "MNotebook");
1998 GtkWidget *page = gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook),
1999 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook)));
2000 Tab *tab;
2001 if(!page) {
2002 return;
2003 } else {
2004 tab = (Tab *)g_object_get_data(G_OBJECT(page), "Tab_Info");
2005 }
2006
2007 LttvHooks * tmp;
2008 LttvAttributeValue value;
2009
2010 g_assert(lttv_iattribute_find_by_path(tab->attributes, "hooks/redraw", LTTV_POINTER, &value));
2011
2012 tmp = (LttvHooks*)*(value.v_pointer);
2013 if(tmp != NULL)
2014 lttv_hooks_call(tmp,NULL);
2015 }
2016
2017
2018 void continue_processing(GtkWidget *widget, gpointer user_data)
2019 {
2020 GtkWidget * notebook = lookup_widget(widget, "MNotebook");
2021 GtkWidget *page = gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook),
2022 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook)));
2023 Tab *tab;
2024 if(!page) {
2025 return;
2026 } else {
2027 tab = (Tab *)g_object_get_data(G_OBJECT(page), "Tab_Info");
2028 }
2029
2030 LttvHooks * tmp;
2031 LttvAttributeValue value;
2032
2033 g_assert(lttv_iattribute_find_by_path(tab->attributes,
2034 "hooks/continue", LTTV_POINTER, &value));
2035
2036 tmp = (LttvHooks*)*(value.v_pointer);
2037 if(tmp != NULL)
2038 lttv_hooks_call(tmp,NULL);
2039 }
2040
2041 /* Stop the processing for the calling main window's current tab.
2042 * It removes every processing requests that are in its list. It does not call
2043 * the end request hooks, because the request is not finished.
2044 */
2045
2046 void stop_processing(GtkWidget *widget, gpointer user_data)
2047 {
2048 GtkWidget * notebook = lookup_widget(widget, "MNotebook");
2049 GtkWidget *page = gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook),
2050 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook)));
2051 Tab *tab;
2052 if(!page) {
2053 return;
2054 } else {
2055 tab = (Tab *)g_object_get_data(G_OBJECT(page), "Tab_Info");
2056 }
2057 GSList *iter = tab->events_requests;
2058
2059 while(iter != NULL) {
2060 GSList *remove_iter = iter;
2061 iter = g_slist_next(iter);
2062
2063 g_free(remove_iter->data);
2064 tab->events_requests =
2065 g_slist_remove_link(tab->events_requests, remove_iter);
2066 }
2067 tab->events_request_pending = FALSE;
2068 g_idle_remove_by_data(tab);
2069 g_assert(g_slist_length(tab->events_requests) == 0);
2070 }
2071
2072
2073 /* save will save the traceset to a file
2074 * Not implemented yet FIXME
2075 */
2076
2077 void save(GtkWidget * widget, gpointer user_data)
2078 {
2079 g_info("Save\n");
2080 }
2081
2082 void save_as(GtkWidget * widget, gpointer user_data)
2083 {
2084 g_info("Save as\n");
2085 }
2086
2087
2088 /* zoom will change the time_window of all the viewers of the
2089 * current tab, and redisplay them. The main functionality is to
2090 * determine the new time_window of the current tab
2091 */
2092
2093 void zoom(GtkWidget * widget, double size)
2094 {
2095 TimeInterval time_span;
2096 TimeWindow new_time_window;
2097 LttTime current_time, time_delta;
2098 MainWindow * mw_data = get_window_data_struct(widget);
2099 LttvTracesetContext *tsc;
2100 GtkWidget * notebook = lookup_widget(widget, "MNotebook");
2101
2102 GtkWidget *page = gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook),
2103 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook)));
2104 Tab *tab;
2105
2106 if(!page) {
2107 return;
2108 } else {
2109 tab = (Tab *)g_object_get_data(G_OBJECT(page), "Tab_Info");
2110 }
2111
2112 if(size == 1) return;
2113
2114 tsc = LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context);
2115 time_span = tsc->time_span;
2116 new_time_window = tab->time_window;
2117 current_time = tab->current_time;
2118
2119 time_delta = ltt_time_sub(time_span.end_time,time_span.start_time);
2120 if(size == 0){
2121 new_time_window.start_time = time_span.start_time;
2122 new_time_window.time_width = time_delta;
2123 new_time_window.time_width_double = ltt_time_to_double(time_delta);
2124 new_time_window.end_time = ltt_time_add(new_time_window.start_time,
2125 new_time_window.time_width) ;
2126 }else{
2127 new_time_window.time_width = ltt_time_div(new_time_window.time_width, size);
2128 new_time_window.time_width_double =
2129 ltt_time_to_double(new_time_window.time_width);
2130 if(ltt_time_compare(new_time_window.time_width,time_delta) > 0)
2131 { /* Case where zoom out is bigger than trace length */
2132 new_time_window.start_time = time_span.start_time;
2133 new_time_window.time_width = time_delta;
2134 new_time_window.time_width_double = ltt_time_to_double(time_delta);
2135 new_time_window.end_time = ltt_time_add(new_time_window.start_time,
2136 new_time_window.time_width) ;
2137 }
2138 else
2139 {
2140 /* Center the image on the current time */
2141 new_time_window.start_time =
2142 ltt_time_sub(current_time,
2143 ltt_time_from_double(new_time_window.time_width_double/2.0));
2144 new_time_window.end_time = ltt_time_add(new_time_window.start_time,
2145 new_time_window.time_width) ;
2146 /* If on borders, don't fall off */
2147 if(ltt_time_compare(new_time_window.start_time, time_span.start_time) <0)
2148 {
2149 new_time_window.start_time = time_span.start_time;
2150 new_time_window.end_time = ltt_time_add(new_time_window.start_time,
2151 new_time_window.time_width) ;
2152 }
2153 else
2154 {
2155 if(ltt_time_compare(new_time_window.end_time,
2156 time_span.end_time) > 0)
2157 {
2158 new_time_window.start_time =
2159 ltt_time_sub(time_span.end_time, new_time_window.time_width);
2160
2161 new_time_window.end_time = ltt_time_add(new_time_window.start_time,
2162 new_time_window.time_width) ;
2163 }
2164 }
2165
2166 }
2167 }
2168
2169 if(ltt_time_compare(new_time_window.time_width, ltt_time_zero) == 0) {
2170 g_warning("Zoom more than 1 ns impossible");
2171 } else {
2172 time_change_manager(tab, new_time_window);
2173 }
2174 }
2175
2176 void zoom_in(GtkWidget * widget, gpointer user_data)
2177 {
2178 zoom(widget, 2);
2179 }
2180
2181 void zoom_out(GtkWidget * widget, gpointer user_data)
2182 {
2183 zoom(widget, 0.5);
2184 }
2185
2186 void zoom_extended(GtkWidget * widget, gpointer user_data)
2187 {
2188 zoom(widget, 0);
2189 }
2190
2191 void go_to_time(GtkWidget * widget, gpointer user_data)
2192 {
2193 g_info("Go to time\n");
2194 }
2195
2196 void show_time_frame(GtkWidget * widget, gpointer user_data)
2197 {
2198 g_info("Show time frame\n");
2199 }
2200
2201
2202 /* callback function */
2203
2204 void
2205 on_empty_traceset_activate (GtkMenuItem *menuitem,
2206 gpointer user_data)
2207 {
2208 create_new_window((GtkWidget*)menuitem, user_data, FALSE);
2209 }
2210
2211
2212 void
2213 on_clone_traceset_activate (GtkMenuItem *menuitem,
2214 gpointer user_data)
2215 {
2216 create_new_window((GtkWidget*)menuitem, user_data, TRUE);
2217 }
2218
2219
2220 /* create_new_tab calls create_tab to construct a new tab in the main window
2221 */
2222
2223 Tab *create_new_tab(GtkWidget* widget, gpointer user_data){
2224 gchar label[PATH_MAX];
2225 MainWindow * mw_data = get_window_data_struct(widget);
2226
2227 GtkNotebook * notebook = (GtkNotebook *)lookup_widget(widget, "MNotebook");
2228 if(notebook == NULL){
2229 g_info("Notebook does not exist\n");
2230 return NULL;
2231 }
2232 GtkWidget *page = gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook),
2233 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook)));
2234 Tab *copy_tab;
2235
2236 if(!page) {
2237 copy_tab = NULL;
2238 } else {
2239 copy_tab = (Tab *)g_object_get_data(G_OBJECT(page), "Tab_Info");
2240 }
2241
2242 strcpy(label,"Page");
2243 if(get_label(mw_data, label,"Get the name of the tab","Please input tab's name"))
2244 return (create_tab (mw_data, copy_tab, notebook, label));
2245 else
2246 return NULL;
2247 }
2248
2249 void
2250 on_tab_activate (GtkMenuItem *menuitem,
2251 gpointer user_data)
2252 {
2253 create_new_tab((GtkWidget*)menuitem, user_data);
2254 }
2255
2256
2257 void
2258 on_open_activate (GtkMenuItem *menuitem,
2259 gpointer user_data)
2260 {
2261 open_traceset((GtkWidget*)menuitem, user_data);
2262 }
2263
2264
2265 void
2266 on_close_activate (GtkMenuItem *menuitem,
2267 gpointer user_data)
2268 {
2269 MainWindow * mw_data = get_window_data_struct((GtkWidget*)menuitem);
2270 main_window_destructor(mw_data);
2271 }
2272
2273
2274 /* remove the current tab from the main window
2275 */
2276
2277 void
2278 on_close_tab_activate (GtkWidget *widget,
2279 gpointer user_data)
2280 {
2281 gint page_num;
2282 GtkWidget * notebook;
2283 GtkWidget * page;
2284 MainWindow * mw_data = get_window_data_struct(widget);
2285 notebook = lookup_widget(widget, "MNotebook");
2286 if(notebook == NULL){
2287 g_info("Notebook does not exist\n");
2288 return;
2289 }
2290
2291 page_num = gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook));
2292
2293 gtk_notebook_remove_page(GTK_NOTEBOOK(notebook), page_num);
2294
2295 }
2296
2297 void
2298 on_close_tab_X_clicked (GtkWidget *widget,
2299 gpointer user_data)
2300 {
2301 gint page_num;
2302 GtkWidget *notebook = lookup_widget(widget, "MNotebook");
2303 if(notebook == NULL){
2304 g_info("Notebook does not exist\n");
2305 return;
2306 }
2307
2308 if((page_num = gtk_notebook_page_num(GTK_NOTEBOOK(notebook), widget)) != -1)
2309 gtk_notebook_remove_page(GTK_NOTEBOOK(notebook), page_num);
2310
2311 }
2312
2313
2314 void
2315 on_add_trace_activate (GtkMenuItem *menuitem,
2316 gpointer user_data)
2317 {
2318 add_trace((GtkWidget*)menuitem, user_data);
2319 }
2320
2321
2322 void
2323 on_remove_trace_activate (GtkMenuItem *menuitem,
2324 gpointer user_data)
2325 {
2326 remove_trace((GtkWidget*)menuitem, user_data);
2327 }
2328
2329
2330 void
2331 on_save_activate (GtkMenuItem *menuitem,
2332 gpointer user_data)
2333 {
2334 save((GtkWidget*)menuitem, user_data);
2335 }
2336
2337
2338 void
2339 on_save_as_activate (GtkMenuItem *menuitem,
2340 gpointer user_data)
2341 {
2342 save_as((GtkWidget*)menuitem, user_data);
2343 }
2344
2345
2346 void
2347 on_quit_activate (GtkMenuItem *menuitem,
2348 gpointer user_data)
2349 {
2350 mainwindow_quit();
2351 }
2352
2353
2354 void
2355 on_cut_activate (GtkMenuItem *menuitem,
2356 gpointer user_data)
2357 {
2358 g_info("Cut\n");
2359 }
2360
2361
2362 void
2363 on_copy_activate (GtkMenuItem *menuitem,
2364 gpointer user_data)
2365 {
2366 g_info("Copye\n");
2367 }
2368
2369
2370 void
2371 on_paste_activate (GtkMenuItem *menuitem,
2372 gpointer user_data)
2373 {
2374 g_info("Paste\n");
2375 }
2376
2377
2378 void
2379 on_delete_activate (GtkMenuItem *menuitem,
2380 gpointer user_data)
2381 {
2382 g_info("Delete\n");
2383 }
2384
2385
2386 void
2387 on_zoom_in_activate (GtkMenuItem *menuitem,
2388 gpointer user_data)
2389 {
2390 zoom_in((GtkWidget*)menuitem, user_data);
2391 }
2392
2393
2394 void
2395 on_zoom_out_activate (GtkMenuItem *menuitem,
2396 gpointer user_data)
2397 {
2398 zoom_out((GtkWidget*)menuitem, user_data);
2399 }
2400
2401
2402 void
2403 on_zoom_extended_activate (GtkMenuItem *menuitem,
2404 gpointer user_data)
2405 {
2406 zoom_extended((GtkWidget*)menuitem, user_data);
2407 }
2408
2409
2410 void
2411 on_go_to_time_activate (GtkMenuItem *menuitem,
2412 gpointer user_data)
2413 {
2414 go_to_time((GtkWidget*)menuitem, user_data);
2415 }
2416
2417
2418 void
2419 on_show_time_frame_activate (GtkMenuItem *menuitem,
2420 gpointer user_data)
2421 {
2422 show_time_frame((GtkWidget*)menuitem, user_data);
2423 }
2424
2425
2426 void
2427 on_move_viewer_up_activate (GtkMenuItem *menuitem,
2428 gpointer user_data)
2429 {
2430 move_up_viewer((GtkWidget*)menuitem, user_data);
2431 }
2432
2433
2434 void
2435 on_move_viewer_down_activate (GtkMenuItem *menuitem,
2436 gpointer user_data)
2437 {
2438 move_down_viewer((GtkWidget*)menuitem, user_data);
2439 }
2440
2441
2442 void
2443 on_remove_viewer_activate (GtkMenuItem *menuitem,
2444 gpointer user_data)
2445 {
2446 delete_viewer((GtkWidget*)menuitem, user_data);
2447 }
2448
2449 void
2450 on_trace_facility_activate (GtkMenuItem *menuitem,
2451 gpointer user_data)
2452 {
2453 g_info("Trace facility selector: %s\n");
2454 }
2455
2456
2457 /* Dispaly a file selection dialogue to let user select a library, then call
2458 * lttv_library_load().
2459 */
2460
2461 void
2462 on_load_library_activate (GtkMenuItem *menuitem,
2463 gpointer user_data)
2464 {
2465 GError *error = NULL;
2466 MainWindow * mw_data = get_window_data_struct((GtkWidget*)menuitem);
2467
2468 gchar load_module_path_alter[PATH_MAX];
2469 {
2470 GPtrArray *name;
2471 guint nb,i;
2472 gchar *load_module_path;
2473 name = g_ptr_array_new();
2474 nb = lttv_library_path_number();
2475 /* ask for the library path */
2476
2477 for(i=0;i<nb;i++){
2478 gchar *path;
2479 path = lttv_library_path_get(i);
2480 g_ptr_array_add(name, path);
2481 }
2482
2483 load_module_path = get_selection((char **)(name->pdata), name->len,
2484 "Select a library path", "Library paths");
2485 if(load_module_path != NULL)
2486 strncpy(load_module_path_alter, load_module_path, PATH_MAX-1); // -1 for /
2487
2488 g_ptr_array_free(name, TRUE);
2489
2490 if(load_module_path == NULL) return;
2491 }
2492
2493 {
2494 /* Make sure the module path ends with a / */
2495 gchar *ptr = load_module_path_alter;
2496
2497 ptr = strchr(ptr, '\0');
2498
2499 if(*(ptr-1) != '/') {
2500 *ptr = '/';
2501 *(ptr+1) = '\0';
2502 }
2503 }
2504
2505 {
2506 /* Ask for the library to load : list files in the previously selected
2507 * directory */
2508 gchar str[PATH_MAX];
2509 gchar ** dir;
2510 gint id;
2511 GtkFileSelection * file_selector =
2512 (GtkFileSelection *)gtk_file_selection_new("Select a module");
2513 gtk_file_selection_set_filename(file_selector, load_module_path_alter);
2514 gtk_file_selection_hide_fileop_buttons(file_selector);
2515
2516 str[0] = '\0';
2517 id = gtk_dialog_run(GTK_DIALOG(file_selector));
2518 switch(id){
2519 case GTK_RESPONSE_ACCEPT:
2520 case GTK_RESPONSE_OK:
2521 dir = gtk_file_selection_get_selections (file_selector);
2522 strncpy(str,dir[0],PATH_MAX);
2523 strncpy(remember_plugins_dir,dir[0],PATH_MAX);
2524 /* only keep file name */
2525 gchar *str1;
2526 str1 = strrchr(str,'/');
2527 if(str1)str1++;
2528 else{
2529 str1 = strrchr(str,'\\');
2530 str1++;
2531 }
2532 #if 0
2533 /* remove "lib" */
2534 if(*str1 == 'l' && *(str1+1)== 'i' && *(str1+2)=='b')
2535 str1=str1+3;
2536 remove info after . */
2537 {
2538 gchar *str2 = str1;
2539
2540 str2 = strrchr(str2, '.');
2541 if(str2 != NULL) *str2 = '\0';
2542 }
2543 lttv_module_require(str1, &error);
2544 #endif //0
2545 lttv_library_load(str1, &error);
2546 if(error != NULL) g_warning("%s", error->message);
2547 else g_info("Load library: %s\n", str);
2548 g_strfreev(dir);
2549 case GTK_RESPONSE_REJECT:
2550 case GTK_RESPONSE_CANCEL:
2551 default:
2552 gtk_widget_destroy((GtkWidget*)file_selector);
2553 break;
2554 }
2555
2556 }
2557
2558
2559
2560 }
2561
2562
2563 /* Display all loaded modules, let user to select a module to unload
2564 * by calling lttv_module_unload
2565 */
2566
2567 void
2568 on_unload_library_activate (GtkMenuItem *menuitem,
2569 gpointer user_data)
2570 {
2571 MainWindow * mw_data = get_window_data_struct((GtkWidget*)menuitem);
2572
2573 LttvLibrary *library = NULL;
2574
2575 GPtrArray *name;
2576 guint nb,i;
2577 gchar *lib_name;
2578 name = g_ptr_array_new();
2579 nb = lttv_library_number();
2580 LttvLibraryInfo *lib_info = g_new(LttvLibraryInfo,nb);
2581 /* ask for the library name */
2582
2583 for(i=0;i<nb;i++){
2584 LttvLibrary *iter_lib = lttv_library_get(i);
2585 lttv_library_info(iter_lib, &lib_info[i]);
2586
2587 gchar *path = lib_info[i].name;
2588 g_ptr_array_add(name, path);
2589 }
2590 lib_name = get_selection((char **)(name->pdata), name->len,
2591 "Select a library", "Libraries");
2592 if(lib_name != NULL) {
2593 for(i=0;i<nb;i++){
2594 if(strcmp(lib_name, lib_info[i].name) == 0) {
2595 library = lttv_library_get(i);
2596 break;
2597 }
2598 }
2599 }
2600 g_ptr_array_free(name, TRUE);
2601 g_free(lib_info);
2602
2603 if(lib_name == NULL) return;
2604
2605 if(library != NULL) lttv_library_unload(library);
2606 }
2607
2608
2609 /* Dispaly a file selection dialogue to let user select a module, then call
2610 * lttv_module_require().
2611 */
2612
2613 void
2614 on_load_module_activate (GtkMenuItem *menuitem,
2615 gpointer user_data)
2616 {
2617 GError *error = NULL;
2618 MainWindow * mw_data = get_window_data_struct((GtkWidget*)menuitem);
2619
2620 LttvLibrary *library = NULL;
2621 {
2622 GPtrArray *name;
2623 guint nb,i;
2624 gchar *lib_name;
2625 name = g_ptr_array_new();
2626 nb = lttv_library_number();
2627 LttvLibraryInfo *lib_info = g_new(LttvLibraryInfo,nb);
2628 /* ask for the library name */
2629
2630 for(i=0;i<nb;i++){
2631 LttvLibrary *iter_lib = lttv_library_get(i);
2632 lttv_library_info(iter_lib, &lib_info[i]);
2633
2634 gchar *path = lib_info[i].name;
2635 g_ptr_array_add(name, path);
2636 }
2637 lib_name = get_selection((char **)(name->pdata), name->len,
2638 "Select a library", "Libraries");
2639 if(lib_name != NULL) {
2640 for(i=0;i<nb;i++){
2641 if(strcmp(lib_name, lib_info[i].name) == 0) {
2642 library = lttv_library_get(i);
2643 break;
2644 }
2645 }
2646 }
2647 g_ptr_array_free(name, TRUE);
2648 g_free(lib_info);
2649
2650 if(lib_name == NULL) return;
2651 }
2652
2653 //LttvModule *module;
2654 gchar module_name_out[PATH_MAX];
2655 {
2656 /* Ask for the module to load : list modules in the selected lib */
2657 GPtrArray *name;
2658 guint nb,i;
2659 gchar *module_name;
2660 nb = lttv_library_module_number(library);
2661 LttvModuleInfo *module_info = g_new(LttvModuleInfo,nb);
2662 name = g_ptr_array_new();
2663 /* ask for the module name */
2664
2665 for(i=0;i<nb;i++){
2666 LttvModule *iter_module = lttv_library_module_get(library, i);
2667 lttv_module_info(iter_module, &module_info[i]);
2668
2669 gchar *path = module_info[i].name;
2670 g_ptr_array_add(name, path);
2671 }
2672 module_name = get_selection((char **)(name->pdata), name->len,
2673 "Select a module", "Modules");
2674 if(module_name != NULL) {
2675 for(i=0;i<nb;i++){
2676 if(strcmp(module_name, module_info[i].name) == 0) {
2677 strncpy(module_name_out, module_name, PATH_MAX);
2678 //module = lttv_library_module_get(i);
2679 break;
2680 }
2681 }
2682 }
2683
2684 g_ptr_array_free(name, TRUE);
2685 g_free(module_info);
2686
2687 if(module_name == NULL) return;
2688 }
2689
2690 lttv_module_require(module_name_out, &error);
2691 if(error != NULL) g_warning("%s", error->message);
2692 else g_info("Load module: %s", module_name_out);
2693
2694
2695 #if 0
2696 {
2697
2698
2699 gchar str[PATH_MAX];
2700 gchar ** dir;
2701 gint id;
2702 GtkFileSelection * file_selector =
2703 (GtkFileSelection *)gtk_file_selection_new("Select a module");
2704 gtk_file_selection_set_filename(file_selector, load_module_path_alter);
2705 gtk_file_selection_hide_fileop_buttons(file_selector);
2706
2707 str[0] = '\0';
2708 id = gtk_dialog_run(GTK_DIALOG(file_selector));
2709 switch(id){
2710 case GTK_RESPONSE_ACCEPT:
2711 case GTK_RESPONSE_OK:
2712 dir = gtk_file_selection_get_selections (file_selector);
2713 strncpy(str,dir[0],PATH_MAX);
2714 strncpy(remember_plugins_dir,dir[0],PATH_MAX);
2715 {
2716 /* only keep file name */
2717 gchar *str1;
2718 str1 = strrchr(str,'/');
2719 if(str1)str1++;
2720 else{
2721 str1 = strrchr(str,'\\');
2722 str1++;
2723 }
2724 #if 0
2725 /* remove "lib" */
2726 if(*str1 == 'l' && *(str1+1)== 'i' && *(str1+2)=='b')
2727 str1=str1+3;
2728 remove info after . */
2729 {
2730 gchar *str2 = str1;
2731
2732 str2 = strrchr(str2, '.');
2733 if(str2 != NULL) *str2 = '\0';
2734 }
2735 lttv_module_require(str1, &error);
2736 #endif //0
2737 lttv_library_load(str1, &error);
2738 if(error != NULL) g_warning(error->message);
2739 else g_info("Load library: %s\n", str);
2740 g_strfreev(dir);
2741 case GTK_RESPONSE_REJECT:
2742 case GTK_RESPONSE_CANCEL:
2743 default:
2744 gtk_widget_destroy((GtkWidget*)file_selector);
2745 break;
2746 }
2747
2748 }
2749 #endif //0
2750
2751
2752 }
2753
2754
2755
2756 /* Display all loaded modules, let user to select a module to unload
2757 * by calling lttv_module_unload
2758 */
2759
2760 void
2761 on_unload_module_activate (GtkMenuItem *menuitem,
2762 gpointer user_data)
2763 {
2764 GError *error = NULL;
2765 MainWindow * mw_data = get_window_data_struct((GtkWidget*)menuitem);
2766
2767 LttvLibrary *library;
2768 {
2769 GPtrArray *name;
2770 guint nb,i;
2771 gchar *lib_name;
2772 name = g_ptr_array_new();
2773 nb = lttv_library_number();
2774 LttvLibraryInfo *lib_info = g_new(LttvLibraryInfo,nb);
2775 /* ask for the library name */
2776
2777 for(i=0;i<nb;i++){
2778 LttvLibrary *iter_lib = lttv_library_get(i);
2779 lttv_library_info(iter_lib, &lib_info[i]);
2780
2781 gchar *path = lib_info[i].name;
2782 g_ptr_array_add(name, path);
2783 }
2784 lib_name = get_selection((char **)(name->pdata), name->len,
2785 "Select a library", "Libraries");
2786 if(lib_name != NULL) {
2787 for(i=0;i<nb;i++){
2788 if(strcmp(lib_name, lib_info[i].name) == 0) {
2789 library = lttv_library_get(i);
2790 break;
2791 }
2792 }
2793 }
2794 g_ptr_array_free(name, TRUE);
2795 g_free(lib_info);
2796
2797 if(lib_name == NULL) return;
2798 }
2799
2800 LttvModule *module = NULL;
2801 {
2802 /* Ask for the module to load : list modules in the selected lib */
2803 GPtrArray *name;
2804 guint nb,i;
2805 gchar *module_name;
2806 nb = lttv_library_module_number(library);
2807 LttvModuleInfo *module_info = g_new(LttvModuleInfo,nb);
2808 name = g_ptr_array_new();
2809 /* ask for the module name */
2810
2811 for(i=0;i<nb;i++){
2812 LttvModule *iter_module = lttv_library_module_get(library, i);
2813 lttv_module_info(iter_module, &module_info[i]);
2814
2815 gchar *path = module_info[i].name;
2816 if(module_info[i].use_count > 0) g_ptr_array_add(name, path);
2817 }
2818 module_name = get_selection((char **)(name->pdata), name->len,
2819 "Select a module", "Modules");
2820 if(module_name != NULL) {
2821 for(i=0;i<nb;i++){
2822 if(strcmp(module_name, module_info[i].name) == 0) {
2823 module = lttv_library_module_get(library, i);
2824 break;
2825 }
2826 }
2827 }
2828
2829 g_ptr_array_free(name, TRUE);
2830 g_free(module_info);
2831
2832 if(module_name == NULL) return;
2833 }
2834
2835 LttvModuleInfo module_info;
2836 lttv_module_info(module, &module_info);
2837 g_info("Release module: %s\n", module_info.name);
2838
2839 lttv_module_release(module);
2840 }
2841
2842
2843 /* Display a directory dialogue to let user select a path for library searching
2844 */
2845
2846 void
2847 on_add_library_search_path_activate (GtkMenuItem *menuitem,
2848 gpointer user_data)
2849 {
2850 //GtkDirSelection * file_selector = (GtkDirSelection *)gtk_dir_selection_new("Select library path");
2851 GtkFileSelection * file_selector = (GtkFileSelection *)gtk_file_selection_new("Select a trace");
2852 gtk_widget_hide( (file_selector)->file_list->parent) ;
2853 const char * dir;
2854 gint id;
2855
2856 MainWindow * mw_data = get_window_data_struct((GtkWidget*)menuitem);
2857 if(remember_plugins_dir[0] != '\0')
2858 gtk_file_selection_set_filename(file_selector, remember_plugins_dir);
2859
2860 id = gtk_dialog_run(GTK_DIALOG(file_selector));
2861 switch(id){
2862 case GTK_RESPONSE_ACCEPT:
2863 case GTK_RESPONSE_OK:
2864 dir = gtk_file_selection_get_filename (file_selector);
2865 strncpy(remember_plugins_dir,dir,PATH_MAX);
2866 strncat(remember_plugins_dir,"/",PATH_MAX);
2867 lttv_library_path_add(dir);
2868 case GTK_RESPONSE_REJECT:
2869 case GTK_RESPONSE_CANCEL:
2870 default:
2871 gtk_widget_destroy((GtkWidget*)file_selector);
2872 break;
2873 }
2874 }
2875
2876
2877 /* Display a directory dialogue to let user select a path for library searching
2878 */
2879
2880 void
2881 on_remove_library_search_path_activate (GtkMenuItem *menuitem,
2882 gpointer user_data)
2883 {
2884 MainWindow * mw_data = get_window_data_struct((GtkWidget*)menuitem);
2885
2886 const char *lib_path;
2887 {
2888 GPtrArray *name;
2889 guint nb,i;
2890 gchar *lib_name;
2891 name = g_ptr_array_new();
2892 nb = lttv_library_path_number();
2893 /* ask for the library name */
2894
2895 for(i=0;i<nb;i++){
2896 gchar *path = lttv_library_path_get(i);
2897 g_ptr_array_add(name, path);
2898 }
2899 lib_path = get_selection((char **)(name->pdata), name->len,
2900 "Select a library path", "Library paths");
2901
2902 g_ptr_array_free(name, TRUE);
2903
2904 if(lib_path == NULL) return;
2905 }
2906
2907 lttv_library_path_remove(lib_path);
2908 }
2909
2910 void
2911 on_color_activate (GtkMenuItem *menuitem,
2912 gpointer user_data)
2913 {
2914 g_info("Color\n");
2915 }
2916
2917
2918 void
2919 on_save_configuration_activate (GtkMenuItem *menuitem,
2920 gpointer user_data)
2921 {
2922 g_info("Save configuration\n");
2923 }
2924
2925
2926 void
2927 on_content_activate (GtkMenuItem *menuitem,
2928 gpointer user_data)
2929 {
2930 g_info("Content\n");
2931 }
2932
2933
2934 static void
2935 on_about_close_activate (GtkButton *button,
2936 gpointer user_data)
2937 {
2938 GtkWidget *about_widget = GTK_WIDGET(user_data);
2939
2940 gtk_widget_destroy(about_widget);
2941 }
2942
2943 void
2944 on_about_activate (GtkMenuItem *menuitem,
2945 gpointer user_data)
2946 {
2947 MainWindow *main_window = get_window_data_struct(GTK_WIDGET(menuitem));
2948 GtkWidget *window_widget = main_window->mwindow;
2949 GtkWidget *about_widget = gtk_window_new(GTK_WINDOW_TOPLEVEL);
2950 GtkWindow *about_window = GTK_WINDOW(about_widget);
2951 gint window_width, window_height;
2952
2953 gtk_window_set_title(about_window, "About Linux Trace Toolkit");
2954
2955 gtk_window_set_resizable(about_window, FALSE);
2956 gtk_window_set_transient_for(GTK_WINDOW(window_widget), about_window);
2957 gtk_window_set_destroy_with_parent(about_window, TRUE);
2958 gtk_window_set_modal(about_window, FALSE);
2959
2960 /* Put the about window at the center of the screen */
2961 gtk_window_get_size(about_window, &window_width, &window_height);
2962 gtk_window_move (about_window,
2963 (gdk_screen_width() - window_width)/2,
2964 (gdk_screen_height() - window_height)/2);
2965
2966 GtkWidget *vbox = gtk_vbox_new(FALSE, 1);
2967
2968 gtk_container_add(GTK_CONTAINER(about_widget), vbox);
2969
2970
2971 /* Text to show */
2972 GtkWidget *label1 = gtk_label_new("");
2973 gtk_misc_set_padding(GTK_MISC(label1), 10, 20);
2974 gtk_label_set_markup(GTK_LABEL(label1), "\
2975 <big>Linux Trace Toolkit</big>");
2976 gtk_label_set_justify(GTK_LABEL(label1), GTK_JUSTIFY_CENTER);
2977
2978 GtkWidget *label2 = gtk_label_new("");
2979 gtk_misc_set_padding(GTK_MISC(label2), 10, 20);
2980 gtk_label_set_markup(GTK_LABEL(label2), "\
2981 Contributors :\n\
2982 \n\
2983 Michel Dagenais (New trace format, lttv main)\n\
2984 Mathieu Desnoyers (Kernel Tracer, Directory structure, build with automake/conf,\n\
2985 lttv gui, control flow view, gui cooperative trace reading\n\
2986 scheduler with interruptible foreground and background\n\
2987 computation, detailed event list (rewrite), trace reading\n\
2988 library (rewrite))\n\
2989 Benoit Des Ligneris, Eric Clement (Cluster adaptation, work in progress)\n\
2990 Xang-Xiu Yang (new trace reading library and converter, lttv gui, \n\
2991 detailed event list and statistics view)\n\
2992 Tom Zanussi (RelayFS)\n\
2993 \n\
2994 Strongly inspired from the original Linux Trace Toolkit Visualizer made by\n\
2995 Karim Yaghmour");
2996
2997 GtkWidget *label3 = gtk_label_new("");
2998 gtk_label_set_markup(GTK_LABEL(label3), "\
2999 Linux Trace Toolkit Viewer, Copyright (C) 2004\n\
3000 Michel Dagenais\n\
3001 Mathieu Desnoyers\n\
3002 Xang-Xiu Yang\n\
3003 Linux Trace Toolkit comes with ABSOLUTELY NO WARRANTY.\n\
3004 This is free software, and you are welcome to redistribute it\n\
3005 under certain conditions. See COPYING for details.");
3006 gtk_misc_set_padding(GTK_MISC(label3), 10, 20);
3007
3008 gtk_box_pack_start_defaults(GTK_BOX(vbox), label1);
3009 gtk_box_pack_start_defaults(GTK_BOX(vbox), label2);
3010 gtk_box_pack_start_defaults(GTK_BOX(vbox), label3);
3011
3012 GtkWidget *hbox = gtk_hbox_new(TRUE, 0);
3013 gtk_box_pack_end(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
3014 GtkWidget *close_button = gtk_button_new_with_mnemonic("_Close");
3015 gtk_box_pack_end(GTK_BOX(hbox), close_button, FALSE, FALSE, 0);
3016 gtk_container_set_border_width(GTK_CONTAINER(close_button), 20);
3017
3018 g_signal_connect(G_OBJECT(close_button), "clicked",
3019 G_CALLBACK(on_about_close_activate),
3020 (gpointer)about_widget);
3021
3022 gtk_widget_show_all(about_widget);
3023 }
3024
3025
3026 void
3027 on_button_new_clicked (GtkButton *button,
3028 gpointer user_data)
3029 {
3030 create_new_window((GtkWidget*)button, user_data, TRUE);
3031 }
3032
3033 void
3034 on_button_new_tab_clicked (GtkButton *button,
3035 gpointer user_data)
3036 {
3037 create_new_tab((GtkWidget*)button, user_data);
3038 }
3039
3040 void
3041 on_button_open_clicked (GtkButton *button,
3042 gpointer user_data)
3043 {
3044 open_traceset((GtkWidget*)button, user_data);
3045 }
3046
3047
3048 void
3049 on_button_add_trace_clicked (GtkButton *button,
3050 gpointer user_data)
3051 {
3052 add_trace((GtkWidget*)button, user_data);
3053 }
3054
3055
3056 void
3057 on_button_remove_trace_clicked (GtkButton *button,
3058 gpointer user_data)
3059 {
3060 remove_trace((GtkWidget*)button, user_data);
3061 }
3062
3063 void
3064 on_button_redraw_clicked (GtkButton *button,
3065 gpointer user_data)
3066 {
3067 redraw((GtkWidget*)button, user_data);
3068 }
3069
3070 void
3071 on_button_continue_processing_clicked (GtkButton *button,
3072 gpointer user_data)
3073 {
3074 continue_processing((GtkWidget*)button, user_data);
3075 }
3076
3077 void
3078 on_button_stop_processing_clicked (GtkButton *button,
3079 gpointer user_data)
3080 {
3081 stop_processing((GtkWidget*)button, user_data);
3082 }
3083
3084
3085
3086 void
3087 on_button_save_clicked (GtkButton *button,
3088 gpointer user_data)
3089 {
3090 save((GtkWidget*)button, user_data);
3091 }
3092
3093
3094 void
3095 on_button_save_as_clicked (GtkButton *button,
3096 gpointer user_data)
3097 {
3098 save_as((GtkWidget*)button, user_data);
3099 }
3100
3101
3102 void
3103 on_button_zoom_in_clicked (GtkButton *button,
3104 gpointer user_data)
3105 {
3106 zoom_in((GtkWidget*)button, user_data);
3107 }
3108
3109
3110 void
3111 on_button_zoom_out_clicked (GtkButton *button,
3112 gpointer user_data)
3113 {
3114 zoom_out((GtkWidget*)button, user_data);
3115 }
3116
3117
3118 void
3119 on_button_zoom_extended_clicked (GtkButton *button,
3120 gpointer user_data)
3121 {
3122 zoom_extended((GtkWidget*)button, user_data);
3123 }
3124
3125
3126 void
3127 on_button_go_to_time_clicked (GtkButton *button,
3128 gpointer user_data)
3129 {
3130 go_to_time((GtkWidget*)button, user_data);
3131 }
3132
3133
3134 void
3135 on_button_show_time_frame_clicked (GtkButton *button,
3136 gpointer user_data)
3137 {
3138 show_time_frame((GtkWidget*)button, user_data);
3139 }
3140
3141
3142 void
3143 on_button_move_up_clicked (GtkButton *button,
3144 gpointer user_data)
3145 {
3146 move_up_viewer((GtkWidget*)button, user_data);
3147 }
3148
3149
3150 void
3151 on_button_move_down_clicked (GtkButton *button,
3152 gpointer user_data)
3153 {
3154 move_down_viewer((GtkWidget*)button, user_data);
3155 }
3156
3157
3158 void
3159 on_button_delete_viewer_clicked (GtkButton *button,
3160 gpointer user_data)
3161 {
3162 delete_viewer((GtkWidget*)button, user_data);
3163 }
3164
3165 void
3166 on_MWindow_destroy (GtkWidget *widget,
3167 gpointer user_data)
3168 {
3169 MainWindow *main_window = get_window_data_struct(widget);
3170 LttvIAttribute *attributes = main_window->attributes;
3171 LttvAttributeValue value;
3172
3173 //This is unnecessary, since widgets will be destroyed
3174 //by the main window widget anyway.
3175 //remove_all_menu_toolbar_constructors(main_window, NULL);
3176
3177 g_assert(lttv_iattribute_find_by_path(attributes,
3178 "viewers/menu", LTTV_POINTER, &value));
3179 lttv_menus_destroy((LttvMenus*)*(value.v_pointer));
3180
3181 g_assert(lttv_iattribute_find_by_path(attributes,
3182 "viewers/toolbar", LTTV_POINTER, &value));
3183 lttv_toolbars_destroy((LttvToolbars*)*(value.v_pointer));
3184
3185 g_object_unref(main_window->attributes);
3186 g_main_window_list = g_slist_remove(g_main_window_list, main_window);
3187
3188 g_info("There are now : %d windows\n",g_slist_length(g_main_window_list));
3189 if(g_slist_length(g_main_window_list) == 0)
3190 mainwindow_quit();
3191 }
3192
3193 gboolean
3194 on_MWindow_configure (GtkWidget *widget,
3195 GdkEventConfigure *event,
3196 gpointer user_data)
3197 {
3198 MainWindow * mw_data = get_window_data_struct((GtkWidget*)widget);
3199
3200 // MD : removed time width modification upon resizing of the main window.
3201 // The viewers will redraw themselves completely, without time interval
3202 // modification.
3203 /* while(tab){
3204 if(mw_data->window_width){
3205 time_span = LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context)->Time_Span ;
3206 time_win = tab->time_window;
3207 ratio = width / mw_data->window_width;
3208 tab->time_window.time_width = ltt_time_mul(time_win.time_width,ratio);
3209 time = ltt_time_sub(time_span->endTime, time_win.start_time);
3210 if(ltt_time_compare(time, tab->time_window.time_width) < 0){
3211 tab->time_window.time_width = time;
3212 }
3213 }
3214 tab = tab->next;
3215 }
3216
3217 mw_data->window_width = (int)width;
3218 */
3219 return FALSE;
3220 }
3221
3222 /* Set current tab
3223 */
3224
3225 void
3226 on_MNotebook_switch_page (GtkNotebook *notebook,
3227 GtkNotebookPage *page,
3228 guint page_num,
3229 gpointer user_data)
3230 {
3231
3232 }
3233
3234
3235 void time_change_manager (Tab *tab,
3236 TimeWindow new_time_window)
3237 {
3238 /* Only one source of time change */
3239 if(tab->time_manager_lock == TRUE) return;
3240
3241 tab->time_manager_lock = TRUE;
3242
3243 LttvTracesetContext *tsc = LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context);
3244 TimeInterval time_span = tsc->time_span;
3245 LttTime start_time = new_time_window.start_time;
3246 LttTime end_time = new_time_window.end_time;
3247
3248 g_assert(ltt_time_compare(start_time, end_time) < 0);
3249
3250 /* Set scrollbar */
3251 GtkAdjustment *adjustment = gtk_range_get_adjustment(GTK_RANGE(tab->scrollbar));
3252 LttTime upper = ltt_time_sub(time_span.end_time, time_span.start_time);
3253 #if 0
3254 gtk_range_set_increments(GTK_RANGE(tab->scrollbar),
3255 ltt_time_to_double(new_time_window.time_width)
3256 / SCROLL_STEP_PER_PAGE
3257 * NANOSECONDS_PER_SECOND, /* step increment */
3258 ltt_time_to_double(new_time_window.time_width)
3259 * NANOSECONDS_PER_SECOND); /* page increment */
3260 gtk_range_set_range(GTK_RANGE(tab->scrollbar),
3261 0.0, /* lower */
3262 ltt_time_to_double(upper)
3263 * NANOSECONDS_PER_SECOND); /* upper */
3264 #endif //0
3265 g_object_set(G_OBJECT(adjustment),
3266 "lower",
3267 0.0, /* lower */
3268 "upper",
3269 ltt_time_to_double(upper), /* upper */
3270 "step_increment",
3271 new_time_window.time_width_double
3272 / SCROLL_STEP_PER_PAGE, /* step increment */
3273 "page_increment",
3274 new_time_window.time_width_double,
3275 /* page increment */
3276 "page_size",
3277 new_time_window.time_width_double, /* page size */
3278 NULL);
3279 gtk_adjustment_changed(adjustment);
3280
3281 // g_object_set(G_OBJECT(adjustment),
3282 // "value",
3283 // ltt_time_to_double(
3284 // ltt_time_sub(start_time, time_span.start_time))
3285 // , /* value */
3286 // NULL);
3287 //gtk_adjustment_value_changed(adjustment);
3288 gtk_range_set_value(GTK_RANGE(tab->scrollbar),
3289 ltt_time_to_double(
3290 ltt_time_sub(start_time, time_span.start_time)) /* value */);
3291
3292 /* set the time bar. */
3293 /* start seconds */
3294 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab->MEntry1),
3295 (double)time_span.start_time.tv_sec,
3296 (double)time_span.end_time.tv_sec);
3297 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab->MEntry1),
3298 (double)start_time.tv_sec);
3299
3300 /* start nanoseconds */
3301 if(start_time.tv_sec == time_span.start_time.tv_sec) {
3302 /* can be both beginning and end at the same time. */
3303 if(start_time.tv_sec == time_span.end_time.tv_sec) {
3304 /* If we are at the end, max nsec to end.. -1 (not zero length) */
3305 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab->MEntry2),
3306 (double)time_span.start_time.tv_nsec,
3307 (double)time_span.end_time.tv_nsec-1);
3308 } else {
3309 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab->MEntry2),
3310 (double)time_span.start_time.tv_nsec,
3311 (double)NANOSECONDS_PER_SECOND-1);
3312 }
3313 } else if(start_time.tv_sec == time_span.end_time.tv_sec) {
3314 /* If we are at the end, max nsec to end.. -1 (not zero length) */
3315 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab->MEntry2),
3316 0.0,
3317 (double)time_span.end_time.tv_nsec-1);
3318 } else /* anywhere else */
3319 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab->MEntry2),
3320 0.0,
3321 (double)NANOSECONDS_PER_SECOND-1);
3322 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab->MEntry2),
3323 (double)start_time.tv_nsec);
3324
3325 /* end seconds */
3326 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab->MEntry3),
3327 (double)time_span.start_time.tv_sec,
3328 (double)time_span.end_time.tv_sec);
3329 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab->MEntry3),
3330 (double)end_time.tv_sec);
3331
3332 /* end nanoseconds */
3333 if(end_time.tv_sec == time_span.start_time.tv_sec) {
3334 /* can be both beginning and end at the same time. */
3335 if(end_time.tv_sec == time_span.end_time.tv_sec) {
3336 /* If we are at the end, max nsec to end.. */
3337 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab->MEntry4),
3338 (double)time_span.start_time.tv_nsec+1,
3339 (double)time_span.end_time.tv_nsec);
3340 } else {
3341 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab->MEntry4),
3342 (double)time_span.start_time.tv_nsec+1,
3343 (double)NANOSECONDS_PER_SECOND-1);
3344 }
3345 }
3346 else if(end_time.tv_sec == time_span.end_time.tv_sec) {
3347 /* If we are at the end, max nsec to end.. */
3348 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab->MEntry4),
3349 0.0,
3350 (double)time_span.end_time.tv_nsec);
3351 }
3352 else /* anywhere else */
3353 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab->MEntry4),
3354 0.0,
3355 (double)NANOSECONDS_PER_SECOND-1);
3356 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab->MEntry4),
3357 (double)end_time.tv_nsec);
3358
3359 /* call viewer hooks for new time window */
3360 set_time_window(tab, &new_time_window);
3361
3362 tab->time_manager_lock = FALSE;
3363 }
3364
3365
3366 /* value changed for frame start s
3367 *
3368 * Check time span : if ns is out of range, clip it the nearest good value.
3369 */
3370 void
3371 on_MEntry1_value_changed (GtkSpinButton *spinbutton,
3372 gpointer user_data)
3373 {
3374 Tab *tab =(Tab *)user_data;
3375 LttvTracesetContext * tsc =
3376 LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context);
3377 TimeInterval time_span = tsc->time_span;
3378 gint value = gtk_spin_button_get_value_as_int(spinbutton);
3379
3380 TimeWindow new_time_window = tab->time_window;
3381
3382 LttTime end_time = new_time_window.end_time;
3383
3384 new_time_window.start_time.tv_sec = value;
3385
3386 /* start nanoseconds */
3387 if(new_time_window.start_time.tv_sec == time_span.start_time.tv_sec) {
3388 if(new_time_window.start_time.tv_sec == time_span.end_time.tv_sec) {
3389 if(new_time_window.start_time.tv_nsec > time_span.end_time.tv_nsec)
3390 new_time_window.start_time.tv_nsec = time_span.end_time.tv_nsec-1;
3391 if(new_time_window.start_time.tv_nsec < time_span.start_time.tv_nsec)
3392 new_time_window.start_time.tv_nsec = time_span.start_time.tv_nsec;
3393 } else {
3394 if(new_time_window.start_time.tv_nsec < time_span.start_time.tv_nsec)
3395 new_time_window.start_time.tv_nsec = time_span.start_time.tv_nsec;
3396 }
3397 }
3398 else if(new_time_window.start_time.tv_sec == time_span.end_time.tv_sec) {
3399 if(new_time_window.start_time.tv_nsec > time_span.end_time.tv_nsec)
3400 new_time_window.start_time.tv_nsec = time_span.end_time.tv_nsec-1;
3401 }
3402
3403 if(ltt_time_compare(new_time_window.start_time, end_time) >= 0) {
3404 /* Then, we must push back end time : keep the same time width
3405 * if possible, else end traceset time */
3406 end_time = LTT_TIME_MIN(ltt_time_add(new_time_window.start_time,
3407 new_time_window.time_width),
3408 time_span.end_time);
3409 }
3410
3411 /* Fix the time width to fit start time and end time */
3412 new_time_window.time_width = ltt_time_sub(end_time,
3413 new_time_window.start_time);
3414 new_time_window.time_width_double =
3415 ltt_time_to_double(new_time_window.time_width);
3416
3417 new_time_window.end_time = end_time;
3418
3419 time_change_manager(tab, new_time_window);
3420
3421 }
3422
3423 void
3424 on_MEntry2_value_changed (GtkSpinButton *spinbutton,
3425 gpointer user_data)
3426 {
3427 Tab *tab =(Tab *)user_data;
3428 LttvTracesetContext * tsc =
3429 LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context);
3430 TimeInterval time_span = tsc->time_span;
3431 gint value = gtk_spin_button_get_value_as_int(spinbutton);
3432
3433 TimeWindow new_time_window = tab->time_window;
3434
3435 LttTime end_time = new_time_window.end_time;
3436
3437 new_time_window.start_time.tv_nsec = value;
3438
3439 if(ltt_time_compare(new_time_window.start_time, end_time) >= 0) {
3440 /* Then, we must push back end time : keep the same time width
3441 * if possible, else end traceset time */
3442 end_time = LTT_TIME_MIN(ltt_time_add(new_time_window.start_time,
3443 new_time_window.time_width),
3444 time_span.end_time);
3445 }
3446
3447 /* Fix the time width to fit start time and end time */
3448 new_time_window.time_width = ltt_time_sub(end_time,
3449 new_time_window.start_time);
3450 new_time_window.time_width_double =
3451 ltt_time_to_double(new_time_window.time_width);
3452
3453 new_time_window.end_time = end_time;
3454
3455 time_change_manager(tab, new_time_window);
3456
3457 }
3458
3459 void
3460 on_MEntry3_value_changed (GtkSpinButton *spinbutton,
3461 gpointer user_data)
3462 {
3463 Tab *tab =(Tab *)user_data;
3464 LttvTracesetContext * tsc =
3465 LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context);
3466 TimeInterval time_span = tsc->time_span;
3467 gint value = gtk_spin_button_get_value_as_int(spinbutton);
3468
3469 TimeWindow new_time_window = tab->time_window;
3470
3471 LttTime end_time = new_time_window.end_time;
3472
3473 end_time.tv_sec = value;
3474
3475 /* end nanoseconds */
3476 if(end_time.tv_sec == time_span.start_time.tv_sec) {
3477 if(end_time.tv_sec == time_span.end_time.tv_sec) {
3478 if(end_time.tv_nsec > time_span.end_time.tv_nsec)
3479 end_time.tv_nsec = time_span.end_time.tv_nsec;
3480 if(end_time.tv_nsec < time_span.start_time.tv_nsec)
3481 end_time.tv_nsec = time_span.start_time.tv_nsec+1;
3482 } else {
3483 if(end_time.tv_nsec < time_span.start_time.tv_nsec)
3484 end_time.tv_nsec = time_span.start_time.tv_nsec+1;
3485 }
3486 }
3487 else if(end_time.tv_sec == time_span.end_time.tv_sec) {
3488 if(end_time.tv_nsec > time_span.end_time.tv_nsec)
3489 end_time.tv_nsec = time_span.end_time.tv_nsec;
3490 }
3491
3492 if(ltt_time_compare(new_time_window.start_time, end_time) >= 0) {
3493 /* Then, we must push front start time : keep the same time width
3494 * if possible, else end traceset time */
3495 new_time_window.start_time = LTT_TIME_MAX(
3496 ltt_time_sub(end_time,
3497 new_time_window.time_width),
3498 time_span.start_time);
3499 }
3500
3501 /* Fix the time width to fit start time and end time */
3502 new_time_window.time_width = ltt_time_sub(end_time,
3503 new_time_window.start_time);
3504 new_time_window.time_width_double =
3505 ltt_time_to_double(new_time_window.time_width);
3506
3507 new_time_window.end_time = end_time;
3508
3509 time_change_manager(tab, new_time_window);
3510
3511 }
3512
3513 void
3514 on_MEntry4_value_changed (GtkSpinButton *spinbutton,
3515 gpointer user_data)
3516 {
3517 Tab *tab =(Tab *)user_data;
3518 LttvTracesetContext * tsc =
3519 LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context);
3520 TimeInterval time_span = tsc->time_span;
3521 gint value = gtk_spin_button_get_value_as_int(spinbutton);
3522
3523 TimeWindow new_time_window = tab->time_window;
3524
3525 LttTime end_time = new_time_window.end_time;
3526
3527 end_time.tv_nsec = value;
3528
3529 if(ltt_time_compare(new_time_window.start_time, end_time) >= 0) {
3530 /* Then, we must push front start time : keep the same time width
3531 * if possible, else end traceset time */
3532 new_time_window.start_time = LTT_TIME_MAX(
3533 ltt_time_sub(end_time,
3534 new_time_window.time_width),
3535 time_span.start_time);
3536 }
3537
3538 /* Fix the time width to fit start time and end time */
3539 new_time_window.time_width = ltt_time_sub(end_time,
3540 new_time_window.start_time);
3541 new_time_window.time_width_double =
3542 ltt_time_to_double(new_time_window.time_width);
3543 new_time_window.end_time = end_time;
3544
3545 time_change_manager(tab, new_time_window);
3546
3547 }
3548
3549
3550 void current_time_change_manager (Tab *tab,
3551 LttTime new_current_time)
3552 {
3553 /* Only one source of time change */
3554 if(tab->current_time_manager_lock == TRUE) return;
3555
3556 tab->current_time_manager_lock = TRUE;
3557
3558 LttvTracesetContext *tsc = LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context);
3559 TimeInterval time_span = tsc->time_span;
3560
3561 /* current seconds */
3562 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab->MEntry5),
3563 (double)time_span.start_time.tv_sec,
3564 (double)time_span.end_time.tv_sec);
3565 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab->MEntry5),
3566 (double)new_current_time.tv_sec);
3567
3568
3569 /* start nanoseconds */
3570 if(new_current_time.tv_sec == time_span.start_time.tv_sec) {
3571 /* can be both beginning and end at the same time. */
3572 if(new_current_time.tv_sec == time_span.end_time.tv_sec) {
3573 /* If we are at the end, max nsec to end.. */
3574 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab->MEntry6),
3575 (double)time_span.start_time.tv_nsec,
3576 (double)time_span.end_time.tv_nsec);
3577 } else {
3578 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab->MEntry6),
3579 (double)time_span.start_time.tv_nsec,
3580 (double)NANOSECONDS_PER_SECOND-1);
3581 }
3582 } else if(new_current_time.tv_sec == time_span.end_time.tv_sec) {
3583 /* If we are at the end, max nsec to end.. */
3584 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab->MEntry6),
3585 0.0,
3586 (double)time_span.end_time.tv_nsec);
3587 } else /* anywhere else */
3588 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab->MEntry6),
3589 0.0,
3590 (double)NANOSECONDS_PER_SECOND-1);
3591
3592 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab->MEntry6),
3593 (double)new_current_time.tv_nsec);
3594
3595 set_current_time(tab, &new_current_time);
3596
3597 tab->current_time_manager_lock = FALSE;
3598 }
3599
3600 void current_position_change_manager(Tab *tab,
3601 LttvTracesetContextPosition *pos)
3602 {
3603 LttvTracesetContext *tsc =
3604 LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context);
3605 TimeInterval time_span = tsc->time_span;
3606
3607 g_assert(lttv_process_traceset_seek_position(tsc, pos) == 0);
3608 LttTime new_time = lttv_traceset_context_position_get_time(pos);
3609
3610 current_time_change_manager(tab, new_time);
3611
3612 set_current_position(tab, pos);
3613 }
3614
3615
3616 void
3617 on_MEntry5_value_changed (GtkSpinButton *spinbutton,
3618 gpointer user_data)
3619 {
3620 Tab *tab = (Tab*)user_data;
3621 LttvTracesetContext * tsc =
3622 LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context);
3623 TimeInterval time_span = tsc->time_span;
3624 gint value = gtk_spin_button_get_value_as_int(spinbutton);
3625 LttTime new_current_time = tab->current_time;
3626 new_current_time.tv_sec = value;
3627
3628 /* current nanoseconds */
3629 if(new_current_time.tv_sec == time_span.start_time.tv_sec) {
3630 if(new_current_time.tv_sec == time_span.end_time.tv_sec) {
3631 if(new_current_time.tv_nsec > time_span.end_time.tv_nsec)
3632 new_current_time.tv_nsec = time_span.end_time.tv_nsec;
3633 if(new_current_time.tv_nsec < time_span.start_time.tv_nsec)
3634 new_current_time.tv_nsec = time_span.start_time.tv_nsec;
3635 } else {
3636 if(new_current_time.tv_nsec < time_span.start_time.tv_nsec)
3637 new_current_time.tv_nsec = time_span.start_time.tv_nsec;
3638 }
3639 }
3640 else if(new_current_time.tv_sec == time_span.end_time.tv_sec) {
3641 if(new_current_time.tv_nsec > time_span.end_time.tv_nsec)
3642 new_current_time.tv_nsec = time_span.end_time.tv_nsec;
3643 }
3644
3645 current_time_change_manager(tab, new_current_time);
3646 }
3647
3648 void
3649 on_MEntry6_value_changed (GtkSpinButton *spinbutton,
3650 gpointer user_data)
3651 {
3652 Tab *tab = (Tab*)user_data;
3653 gint value = gtk_spin_button_get_value_as_int(spinbutton);
3654 LttTime new_current_time = tab->current_time;
3655 new_current_time.tv_nsec = value;
3656
3657 current_time_change_manager(tab, new_current_time);
3658 }
3659
3660
3661 void scroll_value_changed_cb(GtkWidget *scrollbar,
3662 gpointer user_data)
3663 {
3664 Tab *tab = (Tab *)user_data;
3665 TimeWindow new_time_window;
3666 LttTime time;
3667 GtkAdjustment *adjust = gtk_range_get_adjustment(GTK_RANGE(scrollbar));
3668 gdouble value = gtk_adjustment_get_value(adjust);
3669 // gdouble upper, lower, ratio, page_size;
3670 gdouble page_size;
3671 LttvTracesetContext * tsc =
3672 LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context);
3673 TimeInterval time_span = tsc->time_span;
3674
3675 time = ltt_time_add(ltt_time_from_double(value),
3676 time_span.start_time);
3677
3678 new_time_window.start_time = time;
3679
3680 page_size = adjust->page_size;
3681
3682 new_time_window.time_width =
3683 ltt_time_from_double(page_size);
3684
3685 new_time_window.time_width_double =
3686 page_size;
3687
3688 new_time_window.end_time = ltt_time_add(new_time_window.start_time,
3689 new_time_window.time_width);
3690
3691
3692 time_change_manager(tab, new_time_window);
3693 #if 0
3694 //time_window = tab->time_window;
3695
3696 lower = adjust->lower;
3697 upper = adjust->upper;
3698 ratio = (value - lower) / (upper - lower);
3699 g_info("lower %lu, upper %lu, value %lu, ratio %lu", lower, upper, value, ratio);
3700
3701 //time = ltt_time_sub(time_span->end_time, time_span->start_time);
3702 //time = ltt_time_mul(time, (float)ratio);
3703 //time = ltt_time_add(time_span->start_time, time);
3704 time = ltt_time_add(ltt_time_from_double(value),
3705 time_span.start_time);
3706
3707 time_window.start_time = time;
3708
3709 page_size = adjust->page_size;
3710
3711 time_window.time_width =
3712 ltt_time_from_double(page_size);
3713 //time = ltt_time_sub(time_span.end_time, time);
3714 //if(ltt_time_compare(time,time_window.time_width) < 0){
3715 // time_window.time_width = time;
3716 //}
3717
3718 /* call viewer hooks for new time window */
3719 set_time_window(tab, &time_window);
3720 #endif //0
3721 }
3722
3723
3724 /* Display a dialogue showing all eventtypes and traces, let user to select the interested
3725 * eventtypes, tracefiles and traces (filter)
3726 */
3727
3728 /* Select a trace which will be removed from traceset
3729 */
3730
3731 char * get_remove_trace(char ** all_trace_name, int nb_trace)
3732 {
3733 return get_selection(all_trace_name, nb_trace,
3734 "Select a trace", "Trace pathname");
3735 }
3736
3737
3738 /* Select a module which will be loaded
3739 */
3740
3741 char * get_load_module(char ** load_module_name, int nb_module)
3742 {
3743 return get_selection(load_module_name, nb_module,
3744 "Select a module to load", "Module name");
3745 }
3746
3747
3748
3749
3750 /* Select a module which will be unloaded
3751 */
3752
3753 char * get_unload_module(char ** loaded_module_name, int nb_module)
3754 {
3755 return get_selection(loaded_module_name, nb_module,
3756 "Select a module to unload", "Module name");
3757 }
3758
3759
3760 /* Display a dialogue which shows all selectable items, let user to
3761 * select one of them
3762 */
3763
3764 char * get_selection(char ** loaded_module_name, int nb_module,
3765 char *title, char * column_title)
3766 {
3767 GtkWidget * dialogue;
3768 GtkWidget * scroll_win;
3769 GtkWidget * tree;
3770 GtkListStore * store;
3771 GtkTreeViewColumn * column;
3772 GtkCellRenderer * renderer;
3773 GtkTreeSelection * select;
3774 GtkTreeIter iter;
3775 gint id, i;
3776 char * unload_module_name = NULL;
3777
3778 dialogue = gtk_dialog_new_with_buttons(title,
3779 NULL,
3780 GTK_DIALOG_MODAL,
3781 GTK_STOCK_OK,GTK_RESPONSE_ACCEPT,
3782 GTK_STOCK_CANCEL,GTK_RESPONSE_REJECT,
3783 NULL);
3784 gtk_window_set_default_size((GtkWindow*)dialogue, 500, 200);
3785
3786 scroll_win = gtk_scrolled_window_new (NULL, NULL);
3787 gtk_widget_show ( scroll_win);
3788 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll_win),
3789 GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
3790
3791 store = gtk_list_store_new (N_COLUMNS,G_TYPE_STRING);
3792 tree = gtk_tree_view_new_with_model(GTK_TREE_MODEL (store));
3793 gtk_widget_show ( tree);
3794 g_object_unref (G_OBJECT (store));
3795
3796 renderer = gtk_cell_renderer_text_new ();
3797 column = gtk_tree_view_column_new_with_attributes (column_title,
3798 renderer,
3799 "text", MODULE_COLUMN,
3800 NULL);
3801 gtk_tree_view_column_set_alignment (column, 0.5);
3802 gtk_tree_view_column_set_fixed_width (column, 150);
3803 gtk_tree_view_append_column (GTK_TREE_VIEW (tree), column);
3804
3805 select = gtk_tree_view_get_selection (GTK_TREE_VIEW (tree));
3806 gtk_tree_selection_set_mode (select, GTK_SELECTION_SINGLE);
3807
3808 gtk_container_add (GTK_CONTAINER (scroll_win), tree);
3809
3810 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialogue)->vbox), scroll_win,TRUE, TRUE,0);
3811
3812 for(i=0;i<nb_module;i++){
3813 gtk_list_store_append (store, &iter);
3814 gtk_list_store_set (store, &iter, MODULE_COLUMN,loaded_module_name[i],-1);
3815 }
3816
3817 id = gtk_dialog_run(GTK_DIALOG(dialogue));
3818 GtkTreeModel **store_model = (GtkTreeModel**)&store;
3819 switch(id){
3820 case GTK_RESPONSE_ACCEPT:
3821 case GTK_RESPONSE_OK:
3822 if (gtk_tree_selection_get_selected (select, store_model, &iter)){
3823 gtk_tree_model_get ((GtkTreeModel*)store, &iter, MODULE_COLUMN, &unload_module_name, -1);
3824 }
3825 case GTK_RESPONSE_REJECT:
3826 case GTK_RESPONSE_CANCEL:
3827 default:
3828 gtk_widget_destroy(dialogue);
3829 break;
3830 }
3831
3832 return unload_module_name;
3833 }
3834
3835
3836 /* Insert all menu entry and tool buttons into this main window
3837 * for modules.
3838 *
3839 */
3840
3841 void add_all_menu_toolbar_constructors(MainWindow * mw, gpointer user_data)
3842 {
3843 guint i;
3844 GdkPixbuf *pixbuf;
3845 lttvwindow_viewer_constructor constructor;
3846 LttvMenus * global_menu, * instance_menu;
3847 LttvToolbars * global_toolbar, * instance_toolbar;
3848 LttvMenuClosure *menu_item;
3849 LttvToolbarClosure *toolbar_item;
3850 LttvAttributeValue value;
3851 LttvIAttribute *global_attributes = LTTV_IATTRIBUTE(lttv_global_attributes());
3852 LttvIAttribute *attributes = mw->attributes;
3853 GtkWidget * tool_menu_title_menu, *new_widget, *pixmap;
3854
3855 g_assert(lttv_iattribute_find_by_path(global_attributes,
3856 "viewers/menu", LTTV_POINTER, &value));
3857 if(*(value.v_pointer) == NULL)
3858 *(value.v_pointer) = lttv_menus_new();
3859 global_menu = (LttvMenus*)*(value.v_pointer);
3860
3861 g_assert(lttv_iattribute_find_by_path(attributes,
3862 "viewers/menu", LTTV_POINTER, &value));
3863 if(*(value.v_pointer) == NULL)
3864 *(value.v_pointer) = lttv_menus_new();
3865 instance_menu = (LttvMenus*)*(value.v_pointer);
3866
3867
3868
3869 g_assert(lttv_iattribute_find_by_path(global_attributes,
3870 "viewers/toolbar", LTTV_POINTER, &value));
3871 if(*(value.v_pointer) == NULL)
3872 *(value.v_pointer) = lttv_toolbars_new();
3873 global_toolbar = (LttvToolbars*)*(value.v_pointer);
3874
3875 g_assert(lttv_iattribute_find_by_path(attributes,
3876 "viewers/toolbar", LTTV_POINTER, &value));
3877 if(*(value.v_pointer) == NULL)
3878 *(value.v_pointer) = lttv_toolbars_new();
3879 instance_toolbar = (LttvToolbars*)*(value.v_pointer);
3880
3881 /* Add missing menu entries to window instance */
3882 for(i=0;i<global_menu->len;i++) {
3883 menu_item = &g_array_index(global_menu, LttvMenuClosure, i);
3884
3885 //add menu_item to window instance;
3886 constructor = menu_item->con;
3887 tool_menu_title_menu = lookup_widget(mw->mwindow,"ToolMenuTitle_menu");
3888 new_widget =
3889 gtk_menu_item_new_with_mnemonic (menu_item->menu_text);
3890 gtk_container_add (GTK_CONTAINER (tool_menu_title_menu),
3891 new_widget);
3892 g_signal_connect ((gpointer) new_widget, "activate",
3893 G_CALLBACK (insert_viewer_wrap),
3894 constructor);
3895 gtk_widget_show (new_widget);
3896 lttv_menus_add(instance_menu, menu_item->con,
3897 menu_item->menu_path,
3898 menu_item->menu_text,
3899 new_widget);
3900
3901 }
3902
3903 /* Add missing toolbar entries to window instance */
3904 for(i=0;i<global_toolbar->len;i++) {
3905 toolbar_item = &g_array_index(global_toolbar, LttvToolbarClosure, i);
3906
3907 //add toolbar_item to window instance;
3908 constructor = toolbar_item->con;
3909 tool_menu_title_menu = lookup_widget(mw->mwindow,"MToolbar1");
3910 pixbuf = gdk_pixbuf_new_from_xpm_data((const char**)toolbar_item->pixmap);
3911 pixmap = gtk_image_new_from_pixbuf(pixbuf);
3912 new_widget =
3913 gtk_toolbar_append_element (GTK_TOOLBAR (tool_menu_title_menu),
3914 GTK_TOOLBAR_CHILD_BUTTON,
3915 NULL,
3916 "",
3917 toolbar_item->tooltip, NULL,
3918 pixmap, NULL, NULL);
3919 gtk_label_set_use_underline(
3920 GTK_LABEL (((GtkToolbarChild*) (
3921 g_list_last (GTK_TOOLBAR
3922 (tool_menu_title_menu)->children)->data))->label),
3923 TRUE);
3924 gtk_container_set_border_width (GTK_CONTAINER (new_widget), 1);
3925 g_signal_connect ((gpointer) new_widget,
3926 "clicked",
3927 G_CALLBACK (insert_viewer_wrap),
3928 constructor);
3929 gtk_widget_show (new_widget);
3930
3931 lttv_toolbars_add(instance_toolbar, toolbar_item->con,
3932 toolbar_item->tooltip,
3933 toolbar_item->pixmap,
3934 new_widget);
3935
3936 }
3937
3938 }
3939
3940
3941 /* Create a main window
3942 */
3943
3944 void construct_main_window(MainWindow * parent)
3945 {
3946 g_debug("construct_main_window()");
3947 GtkWidget * new_window; /* New generated main window */
3948 MainWindow * new_m_window;/* New main window structure */
3949 GtkNotebook * notebook;
3950 LttvIAttribute *attributes =
3951 LTTV_IATTRIBUTE(g_object_new(LTTV_ATTRIBUTE_TYPE, NULL));
3952 LttvAttributeValue value;
3953 Tab *new_tab;
3954
3955 new_m_window = g_new(MainWindow, 1);
3956
3957 // Add the object's information to the module's array
3958 g_main_window_list = g_slist_append(g_main_window_list, new_m_window);
3959
3960 new_window = create_MWindow();
3961 gtk_widget_show (new_window);
3962
3963 new_m_window->mwindow = new_window;
3964 new_m_window->attributes = attributes;
3965
3966 g_assert(lttv_iattribute_find_by_path(attributes,
3967 "viewers/menu", LTTV_POINTER, &value));
3968 *(value.v_pointer) = lttv_menus_new();
3969
3970 g_assert(lttv_iattribute_find_by_path(attributes,
3971 "viewers/toolbar", LTTV_POINTER, &value));
3972 *(value.v_pointer) = lttv_toolbars_new();
3973
3974 add_all_menu_toolbar_constructors(new_m_window, NULL);
3975
3976 g_object_set_data_full(G_OBJECT(new_window),
3977 "main_window_data",
3978 (gpointer)new_m_window,
3979 (GDestroyNotify)g_free);
3980 //create a default tab
3981 notebook = (GtkNotebook *)lookup_widget(new_m_window->mwindow, "MNotebook");
3982 if(notebook == NULL){
3983 g_info("Notebook does not exist\n");
3984 return;
3985 }
3986 //gtk_notebook_popup_enable (GTK_NOTEBOOK(notebook));
3987 //for now there is no name field in LttvTraceset structure
3988 //Use "Traceset" as the label for the default tab
3989 if(parent) {
3990 GtkWidget * parent_notebook = lookup_widget(parent->mwindow, "MNotebook");
3991 GtkWidget *page = gtk_notebook_get_nth_page(GTK_NOTEBOOK(parent_notebook),
3992 gtk_notebook_get_current_page(GTK_NOTEBOOK(parent_notebook)));
3993 Tab *parent_tab;
3994
3995 if(!page) {
3996 parent_tab = NULL;
3997 } else {
3998 parent_tab = (Tab *)g_object_get_data(G_OBJECT(page), "Tab_Info");
3999 }
4000 new_tab = create_tab(new_m_window, parent_tab, notebook, "Traceset");
4001 } else {
4002 new_tab = create_tab(new_m_window, NULL, notebook, "Traceset");
4003 /* First window, use command line trace */
4004 if(g_init_trace != NULL){
4005 lttvwindow_add_trace(new_tab,
4006 g_init_trace);
4007
4008 }
4009 LttvTraceset *traceset = new_tab->traceset_info->traceset;
4010 SetTraceset(new_tab, traceset);
4011
4012 /* Insert default viewers */
4013 {
4014 LttvAttributeType type;
4015 LttvAttributeName name;
4016 LttvAttributeValue value;
4017 LttvAttribute *attribute;
4018
4019 LttvIAttribute *attributes_global =
4020 LTTV_IATTRIBUTE(lttv_global_attributes());
4021
4022 g_assert(attribute =
4023 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
4024 LTTV_IATTRIBUTE(attributes_global),
4025 LTTV_VIEWER_CONSTRUCTORS)));
4026
4027 name = g_quark_from_string("guievents");
4028 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute),
4029 name, &value);
4030 if(type == LTTV_POINTER) {
4031 lttvwindow_viewer_constructor viewer_constructor =
4032 (lttvwindow_viewer_constructor)*value.v_pointer;
4033 insert_viewer(new_window, viewer_constructor);
4034 }
4035
4036 name = g_quark_from_string("guicontrolflow");
4037 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute),
4038 name, &value);
4039 if(type == LTTV_POINTER) {
4040 lttvwindow_viewer_constructor viewer_constructor =
4041 (lttvwindow_viewer_constructor)*value.v_pointer;
4042 insert_viewer(new_window, viewer_constructor);
4043 }
4044
4045 name = g_quark_from_string("guistatistics");
4046 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute),
4047 name, &value);
4048 if(type == LTTV_POINTER) {
4049 lttvwindow_viewer_constructor viewer_constructor =
4050 (lttvwindow_viewer_constructor)*value.v_pointer;
4051 insert_viewer(new_window, viewer_constructor);
4052 }
4053
4054 }
4055 }
4056
4057 g_info("There are now : %d windows\n",g_slist_length(g_main_window_list));
4058 }
4059
4060
4061 /* Free the memory occupied by a tab structure
4062 * destroy the tab
4063 */
4064
4065 void tab_destructor(Tab * tab)
4066 {
4067 int i, nb, ref_count;
4068 LttvTrace * trace;
4069
4070 gtk_object_destroy(GTK_OBJECT(tab->tooltips));
4071
4072 if(tab->attributes)
4073 g_object_unref(tab->attributes);
4074
4075 if(tab->interrupted_state)
4076 g_object_unref(tab->interrupted_state);
4077
4078
4079 if(tab->traceset_info->traceset_context != NULL){
4080 //remove state update hooks
4081 lttv_state_remove_event_hooks(
4082 (LttvTracesetState*)tab->traceset_info->
4083 traceset_context);
4084 lttv_context_fini(LTTV_TRACESET_CONTEXT(tab->traceset_info->
4085 traceset_context));
4086 g_object_unref(tab->traceset_info->traceset_context);
4087 }
4088 if(tab->traceset_info->traceset != NULL) {
4089 nb = lttv_traceset_number(tab->traceset_info->traceset);
4090 for(i = 0 ; i < nb ; i++) {
4091 trace = lttv_traceset_get(tab->traceset_info->traceset, i);
4092 ref_count = lttv_trace_get_ref_number(trace);
4093 if(ref_count <= 1){
4094 ltt_trace_close(lttv_trace(trace));
4095 }
4096 }
4097 }
4098 lttv_filter_destroy(tab->filter);
4099 lttv_traceset_destroy(tab->traceset_info->traceset);
4100 /* Remove the idle events requests processing function of the tab */
4101 g_idle_remove_by_data(tab);
4102
4103 g_slist_free(tab->events_requests);
4104 g_free(tab->traceset_info);
4105 g_free(tab);
4106 }
4107
4108
4109 /* Create a tab and insert it into the current main window
4110 */
4111
4112 Tab* create_tab(MainWindow * mw, Tab *copy_tab,
4113 GtkNotebook * notebook, char * label)
4114 {
4115 GList * list;
4116 Tab * tab;
4117
4118 //create a new tab data structure
4119 tab = g_new(Tab,1);
4120
4121 //construct and initialize the traceset_info
4122 tab->traceset_info = g_new(TracesetInfo,1);
4123
4124 if(copy_tab) {
4125 tab->traceset_info->traceset =
4126 lttv_traceset_copy(copy_tab->traceset_info->traceset);
4127
4128 /* Copy the previous tab's filter */
4129 /* We can clone the filter, as we copy the trace set also */
4130 /* The filter must always be in sync with the trace set */
4131 tab->filter = lttv_filter_clone(copy_tab->filter);
4132 } else {
4133 tab->traceset_info->traceset = lttv_traceset_new();
4134 tab->filter = NULL;
4135 }
4136 #ifdef DEBUG
4137 lttv_attribute_write_xml(
4138 lttv_traceset_attribute(tab->traceset_info->traceset),
4139 stdout,
4140 0, 4);
4141 fflush(stdout);
4142 #endif //DEBUG
4143
4144 tab->time_manager_lock = FALSE;
4145 tab->current_time_manager_lock = FALSE;
4146
4147 //FIXME copy not implemented in lower level
4148 tab->traceset_info->traceset_context =
4149 g_object_new(LTTV_TRACESET_STATS_TYPE, NULL);
4150 g_assert(tab->traceset_info->traceset_context != NULL);
4151 lttv_context_init(
4152 LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context),
4153 tab->traceset_info->traceset);
4154 //add state update hooks
4155 lttv_state_add_event_hooks(
4156 (LttvTracesetState*)tab->traceset_info->traceset_context);
4157
4158 //determine the current_time and time_window of the tab
4159 #if 0
4160 if(copy_tab != NULL){
4161 tab->time_window = copy_tab->time_window;
4162 tab->current_time = copy_tab->current_time;
4163 }else{
4164 tab->time_window.start_time =
4165 LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context)->
4166 time_span.start_time;
4167 if(DEFAULT_TIME_WIDTH_S <
4168 LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context)->
4169 time_span.end_time.tv_sec)
4170 tmp_time.tv_sec = DEFAULT_TIME_WIDTH_S;
4171 else
4172 tmp_time.tv_sec =
4173 LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context)->
4174 time_span.end_time.tv_sec;
4175 tmp_time.tv_nsec = 0;
4176 tab->time_window.time_width = tmp_time ;
4177 tab->current_time.tv_sec =
4178 LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context)->
4179 time_span.start_time.tv_sec;
4180 tab->current_time.tv_nsec =
4181 LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context)->
4182 time_span.start_time.tv_nsec;
4183 }
4184 #endif //0
4185 tab->attributes = LTTV_IATTRIBUTE(g_object_new(LTTV_ATTRIBUTE_TYPE, NULL));
4186 tab->interrupted_state = g_object_new(LTTV_ATTRIBUTE_TYPE, NULL);
4187
4188 tab->vbox = gtk_vbox_new(FALSE, 2);
4189 tab->viewer_container = gtk_vbox_new(TRUE, 2);
4190 tab->scrollbar = gtk_hscrollbar_new(NULL);
4191 //tab->multivpaned = gtk_multi_vpaned_new();
4192
4193 gtk_box_pack_start(GTK_BOX(tab->vbox),
4194 tab->viewer_container,
4195 TRUE, /* expand */
4196 TRUE, /* Give the extra space to the child */
4197 0); /* No padding */
4198
4199 // if(copy_tab) {
4200 // tab->time_window = copy_tab->time_window;
4201 // tab->current_time = copy_tab->current_time;
4202 // }
4203
4204 /* Create the timebar */
4205 {
4206 tab->MTimebar = gtk_hbox_new(FALSE, 2);
4207 gtk_widget_show(tab->MTimebar);
4208 tab->tooltips = gtk_tooltips_new();
4209
4210 tab->MEventBox1a = gtk_event_box_new();
4211 gtk_widget_show(tab->MEventBox1a);
4212 gtk_tooltips_set_tip(tab->tooltips, tab->MEventBox1a,
4213 "Paste Start and End Times Here", "");
4214 tab->MText1a = gtk_label_new("Time Frame ");
4215 gtk_widget_show(tab->MText1a);
4216 gtk_container_add(GTK_CONTAINER(tab->MEventBox1a), tab->MText1a);
4217 tab->MEventBox1b = gtk_event_box_new();
4218 gtk_widget_show(tab->MEventBox1b);
4219 gtk_tooltips_set_tip(tab->tooltips, tab->MEventBox1b,
4220 "Paste Start Time Here", "");
4221 tab->MText1b = gtk_label_new("start: ");
4222 gtk_widget_show(tab->MText1b);
4223 gtk_container_add(GTK_CONTAINER(tab->MEventBox1b), tab->MText1b);
4224 tab->MText2 = gtk_label_new("s");
4225 gtk_widget_show(tab->MText2);
4226 tab->MText3a = gtk_label_new("ns");
4227 gtk_widget_show(tab->MText3a);
4228 tab->MEventBox3b = gtk_event_box_new();
4229 gtk_widget_show(tab->MEventBox3b);
4230 gtk_tooltips_set_tip(tab->tooltips, tab->MEventBox3b,
4231 "Paste End Time Here", "");
4232 tab->MText3b = gtk_label_new("end:");
4233 gtk_widget_show(tab->MText3b);
4234 gtk_container_add(GTK_CONTAINER(tab->MEventBox3b), tab->MText3b);
4235 tab->MText4 = gtk_label_new("s");
4236 gtk_widget_show(tab->MText4);
4237 tab->MText5a = gtk_label_new("ns");
4238 gtk_widget_show(tab->MText5a);
4239 tab->MEventBox5b = gtk_event_box_new();
4240 gtk_widget_show(tab->MEventBox5b);
4241 gtk_tooltips_set_tip(tab->tooltips, tab->MEventBox5b,
4242 "Paste Current Time Here", "");
4243 tab->MText5b = gtk_label_new("Current Time:");
4244 gtk_widget_show(tab->MText5b);
4245 gtk_container_add(GTK_CONTAINER(tab->MEventBox5b), tab->MText5b);
4246 tab->MText6 = gtk_label_new("s");
4247 gtk_widget_show(tab->MText6);
4248 tab->MText7 = gtk_label_new("ns");
4249 gtk_widget_show(tab->MText7);
4250
4251 tab->MEntry1 = gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4252 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab->MEntry1),0);
4253 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab->MEntry1),TRUE);
4254 gtk_widget_show(tab->MEntry1);
4255 tab->MEntry2 = gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4256 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab->MEntry2),0);
4257 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab->MEntry2),TRUE);
4258 gtk_widget_show(tab->MEntry2);
4259 tab->MEntry3 = gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4260 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab->MEntry3),0);
4261 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab->MEntry3),TRUE);
4262 gtk_widget_show(tab->MEntry3);
4263 tab->MEntry4 = gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4264 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab->MEntry4),0);
4265 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab->MEntry4),TRUE);
4266 gtk_widget_show(tab->MEntry4);
4267 tab->MEntry5 = gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4268 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab->MEntry5),0);
4269 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab->MEntry5),TRUE);
4270 gtk_widget_show(tab->MEntry5);
4271 tab->MEntry6 = gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4272 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab->MEntry6),0);
4273 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab->MEntry6),TRUE);
4274 gtk_widget_show(tab->MEntry6);
4275
4276
4277 GtkWidget *temp_widget;
4278
4279 gtk_box_pack_start (GTK_BOX (tab->MTimebar), tab->MEventBox1a, FALSE,
4280 FALSE, 0);
4281 gtk_box_pack_start (GTK_BOX (tab->MTimebar), tab->MEventBox1b, FALSE,
4282 FALSE, 0);
4283 gtk_box_pack_start (GTK_BOX (tab->MTimebar), tab->MEntry1, FALSE, FALSE, 0);
4284 gtk_box_pack_start (GTK_BOX (tab->MTimebar), tab->MText2, FALSE, FALSE, 0);
4285 gtk_box_pack_start (GTK_BOX (tab->MTimebar), tab->MEntry2, FALSE, FALSE, 0);
4286 gtk_box_pack_start (GTK_BOX (tab->MTimebar), tab->MText3a, FALSE, FALSE, 0);
4287 temp_widget = gtk_vseparator_new();
4288 gtk_widget_show(temp_widget);
4289 gtk_box_pack_start (GTK_BOX (tab->MTimebar), temp_widget, FALSE, FALSE, 0);
4290 gtk_box_pack_start (GTK_BOX (tab->MTimebar), tab->MEventBox3b, FALSE,
4291 FALSE, 0);
4292 gtk_box_pack_start (GTK_BOX (tab->MTimebar), tab->MEntry3, FALSE, FALSE, 0);
4293 gtk_box_pack_start (GTK_BOX (tab->MTimebar), tab->MText4, FALSE, FALSE, 0);
4294 gtk_box_pack_start (GTK_BOX (tab->MTimebar), tab->MEntry4, FALSE, FALSE, 0);
4295 gtk_box_pack_start (GTK_BOX (tab->MTimebar), tab->MText5a, FALSE, FALSE, 0);
4296 temp_widget = gtk_vseparator_new();
4297 gtk_widget_show(temp_widget);
4298 gtk_box_pack_end (GTK_BOX (tab->MTimebar), tab->MText7, FALSE, FALSE, 0);
4299 gtk_box_pack_end (GTK_BOX (tab->MTimebar), tab->MEntry6, FALSE, FALSE, 0);
4300 gtk_box_pack_end (GTK_BOX (tab->MTimebar), tab->MText6, FALSE, FALSE, 0);
4301 gtk_box_pack_end (GTK_BOX (tab->MTimebar), tab->MEntry5, FALSE, FALSE, 0);
4302 gtk_box_pack_end (GTK_BOX (tab->MTimebar), tab->MEventBox5b, FALSE,
4303 FALSE, 0);
4304 gtk_box_pack_end (GTK_BOX (tab->MTimebar), temp_widget, FALSE, FALSE, 0);
4305
4306
4307 //GtkWidget *test = gtk_button_new_with_label("drop");
4308 //gtk_button_set_relief(GTK_BUTTON(test), GTK_RELIEF_NONE);
4309 //gtk_widget_show(test);
4310 //gtk_box_pack_end(GTK_BOX (tab->MTimebar), test, FALSE, FALSE, 0);
4311 //gtk_widget_add_events(tab->MText1, GDK_ALL_EVENTS_MASK);//GDK_BUTTON_PRESS_MASK);
4312 /*GtkWidget *event_box = gtk_event_box_new();
4313 gtk_widget_show(event_box);
4314 gtk_tooltips_set_tip(tooltips, event_box,
4315 "Paste Current Time Here", "");
4316 gtk_box_pack_end(GTK_BOX (tab->MTimebar), event_box, FALSE, FALSE, 0);
4317 GtkWidget *test = gtk_label_new("drop");
4318 gtk_container_add(GTK_CONTAINER(event_box), test);
4319 gtk_widget_show(test);
4320 g_signal_connect (G_OBJECT(event_box),
4321 "button-press-event",
4322 G_CALLBACK (on_MText1_paste),
4323 (gpointer)tab);
4324 */
4325
4326 g_signal_connect (G_OBJECT(tab->MEventBox1a),
4327 "button-press-event",
4328 G_CALLBACK (on_MEventBox1a_paste),
4329 (gpointer)tab);
4330
4331 g_signal_connect (G_OBJECT(tab->MEventBox1b),
4332 "button-press-event",
4333 G_CALLBACK (on_MEventBox1b_paste),
4334 (gpointer)tab);
4335 g_signal_connect (G_OBJECT(tab->MEventBox3b),
4336 "button-press-event",
4337 G_CALLBACK (on_MEventBox3b_paste),
4338 (gpointer)tab);
4339 g_signal_connect (G_OBJECT(tab->MEventBox5b),
4340 "button-press-event",
4341 G_CALLBACK (on_MEventBox5b_paste),
4342 (gpointer)tab);
4343 }
4344
4345 gtk_box_pack_end(GTK_BOX(tab->vbox),
4346 tab->scrollbar,
4347 FALSE, /* Do not expand */
4348 FALSE, /* Fill has no effect here (expand false) */
4349 0); /* No padding */
4350
4351 gtk_box_pack_end(GTK_BOX(tab->vbox),
4352 tab->MTimebar,
4353 FALSE, /* Do not expand */
4354 FALSE, /* Fill has no effect here (expand false) */
4355 0); /* No padding */
4356
4357 g_object_set_data(G_OBJECT(tab->viewer_container), "focused_viewer", NULL);
4358
4359
4360 tab->mw = mw;
4361
4362 /*{
4363 // Display a label with a X
4364 GtkWidget *w_hbox = gtk_hbox_new(FALSE, 4);
4365 GtkWidget *w_label = gtk_label_new (label);
4366 GtkWidget *pixmap = create_pixmap(GTK_WIDGET(notebook), "close.png");
4367 GtkWidget *w_button = gtk_button_new ();
4368 gtk_container_add(GTK_CONTAINER(w_button), pixmap);
4369 //GtkWidget *w_button = gtk_button_new_with_label("x");
4370
4371 gtk_button_set_relief(GTK_BUTTON(w_button), GTK_RELIEF_NONE);
4372
4373 gtk_box_pack_start(GTK_BOX(w_hbox), w_label, TRUE, TRUE, 0);
4374 gtk_box_pack_end(GTK_BOX(w_hbox), w_button, FALSE,
4375 FALSE, 0);
4376
4377 g_signal_connect_swapped (w_button, "clicked",
4378 G_CALLBACK (on_close_tab_X_clicked),
4379 tab->multi_vpaned);
4380
4381 gtk_widget_set_state(w_button, GTK_STATE_ACTIVE);
4382
4383 gtk_widget_show (w_label);
4384 gtk_widget_show (pixmap);
4385 gtk_widget_show (w_button);
4386 gtk_widget_show (w_hbox);
4387
4388 tab->label = w_hbox;
4389 }*/
4390
4391
4392 tab->label = gtk_label_new (label);
4393
4394 gtk_widget_show(tab->label);
4395 gtk_widget_show(tab->scrollbar);
4396 gtk_widget_show(tab->viewer_container);
4397 gtk_widget_show(tab->vbox);
4398 //gtk_widget_show(tab->multivpaned);
4399
4400
4401 /* Start with empty events requests list */
4402 tab->events_requests = NULL;
4403 tab->events_request_pending = FALSE;
4404
4405 g_object_set_data_full(
4406 G_OBJECT(tab->vbox),
4407 "Tab_Info",
4408 tab,
4409 (GDestroyNotify)tab_destructor);
4410
4411 g_signal_connect(G_OBJECT(tab->scrollbar), "value-changed",
4412 G_CALLBACK(scroll_value_changed_cb), tab);
4413
4414 g_signal_connect ((gpointer) tab->MEntry1, "value-changed",
4415 G_CALLBACK (on_MEntry1_value_changed),
4416 tab);
4417 g_signal_connect ((gpointer) tab->MEntry2, "value-changed",
4418 G_CALLBACK (on_MEntry2_value_changed),
4419 tab);
4420 g_signal_connect ((gpointer) tab->MEntry3, "value-changed",
4421 G_CALLBACK (on_MEntry3_value_changed),
4422 tab);
4423 g_signal_connect ((gpointer) tab->MEntry4, "value-changed",
4424 G_CALLBACK (on_MEntry4_value_changed),
4425 tab);
4426 g_signal_connect ((gpointer) tab->MEntry5, "value-changed",
4427 G_CALLBACK (on_MEntry5_value_changed),
4428 tab);
4429 g_signal_connect ((gpointer) tab->MEntry6, "value-changed",
4430 G_CALLBACK (on_MEntry6_value_changed),
4431 tab);
4432
4433 //g_signal_connect(G_OBJECT(tab->scrollbar), "changed",
4434 // G_CALLBACK(scroll_value_changed_cb), tab);
4435
4436
4437 //insert tab into notebook
4438 gtk_notebook_append_page(notebook,
4439 tab->vbox,
4440 tab->label);
4441 list = gtk_container_get_children(GTK_CONTAINER(notebook));
4442 gtk_notebook_set_current_page(notebook,g_list_length(list)-1);
4443 // always show : not if(g_list_length(list)>1)
4444 gtk_notebook_set_show_tabs(notebook, TRUE);
4445
4446 if(copy_tab) {
4447 lttvwindow_report_time_window(tab, copy_tab->time_window);
4448 lttvwindow_report_current_time(tab, copy_tab->current_time);
4449 } else {
4450 TimeWindow time_window;
4451
4452 time_window.start_time = ltt_time_zero;
4453 time_window.end_time = ltt_time_add(time_window.start_time,
4454 lttvwindow_default_time_width);
4455 time_window.time_width = lttvwindow_default_time_width;
4456 time_window.time_width_double = ltt_time_to_double(time_window.time_width);
4457
4458 lttvwindow_report_time_window(tab, time_window);
4459 lttvwindow_report_current_time(tab, ltt_time_zero);
4460 }
4461
4462 LttvTraceset *traceset = tab->traceset_info->traceset;
4463 SetTraceset(tab, traceset);
4464
4465 return tab;
4466 }
4467
4468 /*
4469 * execute_events_requests
4470 *
4471 * Idle function that executes the pending requests for a tab.
4472 *
4473 * @return return value : TRUE : keep the idle function, FALSE : remove it.
4474 */
4475 gboolean execute_events_requests(Tab *tab)
4476 {
4477 return ( lttvwindow_process_pending_requests(tab) );
4478 }
4479
This page took 0.133608 seconds and 4 git commands to generate.