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