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