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