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