Partial revert "Disable sync/"
[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 //GtkDirSelection * file_selector = (GtkDirSelection *)gtk_dir_selection_new("Select a trace");
1849 GtkFileSelection * file_selector = (GtkFileSelection *)gtk_file_selection_new("Select a trace");
1850 gtk_widget_hide( (file_selector)->file_list->parent) ;
1851 gtk_file_selection_hide_fileop_buttons(file_selector);
1852 gtk_window_set_transient_for(GTK_WINDOW(file_selector),
1853 GTK_WINDOW(mw_data->mwindow));
1854
1855 if(remember_trace_dir[0] != '\0')
1856 gtk_file_selection_set_filename(file_selector, remember_trace_dir);
1857
1858 id = gtk_dialog_run(GTK_DIALOG(file_selector));
1859 switch(id){
1860 case GTK_RESPONSE_ACCEPT:
1861 case GTK_RESPONSE_OK:
1862 dir = gtk_file_selection_get_filename (file_selector);
1863 strncpy(remember_trace_dir, dir, PATH_MAX);
1864 strncat(remember_trace_dir, "/", PATH_MAX);
1865 if(!dir || strlen(dir) == 0){
1866 gtk_widget_destroy((GtkWidget*)file_selector);
1867 break;
1868 }
1869 get_absolute_pathname(dir, abs_path);
1870 trace_v = lttvwindowtraces_get_trace_by_name(abs_path);
1871 if(trace_v == NULL) {
1872 trace = ltt_trace_open(abs_path);
1873 if(trace == NULL) {
1874 g_warning("cannot open trace %s", abs_path);
1875
1876 GtkWidget *dialogue =
1877 gtk_message_dialog_new(
1878 GTK_WINDOW(gtk_widget_get_toplevel(widget)),
1879 GTK_DIALOG_MODAL|GTK_DIALOG_DESTROY_WITH_PARENT,
1880 GTK_MESSAGE_ERROR,
1881 GTK_BUTTONS_OK,
1882 "Cannot open trace : maybe you should enter in the trace "
1883 "directory to select it ?");
1884 gtk_dialog_run(GTK_DIALOG(dialogue));
1885 gtk_widget_destroy(dialogue);
1886
1887 } else {
1888 trace_v = lttv_trace_new(trace);
1889 lttvwindowtraces_add_trace(trace_v);
1890 lttvwindow_add_trace(tab, trace_v);
1891 }
1892 } else {
1893 lttvwindow_add_trace(tab, trace_v);
1894 }
1895
1896 gtk_widget_destroy((GtkWidget*)file_selector);
1897
1898 //update current tab
1899 //update_traceset(mw_data);
1900
1901 /* Call the updatetraceset hooks */
1902
1903 traceset = tab->traceset_info->traceset;
1904 SetTraceset(tab, traceset);
1905 // in expose now call_pending_read_hooks(mw_data);
1906
1907 //lttvwindow_report_current_time(mw_data,&(tab->current_time));
1908 break;
1909 case GTK_RESPONSE_REJECT:
1910 case GTK_RESPONSE_CANCEL:
1911 default:
1912 gtk_widget_destroy((GtkWidget*)file_selector);
1913 break;
1914 }
1915 }
1916
1917 /* remove_trace removes a trace from the current traceset if all viewers in
1918 * the current tab are not interested in the trace. It first displays a
1919 * dialogue, which shows all traces in the current traceset, to let user choose
1920 * a trace, then it checks if all viewers unselect the trace, if it is true,
1921 * it will remove the trace, recreate the traceset_contex,
1922 * and redraws all the viewer of the current tab. If there is on trace in the
1923 * current traceset, it will delete all viewers of the current tab
1924 *
1925 * It destroys the filter tree. FIXME... we should request for an update
1926 * instead.
1927 */
1928
1929 void remove_trace(GtkWidget *widget, gpointer user_data)
1930 {
1931 LttTrace *trace;
1932 LttvTrace * trace_v;
1933 LttvTraceset * traceset;
1934 gint i, j, nb_trace, index=-1;
1935 char ** name, *remove_trace_name;
1936 MainWindow * mw_data = get_window_data_struct(widget);
1937 GtkWidget * notebook = lookup_widget(widget, "MNotebook");
1938
1939 GtkWidget *page = gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook),
1940 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook)));
1941 Tab *tab;
1942
1943 if(!page) {
1944 return;
1945 } else {
1946 LttvPluginTab *ptab;
1947 ptab = (LttvPluginTab *)g_object_get_data(G_OBJECT(page), "Tab_Plugin");
1948 tab = ptab->tab;
1949 }
1950
1951 nb_trace =lttv_traceset_number(tab->traceset_info->traceset);
1952 name = g_new(char*,nb_trace);
1953 for(i = 0; i < nb_trace; i++){
1954 trace_v = lttv_traceset_get(tab->traceset_info->traceset, i);
1955 trace = lttv_trace(trace_v);
1956 name[i] = g_quark_to_string(ltt_trace_name(trace));
1957 }
1958
1959 remove_trace_name = get_remove_trace(mw_data, name, nb_trace);
1960
1961
1962 if(remove_trace_name){
1963
1964 /* yuk, cut n paste from old code.. should be better (MD)*/
1965 for(i = 0; i<nb_trace; i++) {
1966 if(strcmp(remove_trace_name,name[i]) == 0){
1967 index = i;
1968 }
1969 }
1970
1971 traceset = tab->traceset_info->traceset;
1972 //Keep a reference to the traces so they are not freed.
1973 for(j=0; j<lttv_traceset_number(traceset); j++)
1974 {
1975 LttvTrace * trace = lttv_traceset_get(traceset, j);
1976 lttv_trace_ref(trace);
1977 }
1978
1979 //remove state update hooks
1980 lttv_state_remove_event_hooks(
1981 (LttvTracesetState*)tab->traceset_info->traceset_context);
1982 lttv_context_fini(LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context));
1983 g_object_unref(tab->traceset_info->traceset_context);
1984
1985 trace_v = lttv_traceset_get(traceset, index);
1986
1987 lttv_traceset_remove(traceset, index);
1988 lttv_trace_unref(trace_v); // Remove local reference
1989
1990 if(lttv_trace_get_ref_number(trace_v) <= 1) {
1991 /* ref 1 : lttvwindowtraces only*/
1992 ltt_trace_close(lttv_trace(trace_v));
1993 /* lttvwindowtraces_remove_trace takes care of destroying
1994 * the traceset linked with the trace_v and also of destroying
1995 * the trace_v at the same time.
1996 */
1997 lttvwindowtraces_remove_trace(trace_v);
1998 }
1999
2000 tab->traceset_info->traceset_context =
2001 g_object_new(LTTV_TRACESET_STATS_TYPE, NULL);
2002 lttv_context_init(
2003 LTTV_TRACESET_CONTEXT(tab->
2004 traceset_info->traceset_context),traceset);
2005 //add state update hooks
2006 lttv_state_add_event_hooks(
2007 (LttvTracesetState*)tab->traceset_info->traceset_context);
2008
2009 //Remove local reference to the traces.
2010 for(j=0; j<lttv_traceset_number(traceset); j++)
2011 {
2012 LttvTrace * trace = lttv_traceset_get(traceset, j);
2013 lttv_trace_unref(trace);
2014 }
2015
2016 SetTraceset(tab, (gpointer)traceset);
2017 }
2018 g_free(name);
2019 }
2020
2021 #if 0
2022 void remove_trace(GtkWidget * widget, gpointer user_data)
2023 {
2024 LttTrace *trace;
2025 LttvTrace * trace_v;
2026 LttvTraceset * traceset;
2027 gint i, j, nb_trace;
2028 char ** name, *remove_trace_name;
2029 MainWindow * mw_data = get_window_data_struct(widget);
2030 LttvTracesetSelector * s;
2031 LttvTraceSelector * t;
2032 GtkWidget * w;
2033 gboolean selected;
2034 GtkWidget * notebook = lookup_widget(widget, "MNotebook");
2035
2036 GtkWidget *page = gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook),
2037 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook)));
2038 Tab *tab;
2039
2040 if(!page) {
2041 return;
2042 } else {
2043 tab = (Tab *)g_object_get_data(G_OBJECT(page), "Tab_Info");
2044 }
2045
2046 nb_trace =lttv_traceset_number(tab->traceset_info->traceset);
2047 name = g_new(char*,nb_trace);
2048 for(i = 0; i < nb_trace; i++){
2049 trace_v = lttv_traceset_get(tab->traceset_info->traceset, i);
2050 trace = lttv_trace(trace_v);
2051 name[i] = ltt_trace_name(trace);
2052 }
2053
2054 remove_trace_name = get_remove_trace(name, nb_trace);
2055
2056 if(remove_trace_name){
2057 for(i=0; i<nb_trace; i++){
2058 if(strcmp(remove_trace_name,name[i]) == 0){
2059 //unselect the trace from the current viewer
2060 //FIXME
2061 w = gtk_multivpaned_get_widget(GTK_MULTIVPANED(tab->multivpaned));
2062 if(w){
2063 s = g_object_get_data(G_OBJECT(w), "Traceset_Selector");
2064 if(s){
2065 t = lttv_traceset_selector_trace_get(s,i);
2066 lttv_trace_selector_set_selected(t, FALSE);
2067 }
2068
2069 //check if other viewers select the trace
2070 w = gtk_multivpaned_get_first_widget(GTK_MULTIVPANED(tab->multivpaned));
2071 while(w){
2072 s = g_object_get_data(G_OBJECT(w), "Traceset_Selector");
2073 if(s){
2074 t = lttv_traceset_selector_trace_get(s,i);
2075 selected = lttv_trace_selector_get_selected(t);
2076 if(selected)break;
2077 }
2078 w = gtk_multivpaned_get_next_widget(GTK_MULTIVPANED(tab->multivpaned));
2079 }
2080 }else selected = FALSE;
2081
2082 //if no viewer selects the trace, remove it
2083 if(!selected){
2084 remove_trace_from_traceset_selector(GTK_MULTIVPANED(tab->multivpaned), i);
2085
2086 traceset = tab->traceset_info->traceset;
2087 //Keep a reference to the traces so they are not freed.
2088 for(j=0; j<lttv_traceset_number(traceset); j++)
2089 {
2090 LttvTrace * trace = lttv_traceset_get(traceset, j);
2091 lttv_trace_ref(trace);
2092 }
2093
2094 //remove state update hooks
2095 lttv_state_remove_event_hooks(
2096 (LttvTracesetState*)tab->traceset_info->traceset_context);
2097 lttv_context_fini(LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context));
2098 g_object_unref(tab->traceset_info->traceset_context);
2099
2100
2101 trace_v = lttv_traceset_get(traceset, i);
2102
2103 if(lttv_trace_get_ref_number(trace_v) <= 2) {
2104 /* ref 2 : traceset, local */
2105 lttvwindowtraces_remove_trace(trace_v);
2106 ltt_trace_close(lttv_trace(trace_v));
2107 }
2108
2109 lttv_traceset_remove(traceset, i);
2110 lttv_trace_unref(trace_v); // Remove local reference
2111
2112 if(!lttv_trace_get_ref_number(trace_v))
2113 lttv_trace_destroy(trace_v);
2114
2115 tab->traceset_info->traceset_context =
2116 g_object_new(LTTV_TRACESET_STATS_TYPE, NULL);
2117 lttv_context_init(
2118 LTTV_TRACESET_CONTEXT(tab->
2119 traceset_info->traceset_context),traceset);
2120 //add state update hooks
2121 lttv_state_add_event_hooks(
2122 (LttvTracesetState*)tab->traceset_info->traceset_context);
2123
2124 //Remove local reference to the traces.
2125 for(j=0; j<lttv_traceset_number(traceset); j++)
2126 {
2127 LttvTrace * trace = lttv_traceset_get(traceset, j);
2128 lttv_trace_unref(trace);
2129 }
2130
2131
2132 //update current tab
2133 //update_traceset(mw_data);
2134 //if(nb_trace > 1){
2135
2136 SetTraceset(tab, (gpointer)traceset);
2137 // in expose now call_pending_read_hooks(mw_data);
2138
2139 //lttvwindow_report_current_time(mw_data,&(tab->current_time));
2140 //}else{
2141 // if(tab){
2142 // while(tab->multi_vpaned->num_children){
2143 // gtk_multi_vpaned_widget_delete(tab->multi_vpaned);
2144 // }
2145 // }
2146 //}
2147 }
2148 break;
2149 }
2150 }
2151 }
2152
2153 g_free(name);
2154 }
2155 #endif //0
2156
2157 /* Redraw all the viewers in the current tab */
2158 void redraw(GtkWidget *widget, gpointer user_data)
2159 {
2160 GtkWidget * notebook = lookup_widget(widget, "MNotebook");
2161 GtkWidget *page = gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook),
2162 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook)));
2163 Tab *tab;
2164 gboolean retval;
2165
2166 if(!page) {
2167 return;
2168 } else {
2169 LttvPluginTab *ptab;
2170 ptab = (LttvPluginTab *)g_object_get_data(G_OBJECT(page), "Tab_Plugin");
2171 tab = ptab->tab;
2172 }
2173
2174 LttvHooks * tmp;
2175 LttvAttributeValue value;
2176
2177 retval= lttv_iattribute_find_by_path(tab->attributes, "hooks/redraw", LTTV_POINTER, &value);
2178 g_assert(retval);
2179
2180 tmp = (LttvHooks*)*(value.v_pointer);
2181 if(tmp != NULL)
2182 lttv_hooks_call(tmp,NULL);
2183 }
2184
2185
2186 void continue_processing(GtkWidget *widget, gpointer user_data)
2187 {
2188 GtkWidget * notebook = lookup_widget(widget, "MNotebook");
2189 GtkWidget *page = gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook),
2190 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook)));
2191 Tab *tab;
2192 gboolean retval;
2193
2194 if(!page) {
2195 return;
2196 } else {
2197 LttvPluginTab *ptab;
2198 ptab = (LttvPluginTab *)g_object_get_data(G_OBJECT(page), "Tab_Plugin");
2199 tab = ptab->tab;
2200 }
2201
2202 LttvHooks * tmp;
2203 LttvAttributeValue value;
2204
2205 retval= lttv_iattribute_find_by_path(tab->attributes, "hooks/continue",
2206 LTTV_POINTER, &value);
2207 g_assert(retval);
2208
2209 tmp = (LttvHooks*)*(value.v_pointer);
2210 if(tmp != NULL)
2211 lttv_hooks_call(tmp,NULL);
2212 }
2213
2214 /* Stop the processing for the calling main window's current tab.
2215 * It removes every processing requests that are in its list. It does not call
2216 * the end request hooks, because the request is not finished.
2217 */
2218
2219 void stop_processing(GtkWidget *widget, gpointer user_data)
2220 {
2221 GtkWidget * notebook = lookup_widget(widget, "MNotebook");
2222 GtkWidget *page = gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook),
2223 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook)));
2224 Tab *tab;
2225 if(!page) {
2226 return;
2227 } else {
2228 LttvPluginTab *ptab;
2229 ptab = (LttvPluginTab *)g_object_get_data(G_OBJECT(page), "Tab_Plugin");
2230 tab = ptab->tab;
2231 }
2232 GSList *iter = tab->events_requests;
2233
2234 while(iter != NULL) {
2235 GSList *remove_iter = iter;
2236 iter = g_slist_next(iter);
2237
2238 g_free(remove_iter->data);
2239 tab->events_requests =
2240 g_slist_remove_link(tab->events_requests, remove_iter);
2241 }
2242 tab->events_request_pending = FALSE;
2243 tab->stop_foreground = TRUE;
2244 g_idle_remove_by_data(tab);
2245 g_assert(g_slist_length(tab->events_requests) == 0);
2246 }
2247
2248
2249 /* save will save the traceset to a file
2250 * Not implemented yet FIXME
2251 */
2252
2253 void save(GtkWidget * widget, gpointer user_data)
2254 {
2255 g_info("Save\n");
2256 }
2257
2258 void save_as(GtkWidget * widget, gpointer user_data)
2259 {
2260 g_info("Save as\n");
2261 }
2262
2263
2264 /* zoom will change the time_window of all the viewers of the
2265 * current tab, and redisplay them. The main functionality is to
2266 * determine the new time_window of the current tab
2267 */
2268
2269 void zoom(GtkWidget * widget, double size)
2270 {
2271 TimeInterval time_span;
2272 TimeWindow new_time_window;
2273 LttTime current_time, time_delta;
2274 MainWindow * mw_data = get_window_data_struct(widget);
2275 LttvTracesetContext *tsc;
2276 GtkWidget * notebook = lookup_widget(widget, "MNotebook");
2277
2278 GtkWidget *page = gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook),
2279 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook)));
2280 Tab *tab;
2281
2282 if(!page) {
2283 return;
2284 } else {
2285 LttvPluginTab *ptab;
2286 ptab = (LttvPluginTab *)g_object_get_data(G_OBJECT(page), "Tab_Plugin");
2287 tab = ptab->tab;
2288 }
2289
2290 if(size == 1) return;
2291
2292 tsc = LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context);
2293 time_span = tsc->time_span;
2294 new_time_window = tab->time_window;
2295 current_time = tab->current_time;
2296
2297 time_delta = ltt_time_sub(time_span.end_time,time_span.start_time);
2298 if(size == 0){
2299 new_time_window.start_time = time_span.start_time;
2300 new_time_window.time_width = time_delta;
2301 new_time_window.time_width_double = ltt_time_to_double(time_delta);
2302 new_time_window.end_time = ltt_time_add(new_time_window.start_time,
2303 new_time_window.time_width) ;
2304 }else{
2305 new_time_window.time_width = ltt_time_div(new_time_window.time_width, size);
2306 new_time_window.time_width_double =
2307 ltt_time_to_double(new_time_window.time_width);
2308 if(ltt_time_compare(new_time_window.time_width,time_delta) > 0)
2309 { /* Case where zoom out is bigger than trace length */
2310 new_time_window.start_time = time_span.start_time;
2311 new_time_window.time_width = time_delta;
2312 new_time_window.time_width_double = ltt_time_to_double(time_delta);
2313 new_time_window.end_time = ltt_time_add(new_time_window.start_time,
2314 new_time_window.time_width) ;
2315 }
2316 else
2317 {
2318 /* Center the image on the current time */
2319 new_time_window.start_time =
2320 ltt_time_sub(current_time,
2321 ltt_time_from_double(new_time_window.time_width_double/2.0));
2322 new_time_window.end_time = ltt_time_add(new_time_window.start_time,
2323 new_time_window.time_width) ;
2324 /* If on borders, don't fall off */
2325 if(ltt_time_compare(new_time_window.start_time, time_span.start_time) <0
2326 || ltt_time_compare(new_time_window.start_time, time_span.end_time) >0)
2327 {
2328 new_time_window.start_time = time_span.start_time;
2329 new_time_window.end_time = ltt_time_add(new_time_window.start_time,
2330 new_time_window.time_width) ;
2331 }
2332 else
2333 {
2334 if(ltt_time_compare(new_time_window.end_time,
2335 time_span.end_time) > 0
2336 || ltt_time_compare(new_time_window.end_time,
2337 time_span.start_time) < 0)
2338 {
2339 new_time_window.start_time =
2340 ltt_time_sub(time_span.end_time, new_time_window.time_width);
2341
2342 new_time_window.end_time = ltt_time_add(new_time_window.start_time,
2343 new_time_window.time_width) ;
2344 }
2345 }
2346
2347 }
2348 }
2349
2350 if(ltt_time_compare(new_time_window.time_width, ltt_time_zero) == 0) {
2351 g_warning("Zoom more than 1 ns impossible");
2352 } else {
2353 time_change_manager(tab, new_time_window);
2354 }
2355 }
2356
2357 void zoom_in(GtkWidget * widget, gpointer user_data)
2358 {
2359 zoom(widget, 2);
2360 }
2361
2362 void zoom_out(GtkWidget * widget, gpointer user_data)
2363 {
2364 zoom(widget, 0.5);
2365 }
2366
2367 void zoom_extended(GtkWidget * widget, gpointer user_data)
2368 {
2369 zoom(widget, 0);
2370 }
2371
2372 void go_to_time(GtkWidget * widget, gpointer user_data)
2373 {
2374 g_info("Go to time\n");
2375 }
2376
2377 void show_time_frame(GtkWidget * widget, gpointer user_data)
2378 {
2379 g_info("Show time frame\n");
2380 }
2381
2382
2383 /* callback function */
2384
2385 void
2386 on_empty_traceset_activate (GtkMenuItem *menuitem,
2387 gpointer user_data)
2388 {
2389 create_new_window((GtkWidget*)menuitem, user_data, FALSE);
2390 }
2391
2392
2393 void
2394 on_clone_traceset_activate (GtkMenuItem *menuitem,
2395 gpointer user_data)
2396 {
2397 create_new_window((GtkWidget*)menuitem, user_data, TRUE);
2398 }
2399
2400
2401 /* create_new_tab calls create_tab to construct a new tab in the main window
2402 */
2403
2404 LttvPluginTab *create_new_tab(GtkWidget* widget, gpointer user_data)
2405 {
2406 gchar label[PATH_MAX];
2407 MainWindow * mw_data = get_window_data_struct(widget);
2408
2409 GtkNotebook * notebook = (GtkNotebook *)lookup_widget(widget, "MNotebook");
2410 if(notebook == NULL){
2411 g_info("Notebook does not exist\n");
2412 return NULL;
2413 }
2414 GtkWidget *page = gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook),
2415 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook)));
2416 Tab *copy_tab;
2417
2418 if(!page) {
2419 copy_tab = NULL;
2420 } else {
2421 LttvPluginTab *ptab;
2422 ptab = (LttvPluginTab *)g_object_get_data(G_OBJECT(page), "Tab_Plugin");
2423 copy_tab = ptab->tab;
2424 }
2425
2426 strcpy(label,"Page");
2427 if(get_label(mw_data, label,"Get the name of the tab","Please input tab's name")) {
2428 LttvPluginTab *ptab;
2429
2430 ptab = g_object_new(LTTV_TYPE_PLUGIN_TAB, NULL);
2431 init_tab (ptab->tab, mw_data, copy_tab, notebook, label);
2432 ptab->parent.top_widget = ptab->tab->top_widget;
2433 g_object_set_data_full(
2434 G_OBJECT(ptab->tab->vbox),
2435 "Tab_Plugin",
2436 ptab,
2437 (GDestroyNotify)tab_destructor);
2438 return ptab;
2439 }
2440 else return NULL;
2441 }
2442
2443 void
2444 on_tab_activate (GtkMenuItem *menuitem,
2445 gpointer user_data)
2446 {
2447 create_new_tab((GtkWidget*)menuitem, user_data);
2448 }
2449
2450
2451 void
2452 on_open_activate (GtkMenuItem *menuitem,
2453 gpointer user_data)
2454 {
2455 open_traceset((GtkWidget*)menuitem, user_data);
2456 }
2457
2458
2459 void
2460 on_close_activate (GtkMenuItem *menuitem,
2461 gpointer user_data)
2462 {
2463 MainWindow * mw_data = get_window_data_struct((GtkWidget*)menuitem);
2464 main_window_destructor(mw_data);
2465 }
2466
2467
2468 /* remove the current tab from the main window
2469 */
2470
2471 void
2472 on_close_tab_activate (GtkWidget *widget,
2473 gpointer user_data)
2474 {
2475 gint page_num;
2476 GtkWidget * notebook;
2477 GtkWidget * page;
2478 MainWindow * mw_data = get_window_data_struct(widget);
2479 notebook = lookup_widget(widget, "MNotebook");
2480 if(notebook == NULL){
2481 g_info("Notebook does not exist\n");
2482 return;
2483 }
2484
2485 page_num = gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook));
2486
2487 gtk_notebook_remove_page(GTK_NOTEBOOK(notebook), page_num);
2488
2489 }
2490
2491 void
2492 on_close_tab_X_clicked (GtkWidget *widget,
2493 gpointer user_data)
2494 {
2495 gint page_num;
2496 GtkWidget *notebook = lookup_widget(widget, "MNotebook");
2497 if(notebook == NULL){
2498 g_info("Notebook does not exist\n");
2499 return;
2500 }
2501
2502 if((page_num = gtk_notebook_page_num(GTK_NOTEBOOK(notebook), widget)) != -1)
2503 gtk_notebook_remove_page(GTK_NOTEBOOK(notebook), page_num);
2504
2505 }
2506
2507
2508 void
2509 on_add_trace_activate (GtkMenuItem *menuitem,
2510 gpointer user_data)
2511 {
2512 add_trace((GtkWidget*)menuitem, user_data);
2513 }
2514
2515
2516 void
2517 on_remove_trace_activate (GtkMenuItem *menuitem,
2518 gpointer user_data)
2519 {
2520 remove_trace((GtkWidget*)menuitem, user_data);
2521 }
2522
2523
2524 void
2525 on_save_activate (GtkMenuItem *menuitem,
2526 gpointer user_data)
2527 {
2528 save((GtkWidget*)menuitem, user_data);
2529 }
2530
2531
2532 void
2533 on_save_as_activate (GtkMenuItem *menuitem,
2534 gpointer user_data)
2535 {
2536 save_as((GtkWidget*)menuitem, user_data);
2537 }
2538
2539
2540 void
2541 on_quit_activate (GtkMenuItem *menuitem,
2542 gpointer user_data)
2543 {
2544 while (g_slist_length(g_main_window_list) != 0) {
2545 on_MWindow_destroy(((MainWindow *)g_main_window_list->data)->mwindow,
2546 user_data);
2547 }
2548 }
2549
2550
2551 void
2552 on_cut_activate (GtkMenuItem *menuitem,
2553 gpointer user_data)
2554 {
2555 g_info("Cut\n");
2556 }
2557
2558
2559 void
2560 on_copy_activate (GtkMenuItem *menuitem,
2561 gpointer user_data)
2562 {
2563 g_info("Copye\n");
2564 }
2565
2566
2567 void
2568 on_paste_activate (GtkMenuItem *menuitem,
2569 gpointer user_data)
2570 {
2571 g_info("Paste\n");
2572 }
2573
2574
2575 void
2576 on_delete_activate (GtkMenuItem *menuitem,
2577 gpointer user_data)
2578 {
2579 g_info("Delete\n");
2580 }
2581
2582
2583 void
2584 on_zoom_in_activate (GtkMenuItem *menuitem,
2585 gpointer user_data)
2586 {
2587 zoom_in((GtkWidget*)menuitem, user_data);
2588 }
2589
2590
2591 void
2592 on_zoom_out_activate (GtkMenuItem *menuitem,
2593 gpointer user_data)
2594 {
2595 zoom_out((GtkWidget*)menuitem, user_data);
2596 }
2597
2598
2599 void
2600 on_zoom_extended_activate (GtkMenuItem *menuitem,
2601 gpointer user_data)
2602 {
2603 zoom_extended((GtkWidget*)menuitem, user_data);
2604 }
2605
2606
2607 void
2608 on_go_to_time_activate (GtkMenuItem *menuitem,
2609 gpointer user_data)
2610 {
2611 go_to_time((GtkWidget*)menuitem, user_data);
2612 }
2613
2614
2615 void
2616 on_show_time_frame_activate (GtkMenuItem *menuitem,
2617 gpointer user_data)
2618 {
2619 show_time_frame((GtkWidget*)menuitem, user_data);
2620 }
2621
2622
2623 void
2624 on_move_viewer_up_activate (GtkMenuItem *menuitem,
2625 gpointer user_data)
2626 {
2627 move_up_viewer((GtkWidget*)menuitem, user_data);
2628 }
2629
2630
2631 void
2632 on_move_viewer_down_activate (GtkMenuItem *menuitem,
2633 gpointer user_data)
2634 {
2635 move_down_viewer((GtkWidget*)menuitem, user_data);
2636 }
2637
2638
2639 void
2640 on_remove_viewer_activate (GtkMenuItem *menuitem,
2641 gpointer user_data)
2642 {
2643 delete_viewer((GtkWidget*)menuitem, user_data);
2644 }
2645
2646 void
2647 on_trace_facility_activate (GtkMenuItem *menuitem,
2648 gpointer user_data)
2649 {
2650 g_info("Trace facility selector: %s\n", "");
2651 }
2652
2653
2654 /* Dispaly a file selection dialogue to let user select a library, then call
2655 * lttv_library_load().
2656 */
2657
2658 void
2659 on_load_library_activate (GtkMenuItem *menuitem,
2660 gpointer user_data)
2661 {
2662 GError *error = NULL;
2663 MainWindow * mw_data = get_window_data_struct((GtkWidget*)menuitem);
2664
2665 gchar load_module_path_alter[PATH_MAX];
2666 {
2667 GPtrArray *name;
2668 guint nb,i;
2669 gchar *load_module_path;
2670 name = g_ptr_array_new();
2671 nb = lttv_library_path_number();
2672 /* ask for the library path */
2673
2674 for(i=0;i<nb;i++){
2675 gchar *path;
2676 path = lttv_library_path_get(i);
2677 g_ptr_array_add(name, path);
2678 }
2679
2680 load_module_path = get_selection(mw_data,
2681 (char **)(name->pdata), name->len,
2682 "Select a library path", "Library paths");
2683 if(load_module_path != NULL)
2684 strncpy(load_module_path_alter, load_module_path, PATH_MAX-1); // -1 for /
2685
2686 g_ptr_array_free(name, TRUE);
2687
2688 if(load_module_path == NULL) return;
2689 }
2690
2691 {
2692 /* Make sure the module path ends with a / */
2693 gchar *ptr = load_module_path_alter;
2694
2695 ptr = strchr(ptr, '\0');
2696
2697 if(*(ptr-1) != '/') {
2698 *ptr = '/';
2699 *(ptr+1) = '\0';
2700 }
2701 }
2702
2703 {
2704 /* Ask for the library to load : list files in the previously selected
2705 * directory */
2706 gchar str[PATH_MAX];
2707 gchar ** dir;
2708 gint id;
2709 GtkFileSelection * file_selector =
2710 (GtkFileSelection *)gtk_file_selection_new("Select a module");
2711 gtk_file_selection_set_filename(file_selector, load_module_path_alter);
2712 gtk_file_selection_hide_fileop_buttons(file_selector);
2713
2714 gtk_window_set_transient_for(GTK_WINDOW(file_selector),
2715 GTK_WINDOW(mw_data->mwindow));
2716
2717 str[0] = '\0';
2718 id = gtk_dialog_run(GTK_DIALOG(file_selector));
2719 switch(id){
2720 case GTK_RESPONSE_ACCEPT:
2721 case GTK_RESPONSE_OK:
2722 dir = gtk_file_selection_get_selections (file_selector);
2723 strncpy(str,dir[0],PATH_MAX);
2724 strncpy(remember_plugins_dir,dir[0],PATH_MAX);
2725 /* only keep file name */
2726 gchar *str1;
2727 str1 = strrchr(str,'/');
2728 if(str1)str1++;
2729 else{
2730 str1 = strrchr(str,'\\');
2731 str1++;
2732 }
2733 #if 0
2734 /* remove "lib" */
2735 if(*str1 == 'l' && *(str1+1)== 'i' && *(str1+2)=='b')
2736 str1=str1+3;
2737 remove info after . */
2738 {
2739 gchar *str2 = str1;
2740
2741 str2 = strrchr(str2, '.');
2742 if(str2 != NULL) *str2 = '\0';
2743 }
2744 lttv_module_require(str1, &error);
2745 #endif //0
2746 lttv_library_load(str1, &error);
2747 if(error != NULL) g_warning("%s", error->message);
2748 else g_info("Load library: %s\n", str);
2749 g_strfreev(dir);
2750 case GTK_RESPONSE_REJECT:
2751 case GTK_RESPONSE_CANCEL:
2752 default:
2753 gtk_widget_destroy((GtkWidget*)file_selector);
2754 break;
2755 }
2756
2757 }
2758
2759
2760
2761 }
2762
2763
2764 /* Display all loaded modules, let user to select a module to unload
2765 * by calling lttv_module_unload
2766 */
2767
2768 void
2769 on_unload_library_activate (GtkMenuItem *menuitem,
2770 gpointer user_data)
2771 {
2772 MainWindow * mw_data = get_window_data_struct((GtkWidget*)menuitem);
2773
2774 LttvLibrary *library = NULL;
2775
2776 GPtrArray *name;
2777 guint nb,i;
2778 gchar *lib_name;
2779 name = g_ptr_array_new();
2780 nb = lttv_library_number();
2781 LttvLibraryInfo *lib_info = g_new(LttvLibraryInfo,nb);
2782 /* ask for the library name */
2783
2784 for(i=0;i<nb;i++){
2785 LttvLibrary *iter_lib = lttv_library_get(i);
2786 lttv_library_info(iter_lib, &lib_info[i]);
2787
2788 gchar *path = lib_info[i].name;
2789 g_ptr_array_add(name, path);
2790 }
2791 lib_name = get_selection(mw_data, (char **)(name->pdata), name->len,
2792 "Select a library", "Libraries");
2793 if(lib_name != NULL) {
2794 for(i=0;i<nb;i++){
2795 if(strcmp(lib_name, lib_info[i].name) == 0) {
2796 library = lttv_library_get(i);
2797 break;
2798 }
2799 }
2800 }
2801 g_ptr_array_free(name, TRUE);
2802 g_free(lib_info);
2803
2804 if(lib_name == NULL) return;
2805
2806 if(library != NULL) lttv_library_unload(library);
2807 }
2808
2809
2810 /* Dispaly a file selection dialogue to let user select a module, then call
2811 * lttv_module_require().
2812 */
2813
2814 void
2815 on_load_module_activate (GtkMenuItem *menuitem,
2816 gpointer user_data)
2817 {
2818 GError *error = NULL;
2819 MainWindow * mw_data = get_window_data_struct((GtkWidget*)menuitem);
2820
2821 LttvLibrary *library = NULL;
2822 {
2823 GPtrArray *name;
2824 guint nb,i;
2825 gchar *lib_name;
2826 name = g_ptr_array_new();
2827 nb = lttv_library_number();
2828 LttvLibraryInfo *lib_info = g_new(LttvLibraryInfo,nb);
2829 /* ask for the library name */
2830
2831 for(i=0;i<nb;i++){
2832 LttvLibrary *iter_lib = lttv_library_get(i);
2833 lttv_library_info(iter_lib, &lib_info[i]);
2834
2835 gchar *path = lib_info[i].name;
2836 g_ptr_array_add(name, path);
2837 }
2838 lib_name = get_selection(mw_data,(char **)(name->pdata), name->len,
2839 "Select a library", "Libraries");
2840 if(lib_name != NULL) {
2841 for(i=0;i<nb;i++){
2842 if(strcmp(lib_name, lib_info[i].name) == 0) {
2843 library = lttv_library_get(i);
2844 break;
2845 }
2846 }
2847 }
2848 g_ptr_array_free(name, TRUE);
2849 g_free(lib_info);
2850
2851 if(lib_name == NULL) return;
2852 }
2853
2854 //LttvModule *module;
2855 gchar module_name_out[PATH_MAX];
2856 {
2857 /* Ask for the module to load : list modules in the selected lib */
2858 GPtrArray *name;
2859 guint nb,i;
2860 gchar *module_name;
2861 nb = lttv_library_module_number(library);
2862 LttvModuleInfo *module_info = g_new(LttvModuleInfo,nb);
2863 name = g_ptr_array_new();
2864 /* ask for the module name */
2865
2866 for(i=0;i<nb;i++){
2867 LttvModule *iter_module = lttv_library_module_get(library, i);
2868 lttv_module_info(iter_module, &module_info[i]);
2869
2870 gchar *path = module_info[i].name;
2871 g_ptr_array_add(name, path);
2872 }
2873 module_name = get_selection(mw_data, (char **)(name->pdata), name->len,
2874 "Select a module", "Modules");
2875 if(module_name != NULL) {
2876 for(i=0;i<nb;i++){
2877 if(strcmp(module_name, module_info[i].name) == 0) {
2878 strncpy(module_name_out, module_name, PATH_MAX);
2879 //module = lttv_library_module_get(i);
2880 break;
2881 }
2882 }
2883 }
2884
2885 g_ptr_array_free(name, TRUE);
2886 g_free(module_info);
2887
2888 if(module_name == NULL) return;
2889 }
2890
2891 lttv_module_require(module_name_out, &error);
2892 if(error != NULL) g_warning("%s", error->message);
2893 else g_info("Load module: %s", module_name_out);
2894
2895
2896 #if 0
2897 {
2898
2899
2900 gchar str[PATH_MAX];
2901 gchar ** dir;
2902 gint id;
2903 GtkFileSelection * file_selector =
2904 (GtkFileSelection *)gtk_file_selection_new("Select a module");
2905 gtk_file_selection_set_filename(file_selector, load_module_path_alter);
2906 gtk_file_selection_hide_fileop_buttons(file_selector);
2907
2908 str[0] = '\0';
2909 id = gtk_dialog_run(GTK_DIALOG(file_selector));
2910 switch(id){
2911 case GTK_RESPONSE_ACCEPT:
2912 case GTK_RESPONSE_OK:
2913 dir = gtk_file_selection_get_selections (file_selector);
2914 strncpy(str,dir[0],PATH_MAX);
2915 strncpy(remember_plugins_dir,dir[0],PATH_MAX);
2916 {
2917 /* only keep file name */
2918 gchar *str1;
2919 str1 = strrchr(str,'/');
2920 if(str1)str1++;
2921 else{
2922 str1 = strrchr(str,'\\');
2923 str1++;
2924 }
2925 #if 0
2926 /* remove "lib" */
2927 if(*str1 == 'l' && *(str1+1)== 'i' && *(str1+2)=='b')
2928 str1=str1+3;
2929 remove info after . */
2930 {
2931 gchar *str2 = str1;
2932
2933 str2 = strrchr(str2, '.');
2934 if(str2 != NULL) *str2 = '\0';
2935 }
2936 lttv_module_require(str1, &error);
2937 #endif //0
2938 lttv_library_load(str1, &error);
2939 if(error != NULL) g_warning(error->message);
2940 else g_info("Load library: %s\n", str);
2941 g_strfreev(dir);
2942 case GTK_RESPONSE_REJECT:
2943 case GTK_RESPONSE_CANCEL:
2944 default:
2945 gtk_widget_destroy((GtkWidget*)file_selector);
2946 break;
2947 }
2948
2949 }
2950 #endif //0
2951
2952
2953 }
2954
2955
2956
2957 /* Display all loaded modules, let user to select a module to unload
2958 * by calling lttv_module_unload
2959 */
2960
2961 void
2962 on_unload_module_activate (GtkMenuItem *menuitem,
2963 gpointer user_data)
2964 {
2965 GError *error = NULL;
2966 MainWindow * mw_data = get_window_data_struct((GtkWidget*)menuitem);
2967
2968 LttvLibrary *library = NULL;
2969 {
2970 GPtrArray *name;
2971 guint nb,i;
2972 gchar *lib_name;
2973 name = g_ptr_array_new();
2974 nb = lttv_library_number();
2975 LttvLibraryInfo *lib_info = g_new(LttvLibraryInfo,nb);
2976 /* ask for the library name */
2977
2978 for(i=0;i<nb;i++){
2979 LttvLibrary *iter_lib = lttv_library_get(i);
2980 lttv_library_info(iter_lib, &lib_info[i]);
2981
2982 gchar *path = lib_info[i].name;
2983 g_ptr_array_add(name, path);
2984 }
2985 lib_name = get_selection(mw_data, (char **)(name->pdata), name->len,
2986 "Select a library", "Libraries");
2987 if(lib_name != NULL) {
2988 for(i=0;i<nb;i++){
2989 if(strcmp(lib_name, lib_info[i].name) == 0) {
2990 library = lttv_library_get(i);
2991 break;
2992 }
2993 }
2994 }
2995 g_ptr_array_free(name, TRUE);
2996 g_free(lib_info);
2997
2998 if(lib_name == NULL) return;
2999 }
3000
3001 LttvModule *module = NULL;
3002 {
3003 /* Ask for the module to load : list modules in the selected lib */
3004 GPtrArray *name;
3005 guint nb,i;
3006 gchar *module_name;
3007 nb = lttv_library_module_number(library);
3008 LttvModuleInfo *module_info = g_new(LttvModuleInfo,nb);
3009 name = g_ptr_array_new();
3010 /* ask for the module name */
3011
3012 for(i=0;i<nb;i++){
3013 LttvModule *iter_module = lttv_library_module_get(library, i);
3014 lttv_module_info(iter_module, &module_info[i]);
3015
3016 gchar *path = module_info[i].name;
3017 if(module_info[i].use_count > 0) g_ptr_array_add(name, path);
3018 }
3019 module_name = get_selection(mw_data, (char **)(name->pdata), name->len,
3020 "Select a module", "Modules");
3021 if(module_name != NULL) {
3022 for(i=0;i<nb;i++){
3023 if(strcmp(module_name, module_info[i].name) == 0) {
3024 module = lttv_library_module_get(library, i);
3025 break;
3026 }
3027 }
3028 }
3029
3030 g_ptr_array_free(name, TRUE);
3031 g_free(module_info);
3032
3033 if(module_name == NULL) return;
3034 }
3035
3036 LttvModuleInfo module_info;
3037 lttv_module_info(module, &module_info);
3038 g_info("Release module: %s\n", module_info.name);
3039
3040 lttv_module_release(module);
3041 }
3042
3043
3044 /* Display a directory dialogue to let user select a path for library searching
3045 */
3046
3047 void
3048 on_add_library_search_path_activate (GtkMenuItem *menuitem,
3049 gpointer user_data)
3050 {
3051 MainWindow * mw_data = get_window_data_struct((GtkWidget*)menuitem);
3052 //GtkDirSelection * file_selector = (GtkDirSelection *)gtk_dir_selection_new("Select library path");
3053 GtkFileSelection * file_selector = (GtkFileSelection *)gtk_file_selection_new("Select a trace");
3054 gtk_widget_hide( (file_selector)->file_list->parent) ;
3055
3056 gtk_window_set_transient_for(GTK_WINDOW(file_selector),
3057 GTK_WINDOW(mw_data->mwindow));
3058
3059 const char * dir;
3060 gint id;
3061
3062 if(remember_plugins_dir[0] != '\0')
3063 gtk_file_selection_set_filename(file_selector, remember_plugins_dir);
3064
3065 id = gtk_dialog_run(GTK_DIALOG(file_selector));
3066 switch(id){
3067 case GTK_RESPONSE_ACCEPT:
3068 case GTK_RESPONSE_OK:
3069 dir = gtk_file_selection_get_filename (file_selector);
3070 strncpy(remember_plugins_dir,dir,PATH_MAX);
3071 strncat(remember_plugins_dir,"/",PATH_MAX);
3072 lttv_library_path_add(dir);
3073 case GTK_RESPONSE_REJECT:
3074 case GTK_RESPONSE_CANCEL:
3075 default:
3076 gtk_widget_destroy((GtkWidget*)file_selector);
3077 break;
3078 }
3079 }
3080
3081
3082 /* Display a directory dialogue to let user select a path for library searching
3083 */
3084
3085 void
3086 on_remove_library_search_path_activate (GtkMenuItem *menuitem,
3087 gpointer user_data)
3088 {
3089 MainWindow * mw_data = get_window_data_struct((GtkWidget*)menuitem);
3090
3091 const char *lib_path;
3092 {
3093 GPtrArray *name;
3094 guint nb,i;
3095 gchar *lib_name;
3096 name = g_ptr_array_new();
3097 nb = lttv_library_path_number();
3098 /* ask for the library name */
3099
3100 for(i=0;i<nb;i++){
3101 gchar *path = lttv_library_path_get(i);
3102 g_ptr_array_add(name, path);
3103 }
3104 lib_path = get_selection(mw_data, (char **)(name->pdata), name->len,
3105 "Select a library path", "Library paths");
3106
3107 g_ptr_array_free(name, TRUE);
3108
3109 if(lib_path == NULL) return;
3110 }
3111
3112 lttv_library_path_remove(lib_path);
3113 }
3114
3115 void
3116 on_color_activate (GtkMenuItem *menuitem,
3117 gpointer user_data)
3118 {
3119 g_info("Color\n");
3120 }
3121
3122
3123 void
3124 on_save_configuration_activate (GtkMenuItem *menuitem,
3125 gpointer user_data)
3126 {
3127 g_info("Save configuration\n");
3128 }
3129
3130
3131 void
3132 on_content_activate (GtkMenuItem *menuitem,
3133 gpointer user_data)
3134 {
3135 g_info("Content\n");
3136 }
3137
3138
3139 static void
3140 on_about_close_activate (GtkButton *button,
3141 gpointer user_data)
3142 {
3143 GtkWidget *about_widget = GTK_WIDGET(user_data);
3144
3145 gtk_widget_destroy(about_widget);
3146 }
3147
3148 void
3149 on_about_activate (GtkMenuItem *menuitem,
3150 gpointer user_data)
3151 {
3152 MainWindow *main_window = get_window_data_struct(GTK_WIDGET(menuitem));
3153 GtkWidget *window_widget = main_window->mwindow;
3154 GtkWidget *about_widget = gtk_window_new(GTK_WINDOW_TOPLEVEL);
3155 GtkWindow *about_window = GTK_WINDOW(about_widget);
3156 gint window_width, window_height;
3157
3158 gtk_window_set_title(about_window, "About Linux Trace Toolkit");
3159
3160 gtk_window_set_resizable(about_window, FALSE);
3161 gtk_window_set_transient_for(about_window, GTK_WINDOW(window_widget));
3162 gtk_window_set_destroy_with_parent(about_window, TRUE);
3163 gtk_window_set_modal(about_window, FALSE);
3164
3165 /* Put the about window at the center of the screen */
3166 gtk_window_get_size(about_window, &window_width, &window_height);
3167 gtk_window_move (about_window,
3168 (gdk_screen_width() - window_width)/2,
3169 (gdk_screen_height() - window_height)/2);
3170
3171 GtkWidget *vbox = gtk_vbox_new(FALSE, 1);
3172
3173 gtk_container_add(GTK_CONTAINER(about_widget), vbox);
3174
3175
3176 /* Text to show */
3177 GtkWidget *label1 = gtk_label_new("");
3178 gtk_misc_set_padding(GTK_MISC(label1), 10, 20);
3179 gtk_label_set_markup(GTK_LABEL(label1), "\
3180 <big>Linux Trace Toolkit " VERSION "</big>");
3181 gtk_label_set_justify(GTK_LABEL(label1), GTK_JUSTIFY_CENTER);
3182
3183 GtkWidget *label2 = gtk_label_new("");
3184 gtk_misc_set_padding(GTK_MISC(label2), 10, 20);
3185 gtk_label_set_markup(GTK_LABEL(label2), "\
3186 Contributors :\n\
3187 \n\
3188 Michel Dagenais (New trace format, lttv main)\n\
3189 Mathieu Desnoyers (Kernel Tracer, Directory structure, build with automake/conf,\n\
3190 lttv gui, control flow view, gui cooperative trace reading\n\
3191 scheduler with interruptible foreground and background\n\
3192 computation, detailed event list (rewrite), trace reading\n\
3193 library (rewrite))\n\
3194 Benoit Des Ligneris, Eric Clement (Cluster adaptation, work in progress)\n\
3195 Xang-Xiu Yang (new trace reading library and converter, lttv gui, \n\
3196 detailed event list and statistics view)\n\
3197 Tom Zanussi (RelayFS)\n\
3198 \n\
3199 Inspired from the original Linux Trace Toolkit Visualizer made by\n\
3200 Karim Yaghmour");
3201
3202 GtkWidget *label3 = gtk_label_new("");
3203 gtk_label_set_markup(GTK_LABEL(label3), "\
3204 Linux Trace Toolkit Viewer, Copyright (C) 2004, 2005, 2006\n\
3205 Michel Dagenais\n\
3206 Mathieu Desnoyers\n\
3207 Xang-Xiu Yang\n\
3208 Linux Trace Toolkit comes with ABSOLUTELY NO WARRANTY.\n\
3209 This is free software, and you are welcome to redistribute it\n\
3210 under certain conditions. See COPYING for details.");
3211 gtk_misc_set_padding(GTK_MISC(label3), 10, 20);
3212
3213 gtk_box_pack_start_defaults(GTK_BOX(vbox), label1);
3214 gtk_box_pack_start_defaults(GTK_BOX(vbox), label2);
3215 gtk_box_pack_start_defaults(GTK_BOX(vbox), label3);
3216
3217 GtkWidget *hbox = gtk_hbox_new(TRUE, 0);
3218 gtk_box_pack_end(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
3219 GtkWidget *close_button = gtk_button_new_with_mnemonic("_Close");
3220 gtk_box_pack_end(GTK_BOX(hbox), close_button, FALSE, FALSE, 0);
3221 gtk_container_set_border_width(GTK_CONTAINER(close_button), 20);
3222
3223 g_signal_connect(G_OBJECT(close_button), "clicked",
3224 G_CALLBACK(on_about_close_activate),
3225 (gpointer)about_widget);
3226
3227 gtk_widget_show_all(about_widget);
3228 }
3229
3230
3231 void
3232 on_button_new_clicked (GtkButton *button,
3233 gpointer user_data)
3234 {
3235 create_new_window((GtkWidget*)button, user_data, TRUE);
3236 }
3237
3238 void
3239 on_button_new_tab_clicked (GtkButton *button,
3240 gpointer user_data)
3241 {
3242 create_new_tab((GtkWidget*)button, user_data);
3243 }
3244
3245 void
3246 on_button_open_clicked (GtkButton *button,
3247 gpointer user_data)
3248 {
3249 open_traceset((GtkWidget*)button, user_data);
3250 }
3251
3252
3253 void
3254 on_button_add_trace_clicked (GtkButton *button,
3255 gpointer user_data)
3256 {
3257 add_trace((GtkWidget*)button, user_data);
3258 }
3259
3260
3261 void
3262 on_button_remove_trace_clicked (GtkButton *button,
3263 gpointer user_data)
3264 {
3265 remove_trace((GtkWidget*)button, user_data);
3266 }
3267
3268 void
3269 on_button_redraw_clicked (GtkButton *button,
3270 gpointer user_data)
3271 {
3272 redraw((GtkWidget*)button, user_data);
3273 }
3274
3275 void
3276 on_button_continue_processing_clicked (GtkButton *button,
3277 gpointer user_data)
3278 {
3279 continue_processing((GtkWidget*)button, user_data);
3280 }
3281
3282 void
3283 on_button_stop_processing_clicked (GtkButton *button,
3284 gpointer user_data)
3285 {
3286 stop_processing((GtkWidget*)button, user_data);
3287 }
3288
3289
3290
3291 void
3292 on_button_save_clicked (GtkButton *button,
3293 gpointer user_data)
3294 {
3295 save((GtkWidget*)button, user_data);
3296 }
3297
3298
3299 void
3300 on_button_save_as_clicked (GtkButton *button,
3301 gpointer user_data)
3302 {
3303 save_as((GtkWidget*)button, user_data);
3304 }
3305
3306
3307 void
3308 on_button_zoom_in_clicked (GtkButton *button,
3309 gpointer user_data)
3310 {
3311 zoom_in((GtkWidget*)button, user_data);
3312 }
3313
3314
3315 void
3316 on_button_zoom_out_clicked (GtkButton *button,
3317 gpointer user_data)
3318 {
3319 zoom_out((GtkWidget*)button, user_data);
3320 }
3321
3322
3323 void
3324 on_button_zoom_extended_clicked (GtkButton *button,
3325 gpointer user_data)
3326 {
3327 zoom_extended((GtkWidget*)button, user_data);
3328 }
3329
3330
3331 void
3332 on_button_go_to_time_clicked (GtkButton *button,
3333 gpointer user_data)
3334 {
3335 go_to_time((GtkWidget*)button, user_data);
3336 }
3337
3338
3339 void
3340 on_button_show_time_frame_clicked (GtkButton *button,
3341 gpointer user_data)
3342 {
3343 show_time_frame((GtkWidget*)button, user_data);
3344 }
3345
3346
3347 void
3348 on_button_move_up_clicked (GtkButton *button,
3349 gpointer user_data)
3350 {
3351 move_up_viewer((GtkWidget*)button, user_data);
3352 }
3353
3354
3355 void
3356 on_button_move_down_clicked (GtkButton *button,
3357 gpointer user_data)
3358 {
3359 move_down_viewer((GtkWidget*)button, user_data);
3360 }
3361
3362
3363 void
3364 on_button_delete_viewer_clicked (GtkButton *button,
3365 gpointer user_data)
3366 {
3367 delete_viewer((GtkWidget*)button, user_data);
3368 }
3369
3370 void
3371 on_MWindow_destroy (GtkWidget *widget,
3372 gpointer user_data)
3373 {
3374 MainWindow *main_window = get_window_data_struct(widget);
3375 LttvIAttribute *attributes = main_window->attributes;
3376 LttvAttributeValue value;
3377 gboolean retval;
3378
3379 //This is unnecessary, since widgets will be destroyed
3380 //by the main window widget anyway.
3381 //remove_all_menu_toolbar_constructors(main_window, NULL);
3382
3383 retval= lttv_iattribute_find_by_path(attributes, "viewers/menu",
3384 LTTV_POINTER, &value);
3385 g_assert(retval);
3386 lttv_menus_destroy((LttvMenus*)*(value.v_pointer));
3387
3388 retval= lttv_iattribute_find_by_path(attributes, "viewers/toolbar",
3389 LTTV_POINTER, &value);
3390 g_assert(retval);
3391 lttv_toolbars_destroy((LttvToolbars*)*(value.v_pointer));
3392
3393 g_object_unref(main_window->attributes);
3394 g_main_window_list = g_slist_remove(g_main_window_list, main_window);
3395
3396 g_info("There are now : %d windows\n",g_slist_length(g_main_window_list));
3397 if(g_slist_length(g_main_window_list) == 0)
3398 mainwindow_quit();
3399 }
3400
3401 gboolean
3402 on_MWindow_configure (GtkWidget *widget,
3403 GdkEventConfigure *event,
3404 gpointer user_data)
3405 {
3406 MainWindow * mw_data = get_window_data_struct((GtkWidget*)widget);
3407
3408 // MD : removed time width modification upon resizing of the main window.
3409 // The viewers will redraw themselves completely, without time interval
3410 // modification.
3411 /* while(tab){
3412 if(mw_data->window_width){
3413 time_span = LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context)->Time_Span ;
3414 time_win = tab->time_window;
3415 ratio = width / mw_data->window_width;
3416 tab->time_window.time_width = ltt_time_mul(time_win.time_width,ratio);
3417 time = ltt_time_sub(time_span->endTime, time_win.start_time);
3418 if(ltt_time_compare(time, tab->time_window.time_width) < 0){
3419 tab->time_window.time_width = time;
3420 }
3421 }
3422 tab = tab->next;
3423 }
3424
3425 mw_data->window_width = (int)width;
3426 */
3427 return FALSE;
3428 }
3429
3430 /* Set current tab
3431 */
3432
3433 void
3434 on_MNotebook_switch_page (GtkNotebook *notebook,
3435 GtkNotebookPage *page,
3436 guint page_num,
3437 gpointer user_data)
3438 {
3439
3440 }
3441
3442
3443 void time_change_manager (Tab *tab,
3444 TimeWindow new_time_window)
3445 {
3446 /* Only one source of time change */
3447 if(tab->time_manager_lock == TRUE) return;
3448
3449 tab->time_manager_lock = TRUE;
3450
3451 LttvTracesetContext *tsc = LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context);
3452 TimeInterval time_span = tsc->time_span;
3453 LttTime start_time = new_time_window.start_time;
3454 LttTime end_time = new_time_window.end_time;
3455 LttTime time_width = new_time_window.time_width;
3456
3457 g_assert(ltt_time_compare(start_time, end_time) < 0);
3458
3459 /* Set scrollbar */
3460 GtkAdjustment *adjustment = gtk_range_get_adjustment(GTK_RANGE(tab->scrollbar));
3461 LttTime upper = ltt_time_sub(time_span.end_time, time_span.start_time);
3462 #if 0
3463 gtk_range_set_increments(GTK_RANGE(tab->scrollbar),
3464 ltt_time_to_double(new_time_window.time_width)
3465 / SCROLL_STEP_PER_PAGE
3466 * NANOSECONDS_PER_SECOND, /* step increment */
3467 ltt_time_to_double(new_time_window.time_width)
3468 * NANOSECONDS_PER_SECOND); /* page increment */
3469 gtk_range_set_range(GTK_RANGE(tab->scrollbar),
3470 0.0, /* lower */
3471 ltt_time_to_double(upper)
3472 * NANOSECONDS_PER_SECOND); /* upper */
3473 #endif //0
3474 g_object_set(G_OBJECT(adjustment),
3475 "lower",
3476 0.0, /* lower */
3477 "upper",
3478 ltt_time_to_double(upper), /* upper */
3479 "step_increment",
3480 new_time_window.time_width_double
3481 / SCROLL_STEP_PER_PAGE, /* step increment */
3482 "page_increment",
3483 new_time_window.time_width_double,
3484 /* page increment */
3485 "page_size",
3486 new_time_window.time_width_double, /* page size */
3487 NULL);
3488 gtk_adjustment_changed(adjustment);
3489
3490 // g_object_set(G_OBJECT(adjustment),
3491 // "value",
3492 // ltt_time_to_double(
3493 // ltt_time_sub(start_time, time_span.start_time))
3494 // , /* value */
3495 // NULL);
3496 //gtk_adjustment_value_changed(adjustment);
3497 gtk_range_set_value(GTK_RANGE(tab->scrollbar),
3498 ltt_time_to_double(
3499 ltt_time_sub(start_time, time_span.start_time)) /* value */);
3500
3501 /* set the time bar. */
3502 /* start seconds */
3503 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab->MEntry1),
3504 (double)time_span.start_time.tv_sec,
3505 (double)time_span.end_time.tv_sec);
3506 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab->MEntry1),
3507 (double)start_time.tv_sec);
3508
3509 /* start nanoseconds */
3510 if(start_time.tv_sec == time_span.start_time.tv_sec) {
3511 /* can be both beginning and end at the same time. */
3512 if(start_time.tv_sec == time_span.end_time.tv_sec) {
3513 /* If we are at the end, max nsec to end.. -1 (not zero length) */
3514 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab->MEntry2),
3515 (double)time_span.start_time.tv_nsec,
3516 (double)time_span.end_time.tv_nsec-1);
3517 } else {
3518 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab->MEntry2),
3519 (double)time_span.start_time.tv_nsec,
3520 (double)NANOSECONDS_PER_SECOND-1);
3521 }
3522 } else if(start_time.tv_sec == time_span.end_time.tv_sec) {
3523 /* If we are at the end, max nsec to end.. -1 (not zero length) */
3524 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab->MEntry2),
3525 0.0,
3526 (double)time_span.end_time.tv_nsec-1);
3527 } else /* anywhere else */
3528 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab->MEntry2),
3529 0.0,
3530 (double)NANOSECONDS_PER_SECOND-1);
3531 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab->MEntry2),
3532 (double)start_time.tv_nsec);
3533
3534 /* end seconds */
3535 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab->MEntry3),
3536 (double)time_span.start_time.tv_sec,
3537 (double)time_span.end_time.tv_sec);
3538 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab->MEntry3),
3539 (double)end_time.tv_sec);
3540
3541 /* end nanoseconds */
3542 if(end_time.tv_sec == time_span.start_time.tv_sec) {
3543 /* can be both beginning and end at the same time. */
3544 if(end_time.tv_sec == time_span.end_time.tv_sec) {
3545 /* If we are at the end, max nsec to end.. */
3546 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab->MEntry4),
3547 (double)time_span.start_time.tv_nsec+1,
3548 (double)time_span.end_time.tv_nsec);
3549 } else {
3550 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab->MEntry4),
3551 (double)time_span.start_time.tv_nsec+1,
3552 (double)NANOSECONDS_PER_SECOND-1);
3553 }
3554 }
3555 else if(end_time.tv_sec == time_span.end_time.tv_sec) {
3556 /* If we are at the end, max nsec to end.. */
3557 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab->MEntry4),
3558 0.0,
3559 (double)time_span.end_time.tv_nsec);
3560 }
3561 else /* anywhere else */
3562 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab->MEntry4),
3563 0.0,
3564 (double)NANOSECONDS_PER_SECOND-1);
3565 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab->MEntry4),
3566 (double)end_time.tv_nsec);
3567
3568 /* width seconds */
3569 if(time_width.tv_nsec == 0) {
3570 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab->MEntry7),
3571 (double)1,
3572 (double)upper.tv_sec);
3573 } else {
3574 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab->MEntry7),
3575 (double)0,
3576 (double)upper.tv_sec);
3577 }
3578 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab->MEntry7),
3579 (double)time_width.tv_sec);
3580
3581 /* width nanoseconds */
3582 if(time_width.tv_sec == upper.tv_sec) {
3583 if(time_width.tv_sec == 0) {
3584 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab->MEntry8),
3585 (double)1,
3586 (double)upper.tv_nsec);
3587 } else {
3588 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab->MEntry8),
3589 (double)0,
3590 (double)upper.tv_nsec);
3591 }
3592 }
3593 else if(time_width.tv_sec == 0) {
3594 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab->MEntry8),
3595 1.0,
3596 (double)upper.tv_nsec);
3597 }
3598 else /* anywhere else */
3599 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab->MEntry8),
3600 0.0,
3601 (double)NANOSECONDS_PER_SECOND-1);
3602 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab->MEntry8),
3603 (double)time_width.tv_nsec);
3604
3605 /* call viewer hooks for new time window */
3606 set_time_window(tab, &new_time_window);
3607
3608 tab->time_manager_lock = FALSE;
3609 }
3610
3611
3612 /* value changed for frame start s
3613 *
3614 * Check time span : if ns is out of range, clip it the nearest good value.
3615 */
3616 void
3617 on_MEntry1_value_changed (GtkSpinButton *spinbutton,
3618 gpointer user_data)
3619 {
3620 Tab *tab =(Tab *)user_data;
3621 LttvTracesetContext * tsc =
3622 LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context);
3623 TimeInterval time_span = tsc->time_span;
3624 gint value = gtk_spin_button_get_value_as_int(spinbutton);
3625
3626 TimeWindow new_time_window = tab->time_window;
3627
3628 LttTime end_time = new_time_window.end_time;
3629
3630 new_time_window.start_time.tv_sec = value;
3631
3632 /* start nanoseconds */
3633 if(new_time_window.start_time.tv_sec == time_span.start_time.tv_sec) {
3634 if(new_time_window.start_time.tv_sec == time_span.end_time.tv_sec) {
3635 if(new_time_window.start_time.tv_nsec > time_span.end_time.tv_nsec)
3636 new_time_window.start_time.tv_nsec = time_span.end_time.tv_nsec-1;
3637 if(new_time_window.start_time.tv_nsec < time_span.start_time.tv_nsec)
3638 new_time_window.start_time.tv_nsec = time_span.start_time.tv_nsec;
3639 } else {
3640 if(new_time_window.start_time.tv_nsec < time_span.start_time.tv_nsec)
3641 new_time_window.start_time.tv_nsec = time_span.start_time.tv_nsec;
3642 }
3643 }
3644 else if(new_time_window.start_time.tv_sec == time_span.end_time.tv_sec) {
3645 if(new_time_window.start_time.tv_nsec > time_span.end_time.tv_nsec)
3646 new_time_window.start_time.tv_nsec = time_span.end_time.tv_nsec-1;
3647 }
3648
3649 if(ltt_time_compare(new_time_window.start_time, end_time) >= 0) {
3650 /* Then, we must push back end time : keep the same time width
3651 * if possible, else end traceset time */
3652 end_time = LTT_TIME_MIN(ltt_time_add(new_time_window.start_time,
3653 new_time_window.time_width),
3654 time_span.end_time);
3655 }
3656
3657 /* Fix the time width to fit start time and end time */
3658 new_time_window.time_width = ltt_time_sub(end_time,
3659 new_time_window.start_time);
3660 new_time_window.time_width_double =
3661 ltt_time_to_double(new_time_window.time_width);
3662
3663 new_time_window.end_time = end_time;
3664
3665 time_change_manager(tab, new_time_window);
3666
3667 }
3668
3669 void
3670 on_MEntry2_value_changed (GtkSpinButton *spinbutton,
3671 gpointer user_data)
3672 {
3673 Tab *tab =(Tab *)user_data;
3674 LttvTracesetContext * tsc =
3675 LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context);
3676 TimeInterval time_span = tsc->time_span;
3677 gint value = gtk_spin_button_get_value_as_int(spinbutton);
3678
3679 TimeWindow new_time_window = tab->time_window;
3680
3681 LttTime end_time = new_time_window.end_time;
3682
3683 new_time_window.start_time.tv_nsec = value;
3684
3685 if(ltt_time_compare(new_time_window.start_time, end_time) >= 0) {
3686 /* Then, we must push back end time : keep the same time width
3687 * if possible, else end traceset time */
3688 end_time = LTT_TIME_MIN(ltt_time_add(new_time_window.start_time,
3689 new_time_window.time_width),
3690 time_span.end_time);
3691 }
3692
3693 /* Fix the time width to fit start time and end time */
3694 new_time_window.time_width = ltt_time_sub(end_time,
3695 new_time_window.start_time);
3696 new_time_window.time_width_double =
3697 ltt_time_to_double(new_time_window.time_width);
3698
3699 new_time_window.end_time = end_time;
3700
3701 time_change_manager(tab, new_time_window);
3702
3703 }
3704
3705 void
3706 on_MEntry3_value_changed (GtkSpinButton *spinbutton,
3707 gpointer user_data)
3708 {
3709 Tab *tab =(Tab *)user_data;
3710 LttvTracesetContext * tsc =
3711 LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context);
3712 TimeInterval time_span = tsc->time_span;
3713 gint value = gtk_spin_button_get_value_as_int(spinbutton);
3714
3715 TimeWindow new_time_window = tab->time_window;
3716
3717 LttTime end_time = new_time_window.end_time;
3718
3719 end_time.tv_sec = value;
3720
3721 /* end nanoseconds */
3722 if(end_time.tv_sec == time_span.start_time.tv_sec) {
3723 if(end_time.tv_sec == time_span.end_time.tv_sec) {
3724 if(end_time.tv_nsec > time_span.end_time.tv_nsec)
3725 end_time.tv_nsec = time_span.end_time.tv_nsec;
3726 if(end_time.tv_nsec < time_span.start_time.tv_nsec)
3727 end_time.tv_nsec = time_span.start_time.tv_nsec+1;
3728 } else {
3729 if(end_time.tv_nsec < time_span.start_time.tv_nsec)
3730 end_time.tv_nsec = time_span.start_time.tv_nsec+1;
3731 }
3732 }
3733 else if(end_time.tv_sec == time_span.end_time.tv_sec) {
3734 if(end_time.tv_nsec > time_span.end_time.tv_nsec)
3735 end_time.tv_nsec = time_span.end_time.tv_nsec;
3736 }
3737
3738 if(ltt_time_compare(new_time_window.start_time, end_time) >= 0) {
3739 /* Then, we must push front start time : keep the same time width
3740 * if possible, else end traceset time */
3741 new_time_window.start_time = LTT_TIME_MAX(
3742 ltt_time_sub(end_time,
3743 new_time_window.time_width),
3744 time_span.start_time);
3745 }
3746
3747 /* Fix the time width to fit start time and end time */
3748 new_time_window.time_width = ltt_time_sub(end_time,
3749 new_time_window.start_time);
3750 new_time_window.time_width_double =
3751 ltt_time_to_double(new_time_window.time_width);
3752
3753 new_time_window.end_time = end_time;
3754
3755 time_change_manager(tab, new_time_window);
3756
3757 }
3758
3759 void
3760 on_MEntry4_value_changed (GtkSpinButton *spinbutton,
3761 gpointer user_data)
3762 {
3763 Tab *tab =(Tab *)user_data;
3764 LttvTracesetContext * tsc =
3765 LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context);
3766 TimeInterval time_span = tsc->time_span;
3767 gint value = gtk_spin_button_get_value_as_int(spinbutton);
3768
3769 TimeWindow new_time_window = tab->time_window;
3770
3771 LttTime end_time = new_time_window.end_time;
3772
3773 end_time.tv_nsec = value;
3774
3775 if(ltt_time_compare(new_time_window.start_time, end_time) >= 0) {
3776 /* Then, we must push front start time : keep the same time width
3777 * if possible, else end traceset time */
3778 new_time_window.start_time = LTT_TIME_MAX(
3779 ltt_time_sub(end_time,
3780 new_time_window.time_width),
3781 time_span.start_time);
3782 }
3783
3784 /* Fix the time width to fit start time and end time */
3785 new_time_window.time_width = ltt_time_sub(end_time,
3786 new_time_window.start_time);
3787 new_time_window.time_width_double =
3788 ltt_time_to_double(new_time_window.time_width);
3789 new_time_window.end_time = end_time;
3790
3791 time_change_manager(tab, new_time_window);
3792
3793 }
3794
3795 /* value changed for time frame interval s
3796 *
3797 * Check time span : if ns is out of range, clip it the nearest good value.
3798 */
3799 void
3800 on_MEntry7_value_changed (GtkSpinButton *spinbutton,
3801 gpointer user_data)
3802 {
3803 Tab *tab =(Tab *)user_data;
3804 LttvTracesetContext * tsc =
3805 LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context);
3806 TimeInterval time_span = tsc->time_span;
3807 gint value = gtk_spin_button_get_value_as_int(spinbutton);
3808 LttTime current_time, time_delta;
3809 TimeWindow new_time_window = tab->time_window;
3810 current_time = tab->current_time;
3811
3812 time_delta = ltt_time_sub(time_span.end_time,time_span.start_time);
3813 new_time_window.time_width.tv_sec = value;
3814 new_time_window.time_width_double =
3815 ltt_time_to_double(new_time_window.time_width);
3816 if(ltt_time_compare(new_time_window.time_width,time_delta) > 0)
3817 { /* Case where zoom out is bigger than trace length */
3818 new_time_window.start_time = time_span.start_time;
3819 new_time_window.time_width = time_delta;
3820 new_time_window.time_width_double = ltt_time_to_double(time_delta);
3821 new_time_window.end_time = ltt_time_add(new_time_window.start_time,
3822 new_time_window.time_width) ;
3823 }
3824 else
3825 {
3826 /* Center the image on the current time */
3827 new_time_window.start_time =
3828 ltt_time_sub(current_time,
3829 ltt_time_from_double(new_time_window.time_width_double/2.0));
3830 new_time_window.end_time = ltt_time_add(new_time_window.start_time,
3831 new_time_window.time_width) ;
3832 /* If on borders, don't fall off */
3833 if(ltt_time_compare(new_time_window.start_time, time_span.start_time) <0
3834 || ltt_time_compare(new_time_window.start_time, time_span.end_time) >0)
3835 {
3836 new_time_window.start_time = time_span.start_time;
3837 new_time_window.end_time = ltt_time_add(new_time_window.start_time,
3838 new_time_window.time_width) ;
3839 }
3840 else
3841 {
3842 if(ltt_time_compare(new_time_window.end_time,
3843 time_span.end_time) > 0
3844 || ltt_time_compare(new_time_window.end_time,
3845 time_span.start_time) < 0)
3846 {
3847 new_time_window.start_time =
3848 ltt_time_sub(time_span.end_time, new_time_window.time_width);
3849
3850 new_time_window.end_time = ltt_time_add(new_time_window.start_time,
3851 new_time_window.time_width) ;
3852 }
3853 }
3854
3855 }
3856
3857 if(ltt_time_compare(new_time_window.time_width, ltt_time_zero) == 0) {
3858 g_warning("Zoom more than 1 ns impossible");
3859 } else {
3860 time_change_manager(tab, new_time_window);
3861 }
3862 }
3863
3864 void
3865 on_MEntry8_value_changed (GtkSpinButton *spinbutton,
3866 gpointer user_data)
3867 {
3868 Tab *tab =(Tab *)user_data;
3869 LttvTracesetContext * tsc =
3870 LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context);
3871 TimeInterval time_span = tsc->time_span;
3872 gint value = gtk_spin_button_get_value_as_int(spinbutton);
3873 LttTime current_time, time_delta;
3874 TimeWindow new_time_window = tab->time_window;
3875 current_time = tab->current_time;
3876
3877 time_delta = ltt_time_sub(time_span.end_time,time_span.start_time);
3878 new_time_window.time_width.tv_nsec = value;
3879 new_time_window.time_width_double =
3880 ltt_time_to_double(new_time_window.time_width);
3881 if(ltt_time_compare(new_time_window.time_width,time_delta) > 0)
3882 { /* Case where zoom out is bigger than trace length */
3883 new_time_window.start_time = time_span.start_time;
3884 new_time_window.time_width = time_delta;
3885 new_time_window.time_width_double = ltt_time_to_double(time_delta);
3886 new_time_window.end_time = ltt_time_add(new_time_window.start_time,
3887 new_time_window.time_width) ;
3888 }
3889 else
3890 {
3891 /* Center the image on the current time */
3892 new_time_window.start_time =
3893 ltt_time_sub(current_time,
3894 ltt_time_from_double(new_time_window.time_width_double/2.0));
3895 new_time_window.end_time = ltt_time_add(new_time_window.start_time,
3896 new_time_window.time_width) ;
3897 /* If on borders, don't fall off */
3898 if(ltt_time_compare(new_time_window.start_time, time_span.start_time) <0
3899 || ltt_time_compare(new_time_window.start_time, time_span.end_time) >0)
3900 {
3901 new_time_window.start_time = time_span.start_time;
3902 new_time_window.end_time = ltt_time_add(new_time_window.start_time,
3903 new_time_window.time_width) ;
3904 }
3905 else
3906 {
3907 if(ltt_time_compare(new_time_window.end_time,
3908 time_span.end_time) > 0
3909 || ltt_time_compare(new_time_window.end_time,
3910 time_span.start_time) < 0)
3911 {
3912 new_time_window.start_time =
3913 ltt_time_sub(time_span.end_time, new_time_window.time_width);
3914
3915 new_time_window.end_time = ltt_time_add(new_time_window.start_time,
3916 new_time_window.time_width) ;
3917 }
3918 }
3919
3920 }
3921
3922 if(ltt_time_compare(new_time_window.time_width, ltt_time_zero) == 0) {
3923 g_warning("Zoom more than 1 ns impossible");
3924 } else {
3925 time_change_manager(tab, new_time_window);
3926 }
3927 }
3928
3929
3930
3931 void current_time_change_manager (Tab *tab,
3932 LttTime new_current_time)
3933 {
3934 /* Only one source of time change */
3935 if(tab->current_time_manager_lock == TRUE) return;
3936
3937 tab->current_time_manager_lock = TRUE;
3938
3939 LttvTracesetContext *tsc = LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context);
3940 TimeInterval time_span = tsc->time_span;
3941
3942 /* current seconds */
3943 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab->MEntry5),
3944 (double)time_span.start_time.tv_sec,
3945 (double)time_span.end_time.tv_sec);
3946 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab->MEntry5),
3947 (double)new_current_time.tv_sec);
3948
3949
3950 /* start nanoseconds */
3951 if(new_current_time.tv_sec == time_span.start_time.tv_sec) {
3952 /* can be both beginning and end at the same time. */
3953 if(new_current_time.tv_sec == time_span.end_time.tv_sec) {
3954 /* If we are at the end, max nsec to end.. */
3955 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab->MEntry6),
3956 (double)time_span.start_time.tv_nsec,
3957 (double)time_span.end_time.tv_nsec);
3958 } else {
3959 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab->MEntry6),
3960 (double)time_span.start_time.tv_nsec,
3961 (double)NANOSECONDS_PER_SECOND-1);
3962 }
3963 } else if(new_current_time.tv_sec == time_span.end_time.tv_sec) {
3964 /* If we are at the end, max nsec to end.. */
3965 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab->MEntry6),
3966 0.0,
3967 (double)time_span.end_time.tv_nsec);
3968 } else /* anywhere else */
3969 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab->MEntry6),
3970 0.0,
3971 (double)NANOSECONDS_PER_SECOND-1);
3972
3973 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab->MEntry6),
3974 (double)new_current_time.tv_nsec);
3975
3976 set_current_time(tab, &new_current_time);
3977
3978 tab->current_time_manager_lock = FALSE;
3979 }
3980
3981 void current_position_change_manager(Tab *tab,
3982 LttvTracesetContextPosition *pos)
3983 {
3984 LttvTracesetContext *tsc =
3985 LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context);
3986 TimeInterval time_span = tsc->time_span;
3987 int retval;
3988
3989 retval= lttv_process_traceset_seek_position(tsc, pos);
3990 g_assert_cmpint(retval, ==, 0);
3991 LttTime new_time = lttv_traceset_context_position_get_time(pos);
3992 /* Put the context in a state coherent position */
3993 lttv_state_traceset_seek_time_closest((LttvTracesetState*)tsc, ltt_time_zero);
3994
3995 current_time_change_manager(tab, new_time);
3996
3997 set_current_position(tab, pos);
3998 }
3999
4000
4001 void
4002 on_MEntry5_value_changed (GtkSpinButton *spinbutton,
4003 gpointer user_data)
4004 {
4005 Tab *tab = (Tab*)user_data;
4006 LttvTracesetContext * tsc =
4007 LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context);
4008 TimeInterval time_span = tsc->time_span;
4009 gint value = gtk_spin_button_get_value_as_int(spinbutton);
4010 LttTime new_current_time = tab->current_time;
4011 new_current_time.tv_sec = value;
4012
4013 /* current nanoseconds */
4014 if(new_current_time.tv_sec == time_span.start_time.tv_sec) {
4015 if(new_current_time.tv_sec == time_span.end_time.tv_sec) {
4016 if(new_current_time.tv_nsec > time_span.end_time.tv_nsec)
4017 new_current_time.tv_nsec = time_span.end_time.tv_nsec;
4018 if(new_current_time.tv_nsec < time_span.start_time.tv_nsec)
4019 new_current_time.tv_nsec = time_span.start_time.tv_nsec;
4020 } else {
4021 if(new_current_time.tv_nsec < time_span.start_time.tv_nsec)
4022 new_current_time.tv_nsec = time_span.start_time.tv_nsec;
4023 }
4024 }
4025 else if(new_current_time.tv_sec == time_span.end_time.tv_sec) {
4026 if(new_current_time.tv_nsec > time_span.end_time.tv_nsec)
4027 new_current_time.tv_nsec = time_span.end_time.tv_nsec;
4028 }
4029
4030 current_time_change_manager(tab, new_current_time);
4031 }
4032
4033 void
4034 on_MEntry6_value_changed (GtkSpinButton *spinbutton,
4035 gpointer user_data)
4036 {
4037 Tab *tab = (Tab*)user_data;
4038 gint value = gtk_spin_button_get_value_as_int(spinbutton);
4039 LttTime new_current_time = tab->current_time;
4040 new_current_time.tv_nsec = value;
4041
4042 current_time_change_manager(tab, new_current_time);
4043 }
4044
4045
4046 void scroll_value_changed_cb(GtkWidget *scrollbar,
4047 gpointer user_data)
4048 {
4049 Tab *tab = (Tab *)user_data;
4050 TimeWindow new_time_window;
4051 LttTime time;
4052 GtkAdjustment *adjust = gtk_range_get_adjustment(GTK_RANGE(scrollbar));
4053 gdouble value = gtk_adjustment_get_value(adjust);
4054 // gdouble upper, lower, ratio, page_size;
4055 gdouble page_size;
4056 LttvTracesetContext * tsc =
4057 LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context);
4058 TimeInterval time_span = tsc->time_span;
4059
4060 time = ltt_time_add(ltt_time_from_double(value),
4061 time_span.start_time);
4062
4063 new_time_window.start_time = time;
4064
4065 page_size = adjust->page_size;
4066
4067 new_time_window.time_width =
4068 ltt_time_from_double(page_size);
4069
4070 new_time_window.time_width_double =
4071 page_size;
4072
4073 new_time_window.end_time = ltt_time_add(new_time_window.start_time,
4074 new_time_window.time_width);
4075
4076
4077 time_change_manager(tab, new_time_window);
4078 #if 0
4079 //time_window = tab->time_window;
4080
4081 lower = adjust->lower;
4082 upper = adjust->upper;
4083 ratio = (value - lower) / (upper - lower);
4084 g_info("lower %lu, upper %lu, value %lu, ratio %lu", lower, upper, value, ratio);
4085
4086 //time = ltt_time_sub(time_span->end_time, time_span->start_time);
4087 //time = ltt_time_mul(time, (float)ratio);
4088 //time = ltt_time_add(time_span->start_time, time);
4089 time = ltt_time_add(ltt_time_from_double(value),
4090 time_span.start_time);
4091
4092 time_window.start_time = time;
4093
4094 page_size = adjust->page_size;
4095
4096 time_window.time_width =
4097 ltt_time_from_double(page_size);
4098 //time = ltt_time_sub(time_span.end_time, time);
4099 //if(ltt_time_compare(time,time_window.time_width) < 0){
4100 // time_window.time_width = time;
4101 //}
4102
4103 /* call viewer hooks for new time window */
4104 set_time_window(tab, &time_window);
4105 #endif //0
4106 }
4107
4108
4109 /* Display a dialogue showing all eventtypes and traces, let user to select the interested
4110 * eventtypes, tracefiles and traces (filter)
4111 */
4112
4113 /* Select a trace which will be removed from traceset
4114 */
4115
4116 char * get_remove_trace(MainWindow *mw_data,
4117 char ** all_trace_name, int nb_trace)
4118 {
4119 return get_selection(mw_data, all_trace_name, nb_trace,
4120 "Select a trace", "Trace pathname");
4121 }
4122
4123
4124 /* Select a module which will be loaded
4125 */
4126
4127 char * get_load_module(MainWindow *mw_data,
4128 char ** load_module_name, int nb_module)
4129 {
4130 return get_selection(mw_data, load_module_name, nb_module,
4131 "Select a module to load", "Module name");
4132 }
4133
4134
4135
4136
4137 /* Select a module which will be unloaded
4138 */
4139
4140 char * get_unload_module(MainWindow *mw_data,
4141 char ** loaded_module_name, int nb_module)
4142 {
4143 return get_selection(mw_data, loaded_module_name, nb_module,
4144 "Select a module to unload", "Module name");
4145 }
4146
4147
4148 /* Display a dialogue which shows all selectable items, let user to
4149 * select one of them
4150 */
4151
4152 char * get_selection(MainWindow *mw_data,
4153 char ** loaded_module_name, int nb_module,
4154 char *title, char * column_title)
4155 {
4156 GtkWidget * dialogue;
4157 GtkWidget * scroll_win;
4158 GtkWidget * tree;
4159 GtkListStore * store;
4160 GtkTreeViewColumn * column;
4161 GtkCellRenderer * renderer;
4162 GtkTreeSelection * select;
4163 GtkTreeIter iter;
4164 gint id, i;
4165 char * unload_module_name = NULL;
4166
4167 dialogue = gtk_dialog_new_with_buttons(title,
4168 NULL,
4169 GTK_DIALOG_MODAL,
4170 GTK_STOCK_OK,GTK_RESPONSE_ACCEPT,
4171 GTK_STOCK_CANCEL,GTK_RESPONSE_REJECT,
4172 NULL);
4173 gtk_window_set_default_size((GtkWindow*)dialogue, 500, 200);
4174 gtk_window_set_transient_for(GTK_WINDOW(dialogue),
4175 GTK_WINDOW(mw_data->mwindow));
4176
4177 scroll_win = gtk_scrolled_window_new (NULL, NULL);
4178 gtk_widget_show ( scroll_win);
4179 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll_win),
4180 GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
4181
4182 store = gtk_list_store_new (N_COLUMNS,G_TYPE_STRING);
4183 tree = gtk_tree_view_new_with_model(GTK_TREE_MODEL (store));
4184 gtk_widget_show ( tree);
4185 g_object_unref (G_OBJECT (store));
4186
4187 renderer = gtk_cell_renderer_text_new ();
4188 column = gtk_tree_view_column_new_with_attributes (column_title,
4189 renderer,
4190 "text", MODULE_COLUMN,
4191 NULL);
4192 gtk_tree_view_column_set_alignment (column, 0.5);
4193 gtk_tree_view_column_set_fixed_width (column, 150);
4194 gtk_tree_view_append_column (GTK_TREE_VIEW (tree), column);
4195
4196 select = gtk_tree_view_get_selection (GTK_TREE_VIEW (tree));
4197 gtk_tree_selection_set_mode (select, GTK_SELECTION_SINGLE);
4198
4199 gtk_container_add (GTK_CONTAINER (scroll_win), tree);
4200
4201 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialogue)->vbox), scroll_win,TRUE, TRUE,0);
4202
4203 for(i=0;i<nb_module;i++){
4204 gtk_list_store_append (store, &iter);
4205 gtk_list_store_set (store, &iter, MODULE_COLUMN,loaded_module_name[i],-1);
4206 }
4207
4208 id = gtk_dialog_run(GTK_DIALOG(dialogue));
4209 GtkTreeModel **store_model = (GtkTreeModel**)&store;
4210 switch(id){
4211 case GTK_RESPONSE_ACCEPT:
4212 case GTK_RESPONSE_OK:
4213 if (gtk_tree_selection_get_selected (select, store_model, &iter)){
4214 gtk_tree_model_get ((GtkTreeModel*)store, &iter, MODULE_COLUMN, &unload_module_name, -1);
4215 }
4216 case GTK_RESPONSE_REJECT:
4217 case GTK_RESPONSE_CANCEL:
4218 default:
4219 gtk_widget_destroy(dialogue);
4220 break;
4221 }
4222
4223 return unload_module_name;
4224 }
4225
4226
4227 /* Insert all menu entry and tool buttons into this main window
4228 * for modules.
4229 *
4230 */
4231
4232 void add_all_menu_toolbar_constructors(MainWindow * mw, gpointer user_data)
4233 {
4234 guint i;
4235 GdkPixbuf *pixbuf;
4236 lttvwindow_viewer_constructor constructor;
4237 LttvMenus * global_menu, * instance_menu;
4238 LttvToolbars * global_toolbar, * instance_toolbar;
4239 LttvMenuClosure *menu_item;
4240 LttvToolbarClosure *toolbar_item;
4241 LttvAttributeValue value;
4242 LttvIAttribute *global_attributes = LTTV_IATTRIBUTE(lttv_global_attributes());
4243 LttvIAttribute *attributes = mw->attributes;
4244 GtkWidget * tool_menu_title_menu, *new_widget, *pixmap;
4245 gboolean retval;
4246
4247 retval= lttv_iattribute_find_by_path(global_attributes, "viewers/menu",
4248 LTTV_POINTER, &value);
4249 g_assert(retval);
4250 if(*(value.v_pointer) == NULL)
4251 *(value.v_pointer) = lttv_menus_new();
4252 global_menu = (LttvMenus*)*(value.v_pointer);
4253
4254 retval= lttv_iattribute_find_by_path(attributes, "viewers/menu",
4255 LTTV_POINTER, &value);
4256 g_assert(retval);
4257 if(*(value.v_pointer) == NULL)
4258 *(value.v_pointer) = lttv_menus_new();
4259 instance_menu = (LttvMenus*)*(value.v_pointer);
4260
4261 retval= lttv_iattribute_find_by_path(global_attributes, "viewers/toolbar",
4262 LTTV_POINTER, &value);
4263 g_assert(retval);
4264 if(*(value.v_pointer) == NULL)
4265 *(value.v_pointer) = lttv_toolbars_new();
4266 global_toolbar = (LttvToolbars*)*(value.v_pointer);
4267
4268 retval= lttv_iattribute_find_by_path(attributes, "viewers/toolbar",
4269 LTTV_POINTER, &value);
4270 g_assert(retval);
4271 if(*(value.v_pointer) == NULL)
4272 *(value.v_pointer) = lttv_toolbars_new();
4273 instance_toolbar = (LttvToolbars*)*(value.v_pointer);
4274
4275 /* Add missing menu entries to window instance */
4276 for(i=0;i<global_menu->len;i++) {
4277 menu_item = &g_array_index(global_menu, LttvMenuClosure, i);
4278
4279 //add menu_item to window instance;
4280 constructor = menu_item->con;
4281 tool_menu_title_menu = lookup_widget(mw->mwindow,"ToolMenuTitle_menu");
4282 new_widget =
4283 gtk_menu_item_new_with_mnemonic (menu_item->menu_text);
4284 gtk_container_add (GTK_CONTAINER (tool_menu_title_menu),
4285 new_widget);
4286 g_signal_connect ((gpointer) new_widget, "activate",
4287 G_CALLBACK (insert_viewer_wrap),
4288 constructor);
4289 gtk_widget_show (new_widget);
4290 lttv_menus_add(instance_menu, menu_item->con,
4291 menu_item->menu_path,
4292 menu_item->menu_text,
4293 new_widget);
4294
4295 }
4296
4297 /* Add missing toolbar entries to window instance */
4298 for(i=0;i<global_toolbar->len;i++) {
4299 toolbar_item = &g_array_index(global_toolbar, LttvToolbarClosure, i);
4300
4301 //add toolbar_item to window instance;
4302 constructor = toolbar_item->con;
4303 tool_menu_title_menu = lookup_widget(mw->mwindow,"MToolbar1");
4304 pixbuf = gdk_pixbuf_new_from_xpm_data((const char**)toolbar_item->pixmap);
4305 pixmap = gtk_image_new_from_pixbuf(pixbuf);
4306 new_widget =
4307 gtk_toolbar_append_element (GTK_TOOLBAR (tool_menu_title_menu),
4308 GTK_TOOLBAR_CHILD_BUTTON,
4309 NULL,
4310 "",
4311 toolbar_item->tooltip, NULL,
4312 pixmap, NULL, NULL);
4313 gtk_label_set_use_underline(
4314 GTK_LABEL (((GtkToolbarChild*) (
4315 g_list_last (GTK_TOOLBAR
4316 (tool_menu_title_menu)->children)->data))->label),
4317 TRUE);
4318 gtk_container_set_border_width (GTK_CONTAINER (new_widget), 1);
4319 g_signal_connect ((gpointer) new_widget,
4320 "clicked",
4321 G_CALLBACK (insert_viewer_wrap),
4322 constructor);
4323 gtk_widget_show (new_widget);
4324
4325 lttv_toolbars_add(instance_toolbar, toolbar_item->con,
4326 toolbar_item->tooltip,
4327 toolbar_item->pixmap,
4328 new_widget);
4329
4330 }
4331
4332 }
4333
4334
4335 /* Create a main window
4336 */
4337
4338 MainWindow *construct_main_window(MainWindow * parent)
4339 {
4340 gboolean retval;
4341
4342 g_debug("construct_main_window()");
4343 GtkWidget * new_window; /* New generated main window */
4344 MainWindow * new_m_window;/* New main window structure */
4345 GtkNotebook * notebook;
4346 LttvIAttribute *attributes =
4347 LTTV_IATTRIBUTE(g_object_new(LTTV_ATTRIBUTE_TYPE, NULL));
4348 LttvAttributeValue value;
4349 Tab *new_tab;
4350
4351 new_m_window = g_new(MainWindow, 1);
4352
4353 // Add the object's information to the module's array
4354 g_main_window_list = g_slist_append(g_main_window_list, new_m_window);
4355
4356 new_window = create_MWindow();
4357 gtk_widget_show (new_window);
4358
4359 new_m_window->mwindow = new_window;
4360 new_m_window->attributes = attributes;
4361
4362 retval= lttv_iattribute_find_by_path(attributes, "viewers/menu",
4363 LTTV_POINTER, &value);
4364 g_assert(retval);
4365 *(value.v_pointer) = lttv_menus_new();
4366
4367 retval= lttv_iattribute_find_by_path(attributes, "viewers/toolbar",
4368 LTTV_POINTER, &value);
4369 g_assert(retval);
4370 *(value.v_pointer) = lttv_toolbars_new();
4371
4372 add_all_menu_toolbar_constructors(new_m_window, NULL);
4373
4374 g_object_set_data_full(G_OBJECT(new_window),
4375 "main_window_data",
4376 (gpointer)new_m_window,
4377 (GDestroyNotify)g_free);
4378 //create a default tab
4379 notebook = (GtkNotebook *)lookup_widget(new_m_window->mwindow, "MNotebook");
4380 if(notebook == NULL){
4381 g_info("Notebook does not exist\n");
4382 /* FIXME : destroy partially created widgets */
4383 g_free(new_m_window);
4384 return NULL;
4385 }
4386 //gtk_notebook_popup_enable (GTK_NOTEBOOK(notebook));
4387 //for now there is no name field in LttvTraceset structure
4388 //Use "Traceset" as the label for the default tab
4389 if(parent) {
4390 GtkWidget * parent_notebook = lookup_widget(parent->mwindow, "MNotebook");
4391 GtkWidget *page = gtk_notebook_get_nth_page(GTK_NOTEBOOK(parent_notebook),
4392 gtk_notebook_get_current_page(GTK_NOTEBOOK(parent_notebook)));
4393 Tab *parent_tab;
4394
4395 if(!page) {
4396 parent_tab = NULL;
4397 } else {
4398 LttvPluginTab *ptab;
4399 ptab = (LttvPluginTab *)g_object_get_data(G_OBJECT(page), "Tab_Plugin");
4400 parent_tab = ptab->tab;
4401 }
4402 LttvPluginTab *ptab = g_object_new(LTTV_TYPE_PLUGIN_TAB, NULL);
4403 init_tab(ptab->tab,
4404 new_m_window, parent_tab, notebook, "Traceset");
4405 ptab->parent.top_widget = ptab->tab->top_widget;
4406 g_object_set_data_full(
4407 G_OBJECT(ptab->tab->vbox),
4408 "Tab_Plugin",
4409 ptab,
4410 (GDestroyNotify)tab_destructor);
4411 new_tab = ptab->tab;
4412 } else {
4413 LttvPluginTab *ptab = g_object_new(LTTV_TYPE_PLUGIN_TAB, NULL);
4414 init_tab(ptab->tab, new_m_window, NULL, notebook, "Traceset");
4415 ptab->parent.top_widget = ptab->tab->top_widget;
4416 g_object_set_data_full(
4417 G_OBJECT(ptab->tab->vbox),
4418 "Tab_Plugin",
4419 ptab,
4420 (GDestroyNotify)tab_destructor);
4421 new_tab = ptab->tab;
4422 }
4423
4424 /* Insert default viewers */
4425 {
4426 LttvAttributeType type;
4427 LttvAttributeName name;
4428 LttvAttributeValue value;
4429 LttvAttribute *attribute;
4430
4431 LttvIAttribute *attributes_global =
4432 LTTV_IATTRIBUTE(lttv_global_attributes());
4433
4434 attribute = LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
4435 LTTV_IATTRIBUTE(attributes_global),
4436 LTTV_VIEWER_CONSTRUCTORS));
4437 g_assert(attribute);
4438
4439 name = g_quark_from_string("guievents");
4440 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute),
4441 name, &value);
4442 if(type == LTTV_POINTER) {
4443 lttvwindow_viewer_constructor viewer_constructor =
4444 (lttvwindow_viewer_constructor)*value.v_pointer;
4445 insert_viewer(new_window, viewer_constructor);
4446 }
4447
4448 name = g_quark_from_string("guicontrolflow");
4449 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute),
4450 name, &value);
4451 if(type == LTTV_POINTER) {
4452 lttvwindow_viewer_constructor viewer_constructor =
4453 (lttvwindow_viewer_constructor)*value.v_pointer;
4454 insert_viewer(new_window, viewer_constructor);
4455 }
4456
4457 name = g_quark_from_string("guistatistics");
4458 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute),
4459 name, &value);
4460 if(type == LTTV_POINTER) {
4461 lttvwindow_viewer_constructor viewer_constructor =
4462 (lttvwindow_viewer_constructor)*value.v_pointer;
4463 insert_viewer(new_window, viewer_constructor);
4464 }
4465 }
4466
4467 g_info("There are now : %d windows\n",g_slist_length(g_main_window_list));
4468
4469 return new_m_window;
4470 }
4471
4472
4473 /* Free the memory occupied by a tab structure
4474 * destroy the tab
4475 */
4476
4477 void tab_destructor(LttvPluginTab * ptab)
4478 {
4479 int i, nb, ref_count;
4480 LttvTrace * trace;
4481 Tab *tab = ptab->tab;
4482
4483 gtk_object_destroy(GTK_OBJECT(tab->tooltips));
4484
4485 if(tab->attributes)
4486 g_object_unref(tab->attributes);
4487
4488 if(tab->interrupted_state)
4489 g_object_unref(tab->interrupted_state);
4490
4491
4492 if(tab->traceset_info->traceset_context != NULL){
4493 //remove state update hooks
4494 lttv_state_remove_event_hooks(
4495 (LttvTracesetState*)tab->traceset_info->
4496 traceset_context);
4497 lttv_context_fini(LTTV_TRACESET_CONTEXT(tab->traceset_info->
4498 traceset_context));
4499 g_object_unref(tab->traceset_info->traceset_context);
4500 }
4501 if(tab->traceset_info->traceset != NULL) {
4502 nb = lttv_traceset_number(tab->traceset_info->traceset);
4503 for(i = 0 ; i < nb ; i++) {
4504 trace = lttv_traceset_get(tab->traceset_info->traceset, i);
4505 ref_count = lttv_trace_get_ref_number(trace);
4506 if(ref_count <= 1){
4507 ltt_trace_close(lttv_trace(trace));
4508 }
4509 }
4510 }
4511 lttv_traceset_destroy(tab->traceset_info->traceset);
4512 /* Remove the idle events requests processing function of the tab */
4513 g_idle_remove_by_data(tab);
4514
4515 g_slist_free(tab->events_requests);
4516 g_free(tab->traceset_info);
4517 //g_free(tab);
4518 g_object_unref(ptab);
4519 }
4520
4521
4522 /* Create a tab and insert it into the current main window
4523 */
4524
4525 void init_tab(Tab *tab, MainWindow * mw, Tab *copy_tab,
4526 GtkNotebook * notebook, char * label)
4527 {
4528 GList * list;
4529 //Tab * tab;
4530 //LttvFilter *filter = NULL;
4531
4532 //create a new tab data structure
4533 //tab = g_new(Tab,1);
4534
4535 //construct and initialize the traceset_info
4536 tab->traceset_info = g_new(TracesetInfo,1);
4537
4538 if(copy_tab) {
4539 tab->traceset_info->traceset =
4540 lttv_traceset_copy(copy_tab->traceset_info->traceset);
4541
4542 /* Copy the previous tab's filter */
4543 /* We can clone the filter, as we copy the trace set also */
4544 /* The filter must always be in sync with the trace set */
4545 tab->filter = lttv_filter_clone(copy_tab->filter);
4546 } else {
4547 tab->traceset_info->traceset = lttv_traceset_new();
4548 tab->filter = NULL;
4549 }
4550 #ifdef DEBUG
4551 lttv_attribute_write_xml(
4552 lttv_traceset_attribute(tab->traceset_info->traceset),
4553 stdout,
4554 0, 4);
4555 fflush(stdout);
4556 #endif //DEBUG
4557
4558 tab->time_manager_lock = FALSE;
4559 tab->current_time_manager_lock = FALSE;
4560
4561 //FIXME copy not implemented in lower level
4562 tab->traceset_info->traceset_context =
4563 g_object_new(LTTV_TRACESET_STATS_TYPE, NULL);
4564 g_assert(tab->traceset_info->traceset_context != NULL);
4565 lttv_context_init(
4566 LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context),
4567 tab->traceset_info->traceset);
4568 //add state update hooks
4569 lttv_state_add_event_hooks(
4570 (LttvTracesetState*)tab->traceset_info->traceset_context);
4571
4572 //determine the current_time and time_window of the tab
4573 #if 0
4574 if(copy_tab != NULL){
4575 tab->time_window = copy_tab->time_window;
4576 tab->current_time = copy_tab->current_time;
4577 }else{
4578 tab->time_window.start_time =
4579 LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context)->
4580 time_span.start_time;
4581 if(DEFAULT_TIME_WIDTH_S <
4582 LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context)->
4583 time_span.end_time.tv_sec)
4584 tmp_time.tv_sec = DEFAULT_TIME_WIDTH_S;
4585 else
4586 tmp_time.tv_sec =
4587 LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context)->
4588 time_span.end_time.tv_sec;
4589 tmp_time.tv_nsec = 0;
4590 tab->time_window.time_width = tmp_time ;
4591 tab->current_time.tv_sec =
4592 LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context)->
4593 time_span.start_time.tv_sec;
4594 tab->current_time.tv_nsec =
4595 LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context)->
4596 time_span.start_time.tv_nsec;
4597 }
4598 #endif //0
4599 tab->attributes = LTTV_IATTRIBUTE(g_object_new(LTTV_ATTRIBUTE_TYPE, NULL));
4600 tab->interrupted_state = g_object_new(LTTV_ATTRIBUTE_TYPE, NULL);
4601
4602 tab->vbox = gtk_vbox_new(FALSE, 2);
4603 tab->top_widget = tab->vbox;
4604 //g_object_set_data_full(G_OBJECT(tab->top_widget), "filter",
4605 // filter, (GDestroyNotify)lttv_filter_destroy);
4606
4607 // g_signal_connect (G_OBJECT(tab->top_widget),
4608 // "notify",
4609 // G_CALLBACK (on_top_notify),
4610 // (gpointer)tab);
4611
4612 tab->viewer_container = gtk_vbox_new(TRUE, 2);
4613 tab->scrollbar = gtk_hscrollbar_new(NULL);
4614 //tab->multivpaned = gtk_multi_vpaned_new();
4615
4616 gtk_box_pack_start(GTK_BOX(tab->vbox),
4617 tab->viewer_container,
4618 TRUE, /* expand */
4619 TRUE, /* Give the extra space to the child */
4620 0); /* No padding */
4621
4622 // if(copy_tab) {
4623 // tab->time_window = copy_tab->time_window;
4624 // tab->current_time = copy_tab->current_time;
4625 // }
4626
4627 /* Create the timebar */
4628 {
4629 tab->MTimebar = gtk_hbox_new(FALSE, 2);
4630 gtk_widget_show(tab->MTimebar);
4631 tab->tooltips = gtk_tooltips_new();
4632
4633 tab->MEventBox1a = gtk_event_box_new();
4634 gtk_widget_show(tab->MEventBox1a);
4635 gtk_tooltips_set_tip(tab->tooltips, tab->MEventBox1a,
4636 "Paste Start and End Times Here", "");
4637 tab->MText1a = gtk_label_new("Time Frame ");
4638 gtk_widget_show(tab->MText1a);
4639 gtk_container_add(GTK_CONTAINER(tab->MEventBox1a), tab->MText1a);
4640 tab->MEventBox1b = gtk_event_box_new();
4641 gtk_widget_show(tab->MEventBox1b);
4642 gtk_tooltips_set_tip(tab->tooltips, tab->MEventBox1b,
4643 "Paste Start Time Here", "");
4644 tab->MText1b = gtk_label_new("start: ");
4645 gtk_widget_show(tab->MText1b);
4646 gtk_container_add(GTK_CONTAINER(tab->MEventBox1b), tab->MText1b);
4647 tab->MText2 = gtk_label_new("s");
4648 gtk_widget_show(tab->MText2);
4649 tab->MText3a = gtk_label_new("ns");
4650 gtk_widget_show(tab->MText3a);
4651
4652 tab->MEventBox3b = gtk_event_box_new();
4653 gtk_widget_show(tab->MEventBox3b);
4654 gtk_tooltips_set_tip(tab->tooltips, tab->MEventBox3b,
4655 "Paste End Time Here", "");
4656 tab->MText3b = gtk_label_new("end:");
4657 gtk_widget_show(tab->MText3b);
4658 gtk_container_add(GTK_CONTAINER(tab->MEventBox3b), tab->MText3b);
4659 tab->MText4 = gtk_label_new("s");
4660 gtk_widget_show(tab->MText4);
4661 tab->MText5a = gtk_label_new("ns");
4662 gtk_widget_show(tab->MText5a);
4663
4664 tab->MEventBox8 = gtk_event_box_new();
4665 gtk_widget_show(tab->MEventBox8);
4666 gtk_tooltips_set_tip(tab->tooltips, tab->MEventBox8,
4667 "Paste Time Interval here", "");
4668 tab->MText8 = gtk_label_new("Time Interval:");
4669 gtk_widget_show(tab->MText8);
4670 gtk_container_add(GTK_CONTAINER(tab->MEventBox8), tab->MText8);
4671 tab->MText9 = gtk_label_new("s");
4672 gtk_widget_show(tab->MText9);
4673 tab->MText10 = gtk_label_new("ns");
4674 gtk_widget_show(tab->MText10);
4675
4676 tab->MEventBox5b = gtk_event_box_new();
4677 gtk_widget_show(tab->MEventBox5b);
4678 gtk_tooltips_set_tip(tab->tooltips, tab->MEventBox5b,
4679 "Paste Current Time Here", "");
4680 tab->MText5b = gtk_label_new("Current Time:");
4681 gtk_widget_show(tab->MText5b);
4682 gtk_container_add(GTK_CONTAINER(tab->MEventBox5b), tab->MText5b);
4683 tab->MText6 = gtk_label_new("s");
4684 gtk_widget_show(tab->MText6);
4685 tab->MText7 = gtk_label_new("ns");
4686 gtk_widget_show(tab->MText7);
4687
4688 tab->MEntry1 = gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4689 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab->MEntry1),0);
4690 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab->MEntry1),TRUE);
4691 gtk_widget_show(tab->MEntry1);
4692 tab->MEntry2 = gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4693 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab->MEntry2),0);
4694 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab->MEntry2),TRUE);
4695 gtk_widget_show(tab->MEntry2);
4696 tab->MEntry3 = gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4697 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab->MEntry3),0);
4698 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab->MEntry3),TRUE);
4699 gtk_widget_show(tab->MEntry3);
4700 tab->MEntry4 = gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4701 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab->MEntry4),0);
4702 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab->MEntry4),TRUE);
4703 gtk_widget_show(tab->MEntry4);
4704 tab->MEntry5 = gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4705 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab->MEntry5),0);
4706 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab->MEntry5),TRUE);
4707 gtk_widget_show(tab->MEntry5);
4708 tab->MEntry6 = gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4709 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab->MEntry6),0);
4710 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab->MEntry6),TRUE);
4711 gtk_widget_show(tab->MEntry6);
4712 tab->MEntry7 = gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4713 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab->MEntry7),0);
4714 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab->MEntry7),TRUE);
4715 gtk_widget_show(tab->MEntry7);
4716 tab->MEntry8 = gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4717 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab->MEntry8),0);
4718 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab->MEntry8),TRUE);
4719 gtk_widget_show(tab->MEntry8);
4720
4721 GtkWidget *temp_widget;
4722
4723 gtk_box_pack_start (GTK_BOX (tab->MTimebar), tab->MEventBox1a, FALSE,
4724 FALSE, 0);
4725 gtk_box_pack_start (GTK_BOX (tab->MTimebar), tab->MEventBox1b, FALSE,
4726 FALSE, 0);
4727 gtk_box_pack_start (GTK_BOX (tab->MTimebar), tab->MEntry1, FALSE, FALSE, 0);
4728 gtk_box_pack_start (GTK_BOX (tab->MTimebar), tab->MText2, FALSE, FALSE, 0);
4729 gtk_box_pack_start (GTK_BOX (tab->MTimebar), tab->MEntry2, FALSE, FALSE, 0);
4730 gtk_box_pack_start (GTK_BOX (tab->MTimebar), tab->MText3a, FALSE, FALSE, 0);
4731 temp_widget = gtk_vseparator_new();
4732 gtk_widget_show(temp_widget);
4733 gtk_box_pack_start (GTK_BOX (tab->MTimebar), temp_widget, FALSE, FALSE, 0);
4734 gtk_box_pack_start (GTK_BOX (tab->MTimebar), tab->MEventBox3b, FALSE,
4735 FALSE, 0);
4736 gtk_box_pack_start (GTK_BOX (tab->MTimebar), tab->MEntry3, FALSE, FALSE, 0);
4737 gtk_box_pack_start (GTK_BOX (tab->MTimebar), tab->MText4, FALSE, FALSE, 0);
4738 gtk_box_pack_start (GTK_BOX (tab->MTimebar), tab->MEntry4, FALSE, FALSE, 0);
4739 gtk_box_pack_start (GTK_BOX (tab->MTimebar), tab->MText5a, FALSE, FALSE, 0);
4740 temp_widget = gtk_vseparator_new();
4741 gtk_widget_show(temp_widget);
4742 gtk_box_pack_start (GTK_BOX (tab->MTimebar), temp_widget, FALSE, FALSE, 0);
4743 gtk_box_pack_start (GTK_BOX (tab->MTimebar), tab->MEventBox8, FALSE,
4744 FALSE, 0);
4745 gtk_box_pack_start (GTK_BOX (tab->MTimebar), tab->MEntry7, FALSE, FALSE, 0);
4746 gtk_box_pack_start (GTK_BOX (tab->MTimebar), tab->MText9, FALSE, FALSE, 0);
4747 gtk_box_pack_start (GTK_BOX (tab->MTimebar), tab->MEntry8, FALSE, FALSE, 0);
4748 gtk_box_pack_start (GTK_BOX (tab->MTimebar), tab->MText10, FALSE, FALSE, 0);
4749
4750 temp_widget = gtk_vseparator_new();
4751 gtk_widget_show(temp_widget);
4752 gtk_box_pack_end (GTK_BOX (tab->MTimebar), tab->MText7, FALSE, FALSE, 0);
4753 gtk_box_pack_end (GTK_BOX (tab->MTimebar), tab->MEntry6, FALSE, FALSE, 0);
4754 gtk_box_pack_end (GTK_BOX (tab->MTimebar), tab->MText6, FALSE, FALSE, 0);
4755 gtk_box_pack_end (GTK_BOX (tab->MTimebar), tab->MEntry5, FALSE, FALSE, 0);
4756 gtk_box_pack_end (GTK_BOX (tab->MTimebar), tab->MEventBox5b, FALSE,
4757 FALSE, 0);
4758 gtk_box_pack_end (GTK_BOX (tab->MTimebar), temp_widget, FALSE, FALSE, 0);
4759
4760
4761 //GtkWidget *test = gtk_button_new_with_label("drop");
4762 //gtk_button_set_relief(GTK_BUTTON(test), GTK_RELIEF_NONE);
4763 //gtk_widget_show(test);
4764 //gtk_box_pack_end(GTK_BOX (tab->MTimebar), test, FALSE, FALSE, 0);
4765 //gtk_widget_add_events(tab->MText1, GDK_ALL_EVENTS_MASK);//GDK_BUTTON_PRESS_MASK);
4766 /*GtkWidget *event_box = gtk_event_box_new();
4767 gtk_widget_show(event_box);
4768 gtk_tooltips_set_tip(tooltips, event_box,
4769 "Paste Current Time Here", "");
4770 gtk_box_pack_end(GTK_BOX (tab->MTimebar), event_box, FALSE, FALSE, 0);
4771 GtkWidget *test = gtk_label_new("drop");
4772 gtk_container_add(GTK_CONTAINER(event_box), test);
4773 gtk_widget_show(test);
4774 g_signal_connect (G_OBJECT(event_box),
4775 "button-press-event",
4776 G_CALLBACK (on_MText1_paste),
4777 (gpointer)tab);
4778 */
4779
4780 g_signal_connect (G_OBJECT(tab->MEventBox1a),
4781 "button-press-event",
4782 G_CALLBACK (on_MEventBox1a_paste),
4783 (gpointer)tab);
4784
4785 g_signal_connect (G_OBJECT(tab->MEventBox1b),
4786 "button-press-event",
4787 G_CALLBACK (on_MEventBox1b_paste),
4788 (gpointer)tab);
4789 g_signal_connect (G_OBJECT(tab->MEventBox3b),
4790 "button-press-event",
4791 G_CALLBACK (on_MEventBox3b_paste),
4792 (gpointer)tab);
4793 g_signal_connect (G_OBJECT(tab->MEventBox5b),
4794 "button-press-event",
4795 G_CALLBACK (on_MEventBox5b_paste),
4796 (gpointer)tab);
4797 g_signal_connect (G_OBJECT(tab->MEventBox8),
4798 "button-press-event",
4799 G_CALLBACK (on_MEventBox8_paste),
4800 (gpointer)tab);
4801 }
4802
4803 gtk_box_pack_end(GTK_BOX(tab->vbox),
4804 tab->scrollbar,
4805 FALSE, /* Do not expand */
4806 FALSE, /* Fill has no effect here (expand false) */
4807 0); /* No padding */
4808
4809 gtk_box_pack_end(GTK_BOX(tab->vbox),
4810 tab->MTimebar,
4811 FALSE, /* Do not expand */
4812 FALSE, /* Fill has no effect here (expand false) */
4813 0); /* No padding */
4814
4815 g_object_set_data(G_OBJECT(tab->viewer_container), "focused_viewer", NULL);
4816
4817
4818 tab->mw = mw;
4819
4820 /*{
4821 // Display a label with a X
4822 GtkWidget *w_hbox = gtk_hbox_new(FALSE, 4);
4823 GtkWidget *w_label = gtk_label_new (label);
4824 GtkWidget *pixmap = create_pixmap(GTK_WIDGET(notebook), "close.png");
4825 GtkWidget *w_button = gtk_button_new ();
4826 gtk_container_add(GTK_CONTAINER(w_button), pixmap);
4827 //GtkWidget *w_button = gtk_button_new_with_label("x");
4828
4829 gtk_button_set_relief(GTK_BUTTON(w_button), GTK_RELIEF_NONE);
4830
4831 gtk_box_pack_start(GTK_BOX(w_hbox), w_label, TRUE, TRUE, 0);
4832 gtk_box_pack_end(GTK_BOX(w_hbox), w_button, FALSE,
4833 FALSE, 0);
4834
4835 g_signal_connect_swapped (w_button, "clicked",
4836 G_CALLBACK (on_close_tab_X_clicked),
4837 tab->multi_vpaned);
4838
4839 gtk_widget_set_state(w_button, GTK_STATE_ACTIVE);
4840
4841 gtk_widget_show (w_label);
4842 gtk_widget_show (pixmap);
4843 gtk_widget_show (w_button);
4844 gtk_widget_show (w_hbox);
4845
4846 tab->label = w_hbox;
4847 }*/
4848
4849
4850 tab->label = gtk_label_new (label);
4851
4852 gtk_widget_show(tab->label);
4853 gtk_widget_show(tab->scrollbar);
4854 gtk_widget_show(tab->viewer_container);
4855 gtk_widget_show(tab->vbox);
4856 //gtk_widget_show(tab->multivpaned);
4857
4858
4859 /* Start with empty events requests list */
4860 tab->events_requests = NULL;
4861 tab->events_request_pending = FALSE;
4862 tab->stop_foreground = FALSE;
4863
4864
4865
4866 g_signal_connect(G_OBJECT(tab->scrollbar), "value-changed",
4867 G_CALLBACK(scroll_value_changed_cb), tab);
4868
4869 g_signal_connect ((gpointer) tab->MEntry1, "value-changed",
4870 G_CALLBACK (on_MEntry1_value_changed),
4871 tab);
4872 g_signal_connect ((gpointer) tab->MEntry2, "value-changed",
4873 G_CALLBACK (on_MEntry2_value_changed),
4874 tab);
4875 g_signal_connect ((gpointer) tab->MEntry3, "value-changed",
4876 G_CALLBACK (on_MEntry3_value_changed),
4877 tab);
4878 g_signal_connect ((gpointer) tab->MEntry4, "value-changed",
4879 G_CALLBACK (on_MEntry4_value_changed),
4880 tab);
4881 g_signal_connect ((gpointer) tab->MEntry5, "value-changed",
4882 G_CALLBACK (on_MEntry5_value_changed),
4883 tab);
4884 g_signal_connect ((gpointer) tab->MEntry6, "value-changed",
4885 G_CALLBACK (on_MEntry6_value_changed),
4886 tab);
4887 g_signal_connect ((gpointer) tab->MEntry7, "value-changed",
4888 G_CALLBACK (on_MEntry7_value_changed),
4889 tab);
4890 g_signal_connect ((gpointer) tab->MEntry8, "value-changed",
4891 G_CALLBACK (on_MEntry8_value_changed),
4892 tab);
4893
4894 //g_signal_connect(G_OBJECT(tab->scrollbar), "changed",
4895 // G_CALLBACK(scroll_value_changed_cb), tab);
4896
4897
4898 //insert tab into notebook
4899 gtk_notebook_append_page(notebook,
4900 tab->vbox,
4901 tab->label);
4902 list = gtk_container_get_children(GTK_CONTAINER(notebook));
4903 gtk_notebook_set_current_page(notebook,g_list_length(list)-1);
4904 // always show : not if(g_list_length(list)>1)
4905 gtk_notebook_set_show_tabs(notebook, TRUE);
4906
4907 if(copy_tab) {
4908 lttvwindow_report_time_window(tab, copy_tab->time_window);
4909 lttvwindow_report_current_time(tab, copy_tab->current_time);
4910 } else {
4911 TimeWindow time_window;
4912
4913 time_window.start_time = ltt_time_zero;
4914 time_window.end_time = ltt_time_add(time_window.start_time,
4915 lttvwindow_default_time_width);
4916 time_window.time_width = lttvwindow_default_time_width;
4917 time_window.time_width_double = ltt_time_to_double(time_window.time_width);
4918
4919 lttvwindow_report_time_window(tab, time_window);
4920 lttvwindow_report_current_time(tab, ltt_time_zero);
4921 }
4922
4923 LttvTraceset *traceset = tab->traceset_info->traceset;
4924 SetTraceset(tab, traceset);
4925 }
4926
4927 /*
4928 * execute_events_requests
4929 *
4930 * Idle function that executes the pending requests for a tab.
4931 *
4932 * @return return value : TRUE : keep the idle function, FALSE : remove it.
4933 */
4934 gboolean execute_events_requests(Tab *tab)
4935 {
4936 return ( lttvwindow_process_pending_requests(tab) );
4937 }
4938
4939
4940 __EXPORT void create_main_window_with_trace_list(GSList *traces)
4941 {
4942 GSList *iter = NULL;
4943
4944 /* Create window */
4945 MainWindow *mw = construct_main_window(NULL);
4946 GtkWidget *widget = mw->mwindow;
4947
4948 GtkWidget * notebook = lookup_widget(widget, "MNotebook");
4949 GtkWidget *page = gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook),
4950 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook)));
4951 LttvPluginTab *ptab;
4952 Tab *tab;
4953
4954 if(!page) {
4955 ptab = create_new_tab(widget, NULL);
4956 tab = ptab->tab;
4957 } else {
4958 ptab = (LttvPluginTab *)g_object_get_data(G_OBJECT(page), "Tab_Plugin");
4959 tab = ptab->tab;
4960 }
4961
4962 for(iter=traces; iter!=NULL; iter=g_slist_next(iter)) {
4963 gchar *path = (gchar*)iter->data;
4964 /* Add trace */
4965 gchar abs_path[PATH_MAX];
4966 LttvTrace *trace_v;
4967 LttTrace *trace;
4968
4969 get_absolute_pathname(path, abs_path);
4970 trace_v = lttvwindowtraces_get_trace_by_name(abs_path);
4971 if(trace_v == NULL) {
4972 trace = ltt_trace_open(abs_path);
4973 if(trace == NULL) {
4974 g_warning("cannot open trace %s", abs_path);
4975
4976 GtkWidget *dialogue =
4977 gtk_message_dialog_new(
4978 GTK_WINDOW(gtk_widget_get_toplevel(widget)),
4979 GTK_DIALOG_MODAL|GTK_DIALOG_DESTROY_WITH_PARENT,
4980 GTK_MESSAGE_ERROR,
4981 GTK_BUTTONS_OK,
4982 "Cannot open trace : maybe you should enter in the directory "
4983 "to select it ?");
4984 gtk_dialog_run(GTK_DIALOG(dialogue));
4985 gtk_widget_destroy(dialogue);
4986 } else {
4987 trace_v = lttv_trace_new(trace);
4988 lttvwindowtraces_add_trace(trace_v);
4989 lttvwindow_add_trace(tab, trace_v);
4990 }
4991 } else {
4992 lttvwindow_add_trace(tab, trace_v);
4993 }
4994 }
4995
4996 LttvTraceset *traceset;
4997
4998 traceset = tab->traceset_info->traceset;
4999 SetTraceset(tab, traceset);
5000 }
5001
This page took 0.150288 seconds and 5 git commands to generate.