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