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