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