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