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