load module uninitialized variable bugfix
[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>
f02b5e22 25#include <ctype.h>
26#include <string.h>
27#include <stdlib.h>
a1a2b649 28
561eba2a 29#include <gtk/gtk.h>
561eba2a 30
31#include "callbacks.h"
32#include "interface.h"
33#include "support.h"
a43d67ba 34#include <ltt/trace.h>
35#include <ltt/facility.h>
36#include <ltt/time.h>
37#include <ltt/event.h>
2a2fa4f0 38#include <lttv/lttv.h>
a43d67ba 39#include <lttv/module.h>
40#include <lttv/iattribute.h>
41#include <lttv/stats.h>
13f86ce2 42#include <lttvwindow/mainwindow.h>
2d262115 43#include <lttvwindow/mainwindow-private.h>
13f86ce2 44#include <lttvwindow/menu.h>
45#include <lttvwindow/toolbar.h>
501e4e70 46#include <lttvwindow/lttvwindow.h>
a1a2b649 47#include <lttvwindow/lttvwindowtraces.h>
13f86ce2 48#include <lttvwindow/gtkdirsel.h>
13f86ce2 49#include <lttvwindow/lttvfilter.h>
6b1d3120 50
a1a2b649 51
f7afe191 52#define DEFAULT_TIME_WIDTH_S 1
f02b5e22 53#define CLIP_BUF 256 // size of clipboard buffer
f7afe191 54
49bf71b5 55extern LttvTrace *g_init_trace ;
561eba2a 56
ec25ff5e 57
58/** Array containing instanced objects. */
68b48a45 59extern GSList * g_main_window_list;
561eba2a 60
a43d67ba 61/** MD : keep old directory. */
a1a2b649 62static char remember_plugins_dir[PATH_MAX] = "";
63static char remember_trace_dir[PATH_MAX] = "";
6fbb1ddf 64
65
bca3b81f 66MainWindow * get_window_data_struct(GtkWidget * widget);
b052368a 67char * get_load_module(char ** load_module_name, int nb_module);
36b3c068 68char * get_unload_module(char ** loaded_module_name, int nb_module);
2176f952 69char * get_remove_trace(char ** all_trace_name, int nb_trace);
70char * get_selection(char ** all_name, int nb, char *title, char * column_title);
a8c0f09d 71gboolean get_filter_selection(LttvTracesetSelector *s, char *title, char * column_title);
6ced96ef 72Tab* create_tab(MainWindow * mw, Tab *copy_tab,
716e4367 73 GtkNotebook * notebook, char * label);
561eba2a 74
2d262115 75static void insert_viewer(GtkWidget* widget, lttvwindow_viewer_constructor constructor);
49bf71b5 76void update_filter(LttvTracesetSelector *s, GtkTreeStore *store );
77
78void checkbox_changed(GtkTreeView *treeview,
79 GtkTreePath *arg1,
80 GtkTreeViewColumn *arg2,
81 gpointer user_data);
b052368a 82void remove_trace_from_traceset_selector(GtkWidget * paned, unsigned i);
83void add_trace_into_traceset_selector(GtkWidget * paned, LttTrace * trace);
6ced96ef 84Tab *create_new_tab(GtkWidget* widget, gpointer user_data);
49bf71b5 85
86LttvTracesetSelector * construct_traceset_selector(LttvTraceset * traceset);
87
501e4e70 88static gboolean lttvwindow_process_pending_requests(Tab *tab);
202f6c8f 89
49bf71b5 90enum {
91 CHECKBOX_COLUMN,
92 NAME_COLUMN,
93 TOTAL_COLUMNS
94};
561eba2a 95
36b3c068 96enum
97{
98 MODULE_COLUMN,
99 N_COLUMNS
100};
101
abe346a3 102/* Construct a selector(filter), which will be associated with a viewer,
103 * and provides an interface for user to select interested events and traces
104 */
561eba2a 105
49bf71b5 106LttvTracesetSelector * construct_traceset_selector(LttvTraceset * traceset)
107{
108 LttvTracesetSelector * s;
109 LttvTraceSelector * trace;
110 LttvTracefileSelector * tracefile;
ed3b99b6 111 LttvEventtypeSelector * eventtype;
112 int i, j, k, m;
113 int nb_trace, nb_tracefile, nb_control, nb_per_cpu, nb_facility, nb_event;
49bf71b5 114 LttvTrace * trace_v;
115 LttTrace * t;
116 LttTracefile *tf;
ed3b99b6 117 LttFacility * fac;
118 LttEventType * et;
49bf71b5 119
120 s = lttv_traceset_selector_new(lttv_traceset_name(traceset));
121 nb_trace = lttv_traceset_number(traceset);
122 for(i=0;i<nb_trace;i++){
123 trace_v = lttv_traceset_get(traceset, i);
124 t = lttv_trace(trace_v);
125 trace = lttv_trace_selector_new(t);
ed3b99b6 126 lttv_traceset_selector_trace_add(s, trace);
127
128 nb_facility = ltt_trace_facility_number(t);
129 for(k=0;k<nb_facility;k++){
130 fac = ltt_trace_facility_get(t,k);
131 nb_event = (int) ltt_facility_eventtype_number(fac);
132 for(m=0;m<nb_event;m++){
133 et = ltt_facility_eventtype_get(fac,m);
134 eventtype = lttv_eventtype_selector_new(et);
135 lttv_trace_selector_eventtype_add(trace, eventtype);
136 }
137 }
138
49bf71b5 139 nb_control = ltt_trace_control_tracefile_number(t);
140 nb_per_cpu = ltt_trace_per_cpu_tracefile_number(t);
141 nb_tracefile = nb_control + nb_per_cpu;
142
143 for(j = 0 ; j < nb_tracefile ; j++) {
144 if(j < nb_control)
145 tf = ltt_trace_control_tracefile_get(t, j);
146 else
147 tf = ltt_trace_per_cpu_tracefile_get(t, j - nb_control);
148 tracefile = lttv_tracefile_selector_new(tf);
ed3b99b6 149 lttv_trace_selector_tracefile_add(trace, tracefile);
150 lttv_eventtype_selector_copy(trace, tracefile);
49bf71b5 151 }
152 }
153 return s;
154}
155
f02b5e22 156/* Pasting routines */
157
158static void MEventBox1a_receive(GtkClipboard *clipboard,
159 const gchar *text,
160 gpointer data)
161{
162 if(text == NULL) return;
163 Tab *tab = (Tab *)data;
164 gchar buffer[CLIP_BUF];
165 gchar *ptr = buffer, *ptr_ssec, *ptr_snsec, *ptr_esec, *ptr_ensec;
166
167 strncpy(buffer, text, CLIP_BUF);
168
169 /* start */
170 while(!isdigit(*ptr) && ptr < buffer+CLIP_BUF-1) ptr++;
171 /* remove leading junk */
172 ptr_ssec = ptr;
173 while(isdigit(*ptr) && ptr < buffer+CLIP_BUF-1) ptr++;
174 /* read all the first number */
175 *ptr = '\0';
176 ptr++;
177
178 while(!isdigit(*ptr) && ptr < buffer+CLIP_BUF-1) ptr++;
179 /* remove leading junk */
180 ptr_snsec = ptr;
181 while(isdigit(*ptr) && ptr < buffer+CLIP_BUF-1) ptr++;
182 /* read all the first number */
183 *ptr = '\0';
184
185 /* end */
186 while(!isdigit(*ptr) && ptr < buffer+CLIP_BUF-1) ptr++;
187 /* remove leading junk */
188 ptr_esec = ptr;
189 while(isdigit(*ptr) && ptr < buffer+CLIP_BUF-1) ptr++;
190 /* read all the first number */
191 *ptr = '\0';
192 ptr++;
193
194 while(!isdigit(*ptr) && ptr < buffer+CLIP_BUF-1) ptr++;
195 /* remove leading junk */
196 ptr_ensec = ptr;
197 while(isdigit(*ptr) && ptr < buffer+CLIP_BUF-1) ptr++;
198 /* read all the first number */
199 *ptr = '\0';
200
201 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab->MEntry1),
202 (double)strtoul(ptr_ssec, NULL, 10));
203 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab->MEntry2),
204 (double)strtoul(ptr_snsec, NULL, 10));
205 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab->MEntry3),
206 (double)strtoul(ptr_esec, NULL, 10));
207 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab->MEntry4),
208 (double)strtoul(ptr_ensec, NULL, 10));
209}
210
211static gboolean on_MEventBox1a_paste(GtkWidget *widget, GdkEventButton *event,
212 gpointer data)
213{
214 Tab *tab = (Tab*)data;
215
216 GtkClipboard *clip = gtk_clipboard_get_for_display(gdk_display_get_default(),
217 GDK_SELECTION_PRIMARY);
218 gtk_clipboard_request_text(clip,
219 (GtkClipboardTextReceivedFunc)MEventBox1a_receive,
220 (gpointer)tab);
221 return 0;
222}
223
224
225/* Start */
226static void MEventBox1b_receive(GtkClipboard *clipboard,
227 const gchar *text,
228 gpointer data)
229{
230 if(text == NULL) return;
231 Tab *tab = (Tab *)data;
232 gchar buffer[CLIP_BUF];
233 gchar *ptr = buffer, *ptr_sec, *ptr_nsec;
234
235 strncpy(buffer, text, CLIP_BUF);
236
237 while(!isdigit(*ptr) && ptr < buffer+CLIP_BUF-1) ptr++;
238 /* remove leading junk */
239 ptr_sec = ptr;
240 while(isdigit(*ptr) && ptr < buffer+CLIP_BUF-1) ptr++;
241 /* read all the first number */
242 *ptr = '\0';
243 ptr++;
244
245 while(!isdigit(*ptr) && ptr < buffer+CLIP_BUF-1) ptr++;
246 /* remove leading junk */
247 ptr_nsec = ptr;
248 while(isdigit(*ptr) && ptr < buffer+CLIP_BUF-1) ptr++;
249 /* read all the first number */
250 *ptr = '\0';
251
252 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab->MEntry1),
253 (double)strtoul(ptr_sec, NULL, 10));
254 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab->MEntry2),
255 (double)strtoul(ptr_nsec, NULL, 10));
256}
257
258/* Start */
259static gboolean on_MEventBox1b_paste(GtkWidget *widget, GdkEventButton *event,
260 gpointer data)
261{
262 Tab *tab = (Tab*)data;
263
264 GtkClipboard *clip = gtk_clipboard_get_for_display(gdk_display_get_default(),
265 GDK_SELECTION_PRIMARY);
266 gtk_clipboard_request_text(clip,
267 (GtkClipboardTextReceivedFunc)MEventBox1b_receive,
268 (gpointer)tab);
269 return 0;
270}
271
272/* End */
273static void MEventBox3b_receive(GtkClipboard *clipboard,
274 const gchar *text,
275 gpointer data)
276{
277 if(text == NULL) return;
278 Tab *tab = (Tab *)data;
279 gchar buffer[CLIP_BUF];
280 gchar *ptr = buffer, *ptr_sec, *ptr_nsec;
281
282 strncpy(buffer, text, CLIP_BUF);
283
284 while(!isdigit(*ptr) && ptr < buffer+CLIP_BUF-1) ptr++;
285 /* remove leading junk */
286 ptr_sec = ptr;
287 while(isdigit(*ptr) && ptr < buffer+CLIP_BUF-1) ptr++;
288 /* read all the first number */
289 *ptr = '\0';
290 ptr++;
291
292 while(!isdigit(*ptr) && ptr < buffer+CLIP_BUF-1) ptr++;
293 /* remove leading junk */
294 ptr_nsec = ptr;
295 while(isdigit(*ptr) && ptr < buffer+CLIP_BUF-1) ptr++;
296 /* read all the first number */
297 *ptr = '\0';
298
299 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab->MEntry3),
300 (double)strtoul(ptr_sec, NULL, 10));
301 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab->MEntry4),
302 (double)strtoul(ptr_nsec, NULL, 10));
303}
304
305/* End */
306static gboolean on_MEventBox3b_paste(GtkWidget *widget, GdkEventButton *event,
307 gpointer data)
308{
309 Tab *tab = (Tab*)data;
310
311 GtkClipboard *clip = gtk_clipboard_get_for_display(gdk_display_get_default(),
312 GDK_SELECTION_PRIMARY);
313 gtk_clipboard_request_text(clip,
314 (GtkClipboardTextReceivedFunc)MEventBox3b_receive,
315 (gpointer)tab);
316 return 0;
317}
318
319/* Current */
320static void MEventBox5b_receive(GtkClipboard *clipboard,
321 const gchar *text,
322 gpointer data)
323{
324 if(text == NULL) return;
325 Tab *tab = (Tab *)data;
326 gchar buffer[CLIP_BUF];
327 gchar *ptr = buffer, *ptr_sec, *ptr_nsec;
328
329 strncpy(buffer, text, CLIP_BUF);
330
331 while(!isdigit(*ptr) && ptr < buffer+CLIP_BUF-1) ptr++;
332 /* remove leading junk */
333 ptr_sec = ptr;
334 while(isdigit(*ptr) && ptr < buffer+CLIP_BUF-1) ptr++;
335 /* read all the first number */
336 *ptr = '\0';
337 ptr++;
338
339 while(!isdigit(*ptr) && ptr < buffer+CLIP_BUF-1) ptr++;
340 /* remove leading junk */
341 ptr_nsec = ptr;
342 while(isdigit(*ptr) && ptr < buffer+CLIP_BUF-1) ptr++;
343 /* read all the first number */
344 *ptr = '\0';
345
346 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab->MEntry5),
347 (double)strtoul(ptr_sec, NULL, 10));
348 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab->MEntry6),
349 (double)strtoul(ptr_nsec, NULL, 10));
350}
351
352/* Current */
353static gboolean on_MEventBox5b_paste(GtkWidget *widget, GdkEventButton *event,
354 gpointer data)
355{
356 Tab *tab = (Tab*)data;
357
358 GtkClipboard *clip = gtk_clipboard_get_for_display(gdk_display_get_default(),
359 GDK_SELECTION_PRIMARY);
360 gtk_clipboard_request_text(clip,
361 (GtkClipboardTextReceivedFunc)MEventBox5b_receive,
362 (gpointer)tab);
363 return 0;
364}
365
366
b052368a 367static gboolean viewer_grab_focus(GtkWidget *widget, GdkEventButton *event,
368 gpointer data)
369{
f37a2002 370 GtkWidget *viewer = GTK_WIDGET(data);
371 GtkWidget *viewer_container = gtk_widget_get_parent(viewer);
b052368a 372
373 g_debug("FOCUS GRABBED");
f37a2002 374 g_object_set_data(G_OBJECT(viewer_container), "focused_viewer", viewer);
375 return 0;
b052368a 376}
377
f02b5e22 378
f37a2002 379static void connect_focus_recursive(GtkWidget *widget,
380 GtkWidget *viewer)
381{
382 if(GTK_IS_CONTAINER(widget)) {
383 gtk_container_forall(GTK_CONTAINER(widget),
384 (GtkCallback)connect_focus_recursive,
385 viewer);
1818a315 386
387 }
388 if(GTK_IS_TREE_VIEW(widget)) {
2eef04b5 389 gtk_tree_view_set_headers_clickable(GTK_TREE_VIEW(widget), TRUE);
f37a2002 390 }
391 gtk_widget_add_events(widget, GDK_BUTTON_PRESS_MASK);
392 g_signal_connect (G_OBJECT(widget),
393 "button-press-event",
394 G_CALLBACK (viewer_grab_focus),
395 (gpointer)viewer);
396}
b052368a 397
abe346a3 398/* insert_viewer function constructs an instance of a viewer first,
399 * then inserts the widget of the instance into the container of the
400 * main window
401 */
402
561eba2a 403void
606309a4 404insert_viewer_wrap(GtkWidget *menuitem, gpointer user_data)
561eba2a 405{
42fcbb71 406 insert_viewer((GtkWidget*)menuitem, (lttvwindow_viewer_constructor)user_data);
561eba2a 407}
408
561eba2a 409
410/* internal functions */
2d262115 411void insert_viewer(GtkWidget* widget, lttvwindow_viewer_constructor constructor)
561eba2a 412{
b052368a 413 GtkWidget * viewer_container;
501e4e70 414 MainWindow * mw_data = get_window_data_struct(widget);
6ced96ef 415 GtkWidget * notebook = lookup_widget(widget, "MNotebook");
f9334f6f 416 GtkWidget * viewer;
49bf71b5 417 LttvTracesetSelector * s;
202f6c8f 418 TimeInterval * time_interval;
6ced96ef 419 GtkWidget *page = gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook),
420 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook)));
421 Tab *tab;
422
423 if(!page) {
424 tab = create_new_tab(widget, NULL);
425 } else {
426 tab = (Tab *)g_object_get_data(G_OBJECT(page), "Tab_Info");
47cd8a09 427 }
428
b052368a 429 viewer_container = tab->viewer_container;
561eba2a 430
501e4e70 431 s = construct_traceset_selector(tab->traceset_info->traceset);
d47b33d2 432 viewer = (GtkWidget*)constructor(tab);
f9334f6f 433 if(viewer)
f0d936c0 434 {
b052368a 435 //gtk_multivpaned_widget_add(GTK_MULTIVPANED(multivpaned), viewer);
436
437 gtk_box_pack_end(GTK_BOX(viewer_container),
438 viewer,
439 TRUE,
440 TRUE,
441 0);
442
f37a2002 443 /* We want to connect the viewer_grab_focus to EVERY
444 * child of this widget. The little trick is to get each child
445 * of each GTK_CONTAINER, even subchildren.
446 */
0f9d55ef 447 connect_focus_recursive(viewer, viewer);
f0d936c0 448 }
561eba2a 449}
450
313bd6fc 451/**
452 * Function to set/update traceset for the viewers
453 * @param tab viewer's tab
454 * @param traceset traceset of the main window.
455 * return value :
456 * 0 : traceset updated
457 * 1 : no traceset hooks to update; not an error.
458 */
459
460int SetTraceset(Tab * tab, LttvTraceset *traceset)
461{
b052368a 462 LttvTracesetContext *tsc =
463 LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context);
464 TimeInterval time_span = tsc->time_span;
e800cf84 465 TimeWindow new_time_window;
466 LttTime new_current_time;
1ba187d3 467
468 /* Set the tab's time window and current time if
469 * out of bounds */
470 if(ltt_time_compare(tab->time_window.start_time, time_span.start_time) < 0
6f26fc38 471 || ltt_time_compare(tab->time_window.end_time,
1ba187d3 472 time_span.end_time) > 0) {
e800cf84 473 new_time_window.start_time = time_span.start_time;
474
475 new_current_time = time_span.start_time;
1ba187d3 476
477 LttTime tmp_time;
478
479 if(DEFAULT_TIME_WIDTH_S < time_span.end_time.tv_sec)
480 tmp_time.tv_sec = DEFAULT_TIME_WIDTH_S;
481 else
482 tmp_time.tv_sec = time_span.end_time.tv_sec;
483 tmp_time.tv_nsec = 0;
e800cf84 484 new_time_window.time_width = tmp_time ;
a18124ff 485 new_time_window.time_width_double = ltt_time_to_double(tmp_time);
6f26fc38 486 new_time_window.end_time = ltt_time_add(new_time_window.start_time,
487 new_time_window.time_width) ;
1ba187d3 488 }
e800cf84 489 time_change_manager(tab, new_time_window);
490 current_time_change_manager(tab, new_current_time);
491
492#if 0
1ba187d3 493 /* Set scrollbar */
b052368a 494 GtkAdjustment *adjustment = gtk_range_get_adjustment(GTK_RANGE(tab->scrollbar));
0c5dbe3b 495 LttTime upper = ltt_time_sub(time_span.end_time, time_span.start_time);
b052368a 496
497 g_object_set(G_OBJECT(adjustment),
498 "lower",
0c5dbe3b 499 0.0, /* lower */
b052368a 500 "upper",
0c5dbe3b 501 ltt_time_to_double(upper)
b052368a 502 * NANOSECONDS_PER_SECOND, /* upper */
503 "step_increment",
504 ltt_time_to_double(tab->time_window.time_width)
505 / SCROLL_STEP_PER_PAGE
506 * NANOSECONDS_PER_SECOND, /* step increment */
507 "page_increment",
508 ltt_time_to_double(tab->time_window.time_width)
509 * NANOSECONDS_PER_SECOND, /* page increment */
510 "page_size",
511 ltt_time_to_double(tab->time_window.time_width)
512 * NANOSECONDS_PER_SECOND, /* page size */
513 NULL);
514 gtk_adjustment_changed(adjustment);
515
516 g_object_set(G_OBJECT(adjustment),
517 "value",
b9a010a2 518 ltt_time_to_double(
519 ltt_time_sub(tab->time_window.start_time, time_span.start_time))
520 * NANOSECONDS_PER_SECOND, /* value */
b052368a 521 NULL);
522 gtk_adjustment_value_changed(adjustment);
1ba187d3 523
e800cf84 524 /* set the time bar. The value callbacks will change their nsec themself */
525 /* start seconds */
526 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab->MEntry1),
527 (double)time_span.start_time.tv_sec,
528 (double)time_span.end_time.tv_sec);
529
530 /* end seconds */
531 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab->MEntry3),
532 (double)time_span.start_time.tv_sec,
533 (double)time_span.end_time.tv_sec);
534
535 /* current seconds */
536 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab->MEntry5),
537 (double)time_span.start_time.tv_sec,
538 (double)time_span.end_time.tv_sec);
539#endif //0
540
1ba187d3 541 /* Finally, call the update hooks of the viewers */
542 LttvHooks * tmp;
543 LttvAttributeValue value;
544 gint retval = 0;
545
546
547 g_assert( lttv_iattribute_find_by_path(tab->attributes,
548 "hooks/updatetraceset", LTTV_POINTER, &value));
549
550 tmp = (LttvHooks*)*(value.v_pointer);
551 if(tmp == NULL) retval = 1;
552 else lttv_hooks_call(tmp,traceset);
553
554
b052368a 555 return retval;
313bd6fc 556}
557
558/**
559 * Function to set/update filter for the viewers
560 * @param tab viewer's tab
561 * @param filter filter of the main window.
562 * return value :
563 * -1 : error
564 * 0 : filters updated
565 * 1 : no filter hooks to update; not an error.
566 */
567
568int SetFilter(Tab * tab, gpointer filter)
569{
570 LttvHooks * tmp;
571 LttvAttributeValue value;
572
573 g_assert(lttv_iattribute_find_by_path(tab->attributes,
574 "hooks/updatefilter", LTTV_POINTER, &value));
575
576 tmp = (LttvHooks*)*(value.v_pointer);
577
578 if(tmp == NULL) return 1;
579 lttv_hooks_call(tmp,filter);
580
581 return 0;
582}
583
584
585
586/**
587 * Function to redraw each viewer belonging to the current tab
588 * @param tab viewer's tab
589 */
590
591void update_traceset(Tab *tab)
592{
593 LttvAttributeValue value;
594 LttvHooks * tmp;
595 g_assert(lttv_iattribute_find_by_path(tab->attributes,
596 "hooks/updatetraceset", LTTV_POINTER, &value));
597 tmp = (LttvHooks*)*(value.v_pointer);
598 if(tmp == NULL) return;
599 lttv_hooks_call(tmp, NULL);
600}
601
abe346a3 602
603/* get_label function is used to get user input, it displays an input
604 * box, which allows user to input a string
605 */
606
561eba2a 607void get_label_string (GtkWidget * text, gchar * label)
608{
609 GtkEntry * entry = (GtkEntry*)text;
610 if(strlen(gtk_entry_get_text(entry))!=0)
611 strcpy(label,gtk_entry_get_text(entry));
612}
613
eb38aea5 614gboolean get_label(MainWindow * mw, gchar * str, gchar* dialogue_title, gchar * label_str)
561eba2a 615{
616 GtkWidget * dialogue;
617 GtkWidget * text;
618 GtkWidget * label;
619 gint id;
620
5723fa24 621 dialogue = gtk_dialog_new_with_buttons(dialogue_title,NULL,
561eba2a 622 GTK_DIALOG_MODAL,
623 GTK_STOCK_OK,GTK_RESPONSE_ACCEPT,
624 GTK_STOCK_CANCEL,GTK_RESPONSE_REJECT,
625 NULL);
626
6b1d3120 627 label = gtk_label_new(label_str);
561eba2a 628 gtk_widget_show(label);
629
630 text = gtk_entry_new();
631 gtk_widget_show(text);
632
633 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialogue)->vbox), label,TRUE, TRUE,0);
634 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialogue)->vbox), text,FALSE, FALSE,0);
635
636 id = gtk_dialog_run(GTK_DIALOG(dialogue));
637 switch(id){
638 case GTK_RESPONSE_ACCEPT:
639 get_label_string(text,str);
640 gtk_widget_destroy(dialogue);
641 break;
642 case GTK_RESPONSE_REJECT:
643 default:
644 gtk_widget_destroy(dialogue);
eb38aea5 645 return FALSE;
561eba2a 646 }
eb38aea5 647 return TRUE;
561eba2a 648}
649
abe346a3 650
651/* get_window_data_struct function is actually a lookup function,
652 * given a widget which is in the tree of the main window, it will
653 * return the MainWindow data structure associated with main window
654 */
655
bca3b81f 656MainWindow * get_window_data_struct(GtkWidget * widget)
561eba2a 657{
658 GtkWidget * mw;
bca3b81f 659 MainWindow * mw_data;
561eba2a 660
661 mw = lookup_widget(widget, "MWindow");
662 if(mw == NULL){
56e5a0f7 663 g_info("Main window does not exist\n");
2d262115 664 return NULL;
561eba2a 665 }
666
2d262115 667 mw_data = (MainWindow *) g_object_get_data(G_OBJECT(mw),"main_window_data");
68b48a45 668 if(mw_data == NULL){
2eef04b5 669 g_warning("Main window data does not exist\n");
2d262115 670 return NULL;
561eba2a 671 }
68b48a45 672 return mw_data;
561eba2a 673}
674
abe346a3 675
676/* create_new_window function, just constructs a new main window
677 */
678
68b48a45 679void create_new_window(GtkWidget* widget, gpointer user_data, gboolean clone)
561eba2a 680{
bca3b81f 681 MainWindow * parent = get_window_data_struct(widget);
561eba2a 682
561eba2a 683 if(clone){
56e5a0f7 684 g_info("Clone : use the same traceset\n");
08b1c66e 685 construct_main_window(parent);
561eba2a 686 }else{
56e5a0f7 687 g_info("Empty : traceset is set to NULL\n");
08b1c66e 688 construct_main_window(NULL);
561eba2a 689 }
690}
691
0f9d55ef 692/* Get the currently focused viewer.
693 * If no viewer is focused, use the first one.
694 *
695 * If no viewer available, return NULL.
696 */
b052368a 697GtkWidget *viewer_container_focus(GtkWidget *container)
698{
699 GtkWidget *widget;
700
701 widget = (GtkWidget*)g_object_get_data(G_OBJECT(container),
bb574a9c 702 "focused_viewer");
b052368a 703
0f9d55ef 704 if(widget == NULL) {
705 g_debug("no widget focused");
706 GList *children = gtk_container_get_children(GTK_CONTAINER(container));
707
708 if(children != NULL)
709 widget = GTK_WIDGET(children->data);
bb574a9c 710 g_object_set_data(G_OBJECT(container),
711 "focused_viewer",
712 widget);
0f9d55ef 713 }
714
b052368a 715 return widget;
716
717
718}
719
720gint viewer_container_position(GtkWidget *container, GtkWidget *child)
721{
722
723 if(child == NULL) return -1;
724
725 gint pos;
2eef04b5 726 GValue value;
727 memset(&value, 0, sizeof(GValue));
b052368a 728 g_value_init(&value, G_TYPE_INT);
729 gtk_container_child_get_property(GTK_CONTAINER(container),
730 child,
731 "position",
732 &value);
733 pos = g_value_get_int(&value);
734
735 return pos;
736}
737
abe346a3 738
739/* move_*_viewer functions move the selected view up/down in
740 * the current tab
741 */
742
b052368a 743void move_down_viewer(GtkWidget * widget, gpointer user_data)
561eba2a 744{
bca3b81f 745 MainWindow * mw = get_window_data_struct(widget);
6ced96ef 746 GtkWidget * notebook = lookup_widget(widget, "MNotebook");
747
748 GtkWidget *page = gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook),
749 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook)));
750
751 Tab *tab;
6ced96ef 752 if(!page) {
753 return;
754 } else {
755 tab = (Tab *)g_object_get_data(G_OBJECT(page), "Tab_Info");
756 }
757
b052368a 758 //gtk_multivpaned_widget_move_up(GTK_MULTIVPANED(tab->multivpaned));
759
760 /* change the position in the vbox */
761 GtkWidget *focus_widget;
762 gint position;
763 focus_widget = viewer_container_focus(tab->viewer_container);
764 position = viewer_container_position(tab->viewer_container, focus_widget);
765
766 if(position > 0) {
767 /* can move up one position */
768 gtk_box_reorder_child(GTK_BOX(tab->viewer_container),
769 focus_widget,
770 position-1);
771 }
772
561eba2a 773}
774
b052368a 775void move_up_viewer(GtkWidget * widget, gpointer user_data)
561eba2a 776{
bca3b81f 777 MainWindow * mw = get_window_data_struct(widget);
6ced96ef 778 GtkWidget * notebook = lookup_widget(widget, "MNotebook");
779
780 GtkWidget *page = gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook),
781 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook)));
782 Tab *tab;
783
784 if(!page) {
785 return;
786 } else {
787 tab = (Tab *)g_object_get_data(G_OBJECT(page), "Tab_Info");
788 }
789
b052368a 790 //gtk_multivpaned_widget_move_down(GTK_MULTIVPANED(tab->multivpaned));
791 /* change the position in the vbox */
792 GtkWidget *focus_widget;
793 gint position;
794 focus_widget = viewer_container_focus(tab->viewer_container);
795 position = viewer_container_position(tab->viewer_container, focus_widget);
796
797 if(position != -1 &&
798 position <
799 g_list_length(gtk_container_get_children(
800 GTK_CONTAINER(tab->viewer_container)))-1
801 ) {
802 /* can move down one position */
803 gtk_box_reorder_child(GTK_BOX(tab->viewer_container),
804 focus_widget,
805 position+1);
806 }
807
561eba2a 808}
809
abe346a3 810
811/* delete_viewer deletes the selected viewer in the current tab
812 */
813
561eba2a 814void delete_viewer(GtkWidget * widget, gpointer user_data)
815{
bca3b81f 816 MainWindow * mw = get_window_data_struct(widget);
6ced96ef 817 GtkWidget * notebook = lookup_widget(widget, "MNotebook");
818
819 GtkWidget *page = gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook),
820 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook)));
821 Tab *tab;
822
823 if(!page) {
824 return;
825 } else {
826 tab = (Tab *)g_object_get_data(G_OBJECT(page), "Tab_Info");
827 }
828
b052368a 829 //gtk_multivpaned_widget_delete(GTK_MULTIVPANED(tab->multivpaned));
830
831 GtkWidget *focus_widget = viewer_container_focus(tab->viewer_container);
832
833 if(focus_widget != NULL)
834 gtk_widget_destroy(focus_widget);
835
836 g_object_set_data(G_OBJECT(tab->viewer_container), "focused_viewer", NULL);
561eba2a 837}
838
abe346a3 839
840/* open_traceset will open a traceset saved in a file
841 * Right now, it is not finished yet, (not working)
a43d67ba 842 * FIXME
abe346a3 843 */
844
561eba2a 845void open_traceset(GtkWidget * widget, gpointer user_data)
846{
2176f952 847 char ** dir;
848 gint id;
849 LttvTraceset * traceset;
bca3b81f 850 MainWindow * mw_data = get_window_data_struct(widget);
68b48a45 851 GtkFileSelection * file_selector =
2176f952 852 (GtkFileSelection *)gtk_file_selection_new("Select a traceset");
853
68b48a45 854 gtk_file_selection_hide_fileop_buttons(file_selector);
c64c7ea1 855
68b48a45 856 id = gtk_dialog_run(GTK_DIALOG(file_selector));
2176f952 857 switch(id){
858 case GTK_RESPONSE_ACCEPT:
859 case GTK_RESPONSE_OK:
68b48a45 860 dir = gtk_file_selection_get_selections (file_selector);
2176f952 861 traceset = lttv_traceset_load(dir[0]);
56e5a0f7 862 g_info("Open a trace set %s\n", dir[0]);
2176f952 863 //Not finished yet
864 g_strfreev(dir);
865 case GTK_RESPONSE_REJECT:
866 case GTK_RESPONSE_CANCEL:
867 default:
68b48a45 868 gtk_widget_destroy((GtkWidget*)file_selector);
2176f952 869 break;
870 }
c64c7ea1 871
561eba2a 872}
873
b052368a 874static void events_request_free(EventsRequest *events_request)
875{
876 if(events_request == NULL) return;
877
878 if(events_request->start_position != NULL)
879 lttv_traceset_context_position_destroy(events_request->start_position);
880 if(events_request->end_position != NULL)
881 lttv_traceset_context_position_destroy(events_request->end_position);
10a1069a 882 if(events_request->hooks != NULL)
883 g_array_free(events_request->hooks, TRUE);
b052368a 884 if(events_request->before_chunk_traceset != NULL)
885 lttv_hooks_destroy(events_request->before_chunk_traceset);
886 if(events_request->before_chunk_trace != NULL)
887 lttv_hooks_destroy(events_request->before_chunk_trace);
888 if(events_request->before_chunk_tracefile != NULL)
889 lttv_hooks_destroy(events_request->before_chunk_tracefile);
890 if(events_request->event != NULL)
891 lttv_hooks_destroy(events_request->event);
892 if(events_request->event_by_id != NULL)
893 lttv_hooks_by_id_destroy(events_request->event_by_id);
894 if(events_request->after_chunk_tracefile != NULL)
895 lttv_hooks_destroy(events_request->after_chunk_tracefile);
896 if(events_request->after_chunk_trace != NULL)
897 lttv_hooks_destroy(events_request->after_chunk_trace);
898 if(events_request->after_chunk_traceset != NULL)
899 lttv_hooks_destroy(events_request->after_chunk_traceset);
900 if(events_request->before_request != NULL)
901 lttv_hooks_destroy(events_request->before_request);
902 if(events_request->after_request != NULL)
903 lttv_hooks_destroy(events_request->after_request);
904
905 g_free(events_request);
906}
907
908
abe346a3 909
501e4e70 910/* lttvwindow_process_pending_requests
911 *
912 * This internal function gets called by g_idle, taking care of the pending
913 * requests. It is responsible for concatenation of time intervals and position
914 * requests. It does it with the following algorithm organizing process traceset
915 * calls. Here is the detailed description of the way it works :
916 *
917 * - Events Requests Servicing Algorithm
918 *
919 * Data structures necessary :
920 *
921 * List of requests added to context : list_in
922 * List of requests not added to context : list_out
923 *
924 * Initial state :
925 *
926 * list_in : empty
927 * list_out : many events requests
928 *
929 * FIXME : insert rest of algorithm here
930 *
abe346a3 931 */
932
6ea08962 933#define list_out tab->events_requests
a43d67ba 934
501e4e70 935gboolean lttvwindow_process_pending_requests(Tab *tab)
a8c0f09d 936{
a8c0f09d 937 GtkWidget* widget;
a43d67ba 938 LttvTracesetContext *tsc;
501e4e70 939 LttvTracefileContext *tfc;
501e4e70 940 GSList *list_in = NULL;
941 LttTime end_time;
942 guint end_nb_events;
2d262115 943 guint count;
501e4e70 944 LttvTracesetContextPosition *end_position;
a43d67ba 945
b052368a 946 if(tab == NULL) {
947 g_critical("Foreground processing : tab does not exist. Processing removed.");
501e4e70 948 return FALSE;
b052368a 949 }
a43d67ba 950
501e4e70 951 /* There is no events requests pending : we should never have been called! */
6ea08962 952 g_assert(g_slist_length(list_out) != 0);
a43d67ba 953
501e4e70 954 tsc = LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context);
a8c0f09d 955
abe346a3 956 //set the cursor to be X shape, indicating that the computer is busy in doing its job
a0577796 957#if 0
a8c0f09d 958 new = gdk_cursor_new(GDK_X_CURSOR);
2d262115 959 widget = lookup_widget(tab->mw->mwindow, "MToolbar1");
a8c0f09d 960 win = gtk_widget_get_parent_window(widget);
961 gdk_window_set_cursor(win, new);
962 gdk_cursor_unref(new);
963 gdk_window_stick(win);
964 gdk_window_unstick(win);
a0577796 965#endif //0
a43d67ba 966
6ea08962 967 g_debug("SIZE events req len : %d", g_slist_length(list_out));
968
969 /* Preliminary check for no trace in traceset */
970 /* Unregister the routine if empty, empty list_out too */
971 if(lttv_traceset_number(tsc->ts) == 0) {
972
973 /* - For each req in list_out */
974 GSList *iter = list_out;
975
976 while(iter != NULL) {
977
978 gboolean remove = FALSE;
979 gboolean free_data = FALSE;
980 EventsRequest *events_request = (EventsRequest *)iter->data;
981
982 /* - Call end request for req */
983 if(events_request->servicing == TRUE)
984 lttv_hooks_call(events_request->after_request, (gpointer)tsc);
985
986 /* - remove req from list_out */
987 /* Destroy the request */
988 remove = TRUE;
989 free_data = TRUE;
990
991 /* Go to next */
992 if(remove)
993 {
994 GSList *remove_iter = iter;
995
996 iter = g_slist_next(iter);
b052368a 997 if(free_data) events_request_free((EventsRequest*)remove_iter->data);
6ea08962 998 list_out = g_slist_remove_link(list_out, remove_iter);
999 } else { // not remove
1000 iter = g_slist_next(iter);
1001 }
1002 }
1003 }
501e4e70 1004
b052368a 1005 /* 0.1 Lock Traces */
1006 {
1007 guint iter_trace=0;
1008
1009 for(iter_trace=0;
1010 iter_trace<lttv_traceset_number(tsc->ts);
1011 iter_trace++) {
1012 LttvTrace *trace_v = lttv_traceset_get(tsc->ts, iter_trace);
1013
1014 if(lttvwindowtraces_lock(trace_v) != 0) {
1015 g_critical("Foreground processing : Unable to get trace lock");
1016 return TRUE; /* Cannot get lock, try later */
1017 }
1018 }
1019 }
1020
1021 /* 0.2 Seek tracefiles positions to context position */
1022 lttv_process_traceset_synchronize_tracefiles(tsc);
1023
1024
501e4e70 1025 /* Events processing algorithm implementation */
dd316a11 1026 /* Warning : the gtk_events_pending takes a LOT of cpu time. So what we do
1027 * instead is to leave the control to GTK and take it back.
1028 */
501e4e70 1029 /* A. Servicing loop */
dd316a11 1030 //while( (g_slist_length(list_in) != 0 || g_slist_length(list_out) != 0)) {
3bafb436 1031 if((g_slist_length(list_in) != 0 || g_slist_length(list_out) != 0)) {
1032 /* Servicing */
1033 /* 1. If list_in is empty (need a seek) */
1034 if( g_slist_length(list_in) == 0 ) {
501e4e70 1035
3bafb436 1036 /* list in is empty, need a seek */
dd316a11 1037 {
3bafb436 1038 /* 1.1 Add requests to list_in */
1039 GSList *ltime = NULL;
1040 GSList *lpos = NULL;
1041 GSList *iter = NULL;
501e4e70 1042
3bafb436 1043 /* 1.1.1 Find all time requests with the lowest start time in list_out
1044 * (ltime)
1045 */
1046 if(g_slist_length(list_out) > 0)
1047 ltime = g_slist_append(ltime, g_slist_nth_data(list_out, 0));
1048 for(iter=g_slist_nth(list_out,1);iter!=NULL;iter=g_slist_next(iter)) {
1049 /* Find all time requests with the lowest start time in list_out */
3bafb436 1050 EventsRequest *event_request_ltime = (EventsRequest*)g_slist_nth_data(ltime, 0);
1051 EventsRequest *event_request_list_out = (EventsRequest*)iter->data;
1052
1053 int comp;
1054 comp = ltt_time_compare(event_request_ltime->start_time,
1055 event_request_list_out->start_time);
1056 if(comp == 0)
1057 ltime = g_slist_append(ltime, event_request_list_out);
1058 else if(comp > 0) {
1059 /* Remove all elements from ltime, and add current */
1060 while(ltime != NULL)
1061 ltime = g_slist_delete_link(ltime, g_slist_nth(ltime, 0));
1062 ltime = g_slist_append(ltime, event_request_list_out);
1063 }
501e4e70 1064 }
1065
3bafb436 1066 /* 1.1.2 Find all position requests with the lowest position in list_out
1067 * (lpos)
1068 */
1069 if(g_slist_length(list_out) > 0)
1070 lpos = g_slist_append(lpos, g_slist_nth_data(list_out, 0));
1071 for(iter=g_slist_nth(list_out,1);iter!=NULL;iter=g_slist_next(iter)) {
1072 /* Find all position requests with the lowest position in list_out */
1073 EventsRequest *event_request_lpos = (EventsRequest*)g_slist_nth_data(lpos, 0);
1074 EventsRequest *event_request_list_out = (EventsRequest*)iter->data;
1075
1076 int comp;
1077 if(event_request_lpos->start_position != NULL
1078 && event_request_list_out->start_position != NULL)
1079 {
1080 comp = lttv_traceset_context_pos_pos_compare
1081 (event_request_lpos->start_position,
1082 event_request_list_out->start_position);
1083 } else {
1084 comp = -1;
553d1e7b 1085 }
3bafb436 1086 if(comp == 0)
1087 lpos = g_slist_append(lpos, event_request_list_out);
1088 else if(comp > 0) {
1089 /* Remove all elements from lpos, and add current */
1090 while(lpos != NULL)
1091 lpos = g_slist_delete_link(lpos, g_slist_nth(lpos, 0));
1092 lpos = g_slist_append(lpos, event_request_list_out);
501e4e70 1093 }
1094 }
3bafb436 1095
1096 {
1097 EventsRequest *event_request_lpos = (EventsRequest*)g_slist_nth_data(lpos, 0);
1098 EventsRequest *event_request_ltime = (EventsRequest*)g_slist_nth_data(ltime, 0);
1099 LttTime lpos_start_time;
dd316a11 1100
3bafb436 1101 if(event_request_lpos != NULL
1102 && event_request_lpos->start_position != NULL) {
1103 lpos_start_time = lttv_traceset_context_position_get_time(
1104 event_request_lpos->start_position);
1105 }
1106
1107 /* 1.1.3 If lpos.start time < ltime */
1108 if(event_request_lpos != NULL
1109 && event_request_lpos->start_position != NULL
1110 && ltt_time_compare(lpos_start_time,
1111 event_request_ltime->start_time)<0) {
1112 /* Add lpos to list_in, remove them from list_out */
1113 for(iter=lpos;iter!=NULL;iter=g_slist_next(iter)) {
1114 /* Add to list_in */
1115 EventsRequest *event_request_lpos =
1116 (EventsRequest*)iter->data;
1117
1118 list_in = g_slist_append(list_in, event_request_lpos);
1119 /* Remove from list_out */
1120 list_out = g_slist_remove(list_out, event_request_lpos);
1121 }
1122 } else {
1123 /* 1.1.4 (lpos.start time >= ltime) */
1124 /* Add ltime to list_in, remove them from list_out */
1125
1126 for(iter=ltime;iter!=NULL;iter=g_slist_next(iter)) {
1127 /* Add to list_in */
1128 EventsRequest *event_request_ltime =
1129 (EventsRequest*)iter->data;
1130
1131 list_in = g_slist_append(list_in, event_request_ltime);
1132 /* Remove from list_out */
1133 list_out = g_slist_remove(list_out, event_request_ltime);
1134 }
1135 }
dd316a11 1136 }
3bafb436 1137 g_slist_free(lpos);
1138 g_slist_free(ltime);
dd316a11 1139 }
dd316a11 1140
3bafb436 1141 /* 1.2 Seek */
1142 {
1143 tfc = lttv_traceset_context_get_current_tfc(tsc);
1144 g_assert(g_slist_length(list_in)>0);
1145 EventsRequest *events_request = g_slist_nth_data(list_in, 0);
1146 guint seek_count;
1147
1148 /* 1.2.1 If first request in list_in is a time request */
1149 if(events_request->start_position == NULL) {
1150 /* - If first req in list_in start time != current time */
1151 if(tfc == NULL || ltt_time_compare(events_request->start_time,
1152 tfc->timestamp) != 0)
1153 /* - Seek to that time */
1154 g_debug("SEEK TIME : %lu, %lu", events_request->start_time.tv_sec,
1155 events_request->start_time.tv_nsec);
1156 //lttv_process_traceset_seek_time(tsc, events_request->start_time);
1157 lttv_state_traceset_seek_time_closest(LTTV_TRACESET_STATE(tsc),
1158 events_request->start_time);
1159
1160 /* Process the traceset with only state hooks */
1161 seek_count =
1162 lttv_process_traceset_middle(tsc,
1163 events_request->start_time,
1164 G_MAXUINT, NULL);
6ea08962 1165
a43d67ba 1166
3bafb436 1167 } else {
1168 LttTime pos_time;
1169 /* Else, the first request in list_in is a position request */
1170 /* If first req in list_in pos != current pos */
1171 g_assert(events_request->start_position != NULL);
1172 g_debug("SEEK POS time : %lu, %lu",
1173 lttv_traceset_context_position_get_time(
1174 events_request->start_position).tv_sec,
1175 lttv_traceset_context_position_get_time(
1176 events_request->start_position).tv_nsec);
1177
1178 g_debug("SEEK POS context time : %lu, %lu",
1179 lttv_traceset_context_get_current_tfc(tsc)->timestamp.tv_sec,
1180 lttv_traceset_context_get_current_tfc(tsc)->timestamp.tv_nsec);
1181 g_assert(events_request->start_position != NULL);
1182 if(lttv_traceset_context_ctx_pos_compare(tsc,
1183 events_request->start_position) != 0) {
1184 /* 1.2.2.1 Seek to that position */
1185 g_debug("SEEK POSITION");
1186 //lttv_process_traceset_seek_position(tsc, events_request->start_position);
1187 pos_time = lttv_traceset_context_position_get_time(
1188 events_request->start_position);
1189
1190 lttv_state_traceset_seek_time_closest(LTTV_TRACESET_STATE(tsc),
1191 pos_time);
1192
1193 /* Process the traceset with only state hooks */
1194 seek_count =
1195 lttv_process_traceset_middle(tsc,
1196 ltt_time_infinite,
1197 G_MAXUINT,
1198 events_request->start_position);
1199 g_assert(lttv_traceset_context_ctx_pos_compare(tsc,
1200 events_request->start_position) == 0);
dd316a11 1201
dd316a11 1202
3bafb436 1203 }
1204 }
1205 }
2d262115 1206
3bafb436 1207 /* 1.3 Add hooks and call before request for all list_in members */
1208 {
1209 GSList *iter = NULL;
dd316a11 1210
3bafb436 1211 for(iter=list_in;iter!=NULL;iter=g_slist_next(iter)) {
1212 EventsRequest *events_request = (EventsRequest*)iter->data;
1213 /* 1.3.1 If !servicing */
2d262115 1214 if(events_request->servicing == FALSE) {
1215 /* - begin request hooks called
1216 * - servicing = TRUE
1217 */
6ea08962 1218 lttv_hooks_call(events_request->before_request, (gpointer)tsc);
2d262115 1219 events_request->servicing = TRUE;
1220 }
3bafb436 1221 /* 1.3.2 call before chunk
1222 * 1.3.3 events hooks added
2d262115 1223 */
54d8f654 1224 if(events_request->trace == -1)
1225 lttv_process_traceset_begin(tsc,
1226 events_request->before_chunk_traceset,
1227 events_request->before_chunk_trace,
1228 events_request->before_chunk_tracefile,
1229 events_request->event,
1230 events_request->event_by_id);
1231 else {
1232 guint nb_trace = lttv_traceset_number(tsc->ts);
2eef04b5 1233 g_assert((guint)events_request->trace < nb_trace &&
54d8f654 1234 events_request->trace > -1);
1235 LttvTraceContext *tc = tsc->traces[events_request->trace];
1236
1237 lttv_hooks_call(events_request->before_chunk_traceset, tsc);
1238
1239 lttv_trace_context_add_hooks(tc,
1240 events_request->before_chunk_trace,
1241 events_request->before_chunk_tracefile,
1242 events_request->event,
1243 events_request->event_by_id);
1244 }
501e4e70 1245 }
3bafb436 1246 }
1247 } else {
1248 /* 2. Else, list_in is not empty, we continue a read */
1249
1250 {
1251 /* 2.0 For each req of list_in */
1252 GSList *iter = list_in;
1253
1254 while(iter != NULL) {
2d262115 1255
3bafb436 1256 EventsRequest *events_request = (EventsRequest *)iter->data;
1257
1258 /* - Call before chunk
1259 * - events hooks added
1260 */
54d8f654 1261 if(events_request->trace == -1)
1262 lttv_process_traceset_begin(tsc,
1263 events_request->before_chunk_traceset,
1264 events_request->before_chunk_trace,
1265 events_request->before_chunk_tracefile,
1266 events_request->event,
1267 events_request->event_by_id);
1268 else {
1269 guint nb_trace = lttv_traceset_number(tsc->ts);
2eef04b5 1270 g_assert((guint)events_request->trace < nb_trace &&
54d8f654 1271 events_request->trace > -1);
1272 LttvTraceContext *tc = tsc->traces[events_request->trace];
1273
1274 lttv_hooks_call(events_request->before_chunk_traceset, tsc);
1275
1276 lttv_trace_context_add_hooks(tc,
3bafb436 1277 events_request->before_chunk_trace,
1278 events_request->before_chunk_tracefile,
1279 events_request->event,
1280 events_request->event_by_id);
54d8f654 1281 }
6ea08962 1282
1283 iter = g_slist_next(iter);
1284 }
1285 }
1286
3bafb436 1287 {
1288 tfc = lttv_traceset_context_get_current_tfc(tsc);
1289
1290 /* 2.1 For each req of list_out */
1291 GSList *iter = list_out;
553d1e7b 1292
3bafb436 1293 while(iter != NULL) {
6ea08962 1294
3bafb436 1295 gboolean remove = FALSE;
1296 gboolean free_data = FALSE;
1297 EventsRequest *events_request = (EventsRequest *)iter->data;
1298
1299 /* if req.start time == current context time
1300 * or req.start position == current position*/
1301 if( ltt_time_compare(events_request->start_time,
1302 tfc->timestamp) == 0
1303 ||
1304 (events_request->start_position != NULL
1305 &&
1306 lttv_traceset_context_ctx_pos_compare(tsc,
1307 events_request->start_position) == 0)
1308 ) {
1309 /* - Add to list_in, remove from list_out */
1310 list_in = g_slist_append(list_in, events_request);
1311 remove = TRUE;
1312 free_data = FALSE;
1313
1314 /* - If !servicing */
1315 if(events_request->servicing == FALSE) {
1316 /* - begin request hooks called
1317 * - servicing = TRUE
1318 */
1319 lttv_hooks_call(events_request->before_request, (gpointer)tsc);
1320 events_request->servicing = TRUE;
1321 }
1322 /* call before chunk
1323 * events hooks added
1324 */
54d8f654 1325 if(events_request->trace == -1)
1326 lttv_process_traceset_begin(tsc,
1327 events_request->before_chunk_traceset,
1328 events_request->before_chunk_trace,
1329 events_request->before_chunk_tracefile,
1330 events_request->event,
1331 events_request->event_by_id);
1332 else {
1333 guint nb_trace = lttv_traceset_number(tsc->ts);
2eef04b5 1334 g_assert((guint)events_request->trace < nb_trace &&
54d8f654 1335 events_request->trace > -1);
1336 LttvTraceContext *tc = tsc->traces[events_request->trace];
1337
1338 lttv_hooks_call(events_request->before_chunk_traceset, tsc);
1339
1340 lttv_trace_context_add_hooks(tc,
1341 events_request->before_chunk_trace,
1342 events_request->before_chunk_tracefile,
1343 events_request->event,
1344 events_request->event_by_id);
1345 }
1346
1347
3bafb436 1348 }
501e4e70 1349
3bafb436 1350 /* Go to next */
1351 if(remove)
1352 {
1353 GSList *remove_iter = iter;
2d262115 1354
3bafb436 1355 iter = g_slist_next(iter);
1356 if(free_data) events_request_free((EventsRequest*)remove_iter->data);
1357 list_out = g_slist_remove_link(list_out, remove_iter);
1358 } else { // not remove
1359 iter = g_slist_next(iter);
1360 }
1361 }
1362 }
1363 }
8f2872f4 1364
3bafb436 1365 /* 3. Find end criterions */
1366 {
1367 /* 3.1 End time */
1368 GSList *iter;
1369
1370 /* 3.1.1 Find lowest end time in list_in */
1371 g_assert(g_slist_length(list_in)>0);
1372 end_time = ((EventsRequest*)g_slist_nth_data(list_in,0))->end_time;
1373
1374 for(iter=g_slist_nth(list_in,1);iter!=NULL;iter=g_slist_next(iter)) {
1375 EventsRequest *events_request = (EventsRequest*)iter->data;
501e4e70 1376
3bafb436 1377 if(ltt_time_compare(events_request->end_time,
1378 end_time) < 0)
1379 end_time = events_request->end_time;
1380 }
1381
1382 /* 3.1.2 Find lowest start time in list_out */
1383 for(iter=list_out;iter!=NULL;iter=g_slist_next(iter)) {
1384 EventsRequest *events_request = (EventsRequest*)iter->data;
2d262115 1385
3bafb436 1386 if(ltt_time_compare(events_request->start_time,
1387 end_time) < 0)
1388 end_time = events_request->start_time;
1389 }
501e4e70 1390 }
1391
3bafb436 1392 {
1393 /* 3.2 Number of events */
dd316a11 1394
3bafb436 1395 /* 3.2.1 Find lowest number of events in list_in */
1396 GSList *iter;
501e4e70 1397
3bafb436 1398 end_nb_events = ((EventsRequest*)g_slist_nth_data(list_in,0))->num_events;
501e4e70 1399
3bafb436 1400 for(iter=g_slist_nth(list_in,1);iter!=NULL;iter=g_slist_next(iter)) {
1401 EventsRequest *events_request = (EventsRequest*)iter->data;
501e4e70 1402
3bafb436 1403 if(events_request->num_events < end_nb_events)
1404 end_nb_events = events_request->num_events;
1405 }
501e4e70 1406
3bafb436 1407 /* 3.2.2 Use min(CHUNK_NUM_EVENTS, min num events in list_in) as
1408 * num_events */
1409
1410 end_nb_events = MIN(CHUNK_NUM_EVENTS, end_nb_events);
501e4e70 1411 }
501e4e70 1412
3bafb436 1413 {
1414 /* 3.3 End position */
501e4e70 1415
3bafb436 1416 /* 3.3.1 Find lowest end position in list_in */
1417 GSList *iter;
6ea08962 1418
3bafb436 1419 end_position =((EventsRequest*)g_slist_nth_data(list_in,0))->end_position;
6ea08962 1420
3bafb436 1421 for(iter=g_slist_nth(list_in,1);iter!=NULL;iter=g_slist_next(iter)) {
1422 EventsRequest *events_request = (EventsRequest*)iter->data;
dd316a11 1423
3bafb436 1424 if(events_request->end_position != NULL && end_position != NULL &&
1425 lttv_traceset_context_pos_pos_compare(events_request->end_position,
1426 end_position) <0)
1427 end_position = events_request->end_position;
1428 }
1429 }
1430
1431 {
1432 /* 3.3.2 Find lowest start position in list_out */
1433 GSList *iter;
dd316a11 1434
3bafb436 1435 for(iter=list_out;iter!=NULL;iter=g_slist_next(iter)) {
1436 EventsRequest *events_request = (EventsRequest*)iter->data;
dd316a11 1437
3bafb436 1438 if(events_request->end_position != NULL && end_position != NULL &&
1439 lttv_traceset_context_pos_pos_compare(events_request->end_position,
1440 end_position) <0)
1441 end_position = events_request->end_position;
dd316a11 1442 }
2d262115 1443 }
3bafb436 1444
2d262115 1445 {
3bafb436 1446 /* 4. Call process traceset middle */
2eef04b5 1447 g_debug("Calling process traceset middle with %p, %lu sec %lu nsec, %u nb ev, %p end pos", tsc, end_time.tv_sec, end_time.tv_nsec, end_nb_events, end_position);
3bafb436 1448 count = lttv_process_traceset_middle(tsc, end_time, end_nb_events, end_position);
2d262115 1449
3bafb436 1450 tfc = lttv_traceset_context_get_current_tfc(tsc);
1451 if(tfc != NULL)
1452 g_debug("Context time after middle : %lu, %lu", tfc->timestamp.tv_sec,
1453 tfc->timestamp.tv_nsec);
1454 else
1455 g_debug("End of trace reached after middle.");
2d262115 1456
3bafb436 1457 }
1458 {
1459 /* 5. After process traceset middle */
1460 tfc = lttv_traceset_context_get_current_tfc(tsc);
1461
1462 /* - if current context time > traceset.end time */
1463 if(tfc == NULL || ltt_time_compare(tfc->timestamp,
1464 tsc->time_span.end_time) > 0) {
1465 /* - For each req in list_in */
1466 GSList *iter = list_in;
1467
1468 while(iter != NULL) {
1469
1470 gboolean remove = FALSE;
1471 gboolean free_data = FALSE;
1472 EventsRequest *events_request = (EventsRequest *)iter->data;
1473
1474 /* - Remove events hooks for req
1475 * - Call end chunk for req
1476 */
54d8f654 1477
1478 if(events_request->trace == -1)
1479 lttv_process_traceset_end(tsc,
1480 events_request->after_chunk_traceset,
3bafb436 1481 events_request->after_chunk_trace,
1482 events_request->after_chunk_tracefile,
1483 events_request->event,
1484 events_request->event_by_id);
54d8f654 1485
1486 else {
1487 guint nb_trace = lttv_traceset_number(tsc->ts);
1488 g_assert(events_request->trace < nb_trace &&
1489 events_request->trace > -1);
1490 LttvTraceContext *tc = tsc->traces[events_request->trace];
1491
1492 lttv_trace_context_remove_hooks(tc,
1493 events_request->after_chunk_trace,
1494 events_request->after_chunk_tracefile,
1495 events_request->event,
1496 events_request->event_by_id);
1497 lttv_hooks_call(events_request->after_chunk_traceset, tsc);
1498
1499
1500 }
1501
3bafb436 1502 /* - Call end request for req */
6ea08962 1503 lttv_hooks_call(events_request->after_request, (gpointer)tsc);
3bafb436 1504
2d262115 1505 /* - remove req from list_in */
1506 /* Destroy the request */
1507 remove = TRUE;
1508 free_data = TRUE;
3bafb436 1509
1510 /* Go to next */
1511 if(remove)
1512 {
1513 GSList *remove_iter = iter;
1514
1515 iter = g_slist_next(iter);
1516 if(free_data) events_request_free((EventsRequest*)remove_iter->data);
1517 list_in = g_slist_remove_link(list_in, remove_iter);
1518 } else { // not remove
1519 iter = g_slist_next(iter);
1520 }
2d262115 1521 }
3bafb436 1522 }
1523 {
1524 /* 5.1 For each req in list_in */
1525 GSList *iter = list_in;
1526
1527 while(iter != NULL) {
501e4e70 1528
3bafb436 1529 gboolean remove = FALSE;
1530 gboolean free_data = FALSE;
1531 EventsRequest *events_request = (EventsRequest *)iter->data;
1532
1533 /* - Remove events hooks for req
1534 * - Call end chunk for req
1535 */
54d8f654 1536 if(events_request->trace == -1)
1537 lttv_process_traceset_end(tsc,
1538 events_request->after_chunk_traceset,
3bafb436 1539 events_request->after_chunk_trace,
1540 events_request->after_chunk_tracefile,
1541 events_request->event,
1542 events_request->event_by_id);
1543
54d8f654 1544 else {
1545 guint nb_trace = lttv_traceset_number(tsc->ts);
1546 g_assert(events_request->trace < nb_trace &&
1547 events_request->trace > -1);
1548 LttvTraceContext *tc = tsc->traces[events_request->trace];
1549
1550 lttv_trace_context_remove_hooks(tc,
1551 events_request->after_chunk_trace,
1552 events_request->after_chunk_tracefile,
1553 events_request->event,
1554 events_request->event_by_id);
1555
1556 lttv_hooks_call(events_request->after_chunk_traceset, tsc);
1557 }
1558
3bafb436 1559 /* - req.num -= count */
1560 g_assert(events_request->num_events >= count);
1561 events_request->num_events -= count;
1562
1563 g_assert(tfc != NULL);
1564 /* - if req.num == 0
1565 * or
1566 * current context time >= req.end time
1567 * or
1568 * req.end pos == current pos
1569 * or
1570 * req.stop_flag == TRUE
1571 */
1572 if( events_request->num_events == 0
1573 ||
1574 events_request->stop_flag == TRUE
1575 ||
1576 ltt_time_compare(tfc->timestamp,
1577 events_request->end_time) >= 0
1578 ||
1579 (events_request->end_position != NULL
1580 &&
1581 lttv_traceset_context_ctx_pos_compare(tsc,
1582 events_request->end_position) == 0)
1583
1584 ) {
1585 g_assert(events_request->servicing == TRUE);
1586 /* - Call end request for req
1587 * - remove req from list_in */
1588 lttv_hooks_call(events_request->after_request, (gpointer)tsc);
1589 /* - remove req from list_in */
1590 /* Destroy the request */
1591 remove = TRUE;
1592 free_data = TRUE;
1593 }
1594
1595 /* Go to next */
1596 if(remove)
1597 {
1598 GSList *remove_iter = iter;
1599
1600 iter = g_slist_next(iter);
1601 if(free_data) events_request_free((EventsRequest*)remove_iter->data);
1602 list_in = g_slist_remove_link(list_in, remove_iter);
1603 } else { // not remove
1604 iter = g_slist_next(iter);
1605 }
2d262115 1606 }
1607 }
1608 }
501e4e70 1609 }
dd316a11 1610 /* End of removed servicing loop : leave control to GTK instead. */
1611 // if(gtk_events_pending()) break;
1612 //}
1613
2d262115 1614 /* B. When interrupted between chunks */
501e4e70 1615
501e4e70 1616 {
1617 GSList *iter = list_in;
1618
2d262115 1619 /* 1. for each request in list_in */
501e4e70 1620 while(iter != NULL) {
1621
1622 gboolean remove = FALSE;
1623 gboolean free_data = FALSE;
2d262115 1624 EventsRequest *events_request = (EventsRequest *)iter->data;
501e4e70 1625
1626 /* 1.1. Use current postition as start position */
a1a2b649 1627 if(events_request->start_position != NULL)
1628 lttv_traceset_context_position_destroy(events_request->start_position);
b052368a 1629 events_request->start_position = lttv_traceset_context_position_new();
501e4e70 1630 lttv_traceset_context_position_save(tsc, events_request->start_position);
1631
1632 /* 1.2. Remove start time */
0aa6c3a1 1633 events_request->start_time = ltt_time_infinite;
501e4e70 1634
2d262115 1635 /* 1.3. Move from list_in to list_out */
501e4e70 1636 remove = TRUE;
1637 free_data = FALSE;
1638 list_out = g_slist_append(list_out, events_request);
1639
501e4e70 1640 /* Go to next */
1641 if(remove)
8f2872f4 1642 {
501e4e70 1643 GSList *remove_iter = iter;
1644
1645 iter = g_slist_next(iter);
b052368a 1646 if(free_data) events_request_free((EventsRequest*)remove_iter->data);
501e4e70 1647 list_in = g_slist_remove_link(list_in, remove_iter);
1648 } else { // not remove
1649 iter = g_slist_next(iter);
8f2872f4 1650 }
1651 }
a43d67ba 1652
501e4e70 1653
1654 }
b052368a 1655
1656 /* C Unlock Traces */
1657 {
1658 //lttv_process_traceset_get_sync_data(tsc);
1659
1660 guint iter_trace;
1661
1662 for(iter_trace=0;
1663 iter_trace<lttv_traceset_number(tsc->ts);
1664 iter_trace++) {
1665 LttvTrace *trace_v = lttv_traceset_get(tsc->ts, iter_trace);
1666
1667 lttvwindowtraces_unlock(trace_v);
1668 }
1669 }
501e4e70 1670
a0577796 1671#if 0
abe346a3 1672 //set the cursor back to normal
a8c0f09d 1673 gdk_window_set_cursor(win, NULL);
a0577796 1674#endif //0
501e4e70 1675
2d262115 1676 g_assert(g_slist_length(list_in) == 0);
6ea08962 1677
2d262115 1678 if( g_slist_length(list_out) == 0 ) {
501e4e70 1679 /* Put tab's request pending flag back to normal */
2d262115 1680 tab->events_request_pending = FALSE;
b052368a 1681 g_debug("remove the idle fct");
501e4e70 1682 return FALSE; /* Remove the idle function */
1683 }
b052368a 1684 g_debug("leave the idle fct");
501e4e70 1685 return TRUE; /* Leave the idle function */
b052368a 1686
1687 /* We do not use simili-round-robin, it may require to read 1 meg buffers
1688 * again and again if many tracesets use the same tracefiles. */
1689 /* Hack for round-robin idle functions */
1690 /* It will put the idle function at the end of the pool */
1691 /*g_idle_add_full((G_PRIORITY_HIGH_IDLE + 21),
1692 (GSourceFunc)execute_events_requests,
1693 tab,
1694 NULL);
1695 return FALSE;
1696 */
202f6c8f 1697}
1698
6ea08962 1699#undef list_out
501e4e70 1700
abe346a3 1701
1702/* add_trace_into_traceset_selector, each instance of a viewer has an associated
1703 * selector (filter), when a trace is added into traceset, the selector should
1704 * reflect the change. The function is used to update the selector
1705 */
b052368a 1706#if 0
1707void add_trace_into_traceset_selector(GtkWidget * paned, LttTrace * t)
49bf71b5 1708{
ed3b99b6 1709 int j, k, m, nb_tracefile, nb_control, nb_per_cpu, nb_facility, nb_event;
49bf71b5 1710 LttvTracesetSelector * s;
1711 LttvTraceSelector * trace;
1712 LttvTracefileSelector * tracefile;
ed3b99b6 1713 LttvEventtypeSelector * eventtype;
49bf71b5 1714 LttTracefile * tf;
1715 GtkWidget * w;
ed3b99b6 1716 LttFacility * fac;
1717 LttEventType * et;
49bf71b5 1718
b052368a 1719 w = gtk_multivpaned_get_first_widget(GTK_MULTIVPANED(paned));
49bf71b5 1720 while(w){
1721 s = g_object_get_data(G_OBJECT(w), "Traceset_Selector");
49bf71b5 1722
abe346a3 1723 if(s){
1724 trace = lttv_trace_selector_new(t);
1725 lttv_traceset_selector_trace_add(s, trace);
1726
1727 nb_facility = ltt_trace_facility_number(t);
1728 for(k=0;k<nb_facility;k++){
1729 fac = ltt_trace_facility_get(t,k);
1730 nb_event = (int) ltt_facility_eventtype_number(fac);
1731 for(m=0;m<nb_event;m++){
1732 et = ltt_facility_eventtype_get(fac,m);
1733 eventtype = lttv_eventtype_selector_new(et);
1734 lttv_trace_selector_eventtype_add(trace, eventtype);
1735 }
1736 }
1737
1738 nb_control = ltt_trace_control_tracefile_number(t);
1739 nb_per_cpu = ltt_trace_per_cpu_tracefile_number(t);
1740 nb_tracefile = nb_control + nb_per_cpu;
1741
1742 for(j = 0 ; j < nb_tracefile ; j++) {
1743 if(j < nb_control)
1744 tf = ltt_trace_control_tracefile_get(t, j);
1745 else
1746 tf = ltt_trace_per_cpu_tracefile_get(t, j - nb_control);
1747 tracefile = lttv_tracefile_selector_new(tf);
1748 lttv_trace_selector_tracefile_add(trace, tracefile);
1749 lttv_eventtype_selector_copy(trace, tracefile);
1750 }
1751 }else g_warning("Module does not support filtering\n");
49bf71b5 1752
b052368a 1753 w = gtk_multivpaned_get_next_widget(GTK_MULTIVPANED(paned));
49bf71b5 1754 }
1755}
b052368a 1756#endif //0
abe346a3 1757
4266dc7f 1758static void lttvwindow_add_trace(Tab *tab, LttvTrace *trace_v)
1759{
1760 LttvTraceset *traceset = tab->traceset_info->traceset;
1761 guint i;
91fd6881 1762 guint num_traces = lttv_traceset_number(traceset);
4266dc7f 1763
a1a2b649 1764 //Verify if trace is already present.
91fd6881 1765 for(i=0; i<num_traces; i++)
a1a2b649 1766 {
1767 LttvTrace * trace = lttv_traceset_get(traceset, i);
1768 if(trace == trace_v)
1769 return;
1770 }
1771
4266dc7f 1772 //Keep a reference to the traces so they are not freed.
1773 for(i=0; i<lttv_traceset_number(traceset); i++)
1774 {
1775 LttvTrace * trace = lttv_traceset_get(traceset, i);
1776 lttv_trace_ref(trace);
1777 }
1778
1779 //remove state update hooks
1780 lttv_state_remove_event_hooks(
1781 (LttvTracesetState*)tab->traceset_info->traceset_context);
1782
1783 lttv_context_fini(LTTV_TRACESET_CONTEXT(
1784 tab->traceset_info->traceset_context));
1785 g_object_unref(tab->traceset_info->traceset_context);
1786
1787 lttv_traceset_add(traceset, trace_v);
a1a2b649 1788 lttv_trace_ref(trace_v); /* local ref */
4266dc7f 1789
1790 /* Create new context */
1791 tab->traceset_info->traceset_context =
1792 g_object_new(LTTV_TRACESET_STATS_TYPE, NULL);
1793 lttv_context_init(
1794 LTTV_TRACESET_CONTEXT(tab->traceset_info->
1795 traceset_context),
1796 traceset);
6ea08962 1797
6ea08962 1798
4266dc7f 1799 //add state update hooks
1800 lttv_state_add_event_hooks(
1801 (LttvTracesetState*)tab->traceset_info->traceset_context);
1802 //Remove local reference to the traces.
1803 for(i=0; i<lttv_traceset_number(traceset); i++)
1804 {
1805 LttvTrace * trace = lttv_traceset_get(traceset, i);
1806 lttv_trace_unref(trace);
1807 }
1808
b052368a 1809 //FIXME
1810 //add_trace_into_traceset_selector(GTK_MULTIVPANED(tab->multivpaned), lttv_trace(trace_v));
4266dc7f 1811}
1812
abe346a3 1813/* add_trace adds a trace into the current traceset. It first displays a
1814 * directory selection dialogue to let user choose a trace, then recreates
1815 * tracset_context, and redraws all the viewer of the current tab
1816 */
1817
561eba2a 1818void add_trace(GtkWidget * widget, gpointer user_data)
1819{
2176f952 1820 LttTrace *trace;
1821 LttvTrace * trace_v;
1822 LttvTraceset * traceset;
94dcfb9e 1823 const char * dir;
a1a2b649 1824 char abs_path[PATH_MAX];
2176f952 1825 gint id;
bca3b81f 1826 MainWindow * mw_data = get_window_data_struct(widget);
6ced96ef 1827 GtkWidget * notebook = lookup_widget(widget, "MNotebook");
1828
1829 GtkWidget *page = gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook),
1830 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook)));
1831 Tab *tab;
1832
1833 if(!page) {
1834 tab = create_new_tab(widget, NULL);
1835 } else {
1836 tab = (Tab *)g_object_get_data(G_OBJECT(page), "Tab_Info");
1837 }
4266dc7f 1838
68b48a45 1839 GtkDirSelection * file_selector = (GtkDirSelection *)gtk_dir_selection_new("Select a trace");
1840 gtk_dir_selection_hide_fileop_buttons(file_selector);
4266dc7f 1841
3658a338 1842 if(remember_trace_dir[0] != '\0')
1843 gtk_dir_selection_set_filename(file_selector, remember_trace_dir);
2176f952 1844
68b48a45 1845 id = gtk_dialog_run(GTK_DIALOG(file_selector));
2176f952 1846 switch(id){
1847 case GTK_RESPONSE_ACCEPT:
1848 case GTK_RESPONSE_OK:
68b48a45 1849 dir = gtk_dir_selection_get_dir (file_selector);
a1a2b649 1850 strncpy(remember_trace_dir, dir, PATH_MAX);
a43d67ba 1851 if(!dir || strlen(dir) == 0){
1852 gtk_widget_destroy((GtkWidget*)file_selector);
1853 break;
284675e3 1854 }
a1a2b649 1855 get_absolute_pathname(dir, abs_path);
1856 trace_v = lttvwindowtraces_get_trace_by_name(abs_path);
1857 if(trace_v == NULL) {
1858 trace = ltt_trace_open(abs_path);
2a74fbf4 1859 if(trace == NULL) {
1860 g_warning("cannot open trace %s", abs_path);
1861 } else {
1862 trace_v = lttv_trace_new(trace);
1863 lttvwindowtraces_add_trace(trace_v);
1864 lttvwindow_add_trace(tab, trace_v);
1865 }
1866 } else {
1867 lttvwindow_add_trace(tab, trace_v);
a1a2b649 1868 }
c2619a30 1869
49bf71b5 1870 gtk_widget_destroy((GtkWidget*)file_selector);
1871
1872 //update current tab
a43d67ba 1873 //update_traceset(mw_data);
21e8c385 1874
a43d67ba 1875 /* Call the updatetraceset hooks */
1876
4266dc7f 1877 traceset = tab->traceset_info->traceset;
1878 SetTraceset(tab, traceset);
a43d67ba 1879 // in expose now call_pending_read_hooks(mw_data);
1880
4266dc7f 1881 //lttvwindow_report_current_time(mw_data,&(tab->current_time));
49bf71b5 1882 break;
2176f952 1883 case GTK_RESPONSE_REJECT:
1884 case GTK_RESPONSE_CANCEL:
1885 default:
68b48a45 1886 gtk_widget_destroy((GtkWidget*)file_selector);
2176f952 1887 break;
1888 }
49bf71b5 1889}
1890
abe346a3 1891
1892/* remove_trace_into_traceset_selector, each instance of a viewer has an associated
1893 * selector (filter), when a trace is remove from traceset, the selector should
1894 * reflect the change. The function is used to update the selector
1895 */
b052368a 1896#if 0
1897void remove_trace_from_traceset_selector(GtkWidget * paned, unsigned i)
49bf71b5 1898{
1899 LttvTracesetSelector * s;
1900 LttvTraceSelector * t;
1901 GtkWidget * w;
1902
b052368a 1903 w = gtk_multivpaned_get_first_widget(GTK_MULTIVPANED(paned));
49bf71b5 1904 while(w){
1905 s = g_object_get_data(G_OBJECT(w), "Traceset_Selector");
abe346a3 1906 if(s){
1907 t = lttv_traceset_selector_trace_get(s,i);
1908 lttv_traceset_selector_trace_remove(s, i);
1909 lttv_trace_selector_destroy(t);
1910 }g_warning("Module dose not support filtering\n");
b052368a 1911 w = gtk_multivpaned_get_next_widget(GTK_MULTIVPANED(paned));
49bf71b5 1912 }
561eba2a 1913}
b052368a 1914#endif //0
abe346a3 1915
1916/* remove_trace removes a trace from the current traceset if all viewers in
1917 * the current tab are not interested in the trace. It first displays a
1918 * dialogue, which shows all traces in the current traceset, to let user choose
1919 * a trace, then it checks if all viewers unselect the trace, if it is true,
1920 * it will remove the trace, recreate the traceset_contex,
1921 * and redraws all the viewer of the current tab. If there is on trace in the
1922 * current traceset, it will delete all viewers of the current tab
1923 */
1924
b052368a 1925// MD : no filter version.
1926void remove_trace(GtkWidget *widget, gpointer user_data)
1927{
1928 LttTrace *trace;
1929 LttvTrace * trace_v;
1930 LttvTraceset * traceset;
1931 gint i, j, nb_trace, index=-1;
1932 char ** name, *remove_trace_name;
1933 MainWindow * mw_data = get_window_data_struct(widget);
1934 GtkWidget * notebook = lookup_widget(widget, "MNotebook");
1935
1936 GtkWidget *page = gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook),
1937 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook)));
1938 Tab *tab;
1939
1940 if(!page) {
1941 return;
1942 } else {
1943 tab = (Tab *)g_object_get_data(G_OBJECT(page), "Tab_Info");
1944 }
1945
1946 nb_trace =lttv_traceset_number(tab->traceset_info->traceset);
1947 name = g_new(char*,nb_trace);
1948 for(i = 0; i < nb_trace; i++){
1949 trace_v = lttv_traceset_get(tab->traceset_info->traceset, i);
1950 trace = lttv_trace(trace_v);
1951 name[i] = ltt_trace_name(trace);
1952 }
1953
1954 remove_trace_name = get_remove_trace(name, nb_trace);
1955
1956
1957 if(remove_trace_name){
1958
1959 /* yuk, cut n paste from old code.. should be better (MD)*/
1960 for(i = 0; i<nb_trace; i++) {
1961 if(strcmp(remove_trace_name,name[i]) == 0){
1962 index = i;
1963 }
1964 }
1965
1966 traceset = tab->traceset_info->traceset;
1967 //Keep a reference to the traces so they are not freed.
1968 for(j=0; j<lttv_traceset_number(traceset); j++)
1969 {
1970 LttvTrace * trace = lttv_traceset_get(traceset, j);
1971 lttv_trace_ref(trace);
1972 }
1973
1974 //remove state update hooks
1975 lttv_state_remove_event_hooks(
1976 (LttvTracesetState*)tab->traceset_info->traceset_context);
1977 lttv_context_fini(LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context));
1978 g_object_unref(tab->traceset_info->traceset_context);
1979
1980 trace_v = lttv_traceset_get(traceset, index);
1981
b052368a 1982 lttv_traceset_remove(traceset, index);
1983 lttv_trace_unref(trace_v); // Remove local reference
1984
1ba187d3 1985 if(lttv_trace_get_ref_number(trace_v) <= 1) {
1986 /* ref 1 : lttvwindowtraces only*/
1987 ltt_trace_close(lttv_trace(trace_v));
1988 /* lttvwindowtraces_remove_trace takes care of destroying
1989 * the traceset linked with the trace_v and also of destroying
1990 * the trace_v at the same time.
1991 */
1992 lttvwindowtraces_remove_trace(trace_v);
1993 }
b052368a 1994
1995 tab->traceset_info->traceset_context =
1996 g_object_new(LTTV_TRACESET_STATS_TYPE, NULL);
1997 lttv_context_init(
1998 LTTV_TRACESET_CONTEXT(tab->
1999 traceset_info->traceset_context),traceset);
2000 //add state update hooks
2001 lttv_state_add_event_hooks(
2002 (LttvTracesetState*)tab->traceset_info->traceset_context);
2003
2004 //Remove local reference to the traces.
2005 for(j=0; j<lttv_traceset_number(traceset); j++)
2006 {
2007 LttvTrace * trace = lttv_traceset_get(traceset, j);
2008 lttv_trace_unref(trace);
2009 }
2010
2011 SetTraceset(tab, (gpointer)traceset);
2012 }
2013 g_free(name);
2014}
2015
2016#if 0
561eba2a 2017void remove_trace(GtkWidget * widget, gpointer user_data)
2018{
2176f952 2019 LttTrace *trace;
2020 LttvTrace * trace_v;
2021 LttvTraceset * traceset;
a43d67ba 2022 gint i, j, nb_trace;
2176f952 2023 char ** name, *remove_trace_name;
bca3b81f 2024 MainWindow * mw_data = get_window_data_struct(widget);
49bf71b5 2025 LttvTracesetSelector * s;
2026 LttvTraceSelector * t;
2027 GtkWidget * w;
2028 gboolean selected;
6ced96ef 2029 GtkWidget * notebook = lookup_widget(widget, "MNotebook");
2030
2031 GtkWidget *page = gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook),
2032 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook)));
2033 Tab *tab;
2034
2035 if(!page) {
2036 return;
2037 } else {
2038 tab = (Tab *)g_object_get_data(G_OBJECT(page), "Tab_Info");
2039 }
2040
4266dc7f 2041 nb_trace =lttv_traceset_number(tab->traceset_info->traceset);
2176f952 2042 name = g_new(char*,nb_trace);
2043 for(i = 0; i < nb_trace; i++){
4266dc7f 2044 trace_v = lttv_traceset_get(tab->traceset_info->traceset, i);
2176f952 2045 trace = lttv_trace(trace_v);
a5dcde2f 2046 name[i] = ltt_trace_name(trace);
2176f952 2047 }
2048
2049 remove_trace_name = get_remove_trace(name, nb_trace);
2050
2051 if(remove_trace_name){
2052 for(i=0; i<nb_trace; i++){
2053 if(strcmp(remove_trace_name,name[i]) == 0){
6ced96ef 2054 //unselect the trace from the current viewer
b052368a 2055 //FIXME
2056 w = gtk_multivpaned_get_widget(GTK_MULTIVPANED(tab->multivpaned));
6ced96ef 2057 if(w){
2058 s = g_object_get_data(G_OBJECT(w), "Traceset_Selector");
2059 if(s){
2060 t = lttv_traceset_selector_trace_get(s,i);
2061 lttv_trace_selector_set_selected(t, FALSE);
2062 }
2063
2064 //check if other viewers select the trace
b052368a 2065 w = gtk_multivpaned_get_first_widget(GTK_MULTIVPANED(tab->multivpaned));
6ced96ef 2066 while(w){
2067 s = g_object_get_data(G_OBJECT(w), "Traceset_Selector");
2068 if(s){
2069 t = lttv_traceset_selector_trace_get(s,i);
2070 selected = lttv_trace_selector_get_selected(t);
2071 if(selected)break;
2072 }
b052368a 2073 w = gtk_multivpaned_get_next_widget(GTK_MULTIVPANED(tab->multivpaned));
6ced96ef 2074 }
2075 }else selected = FALSE;
49bf71b5 2076
6ced96ef 2077 //if no viewer selects the trace, remove it
2078 if(!selected){
b052368a 2079 remove_trace_from_traceset_selector(GTK_MULTIVPANED(tab->multivpaned), i);
49bf71b5 2080
6ced96ef 2081 traceset = tab->traceset_info->traceset;
2082 //Keep a reference to the traces so they are not freed.
2083 for(j=0; j<lttv_traceset_number(traceset); j++)
2084 {
2085 LttvTrace * trace = lttv_traceset_get(traceset, j);
2086 lttv_trace_ref(trace);
2087 }
a43d67ba 2088
6ced96ef 2089 //remove state update hooks
2090 lttv_state_remove_event_hooks(
2091 (LttvTracesetState*)tab->traceset_info->traceset_context);
2092 lttv_context_fini(LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context));
2093 g_object_unref(tab->traceset_info->traceset_context);
a43d67ba 2094
a43d67ba 2095
6ced96ef 2096 trace_v = lttv_traceset_get(traceset, i);
a43d67ba 2097
a1a2b649 2098 if(lttv_trace_get_ref_number(trace_v) <= 2) {
2099 /* ref 2 : traceset, local */
2100 lttvwindowtraces_remove_trace(trace_v);
6ced96ef 2101 ltt_trace_close(lttv_trace(trace_v));
a1a2b649 2102 }
6ced96ef 2103
2104 lttv_traceset_remove(traceset, i);
2105 lttv_trace_unref(trace_v); // Remove local reference
c2619a30 2106
6ced96ef 2107 if(!lttv_trace_get_ref_number(trace_v))
2108 lttv_trace_destroy(trace_v);
2109
2110 tab->traceset_info->traceset_context =
2111 g_object_new(LTTV_TRACESET_STATS_TYPE, NULL);
2112 lttv_context_init(
2113 LTTV_TRACESET_CONTEXT(tab->
2114 traceset_info->traceset_context),traceset);
2115 //add state update hooks
2116 lttv_state_add_event_hooks(
2117 (LttvTracesetState*)tab->traceset_info->traceset_context);
2118
2119 //Remove local reference to the traces.
2120 for(j=0; j<lttv_traceset_number(traceset); j++)
2121 {
2122 LttvTrace * trace = lttv_traceset_get(traceset, j);
2123 lttv_trace_unref(trace);
2124 }
a43d67ba 2125
a43d67ba 2126
6ced96ef 2127 //update current tab
2128 //update_traceset(mw_data);
313bd6fc 2129 //if(nb_trace > 1){
6ced96ef 2130
313bd6fc 2131 SetTraceset(tab, (gpointer)traceset);
6ced96ef 2132 // in expose now call_pending_read_hooks(mw_data);
2133
2134 //lttvwindow_report_current_time(mw_data,&(tab->current_time));
313bd6fc 2135 //}else{
2136 // if(tab){
2137 // while(tab->multi_vpaned->num_children){
2138 // gtk_multi_vpaned_widget_delete(tab->multi_vpaned);
2139 // }
2140 // }
2141 //}
6ced96ef 2142 }
2143 break;
2176f952 2144 }
2145 }
2146 }
2147
2148 g_free(name);
561eba2a 2149}
b052368a 2150#endif //0
abe346a3 2151
9878c8a4 2152/* Redraw all the viewers in the current tab */
2153void redraw(GtkWidget *widget, gpointer user_data)
2154{
2155 GtkWidget * notebook = lookup_widget(widget, "MNotebook");
2156 GtkWidget *page = gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook),
2157 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook)));
2158 Tab *tab;
2159 if(!page) {
2160 return;
2161 } else {
2162 tab = (Tab *)g_object_get_data(G_OBJECT(page), "Tab_Info");
2163 }
2164
2165 LttvHooks * tmp;
2166 LttvAttributeValue value;
2167
2168 g_assert(lttv_iattribute_find_by_path(tab->attributes, "hooks/redraw", LTTV_POINTER, &value));
2169
2170 tmp = (LttvHooks*)*(value.v_pointer);
c07e9b26 2171 if(tmp != NULL)
2172 lttv_hooks_call(tmp,NULL);
9878c8a4 2173}
2174
2175
2176void continue_processing(GtkWidget *widget, gpointer user_data)
2177{
2178 GtkWidget * notebook = lookup_widget(widget, "MNotebook");
2179 GtkWidget *page = gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook),
2180 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook)));
2181 Tab *tab;
2182 if(!page) {
2183 return;
2184 } else {
2185 tab = (Tab *)g_object_get_data(G_OBJECT(page), "Tab_Info");
2186 }
2187
2188 LttvHooks * tmp;
2189 LttvAttributeValue value;
2190
2191 g_assert(lttv_iattribute_find_by_path(tab->attributes,
2192 "hooks/continue", LTTV_POINTER, &value));
2193
2194 tmp = (LttvHooks*)*(value.v_pointer);
c07e9b26 2195 if(tmp != NULL)
2196 lttv_hooks_call(tmp,NULL);
9878c8a4 2197}
2198
2199/* Stop the processing for the calling main window's current tab.
2200 * It removes every processing requests that are in its list. It does not call
2201 * the end request hooks, because the request is not finished.
2202 */
2203
2204void stop_processing(GtkWidget *widget, gpointer user_data)
2205{
2206 GtkWidget * notebook = lookup_widget(widget, "MNotebook");
2207 GtkWidget *page = gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook),
2208 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook)));
2209 Tab *tab;
2210 if(!page) {
2211 return;
2212 } else {
2213 tab = (Tab *)g_object_get_data(G_OBJECT(page), "Tab_Info");
2214 }
a0577796 2215 GSList *iter = tab->events_requests;
9878c8a4 2216
2217 while(iter != NULL) {
2218 GSList *remove_iter = iter;
2219 iter = g_slist_next(iter);
2220
2221 g_free(remove_iter->data);
a0577796 2222 tab->events_requests =
2223 g_slist_remove_link(tab->events_requests, remove_iter);
9878c8a4 2224 }
a0577796 2225 tab->events_request_pending = FALSE;
2226 g_idle_remove_by_data(tab);
2227 g_assert(g_slist_length(tab->events_requests) == 0);
9878c8a4 2228}
2229
2230
abe346a3 2231/* save will save the traceset to a file
a43d67ba 2232 * Not implemented yet FIXME
abe346a3 2233 */
2234
561eba2a 2235void save(GtkWidget * widget, gpointer user_data)
2236{
56e5a0f7 2237 g_info("Save\n");
561eba2a 2238}
2239
2240void save_as(GtkWidget * widget, gpointer user_data)
2241{
56e5a0f7 2242 g_info("Save as\n");
561eba2a 2243}
2244
abe346a3 2245
2246/* zoom will change the time_window of all the viewers of the
2247 * current tab, and redisplay them. The main functionality is to
2248 * determine the new time_window of the current tab
2249 */
2250
1f1ae829 2251void zoom(GtkWidget * widget, double size)
2252{
b052368a 2253 TimeInterval time_span;
a43d67ba 2254 TimeWindow new_time_window;
2eef04b5 2255 LttTime current_time, time_delta;
1f1ae829 2256 MainWindow * mw_data = get_window_data_struct(widget);
4266dc7f 2257 LttvTracesetContext *tsc;
6ced96ef 2258 GtkWidget * notebook = lookup_widget(widget, "MNotebook");
2259
2260 GtkWidget *page = gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook),
2261 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook)));
2262 Tab *tab;
2263
2264 if(!page) {
2265 return;
2266 } else {
2267 tab = (Tab *)g_object_get_data(G_OBJECT(page), "Tab_Info");
2268 }
1f1ae829 2269
fda16332 2270 if(size == 1) return;
2271
4266dc7f 2272 tsc = LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context);
b052368a 2273 time_span = tsc->time_span;
501e4e70 2274 new_time_window = tab->time_window;
2275 current_time = tab->current_time;
1f1ae829 2276
b052368a 2277 time_delta = ltt_time_sub(time_span.end_time,time_span.start_time);
1f1ae829 2278 if(size == 0){
b052368a 2279 new_time_window.start_time = time_span.start_time;
a43d67ba 2280 new_time_window.time_width = time_delta;
a18124ff 2281 new_time_window.time_width_double = ltt_time_to_double(time_delta);
6f26fc38 2282 new_time_window.end_time = ltt_time_add(new_time_window.start_time,
2283 new_time_window.time_width) ;
1f1ae829 2284 }else{
a43d67ba 2285 new_time_window.time_width = ltt_time_div(new_time_window.time_width, size);
a18124ff 2286 new_time_window.time_width_double =
2287 ltt_time_to_double(new_time_window.time_width);
a43d67ba 2288 if(ltt_time_compare(new_time_window.time_width,time_delta) > 0)
2289 { /* Case where zoom out is bigger than trace length */
b052368a 2290 new_time_window.start_time = time_span.start_time;
a43d67ba 2291 new_time_window.time_width = time_delta;
a18124ff 2292 new_time_window.time_width_double = ltt_time_to_double(time_delta);
6f26fc38 2293 new_time_window.end_time = ltt_time_add(new_time_window.start_time,
2294 new_time_window.time_width) ;
a8c0f09d 2295 }
a43d67ba 2296 else
2297 {
2298 /* Center the image on the current time */
a43d67ba 2299 new_time_window.start_time =
a18124ff 2300 ltt_time_sub(current_time,
2301 ltt_time_from_double(new_time_window.time_width_double/2.0));
6f26fc38 2302 new_time_window.end_time = ltt_time_add(new_time_window.start_time,
2303 new_time_window.time_width) ;
a43d67ba 2304 /* If on borders, don't fall off */
b052368a 2305 if(ltt_time_compare(new_time_window.start_time, time_span.start_time) <0)
a43d67ba 2306 {
b052368a 2307 new_time_window.start_time = time_span.start_time;
6f26fc38 2308 new_time_window.end_time = ltt_time_add(new_time_window.start_time,
2309 new_time_window.time_width) ;
a43d67ba 2310 }
2311 else
2312 {
6f26fc38 2313 if(ltt_time_compare(new_time_window.end_time,
2314 time_span.end_time) > 0)
a43d67ba 2315 {
2316 new_time_window.start_time =
b052368a 2317 ltt_time_sub(time_span.end_time, new_time_window.time_width);
6f26fc38 2318
2319 new_time_window.end_time = ltt_time_add(new_time_window.start_time,
2320 new_time_window.time_width) ;
a43d67ba 2321 }
2322 }
2323
1f1ae829 2324 }
1f1ae829 2325 }
a43d67ba 2326
f02b5e22 2327 if(ltt_time_compare(new_time_window.time_width, ltt_time_zero) == 0) {
2328 g_warning("Zoom more than 1 ns impossible");
b052368a 2329 } else {
e800cf84 2330 time_change_manager(tab, new_time_window);
b052368a 2331 }
1f1ae829 2332}
2333
561eba2a 2334void zoom_in(GtkWidget * widget, gpointer user_data)
2335{
1f1ae829 2336 zoom(widget, 2);
561eba2a 2337}
2338
2339void zoom_out(GtkWidget * widget, gpointer user_data)
2340{
1f1ae829 2341 zoom(widget, 0.5);
561eba2a 2342}
2343
2344void zoom_extended(GtkWidget * widget, gpointer user_data)
2345{
1f1ae829 2346 zoom(widget, 0);
561eba2a 2347}
2348
2349void go_to_time(GtkWidget * widget, gpointer user_data)
2350{
56e5a0f7 2351 g_info("Go to time\n");
561eba2a 2352}
2353
2354void show_time_frame(GtkWidget * widget, gpointer user_data)
2355{
56e5a0f7 2356 g_info("Show time frame\n");
561eba2a 2357}
2358
2359
2360/* callback function */
2361
2362void
2363on_empty_traceset_activate (GtkMenuItem *menuitem,
2364 gpointer user_data)
2365{
68b48a45 2366 create_new_window((GtkWidget*)menuitem, user_data, FALSE);
561eba2a 2367}
2368
2369
2370void
2371on_clone_traceset_activate (GtkMenuItem *menuitem,
2372 gpointer user_data)
2373{
68b48a45 2374 create_new_window((GtkWidget*)menuitem, user_data, TRUE);
561eba2a 2375}
2376
abe346a3 2377
2378/* create_new_tab calls create_tab to construct a new tab in the main window
2379 */
2380
6ced96ef 2381Tab *create_new_tab(GtkWidget* widget, gpointer user_data){
a1a2b649 2382 gchar label[PATH_MAX];
2901f314 2383 MainWindow * mw_data = get_window_data_struct(widget);
4266dc7f 2384
2901f314 2385 GtkNotebook * notebook = (GtkNotebook *)lookup_widget(widget, "MNotebook");
561eba2a 2386 if(notebook == NULL){
56e5a0f7 2387 g_info("Notebook does not exist\n");
6ced96ef 2388 return NULL;
2389 }
2390 GtkWidget *page = gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook),
2391 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook)));
2392 Tab *copy_tab;
2393
2394 if(!page) {
2395 copy_tab = NULL;
2396 } else {
2397 copy_tab = (Tab *)g_object_get_data(G_OBJECT(page), "Tab_Info");
561eba2a 2398 }
4266dc7f 2399
6b1d3120 2400 strcpy(label,"Page");
eb38aea5 2401 if(get_label(mw_data, label,"Get the name of the tab","Please input tab's name"))
6ced96ef 2402 return (create_tab (mw_data, copy_tab, notebook, label));
561eba2a 2403}
2404
2901f314 2405void
2406on_tab_activate (GtkMenuItem *menuitem,
2407 gpointer user_data)
2408{
2409 create_new_tab((GtkWidget*)menuitem, user_data);
2410}
2411
561eba2a 2412
2413void
2414on_open_activate (GtkMenuItem *menuitem,
2415 gpointer user_data)
2416{
2417 open_traceset((GtkWidget*)menuitem, user_data);
2418}
2419
2420
2421void
2422on_close_activate (GtkMenuItem *menuitem,
2423 gpointer user_data)
2424{
bca3b81f 2425 MainWindow * mw_data = get_window_data_struct((GtkWidget*)menuitem);
68b48a45 2426 main_window_destructor(mw_data);
561eba2a 2427}
2428
2429
4266dc7f 2430/* remove the current tab from the main window
abe346a3 2431 */
2432
561eba2a 2433void
27a559b9 2434on_close_tab_activate (GtkWidget *widget,
561eba2a 2435 gpointer user_data)
2436{
4266dc7f 2437 gint page_num;
2061e03d 2438 GtkWidget * notebook;
4266dc7f 2439 GtkWidget * page;
27a559b9 2440 MainWindow * mw_data = get_window_data_struct(widget);
2441 notebook = lookup_widget(widget, "MNotebook");
2061e03d 2442 if(notebook == NULL){
56e5a0f7 2443 g_info("Notebook does not exist\n");
2061e03d 2444 return;
2445 }
4266dc7f 2446
2447 page_num = gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook));
2061e03d 2448
4266dc7f 2449 gtk_notebook_remove_page(GTK_NOTEBOOK(notebook), page_num);
2061e03d 2450
561eba2a 2451}
2452
27a559b9 2453void
2454on_close_tab_X_clicked (GtkWidget *widget,
2455 gpointer user_data)
2456{
2457 gint page_num;
2458 GtkWidget *notebook = lookup_widget(widget, "MNotebook");
2459 if(notebook == NULL){
56e5a0f7 2460 g_info("Notebook does not exist\n");
27a559b9 2461 return;
2462 }
2463
2464 if((page_num = gtk_notebook_page_num(GTK_NOTEBOOK(notebook), widget)) != -1)
2465 gtk_notebook_remove_page(GTK_NOTEBOOK(notebook), page_num);
2466
2467}
2468
561eba2a 2469
2470void
2471on_add_trace_activate (GtkMenuItem *menuitem,
2472 gpointer user_data)
2473{
2474 add_trace((GtkWidget*)menuitem, user_data);
2475}
2476
2477
2478void
2479on_remove_trace_activate (GtkMenuItem *menuitem,
2480 gpointer user_data)
2481{
2482 remove_trace((GtkWidget*)menuitem, user_data);
2483}
2484
2485
2486void
2487on_save_activate (GtkMenuItem *menuitem,
2488 gpointer user_data)
2489{
2490 save((GtkWidget*)menuitem, user_data);
2491}
2492
2493
2494void
2495on_save_as_activate (GtkMenuItem *menuitem,
2496 gpointer user_data)
2497{
2498 save_as((GtkWidget*)menuitem, user_data);
2499}
2500
2501
2502void
2503on_quit_activate (GtkMenuItem *menuitem,
2504 gpointer user_data)
2505{
2061e03d 2506 gtk_main_quit ();
561eba2a 2507}
2508
2509
2510void
2511on_cut_activate (GtkMenuItem *menuitem,
2512 gpointer user_data)
2513{
56e5a0f7 2514 g_info("Cut\n");
561eba2a 2515}
2516
2517
2518void
2519on_copy_activate (GtkMenuItem *menuitem,
2520 gpointer user_data)
2521{
56e5a0f7 2522 g_info("Copye\n");
561eba2a 2523}
2524
2525
2526void
2527on_paste_activate (GtkMenuItem *menuitem,
2528 gpointer user_data)
2529{
56e5a0f7 2530 g_info("Paste\n");
561eba2a 2531}
2532
2533
2534void
2535on_delete_activate (GtkMenuItem *menuitem,
2536 gpointer user_data)
2537{
56e5a0f7 2538 g_info("Delete\n");
561eba2a 2539}
2540
2541
2542void
2543on_zoom_in_activate (GtkMenuItem *menuitem,
2544 gpointer user_data)
2545{
2546 zoom_in((GtkWidget*)menuitem, user_data);
2547}
2548
2549
2550void
2551on_zoom_out_activate (GtkMenuItem *menuitem,
2552 gpointer user_data)
2553{
2554 zoom_out((GtkWidget*)menuitem, user_data);
2555}
2556
2557
2558void
2559on_zoom_extended_activate (GtkMenuItem *menuitem,
2560 gpointer user_data)
2561{
2562 zoom_extended((GtkWidget*)menuitem, user_data);
2563}
2564
2565
2566void
2567on_go_to_time_activate (GtkMenuItem *menuitem,
2568 gpointer user_data)
2569{
2570 go_to_time((GtkWidget*)menuitem, user_data);
2571}
2572
2573
2574void
2575on_show_time_frame_activate (GtkMenuItem *menuitem,
2576 gpointer user_data)
2577{
2578 show_time_frame((GtkWidget*)menuitem, user_data);
2579}
2580
2581
2582void
2583on_move_viewer_up_activate (GtkMenuItem *menuitem,
2584 gpointer user_data)
2585{
2586 move_up_viewer((GtkWidget*)menuitem, user_data);
2587}
2588
2589
2590void
2591on_move_viewer_down_activate (GtkMenuItem *menuitem,
2592 gpointer user_data)
2593{
2594 move_down_viewer((GtkWidget*)menuitem, user_data);
2595}
2596
2597
2598void
2599on_remove_viewer_activate (GtkMenuItem *menuitem,
2600 gpointer user_data)
2601{
2602 delete_viewer((GtkWidget*)menuitem, user_data);
2603}
2604
b052368a 2605#if 0
49bf71b5 2606void
2607on_trace_filter_activate (GtkMenuItem *menuitem,
2608 gpointer user_data)
2609{
2610 MainWindow * mw_data = get_window_data_struct((GtkWidget*)menuitem);
2611 LttvTracesetSelector * s;
4266dc7f 2612 GtkWidget * w;
6ced96ef 2613 GtkWidget * notebook = lookup_widget(GTK_WIDGET(menuitem), "MNotebook");
2614
2615 GtkWidget *page = gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook),
2616 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook)));
2617 Tab *tab;
2618
2619 if(!page) {
2620 return;
2621 } else {
2622 tab = (Tab *)g_object_get_data(G_OBJECT(page), "Tab_Info");
2623 }
4266dc7f 2624
b052368a 2625 w = gtk_multivpaned_get_widget(GTK_MULTIVPANED(tab->multivpaned));
49bf71b5 2626
2627 s = g_object_get_data(G_OBJECT(w), "Traceset_Selector");
2628 if(!s){
56e5a0f7 2629 g_info("There is no viewer yet\n");
49bf71b5 2630 return;
2631 }
a8c0f09d 2632 if(get_filter_selection(s, "Configure trace and tracefile filter", "Select traces and tracefiles")){
a43d67ba 2633 //FIXME report filter change
2634 //update_traceset(mw_data);
2635 //call_pending_read_hooks(mw_data);
4266dc7f 2636 //lttvwindow_report_current_time(mw_data,&(tab->current_time));
a8c0f09d 2637 }
49bf71b5 2638}
b052368a 2639#endif //0
49bf71b5 2640
2641void
2642on_trace_facility_activate (GtkMenuItem *menuitem,
2643 gpointer user_data)
2644{
56e5a0f7 2645 g_info("Trace facility selector: %s\n");
49bf71b5 2646}
561eba2a 2647
abe346a3 2648
b052368a 2649/* Dispaly a file selection dialogue to let user select a library, then call
2650 * lttv_library_load().
2651 */
2652
2653void
2654on_load_library_activate (GtkMenuItem *menuitem,
2655 gpointer user_data)
2656{
2657 GError *error = NULL;
2658 MainWindow * mw_data = get_window_data_struct((GtkWidget*)menuitem);
2659
2660 gchar load_module_path_alter[PATH_MAX];
2661 {
2662 GPtrArray *name;
2663 guint nb,i;
2664 gchar *load_module_path;
2665 name = g_ptr_array_new();
2666 nb = lttv_library_path_number();
2667 /* ask for the library path */
2668
2669 for(i=0;i<nb;i++){
2670 gchar *path;
2671 path = lttv_library_path_get(i);
2672 g_ptr_array_add(name, path);
2673 }
2674
2675 load_module_path = get_selection((char **)(name->pdata), name->len,
2676 "Select a library path", "Library paths");
2677 if(load_module_path != NULL)
2678 strncpy(load_module_path_alter, load_module_path, PATH_MAX-1); // -1 for /
2679
2680 g_ptr_array_free(name, TRUE);
2681
2682 if(load_module_path == NULL) return;
2683 }
2684
2685 {
2686 /* Make sure the module path ends with a / */
2687 gchar *ptr = load_module_path_alter;
2688
2689 ptr = strchr(ptr, '\0');
2690
2691 if(*(ptr-1) != '/') {
2692 *ptr = '/';
2693 *(ptr+1) = '\0';
2694 }
2695 }
2696
2697 {
2698 /* Ask for the library to load : list files in the previously selected
2699 * directory */
2700 gchar str[PATH_MAX];
2701 gchar ** dir;
2702 gint id;
2703 GtkFileSelection * file_selector =
2704 (GtkFileSelection *)gtk_file_selection_new("Select a module");
2705 gtk_file_selection_set_filename(file_selector, load_module_path_alter);
2706 gtk_file_selection_hide_fileop_buttons(file_selector);
2707
2708 str[0] = '\0';
2709 id = gtk_dialog_run(GTK_DIALOG(file_selector));
2710 switch(id){
2711 case GTK_RESPONSE_ACCEPT:
2712 case GTK_RESPONSE_OK:
2713 dir = gtk_file_selection_get_selections (file_selector);
2714 strncpy(str,dir[0],PATH_MAX);
2715 strncpy(remember_plugins_dir,dir[0],PATH_MAX);
2716 /* only keep file name */
2717 gchar *str1;
2718 str1 = strrchr(str,'/');
2719 if(str1)str1++;
2720 else{
2721 str1 = strrchr(str,'\\');
2722 str1++;
2723 }
2724#if 0
2725 /* remove "lib" */
2726 if(*str1 == 'l' && *(str1+1)== 'i' && *(str1+2)=='b')
2727 str1=str1+3;
2728 remove info after . */
2729 {
2730 gchar *str2 = str1;
2731
2732 str2 = strrchr(str2, '.');
2733 if(str2 != NULL) *str2 = '\0';
2734 }
2735 lttv_module_require(str1, &error);
2736#endif //0
2737 lttv_library_load(str1, &error);
2eef04b5 2738 if(error != NULL) g_warning("%s", error->message);
56e5a0f7 2739 else g_info("Load library: %s\n", str);
b052368a 2740 g_strfreev(dir);
2741 case GTK_RESPONSE_REJECT:
2742 case GTK_RESPONSE_CANCEL:
2743 default:
2744 gtk_widget_destroy((GtkWidget*)file_selector);
2745 break;
2746 }
2747
2748 }
2749
2750
2751
2752}
2753
2754
2755/* Display all loaded modules, let user to select a module to unload
2756 * by calling lttv_module_unload
2757 */
2758
2759void
2760on_unload_library_activate (GtkMenuItem *menuitem,
2761 gpointer user_data)
2762{
2763 MainWindow * mw_data = get_window_data_struct((GtkWidget*)menuitem);
2764
2eef04b5 2765 LttvLibrary *library = NULL;
b052368a 2766
2eef04b5 2767 GPtrArray *name;
2768 guint nb,i;
2769 gchar *lib_name;
2770 name = g_ptr_array_new();
2771 nb = lttv_library_number();
2772 LttvLibraryInfo *lib_info = g_new(LttvLibraryInfo,nb);
2773 /* ask for the library name */
2774
2775 for(i=0;i<nb;i++){
2776 LttvLibrary *iter_lib = lttv_library_get(i);
2777 lttv_library_info(iter_lib, &lib_info[i]);
2778
2779 gchar *path = lib_info[i].name;
2780 g_ptr_array_add(name, path);
2781 }
2782 lib_name = get_selection((char **)(name->pdata), name->len,
2783 "Select a library", "Libraries");
2784 if(lib_name != NULL) {
b052368a 2785 for(i=0;i<nb;i++){
2eef04b5 2786 if(strcmp(lib_name, lib_info[i].name) == 0) {
2787 library = lttv_library_get(i);
2788 break;
b052368a 2789 }
2790 }
b052368a 2791 }
2eef04b5 2792 g_ptr_array_free(name, TRUE);
2793 g_free(lib_info);
2794
2795 if(lib_name == NULL) return;
2796
2797 if(library != NULL) lttv_library_unload(library);
b052368a 2798}
2799
2800
abe346a3 2801/* Dispaly a file selection dialogue to let user select a module, then call
b052368a 2802 * lttv_module_require().
abe346a3 2803 */
2804
561eba2a 2805void
2806on_load_module_activate (GtkMenuItem *menuitem,
2807 gpointer user_data)
2808{
b052368a 2809 GError *error = NULL;
bca3b81f 2810 MainWindow * mw_data = get_window_data_struct((GtkWidget*)menuitem);
b052368a 2811
2eef04b5 2812 LttvLibrary *library = NULL;
b052368a 2813 {
2814 GPtrArray *name;
2815 guint nb,i;
2816 gchar *lib_name;
2817 name = g_ptr_array_new();
2818 nb = lttv_library_number();
2819 LttvLibraryInfo *lib_info = g_new(LttvLibraryInfo,nb);
2820 /* ask for the library name */
2821
2822 for(i=0;i<nb;i++){
2823 LttvLibrary *iter_lib = lttv_library_get(i);
2824 lttv_library_info(iter_lib, &lib_info[i]);
2825
2826 gchar *path = lib_info[i].name;
2827 g_ptr_array_add(name, path);
2828 }
2829 lib_name = get_selection((char **)(name->pdata), name->len,
2830 "Select a library", "Libraries");
2831 if(lib_name != NULL) {
2832 for(i=0;i<nb;i++){
2833 if(strcmp(lib_name, lib_info[i].name) == 0) {
2834 library = lttv_library_get(i);
2835 break;
2836 }
3872a20e 2837 }
b052368a 2838 }
2839 g_ptr_array_free(name, TRUE);
2840 g_free(lib_info);
2841
2842 if(lib_name == NULL) return;
36b3c068 2843 }
b052368a 2844
2845 //LttvModule *module;
2846 gchar module_name_out[PATH_MAX];
2847 {
2848 /* Ask for the module to load : list modules in the selected lib */
2849 GPtrArray *name;
2850 guint nb,i;
2851 gchar *module_name;
bbbd6c25 2852 nb = lttv_library_module_number(library);
b052368a 2853 LttvModuleInfo *module_info = g_new(LttvModuleInfo,nb);
2854 name = g_ptr_array_new();
b052368a 2855 /* ask for the module name */
2856
2857 for(i=0;i<nb;i++){
2858 LttvModule *iter_module = lttv_library_module_get(library, i);
2859 lttv_module_info(iter_module, &module_info[i]);
2860
2861 gchar *path = module_info[i].name;
2862 g_ptr_array_add(name, path);
2863 }
2864 module_name = get_selection((char **)(name->pdata), name->len,
2865 "Select a module", "Modules");
2866 if(module_name != NULL) {
2867 for(i=0;i<nb;i++){
2868 if(strcmp(module_name, module_info[i].name) == 0) {
2869 strncpy(module_name_out, module_name, PATH_MAX);
2870 //module = lttv_library_module_get(i);
2871 break;
2872 }
2873 }
2874 }
2875
2876 g_ptr_array_free(name, TRUE);
2877 g_free(module_info);
2878
2879 if(module_name == NULL) return;
2880 }
2881
2882 lttv_module_require(module_name_out, &error);
2eef04b5 2883 if(error != NULL) g_warning("%s", error->message);
56e5a0f7 2884 else g_info("Load module: %s", module_name_out);
b052368a 2885
2886
2887#if 0
2888 {
2889
2890
2891 gchar str[PATH_MAX];
2892 gchar ** dir;
2893 gint id;
2894 GtkFileSelection * file_selector =
2895 (GtkFileSelection *)gtk_file_selection_new("Select a module");
2896 gtk_file_selection_set_filename(file_selector, load_module_path_alter);
2897 gtk_file_selection_hide_fileop_buttons(file_selector);
2898
2899 str[0] = '\0';
2900 id = gtk_dialog_run(GTK_DIALOG(file_selector));
2901 switch(id){
2902 case GTK_RESPONSE_ACCEPT:
2903 case GTK_RESPONSE_OK:
2904 dir = gtk_file_selection_get_selections (file_selector);
2905 strncpy(str,dir[0],PATH_MAX);
2906 strncpy(remember_plugins_dir,dir[0],PATH_MAX);
2907 {
2908 /* only keep file name */
2909 gchar *str1;
2910 str1 = strrchr(str,'/');
2911 if(str1)str1++;
2912 else{
2913 str1 = strrchr(str,'\\');
2914 str1++;
2915 }
2916#if 0
2917 /* remove "lib" */
2918 if(*str1 == 'l' && *(str1+1)== 'i' && *(str1+2)=='b')
2919 str1=str1+3;
2920 remove info after . */
2921 {
2922 gchar *str2 = str1;
2923
2924 str2 = strrchr(str2, '.');
2925 if(str2 != NULL) *str2 = '\0';
2926 }
2927 lttv_module_require(str1, &error);
2928#endif //0
2929 lttv_library_load(str1, &error);
2930 if(error != NULL) g_warning(error->message);
56e5a0f7 2931 else g_info("Load library: %s\n", str);
b052368a 2932 g_strfreev(dir);
2933 case GTK_RESPONSE_REJECT:
2934 case GTK_RESPONSE_CANCEL:
2935 default:
2936 gtk_widget_destroy((GtkWidget*)file_selector);
2937 break;
2938 }
2939
2940 }
2941#endif //0
2942
2943
561eba2a 2944}
2945
2946
b052368a 2947
abe346a3 2948/* Display all loaded modules, let user to select a module to unload
2949 * by calling lttv_module_unload
2950 */
2951
561eba2a 2952void
2953on_unload_module_activate (GtkMenuItem *menuitem,
2954 gpointer user_data)
2955{
b052368a 2956 GError *error = NULL;
bca3b81f 2957 MainWindow * mw_data = get_window_data_struct((GtkWidget*)menuitem);
08b1c66e 2958
b052368a 2959 LttvLibrary *library;
2960 {
2961 GPtrArray *name;
2962 guint nb,i;
2963 gchar *lib_name;
2964 name = g_ptr_array_new();
2965 nb = lttv_library_number();
2966 LttvLibraryInfo *lib_info = g_new(LttvLibraryInfo,nb);
2967 /* ask for the library name */
36b3c068 2968
36b3c068 2969 for(i=0;i<nb;i++){
b052368a 2970 LttvLibrary *iter_lib = lttv_library_get(i);
2971 lttv_library_info(iter_lib, &lib_info[i]);
2972
2973 gchar *path = lib_info[i].name;
2974 g_ptr_array_add(name, path);
2975 }
2976 lib_name = get_selection((char **)(name->pdata), name->len,
2977 "Select a library", "Libraries");
2978 if(lib_name != NULL) {
2979 for(i=0;i<nb;i++){
2980 if(strcmp(lib_name, lib_info[i].name) == 0) {
2981 library = lttv_library_get(i);
2982 break;
2983 }
36b3c068 2984 }
b052368a 2985 }
2986 g_ptr_array_free(name, TRUE);
2987 g_free(lib_info);
2988
2989 if(lib_name == NULL) return;
36b3c068 2990 }
2991
2eef04b5 2992 LttvModule *module = NULL;
b052368a 2993 {
2994 /* Ask for the module to load : list modules in the selected lib */
2995 GPtrArray *name;
2996 guint nb,i;
2997 gchar *module_name;
6d677a86 2998 nb = lttv_library_module_number(library);
b052368a 2999 LttvModuleInfo *module_info = g_new(LttvModuleInfo,nb);
3000 name = g_ptr_array_new();
b052368a 3001 /* ask for the module name */
3002
3003 for(i=0;i<nb;i++){
3004 LttvModule *iter_module = lttv_library_module_get(library, i);
3005 lttv_module_info(iter_module, &module_info[i]);
3006
3007 gchar *path = module_info[i].name;
3008 if(module_info[i].use_count > 0) g_ptr_array_add(name, path);
3009 }
3010 module_name = get_selection((char **)(name->pdata), name->len,
3011 "Select a module", "Modules");
3012 if(module_name != NULL) {
3013 for(i=0;i<nb;i++){
3014 if(strcmp(module_name, module_info[i].name) == 0) {
3015 module = lttv_library_module_get(library, i);
3016 break;
3017 }
3018 }
3019 }
3020
3021 g_ptr_array_free(name, TRUE);
3022 g_free(module_info);
3023
3024 if(module_name == NULL) return;
3025 }
3026
b052368a 3027 LttvModuleInfo module_info;
3028 lttv_module_info(module, &module_info);
56e5a0f7 3029 g_info("Release module: %s\n", module_info.name);
fce9a2fc 3030
3031 lttv_module_release(module);
561eba2a 3032}
3033
3034
b052368a 3035/* Display a directory dialogue to let user select a path for library searching
abe346a3 3036 */
3037
561eba2a 3038void
b052368a 3039on_add_library_search_path_activate (GtkMenuItem *menuitem,
561eba2a 3040 gpointer user_data)
3041{
b052368a 3042 GtkDirSelection * file_selector = (GtkDirSelection *)gtk_dir_selection_new("Select library path");
67b98724 3043 const char * dir;
fc188b78 3044 gint id;
3045
bca3b81f 3046 MainWindow * mw_data = get_window_data_struct((GtkWidget*)menuitem);
3658a338 3047 if(remember_plugins_dir[0] != '\0')
3048 gtk_dir_selection_set_filename(file_selector, remember_plugins_dir);
fc188b78 3049
68b48a45 3050 id = gtk_dialog_run(GTK_DIALOG(file_selector));
fc188b78 3051 switch(id){
3052 case GTK_RESPONSE_ACCEPT:
3053 case GTK_RESPONSE_OK:
68b48a45 3054 dir = gtk_dir_selection_get_dir (file_selector);
a1a2b649 3055 strncpy(remember_plugins_dir,dir,PATH_MAX);
3056 strncat(remember_plugins_dir,"/",PATH_MAX);
08b1c66e 3057 lttv_library_path_add(dir);
fc188b78 3058 case GTK_RESPONSE_REJECT:
3059 case GTK_RESPONSE_CANCEL:
3060 default:
68b48a45 3061 gtk_widget_destroy((GtkWidget*)file_selector);
fc188b78 3062 break;
6b1d3120 3063 }
561eba2a 3064}
3065
3066
b052368a 3067/* Display a directory dialogue to let user select a path for library searching
3068 */
3069
3070void
3071on_remove_library_search_path_activate (GtkMenuItem *menuitem,
3072 gpointer user_data)
3073{
3074 MainWindow * mw_data = get_window_data_struct((GtkWidget*)menuitem);
3075
3076 const char *lib_path;
3077 {
3078 GPtrArray *name;
3079 guint nb,i;
3080 gchar *lib_name;
3081 name = g_ptr_array_new();
3082 nb = lttv_library_path_number();
3083 /* ask for the library name */
3084
3085 for(i=0;i<nb;i++){
3086 gchar *path = lttv_library_path_get(i);
3087 g_ptr_array_add(name, path);
3088 }
3089 lib_path = get_selection((char **)(name->pdata), name->len,
3090 "Select a library path", "Library paths");
3091
3092 g_ptr_array_free(name, TRUE);
3093
3094 if(lib_path == NULL) return;
3095 }
3096
3097 lttv_library_path_remove(lib_path);
3098}
3099
561eba2a 3100void
3101on_color_activate (GtkMenuItem *menuitem,
3102 gpointer user_data)
3103{
56e5a0f7 3104 g_info("Color\n");
561eba2a 3105}
3106
3107
3108void
3109on_filter_activate (GtkMenuItem *menuitem,
3110 gpointer user_data)
3111{
56e5a0f7 3112 g_info("Filter\n");
561eba2a 3113}
3114
3115
3116void
3117on_save_configuration_activate (GtkMenuItem *menuitem,
3118 gpointer user_data)
3119{
56e5a0f7 3120 g_info("Save configuration\n");
561eba2a 3121}
3122
3123
3124void
3125on_content_activate (GtkMenuItem *menuitem,
3126 gpointer user_data)
3127{
56e5a0f7 3128 g_info("Content\n");
561eba2a 3129}
3130
3131
51ef553b 3132static void
3133on_about_close_activate (GtkButton *button,
3134 gpointer user_data)
3135{
3136 GtkWidget *about_widget = GTK_WIDGET(user_data);
3137
3138 gtk_widget_destroy(about_widget);
3139}
3140
561eba2a 3141void
3142on_about_activate (GtkMenuItem *menuitem,
3143 gpointer user_data)
3144{
51ef553b 3145 MainWindow *main_window = get_window_data_struct(GTK_WIDGET(menuitem));
3146 GtkWidget *window_widget = main_window->mwindow;
3147 GtkWidget *about_widget = gtk_window_new(GTK_WINDOW_TOPLEVEL);
3148 GtkWindow *about_window = GTK_WINDOW(about_widget);
3149 gint window_width, window_height;
3150
3151 gtk_window_set_title(about_window, "About Linux Trace Toolkit");
3152
3153 gtk_window_set_resizable(about_window, FALSE);
3154 gtk_window_set_transient_for(GTK_WINDOW(window_widget), about_window);
3155 gtk_window_set_destroy_with_parent(about_window, TRUE);
3156 gtk_window_set_modal(about_window, FALSE);
3157
3158 /* Put the about window at the center of the screen */
3159 gtk_window_get_size(about_window, &window_width, &window_height);
3160 gtk_window_move (about_window,
3161 (gdk_screen_width() - window_width)/2,
3162 (gdk_screen_height() - window_height)/2);
3163
3164 GtkWidget *vbox = gtk_vbox_new(FALSE, 1);
3165
3166 gtk_container_add(GTK_CONTAINER(about_widget), vbox);
3167
3168
3169 /* Text to show */
3170 GtkWidget *label1 = gtk_label_new("");
c8bba5fa 3171 gtk_misc_set_padding(GTK_MISC(label1), 10, 20);
51ef553b 3172 gtk_label_set_markup(GTK_LABEL(label1), "\
c8bba5fa 3173<big>Linux Trace Toolkit</big>");
51ef553b 3174 gtk_label_set_justify(GTK_LABEL(label1), GTK_JUSTIFY_CENTER);
3175
3176 GtkWidget *label2 = gtk_label_new("");
c8bba5fa 3177 gtk_misc_set_padding(GTK_MISC(label2), 10, 20);
51ef553b 3178 gtk_label_set_markup(GTK_LABEL(label2), "\
51ef553b 3179Contributors :\n\
3180\n\
3181Michel Dagenais (New trace format, lttv main)\n\
3182Mathieu Desnoyers (Directory structure, build with automake/conf,\n\
ef26c1ea 3183 lttv gui, control flow view, gui cooperative trace reading\n\
4b7bd7e1 3184 scheduler with interruptible foreground and background\n\
e8ac6a5e 3185 computation, detailed event list)\n\