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