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