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