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