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