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