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