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