authors in about
[lttv.git] / ltt / branches / poly / lttv / modules / gui / lttvwindow / lttvwindow / callbacks.c
1 /* This file is part of the Linux Trace Toolkit viewer
2 * Copyright (C) 2003-2004 XangXiu Yang, Mathieu Desnoyers
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License Version 2 as
6 * published by the Free Software Foundation;
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place - Suite 330, Boston,
16 * MA 02111-1307, USA.
17 */
18
19 #ifdef HAVE_CONFIG_H
20 # include <config.h>
21 #endif
22
23 #include <limits.h> // for PATH_MAX
24 #include <stdlib.h>
25
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.tv_sec = G_MAXUINT;
1287 events_request->start_time.tv_nsec = G_MAXUINT;
1288
1289 /* 1.3. Move from list_in to list_out */
1290 remove = TRUE;
1291 free_data = FALSE;
1292 list_out = g_slist_append(list_out, events_request);
1293
1294 /* Go to next */
1295 if(remove)
1296 {
1297 GSList *remove_iter = iter;
1298
1299 iter = g_slist_next(iter);
1300 if(free_data) events_request_free((EventsRequest*)remove_iter->data);
1301 list_in = g_slist_remove_link(list_in, remove_iter);
1302 } else { // not remove
1303 iter = g_slist_next(iter);
1304 }
1305 }
1306
1307
1308 }
1309
1310 /* C Unlock Traces */
1311 {
1312 //lttv_process_traceset_get_sync_data(tsc);
1313
1314 guint iter_trace;
1315
1316 for(iter_trace=0;
1317 iter_trace<lttv_traceset_number(tsc->ts);
1318 iter_trace++) {
1319 LttvTrace *trace_v = lttv_traceset_get(tsc->ts, iter_trace);
1320
1321 lttvwindowtraces_unlock(trace_v);
1322 }
1323 }
1324
1325 #if 0
1326 //set the cursor back to normal
1327 gdk_window_set_cursor(win, NULL);
1328 #endif //0
1329
1330 g_assert(g_slist_length(list_in) == 0);
1331
1332 if( g_slist_length(list_out) == 0 ) {
1333 /* Put tab's request pending flag back to normal */
1334 tab->events_request_pending = FALSE;
1335 g_debug("remove the idle fct");
1336 return FALSE; /* Remove the idle function */
1337 }
1338 g_debug("leave the idle fct");
1339 return TRUE; /* Leave the idle function */
1340
1341 /* We do not use simili-round-robin, it may require to read 1 meg buffers
1342 * again and again if many tracesets use the same tracefiles. */
1343 /* Hack for round-robin idle functions */
1344 /* It will put the idle function at the end of the pool */
1345 /*g_idle_add_full((G_PRIORITY_HIGH_IDLE + 21),
1346 (GSourceFunc)execute_events_requests,
1347 tab,
1348 NULL);
1349 return FALSE;
1350 */
1351 }
1352
1353 #undef list_out
1354
1355
1356 /* add_trace_into_traceset_selector, each instance of a viewer has an associated
1357 * selector (filter), when a trace is added into traceset, the selector should
1358 * reflect the change. The function is used to update the selector
1359 */
1360 #if 0
1361 void add_trace_into_traceset_selector(GtkWidget * paned, LttTrace * t)
1362 {
1363 int j, k, m, nb_tracefile, nb_control, nb_per_cpu, nb_facility, nb_event;
1364 LttvTracesetSelector * s;
1365 LttvTraceSelector * trace;
1366 LttvTracefileSelector * tracefile;
1367 LttvEventtypeSelector * eventtype;
1368 LttTracefile * tf;
1369 GtkWidget * w;
1370 LttFacility * fac;
1371 LttEventType * et;
1372
1373 w = gtk_multivpaned_get_first_widget(GTK_MULTIVPANED(paned));
1374 while(w){
1375 s = g_object_get_data(G_OBJECT(w), "Traceset_Selector");
1376
1377 if(s){
1378 trace = lttv_trace_selector_new(t);
1379 lttv_traceset_selector_trace_add(s, trace);
1380
1381 nb_facility = ltt_trace_facility_number(t);
1382 for(k=0;k<nb_facility;k++){
1383 fac = ltt_trace_facility_get(t,k);
1384 nb_event = (int) ltt_facility_eventtype_number(fac);
1385 for(m=0;m<nb_event;m++){
1386 et = ltt_facility_eventtype_get(fac,m);
1387 eventtype = lttv_eventtype_selector_new(et);
1388 lttv_trace_selector_eventtype_add(trace, eventtype);
1389 }
1390 }
1391
1392 nb_control = ltt_trace_control_tracefile_number(t);
1393 nb_per_cpu = ltt_trace_per_cpu_tracefile_number(t);
1394 nb_tracefile = nb_control + nb_per_cpu;
1395
1396 for(j = 0 ; j < nb_tracefile ; j++) {
1397 if(j < nb_control)
1398 tf = ltt_trace_control_tracefile_get(t, j);
1399 else
1400 tf = ltt_trace_per_cpu_tracefile_get(t, j - nb_control);
1401 tracefile = lttv_tracefile_selector_new(tf);
1402 lttv_trace_selector_tracefile_add(trace, tracefile);
1403 lttv_eventtype_selector_copy(trace, tracefile);
1404 }
1405 }else g_warning("Module does not support filtering\n");
1406
1407 w = gtk_multivpaned_get_next_widget(GTK_MULTIVPANED(paned));
1408 }
1409 }
1410 #endif //0
1411
1412 static void lttvwindow_add_trace(Tab *tab, LttvTrace *trace_v)
1413 {
1414 LttvTraceset *traceset = tab->traceset_info->traceset;
1415 guint i;
1416 guint num_traces = lttv_traceset_number(traceset);
1417
1418 //Verify if trace is already present.
1419 for(i=0; i<num_traces; i++)
1420 {
1421 LttvTrace * trace = lttv_traceset_get(traceset, i);
1422 if(trace == trace_v)
1423 return;
1424 }
1425
1426 //Keep a reference to the traces so they are not freed.
1427 for(i=0; i<lttv_traceset_number(traceset); i++)
1428 {
1429 LttvTrace * trace = lttv_traceset_get(traceset, i);
1430 lttv_trace_ref(trace);
1431 }
1432
1433 //remove state update hooks
1434 lttv_state_remove_event_hooks(
1435 (LttvTracesetState*)tab->traceset_info->traceset_context);
1436
1437 lttv_context_fini(LTTV_TRACESET_CONTEXT(
1438 tab->traceset_info->traceset_context));
1439 g_object_unref(tab->traceset_info->traceset_context);
1440
1441 lttv_traceset_add(traceset, trace_v);
1442 lttv_trace_ref(trace_v); /* local ref */
1443
1444 /* Create new context */
1445 tab->traceset_info->traceset_context =
1446 g_object_new(LTTV_TRACESET_STATS_TYPE, NULL);
1447 lttv_context_init(
1448 LTTV_TRACESET_CONTEXT(tab->traceset_info->
1449 traceset_context),
1450 traceset);
1451
1452
1453 //add state update hooks
1454 lttv_state_add_event_hooks(
1455 (LttvTracesetState*)tab->traceset_info->traceset_context);
1456 //Remove local reference to the traces.
1457 for(i=0; i<lttv_traceset_number(traceset); i++)
1458 {
1459 LttvTrace * trace = lttv_traceset_get(traceset, i);
1460 lttv_trace_unref(trace);
1461 }
1462
1463 //FIXME
1464 //add_trace_into_traceset_selector(GTK_MULTIVPANED(tab->multivpaned), lttv_trace(trace_v));
1465 }
1466
1467 /* add_trace adds a trace into the current traceset. It first displays a
1468 * directory selection dialogue to let user choose a trace, then recreates
1469 * tracset_context, and redraws all the viewer of the current tab
1470 */
1471
1472 void add_trace(GtkWidget * widget, gpointer user_data)
1473 {
1474 LttTrace *trace;
1475 LttvTrace * trace_v;
1476 LttvTraceset * traceset;
1477 const char * dir;
1478 char abs_path[PATH_MAX];
1479 gint id;
1480 gint i;
1481 MainWindow * mw_data = get_window_data_struct(widget);
1482 GtkWidget * notebook = lookup_widget(widget, "MNotebook");
1483
1484 GtkWidget *page = gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook),
1485 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook)));
1486 Tab *tab;
1487
1488 if(!page) {
1489 tab = create_new_tab(widget, NULL);
1490 } else {
1491 tab = (Tab *)g_object_get_data(G_OBJECT(page), "Tab_Info");
1492 }
1493
1494 GtkDirSelection * file_selector = (GtkDirSelection *)gtk_dir_selection_new("Select a trace");
1495 gtk_dir_selection_hide_fileop_buttons(file_selector);
1496
1497 if(remember_trace_dir[0] != '\0')
1498 gtk_dir_selection_set_filename(file_selector, remember_trace_dir);
1499
1500 id = gtk_dialog_run(GTK_DIALOG(file_selector));
1501 switch(id){
1502 case GTK_RESPONSE_ACCEPT:
1503 case GTK_RESPONSE_OK:
1504 dir = gtk_dir_selection_get_dir (file_selector);
1505 strncpy(remember_trace_dir, dir, PATH_MAX);
1506 if(!dir || strlen(dir) == 0){
1507 gtk_widget_destroy((GtkWidget*)file_selector);
1508 break;
1509 }
1510 get_absolute_pathname(dir, abs_path);
1511 trace_v = lttvwindowtraces_get_trace_by_name(abs_path);
1512 if(trace_v == NULL) {
1513 trace = ltt_trace_open(abs_path);
1514 if(trace == NULL) {
1515 g_warning("cannot open trace %s", abs_path);
1516 } else {
1517 trace_v = lttv_trace_new(trace);
1518 lttvwindowtraces_add_trace(trace_v);
1519 lttvwindow_add_trace(tab, trace_v);
1520 }
1521 } else {
1522 lttvwindow_add_trace(tab, trace_v);
1523 }
1524
1525 gtk_widget_destroy((GtkWidget*)file_selector);
1526
1527 //update current tab
1528 //update_traceset(mw_data);
1529
1530 /* Call the updatetraceset hooks */
1531
1532 traceset = tab->traceset_info->traceset;
1533 SetTraceset(tab, traceset);
1534 // in expose now call_pending_read_hooks(mw_data);
1535
1536 //lttvwindow_report_current_time(mw_data,&(tab->current_time));
1537 break;
1538 case GTK_RESPONSE_REJECT:
1539 case GTK_RESPONSE_CANCEL:
1540 default:
1541 gtk_widget_destroy((GtkWidget*)file_selector);
1542 break;
1543 }
1544 }
1545
1546
1547 /* remove_trace_into_traceset_selector, each instance of a viewer has an associated
1548 * selector (filter), when a trace is remove from traceset, the selector should
1549 * reflect the change. The function is used to update the selector
1550 */
1551 #if 0
1552 void remove_trace_from_traceset_selector(GtkWidget * paned, unsigned i)
1553 {
1554 LttvTracesetSelector * s;
1555 LttvTraceSelector * t;
1556 GtkWidget * w;
1557
1558 w = gtk_multivpaned_get_first_widget(GTK_MULTIVPANED(paned));
1559 while(w){
1560 s = g_object_get_data(G_OBJECT(w), "Traceset_Selector");
1561 if(s){
1562 t = lttv_traceset_selector_trace_get(s,i);
1563 lttv_traceset_selector_trace_remove(s, i);
1564 lttv_trace_selector_destroy(t);
1565 }g_warning("Module dose not support filtering\n");
1566 w = gtk_multivpaned_get_next_widget(GTK_MULTIVPANED(paned));
1567 }
1568 }
1569 #endif //0
1570
1571 /* remove_trace removes a trace from the current traceset if all viewers in
1572 * the current tab are not interested in the trace. It first displays a
1573 * dialogue, which shows all traces in the current traceset, to let user choose
1574 * a trace, then it checks if all viewers unselect the trace, if it is true,
1575 * it will remove the trace, recreate the traceset_contex,
1576 * and redraws all the viewer of the current tab. If there is on trace in the
1577 * current traceset, it will delete all viewers of the current tab
1578 */
1579
1580 // MD : no filter version.
1581 void remove_trace(GtkWidget *widget, gpointer user_data)
1582 {
1583 LttTrace *trace;
1584 LttvTrace * trace_v;
1585 LttvTraceset * traceset;
1586 gint i, j, nb_trace, index=-1;
1587 char ** name, *remove_trace_name;
1588 MainWindow * mw_data = get_window_data_struct(widget);
1589 GtkWidget * notebook = lookup_widget(widget, "MNotebook");
1590
1591 GtkWidget *page = gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook),
1592 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook)));
1593 Tab *tab;
1594
1595 if(!page) {
1596 return;
1597 } else {
1598 tab = (Tab *)g_object_get_data(G_OBJECT(page), "Tab_Info");
1599 }
1600
1601 nb_trace =lttv_traceset_number(tab->traceset_info->traceset);
1602 name = g_new(char*,nb_trace);
1603 for(i = 0; i < nb_trace; i++){
1604 trace_v = lttv_traceset_get(tab->traceset_info->traceset, i);
1605 trace = lttv_trace(trace_v);
1606 name[i] = ltt_trace_name(trace);
1607 }
1608
1609 remove_trace_name = get_remove_trace(name, nb_trace);
1610
1611
1612 if(remove_trace_name){
1613
1614 /* yuk, cut n paste from old code.. should be better (MD)*/
1615 for(i = 0; i<nb_trace; i++) {
1616 if(strcmp(remove_trace_name,name[i]) == 0){
1617 index = i;
1618 }
1619 }
1620
1621 traceset = tab->traceset_info->traceset;
1622 //Keep a reference to the traces so they are not freed.
1623 for(j=0; j<lttv_traceset_number(traceset); j++)
1624 {
1625 LttvTrace * trace = lttv_traceset_get(traceset, j);
1626 lttv_trace_ref(trace);
1627 }
1628
1629 //remove state update hooks
1630 lttv_state_remove_event_hooks(
1631 (LttvTracesetState*)tab->traceset_info->traceset_context);
1632 lttv_context_fini(LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context));
1633 g_object_unref(tab->traceset_info->traceset_context);
1634
1635 trace_v = lttv_traceset_get(traceset, index);
1636
1637 lttv_traceset_remove(traceset, index);
1638 lttv_trace_unref(trace_v); // Remove local reference
1639
1640 if(lttv_trace_get_ref_number(trace_v) <= 1) {
1641 /* ref 1 : lttvwindowtraces only*/
1642 ltt_trace_close(lttv_trace(trace_v));
1643 /* lttvwindowtraces_remove_trace takes care of destroying
1644 * the traceset linked with the trace_v and also of destroying
1645 * the trace_v at the same time.
1646 */
1647 lttvwindowtraces_remove_trace(trace_v);
1648 }
1649
1650 tab->traceset_info->traceset_context =
1651 g_object_new(LTTV_TRACESET_STATS_TYPE, NULL);
1652 lttv_context_init(
1653 LTTV_TRACESET_CONTEXT(tab->
1654 traceset_info->traceset_context),traceset);
1655 //add state update hooks
1656 lttv_state_add_event_hooks(
1657 (LttvTracesetState*)tab->traceset_info->traceset_context);
1658
1659 //Remove local reference to the traces.
1660 for(j=0; j<lttv_traceset_number(traceset); j++)
1661 {
1662 LttvTrace * trace = lttv_traceset_get(traceset, j);
1663 lttv_trace_unref(trace);
1664 }
1665
1666 SetTraceset(tab, (gpointer)traceset);
1667 }
1668 g_free(name);
1669 }
1670
1671 #if 0
1672 void remove_trace(GtkWidget * widget, gpointer user_data)
1673 {
1674 LttTrace *trace;
1675 LttvTrace * trace_v;
1676 LttvTraceset * traceset;
1677 gint i, j, nb_trace;
1678 char ** name, *remove_trace_name;
1679 MainWindow * mw_data = get_window_data_struct(widget);
1680 LttvTracesetSelector * s;
1681 LttvTraceSelector * t;
1682 GtkWidget * w;
1683 gboolean selected;
1684 GtkWidget * notebook = lookup_widget(widget, "MNotebook");
1685
1686 GtkWidget *page = gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook),
1687 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook)));
1688 Tab *tab;
1689
1690 if(!page) {
1691 return;
1692 } else {
1693 tab = (Tab *)g_object_get_data(G_OBJECT(page), "Tab_Info");
1694 }
1695
1696 nb_trace =lttv_traceset_number(tab->traceset_info->traceset);
1697 name = g_new(char*,nb_trace);
1698 for(i = 0; i < nb_trace; i++){
1699 trace_v = lttv_traceset_get(tab->traceset_info->traceset, i);
1700 trace = lttv_trace(trace_v);
1701 name[i] = ltt_trace_name(trace);
1702 }
1703
1704 remove_trace_name = get_remove_trace(name, nb_trace);
1705
1706 if(remove_trace_name){
1707 for(i=0; i<nb_trace; i++){
1708 if(strcmp(remove_trace_name,name[i]) == 0){
1709 //unselect the trace from the current viewer
1710 //FIXME
1711 w = gtk_multivpaned_get_widget(GTK_MULTIVPANED(tab->multivpaned));
1712 if(w){
1713 s = g_object_get_data(G_OBJECT(w), "Traceset_Selector");
1714 if(s){
1715 t = lttv_traceset_selector_trace_get(s,i);
1716 lttv_trace_selector_set_selected(t, FALSE);
1717 }
1718
1719 //check if other viewers select the trace
1720 w = gtk_multivpaned_get_first_widget(GTK_MULTIVPANED(tab->multivpaned));
1721 while(w){
1722 s = g_object_get_data(G_OBJECT(w), "Traceset_Selector");
1723 if(s){
1724 t = lttv_traceset_selector_trace_get(s,i);
1725 selected = lttv_trace_selector_get_selected(t);
1726 if(selected)break;
1727 }
1728 w = gtk_multivpaned_get_next_widget(GTK_MULTIVPANED(tab->multivpaned));
1729 }
1730 }else selected = FALSE;
1731
1732 //if no viewer selects the trace, remove it
1733 if(!selected){
1734 remove_trace_from_traceset_selector(GTK_MULTIVPANED(tab->multivpaned), i);
1735
1736 traceset = tab->traceset_info->traceset;
1737 //Keep a reference to the traces so they are not freed.
1738 for(j=0; j<lttv_traceset_number(traceset); j++)
1739 {
1740 LttvTrace * trace = lttv_traceset_get(traceset, j);
1741 lttv_trace_ref(trace);
1742 }
1743
1744 //remove state update hooks
1745 lttv_state_remove_event_hooks(
1746 (LttvTracesetState*)tab->traceset_info->traceset_context);
1747 lttv_context_fini(LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context));
1748 g_object_unref(tab->traceset_info->traceset_context);
1749
1750
1751 trace_v = lttv_traceset_get(traceset, i);
1752
1753 if(lttv_trace_get_ref_number(trace_v) <= 2) {
1754 /* ref 2 : traceset, local */
1755 lttvwindowtraces_remove_trace(trace_v);
1756 ltt_trace_close(lttv_trace(trace_v));
1757 }
1758
1759 lttv_traceset_remove(traceset, i);
1760 lttv_trace_unref(trace_v); // Remove local reference
1761
1762 if(!lttv_trace_get_ref_number(trace_v))
1763 lttv_trace_destroy(trace_v);
1764
1765 tab->traceset_info->traceset_context =
1766 g_object_new(LTTV_TRACESET_STATS_TYPE, NULL);
1767 lttv_context_init(
1768 LTTV_TRACESET_CONTEXT(tab->
1769 traceset_info->traceset_context),traceset);
1770 //add state update hooks
1771 lttv_state_add_event_hooks(
1772 (LttvTracesetState*)tab->traceset_info->traceset_context);
1773
1774 //Remove local reference to the traces.
1775 for(j=0; j<lttv_traceset_number(traceset); j++)
1776 {
1777 LttvTrace * trace = lttv_traceset_get(traceset, j);
1778 lttv_trace_unref(trace);
1779 }
1780
1781
1782 //update current tab
1783 //update_traceset(mw_data);
1784 //if(nb_trace > 1){
1785
1786 SetTraceset(tab, (gpointer)traceset);
1787 // in expose now call_pending_read_hooks(mw_data);
1788
1789 //lttvwindow_report_current_time(mw_data,&(tab->current_time));
1790 //}else{
1791 // if(tab){
1792 // while(tab->multi_vpaned->num_children){
1793 // gtk_multi_vpaned_widget_delete(tab->multi_vpaned);
1794 // }
1795 // }
1796 //}
1797 }
1798 break;
1799 }
1800 }
1801 }
1802
1803 g_free(name);
1804 }
1805 #endif //0
1806
1807 /* Redraw all the viewers in the current tab */
1808 void redraw(GtkWidget *widget, gpointer user_data)
1809 {
1810 GtkWidget * notebook = lookup_widget(widget, "MNotebook");
1811 GtkWidget *page = gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook),
1812 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook)));
1813 Tab *tab;
1814 if(!page) {
1815 return;
1816 } else {
1817 tab = (Tab *)g_object_get_data(G_OBJECT(page), "Tab_Info");
1818 }
1819
1820 LttvHooks * tmp;
1821 LttvAttributeValue value;
1822
1823 g_assert(lttv_iattribute_find_by_path(tab->attributes, "hooks/redraw", LTTV_POINTER, &value));
1824
1825 tmp = (LttvHooks*)*(value.v_pointer);
1826 if(tmp != NULL)
1827 lttv_hooks_call(tmp,NULL);
1828 }
1829
1830
1831 void continue_processing(GtkWidget *widget, gpointer user_data)
1832 {
1833 GtkWidget * notebook = lookup_widget(widget, "MNotebook");
1834 GtkWidget *page = gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook),
1835 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook)));
1836 Tab *tab;
1837 if(!page) {
1838 return;
1839 } else {
1840 tab = (Tab *)g_object_get_data(G_OBJECT(page), "Tab_Info");
1841 }
1842
1843 LttvHooks * tmp;
1844 LttvAttributeValue value;
1845
1846 g_assert(lttv_iattribute_find_by_path(tab->attributes,
1847 "hooks/continue", LTTV_POINTER, &value));
1848
1849 tmp = (LttvHooks*)*(value.v_pointer);
1850 if(tmp != NULL)
1851 lttv_hooks_call(tmp,NULL);
1852 }
1853
1854 /* Stop the processing for the calling main window's current tab.
1855 * It removes every processing requests that are in its list. It does not call
1856 * the end request hooks, because the request is not finished.
1857 */
1858
1859 void stop_processing(GtkWidget *widget, gpointer user_data)
1860 {
1861 GtkWidget * notebook = lookup_widget(widget, "MNotebook");
1862 GtkWidget *page = gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook),
1863 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook)));
1864 Tab *tab;
1865 if(!page) {
1866 return;
1867 } else {
1868 tab = (Tab *)g_object_get_data(G_OBJECT(page), "Tab_Info");
1869 }
1870 GSList *iter = tab->events_requests;
1871
1872 while(iter != NULL) {
1873 GSList *remove_iter = iter;
1874 iter = g_slist_next(iter);
1875
1876 g_free(remove_iter->data);
1877 tab->events_requests =
1878 g_slist_remove_link(tab->events_requests, remove_iter);
1879 }
1880 tab->events_request_pending = FALSE;
1881 g_idle_remove_by_data(tab);
1882 g_assert(g_slist_length(tab->events_requests) == 0);
1883 }
1884
1885
1886 /* save will save the traceset to a file
1887 * Not implemented yet FIXME
1888 */
1889
1890 void save(GtkWidget * widget, gpointer user_data)
1891 {
1892 g_printf("Save\n");
1893 }
1894
1895 void save_as(GtkWidget * widget, gpointer user_data)
1896 {
1897 g_printf("Save as\n");
1898 }
1899
1900
1901 /* zoom will change the time_window of all the viewers of the
1902 * current tab, and redisplay them. The main functionality is to
1903 * determine the new time_window of the current tab
1904 */
1905
1906 void zoom(GtkWidget * widget, double size)
1907 {
1908 TimeInterval time_span;
1909 TimeWindow new_time_window;
1910 LttTime current_time, time_delta, time_s, time_e, time_tmp;
1911 MainWindow * mw_data = get_window_data_struct(widget);
1912 LttvTracesetContext *tsc;
1913 GtkWidget * notebook = lookup_widget(widget, "MNotebook");
1914
1915 GtkWidget *page = gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook),
1916 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook)));
1917 Tab *tab;
1918
1919 if(!page) {
1920 return;
1921 } else {
1922 tab = (Tab *)g_object_get_data(G_OBJECT(page), "Tab_Info");
1923 }
1924
1925 if(size == 1) return;
1926
1927 tsc = LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context);
1928 time_span = tsc->time_span;
1929 new_time_window = tab->time_window;
1930 current_time = tab->current_time;
1931
1932 time_delta = ltt_time_sub(time_span.end_time,time_span.start_time);
1933 if(size == 0){
1934 new_time_window.start_time = time_span.start_time;
1935 new_time_window.time_width = time_delta;
1936 }else{
1937 new_time_window.time_width = ltt_time_div(new_time_window.time_width, size);
1938 if(ltt_time_compare(new_time_window.time_width,time_delta) > 0)
1939 { /* Case where zoom out is bigger than trace length */
1940 new_time_window.start_time = time_span.start_time;
1941 new_time_window.time_width = time_delta;
1942 }
1943 else
1944 {
1945 /* Center the image on the current time */
1946 new_time_window.start_time =
1947 ltt_time_sub(current_time, ltt_time_div(new_time_window.time_width, 2.0));
1948 /* If on borders, don't fall off */
1949 if(ltt_time_compare(new_time_window.start_time, time_span.start_time) <0)
1950 {
1951 new_time_window.start_time = time_span.start_time;
1952 }
1953 else
1954 {
1955 if(ltt_time_compare(
1956 ltt_time_add(new_time_window.start_time, new_time_window.time_width),
1957 time_span.end_time) > 0)
1958 {
1959 new_time_window.start_time =
1960 ltt_time_sub(time_span.end_time, new_time_window.time_width);
1961 }
1962 }
1963
1964 }
1965
1966 //time_tmp = ltt_time_div(new_time_window.time_width, 2);
1967 //if(ltt_time_compare(current_time, time_tmp) < 0){
1968 // time_s = time_span->startTime;
1969 //} else {
1970 // time_s = ltt_time_sub(current_time,time_tmp);
1971 //}
1972 //time_e = ltt_time_add(current_time,time_tmp);
1973 //if(ltt_time_compare(time_span->startTime, time_s) > 0){
1974 // time_s = time_span->startTime;
1975 //}else if(ltt_time_compare(time_span->endTime, time_e) < 0){
1976 // time_e = time_span->endTime;
1977 // time_s = ltt_time_sub(time_e,new_time_window.time_width);
1978 //}
1979 //new_time_window.start_time = time_s;
1980 }
1981
1982 //lttvwindow_report_time_window(mw_data, &new_time_window);
1983 //call_pending_read_hooks(mw_data);
1984
1985 //lttvwindow_report_current_time(mw_data,&(tab->current_time));
1986 //set_time_window(tab, &new_time_window);
1987 // in expose now call_pending_read_hooks(mw_data);
1988 //gtk_multi_vpaned_set_adjust(tab->multi_vpaned, &new_time_window, FALSE);
1989 //
1990 //
1991
1992 LttTime rel_time =
1993 ltt_time_sub(new_time_window.start_time, time_span.start_time);
1994 if( ltt_time_to_double(new_time_window.time_width)
1995 * NANOSECONDS_PER_SECOND
1996 / SCROLL_STEP_PER_PAGE/* step increment */
1997 +
1998 ltt_time_to_double(rel_time) * NANOSECONDS_PER_SECOND /* page size */
1999 ==
2000 ltt_time_to_double(rel_time) * NANOSECONDS_PER_SECOND /* page size */
2001 ) {
2002 g_warning("Can not zoom that far due to scrollbar precision");
2003 } else if(
2004 ltt_time_compare(
2005 ltt_time_from_double(
2006 ltt_time_to_double(new_time_window.time_width)
2007 /SCROLL_STEP_PER_PAGE ),
2008 ltt_time_zero)
2009 == 0 ) {
2010 g_warning("Can not zoom that far due to time nanosecond precision");
2011 } else {
2012 /* Set scrollbar */
2013 GtkAdjustment *adjustment = gtk_range_get_adjustment(GTK_RANGE(tab->scrollbar));
2014
2015 g_object_set(G_OBJECT(adjustment),
2016 //"value",
2017 //ltt_time_to_double(new_time_window.start_time)
2018 // * NANOSECONDS_PER_SECOND, /* value */
2019 "lower",
2020 0.0, /* lower */
2021 "upper",
2022 ltt_time_to_double(
2023 ltt_time_sub(time_span.end_time, time_span.start_time))
2024 * NANOSECONDS_PER_SECOND, /* upper */
2025 "step_increment",
2026 ltt_time_to_double(new_time_window.time_width)
2027 / SCROLL_STEP_PER_PAGE
2028 * NANOSECONDS_PER_SECOND, /* step increment */
2029 "page_increment",
2030 ltt_time_to_double(new_time_window.time_width)
2031 * NANOSECONDS_PER_SECOND, /* page increment */
2032 "page_size",
2033 ltt_time_to_double(new_time_window.time_width)
2034 * NANOSECONDS_PER_SECOND, /* page size */
2035 NULL);
2036 gtk_adjustment_changed(adjustment);
2037 //gtk_range_set_adjustment(GTK_RANGE(tab->scrollbar), adjustment);
2038 //gtk_adjustment_value_changed(adjustment);
2039 g_object_set(G_OBJECT(adjustment),
2040 "value",
2041 ltt_time_to_double(
2042 ltt_time_sub(new_time_window.start_time, time_span.start_time))
2043 * NANOSECONDS_PER_SECOND, /* value */
2044 NULL);
2045 gtk_adjustment_value_changed(adjustment);
2046
2047
2048 //g_object_set(G_OBJECT(adjustment),
2049 // "value",
2050 // ltt_time_to_double(time_window->start_time)
2051 // * NANOSECONDS_PER_SECOND, /* value */
2052 // NULL);
2053 /* Note : the set value will call set_time_window if scrollbar value changed
2054 */
2055 //gtk_adjustment_set_value(adjustment,
2056 // ltt_time_to_double(new_time_window.start_time)
2057 // * NANOSECONDS_PER_SECOND);
2058 }
2059 }
2060
2061 void zoom_in(GtkWidget * widget, gpointer user_data)
2062 {
2063 zoom(widget, 2);
2064 }
2065
2066 void zoom_out(GtkWidget * widget, gpointer user_data)
2067 {
2068 zoom(widget, 0.5);
2069 }
2070
2071 void zoom_extended(GtkWidget * widget, gpointer user_data)
2072 {
2073 zoom(widget, 0);
2074 }
2075
2076 void go_to_time(GtkWidget * widget, gpointer user_data)
2077 {
2078 g_printf("Go to time\n");
2079 }
2080
2081 void show_time_frame(GtkWidget * widget, gpointer user_data)
2082 {
2083 g_printf("Show time frame\n");
2084 }
2085
2086
2087 /* callback function */
2088
2089 void
2090 on_empty_traceset_activate (GtkMenuItem *menuitem,
2091 gpointer user_data)
2092 {
2093 create_new_window((GtkWidget*)menuitem, user_data, FALSE);
2094 }
2095
2096
2097 void
2098 on_clone_traceset_activate (GtkMenuItem *menuitem,
2099 gpointer user_data)
2100 {
2101 create_new_window((GtkWidget*)menuitem, user_data, TRUE);
2102 }
2103
2104
2105 /* create_new_tab calls create_tab to construct a new tab in the main window
2106 */
2107
2108 Tab *create_new_tab(GtkWidget* widget, gpointer user_data){
2109 gchar label[PATH_MAX];
2110 MainWindow * mw_data = get_window_data_struct(widget);
2111
2112 GtkNotebook * notebook = (GtkNotebook *)lookup_widget(widget, "MNotebook");
2113 if(notebook == NULL){
2114 g_printf("Notebook does not exist\n");
2115 return NULL;
2116 }
2117 GtkWidget *page = gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook),
2118 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook)));
2119 Tab *copy_tab;
2120
2121 if(!page) {
2122 copy_tab = NULL;
2123 } else {
2124 copy_tab = (Tab *)g_object_get_data(G_OBJECT(page), "Tab_Info");
2125 }
2126
2127 strcpy(label,"Page");
2128 if(get_label(mw_data, label,"Get the name of the tab","Please input tab's name"))
2129 return (create_tab (mw_data, copy_tab, notebook, label));
2130 }
2131
2132 void
2133 on_tab_activate (GtkMenuItem *menuitem,
2134 gpointer user_data)
2135 {
2136 create_new_tab((GtkWidget*)menuitem, user_data);
2137 }
2138
2139
2140 void
2141 on_open_activate (GtkMenuItem *menuitem,
2142 gpointer user_data)
2143 {
2144 open_traceset((GtkWidget*)menuitem, user_data);
2145 }
2146
2147
2148 void
2149 on_close_activate (GtkMenuItem *menuitem,
2150 gpointer user_data)
2151 {
2152 MainWindow * mw_data = get_window_data_struct((GtkWidget*)menuitem);
2153 main_window_destructor(mw_data);
2154 }
2155
2156
2157 /* remove the current tab from the main window
2158 */
2159
2160 void
2161 on_close_tab_activate (GtkWidget *widget,
2162 gpointer user_data)
2163 {
2164 gint page_num;
2165 GtkWidget * notebook;
2166 GtkWidget * page;
2167 MainWindow * mw_data = get_window_data_struct(widget);
2168 notebook = lookup_widget(widget, "MNotebook");
2169 if(notebook == NULL){
2170 g_printf("Notebook does not exist\n");
2171 return;
2172 }
2173
2174 page_num = gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook));
2175
2176 gtk_notebook_remove_page(GTK_NOTEBOOK(notebook), page_num);
2177
2178 }
2179
2180 void
2181 on_close_tab_X_clicked (GtkWidget *widget,
2182 gpointer user_data)
2183 {
2184 gint page_num;
2185 GtkWidget *notebook = lookup_widget(widget, "MNotebook");
2186 if(notebook == NULL){
2187 g_printf("Notebook does not exist\n");
2188 return;
2189 }
2190
2191 if((page_num = gtk_notebook_page_num(GTK_NOTEBOOK(notebook), widget)) != -1)
2192 gtk_notebook_remove_page(GTK_NOTEBOOK(notebook), page_num);
2193
2194 }
2195
2196
2197 void
2198 on_add_trace_activate (GtkMenuItem *menuitem,
2199 gpointer user_data)
2200 {
2201 add_trace((GtkWidget*)menuitem, user_data);
2202 }
2203
2204
2205 void
2206 on_remove_trace_activate (GtkMenuItem *menuitem,
2207 gpointer user_data)
2208 {
2209 remove_trace((GtkWidget*)menuitem, user_data);
2210 }
2211
2212
2213 void
2214 on_save_activate (GtkMenuItem *menuitem,
2215 gpointer user_data)
2216 {
2217 save((GtkWidget*)menuitem, user_data);
2218 }
2219
2220
2221 void
2222 on_save_as_activate (GtkMenuItem *menuitem,
2223 gpointer user_data)
2224 {
2225 save_as((GtkWidget*)menuitem, user_data);
2226 }
2227
2228
2229 void
2230 on_quit_activate (GtkMenuItem *menuitem,
2231 gpointer user_data)
2232 {
2233 gtk_main_quit ();
2234 }
2235
2236
2237 void
2238 on_cut_activate (GtkMenuItem *menuitem,
2239 gpointer user_data)
2240 {
2241 g_printf("Cut\n");
2242 }
2243
2244
2245 void
2246 on_copy_activate (GtkMenuItem *menuitem,
2247 gpointer user_data)
2248 {
2249 g_printf("Copye\n");
2250 }
2251
2252
2253 void
2254 on_paste_activate (GtkMenuItem *menuitem,
2255 gpointer user_data)
2256 {
2257 g_printf("Paste\n");
2258 }
2259
2260
2261 void
2262 on_delete_activate (GtkMenuItem *menuitem,
2263 gpointer user_data)
2264 {
2265 g_printf("Delete\n");
2266 }
2267
2268
2269 void
2270 on_zoom_in_activate (GtkMenuItem *menuitem,
2271 gpointer user_data)
2272 {
2273 zoom_in((GtkWidget*)menuitem, user_data);
2274 }
2275
2276
2277 void
2278 on_zoom_out_activate (GtkMenuItem *menuitem,
2279 gpointer user_data)
2280 {
2281 zoom_out((GtkWidget*)menuitem, user_data);
2282 }
2283
2284
2285 void
2286 on_zoom_extended_activate (GtkMenuItem *menuitem,
2287 gpointer user_data)
2288 {
2289 zoom_extended((GtkWidget*)menuitem, user_data);
2290 }
2291
2292
2293 void
2294 on_go_to_time_activate (GtkMenuItem *menuitem,
2295 gpointer user_data)
2296 {
2297 go_to_time((GtkWidget*)menuitem, user_data);
2298 }
2299
2300
2301 void
2302 on_show_time_frame_activate (GtkMenuItem *menuitem,
2303 gpointer user_data)
2304 {
2305 show_time_frame((GtkWidget*)menuitem, user_data);
2306 }
2307
2308
2309 void
2310 on_move_viewer_up_activate (GtkMenuItem *menuitem,
2311 gpointer user_data)
2312 {
2313 move_up_viewer((GtkWidget*)menuitem, user_data);
2314 }
2315
2316
2317 void
2318 on_move_viewer_down_activate (GtkMenuItem *menuitem,
2319 gpointer user_data)
2320 {
2321 move_down_viewer((GtkWidget*)menuitem, user_data);
2322 }
2323
2324
2325 void
2326 on_remove_viewer_activate (GtkMenuItem *menuitem,
2327 gpointer user_data)
2328 {
2329 delete_viewer((GtkWidget*)menuitem, user_data);
2330 }
2331
2332 #if 0
2333 void
2334 on_trace_filter_activate (GtkMenuItem *menuitem,
2335 gpointer user_data)
2336 {
2337 MainWindow * mw_data = get_window_data_struct((GtkWidget*)menuitem);
2338 LttvTracesetSelector * s;
2339 GtkWidget * w;
2340 GtkWidget * notebook = lookup_widget(GTK_WIDGET(menuitem), "MNotebook");
2341
2342 GtkWidget *page = gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook),
2343 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook)));
2344 Tab *tab;
2345
2346 if(!page) {
2347 return;
2348 } else {
2349 tab = (Tab *)g_object_get_data(G_OBJECT(page), "Tab_Info");
2350 }
2351
2352 w = gtk_multivpaned_get_widget(GTK_MULTIVPANED(tab->multivpaned));
2353
2354 s = g_object_get_data(G_OBJECT(w), "Traceset_Selector");
2355 if(!s){
2356 g_printf("There is no viewer yet\n");
2357 return;
2358 }
2359 if(get_filter_selection(s, "Configure trace and tracefile filter", "Select traces and tracefiles")){
2360 //FIXME report filter change
2361 //update_traceset(mw_data);
2362 //call_pending_read_hooks(mw_data);
2363 //lttvwindow_report_current_time(mw_data,&(tab->current_time));
2364 }
2365 }
2366 #endif //0
2367
2368 void
2369 on_trace_facility_activate (GtkMenuItem *menuitem,
2370 gpointer user_data)
2371 {
2372 g_printf("Trace facility selector: %s\n");
2373 }
2374
2375
2376 /* Dispaly a file selection dialogue to let user select a library, then call
2377 * lttv_library_load().
2378 */
2379
2380 void
2381 on_load_library_activate (GtkMenuItem *menuitem,
2382 gpointer user_data)
2383 {
2384 GError *error = NULL;
2385 MainWindow * mw_data = get_window_data_struct((GtkWidget*)menuitem);
2386
2387 gchar load_module_path_alter[PATH_MAX];
2388 {
2389 GPtrArray *name;
2390 guint nb,i;
2391 gchar *load_module_path;
2392 name = g_ptr_array_new();
2393 nb = lttv_library_path_number();
2394 /* ask for the library path */
2395
2396 for(i=0;i<nb;i++){
2397 gchar *path;
2398 path = lttv_library_path_get(i);
2399 g_ptr_array_add(name, path);
2400 }
2401
2402 load_module_path = get_selection((char **)(name->pdata), name->len,
2403 "Select a library path", "Library paths");
2404 if(load_module_path != NULL)
2405 strncpy(load_module_path_alter, load_module_path, PATH_MAX-1); // -1 for /
2406
2407 g_ptr_array_free(name, TRUE);
2408
2409 if(load_module_path == NULL) return;
2410 }
2411
2412 {
2413 /* Make sure the module path ends with a / */
2414 gchar *ptr = load_module_path_alter;
2415
2416 ptr = strchr(ptr, '\0');
2417
2418 if(*(ptr-1) != '/') {
2419 *ptr = '/';
2420 *(ptr+1) = '\0';
2421 }
2422 }
2423
2424 {
2425 /* Ask for the library to load : list files in the previously selected
2426 * directory */
2427 gchar str[PATH_MAX];
2428 gchar ** dir;
2429 gint id;
2430 GtkFileSelection * file_selector =
2431 (GtkFileSelection *)gtk_file_selection_new("Select a module");
2432 gtk_file_selection_set_filename(file_selector, load_module_path_alter);
2433 gtk_file_selection_hide_fileop_buttons(file_selector);
2434
2435 str[0] = '\0';
2436 id = gtk_dialog_run(GTK_DIALOG(file_selector));
2437 switch(id){
2438 case GTK_RESPONSE_ACCEPT:
2439 case GTK_RESPONSE_OK:
2440 dir = gtk_file_selection_get_selections (file_selector);
2441 strncpy(str,dir[0],PATH_MAX);
2442 strncpy(remember_plugins_dir,dir[0],PATH_MAX);
2443 /* only keep file name */
2444 gchar *str1;
2445 str1 = strrchr(str,'/');
2446 if(str1)str1++;
2447 else{
2448 str1 = strrchr(str,'\\');
2449 str1++;
2450 }
2451 #if 0
2452 /* remove "lib" */
2453 if(*str1 == 'l' && *(str1+1)== 'i' && *(str1+2)=='b')
2454 str1=str1+3;
2455 remove info after . */
2456 {
2457 gchar *str2 = str1;
2458
2459 str2 = strrchr(str2, '.');
2460 if(str2 != NULL) *str2 = '\0';
2461 }
2462 lttv_module_require(str1, &error);
2463 #endif //0
2464 lttv_library_load(str1, &error);
2465 if(error != NULL) g_warning(error->message);
2466 else g_printf("Load library: %s\n", str);
2467 g_strfreev(dir);
2468 case GTK_RESPONSE_REJECT:
2469 case GTK_RESPONSE_CANCEL:
2470 default:
2471 gtk_widget_destroy((GtkWidget*)file_selector);
2472 break;
2473 }
2474
2475 }
2476
2477
2478
2479 }
2480
2481
2482 /* Display all loaded modules, let user to select a module to unload
2483 * by calling lttv_module_unload
2484 */
2485
2486 void
2487 on_unload_library_activate (GtkMenuItem *menuitem,
2488 gpointer user_data)
2489 {
2490 MainWindow * mw_data = get_window_data_struct((GtkWidget*)menuitem);
2491
2492 LttvLibrary *library;
2493 {
2494 GPtrArray *name;
2495 guint nb,i;
2496 gchar *lib_name;
2497 name = g_ptr_array_new();
2498 nb = lttv_library_number();
2499 LttvLibraryInfo *lib_info = g_new(LttvLibraryInfo,nb);
2500 /* ask for the library name */
2501
2502 for(i=0;i<nb;i++){
2503 LttvLibrary *iter_lib = lttv_library_get(i);
2504 lttv_library_info(iter_lib, &lib_info[i]);
2505
2506 gchar *path = lib_info[i].name;
2507 g_ptr_array_add(name, lib_info[i].name);
2508 }
2509 lib_name = get_selection((char **)(name->pdata), name->len,
2510 "Select a library", "Libraries");
2511 if(lib_name != NULL) {
2512 for(i=0;i<nb;i++){
2513 if(strcmp(lib_name, lib_info[i].name) == 0) {
2514 library = lttv_library_get(i);
2515 break;
2516 }
2517 }
2518 }
2519 g_ptr_array_free(name, TRUE);
2520 g_free(lib_info);
2521
2522 if(lib_name == NULL) return;
2523 }
2524
2525 lttv_library_unload(library);
2526 }
2527
2528
2529 /* Dispaly a file selection dialogue to let user select a module, then call
2530 * lttv_module_require().
2531 */
2532
2533 void
2534 on_load_module_activate (GtkMenuItem *menuitem,
2535 gpointer user_data)
2536 {
2537 GError *error = NULL;
2538 MainWindow * mw_data = get_window_data_struct((GtkWidget*)menuitem);
2539
2540 LttvLibrary *library;
2541 {
2542 GPtrArray *name;
2543 guint nb,i;
2544 gchar *lib_name;
2545 name = g_ptr_array_new();
2546 nb = lttv_library_number();
2547 LttvLibraryInfo *lib_info = g_new(LttvLibraryInfo,nb);
2548 /* ask for the library name */
2549
2550 for(i=0;i<nb;i++){
2551 LttvLibrary *iter_lib = lttv_library_get(i);
2552 lttv_library_info(iter_lib, &lib_info[i]);
2553
2554 gchar *path = lib_info[i].name;
2555 g_ptr_array_add(name, path);
2556 }
2557 lib_name = get_selection((char **)(name->pdata), name->len,
2558 "Select a library", "Libraries");
2559 if(lib_name != NULL) {
2560 for(i=0;i<nb;i++){
2561 if(strcmp(lib_name, lib_info[i].name) == 0) {
2562 library = lttv_library_get(i);
2563 break;
2564 }
2565 }
2566 }
2567 g_ptr_array_free(name, TRUE);
2568 g_free(lib_info);
2569
2570 if(lib_name == NULL) return;
2571 }
2572
2573 //LttvModule *module;
2574 gchar module_name_out[PATH_MAX];
2575 {
2576 /* Ask for the module to load : list modules in the selected lib */
2577 GPtrArray *name;
2578 guint nb,i;
2579 gchar *module_name;
2580 LttvModuleInfo *module_info = g_new(LttvModuleInfo,nb);
2581 name = g_ptr_array_new();
2582 nb = lttv_library_module_number(library);
2583 /* ask for the module name */
2584
2585 for(i=0;i<nb;i++){
2586 LttvModule *iter_module = lttv_library_module_get(library, i);
2587 lttv_module_info(iter_module, &module_info[i]);
2588
2589 gchar *path = module_info[i].name;
2590 g_ptr_array_add(name, path);
2591 }
2592 module_name = get_selection((char **)(name->pdata), name->len,
2593 "Select a module", "Modules");
2594 if(module_name != NULL) {
2595 for(i=0;i<nb;i++){
2596 if(strcmp(module_name, module_info[i].name) == 0) {
2597 strncpy(module_name_out, module_name, PATH_MAX);
2598 //module = lttv_library_module_get(i);
2599 break;
2600 }
2601 }
2602 }
2603
2604 g_ptr_array_free(name, TRUE);
2605 g_free(module_info);
2606
2607 if(module_name == NULL) return;
2608 }
2609
2610 lttv_module_require(module_name_out, &error);
2611 if(error != NULL) g_warning(error->message);
2612 else g_printf("Load module: %s\n", module_name_out);
2613
2614
2615 #if 0
2616 {
2617
2618
2619 gchar str[PATH_MAX];
2620 gchar ** dir;
2621 gint id;
2622 GtkFileSelection * file_selector =
2623 (GtkFileSelection *)gtk_file_selection_new("Select a module");
2624 gtk_file_selection_set_filename(file_selector, load_module_path_alter);
2625 gtk_file_selection_hide_fileop_buttons(file_selector);
2626
2627 str[0] = '\0';
2628 id = gtk_dialog_run(GTK_DIALOG(file_selector));
2629 switch(id){
2630 case GTK_RESPONSE_ACCEPT:
2631 case GTK_RESPONSE_OK:
2632 dir = gtk_file_selection_get_selections (file_selector);
2633 strncpy(str,dir[0],PATH_MAX);
2634 strncpy(remember_plugins_dir,dir[0],PATH_MAX);
2635 {
2636 /* only keep file name */
2637 gchar *str1;
2638 str1 = strrchr(str,'/');
2639 if(str1)str1++;
2640 else{
2641 str1 = strrchr(str,'\\');
2642 str1++;
2643 }
2644 #if 0
2645 /* remove "lib" */
2646 if(*str1 == 'l' && *(str1+1)== 'i' && *(str1+2)=='b')
2647 str1=str1+3;
2648 remove info after . */
2649 {
2650 gchar *str2 = str1;
2651
2652 str2 = strrchr(str2, '.');
2653 if(str2 != NULL) *str2 = '\0';
2654 }
2655 lttv_module_require(str1, &error);
2656 #endif //0
2657 lttv_library_load(str1, &error);
2658 if(error != NULL) g_warning(error->message);
2659 else g_printf("Load library: %s\n", str);
2660 g_strfreev(dir);
2661 case GTK_RESPONSE_REJECT:
2662 case GTK_RESPONSE_CANCEL:
2663 default:
2664 gtk_widget_destroy((GtkWidget*)file_selector);
2665 break;
2666 }
2667
2668 }
2669 #endif //0
2670
2671
2672 }
2673
2674
2675
2676 /* Display all loaded modules, let user to select a module to unload
2677 * by calling lttv_module_unload
2678 */
2679
2680 void
2681 on_unload_module_activate (GtkMenuItem *menuitem,
2682 gpointer user_data)
2683 {
2684 GError *error = NULL;
2685 MainWindow * mw_data = get_window_data_struct((GtkWidget*)menuitem);
2686
2687 LttvLibrary *library;
2688 {
2689 GPtrArray *name;
2690 guint nb,i;
2691 gchar *lib_name;
2692 name = g_ptr_array_new();
2693 nb = lttv_library_number();
2694 LttvLibraryInfo *lib_info = g_new(LttvLibraryInfo,nb);
2695 /* ask for the library name */
2696
2697 for(i=0;i<nb;i++){
2698 LttvLibrary *iter_lib = lttv_library_get(i);
2699 lttv_library_info(iter_lib, &lib_info[i]);
2700
2701 gchar *path = lib_info[i].name;
2702 g_ptr_array_add(name, path);
2703 }
2704 lib_name = get_selection((char **)(name->pdata), name->len,
2705 "Select a library", "Libraries");
2706 if(lib_name != NULL) {
2707 for(i=0;i<nb;i++){
2708 if(strcmp(lib_name, lib_info[i].name) == 0) {
2709 library = lttv_library_get(i);
2710 break;
2711 }
2712 }
2713 }
2714 g_ptr_array_free(name, TRUE);
2715 g_free(lib_info);
2716
2717 if(lib_name == NULL) return;
2718 }
2719
2720 LttvModule *module;
2721 {
2722 /* Ask for the module to load : list modules in the selected lib */
2723 GPtrArray *name;
2724 guint nb,i;
2725 gchar *module_name;
2726 nb = lttv_library_module_number(library);
2727 LttvModuleInfo *module_info = g_new(LttvModuleInfo,nb);
2728 name = g_ptr_array_new();
2729 /* ask for the module name */
2730
2731 for(i=0;i<nb;i++){
2732 LttvModule *iter_module = lttv_library_module_get(library, i);
2733 lttv_module_info(iter_module, &module_info[i]);
2734
2735 gchar *path = module_info[i].name;
2736 if(module_info[i].use_count > 0) g_ptr_array_add(name, path);
2737 }
2738 module_name = get_selection((char **)(name->pdata), name->len,
2739 "Select a module", "Modules");
2740 if(module_name != NULL) {
2741 for(i=0;i<nb;i++){
2742 if(strcmp(module_name, module_info[i].name) == 0) {
2743 module = lttv_library_module_get(library, i);
2744 break;
2745 }
2746 }
2747 }
2748
2749 g_ptr_array_free(name, TRUE);
2750 g_free(module_info);
2751
2752 if(module_name == NULL) return;
2753 }
2754
2755 LttvModuleInfo module_info;
2756 lttv_module_info(module, &module_info);
2757 g_printf("Release module: %s\n", module_info.name);
2758
2759 lttv_module_release(module);
2760 }
2761
2762
2763 /* Display a directory dialogue to let user select a path for library searching
2764 */
2765
2766 void
2767 on_add_library_search_path_activate (GtkMenuItem *menuitem,
2768 gpointer user_data)
2769 {
2770 GtkDirSelection * file_selector = (GtkDirSelection *)gtk_dir_selection_new("Select library path");
2771 const char * dir;
2772 gint id;
2773
2774 MainWindow * mw_data = get_window_data_struct((GtkWidget*)menuitem);
2775 if(remember_plugins_dir[0] != '\0')
2776 gtk_dir_selection_set_filename(file_selector, remember_plugins_dir);
2777
2778 id = gtk_dialog_run(GTK_DIALOG(file_selector));
2779 switch(id){
2780 case GTK_RESPONSE_ACCEPT:
2781 case GTK_RESPONSE_OK:
2782 dir = gtk_dir_selection_get_dir (file_selector);
2783 strncpy(remember_plugins_dir,dir,PATH_MAX);
2784 strncat(remember_plugins_dir,"/",PATH_MAX);
2785 lttv_library_path_add(dir);
2786 case GTK_RESPONSE_REJECT:
2787 case GTK_RESPONSE_CANCEL:
2788 default:
2789 gtk_widget_destroy((GtkWidget*)file_selector);
2790 break;
2791 }
2792 }
2793
2794
2795 /* Display a directory dialogue to let user select a path for library searching
2796 */
2797
2798 void
2799 on_remove_library_search_path_activate (GtkMenuItem *menuitem,
2800 gpointer user_data)
2801 {
2802 MainWindow * mw_data = get_window_data_struct((GtkWidget*)menuitem);
2803
2804 const char *lib_path;
2805 {
2806 GPtrArray *name;
2807 guint nb,i;
2808 gchar *lib_name;
2809 name = g_ptr_array_new();
2810 nb = lttv_library_path_number();
2811 /* ask for the library name */
2812
2813 for(i=0;i<nb;i++){
2814 gchar *path = lttv_library_path_get(i);
2815 g_ptr_array_add(name, path);
2816 }
2817 lib_path = get_selection((char **)(name->pdata), name->len,
2818 "Select a library path", "Library paths");
2819
2820 g_ptr_array_free(name, TRUE);
2821
2822 if(lib_path == NULL) return;
2823 }
2824
2825 lttv_library_path_remove(lib_path);
2826 }
2827
2828 void
2829 on_color_activate (GtkMenuItem *menuitem,
2830 gpointer user_data)
2831 {
2832 g_printf("Color\n");
2833 }
2834
2835
2836 void
2837 on_filter_activate (GtkMenuItem *menuitem,
2838 gpointer user_data)
2839 {
2840 g_printf("Filter\n");
2841 }
2842
2843
2844 void
2845 on_save_configuration_activate (GtkMenuItem *menuitem,
2846 gpointer user_data)
2847 {
2848 g_printf("Save configuration\n");
2849 }
2850
2851
2852 void
2853 on_content_activate (GtkMenuItem *menuitem,
2854 gpointer user_data)
2855 {
2856 g_printf("Content\n");
2857 }
2858
2859
2860 static void
2861 on_about_close_activate (GtkButton *button,
2862 gpointer user_data)
2863 {
2864 GtkWidget *about_widget = GTK_WIDGET(user_data);
2865
2866 gtk_widget_destroy(about_widget);
2867 }
2868
2869 void
2870 on_about_activate (GtkMenuItem *menuitem,
2871 gpointer user_data)
2872 {
2873 MainWindow *main_window = get_window_data_struct(GTK_WIDGET(menuitem));
2874 GtkWidget *window_widget = main_window->mwindow;
2875 GtkWidget *about_widget = gtk_window_new(GTK_WINDOW_TOPLEVEL);
2876 GtkWindow *about_window = GTK_WINDOW(about_widget);
2877 gint window_width, window_height;
2878
2879 gtk_window_set_title(about_window, "About Linux Trace Toolkit");
2880
2881 gtk_window_set_resizable(about_window, FALSE);
2882 gtk_window_set_transient_for(GTK_WINDOW(window_widget), about_window);
2883 gtk_window_set_destroy_with_parent(about_window, TRUE);
2884 gtk_window_set_modal(about_window, FALSE);
2885
2886 /* Put the about window at the center of the screen */
2887 gtk_window_get_size(about_window, &window_width, &window_height);
2888 gtk_window_move (about_window,
2889 (gdk_screen_width() - window_width)/2,
2890 (gdk_screen_height() - window_height)/2);
2891
2892 GtkWidget *vbox = gtk_vbox_new(FALSE, 1);
2893
2894 gtk_container_add(GTK_CONTAINER(about_widget), vbox);
2895
2896
2897 /* Text to show */
2898 GtkWidget *label1 = gtk_label_new("");
2899 gtk_misc_set_padding(GTK_MISC(label1), 10, 20);
2900 gtk_label_set_markup(GTK_LABEL(label1), "\
2901 <big>Linux Trace Toolkit</big>");
2902 gtk_label_set_justify(GTK_LABEL(label1), GTK_JUSTIFY_CENTER);
2903
2904 GtkWidget *label2 = gtk_label_new("");
2905 gtk_misc_set_padding(GTK_MISC(label2), 10, 20);
2906 gtk_label_set_markup(GTK_LABEL(label2), "\
2907 Project author: Karim Yaghmour\n\
2908 \n\
2909 Contributors :\n\
2910 \n\
2911 Michel Dagenais (New trace format, lttv main)\n\
2912 Mathieu Desnoyers (Directory structure, build with automake/conf,\n\
2913 lttv gui, control flow view, gui green threads\n\
2914 with interruptible foreground and background computation,\n\
2915 detailed event list)\n\
2916 Benoit Des Ligneris (Cluster adaptation)\n\
2917 Xang-Xiu Yang (new trace reading library and converter, lttv gui, \n\
2918 detailed event list and statistics view)\n\
2919 Tom Zanussi (RelayFS)");
2920
2921 GtkWidget *label3 = gtk_label_new("");
2922 gtk_label_set_markup(GTK_LABEL(label3), "\
2923 Linux Trace Toolkit, Copyright (C) 2004 Karim Yaghmour\n\
2924 Linux Trace Toolkit comes with ABSOLUTELY NO WARRANTY.\n\
2925 This is free software, and you are welcome to redistribute it\n\
2926 under certain conditions. See COPYING for details.");
2927 gtk_misc_set_padding(GTK_MISC(label3), 10, 20);
2928
2929 gtk_box_pack_start_defaults(GTK_BOX(vbox), label1);
2930 gtk_box_pack_start_defaults(GTK_BOX(vbox), label2);
2931 gtk_box_pack_start_defaults(GTK_BOX(vbox), label3);
2932
2933 GtkWidget *hbox = gtk_hbox_new(TRUE, 0);
2934 gtk_box_pack_end(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
2935 GtkWidget *close_button = gtk_button_new_with_mnemonic("_Close");
2936 gtk_box_pack_end(GTK_BOX(hbox), close_button, FALSE, FALSE, 0);
2937 gtk_container_set_border_width(GTK_CONTAINER(close_button), 20);
2938
2939 g_signal_connect(G_OBJECT(close_button), "clicked",
2940 G_CALLBACK(on_about_close_activate),
2941 (gpointer)about_widget);
2942
2943 gtk_widget_show_all(about_widget);
2944 }
2945
2946
2947 void
2948 on_button_new_clicked (GtkButton *button,
2949 gpointer user_data)
2950 {
2951 create_new_window((GtkWidget*)button, user_data, TRUE);
2952 }
2953
2954 void
2955 on_button_new_tab_clicked (GtkButton *button,
2956 gpointer user_data)
2957 {
2958 create_new_tab((GtkWidget*)button, user_data);
2959 }
2960
2961 void
2962 on_button_open_clicked (GtkButton *button,
2963 gpointer user_data)
2964 {
2965 open_traceset((GtkWidget*)button, user_data);
2966 }
2967
2968
2969 void
2970 on_button_add_trace_clicked (GtkButton *button,
2971 gpointer user_data)
2972 {
2973 add_trace((GtkWidget*)button, user_data);
2974 }
2975
2976
2977 void
2978 on_button_remove_trace_clicked (GtkButton *button,
2979 gpointer user_data)
2980 {
2981 remove_trace((GtkWidget*)button, user_data);
2982 }
2983
2984 void
2985 on_button_redraw_clicked (GtkButton *button,
2986 gpointer user_data)
2987 {
2988 redraw((GtkWidget*)button, user_data);
2989 }
2990
2991 void
2992 on_button_continue_processing_clicked (GtkButton *button,
2993 gpointer user_data)
2994 {
2995 continue_processing((GtkWidget*)button, user_data);
2996 }
2997
2998 void
2999 on_button_stop_processing_clicked (GtkButton *button,
3000 gpointer user_data)
3001 {
3002 stop_processing((GtkWidget*)button, user_data);
3003 }
3004
3005
3006
3007 void
3008 on_button_save_clicked (GtkButton *button,
3009 gpointer user_data)
3010 {
3011 save((GtkWidget*)button, user_data);
3012 }
3013
3014
3015 void
3016 on_button_save_as_clicked (GtkButton *button,
3017 gpointer user_data)
3018 {
3019 save_as((GtkWidget*)button, user_data);
3020 }
3021
3022
3023 void
3024 on_button_zoom_in_clicked (GtkButton *button,
3025 gpointer user_data)
3026 {
3027 zoom_in((GtkWidget*)button, user_data);
3028 }
3029
3030
3031 void
3032 on_button_zoom_out_clicked (GtkButton *button,
3033 gpointer user_data)
3034 {
3035 zoom_out((GtkWidget*)button, user_data);
3036 }
3037
3038
3039 void
3040 on_button_zoom_extended_clicked (GtkButton *button,
3041 gpointer user_data)
3042 {
3043 zoom_extended((GtkWidget*)button, user_data);
3044 }
3045
3046
3047 void
3048 on_button_go_to_time_clicked (GtkButton *button,
3049 gpointer user_data)
3050 {
3051 go_to_time((GtkWidget*)button, user_data);
3052 }
3053
3054
3055 void
3056 on_button_show_time_frame_clicked (GtkButton *button,
3057 gpointer user_data)
3058 {
3059 show_time_frame((GtkWidget*)button, user_data);
3060 }
3061
3062
3063 void
3064 on_button_move_up_clicked (GtkButton *button,
3065 gpointer user_data)
3066 {
3067 move_up_viewer((GtkWidget*)button, user_data);
3068 }
3069
3070
3071 void
3072 on_button_move_down_clicked (GtkButton *button,
3073 gpointer user_data)
3074 {
3075 move_down_viewer((GtkWidget*)button, user_data);
3076 }
3077
3078
3079 void
3080 on_button_delete_viewer_clicked (GtkButton *button,
3081 gpointer user_data)
3082 {
3083 delete_viewer((GtkWidget*)button, user_data);
3084 }
3085
3086 void
3087 on_MWindow_destroy (GtkWidget *widget,
3088 gpointer user_data)
3089 {
3090 MainWindow *main_window = get_window_data_struct(widget);
3091 LttvIAttribute *attributes = main_window->attributes;
3092 LttvAttributeValue value;
3093
3094 //This is unnecessary, since widgets will be destroyed
3095 //by the main window widget anyway.
3096 //remove_all_menu_toolbar_constructors(main_window, NULL);
3097
3098 g_assert(lttv_iattribute_find_by_path(attributes,
3099 "viewers/menu", LTTV_POINTER, &value));
3100 lttv_menus_destroy((LttvMenus*)*(value.v_pointer));
3101
3102 g_assert(lttv_iattribute_find_by_path(attributes,
3103 "viewers/toolbar", LTTV_POINTER, &value));
3104 lttv_toolbars_destroy((LttvToolbars*)*(value.v_pointer));
3105
3106 g_object_unref(main_window->attributes);
3107 g_main_window_list = g_slist_remove(g_main_window_list, main_window);
3108
3109 g_printf("There are now : %d windows\n",g_slist_length(g_main_window_list));
3110 if(g_slist_length(g_main_window_list) == 0)
3111 gtk_main_quit ();
3112 }
3113
3114 gboolean
3115 on_MWindow_configure (GtkWidget *widget,
3116 GdkEventConfigure *event,
3117 gpointer user_data)
3118 {
3119 MainWindow * mw_data = get_window_data_struct((GtkWidget*)widget);
3120 float width = event->width;
3121 TimeWindow time_win;
3122 double ratio;
3123 TimeInterval *time_span;
3124 LttTime time;
3125
3126 // MD : removed time width modification upon resizing of the main window.
3127 // The viewers will redraw themselves completely, without time interval
3128 // modification.
3129 /* while(tab){
3130 if(mw_data->window_width){
3131 time_span = LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context)->Time_Span ;
3132 time_win = tab->time_window;
3133 ratio = width / mw_data->window_width;
3134 tab->time_window.time_width = ltt_time_mul(time_win.time_width,ratio);
3135 time = ltt_time_sub(time_span->endTime, time_win.start_time);
3136 if(ltt_time_compare(time, tab->time_window.time_width) < 0){
3137 tab->time_window.time_width = time;
3138 }
3139 }
3140 tab = tab->next;
3141 }
3142
3143 mw_data->window_width = (int)width;
3144 */
3145 return FALSE;
3146 }
3147
3148 /* Set current tab
3149 */
3150
3151 void
3152 on_MNotebook_switch_page (GtkNotebook *notebook,
3153 GtkNotebookPage *page,
3154 guint page_num,
3155 gpointer user_data)
3156 {
3157
3158 }
3159
3160
3161 void scroll_value_changed_cb(GtkWidget *scrollbar,
3162 gpointer user_data)
3163 {
3164 Tab *tab = (Tab *)user_data;
3165 TimeWindow time_window;
3166 LttTime time;
3167 GtkAdjustment *adjust = gtk_range_get_adjustment(GTK_RANGE(scrollbar));
3168 gdouble value = gtk_adjustment_get_value(adjust);
3169 gdouble upper, lower, ratio, page_size;
3170 LttvTracesetContext * tsc =
3171 LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context);
3172 TimeInterval time_span = tsc->time_span;
3173
3174 //time_window = tab->time_window;
3175
3176 lower = adjust->lower;
3177 upper = adjust->upper;
3178 ratio = (value - lower) / (upper - lower);
3179 g_info("lower %lu, upper %lu, value %lu, ratio %lu", lower, upper, value, ratio);
3180
3181 //time = ltt_time_sub(time_span->end_time, time_span->start_time);
3182 //time = ltt_time_mul(time, (float)ratio);
3183 //time = ltt_time_add(time_span->start_time, time);
3184 time = ltt_time_add(ltt_time_from_double(value/NANOSECONDS_PER_SECOND),
3185 time_span.start_time);
3186
3187 time_window.start_time = time;
3188
3189 page_size = adjust->page_size;
3190
3191 time_window.time_width =
3192 ltt_time_from_double(page_size/NANOSECONDS_PER_SECOND);
3193 //time = ltt_time_sub(time_span.end_time, time);
3194 //if(ltt_time_compare(time,time_window.time_width) < 0){
3195 // time_window.time_width = time;
3196 //}
3197
3198 /* call viewer hooks for new time window */
3199 set_time_window(tab, &time_window);
3200
3201 }
3202
3203
3204 /* callback function to check or uncheck the check box (filter)
3205 */
3206
3207 void checkbox_changed(GtkTreeView *treeview,
3208 GtkTreePath *arg1,
3209 GtkTreeViewColumn *arg2,
3210 gpointer user_data)
3211 {
3212 GtkTreeStore * store = (GtkTreeStore *)gtk_tree_view_get_model (treeview);
3213 GtkTreeIter iter;
3214 gboolean value;
3215
3216 if (gtk_tree_model_get_iter ((GtkTreeModel *)store, &iter, arg1)){
3217 gtk_tree_model_get ((GtkTreeModel *)store, &iter, CHECKBOX_COLUMN, &value, -1);
3218 value = value? FALSE : TRUE;
3219 gtk_tree_store_set (GTK_TREE_STORE (store), &iter, CHECKBOX_COLUMN, value, -1);
3220 }
3221
3222 }
3223
3224
3225 /* According to user's selection, update selector(filter)
3226 */
3227
3228 void update_filter(LttvTracesetSelector *s, GtkTreeStore *store )
3229 {
3230 GtkTreeIter iter, child_iter, child_iter1, child_iter2;
3231 int i, j, k, nb_eventtype;
3232 LttvTraceSelector * trace;
3233 LttvTracefileSelector * tracefile;
3234 LttvEventtypeSelector * eventtype;
3235 gboolean value, value1, value2;
3236
3237 if(gtk_tree_model_get_iter_first((GtkTreeModel*)store, &iter)){
3238 i = 0;
3239 do{
3240 trace = lttv_traceset_selector_trace_get(s, i);
3241 nb_eventtype = lttv_trace_selector_eventtype_number(trace);
3242 gtk_tree_model_get ((GtkTreeModel*)store, &iter, CHECKBOX_COLUMN, &value,-1);
3243 if(value){
3244 j = 0;
3245 if(gtk_tree_model_iter_children ((GtkTreeModel*)store, &child_iter, &iter)){
3246 do{
3247 if(j<1){//eventtype selector for trace
3248 gtk_tree_model_get ((GtkTreeModel*)store, &child_iter, CHECKBOX_COLUMN, &value2,-1);
3249 if(value2){
3250 k=0;
3251 if(gtk_tree_model_iter_children ((GtkTreeModel*)store, &child_iter1, &child_iter)){
3252 do{
3253 eventtype = lttv_trace_selector_eventtype_get(trace,k);
3254 gtk_tree_model_get ((GtkTreeModel*)store, &child_iter1, CHECKBOX_COLUMN, &value2,-1);
3255 lttv_eventtype_selector_set_selected(eventtype,value2);
3256 k++;
3257 }while(gtk_tree_model_iter_next((GtkTreeModel*)store, &child_iter1));
3258 }
3259 }
3260 }else{ //tracefile selector
3261 tracefile = lttv_trace_selector_tracefile_get(trace, j - 1);
3262 gtk_tree_model_get ((GtkTreeModel*)store, &child_iter, CHECKBOX_COLUMN, &value1,-1);
3263 lttv_tracefile_selector_set_selected(tracefile,value1);
3264 if(value1){
3265 gtk_tree_model_iter_children((GtkTreeModel*)store, &child_iter1, &child_iter); //eventtype selector
3266 gtk_tree_model_get ((GtkTreeModel*)store, &child_iter1, CHECKBOX_COLUMN, &value2,-1);
3267 if(value2){
3268 k = 0;
3269 if(gtk_tree_model_iter_children ((GtkTreeModel*)store, &child_iter2, &child_iter1)){
3270 do{//eventtype selector for tracefile
3271 eventtype = lttv_tracefile_selector_eventtype_get(tracefile,k);
3272 gtk_tree_model_get ((GtkTreeModel*)store, &child_iter2, CHECKBOX_COLUMN, &value2,-1);
3273 lttv_eventtype_selector_set_selected(eventtype,value2);
3274 k++;
3275 }while(gtk_tree_model_iter_next((GtkTreeModel*)store, &child_iter2));
3276 }
3277 }
3278 }
3279 }
3280 j++;
3281 }while(gtk_tree_model_iter_next((GtkTreeModel*)store, &child_iter));
3282 }
3283 }
3284 lttv_trace_selector_set_selected(trace,value);
3285 i++;
3286 }while(gtk_tree_model_iter_next((GtkTreeModel*)store, &iter));
3287 }
3288 }
3289
3290
3291 /* Display a dialogue showing all eventtypes and traces, let user to select the interested
3292 * eventtypes, tracefiles and traces (filter)
3293 */
3294
3295 gboolean get_filter_selection(LttvTracesetSelector *s,char *title, char * column_title)
3296 {
3297 GtkWidget * dialogue;
3298 GtkTreeStore * store;
3299 GtkWidget * tree;
3300 GtkWidget * scroll_win;
3301 GtkCellRenderer * renderer;
3302 GtkTreeViewColumn * column;
3303 GtkTreeIter iter, child_iter, child_iter1, child_iter2;
3304 int i, j, k, id, nb_trace, nb_tracefile, nb_eventtype;
3305 LttvTraceSelector * trace;
3306 LttvTracefileSelector * tracefile;
3307 LttvEventtypeSelector * eventtype;
3308 char * name;
3309 gboolean checked;
3310
3311 dialogue = gtk_dialog_new_with_buttons(title,
3312 NULL,
3313 GTK_DIALOG_MODAL,
3314 GTK_STOCK_OK,GTK_RESPONSE_ACCEPT,
3315 GTK_STOCK_CANCEL,GTK_RESPONSE_REJECT,
3316 NULL);
3317 gtk_window_set_default_size((GtkWindow*)dialogue, 300, 500);
3318
3319 store = gtk_tree_store_new (TOTAL_COLUMNS, G_TYPE_BOOLEAN, G_TYPE_STRING);
3320 tree = gtk_tree_view_new_with_model (GTK_TREE_MODEL (store));
3321 g_object_unref (G_OBJECT (store));
3322 g_signal_connect (G_OBJECT (tree), "row-activated",
3323 G_CALLBACK (checkbox_changed),
3324 NULL);
3325
3326
3327 renderer = gtk_cell_renderer_toggle_new ();
3328 gtk_cell_renderer_toggle_set_radio((GtkCellRendererToggle *)renderer, FALSE);
3329
3330 g_object_set (G_OBJECT (renderer),"activatable", TRUE, NULL);
3331
3332 column = gtk_tree_view_column_new_with_attributes ("Checkbox",
3333 renderer,
3334 "active", CHECKBOX_COLUMN,
3335 NULL);
3336 gtk_tree_view_column_set_alignment (column, 0.5);
3337 gtk_tree_view_column_set_fixed_width (column, 20);
3338 gtk_tree_view_append_column (GTK_TREE_VIEW (tree), column);
3339
3340 renderer = gtk_cell_renderer_text_new ();
3341 column = gtk_tree_view_column_new_with_attributes (column_title,
3342 renderer,
3343 "text", NAME_COLUMN,
3344 NULL);
3345 gtk_tree_view_column_set_alignment (column, 0.0);
3346 gtk_tree_view_append_column (GTK_TREE_VIEW (tree), column);
3347 gtk_tree_view_set_headers_visible(GTK_TREE_VIEW (tree), FALSE);
3348
3349 scroll_win = gtk_scrolled_window_new (NULL, NULL);
3350 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll_win),
3351 GTK_POLICY_AUTOMATIC,GTK_POLICY_AUTOMATIC);
3352 gtk_container_add (GTK_CONTAINER (scroll_win), tree);
3353
3354 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialogue)->vbox), scroll_win,TRUE, TRUE,0);
3355
3356 gtk_widget_show(scroll_win);
3357 gtk_widget_show(tree);
3358
3359 nb_trace = lttv_traceset_selector_trace_number(s);
3360 for(i=0;i<nb_trace;i++){
3361 trace = lttv_traceset_selector_trace_get(s, i);
3362 name = lttv_trace_selector_get_name(trace);
3363 gtk_tree_store_append (store, &iter, NULL);
3364 checked = lttv_trace_selector_get_selected(trace);
3365 gtk_tree_store_set (store, &iter,
3366 CHECKBOX_COLUMN,checked,
3367 NAME_COLUMN,name,
3368 -1);
3369
3370 gtk_tree_store_append (store, &child_iter, &iter);
3371 gtk_tree_store_set (store, &child_iter,
3372 CHECKBOX_COLUMN, checked,
3373 NAME_COLUMN,"eventtype",
3374 -1);
3375
3376 nb_eventtype = lttv_trace_selector_eventtype_number(trace);
3377 for(j=0;j<nb_eventtype;j++){
3378 eventtype = lttv_trace_selector_eventtype_get(trace,j);
3379 name = lttv_eventtype_selector_get_name(eventtype);
3380 checked = lttv_eventtype_selector_get_selected(eventtype);
3381 gtk_tree_store_append (store, &child_iter1, &child_iter);
3382 gtk_tree_store_set (store, &child_iter1,
3383 CHECKBOX_COLUMN, checked,
3384 NAME_COLUMN,name,
3385 -1);
3386 }
3387
3388 nb_tracefile = lttv_trace_selector_tracefile_number(trace);
3389 for(j=0;j<nb_tracefile;j++){
3390 tracefile = lttv_trace_selector_tracefile_get(trace, j);
3391 name = lttv_tracefile_selector_get_name(tracefile);
3392 gtk_tree_store_append (store, &child_iter, &iter);
3393 checked = lttv_tracefile_selector_get_selected(tracefile);
3394 gtk_tree_store_set (store, &child_iter,
3395 CHECKBOX_COLUMN, checked,
3396 NAME_COLUMN,name,
3397 -1);
3398
3399 gtk_tree_store_append (store, &child_iter1, &child_iter);
3400 gtk_tree_store_set (store, &child_iter1,
3401 CHECKBOX_COLUMN, checked,
3402 NAME_COLUMN,"eventtype",
3403 -1);
3404
3405 for(k=0;k<nb_eventtype;k++){
3406 eventtype = lttv_tracefile_selector_eventtype_get(tracefile,k);
3407 name = lttv_eventtype_selector_get_name(eventtype);
3408 checked = lttv_eventtype_selector_get_selected(eventtype);
3409 gtk_tree_store_append (store, &child_iter2, &child_iter1);
3410 gtk_tree_store_set (store, &child_iter2,
3411 CHECKBOX_COLUMN, checked,
3412 NAME_COLUMN,name,
3413 -1);
3414 }
3415 }
3416 }
3417
3418 id = gtk_dialog_run(GTK_DIALOG(dialogue));
3419 switch(id){
3420 case GTK_RESPONSE_ACCEPT:
3421 case GTK_RESPONSE_OK:
3422 update_filter(s, store);
3423 gtk_widget_destroy(dialogue);
3424 return TRUE;
3425 case GTK_RESPONSE_REJECT:
3426 case GTK_RESPONSE_CANCEL:
3427 default:
3428 gtk_widget_destroy(dialogue);
3429 break;
3430 }
3431 return FALSE;
3432 }
3433
3434
3435 /* Select a trace which will be removed from traceset
3436 */
3437
3438 char * get_remove_trace(char ** all_trace_name, int nb_trace)
3439 {
3440 return get_selection(all_trace_name, nb_trace,
3441 "Select a trace", "Trace pathname");
3442 }
3443
3444
3445 /* Select a module which will be loaded
3446 */
3447
3448 char * get_load_module(char ** load_module_name, int nb_module)
3449 {
3450 return get_selection(load_module_name, nb_module,
3451 "Select a module to load", "Module name");
3452 }
3453
3454
3455
3456
3457 /* Select a module which will be unloaded
3458 */
3459
3460 char * get_unload_module(char ** loaded_module_name, int nb_module)
3461 {
3462 return get_selection(loaded_module_name, nb_module,
3463 "Select a module to unload", "Module name");
3464 }
3465
3466
3467 /* Display a dialogue which shows all selectable items, let user to
3468 * select one of them
3469 */
3470
3471 char * get_selection(char ** loaded_module_name, int nb_module,
3472 char *title, char * column_title)
3473 {
3474 GtkWidget * dialogue;
3475 GtkWidget * scroll_win;
3476 GtkWidget * tree;
3477 GtkListStore * store;
3478 GtkTreeViewColumn * column;
3479 GtkCellRenderer * renderer;
3480 GtkTreeSelection * select;
3481 GtkTreeIter iter;
3482 gint id, i;
3483 char * unload_module_name = NULL;
3484
3485 dialogue = gtk_dialog_new_with_buttons(title,
3486 NULL,
3487 GTK_DIALOG_MODAL,
3488 GTK_STOCK_OK,GTK_RESPONSE_ACCEPT,
3489 GTK_STOCK_CANCEL,GTK_RESPONSE_REJECT,
3490 NULL);
3491 gtk_window_set_default_size((GtkWindow*)dialogue, 500, 200);
3492
3493 scroll_win = gtk_scrolled_window_new (NULL, NULL);
3494 gtk_widget_show ( scroll_win);
3495 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll_win),
3496 GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
3497
3498 store = gtk_list_store_new (N_COLUMNS,G_TYPE_STRING);
3499 tree = gtk_tree_view_new_with_model(GTK_TREE_MODEL (store));
3500 gtk_widget_show ( tree);
3501 g_object_unref (G_OBJECT (store));
3502
3503 renderer = gtk_cell_renderer_text_new ();
3504 column = gtk_tree_view_column_new_with_attributes (column_title,
3505 renderer,
3506 "text", MODULE_COLUMN,
3507 NULL);
3508 gtk_tree_view_column_set_alignment (column, 0.5);
3509 gtk_tree_view_column_set_fixed_width (column, 150);
3510 gtk_tree_view_append_column (GTK_TREE_VIEW (tree), column);
3511
3512 select = gtk_tree_view_get_selection (GTK_TREE_VIEW (tree));
3513 gtk_tree_selection_set_mode (select, GTK_SELECTION_SINGLE);
3514
3515 gtk_container_add (GTK_CONTAINER (scroll_win), tree);
3516
3517 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialogue)->vbox), scroll_win,TRUE, TRUE,0);
3518
3519 for(i=0;i<nb_module;i++){
3520 gtk_list_store_append (store, &iter);
3521 gtk_list_store_set (store, &iter, MODULE_COLUMN,loaded_module_name[i],-1);
3522 }
3523
3524 id = gtk_dialog_run(GTK_DIALOG(dialogue));
3525 switch(id){
3526 case GTK_RESPONSE_ACCEPT:
3527 case GTK_RESPONSE_OK:
3528 if (gtk_tree_selection_get_selected (select, (GtkTreeModel**)&store, &iter)){
3529 gtk_tree_model_get ((GtkTreeModel*)store, &iter, MODULE_COLUMN, &unload_module_name, -1);
3530 }
3531 case GTK_RESPONSE_REJECT:
3532 case GTK_RESPONSE_CANCEL:
3533 default:
3534 gtk_widget_destroy(dialogue);
3535 break;
3536 }
3537
3538 return unload_module_name;
3539 }
3540
3541
3542 /* Insert all menu entry and tool buttons into this main window
3543 * for modules.
3544 *
3545 */
3546
3547 void add_all_menu_toolbar_constructors(MainWindow * mw, gpointer user_data)
3548 {
3549 int i;
3550 GdkPixbuf *pixbuf;
3551 lttvwindow_viewer_constructor constructor;
3552 LttvMenus * global_menu, * instance_menu;
3553 LttvToolbars * global_toolbar, * instance_toolbar;
3554 LttvMenuClosure *menu_item;
3555 LttvToolbarClosure *toolbar_item;
3556 LttvAttributeValue value;
3557 LttvIAttribute *global_attributes = LTTV_IATTRIBUTE(lttv_global_attributes());
3558 LttvIAttribute *attributes = mw->attributes;
3559 GtkWidget * tool_menu_title_menu, *new_widget, *pixmap;
3560
3561 g_assert(lttv_iattribute_find_by_path(global_attributes,
3562 "viewers/menu", LTTV_POINTER, &value));
3563 if(*(value.v_pointer) == NULL)
3564 *(value.v_pointer) = lttv_menus_new();
3565 global_menu = (LttvMenus*)*(value.v_pointer);
3566
3567 g_assert(lttv_iattribute_find_by_path(attributes,
3568 "viewers/menu", LTTV_POINTER, &value));
3569 if(*(value.v_pointer) == NULL)
3570 *(value.v_pointer) = lttv_menus_new();
3571 instance_menu = (LttvMenus*)*(value.v_pointer);
3572
3573
3574
3575 g_assert(lttv_iattribute_find_by_path(global_attributes,
3576 "viewers/toolbar", LTTV_POINTER, &value));
3577 if(*(value.v_pointer) == NULL)
3578 *(value.v_pointer) = lttv_toolbars_new();
3579 global_toolbar = (LttvToolbars*)*(value.v_pointer);
3580
3581 g_assert(lttv_iattribute_find_by_path(attributes,
3582 "viewers/toolbar", LTTV_POINTER, &value));
3583 if(*(value.v_pointer) == NULL)
3584 *(value.v_pointer) = lttv_toolbars_new();
3585 instance_toolbar = (LttvToolbars*)*(value.v_pointer);
3586
3587 /* Add missing menu entries to window instance */
3588 for(i=0;i<global_menu->len;i++) {
3589 menu_item = &g_array_index(global_menu, LttvMenuClosure, i);
3590
3591 //add menu_item to window instance;
3592 constructor = menu_item->con;
3593 tool_menu_title_menu = lookup_widget(mw->mwindow,"ToolMenuTitle_menu");
3594 new_widget =
3595 gtk_menu_item_new_with_mnemonic (menu_item->menu_text);
3596 gtk_container_add (GTK_CONTAINER (tool_menu_title_menu),
3597 new_widget);
3598 g_signal_connect ((gpointer) new_widget, "activate",
3599 G_CALLBACK (insert_viewer_wrap),
3600 constructor);
3601 gtk_widget_show (new_widget);
3602 lttv_menus_add(instance_menu, menu_item->con,
3603 menu_item->menu_path,
3604 menu_item->menu_text,
3605 new_widget);
3606
3607 }
3608
3609 /* Add missing toolbar entries to window instance */
3610 for(i=0;i<global_toolbar->len;i++) {
3611 toolbar_item = &g_array_index(global_toolbar, LttvToolbarClosure, i);
3612
3613 //add toolbar_item to window instance;
3614 constructor = toolbar_item->con;
3615 tool_menu_title_menu = lookup_widget(mw->mwindow,"MToolbar1");
3616 pixbuf = gdk_pixbuf_new_from_xpm_data((const char**)toolbar_item->pixmap);
3617 pixmap = gtk_image_new_from_pixbuf(pixbuf);
3618 new_widget =
3619 gtk_toolbar_append_element (GTK_TOOLBAR (tool_menu_title_menu),
3620 GTK_TOOLBAR_CHILD_BUTTON,
3621 NULL,
3622 "",
3623 toolbar_item->tooltip, NULL,
3624 pixmap, NULL, NULL);
3625 gtk_label_set_use_underline(
3626 GTK_LABEL (((GtkToolbarChild*) (
3627 g_list_last (GTK_TOOLBAR
3628 (tool_menu_title_menu)->children)->data))->label),
3629 TRUE);
3630 gtk_container_set_border_width (GTK_CONTAINER (new_widget), 1);
3631 g_signal_connect ((gpointer) new_widget,
3632 "clicked",
3633 G_CALLBACK (insert_viewer_wrap),
3634 constructor);
3635 gtk_widget_show (new_widget);
3636
3637 lttv_toolbars_add(instance_toolbar, toolbar_item->con,
3638 toolbar_item->tooltip,
3639 toolbar_item->pixmap,
3640 new_widget);
3641
3642 }
3643
3644 }
3645
3646
3647 /* Create a main window
3648 */
3649
3650 void construct_main_window(MainWindow * parent)
3651 {
3652 g_debug("construct_main_window()");
3653 GtkWidget * new_window; /* New generated main window */
3654 MainWindow * new_m_window;/* New main window structure */
3655 GtkNotebook * notebook;
3656 LttvIAttribute *attributes =
3657 LTTV_IATTRIBUTE(g_object_new(LTTV_ATTRIBUTE_TYPE, NULL));
3658 LttvAttributeValue value;
3659 Tab *new_tab;
3660
3661 new_m_window = g_new(MainWindow, 1);
3662
3663 // Add the object's information to the module's array
3664 g_main_window_list = g_slist_append(g_main_window_list, new_m_window);
3665
3666
3667 new_window = create_MWindow();
3668 gtk_widget_show (new_window);
3669
3670 new_m_window->mwindow = new_window;
3671 new_m_window->attributes = attributes;
3672
3673 g_assert(lttv_iattribute_find_by_path(attributes,
3674 "viewers/menu", LTTV_POINTER, &value));
3675 *(value.v_pointer) = lttv_menus_new();
3676
3677 g_assert(lttv_iattribute_find_by_path(attributes,
3678 "viewers/toolbar", LTTV_POINTER, &value));
3679 *(value.v_pointer) = lttv_toolbars_new();
3680
3681 add_all_menu_toolbar_constructors(new_m_window, NULL);
3682
3683 g_object_set_data_full(G_OBJECT(new_window),
3684 "main_window_data",
3685 (gpointer)new_m_window,
3686 (GDestroyNotify)g_free);
3687 //create a default tab
3688 notebook = (GtkNotebook *)lookup_widget(new_m_window->mwindow, "MNotebook");
3689 if(notebook == NULL){
3690 g_printf("Notebook does not exist\n");
3691 return;
3692 }
3693 gtk_notebook_popup_enable (GTK_NOTEBOOK(notebook));
3694 //for now there is no name field in LttvTraceset structure
3695 //Use "Traceset" as the label for the default tab
3696 if(parent) {
3697 GtkWidget * parent_notebook = lookup_widget(parent->mwindow, "MNotebook");
3698 GtkWidget *page = gtk_notebook_get_nth_page(GTK_NOTEBOOK(parent_notebook),
3699 gtk_notebook_get_current_page(GTK_NOTEBOOK(parent_notebook)));
3700 Tab *parent_tab;
3701
3702 if(!page) {
3703 parent_tab = NULL;
3704 } else {
3705 parent_tab = (Tab *)g_object_get_data(G_OBJECT(page), "Tab_Info");
3706 }
3707 new_tab = create_tab(new_m_window, parent_tab, notebook, "Traceset");
3708 } else {
3709 new_tab = create_tab(new_m_window, NULL, notebook, "Traceset");
3710 /* First window, use command line trace */
3711 if(g_init_trace != NULL){
3712 lttvwindow_add_trace(new_tab,
3713 g_init_trace);
3714
3715 LttvTraceset *traceset = new_tab->traceset_info->traceset;
3716 SetTraceset(new_tab, traceset);
3717 }
3718 }
3719
3720 g_printf("There are now : %d windows\n",g_slist_length(g_main_window_list));
3721 }
3722
3723
3724 /* Free the memory occupied by a tab structure
3725 * destroy the tab
3726 */
3727
3728 void tab_destructor(Tab * tab_instance)
3729 {
3730 int i, nb, ref_count;
3731 LttvTrace * trace;
3732
3733 if(tab_instance->attributes)
3734 g_object_unref(tab_instance->attributes);
3735
3736 if(tab_instance->interrupted_state)
3737 g_object_unref(tab_instance->interrupted_state);
3738
3739
3740 if(tab_instance->traceset_info->traceset_context != NULL){
3741 //remove state update hooks
3742 lttv_state_remove_event_hooks(
3743 (LttvTracesetState*)tab_instance->traceset_info->
3744 traceset_context);
3745 lttv_context_fini(LTTV_TRACESET_CONTEXT(tab_instance->traceset_info->
3746 traceset_context));
3747 g_object_unref(tab_instance->traceset_info->traceset_context);
3748 }
3749 if(tab_instance->traceset_info->traceset != NULL) {
3750 nb = lttv_traceset_number(tab_instance->traceset_info->traceset);
3751 for(i = 0 ; i < nb ; i++) {
3752 trace = lttv_traceset_get(tab_instance->traceset_info->traceset, i);
3753 ref_count = lttv_trace_get_ref_number(trace);
3754 if(ref_count <= 1){
3755 ltt_trace_close(lttv_trace(trace));
3756 }
3757 }
3758 }
3759 lttv_traceset_destroy(tab_instance->traceset_info->traceset);
3760 /* Remove the idle events requests processing function of the tab */
3761 g_idle_remove_by_data(tab_instance);
3762
3763 g_slist_free(tab_instance->events_requests);
3764 g_free(tab_instance->traceset_info);
3765 g_free(tab_instance);
3766 }
3767
3768
3769 /* Create a tab and insert it into the current main window
3770 */
3771
3772 Tab* create_tab(MainWindow * mw, Tab *copy_tab,
3773 GtkNotebook * notebook, char * label)
3774 {
3775 GList * list;
3776 Tab * tab;
3777 LttTime tmp_time;
3778
3779 //create a new tab data structure
3780 tab = g_new(Tab,1);
3781
3782 //construct and initialize the traceset_info
3783 tab->traceset_info = g_new(TracesetInfo,1);
3784
3785 if(copy_tab) {
3786 tab->traceset_info->traceset =
3787 lttv_traceset_copy(copy_tab->traceset_info->traceset);
3788 } else {
3789 tab->traceset_info->traceset = lttv_traceset_new();
3790 }
3791
3792 #ifdef DEBUG
3793 lttv_attribute_write_xml(
3794 lttv_traceset_attribute(tab->traceset_info->traceset),
3795 stdout,
3796 0, 4);
3797 fflush(stdout);
3798 #endif //DEBUG
3799
3800
3801 //FIXME copy not implemented in lower level
3802 tab->traceset_info->traceset_context =
3803 g_object_new(LTTV_TRACESET_STATS_TYPE, NULL);
3804 g_assert(tab->traceset_info->traceset_context != NULL);
3805 lttv_context_init(
3806 LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context),
3807 tab->traceset_info->traceset);
3808 //add state update hooks
3809 lttv_state_add_event_hooks(
3810 (LttvTracesetState*)tab->traceset_info->traceset_context);
3811
3812 //determine the current_time and time_window of the tab
3813 if(copy_tab != NULL){
3814 tab->time_window = copy_tab->time_window;
3815 tab->current_time = copy_tab->current_time;
3816 }else{
3817 tab->time_window.start_time =
3818 LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context)->
3819 time_span.start_time;
3820 if(DEFAULT_TIME_WIDTH_S <
3821 LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context)->
3822 time_span.end_time.tv_sec)
3823 tmp_time.tv_sec = DEFAULT_TIME_WIDTH_S;
3824 else
3825 tmp_time.tv_sec =
3826 LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context)->
3827 time_span.end_time.tv_sec;
3828 tmp_time.tv_nsec = 0;
3829 tab->time_window.time_width = tmp_time ;
3830 tab->current_time.tv_sec =
3831 LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context)->
3832 time_span.start_time.tv_sec;
3833 tab->current_time.tv_nsec =
3834 LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context)->
3835 time_span.start_time.tv_nsec;
3836 }
3837 tab->attributes = LTTV_IATTRIBUTE(g_object_new(LTTV_ATTRIBUTE_TYPE, NULL));
3838 tab->interrupted_state = g_object_new(LTTV_ATTRIBUTE_TYPE, NULL);
3839
3840 tab->vbox = gtk_vbox_new(FALSE, 2);
3841 tab->viewer_container = gtk_vbox_new(TRUE, 2);
3842 tab->scrollbar = gtk_hscrollbar_new(NULL);
3843 //tab->multivpaned = gtk_multi_vpaned_new();
3844
3845 gtk_box_pack_start(GTK_BOX(tab->vbox),
3846 tab->viewer_container,
3847 TRUE, /* expand */
3848 TRUE, /* Give the extra space to the child */
3849 0); /* No padding */
3850
3851 gtk_box_pack_end(GTK_BOX(tab->vbox),
3852 tab->scrollbar,
3853 FALSE, /* Do not expand */
3854 FALSE, /* Fill has no effect here (expand false) */
3855 0); /* No padding */
3856
3857 g_object_set_data(G_OBJECT(tab->viewer_container), "focused_viewer", NULL);
3858
3859
3860 tab->mw = mw;
3861
3862 /*{
3863 // Display a label with a X
3864 GtkWidget *w_hbox = gtk_hbox_new(FALSE, 4);
3865 GtkWidget *w_label = gtk_label_new (label);
3866 GtkWidget *pixmap = create_pixmap(GTK_WIDGET(notebook), "close.png");
3867 GtkWidget *w_button = gtk_button_new ();
3868 gtk_container_add(GTK_CONTAINER(w_button), pixmap);
3869 //GtkWidget *w_button = gtk_button_new_with_label("x");
3870
3871 gtk_button_set_relief(GTK_BUTTON(w_button), GTK_RELIEF_NONE);
3872
3873 gtk_box_pack_start(GTK_BOX(w_hbox), w_label, TRUE, TRUE, 0);
3874 gtk_box_pack_end(GTK_BOX(w_hbox), w_button, FALSE,
3875 FALSE, 0);
3876
3877 g_signal_connect_swapped (w_button, "clicked",
3878 G_CALLBACK (on_close_tab_X_clicked),
3879 tab->multi_vpaned);
3880
3881 gtk_widget_set_state(w_button, GTK_STATE_ACTIVE);
3882
3883 gtk_widget_show (w_label);
3884 gtk_widget_show (pixmap);
3885 gtk_widget_show (w_button);
3886 gtk_widget_show (w_hbox);
3887
3888 tab->label = w_hbox;
3889 }*/
3890
3891
3892 tab->label = gtk_label_new (label);
3893
3894 gtk_widget_show(tab->label);
3895 gtk_widget_show(tab->scrollbar);
3896 gtk_widget_show(tab->viewer_container);
3897 gtk_widget_show(tab->vbox);
3898 //gtk_widget_show(tab->multivpaned);
3899
3900
3901 /* Start with empty events requests list */
3902 tab->events_requests = NULL;
3903 tab->events_request_pending = FALSE;
3904
3905 g_object_set_data_full(
3906 G_OBJECT(tab->vbox),
3907 "Tab_Info",
3908 tab,
3909 (GDestroyNotify)tab_destructor);
3910
3911 g_signal_connect(G_OBJECT(tab->scrollbar), "value-changed",
3912 G_CALLBACK(scroll_value_changed_cb), tab);
3913 //g_signal_connect(G_OBJECT(tab->scrollbar), "changed",
3914 // G_CALLBACK(scroll_value_changed_cb), tab);
3915
3916
3917 //insert tab into notebook
3918 gtk_notebook_append_page(notebook,
3919 tab->vbox,
3920 tab->label);
3921 list = gtk_container_get_children(GTK_CONTAINER(notebook));
3922 gtk_notebook_set_current_page(notebook,g_list_length(list)-1);
3923 // always show : not if(g_list_length(list)>1)
3924 gtk_notebook_set_show_tabs(notebook, TRUE);
3925
3926 return tab;
3927 }
3928
3929 /*
3930 * execute_events_requests
3931 *
3932 * Idle function that executes the pending requests for a tab.
3933 *
3934 * @return return value : TRUE : keep the idle function, FALSE : remove it.
3935 */
3936 gboolean execute_events_requests(Tab *tab)
3937 {
3938 return ( lttvwindow_process_pending_requests(tab) );
3939 }
3940
This page took 0.122064 seconds and 4 git commands to generate.