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