fixed scroll up
[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 */
2d262115 1286 events_request->start_time.tv_sec = G_MAXUINT;
1287 events_request->start_time.tv_nsec = G_MAXUINT;
501e4e70 1288
2d262115 1289 /* 1.3. Move from list_in to list_out */
501e4e70 1290 remove = TRUE;
1291 free_data = FALSE;
1292 list_out = g_slist_append(list_out, events_request);
1293
501e4e70 1294 /* Go to next */
1295 if(remove)
8f2872f4 1296 {
501e4e70 1297 GSList *remove_iter = iter;
1298
1299 iter = g_slist_next(iter);
b052368a 1300 if(free_data) events_request_free((EventsRequest*)remove_iter->data);
501e4e70 1301 list_in = g_slist_remove_link(list_in, remove_iter);
1302 } else { // not remove
1303 iter = g_slist_next(iter);
8f2872f4 1304 }
1305 }
a43d67ba 1306
501e4e70 1307
1308 }
b052368a 1309
1310 /* C Unlock Traces */
1311 {
1312 //lttv_process_traceset_get_sync_data(tsc);
1313
1314 guint iter_trace;
1315
1316 for(iter_trace=0;
1317 iter_trace<lttv_traceset_number(tsc->ts);
1318 iter_trace++) {
1319 LttvTrace *trace_v = lttv_traceset_get(tsc->ts, iter_trace);
1320
1321 lttvwindowtraces_unlock(trace_v);
1322 }
1323 }
501e4e70 1324
a0577796 1325#if 0
abe346a3 1326 //set the cursor back to normal
a8c0f09d 1327 gdk_window_set_cursor(win, NULL);
a0577796 1328#endif //0
501e4e70 1329
2d262115 1330 g_assert(g_slist_length(list_in) == 0);
6ea08962 1331
2d262115 1332 if( g_slist_length(list_out) == 0 ) {
501e4e70 1333 /* Put tab's request pending flag back to normal */
2d262115 1334 tab->events_request_pending = FALSE;
b052368a 1335 g_debug("remove the idle fct");
501e4e70 1336 return FALSE; /* Remove the idle function */
1337 }
b052368a 1338 g_debug("leave the idle fct");
501e4e70 1339 return TRUE; /* Leave the idle function */
b052368a 1340
1341 /* We do not use simili-round-robin, it may require to read 1 meg buffers
1342 * again and again if many tracesets use the same tracefiles. */
1343 /* Hack for round-robin idle functions */
1344 /* It will put the idle function at the end of the pool */
1345 /*g_idle_add_full((G_PRIORITY_HIGH_IDLE + 21),
1346 (GSourceFunc)execute_events_requests,
1347 tab,
1348 NULL);
1349 return FALSE;
1350 */
202f6c8f 1351}
1352
6ea08962 1353#undef list_out
501e4e70 1354
abe346a3 1355
1356/* add_trace_into_traceset_selector, each instance of a viewer has an associated
1357 * selector (filter), when a trace is added into traceset, the selector should
1358 * reflect the change. The function is used to update the selector
1359 */
b052368a 1360#if 0
1361void add_trace_into_traceset_selector(GtkWidget * paned, LttTrace * t)
49bf71b5 1362{
ed3b99b6 1363 int j, k, m, nb_tracefile, nb_control, nb_per_cpu, nb_facility, nb_event;
49bf71b5 1364 LttvTracesetSelector * s;
1365 LttvTraceSelector * trace;
1366 LttvTracefileSelector * tracefile;
ed3b99b6 1367 LttvEventtypeSelector * eventtype;
49bf71b5 1368 LttTracefile * tf;
1369 GtkWidget * w;
ed3b99b6 1370 LttFacility * fac;
1371 LttEventType * et;
49bf71b5 1372
b052368a 1373 w = gtk_multivpaned_get_first_widget(GTK_MULTIVPANED(paned));
49bf71b5 1374 while(w){
1375 s = g_object_get_data(G_OBJECT(w), "Traceset_Selector");
49bf71b5 1376
abe346a3 1377 if(s){
1378 trace = lttv_trace_selector_new(t);
1379 lttv_traceset_selector_trace_add(s, trace);
1380
1381 nb_facility = ltt_trace_facility_number(t);
1382 for(k=0;k<nb_facility;k++){
1383 fac = ltt_trace_facility_get(t,k);
1384 nb_event = (int) ltt_facility_eventtype_number(fac);
1385 for(m=0;m<nb_event;m++){
1386 et = ltt_facility_eventtype_get(fac,m);
1387 eventtype = lttv_eventtype_selector_new(et);
1388 lttv_trace_selector_eventtype_add(trace, eventtype);
1389 }
1390 }
1391
1392 nb_control = ltt_trace_control_tracefile_number(t);
1393 nb_per_cpu = ltt_trace_per_cpu_tracefile_number(t);
1394 nb_tracefile = nb_control + nb_per_cpu;
1395
1396 for(j = 0 ; j < nb_tracefile ; j++) {
1397 if(j < nb_control)
1398 tf = ltt_trace_control_tracefile_get(t, j);
1399 else
1400 tf = ltt_trace_per_cpu_tracefile_get(t, j - nb_control);
1401 tracefile = lttv_tracefile_selector_new(tf);
1402 lttv_trace_selector_tracefile_add(trace, tracefile);
1403 lttv_eventtype_selector_copy(trace, tracefile);
1404 }
1405 }else g_warning("Module does not support filtering\n");
49bf71b5 1406
b052368a 1407 w = gtk_multivpaned_get_next_widget(GTK_MULTIVPANED(paned));
49bf71b5 1408 }
1409}
b052368a 1410#endif //0
abe346a3 1411
4266dc7f 1412static void lttvwindow_add_trace(Tab *tab, LttvTrace *trace_v)
1413{
1414 LttvTraceset *traceset = tab->traceset_info->traceset;
1415 guint i;
91fd6881 1416 guint num_traces = lttv_traceset_number(traceset);
4266dc7f 1417
a1a2b649 1418 //Verify if trace is already present.
91fd6881 1419 for(i=0; i<num_traces; i++)
a1a2b649 1420 {
1421 LttvTrace * trace = lttv_traceset_get(traceset, i);
1422 if(trace == trace_v)
1423 return;
1424 }
1425
4266dc7f 1426 //Keep a reference to the traces so they are not freed.
1427 for(i=0; i<lttv_traceset_number(traceset); i++)
1428 {
1429 LttvTrace * trace = lttv_traceset_get(traceset, i);
1430 lttv_trace_ref(trace);
1431 }
1432
1433 //remove state update hooks
1434 lttv_state_remove_event_hooks(
1435 (LttvTracesetState*)tab->traceset_info->traceset_context);
1436
1437 lttv_context_fini(LTTV_TRACESET_CONTEXT(
1438 tab->traceset_info->traceset_context));
1439 g_object_unref(tab->traceset_info->traceset_context);
1440
1441 lttv_traceset_add(traceset, trace_v);
a1a2b649 1442 lttv_trace_ref(trace_v); /* local ref */
4266dc7f 1443
1444 /* Create new context */
1445 tab->traceset_info->traceset_context =
1446 g_object_new(LTTV_TRACESET_STATS_TYPE, NULL);
1447 lttv_context_init(
1448 LTTV_TRACESET_CONTEXT(tab->traceset_info->
1449 traceset_context),
1450 traceset);
6ea08962 1451
6ea08962 1452
4266dc7f 1453 //add state update hooks
1454 lttv_state_add_event_hooks(
1455 (LttvTracesetState*)tab->traceset_info->traceset_context);
1456 //Remove local reference to the traces.
1457 for(i=0; i<lttv_traceset_number(traceset); i++)
1458 {
1459 LttvTrace * trace = lttv_traceset_get(traceset, i);
1460 lttv_trace_unref(trace);
1461 }
1462
b052368a 1463 //FIXME
1464 //add_trace_into_traceset_selector(GTK_MULTIVPANED(tab->multivpaned), lttv_trace(trace_v));
4266dc7f 1465}
1466
abe346a3 1467/* add_trace adds a trace into the current traceset. It first displays a
1468 * directory selection dialogue to let user choose a trace, then recreates
1469 * tracset_context, and redraws all the viewer of the current tab
1470 */
1471
561eba2a 1472void add_trace(GtkWidget * widget, gpointer user_data)
1473{
2176f952 1474 LttTrace *trace;
1475 LttvTrace * trace_v;
1476 LttvTraceset * traceset;
94dcfb9e 1477 const char * dir;
a1a2b649 1478 char abs_path[PATH_MAX];
2176f952 1479 gint id;
a43d67ba 1480 gint i;
bca3b81f 1481 MainWindow * mw_data = get_window_data_struct(widget);
6ced96ef 1482 GtkWidget * notebook = lookup_widget(widget, "MNotebook");
1483
1484 GtkWidget *page = gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook),
1485 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook)));
1486 Tab *tab;
1487
1488 if(!page) {
1489 tab = create_new_tab(widget, NULL);
1490 } else {
1491 tab = (Tab *)g_object_get_data(G_OBJECT(page), "Tab_Info");
1492 }
4266dc7f 1493
68b48a45 1494 GtkDirSelection * file_selector = (GtkDirSelection *)gtk_dir_selection_new("Select a trace");
1495 gtk_dir_selection_hide_fileop_buttons(file_selector);
4266dc7f 1496
3658a338 1497 if(remember_trace_dir[0] != '\0')
1498 gtk_dir_selection_set_filename(file_selector, remember_trace_dir);
2176f952 1499
68b48a45 1500 id = gtk_dialog_run(GTK_DIALOG(file_selector));
2176f952 1501 switch(id){
1502 case GTK_RESPONSE_ACCEPT:
1503 case GTK_RESPONSE_OK:
68b48a45 1504 dir = gtk_dir_selection_get_dir (file_selector);
a1a2b649 1505 strncpy(remember_trace_dir, dir, PATH_MAX);
a43d67ba 1506 if(!dir || strlen(dir) == 0){
1507 gtk_widget_destroy((GtkWidget*)file_selector);
1508 break;
284675e3 1509 }
a1a2b649 1510 get_absolute_pathname(dir, abs_path);
1511 trace_v = lttvwindowtraces_get_trace_by_name(abs_path);
1512 if(trace_v == NULL) {
1513 trace = ltt_trace_open(abs_path);
2a74fbf4 1514 if(trace == NULL) {
1515 g_warning("cannot open trace %s", abs_path);
1516 } else {
1517 trace_v = lttv_trace_new(trace);
1518 lttvwindowtraces_add_trace(trace_v);
1519 lttvwindow_add_trace(tab, trace_v);
1520 }
1521 } else {
1522 lttvwindow_add_trace(tab, trace_v);
a1a2b649 1523 }
c2619a30 1524
49bf71b5 1525 gtk_widget_destroy((GtkWidget*)file_selector);
1526
1527 //update current tab
a43d67ba 1528 //update_traceset(mw_data);
21e8c385 1529
a43d67ba 1530 /* Call the updatetraceset hooks */
1531
4266dc7f 1532 traceset = tab->traceset_info->traceset;
1533 SetTraceset(tab, traceset);
a43d67ba 1534 // in expose now call_pending_read_hooks(mw_data);
1535
4266dc7f 1536 //lttvwindow_report_current_time(mw_data,&(tab->current_time));
49bf71b5 1537 break;
2176f952 1538 case GTK_RESPONSE_REJECT:
1539 case GTK_RESPONSE_CANCEL:
1540 default:
68b48a45 1541 gtk_widget_destroy((GtkWidget*)file_selector);
2176f952 1542 break;
1543 }
49bf71b5 1544}
1545
abe346a3 1546
1547/* remove_trace_into_traceset_selector, each instance of a viewer has an associated
1548 * selector (filter), when a trace is remove from traceset, the selector should
1549 * reflect the change. The function is used to update the selector
1550 */
b052368a 1551#if 0
1552void remove_trace_from_traceset_selector(GtkWidget * paned, unsigned i)
49bf71b5 1553{
1554 LttvTracesetSelector * s;
1555 LttvTraceSelector * t;
1556 GtkWidget * w;
1557
b052368a 1558 w = gtk_multivpaned_get_first_widget(GTK_MULTIVPANED(paned));
49bf71b5 1559 while(w){
1560 s = g_object_get_data(G_OBJECT(w), "Traceset_Selector");
abe346a3 1561 if(s){
1562 t = lttv_traceset_selector_trace_get(s,i);
1563 lttv_traceset_selector_trace_remove(s, i);
1564 lttv_trace_selector_destroy(t);
1565 }g_warning("Module dose not support filtering\n");
b052368a 1566 w = gtk_multivpaned_get_next_widget(GTK_MULTIVPANED(paned));
49bf71b5 1567 }
561eba2a 1568}
b052368a 1569#endif //0
abe346a3 1570
1571/* remove_trace removes a trace from the current traceset if all viewers in
1572 * the current tab are not interested in the trace. It first displays a
1573 * dialogue, which shows all traces in the current traceset, to let user choose
1574 * a trace, then it checks if all viewers unselect the trace, if it is true,
1575 * it will remove the trace, recreate the traceset_contex,
1576 * and redraws all the viewer of the current tab. If there is on trace in the
1577 * current traceset, it will delete all viewers of the current tab
1578 */
1579
b052368a 1580// MD : no filter version.
1581void remove_trace(GtkWidget *widget, gpointer user_data)
1582{
1583 LttTrace *trace;
1584 LttvTrace * trace_v;
1585 LttvTraceset * traceset;
1586 gint i, j, nb_trace, index=-1;
1587 char ** name, *remove_trace_name;
1588 MainWindow * mw_data = get_window_data_struct(widget);
1589 GtkWidget * notebook = lookup_widget(widget, "MNotebook");
1590
1591 GtkWidget *page = gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook),
1592 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook)));
1593 Tab *tab;
1594
1595 if(!page) {
1596 return;
1597 } else {
1598 tab = (Tab *)g_object_get_data(G_OBJECT(page), "Tab_Info");
1599 }
1600
1601 nb_trace =lttv_traceset_number(tab->traceset_info->traceset);
1602 name = g_new(char*,nb_trace);
1603 for(i = 0; i < nb_trace; i++){
1604 trace_v = lttv_traceset_get(tab->traceset_info->traceset, i);
1605 trace = lttv_trace(trace_v);
1606 name[i] = ltt_trace_name(trace);
1607 }
1608
1609 remove_trace_name = get_remove_trace(name, nb_trace);
1610
1611
1612 if(remove_trace_name){
1613
1614 /* yuk, cut n paste from old code.. should be better (MD)*/
1615 for(i = 0; i<nb_trace; i++) {
1616 if(strcmp(remove_trace_name,name[i]) == 0){
1617 index = i;
1618 }
1619 }
1620
1621 traceset = tab->traceset_info->traceset;
1622 //Keep a reference to the traces so they are not freed.
1623 for(j=0; j<lttv_traceset_number(traceset); j++)
1624 {
1625 LttvTrace * trace = lttv_traceset_get(traceset, j);
1626 lttv_trace_ref(trace);
1627 }
1628
1629 //remove state update hooks
1630 lttv_state_remove_event_hooks(
1631 (LttvTracesetState*)tab->traceset_info->traceset_context);
1632 lttv_context_fini(LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context));
1633 g_object_unref(tab->traceset_info->traceset_context);
1634
1635 trace_v = lttv_traceset_get(traceset, index);
1636
b052368a 1637 lttv_traceset_remove(traceset, index);
1638 lttv_trace_unref(trace_v); // Remove local reference
1639
1ba187d3 1640 if(lttv_trace_get_ref_number(trace_v) <= 1) {
1641 /* ref 1 : lttvwindowtraces only*/
1642 ltt_trace_close(lttv_trace(trace_v));
1643 /* lttvwindowtraces_remove_trace takes care of destroying
1644 * the traceset linked with the trace_v and also of destroying
1645 * the trace_v at the same time.
1646 */
1647 lttvwindowtraces_remove_trace(trace_v);
1648 }
b052368a 1649
1650 tab->traceset_info->traceset_context =
1651 g_object_new(LTTV_TRACESET_STATS_TYPE, NULL);
1652 lttv_context_init(
1653 LTTV_TRACESET_CONTEXT(tab->
1654 traceset_info->traceset_context),traceset);
1655 //add state update hooks
1656 lttv_state_add_event_hooks(
1657 (LttvTracesetState*)tab->traceset_info->traceset_context);
1658
1659 //Remove local reference to the traces.
1660 for(j=0; j<lttv_traceset_number(traceset); j++)
1661 {
1662 LttvTrace * trace = lttv_traceset_get(traceset, j);
1663 lttv_trace_unref(trace);
1664 }
1665
1666 SetTraceset(tab, (gpointer)traceset);
1667 }
1668 g_free(name);
1669}
1670
1671#if 0
561eba2a 1672void remove_trace(GtkWidget * widget, gpointer user_data)
1673{
2176f952 1674 LttTrace *trace;
1675 LttvTrace * trace_v;
1676 LttvTraceset * traceset;
a43d67ba 1677 gint i, j, nb_trace;
2176f952 1678 char ** name, *remove_trace_name;
bca3b81f 1679 MainWindow * mw_data = get_window_data_struct(widget);
49bf71b5 1680 LttvTracesetSelector * s;
1681 LttvTraceSelector * t;
1682 GtkWidget * w;
1683 gboolean selected;
6ced96ef 1684 GtkWidget * notebook = lookup_widget(widget, "MNotebook");
1685
1686 GtkWidget *page = gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook),
1687 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook)));
1688 Tab *tab;
1689
1690 if(!page) {
1691 return;
1692 } else {
1693 tab = (Tab *)g_object_get_data(G_OBJECT(page), "Tab_Info");
1694 }
1695
4266dc7f 1696 nb_trace =lttv_traceset_number(tab->traceset_info->traceset);
2176f952 1697 name = g_new(char*,nb_trace);
1698 for(i = 0; i < nb_trace; i++){
4266dc7f 1699 trace_v = lttv_traceset_get(tab->traceset_info->traceset, i);
2176f952 1700 trace = lttv_trace(trace_v);
a5dcde2f 1701 name[i] = ltt_trace_name(trace);
2176f952 1702 }
1703
1704 remove_trace_name = get_remove_trace(name, nb_trace);
1705
1706 if(remove_trace_name){
1707 for(i=0; i<nb_trace; i++){
1708 if(strcmp(remove_trace_name,name[i]) == 0){
6ced96ef 1709 //unselect the trace from the current viewer
b052368a 1710 //FIXME
1711 w = gtk_multivpaned_get_widget(GTK_MULTIVPANED(tab->multivpaned));
6ced96ef 1712 if(w){
1713 s = g_object_get_data(G_OBJECT(w), "Traceset_Selector");
1714 if(s){
1715 t = lttv_traceset_selector_trace_get(s,i);
1716 lttv_trace_selector_set_selected(t, FALSE);
1717 }
1718
1719 //check if other viewers select the trace
b052368a 1720 w = gtk_multivpaned_get_first_widget(GTK_MULTIVPANED(tab->multivpaned));
6ced96ef 1721 while(w){
1722 s = g_object_get_data(G_OBJECT(w), "Traceset_Selector");
1723 if(s){
1724 t = lttv_traceset_selector_trace_get(s,i);
1725 selected = lttv_trace_selector_get_selected(t);
1726 if(selected)break;
1727 }
b052368a 1728 w = gtk_multivpaned_get_next_widget(GTK_MULTIVPANED(tab->multivpaned));
6ced96ef 1729 }
1730 }else selected = FALSE;
49bf71b5 1731
6ced96ef 1732 //if no viewer selects the trace, remove it
1733 if(!selected){
b052368a 1734 remove_trace_from_traceset_selector(GTK_MULTIVPANED(tab->multivpaned), i);
49bf71b5 1735
6ced96ef 1736 traceset = tab->traceset_info->traceset;
1737 //Keep a reference to the traces so they are not freed.
1738 for(j=0; j<lttv_traceset_number(traceset); j++)
1739 {
1740 LttvTrace * trace = lttv_traceset_get(traceset, j);
1741 lttv_trace_ref(trace);
1742 }
a43d67ba 1743
6ced96ef 1744 //remove state update hooks
1745 lttv_state_remove_event_hooks(
1746 (LttvTracesetState*)tab->traceset_info->traceset_context);
1747 lttv_context_fini(LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context));
1748 g_object_unref(tab->traceset_info->traceset_context);
a43d67ba 1749
a43d67ba 1750
6ced96ef 1751 trace_v = lttv_traceset_get(traceset, i);
a43d67ba 1752
a1a2b649 1753 if(lttv_trace_get_ref_number(trace_v) <= 2) {
1754 /* ref 2 : traceset, local */
1755 lttvwindowtraces_remove_trace(trace_v);
6ced96ef 1756 ltt_trace_close(lttv_trace(trace_v));
a1a2b649 1757 }
6ced96ef 1758
1759 lttv_traceset_remove(traceset, i);
1760 lttv_trace_unref(trace_v); // Remove local reference
c2619a30 1761
6ced96ef 1762 if(!lttv_trace_get_ref_number(trace_v))
1763 lttv_trace_destroy(trace_v);
1764
1765 tab->traceset_info->traceset_context =
1766 g_object_new(LTTV_TRACESET_STATS_TYPE, NULL);
1767 lttv_context_init(
1768 LTTV_TRACESET_CONTEXT(tab->
1769 traceset_info->traceset_context),traceset);
1770 //add state update hooks
1771 lttv_state_add_event_hooks(
1772 (LttvTracesetState*)tab->traceset_info->traceset_context);
1773
1774 //Remove local reference to the traces.
1775 for(j=0; j<lttv_traceset_number(traceset); j++)
1776 {
1777 LttvTrace * trace = lttv_traceset_get(traceset, j);
1778 lttv_trace_unref(trace);
1779 }
a43d67ba 1780
a43d67ba 1781
6ced96ef 1782 //update current tab
1783 //update_traceset(mw_data);
313bd6fc 1784 //if(nb_trace > 1){
6ced96ef 1785
313bd6fc 1786 SetTraceset(tab, (gpointer)traceset);
6ced96ef 1787 // in expose now call_pending_read_hooks(mw_data);
1788
1789 //lttvwindow_report_current_time(mw_data,&(tab->current_time));
313bd6fc 1790 //}else{
1791 // if(tab){
1792 // while(tab->multi_vpaned->num_children){
1793 // gtk_multi_vpaned_widget_delete(tab->multi_vpaned);
1794 // }
1795 // }
1796 //}
6ced96ef 1797 }
1798 break;
2176f952 1799 }
1800 }
1801 }
1802
1803 g_free(name);
561eba2a 1804}
b052368a 1805#endif //0
abe346a3 1806
9878c8a4 1807/* Redraw all the viewers in the current tab */
1808void redraw(GtkWidget *widget, gpointer user_data)
1809{
1810 GtkWidget * notebook = lookup_widget(widget, "MNotebook");
1811 GtkWidget *page = gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook),
1812 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook)));
1813 Tab *tab;
1814 if(!page) {
1815 return;
1816 } else {
1817 tab = (Tab *)g_object_get_data(G_OBJECT(page), "Tab_Info");
1818 }
1819
1820 LttvHooks * tmp;
1821 LttvAttributeValue value;
1822
1823 g_assert(lttv_iattribute_find_by_path(tab->attributes, "hooks/redraw", LTTV_POINTER, &value));
1824
1825 tmp = (LttvHooks*)*(value.v_pointer);
c07e9b26 1826 if(tmp != NULL)
1827 lttv_hooks_call(tmp,NULL);
9878c8a4 1828}
1829
1830
1831void continue_processing(GtkWidget *widget, gpointer user_data)
1832{
1833 GtkWidget * notebook = lookup_widget(widget, "MNotebook");
1834 GtkWidget *page = gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook),
1835 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook)));
1836 Tab *tab;
1837 if(!page) {
1838 return;
1839 } else {
1840 tab = (Tab *)g_object_get_data(G_OBJECT(page), "Tab_Info");
1841 }
1842
1843 LttvHooks * tmp;
1844 LttvAttributeValue value;
1845
1846 g_assert(lttv_iattribute_find_by_path(tab->attributes,
1847 "hooks/continue", LTTV_POINTER, &value));
1848
1849 tmp = (LttvHooks*)*(value.v_pointer);
c07e9b26 1850 if(tmp != NULL)
1851 lttv_hooks_call(tmp,NULL);
9878c8a4 1852}
1853
1854/* Stop the processing for the calling main window's current tab.
1855 * It removes every processing requests that are in its list. It does not call
1856 * the end request hooks, because the request is not finished.
1857 */
1858
1859void stop_processing(GtkWidget *widget, gpointer user_data)
1860{
1861 GtkWidget * notebook = lookup_widget(widget, "MNotebook");
1862 GtkWidget *page = gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook),
1863 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook)));
1864 Tab *tab;
1865 if(!page) {
1866 return;
1867 } else {
1868 tab = (Tab *)g_object_get_data(G_OBJECT(page), "Tab_Info");
1869 }
a0577796 1870 GSList *iter = tab->events_requests;
9878c8a4 1871
1872 while(iter != NULL) {
1873 GSList *remove_iter = iter;
1874 iter = g_slist_next(iter);
1875
1876 g_free(remove_iter->data);
a0577796 1877 tab->events_requests =
1878 g_slist_remove_link(tab->events_requests, remove_iter);
9878c8a4 1879 }
a0577796 1880 tab->events_request_pending = FALSE;
1881 g_idle_remove_by_data(tab);
1882 g_assert(g_slist_length(tab->events_requests) == 0);
9878c8a4 1883}
1884
1885
abe346a3 1886/* save will save the traceset to a file
a43d67ba 1887 * Not implemented yet FIXME
abe346a3 1888 */
1889
561eba2a 1890void save(GtkWidget * widget, gpointer user_data)
1891{
1892 g_printf("Save\n");
1893}
1894
1895void save_as(GtkWidget * widget, gpointer user_data)
1896{
1897 g_printf("Save as\n");
1898}
1899
abe346a3 1900
1901/* zoom will change the time_window of all the viewers of the
1902 * current tab, and redisplay them. The main functionality is to
1903 * determine the new time_window of the current tab
1904 */
1905
1f1ae829 1906void zoom(GtkWidget * widget, double size)
1907{
b052368a 1908 TimeInterval time_span;
a43d67ba 1909 TimeWindow new_time_window;
1910 LttTime current_time, time_delta, time_s, time_e, time_tmp;
1f1ae829 1911 MainWindow * mw_data = get_window_data_struct(widget);
4266dc7f 1912 LttvTracesetContext *tsc;
6ced96ef 1913 GtkWidget * notebook = lookup_widget(widget, "MNotebook");
1914
1915 GtkWidget *page = gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook),
1916 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook)));
1917 Tab *tab;
1918
1919 if(!page) {
1920 return;
1921 } else {
1922 tab = (Tab *)g_object_get_data(G_OBJECT(page), "Tab_Info");
1923 }
1f1ae829 1924
fda16332 1925 if(size == 1) return;
1926
4266dc7f 1927 tsc = LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context);
b052368a 1928 time_span = tsc->time_span;
501e4e70 1929 new_time_window = tab->time_window;
1930 current_time = tab->current_time;
1f1ae829 1931
b052368a 1932 time_delta = ltt_time_sub(time_span.end_time,time_span.start_time);
1f1ae829 1933 if(size == 0){
b052368a 1934 new_time_window.start_time = time_span.start_time;
a43d67ba 1935 new_time_window.time_width = time_delta;
1f1ae829 1936 }else{
a43d67ba 1937 new_time_window.time_width = ltt_time_div(new_time_window.time_width, size);
1938 if(ltt_time_compare(new_time_window.time_width,time_delta) > 0)
1939 { /* Case where zoom out is bigger than trace length */
b052368a 1940 new_time_window.start_time = time_span.start_time;
a43d67ba 1941 new_time_window.time_width = time_delta;
a8c0f09d 1942 }
a43d67ba 1943 else
1944 {
1945 /* Center the image on the current time */
a43d67ba 1946 new_time_window.start_time =
1947 ltt_time_sub(current_time, ltt_time_div(new_time_window.time_width, 2.0));
1948 /* If on borders, don't fall off */
b052368a 1949 if(ltt_time_compare(new_time_window.start_time, time_span.start_time) <0)
a43d67ba 1950 {
b052368a 1951 new_time_window.start_time = time_span.start_time;
a43d67ba 1952 }
1953 else
1954 {
1955 if(ltt_time_compare(
1956 ltt_time_add(new_time_window.start_time, new_time_window.time_width),
b052368a 1957 time_span.end_time) > 0)
a43d67ba 1958 {
1959 new_time_window.start_time =
b052368a 1960 ltt_time_sub(time_span.end_time, new_time_window.time_width);
a43d67ba 1961 }
1962 }
1963
1f1ae829 1964 }
a43d67ba 1965
a43d67ba 1966 //time_tmp = ltt_time_div(new_time_window.time_width, 2);
1967 //if(ltt_time_compare(current_time, time_tmp) < 0){
1968 // time_s = time_span->startTime;
1969 //} else {
1970 // time_s = ltt_time_sub(current_time,time_tmp);
1971 //}
1972 //time_e = ltt_time_add(current_time,time_tmp);
1973 //if(ltt_time_compare(time_span->startTime, time_s) > 0){
1974 // time_s = time_span->startTime;
1975 //}else if(ltt_time_compare(time_span->endTime, time_e) < 0){
1976 // time_e = time_span->endTime;
1977 // time_s = ltt_time_sub(time_e,new_time_window.time_width);
1978 //}
1979 //new_time_window.start_time = time_s;
1f1ae829 1980 }
a43d67ba 1981
1982 //lttvwindow_report_time_window(mw_data, &new_time_window);
1983 //call_pending_read_hooks(mw_data);
1984
4266dc7f 1985 //lttvwindow_report_current_time(mw_data,&(tab->current_time));
b052368a 1986 //set_time_window(tab, &new_time_window);
a43d67ba 1987 // in expose now call_pending_read_hooks(mw_data);
b052368a 1988 //gtk_multi_vpaned_set_adjust(tab->multi_vpaned, &new_time_window, FALSE);
1989 //
1990 //
1991
0c5dbe3b 1992 LttTime rel_time =
1993 ltt_time_sub(new_time_window.start_time, time_span.start_time);
b052368a 1994 if( ltt_time_to_double(new_time_window.time_width)
1995 * NANOSECONDS_PER_SECOND
1996 / SCROLL_STEP_PER_PAGE/* step increment */
1997 +
0c5dbe3b 1998 ltt_time_to_double(rel_time) * NANOSECONDS_PER_SECOND /* page size */
b052368a 1999 ==
0c5dbe3b 2000 ltt_time_to_double(rel_time) * NANOSECONDS_PER_SECOND /* page size */
b052368a 2001 ) {
2002 g_warning("Can not zoom that far due to scrollbar precision");
2003 } else if(
2004 ltt_time_compare(
2005 ltt_time_from_double(
2006 ltt_time_to_double(new_time_window.time_width)
2007 /SCROLL_STEP_PER_PAGE ),
2008 ltt_time_zero)
2009 == 0 ) {
2010 g_warning("Can not zoom that far due to time nanosecond precision");
2011 } else {
2012 /* Set scrollbar */
2013 GtkAdjustment *adjustment = gtk_range_get_adjustment(GTK_RANGE(tab->scrollbar));
2014
2015 g_object_set(G_OBJECT(adjustment),
2016 //"value",
2017 //ltt_time_to_double(new_time_window.start_time)
2018 // * NANOSECONDS_PER_SECOND, /* value */
2019 "lower",
0c5dbe3b 2020 0.0, /* lower */
b052368a 2021 "upper",
b9a010a2 2022 ltt_time_to_double(
2023 ltt_time_sub(time_span.end_time, time_span.start_time))
b052368a 2024 * NANOSECONDS_PER_SECOND, /* upper */
2025 "step_increment",
2026 ltt_time_to_double(new_time_window.time_width)
2027 / SCROLL_STEP_PER_PAGE
2028 * NANOSECONDS_PER_SECOND, /* step increment */
2029 "page_increment",
2030 ltt_time_to_double(new_time_window.time_width)
2031 * NANOSECONDS_PER_SECOND, /* page increment */
2032 "page_size",
2033 ltt_time_to_double(new_time_window.time_width)
2034 * NANOSECONDS_PER_SECOND, /* page size */
2035 NULL);
2036 gtk_adjustment_changed(adjustment);
2037 //gtk_range_set_adjustment(GTK_RANGE(tab->scrollbar), adjustment);
2038 //gtk_adjustment_value_changed(adjustment);
2039 g_object_set(G_OBJECT(adjustment),
2040 "value",
b9a010a2 2041 ltt_time_to_double(
2042 ltt_time_sub(new_time_window.start_time, time_span.start_time))
b052368a 2043 * NANOSECONDS_PER_SECOND, /* value */
2044 NULL);
2045 gtk_adjustment_value_changed(adjustment);
2046
2047
2048 //g_object_set(G_OBJECT(adjustment),
2049 // "value",
2050 // ltt_time_to_double(time_window->start_time)
2051 // * NANOSECONDS_PER_SECOND, /* value */
2052 // NULL);
2053 /* Note : the set value will call set_time_window if scrollbar value changed
2054 */
2055 //gtk_adjustment_set_value(adjustment,
2056 // ltt_time_to_double(new_time_window.start_time)
2057 // * NANOSECONDS_PER_SECOND);
2058 }
1f1ae829 2059}
2060
561eba2a 2061void zoom_in(GtkWidget * widget, gpointer user_data)
2062{
1f1ae829 2063 zoom(widget, 2);
561eba2a 2064}
2065
2066void zoom_out(GtkWidget * widget, gpointer user_data)
2067{
1f1ae829 2068 zoom(widget, 0.5);
561eba2a 2069}
2070
2071void zoom_extended(GtkWidget * widget, gpointer user_data)
2072{
1f1ae829 2073 zoom(widget, 0);
561eba2a 2074}
2075
2076void go_to_time(GtkWidget * widget, gpointer user_data)
2077{
2078 g_printf("Go to time\n");
2079}
2080
2081void show_time_frame(GtkWidget * widget, gpointer user_data)
2082{
2083 g_printf("Show time frame\n");
2084}
2085
2086
2087/* callback function */
2088
2089void
2090on_empty_traceset_activate (GtkMenuItem *menuitem,
2091 gpointer user_data)
2092{
68b48a45 2093 create_new_window((GtkWidget*)menuitem, user_data, FALSE);
561eba2a 2094}
2095
2096
2097void
2098on_clone_traceset_activate (GtkMenuItem *menuitem,
2099 gpointer user_data)
2100{
68b48a45 2101 create_new_window((GtkWidget*)menuitem, user_data, TRUE);
561eba2a 2102}
2103
abe346a3 2104
2105/* create_new_tab calls create_tab to construct a new tab in the main window
2106 */
2107
6ced96ef 2108Tab *create_new_tab(GtkWidget* widget, gpointer user_data){
a1a2b649 2109 gchar label[PATH_MAX];
2901f314 2110 MainWindow * mw_data = get_window_data_struct(widget);
4266dc7f 2111
2901f314 2112 GtkNotebook * notebook = (GtkNotebook *)lookup_widget(widget, "MNotebook");
561eba2a 2113 if(notebook == NULL){
2114 g_printf("Notebook does not exist\n");
6ced96ef 2115 return NULL;
2116 }
2117 GtkWidget *page = gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook),
2118 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook)));
2119 Tab *copy_tab;
2120
2121 if(!page) {
2122 copy_tab = NULL;
2123 } else {
2124 copy_tab = (Tab *)g_object_get_data(G_OBJECT(page), "Tab_Info");
561eba2a 2125 }
4266dc7f 2126
6b1d3120 2127 strcpy(label,"Page");
eb38aea5 2128 if(get_label(mw_data, label,"Get the name of the tab","Please input tab's name"))
6ced96ef 2129 return (create_tab (mw_data, copy_tab, notebook, label));
561eba2a 2130}
2131
2901f314 2132void
2133on_tab_activate (GtkMenuItem *menuitem,
2134 gpointer user_data)
2135{
2136 create_new_tab((GtkWidget*)menuitem, user_data);
2137}
2138
561eba2a 2139
2140void
2141on_open_activate (GtkMenuItem *menuitem,
2142 gpointer user_data)
2143{
2144 open_traceset((GtkWidget*)menuitem, user_data);
2145}
2146
2147
2148void
2149on_close_activate (GtkMenuItem *menuitem,
2150 gpointer user_data)
2151{
bca3b81f 2152 MainWindow * mw_data = get_window_data_struct((GtkWidget*)menuitem);
68b48a45 2153 main_window_destructor(mw_data);
561eba2a 2154}
2155
2156
4266dc7f 2157/* remove the current tab from the main window
abe346a3 2158 */
2159
561eba2a 2160void
27a559b9 2161on_close_tab_activate (GtkWidget *widget,
561eba2a 2162 gpointer user_data)
2163{
4266dc7f 2164 gint page_num;
2061e03d 2165 GtkWidget * notebook;
4266dc7f 2166 GtkWidget * page;
27a559b9 2167 MainWindow * mw_data = get_window_data_struct(widget);
2168 notebook = lookup_widget(widget, "MNotebook");
2061e03d 2169 if(notebook == NULL){
2170 g_printf("Notebook does not exist\n");
2171 return;
2172 }
4266dc7f 2173
2174 page_num = gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook));
2061e03d 2175
4266dc7f 2176 gtk_notebook_remove_page(GTK_NOTEBOOK(notebook), page_num);
2061e03d 2177
561eba2a 2178}
2179
27a559b9 2180void
2181on_close_tab_X_clicked (GtkWidget *widget,
2182 gpointer user_data)
2183{
2184 gint page_num;
2185 GtkWidget *notebook = lookup_widget(widget, "MNotebook");
2186 if(notebook == NULL){
2187 g_printf("Notebook does not exist\n");
2188 return;
2189 }
2190
2191 if((page_num = gtk_notebook_page_num(GTK_NOTEBOOK(notebook), widget)) != -1)
2192 gtk_notebook_remove_page(GTK_NOTEBOOK(notebook), page_num);
2193
2194}
2195
561eba2a 2196
2197void
2198on_add_trace_activate (GtkMenuItem *menuitem,
2199 gpointer user_data)
2200{
2201 add_trace((GtkWidget*)menuitem, user_data);
2202}
2203
2204
2205void
2206on_remove_trace_activate (GtkMenuItem *menuitem,
2207 gpointer user_data)
2208{
2209 remove_trace((GtkWidget*)menuitem, user_data);
2210}
2211
2212
2213void
2214on_save_activate (GtkMenuItem *menuitem,
2215 gpointer user_data)
2216{
2217 save((GtkWidget*)menuitem, user_data);
2218}
2219
2220
2221void
2222on_save_as_activate (GtkMenuItem *menuitem,
2223 gpointer user_data)
2224{
2225 save_as((GtkWidget*)menuitem, user_data);
2226}
2227
2228
2229void
2230on_quit_activate (GtkMenuItem *menuitem,
2231 gpointer user_data)
2232{
2061e03d 2233 gtk_main_quit ();
561eba2a 2234}
2235
2236
2237void
2238on_cut_activate (GtkMenuItem *menuitem,
2239 gpointer user_data)
2240{
2241 g_printf("Cut\n");
2242}
2243
2244
2245void
2246on_copy_activate (GtkMenuItem *menuitem,
2247 gpointer user_data)
2248{
2249 g_printf("Copye\n");
2250}
2251
2252
2253void
2254on_paste_activate (GtkMenuItem *menuitem,
2255 gpointer user_data)
2256{
2257 g_printf("Paste\n");
2258}
2259
2260
2261void
2262on_delete_activate (GtkMenuItem *menuitem,
2263 gpointer user_data)
2264{
2265 g_printf("Delete\n");
2266}
2267
2268
2269void
2270on_zoom_in_activate (GtkMenuItem *menuitem,
2271 gpointer user_data)
2272{
2273 zoom_in((GtkWidget*)menuitem, user_data);
2274}
2275
2276
2277void
2278on_zoom_out_activate (GtkMenuItem *menuitem,
2279 gpointer user_data)
2280{
2281 zoom_out((GtkWidget*)menuitem, user_data);
2282}
2283
2284
2285void
2286on_zoom_extended_activate (GtkMenuItem *menuitem,
2287 gpointer user_data)
2288{
2289 zoom_extended((GtkWidget*)menuitem, user_data);
2290}
2291
2292
2293void
2294on_go_to_time_activate (GtkMenuItem *menuitem,
2295 gpointer user_data)
2296{
2297 go_to_time((GtkWidget*)menuitem, user_data);
2298}
2299
2300
2301void
2302on_show_time_frame_activate (GtkMenuItem *menuitem,
2303 gpointer user_data)
2304{
2305 show_time_frame((GtkWidget*)menuitem, user_data);
2306}
2307
2308
2309void
2310on_move_viewer_up_activate (GtkMenuItem *menuitem,
2311 gpointer user_data)
2312{
2313 move_up_viewer((GtkWidget*)menuitem, user_data);
2314}
2315
2316
2317void
2318on_move_viewer_down_activate (GtkMenuItem *menuitem,
2319 gpointer user_data)
2320{
2321 move_down_viewer((GtkWidget*)menuitem, user_data);
2322}
2323
2324
2325void
2326on_remove_viewer_activate (GtkMenuItem *menuitem,
2327 gpointer user_data)
2328{
2329 delete_viewer((GtkWidget*)menuitem, user_data);
2330}
2331
b052368a 2332#if 0
49bf71b5 2333void
2334on_trace_filter_activate (GtkMenuItem *menuitem,
2335 gpointer user_data)
2336{
2337 MainWindow * mw_data = get_window_data_struct((GtkWidget*)menuitem);
2338 LttvTracesetSelector * s;
4266dc7f 2339 GtkWidget * w;
6ced96ef 2340 GtkWidget * notebook = lookup_widget(GTK_WIDGET(menuitem), "MNotebook");
2341
2342 GtkWidget *page = gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook),
2343 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook)));
2344 Tab *tab;
2345
2346 if(!page) {
2347 return;
2348 } else {
2349 tab = (Tab *)g_object_get_data(G_OBJECT(page), "Tab_Info");
2350 }
4266dc7f 2351
b052368a 2352 w = gtk_multivpaned_get_widget(GTK_MULTIVPANED(tab->multivpaned));
49bf71b5 2353
2354 s = g_object_get_data(G_OBJECT(w), "Traceset_Selector");
2355 if(!s){
2356 g_printf("There is no viewer yet\n");
2357 return;
2358 }
a8c0f09d 2359 if(get_filter_selection(s, "Configure trace and tracefile filter", "Select traces and tracefiles")){
a43d67ba 2360 //FIXME report filter change
2361 //update_traceset(mw_data);
2362 //call_pending_read_hooks(mw_data);
4266dc7f 2363 //lttvwindow_report_current_time(mw_data,&(tab->current_time));
a8c0f09d 2364 }
49bf71b5 2365}
b052368a 2366#endif //0
49bf71b5 2367
2368void
2369on_trace_facility_activate (GtkMenuItem *menuitem,
2370 gpointer user_data)
2371{
2372 g_printf("Trace facility selector: %s\n");
2373}
561eba2a 2374
abe346a3 2375
b052368a 2376/* Dispaly a file selection dialogue to let user select a library, then call
2377 * lttv_library_load().
2378 */
2379
2380void
2381on_load_library_activate (GtkMenuItem *menuitem,
2382 gpointer user_data)
2383{
2384 GError *error = NULL;
2385 MainWindow * mw_data = get_window_data_struct((GtkWidget*)menuitem);
2386
2387 gchar load_module_path_alter[PATH_MAX];
2388 {
2389 GPtrArray *name;
2390 guint nb,i;
2391 gchar *load_module_path;
2392 name = g_ptr_array_new();
2393 nb = lttv_library_path_number();
2394 /* ask for the library path */
2395
2396 for(i=0;i<nb;i++){
2397 gchar *path;
2398 path = lttv_library_path_get(i);
2399 g_ptr_array_add(name, path);
2400 }
2401
2402 load_module_path = get_selection((char **)(name->pdata), name->len,
2403 "Select a library path", "Library paths");
2404 if(load_module_path != NULL)
2405 strncpy(load_module_path_alter, load_module_path, PATH_MAX-1); // -1 for /
2406
2407 g_ptr_array_free(name, TRUE);
2408
2409 if(load_module_path == NULL) return;
2410 }
2411
2412 {
2413 /* Make sure the module path ends with a / */
2414 gchar *ptr = load_module_path_alter;
2415
2416 ptr = strchr(ptr, '\0');
2417
2418 if(*(ptr-1) != '/') {
2419 *ptr = '/';
2420 *(ptr+1) = '\0';
2421 }
2422 }
2423
2424 {
2425 /* Ask for the library to load : list files in the previously selected
2426 * directory */
2427 gchar str[PATH_MAX];
2428 gchar ** dir;
2429 gint id;
2430 GtkFileSelection * file_selector =
2431 (GtkFileSelection *)gtk_file_selection_new("Select a module");
2432 gtk_file_selection_set_filename(file_selector, load_module_path_alter);
2433 gtk_file_selection_hide_fileop_buttons(file_selector);
2434
2435 str[0] = '\0';
2436 id = gtk_dialog_run(GTK_DIALOG(file_selector));
2437 switch(id){
2438 case GTK_RESPONSE_ACCEPT:
2439 case GTK_RESPONSE_OK:
2440 dir = gtk_file_selection_get_selections (file_selector);
2441 strncpy(str,dir[0],PATH_MAX);
2442 strncpy(remember_plugins_dir,dir[0],PATH_MAX);
2443 /* only keep file name */
2444 gchar *str1;
2445 str1 = strrchr(str,'/');
2446 if(str1)str1++;
2447 else{
2448 str1 = strrchr(str,'\\');
2449 str1++;
2450 }
2451#if 0
2452 /* remove "lib" */
2453 if(*str1 == 'l' && *(str1+1)== 'i' && *(str1+2)=='b')
2454 str1=str1+3;
2455 remove info after . */
2456 {
2457 gchar *str2 = str1;
2458
2459 str2 = strrchr(str2, '.');
2460 if(str2 != NULL) *str2 = '\0';
2461 }
2462 lttv_module_require(str1, &error);
2463#endif //0
2464 lttv_library_load(str1, &error);
2465 if(error != NULL) g_warning(error->message);
2466 else g_printf("Load library: %s\n", str);
2467 g_strfreev(dir);
2468 case GTK_RESPONSE_REJECT:
2469 case GTK_RESPONSE_CANCEL:
2470 default:
2471 gtk_widget_destroy((GtkWidget*)file_selector);
2472 break;
2473 }
2474
2475 }
2476
2477
2478
2479}
2480
2481
2482/* Display all loaded modules, let user to select a module to unload
2483 * by calling lttv_module_unload
2484 */
2485
2486void
2487on_unload_library_activate (GtkMenuItem *menuitem,
2488 gpointer user_data)
2489{
2490 MainWindow * mw_data = get_window_data_struct((GtkWidget*)menuitem);
2491
2492 LttvLibrary *library;
2493 {
2494 GPtrArray *name;
2495 guint nb,i;
2496 gchar *lib_name;
2497 name = g_ptr_array_new();
2498 nb = lttv_library_number();
2499 LttvLibraryInfo *lib_info = g_new(LttvLibraryInfo,nb);
2500 /* ask for the library name */
2501
2502 for(i=0;i<nb;i++){
2503 LttvLibrary *iter_lib = lttv_library_get(i);
2504 lttv_library_info(iter_lib, &lib_info[i]);
2505
2506 gchar *path = lib_info[i].name;
2507 g_ptr_array_add(name, lib_info[i].name);
2508 }
2509 lib_name = get_selection((char **)(name->pdata), name->len,
2510 "Select a library", "Libraries");
2511 if(lib_name != NULL) {
2512 for(i=0;i<nb;i++){
2513 if(strcmp(lib_name, lib_info[i].name) == 0) {
2514 library = lttv_library_get(i);
2515 break;
2516 }
2517 }
2518 }
2519 g_ptr_array_free(name, TRUE);
2520 g_free(lib_info);
2521
2522 if(lib_name == NULL) return;
2523 }
2524
2525 lttv_library_unload(library);
2526}
2527
2528
abe346a3 2529/* Dispaly a file selection dialogue to let user select a module, then call
b052368a 2530 * lttv_module_require().
abe346a3 2531 */
2532
561eba2a 2533void
2534on_load_module_activate (GtkMenuItem *menuitem,
2535 gpointer user_data)
2536{
b052368a 2537 GError *error = NULL;
bca3b81f 2538 MainWindow * mw_data = get_window_data_struct((GtkWidget*)menuitem);
b052368a 2539
2540 LttvLibrary *library;
2541 {
2542 GPtrArray *name;
2543 guint nb,i;
2544 gchar *lib_name;
2545 name = g_ptr_array_new();
2546 nb = lttv_library_number();
2547 LttvLibraryInfo *lib_info = g_new(LttvLibraryInfo,nb);
2548 /* ask for the library name */
2549
2550 for(i=0;i<nb;i++){
2551 LttvLibrary *iter_lib = lttv_library_get(i);
2552 lttv_library_info(iter_lib, &lib_info[i]);
2553
2554 gchar *path = lib_info[i].name;
2555 g_ptr_array_add(name, path);
2556 }
2557 lib_name = get_selection((char **)(name->pdata), name->len,
2558 "Select a library", "Libraries");
2559 if(lib_name != NULL) {
2560 for(i=0;i<nb;i++){
2561 if(strcmp(lib_name, lib_info[i].name) == 0) {
2562 library = lttv_library_get(i);
2563 break;
2564 }
3872a20e 2565 }
b052368a 2566 }
2567 g_ptr_array_free(name, TRUE);
2568 g_free(lib_info);
2569
2570 if(lib_name == NULL) return;
36b3c068 2571 }
b052368a 2572
2573 //LttvModule *module;
2574 gchar module_name_out[PATH_MAX];
2575 {
2576 /* Ask for the module to load : list modules in the selected lib */
2577 GPtrArray *name;
2578 guint nb,i;
2579 gchar *module_name;
2580 LttvModuleInfo *module_info = g_new(LttvModuleInfo,nb);
2581 name = g_ptr_array_new();
2582 nb = lttv_library_module_number(library);
2583 /* ask for the module name */
2584
2585 for(i=0;i<nb;i++){
2586 LttvModule *iter_module = lttv_library_module_get(library, i);
2587 lttv_module_info(iter_module, &module_info[i]);
2588
2589 gchar *path = module_info[i].name;
2590 g_ptr_array_add(name, path);
2591 }
2592 module_name = get_selection((char **)(name->pdata), name->len,
2593 "Select a module", "Modules");
2594 if(module_name != NULL) {
2595 for(i=0;i<nb;i++){
2596 if(strcmp(module_name, module_info[i].name) == 0) {
2597 strncpy(module_name_out, module_name, PATH_MAX);
2598 //module = lttv_library_module_get(i);
2599 break;
2600 }
2601 }
2602 }
2603
2604 g_ptr_array_free(name, TRUE);
2605 g_free(module_info);
2606
2607 if(module_name == NULL) return;
2608 }
2609
2610 lttv_module_require(module_name_out, &error);
2611 if(error != NULL) g_warning(error->message);
2612 else g_printf("Load module: %s\n", module_name_out);
2613
2614
2615#if 0
2616 {
2617
2618
2619 gchar str[PATH_MAX];
2620 gchar ** dir;
2621 gint id;
2622 GtkFileSelection * file_selector =
2623 (GtkFileSelection *)gtk_file_selection_new("Select a module");
2624 gtk_file_selection_set_filename(file_selector, load_module_path_alter);
2625 gtk_file_selection_hide_fileop_buttons(file_selector);
2626
2627 str[0] = '\0';
2628 id = gtk_dialog_run(GTK_DIALOG(file_selector));
2629 switch(id){
2630 case GTK_RESPONSE_ACCEPT:
2631 case GTK_RESPONSE_OK:
2632 dir = gtk_file_selection_get_selections (file_selector);
2633 strncpy(str,dir[0],PATH_MAX);
2634 strncpy(remember_plugins_dir,dir[0],PATH_MAX);
2635 {
2636 /* only keep file name */
2637 gchar *str1;
2638 str1 = strrchr(str,'/');
2639 if(str1)str1++;
2640 else{
2641 str1 = strrchr(str,'\\');
2642 str1++;
2643 }
2644#if 0
2645 /* remove "lib" */
2646 if(*str1 == 'l' && *(str1+1)== 'i' && *(str1+2)=='b')
2647 str1=str1+3;
2648 remove info after . */
2649 {
2650 gchar *str2 = str1;
2651
2652 str2 = strrchr(str2, '.');
2653 if(str2 != NULL) *str2 = '\0';
2654 }
2655 lttv_module_require(str1, &error);
2656#endif //0
2657 lttv_library_load(str1, &error);
2658 if(error != NULL) g_warning(error->message);
2659 else g_printf("Load library: %s\n", str);
2660 g_strfreev(dir);
2661 case GTK_RESPONSE_REJECT:
2662 case GTK_RESPONSE_CANCEL:
2663 default:
2664 gtk_widget_destroy((GtkWidget*)file_selector);
2665 break;
2666 }
2667
2668 }
2669#endif //0
2670
2671
561eba2a 2672}
2673
2674
b052368a 2675
abe346a3 2676/* Display all loaded modules, let user to select a module to unload
2677 * by calling lttv_module_unload
2678 */
2679
561eba2a 2680void
2681on_unload_module_activate (GtkMenuItem *menuitem,
2682 gpointer user_data)
2683{
b052368a 2684 GError *error = NULL;
bca3b81f 2685 MainWindow * mw_data = get_window_data_struct((GtkWidget*)menuitem);
08b1c66e 2686
b052368a 2687 LttvLibrary *library;
2688 {
2689 GPtrArray *name;
2690 guint nb,i;
2691 gchar *lib_name;
2692 name = g_ptr_array_new();
2693 nb = lttv_library_number();
2694 LttvLibraryInfo *lib_info = g_new(LttvLibraryInfo,nb);
2695 /* ask for the library name */
36b3c068 2696
36b3c068 2697 for(i=0;i<nb;i++){
b052368a 2698 LttvLibrary *iter_lib = lttv_library_get(i);
2699 lttv_library_info(iter_lib, &lib_info[i]);
2700
2701 gchar *path = lib_info[i].name;
2702 g_ptr_array_add(name, path);
2703 }
2704 lib_name = get_selection((char **)(name->pdata), name->len,
2705 "Select a library", "Libraries");
2706 if(lib_name != NULL) {
2707 for(i=0;i<nb;i++){
2708 if(strcmp(lib_name, lib_info[i].name) == 0) {
2709 library = lttv_library_get(i);
2710 break;
2711 }
36b3c068 2712 }
b052368a 2713 }
2714 g_ptr_array_free(name, TRUE);
2715 g_free(lib_info);
2716
2717 if(lib_name == NULL) return;
36b3c068 2718 }
2719
b052368a 2720 LttvModule *module;
2721 {
2722 /* Ask for the module to load : list modules in the selected lib */
2723 GPtrArray *name;
2724 guint nb,i;
2725 gchar *module_name;
6d677a86 2726 nb = lttv_library_module_number(library);
b052368a 2727 LttvModuleInfo *module_info = g_new(LttvModuleInfo,nb);
2728 name = g_ptr_array_new();
b052368a 2729 /* ask for the module name */
2730
2731 for(i=0;i<nb;i++){
2732 LttvModule *iter_module = lttv_library_module_get(library, i);
2733 lttv_module_info(iter_module, &module_info[i]);
2734
2735 gchar *path = module_info[i].name;
2736 if(module_info[i].use_count > 0) g_ptr_array_add(name, path);
2737 }
2738 module_name = get_selection((char **)(name->pdata), name->len,
2739 "Select a module", "Modules");
2740 if(module_name != NULL) {
2741 for(i=0;i<nb;i++){
2742 if(strcmp(module_name, module_info[i].name) == 0) {
2743 module = lttv_library_module_get(library, i);
2744 break;
2745 }
2746 }
2747 }
2748
2749 g_ptr_array_free(name, TRUE);
2750 g_free(module_info);
2751
2752 if(module_name == NULL) return;
2753 }
2754
b052368a 2755 LttvModuleInfo module_info;
2756 lttv_module_info(module, &module_info);
2757 g_printf("Release module: %s\n", module_info.name);
fce9a2fc 2758
2759 lttv_module_release(module);
561eba2a 2760}
2761
2762
b052368a 2763/* Display a directory dialogue to let user select a path for library searching
abe346a3 2764 */
2765
561eba2a 2766void
b052368a 2767on_add_library_search_path_activate (GtkMenuItem *menuitem,
561eba2a 2768 gpointer user_data)
2769{
b052368a 2770 GtkDirSelection * file_selector = (GtkDirSelection *)gtk_dir_selection_new("Select library path");
67b98724 2771 const char * dir;
fc188b78 2772 gint id;
2773
bca3b81f 2774 MainWindow * mw_data = get_window_data_struct((GtkWidget*)menuitem);
3658a338 2775 if(remember_plugins_dir[0] != '\0')
2776 gtk_dir_selection_set_filename(file_selector, remember_plugins_dir);
fc188b78 2777
68b48a45 2778 id = gtk_dialog_run(GTK_DIALOG(file_selector));
fc188b78 2779 switch(id){
2780 case GTK_RESPONSE_ACCEPT:
2781 case GTK_RESPONSE_OK:
68b48a45 2782 dir = gtk_dir_selection_get_dir (file_selector);
a1a2b649 2783 strncpy(remember_plugins_dir,dir,PATH_MAX);
2784 strncat(remember_plugins_dir,"/",PATH_MAX);
08b1c66e 2785 lttv_library_path_add(dir);
fc188b78 2786 case GTK_RESPONSE_REJECT:
2787 case GTK_RESPONSE_CANCEL:
2788 default:
68b48a45 2789 gtk_widget_destroy((GtkWidget*)file_selector);
fc188b78 2790 break;
6b1d3120 2791 }
561eba2a 2792}
2793
2794
b052368a 2795/* Display a directory dialogue to let user select a path for library searching
2796 */
2797
2798void
2799on_remove_library_search_path_activate (GtkMenuItem *menuitem,
2800 gpointer user_data)
2801{
2802 MainWindow * mw_data = get_window_data_struct((GtkWidget*)menuitem);
2803
2804 const char *lib_path;
2805 {
2806 GPtrArray *name;
2807 guint nb,i;
2808 gchar *lib_name;
2809 name = g_ptr_array_new();
2810 nb = lttv_library_path_number();
2811 /* ask for the library name */
2812
2813 for(i=0;i<nb;i++){
2814 gchar *path = lttv_library_path_get(i);
2815 g_ptr_array_add(name, path);
2816 }
2817 lib_path = get_selection((char **)(name->pdata), name->len,
2818 "Select a library path", "Library paths");
2819
2820 g_ptr_array_free(name, TRUE);
2821
2822 if(lib_path == NULL) return;
2823 }
2824
2825 lttv_library_path_remove(lib_path);
2826}
2827
561eba2a 2828void
2829on_color_activate (GtkMenuItem *menuitem,
2830 gpointer user_data)
2831{
2832 g_printf("Color\n");
2833}
2834
2835
2836void
2837on_filter_activate (GtkMenuItem *menuitem,
2838 gpointer user_data)
2839{
2840 g_printf("Filter\n");
2841}
2842
2843
2844void
2845on_save_configuration_activate (GtkMenuItem *menuitem,
2846 gpointer user_data)
2847{
2848 g_printf("Save configuration\n");
2849}
2850
2851
2852void
2853on_content_activate (GtkMenuItem *menuitem,
2854 gpointer user_data)
2855{
2856 g_printf("Content\n");
2857}
2858
2859
51ef553b 2860static void
2861on_about_close_activate (GtkButton *button,
2862 gpointer user_data)
2863{
2864 GtkWidget *about_widget = GTK_WIDGET(user_data);
2865
2866 gtk_widget_destroy(about_widget);
2867}
2868
561eba2a 2869void
2870on_about_activate (GtkMenuItem *menuitem,
2871 gpointer user_data)
2872{
51ef553b 2873 MainWindow *main_window = get_window_data_struct(GTK_WIDGET(menuitem));
2874 GtkWidget *window_widget = main_window->mwindow;
2875 GtkWidget *about_widget = gtk_window_new(GTK_WINDOW_TOPLEVEL);
2876 GtkWindow *about_window = GTK_WINDOW(about_widget);
2877 gint window_width, window_height;
2878
2879 gtk_window_set_title(about_window, "About Linux Trace Toolkit");
2880
2881 gtk_window_set_resizable(about_window, FALSE);
2882 gtk_window_set_transient_for(GTK_WINDOW(window_widget), about_window);
2883 gtk_window_set_destroy_with_parent(about_window, TRUE);
2884 gtk_window_set_modal(about_window, FALSE);
2885
2886 /* Put the about window at the center of the screen */
2887 gtk_window_get_size(about_window, &window_width, &window_height);
2888 gtk_window_move (about_window,
2889 (gdk_screen_width() - window_width)/2,
2890 (gdk_screen_height() - window_height)/2);
2891
2892 GtkWidget *vbox = gtk_vbox_new(FALSE, 1);
2893
2894 gtk_container_add(GTK_CONTAINER(about_widget), vbox);
2895
2896
2897 /* Text to show */
2898 GtkWidget *label1 = gtk_label_new("");
c8bba5fa 2899 gtk_misc_set_padding(GTK_MISC(label1), 10, 20);
51ef553b 2900 gtk_label_set_markup(GTK_LABEL(label1), "\
c8bba5fa 2901<big>Linux Trace Toolkit</big>");
51ef553b 2902 gtk_label_set_justify(GTK_LABEL(label1), GTK_JUSTIFY_CENTER);
2903
2904 GtkWidget *label2 = gtk_label_new("");
c8bba5fa 2905 gtk_misc_set_padding(GTK_MISC(label2), 10, 20);
51ef553b 2906 gtk_label_set_markup(GTK_LABEL(label2), "\
51ef553b 2907Project author: Karim Yaghmour\n\
2908\n\
2909Contributors :\n\
2910\n\
2911Michel Dagenais (New trace format, lttv main)\n\
2912Mathieu Desnoyers (Directory structure, build with automake/conf,\n\
c8bba5fa 2913 lttv gui, control flow view, gui green threads\n\
2914 with interruptible foreground and background computation,\n\
2915 detailed event list)\n\
51ef553b 2916Benoit Des Ligneris (Cluster adaptation)\n\
2917Xang-Xiu Yang (new trace reading library and converter, lttv gui, \n\
2918 detailed event list and statistics view)\n\
2919Tom Zanussi (RelayFS)");
c8bba5fa 2920
2921 GtkWidget *label3 = gtk_label_new("");
2922 gtk_label_set_markup(GTK_LABEL(label3), "\
2923Linux Trace Toolkit, Copyright (C) 2004 Karim Yaghmour\n\
2924Linux Trace Toolkit comes with ABSOLUTELY NO WARRANTY.\n\
2925This is free software, and you are welcome to redistribute it\n\
2926under certain conditions. See COPYING for details.");
2927 gtk_misc_set_padding(GTK_MISC(label3), 10, 20);
2928
51ef553b 2929 gtk_box_pack_start_defaults(GTK_BOX(vbox), label1);
2930 gtk_box_pack_start_defaults(GTK_BOX(vbox), label2);
c8bba5fa 2931 gtk_box_pack_start_defaults(GTK_BOX(vbox), label3);
51ef553b 2932
2933 GtkWidget *hbox = gtk_hbox_new(TRUE, 0);
2934 gtk_box_pack_end(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
2935 GtkWidget *close_button = gtk_button_new_with_mnemonic("_Close");
2936 gtk_box_pack_end(GTK_BOX(hbox), close_button, FALSE, FALSE, 0);
2937 gtk_container_set_border_width(GTK_CONTAINER(close_button), 20);
2938
2939 g_signal_connect(G_OBJECT(close_button), "clicked",
2940 G_CALLBACK(on_about_close_activate),
2941 (gpointer)about_widget);
2942
2943 gtk_widget_show_all(about_widget);
561eba2a 2944}
2945
2946
2947void
2948on_button_new_clicked (GtkButton *button,
2949 gpointer user_data)
2950{
6f7ad7ae 2951 create_new_window((GtkWidget*)button, user_data, TRUE);
561eba2a 2952}
2953
2901f314 2954void
2955on_button_new_tab_clicked (GtkButton *button,
2956 gpointer user_data)
2957{
2958 create_new_tab((GtkWidget*)button, user_data);
2959}
561eba2a 2960
2961void
2962on_button_open_clicked (GtkButton *button,
2963 gpointer user_data)
2964{
2965 open_traceset((GtkWidget*)button, user_data);
2966}
2967
2968
2969void
2970on_button_add_trace_clicked (GtkButton *button,
2971 gpointer user_data)
2972{
2973 add_trace((GtkWidget*)button, user_data);
2974}
2975
2976
2977void
2978on_button_remove_trace_clicked (GtkButton *button,
2979 gpointer user_data)
2980{
2981 remove_trace((GtkWidget*)button, user_data);
2982}
2983
9878c8a4 2984void
2985on_button_redraw_clicked (GtkButton *button,
2986 gpointer user_data)
2987{
2988 redraw((GtkWidget*)button, user_data);
2989}
2990
2991void
2992on_button_continue_processing_clicked (GtkButton *button,
2993 gpointer user_data)
2994{
2995 continue_processing((GtkWidget*)button, user_data);
2996}
2997
2998void
2999on_button_stop_processing_clicked (GtkButton *button,
3000 gpointer user_data)
3001{
3002 stop_processing((GtkWidget*)button, user_data);
3003}
3004
3005
561eba2a 3006
3007void
3008on_button_save_clicked (GtkButton *button,
3009 gpointer user_data)
3010{
3011 save((GtkWidget*)button, user_data);
3012}
3013
3014
3015void
3016on_button_save_as_clicked (GtkButton *button,
3017 gpointer user_data)
3018{
3019 save_as((GtkWidget*)button, user_data);
3020}
3021
3022
3023void
3024on_button_zoom_in_clicked (GtkButton *button,
3025 gpointer user_data)
3026{
3027 zoom_in((GtkWidget*)button, user_data);
3028}
3029
3030
3031void
3032on_button_zoom_out_clicked (GtkButton *button,
3033 gpointer user_data)
3034{
3035 zoom_out((GtkWidget*)button, user_data);
3036}
3037
3038
3039void
3040on_button_zoom_extended_clicked (GtkButton *button,
3041 gpointer user_data)
3042{
3043 zoom_extended((GtkWidget*)button, user_data);
3044}
3045
3046
3047void
3048on_button_go_to_time_clicked (GtkButton *button,
3049 gpointer user_data)
3050{
3051 go_to_time((GtkWidget*)button, user_data);
3052}
3053
3054
3055void
3056on_button_show_time_frame_clicked (GtkButton *button,
3057 gpointer user_data)
3058{
3059 show_time_frame((GtkWidget*)button, user_data);
3060}
3061
3062
3063void
3064on_button_move_up_clicked (GtkButton *button,
3065 gpointer user_data)
3066{
3067 move_up_viewer((GtkWidget*)button, user_data);
3068}
3069
3070
3071void
3072on_button_move_down_clicked (GtkButton *button,
3073 gpointer user_data)
3074{
3075 move_down_viewer((GtkWidget*)button, user_data);
3076}
3077
3078
3079void
3080on_button_delete_viewer_clicked (GtkButton *button,
3081 gpointer user_data)
3082{
3083 delete_viewer((GtkWidget*)button, user_data);
3084}
3085
3086void
2d262115 3087on_MWindow_destroy (GtkWidget *widget,
561eba2a 3088 gpointer user_data)
3089{
2d262115 3090 MainWindow *main_window = get_window_data_struct(widget);
ef68c3ac 3091 LttvIAttribute *attributes = main_window->attributes;
3092 LttvAttributeValue value;
e4d09234 3093
ef68c3ac 3094 //This is unnecessary, since widgets will be destroyed
3095 //by the main window widget anyway.
3096 //remove_all_menu_toolbar_constructors(main_window, NULL);
3097
3098 g_assert(lttv_iattribute_find_by_path(attributes,
3099 "viewers/menu", LTTV_POINTER, &value));
3100 lttv_menus_destroy((LttvMenus*)*(value.v_pointer));
3101
501e4e70 3102 g_assert(lttv_iattribute_find_by_path(attributes,
ef68c3ac 3103 "viewers/toolbar", LTTV_POINTER, &value));
3104 lttv_toolbars_destroy((LttvToolbars*)*(value.v_pointer));
2d262115 3105
ef68c3ac 3106 g_object_unref(main_window->attributes);
3107 g_main_window_list = g_slist_remove(g_main_window_list, main_window);
561eba2a 3108
ef68c3ac 3109 g_printf("There are now : %d windows\n",g_slist_length(g_main_window_list));
2d262115 3110 if(g_slist_length(g_main_window_list) == 0)
7a859036 3111 gtk_main_quit ();
561eba2a 3112}
3113
58eecf4a 3114gboolean
3115on_MWindow_configure (GtkWidget *widget,
3116 GdkEventConfigure *event,
3117 gpointer user_data)
3118{
3119 MainWindow * mw_data = get_window_data_struct((GtkWidget*)widget);
3120 float width = event->width;
58eecf4a 3121 TimeWindow time_win;
3122 double ratio;
3123 TimeInterval *time_span;
3124 LttTime time;
bd24a9af 3125
3126 // MD : removed time width modification upon resizing of the main window.
3127 // The viewers will redraw themselves completely, without time interval
3128 // modification.
3129/* while(tab){
58eecf4a 3130 if(mw_data->window_width){
3131 time_span = LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context)->Time_Span ;
3132 time_win = tab->time_window;
3133 ratio = width / mw_data->window_width;
3134 tab->time_window.time_width = ltt_time_mul(time_win.time_width,ratio);
3135 time = ltt_time_sub(time_span->endTime, time_win.start_time);
3136 if(ltt_time_compare(time, tab->time_window.time_width) < 0){
3137 tab->time_window.time_width = time;
3138 }
3139 }
3140 tab = tab->next;
3141 }
3142
3143 mw_data->window_width = (int)width;
bd24a9af 3144 */
58eecf4a 3145 return FALSE;
3146}
561eba2a 3147
abe346a3 3148/* Set current tab
3149 */
3150
561eba2a 3151void
3152on_MNotebook_switch_page (GtkNotebook *notebook,
3153 GtkNotebookPage *page,
3154 guint page_num,
3155 gpointer user_data)
3156{
47cd8a09 3157
561eba2a 3158}
3159
abe346a3 3160
b052368a 3161void scroll_value_changed_cb(GtkWidget *scrollbar,
3162 gpointer user_data)
3163{
3164 Tab *tab = (Tab *)user_data;
3165 TimeWindow time_window;
b052368a 3166 LttTime time;
3167 GtkAdjustment *adjust = gtk_range_get_adjustment(GTK_RANGE(scrollbar));
3168 gdouble value = gtk_adjustment_get_value(adjust);
3169 gdouble upper, lower, ratio, page_size;
3170 LttvTracesetContext * tsc =
3171 LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context);
b9a010a2 3172 TimeInterval time_span = tsc->time_span;
b052368a 3173
3174 //time_window = tab->time_window;
3175
b052368a 3176 lower = adjust->lower;
3177 upper = adjust->upper;
3178 ratio = (value - lower) / (upper - lower);
2b5cc5a5 3179 g_info("lower %lu, upper %lu, value %lu, ratio %lu", lower, upper, value, ratio);
b052368a 3180
3181 //time = ltt_time_sub(time_span->end_time, time_span->start_time);
3182 //time = ltt_time_mul(time, (float)ratio);
3183 //time = ltt_time_add(time_span->start_time, time);
b9a010a2 3184 time = ltt_time_add(ltt_time_from_double(value/NANOSECONDS_PER_SECOND),
3185 time_span.start_time);
b052368a 3186
3187 time_window.start_time = time;
3188
3189 page_size = adjust->page_size;
3190
3191 time_window.time_width =
3192 ltt_time_from_double(page_size/NANOSECONDS_PER_SECOND);
b9a010a2 3193 //time = ltt_time_sub(time_span.end_time, time);
b052368a 3194 //if(ltt_time_compare(time,time_window.time_width) < 0){
3195 // time_window.time_width = time;
3196 //}
3197
3198 /* call viewer hooks for new time window */
3199 set_time_window(tab, &time_window);
3200
3201}
3202
3203
abe346a3 3204/* callback function to check or uncheck the check box (filter)
3205 */
3206
49bf71b5 3207void checkbox_changed(GtkTreeView *treeview,
3208 GtkTreePath *arg1,
3209 GtkTreeViewColumn *arg2,
3210 gpointer user_data)
3211{
3212 GtkTreeStore * store = (GtkTreeStore *)gtk_tree_view_get_model (treeview);
3213 GtkTreeIter iter;
3214 gboolean value;
3215
3216 if (gtk_tree_model_get_iter ((GtkTreeModel *)store, &iter, arg1)){
3217 gtk_tree_model_get ((GtkTreeModel *)store, &iter, CHECKBOX_COLUMN, &value, -1);
3218 value = value? FALSE : TRUE;
3219 gtk_tree_store_set (GTK_TREE_STORE (store), &iter, CHECKBOX_COLUMN, value, -1);
3220 }
3221
3222}
3223
abe346a3 3224
3225/* According to user's selection, update selector(filter)
3226 */
3227
49bf71b5 3228void update_filter(LttvTracesetSelector *s, GtkTreeStore *store )
3229{
ed3b99b6 3230 GtkTreeIter iter, child_iter, child_iter1, child_iter2;
3231 int i, j, k, nb_eventtype;
49bf71b5 3232 LttvTraceSelector * trace;
3233 LttvTracefileSelector * tracefile;
ed3b99b6 3234 LttvEventtypeSelector * eventtype;
3235 gboolean value, value1, value2;
49bf71b5 3236
3237 if(gtk_tree_model_get_iter_first((GtkTreeModel*)store, &iter)){
3238 i = 0;
3239 do{
ed3b99b6 3240 trace = lttv_traceset_selector_trace_get(s, i);
3241 nb_eventtype = lttv_trace_selector_eventtype_number(trace);
49bf71b5 3242 gtk_tree_model_get ((GtkTreeModel*)store, &iter, CHECKBOX_COLUMN, &value,-1);
3243 if(value){
3244 j = 0;
3245 if(gtk_tree_model_iter_children ((GtkTreeModel*)store, &child_iter, &iter)){
3246 do{
ed3b99b6 3247 if(j<1){//eventtype selector for trace
3248 gtk_tree_model_get ((GtkTreeModel*)store, &child_iter, CHECKBOX_COLUMN, &value2,-1);
3249 if(value2){
3250 k=0;
3251 if(gtk_tree_model_iter_children ((GtkTreeModel*)store, &child_iter1, &child_iter)){
3252 do{
3253 eventtype = lttv_trace_selector_eventtype_get(trace,k);
3254 gtk_tree_model_get ((GtkTreeModel*)store, &child_iter1, CHECKBOX_COLUMN, &value2,-1);
3255 lttv_eventtype_selector_set_selected(eventtype,value2);
3256 k++;
3257 }while(gtk_tree_model_iter_next((GtkTreeModel*)store, &child_iter1));
3258 }
3259 }
3260 }else{ //tracefile selector
3261 tracefile = lttv_trace_selector_tracefile_get(trace, j - 1);
3262 gtk_tree_model_get ((GtkTreeModel*)store, &child_iter, CHECKBOX_COLUMN, &value1,-1);
3263 lttv_tracefile_selector_set_selected(tracefile,value1);
3264 if(value1){
3265 gtk_tree_model_iter_children((GtkTreeModel*)store, &child_iter1, &child_iter); //eventtype selector
3266 gtk_tree_model_get ((GtkTreeModel*)store, &child_iter1, CHECKBOX_COLUMN, &value2,-1);
3267 if(value2){
3268 k = 0;
3269 if(gtk_tree_model_iter_children ((GtkTreeModel*)store, &child_iter2, &child_iter1)){
3270 do{//eventtype selector for tracefile
3271 eventtype = lttv_tracefile_selector_eventtype_get(tracefile,k);
3272 gtk_tree_model_get ((GtkTreeModel*)store, &child_iter2, CHECKBOX_COLUMN, &value2,-1);
3273 lttv_eventtype_selector_set_selected(eventtype,value2);
3274 k++;
3275 }while(gtk_tree_model_iter_next((GtkTreeModel*)store, &child_iter2));
3276 }
3277 }
3278 }
3279 }
49bf71b5 3280 j++;
3281 }while(gtk_tree_model_iter_next((GtkTreeModel*)store, &child_iter));
3282 }
3283 }
3284 lttv_trace_selector_set_selected(trace,value);
3285 i++;
3286 }while(gtk_tree_model_iter_next((GtkTreeModel*)store, &iter));
3287 }
3288}
3289
abe346a3 3290
3291/* Display a dialogue showing all eventtypes and traces, let user to select the interested
3292 * eventtypes, tracefiles and traces (filter)
3293 */
3294
a8c0f09d 3295gboolean get_filter_selection(LttvTracesetSelector *s,char *title, char * column_title)
49bf71b5 3296{
3297 GtkWidget * dialogue;
3298 GtkTreeStore * store;
3299 GtkWidget * tree;
3300 GtkWidget * scroll_win;
3301 GtkCellRenderer * renderer;
3302 GtkTreeViewColumn * column;
ed3b99b6 3303 GtkTreeIter iter, child_iter, child_iter1, child_iter2;
3304 int i, j, k, id, nb_trace, nb_tracefile, nb_eventtype;
49bf71b5 3305 LttvTraceSelector * trace;
3306 LttvTracefileSelector * tracefile;
ed3b99b6 3307 LttvEventtypeSelector * eventtype;
49bf71b5 3308 char * name;
3309 gboolean checked;
3310
3311 dialogue = gtk_dialog_new_with_buttons(title,
3312 NULL,
3313 GTK_DIALOG_MODAL,
3314 GTK_STOCK_OK,GTK_RESPONSE_ACCEPT,
3315 GTK_STOCK_CANCEL,GTK_RESPONSE_REJECT,
3316 NULL);
ed3b99b6 3317 gtk_window_set_default_size((GtkWindow*)dialogue, 300, 500);
49bf71b5 3318
3319 store = gtk_tree_store_new (TOTAL_COLUMNS, G_TYPE_BOOLEAN, G_TYPE_STRING);
3320 tree = gtk_tree_view_new_with_model (GTK_TREE_MODEL (store));
3321 g_object_unref (G_OBJECT (store));
3322 g_signal_connect (G_OBJECT (tree), "row-activated",
3323 G_CALLBACK (checkbox_changed),
3324 NULL);
3325
3326
3327 renderer = gtk_cell_renderer_toggle_new ();
3328 gtk_cell_renderer_toggle_set_radio((GtkCellRendererToggle *)renderer, FALSE);
3329
3330 g_object_set (G_OBJECT (renderer),"activatable", TRUE, NULL);
3331
3332 column = gtk_tree_view_column_new_with_attributes ("Checkbox",
3333 renderer,
3334 "active", CHECKBOX_COLUMN,
3335 NULL);
3336 gtk_tree_view_column_set_alignment (column, 0.5);
3337 gtk_tree_view_column_set_fixed_width (column, 20);
3338 gtk_tree_view_append_column (GTK_TREE_VIEW (tree), column);
3339
3340 renderer = gtk_cell_renderer_text_new ();
3341 column = gtk_tree_view_column_new_with_attributes (column_title,
3342 renderer,
3343 "text", NAME_COLUMN,
3344 NULL);
3345 gtk_tree_view_column_set_alignment (column, 0.0);
3346 gtk_tree_view_append_column (GTK_TREE_VIEW (tree), column);
3347 gtk_tree_view_set_headers_visible(GTK_TREE_VIEW (tree), FALSE);
3348
3349 scroll_win = gtk_scrolled_window_new (NULL, NULL);
3350 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll_win),
3351 GTK_POLICY_AUTOMATIC,GTK_POLICY_AUTOMATIC);
3352 gtk_container_add (GTK_CONTAINER (scroll_win), tree);
3353
3354 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialogue)->vbox), scroll_win,TRUE, TRUE,0);
3355
3356 gtk_widget_show(scroll_win);
3357 gtk_widget_show(tree);
3358
ed3b99b6 3359 nb_trace = lttv_traceset_selector_trace_number(s);
49bf71b5 3360 for(i=0;i<nb_trace;i++){
ed3b99b6 3361 trace = lttv_traceset_selector_trace_get(s, i);
49bf71b5 3362 name = lttv_trace_selector_get_name(trace);
3363 gtk_tree_store_append (store, &iter, NULL);
3364 checked = lttv_trace_selector_get_selected(trace);
3365 gtk_tree_store_set (store, &iter,
3366 CHECKBOX_COLUMN,checked,
3367 NAME_COLUMN,name,
3368 -1);
ed3b99b6 3369
3370 gtk_tree_store_append (store, &child_iter, &iter);
3371 gtk_tree_store_set (store, &child_iter,
3372 CHECKBOX_COLUMN, checked,
3373 NAME_COLUMN,"eventtype",
3374 -1);
3375
3376 nb_eventtype = lttv_trace_selector_eventtype_number(trace);
3377 for(j=0;j<nb_eventtype;j++){
3378 eventtype = lttv_trace_selector_eventtype_get(trace,j);
3379 name = lttv_eventtype_selector_get_name(eventtype);
3380 checked = lttv_eventtype_selector_get_selected(eventtype);
3381 gtk_tree_store_append (store, &child_iter1, &child_iter);
3382 gtk_tree_store_set (store, &child_iter1,
3383 CHECKBOX_COLUMN, checked,
3384 NAME_COLUMN,name,
3385 -1);
3386 }
3387
3388 nb_tracefile = lttv_trace_selector_tracefile_number(trace);
49bf71b5 3389 for(j=0;j<nb_tracefile;j++){
ed3b99b6 3390 tracefile = lttv_trace_selector_tracefile_get(trace, j);
49bf71b5 3391 name = lttv_tracefile_selector_get_name(tracefile);
3392 gtk_tree_store_append (store, &child_iter, &iter);
3393 checked = lttv_tracefile_selector_get_selected(tracefile);
3394 gtk_tree_store_set (store, &child_iter,
3395 CHECKBOX_COLUMN, checked,
3396 NAME_COLUMN,name,
3397 -1);
ed3b99b6 3398
3399 gtk_tree_store_append (store, &child_iter1, &child_iter);
3400 gtk_tree_store_set (store, &child_iter1,
3401 CHECKBOX_COLUMN, checked,
3402 NAME_COLUMN,"eventtype",
3403 -1);
3404
3405 for(k=0;k<nb_eventtype;k++){
3406 eventtype = lttv_tracefile_selector_eventtype_get(tracefile,k);
3407 name = lttv_eventtype_selector_get_name(eventtype);
3408 checked = lttv_eventtype_selector_get_selected(eventtype);
3409 gtk_tree_store_append (store, &child_iter2, &child_iter1);
3410 gtk_tree_store_set (store, &child_iter2,
3411 CHECKBOX_COLUMN, checked,
3412 NAME_COLUMN,name,
3413 -1);
3414 }
49bf71b5 3415 }
3416 }
3417
3418 id = gtk_dialog_run(GTK_DIALOG(dialogue));
3419 switch(id){
3420 case GTK_RESPONSE_ACCEPT:
3421 case GTK_RESPONSE_OK:
3422 update_filter(s, store);
a8c0f09d 3423 gtk_widget_destroy(dialogue);
3424 return TRUE;
49bf71b5 3425 case GTK_RESPONSE_REJECT:
3426 case GTK_RESPONSE_CANCEL:
3427 default:
3428 gtk_widget_destroy(dialogue);
3429 break;
3430 }
a8c0f09d 3431 return FALSE;
49bf71b5 3432}
3433
abe346a3 3434
3435/* Select a trace which will be removed from traceset
3436 */
3437
2176f952 3438char * get_remove_trace(char ** all_trace_name, int nb_trace)
3439{
3440 return get_selection(all_trace_name, nb_trace,
3441 "Select a trace", "Trace pathname");
3442}
abe346a3 3443
3444
b052368a 3445/* Select a module which will be loaded
3446 */
3447
3448char * get_load_module(char ** load_module_name, int nb_module)
3449{
3450 return get_selection(load_module_name, nb_module,
3451 "Select a module to load", "Module name");
3452}
3453
3454
3455
3456
abe346a3 3457/* Select a module which will be unloaded
3458 */
3459
36b3c068 3460char * get_unload_module(char ** loaded_module_name, int nb_module)
2176f952 3461{
3462 return get_selection(loaded_module_name, nb_module,
b052368a 3463 "Select a module to unload", "Module name");
2176f952 3464}
3465
abe346a3 3466
3467/* Display a dialogue which shows all selectable items, let user to
3468 * select one of them
3469 */
3470
2176f952 3471char * get_selection(char ** loaded_module_name, int nb_module,
3472 char *title, char * column_title)
36b3c068 3473{
3474 GtkWidget * dialogue;
3475 GtkWidget * scroll_win;
3476 GtkWidget * tree;
3477 GtkListStore * store;
3478 GtkTreeViewColumn * column;
3479 GtkCellRenderer * renderer;
3480 GtkTreeSelection * select;
3481 GtkTreeIter iter;
3482 gint id, i;
3483 char * unload_module_name = NULL;
3484
2176f952 3485 dialogue = gtk_dialog_new_with_buttons(title,
36b3c068 3486 NULL,
3487 GTK_DIALOG_MODAL,
3488 GTK_STOCK_OK,GTK_RESPONSE_ACCEPT,
3489 GTK_STOCK_CANCEL,GTK_RESPONSE_REJECT,
3490 NULL);
3491 gtk_window_set_default_size((GtkWindow*)dialogue, 500, 200);
3492
3493 scroll_win = gtk_scrolled_window_new (NULL, NULL);
3494 gtk_widget_show ( scroll_win);
3495 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll_win),
3496 GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
3497
3498 store = gtk_list_store_new (N_COLUMNS,G_TYPE_STRING);
3499 tree = gtk_tree_view_new_with_model(GTK_TREE_MODEL (store));
3500 gtk_widget_show ( tree);
3501 g_object_unref (G_OBJECT (store));
3502
3503 renderer = gtk_cell_renderer_text_new ();
2176f952 3504 column = gtk_tree_view_column_new_with_attributes (column_title,
36b3c068 3505 renderer,
3506 "text", MODULE_COLUMN,
3507 NULL);
3508 gtk_tree_view_column_set_alignment (column, 0.5);
3509 gtk_tree_view_column_set_fixed_width (column, 150);
3510 gtk_tree_view_append_column (GTK_TREE_VIEW (tree), column);
3511
3512 select = gtk_tree_view_get_selection (GTK_TREE_VIEW (tree));
3513 gtk_tree_selection_set_mode (select, GTK_SELECTION_SINGLE);
3514
3515 gtk_container_add (GTK_CONTAINER (scroll_win), tree);
3516
3517 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialogue)->vbox), scroll_win,TRUE, TRUE,0);
3518
3519 for(i=0;i<nb_module;i++){
3520 gtk_list_store_append (store, &iter);
3521 gtk_list_store_set (store, &iter, MODULE_COLUMN,loaded_module_name[i],-1);
3522 }
3523
3524 id = gtk_dialog_run(GTK_DIALOG(dialogue));
3525 switch(id){
3526 case GTK_RESPONSE_ACCEPT:
3527 case GTK_RESPONSE_OK:
3528 if (gtk_tree_selection_get_selected (select, (GtkTreeModel**)&store, &iter)){
3529 gtk_tree_model_get ((GtkTreeModel*)store, &iter, MODULE_COLUMN, &unload_module_name, -1);
3530 }
3531 case GTK_RESPONSE_REJECT:
3532 case GTK_RESPONSE_CANCEL:
3533 default:
3534 gtk_widget_destroy(dialogue);
3535 break;
3536 }
3537
3538 return unload_module_name;
3539}
5723fa24 3540
abe346a3 3541
ef68c3ac 3542/* Insert all menu entry and tool buttons into this main window
001d8606 3543 * for modules.
3544 *
abe346a3 3545 */
3546
6c9d86dd 3547void add_all_menu_toolbar_constructors(MainWindow * mw, gpointer user_data)
5723fa24 3548{
3549 int i;
3550 GdkPixbuf *pixbuf;
42fcbb71 3551 lttvwindow_viewer_constructor constructor;
001d8606 3552 LttvMenus * global_menu, * instance_menu;
3553 LttvToolbars * global_toolbar, * instance_toolbar;
6c9d86dd 3554 LttvMenuClosure *menu_item;
3555 LttvToolbarClosure *toolbar_item;
5723fa24 3556 LttvAttributeValue value;
001d8606 3557 LttvIAttribute *global_attributes = LTTV_IATTRIBUTE(lttv_global_attributes());
501e4e70 3558 LttvIAttribute *attributes = mw->attributes;
001d8606 3559 GtkWidget * tool_menu_title_menu, *new_widget, *pixmap;
3560
3561 g_assert(lttv_iattribute_find_by_path(global_attributes,
3562 "viewers/menu", LTTV_POINTER, &value));
3563 if(*(value.v_pointer) == NULL)
501e4e70 3564 *(value.v_pointer) = lttv_menus_new();
001d8606 3565 global_menu = (LttvMenus*)*(value.v_pointer);
5723fa24 3566
3567 g_assert(lttv_iattribute_find_by_path(attributes,
3568 "viewers/menu", LTTV_POINTER, &value));
001d8606 3569 if(*(value.v_pointer) == NULL)
501e4e70 3570 *(value.v_pointer) = lttv_menus_new();
001d8606 3571 instance_menu = (LttvMenus*)*(value.v_pointer);
5723fa24 3572
001d8606 3573
3574
3575 g_assert(lttv_iattribute_find_by_path(global_attributes,
3576 "viewers/toolbar", LTTV_POINTER, &value));
3577 if(*(value.v_pointer) == NULL)
501e4e70 3578 *(value.v_pointer) = lttv_toolbars_new();
001d8606 3579 global_toolbar = (LttvToolbars*)*(value.v_pointer);
3580
3581 g_assert(lttv_iattribute_find_by_path(attributes,
3582 "viewers/toolbar", LTTV_POINTER, &value));
3583 if(*(value.v_pointer) == NULL)
501e4e70 3584 *(value.v_pointer) = lttv_toolbars_new();
001d8606 3585 instance_toolbar = (LttvToolbars*)*(value.v_pointer);
3586
3587 /* Add missing menu entries to window instance */
3588 for(i=0;i<global_menu->len;i++) {
6c9d86dd 3589 menu_item = &g_array_index(global_menu, LttvMenuClosure, i);
3590
3591 //add menu_item to window instance;
3592 constructor = menu_item->con;
3593 tool_menu_title_menu = lookup_widget(mw->mwindow,"ToolMenuTitle_menu");
3594 new_widget =
501e4e70 3595 gtk_menu_item_new_with_mnemonic (menu_item->menu_text);
6c9d86dd 3596 gtk_container_add (GTK_CONTAINER (tool_menu_title_menu),
3597 new_widget);
3598 g_signal_connect ((gpointer) new_widget, "activate",
3599 G_CALLBACK (insert_viewer_wrap),
3600 constructor);
3601 gtk_widget_show (new_widget);
3602 lttv_menus_add(instance_menu, menu_item->con,
3603 menu_item->menu_path,
3604 menu_item->menu_text,
3605 new_widget);
001d8606 3606
001d8606 3607 }
3608
3609 /* Add missing toolbar entries to window instance */
3610 for(i=0;i<global_toolbar->len;i++) {
6c9d86dd 3611 toolbar_item = &g_array_index(global_toolbar, LttvToolbarClosure, i);
3612
3613 //add toolbar_item to window instance;
3614 constructor = toolbar_item->con;
3615 tool_menu_title_menu = lookup_widget(mw->mwindow,"MToolbar1");
3616 pixbuf = gdk_pixbuf_new_from_xpm_data((const char**)toolbar_item->pixmap);
3617 pixmap = gtk_image_new_from_pixbuf(pixbuf);
3618 new_widget =
3619 gtk_toolbar_append_element (GTK_TOOLBAR (tool_menu_title_menu),
3620 GTK_TOOLBAR_CHILD_BUTTON,
3621 NULL,
3622 "",
3623 toolbar_item->tooltip, NULL,
3624 pixmap, NULL, NULL);
3625 gtk_label_set_use_underline(
3626 GTK_LABEL (((GtkToolbarChild*) (
3627 g_list_last (GTK_TOOLBAR
3628 (tool_menu_title_menu)->children)->data))->label),
3629 TRUE);
3630 gtk_container_set_border_width (GTK_CONTAINER (new_widget), 1);
3631 g_signal_connect ((gpointer) new_widget,
3632 "clicked",
3633 G_CALLBACK (insert_viewer_wrap),
3634 constructor);
3635 gtk_widget_show (new_widget);
001d8606 3636
6c9d86dd 3637 lttv_toolbars_add(instance_toolbar, toolbar_item->con,
3638 toolbar_item->tooltip,
3639 toolbar_item->pixmap,
3640 new_widget);
001d8606 3641
5723fa24 3642 }
6c9d86dd 3643
5723fa24 3644}
3645
abe346a3 3646
3647/* Create a main window
3648 */
3649
08b1c66e 3650void construct_main_window(MainWindow * parent)
5723fa24 3651{
2a2fa4f0 3652 g_debug("construct_main_window()");
68b48a45 3653 GtkWidget * new_window; /* New generated main window */
bca3b81f 3654 MainWindow * new_m_window;/* New main window structure */
5723fa24 3655 GtkNotebook * notebook;
f7afe191 3656 LttvIAttribute *attributes =
3657 LTTV_IATTRIBUTE(g_object_new(LTTV_ATTRIBUTE_TYPE, NULL));
3658 LttvAttributeValue value;
6ced96ef 3659 Tab *new_tab;
2061e03d 3660
bca3b81f 3661 new_m_window = g_new(MainWindow, 1);
5723fa24 3662
3663 // Add the object's information to the module's array
68b48a45 3664 g_main_window_list = g_slist_append(g_main_window_list, new_m_window);
5723fa24 3665
f7afe191 3666
68b48a45 3667 new_window = create_MWindow();
3668 gtk_widget_show (new_window);
5723fa24 3669
bca3b81f 3670 new_m_window->mwindow = new_window;
a43d67ba 3671 new_m_window->attributes = attributes;
5723fa24 3672
001d8606 3673 g_assert(lttv_iattribute_find_by_path(attributes,
3674 "viewers/menu", LTTV_POINTER, &value));
501e4e70 3675 *(value.v_pointer) = lttv_menus_new();
001d8606 3676
501e4e70 3677 g_assert(lttv_iattribute_find_by_path(attributes,
001d8606 3678 "viewers/toolbar", LTTV_POINTER, &value));
501e4e70 3679 *(value.v_pointer) = lttv_toolbars_new();
2061e03d 3680
6c9d86dd 3681 add_all_menu_toolbar_constructors(new_m_window, NULL);
5723fa24 3682
2d262115 3683 g_object_set_data_full(G_OBJECT(new_window),
3684 "main_window_data",
3685 (gpointer)new_m_window,
3686 (GDestroyNotify)g_free);
5723fa24 3687 //create a default tab
bca3b81f 3688 notebook = (GtkNotebook *)lookup_widget(new_m_window->mwindow, "MNotebook");
5723fa24 3689 if(notebook == NULL){
3690 g_printf("Notebook does not exist\n");
3691 return;
3692 }
27a559b9 3693 gtk_notebook_popup_enable (GTK_NOTEBOOK(notebook));
5723fa24 3694 //for now there is no name field in LttvTraceset structure
3695 //Use "Traceset" as the label for the default tab
6ced96ef 3696 if(parent) {
3697 GtkWidget * parent_notebook = lookup_widget(parent->mwindow, "MNotebook");
3698 GtkWidget *page = gtk_notebook_get_nth_page(GTK_NOTEBOOK(parent_notebook),
3699 gtk_notebook_get_current_page(GTK_NOTEBOOK(parent_notebook)));
3700 Tab *parent_tab;
3701
3702 if(!page) {
3703 parent_tab = NULL;
3704 } else {
3705 parent_tab = (Tab *)g_object_get_data(G_OBJECT(page), "Tab_Info");
3706 }
3707 new_tab = create_tab(new_m_window, parent_tab, notebook, "Traceset");
3708 } else {
3709 new_tab = create_tab(new_m_window, NULL, notebook, "Traceset");
91fd6881 3710 /* First window, use command line trace */
4266dc7f 3711 if(g_init_trace != NULL){
6ced96ef 3712 lttvwindow_add_trace(new_tab,
4266dc7f 3713 g_init_trace);
91fd6881 3714
3715 LttvTraceset *traceset = new_tab->traceset_info->traceset;
3716 SetTraceset(new_tab, traceset);
4266dc7f 3717 }
3718 }
5723fa24 3719
ef68c3ac 3720 g_printf("There are now : %d windows\n",g_slist_length(g_main_window_list));
5723fa24 3721}
3722
abe346a3 3723
3724/* Free the memory occupied by a tab structure
3725 * destroy the tab
3726 */
3727
bca3b81f 3728void tab_destructor(Tab * tab_instance)
f7afe191 3729{
716e4367 3730 int i, nb, ref_count;
3731 LttvTrace * trace;
3732
bca3b81f 3733 if(tab_instance->attributes)
501e4e70 3734 g_object_unref(tab_instance->attributes);
3735
3736 if(tab_instance->interrupted_state)
3737 g_object_unref(tab_instance->interrupted_state);
3738
2061e03d 3739
716e4367 3740 if(tab_instance->traceset_info->traceset_context != NULL){
784705cc 3741 //remove state update hooks
3742 lttv_state_remove_event_hooks(
3743 (LttvTracesetState*)tab_instance->traceset_info->
3744 traceset_context);
716e4367 3745 lttv_context_fini(LTTV_TRACESET_CONTEXT(tab_instance->traceset_info->
3746 traceset_context));
3747 g_object_unref(tab_instance->traceset_info->traceset_context);
3748 }
3749 if(tab_instance->traceset_info->traceset != NULL) {
3750 nb = lttv_traceset_number(tab_instance->traceset_info->traceset);
3751 for(i = 0 ; i < nb ; i++) {
3752 trace = lttv_traceset_get(tab_instance->traceset_info->traceset, i);
3753 ref_count = lttv_trace_get_ref_number(trace);
49bf71b5 3754 if(ref_count <= 1){
a1a2b649 3755 ltt_trace_close(lttv_trace(trace));
49bf71b5 3756 }
716e4367 3757 }
3758 }
a43d67ba 3759 lttv_traceset_destroy(tab_instance->traceset_info->traceset);
501e4e70 3760 /* Remove the idle events requests processing function of the tab */
3761 g_idle_remove_by_data(tab_instance);
3762
3763 g_slist_free(tab_instance->events_requests);
716e4367 3764 g_free(tab_instance->traceset_info);
68b48a45 3765 g_free(tab_instance);
f7afe191 3766}
3767
abe346a3 3768
3769/* Create a tab and insert it into the current main window
3770 */
3771
6ced96ef 3772Tab* create_tab(MainWindow * mw, Tab *copy_tab,
716e4367 3773 GtkNotebook * notebook, char * label)
5723fa24 3774{
3775 GList * list;
6ced96ef 3776 Tab * tab;
68b48a45 3777 LttTime tmp_time;
a43d67ba 3778
abe346a3 3779 //create a new tab data structure
6ced96ef 3780 tab = g_new(Tab,1);
716e4367 3781
abe346a3 3782 //construct and initialize the traceset_info
6ced96ef 3783 tab->traceset_info = g_new(TracesetInfo,1);
a43d67ba 3784
4266dc7f 3785 if(copy_tab) {
6ced96ef 3786 tab->traceset_info->traceset =
4266dc7f 3787 lttv_traceset_copy(copy_tab->traceset_info->traceset);
3788 } else {
6ced96ef 3789 tab->traceset_info->traceset = lttv_traceset_new();
716e4367 3790 }
20fde85f 3791
84ddf5c9 3792#ifdef DEBUG
20fde85f 3793 lttv_attribute_write_xml(
6ced96ef 3794 lttv_traceset_attribute(tab->traceset_info->traceset),
20fde85f 3795 stdout,
3796 0, 4);
3797 fflush(stdout);
84ddf5c9 3798#endif //DEBUG
20fde85f 3799
3800
716e4367 3801 //FIXME copy not implemented in lower level
6ced96ef 3802 tab->traceset_info->traceset_context =
716e4367 3803 g_object_new(LTTV_TRACESET_STATS_TYPE, NULL);
6ced96ef 3804 g_assert(tab->traceset_info->traceset_context != NULL);
716e4367 3805 lttv_context_init(
6ced96ef 3806 LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context),
3807 tab->traceset_info->traceset);
784705cc 3808 //add state update hooks
3809 lttv_state_add_event_hooks(
6ced96ef 3810 (LttvTracesetState*)tab->traceset_info->traceset_context);
784705cc 3811
abe346a3 3812 //determine the current_time and time_window of the tab
6ced96ef 3813 if(copy_tab != NULL){
3814 tab->time_window = copy_tab->time_window;
3815 tab->current_time = copy_tab->current_time;
5723fa24 3816 }else{
6ced96ef 3817 tab->time_window.start_time =
3818 LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context)->
3819 time_span.start_time;
f7afe191 3820 if(DEFAULT_TIME_WIDTH_S <
6ced96ef 3821 LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context)->
3822 time_span.end_time.tv_sec)
68b48a45 3823 tmp_time.tv_sec = DEFAULT_TIME_WIDTH_S;
f7afe191 3824 else
68b48a45 3825 tmp_time.tv_sec =
6ced96ef 3826 LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context)->
3827 time_span.end_time.tv_sec;
68b48a45 3828 tmp_time.tv_nsec = 0;
6ced96ef 3829 tab->time_window.time_width = tmp_time ;
3830 tab->current_time.tv_sec =
3831 LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context)->
3832 time_span.start_time.tv_sec;
3833 tab->current_time.tv_nsec =
3834 LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context)->
3835 time_span.start_time.tv_nsec;
5723fa24 3836 }
6ced96ef 3837 tab->attributes = LTTV_IATTRIBUTE(g_object_new(LTTV_ATTRIBUTE_TYPE, NULL));
3838 tab->interrupted_state = g_object_new(LTTV_ATTRIBUTE_TYPE, NULL);
b052368a 3839
58f6c2a4 3840 tab->vbox = gtk_vbox_new(FALSE, 2);
3841 tab->viewer_container = gtk_vbox_new(TRUE, 2);
b052368a 3842 tab->scrollbar = gtk_hscrollbar_new(NULL);
3843 //tab->multivpaned = gtk_multi_vpaned_new();
3844
3845 gtk_box_pack_start(GTK_BOX(tab->vbox),
3846 tab->viewer_container,
3847 TRUE, /* expand */
3848 TRUE, /* Give the extra space to the child */
3849 0); /* No padding */
3850
3851 gtk_box_pack_end(GTK_BOX(tab->vbox),
3852 tab->scrollbar,
3853 FALSE, /* Do not expand */
3854 FALSE, /* Fill has no effect here (expand false) */
3855 0); /* No padding */
3856
3857 g_object_set_data(G_OBJECT(tab->viewer_container), "focused_viewer", NULL);
3858
3859
6ced96ef 3860 tab->mw = mw;
27a559b9 3861
3c031040 3862 /*{
3863 // Display a label with a X
27a559b9 3864 GtkWidget *w_hbox = gtk_hbox_new(FALSE, 4);
3865 GtkWidget *w_label = gtk_label_new (label);
3866 GtkWidget *pixmap = create_pixmap(GTK_WIDGET(notebook), "close.png");
3867 GtkWidget *w_button = gtk_button_new ();
3868 gtk_container_add(GTK_CONTAINER(w_button), pixmap);
3869 //GtkWidget *w_button = gtk_button_new_with_label("x");
3870
3871 gtk_button_set_relief(GTK_BUTTON(w_button), GTK_RELIEF_NONE);
3872
3873 gtk_box_pack_start(GTK_BOX(w_hbox), w_label, TRUE, TRUE, 0);
3874 gtk_box_pack_end(GTK_BOX(w_hbox), w_button, FALSE,
3875 FALSE, 0);
a43d67ba 3876
27a559b9 3877 g_signal_connect_swapped (w_button, "clicked",
3878 G_CALLBACK (on_close_tab_X_clicked),
3879 tab->multi_vpaned);
5723fa24 3880
3c031040 3881 gtk_widget_set_state(w_button, GTK_STATE_ACTIVE);
3882
27a559b9 3883 gtk_widget_show (w_label);
3884 gtk_widget_show (pixmap);
3885 gtk_widget_show (w_button);
3886 gtk_widget_show (w_hbox);
3887
3888 tab->label = w_hbox;
3c031040 3889 }*/
3890
3891
3892 tab->label = gtk_label_new (label);
b052368a 3893
3894 gtk_widget_show(tab->label);
3895 gtk_widget_show(tab->scrollbar);
3896 gtk_widget_show(tab->viewer_container);
3897 gtk_widget_show(tab->vbox);
3898 //gtk_widget_show(tab->multivpaned);
3c031040 3899
3900
501e4e70 3901 /* Start with empty events requests list */
6ced96ef 3902 tab->events_requests = NULL;
3903 tab->events_request_pending = FALSE;
a43d67ba 3904
f7afe191 3905 g_object_set_data_full(
b052368a 3906 G_OBJECT(tab->vbox),
f7afe191 3907 "Tab_Info",
6ced96ef 3908 tab,
3909 (GDestroyNotify)tab_destructor);
540edb40 3910
b052368a 3911 g_signal_connect(G_OBJECT(tab->scrollbar), "value-changed",
3912 G_CALLBACK(scroll_value_changed_cb), tab);
3913 //g_signal_connect(G_OBJECT(tab->scrollbar), "changed",
3914 // G_CALLBACK(scroll_value_changed_cb), tab);
3915
3916
784705cc 3917 //insert tab into notebook
6ced96ef 3918 gtk_notebook_append_page(notebook,
b052368a 3919 tab->vbox,
3920 tab->label);
5723fa24 3921 list = gtk_container_get_children(GTK_CONTAINER(notebook));
3922 gtk_notebook_set_current_page(notebook,g_list_length(list)-1);
a43d67ba 3923 // always show : not if(g_list_length(list)>1)
3924 gtk_notebook_set_show_tabs(notebook, TRUE);
3925
6ced96ef 3926 return tab;
a43d67ba 3927}
3928
501e4e70 3929/*
3930 * execute_events_requests
3931 *
3932 * Idle function that executes the pending requests for a tab.
3933 *
3934 * @return return value : TRUE : keep the idle function, FALSE : remove it.
3935 */
3936gboolean execute_events_requests(Tab *tab)
a43d67ba 3937{
501e4e70 3938 return ( lttvwindow_process_pending_requests(tab) );
a43d67ba 3939}
3940
This page took 0.220917 seconds and 4 git commands to generate.