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