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