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