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