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