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