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