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