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