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