Enable support for opening multiple trace
[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
8924e3e4 286 time_span = lttv_traceset_get_time_span_real(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;
68316c48 347 events_request->event = NULL;
58b4e4ae
YB
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 =
68316c48 1033#endif
ff5c41f1 1034 lttv_process_traceset_middle(ts,
3bafb436 1035 ltt_time_infinite,
1036 G_MAXUINT,
1037 events_request->start_position);
68316c48 1038
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;
3bafb436 1050 for(iter=list_in;iter!=NULL;iter=g_slist_next(iter)) {
1051 EventsRequest *events_request = (EventsRequest*)iter->data;
1052 /* 1.3.1 If !servicing */
2d262115 1053 if(events_request->servicing == FALSE) {
1054 /* - begin request hooks called
1055 * - servicing = TRUE
1056 */
ff5c41f1 1057 lttv_hooks_call(events_request->before_request, (gpointer)ts);
2d262115 1058 events_request->servicing = TRUE;
1059 }
3bafb436 1060 /* 1.3.2 call before chunk
1061 * 1.3.3 events hooks added
2d262115 1062 */
ff5c41f1
YB
1063 //TODO ybrosseau 2012-07-10: || TRUE added since we only support
1064 // traceset wide requests
68316c48
YB
1065 if(events_request->trace == -1 || TRUE) {
1066
ff5c41f1 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 );
68316c48 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
68316c48 1381 if(events_request->trace == -1 || TRUE) {
ff5c41f1 1382 lttv_process_traceset_end(ts,
54d8f654 1383 events_request->after_chunk_traceset,
3bafb436 1384 events_request->after_chunk_trace,
ff5c41f1 1385 events_request->event);
68316c48 1386 } else {
ff5c41f1 1387 guint nb_trace = lttv_traceset_number(ts);
54d8f654 1388 g_assert(events_request->trace < nb_trace &&
1389 events_request->trace > -1);
ff5c41f1 1390 LttvTrace *trace = lttv_traceset_get(ts, events_request->trace);
54d8f654 1391
ff5c41f1 1392 lttv_trace_remove_hooks(trace,
54d8f654 1393 events_request->after_chunk_trace,
54d8f654 1394
ff5c41f1
YB
1395 events_request->event);
1396
1397
1398 lttv_hooks_call(events_request->after_chunk_traceset, ts);
54d8f654 1399 }
1400
3bafb436 1401 /* - req.num -= count */
1402 g_assert(events_request->num_events >= count);
1403 events_request->num_events -= count;
1404
ff5c41f1 1405 //g_assert(tfc != NULL);
3bafb436 1406 /* - if req.num == 0
1407 * or
1408 * current context time >= req.end time
1409 * or
1410 * req.end pos == current pos
1411 * or
1412 * req.stop_flag == TRUE
1413 */
1414 if( events_request->num_events == 0
1415 ||
1416 events_request->stop_flag == TRUE
1417 ||
ff5c41f1 1418 ltt_time_compare(lttv_traceset_get_current_time(ts),
3bafb436 1419 events_request->end_time) >= 0
1420 ||
1421 (events_request->end_position != NULL
1422 &&
ff5c41f1 1423 lttv_traceset_position_compare_current(ts,
3bafb436 1424 events_request->end_position) == 0)
1425
1426 ) {
1427 g_assert(events_request->servicing == TRUE);
1428 /* - Call end request for req
1429 * - remove req from list_in */
ff5c41f1 1430 lttv_hooks_call(events_request->after_request, (gpointer)ts);
3bafb436 1431 /* - remove req from list_in */
1432 /* Destroy the request */
1433 remove = TRUE;
1434 free_data = TRUE;
1435 }
1436
1437 /* Go to next */
1438 if(remove)
1439 {
1440 GSList *remove_iter = iter;
1441
1442 iter = g_slist_next(iter);
1443 if(free_data) events_request_free((EventsRequest*)remove_iter->data);
1444 list_in = g_slist_remove_link(list_in, remove_iter);
1445 } else { // not remove
1446 iter = g_slist_next(iter);
1447 }
2d262115 1448 }
1449 }
1450 }
501e4e70 1451 }
dd316a11 1452 /* End of removed servicing loop : leave control to GTK instead. */
1453 // if(gtk_events_pending()) break;
1454 //}
1455
2d262115 1456 /* B. When interrupted between chunks */
501e4e70 1457
501e4e70 1458 {
1459 GSList *iter = list_in;
1460
2d262115 1461 /* 1. for each request in list_in */
501e4e70 1462 while(iter != NULL) {
1463
1464 gboolean remove = FALSE;
1465 gboolean free_data = FALSE;
2d262115 1466 EventsRequest *events_request = (EventsRequest *)iter->data;
501e4e70 1467
1468 /* 1.1. Use current postition as start position */
a1a2b649 1469 if(events_request->start_position != NULL)
ff5c41f1
YB
1470 lttv_traceset_destroy_position(events_request->start_position);
1471 events_request->start_position = lttv_traceset_create_current_position(ts);
1472
501e4e70 1473
1474 /* 1.2. Remove start time */
0aa6c3a1 1475 events_request->start_time = ltt_time_infinite;
501e4e70 1476
2d262115 1477 /* 1.3. Move from list_in to list_out */
501e4e70 1478 remove = TRUE;
1479 free_data = FALSE;
1480 list_out = g_slist_append(list_out, events_request);
1481
501e4e70 1482 /* Go to next */
1483 if(remove)
8f2872f4 1484 {
501e4e70 1485 GSList *remove_iter = iter;
1486
1487 iter = g_slist_next(iter);
b052368a 1488 if(free_data) events_request_free((EventsRequest*)remove_iter->data);
501e4e70 1489 list_in = g_slist_remove_link(list_in, remove_iter);
1490 } else { // not remove
1491 iter = g_slist_next(iter);
8f2872f4 1492 }
1493 }
a43d67ba 1494
501e4e70 1495
1496 }
b052368a 1497 /* C Unlock Traces */
1498 {
ff5c41f1 1499#ifdef BABEL_CLEANUP
088f6772 1500 lttv_process_traceset_get_sync_data(tsc);
ff5c41f1 1501#endif
088f6772 1502 //lttv_traceset_context_position_save(tsc, sync_position);
b052368a 1503
1504 guint iter_trace;
1505
1506 for(iter_trace=0;
ff5c41f1 1507 iter_trace<lttv_traceset_number(ts);
b052368a 1508 iter_trace++) {
ff5c41f1 1509 LttvTrace *trace_v = lttv_traceset_get(ts, iter_trace);
b052368a 1510
1511 lttvwindowtraces_unlock(trace_v);
1512 }
1513 }
a0577796 1514#if 0
abe346a3 1515 //set the cursor back to normal
a8c0f09d 1516 gdk_window_set_cursor(win, NULL);
a0577796 1517#endif //0
501e4e70 1518
2d262115 1519 g_assert(g_slist_length(list_in) == 0);
6ea08962 1520
2d262115 1521 if( g_slist_length(list_out) == 0 ) {
501e4e70 1522 /* Put tab's request pending flag back to normal */
2d262115 1523 tab->events_request_pending = FALSE;
b052368a 1524 g_debug("remove the idle fct");
501e4e70 1525 return FALSE; /* Remove the idle function */
1526 }
b052368a 1527 g_debug("leave the idle fct");
501e4e70 1528 return TRUE; /* Leave the idle function */
b052368a 1529
1530 /* We do not use simili-round-robin, it may require to read 1 meg buffers
1531 * again and again if many tracesets use the same tracefiles. */
1532 /* Hack for round-robin idle functions */
1533 /* It will put the idle function at the end of the pool */
1534 /*g_idle_add_full((G_PRIORITY_HIGH_IDLE + 21),
1535 (GSourceFunc)execute_events_requests,
1536 tab,
1537 NULL);
1538 return FALSE;
1539 */
451aaf27 1540
ff5c41f1 1541
202f6c8f 1542}
1543
6ea08962 1544#undef list_out
1e3594a3
YB
1545/**
1546 Manage the periodic update of a live trace
1547*/
1548static gboolean
1549live_trace_update_handler(Tab *tab)
1550{
451aaf27 1551#ifdef BABEL_CLEANUP
9a366873 1552 unsigned int updated_count;
1e3594a3
YB
1553 LttvTracesetContext *tsc = LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context);
1554 TimeInterval initial_time_span = tsc->time_span;
1555 TimeInterval updated_time_span;
1556
1557 updated_count = lttv_process_traceset_update(tsc);
1558
1559 /* TODO ybrosseau 2011-01-12: Add trace resynchronization */
501e4e70 1560
1e3594a3
YB
1561 /* Get the changed period bounds */
1562 updated_time_span = tsc->time_span;
1563
1564 if(ltt_time_compare(updated_time_span.start_time,
1565 initial_time_span.start_time) != 0) {
1566 /* The initial time should not change on a live update */
1567 g_assert(FALSE);
1568 }
1569
1570 /* Notify viewers (only on updates) */
1571 if(ltt_time_compare(updated_time_span.end_time,
1572 initial_time_span.end_time) != 0) {
1573
1574 notify_time_span_changed(tab);
1575 /* TODO ybrosseau 2011-01-12: Change the timebar to register
1576 to the time_span hook */
1577 timebar_set_minmax_time(TIMEBAR(tab->MTimebar),
1578 &updated_time_span.start_time,
1579 &updated_time_span.end_time );
1580
1581 /* To update the min max */
1582 time_change_manager(tab, tab->time_window);
1583 }
1584
1585 /* Timer will be recalled as long as there is files to update */
1586 return (updated_count > 0);
451aaf27 1587#endif /* BABEL_CLEANUP */
1e3594a3 1588}
abe346a3 1589
4266dc7f 1590static void lttvwindow_add_trace(Tab *tab, LttvTrace *trace_v)
1591{
9a366873 1592#ifdef BABEL_CLEANUP
4266dc7f 1593 LttvTraceset *traceset = tab->traceset_info->traceset;
1594 guint i;
91fd6881 1595 guint num_traces = lttv_traceset_number(traceset);
4266dc7f 1596
a1a2b649 1597 //Verify if trace is already present.
91fd6881 1598 for(i=0; i<num_traces; i++)
a1a2b649 1599 {
1600 LttvTrace * trace = lttv_traceset_get(traceset, i);
1601 if(trace == trace_v)
1602 return;
1603 }
1604
4266dc7f 1605 //Keep a reference to the traces so they are not freed.
1606 for(i=0; i<lttv_traceset_number(traceset); i++)
1607 {
1608 LttvTrace * trace = lttv_traceset_get(traceset, i);
1609 lttv_trace_ref(trace);
1610 }
1611
1612 //remove state update hooks
1613 lttv_state_remove_event_hooks(
1614 (LttvTracesetState*)tab->traceset_info->traceset_context);
1615
1616 lttv_context_fini(LTTV_TRACESET_CONTEXT(
1617 tab->traceset_info->traceset_context));
1618 g_object_unref(tab->traceset_info->traceset_context);
1619
1620 lttv_traceset_add(traceset, trace_v);
a1a2b649 1621 lttv_trace_ref(trace_v); /* local ref */
4266dc7f 1622
1623 /* Create new context */
1624 tab->traceset_info->traceset_context =
1625 g_object_new(LTTV_TRACESET_STATS_TYPE, NULL);
1626 lttv_context_init(
1627 LTTV_TRACESET_CONTEXT(tab->traceset_info->
1628 traceset_context),
1629 traceset);
6ea08962 1630
6ea08962 1631
4266dc7f 1632 //add state update hooks
1633 lttv_state_add_event_hooks(
1634 (LttvTracesetState*)tab->traceset_info->traceset_context);
1635 //Remove local reference to the traces.
1636 for(i=0; i<lttv_traceset_number(traceset); i++)
1637 {
1638 LttvTrace * trace = lttv_traceset_get(traceset, i);
1639 lttv_trace_unref(trace);
1640 }
1641
b052368a 1642 //FIXME
1643 //add_trace_into_traceset_selector(GTK_MULTIVPANED(tab->multivpaned), lttv_trace(trace_v));
1e3594a3
YB
1644
1645
1646 if (lttv_trace(trace_v)->is_live) {
1647 /* Add timer for live update */
1648 /* TODO ybrosseau 2011-01-12: Parametrize the hardcoded 1 seconds */
1649 g_timeout_add_seconds (1,
1650 (GSourceFunc) live_trace_update_handler,
1651 tab);
1652 }
451aaf27 1653#endif /* BABEL_CLEANUP */
4266dc7f 1654}
1655
abe346a3 1656/* add_trace adds a trace into the current traceset. It first displays a
1657 * directory selection dialogue to let user choose a trace, then recreates
1658 * tracset_context, and redraws all the viewer of the current tab
1659 */
1660
561eba2a 1661void add_trace(GtkWidget * widget, gpointer user_data)
1662{
861fbe5f 1663
deb3d2f8 1664 LttvTraceset * traceset = NULL;
861fbe5f 1665 const char * path;
a1a2b649 1666 char abs_path[PATH_MAX];
2176f952 1667 gint id;
bca3b81f 1668 MainWindow * mw_data = get_window_data_struct(widget);
6ced96ef 1669 GtkWidget * notebook = lookup_widget(widget, "MNotebook");
1670
1671 GtkWidget *page = gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook),
1672 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook)));
e433e6d6 1673 LttvPluginTab *ptab;
6ced96ef 1674 Tab *tab;
1675
1676 if(!page) {
e433e6d6 1677 ptab = create_new_tab(widget, NULL);
1678 tab = ptab->tab;
6ced96ef 1679 } else {
e433e6d6 1680 ptab = (LttvPluginTab *)g_object_get_data(G_OBJECT(page), "Tab_Plugin");
1681 tab = ptab->tab;
6ced96ef 1682 }
8284135e 1683#if 0
1167062f 1684//TODO fdeslauriers 2012-07-06: Remove this popup when we support multiple traces
deb3d2f8 1685 traceset = lttvwindow_get_traceset(tab);
95544594 1686 if(traceset != NULL && lttv_traceset_number(traceset) > 0){
deb3d2f8
FD
1687 GtkWidget *dialogue =
1688 gtk_message_dialog_new(
1689 GTK_WINDOW(gtk_widget_get_toplevel(widget)),
1690 GTK_DIALOG_MODAL|GTK_DIALOG_DESTROY_WITH_PARENT,
1691 GTK_MESSAGE_ERROR,
1692 GTK_BUTTONS_OK,
1693 "Loading multiple traces is not supported at the moment.");
1694 gtk_dialog_run(GTK_DIALOG(dialogue));
1695 gtk_widget_destroy(dialogue);
1696 return;
1697 }
8284135e 1698#endif
861fbe5f 1699 /* Create a new traceset*/
8284135e
YB
1700 traceset = tab->traceset_info->traceset;
1701 if(traceset == NULL) {
1702 traceset = lttv_traceset_new();
1703 }
ba013432 1704 /* File open dialog management */
95544594
FD
1705#ifdef BABEL_CLEANUP
1706 GtkWidget *extra_live_button;
1707#endif //babel_cleanup
ba013432
MD
1708 GtkFileChooser * file_chooser =
1709 GTK_FILE_CHOOSER(
1710 gtk_file_chooser_dialog_new ("Select a trace",
1711 GTK_WINDOW(mw_data->mwindow),
1712 GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER,
1713 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
1714 GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
861fbe5f 1715 NULL));
95544594 1716#ifdef BABEL_CLEANUP
1e3594a3
YB
1717 /* Button to indicate the opening of a live trace */
1718 extra_live_button = gtk_check_button_new_with_mnemonic ("Trace is live (currently being writen)");
1719 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (extra_live_button), FALSE);
1720 gtk_file_chooser_set_extra_widget (GTK_FILE_CHOOSER (file_chooser), extra_live_button);
95544594 1721#endif //babel_cleanup
ba013432 1722 gtk_file_chooser_set_show_hidden (file_chooser, TRUE);
3658a338 1723 if(remember_trace_dir[0] != '\0')
ba013432
MD
1724 gtk_file_chooser_set_filename(file_chooser, remember_trace_dir);
1725
861fbe5f 1726 gboolean closeFileChooserDialog = TRUE;
1e3594a3 1727
861fbe5f
FD
1728 do
1729 {
1730 id = gtk_dialog_run(GTK_DIALOG(file_chooser));
1731 switch(id){
1732 case GTK_RESPONSE_ACCEPT:
1733 case GTK_RESPONSE_OK:
1734 path = gtk_file_chooser_get_filename (file_chooser);
1735
1736 strncpy(remember_trace_dir, path, PATH_MAX);
1737 strncat(remember_trace_dir, "/", PATH_MAX);
1738 if(!path || strlen(path) == 0){
1739 break;
1e3594a3 1740 }
861fbe5f
FD
1741 get_absolute_pathname(path, abs_path);
1742
1743 if(lttv_traceset_add_path(traceset,abs_path) != 0 ){ /*failure*/
49bf71b5 1744
861fbe5f
FD
1745 g_warning("cannot open trace %s", abs_path);
1746 strncpy(remember_trace_dir, "\0", PATH_MAX);
1747 GtkWidget *dialogue =
1748 gtk_message_dialog_new(
1749 GTK_WINDOW(gtk_widget_get_toplevel(widget)),
1750 GTK_DIALOG_MODAL|GTK_DIALOG_DESTROY_WITH_PARENT,
1751 GTK_MESSAGE_ERROR,
1752 GTK_BUTTONS_OK,
1753 "Cannot open trace : maybe you should enter in the directory "
1754 "to select it ?");
1755 gtk_dialog_run(GTK_DIALOG(dialogue));
1756 gtk_widget_destroy(dialogue);
1757 closeFileChooserDialog = FALSE;
1758 }
1759 else{
1760 closeFileChooserDialog = TRUE;
1761 SetTraceset(tab, traceset);
1762 }
1763 break;
1764 //update current tab
1765 //update_traceset(mw_data);
21e8c385 1766
861fbe5f
FD
1767 // in expose now call_pending_read_hooks(mw_data);
1768
1769 //lttvwindow_report_current_time(mw_data,&(tab->current_time));
a43d67ba 1770
861fbe5f
FD
1771 case GTK_RESPONSE_REJECT:
1772 case GTK_RESPONSE_CANCEL:
1773 default:
1774 closeFileChooserDialog = TRUE;
1775 break;
1776 }
1777 }while(!closeFileChooserDialog);
451aaf27 1778
861fbe5f 1779 gtk_widget_destroy((GtkWidget*)file_chooser);
ba013432 1780
49bf71b5 1781}
1782
abe346a3 1783/* remove_trace removes a trace from the current traceset if all viewers in
1784 * the current tab are not interested in the trace. It first displays a
1785 * dialogue, which shows all traces in the current traceset, to let user choose
1786 * a trace, then it checks if all viewers unselect the trace, if it is true,
1787 * it will remove the trace, recreate the traceset_contex,
1788 * and redraws all the viewer of the current tab. If there is on trace in the
1789 * current traceset, it will delete all viewers of the current tab
3a5f75c1 1790 *
1791 * It destroys the filter tree. FIXME... we should request for an update
1792 * instead.
abe346a3 1793 */
1794
b052368a 1795void remove_trace(GtkWidget *widget, gpointer user_data)
1796{
9a366873 1797#ifdef BABEL_CLEANUP
b052368a 1798 LttTrace *trace;
1799 LttvTrace * trace_v;
1800 LttvTraceset * traceset;
1801 gint i, j, nb_trace, index=-1;
1802 char ** name, *remove_trace_name;
1803 MainWindow * mw_data = get_window_data_struct(widget);
1804 GtkWidget * notebook = lookup_widget(widget, "MNotebook");
1805
1806 GtkWidget *page = gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook),
1807 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook)));
1808 Tab *tab;
1809
1810 if(!page) {
1811 return;
1812 } else {
e433e6d6 1813 LttvPluginTab *ptab;
1814 ptab = (LttvPluginTab *)g_object_get_data(G_OBJECT(page), "Tab_Plugin");
1815 tab = ptab->tab;
b052368a 1816 }
1817
1818 nb_trace =lttv_traceset_number(tab->traceset_info->traceset);
1819 name = g_new(char*,nb_trace);
1820 for(i = 0; i < nb_trace; i++){
1821 trace_v = lttv_traceset_get(tab->traceset_info->traceset, i);
1822 trace = lttv_trace(trace_v);
8d8c5ea7 1823 name[i] = (char *) g_quark_to_string(ltt_trace_name(trace));
b052368a 1824 }
1825
93ac601b 1826 remove_trace_name = get_remove_trace(mw_data, name, nb_trace);
b052368a 1827
1828
1829 if(remove_trace_name){
1830
1831 /* yuk, cut n paste from old code.. should be better (MD)*/
1832 for(i = 0; i<nb_trace; i++) {
1833 if(strcmp(remove_trace_name,name[i]) == 0){
1834 index = i;
1835 }
1836 }
1837
1838 traceset = tab->traceset_info->traceset;
1839 //Keep a reference to the traces so they are not freed.
1840 for(j=0; j<lttv_traceset_number(traceset); j++)
1841 {
1842 LttvTrace * trace = lttv_traceset_get(traceset, j);
1843 lttv_trace_ref(trace);
1844 }
1845
1846 //remove state update hooks
1847 lttv_state_remove_event_hooks(
1848 (LttvTracesetState*)tab->traceset_info->traceset_context);
1849 lttv_context_fini(LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context));
1850 g_object_unref(tab->traceset_info->traceset_context);
1851
1852 trace_v = lttv_traceset_get(traceset, index);
1853
b052368a 1854 lttv_traceset_remove(traceset, index);
1855 lttv_trace_unref(trace_v); // Remove local reference
1856
d27948a3 1857 if(lttv_trace_get_ref_number(trace_v) <= 1) {
1ba187d3 1858 /* ref 1 : lttvwindowtraces only*/
1859 ltt_trace_close(lttv_trace(trace_v));
1860 /* lttvwindowtraces_remove_trace takes care of destroying
1861 * the traceset linked with the trace_v and also of destroying
1862 * the trace_v at the same time.
1863 */
d27948a3 1864 lttvwindowtraces_remove_trace(trace_v);
1865 }
b052368a 1866
1867 tab->traceset_info->traceset_context =
1868 g_object_new(LTTV_TRACESET_STATS_TYPE, NULL);
1869 lttv_context_init(
1870 LTTV_TRACESET_CONTEXT(tab->
1871 traceset_info->traceset_context),traceset);
1872 //add state update hooks
1873 lttv_state_add_event_hooks(
1874 (LttvTracesetState*)tab->traceset_info->traceset_context);
1875
1876 //Remove local reference to the traces.
1877 for(j=0; j<lttv_traceset_number(traceset); j++)
1878 {
1879 LttvTrace * trace = lttv_traceset_get(traceset, j);
1880 lttv_trace_unref(trace);
1881 }
1882
1883 SetTraceset(tab, (gpointer)traceset);
1884 }
1885 g_free(name);
451aaf27 1886#endif /* BABEL_CLEANUP */
b052368a 1887}
1888
1889#if 0
561eba2a 1890void remove_trace(GtkWidget * widget, gpointer user_data)
1891{
2176f952 1892 LttTrace *trace;
1893 LttvTrace * trace_v;
1894 LttvTraceset * traceset;
a43d67ba 1895 gint i, j, nb_trace;
2176f952 1896 char ** name, *remove_trace_name;
bca3b81f 1897 MainWindow * mw_data = get_window_data_struct(widget);
49bf71b5 1898 LttvTracesetSelector * s;
1899 LttvTraceSelector * t;
1900 GtkWidget * w;
1901 gboolean selected;
6ced96ef 1902 GtkWidget * notebook = lookup_widget(widget, "MNotebook");
1903
1904 GtkWidget *page = gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook),
1905 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook)));
1906 Tab *tab;
1907
1908 if(!page) {
1909 return;
1910 } else {
1911 tab = (Tab *)g_object_get_data(G_OBJECT(page), "Tab_Info");
1912 }
1913
4266dc7f 1914 nb_trace =lttv_traceset_number(tab->traceset_info->traceset);
2176f952 1915 name = g_new(char*,nb_trace);
1916 for(i = 0; i < nb_trace; i++){
4266dc7f 1917 trace_v = lttv_traceset_get(tab->traceset_info->traceset, i);
2176f952 1918 trace = lttv_trace(trace_v);
a5dcde2f 1919 name[i] = ltt_trace_name(trace);
2176f952 1920 }
1921
1922 remove_trace_name = get_remove_trace(name, nb_trace);
1923
1924 if(remove_trace_name){
1925 for(i=0; i<nb_trace; i++){
1926 if(strcmp(remove_trace_name,name[i]) == 0){
6ced96ef 1927 //unselect the trace from the current viewer
b052368a 1928 //FIXME
1929 w = gtk_multivpaned_get_widget(GTK_MULTIVPANED(tab->multivpaned));
6ced96ef 1930 if(w){
1931 s = g_object_get_data(G_OBJECT(w), "Traceset_Selector");
1932 if(s){
1933 t = lttv_traceset_selector_trace_get(s,i);
1934 lttv_trace_selector_set_selected(t, FALSE);
1935 }
1936
1937 //check if other viewers select the trace
b052368a 1938 w = gtk_multivpaned_get_first_widget(GTK_MULTIVPANED(tab->multivpaned));
6ced96ef 1939 while(w){
1940 s = g_object_get_data(G_OBJECT(w), "Traceset_Selector");
1941 if(s){
1942 t = lttv_traceset_selector_trace_get(s,i);
1943 selected = lttv_trace_selector_get_selected(t);
1944 if(selected)break;
1945 }
b052368a 1946 w = gtk_multivpaned_get_next_widget(GTK_MULTIVPANED(tab->multivpaned));
6ced96ef 1947 }
1948 }else selected = FALSE;
49bf71b5 1949
6ced96ef 1950 //if no viewer selects the trace, remove it
1951 if(!selected){
b052368a 1952 remove_trace_from_traceset_selector(GTK_MULTIVPANED(tab->multivpaned), i);
49bf71b5 1953
6ced96ef 1954 traceset = tab->traceset_info->traceset;
1955 //Keep a reference to the traces so they are not freed.
1956 for(j=0; j<lttv_traceset_number(traceset); j++)
1957 {
1958 LttvTrace * trace = lttv_traceset_get(traceset, j);
1959 lttv_trace_ref(trace);
1960 }
a43d67ba 1961
6ced96ef 1962 //remove state update hooks
1963 lttv_state_remove_event_hooks(
1964 (LttvTracesetState*)tab->traceset_info->traceset_context);
1965 lttv_context_fini(LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context));
1966 g_object_unref(tab->traceset_info->traceset_context);
a43d67ba 1967
a43d67ba 1968
6ced96ef 1969 trace_v = lttv_traceset_get(traceset, i);
a43d67ba 1970
a1a2b649 1971 if(lttv_trace_get_ref_number(trace_v) <= 2) {
1972 /* ref 2 : traceset, local */
1973 lttvwindowtraces_remove_trace(trace_v);
6ced96ef 1974 ltt_trace_close(lttv_trace(trace_v));
a1a2b649 1975 }
6ced96ef 1976
1977 lttv_traceset_remove(traceset, i);
1978 lttv_trace_unref(trace_v); // Remove local reference
c2619a30 1979
6ced96ef 1980 if(!lttv_trace_get_ref_number(trace_v))
1981 lttv_trace_destroy(trace_v);
1982
1983 tab->traceset_info->traceset_context =
1984 g_object_new(LTTV_TRACESET_STATS_TYPE, NULL);
1985 lttv_context_init(
1986 LTTV_TRACESET_CONTEXT(tab->
1987 traceset_info->traceset_context),traceset);
1988 //add state update hooks
1989 lttv_state_add_event_hooks(
1990 (LttvTracesetState*)tab->traceset_info->traceset_context);
1991
1992 //Remove local reference to the traces.
1993 for(j=0; j<lttv_traceset_number(traceset); j++)
1994 {
1995 LttvTrace * trace = lttv_traceset_get(traceset, j);
1996 lttv_trace_unref(trace);
1997 }
a43d67ba 1998
a43d67ba 1999
6ced96ef 2000 //update current tab
2001 //update_traceset(mw_data);
313bd6fc 2002 //if(nb_trace > 1){
6ced96ef 2003
313bd6fc 2004 SetTraceset(tab, (gpointer)traceset);
6ced96ef 2005 // in expose now call_pending_read_hooks(mw_data);
2006
2007 //lttvwindow_report_current_time(mw_data,&(tab->current_time));
313bd6fc 2008 //}else{
2009 // if(tab){
2010 // while(tab->multi_vpaned->num_children){
2011 // gtk_multi_vpaned_widget_delete(tab->multi_vpaned);
2012 // }
2013 // }
2014 //}
6ced96ef 2015 }
2016 break;
2176f952 2017 }
2018 }
2019 }
2020
2021 g_free(name);
561eba2a 2022}
b052368a 2023#endif //0
abe346a3 2024
9878c8a4 2025/* Redraw all the viewers in the current tab */
2026void redraw(GtkWidget *widget, gpointer user_data)
2027{
2028 GtkWidget * notebook = lookup_widget(widget, "MNotebook");
2029 GtkWidget *page = gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook),
2030 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook)));
2031 Tab *tab;
8f318283
BP
2032 gboolean retval;
2033
9878c8a4 2034 if(!page) {
2035 return;
2036 } else {
e433e6d6 2037 LttvPluginTab *ptab;
2038 ptab = (LttvPluginTab *)g_object_get_data(G_OBJECT(page), "Tab_Plugin");
2039 tab = ptab->tab;
9878c8a4 2040 }
2041
2042 LttvHooks * tmp;
2043 LttvAttributeValue value;
2044
8f318283
BP
2045 retval= lttv_iattribute_find_by_path(tab->attributes, "hooks/redraw", LTTV_POINTER, &value);
2046 g_assert(retval);
9878c8a4 2047
2048 tmp = (LttvHooks*)*(value.v_pointer);
c07e9b26 2049 if(tmp != NULL)
2050 lttv_hooks_call(tmp,NULL);
9878c8a4 2051}
2052
2053
2054void continue_processing(GtkWidget *widget, gpointer user_data)
2055{
2056 GtkWidget * notebook = lookup_widget(widget, "MNotebook");
2057 GtkWidget *page = gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook),
2058 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook)));
2059 Tab *tab;
8f318283
BP
2060 gboolean retval;
2061
9878c8a4 2062 if(!page) {
2063 return;
2064 } else {
e433e6d6 2065 LttvPluginTab *ptab;
2066 ptab = (LttvPluginTab *)g_object_get_data(G_OBJECT(page), "Tab_Plugin");
2067 tab = ptab->tab;
9878c8a4 2068 }
2069
2070 LttvHooks * tmp;
2071 LttvAttributeValue value;
2072
8f318283
BP
2073 retval= lttv_iattribute_find_by_path(tab->attributes, "hooks/continue",
2074 LTTV_POINTER, &value);
2075 g_assert(retval);
9878c8a4 2076
2077 tmp = (LttvHooks*)*(value.v_pointer);
c07e9b26 2078 if(tmp != NULL)
2079 lttv_hooks_call(tmp,NULL);
9878c8a4 2080}
2081
2082/* Stop the processing for the calling main window's current tab.
2083 * It removes every processing requests that are in its list. It does not call
2084 * the end request hooks, because the request is not finished.
2085 */
2086
2087void stop_processing(GtkWidget *widget, gpointer user_data)
2088{
2089 GtkWidget * notebook = lookup_widget(widget, "MNotebook");
2090 GtkWidget *page = gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook),
2091 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook)));
2092 Tab *tab;
2093 if(!page) {
2094 return;
2095 } else {
e433e6d6 2096 LttvPluginTab *ptab;
2097 ptab = (LttvPluginTab *)g_object_get_data(G_OBJECT(page), "Tab_Plugin");
2098 tab = ptab->tab;
9878c8a4 2099 }
a0577796 2100 GSList *iter = tab->events_requests;
9878c8a4 2101
2102 while(iter != NULL) {
2103 GSList *remove_iter = iter;
2104 iter = g_slist_next(iter);
2105
2106 g_free(remove_iter->data);
a0577796 2107 tab->events_requests =
2108 g_slist_remove_link(tab->events_requests, remove_iter);
9878c8a4 2109 }
a0577796 2110 tab->events_request_pending = FALSE;
5698740e 2111 tab->stop_foreground = TRUE;
a0577796 2112 g_idle_remove_by_data(tab);
2113 g_assert(g_slist_length(tab->events_requests) == 0);
9878c8a4 2114}
2115
2116
abe346a3 2117/* save will save the traceset to a file
a43d67ba 2118 * Not implemented yet FIXME
abe346a3 2119 */
2120
561eba2a 2121void save(GtkWidget * widget, gpointer user_data)
2122{
56e5a0f7 2123 g_info("Save\n");
561eba2a 2124}
2125
2126void save_as(GtkWidget * widget, gpointer user_data)
2127{
56e5a0f7 2128 g_info("Save as\n");
561eba2a 2129}
2130
abe346a3 2131
2132/* zoom will change the time_window of all the viewers of the
2133 * current tab, and redisplay them. The main functionality is to
2134 * determine the new time_window of the current tab
2135 */
2136
1f1ae829 2137void zoom(GtkWidget * widget, double size)
2138{
88bf15f0 2139
b052368a 2140 TimeInterval time_span;
a43d67ba 2141 TimeWindow new_time_window;
2eef04b5 2142 LttTime current_time, time_delta;
88bf15f0 2143 LttvTraceset *ts;
6ced96ef 2144 GtkWidget * notebook = lookup_widget(widget, "MNotebook");
2145
2146 GtkWidget *page = gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook),
2147 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook)));
2148 Tab *tab;
2149
2150 if(!page) {
2151 return;
2152 } else {
e433e6d6 2153 LttvPluginTab *ptab;
2154 ptab = (LttvPluginTab *)g_object_get_data(G_OBJECT(page), "Tab_Plugin");
2155 tab = ptab->tab;
6ced96ef 2156 }
1f1ae829 2157
fda16332 2158 if(size == 1) return;
2159
88bf15f0
FD
2160 ts = lttvwindow_get_traceset(tab);
2161 time_span = lttv_traceset_get_time_span_real(ts);
501e4e70 2162 new_time_window = tab->time_window;
2163 current_time = tab->current_time;
1f1ae829 2164
b052368a 2165 time_delta = ltt_time_sub(time_span.end_time,time_span.start_time);
1f1ae829 2166 if(size == 0){
b052368a 2167 new_time_window.start_time = time_span.start_time;
a43d67ba 2168 new_time_window.time_width = time_delta;
a18124ff 2169 new_time_window.time_width_double = ltt_time_to_double(time_delta);
6f26fc38 2170 new_time_window.end_time = ltt_time_add(new_time_window.start_time,
2171 new_time_window.time_width) ;
1f1ae829 2172 }else{
a43d67ba 2173 new_time_window.time_width = ltt_time_div(new_time_window.time_width, size);
a18124ff 2174 new_time_window.time_width_double =
2175 ltt_time_to_double(new_time_window.time_width);
a43d67ba 2176 if(ltt_time_compare(new_time_window.time_width,time_delta) > 0)
2177 { /* Case where zoom out is bigger than trace length */
b052368a 2178 new_time_window.start_time = time_span.start_time;
a43d67ba 2179 new_time_window.time_width = time_delta;
a18124ff 2180 new_time_window.time_width_double = ltt_time_to_double(time_delta);
6f26fc38 2181 new_time_window.end_time = ltt_time_add(new_time_window.start_time,
2182 new_time_window.time_width) ;
a8c0f09d 2183 }
a43d67ba 2184 else
2185 {
2186 /* Center the image on the current time */
a43d67ba 2187 new_time_window.start_time =
a18124ff 2188 ltt_time_sub(current_time,
2189 ltt_time_from_double(new_time_window.time_width_double/2.0));
6f26fc38 2190 new_time_window.end_time = ltt_time_add(new_time_window.start_time,
2191 new_time_window.time_width) ;
a43d67ba 2192 /* If on borders, don't fall off */
9e494e53 2193 if(ltt_time_compare(new_time_window.start_time, time_span.start_time) <0
2194 || ltt_time_compare(new_time_window.start_time, time_span.end_time) >0)
a43d67ba 2195 {
b052368a 2196 new_time_window.start_time = time_span.start_time;
6f26fc38 2197 new_time_window.end_time = ltt_time_add(new_time_window.start_time,
2198 new_time_window.time_width) ;
a43d67ba 2199 }
2200 else
2201 {
6f26fc38 2202 if(ltt_time_compare(new_time_window.end_time,
9e494e53 2203 time_span.end_time) > 0
2204 || ltt_time_compare(new_time_window.end_time,
2205 time_span.start_time) < 0)
a43d67ba 2206 {
2207 new_time_window.start_time =
b052368a 2208 ltt_time_sub(time_span.end_time, new_time_window.time_width);
6f26fc38 2209
2210 new_time_window.end_time = ltt_time_add(new_time_window.start_time,
2211 new_time_window.time_width) ;
a43d67ba 2212 }
2213 }
2214
1f1ae829 2215 }
1f1ae829 2216 }
a43d67ba 2217
f02b5e22 2218 if(ltt_time_compare(new_time_window.time_width, ltt_time_zero) == 0) {
2219 g_warning("Zoom more than 1 ns impossible");
b052368a 2220 } else {
e800cf84 2221 time_change_manager(tab, new_time_window);
b052368a 2222 }
1f1ae829 2223}
2224
561eba2a 2225void zoom_in(GtkWidget * widget, gpointer user_data)
2226{
1f1ae829 2227 zoom(widget, 2);
561eba2a 2228}
2229
2230void zoom_out(GtkWidget * widget, gpointer user_data)
2231{
1f1ae829 2232 zoom(widget, 0.5);
561eba2a 2233}
2234
2235void zoom_extended(GtkWidget * widget, gpointer user_data)
2236{
1f1ae829 2237 zoom(widget, 0);
561eba2a 2238}
2239
2240void go_to_time(GtkWidget * widget, gpointer user_data)
2241{
56e5a0f7 2242 g_info("Go to time\n");
561eba2a 2243}
2244
2245void show_time_frame(GtkWidget * widget, gpointer user_data)
2246{
56e5a0f7 2247 g_info("Show time frame\n");
561eba2a 2248}
2249
2250
2251/* callback function */
2252
2253void
2254on_empty_traceset_activate (GtkMenuItem *menuitem,
2255 gpointer user_data)
2256{
68b48a45 2257 create_new_window((GtkWidget*)menuitem, user_data, FALSE);
561eba2a 2258}
2259
2260
2261void
2262on_clone_traceset_activate (GtkMenuItem *menuitem,
2263 gpointer user_data)
2264{
68b48a45 2265 create_new_window((GtkWidget*)menuitem, user_data, TRUE);
561eba2a 2266}
2267
abe346a3 2268
2269/* create_new_tab calls create_tab to construct a new tab in the main window
2270 */
2271
e433e6d6 2272LttvPluginTab *create_new_tab(GtkWidget* widget, gpointer user_data)
2273{
a1a2b649 2274 gchar label[PATH_MAX];
2901f314 2275 MainWindow * mw_data = get_window_data_struct(widget);
4266dc7f 2276
2901f314 2277 GtkNotebook * notebook = (GtkNotebook *)lookup_widget(widget, "MNotebook");
561eba2a 2278 if(notebook == NULL){
56e5a0f7 2279 g_info("Notebook does not exist\n");
6ced96ef 2280 return NULL;
2281 }
2282 GtkWidget *page = gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook),
2283 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook)));
2284 Tab *copy_tab;
2285
2286 if(!page) {
2287 copy_tab = NULL;
2288 } else {
e433e6d6 2289 LttvPluginTab *ptab;
2290 ptab = (LttvPluginTab *)g_object_get_data(G_OBJECT(page), "Tab_Plugin");
2291 copy_tab = ptab->tab;
561eba2a 2292 }
4266dc7f 2293
6b1d3120 2294 strcpy(label,"Page");
e433e6d6 2295 if(get_label(mw_data, label,"Get the name of the tab","Please input tab's name")) {
2296 LttvPluginTab *ptab;
2297
2298 ptab = g_object_new(LTTV_TYPE_PLUGIN_TAB, NULL);
2299 init_tab (ptab->tab, mw_data, copy_tab, notebook, label);
2300 ptab->parent.top_widget = ptab->tab->top_widget;
2301 g_object_set_data_full(
2302 G_OBJECT(ptab->tab->vbox),
2303 "Tab_Plugin",
2304 ptab,
2305 (GDestroyNotify)tab_destructor);
2306 return ptab;
2307 }
2308 else return NULL;
561eba2a 2309}
2310
2901f314 2311void
2312on_tab_activate (GtkMenuItem *menuitem,
2313 gpointer user_data)
2314{
2315 create_new_tab((GtkWidget*)menuitem, user_data);
2316}
2317
561eba2a 2318
2319void
2320on_open_activate (GtkMenuItem *menuitem,
2321 gpointer user_data)
2322{
e865422c 2323#ifdef UNFINISHED_FEATURE
561eba2a 2324 open_traceset((GtkWidget*)menuitem, user_data);
e865422c 2325#endif
561eba2a 2326}
2327
2328
2329void
2330on_close_activate (GtkMenuItem *menuitem,
2331 gpointer user_data)
2332{
bca3b81f 2333 MainWindow * mw_data = get_window_data_struct((GtkWidget*)menuitem);
68b48a45 2334 main_window_destructor(mw_data);
561eba2a 2335}
2336
2337
4266dc7f 2338/* remove the current tab from the main window
abe346a3 2339 */
2340
561eba2a 2341void
27a559b9 2342on_close_tab_activate (GtkWidget *widget,
561eba2a 2343 gpointer user_data)
2344{
4266dc7f 2345 gint page_num;
2061e03d 2346 GtkWidget * notebook;
27a559b9 2347 notebook = lookup_widget(widget, "MNotebook");
2061e03d 2348 if(notebook == NULL){
56e5a0f7 2349 g_info("Notebook does not exist\n");
2061e03d 2350 return;
2351 }
4266dc7f 2352
2353 page_num = gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook));
2061e03d 2354
4266dc7f 2355 gtk_notebook_remove_page(GTK_NOTEBOOK(notebook), page_num);
2061e03d 2356
561eba2a 2357}
2358
27a559b9 2359void
2360on_close_tab_X_clicked (GtkWidget *widget,
2361 gpointer user_data)
2362{
2363 gint page_num;
2364 GtkWidget *notebook = lookup_widget(widget, "MNotebook");
2365 if(notebook == NULL){
56e5a0f7 2366 g_info("Notebook does not exist\n");
27a559b9 2367 return;
2368 }
2369
2370 if((page_num = gtk_notebook_page_num(GTK_NOTEBOOK(notebook), widget)) != -1)
2371 gtk_notebook_remove_page(GTK_NOTEBOOK(notebook), page_num);
2372
2373}
2374
561eba2a 2375
2376void
2377on_add_trace_activate (GtkMenuItem *menuitem,
2378 gpointer user_data)
2379{
2380 add_trace((GtkWidget*)menuitem, user_data);
2381}
2382
2383
2384void
2385on_remove_trace_activate (GtkMenuItem *menuitem,
2386 gpointer user_data)
2387{
2388 remove_trace((GtkWidget*)menuitem, user_data);
2389}
2390
2391
2392void
2393on_save_activate (GtkMenuItem *menuitem,
2394 gpointer user_data)
2395{
2396 save((GtkWidget*)menuitem, user_data);
2397}
2398
2399
2400void
2401on_save_as_activate (GtkMenuItem *menuitem,
2402 gpointer user_data)
2403{
2404 save_as((GtkWidget*)menuitem, user_data);
2405}
2406
2407
2408void
2409on_quit_activate (GtkMenuItem *menuitem,
2410 gpointer user_data)
2411{
6f9c921e 2412 while (g_slist_length(g_main_window_list) != 0) {
2413 on_MWindow_destroy(((MainWindow *)g_main_window_list->data)->mwindow,
2414 user_data);
2415 }
561eba2a 2416}
2417
2418
2419void
2420on_cut_activate (GtkMenuItem *menuitem,
2421 gpointer user_data)
2422{
56e5a0f7 2423 g_info("Cut\n");
561eba2a 2424}
2425
2426
2427void
2428on_copy_activate (GtkMenuItem *menuitem,
2429 gpointer user_data)
2430{
56e5a0f7 2431 g_info("Copye\n");
561eba2a 2432}
2433
2434
2435void
2436on_paste_activate (GtkMenuItem *menuitem,
2437 gpointer user_data)
2438{
56e5a0f7 2439 g_info("Paste\n");
561eba2a 2440}
2441
2442
2443void
2444on_delete_activate (GtkMenuItem *menuitem,
2445 gpointer user_data)
2446{
56e5a0f7 2447 g_info("Delete\n");
561eba2a 2448}
2449
2450
2451void
2452on_zoom_in_activate (GtkMenuItem *menuitem,
2453 gpointer user_data)
2454{
2455 zoom_in((GtkWidget*)menuitem, user_data);
2456}
2457
2458
2459void
2460on_zoom_out_activate (GtkMenuItem *menuitem,
2461 gpointer user_data)
2462{
2463 zoom_out((GtkWidget*)menuitem, user_data);
2464}
2465
2466
2467void
2468on_zoom_extended_activate (GtkMenuItem *menuitem,
2469 gpointer user_data)
2470{
2471 zoom_extended((GtkWidget*)menuitem, user_data);
2472}
2473
2474
2475void
2476on_go_to_time_activate (GtkMenuItem *menuitem,
2477 gpointer user_data)
2478{
2479 go_to_time((GtkWidget*)menuitem, user_data);
2480}
2481
2482
2483void
2484on_show_time_frame_activate (GtkMenuItem *menuitem,
2485 gpointer user_data)
2486{
2487 show_time_frame((GtkWidget*)menuitem, user_data);
2488}
2489
2490
2491void
2492on_move_viewer_up_activate (GtkMenuItem *menuitem,
2493 gpointer user_data)
2494{
2495 move_up_viewer((GtkWidget*)menuitem, user_data);
2496}
2497
2498
2499void
2500on_move_viewer_down_activate (GtkMenuItem *menuitem,
2501 gpointer user_data)
2502{
2503 move_down_viewer((GtkWidget*)menuitem, user_data);
2504}
2505
2506
2507void
2508on_remove_viewer_activate (GtkMenuItem *menuitem,
2509 gpointer user_data)
2510{
2511 delete_viewer((GtkWidget*)menuitem, user_data);
2512}
2513
49bf71b5 2514void
2515on_trace_facility_activate (GtkMenuItem *menuitem,
2516 gpointer user_data)
2517{
43ed82b5 2518 g_info("Trace facility selector: %s\n", "");
49bf71b5 2519}
561eba2a 2520
abe346a3 2521
b052368a 2522/* Dispaly a file selection dialogue to let user select a library, then call
2523 * lttv_library_load().
2524 */
2525
2526void
2527on_load_library_activate (GtkMenuItem *menuitem,
2528 gpointer user_data)
2529{
2530 GError *error = NULL;
2531 MainWindow * mw_data = get_window_data_struct((GtkWidget*)menuitem);
2532
2533 gchar load_module_path_alter[PATH_MAX];
2534 {
2535 GPtrArray *name;
2536 guint nb,i;
2537 gchar *load_module_path;
2538 name = g_ptr_array_new();
2539 nb = lttv_library_path_number();
2540 /* ask for the library path */
2541
2542 for(i=0;i<nb;i++){
2543 gchar *path;
2544 path = lttv_library_path_get(i);
2545 g_ptr_array_add(name, path);
2546 }
2547
93ac601b 2548 load_module_path = get_selection(mw_data,
2549 (char **)(name->pdata), name->len,
b052368a 2550 "Select a library path", "Library paths");
2551 if(load_module_path != NULL)
2552 strncpy(load_module_path_alter, load_module_path, PATH_MAX-1); // -1 for /
2553
2554 g_ptr_array_free(name, TRUE);
2555
2556 if(load_module_path == NULL) return;
2557 }
2558
2559 {
2560 /* Make sure the module path ends with a / */
2561 gchar *ptr = load_module_path_alter;
2562
2563 ptr = strchr(ptr, '\0');
2564
2565 if(*(ptr-1) != '/') {
2566 *ptr = '/';
2567 *(ptr+1) = '\0';
2568 }
2569 }
2570
2571 {
2572 /* Ask for the library to load : list files in the previously selected
2573 * directory */
2574 gchar str[PATH_MAX];
2575 gchar ** dir;
2576 gint id;
2577 GtkFileSelection * file_selector =
2578 (GtkFileSelection *)gtk_file_selection_new("Select a module");
2579 gtk_file_selection_set_filename(file_selector, load_module_path_alter);
2580 gtk_file_selection_hide_fileop_buttons(file_selector);
2581
93ac601b 2582 gtk_window_set_transient_for(GTK_WINDOW(file_selector),
2583 GTK_WINDOW(mw_data->mwindow));
2584
b052368a 2585 str[0] = '\0';
2586 id = gtk_dialog_run(GTK_DIALOG(file_selector));
2587 switch(id){
2588 case GTK_RESPONSE_ACCEPT:
2589 case GTK_RESPONSE_OK:
2590 dir = gtk_file_selection_get_selections (file_selector);
2591 strncpy(str,dir[0],PATH_MAX);
2592 strncpy(remember_plugins_dir,dir[0],PATH_MAX);
2593 /* only keep file name */
2594 gchar *str1;
2595 str1 = strrchr(str,'/');
2596 if(str1)str1++;
2597 else{
2598 str1 = strrchr(str,'\\');
2599 str1++;
2600 }
2601#if 0
2602 /* remove "lib" */
2603 if(*str1 == 'l' && *(str1+1)== 'i' && *(str1+2)=='b')
2604 str1=str1+3;
2605 remove info after . */
2606 {
2607 gchar *str2 = str1;
2608
2609 str2 = strrchr(str2, '.');
2610 if(str2 != NULL) *str2 = '\0';
2611 }
2612 lttv_module_require(str1, &error);
2613#endif //0
2614 lttv_library_load(str1, &error);
2eef04b5 2615 if(error != NULL) g_warning("%s", error->message);
56e5a0f7 2616 else g_info("Load library: %s\n", str);
b052368a 2617 g_strfreev(dir);
2618 case GTK_RESPONSE_REJECT:
2619 case GTK_RESPONSE_CANCEL:
2620 default:
2621 gtk_widget_destroy((GtkWidget*)file_selector);
2622 break;
2623 }
2624
2625 }
2626
2627
2628
2629}
2630
2631
2632/* Display all loaded modules, let user to select a module to unload
2633 * by calling lttv_module_unload
2634 */
2635
2636void
2637on_unload_library_activate (GtkMenuItem *menuitem,
2638 gpointer user_data)
2639{
2640 MainWindow * mw_data = get_window_data_struct((GtkWidget*)menuitem);
2641
2eef04b5 2642 LttvLibrary *library = NULL;
b052368a 2643
2eef04b5 2644 GPtrArray *name;
2645 guint nb,i;
2646 gchar *lib_name;
2647 name = g_ptr_array_new();
2648 nb = lttv_library_number();
2649 LttvLibraryInfo *lib_info = g_new(LttvLibraryInfo,nb);
2650 /* ask for the library name */
2651
2652 for(i=0;i<nb;i++){
2653 LttvLibrary *iter_lib = lttv_library_get(i);
2654 lttv_library_info(iter_lib, &lib_info[i]);
2655
2656 gchar *path = lib_info[i].name;
2657 g_ptr_array_add(name, path);
2658 }
93ac601b 2659 lib_name = get_selection(mw_data, (char **)(name->pdata), name->len,
2eef04b5 2660 "Select a library", "Libraries");
2661 if(lib_name != NULL) {
b052368a 2662 for(i=0;i<nb;i++){
2eef04b5 2663 if(strcmp(lib_name, lib_info[i].name) == 0) {
2664 library = lttv_library_get(i);
2665 break;
b052368a 2666 }
2667 }
b052368a 2668 }
2eef04b5 2669 g_ptr_array_free(name, TRUE);
2670 g_free(lib_info);
2671
2672 if(lib_name == NULL) return;
2673
2674 if(library != NULL) lttv_library_unload(library);
b052368a 2675}
2676
2677
abe346a3 2678/* Dispaly a file selection dialogue to let user select a module, then call
b052368a 2679 * lttv_module_require().
abe346a3 2680 */
2681
561eba2a 2682void
2683on_load_module_activate (GtkMenuItem *menuitem,
2684 gpointer user_data)
2685{
b052368a 2686 GError *error = NULL;
bca3b81f 2687 MainWindow * mw_data = get_window_data_struct((GtkWidget*)menuitem);
b052368a 2688
2eef04b5 2689 LttvLibrary *library = NULL;
b052368a 2690 {
2691 GPtrArray *name;
2692 guint nb,i;
2693 gchar *lib_name;
2694 name = g_ptr_array_new();
2695 nb = lttv_library_number();
2696 LttvLibraryInfo *lib_info = g_new(LttvLibraryInfo,nb);
2697 /* ask for the library name */
2698
2699 for(i=0;i<nb;i++){
2700 LttvLibrary *iter_lib = lttv_library_get(i);
2701 lttv_library_info(iter_lib, &lib_info[i]);
2702
2703 gchar *path = lib_info[i].name;
2704 g_ptr_array_add(name, path);
2705 }
93ac601b 2706 lib_name = get_selection(mw_data,(char **)(name->pdata), name->len,
b052368a 2707 "Select a library", "Libraries");
2708 if(lib_name != NULL) {
2709 for(i=0;i<nb;i++){
2710 if(strcmp(lib_name, lib_info[i].name) == 0) {
2711 library = lttv_library_get(i);
2712 break;
2713 }
3872a20e 2714 }
b052368a 2715 }
2716 g_ptr_array_free(name, TRUE);
2717 g_free(lib_info);
2718
2719 if(lib_name == NULL) return;
36b3c068 2720 }
b052368a 2721
2722 //LttvModule *module;
2723 gchar module_name_out[PATH_MAX];
2724 {
2725 /* Ask for the module to load : list modules in the selected lib */
2726 GPtrArray *name;
2727 guint nb,i;
2728 gchar *module_name;
bbbd6c25 2729 nb = lttv_library_module_number(library);
b052368a 2730 LttvModuleInfo *module_info = g_new(LttvModuleInfo,nb);
2731 name = g_ptr_array_new();
b052368a 2732 /* ask for the module name */
2733
2734 for(i=0;i<nb;i++){
2735 LttvModule *iter_module = lttv_library_module_get(library, i);
2736 lttv_module_info(iter_module, &module_info[i]);
2737
2738 gchar *path = module_info[i].name;
2739 g_ptr_array_add(name, path);
2740 }
93ac601b 2741 module_name = get_selection(mw_data, (char **)(name->pdata), name->len,
b052368a 2742 "Select a module", "Modules");
2743 if(module_name != NULL) {
2744 for(i=0;i<nb;i++){
2745 if(strcmp(module_name, module_info[i].name) == 0) {
2746 strncpy(module_name_out, module_name, PATH_MAX);
2747 //module = lttv_library_module_get(i);
2748 break;
2749 }
2750 }
2751 }
2752
2753 g_ptr_array_free(name, TRUE);
2754 g_free(module_info);
2755
2756 if(module_name == NULL) return;
2757 }
2758
2759 lttv_module_require(module_name_out, &error);
2eef04b5 2760 if(error != NULL) g_warning("%s", error->message);
56e5a0f7 2761 else g_info("Load module: %s", module_name_out);
b052368a 2762
2763
2764#if 0
2765 {
2766
2767
2768 gchar str[PATH_MAX];
2769 gchar ** dir;
2770 gint id;
2771 GtkFileSelection * file_selector =
2772 (GtkFileSelection *)gtk_file_selection_new("Select a module");
2773 gtk_file_selection_set_filename(file_selector, load_module_path_alter);
2774 gtk_file_selection_hide_fileop_buttons(file_selector);
2775
2776 str[0] = '\0';
2777 id = gtk_dialog_run(GTK_DIALOG(file_selector));
2778 switch(id){
2779 case GTK_RESPONSE_ACCEPT:
2780 case GTK_RESPONSE_OK:
2781 dir = gtk_file_selection_get_selections (file_selector);
2782 strncpy(str,dir[0],PATH_MAX);
2783 strncpy(remember_plugins_dir,dir[0],PATH_MAX);
2784 {
2785 /* only keep file name */
2786 gchar *str1;
2787 str1 = strrchr(str,'/');
2788 if(str1)str1++;
2789 else{
2790 str1 = strrchr(str,'\\');
2791 str1++;
2792 }
2793#if 0
2794 /* remove "lib" */
2795 if(*str1 == 'l' && *(str1+1)== 'i' && *(str1+2)=='b')
2796 str1=str1+3;
2797 remove info after . */
2798 {
2799 gchar *str2 = str1;
2800
2801 str2 = strrchr(str2, '.');
2802 if(str2 != NULL) *str2 = '\0';
2803 }
2804 lttv_module_require(str1, &error);
2805#endif //0
2806 lttv_library_load(str1, &error);
2807 if(error != NULL) g_warning(error->message);
56e5a0f7 2808 else g_info("Load library: %s\n", str);
b052368a 2809 g_strfreev(dir);
2810 case GTK_RESPONSE_REJECT:
2811 case GTK_RESPONSE_CANCEL:
2812 default:
2813 gtk_widget_destroy((GtkWidget*)file_selector);
2814 break;
2815 }
2816
2817 }
2818#endif //0
2819
2820
561eba2a 2821}
2822
2823
b052368a 2824
abe346a3 2825/* Display all loaded modules, let user to select a module to unload
2826 * by calling lttv_module_unload
2827 */
2828
561eba2a 2829void
2830on_unload_module_activate (GtkMenuItem *menuitem,
2831 gpointer user_data)
2832{
bca3b81f 2833 MainWindow * mw_data = get_window_data_struct((GtkWidget*)menuitem);
08b1c66e 2834
43ed82b5 2835 LttvLibrary *library = NULL;
b052368a 2836 {
2837 GPtrArray *name;
2838 guint nb,i;
2839 gchar *lib_name;
2840 name = g_ptr_array_new();
2841 nb = lttv_library_number();
2842 LttvLibraryInfo *lib_info = g_new(LttvLibraryInfo,nb);
2843 /* ask for the library name */
36b3c068 2844
36b3c068 2845 for(i=0;i<nb;i++){
b052368a 2846 LttvLibrary *iter_lib = lttv_library_get(i);
2847 lttv_library_info(iter_lib, &lib_info[i]);
2848
2849 gchar *path = lib_info[i].name;
2850 g_ptr_array_add(name, path);
2851 }
93ac601b 2852 lib_name = get_selection(mw_data, (char **)(name->pdata), name->len,
b052368a 2853 "Select a library", "Libraries");
2854 if(lib_name != NULL) {
2855 for(i=0;i<nb;i++){
2856 if(strcmp(lib_name, lib_info[i].name) == 0) {
2857 library = lttv_library_get(i);
2858 break;
2859 }
36b3c068 2860 }
b052368a 2861 }
2862 g_ptr_array_free(name, TRUE);
2863 g_free(lib_info);
2864
2865 if(lib_name == NULL) return;
36b3c068 2866 }
2867
2eef04b5 2868 LttvModule *module = NULL;
b052368a 2869 {
2870 /* Ask for the module to load : list modules in the selected lib */
2871 GPtrArray *name;
2872 guint nb,i;
2873 gchar *module_name;
6d677a86 2874 nb = lttv_library_module_number(library);
b052368a 2875 LttvModuleInfo *module_info = g_new(LttvModuleInfo,nb);
2876 name = g_ptr_array_new();
b052368a 2877 /* ask for the module name */
2878
2879 for(i=0;i<nb;i++){
2880 LttvModule *iter_module = lttv_library_module_get(library, i);
2881 lttv_module_info(iter_module, &module_info[i]);
2882
2883 gchar *path = module_info[i].name;
2884 if(module_info[i].use_count > 0) g_ptr_array_add(name, path);
2885 }
93ac601b 2886 module_name = get_selection(mw_data, (char **)(name->pdata), name->len,
b052368a 2887 "Select a module", "Modules");
2888 if(module_name != NULL) {
2889 for(i=0;i<nb;i++){
2890 if(strcmp(module_name, module_info[i].name) == 0) {
2891 module = lttv_library_module_get(library, i);
2892 break;
2893 }
2894 }
2895 }
2896
2897 g_ptr_array_free(name, TRUE);
2898 g_free(module_info);
2899
2900 if(module_name == NULL) return;
2901 }
2902
b052368a 2903 LttvModuleInfo module_info;
2904 lttv_module_info(module, &module_info);
56e5a0f7 2905 g_info("Release module: %s\n", module_info.name);
fce9a2fc 2906
2907 lttv_module_release(module);
561eba2a 2908}
2909
2910
b052368a 2911/* Display a directory dialogue to let user select a path for library searching
abe346a3 2912 */
2913
561eba2a 2914void
b052368a 2915on_add_library_search_path_activate (GtkMenuItem *menuitem,
561eba2a 2916 gpointer user_data)
2917{
93ac601b 2918 MainWindow * mw_data = get_window_data_struct((GtkWidget*)menuitem);
0a946563 2919 //GtkDirSelection * file_selector = (GtkDirSelection *)gtk_dir_selection_new("Select library path");
2920 GtkFileSelection * file_selector = (GtkFileSelection *)gtk_file_selection_new("Select a trace");
2921 gtk_widget_hide( (file_selector)->file_list->parent) ;
93ac601b 2922
2923 gtk_window_set_transient_for(GTK_WINDOW(file_selector),
2924 GTK_WINDOW(mw_data->mwindow));
2925
67b98724 2926 const char * dir;
fc188b78 2927 gint id;
2928
3658a338 2929 if(remember_plugins_dir[0] != '\0')
0a946563 2930 gtk_file_selection_set_filename(file_selector, remember_plugins_dir);
fc188b78 2931
68b48a45 2932 id = gtk_dialog_run(GTK_DIALOG(file_selector));
fc188b78 2933 switch(id){
2934 case GTK_RESPONSE_ACCEPT:
2935 case GTK_RESPONSE_OK:
0a946563 2936 dir = gtk_file_selection_get_filename (file_selector);
a1a2b649 2937 strncpy(remember_plugins_dir,dir,PATH_MAX);
2938 strncat(remember_plugins_dir,"/",PATH_MAX);
08b1c66e 2939 lttv_library_path_add(dir);
fc188b78 2940 case GTK_RESPONSE_REJECT:
2941 case GTK_RESPONSE_CANCEL:
2942 default:
68b48a45 2943 gtk_widget_destroy((GtkWidget*)file_selector);
fc188b78 2944 break;
6b1d3120 2945 }
561eba2a 2946}
2947
2948
b052368a 2949/* Display a directory dialogue to let user select a path for library searching
2950 */
2951
2952void
2953on_remove_library_search_path_activate (GtkMenuItem *menuitem,
2954 gpointer user_data)
2955{
2956 MainWindow * mw_data = get_window_data_struct((GtkWidget*)menuitem);
2957
2958 const char *lib_path;
2959 {
2960 GPtrArray *name;
2961 guint nb,i;
b052368a 2962 name = g_ptr_array_new();
2963 nb = lttv_library_path_number();
2964 /* ask for the library name */
2965
2966 for(i=0;i<nb;i++){
2967 gchar *path = lttv_library_path_get(i);
2968 g_ptr_array_add(name, path);
2969 }
93ac601b 2970 lib_path = get_selection(mw_data, (char **)(name->pdata), name->len,
b052368a 2971 "Select a library path", "Library paths");
2972
2973 g_ptr_array_free(name, TRUE);
2974
2975 if(lib_path == NULL) return;
2976 }
2977
2978 lttv_library_path_remove(lib_path);
2979}
2980
561eba2a 2981void
2982on_color_activate (GtkMenuItem *menuitem,
2983 gpointer user_data)
2984{
56e5a0f7 2985 g_info("Color\n");
561eba2a 2986}
2987
2988
561eba2a 2989void
2990on_save_configuration_activate (GtkMenuItem *menuitem,
2991 gpointer user_data)
2992{
56e5a0f7 2993 g_info("Save configuration\n");
561eba2a 2994}
2995
2996
2997void
2998on_content_activate (GtkMenuItem *menuitem,
2999 gpointer user_data)
3000{
7e18bb76
F
3001 char* filename = NULL,
3002 *path;
3003 GdkScreen *screen;
3004 const char* relativePath = "doc/user/user_guide/html/index.html";
3005 filename = g_build_filename (g_get_current_dir(), relativePath, NULL);
3006 path = g_strdup_printf ("ghelp://%s", filename);
3007
3008 screen = gdk_screen_get_default();
3009 gtk_show_uri (screen, path, gtk_get_current_event_time(), NULL);
3010
3011 g_free(filename);
3012 g_free(path);
56e5a0f7 3013 g_info("Content\n");
561eba2a 3014}
3015
3016
51ef553b 3017static void
3018on_about_close_activate (GtkButton *button,
3019 gpointer user_data)
3020{
3021 GtkWidget *about_widget = GTK_WIDGET(user_data);
3022
3023 gtk_widget_destroy(about_widget);
3024}
3025
561eba2a 3026void
3027on_about_activate (GtkMenuItem *menuitem,
3028 gpointer user_data)
3029{
51ef553b 3030 MainWindow *main_window = get_window_data_struct(GTK_WIDGET(menuitem));
3031 GtkWidget *window_widget = main_window->mwindow;
3032 GtkWidget *about_widget = gtk_window_new(GTK_WINDOW_TOPLEVEL);
3033 GtkWindow *about_window = GTK_WINDOW(about_widget);
51ef553b 3034
3035 gtk_window_set_title(about_window, "About Linux Trace Toolkit");
3036
3037 gtk_window_set_resizable(about_window, FALSE);
f5f1a04e 3038 gtk_window_set_transient_for(about_window, GTK_WINDOW(window_widget));
51ef553b 3039 gtk_window_set_destroy_with_parent(about_window, TRUE);
3040 gtk_window_set_modal(about_window, FALSE);
3041
3042 /* Put the about window at the center of the screen */
7e18bb76
F
3043 gtk_window_set_position(about_window, GTK_WIN_POS_CENTER_ALWAYS);
3044
51ef553b 3045 GtkWidget *vbox = gtk_vbox_new(FALSE, 1);
3046
3047 gtk_container_add(GTK_CONTAINER(about_widget), vbox);
3048
51ef553b 3049 /* Text to show */
3050 GtkWidget *label1 = gtk_label_new("");
c8bba5fa 3051 gtk_misc_set_padding(GTK_MISC(label1), 10, 20);
51ef553b 3052 gtk_label_set_markup(GTK_LABEL(label1), "\
f5f1a04e 3053<big>Linux Trace Toolkit " VERSION "</big>");
51ef553b 3054 gtk_label_set_justify(GTK_LABEL(label1), GTK_JUSTIFY_CENTER);
3055
3056 GtkWidget *label2 = gtk_label_new("");
c8bba5fa 3057 gtk_misc_set_padding(GTK_MISC(label2), 10, 20);
51ef553b 3058 gtk_label_set_markup(GTK_LABEL(label2), "\
51ef553b 3059Contributors :\n\
3060\n\
3061Michel Dagenais (New trace format, lttv main)\n\
4b601423 3062Mathieu Desnoyers (Kernel Tracer, Directory structure, build with automake/conf,\n\
ef26c1ea 3063 lttv gui, control flow view, gui cooperative trace reading\n\
4b7bd7e1 3064 scheduler with interruptible foreground and background\n\
57ca4914 3065 computation, detailed event list (rewrite), trace reading\n\
3066 library (rewrite))\n\
7d2855bf 3067Benoit Des Ligneris, Eric Clement (Cluster adaptation, work in progress)\n\
51ef553b 3068Xang-Xiu Yang (new trace reading library and converter, lttv gui, \n\
3069 detailed event list and statistics view)\n\
e8ac6a5e 3070Tom Zanussi (RelayFS)\n\
3071\n\
f5f1a04e 3072Inspired from the original Linux Trace Toolkit Visualizer made by\n\
e8ac6a5e 3073Karim Yaghmour");
c8bba5fa 3074
3075 GtkWidget *label3 = gtk_label_new("");
3076 gtk_label_set_markup(GTK_LABEL(label3), "\
f5f1a04e 3077Linux Trace Toolkit Viewer, Copyright (C) 2004, 2005, 2006\n\
7d2855bf 3078 Michel Dagenais\n\
e8ac6a5e 3079 Mathieu Desnoyers\n\
3080 Xang-Xiu Yang\n\
c8bba5fa 3081Linux Trace Toolkit comes with ABSOLUTELY NO WARRANTY.\n\
3082This is free software, and you are welcome to redistribute it\n\
3083under certain conditions. See COPYING for details.");
3084 gtk_misc_set_padding(GTK_MISC(label3), 10, 20);
3085
51ef553b 3086 gtk_box_pack_start_defaults(GTK_BOX(vbox), label1);
3087 gtk_box_pack_start_defaults(GTK_BOX(vbox), label2);
c8bba5fa 3088 gtk_box_pack_start_defaults(GTK_BOX(vbox), label3);
51ef553b 3089
3090 GtkWidget *hbox = gtk_hbox_new(TRUE, 0);
3091 gtk_box_pack_end(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
3092 GtkWidget *close_button = gtk_button_new_with_mnemonic("_Close");
3093 gtk_box_pack_end(GTK_BOX(hbox), close_button, FALSE, FALSE, 0);
3094 gtk_container_set_border_width(GTK_CONTAINER(close_button), 20);
3095
3096 g_signal_connect(G_OBJECT(close_button), "clicked",
3097 G_CALLBACK(on_about_close_activate),
3098 (gpointer)about_widget);
3099
3100 gtk_widget_show_all(about_widget);
561eba2a 3101}
3102
3103
3104void
3105on_button_new_clicked (GtkButton *button,
3106 gpointer user_data)
3107{
6f7ad7ae 3108 create_new_window((GtkWidget*)button, user_data, TRUE);
561eba2a 3109}
3110
2901f314 3111void
3112on_button_new_tab_clicked (GtkButton *button,
3113 gpointer user_data)
3114{
3115 create_new_tab((GtkWidget*)button, user_data);
3116}
561eba2a 3117
3118void
3119on_button_open_clicked (GtkButton *button,
3120 gpointer user_data)
3121{
e865422c 3122#ifdef UNFINISHED_FEATURE
561eba2a 3123 open_traceset((GtkWidget*)button, user_data);
e865422c 3124#endif
561eba2a 3125}
3126
3127
3128void
3129on_button_add_trace_clicked (GtkButton *button,
3130 gpointer user_data)
3131{
3132 add_trace((GtkWidget*)button, user_data);
3133}
3134
3135
3136void
3137on_button_remove_trace_clicked (GtkButton *button,
3138 gpointer user_data)
3139{
3140 remove_trace((GtkWidget*)button, user_data);
3141}
3142
9878c8a4 3143void
3144on_button_redraw_clicked (GtkButton *button,
3145 gpointer user_data)
3146{
3147 redraw((GtkWidget*)button, user_data);
3148}
3149
3150void
3151on_button_continue_processing_clicked (GtkButton *button,
3152 gpointer user_data)
3153{
3154 continue_processing((GtkWidget*)button, user_data);
3155}
3156
3157void
3158on_button_stop_processing_clicked (GtkButton *button,
3159 gpointer user_data)
3160{
3161 stop_processing((GtkWidget*)button, user_data);
3162}
3163
3164
561eba2a 3165
3166void
3167on_button_save_clicked (GtkButton *button,
3168 gpointer user_data)
3169{
3170 save((GtkWidget*)button, user_data);
3171}
3172
3173
3174void
3175on_button_save_as_clicked (GtkButton *button,
3176 gpointer user_data)
3177{
3178 save_as((GtkWidget*)button, user_data);
3179}
3180
3181
3182void
3183on_button_zoom_in_clicked (GtkButton *button,
3184 gpointer user_data)
3185{
3186 zoom_in((GtkWidget*)button, user_data);
3187}
3188
3189
3190void
3191on_button_zoom_out_clicked (GtkButton *button,
3192 gpointer user_data)
3193{
3194 zoom_out((GtkWidget*)button, user_data);
3195}
3196
3197
3198void
3199on_button_zoom_extended_clicked (GtkButton *button,
3200 gpointer user_data)
3201{
3202 zoom_extended((GtkWidget*)button, user_data);
3203}
3204
3205
3206void
3207on_button_go_to_time_clicked (GtkButton *button,
3208 gpointer user_data)
3209{
3210 go_to_time((GtkWidget*)button, user_data);
3211}
3212
3213
3214void
3215on_button_show_time_frame_clicked (GtkButton *button,
3216 gpointer user_data)
3217{
3218 show_time_frame((GtkWidget*)button, user_data);
3219}
3220
3221
3222void
3223on_button_move_up_clicked (GtkButton *button,
3224 gpointer user_data)
3225{
3226 move_up_viewer((GtkWidget*)button, user_data);
3227}
3228
3229
3230void
3231on_button_move_down_clicked (GtkButton *button,
3232 gpointer user_data)
3233{
3234 move_down_viewer((GtkWidget*)button, user_data);
3235}
3236
3237
3238void
3239on_button_delete_viewer_clicked (GtkButton *button,
3240 gpointer user_data)
3241{
3242 delete_viewer((GtkWidget*)button, user_data);
3243}
3244
3245void
2d262115 3246on_MWindow_destroy (GtkWidget *widget,
561eba2a 3247 gpointer user_data)
3248{
2d262115 3249 MainWindow *main_window = get_window_data_struct(widget);
ef68c3ac 3250 LttvIAttribute *attributes = main_window->attributes;
3251 LttvAttributeValue value;
8f318283 3252 gboolean retval;
e4d09234 3253
ef68c3ac 3254 //This is unnecessary, since widgets will be destroyed
3255 //by the main window widget anyway.
3256 //remove_all_menu_toolbar_constructors(main_window, NULL);
3257
8f318283
BP
3258 retval= lttv_iattribute_find_by_path(attributes, "viewers/menu",
3259 LTTV_POINTER, &value);
3260 g_assert(retval);
ef68c3ac 3261 lttv_menus_destroy((LttvMenus*)*(value.v_pointer));
3262
8f318283
BP
3263 retval= lttv_iattribute_find_by_path(attributes, "viewers/toolbar",
3264 LTTV_POINTER, &value);
3265 g_assert(retval);
ef68c3ac 3266 lttv_toolbars_destroy((LttvToolbars*)*(value.v_pointer));
2d262115 3267
ef68c3ac 3268 g_object_unref(main_window->attributes);
3269 g_main_window_list = g_slist_remove(g_main_window_list, main_window);
561eba2a 3270
56e5a0f7 3271 g_info("There are now : %d windows\n",g_slist_length(g_main_window_list));
2d262115 3272 if(g_slist_length(g_main_window_list) == 0)
d27948a3 3273 mainwindow_quit();
561eba2a 3274}
3275
58eecf4a 3276gboolean
3277on_MWindow_configure (GtkWidget *widget,
3278 GdkEventConfigure *event,
3279 gpointer user_data)
3280{
bd24a9af 3281 // MD : removed time width modification upon resizing of the main window.
3282 // The viewers will redraw themselves completely, without time interval
3283 // modification.
3284/* while(tab){
58eecf4a 3285 if(mw_data->window_width){
3286 time_span = LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context)->Time_Span ;
3287 time_win = tab->time_window;
3288 ratio = width / mw_data->window_width;
3289 tab->time_window.time_width = ltt_time_mul(time_win.time_width,ratio);
3290 time = ltt_time_sub(time_span->endTime, time_win.start_time);
3291 if(ltt_time_compare(time, tab->time_window.time_width) < 0){
3292 tab->time_window.time_width = time;
3293 }
3294 }
3295 tab = tab->next;
3296 }
3297
3298 mw_data->window_width = (int)width;
bd24a9af 3299 */
58eecf4a 3300 return FALSE;
3301}
561eba2a 3302
abe346a3 3303/* Set current tab
3304 */
3305
561eba2a 3306void
3307on_MNotebook_switch_page (GtkNotebook *notebook,
3308 GtkNotebookPage *page,
3309 guint page_num,
3310 gpointer user_data)
3311{
47cd8a09 3312
561eba2a 3313}
3314
abe346a3 3315
e800cf84 3316void time_change_manager (Tab *tab,
3317 TimeWindow new_time_window)
451aaf27
FD
3318{
3319
e800cf84 3320 /* Only one source of time change */
3321 if(tab->time_manager_lock == TRUE) return;
3322
3323 tab->time_manager_lock = TRUE;
451aaf27
FD
3324 TimeInterval time_span;
3325
3326 LttvTraceset *ts = tab->traceset_info->traceset;
451aaf27 3327
8924e3e4 3328 time_span = lttv_traceset_get_time_span_real(ts);
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 3434 LttvTraceset * ts =tab->traceset_info->traceset;
8924e3e4 3435 TimeInterval time_span = lttv_traceset_get_time_span_real(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 3470 LttvTraceset * ts =tab->traceset_info->traceset;
8924e3e4 3471 TimeInterval time_span = lttv_traceset_get_time_span_real(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;
8924e3e4 3522 TimeInterval time_span = lttv_traceset_get_time_span_real(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.321207 seconds and 4 git commands to generate.