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