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