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