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