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